| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- .. SPDX-License-Identifier: GPL-2.0-only
- .. Copyright (C) 2022 Red Hat, Inc.
- ========================================================
- BPF_MAP_TYPE_ARRAY_OF_MAPS and BPF_MAP_TYPE_HASH_OF_MAPS
- ========================================================
- .. note::
- - ``BPF_MAP_TYPE_ARRAY_OF_MAPS`` and ``BPF_MAP_TYPE_HASH_OF_MAPS`` were
- introduced in kernel version 4.12
- ``BPF_MAP_TYPE_ARRAY_OF_MAPS`` and ``BPF_MAP_TYPE_HASH_OF_MAPS`` provide general
- purpose support for map in map storage. One level of nesting is supported, where
- an outer map contains instances of a single type of inner map, for example
- ``array_of_maps->sock_map``.
- When creating an outer map, an inner map instance is used to initialize the
- metadata that the outer map holds about its inner maps. This inner map has a
- separate lifetime from the outer map and can be deleted after the outer map has
- been created.
- The outer map supports element lookup, update and delete from user space using
- the syscall API. A BPF program is only allowed to do element lookup in the outer
- map.
- .. note::
- - Multi-level nesting is not supported.
- - Any BPF map type can be used as an inner map, except for
- ``BPF_MAP_TYPE_PROG_ARRAY``.
- - A BPF program cannot update or delete outer map entries.
- For ``BPF_MAP_TYPE_ARRAY_OF_MAPS`` the key is an unsigned 32-bit integer index
- into the array. The array is a fixed size with ``max_entries`` elements that are
- zero initialized when created.
- For ``BPF_MAP_TYPE_HASH_OF_MAPS`` the key type can be chosen when defining the
- map. The kernel is responsible for allocating and freeing key/value pairs, up to
- the max_entries limit that you specify. Hash maps use pre-allocation of hash
- table elements by default. The ``BPF_F_NO_PREALLOC`` flag can be used to disable
- pre-allocation when it is too memory expensive.
- Usage
- =====
- Kernel BPF Helper
- -----------------
- bpf_map_lookup_elem()
- ~~~~~~~~~~~~~~~~~~~~~
- .. code-block:: c
- void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)
- Inner maps can be retrieved using the ``bpf_map_lookup_elem()`` helper. This
- helper returns a pointer to the inner map, or ``NULL`` if no entry was found.
- Examples
- ========
- Kernel BPF Example
- ------------------
- This snippet shows how to create and initialise an array of devmaps in a BPF
- program. Note that the outer array can only be modified from user space using
- the syscall API.
- .. code-block:: c
- struct inner_map {
- __uint(type, BPF_MAP_TYPE_DEVMAP);
- __uint(max_entries, 10);
- __type(key, __u32);
- __type(value, __u32);
- } inner_map1 SEC(".maps"), inner_map2 SEC(".maps");
- struct {
- __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
- __uint(max_entries, 2);
- __type(key, __u32);
- __array(values, struct inner_map);
- } outer_map SEC(".maps") = {
- .values = { &inner_map1,
- &inner_map2 }
- };
- See ``progs/test_btf_map_in_map.c`` in ``tools/testing/selftests/bpf`` for more
- examples of declarative initialisation of outer maps.
- User Space
- ----------
- This snippet shows how to create an array based outer map:
- .. code-block:: c
- int create_outer_array(int inner_fd) {
- LIBBPF_OPTS(bpf_map_create_opts, opts, .inner_map_fd = inner_fd);
- int fd;
- fd = bpf_map_create(BPF_MAP_TYPE_ARRAY_OF_MAPS,
- "example_array", /* name */
- sizeof(__u32), /* key size */
- sizeof(__u32), /* value size */
- 256, /* max entries */
- &opts); /* create opts */
- return fd;
- }
- This snippet shows how to add an inner map to an outer map:
- .. code-block:: c
- int add_devmap(int outer_fd, int index, const char *name) {
- int fd;
- fd = bpf_map_create(BPF_MAP_TYPE_DEVMAP, name,
- sizeof(__u32), sizeof(__u32), 256, NULL);
- if (fd < 0)
- return fd;
- return bpf_map_update_elem(outer_fd, &index, &fd, BPF_ANY);
- }
- References
- ==========
- - https://lore.kernel.org/netdev/20170322170035.923581-3-kafai@fb.com/
- - https://lore.kernel.org/netdev/20170322170035.923581-4-kafai@fb.com/
|