All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: Gregory Etelson <getelson@nvidia.com>
Cc: <dev@dpdk.org>, <mkashani@nvidia.com>, <rasland@nvidia.com>,
	<thomas@monjalon.net>, <stable@dpdk.org>,
	Olivier Matz <olivier.matz@6wind.com>,
	Didier Pallard <didier.pallard@6wind.com>
Subject: Re: [PATCH] net: fix parsing of frames with arbitrary VLAN stacks
Date: Wed, 14 Jan 2026 11:33:27 -0800	[thread overview]
Message-ID: <20260114113327.3618b433@phoenix.local> (raw)
In-Reply-To: <20251103154128.297748-1-getelson@nvidia.com>

On Mon, 3 Nov 2025 17:41:27 +0200
Gregory Etelson <getelson@nvidia.com> wrote:

> 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 an arbitrary 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")
> 
> Cc: stable@dpdk.org
> 
> Signed-off-by: Gregory Etelson <getelson@nvidia.com>

This patch seems to have been unreviewed for some time so forwarded
to AI for review. Agree in general but my take is that a stacking
depth limit should be enforced; too many network products have had
CVE's for malformed nasty packets.

Please address review comments and resubmit

# DPDK Patch Review: net: fix parsing of frames with arbitrary VLAN stacks

**Patch:** net-fix-parsing-of-frames-with-arbitrary-VLAN-stacks.patch  
**Author:** Gregory Etelson <getelson@nvidia.com>  
**Patchwork ID:** 158350  
**Reviewer:** Stephen Hemminger  
**Date:** January 14, 2026

---

## Summary

This patch fixes `rte_net_get_ptype()` to handle arbitrary VLAN header stacks instead of only the two standard configurations (single VLAN, QinQ+VLAN). The fix is correct and well-motivated.

---

## Commit Message Checklist

| Check | Status | Notes |
|-------|--------|-------|
| Subject ≤60 chars | ✓ | 50 characters |
| Lowercase after colon | ✓ | |
| Correct prefix | ✓ | `net:` correct for `lib/net/` |
| Imperative mood | ✓ | "fix parsing" |
| No trailing period | ✓ | |
| Body ≤75 chars | ✓ | Lines within limit |
| Body doesn't start with "It" | ✓ | Starts with "The" |
| Fixes: tags | ✓ | Two fixes with 12-char SHA |
| Cc: stable@dpdk.org | ✓ | Present |
| Signed-off-by | ✓ | Real name and email |
| Tag order | ✓ | Fixes → Cc → Signed-off-by |

**Commit message is well-written** — good problem description with concrete examples showing incorrect vs expected behavior.

---

## Code Review

### Correctness: ✓ Good

The refactoring is sound:

- Replaces fragile if/else with a `while` loop that iterates through any VLAN/QinQ stack
- Uses `|=` instead of `=` to accumulate ptype bits, preserving `RTE_PTYPE_L2_ETHER`
- Each header is read and validated individually via `rte_pktmbuf_read()`
- Loop terminates safely when packet data exhausted (NULL return) or non-VLAN ethertype encountered

### Old Behavior Flaw

The QinQ branch assumed exactly one inner VLAN and skipped 2 headers at once, reading only the second. This failed for stacks like QinQ/QinQ/VLAN.

### New Behavior

Processes each VLAN/QinQ header individually regardless of nesting depth.

---

## Suggestions

### Warning (should consider)

1. **Unbounded loop concern** — While the NULL check provides safety against buffer overrun, a malicious or malformed packet with many consecutive VLAN tags could cause CPU spin. Consider adding a reasonable iteration limit:

```c
#define RTE_NET_VLAN_MAX_DEPTH 8  /* or similar reasonable bound */
unsigned int vlan_depth = 0;

while ((proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN) ||
        proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_QINQ)) &&
       vlan_depth++ < RTE_NET_VLAN_MAX_DEPTH) {
```

This is probably overkill for typical use but would make the parser more defensive.

### Info (minor style)

2. **Ternary formatting** — The nested ternary inside the `|=` is a bit dense. Consider:

```c
if (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN))
    pkt_type |= RTE_PTYPE_L2_ETHER_VLAN;
else
    pkt_type |= RTE_PTYPE_L2_ETHER_QINQ;
```

This is clearer and costs nothing. The ternary version works fine though.

---

## Verdict

**Reviewed-by worthy** — The patch correctly fixes a real parsing limitation. The code change is minimal, correct, and well-explained.

The only substantive suggestion is considering a loop depth limit for defensive programming, but this is optional given the existing NULL-check safety. The patch is good as-is.

---

## Suggested Reply

```
On Mon, 3 Nov 2025 17:41:27 +0200, Gregory Etelson wrote:
> 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:

The fix looks correct. One minor suggestion: consider adding a loop
depth limit (e.g., 8) as a defensive measure against malformed packets
with excessive VLAN tags, though the existing NULL check does provide
buffer safety.

```


  reply	other threads:[~2026-01-14 19:33 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-03 15:41 [PATCH] net: fix parsing of frames with arbitrary VLAN stacks Gregory Etelson
2026-01-14 19:33 ` Stephen Hemminger [this message]
2026-01-15 13:14   ` [PATCH v2] " Gregory Etelson
2026-01-21 13:53     ` Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260114113327.3618b433@phoenix.local \
    --to=stephen@networkplumber.org \
    --cc=dev@dpdk.org \
    --cc=didier.pallard@6wind.com \
    --cc=getelson@nvidia.com \
    --cc=mkashani@nvidia.com \
    --cc=olivier.matz@6wind.com \
    --cc=rasland@nvidia.com \
    --cc=stable@dpdk.org \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.