Fix L2 flood packet replication interaction with VXLAN-tunnel
The check for input sw_if_index against output sw_if_index is not correct for the interface on the replication order after VXLAN tunnel because the encap code overwrite packet sw_if_index[VLIB_RX] with that of the VXLAN tunnel sw_if_index. The check should be done using sw_if_index[VLIB_RX] saved in the packet context. Change-Id: I175717221409977e80576e84dfe5362d1f6aed2f Signed-off-by: John Lo <loj@cisco.com>
This commit is contained in:
@ -131,7 +131,7 @@ l2flood_process (vlib_main_t * vm,
|
||||
l2flood_main_t * msm,
|
||||
u64 * counter_base,
|
||||
vlib_buffer_t * b0,
|
||||
u32 sw_if_index0,
|
||||
u32 * sw_if_index0,
|
||||
l2fib_entry_key_t * key0,
|
||||
u32 * bucket0,
|
||||
l2fib_entry_result_t * result0,
|
||||
@ -156,7 +156,7 @@ l2flood_process (vlib_main_t * vm,
|
||||
// Find first member that passes the reflection and SHG checks
|
||||
current_member = vec_len(members) - 1;
|
||||
while ((current_member >= 0) &&
|
||||
((members[current_member].sw_if_index == sw_if_index0) ||
|
||||
((members[current_member].sw_if_index == *sw_if_index0) ||
|
||||
(in_shg && members[current_member].shg == in_shg))) {
|
||||
current_member--;
|
||||
}
|
||||
@ -170,7 +170,7 @@ l2flood_process (vlib_main_t * vm,
|
||||
|
||||
if ((current_member > 0) &&
|
||||
((current_member > 1) ||
|
||||
((members[0].sw_if_index != sw_if_index0) &&
|
||||
((members[0].sw_if_index != *sw_if_index0) &&
|
||||
(!in_shg || members[0].shg != in_shg)))) {
|
||||
// If more than one member then initiate replication
|
||||
ctx = replication_prep (vm, b0, l2flood_node.index, 1 /* l2_packet */);
|
||||
@ -179,6 +179,7 @@ l2flood_process (vlib_main_t * vm,
|
||||
}
|
||||
|
||||
} else {
|
||||
vnet_buffer_opaque_t *vnet_buff_op;
|
||||
|
||||
// Do flood "recycle node" processing
|
||||
|
||||
@ -196,9 +197,13 @@ l2flood_process (vlib_main_t * vm,
|
||||
members = (l2_flood_member_t *) ctx->feature_replicas;
|
||||
current_member = (i32)ctx->feature_counter - 1;
|
||||
|
||||
// Need to update input index from saved packet context
|
||||
vnet_buff_op = (vnet_buffer_opaque_t *)ctx->vnet_buffer;
|
||||
*sw_if_index0 = vnet_buff_op->sw_if_index[VLIB_RX];
|
||||
|
||||
// Find next member that passes the reflection and SHG check
|
||||
while ((current_member >= 0) &&
|
||||
((members[current_member].sw_if_index == sw_if_index0) ||
|
||||
((members[current_member].sw_if_index == *sw_if_index0) ||
|
||||
(in_shg && members[current_member].shg == in_shg))) {
|
||||
current_member--;
|
||||
}
|
||||
@ -220,7 +225,7 @@ l2flood_process (vlib_main_t * vm,
|
||||
replication_recycle (vm, b0,
|
||||
((current_member == 0) || /*is_last */
|
||||
((current_member == 1) &&
|
||||
((members[0].sw_if_index == sw_if_index0) ||
|
||||
((members[0].sw_if_index == *sw_if_index0) ||
|
||||
(in_shg && members[0].shg == in_shg)))));
|
||||
}
|
||||
|
||||
@ -285,7 +290,6 @@ l2flood_node_fn (vlib_main_t * vm,
|
||||
vlib_buffer_t * b0, * b1;
|
||||
u32 next0, next1;
|
||||
u32 sw_if_index0, sw_if_index1;
|
||||
ethernet_header_t * h0, * h1;
|
||||
l2fib_entry_key_t key0, key1;
|
||||
l2fib_entry_result_t result0, result1;
|
||||
u32 bucket0, bucket1;
|
||||
@ -329,25 +333,21 @@ l2flood_node_fn (vlib_main_t * vm,
|
||||
sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
|
||||
sw_if_index1 = vnet_buffer(b1)->sw_if_index[VLIB_RX];
|
||||
|
||||
/* Process 2 x pkts */
|
||||
|
||||
h0 = vlib_buffer_get_current (b0);
|
||||
h1 = vlib_buffer_get_current (b1);
|
||||
|
||||
/* process 2 pkts */
|
||||
em->counters[node_counter_base_index + L2FLOOD_ERROR_L2FLOOD] += 2;
|
||||
|
||||
l2flood_process (vm, node, msm, &em->counters[node_counter_base_index],
|
||||
b0, sw_if_index0, &key0, &bucket0, &result0, &next0);
|
||||
b0, &sw_if_index0, &key0, &bucket0, &result0, &next0);
|
||||
|
||||
l2flood_process (vm, node, msm, &em->counters[node_counter_base_index],
|
||||
b1, sw_if_index1, &key1, &bucket1, &result1, &next1);
|
||||
b1, &sw_if_index1, &key1, &bucket1, &result1, &next1);
|
||||
|
||||
if (PREDICT_FALSE((node->flags & VLIB_NODE_FLAG_TRACE)))
|
||||
{
|
||||
if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
|
||||
{
|
||||
l2flood_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
|
||||
ethernet_header_t * h0 = vlib_buffer_get_current (b0);
|
||||
t->sw_if_index = sw_if_index0;
|
||||
t->bd_index = vnet_buffer(b0)->l2.bd_index;
|
||||
memcpy(t->src, h0->src_address, 6);
|
||||
@ -356,6 +356,7 @@ l2flood_node_fn (vlib_main_t * vm,
|
||||
if (PREDICT_FALSE(b1->flags & VLIB_BUFFER_IS_TRACED))
|
||||
{
|
||||
l2flood_trace_t *t = vlib_add_trace (vm, node, b1, sizeof (*t));
|
||||
ethernet_header_t * h1 = vlib_buffer_get_current (b1);
|
||||
t->sw_if_index = sw_if_index1;
|
||||
t->bd_index = vnet_buffer(b1)->l2.bd_index;
|
||||
memcpy(t->src, h1->src_address, 6);
|
||||
@ -376,7 +377,6 @@ l2flood_node_fn (vlib_main_t * vm,
|
||||
vlib_buffer_t * b0;
|
||||
u32 next0;
|
||||
u32 sw_if_index0;
|
||||
ethernet_header_t * h0;
|
||||
l2fib_entry_key_t key0;
|
||||
l2fib_entry_result_t result0;
|
||||
u32 bucket0;
|
||||
@ -393,18 +393,17 @@ l2flood_node_fn (vlib_main_t * vm,
|
||||
|
||||
sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
|
||||
|
||||
h0 = vlib_buffer_get_current (b0);
|
||||
|
||||
/* process 1 pkt */
|
||||
em->counters[node_counter_base_index + L2FLOOD_ERROR_L2FLOOD] += 1;
|
||||
|
||||
l2flood_process (vm, node, msm, &em->counters[node_counter_base_index],
|
||||
b0, sw_if_index0, &key0, &bucket0, &result0, &next0);
|
||||
b0, &sw_if_index0, &key0, &bucket0, &result0, &next0);
|
||||
|
||||
if (PREDICT_FALSE((node->flags & VLIB_NODE_FLAG_TRACE) &&
|
||||
(b0->flags & VLIB_BUFFER_IS_TRACED)))
|
||||
{
|
||||
l2flood_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
|
||||
ethernet_header_t * h0 = vlib_buffer_get_current (b0);
|
||||
t->sw_if_index = sw_if_index0;
|
||||
t->bd_index = vnet_buffer(b0)->l2.bd_index;
|
||||
memcpy(t->src, h0->src_address, 6);
|
||||
|
Reference in New Issue
Block a user