mbox series

[RFC,net-next,00/20] DSA FDB isolation

Message ID 20210818120150.892647-1-vladimir.oltean@nxp.com (mailing list archive)
Headers show
Series DSA FDB isolation | expand

Message

Vladimir Oltean Aug. 18, 2021, 12:01 p.m. UTC
I will submit patches separately because this series is very large, but
I want to first give readers the full picture before agreeing on the
fine details.

There are use cases which need FDB isolation between standalone ports
and bridged ports, as well as isolation between ports of different
bridges. Most of these use cases are a result of the fact that packets
can now be partially forwarded by the software bridge, so one port might
need to send a packet to the CPU but its FDB lookup will see that it can
forward it directly to a bridge port where that packet was autonomously
learned. So the source port will attempt to shortcircuit the CPU and
forward autonomously, which it can't due to the forwarding isolation we
have in place. So we will have packet drops instead of proper operation.

DSA does not have a driver API that encourages FDB isolation, so this
needs to be created. The basis for this is the dp->bridge_num allocation
we have created for bridge TX forwarding offload. We generalize that
concept here.

Drivers are provided that bridge_num in .port_bridge_{join,leave}, and
the bridge_dev in .port_fdb_{add,del} and .port_mdb_{add,del}. Drivers
can call dsa_bridge_num_find(bridge_dev) in the FDB/MDB methods and they
can find the bridge_num that was provided to them in .port_bridge_{join,leave}.

The association between bridge_dev and bridge_num is made at
.port_bridge_join time and broken at .port_bridge_leave time.

The trouble is that .port_bridge_leave races with FDB entries deleted by
the bridge when the port leaves. The issue is that all switchdev drivers
schedule a work item to have sleepable context, and that work item can
be actually scheduled after .port_bridge_leave. So dsa_bridge_num_find()
can potentially not work when called from .port_fdb_del after
.port_bridge_leave has been called, and that is not nice.

So switchdev is also modified to use its embedded SWITCHDEV_F_DEFER
mechanism to make the FDB notifiers emitted from the fastpath be
scheduled in sleepable context. All drivers are converted to handle
SWITCHDEV_FDB_{ADD,DEL}_TO_DEVICE from their blocking notifier block
handler. This solves the aforementioned problem because the bridge waits
for the switchdev deferred work items to finish before a port leaves,
whereas a work item privately scheduled by the driver will obviously not
be waited upon by the bridge, leading to the possibility of having the
race.

Vladimir Oltean (20):
  net: dsa: track unique bridge numbers across all DSA switch trees
  net: dsa: assign a bridge number even without TX forwarding offload
  net: dsa: propagate the bridge_num to driver .port_bridge_{join,leave}
    methods
  net: switchdev: move SWITCHDEV_FDB_{ADD,DEL}_TO_DEVICE to the blocking
    notifier chain
  net: bridge: switchdev: make br_fdb_replay offer sleepable context to
    consumers
  net: switchdev: drop the atomic notifier block from
    switchdev_bridge_port_{,un}offload
  net: switchdev: don't assume RCU context in
    switchdev_handle_fdb_{add,del}_to_device
  net: dsa: handle SWITCHDEV_FDB_{ADD,DEL}_TO_DEVICE synchronously
  net: dsa: tag_8021q: replace the SVL bridging with VLAN-unaware IVL
    bridging
  net: dsa: tag_8021q: add support for imprecise RX based on the VBID
  net: dsa: felix: delete workarounds present due to SVL tag_8021q
    bridging
  net: dsa: tag_8021q: merge RX and TX VLANs
  net: dsa: tag_8021q: rename dsa_8021q_bridge_tx_fwd_offload_vid
  net: dsa: pass extack to .port_bridge_join driver methods
  net: dsa: request drivers to perform FDB isolation
  net: dsa: sja1105: enforce FDB isolation
  net: mscc: ocelot: transmit the "native VLAN" error via extack
  net: mscc: ocelot: transmit the VLAN filtering restrictions via extack
  net: mscc: ocelot: use helpers for port VLAN membership
  net: mscc: ocelot: enforce FDB isolation when VLAN-unaware

 drivers/net/dsa/b53/b53_common.c              |  18 +-
 drivers/net/dsa/b53/b53_priv.h                |  18 +-
 drivers/net/dsa/dsa_loop.c                    |   7 +-
 drivers/net/dsa/hirschmann/hellcreek.c        |  13 +-
 drivers/net/dsa/lan9303-core.c                |  18 +-
 drivers/net/dsa/lantiq_gswip.c                |  11 +-
 drivers/net/dsa/microchip/ksz9477.c           |  12 +-
 drivers/net/dsa/microchip/ksz_common.c        |  11 +-
 drivers/net/dsa/microchip/ksz_common.h        |  11 +-
 drivers/net/dsa/mt7530.c                      |  17 +-
 drivers/net/dsa/mv88e6xxx/chip.c              |  30 +-
 drivers/net/dsa/ocelot/felix.c                | 180 ++++++------
 drivers/net/dsa/qca8k.c                       |  12 +-
 drivers/net/dsa/sja1105/sja1105_main.c        |  98 ++++---
 drivers/net/dsa/sja1105/sja1105_vl.c          |   4 +-
 drivers/net/dsa/xrs700x/xrs700x.c             |   5 +-
 .../ethernet/freescale/dpaa2/dpaa2-switch.c   |  86 +++---
 .../marvell/prestera/prestera_switchdev.c     | 112 ++++----
 .../mellanox/mlx5/core/en/rep/bridge.c        |  59 +++-
 .../mellanox/mlxsw/spectrum_switchdev.c       |  61 +++-
 .../microchip/sparx5/sparx5_switchdev.c       |  78 ++---
 drivers/net/ethernet/mscc/ocelot.c            | 255 ++++++++++++++---
 drivers/net/ethernet/mscc/ocelot.h            |   3 +
 drivers/net/ethernet/mscc/ocelot_net.c        |  95 +++++--
 drivers/net/ethernet/rocker/rocker_main.c     |  74 ++---
 drivers/net/ethernet/rocker/rocker_ofdpa.c    |   4 +-
 drivers/net/ethernet/ti/am65-cpsw-nuss.c      |   4 +-
 drivers/net/ethernet/ti/am65-cpsw-switchdev.c |  59 ++--
 drivers/net/ethernet/ti/cpsw_new.c            |   4 +-
 drivers/net/ethernet/ti/cpsw_switchdev.c      |  62 ++--
 drivers/s390/net/qeth_l2_main.c               |   4 +-
 include/linux/dsa/8021q.h                     |  29 +-
 include/net/dsa.h                             |  36 ++-
 include/net/switchdev.h                       |  26 +-
 include/soc/mscc/ocelot.h                     |  30 +-
 net/bridge/br.c                               |   5 +-
 net/bridge/br_fdb.c                           |  40 ++-
 net/bridge/br_private.h                       |   4 -
 net/bridge/br_switchdev.c                     |  18 +-
 net/dsa/dsa.c                                 |  15 -
 net/dsa/dsa2.c                                |  49 ++++
 net/dsa/dsa_priv.h                            |  25 +-
 net/dsa/port.c                                | 126 ++++----
 net/dsa/slave.c                               | 138 +++------
 net/dsa/switch.c                              |  79 ++---
 net/dsa/tag_8021q.c                           | 269 +++++++-----------
 net/dsa/tag_ocelot_8021q.c                    |   4 +-
 net/dsa/tag_sja1105.c                         |  28 +-
 net/switchdev/switchdev.c                     |  61 +++-
 49 files changed, 1428 insertions(+), 979 deletions(-)