summaryrefslogtreecommitdiffstats
path: root/vnet
diff options
context:
space:
mode:
Diffstat (limited to 'vnet')
-rw-r--r--vnet/vnet/devices/dpdk/device.c16
-rw-r--r--vnet/vnet/devices/dpdk/dpdk.h3
-rw-r--r--vnet/vnet/devices/dpdk/node.c4
3 files changed, 17 insertions, 6 deletions
diff --git a/vnet/vnet/devices/dpdk/device.c b/vnet/vnet/devices/dpdk/device.c
index 7f759d6104d..bad149f03c6 100644
--- a/vnet/vnet/devices/dpdk/device.c
+++ b/vnet/vnet/devices/dpdk/device.c
@@ -1136,7 +1136,10 @@ dpdk_subif_add_del_function (vnet_main_t * vnm,
dpdk_device_t * xd = vec_elt_at_index (xm->devices, hw->dev_instance);
vnet_sw_interface_t * t = (vnet_sw_interface_t *) st;
int r, vlan_offload;
+ u32 prev_subifs = xd->vlan_subifs;
+ if (is_add) xd->vlan_subifs++;
+ else if (xd->vlan_subifs) xd->vlan_subifs--;
if (xd->dev_type != VNET_DPDK_DEV_ETH)
return 0;
@@ -1149,21 +1152,26 @@ dpdk_subif_add_del_function (vnet_main_t * vnm,
if (t->sub.eth.flags.no_tags == 1)
return 0;
- if ((t->sub.eth.flags.one_tag != 1) || (t->sub.eth.flags.exact_match != 1 ))
+ if ((t->sub.eth.flags.one_tag != 1) || (t->sub.eth.flags.exact_match != 1 )) {
+ xd->vlan_subifs = prev_subifs;
return clib_error_return (0, "unsupported VLAN setup");
-
+ }
vlan_offload = rte_eth_dev_get_vlan_offload(xd->device_index);
vlan_offload |= ETH_VLAN_FILTER_OFFLOAD;
- if ((r = rte_eth_dev_set_vlan_offload(xd->device_index, vlan_offload)))
+ if ((r = rte_eth_dev_set_vlan_offload(xd->device_index, vlan_offload))) {
+ xd->vlan_subifs = prev_subifs;
return clib_error_return (0, "rte_eth_dev_set_vlan_offload[%d]: err %d",
xd->device_index, r);
+ }
- if ((r = rte_eth_dev_vlan_filter(xd->device_index, t->sub.eth.outer_vlan_id, is_add)))
+ if ((r = rte_eth_dev_vlan_filter(xd->device_index, t->sub.eth.outer_vlan_id, is_add))) {
+ xd->vlan_subifs = prev_subifs;
return clib_error_return (0, "rte_eth_dev_vlan_filter[%d]: err %d",
xd->device_index, r);
+ }
return 0;
}
diff --git a/vnet/vnet/devices/dpdk/dpdk.h b/vnet/vnet/devices/dpdk/dpdk.h
index 4123cc9cbef..23c8eb3eaf5 100644
--- a/vnet/vnet/devices/dpdk/dpdk.h
+++ b/vnet/vnet/devices/dpdk/dpdk.h
@@ -210,6 +210,9 @@ typedef struct {
/* per-worker destination frame queue */
dpdk_frame_t * frames;
+ /* number of sub-interfaces */
+ u16 vlan_subifs;
+
dpdk_device_type_t dev_type:8;
dpdk_pmd_t pmd:8;
i8 cpu_socket;
diff --git a/vnet/vnet/devices/dpdk/node.c b/vnet/vnet/devices/dpdk/node.c
index 2c90d80a31e..d22838f1f06 100644
--- a/vnet/vnet/devices/dpdk/node.c
+++ b/vnet/vnet/devices/dpdk/node.c
@@ -305,9 +305,9 @@ dpdk_rx_next_and_error_from_mb_flags_x1 (dpdk_device_t *xd, struct rte_mbuf *mb,
else
{
*error0 = DPDK_ERROR_NONE;
- if (xd->per_interface_next_index != ~0)
+ if (PREDICT_FALSE(xd->per_interface_next_index != ~0))
n0 = xd->per_interface_next_index;
- else if (mb_flags & PKT_RX_VLAN_PKT)
+ else if (PREDICT_FALSE(xd->vlan_subifs || (mb_flags & PKT_RX_VLAN_PKT)))
n0 = DPDK_RX_NEXT_ETHERNET_INPUT;
else
{