1 // SPDX-License-Identifier: GPL-2.0 2 #include <test_progs.h> 3 #include <network_helpers.h> 4 5 static void test_xdp_adjust_tail_shrink(void) 6 { 7 const char *file = "./test_xdp_adjust_tail_shrink.o"; 8 __u32 duration, retval, size, expect_sz; 9 struct bpf_object *obj; 10 int err, prog_fd; 11 char buf[128]; 12 13 err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); 14 if (CHECK_FAIL(err)) 15 return; 16 17 err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), 18 buf, &size, &retval, &duration); 19 20 CHECK(err || retval != XDP_DROP, 21 "ipv4", "err %d errno %d retval %d size %d\n", 22 err, errno, retval, size); 23 24 expect_sz = sizeof(pkt_v6) - 20; /* Test shrink with 20 bytes */ 25 err = bpf_prog_test_run(prog_fd, 1, &pkt_v6, sizeof(pkt_v6), 26 buf, &size, &retval, &duration); 27 CHECK(err || retval != XDP_TX || size != expect_sz, 28 "ipv6", "err %d errno %d retval %d size %d expect-size %d\n", 29 err, errno, retval, size, expect_sz); 30 bpf_object__close(obj); 31 } 32 33 static void test_xdp_adjust_tail_grow(void) 34 { 35 const char *file = "./test_xdp_adjust_tail_grow.o"; 36 struct bpf_object *obj; 37 char buf[4096]; /* avoid segfault: large buf to hold grow results */ 38 __u32 duration, retval, size, expect_sz; 39 int err, prog_fd; 40 41 err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); 42 if (CHECK_FAIL(err)) 43 return; 44 45 err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), 46 buf, &size, &retval, &duration); 47 CHECK(err || retval != XDP_DROP, 48 "ipv4", "err %d errno %d retval %d size %d\n", 49 err, errno, retval, size); 50 51 expect_sz = sizeof(pkt_v6) + 40; /* Test grow with 40 bytes */ 52 err = bpf_prog_test_run(prog_fd, 1, &pkt_v6, sizeof(pkt_v6) /* 74 */, 53 buf, &size, &retval, &duration); 54 CHECK(err || retval != XDP_TX || size != expect_sz, 55 "ipv6", "err %d errno %d retval %d size %d expect-size %d\n", 56 err, errno, retval, size, expect_sz); 57 58 bpf_object__close(obj); 59 } 60 61 static void test_xdp_adjust_tail_grow2(void) 62 { 63 const char *file = "./test_xdp_adjust_tail_grow.o"; 64 char buf[4096]; /* avoid segfault: large buf to hold grow results */ 65 int tailroom = 320; /* SKB_DATA_ALIGN(sizeof(struct skb_shared_info))*/; 66 struct bpf_object *obj; 67 int err, cnt, i; 68 int max_grow; 69 70 struct bpf_prog_test_run_attr tattr = { 71 .repeat = 1, 72 .data_in = &buf, 73 .data_out = &buf, 74 .data_size_in = 0, /* Per test */ 75 .data_size_out = 0, /* Per test */ 76 }; 77 78 err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &tattr.prog_fd); 79 if (CHECK_ATTR(err, "load", "err %d errno %d\n", err, errno)) 80 return; 81 82 /* Test case-64 */ 83 memset(buf, 1, sizeof(buf)); 84 tattr.data_size_in = 64; /* Determine test case via pkt size */ 85 tattr.data_size_out = 128; /* Limit copy_size */ 86 /* Kernel side alloc packet memory area that is zero init */ 87 err = bpf_prog_test_run_xattr(&tattr); 88 89 CHECK_ATTR(errno != ENOSPC /* Due limit copy_size in bpf_test_finish */ 90 || tattr.retval != XDP_TX 91 || tattr.data_size_out != 192, /* Expected grow size */ 92 "case-64", 93 "err %d errno %d retval %d size %d\n", 94 err, errno, tattr.retval, tattr.data_size_out); 95 96 /* Extra checks for data contents */ 97 CHECK_ATTR(tattr.data_size_out != 192 98 || buf[0] != 1 || buf[63] != 1 /* 0-63 memset to 1 */ 99 || buf[64] != 0 || buf[127] != 0 /* 64-127 memset to 0 */ 100 || buf[128] != 1 || buf[191] != 1, /*128-191 memset to 1 */ 101 "case-64-data", 102 "err %d errno %d retval %d size %d\n", 103 err, errno, tattr.retval, tattr.data_size_out); 104 105 /* Test case-128 */ 106 memset(buf, 2, sizeof(buf)); 107 tattr.data_size_in = 128; /* Determine test case via pkt size */ 108 tattr.data_size_out = sizeof(buf); /* Copy everything */ 109 err = bpf_prog_test_run_xattr(&tattr); 110 111 max_grow = 4096 - XDP_PACKET_HEADROOM - tailroom; /* 3520 */ 112 CHECK_ATTR(err 113 || tattr.retval != XDP_TX 114 || tattr.data_size_out != max_grow,/* Expect max grow size */ 115 "case-128", 116 "err %d errno %d retval %d size %d expect-size %d\n", 117 err, errno, tattr.retval, tattr.data_size_out, max_grow); 118 119 /* Extra checks for data content: Count grow size, will contain zeros */ 120 for (i = 0, cnt = 0; i < sizeof(buf); i++) { 121 if (buf[i] == 0) 122 cnt++; 123 } 124 CHECK_ATTR((cnt != (max_grow - tattr.data_size_in)) /* Grow increase */ 125 || tattr.data_size_out != max_grow, /* Total grow size */ 126 "case-128-data", 127 "err %d errno %d retval %d size %d grow-size %d\n", 128 err, errno, tattr.retval, tattr.data_size_out, cnt); 129 130 bpf_object__close(obj); 131 } 132 133 void test_xdp_adjust_tail(void) 134 { 135 if (test__start_subtest("xdp_adjust_tail_shrink")) 136 test_xdp_adjust_tail_shrink(); 137 if (test__start_subtest("xdp_adjust_tail_grow")) 138 test_xdp_adjust_tail_grow(); 139 if (test__start_subtest("xdp_adjust_tail_grow2")) 140 test_xdp_adjust_tail_grow2(); 141 } 142