libbpfgo example: using ebpf map in kernel and userspace

Preface

Document how to use the ebpf map in the libbpfgo program (see the references for the ebpf map itself).

Using ebpf map in ebpf programs

Define map

Let's look at defining an ebpf map, such as a map of type BPF_MAP_TYPE_HASH:

struct {
        __uint(type, BPF_MAP_TYPE_HASH);
        __type(key, u32);
        __type(value, struct event_t);
        __uint(max_entries, 1024 * 16);
} event_map SEC(".maps");

You can see that you mainly need to specify the fields type, key, value, and max_entries.

Operate on map

The map object can be manipulated in the ebpf program by using the following common helper functions:

void bpf_map_lookup_elem(map, void *key. ...) Perform a lookup in map for an entry associated to key.

event = bpf_map_lookup_elem(&event_map, &pid);
if (!event) {    // key not exist
    return 0;
}

void bpf_map_update_elem(map, void *key, ..., __u64 flags) Add or update the value of the entry associated to key in map with value.

/* File: include/uapi/linux/bpf.h */
/* flags for BPF_MAP_UPDATE_ELEM command */
#define BPF_ANY       0 /* create new element or update existing */
#define BPF_NOEXIST   1 /* create new element only if it didn't exist */
#define BPF_EXIST     2 /* only update existing element */

bpf_map_update_elem(&event_map, &pid, &event, BPF_ANY);

void bpf_map_delete_elem(map, void *key) Delete entry with key from map.

bpf_map_delete_elem(&event_map, &pid);

You can check out full sample codes on Github: https://github.com/mozillazg/hello-libbpfgo/tree/master/08-map-map-type-hash-kernel

pin map

The pin map is used to save the map to the local filesystem for persistence. In libbpf, it is automatically saved to the /sys/fs/bpf/<map_name> path.

The method for defining a pin map is simply to add a pinning field to the normal map:

struct {
        __uint(type, BPF_MAP_TYPE_HASH);
        __type(key, u32);
        __type(value, struct event_t);
        __uint(max_entries, 1024 * 16);
        __uint(pinning, LIBBPF_PIN_BY_NAME);  // <- pin
} event_map SEC(".maps");

You can check out full sample codes on Github: https://github.com/mozillazg/hello-libbpfgo/tree/master/11-map-pin

Using ebpf map in go program

The ebpf map defined in the ebpf program can be manipulated in the go program using libbpfgo.

Operate on map

Get the map object defined by bpfmap, err := bpfModule.GetMap("bpf_map"), and then you can do some common operations:

Update(key, value unsafe.Pointer) error Add or update the value of the entry associated to key in map with value and use BPF_ANY as flag.

key := 1
value := 233
keyPtr := unsafe.Pointer(&key)
valuePtr := unsafe.Pointer(&value)
bpfmap.Update(keyPtr, valuePtr)

GetValue(key unsafe.Pointer) ([]byte, error) Perform a lookup in map for an entry associated to key. Return an error when the key is not exist.

key := 1
keyPtr := unsafe.Pointer(&key)
data, err := bpfmap.GetValue(keyPtr)

DeleteKey(key unsafe.Pointer) error Delete entry with key from map. Return an error when the key is not exist.

key := 1
keyPtr := unsafe.Pointer(&key)
err := bpfmap.DeleteKey(keyPtr)

You can check out full codes on Github: https://github.com/mozillazg/hello-libbpfgo/tree/master/09-map-map-type-hash-userspace


Comments