redbpf

Crates.ioredbpf
lib.rsredbpf
version2.3.0
sourcesrc
created_at2018-09-25 10:08:18.703283
updated_at2022-01-09 12:22:23.036743
descriptioneBPF build and userspace runtime library
homepagehttps://foniod.org
repositoryhttps://github.com/foniod/redbpf
max_upload_size
id86449
size271,826
Alessandro Decina (alessandrod)

documentation

https://docs.rs/redbpf/

README

RedBPF

LICENSE element

A Rust eBPF toolchain.

Overview

The redbpf project is a collection of tools and libraries to build eBPF programs using Rust. It includes:

  • redbpf - a user space library that can be used to load eBPF programs or access eBPF maps.

  • redbpf-probes - an idiomatic Rust API to write eBPF programs that can be loaded by the linux kernel

  • redbpf-macros - companion crate to redbpf-probes which provides convenient procedural macros useful when writing eBPF programs. For example, #[map] for defining a map, #[kprobe] for defining a BPF program that can be attached to kernel functions.

  • cargo-bpf - a cargo subcommand for creating, building and debugging eBPF programs

Features

  • Allows users to write both BPF programs and userspace programs in Rust
  • Offers many BPF map types
    1. HashMap, PerCpuHashMap, LruHashMap, LruPerCpuHashMap, Array, PerCpuArray, PerfMap, TcHashMap, StackTrace, ProgramArray, SockMap
  • Offers several BPF program types
    1. KProbe, KRetProbe, UProbe, URetProbe, SocketFilter, XDP, StreamParser, StreamVerdict, TaskIter, SkLookup
  • Provides attribute macros that define various kind of BPF programs and BPF maps in a declarative way.
    1. #[kprobe], #[kretprobe], #[uprobe], #[uretprobe], #[xdp], #[tc_action], #[socket_filter], #[stream_parser], #[stream_verdict], #[task_iter]
    2. #[map]
  • Can generate Rust bindings from the Linux kernel headers or from the BTF of vmlinux
  • Provides API for both BPF programs and userspace programs to help users write Rust idiomatic code
  • Supports BTF for maps
  • Supports pinning maps and loading maps from pins
  • Supports BPF iterator for task
  • Enables users to write BPF programs for tc action and RedBPF compiles the programs into the ELF object file that is compatible with tc command
  • Provides wrappers of BPF helper functions
  • Offers asynchronous stream of perf events for userspace programs
  • Supports multiple versions of LLVM
  • Shows BPF verifier logs when loading BPF programs, BPF maps or BTF fails
  • Has several example programs that are separated into two parts: BPF programs and userspace programs

Requirements

In order to use redBPF, you need

  • one of LLVM 13, LLVM 12 or LLVM 11 installed in the system
  • either the Linux kernel headers or vmlinux, you want to target

Currently LLVM 12 is used as a default version when compiling BPF programs, but you can specify other LLVM versions as follows:

  • cargo build --no-default-features --features llvm13
  • cargo build --no-default-features --features llvm11

If you want to install cargo-bpf with other LLVM versions then you can try this command:

  • cargo install cargo-bpf --no-default-features --features=llvm13,command-line
  • cargo install cargo-bpf --no-default-features --features=llvm1,command-line

Valid combinations of rust and LLVM versions

rustc uses its own version of LLVM. But RedBPF also requires LLVM installed in the system. In order to compile BPF programs, RedBPF makes use of rustc to emit bitcode first and then parses and optimizes the bitcode by calling LLVM API directly. Thus, two versions of LLVM are used while compiling BPF programs.

  • the version of LLVM that rustc depends on
  • the version of LLVM which is installed in system

Two versions should match.

First RedBPF executes rustc to emit bitcode and second it calls LLVM API to handle the resulting bitcode. Normally LLVM is likely to support backward compatibility for intermediate representation. Thus, it is okay to use rustc that depends on the LLVM version that is equal to or less than system LLVM.

Rust version LLVM version of the Rust Valid system LLVM version
1.56 ~ LLVM 13 LLVM 13
1.52 ~ 1.55 LLVM 12 LLVM 13, LLVM 12
1.48 ~ 1.51 LLVM 11 LLVM 13, LLVM 12, LLVM 11
  • The minimum rust version for compiling redbpf is Rust 1.48

Linux kernel

The minimum kernel version supported is 4.19. Kernel headers are discovered automatically, or you can use the KERNEL_SOURCE environment variable to point to a specific location. Building against a linux source tree is supported as long as you run make prepare first.

NOTE for compiling BPF programs inside containers.
You need to specify KERNEL_SOURCE or KERNEL_VERSION environment variables that indicate kernel headers. The headers should be found inside the container. For example, inside the Ubuntu 21.04 container that contains the Linux 5.11.0-25-generic kernel headers, you should specify KERNEL_VERSION environment variable as follows:

# KERNEL_VERSION=5.11.0-25-generic cargo build --examples

If your container has vmlinux, you can specify it instead of the Linux kernel headers.

# REDBPF_VMLINUX=/boot/vmlinux cargo build --examples

See, build-test.sh for more information.

Installing dependencies on Debian based distributions

On Debian, Ubuntu and derivatives you can install the dependencies running:

sudo apt-get -y install build-essential zlib1g-dev \
		llvm-12-dev libclang-12-dev linux-headers-$(uname -r) \
		libelf-dev

If your distribution doesn't have LLVM 12, you can add the official LLVM APT repository to your sources.list. Or simply run the script that you can download at the llvm.sh. Note that this script is only for Debian or Ubuntu.

Installing dependencies on RPM based distributions

First ensure that your distro includes LLVM 12:

yum info llvm-devel | grep Version
Version      : 12.0.0

If you don't have vesion 12, you can get it from the Fedora 34 repository.

Then install the dependencies running:

yum install clang llvm-devel zlib-devel kernel-devel

Build images

You can refer to various Dockerfiles that contain minimal necessary packages to build RedBPF properly: Dockerfiles for RedBPF

If you want docker images that are prepared to build foniod then refer to this: Dockerfiles for foniod

Getting started

The easiest way to get started is reading a basic tutorial.

You can find several examples in this directory. All example programs are splitted into two parts: example-probes and example-userspace. example-probes contains BPF programs that execute in kernel context. example-userspace includes userspace programs that load BPF programs into kernel space and communicate with BPF programs through BPF maps.

Also see documentation of cargo-bpf. It provides a CLI tool for compiling BPF programs easily.

redbpf-tools is a cargo-bpf generated crate that includes simple examples you can use to understand how to structure your programs.

Finally, check the foniod project that includes more advanced, concrete production ready examples of redbpf programs.

Building from source

After cloning the repository run:

git submodule sync
git submodule update --init

Install the dependencies as documented above, then run cargo build as usual.

License

This repository contains code from other software in the following directories, licensed under their own particular licenses:

  • bpf-sys/libbpf: LGPL2 + BSD-2

Where '+' means they are dual licensed.

RedBPF and its components, unless otherwise stated, are licensed under either of

at your option.

Contribution

This project is for everyone. We ask that our users and contributors take a few minutes to review our code of conduct.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

For further advice on getting started, please consult the Contributor's Guide. Please note that all contributions MUST contain a Developer Certificate of Origin sign-off line.

Commit count: 727

cargo fmt