vmxnet3: add support for "non-default" next node 79/14879/2
authorSteven <sluong@cisco.com>
Tue, 18 Sep 2018 19:34:59 +0000 (12:34 -0700)
committerDamjan Marion <dmarion@me.com>
Tue, 18 Sep 2018 22:50:21 +0000 (22:50 +0000)
Support feature arc
Support set interface next node
Enqueue packet to either ip4, ip6, or ethernet_input based on packet type

Change-Id: I11fb6bba98ee0bfa1d057474fc6cf3be48ef1c48
Signed-off-by: Steven <sluong@cisco.com>
src/plugins/vmxnet3/input.c
src/plugins/vmxnet3/vmxnet3.c
src/plugins/vmxnet3/vmxnet3.h

index a5a5d2f..0ae52ca 100644 (file)
@@ -88,6 +88,8 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
   vmxnet3_rx_comp_ring *comp_ring;
   u16 rid;
   vlib_buffer_t *prev_b0 = 0, *hb = 0;
+  u32 next_index = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;
+  u8 known_next = 0;
 
   rxq = vec_elt_at_index (vd->rxqs, qid);
   comp_ring = &rxq->rx_comp_ring;
@@ -123,12 +125,14 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
       b0 = vlib_get_buffer (vm, bi[0]);
       vnet_buffer (b0)->sw_if_index[VLIB_RX] = vd->sw_if_index;
       vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
+      vnet_buffer (b0)->feature_arc_index = 0;
       b0->current_length = rx_comp->len & VMXNET3_RXCL_LEN_MASK;
       b0->current_data = 0;
       b0->total_length_not_including_first_buffer = 0;
       b0->next_buffer = 0;
       b0->flags = 0;
       b0->error = 0;
+      b0->current_config_index = 0;
       ASSERT (b0->current_length != 0);
 
       if (rx_comp->index & VMXNET3_RXCI_SOP)
@@ -148,7 +152,6 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
               */
              prev_b0 = 0;
            }
-
        }
       else if (rx_comp->index & VMXNET3_RXCI_EOP)
        {
@@ -190,7 +193,55 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
 
       if (!prev_b0)
        {
-         next[0] = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;
+         ethernet_header_t *e = (ethernet_header_t *) hb->data;
+
+         if (PREDICT_FALSE (vd->per_interface_next_index != ~0))
+           {
+             next_index = vd->per_interface_next_index;
+             known_next = 1;
+           }
+
+         if (PREDICT_FALSE
+             (vnet_device_input_have_features (vd->sw_if_index)))
+           {
+             vnet_feature_start_device_input_x1 (vd->sw_if_index,
+                                                 &next_index, hb);
+             known_next = 1;
+           }
+
+         if (PREDICT_FALSE (known_next))
+           {
+             next[0] = next_index;
+           }
+         else
+           {
+             if (ethernet_frame_is_tagged (e->type))
+               next[0] = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;
+             else
+               {
+                 if (rx_comp->flags & VMXNET3_RXCF_IP4)
+                   {
+                     next[0] = VNET_DEVICE_INPUT_NEXT_IP4_NCS_INPUT;
+                     hb->flags |= VNET_BUFFER_F_IS_IP4;
+                     vlib_buffer_advance (hb,
+                                          device_input_next_node_advance
+                                          [next[0]]);
+                   }
+                 else if (rx_comp->flags & VMXNET3_RXCF_IP6)
+                   {
+                     next[0] = VNET_DEVICE_INPUT_NEXT_IP6_INPUT;
+                     hb->flags |= VNET_BUFFER_F_IS_IP6;
+                     vlib_buffer_advance (hb,
+                                          device_input_next_node_advance
+                                          [next[0]]);
+                   }
+                 else
+                   {
+                     next[0] = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;
+                   }
+               }
+           }
+
          n_rx_packets++;
          next++;
          hb = 0;
index 74ef126..74e6003 100644 (file)
@@ -77,6 +77,26 @@ vmxnet3_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, u32 qid,
   return 0;
 }
 
+static void
+vmxnet3_set_interface_next_node (vnet_main_t * vnm, u32 hw_if_index,
+                                u32 node_index)
+{
+  vmxnet3_main_t *vmxm = &vmxnet3_main;
+  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
+  vmxnet3_device_t *vd = pool_elt_at_index (vmxm->devices, hw->dev_instance);
+
+  /* Shut off redirection */
+  if (node_index == ~0)
+    {
+      vd->per_interface_next_index = node_index;
+      return;
+    }
+
+  vd->per_interface_next_index =
+    vlib_node_add_next (vlib_get_main (), vmxnet3_input_node.index,
+                       node_index);
+}
+
 static char *vmxnet3_tx_func_error_strings[] = {
 #define _(n,s) s,
   foreach_vmxnet3_tx_func_error
@@ -91,6 +111,7 @@ VNET_DEVICE_CLASS (vmxnet3_device_class,) =
   .format_device_name = format_vmxnet3_device_name,
   .admin_up_down_function = vmxnet3_interface_admin_up_down,
   .rx_mode_change_function = vmxnet3_interface_rx_mode_change,
+  .rx_redirect_to_node = vmxnet3_set_interface_next_node,
   .tx_function_n_errors = VMXNET3_TX_N_ERROR,
   .tx_function_error_strings = vmxnet3_tx_func_error_strings,
 };
index 1379940..666dec7 100644 (file)
@@ -66,6 +66,8 @@ enum
 
 #define VMXNET3_RXF_BTYPE (1 << 14)    /* rx body buffer type */
 #define VMXNET3_RXF_GEN   (1 << 31)    /* rx generation */
+#define VMXNET3_RXCF_IP6  (1 << 20)    /* rx ip6 packet */
+#define VMXNET3_RXCF_IP4  (1 << 21)    /* rx ip4 packet */
 #define VMXNET3_RXCF_GEN  (1 << 31)    /* rx completion generation */
 #define VMXNET3_RXC_INDEX (0xFFF)      /* rx completion index mask */