cilium/ebpf: load and manage eBPF programs from Go
ebpf-go is a pure-Go library to read, modify and load eBPF programs and attach them to various hooks in the Linux kernel.
At a glance
- What is it?
- The cilium/ebpf library loads, modifies and attaches eBPF programs from Go without cgo, and bpf2go compiles C programs into embeddable Go. It is for Go engineers building long-running kernel observability and networking tools, not for Kubernetes users looking for the Cilium CNI.
- Who is it for?
- Use cilium/ebpf when a Go application needs to load and manage eBPF programs without cgo. Check the release's supported Go versions, operating systems and architectures, and test against your target kernels.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- cilium/ebpf8,038 ★ · +73
| Repository | 2026-09-22 | 2026-11-14 |
|---|---|---|
| cilium/ebpf | 8k | 8k |
73 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What cilium/ebpf solves, and who it is not for
Loading an eBPF program from a Go process means talking to the bpf syscall directly: creating maps, resolving BTF type information, fixing up relocations in the ELF object, attaching to a hook and keeping the file descriptors alive. cilium/ebpf packages that work. The README describes it as a pure Go library that provides utilities for loading, compiling, and debugging eBPF programs, with minimal external dependencies, intended to be used in long running processes. The pure-Go part is the distinguishing property: no cgo, so cross-compilation and static binaries stay simple.
The audience is Go engineers writing agents, profilers or network dataplanes that ship their own eBPF. It is not the Cilium CNI, despite the shared name and organisation. If you are looking for Kubernetes pod networking, NetworkPolicy or kube-proxy replacement, this repository is the wrong artefact; the Cilium project is a separate codebase that happens to be the origin of this library. The README also points readers to ebpf.io for complementary projects rather than presenting itself as a platform.
The packages that make up the library
The README lists the packages explicitly, and the list is a good map of the design. asm is a basic assembler so you can emit eBPF instructions from Go, though the README notes you do not need it if you prefer writing the program in C. cmd/bpf2go compiles C and generates Go code for loading the program and its maps. link attaches programs to hooks. perf reads from a PERF_EVENT_ARRAY and ringbuf reads from a BPF_MAP_TYPE_RINGBUF map, which are the two event channels you will pick between. features is described as the equivalent of bpftool feature probe implemented natively in Go, useful for deciding at runtime whether a kernel supports what you need. rlimit lifts the RLIMIT_MEMLOCK constraint on kernels before 5.11. btf reads the BPF Type Format, and pin works with pinned objects on bpffs.
That split matters because btf and features are the parts that make the library usable across kernel versions. Instead of assuming a feature exists, you can query. The release notes reinforce how central BTF has become: v0.22.0 mentions vmlinux BTF caching changes, and v0.21.0 mentions BTF deduplication alongside Struct Ops and Weak Symbols.
Installing cilium/ebpf and running a first kprobe
The README does not inline install steps; it points to the Getting Started guide at ebpf-go.dev/guides/getting-started. The module path is github.com/cilium/ebpf, so the usual Go module workflow applies.
go get github.com/cilium/ebpfThat adds the dependency. Check the go.mod for the release you select and use a supported Go toolchain; the main branch's requirement can change independently of a published version.
For programs written in C, the second step is bpf2go, which the README says compiles and embeds eBPF programs written in C within Go code and auto-generates Go code for loading and manipulating the program and map objects.
The repository Makefile specifies its own default toolchain for project builds. That is not a universal pin for users: the getting-started example lists LLVM 11 or later, libbpf and Linux headers, and a suitable kernel. Verify requirements for your specific program and release.
Attaching is then a matter of the link package. The repository ships examples/kprobe/, examples/tracepoint_in_c/, examples/tracepoint_in_go/, examples/xdp/, examples/tcx/, examples/ringbuffer/ and others, each with its own directory, and examples/README.md indexes them. Those directories are the practical reference for the load-and-attach sequence, since the top-level README stops at the package list.
Where cilium/ebpf stops being the right tool
The requirements section is unusually honest about the boundary. Linux on amd64 and arm64 is tested against kernel.org LTS releases, and the README says >= 4.4 should work but EOL'ed versions are not supported. It also lists Windows amd64 with the latest eBPF for Windows release. Other architectures are best effort, and 32-bit architectures are unsupported. If your fleet includes 32-bit ARM nodes, this library will not cover them, and no amount of configuration changes that.
The second constraint is the toolchain. bpf2go compiles C, which means a clang and LLVM toolchain must exist at build time. The Makefile pins llvm-strip-22 and llvm-objcopy-22 alongside clang-22, and the Makefile builds inside a container image referenced from testdata/docker/IMAGE. Reproducing that environment is the maintainers' answer to version drift, and it is a signal that a mismatched clang is a real failure mode rather than a theoretical one.
The third is scope. The library loads and attaches programs; it does not give you a Kubernetes integration, a policy engine or a dataplane. The README's own framing is a set of utilities, and the contributing note asks for use cases that help shape the project. If you want a managed networking layer, you are looking at the wrong repository.
There is also a support-channel caveat the README states plainly: the #ebpf-go Slack channel is described as ephemeral and its history is erased past a certain point, which is less helpful for others running into the same problem later. GitHub Discussions is the durable path.
cilium/ebpf compared with libbpf and bpftool
The obvious alternative is libbpf, the C library that most eBPF tooling is built on. The difference is the language boundary. libbpf is C, so a Go program using it needs cgo, which complicates cross-compilation and static linking. cilium/ebpf reimplements the loading path in Go, which is why the README can claim minimal external dependencies and why the go.mod dependency list is short: go-quicktest/qt, google/go-cmp, jsimonetti/rtnetlink/v2, golang.org/x/sync and golang.org/x/sys are the direct requirements, with the rest marked indirect.
The trade-off runs the other way too. The two libraries can support new kernel features on different schedules, so check the specific feature and release instead of assuming either one always gains support first. v0.22.0 is titled around Linux 7.1 compat, BPF tokens and vmlinux BTF caching changes. For newly introduced facilities, verify support in the version you plan to deploy.
bpftool is a different kind of alternative: a command-line utility for inspecting and manipulating BPF objects. The features package is explicitly modelled on bpftool feature probe, so if your need is a one-off inspection rather than an in-process loader, the CLI is simpler. The library earns its place when the loading has to happen inside a long-running Go process that manages its own file descriptors and lifecycle.
Maintenance, licence and upgrade cost
The repository is not archived, and the last push was on 2026-11-02, so it is under active development by any reasonable reading. The release cadence shown is roughly every four to five months: v0.20.0 on 2025-10-31, v0.21.0 on 2026-03-05, v0.22.0 on 2026-06-29. All are pre-1.0, which is the practical upgrade consideration. A minor version bump can carry behavioural changes; v0.22.0's title mentions Linux 7.1 compat and vmlinux BTF caching changes, and v0.21.0 introduced Struct Ops and Weak Symbols. None of those are patch releases.
Because the module is a library rather than a binary, upgrading means rebuilding your agent and re-running its tests against the kernels you support. The repository's own Makefile builds a long list of testdata targets, including loader-clang-14, loader-clang-17 and loader-$(CLANG), plus loader_nobtf and manyprogs. That is a heavy test matrix, and it is a fair indication of how much surface a version bump can touch.
The licence is MIT, stated in both the README and the LICENSE file at the repository root. MIT is permissive and imposes no copyleft obligation on your own code, but this is not legal advice; if you redistribute the library, keep the copyright notice and licence text with it. One non-licence governance detail worth knowing: the README says the project is governed by Cilium's AI policy and the Linux Foundation's AI policy, with its own policy in AGENTS.md, and that submissions in violation are rejected without warning. If you plan to contribute, read AGENTS.md before opening a pull request.
Editorial conclusion
Use cilium/ebpf when a Go application needs to load and manage eBPF programs without cgo. Check the release's supported Go versions, operating systems and architectures, and test against your target kernels. For C programs, follow the getting-started guide and choose a compatible LLVM toolchain; the repository's Makefile defaults are not universal requirements.
Frequently asked questions
What is cilium/ebpf?
It is a pure-Go library for loading, compiling and debugging eBPF programs, described in its README as having minimal external dependencies and intended for long running processes. It is the library, not the Cilium CNI.
How does Cilium use eBPF?
The repository does not describe how the Cilium CNI uses eBPF; it presents itself as a library of utilities for loading, compiling and debugging eBPF programs, and points to ebpf.io for complementary ecosystem projects. Questions about the CNI itself belong with that separate project.
Can eBPF programs crash the kernel?
Linux verifies eBPF programs before loading to reject unsafe behavior, but the verifier and kernel are software and can contain defects. Keep kernels patched, restrict who can load programs and test on the kernels you operate; verification is not an absolute guarantee against kernel faults.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/cilium-ebpf)Star history chart for your README
[](https://hysenlabs.com/projects/cilium-ebpf)Was this useful?