ucode-mod-bpf: switch to ucv_resource_create_ex

On map/program resource, hold references to the module in order to avoid
closing it prematurely.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
pull/18330/merge
Felix Fietkau 2025-06-12 11:41:03 +02:00
parent 64570766cb
commit e4c3c236b8
1 changed files with 33 additions and 25 deletions

View File

@ -17,7 +17,6 @@
#define err_return(err, ...) do { set_error(err, __VA_ARGS__); return NULL; } while(0) #define err_return(err, ...) do { set_error(err, __VA_ARGS__); return NULL; } while(0)
#define TRUE ucv_boolean_new(true) #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_value_t *registry;
static uc_vm_t *debug_vm; static uc_vm_t *debug_vm;
@ -184,21 +183,38 @@ uc_bpf_open_module(uc_vm_t *vm, size_t nargs)
err_return(errno, NULL); err_return(errno, NULL);
} }
return uc_resource_new(module_type, obj); return ucv_resource_create(vm, "bpf.module", obj);
} }
static uc_value_t * static uc_value_t *
uc_bpf_map_create(int fd, unsigned int key_size, unsigned int val_size, bool close) uc_bpf_map_create(uc_vm_t *vm, uc_value_t *mod, int fd, unsigned int key_size,
unsigned int val_size, bool close)
{ {
struct uc_bpf_map *uc_map; struct uc_bpf_map *uc_map;
uc_value_t *res;
uc_map = xalloc(sizeof(*uc_map)); res = ucv_resource_create_ex(vm, "bpf.map", (void **)&uc_map, 1, sizeof(*uc_map));
ucv_resource_value_set(res, 0, ucv_get(mod));
uc_map->fd.fd = fd; uc_map->fd.fd = fd;
uc_map->key_size = key_size; uc_map->key_size = key_size;
uc_map->val_size = val_size; uc_map->val_size = val_size;
uc_map->fd.close = close; uc_map->fd.close = close;
return uc_resource_new(map_type, uc_map); return res;
}
static uc_value_t *
uc_bpf_prog_create(uc_vm_t *vm, uc_value_t *mod, int fd, bool close)
{
struct uc_bpf_fd *uc_fd;
uc_value_t *res;
res = ucv_resource_create_ex(vm, "bpf.program", (void **)&uc_fd, 1, sizeof(*uc_fd));
ucv_resource_value_set(res, 0, ucv_get(mod));
uc_fd->fd = fd;
uc_fd->close = close;
return res;
} }
static uc_value_t * static uc_value_t *
@ -223,14 +239,13 @@ uc_bpf_open_map(uc_vm_t *vm, size_t nargs)
err_return(errno, NULL); err_return(errno, NULL);
} }
return uc_bpf_map_create(fd, info.key_size, info.value_size, true); return uc_bpf_map_create(vm, NULL, fd, info.key_size, info.value_size, true);
} }
static uc_value_t * static uc_value_t *
uc_bpf_open_program(uc_vm_t *vm, size_t nargs) uc_bpf_open_program(uc_vm_t *vm, size_t nargs)
{ {
uc_value_t *path = uc_fn_arg(0); uc_value_t *path = uc_fn_arg(0);
struct uc_bpf_fd *f;
int fd; int fd;
if (ucv_type(path) != UC_STRING) if (ucv_type(path) != UC_STRING)
@ -240,11 +255,7 @@ uc_bpf_open_program(uc_vm_t *vm, size_t nargs)
if (fd < 0) if (fd < 0)
err_return(errno, NULL); err_return(errno, NULL);
f = xalloc(sizeof(*f)); return uc_bpf_prog_create(vm, NULL, fd, true);
f->fd = fd;
f->close = true;
return uc_resource_new(program_type, f);
} }
static uc_value_t * static uc_value_t *
@ -284,7 +295,7 @@ uc_bpf_module_get_map(uc_vm_t *vm, size_t nargs)
if (fd < 0) if (fd < 0)
err_return(EINVAL, NULL); err_return(EINVAL, NULL);
return uc_bpf_map_create(fd, bpf_map__key_size(map), bpf_map__value_size(map), false); return uc_bpf_map_create(vm, _uc_fn_this_res(vm), fd, bpf_map__key_size(map), bpf_map__value_size(map), false);
} }
static uc_value_t * static uc_value_t *
@ -311,7 +322,6 @@ uc_bpf_module_get_program(uc_vm_t *vm, size_t nargs)
struct bpf_object *obj = uc_fn_thisval("bpf.module"); struct bpf_object *obj = uc_fn_thisval("bpf.module");
struct bpf_program *prog; struct bpf_program *prog;
uc_value_t *name = uc_fn_arg(0); uc_value_t *name = uc_fn_arg(0);
struct uc_bpf_fd *f;
int fd; int fd;
if (!obj || !name || ucv_type(name) != UC_STRING) if (!obj || !name || ucv_type(name) != UC_STRING)
@ -325,10 +335,7 @@ uc_bpf_module_get_program(uc_vm_t *vm, size_t nargs)
if (fd < 0) if (fd < 0)
err_return(EINVAL, NULL); err_return(EINVAL, NULL);
f = xalloc(sizeof(*f)); return uc_bpf_prog_create(vm, _uc_fn_this_res(vm), fd, false);
f->fd = fd;
return uc_resource_new(program_type, f);
} }
static void * static void *
@ -493,16 +500,18 @@ 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 *map = uc_fn_thisval("bpf.map");
struct uc_bpf_map_iter *iter; struct uc_bpf_map_iter *iter;
uc_value_t *res;
if (!map) if (!map)
err_return(EINVAL, NULL); err_return(EINVAL, NULL);
iter = xalloc(sizeof(*iter) + map->key_size); res = ucv_resource_create_ex(vm, "bpf.map_iter", (void **)&iter, 1, sizeof(*iter) + map->key_size);
ucv_resource_value_set(res, 0, ucv_get(_uc_fn_this_res(vm)));
iter->fd = map->fd.fd; iter->fd = map->fd.fd;
iter->key_size = map->key_size; iter->key_size = map->key_size;
iter->has_next = !bpf_map_get_next_key(iter->fd, NULL, &iter->key); iter->has_next = !bpf_map_get_next_key(iter->fd, NULL, &iter->key);
return uc_resource_new(map_iter_type, iter); return res;
} }
static uc_value_t * static uc_value_t *
@ -777,7 +786,6 @@ static void uc_bpf_fd_free(void *ptr)
if (f->close) if (f->close)
close(f->fd); close(f->fd);
free(f);
} }
static const uc_function_list_t map_iter_fns[] = { static const uc_function_list_t map_iter_fns[] = {
@ -807,8 +815,8 @@ void uc_module_init(uc_vm_t *vm, uc_value_t *scope)
registry = ucv_array_new(vm); registry = ucv_array_new(vm);
uc_vm_registry_set(vm, "bpf.registry", registry); uc_vm_registry_set(vm, "bpf.registry", registry);
module_type = uc_type_declare(vm, "bpf.module", module_fns, module_free); uc_type_declare(vm, "bpf.module", module_fns, module_free);
map_type = uc_type_declare(vm, "bpf.map", map_fns, uc_bpf_fd_free); 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); uc_type_declare(vm, "bpf.map_iter", map_iter_fns, NULL);
program_type = uc_type_declare(vm, "bpf.program", prog_fns, uc_bpf_fd_free); uc_type_declare(vm, "bpf.program", prog_fns, uc_bpf_fd_free);
} }