Menu

Tree [21eff2] main /
 History

HTTPS access


File Date Author Commit
 .github 2023-02-12 云微 云微 [538110] Build as library and enable test on examples (#12)
 cmake 2023-02-05 Littlefisher619 Littlefisher619 [912422] Add comments and rename bpf-api to wasm-bpf
 examples 2023-02-14 yunwei37 yunwei37 [21eff2] examples: fix set runqlat param
 include 2023-02-07 dexian dexian [205eac] support attach to cgroup and add sockops example
 src 2023-02-12 云微 云微 [538110] Build as library and enable test on examples (#12)
 test 2023-02-12 云微 云微 [538110] Build as library and enable test on examples (#12)
 third_party 2023-02-14 yunwei37 yunwei37 [30e8d5] libbpf-wasm: fix rodata variables setting
 wasm-sdk 2023-02-14 yunwei37 yunwei37 [30e8d5] libbpf-wasm: fix rodata variables setting
 .clang-format 2023-02-04 Littlefisher619 Littlefisher619 [f360cc] add .clang-format
 .gitignore 2023-02-11 yunwei37 yunwei37 [3ea865] add gitignore for wasi-sdk
 .gitmodules 2023-02-04 Littlefisher619 Littlefisher619 [2ea787] update makefiles and build submodule
 CMakeLists.txt 2023-02-04 Littlefisher619 Littlefisher619 [34539d] fix compile in CI
 Dockerfile 2023-02-04 Littlefisher619 Littlefisher619 [d3b47c] init with old project
 LICENSE 2023-02-04 Littlefisher619 Littlefisher619 [7443f4] update license
 Makefile 2023-02-12 yunwei37 yunwei37 [dd50f3] move examples test to another file
 README.md 2023-02-14 yunwei37 yunwei37 [c527f5] doc: fix link to libbpf-wasm header
 README_zh.md 2023-02-14 yunwei37 yunwei37 [c527f5] doc: fix link to libbpf-wasm header

Read Me

📦 Wasm-bpf: Wasm library and toolchain for eBPF

Actions Status
CodeFactor

中文文档

Wasm-bpf is a WebAssembly eBPF library, toolchain and runtime powered by CO-RE(Compile Once – Run Everywhere) libbpf and WAMR. It can help you build almost every eBPF programs or usecases to Wasm.

Features

  • General purpose: provide most abilities from eBPF to Wasm, polling from the ring buffer or perf buffer, bidirectional communications between kernel eBPF and userspace Wasm using maps, dynamically loading, attaching or detaching, etc. Supports a large number of eBPF program types and map types.
  • High performance: No serialization overhead for complex data types, using shared memory to avoid copy overhead between host and Wasm.
  • Easy to use: provide a similar developing experience as the libbpf-bootstrap, auto generate the Wasm-eBPF skeleton headers and type definitions for bindings.
  • Ultralightweight: the sample runtime has only 1.5 MB in binary size. Compiled Wasm module would be only ~90K. With the same toolchain, you can easily build your own Wasm-eBPF runtime in any languages and platforms!

See the examples directory for examples of eBPF programs written in C, Rust and compiled to Wasm, covering the use cases from tracing, networking to security.

For tools to distribute Wasm-eBPF programs in OCI images, please refer to eunomia-bpf repo.

How it works

The wasm-bpf runtime require two parts: the host side(Outside the Wasm runtime) and the Wasm guest side(Inside the Wasm runtime).

  • host side: A simple runtime implementation example
  • see src and include directories, which would be a sample runtime built on the top of libbpf and WAMR.
  • You can easily build your own Wasm-eBPF runtime in any languages, any eBPF libraries and any Wasm runtimes with the same System interface.
  • wasm side: toolchains and libraries
  • a libbpf-wasm header only library to provide libbpf APIs for Wasm guest C/C++ code.
  • a bpftool tool to generate the Wasm-eBPF skeleton headers, and C struct definitions for passing data between the host and Wasm guest without serialization.
  • More languages support(Rust, Go, etc) is on the way.

For details compile process, please refer to the examples/bootstrap/README.md. The figure below shows the overall interaction between the eBPF and Wasm runtimes:

wasi-bpf

A Wasm module could load and control multiple eBPF programs at the same time, and can call another Wasm module written in other languages to process the data or control with the component model.

We have proposed a new WASI issue wasi-bpf.

🔨 Examples

See the examples directory for examples of eBPF programs written in C, Rust and compiled to WASM.

C example: Bootstrap

bootstrap is an example of a simple (but realistic) BPF application. It
tracks process starts (exec() family of syscalls, to be precise) and exits
and emits data about filename, PID and parent PID, as well as exit status and
duration of the process life. With -d <min-duration-ms> you can specify
minimum duration of the process to log. In such mode process start
(technically, exec()) events are not output (see example output below).

bootstrap was created in the similar spirit as
libbpf-tools from
BCC package, but is designed to be more stand-alone and with simpler Makefile
to simplify adoption to user's particular needs. It demonstrates the use of
typical BPF features:

  • cooperating BPF programs (tracepoint handlers for process exec and exit
    events, in this particular case);
  • BPF map for maintaining the state;
  • BPF ring buffer for sending data to user-space;
  • global variables for application behavior parameterization.
  • it utilizes BPF CO-RE and vmlinux.h to read extra process information from
    kernel's struct task_struct.

Here's an example output:

$ sudo sudo ./wasm-bpf bootstrap.wasm -h
BPF bootstrap demo application.

It traces process start and exits and shows associated 
information (filename, process duration, PID and PPID, etc).

USAGE: ./bootstrap [-d <min-duration-ms>] -v
$ sudo ./wasm-bpf bootstrap.wasm
TIME     EVENT COMM             PID     PPID    FILENAME/EXIT CODE
18:57:58 EXEC  sed              74911   74910   /usr/bin/sed
18:57:58 EXIT  sed              74911   74910   [0] (2ms)
18:57:58 EXIT  cat              74912   74910   [0] (0ms)
18:57:58 EXEC  cat              74913   74910   /usr/bin/cat
18:57:59 EXIT  cat              74913   74910   [0] (0ms)
18:57:59 EXEC  cat              74914   74910   /usr/bin/cat
18:57:59 EXIT  cat              74914   74910   [0] (0ms)
18:57:59 EXEC  cat              74915   74910   /usr/bin/cat
18:57:59 EXIT  cat              74915   74910   [0] (1ms)
18:57:59 EXEC  sleep            74916   74910   /usr/bin/sleep

See examples/bootstrap for more details.

Rust example: Bootstrap

similar to C bootstrap, but written in Rust.

See examples/rust-bootstrap for more details.

C example: runqlat

This program summarizes scheduler run queue latency as a histogram, showing
how long tasks spent waiting their turn to run on-CPU.

This program summarizes scheduler run queue latency as a histogram, showing
how long tasks spent waiting their turn to run on-CPU.

$ sudo ./wasm-bpf runqlat.wasm -h
Summarize run queue (scheduler) latency as a histogram.

USAGE: runqlat [--help] [interval] [count]

EXAMPLES:
    runqlat         # summarize run queue latency as a histogram
    runqlat 1 10    # print 1 second summaries, 10 times
$ sudo ./wasm-bpf runqlat.wasm 1

Tracing run queue latency... Hit Ctrl-C to end.

     usecs               : count    distribution
         0 -> 1          : 72       |*****************************           |
         2 -> 3          : 93       |*************************************   |
         4 -> 7          : 98       |****************************************|
         8 -> 15         : 96       |*************************************** |
        16 -> 31         : 38       |***************                         |
        32 -> 63         : 4        |*                                       |
        64 -> 127        : 5        |**                                      |
       128 -> 255        : 6        |**                                      |
       256 -> 511        : 0        |                                        |
       512 -> 1023       : 0        |                                        |
      1024 -> 2047       : 0        |                                        |
      2048 -> 4095       : 1        |                                        |

runqlat is alse an example of a simple (but realistic) BPF application. It
would show a more complex example of BPF program, which contains more than
one file, and directly access the kernel maps from the user space instead of
polling the kernel ring buffer.

The runtime would use shared memory to access the kernel maps, and the kernel
would update the maps in the shared memory, so the wasm code can access the
eBPF maps directly, without any serialization or copy overhead between userspace
host and Wasm runtime.

You can use the bpf_map_update_elem API to update the kernel maps from the user
space, for example:

        cg_map_fd = bpf_map__fd(obj->maps.cgroup_map);
        ....
        bpf_map_update_elem(cg_map_fd, &idx, &cgfd, BPF_ANY);

So the kernel eBPF can be config by wasm side or recieve the messages from
userspace wasm runtime when it is running.

See examples/runqlat for more details.

C example: lsm-rmdir

lsm-rmdir hook in dir remove and check the permission to remove a directory. If dir
name with can_not_rm will raise Operation not permitted.

See examples/lsm for more details.

C example: Socket filter

sockfilter is an example of monitoring packet and dealing with __sk_buff structure.

See examples/sockfilter for more details.

C example: Sockops

sockops add the pid int tcp option in syn packet.

See examples/sockops for more details.

build the runtime

The dependencies are libbpf and wasm-micro-runtime only, they are
registered as git submodules.

git submodule update --init --recursive

Install Dependencies

You will need clang, libelf and zlib to build the examples,
package names may vary across distros.

On Ubuntu/Debian, you need:

apt install clang libelf1 libelf-dev zlib1g-dev

On CentOS/Fedora, you need:

dnf install clang elfutils-libelf elfutils-libelf-devel zlib-devel

Build runtime as a executable tool

Run make to build the runtime, which will be placed in the build
directory. cmake is required to build the runtime.

make build

Build runtime as a library

make build-lib

You may refer to CI for more details on how
to build and run the examples.

LICENSE

MIT

MongoDB Logo MongoDB