Prerequisites
Rust toolchain
Install with rustup
.
cargo-generate
Install openssl
headers first.
Build bpf-linker with Nix’s LLVM
bpf-linker requires LLVM. It’s a good idea to use Nix, but it does not provide the prefix needed if installed with nix-env -i
.
error: No suitable version of LLVM was found system-wide or pointed
to by LLVM_SYS_180_PREFIX.
Consider using `llvmenv` to compile an appropriate copy of LLVM, and
refer to the llvm-sys documentation for more information.
llvm-sys: https://crates.io/crates/llvm-sys
llvmenv: https://crates.io/crates/llvmenv
It’s recommended to use nix-shell
for one-shot builds like this.
nix-shell -p llvm_18 -p libxml2 --run "cargo install bpf-linker --no-default-features"
Note that we used LLVM 18 here. The LLVM version used to build bpf-linker must match the LLVM version from the rust nightly toolchain defined in {{project-name}}-ebpf/rust-toolchain.toml
, which is used to build the eBPF program in your project. For LLVM 18, that means we should specify nightly-2024-07-31
or earlier in the toolchain config file.
Albeit not mentioned in bpf-linker’s README, libxml2 is also required.
Map Types
BPF_MAP_TYPE_LRU_HASH
provides general purpose hash map storage, and will automatically evict the least recently used entries when the hash table reaches capacity.
Pinning
From Map::pin()
:
When a map is pinned it will remain loaded until the corresponding file is deleted.
Log
Supported display hints: https://github.com/aya-rs/aya/blob/5397c1ca4b77cd27082e96aab9ab931631df7fa8/aya-log-parser/src/lib.rs#L55-L65
Reading Kconfig
Kernel configs are defined in Kconfig.*
files. For example, HZ
is defined in https://github.com/torvalds/linux/blob/b831f83e40a24f07c8dcba5be408d93beedc820f/kernel/Kconfig.hz.
There is a PR that implements the same extern
data support as libbpf, but only a sample C BPF program is provided. https://github.com/aya-rs/aya/pull/1017
Programs
sock_ops
NOTE
Until https://github.com/aya-rs/aya/issues/987 is implemented, killing the program does not unload the cgroup attachment automatically. However, a new attachment would replace the existing one.
If the program return code is not 1, __cgroup_bpf_run_filter_sock_ops
considers it a failure and returns -EPERM
.
__cgroup_bpf_run_filter_sock_ops
is lightly wrapped by the BPF_CGROUP_RUN_PROG_SOCK_OPS
macro, and its return value is processed by tcp_call_bpf()
.
-EPERM
is not 0
, so the returned value is -1 and considered a failure.
In case of success, sock_ops.reply
is returned to the caller, which is defined in linux/bpf.h
as below.
Contributing to Aya
If a PR touches public API, run the following command to update xtask/public-api/*.txt
files and commit them.
aya-ebpf.txt
can be regenerated on macOS, but others may require Linux.
error[E0432]: unresolved imports `libc::SYS_bpf`, `libc::SYS_perf_event_open`
--> aya/src/sys/mod.rs:19:19
|
19 | use libc::{pid_t, SYS_bpf, SYS_perf_event_open};
| ^^^^^^^ ^^^^^^^^^^^^^^^^^^^ no `SYS_perf_event_open` in the root
| |
| no `SYS_bpf` in the root
References
- https://aya-rs.dev/book/start/development/
- https://github.com/aya-rs/bpf-linker
- https://github.com/torvalds/linux/blob/5e0497553643b6c6acd16c389afb9cec210f4ea9/Documentation/bpf/map_hash.rst
- https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md#xdp (driver support for XDP in different kernel versions)
- https://github.com/aya-rs/aya/commit/7b71c7e1cd8d6948764d02afb0279151c6eae437#diff-db79c2f426cf46ef19a0265b625663ded9aaf593faa23ab5ca90007f38493e4dR313
- https://docs.rs/aya/0.12.0/aya/maps/enum.Map.html#method.pin (“proper” link for the above. docs.rs failed to build it.)
- https://github.com/torvalds/linux/blob/v5.17/kernel/bpf/cgroup.c#L1166-L1181
- https://github.com/torvalds/linux/blob/v5.17/include/uapi/linux/bpf.h#L5828-L5840