eBPF (Extended Berkeley Packet Filter)
Relevant source files
The following files were used as context for generating this wiki page:
eBPF is a kernel-side facility that allows programs to run in reaction to specific events within the Linux kernel. It extends the original Berkeley Packet Filter (cBPF) by providing a more powerful instruction set and the ability to call special helper functions. eBPF programs interact with the system through various hooks such as tracepoints, kprobes, and network packet processing pipelines.
The eBPF subsystem provides a mechanism to load, verify, and execute code safely within the kernel environment. It uses a Just-In-Time (JIT) compiler to translate eBPF bytecode into native machine instructions for high performance. Applications use eBPF for networking, security (seccomp), and tracing.
Sources: Documentation/bpf/index.rst:1-10, Documentation/bpf/libbpf/libbpf_overview.rst:6-15, Documentation/networking/filter.rst:436-450
Application Lifecycle
A BPF application consists of BPF programs, maps, and global variables. The lifecycle follows four distinct phases managed by the kernel and user-space loaders.
Lifecycle Phases
- Open Phase: The loader parses the BPF object file and discovers maps, programs, and variables.
- Load Phase: The loader creates maps, resolves relocations, and verifies programs before loading them into the kernel.
- Attachment Phase: The loader attaches programs to kernel hooks (e.g., tracepoints or cgroup hooks).
- Tear Down Phase: The loader detaches programs, unloads them, and destroys maps.
This diagram illustrates the progression of an eBPF application from initial object parsing to final resource cleanup.
Sources: Documentation/bpf/libbpf/libbpf_overview.rst:29-57
BPF Architecture and Instruction Set
The eBPF instruction set (ISA) mimics native 64-bit CPU instructions to allow efficient mapping to native code. Internally, the kernel uses this format for both the interpreter and the JIT compiler.
Core Elements
| Element | Description |
|---|---|
| Accumulator (A) | 32-bit wide register for operations in cBPF. |
| X Register | 32-bit wide register in cBPF. |
| Scratch Memory (M[]) | 16 x 32-bit registers for temporary storage. |
| eBPF Registers | Modern 64-bit registers used in extended BPF. |
Sources: Documentation/networking/filter.rst:160-170, Documentation/networking/filter.rst:436-455
Instruction Types
eBPF supports several classes of instructions:
- Load/Store: Moves data between registers, memory, and packets.
- ALU: Performs arithmetic and logic operations (Add, Sub, Mul, Div, etc.).
- Branch: Handles conditional and unconditional jumps (JEQ, JGT, JSET).
- Return: Exits the program with a return code.
Sources: Documentation/networking/filter.rst:192-235
Helper Functions
Helper functions allow eBPF programs to interact with the kernel safely. Because eBPF programs cannot call arbitrary kernel functions, they use a restricted list of stable APIs called helpers.
Common Helper Categories
- Maps Interaction:
bpf_map_lookup_elem,bpf_map_update_elem. - System Information:
bpf_ktime_get_ns,bpf_get_current_pid_tgid. - Networking: Manipulate network packets or redirect traffic.
- Tracing:
bpf_trace_printkfor debugging messages.
Sources: Documentation/bpf/libbpf/libbpf_overview.rst:104-113, scripts/bpf_doc.py:34-45
This diagram shows the synchronous interaction between an eBPF program and the kernel via defined helper functions.
Sources: Documentation/bpf/libbpf/libbpf_overview.rst:104-113, scripts/bpf_doc.py:34-45
BPF CO-RE (Compile Once – Run Everywhere)
BPF CO-RE enables portability across different kernel versions without recompilation on the target machine. It relies on BPF Type Format (BTF) to describe kernel data structures.
Components of CO-RE
- BTF: Authoritative type information exposed via
/sys/kernel/btf/vmlinux. - Compiler (Clang): Records relocation information for structure fields.
- Loader (libbpf): Matches the recorded relocations against the running kernel's BTF and adjusts offsets dynamically.
Sources: Documentation/bpf/libbpf/libbpf_overview.rst:115-143
Summary
eBPF provides a highly efficient and safe method for extending kernel functionality. By leveraging a custom ISA, JIT compilation, and a robust verification system, it allows developers to run complex logic at various hook points without compromising system stability. The introduction of CO-RE and libbpf has significantly improved the portability and ease of development for BPF-based applications.
Sources: Documentation/bpf/index.rst, Documentation/bpf/libbpf/libbpf_overview.rst