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

bpf_iter.c (32907B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright (c) 2020 Facebook */
      3#include <test_progs.h>
      4#include "bpf_iter_ipv6_route.skel.h"
      5#include "bpf_iter_netlink.skel.h"
      6#include "bpf_iter_bpf_map.skel.h"
      7#include "bpf_iter_task.skel.h"
      8#include "bpf_iter_task_stack.skel.h"
      9#include "bpf_iter_task_file.skel.h"
     10#include "bpf_iter_task_vma.skel.h"
     11#include "bpf_iter_task_btf.skel.h"
     12#include "bpf_iter_tcp4.skel.h"
     13#include "bpf_iter_tcp6.skel.h"
     14#include "bpf_iter_udp4.skel.h"
     15#include "bpf_iter_udp6.skel.h"
     16#include "bpf_iter_unix.skel.h"
     17#include "bpf_iter_test_kern1.skel.h"
     18#include "bpf_iter_test_kern2.skel.h"
     19#include "bpf_iter_test_kern3.skel.h"
     20#include "bpf_iter_test_kern4.skel.h"
     21#include "bpf_iter_bpf_hash_map.skel.h"
     22#include "bpf_iter_bpf_percpu_hash_map.skel.h"
     23#include "bpf_iter_bpf_array_map.skel.h"
     24#include "bpf_iter_bpf_percpu_array_map.skel.h"
     25#include "bpf_iter_bpf_sk_storage_helpers.skel.h"
     26#include "bpf_iter_bpf_sk_storage_map.skel.h"
     27#include "bpf_iter_test_kern5.skel.h"
     28#include "bpf_iter_test_kern6.skel.h"
     29#include "bpf_iter_bpf_link.skel.h"
     30
     31static int duration;
     32
     33static void test_btf_id_or_null(void)
     34{
     35	struct bpf_iter_test_kern3 *skel;
     36
     37	skel = bpf_iter_test_kern3__open_and_load();
     38	if (!ASSERT_ERR_PTR(skel, "bpf_iter_test_kern3__open_and_load")) {
     39		bpf_iter_test_kern3__destroy(skel);
     40		return;
     41	}
     42}
     43
     44static void do_dummy_read(struct bpf_program *prog)
     45{
     46	struct bpf_link *link;
     47	char buf[16] = {};
     48	int iter_fd, len;
     49
     50	link = bpf_program__attach_iter(prog, NULL);
     51	if (!ASSERT_OK_PTR(link, "attach_iter"))
     52		return;
     53
     54	iter_fd = bpf_iter_create(bpf_link__fd(link));
     55	if (!ASSERT_GE(iter_fd, 0, "create_iter"))
     56		goto free_link;
     57
     58	/* not check contents, but ensure read() ends without error */
     59	while ((len = read(iter_fd, buf, sizeof(buf))) > 0)
     60		;
     61	CHECK(len < 0, "read", "read failed: %s\n", strerror(errno));
     62
     63	close(iter_fd);
     64
     65free_link:
     66	bpf_link__destroy(link);
     67}
     68
     69static int read_fd_into_buffer(int fd, char *buf, int size)
     70{
     71	int bufleft = size;
     72	int len;
     73
     74	do {
     75		len = read(fd, buf, bufleft);
     76		if (len > 0) {
     77			buf += len;
     78			bufleft -= len;
     79		}
     80	} while (len > 0);
     81
     82	return len < 0 ? len : size - bufleft;
     83}
     84
     85static void test_ipv6_route(void)
     86{
     87	struct bpf_iter_ipv6_route *skel;
     88
     89	skel = bpf_iter_ipv6_route__open_and_load();
     90	if (!ASSERT_OK_PTR(skel, "bpf_iter_ipv6_route__open_and_load"))
     91		return;
     92
     93	do_dummy_read(skel->progs.dump_ipv6_route);
     94
     95	bpf_iter_ipv6_route__destroy(skel);
     96}
     97
     98static void test_netlink(void)
     99{
    100	struct bpf_iter_netlink *skel;
    101
    102	skel = bpf_iter_netlink__open_and_load();
    103	if (!ASSERT_OK_PTR(skel, "bpf_iter_netlink__open_and_load"))
    104		return;
    105
    106	do_dummy_read(skel->progs.dump_netlink);
    107
    108	bpf_iter_netlink__destroy(skel);
    109}
    110
    111static void test_bpf_map(void)
    112{
    113	struct bpf_iter_bpf_map *skel;
    114
    115	skel = bpf_iter_bpf_map__open_and_load();
    116	if (!ASSERT_OK_PTR(skel, "bpf_iter_bpf_map__open_and_load"))
    117		return;
    118
    119	do_dummy_read(skel->progs.dump_bpf_map);
    120
    121	bpf_iter_bpf_map__destroy(skel);
    122}
    123
    124static void test_task(void)
    125{
    126	struct bpf_iter_task *skel;
    127
    128	skel = bpf_iter_task__open_and_load();
    129	if (!ASSERT_OK_PTR(skel, "bpf_iter_task__open_and_load"))
    130		return;
    131
    132	do_dummy_read(skel->progs.dump_task);
    133
    134	bpf_iter_task__destroy(skel);
    135}
    136
    137static void test_task_sleepable(void)
    138{
    139	struct bpf_iter_task *skel;
    140
    141	skel = bpf_iter_task__open_and_load();
    142	if (!ASSERT_OK_PTR(skel, "bpf_iter_task__open_and_load"))
    143		return;
    144
    145	do_dummy_read(skel->progs.dump_task_sleepable);
    146
    147	ASSERT_GT(skel->bss->num_expected_failure_copy_from_user_task, 0,
    148		  "num_expected_failure_copy_from_user_task");
    149	ASSERT_GT(skel->bss->num_success_copy_from_user_task, 0,
    150		  "num_success_copy_from_user_task");
    151
    152	bpf_iter_task__destroy(skel);
    153}
    154
    155static void test_task_stack(void)
    156{
    157	struct bpf_iter_task_stack *skel;
    158
    159	skel = bpf_iter_task_stack__open_and_load();
    160	if (!ASSERT_OK_PTR(skel, "bpf_iter_task_stack__open_and_load"))
    161		return;
    162
    163	do_dummy_read(skel->progs.dump_task_stack);
    164	do_dummy_read(skel->progs.get_task_user_stacks);
    165
    166	bpf_iter_task_stack__destroy(skel);
    167}
    168
    169static void *do_nothing(void *arg)
    170{
    171	pthread_exit(arg);
    172}
    173
    174static void test_task_file(void)
    175{
    176	struct bpf_iter_task_file *skel;
    177	pthread_t thread_id;
    178	void *ret;
    179
    180	skel = bpf_iter_task_file__open_and_load();
    181	if (!ASSERT_OK_PTR(skel, "bpf_iter_task_file__open_and_load"))
    182		return;
    183
    184	skel->bss->tgid = getpid();
    185
    186	if (!ASSERT_OK(pthread_create(&thread_id, NULL, &do_nothing, NULL),
    187		  "pthread_create"))
    188		goto done;
    189
    190	do_dummy_read(skel->progs.dump_task_file);
    191
    192	if (!ASSERT_FALSE(pthread_join(thread_id, &ret) || ret != NULL,
    193		  "pthread_join"))
    194		goto done;
    195
    196	ASSERT_EQ(skel->bss->count, 0, "check_count");
    197
    198done:
    199	bpf_iter_task_file__destroy(skel);
    200}
    201
    202#define TASKBUFSZ		32768
    203
    204static char taskbuf[TASKBUFSZ];
    205
    206static int do_btf_read(struct bpf_iter_task_btf *skel)
    207{
    208	struct bpf_program *prog = skel->progs.dump_task_struct;
    209	struct bpf_iter_task_btf__bss *bss = skel->bss;
    210	int iter_fd = -1, err;
    211	struct bpf_link *link;
    212	char *buf = taskbuf;
    213	int ret = 0;
    214
    215	link = bpf_program__attach_iter(prog, NULL);
    216	if (!ASSERT_OK_PTR(link, "attach_iter"))
    217		return ret;
    218
    219	iter_fd = bpf_iter_create(bpf_link__fd(link));
    220	if (!ASSERT_GE(iter_fd, 0, "create_iter"))
    221		goto free_link;
    222
    223	err = read_fd_into_buffer(iter_fd, buf, TASKBUFSZ);
    224	if (bss->skip) {
    225		printf("%s:SKIP:no __builtin_btf_type_id\n", __func__);
    226		ret = 1;
    227		test__skip();
    228		goto free_link;
    229	}
    230
    231	if (CHECK(err < 0, "read", "read failed: %s\n", strerror(errno)))
    232		goto free_link;
    233
    234	ASSERT_HAS_SUBSTR(taskbuf, "(struct task_struct)",
    235	      "check for btf representation of task_struct in iter data");
    236free_link:
    237	if (iter_fd > 0)
    238		close(iter_fd);
    239	bpf_link__destroy(link);
    240	return ret;
    241}
    242
    243static void test_task_btf(void)
    244{
    245	struct bpf_iter_task_btf__bss *bss;
    246	struct bpf_iter_task_btf *skel;
    247	int ret;
    248
    249	skel = bpf_iter_task_btf__open_and_load();
    250	if (!ASSERT_OK_PTR(skel, "bpf_iter_task_btf__open_and_load"))
    251		return;
    252
    253	bss = skel->bss;
    254
    255	ret = do_btf_read(skel);
    256	if (ret)
    257		goto cleanup;
    258
    259	if (!ASSERT_NEQ(bss->tasks, 0, "no task iteration, did BPF program run?"))
    260		goto cleanup;
    261
    262	ASSERT_EQ(bss->seq_err, 0, "check for unexpected err");
    263
    264cleanup:
    265	bpf_iter_task_btf__destroy(skel);
    266}
    267
    268static void test_tcp4(void)
    269{
    270	struct bpf_iter_tcp4 *skel;
    271
    272	skel = bpf_iter_tcp4__open_and_load();
    273	if (!ASSERT_OK_PTR(skel, "bpf_iter_tcp4__open_and_load"))
    274		return;
    275
    276	do_dummy_read(skel->progs.dump_tcp4);
    277
    278	bpf_iter_tcp4__destroy(skel);
    279}
    280
    281static void test_tcp6(void)
    282{
    283	struct bpf_iter_tcp6 *skel;
    284
    285	skel = bpf_iter_tcp6__open_and_load();
    286	if (!ASSERT_OK_PTR(skel, "bpf_iter_tcp6__open_and_load"))
    287		return;
    288
    289	do_dummy_read(skel->progs.dump_tcp6);
    290
    291	bpf_iter_tcp6__destroy(skel);
    292}
    293
    294static void test_udp4(void)
    295{
    296	struct bpf_iter_udp4 *skel;
    297
    298	skel = bpf_iter_udp4__open_and_load();
    299	if (!ASSERT_OK_PTR(skel, "bpf_iter_udp4__open_and_load"))
    300		return;
    301
    302	do_dummy_read(skel->progs.dump_udp4);
    303
    304	bpf_iter_udp4__destroy(skel);
    305}
    306
    307static void test_udp6(void)
    308{
    309	struct bpf_iter_udp6 *skel;
    310
    311	skel = bpf_iter_udp6__open_and_load();
    312	if (!ASSERT_OK_PTR(skel, "bpf_iter_udp6__open_and_load"))
    313		return;
    314
    315	do_dummy_read(skel->progs.dump_udp6);
    316
    317	bpf_iter_udp6__destroy(skel);
    318}
    319
    320static void test_unix(void)
    321{
    322	struct bpf_iter_unix *skel;
    323
    324	skel = bpf_iter_unix__open_and_load();
    325	if (!ASSERT_OK_PTR(skel, "bpf_iter_unix__open_and_load"))
    326		return;
    327
    328	do_dummy_read(skel->progs.dump_unix);
    329
    330	bpf_iter_unix__destroy(skel);
    331}
    332
    333/* The expected string is less than 16 bytes */
    334static int do_read_with_fd(int iter_fd, const char *expected,
    335			   bool read_one_char)
    336{
    337	int len, read_buf_len, start;
    338	char buf[16] = {};
    339
    340	read_buf_len = read_one_char ? 1 : 16;
    341	start = 0;
    342	while ((len = read(iter_fd, buf + start, read_buf_len)) > 0) {
    343		start += len;
    344		if (CHECK(start >= 16, "read", "read len %d\n", len))
    345			return -1;
    346		read_buf_len = read_one_char ? 1 : 16 - start;
    347	}
    348	if (CHECK(len < 0, "read", "read failed: %s\n", strerror(errno)))
    349		return -1;
    350
    351	if (!ASSERT_STREQ(buf, expected, "read"))
    352		return -1;
    353
    354	return 0;
    355}
    356
    357static void test_anon_iter(bool read_one_char)
    358{
    359	struct bpf_iter_test_kern1 *skel;
    360	struct bpf_link *link;
    361	int iter_fd, err;
    362
    363	skel = bpf_iter_test_kern1__open_and_load();
    364	if (!ASSERT_OK_PTR(skel, "bpf_iter_test_kern1__open_and_load"))
    365		return;
    366
    367	err = bpf_iter_test_kern1__attach(skel);
    368	if (!ASSERT_OK(err, "bpf_iter_test_kern1__attach")) {
    369		goto out;
    370	}
    371
    372	link = skel->links.dump_task;
    373	iter_fd = bpf_iter_create(bpf_link__fd(link));
    374	if (!ASSERT_GE(iter_fd, 0, "create_iter"))
    375		goto out;
    376
    377	do_read_with_fd(iter_fd, "abcd", read_one_char);
    378	close(iter_fd);
    379
    380out:
    381	bpf_iter_test_kern1__destroy(skel);
    382}
    383
    384static int do_read(const char *path, const char *expected)
    385{
    386	int err, iter_fd;
    387
    388	iter_fd = open(path, O_RDONLY);
    389	if (CHECK(iter_fd < 0, "open", "open %s failed: %s\n",
    390		  path, strerror(errno)))
    391		return -1;
    392
    393	err = do_read_with_fd(iter_fd, expected, false);
    394	close(iter_fd);
    395	return err;
    396}
    397
    398static void test_file_iter(void)
    399{
    400	const char *path = "/sys/fs/bpf/bpf_iter_test1";
    401	struct bpf_iter_test_kern1 *skel1;
    402	struct bpf_iter_test_kern2 *skel2;
    403	struct bpf_link *link;
    404	int err;
    405
    406	skel1 = bpf_iter_test_kern1__open_and_load();
    407	if (!ASSERT_OK_PTR(skel1, "bpf_iter_test_kern1__open_and_load"))
    408		return;
    409
    410	link = bpf_program__attach_iter(skel1->progs.dump_task, NULL);
    411	if (!ASSERT_OK_PTR(link, "attach_iter"))
    412		goto out;
    413
    414	/* unlink this path if it exists. */
    415	unlink(path);
    416
    417	err = bpf_link__pin(link, path);
    418	if (CHECK(err, "pin_iter", "pin_iter to %s failed: %d\n", path, err))
    419		goto free_link;
    420
    421	err = do_read(path, "abcd");
    422	if (err)
    423		goto unlink_path;
    424
    425	/* file based iterator seems working fine. Let us a link update
    426	 * of the underlying link and `cat` the iterator again, its content
    427	 * should change.
    428	 */
    429	skel2 = bpf_iter_test_kern2__open_and_load();
    430	if (!ASSERT_OK_PTR(skel2, "bpf_iter_test_kern2__open_and_load"))
    431		goto unlink_path;
    432
    433	err = bpf_link__update_program(link, skel2->progs.dump_task);
    434	if (!ASSERT_OK(err, "update_prog"))
    435		goto destroy_skel2;
    436
    437	do_read(path, "ABCD");
    438
    439destroy_skel2:
    440	bpf_iter_test_kern2__destroy(skel2);
    441unlink_path:
    442	unlink(path);
    443free_link:
    444	bpf_link__destroy(link);
    445out:
    446	bpf_iter_test_kern1__destroy(skel1);
    447}
    448
    449static void test_overflow(bool test_e2big_overflow, bool ret1)
    450{
    451	__u32 map_info_len, total_read_len, expected_read_len;
    452	int err, iter_fd, map1_fd, map2_fd, len;
    453	struct bpf_map_info map_info = {};
    454	struct bpf_iter_test_kern4 *skel;
    455	struct bpf_link *link;
    456	__u32 iter_size;
    457	char *buf;
    458
    459	skel = bpf_iter_test_kern4__open();
    460	if (!ASSERT_OK_PTR(skel, "bpf_iter_test_kern4__open"))
    461		return;
    462
    463	/* create two maps: bpf program will only do bpf_seq_write
    464	 * for these two maps. The goal is one map output almost
    465	 * fills seq_file buffer and then the other will trigger
    466	 * overflow and needs restart.
    467	 */
    468	map1_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, NULL, 4, 8, 1, NULL);
    469	if (CHECK(map1_fd < 0, "bpf_map_create",
    470		  "map_creation failed: %s\n", strerror(errno)))
    471		goto out;
    472	map2_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, NULL, 4, 8, 1, NULL);
    473	if (CHECK(map2_fd < 0, "bpf_map_create",
    474		  "map_creation failed: %s\n", strerror(errno)))
    475		goto free_map1;
    476
    477	/* bpf_seq_printf kernel buffer is 8 pages, so one map
    478	 * bpf_seq_write will mostly fill it, and the other map
    479	 * will partially fill and then trigger overflow and need
    480	 * bpf_seq_read restart.
    481	 */
    482	iter_size = sysconf(_SC_PAGE_SIZE) << 3;
    483
    484	if (test_e2big_overflow) {
    485		skel->rodata->print_len = (iter_size + 8) / 8;
    486		expected_read_len = 2 * (iter_size + 8);
    487	} else if (!ret1) {
    488		skel->rodata->print_len = (iter_size - 8) / 8;
    489		expected_read_len = 2 * (iter_size - 8);
    490	} else {
    491		skel->rodata->print_len = 1;
    492		expected_read_len = 2 * 8;
    493	}
    494	skel->rodata->ret1 = ret1;
    495
    496	if (!ASSERT_OK(bpf_iter_test_kern4__load(skel),
    497		  "bpf_iter_test_kern4__load"))
    498		goto free_map2;
    499
    500	/* setup filtering map_id in bpf program */
    501	map_info_len = sizeof(map_info);
    502	err = bpf_obj_get_info_by_fd(map1_fd, &map_info, &map_info_len);
    503	if (CHECK(err, "get_map_info", "get map info failed: %s\n",
    504		  strerror(errno)))
    505		goto free_map2;
    506	skel->bss->map1_id = map_info.id;
    507
    508	err = bpf_obj_get_info_by_fd(map2_fd, &map_info, &map_info_len);
    509	if (CHECK(err, "get_map_info", "get map info failed: %s\n",
    510		  strerror(errno)))
    511		goto free_map2;
    512	skel->bss->map2_id = map_info.id;
    513
    514	link = bpf_program__attach_iter(skel->progs.dump_bpf_map, NULL);
    515	if (!ASSERT_OK_PTR(link, "attach_iter"))
    516		goto free_map2;
    517
    518	iter_fd = bpf_iter_create(bpf_link__fd(link));
    519	if (!ASSERT_GE(iter_fd, 0, "create_iter"))
    520		goto free_link;
    521
    522	buf = malloc(expected_read_len);
    523	if (!buf)
    524		goto close_iter;
    525
    526	/* do read */
    527	total_read_len = 0;
    528	if (test_e2big_overflow) {
    529		while ((len = read(iter_fd, buf, expected_read_len)) > 0)
    530			total_read_len += len;
    531
    532		CHECK(len != -1 || errno != E2BIG, "read",
    533		      "expected ret -1, errno E2BIG, but get ret %d, error %s\n",
    534			  len, strerror(errno));
    535		goto free_buf;
    536	} else if (!ret1) {
    537		while ((len = read(iter_fd, buf, expected_read_len)) > 0)
    538			total_read_len += len;
    539
    540		if (CHECK(len < 0, "read", "read failed: %s\n",
    541			  strerror(errno)))
    542			goto free_buf;
    543	} else {
    544		do {
    545			len = read(iter_fd, buf, expected_read_len);
    546			if (len > 0)
    547				total_read_len += len;
    548		} while (len > 0 || len == -EAGAIN);
    549
    550		if (CHECK(len < 0, "read", "read failed: %s\n",
    551			  strerror(errno)))
    552			goto free_buf;
    553	}
    554
    555	if (!ASSERT_EQ(total_read_len, expected_read_len, "read"))
    556		goto free_buf;
    557
    558	if (!ASSERT_EQ(skel->bss->map1_accessed, 1, "map1_accessed"))
    559		goto free_buf;
    560
    561	if (!ASSERT_EQ(skel->bss->map2_accessed, 2, "map2_accessed"))
    562		goto free_buf;
    563
    564	ASSERT_EQ(skel->bss->map2_seqnum1, skel->bss->map2_seqnum2, "map2_seqnum");
    565
    566free_buf:
    567	free(buf);
    568close_iter:
    569	close(iter_fd);
    570free_link:
    571	bpf_link__destroy(link);
    572free_map2:
    573	close(map2_fd);
    574free_map1:
    575	close(map1_fd);
    576out:
    577	bpf_iter_test_kern4__destroy(skel);
    578}
    579
    580static void test_bpf_hash_map(void)
    581{
    582	__u32 expected_key_a = 0, expected_key_b = 0;
    583	DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, opts);
    584	struct bpf_iter_bpf_hash_map *skel;
    585	int err, i, len, map_fd, iter_fd;
    586	union bpf_iter_link_info linfo;
    587	__u64 val, expected_val = 0;
    588	struct bpf_link *link;
    589	struct key_t {
    590		int a;
    591		int b;
    592		int c;
    593	} key;
    594	char buf[64];
    595
    596	skel = bpf_iter_bpf_hash_map__open();
    597	if (!ASSERT_OK_PTR(skel, "bpf_iter_bpf_hash_map__open"))
    598		return;
    599
    600	skel->bss->in_test_mode = true;
    601
    602	err = bpf_iter_bpf_hash_map__load(skel);
    603	if (!ASSERT_OK(err, "bpf_iter_bpf_hash_map__load"))
    604		goto out;
    605
    606	/* iterator with hashmap2 and hashmap3 should fail */
    607	memset(&linfo, 0, sizeof(linfo));
    608	linfo.map.map_fd = bpf_map__fd(skel->maps.hashmap2);
    609	opts.link_info = &linfo;
    610	opts.link_info_len = sizeof(linfo);
    611	link = bpf_program__attach_iter(skel->progs.dump_bpf_hash_map, &opts);
    612	if (!ASSERT_ERR_PTR(link, "attach_iter"))
    613		goto out;
    614
    615	linfo.map.map_fd = bpf_map__fd(skel->maps.hashmap3);
    616	link = bpf_program__attach_iter(skel->progs.dump_bpf_hash_map, &opts);
    617	if (!ASSERT_ERR_PTR(link, "attach_iter"))
    618		goto out;
    619
    620	/* hashmap1 should be good, update map values here */
    621	map_fd = bpf_map__fd(skel->maps.hashmap1);
    622	for (i = 0; i < bpf_map__max_entries(skel->maps.hashmap1); i++) {
    623		key.a = i + 1;
    624		key.b = i + 2;
    625		key.c = i + 3;
    626		val = i + 4;
    627		expected_key_a += key.a;
    628		expected_key_b += key.b;
    629		expected_val += val;
    630
    631		err = bpf_map_update_elem(map_fd, &key, &val, BPF_ANY);
    632		if (!ASSERT_OK(err, "map_update"))
    633			goto out;
    634	}
    635
    636	linfo.map.map_fd = map_fd;
    637	link = bpf_program__attach_iter(skel->progs.dump_bpf_hash_map, &opts);
    638	if (!ASSERT_OK_PTR(link, "attach_iter"))
    639		goto out;
    640
    641	iter_fd = bpf_iter_create(bpf_link__fd(link));
    642	if (!ASSERT_GE(iter_fd, 0, "create_iter"))
    643		goto free_link;
    644
    645	/* do some tests */
    646	while ((len = read(iter_fd, buf, sizeof(buf))) > 0)
    647		;
    648	if (CHECK(len < 0, "read", "read failed: %s\n", strerror(errno)))
    649		goto close_iter;
    650
    651	/* test results */
    652	if (!ASSERT_EQ(skel->bss->key_sum_a, expected_key_a, "key_sum_a"))
    653		goto close_iter;
    654	if (!ASSERT_EQ(skel->bss->key_sum_b, expected_key_b, "key_sum_b"))
    655		goto close_iter;
    656	if (!ASSERT_EQ(skel->bss->val_sum, expected_val, "val_sum"))
    657		goto close_iter;
    658
    659close_iter:
    660	close(iter_fd);
    661free_link:
    662	bpf_link__destroy(link);
    663out:
    664	bpf_iter_bpf_hash_map__destroy(skel);
    665}
    666
    667static void test_bpf_percpu_hash_map(void)
    668{
    669	__u32 expected_key_a = 0, expected_key_b = 0;
    670	DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, opts);
    671	struct bpf_iter_bpf_percpu_hash_map *skel;
    672	int err, i, j, len, map_fd, iter_fd;
    673	union bpf_iter_link_info linfo;
    674	__u32 expected_val = 0;
    675	struct bpf_link *link;
    676	struct key_t {
    677		int a;
    678		int b;
    679		int c;
    680	} key;
    681	char buf[64];
    682	void *val;
    683
    684	skel = bpf_iter_bpf_percpu_hash_map__open();
    685	if (!ASSERT_OK_PTR(skel, "bpf_iter_bpf_percpu_hash_map__open"))
    686		return;
    687
    688	skel->rodata->num_cpus = bpf_num_possible_cpus();
    689	val = malloc(8 * bpf_num_possible_cpus());
    690
    691	err = bpf_iter_bpf_percpu_hash_map__load(skel);
    692	if (!ASSERT_OK_PTR(skel, "bpf_iter_bpf_percpu_hash_map__load"))
    693		goto out;
    694
    695	/* update map values here */
    696	map_fd = bpf_map__fd(skel->maps.hashmap1);
    697	for (i = 0; i < bpf_map__max_entries(skel->maps.hashmap1); i++) {
    698		key.a = i + 1;
    699		key.b = i + 2;
    700		key.c = i + 3;
    701		expected_key_a += key.a;
    702		expected_key_b += key.b;
    703
    704		for (j = 0; j < bpf_num_possible_cpus(); j++) {
    705			*(__u32 *)(val + j * 8) = i + j;
    706			expected_val += i + j;
    707		}
    708
    709		err = bpf_map_update_elem(map_fd, &key, val, BPF_ANY);
    710		if (!ASSERT_OK(err, "map_update"))
    711			goto out;
    712	}
    713
    714	memset(&linfo, 0, sizeof(linfo));
    715	linfo.map.map_fd = map_fd;
    716	opts.link_info = &linfo;
    717	opts.link_info_len = sizeof(linfo);
    718	link = bpf_program__attach_iter(skel->progs.dump_bpf_percpu_hash_map, &opts);
    719	if (!ASSERT_OK_PTR(link, "attach_iter"))
    720		goto out;
    721
    722	iter_fd = bpf_iter_create(bpf_link__fd(link));
    723	if (!ASSERT_GE(iter_fd, 0, "create_iter"))
    724		goto free_link;
    725
    726	/* do some tests */
    727	while ((len = read(iter_fd, buf, sizeof(buf))) > 0)
    728		;
    729	if (CHECK(len < 0, "read", "read failed: %s\n", strerror(errno)))
    730		goto close_iter;
    731
    732	/* test results */
    733	if (!ASSERT_EQ(skel->bss->key_sum_a, expected_key_a, "key_sum_a"))
    734		goto close_iter;
    735	if (!ASSERT_EQ(skel->bss->key_sum_b, expected_key_b, "key_sum_b"))
    736		goto close_iter;
    737	if (!ASSERT_EQ(skel->bss->val_sum, expected_val, "val_sum"))
    738		goto close_iter;
    739
    740close_iter:
    741	close(iter_fd);
    742free_link:
    743	bpf_link__destroy(link);
    744out:
    745	bpf_iter_bpf_percpu_hash_map__destroy(skel);
    746	free(val);
    747}
    748
    749static void test_bpf_array_map(void)
    750{
    751	__u64 val, expected_val = 0, res_first_val, first_val = 0;
    752	DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, opts);
    753	__u32 expected_key = 0, res_first_key;
    754	struct bpf_iter_bpf_array_map *skel;
    755	union bpf_iter_link_info linfo;
    756	int err, i, map_fd, iter_fd;
    757	struct bpf_link *link;
    758	char buf[64] = {};
    759	int len, start;
    760
    761	skel = bpf_iter_bpf_array_map__open_and_load();
    762	if (!ASSERT_OK_PTR(skel, "bpf_iter_bpf_array_map__open_and_load"))
    763		return;
    764
    765	map_fd = bpf_map__fd(skel->maps.arraymap1);
    766	for (i = 0; i < bpf_map__max_entries(skel->maps.arraymap1); i++) {
    767		val = i + 4;
    768		expected_key += i;
    769		expected_val += val;
    770
    771		if (i == 0)
    772			first_val = val;
    773
    774		err = bpf_map_update_elem(map_fd, &i, &val, BPF_ANY);
    775		if (!ASSERT_OK(err, "map_update"))
    776			goto out;
    777	}
    778
    779	memset(&linfo, 0, sizeof(linfo));
    780	linfo.map.map_fd = map_fd;
    781	opts.link_info = &linfo;
    782	opts.link_info_len = sizeof(linfo);
    783	link = bpf_program__attach_iter(skel->progs.dump_bpf_array_map, &opts);
    784	if (!ASSERT_OK_PTR(link, "attach_iter"))
    785		goto out;
    786
    787	iter_fd = bpf_iter_create(bpf_link__fd(link));
    788	if (!ASSERT_GE(iter_fd, 0, "create_iter"))
    789		goto free_link;
    790
    791	/* do some tests */
    792	start = 0;
    793	while ((len = read(iter_fd, buf + start, sizeof(buf) - start)) > 0)
    794		start += len;
    795	if (CHECK(len < 0, "read", "read failed: %s\n", strerror(errno)))
    796		goto close_iter;
    797
    798	/* test results */
    799	res_first_key = *(__u32 *)buf;
    800	res_first_val = *(__u64 *)(buf + sizeof(__u32));
    801	if (CHECK(res_first_key != 0 || res_first_val != first_val,
    802		  "bpf_seq_write",
    803		  "seq_write failure: first key %u vs expected 0, "
    804		  " first value %llu vs expected %llu\n",
    805		  res_first_key, res_first_val, first_val))
    806		goto close_iter;
    807
    808	if (!ASSERT_EQ(skel->bss->key_sum, expected_key, "key_sum"))
    809		goto close_iter;
    810	if (!ASSERT_EQ(skel->bss->val_sum, expected_val, "val_sum"))
    811		goto close_iter;
    812
    813	for (i = 0; i < bpf_map__max_entries(skel->maps.arraymap1); i++) {
    814		err = bpf_map_lookup_elem(map_fd, &i, &val);
    815		if (!ASSERT_OK(err, "map_lookup"))
    816			goto out;
    817		if (!ASSERT_EQ(i, val, "invalid_val"))
    818			goto out;
    819	}
    820
    821close_iter:
    822	close(iter_fd);
    823free_link:
    824	bpf_link__destroy(link);
    825out:
    826	bpf_iter_bpf_array_map__destroy(skel);
    827}
    828
    829static void test_bpf_percpu_array_map(void)
    830{
    831	DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, opts);
    832	struct bpf_iter_bpf_percpu_array_map *skel;
    833	__u32 expected_key = 0, expected_val = 0;
    834	union bpf_iter_link_info linfo;
    835	int err, i, j, map_fd, iter_fd;
    836	struct bpf_link *link;
    837	char buf[64];
    838	void *val;
    839	int len;
    840
    841	skel = bpf_iter_bpf_percpu_array_map__open();
    842	if (!ASSERT_OK_PTR(skel, "bpf_iter_bpf_percpu_array_map__open"))
    843		return;
    844
    845	skel->rodata->num_cpus = bpf_num_possible_cpus();
    846	val = malloc(8 * bpf_num_possible_cpus());
    847
    848	err = bpf_iter_bpf_percpu_array_map__load(skel);
    849	if (!ASSERT_OK_PTR(skel, "bpf_iter_bpf_percpu_array_map__load"))
    850		goto out;
    851
    852	/* update map values here */
    853	map_fd = bpf_map__fd(skel->maps.arraymap1);
    854	for (i = 0; i < bpf_map__max_entries(skel->maps.arraymap1); i++) {
    855		expected_key += i;
    856
    857		for (j = 0; j < bpf_num_possible_cpus(); j++) {
    858			*(__u32 *)(val + j * 8) = i + j;
    859			expected_val += i + j;
    860		}
    861
    862		err = bpf_map_update_elem(map_fd, &i, val, BPF_ANY);
    863		if (!ASSERT_OK(err, "map_update"))
    864			goto out;
    865	}
    866
    867	memset(&linfo, 0, sizeof(linfo));
    868	linfo.map.map_fd = map_fd;
    869	opts.link_info = &linfo;
    870	opts.link_info_len = sizeof(linfo);
    871	link = bpf_program__attach_iter(skel->progs.dump_bpf_percpu_array_map, &opts);
    872	if (!ASSERT_OK_PTR(link, "attach_iter"))
    873		goto out;
    874
    875	iter_fd = bpf_iter_create(bpf_link__fd(link));
    876	if (!ASSERT_GE(iter_fd, 0, "create_iter"))
    877		goto free_link;
    878
    879	/* do some tests */
    880	while ((len = read(iter_fd, buf, sizeof(buf))) > 0)
    881		;
    882	if (CHECK(len < 0, "read", "read failed: %s\n", strerror(errno)))
    883		goto close_iter;
    884
    885	/* test results */
    886	if (!ASSERT_EQ(skel->bss->key_sum, expected_key, "key_sum"))
    887		goto close_iter;
    888	if (!ASSERT_EQ(skel->bss->val_sum, expected_val, "val_sum"))
    889		goto close_iter;
    890
    891close_iter:
    892	close(iter_fd);
    893free_link:
    894	bpf_link__destroy(link);
    895out:
    896	bpf_iter_bpf_percpu_array_map__destroy(skel);
    897	free(val);
    898}
    899
    900/* An iterator program deletes all local storage in a map. */
    901static void test_bpf_sk_storage_delete(void)
    902{
    903	DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, opts);
    904	struct bpf_iter_bpf_sk_storage_helpers *skel;
    905	union bpf_iter_link_info linfo;
    906	int err, len, map_fd, iter_fd;
    907	struct bpf_link *link;
    908	int sock_fd = -1;
    909	__u32 val = 42;
    910	char buf[64];
    911
    912	skel = bpf_iter_bpf_sk_storage_helpers__open_and_load();
    913	if (!ASSERT_OK_PTR(skel, "bpf_iter_bpf_sk_storage_helpers__open_and_load"))
    914		return;
    915
    916	map_fd = bpf_map__fd(skel->maps.sk_stg_map);
    917
    918	sock_fd = socket(AF_INET6, SOCK_STREAM, 0);
    919	if (!ASSERT_GE(sock_fd, 0, "socket"))
    920		goto out;
    921	err = bpf_map_update_elem(map_fd, &sock_fd, &val, BPF_NOEXIST);
    922	if (!ASSERT_OK(err, "map_update"))
    923		goto out;
    924
    925	memset(&linfo, 0, sizeof(linfo));
    926	linfo.map.map_fd = map_fd;
    927	opts.link_info = &linfo;
    928	opts.link_info_len = sizeof(linfo);
    929	link = bpf_program__attach_iter(skel->progs.delete_bpf_sk_storage_map,
    930					&opts);
    931	if (!ASSERT_OK_PTR(link, "attach_iter"))
    932		goto out;
    933
    934	iter_fd = bpf_iter_create(bpf_link__fd(link));
    935	if (!ASSERT_GE(iter_fd, 0, "create_iter"))
    936		goto free_link;
    937
    938	/* do some tests */
    939	while ((len = read(iter_fd, buf, sizeof(buf))) > 0)
    940		;
    941	if (CHECK(len < 0, "read", "read failed: %s\n", strerror(errno)))
    942		goto close_iter;
    943
    944	/* test results */
    945	err = bpf_map_lookup_elem(map_fd, &sock_fd, &val);
    946	if (CHECK(!err || errno != ENOENT, "bpf_map_lookup_elem",
    947		  "map value wasn't deleted (err=%d, errno=%d)\n", err, errno))
    948		goto close_iter;
    949
    950close_iter:
    951	close(iter_fd);
    952free_link:
    953	bpf_link__destroy(link);
    954out:
    955	if (sock_fd >= 0)
    956		close(sock_fd);
    957	bpf_iter_bpf_sk_storage_helpers__destroy(skel);
    958}
    959
    960/* This creates a socket and its local storage. It then runs a task_iter BPF
    961 * program that replaces the existing socket local storage with the tgid of the
    962 * only task owning a file descriptor to this socket, this process, prog_tests.
    963 * It then runs a tcp socket iterator that negates the value in the existing
    964 * socket local storage, the test verifies that the resulting value is -pid.
    965 */
    966static void test_bpf_sk_storage_get(void)
    967{
    968	struct bpf_iter_bpf_sk_storage_helpers *skel;
    969	int err, map_fd, val = -1;
    970	int sock_fd = -1;
    971
    972	skel = bpf_iter_bpf_sk_storage_helpers__open_and_load();
    973	if (!ASSERT_OK_PTR(skel, "bpf_iter_bpf_sk_storage_helpers__open_and_load"))
    974		return;
    975
    976	sock_fd = socket(AF_INET6, SOCK_STREAM, 0);
    977	if (!ASSERT_GE(sock_fd, 0, "socket"))
    978		goto out;
    979
    980	err = listen(sock_fd, 1);
    981	if (!ASSERT_OK(err, "listen"))
    982		goto close_socket;
    983
    984	map_fd = bpf_map__fd(skel->maps.sk_stg_map);
    985
    986	err = bpf_map_update_elem(map_fd, &sock_fd, &val, BPF_NOEXIST);
    987	if (!ASSERT_OK(err, "bpf_map_update_elem"))
    988		goto close_socket;
    989
    990	do_dummy_read(skel->progs.fill_socket_owner);
    991
    992	err = bpf_map_lookup_elem(map_fd, &sock_fd, &val);
    993	if (CHECK(err || val != getpid(), "bpf_map_lookup_elem",
    994	    "map value wasn't set correctly (expected %d, got %d, err=%d)\n",
    995	    getpid(), val, err))
    996		goto close_socket;
    997
    998	do_dummy_read(skel->progs.negate_socket_local_storage);
    999
   1000	err = bpf_map_lookup_elem(map_fd, &sock_fd, &val);
   1001	CHECK(err || val != -getpid(), "bpf_map_lookup_elem",
   1002	      "map value wasn't set correctly (expected %d, got %d, err=%d)\n",
   1003	      -getpid(), val, err);
   1004
   1005close_socket:
   1006	close(sock_fd);
   1007out:
   1008	bpf_iter_bpf_sk_storage_helpers__destroy(skel);
   1009}
   1010
   1011static void test_bpf_sk_storage_map(void)
   1012{
   1013	DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, opts);
   1014	int err, i, len, map_fd, iter_fd, num_sockets;
   1015	struct bpf_iter_bpf_sk_storage_map *skel;
   1016	union bpf_iter_link_info linfo;
   1017	int sock_fd[3] = {-1, -1, -1};
   1018	__u32 val, expected_val = 0;
   1019	struct bpf_link *link;
   1020	char buf[64];
   1021
   1022	skel = bpf_iter_bpf_sk_storage_map__open_and_load();
   1023	if (!ASSERT_OK_PTR(skel, "bpf_iter_bpf_sk_storage_map__open_and_load"))
   1024		return;
   1025
   1026	map_fd = bpf_map__fd(skel->maps.sk_stg_map);
   1027	num_sockets = ARRAY_SIZE(sock_fd);
   1028	for (i = 0; i < num_sockets; i++) {
   1029		sock_fd[i] = socket(AF_INET6, SOCK_STREAM, 0);
   1030		if (!ASSERT_GE(sock_fd[i], 0, "socket"))
   1031			goto out;
   1032
   1033		val = i + 1;
   1034		expected_val += val;
   1035
   1036		err = bpf_map_update_elem(map_fd, &sock_fd[i], &val,
   1037					  BPF_NOEXIST);
   1038		if (!ASSERT_OK(err, "map_update"))
   1039			goto out;
   1040	}
   1041
   1042	memset(&linfo, 0, sizeof(linfo));
   1043	linfo.map.map_fd = map_fd;
   1044	opts.link_info = &linfo;
   1045	opts.link_info_len = sizeof(linfo);
   1046	link = bpf_program__attach_iter(skel->progs.dump_bpf_sk_storage_map, &opts);
   1047	if (!ASSERT_OK_PTR(link, "attach_iter"))
   1048		goto out;
   1049
   1050	iter_fd = bpf_iter_create(bpf_link__fd(link));
   1051	if (!ASSERT_GE(iter_fd, 0, "create_iter"))
   1052		goto free_link;
   1053
   1054	/* do some tests */
   1055	while ((len = read(iter_fd, buf, sizeof(buf))) > 0)
   1056		;
   1057	if (CHECK(len < 0, "read", "read failed: %s\n", strerror(errno)))
   1058		goto close_iter;
   1059
   1060	/* test results */
   1061	if (!ASSERT_EQ(skel->bss->ipv6_sk_count, num_sockets, "ipv6_sk_count"))
   1062		goto close_iter;
   1063
   1064	if (!ASSERT_EQ(skel->bss->val_sum, expected_val, "val_sum"))
   1065		goto close_iter;
   1066
   1067close_iter:
   1068	close(iter_fd);
   1069free_link:
   1070	bpf_link__destroy(link);
   1071out:
   1072	for (i = 0; i < num_sockets; i++) {
   1073		if (sock_fd[i] >= 0)
   1074			close(sock_fd[i]);
   1075	}
   1076	bpf_iter_bpf_sk_storage_map__destroy(skel);
   1077}
   1078
   1079static void test_rdonly_buf_out_of_bound(void)
   1080{
   1081	DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, opts);
   1082	struct bpf_iter_test_kern5 *skel;
   1083	union bpf_iter_link_info linfo;
   1084	struct bpf_link *link;
   1085
   1086	skel = bpf_iter_test_kern5__open_and_load();
   1087	if (!ASSERT_OK_PTR(skel, "bpf_iter_test_kern5__open_and_load"))
   1088		return;
   1089
   1090	memset(&linfo, 0, sizeof(linfo));
   1091	linfo.map.map_fd = bpf_map__fd(skel->maps.hashmap1);
   1092	opts.link_info = &linfo;
   1093	opts.link_info_len = sizeof(linfo);
   1094	link = bpf_program__attach_iter(skel->progs.dump_bpf_hash_map, &opts);
   1095	if (!ASSERT_ERR_PTR(link, "attach_iter"))
   1096		bpf_link__destroy(link);
   1097
   1098	bpf_iter_test_kern5__destroy(skel);
   1099}
   1100
   1101static void test_buf_neg_offset(void)
   1102{
   1103	struct bpf_iter_test_kern6 *skel;
   1104
   1105	skel = bpf_iter_test_kern6__open_and_load();
   1106	if (!ASSERT_ERR_PTR(skel, "bpf_iter_test_kern6__open_and_load"))
   1107		bpf_iter_test_kern6__destroy(skel);
   1108}
   1109
   1110static void test_link_iter(void)
   1111{
   1112	struct bpf_iter_bpf_link *skel;
   1113
   1114	skel = bpf_iter_bpf_link__open_and_load();
   1115	if (!ASSERT_OK_PTR(skel, "bpf_iter_bpf_link__open_and_load"))
   1116		return;
   1117
   1118	do_dummy_read(skel->progs.dump_bpf_link);
   1119
   1120	bpf_iter_bpf_link__destroy(skel);
   1121}
   1122
   1123#define CMP_BUFFER_SIZE 1024
   1124static char task_vma_output[CMP_BUFFER_SIZE];
   1125static char proc_maps_output[CMP_BUFFER_SIZE];
   1126
   1127/* remove \0 and \t from str, and only keep the first line */
   1128static void str_strip_first_line(char *str)
   1129{
   1130	char *dst = str, *src = str;
   1131
   1132	do {
   1133		if (*src == ' ' || *src == '\t')
   1134			src++;
   1135		else
   1136			*(dst++) = *(src++);
   1137
   1138	} while (*src != '\0' && *src != '\n');
   1139
   1140	*dst = '\0';
   1141}
   1142
   1143static void test_task_vma(void)
   1144{
   1145	int err, iter_fd = -1, proc_maps_fd = -1;
   1146	struct bpf_iter_task_vma *skel;
   1147	int len, read_size = 4;
   1148	char maps_path[64];
   1149
   1150	skel = bpf_iter_task_vma__open();
   1151	if (!ASSERT_OK_PTR(skel, "bpf_iter_task_vma__open"))
   1152		return;
   1153
   1154	skel->bss->pid = getpid();
   1155
   1156	err = bpf_iter_task_vma__load(skel);
   1157	if (!ASSERT_OK(err, "bpf_iter_task_vma__load"))
   1158		goto out;
   1159
   1160	skel->links.proc_maps = bpf_program__attach_iter(
   1161		skel->progs.proc_maps, NULL);
   1162
   1163	if (!ASSERT_OK_PTR(skel->links.proc_maps, "bpf_program__attach_iter")) {
   1164		skel->links.proc_maps = NULL;
   1165		goto out;
   1166	}
   1167
   1168	iter_fd = bpf_iter_create(bpf_link__fd(skel->links.proc_maps));
   1169	if (!ASSERT_GE(iter_fd, 0, "create_iter"))
   1170		goto out;
   1171
   1172	/* Read CMP_BUFFER_SIZE (1kB) from bpf_iter. Read in small chunks
   1173	 * to trigger seq_file corner cases.
   1174	 */
   1175	len = 0;
   1176	while (len < CMP_BUFFER_SIZE) {
   1177		err = read_fd_into_buffer(iter_fd, task_vma_output + len,
   1178					  MIN(read_size, CMP_BUFFER_SIZE - len));
   1179		if (!err)
   1180			break;
   1181		if (!ASSERT_GE(err, 0, "read_iter_fd"))
   1182			goto out;
   1183		len += err;
   1184	}
   1185
   1186	/* read CMP_BUFFER_SIZE (1kB) from /proc/pid/maps */
   1187	snprintf(maps_path, 64, "/proc/%u/maps", skel->bss->pid);
   1188	proc_maps_fd = open(maps_path, O_RDONLY);
   1189	if (!ASSERT_GE(proc_maps_fd, 0, "open_proc_maps"))
   1190		goto out;
   1191	err = read_fd_into_buffer(proc_maps_fd, proc_maps_output, CMP_BUFFER_SIZE);
   1192	if (!ASSERT_GE(err, 0, "read_prog_maps_fd"))
   1193		goto out;
   1194
   1195	/* strip and compare the first line of the two files */
   1196	str_strip_first_line(task_vma_output);
   1197	str_strip_first_line(proc_maps_output);
   1198
   1199	ASSERT_STREQ(task_vma_output, proc_maps_output, "compare_output");
   1200out:
   1201	close(proc_maps_fd);
   1202	close(iter_fd);
   1203	bpf_iter_task_vma__destroy(skel);
   1204}
   1205
   1206void test_bpf_iter(void)
   1207{
   1208	if (test__start_subtest("btf_id_or_null"))
   1209		test_btf_id_or_null();
   1210	if (test__start_subtest("ipv6_route"))
   1211		test_ipv6_route();
   1212	if (test__start_subtest("netlink"))
   1213		test_netlink();
   1214	if (test__start_subtest("bpf_map"))
   1215		test_bpf_map();
   1216	if (test__start_subtest("task"))
   1217		test_task();
   1218	if (test__start_subtest("task_sleepable"))
   1219		test_task_sleepable();
   1220	if (test__start_subtest("task_stack"))
   1221		test_task_stack();
   1222	if (test__start_subtest("task_file"))
   1223		test_task_file();
   1224	if (test__start_subtest("task_vma"))
   1225		test_task_vma();
   1226	if (test__start_subtest("task_btf"))
   1227		test_task_btf();
   1228	if (test__start_subtest("tcp4"))
   1229		test_tcp4();
   1230	if (test__start_subtest("tcp6"))
   1231		test_tcp6();
   1232	if (test__start_subtest("udp4"))
   1233		test_udp4();
   1234	if (test__start_subtest("udp6"))
   1235		test_udp6();
   1236	if (test__start_subtest("unix"))
   1237		test_unix();
   1238	if (test__start_subtest("anon"))
   1239		test_anon_iter(false);
   1240	if (test__start_subtest("anon-read-one-char"))
   1241		test_anon_iter(true);
   1242	if (test__start_subtest("file"))
   1243		test_file_iter();
   1244	if (test__start_subtest("overflow"))
   1245		test_overflow(false, false);
   1246	if (test__start_subtest("overflow-e2big"))
   1247		test_overflow(true, false);
   1248	if (test__start_subtest("prog-ret-1"))
   1249		test_overflow(false, true);
   1250	if (test__start_subtest("bpf_hash_map"))
   1251		test_bpf_hash_map();
   1252	if (test__start_subtest("bpf_percpu_hash_map"))
   1253		test_bpf_percpu_hash_map();
   1254	if (test__start_subtest("bpf_array_map"))
   1255		test_bpf_array_map();
   1256	if (test__start_subtest("bpf_percpu_array_map"))
   1257		test_bpf_percpu_array_map();
   1258	if (test__start_subtest("bpf_sk_storage_map"))
   1259		test_bpf_sk_storage_map();
   1260	if (test__start_subtest("bpf_sk_storage_delete"))
   1261		test_bpf_sk_storage_delete();
   1262	if (test__start_subtest("bpf_sk_storage_get"))
   1263		test_bpf_sk_storage_get();
   1264	if (test__start_subtest("rdonly-buf-out-of-bound"))
   1265		test_rdonly_buf_out_of_bound();
   1266	if (test__start_subtest("buf-neg-offset"))
   1267		test_buf_neg_offset();
   1268	if (test__start_subtest("link-iter"))
   1269		test_link_iter();
   1270}