Re: [PATCH net] net: dsa: b53: be VLAN unaware when not filtering
From: Jonas Gorski
Date: Wed Aug 05 2026 - 03:49:33 EST
Hi,
On Wed, Aug 5, 2026 at 9:27 AM Semih Baskan <strst.gs@xxxxxxxxx> wrote:
>
> b53 keeps the VLAN table enabled at all times, so a tagged frame whose VID
> is not in the table resolves to an empty member set and is dropped before
> it reaches the CPU. Documentation/networking/switchdev.rst requires a
> standalone port to keep every VLAN configured on top of it working, and a
> port that is not filtering to forward frames whose VID is absent from the
> table.
>
> Turn the table off in that case. It also selects shared VLAN learning,
> which b53_arl_rw_op() already ties to the same flag. Switches with no tag
> protocol keep the CPU port tagged in every VLAN and identify the source
> port from that tag, so they stay VLAN aware.
>
> b53_configure_vlan() has to stop passing dev->vlan_enabled back in as the
> requested state. b53_enable_vlan() stores its result there, so the disabled
> state latches and enabling VLAN filtering later would not re-enable the
> table.
>
> An 8021q upper on a standalone port is the case that breaks, for example a
> PPPoE WAN on VLAN 35. The PADO comes back tagged and is dropped, so no
> session comes up and there is no default route.
>
> Tested on an Asus RT-N18U (BCM53011 rev 5) against a PPPoE concentrator on
> a VLAN 35 subinterface. pppd timed out waiting for PADO before, and the
> session establishes after. With VLAN filtering enabled the table is still
> programmed and still enforces port membership.
>
> Fixes: 06cfb2df7eb0 ("net: dsa: don't advertise 'rx-vlan-filter' when not needed")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Semih Baskan <strst.gs@xxxxxxxxx>
> ---
> I tried setting ds->needs_standalone_vlan_filtering on hardware first. It is
> not sufficient on b53: f089652b6b16 ("net: dsa: b53: do not program vlans
> when vlan filtering is off") makes .port_vlan_add return before the hardware
> write while filtering is off, so the VID still never reaches the table.
> rx-vlan-filter flipped to on and tagged frames were still dropped, 0 of 5.
>
> Relaxing that check instead also works, but only together with the opt-in
> above, since without the feature bit 8021q never calls .port_vlan_add at
> all. Making the port VLAN unaware follows the same switchdev rule that
> commit cites.
>
> I also checked the case where another bridge on the same chip has
> vlan_filtering=1, since b53 sets vlan_filtering_is_global. DSA offloads the
> uppers on the standalone port too, so rx-vlan-filter goes on there and the
> tagged frames keep arriving. This patch cannot execute in that state.
>
> drivers/net/dsa/b53/b53_common.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
> index 3f5b9592794d..76378afe4993 100644
> --- a/drivers/net/dsa/b53/b53_common.c
> +++ b/drivers/net/dsa/b53/b53_common.c
> @@ -385,6 +385,9 @@ static void b53_enable_vlan(struct b53_device *dev, int port, bool enable,
> {
> u8 mgmt, vc0, vc1, vc4 = 0, vc5;
>
> + if (!enable_filtering && dev->tag_protocol != DSA_TAG_PROTO_NONE)
> + enable = false;
> +
> b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt);
> b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL0, &vc0);
> b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL1, &vc1);
> @@ -916,7 +919,7 @@ int b53_configure_vlan(struct dsa_switch *ds)
> b53_do_vlan_op(dev, VTA_CMD_CLEAR);
> }
>
> - b53_enable_vlan(dev, -1, dev->vlan_enabled, dev->vlan_filtering);
> + b53_enable_vlan(dev, -1, true, dev->vlan_filtering);
>
> /* Create an untagged VLAN entry for the default PVID in case
> * CONFIG_VLAN_8021Q is disabled and there are no calls to
Unfortunately what this does is break modifying ARL entries with VID
!= 0, which is why I haven't added this.
While SVL is active, any ARL add/remove operations ignore the VID
field/register and force it to 0, making existing static ARL entries
with VID != 0 inaccessible, and any (static) ARL entries added will
have their VID set to 0, regardless what the software entry said.
This causes the ARL hardware table to go out of sync with the bridge
fdb/mdb software tables, and will lead to potentially hard to debug
network issues.
The options to remedy this are:
1. keep track of all static fdb (and mdb) entries added to the
hardware table, so we "sync" it on switching vlan filtering on/off (or
find a way to do so without having a copy), or
2. while vlan filtering is off, have static vlan table entries for all
possible VIDs, or
3. use direct memory access registers to directly modify the ARL table
memory instead of going through default registers while SVL is
enabled.
Neither one is a quick and easy fix.
1/2 make switching vlan filtering likely a costly operation (I test
implemented 2, and it takes several seconds for SPI connected switches
- not sure if this is acceptable). 3 requires knowing the in-memory
formats for each switch chip, which aren't publicly documented.
Best regards,
Jonas