It is possible to share access to eBPF maps between programs of different types.
First, you can forget about those differences between struct bpf_elf_map
and struct bpf_map_def
. They are structs used in user space to build the objects to pass to the kernel. Iproute2 and libbpf may not use the same struct/attribute names, but they both end up passing the map metadata to the bpf()
system call in the same format, or the kernel would not understand what map is to be created.
When they are loaded to the kernel, eBPF programs refer to a given map through file descriptors to this map. This means that the process calling the bpf()
system call to load the program first has to retrieve file descriptors to the map to use. So the two following cases may happen:
User space application (ip, tc, bpftool...) parses the ELF object file and collects map-related metadata. It does not identify (and possibly did not even try to identify) any existing map that should be reused for the program. So it creates a new map with the bpf()
syscall, which returns a file descriptor to this newly-created map. This file descriptor is used in the program instructions referring to map access (once the program is loaded in the kernel, those file descriptors will be replaced by the map address), and the program is then loaded with the bpf()
syscall. This is what happens with your tc program, and in your case it seems, with your cgroup program which is creating a second map.
Or user application parses the ELF object file, and finds somehow that there is already an existing map that the program should use. For example, it finds a map of id 1337, or a pinned map under /sys/fs/bpf/
. In that case it retrieves a file descriptor to that map (from the id with bpf()
syscall, from a pinned path with open()
). Then as in the first case, it uses this file descriptor to prepare and then load the program.
Libbpf provides a way to reuse a file descriptor for a given map to use with a program. See for example bpf_map__reuse_fd()
. Bpftool uses it to support reusing existing maps, with the map
argument for bpftool prog load
(see man bpftool-prog
). For example, load a program from foo.o
and tell it to reuse map of id 27
for the first map found in the object file, then the map pinned at /sys/fs/bpf/foomap
for the map named foomap
in the object file:
# bpftool prog load foo.o /sys/fs/bpf/foo_prog \
map idx 0 id 27 \
map foomap stats pinned /sys/fs/bpf/foomap