11e38abefSAndrii Nakryiko // SPDX-License-Identifier: GPL-2.0
21e38abefSAndrii Nakryiko /* Copyright (c) 2020 Facebook */
31e38abefSAndrii Nakryiko 
41e38abefSAndrii Nakryiko #include <test_progs.h>
5fa7f17d0SHou Tao #include <stdbool.h>
61e38abefSAndrii Nakryiko #include "test_module_attach.skel.h"
71e38abefSAndrii Nakryiko 
81e38abefSAndrii Nakryiko static int duration;
91e38abefSAndrii Nakryiko 
10fa7f17d0SHou Tao static int trigger_module_test_writable(int *val)
11fa7f17d0SHou Tao {
12fa7f17d0SHou Tao 	int fd, err;
13fa7f17d0SHou Tao 	char buf[65];
14fa7f17d0SHou Tao 	ssize_t rd;
15fa7f17d0SHou Tao 
16fa7f17d0SHou Tao 	fd = open(BPF_TESTMOD_TEST_FILE, O_RDONLY);
17fa7f17d0SHou Tao 	err = -errno;
18fa7f17d0SHou Tao 	if (!ASSERT_GE(fd, 0, "testmode_file_open"))
19fa7f17d0SHou Tao 		return err;
20fa7f17d0SHou Tao 
21fa7f17d0SHou Tao 	rd = read(fd, buf, sizeof(buf) - 1);
22fa7f17d0SHou Tao 	err = -errno;
23fa7f17d0SHou Tao 	if (!ASSERT_GT(rd, 0, "testmod_file_rd_val")) {
24fa7f17d0SHou Tao 		close(fd);
25fa7f17d0SHou Tao 		return err;
26fa7f17d0SHou Tao 	}
27fa7f17d0SHou Tao 
28fa7f17d0SHou Tao 	buf[rd] = '\0';
29fa7f17d0SHou Tao 	*val = strtol(buf, NULL, 0);
30fa7f17d0SHou Tao 	close(fd);
31fa7f17d0SHou Tao 
32fa7f17d0SHou Tao 	return 0;
33fa7f17d0SHou Tao }
34fa7f17d0SHou Tao 
35a1c05c3bSJiri Olsa static int delete_module(const char *name, int flags)
36a1c05c3bSJiri Olsa {
37a1c05c3bSJiri Olsa 	return syscall(__NR_delete_module, name, flags);
38a1c05c3bSJiri Olsa }
39a1c05c3bSJiri Olsa 
401e38abefSAndrii Nakryiko void test_module_attach(void)
411e38abefSAndrii Nakryiko {
421e38abefSAndrii Nakryiko 	const int READ_SZ = 456;
43407be922SQais Yousef 	const int WRITE_SZ = 457;
441e38abefSAndrii Nakryiko 	struct test_module_attach* skel;
451e38abefSAndrii Nakryiko 	struct test_module_attach__bss *bss;
46a1c05c3bSJiri Olsa 	struct bpf_link *link;
471e38abefSAndrii Nakryiko 	int err;
48fa7f17d0SHou Tao 	int writable_val = 0;
491e38abefSAndrii Nakryiko 
502e33f831SAndrii Nakryiko 	skel = test_module_attach__open();
511e38abefSAndrii Nakryiko 	if (CHECK(!skel, "skel_open", "failed to open skeleton\n"))
521e38abefSAndrii Nakryiko 		return;
531e38abefSAndrii Nakryiko 
542e33f831SAndrii Nakryiko 	err = bpf_program__set_attach_target(skel->progs.handle_fentry_manual,
552e33f831SAndrii Nakryiko 					     0, "bpf_testmod_test_read");
562e33f831SAndrii Nakryiko 	ASSERT_OK(err, "set_attach_target");
572e33f831SAndrii Nakryiko 
582e33f831SAndrii Nakryiko 	err = test_module_attach__load(skel);
592e33f831SAndrii Nakryiko 	if (CHECK(err, "skel_load", "failed to load skeleton\n"))
602e33f831SAndrii Nakryiko 		return;
612e33f831SAndrii Nakryiko 
621e38abefSAndrii Nakryiko 	bss = skel->bss;
631e38abefSAndrii Nakryiko 
641e38abefSAndrii Nakryiko 	err = test_module_attach__attach(skel);
651e38abefSAndrii Nakryiko 	if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err))
661e38abefSAndrii Nakryiko 		goto cleanup;
671e38abefSAndrii Nakryiko 
681e38abefSAndrii Nakryiko 	/* trigger tracepoint */
691e38abefSAndrii Nakryiko 	ASSERT_OK(trigger_module_test_read(READ_SZ), "trigger_read");
70407be922SQais Yousef 	ASSERT_OK(trigger_module_test_write(WRITE_SZ), "trigger_write");
711e38abefSAndrii Nakryiko 
721e38abefSAndrii Nakryiko 	ASSERT_EQ(bss->raw_tp_read_sz, READ_SZ, "raw_tp");
73407be922SQais Yousef 	ASSERT_EQ(bss->raw_tp_bare_write_sz, WRITE_SZ, "raw_tp_bare");
741e38abefSAndrii Nakryiko 	ASSERT_EQ(bss->tp_btf_read_sz, READ_SZ, "tp_btf");
751e38abefSAndrii Nakryiko 	ASSERT_EQ(bss->fentry_read_sz, READ_SZ, "fentry");
762e33f831SAndrii Nakryiko 	ASSERT_EQ(bss->fentry_manual_read_sz, READ_SZ, "fentry_manual");
771e38abefSAndrii Nakryiko 	ASSERT_EQ(bss->fexit_read_sz, READ_SZ, "fexit");
781e38abefSAndrii Nakryiko 	ASSERT_EQ(bss->fexit_ret, -EIO, "fexit_tet");
791e38abefSAndrii Nakryiko 	ASSERT_EQ(bss->fmod_ret_read_sz, READ_SZ, "fmod_ret");
801e38abefSAndrii Nakryiko 
81fa7f17d0SHou Tao 	bss->raw_tp_writable_bare_early_ret = true;
82fa7f17d0SHou Tao 	bss->raw_tp_writable_bare_out_val = 0xf1f2f3f4;
83fa7f17d0SHou Tao 	ASSERT_OK(trigger_module_test_writable(&writable_val),
84fa7f17d0SHou Tao 		  "trigger_writable");
85fa7f17d0SHou Tao 	ASSERT_EQ(bss->raw_tp_writable_bare_in_val, 1024, "writable_test_in");
86fa7f17d0SHou Tao 	ASSERT_EQ(bss->raw_tp_writable_bare_out_val, writable_val,
87fa7f17d0SHou Tao 		  "writable_test_out");
88fa7f17d0SHou Tao 
89a1c05c3bSJiri Olsa 	test_module_attach__detach(skel);
90a1c05c3bSJiri Olsa 
91a1c05c3bSJiri Olsa 	/* attach fentry/fexit and make sure it get's module reference */
92a1c05c3bSJiri Olsa 	link = bpf_program__attach(skel->progs.handle_fentry);
93a1c05c3bSJiri Olsa 	if (!ASSERT_OK_PTR(link, "attach_fentry"))
94a1c05c3bSJiri Olsa 		goto cleanup;
95a1c05c3bSJiri Olsa 
96a1c05c3bSJiri Olsa 	ASSERT_ERR(delete_module("bpf_testmod", 0), "delete_module");
97a1c05c3bSJiri Olsa 	bpf_link__destroy(link);
98a1c05c3bSJiri Olsa 
99a1c05c3bSJiri Olsa 	link = bpf_program__attach(skel->progs.handle_fexit);
100a1c05c3bSJiri Olsa 	if (!ASSERT_OK_PTR(link, "attach_fexit"))
101a1c05c3bSJiri Olsa 		goto cleanup;
102a1c05c3bSJiri Olsa 
103a1c05c3bSJiri Olsa 	ASSERT_ERR(delete_module("bpf_testmod", 0), "delete_module");
104a1c05c3bSJiri Olsa 	bpf_link__destroy(link);
105a1c05c3bSJiri Olsa 
106*e697d8dcSJiri Olsa 	link = bpf_program__attach(skel->progs.kprobe_multi);
107*e697d8dcSJiri Olsa 	if (!ASSERT_OK_PTR(link, "attach_kprobe_multi"))
108*e697d8dcSJiri Olsa 		goto cleanup;
109*e697d8dcSJiri Olsa 
110*e697d8dcSJiri Olsa 	ASSERT_ERR(delete_module("bpf_testmod", 0), "delete_module");
111*e697d8dcSJiri Olsa 	bpf_link__destroy(link);
112*e697d8dcSJiri Olsa 
1131e38abefSAndrii Nakryiko cleanup:
1141e38abefSAndrii Nakryiko 	test_module_attach__destroy(skel);
1151e38abefSAndrii Nakryiko }
116