LINUX.ORG.RU

Быстрый форвардер L2 трафика в userspace

 ,


0

2

Добрый день! Есть ядро Linux 4.14.40 на встраиваемом устройстве (AM335x SoC). Задача сделать быстрый форвардер пакетов на уровне L2 в userspace, т.е. чтобы можно было править Ethernet header и т. д. Попробовал в лоб через сырые сокеты (socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) и recvfrom в блокирующем режиме - производительность не очень, даже 4kpps не получается. Подскажите, пожалуйста, какие подходы в моем случае подойдут для увеличения производительности форвардера (нужно именно в userspace, .rx_handler не предлагать)? Потому что я так понимаю 4kpps это не предел для userspace наверное…

eBPF хочешь ты

хотя железо слабое и wire speed все равно не получишь

router ★★★★★
()

Под вопросом.

Вам нужен DPDK вот примерно так для решения Вашей задачи.

Попробовал в лоб через сырые сокеты (socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) и recvfrom в блокирующем режиме - производительность не очень

«Нет». RAW-сокеты позволяют обойти файерволл, т.к. они не обрабатываются ядром и, конкретнее, файерволлом. Но тогда придётся весь проходящий траф как-то в RAW запихивать.

«Нет», AM335x SoC это в любом случае слабовато для высокоскоростной обработки.

Moisha_Liberman ★★
()
Последнее исправление: Moisha_Liberman (всего исправлений: 1)
Ответ на: комментарий от dvetutnev

Потому что...

Линуксовый фаервол умеет править пакеты, но он в ядре.

Для специализированных решений линуксовый файерволл, это тормоз. sk_buff и всё остальное-прочее.

Именно поэтому был создан DPDK. Хотя, данный подход – проброс пакетов в user space, анализ и решение по пакету (дропнуть или пропустить) изначально был продемонстрирован в suricata. Именно для данного проекта создали специализированные модули ядра для ряда сетевых карт (тот же Intel прежде всего), которые позволяли перенести данные из входящего буфера карты для анализа в userspace. Сейчас DPDK позволяет весьма много делать. В т.ч., например, применять различные криптодевайсы (как аппаратные, так и софтовые) для криптопреобразования трафика на лету. Хотя, спектр решаемых задач намного шире.

Хотя, сейчас можно применять nftables, для которых есть библиотеки по управлению правилами из userspace, всё равно используют DPDK (как правило).

Почему именно в userspace нужно?

Там проще анализировать трафик. Безусловно что можно такой анализатор впихнуть в ядро в виде модулей, но это АдЪ, треш и угар. Можно конечно использовать что-нибудь типа libnetfilter_cthelper/libmnl/libnftnl, но быстро и надёжно тут не получится.

Moisha_Liberman ★★
()
Ответ на: комментарий от dvetutnev

Здравствуйте, спасибо за ответ! В userspace нужно для удобства, потому что придется перестраивать много вещей пакетах на уровне payload и т. д., а что никак нельзя в userspace оптимально обрабатывать трафик, сырой сокет + recvfrom()/sendto() оптимальный вариант?

Andy041292
() автор топика
Ответ на: Потому что... от Moisha_Liberman

Спасибо, а используя DPDK я смогу полностью править входящий пакет как хочу? Например MAC-адреса, EthType и payload, т. е. смогу достать любое место в пакете?

Andy041292
() автор топика
Ответ на: комментарий от Andy041292

Может посмотреть на внутренне устройство OpenVPN? Он вроде в userspace трафик обрабатывает.

dvetutnev
()
Ответ на: комментарий от metawishmaster

Уже нет.

а DPDK разве не только для штеудовских карточек?

Исторически, да. Когда создавалась suricata, то изначально она была только на штеудовских картах. Потом, когда начали DPDK, тоже всё это начала Intel. Сейчас это уже целый консорциум производителей. Поддерживаемое железо здесь. В общем и целом. Там чего только нет… Но обычно да, DPDK это основа для оборудования типа магистральных коммутаторов/маршрутизаторов. 10G, 40G, вот этого вот всего.

