Skip to content

Latest commit

 

History

History

examples

Examples

There are examples using wasm-bpf.

Each directory contains one example.

  • go-** stands for examples that userpsace program was written in Go.
  • rust-** denotes that the userspace program is written in Rust.
  • Others means that the userspace program is written in C/C++

Go examples requires tinygo, rust examples requires cargo.

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 ./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.

$ 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 also 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.