bpf: expose information about supported xdp metadata kfunc
authorStanislav Fomichev <sdf@google.com>
Wed, 13 Sep 2023 17:13:49 +0000 (10:13 -0700)
committerMartin KaFai Lau <martin.lau@kernel.org>
Fri, 15 Sep 2023 18:26:58 +0000 (11:26 -0700)
Add new xdp-rx-metadata-features member to netdev netlink
which exports a bitmask of supported kfuncs. Most of the patch
is autogenerated (headers), the only relevant part is netdev.yaml
and the changes in netdev-genl.c to marshal into netlink.

Example output on veth:

$ ip link add veth0 type veth peer name veth1 # ifndex == 12
$ ./tools/net/ynl/samples/netdev 12

Select ifc ($ifindex; or 0 = dump; or -2 ntf check): 12
   veth1[12]    xdp-features (23): basic redirect rx-sg xdp-rx-metadata-features (3): timestamp hash xdp-zc-max-segs=0

Cc: netdev@vger.kernel.org
Cc: Willem de Bruijn <willemb@google.com>
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/r/20230913171350.369987-3-sdf@google.com
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Documentation/netlink/specs/netdev.yaml
Documentation/networking/xdp-rx-metadata.rst
include/net/xdp.h
include/uapi/linux/netdev.h
kernel/bpf/offload.c
net/core/netdev-genl.c
net/core/xdp.c
tools/include/uapi/linux/netdev.h

index 1c7284fd535bd456e54563ecc4e63ce4d977614c..c46fcc78fc047730af5233a93f323e8b855be74f 100644 (file)
@@ -42,6 +42,19 @@ definitions:
         doc:
           This feature informs if netdev implements non-linear XDP buffer
           support in ndo_xdp_xmit callback.
+  -
+    type: flags
+    name: xdp-rx-metadata
+    render-max: true
+    entries:
+      -
+        name: timestamp
+        doc:
+          Device is capable of exposing receive HW timestamp via bpf_xdp_metadata_rx_timestamp().
+      -
+        name: hash
+        doc:
+          Device is capable of exposing receive packet hash via bpf_xdp_metadata_rx_hash().
 
 attribute-sets:
   -
@@ -68,6 +81,13 @@ attribute-sets:
         type: u32
         checks:
           min: 1
+      -
+        name: xdp-rx-metadata-features
+        doc: Bitmask of supported XDP receive metadata features.
+             See Documentation/networking/xdp-rx-metadata.rst for more details.
+        type: u64
+        enum: xdp-rx-metadata
+        enum-as-flags: true
 
 operations:
   list:
@@ -84,6 +104,7 @@ operations:
             - ifindex
             - xdp-features
             - xdp-zc-max-segs
+            - xdp-rx-metadata-features
       dump:
         reply: *dev-all
     -
index 25ce72af81c216322edfe56da3195fdd13a47db8..205696780b7897a01225de9223824e7ed5ca4018 100644 (file)
@@ -105,6 +105,13 @@ bpf_tail_call
 Adding programs that access metadata kfuncs to the ``BPF_MAP_TYPE_PROG_ARRAY``
 is currently not supported.
 
+Supported Devices
+=================
+
+It is possible to query which kfunc the particular netdev implements via
+netlink. See ``xdp-rx-metadata-features`` attribute set in
+``Documentation/netlink/specs/netdev.yaml``.
+
 Example
 =======
 
