AF_XDP - программа пользователя продолжает получать пакеты `ping`, даже если` XDP_DROP` в ядре - PullRequest
0 голосов
/ 21 февраля 2020

Я запустил свое приложение из этого репозитория: https://github.com/xdp-project/xdp-tutorial/tree/master/advanced03-AF_XDP

Так же, как «подтверждение концепции», я хотел изменить поставляемое приложение на

  • отбрасывать каждый второй полученный пакет в программе ядра (af_xdp_kern.c)
  • отвечать на полученные запросы пинга из пространства пользователя (af_xdp_user.c)

Что я ожидал увидеть в окне консоли, выполняющем пинг:

  • ответ на каждый второй запрос пинга (например, только четные или только нечетные порядковые номера)

Что я заметил вместо этого:

  • ответ на каждый запрос ping

Для дальнейшего изучения я заменил программу ядра на простой return XDP_DROP; - насколько мне известно, это означало бы, что программа userpace-program не должен получать никаких пакетов.

Но почему-то я по-прежнему вижу ответы на каждый отправляемый пинг.

Моя программа ядра:

/* SPDX-License-Identifier: GPL-2.0 */

#include <linux/bpf.h>

#include <bpf/bpf_helpers.h>

struct bpf_map_def SEC("maps") xsks_map = {
    .type = BPF_MAP_TYPE_XSKMAP,
    .key_size = sizeof(int),
    .value_size = sizeof(int),
    .max_entries = 64,  /* Assume netdev has no more than 64 queues */
};

struct bpf_map_def SEC("maps") xdp_stats_map = {
    .type        = BPF_MAP_TYPE_PERCPU_ARRAY,
    .key_size    = sizeof(int),
    .value_size  = sizeof(__u32),
    .max_entries = 64,
};

SEC("xdp_sock")
int xdp_sock_prog(struct xdp_md *ctx) {
    int index = ctx->rx_queue_index;
    __u32 *pkt_count;

    pkt_count = bpf_map_lookup_elem(&xdp_stats_map, &index);
    if (pkt_count) {
        /* We drop every other packet */
        if ((*pkt_count)++ % 2 == 0) {
            return XDP_DROP;
        } else {
            if (bpf_map_lookup_elem(&xsks_map, &index)) {
                return bpf_redirect_map(&xsks_map, index, 0);
            }
        }
    }

    return XDP_DROP;
}

char _license[] SEC("license") = "GPL";

Программа-пользовательское пространство: https://github.com/xdp-project/xdp-tutorial/blob/master/advanced03-AF_XDP/af_xdp_user.c (удалить if (false) в строке 287)

Любой идентификатор просто что не так?

Редактировать:

$ ip link
4: veth-basic02@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 96:18:08:5f:c2:c6 brd ff:ff:ff:ff:ff:ff link-netnsid 0

$ ethtool -S veth-basic02
NIC statistics:
     peer_ifindex: 3
     rx_queue_0_xdp_packets: 717
     rx_queue_0_xdp_bytes: 74088
     rx_queue_0_xdp_drops: 0

1 Ответ

0 голосов
/ 23 марта 2020

Запуск https://github.com/xdp-project/xdp-tutorial/tree/master/advanced03-AF_XDP работает для меня.

Результаты, переданные для 'ip link show', не показывают, что программа XDP прикреплена. Поэтому я выполнил шаги

  1. (только для отладки). Усовершенствуйте приложение для подсчета входящих пакетов с индексом 0 и подсчета отброшенных пакетов с индексом.
  2. создайте файл xdp.o для xd_kern . c.
  3. удалить любой предыдущий экземпляр с помощью ip link set dev <interface> xdp off.
  4. Выполнить ip link set dev <interface> xdp object <xdp.o file> section "xdp_sock" verbose.
  5. Выполнить tcpdump -eni ,interface> и проверить отметки времени.

Примечание. Предполагается, что скорость пинга равна 1 в секунду. В каждой альтернативной 1 секунде в любом пакете есть отбрасывания.

...