Getting Started with eBPF
eBPF lets you run small programs inside the Linux kernel safely. In this post, you’ll write one, compile it, and see output.
What you need:
- Linux (kernel 5.4+)
- clang and llvm installed
- Root access
What is eBPF?
eBPF programs run when specific events happen in the kernel:
- System calls
- Function entry/exit
- Network packets
- Tracepoints
Your First eBPF Program
Let’s write a simple eBPF program that traces the execve system call - this runs every time a new process is executed.
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
SEC("kprobe/sys_execve")
int bpf_prog(struct pt_regs *ctx) {
char msg[] = "Hello, eBPF!";
bpf_trace_printk(msg, sizeof(msg));
return 0;
}
char LICENSE[] SEC("license") = "GPL";
Key Concepts
- SEC macro: Defines which hook point to attach to
- bpf_trace_printk: Helper function for debugging output
- License: Required for using certain BPF helpers
Compiling eBPF Programs
You’ll need a modern compiler with BPF support:
# Install dependencies (Ubuntu/Debian)
sudo apt install clang llvm libbpf-dev
# Compile to BPF bytecode
clang -O2 -target bpf -c hello.bpf.c -o hello.bpf.o
Loading and Attaching
Use bpftool or a loader library like libbpf:
# Load and attach with bpftool
sudo bpftool prog load hello.bpf.o /sys/fs/bpf/hello
# View output
sudo cat /sys/kernel/debug/tracing/trace_pipe
Why eBPF Matters
- Performance: Runs in kernel space without context switching
- Safety: Verified by the kernel before execution
- Flexibility: Can be updated without rebooting
- Observability: Deep visibility into kernel operations
Next Steps
- Explore libbpf for production use
- Check out bcc for Python bindings
- Read the eBPF documentation
In future posts, we’ll dive deeper into eBPF maps, more advanced tracing techniques, and building production-grade eBPF applications.