FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
l2_bd.c
Go to the documentation of this file.
1 /*
2  * l2_bd.c : layer 2 bridge domain
3  *
4  * Copyright (c) 2013 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vlib/vlib.h>
19 #include <vnet/vnet.h>
20 #include <vlib/cli.h>
21 #include <vnet/ethernet/ethernet.h>
22 #include <vnet/ip/format.h>
23 #include <vnet/l2/l2_input.h>
24 #include <vnet/l2/feat_bitmap.h>
25 #include <vnet/l2/l2_bd.h>
26 #include <vnet/l2/l2_learn.h>
27 #include <vnet/l2/l2_fib.h>
28 #include <vnet/l2/l2_vtr.h>
29 #include <vnet/ip/ip4_packet.h>
30 #include <vnet/ip/ip6_packet.h>
31 
32 #include <vppinfra/error.h>
33 #include <vppinfra/hash.h>
34 #include <vppinfra/vec.h>
35 
36 /**
37  * @file
38  * @brief Ethernet Bridge Domain.
39  *
40  * Code in this file manages Layer 2 bridge domains.
41  *
42  */
43 
45 
46 /**
47  Init bridge domain if not done already.
48  For feature bitmap, set all bits except ARP termination
49 */
50 void
52 {
53  if (bd_is_valid (bd_config))
54  return;
55  bd_config->feature_bitmap =
56  ~(L2INPUT_FEAT_ARP_TERM | L2INPUT_FEAT_UU_FWD | L2INPUT_FEAT_ARP_UFWD);
57  bd_config->bvi_sw_if_index = ~0;
58  bd_config->uu_fwd_sw_if_index = ~0;
59  bd_config->members = 0;
60  bd_config->flood_count = 0;
61  bd_config->tun_master_count = 0;
62  bd_config->tun_normal_count = 0;
63  bd_config->no_flood_count = 0;
64  bd_config->mac_by_ip4 = 0;
65  bd_config->mac_by_ip6 = hash_create_mem (0, sizeof (ip6_address_t),
66  sizeof (uword));
67 }
68 
69 u32
71 {
72  u32 *p = (u32 *) hash_get (bdm->bd_index_by_bd_id, bd_id);
73  if (!p)
74  return ~0;
75  return p[0];
76 }
77 
78 u32
80 {
83 
84  /* mark this index taken */
86 
88 
94 
95  return rv;
96 }
97 
98 static inline void
100 {
101  u64 mac_addr;
102  ip6_address_t *ip6_addr_key;
103 
104  hash_free (bd->mac_by_ip4);
105  /* *INDENT-OFF* */
106  hash_foreach_mem (ip6_addr_key, mac_addr, bd->mac_by_ip6,
107  ({
108  clib_mem_free (ip6_addr_key); /* free memory used for ip6 addr key */
109  }));
110  /* *INDENT-ON* */
111  hash_free (bd->mac_by_ip6);
112 }
113 
114 static int
115 bd_delete (bd_main_t * bdm, u32 bd_index)
116 {
117  l2_bridge_domain_t *bd = &l2input_main.bd_configs[bd_index];
118  u32 bd_id = bd->bd_id;
119 
120  /* flush non-static MACs in BD and removed bd_id from hash table */
121  l2fib_flush_bd_mac (vlib_get_main (), bd_index);
123 
124  /* mark this index clear */
125  bdm->bd_index_bitmap = clib_bitmap_set (bdm->bd_index_bitmap, bd_index, 0);
126 
127  /* clear BD config for reuse: bd_id to -1 and clear feature_bitmap */
128  bd->bd_id = ~0;
129  bd->feature_bitmap = 0;
130  bd->learn_limit = 0;
131  bd->learn_count = ~0;
132 
133  /* free BD tag */
134  vec_free (bd->bd_tag);
135 
136  /* free memory used by BD */
137  vec_free (bd->members);
139 
140  return 0;
141 }
142 
143 static void
145 {
146  bd_config->flood_count = (vec_len (bd_config->members) -
147  (bd_config->tun_master_count ?
148  bd_config->tun_normal_count : 0));
149  bd_config->flood_count -= bd_config->no_flood_count;
150 }
151 
152 void
154 {
155  u32 ix = 0;
157  (vnet_get_main (), member->sw_if_index);
158 
159  /*
160  * Add one element to the vector
161  * vector is ordered [ bvi, normal/tun_masters..., tun_normals... no_flood]
162  * When flooding, the bvi interface (if present) must be the last member
163  * processed due to how BVI processing can change the packet. To enable
164  * this order, we make the bvi interface the first in the vector and
165  * flooding walks the vector in reverse. The flood-count determines where
166  * in the member list to start the walk from.
167  */
168  switch (sw_if->flood_class)
169  {
171  bd_config->no_flood_count++;
172  ix = vec_len (bd_config->members);
173  break;
175  ix = 0;
176  break;
178  bd_config->tun_master_count++;
179  /* Fall through */
181  ix = (vec_len (bd_config->members) -
182  bd_config->tun_normal_count - bd_config->no_flood_count);
183  break;
185  ix = (vec_len (bd_config->members) - bd_config->no_flood_count);
186  bd_config->tun_normal_count++;
187  break;
188  }
189 
190  vec_insert_elts (bd_config->members, member, 1, ix);
191  update_flood_count (bd_config);
192 }
193 
194 #define BD_REMOVE_ERROR_OK 0
195 #define BD_REMOVE_ERROR_NOT_FOUND 1
196 
197 u32
199 {
200  u32 ix;
201 
202  /* Find and delete the member */
203  vec_foreach_index (ix, bd_config->members)
204  {
205  l2_flood_member_t *m = vec_elt_at_index (bd_config->members, ix);
206  if (m->sw_if_index == sw_if_index)
207  {
210 
211  if (sw_if->flood_class != VNET_FLOOD_CLASS_NORMAL)
212  {
214  bd_config->tun_master_count--;
215  else if (sw_if->flood_class == VNET_FLOOD_CLASS_TUNNEL_NORMAL)
216  bd_config->tun_normal_count--;
217  else if (sw_if->flood_class == VNET_FLOOD_CLASS_NO_FLOOD)
218  bd_config->no_flood_count--;
219  }
220  vec_delete (bd_config->members, 1, ix);
221  update_flood_count (bd_config);
222 
223  return BD_REMOVE_ERROR_OK;
224  }
225  }
226 
228 }
229 
230 
231 clib_error_t *
233 {
234  bd_main_t *bdm = &bd_main;
235  bdm->bd_index_by_bd_id = hash_create (0, sizeof (uword));
236  /*
237  * create a placeholder bd with bd_id of 0 and bd_index of 0 with feature set
238  * to packet drop only. Thus, packets received from any L2 interface with
239  * uninitialized bd_index of 0 can be dropped safely.
240  */
241  u32 bd_index = bd_add_bd_index (bdm, 0);
242  ASSERT (bd_index == 0);
243  l2input_main.bd_configs[0].feature_bitmap = L2INPUT_FEAT_DROP;
244 
245  bdm->vlib_main = vm;
246  return 0;
247 }
248 
250 
252 bd_get (u32 bd_index)
253 {
254  if (bd_index < vec_len (l2input_main.bd_configs))
255  return (vec_elt_at_index (l2input_main.bd_configs, bd_index));
256  return (NULL);
257 }
258 
259 u32
261 {
262  l2_flood_member_t *member;
263  l2_bridge_domain_t *bd;
265 
266  sw_if_index = ~0;
267  bd = bd_get (bd_index);
268 
269  ASSERT (bd);
270 
271  vec_foreach (member, bd->members)
272  {
273  if (WALK_STOP == fn (bd_index, member->sw_if_index))
274  {
275  sw_if_index = member->sw_if_index;
276  break;
277  }
278  }
279 
280  return (sw_if_index);
281 }
282 
283 static void
285 {
286  bd_input_walk (bd_index, l2input_recache, NULL);
287 }
288 
289 /**
290  Set the learn/forward/flood flags for the bridge domain.
291  Return 0 if ok, non-zero if for an error.
292 */
293 u32
295 {
296 
297  l2_bridge_domain_t *bd_config = l2input_bd_config (bd_index);
298  bd_validate (bd_config);
299  u32 feature_bitmap = 0;
300 
301  if (flags & L2_LEARN)
302  {
303  feature_bitmap |= L2INPUT_FEAT_LEARN;
304  }
305  if (flags & L2_FWD)
306  {
307  feature_bitmap |= L2INPUT_FEAT_FWD;
308  }
309  if (flags & L2_FLOOD)
310  {
311  feature_bitmap |= L2INPUT_FEAT_FLOOD;
312  }
313  if (flags & L2_UU_FLOOD)
314  {
315  feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
316  }
317  if (flags & L2_ARP_TERM)
318  {
319  feature_bitmap |= L2INPUT_FEAT_ARP_TERM;
320  }
321  if (flags & L2_ARP_UFWD)
322  {
323  feature_bitmap |= L2INPUT_FEAT_ARP_UFWD;
324  }
325 
326  if (enable)
327  {
328  bd_config->feature_bitmap |= feature_bitmap;
329  }
330  else
331  {
332  bd_config->feature_bitmap &= ~feature_bitmap;
333  }
334 
335  b2_input_recache (bd_index);
336 
337  return bd_config->feature_bitmap;
338 }
339 
340 /**
341  Set the mac age for the bridge domain.
342 */
343 void
344 bd_set_mac_age (vlib_main_t * vm, u32 bd_index, u8 age)
345 {
346  l2_bridge_domain_t *bd_config;
347  int enable = 0;
348 
350  bd_config = vec_elt_at_index (l2input_main.bd_configs, bd_index);
351  bd_config->mac_age = age;
352  b2_input_recache (bd_index);
353 
354  /* check if there is at least one bd with mac aging enabled */
355  vec_foreach (bd_config, l2input_main.bd_configs)
356  enable |= bd_config->bd_id != ~0 && bd_config->mac_age != 0;
357 
361 }
362 
363 /**
364  Set learn limit for the bridge domain.
365 */
366 void
367 bd_set_learn_limit (vlib_main_t *vm, u32 bd_index, u32 learn_limit)
368 {
369  l2_bridge_domain_t *bd_config;
371  bd_config = vec_elt_at_index (l2input_main.bd_configs, bd_index);
372  bd_config->learn_limit = learn_limit;
373 }
374 
375 /**
376  Set the tag for the bridge domain.
377 */
378 static void
379 bd_set_bd_tag (vlib_main_t * vm, u32 bd_index, u8 * bd_tag)
380 {
381  u8 *old;
382  l2_bridge_domain_t *bd_config;
384  bd_config = vec_elt_at_index (l2input_main.bd_configs, bd_index);
385 
386  old = bd_config->bd_tag;
387 
388  if (bd_tag[0])
389  {
390  bd_config->bd_tag = format (0, "%s%c", bd_tag, 0);
391  }
392  else
393  {
394  bd_config->bd_tag = NULL;
395  }
396 
397  vec_free (old);
398 }
399 
400 /**
401  Set bridge-domain learn enable/disable.
402  The CLI format is:
403  set bridge-domain learn <bd_id> [disable]
404 */
405 static clib_error_t *
407  unformat_input_t * input, vlib_cli_command_t * cmd)
408 {
409  bd_main_t *bdm = &bd_main;
410  clib_error_t *error = 0;
411  u32 bd_index, bd_id;
412  u32 enable;
413  uword *p;
414 
415  if (!unformat (input, "%d", &bd_id))
416  {
417  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
418  format_unformat_error, input);
419  goto done;
420  }
421 
422  if (bd_id == 0)
423  return clib_error_return (0,
424  "No operations on the default bridge domain are supported");
425 
426  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
427 
428  if (p == 0)
429  return clib_error_return (0, "No such bridge domain %d", bd_id);
430 
431  bd_index = p[0];
432 
433  enable = 1;
434  if (unformat (input, "disable"))
435  {
436  enable = 0;
437  }
438 
439  /* set the bridge domain flag */
440  bd_set_flags (vm, bd_index, L2_LEARN, enable);
441 
442 done:
443  return error;
444 }
445 
446 /*?
447  * Layer 2 learning can be enabled and disabled on each
448  * interface and on each bridge-domain. Use this command to
449  * manage bridge-domains. It is enabled by default.
450  *
451  * @cliexpar
452  * Example of how to enable learning (where 200 is the bridge-domain-id):
453  * @cliexcmd{set bridge-domain learn 200}
454  * Example of how to disable learning (where 200 is the bridge-domain-id):
455  * @cliexcmd{set bridge-domain learn 200 disable}
456 ?*/
457 /* *INDENT-OFF* */
459  .path = "set bridge-domain learn",
460  .short_help = "set bridge-domain learn <bridge-domain-id> [disable]",
461  .function = bd_learn,
462 };
463 /* *INDENT-ON* */
464 
465 static clib_error_t *
467  vlib_cli_command_t *cmd)
468 {
470  clib_error_t *error = 0;
471  u32 learn_limit;
472 
473  if (!unformat (input, "%d", &learn_limit))
474  {
476  0, "expecting per bridge-domain max entry number got`%U'",
477  format_unformat_error, input);
478  goto done;
479  }
480 
481  l2m->bd_default_learn_limit = learn_limit;
482 
483 done:
484  return error;
485 }
486 
488  .path = "set bridge-domain default-learn-limit",
489  .short_help = "set bridge-domain default-learn-limit <maxentries>",
490  .function = bd_default_learn_limit,
491 };
492 
493 /**
494  Set bridge-domain forward enable/disable.
495  The CLI format is:
496  set bridge-domain forward <bd_index> [disable]
497 */
498 static clib_error_t *
500 {
501  bd_main_t *bdm = &bd_main;
502  clib_error_t *error = 0;
503  u32 bd_index, bd_id;
504  u32 enable;
505  uword *p;
506 
507  if (!unformat (input, "%d", &bd_id))
508  {
509  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
510  format_unformat_error, input);
511  goto done;
512  }
513 
514  if (bd_id == 0)
515  return clib_error_return (0,
516  "No operations on the default bridge domain are supported");
517 
518  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
519 
520  if (p == 0)
521  return clib_error_return (0, "No such bridge domain %d", bd_id);
522 
523  bd_index = p[0];
524 
525  enable = 1;
526  if (unformat (input, "disable"))
527  {
528  enable = 0;
529  }
530 
531  /* set the bridge domain flag */
532  bd_set_flags (vm, bd_index, L2_FWD, enable);
533 
534 done:
535  return error;
536 }
537 
538 
539 /*?
540  * Layer 2 unicast forwarding can be enabled and disabled on each
541  * interface and on each bridge-domain. Use this command to
542  * manage bridge-domains. It is enabled by default.
543  *
544  * @cliexpar
545  * Example of how to enable forwarding (where 200 is the bridge-domain-id):
546  * @cliexcmd{set bridge-domain forward 200}
547  * Example of how to disable forwarding (where 200 is the bridge-domain-id):
548  * @cliexcmd{set bridge-domain forward 200 disable}
549 ?*/
550 /* *INDENT-OFF* */
552  .path = "set bridge-domain forward",
553  .short_help = "set bridge-domain forward <bridge-domain-id> [disable]",
554  .function = bd_fwd,
555 };
556 /* *INDENT-ON* */
557 
558 /**
559  Set bridge-domain flood enable/disable.
560  The CLI format is:
561  set bridge-domain flood <bd_index> [disable]
562 */
563 static clib_error_t *
565  unformat_input_t * input, vlib_cli_command_t * cmd)
566 {
567  bd_main_t *bdm = &bd_main;
568  clib_error_t *error = 0;
569  u32 bd_index, bd_id;
570  u32 enable;
571  uword *p;
572 
573  if (!unformat (input, "%d", &bd_id))
574  {
575  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
576  format_unformat_error, input);
577  goto done;
578  }
579 
580  if (bd_id == 0)
581  return clib_error_return (0,
582  "No operations on the default bridge domain are supported");
583 
584  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
585 
586  if (p == 0)
587  return clib_error_return (0, "No such bridge domain %d", bd_id);
588 
589  bd_index = p[0];
590 
591  enable = 1;
592  if (unformat (input, "disable"))
593  {
594  enable = 0;
595  }
596 
597  /* set the bridge domain flag */
598  bd_set_flags (vm, bd_index, L2_FLOOD, enable);
599 
600 done:
601  return error;
602 }
603 
604 /*?
605  * Layer 2 flooding can be enabled and disabled on each
606  * interface and on each bridge-domain. Use this command to
607  * manage bridge-domains. It is enabled by default.
608  *
609  * @cliexpar
610  * Example of how to enable flooding (where 200 is the bridge-domain-id):
611  * @cliexcmd{set bridge-domain flood 200}
612  * Example of how to disable flooding (where 200 is the bridge-domain-id):
613  * @cliexcmd{set bridge-domain flood 200 disable}
614 ?*/
615 /* *INDENT-OFF* */
617  .path = "set bridge-domain flood",
618  .short_help = "set bridge-domain flood <bridge-domain-id> [disable]",
619  .function = bd_flood,
620 };
621 /* *INDENT-ON* */
622 
623 /**
624  Set bridge-domain unknown-unicast flood enable/disable.
625  The CLI format is:
626  set bridge-domain uu-flood <bd_index> [disable]
627 */
628 static clib_error_t *
630  unformat_input_t * input, vlib_cli_command_t * cmd)
631 {
632  bd_main_t *bdm = &bd_main;
633  clib_error_t *error = 0;
634  u32 bd_index, bd_id;
635  u32 enable;
636  uword *p;
637 
638  if (!unformat (input, "%d", &bd_id))
639  {
640  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
641  format_unformat_error, input);
642  goto done;
643  }
644 
645  if (bd_id == 0)
646  return clib_error_return (0,
647  "No operations on the default bridge domain are supported");
648 
649  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
650 
651  if (p == 0)
652  return clib_error_return (0, "No such bridge domain %d", bd_id);
653 
654  bd_index = p[0];
655 
656  enable = 1;
657  if (unformat (input, "disable"))
658  {
659  enable = 0;
660  }
661 
662  /* set the bridge domain flag */
663  bd_set_flags (vm, bd_index, L2_UU_FLOOD, enable);
664 
665 done:
666  return error;
667 }
668 
669 /*?
670  * Layer 2 unknown-unicast flooding can be enabled and disabled on each
671  * bridge-domain. It is enabled by default.
672  *
673  * @cliexpar
674  * Example of how to enable unknown-unicast flooding (where 200 is the
675  * bridge-domain-id):
676  * @cliexcmd{set bridge-domain uu-flood 200}
677  * Example of how to disable unknown-unicast flooding (where 200 is the bridge-domain-id):
678  * @cliexcmd{set bridge-domain uu-flood 200 disable}
679 ?*/
680 /* *INDENT-OFF* */
682  .path = "set bridge-domain uu-flood",
683  .short_help = "set bridge-domain uu-flood <bridge-domain-id> [disable]",
684  .function = bd_uu_flood,
685 };
686 /* *INDENT-ON* */
687 
688 /**
689  Set bridge-domain arp-unicast forward enable/disable.
690  The CLI format is:
691  set bridge-domain arp-ufwd <bd_index> [disable]
692 */
693 static clib_error_t *
695  unformat_input_t * input, vlib_cli_command_t * cmd)
696 {
697  bd_main_t *bdm = &bd_main;
698  clib_error_t *error = 0;
699  u32 bd_index, bd_id;
700  u32 enable;
701  uword *p;
702 
703  if (!unformat (input, "%d", &bd_id))
704  {
705  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
706  format_unformat_error, input);
707  goto done;
708  }
709 
710  if (bd_id == 0)
711  return clib_error_return (0,
712  "No operations on the default bridge domain are supported");
713 
714  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
715 
716  if (p == 0)
717  return clib_error_return (0, "No such bridge domain %d", bd_id);
718 
719  bd_index = p[0];
720 
721  enable = 1;
722  if (unformat (input, "disable"))
723  {
724  enable = 0;
725  }
726 
727  /* set the bridge domain flag */
728  bd_set_flags (vm, bd_index, L2_ARP_UFWD, enable);
729 
730 done:
731  return error;
732 }
733 
734 /*?
735  * Layer 2 arp-unicast forwarding can be enabled and disabled on each
736  * bridge-domain. It is disabled by default.
737  *
738  * @cliexpar
739  * Example of how to enable arp-unicast forwarding (where 200 is the
740  * bridge-domain-id):
741  * @cliexcmd{set bridge-domain arp-ufwd 200}
742  * Example of how to disable arp-unicast forwarding (where 200 is the bridge-domain-id):
743  * @cliexcmd{set bridge-domain arp-ufwd 200 disable}
744 ?*/
745 /* *INDENT-OFF* */
747  .path = "set bridge-domain arp-ufwd",
748  .short_help = "set bridge-domain arp-ufwd <bridge-domain-id> [disable]",
749  .function = bd_arp_ufwd,
750 };
751 /* *INDENT-ON* */
752 
753 /**
754  Set bridge-domain arp term enable/disable.
755  The CLI format is:
756  set bridge-domain arp term <bridge-domain-id> [disable]
757 */
758 static clib_error_t *
760  unformat_input_t * input, vlib_cli_command_t * cmd)
761 {
762  bd_main_t *bdm = &bd_main;
763  clib_error_t *error = 0;
764  u32 bd_index, bd_id;
765  u32 enable;
766  uword *p;
767 
768  if (!unformat (input, "%d", &bd_id))
769  {
770  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
771  format_unformat_error, input);
772  goto done;
773  }
774 
775  if (bd_id == 0)
776  return clib_error_return (0,
777  "No operations on the default bridge domain are supported");
778 
779  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
780  if (p)
781  bd_index = *p;
782  else
783  return clib_error_return (0, "No such bridge domain %d", bd_id);
784 
785  enable = 1;
786  if (unformat (input, "disable"))
787  enable = 0;
788 
789  /* set the bridge domain flag */
790  bd_set_flags (vm, bd_index, L2_ARP_TERM, enable);
791 
792 done:
793  return error;
794 }
795 
796 static clib_error_t *
798  unformat_input_t * input, vlib_cli_command_t * cmd)
799 {
800  bd_main_t *bdm = &bd_main;
801  clib_error_t *error = 0;
802  u32 bd_index, bd_id;
803  u32 age;
804  uword *p;
805 
806  if (!unformat (input, "%d", &bd_id))
807  {
808  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
809  format_unformat_error, input);
810  goto done;
811  }
812 
813  if (bd_id == 0)
814  return clib_error_return (0,
815  "No operations on the default bridge domain are supported");
816 
817  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
818 
819  if (p == 0)
820  return clib_error_return (0, "No such bridge domain %d", bd_id);
821 
822  bd_index = p[0];
823 
824  if (!unformat (input, "%u", &age))
825  {
826  error =
827  clib_error_return (0, "expecting ageing time in minutes but got `%U'",
828  format_unformat_error, input);
829  goto done;
830  }
831 
832  /* set the bridge domain flag */
833  if (age > 255)
834  {
835  error =
836  clib_error_return (0, "mac aging time cannot be bigger than 255");
837  goto done;
838  }
839  bd_set_mac_age (vm, bd_index, (u8) age);
840 
841 done:
842  return error;
843 }
844 
845 /*?
846  * Layer 2 mac aging can be enabled and disabled on each
847  * bridge-domain. Use this command to set or disable mac aging
848  * on specific bridge-domains. It is disabled by default.
849  *
850  * @cliexpar
851  * Example of how to set mac aging (where 200 is the bridge-domain-id and
852  * 5 is aging time in minutes):
853  * @cliexcmd{set bridge-domain mac-age 200 5}
854  * Example of how to disable mac aging (where 200 is the bridge-domain-id):
855  * @cliexcmd{set bridge-domain flood 200 0}
856 ?*/
857 /* *INDENT-OFF* */
859  .path = "set bridge-domain mac-age",
860  .short_help = "set bridge-domain mac-age <bridge-domain-id> <mins>",
861  .function = bd_mac_age,
862 };
863 /* *INDENT-ON* */
864 
865 static clib_error_t *
867  vlib_cli_command_t *cmd)
868 {
869  bd_main_t *bdm = &bd_main;
870  clib_error_t *error = 0;
871  u32 bd_index, bd_id;
872  u32 learn_limit;
873  uword *p;
874 
875  if (!unformat (input, "%d", &bd_id))
876  {
877  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
878  format_unformat_error, input);
879  goto done;
880  }
881 
882  if (bd_id == 0)
883  return clib_error_return (
884  0, "No operations on the default bridge domain are supported");
885 
886  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
887 
888  if (p == 0)
889  return clib_error_return (0, "No such bridge domain %d", bd_id);
890 
891  bd_index = p[0];
892 
893  if (!unformat (input, "%u", &learn_limit))
894  {
896  0, "expecting maxium number of learned entries but got `%U'",
897  format_unformat_error, input);
898  goto done;
899  }
900 
901  bd_set_learn_limit (vm, bd_index, learn_limit);
902 
903 done:
904  return error;
905 }
906 
908  .path = "set bridge-domain learn-limit",
909  .short_help =
910  "set bridge-domain learn-limit <bridge-domain-id> <learn-limit>",
911  .function = bd_learn_limit,
912 };
913 
914 /*?
915  * Modify whether or not an existing bridge-domain should terminate and respond
916  * to ARP Requests. ARP Termination is disabled by default.
917  *
918  * @cliexpar
919  * Example of how to enable ARP termination (where 200 is the bridge-domain-id):
920  * @cliexcmd{set bridge-domain arp term 200}
921  * Example of how to disable ARP termination (where 200 is the bridge-domain-id):
922  * @cliexcmd{set bridge-domain arp term 200 disable}
923 ?*/
924 /* *INDENT-OFF* */
926  .path = "set bridge-domain arp term",
927  .short_help = "set bridge-domain arp term <bridge-domain-id> [disable]",
928  .function = bd_arp_term,
929 };
930 /* *INDENT-ON* */
931 
932 
933 /**
934  * Add/delete IP address to MAC address mapping.
935  *
936  * The clib hash implementation stores uword entries in the hash table.
937  * The hash table mac_by_ip4 is keyed via IP4 address and store the
938  * 6-byte MAC address directly in the hash table entry uword.
939  *
940  * @warning This only works for 64-bit processor with 8-byte uword;
941  * which means this code *WILL NOT WORK* for a 32-bit processor with
942  * 4-byte uword.
943  */
944 u32
947  const ip46_address_t * ip,
948  const mac_address_t * mac, u8 is_add)
949 {
950  l2_bridge_domain_t *bd_cfg = l2input_bd_config (bd_index);
951  u64 new_mac = mac_address_as_u64 (mac);
952  u64 *old_mac;
953 
954  /* make sure uword is 8 bytes */
955  ASSERT (sizeof (uword) == sizeof (u64));
956  ASSERT (bd_is_valid (bd_cfg));
957 
958  if (IP46_TYPE_IP6 == type)
959  {
960  ip6_address_t *ip6_addr_key;
961  hash_pair_t *hp;
962  old_mac = (u64 *) hash_get_mem (bd_cfg->mac_by_ip6, &ip->ip6);
963  if (is_add)
964  {
965  if (old_mac == NULL)
966  {
967  /* new entry - allocate and create ip6 address key */
968  ip6_addr_key = clib_mem_alloc (sizeof (ip6_address_t));
969  clib_memcpy (ip6_addr_key, &ip->ip6, sizeof (ip6_address_t));
970  }
971  else if (*old_mac == new_mac)
972  {
973  /* same mac entry already exist for ip6 address */
974  return 0;
975  }
976  else
977  {
978  /* update mac for ip6 address */
979  hp = hash_get_pair (bd_cfg->mac_by_ip6, &ip->ip6);
980  ip6_addr_key = (ip6_address_t *) hp->key;
981  }
982  hash_set_mem (bd_cfg->mac_by_ip6, ip6_addr_key, new_mac);
983  }
984  else
985  {
986  if (old_mac && (*old_mac == new_mac))
987  {
988  hp = hash_get_pair (bd_cfg->mac_by_ip6, &ip->ip6);
989  ip6_addr_key = (ip6_address_t *) hp->key;
990  hash_unset_mem (bd_cfg->mac_by_ip6, &ip->ip6);
991  clib_mem_free (ip6_addr_key);
992  }
993  else
994  return 1;
995  }
996  }
997  else
998  {
999  old_mac = (u64 *) hash_get (bd_cfg->mac_by_ip4, ip->ip4.as_u32);
1000  if (is_add)
1001  {
1002  if (old_mac && (*old_mac == new_mac))
1003  /* mac entry already exist */
1004  return 0;
1005  hash_set (bd_cfg->mac_by_ip4, ip->ip4.as_u32, new_mac);
1006  }
1007  else
1008  {
1009  if (old_mac && (*old_mac == new_mac))
1010  hash_unset (bd_cfg->mac_by_ip4, ip->ip4.as_u32);
1011  else
1012  return 1;
1013  }
1014  }
1015  return 0;
1016 }
1017 
1018 /**
1019  * Flush IP address to MAC address mapping tables in a BD.
1020  */
1021 void
1023 {
1024  l2_bridge_domain_t *bd = l2input_bd_config (bd_index);
1025  ASSERT (bd_is_valid (bd));
1026  bd_free_ip_mac_tables (bd);
1027  bd->mac_by_ip4 = 0;
1028  bd->mac_by_ip6 =
1029  hash_create_mem (0, sizeof (ip6_address_t), sizeof (uword));
1030 }
1031 
1032 /**
1033  Set bridge-domain arp entry add/delete.
1034  The CLI format is:
1035  set bridge-domain arp entry <bridge-domain-id> <ip-addr> <mac-addr> [del]
1036 */
1037 static clib_error_t *
1039  unformat_input_t * input, vlib_cli_command_t * cmd)
1040 {
1041  ip46_address_t ip_addr = ip46_address_initializer;
1043  bd_main_t *bdm = &bd_main;
1044  clib_error_t *error = 0;
1045  u32 bd_index, bd_id;
1047  u8 is_add = 1;
1048  uword *p;
1049 
1050  if (!unformat (input, "%d", &bd_id))
1051  {
1052  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
1053  format_unformat_error, input);
1054  goto done;
1055  }
1056 
1057  if (bd_id == 0)
1058  return clib_error_return (0,
1059  "No operations on the default bridge domain are supported");
1060 
1061  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1062 
1063  if (p)
1064  bd_index = *p;
1065  else
1066  return clib_error_return (0, "No such bridge domain %d", bd_id);
1067 
1068  if (unformat (input, "%U", unformat_ip4_address, &ip_addr.ip4))
1069  {
1070  type = IP46_TYPE_IP4;
1071  }
1072  else if (unformat (input, "%U", unformat_ip6_address, &ip_addr.ip6))
1073  {
1074  type = IP46_TYPE_IP6;
1075  }
1076  else if (unformat (input, "del-all"))
1077  {
1078  bd_flush_ip_mac (bd_index);
1079  goto done;
1080  }
1081  else
1082  {
1083  error = clib_error_return (0, "expecting IP address but got `%U'",
1084  format_unformat_error, input);
1085  goto done;
1086  }
1087 
1088  if (!unformat (input, "%U", unformat_mac_address_t, &mac))
1089  {
1090  error = clib_error_return (0, "expecting MAC address but got `%U'",
1091  format_unformat_error, input);
1092  goto done;
1093  }
1094 
1095  if (unformat (input, "del"))
1096  {
1097  is_add = 0;
1098  }
1099 
1100  /* set the bridge domain flagAdd IP-MAC entry into bridge domain */
1101  if (bd_add_del_ip_mac (bd_index, type, &ip_addr, &mac, is_add))
1102  {
1103  error = clib_error_return (0, "MAC %s for IP %U and MAC %U failed",
1104  is_add ? "add" : "del",
1107  }
1108 
1109 done:
1110  return error;
1111 }
1112 
1113 /*?
1114  * Add an ARP entry to an existing bridge-domain.
1115  *
1116  * @cliexpar
1117  * Example of how to add an ARP entry (where 200 is the bridge-domain-id):
1118  * @cliexcmd{set bridge-domain arp entry 200 192.168.72.45 52:54:00:3b:83:1a}
1119  * Example of how to delete an ARP entry (where 200 is the bridge-domain-id):
1120  * @cliexcmd{set bridge-domain arp entry 200 192.168.72.45 52:54:00:3b:83:1a del}
1121 ?*/
1122 /* *INDENT-OFF* */
1124  .path = "set bridge-domain arp entry",
1125  .short_help = "set bridge-domain arp entry <bridge-domain-id> [<ip-addr> <mac-addr> [del] | del-all]",
1126  .function = bd_arp_entry,
1127 };
1128 /* *INDENT-ON* */
1129 
1130 static u8 *
1131 format_uu_cfg (u8 * s, va_list * args)
1132 {
1133  l2_bridge_domain_t *bd_config = va_arg (*args, l2_bridge_domain_t *);
1134 
1135  if (bd_config->feature_bitmap & L2INPUT_FEAT_UU_FWD)
1136  return (format (s, "%U", format_vnet_sw_if_index_name_with_NA,
1137  vnet_get_main (), bd_config->uu_fwd_sw_if_index));
1138  else if (bd_config->feature_bitmap & L2INPUT_FEAT_UU_FLOOD)
1139  return (format (s, "flood"));
1140  else
1141  return (format (s, "drop"));
1142 }
1143 
1144 /**
1145  Show bridge-domain state.
1146  The CLI format is:
1147  show bridge-domain [<bd_index>]
1148 */
1149 static clib_error_t *
1151 {
1152  vnet_main_t *vnm = vnet_get_main ();
1153  bd_main_t *bdm = &bd_main;
1154  clib_error_t *error = 0;
1155  u32 bd_index = ~0;
1156  l2_bridge_domain_t *bd_config;
1157  u32 start, end;
1158  u32 detail = 0;
1159  u32 intf = 0;
1160  u32 arp = 0;
1161  u32 bd_tag = 0;
1162  u32 bd_id = ~0;
1163  uword *p;
1164 
1165  start = 1;
1167 
1168  if (unformat (input, "%d", &bd_id))
1169  {
1170  if (unformat (input, "detail"))
1171  detail = 1;
1172  else if (unformat (input, "det"))
1173  detail = 1;
1174  if (unformat (input, "int"))
1175  intf = 1;
1176  if (unformat (input, "arp"))
1177  arp = 1;
1178  if (unformat (input, "bd-tag"))
1179  bd_tag = 1;
1180 
1181  if (bd_id == 0)
1182  return clib_error_return (0,
1183  "No operations on the default bridge domain are supported");
1184 
1185  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1186  if (p)
1187  bd_index = *p;
1188  else
1189  return clib_error_return (0, "No such bridge domain %d", bd_id);
1190 
1191  vec_validate (l2input_main.bd_configs, bd_index);
1192  bd_config = vec_elt_at_index (l2input_main.bd_configs, bd_index);
1193  if (bd_is_valid (bd_config))
1194  {
1195  start = bd_index;
1196  end = start + 1;
1197  }
1198  else
1199  {
1200  vlib_cli_output (vm, "bridge-domain %d not in use", bd_id);
1201  goto done;
1202  }
1203  }
1204 
1205  /* Show all bridge-domains that have been initialized */
1206  u32 printed = 0;
1207  u8 *as = 0;
1208  for (bd_index = start; bd_index < end; bd_index++)
1209  {
1210  bd_config = vec_elt_at_index (l2input_main.bd_configs, bd_index);
1211  if (bd_is_valid (bd_config))
1212  {
1213  if (!printed)
1214  {
1215  printed = 1;
1217  "%=8s %=7s %=4s %=9s %=9s %=9s %=11s %=9s %=9s "
1218  "%=9s %=8s %=8s %=11s",
1219  "BD-ID", "Index", "BSN", "Age(min)", "Learning",
1220  "U-Forwrd", "UU-Flood", "Flooding", "ARP-Term",
1221  "arp-ufwd", "Learn-count", "Learn-limit",
1222  "BVI-Intf");
1223  }
1224 
1225  if (bd_config->mac_age)
1226  as = format (as, "%d", bd_config->mac_age);
1227  else
1228  as = format (as, "off");
1229  vlib_cli_output (
1230  vm,
1231  "%=8d %=7d %=4d %=9v %=9s %=9s %=11U %=9s %=9s %=9s %=8d %=8d "
1232  "%=11U",
1233  bd_config->bd_id, bd_index, bd_config->seq_num, as,
1234  bd_config->feature_bitmap & L2INPUT_FEAT_LEARN ? "on" : "off",
1235  bd_config->feature_bitmap & L2INPUT_FEAT_FWD ? "on" : "off",
1236  format_uu_cfg, bd_config,
1237  bd_config->feature_bitmap & L2INPUT_FEAT_FLOOD ? "on" : "off",
1238  bd_config->feature_bitmap & L2INPUT_FEAT_ARP_TERM ? "on" : "off",
1239  bd_config->feature_bitmap & L2INPUT_FEAT_ARP_UFWD ? "on" : "off",
1240  bd_config->learn_count, bd_config->learn_limit,
1242  bd_config->bvi_sw_if_index);
1243  if (detail)
1245  bd_config->feature_bitmap);
1246  vec_reset_length (as);
1247 
1248  if (detail || intf)
1249  {
1250  /* Show all member interfaces */
1251  int i;
1252  vec_foreach_index (i, bd_config->members)
1253  {
1254  l2_flood_member_t *member =
1255  vec_elt_at_index (bd_config->members, i);
1256  u8 swif_seq_num = l2_input_seq_num (member->sw_if_index);
1257  u32 vtr_opr, dot1q, tag1, tag2;
1258  if (i == 0)
1259  {
1260  vlib_cli_output (vm, "\n%=30s%=7s%=5s%=5s%=5s%=9s%=30s",
1261  "Interface", "If-idx", "ISN", "SHG",
1262  "BVI", "TxFlood", "VLAN-Tag-Rewrite");
1263  }
1264  l2vtr_get (vm, vnm, member->sw_if_index, &vtr_opr, &dot1q,
1265  &tag1, &tag2);
1266  vlib_cli_output (vm, "%=30U%=7d%=5d%=5d%=5s%=9s%=30U",
1268  member->sw_if_index, member->sw_if_index,
1269  swif_seq_num, member->shg,
1270  member->flags & L2_FLOOD_MEMBER_BVI ? "*" :
1271  "-", i < bd_config->flood_count ? "*" : "-",
1272  format_vtr, vtr_opr, dot1q, tag1, tag2);
1273  }
1274  if (~0 != bd_config->uu_fwd_sw_if_index)
1275  vlib_cli_output (vm, "%=30U%=7d%=5d%=5d%=5s%=9s%=30s",
1277  bd_config->uu_fwd_sw_if_index,
1278  bd_config->uu_fwd_sw_if_index,
1279  0, 0, "uu", "-", "None");
1280 
1281  }
1282 
1283  if ((detail || arp) &&
1284  (bd_config->feature_bitmap & L2INPUT_FEAT_ARP_TERM))
1285  {
1286  u32 ip4_addr;
1287  ip6_address_t *ip6_addr;
1288  u64 mac_addr;
1290  "\n IP4/IP6 to MAC table for ARP Termination");
1291 
1292  /* *INDENT-OFF* */
1293  hash_foreach (ip4_addr, mac_addr, bd_config->mac_by_ip4,
1294  ({
1295  vlib_cli_output (vm, "%=40U => %=20U",
1296  format_ip4_address, &ip4_addr,
1297  format_ethernet_address, &mac_addr);
1298  }));
1299 
1300  hash_foreach_mem (ip6_addr, mac_addr, bd_config->mac_by_ip6,
1301  ({
1302  vlib_cli_output (vm, "%=40U => %=20U",
1303  format_ip6_address, ip6_addr,
1304  format_ethernet_address, &mac_addr);
1305  }));
1306  /* *INDENT-ON* */
1307  }
1308 
1309  if ((detail || bd_tag) && (bd_config->bd_tag))
1310  {
1311  vlib_cli_output (vm, "\n BD-Tag: %s", bd_config->bd_tag);
1312 
1313  }
1314  }
1315  }
1316  vec_free (as);
1317 
1318  if (!printed)
1319  {
1320  vlib_cli_output (vm, "no bridge-domains in use");
1321  }
1322 
1323 done:
1324  return error;
1325 }
1326 
1327 /*?
1328  * Show a summary of all the bridge-domain instances or detailed view of a
1329  * single bridge-domain. Bridge-domains are created by adding an interface
1330  * to a bridge using the '<em>set interface l2 bridge</em>' command.
1331  *
1332  * @cliexpar
1333  * @parblock
1334  * Example of displaying all bridge-domains:
1335  * @cliexstart{show bridge-domain}
1336  * ID Index Learning U-Forwrd UU-Flood Flooding ARP-Term BVI-Intf
1337  * 0 0 off off off off off local0
1338  * 200 1 on on on on off N/A
1339  * @cliexend
1340  *
1341  * Example of displaying details of a single bridge-domains:
1342  * @cliexstart{show bridge-domain 200 detail}
1343  * ID Index Learning U-Forwrd UU-Flood Flooding ARP-Term BVI-Intf
1344  * 200 1 on on on on off N/A
1345  *
1346  * Interface Index SHG BVI VLAN-Tag-Rewrite
1347  * GigabitEthernet0/8/0.200 3 0 - none
1348  * GigabitEthernet0/9/0.200 4 0 - none
1349  * @cliexend
1350  * @endparblock
1351 ?*/
1352 /* *INDENT-OFF* */
1354  .path = "show bridge-domain",
1355  .short_help = "show bridge-domain [bridge-domain-id [detail|int|arp|bd-tag]]",
1356  .function = bd_show,
1357 };
1358 /* *INDENT-ON* */
1359 
1360 int
1362 {
1363  bd_main_t *bdm = &bd_main;
1365  vlib_main_t *vm = bdm->vlib_main;
1366  int rv = 0;
1367 
1368  if (fm->mac_table_initialized == 0)
1369  l2fib_table_init ();
1370 
1371  u32 bd_index = bd_find_index (bdm, a->bd_id);
1372  if (a->is_add)
1373  {
1374  if (bd_index != ~0)
1375  return VNET_API_ERROR_BD_ALREADY_EXISTS;
1376  if (a->bd_id > L2_BD_ID_MAX)
1377  return VNET_API_ERROR_BD_ID_EXCEED_MAX;
1378  bd_index = bd_add_bd_index (bdm, a->bd_id);
1379 
1380  bd_flags_t enable_flags = 0, disable_flags = 0;
1381  if (a->flood)
1382  enable_flags |= L2_FLOOD;
1383  else
1384  disable_flags |= L2_FLOOD;
1385 
1386  if (a->uu_flood)
1387  enable_flags |= L2_UU_FLOOD;
1388  else
1389  disable_flags |= L2_UU_FLOOD;
1390 
1391  if (a->forward)
1392  enable_flags |= L2_FWD;
1393  else
1394  disable_flags |= L2_FWD;
1395 
1396  if (a->learn)
1397  enable_flags |= L2_LEARN;
1398  else
1399  disable_flags |= L2_LEARN;
1400 
1401  if (a->arp_term)
1402  enable_flags |= L2_ARP_TERM;
1403  else
1404  disable_flags |= L2_ARP_TERM;
1405 
1406  if (a->arp_ufwd)
1407  enable_flags |= L2_ARP_UFWD;
1408  else
1409  disable_flags |= L2_ARP_UFWD;
1410 
1411  if (enable_flags)
1412  bd_set_flags (vm, bd_index, enable_flags, 1 /* enable */ );
1413 
1414  if (disable_flags)
1415  bd_set_flags (vm, bd_index, disable_flags, 0 /* disable */ );
1416 
1417  bd_set_mac_age (vm, bd_index, a->mac_age);
1418 
1419  if (a->bd_tag)
1420  bd_set_bd_tag (vm, bd_index, a->bd_tag);
1421 
1423  vec_elt_at_index (l2input_main.bd_configs, bd_index)->learn_count = 0;
1424  }
1425  else
1426  {
1427  if (bd_index == ~0)
1428  return VNET_API_ERROR_NO_SUCH_ENTRY;
1429  if (bd_index == 0)
1430  return VNET_API_ERROR_BD_NOT_MODIFIABLE;
1431  if (vec_len (l2input_main.bd_configs[bd_index].members))
1432  return VNET_API_ERROR_BD_IN_USE;
1433  rv = bd_delete (bdm, bd_index);
1434  }
1435 
1436  return rv;
1437 }
1438 
1439 /**
1440  Create or delete bridge-domain.
1441  The CLI format:
1442  create bridge-domain <bd_index> [learn <0|1>] [forward <0|1>] [uu-flood <0|1>] [flood <0|1>]
1443  [arp-term <0|1>] [mac-age <nn>] [bd-tag <tag>] [del]
1444 */
1445 
1446 static clib_error_t *
1448  vlib_cli_command_t * cmd)
1449 {
1450  unformat_input_t _line_input, *line_input = &_line_input;
1451  clib_error_t *error = 0;
1452  u8 is_add = 1;
1453  u32 bd_id = ~0;
1454  u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term =
1455  0, arp_ufwd = 0;
1456  u32 mac_age = 0;
1457  u8 *bd_tag = NULL;
1459  int rv;
1460 
1461  /* Get a line of input. */
1462  if (!unformat_user (input, unformat_line_input, line_input))
1463  return 0;
1464 
1465  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1466  {
1467  if (unformat (line_input, "%d", &bd_id))
1468  ;
1469  else if (unformat (line_input, "flood %d", &flood))
1470  ;
1471  else if (unformat (line_input, "uu-flood %d", &uu_flood))
1472  ;
1473  else if (unformat (line_input, "forward %d", &forward))
1474  ;
1475  else if (unformat (line_input, "learn %d", &learn))
1476  ;
1477  else if (unformat (line_input, "arp-term %d", &arp_term))
1478  ;
1479  else if (unformat (line_input, "arp-ufwd %d", &arp_ufwd))
1480  ;
1481  else if (unformat (line_input, "mac-age %d", &mac_age))
1482  ;
1483  else if (unformat (line_input, "bd-tag %s", &bd_tag))
1484  ;
1485  else if (unformat (line_input, "del"))
1486  {
1487  is_add = 0;
1488  flood = uu_flood = forward = learn = 0;
1489  }
1490  else
1491  break;
1492  }
1493 
1494  if (bd_id == ~0)
1495  {
1496  error = clib_error_return (0, "bridge-domain-id not specified");
1497  goto done;
1498  }
1499 
1500  if (bd_id == 0)
1501  {
1502  error = clib_error_return (0, "bridge domain 0 can not be modified");
1503  goto done;
1504  }
1505 
1506  if (mac_age > 255)
1507  {
1508  error = clib_error_return (0, "mac age must be less than 256");
1509  goto done;
1510  }
1511  if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
1512  {
1513  error = clib_error_return (0, "bd-tag cannot be longer than 63");
1514  goto done;
1515  }
1516 
1517  clib_memset (a, 0, sizeof (*a));
1518  a->is_add = is_add;
1519  a->bd_id = bd_id;
1520  a->flood = (u8) flood;
1521  a->uu_flood = (u8) uu_flood;
1522  a->forward = (u8) forward;
1523  a->learn = (u8) learn;
1524  a->arp_term = (u8) arp_term;
1525  a->arp_ufwd = (u8) arp_ufwd;
1526  a->mac_age = (u8) mac_age;
1527  a->bd_tag = bd_tag;
1528 
1529  rv = bd_add_del (a);
1530 
1531  switch (rv)
1532  {
1533  case 0:
1534  if (is_add)
1535  vlib_cli_output (vm, "bridge-domain %d", bd_id);
1536  break;
1537  case VNET_API_ERROR_BD_IN_USE:
1538  error = clib_error_return (0, "bridge domain in use - remove members");
1539  goto done;
1540  case VNET_API_ERROR_NO_SUCH_ENTRY:
1541  error = clib_error_return (0, "bridge domain ID does not exist");
1542  goto done;
1543  case VNET_API_ERROR_BD_NOT_MODIFIABLE:
1544  error = clib_error_return (0, "bridge domain 0 can not be modified");
1545  goto done;
1546  case VNET_API_ERROR_BD_ID_EXCEED_MAX:
1547  error = clib_error_return (0, "bridge domain ID exceed 16M limit");
1548  goto done;
1549  default:
1550  error = clib_error_return (0, "bd_add_del returned %d", rv);
1551  goto done;
1552  }
1553 
1554 done:
1555  vec_free (bd_tag);
1556  unformat_free (line_input);
1557 
1558  return error;
1559 }
1560 
1561 
1562 /*?
1563  * Create/Delete bridge-domain instance
1564  *
1565  * @cliexpar
1566  * @parblock
1567  * Example of creating bridge-domain 1:
1568  * @cliexstart{create bridge-domain 1}
1569  * bridge-domain 1
1570  * @cliexend
1571  *
1572  * Example of creating bridge-domain 2 with enabling arp-term, mac-age 60:
1573  * @cliexstart{create bridge-domain 2 arp-term 1 mac-age 60}
1574  * bridge-domain 2
1575  *
1576  * vpp# show bridge-domain
1577  * ID Index BSN Age(min) Learning U-Forwrd UU-Flood Flooding ARP-Term BVI-Intf
1578  * 0 0 0 off off off off off off local0
1579  * 1 1 0 off on on off on off N/A
1580  * 2 2 0 60 on on off on on N/A
1581  *
1582  * @cliexend
1583  *
1584  * Example of delete bridge-domain 1:
1585  * @cliexstart{create bridge-domain 1 del}
1586  * @cliexend
1587  * @endparblock
1588 ?*/
1589 
1590 /* *INDENT-OFF* */
1592  .path = "create bridge-domain",
1593  .short_help = "create bridge-domain <bridge-domain-id>"
1594  " [learn <0|1>] [forward <0|1>] [uu-flood <0|1>] [flood <0|1>] [arp-term <0|1>]"
1595  " [arp-ufwd <0|1>] [mac-age <nn>] [bd-tag <tag>] [del]",
1596  .function = bd_add_del_command_fn,
1597 };
1598 /* *INDENT-ON* */
1599 
1600 
1601 
1602 /*
1603  * fd.io coding-style-patch-verification: ON
1604  *
1605  * Local Variables:
1606  * eval: (c-set-style "gnu")
1607  * End:
1608  */
vec_reset_length
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
Definition: vec_bootstrap.h:194
vlib.h
l2_bridge_domain_add_del_args_t
Definition: l2_bd.h:124
l2_bridge_domain_t::tun_master_count
u32 tun_master_count
Definition: l2_bd.h:92
hash_get_pair
#define hash_get_pair(h, key)
Definition: hash.h:252
L2_FWD
@ L2_FWD
Definition: l2_bd.h:157
l2_bridge_domain_t
Definition: l2_bd.h:63
mac
vl_api_mac_address_t mac
Definition: l2.api:559
unformat_user
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
hash_set
#define hash_set(h, key, value)
Definition: hash.h:255
L2_MAC_AGE_PROCESS_EVENT_START
@ L2_MAC_AGE_PROCESS_EVENT_START
Definition: l2_learn.h:61
vnet_sw_interface_t
Definition: interface.h:869
hash_free
#define hash_free(h)
Definition: hash.h:310
bd_flood_cli
static vlib_cli_command_t bd_flood_cli
(constructor) VLIB_CLI_COMMAND (bd_flood_cli)
Definition: l2_bd.c:616
l2input_main
l2input_main_t l2input_main
Definition: l2_input_node.c:78
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
l2input_bd_config
static_always_inline l2_bridge_domain_t * l2input_bd_config(u32 bd_index)
Definition: l2_input.h:116
bd_arp_term_cli
static vlib_cli_command_t bd_arp_term_cli
(constructor) VLIB_CLI_COMMAND (bd_arp_term_cli)
Definition: l2_bd.c:925
ip46_address_initializer
#define ip46_address_initializer
Definition: ip46_address.h:52
unformat_line_input
unformat_function_t unformat_line_input
Definition: format.h:275
l2_flood_member_t::sw_if_index
u32 sw_if_index
Definition: l2_bd.h:55
bd_arp_entry
static clib_error_t * bd_arp_entry(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Set bridge-domain arp entry add/delete.
Definition: l2_bd.c:1038
vec_insert_elts
#define vec_insert_elts(V, E, N, M)
Insert N vector elements starting at element M, insert given elements (no header, unspecified alignme...
Definition: vec.h:854
L2_MAC_AGE_PROCESS_EVENT_STOP
@ L2_MAC_AGE_PROCESS_EVENT_STOP
Definition: l2_learn.h:62
bd_show_cli
static vlib_cli_command_t bd_show_cli
(constructor) VLIB_CLI_COMMAND (bd_show_cli)
Definition: l2_bd.c:1353
bd_main_t
Definition: l2_bd.h:33
clib_mem_free
static void clib_mem_free(void *p)
Definition: mem.h:314
format_l2_input_feature_bitmap
u8 * format_l2_input_feature_bitmap(u8 *s, va_list *args)
Definition: l2_input.c:65
mac_address_as_u64
static_always_inline u64 mac_address_as_u64(const mac_address_t *mac)
Definition: mac_address.h:112
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
IP46_TYPE_IP4
@ IP46_TYPE_IP4
Definition: ip46_address.h:26
u8
#define u8
Padding.
Definition: clib.h:121
vlib_cli_command_t::path
char * path
Definition: cli.h:96
L2_FLOOD
@ L2_FLOOD
Definition: l2_bd.h:158
L2_FLOOD_MEMBER_BVI
#define L2_FLOOD_MEMBER_BVI
Definition: l2_bd.h:51
bd_remove_member
u32 bd_remove_member(l2_bridge_domain_t *bd_config, u32 sw_if_index)
Definition: l2_bd.c:198
hash_foreach
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:441
VNET_FLOOD_CLASS_NORMAL
@ VNET_FLOOD_CLASS_NORMAL
Definition: interface.h:819
hash_set_mem
#define hash_set_mem(h, key, value)
Definition: hash.h:275
bd_fwd
static clib_error_t * bd_fwd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Set bridge-domain forward enable/disable.
Definition: l2_bd.c:499
l2bd_init
clib_error_t * l2bd_init(vlib_main_t *vm)
Definition: l2_bd.c:232
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
b2_input_recache
static void b2_input_recache(u32 bd_index)
Definition: l2_bd.c:284
vec_delete
#define vec_delete(V, N, M)
Delete N elements starting at element M.
Definition: vec.h:875
fm
vnet_feature_main_t * fm
Definition: nat44_ei_hairpinning.c:592
vnet_get_sw_interface
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:58
l2_learn.h
unformat_input_t
struct _unformat_input_t unformat_input_t
l2_bridge_domain_t::flood_count
u32 flood_count
Definition: l2_bd.h:89
l2_bridge_domain_t::mac_age
u8 mac_age
Definition: l2_bd.h:105
vlib_process_signal_event
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Definition: node_funcs.h:1019
update_flood_count
static void update_flood_count(l2_bridge_domain_t *bd_config)
Definition: l2_bd.c:144
bd_learn_cli
static vlib_cli_command_t bd_learn_cli
(constructor) VLIB_CLI_COMMAND (bd_learn_cli)
Definition: l2_bd.c:458
clib_bitmap_first_clear
static uword clib_bitmap_first_clear(uword *ai)
Return the lowest numbered clear bit in a bitmap.
Definition: bitmap.h:432
ethernet.h
bd_flush_ip_mac
void bd_flush_ip_mac(u32 bd_index)
Flush IP address to MAC address mapping tables in a BD.
Definition: l2_bd.c:1022
error
Definition: cJSON.c:88
bd_get
l2_bridge_domain_t * bd_get(u32 bd_index)
Definition: l2_bd.c:252
hash_unset
#define hash_unset(h, key)
Definition: hash.h:261
l2_fib.h
L2_ARP_TERM
@ L2_ARP_TERM
Definition: l2_bd.h:160
ip6_packet.h
bd_arp_ufwd
static clib_error_t * bd_arp_ufwd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Set bridge-domain arp-unicast forward enable/disable.
Definition: l2_bd.c:694
VNET_FLOOD_CLASS_TUNNEL_NORMAL
@ VNET_FLOOD_CLASS_TUNNEL_NORMAL
Definition: interface.h:822
l2learn_main_t::bd_default_learn_limit
u32 bd_default_learn_limit
Definition: l2_learn.h:39
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
bd_add_del
int bd_add_del(l2_bridge_domain_add_del_args_t *a)
Definition: l2_bd.c:1361
l2_bridge_domain_t::mac_by_ip4
uword * mac_by_ip4
Definition: l2_bd.h:101
bd_set_bd_tag
static void bd_set_bd_tag(vlib_main_t *vm, u32 bd_index, u8 *bd_tag)
Set the tag for the bridge domain.
Definition: l2_bd.c:379
l2_bridge_domain_t::learn_count
u32 learn_count
Definition: l2_bd.h:117
bd_input_walk
u32 bd_input_walk(u32 bd_index, bd_input_walk_fn_t fn, void *data)
Definition: l2_bd.c:260
bd_input_walk_fn_t
walk_rc_t(* bd_input_walk_fn_t)(u32 bd_index, u32 sw_if_index)
Walk all the input interfaces in the BD.
Definition: l2_bd.h:213
l2_bridge_domain_t::tun_normal_count
u32 tun_normal_count
Definition: l2_bd.h:95
hash.h
bd_add_del_ip_mac
u32 bd_add_del_ip_mac(u32 bd_index, ip46_type_t type, const ip46_address_t *ip, const mac_address_t *mac, u8 is_add)
Add/delete IP address to MAC address mapping.
Definition: l2_bd.c:945
l2learn_main_t
Definition: l2_learn.h:26
hash_create_mem
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:660
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
unformat_free
static void unformat_free(unformat_input_t *i)
Definition: format.h:155
error.h
l2_bridge_domain_t::no_flood_count
u32 no_flood_count
Definition: l2_bd.h:98
bd_id
u32 bd_id
Definition: gbp.api:188
VNET_FLOOD_CLASS_BVI
@ VNET_FLOOD_CLASS_BVI
Definition: interface.h:817
l2_bridge_domain_t::uu_fwd_sw_if_index
u32 uu_fwd_sw_if_index
Definition: l2_bd.h:80
hash_unset_mem
#define hash_unset_mem(h, key)
Definition: hash.h:291
bd_main_t::bd_index_bitmap
uword * bd_index_bitmap
Definition: l2_bd.h:39
vec_elt_at_index
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Definition: vec_bootstrap.h:203
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
format.h
bd_learn_limit
static clib_error_t * bd_learn_limit(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: l2_bd.c:866
hash_get
#define hash_get(h, key)
Definition: hash.h:249
format_mac_address_t
u8 * format_mac_address_t(u8 *s, va_list *args)
Definition: mac_address.c:27
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
BD_REMOVE_ERROR_OK
#define BD_REMOVE_ERROR_OK
Definition: l2_bd.c:194
end
f64 end
end of the time range
Definition: mactime.api:44
bd_add_member
void bd_add_member(l2_bridge_domain_t *bd_config, l2_flood_member_t *member)
Definition: l2_bd.c:153
vnet_sw_interface_t::flood_class
vnet_flood_class_t flood_class
Definition: interface.h:898
vec_foreach_index
#define vec_foreach_index(var, v)
Iterate over vector indices.
Definition: vec_bootstrap.h:220
uword
u64 uword
Definition: types.h:112
bd_default_learn_limit
static clib_error_t * bd_default_learn_limit(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: l2_bd.c:466
l2_vtr.h
format_uu_cfg
static u8 * format_uu_cfg(u8 *s, va_list *args)
Definition: l2_bd.c:1131
bd_add_del_command_fn
static clib_error_t * bd_add_del_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Create or delete bridge-domain.
Definition: l2_bd.c:1447
L2_ARP_UFWD
@ L2_ARP_UFWD
Definition: l2_bd.h:161
bd_delete
static int bd_delete(bd_main_t *bdm, u32 bd_index)
Definition: l2_bd.c:115
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
bd_flood
static clib_error_t * bd_flood(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Set bridge-domain flood enable/disable.
Definition: l2_bd.c:564
l2_input_seq_num
static_always_inline u8 l2_input_seq_num(u32 sw_if_index)
Definition: l2_input.h:254
bd_set_flags
u32 bd_set_flags(vlib_main_t *vm, u32 bd_index, bd_flags_t flags, u32 enable)
Set the learn/forward/flood flags for the bridge domain.
Definition: l2_bd.c:294
clib_bitmap_set
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap.
Definition: bitmap.h:167
l2_bridge_domain_t::feature_bitmap
u32 feature_bitmap
Definition: l2_bd.h:69
IP46_TYPE_IP6
@ IP46_TYPE_IP6
Definition: ip46_address.h:27
bd_learn
static clib_error_t * bd_learn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Set bridge-domain learn enable/disable.
Definition: l2_bd.c:406
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
l2_bridge_domain_t::seq_num
u8 seq_num
Definition: l2_bd.h:108
bd_flags_t
enum bd_flags_t_ bd_flags_t
L2_LEARN
@ L2_LEARN
Definition: l2_bd.h:156
bd_uu_flood
static clib_error_t * bd_uu_flood(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Set bridge-domain unknown-unicast flood enable/disable.
Definition: l2_bd.c:629
l2_input.h
bd_free_ip_mac_tables
static void bd_free_ip_mac_tables(l2_bridge_domain_t *bd)
Definition: l2_bd.c:99
mac_addr
vl_api_mac_address_t mac_addr
Definition: l2.api:210
data
u8 data[128]
Definition: ipsec_types.api:95
ip4_packet.h
l2learn_main
l2learn_main_t l2learn_main
Definition: l2_learn.c:32
hash_get_mem
#define hash_get_mem(h, key)
Definition: hash.h:269
bd_default_learn_limit_cli
static vlib_cli_command_t bd_default_learn_limit_cli
(constructor) VLIB_CLI_COMMAND (bd_default_learn_limit_cli)
Definition: l2_bd.c:487
l2fib_flush_bd_mac
void l2fib_flush_bd_mac(vlib_main_t *vm, u32 bd_index)
Flush all non static MACs in a bridge domain.
Definition: l2_fib.c:911
vnet_main_t
Definition: vnet.h:76
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
l2fib_main_t
Definition: l2_fib.h:42
l2_flood_member_t::shg
u8 shg
Definition: l2_bd.h:57
bd_is_valid
static u32 bd_is_valid(l2_bridge_domain_t *bd_config)
Definition: l2_bd.h:140
l2_bridge_domain_t::bd_id
u32 bd_id
Definition: l2_bd.h:83
l2_bridge_domain_t::learn_limit
u32 learn_limit
Definition: l2_bd.h:114
l2_bridge_domain_t::bvi_sw_if_index
u32 bvi_sw_if_index
Definition: l2_bd.h:74
L2_UU_FLOOD
@ L2_UU_FLOOD
Definition: l2_bd.h:159
bd_find_index
u32 bd_find_index(bd_main_t *bdm, u32 bd_id)
Get a bridge domain.
Definition: l2_bd.c:70
BD_REMOVE_ERROR_NOT_FOUND
#define BD_REMOVE_ERROR_NOT_FOUND
Definition: l2_bd.c:195
bd_create_cli
static vlib_cli_command_t bd_create_cli
(constructor) VLIB_CLI_COMMAND (bd_create_cli)
Definition: l2_bd.c:1591
u64
unsigned long u64
Definition: types.h:89
format_vnet_sw_if_index_name
format_function_t format_vnet_sw_if_index_name
Definition: interface_funcs.h:458
bd_main_t::vlib_main
vlib_main_t * vlib_main
Definition: l2_bd.h:42
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
l2fib_main
l2fib_main_t l2fib_main
Definition: l2_fib.c:50
VNET_FLOOD_CLASS_NO_FLOOD
@ VNET_FLOOD_CLASS_NO_FLOOD
Definition: interface.h:824
unformat_mac_address_t
uword unformat_mac_address_t(unformat_input_t *input, va_list *args)
Definition: mac_address.c:37
format_ip46_address
format_function_t format_ip46_address
Definition: ip46_address.h:50
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
format_vtr
format_function_t format_vtr
Definition: interface_funcs.h:472
l2vtr_get
u32 l2vtr_get(vlib_main_t *vlib_main, vnet_main_t *vnet_main, u32 sw_if_index, u32 *vtr_op, u32 *push_dot1q, u32 *vtr_tag1, u32 *vtr_tag2)
Get vtag tag rewrite on the given interface.
Definition: l2_vtr.c:347
cli.h
bd_mac_age_cli
static vlib_cli_command_t bd_mac_age_cli
(constructor) VLIB_CLI_COMMAND (bd_mac_age_cli)
Definition: l2_bd.c:858
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
hash_pair_t::key
uword key
Definition: hash.h:162
bd_validate
void bd_validate(l2_bridge_domain_t *bd_config)
Init bridge domain if not done already.
Definition: l2_bd.c:51
l2_flood_member_t
Definition: l2_bd.h:53
mac_address_t_
Definition: mac_address.h:21
vec.h
bd_arp_term
static clib_error_t * bd_arp_term(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Set bridge-domain arp term enable/disable.
Definition: l2_bd.c:759
l2fib_mac_age_scanner_process_node
vlib_node_registration_t l2fib_mac_age_scanner_process_node
(constructor) VLIB_REGISTER_NODE (l2fib_mac_age_scanner_process_node)
Definition: l2_fib.c:1370
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
bd_show
static clib_error_t * bd_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Show bridge-domain state.
Definition: l2_bd.c:1150
L2_BD_ID_MAX
#define L2_BD_ID_MAX
Definition: l2_bd.h:122
bd_main
bd_main_t bd_main
Definition: l2_bd.c:44
bd_uu_flood_cli
static vlib_cli_command_t bd_uu_flood_cli
(constructor) VLIB_CLI_COMMAND (bd_uu_flood_cli)
Definition: l2_bd.c:681
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
a
a
Definition: bitmap.h:525
feat_bitmap.h
ip
vl_api_address_t ip
Definition: l2.api:558
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
bd_fwd_cli
static vlib_cli_command_t bd_fwd_cli
(constructor) VLIB_CLI_COMMAND (bd_fwd_cli)
Definition: l2_bd.c:551
bd_arp_entry_cli
static vlib_cli_command_t bd_arp_entry_cli
(constructor) VLIB_CLI_COMMAND (bd_arp_entry_cli)
Definition: l2_bd.c:1123
l2_bridge_domain_t::members
l2_flood_member_t * members
Definition: l2_bd.h:86
l2_bridge_domain_t::bd_tag
u8 * bd_tag
Definition: l2_bd.h:111
ip46_type_t
ip46_type_t
Definition: ip46_address.h:22
i
int i
Definition: flowhash_template.h:376
bd_add_bd_index
u32 bd_add_bd_index(bd_main_t *bdm, u32 bd_id)
Create a bridge domain.
Definition: l2_bd.c:79
VNET_FLOOD_CLASS_TUNNEL_MASTER
@ VNET_FLOOD_CLASS_TUNNEL_MASTER
Definition: interface.h:820
unformat_ip6_address
unformat_function_t unformat_ip6_address
Definition: format.h:89
rv
int __clib_unused rv
Definition: application.c:491
IP46_TYPE_ANY
@ IP46_TYPE_ANY
Definition: ip46_address.h:24
unformat_ip4_address
unformat_function_t unformat_ip4_address
Definition: format.h:68
l2_flood_member_t::flags
u8 flags
Definition: l2_bd.h:56
bd_set_learn_limit
void bd_set_learn_limit(vlib_main_t *vm, u32 bd_index, u32 learn_limit)
Set learn limit for the bridge domain.
Definition: l2_bd.c:367
vnet.h
bd_learn_limit_cli
static vlib_cli_command_t bd_learn_limit_cli
(constructor) VLIB_CLI_COMMAND (bd_learn_limit_cli)
Definition: l2_bd.c:907
l2_bridge_domain_t::mac_by_ip6
uword * mac_by_ip6
Definition: l2_bd.h:102
format_vnet_sw_if_index_name_with_NA
u8 * format_vnet_sw_if_index_name_with_NA(u8 *s, va_list *args)
Format sw_if_index.
Definition: l2_fib.c:86
bd_mac_age
static clib_error_t * bd_mac_age(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: l2_bd.c:797
bd_set_mac_age
void bd_set_mac_age(vlib_main_t *vm, u32 bd_index, u8 age)
Set the mac age for the bridge domain.
Definition: l2_bd.c:344
vlib_cli_command_t
Definition: cli.h:92
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
hash_create
#define hash_create(elts, value_bytes)
Definition: hash.h:695
l2_bd.h
hash_foreach_mem
#define hash_foreach_mem(key_var, value_var, h, body)
Definition: hash.h:460
bd_main_t::bd_index_by_bd_id
uword * bd_index_by_bd_id
Definition: l2_bd.h:36
clib_mem_alloc
static void * clib_mem_alloc(uword size)
Definition: mem.h:256
WALK_STOP
@ WALK_STOP
Definition: interface_funcs.h:173
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
l2input_recache
walk_rc_t l2input_recache(u32 bd_index, u32 sw_if_index)
Definition: l2_input.c:222
bd_arp_ufwd_cli
static vlib_cli_command_t bd_arp_ufwd_cli
(constructor) VLIB_CLI_COMMAND (bd_arp_ufwd_cli)
Definition: l2_bd.c:746
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
hash_pair_t
Definition: hash.h:159
l2fib_table_init
void l2fib_table_init(void)
Definition: l2_fib.c:365
l2input_main_t::bd_configs
l2_bridge_domain_t * bd_configs
Definition: l2_input.h:93
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105