|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
| 2 | + |
| 3 | +#include <test_progs.h> |
| 4 | +#include <network_helpers.h> |
| 5 | +#include "test_xdp_pull_data.skel.h" |
| 6 | + |
| 7 | +/* xdp_pull_data_prog will directly read a marker 0xbb stored at buf[1024] |
| 8 | + * so caller expecting XDP_PASS should always pass pull_len no less than 1024 |
| 9 | + */ |
| 10 | +void test_xdp_pull_data_common(struct test_xdp_pull_data *skel, |
| 11 | + int buf_len, int linear_len, |
| 12 | + int pull_len, int retval) |
| 13 | +{ |
| 14 | + LIBBPF_OPTS(bpf_test_run_opts, topts); |
| 15 | + struct xdp_md ctx = {}; |
| 16 | + int prog_fd, err; |
| 17 | + __u8 *buf; |
| 18 | + |
| 19 | + buf = calloc(buf_len, sizeof(__u8)); |
| 20 | + if (!ASSERT_OK_PTR(buf, "calloc buf")) |
| 21 | + return; |
| 22 | + |
| 23 | + buf[1023] = 0xaa; |
| 24 | + buf[1024] = 0xbb; |
| 25 | + buf[1025] = 0xcc; |
| 26 | + |
| 27 | + topts.data_in = buf; |
| 28 | + topts.data_out = buf; |
| 29 | + topts.data_size_in = buf_len; |
| 30 | + topts.data_size_out = buf_len; |
| 31 | + ctx.data_end = linear_len; |
| 32 | + topts.ctx_in = &ctx; |
| 33 | + topts.ctx_out = &ctx; |
| 34 | + topts.ctx_size_in = sizeof(ctx); |
| 35 | + topts.ctx_size_out = sizeof(ctx); |
| 36 | + |
| 37 | + skel->bss->linear_len = linear_len; |
| 38 | + skel->bss->pull_len = pull_len; |
| 39 | + |
| 40 | + prog_fd = bpf_program__fd(skel->progs.xdp_pull_data_prog); |
| 41 | + err = bpf_prog_test_run_opts(prog_fd, &topts); |
| 42 | + ASSERT_OK(err, "bpf_prog_test_run_opts"); |
| 43 | + ASSERT_EQ(topts.retval, retval, "xdp_pull_data_prog retval"); |
| 44 | + |
| 45 | + if (retval == XDP_DROP) |
| 46 | + goto out; |
| 47 | + |
| 48 | + ASSERT_EQ(ctx.data_end, pull_len, "linear data size"); |
| 49 | + ASSERT_EQ(topts.data_size_out, buf_len, "linear + non-linear data size"); |
| 50 | + /* Make sure data around xdp->data_end was not messed up |
| 51 | + * by bpf_xdp_pull_data() */ |
| 52 | + ASSERT_EQ(buf[1023], 0xaa, "buf[1023]"); |
| 53 | + ASSERT_EQ(buf[1024], 0xbb, "buf[1024]"); |
| 54 | + ASSERT_EQ(buf[1025], 0xcc, "buf[1025]"); |
| 55 | +out: |
| 56 | + free(buf); |
| 57 | +} |
| 58 | + |
| 59 | +static void test_xdp_pull_data_basic(void) |
| 60 | +{ |
| 61 | + struct test_xdp_pull_data *skel; |
| 62 | + |
| 63 | + skel = test_xdp_pull_data__open_and_load(); |
| 64 | + if (!ASSERT_OK_PTR(skel, "test_xdp_pull_data__open_and_load")) |
| 65 | + return; |
| 66 | + |
| 67 | + /* linear xdp pkt, pull 0 byte */ |
| 68 | + test_xdp_pull_data_common(skel, 2048, 2048, 2048, XDP_PASS); |
| 69 | + /* multi-buf pkt, pull results in linear xdp pkt */ |
| 70 | + test_xdp_pull_data_common(skel, 2048, 1024, 2048, XDP_PASS); |
| 71 | + /* multi-buf pkt, pull 1 byte to linear data area */ |
| 72 | + test_xdp_pull_data_common(skel, 9000, 1024, 1025, XDP_PASS); |
| 73 | + /* multi-buf pkt, pull 0 byte to linear data area */ |
| 74 | + test_xdp_pull_data_common(skel, 9000, 1025, 1025, XDP_PASS); |
| 75 | + |
| 76 | + /* linear xdp pkt, pull more than total data len */ |
| 77 | + test_xdp_pull_data_common(skel, 2048, 2048, 2049, XDP_DROP); |
| 78 | + /* multi-buf pkt with no space left in linear data area. |
| 79 | + * Since ctx.data_end (4096) > max_data_sz, bpf_prog_test_run_xdp() |
| 80 | + * will fill the whole linear data area and put the reset into a |
| 81 | + * fragment. |
| 82 | + */ |
| 83 | + test_xdp_pull_data_common(skel, 4096, 4096, 4096, XDP_DROP); |
| 84 | + |
| 85 | + test_xdp_pull_data__destroy(skel); |
| 86 | +} |
| 87 | + |
| 88 | +void test_xdp_pull_data(void) |
| 89 | +{ |
| 90 | + if (test__start_subtest("xdp_pull_data")) |
| 91 | + test_xdp_pull_data_basic(); |
| 92 | +} |
0 commit comments