Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Lab environment

The book targets Linux 7.1. Reading and rendering the mdBook works on other platforms; compiling or running the eBPF labs requires Linux.

Use an isolated Linux host

Use a disposable VM or dedicated development machine where you have root. Tracing labs attach read-only programs, but later chapters exercise XDP, tc, tcx, AF_XDP, cgroups, TCP struct_ops, and sched_ext. Never learn those hooks on the interface carrying your only SSH session or on a production scheduler.

For runtime work the kernel needs BTF at /sys/kernel/btf/vmlinux, BPF syscall and JIT support, and each chapter’s hook/map/kfunc configuration. Linux 7.1 provides the required APIs when its corresponding BPF, networking, cgroup, TCP-congestion-control, and sched_ext options are enabled. The preflight checks what it can without changing the host; attachment failures still report the specific unavailable hook or kfunc.

Clone the pinned dependencies

git clone --recurse-submodules https://github.com/biefy/books.git
cd books

For an existing clone:

git submodule update --init --recursive

The repository pins:

  • libbpf-bootstrap at fac4e8ddf011aead8e14962bf8db74542331264b, recursively including libbpf, bpftool, and architecture vmlinux.h;
  • xdp-tools/libxdp v1.6.3 at 8fbad9f0af621a22aa87ff2520b3735915b1f0fd;
  • the official Linux 7.1 archive and commit in ebpf/labs/linux-source.lock.json.

Do not replace these with moving branches when validating book code.

Install build prerequisites

You need Clang 17+ with the BPF target, a C compiler, GNU Make, Git, Python 3, libelf/zlib development headers, and m4 for the pinned libxdp build. The kernel-backed DCTCP and sched_ext builds add ordinary kernel build tools. On Ubuntu or Debian:

sudo apt update
sudo apt install -y \
  clang llvm git make gcc libc6-dev libelf-dev zlib1g-dev pkg-config python3 \
  curl xz-utils m4 flex bison pahole libssl-dev libcap-dev libunwind-dev \
  libdw-dev libpcap-dev bc rsync binutils iproute2 iperf3

Package names differ on other distributions. Repository scripts do not install packages, invoke sudo, mount filesystems, or silently fetch dependencies.

Run the check-only standalone preflight:

ebpf/labs/scripts/preflight.sh

Add --kernel after selecting/fetching the locked source and --runtime when you also want checks against the running host:

ebpf/labs/scripts/linux-source.sh fetch
ebpf/labs/scripts/preflight.sh --kernel --runtime

Build all lab sources

The quick path compiles every repository-owned standalone lab, including AF_XDP and the reference capstone:

make -C ebpf/labs check-standalone

The exhaustive check also builds the canonical Linux v7.1 DCTCP object and the sched_ext backends:

ebpf/labs/scripts/linux-source.sh fetch
make -C ebpf/labs check

Use an existing exact checkout with LINUX_SRC=/path/to/linux. The helper rejects other commits/releases. Build one chapter with make -C ebpf/labs dayNN; use day28-30 for the combined capstone. All generated artifacts stay under ebpf/labs/.output/ and make clean removes them. Kernel-backed wrappers build only the relevant v7.1 aggregate, convert its DWARF to BTF, and generate a narrow vmlinux.h; compilation never depends on the build host’s kernel BTF.

Coverage by backend

DaysRunnable source/build owner
1–21, 24Repo-owned standalone libbpf/libxdp apps
22Exact Linux v7.1 DCTCP BPF selftest wrapper
23Repo-owned telemetry DCTCP derivative against v7.1 support
25Exact v7.1 tools/sched_ext/scx_simple wrapper
26Repo-owned priority-cgroup sched_ext derivative against v7.1 support
27Exact v7.1 tools/sched_ext/scx_central wrapper
28–30Repo-owned Option A reference capstone; the other project choices remain open-ended

make check-coverage compares this curriculum mechanically with SUMMARY.md, manifest.json, the source tree, and the chapter includes.

Run without leaking state

Run ordinary loaders in the foreground and stop them with Ctrl-C. Their signal paths destroy skeleton-owned links and maps; nothing is pinned unless a chapter explicitly teaches pinning.

The privileged smoke dispatcher is opt-in and accepts an explicit day list:

EBPF_LABS_ALLOW_PRIVILEGED=1 \
  sudo --preserve-env=EBPF_LABS_ALLOW_PRIVILEGED \
  ebpf/labs/scripts/smoke.sh day01 day14

It owns its triggers, child PIDs, temporary files, namespaces/veths, qdiscs, and cgroups and cleans them in reverse order. TCP struct_ops registration additionally requires EBPF_LABS_ALLOW_STRUCT_OPS=1; sched_ext replacement requires EBPF_LABS_ALLOW_SCHED_EXT=1. Run either only on a disposable compatible VM. Hosted CI performs compile/link/BTF and locked-source builds only; it never performs privileged attachment.