0
votes

I want to pass data between user/kernel side with BPF_PROG_TYPE_CGROUP_DEVICE

I have defined map as:

struct bpf_map_def SEC("maps") my_map = {
    .type = BPF_MAP_TYPE_ARRAY,
    .key_size = sizeof(int),
    .value_size = sizeof(int),
    .max_entries = 100,
};

When I execute following in BPF program:

int ret = bpf_map_update_elem(&my_map, &key, &value, BPF_ANY);
void *out = bpf_map_lookup_elem(&my_map, &key);

if (!out)
{
    // Never gets in here
}

My code never gets in if statement.

User side

On user side, I get correctly loaded reference to map with helper functions that provide me global arrays like struct bpf_map_data map_data[MAX_MAPS];.

I am able to fetch map name with:

printf("Name: %s \n", map_data[0].name); this means that I am able to correctly parse ELF file for SEC("maps") attribute, and when I try the following:

bpf_map_update_elem(map_data[0].fd, &key, &value, BPF_ANY); bpf_map_lookup_elem(map_data[0].fd, &key, &value);

Map data is updated and it is visible in user space.

Problem is that I can not see map defined in BPF program inside it self. I have tried with another type of program and it is behaving as expected.

Am I missing something with this type BPF_PROG_TYPE_CGROUP_DEVICE and data sharing with maps ?

2

2 Answers

1
votes

This is not related to BPF_PROG_TYPE_CGROUP_DEVICE, but to your use of BPF_MAP_TYPE_ARRAY. Values of BPF maps of type array are always initialized (to zero), so out can never be null. You can check the value pointed by out however; it will be zero by default.

You still need to check that the returned value is not null because the BPF verifier doesn't know it never will. So, if you don't check, it will complain.

0
votes

My map was not referenced properly with int map_fd[MAX_MAPS]; object. I will take a look for a reason, but fetching map with this call:

int map_fd = bpf_object__find_map_fd_by_name(obj, "my_map");

solved my issues.