1. 23 5月, 2022 3 次提交
  2. 21 5月, 2022 1 次提交
  3. 13 5月, 2022 4 次提交
  4. 09 5月, 2022 1 次提交
  5. 08 5月, 2022 1 次提交
  6. 07 5月, 2022 1 次提交
  7. 06 5月, 2022 5 次提交
    • V
      net: mscc: ocelot: avoid corrupting hardware counters when moving VCAP filters · 93a84170
      Vladimir Oltean 提交于
      Given the following order of operations:
      
      (1) we add filter A using tc-flower
      (2) we send a packet that matches it
      (3) we read the filter's statistics to find a hit count of 1
      (4) we add a second filter B with a higher preference than A, and A
          moves one position to the right to make room in the TCAM for it
      (5) we send another packet, and this matches the second filter B
      (6) we read the filter statistics again.
      
      When this happens, the hit count of filter A is 2 and of filter B is 1,
      despite a single packet having matched each filter.
      
      Furthermore, in an alternate history, reading the filter stats a second
      time between steps (3) and (4) makes the hit count of filter A remain at
      1 after step (6), as expected.
      
      The reason why this happens has to do with the filter->stats.pkts field,
      which is written to hardware through the call path below:
      
                     vcap_entry_set
                     /      |      \
                    /       |       \
                   /        |        \
                  /         |         \
      es0_entry_set   is1_entry_set   is2_entry_set
                  \         |         /
                   \        |        /
                    \       |       /
              vcap_data_set(data.counter, ...)
      
      The primary role of filter->stats.pkts is to transport the filter hit
      counters from the last readout all the way from vcap_entry_get() ->
      ocelot_vcap_filter_stats_update() -> ocelot_cls_flower_stats().
      The reason why vcap_entry_set() writes it to hardware is so that the
      counters (saturating and having a limited bit width) are cleared
      after each user space readout.
      
      The writing of filter->stats.pkts to hardware during the TCAM entry
      movement procedure is an unintentional consequence of the code design,
      because the hit count isn't up to date at this point.
      
      So at step (4), when filter A is moved by ocelot_vcap_filter_add() to
      make room for filter B, the hardware hit count is 0 (no packet matched
      on it in the meantime), but filter->stats.pkts is 1, because the last
      readout saw the earlier packet. The movement procedure programs the old
      hit count back to hardware, so this creates the impression to user space
      that more packets have been matched than they really were.
      
      The bug can be seen when running the gact_drop_and_ok_test() from the
      tc_actions.sh selftest.
      
      Fix the issue by reading back the hit count to tmp->stats.pkts before
      migrating the VCAP filter. Sure, this is a best-effort technique, since
      the packets that hit the rule between vcap_entry_get() and
      vcap_entry_set() won't be counted, but at least it allows the counters
      to be reliably used for selftests where the traffic is under control.
      
      The vcap_entry_get() name is a bit unintuitive, but it only reads back
      the counter portion of the TCAM entry, not the entire entry.
      
      The index from which we retrieve the counter is also a bit unintuitive
      (i - 1 during add, i + 1 during del), but this is the way in which TCAM
      entry movement works. The "entry index" isn't a stored integer for a
      TCAM filter, instead it is dynamically computed by
      ocelot_vcap_block_get_filter_index() based on the entry's position in
      the &block->rules list. That position (as well as block->count) is
      automatically updated by ocelot_vcap_filter_add_to_block() on add, and
      by ocelot_vcap_block_remove_filter() on del. So "i" is the new filter
      index, and "i - 1" or "i + 1" respectively are the old addresses of that
      TCAM entry (we only support installing/deleting one filter at a time).
      
      Fixes: b5962294 ("net: mscc: ocelot: Add support for tcam")
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      93a84170
    • V
      net: mscc: ocelot: restrict tc-trap actions to VCAP IS2 lookup 0 · 477d2b91
      Vladimir Oltean 提交于
      Once the CPU port was added to the destination port mask of a packet, it
      can never be cleared, so even packets marked as dropped by the MASK_MODE
      of a VCAP IS2 filter will still reach it. This is why we need the
      OCELOT_POLICER_DISCARD to "kill dropped packets dead" and make software
      stop seeing them.
      
      We disallow policer rules from being put on any other chain than the one
      for the first lookup, but we don't do this for "drop" rules, although we
      should. This change is merely ascertaining that the rules dont't
      (completely) work and letting the user know.
      
      The blamed commit is the one that introduced the multi-chain architecture
      in ocelot. Prior to that, we should have always offloaded the filters to
      VCAP IS2 lookup 0, where they did work.
      
      Fixes: 1397a2eb ("net: mscc: ocelot: create TCAM skeleton from tc filter chains")
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      477d2b91
    • V
      net: mscc: ocelot: fix VCAP IS2 filters matching on both lookups · 6741e118
      Vladimir Oltean 提交于
      The VCAP IS2 TCAM is looked up twice per packet, and each filter can be
      configured to only match during the first, second lookup, or both, or
      none.
      
      The blamed commit wrote the code for making VCAP IS2 filters match only
      on the given lookup. But right below that code, there was another line
      that explicitly made the lookup a "don't care", and this is overwriting
      the lookup we've selected. So the code had no effect.
      
      Some of the more noticeable effects of having filters match on both
      lookups:
      
      - in "tc -s filter show dev swp0 ingress", we see each packet matching a
        VCAP IS2 filter counted twice. This throws off scripts such as
        tools/testing/selftests/net/forwarding/tc_actions.sh and makes them
        fail.
      
      - a "tc-drop" action offloaded to VCAP IS2 needs a policer as well,
        because once the CPU port becomes a member of the destination port
        mask of a packet, nothing removes it, not even a PERMIT/DENY mask mode
        with a port mask of 0. But VCAP IS2 rules with the POLICE_ENA bit in
        the action vector can only appear in the first lookup. What happens
        when a filter matches both lookups is that the action vector is
        combined, and this makes the POLICE_ENA bit ineffective, since the
        last lookup in which it has appeared is the second one. In other
        words, "tc-drop" actions do not drop packets for the CPU port, dropped
        packets are still seen by software unless there was an FDB entry that
        directed those packets to some other place different from the CPU.
      
      The last bit used to work, because in the initial commit b5962294
      ("net: mscc: ocelot: Add support for tcam"), we were writing the FIRST
      field of the VCAP IS2 half key with a 1, not with a "don't care".
      The change to "don't care" was made inadvertently by me in commit
      c1c3993e ("net: mscc: ocelot: generalize existing code for VCAP"),
      which I just realized, and which needs a separate fix from this one,
      for "stable" kernels that lack the commit blamed below.
      
      Fixes: 226e9cd8 ("net: mscc: ocelot: only install TCAM entries into a specific lookup and PAG")
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      6741e118
    • V
      net: mscc: ocelot: fix last VCAP IS1/IS2 filter persisting in hardware when deleted · 16bbebd3
      Vladimir Oltean 提交于
      ocelot_vcap_filter_del() works by moving the next filters over the
      current one, and then deleting the last filter by calling vcap_entry_set()
      with a del_filter which was specially created by memsetting its memory
      to zeroes. vcap_entry_set() then programs this to the TCAM and action
      RAM via the cache registers.
      
      The problem is that vcap_entry_set() is a dispatch function which looks
      at del_filter->block_id. But since del_filter is zeroized memory, the
      block_id is 0, or otherwise said, VCAP_ES0. So practically, what we do
      is delete the entry at the same TCAM index from VCAP ES0 instead of IS1
      or IS2.
      
      The code was not always like this. vcap_entry_set() used to simply be
      is2_entry_set(), and then, the logic used to work.
      
      Restore the functionality by populating the block_id of the del_filter
      based on the VCAP block of the filter that we're deleting. This makes
      vcap_entry_set() know what to do.
      
      Fixes: 1397a2eb ("net: mscc: ocelot: create TCAM skeleton from tc filter chains")
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      16bbebd3
    • V
      net: mscc: ocelot: mark traps with a bool instead of keeping them in a list · e1846cff
      Vladimir Oltean 提交于
      Since the blamed commit, VCAP filters can appear on more than one list.
      If their action is "trap", they are chained on ocelot->traps via
      filter->trap_list. This is in addition to their normal placement on the
      VCAP block->rules list head.
      
      Therefore, when we free a VCAP filter, we must remove it from all lists
      it is a member of, including ocelot->traps.
      
      There are at least 2 bugs which are direct consequences of this design
      decision.
      
      First is the incorrect usage of list_empty(), meant to denote whether
      "filter" is chained into ocelot->traps via filter->trap_list.
      This does not do the correct thing, because list_empty() checks whether
      "head->next == head", but in our case, head->next == head->prev == NULL.
      So we dereference NULL pointers and die when we call list_del().
      
      Second is the fact that not all places that should remove the filter
      from ocelot->traps do so. One example is ocelot_vcap_block_remove_filter(),
      which is where we have the main kfree(filter). By keeping freed filters
      in ocelot->traps we end up in a use-after-free in
      felix_update_trapping_destinations().
      
      Attempting to fix all the buggy patterns is a whack-a-mole game which
      makes the driver unmaintainable. Actually this is what the previous
      patch version attempted to do:
      https://patchwork.kernel.org/project/netdevbpf/patch/20220503115728.834457-3-vladimir.oltean@nxp.com/
      
      but it introduced another set of bugs, because there are other places in
      which create VCAP filters, not just ocelot_vcap_filter_create():
      
      - ocelot_trap_add()
      - felix_tag_8021q_vlan_add_rx()
      - felix_tag_8021q_vlan_add_tx()
      
      Relying on the convention that all those code paths must call
      INIT_LIST_HEAD(&filter->trap_list) is not going to scale.
      
      So let's do what should have been done in the first place and keep a
      bool in struct ocelot_vcap_filter which denotes whether we are looking
      at a trapping rule or not. Iterating now happens over the main VCAP IS2
      block->rules. The advantage is that we no longer risk having stale
      references to a freed filter, since it is only present in that list.
      
      Fixes: e42bd4ed ("net: mscc: ocelot: keep traps in a list")
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      e1846cff
  8. 05 5月, 2022 5 次提交
  9. 30 4月, 2022 1 次提交
    • C
      net: ethernet: ocelot: remove the need for num_stats initializer · 2f187bfa
      Colin Foster 提交于
      There is a desire to share the oclot_stats_layout struct outside of the
      current vsc7514 driver. In order to do so, the length of the array needs to
      be known at compile time, and defined in the struct ocelot and struct
      felix_info.
      
      Since the array is defined in a .c file and would be declared in the header
      file via:
      extern struct ocelot_stat_layout[];
      the size of the array will not be known at compile time to outside modules.
      
      To fix this, remove the need for defining the number of stats at compile
      time and allow this number to be determined at initialization.
      Signed-off-by: NColin Foster <colin.foster@in-advantage.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      2f187bfa
  10. 25 4月, 2022 3 次提交
    • V
      net: mscc: ocelot: don't add VID 0 to ocelot->vlans when leaving VLAN-aware bridge · 1fcb8fb3
      Vladimir Oltean 提交于
      DSA, through dsa_port_bridge_leave(), first notifies the port of the
      fact that it left a bridge, then, if that bridge was VLAN-aware, it
      notifies the port of the change in VLAN awareness state, towards
      VLAN-unaware mode.
      
      So ocelot_port_vlan_filtering() can be called when ocelot_port->bridge
      is NULL, and this makes ocelot_add_vlan_unaware_pvid() create a struct
      ocelot_bridge_vlan with a vid of 0 and an "untagged" setting of true on
      that port.
      
      In a way this structure correctly reflects the reality, but by design,
      VID 0 (OCELOT_STANDALONE_PVID) was not meant to be kept in the bridge
      VLAN list of the driver, but managed separately.
      
      Having OCELOT_STANDALONE_PVID in ocelot->vlans makes us trip up on
      several sanity checks that did not expect to have this VID there.
      For example, after we leave a VLAN-aware bridge and we re-join it, we
      can no longer program egress-tagged VLANs to hardware:
      
       # ip link add br0 type bridge vlan_filtering 1 && ip link set br0 up
       # ip link set swp0 master br0
       # ip link set swp0 nomaster
       # ip link set swp0 master br0
       # bridge vlan add dev swp0 vid 100
      Error: mscc_ocelot_switch_lib: Port with more than one egress-untagged VLAN cannot have egress-tagged VLANs.
      
      But this configuration is in fact supported by the hardware, since we
      could use OCELOT_PORT_TAG_NATIVE. According to its comment:
      
      /* all VLANs except the native VLAN and VID 0 are egress-tagged */
      
      yet when assessing the eligibility for this mode, we do not check for
      VID 0 in ocelot_port_uses_native_vlan(), instead we just ensure that
      ocelot_port_num_untagged_vlans() == 1. This is simply because VID 0
      doesn't have a bridge VLAN structure.
      
      The way I identify the problem is that ocelot_port_vlan_filtering(false)
      only means to call ocelot_add_vlan_unaware_pvid() when we dynamically
      turn off VLAN awareness for a bridge we are under, and the PVID changes
      from the bridge PVID to a reserved PVID based on the bridge number.
      
      Since OCELOT_STANDALONE_PVID is statically added to the VLAN table
      during ocelot_vlan_init() and never removed afterwards, calling
      ocelot_add_vlan_unaware_pvid() for it is not intended and does not serve
      any purpose.
      
      Fix the issue by avoiding the call to ocelot_add_vlan_unaware_pvid(vid=0)
      when we're resetting VLAN awareness after leaving the bridge, to become
      a standalone port.
      
      Fixes: 54c31984 ("net: mscc: ocelot: enforce FDB isolation when VLAN-unaware")
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      1fcb8fb3
    • V
      net: mscc: ocelot: ignore VID 0 added by 8021q module · 9323ac36
      Vladimir Oltean 提交于
      Both the felix DSA driver and ocelot switchdev driver declare
      dev->features & NETIF_F_HW_VLAN_CTAG_FILTER under certain circumstances*,
      so the 8021q module will add VID 0 to our RX filter when the port goes
      up, to ensure 802.1p traffic is not dropped.
      
      We treat VID 0 as a special value (OCELOT_STANDALONE_PVID) which
      deliberately does not have a struct ocelot_bridge_vlan associated with
      it. Instead, this gets programmed to the VLAN table in ocelot_vlan_init().
      
      If we allow external calls to modify VID 0, we reach the following
      situation:
      
       # ip link add br0 type bridge vlan_filtering 1 && ip link set br0 up
       # ip link set swp0 master br0
       # ip link set swp0 up # this adds VID 0 to ocelot->vlans with untagged=false
      bridge vlan
      port              vlan-id
      swp0              1 PVID Egress Untagged # the bridge also adds VID 1
      br0               1 PVID Egress Untagged
       # bridge vlan add dev swp0 vid 100 untagged
      Error: mscc_ocelot_switch_lib: Port with egress-tagged VLANs cannot have more than one egress-untagged (native) VLAN.
      
      This configuration should have been accepted, because
      ocelot_port_manage_port_tag() should select OCELOT_PORT_TAG_NATIVE.
      Yet it isn't, because we have an entry in ocelot->vlans which says
      VID 0 should be egress-tagged, something the hardware can't do.
      
      Fix this by suppressing additions/deletions on VID 0 and managing this
      VLAN exclusively using OCELOT_STANDALONE_PVID.
      
      *DSA toggles it when the port becomes VLAN-aware by joining a VLAN-aware
      bridge. Ocelot declares it unconditionally for some reason.
      
      Fixes: 54c31984 ("net: mscc: ocelot: enforce FDB isolation when VLAN-unaware")
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      9323ac36
    • H
      net: mscc: ocelot: Remove useless code · 985e254c
      Haowen Bai 提交于
      payload only memset but no use at all, so we drop them.
      Signed-off-by: NHaowen Bai <baihaowen@meizu.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      985e254c
  11. 19 4月, 2022 1 次提交
  12. 18 3月, 2022 5 次提交
    • V
      net: mscc: ocelot: offload per-flow mirroring using tc-mirred and VCAP IS2 · f2a0e216
      Vladimir Oltean 提交于
      Per-flow mirroring with the VCAP IS2 TCAM (in itself handled as an
      offload for tc-flower) is done by setting the MIRROR_ENA bit from the
      action vector of the filter. The packet is mirrored to the port mask
      configured in the ANA:ANA:MIRRORPORTS register (the same port mask as
      the destinations for port-based mirroring).
      
      Functionality was tested with:
      
      tc qdisc add dev swp3 clsact
      tc filter add dev swp3 ingress protocol ip \
      	flower skip_sw ip_proto icmp \
      	action mirred egress mirror dev swp1
      
      and pinging through swp3, while seeing that the ICMP replies are
      mirrored towards swp1.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      f2a0e216
    • V
      net: mscc: ocelot: establish functions for handling VCAP aux resources · c3d427ea
      Vladimir Oltean 提交于
      Some VCAP filters utilize resources which are global to the switch, like
      for example VCAP IS2 policers take an index into a global policer pool.
      
      In commit c9a7fe12 ("net: mscc: ocelot: add action of police on
      vcap_is2"), Xiaoliang expressed this by hooking into the low-level
      ocelot_vcap_filter_add_to_block() and ocelot_vcap_block_remove_filter()
      functions, and allocating/freeing the policers from there.
      
      Evaluating the code, there probably isn't a better place, but we'll need
      to do something similar for the mirror ports, and the code will start to
      look even more hacked up than it is right now.
      
      Create two ocelot_vcap_filter_{add,del}_aux_resources() functions to
      contain the madness, and pollute less the body of other functions such
      as ocelot_vcap_filter_add_to_block().
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      c3d427ea
    • V
      net: mscc: ocelot: add port mirroring support using tc-matchall · ccb6ed42
      Vladimir Oltean 提交于
      Ocelot switches perform port-based ingress mirroring if
      ANA:PORT:PORT_CFG field SRC_MIRROR_ENA is set, and egress mirroring if
      the port is in ANA:ANA:EMIRRORPORTS.
      
      Both ingress-mirrored and egress-mirrored frames are copied to the port
      mask from ANA:ANA:MIRRORPORTS.
      
      So the choice of limiting to a single mirror port via ocelot_mirror_get()
      and ocelot_mirror_put() may seem bizarre, but the hardware model doesn't
      map very well to the user space model. If the user wants to mirror the
      ingress of swp1 towards swp2 and the ingress of swp3 towards swp4, we'd
      have to program ANA:ANA:MIRRORPORTS with BIT(2) | BIT(4), and that would
      make swp1 be mirrored towards swp4 too, and swp3 towards swp2. But there
      are no tc-matchall rules to describe those actions.
      
      Now, we could offload a matchall rule with multiple mirred actions, one
      per desired mirror port, and force the user to stick to the multi-action
      rule format for subsequent matchall filters. But both DSA and ocelot
      have the flow_offload_has_one_action() check for the matchall offload,
      plus the fact that it will get cumbersome to cross-check matchall
      mirrors with flower mirrors (which will be added in the next patch).
      
      As a result, we limit the configuration to a single mirror port, with
      the possibility of lifting the restriction in the future.
      
      Frames injected from the CPU don't get egress-mirrored, since they are
      sent with the BYPASS bit in the injection frame header, and this
      bypasses the analyzer module (effectively also the mirroring logic).
      I don't know what to do/say about this.
      
      Functionality was tested with:
      
      tc qdisc add dev swp3 clsact
      tc filter add dev swp3 ingress \
      	matchall skip_sw \
      	action mirred egress mirror dev swp1
      
      and pinging through swp3, while seeing that the ICMP replies are
      mirrored towards swp1.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      ccb6ed42
    • V
      net: mscc: ocelot: refactor policer work out of ocelot_setup_tc_cls_matchall · 4fa72108
      Vladimir Oltean 提交于
      In preparation for adding port mirroring support to the ocelot driver,
      the dispatching function ocelot_setup_tc_cls_matchall() must be free of
      action-specific code. Move port policer creation and deletion to
      separate functions.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      4fa72108
    • V
      net: mscc: ocelot: fix backwards compatibility with single-chain tc-flower offload · 8e0341ae
      Vladimir Oltean 提交于
      ACL rules can be offloaded to VCAP IS2 either through chain 0, or, since
      the blamed commit, through a chain index whose number encodes a specific
      PAG (Policy Action Group) and lookup number.
      
      The chain number is translated through ocelot_chain_to_pag() into a PAG,
      and through ocelot_chain_to_lookup() into a lookup number.
      
      The problem with the blamed commit is that the above 2 functions don't
      have special treatment for chain 0. So ocelot_chain_to_pag(0) returns
      filter->pag = 224, which is in fact -32, but the "pag" field is an u8.
      
      So we end up programming the hardware with VCAP IS2 entries having a PAG
      of 224. But the way in which the PAG works is that it defines a subset
      of VCAP IS2 filters which should match on a packet. The default PAG is
      0, and previous VCAP IS1 rules (which we offload using 'goto') can
      modify it. So basically, we are installing filters with a PAG on which
      no packet will ever match. This is the hardware equivalent of adding
      filters to a chain which has no 'goto' to it.
      
      Restore the previous functionality by making ACL filters offloaded to
      chain 0 go to PAG 0 and lookup number 0. The choice of PAG is clearly
      correct, but the choice of lookup number isn't "as before" (which was to
      leave the lookup a "don't care"). However, lookup 0 should be fine,
      since even though there are ACL actions (policers) which have a
      requirement to be used in a specific lookup, that lookup is 0.
      
      Fixes: 226e9cd8 ("net: mscc: ocelot: only install TCAM entries into a specific lookup and PAG")
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Link: https://lore.kernel.org/r/20220316192117.2568261-1-vladimir.oltean@nxp.comSigned-off-by: NJakub Kicinski <kuba@kernel.org>
      8e0341ae
  13. 16 3月, 2022 1 次提交
  14. 14 3月, 2022 1 次提交
    • V
      net: dsa: felix: configure default-prio and dscp priorities · 978777d0
      Vladimir Oltean 提交于
      Follow the established programming model for this driver and provide
      shims in the felix DSA driver which call the implementations from the
      ocelot switch lib. The ocelot switchdev driver wasn't integrated with
      dcbnl due to lack of hardware availability.
      
      The switch doesn't have any fancy QoS classification enabled by default.
      The provided getters will create a default-prio app table entry of 0,
      and no dscp entry. However, the getters have been made to actually
      retrieve the hardware configuration rather than static values, to be
      future proof in case DSA will need this information from more call paths.
      
      For default-prio, there is a single field per port, in ANA_PORT_QOS_CFG,
      called QOS_DEFAULT_VAL.
      
      DSCP classification is enabled per-port, again via ANA_PORT_QOS_CFG
      (field QOS_DSCP_ENA), and individual DSCP values are configured as
      trusted or not through register ANA_DSCP_CFG (replicated 64 times).
      An untrusted DSCP value falls back to other QoS classification methods.
      If trusted, the selected ANA_DSCP_CFG register also holds the QoS class
      in the QOS_DSCP_VAL field.
      
      The hardware also supports DSCP remapping (DSCP value X is translated to
      DSCP value Y before the QoS class is determined based on the app table
      entry for Y) and DSCP packet rewriting. The dcbnl framework, for being
      so flexible in other useless areas, doesn't appear to support this.
      So this functionality has been left out.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      978777d0
  15. 04 3月, 2022 2 次提交
  16. 03 3月, 2022 1 次提交
  17. 28 2月, 2022 1 次提交
  18. 27 2月, 2022 1 次提交
    • V
      net: mscc: ocelot: enforce FDB isolation when VLAN-unaware · 54c31984
      Vladimir Oltean 提交于
      Currently ocelot uses a pvid of 0 for standalone ports and ports under a
      VLAN-unaware bridge, and the pvid of the bridge for ports under a
      VLAN-aware bridge. Standalone ports do not perform learning, but packets
      received on them are still subject to FDB lookups. So if the MAC DA that
      a standalone port receives has been also learned on a VLAN-unaware
      bridge port, ocelot will attempt to forward to that port, even though it
      can't, so it will drop packets.
      
      So there is a desire to avoid that, and isolate the FDBs of different
      bridges from one another, and from standalone ports.
      
      The ocelot switch library has two distinct entry points: the felix DSA
      driver and the ocelot switchdev driver.
      
      We need to code up a minimal bridge_num allocation in the ocelot
      switchdev driver too, this is copied from DSA with the exception that
      ocelot does not care about DSA trees, cross-chip bridging etc. So it
      only looks at its own ports that are already in the same bridge.
      
      The ocelot switchdev driver uses the bridge_num it has allocated itself,
      while the felix driver uses the bridge_num allocated by DSA. They are
      both stored inside ocelot_port->bridge_num by the common function
      ocelot_port_bridge_join() which receives the bridge_num passed by value.
      
      Once we have a bridge_num, we can only use it to enforce isolation
      between VLAN-unaware bridges. As far as I can see, ocelot does not have
      anything like a FID that further makes VLAN 100 from a port be different
      to VLAN 100 from another port with regard to FDB lookup. So we simply
      deny multiple VLAN-aware bridges.
      
      For VLAN-unaware bridges, we crop the 4000-4095 VLAN region and we
      allocate a VLAN for each bridge_num. This will be used as the pvid of
      each port that is under that VLAN-unaware bridge, for as long as that
      bridge is VLAN-unaware.
      
      VID 0 remains only for standalone ports. It is okay if all standalone
      ports use the same VID 0, since they perform no address learning, the
      FDB will contain no entry in VLAN 0, so the packets will always be
      flooded to the only possible destination, the CPU port.
      
      The CPU port module doesn't need to be member of the VLANs to receive
      packets, but if we use the DSA tag_8021q protocol, those packets are
      part of the data plane as far as ocelot is concerned, so there it needs
      to. Just ensure that the DSA tag_8021q CPU port is a member of all
      reserved VLANs when it is created, and is removed when it is deleted.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      54c31984
  19. 25 2月, 2022 1 次提交
    • V
      net: dsa: felix: support FDB entries on offloaded LAG interfaces · 961d8b69
      Vladimir Oltean 提交于
      This adds the logic in the Felix DSA driver and Ocelot switch library.
      For Ocelot switches, the DEST_IDX that is the output of the MAC table
      lookup is a logical port (equal to physical port, if no LAG is used, or
      a dynamically allocated number otherwise). The allocation we have in
      place for LAG IDs is different from DSA's, so we can't use that:
      - DSA allocates a continuous range of LAG IDs starting from 1
      - Ocelot appears to require that physical ports and LAG IDs are in the
        same space of [0, num_phys_ports), and additionally, ports that aren't
        in a LAG must have physical port id == logical port id
      
      The implication is that an FDB entry towards a LAG might need to be
      deleted and reinstalled when the LAG ID changes.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      961d8b69
  20. 17 2月, 2022 1 次提交
    • V
      net: mscc: ocelot: annotate which traps need PTP timestamping · 9d75b881
      Vladimir Oltean 提交于
      The ocelot switch library does not need this information, but the felix
      DSA driver does.
      
      As a reminder, the VSC9959 switch in LS1028A doesn't have an IRQ line
      for packet extraction, so to be notified that a PTP packet needs to be
      dequeued, it receives that packet also over Ethernet, by setting up a
      packet trap. The Felix driver needs to install special kinds of traps
      for packets in need of RX timestamps, such that the packets are
      replicated both over Ethernet and over the CPU port module.
      
      But the Ocelot switch library sets up more than one trap for PTP event
      messages; it also traps PTP general messages, MRP control messages etc.
      Those packets don't need PTP timestamps, so there's no reason for the
      Felix driver to send them to the CPU port module.
      
      By knowing which traps need PTP timestamps, the Felix driver can
      adjust the traps installed using ocelot_trap_add() such that only those
      will actually get delivered to the CPU port module.
      Signed-off-by: NVladimir Oltean <vladimir.oltean@nxp.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      9d75b881