ucode-mod-bpf: add map-in-map and prog array support
Updates on array/hash-of-maps and prog array maps take the fd of the inner object as a 4-byte value. Accept bpf.map and bpf.program resources as map values and convert them to their fd. Lookups on map-in-map types return the inner map id; add open_map_id and open_program_id to obtain a usable object from such an id. Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
@@ -220,20 +220,11 @@ uc_bpf_prog_create(uc_vm_t *vm, uc_value_t *mod, int fd, bool close)
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_bpf_open_map(uc_vm_t *vm, size_t nargs)
|
||||
uc_bpf_open_map_fd(uc_vm_t *vm, int fd)
|
||||
{
|
||||
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) {
|
||||
@@ -245,6 +236,38 @@ uc_bpf_open_map(uc_vm_t *vm, size_t nargs)
|
||||
info.value_size, true);
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_bpf_open_map(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
uc_value_t *path = uc_fn_arg(0);
|
||||
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);
|
||||
|
||||
return uc_bpf_open_map_fd(vm, fd);
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_bpf_open_map_id(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
uc_value_t *id = uc_fn_arg(0);
|
||||
int fd;
|
||||
|
||||
if (ucv_type(id) != UC_INTEGER)
|
||||
err_return(EINVAL, "map id");
|
||||
|
||||
fd = bpf_map_get_fd_by_id(ucv_int64_get(id));
|
||||
if (fd < 0)
|
||||
err_return(errno, NULL);
|
||||
|
||||
return uc_bpf_open_map_fd(vm, fd);
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_bpf_open_program(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
@@ -261,6 +284,22 @@ uc_bpf_open_program(uc_vm_t *vm, size_t nargs)
|
||||
return uc_bpf_prog_create(vm, NULL, fd, true);
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_bpf_open_program_id(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
uc_value_t *id = uc_fn_arg(0);
|
||||
int fd;
|
||||
|
||||
if (ucv_type(id) != UC_INTEGER)
|
||||
err_return(EINVAL, "program id");
|
||||
|
||||
fd = bpf_prog_get_fd_by_id(ucv_int64_get(id));
|
||||
if (fd < 0)
|
||||
err_return(errno, NULL);
|
||||
|
||||
return uc_bpf_prog_create(vm, NULL, fd, true);
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_bpf_module_get_maps(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
@@ -362,6 +401,22 @@ uc_bpf_map_arg(uc_value_t *val, const char *kind, unsigned int size,
|
||||
break;
|
||||
|
||||
return ucv_string_get(val);
|
||||
case UC_RESOURCE: {
|
||||
struct uc_bpf_fd *f;
|
||||
|
||||
f = ucv_resource_data(val, "bpf.map");
|
||||
if (!f)
|
||||
f = ucv_resource_data(val, "bpf.program");
|
||||
if (!f)
|
||||
err_return(EINVAL, "%s type", kind);
|
||||
|
||||
if (size != 4)
|
||||
break;
|
||||
|
||||
*(uint32_t *)val_int = f->fd;
|
||||
|
||||
return val_int;
|
||||
}
|
||||
default:
|
||||
err_return(EINVAL, "%s type", kind);
|
||||
}
|
||||
@@ -962,7 +1017,9 @@ static const uc_function_list_t global_fns[] = {
|
||||
{ "set_debug_handler", uc_bpf_set_debug_handler },
|
||||
{ "open_module", uc_bpf_open_module },
|
||||
{ "open_map", uc_bpf_open_map },
|
||||
{ "open_map_id", uc_bpf_open_map_id },
|
||||
{ "open_program", uc_bpf_open_program },
|
||||
{ "open_program_id", uc_bpf_open_program_id },
|
||||
{ "tc_detach", uc_bpf_tc_detach },
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user