selftests/bpf: Add flags and VLAN hint to xdp_hw_metadata
authorLarysa Zaremba <larysa.zaremba@intel.com>
Tue, 5 Dec 2023 21:08:45 +0000 (22:08 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 14 Dec 2023 00:16:41 +0000 (16:16 -0800)
Add VLAN hint to the xdp_hw_metadata program.

Also, to make metadata layout more straightforward, add flags field
to pass information about validity of every separate hint separately.

Acked-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Larysa Zaremba <larysa.zaremba@intel.com>
Link: https://lore.kernel.org/r/20231205210847.28460-17-larysa.zaremba@intel.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/progs/xdp_hw_metadata.c
tools/testing/selftests/bpf/xdp_hw_metadata.c
tools/testing/selftests/bpf/xdp_metadata.h

index 8767d919c881b59228a3a9d93fd5bac06e6c8f64..330ece2eabdb454da2bb2cbd297d2b2dd6efddc0 100644 (file)
@@ -20,6 +20,9 @@ extern int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx,
                                         __u64 *timestamp) __ksym;
 extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, __u32 *hash,
                                    enum xdp_rss_hash_type *rss_type) __ksym;
+extern int bpf_xdp_metadata_rx_vlan_tag(const struct xdp_md *ctx,
+                                       __be16 *vlan_proto,
+                                       __u16 *vlan_tci) __ksym;
 
 SEC("xdp.frags")
 int rx(struct xdp_md *ctx)
@@ -84,15 +87,28 @@ int rx(struct xdp_md *ctx)
                return XDP_PASS;
        }
 
+       meta->hint_valid = 0;
+
+       meta->xdp_timestamp = bpf_ktime_get_tai_ns();
        err = bpf_xdp_metadata_rx_timestamp(ctx, &meta->rx_timestamp);
-       if (!err)
-               meta->xdp_timestamp = bpf_ktime_get_tai_ns();
+       if (err)
+               meta->rx_timestamp_err = err;
+       else
+               meta->hint_valid |= XDP_META_FIELD_TS;
+
+       err = bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash,
+                                      &meta->rx_hash_type);
+       if (err)
+               meta->rx_hash_err = err;
        else
-               meta->rx_timestamp = 0; /* Used by AF_XDP as not avail signal */
+               meta->hint_valid |= XDP_META_FIELD_RSS;
 
-       err = bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash, &meta->rx_hash_type);
-       if (err < 0)
-               meta->rx_hash_err = err; /* Used by AF_XDP as no hash signal */
+       err = bpf_xdp_metadata_rx_vlan_tag(ctx, &meta->rx_vlan_proto,
+                                          &meta->rx_vlan_tci);
+       if (err)
+               meta->rx_vlan_tag_err = err;
+       else
+               meta->hint_valid |= XDP_META_FIELD_VLAN_TAG;
 
        __sync_add_and_fetch(&pkts_redir, 1);
        return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS);
index c69c08933fdd397e918d4927495efe7e1e6b6f2b..878d68db0325673c0fa16ccefe583ea283903f88 100644 (file)
@@ -21,6 +21,9 @@
 #include "xsk.h"
 
 #include <error.h>
+#include <linux/kernel.h>
+#include <linux/bits.h>
+#include <linux/bitfield.h>
 #include <linux/errqueue.h>
 #include <linux/if_link.h>
 #include <linux/net_tstamp.h>
@@ -182,19 +185,31 @@ static void print_tstamp_delta(const char *name, const char *refname,
               (double)delta / 1000);
 }
 
+#define VLAN_PRIO_MASK         GENMASK(15, 13) /* Priority Code Point */
+#define VLAN_DEI_MASK          GENMASK(12, 12) /* Drop Eligible Indicator */
+#define VLAN_VID_MASK          GENMASK(11, 0)  /* VLAN Identifier */
+static void print_vlan_tci(__u16 tag)
+{
+       __u16 vlan_id = FIELD_GET(VLAN_VID_MASK, tag);
+       __u8 pcp = FIELD_GET(VLAN_PRIO_MASK, tag);
+       bool dei = FIELD_GET(VLAN_DEI_MASK, tag);
+
+       printf("PCP=%u, DEI=%d, VID=0x%X\n", pcp, dei, vlan_id);
+}
+
 static void verify_xdp_metadata(void *data, clockid_t clock_id)
 {
        struct xdp_meta *meta;
 
        meta = data - sizeof(*meta);
 
-       if (meta->rx_hash_err < 0)
-               printf("No rx_hash err=%d\n", meta->rx_hash_err);
-       else
+       if (meta->hint_valid & XDP_META_FIELD_RSS)
                printf("rx_hash: 0x%X with RSS type:0x%X\n",
                       meta->rx_hash, meta->rx_hash_type);
+       else
+               printf("No rx_hash, err=%d\n", meta->rx_hash_err);
 
-       if (meta->rx_timestamp) {
+       if (meta->hint_valid & XDP_META_FIELD_TS) {
                __u64 ref_tstamp = gettime(clock_id);
 
                /* store received timestamps to calculate a delta at tx */
@@ -206,7 +221,16 @@ static void verify_xdp_metadata(void *data, clockid_t clock_id)
                print_tstamp_delta("XDP RX-time", "User RX-time",
                                   meta->xdp_timestamp, ref_tstamp);
        } else {
-               printf("No rx_timestamp\n");
+               printf("No rx_timestamp, err=%d\n", meta->rx_timestamp_err);
+       }
+
+       if (meta->hint_valid & XDP_META_FIELD_VLAN_TAG) {
+               printf("rx_vlan_proto: 0x%X\n", ntohs(meta->rx_vlan_proto));
+               printf("rx_vlan_tci: ");
+               print_vlan_tci(meta->rx_vlan_tci);
+       } else {
+               printf("No rx_vlan_tci or rx_vlan_proto, err=%d\n",
+                      meta->rx_vlan_tag_err);
        }
 }
 
index 6664893c2c77db228a8e5c91f28d35a9404a63c1..87318ad1117a1d677af121f11778178532e2a562 100644 (file)
 #define ETH_P_8021AD 0x88A8
 #endif
 
+#ifndef BIT
+#define BIT(nr)                        (1 << (nr))
+#endif
+
+/* Non-existent checksum status */
+#define XDP_CHECKSUM_MAGIC     BIT(2)
+
+enum xdp_meta_field {
+       XDP_META_FIELD_TS       = BIT(0),
+       XDP_META_FIELD_RSS      = BIT(1),
+       XDP_META_FIELD_VLAN_TAG = BIT(2),
+};
+
 struct xdp_meta {
-       __u64 rx_timestamp;
+       union {
+               __u64 rx_timestamp;
+               __s32 rx_timestamp_err;
+       };
        __u64 xdp_timestamp;
        __u32 rx_hash;
        union {
                __u32 rx_hash_type;
                __s32 rx_hash_err;
        };
+       union {
+               struct {
+                       __be16 rx_vlan_proto;
+                       __u16 rx_vlan_tci;
+               };
+               __s32 rx_vlan_tag_err;
+       };
+       enum xdp_meta_field hint_valid;
 };