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