aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEyal Bari <ebari@cisco.com>2017-04-20 14:45:17 +0300
committerJohn Lo <loj@cisco.com>2017-05-03 13:48:11 +0000
commitafc47aa36f44d3f865c6e1e48f41eded366a85ac (patch)
tree8d9b9ef47ea524f965174d6b81260d1f418bb5d8
parente72be39cd0f498178fd62dfc0a0b0daa2b633f62 (diff)
L2FIB:flush interface learned macs on down
Change-Id: I80a723f55fcf2ecc3209a35e8297c88b45b1abfb Signed-off-by: Eyal Bari <ebari@cisco.com>
-rw-r--r--src/vnet/l2/l2_bd.c15
-rw-r--r--src/vnet/l2/l2_fib.c13
-rw-r--r--src/vnet/l2/l2_input.c42
-rw-r--r--src/vnet/l2/l2_input.h11
4 files changed, 42 insertions, 39 deletions
diff --git a/src/vnet/l2/l2_bd.c b/src/vnet/l2/l2_bd.c
index 4ebbb547134..4d540220a35 100644
--- a/src/vnet/l2/l2_bd.c
+++ b/src/vnet/l2/l2_bd.c
@@ -94,6 +94,8 @@ bd_delete (bd_main_t * bdm, u32 bd_index)
{
l2_bridge_domain_t *bd = &l2input_main.bd_configs[bd_index];
u32 bd_id = bd->bd_id;
+ l2fib_flush_bd_mac (vlib_get_main (), bd_index);
+
hash_unset (bdm->bd_index_by_bd_id, bd_id);
/* mark this index clear */
@@ -107,7 +109,6 @@ bd_delete (bd_main_t * bdm, u32 bd_index)
vec_free (bd->members);
hash_free (bd->mac_by_ip4);
hash_free (bd->mac_by_ip6);
- l2fib_flush_bd_mac (vlib_get_main (), bd_index);
return 0;
}
@@ -219,13 +220,9 @@ u32
bd_set_flags (vlib_main_t * vm, u32 bd_index, u32 flags, u32 enable)
{
- l2_bridge_domain_t *bd_config;
- u32 feature_bitmap = 0;
-
- vec_validate (l2input_main.bd_configs, bd_index);
- bd_config = vec_elt_at_index (l2input_main.bd_configs, bd_index);
-
+ l2_bridge_domain_t *bd_config = l2input_bd_config (bd_index);
bd_validate (bd_config);
+ u32 feature_bitmap = 0;
if (flags & L2_LEARN)
{
@@ -713,13 +710,13 @@ u32
bd_add_del_ip_mac (u32 bd_index,
u8 * ip_addr, u8 * mac_addr, u8 is_ip6, u8 is_add)
{
- l2input_main_t *l2im = &l2input_main;
- l2_bridge_domain_t *bd_cfg = l2input_bd_config_from_index (l2im, bd_index);
+ l2_bridge_domain_t *bd_cfg = l2input_bd_config (bd_index);
u64 new_mac = *(u64 *) mac_addr;
u64 *old_mac;
u16 *mac16 = (u16 *) & new_mac;
ASSERT (sizeof (uword) == sizeof (u64)); /* make sure uword is 8 bytes */
+ ASSERT (bd_is_valid (bd_cfg));
mac16[3] = 0; /* Clear last 2 unsed bytes of the 8-byte MAC address */
if (is_ip6)
diff --git a/src/vnet/l2/l2_fib.c b/src/vnet/l2/l2_fib.c
index fadd79ebdf6..d8fcc319567 100644
--- a/src/vnet/l2/l2_fib.c
+++ b/src/vnet/l2/l2_fib.c
@@ -751,8 +751,7 @@ void
l2fib_flush_bd_mac (vlib_main_t * vm, u32 bd_index)
{
l2_bridge_domain_t *bd_config;
- vec_validate (l2input_main.bd_configs, bd_index);
- bd_config = vec_elt_at_index (l2input_main.bd_configs, bd_index);
+ bd_config = l2input_bd_config (bd_index);
bd_config->seq_num += 1;
l2fib_start_ager_scan (vm);
}
@@ -848,6 +847,16 @@ VLIB_CLI_COMMAND (l2fib_flush_mac_bd_cli, static) = {
};
/* *INDENT-ON* */
+clib_error_t *
+l2fib_sw_interface_up_down (vnet_main_t * vnm, u32 sw_if_index, u32 flags)
+{
+ l2_input_config_t *config = l2input_intf_config (sw_if_index);
+ if ((flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0 && config->bridge)
+ l2fib_flush_int_mac (vnm->vlib_main, sw_if_index);
+ return 0;
+}
+
+VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (l2fib_sw_interface_up_down);
BVT (clib_bihash) * get_mac_table (void)
{
diff --git a/src/vnet/l2/l2_input.c b/src/vnet/l2/l2_input.c
index e5d6878a7ae..fe65e694f3b 100644
--- a/src/vnet/l2/l2_input.c
+++ b/src/vnet/l2/l2_input.c
@@ -481,20 +481,12 @@ l2input_intf_config (u32 sw_if_index)
u32
l2input_intf_bitmap_enable (u32 sw_if_index, u32 feature_bitmap, u32 enable)
{
- l2input_main_t *mp = &l2input_main;
- l2_input_config_t *config;
-
- vec_validate (mp->configs, sw_if_index);
- config = vec_elt_at_index (mp->configs, sw_if_index);
+ l2_input_config_t *config = l2input_intf_config (sw_if_index);
if (enable)
- {
- config->feature_bitmap |= feature_bitmap;
- }
+ config->feature_bitmap |= feature_bitmap;
else
- {
- config->feature_bitmap &= ~feature_bitmap;
- }
+ config->feature_bitmap &= ~feature_bitmap;
return config->feature_bitmap;
}
@@ -502,9 +494,7 @@ l2input_intf_bitmap_enable (u32 sw_if_index, u32 feature_bitmap, u32 enable)
u32
l2input_set_bridge_features (u32 bd_index, u32 feat_mask, u32 feat_value)
{
- l2_bridge_domain_t *bd_config;
- vec_validate (l2input_main.bd_configs, bd_index);
- bd_config = vec_elt_at_index (l2input_main.bd_configs, bd_index);
+ l2_bridge_domain_t *bd_config = l2input_bd_config (bd_index);;
bd_validate (bd_config);
bd_config->feature_bitmap =
(bd_config->feature_bitmap & ~feat_mask) | feat_value;
@@ -535,7 +525,6 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /* */
l2_output_config_t *out_config;
l2_input_config_t *config;
l2_bridge_domain_t *bd_config;
- l2_flood_member_t member;
u64 mac;
i32 l2_if_adjust = 0;
u32 slot;
@@ -570,8 +559,8 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /* */
}
/* Clear MACs learned on the interface */
- if ((config->feature_bitmap | L2INPUT_FEAT_LEARN) ||
- (bd_config->feature_bitmap | L2INPUT_FEAT_LEARN))
+ if ((config->feature_bitmap & L2INPUT_FEAT_LEARN) ||
+ (bd_config->feature_bitmap & L2INPUT_FEAT_LEARN))
l2fib_flush_int_mac (vm, sw_if_index);
l2_if_adjust--;
@@ -661,8 +650,7 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /* */
config->feature_bitmap &= ~L2INPUT_FEAT_XCONNECT;
/* Set up bridge domain */
- vec_validate (mp->bd_configs, bd_index);
- bd_config = vec_elt_at_index (mp->bd_configs, bd_index);
+ bd_config = l2input_bd_config (bd_index);
bd_validate (bd_config);
/* TODO: think: add l2fib entry even for non-bvi interface? */
@@ -694,9 +682,11 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /* */
}
/* Add interface to bridge-domain flood vector */
- member.sw_if_index = sw_if_index;
- member.flags = bvi ? L2_FLOOD_MEMBER_BVI : L2_FLOOD_MEMBER_NORMAL;
- member.shg = shg;
+ l2_flood_member_t member = {
+ .sw_if_index = sw_if_index,
+ .flags = bvi ? L2_FLOOD_MEMBER_BVI : L2_FLOOD_MEMBER_NORMAL,
+ .shg = shg,
+ };
bd_add_member (bd_config, &member);
}
@@ -997,10 +987,8 @@ show_int_mode (vlib_main_t * vm,
char *mode;
u8 *args;
vnet_interface_main_t *im = &vnm->interface_main;
- vnet_sw_interface_t *si, *sis = 0;
- l2input_main_t *mp = &l2input_main;
- l2_input_config_t *config;
+ vnet_sw_interface_t *si, *sis = 0;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
u32 sw_if_index;
@@ -1018,7 +1006,6 @@ show_int_mode (vlib_main_t * vm,
format_unformat_error, input);
goto done;
}
-
}
if (vec_len (sis) == 0) /* Get all interfaces */
@@ -1033,8 +1020,7 @@ show_int_mode (vlib_main_t * vm,
vec_foreach (si, sis)
{
- vec_validate (mp->configs, si->sw_if_index);
- config = vec_elt_at_index (mp->configs, si->sw_if_index);
+ l2_input_config_t *config = l2input_intf_config (si->sw_if_index);
if (config->bridge)
{
u32 bd_id;
diff --git a/src/vnet/l2/l2_input.h b/src/vnet/l2/l2_input.h
index a2ade8d8e1e..cb67cb9d20e 100644
--- a/src/vnet/l2/l2_input.h
+++ b/src/vnet/l2/l2_input.h
@@ -89,6 +89,17 @@ l2input_bd_config_from_index (l2input_main_t * l2im, u32 bd_index)
return bd_is_valid (bd_config) ? bd_config : NULL;
}
+static_always_inline l2_bridge_domain_t *
+l2input_bd_config (u32 bd_index)
+{
+ l2input_main_t *mp = &l2input_main;
+ l2_bridge_domain_t *bd_config;
+
+ vec_validate (mp->bd_configs, bd_index);
+ bd_config = vec_elt_at_index (mp->bd_configs, bd_index);
+ return bd_config;
+}
+
/* L2 input indication packet is from BVI, using -2 */
#define L2INPUT_BVI ((u32) (~0-1))