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