TL; DR: есть ли способ использовать «ip route» для добавления маршрутов многоадресной рассылки для нескольких сетевых адаптеров?
У нас есть программное обеспечение, которое использует две группы многоадресной рассылки для связи с двумя разными группами устройств в двух отдельных физических сетях. За исключением этого приложения, устройствам в одной сети не нужно взаимодействовать через наше устройство для связи с устройствами в другой сети.
Для этого программа создает два сокета. Каждый из них привязан к одному из IP-адресов отдельных сетевых адаптеров. Затем этот сокет присоединяется к группе многоадресной рассылки, которая существует в этой сети, например сокет 1 привязан к 192.168.0.2 и присоединен к группе многоадресной рассылки 233.255.10.1, а сокет 2 привязан к группе 10.57.31.2 и присоединен к группе многоадресной рассылки 239.255.100.1.
В настоящее время мы используем сценарий bash (ядро Linux 3.14.39) для установки маршрутов многоадресной рассылки на двух сетевых интерфейсах с использованием маршрута, например
route add -net 224.0.0.0 netmask 240.0.0.0 eth0
route add -net 224.0.0.0 netmask 240.0.0.0 eth1
и проверено через маршрут -n
Destination Gateway Genmask Flags Metric Ref Use Iface
224.0.0.0 0.0.0.0 240.0.0.0 U 0 0 0 eth0
224.0.0.0 0.0.0.0 240.0.0.0 U 0 0 0 eth1
Недавно я прочитал, что маршрут устарел / устарел и что вместо этого мы должны использовать ip route, например
ip route add 224.0.0.0/4 dev eth0
ip route add 224.0.0.0/4 dev eth1
К сожалению, второй вызов завершается неудачно с ответом «RTNETLINK: файл существует», и, конечно же, второй маршрут не отображается после этих вызовов.
Есть ли способ использовать IP-маршрут для добавления многоадресных маршрутов к нескольким сетевым адаптерам?
Могу я использовать / 8 в качестве сетевой маски? например
ip route add 233.0.0.0/8 dev eth0
и
ip route add 239.0.0.0/8 dev eth1
но это проблематично, поскольку скрипт, который это делает, не знает, какой адрес многоадресной рассылки связан с каким устройством, и его не всегда гарантируется то же самое в зависимости от конфигурации системы. Используя мой первый пример добавления маршрута, это не проблема.
ОБНОВЛЕНИЯ Благодаря расширенному обсуждению с @Ron Maupin я понял, что ошибка была в нашем коде. Мы не настраивали интерфейс для использования многоадресной рассылки с IP_MULTICAST_IF. После того как я добавил вызов setsockopt для установки IP_MULTICAST_IF, мне больше не нужно было добавлять таблицы маршрутизации.
struct in_addr multicastInterface = {};
multicastInterface.s_addr = interfaceAddressNetworkOrder;
// Set which outgoing interface to use
int result = setsockopt(m_socket, IPPROTO_IP, IP_MULTICAST_IF, (char*)&multicastInterface, sizeof(struct in_addr));
То, что у вас есть многоадресная рассылка через ваш Linux-сервер с использованием одноадресной маршрутизации, - это комбинация нескольких удачных обстоятельств.
Многоадресная маршрутизация отличается от одноадресной. Одноадресная маршрутизация основана на том, что трафик отправляется на один адрес, но многоадресный трафик отправляется на групповой адрес, который представляет хосты, которые хотят подписаться на группу многоадресной рассылки.
Хосты используют IGMP, чтобы сообщить маршрутизатору многоадресной рассылки, что они хотят присоединиться к группе многоадресной рассылки, и затем маршрутизатор многоадресной рассылки начнет отправлять многоадресный трафик для этой группы в сеть узлов, запрашивающих это.
Современные коммутаторы будут использовать IGMP Snooping, чтобы определить, на каких портах коммутатора есть узлы, запрашивающие присоединение к определенной группе многоадресной рассылки, и они будут отправлять трафик для этой группы многоадресной рассылки только на те порты коммутатора, где узлы запросили присоединение к группе многоадресной рассылки.
Сам по себе Linux не поддерживает многоадресную маршрутизацию, и вам нужно что-то добавить к устройству Linux для поддержки многоадресной маршрутизации. См. Схему ниже:
Когда источник многоадресной рассылки начинает отправлять многоадресный трафик для группы многоадресной рассылки, коммутатор, вероятно, не видел никаких IGMP-запросов на присоединение к группе многоадресной рассылки, поэтому многоадресный трафик для этой группы никуда не уходит.
Когда один из ПК на том же коммутаторе хочет присоединиться к группе многоадресной рассылки, он отправляет сообщение о присоединении IGMP, и коммутатор отслеживает это и отправляет многоадресный трафик на порт, к которому подключен запрашивающий ПК.
Если ПК на другой стороне маршрутизатора Linux хочет присоединиться к группе многоадресной рассылки, ему не повезло, потому что многоадресный трафик не проходит на эту сторону маршрутизатора Linux. Маршрутизатор Linux даже не присоединился к группе многоадресной рассылки, поэтому коммутатор никогда не отправляет ему многоадресный трафик.
Когда вы запускаете многоадресную маршрутизацию на маршрутизаторе, маршрутизатор будет отвечать на IGMP-запрос хоста, и коммутатор будет знать, что это многоадресный маршрутизатор, и будет отправлять многоадресный трафик на порт коммутатора, к которому подключен многоадресный маршрутизатор. Проще говоря, маршрутизатор не будет отправлять многоадресный трафик на другой интерфейс, если на другом интерфейсе нет активного получателя (это зависит от версии многоадресной рассылки, например, PIM-DM начнет отправку, но отключается, если запросы IGMP не отображаются) .
Если на маршрутизаторе включена многоадресная маршрутизация, ПК, подключенный к другому интерфейсу, отправит сообщение IGMP Join, а маршрутизатор Linux начнет отправлять многоадресный трафик для запрошенной группы на интерфейс. Коммутатор будет отслеживать запрос и будет отправлять многоадресный трафик на порт коммутатора, к которому подключен ПК, который запросил присоединение к группе многоадресной рассылки.
Это становится более сложным, если вам нужно маршрутизировать через несколько маршрутизаторов. IGMP используется между хостами и локальным многоадресным маршрутизатором. PIM (или какой-либо другой протокол многоадресной маршрутизации) используется между многоадресными маршрутизаторами.
Все это предотвращает попадание многоадресного трафика туда, где он не нужен.
К Linux есть надстройки, которые помогают ему правильно обрабатывать IGMP и многоадресную маршрутизацию.