Commit 8e68a4be authored by Larysa Zaremba's avatar Larysa Zaremba Committed by Alexei Starovoitov

selftests/bpf: Add flags and VLAN hint to xdp_hw_metadata

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: default avatarStanislav Fomichev <sdf@google.com>
Signed-off-by: default avatarLarysa Zaremba <larysa.zaremba@intel.com>
Link: https://lore.kernel.org/r/20231205210847.28460-17-larysa.zaremba@intel.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent e71a9fa7
...@@ -20,6 +20,9 @@ extern int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx, ...@@ -20,6 +20,9 @@ extern int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx,
__u64 *timestamp) __ksym; __u64 *timestamp) __ksym;
extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, __u32 *hash, extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, __u32 *hash,
enum xdp_rss_hash_type *rss_type) __ksym; 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") SEC("xdp.frags")
int rx(struct xdp_md *ctx) int rx(struct xdp_md *ctx)
...@@ -84,15 +87,28 @@ int rx(struct xdp_md *ctx) ...@@ -84,15 +87,28 @@ int rx(struct xdp_md *ctx)
return XDP_PASS; return XDP_PASS;
} }
err = bpf_xdp_metadata_rx_timestamp(ctx, &meta->rx_timestamp); meta->hint_valid = 0;
if (!err)
meta->xdp_timestamp = bpf_ktime_get_tai_ns(); meta->xdp_timestamp = bpf_ktime_get_tai_ns();
err = bpf_xdp_metadata_rx_timestamp(ctx, &meta->rx_timestamp);
if (err)
meta->rx_timestamp_err = err;
else else
meta->rx_timestamp = 0; /* Used by AF_XDP as not avail signal */ meta->hint_valid |= XDP_META_FIELD_TS;
err = bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash, &meta->rx_hash_type); err = bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash,
if (err < 0) &meta->rx_hash_type);
meta->rx_hash_err = err; /* Used by AF_XDP as no hash signal */ if (err)
meta->rx_hash_err = err;
else
meta->hint_valid |= XDP_META_FIELD_RSS;
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); __sync_add_and_fetch(&pkts_redir, 1);
return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS); return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS);
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
#include "xsk.h" #include "xsk.h"
#include <error.h> #include <error.h>
#include <linux/kernel.h>
#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/errqueue.h> #include <linux/errqueue.h>
#include <linux/if_link.h> #include <linux/if_link.h>
#include <linux/net_tstamp.h> #include <linux/net_tstamp.h>
...@@ -182,19 +185,31 @@ static void print_tstamp_delta(const char *name, const char *refname, ...@@ -182,19 +185,31 @@ static void print_tstamp_delta(const char *name, const char *refname,
(double)delta / 1000); (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) static void verify_xdp_metadata(void *data, clockid_t clock_id)
{ {
struct xdp_meta *meta; struct xdp_meta *meta;
meta = data - sizeof(*meta); meta = data - sizeof(*meta);
if (meta->rx_hash_err < 0) if (meta->hint_valid & XDP_META_FIELD_RSS)
printf("No rx_hash err=%d\n", meta->rx_hash_err);
else
printf("rx_hash: 0x%X with RSS type:0x%X\n", printf("rx_hash: 0x%X with RSS type:0x%X\n",
meta->rx_hash, meta->rx_hash_type); 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); __u64 ref_tstamp = gettime(clock_id);
/* store received timestamps to calculate a delta at tx */ /* store received timestamps to calculate a delta at tx */
...@@ -206,7 +221,16 @@ static void verify_xdp_metadata(void *data, clockid_t clock_id) ...@@ -206,7 +221,16 @@ static void verify_xdp_metadata(void *data, clockid_t clock_id)
print_tstamp_delta("XDP RX-time", "User RX-time", print_tstamp_delta("XDP RX-time", "User RX-time",
meta->xdp_timestamp, ref_tstamp); meta->xdp_timestamp, ref_tstamp);
} else { } 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);
} }
} }
......
...@@ -17,12 +17,36 @@ ...@@ -17,12 +17,36 @@
#define ETH_P_8021AD 0x88A8 #define ETH_P_8021AD 0x88A8
#endif #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 { struct xdp_meta {
union {
__u64 rx_timestamp; __u64 rx_timestamp;
__s32 rx_timestamp_err;
};
__u64 xdp_timestamp; __u64 xdp_timestamp;
__u32 rx_hash; __u32 rx_hash;
union { union {
__u32 rx_hash_type; __u32 rx_hash_type;
__s32 rx_hash_err; __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;
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment