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,
__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);
......
......@@ -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);
}
}
......
......@@ -17,12 +17,36 @@
#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;
};
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