Add support for multiple microarchitectures in single binary
[vpp.git] / vnet / vnet / ethernet / node.c
index 9aed302..226a66e 100644 (file)
@@ -98,6 +98,7 @@ parse_header (ethernet_input_variant_t variant,
               u16 * outer_id,
               u16 * inner_id,
               u32 * match_flags) {
+  u8 vlan_count;
 
   if (variant == ETHERNET_INPUT_VARIANT_ETHERNET 
       || variant == ETHERNET_INPUT_VARIANT_NOT_L2) {
@@ -129,6 +130,7 @@ parse_header (ethernet_input_variant_t variant,
   *inner_id = 0;
 
   *match_flags = SUBINT_CONFIG_VALID | SUBINT_CONFIG_MATCH_0_TAG;
+  vlan_count = 0;
 
   // check for vlan encaps
   if ((*type == ETHERNET_TYPE_VLAN) ||
@@ -150,6 +152,7 @@ parse_header (ethernet_input_variant_t variant,
     *type = clib_net_to_host_u16(h0->type);
 
     vlib_buffer_advance (b0, sizeof (h0[0]));
+    vlan_count = 1;
 
     if (*type == ETHERNET_TYPE_VLAN) {
       // Double tagged packet
@@ -164,13 +167,16 @@ parse_header (ethernet_input_variant_t variant,
       *type = clib_net_to_host_u16(h0->type);
 
       vlib_buffer_advance (b0, sizeof (h0[0]));
+      vlan_count = 2;
 
       if (*type == ETHERNET_TYPE_VLAN) {
         // More than double tagged packet
         *match_flags = SUBINT_CONFIG_VALID | SUBINT_CONFIG_MATCH_3_TAG;
+        vlan_count = 3; // "unknown" number, aka, 3-or-more
       }
     }
   }
+  ethernet_buffer_set_vlan_count(b0, vlan_count);
 }
 
 // Determine the subinterface for this packet, given the result of the
@@ -230,7 +236,7 @@ determine_next_node (ethernet_main_t * em,
     *next0 = em->l2_next;
     // record the L2 len and reset the buffer so the L2 header is preserved
     vnet_buffer(b0)->l2.l2_len = b0->current_data;
-    vlib_buffer_advance (b0, -(b0->current_data));
+    vlib_buffer_advance(b0, - ethernet_buffer_header_size(b0));
 
   // check for common IP/MPLS ethertypes
   } else if (type0 == ETHERNET_TYPE_IP4) {
@@ -833,6 +839,41 @@ ethernet_sw_interface_set_l2_mode (vnet_main_t * vnm,
   return;
 }
 
+/*
+ * Set the L2/L3 mode for the subinterface regardless of port
+ */
+void
+ethernet_sw_interface_set_l2_mode_noport (vnet_main_t * vnm,
+                                          u32 sw_if_index,
+                                          u32 l2)
+{
+  subint_config_t *subint;
+  u32 dummy_flags;
+  u32 dummy_unsup;
+
+  /* Find the config for this subinterface */
+  subint = ethernet_sw_interface_get_config (vnm, sw_if_index, &dummy_flags, &dummy_unsup);
+
+  if (subint == 0) {
+    /* unimplemented or not ethernet */
+    goto done;
+  }
+
+  /*
+   * Double check that the config we found is for our interface (or the
+   * interface is down)
+   */
+  ASSERT ((subint->sw_if_index == sw_if_index) | (subint->sw_if_index == ~0));
+
+  if (l2) {
+    subint->flags |= SUBINT_CONFIG_L2;
+  } else {
+    subint->flags &= ~SUBINT_CONFIG_L2;
+  }
+
+ done:
+  return;
+}
 
 static clib_error_t *
 ethernet_sw_interface_add_del (vnet_main_t * vnm,
@@ -842,7 +883,7 @@ ethernet_sw_interface_add_del (vnet_main_t * vnm,
   clib_error_t * error = 0;
   subint_config_t *subint;
   u32 match_flags;
-  u32 unsupported;
+  u32 unsupported=0;
 
   // Find the config for this subinterface
   subint = ethernet_sw_interface_get_config (vnm, sw_if_index, &match_flags, &unsupported);
@@ -904,6 +945,8 @@ VLIB_REGISTER_NODE (ethernet_input_node) = {
   .unformat_buffer = unformat_ethernet_header,
 };
 
+VLIB_NODE_FUNCTION_MULTIARCH (ethernet_input_node, ethernet_input)
+
 VLIB_REGISTER_NODE (ethernet_input_type_node,static) = {
   .function = ethernet_input_type,
   .name = "ethernet-input-type",
@@ -918,6 +961,8 @@ VLIB_REGISTER_NODE (ethernet_input_type_node,static) = {
   },
 };
 
+VLIB_NODE_FUNCTION_MULTIARCH (ethernet_input_type_node, ethernet_input_type)
+
 VLIB_REGISTER_NODE (ethernet_input_not_l2_node,static) = {
   .function = ethernet_input_not_l2,
   .name = "ethernet-input-not-l2",
@@ -932,6 +977,8 @@ VLIB_REGISTER_NODE (ethernet_input_not_l2_node,static) = {
   },
 };
 
+VLIB_NODE_FUNCTION_MULTIARCH (ethernet_input_not_l2_node, ethernet_input_not_l2)
+
 void ethernet_set_rx_redirect (vnet_main_t * vnm, 
                                vnet_hw_interface_t * hi, 
                                u32 enable)