Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <test_progs.h>
0003 #include <network_helpers.h>
0004 
0005 static void test_xdp_adjust_tail_shrink(void)
0006 {
0007     const char *file = "./test_xdp_adjust_tail_shrink.o";
0008     __u32 expect_sz;
0009     struct bpf_object *obj;
0010     int err, prog_fd;
0011     char buf[128];
0012     LIBBPF_OPTS(bpf_test_run_opts, topts,
0013         .data_in = &pkt_v4,
0014         .data_size_in = sizeof(pkt_v4),
0015         .data_out = buf,
0016         .data_size_out = sizeof(buf),
0017         .repeat = 1,
0018     );
0019 
0020     err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
0021     if (ASSERT_OK(err, "test_xdp_adjust_tail_shrink"))
0022         return;
0023 
0024     err = bpf_prog_test_run_opts(prog_fd, &topts);
0025     ASSERT_OK(err, "ipv4");
0026     ASSERT_EQ(topts.retval, XDP_DROP, "ipv4 retval");
0027 
0028     expect_sz = sizeof(pkt_v6) - 20;  /* Test shrink with 20 bytes */
0029     topts.data_in = &pkt_v6;
0030     topts.data_size_in = sizeof(pkt_v6);
0031     topts.data_size_out = sizeof(buf);
0032     err = bpf_prog_test_run_opts(prog_fd, &topts);
0033     ASSERT_OK(err, "ipv6");
0034     ASSERT_EQ(topts.retval, XDP_TX, "ipv6 retval");
0035     ASSERT_EQ(topts.data_size_out, expect_sz, "ipv6 size");
0036 
0037     bpf_object__close(obj);
0038 }
0039 
0040 static void test_xdp_adjust_tail_grow(void)
0041 {
0042     const char *file = "./test_xdp_adjust_tail_grow.o";
0043     struct bpf_object *obj;
0044     char buf[4096]; /* avoid segfault: large buf to hold grow results */
0045     __u32 expect_sz;
0046     int err, prog_fd;
0047     LIBBPF_OPTS(bpf_test_run_opts, topts,
0048         .data_in = &pkt_v4,
0049         .data_size_in = sizeof(pkt_v4),
0050         .data_out = buf,
0051         .data_size_out = sizeof(buf),
0052         .repeat = 1,
0053     );
0054 
0055     err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
0056     if (ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
0057         return;
0058 
0059     err = bpf_prog_test_run_opts(prog_fd, &topts);
0060     ASSERT_OK(err, "ipv4");
0061     ASSERT_EQ(topts.retval, XDP_DROP, "ipv4 retval");
0062 
0063     expect_sz = sizeof(pkt_v6) + 40; /* Test grow with 40 bytes */
0064     topts.data_in = &pkt_v6;
0065     topts.data_size_in = sizeof(pkt_v6);
0066     err = bpf_prog_test_run_opts(prog_fd, &topts);
0067     ASSERT_OK(err, "ipv6");
0068     ASSERT_EQ(topts.retval, XDP_TX, "ipv6 retval");
0069     ASSERT_EQ(topts.data_size_out, expect_sz, "ipv6 size");
0070 
0071     bpf_object__close(obj);
0072 }
0073 
0074 static void test_xdp_adjust_tail_grow2(void)
0075 {
0076     const char *file = "./test_xdp_adjust_tail_grow.o";
0077     char buf[4096]; /* avoid segfault: large buf to hold grow results */
0078     int tailroom = 320; /* SKB_DATA_ALIGN(sizeof(struct skb_shared_info))*/;
0079     struct bpf_object *obj;
0080     int err, cnt, i;
0081     int max_grow, prog_fd;
0082 
0083     LIBBPF_OPTS(bpf_test_run_opts, tattr,
0084         .repeat     = 1,
0085         .data_in    = &buf,
0086         .data_out   = &buf,
0087         .data_size_in   = 0, /* Per test */
0088         .data_size_out  = 0, /* Per test */
0089     );
0090 
0091     err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
0092     if (ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
0093         return;
0094 
0095     /* Test case-64 */
0096     memset(buf, 1, sizeof(buf));
0097     tattr.data_size_in  =  64; /* Determine test case via pkt size */
0098     tattr.data_size_out = 128; /* Limit copy_size */
0099     /* Kernel side alloc packet memory area that is zero init */
0100     err = bpf_prog_test_run_opts(prog_fd, &tattr);
0101 
0102     ASSERT_EQ(errno, ENOSPC, "case-64 errno"); /* Due limit copy_size in bpf_test_finish */
0103     ASSERT_EQ(tattr.retval, XDP_TX, "case-64 retval");
0104     ASSERT_EQ(tattr.data_size_out, 192, "case-64 data_size_out"); /* Expected grow size */
0105 
0106     /* Extra checks for data contents */
0107     ASSERT_EQ(buf[0], 1, "case-64-data buf[0]"); /*  0-63  memset to 1 */
0108     ASSERT_EQ(buf[63], 1, "case-64-data buf[63]");
0109     ASSERT_EQ(buf[64], 0, "case-64-data buf[64]"); /* 64-127 memset to 0 */
0110     ASSERT_EQ(buf[127], 0, "case-64-data buf[127]");
0111     ASSERT_EQ(buf[128], 1, "case-64-data buf[128]"); /* 128-191 memset to 1 */
0112     ASSERT_EQ(buf[191], 1, "case-64-data buf[191]");
0113 
0114     /* Test case-128 */
0115     memset(buf, 2, sizeof(buf));
0116     tattr.data_size_in  = 128; /* Determine test case via pkt size */
0117     tattr.data_size_out = sizeof(buf);   /* Copy everything */
0118     err = bpf_prog_test_run_opts(prog_fd, &tattr);
0119 
0120     max_grow = 4096 - XDP_PACKET_HEADROOM - tailroom; /* 3520 */
0121     ASSERT_OK(err, "case-128");
0122     ASSERT_EQ(tattr.retval, XDP_TX, "case-128 retval");
0123     ASSERT_EQ(tattr.data_size_out, max_grow, "case-128 data_size_out"); /* Expect max grow */
0124 
0125     /* Extra checks for data content: Count grow size, will contain zeros */
0126     for (i = 0, cnt = 0; i < sizeof(buf); i++) {
0127         if (buf[i] == 0)
0128             cnt++;
0129     }
0130     ASSERT_EQ(cnt, max_grow - tattr.data_size_in, "case-128-data cnt"); /* Grow increase */
0131     ASSERT_EQ(tattr.data_size_out, max_grow, "case-128-data data_size_out"); /* Total grow */
0132 
0133     bpf_object__close(obj);
0134 }
0135 
0136 static void test_xdp_adjust_frags_tail_shrink(void)
0137 {
0138     const char *file = "./test_xdp_adjust_tail_shrink.o";
0139     __u32 exp_size;
0140     struct bpf_program *prog;
0141     struct bpf_object *obj;
0142     int err, prog_fd;
0143     __u8 *buf;
0144     LIBBPF_OPTS(bpf_test_run_opts, topts);
0145 
0146     /* For the individual test cases, the first byte in the packet
0147      * indicates which test will be run.
0148      */
0149     obj = bpf_object__open(file);
0150     if (libbpf_get_error(obj))
0151         return;
0152 
0153     prog = bpf_object__next_program(obj, NULL);
0154     if (bpf_object__load(obj))
0155         return;
0156 
0157     prog_fd = bpf_program__fd(prog);
0158 
0159     buf = malloc(9000);
0160     if (!ASSERT_OK_PTR(buf, "alloc buf 9Kb"))
0161         goto out;
0162 
0163     memset(buf, 0, 9000);
0164 
0165     /* Test case removing 10 bytes from last frag, NOT freeing it */
0166     exp_size = 8990; /* 9000 - 10 */
0167     topts.data_in = buf;
0168     topts.data_out = buf;
0169     topts.data_size_in = 9000;
0170     topts.data_size_out = 9000;
0171     err = bpf_prog_test_run_opts(prog_fd, &topts);
0172 
0173     ASSERT_OK(err, "9Kb-10b");
0174     ASSERT_EQ(topts.retval, XDP_TX, "9Kb-10b retval");
0175     ASSERT_EQ(topts.data_size_out, exp_size, "9Kb-10b size");
0176 
0177     /* Test case removing one of two pages, assuming 4K pages */
0178     buf[0] = 1;
0179     exp_size = 4900; /* 9000 - 4100 */
0180 
0181     topts.data_size_out = 9000; /* reset from previous invocation */
0182     err = bpf_prog_test_run_opts(prog_fd, &topts);
0183 
0184     ASSERT_OK(err, "9Kb-4Kb");
0185     ASSERT_EQ(topts.retval, XDP_TX, "9Kb-4Kb retval");
0186     ASSERT_EQ(topts.data_size_out, exp_size, "9Kb-4Kb size");
0187 
0188     /* Test case removing two pages resulting in a linear xdp_buff */
0189     buf[0] = 2;
0190     exp_size = 800; /* 9000 - 8200 */
0191     topts.data_size_out = 9000; /* reset from previous invocation */
0192     err = bpf_prog_test_run_opts(prog_fd, &topts);
0193 
0194     ASSERT_OK(err, "9Kb-9Kb");
0195     ASSERT_EQ(topts.retval, XDP_TX, "9Kb-9Kb retval");
0196     ASSERT_EQ(topts.data_size_out, exp_size, "9Kb-9Kb size");
0197 
0198     free(buf);
0199 out:
0200     bpf_object__close(obj);
0201 }
0202 
0203 static void test_xdp_adjust_frags_tail_grow(void)
0204 {
0205     const char *file = "./test_xdp_adjust_tail_grow.o";
0206     __u32 exp_size;
0207     struct bpf_program *prog;
0208     struct bpf_object *obj;
0209     int err, i, prog_fd;
0210     __u8 *buf;
0211     LIBBPF_OPTS(bpf_test_run_opts, topts);
0212 
0213     obj = bpf_object__open(file);
0214     if (libbpf_get_error(obj))
0215         return;
0216 
0217     prog = bpf_object__next_program(obj, NULL);
0218     if (bpf_object__load(obj))
0219         return;
0220 
0221     prog_fd = bpf_program__fd(prog);
0222 
0223     buf = malloc(16384);
0224     if (!ASSERT_OK_PTR(buf, "alloc buf 16Kb"))
0225         goto out;
0226 
0227     /* Test case add 10 bytes to last frag */
0228     memset(buf, 1, 16384);
0229     exp_size = 9000 + 10;
0230 
0231     topts.data_in = buf;
0232     topts.data_out = buf;
0233     topts.data_size_in = 9000;
0234     topts.data_size_out = 16384;
0235     err = bpf_prog_test_run_opts(prog_fd, &topts);
0236 
0237     ASSERT_OK(err, "9Kb+10b");
0238     ASSERT_EQ(topts.retval, XDP_TX, "9Kb+10b retval");
0239     ASSERT_EQ(topts.data_size_out, exp_size, "9Kb+10b size");
0240 
0241     for (i = 0; i < 9000; i++)
0242         ASSERT_EQ(buf[i], 1, "9Kb+10b-old");
0243 
0244     for (i = 9000; i < 9010; i++)
0245         ASSERT_EQ(buf[i], 0, "9Kb+10b-new");
0246 
0247     for (i = 9010; i < 16384; i++)
0248         ASSERT_EQ(buf[i], 1, "9Kb+10b-untouched");
0249 
0250     /* Test a too large grow */
0251     memset(buf, 1, 16384);
0252     exp_size = 9001;
0253 
0254     topts.data_in = topts.data_out = buf;
0255     topts.data_size_in = 9001;
0256     topts.data_size_out = 16384;
0257     err = bpf_prog_test_run_opts(prog_fd, &topts);
0258 
0259     ASSERT_OK(err, "9Kb+10b");
0260     ASSERT_EQ(topts.retval, XDP_DROP, "9Kb+10b retval");
0261     ASSERT_EQ(topts.data_size_out, exp_size, "9Kb+10b size");
0262 
0263     free(buf);
0264 out:
0265     bpf_object__close(obj);
0266 }
0267 
0268 void test_xdp_adjust_tail(void)
0269 {
0270     if (test__start_subtest("xdp_adjust_tail_shrink"))
0271         test_xdp_adjust_tail_shrink();
0272     if (test__start_subtest("xdp_adjust_tail_grow"))
0273         test_xdp_adjust_tail_grow();
0274     if (test__start_subtest("xdp_adjust_tail_grow2"))
0275         test_xdp_adjust_tail_grow2();
0276     if (test__start_subtest("xdp_adjust_frags_tail_shrink"))
0277         test_xdp_adjust_frags_tail_shrink();
0278     if (test__start_subtest("xdp_adjust_frags_tail_grow"))
0279         test_xdp_adjust_frags_tail_grow();
0280 }