From: Semih Baskan <strst.gs@gmail.com>
To: florian.fainelli@broadcom.com, jonas.gorski@gmail.com,
andrew@lunn.ch, olteanv@gmail.com, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com
Cc: vladimir.oltean@nxp.com, horms@kernel.org,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH net 0/2] net: dsa: b53: fix 8021q uppers on standalone ports
Date: Thu, 6 Aug 2026 10:31:17 +0300 [thread overview]
Message-ID: <20260806073119.387-1-strst.gs@gmail.com> (raw)
Since v5.15, a standalone port on a b53 switch cannot receive its own
tagged traffic: the switch VID lookup is always active, an 8021q
upper's VID never reaches the VLAN table, and every tagged frame
resolves to an empty member set and is discarded. The common victim is
a VLAN-tagged PPPoE WAN, where the PADI goes out and the tagged PADO
never reaches the CPU.
My first attempt disabled the VLAN table while not filtering:
https://lore.kernel.org/all/20260805072641.402-1-strst.gs@gmail.com/
Jonas pointed out that this moves the ARL to shared VLAN learning and
desynchronizes the hardware table from the bridge fdb, and I withdrew
it. I then measured the alternatives on an RT-N18U (BCM53011 rev 5),
with the outbound direction of the same link as a positive control on
every run:
- With the table enabled, no ingress VID check setting delivers the
frame: VC4_NO_ING_VID_CHK, VC4_ING_VID_VIO_FWD and
VC4_ING_VID_VIO_TO_IMP all give 0, and clearing VC0_DROP_VID_MISS
changes nothing. The frame does not die at ingress admission, it
dies when forwarding resolves the VID against an empty member set.
- With the table disabled, a static fdb entry with VID 100 is lost
from the hardware ARL no matter how the driver drives the ARL
registers: keeping ARLTBL_IVL_SVL_SELECT at IVL does not preserve
it, and neither does additionally keeping the VID learning bits in
VLAN_CTRL0 set.
So on this hardware, delivering the frame and keeping VID-keyed ARL
entries are mutually exclusive unless the VID is in the table. This
series therefore programs the table, narrowed to what is actually
needed: a standalone port only needs the VIDs its 8021q uppers use,
which is one table write per upper instead of entries for all 4096
VIDs.
I tried to keep the fix inside b53, but the driver cannot solve this
alone: without NETIF_F_HW_VLAN_CTAG_FILTER the 8021q layer never calls
.ndo_vlan_rx_add_vid, so the VIDs never reach the driver, and DSA
manages that feature bit. The one existing way to get it,
ds->needs_standalone_vlan_filtering, does not work here. It was
measured insufficient, because f089652b6b16 makes .port_vlan_add skip
the hardware write while not filtering, and its other effect is one
b53 cannot take: with vlan_filtering_is_global, the forced
vlan_filtering=1 in dsa_port_reset_vlan_filtering() would flip the
whole switch into VLAN filtering when any port leaves a VLAN-unaware
bridge. hellcreek relies on exactly those semantics, so patch 1 adds a
narrower opt-in that only delivers the VIDs and leaves vlan_filtering
alone, and patch 2 uses it in b53 and programs entries that carry
standalone members, masked so bridge VLANs stay without effect while
not filtering.
Tested on the RT-N18U: the standalone upper receives 7 of 7 probe
frames with vlan_filtering staying 0, the static fdb entry with a VID
now survives a vlan_filtering toggle since the table and the ARL mode
are never touched, uppers keep working across bridge join and leave
and across a vlan_filtering toggle including on ports that were
bridged while the toggle happened, deleting an upper or bridging its
port verifiably stops delivery of that VID to the CPU, and the PPPoE
session from the original report establishes. 802.1ad uppers keep
working as software VLANs, since this switch does not parse 0x88a8,
and stacked QinQ over an offloaded upper works too.
Semih Baskan (2):
net: dsa: let drivers offload 8021q uppers on standalone ports
net: dsa: b53: offload 8021q uppers on standalone ports
drivers/net/dsa/b53/b53_common.c | 118 ++++++++++++++++++++++++++-----
include/net/dsa.h | 3 +
net/dsa/port.c | 21 ++++--
net/dsa/user.c | 4 +-
4 files changed, 120 insertions(+), 26 deletions(-)
next reply other threads:[~2026-08-06 7:31 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-06 7:31 Semih Baskan [this message]
2026-08-06 7:31 ` [PATCH net 1/2] net: dsa: let drivers offload 8021q uppers on standalone ports Semih Baskan
2026-08-06 11:15 ` Vladimir Oltean
2026-08-06 11:44 ` Semih Baskan
2026-08-06 12:43 ` Vladimir Oltean
2026-08-06 13:39 ` Semih Baskan
2026-08-10 12:08 ` Vladimir Oltean
2026-08-11 6:25 ` Semih Baskan
2026-08-11 7:44 ` Jonas Gorski
2026-08-11 9:58 ` Vladimir Oltean
2026-08-11 13:19 ` Semih Baskan
2026-08-12 7:24 ` Jonas Gorski
2026-08-12 9:21 ` Semih Baskan
2026-08-12 7:14 ` Jonas Gorski
2026-08-06 7:31 ` [PATCH net 2/2] net: dsa: b53: " Semih Baskan
2026-08-06 8:39 ` [PATCH net 0/2] net: dsa: b53: fix " Jonas Gorski
2026-08-06 11:06 ` Semih Baskan
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=20260806073119.387-1-strst.gs@gmail.com \
--to=strst.gs@gmail.com \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=florian.fainelli@broadcom.com \
--cc=horms@kernel.org \
--cc=jonas.gorski@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=pabeni@redhat.com \
--cc=vladimir.oltean@nxp.com \
/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.