• Vladimir Oltean's avatar
    net: dsa: sja1105: suppress TX packets from looping back in "H" topologies · 0f9b762c
    Vladimir Oltean authored
    H topologies like this one have a problem:
    
             eth0                                                     eth1
              |                                                        |
           CPU port                                                CPU port
              |                        DSA link                        |
     sw0p0  sw0p1  sw0p2  sw0p3  sw0p4 -------- sw1p4  sw1p3  sw1p2  sw1p1  sw1p0
       |             |      |                            |      |             |
     user          user   user                         user   user          user
     port          port   port                         port   port          port
    
    Basically any packet sent by the eth0 DSA master can be flooded on the
    interconnecting DSA link sw0p4 <-> sw1p4 and it will be received by the
    eth1 DSA master too. Basically we are talking to ourselves.
    
    In VLAN-unaware mode, these packets are encoded using a tag_8021q TX
    VLAN, which dsa_8021q_rcv() rightfully cannot decode and complains.
    Whereas in VLAN-aware mode, the packets are encoded with a bridge VLAN
    which _can_ be decoded by the tagger running on eth1, so it will attempt
    to reinject that packet into the network stack (the bridge, if there is
    any port under eth1 that is under a bridge). In the case where the ports
    under eth1 are under the same cross-chip bridge as the ports under eth0,
    the TX packets will even be learned as RX packets. The only thing that
    will prevent loops with the software bridging path, and therefore
    disaster, is that the source port and the destination port are in the
    same hardware domain, and the bridge will receive packets from the
    driver with skb->offload_fwd_mark = true and will not forward between
    the two.
    
    The proper solution to this problem is to detect H topologies and
    enforce that all packets are received through the local switch and we do
    not attempt to receive packets on our CPU port from switches that have
    their own. This is a viable solution which works thanks to the fact that
    MAC addresses which should be filtered towards the host are installed by
    DSA as static MAC addresses towards the CPU port of each switch.
    
    TX from a CPU port towards the DSA port continues to be allowed, this is
    because sja1105 supports bridge TX forwarding offload, and the skb->dev
    used initially for xmit does not have any direct correlation with where
    the station that will respond to that packet is connected. It may very
    well happen that when we send a ping through a br0 interface that spans
    all switch ports, the xmit packet will exit the system through a DSA
    switch interface under eth1 (say sw1p2), but the destination station is
    connected to a switch port under eth0, like sw0p0. So the switch under
    eth1 needs to communicate on TX with the switch under eth0. The
    response, however, will not follow the same path, but instead, this
    patch enforces that the response is sent by the first switch directly to
    its DSA master which is eth0.
    Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    0f9b762c
sja1105_main.c 91.9 KB