BLOG
Fundamentals

The Two BPFs: How a Packet Filter Runs Code on Your Favourite Blockchain

Sourav Mishra

Sourav Mishra

Feb 16, 202610 min read

The Two BPFs: How a Packet Filter Runs Code on Your Favourite Blockchain

TL;DR: Every Solana program you've ever written compiles down to BPF bytecode - the same technology that powers Linux kernel observability at Cloudflare, Netflix, and Facebook. BPF was born in 1992 as a tiny packet filter VM. In 2014 it became eBPF and took over the Linux kernel. In 2020 Solana forked it to run smart contracts. Same instruction set, completely different lives. On Linux it observes the system; on Solana it is the system. The weird constraints you deal with (no floats, 4KB stack, forked toolchain) all trace back to this shared lineage. Understanding where your VM came from makes you a sharper developer when things break.

Both sides even share a compilation path - Rust through LLVM - but the toolchains forked hard. That's why you're stuck on an older Rust version while Linux eBPF devs get the latest nightly. The good news is that gap is closing. Two guys in Berkeley just wanted to filter packets faster. Now their little VM runs half the internet and all of Solana.


There's a piece of technology that simultaneously powers Cloudflare's DDoS protection, Netflix's performance monitoring, Facebook's load balancers - and every single smart contract on Solana. Same ancestor. Same bytecode format. Completely different lives.

If you write Solana programs, you've been compiling to BPF this whole time. If you've ever used tcpdump on a Linux box, you've been running BPF too. These aren't naming coincidences - they're the same technology that forked into two parallel universes, and very few people talk about both.

You probably already know one side. Here's the other - and why understanding it makes you a powerful Solana developer.

Your VM Has a Day Job

BPF (Berkeley Packet Filter) was built in 1992 to filter network packets inside the Linux kernel. A tiny register-based VM, about 20 instructions, deliberately limited because a bug in kernel space means the machine is dead. For two decades it just sat inside tcpdump, doing nothing interesting.

Then around 2014, Alexei Starovoitov at Facebook extended it into something massive. "Extended" BPF (eBPF) kept the safety model but expanded the scope: instead of just filtering packets, eBPF programs can now hook into any event in the Linux kernel. System calls, function entries, network sockets, scheduler decisions, storage I/O. It got 64-bit registers, persistent maps, helper functions and a JIT compiler, giving near-native performance.

Today, eBPF runs the infrastructure under the infrastructure. Cilium replaced iptables with it for Kubernetes networking. Cloudflare filters DDoS traffic with it at the edge. Datadog and Pixie use it for zero-instrumentation observability. It's arguably the most significant Linux kernel innovation of the past decade.

And this is where you come in. When Anatoly needed a safe, fast, sandboxed execution environment for Solana smart contracts, the requirements (run untrusted code safely, guarantee termination, near-native performance, deterministic execution) mapped almost perfectly onto what eBPF already did. So Solana forked the rbpf crate (a Rust eBPF VM by Quentin Monnet), modified it, and made it the runtime for every on-chain program you've ever deployed.

When you run cargo build-sbf, you're compiling through LLVM to eBPF bytecode. Same instruction set. Same binary format. Same register layout. You've been writing eBPF programs this whole time. You just didn't know it.

What the Other Side Looks Like

So what does BPF do when it's not running your token swaps? Understanding this is actually useful - it explains why the Solana VM works the way it does, and why some of its constraints exist.

On Linux, eBPF programs are middleware. They observe, measure, and sometimes modify - but they're never the main application. They hook into kernel events and add intelligence. Think of them as invisible plugins that watch the kernel work and occasionally tap it on the shoulder.

Your Solana programs are the opposite. They are the application. The business logic, the state transitions, the token movements - that's all happening inside the sBPF VM. You're not observing the system; you're being the system.

On Linux, eBPF gets the full kernel context: process info, network state, file descriptors, memory maps. On Solana, you get nothing except the accounts explicitly passed to your instruction. No network. No filesystem. No clock unless you read the Sysvar. This isolation isn't a limitation - it's the whole design. Your program has to produce identical output on every validator, and the moment it can see machine-specific state, that guarantee dies.

