net: mscc: ocelot: ignore VID 0 added by 8021q module
Both the felix DSA driver and ocelot switchdev driver declare dev->features & NETIF_F_HW_VLAN_CTAG_FILTER under certain circumstances*, so the 8021q module will add VID 0 to our RX filter when the port goes up, to ensure 802.1p traffic is not dropped. We treat VID 0 as a special value (OCELOT_STANDALONE_PVID) which deliberately does not have a struct ocelot_bridge_vlan associated with it. Instead, this gets programmed to the VLAN table in ocelot_vlan_init(). If we allow external calls to modify VID 0, we reach the following situation: # ip link add br0 type bridge vlan_filtering 1 && ip link set br0 up # ip link set swp0 master br0 # ip link set swp0 up # this adds VID 0 to ocelot->vlans with untagged=false bridge vlan port vlan-id swp0 1 PVID Egress Untagged # the bridge also adds VID 1 br0 1 PVID Egress Untagged # bridge vlan add dev swp0 vid 100 untagged Error: mscc_ocelot_switch_lib: Port with egress-tagged VLANs cannot have more than one egress-untagged (native) VLAN. This configuration should have been accepted, because ocelot_port_manage_port_tag() should select OCELOT_PORT_TAG_NATIVE. Yet it isn't, because we have an entry in ocelot->vlans which says VID 0 should be egress-tagged, something the hardware can't do. Fix this by suppressing additions/deletions on VID 0 and managing this VLAN exclusively using OCELOT_STANDALONE_PVID. *DSA toggles it when the port becomes VLAN-aware by joining a VLAN-aware bridge. Ocelot declares it unconditionally for some reason. Fixes: 54c319846086 ("net: mscc: ocelot: enforce FDB isolation when VLAN-unaware") Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
7c762e70c5
commit
9323ac3670
@ -629,6 +629,13 @@ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Ignore VID 0 added to our RX filter by the 8021q module, since
|
||||
* that collides with OCELOT_STANDALONE_PVID and changes it from
|
||||
* egress-untagged to egress-tagged.
|
||||
*/
|
||||
if (!vid)
|
||||
return 0;
|
||||
|
||||
err = ocelot_vlan_member_add(ocelot, port, vid, untagged);
|
||||
if (err)
|
||||
return err;
|
||||
@ -651,6 +658,9 @@ int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid)
|
||||
bool del_pvid = false;
|
||||
int err;
|
||||
|
||||
if (!vid)
|
||||
return 0;
|
||||
|
||||
if (ocelot_port->pvid_vlan && ocelot_port->pvid_vlan->vid == vid)
|
||||
del_pvid = true;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user