Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2021 Facebook */ #include <test_progs.h> #include <network_helpers.h> #include "for_each_hash_map_elem.skel.h" #include "for_each_array_map_elem.skel.h" #include "for_each_map_elem_write_key.skel.h" static unsigned int duration; static void test_hash_map(void) { int i, err, max_entries; struct for_each_hash_map_elem *skel; __u64 *percpu_valbuf = NULL; size_t percpu_val_sz; __u32 key, num_cpus; __u64 val; LIBBPF_OPTS(bpf_test_run_opts, topts, .data_in = &pkt_v4, .data_size_in = sizeof(pkt_v4), .repeat = 1, ); skel = for_each_hash_map_elem__open_and_load(); if (!ASSERT_OK_PTR(skel, "for_each_hash_map_elem__open_and_load")) return; max_entries = bpf_map__max_entries(skel->maps.hashmap); for (i = 0; i < max_entries; i++) { key = i; val = i + 1; err = bpf_map__update_elem(skel->maps.hashmap, &key, sizeof(key), &val, sizeof(val), BPF_ANY); if (!ASSERT_OK(err, "map_update")) goto out; } num_cpus = bpf_num_possible_cpus(); percpu_val_sz = sizeof(__u64) * num_cpus; percpu_valbuf = malloc(percpu_val_sz); if (!ASSERT_OK_PTR(percpu_valbuf, "percpu_valbuf")) goto out; key = 1; for (i = 0; i < num_cpus; i++) percpu_valbuf[i] = i + 1; err = bpf_map__update_elem(skel->maps.percpu_map, &key, sizeof(key), percpu_valbuf, percpu_val_sz, BPF_ANY); if (!ASSERT_OK(err, "percpu_map_update")) goto out; err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_pkt_access), &topts); duration = topts.duration; if (CHECK(err || topts.retval, "ipv4", "err %d errno %d retval %d\n", err, errno, topts.retval)) goto out; ASSERT_EQ(skel->bss->hashmap_output, 4, "hashmap_output"); ASSERT_EQ(skel->bss->hashmap_elems, max_entries, "hashmap_elems"); key = 1; err = bpf_map__lookup_elem(skel->maps.hashmap, &key, sizeof(key), &val, sizeof(val), 0); ASSERT_ERR(err, "hashmap_lookup"); ASSERT_EQ(skel->bss->percpu_called, 1, "percpu_called"); ASSERT_LT(skel->bss->cpu, num_cpus, "num_cpus"); ASSERT_EQ(skel->bss->percpu_map_elems, 1, "percpu_map_elems"); ASSERT_EQ(skel->bss->percpu_key, 1, "percpu_key"); ASSERT_EQ(skel->bss->percpu_val, skel->bss->cpu + 1, "percpu_val"); ASSERT_EQ(skel->bss->percpu_output, 100, "percpu_output"); out: free(percpu_valbuf); for_each_hash_map_elem__destroy(skel); } static void test_array_map(void) { __u32 key, num_cpus, max_entries; int i, err; struct for_each_array_map_elem *skel; __u64 *percpu_valbuf = NULL; size_t percpu_val_sz; __u64 val, expected_total; LIBBPF_OPTS(bpf_test_run_opts, topts, .data_in = &pkt_v4, .data_size_in = sizeof(pkt_v4), .repeat = 1, ); skel = for_each_array_map_elem__open_and_load(); if (!ASSERT_OK_PTR(skel, "for_each_array_map_elem__open_and_load")) return; expected_total = 0; max_entries = bpf_map__max_entries(skel->maps.arraymap); for (i = 0; i < max_entries; i++) { key = i; val = i + 1; /* skip the last iteration for expected total */ if (i != max_entries - 1) expected_total += val; err = bpf_map__update_elem(skel->maps.arraymap, &key, sizeof(key), &val, sizeof(val), BPF_ANY); if (!ASSERT_OK(err, "map_update")) goto out; } num_cpus = bpf_num_possible_cpus(); percpu_val_sz = sizeof(__u64) * num_cpus; percpu_valbuf = malloc(percpu_val_sz); if (!ASSERT_OK_PTR(percpu_valbuf, "percpu_valbuf")) goto out; key = 0; for (i = 0; i < num_cpus; i++) percpu_valbuf[i] = i + 1; err = bpf_map__update_elem(skel->maps.percpu_map, &key, sizeof(key), percpu_valbuf, percpu_val_sz, BPF_ANY); if (!ASSERT_OK(err, "percpu_map_update")) goto out; err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_pkt_access), &topts); duration = topts.duration; if (CHECK(err || topts.retval, "ipv4", "err %d errno %d retval %d\n", err, errno, topts.retval)) goto out; ASSERT_EQ(skel->bss->arraymap_output, expected_total, "array_output"); ASSERT_EQ(skel->bss->cpu + 1, skel->bss->percpu_val, "percpu_val"); out: free(percpu_valbuf); for_each_array_map_elem__destroy(skel); } static void test_write_map_key(void) { struct for_each_map_elem_write_key *skel; skel = for_each_map_elem_write_key__open_and_load(); if (!ASSERT_ERR_PTR(skel, "for_each_map_elem_write_key__open_and_load")) for_each_map_elem_write_key__destroy(skel); } void test_for_each(void) { if (test__start_subtest("hash_map")) test_hash_map(); if (test__start_subtest("array_map")) test_array_map(); if (test__start_subtest("write_map_key")) test_write_map_key(); } |