index d59e12f8f311dc40a4a75f532bee18250875c462..349c36fb5fd8f75d9c38da795c8bc1f787c79d2f 100644 (file)
@@ -386,19 +386,22 @@ void xdp_attachment_setup(struct xdp_attachment_info *info,
 /* Define the relationship between xdp-rx-metadata kfunc and
  * various other entities:
  * - xdp_rx_metadata enum
+ * - netdev netlink enum (Documentation/netlink/specs/netdev.yaml)
  * - kfunc name
  * - xdp_metadata_ops field
  */
 #define XDP_METADATA_KFUNC_xxx \
        XDP_METADATA_KFUNC(XDP_METADATA_KFUNC_RX_TIMESTAMP, \
+                          NETDEV_XDP_RX_METADATA_TIMESTAMP, \
                           bpf_xdp_metadata_rx_timestamp, \
                           xmo_rx_timestamp) \
        XDP_METADATA_KFUNC(XDP_METADATA_KFUNC_RX_HASH, \
+                          NETDEV_XDP_RX_METADATA_HASH, \
                           bpf_xdp_metadata_rx_hash, \
                           xmo_rx_hash) \
 
 enum xdp_rx_metadata {
-#define XDP_METADATA_KFUNC(name, _, __) name,
+#define XDP_METADATA_KFUNC(name, _, __, ___) name,
 XDP_METADATA_KFUNC_xxx
 #undef XDP_METADATA_KFUNC
 MAX_XDP_METADATA_KFUNC,
index c1634b95c223ab5b1ea74b4b8e7d32505390012c..2943a151d4f128e1a0cf351a7870bb53bbaebe1c 100644 (file)
@@ -38,11 +38,27 @@ enum netdev_xdp_act {
        NETDEV_XDP_ACT_MASK = 127,
 };
 
+/**
+ * enum netdev_xdp_rx_metadata
+ * @NETDEV_XDP_RX_METADATA_TIMESTAMP: Device is capable of exposing receive HW
+ *   timestamp via bpf_xdp_metadata_rx_timestamp().
+ * @NETDEV_XDP_RX_METADATA_HASH: Device is capable of exposing receive packet
+ *   hash via bpf_xdp_metadata_rx_hash().
+ */
+enum netdev_xdp_rx_metadata {
+       NETDEV_XDP_RX_METADATA_TIMESTAMP = 1,
+       NETDEV_XDP_RX_METADATA_HASH = 2,
+
+       /* private: */
+       NETDEV_XDP_RX_METADATA_MASK = 3,
+};
+
 enum {
        NETDEV_A_DEV_IFINDEX = 1,
        NETDEV_A_DEV_PAD,
        NETDEV_A_DEV_XDP_FEATURES,
        NETDEV_A_DEV_XDP_ZC_MAX_SEGS,
+       NETDEV_A_DEV_XDP_RX_METADATA_FEATURES,
 
        __NETDEV_A_DEV_MAX,
        NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
index 6aa6de8d715dde45014cd38b48f6459112441811..e7a1752b5a09a6366d3ce6202f49c8027e989f78 100644 (file)
@@ -845,7 +845,7 @@ void *bpf_dev_bound_resolve_kfunc(struct bpf_prog *prog, u32 func_id)
        if (!ops)
                goto out;
 
-#define XDP_METADATA_KFUNC(name, _, xmo) \
+#define XDP_METADATA_KFUNC(name, _, __, xmo) \
        if (func_id == bpf_xdp_metadata_kfunc_id(name)) p = ops->xmo;
        XDP_METADATA_KFUNC_xxx
 #undef XDP_METADATA_KFUNC
index c1aea8b756b6cfb1c16c3420cee22d913ecfb850..fe61f85bcf336272969c5cc70c952f85988171c2 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/rtnetlink.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
+#include <net/xdp.h>
 
 #include "netdev-genl-gen.h"
 
@@ -12,15 +13,24 @@ static int
 netdev_nl_dev_fill(struct net_device *netdev, struct sk_buff *rsp,
                   const struct genl_info *info)
 {
+       u64 xdp_rx_meta = 0;
        void *hdr;
 
        hdr = genlmsg_iput(rsp, info);
        if (!hdr)
                return -EMSGSIZE;
 
+#define XDP_METADATA_KFUNC(_, flag, __, xmo) \
+       if (netdev->xdp_metadata_ops && netdev->xdp_metadata_ops->xmo) \
+               xdp_rx_meta |= flag;
+XDP_METADATA_KFUNC_xxx
+#undef XDP_METADATA_KFUNC
+
        if (nla_put_u32(rsp, NETDEV_A_DEV_IFINDEX, netdev->ifindex) ||
            nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_FEATURES,
-                             netdev->xdp_features, NETDEV_A_DEV_PAD)) {
+                             netdev->xdp_features, NETDEV_A_DEV_PAD) ||
+           nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_RX_METADATA_FEATURES,
+                             xdp_rx_meta, NETDEV_A_DEV_PAD)) {
                genlmsg_cancel(rsp, hdr);
                return -EINVAL;
        }
index bab563b2f8129988736dfa202c8e9a28e27869f3..df4789ab512d72581915d2a829369a05398434bd 100644 (file)
@@ -741,7 +741,7 @@ __bpf_kfunc int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, u32 *hash,
 __diag_pop();
 
 BTF_SET8_START(xdp_metadata_kfunc_ids)
-#define XDP_METADATA_KFUNC(_, name, __) BTF_ID_FLAGS(func, name, KF_TRUSTED_ARGS)
+#define XDP_METADATA_KFUNC(_, __, name, ___) BTF_ID_FLAGS(func, name, KF_TRUSTED_ARGS)
 XDP_METADATA_KFUNC_xxx
 #undef XDP_METADATA_KFUNC
 BTF_SET8_END(xdp_metadata_kfunc_ids)
@@ -752,7 +752,7 @@ static const struct btf_kfunc_id_set xdp_metadata_kfunc_set = {
 };
 
 BTF_ID_LIST(xdp_metadata_kfunc_ids_unsorted)
-#define XDP_METADATA_KFUNC(name, str, _) BTF_ID(func, str)
+#define XDP_METADATA_KFUNC(name, _, str, __) BTF_ID(func, str)
 XDP_METADATA_KFUNC_xxx
 #undef XDP_METADATA_KFUNC
 
index c1634b95c223ab5b1ea74b4b8e7d32505390012c..2943a151d4f128e1a0cf351a7870bb53bbaebe1c 100644 (file)
@@ -38,11 +38,27 @@ enum netdev_xdp_act {
        NETDEV_XDP_ACT_MASK = 127,
 };
 
+/**
+ * enum netdev_xdp_rx_metadata
+ * @NETDEV_XDP_RX_METADATA_TIMESTAMP: Device is capable of exposing receive HW
+ *   timestamp via bpf_xdp_metadata_rx_timestamp().
+ * @NETDEV_XDP_RX_METADATA_HASH: Device is capable of exposing receive packet
+ *   hash via bpf_xdp_metadata_rx_hash().
+ */
+enum netdev_xdp_rx_metadata {
+       NETDEV_XDP_RX_METADATA_TIMESTAMP = 1,
+       NETDEV_XDP_RX_METADATA_HASH = 2,
+
+       /* private: */
+       NETDEV_XDP_RX_METADATA_MASK = 3,
+};
+
 enum {
        NETDEV_A_DEV_IFINDEX = 1,
        NETDEV_A_DEV_PAD,
        NETDEV_A_DEV_XDP_FEATURES,
        NETDEV_A_DEV_XDP_ZC_MAX_SEGS,
+       NETDEV_A_DEV_XDP_RX_METADATA_FEATURES,
 
        __NETDEV_A_DEV_MAX,
        NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)