BPF: `bpf_obj_get_info_by_fd` завершается с ошибкой« Неверный аргумент » - PullRequest
0 голосов
/ 12 марта 2020

Я пытаюсь получить fd BPF_MAP_TYPE_XSKMAP в моей программе пользовательского пространства.

Это код:

ret = bpf_get_link_xdp_id(cfg->ifindex, &cfg->prog_id, cfg->xdp_flags);
if (ret) {
    fprintf(stderr, "`bpf_get_link_xdp_id` returned error: %s\n", strerror(errno));
    exit(-ret);
}

cfg->prog_fd = bpf_prog_get_fd_by_id(cfg->prog_id);
if(cfg->prog_fd < 0) {
    fprintf(stderr, "Failed to obtain prog_fd: %s\n", strerror(errno));
    exit(1);
}

struct bpf_prog_info prog_info;
uint32_t prog_info_len = sizeof(struct bpf_prog_info);
uint32_t map_info_len = sizeof(struct bpf_map_info);
if(bpf_obj_get_info_by_fd(cfg->prog_fd, &prog_info, &prog_info_len) == 0) {

    const uint32_t amnt_of_maps = prog_info.nr_map_ids;
    uint32_t *map_ids = (uint32_t*)malloc(sizeof(uint32_t) * prog_info.nr_map_ids);

    memset(&prog_info, 0, prog_info_len);
    prog_info.nr_map_ids = amnt_of_maps;
    prog_info.map_ids = (uint64_t)(unsigned long)map_ids;

    if(bpf_obj_get_info_by_fd(cfg->prog_fd, &prog_info, &prog_info_len) == 0) {

        for(uint32_t i = 0; i < prog_info.nr_map_ids; i++) {

            const int map_fd = bpf_map_get_fd_by_id(map_ids[i]);

            if(map_fd >= 0) {
                struct bpf_map_info map_info;
                if(bpf_obj_get_info_by_fd(map_fd, &map_info, &map_info_len) == 0) {
                    if(strcmp(map_info.name, "xsks_map") == 0) {
                        cfg->xsks_map_fd = map_fd;
                        printf("Got fd of xsks_map!\n");
                        break;
                    }
                } else {
                    close(map_fd);
                }
            } else {
                fprintf(stderr, "Failed to obtain map_fd for id %d: %s\n", i, strerror(errno));
            }

        }
    } else {
        fprintf(stderr, "Failed to obtain prog_info 2: %s\n", strerror(errno));
    }
} else {
    fprintf(stderr, "Failed to obtain prog_info 1: %s\n", strerror(errno));
}

Но, к сожалению, я получаю ошибку при вызове bpf_obj_get_info_by_fd(cfg->prog_fd, &prog_info, &prog_info_len): Failed to obtain prog_info 1: Invalid argument.

Не знаю, так ли это, потому что XDP-программа загружается из другого процесса? Должен ли тот же процесс получать информацию о программе, которая также загружала программу AF-XDP?

Редактировать: единственное, что я изменил в своей программе пользовательского пространства, это заполнение BPF_MAP_TYPE_HASH через bpf_map_update_elem ( там есть записи, отмеченные bpftool map dump id <id>) и для использования bpf_map_lookup_elem в моей XDP-программе (та же карта ha sh).

И вдруг ошибка меняется на: Failed to obtain prog_info 1: Bad address

1 Ответ

1 голос
/ 13 марта 2020

Есть комментарий в функции из кода ядра , вызываемой при попытке получить информацию о вашей программе, в которой говорится:

/ * Если нам передали большая структура, чем мы знаем, гарантирует, что все неизвестные биты равны 0 - т.е. новое пользовательское пространство не зависит от каких-либо расширений ядра, о которых мы пока не знаем. [...] * /

Я думаю, это то, что вы ударили в вашем случае. Ваша версия libbpf может использовать некоторые атрибуты в struct bpf_prog_info, о которых ядро ​​не знает.

Чтобы убедиться, что ядро ​​это принимает, просто попробуйте инициализировать нулем вашу структуру :

struct bpf_prog_info prog_info = {};
...