From 473e9407a4d7a365074d9b0618a8f1eccef291b5 Mon Sep 17 00:00:00 2001 From: Hyong Youb Kim Date: Wed, 9 Sep 2020 07:00:04 -0700 Subject: [PATCH] net/enic: ignore VLAN inner type when it is zero When a VLAN pattern is present, the flow handler always copies its inner_type to the match buffer regardless of its value (i.e. HW matches inner_type against packet's inner ethertype). When inner_type spec and mask are both 0, adding it to the match buffer is usually harmless but breaks the following pattern used in some applications like OVS-DPDK. flow create 0 ingress ... pattern eth ... type is 0x0800 / vlan tci spec 0x2 tci mask 0xefff / ipv4 / end actions count / of_pop_vlan / ... The VLAN pattern's inner_type is 0. And the outer eth pattern's type actually specifies the inner ethertype. The outer ethertype (0x0800) is first copied to the match buffer. Then, the driver copies inner_type (0) to the match buffer, which overwrites the existing 0x0800 with 0 and breaks the app usage above. Simply ignore inner_type when it is 0, which is the correct behavior. As a byproduct, the driver can support the usage like the above. Fixes: ea7768b5bba8 ("net/enic: add flow implementation based on Flow Manager API") Cc: stable@dpdk.org Signed-off-by: Hyong Youb Kim Reviewed-by: John Daley --- drivers/net/enic/enic_fm_flow.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c index ee671e11df..94e39a94bf 100644 --- a/drivers/net/enic/enic_fm_flow.c +++ b/drivers/net/enic/enic_fm_flow.c @@ -392,8 +392,11 @@ enic_fm_copy_item_vlan(struct copy_item_args *arg) eth_mask = (void *)&fm_mask->l2.eth; eth_val = (void *)&fm_data->l2.eth; - /* Outer TPID cannot be matched */ - if (eth_mask->ether_type) + /* + * Outer TPID cannot be matched. If inner_type is 0, use what is + * in the eth header. + */ + if (eth_mask->ether_type && mask->inner_type) return -ENOTSUP; /* @@ -401,8 +404,10 @@ enic_fm_copy_item_vlan(struct copy_item_args *arg) * L2, regardless of vlan stripping settings. So, the inner type * from vlan becomes the ether type of the eth header. */ - eth_mask->ether_type = mask->inner_type; - eth_val->ether_type = spec->inner_type; + if (mask->inner_type) { + eth_mask->ether_type = mask->inner_type; + eth_val->ether_type = spec->inner_type; + } fm_data->fk_header_select |= FKH_ETHER | FKH_QTAG; fm_mask->fk_header_select |= FKH_ETHER | FKH_QTAG; fm_data->fk_vlan = rte_be_to_cpu_16(spec->tci); -- 2.20.1