web-dev-qa-db-fra.com

Utilisez ip route add pour ajouter des routes de multidiffusion à plusieurs interfaces

TLDR: existe-t-il un moyen d'utiliser "ip route" pour ajouter des itinéraires de multidiffusion pour plusieurs cartes réseau?

Nous avons un logiciel qui utilise deux groupes de multidiffusion pour communiquer avec deux groupes différents d'appareils sur deux réseaux physiques distincts. À l'exception de cette application, les appareils d'un réseau n'ont pas besoin de communiquer sur notre appareil pour communiquer avec les appareils de l'autre réseau.

Multicast groups

Pour ce faire, le logiciel crée deux sockets. Chacun est lié à l'une des adresses IP du NICS distinct. Ce socket est ensuite joint au groupe de multidiffusion qui existe sur ce réseau, par exemple le socket 1 est lié à 192.168.0.2 et joint au groupe de multidiffusion 233.255.10.1 tandis que le socket 2 est lié à 10.57.31.2 et joint au groupe de multidiffusion 239.255.100.1.

Nous utilisons actuellement un script bash (noyau Linux 3.14.39) pour définir des routes de multidiffusion sur les deux interfaces réseau en utilisant route, par exemple

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

et vérifié via la route -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

J'ai récemment lu que l'itinéraire était obsolète/obsolète et que nous devrions plutôt utiliser ip route, par exemple

ip route add 224.0.0.0/4 dev eth0
ip route add 224.0.0.0/4 dev eth1

Malheureusement, le deuxième appel échoue avec "RTNETLINK répond: le fichier existe" et bien sûr la deuxième route n'apparaît pas après ces appels.

Existe-t-il un moyen d'utiliser la route IP pour ajouter des routes de multidiffusion à plusieurs cartes réseau?

Puis-je utiliser/8 comme masque de réseau? par exemple

ip route add 233.0.0.0/8 dev eth0

et

ip route add 239.0.0.0/8 dev eth1

mais cela est problématique car le script qui fait cela ne sait pas quelle adresse de multidiffusion est associée à quel périphérique et ce n'est pas toujours garanti d'être le même en fonction de la configuration du système. L'utilisation de mon premier exemple d'ajout de route en fait un problème non.

[~ # ~] met à jour [~ # ~] Grâce à une longue discussion avec @Ron Maupin, j'ai réalisé que l'erreur était dans notre code. Nous ne configurions pas l'interface à utiliser pour la multidiffusion avec IP_MULTICAST_IF. Une fois que j'ai ajouté l'appel setsockopt pour définir IP_MULTICAST_IF, je n'avais plus besoin d'ajouter les tables de routage.

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));
8
gnac

Le fait que la multidiffusion passe par votre boîtier Linux en utilisant le routage unicast est une combinaison de quelques circonstances chanceuses.

Le routage multidiffusion n'est pas identique au routage unicast. Le routage unicast est basé sur le fait que le trafic est envoyé à une seule adresse, mais le trafic multicast est envoyé à une adresse de groupe qui représente les hôtes qui souhaitent s'abonner au groupe multicast.

Les hôtes utilisent IGMP pour dire à un routeur de multidiffusion qu'ils souhaitent rejoindre un groupe de multidiffusion, et le routeur de multidiffusion commencera alors à envoyer du trafic de multidiffusion pour ce groupe au réseau des hôtes qui le demandent.

Les commutateurs modernes utiliseront IGMP Snooping pour déterminer quels ports de commutateur ont des hôtes demandant à rejoindre un groupe de multidiffusion particulier, et ils n'enverront que le trafic pour ce groupe de multidiffusion aux ports de commutateur où les hôtes ont demandé à rejoindre le groupe de multidiffusion.

Linux, en soi, ne prend pas en charge le routage multicast, et vous devez ajouter quelque chose au périphérique Linux pour prendre en charge le routage multicast. Reportez-vous au schéma ci-dessous:

enter image description here

Lorsque la source de multidiffusion commence à envoyer du trafic de multidiffusion pour un groupe de multidiffusion, le commutateur n'a probablement vu aucune demande IGMP de rejoindre le groupe de multidiffusion, de sorte que le trafic de multidiffusion de ce groupe ne va nulle part.

Lorsque l'un des PC sur le même commutateur souhaite rejoindre le groupe de multidiffusion, il envoie un message IGMP Join, et le commutateur le surveille et envoie le trafic de multidiffusion au port où le PC demandeur est connecté.

Si un PC de l'autre côté du routeur Linux veut rejoindre le groupe de multidiffusion, cela n'a pas de chance car le trafic de multidiffusion ne circule pas de ce côté du routeur Linux. Le routeur Linux n'a même pas rejoint le groupe de multidiffusion, de sorte que le commutateur ne lui envoie jamais le trafic de multidiffusion.

Lorsque vous exécutez le routage de multidiffusion sur un routeur, le routeur répondra à la demande IGMP de l'hôte et le commutateur saura qu'il s'agit d'un routeur de multidiffusion et il enverra du trafic de multidiffusion au port du commutateur auquel le routeur de multidiffusion est connecté. Simplement, le routeur n'enverra pas le trafic de multidiffusion à une autre interface à moins qu'il n'y ait un récepteur actif sur une autre interface (cela dépend de la version de multidiffusion, par exemple, PIM-DM commencera à envoyer, mais s'arrêtera si aucune demande IGMP n'est vue) .

Avec le routage multicast activé sur le routeur, un PC connecté à l'autre interface enverra un message IGMP Join et le routeur Linux commencera à envoyer le trafic multicast du groupe demandé à l'interface. Le commutateur espionnera la demande et enverra le trafic de multidiffusion au port du commutateur où le PC qui a demandé à rejoindre le groupe de multidiffusion est connecté.

Cela devient plus compliqué si vous devez acheminer via plusieurs routeurs. IGMP est utilisé entre les hôtes et le routeur de multidiffusion local. PIM (ou un autre protocole de routage de multidiffusion) est utilisé entre les routeurs de multidiffusion.

Tout cela empêche le trafic de multidiffusion d'aller là où il n'est pas souhaité.

Il existe des modules complémentaires pour Linux pour l'aider à gérer correctement IGMP et le routage multicast.

7
Ron Maupin