Linux

使用 ip route add 將組播路由添加到多個介面

  • October 31, 2020

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

並通過 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

我最近讀到該路由已棄用/過時,我們應該使用 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 Snooping 來確定哪些交換機埠具有請求加入特定多播組的主機,並且它們只會將該多播組的流量發送到主機已請求加入多播組的交換機埠。

Linux 本身不支持多播路由,您需要在 Linux 設備中添加一些內容以支持多播路由。請參考下圖:

在此處輸入圖像描述

當組播源開始為組播組發送組播流量時,交換機可能還沒有看到任何加入組播組的 IGMP 請求,因此該組的組播流量無處可去。

當同一交換機上的一台 PC 想要加入多播組時,它會發送一條 IGMP Join 消息,交換機會監聽該消息並將多播流量發送到請求 PC 連接的埠。

如果 Linux 路由器另一端的 PC 想要加入多播組,那麼它很不走運,因為多播流量沒有流向 Linux 路由器的那一側。Linux 路由器甚至還沒有加入多播組,因此交換機永遠不會向它發送多播流量。

當你在一個路由器上執行組播路由時,路由器會響應主機的IGMP請求,交換機就會知道它是一個組播路由器,它會將組播流量發送到組播路由器所連接的交換機埠。簡單地說,路由器不會將組播流量發送到另一個介面,除非另一個介面上有一個活動接收器(這取決於組播版本,例如,PIM-DM 將開始發送,但如果沒有看到 IGMP 請求,則退出) .

在路由器上啟用多播路由後,連接到另一個介面的 PC 將發送 IGMP 加入消息,Linux 路由器將開始將請求組的多播流量發送到介面。交換機將監聽該請求,並將多播流量發送到請求加入多播組的 PC 所連接的交換機埠。

如果您需要通過多個路由器進行路由,它會變得更加複雜。IGMP 用於主機和本地多播路由器之間。PIM(或其他一些多播路由協議)用於多播路由器之間。

這一切都可以防止多播流量到達不需要的地方。

Linux 有一些附加組件可以幫助它正確處理 IGMP 和多播路由。

引用自:https://serverfault.com/questions/814259