-
Notifications
You must be signed in to change notification settings - Fork 714
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Timo Beckers <[email protected]>
- Loading branch information
Showing
43 changed files
with
3,486 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Python | ||
__pycache__ | ||
|
||
# Build output | ||
build/ | ||
site/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
build: pipenv | ||
@# Run a production build of the documentation. Strict mode makes warnings fatal. | ||
pipenv run mkdocs build --strict | ||
|
||
@# Build main packages, discarding build output. | ||
go build -v ./... | ||
|
||
@# build _test.go files containing Doc* functions and skip all tests. | ||
go test -c -o /dev/null ./... >/dev/null | ||
|
||
preview: pipenv | ||
pipenv run mkdocs serve | ||
|
||
shell: pipenv | ||
pipenv shell | ||
|
||
pipenv: | ||
ifeq (, $(shell command -v pipenv 2> /dev/null)) | ||
$(error "pipenv is not installed, exiting..") | ||
endif | ||
|
||
.PHONY: pipenv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[[source]] | ||
url = "https://pypi.org/simple" | ||
verify_ssl = true | ||
name = "pypi" | ||
|
||
[packages] | ||
mkdocs = "*" | ||
pymdown-extensions = "*" | ||
mkdocs-material = "9.3.2" | ||
mkdocs-macros-plugin = "*" | ||
mkdocs-git-revision-date-localized-plugin = "*" | ||
mkdocs-git-authors-plugin = "*" | ||
|
||
[dev-packages] | ||
|
||
# Whatever Netlify's Ubuntu version uses. | ||
[requires] | ||
python_version = "3.8" |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# epbf-go documentation | ||
|
||
The documentation project uses Pipenv to manage its dependencies, which will | ||
automatically create a Python virtualenv when invoked from this subdirectory. | ||
Follow your distribution's documentation for installing `pipenv`. You may also | ||
need `pyenv` to install a different Python version if your distribution doesn't | ||
provide the version specified in the `Pipfile`. | ||
|
||
Host a live preview of the documentation at http://127.0.0.1:8000: | ||
|
||
`make preview` | ||
|
||
Build the documentation, output to the site/ directory. This is a self-contained | ||
production copy that can be uploaded to hosting. | ||
|
||
`make build` | ||
|
||
To enter the virtualenv with all the documentation's Python dependencies | ||
installed: | ||
|
||
`make shell` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# About {{ proj }} | ||
|
||
The project was initially created in 2017 as | ||
[`newtools/ebpf`](https://github.com/newtools/ebpf). It quickly gained traction | ||
within the Go community, especially for projects that couldn't or wouldn't build | ||
upon the CGo-based BCC bindings at the time (`gobpf`). | ||
|
||
Since then, it's been widely adopted by hundreds of open-source projects, large | ||
industry players, as well as startups building their businesses on top of eBPF. | ||
It continues to evolve thanks to its thriving community and close collaboration | ||
with the upstream Linux project. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
!!! incomplete | ||
Give an overview of bpf2go's features and flags. Note that [Getting | ||
Started](../guides/getting-started.md) already acts as an introduction. | ||
|
||
Might not warrant its own section, could move to 'Concepts'. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
!!! incomplete | ||
Document package `btf/` here. Give a small overview of its API, how to | ||
interact with user BTF and kernel BTF and what the difference is between | ||
the two and what their purpose is within the bigger picture. | ||
|
||
Might not warrant its own section, could move to 'Concepts'. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
!!! incomplete | ||
On this page, we want to document package `features/`, a bit of its | ||
background, and how it can be used. Comparison to `bpftool feature probe` | ||
would be useful. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
# Loading Objects | ||
|
||
{{ proj }} 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. | ||
|
||
```mermaid | ||
graph LR | ||
ELF --> ProgramSpec --> Program | ||
ELF --> Types | ||
ELF --> MapSpec --> Map | ||
Map & Program --> Links | ||
subgraph Collection | ||
Program & Map | ||
end | ||
subgraph CollectionSpec | ||
ProgramSpec & MapSpec & Types | ||
end | ||
``` | ||
|
||
## {{ godoc('CollectionSpec') }} | ||
|
||
A CollectionSpec represents eBPF objects extracted from an ELF, and can be | ||
obtained by calling {{ godoc('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. | ||
|
||
=== ":simple-go: Go" | ||
{{ go_example('DocLoadCollectionSpec', title='Parse ELF and inspect its CollectionSpec') | indent(4) }} | ||
|
||
!!! warning "" | ||
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. | ||
|
||
=== ":ebee-color: eBPF C" | ||
{{ c_example('DocMyMapProgram', title='Declare a minimal map and a program') | indent(4) }} | ||
|
||
!!! tip "" | ||
See [Section Naming](section-naming.md) to learn about the use of the | ||
`SEC()` macro in the example above. | ||
|
||
## {{ godoc('NewCollection') }} | ||
|
||
After parsing the ELF into a CollectionSpec, it can be loaded into the kernel | ||
using {{ godoc('NewCollection') }}, resulting in a {{ godoc('Collection') }}. | ||
|
||
{{ go_example('DocNewCollection') }} | ||
|
||
!!! note "" | ||
{{ godoc('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](object-lifecycle.md) to gain a better understanding of how {{ | ||
proj }} manages its resources and for best practices handling Maps and | ||
Programs. | ||
|
||
## {{ godoc('CollectionSpec.LoadAndAssign', short=True) }} | ||
|
||
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 `#!go 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 `#!go Close()` method to make cleanup | ||
easier. | ||
|
||
{{ go_example('DocLoadAndAssignObjs', title='Declare a custom struct myObjs') }} | ||
|
||
!!! note "" | ||
Use [bpf2go](../bpf2go/index.md) 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`. | ||
|
||
{{ go_example('DocLoadAndAssign', title='Pass a custom struct to LoadAndAssign') }} | ||
|
||
!!! warning "" | ||
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 {{ | ||
godoc('CollectionSpec.Types') }}. Note that this field will be `nil` if the ELF | ||
was built without BTF. | ||
|
||
{{ go_example('DocBTFTypeByName') }} | ||
|
||
!!! note "" | ||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
!!! info "" | ||
This is an advanced topic and does not need to be fully understood in order | ||
to get started writing useful tools. | ||
|
||
If you find yourself debugging unexpectedly-detached programs, resource | ||
leaks, or you want to gain a deeper understanding of how eBPF objects are | ||
managed by {{ proj }}, this page should prove helpful. | ||
|
||
## File Descriptors and Go | ||
|
||
Interacting with eBPF objects from user space is done using file descriptors. | ||
Counter-intuitively, 'file' descriptors are used as references to many types of | ||
kernel resources in modern Linux, not just files. In {{ proj }}, {{ godoc('Map') | ||
}}, {{ godoc('Program') }} and {{ godoc('link/Link') }} are all modeled around | ||
these underlying file descriptors. | ||
|
||
Go, being a garbage-collected language, automatically manages the lifecycle of | ||
Go objects. Keeping in line with the standard library's `os.File` and friends, | ||
eBPF resources in {{ proj }} were designed in a way so their underlying file | ||
descriptors are closed when their Go objects are garbage collected. This | ||
generally prevents runaway resource leaks, but is not without its drawbacks. | ||
|
||
This has subtle but important repercussions for BPF, since this means the Go | ||
runtime will call `Close()` on an object's underlying file descriptor if the | ||
object is no longer reachable by the garbage collector. For example, this can | ||
happen if an object is created in a function, but is not returned to the caller. | ||
One type of map, {{ godoc('ProgramArray') }}, is particularly sensitive to this. | ||
More about that in [Program Arrays](#program-arrays). | ||
|
||
## Extending Object Lifetime | ||
|
||
### Pinning | ||
|
||
Aside from file descriptors, BPF provides another method of creating references | ||
to eBPF objects: pinning. This is the concept of associating a file on a virtual | ||
file system (the BPF File System, bpffs for short) with a BPF resource like a | ||
Map, Program or Link. Pins can be organized into arbitrary directory structures, | ||
just like on any other file system. | ||
|
||
When the Go process exits, the pin will maintain a reference to the object, | ||
preventing it from being automatically destroyed. In this scenario, removing the | ||
pin using plain `rm` will remove the last reference, causing the kernel to | ||
destroy the object. If you're holding an active object in Go, you can also call | ||
{{ godoc('Map.Unpin') }}, {{ godoc('Program.Unpin') }} or {{ | ||
godoc('link/Link.Unpin') }} if the object was previously pinned. | ||
|
||
!!! warning | ||
Pins do **not** persist through a reboot! | ||
|
||
A common use case for pinning is sharing eBPF objects between processes. For | ||
example, one could create a Map from Go, pin it, and inspect it using `bpftool | ||
map dump pinned /sys/fs/bpf/my_map`. | ||
|
||
### Attaching | ||
|
||
Attaching a Program to a hook acts as a reference to a Program, since the kernel | ||
needs to be able to execute the program's instructions at any point. More on | ||
that in [the section on attaching programs](../programs/attaching.md). | ||
|
||
For legacy reasons, some {{ godoc('link/Link') }} types don't support pinning. | ||
It is generally safe to assume these links will persist beyond the lifetime of | ||
the Go application. | ||
|
||
## :warning: Program Arrays | ||
|
||
A {{ godoc('ProgramArray') }} is a Map type that holds references to other | ||
Programs. This allows programs to 'tail call' into other programs, useful for | ||
splitting up long and complex programs. | ||
|
||
Program Arrays have a unique property: they allow cyclic dependencies to be | ||
created between the Program Array and a Program (e.g. allowing programs to call | ||
into themselves).To avoid ending up with a set of programs loaded into the | ||
kernel that cannot be freed, the kernel maintains a hard rule: **Program Arrays | ||
require at least one open file descriptor or bpffs pin**. | ||
|
||
!!! warning | ||
If all user space/bpffs references are gone, **any tail calls into the array | ||
will fail**, but the Map itself will remain loaded as long as there are | ||
programs that use it. This property, combined with interactions with Go's | ||
garbage collector previously described in [File Descriptors and | ||
Go](#file-descriptors-and-go), is a great source of bugs. | ||
|
||
A few tips to handle this problem correctly: | ||
|
||
- Use {{ godoc('CollectionSpec.LoadAndAssign') }}. It will refuse to load the | ||
CollectionSpec if doing so would result in a Program Array without a userspace | ||
reference. | ||
- Pin Program Arrays if execution of your eBPF code needs to continue past the | ||
lifetime of your Go application, e.g. for upgrades or short-lived CLI tools. | ||
- Retain references to the Map at all times in long-running applications. Note | ||
that `#!go defer m.Close()` makes Go retain a reference until the end of the | ||
current scope. |
Oops, something went wrong.