[PATCH net-next 07/11] net: dsa: lantiq_gswip: disallow changes to privately set up VID 0

From: Daniel Golle

Date: Wed Oct 15 2025 - 18:33:31 EST


From: Vladimir Oltean <vladimir.oltean@xxxxxxx>

User space can force the altering of VID 0 as it was privately set up by
this driver.

For example, when the port joins a VLAN-aware bridge,
dsa_user_manage_vlan_filtering() will set NETIF_F_HW_VLAN_CTAG_FILTER.
If the port is subsequently brought up and CONFIG_VLAN_8021Q is enabled,
the vlan_vid0_add() function will want to make sure we are capable of
accepting packets tagged with VID 0.

Generally, DSA/switchdev drivers want to suppress that bit of help from
the 8021q layer, and handle VID 0 filters themselves. The 8021q layer
might actually be even detrimential, because VLANs added through
vlan_vid_add() pass through dsa_user_vlan_rx_add_vid(), which is
documented as this:

/* This API only allows programming tagged, non-PVID VIDs */
.flags = 0,

so it will force VID 0 to be reconfigured as egress-tagged, non-PVID.
Whereas the driver configures it as PVID and egress-untagged, the exact
opposite.

Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
Signed-off-by: Daniel Golle <daniel@xxxxxxxxxxxxxx>
---
drivers/net/dsa/lantiq/lantiq_gswip.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/net/dsa/lantiq/lantiq_gswip.c b/drivers/net/dsa/lantiq/lantiq_gswip.c
index 58fdd54094d6..26e963840f3b 100644
--- a/drivers/net/dsa/lantiq/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq/lantiq_gswip.c
@@ -1000,6 +1000,9 @@ static int gswip_port_vlan_add(struct dsa_switch *ds, int port,
bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
int err;

+ if (vlan->vid == GSWIP_VLAN_UNAWARE_PVID)
+ return 0;
+
err = gswip_port_vlan_prepare(ds, port, vlan, extack);
if (err)
return err;
@@ -1023,6 +1026,9 @@ static int gswip_port_vlan_del(struct dsa_switch *ds, int port,
struct gswip_priv *priv = ds->priv;
bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;

+ if (vlan->vid == GSWIP_VLAN_UNAWARE_PVID)
+ return 0;
+
/* We have to receive all packets on the CPU port and should not
* do any VLAN filtering here. This is also called with bridge
* NULL and then we do not know for which bridge to configure
--
2.51.0