TLDR:有没有办法使用“ip route”为多个网卡添加组播路由?
我们的软件使用两个多播组与两个不同的物理网络上的两个不同的设备组进行通信.除此应用程序外,一个网络上的设备无需通过我们的设备进行通信,即可与另一个网络上的设备进行通信.
为此,该软件创建了两个套接字.每个绑定到单独的NICS的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 route将组播路由添加到多个NIC?
我可以使用/ 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侦听来确定哪些交换机端口具有请求加入特定多播组的主机,并且它们仅将该多播组的流量发送到主机已请求加入多播组的交换机端口.
Linux本身不支持组播路由,您需要向Linux设备添加一些内容以支持组播路由.请参考下图:
当组播源开始为组播组发送组播流量时,交换机可能没有看到任何加入组播组的IGMP请求,因此该组的组播流量无处可去.
当同一台交换机上的其中一台PC想加入组播组时,它会发送IGMP加入消息,交换机将监听该消息,并将组播流量发送到请求PC所连接的端口.
如果Linux路由器另一侧的PC想要加入组播组,则运气不好,因为组播流量没有流向Linux路由器的那一侧. Linux路由器甚至没有加入组播组,因此交换机永远不会向其发送组播流量.
当您在路由器上运行多播路由时,路由器将响应主机IGMP请求,并且交换机将知道它是多播路由器,并且它将多播流量发送到多播路由器所连接的交换机端口.简单地说,路由器不会将组播流量发送到另一个接口,除非另一个接口上有活动接收器(这取决于组播版本,例如,PIM-DM将开始发送,但如果没有看到IGMP请求则退回) .
在路由器上启用多播路由后,连接到另一个接口的PC将发送IGMP加入消息,Linux路由器将开始将请求组的多播流量发送到接口.交换机将监听请求,并将组播流量发送到请求加入组播组的PC所连接的交换机端口.
如果你需要路由throgh多个路由器,它会变得更复杂. IGMP用于主机和本地多播路由器之间.在组播路由器之间使用PIM(或一些其他组播路由协议).
这一切都可以防止多播流量进入不需要的地方.
有一些Linux附加组件可以帮助它正确处理IGMP和组播路由.