Loading Objects¶
ebpf-go
ships an eBPF object (ELF) loader that aims to be compatible with the
upstream libbpf and iproute2 (tc
/ip
) projects. An ELF is typically obtained
by compiling a eBPF C program using the LLVM toolchain (clang
).
This page describes the journey from compiled eBPF ELF to resources in the kernel. This involves parsing the ELF into intermediate Go (Spec) types that can be modified and copied before loading them into the kernel.
graph LR
ELF --> ProgramSpec --> Program
ELF --> Types
ELF --> MapSpec --> Map
Map & Program --> Links
subgraph Collection
Program & Map
end
subgraph CollectionSpec
ProgramSpec & MapSpec & Types
end
CollectionSpec
¶
A CollectionSpec represents eBPF objects extracted from an ELF, and can be
obtained by calling LoadCollectionSpec
. In the examples below, we
declare a Map and Program in eBPF C, then load and inspect them using Go. Use
the tabs to explore the Go and C counterparts below.
All of a Spec's attributes can be modified, and those modifications influence the resources created in the kernel. Be aware that doing so may invalidate any assumptions made by the compiler, resulting in maps or programs being rejected by the kernel. Proceed with caution.
See Section Naming to learn about the use of the
SEC()
macro in the example above.
NewCollection
¶
After parsing the ELF into a CollectionSpec, it can be loaded into the kernel
using NewCollection
, resulting in a Collection
.
Collection.Close
closes all Maps and Programs in the
Collection. Interacting with any resources after Close()
will return an
error, since their underlying file descriptors will be closed. See Object
Lifecycle to gain a better understanding of how ebpf-go
manages its resources and for best practices handling Maps and
Programs.
LoadAndAssign
¶
LoadAndAssign is a convenience API that can be used instead of NewCollection
.
It has two major benefits:
- It automates pulling Maps and Programs out of a Collection. No more
if m := coll.Maps["my_map"]; m == nil { return ... }
. - Selective loading of Maps and Programs! Only resources of interest and their dependencies are loaded into the kernel. Great for working with large CollectionSpecs that only need to be partially loaded.
First, declare a struct that will receive pointers to a Map and a Program after
loading them into the kernel. Give it a Close()
method to make cleanup
easier.
Declare a custom struct myObjs | |
---|---|
Use bpf2go if the preceding code snippet looks tedious. bpf2go can generate this kind of boilerplate code automatically and will make sure it stays in sync with your C code.
Next, instantiate a variable of our newly-declared type and pass its pointer to
LoadAndAssign
.
If your use case requires dynamically renaming keys in CollectionSpec.Maps, you may need to use NewCollection instead. Map and Program names in struct tags are baked into the Go binary at compile time.
Type Information (BTF)¶
If an eBPF ELF was built with clang -g
, it will automatically contain BTF type
information. This information can be accessed programmatically through CollectionSpec.Types
. Note that this field will be nil
if the ELF
was built without BTF.
Many eBPF features rely on ELFs to be built with BTF, and there is
little to be gained by opting out of it. clang -g
also includes DWARF
information in the ELF which can be safely removed with llvm-strip
. eBPF
does not rely on DWARF information.
Authored by