Moisha_Liberman ★★
()
Ответ на: комментарий от Andy041292

В принципе можете.

используя DPDK я смогу полностью править входящий пакет как хочу? Например MAC-адреса, EthType и payload, т. е. смогу достать любое место в пакете?

Да. Вы перехватываете пакеты, заполняете соответствующие структуры данных. Следовательно, Вы можете их нужным Вам образом менять и отправлять дальше. Тут и тут для начала. Потом посмотрите на структуры пакетов начиная, например, вот отсюда. Собственно, нужно понять как именно подсунуть своё решение в уже готовый фреймворк, расширив его. Могу сказать сразу – в самом общем случае DPDK работает с шаблонами, т.е. на приходящий пакет накладывается некий шаблон и производится сравнение.

Но вот тут есть некоторые вопросы. Я малость подумал и прихожу к выводу, что перед Вами может внезапно возникнуть ряд вопросов. Первый – будет ли поддерживаться Ваше оборудование? Потому что если нет, то тогда придётся брать готовый модель ядра именно для Вашего оборудования и дотачивать его до того, чтобы оборудование поддерживалось в DPDK. А это, в свою очередь, может резко увеличить общий бюджет проекта. Собственно, поэтому дяденьки, которые работают со всем этим… достаточно высокооплачиваемые и проекты эти довольно дорогостоящие.

Второй вопрос – а хватит ли производительности у Вашего железа? Вполне вероятно что канителиться с этим железом под DPDK, это из пушки по воробьям. Шибко большой скорости можно будет не ждать.

У меня тут идея возникла – а что бы не попробовать использовать просто libpcap? Т.е., перехватывать и парсить пакеты мы можем (см. pcap_filter()). Но libpcap умеет работать с packet injection (см. pcap_inject(), pcap_sendpacket()). Т.е., Вы сможете перехватывать трафик по своим фильтрам и модифицировать его нужным образом и отправить далее. Например

С libpcap ненужны RAW-sockets, всё можно упростить и без длительного траха с DPDK. И приложение будет довольно простым. В принципе, задача сводится к написанию своего сниффера и пропустить трафик через него. Может оказаться рабочим вариантом. И проверить вариант решения достаточно быстро и ненужно трахаться с модулями ядра и достаточно обширным фреймворком.

Moisha_Liberman ★★
()
Ответ на: В принципе можете. от Moisha_Liberman

Так. Стоп.

Отставить DPDK. Я внимательно посмотрел на спеки AM335x SoC. У Вас там указано что карта поддерживает 1G, но это только на сети. Внутри эти интерфейсы посажены на USB2.0. Т.е., скорости на каждой сетевой карте будут 480M, не более (ограничение USB2.0). Т.е., в любом случае выше 480M можно не ждать.

Дальше всё хуже. Вам надо как-то обрабатывать трафик, т.е., добавляем ещё затраты времени на обработку. Ну, где-то 300-400M и не более. Как-то так будет.

И ещё – если у Вас там Linux, то нужно пересобрать ядро и вырубить на фиг всё, что касается файерволла в ядре, чтобы он не болтался под ногами у сниффера, который должен работать в promiscuous mode (в случае, если Вы будете использовать libpacap).

Moisha_Liberman ★★
()
Ответ на: Так. Стоп. от Moisha_Liberman

Внутри эти интерфейсы посажены на USB2.0. Т.е., скорости на каждой сетевой карте будут 480M, не более (ограничение USB2.0). Т.е., в любом случае выше 480M можно не ждать.

знатный бред, смотри рефман раздел 10 Interconnects, Figure 10-1. L3 Topology

https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/790/AM335x_5F00_techincal_5F00_reference_5F00_manual.pdf

