aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/arraymap.c
diff options
context:
space:
mode:
authorMartin KaFai Lau <kafai@fb.com>2017-06-28 02:08:34 -0400
committerDavid S. Miller <davem@davemloft.net>2017-06-29 13:13:25 -0400
commit14dc6f04f49dc12614d7e90928b495b8d73cd471 (patch)
tree159ebddef04be2ae417c503ab46593be570c680f /kernel/bpf/arraymap.c
parent77b0d3617738e532bae683bf9d88ea35fff223e5 (diff)
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>
Diffstat (limited to 'kernel/bpf/arraymap.c')
-rw-r--r--kernel/bpf/arraymap.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index ecb43542246e..d771a3872500 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -335,6 +335,26 @@ static void *fd_array_map_lookup_elem(struct bpf_map *map, void *key)
335} 335}
336 336
337/* only called from syscall */ 337/* only called from syscall */
338int bpf_fd_array_map_lookup_elem(struct bpf_map *map, void *key, u32 *value)
339{
340 void **elem, *ptr;
341 int ret = 0;
342
343 if (!map->ops->map_fd_sys_lookup_elem)
344 return -ENOTSUPP;
345
346 rcu_read_lock();
347 elem = array_map_lookup_elem(map, key);
348 if (elem && (ptr = READ_ONCE(*elem)))
349 *value = map->ops->map_fd_sys_lookup_elem(ptr);
350 else
351 ret = -ENOENT;
352 rcu_read_unlock();
353
354 return ret;
355}
356
357/* only called from syscall */
338int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file, 358int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file,
339 void *key, void *value, u64 map_flags) 359 void *key, void *value, u64 map_flags)
340{ 360{
@@ -400,6 +420,11 @@ static void prog_fd_array_put_ptr(void *ptr)
400 bpf_prog_put(ptr); 420 bpf_prog_put(ptr);
401} 421}
402 422
423static u32 prog_fd_array_sys_lookup_elem(void *ptr)
424{
425 return ((struct bpf_prog *)ptr)->aux->id;
426}
427
403/* decrement refcnt of all bpf_progs that are stored in this map */ 428/* decrement refcnt of all bpf_progs that are stored in this map */
404void bpf_fd_array_map_clear(struct bpf_map *map) 429void bpf_fd_array_map_clear(struct bpf_map *map)
405{ 430{
@@ -418,6 +443,7 @@ const struct bpf_map_ops prog_array_map_ops = {
418 .map_delete_elem = fd_array_map_delete_elem, 443 .map_delete_elem = fd_array_map_delete_elem,
419 .map_fd_get_ptr = prog_fd_array_get_ptr, 444 .map_fd_get_ptr = prog_fd_array_get_ptr,
420 .map_fd_put_ptr = prog_fd_array_put_ptr, 445 .map_fd_put_ptr = prog_fd_array_put_ptr,
446 .map_fd_sys_lookup_elem = prog_fd_array_sys_lookup_elem,
421}; 447};
422 448
423static struct bpf_event_entry *bpf_event_entry_gen(struct file *perf_file, 449static 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 = {
585 .map_delete_elem = fd_array_map_delete_elem, 611 .map_delete_elem = fd_array_map_delete_elem,
586 .map_fd_get_ptr = bpf_map_fd_get_ptr, 612 .map_fd_get_ptr = bpf_map_fd_get_ptr,
587 .map_fd_put_ptr = bpf_map_fd_put_ptr, 613 .map_fd_put_ptr = bpf_map_fd_put_ptr,
614 .map_fd_sys_lookup_elem = bpf_map_fd_sys_lookup_elem,
588}; 615};