• Vladimir Oltean's avatar
    __netif_receive_skb_core: don't untag vlan from skb on DSA master · b14a9fc4
    Vladimir Oltean authored
    A DSA master interface has upper network devices, each representing an
    Ethernet switch port attached to it. Demultiplexing the source ports and
    setting skb->dev accordingly is done through the catch-all ETH_P_XDSA
    packet_type handler. Catch-all because DSA vendors have various header
    implementations, which can be placed anywhere in the frame: before the
    DMAC, before the EtherType, before the FCS, etc. So, the ETH_P_XDSA
    handler acts like an rx_handler more than anything.
    
    It is unlikely for the DSA master interface to have any other upper than
    the DSA switch interfaces themselves. Only maybe a bridge upper*, but it
    is very likely that the DSA master will have no 8021q upper. So
    __netif_receive_skb_core() will try to untag the VLAN, despite the fact
    that the DSA switch interface might have an 8021q upper. So the skb will
    never reach that.
    
    So far, this hasn't been a problem because most of the possible
    placements of the DSA switch header mentioned in the first paragraph
    will displace the VLAN header when the DSA master receives the frame, so
    __netif_receive_skb_core() will not actually execute any VLAN-specific
    code for it. This only becomes a problem when the DSA switch header does
    not displace the VLAN header (for example with a tail tag).
    
    What the patch does is it bypasses the untagging of the skb when there
    is a DSA switch attached to this net device. So, DSA is the only
    packet_type handler which requires seeing the VLAN header. Once skb->dev
    will be changed, __netif_receive_skb_core() will be invoked again and
    untagging, or delivery to an 8021q upper, will happen in the RX of the
    DSA switch interface itself.
    
    *see commit 9eb8eff0 ("net: bridge: allow enslaving some DSA master
    network devices". This is actually the reason why I prefer keeping DSA
    as a packet_type handler of ETH_P_XDSA rather than converting to an
    rx_handler. Currently the rx_handler code doesn't support chaining, and
    this is a problem because a DSA master might be bridged.
    Signed-off-by: default avatarVladimir Oltean <olteanv@gmail.com>
    Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    b14a9fc4
dev.c 275 KB