Fix crash with worker threads on 4K VXLAN/BD setup (VPP-907)
[vpp.git] / src / vnet / l2 / l2_input.c
index fe65e69..9a3148c 100644 (file)
@@ -202,8 +202,14 @@ classify_and_dispatch (vlib_main_t * vm,
       /* Get config for the bridge domain interface */
       bd_config = vec_elt_at_index (msm->bd_configs, bd_index0);
 
-      /* Save bridge domain seq_num */
-      vnet_buffer (b0)->l2.bd_sn = bd_config->seq_num;
+      /* Save bridge domain and interface seq_num */
+      /* *INDENT-OFF* */
+      l2fib_seq_num_t sn = {
+        .swif = *l2fib_swif_seq_num(sw_if_index0),
+       .bd = bd_config->seq_num,
+      };
+      /* *INDENT-ON* */
+      vnet_buffer (b0)->l2.l2fib_sn = sn.as_u16;;
 
       /*
        * Process bridge domain feature enables.
@@ -218,9 +224,6 @@ classify_and_dispatch (vlib_main_t * vm,
   /* mask out features from bitmap using packet type and bd config */
   feature_bitmap = config->feature_bitmap & feat_mask;
 
-  /* Save interface seq_num */
-  vnet_buffer (b0)->l2.int_sn = config->seq_num;
-
   /* save for next feature graph nodes */
   vnet_buffer (b0)->l2.feature_bitmap = feature_bitmap;
 
@@ -570,13 +573,9 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main,        /*           */
       l2_if_adjust--;
     }
 
-  /*
-   * Directs the l2 output path to work out the interface
-   * output next-arc itself. Needed when recycling a sw_if_index.
-   */
+  /* Make sure vector is big enough */
   vec_validate_init_empty (l2om->next_nodes.output_node_index_vec,
-                          sw_if_index, ~0);
-  l2om->next_nodes.output_node_index_vec[sw_if_index] = ~0;
+                          sw_if_index, L2OUTPUT_NEXT_DROP);
 
   /* Initialize the l2-input configuration for the interface */
   if (mode == MODE_L3)
@@ -598,26 +597,11 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main,       /*           */
       l2om->next_nodes.output_node_index_vec[sw_if_index] =
        L2OUTPUT_NEXT_BAD_INTF;
     }
-  else if (mode == MODE_L2_CLASSIFY)
-    {
-      config->xconnect = 1;
-      config->bridge = 0;
-      config->output_sw_if_index = xc_sw_if_index;
-
-      /* Make sure last-chance drop is configured */
-      config->feature_bitmap |=
-       L2INPUT_FEAT_DROP | L2INPUT_FEAT_INPUT_CLASSIFY;
-
-      /* Make sure bridging features are disabled */
-      config->feature_bitmap &=
-       ~(L2INPUT_FEAT_LEARN | L2INPUT_FEAT_FWD | L2INPUT_FEAT_FLOOD);
-      shg = 0;                 /* not used in xconnect */
-
-      /* Insure all packets go to ethernet-input */
-      ethernet_set_rx_redirect (vnet_main, hi, 1);
-    }
   else
     {
+      /* Add or update l2-output node next-arc and output_node_index_vec table
+       * for the interface */
+      l2output_create_output_node_mapping (vm, vnet_main, sw_if_index);
 
       if (mode == MODE_L2_BRIDGE)
        {
@@ -634,7 +618,7 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /*           */
          config->xconnect = 0;
          config->bridge = 1;
          config->bd_index = bd_index;
-         config->seq_num += 1;
+         *l2fib_swif_seq_num (sw_if_index) += 1;
 
          /*
           * Enable forwarding, flooding, learning and ARP termination by default
@@ -668,7 +652,7 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /*           */
 
              /* create the l2fib entry for the bvi interface */
              mac = *((u64 *) hi->hw_address);
-             l2fib_add_entry (mac, bd_index, sw_if_index, 1, 0, 1);    /* static + bvi */
+             l2fib_add_fwd_entry (mac, bd_index, sw_if_index, 1, 1);   /* static + bvi */
 
              /* Disable learning by default. no use since l2fib entry is static. */
              config->feature_bitmap &= ~L2INPUT_FEAT_LEARN;
@@ -690,7 +674,7 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /*           */
          bd_add_member (bd_config, &member);
 
        }
-      else
+      else if (mode == MODE_L2_XC)
        {
          config->xconnect = 1;
          config->bridge = 0;
@@ -706,6 +690,24 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main,        /*           */
          config->feature_bitmap |= L2INPUT_FEAT_XCONNECT;
          shg = 0;              /* not used in xconnect */
        }
+      else if (mode == MODE_L2_CLASSIFY)
+       {
+         config->xconnect = 1;
+         config->bridge = 0;
+         config->output_sw_if_index = xc_sw_if_index;
+
+         /* Make sure last-chance drop is configured */
+         config->feature_bitmap |=
+           L2INPUT_FEAT_DROP | L2INPUT_FEAT_INPUT_CLASSIFY;
+
+         /* Make sure bridging features are disabled */
+         config->feature_bitmap &=
+           ~(L2INPUT_FEAT_LEARN | L2INPUT_FEAT_FWD | L2INPUT_FEAT_FLOOD);
+         shg = 0;              /* not used in xconnect */
+
+         /* Insure all packets go to ethernet-input */
+         ethernet_set_rx_redirect (vnet_main, hi, 1);
+       }
 
       /* set up split-horizon group and set output feature bit */
       config->shg = shg;
@@ -788,6 +790,12 @@ int_l2_bridge (vlib_main_t * vm,
       goto done;
     }
 
+  if (bd_id > L2_BD_ID_MAX)
+    {
+      error = clib_error_return (0, "bridge domain ID exceed 16M limit",
+                                format_unformat_error, input);
+      goto done;
+    }
   bd_index = bd_find_or_add_bd_index (&bd_main, bd_id);
 
   /* optional bvi  */