Queue/stack maps implement a FIFO/LIFO data storage for ebpf programs. These maps support peek, pop and push operations that are exposed to eBPF programs through the new bpf_map[peek/pop/push] helpers. Those operations are exposed to userspace applications through the already existing syscalls in the following way: BPF_MAP_LOOKUP_ELEM -> peek BPF_MAP_LOOKUP_AND_DELETE_ELEM -> pop BPF_MAP_UPDATE_ELEM -> push Queue/stack maps are implemented using a buffer, tail and head indexes, hence BPF_F_NO_PREALLOC is not supported. As opposite to other maps, queue and stack do not use RCU for protecting maps values, the bpf_map[peek/pop] have a ARG_PTR_TO_UNINIT_MAP_VALUE argument that is a pointer to a memory zone where to save the value of a map. Basically the same as ARG_PTR_TO_UNINIT_MEM, but the size has not be passed as an extra argument. Our main motivation for implementing queue/stack maps was to keep track of a pool of elements, like network ports in a SNAT, however we forsee other use cases, like for exampling saving last N kernel events in a map and then analysing from userspace.
Showing the changes to include/uapi/linux (1 of 10 files). Show all
Unified · Split
| @@ -128,6 +128,8 @@ enum bpf_map_type { · 127 unmodified lines | |||
| 128 | BPF_MAP_TYPE_CGROUP_STORAGE, | 128 | BPF_MAP_TYPE_CGROUP_STORAGE, |
| 129 | BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, | 129 | BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, |
| 130 | BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE, | 130 | BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE, |
| 131 | BPF_MAP_TYPE_QUEUE, | ||
| 132 | BPF_MAP_TYPE_STACK, | ||
| 131 | }; | 133 | }; |
| 132 | 134 | ||
| 133 | enum bpf_prog_type { | 135 | enum bpf_prog_type { |
| @@ -462,6 +464,28 @@ union bpf_attr { · 328 unmodified lines | |||
| 462 | * Return | 464 | * Return |
| 463 | * 0 on success, or a negative error in case of failure. | 465 | * 0 on success, or a negative error in case of failure. |
| 464 | * | 466 | * |
| 467 | * int bpf_map_push_elem(struct bpf_map *map, const void *value, u64 flags) | ||
| 468 | * Description | ||
| 469 | * Push an element *value* in *map*. *flags* is one of: | ||
| 470 | * | ||
| 471 | * **BPF_EXIST** | ||
| 472 | * If the queue/stack is full, the oldest element is removed to | ||
| 473 | * make room for this. | ||
| 474 | * Return | ||
| 475 | * 0 on success, or a negative error in case of failure. | ||
| 476 | * | ||
| 477 | * int bpf_map_pop_elem(struct bpf_map *map, void *value) | ||
| 478 | * Description | ||
| 479 | * Pop an element from *map*. | ||
| 480 | * Return | ||
| 481 | * 0 on success, or a negative error in case of failure. | ||
| 482 | * | ||
| 483 | * int bpf_map_peek_elem(struct bpf_map *map, void *value) | ||
| 484 | * Description | ||
| 485 | * Get an element from *map* without removing it. | ||
| 486 | * Return | ||
| 487 | * 0 on success, or a negative error in case of failure. | ||
| 488 | * | ||
| 465 | * int bpf_probe_read(void *dst, u32 size, const void *src) | 489 | * int bpf_probe_read(void *dst, u32 size, const void *src) |
| 466 | * Description | 490 | * Description |
| 467 | * For tracing programs, safely attempt to read *size* bytes from | 491 | * For tracing programs, safely attempt to read *size* bytes from |
| @@ -2303,7 +2327,10 @@ union bpf_attr { · 1835 unmodified lines | |||
| 2303 | FN(skb_ancestor_cgroup_id), \ | 2327 | FN(skb_ancestor_cgroup_id), \ |
| 2304 | FN(sk_lookup_tcp), \ | 2328 | FN(sk_lookup_tcp), \ |
| 2305 | FN(sk_lookup_udp), \ | 2329 | FN(sk_lookup_udp), \ |
| 2306 | FN(sk_release), | 2330 | FN(sk_release), \ |
| 2331 | FN(map_push_elem), \ | ||
| 2332 | FN(map_pop_elem), \ | ||
| 2333 | FN(map_peek_elem), | ||
| 2307 | 2334 | ||
| 2308 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper | 2335 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper |
| 2309 | * function eBPF program intends to call | 2336 | * function eBPF program intends to call |