Как добиться многопутевой маршрутизации для каждого пакета в Linux?

9

Ядро Linux до 3.6 использовало кэширование маршрутов для многопутевой маршрутизации IPv4, что означало, что маршрутизация между двумя отдельными линиями / провайдерами была довольно простой. С 3.6 алгоритм изменился на пакетный, что означало, что для достижения двух линий / интернет-провайдеров требовались некоторые приемы маркера таблицы маршрутов / правила / iptables.

Однако если бы у вас было две линии с одним и тем же провайдером, которые могли бы маршрутизировать один IP по обеим линиям для каждого пакета в режиме сбалансированного / аварийного переключения, то из 3.6 вы могли бы легко добиться соединения линий (на уровне IP) из-за маршрутизация за пакет в обоих направлениях.

Начиная с 4.4, ядро снова переключилось на балансировку нагрузки на основе потоков на основе хэша по адресам источника и назначения.

В настоящее время я использую ядро ​​4.4.36 и использую многолучевую маршрутизацию по соединениям PPPoE. Мой нисходящий трафик от интернет-провайдера направляется через две отдельные линии для каждого пакета (один IP направляется по обеим линиям). Это дает мне скорость загрузки быстрее, чем скорость одной отдельной строки. Почти скорость обеих линий суммируется. Это работает очень хорошо, видео Skype, VoIP (UDP), YouTube и т. Д. Все отлично работает.

Из-за такого хорошего нисходящего потока я хочу попробовать его в восходящем направлении, но мой восходящий трафик направляется в соответствии с более новым алгоритмом на основе потоков на обоих устройствах ppp (которые имеют один и тот же IP-адрес). Это означает, что я не могу достичь скорости загрузки, превышающей скорость отдельной строки.

Есть ли способ настроить текущее ядро ​​для использования алгоритма для каждого пакета? Или какой-то другой метод для достижения многопутевой маршрутизации на пакет? Нужно ли мне возвращаться к более старому Ядру (что я не хочу делать по другим причинам)?

Мой провайдер не поддерживает многоканальный ppp.

В случае, если это уместно, я сейчас использую Arch Linux ARMv7 на Raspberry Pi 3.

bao7uo
источник
3
Это очень плохая идея. Балансировка каждого пакета в L2 (то есть MLPPP) включает в себя достаточно логики для повторной сборки пакетов по порядку. Выполнение этого по IP оставляет открытой огромную возможность (если не почти наверняка) для доставки не по порядку. Это приведет к огромному количеству проблем с медленными сеансами TCP, полностью прерванными UDP, проблемами с любыми видами потоковой передачи в реальном времени и т. Д. Другая проблема заключается в том, что даже если вы отправляете пакеты циклически на ваш ISP, есть абсолютно нет предположений, что они будут так же балансировать по отношению к вам.
rnxrx
@rnxrx спасибо за ваш комментарий - отредактировал вопрос, чтобы предоставить дополнительную информацию. Из моего вопроса: «нисходящий трафик от провайдера маршрутизируется через две отдельные линии для каждого пакета». Интернет-провайдер предоставляет панель управления - когда я выбираю один IP-адрес для маршрутизации по обеим линиям, он направляет его идеально сбалансированным циклическим перебором для каждого пакета. Работает хорошо, при суммировании примерно 90% от общей скорости обеих линий и обеспечивает мгновенное переключение при сбое. Skype видео, VOIP звонки, YouTube, BBC потоковое и т. Д. Все отлично - такой замечательный нисходящий опыт заставляет меня хотеть попробовать upstream
bao7uo
1
Ааа - понял ... Итак, в настоящее время у вас есть два уникальных IP-адреса (по одному на соединение) или они маршрутизируются на один IP-адрес (или подсеть) на вашей стороне через два параллельных пути? Если вы используете какой-либо NAT, очевидно, важно, чтобы это произошло до этой балансировки. В любом случае - вы смотрели на support.aa.net.uk/… ? Он использует расширения iptables, чтобы выполнить в основном то, что вы описываете, и поэтому должен быть достаточно согласованным с достаточно современными версиями ядра.
rnxrx
Спасибо @rnxrx - да, я могу сделать любой вариант (два уникальных IP или один IP через параллельные пути). Я предпочел вариант с одним IP, так как он казался более логичным.
bao7uo

