Allow DPDK per interface startup config to enable/disable VLAN stripping 06/1906/3
authorJohn Lo <loj@cisco.com>
Thu, 7 Jul 2016 17:54:44 +0000 (13:54 -0400)
committerDamjan Marion <dmarion.lists@gmail.com>
Fri, 8 Jul 2016 09:38:56 +0000 (09:38 +0000)
The init of VIC/ENIC ports enable VLAN stripping of received packets by
default, which is different to all other devices. The VLAN stripping of
ENIC ports can be disabled by adding the per device DPDK config as
"vlan-strip-offload off" such as:
  dpdk {...  dev 0000:0c:00.0 {vlan-strip-offload off} ...}
The per device config "vlan-strip-offload on" can be used for enabling VLAN
stripping for other devices which support this function but is disabled
by default.

Change-Id: I9c81904a87c26868a07900b03677aeeb57f72372
Signed-off-by: John Lo <loj@cisco.com>
vnet/vnet/devices/dpdk/dpdk.h
vnet/vnet/devices/dpdk/init.c

index dee4625..05f74b8 100644 (file)
@@ -294,6 +294,11 @@ typedef struct dpdk_efd_t {
 typedef struct {
     vlib_pci_addr_t pci_addr;
     u8 is_blacklisted;
+    u8 vlan_strip_offload;
+#define DPDK_DEVICE_VLAN_STRIP_DEFAULT 0
+#define DPDK_DEVICE_VLAN_STRIP_OFF 1
+#define DPDK_DEVICE_VLAN_STRIP_ON  2
+
 #define _(x) uword x;
     foreach_dpdk_device_config_item
 #undef _
index 471d901..7514ff8 100644 (file)
@@ -286,6 +286,7 @@ dpdk_lib_init (dpdk_main_t * dm)
   for (i = 0; i < nports; i++)
     {
       u8 addr[6];
+      u8 vlan_strip = 0;
       int j;
       struct rte_eth_dev_info dev_info;
       clib_error_t * rv;
@@ -651,15 +652,24 @@ dpdk_lib_init (dpdk_main_t * dm)
           * Initialize mtu to what has been set by CIMC in the firmware cfg.
           */
          hi->max_packet_bytes = dev_info.max_rx_pktlen;
-          /*
-           * remove vlan tag from VIC port to fix VLAN0 issue.
-           * TODO Handle VLAN tagged traffic
-           */
-          int vlan_off;
-          vlan_off = rte_eth_dev_get_vlan_offload(xd->device_index);
-          vlan_off |= ETH_VLAN_STRIP_OFFLOAD;
-          rte_eth_dev_set_vlan_offload(xd->device_index, vlan_off);
+         if (devconf->vlan_strip_offload != DPDK_DEVICE_VLAN_STRIP_OFF)
+           vlan_strip = 1; /* remove vlan tag from VIC port by default */
+         else
+           clib_warning("VLAN strip disabled for interface\n");
        }
+      else if (devconf->vlan_strip_offload == DPDK_DEVICE_VLAN_STRIP_ON)
+       vlan_strip = 1;
+
+      if (vlan_strip)
+        { 
+         int vlan_off;
+         vlan_off = rte_eth_dev_get_vlan_offload(xd->device_index);
+         vlan_off |= ETH_VLAN_STRIP_OFFLOAD;
+         if (rte_eth_dev_set_vlan_offload(xd->device_index, vlan_off) == 0)
+           clib_warning("VLAN strip enabled for interface\n");
+         else
+           clib_warning("VLAN strip cannot be supported by interface\n");
+        }
 
 #if RTE_VERSION < RTE_VERSION_NUM(16, 4, 0, 0) 
       /*
@@ -884,6 +894,10 @@ dpdk_device_config (dpdk_config_main_t * conf, vlib_pci_addr_t pci_addr, unforma
           if (error)
             break;
         }
+      else if (unformat (input, "vlan-strip-offload off"))
+         devconf->vlan_strip_offload = DPDK_DEVICE_VLAN_STRIP_OFF;
+      else if (unformat (input, "vlan-strip-offload on"))
+         devconf->vlan_strip_offload = DPDK_DEVICE_VLAN_STRIP_ON;
       else
        {
          error = clib_error_return (0, "unknown input `%U'",