Linux内核未通过多播UDP数据包


35

最近,我建立了一个新的Ubuntu Server 10.04,并注意到即使加入多播组后,我的UDP服务器也不再能够看到发送到该接口的任何多播数据。我在其他两台Ubuntu 8.04.4 LTS计算机上设置了完全相同的设置,加入相同的多播组后接收数据没有问题。

以太网卡是Broadcom netXtreme II BCM5709,使用的驱动程序是:

b $ ethtool -i eth1
driver: bnx2
version: 2.0.2
firmware-version: 5.0.11 NCSI 2.0.5
bus-info: 0000:01:00.1

我正在使用smcroute管理我的多播注册。

b$ smcroute -d
b$ smcroute -j eth1 233.37.54.71

加入该组后,ip maddr显示新添加的注册。

b$ ip maddr

    1:  lo
        inet  224.0.0.1
        inet6 ff02::1
    2:  eth0
        link  33:33:ff:40:c6:ad
        link  01:00:5e:00:00:01
        link  33:33:00:00:00:01
        inet  224.0.0.1
        inet6 ff02::1:ff40:c6ad
        inet6 ff02::1
    3:  eth1
        link  01:00:5e:25:36:47
        link  01:00:5e:25:36:3e
        link  01:00:5e:25:36:3d
        link  33:33:ff:40:c6:af
        link  01:00:5e:00:00:01
        link  33:33:00:00:00:01
        inet  233.37.54.71 <------- McastGroup.
        inet  224.0.0.1
        inet6 ff02::1:ff40:c6af
        inet6 ff02::1

到目前为止,我可以看到我正在接收该多播组的数据。

b$ sudo tcpdump -i eth1 -s 65534 host 233.37.54.71
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65534 bytes
09:30:09.924337 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
09:30:09.947547 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
09:30:10.108378 IP 192.164.1.120.58866 > 233.37.54.71.15574: UDP, length 268
09:30:10.196841 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
...

我还可以确认接口正在接收mcast数据包。

b $ ethtool -S eth1 | grep mcast_pack
rx_mcast_packets: 103998
tx_mcast_packets: 33

现在是问题所在。当我尝试使用简单的ruby UDP服务器捕获流量时,我收到的数据为零!这是一个简单的服务器,它读取在端口15572上发送的数据并打印前两个字符。这适用于两个8.04.4 Ubuntu服务器,但不适用于10.04服务器。

require 'socket'
s = UDPSocket.new
s.bind("", 15572)
5.times do
  text, sender = s.recvfrom(2)
  puts text
end

如果我将用ruby制作的UDP数据包发送到localhost,则服务器会收到它并打印出前两个字符。所以我知道上面的服务器可以正常工作。

irb(main):001:0> require 'socket'
=> true
irb(main):002:0> s = UDPSocket.new
=> #<UDPSocket:0x7f3ccd6615f0>
irb(main):003:0> s.send("I2 XXX", 0, 'localhost', 15572)

当我检查协议统计信息时,我看到InMcastPkts没有增加。而在同一网络上的其他8.04服务器上,则在10秒内收到了数千个数据包。

b $ netstat -sgu ; sleep 10 ; netstat -sgu
IcmpMsg:
    InType3: 11
    OutType3: 11
Udp:
    446 packets received
    4 packets to unknown port received.
    0 packet receive errors
    461 packets sent
UdpLite:
IpExt:
    InMcastPkts: 4654 <--------- Same as below
    OutMcastPkts: 3426
    InBcastPkts: 9854
    InOctets: -1691733021
    OutOctets: 51187936
    InMcastOctets: 145207
    OutMcastOctets: 109680
    InBcastOctets: 1246341
IcmpMsg:
    InType3: 11
    OutType3: 11
Udp:
    446 packets received
    4 packets to unknown port received.
    0 packet receive errors
    461 packets sent
