There is a moment in the recent history of Linux when the kernel stopped being an untouchable monolith. Years ago, if you wanted to inspect or filter your server’s network traffic you had to accept an uncomfortable trade-off: recompile the kernel with a custom module, or resign yourself to analysing data by copying packets into user space. Neither option was good. The first could take the machine down with a single fault; the second paid a brutal bill in performance.
eBPF (extended Berkeley Packet Filter) changed that balance. Today it is the technology that lets you run programs inside the kernel without recompiling it and without putting the system at risk. It is not a lab trick: Cloudflare, Netflix, Meta and Google use it in production for observability, network security and load balancing. If you use Kubernetes, your cluster almost certainly already runs eBPF under the hood.
From packet filter to a programmable kernel
The origin goes back to 1992 and to the classic tcpdump, the tool that captures network packets. To filter which packets you were interested in, BSD invented the original BPF: a small filtering language translated into simple, safe instructions, designed to run quickly over each packet.
The jump to “extended” arrived with the Linux 3.18 kernel (2014), the work of Red Hat engineer Alexei Starovoitov. Suddenly the bytecode was no longer only for saying “I will keep this packet”. The instruction set was expanded, maps were added to store state and, above all, a loader was invented that checks the program before running it. BPF went from filtering to programming the kernel itself.
A verifier that acts as judge before the verdict
The key piece that makes all this possible is the verifier. When you load an eBPF program, the kernel does not run it blindly: it analyses it instruction by instruction in a static-analysis phase. It walks the program’s control-flow graph and proves that it terminates, that it does not access memory out of bounds, and that it cannot stall the system.
This analysis is so strict that loops are limited to a maximum number of iterations checked at load time, unless you use the bounded loops added in kernel 5.3. There is a single goal: an eBPF program that passes verification cannot hang or corrupt the kernel, no matter what happens at runtime. That is why it is considered safe to run third-party code in kernel space.
Once verified, the bytecode is compiled to native CPU instructions by a JIT (just-in-time) compiler, the same concept the Java JVM uses: instead of interpreting, machine code is generated on the fly so that execution is almost as fast as the kernel’s own code.
Hooks and maps
An eBPF program does not run by itself: it attaches to a hook (an anchor point). There are hundreds of them spread across the kernel. The most common are the system-call hooks (kprobes and tracepoints in the tracing layer), the network-stack hooks (XDP, which acts even before a packet enters the TCP/IP stack) and those in the driver layer.
To remember things between one invocation and the next, the program uses maps: data structures such as hash tables or arrays that live in the kernel but that user space can also read and write. That is how the counters, traffic limits and shared caches that feed monitoring dashboards are built.
This event-driven model explains its efficiency: the program runs in the same place where the event happens, without copying data to user space or switching context. In XDP, for example, millions of packets per second per core can be dropped because the decision is made inside the network driver itself.
What an attacker cannot do
Security does not depend on the developer’s good faith but on design. Even if a program passes the verifier, it has deliberate limitations: the maximum number of instructions per program, the ban on arbitrary pointers, and a bounded stack size (512 bytes). You cannot roam kernel memory at will or call arbitrary functions; only a small set of official, safe helpers (auxiliary functions) is available.
The verifier keeps two kinds of pointers separate, kernel and user, and tags each register of the program to know what it holds at all times. If it detects an attempt to use an uninitialised value or an out-of-bounds pointer, it simply rejects the load. This is what makes eBPF usable even for loading code whose authorship you do not fully control.
From observability to your cloud provider
The ecosystem that has grown around it is huge. Cilium manages the networking, security and observability of Kubernetes by replacing iptables with eBPF programs that decide traffic packet by packet. Falco watches container behaviour by detecting anomalous system calls. bpftrace lets you write small tracing programs with a syntax similar to awk, ideal for diagnosing a live server without restarting it.
At heart they are all the same story: a safe language, a strict verifier and a privileged execution point. That is why eBPF has earned the nickname “the kernel’s virtual machine”: it is not exactly that, but it comes close. It is an isolated, general-purpose interpreter that has turned the Linux kernel into a platform where inspection no longer has to be expensive.





