1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2022 Facebook */
3
4#include <test_progs.h>
5#include <network_helpers.h>
6#include "dynptr_fail.skel.h"
7#include "dynptr_success.skel.h"
8
9enum test_setup_type {
10	SETUP_SYSCALL_SLEEP,
11	SETUP_SKB_PROG,
12};
13
14static struct {
15	const char *prog_name;
16	enum test_setup_type type;
17} success_tests[] = {
18	{"test_read_write", SETUP_SYSCALL_SLEEP},
19	{"test_dynptr_data", SETUP_SYSCALL_SLEEP},
20	{"test_ringbuf", SETUP_SYSCALL_SLEEP},
21	{"test_skb_readonly", SETUP_SKB_PROG},
22	{"test_dynptr_skb_data", SETUP_SKB_PROG},
23	{"test_adjust", SETUP_SYSCALL_SLEEP},
24	{"test_adjust_err", SETUP_SYSCALL_SLEEP},
25	{"test_zero_size_dynptr", SETUP_SYSCALL_SLEEP},
26	{"test_dynptr_is_null", SETUP_SYSCALL_SLEEP},
27	{"test_dynptr_is_rdonly", SETUP_SKB_PROG},
28	{"test_dynptr_clone", SETUP_SKB_PROG},
29	{"test_dynptr_skb_no_buff", SETUP_SKB_PROG},
30	{"test_dynptr_skb_strcmp", SETUP_SKB_PROG},
31};
32
33static void verify_success(const char *prog_name, enum test_setup_type setup_type)
34{
35	struct dynptr_success *skel;
36	struct bpf_program *prog;
37	struct bpf_link *link;
38       int err;
39
40	skel = dynptr_success__open();
41	if (!ASSERT_OK_PTR(skel, "dynptr_success__open"))
42		return;
43
44	skel->bss->pid = getpid();
45
46	prog = bpf_object__find_program_by_name(skel->obj, prog_name);
47	if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))
48		goto cleanup;
49
50       bpf_program__set_autoload(prog, true);
51
52	err = dynptr_success__load(skel);
53	if (!ASSERT_OK(err, "dynptr_success__load"))
54		goto cleanup;
55
56	switch (setup_type) {
57	case SETUP_SYSCALL_SLEEP:
58		link = bpf_program__attach(prog);
59		if (!ASSERT_OK_PTR(link, "bpf_program__attach"))
60			goto cleanup;
61
62		usleep(1);
63
64		bpf_link__destroy(link);
65		break;
66	case SETUP_SKB_PROG:
67	{
68		int prog_fd;
69		char buf[64];
70
71		LIBBPF_OPTS(bpf_test_run_opts, topts,
72			    .data_in = &pkt_v4,
73			    .data_size_in = sizeof(pkt_v4),
74			    .data_out = buf,
75			    .data_size_out = sizeof(buf),
76			    .repeat = 1,
77		);
78
79		prog_fd = bpf_program__fd(prog);
80		if (!ASSERT_GE(prog_fd, 0, "prog_fd"))
81			goto cleanup;
82
83		err = bpf_prog_test_run_opts(prog_fd, &topts);
84
85		if (!ASSERT_OK(err, "test_run"))
86			goto cleanup;
87
88		break;
89	}
90	}
91
92	ASSERT_EQ(skel->bss->err, 0, "err");
93
94cleanup:
95	dynptr_success__destroy(skel);
96}
97
98void test_dynptr(void)
99{
100	int i;
101
102	for (i = 0; i < ARRAY_SIZE(success_tests); i++) {
103		if (!test__start_subtest(success_tests[i].prog_name))
104			continue;
105
106		verify_success(success_tests[i].prog_name, success_tests[i].type);
107	}
108
109	RUN_TESTS(dynptr_fail);
110}
111