UdpLite:
IpExt:
    InMcastPkts: 4656  <-------------- Same as above
    OutMcastPkts: 3427
    InBcastPkts: 9854
    InOctets: -1690886265
    OutOctets: 51188788
    InMcastOctets: 145267
    OutMcastOctets: 109712
    InBcastOctets: 1246341

如果我尝试将接口强制为混杂模式,则不会发生任何变化。

在这一点上,我被困住了。我已经确认内核配置已启用多播。也许还有其他配置选项我应该检查?

b $ grep CONFIG_IP_MULTICAST /boot/config-2.6.32-23-server
CONFIG_IP_MULTICAST=y

有什么想法从这里去?


去搞清楚。我输入一个新问题,相关的算法愉快地向我展示了这个问题的存在,但没有有意义的答案。嘘:(。
VxJasonxV

我不确定我将如何奖励赏金。一位同事发现了问题,我想出了为什么会这样发生的原因。我非常乐意就如何授予赏金提出建议。
VxJasonxV 2010年

你还在吗?我有个问题要问你。
VxJasonxV 2010年

我也遇到了这个问题。亲爱的贝克汉姆,您解决了吗?

对于其他遇到此问题的人,请阅读此问题的所有答案,因为有2-3个O / S设置需要修复。我们通过改变解决了这个问题rp_filter,并/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts,然后它开始工作。
山姆·戈德堡

Answers:


35

在我们的实例中,我们的问题是通过sysctl参数解决的,这与Maciej不同。

请注意,我不代表OP(打包),我之所以出现在此帖子上是因为该问题与基本详细信息有关(用户域中没有多播流量)。

我们有一个应用程序,该应用程序从(通常)直接连接到接收服务器上的接口的设备读取发送到四个多播地址的数据,以及每个多播地址唯一的端口。

当它因未知原因神秘失败时,我们正在尝试将该软件部署在客户站点上。尝试调试该软件导致检查每个系统调用,最终它们都告诉我们相同的事情:

我们的软件需要数据,而操作系统从不提供任何数据。

多播数据包计数器增加了,tcpdump显示了到达设备箱/特定接口的流量,但是我们不能做任何事情。SELinux被禁用,iptables正在运行,但是任何表中都没有规则。

被困住了,我们过去了。

在随机浏览时,我们开始考虑sysctl处理的内核参数,但是所有记录的功能都没有特别相关,或者如果它们与多播流量有关,则启用它们。哦,ifconfig确实在功能行(启动,广播,运行,多播)中列出了“ MULTICAST”。出于好奇,我们看着/etc/sysctl.conf。“瞧,该客户的基本图片在底部添加了几行。

在我们的情况下,客户已设置net.ipv4.all.rp_filter = 1。rp_filter是路由路径过滤器,据我所知,它拒绝所有可能无法到达此框的流量。网络子网跳跃,认为是源IP被欺骗。

好吧,该服务器位于192.168.1 / 24子网中,并且用于多播流量的设备的源IP地址在10. *网络中。因此,筛选器阻止服务器对流量进行有意义的操作。

经过客户批准的几项调整;net.ipv4.eth0.rp_filter = 1而且net.ipv4.eth1.rp_filter = 0我们快乐地跑步。


2
这工作了!在rp_filter我们的10千兆网络接口被倾倒所有的UDP多播数据包。关闭过滤器可让所有液体流通。
chrisaycock 2012年

在Ubuntu接收器上通过tun设备在AMT多播上设置流传输时遇到了问题,我们可能会看到数据包通过tcpdump传递到设备,但是应用程序只是不想流式传输。这篇文章救了我们!
软件工程师

2
在Ubuntu 14.04上运行,这仅在我设置以后对我有效net.ipv4.all.rp_filter = 0。具体来说,当组播数据到达eth2时,我必须同时设置net.ipv4.eth2.rp_filter = 0net.ipv4.all.rp_filter = 0
T-鹰

4

TL / DR还请确保您的多播不是来自VLAN。tcpdump -e将有助于确定他们是否这样做。

公平地说,有人应该建立一个带有清单的页面,以防止多播到达用户领域。我已经为此苦苦挣扎了几天,自然我在网上找不到任何帮助。

我不仅可以看到中的数据包tcpdump,而且实际上可以在其他接口上接收其他生产者的其他多播数据包。我最终用来测试是否可以接收多播的命令是:

$ GRP=224.x.x.x # set me to the group
$ PORT=yyyy # set me to the receiving port
$ IFACE=mmmm # set me to the name or IP address of the interface
$ strace -f socat -  UDP4-DATAGRAM:$GRP:$PORT,ip-add-membership=$GRP:$IFACE,bind=0.0.0.0:$PORT,multicast-loop=0

这样做的原因strace是我实际上无法socat将数据包打印输出到stdout,但是在strace输出中您可以清楚地看到是否socat正在从绑定的套接字接收实际数据(否则它将是静音的,否则会经过几次初始select调用)

  • rp_filtersysctl-不适用,系统位于同一IP网络上(我将它们设置0为相同,似乎现在1是默认设置,至少对于Ubuntu而言)。
  • 防火墙/等-接收系统没有防火墙(如果数据包经过防火墙,我不认为数据包会显示在tcpdump中,但我想防火墙可能很有趣)
  • IP /多播路由和多个接口-我在正确的接口上明确加入了该组
  • 古怪的网络硬件-这是我的最后选择,但是将某些笔记本电脑更改为Intel NUC并没有帮助。这是关于我开始咀嚼肘部并将其张贴到SE的地方。
  • 在我的情况下,问题是产生这些多播数据包的专用硬件使用了VLAN。要查看这是否是您的问题,请确保在包括-e标记tcpdump,并检查vlan标签。在userland能够获取这些数据包之前,需要将接口配置为正确的VLAN。对我来说,赠品实际上是多播生产者不会ping,但甚至不会进入ARP缓存,尽管我可以清楚地看到ARP答复。

为了使其与VLAN一起运行,此链接可能对配置多播路由很有帮助。(很遗憾,我是新手,因此信誉不允许我添加答案。因此请进行此编辑。)

这是我所做的(如果需要,请使用sudo):

ip link add link eth0 name eth0_100 type vlan id 100
ip addr add 192.168.100.2/24 brd 192.168.100.255 dev eth0_100
ip link set dev eth0_100 up
ip maddr add 01:00:5e:01:01:01 dev eth0_100
route -n add -net 224.0.0.0 netmask 240.0.0.0 dev eth0_100

这样,如果为VLAN ID为100的VLAN流量创建了其他接口。VLANIP可能是不必要的。然后,为新接口配置一个多播地址(01:00:5e:01:01:01是239.1.1.1的链路层地址),所有传入的多播流量都绑定到eth0_100。我还在上面的答案中做了所有可能的步骤(检查iptables,rp_filter等)。


@Gero:添加多播路由会设置传出多播,而不是传入多播。您不应该将多播IP地址直接绑定到接口,除非您做一些时髦的事情,这通常是应用程序的工作。
Pawel Veselov

2

您可能想要尝试看看以下设置:

进程

echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

sysctl.conf

sed -i -e 's|^net.ipv4.icmp_echo_ignore_broadcasts =.*|net.ipv4.icmp_echo_ignore_broadcasts = 0|g' /etc/sysctl.conf

这些已用于在RHEL中启用多播。

您可能要确保您的防火墙允许多路复用流量。再次使用RHEL启用了以下功能:

# allow anything in on multicast addresses
-A INPUT -s 224.0.0.0/4 -j ACCEPT
-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT
# needed for multicast ping responses
-A INPUT -p icmp --icmp-type 0 -j ACCEPT

“广播”选项也适用于“多播”吗?
Raedwald

0

您是否正在使用管理型交换机?有些具有防止“广播风暴”或其他多播问题的选项,这将导致它们阻止某些类型的数据包。我建议看看您的交换机文档。


0
s.bind("", 15572)

确信 ””?为什么不使用多播IP地址进行绑定?


空主机地址通常表示“所有接口”。
VxJasonxV
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.