使用ip route add将组播路由添加到多个接口

TLDR:有没有办法使用“ip route”为多个NIC添加组播路由

我们拥有使用两个多播组的软件,可以在两个独立的物理networking上与两组不同的设备进行通信。 除此应用程序外,一个networking上的设备无需通过我们的设备进行通信即可与另一个networking上的设备进行通信。

多播组

为此,该软件创build两个套接字。 每个绑定到单独的NICS的一个IP地址。 然后,该套接字join到该networking中存在的多播组,例如,套接字1绑定到192.168.0.2,并join到多播组233.255.10.1,而套接字2绑定到10.57.31.2,并join多播组239.255.100.1。

我们正在使用bash脚本(Linux内核3.14.39)在两个networking接口上使用路由来设置组播路由

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进行validation

 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路由,例如

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

不幸的是,第二次调用失败,“RTNETLINK答案:文件存在”,当然第二个路由不会在这些调用后显示。

有没有办法使用IP路由添加组播路由到多个NIC?

我可以使用/ 8作为networking掩码? 例如

 ip route add 233.0.0.0/8 dev eth0 

 ip route add 239.0.0.0/8 dev eth1 

但这是有问题的,因为执行此操作的脚本不知道哪个多播地址与哪个设备关联,并且根据系统configuration,并不总是保证相同。 使用我的路由添加的第一个例子使这不成问题。

更新由于与@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机器进行多播是两个幸运的情况的组合。

组播路由与单播路由不一样。 单播路由是基于stream量被发送到单个地址的情况,但是多播stream量被发送到表示要订阅多播组的主机的组地址。

主机使用IGMP告诉组播路由器他们想要join一个组播组,然后组播路由器将开始发送该组的组播stream量到请求这个主机的networking。

现代交换机将使用IGMP侦听来确定哪些交换机端口有主机请求join特定的多播组,并且它们只会将该多播组的stream量发送到主机请求join多播组的交换机端口。

Linux本身不支持多播路由,你需要在Linux设备上添加一些东西来支持多播路由。 请参考下图:

在这里输入图像说明

当组播源开始向组播组发送组播stream量时,交换机可能没有看到任何join组播组的IGMP请求,所以该组播组的stream量不通。

当同一交换机上的其中一台PC想要join组播组时,会发送一个IGMPjoin报文,交换机将侦听该报文,并将组播stream量发送到请求PC所连接的端口。

如果Linux路由器另一端的PC希望join组播组,那么这是不好的,因为组播stream量不会stream向Linux路由器的那一边。 Linux路由器甚至还没有join组播组,所以交换机不会向其发送组播stream量。

在路由器上运行组播路由器时,路由器会响应主机的IGMP请求,交换机会知道它是一个组播路由器,并将组播stream量发送到组播路由器所连接的交换机端口。 简单地说,路由器不会将组播stream量发送到另一个接口,除非在另一个接口上有一个活动的接收器(这取决于组播版本,例如,如果没有看到IGMP请求,PIM-DM将开始发送,但返回) 。

在路由器上启用组播路由后,连接到其他接口的PC将发送IGMPjoin消息,Linux路由器将开始向请求的组发送组播stream量。 交换机将根据请求窥探,并将组播stream量发送到请求join组播组的PC连接的交换机端口。

如果你需要路由多个路由器,它会变得更加复杂。 在主机和本地多播路由器之间使用IGMP。 在多播路由器之间使用PIM(或其他多播路由协议)。

这一切都可以防止组播stream量到达不需要的地方。

Linux有附加组件来帮助它正确处理IGMP和组播路由。