• Vladimir Oltean's avatar
    net: dsa: support FDB events on offloaded LAG interfaces · e212fa7c
    Vladimir Oltean authored
    This change introduces support for installing static FDB entries towards
    a bridge port that is a LAG of multiple DSA switch ports, as well as
    support for filtering towards the CPU local FDB entries emitted for LAG
    interfaces that are bridge ports.
    
    Conceptually, host addresses on LAG ports are identical to what we do
    for plain bridge ports. Whereas FDB entries _towards_ a LAG can't simply
    be replicated towards all member ports like we do for multicast, or VLAN.
    Instead we need new driver API. Hardware usually considers a LAG to be a
    "logical port", and sets the entire LAG as the forwarding destination.
    The physical egress port selection within the LAG is made by hashing
    policy, as usual.
    
    To represent the logical port corresponding to the LAG, we pass by value
    a copy of the dsa_lag structure to all switches in the tree that have at
    least one port in that LAG.
    
    To illustrate why a refcounted list of FDB entries is needed in struct
    dsa_lag, it is enough to say that:
    - a LAG may be a bridge port and may therefore receive FDB events even
      while it isn't yet offloaded by any DSA interface
    - DSA interfaces may be removed from a LAG while that is a bridge port;
      we don't want FDB entries lingering around, but we don't want to
      remove entries that are still in use, either
    
    For all the cases below to work, the idea is to always keep an FDB entry
    on a LAG with a reference count equal to the DSA member ports. So:
    - if a port joins a LAG, it requests the bridge to replay the FDB, and
      the FDB entries get created, or their refcount gets bumped by one
    - if a port leaves a LAG, the FDB replay deletes or decrements refcount
      by one
    - if an FDB is installed towards a LAG with ports already present, that
      entry is created (if it doesn't exist) and its refcount is bumped by
      the amount of ports already present in the LAG
    
    echo "Adding FDB entry to bond with existing ports"
    ip link del bond0
    ip link add bond0 type bond mode 802.3ad
    ip link set swp1 down && ip link set swp1 master bond0 && ip link set swp1 up
    ip link set swp2 down && ip link set swp2 master bond0 && ip link set swp2 up
    ip link del br0
    ip link add br0 type bridge
    ip link set bond0 master br0
    bridge fdb add dev bond0 00:01:02:03:04:05 master static
    
    ip link del br0
    ip link del bond0
    
    echo "Adding FDB entry to empty bond"
    ip link del bond0
    ip link add bond0 type bond mode 802.3ad
    ip link del br0
    ip link add br0 type bridge
    ip link set bond0 master br0
    bridge fdb add dev bond0 00:01:02:03:04:05 master static
    ip link set swp1 down && ip link set swp1 master bond0 && ip link set swp1 up
    ip link set swp2 down && ip link set swp2 master bond0 && ip link set swp2 up
    
    ip link del br0
    ip link del bond0
    
    echo "Adding FDB entry to empty bond, then removing ports one by one"
    ip link del bond0
    ip link add bond0 type bond mode 802.3ad
    ip link del br0
    ip link add br0 type bridge
    ip link set bond0 master br0
    bridge fdb add dev bond0 00:01:02:03:04:05 master static
    ip link set swp1 down && ip link set swp1 master bond0 && ip link set swp1 up
    ip link set swp2 down && ip link set swp2 master bond0 && ip link set swp2 up
    
    ip link set swp1 nomaster
    ip link set swp2 nomaster
    ip link del br0
    ip link del bond0
    Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
    Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    e212fa7c
switch.c 25 KB