diff options
-rw-r--r-- | src/vat/api_format.c | 4 | ||||
-rw-r--r-- | src/vnet/l2/l2_api.c | 4 | ||||
-rw-r--r-- | src/vnet/l2/l2_fib.c | 115 | ||||
-rw-r--r-- | src/vnet/l2/l2_fib.h | 2 | ||||
-rw-r--r-- | src/vnet/l2/l2_input.c | 2 |
5 files changed, 71 insertions, 56 deletions
diff --git a/src/vat/api_format.c b/src/vat/api_format.c index ca9ebec698e..dfb0284955e 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -7354,7 +7354,7 @@ api_l2fib_add_del (vat_main_t * vam) u8 mac_set = 0; u32 bd_id; u8 bd_id_set = 0; - u32 sw_if_index = ~0; + u32 sw_if_index = 0; u8 sw_if_index_set = 0; u8 is_add = 1; u8 static_mac = 0; @@ -7437,10 +7437,10 @@ api_l2fib_add_del (vat_main_t * vam) clib_memcpy (mp->mac, mac, 6); mp->bd_id = ntohl (bd_id); mp->is_add = is_add; + mp->sw_if_index = ntohl (sw_if_index); if (is_add) { - mp->sw_if_index = ntohl (sw_if_index); mp->static_mac = static_mac; mp->filter_mac = filter_mac; mp->bvi_mac = bvi_mac; diff --git a/src/vnet/l2/l2_api.c b/src/vnet/l2/l2_api.c index 0fe119b0db0..ebb64ff2420 100644 --- a/src/vnet/l2/l2_api.c +++ b/src/vnet/l2/l2_api.c @@ -239,7 +239,9 @@ vl_api_l2fib_add_del_t_handler (vl_api_l2fib_add_del_t * mp) } else { - l2fib_del_entry (mac, bd_index); + u32 sw_if_index = ntohl (mp->sw_if_index); + if (l2fib_del_entry (mac, bd_index, sw_if_index)) + rv = VNET_API_ERROR_NO_SUCH_ENTRY; } BAD_SW_IF_INDEX_LABEL; diff --git a/src/vnet/l2/l2_fib.c b/src/vnet/l2/l2_fib.c index 918700b2129..959cf4dea17 100644 --- a/src/vnet/l2/l2_fib.c +++ b/src/vnet/l2/l2_fib.c @@ -140,35 +140,52 @@ show_l2fib (vlib_main_t * vm, u8 verbose = 0; u8 raw = 0; u8 learn = 0; + u8 add = 0; u32 bd_id, bd_index = ~0; u8 now = (u8) (vlib_time_now (vm) / 60); u8 *s = 0; - if (unformat (input, "raw")) - raw = 1; - else if (unformat (input, "verbose")) - verbose = 1; - else if (unformat (input, "bd_index %d", &bd_index)) - verbose = 1; - else if (unformat (input, "learn")) - { - learn = 1; - verbose = 0; - } - else if (unformat (input, "bd_id %d", &bd_id)) + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { - uword *p = hash_get (bdm->bd_index_by_bd_id, bd_id); - if (p) + if (unformat (input, "raw")) { - if (learn == 0) - verbose = 1; - bd_index = p[0]; + raw = 1; + verbose = 0; + break; } - else + else if (unformat (input, "verbose")) + verbose = 1; + else if (unformat (input, "all")) + verbose = 1; + else if (unformat (input, "bd_index %d", &bd_index)) + verbose = 1; + else if (unformat (input, "learn")) + { + add = 0; + learn = 1; + verbose = 1; + } + else if (unformat (input, "add")) + { + learn = 0; + add = 1; + verbose = 1; + } + else if (unformat (input, "bd_id %d", &bd_id)) { - vlib_cli_output (vm, "no such bridge domain id"); - return 0; + uword *p = hash_get (bdm->bd_index_by_bd_id, bd_id); + if (p) + { + verbose = 1; + bd_index = p[0]; + } + else + return clib_error_return (0, + "bridge domain id %d doesn't exist\n", + bd_id); } + else + break; } for (i = 0; i < h->nbuckets; i++) @@ -184,7 +201,7 @@ show_l2fib (vlib_main_t * vm, if (v->kvp[k].key == ~0ULL && v->kvp[k].value == ~0ULL) continue; - if ((verbose || learn) && first_entry) + if (verbose && first_entry) { first_entry = 0; vlib_cli_output (vm, @@ -196,27 +213,30 @@ show_l2fib (vlib_main_t * vm, key.raw = v->kvp[k].key; result.raw = v->kvp[k].value; + total_entries++; - if ((verbose || learn) - & ((bd_index >> 31) || (bd_index == key.fields.bd_index))) + if (verbose && + ((bd_index >> 31) || (bd_index == key.fields.bd_index))) { if (learn && result.fields.age_not) - { - total_entries++; - continue; /* skip provisioned macs */ - } + continue; /* skip provisioned macs */ + + if (add && !result.fields.age_not) + continue; /* skip learned macs */ bd_config = vec_elt_at_index (l2input_main.bd_configs, key.fields.bd_index); - if (bd_config->mac_age && !result.fields.age_not) + if (result.fields.age_not) + s = format (s, "no"); + else if (bd_config->mac_age == 0) + s = format (s, "-"); + else { i16 delta = now - result.fields.timestamp; delta += delta < 0 ? 256 : 0; s = format (s, "%d", delta); } - else - s = format (s, "-"); vlib_cli_output (vm, "%=19U%=7d%=7d %3d/%-3d%=9v%=7s%=7s%=5s%=30U", @@ -232,7 +252,6 @@ show_l2fib (vlib_main_t * vm, msm->vnet_main, result.fields.sw_if_index); vec_reset_length (s); } - total_entries++; } v++; } @@ -276,7 +295,7 @@ show_l2fib (vlib_main_t * vm, * @cliexend * Example of how to display all the MAC Address entries in the L2 * FIB table: - * @cliexstart{show l2fib verbose} + * @cliexstart{show l2fib all} * Mac Address BD Idx Interface Index static filter bvi refresh timestamp * 52:54:00:53:18:33 1 GigabitEthernet0/8/0.200 3 0 0 0 0 0 * 52:54:00:53:18:55 1 GigabitEthernet0/8/0.200 3 1 0 0 0 0 @@ -287,7 +306,7 @@ show_l2fib (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_l2fib_cli, static) = { .path = "show l2fib", - .short_help = "show l2fib [verbose | learn | bd_id <nn> | bd_index <nn> | raw", + .short_help = "show l2fib [all] | [bd_id <nn> | bd_index <nn>] [learn | add] | [raw]", .function = show_l2fib, }; /* *INDENT-ON* */ @@ -580,7 +599,7 @@ l2fib_test_command_fn (vlib_main_t * vm, for (i = 0; i < count; i++) { - l2fib_del_entry (mac, bd_index); + l2fib_del_entry (mac, bd_index, 0); incr_mac_address (mac); } } @@ -636,24 +655,28 @@ VLIB_CLI_COMMAND (l2fib_test_command, static) = { /** * Delete an entry from the l2fib. - * Return 0 if the entry was deleted, or 1 if it was not found + * Return 0 if the entry was deleted, or 1 it was not found or if + * sw_if_index is non-zero and does not match that in the entry. */ -static u32 -l2fib_del_entry_by_key (u64 raw_key) +u32 +l2fib_del_entry (u8 * mac, u32 bd_index, u32 sw_if_index) { - l2fib_entry_result_t result; l2fib_main_t *mp = &l2fib_main; BVT (clib_bihash_kv) kv; /* set up key */ - kv.key = raw_key; + kv.key = l2fib_make_key (mac, bd_index); if (BV (clib_bihash_search) (&mp->mac_table, &kv, &kv)) return 1; result.raw = kv.value; + /* check if sw_if_index of entry match */ + if ((sw_if_index != 0) && (sw_if_index != result.fields.sw_if_index)) + return 1; + /* decrement counter if dynamically learned mac */ if ((result.fields.age_not == 0) && (l2learn_main.global_learn_count)) l2learn_main.global_learn_count--; @@ -664,16 +687,6 @@ l2fib_del_entry_by_key (u64 raw_key) } /** - * Delete an entry from the l2fib. - * Return 0 if the entry was deleted, or 1 if it was not found - */ -u32 -l2fib_del_entry (u8 * mac, u32 bd_index) -{ - return l2fib_del_entry_by_key (l2fib_make_key (mac, bd_index)); -} - -/** * Delete an entry from the L2FIB. * The CLI format is: * l2fib del <mac> <bd-id> @@ -712,7 +725,7 @@ l2fib_del (vlib_main_t * vm, bd_index = p[0]; /* Delete the entry */ - if (l2fib_del_entry (mac, bd_index)) + if (l2fib_del_entry (mac, bd_index, 0)) { error = clib_error_return (0, "mac entry not found"); goto done; @@ -733,7 +746,7 @@ done: /* *INDENT-OFF* */ VLIB_CLI_COMMAND (l2fib_del_cli, static) = { .path = "l2fib del", - .short_help = "l2fib del <mac> <bridge-domain-id>", + .short_help = "l2fib del <mac> <bridge-domain-id> []", .function = l2fib_del, }; /* *INDENT-ON* */ diff --git a/src/vnet/l2/l2_fib.h b/src/vnet/l2/l2_fib.h index ad7035bff54..50fd474087b 100644 --- a/src/vnet/l2/l2_fib.h +++ b/src/vnet/l2/l2_fib.h @@ -402,7 +402,7 @@ l2fib_add_filter_entry (u8 * mac, u32 bd_index) l2fib_add_entry (mac, bd_index, ~0, 1, 1, 0); } -u32 l2fib_del_entry (u8 * mac, u32 bd_index); +u32 l2fib_del_entry (u8 * mac, u32 bd_index, u32 sw_if_index); void l2fib_start_ager_scan (vlib_main_t * vm); diff --git a/src/vnet/l2/l2_input.c b/src/vnet/l2/l2_input.c index 69de2815536..6e3851e8512 100644 --- a/src/vnet/l2/l2_input.c +++ b/src/vnet/l2/l2_input.c @@ -587,7 +587,7 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /* */ config->bvi = 0; /* delete the l2fib entry for the bvi interface */ - l2fib_del_entry (hi->hw_address, config->bd_index); + l2fib_del_entry (hi->hw_address, config->bd_index, sw_if_index); /* Make loop output node send packet back to ethernet-input node */ slot = |