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