bpf: Add syscall lookup support for fd array and htab
This patch allows userspace to do BPF_MAP_LOOKUP_ELEM on BPF_MAP_TYPE_PROG_ARRAY, BPF_MAP_TYPE_ARRAY_OF_MAPS and BPF_MAP_TYPE_HASH_OF_MAPS. The lookup returns a prog-id or map-id to the userspace. The userspace can then use the BPF_PROG_GET_FD_BY_ID or BPF_MAP_GET_FD_BY_ID to get a fd. Signed-off-by: Martin KaFai Lau <kafai@fb.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
77b0d36177
commit
14dc6f04f4
@@ -334,6 +334,26 @@ static void *fd_array_map_lookup_elem(struct bpf_map *map, void *key)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* only called from syscall */
|
||||
int bpf_fd_array_map_lookup_elem(struct bpf_map *map, void *key, u32 *value)
|
||||
{
|
||||
void **elem, *ptr;
|
||||
int ret = 0;
|
||||
|
||||
if (!map->ops->map_fd_sys_lookup_elem)
|
||||
return -ENOTSUPP;
|
||||
|
||||
rcu_read_lock();
|
||||
elem = array_map_lookup_elem(map, key);
|
||||
if (elem && (ptr = READ_ONCE(*elem)))
|
||||
*value = map->ops->map_fd_sys_lookup_elem(ptr);
|
||||
else
|
||||
ret = -ENOENT;
|
||||
rcu_read_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* only called from syscall */
|
||||
int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file,
|
||||
void *key, void *value, u64 map_flags)
|
||||
@@ -400,6 +420,11 @@ static void prog_fd_array_put_ptr(void *ptr)
|
||||
bpf_prog_put(ptr);
|
||||
}
|
||||
|
||||
static u32 prog_fd_array_sys_lookup_elem(void *ptr)
|
||||
{
|
||||
return ((struct bpf_prog *)ptr)->aux->id;
|
||||
}
|
||||
|
||||
/* decrement refcnt of all bpf_progs that are stored in this map */
|
||||
void bpf_fd_array_map_clear(struct bpf_map *map)
|
||||
{
|
||||
@@ -418,6 +443,7 @@ const struct bpf_map_ops prog_array_map_ops = {
|
||||
.map_delete_elem = fd_array_map_delete_elem,
|
||||
.map_fd_get_ptr = prog_fd_array_get_ptr,
|
||||
.map_fd_put_ptr = prog_fd_array_put_ptr,
|
||||
.map_fd_sys_lookup_elem = prog_fd_array_sys_lookup_elem,
|
||||
};
|
||||
|
||||
static struct bpf_event_entry *bpf_event_entry_gen(struct file *perf_file,
|
||||
@@ -585,4 +611,5 @@ const struct bpf_map_ops array_of_maps_map_ops = {
|
||||
.map_delete_elem = fd_array_map_delete_elem,
|
||||
.map_fd_get_ptr = bpf_map_fd_get_ptr,
|
||||
.map_fd_put_ptr = bpf_map_fd_put_ptr,
|
||||
.map_fd_sys_lookup_elem = bpf_map_fd_sys_lookup_elem,
|
||||
};
|
||||
|
Reference in New Issue
Block a user