我嘗試從 Centos 8 機器加入 IGMP 多播流,但發送 JOIN 後,沒有來自交換器的流量。
簡單連接:
MUX <-----------> cisco3850 <--------> Centos8
192.168.117.13 192.168.117.21
上游交換器(cisco Catalyst 3850)從 MUX 向 239.1.1.1:4000 饋送 MPEG-TS。
我已經嘗試過socat
我自己的程式來打開套接字,加入串流並保持套接字打開。兩者都發送相同的 IGMP 加入訊息,經wireshark確認:
Internet Group Management Protocol
[IGMP Version: 3]
Type: Membership Report (0x22)
Reserved: 00
Checksum: 0xe9fb [correct]
[Checksum Status: Good]
Reserved: 0000
Num Group Records: 1
Group Record : 239.1.1.1 Change To Exclude Mode
Record Type: Change To Exclude Mode (4)
Aux Data Len: 0
Num Src: 0
Multicast Address: 239.1.1.1
使用ip route add
我為多播群組建立到介面的路由:
224.0.0.0/4 dev eth1 scope link
225.0.0.0/8 dev eth1 scope link
239.0.0.0/8 dev eth1 scope link
並cat /proc/net/igmp
顯示該群組已加入:
cat /proc/net/igmp
Idx Device : Count Querier Group Users Timer Reporter
3 eth1 : 2 V3
030101E1 1 0:00000000 0
010000E0 1 0:00000000 0
我懷疑這是交換器的問題,而不是 Linux 的問題,但客戶(擁有交換器)說一切都很好。
我還可以在 Linux 端做什麼來調查/解決這個問題?
如果是交換器的問題怎麼辦?那裡需要配置什麼? (需向客戶解釋)
作為參考,我的連接並保持套接字打開的程式如下所示:
// Error checking omitted for brevity
fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes);
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = PF_INET;
saddr.sin_addr.s_addr = mcastAddr;
saddr.sin_port = htons(port);
bind(fd, (struct sockaddr *)&saddr, sizeof(saddr);
struct ip_mreq mcastReq;
mcastReq.imr_multiaddr.s_addr = mcastAddr;
&mcastReq.imr_interface.s_addr = interfaceAddr;
setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcastReq, sizeof(mcastReq);
答案1
最後,客戶交換器無法/不會啟動 IGMPv3,因此我們透過在/etc/sysctl.d
.
然後 JOIN 起作用了,但 Linux 沒有回應多播成員資格查詢,因此交換器在 1-2 分鐘後丟棄了流(即使我們已net.ipv4.conf.default.rp_filter
設定為零)。
事實證明,要完全停用返迴路徑驗證,我們需要將所有設定設為rp_filter
零(包括明確列出介面)
# Set IGMP Version for eth1
# Set to '2' or '3' depending on what is enabled in the switch
net.ipv4.conf.eth1.force_igmp_version = 2
# Disable source route verification
# In addition to 90-torque.conf, also explicitly set eth1 to ignore
# return path validation
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.eth1.rp_filter = 0