github.com/cilium/ebpf@v0.15.0/docs/ebpf/contributing/architecture.md (about) 1 Architecture of the library 2 === 3 4 The bulk of the functionality of the library split across the `ebpf`, `btf` and 5 `link` packages. 6 Below is a diagram how the most important types relate to each other. 7 The graph is in dependecy order, so an arrow from `Links` to `Map` can be read 8 as "Link depends on Map". 9 10 ```mermaid 11 graph RL 12 Program --> ProgramSpec --> ELF 13 btf.Spec --> ELF 14 Map --> MapSpec --> ELF 15 Links --> Map & Program 16 ProgramSpec -.-> btf.Spec 17 MapSpec -.-> btf.Spec 18 subgraph Collection 19 Program & Map 20 end 21 subgraph CollectionSpec 22 ProgramSpec & MapSpec & btf.Spec 23 end 24 ``` 25 26 ELF 27 --- 28 29 BPF is usually produced by using Clang to compile a subset of C. Clang outputs 30 an ELF file which contains program byte code (aka BPF), but also metadata for 31 maps used by the program. The metadata follows the conventions set by libbpf 32 shipped with the kernel. Certain ELF sections have special meaning 33 and contain structures defined by libbpf. Newer versions of clang emit 34 additional metadata in BPF Type Format. 35 36 The library aims to be compatible with libbpf so that moving from a C toolchain 37 to a Go one creates little friction. To that end, the ELF reader 38 is tested against the Linux selftests and avoids introducing custom behaviour 39 if possible. 40 41 The output of the ELF reader is a `CollectionSpec` which encodes 42 all of the information contained in the ELF in a form that is easy to work with 43 in Go. The returned `CollectionSpec` should be deterministic: reading the same ELF 44 file on different systems must produce the same output. 45 As a corollary, any changes that depend on the runtime environment like the 46 current kernel version must happen when creating [Objects](#objects). 47 48 Specifications 49 --- 50 51 `CollectionSpec` is a very simple container for `ProgramSpec`, `MapSpec` and 52 `btf.Spec`. Avoid adding functionality to it if possible. 53 54 `ProgramSpec` and `MapSpec` are blueprints for in-kernel 55 objects and contain everything necessary to execute the relevant `bpf(2)` 56 syscalls. They refer to `btf.Spec` for type information such as `Map` key and 57 value types. 58 59 The {{ godoc("asm") }} package provides an assembler that can be used to generate 60 `ProgramSpec` on the fly. 61 62 Objects 63 --- 64 65 `Program` and `Map` are the result of loading specifications into the kernel. 66 Features that depend on knowledge of the current system (e.g kernel version) 67 are implemented at this point. 68 69 Sometimes loading a spec will fail because the kernel is too old, or a feature is not 70 enabled. There are multiple ways the library deals with that: 71 72 * Fallback: older kernels don't allow naming programs and maps. The library 73 automatically detects support for names, and omits them during load if 74 necessary. This works since name is primarily a debug aid. 75 76 * Sentinel error: sometimes it's possible to detect that a feature isn't available. 77 In that case the library will return an error wrapping `ErrNotSupported`. 78 This is also useful to skip tests that can't run on the current kernel. 79 80 Once program and map objects are loaded they expose the kernel's low-level API, 81 e.g. `NextKey`. Often this API is awkward to use in Go, so there are safer 82 wrappers on top of the low-level API, like `MapIterator`. The low-level API is 83 useful when our higher-level API doesn't support a particular use case. 84 85 Links 86 --- 87 88 Programs can be attached to many different points in the kernel and newer BPF hooks 89 tend to use bpf_link to do so. Older hooks unfortunately use a combination of 90 syscalls, netlink messages, etc. Adding support for a new link type should not 91 pull in large dependencies like netlink, so XDP programs or tracepoints are 92 out of scope. 93 94 Each bpf_link_type has one corresponding Go type, e.g. `link.tracing` corresponds 95 to BPF_LINK_TRACING. In general, these types should be unexported as long as they 96 don't export methods outside of the Link interface. Each Go type may have multiple 97 exported constructors. For example `AttachTracing` and `AttachLSM` create a 98 tracing link, but are distinct functions since they may require different arguments.