patch 'net: fix packet type for stacked VLAN' has been queued to stable release 25.11.1

Kevin Traynor ktraynor at redhat.com
Thu Feb 26 14:08:26 CET 2026


Hi,

FYI, your patch has been queued to stable release 25.11.1

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 03/02/26. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/kevintraynor/dpdk-stable

This queued commit can be viewed at:
https://github.com/kevintraynor/dpdk-stable/commit/df91c02788ebc532f342c99bc232b71c78cc1daa

Thanks.

Kevin

---
>From df91c02788ebc532f342c99bc232b71c78cc1daa Mon Sep 17 00:00:00 2001
From: Gregory Etelson <getelson at nvidia.com>
Date: Thu, 15 Jan 2026 15:14:56 +0200
Subject: [PATCH] net: fix packet type for stacked VLAN

[ upstream commit 1f250674085aeb4ffd15ac2519a68efc04faf7ac ]

The rte_net_get_ptype() supported only 2 types of VLAN headers frames
that are defined in the IEEE standards 802.1Q and 802.1ad:

frames with a single 0x8100 VLAN header:
  eth type VLAN / vlan / [IPv4 | IPv6 ]

frames with 0x88A8 QinQ header followed by 0x8100 VLAN:
 eth type QinQ / vlan type VLAN / vlan / [IPv4 | IPv6 ]

The function did not parse frames where VLAN headers were stacked in
different configurations.
Such frames should also be allowed to provide HW vendor flexibility.
As a result, ptype bitmask and header length returned from
rte_net_get_ptype() for a custom VLAN frame were wrong.

For example, the parser result for the frame
  eth type QinQ / vlan type QinQ / vlan type VLAN / vlan / ipv4
was:
pkt_type:=0x120007
   RTE_PTYPE_L2_ETHER_QINQ         0x00000007 OK
   RTE_PTYPE_INNER_L2_ETHER_VLAN   0x00020000 wrong
   RTE_PTYPE_INNER_L3_IPV4         0x00100000 wrong

hdr_lens:={
  l2_len       = 22 wrong
  inner_l2_len =  4 wrong
  l3_len       =  0 wrong
  inner_l3_len = 20 wrong
}

The patch changes:
1. Allow frames with up to RTE_NET_VLAN_MAX_DEPTH:=8
   number of VLAN headers.

2. Set each parsed VLAN type in the returned ptype bitmask.
   Multiple VLAN headers are referenced by a single
   RTE_PTYPE_L2_ETHER_VLAN bit.
   Multiple QinQ headers are references by a single
   RTE_PTYPE_L2_ETHER_QINQ bit.

3. Preserve RTE_PTYPE_L2_ETHER bit if VLAN or QinQ type was detected.

Fixes: eb173c8def0a ("net: support VLAN in software packet type parser")
Fixes: 218a163efd67 ("net: support QinQ in software packet type parser")

Signed-off-by: Gregory Etelson <getelson at nvidia.com>
---
 lib/net/rte_net.c | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/lib/net/rte_net.c b/lib/net/rte_net.c
index c70b57fdc0..458b4814a9 100644
--- a/lib/net/rte_net.c
+++ b/lib/net/rte_net.c
@@ -321,4 +321,7 @@ rte_net_skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off,
 }
 
+/* limit number of supported VLAN headers */
+#define RTE_NET_VLAN_MAX_DEPTH 8
+
 /* parse mbuf data to get packet type */
 RTE_EXPORT_SYMBOL(rte_net_get_ptype)
@@ -330,5 +333,5 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
 	struct rte_ether_hdr eh_copy;
 	uint32_t pkt_type = RTE_PTYPE_L2_ETHER;
-	uint32_t off = 0;
+	uint32_t off = 0, vlan_depth = 0;
 	uint16_t proto;
 	int ret;
@@ -350,9 +353,15 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
 		goto l3; /* fast path if packet is IPv4 */
 
-	if (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN)) {
+	while (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN) ||
+	       proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_QINQ)) {
 		const struct rte_vlan_hdr *vh;
 		struct rte_vlan_hdr vh_copy;
 
-		pkt_type = RTE_PTYPE_L2_ETHER_VLAN;
+		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;
 		vh = rte_pktmbuf_read(m, off, sizeof(*vh), &vh_copy);
 		if (unlikely(vh == NULL))
@@ -361,17 +370,7 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
 		hdr_lens->l2_len += sizeof(*vh);
 		proto = vh->eth_proto;
-	} else if (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_QINQ)) {
-		const struct rte_vlan_hdr *vh;
-		struct rte_vlan_hdr vh_copy;
+	}
 
-		pkt_type = RTE_PTYPE_L2_ETHER_QINQ;
-		vh = rte_pktmbuf_read(m, off + sizeof(*vh), sizeof(*vh),
-			&vh_copy);
-		if (unlikely(vh == NULL))
-			return pkt_type;
-		off += 2 * sizeof(*vh);
-		hdr_lens->l2_len += 2 * sizeof(*vh);
-		proto = vh->eth_proto;
-	} else if ((proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS)) ||
+	if ((proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS)) ||
 		(proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLSM))) {
 		unsigned int i;
-- 
2.53.0

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2026-02-26 10:16:48.079651389 +0000
+++ 0024-net-fix-packet-type-for-stacked-VLAN.patch	2026-02-26 10:16:46.926197048 +0000
@@ -1 +1 @@
-From 1f250674085aeb4ffd15ac2519a68efc04faf7ac Mon Sep 17 00:00:00 2001
+From df91c02788ebc532f342c99bc232b71c78cc1daa Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit 1f250674085aeb4ffd15ac2519a68efc04faf7ac ]
+
@@ -50,2 +51,0 @@
-
-Cc: stable at dpdk.org



More information about the stable mailing list