All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next 0/7] xdp: introduce xdp-feature support
@ 2023-01-20 17:16 ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: netdev, ast, daniel, andrii, davem, kuba, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

Introduce the capability to export the XDP features supported by the NIC.
Introduce a XDP compliance test tool (xdp_features) to check the features
exported by the NIC match the real features supported by the driver.
Allow XDP_REDIRECT of non-linear XDP frames into a devmap.
Export XDP features for each XDP capable driver.
Extend libbpf netlink implementation in order to support netlink_generic
protocol.
Introduce a simple generic netlink family for netdev data.

Changes since RFCv2:
- do not assume fixed layout for genl kernel messages
- fix warnings in netdev_nl_dev_fill
- fix capabilities for nfp driver
- add supported_sg parameter to xdp_features_set_redirect_target and drop
  __xdp_features_set_redirect_target routine

Changes since RFCv1:
- Introduce netdev-genl implementation and get rid of rtnl one.
- Introduce netlink_generic support in libbpf netlink implementation
- Rename XDP_FEATURE_* in NETDEV_XDP_ACT_*
- Rename XDP_FEATURE_REDIRECT_TARGET in NETDEV_XDP_ACT_NDO_XMIT
- Rename XDP_FEATURE_FRAG_RX in NETDEV_XDP_ACT_RX_SG
- Rename XDP_FEATURE_FRAG_TARFET in NETDEV_XDP_ACT_NDO_XMIT
- Get rid of XDP_LOCK feature.
- Move xdp_feature field in a netdevice struct hole in the 4th cacheline.

Jakub Kicinski (1):
  netdev-genl: create a simple family for netdev stuff

Lorenzo Bianconi (4):
  libbpf: add the capability to specify netlink proto in
    libbpf_netlink_send_recv
  libbpf: add API to get XDP/XSK supported features
  bpf: devmap: check XDP features in bpf_map_update_elem and
    __xdp_enqueue
  selftests/bpf: introduce XDP compliance test tool

Marek Majtyka (2):
  drivers: net: turn on XDP features
  xsk: add usage of XDP features flags

 Documentation/netlink/specs/netdev.yaml       |  72 ++
 drivers/net/ethernet/amazon/ena/ena_netdev.c  |   5 +
 .../net/ethernet/aquantia/atlantic/aq_nic.c   |   4 +
 drivers/net/ethernet/broadcom/bnxt/bnxt.c     |   2 +
 drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |   2 +
 .../net/ethernet/cavium/thunder/nicvf_main.c  |   2 +
 .../net/ethernet/freescale/dpaa/dpaa_eth.c    |   2 +
 .../net/ethernet/freescale/dpaa2/dpaa2-eth.c  |   1 +
 .../net/ethernet/freescale/enetc/enetc_pf.c   |   2 +
 .../ethernet/fungible/funeth/funeth_main.c    |   6 +
 drivers/net/ethernet/intel/i40e/i40e_main.c   |  10 +-
 drivers/net/ethernet/intel/ice/ice_main.c     |   5 +
 drivers/net/ethernet/intel/igb/igb_main.c     |  10 +-
 drivers/net/ethernet/intel/igc/igc_main.c     |   2 +
 drivers/net/ethernet/intel/igc/igc_xdp.c      |   5 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |   5 +
 .../net/ethernet/intel/ixgbevf/ixgbevf_main.c |   1 +
 drivers/net/ethernet/marvell/mvneta.c         |   2 +
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c   |   3 +
 .../ethernet/marvell/octeontx2/nic/otx2_pf.c  |   8 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |   5 +
 .../net/ethernet/mellanox/mlx4/en_netdev.c    |   2 +
 .../net/ethernet/mellanox/mlx5/core/en_main.c |  10 +
 drivers/net/ethernet/microsoft/mana/mana_en.c |   1 +
 .../ethernet/netronome/nfp/nfp_net_common.c   |   5 +
 drivers/net/ethernet/qlogic/qede/qede_main.c  |   2 +
 drivers/net/ethernet/sfc/efx.c                |   3 +
 drivers/net/ethernet/sfc/siena/efx.c          |   3 +
 drivers/net/ethernet/socionext/netsec.c       |   2 +
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |   1 +
 drivers/net/ethernet/ti/cpsw.c                |   2 +
 drivers/net/ethernet/ti/cpsw_new.c            |   3 +
 drivers/net/hyperv/netvsc_drv.c               |   2 +
 drivers/net/netdevsim/netdev.c                |   1 +
 drivers/net/tun.c                             |   4 +
 drivers/net/veth.c                            |   3 +
 drivers/net/virtio_net.c                      |   5 +
 drivers/net/xen-netfront.c                    |   1 +
 include/linux/netdevice.h                     |   2 +
 include/net/xdp.h                             |  34 +
 include/uapi/linux/netdev.h                   |  66 ++
 kernel/bpf/devmap.c                           |  25 +-
 net/core/Makefile                             |   3 +-
 net/core/filter.c                             |  13 +-
 net/core/netdev-genl-gen.c                    |  48 ++
 net/core/netdev-genl-gen.h                    |  23 +
 net/core/netdev-genl.c                        | 178 +++++
 net/xdp/xsk_buff_pool.c                       |   3 +-
 tools/include/uapi/linux/netdev.h             |  66 ++
 tools/lib/bpf/libbpf.h                        |   3 +-
 tools/lib/bpf/netlink.c                       | 121 ++-
 tools/lib/bpf/nlattr.h                        |  12 +
 tools/testing/selftests/bpf/Makefile          |   5 +-
 .../selftests/bpf/progs/test_xdp_features.c   | 237 ++++++
 .../selftests/bpf/test_xdp_features.sh        |  99 +++
 tools/testing/selftests/bpf/xdp_features.c    | 743 ++++++++++++++++++
 56 files changed, 1852 insertions(+), 33 deletions(-)
 create mode 100644 Documentation/netlink/specs/netdev.yaml
 create mode 100644 include/uapi/linux/netdev.h
 create mode 100644 net/core/netdev-genl-gen.c
 create mode 100644 net/core/netdev-genl-gen.h
 create mode 100644 net/core/netdev-genl.c
 create mode 100644 tools/include/uapi/linux/netdev.h
 create mode 100644 tools/testing/selftests/bpf/progs/test_xdp_features.c
 create mode 100755 tools/testing/selftests/bpf/test_xdp_features.sh
 create mode 100644 tools/testing/selftests/bpf/xdp_features.c

-- 
2.39.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Intel-wired-lan] [PATCH bpf-next 0/7] xdp: introduce xdp-feature support
@ 2023-01-20 17:16 ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, kuba,
	pabeni, aelior, hawk, christophe.jaillet, memxor, john, bjorn,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

Introduce the capability to export the XDP features supported by the NIC.
Introduce a XDP compliance test tool (xdp_features) to check the features
exported by the NIC match the real features supported by the driver.
Allow XDP_REDIRECT of non-linear XDP frames into a devmap.
Export XDP features for each XDP capable driver.
Extend libbpf netlink implementation in order to support netlink_generic
protocol.
Introduce a simple generic netlink family for netdev data.

Changes since RFCv2:
- do not assume fixed layout for genl kernel messages
- fix warnings in netdev_nl_dev_fill
- fix capabilities for nfp driver
- add supported_sg parameter to xdp_features_set_redirect_target and drop
  __xdp_features_set_redirect_target routine

Changes since RFCv1:
- Introduce netdev-genl implementation and get rid of rtnl one.
- Introduce netlink_generic support in libbpf netlink implementation
- Rename XDP_FEATURE_* in NETDEV_XDP_ACT_*
- Rename XDP_FEATURE_REDIRECT_TARGET in NETDEV_XDP_ACT_NDO_XMIT
- Rename XDP_FEATURE_FRAG_RX in NETDEV_XDP_ACT_RX_SG
- Rename XDP_FEATURE_FRAG_TARFET in NETDEV_XDP_ACT_NDO_XMIT
- Get rid of XDP_LOCK feature.
- Move xdp_feature field in a netdevice struct hole in the 4th cacheline.

Jakub Kicinski (1):
  netdev-genl: create a simple family for netdev stuff

Lorenzo Bianconi (4):
  libbpf: add the capability to specify netlink proto in
    libbpf_netlink_send_recv
  libbpf: add API to get XDP/XSK supported features
  bpf: devmap: check XDP features in bpf_map_update_elem and
    __xdp_enqueue
  selftests/bpf: introduce XDP compliance test tool

Marek Majtyka (2):
  drivers: net: turn on XDP features
  xsk: add usage of XDP features flags

 Documentation/netlink/specs/netdev.yaml       |  72 ++
 drivers/net/ethernet/amazon/ena/ena_netdev.c  |   5 +
 .../net/ethernet/aquantia/atlantic/aq_nic.c   |   4 +
 drivers/net/ethernet/broadcom/bnxt/bnxt.c     |   2 +
 drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |   2 +
 .../net/ethernet/cavium/thunder/nicvf_main.c  |   2 +
 .../net/ethernet/freescale/dpaa/dpaa_eth.c    |   2 +
 .../net/ethernet/freescale/dpaa2/dpaa2-eth.c  |   1 +
 .../net/ethernet/freescale/enetc/enetc_pf.c   |   2 +
 .../ethernet/fungible/funeth/funeth_main.c    |   6 +
 drivers/net/ethernet/intel/i40e/i40e_main.c   |  10 +-
 drivers/net/ethernet/intel/ice/ice_main.c     |   5 +
 drivers/net/ethernet/intel/igb/igb_main.c     |  10 +-
 drivers/net/ethernet/intel/igc/igc_main.c     |   2 +
 drivers/net/ethernet/intel/igc/igc_xdp.c      |   5 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |   5 +
 .../net/ethernet/intel/ixgbevf/ixgbevf_main.c |   1 +
 drivers/net/ethernet/marvell/mvneta.c         |   2 +
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c   |   3 +
 .../ethernet/marvell/octeontx2/nic/otx2_pf.c  |   8 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |   5 +
 .../net/ethernet/mellanox/mlx4/en_netdev.c    |   2 +
 .../net/ethernet/mellanox/mlx5/core/en_main.c |  10 +
 drivers/net/ethernet/microsoft/mana/mana_en.c |   1 +
 .../ethernet/netronome/nfp/nfp_net_common.c   |   5 +
 drivers/net/ethernet/qlogic/qede/qede_main.c  |   2 +
 drivers/net/ethernet/sfc/efx.c                |   3 +
 drivers/net/ethernet/sfc/siena/efx.c          |   3 +
 drivers/net/ethernet/socionext/netsec.c       |   2 +
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |   1 +
 drivers/net/ethernet/ti/cpsw.c                |   2 +
 drivers/net/ethernet/ti/cpsw_new.c            |   3 +
 drivers/net/hyperv/netvsc_drv.c               |   2 +
 drivers/net/netdevsim/netdev.c                |   1 +
 drivers/net/tun.c                             |   4 +
 drivers/net/veth.c                            |   3 +
 drivers/net/virtio_net.c                      |   5 +
 drivers/net/xen-netfront.c                    |   1 +
 include/linux/netdevice.h                     |   2 +
 include/net/xdp.h                             |  34 +
 include/uapi/linux/netdev.h                   |  66 ++
 kernel/bpf/devmap.c                           |  25 +-
 net/core/Makefile                             |   3 +-
 net/core/filter.c                             |  13 +-
 net/core/netdev-genl-gen.c                    |  48 ++
 net/core/netdev-genl-gen.h                    |  23 +
 net/core/netdev-genl.c                        | 178 +++++
 net/xdp/xsk_buff_pool.c                       |   3 +-
 tools/include/uapi/linux/netdev.h             |  66 ++
 tools/lib/bpf/libbpf.h                        |   3 +-
 tools/lib/bpf/netlink.c                       | 121 ++-
 tools/lib/bpf/nlattr.h                        |  12 +
 tools/testing/selftests/bpf/Makefile          |   5 +-
 .../selftests/bpf/progs/test_xdp_features.c   | 237 ++++++
 .../selftests/bpf/test_xdp_features.sh        |  99 +++
 tools/testing/selftests/bpf/xdp_features.c    | 743 ++++++++++++++++++
 56 files changed, 1852 insertions(+), 33 deletions(-)
 create mode 100644 Documentation/netlink/specs/netdev.yaml
 create mode 100644 include/uapi/linux/netdev.h
 create mode 100644 net/core/netdev-genl-gen.c
 create mode 100644 net/core/netdev-genl-gen.h
 create mode 100644 net/core/netdev-genl.c
 create mode 100644 tools/include/uapi/linux/netdev.h
 create mode 100644 tools/testing/selftests/bpf/progs/test_xdp_features.c
 create mode 100755 tools/testing/selftests/bpf/test_xdp_features.sh
 create mode 100644 tools/testing/selftests/bpf/xdp_features.c

-- 
2.39.0

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
  2023-01-20 17:16 ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: netdev, ast, daniel, andrii, davem, kuba, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

From: Jakub Kicinski <kuba@kernel.org>

Add a Netlink spec-compatible family for netdevs.
This is a very simple implementation without much
thought going into it.

It allows us to reap all the benefits of Netlink specs,
one can use the generic client to issue the commands:

  $ ./gen.py --spec netdev.yaml --do dev_get --json='{"ifindex": 2}'
  {'ifindex': 2, 'xdp-features': 31}

  $ ./gen.py --spec netdev.yaml --dump dev_get
  [{'ifindex': 1, 'xdp-features': 0}, {'ifindex': 2, 'xdp-features': 31}]

the generic python library does not have flags-by-name
support, yet, but we also don't have to carry strings
in the messages, as user space can get the names from
the spec.

Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Co-developed-by: Marek Majtyka <alardam@gmail.com>
Signed-off-by: Marek Majtyka <alardam@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 Documentation/netlink/specs/netdev.yaml |  72 ++++++++++
 include/linux/netdevice.h               |   2 +
 include/net/xdp.h                       |   3 +
 include/uapi/linux/netdev.h             |  66 +++++++++
 net/core/Makefile                       |   3 +-
 net/core/netdev-genl-gen.c              |  48 +++++++
 net/core/netdev-genl-gen.h              |  23 +++
 net/core/netdev-genl.c                  | 178 ++++++++++++++++++++++++
 tools/include/uapi/linux/netdev.h       |  66 +++++++++
 9 files changed, 460 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/netlink/specs/netdev.yaml
 create mode 100644 include/uapi/linux/netdev.h
 create mode 100644 net/core/netdev-genl-gen.c
 create mode 100644 net/core/netdev-genl-gen.h
 create mode 100644 net/core/netdev-genl.c
 create mode 100644 tools/include/uapi/linux/netdev.h

diff --git a/Documentation/netlink/specs/netdev.yaml b/Documentation/netlink/specs/netdev.yaml
new file mode 100644
index 000000000000..6445fa5af9d3
--- /dev/null
+++ b/Documentation/netlink/specs/netdev.yaml
@@ -0,0 +1,72 @@
+name: netdev
+
+doc:
+  netdev configuration over generic netlink.
+
+definitions:
+  -
+    type: enum
+    name: xdp-feat
+    entries: [ aborted, drop, pass, redirect,
+               ndo-xmit, xsk-zerocopy,
+               hw-offload, rx-sg, ndo-xmit-sg
+    ]
+
+attribute-sets:
+  -
+    name: dev
+    attributes:
+      -
+        name: ifindex
+        doc: netdev ifindex
+        type: u32
+        value: 1
+        checks:
+          min: 1
+      -
+        name: pad
+        type: pad
+      -
+        name: xdp-features
+        doc: Bitmask of enabled xdp-features.
+        type: u64
+        enum: xdp-feat
+        enum-as-flags: true
+
+operations:
+  list:
+    -
+      name: dev-get
+      doc: Get / dump information about a netdev.
+      value: 1
+      attribute-set: dev
+      do:
+        request:
+          attributes:
+            - ifindex
+        reply: &dev-all
+          attributes:
+            - ifindex
+            - xdp-features
+      dump:
+        reply: *dev-all
+    -
+      name: dev-add-ntf
+      doc: Notification about device appearing.
+      notify: dev-get
+      mcgrp: mgmt
+    -
+      name: dev-del-ntf
+      doc: Notification about device disappearing.
+      notify: dev-get
+      mcgrp: mgmt
+    -
+      name: dev-change-ntf
+      doc: Notification about device configuration being changed.
+      notify: dev-get
+      mcgrp: mgmt
+
+mcast-groups:
+  list:
+    -
+      name: mgmt
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index aad12a179e54..5c2ebc214583 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -47,6 +47,7 @@
 #include <uapi/linux/netdevice.h>
 #include <uapi/linux/if_bonding.h>
 #include <uapi/linux/pkt_cls.h>
+#include <uapi/linux/netdev.h>
 #include <linux/hashtable.h>
 #include <linux/rbtree.h>
 #include <net/net_trackers.h>
@@ -2048,6 +2049,7 @@ struct net_device {
 
 	/* Read-mostly cache-line for fast-path access */
 	unsigned int		flags;
+	xdp_features_t		xdp_features;
 	unsigned long long	priv_flags;
 	const struct net_device_ops *netdev_ops;
 	int			ifindex;
diff --git a/include/net/xdp.h b/include/net/xdp.h
index 55dbc68bfffc..3d37460f0bdb 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -7,6 +7,7 @@
 #define __LINUX_NET_XDP_H__
 
 #include <linux/skbuff.h> /* skb_shared_info */
+#include <uapi/linux/netdev.h>
 
 /**
  * DOC: XDP RX-queue information
@@ -43,6 +44,8 @@ enum xdp_mem_type {
 	MEM_TYPE_MAX,
 };
 
+typedef u32 xdp_features_t;
+
 /* XDP flags for ndo_xdp_xmit */
 #define XDP_XMIT_FLUSH		(1U << 0)	/* doorbell signal consumer */
 #define XDP_XMIT_FLAGS_MASK	XDP_XMIT_FLUSH
diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
new file mode 100644
index 000000000000..254fc336d469
--- /dev/null
+++ b/include/uapi/linux/netdev.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* Do not edit directly, auto-generated from: */
+/*	Documentation/netlink/specs/netdev.yaml */
+/* YNL-GEN uapi header */
+
+#ifndef _UAPI_LINUX_NETDEV_H
+#define _UAPI_LINUX_NETDEV_H
+
+#define NETDEV_FAMILY_NAME	"netdev"
+#define NETDEV_FAMILY_VERSION	1
+
+enum netdev_xdp_act {
+	NETDEV_XDP_ACT_ABORTED_BIT,
+	NETDEV_XDP_ACT_DROP_BIT,
+	NETDEV_XDP_ACT_PASS_BIT,
+	NETDEV_XDP_ACT_TX_BIT,
+	NETDEV_XDP_ACT_REDIRECT_BIT,
+	NETDEV_XDP_ACT_NDO_XMIT_BIT,
+	NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT,
+	NETDEV_XDP_ACT_HW_OFFLOAD_BIT,
+	NETDEV_XDP_ACT_RX_SG_BIT,
+	NETDEV_XDP_ACT_NDO_XMIT_SG_BIT
+};
+
+#define NETDEV_XDP_ACT_ABORTED		BIT(NETDEV_XDP_ACT_ABORTED_BIT)
+#define NETDEV_XDP_ACT_DROP		BIT(NETDEV_XDP_ACT_DROP_BIT)
+#define NETDEV_XDP_ACT_PASS		BIT(NETDEV_XDP_ACT_PASS_BIT)
+#define NETDEV_XDP_ACT_TX		BIT(NETDEV_XDP_ACT_TX_BIT)
+#define NETDEV_XDP_ACT_REDIRECT		BIT(NETDEV_XDP_ACT_REDIRECT_BIT)
+#define NETDEV_XDP_ACT_NDO_XMIT		BIT(NETDEV_XDP_ACT_NDO_XMIT_BIT)
+#define NETDEV_XDP_ACT_XSK_ZEROCOPY	BIT(NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT)
+#define NETDEV_XDP_ACT_HW_OFFLOAD	BIT(NETDEV_XDP_ACT_HW_OFFLOAD_BIT)
+#define NETDEV_XDP_ACT_RX_SG		BIT(NETDEV_XDP_ACT_RX_SG_BIT)
+#define NETDEV_XDP_ACT_NDO_XMIT_SG	BIT(NETDEV_XDP_ACT_NDO_XMIT_SG_BIT)
+
+#define NETDEV_XDP_ACT_BASIC		(NETDEV_XDP_ACT_DROP |	\
+					 NETDEV_XDP_ACT_PASS |	\
+					 NETDEV_XDP_ACT_TX |	\
+					 NETDEV_XDP_ACT_ABORTED)
+#define NETDEV_XDP_ACT_FULL		(NETDEV_XDP_ACT_BASIC |	\
+					 NETDEV_XDP_ACT_REDIRECT)
+#define NETDEV_XDP_ACT_ZC		(NETDEV_XDP_ACT_FULL |	\
+					 NETDEV_XDP_ACT_XSK_ZEROCOPY)
+
+enum {
+	NETDEV_A_DEV_IFINDEX = 1,
+	NETDEV_A_DEV_PAD,
+	NETDEV_A_DEV_XDP_FEATURES,
+
+	__NETDEV_A_DEV_MAX,
+	NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
+};
+
+enum {
+	NETDEV_CMD_DEV_GET = 1,
+	NETDEV_CMD_DEV_ADD_NTF,
+	NETDEV_CMD_DEV_DEL_NTF,
+	NETDEV_CMD_DEV_CHANGE_NTF,
+
+	__NETDEV_CMD_MAX,
+	NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
+};
+
+#define NETDEV_MCGRP_MGMT	"mgmt"
+
+#endif /* _UAPI_LINUX_NETDEV_H */
diff --git a/net/core/Makefile b/net/core/Makefile
index 10edd66a8a37..8f367813bc68 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -12,7 +12,8 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
 obj-y		     += dev.o dev_addr_lists.o dst.o netevent.o \
 			neighbour.o rtnetlink.o utils.o link_watch.o filter.o \
 			sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \
-			fib_notifier.o xdp.o flow_offload.o gro.o
+			fib_notifier.o xdp.o flow_offload.o gro.o \
+			netdev-genl.o netdev-genl-gen.o
 
 obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o
 
diff --git a/net/core/netdev-genl-gen.c b/net/core/netdev-genl-gen.c
new file mode 100644
index 000000000000..affb427c3b89
--- /dev/null
+++ b/net/core/netdev-genl-gen.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/* Do not edit directly, auto-generated from: */
+/*	Documentation/netlink/specs/netdev.yaml */
+/* YNL-GEN kernel source */
+
+#include <net/netlink.h>
+#include <net/genetlink.h>
+
+#include "netdev-genl-gen.h"
+
+#include <linux/netdev.h>
+
+// NETDEV_CMD_DEV_GET - do
+static const struct nla_policy netdev_dev_get_nl_policy[NETDEV_A_DEV_IFINDEX + 1] = {
+	[NETDEV_A_DEV_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
+};
+
+// Ops table for netdev
+static const struct genl_split_ops netdev_nl_ops[2] = {
+	{
+		.cmd		= NETDEV_CMD_DEV_GET,
+		.doit		= netdev_nl_dev_get_doit,
+		.policy		= netdev_dev_get_nl_policy,
+		.maxattr	= NETDEV_A_DEV_IFINDEX,
+		.flags		= GENL_CMD_CAP_DO,
+	},
+	{
+		.cmd	= NETDEV_CMD_DEV_GET,
+		.dumpit	= netdev_nl_dev_get_dumpit,
+		.flags	= GENL_CMD_CAP_DUMP,
+	},
+};
+
+static const struct genl_multicast_group netdev_nl_mcgrps[] = {
+	[NETDEV_NLGRP_MGMT] = { "mgmt", },
+};
+
+struct genl_family netdev_nl_family __ro_after_init = {
+	.name		= NETDEV_FAMILY_NAME,
+	.version	= NETDEV_FAMILY_VERSION,
+	.netnsok	= true,
+	.parallel_ops	= true,
+	.module		= THIS_MODULE,
+	.split_ops	= netdev_nl_ops,
+	.n_split_ops	= ARRAY_SIZE(netdev_nl_ops),
+	.mcgrps		= netdev_nl_mcgrps,
+	.n_mcgrps	= ARRAY_SIZE(netdev_nl_mcgrps),
+};
diff --git a/net/core/netdev-genl-gen.h b/net/core/netdev-genl-gen.h
new file mode 100644
index 000000000000..8bdbe61e9d74
--- /dev/null
+++ b/net/core/netdev-genl-gen.h
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/* Do not edit directly, auto-generated from: */
+/*	Documentation/netlink/specs/netdev.yaml */
+/* YNL-GEN kernel header */
+
+#ifndef _LINUX_NETDEV_GEN_H
+#define _LINUX_NETDEV_GEN_H
+
+#include <net/netlink.h>
+#include <net/genetlink.h>
+
+#include <linux/netdev.h>
+
+int netdev_nl_dev_get_doit(struct sk_buff *skb, struct genl_info *info);
+int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
+
+enum {
+	NETDEV_NLGRP_MGMT,
+};
+
+extern struct genl_family netdev_nl_family;
+
+#endif /* _LINUX_NETDEV_GEN_H */
diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
new file mode 100644
index 000000000000..ad1751adb3c6
--- /dev/null
+++ b/net/core/netdev-genl.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/netdevice.h>
+#include <linux/notifier.h>
+#include <linux/rtnetlink.h>
+#include <net/net_namespace.h>
+#include <net/sock.h>
+
+#include "netdev-genl-gen.h"
+
+static int
+netdev_nl_dev_fill(struct net_device *netdev, struct sk_buff *rsp,
+		   u32 portid, u32 seq, int flags, u32 cmd)
+{
+	void *hdr;
+	int err;
+
+	hdr = genlmsg_put(rsp, portid, seq, &netdev_nl_family, flags, cmd);
+	if (!hdr)
+		return -EMSGSIZE;
+
+	if (nla_put_u32(rsp, NETDEV_A_DEV_IFINDEX, netdev->ifindex) ||
+	    nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_FEATURES,
+			      netdev->xdp_features, NETDEV_A_DEV_PAD)) {
+		genlmsg_cancel(rsp, hdr);
+		return -EINVAL;
+	}
+
+	genlmsg_end(rsp, hdr);
+
+	return 0;
+}
+
+static void
+netdev_genl_dev_notify(struct net_device *netdev, int cmd)
+{
+	struct sk_buff *ntf;
+
+	if (!genl_has_listeners(&netdev_nl_family, dev_net(netdev),
+				NETDEV_NLGRP_MGMT))
+		return;
+
+	ntf = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!ntf)
+		return;
+
+	if (netdev_nl_dev_fill(netdev, ntf, 0, 0, 0, cmd)) {
+		nlmsg_free(ntf);
+		return;
+	}
+
+	genlmsg_multicast_netns(&netdev_nl_family, dev_net(netdev), ntf,
+				0, NETDEV_NLGRP_MGMT, GFP_KERNEL);
+}
+
+int netdev_nl_dev_get_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	struct net_device *netdev;
+	struct sk_buff *rsp;
+	u32 ifindex;
+	int err;
+
+	if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_DEV_IFINDEX))
+		return -EINVAL;
+
+	ifindex = nla_get_u32(info->attrs[NETDEV_A_DEV_IFINDEX]);
+
+	rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!rsp)
+		return -ENOMEM;
+
+	rtnl_lock();
+
+	netdev = __dev_get_by_index(genl_info_net(info), ifindex);
+	if (netdev)
+		err = netdev_nl_dev_fill(netdev, rsp, info->snd_portid,
+					 info->snd_seq, 0, info->genlhdr->cmd);
+	else
+		err = -ENODEV;
+
+	rtnl_unlock();
+
+	if (err)
+		goto err_free_msg;
+
+	return genlmsg_reply(rsp, info);
+
+err_free_msg:
+	nlmsg_free(rsp);
+	return err;
+}
+
+int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct net *net = sock_net(skb->sk);
+	struct net_device *netdev;
+	int idx = 0, s_idx;
+	int h, s_h;
+	int err;
+
+	s_h = cb->args[0];
+	s_idx = cb->args[1];
+
+	rtnl_lock();
+
+	for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
+		struct hlist_head *head;
+
+		idx = 0;
+		head = &net->dev_index_head[h];
+		hlist_for_each_entry(netdev, head, index_hlist) {
+			if (idx < s_idx)
+				goto cont;
+			err = netdev_nl_dev_fill(netdev, skb,
+						 NETLINK_CB(cb->skb).portid,
+						 cb->nlh->nlmsg_seq, 0,
+						 NETDEV_CMD_DEV_GET);
+			if (err < 0)
+				break;
+cont:
+			idx++;
+		}
+	}
+
+	rtnl_unlock();
+
+	if (err != -EMSGSIZE)
+		return err;
+
+	cb->args[1] = idx;
+	cb->args[0] = h;
+	cb->seq = net->dev_base_seq;
+	nl_dump_check_consistent(cb, nlmsg_hdr(skb));
+
+	return skb->len;
+}
+
+static int netdev_genl_netdevice_event(struct notifier_block *nb,
+				       unsigned long event, void *ptr)
+{
+	struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
+
+	switch (event) {
+	case NETDEV_REGISTER:
+		netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_ADD_NTF);
+		break;
+	case NETDEV_UNREGISTER:
+		netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_DEL_NTF);
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block netdev_genl_nb = {
+	.notifier_call	= netdev_genl_netdevice_event,
+};
+
+static int __init netdev_genl_init(void)
+{
+	int err;
+
+	err = register_netdevice_notifier(&netdev_genl_nb);
+	if (err)
+		return err;
+
+	err = genl_register_family(&netdev_nl_family);
+	if (err)
+		goto err_unreg_ntf;
+
+	return 0;
+
+err_unreg_ntf:
+	unregister_netdevice_notifier(&netdev_genl_nb);
+	return err;
+}
+
+subsys_initcall(netdev_genl_init);
diff --git a/tools/include/uapi/linux/netdev.h b/tools/include/uapi/linux/netdev.h
new file mode 100644
index 000000000000..254fc336d469
--- /dev/null
+++ b/tools/include/uapi/linux/netdev.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* Do not edit directly, auto-generated from: */
+/*	Documentation/netlink/specs/netdev.yaml */
+/* YNL-GEN uapi header */
+
+#ifndef _UAPI_LINUX_NETDEV_H
+#define _UAPI_LINUX_NETDEV_H
+
+#define NETDEV_FAMILY_NAME	"netdev"
+#define NETDEV_FAMILY_VERSION	1
+
+enum netdev_xdp_act {
+	NETDEV_XDP_ACT_ABORTED_BIT,
+	NETDEV_XDP_ACT_DROP_BIT,
+	NETDEV_XDP_ACT_PASS_BIT,
+	NETDEV_XDP_ACT_TX_BIT,
+	NETDEV_XDP_ACT_REDIRECT_BIT,
+	NETDEV_XDP_ACT_NDO_XMIT_BIT,
+	NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT,
+	NETDEV_XDP_ACT_HW_OFFLOAD_BIT,
+	NETDEV_XDP_ACT_RX_SG_BIT,
+	NETDEV_XDP_ACT_NDO_XMIT_SG_BIT
+};
+
+#define NETDEV_XDP_ACT_ABORTED		BIT(NETDEV_XDP_ACT_ABORTED_BIT)
+#define NETDEV_XDP_ACT_DROP		BIT(NETDEV_XDP_ACT_DROP_BIT)
+#define NETDEV_XDP_ACT_PASS		BIT(NETDEV_XDP_ACT_PASS_BIT)
+#define NETDEV_XDP_ACT_TX		BIT(NETDEV_XDP_ACT_TX_BIT)
+#define NETDEV_XDP_ACT_REDIRECT		BIT(NETDEV_XDP_ACT_REDIRECT_BIT)
+#define NETDEV_XDP_ACT_NDO_XMIT		BIT(NETDEV_XDP_ACT_NDO_XMIT_BIT)
+#define NETDEV_XDP_ACT_XSK_ZEROCOPY	BIT(NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT)
+#define NETDEV_XDP_ACT_HW_OFFLOAD	BIT(NETDEV_XDP_ACT_HW_OFFLOAD_BIT)
+#define NETDEV_XDP_ACT_RX_SG		BIT(NETDEV_XDP_ACT_RX_SG_BIT)
+#define NETDEV_XDP_ACT_NDO_XMIT_SG	BIT(NETDEV_XDP_ACT_NDO_XMIT_SG_BIT)
+
+#define NETDEV_XDP_ACT_BASIC		(NETDEV_XDP_ACT_DROP |	\
+					 NETDEV_XDP_ACT_PASS |	\
+					 NETDEV_XDP_ACT_TX |	\
+					 NETDEV_XDP_ACT_ABORTED)
+#define NETDEV_XDP_ACT_FULL		(NETDEV_XDP_ACT_BASIC |	\
+					 NETDEV_XDP_ACT_REDIRECT)
+#define NETDEV_XDP_ACT_ZC		(NETDEV_XDP_ACT_FULL |	\
+					 NETDEV_XDP_ACT_XSK_ZEROCOPY)
+
+enum {
+	NETDEV_A_DEV_IFINDEX = 1,
+	NETDEV_A_DEV_PAD,
+	NETDEV_A_DEV_XDP_FEATURES,
+
+	__NETDEV_A_DEV_MAX,
+	NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
+};
+
+enum {
+	NETDEV_CMD_DEV_GET = 1,
+	NETDEV_CMD_DEV_ADD_NTF,
+	NETDEV_CMD_DEV_DEL_NTF,
+	NETDEV_CMD_DEV_CHANGE_NTF,
+
+	__NETDEV_CMD_MAX,
+	NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
+};
+
+#define NETDEV_MCGRP_MGMT	"mgmt"
+
+#endif /* _UAPI_LINUX_NETDEV_H */
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-wired-lan] [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, kuba,
	pabeni, aelior, hawk, christophe.jaillet, memxor, john, bjorn,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

From: Jakub Kicinski <kuba@kernel.org>

Add a Netlink spec-compatible family for netdevs.
This is a very simple implementation without much
thought going into it.

It allows us to reap all the benefits of Netlink specs,
one can use the generic client to issue the commands:

  $ ./gen.py --spec netdev.yaml --do dev_get --json='{"ifindex": 2}'
  {'ifindex': 2, 'xdp-features': 31}

  $ ./gen.py --spec netdev.yaml --dump dev_get
  [{'ifindex': 1, 'xdp-features': 0}, {'ifindex': 2, 'xdp-features': 31}]

the generic python library does not have flags-by-name
support, yet, but we also don't have to carry strings
in the messages, as user space can get the names from
the spec.

Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Co-developed-by: Marek Majtyka <alardam@gmail.com>
Signed-off-by: Marek Majtyka <alardam@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 Documentation/netlink/specs/netdev.yaml |  72 ++++++++++
 include/linux/netdevice.h               |   2 +
 include/net/xdp.h                       |   3 +
 include/uapi/linux/netdev.h             |  66 +++++++++
 net/core/Makefile                       |   3 +-
 net/core/netdev-genl-gen.c              |  48 +++++++
 net/core/netdev-genl-gen.h              |  23 +++
 net/core/netdev-genl.c                  | 178 ++++++++++++++++++++++++
 tools/include/uapi/linux/netdev.h       |  66 +++++++++
 9 files changed, 460 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/netlink/specs/netdev.yaml
 create mode 100644 include/uapi/linux/netdev.h
 create mode 100644 net/core/netdev-genl-gen.c
 create mode 100644 net/core/netdev-genl-gen.h
 create mode 100644 net/core/netdev-genl.c
 create mode 100644 tools/include/uapi/linux/netdev.h

diff --git a/Documentation/netlink/specs/netdev.yaml b/Documentation/netlink/specs/netdev.yaml
new file mode 100644
index 000000000000..6445fa5af9d3
--- /dev/null
+++ b/Documentation/netlink/specs/netdev.yaml
@@ -0,0 +1,72 @@
+name: netdev
+
+doc:
+  netdev configuration over generic netlink.
+
+definitions:
+  -
+    type: enum
+    name: xdp-feat
+    entries: [ aborted, drop, pass, redirect,
+               ndo-xmit, xsk-zerocopy,
+               hw-offload, rx-sg, ndo-xmit-sg
+    ]
+
+attribute-sets:
+  -
+    name: dev
+    attributes:
+      -
+        name: ifindex
+        doc: netdev ifindex
+        type: u32
+        value: 1
+        checks:
+          min: 1
+      -
+        name: pad
+        type: pad
+      -
+        name: xdp-features
+        doc: Bitmask of enabled xdp-features.
+        type: u64
+        enum: xdp-feat
+        enum-as-flags: true
+
+operations:
+  list:
+    -
+      name: dev-get
+      doc: Get / dump information about a netdev.
+      value: 1
+      attribute-set: dev
+      do:
+        request:
+          attributes:
+            - ifindex
+        reply: &dev-all
+          attributes:
+            - ifindex
+            - xdp-features
+      dump:
+        reply: *dev-all
+    -
+      name: dev-add-ntf
+      doc: Notification about device appearing.
+      notify: dev-get
+      mcgrp: mgmt
+    -
+      name: dev-del-ntf
+      doc: Notification about device disappearing.
+      notify: dev-get
+      mcgrp: mgmt
+    -
+      name: dev-change-ntf
+      doc: Notification about device configuration being changed.
+      notify: dev-get
+      mcgrp: mgmt
+
+mcast-groups:
+  list:
+    -
+      name: mgmt
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index aad12a179e54..5c2ebc214583 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -47,6 +47,7 @@
 #include <uapi/linux/netdevice.h>
 #include <uapi/linux/if_bonding.h>
 #include <uapi/linux/pkt_cls.h>
+#include <uapi/linux/netdev.h>
 #include <linux/hashtable.h>
 #include <linux/rbtree.h>
 #include <net/net_trackers.h>
@@ -2048,6 +2049,7 @@ struct net_device {
 
 	/* Read-mostly cache-line for fast-path access */
 	unsigned int		flags;
+	xdp_features_t		xdp_features;
 	unsigned long long	priv_flags;
 	const struct net_device_ops *netdev_ops;
 	int			ifindex;
diff --git a/include/net/xdp.h b/include/net/xdp.h
index 55dbc68bfffc..3d37460f0bdb 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -7,6 +7,7 @@
 #define __LINUX_NET_XDP_H__
 
 #include <linux/skbuff.h> /* skb_shared_info */
+#include <uapi/linux/netdev.h>
 
 /**
  * DOC: XDP RX-queue information
@@ -43,6 +44,8 @@ enum xdp_mem_type {
 	MEM_TYPE_MAX,
 };
 
+typedef u32 xdp_features_t;
+
 /* XDP flags for ndo_xdp_xmit */
 #define XDP_XMIT_FLUSH		(1U << 0)	/* doorbell signal consumer */
 #define XDP_XMIT_FLAGS_MASK	XDP_XMIT_FLUSH
diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
new file mode 100644
index 000000000000..254fc336d469
--- /dev/null
+++ b/include/uapi/linux/netdev.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* Do not edit directly, auto-generated from: */
+/*	Documentation/netlink/specs/netdev.yaml */
+/* YNL-GEN uapi header */
+
+#ifndef _UAPI_LINUX_NETDEV_H
+#define _UAPI_LINUX_NETDEV_H
+
+#define NETDEV_FAMILY_NAME	"netdev"
+#define NETDEV_FAMILY_VERSION	1
+
+enum netdev_xdp_act {
+	NETDEV_XDP_ACT_ABORTED_BIT,
+	NETDEV_XDP_ACT_DROP_BIT,
+	NETDEV_XDP_ACT_PASS_BIT,
+	NETDEV_XDP_ACT_TX_BIT,
+	NETDEV_XDP_ACT_REDIRECT_BIT,
+	NETDEV_XDP_ACT_NDO_XMIT_BIT,
+	NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT,
+	NETDEV_XDP_ACT_HW_OFFLOAD_BIT,
+	NETDEV_XDP_ACT_RX_SG_BIT,
+	NETDEV_XDP_ACT_NDO_XMIT_SG_BIT
+};
+
+#define NETDEV_XDP_ACT_ABORTED		BIT(NETDEV_XDP_ACT_ABORTED_BIT)
+#define NETDEV_XDP_ACT_DROP		BIT(NETDEV_XDP_ACT_DROP_BIT)
+#define NETDEV_XDP_ACT_PASS		BIT(NETDEV_XDP_ACT_PASS_BIT)
+#define NETDEV_XDP_ACT_TX		BIT(NETDEV_XDP_ACT_TX_BIT)
+#define NETDEV_XDP_ACT_REDIRECT		BIT(NETDEV_XDP_ACT_REDIRECT_BIT)
+#define NETDEV_XDP_ACT_NDO_XMIT		BIT(NETDEV_XDP_ACT_NDO_XMIT_BIT)
+#define NETDEV_XDP_ACT_XSK_ZEROCOPY	BIT(NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT)
+#define NETDEV_XDP_ACT_HW_OFFLOAD	BIT(NETDEV_XDP_ACT_HW_OFFLOAD_BIT)
+#define NETDEV_XDP_ACT_RX_SG		BIT(NETDEV_XDP_ACT_RX_SG_BIT)
+#define NETDEV_XDP_ACT_NDO_XMIT_SG	BIT(NETDEV_XDP_ACT_NDO_XMIT_SG_BIT)
+
+#define NETDEV_XDP_ACT_BASIC		(NETDEV_XDP_ACT_DROP |	\
+					 NETDEV_XDP_ACT_PASS |	\
+					 NETDEV_XDP_ACT_TX |	\
+					 NETDEV_XDP_ACT_ABORTED)
+#define NETDEV_XDP_ACT_FULL		(NETDEV_XDP_ACT_BASIC |	\
+					 NETDEV_XDP_ACT_REDIRECT)
+#define NETDEV_XDP_ACT_ZC		(NETDEV_XDP_ACT_FULL |	\
+					 NETDEV_XDP_ACT_XSK_ZEROCOPY)
+
+enum {
+	NETDEV_A_DEV_IFINDEX = 1,
+	NETDEV_A_DEV_PAD,
+	NETDEV_A_DEV_XDP_FEATURES,
+
+	__NETDEV_A_DEV_MAX,
+	NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
+};
+
+enum {
+	NETDEV_CMD_DEV_GET = 1,
+	NETDEV_CMD_DEV_ADD_NTF,
+	NETDEV_CMD_DEV_DEL_NTF,
+	NETDEV_CMD_DEV_CHANGE_NTF,
+
+	__NETDEV_CMD_MAX,
+	NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
+};
+
+#define NETDEV_MCGRP_MGMT	"mgmt"
+
+#endif /* _UAPI_LINUX_NETDEV_H */
diff --git a/net/core/Makefile b/net/core/Makefile
index 10edd66a8a37..8f367813bc68 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -12,7 +12,8 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
 obj-y		     += dev.o dev_addr_lists.o dst.o netevent.o \
 			neighbour.o rtnetlink.o utils.o link_watch.o filter.o \
 			sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \
-			fib_notifier.o xdp.o flow_offload.o gro.o
+			fib_notifier.o xdp.o flow_offload.o gro.o \
+			netdev-genl.o netdev-genl-gen.o
 
 obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o
 
diff --git a/net/core/netdev-genl-gen.c b/net/core/netdev-genl-gen.c
new file mode 100644
index 000000000000..affb427c3b89
--- /dev/null
+++ b/net/core/netdev-genl-gen.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/* Do not edit directly, auto-generated from: */
+/*	Documentation/netlink/specs/netdev.yaml */
+/* YNL-GEN kernel source */
+
+#include <net/netlink.h>
+#include <net/genetlink.h>
+
+#include "netdev-genl-gen.h"
+
+#include <linux/netdev.h>
+
+// NETDEV_CMD_DEV_GET - do
+static const struct nla_policy netdev_dev_get_nl_policy[NETDEV_A_DEV_IFINDEX + 1] = {
+	[NETDEV_A_DEV_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
+};
+
+// Ops table for netdev
+static const struct genl_split_ops netdev_nl_ops[2] = {
+	{
+		.cmd		= NETDEV_CMD_DEV_GET,
+		.doit		= netdev_nl_dev_get_doit,
+		.policy		= netdev_dev_get_nl_policy,
+		.maxattr	= NETDEV_A_DEV_IFINDEX,
+		.flags		= GENL_CMD_CAP_DO,
+	},
+	{
+		.cmd	= NETDEV_CMD_DEV_GET,
+		.dumpit	= netdev_nl_dev_get_dumpit,
+		.flags	= GENL_CMD_CAP_DUMP,
+	},
+};
+
+static const struct genl_multicast_group netdev_nl_mcgrps[] = {
+	[NETDEV_NLGRP_MGMT] = { "mgmt", },
+};
+
+struct genl_family netdev_nl_family __ro_after_init = {
+	.name		= NETDEV_FAMILY_NAME,
+	.version	= NETDEV_FAMILY_VERSION,
+	.netnsok	= true,
+	.parallel_ops	= true,
+	.module		= THIS_MODULE,
+	.split_ops	= netdev_nl_ops,
+	.n_split_ops	= ARRAY_SIZE(netdev_nl_ops),
+	.mcgrps		= netdev_nl_mcgrps,
+	.n_mcgrps	= ARRAY_SIZE(netdev_nl_mcgrps),
+};
diff --git a/net/core/netdev-genl-gen.h b/net/core/netdev-genl-gen.h
new file mode 100644
index 000000000000..8bdbe61e9d74
--- /dev/null
+++ b/net/core/netdev-genl-gen.h
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/* Do not edit directly, auto-generated from: */
+/*	Documentation/netlink/specs/netdev.yaml */
+/* YNL-GEN kernel header */
+
+#ifndef _LINUX_NETDEV_GEN_H
+#define _LINUX_NETDEV_GEN_H
+
+#include <net/netlink.h>
+#include <net/genetlink.h>
+
+#include <linux/netdev.h>
+
+int netdev_nl_dev_get_doit(struct sk_buff *skb, struct genl_info *info);
+int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
+
+enum {
+	NETDEV_NLGRP_MGMT,
+};
+
+extern struct genl_family netdev_nl_family;
+
+#endif /* _LINUX_NETDEV_GEN_H */
diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
new file mode 100644
index 000000000000..ad1751adb3c6
--- /dev/null
+++ b/net/core/netdev-genl.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/netdevice.h>
+#include <linux/notifier.h>
+#include <linux/rtnetlink.h>
+#include <net/net_namespace.h>
+#include <net/sock.h>
+
+#include "netdev-genl-gen.h"
+
+static int
+netdev_nl_dev_fill(struct net_device *netdev, struct sk_buff *rsp,
+		   u32 portid, u32 seq, int flags, u32 cmd)
+{
+	void *hdr;
+	int err;
+
+	hdr = genlmsg_put(rsp, portid, seq, &netdev_nl_family, flags, cmd);
+	if (!hdr)
+		return -EMSGSIZE;
+
+	if (nla_put_u32(rsp, NETDEV_A_DEV_IFINDEX, netdev->ifindex) ||
+	    nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_FEATURES,
+			      netdev->xdp_features, NETDEV_A_DEV_PAD)) {
+		genlmsg_cancel(rsp, hdr);
+		return -EINVAL;
+	}
+
+	genlmsg_end(rsp, hdr);
+
+	return 0;
+}
+
+static void
+netdev_genl_dev_notify(struct net_device *netdev, int cmd)
+{
+	struct sk_buff *ntf;
+
+	if (!genl_has_listeners(&netdev_nl_family, dev_net(netdev),
+				NETDEV_NLGRP_MGMT))
+		return;
+
+	ntf = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!ntf)
+		return;
+
+	if (netdev_nl_dev_fill(netdev, ntf, 0, 0, 0, cmd)) {
+		nlmsg_free(ntf);
+		return;
+	}
+
+	genlmsg_multicast_netns(&netdev_nl_family, dev_net(netdev), ntf,
+				0, NETDEV_NLGRP_MGMT, GFP_KERNEL);
+}
+
+int netdev_nl_dev_get_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	struct net_device *netdev;
+	struct sk_buff *rsp;
+	u32 ifindex;
+	int err;
+
+	if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_DEV_IFINDEX))
+		return -EINVAL;
+
+	ifindex = nla_get_u32(info->attrs[NETDEV_A_DEV_IFINDEX]);
+
+	rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!rsp)
+		return -ENOMEM;
+
+	rtnl_lock();
+
+	netdev = __dev_get_by_index(genl_info_net(info), ifindex);
+	if (netdev)
+		err = netdev_nl_dev_fill(netdev, rsp, info->snd_portid,
+					 info->snd_seq, 0, info->genlhdr->cmd);
+	else
+		err = -ENODEV;
+
+	rtnl_unlock();
+
+	if (err)
+		goto err_free_msg;
+
+	return genlmsg_reply(rsp, info);
+
+err_free_msg:
+	nlmsg_free(rsp);
+	return err;
+}
+
+int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct net *net = sock_net(skb->sk);
+	struct net_device *netdev;
+	int idx = 0, s_idx;
+	int h, s_h;
+	int err;
+
+	s_h = cb->args[0];
+	s_idx = cb->args[1];
+
+	rtnl_lock();
+
+	for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
+		struct hlist_head *head;
+
+		idx = 0;
+		head = &net->dev_index_head[h];
+		hlist_for_each_entry(netdev, head, index_hlist) {
+			if (idx < s_idx)
+				goto cont;
+			err = netdev_nl_dev_fill(netdev, skb,
+						 NETLINK_CB(cb->skb).portid,
+						 cb->nlh->nlmsg_seq, 0,
+						 NETDEV_CMD_DEV_GET);
+			if (err < 0)
+				break;
+cont:
+			idx++;
+		}
+	}
+
+	rtnl_unlock();
+
+	if (err != -EMSGSIZE)
+		return err;
+
+	cb->args[1] = idx;
+	cb->args[0] = h;
+	cb->seq = net->dev_base_seq;
+	nl_dump_check_consistent(cb, nlmsg_hdr(skb));
+
+	return skb->len;
+}
+
+static int netdev_genl_netdevice_event(struct notifier_block *nb,
+				       unsigned long event, void *ptr)
+{
+	struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
+
+	switch (event) {
+	case NETDEV_REGISTER:
+		netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_ADD_NTF);
+		break;
+	case NETDEV_UNREGISTER:
+		netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_DEL_NTF);
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block netdev_genl_nb = {
+	.notifier_call	= netdev_genl_netdevice_event,
+};
+
+static int __init netdev_genl_init(void)
+{
+	int err;
+
+	err = register_netdevice_notifier(&netdev_genl_nb);
+	if (err)
+		return err;
+
+	err = genl_register_family(&netdev_nl_family);
+	if (err)
+		goto err_unreg_ntf;
+
+	return 0;
+
+err_unreg_ntf:
+	unregister_netdevice_notifier(&netdev_genl_nb);
+	return err;
+}
+
+subsys_initcall(netdev_genl_init);
diff --git a/tools/include/uapi/linux/netdev.h b/tools/include/uapi/linux/netdev.h
new file mode 100644
index 000000000000..254fc336d469
--- /dev/null
+++ b/tools/include/uapi/linux/netdev.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* Do not edit directly, auto-generated from: */
+/*	Documentation/netlink/specs/netdev.yaml */
+/* YNL-GEN uapi header */
+
+#ifndef _UAPI_LINUX_NETDEV_H
+#define _UAPI_LINUX_NETDEV_H
+
+#define NETDEV_FAMILY_NAME	"netdev"
+#define NETDEV_FAMILY_VERSION	1
+
+enum netdev_xdp_act {
+	NETDEV_XDP_ACT_ABORTED_BIT,
+	NETDEV_XDP_ACT_DROP_BIT,
+	NETDEV_XDP_ACT_PASS_BIT,
+	NETDEV_XDP_ACT_TX_BIT,
+	NETDEV_XDP_ACT_REDIRECT_BIT,
+	NETDEV_XDP_ACT_NDO_XMIT_BIT,
+	NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT,
+	NETDEV_XDP_ACT_HW_OFFLOAD_BIT,
+	NETDEV_XDP_ACT_RX_SG_BIT,
+	NETDEV_XDP_ACT_NDO_XMIT_SG_BIT
+};
+
+#define NETDEV_XDP_ACT_ABORTED		BIT(NETDEV_XDP_ACT_ABORTED_BIT)
+#define NETDEV_XDP_ACT_DROP		BIT(NETDEV_XDP_ACT_DROP_BIT)
+#define NETDEV_XDP_ACT_PASS		BIT(NETDEV_XDP_ACT_PASS_BIT)
+#define NETDEV_XDP_ACT_TX		BIT(NETDEV_XDP_ACT_TX_BIT)
+#define NETDEV_XDP_ACT_REDIRECT		BIT(NETDEV_XDP_ACT_REDIRECT_BIT)
+#define NETDEV_XDP_ACT_NDO_XMIT		BIT(NETDEV_XDP_ACT_NDO_XMIT_BIT)
+#define NETDEV_XDP_ACT_XSK_ZEROCOPY	BIT(NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT)
+#define NETDEV_XDP_ACT_HW_OFFLOAD	BIT(NETDEV_XDP_ACT_HW_OFFLOAD_BIT)
+#define NETDEV_XDP_ACT_RX_SG		BIT(NETDEV_XDP_ACT_RX_SG_BIT)
+#define NETDEV_XDP_ACT_NDO_XMIT_SG	BIT(NETDEV_XDP_ACT_NDO_XMIT_SG_BIT)
+
+#define NETDEV_XDP_ACT_BASIC		(NETDEV_XDP_ACT_DROP |	\
+					 NETDEV_XDP_ACT_PASS |	\
+					 NETDEV_XDP_ACT_TX |	\
+					 NETDEV_XDP_ACT_ABORTED)
+#define NETDEV_XDP_ACT_FULL		(NETDEV_XDP_ACT_BASIC |	\
+					 NETDEV_XDP_ACT_REDIRECT)
+#define NETDEV_XDP_ACT_ZC		(NETDEV_XDP_ACT_FULL |	\
+					 NETDEV_XDP_ACT_XSK_ZEROCOPY)
+
+enum {
+	NETDEV_A_DEV_IFINDEX = 1,
+	NETDEV_A_DEV_PAD,
+	NETDEV_A_DEV_XDP_FEATURES,
+
+	__NETDEV_A_DEV_MAX,
+	NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
+};
+
+enum {
+	NETDEV_CMD_DEV_GET = 1,
+	NETDEV_CMD_DEV_ADD_NTF,
+	NETDEV_CMD_DEV_DEL_NTF,
+	NETDEV_CMD_DEV_CHANGE_NTF,
+
+	__NETDEV_CMD_MAX,
+	NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
+};
+
+#define NETDEV_MCGRP_MGMT	"mgmt"
+
+#endif /* _UAPI_LINUX_NETDEV_H */
-- 
2.39.0

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH bpf-next 2/7] drivers: net: turn on XDP features
  2023-01-20 17:16 ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: netdev, ast, daniel, andrii, davem, kuba, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

From: Marek Majtyka <alardam@gmail.com>

A summary of the flags being set for various drivers is given below.
Note that XDP_F_REDIRECT_TARGET and XDP_F_FRAG_TARGET are features
that can be turned off and on at runtime. This means that these flags
may be set and unset under RTNL lock protection by the driver. Hence,
READ_ONCE must be used by code loading the flag value.

Also, these flags are not used for synchronization against the availability
of XDP resources on a device. It is merely a hint, and hence the read
may race with the actual teardown of XDP resources on the device. This
may change in the future, e.g. operations taking a reference on the XDP
resources of the driver, and in turn inhibiting turning off this flag.
However, for now, it can only be used as a hint to check whether device
supports becoming a redirection target.

Turn 'hw-offload' feature flag on for:
 - netronome (nfp)
 - netdevsim.

Turn 'native' and 'zerocopy' features flags on for:
 - intel (i40e, ice, ixgbe, igc)
 - mellanox (mlx5).
 - stmmac

Turn 'native' features flags on for:
 - amazon (ena)
 - broadcom (bnxt)
 - freescale (dpaa, dpaa2, enetc)
 - funeth
 - intel (igb)
 - marvell (mvneta, mvpp2, octeontx2)
 - mellanox (mlx4)
 - qlogic (qede)
 - sfc
 - socionext (netsec)
 - ti (cpsw)
 - tap
 - veth
 - xen
 - virtio_net.

Turn 'basic' (tx, pass, aborted and drop) features flags on for:
 - netronome (nfp)
 - cavium (thunder)
 - hyperv.

Turn 'tx_lock' feature flag on for:
 - aquantia
 - freescale (dpaa2)
 - intel (igb)
 - marvell (mvneta, mvpp2)
 - microsoft (mana)
 - mediatek
 - qlogic (qede)
 - socionext (netsec)
 - ti (cpsw)
 - tap
 - veth
 - xen

Turn 'redirect_target' feature flag on for:
 - amanzon (ena)
 - broadcom (bnxt)
 - freescale (dpaa, dpaa2)
 - intel (i40e, ice, igb, ixgbe)
 - ti (cpsw)
 - marvell (mvneta, mvpp2)
 - sfc
 - socionext (netsec)
 - qlogic (qede)
 - mellanox (mlx5)
 - tap
 - veth
 - virtio_net
 - xen

Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Marek Majtyka <alardam@gmail.com>
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c  |  5 +++
 .../net/ethernet/aquantia/atlantic/aq_nic.c   |  4 +++
 drivers/net/ethernet/broadcom/bnxt/bnxt.c     |  2 ++
 drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |  2 ++
 .../net/ethernet/cavium/thunder/nicvf_main.c  |  2 ++
 .../net/ethernet/freescale/dpaa/dpaa_eth.c    |  2 ++
 .../net/ethernet/freescale/dpaa2/dpaa2-eth.c  |  1 +
 .../net/ethernet/freescale/enetc/enetc_pf.c   |  2 ++
 .../ethernet/fungible/funeth/funeth_main.c    |  6 ++++
 drivers/net/ethernet/intel/i40e/i40e_main.c   | 10 ++++--
 drivers/net/ethernet/intel/ice/ice_main.c     |  5 +++
 drivers/net/ethernet/intel/igb/igb_main.c     | 10 +++++-
 drivers/net/ethernet/intel/igc/igc_main.c     |  2 ++
 drivers/net/ethernet/intel/igc/igc_xdp.c      |  5 +++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  5 +++
 .../net/ethernet/intel/ixgbevf/ixgbevf_main.c |  1 +
 drivers/net/ethernet/marvell/mvneta.c         |  2 ++
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c   |  3 ++
 .../ethernet/marvell/octeontx2/nic/otx2_pf.c  |  8 +++--
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  5 +++
 .../net/ethernet/mellanox/mlx4/en_netdev.c    |  2 ++
 .../net/ethernet/mellanox/mlx5/core/en_main.c | 10 ++++++
 drivers/net/ethernet/microsoft/mana/mana_en.c |  1 +
 .../ethernet/netronome/nfp/nfp_net_common.c   |  5 +++
 drivers/net/ethernet/qlogic/qede/qede_main.c  |  2 ++
 drivers/net/ethernet/sfc/efx.c                |  3 ++
 drivers/net/ethernet/sfc/siena/efx.c          |  3 ++
 drivers/net/ethernet/socionext/netsec.c       |  2 ++
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  1 +
 drivers/net/ethernet/ti/cpsw.c                |  2 ++
 drivers/net/ethernet/ti/cpsw_new.c            |  3 ++
 drivers/net/hyperv/netvsc_drv.c               |  2 ++
 drivers/net/netdevsim/netdev.c                |  1 +
 drivers/net/tun.c                             |  4 +++
 drivers/net/veth.c                            |  3 ++
 drivers/net/virtio_net.c                      |  5 +++
 drivers/net/xen-netfront.c                    |  1 +
 include/net/xdp.h                             | 31 +++++++++++++++++++
 38 files changed, 158 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index e8ad5ea31aff..8226c93a0cbc 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -597,7 +597,10 @@ static int ena_xdp_set(struct net_device *netdev, struct netdev_bpf *bpf)
 				if (rc)
 					return rc;
 			}
+			xdp_features_set_redirect_target(&netdev->xdp_features,
+							 false);
 		} else if (old_bpf_prog) {
+			xdp_features_clear_redirect_target(&netdev->xdp_features);
 			rc = ena_destroy_and_free_all_xdp_queues(adapter);
 			if (rc)
 				return rc;
@@ -4103,6 +4106,8 @@ static void ena_set_conf_feat_params(struct ena_adapter *adapter,
 	/* Set offload features */
 	ena_set_dev_offloads(feat, netdev);
 
+	netdev->xdp_features = NETDEV_XDP_ACT_FULL;
+
 	adapter->max_mtu = feat->dev_attr.max_mtu;
 	netdev->max_mtu = adapter->max_mtu;
 	netdev->min_mtu = ENA_MIN_MTU;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 06508eebb585..3fc9a702083c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -384,6 +384,10 @@ void aq_nic_ndev_init(struct aq_nic_s *self)
 	self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN;
 	self->ndev->max_mtu = aq_hw_caps->mtu - ETH_FCS_LEN - ETH_HLEN;
 
+	self->ndev->xdp_features = NETDEV_XDP_ACT_FULL |
+				   NETDEV_XDP_ACT_NDO_XMIT |
+				   NETDEV_XDP_ACT_RX_SG |
+				   NETDEV_XDP_ACT_NDO_XMIT_SG;
 }
 
 void aq_nic_set_tx_ring(struct aq_nic_s *self, unsigned int idx,
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 16ce7a90610c..333636d83620 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -13686,6 +13686,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	netif_set_tso_max_size(dev, GSO_MAX_SIZE);
 
+	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_RX_SG;
+
 #ifdef CONFIG_BNXT_SRIOV
 	init_waitqueue_head(&bp->sriov_cfg_wait);
 #endif
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index 36d5202c0aee..933b56eb5afe 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -422,9 +422,11 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
 
 	if (prog) {
 		bnxt_set_rx_skb_mode(bp, true);
+		xdp_features_set_redirect_target(&dev->xdp_features, true);
 	} else {
 		int rx, tx;
 
+		xdp_features_clear_redirect_target(&dev->xdp_features);
 		bnxt_set_rx_skb_mode(bp, false);
 		bnxt_get_max_rings(bp, &rx, &tx, true);
 		if (rx > 1) {
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index f2f95493ec89..8b25313c7f6b 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -2218,6 +2218,8 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->netdev_ops = &nicvf_netdev_ops;
 	netdev->watchdog_timeo = NICVF_TX_TIMEOUT;
 
+	netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
+
 	/* MTU range: 64 - 9200 */
 	netdev->min_mtu = NIC_HW_MIN_FRS;
 	netdev->max_mtu = NIC_HW_MAX_FRS;
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 3f8032947d86..f6e1b270b6d0 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -244,6 +244,8 @@ static int dpaa_netdev_init(struct net_device *net_dev,
 	net_dev->features |= net_dev->hw_features;
 	net_dev->vlan_features = net_dev->features;
 
+	net_dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
+
 	if (is_valid_ether_addr(mac_addr)) {
 		memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
 		eth_hw_addr_set(net_dev, mac_addr);
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 0c35abb7d065..6bf4eec441b9 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -4593,6 +4593,7 @@ static int dpaa2_eth_netdev_init(struct net_device *net_dev)
 			    NETIF_F_LLTX | NETIF_F_HW_TC | NETIF_F_TSO;
 	net_dev->gso_max_segs = DPAA2_ETH_ENQUEUE_MAX_FDS;
 	net_dev->hw_features = net_dev->features;
+	net_dev->xdp_features = NETDEV_XDP_ACT_ZC | NETDEV_XDP_ACT_NDO_XMIT;
 
 	if (priv->dpni_attrs.vlan_filter_entries)
 		net_dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index 9f6c4f5c0a6c..5f481985d3c1 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -825,6 +825,8 @@ static void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
 		ndev->hw_features |= NETIF_F_RXHASH;
 
 	ndev->priv_flags |= IFF_UNICAST_FLT;
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT |
+			     NETDEV_XDP_ACT_RX_SG | NETDEV_XDP_ACT_NDO_XMIT_SG;
 
 	if (si->hw_features & ENETC_SI_F_PSFP && !enetc_psfp_enable(priv)) {
 		priv->active_offloads |= ENETC_F_QCI;
diff --git a/drivers/net/ethernet/fungible/funeth/funeth_main.c b/drivers/net/ethernet/fungible/funeth/funeth_main.c
index b4cce30e526a..544200c940e1 100644
--- a/drivers/net/ethernet/fungible/funeth/funeth_main.c
+++ b/drivers/net/ethernet/fungible/funeth/funeth_main.c
@@ -1160,6 +1160,11 @@ static int fun_xdp_setup(struct net_device *dev, struct netdev_bpf *xdp)
 			WRITE_ONCE(rxqs[i]->xdp_prog, prog);
 	}
 
+	if (prog)
+		xdp_features_set_redirect_target(&dev->xdp_features, true);
+	else
+		xdp_features_clear_redirect_target(&dev->xdp_features);
+
 	dev->max_mtu = prog ? XDP_MAX_MTU : FUN_MAX_MTU;
 	old_prog = xchg(&fp->xdp_prog, prog);
 	if (old_prog)
@@ -1765,6 +1770,7 @@ static int fun_create_netdev(struct fun_ethdev *ed, unsigned int portid)
 	netdev->vlan_features = netdev->features & VLAN_FEAT;
 	netdev->mpls_features = netdev->vlan_features;
 	netdev->hw_enc_features = netdev->hw_features;
+	netdev->xdp_features = NETDEV_XDP_ACT_FULL;
 
 	netdev->min_mtu = ETH_MIN_MTU;
 	netdev->max_mtu = FUN_MAX_MTU;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 53d0083e35da..3b868c5a8052 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -13339,9 +13339,11 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,
 	old_prog = xchg(&vsi->xdp_prog, prog);
 
 	if (need_reset) {
-		if (!prog)
+		if (!prog) {
+			xdp_features_clear_redirect_target(&vsi->netdev->xdp_features);
 			/* Wait until ndo_xsk_wakeup completes. */
 			synchronize_rcu();
+		}
 		i40e_reset_and_rebuild(pf, true, true);
 	}
 
@@ -13362,11 +13364,14 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,
 	/* Kick start the NAPI context if there is an AF_XDP socket open
 	 * on that queue id. This so that receiving will start.
 	 */
-	if (need_reset && prog)
+	if (need_reset && prog) {
 		for (i = 0; i < vsi->num_queue_pairs; i++)
 			if (vsi->xdp_rings[i]->xsk_pool)
 				(void)i40e_xsk_wakeup(vsi->netdev, i,
 						      XDP_WAKEUP_RX);
+		xdp_features_set_redirect_target(&vsi->netdev->xdp_features,
+						 true);
+	}
 
 	return 0;
 }
@@ -13783,6 +13788,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
 	netdev->hw_enc_features |= NETIF_F_TSO_MANGLEID;
 
 	netdev->features &= ~NETIF_F_HW_TC;
+	netdev->xdp_features = NETDEV_XDP_ACT_ZC;
 
 	if (vsi->type == I40E_VSI_MAIN) {
 		SET_NETDEV_DEV(netdev, &pf->pdev->dev);
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index a9a7f8b52140..ff2e35f50376 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -22,6 +22,7 @@
 #include "ice_eswitch.h"
 #include "ice_tc_lib.h"
 #include "ice_vsi_vlan_ops.h"
+#include <net/xdp_sock_drv.h>
 
 #define DRV_SUMMARY	"Intel(R) Ethernet Connection E800 Series Linux Driver"
 static const char ice_driver_string[] = DRV_SUMMARY;
@@ -2899,11 +2900,14 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
 			if (xdp_ring_err)
 				NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed");
 		}
+		xdp_features_set_redirect_target(&vsi->netdev->xdp_features,
+						 false);
 		/* reallocate Rx queues that are used for zero-copy */
 		xdp_ring_err = ice_realloc_zc_buf(vsi, true);
 		if (xdp_ring_err)
 			NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Rx resources failed");
 	} else if (ice_is_xdp_ena_vsi(vsi) && !prog) {
+		xdp_features_clear_redirect_target(&vsi->netdev->xdp_features);
 		xdp_ring_err = ice_destroy_xdp_rings(vsi);
 		if (xdp_ring_err)
 			NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Tx resources failed");
@@ -3446,6 +3450,7 @@ static int ice_cfg_netdev(struct ice_vsi *vsi)
 	np->vsi = vsi;
 
 	ice_set_netdev_features(netdev);
+	netdev->xdp_features = NETDEV_XDP_ACT_ZC;
 
 	ice_set_ops(netdev);
 
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 3c0c35ecea10..43a6f1f9d3fd 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2871,8 +2871,15 @@ static int igb_xdp_setup(struct net_device *dev, struct netdev_bpf *bpf)
 		bpf_prog_put(old_prog);
 
 	/* bpf is just replaced, RXQ and MTU are already setup */
-	if (!need_reset)
+	if (!need_reset) {
 		return 0;
+	} else {
+		if (prog)
+			xdp_features_set_redirect_target(&dev->xdp_features,
+							 true);
+		else
+			xdp_features_clear_redirect_target(&dev->xdp_features);
+	}
 
 	if (running)
 		igb_open(dev);
@@ -3317,6 +3324,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->priv_flags |= IFF_SUPP_NOFCS;
 
 	netdev->priv_flags |= IFF_UNICAST_FLT;
+	netdev->xdp_features = NETDEV_XDP_ACT_FULL;
 
 	/* MTU range: 68 - 9216 */
 	netdev->min_mtu = ETH_MIN_MTU;
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index e86b15efaeb8..3702c3cea383 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -6533,6 +6533,8 @@ static int igc_probe(struct pci_dev *pdev,
 	netdev->mpls_features |= NETIF_F_HW_CSUM;
 	netdev->hw_enc_features |= netdev->vlan_features;
 
+	netdev->xdp_features = NETDEV_XDP_ACT_ZC;
+
 	/* MTU range: 68 - 9216 */
 	netdev->min_mtu = ETH_MIN_MTU;
 	netdev->max_mtu = MAX_STD_JUMBO_FRAME_SIZE;
diff --git a/drivers/net/ethernet/intel/igc/igc_xdp.c b/drivers/net/ethernet/intel/igc/igc_xdp.c
index aeeb34e64610..49c73a4034b1 100644
--- a/drivers/net/ethernet/intel/igc/igc_xdp.c
+++ b/drivers/net/ethernet/intel/igc/igc_xdp.c
@@ -29,6 +29,11 @@ int igc_xdp_set_prog(struct igc_adapter *adapter, struct bpf_prog *prog,
 	if (old_prog)
 		bpf_prog_put(old_prog);
 
+	if (prog)
+		xdp_features_set_redirect_target(&dev->xdp_features, true);
+	else
+		xdp_features_clear_redirect_target(&dev->xdp_features);
+
 	if (if_running)
 		igc_open(dev);
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index ab8370c413f3..7edb2721c1a8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -10301,6 +10301,8 @@ static int ixgbe_xdp_setup(struct net_device *dev, struct bpf_prog *prog)
 			rcu_assign_pointer(adapter->xdp_prog, old_prog);
 			return -EINVAL;
 		}
+		if (!prog)
+			xdp_features_clear_redirect_target(&dev->xdp_features);
 	} else {
 		for (i = 0; i < adapter->num_rx_queues; i++)
 			(void)xchg(&adapter->rx_ring[i]->xdp_prog,
@@ -10320,6 +10322,7 @@ static int ixgbe_xdp_setup(struct net_device *dev, struct bpf_prog *prog)
 			if (adapter->xdp_ring[i]->xsk_pool)
 				(void)ixgbe_xsk_wakeup(adapter->netdev, i,
 						       XDP_WAKEUP_RX);
+		xdp_features_set_redirect_target(&dev->xdp_features, true);
 	}
 
 	return 0;
@@ -11017,6 +11020,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->priv_flags |= IFF_UNICAST_FLT;
 	netdev->priv_flags |= IFF_SUPP_NOFCS;
 
+	netdev->xdp_features = NETDEV_XDP_ACT_ZC;
+
 	/* MTU range: 68 - 9710 */
 	netdev->min_mtu = ETH_MIN_MTU;
 	netdev->max_mtu = IXGBE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN);
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index ea0a230c1153..a44e4bd56142 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -4634,6 +4634,7 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 			    NETIF_F_HW_VLAN_CTAG_TX;
 
 	netdev->priv_flags |= IFF_UNICAST_FLT;
+	netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
 
 	/* MTU range: 68 - 1504 or 9710 */
 	netdev->min_mtu = ETH_MIN_MTU;
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index f8925cac61e4..7ca49753d618 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -5612,6 +5612,8 @@ static int mvneta_probe(struct platform_device *pdev)
 			NETIF_F_TSO | NETIF_F_RXCSUM;
 	dev->hw_features |= dev->features;
 	dev->vlan_features |= dev->features;
+	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT |
+			    NETDEV_XDP_ACT_RX_SG | NETDEV_XDP_ACT_NDO_XMIT_SG;
 	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
 	netif_set_tso_max_segs(dev, MVNETA_MAX_TSO_SEGS);
 
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 4da45c5abba5..826423541d7a 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -6866,6 +6866,9 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 
 	dev->vlan_features |= features;
 	netif_set_tso_max_segs(dev, MVPP2_MAX_TSO_SEGS);
+
+	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
+
 	dev->priv_flags |= IFF_UNICAST_FLT;
 
 	/* MTU range: 68 - 9704 */
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
index c1ea60bc2630..d88fd42e39b6 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
@@ -2512,10 +2512,13 @@ static int otx2_xdp_setup(struct otx2_nic *pf, struct bpf_prog *prog)
 	/* Network stack and XDP shared same rx queues.
 	 * Use separate tx queues for XDP and network stack.
 	 */
-	if (pf->xdp_prog)
+	if (pf->xdp_prog) {
 		pf->hw.xdp_queues = pf->hw.rx_queues;
-	else
+		xdp_features_set_redirect_target(&dev->xdp_features, false);
+	} else {
 		pf->hw.xdp_queues = 0;
+		xdp_features_clear_redirect_target(&dev->xdp_features);
+	}
 
 	pf->hw.tot_tx_queues += pf->hw.xdp_queues;
 
@@ -2878,6 +2881,7 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	netdev->watchdog_timeo = OTX2_TX_TIMEOUT;
 
 	netdev->netdev_ops = &otx2_netdev_ops;
+	netdev->xdp_features = NETDEV_XDP_ACT_FULL;
 
 	netdev->min_mtu = OTX2_MIN_MTU;
 	netdev->max_mtu = otx2_get_max_mtu(pf);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index e3de9a53b2d9..d960dd3841d7 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4186,6 +4186,11 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 		register_netdevice_notifier(&mac->device_notifier);
 	}
 
+	if (mtk_page_pool_enabled(eth))
+		eth->netdev[id]->xdp_features = NETDEV_XDP_ACT_FULL |
+						NETDEV_XDP_ACT_NDO_XMIT |
+						NETDEV_XDP_ACT_NDO_XMIT_SG;
+
 	return 0;
 
 free_netdev:
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 8800d3f1f55c..77957db600cb 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -3410,6 +3410,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
 		priv->rss_hash_fn = ETH_RSS_HASH_TOP;
 	}
 
+	dev->xdp_features = NETDEV_XDP_ACT_FULL;
+
 	/* MTU range: 68 - hw-specific max */
 	dev->min_mtu = ETH_MIN_MTU;
 	dev->max_mtu = priv->max_mtu;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index cff5f2e29e1e..d3ad380ec959 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -4776,6 +4776,14 @@ static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog)
 	if (old_prog)
 		bpf_prog_put(old_prog);
 
+	if (reset) {
+		if (prog)
+			xdp_features_set_redirect_target(&netdev->xdp_features,
+							 true);
+		else
+			xdp_features_clear_redirect_target(&netdev->xdp_features);
+	}
+
 	if (!test_bit(MLX5E_STATE_OPENED, &priv->state) || reset)
 		goto unlock;
 
@@ -5170,6 +5178,8 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
 	netdev->features         |= NETIF_F_HIGHDMA;
 	netdev->features         |= NETIF_F_HW_VLAN_STAG_FILTER;
 
+	netdev->xdp_features = NETDEV_XDP_ACT_ZC | NETDEV_XDP_ACT_RX_SG;
+
 	netdev->priv_flags       |= IFF_UNICAST_FLT;
 
 	netif_set_tso_max_size(netdev, GSO_MAX_SIZE);
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 2f6a048dee90..25f21942aa20 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -2160,6 +2160,7 @@ static int mana_probe_port(struct mana_context *ac, int port_idx,
 	ndev->hw_features |= NETIF_F_RXHASH;
 	ndev->features = ndev->hw_features;
 	ndev->vlan_features = 0;
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
 
 	err = register_netdev(ndev);
 	if (err) {
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 18fc9971f1c8..e4825d885560 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -2529,10 +2529,15 @@ static void nfp_net_netdev_init(struct nfp_net *nn)
 	netdev->features &= ~NETIF_F_HW_VLAN_STAG_RX;
 	nn->dp.ctrl &= ~NFP_NET_CFG_CTRL_RXQINQ;
 
+	netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
+	if (nn->app && nn->app->type->id == NFP_APP_BPF_NIC)
+		netdev->xdp_features |= NETDEV_XDP_ACT_HW_OFFLOAD;
+
 	/* Finalise the netdev setup */
 	switch (nn->dp.ops->version) {
 	case NFP_NFD_VER_NFD3:
 		netdev->netdev_ops = &nfp_nfd3_netdev_ops;
+		netdev->xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY;
 		break;
 	case NFP_NFD_VER_NFDK:
 		netdev->netdev_ops = &nfp_nfdk_netdev_ops;
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 953f304b8588..a8ad2b8386d3 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -892,6 +892,8 @@ static void qede_init_ndev(struct qede_dev *edev)
 
 	ndev->hw_features = hw_features;
 
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
+
 	/* MTU range: 46 - 9600 */
 	ndev->min_mtu = ETH_ZLEN - ETH_HLEN;
 	ndev->max_mtu = QEDE_MAX_JUMBO_PACKET_SIZE;
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 0556542d7a6b..60b2183681ce 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1078,6 +1078,9 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
 
 	pci_info(pci_dev, "Solarflare NIC detected\n");
 
+	efx->net_dev->xdp_features = NETDEV_XDP_ACT_FULL |
+				     NETDEV_XDP_ACT_NDO_XMIT;
+
 	if (!efx->type->is_vf)
 		efx_probe_vpd_strings(efx);
 
diff --git a/drivers/net/ethernet/sfc/siena/efx.c b/drivers/net/ethernet/sfc/siena/efx.c
index 60e5b7c8ccf9..175c999bebc1 100644
--- a/drivers/net/ethernet/sfc/siena/efx.c
+++ b/drivers/net/ethernet/sfc/siena/efx.c
@@ -1048,6 +1048,9 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
 
 	pci_info(pci_dev, "Solarflare NIC detected\n");
 
+	efx->net_dev->xdp_features = NETDEV_XDP_ACT_FULL |
+				     NETDEV_XDP_ACT_NDO_XMIT;
+
 	if (!efx->type->is_vf)
 		efx_probe_vpd_strings(efx);
 
diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
index 9b46579b5a10..4d6f17efa227 100644
--- a/drivers/net/ethernet/socionext/netsec.c
+++ b/drivers/net/ethernet/socionext/netsec.c
@@ -2104,6 +2104,8 @@ static int netsec_probe(struct platform_device *pdev)
 				NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
 	ndev->hw_features = ndev->features;
 
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
+
 	priv->rx_cksum_offload_flag = true;
 
 	ret = netsec_register_mdio(priv, phy_addr);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c6951c976f5d..316574ce3aa0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7145,6 +7145,7 @@ int stmmac_dvr_probe(struct device *device,
 
 	ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
 			    NETIF_F_RXCSUM;
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
 
 	ret = stmmac_tc_init(priv, priv);
 	if (!ret) {
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 13c9c2d6b79b..68b89c56d8b6 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1458,6 +1458,7 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv)
 	priv_sl2->emac_port = 1;
 	cpsw->slaves[1].ndev = ndev;
 	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
 
 	ndev->netdev_ops = &cpsw_netdev_ops;
 	ndev->ethtool_ops = &cpsw_ethtool_ops;
@@ -1635,6 +1636,7 @@ static int cpsw_probe(struct platform_device *pdev)
 	cpsw->slaves[0].ndev = ndev;
 
 	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
 
 	ndev->netdev_ops = &cpsw_netdev_ops;
 	ndev->ethtool_ops = &cpsw_ethtool_ops;
diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c
index 83596ec0c7cb..1cf8c6202e05 100644
--- a/drivers/net/ethernet/ti/cpsw_new.c
+++ b/drivers/net/ethernet/ti/cpsw_new.c
@@ -1405,6 +1405,9 @@ static int cpsw_create_ports(struct cpsw_common *cpsw)
 		ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |
 				  NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_NETNS_LOCAL | NETIF_F_HW_TC;
 
+		ndev->xdp_features = NETDEV_XDP_ACT_FULL |
+				     NETDEV_XDP_ACT_NDO_XMIT;
+
 		ndev->netdev_ops = &cpsw_netdev_ops;
 		ndev->ethtool_ops = &cpsw_ethtool_ops;
 		SET_NETDEV_DEV(ndev, dev);
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index f9b219e6cd58..c7c1ce6ca201 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -2559,6 +2559,8 @@ static int netvsc_probe(struct hv_device *dev,
 
 	netdev_lockdep_set_classes(net);
 
+	net->xdp_features = NETDEV_XDP_ACT_FULL;
+
 	/* MTU range: 68 - 1500 or 65521 */
 	net->min_mtu = NETVSC_MTU_MIN;
 	if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index 6db6a75ff9b9..35fa1ca98671 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -286,6 +286,7 @@ static void nsim_setup(struct net_device *dev)
 			 NETIF_F_TSO;
 	dev->hw_features |= NETIF_F_HW_TC;
 	dev->max_mtu = ETH_MAX_MTU;
+	dev->xdp_features = NETDEV_XDP_ACT_HW_OFFLOAD;
 }
 
 static int nsim_init_netdevsim(struct netdevsim *ns)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index a7d17c680f4a..fc041cff75e4 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1401,6 +1401,10 @@ static void tun_net_initialize(struct net_device *dev)
 
 		eth_hw_addr_random(dev);
 
+		/* Currently tun does not support XDP, only tap does. */
+		dev->xdp_features = NETDEV_XDP_ACT_FULL |
+				    NETDEV_XDP_ACT_NDO_XMIT;
+
 		break;
 	}
 
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index dfc7d87fad59..01f7b38888a0 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -1649,6 +1649,9 @@ static void veth_setup(struct net_device *dev)
 	dev->hw_enc_features = VETH_FEATURES;
 	dev->mpls_features = NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE;
 	netif_set_tso_max_size(dev, GSO_MAX_SIZE);
+
+	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT |
+			    NETDEV_XDP_ACT_RX_SG | NETDEV_XDP_ACT_NDO_XMIT_SG;
 }
 
 /*
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 7723b2a49d8e..2b32fd84016f 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -3155,7 +3155,11 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
 			if (i == 0 && !old_prog)
 				virtnet_clear_guest_offloads(vi);
 		}
+		if (!old_prog)
+			xdp_features_set_redirect_target(&dev->xdp_features,
+							 false);
 	} else {
+		xdp_features_clear_redirect_target(&dev->xdp_features);
 		vi->xdp_enabled = false;
 	}
 
@@ -3785,6 +3789,7 @@ static int virtnet_probe(struct virtio_device *vdev)
 		dev->hw_features |= NETIF_F_GRO_HW;
 
 	dev->vlan_features = dev->features;
+	dev->xdp_features = NETDEV_XDP_ACT_FULL;
 
 	/* MTU range: 68 - 65535 */
 	dev->min_mtu = MIN_MTU;
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 14aec417fa06..58f0cbbadc90 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1741,6 +1741,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
          * negotiate with the backend regarding supported features.
          */
 	netdev->features |= netdev->hw_features;
+	netdev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
 
 	netdev->ethtool_ops = &xennet_ethtool_ops;
 	netdev->min_mtu = ETH_MIN_MTU;
diff --git a/include/net/xdp.h b/include/net/xdp.h
index 3d37460f0bdb..383f8051eb28 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -410,6 +410,37 @@ struct netdev_bpf;
 void xdp_attachment_setup(struct xdp_attachment_info *info,
 			  struct netdev_bpf *bpf);
 
+#if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL)
+
+static inline void
+xdp_features_set_redirect_target(xdp_features_t *xdp_features, bool support_sg)
+{
+	*xdp_features |= NETDEV_XDP_ACT_NDO_XMIT;
+	if (support_sg)
+		*xdp_features |= NETDEV_XDP_ACT_NDO_XMIT_SG;
+}
+
+static inline void
+xdp_features_clear_redirect_target(xdp_features_t *xdp_features)
+{
+	*xdp_features &= ~(NETDEV_XDP_ACT_NDO_XMIT |
+			   NETDEV_XDP_ACT_NDO_XMIT_SG);
+}
+
+#else
+
+static inline void
+xdp_features_set_redirect_target(xdp_features_t *xdp_features, bool support_sg)
+{
+}
+
+static inline void
+xdp_features_clear_redirect_target(xdp_features_t *xdp_features)
+{
+}
+
+#endif
+
 #define DEV_MAP_BULK_SIZE XDP_BULK_QUEUE_SIZE
 
 #endif /* __LINUX_NET_XDP_H__ */
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-wired-lan] [PATCH bpf-next 2/7] drivers: net: turn on XDP features
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, kuba,
	pabeni, aelior, hawk, christophe.jaillet, memxor, john, bjorn,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

From: Marek Majtyka <alardam@gmail.com>

A summary of the flags being set for various drivers is given below.
Note that XDP_F_REDIRECT_TARGET and XDP_F_FRAG_TARGET are features
that can be turned off and on at runtime. This means that these flags
may be set and unset under RTNL lock protection by the driver. Hence,
READ_ONCE must be used by code loading the flag value.

Also, these flags are not used for synchronization against the availability
of XDP resources on a device. It is merely a hint, and hence the read
may race with the actual teardown of XDP resources on the device. This
may change in the future, e.g. operations taking a reference on the XDP
resources of the driver, and in turn inhibiting turning off this flag.
However, for now, it can only be used as a hint to check whether device
supports becoming a redirection target.

Turn 'hw-offload' feature flag on for:
 - netronome (nfp)
 - netdevsim.

Turn 'native' and 'zerocopy' features flags on for:
 - intel (i40e, ice, ixgbe, igc)
 - mellanox (mlx5).
 - stmmac

Turn 'native' features flags on for:
 - amazon (ena)
 - broadcom (bnxt)
 - freescale (dpaa, dpaa2, enetc)
 - funeth
 - intel (igb)
 - marvell (mvneta, mvpp2, octeontx2)
 - mellanox (mlx4)
 - qlogic (qede)
 - sfc
 - socionext (netsec)
 - ti (cpsw)
 - tap
 - veth
 - xen
 - virtio_net.

Turn 'basic' (tx, pass, aborted and drop) features flags on for:
 - netronome (nfp)
 - cavium (thunder)
 - hyperv.

Turn 'tx_lock' feature flag on for:
 - aquantia
 - freescale (dpaa2)
 - intel (igb)
 - marvell (mvneta, mvpp2)
 - microsoft (mana)
 - mediatek
 - qlogic (qede)
 - socionext (netsec)
 - ti (cpsw)
 - tap
 - veth
 - xen

Turn 'redirect_target' feature flag on for:
 - amanzon (ena)
 - broadcom (bnxt)
 - freescale (dpaa, dpaa2)
 - intel (i40e, ice, igb, ixgbe)
 - ti (cpsw)
 - marvell (mvneta, mvpp2)
 - sfc
 - socionext (netsec)
 - qlogic (qede)
 - mellanox (mlx5)
 - tap
 - veth
 - virtio_net
 - xen

Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Marek Majtyka <alardam@gmail.com>
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c  |  5 +++
 .../net/ethernet/aquantia/atlantic/aq_nic.c   |  4 +++
 drivers/net/ethernet/broadcom/bnxt/bnxt.c     |  2 ++
 drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |  2 ++
 .../net/ethernet/cavium/thunder/nicvf_main.c  |  2 ++
 .../net/ethernet/freescale/dpaa/dpaa_eth.c    |  2 ++
 .../net/ethernet/freescale/dpaa2/dpaa2-eth.c  |  1 +
 .../net/ethernet/freescale/enetc/enetc_pf.c   |  2 ++
 .../ethernet/fungible/funeth/funeth_main.c    |  6 ++++
 drivers/net/ethernet/intel/i40e/i40e_main.c   | 10 ++++--
 drivers/net/ethernet/intel/ice/ice_main.c     |  5 +++
 drivers/net/ethernet/intel/igb/igb_main.c     | 10 +++++-
 drivers/net/ethernet/intel/igc/igc_main.c     |  2 ++
 drivers/net/ethernet/intel/igc/igc_xdp.c      |  5 +++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  5 +++
 .../net/ethernet/intel/ixgbevf/ixgbevf_main.c |  1 +
 drivers/net/ethernet/marvell/mvneta.c         |  2 ++
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c   |  3 ++
 .../ethernet/marvell/octeontx2/nic/otx2_pf.c  |  8 +++--
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  5 +++
 .../net/ethernet/mellanox/mlx4/en_netdev.c    |  2 ++
 .../net/ethernet/mellanox/mlx5/core/en_main.c | 10 ++++++
 drivers/net/ethernet/microsoft/mana/mana_en.c |  1 +
 .../ethernet/netronome/nfp/nfp_net_common.c   |  5 +++
 drivers/net/ethernet/qlogic/qede/qede_main.c  |  2 ++
 drivers/net/ethernet/sfc/efx.c                |  3 ++
 drivers/net/ethernet/sfc/siena/efx.c          |  3 ++
 drivers/net/ethernet/socionext/netsec.c       |  2 ++
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  1 +
 drivers/net/ethernet/ti/cpsw.c                |  2 ++
 drivers/net/ethernet/ti/cpsw_new.c            |  3 ++
 drivers/net/hyperv/netvsc_drv.c               |  2 ++
 drivers/net/netdevsim/netdev.c                |  1 +
 drivers/net/tun.c                             |  4 +++
 drivers/net/veth.c                            |  3 ++
 drivers/net/virtio_net.c                      |  5 +++
 drivers/net/xen-netfront.c                    |  1 +
 include/net/xdp.h                             | 31 +++++++++++++++++++
 38 files changed, 158 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index e8ad5ea31aff..8226c93a0cbc 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -597,7 +597,10 @@ static int ena_xdp_set(struct net_device *netdev, struct netdev_bpf *bpf)
 				if (rc)
 					return rc;
 			}
+			xdp_features_set_redirect_target(&netdev->xdp_features,
+							 false);
 		} else if (old_bpf_prog) {
+			xdp_features_clear_redirect_target(&netdev->xdp_features);
 			rc = ena_destroy_and_free_all_xdp_queues(adapter);
 			if (rc)
 				return rc;
@@ -4103,6 +4106,8 @@ static void ena_set_conf_feat_params(struct ena_adapter *adapter,
 	/* Set offload features */
 	ena_set_dev_offloads(feat, netdev);
 
+	netdev->xdp_features = NETDEV_XDP_ACT_FULL;
+
 	adapter->max_mtu = feat->dev_attr.max_mtu;
 	netdev->max_mtu = adapter->max_mtu;
 	netdev->min_mtu = ENA_MIN_MTU;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 06508eebb585..3fc9a702083c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -384,6 +384,10 @@ void aq_nic_ndev_init(struct aq_nic_s *self)
 	self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN;
 	self->ndev->max_mtu = aq_hw_caps->mtu - ETH_FCS_LEN - ETH_HLEN;
 
+	self->ndev->xdp_features = NETDEV_XDP_ACT_FULL |
+				   NETDEV_XDP_ACT_NDO_XMIT |
+				   NETDEV_XDP_ACT_RX_SG |
+				   NETDEV_XDP_ACT_NDO_XMIT_SG;
 }
 
 void aq_nic_set_tx_ring(struct aq_nic_s *self, unsigned int idx,
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 16ce7a90610c..333636d83620 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -13686,6 +13686,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	netif_set_tso_max_size(dev, GSO_MAX_SIZE);
 
+	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_RX_SG;
+
 #ifdef CONFIG_BNXT_SRIOV
 	init_waitqueue_head(&bp->sriov_cfg_wait);
 #endif
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index 36d5202c0aee..933b56eb5afe 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -422,9 +422,11 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
 
 	if (prog) {
 		bnxt_set_rx_skb_mode(bp, true);
+		xdp_features_set_redirect_target(&dev->xdp_features, true);
 	} else {
 		int rx, tx;
 
+		xdp_features_clear_redirect_target(&dev->xdp_features);
 		bnxt_set_rx_skb_mode(bp, false);
 		bnxt_get_max_rings(bp, &rx, &tx, true);
 		if (rx > 1) {
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index f2f95493ec89..8b25313c7f6b 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -2218,6 +2218,8 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->netdev_ops = &nicvf_netdev_ops;
 	netdev->watchdog_timeo = NICVF_TX_TIMEOUT;
 
+	netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
+
 	/* MTU range: 64 - 9200 */
 	netdev->min_mtu = NIC_HW_MIN_FRS;
 	netdev->max_mtu = NIC_HW_MAX_FRS;
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 3f8032947d86..f6e1b270b6d0 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -244,6 +244,8 @@ static int dpaa_netdev_init(struct net_device *net_dev,
 	net_dev->features |= net_dev->hw_features;
 	net_dev->vlan_features = net_dev->features;
 
+	net_dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
+
 	if (is_valid_ether_addr(mac_addr)) {
 		memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
 		eth_hw_addr_set(net_dev, mac_addr);
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 0c35abb7d065..6bf4eec441b9 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -4593,6 +4593,7 @@ static int dpaa2_eth_netdev_init(struct net_device *net_dev)
 			    NETIF_F_LLTX | NETIF_F_HW_TC | NETIF_F_TSO;
 	net_dev->gso_max_segs = DPAA2_ETH_ENQUEUE_MAX_FDS;
 	net_dev->hw_features = net_dev->features;
+	net_dev->xdp_features = NETDEV_XDP_ACT_ZC | NETDEV_XDP_ACT_NDO_XMIT;
 
 	if (priv->dpni_attrs.vlan_filter_entries)
 		net_dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index 9f6c4f5c0a6c..5f481985d3c1 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -825,6 +825,8 @@ static void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
 		ndev->hw_features |= NETIF_F_RXHASH;
 
 	ndev->priv_flags |= IFF_UNICAST_FLT;
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT |
+			     NETDEV_XDP_ACT_RX_SG | NETDEV_XDP_ACT_NDO_XMIT_SG;
 
 	if (si->hw_features & ENETC_SI_F_PSFP && !enetc_psfp_enable(priv)) {
 		priv->active_offloads |= ENETC_F_QCI;
diff --git a/drivers/net/ethernet/fungible/funeth/funeth_main.c b/drivers/net/ethernet/fungible/funeth/funeth_main.c
index b4cce30e526a..544200c940e1 100644
--- a/drivers/net/ethernet/fungible/funeth/funeth_main.c
+++ b/drivers/net/ethernet/fungible/funeth/funeth_main.c
@@ -1160,6 +1160,11 @@ static int fun_xdp_setup(struct net_device *dev, struct netdev_bpf *xdp)
 			WRITE_ONCE(rxqs[i]->xdp_prog, prog);
 	}
 
+	if (prog)
+		xdp_features_set_redirect_target(&dev->xdp_features, true);
+	else
+		xdp_features_clear_redirect_target(&dev->xdp_features);
+
 	dev->max_mtu = prog ? XDP_MAX_MTU : FUN_MAX_MTU;
 	old_prog = xchg(&fp->xdp_prog, prog);
 	if (old_prog)
@@ -1765,6 +1770,7 @@ static int fun_create_netdev(struct fun_ethdev *ed, unsigned int portid)
 	netdev->vlan_features = netdev->features & VLAN_FEAT;
 	netdev->mpls_features = netdev->vlan_features;
 	netdev->hw_enc_features = netdev->hw_features;
+	netdev->xdp_features = NETDEV_XDP_ACT_FULL;
 
 	netdev->min_mtu = ETH_MIN_MTU;
 	netdev->max_mtu = FUN_MAX_MTU;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 53d0083e35da..3b868c5a8052 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -13339,9 +13339,11 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,
 	old_prog = xchg(&vsi->xdp_prog, prog);
 
 	if (need_reset) {
-		if (!prog)
+		if (!prog) {
+			xdp_features_clear_redirect_target(&vsi->netdev->xdp_features);
 			/* Wait until ndo_xsk_wakeup completes. */
 			synchronize_rcu();
+		}
 		i40e_reset_and_rebuild(pf, true, true);
 	}
 
@@ -13362,11 +13364,14 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,
 	/* Kick start the NAPI context if there is an AF_XDP socket open
 	 * on that queue id. This so that receiving will start.
 	 */
-	if (need_reset && prog)
+	if (need_reset && prog) {
 		for (i = 0; i < vsi->num_queue_pairs; i++)
 			if (vsi->xdp_rings[i]->xsk_pool)
 				(void)i40e_xsk_wakeup(vsi->netdev, i,
 						      XDP_WAKEUP_RX);
+		xdp_features_set_redirect_target(&vsi->netdev->xdp_features,
+						 true);
+	}
 
 	return 0;
 }
@@ -13783,6 +13788,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
 	netdev->hw_enc_features |= NETIF_F_TSO_MANGLEID;
 
 	netdev->features &= ~NETIF_F_HW_TC;
+	netdev->xdp_features = NETDEV_XDP_ACT_ZC;
 
 	if (vsi->type == I40E_VSI_MAIN) {
 		SET_NETDEV_DEV(netdev, &pf->pdev->dev);
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index a9a7f8b52140..ff2e35f50376 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -22,6 +22,7 @@
 #include "ice_eswitch.h"
 #include "ice_tc_lib.h"
 #include "ice_vsi_vlan_ops.h"
+#include <net/xdp_sock_drv.h>
 
 #define DRV_SUMMARY	"Intel(R) Ethernet Connection E800 Series Linux Driver"
 static const char ice_driver_string[] = DRV_SUMMARY;
@@ -2899,11 +2900,14 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
 			if (xdp_ring_err)
 				NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed");
 		}
+		xdp_features_set_redirect_target(&vsi->netdev->xdp_features,
+						 false);
 		/* reallocate Rx queues that are used for zero-copy */
 		xdp_ring_err = ice_realloc_zc_buf(vsi, true);
 		if (xdp_ring_err)
 			NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Rx resources failed");
 	} else if (ice_is_xdp_ena_vsi(vsi) && !prog) {
+		xdp_features_clear_redirect_target(&vsi->netdev->xdp_features);
 		xdp_ring_err = ice_destroy_xdp_rings(vsi);
 		if (xdp_ring_err)
 			NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Tx resources failed");
@@ -3446,6 +3450,7 @@ static int ice_cfg_netdev(struct ice_vsi *vsi)
 	np->vsi = vsi;
 
 	ice_set_netdev_features(netdev);
+	netdev->xdp_features = NETDEV_XDP_ACT_ZC;
 
 	ice_set_ops(netdev);
 
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 3c0c35ecea10..43a6f1f9d3fd 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2871,8 +2871,15 @@ static int igb_xdp_setup(struct net_device *dev, struct netdev_bpf *bpf)
 		bpf_prog_put(old_prog);
 
 	/* bpf is just replaced, RXQ and MTU are already setup */
-	if (!need_reset)
+	if (!need_reset) {
 		return 0;
+	} else {
+		if (prog)
+			xdp_features_set_redirect_target(&dev->xdp_features,
+							 true);
+		else
+			xdp_features_clear_redirect_target(&dev->xdp_features);
+	}
 
 	if (running)
 		igb_open(dev);
@@ -3317,6 +3324,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->priv_flags |= IFF_SUPP_NOFCS;
 
 	netdev->priv_flags |= IFF_UNICAST_FLT;
+	netdev->xdp_features = NETDEV_XDP_ACT_FULL;
 
 	/* MTU range: 68 - 9216 */
 	netdev->min_mtu = ETH_MIN_MTU;
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index e86b15efaeb8..3702c3cea383 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -6533,6 +6533,8 @@ static int igc_probe(struct pci_dev *pdev,
 	netdev->mpls_features |= NETIF_F_HW_CSUM;
 	netdev->hw_enc_features |= netdev->vlan_features;
 
+	netdev->xdp_features = NETDEV_XDP_ACT_ZC;
+
 	/* MTU range: 68 - 9216 */
 	netdev->min_mtu = ETH_MIN_MTU;
 	netdev->max_mtu = MAX_STD_JUMBO_FRAME_SIZE;
diff --git a/drivers/net/ethernet/intel/igc/igc_xdp.c b/drivers/net/ethernet/intel/igc/igc_xdp.c
index aeeb34e64610..49c73a4034b1 100644
--- a/drivers/net/ethernet/intel/igc/igc_xdp.c
+++ b/drivers/net/ethernet/intel/igc/igc_xdp.c
@@ -29,6 +29,11 @@ int igc_xdp_set_prog(struct igc_adapter *adapter, struct bpf_prog *prog,
 	if (old_prog)
 		bpf_prog_put(old_prog);
 
+	if (prog)
+		xdp_features_set_redirect_target(&dev->xdp_features, true);
+	else
+		xdp_features_clear_redirect_target(&dev->xdp_features);
+
 	if (if_running)
 		igc_open(dev);
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index ab8370c413f3..7edb2721c1a8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -10301,6 +10301,8 @@ static int ixgbe_xdp_setup(struct net_device *dev, struct bpf_prog *prog)
 			rcu_assign_pointer(adapter->xdp_prog, old_prog);
 			return -EINVAL;
 		}
+		if (!prog)
+			xdp_features_clear_redirect_target(&dev->xdp_features);
 	} else {
 		for (i = 0; i < adapter->num_rx_queues; i++)
 			(void)xchg(&adapter->rx_ring[i]->xdp_prog,
@@ -10320,6 +10322,7 @@ static int ixgbe_xdp_setup(struct net_device *dev, struct bpf_prog *prog)
 			if (adapter->xdp_ring[i]->xsk_pool)
 				(void)ixgbe_xsk_wakeup(adapter->netdev, i,
 						       XDP_WAKEUP_RX);
+		xdp_features_set_redirect_target(&dev->xdp_features, true);
 	}
 
 	return 0;
@@ -11017,6 +11020,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->priv_flags |= IFF_UNICAST_FLT;
 	netdev->priv_flags |= IFF_SUPP_NOFCS;
 
+	netdev->xdp_features = NETDEV_XDP_ACT_ZC;
+
 	/* MTU range: 68 - 9710 */
 	netdev->min_mtu = ETH_MIN_MTU;
 	netdev->max_mtu = IXGBE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN);
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index ea0a230c1153..a44e4bd56142 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -4634,6 +4634,7 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 			    NETIF_F_HW_VLAN_CTAG_TX;
 
 	netdev->priv_flags |= IFF_UNICAST_FLT;
+	netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
 
 	/* MTU range: 68 - 1504 or 9710 */
 	netdev->min_mtu = ETH_MIN_MTU;
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index f8925cac61e4..7ca49753d618 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -5612,6 +5612,8 @@ static int mvneta_probe(struct platform_device *pdev)
 			NETIF_F_TSO | NETIF_F_RXCSUM;
 	dev->hw_features |= dev->features;
 	dev->vlan_features |= dev->features;
+	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT |
+			    NETDEV_XDP_ACT_RX_SG | NETDEV_XDP_ACT_NDO_XMIT_SG;
 	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
 	netif_set_tso_max_segs(dev, MVNETA_MAX_TSO_SEGS);
 
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 4da45c5abba5..826423541d7a 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -6866,6 +6866,9 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 
 	dev->vlan_features |= features;
 	netif_set_tso_max_segs(dev, MVPP2_MAX_TSO_SEGS);
+
+	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
+
 	dev->priv_flags |= IFF_UNICAST_FLT;
 
 	/* MTU range: 68 - 9704 */
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
index c1ea60bc2630..d88fd42e39b6 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
@@ -2512,10 +2512,13 @@ static int otx2_xdp_setup(struct otx2_nic *pf, struct bpf_prog *prog)
 	/* Network stack and XDP shared same rx queues.
 	 * Use separate tx queues for XDP and network stack.
 	 */
-	if (pf->xdp_prog)
+	if (pf->xdp_prog) {
 		pf->hw.xdp_queues = pf->hw.rx_queues;
-	else
+		xdp_features_set_redirect_target(&dev->xdp_features, false);
+	} else {
 		pf->hw.xdp_queues = 0;
+		xdp_features_clear_redirect_target(&dev->xdp_features);
+	}
 
 	pf->hw.tot_tx_queues += pf->hw.xdp_queues;
 
@@ -2878,6 +2881,7 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	netdev->watchdog_timeo = OTX2_TX_TIMEOUT;
 
 	netdev->netdev_ops = &otx2_netdev_ops;
+	netdev->xdp_features = NETDEV_XDP_ACT_FULL;
 
 	netdev->min_mtu = OTX2_MIN_MTU;
 	netdev->max_mtu = otx2_get_max_mtu(pf);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index e3de9a53b2d9..d960dd3841d7 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4186,6 +4186,11 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 		register_netdevice_notifier(&mac->device_notifier);
 	}
 
+	if (mtk_page_pool_enabled(eth))
+		eth->netdev[id]->xdp_features = NETDEV_XDP_ACT_FULL |
+						NETDEV_XDP_ACT_NDO_XMIT |
+						NETDEV_XDP_ACT_NDO_XMIT_SG;
+
 	return 0;
 
 free_netdev:
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 8800d3f1f55c..77957db600cb 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -3410,6 +3410,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
 		priv->rss_hash_fn = ETH_RSS_HASH_TOP;
 	}
 
+	dev->xdp_features = NETDEV_XDP_ACT_FULL;
+
 	/* MTU range: 68 - hw-specific max */
 	dev->min_mtu = ETH_MIN_MTU;
 	dev->max_mtu = priv->max_mtu;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index cff5f2e29e1e..d3ad380ec959 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -4776,6 +4776,14 @@ static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog)
 	if (old_prog)
 		bpf_prog_put(old_prog);
 
+	if (reset) {
+		if (prog)
+			xdp_features_set_redirect_target(&netdev->xdp_features,
+							 true);
+		else
+			xdp_features_clear_redirect_target(&netdev->xdp_features);
+	}
+
 	if (!test_bit(MLX5E_STATE_OPENED, &priv->state) || reset)
 		goto unlock;
 
@@ -5170,6 +5178,8 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
 	netdev->features         |= NETIF_F_HIGHDMA;
 	netdev->features         |= NETIF_F_HW_VLAN_STAG_FILTER;
 
+	netdev->xdp_features = NETDEV_XDP_ACT_ZC | NETDEV_XDP_ACT_RX_SG;
+
 	netdev->priv_flags       |= IFF_UNICAST_FLT;
 
 	netif_set_tso_max_size(netdev, GSO_MAX_SIZE);
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 2f6a048dee90..25f21942aa20 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -2160,6 +2160,7 @@ static int mana_probe_port(struct mana_context *ac, int port_idx,
 	ndev->hw_features |= NETIF_F_RXHASH;
 	ndev->features = ndev->hw_features;
 	ndev->vlan_features = 0;
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
 
 	err = register_netdev(ndev);
 	if (err) {
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 18fc9971f1c8..e4825d885560 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -2529,10 +2529,15 @@ static void nfp_net_netdev_init(struct nfp_net *nn)
 	netdev->features &= ~NETIF_F_HW_VLAN_STAG_RX;
 	nn->dp.ctrl &= ~NFP_NET_CFG_CTRL_RXQINQ;
 
+	netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
+	if (nn->app && nn->app->type->id == NFP_APP_BPF_NIC)
+		netdev->xdp_features |= NETDEV_XDP_ACT_HW_OFFLOAD;
+
 	/* Finalise the netdev setup */
 	switch (nn->dp.ops->version) {
 	case NFP_NFD_VER_NFD3:
 		netdev->netdev_ops = &nfp_nfd3_netdev_ops;
+		netdev->xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY;
 		break;
 	case NFP_NFD_VER_NFDK:
 		netdev->netdev_ops = &nfp_nfdk_netdev_ops;
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 953f304b8588..a8ad2b8386d3 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -892,6 +892,8 @@ static void qede_init_ndev(struct qede_dev *edev)
 
 	ndev->hw_features = hw_features;
 
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
+
 	/* MTU range: 46 - 9600 */
 	ndev->min_mtu = ETH_ZLEN - ETH_HLEN;
 	ndev->max_mtu = QEDE_MAX_JUMBO_PACKET_SIZE;
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 0556542d7a6b..60b2183681ce 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1078,6 +1078,9 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
 
 	pci_info(pci_dev, "Solarflare NIC detected\n");
 
+	efx->net_dev->xdp_features = NETDEV_XDP_ACT_FULL |
+				     NETDEV_XDP_ACT_NDO_XMIT;
+
 	if (!efx->type->is_vf)
 		efx_probe_vpd_strings(efx);
 
diff --git a/drivers/net/ethernet/sfc/siena/efx.c b/drivers/net/ethernet/sfc/siena/efx.c
index 60e5b7c8ccf9..175c999bebc1 100644
--- a/drivers/net/ethernet/sfc/siena/efx.c
+++ b/drivers/net/ethernet/sfc/siena/efx.c
@@ -1048,6 +1048,9 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
 
 	pci_info(pci_dev, "Solarflare NIC detected\n");
 
+	efx->net_dev->xdp_features = NETDEV_XDP_ACT_FULL |
+				     NETDEV_XDP_ACT_NDO_XMIT;
+
 	if (!efx->type->is_vf)
 		efx_probe_vpd_strings(efx);
 
diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
index 9b46579b5a10..4d6f17efa227 100644
--- a/drivers/net/ethernet/socionext/netsec.c
+++ b/drivers/net/ethernet/socionext/netsec.c
@@ -2104,6 +2104,8 @@ static int netsec_probe(struct platform_device *pdev)
 				NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
 	ndev->hw_features = ndev->features;
 
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
+
 	priv->rx_cksum_offload_flag = true;
 
 	ret = netsec_register_mdio(priv, phy_addr);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c6951c976f5d..316574ce3aa0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7145,6 +7145,7 @@ int stmmac_dvr_probe(struct device *device,
 
 	ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
 			    NETIF_F_RXCSUM;
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
 
 	ret = stmmac_tc_init(priv, priv);
 	if (!ret) {
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 13c9c2d6b79b..68b89c56d8b6 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1458,6 +1458,7 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv)
 	priv_sl2->emac_port = 1;
 	cpsw->slaves[1].ndev = ndev;
 	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
 
 	ndev->netdev_ops = &cpsw_netdev_ops;
 	ndev->ethtool_ops = &cpsw_ethtool_ops;
@@ -1635,6 +1636,7 @@ static int cpsw_probe(struct platform_device *pdev)
 	cpsw->slaves[0].ndev = ndev;
 
 	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
+	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
 
 	ndev->netdev_ops = &cpsw_netdev_ops;
 	ndev->ethtool_ops = &cpsw_ethtool_ops;
diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c
index 83596ec0c7cb..1cf8c6202e05 100644
--- a/drivers/net/ethernet/ti/cpsw_new.c
+++ b/drivers/net/ethernet/ti/cpsw_new.c
@@ -1405,6 +1405,9 @@ static int cpsw_create_ports(struct cpsw_common *cpsw)
 		ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |
 				  NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_NETNS_LOCAL | NETIF_F_HW_TC;
 
+		ndev->xdp_features = NETDEV_XDP_ACT_FULL |
+				     NETDEV_XDP_ACT_NDO_XMIT;
+
 		ndev->netdev_ops = &cpsw_netdev_ops;
 		ndev->ethtool_ops = &cpsw_ethtool_ops;
 		SET_NETDEV_DEV(ndev, dev);
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index f9b219e6cd58..c7c1ce6ca201 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -2559,6 +2559,8 @@ static int netvsc_probe(struct hv_device *dev,
 
 	netdev_lockdep_set_classes(net);
 
+	net->xdp_features = NETDEV_XDP_ACT_FULL;
+
 	/* MTU range: 68 - 1500 or 65521 */
 	net->min_mtu = NETVSC_MTU_MIN;
 	if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index 6db6a75ff9b9..35fa1ca98671 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -286,6 +286,7 @@ static void nsim_setup(struct net_device *dev)
 			 NETIF_F_TSO;
 	dev->hw_features |= NETIF_F_HW_TC;
 	dev->max_mtu = ETH_MAX_MTU;
+	dev->xdp_features = NETDEV_XDP_ACT_HW_OFFLOAD;
 }
 
 static int nsim_init_netdevsim(struct netdevsim *ns)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index a7d17c680f4a..fc041cff75e4 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1401,6 +1401,10 @@ static void tun_net_initialize(struct net_device *dev)
 
 		eth_hw_addr_random(dev);
 
+		/* Currently tun does not support XDP, only tap does. */
+		dev->xdp_features = NETDEV_XDP_ACT_FULL |
+				    NETDEV_XDP_ACT_NDO_XMIT;
+
 		break;
 	}
 
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index dfc7d87fad59..01f7b38888a0 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -1649,6 +1649,9 @@ static void veth_setup(struct net_device *dev)
 	dev->hw_enc_features = VETH_FEATURES;
 	dev->mpls_features = NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE;
 	netif_set_tso_max_size(dev, GSO_MAX_SIZE);
+
+	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT |
+			    NETDEV_XDP_ACT_RX_SG | NETDEV_XDP_ACT_NDO_XMIT_SG;
 }
 
 /*
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 7723b2a49d8e..2b32fd84016f 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -3155,7 +3155,11 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
 			if (i == 0 && !old_prog)
 				virtnet_clear_guest_offloads(vi);
 		}
+		if (!old_prog)
+			xdp_features_set_redirect_target(&dev->xdp_features,
+							 false);
 	} else {
+		xdp_features_clear_redirect_target(&dev->xdp_features);
 		vi->xdp_enabled = false;
 	}
 
@@ -3785,6 +3789,7 @@ static int virtnet_probe(struct virtio_device *vdev)
 		dev->hw_features |= NETIF_F_GRO_HW;
 
 	dev->vlan_features = dev->features;
+	dev->xdp_features = NETDEV_XDP_ACT_FULL;
 
 	/* MTU range: 68 - 65535 */
 	dev->min_mtu = MIN_MTU;
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 14aec417fa06..58f0cbbadc90 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1741,6 +1741,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
          * negotiate with the backend regarding supported features.
          */
 	netdev->features |= netdev->hw_features;
+	netdev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
 
 	netdev->ethtool_ops = &xennet_ethtool_ops;
 	netdev->min_mtu = ETH_MIN_MTU;
diff --git a/include/net/xdp.h b/include/net/xdp.h
index 3d37460f0bdb..383f8051eb28 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -410,6 +410,37 @@ struct netdev_bpf;
 void xdp_attachment_setup(struct xdp_attachment_info *info,
 			  struct netdev_bpf *bpf);
 
+#if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL)
+
+static inline void
+xdp_features_set_redirect_target(xdp_features_t *xdp_features, bool support_sg)
+{
+	*xdp_features |= NETDEV_XDP_ACT_NDO_XMIT;
+	if (support_sg)
+		*xdp_features |= NETDEV_XDP_ACT_NDO_XMIT_SG;
+}
+
+static inline void
+xdp_features_clear_redirect_target(xdp_features_t *xdp_features)
+{
+	*xdp_features &= ~(NETDEV_XDP_ACT_NDO_XMIT |
+			   NETDEV_XDP_ACT_NDO_XMIT_SG);
+}
+
+#else
+
+static inline void
+xdp_features_set_redirect_target(xdp_features_t *xdp_features, bool support_sg)
+{
+}
+
+static inline void
+xdp_features_clear_redirect_target(xdp_features_t *xdp_features)
+{
+}
+
+#endif
+
 #define DEV_MAP_BULK_SIZE XDP_BULK_QUEUE_SIZE
 
 #endif /* __LINUX_NET_XDP_H__ */
-- 
2.39.0

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH bpf-next 3/7] xsk: add usage of XDP features flags
  2023-01-20 17:16 ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: netdev, ast, daniel, andrii, davem, kuba, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

From: Marek Majtyka <alardam@gmail.com>

Change necessary condition check for XSK from ndo functions to
xdp features flags.

Signed-off-by: Marek Majtyka <alardam@gmail.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 net/xdp/xsk_buff_pool.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
index ed6c71826d31..2e6fa082142a 100644
--- a/net/xdp/xsk_buff_pool.c
+++ b/net/xdp/xsk_buff_pool.c
@@ -178,8 +178,7 @@ int xp_assign_dev(struct xsk_buff_pool *pool,
 		/* For copy-mode, we are done. */
 		return 0;
 
-	if (!netdev->netdev_ops->ndo_bpf ||
-	    !netdev->netdev_ops->ndo_xsk_wakeup) {
+	if ((netdev->xdp_features & NETDEV_XDP_ACT_ZC) != NETDEV_XDP_ACT_ZC) {
 		err = -EOPNOTSUPP;
 		goto err_unreg_pool;
 	}
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-wired-lan] [PATCH bpf-next 3/7] xsk: add usage of XDP features flags
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, kuba,
	pabeni, aelior, hawk, christophe.jaillet, memxor, john, bjorn,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

From: Marek Majtyka <alardam@gmail.com>

Change necessary condition check for XSK from ndo functions to
xdp features flags.

Signed-off-by: Marek Majtyka <alardam@gmail.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 net/xdp/xsk_buff_pool.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
index ed6c71826d31..2e6fa082142a 100644
--- a/net/xdp/xsk_buff_pool.c
+++ b/net/xdp/xsk_buff_pool.c
@@ -178,8 +178,7 @@ int xp_assign_dev(struct xsk_buff_pool *pool,
 		/* For copy-mode, we are done. */
 		return 0;
 
-	if (!netdev->netdev_ops->ndo_bpf ||
-	    !netdev->netdev_ops->ndo_xsk_wakeup) {
+	if ((netdev->xdp_features & NETDEV_XDP_ACT_ZC) != NETDEV_XDP_ACT_ZC) {
 		err = -EOPNOTSUPP;
 		goto err_unreg_pool;
 	}
-- 
2.39.0

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH bpf-next 4/7] libbpf: add the capability to specify netlink proto in libbpf_netlink_send_recv
  2023-01-20 17:16 ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: netdev, ast, daniel, andrii, davem, kuba, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

This is a preliminary patch in order to introduce netlink_generic
protocol support to libbpf.

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 tools/lib/bpf/netlink.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
index 35104580870c..d2468a04a6c3 100644
--- a/tools/lib/bpf/netlink.c
+++ b/tools/lib/bpf/netlink.c
@@ -41,7 +41,7 @@ struct xdp_id_md {
 	struct xdp_link_info info;
 };
 
-static int libbpf_netlink_open(__u32 *nl_pid)
+static int libbpf_netlink_open(__u32 *nl_pid, int proto)
 {
 	struct sockaddr_nl sa;
 	socklen_t addrlen;
@@ -51,7 +51,7 @@ static int libbpf_netlink_open(__u32 *nl_pid)
 	memset(&sa, 0, sizeof(sa));
 	sa.nl_family = AF_NETLINK;
 
-	sock = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
+	sock = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, proto);
 	if (sock < 0)
 		return -errno;
 
@@ -212,14 +212,14 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
 }
 
 static int libbpf_netlink_send_recv(struct libbpf_nla_req *req,
-				    __dump_nlmsg_t parse_msg,
+				    int proto, __dump_nlmsg_t parse_msg,
 				    libbpf_dump_nlmsg_t parse_attr,
 				    void *cookie)
 {
 	__u32 nl_pid = 0;
 	int sock, ret;
 
-	sock = libbpf_netlink_open(&nl_pid);
+	sock = libbpf_netlink_open(&nl_pid, proto);
 	if (sock < 0)
 		return sock;
 
@@ -271,7 +271,7 @@ static int __bpf_set_link_xdp_fd_replace(int ifindex, int fd, int old_fd,
 	}
 	nlattr_end_nested(&req, nla);
 
-	return libbpf_netlink_send_recv(&req, NULL, NULL, NULL);
+	return libbpf_netlink_send_recv(&req, NETLINK_ROUTE, NULL, NULL, NULL);
 }
 
 int bpf_xdp_attach(int ifindex, int prog_fd, __u32 flags, const struct bpf_xdp_attach_opts *opts)
@@ -382,7 +382,7 @@ int bpf_xdp_query(int ifindex, int xdp_flags, struct bpf_xdp_query_opts *opts)
 	xdp_id.ifindex = ifindex;
 	xdp_id.flags = xdp_flags;
 
-	err = libbpf_netlink_send_recv(&req, __dump_link_nlmsg,
+	err = libbpf_netlink_send_recv(&req, NETLINK_ROUTE, __dump_link_nlmsg,
 				       get_xdp_info, &xdp_id);
 	if (err)
 		return libbpf_err(err);
@@ -493,7 +493,7 @@ static int tc_qdisc_modify(struct bpf_tc_hook *hook, int cmd, int flags)
 	if (ret < 0)
 		return ret;
 
-	return libbpf_netlink_send_recv(&req, NULL, NULL, NULL);
+	return libbpf_netlink_send_recv(&req, NETLINK_ROUTE, NULL, NULL, NULL);
 }
 
 static int tc_qdisc_create_excl(struct bpf_tc_hook *hook)
@@ -673,7 +673,8 @@ int bpf_tc_attach(const struct bpf_tc_hook *hook, struct bpf_tc_opts *opts)
 
 	info.opts = opts;
 
-	ret = libbpf_netlink_send_recv(&req, get_tc_info, NULL, &info);
+	ret = libbpf_netlink_send_recv(&req, NETLINK_ROUTE, get_tc_info, NULL,
+				       &info);
 	if (ret < 0)
 		return libbpf_err(ret);
 	if (!info.processed)
@@ -739,7 +740,7 @@ static int __bpf_tc_detach(const struct bpf_tc_hook *hook,
 			return ret;
 	}
 
-	return libbpf_netlink_send_recv(&req, NULL, NULL, NULL);
+	return libbpf_netlink_send_recv(&req, NETLINK_ROUTE, NULL, NULL, NULL);
 }
 
 int bpf_tc_detach(const struct bpf_tc_hook *hook,
@@ -804,7 +805,8 @@ int bpf_tc_query(const struct bpf_tc_hook *hook, struct bpf_tc_opts *opts)
 
 	info.opts = opts;
 
-	ret = libbpf_netlink_send_recv(&req, get_tc_info, NULL, &info);
+	ret = libbpf_netlink_send_recv(&req, NETLINK_ROUTE, get_tc_info, NULL,
+				       &info);
 	if (ret < 0)
 		return libbpf_err(ret);
 	if (!info.processed)
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-wired-lan] [PATCH bpf-next 4/7] libbpf: add the capability to specify netlink proto in libbpf_netlink_send_recv
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, kuba,
	pabeni, aelior, hawk, christophe.jaillet, memxor, john, bjorn,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

This is a preliminary patch in order to introduce netlink_generic
protocol support to libbpf.

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 tools/lib/bpf/netlink.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
index 35104580870c..d2468a04a6c3 100644
--- a/tools/lib/bpf/netlink.c
+++ b/tools/lib/bpf/netlink.c
@@ -41,7 +41,7 @@ struct xdp_id_md {
 	struct xdp_link_info info;
 };
 
-static int libbpf_netlink_open(__u32 *nl_pid)
+static int libbpf_netlink_open(__u32 *nl_pid, int proto)
 {
 	struct sockaddr_nl sa;
 	socklen_t addrlen;
@@ -51,7 +51,7 @@ static int libbpf_netlink_open(__u32 *nl_pid)
 	memset(&sa, 0, sizeof(sa));
 	sa.nl_family = AF_NETLINK;
 
-	sock = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
+	sock = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, proto);
 	if (sock < 0)
 		return -errno;
 
@@ -212,14 +212,14 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
 }
 
 static int libbpf_netlink_send_recv(struct libbpf_nla_req *req,
-				    __dump_nlmsg_t parse_msg,
+				    int proto, __dump_nlmsg_t parse_msg,
 				    libbpf_dump_nlmsg_t parse_attr,
 				    void *cookie)
 {
 	__u32 nl_pid = 0;
 	int sock, ret;
 
-	sock = libbpf_netlink_open(&nl_pid);
+	sock = libbpf_netlink_open(&nl_pid, proto);
 	if (sock < 0)
 		return sock;
 
@@ -271,7 +271,7 @@ static int __bpf_set_link_xdp_fd_replace(int ifindex, int fd, int old_fd,
 	}
 	nlattr_end_nested(&req, nla);
 
-	return libbpf_netlink_send_recv(&req, NULL, NULL, NULL);
+	return libbpf_netlink_send_recv(&req, NETLINK_ROUTE, NULL, NULL, NULL);
 }
 
 int bpf_xdp_attach(int ifindex, int prog_fd, __u32 flags, const struct bpf_xdp_attach_opts *opts)
@@ -382,7 +382,7 @@ int bpf_xdp_query(int ifindex, int xdp_flags, struct bpf_xdp_query_opts *opts)
 	xdp_id.ifindex = ifindex;
 	xdp_id.flags = xdp_flags;
 
-	err = libbpf_netlink_send_recv(&req, __dump_link_nlmsg,
+	err = libbpf_netlink_send_recv(&req, NETLINK_ROUTE, __dump_link_nlmsg,
 				       get_xdp_info, &xdp_id);
 	if (err)
 		return libbpf_err(err);
@@ -493,7 +493,7 @@ static int tc_qdisc_modify(struct bpf_tc_hook *hook, int cmd, int flags)
 	if (ret < 0)
 		return ret;
 
-	return libbpf_netlink_send_recv(&req, NULL, NULL, NULL);
+	return libbpf_netlink_send_recv(&req, NETLINK_ROUTE, NULL, NULL, NULL);
 }
 
 static int tc_qdisc_create_excl(struct bpf_tc_hook *hook)
@@ -673,7 +673,8 @@ int bpf_tc_attach(const struct bpf_tc_hook *hook, struct bpf_tc_opts *opts)
 
 	info.opts = opts;
 
-	ret = libbpf_netlink_send_recv(&req, get_tc_info, NULL, &info);
+	ret = libbpf_netlink_send_recv(&req, NETLINK_ROUTE, get_tc_info, NULL,
+				       &info);
 	if (ret < 0)
 		return libbpf_err(ret);
 	if (!info.processed)
@@ -739,7 +740,7 @@ static int __bpf_tc_detach(const struct bpf_tc_hook *hook,
 			return ret;
 	}
 
-	return libbpf_netlink_send_recv(&req, NULL, NULL, NULL);
+	return libbpf_netlink_send_recv(&req, NETLINK_ROUTE, NULL, NULL, NULL);
 }
 
 int bpf_tc_detach(const struct bpf_tc_hook *hook,
@@ -804,7 +805,8 @@ int bpf_tc_query(const struct bpf_tc_hook *hook, struct bpf_tc_opts *opts)
 
 	info.opts = opts;
 
-	ret = libbpf_netlink_send_recv(&req, get_tc_info, NULL, &info);
+	ret = libbpf_netlink_send_recv(&req, NETLINK_ROUTE, get_tc_info, NULL,
+				       &info);
 	if (ret < 0)
 		return libbpf_err(ret);
 	if (!info.processed)
-- 
2.39.0

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH bpf-next 5/7] libbpf: add API to get XDP/XSK supported features
  2023-01-20 17:16 ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: netdev, ast, daniel, andrii, davem, kuba, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

Extend bpf_xdp_query routine in order to get XDP/XSK supported features
of netdev over route netlink interface.
Extend libbpf netlink implementation in order to support netlink_generic
protocol.

Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Co-developed-by: Marek Majtyka <alardam@gmail.com>
Signed-off-by: Marek Majtyka <alardam@gmail.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 tools/lib/bpf/libbpf.h  |  3 +-
 tools/lib/bpf/netlink.c | 99 +++++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/nlattr.h  | 12 +++++
 3 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 898db26e42e9..29cb7040fa77 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -982,9 +982,10 @@ struct bpf_xdp_query_opts {
 	__u32 hw_prog_id;	/* output */
 	__u32 skb_prog_id;	/* output */
 	__u8 attach_mode;	/* output */
+	__u64 fflags;		/* output */
 	size_t :0;
 };
-#define bpf_xdp_query_opts__last_field attach_mode
+#define bpf_xdp_query_opts__last_field fflags
 
 LIBBPF_API int bpf_xdp_attach(int ifindex, int prog_fd, __u32 flags,
 			      const struct bpf_xdp_attach_opts *opts);
diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
index d2468a04a6c3..67d6795f4c0a 100644
--- a/tools/lib/bpf/netlink.c
+++ b/tools/lib/bpf/netlink.c
@@ -9,6 +9,7 @@
 #include <linux/if_ether.h>
 #include <linux/pkt_cls.h>
 #include <linux/rtnetlink.h>
+#include <linux/netdev.h>
 #include <sys/socket.h>
 #include <errno.h>
 #include <time.h>
@@ -39,6 +40,12 @@ struct xdp_id_md {
 	int ifindex;
 	__u32 flags;
 	struct xdp_link_info info;
+	__u64 fflags;
+};
+
+struct xdp_features_md {
+	int ifindex;
+	__u64 flags;
 };
 
 static int libbpf_netlink_open(__u32 *nl_pid, int proto)
@@ -238,6 +245,43 @@ static int libbpf_netlink_send_recv(struct libbpf_nla_req *req,
 	return ret;
 }
 
+static int parse_genl_family_id(struct nlmsghdr *nh, libbpf_dump_nlmsg_t fn,
+				void *cookie)
+{
+	struct genlmsghdr *gnl = NLMSG_DATA(nh);
+	struct nlattr *na = (struct nlattr *)((void *)gnl + GENL_HDRLEN);
+	struct nlattr *tb[CTRL_ATTR_FAMILY_ID + 1];
+	__u16 *id = cookie;
+
+	libbpf_nla_parse(tb, CTRL_ATTR_FAMILY_ID, na,
+			 NLMSG_PAYLOAD(nh, sizeof(*gnl)), NULL);
+	if (!tb[CTRL_ATTR_FAMILY_ID])
+		return NL_CONT;
+
+	*id = libbpf_nla_getattr_u16(tb[CTRL_ATTR_FAMILY_ID]);
+	return NL_DONE;
+}
+
+static int libbpf_netlink_resolve_genl_family_id(const char *name,
+						 __u16 len, __u16 *id)
+{
+	struct libbpf_nla_req req = {
+		.nh.nlmsg_len	= NLMSG_LENGTH(GENL_HDRLEN),
+		.nh.nlmsg_type	= GENL_ID_CTRL,
+		.nh.nlmsg_flags	= NLM_F_REQUEST,
+		.gnl.cmd	= CTRL_CMD_GETFAMILY,
+		.gnl.version	= 1,
+	};
+	int err;
+
+	err = nlattr_add(&req, CTRL_ATTR_FAMILY_NAME, name, len);
+	if (err < 0)
+		return err;
+
+	return libbpf_netlink_send_recv(&req, NETLINK_GENERIC,
+					parse_genl_family_id, NULL, id);
+}
+
 static int __bpf_set_link_xdp_fd_replace(int ifindex, int fd, int old_fd,
 					 __u32 flags)
 {
@@ -357,6 +401,29 @@ static int get_xdp_info(void *cookie, void *msg, struct nlattr **tb)
 	return 0;
 }
 
+static int parse_xdp_features(struct nlmsghdr *nh, libbpf_dump_nlmsg_t fn,
+			      void *cookie)
+{
+	struct genlmsghdr *gnl = NLMSG_DATA(nh);
+	struct nlattr *na = (struct nlattr *)((void *)gnl + GENL_HDRLEN);
+	struct nlattr *tb[NETDEV_CMD_MAX + 1];
+	struct xdp_features_md *md = cookie;
+	__u32 ifindex;
+
+	libbpf_nla_parse(tb, NETDEV_CMD_MAX, na,
+			 NLMSG_PAYLOAD(nh, sizeof(*gnl)), NULL);
+
+	if (!tb[NETDEV_A_DEV_IFINDEX] || !tb[NETDEV_A_DEV_XDP_FEATURES])
+		return NL_CONT;
+
+	ifindex = libbpf_nla_getattr_u32(tb[NETDEV_A_DEV_IFINDEX]);
+	if (ifindex != md->ifindex)
+		return NL_CONT;
+
+	md->flags = libbpf_nla_getattr_u64(tb[NETDEV_A_DEV_XDP_FEATURES]);
+	return NL_DONE;
+}
+
 int bpf_xdp_query(int ifindex, int xdp_flags, struct bpf_xdp_query_opts *opts)
 {
 	struct libbpf_nla_req req = {
@@ -393,6 +460,38 @@ int bpf_xdp_query(int ifindex, int xdp_flags, struct bpf_xdp_query_opts *opts)
 	OPTS_SET(opts, skb_prog_id, xdp_id.info.skb_prog_id);
 	OPTS_SET(opts, attach_mode, xdp_id.info.attach_mode);
 
+	if (OPTS_HAS(opts, fflags)) {
+		struct xdp_features_md md = {
+			.ifindex = ifindex,
+		};
+		__u16 id;
+
+		err = libbpf_netlink_resolve_genl_family_id("netdev",
+							    sizeof("netdev"),
+							    &id);
+		if (err < 0)
+			return libbpf_err(err);
+
+		memset(&req, 0, sizeof(req));
+		req.nh.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
+		req.nh.nlmsg_flags = NLM_F_REQUEST;
+		req.nh.nlmsg_type = id;
+		req.gnl.cmd = NETDEV_CMD_DEV_GET;
+		req.gnl.version = 1;
+
+		err = nlattr_add(&req, NETDEV_A_DEV_IFINDEX, &ifindex,
+				 sizeof(ifindex));
+		if (err < 0)
+			return err;
+
+		err = libbpf_netlink_send_recv(&req, NETLINK_GENERIC,
+					       parse_xdp_features, NULL, &md);
+		if (err)
+			return libbpf_err(err);
+
+		opts->fflags = md.flags;
+	}
+
 	return 0;
 }
 
diff --git a/tools/lib/bpf/nlattr.h b/tools/lib/bpf/nlattr.h
index 4d15ae2ff812..d92d1c1de700 100644
--- a/tools/lib/bpf/nlattr.h
+++ b/tools/lib/bpf/nlattr.h
@@ -14,6 +14,7 @@
 #include <errno.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <linux/genetlink.h>
 
 /* avoid multiple definition of netlink features */
 #define __LINUX_NETLINK_H
@@ -58,6 +59,7 @@ struct libbpf_nla_req {
 	union {
 		struct ifinfomsg ifinfo;
 		struct tcmsg tc;
+		struct genlmsghdr gnl;
 	};
 	char buf[128];
 };
@@ -89,11 +91,21 @@ static inline uint8_t libbpf_nla_getattr_u8(const struct nlattr *nla)
 	return *(uint8_t *)libbpf_nla_data(nla);
 }
 
+static inline uint16_t libbpf_nla_getattr_u16(const struct nlattr *nla)
+{
+	return *(uint16_t *)libbpf_nla_data(nla);
+}
+
 static inline uint32_t libbpf_nla_getattr_u32(const struct nlattr *nla)
 {
 	return *(uint32_t *)libbpf_nla_data(nla);
 }
 
+static inline uint64_t libbpf_nla_getattr_u64(const struct nlattr *nla)
+{
+	return *(uint64_t *)libbpf_nla_data(nla);
+}
+
 static inline const char *libbpf_nla_getattr_str(const struct nlattr *nla)
 {
 	return (const char *)libbpf_nla_data(nla);
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-wired-lan] [PATCH bpf-next 5/7] libbpf: add API to get XDP/XSK supported features
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, kuba,
	pabeni, aelior, hawk, christophe.jaillet, memxor, john, bjorn,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

Extend bpf_xdp_query routine in order to get XDP/XSK supported features
of netdev over route netlink interface.
Extend libbpf netlink implementation in order to support netlink_generic
protocol.

Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Co-developed-by: Marek Majtyka <alardam@gmail.com>
Signed-off-by: Marek Majtyka <alardam@gmail.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 tools/lib/bpf/libbpf.h  |  3 +-
 tools/lib/bpf/netlink.c | 99 +++++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/nlattr.h  | 12 +++++
 3 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 898db26e42e9..29cb7040fa77 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -982,9 +982,10 @@ struct bpf_xdp_query_opts {
 	__u32 hw_prog_id;	/* output */
 	__u32 skb_prog_id;	/* output */
 	__u8 attach_mode;	/* output */
+	__u64 fflags;		/* output */
 	size_t :0;
 };
-#define bpf_xdp_query_opts__last_field attach_mode
+#define bpf_xdp_query_opts__last_field fflags
 
 LIBBPF_API int bpf_xdp_attach(int ifindex, int prog_fd, __u32 flags,
 			      const struct bpf_xdp_attach_opts *opts);
diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
index d2468a04a6c3..67d6795f4c0a 100644
--- a/tools/lib/bpf/netlink.c
+++ b/tools/lib/bpf/netlink.c
@@ -9,6 +9,7 @@
 #include <linux/if_ether.h>
 #include <linux/pkt_cls.h>
 #include <linux/rtnetlink.h>
+#include <linux/netdev.h>
 #include <sys/socket.h>
 #include <errno.h>
 #include <time.h>
@@ -39,6 +40,12 @@ struct xdp_id_md {
 	int ifindex;
 	__u32 flags;
 	struct xdp_link_info info;
+	__u64 fflags;
+};
+
+struct xdp_features_md {
+	int ifindex;
+	__u64 flags;
 };
 
 static int libbpf_netlink_open(__u32 *nl_pid, int proto)
@@ -238,6 +245,43 @@ static int libbpf_netlink_send_recv(struct libbpf_nla_req *req,
 	return ret;
 }
 
+static int parse_genl_family_id(struct nlmsghdr *nh, libbpf_dump_nlmsg_t fn,
+				void *cookie)
+{
+	struct genlmsghdr *gnl = NLMSG_DATA(nh);
+	struct nlattr *na = (struct nlattr *)((void *)gnl + GENL_HDRLEN);
+	struct nlattr *tb[CTRL_ATTR_FAMILY_ID + 1];
+	__u16 *id = cookie;
+
+	libbpf_nla_parse(tb, CTRL_ATTR_FAMILY_ID, na,
+			 NLMSG_PAYLOAD(nh, sizeof(*gnl)), NULL);
+	if (!tb[CTRL_ATTR_FAMILY_ID])
+		return NL_CONT;
+
+	*id = libbpf_nla_getattr_u16(tb[CTRL_ATTR_FAMILY_ID]);
+	return NL_DONE;
+}
+
+static int libbpf_netlink_resolve_genl_family_id(const char *name,
+						 __u16 len, __u16 *id)
+{
+	struct libbpf_nla_req req = {
+		.nh.nlmsg_len	= NLMSG_LENGTH(GENL_HDRLEN),
+		.nh.nlmsg_type	= GENL_ID_CTRL,
+		.nh.nlmsg_flags	= NLM_F_REQUEST,
+		.gnl.cmd	= CTRL_CMD_GETFAMILY,
+		.gnl.version	= 1,
+	};
+	int err;
+
+	err = nlattr_add(&req, CTRL_ATTR_FAMILY_NAME, name, len);
+	if (err < 0)
+		return err;
+
+	return libbpf_netlink_send_recv(&req, NETLINK_GENERIC,
+					parse_genl_family_id, NULL, id);
+}
+
 static int __bpf_set_link_xdp_fd_replace(int ifindex, int fd, int old_fd,
 					 __u32 flags)
 {
@@ -357,6 +401,29 @@ static int get_xdp_info(void *cookie, void *msg, struct nlattr **tb)
 	return 0;
 }
 
+static int parse_xdp_features(struct nlmsghdr *nh, libbpf_dump_nlmsg_t fn,
+			      void *cookie)
+{
+	struct genlmsghdr *gnl = NLMSG_DATA(nh);
+	struct nlattr *na = (struct nlattr *)((void *)gnl + GENL_HDRLEN);
+	struct nlattr *tb[NETDEV_CMD_MAX + 1];
+	struct xdp_features_md *md = cookie;
+	__u32 ifindex;
+
+	libbpf_nla_parse(tb, NETDEV_CMD_MAX, na,
+			 NLMSG_PAYLOAD(nh, sizeof(*gnl)), NULL);
+
+	if (!tb[NETDEV_A_DEV_IFINDEX] || !tb[NETDEV_A_DEV_XDP_FEATURES])
+		return NL_CONT;
+
+	ifindex = libbpf_nla_getattr_u32(tb[NETDEV_A_DEV_IFINDEX]);
+	if (ifindex != md->ifindex)
+		return NL_CONT;
+
+	md->flags = libbpf_nla_getattr_u64(tb[NETDEV_A_DEV_XDP_FEATURES]);
+	return NL_DONE;
+}
+
 int bpf_xdp_query(int ifindex, int xdp_flags, struct bpf_xdp_query_opts *opts)
 {
 	struct libbpf_nla_req req = {
@@ -393,6 +460,38 @@ int bpf_xdp_query(int ifindex, int xdp_flags, struct bpf_xdp_query_opts *opts)
 	OPTS_SET(opts, skb_prog_id, xdp_id.info.skb_prog_id);
 	OPTS_SET(opts, attach_mode, xdp_id.info.attach_mode);
 
+	if (OPTS_HAS(opts, fflags)) {
+		struct xdp_features_md md = {
+			.ifindex = ifindex,
+		};
+		__u16 id;
+
+		err = libbpf_netlink_resolve_genl_family_id("netdev",
+							    sizeof("netdev"),
+							    &id);
+		if (err < 0)
+			return libbpf_err(err);
+
+		memset(&req, 0, sizeof(req));
+		req.nh.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
+		req.nh.nlmsg_flags = NLM_F_REQUEST;
+		req.nh.nlmsg_type = id;
+		req.gnl.cmd = NETDEV_CMD_DEV_GET;
+		req.gnl.version = 1;
+
+		err = nlattr_add(&req, NETDEV_A_DEV_IFINDEX, &ifindex,
+				 sizeof(ifindex));
+		if (err < 0)
+			return err;
+
+		err = libbpf_netlink_send_recv(&req, NETLINK_GENERIC,
+					       parse_xdp_features, NULL, &md);
+		if (err)
+			return libbpf_err(err);
+
+		opts->fflags = md.flags;
+	}
+
 	return 0;
 }
 
diff --git a/tools/lib/bpf/nlattr.h b/tools/lib/bpf/nlattr.h
index 4d15ae2ff812..d92d1c1de700 100644
--- a/tools/lib/bpf/nlattr.h
+++ b/tools/lib/bpf/nlattr.h
@@ -14,6 +14,7 @@
 #include <errno.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <linux/genetlink.h>
 
 /* avoid multiple definition of netlink features */
 #define __LINUX_NETLINK_H
@@ -58,6 +59,7 @@ struct libbpf_nla_req {
 	union {
 		struct ifinfomsg ifinfo;
 		struct tcmsg tc;
+		struct genlmsghdr gnl;
 	};
 	char buf[128];
 };
@@ -89,11 +91,21 @@ static inline uint8_t libbpf_nla_getattr_u8(const struct nlattr *nla)
 	return *(uint8_t *)libbpf_nla_data(nla);
 }
 
+static inline uint16_t libbpf_nla_getattr_u16(const struct nlattr *nla)
+{
+	return *(uint16_t *)libbpf_nla_data(nla);
+}
+
 static inline uint32_t libbpf_nla_getattr_u32(const struct nlattr *nla)
 {
 	return *(uint32_t *)libbpf_nla_data(nla);
 }
 
+static inline uint64_t libbpf_nla_getattr_u64(const struct nlattr *nla)
+{
+	return *(uint64_t *)libbpf_nla_data(nla);
+}
+
 static inline const char *libbpf_nla_getattr_str(const struct nlattr *nla)
 {
 	return (const char *)libbpf_nla_data(nla);
-- 
2.39.0

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH bpf-next 6/7] bpf: devmap: check XDP features in bpf_map_update_elem and __xdp_enqueue
  2023-01-20 17:16 ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: netdev, ast, daniel, andrii, davem, kuba, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

When we update devmap element, the net_device whose ifindex is specified
in map value must support ndo_xdp_xmit callback, which is indicated by
the presence of XDP_F_REDIRECT_TARGET feature. Let's check for
this feature and return an error if device cannot be used as a redirect
target.

Moreover check the device support xdp non-linear frame in __xdp_enqueue
and is_valid_dst routines. This patch allows to perfrom XDP_REDIRECT on
non-linear xdp buffers.

Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 kernel/bpf/devmap.c | 25 +++++++++++++++++++++----
 net/core/filter.c   | 13 +++++--------
 2 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
index d01e4c55b376..69ceecc792df 100644
--- a/kernel/bpf/devmap.c
+++ b/kernel/bpf/devmap.c
@@ -474,7 +474,11 @@ static inline int __xdp_enqueue(struct net_device *dev, struct xdp_frame *xdpf,
 {
 	int err;
 
-	if (!dev->netdev_ops->ndo_xdp_xmit)
+	if (!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))
+		return -EOPNOTSUPP;
+
+	if (unlikely(!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT_SG) &&
+		     xdp_frame_has_frags(xdpf)))
 		return -EOPNOTSUPP;
 
 	err = xdp_ok_fwd_dev(dev, xdp_get_frame_len(xdpf));
@@ -532,8 +536,14 @@ int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_frame *xdpf,
 
 static bool is_valid_dst(struct bpf_dtab_netdev *obj, struct xdp_frame *xdpf)
 {
-	if (!obj ||
-	    !obj->dev->netdev_ops->ndo_xdp_xmit)
+	if (!obj)
+		return false;
+
+	if (!(obj->dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))
+		return false;
+
+	if (unlikely(!(obj->dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT_SG) &&
+		     xdp_frame_has_frags(xdpf)))
 		return false;
 
 	if (xdp_ok_fwd_dev(obj->dev, xdp_get_frame_len(xdpf)))
@@ -843,6 +853,7 @@ static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,
 {
 	struct bpf_prog *prog = NULL;
 	struct bpf_dtab_netdev *dev;
+	int ret = -EINVAL;
 
 	dev = bpf_map_kmalloc_node(&dtab->map, sizeof(*dev),
 				   GFP_NOWAIT | __GFP_NOWARN,
@@ -854,6 +865,12 @@ static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,
 	if (!dev->dev)
 		goto err_out;
 
+	/* Check if net_device can be used as a redirect target */
+	if (!(READ_ONCE(dev->dev->xdp_features) & NETDEV_XDP_ACT_NDO_XMIT)) {
+		ret = -EOPNOTSUPP;
+		goto err_put_dev;
+	}
+
 	if (val->bpf_prog.fd > 0) {
 		prog = bpf_prog_get_type_dev(val->bpf_prog.fd,
 					     BPF_PROG_TYPE_XDP, false);
@@ -882,7 +899,7 @@ static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,
 	dev_put(dev->dev);
 err_out:
 	kfree(dev);
-	return ERR_PTR(-EINVAL);
+	return ERR_PTR(ret);
 }
 
 static int __dev_map_update_elem(struct net *net, struct bpf_map *map,
diff --git a/net/core/filter.c b/net/core/filter.c
index b4547a2c02f4..c1e12e8502e9 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -4314,16 +4314,13 @@ int xdp_do_redirect(struct net_device *dev, struct xdp_buff *xdp,
 	struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
 	enum bpf_map_type map_type = ri->map_type;
 
-	/* XDP_REDIRECT is not fully supported yet for xdp frags since
-	 * not all XDP capable drivers can map non-linear xdp_frame in
-	 * ndo_xdp_xmit.
-	 */
-	if (unlikely(xdp_buff_has_frags(xdp) &&
-		     map_type != BPF_MAP_TYPE_CPUMAP))
-		return -EOPNOTSUPP;
+	if (map_type == BPF_MAP_TYPE_XSKMAP) {
+		/* XDP_REDIRECT is not supported AF_XDP yet. */
+		if (unlikely(xdp_buff_has_frags(xdp)))
+			return -EOPNOTSUPP;
 
-	if (map_type == BPF_MAP_TYPE_XSKMAP)
 		return __xdp_do_redirect_xsk(ri, dev, xdp, xdp_prog);
+	}
 
 	return __xdp_do_redirect_frame(ri, dev, xdp_convert_buff_to_frame(xdp),
 				       xdp_prog);
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-wired-lan] [PATCH bpf-next 6/7] bpf: devmap: check XDP features in bpf_map_update_elem and __xdp_enqueue
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, kuba,
	pabeni, aelior, hawk, christophe.jaillet, memxor, john, bjorn,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

When we update devmap element, the net_device whose ifindex is specified
in map value must support ndo_xdp_xmit callback, which is indicated by
the presence of XDP_F_REDIRECT_TARGET feature. Let's check for
this feature and return an error if device cannot be used as a redirect
target.

Moreover check the device support xdp non-linear frame in __xdp_enqueue
and is_valid_dst routines. This patch allows to perfrom XDP_REDIRECT on
non-linear xdp buffers.

Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 kernel/bpf/devmap.c | 25 +++++++++++++++++++++----
 net/core/filter.c   | 13 +++++--------
 2 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
index d01e4c55b376..69ceecc792df 100644
--- a/kernel/bpf/devmap.c
+++ b/kernel/bpf/devmap.c
@@ -474,7 +474,11 @@ static inline int __xdp_enqueue(struct net_device *dev, struct xdp_frame *xdpf,
 {
 	int err;
 
-	if (!dev->netdev_ops->ndo_xdp_xmit)
+	if (!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))
+		return -EOPNOTSUPP;
+
+	if (unlikely(!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT_SG) &&
+		     xdp_frame_has_frags(xdpf)))
 		return -EOPNOTSUPP;
 
 	err = xdp_ok_fwd_dev(dev, xdp_get_frame_len(xdpf));
@@ -532,8 +536,14 @@ int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_frame *xdpf,
 
 static bool is_valid_dst(struct bpf_dtab_netdev *obj, struct xdp_frame *xdpf)
 {
-	if (!obj ||
-	    !obj->dev->netdev_ops->ndo_xdp_xmit)
+	if (!obj)
+		return false;
+
+	if (!(obj->dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))
+		return false;
+
+	if (unlikely(!(obj->dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT_SG) &&
+		     xdp_frame_has_frags(xdpf)))
 		return false;
 
 	if (xdp_ok_fwd_dev(obj->dev, xdp_get_frame_len(xdpf)))
@@ -843,6 +853,7 @@ static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,
 {
 	struct bpf_prog *prog = NULL;
 	struct bpf_dtab_netdev *dev;
+	int ret = -EINVAL;
 
 	dev = bpf_map_kmalloc_node(&dtab->map, sizeof(*dev),
 				   GFP_NOWAIT | __GFP_NOWARN,
@@ -854,6 +865,12 @@ static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,
 	if (!dev->dev)
 		goto err_out;
 
+	/* Check if net_device can be used as a redirect target */
+	if (!(READ_ONCE(dev->dev->xdp_features) & NETDEV_XDP_ACT_NDO_XMIT)) {
+		ret = -EOPNOTSUPP;
+		goto err_put_dev;
+	}
+
 	if (val->bpf_prog.fd > 0) {
 		prog = bpf_prog_get_type_dev(val->bpf_prog.fd,
 					     BPF_PROG_TYPE_XDP, false);
@@ -882,7 +899,7 @@ static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,
 	dev_put(dev->dev);
 err_out:
 	kfree(dev);
-	return ERR_PTR(-EINVAL);
+	return ERR_PTR(ret);
 }
 
 static int __dev_map_update_elem(struct net *net, struct bpf_map *map,
diff --git a/net/core/filter.c b/net/core/filter.c
index b4547a2c02f4..c1e12e8502e9 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -4314,16 +4314,13 @@ int xdp_do_redirect(struct net_device *dev, struct xdp_buff *xdp,
 	struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
 	enum bpf_map_type map_type = ri->map_type;
 
-	/* XDP_REDIRECT is not fully supported yet for xdp frags since
-	 * not all XDP capable drivers can map non-linear xdp_frame in
-	 * ndo_xdp_xmit.
-	 */
-	if (unlikely(xdp_buff_has_frags(xdp) &&
-		     map_type != BPF_MAP_TYPE_CPUMAP))
-		return -EOPNOTSUPP;
+	if (map_type == BPF_MAP_TYPE_XSKMAP) {
+		/* XDP_REDIRECT is not supported AF_XDP yet. */
+		if (unlikely(xdp_buff_has_frags(xdp)))
+			return -EOPNOTSUPP;
 
-	if (map_type == BPF_MAP_TYPE_XSKMAP)
 		return __xdp_do_redirect_xsk(ri, dev, xdp, xdp_prog);
+	}
 
 	return __xdp_do_redirect_frame(ri, dev, xdp_convert_buff_to_frame(xdp),
 				       xdp_prog);
-- 
2.39.0

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH bpf-next 7/7] selftests/bpf: introduce XDP compliance test tool
  2023-01-20 17:16 ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: netdev, ast, daniel, andrii, davem, kuba, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

Introduce xdp_features tool in order to test XDP features supported by
the NIC and match them against advertised ones.
In order to test supported/advertised XDP features, xdp_features must
run on the Device Under Test (DUT) and on a Tester device.
xdp_features opens a control TCP channel between DUT and Tester devices
to send control commands from Tester to the DUT and a UDP data channel
where the Tester sends UDP 'echo' packets and the DUT is expected to
reply back with the same packet. DUT installs multiple XDP programs on the
NIC to test XDP capabilities and reports back to the Tester some XDP stats.
Currently xdp_features supports the following XDP features:
- XDP_DROP
- XDP_PASS
- XDP_TX
- XDP_REDIRECT
- XDP_REDIRECT_TARGET

Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 tools/testing/selftests/bpf/Makefile          |   5 +-
 .../selftests/bpf/progs/test_xdp_features.c   | 237 ++++++
 .../selftests/bpf/test_xdp_features.sh        |  99 +++
 tools/testing/selftests/bpf/xdp_features.c    | 743 ++++++++++++++++++
 4 files changed, 1082 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/progs/test_xdp_features.c
 create mode 100755 tools/testing/selftests/bpf/test_xdp_features.sh
 create mode 100644 tools/testing/selftests/bpf/xdp_features.c

diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 22533a18705e..071cd064625d 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -73,7 +73,8 @@ TEST_PROGS := test_kmod.sh \
 	test_bpftool.sh \
 	test_bpftool_metadata.sh \
 	test_doc_build.sh \
-	test_xsk.sh
+	test_xsk.sh \
+	test_xdp_features.sh
 
 TEST_PROGS_EXTENDED := with_addr.sh \
 	with_tunnels.sh ima_setup.sh verify_sig_setup.sh \
@@ -83,7 +84,7 @@ TEST_PROGS_EXTENDED := with_addr.sh \
 TEST_GEN_PROGS_EXTENDED = test_sock_addr test_skb_cgroup_id_user \
 	flow_dissector_load test_flow_dissector test_tcp_check_syncookie_user \
 	test_lirc_mode2_user xdping test_cpp runqslower bench bpf_testmod.ko \
-	xskxceiver xdp_redirect_multi xdp_synproxy veristat
+	xskxceiver xdp_redirect_multi xdp_synproxy veristat xdp_features
 
 TEST_CUSTOM_PROGS = $(OUTPUT)/urandom_read $(OUTPUT)/sign-file
 TEST_GEN_FILES += liburandom_read.so
diff --git a/tools/testing/selftests/bpf/progs/test_xdp_features.c b/tools/testing/selftests/bpf/progs/test_xdp_features.c
new file mode 100644
index 000000000000..40f2a3e8c4e9
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/test_xdp_features.c
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <stdbool.h>
+#include <linux/bpf.h>
+#include <linux/netdev.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
+#include <bpf/bpf_tracing.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/udp.h>
+#include <asm-generic/errno-base.h>
+
+#define BIT(x)	(1 << (x))
+
+struct xdp_cpumap_stats {
+	unsigned int redirect;
+	unsigned int pass;
+	unsigned int drop;
+};
+
+struct {
+	__uint(type, BPF_MAP_TYPE_ARRAY);
+	__type(key, __u32);
+	__type(value, __u32);
+	__uint(max_entries, 1);
+} stats SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_ARRAY);
+	__type(key, __u32);
+	__type(value, __u32);
+	__uint(max_entries, 1);
+} dut_stats SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_CPUMAP);
+	__uint(key_size, sizeof(__u32));
+	__uint(value_size, sizeof(struct bpf_cpumap_val));
+	__uint(max_entries, 1);
+} cpu_map SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_DEVMAP);
+	__uint(key_size, sizeof(__u32));
+	__uint(value_size, sizeof(struct bpf_devmap_val));
+	__uint(max_entries, 1);
+} dev_map SEC(".maps");
+
+const volatile __u32 expected_feature = NETDEV_XDP_ACT_PASS;
+const volatile __be32 tester_ip;
+const volatile __be32 dut_ip;
+
+#define ECHO_PORT	12346
+
+/* test commands */
+enum test_commands {
+	CMD_STOP,		/* CMD */
+	CMD_START,		/* CMD + xdp feature */
+	CMD_ECHO,		/* CMD */
+	CMD_ACK,		/* CMD + data */
+	CMD_GET_XDP_CAP,	/* CMD */
+	CMD_GET_STATS,		/* CMD */
+};
+
+struct tlv_hdr {
+	__be16 type;
+	__be16 len;
+	__be32 data[];
+};
+
+static __always_inline int xdp_process_echo_packet(struct xdp_md *xdp, bool dut)
+{
+	void *data_end = (void *)(long)xdp->data_end;
+	__be32 saddr = dut ? tester_ip : dut_ip;
+	__be32 daddr = dut ? dut_ip : tester_ip;
+	void *data = (void *)(long)xdp->data;
+	struct ethhdr *eh = data;
+	struct tlv_hdr *tlv;
+	struct udphdr *uh;
+	struct iphdr *ih;
+	__be16 port;
+	__u8 *cmd;
+
+	if (eh + 1 > (struct ethhdr *)data_end)
+		return -EINVAL;
+
+	if (eh->h_proto != bpf_htons(ETH_P_IP))
+		return -EINVAL;
+
+	ih = (struct iphdr *)(eh + 1);
+	if (ih + 1 > (struct iphdr *)data_end)
+		return -EINVAL;
+
+	if (saddr != ih->saddr)
+		return -EINVAL;
+
+	if (daddr != ih->daddr)
+		return -EINVAL;
+
+	if (ih->protocol != IPPROTO_UDP)
+		return -EINVAL;
+
+	uh = (struct udphdr *)(ih + 1);
+	if (uh + 1 > (struct udphdr *)data_end)
+		return -EINVAL;
+
+	port = dut ? uh->dest : uh->source;
+	if (port != bpf_htons(ECHO_PORT))
+		return -EINVAL;
+
+	tlv = (struct tlv_hdr *)(uh + 1);
+	if (tlv + 1 > data_end)
+		return -EINVAL;
+
+	return bpf_htons(tlv->type) == CMD_ECHO ? 0 : -EINVAL;
+}
+
+SEC("xdp")
+int xdp_tester(struct xdp_md *xdp)
+{
+	__u32 *val, key = 0;
+
+	switch (expected_feature) {
+	case NETDEV_XDP_ACT_NDO_XMIT:
+	case NETDEV_XDP_ACT_TX:
+		if (xdp_process_echo_packet(xdp, true))
+			goto out;
+		break;
+	case NETDEV_XDP_ACT_DROP:
+	case NETDEV_XDP_ACT_PASS:
+	case NETDEV_XDP_ACT_REDIRECT:
+		if (xdp_process_echo_packet(xdp, false))
+			goto out;
+		break;
+	default:
+		goto out;
+	}
+
+	val = bpf_map_lookup_elem(&stats, &key);
+	if (val)
+		__sync_add_and_fetch(val, 1);
+
+out:
+	return XDP_PASS;
+}
+
+SEC("xdp")
+int xdp_do_pass(struct xdp_md *xdp)
+{
+	__u32 *val, key = 0;
+
+	val = bpf_map_lookup_elem(&dut_stats, &key);
+	if (val)
+		__sync_add_and_fetch(val, 1);
+
+	return XDP_PASS;
+}
+
+SEC("xdp")
+int xdp_do_drop(struct xdp_md *xdp)
+{
+	__u32 *val, key = 0;
+
+	if (xdp_process_echo_packet(xdp, true))
+		return XDP_PASS;
+
+	val = bpf_map_lookup_elem(&dut_stats, &key);
+	if (val)
+		__sync_add_and_fetch(val, 1);
+
+	return XDP_DROP;
+}
+
+SEC("xdp")
+int xdp_do_tx(struct xdp_md *xdp)
+{
+	void *data = (void *)(long)xdp->data;
+	struct ethhdr *eh = data;
+	__u8 tmp_mac[ETH_ALEN];
+	__u32 *val, key = 0;
+
+	if (xdp_process_echo_packet(xdp, true))
+		return XDP_PASS;
+
+	__builtin_memcpy(tmp_mac, eh->h_source, ETH_ALEN);
+	__builtin_memcpy(eh->h_source, eh->h_dest, ETH_ALEN);
+	__builtin_memcpy(eh->h_dest, tmp_mac, ETH_ALEN);
+
+	val = bpf_map_lookup_elem(&dut_stats, &key);
+	if (val)
+		__sync_add_and_fetch(val, 1);
+
+	return XDP_TX;
+}
+
+SEC("xdp")
+int xdp_do_redirect(struct xdp_md *xdp)
+{
+	if (xdp_process_echo_packet(xdp, true))
+		return XDP_PASS;
+
+	return bpf_redirect_map(&cpu_map, 0, 0);
+}
+
+SEC("tp_btf/xdp_cpumap_kthread")
+int BPF_PROG(tp_xdp_cpumap_kthread, int map_id, unsigned int processed,
+	     unsigned int drops, int sched, struct xdp_cpumap_stats *xdp_stats)
+{
+	__u32 *val, key = 0;
+
+	val = bpf_map_lookup_elem(&dut_stats, &key);
+	if (val)
+		__sync_add_and_fetch(val, 1);
+
+	return 0;
+}
+
+SEC("xdp/cpumap")
+int xdp_do_redirect_cpumap(struct xdp_md *xdp)
+{
+	void *data = (void *)(long)xdp->data;
+	struct ethhdr *eh = data;
+	__u8 tmp_mac[ETH_ALEN];
+
+	if (xdp_process_echo_packet(xdp, true))
+		return XDP_PASS;
+
+	__builtin_memcpy(tmp_mac, eh->h_source, ETH_ALEN);
+	__builtin_memcpy(eh->h_source, eh->h_dest, ETH_ALEN);
+	__builtin_memcpy(eh->h_dest, tmp_mac, ETH_ALEN);
+
+	return bpf_redirect_map(&dev_map, 0, 0);
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_xdp_features.sh b/tools/testing/selftests/bpf/test_xdp_features.sh
new file mode 100755
index 000000000000..98b8fd2b6c16
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_xdp_features.sh
@@ -0,0 +1,99 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+# Create 2 namespaces with two veth peers, and
+# check reported and detected XDP capabilities
+#
+#   NS0(v00)              NS1(v11)
+#       |                     |
+#       |                     |
+# (v01, id:111)  ------  (v10,id:222)
+
+readonly NS0="ns1-$(mktemp -u XXXXXX)"
+readonly NS1="ns2-$(mktemp -u XXXXXX)"
+ret=1
+
+setup() {
+	{
+		ip netns add ${NS0}
+		ip netns add ${NS1}
+
+		ip link add v01 index 111 type veth peer name v00 netns ${NS0}
+		ip link add v10 index 222 type veth peer name v11 netns ${NS1}
+
+		ip link set v01 up
+		ip addr add 10.10.0.1/24 dev v01
+		ip link set v01 address 00:11:22:33:44:55
+		ip -n ${NS0} link set dev v00 up
+		ip -n ${NS0} addr add 10.10.0.11/24 dev v00
+		ip -n ${NS0} route add default via 10.10.0.1
+		ip -n ${NS0} link set v00 address 00:12:22:33:44:55
+
+		ip link set v10 up
+		ip addr add 10.10.1.1/24 dev v10
+		ip link set v10 address 00:13:22:33:44:55
+		ip -n ${NS1} link set dev v11 up
+		ip -n ${NS1} addr add 10.10.1.11/24 dev v11
+		ip -n ${NS1} route add default via 10.10.1.1
+		ip -n ${NS1} link set v11 address 00:14:22:33:44:55
+
+		sysctl -w net.ipv4.ip_forward=1
+		# Enable XDP mode
+		ethtool -K v01 gro on
+		ethtool -K v01 tx-checksumming off
+		ip netns exec ${NS0} ethtool -K v00 gro on
+		ip netns exec ${NS0} ethtool -K v00 tx-checksumming off
+		ethtool -K v10 gro on
+		ethtool -K v10 tx-checksumming off
+		ip netns exec ${NS1} ethtool -K v11 gro on
+		ip netns exec ${NS1} ethtool -K v11 tx-checksumming off
+	} > /dev/null 2>&1
+}
+
+cleanup() {
+	ip link del v01 2> /dev/null
+	ip link del v10 2> /dev/null
+	ip netns del ${NS0} 2> /dev/null
+	ip netns del ${NS1} 2> /dev/null
+	[ "$(pidof xdp_features)" = "" ] || kill $(pidof xdp_features) 2> /dev/null
+}
+
+test_xdp_features() {
+	setup
+
+	## XDP_PASS
+	ip netns exec ${NS1} ./xdp_features -f XDP_PASS -D 10.10.1.11 -T 10.10.0.11 v11 &
+	ip netns exec ${NS0} ./xdp_features -t -f XDP_PASS -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
+
+	[ $? -ne 0 ] && exit
+
+	# XDP_DROP
+	ip netns exec ${NS1} ./xdp_features -f XDP_DROP -D 10.10.1.11 -T 10.10.0.11 v11 &
+	ip netns exec ${NS0} ./xdp_features -t -f XDP_DROP -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
+
+	[ $? -ne 0 ] && exit
+
+	## XDP_TX
+	./xdp_features -f XDP_TX -D 10.10.0.1 -T 10.10.0.11 v01 &
+	ip netns exec ${NS0} ./xdp_features -t -f XDP_TX -D 10.10.0.1 -C 10.10.0.1 -T 10.10.0.11 v00
+
+	## XDP_REDIRECT
+	ip netns exec ${NS1} ./xdp_features -f XDP_REDIRECT -D 10.10.1.11 -T 10.10.0.11 v11 &
+	ip netns exec ${NS0} ./xdp_features -t -f XDP_REDIRECT -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
+
+	[ $? -ne 0 ] && exit
+
+	## XDP_NDO_XMIT
+	./xdp_features -f XDP_NDO_XMIT -D 10.10.0.1 -T 10.10.0.11 v01 &
+	ip netns exec ${NS0} ./xdp_features -t -f XDP_NDO_XMIT -D 10.10.0.1 -C 10.10.0.1 -T 10.10.0.11 v00
+
+	ret=$?
+	cleanup
+}
+
+set -e
+trap cleanup 2 3 6 9
+
+test_xdp_features
+
+exit $ret
diff --git a/tools/testing/selftests/bpf/xdp_features.c b/tools/testing/selftests/bpf/xdp_features.c
new file mode 100644
index 000000000000..5f1146b1b532
--- /dev/null
+++ b/tools/testing/selftests/bpf/xdp_features.c
@@ -0,0 +1,743 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <uapi/linux/bpf.h>
+#include <uapi/linux/netdev.h>
+#include <linux/if_link.h>
+#include <signal.h>
+#include <argp.h>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <bpf/bpf.h>
+#include <bpf/libbpf.h>
+#include <pthread.h>
+
+#include "test_xdp_features.skel.h"
+
+#define BIT(x)		(1 << (x))
+#define RED(str)	"\033[0;31m" str "\033[0m"
+#define GREEN(str)	"\033[0;32m" str "\033[0m"
+#define YELLOW(str)	"\033[0;33m" str "\033[0m"
+
+static struct env {
+	bool verbosity;
+	int ifindex;
+	unsigned int feature;
+	bool tester;
+	in_addr_t dut_ctrl_ip;
+	in_addr_t dut_ip;
+	in_addr_t tester_ip;
+} env;
+
+#define DUT_CTRL_PORT	12345
+#define DUT_ECHO_PORT	12346
+
+/* test commands */
+enum test_commands {
+	CMD_STOP,		/* CMD */
+	CMD_START,		/* CMD + xdp feature */
+	CMD_ECHO,		/* CMD */
+	CMD_ACK,		/* CMD + data */
+	CMD_GET_XDP_CAP,	/* CMD */
+	CMD_GET_STATS,		/* CMD */
+};
+
+struct tlv_hdr {
+	__be16 type;
+	__be16 len;
+	__be32 data[];
+};
+
+#define BUFSIZE		128
+
+static int libbpf_print_fn(enum libbpf_print_level level,
+			   const char *format, va_list args)
+{
+	if (level == LIBBPF_DEBUG && !env.verbosity)
+		return 0;
+	return vfprintf(stderr, format, args);
+}
+
+static volatile bool exiting;
+
+static void sig_handler(int sig)
+{
+	exiting = true;
+}
+
+const char *argp_program_version = "xdp-features 0.0";
+const char argp_program_doc[] =
+"XDP features detecion application.\n"
+"\n"
+"XDP features application checks the XDP advertised features match detected ones.\n"
+"\n"
+"USAGE: ./xdp-features [-vt] [-f <xdp-feature>] [-D <dut-data-ip>] [-T <tester-data-ip>] [-C <dut-ctrl-ip>] <iface-name>\n"
+"\n"
+"XDP features\n:"
+"- XDP_PASS\n"
+"- XDP_DROP\n"
+"- XDP_ABORTED\n"
+"- XDP_REDIRECT\n"
+"- XDP_NDO_XMIT\n"
+"- XDP_TX\n";
+
+static const struct argp_option opts[] = {
+	{ "verbose", 'v', NULL, 0, "Verbose debug output" },
+	{ "tester", 't', NULL, 0, "Tester mode" },
+	{ "feature", 'f', "XDP-FEATURE", 0, "XDP feature to test" },
+	{ "dut_data_ip", 'D', "DUT-DATA-IP", 0, "DUT IP data channel" },
+	{ "dut_ctrl_ip", 'C', "DUT-CTRL-IP", 0, "DUT IP control channel" },
+	{ "tester_data_ip", 'T', "TESTER-DATA-IP", 0, "Tester IP data channel" },
+	{},
+};
+
+static int get_xdp_feature(const char *arg)
+{
+	if (!strcmp(arg, "XDP_PASS"))
+		return NETDEV_XDP_ACT_PASS;
+	else if (!strcmp(arg, "XDP_DROP"))
+		return NETDEV_XDP_ACT_DROP;
+	else if (!strcmp(arg, "XDP_ABORTED"))
+		return NETDEV_XDP_ACT_ABORTED;
+	else if (!strcmp(arg, "XDP_REDIRECT"))
+		return NETDEV_XDP_ACT_REDIRECT;
+	else if (!strcmp(arg, "XDP_NDO_XMIT"))
+		return NETDEV_XDP_ACT_NDO_XMIT;
+	else if (!strcmp(arg, "XDP_TX"))
+		return NETDEV_XDP_ACT_TX;
+
+	return -EINVAL;
+}
+
+static char *get_xdp_feature_str(int feature)
+{
+	switch (feature) {
+	case NETDEV_XDP_ACT_PASS:
+		return YELLOW("XDP_PASS");
+	case NETDEV_XDP_ACT_DROP:
+		return YELLOW("XDP_DROP");
+	case NETDEV_XDP_ACT_ABORTED:
+		return YELLOW("XDP_ABORTED");
+	case NETDEV_XDP_ACT_TX:
+		return YELLOW("XDP_TX");
+	case NETDEV_XDP_ACT_REDIRECT:
+		return YELLOW("XDP_REDIRECT");
+	case NETDEV_XDP_ACT_NDO_XMIT:
+		return YELLOW("XDP_NDO_XMIT");
+	default:
+		return "";
+	}
+}
+
+static error_t parse_arg(int key, char *arg, struct argp_state *state)
+{
+	switch (key) {
+	case 'v':
+		env.verbosity = true;
+		break;
+	case 't':
+		env.tester = true;
+		break;
+	case 'f':
+		env.feature = get_xdp_feature(arg);
+		if (env.feature < 0) {
+			fprintf(stderr, "Invalid xdp feature: %s\n", arg);
+			argp_usage(state);
+			return ARGP_ERR_UNKNOWN;
+		}
+		break;
+	case 'D':
+		env.dut_ip = inet_addr(arg);
+		if (env.dut_ip < 0)
+			return ARGP_ERR_UNKNOWN;
+		break;
+	case 'C':
+		env.dut_ctrl_ip = inet_addr(arg);
+		if (env.dut_ctrl_ip < 0)
+			return ARGP_ERR_UNKNOWN;
+		break;
+	case 'T':
+		env.tester_ip = inet_addr(arg);
+		if (env.tester_ip < 0)
+			return ARGP_ERR_UNKNOWN;
+		break;
+	case ARGP_KEY_ARG:
+		errno = 0;
+		if (strlen(arg) >= IF_NAMESIZE) {
+			fprintf(stderr, "Invalid device name: %s\n", arg);
+			argp_usage(state);
+			return ARGP_ERR_UNKNOWN;
+		}
+
+		env.ifindex = if_nametoindex(arg);
+		if (!env.ifindex)
+			env.ifindex = strtoul(arg, NULL, 0);
+		if (!env.ifindex) {
+			fprintf(stderr,
+				"Bad interface index or name (%d): %s\n",
+				errno, strerror(errno));
+			argp_usage(state);
+			return ARGP_ERR_UNKNOWN;
+		}
+		break;
+	default:
+		return ARGP_ERR_UNKNOWN;
+	}
+
+	return 0;
+}
+
+static const struct argp argp = {
+	.options = opts,
+	.parser = parse_arg,
+	.doc = argp_program_doc,
+};
+
+static void set_env_defaul(void)
+{
+	env.feature = NETDEV_XDP_ACT_PASS;
+	env.ifindex = -ENODEV;
+	env.dut_ctrl_ip = inet_addr("127.0.0.1");
+	env.dut_ip = inet_addr("127.0.0.1");
+	env.tester_ip = inet_addr("127.0.0.1");
+}
+
+static void *dut_echo_thread(void *arg)
+{
+	unsigned char buf[sizeof(struct tlv_hdr)];
+	int sockfd = *(int *)arg;
+
+	while (!exiting) {
+		unsigned int len = sizeof(struct sockaddr_in);
+		struct sockaddr_in addr;
+		struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
+		size_t n;
+
+		n = recvfrom(sockfd, buf, sizeof(buf), MSG_WAITALL,
+			     (struct sockaddr *)&addr, &len);
+		if (n != ntohs(tlv->len))
+			continue;
+
+		if (ntohs(tlv->type) != CMD_ECHO)
+			continue;
+
+		sendto(sockfd, buf, sizeof(buf), MSG_NOSIGNAL | MSG_CONFIRM,
+		       (struct sockaddr *)&addr, sizeof(addr));
+	}
+
+	pthread_exit((void *)0);
+	close(sockfd);
+
+	return NULL;
+}
+
+static int dut_run_echo_thread(pthread_t *t, int *echo_sockfd)
+{
+	struct sockaddr_in addr = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = htonl(INADDR_ANY),
+		.sin_port = htons(DUT_ECHO_PORT),
+	};
+	int err, sockfd, optval = 1;
+
+	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sockfd < 0) {
+		fprintf(stderr, "Failed to create echo socket\n");
+		return -errno;
+	}
+
+	err = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval,
+			 sizeof(optval));
+	if (err < 0) {
+		fprintf(stderr, "Failed sockopt on echo socket\n");
+		return -errno;
+	}
+
+	err = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
+	if (err) {
+		fprintf(stderr, "Failed to bind echo socket\n");
+		return -errno;
+	}
+
+	/* start echo channel */
+	*echo_sockfd = sockfd;
+	err = pthread_create(t, NULL, dut_echo_thread, echo_sockfd);
+	if (err) {
+		fprintf(stderr, "Failed creating dut_echo thread: %s\n",
+			strerror(-err));
+		close(sockfd);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int dut_attach_xdp_prog(struct test_xdp_features *skel, int feature,
+			       int flags)
+{
+	struct bpf_program *prog;
+	unsigned int key = 0;
+	int err, fd = 0;
+
+	switch (feature) {
+	case NETDEV_XDP_ACT_TX:
+		prog = skel->progs.xdp_do_tx;
+		break;
+	case NETDEV_XDP_ACT_DROP:
+	case NETDEV_XDP_ACT_ABORTED:
+		prog = skel->progs.xdp_do_drop;
+		break;
+	case NETDEV_XDP_ACT_PASS:
+		prog = skel->progs.xdp_do_pass;
+		break;
+	case NETDEV_XDP_ACT_NDO_XMIT: {
+		struct bpf_devmap_val entry = {
+			.ifindex = env.ifindex,
+		};
+
+		err = bpf_map__update_elem(skel->maps.dev_map,
+					   &key, sizeof(key),
+					   &entry, sizeof(entry), 0);
+		if (err < 0)
+			return err;
+
+		fd = bpf_program__fd(skel->progs.xdp_do_redirect_cpumap);
+	}
+	case NETDEV_XDP_ACT_REDIRECT: {
+		struct bpf_cpumap_val entry = {
+			.qsize = 2048,
+			.bpf_prog.fd = fd,
+		};
+
+		err = bpf_map__update_elem(skel->maps.cpu_map,
+					   &key, sizeof(key),
+					   &entry, sizeof(entry), 0);
+		if (err < 0)
+			return err;
+
+		prog = skel->progs.xdp_do_redirect;
+		break;
+	}
+	default:
+		return -EINVAL;
+	}
+
+	err = bpf_xdp_attach(env.ifindex, bpf_program__fd(prog), flags, NULL);
+	if (err)
+		fprintf(stderr,
+			"Failed to attach XDP program to ifindex %d\n",
+			env.ifindex);
+	return err;
+}
+
+static int __recv_msg(int sockfd, void *buf, size_t bufsize,
+		      unsigned int *val, unsigned int val_size)
+{
+	struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
+	int len, n = sizeof(*tlv), i = 0;
+
+	len = recv(sockfd, buf, bufsize, 0);
+	if (len != ntohs(tlv->len))
+		return -EINVAL;
+
+	while (n < len && i < val_size) {
+		val[i] = ntohl(tlv->data[i]);
+		n += sizeof(tlv->data[0]);
+		i++;
+	}
+
+	return i;
+}
+
+static int recv_msg(int sockfd, void *buf, size_t bufsize)
+{
+	return __recv_msg(sockfd, buf, bufsize, NULL, 0);
+}
+
+static int dut_run(struct test_xdp_features *skel)
+{
+	int flags = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_DRV_MODE;
+	int state, err, sockfd, ctrl_sockfd, echo_sockfd, optval = 1;
+	struct sockaddr_in ctrl_addr, addr = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = htonl(INADDR_ANY),
+		.sin_port = htons(DUT_CTRL_PORT),
+	};
+	unsigned int len = sizeof(ctrl_addr);
+	pthread_t dut_thread;
+
+	sockfd = socket(AF_INET, SOCK_STREAM, 0);
+	if (sockfd < 0) {
+		fprintf(stderr, "Failed to create DUT socket\n");
+		return -errno;
+	}
+
+	err = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval,
+			 sizeof(optval));
+	if (err < 0) {
+		fprintf(stderr, "Failed sockopt on DUT socket\n");
+		return -errno;
+	}
+
+	err = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
+	if (err < 0) {
+		fprintf(stderr, "Failed to bind DUT socket\n");
+		return -errno;
+	}
+
+	err = listen(sockfd, 5);
+	if (err) {
+		fprintf(stderr, "Failed to listen DUT socket\n");
+		return -errno;
+	}
+
+	ctrl_sockfd = accept(sockfd, (struct sockaddr *)&ctrl_addr, &len);
+	if (ctrl_sockfd < 0) {
+		fprintf(stderr, "Failed to accept connection on DUT socket\n");
+		close(sockfd);
+		return -errno;
+	}
+
+	/* CTRL loop */
+	while (!exiting) {
+		unsigned char buf[BUFSIZE] = {};
+		struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
+
+		err = recv_msg(ctrl_sockfd, buf, BUFSIZE);
+		if (err)
+			continue;
+
+		switch (ntohs(tlv->type)) {
+		case CMD_START: {
+			if (state == CMD_START)
+				continue;
+
+			state = CMD_START;
+			/* Load the XDP program on the DUT */
+			err = dut_attach_xdp_prog(skel, ntohl(tlv->data[0]), flags);
+			if (err)
+				goto out;
+
+			err = dut_run_echo_thread(&dut_thread, &echo_sockfd);
+			if (err < 0)
+				goto out;
+
+			tlv->type = htons(CMD_ACK);
+			tlv->len = htons(sizeof(*tlv));
+			err = send(ctrl_sockfd, buf, sizeof(*tlv), 0);
+			if (err < 0)
+				goto end_thread;
+			break;
+		}
+		case CMD_STOP:
+			if (state != CMD_START)
+				break;
+
+			state = CMD_STOP;
+
+			exiting = true;
+			bpf_xdp_detach(env.ifindex, flags, NULL);
+
+			tlv->type = htons(CMD_ACK);
+			tlv->len = htons(sizeof(*tlv));
+			err = send(ctrl_sockfd, buf, sizeof(*tlv), 0);
+			goto end_thread;
+		case CMD_GET_XDP_CAP: {
+			LIBBPF_OPTS(bpf_xdp_query_opts, opts);
+			size_t n;
+
+			err = bpf_xdp_query(env.ifindex, XDP_FLAGS_DRV_MODE,
+					    &opts);
+			if (err) {
+				fprintf(stderr,
+					"Failed to query XDP cap for ifindex %d\n",
+					env.ifindex);
+				goto end_thread;
+			}
+
+			tlv->type = htons(CMD_ACK);
+			n = sizeof(*tlv) + sizeof(opts.fflags);
+			tlv->len = htons(n);
+			tlv->data[0] = htonl(opts.fflags);
+
+			err = send(ctrl_sockfd, buf, n, 0);
+			if (err < 0)
+				goto end_thread;
+			break;
+		}
+		case CMD_GET_STATS: {
+			unsigned int key = 0, val;
+			size_t n;
+
+			err = bpf_map__lookup_elem(skel->maps.dut_stats,
+						   &key, sizeof(key),
+						   &val, sizeof(val), 0);
+			if (err) {
+				fprintf(stderr, "bpf_map_lookup_elem failed\n");
+				goto end_thread;
+			}
+
+			tlv->type = htons(CMD_ACK);
+			n = sizeof(*tlv) + sizeof(val);
+			tlv->len = htons(n);
+			tlv->data[0] = htonl(val);
+
+			err = send(ctrl_sockfd, buf, n, 0);
+			if (err < 0)
+				goto end_thread;
+			break;
+		}
+		default:
+			break;
+		}
+	}
+
+end_thread:
+	pthread_join(dut_thread, NULL);
+out:
+	bpf_xdp_detach(env.ifindex, flags, NULL);
+	close(ctrl_sockfd);
+	close(sockfd);
+
+	return err;
+}
+
+static bool tester_collect_advertised_cap(unsigned int cap)
+{
+	return cap & env.feature;
+}
+
+static bool tester_collect_detected_cap(struct test_xdp_features *skel,
+					unsigned int dut_stats)
+{
+	unsigned int err, key = 0, val;
+
+	if (!dut_stats)
+		return false;
+
+	err = bpf_map__lookup_elem(skel->maps.stats, &key, sizeof(key),
+				   &val, sizeof(val), 0);
+	if (err) {
+		fprintf(stderr, "bpf_map_lookup_elem failed\n");
+		return false;
+	}
+
+	switch (env.feature) {
+	case NETDEV_XDP_ACT_PASS:
+	case NETDEV_XDP_ACT_TX:
+	case NETDEV_XDP_ACT_REDIRECT:
+	case NETDEV_XDP_ACT_NDO_XMIT:
+		return val > 0;
+	case NETDEV_XDP_ACT_DROP:
+	case NETDEV_XDP_ACT_ABORTED:
+		return val == 0;
+	default:
+		return false;
+	}
+}
+
+static int __send_and_recv_msg(int sockfd, enum test_commands cmd,
+			       unsigned int *val, unsigned int val_size)
+{
+	unsigned char buf[BUFSIZE] = {};
+	struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
+	int n = sizeof(*tlv), err;
+
+	tlv->type = htons(cmd);
+	switch (cmd) {
+	case CMD_START:
+		tlv->data[0] = htonl(env.feature);
+		n += sizeof(*val);
+		break;
+	default:
+		break;
+	}
+	tlv->len = htons(n);
+
+	err = send(sockfd, buf, n, 0);
+	if (err < 0)
+		return err;
+
+	err = __recv_msg(sockfd, buf, BUFSIZE, val, val_size);
+	if (err < 0)
+		return err;
+
+	return ntohs(tlv->type) == CMD_ACK ? 0 : -EINVAL;
+}
+
+static int send_and_recv_msg(int sockfd, enum test_commands cmd)
+{
+	return __send_and_recv_msg(sockfd, cmd, NULL, 0);
+}
+
+static int send_echo_msg(void)
+{
+	struct sockaddr_in addr = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = env.dut_ip,
+		.sin_port = htons(DUT_ECHO_PORT),
+	};
+	unsigned char buf[sizeof(struct tlv_hdr)];
+	struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
+	int sockfd, n;
+
+	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sockfd < 0) {
+		fprintf(stderr, "Failed to create echo socket\n");
+		return -errno;
+	}
+
+	tlv->type = htons(CMD_ECHO);
+	tlv->len = htons(sizeof(*tlv));
+
+	n = sendto(sockfd, buf, sizeof(*tlv), MSG_NOSIGNAL | MSG_CONFIRM,
+		   (struct sockaddr *)&addr, sizeof(addr));
+	close(sockfd);
+
+	return n == ntohs(tlv->len) ? 0 : -EINVAL;
+}
+
+static int tester_run(struct test_xdp_features *skel)
+{
+	int flags = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_DRV_MODE;
+	struct sockaddr_in addr = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = env.dut_ctrl_ip,
+		.sin_port = htons(DUT_CTRL_PORT),
+	};
+	bool advertised_cap;
+	int i, err, sockfd;
+	bool detected_cap;
+	unsigned int val[1];
+
+	sockfd = socket(AF_INET, SOCK_STREAM, 0);
+	if (sockfd < 0) {
+		fprintf(stderr, "Failed to create tester socket\n");
+		return -errno;
+	}
+
+	for (i = 0; i < 10; i++) {
+		/* connect ctrl channel */
+		if (!connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)))
+			break;
+		sleep(1);
+	}
+
+	if (i == 10) {
+		fprintf(stderr, "Failed to connect to the DUT\n");
+		return -ETIMEDOUT;
+	}
+
+	err = __send_and_recv_msg(sockfd, CMD_GET_XDP_CAP, val, ARRAY_SIZE(val));
+	if (err < 0) {
+		close(sockfd);
+		return err;
+	}
+
+	advertised_cap = tester_collect_advertised_cap(val[0]);
+
+	err = bpf_xdp_attach(env.ifindex,
+			     bpf_program__fd(skel->progs.xdp_tester),
+			     flags, NULL);
+	if (err) {
+		fprintf(stderr, "Failed to attach XDP program to ifindex %d\n",
+			env.ifindex);
+		goto out;
+	}
+
+	err = send_and_recv_msg(sockfd, CMD_START);
+	if (err)
+		goto out;
+
+	for (i = 0; i < 10 && !exiting; i++) {
+		err = send_echo_msg();
+		if (err < 0)
+			goto out;
+
+		sleep(1);
+	}
+
+	err = __send_and_recv_msg(sockfd, CMD_GET_STATS, val, ARRAY_SIZE(val));
+	if (err)
+		goto out;
+
+	/* stop the test */
+	err = send_and_recv_msg(sockfd, CMD_STOP);
+	/* send a new echo message to wake echo thread of the dut */
+	send_echo_msg();
+
+	detected_cap = tester_collect_detected_cap(skel, val[0]);
+
+	fprintf(stdout, "Feature %s: [%s][%s]\n", get_xdp_feature_str(env.feature),
+		detected_cap ? GREEN("DETECTED") : RED("NOT DETECTED"),
+		advertised_cap ? GREEN("ADVERTISED") : RED("NOT ADVERTISED"));
+out:
+	bpf_xdp_detach(env.ifindex, flags, NULL);
+	close(sockfd);
+	return err < 0 ? err : 0;
+}
+
+int main(int argc, char **argv)
+{
+	struct test_xdp_features *skel;
+	int err;
+
+	libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
+	libbpf_set_print(libbpf_print_fn);
+
+	signal(SIGINT, sig_handler);
+	signal(SIGTERM, sig_handler);
+
+	set_env_defaul();
+
+	/* Parse command line arguments */
+	err = argp_parse(&argp, argc, argv, 0, NULL, NULL);
+	if (err)
+		return err;
+
+	if (env.ifindex < 0) {
+		fprintf(stderr, "Invalid ifindex\n");
+		return -ENODEV;
+	}
+
+	/* Load and verify BPF application */
+	skel = test_xdp_features__open();
+	if (!skel) {
+		fprintf(stderr, "Failed to open and load BPF skeleton\n");
+		return -EINVAL;
+	}
+
+	skel->rodata->expected_feature = env.feature;
+	skel->rodata->dut_ip = env.dut_ip;
+	skel->rodata->tester_ip = env.tester_ip;
+
+	/* Load & verify BPF programs */
+	err = test_xdp_features__load(skel);
+	if (err) {
+		fprintf(stderr, "Failed to load and verify BPF skeleton\n");
+		goto cleanup;
+	}
+
+	err = test_xdp_features__attach(skel);
+	if (err) {
+		fprintf(stderr, "Failed to attach BPF skeleton\n");
+		goto cleanup;
+	}
+
+	if (env.tester) {
+		/* Tester */
+		fprintf(stdout, "Starting tester on device %d\n", env.ifindex);
+		err = tester_run(skel);
+	} else {
+		/* DUT */
+		fprintf(stdout, "Starting DUT on device %d\n", env.ifindex);
+		err = dut_run(skel);
+	}
+
+cleanup:
+	test_xdp_features__destroy(skel);
+
+	return err < 0 ? -err : 0;
+}
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Intel-wired-lan] [PATCH bpf-next 7/7] selftests/bpf: introduce XDP compliance test tool
@ 2023-01-20 17:16   ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-20 17:16 UTC (permalink / raw)
  To: bpf
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, kuba,
	pabeni, aelior, hawk, christophe.jaillet, memxor, john, bjorn,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

Introduce xdp_features tool in order to test XDP features supported by
the NIC and match them against advertised ones.
In order to test supported/advertised XDP features, xdp_features must
run on the Device Under Test (DUT) and on a Tester device.
xdp_features opens a control TCP channel between DUT and Tester devices
to send control commands from Tester to the DUT and a UDP data channel
where the Tester sends UDP 'echo' packets and the DUT is expected to
reply back with the same packet. DUT installs multiple XDP programs on the
NIC to test XDP capabilities and reports back to the Tester some XDP stats.
Currently xdp_features supports the following XDP features:
- XDP_DROP
- XDP_PASS
- XDP_TX
- XDP_REDIRECT
- XDP_REDIRECT_TARGET

Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 tools/testing/selftests/bpf/Makefile          |   5 +-
 .../selftests/bpf/progs/test_xdp_features.c   | 237 ++++++
 .../selftests/bpf/test_xdp_features.sh        |  99 +++
 tools/testing/selftests/bpf/xdp_features.c    | 743 ++++++++++++++++++
 4 files changed, 1082 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/progs/test_xdp_features.c
 create mode 100755 tools/testing/selftests/bpf/test_xdp_features.sh
 create mode 100644 tools/testing/selftests/bpf/xdp_features.c

diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 22533a18705e..071cd064625d 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -73,7 +73,8 @@ TEST_PROGS := test_kmod.sh \
 	test_bpftool.sh \
 	test_bpftool_metadata.sh \
 	test_doc_build.sh \
-	test_xsk.sh
+	test_xsk.sh \
+	test_xdp_features.sh
 
 TEST_PROGS_EXTENDED := with_addr.sh \
 	with_tunnels.sh ima_setup.sh verify_sig_setup.sh \
@@ -83,7 +84,7 @@ TEST_PROGS_EXTENDED := with_addr.sh \
 TEST_GEN_PROGS_EXTENDED = test_sock_addr test_skb_cgroup_id_user \
 	flow_dissector_load test_flow_dissector test_tcp_check_syncookie_user \
 	test_lirc_mode2_user xdping test_cpp runqslower bench bpf_testmod.ko \
-	xskxceiver xdp_redirect_multi xdp_synproxy veristat
+	xskxceiver xdp_redirect_multi xdp_synproxy veristat xdp_features
 
 TEST_CUSTOM_PROGS = $(OUTPUT)/urandom_read $(OUTPUT)/sign-file
 TEST_GEN_FILES += liburandom_read.so
diff --git a/tools/testing/selftests/bpf/progs/test_xdp_features.c b/tools/testing/selftests/bpf/progs/test_xdp_features.c
new file mode 100644
index 000000000000..40f2a3e8c4e9
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/test_xdp_features.c
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <stdbool.h>
+#include <linux/bpf.h>
+#include <linux/netdev.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
+#include <bpf/bpf_tracing.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/udp.h>
+#include <asm-generic/errno-base.h>
+
+#define BIT(x)	(1 << (x))
+
+struct xdp_cpumap_stats {
+	unsigned int redirect;
+	unsigned int pass;
+	unsigned int drop;
+};
+
+struct {
+	__uint(type, BPF_MAP_TYPE_ARRAY);
+	__type(key, __u32);
+	__type(value, __u32);
+	__uint(max_entries, 1);
+} stats SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_ARRAY);
+	__type(key, __u32);
+	__type(value, __u32);
+	__uint(max_entries, 1);
+} dut_stats SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_CPUMAP);
+	__uint(key_size, sizeof(__u32));
+	__uint(value_size, sizeof(struct bpf_cpumap_val));
+	__uint(max_entries, 1);
+} cpu_map SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_DEVMAP);
+	__uint(key_size, sizeof(__u32));
+	__uint(value_size, sizeof(struct bpf_devmap_val));
+	__uint(max_entries, 1);
+} dev_map SEC(".maps");
+
+const volatile __u32 expected_feature = NETDEV_XDP_ACT_PASS;
+const volatile __be32 tester_ip;
+const volatile __be32 dut_ip;
+
+#define ECHO_PORT	12346
+
+/* test commands */
+enum test_commands {
+	CMD_STOP,		/* CMD */
+	CMD_START,		/* CMD + xdp feature */
+	CMD_ECHO,		/* CMD */
+	CMD_ACK,		/* CMD + data */
+	CMD_GET_XDP_CAP,	/* CMD */
+	CMD_GET_STATS,		/* CMD */
+};
+
+struct tlv_hdr {
+	__be16 type;
+	__be16 len;
+	__be32 data[];
+};
+
+static __always_inline int xdp_process_echo_packet(struct xdp_md *xdp, bool dut)
+{
+	void *data_end = (void *)(long)xdp->data_end;
+	__be32 saddr = dut ? tester_ip : dut_ip;
+	__be32 daddr = dut ? dut_ip : tester_ip;
+	void *data = (void *)(long)xdp->data;
+	struct ethhdr *eh = data;
+	struct tlv_hdr *tlv;
+	struct udphdr *uh;
+	struct iphdr *ih;
+	__be16 port;
+	__u8 *cmd;
+
+	if (eh + 1 > (struct ethhdr *)data_end)
+		return -EINVAL;
+
+	if (eh->h_proto != bpf_htons(ETH_P_IP))
+		return -EINVAL;
+
+	ih = (struct iphdr *)(eh + 1);
+	if (ih + 1 > (struct iphdr *)data_end)
+		return -EINVAL;
+
+	if (saddr != ih->saddr)
+		return -EINVAL;
+
+	if (daddr != ih->daddr)
+		return -EINVAL;
+
+	if (ih->protocol != IPPROTO_UDP)
+		return -EINVAL;
+
+	uh = (struct udphdr *)(ih + 1);
+	if (uh + 1 > (struct udphdr *)data_end)
+		return -EINVAL;
+
+	port = dut ? uh->dest : uh->source;
+	if (port != bpf_htons(ECHO_PORT))
+		return -EINVAL;
+
+	tlv = (struct tlv_hdr *)(uh + 1);
+	if (tlv + 1 > data_end)
+		return -EINVAL;
+
+	return bpf_htons(tlv->type) == CMD_ECHO ? 0 : -EINVAL;
+}
+
+SEC("xdp")
+int xdp_tester(struct xdp_md *xdp)
+{
+	__u32 *val, key = 0;
+
+	switch (expected_feature) {
+	case NETDEV_XDP_ACT_NDO_XMIT:
+	case NETDEV_XDP_ACT_TX:
+		if (xdp_process_echo_packet(xdp, true))
+			goto out;
+		break;
+	case NETDEV_XDP_ACT_DROP:
+	case NETDEV_XDP_ACT_PASS:
+	case NETDEV_XDP_ACT_REDIRECT:
+		if (xdp_process_echo_packet(xdp, false))
+			goto out;
+		break;
+	default:
+		goto out;
+	}
+
+	val = bpf_map_lookup_elem(&stats, &key);
+	if (val)
+		__sync_add_and_fetch(val, 1);
+
+out:
+	return XDP_PASS;
+}
+
+SEC("xdp")
+int xdp_do_pass(struct xdp_md *xdp)
+{
+	__u32 *val, key = 0;
+
+	val = bpf_map_lookup_elem(&dut_stats, &key);
+	if (val)
+		__sync_add_and_fetch(val, 1);
+
+	return XDP_PASS;
+}
+
+SEC("xdp")
+int xdp_do_drop(struct xdp_md *xdp)
+{
+	__u32 *val, key = 0;
+
+	if (xdp_process_echo_packet(xdp, true))
+		return XDP_PASS;
+
+	val = bpf_map_lookup_elem(&dut_stats, &key);
+	if (val)
+		__sync_add_and_fetch(val, 1);
+
+	return XDP_DROP;
+}
+
+SEC("xdp")
+int xdp_do_tx(struct xdp_md *xdp)
+{
+	void *data = (void *)(long)xdp->data;
+	struct ethhdr *eh = data;
+	__u8 tmp_mac[ETH_ALEN];
+	__u32 *val, key = 0;
+
+	if (xdp_process_echo_packet(xdp, true))
+		return XDP_PASS;
+
+	__builtin_memcpy(tmp_mac, eh->h_source, ETH_ALEN);
+	__builtin_memcpy(eh->h_source, eh->h_dest, ETH_ALEN);
+	__builtin_memcpy(eh->h_dest, tmp_mac, ETH_ALEN);
+
+	val = bpf_map_lookup_elem(&dut_stats, &key);
+	if (val)
+		__sync_add_and_fetch(val, 1);
+
+	return XDP_TX;
+}
+
+SEC("xdp")
+int xdp_do_redirect(struct xdp_md *xdp)
+{
+	if (xdp_process_echo_packet(xdp, true))
+		return XDP_PASS;
+
+	return bpf_redirect_map(&cpu_map, 0, 0);
+}
+
+SEC("tp_btf/xdp_cpumap_kthread")
+int BPF_PROG(tp_xdp_cpumap_kthread, int map_id, unsigned int processed,
+	     unsigned int drops, int sched, struct xdp_cpumap_stats *xdp_stats)
+{
+	__u32 *val, key = 0;
+
+	val = bpf_map_lookup_elem(&dut_stats, &key);
+	if (val)
+		__sync_add_and_fetch(val, 1);
+
+	return 0;
+}
+
+SEC("xdp/cpumap")
+int xdp_do_redirect_cpumap(struct xdp_md *xdp)
+{
+	void *data = (void *)(long)xdp->data;
+	struct ethhdr *eh = data;
+	__u8 tmp_mac[ETH_ALEN];
+
+	if (xdp_process_echo_packet(xdp, true))
+		return XDP_PASS;
+
+	__builtin_memcpy(tmp_mac, eh->h_source, ETH_ALEN);
+	__builtin_memcpy(eh->h_source, eh->h_dest, ETH_ALEN);
+	__builtin_memcpy(eh->h_dest, tmp_mac, ETH_ALEN);
+
+	return bpf_redirect_map(&dev_map, 0, 0);
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_xdp_features.sh b/tools/testing/selftests/bpf/test_xdp_features.sh
new file mode 100755
index 000000000000..98b8fd2b6c16
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_xdp_features.sh
@@ -0,0 +1,99 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+# Create 2 namespaces with two veth peers, and
+# check reported and detected XDP capabilities
+#
+#   NS0(v00)              NS1(v11)
+#       |                     |
+#       |                     |
+# (v01, id:111)  ------  (v10,id:222)
+
+readonly NS0="ns1-$(mktemp -u XXXXXX)"
+readonly NS1="ns2-$(mktemp -u XXXXXX)"
+ret=1
+
+setup() {
+	{
+		ip netns add ${NS0}
+		ip netns add ${NS1}
+
+		ip link add v01 index 111 type veth peer name v00 netns ${NS0}
+		ip link add v10 index 222 type veth peer name v11 netns ${NS1}
+
+		ip link set v01 up
+		ip addr add 10.10.0.1/24 dev v01
+		ip link set v01 address 00:11:22:33:44:55
+		ip -n ${NS0} link set dev v00 up
+		ip -n ${NS0} addr add 10.10.0.11/24 dev v00
+		ip -n ${NS0} route add default via 10.10.0.1
+		ip -n ${NS0} link set v00 address 00:12:22:33:44:55
+
+		ip link set v10 up
+		ip addr add 10.10.1.1/24 dev v10
+		ip link set v10 address 00:13:22:33:44:55
+		ip -n ${NS1} link set dev v11 up
+		ip -n ${NS1} addr add 10.10.1.11/24 dev v11
+		ip -n ${NS1} route add default via 10.10.1.1
+		ip -n ${NS1} link set v11 address 00:14:22:33:44:55
+
+		sysctl -w net.ipv4.ip_forward=1
+		# Enable XDP mode
+		ethtool -K v01 gro on
+		ethtool -K v01 tx-checksumming off
+		ip netns exec ${NS0} ethtool -K v00 gro on
+		ip netns exec ${NS0} ethtool -K v00 tx-checksumming off
+		ethtool -K v10 gro on
+		ethtool -K v10 tx-checksumming off
+		ip netns exec ${NS1} ethtool -K v11 gro on
+		ip netns exec ${NS1} ethtool -K v11 tx-checksumming off
+	} > /dev/null 2>&1
+}
+
+cleanup() {
+	ip link del v01 2> /dev/null
+	ip link del v10 2> /dev/null
+	ip netns del ${NS0} 2> /dev/null
+	ip netns del ${NS1} 2> /dev/null
+	[ "$(pidof xdp_features)" = "" ] || kill $(pidof xdp_features) 2> /dev/null
+}
+
+test_xdp_features() {
+	setup
+
+	## XDP_PASS
+	ip netns exec ${NS1} ./xdp_features -f XDP_PASS -D 10.10.1.11 -T 10.10.0.11 v11 &
+	ip netns exec ${NS0} ./xdp_features -t -f XDP_PASS -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
+
+	[ $? -ne 0 ] && exit
+
+	# XDP_DROP
+	ip netns exec ${NS1} ./xdp_features -f XDP_DROP -D 10.10.1.11 -T 10.10.0.11 v11 &
+	ip netns exec ${NS0} ./xdp_features -t -f XDP_DROP -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
+
+	[ $? -ne 0 ] && exit
+
+	## XDP_TX
+	./xdp_features -f XDP_TX -D 10.10.0.1 -T 10.10.0.11 v01 &
+	ip netns exec ${NS0} ./xdp_features -t -f XDP_TX -D 10.10.0.1 -C 10.10.0.1 -T 10.10.0.11 v00
+
+	## XDP_REDIRECT
+	ip netns exec ${NS1} ./xdp_features -f XDP_REDIRECT -D 10.10.1.11 -T 10.10.0.11 v11 &
+	ip netns exec ${NS0} ./xdp_features -t -f XDP_REDIRECT -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
+
+	[ $? -ne 0 ] && exit
+
+	## XDP_NDO_XMIT
+	./xdp_features -f XDP_NDO_XMIT -D 10.10.0.1 -T 10.10.0.11 v01 &
+	ip netns exec ${NS0} ./xdp_features -t -f XDP_NDO_XMIT -D 10.10.0.1 -C 10.10.0.1 -T 10.10.0.11 v00
+
+	ret=$?
+	cleanup
+}
+
+set -e
+trap cleanup 2 3 6 9
+
+test_xdp_features
+
+exit $ret
diff --git a/tools/testing/selftests/bpf/xdp_features.c b/tools/testing/selftests/bpf/xdp_features.c
new file mode 100644
index 000000000000..5f1146b1b532
--- /dev/null
+++ b/tools/testing/selftests/bpf/xdp_features.c
@@ -0,0 +1,743 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <uapi/linux/bpf.h>
+#include <uapi/linux/netdev.h>
+#include <linux/if_link.h>
+#include <signal.h>
+#include <argp.h>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <bpf/bpf.h>
+#include <bpf/libbpf.h>
+#include <pthread.h>
+
+#include "test_xdp_features.skel.h"
+
+#define BIT(x)		(1 << (x))
+#define RED(str)	"\033[0;31m" str "\033[0m"
+#define GREEN(str)	"\033[0;32m" str "\033[0m"
+#define YELLOW(str)	"\033[0;33m" str "\033[0m"
+
+static struct env {
+	bool verbosity;
+	int ifindex;
+	unsigned int feature;
+	bool tester;
+	in_addr_t dut_ctrl_ip;
+	in_addr_t dut_ip;
+	in_addr_t tester_ip;
+} env;
+
+#define DUT_CTRL_PORT	12345
+#define DUT_ECHO_PORT	12346
+
+/* test commands */
+enum test_commands {
+	CMD_STOP,		/* CMD */
+	CMD_START,		/* CMD + xdp feature */
+	CMD_ECHO,		/* CMD */
+	CMD_ACK,		/* CMD + data */
+	CMD_GET_XDP_CAP,	/* CMD */
+	CMD_GET_STATS,		/* CMD */
+};
+
+struct tlv_hdr {
+	__be16 type;
+	__be16 len;
+	__be32 data[];
+};
+
+#define BUFSIZE		128
+
+static int libbpf_print_fn(enum libbpf_print_level level,
+			   const char *format, va_list args)
+{
+	if (level == LIBBPF_DEBUG && !env.verbosity)
+		return 0;
+	return vfprintf(stderr, format, args);
+}
+
+static volatile bool exiting;
+
+static void sig_handler(int sig)
+{
+	exiting = true;
+}
+
+const char *argp_program_version = "xdp-features 0.0";
+const char argp_program_doc[] =
+"XDP features detecion application.\n"
+"\n"
+"XDP features application checks the XDP advertised features match detected ones.\n"
+"\n"
+"USAGE: ./xdp-features [-vt] [-f <xdp-feature>] [-D <dut-data-ip>] [-T <tester-data-ip>] [-C <dut-ctrl-ip>] <iface-name>\n"
+"\n"
+"XDP features\n:"
+"- XDP_PASS\n"
+"- XDP_DROP\n"
+"- XDP_ABORTED\n"
+"- XDP_REDIRECT\n"
+"- XDP_NDO_XMIT\n"
+"- XDP_TX\n";
+
+static const struct argp_option opts[] = {
+	{ "verbose", 'v', NULL, 0, "Verbose debug output" },
+	{ "tester", 't', NULL, 0, "Tester mode" },
+	{ "feature", 'f', "XDP-FEATURE", 0, "XDP feature to test" },
+	{ "dut_data_ip", 'D', "DUT-DATA-IP", 0, "DUT IP data channel" },
+	{ "dut_ctrl_ip", 'C', "DUT-CTRL-IP", 0, "DUT IP control channel" },
+	{ "tester_data_ip", 'T', "TESTER-DATA-IP", 0, "Tester IP data channel" },
+	{},
+};
+
+static int get_xdp_feature(const char *arg)
+{
+	if (!strcmp(arg, "XDP_PASS"))
+		return NETDEV_XDP_ACT_PASS;
+	else if (!strcmp(arg, "XDP_DROP"))
+		return NETDEV_XDP_ACT_DROP;
+	else if (!strcmp(arg, "XDP_ABORTED"))
+		return NETDEV_XDP_ACT_ABORTED;
+	else if (!strcmp(arg, "XDP_REDIRECT"))
+		return NETDEV_XDP_ACT_REDIRECT;
+	else if (!strcmp(arg, "XDP_NDO_XMIT"))
+		return NETDEV_XDP_ACT_NDO_XMIT;
+	else if (!strcmp(arg, "XDP_TX"))
+		return NETDEV_XDP_ACT_TX;
+
+	return -EINVAL;
+}
+
+static char *get_xdp_feature_str(int feature)
+{
+	switch (feature) {
+	case NETDEV_XDP_ACT_PASS:
+		return YELLOW("XDP_PASS");
+	case NETDEV_XDP_ACT_DROP:
+		return YELLOW("XDP_DROP");
+	case NETDEV_XDP_ACT_ABORTED:
+		return YELLOW("XDP_ABORTED");
+	case NETDEV_XDP_ACT_TX:
+		return YELLOW("XDP_TX");
+	case NETDEV_XDP_ACT_REDIRECT:
+		return YELLOW("XDP_REDIRECT");
+	case NETDEV_XDP_ACT_NDO_XMIT:
+		return YELLOW("XDP_NDO_XMIT");
+	default:
+		return "";
+	}
+}
+
+static error_t parse_arg(int key, char *arg, struct argp_state *state)
+{
+	switch (key) {
+	case 'v':
+		env.verbosity = true;
+		break;
+	case 't':
+		env.tester = true;
+		break;
+	case 'f':
+		env.feature = get_xdp_feature(arg);
+		if (env.feature < 0) {
+			fprintf(stderr, "Invalid xdp feature: %s\n", arg);
+			argp_usage(state);
+			return ARGP_ERR_UNKNOWN;
+		}
+		break;
+	case 'D':
+		env.dut_ip = inet_addr(arg);
+		if (env.dut_ip < 0)
+			return ARGP_ERR_UNKNOWN;
+		break;
+	case 'C':
+		env.dut_ctrl_ip = inet_addr(arg);
+		if (env.dut_ctrl_ip < 0)
+			return ARGP_ERR_UNKNOWN;
+		break;
+	case 'T':
+		env.tester_ip = inet_addr(arg);
+		if (env.tester_ip < 0)
+			return ARGP_ERR_UNKNOWN;
+		break;
+	case ARGP_KEY_ARG:
+		errno = 0;
+		if (strlen(arg) >= IF_NAMESIZE) {
+			fprintf(stderr, "Invalid device name: %s\n", arg);
+			argp_usage(state);
+			return ARGP_ERR_UNKNOWN;
+		}
+
+		env.ifindex = if_nametoindex(arg);
+		if (!env.ifindex)
+			env.ifindex = strtoul(arg, NULL, 0);
+		if (!env.ifindex) {
+			fprintf(stderr,
+				"Bad interface index or name (%d): %s\n",
+				errno, strerror(errno));
+			argp_usage(state);
+			return ARGP_ERR_UNKNOWN;
+		}
+		break;
+	default:
+		return ARGP_ERR_UNKNOWN;
+	}
+
+	return 0;
+}
+
+static const struct argp argp = {
+	.options = opts,
+	.parser = parse_arg,
+	.doc = argp_program_doc,
+};
+
+static void set_env_defaul(void)
+{
+	env.feature = NETDEV_XDP_ACT_PASS;
+	env.ifindex = -ENODEV;
+	env.dut_ctrl_ip = inet_addr("127.0.0.1");
+	env.dut_ip = inet_addr("127.0.0.1");
+	env.tester_ip = inet_addr("127.0.0.1");
+}
+
+static void *dut_echo_thread(void *arg)
+{
+	unsigned char buf[sizeof(struct tlv_hdr)];
+	int sockfd = *(int *)arg;
+
+	while (!exiting) {
+		unsigned int len = sizeof(struct sockaddr_in);
+		struct sockaddr_in addr;
+		struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
+		size_t n;
+
+		n = recvfrom(sockfd, buf, sizeof(buf), MSG_WAITALL,
+			     (struct sockaddr *)&addr, &len);
+		if (n != ntohs(tlv->len))
+			continue;
+
+		if (ntohs(tlv->type) != CMD_ECHO)
+			continue;
+
+		sendto(sockfd, buf, sizeof(buf), MSG_NOSIGNAL | MSG_CONFIRM,
+		       (struct sockaddr *)&addr, sizeof(addr));
+	}
+
+	pthread_exit((void *)0);
+	close(sockfd);
+
+	return NULL;
+}
+
+static int dut_run_echo_thread(pthread_t *t, int *echo_sockfd)
+{
+	struct sockaddr_in addr = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = htonl(INADDR_ANY),
+		.sin_port = htons(DUT_ECHO_PORT),
+	};
+	int err, sockfd, optval = 1;
+
+	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sockfd < 0) {
+		fprintf(stderr, "Failed to create echo socket\n");
+		return -errno;
+	}
+
+	err = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval,
+			 sizeof(optval));
+	if (err < 0) {
+		fprintf(stderr, "Failed sockopt on echo socket\n");
+		return -errno;
+	}
+
+	err = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
+	if (err) {
+		fprintf(stderr, "Failed to bind echo socket\n");
+		return -errno;
+	}
+
+	/* start echo channel */
+	*echo_sockfd = sockfd;
+	err = pthread_create(t, NULL, dut_echo_thread, echo_sockfd);
+	if (err) {
+		fprintf(stderr, "Failed creating dut_echo thread: %s\n",
+			strerror(-err));
+		close(sockfd);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int dut_attach_xdp_prog(struct test_xdp_features *skel, int feature,
+			       int flags)
+{
+	struct bpf_program *prog;
+	unsigned int key = 0;
+	int err, fd = 0;
+
+	switch (feature) {
+	case NETDEV_XDP_ACT_TX:
+		prog = skel->progs.xdp_do_tx;
+		break;
+	case NETDEV_XDP_ACT_DROP:
+	case NETDEV_XDP_ACT_ABORTED:
+		prog = skel->progs.xdp_do_drop;
+		break;
+	case NETDEV_XDP_ACT_PASS:
+		prog = skel->progs.xdp_do_pass;
+		break;
+	case NETDEV_XDP_ACT_NDO_XMIT: {
+		struct bpf_devmap_val entry = {
+			.ifindex = env.ifindex,
+		};
+
+		err = bpf_map__update_elem(skel->maps.dev_map,
+					   &key, sizeof(key),
+					   &entry, sizeof(entry), 0);
+		if (err < 0)
+			return err;
+
+		fd = bpf_program__fd(skel->progs.xdp_do_redirect_cpumap);
+	}
+	case NETDEV_XDP_ACT_REDIRECT: {
+		struct bpf_cpumap_val entry = {
+			.qsize = 2048,
+			.bpf_prog.fd = fd,
+		};
+
+		err = bpf_map__update_elem(skel->maps.cpu_map,
+					   &key, sizeof(key),
+					   &entry, sizeof(entry), 0);
+		if (err < 0)
+			return err;
+
+		prog = skel->progs.xdp_do_redirect;
+		break;
+	}
+	default:
+		return -EINVAL;
+	}
+
+	err = bpf_xdp_attach(env.ifindex, bpf_program__fd(prog), flags, NULL);
+	if (err)
+		fprintf(stderr,
+			"Failed to attach XDP program to ifindex %d\n",
+			env.ifindex);
+	return err;
+}
+
+static int __recv_msg(int sockfd, void *buf, size_t bufsize,
+		      unsigned int *val, unsigned int val_size)
+{
+	struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
+	int len, n = sizeof(*tlv), i = 0;
+
+	len = recv(sockfd, buf, bufsize, 0);
+	if (len != ntohs(tlv->len))
+		return -EINVAL;
+
+	while (n < len && i < val_size) {
+		val[i] = ntohl(tlv->data[i]);
+		n += sizeof(tlv->data[0]);
+		i++;
+	}
+
+	return i;
+}
+
+static int recv_msg(int sockfd, void *buf, size_t bufsize)
+{
+	return __recv_msg(sockfd, buf, bufsize, NULL, 0);
+}
+
+static int dut_run(struct test_xdp_features *skel)
+{
+	int flags = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_DRV_MODE;
+	int state, err, sockfd, ctrl_sockfd, echo_sockfd, optval = 1;
+	struct sockaddr_in ctrl_addr, addr = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = htonl(INADDR_ANY),
+		.sin_port = htons(DUT_CTRL_PORT),
+	};
+	unsigned int len = sizeof(ctrl_addr);
+	pthread_t dut_thread;
+
+	sockfd = socket(AF_INET, SOCK_STREAM, 0);
+	if (sockfd < 0) {
+		fprintf(stderr, "Failed to create DUT socket\n");
+		return -errno;
+	}
+
+	err = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval,
+			 sizeof(optval));
+	if (err < 0) {
+		fprintf(stderr, "Failed sockopt on DUT socket\n");
+		return -errno;
+	}
+
+	err = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
+	if (err < 0) {
+		fprintf(stderr, "Failed to bind DUT socket\n");
+		return -errno;
+	}
+
+	err = listen(sockfd, 5);
+	if (err) {
+		fprintf(stderr, "Failed to listen DUT socket\n");
+		return -errno;
+	}
+
+	ctrl_sockfd = accept(sockfd, (struct sockaddr *)&ctrl_addr, &len);
+	if (ctrl_sockfd < 0) {
+		fprintf(stderr, "Failed to accept connection on DUT socket\n");
+		close(sockfd);
+		return -errno;
+	}
+
+	/* CTRL loop */
+	while (!exiting) {
+		unsigned char buf[BUFSIZE] = {};
+		struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
+
+		err = recv_msg(ctrl_sockfd, buf, BUFSIZE);
+		if (err)
+			continue;
+
+		switch (ntohs(tlv->type)) {
+		case CMD_START: {
+			if (state == CMD_START)
+				continue;
+
+			state = CMD_START;
+			/* Load the XDP program on the DUT */
+			err = dut_attach_xdp_prog(skel, ntohl(tlv->data[0]), flags);
+			if (err)
+				goto out;
+
+			err = dut_run_echo_thread(&dut_thread, &echo_sockfd);
+			if (err < 0)
+				goto out;
+
+			tlv->type = htons(CMD_ACK);
+			tlv->len = htons(sizeof(*tlv));
+			err = send(ctrl_sockfd, buf, sizeof(*tlv), 0);
+			if (err < 0)
+				goto end_thread;
+			break;
+		}
+		case CMD_STOP:
+			if (state != CMD_START)
+				break;
+
+			state = CMD_STOP;
+
+			exiting = true;
+			bpf_xdp_detach(env.ifindex, flags, NULL);
+
+			tlv->type = htons(CMD_ACK);
+			tlv->len = htons(sizeof(*tlv));
+			err = send(ctrl_sockfd, buf, sizeof(*tlv), 0);
+			goto end_thread;
+		case CMD_GET_XDP_CAP: {
+			LIBBPF_OPTS(bpf_xdp_query_opts, opts);
+			size_t n;
+
+			err = bpf_xdp_query(env.ifindex, XDP_FLAGS_DRV_MODE,
+					    &opts);
+			if (err) {
+				fprintf(stderr,
+					"Failed to query XDP cap for ifindex %d\n",
+					env.ifindex);
+				goto end_thread;
+			}
+
+			tlv->type = htons(CMD_ACK);
+			n = sizeof(*tlv) + sizeof(opts.fflags);
+			tlv->len = htons(n);
+			tlv->data[0] = htonl(opts.fflags);
+
+			err = send(ctrl_sockfd, buf, n, 0);
+			if (err < 0)
+				goto end_thread;
+			break;
+		}
+		case CMD_GET_STATS: {
+			unsigned int key = 0, val;
+			size_t n;
+
+			err = bpf_map__lookup_elem(skel->maps.dut_stats,
+						   &key, sizeof(key),
+						   &val, sizeof(val), 0);
+			if (err) {
+				fprintf(stderr, "bpf_map_lookup_elem failed\n");
+				goto end_thread;
+			}
+
+			tlv->type = htons(CMD_ACK);
+			n = sizeof(*tlv) + sizeof(val);
+			tlv->len = htons(n);
+			tlv->data[0] = htonl(val);
+
+			err = send(ctrl_sockfd, buf, n, 0);
+			if (err < 0)
+				goto end_thread;
+			break;
+		}
+		default:
+			break;
+		}
+	}
+
+end_thread:
+	pthread_join(dut_thread, NULL);
+out:
+	bpf_xdp_detach(env.ifindex, flags, NULL);
+	close(ctrl_sockfd);
+	close(sockfd);
+
+	return err;
+}
+
+static bool tester_collect_advertised_cap(unsigned int cap)
+{
+	return cap & env.feature;
+}
+
+static bool tester_collect_detected_cap(struct test_xdp_features *skel,
+					unsigned int dut_stats)
+{
+	unsigned int err, key = 0, val;
+
+	if (!dut_stats)
+		return false;
+
+	err = bpf_map__lookup_elem(skel->maps.stats, &key, sizeof(key),
+				   &val, sizeof(val), 0);
+	if (err) {
+		fprintf(stderr, "bpf_map_lookup_elem failed\n");
+		return false;
+	}
+
+	switch (env.feature) {
+	case NETDEV_XDP_ACT_PASS:
+	case NETDEV_XDP_ACT_TX:
+	case NETDEV_XDP_ACT_REDIRECT:
+	case NETDEV_XDP_ACT_NDO_XMIT:
+		return val > 0;
+	case NETDEV_XDP_ACT_DROP:
+	case NETDEV_XDP_ACT_ABORTED:
+		return val == 0;
+	default:
+		return false;
+	}
+}
+
+static int __send_and_recv_msg(int sockfd, enum test_commands cmd,
+			       unsigned int *val, unsigned int val_size)
+{
+	unsigned char buf[BUFSIZE] = {};
+	struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
+	int n = sizeof(*tlv), err;
+
+	tlv->type = htons(cmd);
+	switch (cmd) {
+	case CMD_START:
+		tlv->data[0] = htonl(env.feature);
+		n += sizeof(*val);
+		break;
+	default:
+		break;
+	}
+	tlv->len = htons(n);
+
+	err = send(sockfd, buf, n, 0);
+	if (err < 0)
+		return err;
+
+	err = __recv_msg(sockfd, buf, BUFSIZE, val, val_size);
+	if (err < 0)
+		return err;
+
+	return ntohs(tlv->type) == CMD_ACK ? 0 : -EINVAL;
+}
+
+static int send_and_recv_msg(int sockfd, enum test_commands cmd)
+{
+	return __send_and_recv_msg(sockfd, cmd, NULL, 0);
+}
+
+static int send_echo_msg(void)
+{
+	struct sockaddr_in addr = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = env.dut_ip,
+		.sin_port = htons(DUT_ECHO_PORT),
+	};
+	unsigned char buf[sizeof(struct tlv_hdr)];
+	struct tlv_hdr *tlv = (struct tlv_hdr *)buf;
+	int sockfd, n;
+
+	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sockfd < 0) {
+		fprintf(stderr, "Failed to create echo socket\n");
+		return -errno;
+	}
+
+	tlv->type = htons(CMD_ECHO);
+	tlv->len = htons(sizeof(*tlv));
+
+	n = sendto(sockfd, buf, sizeof(*tlv), MSG_NOSIGNAL | MSG_CONFIRM,
+		   (struct sockaddr *)&addr, sizeof(addr));
+	close(sockfd);
+
+	return n == ntohs(tlv->len) ? 0 : -EINVAL;
+}
+
+static int tester_run(struct test_xdp_features *skel)
+{
+	int flags = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_DRV_MODE;
+	struct sockaddr_in addr = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = env.dut_ctrl_ip,
+		.sin_port = htons(DUT_CTRL_PORT),
+	};
+	bool advertised_cap;
+	int i, err, sockfd;
+	bool detected_cap;
+	unsigned int val[1];
+
+	sockfd = socket(AF_INET, SOCK_STREAM, 0);
+	if (sockfd < 0) {
+		fprintf(stderr, "Failed to create tester socket\n");
+		return -errno;
+	}
+
+	for (i = 0; i < 10; i++) {
+		/* connect ctrl channel */
+		if (!connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)))
+			break;
+		sleep(1);
+	}
+
+	if (i == 10) {
+		fprintf(stderr, "Failed to connect to the DUT\n");
+		return -ETIMEDOUT;
+	}
+
+	err = __send_and_recv_msg(sockfd, CMD_GET_XDP_CAP, val, ARRAY_SIZE(val));
+	if (err < 0) {
+		close(sockfd);
+		return err;
+	}
+
+	advertised_cap = tester_collect_advertised_cap(val[0]);
+
+	err = bpf_xdp_attach(env.ifindex,
+			     bpf_program__fd(skel->progs.xdp_tester),
+			     flags, NULL);
+	if (err) {
+		fprintf(stderr, "Failed to attach XDP program to ifindex %d\n",
+			env.ifindex);
+		goto out;
+	}
+
+	err = send_and_recv_msg(sockfd, CMD_START);
+	if (err)
+		goto out;
+
+	for (i = 0; i < 10 && !exiting; i++) {
+		err = send_echo_msg();
+		if (err < 0)
+			goto out;
+
+		sleep(1);
+	}
+
+	err = __send_and_recv_msg(sockfd, CMD_GET_STATS, val, ARRAY_SIZE(val));
+	if (err)
+		goto out;
+
+	/* stop the test */
+	err = send_and_recv_msg(sockfd, CMD_STOP);
+	/* send a new echo message to wake echo thread of the dut */
+	send_echo_msg();
+
+	detected_cap = tester_collect_detected_cap(skel, val[0]);
+
+	fprintf(stdout, "Feature %s: [%s][%s]\n", get_xdp_feature_str(env.feature),
+		detected_cap ? GREEN("DETECTED") : RED("NOT DETECTED"),
+		advertised_cap ? GREEN("ADVERTISED") : RED("NOT ADVERTISED"));
+out:
+	bpf_xdp_detach(env.ifindex, flags, NULL);
+	close(sockfd);
+	return err < 0 ? err : 0;
+}
+
+int main(int argc, char **argv)
+{
+	struct test_xdp_features *skel;
+	int err;
+
+	libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
+	libbpf_set_print(libbpf_print_fn);
+
+	signal(SIGINT, sig_handler);
+	signal(SIGTERM, sig_handler);
+
+	set_env_defaul();
+
+	/* Parse command line arguments */
+	err = argp_parse(&argp, argc, argv, 0, NULL, NULL);
+	if (err)
+		return err;
+
+	if (env.ifindex < 0) {
+		fprintf(stderr, "Invalid ifindex\n");
+		return -ENODEV;
+	}
+
+	/* Load and verify BPF application */
+	skel = test_xdp_features__open();
+	if (!skel) {
+		fprintf(stderr, "Failed to open and load BPF skeleton\n");
+		return -EINVAL;
+	}
+
+	skel->rodata->expected_feature = env.feature;
+	skel->rodata->dut_ip = env.dut_ip;
+	skel->rodata->tester_ip = env.tester_ip;
+
+	/* Load & verify BPF programs */
+	err = test_xdp_features__load(skel);
+	if (err) {
+		fprintf(stderr, "Failed to load and verify BPF skeleton\n");
+		goto cleanup;
+	}
+
+	err = test_xdp_features__attach(skel);
+	if (err) {
+		fprintf(stderr, "Failed to attach BPF skeleton\n");
+		goto cleanup;
+	}
+
+	if (env.tester) {
+		/* Tester */
+		fprintf(stdout, "Starting tester on device %d\n", env.ifindex);
+		err = tester_run(skel);
+	} else {
+		/* DUT */
+		fprintf(stdout, "Starting DUT on device %d\n", env.ifindex);
+		err = dut_run(skel);
+	}
+
+cleanup:
+	test_xdp_features__destroy(skel);
+
+	return err < 0 ? -err : 0;
+}
-- 
2.39.0

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
  2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-21  1:19     ` Alexei Starovoitov
  -1 siblings, 0 replies; 52+ messages in thread
From: Alexei Starovoitov @ 2023-01-21  1:19 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: bpf, Network Development, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, David S. Miller, Jakub Kicinski,
	Jesper Dangaard Brouer, Paolo Abeni, Eric Dumazet,
	Toke Høiland-Jørgensen, Kumar Kartikeya Dwivedi,
	Marek Majtyka, Saeed Mahameed, anthony.l.nguyen, Andy Gospodarek,
	vladimir.oltean, Felix Fietkau, john, leon, Simon Horman,
	Ariel Elior, christophe.jaillet, ecree.xilinx,
	Michael S. Tsirkin, Björn Töpel, Karlsson, Magnus,
	Fijalkowski, Maciej, intel-wired-lan, Lorenzo Bianconi,
	Niklas Söderlund

On Fri, Jan 20, 2023 at 9:17 AM Lorenzo Bianconi <lorenzo@kernel.org> wrote:
> +
> +#define NETDEV_XDP_ACT_BASIC           (NETDEV_XDP_ACT_DROP |  \
> +                                        NETDEV_XDP_ACT_PASS |  \
> +                                        NETDEV_XDP_ACT_TX |    \
> +                                        NETDEV_XDP_ACT_ABORTED)

Why split it into 4?
Is there a driver that does a subset?

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
@ 2023-01-21  1:19     ` Alexei Starovoitov
  0 siblings, 0 replies; 52+ messages in thread
From: Alexei Starovoitov @ 2023-01-21  1:19 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Michael S. Tsirkin, vladimir.oltean, Alexei Starovoitov,
	Eric Dumazet, anthony.l.nguyen, Daniel Borkmann,
	Niklas Söderlund, Andrii Nakryiko, intel-wired-lan,
	Simon Horman, Jakub Kicinski, Paolo Abeni, Ariel Elior,
	Jesper Dangaard Brouer, christophe.jaillet,
	Kumar Kartikeya Dwivedi, john, Björn Töpel, bpf,
	Karlsson, Magnus, leon, Network Development,
	Toke Høiland-Jørgensen, ecree.xilinx, Marek Majtyka,
	Andy Gospodarek, Saeed Mahameed, David S. Miller, Felix Fietkau

On Fri, Jan 20, 2023 at 9:17 AM Lorenzo Bianconi <lorenzo@kernel.org> wrote:
> +
> +#define NETDEV_XDP_ACT_BASIC           (NETDEV_XDP_ACT_DROP |  \
> +                                        NETDEV_XDP_ACT_PASS |  \
> +                                        NETDEV_XDP_ACT_TX |    \
> +                                        NETDEV_XDP_ACT_ABORTED)

Why split it into 4?
Is there a driver that does a subset?
_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 6/7] bpf: devmap: check XDP features in bpf_map_update_elem and __xdp_enqueue
  2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-21  2:02     ` Martin KaFai Lau
  -1 siblings, 0 replies; 52+ messages in thread
From: Martin KaFai Lau @ 2023-01-21  2:02 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: netdev, ast, daniel, andrii, davem, kuba, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund, bpf

On 1/20/23 9:16 AM, Lorenzo Bianconi wrote:
> ---
>   kernel/bpf/devmap.c | 25 +++++++++++++++++++++----
>   net/core/filter.c   | 13 +++++--------
>   2 files changed, 26 insertions(+), 12 deletions(-)
> 
> diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
> index d01e4c55b376..69ceecc792df 100644
> --- a/kernel/bpf/devmap.c
> +++ b/kernel/bpf/devmap.c
> @@ -474,7 +474,11 @@ static inline int __xdp_enqueue(struct net_device *dev, struct xdp_frame *xdpf,
>   {
>   	int err;
>   
> -	if (!dev->netdev_ops->ndo_xdp_xmit)
> +	if (!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))

The current "dev->netdev_ops->ndo_xdp_xmit" check is self explaining.
Any plan to put some document for the NETDEV_XDP_ACT_* values?


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 6/7] bpf: devmap: check XDP features in bpf_map_update_elem and __xdp_enqueue
@ 2023-01-21  2:02     ` Martin KaFai Lau
  0 siblings, 0 replies; 52+ messages in thread
From: Martin KaFai Lau @ 2023-01-21  2:02 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, kuba,
	pabeni, aelior, hawk, christophe.jaillet, memxor, john, bjorn,
	bpf, magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

On 1/20/23 9:16 AM, Lorenzo Bianconi wrote:
> ---
>   kernel/bpf/devmap.c | 25 +++++++++++++++++++++----
>   net/core/filter.c   | 13 +++++--------
>   2 files changed, 26 insertions(+), 12 deletions(-)
> 
> diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
> index d01e4c55b376..69ceecc792df 100644
> --- a/kernel/bpf/devmap.c
> +++ b/kernel/bpf/devmap.c
> @@ -474,7 +474,11 @@ static inline int __xdp_enqueue(struct net_device *dev, struct xdp_frame *xdpf,
>   {
>   	int err;
>   
> -	if (!dev->netdev_ops->ndo_xdp_xmit)
> +	if (!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))

The current "dev->netdev_ops->ndo_xdp_xmit" check is self explaining.
Any plan to put some document for the NETDEV_XDP_ACT_* values?

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
  2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-21  3:11     ` Jakub Kicinski
  -1 siblings, 0 replies; 52+ messages in thread
From: Jakub Kicinski @ 2023-01-21  3:11 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: bpf, netdev, ast, daniel, andrii, davem, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

On Fri, 20 Jan 2023 18:16:50 +0100 Lorenzo Bianconi wrote:
> From: Jakub Kicinski <kuba@kernel.org>
> 
> Add a Netlink spec-compatible family for netdevs.
> This is a very simple implementation without much
> thought going into it.
> 
> It allows us to reap all the benefits of Netlink specs,
> one can use the generic client to issue the commands:
> 
>   $ ./gen.py --spec netdev.yaml --do dev_get --json='{"ifindex": 2}'
>   {'ifindex': 2, 'xdp-features': 31}
> 
>   $ ./gen.py --spec netdev.yaml --dump dev_get
>   [{'ifindex': 1, 'xdp-features': 0}, {'ifindex': 2, 'xdp-features': 31}]

In the meantime I added support for rendering enums in Python.
So you can show names in the example. eg:

$ ./cli.py --spec netdev.yaml --dump dev_get 
[{'ifindex': 1, 'xdp-features': set()},
 {'ifindex': 2,
  'xdp-features': {'ndo-xmit', 'pass', 'redirect', 'aborted', 'drop'}},
 {'ifindex': 3, 'xdp-features': {'rx-sg'}}]

> the generic python library does not have flags-by-name
> support, yet, but we also don't have to carry strings
> in the messages, as user space can get the names from
> the spec.
> 
> Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Co-developed-by: Marek Majtyka <alardam@gmail.com>
> Signed-off-by: Marek Majtyka <alardam@gmail.com>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
>  Documentation/netlink/specs/netdev.yaml |  72 ++++++++++

FWIW I'm not 100% sure if we should scope the family to all of netdev
or just xdp. Same for the name of the op, should we call the op dev_get
or dev_xdp_get..

> diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
> new file mode 100644
> index 000000000000..254fc336d469
> --- /dev/null
> +++ b/include/uapi/linux/netdev.h
> @@ -0,0 +1,66 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +/* Do not edit directly, auto-generated from: */

Like this line says, you can't hand edit this file.
Next time someone adds an attribute all your changes will be wiped.

> +/*	Documentation/netlink/specs/netdev.yaml */
> +/* YNL-GEN uapi header */
> +
> +#ifndef _UAPI_LINUX_NETDEV_H
> +#define _UAPI_LINUX_NETDEV_H
> +
> +#define NETDEV_FAMILY_NAME	"netdev"
> +#define NETDEV_FAMILY_VERSION	1
> +
> +enum netdev_xdp_act {
> +	NETDEV_XDP_ACT_ABORTED_BIT,
> +	NETDEV_XDP_ACT_DROP_BIT,
> +	NETDEV_XDP_ACT_PASS_BIT,
> +	NETDEV_XDP_ACT_TX_BIT,
> +	NETDEV_XDP_ACT_REDIRECT_BIT,
> +	NETDEV_XDP_ACT_NDO_XMIT_BIT,
> +	NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT,
> +	NETDEV_XDP_ACT_HW_OFFLOAD_BIT,
> +	NETDEV_XDP_ACT_RX_SG_BIT,
> +	NETDEV_XDP_ACT_NDO_XMIT_SG_BIT

You need to add -bit to all the enum names in the yaml if you want 
to have _BIT in the name here.

> +};
> +
> +#define NETDEV_XDP_ACT_ABORTED		BIT(NETDEV_XDP_ACT_ABORTED_BIT)
> +#define NETDEV_XDP_ACT_DROP		BIT(NETDEV_XDP_ACT_DROP_BIT)
> +#define NETDEV_XDP_ACT_PASS		BIT(NETDEV_XDP_ACT_PASS_BIT)
> +#define NETDEV_XDP_ACT_TX		BIT(NETDEV_XDP_ACT_TX_BIT)
> +#define NETDEV_XDP_ACT_REDIRECT		BIT(NETDEV_XDP_ACT_REDIRECT_BIT)
> +#define NETDEV_XDP_ACT_NDO_XMIT		BIT(NETDEV_XDP_ACT_NDO_XMIT_BIT)
> +#define NETDEV_XDP_ACT_XSK_ZEROCOPY	BIT(NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT)
> +#define NETDEV_XDP_ACT_HW_OFFLOAD	BIT(NETDEV_XDP_ACT_HW_OFFLOAD_BIT)
> +#define NETDEV_XDP_ACT_RX_SG		BIT(NETDEV_XDP_ACT_RX_SG_BIT)
> +#define NETDEV_XDP_ACT_NDO_XMIT_SG	BIT(NETDEV_XDP_ACT_NDO_XMIT_SG_BIT)
> +
> +#define NETDEV_XDP_ACT_BASIC		(NETDEV_XDP_ACT_DROP |	\
> +					 NETDEV_XDP_ACT_PASS |	\
> +					 NETDEV_XDP_ACT_TX |	\
> +					 NETDEV_XDP_ACT_ABORTED)
> +#define NETDEV_XDP_ACT_FULL		(NETDEV_XDP_ACT_BASIC |	\
> +					 NETDEV_XDP_ACT_REDIRECT)
> +#define NETDEV_XDP_ACT_ZC		(NETDEV_XDP_ACT_FULL |	\
> +					 NETDEV_XDP_ACT_XSK_ZEROCOPY)

These defines don't belong in uAPI. Especially the use of BIT().

> +			if (err < 0)
> +				break;
> +cont:
> +			idx++;
> +		}
> +	}
> +
> +	rtnl_unlock();
> +
> +	if (err != -EMSGSIZE)
> +		return err;
> +
> +	cb->args[1] = idx;
> +	cb->args[0] = h;
> +	cb->seq = net->dev_base_seq;
> +	nl_dump_check_consistent(cb, nlmsg_hdr(skb));

I think that this line can be dropped.

> +	return skb->len;
> +}

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
@ 2023-01-21  3:11     ` Jakub Kicinski
  0 siblings, 0 replies; 52+ messages in thread
From: Jakub Kicinski @ 2023-01-21  3:11 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, pabeni,
	aelior, hawk, christophe.jaillet, memxor, john, bjorn, bpf,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

On Fri, 20 Jan 2023 18:16:50 +0100 Lorenzo Bianconi wrote:
> From: Jakub Kicinski <kuba@kernel.org>
> 
> Add a Netlink spec-compatible family for netdevs.
> This is a very simple implementation without much
> thought going into it.
> 
> It allows us to reap all the benefits of Netlink specs,
> one can use the generic client to issue the commands:
> 
>   $ ./gen.py --spec netdev.yaml --do dev_get --json='{"ifindex": 2}'
>   {'ifindex': 2, 'xdp-features': 31}
> 
>   $ ./gen.py --spec netdev.yaml --dump dev_get
>   [{'ifindex': 1, 'xdp-features': 0}, {'ifindex': 2, 'xdp-features': 31}]

In the meantime I added support for rendering enums in Python.
So you can show names in the example. eg:

$ ./cli.py --spec netdev.yaml --dump dev_get 
[{'ifindex': 1, 'xdp-features': set()},
 {'ifindex': 2,
  'xdp-features': {'ndo-xmit', 'pass', 'redirect', 'aborted', 'drop'}},
 {'ifindex': 3, 'xdp-features': {'rx-sg'}}]

> the generic python library does not have flags-by-name
> support, yet, but we also don't have to carry strings
> in the messages, as user space can get the names from
> the spec.
> 
> Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Co-developed-by: Marek Majtyka <alardam@gmail.com>
> Signed-off-by: Marek Majtyka <alardam@gmail.com>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
>  Documentation/netlink/specs/netdev.yaml |  72 ++++++++++

FWIW I'm not 100% sure if we should scope the family to all of netdev
or just xdp. Same for the name of the op, should we call the op dev_get
or dev_xdp_get..

> diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
> new file mode 100644
> index 000000000000..254fc336d469
> --- /dev/null
> +++ b/include/uapi/linux/netdev.h
> @@ -0,0 +1,66 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +/* Do not edit directly, auto-generated from: */

Like this line says, you can't hand edit this file.
Next time someone adds an attribute all your changes will be wiped.

> +/*	Documentation/netlink/specs/netdev.yaml */
> +/* YNL-GEN uapi header */
> +
> +#ifndef _UAPI_LINUX_NETDEV_H
> +#define _UAPI_LINUX_NETDEV_H
> +
> +#define NETDEV_FAMILY_NAME	"netdev"
> +#define NETDEV_FAMILY_VERSION	1
> +
> +enum netdev_xdp_act {
> +	NETDEV_XDP_ACT_ABORTED_BIT,
> +	NETDEV_XDP_ACT_DROP_BIT,
> +	NETDEV_XDP_ACT_PASS_BIT,
> +	NETDEV_XDP_ACT_TX_BIT,
> +	NETDEV_XDP_ACT_REDIRECT_BIT,
> +	NETDEV_XDP_ACT_NDO_XMIT_BIT,
> +	NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT,
> +	NETDEV_XDP_ACT_HW_OFFLOAD_BIT,
> +	NETDEV_XDP_ACT_RX_SG_BIT,
> +	NETDEV_XDP_ACT_NDO_XMIT_SG_BIT

You need to add -bit to all the enum names in the yaml if you want 
to have _BIT in the name here.

> +};
> +
> +#define NETDEV_XDP_ACT_ABORTED		BIT(NETDEV_XDP_ACT_ABORTED_BIT)
> +#define NETDEV_XDP_ACT_DROP		BIT(NETDEV_XDP_ACT_DROP_BIT)
> +#define NETDEV_XDP_ACT_PASS		BIT(NETDEV_XDP_ACT_PASS_BIT)
> +#define NETDEV_XDP_ACT_TX		BIT(NETDEV_XDP_ACT_TX_BIT)
> +#define NETDEV_XDP_ACT_REDIRECT		BIT(NETDEV_XDP_ACT_REDIRECT_BIT)
> +#define NETDEV_XDP_ACT_NDO_XMIT		BIT(NETDEV_XDP_ACT_NDO_XMIT_BIT)
> +#define NETDEV_XDP_ACT_XSK_ZEROCOPY	BIT(NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT)
> +#define NETDEV_XDP_ACT_HW_OFFLOAD	BIT(NETDEV_XDP_ACT_HW_OFFLOAD_BIT)
> +#define NETDEV_XDP_ACT_RX_SG		BIT(NETDEV_XDP_ACT_RX_SG_BIT)
> +#define NETDEV_XDP_ACT_NDO_XMIT_SG	BIT(NETDEV_XDP_ACT_NDO_XMIT_SG_BIT)
> +
> +#define NETDEV_XDP_ACT_BASIC		(NETDEV_XDP_ACT_DROP |	\
> +					 NETDEV_XDP_ACT_PASS |	\
> +					 NETDEV_XDP_ACT_TX |	\
> +					 NETDEV_XDP_ACT_ABORTED)
> +#define NETDEV_XDP_ACT_FULL		(NETDEV_XDP_ACT_BASIC |	\
> +					 NETDEV_XDP_ACT_REDIRECT)
> +#define NETDEV_XDP_ACT_ZC		(NETDEV_XDP_ACT_FULL |	\
> +					 NETDEV_XDP_ACT_XSK_ZEROCOPY)

These defines don't belong in uAPI. Especially the use of BIT().

> +			if (err < 0)
> +				break;
> +cont:
> +			idx++;
> +		}
> +	}
> +
> +	rtnl_unlock();
> +
> +	if (err != -EMSGSIZE)
> +		return err;
> +
> +	cb->args[1] = idx;
> +	cb->args[0] = h;
> +	cb->seq = net->dev_base_seq;
> +	nl_dump_check_consistent(cb, nlmsg_hdr(skb));

I think that this line can be dropped.

> +	return skb->len;
> +}
_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 2/7] drivers: net: turn on XDP features
  2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-21  3:11     ` Jakub Kicinski
  -1 siblings, 0 replies; 52+ messages in thread
From: Jakub Kicinski @ 2023-01-21  3:11 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: bpf, netdev, ast, daniel, andrii, davem, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

On Fri, 20 Jan 2023 18:16:51 +0100 Lorenzo Bianconi wrote:
> +static inline void
> +xdp_features_set_redirect_target(xdp_features_t *xdp_features, bool support_sg)
> +{
> +	*xdp_features |= NETDEV_XDP_ACT_NDO_XMIT;
> +	if (support_sg)
> +		*xdp_features |= NETDEV_XDP_ACT_NDO_XMIT_SG;
> +}
> +
> +static inline void
> +xdp_features_clear_redirect_target(xdp_features_t *xdp_features)
> +{
> +	*xdp_features &= ~(NETDEV_XDP_ACT_NDO_XMIT |
> +			   NETDEV_XDP_ACT_NDO_XMIT_SG);
> +}
> +

Shouldn't these generate netlink notifications?

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 2/7] drivers: net: turn on XDP features
@ 2023-01-21  3:11     ` Jakub Kicinski
  0 siblings, 0 replies; 52+ messages in thread
From: Jakub Kicinski @ 2023-01-21  3:11 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, pabeni,
	aelior, hawk, christophe.jaillet, memxor, john, bjorn, bpf,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

On Fri, 20 Jan 2023 18:16:51 +0100 Lorenzo Bianconi wrote:
> +static inline void
> +xdp_features_set_redirect_target(xdp_features_t *xdp_features, bool support_sg)
> +{
> +	*xdp_features |= NETDEV_XDP_ACT_NDO_XMIT;
> +	if (support_sg)
> +		*xdp_features |= NETDEV_XDP_ACT_NDO_XMIT_SG;
> +}
> +
> +static inline void
> +xdp_features_clear_redirect_target(xdp_features_t *xdp_features)
> +{
> +	*xdp_features &= ~(NETDEV_XDP_ACT_NDO_XMIT |
> +			   NETDEV_XDP_ACT_NDO_XMIT_SG);
> +}
> +

Shouldn't these generate netlink notifications?
_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 5/7] libbpf: add API to get XDP/XSK supported features
  2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-21  3:20     ` Jakub Kicinski
  -1 siblings, 0 replies; 52+ messages in thread
From: Jakub Kicinski @ 2023-01-21  3:20 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: bpf, netdev, ast, daniel, andrii, davem, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

On Fri, 20 Jan 2023 18:16:54 +0100 Lorenzo Bianconi wrote:
> +static int libbpf_netlink_resolve_genl_family_id(const char *name,
> +						 __u16 len, __u16 *id)
> +{
> +	struct libbpf_nla_req req = {
> +		.nh.nlmsg_len	= NLMSG_LENGTH(GENL_HDRLEN),
> +		.nh.nlmsg_type	= GENL_ID_CTRL,
> +		.nh.nlmsg_flags	= NLM_F_REQUEST,
> +		.gnl.cmd	= CTRL_CMD_GETFAMILY,
> +		.gnl.version	= 1,

nlctrl is version 2, shouldn't matter in practice

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 5/7] libbpf: add API to get XDP/XSK supported features
@ 2023-01-21  3:20     ` Jakub Kicinski
  0 siblings, 0 replies; 52+ messages in thread
From: Jakub Kicinski @ 2023-01-21  3:20 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, pabeni,
	aelior, hawk, christophe.jaillet, memxor, john, bjorn, bpf,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

On Fri, 20 Jan 2023 18:16:54 +0100 Lorenzo Bianconi wrote:
> +static int libbpf_netlink_resolve_genl_family_id(const char *name,
> +						 __u16 len, __u16 *id)
> +{
> +	struct libbpf_nla_req req = {
> +		.nh.nlmsg_len	= NLMSG_LENGTH(GENL_HDRLEN),
> +		.nh.nlmsg_type	= GENL_ID_CTRL,
> +		.nh.nlmsg_flags	= NLM_F_REQUEST,
> +		.gnl.cmd	= CTRL_CMD_GETFAMILY,
> +		.gnl.version	= 1,

nlctrl is version 2, shouldn't matter in practice
_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
  2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-21  4:42     ` kernel test robot
  -1 siblings, 0 replies; 52+ messages in thread
From: kernel test robot @ 2023-01-21  4:42 UTC (permalink / raw)
  To: Lorenzo Bianconi, bpf
  Cc: oe-kbuild-all, netdev, ast, daniel, andrii, davem, kuba, hawk,
	pabeni, edumazet, toke, memxor, alardam, saeedm,
	anthony.l.nguyen, gospo, vladimir.oltean, nbd, john, leon,
	simon.horman, aelior, christophe.jaillet, ecree.xilinx, mst,
	bjorn, magnus.karlsson, maciej.fijalkowski, intel-wired-lan,
	lorenzo.bianconi

Hi Lorenzo,

I love your patch! Perhaps something to improve:

[auto build test WARNING on bpf-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Lorenzo-Bianconi/netdev-genl-create-a-simple-family-for-netdev-stuff/20230121-011957
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
patch link:    https://lore.kernel.org/r/272fa19f57de2d14e9666b4cd9b1ae8a61a94807.1674234430.git.lorenzo%40kernel.org
patch subject: [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
config: x86_64-rhel-8.3-syz (https://download.01.org/0day-ci/archive/20230121/202301211259.eI8T3TMB-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/bab8ed890888146e07283e2ae27174b3562b6931
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Lorenzo-Bianconi/netdev-genl-create-a-simple-family-for-netdev-stuff/20230121-011957
        git checkout bab8ed890888146e07283e2ae27174b3562b6931
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=x86_64 olddefconfig
        make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash net/core/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   net/core/netdev-genl.c: In function 'netdev_nl_dev_fill':
>> net/core/netdev-genl.c:16:13: warning: unused variable 'err' [-Wunused-variable]
      16 |         int err;
         |             ^~~


vim +/err +16 net/core/netdev-genl.c

    10	
    11	static int
    12	netdev_nl_dev_fill(struct net_device *netdev, struct sk_buff *rsp,
    13			   u32 portid, u32 seq, int flags, u32 cmd)
    14	{
    15		void *hdr;
  > 16		int err;
    17	
    18		hdr = genlmsg_put(rsp, portid, seq, &netdev_nl_family, flags, cmd);
    19		if (!hdr)
    20			return -EMSGSIZE;
    21	
    22		if (nla_put_u32(rsp, NETDEV_A_DEV_IFINDEX, netdev->ifindex) ||
    23		    nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_FEATURES,
    24				      netdev->xdp_features, NETDEV_A_DEV_PAD)) {
    25			genlmsg_cancel(rsp, hdr);
    26			return -EINVAL;
    27		}
    28	
    29		genlmsg_end(rsp, hdr);
    30	
    31		return 0;
    32	}
    33	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
@ 2023-01-21  4:42     ` kernel test robot
  0 siblings, 0 replies; 52+ messages in thread
From: kernel test robot @ 2023-01-21  4:42 UTC (permalink / raw)
  To: Lorenzo Bianconi, bpf
  Cc: mst, vladimir.oltean, john, ast, edumazet, anthony.l.nguyen,
	daniel, andrii, intel-wired-lan, simon.horman, kuba, pabeni,
	aelior, hawk, christophe.jaillet, memxor, oe-kbuild-all, bjorn,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

Hi Lorenzo,

I love your patch! Perhaps something to improve:

[auto build test WARNING on bpf-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Lorenzo-Bianconi/netdev-genl-create-a-simple-family-for-netdev-stuff/20230121-011957
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
patch link:    https://lore.kernel.org/r/272fa19f57de2d14e9666b4cd9b1ae8a61a94807.1674234430.git.lorenzo%40kernel.org
patch subject: [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
config: x86_64-rhel-8.3-syz (https://download.01.org/0day-ci/archive/20230121/202301211259.eI8T3TMB-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/bab8ed890888146e07283e2ae27174b3562b6931
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Lorenzo-Bianconi/netdev-genl-create-a-simple-family-for-netdev-stuff/20230121-011957
        git checkout bab8ed890888146e07283e2ae27174b3562b6931
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=x86_64 olddefconfig
        make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash net/core/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   net/core/netdev-genl.c: In function 'netdev_nl_dev_fill':
>> net/core/netdev-genl.c:16:13: warning: unused variable 'err' [-Wunused-variable]
      16 |         int err;
         |             ^~~


vim +/err +16 net/core/netdev-genl.c

    10	
    11	static int
    12	netdev_nl_dev_fill(struct net_device *netdev, struct sk_buff *rsp,
    13			   u32 portid, u32 seq, int flags, u32 cmd)
    14	{
    15		void *hdr;
  > 16		int err;
    17	
    18		hdr = genlmsg_put(rsp, portid, seq, &netdev_nl_family, flags, cmd);
    19		if (!hdr)
    20			return -EMSGSIZE;
    21	
    22		if (nla_put_u32(rsp, NETDEV_A_DEV_IFINDEX, netdev->ifindex) ||
    23		    nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_FEATURES,
    24				      netdev->xdp_features, NETDEV_A_DEV_PAD)) {
    25			genlmsg_cancel(rsp, hdr);
    26			return -EINVAL;
    27		}
    28	
    29		genlmsg_end(rsp, hdr);
    30	
    31		return 0;
    32	}
    33	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests
_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 2/7] drivers: net: turn on XDP features
  2023-01-21  3:11     ` [Intel-wired-lan] " Jakub Kicinski
@ 2023-01-22 11:49       ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-22 11:49 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: bpf, netdev, ast, daniel, andrii, davem, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

[-- Attachment #1: Type: text/plain, Size: 795 bytes --]

> On Fri, 20 Jan 2023 18:16:51 +0100 Lorenzo Bianconi wrote:
> > +static inline void
> > +xdp_features_set_redirect_target(xdp_features_t *xdp_features, bool support_sg)
> > +{
> > +	*xdp_features |= NETDEV_XDP_ACT_NDO_XMIT;
> > +	if (support_sg)
> > +		*xdp_features |= NETDEV_XDP_ACT_NDO_XMIT_SG;
> > +}
> > +
> > +static inline void
> > +xdp_features_clear_redirect_target(xdp_features_t *xdp_features)
> > +{
> > +	*xdp_features &= ~(NETDEV_XDP_ACT_NDO_XMIT |
> > +			   NETDEV_XDP_ACT_NDO_XMIT_SG);
> > +}
> > +
> 
> Shouldn't these generate netlink notifications?

ack, I would say we need to add NETDEV_XDP_FEAT_CHANGE case in
netdev_genl_netdevice_event routine and maybe add a new
NETDEV_XDP_FEAT_CHANGE flag in netdev_cmd. What do you think?

Regards,
Lorenzo

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 2/7] drivers: net: turn on XDP features
@ 2023-01-22 11:49       ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-22 11:49 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, pabeni,
	aelior, hawk, christophe.jaillet, memxor, john, bjorn, bpf,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd


[-- Attachment #1.1: Type: text/plain, Size: 795 bytes --]

> On Fri, 20 Jan 2023 18:16:51 +0100 Lorenzo Bianconi wrote:
> > +static inline void
> > +xdp_features_set_redirect_target(xdp_features_t *xdp_features, bool support_sg)
> > +{
> > +	*xdp_features |= NETDEV_XDP_ACT_NDO_XMIT;
> > +	if (support_sg)
> > +		*xdp_features |= NETDEV_XDP_ACT_NDO_XMIT_SG;
> > +}
> > +
> > +static inline void
> > +xdp_features_clear_redirect_target(xdp_features_t *xdp_features)
> > +{
> > +	*xdp_features &= ~(NETDEV_XDP_ACT_NDO_XMIT |
> > +			   NETDEV_XDP_ACT_NDO_XMIT_SG);
> > +}
> > +
> 
> Shouldn't these generate netlink notifications?

ack, I would say we need to add NETDEV_XDP_FEAT_CHANGE case in
netdev_genl_netdevice_event routine and maybe add a new
NETDEV_XDP_FEAT_CHANGE flag in netdev_cmd. What do you think?

Regards,
Lorenzo

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 162 bytes --]

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 5/7] libbpf: add API to get XDP/XSK supported features
  2023-01-21  3:20     ` [Intel-wired-lan] " Jakub Kicinski
@ 2023-01-22 12:09       ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-22 12:09 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: bpf, netdev, ast, daniel, andrii, davem, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

[-- Attachment #1: Type: text/plain, Size: 512 bytes --]

> On Fri, 20 Jan 2023 18:16:54 +0100 Lorenzo Bianconi wrote:
> > +static int libbpf_netlink_resolve_genl_family_id(const char *name,
> > +						 __u16 len, __u16 *id)
> > +{
> > +	struct libbpf_nla_req req = {
> > +		.nh.nlmsg_len	= NLMSG_LENGTH(GENL_HDRLEN),
> > +		.nh.nlmsg_type	= GENL_ID_CTRL,
> > +		.nh.nlmsg_flags	= NLM_F_REQUEST,
> > +		.gnl.cmd	= CTRL_CMD_GETFAMILY,
> > +		.gnl.version	= 1,
> 
> nlctrl is version 2, shouldn't matter in practice

ack, I will fix it.

Regards,
Lorenzo

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 5/7] libbpf: add API to get XDP/XSK supported features
@ 2023-01-22 12:09       ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-22 12:09 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, pabeni,
	aelior, hawk, christophe.jaillet, memxor, john, bjorn, bpf,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd


[-- Attachment #1.1: Type: text/plain, Size: 512 bytes --]

> On Fri, 20 Jan 2023 18:16:54 +0100 Lorenzo Bianconi wrote:
> > +static int libbpf_netlink_resolve_genl_family_id(const char *name,
> > +						 __u16 len, __u16 *id)
> > +{
> > +	struct libbpf_nla_req req = {
> > +		.nh.nlmsg_len	= NLMSG_LENGTH(GENL_HDRLEN),
> > +		.nh.nlmsg_type	= GENL_ID_CTRL,
> > +		.nh.nlmsg_flags	= NLM_F_REQUEST,
> > +		.gnl.cmd	= CTRL_CMD_GETFAMILY,
> > +		.gnl.version	= 1,
> 
> nlctrl is version 2, shouldn't matter in practice

ack, I will fix it.

Regards,
Lorenzo

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 162 bytes --]

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 6/7] bpf: devmap: check XDP features in bpf_map_update_elem and __xdp_enqueue
  2023-01-21  2:02     ` [Intel-wired-lan] " Martin KaFai Lau
@ 2023-01-22 12:13       ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-22 12:13 UTC (permalink / raw)
  To: Martin KaFai Lau
  Cc: netdev, ast, daniel, andrii, davem, kuba, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund, bpf

[-- Attachment #1: Type: text/plain, Size: 950 bytes --]

> On 1/20/23 9:16 AM, Lorenzo Bianconi wrote:
> > ---
> >   kernel/bpf/devmap.c | 25 +++++++++++++++++++++----
> >   net/core/filter.c   | 13 +++++--------
> >   2 files changed, 26 insertions(+), 12 deletions(-)
> > 
> > diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
> > index d01e4c55b376..69ceecc792df 100644
> > --- a/kernel/bpf/devmap.c
> > +++ b/kernel/bpf/devmap.c
> > @@ -474,7 +474,11 @@ static inline int __xdp_enqueue(struct net_device *dev, struct xdp_frame *xdpf,
> >   {
> >   	int err;
> > -	if (!dev->netdev_ops->ndo_xdp_xmit)
> > +	if (!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))
> 
> The current "dev->netdev_ops->ndo_xdp_xmit" check is self explaining.
> Any plan to put some document for the NETDEV_XDP_ACT_* values?
> 

I am not a yaml description expert but I guess we can xdp features description
in Documentation/netlink/specs/netdev.yaml.

@Jakub: what do you think?

Regards,
Lorenzo

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 6/7] bpf: devmap: check XDP features in bpf_map_update_elem and __xdp_enqueue
@ 2023-01-22 12:13       ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-22 12:13 UTC (permalink / raw)
  To: Martin KaFai Lau
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, kuba,
	pabeni, aelior, hawk, christophe.jaillet, memxor, john, bjorn,
	bpf, magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd


[-- Attachment #1.1: Type: text/plain, Size: 950 bytes --]

> On 1/20/23 9:16 AM, Lorenzo Bianconi wrote:
> > ---
> >   kernel/bpf/devmap.c | 25 +++++++++++++++++++++----
> >   net/core/filter.c   | 13 +++++--------
> >   2 files changed, 26 insertions(+), 12 deletions(-)
> > 
> > diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
> > index d01e4c55b376..69ceecc792df 100644
> > --- a/kernel/bpf/devmap.c
> > +++ b/kernel/bpf/devmap.c
> > @@ -474,7 +474,11 @@ static inline int __xdp_enqueue(struct net_device *dev, struct xdp_frame *xdpf,
> >   {
> >   	int err;
> > -	if (!dev->netdev_ops->ndo_xdp_xmit)
> > +	if (!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))
> 
> The current "dev->netdev_ops->ndo_xdp_xmit" check is self explaining.
> Any plan to put some document for the NETDEV_XDP_ACT_* values?
> 

I am not a yaml description expert but I guess we can xdp features description
in Documentation/netlink/specs/netdev.yaml.

@Jakub: what do you think?

Regards,
Lorenzo

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 162 bytes --]

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
  2023-01-21  1:19     ` [Intel-wired-lan] " Alexei Starovoitov
@ 2023-01-22 17:45       ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-22 17:45 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: bpf, Network Development, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, David S. Miller, Jakub Kicinski,
	Jesper Dangaard Brouer, Paolo Abeni, Eric Dumazet,
	Toke Høiland-Jørgensen, Kumar Kartikeya Dwivedi,
	Marek Majtyka, Saeed Mahameed, anthony.l.nguyen, Andy Gospodarek,
	vladimir.oltean, Felix Fietkau, john, leon, Simon Horman,
	Ariel Elior, christophe.jaillet, ecree.xilinx,
	Michael S. Tsirkin, Björn Töpel, Karlsson, Magnus,
	Fijalkowski, Maciej, intel-wired-lan, Lorenzo Bianconi,
	Niklas Söderlund

[-- Attachment #1: Type: text/plain, Size: 622 bytes --]

On Jan 20, Alexei Starovoitov wrote:
> On Fri, Jan 20, 2023 at 9:17 AM Lorenzo Bianconi <lorenzo@kernel.org> wrote:
> > +
> > +#define NETDEV_XDP_ACT_BASIC           (NETDEV_XDP_ACT_DROP |  \
> > +                                        NETDEV_XDP_ACT_PASS |  \
> > +                                        NETDEV_XDP_ACT_TX |    \
> > +                                        NETDEV_XDP_ACT_ABORTED)
> 
> Why split it into 4?
> Is there a driver that does a subset?

nope, at least all drivers support NETDEV_XDP_ACT_BASIC. I guess we can squash
them and just add  NETDEV_XDP_ACT_BASIC.

Regards,
Lorenzo

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
@ 2023-01-22 17:45       ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-22 17:45 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Michael S. Tsirkin, vladimir.oltean, Alexei Starovoitov,
	Eric Dumazet, anthony.l.nguyen, Daniel Borkmann,
	Niklas Söderlund, Andrii Nakryiko, intel-wired-lan,
	Simon Horman, Jakub Kicinski, Paolo Abeni, Ariel Elior,
	Jesper Dangaard Brouer, christophe.jaillet,
	Kumar Kartikeya Dwivedi, john, Björn Töpel, bpf,
	Karlsson, Magnus, leon, Network Development,
	Toke Høiland-Jørgensen, ecree.xilinx, Marek Majtyka,
	Andy Gospodarek, Saeed Mahameed, David S. Miller, Felix Fietkau


[-- Attachment #1.1: Type: text/plain, Size: 622 bytes --]

On Jan 20, Alexei Starovoitov wrote:
> On Fri, Jan 20, 2023 at 9:17 AM Lorenzo Bianconi <lorenzo@kernel.org> wrote:
> > +
> > +#define NETDEV_XDP_ACT_BASIC           (NETDEV_XDP_ACT_DROP |  \
> > +                                        NETDEV_XDP_ACT_PASS |  \
> > +                                        NETDEV_XDP_ACT_TX |    \
> > +                                        NETDEV_XDP_ACT_ABORTED)
> 
> Why split it into 4?
> Is there a driver that does a subset?

nope, at least all drivers support NETDEV_XDP_ACT_BASIC. I guess we can squash
them and just add  NETDEV_XDP_ACT_BASIC.

Regards,
Lorenzo

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 162 bytes --]

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
  2023-01-21  3:11     ` [Intel-wired-lan] " Jakub Kicinski
@ 2023-01-22 23:00       ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-22 23:00 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: bpf, netdev, ast, daniel, andrii, davem, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

[-- Attachment #1: Type: text/plain, Size: 5083 bytes --]

> On Fri, 20 Jan 2023 18:16:50 +0100 Lorenzo Bianconi wrote:
> > From: Jakub Kicinski <kuba@kernel.org>
> > 
> > Add a Netlink spec-compatible family for netdevs.
> > This is a very simple implementation without much
> > thought going into it.
> > 
> > It allows us to reap all the benefits of Netlink specs,
> > one can use the generic client to issue the commands:
> > 
> >   $ ./gen.py --spec netdev.yaml --do dev_get --json='{"ifindex": 2}'
> >   {'ifindex': 2, 'xdp-features': 31}
> > 
> >   $ ./gen.py --spec netdev.yaml --dump dev_get
> >   [{'ifindex': 1, 'xdp-features': 0}, {'ifindex': 2, 'xdp-features': 31}]
> 
> In the meantime I added support for rendering enums in Python.
> So you can show names in the example. eg:
> 
> $ ./cli.py --spec netdev.yaml --dump dev_get 
> [{'ifindex': 1, 'xdp-features': set()},
>  {'ifindex': 2,
>   'xdp-features': {'ndo-xmit', 'pass', 'redirect', 'aborted', 'drop'}},
>  {'ifindex': 3, 'xdp-features': {'rx-sg'}}]
> 
> > the generic python library does not have flags-by-name
> > support, yet, but we also don't have to carry strings
> > in the messages, as user space can get the names from
> > the spec.
> > 
> > Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> > Co-developed-by: Marek Majtyka <alardam@gmail.com>
> > Signed-off-by: Marek Majtyka <alardam@gmail.com>
> > Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> > ---
> >  Documentation/netlink/specs/netdev.yaml |  72 ++++++++++
> 
> FWIW I'm not 100% sure if we should scope the family to all of netdev
> or just xdp. Same for the name of the op, should we call the op dev_get
> or dev_xdp_get..

is it likely we are going to add non-xdp info here in the near future? If not
I would say we can target just xdp for the moment.

> 
> > diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
> > new file mode 100644
> > index 000000000000..254fc336d469
> > --- /dev/null
> > +++ b/include/uapi/linux/netdev.h
> > @@ -0,0 +1,66 @@
> > +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> > +/* Do not edit directly, auto-generated from: */
> 
> Like this line says, you can't hand edit this file.
> Next time someone adds an attribute all your changes will be wiped.

ack, right.

> 
> > +/*	Documentation/netlink/specs/netdev.yaml */
> > +/* YNL-GEN uapi header */
> > +
> > +#ifndef _UAPI_LINUX_NETDEV_H
> > +#define _UAPI_LINUX_NETDEV_H
> > +
> > +#define NETDEV_FAMILY_NAME	"netdev"
> > +#define NETDEV_FAMILY_VERSION	1
> > +
> > +enum netdev_xdp_act {
> > +	NETDEV_XDP_ACT_ABORTED_BIT,
> > +	NETDEV_XDP_ACT_DROP_BIT,
> > +	NETDEV_XDP_ACT_PASS_BIT,
> > +	NETDEV_XDP_ACT_TX_BIT,
> > +	NETDEV_XDP_ACT_REDIRECT_BIT,
> > +	NETDEV_XDP_ACT_NDO_XMIT_BIT,
> > +	NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT,
> > +	NETDEV_XDP_ACT_HW_OFFLOAD_BIT,
> > +	NETDEV_XDP_ACT_RX_SG_BIT,
> > +	NETDEV_XDP_ACT_NDO_XMIT_SG_BIT
> 
> You need to add -bit to all the enum names in the yaml if you want 
> to have _BIT in the name here.

ack, I do not think it is needed (according to the comment below).

> 
> > +};
> > +
> > +#define NETDEV_XDP_ACT_ABORTED		BIT(NETDEV_XDP_ACT_ABORTED_BIT)
> > +#define NETDEV_XDP_ACT_DROP		BIT(NETDEV_XDP_ACT_DROP_BIT)
> > +#define NETDEV_XDP_ACT_PASS		BIT(NETDEV_XDP_ACT_PASS_BIT)
> > +#define NETDEV_XDP_ACT_TX		BIT(NETDEV_XDP_ACT_TX_BIT)
> > +#define NETDEV_XDP_ACT_REDIRECT		BIT(NETDEV_XDP_ACT_REDIRECT_BIT)
> > +#define NETDEV_XDP_ACT_NDO_XMIT		BIT(NETDEV_XDP_ACT_NDO_XMIT_BIT)
> > +#define NETDEV_XDP_ACT_XSK_ZEROCOPY	BIT(NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT)
> > +#define NETDEV_XDP_ACT_HW_OFFLOAD	BIT(NETDEV_XDP_ACT_HW_OFFLOAD_BIT)
> > +#define NETDEV_XDP_ACT_RX_SG		BIT(NETDEV_XDP_ACT_RX_SG_BIT)
> > +#define NETDEV_XDP_ACT_NDO_XMIT_SG	BIT(NETDEV_XDP_ACT_NDO_XMIT_SG_BIT)
> > +
> > +#define NETDEV_XDP_ACT_BASIC		(NETDEV_XDP_ACT_DROP |	\
> > +					 NETDEV_XDP_ACT_PASS |	\
> > +					 NETDEV_XDP_ACT_TX |	\
> > +					 NETDEV_XDP_ACT_ABORTED)
> > +#define NETDEV_XDP_ACT_FULL		(NETDEV_XDP_ACT_BASIC |	\
> > +					 NETDEV_XDP_ACT_REDIRECT)
> > +#define NETDEV_XDP_ACT_ZC		(NETDEV_XDP_ACT_FULL |	\
> > +					 NETDEV_XDP_ACT_XSK_ZEROCOPY)
> 
> These defines don't belong in uAPI. Especially the use of BIT().

since netdev xdp_features is a bitmask, can we use 'flags' as type for definitions in
netdev.yaml so we can get rid of this BIT() definitions for both user and
kernel space?

> 
> > +			if (err < 0)
> > +				break;
> > +cont:
> > +			idx++;
> > +		}
> > +	}
> > +
> > +	rtnl_unlock();
> > +
> > +	if (err != -EMSGSIZE)
> > +		return err;
> > +
> > +	cb->args[1] = idx;
> > +	cb->args[0] = h;
> > +	cb->seq = net->dev_base_seq;
> > +	nl_dump_check_consistent(cb, nlmsg_hdr(skb));
> 
> I think that this line can be dropped.

ack, I will fix it.

Regards,
Lorenzo

> 
> > +	return skb->len;
> > +}

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
@ 2023-01-22 23:00       ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-22 23:00 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, pabeni,
	aelior, hawk, christophe.jaillet, memxor, john, bjorn, bpf,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd


[-- Attachment #1.1: Type: text/plain, Size: 5083 bytes --]

> On Fri, 20 Jan 2023 18:16:50 +0100 Lorenzo Bianconi wrote:
> > From: Jakub Kicinski <kuba@kernel.org>
> > 
> > Add a Netlink spec-compatible family for netdevs.
> > This is a very simple implementation without much
> > thought going into it.
> > 
> > It allows us to reap all the benefits of Netlink specs,
> > one can use the generic client to issue the commands:
> > 
> >   $ ./gen.py --spec netdev.yaml --do dev_get --json='{"ifindex": 2}'
> >   {'ifindex': 2, 'xdp-features': 31}
> > 
> >   $ ./gen.py --spec netdev.yaml --dump dev_get
> >   [{'ifindex': 1, 'xdp-features': 0}, {'ifindex': 2, 'xdp-features': 31}]
> 
> In the meantime I added support for rendering enums in Python.
> So you can show names in the example. eg:
> 
> $ ./cli.py --spec netdev.yaml --dump dev_get 
> [{'ifindex': 1, 'xdp-features': set()},
>  {'ifindex': 2,
>   'xdp-features': {'ndo-xmit', 'pass', 'redirect', 'aborted', 'drop'}},
>  {'ifindex': 3, 'xdp-features': {'rx-sg'}}]
> 
> > the generic python library does not have flags-by-name
> > support, yet, but we also don't have to carry strings
> > in the messages, as user space can get the names from
> > the spec.
> > 
> > Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> > Co-developed-by: Marek Majtyka <alardam@gmail.com>
> > Signed-off-by: Marek Majtyka <alardam@gmail.com>
> > Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> > ---
> >  Documentation/netlink/specs/netdev.yaml |  72 ++++++++++
> 
> FWIW I'm not 100% sure if we should scope the family to all of netdev
> or just xdp. Same for the name of the op, should we call the op dev_get
> or dev_xdp_get..

is it likely we are going to add non-xdp info here in the near future? If not
I would say we can target just xdp for the moment.

> 
> > diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
> > new file mode 100644
> > index 000000000000..254fc336d469
> > --- /dev/null
> > +++ b/include/uapi/linux/netdev.h
> > @@ -0,0 +1,66 @@
> > +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> > +/* Do not edit directly, auto-generated from: */
> 
> Like this line says, you can't hand edit this file.
> Next time someone adds an attribute all your changes will be wiped.

ack, right.

> 
> > +/*	Documentation/netlink/specs/netdev.yaml */
> > +/* YNL-GEN uapi header */
> > +
> > +#ifndef _UAPI_LINUX_NETDEV_H
> > +#define _UAPI_LINUX_NETDEV_H
> > +
> > +#define NETDEV_FAMILY_NAME	"netdev"
> > +#define NETDEV_FAMILY_VERSION	1
> > +
> > +enum netdev_xdp_act {
> > +	NETDEV_XDP_ACT_ABORTED_BIT,
> > +	NETDEV_XDP_ACT_DROP_BIT,
> > +	NETDEV_XDP_ACT_PASS_BIT,
> > +	NETDEV_XDP_ACT_TX_BIT,
> > +	NETDEV_XDP_ACT_REDIRECT_BIT,
> > +	NETDEV_XDP_ACT_NDO_XMIT_BIT,
> > +	NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT,
> > +	NETDEV_XDP_ACT_HW_OFFLOAD_BIT,
> > +	NETDEV_XDP_ACT_RX_SG_BIT,
> > +	NETDEV_XDP_ACT_NDO_XMIT_SG_BIT
> 
> You need to add -bit to all the enum names in the yaml if you want 
> to have _BIT in the name here.

ack, I do not think it is needed (according to the comment below).

> 
> > +};
> > +
> > +#define NETDEV_XDP_ACT_ABORTED		BIT(NETDEV_XDP_ACT_ABORTED_BIT)
> > +#define NETDEV_XDP_ACT_DROP		BIT(NETDEV_XDP_ACT_DROP_BIT)
> > +#define NETDEV_XDP_ACT_PASS		BIT(NETDEV_XDP_ACT_PASS_BIT)
> > +#define NETDEV_XDP_ACT_TX		BIT(NETDEV_XDP_ACT_TX_BIT)
> > +#define NETDEV_XDP_ACT_REDIRECT		BIT(NETDEV_XDP_ACT_REDIRECT_BIT)
> > +#define NETDEV_XDP_ACT_NDO_XMIT		BIT(NETDEV_XDP_ACT_NDO_XMIT_BIT)
> > +#define NETDEV_XDP_ACT_XSK_ZEROCOPY	BIT(NETDEV_XDP_ACT_XSK_ZEROCOPY_BIT)
> > +#define NETDEV_XDP_ACT_HW_OFFLOAD	BIT(NETDEV_XDP_ACT_HW_OFFLOAD_BIT)
> > +#define NETDEV_XDP_ACT_RX_SG		BIT(NETDEV_XDP_ACT_RX_SG_BIT)
> > +#define NETDEV_XDP_ACT_NDO_XMIT_SG	BIT(NETDEV_XDP_ACT_NDO_XMIT_SG_BIT)
> > +
> > +#define NETDEV_XDP_ACT_BASIC		(NETDEV_XDP_ACT_DROP |	\
> > +					 NETDEV_XDP_ACT_PASS |	\
> > +					 NETDEV_XDP_ACT_TX |	\
> > +					 NETDEV_XDP_ACT_ABORTED)
> > +#define NETDEV_XDP_ACT_FULL		(NETDEV_XDP_ACT_BASIC |	\
> > +					 NETDEV_XDP_ACT_REDIRECT)
> > +#define NETDEV_XDP_ACT_ZC		(NETDEV_XDP_ACT_FULL |	\
> > +					 NETDEV_XDP_ACT_XSK_ZEROCOPY)
> 
> These defines don't belong in uAPI. Especially the use of BIT().

since netdev xdp_features is a bitmask, can we use 'flags' as type for definitions in
netdev.yaml so we can get rid of this BIT() definitions for both user and
kernel space?

> 
> > +			if (err < 0)
> > +				break;
> > +cont:
> > +			idx++;
> > +		}
> > +	}
> > +
> > +	rtnl_unlock();
> > +
> > +	if (err != -EMSGSIZE)
> > +		return err;
> > +
> > +	cb->args[1] = idx;
> > +	cb->args[0] = h;
> > +	cb->seq = net->dev_base_seq;
> > +	nl_dump_check_consistent(cb, nlmsg_hdr(skb));
> 
> I think that this line can be dropped.

ack, I will fix it.

Regards,
Lorenzo

> 
> > +	return skb->len;
> > +}

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 162 bytes --]

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
  2023-01-22 23:00       ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-23 20:01         ` Jakub Kicinski
  -1 siblings, 0 replies; 52+ messages in thread
From: Jakub Kicinski @ 2023-01-23 20:01 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: bpf, netdev, ast, daniel, andrii, davem, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

On Mon, 23 Jan 2023 00:00:15 +0100 Lorenzo Bianconi wrote:
> > FWIW I'm not 100% sure if we should scope the family to all of netdev
> > or just xdp. Same for the name of the op, should we call the op dev_get
> > or dev_xdp_get..  
> 
> is it likely we are going to add non-xdp info here in the near future? If not
> I would say we can target just xdp for the moment.

What brought it to mind for me was offloads like the NVMe/DDP for
instance. Whether that stuff should live in ethtool or a netdev
family is a bit unclear.

> > These defines don't belong in uAPI. Especially the use of BIT().  
> 
> since netdev xdp_features is a bitmask, can we use 'flags' as type for definitions in
> netdev.yaml so we can get rid of this BIT() definitions for both user and
> kernel space?

If you have no use for the bit numbers - definitely.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
@ 2023-01-23 20:01         ` Jakub Kicinski
  0 siblings, 0 replies; 52+ messages in thread
From: Jakub Kicinski @ 2023-01-23 20:01 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, pabeni,
	aelior, hawk, christophe.jaillet, memxor, john, bjorn, bpf,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

On Mon, 23 Jan 2023 00:00:15 +0100 Lorenzo Bianconi wrote:
> > FWIW I'm not 100% sure if we should scope the family to all of netdev
> > or just xdp. Same for the name of the op, should we call the op dev_get
> > or dev_xdp_get..  
> 
> is it likely we are going to add non-xdp info here in the near future? If not
> I would say we can target just xdp for the moment.

What brought it to mind for me was offloads like the NVMe/DDP for
instance. Whether that stuff should live in ethtool or a netdev
family is a bit unclear.

> > These defines don't belong in uAPI. Especially the use of BIT().  
> 
> since netdev xdp_features is a bitmask, can we use 'flags' as type for definitions in
> netdev.yaml so we can get rid of this BIT() definitions for both user and
> kernel space?

If you have no use for the bit numbers - definitely.
_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 2/7] drivers: net: turn on XDP features
  2023-01-22 11:49       ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-23 20:03         ` Jakub Kicinski
  -1 siblings, 0 replies; 52+ messages in thread
From: Jakub Kicinski @ 2023-01-23 20:03 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, pabeni,
	aelior, hawk, christophe.jaillet, memxor, john, bjorn, bpf,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

On Sun, 22 Jan 2023 12:49:20 +0100 Lorenzo Bianconi wrote:
> > Shouldn't these generate netlink notifications?  
> 
> ack, I would say we need to add NETDEV_XDP_FEAT_CHANGE case in
> netdev_genl_netdevice_event routine and maybe add a new
> NETDEV_XDP_FEAT_CHANGE flag in netdev_cmd. What do you think?

No strong preference between a full event or just a direct call until
we have another in-kernel user interested in the notification.
The changes are wrapped nicely in helpers, so we can change it later
easily.
_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 2/7] drivers: net: turn on XDP features
@ 2023-01-23 20:03         ` Jakub Kicinski
  0 siblings, 0 replies; 52+ messages in thread
From: Jakub Kicinski @ 2023-01-23 20:03 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: bpf, netdev, ast, daniel, andrii, davem, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

On Sun, 22 Jan 2023 12:49:20 +0100 Lorenzo Bianconi wrote:
> > Shouldn't these generate netlink notifications?  
> 
> ack, I would say we need to add NETDEV_XDP_FEAT_CHANGE case in
> netdev_genl_netdevice_event routine and maybe add a new
> NETDEV_XDP_FEAT_CHANGE flag in netdev_cmd. What do you think?

No strong preference between a full event or just a direct call until
we have another in-kernel user interested in the notification.
The changes are wrapped nicely in helpers, so we can change it later
easily.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 6/7] bpf: devmap: check XDP features in bpf_map_update_elem and __xdp_enqueue
  2023-01-22 12:13       ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-23 20:09         ` Jakub Kicinski
  -1 siblings, 0 replies; 52+ messages in thread
From: Jakub Kicinski @ 2023-01-23 20:09 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Martin KaFai Lau, netdev, ast, daniel, andrii, davem, hawk,
	pabeni, edumazet, toke, memxor, alardam, saeedm,
	anthony.l.nguyen, gospo, vladimir.oltean, nbd, john, leon,
	simon.horman, aelior, christophe.jaillet, ecree.xilinx, mst,
	bjorn, magnus.karlsson, maciej.fijalkowski, intel-wired-lan,
	lorenzo.bianconi, niklas.soderlund, bpf

On Sun, 22 Jan 2023 13:13:41 +0100 Lorenzo Bianconi wrote:
> > > diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
> > > index d01e4c55b376..69ceecc792df 100644
> > > --- a/kernel/bpf/devmap.c
> > > +++ b/kernel/bpf/devmap.c
> > > @@ -474,7 +474,11 @@ static inline int __xdp_enqueue(struct net_device *dev, struct xdp_frame *xdpf,
> > >   {
> > >   	int err;
> > > -	if (!dev->netdev_ops->ndo_xdp_xmit)
> > > +	if (!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))  
> > 
> > The current "dev->netdev_ops->ndo_xdp_xmit" check is self explaining.
> > Any plan to put some document for the NETDEV_XDP_ACT_* values?
> >   
> 
> I am not a yaml description expert but I guess we can xdp features description
> in Documentation/netlink/specs/netdev.yaml.
> 
> @Jakub: what do you think?

I've added the ability to document enums recently, so you may need
to rebase. But it should work and render the documentation as kdoc 
in the uAPI header (hopefully in a not-too-ugly way).

Example of YAML:
https://github.com/kuba-moo/ynl/blob/dpll/Documentation/netlink/specs/dpll.yaml#L27-L46

I've also talked to the iproute2-py maintainer about generating
documentation directly from YAML to Sphinx/htmldocs, hopefully 
that will happen, too. It would be good to have a few families 
to work with before we start that work, tho.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 6/7] bpf: devmap: check XDP features in bpf_map_update_elem and __xdp_enqueue
@ 2023-01-23 20:09         ` Jakub Kicinski
  0 siblings, 0 replies; 52+ messages in thread
From: Jakub Kicinski @ 2023-01-23 20:09 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, pabeni,
	aelior, hawk, christophe.jaillet, memxor, john, bjorn, bpf,
	magnus.karlsson, leon, netdev, toke, Martin KaFai Lau,
	ecree.xilinx, alardam, gospo, saeedm, davem, nbd

On Sun, 22 Jan 2023 13:13:41 +0100 Lorenzo Bianconi wrote:
> > > diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
> > > index d01e4c55b376..69ceecc792df 100644
> > > --- a/kernel/bpf/devmap.c
> > > +++ b/kernel/bpf/devmap.c
> > > @@ -474,7 +474,11 @@ static inline int __xdp_enqueue(struct net_device *dev, struct xdp_frame *xdpf,
> > >   {
> > >   	int err;
> > > -	if (!dev->netdev_ops->ndo_xdp_xmit)
> > > +	if (!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))  
> > 
> > The current "dev->netdev_ops->ndo_xdp_xmit" check is self explaining.
> > Any plan to put some document for the NETDEV_XDP_ACT_* values?
> >   
> 
> I am not a yaml description expert but I guess we can xdp features description
> in Documentation/netlink/specs/netdev.yaml.
> 
> @Jakub: what do you think?

I've added the ability to document enums recently, so you may need
to rebase. But it should work and render the documentation as kdoc 
in the uAPI header (hopefully in a not-too-ugly way).

Example of YAML:
https://github.com/kuba-moo/ynl/blob/dpll/Documentation/netlink/specs/dpll.yaml#L27-L46

I've also talked to the iproute2-py maintainer about generating
documentation directly from YAML to Sphinx/htmldocs, hopefully 
that will happen, too. It would be good to have a few families 
to work with before we start that work, tho.
_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 6/7] bpf: devmap: check XDP features in bpf_map_update_elem and __xdp_enqueue
  2023-01-23 20:09         ` [Intel-wired-lan] " Jakub Kicinski
@ 2023-01-23 23:29           ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-23 23:29 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Martin KaFai Lau, netdev, ast, daniel, andrii, davem, hawk,
	pabeni, edumazet, toke, memxor, alardam, saeedm,
	anthony.l.nguyen, gospo, vladimir.oltean, nbd, john, leon,
	simon.horman, aelior, christophe.jaillet, ecree.xilinx, mst,
	bjorn, magnus.karlsson, maciej.fijalkowski, intel-wired-lan,
	lorenzo.bianconi, niklas.soderlund, bpf

[-- Attachment #1: Type: text/plain, Size: 2602 bytes --]

On Jan 23, Jakub Kicinski wrote:
> On Sun, 22 Jan 2023 13:13:41 +0100 Lorenzo Bianconi wrote:
> > > > diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
> > > > index d01e4c55b376..69ceecc792df 100644
> > > > --- a/kernel/bpf/devmap.c
> > > > +++ b/kernel/bpf/devmap.c
> > > > @@ -474,7 +474,11 @@ static inline int __xdp_enqueue(struct net_device *dev, struct xdp_frame *xdpf,
> > > >   {
> > > >   	int err;
> > > > -	if (!dev->netdev_ops->ndo_xdp_xmit)
> > > > +	if (!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))  
> > > 
> > > The current "dev->netdev_ops->ndo_xdp_xmit" check is self explaining.
> > > Any plan to put some document for the NETDEV_XDP_ACT_* values?
> > >   
> > 
> > I am not a yaml description expert but I guess we can xdp features description
> > in Documentation/netlink/specs/netdev.yaml.
> > 
> > @Jakub: what do you think?
> 
> I've added the ability to document enums recently, so you may need
> to rebase. But it should work and render the documentation as kdoc 
> in the uAPI header (hopefully in a not-too-ugly way).
> 
> Example of YAML:
> https://github.com/kuba-moo/ynl/blob/dpll/Documentation/netlink/specs/dpll.yaml#L27-L46

ack, it works properly I guess, I got the following kdoc in the uAPI:

/**
 * enum netdev_xdp_act
 * @NETDEV_XDP_ACT_BASIC: XDP feautues set supported by all drivers
 *   (XDP_ABORTED, XDP_DROP, XDP_PASS, XDP_TX)
 * @NETDEV_XDP_ACT_REDIRECT: The netdev supports XDP_REDIRECT
 * @NETDEV_XDP_ACT_NDO_XMIT: This feature informs if netdev implements
 *   ndo_xdp_xmit callback.
 * @NETDEV_XDP_ACT_XSK_ZEROCOPY: This feature informs if netdev supports AF_XDP
 *   in zero copy mode.
 * @NETDEV_XDP_ACT_HW_OFFLOAD: This feature informs if netdev supports XDP hw
 *   oflloading.
 * @NETDEV_XDP_ACT_RX_SG: This feature informs if netdev implements non-linear
 *   XDP buffer support in the driver napi callback.
 * @NETDEV_XDP_ACT_NDO_XMIT_SG: This feature informs if netdev implements
 *   non-linear XDP buffer support in ndo_xdp_xmit callback.
 */
enum netdev_xdp_act {
        NETDEV_XDP_ACT_BASIC,
        NETDEV_XDP_ACT_REDIRECT,
        NETDEV_XDP_ACT_NDO_XMIT,
        NETDEV_XDP_ACT_XSK_ZEROCOPY,
        NETDEV_XDP_ACT_HW_OFFLOAD,
        NETDEV_XDP_ACT_RX_SG,
        NETDEV_XDP_ACT_NDO_XMIT_SG,
};

Regards,
Lorenzo

> 
> I've also talked to the iproute2-py maintainer about generating
> documentation directly from YAML to Sphinx/htmldocs, hopefully 
> that will happen, too. It would be good to have a few families 
> to work with before we start that work, tho.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 6/7] bpf: devmap: check XDP features in bpf_map_update_elem and __xdp_enqueue
@ 2023-01-23 23:29           ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-23 23:29 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, pabeni,
	aelior, hawk, christophe.jaillet, memxor, john, bjorn, bpf,
	magnus.karlsson, leon, netdev, toke, Martin KaFai Lau,
	ecree.xilinx, alardam, gospo, saeedm, davem, nbd


[-- Attachment #1.1: Type: text/plain, Size: 2602 bytes --]

On Jan 23, Jakub Kicinski wrote:
> On Sun, 22 Jan 2023 13:13:41 +0100 Lorenzo Bianconi wrote:
> > > > diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
> > > > index d01e4c55b376..69ceecc792df 100644
> > > > --- a/kernel/bpf/devmap.c
> > > > +++ b/kernel/bpf/devmap.c
> > > > @@ -474,7 +474,11 @@ static inline int __xdp_enqueue(struct net_device *dev, struct xdp_frame *xdpf,
> > > >   {
> > > >   	int err;
> > > > -	if (!dev->netdev_ops->ndo_xdp_xmit)
> > > > +	if (!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))  
> > > 
> > > The current "dev->netdev_ops->ndo_xdp_xmit" check is self explaining.
> > > Any plan to put some document for the NETDEV_XDP_ACT_* values?
> > >   
> > 
> > I am not a yaml description expert but I guess we can xdp features description
> > in Documentation/netlink/specs/netdev.yaml.
> > 
> > @Jakub: what do you think?
> 
> I've added the ability to document enums recently, so you may need
> to rebase. But it should work and render the documentation as kdoc 
> in the uAPI header (hopefully in a not-too-ugly way).
> 
> Example of YAML:
> https://github.com/kuba-moo/ynl/blob/dpll/Documentation/netlink/specs/dpll.yaml#L27-L46

ack, it works properly I guess, I got the following kdoc in the uAPI:

/**
 * enum netdev_xdp_act
 * @NETDEV_XDP_ACT_BASIC: XDP feautues set supported by all drivers
 *   (XDP_ABORTED, XDP_DROP, XDP_PASS, XDP_TX)
 * @NETDEV_XDP_ACT_REDIRECT: The netdev supports XDP_REDIRECT
 * @NETDEV_XDP_ACT_NDO_XMIT: This feature informs if netdev implements
 *   ndo_xdp_xmit callback.
 * @NETDEV_XDP_ACT_XSK_ZEROCOPY: This feature informs if netdev supports AF_XDP
 *   in zero copy mode.
 * @NETDEV_XDP_ACT_HW_OFFLOAD: This feature informs if netdev supports XDP hw
 *   oflloading.
 * @NETDEV_XDP_ACT_RX_SG: This feature informs if netdev implements non-linear
 *   XDP buffer support in the driver napi callback.
 * @NETDEV_XDP_ACT_NDO_XMIT_SG: This feature informs if netdev implements
 *   non-linear XDP buffer support in ndo_xdp_xmit callback.
 */
enum netdev_xdp_act {
        NETDEV_XDP_ACT_BASIC,
        NETDEV_XDP_ACT_REDIRECT,
        NETDEV_XDP_ACT_NDO_XMIT,
        NETDEV_XDP_ACT_XSK_ZEROCOPY,
        NETDEV_XDP_ACT_HW_OFFLOAD,
        NETDEV_XDP_ACT_RX_SG,
        NETDEV_XDP_ACT_NDO_XMIT_SG,
};

Regards,
Lorenzo

> 
> I've also talked to the iproute2-py maintainer about generating
> documentation directly from YAML to Sphinx/htmldocs, hopefully 
> that will happen, too. It would be good to have a few families 
> to work with before we start that work, tho.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 162 bytes --]

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
  2023-01-23 20:01         ` [Intel-wired-lan] " Jakub Kicinski
@ 2023-01-23 23:29           ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-23 23:29 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: bpf, netdev, ast, daniel, andrii, davem, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund

[-- Attachment #1: Type: text/plain, Size: 960 bytes --]

> On Mon, 23 Jan 2023 00:00:15 +0100 Lorenzo Bianconi wrote:
> > > FWIW I'm not 100% sure if we should scope the family to all of netdev
> > > or just xdp. Same for the name of the op, should we call the op dev_get
> > > or dev_xdp_get..  
> > 
> > is it likely we are going to add non-xdp info here in the near future? If not
> > I would say we can target just xdp for the moment.
> 
> What brought it to mind for me was offloads like the NVMe/DDP for
> instance. Whether that stuff should live in ethtool or a netdev
> family is a bit unclear.

ack, let's keep netdev in this case.

> 
> > > These defines don't belong in uAPI. Especially the use of BIT().  
> > 
> > since netdev xdp_features is a bitmask, can we use 'flags' as type for definitions in
> > netdev.yaml so we can get rid of this BIT() definitions for both user and
> > kernel space?
> 
> If you have no use for the bit numbers - definitely.

ack

Regards,
Lorenzo

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff
@ 2023-01-23 23:29           ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-23 23:29 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, pabeni,
	aelior, hawk, christophe.jaillet, memxor, john, bjorn, bpf,
	magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd


[-- Attachment #1.1: Type: text/plain, Size: 960 bytes --]

> On Mon, 23 Jan 2023 00:00:15 +0100 Lorenzo Bianconi wrote:
> > > FWIW I'm not 100% sure if we should scope the family to all of netdev
> > > or just xdp. Same for the name of the op, should we call the op dev_get
> > > or dev_xdp_get..  
> > 
> > is it likely we are going to add non-xdp info here in the near future? If not
> > I would say we can target just xdp for the moment.
> 
> What brought it to mind for me was offloads like the NVMe/DDP for
> instance. Whether that stuff should live in ethtool or a netdev
> family is a bit unclear.

ack, let's keep netdev in this case.

> 
> > > These defines don't belong in uAPI. Especially the use of BIT().  
> > 
> > since netdev xdp_features is a bitmask, can we use 'flags' as type for definitions in
> > netdev.yaml so we can get rid of this BIT() definitions for both user and
> > kernel space?
> 
> If you have no use for the bit numbers - definitely.

ack

Regards,
Lorenzo

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 162 bytes --]

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 7/7] selftests/bpf: introduce XDP compliance test tool
  2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
@ 2023-01-24  6:34     ` Martin KaFai Lau
  -1 siblings, 0 replies; 52+ messages in thread
From: Martin KaFai Lau @ 2023-01-24  6:34 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: netdev, ast, daniel, andrii, davem, kuba, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund, bpf

On 1/20/23 9:16 AM, Lorenzo Bianconi wrote:
> +static __always_inline int xdp_process_echo_packet(struct xdp_md *xdp, bool dut)
> +{
> +	void *data_end = (void *)(long)xdp->data_end;
> +	__be32 saddr = dut ? tester_ip : dut_ip;
> +	__be32 daddr = dut ? dut_ip : tester_ip;
> +	void *data = (void *)(long)xdp->data;
> +	struct ethhdr *eh = data;
> +	struct tlv_hdr *tlv;
> +	struct udphdr *uh;
> +	struct iphdr *ih;
> +	__be16 port;
> +	__u8 *cmd;
> +
> +	if (eh + 1 > (struct ethhdr *)data_end)
> +		return -EINVAL;
> +
> +	if (eh->h_proto != bpf_htons(ETH_P_IP))
> +		return -EINVAL;

Both v6 and v4 support are needed as a tool.

[ ... ]

> diff --git a/tools/testing/selftests/bpf/test_xdp_features.sh b/tools/testing/selftests/bpf/test_xdp_features.sh
> new file mode 100755
> index 000000000000..98b8fd2b6c16
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/test_xdp_features.sh
> @@ -0,0 +1,99 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +
> +# Create 2 namespaces with two veth peers, and
> +# check reported and detected XDP capabilities
> +#
> +#   NS0(v00)              NS1(v11)
> +#       |                     |
> +#       |                     |
> +# (v01, id:111)  ------  (v10,id:222)
> +
> +readonly NS0="ns1-$(mktemp -u XXXXXX)"
> +readonly NS1="ns2-$(mktemp -u XXXXXX)"
> +ret=1
> +
> +setup() {
> +	{
> +		ip netns add ${NS0}
> +		ip netns add ${NS1}
> +
> +		ip link add v01 index 111 type veth peer name v00 netns ${NS0}
> +		ip link add v10 index 222 type veth peer name v11 netns ${NS1}
> +
> +		ip link set v01 up
> +		ip addr add 10.10.0.1/24 dev v01
> +		ip link set v01 address 00:11:22:33:44:55
> +		ip -n ${NS0} link set dev v00 up
> +		ip -n ${NS0} addr add 10.10.0.11/24 dev v00
> +		ip -n ${NS0} route add default via 10.10.0.1
> +		ip -n ${NS0} link set v00 address 00:12:22:33:44:55
> +
> +		ip link set v10 up
> +		ip addr add 10.10.1.1/24 dev v10
> +		ip link set v10 address 00:13:22:33:44:55
> +		ip -n ${NS1} link set dev v11 up
> +		ip -n ${NS1} addr add 10.10.1.11/24 dev v11
> +		ip -n ${NS1} route add default via 10.10.1.1
> +		ip -n ${NS1} link set v11 address 00:14:22:33:44:55
> +
> +		sysctl -w net.ipv4.ip_forward=1
> +		# Enable XDP mode
> +		ethtool -K v01 gro on
> +		ethtool -K v01 tx-checksumming off
> +		ip netns exec ${NS0} ethtool -K v00 gro on
> +		ip netns exec ${NS0} ethtool -K v00 tx-checksumming off
> +		ethtool -K v10 gro on
> +		ethtool -K v10 tx-checksumming off
> +		ip netns exec ${NS1} ethtool -K v11 gro on
> +		ip netns exec ${NS1} ethtool -K v11 tx-checksumming off
> +	} > /dev/null 2>&1
> +}
> +
> +cleanup() {
> +	ip link del v01 2> /dev/null
> +	ip link del v10 2> /dev/null
> +	ip netns del ${NS0} 2> /dev/null
> +	ip netns del ${NS1} 2> /dev/null
> +	[ "$(pidof xdp_features)" = "" ] || kill $(pidof xdp_features) 2> /dev/null
> +}
> +
> +test_xdp_features() {
> +	setup
> +
> +	## XDP_PASS
> +	ip netns exec ${NS1} ./xdp_features -f XDP_PASS -D 10.10.1.11 -T 10.10.0.11 v11 &
> +	ip netns exec ${NS0} ./xdp_features -t -f XDP_PASS -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
> +
> +	[ $? -ne 0 ] && exit
> +
> +	# XDP_DROP
> +	ip netns exec ${NS1} ./xdp_features -f XDP_DROP -D 10.10.1.11 -T 10.10.0.11 v11 &
> +	ip netns exec ${NS0} ./xdp_features -t -f XDP_DROP -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
> +
> +	[ $? -ne 0 ] && exit
> +
> +	## XDP_TX
> +	./xdp_features -f XDP_TX -D 10.10.0.1 -T 10.10.0.11 v01 &
> +	ip netns exec ${NS0} ./xdp_features -t -f XDP_TX -D 10.10.0.1 -C 10.10.0.1 -T 10.10.0.11 v00
> +
> +	## XDP_REDIRECT
> +	ip netns exec ${NS1} ./xdp_features -f XDP_REDIRECT -D 10.10.1.11 -T 10.10.0.11 v11 &
> +	ip netns exec ${NS0} ./xdp_features -t -f XDP_REDIRECT -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
> +
> +	[ $? -ne 0 ] && exit
> +
> +	## XDP_NDO_XMIT
> +	./xdp_features -f XDP_NDO_XMIT -D 10.10.0.1 -T 10.10.0.11 v01 &
> +	ip netns exec ${NS0} ./xdp_features -t -f XDP_NDO_XMIT -D 10.10.0.1 -C 10.10.0.1 -T 10.10.0.11 v00
> +
> +	ret=$?
> +	cleanup
> +}
> +
> +set -e
> +trap cleanup 2 3 6 9
> +
> +test_xdp_features

This won't be run by bpf CI.

A selftest in test_progs is needed to test the libbpf changes in patch 6.


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 7/7] selftests/bpf: introduce XDP compliance test tool
@ 2023-01-24  6:34     ` Martin KaFai Lau
  0 siblings, 0 replies; 52+ messages in thread
From: Martin KaFai Lau @ 2023-01-24  6:34 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, kuba,
	pabeni, aelior, hawk, christophe.jaillet, memxor, john, bjorn,
	bpf, magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd

On 1/20/23 9:16 AM, Lorenzo Bianconi wrote:
> +static __always_inline int xdp_process_echo_packet(struct xdp_md *xdp, bool dut)
> +{
> +	void *data_end = (void *)(long)xdp->data_end;
> +	__be32 saddr = dut ? tester_ip : dut_ip;
> +	__be32 daddr = dut ? dut_ip : tester_ip;
> +	void *data = (void *)(long)xdp->data;
> +	struct ethhdr *eh = data;
> +	struct tlv_hdr *tlv;
> +	struct udphdr *uh;
> +	struct iphdr *ih;
> +	__be16 port;
> +	__u8 *cmd;
> +
> +	if (eh + 1 > (struct ethhdr *)data_end)
> +		return -EINVAL;
> +
> +	if (eh->h_proto != bpf_htons(ETH_P_IP))
> +		return -EINVAL;

Both v6 and v4 support are needed as a tool.

[ ... ]

> diff --git a/tools/testing/selftests/bpf/test_xdp_features.sh b/tools/testing/selftests/bpf/test_xdp_features.sh
> new file mode 100755
> index 000000000000..98b8fd2b6c16
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/test_xdp_features.sh
> @@ -0,0 +1,99 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +
> +# Create 2 namespaces with two veth peers, and
> +# check reported and detected XDP capabilities
> +#
> +#   NS0(v00)              NS1(v11)
> +#       |                     |
> +#       |                     |
> +# (v01, id:111)  ------  (v10,id:222)
> +
> +readonly NS0="ns1-$(mktemp -u XXXXXX)"
> +readonly NS1="ns2-$(mktemp -u XXXXXX)"
> +ret=1
> +
> +setup() {
> +	{
> +		ip netns add ${NS0}
> +		ip netns add ${NS1}
> +
> +		ip link add v01 index 111 type veth peer name v00 netns ${NS0}
> +		ip link add v10 index 222 type veth peer name v11 netns ${NS1}
> +
> +		ip link set v01 up
> +		ip addr add 10.10.0.1/24 dev v01
> +		ip link set v01 address 00:11:22:33:44:55
> +		ip -n ${NS0} link set dev v00 up
> +		ip -n ${NS0} addr add 10.10.0.11/24 dev v00
> +		ip -n ${NS0} route add default via 10.10.0.1
> +		ip -n ${NS0} link set v00 address 00:12:22:33:44:55
> +
> +		ip link set v10 up
> +		ip addr add 10.10.1.1/24 dev v10
> +		ip link set v10 address 00:13:22:33:44:55
> +		ip -n ${NS1} link set dev v11 up
> +		ip -n ${NS1} addr add 10.10.1.11/24 dev v11
> +		ip -n ${NS1} route add default via 10.10.1.1
> +		ip -n ${NS1} link set v11 address 00:14:22:33:44:55
> +
> +		sysctl -w net.ipv4.ip_forward=1
> +		# Enable XDP mode
> +		ethtool -K v01 gro on
> +		ethtool -K v01 tx-checksumming off
> +		ip netns exec ${NS0} ethtool -K v00 gro on
> +		ip netns exec ${NS0} ethtool -K v00 tx-checksumming off
> +		ethtool -K v10 gro on
> +		ethtool -K v10 tx-checksumming off
> +		ip netns exec ${NS1} ethtool -K v11 gro on
> +		ip netns exec ${NS1} ethtool -K v11 tx-checksumming off
> +	} > /dev/null 2>&1
> +}
> +
> +cleanup() {
> +	ip link del v01 2> /dev/null
> +	ip link del v10 2> /dev/null
> +	ip netns del ${NS0} 2> /dev/null
> +	ip netns del ${NS1} 2> /dev/null
> +	[ "$(pidof xdp_features)" = "" ] || kill $(pidof xdp_features) 2> /dev/null
> +}
> +
> +test_xdp_features() {
> +	setup
> +
> +	## XDP_PASS
> +	ip netns exec ${NS1} ./xdp_features -f XDP_PASS -D 10.10.1.11 -T 10.10.0.11 v11 &
> +	ip netns exec ${NS0} ./xdp_features -t -f XDP_PASS -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
> +
> +	[ $? -ne 0 ] && exit
> +
> +	# XDP_DROP
> +	ip netns exec ${NS1} ./xdp_features -f XDP_DROP -D 10.10.1.11 -T 10.10.0.11 v11 &
> +	ip netns exec ${NS0} ./xdp_features -t -f XDP_DROP -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
> +
> +	[ $? -ne 0 ] && exit
> +
> +	## XDP_TX
> +	./xdp_features -f XDP_TX -D 10.10.0.1 -T 10.10.0.11 v01 &
> +	ip netns exec ${NS0} ./xdp_features -t -f XDP_TX -D 10.10.0.1 -C 10.10.0.1 -T 10.10.0.11 v00
> +
> +	## XDP_REDIRECT
> +	ip netns exec ${NS1} ./xdp_features -f XDP_REDIRECT -D 10.10.1.11 -T 10.10.0.11 v11 &
> +	ip netns exec ${NS0} ./xdp_features -t -f XDP_REDIRECT -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
> +
> +	[ $? -ne 0 ] && exit
> +
> +	## XDP_NDO_XMIT
> +	./xdp_features -f XDP_NDO_XMIT -D 10.10.0.1 -T 10.10.0.11 v01 &
> +	ip netns exec ${NS0} ./xdp_features -t -f XDP_NDO_XMIT -D 10.10.0.1 -C 10.10.0.1 -T 10.10.0.11 v00
> +
> +	ret=$?
> +	cleanup
> +}
> +
> +set -e
> +trap cleanup 2 3 6 9
> +
> +test_xdp_features

This won't be run by bpf CI.

A selftest in test_progs is needed to test the libbpf changes in patch 6.

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH bpf-next 7/7] selftests/bpf: introduce XDP compliance test tool
  2023-01-24  6:34     ` [Intel-wired-lan] " Martin KaFai Lau
@ 2023-01-24 11:12       ` Lorenzo Bianconi
  -1 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-24 11:12 UTC (permalink / raw)
  To: Martin KaFai Lau
  Cc: netdev, ast, daniel, andrii, davem, kuba, hawk, pabeni, edumazet,
	toke, memxor, alardam, saeedm, anthony.l.nguyen, gospo,
	vladimir.oltean, nbd, john, leon, simon.horman, aelior,
	christophe.jaillet, ecree.xilinx, mst, bjorn, magnus.karlsson,
	maciej.fijalkowski, intel-wired-lan, lorenzo.bianconi,
	niklas.soderlund, bpf

[-- Attachment #1: Type: text/plain, Size: 4627 bytes --]

> On 1/20/23 9:16 AM, Lorenzo Bianconi wrote:
> > +static __always_inline int xdp_process_echo_packet(struct xdp_md *xdp, bool dut)
> > +{
> > +	void *data_end = (void *)(long)xdp->data_end;
> > +	__be32 saddr = dut ? tester_ip : dut_ip;
> > +	__be32 daddr = dut ? dut_ip : tester_ip;
> > +	void *data = (void *)(long)xdp->data;
> > +	struct ethhdr *eh = data;
> > +	struct tlv_hdr *tlv;
> > +	struct udphdr *uh;
> > +	struct iphdr *ih;
> > +	__be16 port;
> > +	__u8 *cmd;
> > +
> > +	if (eh + 1 > (struct ethhdr *)data_end)
> > +		return -EINVAL;
> > +
> > +	if (eh->h_proto != bpf_htons(ETH_P_IP))
> > +		return -EINVAL;
> 
> Both v6 and v4 support are needed as a tool.

ack, I will fix it.

> 
> [ ... ]
> 
> > diff --git a/tools/testing/selftests/bpf/test_xdp_features.sh b/tools/testing/selftests/bpf/test_xdp_features.sh
> > new file mode 100755
> > index 000000000000..98b8fd2b6c16
> > --- /dev/null
> > +++ b/tools/testing/selftests/bpf/test_xdp_features.sh
> > @@ -0,0 +1,99 @@
> > +#!/bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +# Create 2 namespaces with two veth peers, and
> > +# check reported and detected XDP capabilities
> > +#
> > +#   NS0(v00)              NS1(v11)
> > +#       |                     |
> > +#       |                     |
> > +# (v01, id:111)  ------  (v10,id:222)
> > +
> > +readonly NS0="ns1-$(mktemp -u XXXXXX)"
> > +readonly NS1="ns2-$(mktemp -u XXXXXX)"
> > +ret=1
> > +
> > +setup() {
> > +	{
> > +		ip netns add ${NS0}
> > +		ip netns add ${NS1}
> > +
> > +		ip link add v01 index 111 type veth peer name v00 netns ${NS0}
> > +		ip link add v10 index 222 type veth peer name v11 netns ${NS1}
> > +
> > +		ip link set v01 up
> > +		ip addr add 10.10.0.1/24 dev v01
> > +		ip link set v01 address 00:11:22:33:44:55
> > +		ip -n ${NS0} link set dev v00 up
> > +		ip -n ${NS0} addr add 10.10.0.11/24 dev v00
> > +		ip -n ${NS0} route add default via 10.10.0.1
> > +		ip -n ${NS0} link set v00 address 00:12:22:33:44:55
> > +
> > +		ip link set v10 up
> > +		ip addr add 10.10.1.1/24 dev v10
> > +		ip link set v10 address 00:13:22:33:44:55
> > +		ip -n ${NS1} link set dev v11 up
> > +		ip -n ${NS1} addr add 10.10.1.11/24 dev v11
> > +		ip -n ${NS1} route add default via 10.10.1.1
> > +		ip -n ${NS1} link set v11 address 00:14:22:33:44:55
> > +
> > +		sysctl -w net.ipv4.ip_forward=1
> > +		# Enable XDP mode
> > +		ethtool -K v01 gro on
> > +		ethtool -K v01 tx-checksumming off
> > +		ip netns exec ${NS0} ethtool -K v00 gro on
> > +		ip netns exec ${NS0} ethtool -K v00 tx-checksumming off
> > +		ethtool -K v10 gro on
> > +		ethtool -K v10 tx-checksumming off
> > +		ip netns exec ${NS1} ethtool -K v11 gro on
> > +		ip netns exec ${NS1} ethtool -K v11 tx-checksumming off
> > +	} > /dev/null 2>&1
> > +}
> > +
> > +cleanup() {
> > +	ip link del v01 2> /dev/null
> > +	ip link del v10 2> /dev/null
> > +	ip netns del ${NS0} 2> /dev/null
> > +	ip netns del ${NS1} 2> /dev/null
> > +	[ "$(pidof xdp_features)" = "" ] || kill $(pidof xdp_features) 2> /dev/null
> > +}
> > +
> > +test_xdp_features() {
> > +	setup
> > +
> > +	## XDP_PASS
> > +	ip netns exec ${NS1} ./xdp_features -f XDP_PASS -D 10.10.1.11 -T 10.10.0.11 v11 &
> > +	ip netns exec ${NS0} ./xdp_features -t -f XDP_PASS -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
> > +
> > +	[ $? -ne 0 ] && exit
> > +
> > +	# XDP_DROP
> > +	ip netns exec ${NS1} ./xdp_features -f XDP_DROP -D 10.10.1.11 -T 10.10.0.11 v11 &
> > +	ip netns exec ${NS0} ./xdp_features -t -f XDP_DROP -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
> > +
> > +	[ $? -ne 0 ] && exit
> > +
> > +	## XDP_TX
> > +	./xdp_features -f XDP_TX -D 10.10.0.1 -T 10.10.0.11 v01 &
> > +	ip netns exec ${NS0} ./xdp_features -t -f XDP_TX -D 10.10.0.1 -C 10.10.0.1 -T 10.10.0.11 v00
> > +
> > +	## XDP_REDIRECT
> > +	ip netns exec ${NS1} ./xdp_features -f XDP_REDIRECT -D 10.10.1.11 -T 10.10.0.11 v11 &
> > +	ip netns exec ${NS0} ./xdp_features -t -f XDP_REDIRECT -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
> > +
> > +	[ $? -ne 0 ] && exit
> > +
> > +	## XDP_NDO_XMIT
> > +	./xdp_features -f XDP_NDO_XMIT -D 10.10.0.1 -T 10.10.0.11 v01 &
> > +	ip netns exec ${NS0} ./xdp_features -t -f XDP_NDO_XMIT -D 10.10.0.1 -C 10.10.0.1 -T 10.10.0.11 v00
> > +
> > +	ret=$?
> > +	cleanup
> > +}
> > +
> > +set -e
> > +trap cleanup 2 3 6 9
> > +
> > +test_xdp_features
> 
> This won't be run by bpf CI.
> 
> A selftest in test_progs is needed to test the libbpf changes in patch 6.

ack, I will add it.

Regards,
Lorenzo

> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Intel-wired-lan] [PATCH bpf-next 7/7] selftests/bpf: introduce XDP compliance test tool
@ 2023-01-24 11:12       ` Lorenzo Bianconi
  0 siblings, 0 replies; 52+ messages in thread
From: Lorenzo Bianconi @ 2023-01-24 11:12 UTC (permalink / raw)
  To: Martin KaFai Lau
  Cc: mst, vladimir.oltean, ast, edumazet, anthony.l.nguyen, daniel,
	niklas.soderlund, andrii, intel-wired-lan, simon.horman, kuba,
	pabeni, aelior, hawk, christophe.jaillet, memxor, john, bjorn,
	bpf, magnus.karlsson, leon, netdev, toke, ecree.xilinx, alardam,
	gospo, saeedm, davem, nbd


[-- Attachment #1.1: Type: text/plain, Size: 4627 bytes --]

> On 1/20/23 9:16 AM, Lorenzo Bianconi wrote:
> > +static __always_inline int xdp_process_echo_packet(struct xdp_md *xdp, bool dut)
> > +{
> > +	void *data_end = (void *)(long)xdp->data_end;
> > +	__be32 saddr = dut ? tester_ip : dut_ip;
> > +	__be32 daddr = dut ? dut_ip : tester_ip;
> > +	void *data = (void *)(long)xdp->data;
> > +	struct ethhdr *eh = data;
> > +	struct tlv_hdr *tlv;
> > +	struct udphdr *uh;
> > +	struct iphdr *ih;
> > +	__be16 port;
> > +	__u8 *cmd;
> > +
> > +	if (eh + 1 > (struct ethhdr *)data_end)
> > +		return -EINVAL;
> > +
> > +	if (eh->h_proto != bpf_htons(ETH_P_IP))
> > +		return -EINVAL;
> 
> Both v6 and v4 support are needed as a tool.

ack, I will fix it.

> 
> [ ... ]
> 
> > diff --git a/tools/testing/selftests/bpf/test_xdp_features.sh b/tools/testing/selftests/bpf/test_xdp_features.sh
> > new file mode 100755
> > index 000000000000..98b8fd2b6c16
> > --- /dev/null
> > +++ b/tools/testing/selftests/bpf/test_xdp_features.sh
> > @@ -0,0 +1,99 @@
> > +#!/bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +# Create 2 namespaces with two veth peers, and
> > +# check reported and detected XDP capabilities
> > +#
> > +#   NS0(v00)              NS1(v11)
> > +#       |                     |
> > +#       |                     |
> > +# (v01, id:111)  ------  (v10,id:222)
> > +
> > +readonly NS0="ns1-$(mktemp -u XXXXXX)"
> > +readonly NS1="ns2-$(mktemp -u XXXXXX)"
> > +ret=1
> > +
> > +setup() {
> > +	{
> > +		ip netns add ${NS0}
> > +		ip netns add ${NS1}
> > +
> > +		ip link add v01 index 111 type veth peer name v00 netns ${NS0}
> > +		ip link add v10 index 222 type veth peer name v11 netns ${NS1}
> > +
> > +		ip link set v01 up
> > +		ip addr add 10.10.0.1/24 dev v01
> > +		ip link set v01 address 00:11:22:33:44:55
> > +		ip -n ${NS0} link set dev v00 up
> > +		ip -n ${NS0} addr add 10.10.0.11/24 dev v00
> > +		ip -n ${NS0} route add default via 10.10.0.1
> > +		ip -n ${NS0} link set v00 address 00:12:22:33:44:55
> > +
> > +		ip link set v10 up
> > +		ip addr add 10.10.1.1/24 dev v10
> > +		ip link set v10 address 00:13:22:33:44:55
> > +		ip -n ${NS1} link set dev v11 up
> > +		ip -n ${NS1} addr add 10.10.1.11/24 dev v11
> > +		ip -n ${NS1} route add default via 10.10.1.1
> > +		ip -n ${NS1} link set v11 address 00:14:22:33:44:55
> > +
> > +		sysctl -w net.ipv4.ip_forward=1
> > +		# Enable XDP mode
> > +		ethtool -K v01 gro on
> > +		ethtool -K v01 tx-checksumming off
> > +		ip netns exec ${NS0} ethtool -K v00 gro on
> > +		ip netns exec ${NS0} ethtool -K v00 tx-checksumming off
> > +		ethtool -K v10 gro on
> > +		ethtool -K v10 tx-checksumming off
> > +		ip netns exec ${NS1} ethtool -K v11 gro on
> > +		ip netns exec ${NS1} ethtool -K v11 tx-checksumming off
> > +	} > /dev/null 2>&1
> > +}
> > +
> > +cleanup() {
> > +	ip link del v01 2> /dev/null
> > +	ip link del v10 2> /dev/null
> > +	ip netns del ${NS0} 2> /dev/null
> > +	ip netns del ${NS1} 2> /dev/null
> > +	[ "$(pidof xdp_features)" = "" ] || kill $(pidof xdp_features) 2> /dev/null
> > +}
> > +
> > +test_xdp_features() {
> > +	setup
> > +
> > +	## XDP_PASS
> > +	ip netns exec ${NS1} ./xdp_features -f XDP_PASS -D 10.10.1.11 -T 10.10.0.11 v11 &
> > +	ip netns exec ${NS0} ./xdp_features -t -f XDP_PASS -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
> > +
> > +	[ $? -ne 0 ] && exit
> > +
> > +	# XDP_DROP
> > +	ip netns exec ${NS1} ./xdp_features -f XDP_DROP -D 10.10.1.11 -T 10.10.0.11 v11 &
> > +	ip netns exec ${NS0} ./xdp_features -t -f XDP_DROP -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
> > +
> > +	[ $? -ne 0 ] && exit
> > +
> > +	## XDP_TX
> > +	./xdp_features -f XDP_TX -D 10.10.0.1 -T 10.10.0.11 v01 &
> > +	ip netns exec ${NS0} ./xdp_features -t -f XDP_TX -D 10.10.0.1 -C 10.10.0.1 -T 10.10.0.11 v00
> > +
> > +	## XDP_REDIRECT
> > +	ip netns exec ${NS1} ./xdp_features -f XDP_REDIRECT -D 10.10.1.11 -T 10.10.0.11 v11 &
> > +	ip netns exec ${NS0} ./xdp_features -t -f XDP_REDIRECT -D 10.10.1.11 -C 10.10.1.11 -T 10.10.0.11 v00
> > +
> > +	[ $? -ne 0 ] && exit
> > +
> > +	## XDP_NDO_XMIT
> > +	./xdp_features -f XDP_NDO_XMIT -D 10.10.0.1 -T 10.10.0.11 v01 &
> > +	ip netns exec ${NS0} ./xdp_features -t -f XDP_NDO_XMIT -D 10.10.0.1 -C 10.10.0.1 -T 10.10.0.11 v00
> > +
> > +	ret=$?
> > +	cleanup
> > +}
> > +
> > +set -e
> > +trap cleanup 2 3 6 9
> > +
> > +test_xdp_features
> 
> This won't be run by bpf CI.
> 
> A selftest in test_progs is needed to test the libbpf changes in patch 6.

ack, I will add it.

Regards,
Lorenzo

> 

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 162 bytes --]

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

^ permalink raw reply	[flat|nested] 52+ messages in thread

end of thread, other threads:[~2023-01-24 16:03 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-20 17:16 [PATCH bpf-next 0/7] xdp: introduce xdp-feature support Lorenzo Bianconi
2023-01-20 17:16 ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-20 17:16 ` [PATCH bpf-next 1/7] netdev-genl: create a simple family for netdev stuff Lorenzo Bianconi
2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-21  1:19   ` Alexei Starovoitov
2023-01-21  1:19     ` [Intel-wired-lan] " Alexei Starovoitov
2023-01-22 17:45     ` Lorenzo Bianconi
2023-01-22 17:45       ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-21  3:11   ` Jakub Kicinski
2023-01-21  3:11     ` [Intel-wired-lan] " Jakub Kicinski
2023-01-22 23:00     ` Lorenzo Bianconi
2023-01-22 23:00       ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-23 20:01       ` Jakub Kicinski
2023-01-23 20:01         ` [Intel-wired-lan] " Jakub Kicinski
2023-01-23 23:29         ` Lorenzo Bianconi
2023-01-23 23:29           ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-21  4:42   ` kernel test robot
2023-01-21  4:42     ` [Intel-wired-lan] " kernel test robot
2023-01-20 17:16 ` [PATCH bpf-next 2/7] drivers: net: turn on XDP features Lorenzo Bianconi
2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-21  3:11   ` Jakub Kicinski
2023-01-21  3:11     ` [Intel-wired-lan] " Jakub Kicinski
2023-01-22 11:49     ` Lorenzo Bianconi
2023-01-22 11:49       ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-23 20:03       ` Jakub Kicinski
2023-01-23 20:03         ` Jakub Kicinski
2023-01-20 17:16 ` [PATCH bpf-next 3/7] xsk: add usage of XDP features flags Lorenzo Bianconi
2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-20 17:16 ` [PATCH bpf-next 4/7] libbpf: add the capability to specify netlink proto in libbpf_netlink_send_recv Lorenzo Bianconi
2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-20 17:16 ` [PATCH bpf-next 5/7] libbpf: add API to get XDP/XSK supported features Lorenzo Bianconi
2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-21  3:20   ` Jakub Kicinski
2023-01-21  3:20     ` [Intel-wired-lan] " Jakub Kicinski
2023-01-22 12:09     ` Lorenzo Bianconi
2023-01-22 12:09       ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-20 17:16 ` [PATCH bpf-next 6/7] bpf: devmap: check XDP features in bpf_map_update_elem and __xdp_enqueue Lorenzo Bianconi
2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-21  2:02   ` Martin KaFai Lau
2023-01-21  2:02     ` [Intel-wired-lan] " Martin KaFai Lau
2023-01-22 12:13     ` Lorenzo Bianconi
2023-01-22 12:13       ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-23 20:09       ` Jakub Kicinski
2023-01-23 20:09         ` [Intel-wired-lan] " Jakub Kicinski
2023-01-23 23:29         ` Lorenzo Bianconi
2023-01-23 23:29           ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-20 17:16 ` [PATCH bpf-next 7/7] selftests/bpf: introduce XDP compliance test tool Lorenzo Bianconi
2023-01-20 17:16   ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-24  6:34   ` Martin KaFai Lau
2023-01-24  6:34     ` [Intel-wired-lan] " Martin KaFai Lau
2023-01-24 11:12     ` Lorenzo Bianconi
2023-01-24 11:12       ` [Intel-wired-lan] " Lorenzo Bianconi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.