1. 04 8月, 2021 4 次提交
    • D
      net: dsa: mt7530: always install FDB entries with IVL and FID 1 · 73c447ca
      DENG Qingfang 提交于
      This reverts commit 7e777021 ("mt7530 mt7530_fdb_write only set ivl
      bit vid larger than 1").
      
      Before this series, the default value of all ports' PVID is 1, which is
      copied into the FDB entry, even if the ports are VLAN unaware. So
      `bridge fdb show` will show entries like `dev swp0 vlan 1 self` even on
      a VLAN-unaware bridge.
      
      The blamed commit does not solve that issue completely, instead it may
      cause a new issue that FDB is inaccessible in a VLAN-aware bridge with
      PVID 1.
      
      This series sets PVID to 0 on VLAN-unaware ports, so `bridge fdb show`
      will no longer print `vlan 1` on VLAN-unaware bridges, and that special
      case in fdb_write is not required anymore.
      
      Set FDB entries' filter ID to 1 to match the VLAN table.
      Signed-off-by: NDENG Qingfang <dqfext@gmail.com>
      Reviewed-by: NVladimir Oltean <olteanv@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      73c447ca
    • D
      net: dsa: mt7530: set STP state on filter ID 1 · a9e3f62d
      DENG Qingfang 提交于
      As filter ID 1 is the only one used for bridges, set STP state on it.
      Signed-off-by: NDENG Qingfang <dqfext@gmail.com>
      Reviewed-by: NVladimir Oltean <olteanv@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      a9e3f62d
    • D
      net: dsa: mt7530: use independent VLAN learning on VLAN-unaware bridges · 6087175b
      DENG Qingfang 提交于
      Consider the following bridge configuration, where bond0 is not
      offloaded:
      
               +-- br0 --+
              / /   |     \
             / /    |      \
            /  |    |     bond0
           /   |    |     /   \
         swp0 swp1 swp2 swp3 swp4
           .        .       .
           .        .       .
           A        B       C
      
      Ideally, when the switch receives a packet from swp3 or swp4, it should
      forward the packet to the CPU, according to the port matrix and unknown
      unicast flood settings.
      
      But packet loss will happen if the destination address is at one of the
      offloaded ports (swp0~2). For example, when client C sends a packet to
      A, the FDB lookup will indicate that it should be forwarded to swp0, but
      the port matrix of swp3 and swp4 is configured to only allow the CPU to
      be its destination, so it is dropped.
      
      However, this issue does not happen if the bridge is VLAN-aware. That is
      because VLAN-aware bridges use independent VLAN learning, i.e. use VID
      for FDB lookup, on offloaded ports. As swp3 and swp4 are not offloaded,
      shared VLAN learning with default filter ID of 0 is used instead. So the
      lookup for A with filter ID 0 never hits and the packet can be forwarded
      to the CPU.
      
      In the current code, only two combinations were used to toggle user
      ports' VLAN awareness: one is PCR.PORT_VLAN set to port matrix mode with
      PVC.VLAN_ATTR set to transparent port, the other is PCR.PORT_VLAN set to
      security mode with PVC.VLAN_ATTR set to user port.
      
      It turns out that only PVC.VLAN_ATTR contributes to VLAN awareness, and
      port matrix mode just skips the VLAN table lookup. The reference manual
      is somehow misleading when describing PORT_VLAN modes. It states that
      PORT_MEM (VLAN port member) is used for destination if the VLAN table
      lookup hits, but actually **PORT_MEM & PORT_MATRIX** (bitwise AND of
      VLAN port member and port matrix) is used instead, which means we can
      have two or more separate VLAN-aware bridges with the same PVID and
      traffic won't leak between them.
      
      Therefore, to solve this, enable independent VLAN learning with PVID 0
      on VLAN-unaware bridges, by setting their PCR.PORT_VLAN to fallback
      mode, while leaving standalone ports in port matrix mode. The CPU port
      is always set to fallback mode to serve those bridges.
      
      During testing, it is found that FDB lookup with filter ID of 0 will
      also hit entries with VID 0 even with independent VLAN learning. To
      avoid that, install all VLANs with filter ID of 1.
      Signed-off-by: NDENG Qingfang <dqfext@gmail.com>
      Reviewed-by: NVladimir Oltean <olteanv@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      6087175b
    • D
      net: dsa: mt7530: enable assisted learning on CPU port · 0b69c54c
      DENG Qingfang 提交于
      Consider the following bridge configuration, where bond0 is not
      offloaded:
      
               +-- br0 --+
              / /   |     \
             / /    |      \
            /  |    |     bond0
           /   |    |     /   \
         swp0 swp1 swp2 swp3 swp4
           .        .       .
           .        .       .
           A        B       C
      
      Address learning is enabled on offloaded ports (swp0~2) and the CPU
      port, so when client A sends a packet to C, the following will happen:
      
      1. The switch learns that client A can be reached at swp0.
      2. The switch probably already knows that client C can be reached at the
         CPU port, so it forwards the packet to the CPU.
      3. The bridge core knows client C can be reached at bond0, so it
         forwards the packet back to the switch.
      4. The switch learns that client A can be reached at the CPU port.
      5. The switch forwards the packet to either swp3 or swp4, according to
         the packet's tag.
      
      That makes client A's MAC address flap between swp0 and the CPU port. If
      client B sends a packet to A, it is possible that the packet is
      forwarded to the CPU. With offload_fwd_mark = 1, the bridge core won't
      forward it back to the switch, resulting in packet loss.
      
      As we have the assisted_learning_on_cpu_port in DSA core now, enable
      that and disable hardware learning on the CPU port.
      Signed-off-by: NDENG Qingfang <dqfext@gmail.com>
      Reviewed-by: NVladimir Oltean <oltean@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      0b69c54c
  2. 02 8月, 2021 1 次提交
  3. 29 7月, 2021 3 次提交
    • V
      net: dsa: sja1105: make sure untagged packets are dropped on ingress ports with no pvid · bef0746c
      Vladimir Oltean 提交于
      Surprisingly, this configuration:
      
      ip link add br0 type bridge vlan_filtering 1
      ip link set swp2 master br0
      bridge vlan del dev swp2 vid 1
      
      still has the sja1105 switch sending untagged packets to the CPU (and
      failing to decode them, since dsa_find_designated_bridge_port_by_vid
      searches by VID 1 and rightfully finds no bridge VLAN 1 on a port).
      
      Dumping the switch configuration, the VLANs are managed properly:
      - the pvid of swp2 is 1 in the MAC Configuration Table, but
      - only the CPU port is in the port membership of VLANID 1 in the VLAN
        Lookup Table
      
      When the ingress packets are tagged with VID 1, they are properly
      dropped. But when they are untagged, they are able to reach the CPU
      port. Also, when the pvid in the MAC Configuration Table is changed to
      e.g. 55 (an unused VLAN), the untagged packets are also dropped.
      
      So it looks like:
      - the switch bypasses ingress VLAN membership checks for untagged traffic
      - the reason why the untagged traffic is dropped when I make the pvid 55
        is due to the lack of valid destination ports in VLAN 55, rather than
        an ingress membership violation
      - the ingress VLAN membership cheks are only done for VLAN-tagged traffic
      
      Interesting. It looks like there is an explicit bit to drop untagged
      traffic, so we should probably be using that to preserve user expectations.
      
      Note that only VLAN-aware ports should drop untagged packets due to no
      pvid - when VLAN-unaware, the software bridge doesn't do this even if
      there is no pvid on any bridge port and on the bridge itself. So the new
      sja1105_drop_untagged() function cannot simply be called with "false"
      from sja1105_bridge_vlan_add() and with "true" from sja1105_bridge_vlan_del.
      Instead, we need to also consider the VLAN awareness state. That means
      we need to hook the "drop untagged" setting in all the same places where
      the "commit pvid" logic is, and it needs to factor in all the state when
      flipping the "drop untagged" bit: is our current pvid in the VLAN Lookup
      Table, and is the current port in that VLAN's port membership list?
      VLAN-unaware ports will never drop untagged frames because these checks
      always succeed by construction, and the tag_8021q VLANs cannot be changed
      by the user.
      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>
      bef0746c
    • V
      net: dsa: sja1105: reset the port pvid when leaving a VLAN-aware bridge · cde8078e
      Vladimir Oltean 提交于
      Now that we no longer have the ultra-central sja1105_build_vlan_table(),
      we need to be more careful about checking all corner cases manually.
      
      For example, when a port leaves a VLAN-aware bridge, it becomes
      standalone so its pvid should become a tag_8021q RX VLAN again. However,
      sja1105_commit_pvid() only gets called from sja1105_bridge_vlan_add()
      and from sja1105_vlan_filtering(), and no VLAN awareness change takes
      place (VLAN filtering is a global setting for sja1105, so the switch
      remains VLAN-aware overall).
      
      This means that we need to put another sja1105_commit_pvid() call in
      sja1105_bridge_member().
      
      Fixes: 6dfd23d3 ("net: dsa: sja1105: delete vlan delta save/restore logic")
      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>
      cde8078e
    • V
      net: dsa: sja1105: be stateless when installing FDB entries · b11f0a4c
      Vladimir Oltean 提交于
      Currently there are issues when adding a bridge FDB entry as VLAN-aware
      and deleting it as VLAN-unaware, or vice versa.
      
      However this is an unneeded complication, since the bridge always
      installs its default FDB entries in VLAN 0 to match on VLAN-unaware
      ports, and in the default_pvid (VLAN 1) to match on VLAN-aware ports.
      So instead of trying to outsmart the bridge, just install all entries it
      gives us, and they will start matching packets when the vlan_filtering
      mode changes.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b11f0a4c
  4. 27 7月, 2021 6 次提交
    • V
      net: dsa: sja1105: add bridge TX data plane offload based on tag_8021q · b6ad86e6
      Vladimir Oltean 提交于
      The main desire for having this feature in sja1105 is to support network
      stack termination for traffic coming from a VLAN-aware bridge.
      
      For sja1105, offloading the bridge data plane means sending packets
      as-is, with the proper VLAN tag, to the chip. The chip will look up its
      FDB and forward them to the correct destination port.
      
      But we support bridge data plane offload even for VLAN-unaware bridges,
      and the implementation there is different. In fact, VLAN-unaware
      bridging is governed by tag_8021q, so it makes sense to have the
      .bridge_fwd_offload_add() implementation fully within tag_8021q.
      The key difference is that we only support 1 VLAN-aware bridge, but we
      support multiple VLAN-unaware bridges. So we need to make sure that the
      forwarding domain is not crossed by packets injected from the stack.
      
      For this, we introduce the concept of a tag_8021q TX VLAN for bridge
      forwarding offload. As opposed to the regular TX VLANs which contain
      only 2 ports (the user port and the CPU port), a bridge data plane TX
      VLAN is "multicast" (or "imprecise"): it contains all the ports that are
      part of a certain bridge, and the hardware will select where the packet
      goes within this "imprecise" forwarding domain.
      
      Each VLAN-unaware bridge has its own "imprecise" TX VLAN, so we make use
      of the unique "bridge_num" provided by DSA for the data plane offload.
      We use the same 3 bits from the tag_8021q VLAN ID format to encode this
      bridge number.
      
      Note that these 3 bit positions have been used before for sub-VLANs in
      best-effort VLAN filtering mode. The difference is that for best-effort,
      the sub-VLANs were only valid on RX (and it was documented that the
      sub-VLAN field needed to be transmitted as zero). Whereas for the bridge
      data plane offload, these 3 bits are only valid on TX.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b6ad86e6
    • V
      net: dsa: sja1105: add support for imprecise RX · 884be12f
      Vladimir Oltean 提交于
      This is already common knowledge by now, but the sja1105 does not have
      hardware support for DSA tagging for data plane packets, and tag_8021q
      sets up a unique pvid per port, transmitted as VLAN-tagged towards the
      CPU, for the source port to be decoded nonetheless.
      
      When the port is part of a VLAN-aware bridge, the pvid committed to
      hardware is taken from the bridge and not from tag_8021q, so we need to
      work with that the best we can.
      
      Configure the switches to send all packets to the CPU as VLAN-tagged
      (even ones that were originally untagged on the wire) and make use of
      dsa_untag_bridge_pvid() to get rid of it before we send those packets up
      the network stack.
      
      With the classified VLAN used by hardware known to the tagger, we first
      peek at the VID in an attempt to figure out if the packet was received
      from a VLAN-unaware port (standalone or under a VLAN-unaware bridge),
      case in which we can continue to call dsa_8021q_rcv(). If that is not
      the case, the packet probably came from a VLAN-aware bridge. So we call
      the DSA helper that finds for us a "designated bridge port" - one that
      is a member of the VLAN ID from the packet, and is in the proper STP
      state - basically these are all checks performed by br_handle_frame() in
      the software RX data path.
      
      The bridge will accept the packet as valid even if the source port was
      maybe wrong. So it will maybe learn the MAC SA of the packet on the
      wrong port, and its software FDB will be out of sync with the hardware
      FDB. So replies towards this same MAC DA will not work, because the
      bridge will send towards a different netdev.
      
      This is where the bridge data plane offload ("imprecise TX") added by
      the next patch comes in handy. The software FDB is wrong, true, but the
      hardware FDB isn't, and by offloading the bridge forwarding plane we
      have a chance to right a wrong, and have the hardware look up the FDB
      for us for the reply packet. So it all cancels out.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      884be12f
    • V
      net: dsa: sja1105: deny more than one VLAN-aware bridge · 19fa937a
      Vladimir Oltean 提交于
      With tag_sja1105.c's only ability being to perform an imprecise RX
      procedure and identify whether a packet comes from a VLAN-aware bridge
      or not, we have no way to determine whether a packet with VLAN ID 5
      comes from, say, br0 or br1. Actually we could, but it would mean that
      we need to restrict all VLANs from br0 to be different from all VLANs
      from br1, and this includes the default_pvid, which makes a setup with 2
      VLAN-aware bridges highly imprectical.
      
      The fact of the matter is that this isn't even that big of a practical
      limitation, since even with a single VLAN-aware bridge we can pretty
      much enforce forwarding isolation based on the VLAN port membership.
      
      So in the end, tell the user that they need to model their setup using a
      single VLAN-aware bridge.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      19fa937a
    • V
      net: dsa: sja1105: deny 8021q uppers on ports · 4fbc08bd
      Vladimir Oltean 提交于
      Now that best-effort VLAN filtering is gone and we are left with the
      imprecise RX and imprecise TX based in VLAN-aware mode, where the tagger
      just guesses the source port based on plausibility of the VLAN ID, 8021q
      uppers installed on top of a standalone port, while other ports of that
      switch are under a VLAN-aware bridge don't quite "just work".
      
      In fact it could be possible to restrict the VLAN IDs used by the 8021q
      uppers to not be shared with VLAN IDs used by that VLAN-aware bridge,
      but then the tagger needs to be patched to search for 8021q uppers too,
      not just for the "designated bridge port" which will be introduced in a
      later patch.
      
      I haven't given a possible implementation full thought, it seems maybe
      possible but not worth the effort right now. The only certain thing is
      that currently the tagger won't be able to figure out the source port
      for these packets because they will come with the VLAN ID of the 8021q
      upper and are no longer retagged to a tag_8021q sub-VLAN like the best
      effort VLAN filtering code used to do. So just deny these for the
      moment.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4fbc08bd
    • V
      net: dsa: sja1105: delete vlan delta save/restore logic · 6dfd23d3
      Vladimir Oltean 提交于
      With the best_effort_vlan_filtering mode now gone, the driver does not
      have 3 operating modes anymore (VLAN-unaware, VLAN-aware and best effort),
      but only 2.
      
      The idea is that we will gain support for network stack I/O through a
      VLAN-aware bridge, using the data plane offload framework (imprecise RX,
      imprecise TX). So the VLAN-aware use case will be more functional.
      
      But standalone ports that are part of the same switch when some other
      ports are under a VLAN-aware bridge should work too. Termination on
      those should work through the tag_8021q RX VLAN and TX VLAN.
      
      This was not possible using the old logic, because:
      - in VLAN-unaware mode, only the tag_8021q VLANs were committed to hw
      - in VLAN-aware mode, only the bridge VLANs were committed to hw
      - in best-effort VLAN mode, both the tag_8021q and bridge VLANs were
        committed to hw
      
      The strategy for the new VLAN-aware mode is to allow the bridge and the
      tag_8021q VLANs to coexist in the VLAN table at the same time.
      
      [ yes, we need to make sure that the bridge cannot install a tag_8021q
        VLAN, but ]
      
      This means that the save/restore logic introduced by commit ec5ae610
      ("net: dsa: sja1105: save/restore VLANs using a delta commit method")
      does not serve a purpose any longer. We can delete it and restore the
      old code that simply adds a VLAN to the VLAN table and calls it a day.
      
      Note that we keep the sja1105_commit_pvid() function from those days,
      but adapt it slightly. Ports that are under a VLAN-aware bridge use the
      bridge's pvid, ports that are standalone or under a VLAN-unaware bridge
      use the tag_8021q pvid, for local termination or VLAN-unaware forwarding.
      
      Now, when the vlan_filtering property is toggled for the bridge, the
      pvid of the ports beneath it is the only thing that's changing, we no
      longer delete some VLANs and restore others.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      6dfd23d3
    • C
      net: dsa: sja1105: remove redundant re-assignment of pointer table · d63f8877
      Colin Ian King 提交于
      The pointer table is being re-assigned with a value that is never
      read. The assignment is redundant and can be removed.
      
      Addresses-Coverity: ("Unused value")
      Signed-off-by: NColin Ian King <colin.king@canonical.com>
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      d63f8877
  5. 24 7月, 2021 1 次提交
  6. 23 7月, 2021 1 次提交
    • V
      net: dsa: mv88e6xxx: map virtual bridges with forwarding offload in the PVT · ce5df689
      Vladimir Oltean 提交于
      The mv88e6xxx switches have the ability to receive FORWARD (data plane)
      frames from the CPU port and route them according to the FDB. We can use
      this to offload the forwarding process of packets sent by the software
      bridge.
      
      Because DSA supports bridge domain isolation between user ports, just
      sending FORWARD frames is not enough, as they might leak the intended
      broadcast domain of the bridge on behalf of which the packets are sent.
      
      It should be noted that FORWARD frames are also (and typically) used to
      forward data plane packets on DSA links in cross-chip topologies. The
      FORWARD frame header contains the source port and switch ID, and
      switches receiving this frame header forward the packet according to
      their cross-chip port-based VLAN table (PVT).
      
      To address the bridging domain isolation in the context of offloading
      the forwarding on TX, the idea is that we can reuse the parts of the PVT
      that don't have any physical switch mapped to them, one entry for each
      software bridge. The switches will therefore think that behind their
      upstream port lie many switches, all in fact backed up by software
      bridges through tag_dsa.c, which constructs FORWARD packets with the
      right switch ID corresponding to each bridge.
      
      The mapping we use is absolutely trivial: DSA gives us a unique bridge
      number, and we add the number of the physical switches in the DSA switch
      tree to that, to obtain a unique virtual bridge device number to use in
      the PVT.
      Co-developed-by: NTobias Waldekranz <tobias@waldekranz.com>
      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>
      ce5df689
  7. 22 7月, 2021 1 次提交
    • V
      net: dsa: sja1105: make VID 4095 a bridge VLAN too · e40cba94
      Vladimir Oltean 提交于
      This simple series of commands:
      
      ip link add br0 type bridge vlan_filtering 1
      ip link set swp0 master br0
      
      fails on sja1105 with the following error:
      [   33.439103] sja1105 spi0.1: vlan-lookup-table needs to have at least the default untagged VLAN
      [   33.447710] sja1105 spi0.1: Invalid config, cannot upload
      Warning: sja1105: Failed to change VLAN Ethertype.
      
      For context, sja1105 has 3 operating modes:
      - SJA1105_VLAN_UNAWARE: the dsa_8021q_vlans are committed to hardware
      - SJA1105_VLAN_FILTERING_FULL: the bridge_vlans are committed to hardware
      - SJA1105_VLAN_FILTERING_BEST_EFFORT: both the dsa_8021q_vlans and the
        bridge_vlans are committed to hardware
      
      Swapping out a VLAN list and another in happens in
      sja1105_build_vlan_table(), which performs a delta update procedure.
      That function is called from a few places, notably from
      sja1105_vlan_filtering() which is called from the
      SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING handler.
      
      The above set of 2 commands fails when run on a kernel pre-commit
      8841f6e6 ("net: dsa: sja1105: make devlink property
      best_effort_vlan_filtering true by default"). So the priv->vlan_state
      transition that takes place is between VLAN-unaware and full VLAN
      filtering. So the dsa_8021q_vlans are swapped out and the bridge_vlans
      are swapped in.
      
      So why does it fail?
      
      Well, the bridge driver, through nbp_vlan_init(), first sets up the
      SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING attribute, and only then
      proceeds to call nbp_vlan_add for the default_pvid.
      
      So when we swap out the dsa_8021q_vlans and swap in the bridge_vlans in
      the SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING handler, there are no bridge
      VLANs (yet). So we have wiped the VLAN table clean, and the low-level
      static config checker complains of an invalid configuration. We _will_
      add the bridge VLANs using the dynamic config interface, albeit later,
      when nbp_vlan_add() calls us. So it is natural that it fails.
      
      So why did it ever work?
      
      Surprisingly, it looks like I only tested this configuration with 2
      things set up in a particular way:
      - a network manager that brings all ports up
      - a kernel with CONFIG_VLAN_8021Q=y
      
      It is widely known that commit ad1afb00 ("vlan_dev: VLAN 0 should be
      treated as "no vlan tag" (802.1p packet)") installs VID 0 to every net
      device that comes up. DSA treats these VLANs as bridge VLANs, and
      therefore, in my testing, the list of bridge_vlans was never empty.
      
      However, if CONFIG_VLAN_8021Q is not enabled, or the port is not up when
      it joins a VLAN-aware bridge, the bridge_vlans list will be temporarily
      empty, and the sja1105_static_config_reload() call from
      sja1105_vlan_filtering() will fail.
      
      To fix this, the simplest thing is to keep VID 4095, the one used for
      CPU-injected control packets since commit ed040abc ("net: dsa:
      sja1105: use 4095 as the private VLAN for untagged traffic"), in the
      list of bridge VLANs too, not just the list of tag_8021q VLANs. This
      ensures that the list of bridge VLANs will never be empty.
      
      Fixes: ec5ae610 ("net: dsa: sja1105: save/restore VLANs using a delta commit method")
      Reported-by: NRadu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      e40cba94
  8. 20 7月, 2021 7 次提交
    • E
      mt7530 mt7530_fdb_write only set ivl bit vid larger than 1 · 7e777021
      Eric Woudstra 提交于
      Fixes my earlier patch which broke vlan unaware bridges.
      
      The IVL bit now only gets set for vid's larger than 1.
      
      Fixes: 11d8d98c ("mt7530 fix mt7530_fdb_write vid missing ivl bit")
      Signed-off-by: NEric Woudstra <ericwouds@gmail.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      7e777021
    • V
      net: dsa: tag_8021q: add proper cross-chip notifier support · c64b9c05
      Vladimir Oltean 提交于
      The big problem which mandates cross-chip notifiers for tag_8021q is
      this:
      
                                                   |
          sw0p0     sw0p1     sw0p2     sw0p3     sw0p4
       [  user ] [  user ] [  user ] [  dsa  ] [  cpu  ]
                                         |
                                         +---------+
                                                   |
          sw1p0     sw1p1     sw1p2     sw1p3     sw1p4
       [  user ] [  user ] [  user ] [  dsa  ] [  dsa  ]
                                         |
                                         +---------+
                                                   |
          sw2p0     sw2p1     sw2p2     sw2p3     sw2p4
       [  user ] [  user ] [  user ] [  dsa  ] [  dsa  ]
      
      When the user runs:
      
      ip link add br0 type bridge
      ip link set sw0p0 master br0
      ip link set sw2p0 master br0
      
      It doesn't work.
      
      This is because dsa_8021q_crosschip_bridge_join() assumes that "ds" and
      "other_ds" are at most 1 hop away from each other, so it is sufficient
      to add the RX VLAN of {ds, port} into {other_ds, other_port} and vice
      versa and presto, the cross-chip link works. When there is another
      switch in the middle, such as in this case switch 1 with its DSA links
      sw1p3 and sw1p4, somebody needs to tell it about these VLANs too.
      
      Which is exactly why the problem is quadratic: when a port joins a
      bridge, for each port in the tree that's already in that same bridge we
      notify a tag_8021q VLAN addition of that port's RX VLAN to the entire
      tree. It is a very complicated web of VLANs.
      
      It must be mentioned that currently we install tag_8021q VLANs on too
      many ports (DSA links - to be precise, on all of them). For example,
      when sw2p0 joins br0, and assuming sw1p0 was part of br0 too, we add the
      RX VLAN of sw2p0 on the DSA links of switch 0 too, even though there
      isn't any port of switch 0 that is a member of br0 (at least yet).
      In theory we could notify only the switches which sit in between the
      port joining the bridge and the port reacting to that bridge_join event.
      But in practice that is impossible, because of the way 'link' properties
      are described in the device tree. The DSA bindings require DT writers to
      list out not only the real/physical DSA links, but in fact the entire
      routing table, like for example switch 0 above will have:
      
      	sw0p3: port@3 {
      		link = <&sw1p4 &sw2p4>;
      	};
      
      This was done because:
      
      /* TODO: ideally DSA ports would have a single dp->link_dp member,
       * and no dst->rtable nor this struct dsa_link would be needed,
       * but this would require some more complex tree walking,
       * so keep it stupid at the moment and list them all.
       */
      
      but it is a perfect example of a situation where too much information is
      actively detrimential, because we are now in the position where we
      cannot distinguish a real DSA link from one that is put there to avoid
      the 'complex tree walking'. And because DT is ABI, there is not much we
      can change.
      
      And because we do not know which DSA links are real and which ones
      aren't, we can't really know if DSA switch A is in the data path between
      switches B and C, in the general case.
      
      So this is why tag_8021q RX VLANs are added on all DSA links, and
      probably why it will never change.
      
      On the other hand, at least the number of additions/deletions is well
      balanced, and this means that once we implement reference counting at
      the cross-chip notifier level a la fdb/mdb, there is absolutely zero
      need for a struct dsa_8021q_crosschip_link, it's all self-managing.
      
      In fact, with the tag_8021q notifiers emitted from the bridge join
      notifiers, it becomes so generic that sja1105 does not need to do
      anything anymore, we can just delete its implementation of the
      .crosschip_bridge_{join,leave} methods.
      
      Among other things we can simply delete is the home-grown implementation
      of sja1105_notify_crosschip_switches(). The reason why that is wrong is
      because it is not quadratic - it only covers remote switches to which we
      have a cross-chip bridging link and that does not cover in-between
      switches. This deletion is part of the same patch because sja1105 used
      to poke deep inside the guts of the tag_8021q context in order to do
      that. Because the cross-chip links went away, so needs the sja1105 code.
      
      Last but not least, dsa_8021q_setup_port() is simplified (and also
      renamed). Because our TAG_8021Q_VLAN_ADD notifier is designed to react
      on the CPU port too, the four dsa_8021q_vid_apply() calls:
      - 1 for RX VLAN on user port
      - 1 for the user port's RX VLAN on the CPU port
      - 1 for TX VLAN on user port
      - 1 for the user port's TX VLAN on the CPU port
      
      now get squashed into only 2 notifier calls via
      dsa_port_tag_8021q_vlan_add.
      
      And because the notifiers to add and to delete a tag_8021q VLAN are
      distinct, now we finally break up the port setup and teardown into
      separate functions instead of relying on a "bool enabled" flag which
      tells us what to do. Arguably it should have been this way from the
      get go.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      c64b9c05
    • V
      net: dsa: tag_8021q: absorb dsa_8021q_setup into dsa_tag_8021q_{,un}register · 328621f6
      Vladimir Oltean 提交于
      Right now, setting up tag_8021q is a 2-step operation for a driver,
      first the context structure needs to be created, then the VLANs need to
      be installed on the ports. A similar thing is true for teardown.
      
      Merge the 2 steps into the register/unregister methods, to be as
      transparent as possible for the driver as to what tag_8021q does behind
      the scenes. This also gets rid of the funny "bool setup == true means
      setup, == false means teardown" API that tag_8021q used to expose.
      
      Note that dsa_tag_8021q_register() must be called at least in the
      .setup() driver method and never earlier (like in the driver probe
      function). This is because the DSA switch tree is not initialized at
      probe time, and the cross-chip notifiers will not work.
      
      For symmetry with .setup(), the unregister method should be put in
      .teardown().
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      328621f6
    • V
      net: dsa: make tag_8021q operations part of the core · 5da11eb4
      Vladimir Oltean 提交于
      Make tag_8021q a more central element of DSA and move the 2 driver
      specific operations outside of struct dsa_8021q_context (which is
      supposed to hold dynamic data and not really constant function
      pointers).
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      5da11eb4
    • V
      net: dsa: let the core manage the tag_8021q context · d7b1fd52
      Vladimir Oltean 提交于
      The basic problem description is as follows:
      
      Be there 3 switches in a daisy chain topology:
      
                                                   |
          sw0p0     sw0p1     sw0p2     sw0p3     sw0p4
       [  user ] [  user ] [  user ] [  dsa  ] [  cpu  ]
                                         |
                                         +---------+
                                                   |
          sw1p0     sw1p1     sw1p2     sw1p3     sw1p4
       [  user ] [  user ] [  user ] [  dsa  ] [  dsa  ]
                                         |
                                         +---------+
                                                   |
          sw2p0     sw2p1     sw2p2     sw2p3     sw2p4
       [  user ] [  user ] [  user ] [  user ] [  dsa  ]
      
      The CPU will not be able to ping through the user ports of the
      bottom-most switch (like for example sw2p0), simply because tag_8021q
      was not coded up for this scenario - it has always assumed DSA switch
      trees with a single switch.
      
      To add support for the topology above, we must admit that the RX VLAN of
      sw2p0 must be added on some ports of switches 0 and 1 as well. This is
      in fact a textbook example of thing that can use the cross-chip notifier
      framework that DSA has set up in switch.c.
      
      There is only one problem: core DSA (switch.c) is not able right now to
      make the connection between a struct dsa_switch *ds and a struct
      dsa_8021q_context *ctx. Right now, it is drivers who call into
      tag_8021q.c and always provide a struct dsa_8021q_context *ctx pointer,
      and tag_8021q.c calls them back with the .tag_8021q_vlan_{add,del}
      methods.
      
      But with cross-chip notifiers, it is possible for tag_8021q to call
      drivers without drivers having ever asked for anything. A good example
      is right above: when sw2p0 wants to set itself up for tag_8021q,
      the .tag_8021q_vlan_add method needs to be called for switches 1 and 0,
      so that they transport sw2p0's VLANs towards the CPU without dropping
      them.
      
      So instead of letting drivers manage the tag_8021q context, add a
      tag_8021q_ctx pointer inside of struct dsa_switch, which will be
      populated when dsa_tag_8021q_register() returns success.
      
      The patch is fairly long-winded because we are partly reverting commit
      5899ee36 ("net: dsa: tag_8021q: add a context structure") which made
      the driver-facing tag_8021q API use "ctx" instead of "ds". Now that we
      can access "ctx" directly from "ds", this is no longer needed.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      d7b1fd52
    • V
      net: dsa: tag_8021q: create dsa_tag_8021q_{register,unregister} helpers · cedf4670
      Vladimir Oltean 提交于
      In preparation of moving tag_8021q to core DSA, move all initialization
      and teardown related to tag_8021q which is currently done by drivers in
      2 functions called "register" and "unregister". These will gather more
      functionality in future patches, which will better justify the chosen
      naming scheme.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      cedf4670
    • V
      net: dsa: sja1105: delete the best_effort_vlan_filtering mode · 0fac6aa0
      Vladimir Oltean 提交于
      Simply put, the best-effort VLAN filtering mode relied on VLAN retagging
      from a bridge VLAN towards a tag_8021q sub-VLAN in order to be able to
      decode the source port in the tagger, but the VLAN retagging
      implementation inside the sja1105 chips is not the best and we were
      relying on marginal operating conditions.
      
      The most notable limitation of the best-effort VLAN filtering mode is
      its incapacity to treat this case properly:
      
      ip link add br0 type bridge vlan_filtering 1
      ip link set swp2 master br0
      ip link set swp4 master br0
      bridge vlan del dev swp4 vid 1
      bridge vlan add dev swp4 vid 1 pvid
      
      When sending an untagged packet through swp2, the expectation is for it
      to be forwarded to swp4 as egress-tagged (so it will contain VLAN ID 1
      on egress). But the switch will send it as egress-untagged.
      
      There was an attempt to fix this here:
      https://patchwork.kernel.org/project/netdevbpf/patch/20210407201452.1703261-2-olteanv@gmail.com/
      
      but it failed miserably because it broke PTP RX timestamping, in a way
      that cannot be corrected due to hardware issues related to VLAN
      retagging.
      
      So with either PTP broken or pushing VLAN headers on egress for untagged
      packets being broken, the sad reality is that the best-effort VLAN
      filtering code is broken. Delete it.
      
      Note that this means there will be a temporary loss of functionality in
      this driver until it is replaced with something better (network stack
      RX/TX capability for "mode 2" as described in
      Documentation/networking/dsa/sja1105.rst, the "port under VLAN-aware
      bridge" case). We simply cannot keep this code until that driver rework
      is done, it is super bloated and tangled with tag_8021q.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      0fac6aa0
  9. 17 7月, 2021 1 次提交
  10. 16 7月, 2021 1 次提交
  11. 14 7月, 2021 1 次提交
    • V
      net: dsa: sja1105: fix address learning getting disabled on the CPU port · b0b33b04
      Vladimir Oltean 提交于
      In May 2019 when commit 640f763f ("net: dsa: sja1105: Add support
      for Spanning Tree Protocol") was introduced, the comment that "STP does
      not get called for the CPU port" was true. This changed after commit
      0394a63a ("net: dsa: enable and disable all ports") in August 2019
      and went largely unnoticed, because the sja1105_bridge_stp_state_set()
      method did nothing different compared to the static setup done by
      sja1105_init_mac_settings().
      
      With the ability to turn address learning off introduced by the blamed
      commit, there is a new priv->learn_ena port mask in the driver. When
      sja1105_bridge_stp_state_set() gets called and we are in
      BR_STATE_LEARNING or later, address learning is enabled or not depending
      on priv->learn_ena & BIT(port).
      
      So what happens is that priv->learn_ena is not being set from anywhere
      for the CPU port, and the static configuration done by
      sja1105_init_mac_settings() is being overwritten.
      
      To solve this, acknowledge that the static configuration of STP state is
      no longer necessary because the STP state is being set by the DSA core
      now, but what is necessary is to set priv->learn_ena for the CPU port.
      
      Fixes: 4d942354 ("net: dsa: sja1105: offload bridge port flags to device")
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b0b33b04
  12. 12 7月, 2021 1 次提交
  13. 02 7月, 2021 6 次提交
  14. 29 6月, 2021 1 次提交
    • V
      net: dsa: sja1105: fix dynamic access to L2 Address Lookup table for SJA1110 · 74e7feff
      Vladimir Oltean 提交于
      The SJA1105P/Q/R/S and SJA1110 may have the same layout for the command
      to read/write/search for L2 Address Lookup entries, but as explained in
      the comments at the beginning of the sja1105_dynamic_config.c file, the
      command portion of the buffer is at the end, and we need to obtain a
      pointer to it by adding the length of the entry to the buffer.
      
      Alas, the length of an L2 Address Lookup entry is larger in SJA1110 than
      it is for SJA1105P/Q/R/S, so we need to create a common helper to access
      the command buffer, and this receives as argument the length of the
      entry buffer.
      
      Fixes: 3e77e59b ("net: dsa: sja1105: add support for the SJA1110 switch family")
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      74e7feff
  15. 25 6月, 2021 2 次提交
  16. 23 6月, 2021 1 次提交
  17. 22 6月, 2021 1 次提交
    • E
      net: dsa: mv88e6xxx: Fix adding vlan 0 · b8b79c41
      Eldar Gasanov 提交于
      8021q module adds vlan 0 to all interfaces when it starts.
      When 8021q module is loaded it isn't possible to create bond
      with mv88e6xxx interfaces, bonding module dipslay error
      "Couldn't add bond vlan ids", because it tries to add vlan 0
      to slave interfaces.
      
      There is unexpected behavior in the switch. When a PVID
      is assigned to a port the switch changes VID to PVID
      in ingress frames with VID 0 on the port. Expected
      that the switch doesn't assign PVID to tagged frames
      with VID 0. But there isn't a way to change this behavior
      in the switch.
      
      Fixes: 57e661aa ("net: dsa: mv88e6xxx: Link aggregation support")
      Signed-off-by: NEldar Gasanov <eldargasanov2@gmail.com>
      Reviewed-by: NVladimir Oltean <olteanv@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b8b79c41
  18. 19 6月, 2021 1 次提交