summaryrefslogtreecommitdiffstats
path: root/src/vnet/l2
diff options
context:
space:
mode:
authorJohn Lo <loj@cisco.com>2018-05-31 10:25:18 -0400
committerFlorin Coras <florin.coras@gmail.com>2018-05-31 23:30:19 +0000
commit7dbd7265daf6fa0f522870586036c89a99bc4958 (patch)
treecba4a7ed53b36b3640e0942d10c88fc238d56e07 /src/vnet/l2
parenta059a000f81a7251ffed2821f69dd96cfd94c8c7 (diff)
Improve L2FIB delete entry handling and "show l2fib" CLI options
Improve deletion of L2FIB MAC entry using l2fib_add_del API. If sw_if_index param specified in th API is non-zero, check that its value match that of the MAC entry to proceed with deletion. Improve "show l2fib" CLI to allow display of all entries, learned entries only, or added ovia CLI/API entries only. For added entry, show "no" under the age column to indicate entry does not age. Change-Id: I0bd2582c2b6bac268e551e4f8ca6dab2be4400ad Signed-off-by: John Lo <loj@cisco.com>
Diffstat (limited to 'src/vnet/l2')
-rw-r--r--src/vnet/l2/l2_api.c4
-rw-r--r--src/vnet/l2/l2_fib.c115
-rw-r--r--src/vnet/l2/l2_fib.h2
-rw-r--r--src/vnet/l2/l2_input.c2
4 files changed, 69 insertions, 54 deletions
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 =