1. 31 May, 2023 4 commits
    • Ido Schimmel's avatar
      flow_offload: Reject matching on layer 2 miss · f4356947
      Ido Schimmel authored
      Adjust drivers that support the 'FLOW_DISSECTOR_KEY_META' key to reject
      filters that try to match on the newly added layer 2 miss field. Add an
      extack message to clearly communicate the failure reason to user space.
      
      The following users were not patched:
      
      1. mtk_flow_offload_replace(): Only checks that the key is present, but
         does not do anything with it.
      2. mlx5_tc_ct_set_tuple_match(): Used as part of netfilter offload,
         which does not make use of the new field, unlike tc.
      3. get_netdev_from_rule() in nfp: Likewise.
      
      Example:
      
       # tc filter add dev swp1 egress pref 1 proto all flower skip_sw l2_miss true action drop
       Error: mlxsw_spectrum: Can't match on "l2_miss".
       We have an error talking to the kernel
      Acked-by: default avatarElad Nachman <enachman@marvell.com>
      Signed-off-by: default avatarIdo Schimmel <idosch@nvidia.com>
      Reviewed-by: default avatarNikolay Aleksandrov <razor@blackwall.org>
      Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      f4356947
    • Ido Schimmel's avatar
      net/sched: flower: Allow matching on layer 2 miss · 1a432018
      Ido Schimmel authored
      Add the 'TCA_FLOWER_L2_MISS' netlink attribute that allows user space to
      match on packets that encountered a layer 2 miss. The miss indication is
      set as metadata in the tc skb extension by the bridge driver upon FDB or
      MDB lookup miss and dissected by the flow dissector to the
      'FLOW_DISSECTOR_KEY_META' key.
      
      The use of this skb extension is guarded by the 'tc_skb_ext_tc' static
      key. As such, enable / disable this key when filters that match on layer
      2 miss are added / deleted.
      
      Tested:
      
       # cat tc_skb_ext_tc.py
       #!/usr/bin/env -S drgn -s vmlinux
      
       refcount = prog["tc_skb_ext_tc"].key.enabled.counter.value_()
       print(f"tc_skb_ext_tc reference count is {refcount}")
      
       # ./tc_skb_ext_tc.py
       tc_skb_ext_tc reference count is 0
      
       # tc filter add dev swp1 egress proto all handle 101 pref 1 flower src_mac 00:11:22:33:44:55 action drop
       # tc filter add dev swp1 egress proto all handle 102 pref 2 flower src_mac 00:11:22:33:44:55 l2_miss true action drop
       # tc filter add dev swp1 egress proto all handle 103 pref 3 flower src_mac 00:11:22:33:44:55 l2_miss false action drop
      
       # ./tc_skb_ext_tc.py
       tc_skb_ext_tc reference count is 2
      
       # tc filter replace dev swp1 egress proto all handle 102 pref 2 flower src_mac 00:01:02:03:04:05 l2_miss false action drop
      
       # ./tc_skb_ext_tc.py
       tc_skb_ext_tc reference count is 2
      
       # tc filter del dev swp1 egress proto all handle 103 pref 3 flower
       # tc filter del dev swp1 egress proto all handle 102 pref 2 flower
       # tc filter del dev swp1 egress proto all handle 101 pref 1 flower
      
       # ./tc_skb_ext_tc.py
       tc_skb_ext_tc reference count is 0
      Signed-off-by: default avatarIdo Schimmel <idosch@nvidia.com>
      Reviewed-by: default avatarNikolay Aleksandrov <razor@blackwall.org>
      Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      1a432018
    • Ido Schimmel's avatar
      flow_dissector: Dissect layer 2 miss from tc skb extension · d5ccfd90
      Ido Schimmel authored
      Extend the 'FLOW_DISSECTOR_KEY_META' key with a new 'l2_miss' field and
      populate it from a field with the same name in the tc skb extension.
      This field is set by the bridge driver for packets that incur an FDB or
      MDB miss.
      
      The next patch will extend the flower classifier to be able to match on
      layer 2 misses.
      Signed-off-by: default avatarIdo Schimmel <idosch@nvidia.com>
      Reviewed-by: default avatarNikolay Aleksandrov <razor@blackwall.org>
      Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      d5ccfd90
    • Ido Schimmel's avatar
      skbuff: bridge: Add layer 2 miss indication · 7b4858df
      Ido Schimmel authored
      For EVPN non-DF (Designated Forwarder) filtering we need to be able to
      prevent decapsulated traffic from being flooded to a multi-homed host.
      Filtering of multicast and broadcast traffic can be achieved using the
      following flower filter:
      
       # tc filter add dev bond0 egress pref 1 proto all flower indev vxlan0 dst_mac 01:00:00:00:00:00/01:00:00:00:00:00 action drop
      
      Unlike broadcast and multicast traffic, it is not currently possible to
      filter unknown unicast traffic. The classification into unknown unicast
      is performed by the bridge driver, but is not visible to other layers
      such as tc.
      
      Solve this by adding a new 'l2_miss' bit to the tc skb extension. Clear
      the bit whenever a packet enters the bridge (received from a bridge port
      or transmitted via the bridge) and set it if the packet did not match an
      FDB or MDB entry. If there is no skb extension and the bit needs to be
      cleared, then do not allocate one as no extension is equivalent to the
      bit being cleared. The bit is not set for broadcast packets as they
      never perform a lookup and therefore never incur a miss.
      
      A bit that is set for every flooded packet would also work for the
      current use case, but it does not allow us to differentiate between
      registered and unregistered multicast traffic, which might be useful in
      the future.
      
      To keep the performance impact to a minimum, the marking of packets is
      guarded by the 'tc_skb_ext_tc' static key. When 'false', the skb is not
      touched and an skb extension is not allocated. Instead, only a
      5 bytes nop is executed, as demonstrated below for the call site in
      br_handle_frame().
      
      Before the patch:
      
      ```
              memset(skb->cb, 0, sizeof(struct br_input_skb_cb));
        c37b09:       49 c7 44 24 28 00 00    movq   $0x0,0x28(%r12)
        c37b10:       00 00
      
              p = br_port_get_rcu(skb->dev);
        c37b12:       49 8b 44 24 10          mov    0x10(%r12),%rax
              memset(skb->cb, 0, sizeof(struct br_input_skb_cb));
        c37b17:       49 c7 44 24 30 00 00    movq   $0x0,0x30(%r12)
        c37b1e:       00 00
        c37b20:       49 c7 44 24 38 00 00    movq   $0x0,0x38(%r12)
        c37b27:       00 00
      ```
      
      After the patch (when static key is disabled):
      
      ```
              memset(skb->cb, 0, sizeof(struct br_input_skb_cb));
        c37c29:       49 c7 44 24 28 00 00    movq   $0x0,0x28(%r12)
        c37c30:       00 00
        c37c32:       49 8d 44 24 28          lea    0x28(%r12),%rax
        c37c37:       48 c7 40 08 00 00 00    movq   $0x0,0x8(%rax)
        c37c3e:       00
        c37c3f:       48 c7 40 10 00 00 00    movq   $0x0,0x10(%rax)
        c37c46:       00
      
      #ifdef CONFIG_HAVE_JUMP_LABEL_HACK
      
      static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
      {
              asm_volatile_goto("1:"
        c37c47:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
              br_tc_skb_miss_set(skb, false);
      
              p = br_port_get_rcu(skb->dev);
        c37c4c:       49 8b 44 24 10          mov    0x10(%r12),%rax
      ```
      
      Subsequent patches will extend the flower classifier to be able to match
      on the new 'l2_miss' bit and enable / disable the static key when
      filters that match on it are added / deleted.
      Signed-off-by: default avatarIdo Schimmel <idosch@nvidia.com>
      Acked-by: default avatarNikolay Aleksandrov <razor@blackwall.org>
      Acked-by: default avatarJakub Kicinski <kuba@kernel.org>
      Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      7b4858df
  2. 30 May, 2023 36 commits