Fix L2 flood packet replication interaction with VXLAN-tunnel 02/602/1
authorJohn Lo <loj@cisco.com>
Wed, 23 Mar 2016 23:44:39 +0000 (19:44 -0400)
committerJohn Lo <loj@cisco.com>
Wed, 23 Mar 2016 23:44:39 +0000 (19:44 -0400)
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>
vnet/vnet/l2/l2_flood.c

index 8a70216..0d25f58 100644 (file)
@@ -131,7 +131,7 @@ l2flood_process (vlib_main_t * vm,
                  l2flood_main_t * msm,
                  u64 * counter_base,
                  vlib_buffer_t * b0,
                  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,
                  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) && 
     // 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--;
     }
            (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) || 
 
     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 */);
          (!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 {
     }
 
   } else {
+    vnet_buffer_opaque_t *vnet_buff_op;
 
     // Do flood "recycle node" processing
 
 
     // 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;
 
     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) &&
     // 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--;
     }
            (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) && 
     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)))));
   }
 
          (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;
          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;
           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];
 
           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],
             /* 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],
 
             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));
 
           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);
                   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));
               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);
                   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;
          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;
           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];
  
 
           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],
           /* 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));
 
           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);
               t->sw_if_index = sw_if_index0;
               t->bd_index = vnet_buffer(b0)->l2.bd_index;
               memcpy(t->src, h0->src_address, 6);