• Vladimir Oltean's avatar
    net: dsa: install secondary unicast and multicast addresses as host FDB/MDB · 5e8a1e03
    Vladimir Oltean authored
    In preparation of disabling flooding towards the CPU in standalone ports
    mode, identify the addresses requested by upper interfaces and use the
    new API for DSA FDB isolation to request the hardware driver to offload
    these as FDB or MDB objects. The objects belong to the user port's
    database, and are installed pointing towards the CPU port.
    
    Because dev_uc_add()/dev_mc_add() is VLAN-unaware, we offload to the
    port standalone database addresses with VID 0 (also VLAN-unaware).
    So this excludes switches with global VLAN filtering from supporting
    unicast filtering, because there, it is possible for a port of a switch
    to join a VLAN-aware bridge, and this changes the VLAN awareness of
    standalone ports, requiring VLAN-aware standalone host FDB entries.
    For the same reason, hellcreek, which requires VLAN awareness in
    standalone mode, is also exempted from unicast filtering.
    
    We create "standalone" variants of dsa_port_host_fdb_add() and
    dsa_port_host_mdb_add() (and the _del coresponding functions).
    
    We also create a separate work item type for handling deferred
    standalone host FDB/MDB entries compared to the switchdev one.
    This is done for the purpose of clarity - the procedure for offloading a
    bridge FDB entry is different than offloading a standalone one, and
    the switchdev event work handles only FDBs anyway, not MDBs.
    Deferral is needed for standalone entries because ndo_set_rx_mode runs
    in atomic context. We could probably optimize things a little by first
    queuing up all entries that need to be offloaded, and scheduling the
    work item just once, but the data structures that we can pass through
    __dev_uc_sync() and __dev_mc_sync() are limiting (there is nothing like
    a void *priv), so we'd have to keep the list of queued events somewhere
    in struct dsa_switch, and possibly a lock for it. Too complicated for
    now.
    
    Adding the address to the master is handled by dev_uc_sync(), adding it
    to the hardware is handled by __dev_uc_sync(). So this is the reason why
    dsa_port_standalone_host_fdb_add() does not call dev_uc_add(). Not that
    it had the rtnl_mutex anyway - ndo_set_rx_mode has it, but is atomic.
    Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    5e8a1e03
port.c 37.4 KB