xdp: introduce xdp-feature support
Subsystems (40)
Lorenzo Bianconi
maintainerv3 cover xdp: introduce xdp-feature support
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 v2:
- rebase on top of bpf-next
- fix compilation error
Changes since v1:
- add Documentation to netdev.yaml
- use flags instead of enum as type for netdev.yaml definitions
- squash XDP_PASS, XDP_DROP, XDP_TX and XDP_ABORTED into XDP_BASIC since they are supported by all drivers.
- add notifier event to xdp_features_set_redirect_target() and xdp_features_clear_redirect_target()
- add selftest for xdp-features support in bpf_xdp_detach()
- add IPv6 preliminary support to XDP compliance test tool
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 (5):
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 __xdp_enqueue routine selftests/bpf: add test for bpf_xdp_query xdp-features support 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 | 100 +++ drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 + .../net/ethernet/aquantia/atlantic/aq_nic.c | 5 + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 3 + drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 2 + .../net/ethernet/cavium/thunder/nicvf_main.c | 2 + .../net/ethernet/freescale/dpaa/dpaa_eth.c | 4 + .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 + .../net/ethernet/freescale/enetc/enetc_pf.c | 3 + .../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 | 9 +- drivers/net/ethernet/intel/igc/igc_main.c | 3 + drivers/net/ethernet/intel/igc/igc_xdp.c | 5 + drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 6 + .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 1 + drivers/net/ethernet/marvell/mvneta.c | 3 + .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 4 + .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 8 +- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 + .../net/ethernet/mellanox/mlx4/en_netdev.c | 2 + .../net/ethernet/mellanox/mlx5/core/en_main.c | 11 + drivers/net/ethernet/microsoft/mana/mana_en.c | 2 + .../ethernet/netronome/nfp/nfp_net_common.c | 5 + drivers/net/ethernet/qlogic/qede/qede_main.c | 3 + drivers/net/ethernet/sfc/efx.c | 4 + drivers/net/ethernet/sfc/siena/efx.c | 4 + drivers/net/ethernet/socionext/netsec.c | 3 + .../net/ethernet/stmicro/stmmac/stmmac_main.c | 2 + drivers/net/ethernet/ti/cpsw.c | 4 + drivers/net/ethernet/ti/cpsw_new.c | 4 + drivers/net/hyperv/netvsc_drv.c | 2 + drivers/net/netdevsim/netdev.c | 1 + drivers/net/tun.c | 5 + drivers/net/veth.c | 4 + drivers/net/virtio_net.c | 4 + drivers/net/xen-netfront.c | 2 + include/linux/netdevice.h | 3 + include/net/xdp.h | 15 + include/uapi/linux/netdev.h | 59 ++ kernel/bpf/devmap.c | 16 +- net/core/Makefile | 3 +- net/core/dev.c | 1 + net/core/filter.c | 13 +- net/core/netdev-genl-gen.c | 48 ++ net/core/netdev-genl-gen.h | 23 + net/core/netdev-genl.c | 179 +++++ net/core/xdp.c | 18 + net/xdp/xsk_buff_pool.c | 7 +- tools/include/uapi/linux/netdev.h | 59 ++ tools/lib/bpf/libbpf.h | 3 +- tools/lib/bpf/netlink.c | 121 ++- tools/lib/bpf/nlattr.h | 12 + tools/testing/selftests/bpf/.gitignore | 1 + tools/testing/selftests/bpf/Makefile | 11 +- .../bpf/prog_tests/xdp_do_redirect.c | 27 +- .../selftests/bpf/prog_tests/xdp_info.c | 8 + .../selftests/bpf/progs/xdp_features.c | 249 ++++++ .../selftests/bpf/test_xdp_features.sh | 99 +++ tools/testing/selftests/bpf/xdp_features.c | 736 ++++++++++++++++++ tools/testing/selftests/bpf/xdp_features.h | 33 + 62 files changed, 1966 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/xdp_features.c create mode 100755 tools/testing/selftests/bpf/test_xdp_features.sh create mode 100644 tools/testing/selftests/bpf/xdp_features.c create mode 100644 tools/testing/selftests/bpf/xdp_features.h
Signature · 1 line
2.39.1
Lorenzo Bianconi
maintainerPATCH v3 1/8 netdev-genl: create a simple family for netdev stuff
From: Jakub Kicinski <[email protected]>
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:
$ ./cli.py --spec netdev.yaml --dump dev_get
[{'ifindex': 1, 'xdp-features': set()},
{'ifindex': 2, 'xdp-features': {'basic', 'ndo-xmit', 'redirect'}},
{'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.
--- Documentation/netlink/specs/netdev.yaml | 100 +++++++++++++ include/linux/netdevice.h | 3 + include/net/xdp.h | 3 + include/uapi/linux/netdev.h | 59 ++++++++ net/core/Makefile | 3 +- net/core/dev.c | 1 + net/core/netdev-genl-gen.c | 48 +++++++ net/core/netdev-genl-gen.h | 23 +++ net/core/netdev-genl.c | 179 ++++++++++++++++++++++++ tools/include/uapi/linux/netdev.h | 59 ++++++++ 10 files changed, 477 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
Documentation/netlink/specs/netdev.yaml new file +100 -0
@@ -0,0 +1,100 @@ +name: netdev + +doc: + netdev configuration over generic netlink. + +definitions: + - + type: flags + name: xdp-act + entries: + - + name: basic + doc: + XDP feautues set supported by all drivers + (XDP_ABORTED, XDP_DROP, XDP_PASS, XDP_TX) + - + name: redirect + doc: + The netdev supports XDP_REDIRECT + - + name: ndo-xmit + doc: + This feature informs if netdev implements ndo_xdp_xmit callback. + - + name: xsk-zerocopy + doc: + This feature informs if netdev supports AF_XDP in zero copy mode. + - + name: hw-offload + doc: + This feature informs if netdev supports XDP hw oflloading. + - + name: rx-sg + doc: + This feature informs if netdev implements non-linear XDP buffer + support in the driver napi callback. + - + name: ndo-xmit-sg + doc: + This feature informs if netdev implements non-linear XDP buffer + support in ndo_xdp_xmit callback. + +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-act + 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
include/linux/netdevice.h +3 -0
@@ -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>
@@ -2055,6 +2056,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;const struct xdp_metadata_ops *xdp_metadata_ops;
@@ -2839,6 +2841,7 @@ enum netdev_cmd {NETDEV_OFFLOAD_XSTATS_DISABLE ,NETDEV_OFFLOAD_XSTATS_REPORT_USED ,NETDEV_OFFLOAD_XSTATS_REPORT_DELTA , + NETDEV_XDP_FEAT_CHANGE, };const char *netdev_cmd_to_name (enum netdev_cmd cmd);
include/net/xdp.h +3 -0
@@ -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
include/uapi/linux/netdev.h new file +59 -0
59 lines not on this page · raw message
net/core/Makefile +2 -1
@@ -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
net/core/dev.c +1 -0
@@ -1614,6 +1614,7 @@ const char *netdev_cmd_to_name(enum netdev_cmd cmd) N(SVLAN_FILTER_PUSH_INFO) N(SVLAN_FILTER_DROP_INFO) N(PRE_CHANGEADDR) N(OFFLOAD_XSTATS_ENABLE) N(OFFLOAD_XSTATS_DISABLE) N(OFFLOAD_XSTATS_REPORT_USED) N(OFFLOAD_XSTATS_REPORT_DELTA) + N(XDP_FEAT_CHANGE) }#undef Nreturn "UNKNOWN_NETDEV_EVENT" ;
net/core/netdev-genl-gen.c new file +48 -0
48 lines not on this page · raw message
net/core/netdev-genl-gen.h new file +23 -0
@@ -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 */
net/core/netdev-genl.c new file +179 -0
179 lines not on this page · raw message
tools/include/uapi/linux/netdev.h new file +59 -0
59 lines not on this page · raw message
Signature · 1 line
2.39.1
Lorenzo Bianconi
maintainerPATCH v3 2/8 drivers: net: turn on XDP features
In reply to Lorenzo BianconiFrom: Marek Majtyka <[email protected]>
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
- netronome (nfp)
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 '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
--- drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 ++++ .../net/ethernet/aquantia/atlantic/aq_nic.c | 5 +++++ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 3 +++ drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 2 ++ .../net/ethernet/cavium/thunder/nicvf_main.c | 2 ++ drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 4 ++++ .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 ++++ .../net/ethernet/freescale/enetc/enetc_pf.c | 3 +++ .../net/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 | 9 ++++++++- drivers/net/ethernet/intel/igc/igc_main.c | 3 +++ drivers/net/ethernet/intel/igc/igc_xdp.c | 5 +++++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 6 ++++++ .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 1 + drivers/net/ethernet/marvell/mvneta.c | 3 +++ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 4 ++++ .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 8 ++++++-- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 ++++++ drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 ++ .../net/ethernet/mellanox/mlx5/core/en_main.c | 11 +++++++++++ drivers/net/ethernet/microsoft/mana/mana_en.c | 2 ++ .../ethernet/netronome/nfp/nfp_net_common.c | 5 +++++ drivers/net/ethernet/qlogic/qede/qede_main.c | 3 +++ drivers/net/ethernet/sfc/efx.c | 4 ++++ drivers/net/ethernet/sfc/siena/efx.c | 4 ++++ drivers/net/ethernet/socionext/netsec.c | 3 +++ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 2 ++ drivers/net/ethernet/ti/cpsw.c | 4 ++++ drivers/net/ethernet/ti/cpsw_new.c | 4 ++++ drivers/net/hyperv/netvsc_drv.c | 2 ++ drivers/net/netdevsim/netdev.c | 1 + drivers/net/tun.c | 5 +++++ drivers/net/veth.c | 4 ++++ drivers/net/virtio_net.c | 4 ++++ drivers/net/xen-netfront.c | 2 ++ include/net/xdp.h | 12 ++++++++++++ net/core/xdp.c | 18 ++++++++++++++++++ 39 files changed, 180 insertions(+), 5 deletions(-)
drivers/net/ethernet/amazon/ena/ena_netdev.c +4 -0
@@ -597,7 +597,9 @@ static int ena_xdp_set(struct net_device *netdev, struct netdev_bpf *bpf)if (rc)return rc; } +xdp_features_set_redirect_target (netdev, false); }else if (old_bpf_prog) { +xdp_features_clear_redirect_target (netdev); rc =ena_destroy_and_free_all_xdp_queues (adapter);if (rc)return rc;
@@ -4103,6 +4105,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_BASIC |NETDEV_XDP_ACT_REDIRECT ; + adapter->max_mtu = feat->dev_attr.max_mtu; netdev->max_mtu = adapter->max_mtu; netdev->min_mtu =ENA_MIN_MTU ;
drivers/net/ethernet/aquantia/atlantic/aq_nic.c +5 -0
@@ -384,6 +384,11 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +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,
drivers/net/ethernet/broadcom/bnxt/bnxt.c +3 -0
@@ -13686,6 +13686,9 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_RX_SG ; +#ifdef CONFIG_BNXT_SRIOV init_waitqueue_head (&bp->sriov_cfg_wait);#endif
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c +2 -0
@@ -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, true); }else {int rx, tx; +xdp_features_clear_redirect_target (dev);bnxt_set_rx_skb_mode (bp, false);bnxt_get_max_rings (bp, &rx, &tx, true);if (rx >1 ) {
drivers/net/ethernet/cavium/thunder/nicvf_main.c +2 -0
@@ -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 ;
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +4 -0
@@ -244,6 +244,10 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +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);
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +4 -0
@@ -4593,6 +4593,10 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_XSK_ZEROCOPY | +NETDEV_XDP_ACT_NDO_XMIT ;if (priv->dpni_attrs.vlan_filter_entries) net_dev->hw_features |=NETIF_F_HW_VLAN_CTAG_FILTER ;
drivers/net/ethernet/freescale/enetc/enetc_pf.c +3 -0
@@ -825,6 +825,9 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +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 ;
drivers/net/ethernet/fungible/funeth/funeth_main.c +6 -0
@@ -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, true); +else +xdp_features_clear_redirect_target (dev); + 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_BASIC |NETDEV_XDP_ACT_REDIRECT ; netdev->min_mtu =ETH_MIN_MTU ; netdev->max_mtu =FUN_MAX_MTU ;
drivers/net/ethernet/intel/i40e/i40e_main.c +8 -2
@@ -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);/* Wait until ndo_xsk_wakeup completes. */ synchronize_rcu (); + }i40e_reset_and_rebuild (pf, true, true); }
@@ -13362,11 +13364,13 @@ 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, true); + }return 0 ; }
@@ -13783,6 +13787,8 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_XSK_ZEROCOPY ;if (vsi->type ==I40E_VSI_MAIN ) {SET_NETDEV_DEV (netdev, &pf->pdev->dev);
drivers/net/ethernet/intel/ice/ice_main.c +5 -0
@@ -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,13 @@ 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, 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_ring_err =ice_destroy_xdp_rings (vsi);if (xdp_ring_err)NL_SET_ERR_MSG_MOD (extack,"Freeing XDP Tx resources failed" );
@@ -3446,6 +3449,8 @@ static int ice_cfg_netdev(struct ice_vsi *vsi) np->vsi = vsi;ice_set_netdev_features (netdev); + netdev->xdp_features =NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_XSK_ZEROCOPY ;ice_set_ops (netdev);
drivers/net/ethernet/intel/igb/igb_main.c +8 -1
@@ -2871,8 +2871,14 @@ 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, true); +else +xdp_features_clear_redirect_target (dev); + }if (running)igb_open (dev);
@@ -3317,6 +3323,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_BASIC |NETDEV_XDP_ACT_REDIRECT ;/* MTU range: 68 - 9216 */ netdev->min_mtu =ETH_MIN_MTU ;
drivers/net/ethernet/intel/igc/igc_main.c +3 -0
@@ -6533,6 +6533,9 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_XSK_ZEROCOPY ; +/* MTU range: 68 - 9216 */ netdev->min_mtu =ETH_MIN_MTU ; netdev->max_mtu =MAX_STD_JUMBO_FRAME_SIZE ;
drivers/net/ethernet/intel/igc/igc_xdp.c +5 -0
@@ -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, true); +else +xdp_features_clear_redirect_target (dev); +if (if_running)igc_open (dev);
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +6 -0
@@ -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); }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, true); }return 0 ;
@@ -11017,6 +11020,9 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_XSK_ZEROCOPY ; +/* MTU range: 68 - 9710 */ netdev->min_mtu =ETH_MIN_MTU ; netdev->max_mtu =IXGBE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN +ETH_FCS_LEN );
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +1 -0
@@ -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 ;
drivers/net/ethernet/marvell/mvneta.c +3 -0
@@ -5612,6 +5612,9 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +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 );
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +4 -0
@@ -6866,6 +6866,10 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; + dev->priv_flags |=IFF_UNICAST_FLT ;/* MTU range: 68 - 9704 */
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +6 -2
@@ -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, false); + }else { pf->hw.xdp_queues =0 ; +xdp_features_clear_redirect_target (dev); + } 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_BASIC |NETDEV_XDP_ACT_REDIRECT ; netdev->min_mtu =OTX2_MIN_MTU ; netdev->max_mtu =otx2_get_max_mtu (pf);
drivers/net/ethernet/mediatek/mtk_eth_soc.c +6 -0
@@ -4186,6 +4186,12 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT | +NETDEV_XDP_ACT_NDO_XMIT_SG ; +return 0 ; free_netdev:
drivers/net/ethernet/mellanox/mlx4/en_netdev.c +2 -0
@@ -3416,6 +3416,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_BASIC |NETDEV_XDP_ACT_REDIRECT ; +/* MTU range: 68 - hw-specific max */ dev->min_mtu =ETH_MIN_MTU ; dev->max_mtu = priv->max_mtu;
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +11 -0
@@ -4776,6 +4776,13 @@ 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, true); +else +xdp_features_clear_redirect_target (netdev); + } +if (!test_bit (MLX5E_STATE_OPENED , &priv->state) || reset) goto unlock;
@@ -5171,6 +5178,10 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_XSK_ZEROCOPY | +NETDEV_XDP_ACT_RX_SG ; + netdev->priv_flags |=IFF_UNICAST_FLT ;netif_set_tso_max_size (netdev,GSO_MAX_SIZE );
drivers/net/ethernet/microsoft/mana/mana_en.c +2 -0
@@ -2160,6 +2160,8 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; err =register_netdev (ndev);if (err) {
drivers/net/ethernet/netronome/nfp/nfp_net_common.c +5 -0
@@ -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;
drivers/net/ethernet/qlogic/qede/qede_main.c +3 -0
@@ -892,6 +892,9 @@ static void qede_init_ndev(struct qede_dev *edev) ndev->hw_features = hw_features; + ndev->xdp_features =NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; +/* MTU range: 46 - 9600 */ ndev->min_mtu =ETH_ZLEN -ETH_HLEN ; ndev->max_mtu =QEDE_MAX_JUMBO_PACKET_SIZE ;
drivers/net/ethernet/sfc/efx.c +4 -0
@@ -1078,6 +1078,10 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; +if (!efx->type->is_vf)efx_probe_vpd_strings (efx);
drivers/net/ethernet/sfc/siena/efx.c +4 -0
@@ -1048,6 +1048,10 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; +if (!efx->type->is_vf)efx_probe_vpd_strings (efx);
drivers/net/ethernet/socionext/netsec.c +3 -0
@@ -2104,6 +2104,9 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; + priv->rx_cksum_offload_flag = true; ret =netsec_register_mdio (priv, phy_addr);
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +2 -0
@@ -7145,6 +7145,8 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; ret =stmmac_tc_init (priv, priv);if (!ret) {
drivers/net/ethernet/ti/cpsw.c +4 -0
@@ -1458,6 +1458,8 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; ndev->netdev_ops = &cpsw_netdev_ops; ndev->ethtool_ops = &cpsw_ethtool_ops;
@@ -1635,6 +1637,8 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; ndev->netdev_ops = &cpsw_netdev_ops; ndev->ethtool_ops = &cpsw_ethtool_ops;
drivers/net/ethernet/ti/cpsw_new.c +4 -0
@@ -1405,6 +1405,10 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; + ndev->netdev_ops = &cpsw_netdev_ops; ndev->ethtool_ops = &cpsw_ethtool_ops;SET_NETDEV_DEV (ndev, dev);
drivers/net/hyperv/netvsc_drv.c +2 -0
@@ -2559,6 +2559,8 @@ static int netvsc_probe(struct hv_device *dev,netdev_lockdep_set_classes (net); + net->xdp_features =NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT ; +/* MTU range: 68 - 1500 or 65521 */ net->min_mtu =NETVSC_MTU_MIN ;if (nvdev->nvsp_version >=NVSP_PROTOCOL_VERSION_2 )
drivers/net/netdevsim/netdev.c +1 -0
@@ -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)
drivers/net/tun.c +5 -0
@@ -1401,6 +1401,11 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; +break ; }
drivers/net/veth.c +4 -0
@@ -1686,6 +1686,10 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT |NETDEV_XDP_ACT_RX_SG | +NETDEV_XDP_ACT_NDO_XMIT_SG ; }/*
drivers/net/virtio_net.c +4 -0
@@ -3155,7 +3155,10 @@ 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, false); }else { +xdp_features_clear_redirect_target (dev); vi->xdp_enabled = false; }
@@ -3785,6 +3788,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_BASIC |NETDEV_XDP_ACT_REDIRECT ;/* MTU range: 68 - 65535 */ dev->min_mtu =MIN_MTU ;
drivers/net/xen-netfront.c +2 -0
@@ -1741,6 +1741,8 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; netdev->ethtool_ops = &xennet_ethtool_ops; netdev->min_mtu =ETH_MIN_MTU ;
include/net/xdp.h +12 -0
@@ -428,9 +428,21 @@ MAX_XDP_METADATA_KFUNC,#ifdef CONFIG_NET u32 bpf_xdp_metadata_kfunc_id (int id);bool bpf_dev_bound_kfunc_id (u32 btf_id); +void xdp_features_set_redirect_target (struct net_device *dev,bool support_sg); +void xdp_features_clear_redirect_target (struct net_device *dev);#else static inline u32 bpf_xdp_metadata_kfunc_id (int id) {return 0 ; }static inline bool bpf_dev_bound_kfunc_id (u32 btf_id) {return false; } + +static inline void +xdp_features_set_redirect_target (struct net_device *dev,bool support_sg) +{ +} + +static inline void +xdp_features_clear_redirect_target (struct net_device *dev) +{ +}#endif #endif /* __LINUX_NET_XDP_H__ */
net/core/xdp.c +18 -0
@@ -773,3 +773,21 @@ static int __init xdp_metadata_init(void)return register_btf_kfunc_id_set (BPF_PROG_TYPE_XDP , &xdp_metadata_kfunc_set); }late_initcall (xdp_metadata_init); + +void xdp_features_set_redirect_target (struct net_device *dev,bool support_sg) +{ + dev->xdp_features |=NETDEV_XDP_ACT_NDO_XMIT ; +if (support_sg) + dev->xdp_features |=NETDEV_XDP_ACT_NDO_XMIT_SG ; + +call_netdevice_notifiers (NETDEV_XDP_FEAT_CHANGE , dev); +} +EXPORT_SYMBOL_GPL (xdp_features_set_redirect_target); + +void xdp_features_clear_redirect_target (struct net_device *dev) +{ + dev->xdp_features &= ~(NETDEV_XDP_ACT_NDO_XMIT | +NETDEV_XDP_ACT_NDO_XMIT_SG ); +call_netdevice_notifiers (NETDEV_XDP_FEAT_CHANGE , dev); +} +EXPORT_SYMBOL_GPL (xdp_features_clear_redirect_target);
Signature · 1 line
2.39.1
Re: [PATCH v3 bpf-next 2/8] drivers: net: turn on XDP features
Quoted 64 lines · Lorenzo Bianconi
From: Marek Majtyka <[email protected]>
A summary of the flags being set for various drivers is given below. Note that
XDP_F_REDIRECT_TARGETandXDP_F_FRAG_TARGETare 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_ONCEmust 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
- netronome (nfp)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 '
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
Quoted 7 lines
Reviewed-by Simon Horman <[email protected]>Acked-by Jakub Kicinski <[email protected]>Co-developed-by Kumar Kartikeya Dwivedi <[email protected]>Signed-off-by Kumar Kartikeya Dwivedi <[email protected]>Co-developed-by Lorenzo Bianconi <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>Signed-off-by Marek Majtyka <[email protected]>
Thank you!
Quoted 812 lines
--- drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 ++++ .../net/ethernet/aquantia/atlantic/aq_nic.c | 5 +++++ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 3 +++ drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 2 ++ .../net/ethernet/cavium/thunder/nicvf_main.c | 2 ++ drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 4 ++++ .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 ++++ .../net/ethernet/freescale/enetc/enetc_pf.c | 3 +++ .../net/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 | 9 ++++++++- drivers/net/ethernet/intel/igc/igc_main.c | 3 +++ drivers/net/ethernet/intel/igc/igc_xdp.c | 5 +++++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 6 ++++++ .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 1 + drivers/net/ethernet/marvell/mvneta.c | 3 +++ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 4 ++++ .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 8 ++++++-- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 ++++++ drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 ++ .../net/ethernet/mellanox/mlx5/core/en_main.c | 11 +++++++++++ drivers/net/ethernet/microsoft/mana/mana_en.c | 2 ++ .../ethernet/netronome/nfp/nfp_net_common.c | 5 +++++ drivers/net/ethernet/qlogic/qede/qede_main.c | 3 +++ drivers/net/ethernet/sfc/efx.c | 4 ++++ drivers/net/ethernet/sfc/siena/efx.c | 4 ++++ drivers/net/ethernet/socionext/netsec.c | 3 +++ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 2 ++ drivers/net/ethernet/ti/cpsw.c | 4 ++++ drivers/net/ethernet/ti/cpsw_new.c | 4 ++++ drivers/net/hyperv/netvsc_drv.c | 2 ++ drivers/net/netdevsim/netdev.c | 1 + drivers/net/tun.c | 5 +++++ drivers/net/veth.c | 4 ++++ drivers/net/virtio_net.c | 4 ++++ drivers/net/xen-netfront.c | 2 ++ include/net/xdp.h | 12 ++++++++++++ net/core/xdp.c | 18 ++++++++++++++++++ 39 files changed, 180 insertions(+), 5 deletions(-)drivers/net/ethernet/amazon/ena/ena_netdev.c +2
-0@@ -597,7 +597,9 @@ static int ena_xdp_set(struct net_device *netdev, struct netdev_bpf *bpf)if (rc)return rc; } +xdp_features_set_redirect_target (netdev, false); }else if (old_bpf_prog) { +xdp_features_clear_redirect_target (netdev); rc =ena_destroy_and_free_all_xdp_queues (adapter);if (rc)return rc;
drivers/net/ethernet/amazon/ena/ena_netdev.c +2
-0@@ -4103,6 +4105,8 @@ static void ena_set_conf_feat_params(structena_adapter *adapter,/* Set offload features */ ena_set_dev_offloads (feat ,netdev ); + netdev->xdp_features =NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT ; + adapter->max_mtu = feat->dev_attr.max_mtu; netdev->max_mtu = adapter->max_mtu;netdev->min_mtu = ENA_MIN_MTU;drivers/net/ethernet/aquantia/atlantic/aq_nic.c +5
-0@@ -384,6 +384,11 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +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,drivers/net/ethernet/broadcom/bnxt/bnxt.c +3
-0@@ -13686,6 +13686,9 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_RX_SG ; +#ifdef CONFIG_BNXT_SRIOV init_waitqueue_head (&bp->sriov_cfg_wait);#endifdrivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c +2
-0@@ -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, true); }else {int rx, tx; +xdp_features_clear_redirect_target (dev);bnxt_set_rx_skb_mode (bp, false);bnxt_get_max_rings (bp, &rx, &tx, true);if (rx > 1) {drivers/net/ethernet/cavium/thunder/nicvf_main.c +2
-0@@ -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;drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +4
-0@@ -244,6 +244,10 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +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);drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +4
-0@@ -4593,6 +4593,10 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_XSK_ZEROCOPY | +NETDEV_XDP_ACT_NDO_XMIT ;if (priv->dpni_attrs.vlan_filter_entries)net_dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;drivers/net/ethernet/freescale/enetc/enetc_pf.c +3
-0@@ -825,6 +825,9 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +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;drivers/net/ethernet/fungible/funeth/funeth_main.c +5
-0@@ -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, true); +else +xdp_features_clear_redirect_target (dev); + dev->max_mtu = prog ?XDP_MAX_MTU :FUN_MAX_MTU ; old_prog =xchg (&fp->xdp_prog, prog);if (
old_prog)drivers/net/ethernet/fungible/funeth/funeth_main.c +1
-0@@ -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_BASIC |NETDEV_XDP_ACT_REDIRECT ; netdev->min_mtu =ETH_MIN_MTU ;netdev->max_mtu = FUN_MAX_MTU;drivers/net/ethernet/intel/i40e/i40e_main.c +6
-2@@ -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);/* Wait until ndo_xsk_wakeup completes. */ synchronize_rcu (); + }i40e_reset_and_rebuild (pf, true, true); }@@ -13362,11 +13364,13 @@ 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, true); + }return 0 ;}drivers/net/ethernet/intel/i40e/i40e_main.c +2
-0@@ -13783,6 +13787,8 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_XSK_ZEROCOPY ;if (vsi->type ==I40E_VSI_MAIN ) {SET_NETDEV_DEV(netdev, &pf->pdev->dev);drivers/net/ethernet/intel/ice/ice_main.c +1
-0@@ -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 LinuxDriver"
static const char ice_driver_string[] =DRV_SUMMARY;drivers/net/ethernet/intel/ice/ice_main.c +2
-0@@ -2899,11 +2900,13 @@ 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, 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_ring_err =ice_destroy_xdp_rings (vsi);if (xdp_ring_err)
NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Tx resources failed");drivers/net/ethernet/intel/ice/ice_main.c +2
-0@@ -3446,6 +3449,8 @@ static int ice_cfg_netdev(struct ice_vsi *vsi) np->vsi = vsi;ice_set_netdev_features (netdev); + netdev->xdp_features =NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_XSK_ZEROCOPY ;ice_set_ops (netdev);drivers/net/ethernet/intel/igb/igb_main.c +7
-1@@ -2871,8 +2871,14 @@ 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, true); +else +xdp_features_clear_redirect_target (dev); + }if (running)igb_open(dev);drivers/net/ethernet/intel/igb/igb_main.c +1
-0@@ -3317,6 +3323,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_BASIC |NETDEV_XDP_ACT_REDIRECT ;/* MTU range: 68 - 9216 */ netdev->min_mtu = ETH_MIN_MTU;drivers/net/ethernet/intel/igc/igc_main.c +3
-0@@ -6533,6 +6533,9 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_XSK_ZEROCOPY ; +/* MTU range: 68 - 9216 */ netdev->min_mtu =ETH_MIN_MTU ; netdev->max_mtu =MAX_STD_JUMBO_FRAME_SIZE ;drivers/net/ethernet/intel/igc/igc_xdp.c +5
-0@@ -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, true); +else +xdp_features_clear_redirect_target (dev); +if (if_running)igc_open (dev);drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +2
-0@@ -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); }else {for (i =0 ; i < adapter->num_rx_queues; i++)(void)xchg(&adapter->rx_ring[i]->xdp_prog,
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +1
-0@@ -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, true); }return 0;
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +3
-0@@ -11017,6 +11020,9 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_XSK_ZEROCOPY ; +/* MTU range: 68 - 9710 */ netdev->min_mtu =ETH_MIN_MTU ;netdev->max_mtu = IXGBE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN);drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +1
-0@@ -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;drivers/net/ethernet/marvell/mvneta.c +3
-0@@ -5612,6 +5612,9 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +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 );drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +4
-0@@ -6866,6 +6866,10 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; + dev->priv_flags |=IFF_UNICAST_FLT ;/* MTU range: 68 - 9704 */
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +6
-2@@ -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, false); + }else { pf->hw.xdp_queues =0 ; +xdp_features_clear_redirect_target (dev); + } 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_BASIC |NETDEV_XDP_ACT_REDIRECT ; netdev->min_mtu =OTX2_MIN_MTU ;netdev->max_mtu = otx2_get_max_mtu(pf);drivers/net/ethernet/mediatek/mtk_eth_soc.c +6
-0@@ -4186,6 +4186,12 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT | +NETDEV_XDP_ACT_NDO_XMIT_SG ; +return 0 ;
free_netdev:drivers/net/ethernet/mellanox/mlx4/en_netdev.c +2
-0@@ -3416,6 +3416,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_BASIC |NETDEV_XDP_ACT_REDIRECT ; +/* MTU range: 68 - hw-specific max */ dev->min_mtu =ETH_MIN_MTU ;dev->max_mtu = priv->max_mtu;drivers/net/ethernet/mellanox/mlx5/core/en_main.c +11
-0@@ -4776,6 +4776,13 @@ 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, true); +else +xdp_features_clear_redirect_target (netdev); + } +if (!test_bit (MLX5E_STATE_OPENED , &priv->state) || reset) goto unlock;@@ -5171,6 +5178,10 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_XSK_ZEROCOPY | +NETDEV_XDP_ACT_RX_SG ; + netdev->priv_flags |=IFF_UNICAST_FLT ;netif_set_tso_max_size(netdev, GSO_MAX_SIZE);drivers/net/ethernet/microsoft/mana/mana_en.c +2
-0@@ -2160,6 +2160,8 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; err =register_netdev (ndev);if (err) {drivers/net/ethernet/netronome/nfp/nfp_net_common.c +5
-0@@ -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;drivers/net/ethernet/qlogic/qede/qede_main.c +3
-0@@ -892,6 +892,9 @@ static void qede_init_ndev(struct qede_dev *edev) ndev->hw_features = hw_features; + ndev->xdp_features =NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; +/* MTU range: 46 - 9600 */ ndev->min_mtu =ETH_ZLEN -ETH_HLEN ; ndev->max_mtu =QEDE_MAX_JUMBO_PACKET_SIZE ;drivers/net/ethernet/sfc/efx.c +4
-0@@ -1078,6 +1078,10 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; +if (!efx->type->is_vf)efx_probe_vpd_strings (efx);drivers/net/ethernet/sfc/siena/efx.c +4
-0@@ -1048,6 +1048,10 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; +if (!efx->type->is_vf)efx_probe_vpd_strings (efx);drivers/net/ethernet/socionext/netsec.c +3
-0@@ -2104,6 +2104,9 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; + priv->rx_cksum_offload_flag = true;ret = netsec_register_mdio(priv, phy_addr);drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +2
-0@@ -7145,6 +7145,8 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; ret =stmmac_tc_init (priv, priv);if (!ret) {drivers/net/ethernet/ti/cpsw.c +2
-0@@ -1458,6 +1458,8 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; ndev->netdev_ops = &cpsw_netdev_ops;ndev->ethtool_ops = &cpsw_ethtool_ops;drivers/net/ethernet/ti/cpsw.c +2
-0@@ -1635,6 +1637,8 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; ndev->netdev_ops = &cpsw_netdev_ops; ndev->ethtool_ops = &cpsw_ethtool_ops;drivers/net/ethernet/ti/cpsw_new.c +4
-0@@ -1405,6 +1405,10 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; + ndev->netdev_ops = &cpsw_netdev_ops; ndev->ethtool_ops = &cpsw_ethtool_ops;SET_NETDEV_DEV(ndev, dev);drivers/net/hyperv/netvsc_drv.c +2
-0@@ -2559,6 +2559,8 @@ static int netvsc_probe(struct hv_device *dev,netdev_lockdep_set_classes (net); + net->xdp_features =NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT ; +/* MTU range: 68 - 1500 or 65521 */ net->min_mtu =NETVSC_MTU_MIN ;if (nvdev->nvsp_version >=NVSP_PROTOCOL_VERSION_2 )drivers/net/netdevsim/netdev.c +1
-0@@ -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)drivers/net/tun.c +5
-0@@ -1401,6 +1401,11 @@ 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_BASIC | +NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; +break ; }drivers/net/veth.c +4
-0@@ -1686,6 +1686,10 @@ 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_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT |NETDEV_XDP_ACT_RX_SG | +NETDEV_XDP_ACT_NDO_XMIT_SG ; }/* drivers/net/virtio_net.c +4
-0@@ -3155,7 +3155,10 @@ 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, false); }else { +xdp_features_clear_redirect_target (dev); vi->xdp_enabled = false; }@@ -3785,6 +3788,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_BASIC |NETDEV_XDP_ACT_REDIRECT ;/* MTU range: 68 - 65535 */ dev->min_mtu =MIN_MTU ;drivers/net/xen-netfront.c +2
-0@@ -1741,6 +1741,8 @@ static struct net_device *xennet_create_dev(structxenbus_device *dev) * negotiate with the backend regarding supported features. */ netdev->features |= netdev->hw_features; + netdev->xdp_features =NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT ; netdev->ethtool_ops = &xennet_ethtool_ops;netdev->min_mtu = ETH_MIN_MTU;include/net/xdp.h +12
-0@@ -428,9 +428,21 @@ MAX_XDP_METADATA_KFUNC,#ifdef CONFIG_NET u32 bpf_xdp_metadata_kfunc_id (int id);bool bpf_dev_bound_kfunc_id (u32 btf_id); +void xdp_features_set_redirect_target (struct net_device *dev,bool support_sg); +void xdp_features_clear_redirect_target (struct net_device *dev);#else static inline u32 bpf_xdp_metadata_kfunc_id (int id) {return 0 ; }static inline bool bpf_dev_bound_kfunc_id (u32 btf_id) {return false; } + +static inline void +xdp_features_set_redirect_target (struct net_device *dev,bool support_sg) +{ +} + +static inline void +xdp_features_clear_redirect_target (struct net_device *dev) +{ +}#endif #endif /* __LINUX_NET_XDP_H__ */net/core/xdp.c +2
-0@@ -773,3 +773,21 @@ static int __init xdp_metadata_init(void)return register_btf_kfunc_id_set (BPF_PROG_TYPE_XDP , &xdp_metadata_kfunc_set); }late_initcall (xdp_metadata_init); + +void xdp_features_set_redirect_target(struct net_device *dev, bool
support_sg)net/core/xdp.c +16
-1+{ + dev->xdp_features |=NETDEV_XDP_ACT_NDO_XMIT ; +if (support_sg) + dev->xdp_features |=NETDEV_XDP_ACT_NDO_XMIT_SG ; + +call_netdevice_notifiers (NETDEV_XDP_FEAT_CHANGE , dev); +} +EXPORT_SYMBOL_GPL (xdp_features_set_redirect_target); + +void xdp_features_clear_redirect_target (struct net_device *dev) +{ + dev->xdp_features &= ~(NETDEV_XDP_ACT_NDO_XMIT | +NETDEV_XDP_ACT_NDO_XMIT_SG ); +call_netdevice_notifiers (NETDEV_XDP_FEAT_CHANGE , dev); +} +EXPORT_SYMBOL_GPL (xdp_features_clear_redirect_target); --
Quoted 1 line
2.39.1
_______________________________________________
Intel-wired-lan mailing list
[email protected]
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
Lorenzo Bianconi
maintainerPATCH v3 3/8 xsk: add usage of XDP features flags
In reply to Lorenzo BianconiFrom: Marek Majtyka <[email protected]>
Change necessary condition check for XSK from ndo functions to xdp features flags.
--- net/xdp/xsk_buff_pool.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/xdp/xsk_buff_pool.c +5 -2
@@ -140,6 +140,10 @@ static void xp_disable_drv_zc(struct xsk_buff_pool *pool) } } +#define NETDEV_XDP_ACT_ZC (NETDEV_XDP_ACT_BASIC | \ + NETDEV_XDP_ACT_REDIRECT | \ + NETDEV_XDP_ACT_XSK_ZEROCOPY) +int xp_assign_dev (struct xsk_buff_pool *pool,struct net_device *netdev,u16 queue_id,u16 flags) {
@@ -178,8 +182,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; }
Signature · 1 line
2.39.1
Lorenzo Bianconi
maintainerPATCH v3 4/8 libbpf: add the capability to specify netlink proto in libbpf_netlink_send_recv
In reply to Lorenzo BianconiThis is a preliminary patch in order to introduce netlink_generic protocol support to libbpf.
--- tools/lib/bpf/netlink.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
tools/lib/bpf/netlink.c +12 -10
@@ -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)
Signature · 6 lines
2.39.1 _______________________________________________ Intel-wired-lan mailing list [email protected] https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
Lorenzo Bianconi
maintainerPATCH v3 5/8 libbpf: add API to get XDP/XSK supported features
In reply to Lorenzo BianconiExtend 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.
--- 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(-)
tools/lib/bpf/libbpf.h +2 -1
@@ -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);
tools/lib/bpf/netlink.c +99 -0
129 lines not on this page · raw message
tools/lib/bpf/nlattr.h +12 -0
@@ -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);
Signature · 6 lines
2.39.1 _______________________________________________ Intel-wired-lan mailing list [email protected] https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
Re: [PATCH v3 bpf-next 5/8] libbpf: add API to get XDP/XSK supported features
Quoted 22 lines · Lorenzo Bianconi
Extend
bpf_xdp_queryroutine in order to get XDP/XSK supported features of netdev over route netlink interface.
Extend libbpf netlink implementation in order to supportnetlink_genericprotocol.Co-developed-by Kumar Kartikeya Dwivedi <[email protected]>Signed-off-by Kumar Kartikeya Dwivedi <[email protected]>Co-developed-by Marek Majtyka <[email protected]>Signed-off-by Marek Majtyka <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>--- 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(-)tools/lib/bpf/libbpf.h +0
-0
tools/lib/bpf/libbpf.h struct bpf_xdp_query_opts { · line 988
Quoted 8 lines
tools/lib/bpf/libbpf.h +2
-1@@ -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
is "fflags" an obvious name in this context? I'd expect "feature_flags", especially that there are already "flags". Is saving a few characters worth the confusion?
Quoted 28 lines
tools/lib/bpf/libbpf.h +0
-0LIBBPF_API int bpf_xdp_attach(int ifindex, int prog_fd, __u32 flags,const struct bpf_xdp_attach_opts *opts);tools/lib/bpf/netlink.c +7
-0@@ -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)
[...]
tools/lib/bpf/netlink.c int bpf_xdp_query(int ifindex, int xdp_flags, struct bpf_xdp_query_opts *opts) · line 463
Quoted 8 lines
int
bpf_xdp_query(int ifindex, int xdp_flags, struct bpf_xdp_query_opts *opts){ struct libbpf_nla_req req = {tools/lib/bpf/netlink.c +1
-0@@ -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)) {
maybe invert condition, return early, reduce nesting of the following code?
tools/lib/bpf/netlink.c int bpf_xdp_query(int ifindex, int xdp_flags, struct bpf_xdp_query_opts *opts) · line 471
Quoted 8 lines
tools/lib/bpf/netlink.c +8
-0+struct xdp_features_md md = { + .ifindex = ifindex, + }; +__u16 id; + + err =libbpf_netlink_resolve_genl_family_id ("netdev" , +sizeof ("netdev" ), + &id);
nit: if it fits under 100 characters, let's leave it on a single line
Quoted 26 lines
tools/lib/bpf/netlink.c +23
-0+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 =2 ; + + 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 ; }
[...]
Lorenzo Bianconi
maintainerRe: [PATCH v3 bpf-next 5/8] libbpf: add API to get XDP/XSK supported features
Quoted 27 lines · Lorenzo Bianconi
Quoted 26 lines
Extend
bpf_xdp_queryroutine in order to get XDP/XSK supported features of netdev over route netlink interface.
Extend libbpf netlink implementation in order to supportnetlink_genericprotocol.Co-developed-by Kumar Kartikeya Dwivedi <[email protected]>Signed-off-by Kumar Kartikeya Dwivedi <[email protected]>Co-developed-by Marek Majtyka <[email protected]>Signed-off-by Marek Majtyka <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>--- 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(-)tools/lib/bpf/libbpf.h +1
-0@@ -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 */
Quoted 8 lines
tools/lib/bpf/libbpf.h struct bpf_xdp_query_opts { · line 988
Quoted 4 lines
tools/lib/bpf/libbpf.h +1
-1size_t :0; }; -#define bpf_xdp_query_opts__last_field attach_mode +#define bpf_xdp_query_opts__last_field fflagsis "fflags" an obvious name in this context? I'd expect "
feature_flags", especially that there are already "flags". Is saving a few characters worth the confusion?
ack, I will fix it.
Quoted 40 lines
Quoted 30 lines
tools/lib/bpf/libbpf.h +0
-0LIBBPF_API int bpf_xdp_attach(int ifindex, int prog_fd, __u32 flags,const struct bpf_xdp_attach_opts *opts);tools/lib/bpf/netlink.c +7
-0@@ -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)[...]
Quoted 7 lines
int
bpf_xdp_query(int ifindex, int xdp_flags, struct bpf_xdp_query_opts *opts){ struct libbpf_nla_req req = {tools/lib/bpf/netlink.c +0
-0@@ -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);
Quoted 3 lines
tools/lib/bpf/netlink.c int bpf_xdp_query(int ifindex, int xdp_flags, struct bpf_xdp_query_opts *opts) · line 463
Quoted 1 line
tools/lib/bpf/netlink.c +1
-0+if (OPTS_HAS (opts, fflags)) {maybe invert condition, return early, reduce nesting of the following code?
ack, fine, I will fix it.
Quoted 11 lines
tools/lib/bpf/netlink.c int bpf_xdp_query(int ifindex, int xdp_flags, struct bpf_xdp_query_opts *opts) · line 471
Quoted 9 lines
tools/lib/bpf/netlink.c +8
-0+struct xdp_features_md md = { + .ifindex = ifindex, + }; +__u16 id; + + err =libbpf_netlink_resolve_genl_family_id ("netdev" , +sizeof ("netdev" ), + &id);nit: if it fits under 100 characters, let's leave it on a single line
ack, fine, I will fix it (I am still used to 79 char limits :))
Regards,
Lorenzo
Quoted 29 lines
Quoted 27 lines
tools/lib/bpf/netlink.c +23
-0+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 =2 ; + + 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 ; }[...]
Lorenzo Bianconi
maintainerPATCH v3 6/8 bpf: devmap: check XDP features in __xdp_enqueue routine
In reply to Lorenzo BianconiCheck if the destination device implements ndo_xdp_xmit callback relying on NETDEV_XDP_ACT_NDO_XMIT flags. Moreover, check if the destination device supports XDP non-linear frame in __xdp_enqueue and is_valid_dst routines. This patch allows to perform XDP_REDIRECT on non-linear XDP buffers.
--- kernel/bpf/devmap.c | 16 +++++++++++++--- net/core/filter.c | 13 +++++-------- 2 files changed, 18 insertions(+), 11 deletions(-)
kernel/bpf/devmap.c +13 -3
@@ -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)))
net/core/filter.c +5 -8
@@ -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);
Signature · 6 lines
2.39.1 _______________________________________________ Intel-wired-lan mailing list [email protected] https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
Lorenzo Bianconi
maintainerPATCH v3 7/8 selftests/bpf: add test for bpf_xdp_query xdp-features support
In reply to Lorenzo BianconiIntroduce a self-test to verify libbpf bpf_xdp_query capability to dump the xdp-features supported by the device (lo and veth in this case).
--- .../bpf/prog_tests/xdp_do_redirect.c | 27 ++++++++++++++++++- .../selftests/bpf/prog_tests/xdp_info.c | 8 ++++++ 2 files changed, 34 insertions(+), 1 deletion(-)
tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c +26 -1
@@ -4,10 +4,12 @@#include <net/if.h> #include <linux/if_ether.h> #include <linux/if_packet.h> +#include <linux/if_link.h> #include <linux/ipv6.h> #include <linux/in6.h> #include <linux/udp.h> #include <bpf/bpf_endian.h> +#include <uapi/linux/netdev.h> #include "test_xdp_do_redirect.skel.h" #define SYS (fmt, ...) \
@@ -92,7 +94,7 @@ void test_xdp_do_redirect(void)struct test_xdp_do_redirect *skel =NULL ;struct nstoken *nstoken =NULL ;struct bpf_link *link; - +LIBBPF_OPTS (bpf_xdp_query_opts, query_opts);struct xdp_md ctx_in = { .data =sizeof (__u32), .data_end =sizeof (data) }; DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts,
@@ -153,6 +155,29 @@ void test_xdp_do_redirect(void) !ASSERT_NEQ(ifindex_dst, 0, "ifindex_dst")) goto out; +/* Check xdp features supported by veth driver */ + err =bpf_xdp_query (ifindex_src,XDP_FLAGS_DRV_MODE , &query_opts); +if (!ASSERT_OK (err,"veth_src bpf_xdp_query" )) + goto out; + +if (!ASSERT_EQ (query_opts.fflags, +NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT |NETDEV_XDP_ACT_RX_SG | +NETDEV_XDP_ACT_NDO_XMIT_SG , +"veth_src query_opts.fflags" )) + goto out; + + err =bpf_xdp_query (ifindex_dst,XDP_FLAGS_DRV_MODE , &query_opts); +if (!ASSERT_OK (err,"veth_dst bpf_xdp_query" )) + goto out; + +if (!ASSERT_EQ (query_opts.fflags, +NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT |NETDEV_XDP_ACT_RX_SG | +NETDEV_XDP_ACT_NDO_XMIT_SG , +"veth_dst query_opts.fflags" )) + goto out; +memcpy (skel->rodata->expect_dst, &pkt_udp.eth.h_dest,ETH_ALEN ); skel->rodata->ifindex_out = ifindex_src;/* redirect back to the same iface */ skel->rodata->ifindex_in = ifindex_src;
tools/testing/selftests/bpf/prog_tests/xdp_info.c +8 -0
@@ -8,6 +8,7 @@ void serial_test_xdp_info(void) {__u32 len =sizeof (struct bpf_prog_info ), duration =0 , prog_id;const char *file ="./xdp_dummy.bpf.o" ; +LIBBPF_OPTS (bpf_xdp_query_opts, opts);struct bpf_prog_info info = {};struct bpf_object *obj;int err, prog_fd;
@@ -61,6 +62,13 @@ void serial_test_xdp_info(void)if (CHECK (prog_id,"prog_id_drv" ,"unexpected prog_id=%u\n" , prog_id)) goto out; +/* Check xdp features supported by lo device */ + opts.fflags = ~0 ; + err =bpf_xdp_query (IFINDEX_LO ,XDP_FLAGS_DRV_MODE , &opts); +if (!ASSERT_OK (err,"bpf_xdp_query" )) + goto out; + +ASSERT_EQ (opts.fflags,0 ,"opts.fflags" ); out:bpf_xdp_detach (IFINDEX_LO ,0 ,NULL ); out_close:
Signature · 6 lines
2.39.1 _______________________________________________ Intel-wired-lan mailing list [email protected] https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
Re: [PATCH v3 bpf-next 7/8] selftests/bpf: add test for bpf_xdp_query xdp-features support
Quoted 4 lines · Lorenzo Bianconi
Introduce a self-test to verify libbpf
bpf_xdp_querycapability to dump the xdp-features supported by the device (lo and veth in this case).Signed-off-by Lorenzo Bianconi <[email protected]>
Quoted 89 lines
--- .../bpf/prog_tests/xdp_do_redirect.c | 27 ++++++++++++++++++- .../selftests/bpf/prog_tests/xdp_info.c | 8 ++++++ 2 files changed, 34 insertions(+), 1 deletion(-)tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c +26
-1@@ -4,10 +4,12 @@#include <net/if.h> #include <linux/if_ether.h> #include <linux/if_packet.h> +#include <linux/if_link.h> #include <linux/ipv6.h> #include <linux/in6.h> #include <linux/udp.h> #include <bpf/bpf_endian.h> +#include <uapi/linux/netdev.h> #include "test_xdp_do_redirect.skel.h" #define SYS (fmt, ...) \@@ -92,7 +94,7 @@ void test_xdp_do_redirect(void)struct test_xdp_do_redirect *skel =NULL ;struct nstoken *nstoken =NULL ;struct bpf_link *link; - +LIBBPF_OPTS (bpf_xdp_query_opts, query_opts);struct xdp_md ctx_in = { .data =sizeof (__u32), .data_end =sizeof (data) }; DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts,@@ -153,6 +155,29 @@ void test_xdp_do_redirect(void) !ASSERT_NEQ(ifindex_dst, 0, "ifindex_dst")) goto out; +/* Check xdp features supported by veth driver */ + err =bpf_xdp_query (ifindex_src,XDP_FLAGS_DRV_MODE , &query_opts); +if (!ASSERT_OK (err,"veth_src bpf_xdp_query" )) + goto out; + +if (!ASSERT_EQ (query_opts.fflags, +NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT |NETDEV_XDP_ACT_RX_SG | +NETDEV_XDP_ACT_NDO_XMIT_SG , +"veth_src query_opts.fflags" )) + goto out; + + err =bpf_xdp_query (ifindex_dst,XDP_FLAGS_DRV_MODE , &query_opts); +if (!ASSERT_OK (err,"veth_dst bpf_xdp_query" )) + goto out; + +if (!ASSERT_EQ (query_opts.fflags, +NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_NDO_XMIT |NETDEV_XDP_ACT_RX_SG | +NETDEV_XDP_ACT_NDO_XMIT_SG , +"veth_dst query_opts.fflags" )) + goto out; +memcpy (skel->rodata->expect_dst, &pkt_udp.eth.h_dest,ETH_ALEN ); skel->rodata->ifindex_out = ifindex_src;/* redirect back to the same iface */
skel->rodata->ifindex_in=ifindex_src;tools/testing/selftests/bpf/prog_tests/xdp_info.c +8
-1@@ -8,6 +8,7 @@ void serial_test_xdp_info(void) {__u32 len =sizeof (struct bpf_prog_info ), duration =0 , prog_id;const char *file ="./xdp_dummy.bpf.o" ; +LIBBPF_OPTS (bpf_xdp_query_opts, opts);struct bpf_prog_info info = {};struct bpf_object *obj;int err, prog_fd;@@ -61,6 +62,13 @@ void serial_test_xdp_info(void)if (CHECK (prog_id,"prog_id_drv" ,"unexpected prog_id=%u\n" , prog_id)) goto out; +/* Check xdp features supported by lo device */ + opts.fflags = ~0 ; + err =bpf_xdp_query (IFINDEX_LO ,XDP_FLAGS_DRV_MODE , &opts); +if (!ASSERT_OK (err,"bpf_xdp_query" )) + goto out; + +ASSERT_EQ (opts.fflags,0 ,"opts.fflags" ); out:bpf_xdp_detach (IFINDEX_LO ,0 ,NULL ); out_close: --
Quoted 1 line
2.39.1
_______________________________________________
Intel-wired-lan mailing list
[email protected]
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
Lorenzo Bianconi
maintainerPATCH v3 8/8 selftests/bpf: introduce XDP compliance test tool
In reply to Lorenzo BianconiIntroduce 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
--- tools/testing/selftests/bpf/.gitignore | 1 + tools/testing/selftests/bpf/Makefile | 11 +- .../selftests/bpf/progs/xdp_features.c | 249 ++++++ .../selftests/bpf/test_xdp_features.sh | 99 +++ tools/testing/selftests/bpf/xdp_features.c | 736 ++++++++++++++++++ tools/testing/selftests/bpf/xdp_features.h | 33 + 6 files changed, 1127 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/bpf/progs/xdp_features.c create mode 100755 tools/testing/selftests/bpf/test_xdp_features.sh create mode 100644 tools/testing/selftests/bpf/xdp_features.c create mode 100644 tools/testing/selftests/bpf/xdp_features.h
tools/testing/selftests/bpf/.gitignore +1 -0
@@ -48,3 +48,4 @@ xskxceiver xdp_redirect_multi xdp_synproxy xdp_hw_metadata +xdp_features
tools/testing/selftests/bpf/Makefile +9 -2
@@ -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,8 @@ 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 xdp_hw_metadata + xskxceiver xdp_redirect_multi xdp_synproxy veristat xdp_hw_metadata \ + xdp_features TEST_CUSTOM_PROGS = $(OUTPUT)/urandom_read $(OUTPUT)/sign-file TEST_GEN_FILES += liburandom_read.so
@@ -385,6 +387,7 @@ test_subskeleton_lib.skel.h-deps := test_subskeleton_lib2.bpf.o test_subskeleton test_usdt.skel.h-deps := test_usdt.bpf.o test_usdt_multispec.bpf.o xsk_xdp_progs.skel.h-deps := xsk_xdp_progs.bpf.o xdp_hw_metadata.skel.h-deps := xdp_hw_metadata.bpf.o +xdp_features.skel.h-deps := xdp_features.bpf.o LINKED_BPF_SRCS := $(patsubst %.bpf.o,%.c,$(foreach skel,$(LINKED_SKELS),$($(skel)-deps)))
@@ -586,6 +589,10 @@ $(OUTPUT)/xdp_hw_metadata: xdp_hw_metadata.c $(OUTPUT)/network_helpers.o $(OUTPU $(call msg,BINARY,,$@) $(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@ +$(OUTPUT)/xdp_features: xdp_features.c $(OUTPUT)/xdp_features.skel.h | $(OUTPUT) + $(call msg,BINARY,,$@) + $(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@ + # Make sure we are able to include and link libbpf against c++. $(OUTPUT)/test_cpp: test_cpp.cpp $(OUTPUT)/test_core_extern.skel.h $(BPFOBJ) $(call msg,CXX,,$@)
tools/testing/selftests/bpf/progs/xdp_features.c new file +249 -0
249 lines not on this page · raw message
tools/testing/selftests/bpf/test_xdp_features.sh new file +99 -0
99 lines not on this page · raw message
tools/testing/selftests/bpf/xdp_features.c new file +736 -0
736 lines not on this page · raw message
tools/testing/selftests/bpf/xdp_features.h new file +33 -0
@@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* 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 */ +}; + +#define DUT_CTRL_PORT 12345 +#define DUT_ECHO_PORT 12346 + +struct tlv_hdr { +__be16 type; +__be16 len; +__be32 data[]; +}; + +enum { +XDP_FEATURE_ABORTED , +XDP_FEATURE_DROP , +XDP_FEATURE_PASS , +XDP_FEATURE_TX , +XDP_FEATURE_REDIRECT , +XDP_FEATURE_NDO_XMIT , +XDP_FEATURE_XSK_ZEROCOPY , +XDP_FEATURE_HW_OFFLOAD , +XDP_FEATURE_RX_SG , +XDP_FEATURE_NDO_XMIT_SG , +};
Signature · 6 lines
2.39.1 _______________________________________________ Intel-wired-lan mailing list [email protected] https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
Re: [PATCH v3 bpf-next 8/8] selftests/bpf: introduce XDP compliance test tool
Quoted 354 lines · Lorenzo Bianconi
Introduce
xdp_featurestool 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_featuresmust run on the Device Under Test (DUT) and on a Tester device.xdp_featuresopens 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. Currentlyxdp_featuressupports the following XDP features:
-XDP_DROP
-XDP_PASS
-XDP_TX
-XDP_REDIRECT
-XDP_REDIRECT_TARGETCo-developed-by Kumar Kartikeya Dwivedi <[email protected]>Signed-off-by Kumar Kartikeya Dwivedi <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>--- tools/testing/selftests/bpf/.gitignore | 1 + tools/testing/selftests/bpf/Makefile | 11 +- .../selftests/bpf/progs/xdp_features.c | 249 ++++++ .../selftests/bpf/test_xdp_features.sh | 99 +++ tools/testing/selftests/bpf/xdp_features.c | 736 ++++++++++++++++++ tools/testing/selftests/bpf/xdp_features.h | 33 + 6 files changed, 1127 insertions(+), 2 deletions(-)create mode 100644
tools/testing/selftests/bpf/progs/xdp_features.ccreate mode 100755tools/testing/selftests/bpf/test_xdp_features.shcreate mode 100644tools/testing/selftests/bpf/xdp_features.ccreate mode 100644tools/testing/selftests/bpf/xdp_features.htools/testing/selftests/bpf/.gitignore +1
-0@@ -48,3 +48,4 @@ xskxceiver xdp_redirect_multi xdp_synproxy xdp_hw_metadata +xdp_featurestools/testing/selftests/bpf/Makefile +4
-2@@ -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,8 @@ 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 xdp_hw_metadata + xskxceiver xdp_redirect_multi xdp_synproxy veristat xdp_hw_metadata \ + xdp_features TEST_CUSTOM_PROGS = $(OUTPUT)/urandom_read $(OUTPUT)/sign-file TEST_GEN_FILES += liburandom_read.so@@ -385,6 +387,7 @@ test_subskeleton_lib.skel.h-deps :=test_subskeleton_lib2.bpf.o
test_subskeleton
test_usdt.skel.h-deps := test_usdt.bpf.o test_usdt_multispec.bpf.o xsk_xdp_progs.skel.h-deps := xsk_xdp_progs.bpf.o xdp_hw_metadata.skel.h-deps := xdp_hw_metadata.bpf.o
+xdp_features.skel.h-deps := xdp_features.bpf.o
LINKED_BPF_SRCS:= $(patsubst %.bpf.o,%.c,$(foreach
skel,$(LINKED_SKELS),$($(skel)-deps)))tools/testing/selftests/bpf/Makefile +0
-0@@ -586,6 +589,10 @@ $(OUTPUT)/xdp_hw_metadata: xdp_hw_metadata.c$(OUTPUT)/network_helpers.o $(OUTPU
$(call msg,BINARY,,$@)
$(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@+$(OUTPUT)/xdp_features:
xdp_features.c$(OUTPUT)/xdp_features.skel.h | $(OUTPUT)tools/testing/selftests/bpf/Makefile +3
-0+ $(call msg,BINARY,,$@) + $(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@ + # Make sure we are able to include and link libbpf against c++. $(OUTPUT)/test_cpp: test_cpp.cpp $(OUTPUT)/test_core_extern.skel.h$(BPFOBJ)
$(call msg,CXX,,$@)tools/testing/selftests/bpf/progs/xdp_features.c new file +64
-0@@ -0,0 +1,249 @@ +// 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/ipv6.h> +#include <linux/in.h> +#include <linux/in6.h> +#include <linux/udp.h> +#include <asm-generic/errno-base.h> + +#include "xdp_features.h" + +#define ipv6_addr_equal (a, b) ((a).s6_addr32[0] == (b).s6_addr32[0] && \ + (a).s6_addr32[1] == (b).s6_addr32[1] && \ + (a).s6_addr32[2] == (b).s6_addr32[2] && \ + (a).s6_addr32[3] == (b).s6_addr32[3]) + +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 =XDP_FEATURE_PASS ; +const volatile __be32 tester_ip; +const volatile __be32 dut_ip; +const volatile struct in6_addr tester_ip6; +const volatile struct in6_addr dut_ip6; + +static __always_inline int xdp_process_echo_packet(struct xdp_md *xdp,bool dut)
tools/testing/selftests/bpf/progs/xdp_features.c new file +185
-0+{ +void *data_end = (void *)(long )xdp->data_end; +void *data = (void *)(long )xdp->data; +struct ethhdr *eh = data; +struct tlv_hdr *tlv; +struct udphdr *uh; +__be16 port; +__u8 *cmd; + +if (eh +1 > (struct ethhdr *)data_end) +return -EINVAL ; + +if (eh->h_proto ==bpf_htons (ETH_P_IP )) { +struct iphdr *ih = (struct iphdr *)(eh +1 ); +__be32 saddr = dut ? tester_ip : dut_ip; +__be32 daddr = dut ? dut_ip : tester_ip; + + 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 ); + }else if (eh->h_proto ==bpf_htons (ETH_P_IPV6 )) { +struct in6_addr saddr = dut ? tester_ip6 : dut_ip6; +struct in6_addr daddr = dut ? dut_ip6 : tester_ip6; +struct ipv6hdr *ih6 = (struct ipv6hdr *)(eh +1 ); + +if (ih6 +1 > (struct ipv6hdr *)data_end) +return -EINVAL ; + +if (!ipv6_addr_equal (saddr, ih6->saddr)) +return -EINVAL ; + +if (!ipv6_addr_equal (daddr, ih6->daddr)) +return -EINVAL ; + +if (ih6->nexthdr !=IPPROTO_UDP ) +return -EINVAL ; + + uh = (struct udphdr *)(ih6 +1 ); + }else { +return -EINVAL ; + } + +if (uh +1 > (struct udphdr *)data_end) +return -EINVAL ; + + port = dut ? uh->dest : uh->source; +if (port !=bpf_htons (DUT_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 XDP_FEATURE_NDO_XMIT : +case XDP_FEATURE_TX : +if (xdp_process_echo_packet (xdp, true)) + goto out; +break ; +case XDP_FEATURE_DROP : +case XDP_FEATURE_PASS : +case XDP_FEATURE_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";tools/testing/selftests/bpf/test_xdp_features.sh new file +3
-0@@ -0,0 +1,99 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +
tools/testing/selftests/bpf/test_xdp_features.sh line 13
Quoted 10 lines
tools/testing/selftests/bpf/test_xdp_features.sh new file +10
-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)"
Why do we need the namespaces? Why not have two veth peers in the current namespace?
(not sure it matters, just wondering)
Quoted 329 lines
tools/testing/selftests/bpf/test_xdp_features.sh new file +45
-0+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/nulltools/testing/selftests/bpf/test_xdp_features.sh new file +7
-0+} + +test_xdp_features() { + setup + + ## XDP_PASS + ip netns exec ${NS1} ./xdp_features -f XDP_PASS -D 10.10.1.11 -T10.10.0.11 v11 &
tools/testing/selftests/bpf/test_xdp_features.sh new file +1
-0+ ip netns exec ${NS0} ./xdp_features -t -f XDP_PASS -D 10.10.1.11 -C10.10.1.11 -T 10.10.0.11 v00
tools/testing/selftests/bpf/test_xdp_features.sh new file +5
-0+ + [ $? -ne 0 ] && exit + + # XDP_DROP + ip netns exec ${NS1} ./xdp_features -f XDP_DROP -D 10.10.1.11 -T10.10.0.11 v11 &
tools/testing/selftests/bpf/test_xdp_features.sh new file +1
-0+ ip netns exec ${NS0} ./xdp_features -t -f XDP_DROP -D 10.10.1.11 -C10.10.1.11 -T 10.10.0.11 v00
tools/testing/selftests/bpf/test_xdp_features.sh new file +6
-0+ + [ $? -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 -C10.10.0.1 -T 10.10.0.11 v00
tools/testing/selftests/bpf/test_xdp_features.sh new file +3
-0+ + ## XDP_REDIRECT + ip netns exec ${NS1} ./xdp_features -f XDP_REDIRECT -D 10.10.1.11 -T10.10.0.11 v11 &
tools/testing/selftests/bpf/test_xdp_features.sh new file +1
-0+ ip netns exec ${NS0} ./xdp_features -t -f XDP_REDIRECT -D 10.10.1.11 -C10.10.1.11 -T 10.10.0.11 v00
tools/testing/selftests/bpf/test_xdp_features.sh new file +6
-0+ + [ $? -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 -C10.10.0.1 -T 10.10.0.11 v00
tools/testing/selftests/bpf/test_xdp_features.sh new file +11
-0+ + ret=$? + cleanup +} + +set -e +trap cleanup 2 3 6 9 + +test_xdp_features + +exit $rettools/testing/selftests/bpf/xdp_features.c new file +55
-0@@ -0,0 +1,736 @@ +// 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 "xdp_features.skel.h" +#include "xdp_features.h" + +#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 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 matchdetected 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";tools/testing/selftests/bpf/xdp_features.c new file +8
-0+ +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" },
tools/testing/selftests/bpf/xdp_features.c new file +152
-0+ {}, +}; + +static int get_xdp_feature (const char *arg) +{ +if (!strcmp (arg,"XDP_PASS" )) +return XDP_FEATURE_PASS ; +else if (!strcmp (arg,"XDP_DROP" )) +return XDP_FEATURE_DROP ; +else if (!strcmp (arg,"XDP_ABORTED" )) +return XDP_FEATURE_ABORTED ; +else if (!strcmp (arg,"XDP_REDIRECT" )) +return XDP_FEATURE_REDIRECT ; +else if (!strcmp (arg,"XDP_NDO_XMIT" )) +return XDP_FEATURE_NDO_XMIT ; +else if (!strcmp (arg,"XDP_TX" )) +return XDP_FEATURE_TX ; + +return -EINVAL ; +} + +static char *get_xdp_feature_str (int feature) +{ +switch (feature) { +case XDP_FEATURE_PASS : +return YELLOW ("XDP_PASS" ); +case XDP_FEATURE_DROP : +return YELLOW ("XDP_DROP" ); +case XDP_FEATURE_ABORTED : +return YELLOW ("XDP_ABORTED" ); +case XDP_FEATURE_TX : +return YELLOW ("XDP_TX" ); +case XDP_FEATURE_REDIRECT : +return YELLOW ("XDP_REDIRECT" ); +case XDP_FEATURE_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 =XDP_FEATURE_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 ; +
[..]
Quoted 8 lines
tools/testing/selftests/bpf/xdp_features.c new file +8
-0+ 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));
tools/testing/selftests/bpf/xdp_features.c line 243
Quoted 10 lines
tools/testing/selftests/bpf/xdp_features.c new file +10
-0+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; + }
IIRC, Martin mentioned IPv6 support in the previous version. Should we also make the userspace v6 aware by at least using AF_INET6 dualstack sockets? I feel like listening on inaddr_any with AF_INET6 should get us there without too much pain..
Quoted 108 lines
tools/testing/selftests/bpf/xdp_features.c new file +108
-0+ +/* 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 xdp_features *skel,int feature, +int flags) +{ +struct bpf_program *prog; +unsigned int key =0 ; +int err, fd =0 ; + +switch (feature) { +case XDP_FEATURE_TX : + prog = skel->progs.xdp_do_tx; +break ; +case XDP_FEATURE_DROP : +case XDP_FEATURE_ABORTED : + prog = skel->progs.xdp_do_drop; +break ; +case XDP_FEATURE_PASS : + prog = skel->progs.xdp_do_pass; +break ; +case XDP_FEATURE_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 XDP_FEATURE_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 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; +
[..]
Quoted 14 lines
tools/testing/selftests/bpf/xdp_features.c new file +14
-0+ 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));
tools/testing/selftests/bpf/xdp_features.c line 375
Quoted 10 lines
tools/testing/selftests/bpf/xdp_features.c new file +10
-0+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; + }
Should we use start_server from network_helpers.h here?
Quoted 232 lines
tools/testing/selftests/bpf/xdp_features.c new file +232
-0+ + 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) +{ +switch (env.feature) { +case XDP_FEATURE_ABORTED : +case XDP_FEATURE_DROP : +case XDP_FEATURE_PASS : +case XDP_FEATURE_TX : +return cap &NETDEV_XDP_ACT_BASIC ; +case XDP_FEATURE_REDIRECT : +return cap &NETDEV_XDP_ACT_REDIRECT ; +case XDP_FEATURE_NDO_XMIT : +return cap &NETDEV_XDP_ACT_NDO_XMIT ; +default : +return false; + } +} + +static bool tester_collect_detected_cap (struct 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 XDP_FEATURE_PASS : +case XDP_FEATURE_TX : +case XDP_FEATURE_REDIRECT : +case XDP_FEATURE_NDO_XMIT : +return val >0 ; +case XDP_FEATURE_DROP : +case XDP_FEATURE_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 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 ]; +
[..]
tools/testing/selftests/bpf/xdp_features.c line 619
Quoted 12 lines
tools/testing/selftests/bpf/xdp_features.c new file +12
-0+ 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 ); + }
There is also connect_to_fd, maybe we can use that? It should take care of the timeouts.. (requires plumbing server_fd, not sure whether it's a problem or not)
Quoted 160 lines
tools/testing/selftests/bpf/xdp_features.c new file +7
-0+ +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));tools/testing/selftests/bpf/xdp_features.c new file +40
-0+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),tools/testing/selftests/bpf/xdp_features.c new file +70
-0+ 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 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 =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 =xdp_features__load (skel); +if (err) { +fprintf (stderr,"Failed to load and verify BPF skeleton\n" ); + goto cleanup; + } + + err =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: +xdp_features__destroy (skel); + +return err <0 ? -err :0 ; +}tools/testing/selftests/bpf/xdp_features.h new file +33
-1@@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* 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 */ +}; + +#define DUT_CTRL_PORT 12345 +#define DUT_ECHO_PORT 12346 + +struct tlv_hdr { +__be16 type; +__be16 len; +__be32 data[]; +}; + +enum { +XDP_FEATURE_ABORTED , +XDP_FEATURE_DROP , +XDP_FEATURE_PASS , +XDP_FEATURE_TX , +XDP_FEATURE_REDIRECT , +XDP_FEATURE_NDO_XMIT , +XDP_FEATURE_XSK_ZEROCOPY , +XDP_FEATURE_HW_OFFLOAD , +XDP_FEATURE_RX_SG , +XDP_FEATURE_NDO_XMIT_SG , +}; --2.39.1
Martin KaFai Lau
reviewerRe: [PATCH v3 bpf-next 8/8] selftests/bpf: introduce XDP compliance test tool
Quoted 16 lines · On 1/26/23 10:36 AM, [email protected] wrote:
Quoted 16 lines
+ sockfd =
socket(AF_INET, SOCK_DGRAM, 0);
+ if (sockfd < 0) {
+fprintf(stderr, "Failed to create echo socket\n"); + return -errno;
+ }tools/testing/selftests/bpf/xdp_features.c new file +10
-0+ + 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) {
Quoted 8 lines
Quoted 3 lines
+
fprintf(stderr, "Failed to bind echo socket\n"); + return -errno;
+ }IIRC, Martin mentioned IPv6 support in the previous version. Should we also make the userspace v6 aware by at least using
AF_INET6dualstack sockets? I feel like listening oninaddr_anywithAF_INET6should get us there without too much pain..
Yeah. Think about host that only has IPv6 address. A tool not supporting IPv6 is a no-go nowadays.
Lorenzo Bianconi
maintainerRe: [PATCH v3 bpf-next 8/8] selftests/bpf: introduce XDP compliance test tool
Quoted 26 lines · On 1/26/23 10:36 AM, [email protected] wrote:
Quoted 16 lines
Quoted 16 lines
+ sockfd =
socket(AF_INET, SOCK_DGRAM, 0);
+ if (sockfd < 0) {
+fprintf(stderr, "Failed to create echo socket\n"); + return -errno;
+ }tools/testing/selftests/bpf/xdp_features.c new file +10
-0+ + 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) {Quoted 8 lines
Quoted 3 lines
+
fprintf(stderr, "Failed to bind echo socket\n"); + return -errno;
+ }IIRC, Martin mentioned IPv6 support in the previous version. Should we also make the userspace v6 aware by at least using
AF_INET6dualstack sockets? I feel like listening oninaddr_anywithAF_INET6should get us there without too much pain..
Quoted 2 lines
Yeah. Think about host that only has IPv6 address. A tool not supporting IPv6 is a no-go nowadays.
ack, I will add it in v4.
Regards,
Lorenzo
_______________________________________________
Intel-wired-lan mailing list
[email protected]
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
Lorenzo Bianconi
maintainerRe: [PATCH v3 bpf-next 8/8] selftests/bpf: introduce XDP compliance test tool
In reply to [email protected]Quoted 1 line · Lorenzo Bianconi
[...]
Quoted 3 lines
Why do we need the namespaces? Why not have two veth peers in the current namespace?
I think we can use just a veth pair here, we do not need two, I will fix it.
Quoted 41 lines
(not sure it matters, just wondering)
Quoted 38 lines
tools/testing/selftests/bpf/test_xdp_features.sh new file +38
-0+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 +}
[...]
Quoted 5 lines
IIRC, Martin mentioned IPv6 support in the previous version. Should we also make the userspace v6 aware by at least using
AF_INET6dualstack sockets? I feel like listening oninaddr_anywithAF_INET6should get us there without too much pain..
ack, I will fix it.
Quoted 130 lines
Quoted 109 lines
tools/testing/selftests/bpf/xdp_features.c new file +108
-0+ +/* 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 xdp_features *skel,int feature, +int flags) +{ +struct bpf_program *prog; +unsigned int key =0 ; +int err, fd =0 ; + +switch (feature) { +case XDP_FEATURE_TX : + prog = skel->progs.xdp_do_tx; +break ; +case XDP_FEATURE_DROP : +case XDP_FEATURE_ABORTED : + prog = skel->progs.xdp_do_drop; +break ; +case XDP_FEATURE_PASS : + prog = skel->progs.xdp_do_pass; +break ; +case XDP_FEATURE_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 XDP_FEATURE_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 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; +[..]
Quoted 18 lines
tools/testing/selftests/bpf/xdp_features.c new file +18
-0+ 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; + }
Quoted 8 lines
tools/testing/selftests/bpf/xdp_features.c line 375
Quoted 6 lines
tools/testing/selftests/bpf/xdp_features.c new file +6
-0+ + err =listen (sockfd,5 ); +if (err) { +fprintf (stderr,"Failed to listen DUT socket\n" ); +return -errno; + }Should we use
start_serverfromnetwork_helpers.hhere?
ack, I will use it.
Quoted 9 lines
Quoted 9 lines
tools/testing/selftests/bpf/xdp_features.c new file +8
-0+ + 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; + } +
[...]
Quoted 4 lines
There is also
connect_to_fd, maybe we can use that? It should take care of the timeouts.. (requires plumbingserver_fd, not sure whether it's a problem or not)
please correct me if I am wrong, but in order to have server_fd it is mandatory both tester and DUT are running on the same process, right? Here, I guess 99% of the times DUT and tester will run on two separated devices. Agree?
Regards,
Lorenzo
Quoted 163 lines
Quoted 162 lines
tools/testing/selftests/bpf/xdp_features.c new file +7
-0+ +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));tools/testing/selftests/bpf/xdp_features.c new file +40
-0+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),tools/testing/selftests/bpf/xdp_features.c new file +70
-0+ 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 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 =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 =xdp_features__load (skel); +if (err) { +fprintf (stderr,"Failed to load and verify BPF skeleton\n" ); + goto cleanup; + } + + err =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: +xdp_features__destroy (skel); + +return err <0 ? -err :0 ; +}tools/testing/selftests/bpf/xdp_features.h new file +33
-1@@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* 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 */ +}; + +#define DUT_CTRL_PORT 12345 +#define DUT_ECHO_PORT 12346 + +struct tlv_hdr { +__be16 type; +__be16 len; +__be32 data[]; +}; + +enum { +XDP_FEATURE_ABORTED , +XDP_FEATURE_DROP , +XDP_FEATURE_PASS , +XDP_FEATURE_TX , +XDP_FEATURE_REDIRECT , +XDP_FEATURE_NDO_XMIT , +XDP_FEATURE_XSK_ZEROCOPY , +XDP_FEATURE_HW_OFFLOAD , +XDP_FEATURE_RX_SG , +XDP_FEATURE_NDO_XMIT_SG , +}; --2.39.1
Re: [PATCH v3 bpf-next 8/8] selftests/bpf: introduce XDP compliance test tool
Quoted 216 lines · Lorenzo Bianconi
Quoted 2 lines · Lorenzo Bianconi
[...]
Quoted 3 lines
Why do we need the namespaces? Why not have two veth peers in the current namespace?
I think we can use just a veth pair here, we do not need two, I will fix it.
Quoted 41 lines
(not sure it matters, just wondering)
Quoted 38 lines
tools/testing/selftests/bpf/test_xdp_features.sh new file +38
-0+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 +}[...]
Quoted 5 lines
IIRC, Martin mentioned IPv6 support in the previous version. Should we also make the userspace v6 aware by at least using
AF_INET6dualstack sockets? I feel like listening oninaddr_anywithAF_INET6should get us there without too much pain..ack, I will fix it.
Quoted 130 lines
Quoted 109 lines
tools/testing/selftests/bpf/xdp_features.c new file +108
-0+ +/* 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 xdp_features *skel,int feature, +int flags) +{ +struct bpf_program *prog; +unsigned int key =0 ; +int err, fd =0 ; + +switch (feature) { +case XDP_FEATURE_TX : + prog = skel->progs.xdp_do_tx; +break ; +case XDP_FEATURE_DROP : +case XDP_FEATURE_ABORTED : + prog = skel->progs.xdp_do_drop; +break ; +case XDP_FEATURE_PASS : + prog = skel->progs.xdp_do_pass; +break ; +case XDP_FEATURE_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 XDP_FEATURE_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 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; +[..]
Quoted 18 lines
tools/testing/selftests/bpf/xdp_features.c new file +18
-0+ 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; + }Quoted 8 lines
tools/testing/selftests/bpf/xdp_features.c line 375
Quoted 6 lines
tools/testing/selftests/bpf/xdp_features.c new file +6
-0+ + err =listen (sockfd,5 ); +if (err) { +fprintf (stderr,"Failed to listen DUT socket\n" ); +return -errno; + }Should we use
start_serverfromnetwork_helpers.hhere?ack, I will use it.
Quoted 9 lines
Quoted 9 lines
tools/testing/selftests/bpf/xdp_features.c new file +8
-0+ + 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; + } +[...]
Quoted 1 line
Quoted 7 lines
Quoted 3 lines
There is also
connect_to_fd, maybe we can use that? It should take care of the timeouts.. (requires plumbingserver_fd, not sure whether it's a problem or not)please correct me if I am wrong, but in order to have
server_fdit is mandatory both tester and DUT are running on the same process, right? Here, I guess 99% of the times DUT and tester will run on two separated devices. Agree?
Yes, it's targeting more the case where you have a server fd and a bunch of clients in the same process. But I think it's still usable in your case, you're not using fork() anywhere afaict, so even if these are separate devices, connect_to_fd should still work. (unless I'm missing something, haven't looked too closely)
Quoted 166 lines
Regards,
LorenzoQuoted 163 lines
Quoted 162 lines
tools/testing/selftests/bpf/xdp_features.c new file +7
-0+ +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));tools/testing/selftests/bpf/xdp_features.c new file +40
-0+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),tools/testing/selftests/bpf/xdp_features.c new file +70
-0+ 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 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 =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 =xdp_features__load (skel); +if (err) { +fprintf (stderr,"Failed to load and verify BPF skeleton\n" ); + goto cleanup; + } + + err =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: +xdp_features__destroy (skel); + +return err <0 ? -err :0 ; +}tools/testing/selftests/bpf/xdp_features.h new file +33
-1@@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* 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 */ +}; + +#define DUT_CTRL_PORT 12345 +#define DUT_ECHO_PORT 12346 + +struct tlv_hdr { +__be16 type; +__be16 len; +__be32 data[]; +}; + +enum { +XDP_FEATURE_ABORTED , +XDP_FEATURE_DROP , +XDP_FEATURE_PASS , +XDP_FEATURE_TX , +XDP_FEATURE_REDIRECT , +XDP_FEATURE_NDO_XMIT , +XDP_FEATURE_XSK_ZEROCOPY , +XDP_FEATURE_HW_OFFLOAD , +XDP_FEATURE_RX_SG , +XDP_FEATURE_NDO_XMIT_SG , +}; --2.39.1
_______________________________________________
Intel-wired-lan mailing list
[email protected]
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
Re: [PATCH v3 bpf-next 8/8] selftests/bpf: introduce XDP compliance test tool
Quoted 20 lines · Stanislav Fomichev
Quoted 12 lines
Quoted 8 lines
Quoted 8 lines
tools/testing/selftests/bpf/xdp_features.c new file +8
-0+ + 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; + } +[...]
Quoted 1 line
Quoted 7 lines
Quoted 3 lines
There is also
connect_to_fd, maybe we can use that? It should take care of the timeouts.. (requires plumbingserver_fd, not sure whether it's a problem or not)please correct me if I am wrong, but in order to have
server_fdit is mandatory both tester and DUT are running on the same process, right? Here, I guess 99% of the times DUT and tester will run on two separated devices. Agree?
Quoted 5 lines
Yes, it's targeting more the case where you have a server fd and a bunch of clients in the same process. But I think it's still usable in your case, you're not using
fork()anywhere afaict, so even if these are separate devices,connect_to_fdshould still work. (unless I'm missing something, haven't looked too closely)
Just to add a bit of context here, "separate devices" can refer to the hosts as well as the netdevs. I.e., it should also be possible to run this in a mode where the client bit runs on a different physical machine than the server bit (as it will not be feasible in any case to connect things with loopback cables).
-Toke
_______________________________________________
Intel-wired-lan mailing list
[email protected]
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
Lorenzo Bianconi
maintainerRe: [PATCH v3 bpf-next 8/8] selftests/bpf: introduce XDP compliance test tool
Quoted 28 lines · Toke
Quoted 20 lines · Stanislav Fomichev
Quoted 12 lines
Quoted 8 lines
Quoted 8 lines
tools/testing/selftests/bpf/xdp_features.c new file +8
-0+ + 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; + } +[...]
Quoted 1 line
Quoted 7 lines
Quoted 3 lines
There is also
connect_to_fd, maybe we can use that? It should take care of the timeouts.. (requires plumbingserver_fd, not sure whether it's a problem or not)please correct me if I am wrong, but in order to have
server_fdit is mandatory both tester and DUT are running on the same process, right? Here, I guess 99% of the times DUT and tester will run on two separated devices. Agree?Quoted 5 lines
Yes, it's targeting more the case where you have a server fd and a bunch of clients in the same process. But I think it's still usable in your case, you're not using
fork()anywhere afaict, so even if these are separate devices,connect_to_fdshould still work. (unless I'm missing something, haven't looked too closely)
Quoted 5 lines
Just to add a bit of context here, "separate devices" can refer to the hosts as well as the netdevs. I.e., it should also be possible to run this in a mode where the client bit runs on a different physical machine than the server bit (as it will not be feasible in any case to connect things with loopback cables).
yes, this is what I meant with 'DUT and tester will run on two separated devices' (sorry to have not been so clear). Looking at the code server_fd is always obtained from start_server(), while here the client on the tester just knows the IPv4/IPv6 address and the port of the server running on the DUT.
Regards,
Lorenzo
Quoted 3 lines
-Toke
Re: [PATCH v3 bpf-next 8/8] selftests/bpf: introduce XDP compliance test tool
Quoted 36 lines · Lorenzo Bianconi
Quoted 28 lines · Toke
Quoted 20 lines · Stanislav Fomichev
Quoted 12 lines
Quoted 8 lines
Quoted 8 lines
tools/testing/selftests/bpf/xdp_features.c new file +8
-0+ + 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; + } +[...]
Quoted 1 line
Quoted 7 lines
Quoted 3 lines
There is also
connect_to_fd, maybe we can use that? It should take care of the timeouts.. (requires plumbingserver_fd, not sure whether it's a problem or not)please correct me if I am wrong, but in order to have
server_fdit is mandatory both tester and DUT are running on the same process, right? Here, I guess 99% of the times DUT and tester will run on two separated devices. Agree?Quoted 5 lines
Yes, it's targeting more the case where you have a server fd and a bunch of clients in the same process. But I think it's still usable in your case, you're not using
fork()anywhere afaict, so even if these are separate devices,connect_to_fdshould still work. (unless I'm missing something, haven't looked too closely)Quoted 5 lines
Just to add a bit of context here, "separate devices" can refer to the hosts as well as the netdevs. I.e., it should also be possible to run this in a mode where the client bit runs on a different physical machine than the server bit (as it will not be feasible in any case to connect things with loopback cables).
Quoted 4 lines
yes, this is what I meant with 'DUT and tester will run on two separated devices' (sorry to have not been so clear). Looking at the code
server_fdis always obtained fromstart_server(), while here the client on the tester just knows the IPv4/IPv6 address and the port of the server running on the DUT.
Ah, in this case yeah, definitely, connect_to_fd can't be applied here, ignore me.
Thanks for clarifying! In this case let's just make the tool dualstack aware.
Quoted 6 lines
Regards,
LorenzoQuoted 3 lines
-Toke
_______________________________________________
Intel-wired-lan mailing list
[email protected]
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan