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/resource.h>
21
22#include <linux/bpf.h>
23
24#include <bpf/bpf.h>
25#include <bpf/libbpf.h>
26#include "bpf_util.h"
27
28static int map_flags;
29
30static void test_hashmap(int task, void *data)
31{
32	long long key, next_key, first_key, value;
33	int fd;
34
35	fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
36			    2, map_flags);
37	if (fd < 0) {
38		printf("Failed to create hashmap '%s'!\n", strerror(errno));
39		exit(1);
40	}
41
42	key = 1;
43	value = 1234;
44	/* Insert key=1 element. */
45	assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
46
47	value = 0;
48	/* BPF_NOEXIST means add new element if it doesn't exist. */
49	assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
50	       /* key=1 already exists. */
51	       errno == EEXIST);
52
53	/* -1 is an invalid flag. */
54	assert(bpf_map_update_elem(fd, &key, &value, -1) == -1 &&
55	       errno == EINVAL);
56
57	/* Check that key=1 can be found. */
58	assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 1234);
59
60	key = 2;
61	/* Check that key=2 is not found. */
62	assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == ENOENT);
63
64	/* BPF_EXIST means update existing element. */
65	assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == -1 &&
66	       /* key=2 is not there. */
67	       errno == ENOENT);
68
69	/* Insert key=2 element. */
70	assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == 0);
71
72	/* key=1 and key=2 were inserted, check that key=0 cannot be
73	 * inserted due to max_entries limit.
74	 */
75	key = 0;
76	assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
77	       errno == E2BIG);
78
79	/* Update existing element, though the map is full. */
80	key = 1;
81	assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == 0);
82	key = 2;
83	assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
84	key = 3;
85	assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
86	       errno == E2BIG);
87
88	/* Check that key = 0 doesn't exist. */
89	key = 0;
90	assert(bpf_map_delete_elem(fd, &key) == -1 && errno == ENOENT);
91
92	/* Iterate over two elements. */
93	assert(bpf_map_get_next_key(fd, NULL, &first_key) == 0 &&
94	       (first_key == 1 || first_key == 2));
95	assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
96	       (next_key == first_key));
97	assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
98	       (next_key == 1 || next_key == 2) &&
99	       (next_key != first_key));
100	assert(bpf_map_get_next_key(fd, &next_key, &next_key) == -1 &&
101	       errno == ENOENT);
102
103	/* Delete both elements. */
104	key = 1;
105	assert(bpf_map_delete_elem(fd, &key) == 0);
106	key = 2;
107	assert(bpf_map_delete_elem(fd, &key) == 0);
108	assert(bpf_map_delete_elem(fd, &key) == -1 && errno == ENOENT);
109
110	key = 0;
111	/* Check that map is empty. */
112	assert(bpf_map_get_next_key(fd, NULL, &next_key) == -1 &&
113	       errno == ENOENT);
114	assert(bpf_map_get_next_key(fd, &key, &next_key) == -1 &&
115	       errno == ENOENT);
116
117	close(fd);
118}
119
120static void test_hashmap_sizes(int task, void *data)
121{
122	int fd, i, j;
123
124	for (i = 1; i <= 512; i <<= 1)
125		for (j = 1; j <= 1 << 18; j <<= 1) {
126			fd = bpf_create_map(BPF_MAP_TYPE_HASH, i, j,
127					    2, map_flags);
128			if (fd < 0) {
129				printf("Failed to create hashmap key=%d value=%d '%s'\n",
130				       i, j, strerror(errno));
131				exit(1);
132			}
133			close(fd);
134			usleep(10); /* give kernel time to destroy */
135		}
136}
137
138static void test_hashmap_percpu(int task, void *data)
139{
140	unsigned int nr_cpus = bpf_num_possible_cpus();
141	BPF_DECLARE_PERCPU(long, value);
142	long long key, next_key, first_key;
143	int expected_key_mask = 0;
144	int fd, i;
145
146	fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_HASH, sizeof(key),
147			    sizeof(bpf_percpu(value, 0)), 2, map_flags);
148	if (fd < 0) {
149		printf("Failed to create hashmap '%s'!\n", strerror(errno));
150		exit(1);
151	}
152
153	for (i = 0; i < nr_cpus; i++)
154		bpf_percpu(value, i) = i + 100;
155
156	key = 1;
157	/* Insert key=1 element. */
158	assert(!(expected_key_mask & key));
159	assert(bpf_map_update_elem(fd, &key, value, BPF_ANY) == 0);
160	expected_key_mask |= key;
161
162	/* BPF_NOEXIST means add new element if it doesn't exist. */
163	assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) == -1 &&
164	       /* key=1 already exists. */
165	       errno == EEXIST);
166
167	/* -1 is an invalid flag. */
168	assert(bpf_map_update_elem(fd, &key, value, -1) == -1 &&
169	       errno == EINVAL);
170
171	/* Check that key=1 can be found. Value could be 0 if the lookup
172	 * was run from a different CPU.
173	 */
174	bpf_percpu(value, 0) = 1;
175	assert(bpf_map_lookup_elem(fd, &key, value) == 0 &&
176	       bpf_percpu(value, 0) == 100);
177
178	key = 2;
179	/* Check that key=2 is not found. */
180	assert(bpf_map_lookup_elem(fd, &key, value) == -1 && errno == ENOENT);
181
182	/* BPF_EXIST means update existing element. */
183	assert(bpf_map_update_elem(fd, &key, value, BPF_EXIST) == -1 &&
184	       /* key=2 is not there. */
185	       errno == ENOENT);
186
187	/* Insert key=2 element. */
188	assert(!(expected_key_mask & key));
189	assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) == 0);
190	expected_key_mask |= key;
191
192	/* key=1 and key=2 were inserted, check that key=0 cannot be
193	 * inserted due to max_entries limit.
194	 */
195	key = 0;
196	assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) == -1 &&
197	       errno == E2BIG);
198
199	/* Check that key = 0 doesn't exist. */
200	assert(bpf_map_delete_elem(fd, &key) == -1 && errno == ENOENT);
201
202	/* Iterate over two elements. */
203	assert(bpf_map_get_next_key(fd, NULL, &first_key) == 0 &&
204	       ((expected_key_mask & first_key) == first_key));
205	while (!bpf_map_get_next_key(fd, &key, &next_key)) {
206		if (first_key) {
207			assert(next_key == first_key);
208			first_key = 0;
209		}
210		assert((expected_key_mask & next_key) == next_key);
211		expected_key_mask &= ~next_key;
212
213		assert(bpf_map_lookup_elem(fd, &next_key, value) == 0);
214
215		for (i = 0; i < nr_cpus; i++)
216			assert(bpf_percpu(value, i) == i + 100);
217
218		key = next_key;
219	}
220	assert(errno == ENOENT);
221
222	/* Update with BPF_EXIST. */
223	key = 1;
224	assert(bpf_map_update_elem(fd, &key, value, BPF_EXIST) == 0);
225
226	/* Delete both elements. */
227	key = 1;
228	assert(bpf_map_delete_elem(fd, &key) == 0);
229	key = 2;
230	assert(bpf_map_delete_elem(fd, &key) == 0);
231	assert(bpf_map_delete_elem(fd, &key) == -1 && errno == ENOENT);
232
233	key = 0;
234	/* Check that map is empty. */
235	assert(bpf_map_get_next_key(fd, NULL, &next_key) == -1 &&
236	       errno == ENOENT);
237	assert(bpf_map_get_next_key(fd, &key, &next_key) == -1 &&
238	       errno == ENOENT);
239
240	close(fd);
241}
242
243static void test_hashmap_walk(int task, void *data)
244{
245	int fd, i, max_entries = 100000;
246	long long key, value, next_key;
247	bool next_key_valid = true;
248
249	fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
250			    max_entries, map_flags);
251	if (fd < 0) {
252		printf("Failed to create hashmap '%s'!\n", strerror(errno));
253		exit(1);
254	}
255
256	for (i = 0; i < max_entries; i++) {
257		key = i; value = key;
258		assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == 0);
259	}
260
261	for (i = 0; bpf_map_get_next_key(fd, !i ? NULL : &key,
262					 &next_key) == 0; i++) {
263		key = next_key;
264		assert(bpf_map_lookup_elem(fd, &key, &value) == 0);
265	}
266
267	assert(i == max_entries);
268
269	assert(bpf_map_get_next_key(fd, NULL, &key) == 0);
270	for (i = 0; next_key_valid; i++) {
271		next_key_valid = bpf_map_get_next_key(fd, &key, &next_key) == 0;
272		assert(bpf_map_lookup_elem(fd, &key, &value) == 0);
273		value++;
274		assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == 0);
275		key = next_key;
276	}
277
278	assert(i == max_entries);
279
280	for (i = 0; bpf_map_get_next_key(fd, !i ? NULL : &key,
281					 &next_key) == 0; i++) {
282		key = next_key;
283		assert(bpf_map_lookup_elem(fd, &key, &value) == 0);
284		assert(value - 1 == key);
285	}
286
287	assert(i == max_entries);
288	close(fd);
289}
290
291static void test_arraymap(int task, void *data)
292{
293	int key, next_key, fd;
294	long long value;
295
296	fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(key), sizeof(value),
297			    2, 0);
298	if (fd < 0) {
299		printf("Failed to create arraymap '%s'!\n", strerror(errno));
300		exit(1);
301	}
302
303	key = 1;
304	value = 1234;
305	/* Insert key=1 element. */
306	assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
307
308	value = 0;
309	assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
310	       errno == EEXIST);
311
312	/* Check that key=1 can be found. */
313	assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 1234);
314
315	key = 0;
316	/* Check that key=0 is also found and zero initialized. */
317	assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 0);
318
319	/* key=0 and key=1 were inserted, check that key=2 cannot be inserted
320	 * due to max_entries limit.
321	 */
322	key = 2;
323	assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == -1 &&
324	       errno == E2BIG);
325
326	/* Check that key = 2 doesn't exist. */
327	assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == ENOENT);
328
329	/* Iterate over two elements. */
330	assert(bpf_map_get_next_key(fd, NULL, &next_key) == 0 &&
331	       next_key == 0);
332	assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
333	       next_key == 0);
334	assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
335	       next_key == 1);
336	assert(bpf_map_get_next_key(fd, &next_key, &next_key) == -1 &&
337	       errno == ENOENT);
338
339	/* Delete shouldn't succeed. */
340	key = 1;
341	assert(bpf_map_delete_elem(fd, &key) == -1 && errno == EINVAL);
342
343	close(fd);
344}
345
346static void test_arraymap_percpu(int task, void *data)
347{
348	unsigned int nr_cpus = bpf_num_possible_cpus();
349	BPF_DECLARE_PERCPU(long, values);
350	int key, next_key, fd, i;
351
352	fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_ARRAY, sizeof(key),
353			    sizeof(bpf_percpu(values, 0)), 2, 0);
354	if (fd < 0) {
355		printf("Failed to create arraymap '%s'!\n", strerror(errno));
356		exit(1);
357	}
358
359	for (i = 0; i < nr_cpus; i++)
360		bpf_percpu(values, i) = i + 100;
361
362	key = 1;
363	/* Insert key=1 element. */
364	assert(bpf_map_update_elem(fd, &key, values, BPF_ANY) == 0);
365
366	bpf_percpu(values, 0) = 0;
367	assert(bpf_map_update_elem(fd, &key, values, BPF_NOEXIST) == -1 &&
368	       errno == EEXIST);
369
370	/* Check that key=1 can be found. */
371	assert(bpf_map_lookup_elem(fd, &key, values) == 0 &&
372	       bpf_percpu(values, 0) == 100);
373
374	key = 0;
375	/* Check that key=0 is also found and zero initialized. */
376	assert(bpf_map_lookup_elem(fd, &key, values) == 0 &&
377	       bpf_percpu(values, 0) == 0 &&
378	       bpf_percpu(values, nr_cpus - 1) == 0);
379
380	/* Check that key=2 cannot be inserted due to max_entries limit. */
381	key = 2;
382	assert(bpf_map_update_elem(fd, &key, values, BPF_EXIST) == -1 &&
383	       errno == E2BIG);
384
385	/* Check that key = 2 doesn't exist. */
386	assert(bpf_map_lookup_elem(fd, &key, values) == -1 && errno == ENOENT);
387
388	/* Iterate over two elements. */
389	assert(bpf_map_get_next_key(fd, NULL, &next_key) == 0 &&
390	       next_key == 0);
391	assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
392	       next_key == 0);
393	assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
394	       next_key == 1);
395	assert(bpf_map_get_next_key(fd, &next_key, &next_key) == -1 &&
396	       errno == ENOENT);
397
398	/* Delete shouldn't succeed. */
399	key = 1;
400	assert(bpf_map_delete_elem(fd, &key) == -1 && errno == EINVAL);
401
402	close(fd);
403}
404
405static void test_arraymap_percpu_many_keys(void)
406{
407	unsigned int nr_cpus = bpf_num_possible_cpus();
408	BPF_DECLARE_PERCPU(long, values);
409	/* nr_keys is not too large otherwise the test stresses percpu
410	 * allocator more than anything else
411	 */
412	unsigned int nr_keys = 2000;
413	int key, fd, i;
414
415	fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_ARRAY, sizeof(key),
416			    sizeof(bpf_percpu(values, 0)), nr_keys, 0);
417	if (fd < 0) {
418		printf("Failed to create per-cpu arraymap '%s'!\n",
419		       strerror(errno));
420		exit(1);
421	}
422
423	for (i = 0; i < nr_cpus; i++)
424		bpf_percpu(values, i) = i + 10;
425
426	for (key = 0; key < nr_keys; key++)
427		assert(bpf_map_update_elem(fd, &key, values, BPF_ANY) == 0);
428
429	for (key = 0; key < nr_keys; key++) {
430		for (i = 0; i < nr_cpus; i++)
431			bpf_percpu(values, i) = 0;
432
433		assert(bpf_map_lookup_elem(fd, &key, values) == 0);
434
435		for (i = 0; i < nr_cpus; i++)
436			assert(bpf_percpu(values, i) == i + 10);
437	}
438
439	close(fd);
440}
441
442static void test_devmap(int task, void *data)
443{
444	int fd;
445	__u32 key, value;
446
447	fd = bpf_create_map(BPF_MAP_TYPE_DEVMAP, sizeof(key), sizeof(value),
448			    2, 0);
449	if (fd < 0) {
450		printf("Failed to create arraymap '%s'!\n", strerror(errno));
451		exit(1);
452	}
453
454	close(fd);
455}
456
457#include <sys/socket.h>
458#include <sys/ioctl.h>
459#include <arpa/inet.h>
460#include <sys/select.h>
461#include <linux/err.h>
462#define SOCKMAP_PARSE_PROG "./sockmap_parse_prog.o"
463#define SOCKMAP_VERDICT_PROG "./sockmap_verdict_prog.o"
464static void test_sockmap(int tasks, void *data)
465{
466	int one = 1, map_fd_rx, map_fd_tx, map_fd_break, s, sc, rc;
467	struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_break;
468	int ports[] = {50200, 50201, 50202, 50204};
469	int err, i, fd, udp, sfd[6] = {0xdeadbeef};
470	u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0};
471	int parse_prog, verdict_prog;
472	struct sockaddr_in addr;
473	struct bpf_object *obj;
474	struct timeval to;
475	__u32 key, value;
476	pid_t pid[tasks];
477	fd_set w;
478
479	/* Create some sockets to use with sockmap */
480	for (i = 0; i < 2; i++) {
481		sfd[i] = socket(AF_INET, SOCK_STREAM, 0);
482		if (sfd[i] < 0)
483			goto out;
484		err = setsockopt(sfd[i], SOL_SOCKET, SO_REUSEADDR,
485				 (char *)&one, sizeof(one));
486		if (err) {
487			printf("failed to setsockopt\n");
488			goto out;
489		}
490		err = ioctl(sfd[i], FIONBIO, (char *)&one);
491		if (err < 0) {
492			printf("failed to ioctl\n");
493			goto out;
494		}
495		memset(&addr, 0, sizeof(struct sockaddr_in));
496		addr.sin_family = AF_INET;
497		addr.sin_addr.s_addr = inet_addr("127.0.0.1");
498		addr.sin_port = htons(ports[i]);
499		err = bind(sfd[i], (struct sockaddr *)&addr, sizeof(addr));
500		if (err < 0) {
501			printf("failed to bind: err %i: %i:%i\n",
502			       err, i, sfd[i]);
503			goto out;
504		}
505		err = listen(sfd[i], 32);
506		if (err < 0) {
507			printf("failed to listen\n");
508			goto out;
509		}
510	}
511
512	for (i = 2; i < 4; i++) {
513		sfd[i] = socket(AF_INET, SOCK_STREAM, 0);
514		if (sfd[i] < 0)
515			goto out;
516		err = setsockopt(sfd[i], SOL_SOCKET, SO_REUSEADDR,
517				 (char *)&one, sizeof(one));
518		if (err) {
519			printf("set sock opt\n");
520			goto out;
521		}
522		memset(&addr, 0, sizeof(struct sockaddr_in));
523		addr.sin_family = AF_INET;
524		addr.sin_addr.s_addr = inet_addr("127.0.0.1");
525		addr.sin_port = htons(ports[i - 2]);
526		err = connect(sfd[i], (struct sockaddr *)&addr, sizeof(addr));
527		if (err) {
528			printf("failed to connect\n");
529			goto out;
530		}
531	}
532
533
534	for (i = 4; i < 6; i++) {
535		sfd[i] = accept(sfd[i - 4], NULL, NULL);
536		if (sfd[i] < 0) {
537			printf("accept failed\n");
538			goto out;
539		}
540	}
541
542	/* Test sockmap with connected sockets */
543	fd = bpf_create_map(BPF_MAP_TYPE_SOCKMAP,
544			    sizeof(key), sizeof(value),
545			    6, 0);
546	if (fd < 0) {
547		printf("Failed to create sockmap %i\n", fd);
548		goto out_sockmap;
549	}
550
551	/* Test update with unsupported UDP socket */
552	udp = socket(AF_INET, SOCK_DGRAM, 0);
553	i = 0;
554	err = bpf_map_update_elem(fd, &i, &udp, BPF_ANY);
555	if (!err) {
556		printf("Failed socket SOCK_DGRAM allowed '%i:%i'\n",
557		       i, udp);
558		goto out_sockmap;
559	}
560
561	/* Test update without programs */
562	for (i = 0; i < 6; i++) {
563		err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
564		if (err) {
565			printf("Failed noprog update sockmap '%i:%i'\n",
566			       i, sfd[i]);
567			goto out_sockmap;
568		}
569	}
570
571	/* Test attaching/detaching bad fds */
572	err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_PARSER, 0);
573	if (!err) {
574		printf("Failed invalid parser prog attach\n");
575		goto out_sockmap;
576	}
577
578	err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_VERDICT, 0);
579	if (!err) {
580		printf("Failed invalid verdict prog attach\n");
581		goto out_sockmap;
582	}
583
584	err = bpf_prog_attach(-1, fd, __MAX_BPF_ATTACH_TYPE, 0);
585	if (!err) {
586		printf("Failed unknown prog attach\n");
587		goto out_sockmap;
588	}
589
590	err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_PARSER);
591	if (err) {
592		printf("Failed empty parser prog detach\n");
593		goto out_sockmap;
594	}
595
596	err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_VERDICT);
597	if (err) {
598		printf("Failed empty verdict prog detach\n");
599		goto out_sockmap;
600	}
601
602	err = bpf_prog_detach(fd, __MAX_BPF_ATTACH_TYPE);
603	if (!err) {
604		printf("Detach invalid prog successful\n");
605		goto out_sockmap;
606	}
607
608	/* Load SK_SKB program and Attach */
609	err = bpf_prog_load(SOCKMAP_PARSE_PROG,
610			    BPF_PROG_TYPE_SK_SKB, &obj, &parse_prog);
611	if (err) {
612		printf("Failed to load SK_SKB parse prog\n");
613		goto out_sockmap;
614	}
615
616	err = bpf_prog_load(SOCKMAP_VERDICT_PROG,
617			    BPF_PROG_TYPE_SK_SKB, &obj, &verdict_prog);
618	if (err) {
619		printf("Failed to load SK_SKB verdict prog\n");
620		goto out_sockmap;
621	}
622
623	bpf_map_rx = bpf_object__find_map_by_name(obj, "sock_map_rx");
624	if (IS_ERR(bpf_map_rx)) {
625		printf("Failed to load map rx from verdict prog\n");
626		goto out_sockmap;
627	}
628
629	map_fd_rx = bpf_map__fd(bpf_map_rx);
630	if (map_fd_rx < 0) {
631		printf("Failed to get map fd\n");
632		goto out_sockmap;
633	}
634
635	bpf_map_tx = bpf_object__find_map_by_name(obj, "sock_map_tx");
636	if (IS_ERR(bpf_map_tx)) {
637		printf("Failed to load map tx from verdict prog\n");
638		goto out_sockmap;
639	}
640
641	map_fd_tx = bpf_map__fd(bpf_map_tx);
642	if (map_fd_tx < 0) {
643		printf("Failed to get map tx fd\n");
644		goto out_sockmap;
645	}
646
647	bpf_map_break = bpf_object__find_map_by_name(obj, "sock_map_break");
648	if (IS_ERR(bpf_map_break)) {
649		printf("Failed to load map tx from verdict prog\n");
650		goto out_sockmap;
651	}
652
653	map_fd_break = bpf_map__fd(bpf_map_break);
654	if (map_fd_break < 0) {
655		printf("Failed to get map tx fd\n");
656		goto out_sockmap;
657	}
658
659	err = bpf_prog_attach(parse_prog, map_fd_break,
660			      BPF_SK_SKB_STREAM_PARSER, 0);
661	if (!err) {
662		printf("Allowed attaching SK_SKB program to invalid map\n");
663		goto out_sockmap;
664	}
665
666	err = bpf_prog_attach(parse_prog, map_fd_rx,
667		      BPF_SK_SKB_STREAM_PARSER, 0);
668	if (err) {
669		printf("Failed stream parser bpf prog attach\n");
670		goto out_sockmap;
671	}
672
673	err = bpf_prog_attach(verdict_prog, map_fd_rx,
674			      BPF_SK_SKB_STREAM_VERDICT, 0);
675	if (err) {
676		printf("Failed stream verdict bpf prog attach\n");
677		goto out_sockmap;
678	}
679
680	err = bpf_prog_attach(verdict_prog, map_fd_rx,
681			      __MAX_BPF_ATTACH_TYPE, 0);
682	if (!err) {
683		printf("Attached unknown bpf prog\n");
684		goto out_sockmap;
685	}
686
687	/* Test map update elem afterwards fd lives in fd and map_fd */
688	for (i = 0; i < 6; i++) {
689		err = bpf_map_update_elem(map_fd_rx, &i, &sfd[i], BPF_ANY);
690		if (err) {
691			printf("Failed map_fd_rx update sockmap %i '%i:%i'\n",
692			       err, i, sfd[i]);
693			goto out_sockmap;
694		}
695		err = bpf_map_update_elem(map_fd_tx, &i, &sfd[i], BPF_ANY);
696		if (err) {
697			printf("Failed map_fd_tx update sockmap %i '%i:%i'\n",
698			       err, i, sfd[i]);
699			goto out_sockmap;
700		}
701	}
702
703	/* Test map delete elem and remove send/recv sockets */
704	for (i = 2; i < 4; i++) {
705		err = bpf_map_delete_elem(map_fd_rx, &i);
706		if (err) {
707			printf("Failed delete sockmap rx %i '%i:%i'\n",
708			       err, i, sfd[i]);
709			goto out_sockmap;
710		}
711		err = bpf_map_delete_elem(map_fd_tx, &i);
712		if (err) {
713			printf("Failed delete sockmap tx %i '%i:%i'\n",
714			       err, i, sfd[i]);
715			goto out_sockmap;
716		}
717	}
718
719	/* Test map send/recv */
720	for (i = 0; i < 2; i++) {
721		buf[0] = i;
722		buf[1] = 0x5;
723		sc = send(sfd[2], buf, 20, 0);
724		if (sc < 0) {
725			printf("Failed sockmap send\n");
726			goto out_sockmap;
727		}
728
729		FD_ZERO(&w);
730		FD_SET(sfd[3], &w);
731		to.tv_sec = 1;
732		to.tv_usec = 0;
733		s = select(sfd[3] + 1, &w, NULL, NULL, &to);
734		if (s == -1) {
735			perror("Failed sockmap select()");
736			goto out_sockmap;
737		} else if (!s) {
738			printf("Failed sockmap unexpected timeout\n");
739			goto out_sockmap;
740		}
741
742		if (!FD_ISSET(sfd[3], &w)) {
743			printf("Failed sockmap select/recv\n");
744			goto out_sockmap;
745		}
746
747		rc = recv(sfd[3], buf, sizeof(buf), 0);
748		if (rc < 0) {
749			printf("Failed sockmap recv\n");
750			goto out_sockmap;
751		}
752	}
753
754	/* Negative null entry lookup from datapath should be dropped */
755	buf[0] = 1;
756	buf[1] = 12;
757	sc = send(sfd[2], buf, 20, 0);
758	if (sc < 0) {
759		printf("Failed sockmap send\n");
760		goto out_sockmap;
761	}
762
763	/* Push fd into same slot */
764	i = 2;
765	err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST);
766	if (!err) {
767		printf("Failed allowed sockmap dup slot BPF_NOEXIST\n");
768		goto out_sockmap;
769	}
770
771	err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
772	if (err) {
773		printf("Failed sockmap update new slot BPF_ANY\n");
774		goto out_sockmap;
775	}
776
777	err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST);
778	if (err) {
779		printf("Failed sockmap update new slot BPF_EXIST\n");
780		goto out_sockmap;
781	}
782
783	/* Delete the elems without programs */
784	for (i = 0; i < 6; i++) {
785		err = bpf_map_delete_elem(fd, &i);
786		if (err) {
787			printf("Failed delete sockmap %i '%i:%i'\n",
788			       err, i, sfd[i]);
789		}
790	}
791
792	/* Test having multiple maps open and set with programs on same fds */
793	err = bpf_prog_attach(parse_prog, fd,
794			      BPF_SK_SKB_STREAM_PARSER, 0);
795	if (err) {
796		printf("Failed fd bpf parse prog attach\n");
797		goto out_sockmap;
798	}
799	err = bpf_prog_attach(verdict_prog, fd,
800			      BPF_SK_SKB_STREAM_VERDICT, 0);
801	if (err) {
802		printf("Failed fd bpf verdict prog attach\n");
803		goto out_sockmap;
804	}
805
806	for (i = 4; i < 6; i++) {
807		err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
808		if (!err) {
809			printf("Failed allowed duplicate programs in update ANY sockmap %i '%i:%i'\n",
810			       err, i, sfd[i]);
811			goto out_sockmap;
812		}
813		err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST);
814		if (!err) {
815			printf("Failed allowed duplicate program in update NOEXIST sockmap  %i '%i:%i'\n",
816			       err, i, sfd[i]);
817			goto out_sockmap;
818		}
819		err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST);
820		if (!err) {
821			printf("Failed allowed duplicate program in update EXIST sockmap  %i '%i:%i'\n",
822			       err, i, sfd[i]);
823			goto out_sockmap;
824		}
825	}
826
827	/* Test tasks number of forked operations */
828	for (i = 0; i < tasks; i++) {
829		pid[i] = fork();
830		if (pid[i] == 0) {
831			for (i = 0; i < 6; i++) {
832				bpf_map_delete_elem(map_fd_tx, &i);
833				bpf_map_delete_elem(map_fd_rx, &i);
834				bpf_map_update_elem(map_fd_tx, &i,
835						    &sfd[i], BPF_ANY);
836				bpf_map_update_elem(map_fd_rx, &i,
837						    &sfd[i], BPF_ANY);
838			}
839			exit(0);
840		} else if (pid[i] == -1) {
841			printf("Couldn't spawn #%d process!\n", i);
842			exit(1);
843		}
844	}
845
846	for (i = 0; i < tasks; i++) {
847		int status;
848
849		assert(waitpid(pid[i], &status, 0) == pid[i]);
850		assert(status == 0);
851	}
852
853	err = bpf_prog_detach(map_fd_rx, __MAX_BPF_ATTACH_TYPE);
854	if (!err) {
855		printf("Detached an invalid prog type.\n");
856		goto out_sockmap;
857	}
858
859	err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_PARSER);
860	if (err) {
861		printf("Failed parser prog detach\n");
862		goto out_sockmap;
863	}
864
865	err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_VERDICT);
866	if (err) {
867		printf("Failed parser prog detach\n");
868		goto out_sockmap;
869	}
870
871	/* Test map close sockets */
872	for (i = 0; i < 6; i++)
873		close(sfd[i]);
874	close(fd);
875	close(map_fd_rx);
876	bpf_object__close(obj);
877	return;
878out:
879	for (i = 0; i < 6; i++)
880		close(sfd[i]);
881	printf("Failed to create sockmap '%i:%s'!\n", i, strerror(errno));
882	exit(1);
883out_sockmap:
884	for (i = 0; i < 6; i++)
885		close(sfd[i]);
886	close(fd);
887	exit(1);
888}
889
890#define MAP_SIZE (32 * 1024)
891
892static void test_map_large(void)
893{
894	struct bigkey {
895		int a;
896		char b[116];
897		long long c;
898	} key;
899	int fd, i, value;
900
901	fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
902			    MAP_SIZE, map_flags);
903	if (fd < 0) {
904		printf("Failed to create large map '%s'!\n", strerror(errno));
905		exit(1);
906	}
907
908	for (i = 0; i < MAP_SIZE; i++) {
909		key = (struct bigkey) { .c = i };
910		value = i;
911
912		assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == 0);
913	}
914
915	key.c = -1;
916	assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
917	       errno == E2BIG);
918
919	/* Iterate through all elements. */
920	assert(bpf_map_get_next_key(fd, NULL, &key) == 0);
921	key.c = -1;
922	for (i = 0; i < MAP_SIZE; i++)
923		assert(bpf_map_get_next_key(fd, &key, &key) == 0);
924	assert(bpf_map_get_next_key(fd, &key, &key) == -1 && errno == ENOENT);
925
926	key.c = 0;
927	assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 0);
928	key.a = 1;
929	assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == ENOENT);
930
931	close(fd);
932}
933
934static void run_parallel(int tasks, void (*fn)(int task, void *data),
935			 void *data)
936{
937	pid_t pid[tasks];
938	int i;
939
940	for (i = 0; i < tasks; i++) {
941		pid[i] = fork();
942		if (pid[i] == 0) {
943			fn(i, data);
944			exit(0);
945		} else if (pid[i] == -1) {
946			printf("Couldn't spawn #%d process!\n", i);
947			exit(1);
948		}
949	}
950
951	for (i = 0; i < tasks; i++) {
952		int status;
953
954		assert(waitpid(pid[i], &status, 0) == pid[i]);
955		assert(status == 0);
956	}
957}
958
959static void test_map_stress(void)
960{
961	run_parallel(100, test_hashmap, NULL);
962	run_parallel(100, test_hashmap_percpu, NULL);
963	run_parallel(100, test_hashmap_sizes, NULL);
964	run_parallel(100, test_hashmap_walk, NULL);
965
966	run_parallel(100, test_arraymap, NULL);
967	run_parallel(100, test_arraymap_percpu, NULL);
968}
969
970#define TASKS 1024
971
972#define DO_UPDATE 1
973#define DO_DELETE 0
974
975static void do_work(int fn, void *data)
976{
977	int do_update = ((int *)data)[1];
978	int fd = ((int *)data)[0];
979	int i, key, value;
980
981	for (i = fn; i < MAP_SIZE; i += TASKS) {
982		key = value = i;
983
984		if (do_update) {
985			assert(bpf_map_update_elem(fd, &key, &value,
986						   BPF_NOEXIST) == 0);
987			assert(bpf_map_update_elem(fd, &key, &value,
988						   BPF_EXIST) == 0);
989		} else {
990			assert(bpf_map_delete_elem(fd, &key) == 0);
991		}
992	}
993}
994
995static void test_map_parallel(void)
996{
997	int i, fd, key = 0, value = 0;
998	int data[2];
999
1000	fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
1001			    MAP_SIZE, map_flags);
1002	if (fd < 0) {
1003		printf("Failed to create map for parallel test '%s'!\n",
1004		       strerror(errno));
1005		exit(1);
1006	}
1007
1008	/* Use the same fd in children to add elements to this map:
1009	 * child_0 adds key=0, key=1024, key=2048, ...
1010	 * child_1 adds key=1, key=1025, key=2049, ...
1011	 * child_1023 adds key=1023, ...
1012	 */
1013	data[0] = fd;
1014	data[1] = DO_UPDATE;
1015	run_parallel(TASKS, do_work, data);
1016
1017	/* Check that key=0 is already there. */
1018	assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
1019	       errno == EEXIST);
1020
1021	/* Check that all elements were inserted. */
1022	assert(bpf_map_get_next_key(fd, NULL, &key) == 0);
1023	key = -1;
1024	for (i = 0; i < MAP_SIZE; i++)
1025		assert(bpf_map_get_next_key(fd, &key, &key) == 0);
1026	assert(bpf_map_get_next_key(fd, &key, &key) == -1 && errno == ENOENT);
1027
1028	/* Another check for all elements */
1029	for (i = 0; i < MAP_SIZE; i++) {
1030		key = MAP_SIZE - i - 1;
1031
1032		assert(bpf_map_lookup_elem(fd, &key, &value) == 0 &&
1033		       value == key);
1034	}
1035
1036	/* Now let's delete all elemenets in parallel. */
1037	data[1] = DO_DELETE;
1038	run_parallel(TASKS, do_work, data);
1039
1040	/* Nothing should be left. */
1041	key = -1;
1042	assert(bpf_map_get_next_key(fd, NULL, &key) == -1 && errno == ENOENT);
1043	assert(bpf_map_get_next_key(fd, &key, &key) == -1 && errno == ENOENT);
1044}
1045
1046static void test_map_rdonly(void)
1047{
1048	int fd, key = 0, value = 0;
1049
1050	fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
1051			    MAP_SIZE, map_flags | BPF_F_RDONLY);
1052	if (fd < 0) {
1053		printf("Failed to create map for read only test '%s'!\n",
1054		       strerror(errno));
1055		exit(1);
1056	}
1057
1058	key = 1;
1059	value = 1234;
1060	/* Insert key=1 element. */
1061	assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == -1 &&
1062	       errno == EPERM);
1063
1064	/* Check that key=2 is not found. */
1065	assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == ENOENT);
1066	assert(bpf_map_get_next_key(fd, &key, &value) == -1 && errno == ENOENT);
1067}
1068
1069static void test_map_wronly(void)
1070{
1071	int fd, key = 0, value = 0;
1072
1073	fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
1074			    MAP_SIZE, map_flags | BPF_F_WRONLY);
1075	if (fd < 0) {
1076		printf("Failed to create map for read only test '%s'!\n",
1077		       strerror(errno));
1078		exit(1);
1079	}
1080
1081	key = 1;
1082	value = 1234;
1083	/* Insert key=1 element. */
1084	assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
1085
1086	/* Check that key=2 is not found. */
1087	assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == EPERM);
1088	assert(bpf_map_get_next_key(fd, &key, &value) == -1 && errno == EPERM);
1089}
1090
1091static void run_all_tests(void)
1092{
1093	test_hashmap(0, NULL);
1094	test_hashmap_percpu(0, NULL);
1095	test_hashmap_walk(0, NULL);
1096
1097	test_arraymap(0, NULL);
1098	test_arraymap_percpu(0, NULL);
1099
1100	test_arraymap_percpu_many_keys();
1101
1102	test_devmap(0, NULL);
1103	test_sockmap(0, NULL);
1104
1105	test_map_large();
1106	test_map_parallel();
1107	test_map_stress();
1108
1109	test_map_rdonly();
1110	test_map_wronly();
1111}
1112
1113int main(void)
1114{
1115	struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
1116
1117	setrlimit(RLIMIT_MEMLOCK, &rinf);
1118
1119	map_flags = 0;
1120	run_all_tests();
1121
1122	map_flags = BPF_F_NO_PREALLOC;
1123	run_all_tests();
1124
1125	printf("test_maps: OK\n");
1126	return 0;
1127}
1128