Home | History | Annotate | Download | only in bpf
      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 
     28 static int map_flags;
     29 
     30 static 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 
    120 static 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 
    138 static 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 
    243 static 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 
    291 static 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 
    346 static 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 
    405 static 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 
    442 static 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"
    464 static 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;
    878 out:
    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);
    883 out_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 
    892 static 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 
    934 static 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 
    959 static 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 
    975 static 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 
    995 static 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 
   1046 static 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 
   1069 static 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 
   1091 static 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 
   1113 int 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