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