Мне нужно создать систему, в которой я могу маршрутизировать пакеты на основе ряда параметров, таких как порт / протокол и т. Д., Которые в некотором роде «нормальные», но также и по другим аспектам, таким как длина очереди и другие внешние факторы. . Мой маршрутизатор состоит из 2 внутренних интерфейсов (802.11) и двух внешних интерфейсов (один ADSL, один LTE). Поэтому я хотел бы изучить каждый пакет с помощью внешней программы и решить, через какой интерфейс он должен быть маршрутизирован.
Я взглянул на iproute2, но не нашел способа передать каждый пакет внешней программе или каким-то образом динамически выбирать маршрут для каждого пакета.
Итак, вопрос: как лучше всего это сделать? Существуют ли уже инструменты, которые работают в этом направлении, или мне следует полагаться на то, что я сделал сам и передавая пакет через стандартные инструменты Linux?
Netfilter (iptables) имеет модуль очереди для отправки кадров в программу пользовательского пространства. Библиотеки для разных языков (c, питон, perl и т. д.) доступны для проверки пакетов. После обработки кадра вы вернете вердикт ACCEPT или DROP, исходный или измененный кадр и возможность установить отметку.
Я предполагаю, что вы можете использовать метку для обработки этого пакета по-другому в остальной части цепочки netfilter и изменить метку маршрутизации, чтобы выбрать конкретную таблицу маршрутизации.
Это было бы более элегантным решением, чем обработка устройств на очень низком уровне, но это может быть проблемой производительности в зависимости от выбора реализации вашего пользовательского пространства.
Я использовал это в другом проекте для изменения входящих кадров DHCP от сломанного клиента, но никогда не использовал метку.
Маршрутизация в пользовательском пространстве может быть достигнута путем указания маршрута по умолчанию на tun
устройство и программа пользовательского пространства проверяет каждый полученный пакет. Это неэффективный и хрупкий подход, но его заставили работать - благодаря Хеннингу Рогге была реализация AODVv2, которая работала таким образом.
Другой вариант, конечно же, - реализовать свой протокол маршрутизации в ядре - большинство реализаций AODV / DYMO / AODVv2 работают именно так.
Прежде чем браться за такую задачу, я бы рекомендовал тщательно подумать, нужно ли вам принимать решения о маршрутизации для каждого отдельного пакета; если возможно, лучший подход - динамически манипулировать таблицами маршрутизации, оставляя фактическую пересылку ядру. Пример того, чего можно достичь с помощью этого подхода, приведен в этот черновой документ. (Отказ от ответственности: я соавтор.)
Какое оборудование вы используете? Похоже, вы работаете со встроенным устройством, и в этом случае вам, вероятно, следует использовать параметр netfilter. Но если в вашем распоряжении больше ресурсов, вам следует подумать об использовании OVS (http://openvswitch.org/), который де-факто является стандартом с открытым исходным кодом для программно-определяемых сетей.
В программно-конфигурируемых сетях используется концепция «плоскости данных» и «плоскости управления». Пакеты перемещаются между физическими / виртуальными коммутаторами в плоскости данных. В плоскости управления ваше программное обеспечение отправляет инструкции коммутаторам о том, как пересылать пакеты через плоскость данных.
Вы можете настроить OVS в контейнере и рассматривать его как переключатель ToR (вершина маршрутизатора) для вашей системы. Маршрутизируйте все входящие пакеты в OVS, и пусть он решает, что с ними делать. Ваше программное обеспечение отправляет на коммутатор инструкции openflow.
Вот несколько ресурсов, с которых можно начать:
Удачи!