1d42d1cc4SYiFei Zhu // SPDX-License-Identifier: GPL-2.0-only 2d42d1cc4SYiFei Zhu 3d42d1cc4SYiFei Zhu /* 4d42d1cc4SYiFei Zhu * Copyright 2020 Google LLC. 5d42d1cc4SYiFei Zhu */ 6d42d1cc4SYiFei Zhu 7d42d1cc4SYiFei Zhu #include <test_progs.h> 8d42d1cc4SYiFei Zhu #include <cgroup_helpers.h> 9d42d1cc4SYiFei Zhu #include <network_helpers.h> 10d42d1cc4SYiFei Zhu 11d42d1cc4SYiFei Zhu #include "metadata_unused.skel.h" 12d42d1cc4SYiFei Zhu #include "metadata_used.skel.h" 13d42d1cc4SYiFei Zhu 14d42d1cc4SYiFei Zhu static int duration; 15d42d1cc4SYiFei Zhu 16d42d1cc4SYiFei Zhu static int prog_holds_map(int prog_fd, int map_fd) 17d42d1cc4SYiFei Zhu { 18d42d1cc4SYiFei Zhu struct bpf_prog_info prog_info = {}; 19*c5a237a4SIlya Leoshkevich struct bpf_map_info map_info = {}; 20d42d1cc4SYiFei Zhu __u32 prog_info_len; 21d42d1cc4SYiFei Zhu __u32 map_info_len; 22d42d1cc4SYiFei Zhu __u32 *map_ids; 23d42d1cc4SYiFei Zhu int nr_maps; 24d42d1cc4SYiFei Zhu int ret; 25d42d1cc4SYiFei Zhu int i; 26d42d1cc4SYiFei Zhu 27d42d1cc4SYiFei Zhu map_info_len = sizeof(map_info); 28*c5a237a4SIlya Leoshkevich ret = bpf_map_get_info_by_fd(map_fd, &map_info, &map_info_len); 29d42d1cc4SYiFei Zhu if (ret) 30d42d1cc4SYiFei Zhu return -errno; 31d42d1cc4SYiFei Zhu 32d42d1cc4SYiFei Zhu prog_info_len = sizeof(prog_info); 33*c5a237a4SIlya Leoshkevich ret = bpf_prog_get_info_by_fd(prog_fd, &prog_info, &prog_info_len); 34d42d1cc4SYiFei Zhu if (ret) 35d42d1cc4SYiFei Zhu return -errno; 36d42d1cc4SYiFei Zhu 37d42d1cc4SYiFei Zhu map_ids = calloc(prog_info.nr_map_ids, sizeof(__u32)); 38d42d1cc4SYiFei Zhu if (!map_ids) 39d42d1cc4SYiFei Zhu return -ENOMEM; 40d42d1cc4SYiFei Zhu 41d42d1cc4SYiFei Zhu nr_maps = prog_info.nr_map_ids; 42d42d1cc4SYiFei Zhu memset(&prog_info, 0, sizeof(prog_info)); 43d42d1cc4SYiFei Zhu prog_info.nr_map_ids = nr_maps; 44d42d1cc4SYiFei Zhu prog_info.map_ids = ptr_to_u64(map_ids); 45d42d1cc4SYiFei Zhu prog_info_len = sizeof(prog_info); 46d42d1cc4SYiFei Zhu 47*c5a237a4SIlya Leoshkevich ret = bpf_prog_get_info_by_fd(prog_fd, &prog_info, &prog_info_len); 48d42d1cc4SYiFei Zhu if (ret) { 49d42d1cc4SYiFei Zhu ret = -errno; 50d42d1cc4SYiFei Zhu goto free_map_ids; 51d42d1cc4SYiFei Zhu } 52d42d1cc4SYiFei Zhu 53d42d1cc4SYiFei Zhu ret = -ENOENT; 54d42d1cc4SYiFei Zhu for (i = 0; i < prog_info.nr_map_ids; i++) { 55d42d1cc4SYiFei Zhu if (map_ids[i] == map_info.id) { 56d42d1cc4SYiFei Zhu ret = 0; 57d42d1cc4SYiFei Zhu break; 58d42d1cc4SYiFei Zhu } 59d42d1cc4SYiFei Zhu } 60d42d1cc4SYiFei Zhu 61d42d1cc4SYiFei Zhu free_map_ids: 62d42d1cc4SYiFei Zhu free(map_ids); 63d42d1cc4SYiFei Zhu return ret; 64d42d1cc4SYiFei Zhu } 65d42d1cc4SYiFei Zhu 66d42d1cc4SYiFei Zhu static void test_metadata_unused(void) 67d42d1cc4SYiFei Zhu { 68d42d1cc4SYiFei Zhu struct metadata_unused *obj; 69d42d1cc4SYiFei Zhu int err; 70d42d1cc4SYiFei Zhu 71d42d1cc4SYiFei Zhu obj = metadata_unused__open_and_load(); 72d42d1cc4SYiFei Zhu if (CHECK(!obj, "skel-load", "errno %d", errno)) 73d42d1cc4SYiFei Zhu return; 74d42d1cc4SYiFei Zhu 75d42d1cc4SYiFei Zhu err = prog_holds_map(bpf_program__fd(obj->progs.prog), 76d42d1cc4SYiFei Zhu bpf_map__fd(obj->maps.rodata)); 77d42d1cc4SYiFei Zhu if (CHECK(err, "prog-holds-rodata", "errno: %d", err)) 78d42d1cc4SYiFei Zhu return; 79d42d1cc4SYiFei Zhu 80d42d1cc4SYiFei Zhu /* Assert that we can access the metadata in skel and the values are 81d42d1cc4SYiFei Zhu * what we expect. 82d42d1cc4SYiFei Zhu */ 83d42d1cc4SYiFei Zhu if (CHECK(strncmp(obj->rodata->bpf_metadata_a, "foo", 84d42d1cc4SYiFei Zhu sizeof(obj->rodata->bpf_metadata_a)), 85d42d1cc4SYiFei Zhu "bpf_metadata_a", "expected \"foo\", value differ")) 86d42d1cc4SYiFei Zhu goto close_bpf_object; 87d42d1cc4SYiFei Zhu if (CHECK(obj->rodata->bpf_metadata_b != 1, "bpf_metadata_b", 88d42d1cc4SYiFei Zhu "expected 1, got %d", obj->rodata->bpf_metadata_b)) 89d42d1cc4SYiFei Zhu goto close_bpf_object; 90d42d1cc4SYiFei Zhu 91d42d1cc4SYiFei Zhu /* Assert that binding metadata map to prog again succeeds. */ 92d42d1cc4SYiFei Zhu err = bpf_prog_bind_map(bpf_program__fd(obj->progs.prog), 93d42d1cc4SYiFei Zhu bpf_map__fd(obj->maps.rodata), NULL); 94d42d1cc4SYiFei Zhu CHECK(err, "rebind_map", "errno %d, expected 0", errno); 95d42d1cc4SYiFei Zhu 96d42d1cc4SYiFei Zhu close_bpf_object: 97d42d1cc4SYiFei Zhu metadata_unused__destroy(obj); 98d42d1cc4SYiFei Zhu } 99d42d1cc4SYiFei Zhu 100d42d1cc4SYiFei Zhu static void test_metadata_used(void) 101d42d1cc4SYiFei Zhu { 102d42d1cc4SYiFei Zhu struct metadata_used *obj; 103d42d1cc4SYiFei Zhu int err; 104d42d1cc4SYiFei Zhu 105d42d1cc4SYiFei Zhu obj = metadata_used__open_and_load(); 106d42d1cc4SYiFei Zhu if (CHECK(!obj, "skel-load", "errno %d", errno)) 107d42d1cc4SYiFei Zhu return; 108d42d1cc4SYiFei Zhu 109d42d1cc4SYiFei Zhu err = prog_holds_map(bpf_program__fd(obj->progs.prog), 110d42d1cc4SYiFei Zhu bpf_map__fd(obj->maps.rodata)); 111d42d1cc4SYiFei Zhu if (CHECK(err, "prog-holds-rodata", "errno: %d", err)) 112d42d1cc4SYiFei Zhu return; 113d42d1cc4SYiFei Zhu 114d42d1cc4SYiFei Zhu /* Assert that we can access the metadata in skel and the values are 115d42d1cc4SYiFei Zhu * what we expect. 116d42d1cc4SYiFei Zhu */ 117d42d1cc4SYiFei Zhu if (CHECK(strncmp(obj->rodata->bpf_metadata_a, "bar", 118d42d1cc4SYiFei Zhu sizeof(obj->rodata->bpf_metadata_a)), 119d42d1cc4SYiFei Zhu "metadata_a", "expected \"bar\", value differ")) 120d42d1cc4SYiFei Zhu goto close_bpf_object; 121d42d1cc4SYiFei Zhu if (CHECK(obj->rodata->bpf_metadata_b != 2, "metadata_b", 122d42d1cc4SYiFei Zhu "expected 2, got %d", obj->rodata->bpf_metadata_b)) 123d42d1cc4SYiFei Zhu goto close_bpf_object; 124d42d1cc4SYiFei Zhu 125d42d1cc4SYiFei Zhu /* Assert that binding metadata map to prog again succeeds. */ 126d42d1cc4SYiFei Zhu err = bpf_prog_bind_map(bpf_program__fd(obj->progs.prog), 127d42d1cc4SYiFei Zhu bpf_map__fd(obj->maps.rodata), NULL); 128d42d1cc4SYiFei Zhu CHECK(err, "rebind_map", "errno %d, expected 0", errno); 129d42d1cc4SYiFei Zhu 130d42d1cc4SYiFei Zhu close_bpf_object: 131d42d1cc4SYiFei Zhu metadata_used__destroy(obj); 132d42d1cc4SYiFei Zhu } 133d42d1cc4SYiFei Zhu 134d42d1cc4SYiFei Zhu void test_metadata(void) 135d42d1cc4SYiFei Zhu { 136d42d1cc4SYiFei Zhu if (test__start_subtest("unused")) 137d42d1cc4SYiFei Zhu test_metadata_unused(); 138d42d1cc4SYiFei Zhu 139d42d1cc4SYiFei Zhu if (test__start_subtest("used")) 140d42d1cc4SYiFei Zhu test_metadata_used(); 141d42d1cc4SYiFei Zhu } 142