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