Linux eBPF stores state in maps, persistent key-value stores shared between invocations. You store state in accounts. There's no equivalent of BPF maps on Solana. Linux eBPF talks to user space through ring buffers and perf events. You talk to other programs through CPI. These are fundamentally different communication models - eBPF is vertical (kernel to user space), CPI is horizontal (program to program). eBPF has no equivalent of composability.

Why Solana's Verifier Is Softer (And That's Fine)

Here's something that might surprise you: the Linux eBPF verifier is significantly more paranoid than Solana's BPF loader. And for good reason.

The Linux verifier walks every possible execution path before your program loads. It tracks register states per-branch and proves termination statically. Over 10,000 lines of the most security-critical code in all of Linux. If it can't prove your program is safe, it doesn't run. Period. Because a bad eBPF program runs in kernel space, and a kernel crash means the machine is bricked until reboot.

Solana doesn't need that level of static paranoia because the threat model is different. Your program runs in a user-space VM. If it misbehaves, the VM catches it and the validator doesn't die. Instead, Solana leans on runtime checks: compute metering caps execution time, account ownership rules enforce permissions, and the big one - total environmental determinism (no floats, no randomness, no syscalls) prevents consensus divergence.

Neither verifier would accept the other's programs. A valid Linux eBPF program that reads /proc would instantly fail Solana's loader. One of your CPI-heavy Solana programs would make zero sense to the kernel verifier. Same bytecode format, incompatible safety models.

This actually explains some of the weird constraints you hit as a Solana developer. Why can't you use floats? Because two validators might round differently, and then the network forks. Why is your stack 4KB when you feel like you need more? Because the original BPF design was built around strict memory bounds — Solana actually gave you eight times what Linux eBPF allows (512 bytes). You're welcome.

The Toolchain Split (And Why It's Healing)

Here's the part that actually affects your day-to-day.

Both paths go through LLVM. Both start as Rust (usually). Same backend, similar constraints - #[no_std], #[no_main], restricted stdlib, no standard allocator. But the toolchains diverged hard.

You know this pain. Solana has maintained its own fork of Rust and LLVM to support the sbf-solana-solana target. cargo build-sbf pulls in a custom toolchain pinned to a specific Rust version. That's why you're sometimes stuck on older Rust - no latest nightly features, no newest crate versions, wondering why a perfectly good crate won't compile for your target.

On the Linux side, eBPF tooling is fully upstream. Standard compiler, standard distribution, no forks. Developers use libbpf, libbpf-rs, or Aya (pure Rust). Everything just works with the latest Rust.

The good news: this gap is closing. Recent work from Blueshift has shown you can compile Solana programs using upstream nightly Rust with a custom linker - no fork required. If this goes mainstream, you get the full Rust ecosystem without waiting for the Solana toolchain to catch up. Every crate, every nightly feature, every quality-of-life improvement. That's bigger than it sounds, and it's a direct benefit of the shared BPF lineage - the closer Solana stays to the upstream spec, the less custom tooling it needs to maintain.

The Payoff

Next time cargo build-sbf throws a cryptic BPF error at you, you'll know what layer you're fighting. When you hit the 4KB stack limit, you'll understand it's a generous upgrade from the 512 bytes that kernel developers get. When someone asks why Solana doesn't support floats, you won't say "idk, it just doesn't" - you'll explain that determinism is the price of consensus, and the VM was designed around that constraint from birth.

The VM under your smart contracts has a whole other life. It secures kernels, filters packets, monitors production systems, and balances traffic at planetary scale. The same instruction set that processes your token swaps traces system calls at Cloudflare.

It all started with two guys in Berkeley who just wanted to filter packets faster. Look what they started.


At OrbitFlare, we build Solana infrastructure - RPC nodes, Jetstream gRPC streaming, and trading APIs. If you're building on Solana and need reliable infrastructure under it, come talk to us.

Related articles