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