FD.io VPP  v16.06
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_fib.h>
27 #include <vnet/l2/l2_vtr.h>
28 #include <vnet/ip/ip4_packet.h>
29 #include <vnet/ip/ip6_packet.h>
30 
31 #include <vppinfra/error.h>
32 #include <vppinfra/hash.h>
33 #include <vppinfra/vec.h>
34 
36 
37 // Init bridge domain if not done already
38 // For feature bitmap, set all bits except ARP termination
39 void
41 {
42  if (!bd_is_valid (bd_config)) {
43  bd_config->feature_bitmap = ~L2INPUT_FEAT_ARP_TERM;
44  bd_config->bvi_sw_if_index = ~0;
45  bd_config->members = 0;
46  bd_config->mac_by_ip4 = 0;
47 // bd_config->mac_by_ip6 = hash_create_mem (0, sizeof(ip6_address_t),
48 // sizeof(uword));
49  }
50 }
51 
53 {
54  uword * p;
55  u32 rv;
56 
57  if (bd_id == ~0) {
58  bd_id = 0;
59  while (hash_get (bdm->bd_index_by_bd_id, bd_id))
60  bd_id++;
61  } else {
62  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
63  if (p)
64  return (p[0]);
65  }
66 
68 
69  // mark this index busy
70  bdm->bd_index_bitmap = clib_bitmap_set (bdm->bd_index_bitmap, rv, 1);
71 
72  hash_set (bdm->bd_index_by_bd_id, bd_id, rv);
73 
75  l2input_main.bd_configs[rv].bd_id = bd_id;
76 
77  return rv;
78 }
79 
80 int bd_delete_bd_index (bd_main_t * bdm, u32 bd_id)
81 {
82  uword * p;
83  u32 bd_index;
84 
85  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
86  if (p == 0)
87  return -1;
88 
89  bd_index = p[0];
90 
91  // mark this index clear
92  bdm->bd_index_bitmap = clib_bitmap_set (bdm->bd_index_bitmap, bd_index, 0);
93  hash_unset (bdm->bd_index_by_bd_id, bd_id);
94 
95  l2input_main.bd_configs[bd_index].bd_id = ~0;
97 
98  return 0;
99 }
100 
101 void
103  l2_flood_member_t * member)
104 {
105  // Add one element to the vector
106 
107  // When flooding, the bvi interface (if present) must be the last member
108  // processed due to how BVI processing can change the packet. To enable
109  // this order, we make the bvi interface the first in the vector and
110  // flooding walks the vector in reverse.
111  if ((member->flags == L2_FLOOD_MEMBER_NORMAL) ||
112  (vec_len(bd_config->members) == 0)) {
113  vec_add1 (bd_config->members, *member);
114 
115  } else {
116  // Move 0th element to the end
117  vec_add1 (bd_config->members, bd_config->members[0]);
118  bd_config->members[0] = *member;
119  }
120 }
121 
122 
123 #define BD_REMOVE_ERROR_OK 0
124 #define BD_REMOVE_ERROR_NOT_FOUND 1
125 
126 u32
128  u32 sw_if_index)
129 {
130  u32 ix;
131 
132  // Find and delete the member
133  vec_foreach_index(ix, bd_config->members) {
134  if (vec_elt(bd_config->members, ix).sw_if_index == sw_if_index) {
135  vec_del1 (bd_config->members, ix);
136  return BD_REMOVE_ERROR_OK;
137  }
138  }
139 
141 }
142 
143 
145 {
146  bd_main_t *bdm = &bd_main;
147  u32 bd_index;
148  bdm->bd_index_by_bd_id = hash_create (0, sizeof(uword));
149  // create a dummy bd with bd_id of 0 and bd_index of 0 with feature set
150  // to packet drop only. Thus, packets received from any L2 interface with
151  // uninitialized bd_index of 0 can be dropped safely.
152  bd_index = bd_find_or_add_bd_index (bdm, 0);
153  ASSERT (bd_index == 0);
154  l2input_main.bd_configs[0].feature_bitmap = L2INPUT_FEAT_DROP;
155  return 0;
156 }
157 
159 
160 
161 // Set the learn/forward/flood flags for the bridge domain
162 // Return 0 if ok, non-zero if for an error.
163 u32
165  u32 bd_index,
166  u32 flags,
167  u32 enable) {
168 
169  l2_bridge_domain_t * bd_config;
170  u32 feature_bitmap = 0;
171 
173  bd_config = vec_elt_at_index(l2input_main.bd_configs, bd_index);
174 
175  bd_validate (bd_config);
176 
177  if (flags & L2_LEARN) {
178  feature_bitmap |= L2INPUT_FEAT_LEARN;
179  }
180  if (flags & L2_FWD) {
181  feature_bitmap |= L2INPUT_FEAT_FWD;
182  }
183  if (flags & L2_FLOOD) {
184  feature_bitmap |= L2INPUT_FEAT_FLOOD;
185  }
186  if (flags & L2_UU_FLOOD) {
187  feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
188  }
189  if (flags & L2_ARP_TERM) {
190  feature_bitmap |= L2INPUT_FEAT_ARP_TERM;
191  }
192 
193  if (enable) {
194  bd_config->feature_bitmap |= feature_bitmap;
195  } else {
196  bd_config->feature_bitmap &= ~feature_bitmap;
197  }
198 
199  return 0;
200 }
201 
202 // set bridge-domain learn enable/disable
203 // The CLI format is:
204 // set bridge-domain learn <bd_id> [disable]
205 static clib_error_t *
207  unformat_input_t * input,
208  vlib_cli_command_t * cmd)
209 {
210  bd_main_t * bdm = &bd_main;
211  clib_error_t * error = 0;
212  u32 bd_index, bd_id;
213  u32 enable;
214  uword * p;
215 
216  if (! unformat (input, "%d", &bd_id))
217  {
218  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
219  format_unformat_error, input);
220  goto done;
221  }
222 
223  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
224 
225  if (p == 0)
226  return clib_error_return (0, "No such bridge domain %d", bd_id);
227 
228  bd_index = p[0];
229 
230  enable = 1;
231  if (unformat (input, "disable")) {
232  enable = 0;
233  }
234 
235  // set the bridge domain flag
236  if (bd_set_flags(vm, bd_index, L2_LEARN, enable)) {
237  error = clib_error_return (0, "bridge-domain id %d out of range", bd_index);
238  goto done;
239  }
240 
241  done:
242  return error;
243 }
244 
245 VLIB_CLI_COMMAND (bd_learn_cli, static) = {
246  .path = "set bridge-domain learn",
247  .short_help = "set bridge-domain learn <bridge-domain-id> [disable]",
248  .function = bd_learn,
249 };
250 
251 // set bridge-domain forward enable/disable
252 // The CLI format is:
253 // set bridge-domain forward <bd_index> [disable]
254 static clib_error_t *
256  unformat_input_t * input,
257  vlib_cli_command_t * cmd)
258 {
259  bd_main_t * bdm = &bd_main;
260  clib_error_t * error = 0;
261  u32 bd_index, bd_id;
262  u32 enable;
263  uword * p;
264 
265  if (! unformat (input, "%d", &bd_id))
266  {
267  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
268  format_unformat_error, input);
269  goto done;
270  }
271 
272  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
273 
274  if (p == 0)
275  return clib_error_return (0, "No such bridge domain %d", bd_id);
276 
277  bd_index = p[0];
278 
279  enable = 1;
280  if (unformat (input, "disable")) {
281  enable = 0;
282  }
283 
284  // set the bridge domain flag
285  if (bd_set_flags(vm, bd_index, L2_FWD, enable)) {
286  error = clib_error_return (0, "bridge-domain id %d out of range", bd_index);
287  goto done;
288  }
289 
290  done:
291  return error;
292 }
293 
294 VLIB_CLI_COMMAND (bd_fwd_cli, static) = {
295  .path = "set bridge-domain forward",
296  .short_help = "set bridge-domain forward <bridge-domain-id> [disable]",
297  .function = bd_fwd,
298 };
299 
300 // set bridge-domain flood enable/disable
301 // The CLI format is:
302 // set bridge-domain flood <bd_index> [disable]
303 static clib_error_t *
305  unformat_input_t * input,
306  vlib_cli_command_t * cmd)
307 {
308  bd_main_t * bdm = &bd_main;
309  clib_error_t * error = 0;
310  u32 bd_index, bd_id;
311  u32 enable;
312  uword * p;
313 
314  if (! unformat (input, "%d", &bd_id))
315  {
316  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
317  format_unformat_error, input);
318  goto done;
319  }
320 
321  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
322 
323  if (p == 0)
324  return clib_error_return (0, "No such bridge domain %d", bd_id);
325 
326  bd_index = p[0];
327 
328  enable = 1;
329  if (unformat (input, "disable")) {
330  enable = 0;
331  }
332 
333  // set the bridge domain flag
334  if (bd_set_flags(vm, bd_index, L2_FLOOD, enable)) {
335  error = clib_error_return (0, "bridge-domain id %d out of range", bd_index);
336  goto done;
337  }
338 
339  done:
340  return error;
341 }
342 
343 VLIB_CLI_COMMAND (bd_flood_cli, static) = {
344  .path = "set bridge-domain flood",
345  .short_help = "set bridge-domain flood <bridge-domain-id> [disable]",
346  .function = bd_flood,
347 };
348 
349 // set bridge-domain unkown-unicast flood enable/disable
350 // The CLI format is:
351 // set bridge-domain uu-flood <bd_index> [disable]
352 static clib_error_t *
354  unformat_input_t * input,
355  vlib_cli_command_t * cmd)
356 {
357  bd_main_t * bdm = &bd_main;
358  clib_error_t * error = 0;
359  u32 bd_index, bd_id;
360  u32 enable;
361  uword * p;
362 
363  if (! unformat (input, "%d", &bd_id))
364  {
365  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
366  format_unformat_error, input);
367  goto done;
368  }
369 
370  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
371 
372  if (p == 0)
373  return clib_error_return (0, "No such bridge domain %d", bd_id);
374 
375  bd_index = p[0];
376 
377  enable = 1;
378  if (unformat (input, "disable")) {
379  enable = 0;
380  }
381 
382  // set the bridge domain flag
383  if (bd_set_flags(vm, bd_index, L2_UU_FLOOD, enable)) {
384  error = clib_error_return (0, "bridge-domain id %d out of range", bd_index);
385  goto done;
386  }
387 
388  done:
389  return error;
390 }
391 
392 VLIB_CLI_COMMAND (bd_uu_flood_cli, static) = {
393  .path = "set bridge-domain uu-flood",
394  .short_help = "set bridge-domain uu-flood <bridge-domain-id> [disable]",
395  .function = bd_uu_flood,
396 };
397 
398 // set bridge-domain arp term enable/disable
399 // The CLI format is:
400 // set bridge-domain arp term <bridge-domain-id> [disable]
401 static clib_error_t *
403  unformat_input_t * input,
404  vlib_cli_command_t * cmd)
405 {
406  bd_main_t * bdm = &bd_main;
407  clib_error_t * error = 0;
408  u32 bd_index, bd_id;
409  u32 enable;
410  uword * p;
411 
412  if (! unformat (input, "%d", &bd_id)) {
413  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
414  format_unformat_error, input);
415  goto done;
416  }
417 
418  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
419  if (p) bd_index = *p;
420  else return clib_error_return (0, "No such bridge domain %d", bd_id);
421 
422  enable = 1;
423  if (unformat (input, "disable")) enable = 0;
424 
425  // set the bridge domain flag
426  if (bd_set_flags(vm, bd_index, L2_ARP_TERM, enable)) {
427  error = clib_error_return (0, "bridge-domain id %d out of range", bd_index);
428  goto done;
429  }
430 
431 done:
432  return error;
433 }
434 
435 VLIB_CLI_COMMAND (bd_arp_term_cli, static) = {
436  .path = "set bridge-domain arp term",
437  .short_help = "set bridge-domain arp term <bridge-domain-id> [disable]",
438  .function = bd_arp_term,
439 };
440 
441 
442 // The clib hash implementation stores uword entries in the hash table.
443 // The hash table mac_by_ip4 is keyed via IP4 address and store the
444 // 6-byte MAC address directly in the hash table entry uword.
445 // This only works for 64-bit processor with 8-byte uword; which means
446 // this code *WILL NOT WORK* for a 32-bit prcessor with 4-byte uword.
448  u8 *ip_addr,
449  u8 *mac_addr,
450  u8 is_ip6,
451  u8 is_add)
452 {
453  l2input_main_t * l2im = &l2input_main;
454  l2_bridge_domain_t * bd_cfg = l2input_bd_config_from_index (l2im, bd_index);
455  u64 new_mac = *(u64 *) mac_addr;
456  u64 * old_mac;
457  u16 * mac16 = (u16 *) &new_mac;
458 
459  ASSERT (sizeof(uword) == sizeof(u64)); // make sure uword is 8 bytes
460 
461  mac16[3] = 0; // Clear last 2 unsed bytes of the 8-byte MAC address
462  if (is_ip6) {
463  // ip6_address_t ip6_addr = *(ip6_address_t *) ip_addr;
464  return 1; // not yet implemented
465  } else {
466  ip4_address_t ip4_addr = *(ip4_address_t *) ip_addr;
467  old_mac = (u64 *) hash_get (bd_cfg->mac_by_ip4, ip4_addr.as_u32);
468  if (is_add) {
469  if (old_mac && (*old_mac == new_mac)) return 0; // mac entry already exist
470  hash_set (bd_cfg->mac_by_ip4, ip4_addr.as_u32, new_mac);
471  } else {
472  if (old_mac && (*old_mac == new_mac)) { // mac entry match
473  hash_unset (bd_cfg->mac_by_ip4, ip4_addr.as_u32); // clear entry
474  } else {
475  return 1;
476  }
477  }
478  return 0;
479  }
480 }
481 
482 // set bridge-domain arp entry add/delete
483 // The CLI format is:
484 // set bridge-domain arp entry <bd-id> <ip-addr> <mac-addr> [del]
485 static clib_error_t *
487  unformat_input_t * input,
488  vlib_cli_command_t * cmd)
489 {
490  bd_main_t * bdm = &bd_main;
491  clib_error_t * error = 0;
492  u32 bd_index, bd_id;
493  u8 is_add = 1;
494  u8 is_ip6 = 0;
495  u8 ip_addr[16];
496  u8 mac_addr[6];
497  uword * p;
498 
499  if (! unformat (input, "%d", &bd_id)) {
500  error = clib_error_return (0, "expecting bridge-domain id but got `%U'",
501  format_unformat_error, input);
502  goto done;
503  }
504 
505  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
506 
507  if (p) bd_index = *p;
508  else return clib_error_return (0, "No such bridge domain %d", bd_id);
509 
510  if (unformat (input, "%U", unformat_ip4_address, ip_addr)) {
511  is_ip6 = 0;
512  } else if (unformat (input, "%U", unformat_ip6_address, ip_addr)) {
513  is_ip6 = 1;
514  } else {
515  error = clib_error_return (0, "expecting IP address but got `%U'",
516  format_unformat_error, input);
517  goto done;
518  }
519 
520  if (!unformat(input, "%U", unformat_ethernet_address, mac_addr)) {
521  error = clib_error_return (0, "expecting MAC address but got `%U'",
522  format_unformat_error, input);
523  goto done;
524  }
525 
526  if (unformat (input, "del")) {
527  is_add = 0;
528  }
529 
530  // set the bridge domain flagAdd IP-MAC entry into bridge domain
531  if (bd_add_del_ip_mac(bd_index, ip_addr, mac_addr, is_ip6, is_add)) {
532  error = clib_error_return (0, "MAC %s for IP %U and MAC %U failed",
533  is_add ? "add" : "del",
534  format_ip4_address, ip_addr,
535  format_ethernet_address, mac_addr);
536  }
537 
538 done:
539  return error;
540 }
541 
542 VLIB_CLI_COMMAND (bd_arp_entry_cli, static) = {
543  .path = "set bridge-domain arp entry",
544  .short_help = "set bridge-domain arp entry <bd-id> <ip-addr> <mac-addr> [del]",
545  .function = bd_arp_entry,
546 };
547 
548 u8* format_vtr(u8 * s, va_list *args)
549 {
550  u32 vtr_op = va_arg (*args, u32);
551  u32 dot1q = va_arg (*args, u32);
552  u32 tag1 = va_arg (*args, u32);
553  u32 tag2 = va_arg (*args, u32);
554  switch (vtr_op) {
555  case L2_VTR_DISABLED:
556  return format (s, "none");
557  case L2_VTR_PUSH_1:
558  return format (s, "push-1 %s %d", dot1q? "dot1q":"dot1ad", tag1);
559  case L2_VTR_PUSH_2:
560  return format (s, "push-2 %s %d %d", dot1q? "dot1q":"dot1ad", tag1, tag2);
561  case L2_VTR_POP_1:
562  return format (s, "pop-1");
563  case L2_VTR_POP_2:
564  return format (s, "pop-2");
566  return format (s, "trans-1-1 %s %d", dot1q? "dot1q":"dot1ad", tag1);
568  return format (s, "trans-1-2 %s %d %d",dot1q? "dot1q":"dot1ad", tag1, tag2);
570  return format (s, "trans-2-1 %s %d", dot1q? "dot1q":"dot1ad", tag1);
572  return format (s, "trans-2-2 %s %d %d", dot1q? "dot1q":"dot1ad", tag1, tag2);
573  default:
574  return format (s, "none");
575  }
576 }
577 
578 // show bridge-domain state
579 // The CLI format is:
580 // show bridge-domain [<bd_index>]
581 static clib_error_t *
583  unformat_input_t * input,
584  vlib_cli_command_t * cmd)
585 {
586  vnet_main_t * vnm = vnet_get_main();
587  bd_main_t * bdm = &bd_main;
588  clib_error_t * error = 0;
589  u32 bd_index = ~0;
590  l2_bridge_domain_t * bd_config;
591  u32 start, end;
592  u32 printed;
593  u32 detail = 0;
594  u32 intf = 0;
595  u32 arp = 0;
596  u32 bd_id = ~0;
597  uword * p;
598 
599  start = 0;
601 
602  if (unformat (input, "%d", &bd_id)) {
603  if (unformat (input, "detail")) detail = 1;
604  else if (unformat (input, "det")) detail = 1;
605  if (unformat (input, "int")) intf = 1;
606  if (unformat (input, "arp")) arp = 1;
607 
608  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
609  if (p) bd_index = *p;
610  else return clib_error_return (0, "No such bridge domain %d", bd_id);
611 
613  bd_config = vec_elt_at_index(l2input_main.bd_configs, bd_index);
614  if (bd_is_valid (bd_config)) {
615  start = bd_index;
616  end = start + 1;
617  } else {
618  vlib_cli_output (vm, "bridge-domain %d not in use", bd_id);
619  goto done;
620  }
621  }
622 
623  // Show all bridge-domains that have been initialized
624 
625  printed = 0;
626  for (bd_index=start; bd_index<end; bd_index++) {
627  bd_config = vec_elt_at_index(l2input_main.bd_configs, bd_index);
628  if (bd_is_valid(bd_config)) {
629  if (!printed) {
630  printed = 1;
631  vlib_cli_output (vm, "%=5s %=7s %=10s %=10s %=10s %=10s %=10s %=14s",
632  "ID",
633  "Index",
634  "Learning",
635  "U-Forwrd",
636  "UU-Flood",
637  "Flooding",
638  "ARP-Term",
639  "BVI-Intf");
640  }
641 
643  vm, "%=5d %=7d %=10s %=10s %=10s %=10s %=10s %=14U",
644  bd_config->bd_id, bd_index,
645  bd_config->feature_bitmap & L2INPUT_FEAT_LEARN ? "on" : "off",
646  bd_config->feature_bitmap & L2INPUT_FEAT_FWD ? "on" : "off",
647  bd_config->feature_bitmap & L2INPUT_FEAT_UU_FLOOD ? "on" : "off",
648  bd_config->feature_bitmap & L2INPUT_FEAT_FLOOD ? "on" : "off",
649  bd_config->feature_bitmap & L2INPUT_FEAT_ARP_TERM ? "on" : "off",
651 
652  if (detail || intf) {
653  // Show all member interfaces
654 
655  l2_flood_member_t * member;
656  u32 header = 0;
657 
658  vec_foreach(member, bd_config->members) {
659  u32 vtr_opr, dot1q, tag1, tag2;
660  if (!header) {
661  header = 1;
662  vlib_cli_output (vm, "\n%=30s%=7s%=5s%=5s%=30s",
663  "Interface", "Index", "SHG", "BVI","VLAN-Tag-Rewrite");
664  }
665  l2vtr_get(vm, vnm, member->sw_if_index, &vtr_opr, &dot1q, &tag1, &tag2);
666  vlib_cli_output (vm, "%=30U%=7d%=5d%=5s%=30U",
668  member->sw_if_index,
669  member->shg,
670  member->flags & L2_FLOOD_MEMBER_BVI ? "*" : "-",
671  format_vtr, vtr_opr, dot1q, tag1, tag2);
672  }
673  }
674 
675  if ((detail || arp) &&
676  (bd_config->feature_bitmap & L2INPUT_FEAT_ARP_TERM)) {
677  u32 ip4_addr;
678  u64 mac_addr;
679  vlib_cli_output (vm, "\n IP4 to MAC table for ARP Termination");
680  hash_foreach (ip4_addr, mac_addr, bd_config->mac_by_ip4, ({
681  vlib_cli_output (vm, "%=20U => %=20U",
682  format_ip4_address, &ip4_addr,
683  format_ethernet_address, &mac_addr);
684  }));
685  }
686  }
687  }
688 
689  if (!printed) {
690  vlib_cli_output (vm, "no bridge-domains in use");
691  }
692 
693  done:
694  return error;
695 }
696 
697 VLIB_CLI_COMMAND (bd_show_cli, static) = {
698  .path = "show bridge-domain",
699  .short_help = "show bridge-domain [bridge-domain-id [detail|int|arp]]",
700  .function = bd_show,
701 };
void bd_validate(l2_bridge_domain_t *bd_config)
Definition: l2_bd.c:40
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:394
u32 bd_set_flags(vlib_main_t *vm, u32 bd_index, u32 flags, u32 enable)
Definition: l2_bd.c:164
#define vec_foreach_index(var, v)
Iterate over vector indices.
#define hash_set(h, key, value)
Definition: hash.h:237
#define L2_FLOOD_MEMBER_NORMAL
Definition: l2_bd.h:40
u8 * format_vnet_sw_if_index_name_with_NA(u8 *s, va_list *args)
Definition: l2_fib.c:47
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:942
#define hash_unset(h, key)
Definition: hash.h:243
u32 bvi_sw_if_index
Definition: l2_bd.h:60
always_inline u32 bd_is_valid(l2_bridge_domain_t *bd_config)
Definition: l2_bd.h:76
#define L2_FLOOD
Definition: l2_bd.h:97
#define L2_FWD
Definition: l2_bd.h:96
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:480
l2_flood_member_t * members
Definition: l2_bd.h:66
u32 bd_remove_member(l2_bridge_domain_t *bd_config, u32 sw_if_index)
Definition: l2_bd.c:127
#define L2_FLOOD_MEMBER_BVI
Definition: l2_bd.h:41
format_function_t format_ip4_address
Definition: format.h:71
format_function_t format_vnet_sw_if_index_name
vnet_main_t * vnet_get_main(void)
Definition: misc.c:45
int bd_delete_bd_index(bd_main_t *bdm, u32 bd_id)
Delete a bridge domain.
Definition: l2_bd.c:80
u8 * format_ethernet_address(u8 *s, va_list *args)
Definition: format.c:43
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:109
void bd_add_member(l2_bridge_domain_t *bd_config, l2_flood_member_t *member)
Definition: l2_bd.c:102
static clib_error_t * bd_fwd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: l2_bd.c:255
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:380
clib_error_t * l2bd_init(vlib_main_t *vm)
Definition: l2_bd.c:144
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define L2_UU_FLOOD
Definition: l2_bd.h:98
unsigned long u64
Definition: types.h:89
uword * bd_index_by_bd_id
Definition: l2_bd.h:26
unformat_function_t unformat_ip4_address
Definition: format.h:68
#define BD_REMOVE_ERROR_OK
Definition: l2_bd.c:123
#define hash_get(h, key)
Definition: hash.h:231
always_inline uword clib_bitmap_first_clear(uword *ai)
Definition: bitmap.h:343
static clib_error_t * bd_arp_entry(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: l2_bd.c:486
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:763
always_inline uword * clib_bitmap_set(uword *ai, uword i, uword value)
Definition: bitmap.h:132
static clib_error_t * bd_flood(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: l2_bd.c:304
uword * bd_index_bitmap
Definition: l2_bd.h:29
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:538
unformat_function_t unformat_ip6_address
Definition: format.h:86
#define BD_REMOVE_ERROR_NOT_FOUND
Definition: l2_bd.c:124
u32 bd_add_del_ip_mac(u32 bd_index, u8 *ip_addr, u8 *mac_addr, u8 is_ip6, u8 is_add)
Definition: l2_bd.c:447
static clib_error_t * bd_learn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: l2_bd.c:206
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:150
static clib_error_t * bd_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: l2_bd.c:582
#define hash_create(elts, value_bytes)
Definition: hash.h:615
uword unformat_ethernet_address(unformat_input_t *input, va_list *args)
Definition: format.c:187
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:87
static_always_inline l2_bridge_domain_t * l2input_bd_config_from_index(l2input_main_t *l2im, u32 bd_index)
Definition: l2_input.h:78
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:405
static clib_error_t * bd_arp_term(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: l2_bd.c:402
u64 uword
Definition: types.h:112
#define vec_elt(v, i)
Get vector value at index i.
unsigned short u16
Definition: types.h:57
l2input_main_t l2input_main
Definition: l2_input.c:72
u32 bd_find_or_add_bd_index(bd_main_t *bdm, u32 bd_id)
Get or create a bridge domain.
Definition: l2_bd.c:52
u32 feature_bitmap
Definition: l2_bd.h:54
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
#define L2_ARP_TERM
Definition: l2_bd.h:99
l2_bridge_domain_t * bd_configs
Definition: l2_input.h:66
static clib_error_t * bd_uu_flood(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: l2_bd.c:353
u8 * format_vtr(u8 *s, va_list *args)
Definition: l2_bd.c:548
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)
Definition: l2_vtr.c:230
#define vec_foreach(var, vec)
Vector iterator.
uword * mac_by_ip4
Definition: l2_bd.h:69
u32 sw_if_index
Definition: l2_bd.h:44
#define clib_error_return(e, args...)
Definition: error.h:112
struct _unformat_input_t unformat_input_t
u32 flags
Definition: vhost-user.h:73
bd_main_t bd_main
Definition: l2_bd.c:35
#define L2_LEARN
Definition: l2_bd.h:95
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".