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 
test_hashmap(int task,void * data)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 
test_hashmap_sizes(int task,void * data)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 
test_hashmap_percpu(int task,void * data)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 
test_hashmap_walk(int task,void * data)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 
test_arraymap(int task,void * data)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 
test_arraymap_percpu(int task,void * data)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 
test_arraymap_percpu_many_keys(void)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 
test_devmap(int task,void * data)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"
test_sockmap(int tasks,void * data)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 (i < 2 && !err) {
584 			printf("Allowed update sockmap '%i:%i' not in ESTABLISHED\n",
585 			       i, sfd[i]);
586 			goto out_sockmap;
587 		} else if (i >= 2 && err) {
588 			printf("Failed noprog update sockmap '%i:%i'\n",
589 			       i, sfd[i]);
590 			goto out_sockmap;
591 		}
592 	}
593 
594 	/* Test attaching/detaching bad fds */
595 	err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_PARSER, 0);
596 	if (!err) {
597 		printf("Failed invalid parser prog attach\n");
598 		goto out_sockmap;
599 	}
600 
601 	err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_VERDICT, 0);
602 	if (!err) {
603 		printf("Failed invalid verdict prog attach\n");
604 		goto out_sockmap;
605 	}
606 
607 	err = bpf_prog_attach(-1, fd, BPF_SK_MSG_VERDICT, 0);
608 	if (!err) {
609 		printf("Failed invalid msg verdict prog attach\n");
610 		goto out_sockmap;
611 	}
612 
613 	err = bpf_prog_attach(-1, fd, __MAX_BPF_ATTACH_TYPE, 0);
614 	if (!err) {
615 		printf("Failed unknown prog attach\n");
616 		goto out_sockmap;
617 	}
618 
619 	err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_PARSER);
620 	if (err) {
621 		printf("Failed empty parser prog detach\n");
622 		goto out_sockmap;
623 	}
624 
625 	err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_VERDICT);
626 	if (err) {
627 		printf("Failed empty verdict prog detach\n");
628 		goto out_sockmap;
629 	}
630 
631 	err = bpf_prog_detach(fd, BPF_SK_MSG_VERDICT);
632 	if (err) {
633 		printf("Failed empty msg verdict prog detach\n");
634 		goto out_sockmap;
635 	}
636 
637 	err = bpf_prog_detach(fd, __MAX_BPF_ATTACH_TYPE);
638 	if (!err) {
639 		printf("Detach invalid prog successful\n");
640 		goto out_sockmap;
641 	}
642 
643 	/* Load SK_SKB program and Attach */
644 	err = bpf_prog_load(SOCKMAP_PARSE_PROG,
645 			    BPF_PROG_TYPE_SK_SKB, &obj, &parse_prog);
646 	if (err) {
647 		printf("Failed to load SK_SKB parse prog\n");
648 		goto out_sockmap;
649 	}
650 
651 	err = bpf_prog_load(SOCKMAP_TCP_MSG_PROG,
652 			    BPF_PROG_TYPE_SK_MSG, &obj, &msg_prog);
653 	if (err) {
654 		printf("Failed to load SK_SKB msg prog\n");
655 		goto out_sockmap;
656 	}
657 
658 	err = bpf_prog_load(SOCKMAP_VERDICT_PROG,
659 			    BPF_PROG_TYPE_SK_SKB, &obj, &verdict_prog);
660 	if (err) {
661 		printf("Failed to load SK_SKB verdict prog\n");
662 		goto out_sockmap;
663 	}
664 
665 	bpf_map_rx = bpf_object__find_map_by_name(obj, "sock_map_rx");
666 	if (IS_ERR(bpf_map_rx)) {
667 		printf("Failed to load map rx from verdict prog\n");
668 		goto out_sockmap;
669 	}
670 
671 	map_fd_rx = bpf_map__fd(bpf_map_rx);
672 	if (map_fd_rx < 0) {
673 		printf("Failed to get map rx fd\n");
674 		goto out_sockmap;
675 	}
676 
677 	bpf_map_tx = bpf_object__find_map_by_name(obj, "sock_map_tx");
678 	if (IS_ERR(bpf_map_tx)) {
679 		printf("Failed to load map tx from verdict prog\n");
680 		goto out_sockmap;
681 	}
682 
683 	map_fd_tx = bpf_map__fd(bpf_map_tx);
684 	if (map_fd_tx < 0) {
685 		printf("Failed to get map tx fd\n");
686 		goto out_sockmap;
687 	}
688 
689 	bpf_map_msg = bpf_object__find_map_by_name(obj, "sock_map_msg");
690 	if (IS_ERR(bpf_map_msg)) {
691 		printf("Failed to load map msg from msg_verdict prog\n");
692 		goto out_sockmap;
693 	}
694 
695 	map_fd_msg = bpf_map__fd(bpf_map_msg);
696 	if (map_fd_msg < 0) {
697 		printf("Failed to get map msg fd\n");
698 		goto out_sockmap;
699 	}
700 
701 	bpf_map_break = bpf_object__find_map_by_name(obj, "sock_map_break");
702 	if (IS_ERR(bpf_map_break)) {
703 		printf("Failed to load map tx from verdict prog\n");
704 		goto out_sockmap;
705 	}
706 
707 	map_fd_break = bpf_map__fd(bpf_map_break);
708 	if (map_fd_break < 0) {
709 		printf("Failed to get map tx fd\n");
710 		goto out_sockmap;
711 	}
712 
713 	err = bpf_prog_attach(parse_prog, map_fd_break,
714 			      BPF_SK_SKB_STREAM_PARSER, 0);
715 	if (!err) {
716 		printf("Allowed attaching SK_SKB program to invalid map\n");
717 		goto out_sockmap;
718 	}
719 
720 	err = bpf_prog_attach(parse_prog, map_fd_rx,
721 		      BPF_SK_SKB_STREAM_PARSER, 0);
722 	if (err) {
723 		printf("Failed stream parser bpf prog attach\n");
724 		goto out_sockmap;
725 	}
726 
727 	err = bpf_prog_attach(verdict_prog, map_fd_rx,
728 			      BPF_SK_SKB_STREAM_VERDICT, 0);
729 	if (err) {
730 		printf("Failed stream verdict bpf prog attach\n");
731 		goto out_sockmap;
732 	}
733 
734 	err = bpf_prog_attach(msg_prog, map_fd_msg, BPF_SK_MSG_VERDICT, 0);
735 	if (err) {
736 		printf("Failed msg verdict bpf prog attach\n");
737 		goto out_sockmap;
738 	}
739 
740 	err = bpf_prog_attach(verdict_prog, map_fd_rx,
741 			      __MAX_BPF_ATTACH_TYPE, 0);
742 	if (!err) {
743 		printf("Attached unknown bpf prog\n");
744 		goto out_sockmap;
745 	}
746 
747 	/* Test map update elem afterwards fd lives in fd and map_fd */
748 	for (i = 2; i < 6; i++) {
749 		err = bpf_map_update_elem(map_fd_rx, &i, &sfd[i], BPF_ANY);
750 		if (err) {
751 			printf("Failed map_fd_rx update sockmap %i '%i:%i'\n",
752 			       err, i, sfd[i]);
753 			goto out_sockmap;
754 		}
755 		err = bpf_map_update_elem(map_fd_tx, &i, &sfd[i], BPF_ANY);
756 		if (err) {
757 			printf("Failed map_fd_tx update sockmap %i '%i:%i'\n",
758 			       err, i, sfd[i]);
759 			goto out_sockmap;
760 		}
761 	}
762 
763 	/* Test map delete elem and remove send/recv sockets */
764 	for (i = 2; i < 4; i++) {
765 		err = bpf_map_delete_elem(map_fd_rx, &i);
766 		if (err) {
767 			printf("Failed delete sockmap rx %i '%i:%i'\n",
768 			       err, i, sfd[i]);
769 			goto out_sockmap;
770 		}
771 		err = bpf_map_delete_elem(map_fd_tx, &i);
772 		if (err) {
773 			printf("Failed delete sockmap tx %i '%i:%i'\n",
774 			       err, i, sfd[i]);
775 			goto out_sockmap;
776 		}
777 	}
778 
779 	/* Put sfd[2] (sending fd below) into msg map to test sendmsg bpf */
780 	i = 0;
781 	err = bpf_map_update_elem(map_fd_msg, &i, &sfd[2], BPF_ANY);
782 	if (err) {
783 		printf("Failed map_fd_msg update sockmap %i\n", err);
784 		goto out_sockmap;
785 	}
786 
787 	/* Test map send/recv */
788 	for (i = 0; i < 2; i++) {
789 		buf[0] = i;
790 		buf[1] = 0x5;
791 		sc = send(sfd[2], buf, 20, 0);
792 		if (sc < 0) {
793 			printf("Failed sockmap send\n");
794 			goto out_sockmap;
795 		}
796 
797 		FD_ZERO(&w);
798 		FD_SET(sfd[3], &w);
799 		to.tv_sec = 1;
800 		to.tv_usec = 0;
801 		s = select(sfd[3] + 1, &w, NULL, NULL, &to);
802 		if (s == -1) {
803 			perror("Failed sockmap select()");
804 			goto out_sockmap;
805 		} else if (!s) {
806 			printf("Failed sockmap unexpected timeout\n");
807 			goto out_sockmap;
808 		}
809 
810 		if (!FD_ISSET(sfd[3], &w)) {
811 			printf("Failed sockmap select/recv\n");
812 			goto out_sockmap;
813 		}
814 
815 		rc = recv(sfd[3], buf, sizeof(buf), 0);
816 		if (rc < 0) {
817 			printf("Failed sockmap recv\n");
818 			goto out_sockmap;
819 		}
820 	}
821 
822 	/* Negative null entry lookup from datapath should be dropped */
823 	buf[0] = 1;
824 	buf[1] = 12;
825 	sc = send(sfd[2], buf, 20, 0);
826 	if (sc < 0) {
827 		printf("Failed sockmap send\n");
828 		goto out_sockmap;
829 	}
830 
831 	/* Push fd into same slot */
832 	i = 2;
833 	err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST);
834 	if (!err) {
835 		printf("Failed allowed sockmap dup slot BPF_NOEXIST\n");
836 		goto out_sockmap;
837 	}
838 
839 	err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
840 	if (err) {
841 		printf("Failed sockmap update new slot BPF_ANY\n");
842 		goto out_sockmap;
843 	}
844 
845 	err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST);
846 	if (err) {
847 		printf("Failed sockmap update new slot BPF_EXIST\n");
848 		goto out_sockmap;
849 	}
850 
851 	/* Delete the elems without programs */
852 	for (i = 2; i < 6; i++) {
853 		err = bpf_map_delete_elem(fd, &i);
854 		if (err) {
855 			printf("Failed delete sockmap %i '%i:%i'\n",
856 			       err, i, sfd[i]);
857 		}
858 	}
859 
860 	/* Test having multiple maps open and set with programs on same fds */
861 	err = bpf_prog_attach(parse_prog, fd,
862 			      BPF_SK_SKB_STREAM_PARSER, 0);
863 	if (err) {
864 		printf("Failed fd bpf parse prog attach\n");
865 		goto out_sockmap;
866 	}
867 	err = bpf_prog_attach(verdict_prog, fd,
868 			      BPF_SK_SKB_STREAM_VERDICT, 0);
869 	if (err) {
870 		printf("Failed fd bpf verdict prog attach\n");
871 		goto out_sockmap;
872 	}
873 
874 	for (i = 4; i < 6; i++) {
875 		err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
876 		if (!err) {
877 			printf("Failed allowed duplicate programs in update ANY sockmap %i '%i:%i'\n",
878 			       err, i, sfd[i]);
879 			goto out_sockmap;
880 		}
881 		err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST);
882 		if (!err) {
883 			printf("Failed allowed duplicate program in update NOEXIST sockmap  %i '%i:%i'\n",
884 			       err, i, sfd[i]);
885 			goto out_sockmap;
886 		}
887 		err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST);
888 		if (!err) {
889 			printf("Failed allowed duplicate program in update EXIST sockmap  %i '%i:%i'\n",
890 			       err, i, sfd[i]);
891 			goto out_sockmap;
892 		}
893 	}
894 
895 	/* Test tasks number of forked operations */
896 	for (i = 0; i < tasks; i++) {
897 		pid[i] = fork();
898 		if (pid[i] == 0) {
899 			for (i = 0; i < 6; i++) {
900 				bpf_map_delete_elem(map_fd_tx, &i);
901 				bpf_map_delete_elem(map_fd_rx, &i);
902 				bpf_map_update_elem(map_fd_tx, &i,
903 						    &sfd[i], BPF_ANY);
904 				bpf_map_update_elem(map_fd_rx, &i,
905 						    &sfd[i], BPF_ANY);
906 			}
907 			exit(0);
908 		} else if (pid[i] == -1) {
909 			printf("Couldn't spawn #%d process!\n", i);
910 			exit(1);
911 		}
912 	}
913 
914 	for (i = 0; i < tasks; i++) {
915 		int status;
916 
917 		assert(waitpid(pid[i], &status, 0) == pid[i]);
918 		assert(status == 0);
919 	}
920 
921 	err = bpf_prog_detach(map_fd_rx, __MAX_BPF_ATTACH_TYPE);
922 	if (!err) {
923 		printf("Detached an invalid prog type.\n");
924 		goto out_sockmap;
925 	}
926 
927 	err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_PARSER);
928 	if (err) {
929 		printf("Failed parser prog detach\n");
930 		goto out_sockmap;
931 	}
932 
933 	err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_VERDICT);
934 	if (err) {
935 		printf("Failed parser prog detach\n");
936 		goto out_sockmap;
937 	}
938 
939 	/* Test map close sockets and empty maps */
940 	for (i = 0; i < 6; i++) {
941 		bpf_map_delete_elem(map_fd_tx, &i);
942 		bpf_map_delete_elem(map_fd_rx, &i);
943 		close(sfd[i]);
944 	}
945 	close(fd);
946 	close(map_fd_rx);
947 	bpf_object__close(obj);
948 	return;
949 out:
950 	for (i = 0; i < 6; i++)
951 		close(sfd[i]);
952 	printf("Failed to create sockmap '%i:%s'!\n", i, strerror(errno));
953 	exit(1);
954 out_sockmap:
955 	for (i = 0; i < 6; i++) {
956 		if (map_fd_tx)
957 			bpf_map_delete_elem(map_fd_tx, &i);
958 		if (map_fd_rx)
959 			bpf_map_delete_elem(map_fd_rx, &i);
960 		close(sfd[i]);
961 	}
962 	close(fd);
963 	exit(1);
964 }
965 
966 #define MAP_SIZE (32 * 1024)
967 
test_map_large(void)968 static void test_map_large(void)
969 {
970 	struct bigkey {
971 		int a;
972 		char b[116];
973 		long long c;
974 	} key;
975 	int fd, i, value;
976 
977 	fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
978 			    MAP_SIZE, map_flags);
979 	if (fd < 0) {
980 		printf("Failed to create large map '%s'!\n", strerror(errno));
981 		exit(1);
982 	}
983 
984 	for (i = 0; i < MAP_SIZE; i++) {
985 		key = (struct bigkey) { .c = i };
986 		value = i;
987 
988 		assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == 0);
989 	}
990 
991 	key.c = -1;
992 	assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
993 	       errno == E2BIG);
994 
995 	/* Iterate through all elements. */
996 	assert(bpf_map_get_next_key(fd, NULL, &key) == 0);
997 	key.c = -1;
998 	for (i = 0; i < MAP_SIZE; i++)
999 		assert(bpf_map_get_next_key(fd, &key, &key) == 0);
1000 	assert(bpf_map_get_next_key(fd, &key, &key) == -1 && errno == ENOENT);
1001 
1002 	key.c = 0;
1003 	assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 0);
1004 	key.a = 1;
1005 	assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == ENOENT);
1006 
1007 	close(fd);
1008 }
1009 
1010 #define run_parallel(N, FN, DATA) \
1011 	printf("Fork %d tasks to '" #FN "'\n", N); \
1012 	__run_parallel(N, FN, DATA)
1013 
__run_parallel(int tasks,void (* fn)(int task,void * data),void * data)1014 static void __run_parallel(int tasks, void (*fn)(int task, void *data),
1015 			   void *data)
1016 {
1017 	pid_t pid[tasks];
1018 	int i;
1019 
1020 	for (i = 0; i < tasks; i++) {
1021 		pid[i] = fork();
1022 		if (pid[i] == 0) {
1023 			fn(i, data);
1024 			exit(0);
1025 		} else if (pid[i] == -1) {
1026 			printf("Couldn't spawn #%d process!\n", i);
1027 			exit(1);
1028 		}
1029 	}
1030 
1031 	for (i = 0; i < tasks; i++) {
1032 		int status;
1033 
1034 		assert(waitpid(pid[i], &status, 0) == pid[i]);
1035 		assert(status == 0);
1036 	}
1037 }
1038 
test_map_stress(void)1039 static void test_map_stress(void)
1040 {
1041 	run_parallel(100, test_hashmap, NULL);
1042 	run_parallel(100, test_hashmap_percpu, NULL);
1043 	run_parallel(100, test_hashmap_sizes, NULL);
1044 	run_parallel(100, test_hashmap_walk, NULL);
1045 
1046 	run_parallel(100, test_arraymap, NULL);
1047 	run_parallel(100, test_arraymap_percpu, NULL);
1048 }
1049 
1050 #define TASKS 1024
1051 
1052 #define DO_UPDATE 1
1053 #define DO_DELETE 0
1054 
test_update_delete(int fn,void * data)1055 static void test_update_delete(int fn, void *data)
1056 {
1057 	int do_update = ((int *)data)[1];
1058 	int fd = ((int *)data)[0];
1059 	int i, key, value;
1060 
1061 	for (i = fn; i < MAP_SIZE; i += TASKS) {
1062 		key = value = i;
1063 
1064 		if (do_update) {
1065 			assert(bpf_map_update_elem(fd, &key, &value,
1066 						   BPF_NOEXIST) == 0);
1067 			assert(bpf_map_update_elem(fd, &key, &value,
1068 						   BPF_EXIST) == 0);
1069 		} else {
1070 			assert(bpf_map_delete_elem(fd, &key) == 0);
1071 		}
1072 	}
1073 }
1074 
test_map_parallel(void)1075 static void test_map_parallel(void)
1076 {
1077 	int i, fd, key = 0, value = 0;
1078 	int data[2];
1079 
1080 	fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
1081 			    MAP_SIZE, map_flags);
1082 	if (fd < 0) {
1083 		printf("Failed to create map for parallel test '%s'!\n",
1084 		       strerror(errno));
1085 		exit(1);
1086 	}
1087 
1088 	/* Use the same fd in children to add elements to this map:
1089 	 * child_0 adds key=0, key=1024, key=2048, ...
1090 	 * child_1 adds key=1, key=1025, key=2049, ...
1091 	 * child_1023 adds key=1023, ...
1092 	 */
1093 	data[0] = fd;
1094 	data[1] = DO_UPDATE;
1095 	run_parallel(TASKS, test_update_delete, data);
1096 
1097 	/* Check that key=0 is already there. */
1098 	assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
1099 	       errno == EEXIST);
1100 
1101 	/* Check that all elements were inserted. */
1102 	assert(bpf_map_get_next_key(fd, NULL, &key) == 0);
1103 	key = -1;
1104 	for (i = 0; i < MAP_SIZE; i++)
1105 		assert(bpf_map_get_next_key(fd, &key, &key) == 0);
1106 	assert(bpf_map_get_next_key(fd, &key, &key) == -1 && errno == ENOENT);
1107 
1108 	/* Another check for all elements */
1109 	for (i = 0; i < MAP_SIZE; i++) {
1110 		key = MAP_SIZE - i - 1;
1111 
1112 		assert(bpf_map_lookup_elem(fd, &key, &value) == 0 &&
1113 		       value == key);
1114 	}
1115 
1116 	/* Now let's delete all elemenets in parallel. */
1117 	data[1] = DO_DELETE;
1118 	run_parallel(TASKS, test_update_delete, data);
1119 
1120 	/* Nothing should be left. */
1121 	key = -1;
1122 	assert(bpf_map_get_next_key(fd, NULL, &key) == -1 && errno == ENOENT);
1123 	assert(bpf_map_get_next_key(fd, &key, &key) == -1 && errno == ENOENT);
1124 }
1125 
test_map_rdonly(void)1126 static void test_map_rdonly(void)
1127 {
1128 	int fd, key = 0, value = 0;
1129 
1130 	fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
1131 			    MAP_SIZE, map_flags | BPF_F_RDONLY);
1132 	if (fd < 0) {
1133 		printf("Failed to create map for read only test '%s'!\n",
1134 		       strerror(errno));
1135 		exit(1);
1136 	}
1137 
1138 	key = 1;
1139 	value = 1234;
1140 	/* Insert key=1 element. */
1141 	assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == -1 &&
1142 	       errno == EPERM);
1143 
1144 	/* Check that key=2 is not found. */
1145 	assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == ENOENT);
1146 	assert(bpf_map_get_next_key(fd, &key, &value) == -1 && errno == ENOENT);
1147 }
1148 
test_map_wronly(void)1149 static void test_map_wronly(void)
1150 {
1151 	int fd, key = 0, value = 0;
1152 
1153 	fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
1154 			    MAP_SIZE, map_flags | BPF_F_WRONLY);
1155 	if (fd < 0) {
1156 		printf("Failed to create map for read only test '%s'!\n",
1157 		       strerror(errno));
1158 		exit(1);
1159 	}
1160 
1161 	key = 1;
1162 	value = 1234;
1163 	/* Insert key=1 element. */
1164 	assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
1165 
1166 	/* Check that key=2 is not found. */
1167 	assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == EPERM);
1168 	assert(bpf_map_get_next_key(fd, &key, &value) == -1 && errno == EPERM);
1169 }
1170 
prepare_reuseport_grp(int type,int map_fd,__s64 * fds64,__u64 * sk_cookies,unsigned int n)1171 static void prepare_reuseport_grp(int type, int map_fd,
1172 				  __s64 *fds64, __u64 *sk_cookies,
1173 				  unsigned int n)
1174 {
1175 	socklen_t optlen, addrlen;
1176 	struct sockaddr_in6 s6;
1177 	const __u32 index0 = 0;
1178 	const int optval = 1;
1179 	unsigned int i;
1180 	u64 sk_cookie;
1181 	__s64 fd64;
1182 	int err;
1183 
1184 	s6.sin6_family = AF_INET6;
1185 	s6.sin6_addr = in6addr_any;
1186 	s6.sin6_port = 0;
1187 	addrlen = sizeof(s6);
1188 	optlen = sizeof(sk_cookie);
1189 
1190 	for (i = 0; i < n; i++) {
1191 		fd64 = socket(AF_INET6, type, 0);
1192 		CHECK(fd64 == -1, "socket()",
1193 		      "sock_type:%d fd64:%lld errno:%d\n",
1194 		      type, fd64, errno);
1195 
1196 		err = setsockopt(fd64, SOL_SOCKET, SO_REUSEPORT,
1197 				 &optval, sizeof(optval));
1198 		CHECK(err == -1, "setsockopt(SO_REUSEPORT)",
1199 		      "err:%d errno:%d\n", err, errno);
1200 
1201 		/* reuseport_array does not allow unbound sk */
1202 		err = bpf_map_update_elem(map_fd, &index0, &fd64,
1203 					  BPF_ANY);
1204 		CHECK(err != -1 || errno != EINVAL,
1205 		      "reuseport array update unbound sk",
1206 		      "sock_type:%d err:%d errno:%d\n",
1207 		      type, err, errno);
1208 
1209 		err = bind(fd64, (struct sockaddr *)&s6, sizeof(s6));
1210 		CHECK(err == -1, "bind()",
1211 		      "sock_type:%d err:%d errno:%d\n", type, err, errno);
1212 
1213 		if (i == 0) {
1214 			err = getsockname(fd64, (struct sockaddr *)&s6,
1215 					  &addrlen);
1216 			CHECK(err == -1, "getsockname()",
1217 			      "sock_type:%d err:%d errno:%d\n",
1218 			      type, err, errno);
1219 		}
1220 
1221 		err = getsockopt(fd64, SOL_SOCKET, SO_COOKIE, &sk_cookie,
1222 				 &optlen);
1223 		CHECK(err == -1, "getsockopt(SO_COOKIE)",
1224 		      "sock_type:%d err:%d errno:%d\n", type, err, errno);
1225 
1226 		if (type == SOCK_STREAM) {
1227 			/*
1228 			 * reuseport_array does not allow
1229 			 * non-listening tcp sk.
1230 			 */
1231 			err = bpf_map_update_elem(map_fd, &index0, &fd64,
1232 						  BPF_ANY);
1233 			CHECK(err != -1 || errno != EINVAL,
1234 			      "reuseport array update non-listening sk",
1235 			      "sock_type:%d err:%d errno:%d\n",
1236 			      type, err, errno);
1237 			err = listen(fd64, 0);
1238 			CHECK(err == -1, "listen()",
1239 			      "sock_type:%d, err:%d errno:%d\n",
1240 			      type, err, errno);
1241 		}
1242 
1243 		fds64[i] = fd64;
1244 		sk_cookies[i] = sk_cookie;
1245 	}
1246 }
1247 
test_reuseport_array(void)1248 static void test_reuseport_array(void)
1249 {
1250 #define REUSEPORT_FD_IDX(err, last) ({ (err) ? last : !last; })
1251 
1252 	const __u32 array_size = 4, index0 = 0, index3 = 3;
1253 	int types[2] = { SOCK_STREAM, SOCK_DGRAM }, type;
1254 	__u64 grpa_cookies[2], sk_cookie, map_cookie;
1255 	__s64 grpa_fds64[2] = { -1, -1 }, fd64 = -1;
1256 	const __u32 bad_index = array_size;
1257 	int map_fd, err, t, f;
1258 	__u32 fds_idx = 0;
1259 	int fd;
1260 
1261 	map_fd = bpf_create_map(BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
1262 				sizeof(__u32), sizeof(__u64), array_size, 0);
1263 	CHECK(map_fd == -1, "reuseport array create",
1264 	      "map_fd:%d, errno:%d\n", map_fd, errno);
1265 
1266 	/* Test lookup/update/delete with invalid index */
1267 	err = bpf_map_delete_elem(map_fd, &bad_index);
1268 	CHECK(err != -1 || errno != E2BIG, "reuseport array del >=max_entries",
1269 	      "err:%d errno:%d\n", err, errno);
1270 
1271 	err = bpf_map_update_elem(map_fd, &bad_index, &fd64, BPF_ANY);
1272 	CHECK(err != -1 || errno != E2BIG,
1273 	      "reuseport array update >=max_entries",
1274 	      "err:%d errno:%d\n", err, errno);
1275 
1276 	err = bpf_map_lookup_elem(map_fd, &bad_index, &map_cookie);
1277 	CHECK(err != -1 || errno != ENOENT,
1278 	      "reuseport array update >=max_entries",
1279 	      "err:%d errno:%d\n", err, errno);
1280 
1281 	/* Test lookup/delete non existence elem */
1282 	err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1283 	CHECK(err != -1 || errno != ENOENT,
1284 	      "reuseport array lookup not-exist elem",
1285 	      "err:%d errno:%d\n", err, errno);
1286 	err = bpf_map_delete_elem(map_fd, &index3);
1287 	CHECK(err != -1 || errno != ENOENT,
1288 	      "reuseport array del not-exist elem",
1289 	      "err:%d errno:%d\n", err, errno);
1290 
1291 	for (t = 0; t < ARRAY_SIZE(types); t++) {
1292 		type = types[t];
1293 
1294 		prepare_reuseport_grp(type, map_fd, grpa_fds64,
1295 				      grpa_cookies, ARRAY_SIZE(grpa_fds64));
1296 
1297 		/* Test BPF_* update flags */
1298 		/* BPF_EXIST failure case */
1299 		err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1300 					  BPF_EXIST);
1301 		CHECK(err != -1 || errno != ENOENT,
1302 		      "reuseport array update empty elem BPF_EXIST",
1303 		      "sock_type:%d err:%d errno:%d\n",
1304 		      type, err, errno);
1305 		fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1306 
1307 		/* BPF_NOEXIST success case */
1308 		err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1309 					  BPF_NOEXIST);
1310 		CHECK(err == -1,
1311 		      "reuseport array update empty elem BPF_NOEXIST",
1312 		      "sock_type:%d err:%d errno:%d\n",
1313 		      type, err, errno);
1314 		fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1315 
1316 		/* BPF_EXIST success case. */
1317 		err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1318 					  BPF_EXIST);
1319 		CHECK(err == -1,
1320 		      "reuseport array update same elem BPF_EXIST",
1321 		      "sock_type:%d err:%d errno:%d\n", type, err, errno);
1322 		fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1323 
1324 		/* BPF_NOEXIST failure case */
1325 		err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1326 					  BPF_NOEXIST);
1327 		CHECK(err != -1 || errno != EEXIST,
1328 		      "reuseport array update non-empty elem BPF_NOEXIST",
1329 		      "sock_type:%d err:%d errno:%d\n",
1330 		      type, err, errno);
1331 		fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1332 
1333 		/* BPF_ANY case (always succeed) */
1334 		err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1335 					  BPF_ANY);
1336 		CHECK(err == -1,
1337 		      "reuseport array update same sk with BPF_ANY",
1338 		      "sock_type:%d err:%d errno:%d\n", type, err, errno);
1339 
1340 		fd64 = grpa_fds64[fds_idx];
1341 		sk_cookie = grpa_cookies[fds_idx];
1342 
1343 		/* The same sk cannot be added to reuseport_array twice */
1344 		err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_ANY);
1345 		CHECK(err != -1 || errno != EBUSY,
1346 		      "reuseport array update same sk with same index",
1347 		      "sock_type:%d err:%d errno:%d\n",
1348 		      type, err, errno);
1349 
1350 		err = bpf_map_update_elem(map_fd, &index0, &fd64, BPF_ANY);
1351 		CHECK(err != -1 || errno != EBUSY,
1352 		      "reuseport array update same sk with different index",
1353 		      "sock_type:%d err:%d errno:%d\n",
1354 		      type, err, errno);
1355 
1356 		/* Test delete elem */
1357 		err = bpf_map_delete_elem(map_fd, &index3);
1358 		CHECK(err == -1, "reuseport array delete sk",
1359 		      "sock_type:%d err:%d errno:%d\n",
1360 		      type, err, errno);
1361 
1362 		/* Add it back with BPF_NOEXIST */
1363 		err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_NOEXIST);
1364 		CHECK(err == -1,
1365 		      "reuseport array re-add with BPF_NOEXIST after del",
1366 		      "sock_type:%d err:%d errno:%d\n", type, err, errno);
1367 
1368 		/* Test cookie */
1369 		err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1370 		CHECK(err == -1 || sk_cookie != map_cookie,
1371 		      "reuseport array lookup re-added sk",
1372 		      "sock_type:%d err:%d errno:%d sk_cookie:0x%llx map_cookie:0x%llxn",
1373 		      type, err, errno, sk_cookie, map_cookie);
1374 
1375 		/* Test elem removed by close() */
1376 		for (f = 0; f < ARRAY_SIZE(grpa_fds64); f++)
1377 			close(grpa_fds64[f]);
1378 		err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1379 		CHECK(err != -1 || errno != ENOENT,
1380 		      "reuseport array lookup after close()",
1381 		      "sock_type:%d err:%d errno:%d\n",
1382 		      type, err, errno);
1383 	}
1384 
1385 	/* Test SOCK_RAW */
1386 	fd64 = socket(AF_INET6, SOCK_RAW, IPPROTO_UDP);
1387 	CHECK(fd64 == -1, "socket(SOCK_RAW)", "err:%d errno:%d\n",
1388 	      err, errno);
1389 	err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_NOEXIST);
1390 	CHECK(err != -1 || errno != ENOTSUPP, "reuseport array update SOCK_RAW",
1391 	      "err:%d errno:%d\n", err, errno);
1392 	close(fd64);
1393 
1394 	/* Close the 64 bit value map */
1395 	close(map_fd);
1396 
1397 	/* Test 32 bit fd */
1398 	map_fd = bpf_create_map(BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
1399 				sizeof(__u32), sizeof(__u32), array_size, 0);
1400 	CHECK(map_fd == -1, "reuseport array create",
1401 	      "map_fd:%d, errno:%d\n", map_fd, errno);
1402 	prepare_reuseport_grp(SOCK_STREAM, map_fd, &fd64, &sk_cookie, 1);
1403 	fd = fd64;
1404 	err = bpf_map_update_elem(map_fd, &index3, &fd, BPF_NOEXIST);
1405 	CHECK(err == -1, "reuseport array update 32 bit fd",
1406 	      "err:%d errno:%d\n", err, errno);
1407 	err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1408 	CHECK(err != -1 || errno != ENOSPC,
1409 	      "reuseport array lookup 32 bit fd",
1410 	      "err:%d errno:%d\n", err, errno);
1411 	close(fd);
1412 	close(map_fd);
1413 }
1414 
run_all_tests(void)1415 static void run_all_tests(void)
1416 {
1417 	test_hashmap(0, NULL);
1418 	test_hashmap_percpu(0, NULL);
1419 	test_hashmap_walk(0, NULL);
1420 
1421 	test_arraymap(0, NULL);
1422 	test_arraymap_percpu(0, NULL);
1423 
1424 	test_arraymap_percpu_many_keys();
1425 
1426 	test_devmap(0, NULL);
1427 	test_sockmap(0, NULL);
1428 
1429 	test_map_large();
1430 	test_map_parallel();
1431 	test_map_stress();
1432 
1433 	test_map_rdonly();
1434 	test_map_wronly();
1435 
1436 	test_reuseport_array();
1437 }
1438 
main(void)1439 int main(void)
1440 {
1441 	map_flags = 0;
1442 	run_all_tests();
1443 
1444 	map_flags = BPF_F_NO_PREALLOC;
1445 	run_all_tests();
1446 
1447 	printf("test_maps: OK\n");
1448 	return 0;
1449 }
1450