When a tag is discovered, the code does not remove 'RTE_PTYPE_L2_ETHER'
set on function entry. For single-tagged packets, 'RTE_PTYPE_L2_ETHER'
and 'RTE_PTYPE_L2_ETHER_VLAN' give 'RTE_PTYPE_L2_ETHER_QINQ' when
OR-ed together. Clear previously set L2 type when handling VLANs.
Also, since 'RTE_PTYPE_L2_ETHER_VLAN' requires that the EtherType field
in the Ethernet header be set to 0x8100 and 'RTE_PTYPE_L2_ETHER_QINQ'
requires that it be set to 0x88a8, it is the outermost (first) tag
that determines what the software L2 ptype should be. Clarify that.
Fixes: 1f250674085a ("net: fix packet type for stacked VLAN")
Cc: [email protected]
Signed-off-by: Ivan Malov <[email protected]>
---
lib/net/rte_net.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/lib/net/rte_net.c b/lib/net/rte_net.c
index 0a91e92ba0..826d9f58b9 100644
--- a/lib/net/rte_net.c
+++ b/lib/net/rte_net.c
@@ -365,10 +365,18 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
if (++vlan_depth > RTE_NET_VLAN_MAX_DEPTH)
return 0;
- pkt_type |=
- proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN) ?
- RTE_PTYPE_L2_ETHER_VLAN :
- RTE_PTYPE_L2_ETHER_QINQ;
+
+ /*
+ * It is the outermost tag that determines whether
+ * the packet will be classified as VLAN or QinQ.
+ */
+ if (vlan_depth == 1) {
+ /* Override previously set 'RTE_PTYPE_L2_ETHER'. */
+ pkt_type = (proto ==
rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN) ?
+ RTE_PTYPE_L2_ETHER_VLAN :
+ RTE_PTYPE_L2_ETHER_QINQ);
+ }
+
vh = rte_pktmbuf_read(m, off, sizeof(*vh), &vh_copy);
if (unlikely(vh == NULL))
return pkt_type;
--
2.47.3