Skip to content

Commit 9a321fd

Browse files
tvyavahaAlexei Starovoitov
authored andcommitted
selftests/xsk: add xdp populate metadata test
Add a new test in copy-mode for testing the copying of metadata from the buffer in kernel-space to user-space. This is accomplished by adding a new XDP program and using the bss map to store a counter that is written to the metadata field. This counter is incremented for every packet so that the number becomes unique and should be the same as the payload. It is store in the bss so the value can be reset between runs. The XDP program populates the metadata and the userspace program checks the value stored in the metadata field against the payload using the new is_metadata_correct() function. To turn this verification on or off, add a new parameter (use_metadata) to the ifobject structure. Signed-off-by: Tushar Vyavahare <[email protected]> Reviewed-by: Maciej Fijalkowski <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 6a9f5cd commit 9a321fd

File tree

4 files changed

+77
-1
lines changed

4 files changed

+77
-1
lines changed

tools/testing/selftests/bpf/progs/xsk_xdp_progs.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <linux/bpf.h>
55
#include <bpf/bpf_helpers.h>
6+
#include "xsk_xdp_metadata.h"
67

78
struct {
89
__uint(type, BPF_MAP_TYPE_XSKMAP);
@@ -12,6 +13,7 @@ struct {
1213
} xsk SEC(".maps");
1314

1415
static unsigned int idx;
16+
int count = 0;
1517

1618
SEC("xdp") int xsk_def_prog(struct xdp_md *xdp)
1719
{
@@ -27,4 +29,27 @@ SEC("xdp") int xsk_xdp_drop(struct xdp_md *xdp)
2729
return bpf_redirect_map(&xsk, 0, XDP_DROP);
2830
}
2931

32+
SEC("xdp") int xsk_xdp_populate_metadata(struct xdp_md *xdp)
33+
{
34+
void *data, *data_meta;
35+
struct xdp_info *meta;
36+
int err;
37+
38+
/* Reserve enough for all custom metadata. */
39+
err = bpf_xdp_adjust_meta(xdp, -(int)sizeof(struct xdp_info));
40+
if (err)
41+
return XDP_DROP;
42+
43+
data = (void *)(long)xdp->data;
44+
data_meta = (void *)(long)xdp->data_meta;
45+
46+
if (data_meta + sizeof(struct xdp_info) > data)
47+
return XDP_DROP;
48+
49+
meta = data_meta;
50+
meta->count = count++;
51+
52+
return bpf_redirect_map(&xsk, 0, XDP_DROP);
53+
}
54+
3055
char _license[] SEC("license") = "GPL";
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
3+
struct xdp_info {
4+
__u64 count;
5+
} __attribute__((aligned(32)));

tools/testing/selftests/bpf/xskxceiver.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
#include <bpf/bpf.h>
104104
#include <linux/filter.h>
105105
#include "../kselftest.h"
106+
#include "xsk_xdp_metadata.h"
106107

107108
static const char *MAC1 = "\x00\x0A\x56\x9E\xEE\x62";
108109
static const char *MAC2 = "\x00\x0A\x56\x9E\xEE\x61";
@@ -464,6 +465,7 @@ static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
464465
ifobj->use_fill_ring = true;
465466
ifobj->release_rx = true;
466467
ifobj->validation_func = NULL;
468+
ifobj->use_metadata = false;
467469

468470
if (i == 0) {
469471
ifobj->rx_on = false;
@@ -798,6 +800,20 @@ static bool is_offset_correct(struct xsk_umem_info *umem, struct pkt_stream *pkt
798800
return false;
799801
}
800802

803+
static bool is_metadata_correct(struct pkt *pkt, void *buffer, u64 addr)
804+
{
805+
void *data = xsk_umem__get_data(buffer, addr);
806+
struct xdp_info *meta = data - sizeof(struct xdp_info);
807+
808+
if (meta->count != pkt->payload) {
809+
ksft_print_msg("[%s] expected meta_count [%d], got meta_count [%d]\n",
810+
__func__, pkt->payload, meta->count);
811+
return false;
812+
}
813+
814+
return true;
815+
}
816+
801817
static bool is_pkt_valid(struct pkt *pkt, void *buffer, u64 addr, u32 len)
802818
{
803819
void *data = xsk_umem__get_data(buffer, addr);
@@ -959,7 +975,8 @@ static int receive_pkts(struct test_spec *test, struct pollfd *fds)
959975
addr = xsk_umem__add_offset_to_addr(addr);
960976

961977
if (!is_pkt_valid(pkt, umem->buffer, addr, desc->len) ||
962-
!is_offset_correct(umem, pkt_stream, addr, pkt->addr))
978+
!is_offset_correct(umem, pkt_stream, addr, pkt->addr) ||
979+
(ifobj->use_metadata && !is_metadata_correct(pkt, umem->buffer, addr)))
963980
return TEST_FAILURE;
964981

965982
if (ifobj->use_fill_ring)
@@ -1686,6 +1703,30 @@ static void testapp_xdp_drop(struct test_spec *test)
16861703
testapp_validate_traffic(test);
16871704
}
16881705

1706+
static void testapp_xdp_metadata_count(struct test_spec *test)
1707+
{
1708+
struct xsk_xdp_progs *skel_rx = test->ifobj_rx->xdp_progs;
1709+
struct xsk_xdp_progs *skel_tx = test->ifobj_tx->xdp_progs;
1710+
struct bpf_map *data_map;
1711+
int count = 0;
1712+
int key = 0;
1713+
1714+
test_spec_set_name(test, "XDP_METADATA_COUNT");
1715+
test_spec_set_xdp_prog(test, skel_rx->progs.xsk_xdp_populate_metadata,
1716+
skel_tx->progs.xsk_xdp_populate_metadata,
1717+
skel_rx->maps.xsk, skel_tx->maps.xsk);
1718+
test->ifobj_rx->use_metadata = true;
1719+
1720+
data_map = bpf_object__find_map_by_name(skel_rx->obj, "xsk_xdp_.bss");
1721+
if (!data_map || !bpf_map__is_internal(data_map))
1722+
exit_with_error(ENOMEM);
1723+
1724+
if (bpf_map_update_elem(bpf_map__fd(data_map), &key, &count, BPF_ANY))
1725+
exit_with_error(errno);
1726+
1727+
testapp_validate_traffic(test);
1728+
}
1729+
16891730
static void testapp_poll_txq_tmout(struct test_spec *test)
16901731
{
16911732
test_spec_set_name(test, "POLL_TXQ_FULL");
@@ -1835,6 +1876,9 @@ static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_
18351876
case TEST_TYPE_XDP_DROP_HALF:
18361877
testapp_xdp_drop(test);
18371878
break;
1879+
case TEST_TYPE_XDP_METADATA_COUNT:
1880+
testapp_xdp_metadata_count(test);
1881+
break;
18381882
default:
18391883
break;
18401884
}

tools/testing/selftests/bpf/xskxceiver.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ enum test_type {
8888
TEST_TYPE_STATS_FILL_EMPTY,
8989
TEST_TYPE_BPF_RES,
9090
TEST_TYPE_XDP_DROP_HALF,
91+
TEST_TYPE_XDP_METADATA_COUNT,
9192
TEST_TYPE_MAX
9293
};
9394

@@ -158,6 +159,7 @@ struct ifobject {
158159
bool use_fill_ring;
159160
bool release_rx;
160161
bool shared_umem;
162+
bool use_metadata;
161163
u8 dst_mac[ETH_ALEN];
162164
u8 src_mac[ETH_ALEN];
163165
};

0 commit comments

Comments
 (0)