Ответы:

3

Итак, после того, как у меня появилось больше времени на изучение этого вопроса, я нашел способ сделать это с помощью Linux TEQL (True Link Equalizer). Вот ссылка, по которой я свободно следовал, но с некоторыми изменениями.

http://lartc.org/howto/lartc.loadshare.html

Вот как я начал работать над Arch Linux ARMv7 (Raspberry Pi 3)

При загрузке:

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

modprobe sch_teql

Следующие команды также запускаются при загрузке, если вы хотите использовать NAT из локальной сети на eth0.

sysctl -w net.ipv4.ip_forward=1
iptables -A INPUT -i ppp+ -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i ppp+ -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A POSTROUTING -t nat -o teql+ -j MASQUERADE

Обратный трафик FORWARD находится на ppp +, а MASQUERADE POSTROUTING на teql +, потому что исходящий трафик выходит на teql, а обратный трафик возвращается на ppp.

Когда появляются ppp ссылки:

Предполагая, что ссылки для балансировки нагрузки являются ppp, следующие команды должны быть выполнены в скрипте в /etc/ppp/ip-up.d/скрипте.

sysctl -w net.ipv4.conf.ppp1.rp_filter=2
sysctl -w net.ipv4.conf.ppp2.rp_filter=2
tc qdisc add dev ppp1 root teql0
tc qdisc add dev ppp2 root teql0
ip address add 1.1.1.1/32 dev teql0
# you can add additional public IP addresses teql0 if you need to
ip link set teql0 up
ip route replace default scope global dev teql0

Где 1.1.1.1ваш общедоступный IP-адрес для вашего интернет-провайдера. Дополнительные общедоступные IP-адреса могут быть назначены устройству teql0, но их не нужно назначать устройствам ppp. В моей настройке две ссылки ppp имеют один и тот же IP-адрес (по согласованию с pppoe и т. Д.). Ссылка teql назначается вручную, как показано выше. Интернет-провайдер должен отправлять трафик для IP-адреса одинаково по обоим каналам.

Обратный путь ( rp_filter) 2в вышеприведенном сценарии установлен как (свободный), так что возвращаемые пакеты не отбрасываются из-за их возвращения на интерфейсы ppp, а не на teql0.

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

Кроме того, один из комментаторов предложил ссылку ниже, которая использует политику маршрутизации, с iptables, чтобы пометить каждый второй пакет и т. Д., Но я постараюсь через несколько дней выяснить, работает ли он лучше, чем выше, и предоставить соответствующую информацию здесь.

http://support.aa.net.uk/Router_-_Linux_upload_bonding_using_policy_routing

bao7uo
источник
Я никогда не пробовал политику маршрутизации, потому что TEQL работал так хорошо. Если это не сломано ....
bao7uo
Я пытаюсь заставить это работать. У меня работает соединение, я могу использовать связанный интерфейс от роутера. Я не могу заставить работать NAT, хотя трафик из моей локальной сети не идет по соединенному каналу :(
andynormancx
если вы отправите новый вопрос по вине сервера, и ссылку на него из комментария, я постараюсь выяснить это для вас. включать как можно больше информации, такой как конфигурация интерфейса / ip, таблица маршрутизации, правила iptables и т. д., если вы не можете разместить всю информацию здесь в комментариях?
bao7uo
1
PS. только что заметил ошибку в моем конфиге. он сказал, sysctl -w net.ipv4.ip_forwardно должен сказать, sysctl -w net.ipv4.ip_forward=1так что я исправил выше. Это, безусловно, предотвратит передачу трафика из локальной сети по соединенному каналу.
bao7uo
Я не думаю, что это перестало работать на меня, у меня была включена пересылка в sysctl. Сейчас я пытаюсь выяснить, ожидается ли огромное количество неупорядоченных пакетов, которые я вижу.
andynormancx