From ce3e971bab3a67b5d484294f5cfd3d270c76bc38 Mon Sep 17 00:00:00 2001 From: John Lo Date: Thu, 7 Jul 2016 13:54:44 -0400 Subject: [PATCH] Allow DPDK per interface startup config to enable/disable VLAN stripping 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 --- vnet/vnet/devices/dpdk/dpdk.h | 5 +++++ vnet/vnet/devices/dpdk/init.c | 30 ++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/vnet/vnet/devices/dpdk/dpdk.h b/vnet/vnet/devices/dpdk/dpdk.h index dee4625b82f..05f74b849f5 100644 --- a/vnet/vnet/devices/dpdk/dpdk.h +++ b/vnet/vnet/devices/dpdk/dpdk.h @@ -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 _ diff --git a/vnet/vnet/devices/dpdk/init.c b/vnet/vnet/devices/dpdk/init.c index 471d9015342..7514ff86ac6 100644 --- a/vnet/vnet/devices/dpdk/init.c +++ b/vnet/vnet/devices/dpdk/init.c @@ -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'", -- 2.16.6