AF-XDP: есть ли ошибка в отношении небольших пакетов? - PullRequest
1 голос
/ 20 марта 2020

Есть ли известная (или, возможно, неизвестная) ошибка, касающаяся размера пакетов в структуре сокетов AF-XDP (+ libbpf)?

Я испытываю странную потерю пакетов для своего приложения:

  • Поток пакетов IPv4 / UDP / RTP со всеми пакетами одинакового размера (1442 байта): без потери пакетов
  • Поток пакетов IPv4 / UDP / RTP, где почти все пакеты имеют одинаковый размер (1492 байта), за исключением специального "маркерного" пакета (всего 357 байтов, но они также являются IPv4 / UDP-пакетами): все маркерные пакеты теряются

Я добавил оператор bpf_printk в своем XDP -Программа ядра:

const int len = bpf_ntohs(iph->tot_len);
if(len < 400) {
    bpf_printk("FOUND PACKET LEN < 400: %d.\n", len);
}

Этот вывод никогда не наблюдается через sudo cat /sys/kernel/debug/tracing/trace_pipe. Таким образом, эти маленькие пакеты RTP-маркера даже не принимаются моим фильтром ядра - не удивительно, почему я не получаю их в пользовательском пространстве.

ethtool -S <if> показывает мне это число: rx_256_to_511_bytes_phy. Это число увеличивается с той же скоростью, что и маркерные пакеты (около 30 / с). Таким образом, это означает, что мой NI C принимает пакеты, а моя XDP-программа - почему?

Есть идеи, что может быть причиной этой проблемы?

1 Ответ

0 голосов
/ 01 апреля 2020

Во-первых, bpf_printk() не всегда работает для меня. Возможно, вы захотите взглянуть на этот фрагмент (код пространства ядра):

// Nicer way to call bpf_trace_printk()
#define bpf_custom_printk(fmt, ...)                     \
        ({                                              \
            char ____fmt[] = fmt;                       \
            bpf_trace_printk(____fmt, sizeof(____fmt),  \
                    ##__VA_ARGS__);                     \
        })

// print:
bpf_custom_printk("This year is %d\n", 2020);
// output: sudo cat /sys/kernel/debug/tracing/trace_pipe

Второе: возможно, пакет вошел в другую очередь NI C. Возможно, вы захотите использовать ванильный код из xdp-tutorial и добавить трассировку ядра из приведенного выше фрагмента для печати размера пакета, а затем скомпилировать и запустить пример программы с -q 1 для очереди № 1, например.

Способ получения размера пакета:

void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
size_t size_pkt = data - data_end;
bpf_custom_printk("Packet size %d\n", size_pkt);
...