1. 24 Mar, 2021 39 commits
  2. 23 Mar, 2021 1 commit
    • David S. Miller's avatar
      Merge branch 'bridge-dsa-sandwiched-LAG' · c692a0be
      David S. Miller authored
      Vladimir Oltean says:
      
      ====================
      Better support for sandwiched LAGs with bridge and DSA
      
      Changes in v4:
      - Added missing EXPORT_SYMBOL_GPL
      - Using READ_ONCE(fdb->dst)
      - Split patches into (a) adding the bridge helpers (b) making DSA use them
      - br_mdb_replay went back to the v1 approach where it allocated memory
        in atomic context
      - Created a br_switchdev_mdb_populate which reduces some of the code
        duplication
      - Fixed the error message in dsa_port_clear_brport_flags
      - Replaced "dsa_port_vlan_filtering(dp, br, extack)" with
        "dsa_port_vlan_filtering(dp, br_vlan_enabled(br), extack)" (duh)
      - Added review tags (sorry if I missed any)
      
      The objective of this series is to make LAG uppers on top of switchdev
      ports work regardless of which order we link interfaces to their masters
      (first make the port join the LAG, then the LAG join the bridge, or the
      other way around).
      
      There was a design decision to be made in patches 2-4 on whether we
      should adopt the "push" model (which attempts to solve the problem
      centrally, in the bridge layer) where the driver just calls:
      
        switchdev_bridge_port_offloaded(brport_dev,
                                        &atomic_notifier_block,
                                        &blocking_notifier_block,
                                        extack);
      
      and the bridge just replays the entire collection of switchdev port
      attributes and objects that it has, in some predefined order and with
      some predefined error handling logic;
      
      or the "pull" model (which attempts to solve the problem by giving the
      driver the rope to hang itself), where the driver, apart from calling:
      
        switchdev_bridge_port_offloaded(brport_dev, extack);
      
      has the task of "dumpster diving" (as Tobias puts it) through the bridge
      attributes and objects by itself, by calling:
      
        - br_vlan_replay
        - br_fdb_replay
        - br_mdb_replay
        - br_vlan_enabled
        - br_port_flag_is_set
        - br_port_get_stp_state
        - br_multicast_router
        - br_get_ageing_time
      
      (not necessarily all of them, and not necessarily in this order, and
      with driver-defined error handling).
      
      Even though I'm not in love myself with the "pull" model, I chose it
      because there is a fundamental trick with replaying switchdev events
      like this:
      
      ip link add br0 type bridge
      ip link add bond0 type bond
      ip link set bond0 master br0
      ip link set swp0 master bond0 <- this will replay the objects once for
                                       the bond0 bridge port, and the swp0
                                       switchdev port will process them
      ip link set swp1 master bond0 <- this will replay the objects again for
                                       the bond0 bridge port, and the swp1
                                       switchdev port will see them, but swp0
                                       will see them for the second time now
      
      Basically I believe that it is implementation defined whether the driver
      wants to error out on switchdev objects seen twice on a port, and the
      bridge should not enforce a certain model for that. For example, for FDB
      entries added to a bonding interface, the underling switchdev driver
      might have an abstraction for just that: an FDB entry pointing towards a
      logical (as opposed to physical) port. So when the second port joins the
      bridge, it doesn't realy need to replay FDB entries, since there is
      already at least one hardware port which has been receiving those
      events, and the FDB entries don't need to be added a second time to the
      same logical port.
      In the other corner, we have the drivers that handle switchdev port
      attributes on a LAG as individual switchdev port attributes on physical
      ports (example: VLAN filtering). In fact, the switchdev_handle_port_attr_set
      helper facilitates this: it is a fan-out from a single orig_dev towards
      multiple lowers that pass the check_cb().
      But that's the point: switchdev_handle_port_attr_set is just a helper
      which the driver _opts_ to use. The bridge can't enforce the "push"
      model, because that would assume that all drivers handle port attributes
      in the same way, which is probably false.
      
      For this reason, I preferred to go with the "pull" mode for this patch
      set. Just to see how bad it is for other switchdev drivers to copy-paste
      this logic, I added the pull support to ocelot too, and I think it's
      pretty manageable.
      ====================
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      c692a0be