# bpf-examples: a working build environment for eBPF programs

> The xdp-project bpf-examples repository is a set of practical eBPF programs that also solve a quieter problem, which is getting a BPF toolchain working on a new machine without fighting libbpf. The configure script does the detection and the top level Makefile quietly drops the examples that cannot compile.

**xdp-project/bpf-examples** — Making eBPF programming easier via build env and examples

- Repository: https://github.com/xdp-project/bpf-examples
- Stars: 570 · Forks: 126
- Language: C
- License: not declared
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/xdp-project-bpf-examples

## A set of examples with a build system attached

The xdp-project bpf-examples repository contains a diverse set of practical BPF examples that solve or demonstrate a specific use case using BPF.

The declared purpose is not only the examples. The repository is meant to ease rapid prototyping and development, writing C code BPF programs using libbpf, and the stated goal is to make it easier for developers to get started coding.

The problem being solved is one every eBPF developer recognises. Writing a BPF program is easy. Getting a build environment where a BPF program compiles, loads, and attaches is where the time goes. libbpf needs specific clang features, specific BTF, specific kernel headers, and a set of build flags that are not obvious from a tutorial. The repository handles that setup transparently, using a configure script, and detects missing compile dependencies.

The README is explicit that the aim is to make BPF programming more consumable by detecting and reporting issues where it can. That framing matters, because a repository of examples that only works on the author's machine teaches nothing. One that fails with a specific message about a missing header is actually usable for learning.

The licence is recorded as one GitHub cannot classify, and the Makefile carries an SPDX identifier of GPL-2.0. The primary language is C, the last push was on 2026-10-20, and the repository publishes no GitHub releases.

## The directory names are the BPF hook points

The top level listing is a catalogue of eBPF attachment points, and reading the names tells you what the repository covers.

There are four AF_XDP examples, one for a basic example, one for forwarding and one for interaction, which covers the AF_XDP socket path for user space to kernel packet handling. There is a tc-basic-classifier and a tc-policy example, which is the traffic control hook. There is an LPM-map-bench for the longest prefix match map, an MTU-tests directory, and a bpf-link-hang example, which is about the pinning and lifetime semantics of bpf links.

The rest cover a spread of newer and more specialised mechanisms. There is a delay-kfunc example, which uses the delay kfunc style of sleepable BPF work, a ktrace-CO-RE directory for kernel tracing with compile-time type information, an lsm-nobpf example, and a nat64-bpf example for network address translation in BPF. There is a dhcp-relay, a pkt-loop-filter, a pping for latency probing, a preserve-dscp example, a traffic-pacing-edt example for the newer packet pacing mode, an xdp-synproxy for a SYN proxy in XDP, an encap-forward for encapsulation and forwarding, a netstacklat for latency measurement in the network stack, and a BTF-playground.

The two directories that are not example programs at all are lib/, which holds the libbpf submodule, and include/ and headers/, which hold shared headers. That is the layering: libbpf is a dependency, the examples are the content, and the headers are shared between them.

## The configure script reports what is missing instead of failing later

The mechanism that makes the repository usable is the configure script, and the README describes a specific failure it is designed to catch.

If you get the following output from configure:

> clang errno support: no - some examples will fail and won't be compiled from the top-level Makefile. See README.md.

then you are missing a header file that is included in a 32-bit architecture header file. The README explains what happens next: some of the examples in the repository will compile fine without this header file, and the build system will automatically exclude the examples that require the header from the build if the header is missing. Manually compiling the utilities excluded will fail in this case.

The fix is per distribution. On Fedora you install glibc-devel.i686, and on Debian you install libc6-dev-i386:

```bash
  -  dnf install glibc-devel.i686
  -  apt install libc6-dev-i386
```

The two-part failure here is instructive. The build does not simply stop, because a build that stops tells you less than a build that continues with the affected parts removed. You get a warning, the affected examples are dropped from the build, and the README tells you that compiling those by hand will fail. The error is reported at the point where it is still actionable.

The top level Makefile encodes the same decision. The subdirectories that need the header are listed in a conditional block, and the ones that do not are always included.

## The Makefile lists the always-built examples separately from the conditional ones

The top level Makefile is where the configuration result is applied, and reading it shows the shape of the whole build.

Some example directories are unconditional. They are always part of the build:

