1. 16 2月, 2022 4 次提交
    • V
      net: bridge: vlan: notify switchdev only when something changed · 27c5f74c
      Vladimir Oltean 提交于
      Currently, when a VLAN entry is added multiple times in a row to a
      bridge port, nbp_vlan_add() calls br_switchdev_port_vlan_add() each
      time, even if the VLAN already exists and nothing about it has changed:
      
      bridge vlan add dev lan12 vid 100 master static
      
      Similarly, when a VLAN is added multiple times in a row to a bridge,
      br_vlan_add_existing() doesn't filter at all the calls to
      br_switchdev_port_vlan_add():
      
      bridge vlan add dev br0 vid 100 self
      
      This behavior makes driver-level accounting of VLANs impossible, since
      it is enough for a single deletion event to remove a VLAN, but the
      addition event can be emitted an unlimited number of times.
      
      The cause for this can be identified as follows: we rely on
      __vlan_add_flags() to retroactively tell us whether it has changed
      anything about the VLAN flags or VLAN group pvid. So we'd first have to
      call __vlan_add_flags() before calling br_switchdev_port_vlan_add(), in
      order to have access to the "bool *changed" information. But we don't
      want to change the event ordering, because we'd have to revert the
      struct net_bridge_vlan changes we've made if switchdev returns an error.
      
      So to solve this, we need another function that tells us whether any
      change is going to occur in the VLAN or VLAN group, _prior_ to calling
      __vlan_add_flags().
      
      Split __vlan_add_flags() into a precommit and a commit stage, and rename
      it to __vlan_flags_update(). The precommit stage,
      __vlan_flags_would_change(), will determine whether there is any reason
      to notify switchdev due to a change of flags (note: the BRENTRY flag
      transition from false to true is treated separately: as a new switchdev
      entry, because we skipped notifying the master VLAN when it wasn't a
      brentry yet, and therefore not as a change of flags).
      
      With this lookahead/precommit function in place, we can avoid notifying
      switchdev if nothing changed for the VLAN and VLAN group.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      27c5f74c
    • V
      net: bridge: vlan: make __vlan_add_flags react only to PVID and UNTAGGED · cab2cd77
      Vladimir Oltean 提交于
      Currently there is a very subtle aspect to the behavior of
      __vlan_add_flags(): it changes the struct net_bridge_vlan flags and
      pvid, yet it returns true ("changed") even if none of those changed,
      just a transition of br_vlan_is_brentry(v) took place from false to
      true.
      
      This can be seen in br_vlan_add_existing(), however we do not actually
      rely on this subtle behavior, since the "if" condition that checks that
      the vlan wasn't a brentry before had a useless (until now) assignment:
      
      	*changed = true;
      
      Make things more obvious by actually making __vlan_add_flags() do what's
      written on the box, and be more specific about what is actually written
      on the box. This is needed because further transformations will be done
      to __vlan_add_flags().
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Acked-by: NNikolay Aleksandrov <nikolay@nvidia.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      cab2cd77
    • V
      net: bridge: vlan: don't notify to switchdev master VLANs without BRENTRY flag · 3116ad06
      Vladimir Oltean 提交于
      When a VLAN is added to a bridge port and it doesn't exist on the bridge
      device yet, it gets created for the multicast context, but it is
      'hidden', since it doesn't have the BRENTRY flag yet:
      
      ip link add br0 type bridge && ip link set swp0 master br0
      bridge vlan add dev swp0 vid 100 # the master VLAN 100 gets created
      bridge vlan add dev br0 vid 100 self # that VLAN becomes brentry just now
      
      All switchdev drivers ignore switchdev notifiers for VLAN entries which
      have the BRENTRY unset, and for good reason: these are merely private
      data structures used by the bridge driver. So we might just as well not
      notify those at all.
      
      Cleanup in the switchdev drivers that check for the BRENTRY flag is now
      possible, and will be handled separately, since those checks just became
      dead code.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Acked-by: NNikolay Aleksandrov <nikolay@nvidia.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      3116ad06
    • V
      net: bridge: vlan: check early for lack of BRENTRY flag in br_vlan_add_existing · b2bc58d4
      Vladimir Oltean 提交于
      When a VLAN is added to a bridge port, a master VLAN gets created on the
      bridge for context, but it doesn't have the BRENTRY flag.
      
      Then, when the same VLAN is added to the bridge itself, that enters
      through the br_vlan_add_existing() code path and gains the BRENTRY flag,
      thus it becomes "existing".
      
      It seems natural to check for this condition early, because the current
      code flow is to notify switchdev of the addition of a VLAN that isn't a
      brentry, just to delete it immediately afterwards.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Acked-by: NNikolay Aleksandrov <nikolay@nvidia.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b2bc58d4
  2. 15 2月, 2022 1 次提交
  3. 28 1月, 2022 1 次提交
  4. 27 1月, 2022 1 次提交
  5. 27 11月, 2021 1 次提交
  6. 29 10月, 2021 1 次提交
  7. 27 10月, 2021 1 次提交
  8. 20 8月, 2021 1 次提交
  9. 17 8月, 2021 1 次提交
  10. 12 8月, 2021 1 次提交
  11. 27 7月, 2021 2 次提交
    • V
      net: bridge: add a helper for retrieving port VLANs from the data path · ee80dd2e
      Vladimir Oltean 提交于
      Introduce a brother of br_vlan_get_info() which is protected by the RCU
      mechanism, as opposed to br_vlan_get_info() which relies on taking the
      write-side rtnl_mutex.
      
      This is needed for drivers which need to find out whether a bridge port
      has a VLAN configured or not. For example, certain DSA switches might
      not offer complete source port identification to the CPU on RX, just the
      VLAN in which the packet was received. Based on this VLAN, we cannot set
      an accurate skb->dev ingress port, but at least we can configure one
      that behaves the same as the correct one would (this is possible because
      DSA sets skb->offload_fwd_mark = 1).
      
      When we look at the bridge RX handler (br_handle_frame), we see that
      what matters regarding skb->dev is the VLAN ID and the port STP state.
      So we need to select an skb->dev that has the same bridge VLAN as the
      packet we're receiving, and is in the LEARNING or FORWARDING STP state.
      The latter is easy, but for the former, we should somehow keep a shadow
      list of the bridge VLANs on each port, and a lookup table between VLAN
      ID and the 'designated port for imprecise RX'. That is rather
      complicated to keep in sync properly (the designated port per VLAN needs
      to be updated on the addition and removal of a VLAN, as well as on the
      join/leave events of the bridge on that port).
      
      So, to avoid all that complexity, let's just iterate through our finite
      number of ports and ask the bridge, for each packet: "do you have this
      VLAN configured on this port?".
      
      Cc: Roopa Prabhu <roopa@nvidia.com>
      Cc: Nikolay Aleksandrov <nikolay@nvidia.com>
      Cc: Ido Schimmel <idosch@nvidia.com>
      Cc: Jiri Pirko <jiri@nvidia.com>
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      ee80dd2e
    • V
      net: bridge: update BROPT_VLAN_ENABLED before notifying switchdev in br_vlan_filter_toggle · f7cdb3ec
      Vladimir Oltean 提交于
      SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING is notified by the bridge from
      two places:
      - nbp_vlan_init(), during bridge port creation
      - br_vlan_filter_toggle(), during a netlink/sysfs/ioctl change requested
        by user space
      
      If a switchdev driver uses br_vlan_enabled(br_dev) inside its handler
      for the SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING attribute notifier,
      different things will be seen depending on whether the bridge calls from
      the first path or the second:
      - in nbp_vlan_init(), br_vlan_enabled() reflects the current state of
        the bridge
      - in br_vlan_filter_toggle(), br_vlan_enabled() reflects the past state
        of the bridge
      
      This can lead in some cases to complications in driver implementation,
      which can be avoided if these could reliably use br_vlan_enabled().
      
      Nothing seems to depend on this behavior, and it seems overall more
      straightforward for br_vlan_enabled() to return the proper value even
      during the SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING notifier, so
      temporarily enable the bridge option, then revert it if the switchdev
      notifier failed.
      
      Cc: Roopa Prabhu <roopa@nvidia.com>
      Cc: Nikolay Aleksandrov <nikolay@nvidia.com>
      Cc: Ido Schimmel <idosch@nvidia.com>
      Cc: Jiri Pirko <jiri@nvidia.com>
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      f7cdb3ec
  12. 23 7月, 2021 1 次提交
    • T
      net: bridge: switchdev: allow the TX data plane forwarding to be offloaded · 47211192
      Tobias Waldekranz 提交于
      Allow switchdevs to forward frames from the CPU in accordance with the
      bridge configuration in the same way as is done between bridge
      ports. This means that the bridge will only send a single skb towards
      one of the ports under the switchdev's control, and expects the driver
      to deliver the packet to all eligible ports in its domain.
      
      Primarily this improves the performance of multicast flows with
      multiple subscribers, as it allows the hardware to perform the frame
      replication.
      
      The basic flow between the driver and the bridge is as follows:
      
      - When joining a bridge port, the switchdev driver calls
        switchdev_bridge_port_offload() with tx_fwd_offload = true.
      
      - The bridge sends offloadable skbs to one of the ports under the
        switchdev's control using skb->offload_fwd_mark = true.
      
      - The switchdev driver checks the skb->offload_fwd_mark field and lets
        its FDB lookup select the destination port mask for this packet.
      
      v1->v2:
      - convert br_input_skb_cb::fwd_hwdoms to a plain unsigned long
      - introduce a static key "br_switchdev_fwd_offload_used" to minimize the
        impact of the newly introduced feature on all the setups which don't
        have hardware that can make use of it
      - introduce a check for nbp->flags & BR_FWD_OFFLOAD to optimize cache
        line access
      - reorder nbp_switchdev_frame_mark_accel() and br_handle_vlan() in
        __br_forward()
      - do not strip VLAN on egress if forwarding offload on VLAN-aware bridge
        is being used
      - propagate errors from .ndo_dfwd_add_station() if not EOPNOTSUPP
      
      v2->v3:
      - replace the solution based on .ndo_dfwd_add_station with a solution
        based on switchdev_bridge_port_offload
      - rename BR_FWD_OFFLOAD to BR_TX_FWD_OFFLOAD
      v3->v4: rebase
      v4->v5:
      - make sure the static key is decremented on bridge port unoffload
      - more function and variable renaming and comments for them:
        br_switchdev_fwd_offload_used to br_switchdev_tx_fwd_offload
        br_switchdev_accels_skb to br_switchdev_frame_uses_tx_fwd_offload
        nbp_switchdev_frame_mark_tx_fwd to nbp_switchdev_frame_mark_tx_fwd_to_hwdom
        nbp_switchdev_frame_mark_accel to nbp_switchdev_frame_mark_tx_fwd_offload
        fwd_accel to tx_fwd_offload
      Signed-off-by: NTobias Waldekranz <tobias@waldekranz.com>
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      47211192
  13. 22 7月, 2021 2 次提交
    • V
      net: bridge: move the switchdev object replay helpers to "push" mode · 4e51bf44
      Vladimir Oltean 提交于
      Starting with commit 4f2673b3 ("net: bridge: add helper to replay
      port and host-joined mdb entries"), DSA has introduced some bridge
      helpers that replay switchdev events (FDB/MDB/VLAN additions and
      deletions) that can be lost by the switchdev drivers in a variety of
      circumstances:
      
      - an IP multicast group was host-joined on the bridge itself before any
        switchdev port joined the bridge, leading to the host MDB entries
        missing in the hardware database.
      - during the bridge creation process, the MAC address of the bridge was
        added to the FDB as an entry pointing towards the bridge device
        itself, but with no switchdev ports being part of the bridge yet, this
        local FDB entry would remain unknown to the switchdev hardware
        database.
      - a VLAN/FDB/MDB was added to a bridge port that is a LAG interface,
        before any switchdev port joined that LAG, leading to the hardware
        database missing those entries.
      - a switchdev port left a LAG that is a bridge port, while the LAG
        remained part of the bridge, and all FDB/MDB/VLAN entries remained
        installed in the hardware database of the switchdev port.
      
      Also, since commit 0d2cfbd4 ("net: bridge: ignore switchdev events
      for LAG ports which didn't request replay"), DSA introduced a method,
      based on a const void *ctx, to ensure that two switchdev ports under the
      same LAG that is a bridge port do not see the same MDB/VLAN entry being
      replayed twice by the bridge, once for every bridge port that joins the
      LAG.
      
      With so many ordering corner cases being possible, it seems unreasonable
      to expect a switchdev driver writer to get it right from the first try.
      Therefore, now that DSA has experimented with the bridge replay helpers
      for a little bit, we can move the code to the bridge driver where it is
      more readily available to all switchdev drivers.
      
      To convert the switchdev object replay helpers from "pull mode" (where
      the driver asks for them) to a "push mode" (where the bridge offers them
      automatically), the biggest problem is that the bridge needs to be aware
      when a switchdev port joins and leaves, even when the switchdev is only
      indirectly a bridge port (for example when the bridge port is a LAG
      upper of the switchdev).
      
      Luckily, we already have a hook for that, in the form of the newly
      introduced switchdev_bridge_port_offload() and
      switchdev_bridge_port_unoffload() calls. These offer a natural place for
      hooking the object addition and deletion replays.
      
      Extend the above 2 functions with:
      - pointers to the switchdev atomic notifier (for FDB replays) and the
        blocking notifier (for MDB and VLAN replays).
      - the "const void *ctx" argument required for drivers to be able to
        disambiguate between which port is targeted, when multiple ports are
        lowers of the same LAG that is a bridge port. Most of the drivers pass
        NULL to this argument, except the ones that support LAG offload and have
        the proper context check already in place in the switchdev blocking
        notifier handler.
      
      Also unexport the replay helpers, since nobody except the bridge calls
      them directly now.
      
      Note that:
      (a) we abuse the terminology slightly, because FDB entries are not
          "switchdev objects", but we count them as objects nonetheless.
          With no direct way to prove it, I think they are not modeled as
          switchdev objects because those can only be installed by the bridge
          to the hardware (as opposed to FDB entries which can be propagated
          in the other direction too). This is merely an abuse of terms, FDB
          entries are replayed too, despite not being objects.
      (b) the bridge does not attempt to sync port attributes to newly joined
          ports, just the countable stuff (the objects). The reason for this
          is simple: no universal and symmetric way to sync and unsync them is
          known. For example, VLAN filtering: what to do on unsync, disable or
          leave it enabled? Similarly, STP state, ageing timer, etc etc. What
          a switchdev port does when it becomes standalone again is not really
          up to the bridge's competence, and the driver should deal with it.
          On the other hand, replaying deletions of switchdev objects can be
          seen a matter of cleanup and therefore be treated by the bridge,
          hence this patch.
      
      We make the replay helpers opt-in for drivers, because they might not
      bring immediate benefits for them:
      
      - nbp_vlan_init() is called _after_ netdev_master_upper_dev_link(),
        so br_vlan_replay() should not do anything for the new drivers on
        which we call it. The existing drivers where there was even a slight
        possibility for there to exist a VLAN on a bridge port before they
        join it are already guarded against this: mlxsw and prestera deny
        joining LAG interfaces that are members of a bridge.
      
      - br_fdb_replay() should now notify of local FDB entries, but I patched
        all drivers except DSA to ignore these new entries in commit
        2c4eca3e ("net: bridge: switchdev: include local flag in FDB
        notifications"). Driver authors can lift this restriction as they
        wish, and when they do, they can also opt into the FDB replay
        functionality.
      
      - br_mdb_replay() should fix a real issue which is described in commit
        4f2673b3 ("net: bridge: add helper to replay port and host-joined
        mdb entries"). However most drivers do not offload the
        SWITCHDEV_OBJ_ID_HOST_MDB to see this issue: only cpsw and am65_cpsw
        offload this switchdev object, and I don't completely understand the
        way in which they offload this switchdev object anyway. So I'll leave
        it up to these drivers' respective maintainers to opt into
        br_mdb_replay().
      
      So most of the drivers pass NULL notifier blocks for the replay helpers,
      except:
      - dpaa2-switch which was already acked/regression-tested with the
        helpers enabled (and there isn't much of a downside in having them)
      - ocelot which already had replay logic in "pull" mode
      - DSA which already had replay logic in "pull" mode
      
      An important observation is that the drivers which don't currently
      request bridge event replays don't even have the
      switchdev_bridge_port_{offload,unoffload} calls placed in proper places
      right now. This was done to avoid unnecessary rework for drivers which
      might never even add support for this. For driver writers who wish to
      add replay support, this can be used as a tentative placement guide:
      https://patchwork.kernel.org/project/netdevbpf/patch/20210720134655.892334-11-vladimir.oltean@nxp.com/
      
      Cc: Vadym Kochan <vkochan@marvell.com>
      Cc: Taras Chornyi <tchornyi@marvell.com>
      Cc: Ioana Ciornei <ioana.ciornei@nxp.com>
      Cc: Lars Povlsen <lars.povlsen@microchip.com>
      Cc: Steen Hegelund <Steen.Hegelund@microchip.com>
      Cc: UNGLinuxDriver@microchip.com
      Cc: Claudiu Manoil <claudiu.manoil@nxp.com>
      Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
      Cc: Grygorii Strashko <grygorii.strashko@ti.com>
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Acked-by: Ioana Ciornei <ioana.ciornei@nxp.com> # dpaa2-switch
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4e51bf44
    • V
      net: bridge: guard the switchdev replay helpers against a NULL notifier block · 7105b50b
      Vladimir Oltean 提交于
      There is a desire to make the object and FDB replay helpers optional
      when moving them inside the bridge driver. For example a certain driver
      might not offload host MDBs and there is no case where the replay
      helpers would be of immediate use to it.
      
      So it would be nice if we could allow drivers to pass NULL pointers for
      the atomic and blocking notifier blocks, and the replay helpers to do
      nothing in that case.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      7105b50b
  14. 20 7月, 2021 5 次提交
    • N
      net: bridge: vlan: add support for dumping global vlan options · 743a53d9
      Nikolay Aleksandrov 提交于
      Add a new vlan options dump flag which causes only global vlan options
      to be dumped. The dumps are done only with bridge devices, ports are
      ignored. They support vlan compression if the options in sequential
      vlans are equal (currently always true).
      Signed-off-by: NNikolay Aleksandrov <nikolay@nvidia.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      743a53d9
    • N
      net: bridge: vlan: add support for global options · 47ecd2db
      Nikolay Aleksandrov 提交于
      We can have two types of vlan options depending on context:
       - per-device vlan options (split in per-bridge and per-port)
       - global vlan options
      
      The second type wasn't supported in the bridge until now, but we need
      them for per-vlan multicast support, per-vlan STP support and other
      options which require global vlan context. They are contained in the global
      bridge vlan context even if the vlan is not configured on the bridge device
      itself. This patch adds initial netlink attributes and support for setting
      these global vlan options, they can only be set (RTM_NEWVLAN) and the
      operation must use the bridge device. Since there are no such options yet
      it shouldn't have any functional effect.
      Signed-off-by: NNikolay Aleksandrov <nikolay@nvidia.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      47ecd2db
    • N
      net: bridge: add vlan mcast snooping knob · f4b7002a
      Nikolay Aleksandrov 提交于
      Add a global knob that controls if vlan multicast snooping is enabled.
      The proper contexts (vlan or bridge-wide) will be chosen based on the knob
      when processing packets and changing bridge device state. Note that
      vlans have their individual mcast snooping enabled by default, but this
      knob is needed to turn on bridge vlan snooping. It is disabled by
      default. To enable the knob vlan filtering must also be enabled, it
      doesn't make sense to have vlan mcast snooping without vlan filtering
      since that would lead to inconsistencies. Disabling vlan filtering will
      also automatically disable vlan mcast snooping.
      Signed-off-by: NNikolay Aleksandrov <nikolay@nvidia.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      f4b7002a
    • N
      net: bridge: multicast: add vlan state initialization and control · 7b54aaaf
      Nikolay Aleksandrov 提交于
      Add helpers to enable/disable vlan multicast based on its flags, we need
      two flags because we need to know if the vlan has multicast enabled
      globally (user-controlled) and if it has it enabled on the specific device
      (bridge or port). The new private vlan flags are:
       - BR_VLFLAG_MCAST_ENABLED: locally enabled multicast on the device, used
         when removing a vlan, toggling vlan mcast snooping and controlling
         single vlan (kernel-controlled, valid under RTNL and multicast_lock)
       - BR_VLFLAG_GLOBAL_MCAST_ENABLED: globally enabled multicast for the
         vlan, used to control the bridge-wide vlan mcast snooping for a
         single vlan (user-controlled, can be checked under any context)
      
      Bridge vlan contexts are created with multicast snooping enabled by
      default to be in line with the current bridge snooping defaults. In
      order to actually activate per vlan snooping and context usage a
      bridge-wide knob will be added later which will default to disabled.
      If that knob is enabled then automatically all vlan snooping will be
      enabled. All vlan contexts are initialized with the current bridge
      multicast context defaults.
      Signed-off-by: NNikolay Aleksandrov <nikolay@nvidia.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      7b54aaaf
    • N
      net: bridge: vlan: add global and per-port multicast context · 613d61db
      Nikolay Aleksandrov 提交于
      Add global and per-port vlan multicast context, only initialized but
      still not used. No functional changes intended.
      Signed-off-by: NNikolay Aleksandrov <nikolay@nvidia.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      613d61db
  15. 29 6月, 2021 2 次提交
    • V
      net: bridge: allow the switchdev replay functions to be called for deletion · 7e8c1858
      Vladimir Oltean 提交于
      When a switchdev port leaves a LAG that is a bridge port, the switchdev
      objects and port attributes offloaded to that port are not removed:
      
      ip link add br0 type bridge
      ip link add bond0 type bond mode 802.3ad
      ip link set swp0 master bond0
      ip link set bond0 master br0
      bridge vlan add dev bond0 vid 100
      ip link set swp0 nomaster
      
      VLAN 100 will remain installed on swp0 despite it going into standalone
      mode, because as far as the bridge is concerned, nothing ever happened
      to its bridge port.
      
      Let's extend the bridge vlan, fdb and mdb replay functions to take a
      'bool adding' argument, and make DSA and ocelot call the replay
      functions with 'adding' as false from the switchdev unsync path, for the
      switch port that leaves the bridge.
      
      Note that this patch in itself does not salvage anything, because in the
      current pull mode of operation, DSA still needs to call the replay
      helpers with adding=false. This will be done in another patch.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      7e8c1858
    • V
      net: bridge: ignore switchdev events for LAG ports which didn't request replay · 0d2cfbd4
      Vladimir Oltean 提交于
      There is a slight inconvenience in the switchdev replay helpers added
      recently, and this is when:
      
      ip link add br0 type bridge
      ip link add bond0 type bond
      ip link set bond0 master br0
      bridge vlan add dev bond0 vid 100
      ip link set swp0 master bond0
      ip link set swp1 master bond0
      
      Since the underlying driver (currently only DSA) asks for a replay of
      VLANs when swp0 and swp1 join the LAG because it is bridged, what will
      happen is that DSA will try to react twice on the VLAN event for swp0.
      This is not really a huge problem right now, because most drivers accept
      duplicates since the bridge itself does, but it will become a problem
      when we add support for replaying switchdev object deletions.
      
      Let's fix this by adding a blank void *ctx in the replay helpers, which
      will be passed on by the bridge in the switchdev notifications. If the
      context is NULL, everything is the same as before. But if the context is
      populated with a valid pointer, the underlying switchdev driver
      (currently DSA) can use the pointer to 'see through' the bridge port
      (which in the example above is bond0) and 'know' that the event is only
      for a particular physical port offloading that bridge port, and not for
      all of them.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      0d2cfbd4
  16. 19 6月, 2021 1 次提交
  17. 25 3月, 2021 3 次提交
  18. 24 3月, 2021 1 次提交
    • V
      net: bridge: add helper to replay VLANs installed on port · 22f67cdf
      Vladimir Oltean 提交于
      Currently this simple setup with DSA:
      
      ip link add br0 type bridge vlan_filtering 1
      ip link add bond0 type bond
      ip link set bond0 master br0
      ip link set swp0 master bond0
      
      will not work because the bridge has created the PVID in br_add_if ->
      nbp_vlan_init, and it has notified switchdev of the existence of VLAN 1,
      but that was too early, since swp0 was not yet a lower of bond0, so it
      had no reason to act upon that notification.
      
      We need a helper in the bridge to replay the switchdev VLAN objects that
      were notified since the bridge port creation, because some of them may
      have been missed.
      
      As opposed to the br_mdb_replay function, the vg->vlan_list write side
      protection is offered by the rtnl_mutex which is sleepable, so we don't
      need to queue up the objects in atomic context, we can replay them right
      away.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Acked-by: NNikolay Aleksandrov <nikolay@nvidia.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      22f67cdf
  19. 15 2月, 2021 3 次提交
  20. 19 1月, 2021 1 次提交
  21. 05 12月, 2020 1 次提交
  22. 02 12月, 2020 1 次提交
  23. 19 11月, 2020 1 次提交
  24. 29 9月, 2020 1 次提交
  25. 22 9月, 2020 1 次提交
    • V
      net: bridge: br_vlan_get_pvid_rcu() should dereference the VLAN group under RCU · 99f62a74
      Vladimir Oltean 提交于
      When calling the RCU brother of br_vlan_get_pvid(), lockdep warns:
      
      =============================
      WARNING: suspicious RCU usage
      5.9.0-rc3-01631-g13c17acb8e38-dirty #814 Not tainted
      -----------------------------
      net/bridge/br_private.h:1054 suspicious rcu_dereference_protected() usage!
      
      Call trace:
       lockdep_rcu_suspicious+0xd4/0xf8
       __br_vlan_get_pvid+0xc0/0x100
       br_vlan_get_pvid_rcu+0x78/0x108
      
      The warning is because br_vlan_get_pvid_rcu() calls nbp_vlan_group()
      which calls rtnl_dereference() instead of rcu_dereference(). In turn,
      rtnl_dereference() calls rcu_dereference_protected() which assumes
      operation under an RCU write-side critical section, which obviously is
      not the case here. So, when the incorrect primitive is used to access
      the RCU-protected VLAN group pointer, READ_ONCE() is not used, which may
      cause various unexpected problems.
      
      I'm sad to say that br_vlan_get_pvid() and br_vlan_get_pvid_rcu() cannot
      share the same implementation. So fix the bug by splitting the 2
      functions, and making br_vlan_get_pvid_rcu() retrieve the VLAN groups
      under proper locking annotations.
      
      Fixes: 7582f5b7 ("bridge: add br_vlan_get_pvid_rcu()")
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      99f62a74
  26. 19 9月, 2020 1 次提交