Ido Kelson
Ido Kelson

Reputation: 23

ebpf - use ringbuf and perfbuf depending on kernel version

I am using ebpf to capture process creation. I am using ringbuf for kernel 5.8 and above and would like to use perfbuf for older kernels in the same ebpf kernel file. There is a great blog about it https://nakryiko.com/posts/bpf-core-reference-guide/#linux-kernel-version, according to it I can use a code like:

if (LINUX_KERNEL_VERSION < KERNEL_VERSION(5, 8, 0))
{
    // use the perfbuf
}
else
{
    // use the ringbuf
}

and the loader ignores the dead code. The issue is how to declare the ring buffer map under such a condition, because it is declared in a global scope and not inside a function:

struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 64 * 4096);
} rb SEC(".maps");

In kernels before 5.8 BPF_MAP_TYPE_RINGBUF is not defined and the load fails. Is there some Initialization function that is called that I can define and add the map in there according to the kernel version?

Upvotes: 2

Views: 1508

Answers (1)

Dylan Reimerink
Dylan Reimerink

Reputation: 7968

The creation of maps like this is always performed by the loader. So you can declare both a ring buffer and perf buffer and write your userspace program in such a way as to only load one of the two.

In general it isn't recommended to use kernel versions to detect feature support since some distros will backport certain features to older kernel versions (RedHat enterprise for example).

So if at all possible, its recommended to use feature probes provided by bpftool or cilium/ebpf.

In the case of bpftool it is also possible to ask the command to output C macros which allow you to use #ifdef pre-processor statements in your eBPF code (though this will require compiling on the target).

Upvotes: 1

Related Questions