2 Port GEMAC Switch и USB даже в разных доменах

anonymous
()

pf_ring можно попробовать

ates
()
Ответ на: комментарий от anonymous

Батенька, Вы балбес.

И это не оскорбление, а простая констатация медицинского факта.

Вот Ваша ссылка. Открываем прямо 1.4 Functional Block Diagram, Figure 1-1 shows the AM335x microprocessor functional block diagram.

Ниже приведена функциональная блок-схема, прямо там же, на стр. 5 приведённого Вами документа (удивляюсь – зачем приводить документ, который либо не читали, либо хреново поняли?).

Вот то, что там нарисовано, это всё, что Вам нужно знать о внутреннем устройстве данного SoC. Даже не особо разбираясь в том, что там с PHY творится, Вам это не нужно. Особо глубоко лезть тоже. На ARM только на Raspberry Pi 4 сетка сделана более-менее по-честному. В остальных случаях она на USB болтается. Точно так же, как и в данном случае EMAC (2-port) 10M, 100M, 1G IEEE 1588v1, and switch (MII, RMII, RGMII) это всё «serial», который через L3/L4 interconnect заведён на проц.

Тут Вы уже можете не фантазировать насчёт доменов. Домен это не столько аппаратная часть, сколько прежде всего логическая (вообще-то). И тут похрен что Вы думаете.

Отдельно я замечу что в приведённом Вами документе нет раздел 10 Interconnects, Figure 10-1. L3 Topology. Т.е., что Вы за говнину сюда приволокли и зачем, лично мне не понятно.

Ладно, пусть будет документ по Вашей ссылке. Дальше открываем приведённую на стр. 18 из Вашего документа ссылку, тоже PDF. Идём на стр. 2013 документа и читаем внимательно в разделе 14.3.1.1 Interrupt Pacing:

The Interrupt pacing feature limits the number of interrupts that occur during a given period of time. For heavily loaded systems in which interrupts can occur at a very high rate (e.g. 148,800 packets per second for Ethernet), the performance benefit is significant due to minimizing the overhead associated with servicing each interrupt. Interrupt pacing increases the CPU cache hit ratio by minimizing the number of times that large interrupt service routines are moved to and from the CPU instruction cache.

Несложно заметить что это значение для свича, который там встроен. Собственно, с ним как-то и надо работать чтобы выполнять преобразования пакетов. Или Вы предполагаете прямо на процессоре софтсвитч организовать? Тогда у меня для Вас ещё более плохие новости…

Жирным я специально для долб… эээ… для Вас лично выделил значимое значение. Ваш свитч Ethernet будет в лучшем случае пропускать 148 800 пакетов в секунду. Дальше простой расчёт – умножаем число пакетов в секунду на размер eth-фрейма в байтах округлённо. Т.е., 148 800 * 1500 = 223200000 байт в секунду. Или, по-просту, 223M в секунду. Это максимальная скорость, с которой будет работать Ваш свитч (и то если будет, т.к. пакеты надо преобразовывать, а это дополнительные расходы, сжирающие ресурсы).

Отдельно замечу что в документации не сказано какой именно размер пакетов принимается. А то, если размер пакета по 64 байта, то всё будет ещё печальнее. Если Вы посмотрите на доки для ряда свичей, то там отдельно этот момент оговаривается. Размер пакета и его тут надо отдельно смотреть.

Если Вы вознамеритесь на самом проце сорганизовать софтсвитч (игнорируя аппаратный), то тогда Вы упрётесь в то, о чём я и говорил выше. Тут вся сеть болтается на USB 2.0, следовательно, скорости будут примерно такими, которые я и обозначил. И то, что Eth поддерживает 1G вовсе не означает того, что ровно мегабит реальных данных будет обрабатываться устройством.

В общем, милейший, не вводите людей в заблуждение, а то люди по простоте душевной от микрухи за условные «пять баксов» будут ожидать просто очешуенной производительности.

