| /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ |
| #include <iostream> |
| #include <unistd.h> |
| #include <linux/bpf.h> |
| #include <linux/btf.h> |
| #include <bpf/libbpf.h> |
| #include <bpf/bpf.h> |
| #include <bpf/btf.h> |
| |
| #ifndef _Bool |
| #define _Bool bool |
| #endif |
| #include "test_core_extern.skel.h" |
| #include "struct_ops_module.skel.h" |
| |
| template <typename T> |
| class Skeleton { |
| private: |
| T *skel; |
| public: |
| Skeleton(): skel(nullptr) { } |
| |
| ~Skeleton() { if (skel) T::destroy(skel); } |
| |
| int open(const struct bpf_object_open_opts *opts = nullptr) |
| { |
| int err; |
| |
| if (skel) |
| return -EBUSY; |
| |
| skel = T::open(opts); |
| err = libbpf_get_error(skel); |
| if (err) { |
| skel = nullptr; |
| return err; |
| } |
| |
| return 0; |
| } |
| |
| int load() { return T::load(skel); } |
| |
| int attach() { return T::attach(skel); } |
| |
| void detach() { return T::detach(skel); } |
| |
| const T* operator->() const { return skel; } |
| |
| T* operator->() { return skel; } |
| |
| const T *get() const { return skel; } |
| }; |
| |
| static void dump_printf(void *ctx, const char *fmt, va_list args) |
| { |
| } |
| |
| static void try_skeleton_template() |
| { |
| Skeleton<test_core_extern> skel; |
| std::string prog_name; |
| int err; |
| LIBBPF_OPTS(bpf_object_open_opts, opts); |
| |
| err = skel.open(&opts); |
| if (err) { |
| fprintf(stderr, "Skeleton open failed: %d\n", err); |
| return; |
| } |
| |
| skel->data->kern_ver = 123; |
| skel->data->int_val = skel->data->ushort_val; |
| |
| err = skel.load(); |
| if (err) { |
| fprintf(stderr, "Skeleton load failed: %d\n", err); |
| return; |
| } |
| |
| if (!skel->kconfig->CONFIG_BPF_SYSCALL) |
| fprintf(stderr, "Seems like CONFIG_BPF_SYSCALL isn't set?!\n"); |
| |
| err = skel.attach(); |
| if (err) { |
| fprintf(stderr, "Skeleton attach failed: %d\n", err); |
| return; |
| } |
| |
| prog_name = bpf_program__name(skel->progs.handle_sys_enter); |
| if (prog_name != "handle_sys_enter") |
| fprintf(stderr, "Unexpected program name: %s\n", prog_name.c_str()); |
| |
| bpf_link__destroy(skel->links.handle_sys_enter); |
| skel->links.handle_sys_enter = bpf_program__attach(skel->progs.handle_sys_enter); |
| |
| skel.detach(); |
| |
| /* destructor will destroy underlying skeleton */ |
| } |
| |
| int main(int argc, char *argv[]) |
| { |
| struct btf_dump_opts opts = { }; |
| struct test_core_extern *skel; |
| struct struct_ops_module *skel2; |
| struct btf *btf; |
| int fd; |
| |
| try_skeleton_template(); |
| |
| /* libbpf.h */ |
| libbpf_set_print(NULL); |
| |
| /* bpf.h */ |
| bpf_prog_get_fd_by_id(0); |
| |
| /* btf.h */ |
| btf = btf__new(NULL, 0); |
| if (!libbpf_get_error(btf)) |
| btf_dump__new(btf, dump_printf, nullptr, &opts); |
| |
| /* BPF skeleton */ |
| skel = test_core_extern__open_and_load(); |
| test_core_extern__destroy(skel); |
| |
| skel2 = struct_ops_module__open_and_load(); |
| struct_ops_module__destroy(skel2); |
| |
| fd = bpf_enable_stats(BPF_STATS_RUN_TIME); |
| if (fd < 0) |
| std::cout << "FAILED to enable stats: " << fd << std::endl; |
| else |
| ::close(fd); |
| |
| std::cout << "DONE!" << std::endl; |
| |
| return 0; |
| } |