Line data Source code
1 : /* SPDX-License-Identifier: Apache-2.0
2 : * Copyright(c) 2021 Cisco Systems, Inc.
3 : * Copyright(c) 2022 Nordix Foundation.
4 : */
5 :
6 : #include <vat/vat.h>
7 : #include <vlibapi/api.h>
8 : #include <vlibmemory/api.h>
9 : #include <vppinfra/error.h>
10 : #include <vpp/api/types.h>
11 : #include <inttypes.h>
12 :
13 : #include <vnet/l2/l2_classify.h>
14 : #include <vnet/l2/l2_vtr.h>
15 : #include <vnet/ip/ip_types_api.h>
16 :
17 : #define __plugin_msg_base l2_test_main.msg_id_base
18 : #include <vlibapi/vat_helper_macros.h>
19 :
20 : #include <vlibmemory/vlib.api_enum.h>
21 : #include <vlibmemory/vlib.api_types.h>
22 :
23 : /* Declare message IDs */
24 : #include <vnet/format_fns.h>
25 : #include <vnet/l2/l2.api_enum.h>
26 : #include <vnet/l2/l2.api_types.h>
27 :
28 : #define vl_endianfun /* define message structures */
29 : #include <vnet/l2/l2.api.h>
30 : #undef vl_endianfun
31 :
32 : #define vl_calcsizefun
33 : #include <vnet/l2/l2.api.h>
34 : #undef vl_calcsizefun
35 :
36 : typedef struct
37 : {
38 : /* API message ID base */
39 : u16 msg_id_base;
40 : u32 ping_id;
41 : vat_main_t *vat_main;
42 : } l2_test_main_t;
43 :
44 : static l2_test_main_t l2_test_main;
45 :
46 : static void
47 0 : vl_api_l2_fib_table_details_t_handler (vl_api_l2_fib_table_details_t *mp)
48 : {
49 0 : vat_main_t *vam = l2_test_main.vat_main;
50 :
51 0 : fformat (
52 : vam->ofp, "%3" PRIu32 " %U %3" PRIu32 " %d %d %d",
53 0 : ntohl (mp->bd_id), format_ethernet_address, mp->mac,
54 0 : ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac, mp->bvi_mac);
55 0 : }
56 :
57 : static int
58 0 : api_l2_fib_table_dump (vat_main_t *vam)
59 : {
60 0 : unformat_input_t *i = vam->input;
61 : vl_api_l2_fib_table_dump_t *mp;
62 : vl_api_control_ping_t *mp_ping;
63 : u32 bd_id;
64 0 : u8 bd_id_set = 0;
65 : int ret;
66 :
67 : /* Parse args required to build the message */
68 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
69 : {
70 0 : if (unformat (i, "bd_id %d", &bd_id))
71 0 : bd_id_set = 1;
72 : else
73 0 : break;
74 : }
75 :
76 0 : if (bd_id_set == 0)
77 : {
78 0 : errmsg ("missing bridge domain");
79 0 : return -99;
80 : }
81 :
82 0 : fformat (vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI");
83 :
84 : /* Get list of l2 fib entries */
85 0 : M (L2_FIB_TABLE_DUMP, mp);
86 :
87 0 : mp->bd_id = ntohl (bd_id);
88 0 : S (mp);
89 :
90 : /* Use a control ping for synchronization */
91 0 : PING (&l2_test_main, mp_ping);
92 0 : S (mp_ping);
93 :
94 0 : W (ret);
95 0 : return ret;
96 : }
97 :
98 : static void
99 0 : vl_api_l2_xconnect_details_t_handler (vl_api_l2_xconnect_details_t *mp)
100 : {
101 0 : vat_main_t *vam = l2_test_main.vat_main;
102 0 : fformat (vam->ofp, "%15d%15d", ntohl (mp->rx_sw_if_index),
103 : ntohl (mp->tx_sw_if_index));
104 0 : }
105 :
106 : static int
107 0 : api_l2_xconnect_dump (vat_main_t *vam)
108 : {
109 : vl_api_l2_xconnect_dump_t *mp;
110 : vl_api_control_ping_t *mp_ping;
111 : int ret;
112 :
113 0 : if (!vam->json_output)
114 : {
115 0 : print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
116 : }
117 :
118 0 : M (L2_XCONNECT_DUMP, mp);
119 :
120 0 : S (mp);
121 :
122 : /* Use a control ping for synchronization */
123 0 : PING (&l2_test_main, mp_ping);
124 0 : S (mp_ping);
125 :
126 0 : W (ret);
127 0 : return ret;
128 : }
129 :
130 : static int
131 0 : api_want_l2_arp_term_events (vat_main_t *vam)
132 : {
133 0 : return -1;
134 : }
135 :
136 : static int
137 0 : api_want_l2_macs_events (vat_main_t *vam)
138 : {
139 0 : unformat_input_t *line_input = vam->input;
140 : vl_api_want_l2_macs_events_t *mp;
141 0 : u8 enable_disable = 1;
142 0 : u32 scan_delay = 0;
143 0 : u32 max_macs_in_event = 0;
144 0 : u32 learn_limit = 0;
145 : int ret;
146 :
147 0 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
148 : {
149 0 : if (unformat (line_input, "learn-limit %d", &learn_limit))
150 : ;
151 0 : else if (unformat (line_input, "scan-delay %d", &scan_delay))
152 : ;
153 0 : else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
154 : ;
155 0 : else if (unformat (line_input, "disable"))
156 0 : enable_disable = 0;
157 : else
158 0 : break;
159 : }
160 :
161 0 : M (WANT_L2_MACS_EVENTS, mp);
162 0 : mp->enable_disable = enable_disable;
163 0 : mp->pid = htonl (getpid ());
164 0 : mp->learn_limit = htonl (learn_limit);
165 0 : mp->scan_delay = (u8) scan_delay;
166 0 : mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
167 0 : S (mp);
168 0 : W (ret);
169 0 : return ret;
170 : }
171 :
172 : static int
173 0 : api_l2fib_flush_all (vat_main_t *vam)
174 : {
175 0 : return -1;
176 : }
177 :
178 : static void
179 0 : increment_mac_address (u8 *mac)
180 : {
181 0 : u64 tmp = *((u64 *) mac);
182 0 : tmp = clib_net_to_host_u64 (tmp);
183 0 : tmp += 1 << 16; /* skip unused (least significant) octets */
184 0 : tmp = clib_host_to_net_u64 (tmp);
185 :
186 0 : clib_memcpy (mac, &tmp, 6);
187 0 : }
188 :
189 : static int
190 0 : api_l2fib_add_del (vat_main_t *vam)
191 : {
192 0 : vnet_main_t *vnm = vnet_get_main ();
193 0 : unformat_input_t *i = vam->input;
194 : vl_api_l2fib_add_del_t *mp;
195 : f64 timeout;
196 0 : u8 mac[8] = { 0 };
197 0 : u8 mac_set = 0;
198 : u32 bd_id;
199 0 : u8 bd_id_set = 0;
200 0 : u32 sw_if_index = 0;
201 0 : u8 sw_if_index_set = 0;
202 0 : u8 is_add = 1;
203 0 : u8 static_mac = 0;
204 0 : u8 filter_mac = 0;
205 0 : u8 bvi_mac = 0;
206 0 : int count = 1;
207 0 : f64 before = 0;
208 : int j;
209 :
210 : /* Parse args required to build the message */
211 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
212 : {
213 0 : if (unformat (i, "mac %U", unformat_ethernet_address, mac))
214 0 : mac_set = 1;
215 0 : else if (unformat (i, "bd_id %d", &bd_id))
216 0 : bd_id_set = 1;
217 0 : else if (unformat (i, "sw_if_index %d", &sw_if_index))
218 0 : sw_if_index_set = 1;
219 0 : else if (unformat (i, "sw_if"))
220 : {
221 0 : if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
222 : {
223 0 : if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
224 : &sw_if_index))
225 0 : sw_if_index_set = 1;
226 : }
227 : else
228 0 : break;
229 : }
230 0 : else if (unformat (i, "static"))
231 0 : static_mac = 1;
232 0 : else if (unformat (i, "filter"))
233 : {
234 0 : filter_mac = 1;
235 0 : static_mac = 1;
236 : }
237 0 : else if (unformat (i, "bvi"))
238 : {
239 0 : bvi_mac = 1;
240 0 : static_mac = 1;
241 : }
242 0 : else if (unformat (i, "del"))
243 0 : is_add = 0;
244 0 : else if (unformat (i, "count %d", &count))
245 : ;
246 : else
247 0 : break;
248 : }
249 :
250 0 : if (mac_set == 0)
251 : {
252 0 : errmsg ("missing mac address");
253 0 : return -99;
254 : }
255 :
256 0 : if (bd_id_set == 0)
257 : {
258 0 : errmsg ("missing bridge domain");
259 0 : return -99;
260 : }
261 :
262 0 : if (is_add && sw_if_index_set == 0 && filter_mac == 0)
263 : {
264 0 : errmsg ("missing interface name or sw_if_index");
265 0 : return -99;
266 : }
267 :
268 0 : if (count > 1)
269 : {
270 : /* Turn on async mode */
271 0 : vam->async_mode = 1;
272 0 : vam->async_errors = 0;
273 0 : before = vat_time_now (vam);
274 : }
275 :
276 0 : for (j = 0; j < count; j++)
277 : {
278 0 : M (L2FIB_ADD_DEL, mp);
279 :
280 0 : clib_memcpy (mp->mac, mac, 6);
281 0 : mp->bd_id = ntohl (bd_id);
282 0 : mp->is_add = is_add;
283 0 : mp->sw_if_index = ntohl (sw_if_index);
284 :
285 0 : if (is_add)
286 : {
287 0 : mp->static_mac = static_mac;
288 0 : mp->filter_mac = filter_mac;
289 0 : mp->bvi_mac = bvi_mac;
290 : }
291 0 : increment_mac_address (mac);
292 : /* send it... */
293 0 : S (mp);
294 : }
295 :
296 0 : if (count > 1)
297 : {
298 : vl_api_control_ping_t *mp_ping;
299 : f64 after;
300 :
301 : /* Shut off async mode */
302 0 : vam->async_mode = 0;
303 :
304 0 : PING (&l2_test_main, mp_ping);
305 0 : S (mp_ping);
306 :
307 0 : timeout = vat_time_now (vam) + 1.0;
308 0 : while (vat_time_now (vam) < timeout)
309 0 : if (vam->result_ready == 1)
310 0 : goto out;
311 0 : vam->retval = -99;
312 :
313 0 : out:
314 0 : if (vam->retval == -99)
315 0 : errmsg ("timeout");
316 :
317 0 : if (vam->async_errors > 0)
318 : {
319 0 : errmsg ("%d asynchronous errors", vam->async_errors);
320 0 : vam->retval = -98;
321 : }
322 0 : vam->async_errors = 0;
323 0 : after = vat_time_now (vam);
324 :
325 0 : print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec", count,
326 0 : after - before, count / (after - before));
327 : }
328 : else
329 : {
330 : int ret;
331 :
332 : /* Wait for a reply... */
333 0 : W (ret);
334 0 : return ret;
335 : }
336 : /* Return the good/bad news */
337 0 : return (vam->retval);
338 : }
339 :
340 : static int
341 0 : api_l2fib_flush_int (vat_main_t *vam)
342 : {
343 0 : vnet_main_t *vnm = vnet_get_main ();
344 0 : unformat_input_t *i = vam->input;
345 : vl_api_l2fib_flush_int_t *mp;
346 0 : u32 sw_if_index = ~0;
347 : int ret;
348 :
349 : /* Parse args required to build the message */
350 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
351 : {
352 0 : if (unformat (i, "sw_if_index %d", &sw_if_index))
353 : ;
354 0 : else if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
355 : &sw_if_index))
356 : ;
357 : else
358 0 : break;
359 : }
360 :
361 0 : if (sw_if_index == ~0)
362 : {
363 0 : errmsg ("missing interface name or sw_if_index");
364 0 : return -99;
365 : }
366 :
367 0 : M (L2FIB_FLUSH_INT, mp);
368 :
369 0 : mp->sw_if_index = ntohl (sw_if_index);
370 :
371 0 : S (mp);
372 0 : W (ret);
373 0 : return ret;
374 : }
375 :
376 : static int
377 0 : api_l2_fib_clear_table (vat_main_t *vam)
378 : {
379 : vl_api_l2_fib_clear_table_t *mp;
380 : int ret;
381 :
382 0 : M (L2_FIB_CLEAR_TABLE, mp);
383 :
384 0 : S (mp);
385 0 : W (ret);
386 0 : return ret;
387 : }
388 :
389 : static int
390 0 : api_bridge_domain_set_mac_age (vat_main_t *vam)
391 : {
392 0 : unformat_input_t *i = vam->input;
393 : vl_api_bridge_domain_set_mac_age_t *mp;
394 0 : u32 bd_id = ~0;
395 0 : u32 mac_age = 0;
396 : int ret;
397 :
398 : /* Parse args required to build the message */
399 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
400 : {
401 0 : if (unformat (i, "bd_id %d", &bd_id))
402 : ;
403 0 : else if (unformat (i, "mac-age %d", &mac_age))
404 : ;
405 : else
406 0 : break;
407 : }
408 :
409 0 : if (bd_id == ~0)
410 : {
411 0 : errmsg ("missing bridge domain");
412 0 : return -99;
413 : }
414 :
415 0 : if (mac_age > 255)
416 : {
417 0 : errmsg ("mac age must be less than 256 ");
418 0 : return -99;
419 : }
420 :
421 0 : M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
422 :
423 0 : mp->bd_id = htonl (bd_id);
424 0 : mp->mac_age = (u8) mac_age;
425 :
426 0 : S (mp);
427 0 : W (ret);
428 0 : return ret;
429 : }
430 :
431 : static int
432 0 : api_l2fib_set_scan_delay (vat_main_t *vam)
433 : {
434 0 : return -1;
435 : }
436 :
437 : static int
438 0 : api_want_l2_macs_events2 (vat_main_t *vam)
439 : {
440 0 : return -1;
441 : }
442 :
443 : static int
444 0 : api_l2_flags (vat_main_t *vam)
445 : {
446 0 : vnet_main_t *vnm = vnet_get_main ();
447 0 : unformat_input_t *i = vam->input;
448 : vl_api_l2_flags_t *mp;
449 : u32 sw_if_index;
450 0 : u32 flags = 0;
451 0 : u8 sw_if_index_set = 0;
452 0 : u8 is_set = 0;
453 : int ret;
454 :
455 : /* Parse args required to build the message */
456 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
457 : {
458 0 : if (unformat (i, "sw_if_index %d", &sw_if_index))
459 0 : sw_if_index_set = 1;
460 0 : else if (unformat (i, "sw_if"))
461 : {
462 0 : if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
463 : {
464 0 : if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
465 : &sw_if_index))
466 0 : sw_if_index_set = 1;
467 : }
468 : else
469 0 : break;
470 : }
471 0 : else if (unformat (i, "learn"))
472 0 : flags |= L2_LEARN;
473 0 : else if (unformat (i, "forward"))
474 0 : flags |= L2_FWD;
475 0 : else if (unformat (i, "flood"))
476 0 : flags |= L2_FLOOD;
477 0 : else if (unformat (i, "uu-flood"))
478 0 : flags |= L2_UU_FLOOD;
479 0 : else if (unformat (i, "arp-term"))
480 0 : flags |= L2_ARP_TERM;
481 0 : else if (unformat (i, "off"))
482 0 : is_set = 0;
483 0 : else if (unformat (i, "disable"))
484 0 : is_set = 0;
485 : else
486 0 : break;
487 : }
488 :
489 0 : if (sw_if_index_set == 0)
490 : {
491 0 : errmsg ("missing interface name or sw_if_index");
492 0 : return -99;
493 : }
494 :
495 0 : M (L2_FLAGS, mp);
496 :
497 0 : mp->sw_if_index = ntohl (sw_if_index);
498 0 : mp->feature_bitmap = ntohl (flags);
499 0 : mp->is_set = is_set;
500 :
501 0 : S (mp);
502 0 : W (ret);
503 0 : return ret;
504 : }
505 :
506 : static void
507 0 : vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t *mp)
508 : {
509 0 : vat_main_t *vam = l2_test_main.vat_main;
510 0 : i32 retval = ntohl (mp->retval);
511 0 : if (vam->async_mode)
512 : {
513 0 : vam->async_errors += (retval < 0);
514 : }
515 : else
516 : {
517 0 : vam->retval = retval;
518 0 : vam->result_ready = 1;
519 : }
520 0 : }
521 :
522 : static int
523 0 : api_l2fib_flush_bd (vat_main_t *vam)
524 : {
525 0 : unformat_input_t *i = vam->input;
526 : vl_api_l2fib_flush_bd_t *mp;
527 0 : u32 bd_id = ~0;
528 : int ret;
529 :
530 : /* Parse args required to build the message */
531 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
532 : {
533 0 : if (unformat (i, "bd_id %d", &bd_id))
534 : ;
535 : else
536 0 : break;
537 : }
538 :
539 0 : if (bd_id == ~0)
540 : {
541 0 : errmsg ("missing bridge domain");
542 0 : return -99;
543 : }
544 :
545 0 : M (L2FIB_FLUSH_BD, mp);
546 :
547 0 : mp->bd_id = htonl (bd_id);
548 :
549 0 : S (mp);
550 0 : W (ret);
551 0 : return ret;
552 : }
553 :
554 : static int
555 0 : api_bridge_domain_add_del (vat_main_t *vam)
556 : {
557 0 : unformat_input_t *i = vam->input;
558 : vl_api_bridge_domain_add_del_t *mp;
559 0 : u32 bd_id = ~0;
560 0 : u8 is_add = 1;
561 0 : u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
562 0 : u8 *bd_tag = NULL;
563 0 : u32 mac_age = 0;
564 : int ret;
565 :
566 : /* Parse args required to build the message */
567 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
568 : {
569 0 : if (unformat (i, "bd_id %d", &bd_id))
570 : ;
571 0 : else if (unformat (i, "flood %d", &flood))
572 : ;
573 0 : else if (unformat (i, "uu-flood %d", &uu_flood))
574 : ;
575 0 : else if (unformat (i, "forward %d", &forward))
576 : ;
577 0 : else if (unformat (i, "learn %d", &learn))
578 : ;
579 0 : else if (unformat (i, "arp-term %d", &arp_term))
580 : ;
581 0 : else if (unformat (i, "mac-age %d", &mac_age))
582 : ;
583 0 : else if (unformat (i, "bd-tag %s", &bd_tag))
584 : ;
585 0 : else if (unformat (i, "del"))
586 : {
587 0 : is_add = 0;
588 0 : flood = uu_flood = forward = learn = 0;
589 : }
590 : else
591 0 : break;
592 : }
593 :
594 0 : if (bd_id == ~0)
595 : {
596 0 : errmsg ("missing bridge domain");
597 0 : ret = -99;
598 0 : goto done;
599 : }
600 :
601 0 : if (mac_age > 255)
602 : {
603 0 : errmsg ("mac age must be less than 256 ");
604 0 : ret = -99;
605 0 : goto done;
606 : }
607 :
608 0 : if ((bd_tag) && (vec_len (bd_tag) > 63))
609 : {
610 0 : errmsg ("bd-tag cannot be longer than 63");
611 0 : ret = -99;
612 0 : goto done;
613 : }
614 :
615 0 : M (BRIDGE_DOMAIN_ADD_DEL, mp);
616 :
617 0 : mp->bd_id = ntohl (bd_id);
618 0 : mp->flood = flood;
619 0 : mp->uu_flood = uu_flood;
620 0 : mp->forward = forward;
621 0 : mp->learn = learn;
622 0 : mp->arp_term = arp_term;
623 0 : mp->is_add = is_add;
624 0 : mp->mac_age = (u8) mac_age;
625 0 : if (bd_tag)
626 : {
627 0 : clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
628 0 : mp->bd_tag[vec_len (bd_tag)] = 0;
629 : }
630 0 : S (mp);
631 0 : W (ret);
632 :
633 0 : done:
634 0 : vec_free (bd_tag);
635 0 : return ret;
636 : }
637 :
638 : static int
639 0 : api_bridge_domain_add_del_v2 (vat_main_t *vam)
640 : {
641 0 : return -1;
642 : }
643 :
644 : static void
645 0 : vl_api_bridge_domain_add_del_v2_reply_t_handler (
646 : vl_api_bridge_domain_add_del_v2_reply_t *mp)
647 : {
648 0 : }
649 :
650 : #define foreach_pbb_vtr_op \
651 : _ ("disable", L2_VTR_DISABLED) \
652 : _ ("pop", L2_VTR_POP_2) \
653 : _ ("push", L2_VTR_PUSH_2)
654 :
655 : static int
656 0 : api_l2_interface_pbb_tag_rewrite (vat_main_t *vam)
657 : {
658 0 : vnet_main_t *vnm = vnet_get_main ();
659 0 : unformat_input_t *i = vam->input;
660 : vl_api_l2_interface_pbb_tag_rewrite_t *mp;
661 0 : u32 sw_if_index = ~0, vtr_op = ~0;
662 0 : u16 outer_tag = ~0;
663 : u8 dmac[6], smac[6];
664 0 : u8 dmac_set = 0, smac_set = 0;
665 0 : u16 vlanid = 0;
666 0 : u32 sid = ~0;
667 : u32 tmp;
668 : int ret;
669 :
670 : /* Shut up coverity */
671 0 : clib_memset (dmac, 0, sizeof (dmac));
672 0 : clib_memset (smac, 0, sizeof (smac));
673 :
674 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
675 : {
676 0 : if (unformat (i, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
677 : ;
678 0 : else if (unformat (i, "sw_if_index %d", &sw_if_index))
679 : ;
680 0 : else if (unformat (i, "vtr_op %d", &vtr_op))
681 : ;
682 : #define _(n, v) \
683 : else if (unformat (i, n)) { vtr_op = v; }
684 0 : foreach_pbb_vtr_op
685 : #undef _
686 0 : else if (unformat (i, "translate_pbb_stag"))
687 : {
688 0 : if (unformat (i, "%d", &tmp))
689 : {
690 0 : vtr_op = L2_VTR_TRANSLATE_2_1;
691 0 : outer_tag = tmp;
692 : }
693 : else
694 : {
695 0 : errmsg (
696 : "translate_pbb_stag operation requires outer tag definition");
697 0 : return -99;
698 : }
699 : }
700 0 : else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
701 0 : dmac_set++;
702 0 : else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
703 0 : smac_set++;
704 0 : else if (unformat (i, "sid %d", &sid));
705 0 : else if (unformat (i, "vlanid %d", &tmp)) vlanid = tmp;
706 : else
707 : {
708 0 : clib_warning ("parse error '%U'", format_unformat_error, i);
709 0 : return -99;
710 : }
711 : }
712 :
713 0 : if ((sw_if_index == ~0) || (vtr_op == ~0))
714 : {
715 0 : errmsg ("missing sw_if_index or vtr operation");
716 0 : return -99;
717 : }
718 0 : if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2)) &&
719 0 : ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
720 : {
721 0 : errmsg ("push and translate_qinq operations require dmac, smac, sid and "
722 : "optionally vlanid");
723 0 : return -99;
724 : }
725 :
726 0 : M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
727 0 : mp->sw_if_index = ntohl (sw_if_index);
728 0 : mp->vtr_op = ntohl (vtr_op);
729 0 : mp->outer_tag = ntohs (outer_tag);
730 0 : clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
731 0 : clib_memcpy (mp->b_smac, smac, sizeof (smac));
732 0 : mp->b_vlanid = ntohs (vlanid);
733 0 : mp->i_sid = ntohl (sid);
734 :
735 0 : S (mp);
736 0 : W (ret);
737 0 : return ret;
738 : }
739 :
740 : static int
741 0 : api_sw_interface_set_l2_xconnect (vat_main_t *vam)
742 : {
743 0 : vnet_main_t *vnm = vnet_get_main ();
744 0 : unformat_input_t *i = vam->input;
745 : vl_api_sw_interface_set_l2_xconnect_t *mp;
746 : u32 rx_sw_if_index;
747 0 : u8 rx_sw_if_index_set = 0;
748 : u32 tx_sw_if_index;
749 0 : u8 tx_sw_if_index_set = 0;
750 0 : u8 enable = 1;
751 : int ret;
752 :
753 : /* Parse args required to build the message */
754 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
755 : {
756 0 : if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
757 0 : rx_sw_if_index_set = 1;
758 0 : else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
759 0 : tx_sw_if_index_set = 1;
760 0 : else if (unformat (i, "rx"))
761 : {
762 0 : if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
763 : {
764 0 : if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
765 : &rx_sw_if_index))
766 0 : rx_sw_if_index_set = 1;
767 : }
768 : else
769 0 : break;
770 : }
771 0 : else if (unformat (i, "tx"))
772 : {
773 0 : if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
774 : {
775 0 : if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
776 : &tx_sw_if_index))
777 0 : tx_sw_if_index_set = 1;
778 : }
779 : else
780 0 : break;
781 : }
782 0 : else if (unformat (i, "enable"))
783 0 : enable = 1;
784 0 : else if (unformat (i, "disable"))
785 0 : enable = 0;
786 : else
787 0 : break;
788 : }
789 :
790 0 : if (rx_sw_if_index_set == 0)
791 : {
792 0 : errmsg ("missing rx interface name or rx_sw_if_index");
793 0 : return -99;
794 : }
795 :
796 0 : if (enable && (tx_sw_if_index_set == 0))
797 : {
798 0 : errmsg ("missing tx interface name or tx_sw_if_index");
799 0 : return -99;
800 : }
801 :
802 0 : M (SW_INTERFACE_SET_L2_XCONNECT, mp);
803 :
804 0 : mp->rx_sw_if_index = ntohl (rx_sw_if_index);
805 0 : mp->tx_sw_if_index = ntohl (tx_sw_if_index);
806 0 : mp->enable = enable;
807 :
808 0 : S (mp);
809 0 : W (ret);
810 0 : return ret;
811 : }
812 :
813 : static int
814 0 : api_l2_interface_efp_filter (vat_main_t *vam)
815 : {
816 0 : vnet_main_t *vnm = vnet_get_main ();
817 0 : unformat_input_t *i = vam->input;
818 : vl_api_l2_interface_efp_filter_t *mp;
819 : u32 sw_if_index;
820 0 : u8 enable = 1;
821 0 : u8 sw_if_index_set = 0;
822 : int ret;
823 :
824 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
825 : {
826 0 : if (unformat (i, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
827 0 : sw_if_index_set = 1;
828 0 : else if (unformat (i, "sw_if_index %d", &sw_if_index))
829 0 : sw_if_index_set = 1;
830 0 : else if (unformat (i, "enable"))
831 0 : enable = 1;
832 0 : else if (unformat (i, "disable"))
833 0 : enable = 0;
834 : else
835 : {
836 0 : clib_warning ("parse error '%U'", format_unformat_error, i);
837 0 : return -99;
838 : }
839 : }
840 :
841 0 : if (sw_if_index_set == 0)
842 : {
843 0 : errmsg ("missing sw_if_index");
844 0 : return -99;
845 : }
846 :
847 0 : M (L2_INTERFACE_EFP_FILTER, mp);
848 :
849 0 : mp->sw_if_index = ntohl (sw_if_index);
850 0 : mp->enable_disable = enable;
851 :
852 0 : S (mp);
853 0 : W (ret);
854 0 : return ret;
855 : }
856 :
857 : static void
858 0 : vl_api_bd_ip_mac_details_t_handler (vl_api_bd_ip_mac_details_t *mp)
859 : {
860 0 : vat_main_t *vam = &vat_main;
861 :
862 0 : print (vam->ofp, "\n%-5d %U %U", ntohl (mp->entry.bd_id),
863 0 : format_vl_api_mac_address, mp->entry.mac, format_vl_api_address,
864 : &mp->entry.ip);
865 0 : }
866 :
867 : static void
868 0 : vl_api_bvi_create_reply_t_handler (vl_api_bvi_create_reply_t *mp)
869 : {
870 0 : }
871 :
872 : static int
873 0 : api_sw_interface_set_l2_bridge (vat_main_t *vam)
874 : {
875 0 : vnet_main_t *vnm = vnet_get_main ();
876 0 : unformat_input_t *i = vam->input;
877 : vl_api_sw_interface_set_l2_bridge_t *mp;
878 : vl_api_l2_port_type_t port_type;
879 : u32 rx_sw_if_index;
880 0 : u8 rx_sw_if_index_set = 0;
881 : u32 bd_id;
882 0 : u8 bd_id_set = 0;
883 0 : u32 shg = 0;
884 0 : u8 enable = 1;
885 : int ret;
886 :
887 0 : port_type = L2_API_PORT_TYPE_NORMAL;
888 :
889 : /* Parse args required to build the message */
890 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
891 : {
892 0 : if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
893 0 : rx_sw_if_index_set = 1;
894 0 : else if (unformat (i, "bd_id %d", &bd_id))
895 0 : bd_id_set = 1;
896 0 : else if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
897 : &rx_sw_if_index))
898 0 : rx_sw_if_index_set = 1;
899 0 : else if (unformat (i, "shg %d", &shg))
900 : ;
901 0 : else if (unformat (i, "bvi"))
902 0 : port_type = L2_API_PORT_TYPE_BVI;
903 0 : else if (unformat (i, "uu-fwd"))
904 0 : port_type = L2_API_PORT_TYPE_UU_FWD;
905 0 : else if (unformat (i, "enable"))
906 0 : enable = 1;
907 0 : else if (unformat (i, "disable"))
908 0 : enable = 0;
909 : else
910 0 : break;
911 : }
912 :
913 0 : if (rx_sw_if_index_set == 0)
914 : {
915 0 : errmsg ("missing rx interface name or sw_if_index");
916 0 : return -99;
917 : }
918 :
919 0 : if (enable && (bd_id_set == 0))
920 : {
921 0 : errmsg ("missing bridge domain");
922 0 : return -99;
923 : }
924 :
925 0 : M (SW_INTERFACE_SET_L2_BRIDGE, mp);
926 :
927 0 : mp->rx_sw_if_index = ntohl (rx_sw_if_index);
928 0 : mp->bd_id = ntohl (bd_id);
929 0 : mp->shg = (u8) shg;
930 0 : mp->port_type = ntohl (port_type);
931 0 : mp->enable = enable;
932 :
933 0 : S (mp);
934 0 : W (ret);
935 0 : return ret;
936 : }
937 :
938 : static int
939 0 : api_sw_interface_set_vpath (vat_main_t *vam)
940 : {
941 0 : vnet_main_t *vnm = vnet_get_main ();
942 0 : unformat_input_t *i = vam->input;
943 : vl_api_sw_interface_set_vpath_t *mp;
944 0 : u32 sw_if_index = 0;
945 0 : u8 sw_if_index_set = 0;
946 0 : u8 is_enable = 0;
947 : int ret;
948 :
949 : /* Parse args required to build the message */
950 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
951 : {
952 0 : if (unformat (i, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
953 0 : sw_if_index_set = 1;
954 0 : else if (unformat (i, "sw_if_index %d", &sw_if_index))
955 0 : sw_if_index_set = 1;
956 0 : else if (unformat (i, "enable"))
957 0 : is_enable = 1;
958 0 : else if (unformat (i, "disable"))
959 0 : is_enable = 0;
960 : else
961 0 : break;
962 : }
963 :
964 0 : if (sw_if_index_set == 0)
965 : {
966 0 : errmsg ("missing interface name or sw_if_index");
967 0 : return -99;
968 : }
969 :
970 : /* Construct the API message */
971 0 : M (SW_INTERFACE_SET_VPATH, mp);
972 :
973 0 : mp->sw_if_index = ntohl (sw_if_index);
974 0 : mp->enable = is_enable;
975 :
976 : /* send it... */
977 0 : S (mp);
978 :
979 : /* Wait for a reply... */
980 0 : W (ret);
981 0 : return ret;
982 : }
983 :
984 : static int
985 0 : api_l2_patch_add_del (vat_main_t *vam)
986 : {
987 0 : vnet_main_t *vnm = vnet_get_main ();
988 0 : unformat_input_t *i = vam->input;
989 : vl_api_l2_patch_add_del_t *mp;
990 : u32 rx_sw_if_index;
991 0 : u8 rx_sw_if_index_set = 0;
992 : u32 tx_sw_if_index;
993 0 : u8 tx_sw_if_index_set = 0;
994 0 : u8 is_add = 1;
995 : int ret;
996 :
997 : /* Parse args required to build the message */
998 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
999 : {
1000 0 : if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
1001 0 : rx_sw_if_index_set = 1;
1002 0 : else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
1003 0 : tx_sw_if_index_set = 1;
1004 0 : else if (unformat (i, "rx"))
1005 : {
1006 0 : if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1007 : {
1008 0 : if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
1009 : &rx_sw_if_index))
1010 0 : rx_sw_if_index_set = 1;
1011 : }
1012 : else
1013 0 : break;
1014 : }
1015 0 : else if (unformat (i, "tx"))
1016 : {
1017 0 : if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1018 : {
1019 0 : if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
1020 : &tx_sw_if_index))
1021 0 : tx_sw_if_index_set = 1;
1022 : }
1023 : else
1024 0 : break;
1025 : }
1026 0 : else if (unformat (i, "del"))
1027 0 : is_add = 0;
1028 : else
1029 0 : break;
1030 : }
1031 :
1032 0 : if (rx_sw_if_index_set == 0)
1033 : {
1034 0 : errmsg ("missing rx interface name or rx_sw_if_index");
1035 0 : return -99;
1036 : }
1037 :
1038 0 : if (tx_sw_if_index_set == 0)
1039 : {
1040 0 : errmsg ("missing tx interface name or tx_sw_if_index");
1041 0 : return -99;
1042 : }
1043 :
1044 0 : M (L2_PATCH_ADD_DEL, mp);
1045 :
1046 0 : mp->rx_sw_if_index = ntohl (rx_sw_if_index);
1047 0 : mp->tx_sw_if_index = ntohl (tx_sw_if_index);
1048 0 : mp->is_add = is_add;
1049 :
1050 0 : S (mp);
1051 0 : W (ret);
1052 0 : return ret;
1053 : }
1054 :
1055 : static void
1056 0 : vl_api_bridge_flags_reply_t_handler (vl_api_bridge_flags_reply_t *mp)
1057 : {
1058 0 : vat_main_t *vam = &vat_main;
1059 0 : i32 retval = ntohl (mp->retval);
1060 0 : if (vam->async_mode)
1061 : {
1062 0 : vam->async_errors += (retval < 0);
1063 : }
1064 : else
1065 : {
1066 0 : vam->retval = retval;
1067 0 : vam->result_ready = 1;
1068 : }
1069 0 : }
1070 :
1071 : #define foreach_vtr_op \
1072 : _ ("disable", L2_VTR_DISABLED) \
1073 : _ ("push-1", L2_VTR_PUSH_1) \
1074 : _ ("push-2", L2_VTR_PUSH_2) \
1075 : _ ("pop-1", L2_VTR_POP_1) \
1076 : _ ("pop-2", L2_VTR_POP_2) \
1077 : _ ("translate-1-1", L2_VTR_TRANSLATE_1_1) \
1078 : _ ("translate-1-2", L2_VTR_TRANSLATE_1_2) \
1079 : _ ("translate-2-1", L2_VTR_TRANSLATE_2_1) \
1080 : _ ("translate-2-2", L2_VTR_TRANSLATE_2_2)
1081 :
1082 : static int
1083 0 : api_l2_interface_vlan_tag_rewrite (vat_main_t *vam)
1084 : {
1085 0 : vnet_main_t *vnm = vnet_get_main ();
1086 0 : unformat_input_t *i = vam->input;
1087 : vl_api_l2_interface_vlan_tag_rewrite_t *mp;
1088 : u32 sw_if_index;
1089 0 : u8 sw_if_index_set = 0;
1090 0 : u8 vtr_op_set = 0;
1091 0 : u32 vtr_op = 0;
1092 0 : u32 push_dot1q = 1;
1093 0 : u32 tag1 = ~0;
1094 0 : u32 tag2 = ~0;
1095 : int ret;
1096 :
1097 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1098 : {
1099 0 : if (unformat (i, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
1100 0 : sw_if_index_set = 1;
1101 0 : else if (unformat (i, "sw_if_index %d", &sw_if_index))
1102 0 : sw_if_index_set = 1;
1103 0 : else if (unformat (i, "vtr_op %d", &vtr_op))
1104 0 : vtr_op_set = 1;
1105 : #define _(n, v) \
1106 : else if (unformat (i, n)) \
1107 : { \
1108 : vtr_op = v; \
1109 : vtr_op_set = 1; \
1110 : }
1111 0 : foreach_vtr_op
1112 : #undef _
1113 0 : else if (unformat (i, "push_dot1q %d", &push_dot1q));
1114 0 : else if (unformat (i, "tag1 %d", &tag1));
1115 0 : else if (unformat (i, "tag2 %d", &tag2));
1116 : else
1117 : {
1118 0 : clib_warning ("parse error '%U'", format_unformat_error, i);
1119 0 : return -99;
1120 : }
1121 : }
1122 :
1123 0 : if ((sw_if_index_set == 0) || (vtr_op_set == 0))
1124 : {
1125 0 : errmsg ("missing vtr operation or sw_if_index");
1126 0 : return -99;
1127 : }
1128 :
1129 0 : M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
1130 0 : mp->sw_if_index = ntohl (sw_if_index);
1131 0 : mp->vtr_op = ntohl (vtr_op);
1132 0 : mp->push_dot1q = ntohl (push_dot1q);
1133 0 : mp->tag1 = ntohl (tag1);
1134 0 : mp->tag2 = ntohl (tag2);
1135 :
1136 0 : S (mp);
1137 0 : W (ret);
1138 0 : return ret;
1139 : }
1140 :
1141 : static int
1142 0 : api_bridge_domain_set_learn_limit (vat_main_t *vam)
1143 : {
1144 0 : return -1;
1145 : }
1146 :
1147 : static int
1148 0 : api_bd_ip_mac_add_del (vat_main_t *vam)
1149 : {
1150 0 : vl_api_address_t ip = VL_API_ZERO_ADDRESS;
1151 0 : vl_api_mac_address_t mac = { 0 };
1152 0 : unformat_input_t *i = vam->input;
1153 : vl_api_bd_ip_mac_add_del_t *mp;
1154 : u32 bd_id;
1155 0 : u8 is_add = 1;
1156 0 : u8 bd_id_set = 0;
1157 0 : u8 ip_set = 0;
1158 0 : u8 mac_set = 0;
1159 : int ret;
1160 :
1161 : /* Parse args required to build the message */
1162 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1163 : {
1164 0 : if (unformat (i, "bd_id %d", &bd_id))
1165 : {
1166 0 : bd_id_set++;
1167 : }
1168 0 : else if (unformat (i, "%U", unformat_vl_api_address, &ip))
1169 : {
1170 0 : ip_set++;
1171 : }
1172 0 : else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
1173 : {
1174 0 : mac_set++;
1175 : }
1176 0 : else if (unformat (i, "del"))
1177 0 : is_add = 0;
1178 : else
1179 0 : break;
1180 : }
1181 :
1182 0 : if (bd_id_set == 0)
1183 : {
1184 0 : errmsg ("missing bridge domain");
1185 0 : return -99;
1186 : }
1187 0 : else if (ip_set == 0)
1188 : {
1189 0 : errmsg ("missing IP address");
1190 0 : return -99;
1191 : }
1192 0 : else if (mac_set == 0)
1193 : {
1194 0 : errmsg ("missing MAC address");
1195 0 : return -99;
1196 : }
1197 :
1198 0 : M (BD_IP_MAC_ADD_DEL, mp);
1199 :
1200 0 : mp->entry.bd_id = ntohl (bd_id);
1201 0 : mp->is_add = is_add;
1202 :
1203 0 : clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
1204 0 : clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
1205 :
1206 0 : S (mp);
1207 0 : W (ret);
1208 0 : return ret;
1209 : }
1210 :
1211 : static void
1212 0 : vl_api_bridge_domain_details_t_handler (vl_api_bridge_domain_details_t *mp)
1213 : {
1214 0 : vat_main_t *vam = l2_test_main.vat_main;
1215 0 : u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1216 : int i;
1217 :
1218 0 : print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s", " ID", "LRN", "FWD",
1219 : "FLD", "BVI", "UU-FWD", "#IF");
1220 :
1221 0 : print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d", ntohl (mp->bd_id), mp->learn,
1222 0 : mp->forward, mp->flood, ntohl (mp->bvi_sw_if_index),
1223 : ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1224 :
1225 0 : if (n_sw_ifs)
1226 : {
1227 : vl_api_bridge_domain_sw_if_t *sw_ifs;
1228 0 : print (vam->ofp, "\n\n%s %s %s", "sw_if_index", "SHG",
1229 : "Interface Name");
1230 :
1231 0 : sw_ifs = mp->sw_if_details;
1232 0 : for (i = 0; i < n_sw_ifs; i++)
1233 : {
1234 0 : u8 *sw_if_name = 0;
1235 : u32 sw_if_index;
1236 : hash_pair_t *p;
1237 :
1238 0 : sw_if_index = ntohl (sw_ifs->sw_if_index);
1239 :
1240 0 : hash_foreach_pair (p, vam->sw_if_index_by_interface_name, ({
1241 : if ((u32) p->value[0] == sw_if_index)
1242 : {
1243 : sw_if_name = (u8 *) (p->key);
1244 : break;
1245 : }
1246 : }));
1247 0 : print (vam->ofp, "%7d %3d %s", sw_if_index, sw_ifs->shg,
1248 : sw_if_name ? (char *) sw_if_name : "sw_if_index not found!");
1249 :
1250 0 : sw_ifs++;
1251 : }
1252 : }
1253 0 : }
1254 :
1255 : static int
1256 0 : api_bridge_domain_dump (vat_main_t *vam)
1257 : {
1258 0 : unformat_input_t *i = vam->input;
1259 : vl_api_bridge_domain_dump_t *mp;
1260 : vl_api_control_ping_t *mp_ping;
1261 0 : u32 bd_id = ~0;
1262 : int ret;
1263 :
1264 : /* Parse args required to build the message */
1265 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1266 : {
1267 0 : if (unformat (i, "bd_id %d", &bd_id))
1268 : ;
1269 : else
1270 0 : break;
1271 : }
1272 :
1273 0 : M (BRIDGE_DOMAIN_DUMP, mp);
1274 0 : mp->bd_id = ntohl (bd_id);
1275 0 : S (mp);
1276 :
1277 : /* Use a control ping for synchronization */
1278 0 : PING (&l2_test_main, mp_ping);
1279 0 : S (mp_ping);
1280 :
1281 0 : W (ret);
1282 0 : return ret;
1283 : }
1284 :
1285 : static int
1286 0 : api_bridge_domain_set_default_learn_limit (vat_main_t *vam)
1287 : {
1288 0 : return -1;
1289 : }
1290 :
1291 : static int
1292 0 : api_bd_ip_mac_flush (vat_main_t *vam)
1293 : {
1294 0 : unformat_input_t *i = vam->input;
1295 : vl_api_bd_ip_mac_flush_t *mp;
1296 : u32 bd_id;
1297 0 : u8 bd_id_set = 0;
1298 : int ret;
1299 :
1300 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1301 : {
1302 0 : if (unformat (i, "bd_id %d", &bd_id))
1303 : {
1304 0 : bd_id_set++;
1305 : }
1306 : else
1307 0 : break;
1308 : }
1309 :
1310 0 : if (bd_id_set == 0)
1311 : {
1312 0 : errmsg ("missing bridge domain");
1313 0 : return -99;
1314 : }
1315 :
1316 0 : M (BD_IP_MAC_FLUSH, mp);
1317 :
1318 0 : mp->bd_id = ntohl (bd_id);
1319 :
1320 0 : S (mp);
1321 0 : W (ret);
1322 0 : return ret;
1323 : }
1324 :
1325 : static int
1326 0 : api_bd_ip_mac_dump (vat_main_t *vam)
1327 : {
1328 0 : unformat_input_t *i = vam->input;
1329 : vl_api_bd_ip_mac_dump_t *mp;
1330 : vl_api_control_ping_t *mp_ping;
1331 : int ret;
1332 : u32 bd_id;
1333 0 : u8 bd_id_set = 0;
1334 :
1335 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1336 : {
1337 0 : if (unformat (i, "bd_id %d", &bd_id))
1338 : {
1339 0 : bd_id_set++;
1340 : }
1341 : else
1342 0 : break;
1343 : }
1344 :
1345 0 : fformat (vam->ofp, "\n%-5s %-7s %-20s %-30s", "bd_id", "is_ipv6",
1346 : "mac_address", "ip_address");
1347 :
1348 : /* Dump Bridge Domain Ip to Mac entries */
1349 0 : M (BD_IP_MAC_DUMP, mp);
1350 :
1351 0 : if (bd_id_set)
1352 0 : mp->bd_id = htonl (bd_id);
1353 : else
1354 0 : mp->bd_id = ~0;
1355 :
1356 0 : S (mp);
1357 :
1358 : /* Use a control ping for synchronization */
1359 0 : PING (&l2_test_main, mp_ping);
1360 0 : S (mp_ping);
1361 :
1362 0 : W (ret);
1363 0 : return ret;
1364 : }
1365 :
1366 : static int
1367 0 : api_bvi_create (vat_main_t *vam)
1368 : {
1369 0 : return -1;
1370 : }
1371 :
1372 : static int
1373 0 : api_bvi_delete (vat_main_t *vam)
1374 : {
1375 0 : return -1;
1376 : }
1377 :
1378 : static int
1379 0 : api_bridge_flags (vat_main_t *vam)
1380 : {
1381 0 : unformat_input_t *i = vam->input;
1382 : vl_api_bridge_flags_t *mp;
1383 : u32 bd_id;
1384 0 : u8 bd_id_set = 0;
1385 0 : u8 is_set = 1;
1386 0 : bd_flags_t flags = 0;
1387 : int ret;
1388 :
1389 : /* Parse args required to build the message */
1390 0 : while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1391 : {
1392 0 : if (unformat (i, "bd_id %d", &bd_id))
1393 0 : bd_id_set = 1;
1394 0 : else if (unformat (i, "learn"))
1395 0 : flags |= BRIDGE_API_FLAG_LEARN;
1396 0 : else if (unformat (i, "forward"))
1397 0 : flags |= BRIDGE_API_FLAG_FWD;
1398 0 : else if (unformat (i, "flood"))
1399 0 : flags |= BRIDGE_API_FLAG_FLOOD;
1400 0 : else if (unformat (i, "uu-flood"))
1401 0 : flags |= BRIDGE_API_FLAG_UU_FLOOD;
1402 0 : else if (unformat (i, "arp-term"))
1403 0 : flags |= BRIDGE_API_FLAG_ARP_TERM;
1404 0 : else if (unformat (i, "off"))
1405 0 : is_set = 0;
1406 0 : else if (unformat (i, "disable"))
1407 0 : is_set = 0;
1408 : else
1409 0 : break;
1410 : }
1411 :
1412 0 : if (bd_id_set == 0)
1413 : {
1414 0 : errmsg ("missing bridge domain");
1415 0 : return -99;
1416 : }
1417 :
1418 0 : M (BRIDGE_FLAGS, mp);
1419 :
1420 0 : mp->bd_id = ntohl (bd_id);
1421 0 : mp->flags = ntohl (flags);
1422 0 : mp->is_set = is_set;
1423 :
1424 0 : S (mp);
1425 0 : W (ret);
1426 0 : return ret;
1427 : }
1428 :
1429 : #include <vnet/l2/l2.api_test.c>
1430 :
1431 : /*
1432 : * Local Variables:
1433 : * eval: (c-set-style "gnu")
1434 : * End:
1435 : */
|