Я, конечно, тоже погорячился насчёт DPDK. Просто сразу не посмотрел спеки. DPDK здесь лишний, т.к. обработки гигабитного потока реальных данных я не ожидаю. Максимум 300-400М и то, если повезёт.

Умоляю. Не пишите больше ерунды, хорошо? =)))

Moisha_Liberman ★★
()
Последнее исправление: Moisha_Liberman (всего исправлений: 1)
Ответ на: Батенька, Вы балбес. от Moisha_Liberman

На ARM только на Raspberry Pi 4 сетка сделана более-менее по-честному.

посмотри Marvell Octeon или NXP Layerscape

В остальных случаях она на USB болтается. Точно так же, как и в данном случае EMAC (2-port) 10M, 100M, 1G IEEE 1588v1, and switch (MII, RMII, RGMII) это всё «serial», который через L3/L4 interconnect заведён на проц

дурачёк увидел serial на блок-схеме и решил что EMAC подключен через USB :) Я же тебе тупице раздел назвал где смотреть - стр 864.

anonymous
()
Ответ на: комментарий от anonymous

ЛОЛ, ПРАСТИТИ, ШТА?!? =)))

дурачёк увидел serial на блок-схеме и решил что EMAC подключен через USB :) Я же тебе тупице раздел назвал где смотреть - стр 864.

Что, умишком скорбный, Вы так и не поняли что этот самый «serial» включается через L3/L4 interconnector? На приведённой Вами диаграмме именно это и нарисовано. Но того, что это «serial» (в данном случае USB) это не отменяет. Ну да, «serial» включается в шину, реализованную внутренней шиной SoC. На скорость обработки сетевого трафика это не повлияет ни как. Это просто способ объединения внутри SoC. =)))

Вот китайский раб Божий прямо скриншот приводит пересборки ядра. Нотариально заверенный скриншот представлен по ссылке. =)))

Recompile the kernel (2.6.29)

2.6.29 kernel

   Device Drivers ---> USB support --->   USB Gadget Support ---> 

Among them, the USB Peripheral Controller selects S3C2410 USB Device Controller Then choose a Gadget driver that comes with the kernel to demonstrate, here is Ethernet Gadget (with CDC Ethernet support) Since this driver does not need to pass in parameters, give Y instead of M, which saves trouble

Чё, теперь версия ядра не понравится, т.к. старенькая? =))) Ну или вот. Прямо в Kconfig можно порыться (у меня железки нет под руками).

посмотри Marvell Octeon или NXP Layerscape

Зойчеммм? Здесь разговор не про них.

Moisha_Liberman ★★
()
Последнее исправление: Moisha_Liberman (всего исправлений: 1)
Ответ на: ЛОЛ, ПРАСТИТИ, ШТА?!? =))) от Moisha_Liberman

Но того, что это «serial» (в данном случае USB)

на блок-схеме serial обознчены блоки с последовательными интерфейсами, USB в том числе

Нотариально заверенный скриншот представлен по ссылке

програмной эмуляции Ethernet поверх USB, к аппаратному EMAC это никакого отношения не имеет, тупостью решил поразить ? отчасти получилось, но тут и похлеще встречаются.

anonymous
()
Ответ на: комментарий от anonymous

Ну, тоесть...

В TI работают идиоты, которые не в состоянии запилить поддержку eth без USB на своей борде? Или всё проще – eth здесь, как и сказано, реализован через USB?

В общем, ясно. Ничего нового я не прочитаю.

Удачи.

Moisha_Liberman ★★
()
Ответ на: комментарий от Andy041292

Ладушки. =)

Ежели какие вопросы будут возникать, то пишите. Чем смогу, помогу. =)

С этими технологиями (в частности «перехватом» или сниффингом) и такого рода девайсами я дружу достаточно плотно.

Moisha_Liberman ★★
()
Последнее исправление: Moisha_Liberman (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.