This adds a test to exercise the new bpf_map__set_initial_value() function. The test simply overrides the global data section with all zeroes, and checks that the new value makes it into the kernel map on load.
Unified · Split
| @@ -0,0 +1,61 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | #include <test_progs.h> | ||
| 3 | |||
| 4 | void test_global_data_init(void) | ||
| 5 | { | ||
| 6 | const char *file = "./test_global_data.o"; | ||
| 7 | int err = -ENOMEM, map_fd, zero = 0; | ||
| 8 | __u8 *buff = NULL, *newval = NULL; | ||
| 9 | struct bpf_object *obj; | ||
| 10 | struct bpf_map *map; | ||
| 11 | __u32 duration = 0; | ||
| 12 | size_t sz; | ||
| 13 | |||
| 14 | obj = bpf_object__open_file(file, NULL); | ||
| 15 | if (CHECK_FAIL(!obj)) | ||
| 16 | return; | ||
| 17 | |||
| 18 | map = bpf_object__find_map_by_name(obj, "test_glo.rodata"); | ||
| 19 | if (CHECK_FAIL(!map || !bpf_map__is_internal(map))) | ||
| 20 | goto out; | ||
| 21 | |||
| 22 | sz = bpf_map__def(map)->value_size; | ||
| 23 | newval = malloc(sz); | ||
| 24 | if (CHECK_FAIL(!newval)) | ||
| 25 | goto out; | ||
| 26 | |||
| 27 | memset(newval, 0, sz); | ||
| 28 | /* wrong size, should fail */ | ||
| 29 | err = bpf_map__set_initial_value(map, newval, sz - 1); | ||
| 30 | if (CHECK(!err, "reject set initial value wrong size", "err %d\n", err)) | ||
| 31 | goto out; | ||
| 32 | |||
| 33 | err = bpf_map__set_initial_value(map, newval, sz); | ||
| 34 | if (CHECK(err, "set initial value", "err %d\n", err)) | ||
| 35 | goto out; | ||
| 36 | |||
| 37 | err = bpf_object__load(obj); | ||
| 38 | if (CHECK_FAIL(err)) | ||
| 39 | goto out; | ||
| 40 | |||
| 41 | map_fd = bpf_map__fd(map); | ||
| 42 | if (CHECK_FAIL(map_fd < 0)) | ||
| 43 | goto out; | ||
| 44 | |||
| 45 | buff = malloc(sz); | ||
| 46 | if (buff) | ||
| 47 | err = bpf_map_lookup_elem(map_fd, &zero, buff); | ||
| 48 | if (CHECK(!buff || err || memcmp(buff, newval, sz), | ||
| 49 | "compare .rodata map data override", | ||
| 50 | "err %d errno %d\n", err, errno)) | ||
| 51 | goto out; | ||
| 52 | |||
| 53 | memset(newval, 1, sz); | ||
| 54 | /* object loaded - should fail */ | ||
| 55 | err = bpf_map__set_initial_value(map, newval, sz); | ||
| 56 | CHECK(!err, "reject set initial value after load", "err %d\n", err); | ||
| 57 | out: | ||
| 58 | free(buff); | ||
| 59 | free(newval); | ||
| 60 | bpf_object__close(obj); | ||
| 61 | } | ||
| @@ -68,7 +68,7 @@ static struct foo struct3 = { · 67 unmodified lines | |||
| 68 | bpf_map_update_elem(&result_##map, &key, var, 0); \ | 68 | bpf_map_update_elem(&result_##map, &key, var, 0); \ |
| 69 | } while (0) | 69 | } while (0) |
| 70 | 70 | ||
| 71 | SEC("static_data_load") | 71 | SEC("classifier/static_data_load") |
| 72 | int load_static_data(struct __sk_buff *skb) | 72 | int load_static_data(struct __sk_buff *skb) |
| 73 | { | 73 | { |
| 74 | static const __u64 bar = ~0; | 74 | static const __u64 bar = ~0; |