From: Felix Fietkau Date: Thu, 16 Jul 2026 18:25:50 +0000 (+0200) Subject: ucode-mod-bpf: add support for keyless maps X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ec06937a5ab4b45128d58d2e0d5cfb5c93df3ea3;p=thirdparty%2Fopenwrt.git ucode-mod-bpf: add support for keyless maps Queue and stack maps have zero-sized keys and require a NULL key pointer; the kernel rejects any non-NULL key with EINVAL, making these maps unusable. Accept a null key argument on maps without a key, mapping get() to peek, set() to push and delete() with return to pop. Signed-off-by: Felix Fietkau --- diff --git a/package/utils/ucode-mod-bpf/src/bpf.c b/package/utils/ucode-mod-bpf/src/bpf.c index c34772bff5d..d32c7ec45eb 100644 --- a/package/utils/ucode-mod-bpf/src/bpf.c +++ b/package/utils/ucode-mod-bpf/src/bpf.c @@ -369,6 +369,26 @@ uc_bpf_map_arg(uc_value_t *val, const char *kind, unsigned int size, err_return(EINVAL, "%s size mismatch (expected: %d)", kind, size); } +static bool +uc_bpf_map_key_arg(struct uc_bpf_map *map, uc_value_t *a_key, uint64_t *buf, + void **key) +{ + if (!map->key_size) { + if (a_key) { + set_error(EINVAL, "map has no key"); + return false; + } + + *key = NULL; + + return true; + } + + *key = uc_bpf_map_arg(a_key, "key", map->key_size, buf); + + return *key != NULL; +} + static bool uc_bpf_map_is_percpu(struct uc_bpf_map *map) { @@ -488,8 +508,7 @@ uc_bpf_map_get(uc_vm_t *vm, size_t nargs) if (!map) err_return(EINVAL, NULL); - key = uc_bpf_map_arg(a_key, "key", map->key_size, &key_int); - if (!key) + if (!uc_bpf_map_key_arg(map, a_key, &key_int, &key)) return NULL; if (!uc_bpf_map_val_len(map, &val_len, &num_cpus)) @@ -518,8 +537,7 @@ uc_bpf_map_set(uc_vm_t *vm, size_t nargs) if (!map) err_return(EINVAL, NULL); - key = uc_bpf_map_arg(a_key, "key", map->key_size, &key_int); - if (!key) + if (!uc_bpf_map_key_arg(map, a_key, &key_int, &key)) return NULL; if (!uc_bpf_map_val_len(map, &val_len, &num_cpus)) @@ -558,8 +576,7 @@ uc_bpf_map_delete(uc_vm_t *vm, size_t nargs) if (!map) err_return(EINVAL, NULL); - key = uc_bpf_map_arg(a_key, "key", map->key_size, &key_int); - if (!key) + if (!uc_bpf_map_key_arg(map, a_key, &key_int, &key)) return NULL; if (!ucv_is_truish(a_return)) {