BPF From Scratch In Rust

17 points by airdrop


niklaskorz

At the time of this writing the bpfel-unknown-none target is only available on nightly

That is not entirely correct. The bpf targets themselves (there are two, little endian and big endian) do not require nightly, but build-std = ["core"] does. Thankfully, build-std is not a hard requirement to compile to the bpf targets. This was the motivation for my first and so far only rustc pull request. Before, you could not bootstrap the Rust compiler with both full-featured targets such as aarch64-apple-darwin or x86_64-unknown-linux-gnu and a no-std target such as bpfel-unknown-none while also generating docs. However, including the bpf targets in the bootstrap is required to avoid depending on build-std = ["core"] later on, as we then need an already precompiled core library in our toolchain. Disabling the documentation step wasn’t an option for NixOS either, so I’m very happy we were able to fix this in rustc itself. This allowed us to include both bpf targets in nixpkgs’ rustc, so if you pull in rustc from nixpkgs unstable (and soon NixOS 25.05, but not from fenix or rust-overlay!), there is no need for any nightly flags such as build-std to follow this article.

sammko

The article proceeds to remove all boilerplate and end up with a function written entirely in asm, because for some reason it can’t be written in Rust. Maybe could use a more interesting demo, that actually uses Rust for processing the events.

ocramz

As someone who has been living under a rock since reading about the OSI model back in ~ y2k and got out in 2025 reading about eBPF, please calibrate my (mis)understanding:

A linux-based router with a modern kernel could, in principle, see all traffic that goes through it as plaintext? Filter/route traffic selectively based on said content?

sammko

How come loop {} passes for a panic handler? I thought that would not appease the verifier, as it does not terminate. Or is it simply pruned by the linker as the code does not panic anywhere? But then panic=abort is also specified in the compilation flags, how does that interact with defining a panic_handler manually? Maybe I just don’t understand what the panic=abort flag actually does.

tonnydourado

It says no macros, but isn’t asm!a macro?