xdp_context_test_run.c (3560B)
1// SPDX-License-Identifier: GPL-2.0 2#include <test_progs.h> 3#include <network_helpers.h> 4#include "test_xdp_context_test_run.skel.h" 5 6void test_xdp_context_error(int prog_fd, struct bpf_test_run_opts opts, 7 __u32 data_meta, __u32 data, __u32 data_end, 8 __u32 ingress_ifindex, __u32 rx_queue_index, 9 __u32 egress_ifindex) 10{ 11 struct xdp_md ctx = { 12 .data = data, 13 .data_end = data_end, 14 .data_meta = data_meta, 15 .ingress_ifindex = ingress_ifindex, 16 .rx_queue_index = rx_queue_index, 17 .egress_ifindex = egress_ifindex, 18 }; 19 int err; 20 21 opts.ctx_in = &ctx; 22 opts.ctx_size_in = sizeof(ctx); 23 err = bpf_prog_test_run_opts(prog_fd, &opts); 24 ASSERT_EQ(errno, EINVAL, "errno-EINVAL"); 25 ASSERT_ERR(err, "bpf_prog_test_run"); 26} 27 28void test_xdp_context_test_run(void) 29{ 30 struct test_xdp_context_test_run *skel = NULL; 31 char data[sizeof(pkt_v4) + sizeof(__u32)]; 32 char bad_ctx[sizeof(struct xdp_md) + 1]; 33 struct xdp_md ctx_in, ctx_out; 34 DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts, 35 .data_in = &data, 36 .data_size_in = sizeof(data), 37 .ctx_out = &ctx_out, 38 .ctx_size_out = sizeof(ctx_out), 39 .repeat = 1, 40 ); 41 int err, prog_fd; 42 43 skel = test_xdp_context_test_run__open_and_load(); 44 if (!ASSERT_OK_PTR(skel, "skel")) 45 return; 46 prog_fd = bpf_program__fd(skel->progs.xdp_context); 47 48 /* Data past the end of the kernel's struct xdp_md must be 0 */ 49 bad_ctx[sizeof(bad_ctx) - 1] = 1; 50 opts.ctx_in = bad_ctx; 51 opts.ctx_size_in = sizeof(bad_ctx); 52 err = bpf_prog_test_run_opts(prog_fd, &opts); 53 ASSERT_EQ(errno, E2BIG, "extradata-errno"); 54 ASSERT_ERR(err, "bpf_prog_test_run(extradata)"); 55 56 *(__u32 *)data = XDP_PASS; 57 *(struct ipv4_packet *)(data + sizeof(__u32)) = pkt_v4; 58 opts.ctx_in = &ctx_in; 59 opts.ctx_size_in = sizeof(ctx_in); 60 memset(&ctx_in, 0, sizeof(ctx_in)); 61 ctx_in.data_meta = 0; 62 ctx_in.data = sizeof(__u32); 63 ctx_in.data_end = ctx_in.data + sizeof(pkt_v4); 64 err = bpf_prog_test_run_opts(prog_fd, &opts); 65 ASSERT_OK(err, "bpf_prog_test_run(valid)"); 66 ASSERT_EQ(opts.retval, XDP_PASS, "valid-retval"); 67 ASSERT_EQ(opts.data_size_out, sizeof(pkt_v4), "valid-datasize"); 68 ASSERT_EQ(opts.ctx_size_out, opts.ctx_size_in, "valid-ctxsize"); 69 ASSERT_EQ(ctx_out.data_meta, 0, "valid-datameta"); 70 ASSERT_EQ(ctx_out.data, 0, "valid-data"); 71 ASSERT_EQ(ctx_out.data_end, sizeof(pkt_v4), "valid-dataend"); 72 73 /* Meta data's size must be a multiple of 4 */ 74 test_xdp_context_error(prog_fd, opts, 0, 1, sizeof(data), 0, 0, 0); 75 76 /* data_meta must reference the start of data */ 77 test_xdp_context_error(prog_fd, opts, 4, sizeof(__u32), sizeof(data), 78 0, 0, 0); 79 80 /* Meta data must be 32 bytes or smaller */ 81 test_xdp_context_error(prog_fd, opts, 0, 36, sizeof(data), 0, 0, 0); 82 83 /* Total size of data must match data_end - data_meta */ 84 test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), 85 sizeof(data) - 1, 0, 0, 0); 86 test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), 87 sizeof(data) + 1, 0, 0, 0); 88 89 /* RX queue cannot be specified without specifying an ingress */ 90 test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), sizeof(data), 91 0, 1, 0); 92 93 /* Interface 1 is always the loopback interface which always has only 94 * one RX queue (index 0). This makes index 1 an invalid rx queue index 95 * for interface 1. 96 */ 97 test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), sizeof(data), 98 1, 1, 0); 99 100 /* The egress cannot be specified */ 101 test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), sizeof(data), 102 0, 0, 1); 103 104 test_xdp_context_test_run__destroy(skel); 105}