xref: /linux/tools/testing/selftests/bpf/test_cpp.cpp (revision 06b9cce42634a50f2840777a66553b02320db5ef)
1 /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
2 #include <iostream>
3 #include <bpf/libbpf.h>
4 #include <bpf/bpf.h>
5 #include <bpf/btf.h>
6 #include "test_core_extern.skel.h"
7 
8 template <typename T>
9 class Skeleton {
10 private:
11 	T *skel;
12 public:
13 	Skeleton(): skel(nullptr) { }
14 
15 	~Skeleton() { if (skel) T::destroy(skel); }
16 
17 	int open(const struct bpf_object_open_opts *opts = nullptr)
18 	{
19 		int err;
20 
21 		if (skel)
22 			return -EBUSY;
23 
24 		skel = T::open(opts);
25 		err = libbpf_get_error(skel);
26 		if (err) {
27 			skel = nullptr;
28 			return err;
29 		}
30 
31 		return 0;
32 	}
33 
34 	int load() { return T::load(skel); }
35 
36 	int attach() { return T::attach(skel); }
37 
38 	void detach() { return T::detach(skel); }
39 
40 	const T* operator->() const { return skel; }
41 
42 	T* operator->() { return skel; }
43 
44 	const T *get() const { return skel; }
45 };
46 
47 static void dump_printf(void *ctx, const char *fmt, va_list args)
48 {
49 }
50 
51 static void try_skeleton_template()
52 {
53 	Skeleton<test_core_extern> skel;
54 	std::string prog_name;
55 	int err;
56 	LIBBPF_OPTS(bpf_object_open_opts, opts);
57 
58 	err = skel.open(&opts);
59 	if (err) {
60 		fprintf(stderr, "Skeleton open failed: %d\n", err);
61 		return;
62 	}
63 
64 	skel->data->kern_ver = 123;
65 	skel->data->int_val = skel->data->ushort_val;
66 
67 	err = skel.load();
68 	if (err) {
69 		fprintf(stderr, "Skeleton load failed: %d\n", err);
70 		return;
71 	}
72 
73 	if (!skel->kconfig->CONFIG_BPF_SYSCALL)
74 		fprintf(stderr, "Seems like CONFIG_BPF_SYSCALL isn't set?!\n");
75 
76 	err = skel.attach();
77 	if (err) {
78 		fprintf(stderr, "Skeleton attach failed: %d\n", err);
79 		return;
80 	}
81 
82 	prog_name = bpf_program__name(skel->progs.handle_sys_enter);
83 	if (prog_name != "handle_sys_enter")
84 		fprintf(stderr, "Unexpected program name: %s\n", prog_name.c_str());
85 
86 	bpf_link__destroy(skel->links.handle_sys_enter);
87 	skel->links.handle_sys_enter = bpf_program__attach(skel->progs.handle_sys_enter);
88 
89 	skel.detach();
90 
91 	/* destructor will destory underlying skeleton */
92 }
93 
94 int main(int argc, char *argv[])
95 {
96 	struct btf_dump_opts opts = { };
97 	struct test_core_extern *skel;
98 	struct btf *btf;
99 
100 	try_skeleton_template();
101 
102 	/* libbpf.h */
103 	libbpf_set_print(NULL);
104 
105 	/* bpf.h */
106 	bpf_prog_get_fd_by_id(0);
107 
108 	/* btf.h */
109 	btf = btf__new(NULL, 0);
110 	if (!libbpf_get_error(btf))
111 		btf_dump__new(btf, dump_printf, nullptr, &opts);
112 
113 	/* BPF skeleton */
114 	skel = test_core_extern__open_and_load();
115 	test_core_extern__destroy(skel);
116 
117 	std::cout << "DONE!" << std::endl;
118 
119 	return 0;
120 }
121