```bash
SUBDIRS += AF_XDP-example
SUBDIRS += AF_XDP-forwarding
SUBDIRS += ktrace-CO-RE
SUBDIRS += tc-policy
SUBDIRS += delay-kfunc
```

And a larger group is conditional on the clang errno check having succeeded, which is the HAVE_CLANG_ERRNO variable set by the configure script. The conditional set includes encap-forward, lsm-nobpf, nat64-bpf, pkt-loop-filter, pping, preserve-dscp, tc-basic-classifier, traffic-pacing-edt and xdp-synproxy.

The build order is driven by a single rule that depends on the lib target, which in turn depends on config.mk and the submodule check. config.mk is generated by running the configure script, so the first make invocation runs configure for you.

There is also a check_submodule target that compares the recorded submodule SHA against what is checked out and prints a warning if they are out of sync, suggesting you run git submodule update. That is the second common way a fresh clone fails, and having the build tell you about it rather than failing to find a header saves the same kind of time as the errno check.

The Makefile also has a help target listing the available targets and the V argument for build verbosity, and the top of the file sets the shell to bash with a comment explaining that some environments do not link sh to bash.

## What the examples are for, and what they are not

It is worth being precise about the scope, because a repository of eBPF programs can be mistaken for something it is not.

These are teaching examples, not a library. There is no API you depend on, no stability guarantee, and no release tags. The value is in reading working code that attaches to a specific hook, and in being able to build and run it to see what it does.

The breadth across hook types is the interesting part for learning. A single hook teaches you one attachment model. This repository has XDP at the link layer, tc at the queueing layer, LSM for security decisions, kfunc and kprobe for kernel functions, CO-RE tracing for typed kernel data, and traffic control and pacing for the newer packet scheduling work. Each of those has its own section of the BPF API and its own set of gotchas, and having them side by side in one tree makes the differences visible.

The alternative approach is to read the kernel documentation and the libbpf examples directly. The kernel sources ship their own selftests, which are the most authoritative reference and the closest thing to a specification. What this repository adds is a build environment that works and a set of programs written in a style closer to application code than to test code.

The cost is that examples age. A BPF example written against an older libbpf or an older kernel can need updating, and the repository records no releases, so there is no version to correlate the code with. The kfunc and traffic pacing examples in particular are areas where the kernel API has been moving.

## Conclusion

Adopt bpf-examples if you are learning eBPF and want a working libbpf build environment plus runnable programs to read, or if you need a reference for a specific BPF hook such as tc, XDP, LSM or a kfunc. Do not adopt it as a library, since it is a set of examples rather than a reusable component, and do not expect the examples to be a maintained API surface. Before you start, run the configure script and read its output about clang errno support, because a missing 32-bit header causes some examples to be excluded from the top level Makefile build and the excluded utilities will fail to compile by hand.

## FAQ

### What is the xdp-project bpf-examples repository for?

It holds a diverse set of practical BPF examples that solve or demonstrate a specific use case, written in C using libbpf, and it is meant to ease rapid prototyping and development by providing a build environment that sets up libbpf transparently and detects missing compile dependencies.

### What does the clang errno support message in the bpf-examples configure output mean?

It means you are missing a header file that is included in a 32-bit architecture header file. The build system automatically excludes the examples that require it from the top level Makefile build, and compiling those excluded utilities manually will fail.

### How do I fix the missing clang errno support in bpf-examples?

Install the 32-bit development headers for your distribution. On Fedora that is `dnf install glibc-devel.i686`, and on Debian it is `apt install libc6-dev-i386`. Some examples compile without the header, so the build continues with the affected ones excluded.

### Which BPF hook points do the bpf-examples cover?

The directory listing includes AF_XDP examples, tc-basic-classifier and tc-policy, an LPM-map-bench, ktrace-CO-RE, lsm-nobpf, nat64-bpf, dhcp-relay, pkt-loop-filter, pping, preserve-dscp, traffic-pacing-edt, xdp-synproxy, encap-forward, delay-kfunc, bpf-link-hang, MTU-tests, a netstacklat example and a BTF-playground.

## Sources

- [Issues](https://github.com/xdp-project/bpf-examples/issues)
- [README](https://github.com/xdp-project/bpf-examples/blob/main/README.md)
- [xdp-project/bpf-examples on GitHub](https://github.com/xdp-project/bpf-examples)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/xdp-project-bpf-examples
