From 1617b399c145ccf5a3c15719ff5e265e64c7dbf4 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 16 Jul 2023 19:29:33 +0200 Subject: [PATCH] 23.05: drop ucode-mod-bpf backport Signed-off-by: John Crispin --- feeds/ucentral/ucode-mod-bpf/Makefile | 40 -- feeds/ucentral/ucode-mod-bpf/src/bpf.c | 814 ------------------------- 2 files changed, 854 deletions(-) delete mode 100644 feeds/ucentral/ucode-mod-bpf/Makefile delete mode 100644 feeds/ucentral/ucode-mod-bpf/src/bpf.c diff --git a/feeds/ucentral/ucode-mod-bpf/Makefile b/feeds/ucentral/ucode-mod-bpf/Makefile deleted file mode 100644 index a748b9dbb..000000000 --- a/feeds/ucentral/ucode-mod-bpf/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=ucode-mod-bpf -PKG_RELEASE:=1 -PKG_LICENSE:=ISC -PKG_MAINTAINER:=Felix Fietkau - -include $(INCLUDE_DIR)/package.mk -include $(INCLUDE_DIR)/nls.mk - -define Package/ucode-mod-bpf - SECTION:=utils - CATEGORY:=Utilities - TITLE:=ucode eBPF module - DEPENDS:=+libucode +libbpf -endef - -define Package/ucode-mod-bpf/description -The bpf plugin provides functionality for loading and interacting with -eBPF modules. - -It allows loading full modules and pinned maps/programs and supports -interacting with maps and attaching programs as tc classifiers. -endef - -define Package/ucode-mod-bpf/install - $(INSTALL_DIR) $(1)/usr/lib/ucode - $(CP) $(PKG_BUILD_DIR)/bpf.so $(1)/usr/lib/ucode/ -endef - -define Build/Configure -endef - -define Build/Compile - $(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) $(FPIC) \ - -Wall -ffunction-sections -Wl,--gc-sections -shared -Wl,--no-as-needed -lbpf \ - -o $(PKG_BUILD_DIR)/bpf.so $(PKG_BUILD_DIR)/bpf.c -endef - -$(eval $(call BuildPackage,ucode-mod-bpf)) diff --git a/feeds/ucentral/ucode-mod-bpf/src/bpf.c b/feeds/ucentral/ucode-mod-bpf/src/bpf.c deleted file mode 100644 index 415215e54..000000000 --- a/feeds/ucentral/ucode-mod-bpf/src/bpf.c +++ /dev/null @@ -1,814 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "ucode/module.h" - -#define err_return_int(err, ...) do { set_error(err, __VA_ARGS__); return -1; } while(0) -#define err_return(err, ...) do { set_error(err, __VA_ARGS__); return NULL; } while(0) -#define TRUE ucv_boolean_new(true) - -static uc_resource_type_t *module_type, *map_type, *map_iter_type, *program_type; -static uc_value_t *registry; -static uc_vm_t *debug_vm; - -static struct { - int code; - char *msg; -} last_error; - -struct uc_bpf_fd { - int fd; - bool close; -}; - -struct uc_bpf_map { - struct uc_bpf_fd fd; /* must be first */ - unsigned int key_size, val_size; -}; - -struct uc_bpf_map_iter { - int fd; - unsigned int key_size; - bool has_next; - uint8_t key[]; -}; - -__attribute__((format(printf, 2, 3))) static void -set_error(int errcode, const char *fmt, ...) -{ - va_list ap; - - free(last_error.msg); - - last_error.code = errcode; - last_error.msg = NULL; - - if (fmt) { - va_start(ap, fmt); - xvasprintf(&last_error.msg, fmt, ap); - va_end(ap); - } -} - -static void init_env(void) -{ - static bool init_done = false; - struct rlimit limit = { - .rlim_cur = RLIM_INFINITY, - .rlim_max = RLIM_INFINITY, - }; - - if (init_done) - return; - - setrlimit(RLIMIT_MEMLOCK, &limit); - init_done = true; -} - -static uc_value_t * -uc_bpf_error(uc_vm_t *vm, size_t nargs) -{ - uc_value_t *numeric = uc_fn_arg(0); - const char *msg = last_error.msg; - int code = last_error.code; - uc_stringbuf_t *buf; - const char *s; - - if (last_error.code == 0) - return NULL; - - set_error(0, NULL); - - if (ucv_is_truish(numeric)) - return ucv_int64_new(code); - - buf = ucv_stringbuf_new(); - if (code < 0 && msg) { - ucv_stringbuf_addstr(buf, msg, strlen(msg)); - } else { - s = strerror(code); - ucv_stringbuf_addstr(buf, s, strlen(s)); - if (msg) - ucv_stringbuf_printf(buf, ": %s", msg); - } - - return ucv_stringbuf_finish(buf); -} - -static int -uc_bpf_module_set_opts(struct bpf_object *obj, uc_value_t *opts) -{ - uc_value_t *val; - - if (!opts) - return 0; - - if (ucv_type(opts) != UC_OBJECT) - err_return_int(EINVAL, "options argument"); - - if ((val = ucv_object_get(opts, "rodata", NULL)) != NULL) { - struct bpf_map *map = NULL; - - if (ucv_type(val) != UC_STRING) - err_return_int(EINVAL, "rodata type"); - - while ((map = bpf_object__next_map(obj, map)) != NULL) { - if (!strstr(bpf_map__name(map), ".rodata")) - continue; - - break; - } - - if (!map) - err_return_int(errno, "rodata map"); - - if (bpf_map__set_initial_value(map, ucv_string_get(val), - ucv_string_length(val))) - err_return_int(errno, "rodata"); - } - - if ((val = ucv_object_get(opts, "program-type", NULL)) != NULL) { - if (ucv_type(val) != UC_OBJECT) - err_return_int(EINVAL, "prog_types argument"); - - ucv_object_foreach(val, name, type) { - struct bpf_program *prog; - - if (ucv_type(type) != UC_INTEGER) - err_return_int(EINVAL, "program %s type", name); - - prog = bpf_object__find_program_by_name(obj, name); - if (!prog) - err_return_int(-1, "program %s not found", name); - - bpf_program__set_type(prog, ucv_int64_get(type)); - } - } - - return 0; -} - -static uc_value_t * -uc_bpf_open_module(uc_vm_t *vm, size_t nargs) -{ - DECLARE_LIBBPF_OPTS(bpf_object_open_opts, bpf_opts); - uc_value_t *path = uc_fn_arg(0); - uc_value_t *opts = uc_fn_arg(1); - struct bpf_object *obj; - - if (ucv_type(path) != UC_STRING) - err_return(EINVAL, "module path"); - - init_env(); - obj = bpf_object__open_file(ucv_string_get(path), &bpf_opts); - if (libbpf_get_error(obj)) - err_return(errno, NULL); - - if (uc_bpf_module_set_opts(obj, opts)) { - bpf_object__close(obj); - return NULL; - } - - if (bpf_object__load(obj)) { - bpf_object__close(obj); - err_return(errno, NULL); - } - - return uc_resource_new(module_type, obj); -} - -static uc_value_t * -uc_bpf_map_create(int fd, unsigned int key_size, unsigned int val_size, bool close) -{ - struct uc_bpf_map *uc_map; - - uc_map = xalloc(sizeof(*uc_map)); - uc_map->fd.fd = fd; - uc_map->key_size = key_size; - uc_map->val_size = val_size; - uc_map->fd.close = close; - - return uc_resource_new(map_type, uc_map); -} - -static uc_value_t * -uc_bpf_open_map(uc_vm_t *vm, size_t nargs) -{ - struct bpf_map_info info; - uc_value_t *path = uc_fn_arg(0); - __u32 len = sizeof(info); - int err; - int fd; - - if (ucv_type(path) != UC_STRING) - err_return(EINVAL, "module path"); - - fd = bpf_obj_get(ucv_string_get(path)); - if (fd < 0) - err_return(errno, NULL); - - err = bpf_obj_get_info_by_fd(fd, &info, &len); - if (err) { - close(fd); - err_return(errno, NULL); - } - - return uc_bpf_map_create(fd, info.key_size, info.value_size, true); -} - -static uc_value_t * -uc_bpf_open_program(uc_vm_t *vm, size_t nargs) -{ - uc_value_t *path = uc_fn_arg(0); - struct uc_bpf_fd *f; - int fd; - - if (ucv_type(path) != UC_STRING) - err_return(EINVAL, "module path"); - - fd = bpf_obj_get(ucv_string_get(path)); - if (fd < 0) - err_return(errno, NULL); - - f = xalloc(sizeof(*f)); - f->fd = fd; - f->close = true; - - return uc_resource_new(program_type, f); -} - -static uc_value_t * -uc_bpf_module_get_maps(uc_vm_t *vm, size_t nargs) -{ - struct bpf_object *obj = uc_fn_thisval("bpf.module"); - struct bpf_map *map = NULL; - uc_value_t *rv; - int i = 0; - - if (!obj) - err_return(EINVAL, NULL); - - rv = ucv_array_new(vm); - bpf_object__for_each_map(map, obj) - ucv_array_set(rv, i++, ucv_string_new(bpf_map__name(map))); - - return rv; -} - -static uc_value_t * -uc_bpf_module_get_map(uc_vm_t *vm, size_t nargs) -{ - struct bpf_object *obj = uc_fn_thisval("bpf.module"); - struct bpf_map *map; - uc_value_t *name = uc_fn_arg(0); - int fd; - - if (!obj || ucv_type(name) != UC_STRING) - err_return(EINVAL, NULL); - - map = bpf_object__find_map_by_name(obj, ucv_string_get(name)); - if (!map) - err_return(errno, NULL); - - fd = bpf_map__fd(map); - if (fd < 0) - err_return(EINVAL, NULL); - - return uc_bpf_map_create(fd, bpf_map__key_size(map), bpf_map__value_size(map), false); -} - -static uc_value_t * -uc_bpf_module_get_programs(uc_vm_t *vm, size_t nargs) -{ - struct bpf_object *obj = uc_fn_thisval("bpf.module"); - struct bpf_program *prog = NULL; - uc_value_t *rv; - int i = 0; - - if (!obj) - err_return(EINVAL, NULL); - - rv = ucv_array_new(vm); - bpf_object__for_each_program(prog, obj) - ucv_array_set(rv, i++, ucv_string_new(bpf_program__name(prog))); - - return rv; -} - -static uc_value_t * -uc_bpf_module_get_program(uc_vm_t *vm, size_t nargs) -{ - struct bpf_object *obj = uc_fn_thisval("bpf.module"); - struct bpf_program *prog; - uc_value_t *name = uc_fn_arg(0); - struct uc_bpf_fd *f; - int fd; - - if (!obj || !name || ucv_type(name) != UC_STRING) - err_return(EINVAL, NULL); - - prog = bpf_object__find_program_by_name(obj, ucv_string_get(name)); - if (!prog) - err_return(errno, NULL); - - fd = bpf_program__fd(prog); - if (fd < 0) - err_return(EINVAL, NULL); - - f = xalloc(sizeof(*f)); - f->fd = fd; - - return uc_resource_new(program_type, f); -} - -static void * -uc_bpf_map_arg(uc_value_t *val, const char *kind, unsigned int size) -{ - static union { - uint32_t u32; - uint64_t u64; - } val_int; - - switch (ucv_type(val)) { - case UC_INTEGER: - if (size == 4) - val_int.u32 = ucv_int64_get(val); - else if (size == 8) - val_int.u64 = ucv_int64_get(val); - else - break; - - return &val_int; - case UC_STRING: - if (size != ucv_string_length(val)) - break; - - return ucv_string_get(val); - default: - err_return(EINVAL, "%s type", kind); - } - - err_return(EINVAL, "%s size mismatch (expected: %d)", kind, size); -} - -static uc_value_t * -uc_bpf_map_get(uc_vm_t *vm, size_t nargs) -{ - struct uc_bpf_map *map = uc_fn_thisval("bpf.map"); - uc_value_t *a_key = uc_fn_arg(0); - void *key, *val; - - if (!map) - err_return(EINVAL, NULL); - - key = uc_bpf_map_arg(a_key, "key", map->key_size); - if (!key) - return NULL; - - val = alloca(map->val_size); - if (bpf_map_lookup_elem(map->fd.fd, key, val)) - return NULL; - - return ucv_string_new_length(val, map->val_size); -} - -static uc_value_t * -uc_bpf_map_set(uc_vm_t *vm, size_t nargs) -{ - struct uc_bpf_map *map = uc_fn_thisval("bpf.map"); - uc_value_t *a_key = uc_fn_arg(0); - uc_value_t *a_val = uc_fn_arg(1); - uc_value_t *a_flags = uc_fn_arg(2); - uint64_t flags; - void *key, *val; - - if (!map) - err_return(EINVAL, NULL); - - key = uc_bpf_map_arg(a_key, "key", map->key_size); - if (!key) - return NULL; - - val = uc_bpf_map_arg(a_val, "value", map->val_size); - if (!val) - return NULL; - - if (!a_flags) - flags = BPF_ANY; - else if (ucv_type(a_flags) != UC_INTEGER) - err_return(EINVAL, "flags"); - else - flags = ucv_int64_get(a_flags); - - if (bpf_map_update_elem(map->fd.fd, key, val, flags)) - return NULL; - - return ucv_string_new_length(val, map->val_size); -} - -static uc_value_t * -uc_bpf_map_delete(uc_vm_t *vm, size_t nargs) -{ - struct uc_bpf_map *map = uc_fn_thisval("bpf.map"); - uc_value_t *a_key = uc_fn_arg(0); - uc_value_t *a_return = uc_fn_arg(1); - void *key, *val = NULL; - int ret; - - if (!map) - err_return(EINVAL, NULL); - - key = uc_bpf_map_arg(a_key, "key", map->key_size); - if (!key) - return NULL; - - if (!ucv_is_truish(a_return)) { - ret = bpf_map_delete_elem(map->fd.fd, key); - - return ucv_boolean_new(ret == 0); - } - - val = alloca(map->val_size); - if (bpf_map_lookup_and_delete_elem(map->fd.fd, key, val)) - return NULL; - - return ucv_string_new_length(val, map->val_size); -} - -static uc_value_t * -uc_bpf_map_delete_all(uc_vm_t *vm, size_t nargs) -{ - struct uc_bpf_map *map = uc_fn_thisval("bpf.map"); - uc_value_t *filter = uc_fn_arg(0); - bool has_next; - void *key, *next; - - if (!map) - err_return(EINVAL, NULL); - - key = alloca(map->key_size); - next = alloca(map->key_size); - has_next = !bpf_map_get_next_key(map->fd.fd, NULL, next); - while (has_next) { - bool skip = false; - - memcpy(key, next, map->key_size); - has_next = !bpf_map_get_next_key(map->fd.fd, next, next); - - if (ucv_is_callable(filter)) { - uc_value_t *rv; - - uc_value_push(ucv_get(filter)); - uc_value_push(ucv_string_new_length((const char *)key, map->key_size)); - if (uc_call(1) != EXCEPTION_NONE) - break; - - rv = uc_vm_stack_pop(vm); - if (!rv) - break; - - skip = !ucv_is_truish(rv); - ucv_put(rv); - } - - if (!skip) - bpf_map_delete_elem(map->fd.fd, key); - } - - return TRUE; -} - -static uc_value_t * -uc_bpf_map_iterator(uc_vm_t *vm, size_t nargs) -{ - struct uc_bpf_map *map = uc_fn_thisval("bpf.map"); - struct uc_bpf_map_iter *iter; - - if (!map) - err_return(EINVAL, NULL); - - iter = xalloc(sizeof(*iter) + map->key_size); - iter->fd = map->fd.fd; - iter->key_size = map->key_size; - iter->has_next = !bpf_map_get_next_key(iter->fd, NULL, &iter->key); - - return uc_resource_new(map_iter_type, iter); -} - -static uc_value_t * -uc_bpf_map_iter_next(uc_vm_t *vm, size_t nargs) -{ - struct uc_bpf_map_iter *iter = uc_fn_thisval("bpf.map_iter"); - uc_value_t *rv; - - if (!iter->has_next) - return NULL; - - rv = ucv_string_new_length((const char *)iter->key, iter->key_size); - iter->has_next = !bpf_map_get_next_key(iter->fd, &iter->key, &iter->key); - - return rv; -} - -static uc_value_t * -uc_bpf_map_iter_next_int(uc_vm_t *vm, size_t nargs) -{ - struct uc_bpf_map_iter *iter = uc_fn_thisval("bpf.map_iter"); - uint64_t intval; - uc_value_t *rv; - - if (!iter->has_next) - return NULL; - - if (iter->key_size == 4) - intval = *(uint32_t *)iter->key; - else if (iter->key_size == 8) - intval = *(uint64_t *)iter->key; - else - return NULL; - - rv = ucv_int64_new(intval); - iter->has_next = !bpf_map_get_next_key(iter->fd, &iter->key, &iter->key); - - return rv; -} - -static uc_value_t * -uc_bpf_map_foreach(uc_vm_t *vm, size_t nargs) -{ - struct uc_bpf_map *map = uc_fn_thisval("bpf.map"); - uc_value_t *func = uc_fn_arg(0); - bool has_next; - void *key, *next; - bool ret = false; - - key = alloca(map->key_size); - next = alloca(map->key_size); - has_next = !bpf_map_get_next_key(map->fd.fd, NULL, next); - - while (has_next) { - uc_value_t *rv; - bool stop; - - memcpy(key, next, map->key_size); - has_next = !bpf_map_get_next_key(map->fd.fd, next, next); - - uc_value_push(ucv_get(func)); - uc_value_push(ucv_string_new_length((const char *)key, map->key_size)); - - if (uc_call(1) != EXCEPTION_NONE) - break; - - rv = uc_vm_stack_pop(vm); - stop = (ucv_type(rv) == UC_BOOLEAN && !ucv_boolean_get(rv)); - ucv_put(rv); - - if (stop) - break; - - ret = true; - } - - return ucv_boolean_new(ret); -} - -static uc_value_t * -uc_bpf_obj_pin(uc_vm_t *vm, size_t nargs, const char *type) -{ - struct uc_bpf_fd *f = uc_fn_thisval(type); - uc_value_t *path = uc_fn_arg(0); - - if (ucv_type(path) != UC_STRING) - err_return(EINVAL, NULL); - - if (bpf_obj_pin(f->fd, ucv_string_get(path))) - err_return(errno, NULL); - - return TRUE; -} - -static uc_value_t * -uc_bpf_program_pin(uc_vm_t *vm, size_t nargs) -{ - return uc_bpf_obj_pin(vm, nargs, "bpf.program"); -} - -static uc_value_t * -uc_bpf_map_pin(uc_vm_t *vm, size_t nargs) -{ - return uc_bpf_obj_pin(vm, nargs, "bpf.map"); -} - -static uc_value_t * -uc_bpf_set_tc_hook(uc_value_t *ifname, uc_value_t *type, uc_value_t *prio, - int fd) -{ - DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook); - DECLARE_LIBBPF_OPTS(bpf_tc_opts, attach_tc, - .handle = 1); - const char *type_str; - uint64_t prio_val; - - if (ucv_type(ifname) != UC_STRING || ucv_type(type) != UC_STRING || - ucv_type(prio) != UC_INTEGER) - err_return(EINVAL, NULL); - - prio_val = ucv_int64_get(prio); - if (prio_val > 0xffff) - err_return(EINVAL, NULL); - - type_str = ucv_string_get(type); - if (!strcmp(type_str, "ingress")) - hook.attach_point = BPF_TC_INGRESS; - else if (!strcmp(type_str, "egress")) - hook.attach_point = BPF_TC_EGRESS; - else - err_return(EINVAL, NULL); - - hook.ifindex = if_nametoindex(ucv_string_get(ifname)); - if (!hook.ifindex) - goto error; - - bpf_tc_hook_create(&hook); - attach_tc.priority = prio_val; - if (bpf_tc_detach(&hook, &attach_tc) < 0 && fd < 0) - goto error; - - if (fd < 0) - goto out; - - attach_tc.prog_fd = fd; - if (bpf_tc_attach(&hook, &attach_tc) < 0) - goto error; - -out: - return TRUE; - -error: - if (fd >= 0) - err_return(ENOENT, NULL); - return NULL; -} - -static uc_value_t * -uc_bpf_program_tc_attach(uc_vm_t *vm, size_t nargs) -{ - struct uc_bpf_fd *f = uc_fn_thisval("bpf.program"); - uc_value_t *ifname = uc_fn_arg(0); - uc_value_t *type = uc_fn_arg(1); - uc_value_t *prio = uc_fn_arg(2); - - if (!f) - err_return(EINVAL, NULL); - - return uc_bpf_set_tc_hook(ifname, type, prio, f->fd); -} - -static uc_value_t * -uc_bpf_tc_detach(uc_vm_t *vm, size_t nargs) -{ - uc_value_t *ifname = uc_fn_arg(0); - uc_value_t *type = uc_fn_arg(1); - uc_value_t *prio = uc_fn_arg(2); - - return uc_bpf_set_tc_hook(ifname, type, prio, -1); -} - -static int -uc_bpf_debug_print(enum libbpf_print_level level, const char *format, - va_list args) -{ - char buf[256], *str = NULL; - uc_value_t *val; - va_list ap; - int size; - - va_copy(ap, args); - size = vsnprintf(buf, sizeof(buf), format, ap); - va_end(ap); - - if (size > 0 && (unsigned long)size < ARRAY_SIZE(buf) - 1) { - val = ucv_string_new(buf); - goto out; - } - - if (vasprintf(&str, format, args) < 0) - return 0; - - val = ucv_string_new(str); - free(str); - -out: - uc_vm_stack_push(debug_vm, ucv_get(ucv_array_get(registry, 0))); - uc_vm_stack_push(debug_vm, ucv_int64_new(level)); - uc_vm_stack_push(debug_vm, val); - if (uc_vm_call(debug_vm, false, 2) == EXCEPTION_NONE) - ucv_put(uc_vm_stack_pop(debug_vm)); - - return 0; -} - -static uc_value_t * -uc_bpf_set_debug_handler(uc_vm_t *vm, size_t nargs) -{ - uc_value_t *handler = uc_fn_arg(0); - - if (handler && !ucv_is_callable(handler)) - err_return(EINVAL, NULL); - - debug_vm = vm; - libbpf_set_print(handler ? uc_bpf_debug_print : NULL); - - ucv_array_set(registry, 0, ucv_get(handler)); - - return NULL; -} - -static void -register_constants(uc_vm_t *vm, uc_value_t *scope) -{ -#define ADD_CONST(x) ucv_object_add(scope, #x, ucv_int64_new(x)) - ADD_CONST(BPF_PROG_TYPE_SCHED_CLS); - ADD_CONST(BPF_PROG_TYPE_SCHED_ACT); - - ADD_CONST(BPF_ANY); - ADD_CONST(BPF_NOEXIST); - ADD_CONST(BPF_EXIST); - ADD_CONST(BPF_F_LOCK); -} - -static const uc_function_list_t module_fns[] = { - { "get_map", uc_bpf_module_get_map }, - { "get_maps", uc_bpf_module_get_maps }, - { "get_programs", uc_bpf_module_get_programs }, - { "get_program", uc_bpf_module_get_program }, -}; - -static void module_free(void *ptr) -{ - struct bpf_object *obj = ptr; - - bpf_object__close(obj); -} - -static const uc_function_list_t map_fns[] = { - { "pin", uc_bpf_map_pin }, - { "get", uc_bpf_map_get }, - { "set", uc_bpf_map_set }, - { "delete", uc_bpf_map_delete }, - { "delete_all", uc_bpf_map_delete_all }, - { "foreach", uc_bpf_map_foreach }, - { "iterator", uc_bpf_map_iterator }, -}; - -static void uc_bpf_fd_free(void *ptr) -{ - struct uc_bpf_fd *f = ptr; - - if (f->close) - close(f->fd); - free(f); -} - -static const uc_function_list_t map_iter_fns[] = { - { "next", uc_bpf_map_iter_next }, - { "next_int", uc_bpf_map_iter_next_int }, -}; - -static const uc_function_list_t prog_fns[] = { - { "pin", uc_bpf_program_pin }, - { "tc_attach", uc_bpf_program_tc_attach }, -}; - -static const uc_function_list_t global_fns[] = { - { "error", uc_bpf_error }, - { "set_debug_handler", uc_bpf_set_debug_handler }, - { "open_module", uc_bpf_open_module }, - { "open_map", uc_bpf_open_map }, - { "open_program", uc_bpf_open_program }, - { "tc_detach", uc_bpf_tc_detach }, -}; - -void uc_module_init(uc_vm_t *vm, uc_value_t *scope) -{ - uc_function_list_register(scope, global_fns); - register_constants(vm, scope); - - registry = ucv_array_new(vm); - uc_vm_registry_set(vm, "bpf.registry", registry); - - module_type = uc_type_declare(vm, "bpf.module", module_fns, module_free); - map_type = uc_type_declare(vm, "bpf.map", map_fns, uc_bpf_fd_free); - map_iter_type = uc_type_declare(vm, "bpf.map_iter", map_iter_fns, free); - program_type = uc_type_declare(vm, "bpf.program", prog_fns, uc_bpf_fd_free); -}