cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

test_maps.c (50829B)


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