diff options
Diffstat (limited to 'vnet/vnet/l2/l2_bd.c')
-rw-r--r-- | vnet/vnet/l2/l2_bd.c | 82 |
1 files changed, 57 insertions, 25 deletions
diff --git a/vnet/vnet/l2/l2_bd.c b/vnet/vnet/l2/l2_bd.c index 0b5656e6d2c..e2ef6797489 100644 --- a/vnet/vnet/l2/l2_bd.c +++ b/vnet/vnet/l2/l2_bd.c @@ -54,6 +54,9 @@ bd_validate (l2_bridge_domain_t * bd_config) bd_config->feature_bitmap = ~L2INPUT_FEAT_ARP_TERM; bd_config->bvi_sw_if_index = ~0; bd_config->members = 0; + bd_config->flood_count = 0; + bd_config->tun_master_count = 0; + bd_config->tun_normal_count = 0; bd_config->mac_by_ip4 = 0; bd_config->mac_by_ip6 = hash_create_mem (0, sizeof (ip6_address_t), sizeof (uword)); @@ -114,32 +117,49 @@ bd_delete_bd_index (bd_main_t * bdm, u32 bd_id) return 0; } +static void +update_flood_count (l2_bridge_domain_t * bd_config) +{ + bd_config->flood_count = vec_len (bd_config->members) - + (bd_config->tun_master_count ? bd_config->tun_normal_count : 0); +} + void bd_add_member (l2_bridge_domain_t * bd_config, l2_flood_member_t * member) { + u32 ix; + vnet_sw_interface_t *sw_if = vnet_get_sw_interface + (vnet_get_main (), member->sw_if_index); + /* * Add one element to the vector - * + * vector is ordered [ bvi, normal/tun_masters..., tun_normals... ] * When flooding, the bvi interface (if present) must be the last member * processed due to how BVI processing can change the packet. To enable * this order, we make the bvi interface the first in the vector and * flooding walks the vector in reverse. */ - if ((member->flags == L2_FLOOD_MEMBER_NORMAL) || - (vec_len (bd_config->members) == 0)) + switch (sw_if->flood_class) { - vec_add1 (bd_config->members, *member); - - } - else - { - /* Move 0th element to the end */ - vec_add1 (bd_config->members, bd_config->members[0]); - bd_config->members[0] = *member; - } + case VNET_FLOOD_CLASS_TUNNEL_MASTER: + bd_config->tun_master_count++; + /* Fall through */ + default: + /* Fall through */ + case VNET_FLOOD_CLASS_NORMAL: + ix = (member->flags & L2_FLOOD_MEMBER_BVI) ? 0 : + vec_len (bd_config->members) - bd_config->tun_normal_count; + break; + case VNET_FLOOD_CLASS_TUNNEL_NORMAL: + ix = vec_len (bd_config->members); + bd_config->tun_normal_count++; + break; + } + + vec_insert_elts (bd_config->members, member, 1, ix); + update_flood_count (bd_config); } - #define BD_REMOVE_ERROR_OK 0 #define BD_REMOVE_ERROR_NOT_FOUND 1 @@ -151,9 +171,22 @@ bd_remove_member (l2_bridge_domain_t * bd_config, u32 sw_if_index) /* Find and delete the member */ vec_foreach_index (ix, bd_config->members) { - if (vec_elt (bd_config->members, ix).sw_if_index == sw_if_index) + l2_flood_member_t *m = vec_elt_at_index (bd_config->members, ix); + if (m->sw_if_index == sw_if_index) { + vnet_sw_interface_t *sw_if = vnet_get_sw_interface + (vnet_get_main (), sw_if_index); + + if (sw_if->flood_class != VNET_FLOOD_CLASS_NORMAL) + { + if (sw_if->flood_class == VNET_FLOOD_CLASS_TUNNEL_MASTER) + bd_config->tun_master_count--; + else if (sw_if->flood_class == VNET_FLOOD_CLASS_TUNNEL_NORMAL) + bd_config->tun_normal_count--; + } vec_del1 (bd_config->members, ix); + update_flood_count (bd_config); + return BD_REMOVE_ERROR_OK; } } @@ -854,28 +887,27 @@ bd_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) if (detail || intf) { /* Show all member interfaces */ - - l2_flood_member_t *member; - u32 header = 0; - - vec_foreach (member, bd_config->members) + int i; + vec_foreach_index (i, bd_config->members) { + l2_flood_member_t *member = + vec_elt_at_index (bd_config->members, i); u32 vtr_opr, dot1q, tag1, tag2; - if (!header) + if (i == 0) { - header = 1; - vlib_cli_output (vm, "\n%=30s%=7s%=5s%=5s%=30s", + vlib_cli_output (vm, "\n%=30s%=7s%=5s%=5s%=9s%=30s", "Interface", "Index", "SHG", "BVI", - "VLAN-Tag-Rewrite"); + "TxFlood", "VLAN-Tag-Rewrite"); } l2vtr_get (vm, vnm, member->sw_if_index, &vtr_opr, &dot1q, &tag1, &tag2); - vlib_cli_output (vm, "%=30U%=7d%=5d%=5s%=30U", + vlib_cli_output (vm, "%=30U%=7d%=5d%=5s%=9s%=30U", format_vnet_sw_if_index_name, vnm, member->sw_if_index, member->sw_if_index, member->shg, member->flags & L2_FLOOD_MEMBER_BVI ? "*" : - "-", format_vtr, vtr_opr, dot1q, tag1, tag2); + "-", i < bd_config->flood_count ? "*" : "-", + format_vtr, vtr_opr, dot1q, tag1, tag2); } } |