Как стать автором
Обновить

Покоряем сетевой стек Linux: декапсулируем пакеты с помощью eBPF на скорости 6Mpps+

Время на прочтение15 мин
Количество просмотров7.4K
Всего голосов 72: ↑72 и ↓0+85
Комментарии5

Комментарии 5

Вариант netgraph на bsd не рассматривался?

Теория про парсинг пакета интересна, но хотелось бы посмотреть на эти 205 строчек хоть и адаптированном для публикации виде )
В теории: может оказаться что быстрее первым действием проверить наличия числа 4789 (порт UDP) на некоторых фиксированных смещения, вариаций где оно может быть не так много. Не нашли - пакет не наш. Нашли - проверяем остальное.

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

Причина просадки неочевидна: ipt_NETFLOW ведь все равно должен видеть этот трафик, пусть и относить он его будет к непонятному потоку на 4789/udp. Или у ваших коллег там фильтр на потоки стоит, чтобы отвергать все непонятное? Впрочем толку с этого потока для них действительно никакого.

Программа обязательно должна завершаться. И verifier это строго проверит.

Интересно, как? Утверждается ведь, что язык eBPF - полный по Тюрингу, а задача останова для Тюринг-полных языков неразрешима, как известно. Короче, похоже кто-то что-то недоговаривает.

А ещё непонятно - неужели в для Netfilter нельзя сделать цепочку модулей: подключить перед ipt_NETFLOW модуль=драйвер, который будет производить декапсуляцию VXLAN (типа, как этот ваш eBPF), а его результат уже отдавать в ipt_NETFLOW? WFP (это функциональный аналог Netfilter в ядре Windows) свои Callout Drivers так подключать позволяет (ЕМНИП).

PS Ну и, общее впечатление - хорошо, когда в ядро некая базовая функциональность была встроена изначально.
В NT, например, подключение своего драйвера (т.е. модуля режима ядра общего наззначения, каким-либо устройством ему управлять необязательно) в разрыв между любыми компонентами ввода/вывода, работяющими с IRP (пакетами запросов ввода/вывда) - это штатная функциональность, существовавшая изначально, даже когда той же WFP и в проекте не было: она появилась даже позже Netfilter в Linux - я ещё помню, как я читал про нее и облизывался.
Опять же - обработка прерываний. В архитектруе драйвера изначально было заложено наличие короткой процедуры обработки прерывания, работавшей на IRQL драйвера, которая максимально быстро ставит в общесистемную очередь процедуру отложенного вызова, которая обрабатывается системой (а не драйвером) на IRQL=DISPATCH_LEVEL, на котором можно позволить горздо больше - вплоть до обращения к старнице виртуальной памяти, выгруженной в данный момент на диск (на IRQL драйвера за такие художества синий экран показывают). Очередь - общисистемная, а потому ограничения на размер очереди там мягче.

Утверждается ведь, что язык eBPF - полный по Тюрингу, а задача останова для Тюринг-полных языков неразрешима, как известно. Короче, похоже кто-то что-то недоговаривает.

И я вам даже скажу кто недоговаривает.

Тадам!

Это математики.

В данном конкретном случае они берут машину Тьюринга (с бесконечной лентой) и заявляют, что решение проблемы останова для бесконечной ленты занимает бесконечное время.

Ну, ок, вопросов нет.

Но дальше мы берём машину с конечной лентой (1М слов команд + несколько М слов памяти), и... оказывается, что при конечной ленте решение проблемы останова занимает не просто конечное, но чуть ли не линейное время (n log n если точнее)

И кто же тут по факту не договаривает, ваше мнение?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий