0001
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;
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];
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;
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];
0078 int tailroom = 320; ;
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,
0088 .data_size_out = 0,
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
0096 memset(buf, 1, sizeof(buf));
0097 tattr.data_size_in = 64;
0098 tattr.data_size_out = 128;
0099
0100 err = bpf_prog_test_run_opts(prog_fd, &tattr);
0101
0102 ASSERT_EQ(errno, ENOSPC, "case-64 errno");
0103 ASSERT_EQ(tattr.retval, XDP_TX, "case-64 retval");
0104 ASSERT_EQ(tattr.data_size_out, 192, "case-64 data_size_out");
0105
0106
0107 ASSERT_EQ(buf[0], 1, "case-64-data buf[0]");
0108 ASSERT_EQ(buf[63], 1, "case-64-data buf[63]");
0109 ASSERT_EQ(buf[64], 0, "case-64-data buf[64]");
0110 ASSERT_EQ(buf[127], 0, "case-64-data buf[127]");
0111 ASSERT_EQ(buf[128], 1, "case-64-data buf[128]");
0112 ASSERT_EQ(buf[191], 1, "case-64-data buf[191]");
0113
0114
0115 memset(buf, 2, sizeof(buf));
0116 tattr.data_size_in = 128;
0117 tattr.data_size_out = sizeof(buf);
0118 err = bpf_prog_test_run_opts(prog_fd, &tattr);
0119
0120 max_grow = 4096 - XDP_PACKET_HEADROOM - tailroom;
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");
0124
0125
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");
0131 ASSERT_EQ(tattr.data_size_out, max_grow, "case-128-data data_size_out");
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
0147
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
0166 exp_size = 8990;
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
0178 buf[0] = 1;
0179 exp_size = 4900;
0180
0181 topts.data_size_out = 9000;
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
0189 buf[0] = 2;
0190 exp_size = 800;
0191 topts.data_size_out = 9000;
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
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
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 }