Crate libbpf_rs

Source
Expand description

§libbpf-rs

libbpf-rs is a safe, idiomatic, and opinionated wrapper around libbpf.

libbpf-rs, together with libbpf-cargo (libbpf cargo plugin) allow you to write Compile-Once-Run-Everywhere (CO-RE) eBPF programs. Note this document uses “eBPF” and “BPF” interchangeably.

More information about CO-RE is available here.

§High level workflow

  1. Create new rust project (via cargo new or similar) at path $PROJ_PATH
  2. Create directory $PROJ_PATH/src/bpf
  3. Write CO-RE bpf code in $PROJ_PATH/src/bpf/${MYFILE}.bpf.c, where $MYFILE may be any valid filename. Note the .bpf.c extension is required.
  4. Create a build script that builds and generates a skeleton module using libbpf_cargo::SkeletonBuilder
  5. Write your userspace code by importing and using the generated module. Import the module by using the path attribute. Your userspace code goes in $PROJ_PATH/src/ as it would in a normal rust project.
  6. Continue regular rust workflow (ie cargo build, cargo run, etc)

§Alternate workflow

While using the skeleton is recommended, it is also possible to directly use libbpf-rs.

  1. Follow steps 1-3 of “High level workflow”
  2. Generate a BPF object file. Options include manually invoking clang, creating a build script to invoke clang, or using libbpf-cargo cargo plugins.
  3. Write your userspace code in $PROJ_PATH/src/ as you would a normal rust project and point libbpf-rs at your BPF object file
  4. Continue regular rust workflow (ie cargo build, cargo run, etc)

§Design

libbpf-rs models various “phases”:

               from_*()        load()
                 |               |
                 v               v
   ObjectBuilder ->  OpenObject  -> Object
                         ^            ^
                         |            |
             <pre-load modifications> |
                                      |
                           <post-load interactions>

The entry point into libbpf-rs is ObjectBuilder. ObjectBuilder helps open the BPF object file. After the object file is opened, you are returned an OpenObject where you can perform all your pre-load operations. Pre-load means before any BPF maps are created or BPF programs are loaded and verified by the kernel. Finally, after the BPF object is loaded, you are returned an Object instance where you can read/write to BPF maps, attach BPF programs to hooks, etc.

You must keep the Object alive the entire duration you interact with anything inside the BPF object it represents. This is further documented in Object documentation.

§Example

This is probably the best way to understand how libbpf-rs and libbpf-cargo work together.

See example here.

Re-exports§

Modules§

  • Parse and introspect btf information, from files or loaded objects.
  • Query the host about BPF
  • Skeleton related definitions.

Macros§

Structs§

Enums§

Constants§

Traits§

  • A trait implemented for types that are thin wrappers around libbpf types.
  • A trait providing ergonomic chaining capabilities to Error.
  • A trait representing core functionality common to fully initialized maps.

Functions§

  • Return the current print callback and level.
  • Get the number of CPUs in the system, e.g., to interact with per-cpu maps.
  • Set a callback to receive log messages from libbpf, instead of printing them to stderr.

Type Aliases§