sch_htb: Fix inconsistency when leaf qdisc creation fails
[linux-2.6-microblaze.git] / tools / testing / selftests / bpf / test_maps.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Testsuite for eBPF maps
4  *
5  * Copyright (c) 2014 PLUMgrid, http://plumgrid.com
6  * Copyright (c) 2016 Facebook
7  */
8
9 #include <stdio.h>
10 #include <unistd.h>
11 #include <errno.h>
12 #include <string.h>
13 #include <assert.h>
14 #include <stdlib.h>
15 #include <time.h>
16
17 #include <sys/wait.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <linux/bpf.h>
21
22 #include <bpf/bpf.h>
23 #include <bpf/libbpf.h>
24
25 #include "bpf_util.h"
26 #include "bpf_rlimit.h"
27 #include "test_maps.h"
28
29 #ifndef ENOTSUPP
30 #define ENOTSUPP 524
31 #endif
32
33 static int skips;
34
35 static int map_flags;
36
37 static void test_hashmap(unsigned int task, void *data)
38 {
39         long long key, next_key, first_key, value;
40         int fd;
41
42         fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
43                             2, map_flags);
44         if (fd < 0) {
45                 printf("Failed to create hashmap '%s'!\n", strerror(errno));
46                 exit(1);
47         }
48
49         key = 1;
50         value = 1234;
51         /* Insert key=1 element. */
52         assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
53
54         value = 0;
55         /* BPF_NOEXIST means add new element if it doesn't exist. */
56         assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) < 0 &&
57                /* key=1 already exists. */
58                errno == EEXIST);
59
60         /* -1 is an invalid flag. */
61         assert(bpf_map_update_elem(fd, &key, &value, -1) < 0 &&
62                errno == EINVAL);
63
64         /* Check that key=1 can be found. */
65         assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 1234);
66
67         key = 2;
68         value = 1234;
69         /* Insert key=2 element. */
70         assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
71
72         /* Check that key=2 matches the value and delete it */
73         assert(bpf_map_lookup_and_delete_elem(fd, &key, &value) == 0 && value == 1234);
74
75         /* Check that key=2 is not found. */
76         assert(bpf_map_lookup_elem(fd, &key, &value) < 0 && errno == ENOENT);
77
78         /* BPF_EXIST means update existing element. */
79         assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) < 0 &&
80                /* key=2 is not there. */
81                errno == ENOENT);
82
83         /* Insert key=2 element. */
84         assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == 0);
85
86         /* key=1 and key=2 were inserted, check that key=0 cannot be
87          * inserted due to max_entries limit.
88          */
89         key = 0;
90         assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) < 0 &&
91                errno == E2BIG);
92
93         /* Update existing element, though the map is full. */
94         key = 1;
95         assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == 0);
96         key = 2;
97         assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
98         key = 3;
99         assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) < 0 &&
100                errno == E2BIG);
101
102         /* Check that key = 0 doesn't exist. */
103         key = 0;
104         assert(bpf_map_delete_elem(fd, &key) < 0 && errno == ENOENT);
105
106         /* Iterate over two elements. */
107         assert(bpf_map_get_next_key(fd, NULL, &first_key) == 0 &&
108                (first_key == 1 || first_key == 2));
109         assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
110                (next_key == first_key));
111         assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
112                (next_key == 1 || next_key == 2) &&
113                (next_key != first_key));
114         assert(bpf_map_get_next_key(fd, &next_key, &next_key) < 0 &&
115                errno == ENOENT);
116
117         /* Delete both elements. */
118         key = 1;
119         assert(bpf_map_delete_elem(fd, &key) == 0);
120         key = 2;
121         assert(bpf_map_delete_elem(fd, &key) == 0);
122         assert(bpf_map_delete_elem(fd, &key) < 0 && errno == ENOENT);
123
124         key = 0;
125         /* Check that map is empty. */
126         assert(bpf_map_get_next_key(fd, NULL, &next_key) < 0 &&
127                errno == ENOENT);
128         assert(bpf_map_get_next_key(fd, &key, &next_key) < 0 &&
129                errno == ENOENT);
130
131         close(fd);
132 }
133
134 static void test_hashmap_sizes(unsigned int task, void *data)
135 {
136         int fd, i, j;
137
138         for (i = 1; i <= 512; i <<= 1)
139                 for (j = 1; j <= 1 << 18; j <<= 1) {
140                         fd = bpf_create_map(BPF_MAP_TYPE_HASH, i, j,
141                                             2, map_flags);
142                         if (fd < 0) {
143                                 if (errno == ENOMEM)
144                                         return;
145                                 printf("Failed to create hashmap key=%d value=%d '%s'\n",
146                                        i, j, strerror(errno));
147                                 exit(1);
148                         }
149                         close(fd);
150                         usleep(10); /* give kernel time to destroy */
151                 }
152 }
153
154 static void test_hashmap_percpu(unsigned int task, void *data)
155 {
156         unsigned int nr_cpus = bpf_num_possible_cpus();
157         BPF_DECLARE_PERCPU(long, value);
158         long long key, next_key, first_key;
159         int expected_key_mask = 0;
160         int fd, i;
161
162         fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_HASH, sizeof(key),
163                             sizeof(bpf_percpu(value, 0)), 2, map_flags);
164         if (fd < 0) {
165                 printf("Failed to create hashmap '%s'!\n", strerror(errno));
166                 exit(1);
167         }
168
169         for (i = 0; i < nr_cpus; i++)
170                 bpf_percpu(value, i) = i + 100;
171
172         key = 1;
173         /* Insert key=1 element. */
174         assert(!(expected_key_mask & key));
175         assert(bpf_map_update_elem(fd, &key, value, BPF_ANY) == 0);
176
177         /* Lookup and delete elem key=1 and check value. */
178         assert(bpf_map_lookup_and_delete_elem(fd, &key, value) == 0 &&
179                bpf_percpu(value,0) == 100);
180
181         for (i = 0; i < nr_cpus; i++)
182                 bpf_percpu(value,i) = i + 100;
183
184         /* Insert key=1 element which should not exist. */
185         assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) == 0);
186         expected_key_mask |= key;
187
188         /* BPF_NOEXIST means add new element if it doesn't exist. */
189         assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) < 0 &&
190                /* key=1 already exists. */
191                errno == EEXIST);
192
193         /* -1 is an invalid flag. */
194         assert(bpf_map_update_elem(fd, &key, value, -1) < 0 &&
195                errno == EINVAL);
196
197         /* Check that key=1 can be found. Value could be 0 if the lookup
198          * was run from a different CPU.
199          */
200         bpf_percpu(value, 0) = 1;
201         assert(bpf_map_lookup_elem(fd, &key, value) == 0 &&
202                bpf_percpu(value, 0) == 100);
203
204         key = 2;
205         /* Check that key=2 is not found. */
206         assert(bpf_map_lookup_elem(fd, &key, value) < 0 && errno == ENOENT);
207
208         /* BPF_EXIST means update existing element. */
209         assert(bpf_map_update_elem(fd, &key, value, BPF_EXIST) < 0 &&
210                /* key=2 is not there. */
211                errno == ENOENT);
212
213         /* Insert key=2 element. */
214         assert(!(expected_key_mask & key));
215         assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) == 0);
216         expected_key_mask |= key;
217
218         /* key=1 and key=2 were inserted, check that key=0 cannot be
219          * inserted due to max_entries limit.
220          */
221         key = 0;
222         assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) < 0 &&
223                errno == E2BIG);
224
225         /* Check that key = 0 doesn't exist. */
226         assert(bpf_map_delete_elem(fd, &key) < 0 && errno == ENOENT);
227
228         /* Iterate over two elements. */
229         assert(bpf_map_get_next_key(fd, NULL, &first_key) == 0 &&
230                ((expected_key_mask & first_key) == first_key));
231         while (!bpf_map_get_next_key(fd, &key, &next_key)) {
232                 if (first_key) {
233                         assert(next_key == first_key);
234                         first_key = 0;
235                 }
236                 assert((expected_key_mask & next_key) == next_key);
237                 expected_key_mask &= ~next_key;
238
239                 assert(bpf_map_lookup_elem(fd, &next_key, value) == 0);
240
241                 for (i = 0; i < nr_cpus; i++)
242                         assert(bpf_percpu(value, i) == i + 100);
243
244                 key = next_key;
245         }
246         assert(errno == ENOENT);
247
248         /* Update with BPF_EXIST. */
249         key = 1;
250         assert(bpf_map_update_elem(fd, &key, value, BPF_EXIST) == 0);
251
252         /* Delete both elements. */
253         key = 1;
254         assert(bpf_map_delete_elem(fd, &key) == 0);
255         key = 2;
256         assert(bpf_map_delete_elem(fd, &key) == 0);
257         assert(bpf_map_delete_elem(fd, &key) < 0 && errno == ENOENT);
258
259         key = 0;
260         /* Check that map is empty. */
261         assert(bpf_map_get_next_key(fd, NULL, &next_key) < 0 &&
262                errno == ENOENT);
263         assert(bpf_map_get_next_key(fd, &key, &next_key) < 0 &&
264                errno == ENOENT);
265
266         close(fd);
267 }
268
269 static int helper_fill_hashmap(int max_entries)
270 {
271         int i, fd, ret;
272         long long key, value;
273
274         fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
275                             max_entries, map_flags);
276         CHECK(fd < 0,
277               "failed to create hashmap",
278               "err: %s, flags: 0x%x\n", strerror(errno), map_flags);
279
280         for (i = 0; i < max_entries; i++) {
281                 key = i; value = key;
282                 ret = bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST);
283                 CHECK(ret != 0,
284                       "can't update hashmap",
285                       "err: %s\n", strerror(ret));
286         }
287
288         return fd;
289 }
290
291 static void test_hashmap_walk(unsigned int task, void *data)
292 {
293         int fd, i, max_entries = 1000;
294         long long key, value, next_key;
295         bool next_key_valid = true;
296
297         fd = helper_fill_hashmap(max_entries);
298
299         for (i = 0; bpf_map_get_next_key(fd, !i ? NULL : &key,
300                                          &next_key) == 0; i++) {
301                 key = next_key;
302                 assert(bpf_map_lookup_elem(fd, &key, &value) == 0);
303         }
304
305         assert(i == max_entries);
306
307         assert(bpf_map_get_next_key(fd, NULL, &key) == 0);
308         for (i = 0; next_key_valid; i++) {
309                 next_key_valid = bpf_map_get_next_key(fd, &key, &next_key) == 0;
310                 assert(bpf_map_lookup_elem(fd, &key, &value) == 0);
311                 value++;
312                 assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == 0);
313                 key = next_key;
314         }
315
316         assert(i == max_entries);
317
318         for (i = 0; bpf_map_get_next_key(fd, !i ? NULL : &key,
319                                          &next_key) == 0; i++) {
320                 key = next_key;
321                 assert(bpf_map_lookup_elem(fd, &key, &value) == 0);
322                 assert(value - 1 == key);
323         }
324
325         assert(i == max_entries);
326         close(fd);
327 }
328
329 static void test_hashmap_zero_seed(void)
330 {
331         int i, first, second, old_flags;
332         long long key, next_first, next_second;
333
334         old_flags = map_flags;
335         map_flags |= BPF_F_ZERO_SEED;
336
337         first = helper_fill_hashmap(3);
338         second = helper_fill_hashmap(3);
339
340         for (i = 0; ; i++) {
341                 void *key_ptr = !i ? NULL : &key;
342
343                 if (bpf_map_get_next_key(first, key_ptr, &next_first) != 0)
344                         break;
345
346                 CHECK(bpf_map_get_next_key(second, key_ptr, &next_second) != 0,
347                       "next_key for second map must succeed",
348                       "key_ptr: %p", key_ptr);
349                 CHECK(next_first != next_second,
350                       "keys must match",
351                       "i: %d first: %lld second: %lld\n", i,
352                       next_first, next_second);
353
354                 key = next_first;
355         }
356
357         map_flags = old_flags;
358         close(first);
359         close(second);
360 }
361
362 static void test_arraymap(unsigned int task, void *data)
363 {
364         int key, next_key, fd;
365         long long value;
366
367         fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(key), sizeof(value),
368                             2, 0);
369         if (fd < 0) {
370                 printf("Failed to create arraymap '%s'!\n", strerror(errno));
371                 exit(1);
372         }
373
374         key = 1;
375         value = 1234;
376         /* Insert key=1 element. */
377         assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
378
379         value = 0;
380         assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) < 0 &&
381                errno == EEXIST);
382
383         /* Check that key=1 can be found. */
384         assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 1234);
385
386         key = 0;
387         /* Check that key=0 is also found and zero initialized. */
388         assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 0);
389
390         /* key=0 and key=1 were inserted, check that key=2 cannot be inserted
391          * due to max_entries limit.
392          */
393         key = 2;
394         assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) < 0 &&
395                errno == E2BIG);
396
397         /* Check that key = 2 doesn't exist. */
398         assert(bpf_map_lookup_elem(fd, &key, &value) < 0 && errno == ENOENT);
399
400         /* Iterate over two elements. */
401         assert(bpf_map_get_next_key(fd, NULL, &next_key) == 0 &&
402                next_key == 0);
403         assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
404                next_key == 0);
405         assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
406                next_key == 1);
407         assert(bpf_map_get_next_key(fd, &next_key, &next_key) < 0 &&
408                errno == ENOENT);
409
410         /* Delete shouldn't succeed. */
411         key = 1;
412         assert(bpf_map_delete_elem(fd, &key) < 0 && errno == EINVAL);
413
414         close(fd);
415 }
416
417 static void test_arraymap_percpu(unsigned int task, void *data)
418 {
419         unsigned int nr_cpus = bpf_num_possible_cpus();
420         BPF_DECLARE_PERCPU(long, values);
421         int key, next_key, fd, i;
422
423         fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_ARRAY, sizeof(key),
424                             sizeof(bpf_percpu(values, 0)), 2, 0);
425         if (fd < 0) {
426                 printf("Failed to create arraymap '%s'!\n", strerror(errno));
427                 exit(1);
428         }
429
430         for (i = 0; i < nr_cpus; i++)
431                 bpf_percpu(values, i) = i + 100;
432
433         key = 1;
434         /* Insert key=1 element. */
435         assert(bpf_map_update_elem(fd, &key, values, BPF_ANY) == 0);
436
437         bpf_percpu(values, 0) = 0;
438         assert(bpf_map_update_elem(fd, &key, values, BPF_NOEXIST) < 0 &&
439                errno == EEXIST);
440
441         /* Check that key=1 can be found. */
442         assert(bpf_map_lookup_elem(fd, &key, values) == 0 &&
443                bpf_percpu(values, 0) == 100);
444
445         key = 0;
446         /* Check that key=0 is also found and zero initialized. */
447         assert(bpf_map_lookup_elem(fd, &key, values) == 0 &&
448                bpf_percpu(values, 0) == 0 &&
449                bpf_percpu(values, nr_cpus - 1) == 0);
450
451         /* Check that key=2 cannot be inserted due to max_entries limit. */
452         key = 2;
453         assert(bpf_map_update_elem(fd, &key, values, BPF_EXIST) < 0 &&
454                errno == E2BIG);
455
456         /* Check that key = 2 doesn't exist. */
457         assert(bpf_map_lookup_elem(fd, &key, values) < 0 && errno == ENOENT);
458
459         /* Iterate over two elements. */
460         assert(bpf_map_get_next_key(fd, NULL, &next_key) == 0 &&
461                next_key == 0);
462         assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
463                next_key == 0);
464         assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
465                next_key == 1);
466         assert(bpf_map_get_next_key(fd, &next_key, &next_key) < 0 &&
467                errno == ENOENT);
468
469         /* Delete shouldn't succeed. */
470         key = 1;
471         assert(bpf_map_delete_elem(fd, &key) < 0 && errno == EINVAL);
472
473         close(fd);
474 }
475
476 static void test_arraymap_percpu_many_keys(void)
477 {
478         unsigned int nr_cpus = bpf_num_possible_cpus();
479         BPF_DECLARE_PERCPU(long, values);
480         /* nr_keys is not too large otherwise the test stresses percpu
481          * allocator more than anything else
482          */
483         unsigned int nr_keys = 2000;
484         int key, fd, i;
485
486         fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_ARRAY, sizeof(key),
487                             sizeof(bpf_percpu(values, 0)), nr_keys, 0);
488         if (fd < 0) {
489                 printf("Failed to create per-cpu arraymap '%s'!\n",
490                        strerror(errno));
491                 exit(1);
492         }
493
494         for (i = 0; i < nr_cpus; i++)
495                 bpf_percpu(values, i) = i + 10;
496
497         for (key = 0; key < nr_keys; key++)
498                 assert(bpf_map_update_elem(fd, &key, values, BPF_ANY) == 0);
499
500         for (key = 0; key < nr_keys; key++) {
501                 for (i = 0; i < nr_cpus; i++)
502                         bpf_percpu(values, i) = 0;
503
504                 assert(bpf_map_lookup_elem(fd, &key, values) == 0);
505
506                 for (i = 0; i < nr_cpus; i++)
507                         assert(bpf_percpu(values, i) == i + 10);
508         }
509
510         close(fd);
511 }
512
513 static void test_devmap(unsigned int task, void *data)
514 {
515         int fd;
516         __u32 key, value;
517
518         fd = bpf_create_map(BPF_MAP_TYPE_DEVMAP, sizeof(key), sizeof(value),
519                             2, 0);
520         if (fd < 0) {
521                 printf("Failed to create devmap '%s'!\n", strerror(errno));
522                 exit(1);
523         }
524
525         close(fd);
526 }
527
528 static void test_devmap_hash(unsigned int task, void *data)
529 {
530         int fd;
531         __u32 key, value;
532
533         fd = bpf_create_map(BPF_MAP_TYPE_DEVMAP_HASH, sizeof(key), sizeof(value),
534                             2, 0);
535         if (fd < 0) {
536                 printf("Failed to create devmap_hash '%s'!\n", strerror(errno));
537                 exit(1);
538         }
539
540         close(fd);
541 }
542
543 static void test_queuemap(unsigned int task, void *data)
544 {
545         const int MAP_SIZE = 32;
546         __u32 vals[MAP_SIZE + MAP_SIZE/2], val;
547         int fd, i;
548
549         /* Fill test values to be used */
550         for (i = 0; i < MAP_SIZE + MAP_SIZE/2; i++)
551                 vals[i] = rand();
552
553         /* Invalid key size */
554         fd = bpf_create_map(BPF_MAP_TYPE_QUEUE, 4, sizeof(val), MAP_SIZE,
555                             map_flags);
556         assert(fd < 0 && errno == EINVAL);
557
558         fd = bpf_create_map(BPF_MAP_TYPE_QUEUE, 0, sizeof(val), MAP_SIZE,
559                             map_flags);
560         /* Queue map does not support BPF_F_NO_PREALLOC */
561         if (map_flags & BPF_F_NO_PREALLOC) {
562                 assert(fd < 0 && errno == EINVAL);
563                 return;
564         }
565         if (fd < 0) {
566                 printf("Failed to create queuemap '%s'!\n", strerror(errno));
567                 exit(1);
568         }
569
570         /* Push MAP_SIZE elements */
571         for (i = 0; i < MAP_SIZE; i++)
572                 assert(bpf_map_update_elem(fd, NULL, &vals[i], 0) == 0);
573
574         /* Check that element cannot be pushed due to max_entries limit */
575         assert(bpf_map_update_elem(fd, NULL, &val, 0) < 0 &&
576                errno == E2BIG);
577
578         /* Peek element */
579         assert(bpf_map_lookup_elem(fd, NULL, &val) == 0 && val == vals[0]);
580
581         /* Replace half elements */
582         for (i = MAP_SIZE; i < MAP_SIZE + MAP_SIZE/2; i++)
583                 assert(bpf_map_update_elem(fd, NULL, &vals[i], BPF_EXIST) == 0);
584
585         /* Pop all elements */
586         for (i = MAP_SIZE/2; i < MAP_SIZE + MAP_SIZE/2; i++)
587                 assert(bpf_map_lookup_and_delete_elem(fd, NULL, &val) == 0 &&
588                        val == vals[i]);
589
590         /* Check that there are not elements left */
591         assert(bpf_map_lookup_and_delete_elem(fd, NULL, &val) < 0 &&
592                errno == ENOENT);
593
594         /* Check that non supported functions set errno to EINVAL */
595         assert(bpf_map_delete_elem(fd, NULL) < 0 && errno == EINVAL);
596         assert(bpf_map_get_next_key(fd, NULL, NULL) < 0 && errno == EINVAL);
597
598         close(fd);
599 }
600
601 static void test_stackmap(unsigned int task, void *data)
602 {
603         const int MAP_SIZE = 32;
604         __u32 vals[MAP_SIZE + MAP_SIZE/2], val;
605         int fd, i;
606
607         /* Fill test values to be used */
608         for (i = 0; i < MAP_SIZE + MAP_SIZE/2; i++)
609                 vals[i] = rand();
610
611         /* Invalid key size */
612         fd = bpf_create_map(BPF_MAP_TYPE_STACK, 4, sizeof(val), MAP_SIZE,
613                             map_flags);
614         assert(fd < 0 && errno == EINVAL);
615
616         fd = bpf_create_map(BPF_MAP_TYPE_STACK, 0, sizeof(val), MAP_SIZE,
617                             map_flags);
618         /* Stack map does not support BPF_F_NO_PREALLOC */
619         if (map_flags & BPF_F_NO_PREALLOC) {
620                 assert(fd < 0 && errno == EINVAL);
621                 return;
622         }
623         if (fd < 0) {
624                 printf("Failed to create stackmap '%s'!\n", strerror(errno));
625                 exit(1);
626         }
627
628         /* Push MAP_SIZE elements */
629         for (i = 0; i < MAP_SIZE; i++)
630                 assert(bpf_map_update_elem(fd, NULL, &vals[i], 0) == 0);
631
632         /* Check that element cannot be pushed due to max_entries limit */
633         assert(bpf_map_update_elem(fd, NULL, &val, 0) < 0 &&
634                errno == E2BIG);
635
636         /* Peek element */
637         assert(bpf_map_lookup_elem(fd, NULL, &val) == 0 && val == vals[i - 1]);
638
639         /* Replace half elements */
640         for (i = MAP_SIZE; i < MAP_SIZE + MAP_SIZE/2; i++)
641                 assert(bpf_map_update_elem(fd, NULL, &vals[i], BPF_EXIST) == 0);
642
643         /* Pop all elements */
644         for (i = MAP_SIZE + MAP_SIZE/2 - 1; i >= MAP_SIZE/2; i--)
645                 assert(bpf_map_lookup_and_delete_elem(fd, NULL, &val) == 0 &&
646                        val == vals[i]);
647
648         /* Check that there are not elements left */
649         assert(bpf_map_lookup_and_delete_elem(fd, NULL, &val) < 0 &&
650                errno == ENOENT);
651
652         /* Check that non supported functions set errno to EINVAL */
653         assert(bpf_map_delete_elem(fd, NULL) < 0 && errno == EINVAL);
654         assert(bpf_map_get_next_key(fd, NULL, NULL) < 0 && errno == EINVAL);
655
656         close(fd);
657 }
658
659 #include <sys/ioctl.h>
660 #include <arpa/inet.h>
661 #include <sys/select.h>
662 #include <linux/err.h>
663 #define SOCKMAP_PARSE_PROG "./sockmap_parse_prog.o"
664 #define SOCKMAP_VERDICT_PROG "./sockmap_verdict_prog.o"
665 #define SOCKMAP_TCP_MSG_PROG "./sockmap_tcp_msg_prog.o"
666 static void test_sockmap(unsigned int tasks, void *data)
667 {
668         struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_msg, *bpf_map_break;
669         int map_fd_msg = 0, map_fd_rx = 0, map_fd_tx = 0, map_fd_break;
670         int ports[] = {50200, 50201, 50202, 50204};
671         int err, i, fd, udp, sfd[6] = {0xdeadbeef};
672         u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0};
673         int parse_prog, verdict_prog, msg_prog;
674         struct sockaddr_in addr;
675         int one = 1, s, sc, rc;
676         struct bpf_object *obj;
677         struct timeval to;
678         __u32 key, value;
679         pid_t pid[tasks];
680         fd_set w;
681
682         /* Create some sockets to use with sockmap */
683         for (i = 0; i < 2; i++) {
684                 sfd[i] = socket(AF_INET, SOCK_STREAM, 0);
685                 if (sfd[i] < 0)
686                         goto out;
687                 err = setsockopt(sfd[i], SOL_SOCKET, SO_REUSEADDR,
688                                  (char *)&one, sizeof(one));
689                 if (err) {
690                         printf("failed to setsockopt\n");
691                         goto out;
692                 }
693                 err = ioctl(sfd[i], FIONBIO, (char *)&one);
694                 if (err < 0) {
695                         printf("failed to ioctl\n");
696                         goto out;
697                 }
698                 memset(&addr, 0, sizeof(struct sockaddr_in));
699                 addr.sin_family = AF_INET;
700                 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
701                 addr.sin_port = htons(ports[i]);
702                 err = bind(sfd[i], (struct sockaddr *)&addr, sizeof(addr));
703                 if (err < 0) {
704                         printf("failed to bind: err %i: %i:%i\n",
705                                err, i, sfd[i]);
706                         goto out;
707                 }
708                 err = listen(sfd[i], 32);
709                 if (err < 0) {
710                         printf("failed to listen\n");
711                         goto out;
712                 }
713         }
714
715         for (i = 2; i < 4; i++) {
716                 sfd[i] = socket(AF_INET, SOCK_STREAM, 0);
717                 if (sfd[i] < 0)
718                         goto out;
719                 err = setsockopt(sfd[i], SOL_SOCKET, SO_REUSEADDR,
720                                  (char *)&one, sizeof(one));
721                 if (err) {
722                         printf("set sock opt\n");
723                         goto out;
724                 }
725                 memset(&addr, 0, sizeof(struct sockaddr_in));
726                 addr.sin_family = AF_INET;
727                 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
728                 addr.sin_port = htons(ports[i - 2]);
729                 err = connect(sfd[i], (struct sockaddr *)&addr, sizeof(addr));
730                 if (err) {
731                         printf("failed to connect\n");
732                         goto out;
733                 }
734         }
735
736
737         for (i = 4; i < 6; i++) {
738                 sfd[i] = accept(sfd[i - 4], NULL, NULL);
739                 if (sfd[i] < 0) {
740                         printf("accept failed\n");
741                         goto out;
742                 }
743         }
744
745         /* Test sockmap with connected sockets */
746         fd = bpf_create_map(BPF_MAP_TYPE_SOCKMAP,
747                             sizeof(key), sizeof(value),
748                             6, 0);
749         if (fd < 0) {
750                 if (!bpf_probe_map_type(BPF_MAP_TYPE_SOCKMAP, 0)) {
751                         printf("%s SKIP (unsupported map type BPF_MAP_TYPE_SOCKMAP)\n",
752                                __func__);
753                         skips++;
754                         for (i = 0; i < 6; i++)
755                                 close(sfd[i]);
756                         return;
757                 }
758
759                 printf("Failed to create sockmap %i\n", fd);
760                 goto out_sockmap;
761         }
762
763         /* Test update with unsupported UDP socket */
764         udp = socket(AF_INET, SOCK_DGRAM, 0);
765         i = 0;
766         err = bpf_map_update_elem(fd, &i, &udp, BPF_ANY);
767         if (err) {
768                 printf("Failed socket update SOCK_DGRAM '%i:%i'\n",
769                        i, udp);
770                 goto out_sockmap;
771         }
772
773         /* Test update without programs */
774         for (i = 0; i < 6; i++) {
775                 err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
776                 if (err) {
777                         printf("Failed noprog update sockmap '%i:%i'\n",
778                                i, sfd[i]);
779                         goto out_sockmap;
780                 }
781         }
782
783         /* Test attaching/detaching bad fds */
784         err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_PARSER, 0);
785         if (!err) {
786                 printf("Failed invalid parser prog attach\n");
787                 goto out_sockmap;
788         }
789
790         err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_VERDICT, 0);
791         if (!err) {
792                 printf("Failed invalid verdict prog attach\n");
793                 goto out_sockmap;
794         }
795
796         err = bpf_prog_attach(-1, fd, BPF_SK_MSG_VERDICT, 0);
797         if (!err) {
798                 printf("Failed invalid msg verdict prog attach\n");
799                 goto out_sockmap;
800         }
801
802         err = bpf_prog_attach(-1, fd, __MAX_BPF_ATTACH_TYPE, 0);
803         if (!err) {
804                 printf("Failed unknown prog attach\n");
805                 goto out_sockmap;
806         }
807
808         err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_PARSER);
809         if (!err) {
810                 printf("Failed empty parser prog detach\n");
811                 goto out_sockmap;
812         }
813
814         err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_VERDICT);
815         if (!err) {
816                 printf("Failed empty verdict prog detach\n");
817                 goto out_sockmap;
818         }
819
820         err = bpf_prog_detach(fd, BPF_SK_MSG_VERDICT);
821         if (!err) {
822                 printf("Failed empty msg verdict prog detach\n");
823                 goto out_sockmap;
824         }
825
826         err = bpf_prog_detach(fd, __MAX_BPF_ATTACH_TYPE);
827         if (!err) {
828                 printf("Detach invalid prog successful\n");
829                 goto out_sockmap;
830         }
831
832         /* Load SK_SKB program and Attach */
833         err = bpf_prog_load(SOCKMAP_PARSE_PROG,
834                             BPF_PROG_TYPE_SK_SKB, &obj, &parse_prog);
835         if (err) {
836                 printf("Failed to load SK_SKB parse prog\n");
837                 goto out_sockmap;
838         }
839
840         err = bpf_prog_load(SOCKMAP_TCP_MSG_PROG,
841                             BPF_PROG_TYPE_SK_MSG, &obj, &msg_prog);
842         if (err) {
843                 printf("Failed to load SK_SKB msg prog\n");
844                 goto out_sockmap;
845         }
846
847         err = bpf_prog_load(SOCKMAP_VERDICT_PROG,
848                             BPF_PROG_TYPE_SK_SKB, &obj, &verdict_prog);
849         if (err) {
850                 printf("Failed to load SK_SKB verdict prog\n");
851                 goto out_sockmap;
852         }
853
854         bpf_map_rx = bpf_object__find_map_by_name(obj, "sock_map_rx");
855         if (!bpf_map_rx) {
856                 printf("Failed to load map rx from verdict prog\n");
857                 goto out_sockmap;
858         }
859
860         map_fd_rx = bpf_map__fd(bpf_map_rx);
861         if (map_fd_rx < 0) {
862                 printf("Failed to get map rx fd\n");
863                 goto out_sockmap;
864         }
865
866         bpf_map_tx = bpf_object__find_map_by_name(obj, "sock_map_tx");
867         if (!bpf_map_tx) {
868                 printf("Failed to load map tx from verdict prog\n");
869                 goto out_sockmap;
870         }
871
872         map_fd_tx = bpf_map__fd(bpf_map_tx);
873         if (map_fd_tx < 0) {
874                 printf("Failed to get map tx fd\n");
875                 goto out_sockmap;
876         }
877
878         bpf_map_msg = bpf_object__find_map_by_name(obj, "sock_map_msg");
879         if (!bpf_map_msg) {
880                 printf("Failed to load map msg from msg_verdict prog\n");
881                 goto out_sockmap;
882         }
883
884         map_fd_msg = bpf_map__fd(bpf_map_msg);
885         if (map_fd_msg < 0) {
886                 printf("Failed to get map msg fd\n");
887                 goto out_sockmap;
888         }
889
890         bpf_map_break = bpf_object__find_map_by_name(obj, "sock_map_break");
891         if (!bpf_map_break) {
892                 printf("Failed to load map tx from verdict prog\n");
893                 goto out_sockmap;
894         }
895
896         map_fd_break = bpf_map__fd(bpf_map_break);
897         if (map_fd_break < 0) {
898                 printf("Failed to get map tx fd\n");
899                 goto out_sockmap;
900         }
901
902         err = bpf_prog_attach(parse_prog, map_fd_break,
903                               BPF_SK_SKB_STREAM_PARSER, 0);
904         if (!err) {
905                 printf("Allowed attaching SK_SKB program to invalid map\n");
906                 goto out_sockmap;
907         }
908
909         err = bpf_prog_attach(parse_prog, map_fd_rx,
910                       BPF_SK_SKB_STREAM_PARSER, 0);
911         if (err) {
912                 printf("Failed stream parser bpf prog attach\n");
913                 goto out_sockmap;
914         }
915
916         err = bpf_prog_attach(verdict_prog, map_fd_rx,
917                               BPF_SK_SKB_STREAM_VERDICT, 0);
918         if (err) {
919                 printf("Failed stream verdict bpf prog attach\n");
920                 goto out_sockmap;
921         }
922
923         err = bpf_prog_attach(msg_prog, map_fd_msg, BPF_SK_MSG_VERDICT, 0);
924         if (err) {
925                 printf("Failed msg verdict bpf prog attach\n");
926                 goto out_sockmap;
927         }
928
929         err = bpf_prog_attach(verdict_prog, map_fd_rx,
930                               __MAX_BPF_ATTACH_TYPE, 0);
931         if (!err) {
932                 printf("Attached unknown bpf prog\n");
933                 goto out_sockmap;
934         }
935
936         /* Test map update elem afterwards fd lives in fd and map_fd */
937         for (i = 2; i < 6; i++) {
938                 err = bpf_map_update_elem(map_fd_rx, &i, &sfd[i], BPF_ANY);
939                 if (err) {
940                         printf("Failed map_fd_rx update sockmap %i '%i:%i'\n",
941                                err, i, sfd[i]);
942                         goto out_sockmap;
943                 }
944                 err = bpf_map_update_elem(map_fd_tx, &i, &sfd[i], BPF_ANY);
945                 if (err) {
946                         printf("Failed map_fd_tx update sockmap %i '%i:%i'\n",
947                                err, i, sfd[i]);
948                         goto out_sockmap;
949                 }
950         }
951
952         /* Test map delete elem and remove send/recv sockets */
953         for (i = 2; i < 4; i++) {
954                 err = bpf_map_delete_elem(map_fd_rx, &i);
955                 if (err) {
956                         printf("Failed delete sockmap rx %i '%i:%i'\n",
957                                err, i, sfd[i]);
958                         goto out_sockmap;
959                 }
960                 err = bpf_map_delete_elem(map_fd_tx, &i);
961                 if (err) {
962                         printf("Failed delete sockmap tx %i '%i:%i'\n",
963                                err, i, sfd[i]);
964                         goto out_sockmap;
965                 }
966         }
967
968         /* Put sfd[2] (sending fd below) into msg map to test sendmsg bpf */
969         i = 0;
970         err = bpf_map_update_elem(map_fd_msg, &i, &sfd[2], BPF_ANY);
971         if (err) {
972                 printf("Failed map_fd_msg update sockmap %i\n", err);
973                 goto out_sockmap;
974         }
975
976         /* Test map send/recv */
977         for (i = 0; i < 2; i++) {
978                 buf[0] = i;
979                 buf[1] = 0x5;
980                 sc = send(sfd[2], buf, 20, 0);
981                 if (sc < 0) {
982                         printf("Failed sockmap send\n");
983                         goto out_sockmap;
984                 }
985
986                 FD_ZERO(&w);
987                 FD_SET(sfd[3], &w);
988                 to.tv_sec = 1;
989                 to.tv_usec = 0;
990                 s = select(sfd[3] + 1, &w, NULL, NULL, &to);
991                 if (s == -1) {
992                         perror("Failed sockmap select()");
993                         goto out_sockmap;
994                 } else if (!s) {
995                         printf("Failed sockmap unexpected timeout\n");
996                         goto out_sockmap;
997                 }
998
999                 if (!FD_ISSET(sfd[3], &w)) {
1000                         printf("Failed sockmap select/recv\n");
1001                         goto out_sockmap;
1002                 }
1003
1004                 rc = recv(sfd[3], buf, sizeof(buf), 0);
1005                 if (rc < 0) {
1006                         printf("Failed sockmap recv\n");
1007                         goto out_sockmap;
1008                 }
1009         }
1010
1011         /* Negative null entry lookup from datapath should be dropped */
1012         buf[0] = 1;
1013         buf[1] = 12;
1014         sc = send(sfd[2], buf, 20, 0);
1015         if (sc < 0) {
1016                 printf("Failed sockmap send\n");
1017                 goto out_sockmap;
1018         }
1019
1020         /* Push fd into same slot */
1021         i = 2;
1022         err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST);
1023         if (!err) {
1024                 printf("Failed allowed sockmap dup slot BPF_NOEXIST\n");
1025                 goto out_sockmap;
1026         }
1027
1028         err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
1029         if (err) {
1030                 printf("Failed sockmap update new slot BPF_ANY\n");
1031                 goto out_sockmap;
1032         }
1033
1034         err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST);
1035         if (err) {
1036                 printf("Failed sockmap update new slot BPF_EXIST\n");
1037                 goto out_sockmap;
1038         }
1039
1040         /* Delete the elems without programs */
1041         for (i = 2; i < 6; i++) {
1042                 err = bpf_map_delete_elem(fd, &i);
1043                 if (err) {
1044                         printf("Failed delete sockmap %i '%i:%i'\n",
1045                                err, i, sfd[i]);
1046                 }
1047         }
1048
1049         /* Test having multiple maps open and set with programs on same fds */
1050         err = bpf_prog_attach(parse_prog, fd,
1051                               BPF_SK_SKB_STREAM_PARSER, 0);
1052         if (err) {
1053                 printf("Failed fd bpf parse prog attach\n");
1054                 goto out_sockmap;
1055         }
1056         err = bpf_prog_attach(verdict_prog, fd,
1057                               BPF_SK_SKB_STREAM_VERDICT, 0);
1058         if (err) {
1059                 printf("Failed fd bpf verdict prog attach\n");
1060                 goto out_sockmap;
1061         }
1062
1063         for (i = 4; i < 6; i++) {
1064                 err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
1065                 if (!err) {
1066                         printf("Failed allowed duplicate programs in update ANY sockmap %i '%i:%i'\n",
1067                                err, i, sfd[i]);
1068                         goto out_sockmap;
1069                 }
1070                 err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST);
1071                 if (!err) {
1072                         printf("Failed allowed duplicate program in update NOEXIST sockmap  %i '%i:%i'\n",
1073                                err, i, sfd[i]);
1074                         goto out_sockmap;
1075                 }
1076                 err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST);
1077                 if (!err) {
1078                         printf("Failed allowed duplicate program in update EXIST sockmap  %i '%i:%i'\n",
1079                                err, i, sfd[i]);
1080                         goto out_sockmap;
1081                 }
1082         }
1083
1084         /* Test tasks number of forked operations */
1085         for (i = 0; i < tasks; i++) {
1086                 pid[i] = fork();
1087                 if (pid[i] == 0) {
1088                         for (i = 0; i < 6; i++) {
1089                                 bpf_map_delete_elem(map_fd_tx, &i);
1090                                 bpf_map_delete_elem(map_fd_rx, &i);
1091                                 bpf_map_update_elem(map_fd_tx, &i,
1092                                                     &sfd[i], BPF_ANY);
1093                                 bpf_map_update_elem(map_fd_rx, &i,
1094                                                     &sfd[i], BPF_ANY);
1095                         }
1096                         exit(0);
1097                 } else if (pid[i] == -1) {
1098                         printf("Couldn't spawn #%d process!\n", i);
1099                         exit(1);
1100                 }
1101         }
1102
1103         for (i = 0; i < tasks; i++) {
1104                 int status;
1105
1106                 assert(waitpid(pid[i], &status, 0) == pid[i]);
1107                 assert(status == 0);
1108         }
1109
1110         err = bpf_prog_detach2(parse_prog, map_fd_rx, __MAX_BPF_ATTACH_TYPE);
1111         if (!err) {
1112                 printf("Detached an invalid prog type.\n");
1113                 goto out_sockmap;
1114         }
1115
1116         err = bpf_prog_detach2(parse_prog, map_fd_rx, BPF_SK_SKB_STREAM_PARSER);
1117         if (err) {
1118                 printf("Failed parser prog detach\n");
1119                 goto out_sockmap;
1120         }
1121
1122         err = bpf_prog_detach2(verdict_prog, map_fd_rx, BPF_SK_SKB_STREAM_VERDICT);
1123         if (err) {
1124                 printf("Failed parser prog detach\n");
1125                 goto out_sockmap;
1126         }
1127
1128         /* Test map close sockets and empty maps */
1129         for (i = 0; i < 6; i++) {
1130                 bpf_map_delete_elem(map_fd_tx, &i);
1131                 bpf_map_delete_elem(map_fd_rx, &i);
1132                 close(sfd[i]);
1133         }
1134         close(fd);
1135         close(map_fd_rx);
1136         bpf_object__close(obj);
1137         return;
1138 out:
1139         for (i = 0; i < 6; i++)
1140                 close(sfd[i]);
1141         printf("Failed to create sockmap '%i:%s'!\n", i, strerror(errno));
1142         exit(1);
1143 out_sockmap:
1144         for (i = 0; i < 6; i++) {
1145                 if (map_fd_tx)
1146                         bpf_map_delete_elem(map_fd_tx, &i);
1147                 if (map_fd_rx)
1148                         bpf_map_delete_elem(map_fd_rx, &i);
1149                 close(sfd[i]);
1150         }
1151         close(fd);
1152         exit(1);
1153 }
1154
1155 #define MAPINMAP_PROG "./test_map_in_map.o"
1156 #define MAPINMAP_INVALID_PROG "./test_map_in_map_invalid.o"
1157 static void test_map_in_map(void)
1158 {
1159         struct bpf_object *obj;
1160         struct bpf_map *map;
1161         int mim_fd, fd, err;
1162         int pos = 0;
1163         struct bpf_map_info info = {};
1164         __u32 len = sizeof(info);
1165         __u32 id = 0;
1166         libbpf_print_fn_t old_print_fn;
1167
1168         obj = bpf_object__open(MAPINMAP_PROG);
1169
1170         fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(int), sizeof(int),
1171                             2, 0);
1172         if (fd < 0) {
1173                 printf("Failed to create hashmap '%s'!\n", strerror(errno));
1174                 exit(1);
1175         }
1176
1177         map = bpf_object__find_map_by_name(obj, "mim_array");
1178         if (!map) {
1179                 printf("Failed to load array of maps from test prog\n");
1180                 goto out_map_in_map;
1181         }
1182         err = bpf_map__set_inner_map_fd(map, fd);
1183         if (err) {
1184                 printf("Failed to set inner_map_fd for array of maps\n");
1185                 goto out_map_in_map;
1186         }
1187
1188         map = bpf_object__find_map_by_name(obj, "mim_hash");
1189         if (!map) {
1190                 printf("Failed to load hash of maps from test prog\n");
1191                 goto out_map_in_map;
1192         }
1193         err = bpf_map__set_inner_map_fd(map, fd);
1194         if (err) {
1195                 printf("Failed to set inner_map_fd for hash of maps\n");
1196                 goto out_map_in_map;
1197         }
1198
1199         bpf_object__load(obj);
1200
1201         map = bpf_object__find_map_by_name(obj, "mim_array");
1202         if (!map) {
1203                 printf("Failed to load array of maps from test prog\n");
1204                 goto out_map_in_map;
1205         }
1206         mim_fd = bpf_map__fd(map);
1207         if (mim_fd < 0) {
1208                 printf("Failed to get descriptor for array of maps\n");
1209                 goto out_map_in_map;
1210         }
1211
1212         err = bpf_map_update_elem(mim_fd, &pos, &fd, 0);
1213         if (err) {
1214                 printf("Failed to update array of maps\n");
1215                 goto out_map_in_map;
1216         }
1217
1218         map = bpf_object__find_map_by_name(obj, "mim_hash");
1219         if (!map) {
1220                 printf("Failed to load hash of maps from test prog\n");
1221                 goto out_map_in_map;
1222         }
1223         mim_fd = bpf_map__fd(map);
1224         if (mim_fd < 0) {
1225                 printf("Failed to get descriptor for hash of maps\n");
1226                 goto out_map_in_map;
1227         }
1228
1229         err = bpf_map_update_elem(mim_fd, &pos, &fd, 0);
1230         if (err) {
1231                 printf("Failed to update hash of maps\n");
1232                 goto out_map_in_map;
1233         }
1234
1235         close(fd);
1236         fd = -1;
1237         bpf_object__close(obj);
1238
1239         /* Test that failing bpf_object__create_map() destroys the inner map */
1240         obj = bpf_object__open(MAPINMAP_INVALID_PROG);
1241         err = libbpf_get_error(obj);
1242         if (err) {
1243                 printf("Failed to load %s program: %d %d",
1244                        MAPINMAP_INVALID_PROG, err, errno);
1245                 goto out_map_in_map;
1246         }
1247
1248         map = bpf_object__find_map_by_name(obj, "mim");
1249         if (!map) {
1250                 printf("Failed to load array of maps from test prog\n");
1251                 goto out_map_in_map;
1252         }
1253
1254         old_print_fn = libbpf_set_print(NULL);
1255
1256         err = bpf_object__load(obj);
1257         if (!err) {
1258                 printf("Loading obj supposed to fail\n");
1259                 goto out_map_in_map;
1260         }
1261
1262         libbpf_set_print(old_print_fn);
1263
1264         /* Iterate over all maps to check whether the internal map
1265          * ("mim.internal") has been destroyed.
1266          */
1267         while (true) {
1268                 err = bpf_map_get_next_id(id, &id);
1269                 if (err) {
1270                         if (errno == ENOENT)
1271                                 break;
1272                         printf("Failed to get next map: %d", errno);
1273                         goto out_map_in_map;
1274                 }
1275
1276                 fd = bpf_map_get_fd_by_id(id);
1277                 if (fd < 0) {
1278                         if (errno == ENOENT)
1279                                 continue;
1280                         printf("Failed to get map by id %u: %d", id, errno);
1281                         goto out_map_in_map;
1282                 }
1283
1284                 err = bpf_obj_get_info_by_fd(fd, &info, &len);
1285                 if (err) {
1286                         printf("Failed to get map info by fd %d: %d", fd,
1287                                errno);
1288                         goto out_map_in_map;
1289                 }
1290
1291                 if (!strcmp(info.name, "mim.inner")) {
1292                         printf("Inner map mim.inner was not destroyed\n");
1293                         goto out_map_in_map;
1294                 }
1295         }
1296
1297         return;
1298
1299 out_map_in_map:
1300         if (fd >= 0)
1301                 close(fd);
1302         exit(1);
1303 }
1304
1305 #define MAP_SIZE (32 * 1024)
1306
1307 static void test_map_large(void)
1308 {
1309
1310         struct bigkey {
1311                 int a;
1312                 char b[4096];
1313                 long long c;
1314         } key;
1315         int fd, i, value;
1316
1317         fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
1318                             MAP_SIZE, map_flags);
1319         if (fd < 0) {
1320                 printf("Failed to create large map '%s'!\n", strerror(errno));
1321                 exit(1);
1322         }
1323
1324         for (i = 0; i < MAP_SIZE; i++) {
1325                 key = (struct bigkey) { .c = i };
1326                 value = i;
1327
1328                 assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == 0);
1329         }
1330
1331         key.c = -1;
1332         assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) < 0 &&
1333                errno == E2BIG);
1334
1335         /* Iterate through all elements. */
1336         assert(bpf_map_get_next_key(fd, NULL, &key) == 0);
1337         key.c = -1;
1338         for (i = 0; i < MAP_SIZE; i++)
1339                 assert(bpf_map_get_next_key(fd, &key, &key) == 0);
1340         assert(bpf_map_get_next_key(fd, &key, &key) < 0 && errno == ENOENT);
1341
1342         key.c = 0;
1343         assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 0);
1344         key.a = 1;
1345         assert(bpf_map_lookup_elem(fd, &key, &value) < 0 && errno == ENOENT);
1346
1347         close(fd);
1348 }
1349
1350 #define run_parallel(N, FN, DATA) \
1351         printf("Fork %u tasks to '" #FN "'\n", N); \
1352         __run_parallel(N, FN, DATA)
1353
1354 static void __run_parallel(unsigned int tasks,
1355                            void (*fn)(unsigned int task, void *data),
1356                            void *data)
1357 {
1358         pid_t pid[tasks];
1359         int i;
1360
1361         fflush(stdout);
1362
1363         for (i = 0; i < tasks; i++) {
1364                 pid[i] = fork();
1365                 if (pid[i] == 0) {
1366                         fn(i, data);
1367                         exit(0);
1368                 } else if (pid[i] == -1) {
1369                         printf("Couldn't spawn #%d process!\n", i);
1370                         exit(1);
1371                 }
1372         }
1373
1374         for (i = 0; i < tasks; i++) {
1375                 int status;
1376
1377                 assert(waitpid(pid[i], &status, 0) == pid[i]);
1378                 assert(status == 0);
1379         }
1380 }
1381
1382 static void test_map_stress(void)
1383 {
1384         run_parallel(100, test_hashmap, NULL);
1385         run_parallel(100, test_hashmap_percpu, NULL);
1386         run_parallel(100, test_hashmap_sizes, NULL);
1387         run_parallel(100, test_hashmap_walk, NULL);
1388
1389         run_parallel(100, test_arraymap, NULL);
1390         run_parallel(100, test_arraymap_percpu, NULL);
1391 }
1392
1393 #define TASKS 1024
1394
1395 #define DO_UPDATE 1
1396 #define DO_DELETE 0
1397
1398 #define MAP_RETRIES 20
1399
1400 static int map_update_retriable(int map_fd, const void *key, const void *value,
1401                                 int flags, int attempts)
1402 {
1403         while (bpf_map_update_elem(map_fd, key, value, flags)) {
1404                 if (!attempts || (errno != EAGAIN && errno != EBUSY))
1405                         return -errno;
1406
1407                 usleep(1);
1408                 attempts--;
1409         }
1410
1411         return 0;
1412 }
1413
1414 static int map_delete_retriable(int map_fd, const void *key, int attempts)
1415 {
1416         while (bpf_map_delete_elem(map_fd, key)) {
1417                 if (!attempts || (errno != EAGAIN && errno != EBUSY))
1418                         return -errno;
1419
1420                 usleep(1);
1421                 attempts--;
1422         }
1423
1424         return 0;
1425 }
1426
1427 static void test_update_delete(unsigned int fn, void *data)
1428 {
1429         int do_update = ((int *)data)[1];
1430         int fd = ((int *)data)[0];
1431         int i, key, value, err;
1432
1433         for (i = fn; i < MAP_SIZE; i += TASKS) {
1434                 key = value = i;
1435
1436                 if (do_update) {
1437                         err = map_update_retriable(fd, &key, &value, BPF_NOEXIST, MAP_RETRIES);
1438                         if (err)
1439                                 printf("error %d %d\n", err, errno);
1440                         assert(err == 0);
1441                         err = map_update_retriable(fd, &key, &value, BPF_EXIST, MAP_RETRIES);
1442                         if (err)
1443                                 printf("error %d %d\n", err, errno);
1444                         assert(err == 0);
1445                 } else {
1446                         err = map_delete_retriable(fd, &key, MAP_RETRIES);
1447                         if (err)
1448                                 printf("error %d %d\n", err, errno);
1449                         assert(err == 0);
1450                 }
1451         }
1452 }
1453
1454 static void test_map_parallel(void)
1455 {
1456         int i, fd, key = 0, value = 0;
1457         int data[2];
1458
1459         fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
1460                             MAP_SIZE, map_flags);
1461         if (fd < 0) {
1462                 printf("Failed to create map for parallel test '%s'!\n",
1463                        strerror(errno));
1464                 exit(1);
1465         }
1466
1467         /* Use the same fd in children to add elements to this map:
1468          * child_0 adds key=0, key=1024, key=2048, ...
1469          * child_1 adds key=1, key=1025, key=2049, ...
1470          * child_1023 adds key=1023, ...
1471          */
1472         data[0] = fd;
1473         data[1] = DO_UPDATE;
1474         run_parallel(TASKS, test_update_delete, data);
1475
1476         /* Check that key=0 is already there. */
1477         assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) < 0 &&
1478                errno == EEXIST);
1479
1480         /* Check that all elements were inserted. */
1481         assert(bpf_map_get_next_key(fd, NULL, &key) == 0);
1482         key = -1;
1483         for (i = 0; i < MAP_SIZE; i++)
1484                 assert(bpf_map_get_next_key(fd, &key, &key) == 0);
1485         assert(bpf_map_get_next_key(fd, &key, &key) < 0 && errno == ENOENT);
1486
1487         /* Another check for all elements */
1488         for (i = 0; i < MAP_SIZE; i++) {
1489                 key = MAP_SIZE - i - 1;
1490
1491                 assert(bpf_map_lookup_elem(fd, &key, &value) == 0 &&
1492                        value == key);
1493         }
1494
1495         /* Now let's delete all elemenets in parallel. */
1496         data[1] = DO_DELETE;
1497         run_parallel(TASKS, test_update_delete, data);
1498
1499         /* Nothing should be left. */
1500         key = -1;
1501         assert(bpf_map_get_next_key(fd, NULL, &key) < 0 && errno == ENOENT);
1502         assert(bpf_map_get_next_key(fd, &key, &key) < 0 && errno == ENOENT);
1503 }
1504
1505 static void test_map_rdonly(void)
1506 {
1507         int fd, key = 0, value = 0;
1508
1509         fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
1510                             MAP_SIZE, map_flags | BPF_F_RDONLY);
1511         if (fd < 0) {
1512                 printf("Failed to create map for read only test '%s'!\n",
1513                        strerror(errno));
1514                 exit(1);
1515         }
1516
1517         key = 1;
1518         value = 1234;
1519         /* Try to insert key=1 element. */
1520         assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) < 0 &&
1521                errno == EPERM);
1522
1523         /* Check that key=1 is not found. */
1524         assert(bpf_map_lookup_elem(fd, &key, &value) < 0 && errno == ENOENT);
1525         assert(bpf_map_get_next_key(fd, &key, &value) < 0 && errno == ENOENT);
1526
1527         close(fd);
1528 }
1529
1530 static void test_map_wronly_hash(void)
1531 {
1532         int fd, key = 0, value = 0;
1533
1534         fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
1535                             MAP_SIZE, map_flags | BPF_F_WRONLY);
1536         if (fd < 0) {
1537                 printf("Failed to create map for write only test '%s'!\n",
1538                        strerror(errno));
1539                 exit(1);
1540         }
1541
1542         key = 1;
1543         value = 1234;
1544         /* Insert key=1 element. */
1545         assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
1546
1547         /* Check that reading elements and keys from the map is not allowed. */
1548         assert(bpf_map_lookup_elem(fd, &key, &value) < 0 && errno == EPERM);
1549         assert(bpf_map_get_next_key(fd, &key, &value) < 0 && errno == EPERM);
1550
1551         close(fd);
1552 }
1553
1554 static void test_map_wronly_stack_or_queue(enum bpf_map_type map_type)
1555 {
1556         int fd, value = 0;
1557
1558         assert(map_type == BPF_MAP_TYPE_QUEUE ||
1559                map_type == BPF_MAP_TYPE_STACK);
1560         fd = bpf_create_map(map_type, 0, sizeof(value), MAP_SIZE,
1561                             map_flags | BPF_F_WRONLY);
1562         /* Stack/Queue maps do not support BPF_F_NO_PREALLOC */
1563         if (map_flags & BPF_F_NO_PREALLOC) {
1564                 assert(fd < 0 && errno == EINVAL);
1565                 return;
1566         }
1567         if (fd < 0) {
1568                 printf("Failed to create map '%s'!\n", strerror(errno));
1569                 exit(1);
1570         }
1571
1572         value = 1234;
1573         assert(bpf_map_update_elem(fd, NULL, &value, BPF_ANY) == 0);
1574
1575         /* Peek element should fail */
1576         assert(bpf_map_lookup_elem(fd, NULL, &value) < 0 && errno == EPERM);
1577
1578         /* Pop element should fail */
1579         assert(bpf_map_lookup_and_delete_elem(fd, NULL, &value) < 0 &&
1580                errno == EPERM);
1581
1582         close(fd);
1583 }
1584
1585 static void test_map_wronly(void)
1586 {
1587         test_map_wronly_hash();
1588         test_map_wronly_stack_or_queue(BPF_MAP_TYPE_STACK);
1589         test_map_wronly_stack_or_queue(BPF_MAP_TYPE_QUEUE);
1590 }
1591
1592 static void prepare_reuseport_grp(int type, int map_fd, size_t map_elem_size,
1593                                   __s64 *fds64, __u64 *sk_cookies,
1594                                   unsigned int n)
1595 {
1596         socklen_t optlen, addrlen;
1597         struct sockaddr_in6 s6;
1598         const __u32 index0 = 0;
1599         const int optval = 1;
1600         unsigned int i;
1601         u64 sk_cookie;
1602         void *value;
1603         __s32 fd32;
1604         __s64 fd64;
1605         int err;
1606
1607         s6.sin6_family = AF_INET6;
1608         s6.sin6_addr = in6addr_any;
1609         s6.sin6_port = 0;
1610         addrlen = sizeof(s6);
1611         optlen = sizeof(sk_cookie);
1612
1613         for (i = 0; i < n; i++) {
1614                 fd64 = socket(AF_INET6, type, 0);
1615                 CHECK(fd64 == -1, "socket()",
1616                       "sock_type:%d fd64:%lld errno:%d\n",
1617                       type, fd64, errno);
1618
1619                 err = setsockopt(fd64, SOL_SOCKET, SO_REUSEPORT,
1620                                  &optval, sizeof(optval));
1621                 CHECK(err == -1, "setsockopt(SO_REUSEPORT)",
1622                       "err:%d errno:%d\n", err, errno);
1623
1624                 /* reuseport_array does not allow unbound sk */
1625                 if (map_elem_size == sizeof(__u64))
1626                         value = &fd64;
1627                 else {
1628                         assert(map_elem_size == sizeof(__u32));
1629                         fd32 = (__s32)fd64;
1630                         value = &fd32;
1631                 }
1632                 err = bpf_map_update_elem(map_fd, &index0, value, BPF_ANY);
1633                 CHECK(err >= 0 || errno != EINVAL,
1634                       "reuseport array update unbound sk",
1635                       "sock_type:%d err:%d errno:%d\n",
1636                       type, err, errno);
1637
1638                 err = bind(fd64, (struct sockaddr *)&s6, sizeof(s6));
1639                 CHECK(err == -1, "bind()",
1640                       "sock_type:%d err:%d errno:%d\n", type, err, errno);
1641
1642                 if (i == 0) {
1643                         err = getsockname(fd64, (struct sockaddr *)&s6,
1644                                           &addrlen);
1645                         CHECK(err == -1, "getsockname()",
1646                               "sock_type:%d err:%d errno:%d\n",
1647                               type, err, errno);
1648                 }
1649
1650                 err = getsockopt(fd64, SOL_SOCKET, SO_COOKIE, &sk_cookie,
1651                                  &optlen);
1652                 CHECK(err == -1, "getsockopt(SO_COOKIE)",
1653                       "sock_type:%d err:%d errno:%d\n", type, err, errno);
1654
1655                 if (type == SOCK_STREAM) {
1656                         /*
1657                          * reuseport_array does not allow
1658                          * non-listening tcp sk.
1659                          */
1660                         err = bpf_map_update_elem(map_fd, &index0, value,
1661                                                   BPF_ANY);
1662                         CHECK(err >= 0 || errno != EINVAL,
1663                               "reuseport array update non-listening sk",
1664                               "sock_type:%d err:%d errno:%d\n",
1665                               type, err, errno);
1666                         err = listen(fd64, 0);
1667                         CHECK(err == -1, "listen()",
1668                               "sock_type:%d, err:%d errno:%d\n",
1669                               type, err, errno);
1670                 }
1671
1672                 fds64[i] = fd64;
1673                 sk_cookies[i] = sk_cookie;
1674         }
1675 }
1676
1677 static void test_reuseport_array(void)
1678 {
1679 #define REUSEPORT_FD_IDX(err, last) ({ (err) ? last : !last; })
1680
1681         const __u32 array_size = 4, index0 = 0, index3 = 3;
1682         int types[2] = { SOCK_STREAM, SOCK_DGRAM }, type;
1683         __u64 grpa_cookies[2], sk_cookie, map_cookie;
1684         __s64 grpa_fds64[2] = { -1, -1 }, fd64 = -1;
1685         const __u32 bad_index = array_size;
1686         int map_fd, err, t, f;
1687         __u32 fds_idx = 0;
1688         int fd;
1689
1690         map_fd = bpf_create_map(BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
1691                                 sizeof(__u32), sizeof(__u64), array_size, 0);
1692         CHECK(map_fd < 0, "reuseport array create",
1693               "map_fd:%d, errno:%d\n", map_fd, errno);
1694
1695         /* Test lookup/update/delete with invalid index */
1696         err = bpf_map_delete_elem(map_fd, &bad_index);
1697         CHECK(err >= 0 || errno != E2BIG, "reuseport array del >=max_entries",
1698               "err:%d errno:%d\n", err, errno);
1699
1700         err = bpf_map_update_elem(map_fd, &bad_index, &fd64, BPF_ANY);
1701         CHECK(err >= 0 || errno != E2BIG,
1702               "reuseport array update >=max_entries",
1703               "err:%d errno:%d\n", err, errno);
1704
1705         err = bpf_map_lookup_elem(map_fd, &bad_index, &map_cookie);
1706         CHECK(err >= 0 || errno != ENOENT,
1707               "reuseport array update >=max_entries",
1708               "err:%d errno:%d\n", err, errno);
1709
1710         /* Test lookup/delete non existence elem */
1711         err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1712         CHECK(err >= 0 || errno != ENOENT,
1713               "reuseport array lookup not-exist elem",
1714               "err:%d errno:%d\n", err, errno);
1715         err = bpf_map_delete_elem(map_fd, &index3);
1716         CHECK(err >= 0 || errno != ENOENT,
1717               "reuseport array del not-exist elem",
1718               "err:%d errno:%d\n", err, errno);
1719
1720         for (t = 0; t < ARRAY_SIZE(types); t++) {
1721                 type = types[t];
1722
1723                 prepare_reuseport_grp(type, map_fd, sizeof(__u64), grpa_fds64,
1724                                       grpa_cookies, ARRAY_SIZE(grpa_fds64));
1725
1726                 /* Test BPF_* update flags */
1727                 /* BPF_EXIST failure case */
1728                 err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1729                                           BPF_EXIST);
1730                 CHECK(err >= 0 || errno != ENOENT,
1731                       "reuseport array update empty elem BPF_EXIST",
1732                       "sock_type:%d err:%d errno:%d\n",
1733                       type, err, errno);
1734                 fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1735
1736                 /* BPF_NOEXIST success case */
1737                 err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1738                                           BPF_NOEXIST);
1739                 CHECK(err < 0,
1740                       "reuseport array update empty elem BPF_NOEXIST",
1741                       "sock_type:%d err:%d errno:%d\n",
1742                       type, err, errno);
1743                 fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1744
1745                 /* BPF_EXIST success case. */
1746                 err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1747                                           BPF_EXIST);
1748                 CHECK(err < 0,
1749                       "reuseport array update same elem BPF_EXIST",
1750                       "sock_type:%d err:%d errno:%d\n", type, err, errno);
1751                 fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1752
1753                 /* BPF_NOEXIST failure case */
1754                 err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1755                                           BPF_NOEXIST);
1756                 CHECK(err >= 0 || errno != EEXIST,
1757                       "reuseport array update non-empty elem BPF_NOEXIST",
1758                       "sock_type:%d err:%d errno:%d\n",
1759                       type, err, errno);
1760                 fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1761
1762                 /* BPF_ANY case (always succeed) */
1763                 err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1764                                           BPF_ANY);
1765                 CHECK(err < 0,
1766                       "reuseport array update same sk with BPF_ANY",
1767                       "sock_type:%d err:%d errno:%d\n", type, err, errno);
1768
1769                 fd64 = grpa_fds64[fds_idx];
1770                 sk_cookie = grpa_cookies[fds_idx];
1771
1772                 /* The same sk cannot be added to reuseport_array twice */
1773                 err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_ANY);
1774                 CHECK(err >= 0 || errno != EBUSY,
1775                       "reuseport array update same sk with same index",
1776                       "sock_type:%d err:%d errno:%d\n",
1777                       type, err, errno);
1778
1779                 err = bpf_map_update_elem(map_fd, &index0, &fd64, BPF_ANY);
1780                 CHECK(err >= 0 || errno != EBUSY,
1781                       "reuseport array update same sk with different index",
1782                       "sock_type:%d err:%d errno:%d\n",
1783                       type, err, errno);
1784
1785                 /* Test delete elem */
1786                 err = bpf_map_delete_elem(map_fd, &index3);
1787                 CHECK(err < 0, "reuseport array delete sk",
1788                       "sock_type:%d err:%d errno:%d\n",
1789                       type, err, errno);
1790
1791                 /* Add it back with BPF_NOEXIST */
1792                 err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_NOEXIST);
1793                 CHECK(err < 0,
1794                       "reuseport array re-add with BPF_NOEXIST after del",
1795                       "sock_type:%d err:%d errno:%d\n", type, err, errno);
1796
1797                 /* Test cookie */
1798                 err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1799                 CHECK(err < 0 || sk_cookie != map_cookie,
1800                       "reuseport array lookup re-added sk",
1801                       "sock_type:%d err:%d errno:%d sk_cookie:0x%llx map_cookie:0x%llxn",
1802                       type, err, errno, sk_cookie, map_cookie);
1803
1804                 /* Test elem removed by close() */
1805                 for (f = 0; f < ARRAY_SIZE(grpa_fds64); f++)
1806                         close(grpa_fds64[f]);
1807                 err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1808                 CHECK(err >= 0 || errno != ENOENT,
1809                       "reuseport array lookup after close()",
1810                       "sock_type:%d err:%d errno:%d\n",
1811                       type, err, errno);
1812         }
1813
1814         /* Test SOCK_RAW */
1815         fd64 = socket(AF_INET6, SOCK_RAW, IPPROTO_UDP);
1816         CHECK(fd64 == -1, "socket(SOCK_RAW)", "err:%d errno:%d\n",
1817               err, errno);
1818         err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_NOEXIST);
1819         CHECK(err >= 0 || errno != ENOTSUPP, "reuseport array update SOCK_RAW",
1820               "err:%d errno:%d\n", err, errno);
1821         close(fd64);
1822
1823         /* Close the 64 bit value map */
1824         close(map_fd);
1825
1826         /* Test 32 bit fd */
1827         map_fd = bpf_create_map(BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
1828                                 sizeof(__u32), sizeof(__u32), array_size, 0);
1829         CHECK(map_fd < 0, "reuseport array create",
1830               "map_fd:%d, errno:%d\n", map_fd, errno);
1831         prepare_reuseport_grp(SOCK_STREAM, map_fd, sizeof(__u32), &fd64,
1832                               &sk_cookie, 1);
1833         fd = fd64;
1834         err = bpf_map_update_elem(map_fd, &index3, &fd, BPF_NOEXIST);
1835         CHECK(err < 0, "reuseport array update 32 bit fd",
1836               "err:%d errno:%d\n", err, errno);
1837         err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1838         CHECK(err >= 0 || errno != ENOSPC,
1839               "reuseport array lookup 32 bit fd",
1840               "err:%d errno:%d\n", err, errno);
1841         close(fd);
1842         close(map_fd);
1843 }
1844
1845 static void run_all_tests(void)
1846 {
1847         test_hashmap(0, NULL);
1848         test_hashmap_percpu(0, NULL);
1849         test_hashmap_walk(0, NULL);
1850         test_hashmap_zero_seed();
1851
1852         test_arraymap(0, NULL);
1853         test_arraymap_percpu(0, NULL);
1854
1855         test_arraymap_percpu_many_keys();
1856
1857         test_devmap(0, NULL);
1858         test_devmap_hash(0, NULL);
1859         test_sockmap(0, NULL);
1860
1861         test_map_large();
1862         test_map_parallel();
1863         test_map_stress();
1864
1865         test_map_rdonly();
1866         test_map_wronly();
1867
1868         test_reuseport_array();
1869
1870         test_queuemap(0, NULL);
1871         test_stackmap(0, NULL);
1872
1873         test_map_in_map();
1874 }
1875
1876 #define DEFINE_TEST(name) extern void test_##name(void);
1877 #include <map_tests/tests.h>
1878 #undef DEFINE_TEST
1879
1880 int main(void)
1881 {
1882         srand(time(NULL));
1883
1884         libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
1885
1886         map_flags = 0;
1887         run_all_tests();
1888
1889         map_flags = BPF_F_NO_PREALLOC;
1890         run_all_tests();
1891
1892 #define DEFINE_TEST(name) test_##name();
1893 #include <map_tests/tests.h>
1894 #undef DEFINE_TEST
1895
1896         printf("test_maps: OK, %d SKIPPED\n", skips);
1897         return 0;
1898 }