Search code examples
cebpf

Does libbpf provide an API that allows user space to pass a value to kernel space?


I am using libbpf and I am familiar with passing data using ebpf maps from kernel space to user space. However, how do I do it the other way around?

The closest API I find is below, but I think this is to pass value from kernel to user and it wasn't working for me when I tried it in user space.

int bpf_map_update_elem(int fd, const void *key, const void *value,
      __u64 flags)

Solution

  • bpf_map_update_elem is indeed the way to update the contents of a map from userspace. I have changed the sockex1_user.c program to demonstrate how you would use this function:

      
    // SPDX-License-Identifier: GPL-2.0
    #include <stdio.h>
    #include <assert.h>
    #include <linux/bpf.h>
    #include <bpf/bpf.h>
    #include <bpf/libbpf.h>
    #include "sock_example.h"
    #include <unistd.h>
    #include <arpa/inet.h>
    
    int main(int ac, char **argv)
    {
        struct bpf_object *obj;
        int map_fd, prog_fd;
        char filename[256];
        int i, sock, key;
        long value;
        FILE *f;
    
        snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
    
        if (bpf_prog_load(filename, BPF_PROG_TYPE_SOCKET_FILTER,
                    &obj, &prog_fd))
            return 1;
    
        map_fd = bpf_object__find_map_fd_by_name(obj, "my_map");
    
        sock = open_raw_sock("lo");
    
        assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,
                    sizeof(prog_fd)) == 0);
    
        key = 1;
        value = 123;
        bpf_map_update_elem(map_fd, &key, &value, BPF_ANY);
    
        return 0;
    }
    

    The BPF_ANY flag is the one you will use the most. It is defined here along with its meaning: https://elixir.bootlin.com/linux/v5.15.11/source/include/uapi/linux/bpf.h#L1169