0001
0002 #include <test_progs.h>
0003 #include <network_helpers.h>
0004
0005 static void test_xdp_update_frags(void)
0006 {
0007 const char *file = "./test_xdp_update_frags.o";
0008 int err, prog_fd, max_skb_frags, buf_size, num;
0009 struct bpf_program *prog;
0010 struct bpf_object *obj;
0011 __u32 *offset;
0012 __u8 *buf;
0013 FILE *f;
0014 LIBBPF_OPTS(bpf_test_run_opts, topts);
0015
0016 obj = bpf_object__open(file);
0017 if (libbpf_get_error(obj))
0018 return;
0019
0020 prog = bpf_object__next_program(obj, NULL);
0021 if (bpf_object__load(obj))
0022 return;
0023
0024 prog_fd = bpf_program__fd(prog);
0025
0026 buf = malloc(128);
0027 if (!ASSERT_OK_PTR(buf, "alloc buf 128b"))
0028 goto out;
0029
0030 memset(buf, 0, 128);
0031 offset = (__u32 *)buf;
0032 *offset = 16;
0033 buf[*offset] = 0xaa;
0034 buf[*offset + 15] = 0xaa;
0035
0036 topts.data_in = buf;
0037 topts.data_out = buf;
0038 topts.data_size_in = 128;
0039 topts.data_size_out = 128;
0040
0041 err = bpf_prog_test_run_opts(prog_fd, &topts);
0042
0043
0044 ASSERT_OK(err, "xdp_update_frag");
0045 ASSERT_EQ(topts.retval, XDP_PASS, "xdp_update_frag retval");
0046 ASSERT_EQ(buf[16], 0xbb, "xdp_update_frag buf[16]");
0047 ASSERT_EQ(buf[31], 0xbb, "xdp_update_frag buf[31]");
0048
0049 free(buf);
0050
0051 buf = malloc(9000);
0052 if (!ASSERT_OK_PTR(buf, "alloc buf 9Kb"))
0053 goto out;
0054
0055 memset(buf, 0, 9000);
0056 offset = (__u32 *)buf;
0057 *offset = 5000;
0058 buf[*offset] = 0xaa;
0059 buf[*offset + 15] = 0xaa;
0060
0061 topts.data_in = buf;
0062 topts.data_out = buf;
0063 topts.data_size_in = 9000;
0064 topts.data_size_out = 9000;
0065
0066 err = bpf_prog_test_run_opts(prog_fd, &topts);
0067
0068
0069 ASSERT_OK(err, "xdp_update_frag");
0070 ASSERT_EQ(topts.retval, XDP_PASS, "xdp_update_frag retval");
0071 ASSERT_EQ(buf[5000], 0xbb, "xdp_update_frag buf[5000]");
0072 ASSERT_EQ(buf[5015], 0xbb, "xdp_update_frag buf[5015]");
0073
0074 memset(buf, 0, 9000);
0075 offset = (__u32 *)buf;
0076 *offset = 3510;
0077 buf[*offset] = 0xaa;
0078 buf[*offset + 15] = 0xaa;
0079
0080 err = bpf_prog_test_run_opts(prog_fd, &topts);
0081
0082
0083 ASSERT_OK(err, "xdp_update_frag");
0084 ASSERT_EQ(topts.retval, XDP_PASS, "xdp_update_frag retval");
0085 ASSERT_EQ(buf[3510], 0xbb, "xdp_update_frag buf[3510]");
0086 ASSERT_EQ(buf[3525], 0xbb, "xdp_update_frag buf[3525]");
0087
0088 memset(buf, 0, 9000);
0089 offset = (__u32 *)buf;
0090 *offset = 7606;
0091 buf[*offset] = 0xaa;
0092 buf[*offset + 15] = 0xaa;
0093
0094 err = bpf_prog_test_run_opts(prog_fd, &topts);
0095
0096
0097 ASSERT_OK(err, "xdp_update_frag");
0098 ASSERT_EQ(topts.retval, XDP_PASS, "xdp_update_frag retval");
0099 ASSERT_EQ(buf[7606], 0xbb, "xdp_update_frag buf[7606]");
0100 ASSERT_EQ(buf[7621], 0xbb, "xdp_update_frag buf[7621]");
0101
0102 free(buf);
0103
0104
0105 f = fopen("/proc/sys/net/core/max_skb_frags", "r");
0106 if (!ASSERT_OK_PTR(f, "max_skb_frag file pointer"))
0107 goto out;
0108
0109 num = fscanf(f, "%d", &max_skb_frags);
0110 fclose(f);
0111
0112 if (!ASSERT_EQ(num, 1, "max_skb_frags read failed"))
0113 goto out;
0114
0115
0116
0117
0118 buf_size = 4096 + (max_skb_frags + 1) * sysconf(_SC_PAGE_SIZE);
0119 buf = malloc(buf_size);
0120 if (!ASSERT_OK_PTR(buf, "alloc buf"))
0121 goto out;
0122
0123 memset(buf, 0, buf_size);
0124 offset = (__u32 *)buf;
0125 *offset = 16;
0126 buf[*offset] = 0xaa;
0127 buf[*offset + 15] = 0xaa;
0128
0129 topts.data_in = buf;
0130 topts.data_out = buf;
0131 topts.data_size_in = buf_size;
0132 topts.data_size_out = buf_size;
0133
0134 err = bpf_prog_test_run_opts(prog_fd, &topts);
0135 ASSERT_EQ(err, -ENOMEM,
0136 "unsupported buf size, possible non-default /proc/sys/net/core/max_skb_flags?");
0137 free(buf);
0138 out:
0139 bpf_object__close(obj);
0140 }
0141
0142 void test_xdp_adjust_frags(void)
0143 {
0144 if (test__start_subtest("xdp_adjust_frags"))
0145 test_xdp_update_frags();
0146 }