Beeper (BEEline's ParsER) is an application-layer parser for eBPF. It allows you to process L7 protocols directly in the kernel, which can accelerate user space applications significantly. It achieves this by constructing an Aho-Corasick-like DFA in user space, reducing the parsing complexity to an eBPF-compatible level. With Beeper, you can for example monitor application-layer traffic, redirect it based on its payload, or respond to it, directly from the kernel. For more information, please have a look at the full paper.
| Protocol | Status | Minimal Kernel Version |
|---|---|---|
| HTTP/1.1 | ✅ | 6.8 |
| HTTP/2 | ✅ | 6.8 |
| gRPC | WIP |
First, in the Rust program, create a new parser instance, add the desired headers that it should parse, and attach it to an existing eBPF program:
use beeper::h2;
let h2 = h2::Parser::new()
.capture_hdr(&beeper::header::PATH)?
.capture_hdr(&http::header::CONTENT_LENGTH)?
.replace_parse_msg("parse_h2")
.replace_extract("extract_h2_match")
.attach(prog_fd)?;Next, in your eBPF program, import the beeper.h header, define the stub functions, and call them with the input buffer:
#include "beeper.h"
// stub funcs
BEEPER_EXTRACT_MATCH(extract_h2_match)
BEEPER_H2_PARSE_MSG(parse_h2)
// the header matches occur in the same order as configured in user space
#define H2_PATH_MID 0
#define H2_CONTENT_LENGTH_MID 1
SEC("sk_msg")
int msg_verdict(struct sk_msg_md *msg) {
struct parse_res pres = { 0 };
struct h2_frame frame = { 0 };
int msg_len = parse_h2(msg, &pres, &frame);
if (msg_len >= 0) {
struct hdr_str path = { 0 };
if (extract_h2_match(msg, &pres, H2_PATH_MID, &path) == 0) {
// note that path can be Huffman-encoded
}
}
}Finally, to make this all compile, Beeper relies on xbpf. Add the following to build.rs:
use beeper::build::clang_args;
use xbpf::build::Builder;
fn main() {
Builder::new()
.clang_arg(clang_args().iter())
.export_headers()
.build();
}Please refer to the example for the full code.
To build and test Beeper, you need to install the following packages:
sudo apt install clang-18 llvm-18 libelf-dev zlib1g-dev linux-headers-`uname -r` linux-tools-`uname -r` You should now be able to compile and test Beeper as follows:
RUST_LOG=trace cargo testOnce you can build Beeper, you can also run the example. It is a simple HTTP server, with Beeper attached to it. It will serve some static files directly from the kernel. To run it, first start the server:
cargo run --bin exampleThen, in another terminal, make a request to the server:
curl -vv http://127.0.0.1:8080/index.htmlIn the logs of the server, you should find a line that indicates that the request was served directly from the kernel:
Served request
To benchmark the server, run the following:
# server accelerated with beeper
RUST_LOG= cargo run -r --bin example
# baseline: server without the fastpath
RUST_LOG= cargo run -r --bin example -- --no-fastpathIn a new window, you can now run the load test:
cargo install oha
# to test http1 performance
oha -c 100 -q 1000 -z 30s --latency-correction --urls-from-file example/load.txt
# to test http2 performance
oha -c 100 -q 1000 -z 30s --http2 --latency-correction --urls-from-file example/load.txtIf you use this library to conduct your own research, please cite the full paper as follows:
@misc{beeline,
title={Enforcing Application-Layer Policies in eBPF},
author={Laurin Brandner and Ayush Mishra and Sebastiano Miano and Aurojit Panda and Gianni Antichi and Laurent Vanbever},
year={2026},
eprint={2605.31084},
archivePrefix={arXiv},
primaryClass={cs.NI},
url={https://arxiv.org/abs/2605.31084},
}