106 lines · c
1// SPDX-License-Identifier: GPL-2.02#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 255 bytes or smaller */81 test_xdp_context_error(prog_fd, opts, 0, 256, 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 only94 * one RX queue (index 0). This makes index 1 an invalid rx queue index95 * 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}106