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