Especially in large software projects which have contributions from dozens of developers, changes can unexpectedly disrupt related functionalities.
Likewise, eBPF programs require thorough testing to detect issues before they could impact production applications.
In today’s newsletter, I will demonstrate how to test eBPF XDP programs.
The core functionality for unit testing eBPF programs is the BPF_PROG_RUN command, which was previously named BPF_PROG_TEST_RUN and can be used interchangeably.
This command is invoked via the bpf() syscall to execute an eBPF program and return its results to user-space, enabling unit tests with user-supplied context objects.
As of this writing, it supports the execution of the following eBPF program types:
BPF_PROG_TYPE_SOCKET_FILTERBPF_PROG_TYPE_SCHED_CLSBPF_PROG_TYPE_SCHED_ACTBPF_PROG_TYPE_XDPBPF_PROG_TYPE_SK_LOOKUPBPF_PROG_TYPE_CGROUP_SKBBPF_PROG_TYPE_LWT_INBPF_PROG_TYPE_LWT_OUTBPF_PROG_TYPE_LWT_XMITBPF_PROG_TYPE_LWT_SEG6LOCALBPF_PROG_TYPE_FLOW_DISSECTORBPF_PROG_TYPE_STRUCT_OPSBPF_PROG_TYPE_RAW_TRACEPOINTBPF_PROG_TYPE_SYSCALL
However, directly invoking the syscall and ensuring all parameters are correctly set can be tedious. To simplify this, libbpf offers the bpf_prog_test_run_opts wrapper, which streamlines the process.
💡libbpfis a C library that provides essential tools and abstractions for loading, managing, and interacting with eBPF programs in the Linux kernel.
The arguments for the bpf_prog_test_run_opts function are an eBPF program file descriptor and a bpf_test_run_opts structure.
Inside the function, bpf_prog_test_run_opts simply copies the provided bpf_test_run_opts struct, performs some sanity checks, and then directly invokes the bpf() syscall through the sys_bpf() wrapper.
While many fields in the bpf_test_run_opts struct are optional, it really depends on the type of eBPF program you are testing.
The important fields we utilize for unit testing XDP programs are:
szis always required, and it is simply set tosizeof(bpf_test_run_opts).data_inanddata_size_inallow us to provide mock data to the eBPF program. In the case of an XDP program, this would be an IPv4 packet.repeatspecifies how many times the test should run. This is useful if we want to gather some performance measurements.
I find code example renders in Substack tedious, so I’ll refer to my GitHub repository with the complete code demonstration.
⏪ Did you miss the previous issues? I'm sure you wouldn't, but JUST in case:
I hope you find this resource as interesting as I do. Stay tuned for more exciting developments and updates in the world of eBPF in next week's newsletter.
Until then, keep 🐝-ing!
Warm regards, Teodor





