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