Search code examples
bpfebpfxdp-bpfbcc-bpf

How to share a ebpf map between interfaces


Is it possible to share an ebpf Map between two network interfaces. I want to write an XDP program and hook it on two devices namely eth0 and eth1. The implementation requires that they both use the same map. Is it possible to load the same program, hooking them at eth0 and eth1 and use the same Map.

Thank you all!


Solution

  • Yes, this is entirely possible. An eBPF map is not attached to an interface, it is created in the kernel and then referenced by one or several of:

    • A file descriptor, from the application that created the map,
    • An eBPF program that uses the map,
    • A reference in another map of a dedicated type (array-of-maps, hash-of-maps),
    • A pinned path in the eBPF virtual file system.

    eBPF maps can be shared between consecutive program runs, between kernel and user space, or - as for your use case - between different eBPF programs, no matter what interfaces they are attached to. Note that a given program could even be detached and later re-attached to another interface, anyway.

    For reusing a map for several programs, this is done by pointing to the same map when you load your programs: What happens when you load one is that you get a handle to the map (its id or its pinned path, for example), get a file descriptor to the map from that handle, and place this file descriptor in your eBPF bytecode before loading it. Then the kernel translates the file descriptor into the relevant memory address.

    What happens most of the time in practice is that this “relocation” step (placing the file descriptor in the bytecode) is handled for you by the framework you are using to load your programs, such as libbpf or bcc tools. For example, libbpf has a bpf_map__reuse_fd(struct bpf_map *map, int fd) function to explicitly reuse a given file descriptor for a specific map used by a program, after parsing an object file to extract the bytecode but before loading it.