gna*_*nac 10 linux routing multicast iproute
TLDR:有没有办法使用“ip route”为多个 NIC 添加多播路由?
我们的软件使用两个多播组与两个不同物理网络上的两组不同设备进行通信。除此应用程序外,一个网络上的设备不需要通过我们的设备与另一个网络上的设备进行通信。
为此,软件会创建两个套接字。每个都绑定到单独 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
Run Code Online (Sandbox Code Playgroud)
并通过 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
Run Code Online (Sandbox Code Playgroud)
我最近读到该路由已弃用/过时,我们应该改用 ip route,例如
ip route add 224.0.0.0/4 dev eth0
ip route add 224.0.0.0/4 dev eth1
Run Code Online (Sandbox Code Playgroud)
不幸的是,第二次调用失败并显示“RTNETLINK 答案:文件存在”,当然在这些调用后第二条路由不会出现。
有没有办法使用 ip route 将多播路由添加到多个 NIC?
我可以使用 /8 作为网络掩码吗?例如
ip route add 233.0.0.0/8 dev eth0
Run Code Online (Sandbox Code Playgroud)
和
ip route add 239.0.0.0/8 dev eth1
Run Code Online (Sandbox Code Playgroud)
但这是有问题的,因为执行此操作的脚本不知道哪个多播地址与哪个设备相关联,并且根据系统配置并不总是保证相同。使用我的第一个路由添加示例使这不是问题。
更新 感谢与@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));
Run Code Online (Sandbox Code Playgroud)
使用单播路由使多播通过 Linux 机器是两种幸运情况的组合。
多播路由与单播路由不同。单播路由基于流量被发送到单个地址的表面,但多播流量被发送到代表想要订阅多播组的主机的组地址。
主机使用 IGMP 告诉多播路由器他们想要加入多播组,然后多播路由器将开始向请求此的主机网络发送该组的多播流量。
现代交换机将使用 IGMP 侦听来确定哪些交换机端口有主机请求加入特定多播组,并且它们只会将该多播组的流量发送到主机请求加入多播组的交换机端口。
Linux 本身不支持多播路由,您需要向 Linux 设备添加一些内容以支持多播路由。参考下图:
当组播源开始发送组播组的组播流量时,交换机可能没有看到任何加入组播组的 IGMP 请求,因此该组的组播流量无处可去。
当同一交换机上的其中一台 PC 想要加入组播组时,它会发送 IGMP 加入消息,交换机将侦听该消息并将组播流量发送到请求 PC 连接的端口。
如果 Linux 路由器另一端的 PC 想要加入多播组,那是不走运的,因为多播流量没有流向 Linux 路由器的那一侧。Linux 路由器甚至没有加入多播组,因此交换机从不向它发送多播流量。
当您在路由器上运行组播路由时,路由器会响应主机的 IGMP 请求,交换机就会知道它是组播路由器,并将组播流量发送到组播路由器连接的交换机端口。简单地说,路由器不会将多播流量发送到另一个接口,除非另一个接口上有一个活动的接收器(这取决于多播版本,例如,PIM-DM 将开始发送,但如果没有看到 IGMP 请求,则会退回) .
在路由器上启用多播路由后,连接到另一个接口的 PC 将发送 IGMP 加入消息,Linux 路由器将开始向该接口发送请求组的多播流量。交换机将监听请求,并将组播流量发送到请求加入组播组的 PC 所连接的交换机端口。
如果您需要通过多个路由器进行路由,则情况会变得更加复杂。IGMP 用于主机和本地组播路由器之间。PIM(或其他一些多播路由协议)用于多播路由器之间。
这一切都可以防止多播流量到达不需要的地方。
Linux 有附加组件可以帮助它正确处理 IGMP 和多播路由。
归档时间: |
|
查看次数: |
55012 次 |
最近记录: |