0

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 Answers2

1

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.

pchaigno
  • 11,313
  • 2
  • 29
  • 54
  • I totally agree. But let me explain further more: In BPF program I assign element with key=1 to value=5, when I examine that key on user side it is still zero. This behavior is vice versa. Somehow values are not propagated properly? I am confused because the results are as expected when used with **BPF_PROG_TYPE_SOCKET_FILTER** type of program. – Kenan Hadžihasanović Mar 09 '20 at 11:55
0

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.