L2FWD:fix seq_num overwritten + validate l2fib entries when forwarding
l2_classify memeber table_index was overlaid over l2.l2fib_seq_num
which over written when table_index gets initialized in l2_input_classify
solved by overlaying both table_index and opaque_index as only one is used
seperated l2fib seq num from l2_input configs
for better handling of theoretical ABA issue where an entry for a deleted
interface is considered valid by the ager because a different interface with
same sw_if_index and seq_num was created before the ager got a chance to delete
Change-Id: I7b0eeded971627406f1c80834d7e02c0ebe62136
Signed-off-by: Eyal Bari <ebari@cisco.com>
diff --git a/src/vnet/l2/l2_fwd.c b/src/vnet/l2/l2_fwd.c
index f7e2ccb..8140728 100644
--- a/src/vnet/l2/l2_fwd.c
+++ b/src/vnet/l2/l2_fwd.c
@@ -89,7 +89,8 @@
_(BVI_BAD_MAC, "BVI L3 MAC mismatch") \
_(BVI_ETHERTYPE, "BVI packet with unhandled ethertype") \
_(FILTER_DROP, "Filter Mac Drop") \
-_(REFLECT_DROP, "Reflection Drop")
+_(REFLECT_DROP, "Reflection Drop") \
+_(STALE_DROP, "Stale entry Drop")
typedef enum
{
@@ -123,28 +124,15 @@
vlib_buffer_t * b0,
u32 sw_if_index0, l2fib_entry_result_t * result0, u32 * next0)
{
- if (PREDICT_FALSE (result0->raw == ~0))
- {
- /*
- * lookup miss, so flood
- * TODO:replicate packet to each intf in bridge-domain
- * For now just drop
- */
- if (vnet_buffer (b0)->l2.feature_bitmap & L2INPUT_FEAT_UU_FLOOD)
- {
- *next0 = L2FWD_NEXT_FLOOD;
- }
- else
- {
- /* Flooding is disabled */
- b0->error = node->errors[L2FWD_ERROR_FLOOD];
- *next0 = L2FWD_NEXT_DROP;
- }
+ int try_flood = result0->raw == ~0;
+ int flood_error;
+ if (PREDICT_FALSE (try_flood))
+ {
+ flood_error = L2FWD_ERROR_FLOOD;
}
else
{
-
/* lookup hit, forward packet */
#ifdef COUNTERS
em->counters[node_counter_base_index + L2FWD_ERROR_HIT] += 1;
@@ -152,22 +140,37 @@
vnet_buffer (b0)->sw_if_index[VLIB_TX] = result0->fields.sw_if_index;
*next0 = L2FWD_NEXT_L2_OUTPUT;
+ int l2fib_seq_num_valid = 1;
+ /* check l2fib seq num for stale entries */
+ if (!result0->fields.static_mac)
+ {
+ l2fib_seq_num_t in_sn = {.as_u16 = vnet_buffer (b0)->l2.l2fib_sn };
+ l2fib_seq_num_t expected_sn = {
+ .bd = in_sn.bd,
+ .swif = *l2fib_swif_seq_num (result0->fields.sw_if_index),
+ };
+ l2fib_seq_num_valid =
+ expected_sn.as_u16 == result0->fields.sn.as_u16;
+ }
+ if (PREDICT_FALSE (!l2fib_seq_num_valid))
+ {
+ flood_error = L2FWD_ERROR_STALE_DROP;
+ try_flood = 1;
+ }
/* perform reflection check */
- if (PREDICT_FALSE (sw_if_index0 == result0->fields.sw_if_index))
+ else if (PREDICT_FALSE (sw_if_index0 == result0->fields.sw_if_index))
{
b0->error = node->errors[L2FWD_ERROR_REFLECT_DROP];
*next0 = L2FWD_NEXT_DROP;
-
- /* perform filter check */
}
+ /* perform filter check */
else if (PREDICT_FALSE (result0->fields.filter))
{
b0->error = node->errors[L2FWD_ERROR_FILTER_DROP];
*next0 = L2FWD_NEXT_DROP;
-
- /* perform BVI check */
}
+ /* perform BVI check */
else if (PREDICT_FALSE (result0->fields.bvi))
{
u32 rc;
@@ -192,6 +195,27 @@
}
}
}
+
+ /* flood */
+ if (PREDICT_FALSE (try_flood))
+ {
+ /*
+ * lookup miss, so flood
+ * TODO:replicate packet to each intf in bridge-domain
+ * For now just drop
+ */
+ if (vnet_buffer (b0)->l2.feature_bitmap & L2INPUT_FEAT_UU_FLOOD)
+ {
+ *next0 = L2FWD_NEXT_FLOOD;
+ }
+ else
+ {
+ /* Flooding is disabled */
+ b0->error = node->errors[flood_error];
+ *next0 = L2FWD_NEXT_DROP;
+ }
+ }
+
}