• Vladimir Oltean's avatar
    net: dsa: untag the bridge pvid from rx skbs · 412a1526
    Vladimir Oltean authored
    Currently the bridge untags VLANs present in its VLAN groups in
    __allowed_ingress() only when VLAN filtering is enabled.
    
    But when a skb is seen on the RX path as tagged with the bridge's pvid,
    and that bridge has vlan_filtering=0, and there isn't any 8021q upper
    with that VLAN either, then we have a problem. The bridge will not untag
    it (since it is supposed to remain VLAN-unaware), and pvid-tagged
    communication will be broken.
    
    There are 2 situations where we can end up like that:
    
    1. When installing a pvid in egress-tagged mode, like this:
    
    ip link add dev br0 type bridge vlan_filtering 0
    ip link set swp0 master br0
    bridge vlan del dev swp0 vid 1
    bridge vlan add dev swp0 vid 1 pvid
    
    This happens because DSA configures the VLAN membership of the CPU port
    using the same flags as swp0 (in this case "pvid and not untagged"), in
    an attempt to copy the frame as-is from ingress to the CPU.
    
    However, in this case, the packet may arrive untagged on ingress, it
    will be pvid-tagged by the ingress port, and will be sent as
    egress-tagged towards the CPU. Otherwise stated, the CPU will see a VLAN
    tag where there was none to speak of on ingress.
    
    When vlan_filtering is 1, this is not a problem, as stated in the first
    paragraph, because __allowed_ingress() will pop it. But currently, when
    vlan_filtering is 0 and we have such a VLAN configuration, we need an
    8021q upper (br0.1) to be able to ping over that VLAN, which is not
    symmetrical with the vlan_filtering=1 case, and therefore, confusing for
    users.
    
    Basically what DSA attempts to do is simply an approximation: try to
    copy the skb with (or without) the same VLAN all the way up to the CPU.
    But DSA drivers treat CPU port VLAN membership in various ways (which is
    a good segue into situation 2). And some of those drivers simply tell
    the CPU port to copy the frame unmodified, which is the golden standard
    when it comes to VLAN processing (therefore, any driver which can
    configure the hardware to do that, should do that, and discard the VLAN
    flags requested by DSA on the CPU port).
    
    2. Some DSA drivers always configure the CPU port as egress-tagged, in
    an attempt to recover the classified VLAN from the skb. These drivers
    cannot work at all with untagged traffic when bridged in
    vlan_filtering=0 mode. And they can't go for the easy "just keep the
    pvid as egress-untagged towards the CPU" route, because each front port
    can have its own pvid, and that might require conflicting VLAN
    membership settings on the CPU port (swp1 is pvid for VID 1 and
    egress-tagged for VID 2; swp2 is egress-taggeed for VID 1 and pvid for
    VID 2; with this simplistic approach, the CPU port, which is really a
    separate hardware entity and has its own VLAN membership settings, would
    end up being egress-untagged in both VID 1 and VID 2, therefore losing
    the VLAN tags of ingress traffic).
    
    So the only thing we can do is to create a helper function for resolving
    the problematic case (that is, a function which untags the bridge pvid
    when that is in vlan_filtering=0 mode), which taggers in need should
    call. It isn't called from the generic DSA receive path because there
    are drivers that fall neither in the first nor second category.
    Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
    Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    412a1526
dsa_priv.h 7.65 KB