1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2021 Facebook */
4 #include <sys/syscall.h>
6 #include <test_progs.h>
7 #include "bloom_filter_map.skel.h"
9 static void test_fail_cases(void)
11 LIBBPF_OPTS(bpf_map_create_opts, opts);
15 /* Invalid key size */
16 fd = bpf_map_create(BPF_MAP_TYPE_BLOOM_FILTER, NULL, 4, sizeof(value), 100, NULL);
17 if (!ASSERT_LT(fd, 0, "bpf_map_create bloom filter invalid key size"))
20 /* Invalid value size */
21 fd = bpf_map_create(BPF_MAP_TYPE_BLOOM_FILTER, NULL, 0, 0, 100, NULL);
22 if (!ASSERT_LT(fd, 0, "bpf_map_create bloom filter invalid value size 0"))
25 /* Invalid value size: too big */
26 fd = bpf_map_create(BPF_MAP_TYPE_BLOOM_FILTER, NULL, 0, INT32_MAX, 100, NULL);
27 if (!ASSERT_LT(fd, 0, "bpf_map_create bloom filter invalid value too large"))
30 /* Invalid max entries size */
31 fd = bpf_map_create(BPF_MAP_TYPE_BLOOM_FILTER, NULL, 0, sizeof(value), 0, NULL);
32 if (!ASSERT_LT(fd, 0, "bpf_map_create bloom filter invalid max entries size"))
35 /* Bloom filter maps do not support BPF_F_NO_PREALLOC */
36 opts.map_flags = BPF_F_NO_PREALLOC;
37 fd = bpf_map_create(BPF_MAP_TYPE_BLOOM_FILTER, NULL, 0, sizeof(value), 100, &opts);
38 if (!ASSERT_LT(fd, 0, "bpf_map_create bloom filter invalid flags"))
41 fd = bpf_map_create(BPF_MAP_TYPE_BLOOM_FILTER, NULL, 0, sizeof(value), 100, NULL);
42 if (!ASSERT_GE(fd, 0, "bpf_map_create bloom filter"))
45 /* Test invalid flags */
46 err = bpf_map_update_elem(fd, NULL, &value, -1);
47 ASSERT_EQ(err, -EINVAL, "bpf_map_update_elem bloom filter invalid flags");
49 err = bpf_map_update_elem(fd, NULL, &value, BPF_EXIST);
50 ASSERT_EQ(err, -EINVAL, "bpf_map_update_elem bloom filter invalid flags");
52 err = bpf_map_update_elem(fd, NULL, &value, BPF_F_LOCK);
53 ASSERT_EQ(err, -EINVAL, "bpf_map_update_elem bloom filter invalid flags");
55 err = bpf_map_update_elem(fd, NULL, &value, BPF_NOEXIST);
56 ASSERT_EQ(err, -EINVAL, "bpf_map_update_elem bloom filter invalid flags");
58 err = bpf_map_update_elem(fd, NULL, &value, 10000);
59 ASSERT_EQ(err, -EINVAL, "bpf_map_update_elem bloom filter invalid flags");
64 static void test_success_cases(void)
66 LIBBPF_OPTS(bpf_map_create_opts, opts);
71 opts.map_flags = BPF_F_ZERO_SEED | BPF_F_NUMA_NODE;
72 fd = bpf_map_create(BPF_MAP_TYPE_BLOOM_FILTER, NULL, 0, sizeof(value), 100, &opts);
73 if (!ASSERT_GE(fd, 0, "bpf_map_create bloom filter success case"))
76 /* Add a value to the bloom filter */
77 err = bpf_map_update_elem(fd, NULL, &value, 0);
78 if (!ASSERT_OK(err, "bpf_map_update_elem bloom filter success case"))
81 /* Lookup a value in the bloom filter */
82 err = bpf_map_lookup_elem(fd, NULL, &value);
83 ASSERT_OK(err, "bpf_map_update_elem bloom filter success case");
89 static void check_bloom(struct bloom_filter_map *skel)
91 struct bpf_link *link;
93 link = bpf_program__attach(skel->progs.check_bloom);
94 if (!ASSERT_OK_PTR(link, "link"))
99 ASSERT_EQ(skel->bss->error, 0, "error");
101 bpf_link__destroy(link);
104 static void test_inner_map(struct bloom_filter_map *skel, const __u32 *rand_vals,
107 int outer_map_fd, inner_map_fd, err, i, key = 0;
108 struct bpf_link *link;
110 /* Create a bloom filter map that will be used as the inner map */
111 inner_map_fd = bpf_map_create(BPF_MAP_TYPE_BLOOM_FILTER, NULL, 0, sizeof(*rand_vals),
113 if (!ASSERT_GE(inner_map_fd, 0, "bpf_map_create bloom filter inner map"))
116 for (i = 0; i < nr_rand_vals; i++) {
117 err = bpf_map_update_elem(inner_map_fd, NULL, rand_vals + i, BPF_ANY);
118 if (!ASSERT_OK(err, "Add random value to inner_map_fd"))
122 /* Add the bloom filter map to the outer map */
123 outer_map_fd = bpf_map__fd(skel->maps.outer_map);
124 err = bpf_map_update_elem(outer_map_fd, &key, &inner_map_fd, BPF_ANY);
125 if (!ASSERT_OK(err, "Add bloom filter map to outer map"))
128 /* Attach the bloom_filter_inner_map prog */
129 link = bpf_program__attach(skel->progs.inner_map);
130 if (!ASSERT_OK_PTR(link, "link"))
131 goto delete_inner_map;
133 syscall(SYS_getpgid);
135 ASSERT_EQ(skel->bss->error, 0, "error");
137 bpf_link__destroy(link);
140 /* Ensure the inner bloom filter map can be deleted */
141 err = bpf_map_delete_elem(outer_map_fd, &key);
142 ASSERT_OK(err, "Delete inner bloom filter map");
148 static int setup_progs(struct bloom_filter_map **out_skel, __u32 **out_rand_vals,
149 __u32 *out_nr_rand_vals)
151 struct bloom_filter_map *skel;
152 int random_data_fd, bloom_fd;
153 __u32 *rand_vals = NULL;
157 /* Set up a bloom filter map skeleton */
158 skel = bloom_filter_map__open_and_load();
159 if (!ASSERT_OK_PTR(skel, "bloom_filter_map__open_and_load"))
162 /* Set up rand_vals */
163 map_size = bpf_map__max_entries(skel->maps.map_random_data);
164 rand_vals = malloc(sizeof(*rand_vals) * map_size);
170 /* Generate random values and populate both skeletons */
171 random_data_fd = bpf_map__fd(skel->maps.map_random_data);
172 bloom_fd = bpf_map__fd(skel->maps.map_bloom);
173 for (i = 0; i < map_size; i++) {
176 err = bpf_map_update_elem(random_data_fd, &i, &val, BPF_ANY);
177 if (!ASSERT_OK(err, "Add random value to map_random_data"))
180 err = bpf_map_update_elem(bloom_fd, NULL, &val, BPF_ANY);
181 if (!ASSERT_OK(err, "Add random value to map_bloom"))
188 *out_rand_vals = rand_vals;
189 *out_nr_rand_vals = map_size;
194 bloom_filter_map__destroy(skel);
200 void test_bloom_filter_map(void)
202 __u32 *rand_vals = NULL, nr_rand_vals = 0;
203 struct bloom_filter_map *skel = NULL;
207 test_success_cases();
209 err = setup_progs(&skel, &rand_vals, &nr_rand_vals);
213 test_inner_map(skel, rand_vals, nr_rand_vals);
218 bloom_filter_map__destroy(skel);