1. 17 Feb, 2022 38 commits
  2. 16 Feb, 2022 2 commits
    • David S. Miller's avatar
      Merge branch 'Replay-and-offload-host-VLAN-entries-in-DSA' · f0ead99e
      David S. Miller authored
      Vladimir Oltean says:
      
      ====================
      Replay and offload host VLAN entries in DSA
      
      v2->v3:
      - make the bridge stop notifying switchdev for !BRENTRY VLANs
      - create precommit and commit wrappers around __vlan_add_flags().
      - special-case the BRENTRY transition from false to true, instead of
        treating it as a change of flags and letting drivers figure out that
        it really isn't.
      - avoid setting *changed unless we know that functions will not error
        out later.
      - drop "old_flags" from struct switchdev_obj_port_vlan, nobody needs it
        now, in v2 only DSA needed it to filter out BRENTRY transitions, that
        is now solved cleaner.
      - no BRIDGE_VLAN_INFO_BRENTRY flag checks and manipulations in DSA
        whatsoever, use the "bool changed" bit as-is after changing what it
        means.
      - merge dsa_slave_host_vlan_{add,del}() with
        dsa_slave_foreign_vlan_{add,del}(), since now they do the same thing,
        because the host_vlan functions no longer need to mangle the vlan
        BRENTRY flags and bool changed.
      
      v1->v2:
      - prune switchdev VLAN additions with no actual change differently
      - no longer need to revert struct net_bridge_vlan changes on error from
        switchdev
      - no longer need to first delete a changed VLAN before readding it
      - pass 'bool changed' and 'u16 old_flags' through switchdev_obj_port_vlan
        so that DSA can do some additional post-processing with the
        BRIDGE_VLAN_INFO_BRENTRY flag
      - support VLANs on foreign interfaces
      - fix the same -EOPNOTSUPP error in mv88e6xxx, this time on removal, due
        to VLAN deletion getting replayed earlier than FDB deletion
      
      The motivation behind these patches is that Rafael reported the
      following error with mv88e6xxx when the first switch port joins a
      bridge:
      
      mv88e6085 0x0000000008b96000:00: port 0 failed to add a6:ef:77:c8:5f:3d vid 1 to fdb: -95 (-EOPNOTSUPP)
      
      The FDB entry that's added is the MAC address of the bridge, in VID 1
      (the default_pvid), being replayed as part of br_add_if() -> ... ->
      nbp_switchdev_sync_objs().
      
      -EOPNOTSUPP is the mv88e6xxx driver's way of saying that VID 1 doesn't
      exist in the VTU, so it can't program the ATU with a FID, something
      which it needs.
      
      It appears to be a race, but it isn't, since we only end up installing
      VID 1 in the VTU by coincidence. DSA's approximation of programming
      VLANs on the CPU port together with the user ports breaks down with
      host FDB entries on mv88e6xxx, since that strictly requires the VTU to
      contain the VID. But the user may freely add VLANs pointing just towards
      the bridge, and FDB entries in those VLANs, and DSA will not be aware of
      them, because it only listens for VLANs on user ports.
      
      To create a solution that scales properly to cross-chip setups and
      doesn't leak entries behind, some changes in the bridge driver are
      required. I believe that these are for the better overall, but I may be
      wrong. Namely, the same refcounting procedure that DSA has in place for
      host FDB and MDB entries can be replicated for VLANs, except that it's
      garbage in, garbage out: the VLAN addition and removal notifications
      from switchdev aren't balanced. So the first 2 patches attempt to deal
      with that.
      
      This patch set has been superficially tested on a board with 3 mv88e6xxx
      switches in a daisy chain and appears to produce the primary desired
      effect - the driver no longer returns -EOPNOTSUPP when the first port
      joins a bridge, and is successful in performing local termination under
      a VLAN-aware bridge.
      As an additional side effect, it silences the annoying "p%d: already a
      member of VLAN %d\n" warning messages that the mv88e6xxx driver produces
      when coupled with systemd-networkd, and a few VLANs are configured.
      Furthermore, it advances Florian's idea from a few years back, which
      never got merged:
      https://lore.kernel.org/lkml/20180624153339.13572-1-f.fainelli@gmail.com/
      v2 has also been tested on the NXP LS1028A felix switch.
      
      Some testing:
      
      root@debian:~# bridge vlan add dev br0 vid 101 pvid self
      [  100.709220] mv88e6085 d0032004.mdio-mii:10: mv88e6xxx_port_vlan_add: port 9 vlan 101
      [  100.873426] mv88e6085 d0032004.mdio-mii:10: mv88e6xxx_port_vlan_add: port 10 vlan 101
      [  100.892314] mv88e6085 d0032004.mdio-mii:11: mv88e6xxx_port_vlan_add: port 9 vlan 101
      [  101.053392] mv88e6085 d0032004.mdio-mii:11: mv88e6xxx_port_vlan_add: port 10 vlan 101
      [  101.076994] mv88e6085 d0032004.mdio-mii:12: mv88e6xxx_port_vlan_add: port 9 vlan 101
      root@debian:~# bridge vlan add dev br0 vid 101 pvid self
      root@debian:~# bridge vlan add dev br0 vid 101 pvid self
      root@debian:~# bridge vlan
      port              vlan-id
      eth0              1 PVID Egress Untagged
      lan9              1 PVID Egress Untagged
      lan10             1 PVID Egress Untagged
      lan11             1 PVID Egress Untagged
      lan12             1 PVID Egress Untagged
      lan13             1 PVID Egress Untagged
      lan14             1 PVID Egress Untagged
      lan15             1 PVID Egress Untagged
      lan16             1 PVID Egress Untagged
      lan17             1 PVID Egress Untagged
      lan18             1 PVID Egress Untagged
      lan19             1 PVID Egress Untagged
      lan20             1 PVID Egress Untagged
      lan21             1 PVID Egress Untagged
      lan22             1 PVID Egress Untagged
      lan23             1 PVID Egress Untagged
      lan24             1 PVID Egress Untagged
      sfp               1 PVID Egress Untagged
      lan1              1 PVID Egress Untagged
      lan2              1 PVID Egress Untagged
      lan3              1 PVID Egress Untagged
      lan4              1 PVID Egress Untagged
      lan5              1 PVID Egress Untagged
      lan6              1 PVID Egress Untagged
      lan7              1 PVID Egress Untagged
      lan8              1 PVID Egress Untagged
      br0               1 Egress Untagged
                        101 PVID
      root@debian:~# bridge vlan del dev br0 vid 101 pvid self
      [  108.340487] mv88e6085 d0032004.mdio-mii:11: mv88e6xxx_port_vlan_del: port 9 vlan 101
      [  108.379167] mv88e6085 d0032004.mdio-mii:11: mv88e6xxx_port_vlan_del: port 10 vlan 101
      [  108.402319] mv88e6085 d0032004.mdio-mii:12: mv88e6xxx_port_vlan_del: port 9 vlan 101
      [  108.425866] mv88e6085 d0032004.mdio-mii:10: mv88e6xxx_port_vlan_del: port 9 vlan 101
      [  108.452280] mv88e6085 d0032004.mdio-mii:10: mv88e6xxx_port_vlan_del: port 10 vlan 101
      root@debian:~# bridge vlan del dev br0 vid 101 pvid self
      root@debian:~# bridge vlan del dev br0 vid 101 pvid self
      root@debian:~# bridge vlan
      port              vlan-id
      eth0              1 PVID Egress Untagged
      lan9              1 PVID Egress Untagged
      lan10             1 PVID Egress Untagged
      lan11             1 PVID Egress Untagged
      lan12             1 PVID Egress Untagged
      lan13             1 PVID Egress Untagged
      lan14             1 PVID Egress Untagged
      lan15             1 PVID Egress Untagged
      lan16             1 PVID Egress Untagged
      lan17             1 PVID Egress Untagged
      lan18             1 PVID Egress Untagged
      lan19             1 PVID Egress Untagged
      lan20             1 PVID Egress Untagged
      lan21             1 PVID Egress Untagged
      lan22             1 PVID Egress Untagged
      lan23             1 PVID Egress Untagged
      lan24             1 PVID Egress Untagged
      sfp               1 PVID Egress Untagged
      lan1              1 PVID Egress Untagged
      lan2              1 PVID Egress Untagged
      lan3              1 PVID Egress Untagged
      lan4              1 PVID Egress Untagged
      lan5              1 PVID Egress Untagged
      lan6              1 PVID Egress Untagged
      lan7              1 PVID Egress Untagged
      lan8              1 PVID Egress Untagged
      br0               1 Egress Untagged
      root@debian:~# bridge vlan del dev br0 vid 101 pvid self
      ====================
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      f0ead99e
    • Vladimir Oltean's avatar
      net: dsa: offload bridge port VLANs on foreign interfaces · 164f861b
      Vladimir Oltean authored
      DSA now explicitly handles VLANs installed with the 'self' flag on the
      bridge as host VLANs, instead of just replicating every bridge port VLAN
      also on the CPU port and never deleting it, which is what it did before.
      
      However, this leaves a corner case uncovered, as explained by
      Tobias Waldekranz:
      https://patchwork.kernel.org/project/netdevbpf/patch/20220209213044.2353153-6-vladimir.oltean@nxp.com/#24735260
      
      Forwarding towards a bridge port VLAN installed on a bridge port foreign
      to DSA (separate NIC, Wi-Fi AP) used to work by virtue of the fact that
      DSA itself needed to have at least one port in that VLAN (therefore, it
      also had the CPU port in said VLAN). However, now that the CPU port may
      not be member of all VLANs that user ports are members of, we need to
      ensure this isn't the case if software forwarding to a foreign interface
      is required.
      
      The solution is to treat bridge port VLANs on standalone interfaces in
      the exact same way as host VLANs. From DSA's perspective, there is no
      difference between local termination and software forwarding; packets in
      that VLAN must reach the CPU in both cases.
      Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      164f861b