• Vladimir Oltean's avatar
    net: mscc: ocelot: use the pvid of zero when bridged with vlan_filtering=0 · 75e5a554
    Vladimir Oltean authored
    Currently, mscc_ocelot ports configure pvid=0 in standalone mode, and
    inherit the pvid from the bridge when one is present.
    
    When the bridge has vlan_filtering=0, the software semantics are that
    packets should be received regardless of whether there's a pvid
    configured on the ingress port or not. However, ocelot does not observe
    those semantics today.
    
    Moreover, changing the PVID is also a problem with vlan_filtering=0.
    We are privately remapping the VID of FDB, MDB entries to the port's
    PVID when those are VLAN-unaware (i.e. when the VID of these entries
    comes to us as 0). But we have no logic of adjusting that remapping when
    the user changes the pvid and vlan_filtering is 0. So stale entries
    would be left behind, and untagged traffic will stop matching on them.
    
    And even if we were to solve that, there's an even bigger problem. If
    swp0 has pvid 1, and swp1 has pvid 2, and both are under a vlan_filtering=0
    bridge, they should be able to forward traffic between one another.
    However, with ocelot they wouldn't do that.
    
    The simplest way of fixing this is to never configure the pvid based on
    what the bridge is asking for, when vlan_filtering is 0. Only if there
    was a VLAN that the bridge couldn't mangle, that we could use as pvid....
    So, turns out, there's 0 just for that. And for a reason: IEEE
    802.1Q-2018, page 247, Table 9-2-Reserved VID values says:
    
    	The null VID. Indicates that the tag header contains only
    	priority information; no VID is present in the frame.
    	This VID value shall not be configured as a PVID or a member
    	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    	of a VID Set, or configured in any FDB entry, or used in any
    	Management operation.
    
    So, aren't we doing exactly what 802.1Q says not to? Well, in a way, but
    what we're doing here is just driver-level bookkeeping, all for the
    better. The fact that we're using a pvid of 0 is not observable behavior
    from the outside world: the network stack does not see the classified
    VLAN that the switch uses, in vlan_filtering=0 mode. And we're also more
    consistent with the standalone mode now.
    
    And now that we use the pvid of 0 in this mode, there's another advantage:
    we don't need to perform any VID remapping for FDB and MDB entries either,
    we can just use the VID of 0 that the bridge is passing to us.
    
    The only gotcha is that every time we change the vlan_filtering setting,
    we need to reapply the pvid (either to 0, or to the value from the bridge).
    A small side-effect visible in the patch is that ocelot_port_set_pvid
    needs to be moved above ocelot_port_vlan_filtering, so that it can be
    called from there without forward-declarations.
    Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
    Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    75e5a554
ocelot.c 42.7 KB