• Vladimir Oltean's avatar
    net: dsa: sync unicast and multicast addresses for VLAN filters too · 64fdc5f3
    Vladimir Oltean authored
    If certain conditions are met, DSA can install all necessary MAC
    addresses on the CPU ports as FDB entries and disable flooding towards
    the CPU (we call this RX filtering).
    
    There is one corner case where this does not work.
    
    ip link add br0 type bridge vlan_filtering 1 && ip link set br0 up
    ip link set swp0 master br0 && ip link set swp0 up
    ip link add link swp0 name swp0.100 type vlan id 100
    ip link set swp0.100 up && ip addr add 192.168.100.1/24 dev swp0.100
    
    Traffic through swp0.100 is broken, because the bridge turns on VLAN
    filtering in the swp0 port (causing RX packets to be classified to the
    FDB database corresponding to the VID from their 802.1Q header), and
    although the 8021q module does call dev_uc_add() towards the real
    device, that API is VLAN-unaware, so it only contains the MAC address,
    not the VID; and DSA's current implementation of ndo_set_rx_mode() is
    only for VID 0 (corresponding to FDB entries which are installed in an
    FDB database which is only hit when the port is VLAN-unaware).
    
    It's interesting to understand why the bridge does not turn on
    IFF_PROMISC for its swp0 bridge port, and it may appear at first glance
    that this is a regression caused by the logic in commit 2796d0c6
    ("bridge: Automatically manage port promiscuous mode."). After all,
    a bridge port needs to have IFF_PROMISC by its very nature - it needs to
    receive and forward frames with a MAC DA different from the bridge
    ports' MAC addresses.
    
    While that may be true, when the bridge is VLAN-aware *and* it has a
    single port, there is no real reason to enable promiscuity even if that
    is an automatic port, with flooding and learning (there is nowhere for
    packets to go except to the BR_FDB_LOCAL entries), and this is how the
    corner case appears. Adding a second automatic interface to the bridge
    would make swp0 promisc as well, and would mask the corner case.
    
    Given the dev_uc_add() / ndo_set_rx_mode() API is what it is (it doesn't
    pass a VLAN ID), the only way to address that problem is to install host
    FDB entries for the cartesian product of RX filtering MAC addresses and
    VLAN RX filters.
    
    Fixes: 7569459a ("net: dsa: manage flooding on the CPU ports")
    Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
    Reviewed-by: default avatarSimon Horman <simon.horman@corigine.com>
    Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
    Link: https://lore.kernel.org/r/20230329151821.745752-1-vladimir.oltean@nxp.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    64fdc5f3
slave.c 91.3 KB