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_global_data_number(struct bpf_object *obj, __u32 duration)
0006 {
0007     int i, err, map_fd;
0008     __u64 num;
0009 
0010     map_fd = bpf_find_map(__func__, obj, "result_number");
0011     if (CHECK_FAIL(map_fd < 0))
0012         return;
0013 
0014     struct {
0015         char *name;
0016         uint32_t key;
0017         __u64 num;
0018     } tests[] = {
0019         { "relocate .bss reference",     0, 0 },
0020         { "relocate .data reference",    1, 42 },
0021         { "relocate .rodata reference",  2, 24 },
0022         { "relocate .bss reference",     3, 0 },
0023         { "relocate .data reference",    4, 0xffeeff },
0024         { "relocate .rodata reference",  5, 0xabab },
0025         { "relocate .bss reference",     6, 1234 },
0026         { "relocate .bss reference",     7, 0 },
0027         { "relocate .rodata reference",  8, 0xab },
0028         { "relocate .rodata reference",  9, 0x1111111111111111 },
0029         { "relocate .rodata reference", 10, ~0 },
0030     };
0031 
0032     for (i = 0; i < ARRAY_SIZE(tests); i++) {
0033         err = bpf_map_lookup_elem(map_fd, &tests[i].key, &num);
0034         CHECK(err || num != tests[i].num, tests[i].name,
0035               "err %d result %llx expected %llx\n",
0036               err, num, tests[i].num);
0037     }
0038 }
0039 
0040 static void test_global_data_string(struct bpf_object *obj, __u32 duration)
0041 {
0042     int i, err, map_fd;
0043     char str[32];
0044 
0045     map_fd = bpf_find_map(__func__, obj, "result_string");
0046     if (CHECK_FAIL(map_fd < 0))
0047         return;
0048 
0049     struct {
0050         char *name;
0051         uint32_t key;
0052         char str[32];
0053     } tests[] = {
0054         { "relocate .rodata reference", 0, "abcdefghijklmnopqrstuvwxyz" },
0055         { "relocate .data reference",   1, "abcdefghijklmnopqrstuvwxyz" },
0056         { "relocate .bss reference",    2, "" },
0057         { "relocate .data reference",   3, "abcdexghijklmnopqrstuvwxyz" },
0058         { "relocate .bss reference",    4, "\0\0hello" },
0059     };
0060 
0061     for (i = 0; i < ARRAY_SIZE(tests); i++) {
0062         err = bpf_map_lookup_elem(map_fd, &tests[i].key, str);
0063         CHECK(err || memcmp(str, tests[i].str, sizeof(str)),
0064               tests[i].name, "err %d result \'%s\' expected \'%s\'\n",
0065               err, str, tests[i].str);
0066     }
0067 }
0068 
0069 struct foo {
0070     __u8  a;
0071     __u32 b;
0072     __u64 c;
0073 };
0074 
0075 static void test_global_data_struct(struct bpf_object *obj, __u32 duration)
0076 {
0077     int i, err, map_fd;
0078     struct foo val;
0079 
0080     map_fd = bpf_find_map(__func__, obj, "result_struct");
0081     if (CHECK_FAIL(map_fd < 0))
0082         return;
0083 
0084     struct {
0085         char *name;
0086         uint32_t key;
0087         struct foo val;
0088     } tests[] = {
0089         { "relocate .rodata reference", 0, { 42, 0xfefeefef, 0x1111111111111111ULL, } },
0090         { "relocate .bss reference",    1, { } },
0091         { "relocate .rodata reference", 2, { } },
0092         { "relocate .data reference",   3, { 41, 0xeeeeefef, 0x2111111111111111ULL, } },
0093     };
0094 
0095     for (i = 0; i < ARRAY_SIZE(tests); i++) {
0096         err = bpf_map_lookup_elem(map_fd, &tests[i].key, &val);
0097         CHECK(err || memcmp(&val, &tests[i].val, sizeof(val)),
0098               tests[i].name, "err %d result { %u, %u, %llu } expected { %u, %u, %llu }\n",
0099               err, val.a, val.b, val.c, tests[i].val.a, tests[i].val.b, tests[i].val.c);
0100     }
0101 }
0102 
0103 static void test_global_data_rdonly(struct bpf_object *obj, __u32 duration)
0104 {
0105     int err = -ENOMEM, map_fd, zero = 0;
0106     struct bpf_map *map, *map2;
0107     __u8 *buff;
0108 
0109     map = bpf_object__find_map_by_name(obj, "test_glo.rodata");
0110     if (!ASSERT_OK_PTR(map, "map"))
0111         return;
0112     if (!ASSERT_TRUE(bpf_map__is_internal(map), "is_internal"))
0113         return;
0114 
0115     /* ensure we can lookup internal maps by their ELF names */
0116     map2 = bpf_object__find_map_by_name(obj, ".rodata");
0117     if (!ASSERT_EQ(map, map2, "same_maps"))
0118         return;
0119 
0120     map_fd = bpf_map__fd(map);
0121     if (CHECK_FAIL(map_fd < 0))
0122         return;
0123 
0124     buff = malloc(bpf_map__value_size(map));
0125     if (buff)
0126         err = bpf_map_update_elem(map_fd, &zero, buff, 0);
0127     free(buff);
0128     CHECK(!err || errno != EPERM, "test .rodata read-only map",
0129           "err %d errno %d\n", err, errno);
0130 }
0131 
0132 void test_global_data(void)
0133 {
0134     const char *file = "./test_global_data.o";
0135     struct bpf_object *obj;
0136     int err, prog_fd;
0137     LIBBPF_OPTS(bpf_test_run_opts, topts,
0138         .data_in = &pkt_v4,
0139         .data_size_in = sizeof(pkt_v4),
0140         .repeat = 1,
0141     );
0142 
0143     err = bpf_prog_test_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd);
0144     if (!ASSERT_OK(err, "load program"))
0145         return;
0146 
0147     err = bpf_prog_test_run_opts(prog_fd, &topts);
0148     ASSERT_OK(err, "pass global data run err");
0149     ASSERT_OK(topts.retval, "pass global data run retval");
0150 
0151     test_global_data_number(obj, topts.duration);
0152     test_global_data_string(obj, topts.duration);
0153     test_global_data_struct(obj, topts.duration);
0154     test_global_data_rdonly(obj, topts.duration);
0155 
0156     bpf_object__close(obj);
0157 }