Skip to content

Commit

Permalink
bpf: selftests: update xdp_adjust_tail selftest to include xdp frags
Browse files Browse the repository at this point in the history
This change adds test cases for the xdp frags scenarios when shrinking
and growing.

Acked-by: Toke Hoiland-Jorgensen <toke@redhat.com>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
Link: https://lore.kernel.org/r/d2e6a0ebc52db6f89e62b9befe045032e5e0a5fe.1642758637.git.lorenzo@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
  • Loading branch information
Eelco Chaudron authored and Alexei Starovoitov committed Jan 21, 2022
1 parent 7855e0d commit 1102210
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 7 deletions.
125 changes: 125 additions & 0 deletions tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,127 @@ static void test_xdp_adjust_tail_grow2(void)
bpf_object__close(obj);
}

void test_xdp_adjust_frags_tail_shrink(void)
{
const char *file = "./test_xdp_adjust_tail_shrink.o";
__u32 duration, retval, size, exp_size;
struct bpf_program *prog;
struct bpf_object *obj;
int err, prog_fd;
__u8 *buf;

/* For the individual test cases, the first byte in the packet
* indicates which test will be run.
*/
obj = bpf_object__open(file);
if (libbpf_get_error(obj))
return;

prog = bpf_object__next_program(obj, NULL);
if (bpf_object__load(obj))
return;

prog_fd = bpf_program__fd(prog);

buf = malloc(9000);
if (!ASSERT_OK_PTR(buf, "alloc buf 9Kb"))
goto out;

memset(buf, 0, 9000);

/* Test case removing 10 bytes from last frag, NOT freeing it */
exp_size = 8990; /* 9000 - 10 */
err = bpf_prog_test_run(prog_fd, 1, buf, 9000,
buf, &size, &retval, &duration);

ASSERT_OK(err, "9Kb-10b");
ASSERT_EQ(retval, XDP_TX, "9Kb-10b retval");
ASSERT_EQ(size, exp_size, "9Kb-10b size");

/* Test case removing one of two pages, assuming 4K pages */
buf[0] = 1;
exp_size = 4900; /* 9000 - 4100 */
err = bpf_prog_test_run(prog_fd, 1, buf, 9000,
buf, &size, &retval, &duration);

ASSERT_OK(err, "9Kb-4Kb");
ASSERT_EQ(retval, XDP_TX, "9Kb-4Kb retval");
ASSERT_EQ(size, exp_size, "9Kb-4Kb size");

/* Test case removing two pages resulting in a linear xdp_buff */
buf[0] = 2;
exp_size = 800; /* 9000 - 8200 */
err = bpf_prog_test_run(prog_fd, 1, buf, 9000,
buf, &size, &retval, &duration);

ASSERT_OK(err, "9Kb-9Kb");
ASSERT_EQ(retval, XDP_TX, "9Kb-9Kb retval");
ASSERT_EQ(size, exp_size, "9Kb-9Kb size");

free(buf);
out:
bpf_object__close(obj);
}

void test_xdp_adjust_frags_tail_grow(void)
{
const char *file = "./test_xdp_adjust_tail_grow.o";
__u32 duration, retval, size, exp_size;
struct bpf_program *prog;
struct bpf_object *obj;
int err, i, prog_fd;
__u8 *buf;

obj = bpf_object__open(file);
if (libbpf_get_error(obj))
return;

prog = bpf_object__next_program(obj, NULL);
if (bpf_object__load(obj))
return;

prog_fd = bpf_program__fd(prog);

buf = malloc(16384);
if (!ASSERT_OK_PTR(buf, "alloc buf 16Kb"))
goto out;

/* Test case add 10 bytes to last frag */
memset(buf, 1, 16384);
size = 9000;
exp_size = size + 10;
err = bpf_prog_test_run(prog_fd, 1, buf, size,
buf, &size, &retval, &duration);

ASSERT_OK(err, "9Kb+10b");
ASSERT_EQ(retval, XDP_TX, "9Kb+10b retval");
ASSERT_EQ(size, exp_size, "9Kb+10b size");

for (i = 0; i < 9000; i++)
ASSERT_EQ(buf[i], 1, "9Kb+10b-old");

for (i = 9000; i < 9010; i++)
ASSERT_EQ(buf[i], 0, "9Kb+10b-new");

for (i = 9010; i < 16384; i++)
ASSERT_EQ(buf[i], 1, "9Kb+10b-untouched");

/* Test a too large grow */
memset(buf, 1, 16384);
size = 9001;
exp_size = size;
err = bpf_prog_test_run(prog_fd, 1, buf, size,
buf, &size, &retval, &duration);

ASSERT_OK(err, "9Kb+10b");
ASSERT_EQ(retval, XDP_DROP, "9Kb+10b retval");
ASSERT_EQ(size, exp_size, "9Kb+10b size");

free(buf);
out:
bpf_object__close(obj);
}

void test_xdp_adjust_tail(void)
{
if (test__start_subtest("xdp_adjust_tail_shrink"))
Expand All @@ -126,4 +247,8 @@ void test_xdp_adjust_tail(void)
test_xdp_adjust_tail_grow();
if (test__start_subtest("xdp_adjust_tail_grow2"))
test_xdp_adjust_tail_grow2();
if (test__start_subtest("xdp_adjust_frags_tail_shrink"))
test_xdp_adjust_frags_tail_shrink();
if (test__start_subtest("xdp_adjust_frags_tail_grow"))
test_xdp_adjust_frags_tail_grow();
}
10 changes: 7 additions & 3 deletions tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp)
{
void *data_end = (void *)(long)xdp->data_end;
void *data = (void *)(long)xdp->data;
unsigned int data_len;
int data_len = bpf_xdp_get_buff_len(xdp);
int offset = 0;

/* Data length determine test case */
data_len = data_end - data;

if (data_len == 54) { /* sizeof(pkt_v4) */
offset = 4096; /* test too large offset */
Expand All @@ -20,7 +19,12 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp)
} else if (data_len == 64) {
offset = 128;
} else if (data_len == 128) {
offset = 4096 - 256 - 320 - data_len; /* Max tail grow 3520 */
/* Max tail grow 3520 */
offset = 4096 - 256 - 320 - data_len;
} else if (data_len == 9000) {
offset = 10;
} else if (data_len == 9001) {
offset = 4096;
} else {
return XDP_ABORTED; /* No matching test */
}
Expand Down
32 changes: 28 additions & 4 deletions tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_shrink.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,38 @@
SEC("xdp")
int _xdp_adjust_tail_shrink(struct xdp_md *xdp)
{
void *data_end = (void *)(long)xdp->data_end;
void *data = (void *)(long)xdp->data;
__u8 *data_end = (void *)(long)xdp->data_end;
__u8 *data = (void *)(long)xdp->data;
int offset = 0;

if (data_end - data == 54) /* sizeof(pkt_v4) */
switch (bpf_xdp_get_buff_len(xdp)) {
case 54:
/* sizeof(pkt_v4) */
offset = 256; /* shrink too much */
else
break;
case 9000:
/* non-linear buff test cases */
if (data + 1 > data_end)
return XDP_DROP;

switch (data[0]) {
case 0:
offset = 10;
break;
case 1:
offset = 4100;
break;
case 2:
offset = 8200;
break;
default:
return XDP_DROP;
}
break;
default:
offset = 20;
break;
}
if (bpf_xdp_adjust_tail(xdp, 0 - offset))
return XDP_DROP;
return XDP_TX;
Expand Down

0 comments on commit 1102210

Please sign in to comment.