Карты eBPF: как обновить с помощью bpftool из командной строки

Я использую tc для подключения моего eBPF (код C скомпилирован с использованием clang), к сети.

Я использую Карты eBPF для хранения некоторых данных.

В частности, я использую bpf_map_update_elem для обновления карт eBPF изнутри программы BPF, но я также хочу изменить содержимое карты из-за пределов программы. 1111]

Структура карты :

struct rt_val {
    int ifaceno;
    int macaddr[6];
};
union key_4 {
    __u32 b32[2];
    __u8 b8[8];
};
struct bpf_map_def SEC("maps") lpm_map_fwd = {
    .type = BPF_MAP_TYPE_LPM_TRIE,
    .key_size = 8,
    .value_size = sizeof(struct rt_val),
    .max_entries = 50,
    .map_flags = BPF_F_NO_PREALLOC,
};

Обновление карты и поиск в порядке.

Но я хочу динамически изменять содержимое карты eBPF извне выполнения программы.

Любые комментарии / предложения, касающиеся того же самого, будут высоко оценены !

Ресурсы:

Особенности системы:

  • uname -r: 4.15.0-47- универсальный
  • OS: Ubuntu 18
2
задан 18 April 2019 в 13:22

1 ответ

Вы уже нашли все инструменты, необходимые для обновления карт eBPF из пространства пользователя.

bpf()

Системный вызов bpf(cmd, attr, size) используется для выполнения обновления. cmd, переданный в качестве первого аргумента, указывает, какой тип операции вы хотите выполнить: в вашем случае это будет BPF_MAP_UPDATE_ELEM. Затем на странице руководства, на которую вы ссылаетесь, объясняется, как создать attr: в вашем случае (для обновления карты) это должно быть:

struct {    /* Used by BPF_MAP_*_ELEM and BPF_MAP_GET_NEXT_KEY commands */
        __u32         map_fd;
        __aligned_u64 key;
        union {
                __aligned_u64 value;
                /* [...] */
        };
        __u64         flags;
};

То есть вы должны построить union bpf_attr и передать ему дескриптор файла. на карту - ключ записи, которую вы хотите обновить, новое значение для этого ключа и, возможно, некоторые флаги.

Дескриптор файла для карты можно получить:

  • из пути в виртуальной файловой системе BPF, если карта была предварительно закреплена,
  • из идентификатора карта, с другим вызовом системного вызова bpf(), используя команду BPF_MAP_GET_FD_BY_ID,
  • (или как возвращаемое значение из вызова к bpf(), который создал карту, но не в этом случае вы использовали tc для загрузки программы).

Обратите внимание, что libbpf ( поставляется с ядром или , отраженным на GitHub ), предоставляет оболочки вокруг системного вызова bpf() и может упростить задачу.

bpftool

На практике вам не нужно переопределять все это. Как вы упомянули в заголовке, bpftool позволяет обновлять карты из командной строки, не переопределяя весь процесс.

Получить bpftool

На момент написания этой статьи bpftool не был упакован для Debian / Ubuntu, что означает, что вы должны собрать его из исходного кода. Он поставляется вместе с ядром, поэтому для его загрузки требуется время, но сборка на самом деле очень проста:

 $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
 $ cd linux
 $ cd tools/bpf/bpftool
 $ make
(# make install)
(# make doc doc-install)

В качестве альтернативы на этой странице есть неофициальная версия (заявление об отказе: из моей компании). Упакованный двоичный файл был статически собран и должен работать на всех компьютерах Linux x86_64.

Обновление карт

После этого вы можете использовать его для отображения карт, существующих в настоящее время в вашей системе:

# bpftool -f map show

Идентификаторы каждой карты будут отображаться слева. Найдите идентификатор, связанный с картой, которую вы хотите обновить (или, если карта была закреплена, запишите ее путь, отображаемый с опцией -f), а затем используйте одно из:

# bpftool map update id <id> key <key> value <new_value>
# bpftool map update pinned <path> key <key> value <new_value>

Например:

# bpftool map update id 17 key 0x1 0 0 0 0 0 0 0 value 0x1 0x2 0x3...

(Примечание: я бы использовал массив __u8 с, а не int с для хранения MAC-адреса в вашем struct rt_val. Ваш macaddr, скорее всего, будет рассчитывать на 24 байта .)

Если вы не знаете, как значения хранятся на карте, не стесняйтесь вывести их в консоль:

# bpftool map dump id 17

Дополнительные ресурсы

I не знаю ни одного существующего руководства по bpftool, но вы можете найти все подробности на страницах руководства для этого инструмента. Я также написал несколько советов об этом в Твиттере .

0
ответ дан 18 April 2019 в 13:22

Другие вопросы по тегам:

Похожие вопросы: