如何通过Linux中的特定接口发送组播数据包

问题描述 投票:6回答:2

尝试了所有可能的方法无法找到解决此问题的方法。我有一台带有两个接口eth0和eth2的机器。我想要所有ff38:40:2001:dead:beef:cafe :: / 96包继续使用eth2。我尝试了以下所有,但是当我做ping6 ff38:40:2001:dead:beef:cafe :: 1数据包总是在eth0上。我尝试过但没有工作的东西(即数据包仍然在eth0上消失)。

$> route add --inet6 ff38:40:2001:dead:beef:cafe::/96 gw 2003::100 dev eth2
$> route add --inet6 ff38:40:2001:dead:beef:cafe::/96 dev eth2
$> route add --inet6 ff38:40:2001:dead:beef:cafe::/96 metric 1 gw 2003::100 dev eth2

我的路由表是

[root@dev ~]# route --inet6  |grep eth0
fe80::/64                                   *                                       U     256    0        0 eth0
ff00::/8                                    *                                       U     256    0        0 eth0

[root@dev ~]# route --inet6  |grep eth2
2003::/64                                   *                                       U     256    68       0 eth2
fe80::/64                                   *                                       U     256    0        0 eth2
ff38:40:2001:dead:beef:cafe::/96            2003::100                               UG    1      0        0 eth2
*/0                                         fe80::c671:feff:fe14:e482               UGDA  1024   0        0 eth2
ff00::/8                                    *                                       U     256    0        0 eth2

但是,ping6 ff38:40:2001:dead:beef:cafe :: 1 -I eth2工作得很好。而且,我只在Linux机器上看到这个问题(MAC很好)。

[root@dev ~]# ping6 ff38:40:2001:dead:beef:cafe::1 -I eth2
PING ff38:40:2001:dead:beef:cafe::1(ff38:40:2001:dead:beef:cafe:0:1) from cal eth2: 56 data bytes
64 bytes from 2012::1: icmp_seq=0 ttl=253 time=19.1 ms
64 bytes from 2012::1: icmp_seq=1 ttl=253 time=2.16 ms
64 bytes from 2012::1: icmp_seq=2 ttl=253 time=2.14 ms
64 bytes from 2012::1: icmp_seq=3 ttl=253 time=2.26 ms
64 bytes from 2012::1: icmp_seq=4 ttl=253 time=2.08 ms
64 bytes from 2012::1: icmp_seq=5 ttl=253 time=2.15 ms

root@dev ~]# uname -a
Linux 2.6.18-194.el5 #1 SMP Tue Mar 16 21:52:39 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux

也许这个问题与eth0的ff00 :: / 8这个事实有关。我该如何否决这条路线。我也无法删除ff00 :: / 8路由。

linux routing ipv6 multicast
2个回答
13
投票

我并不完全相信我的解决方案是正确的,但我至少可以对正在发生的事情有所了解。

背景

Linux实际上有多个路由表,它们以特定的优先级顺序一次搜索一个,直到找到具有匹配路由的表。您可以选择根据源地址或协议搜索某些路由表;请参阅ip-rule(8)手册页。

问题是“本地”路由表,其优先级为0,可能性最高。 “本地”表由内核自动填充,并保存“明显的”接口和广播路由。对于Linux下的IPv6,这显然包括整个多播块。

问题

我将使用iproute2工具而不是更传统的route,因为它将向我展示我需要知道的一切。

在我的Linux机器上:

$ ip -6 route show table local
local ::1 via :: dev lo  proto none  metric 0 
local fe80::213:a9ff:fe91:5bcb via :: dev lo  proto none  metric 0 
local fe80::250:b6ff:fe44:37d1 via :: dev lo  proto none  metric 0 
ff00::/8 dev eth0  metric 256 
ff00::/8 dev eth1  metric 256

$ ip -6 route show table main
fe80::/64 dev eth0  proto kernel  metric 256 
fe80::/64 dev eth1  proto kernel  metric 256 
ff15::/16 dev eth1  metric 1024
ff00::/8 dev eth1  metric 1024 

$ ip -6 rule show
0:      from all lookup local 
32766:  from all lookup main 

...我的ff15 :: 1(5 == site-local,> link-local)的组播数据包最终在eth0上,因为“本地”路由表首先匹配并覆盖“主”表,即使“主”表有更具体的路线。在更大的策略路由方案中,这种重写行为是正确的,但是对本地表自动添加ff00 :: / 8的选择对我来说是个问题。

我的解决方案

我没有足够的经验知道这是不是一个好主意,但是:

# ip -6 route add ff15::/16 dev eth1 table local

现在我的ff15 :: 1数据包通过eth1路由。

这与本地表的语义有些一致,因为它直接通过设备进行路由。它感觉不完全正确(考虑自动管理和“你不应该看这个表”),但这是我发现的最佳解决方案。


0
投票

多播本质上是本地链接“广播”。因此,您必须始终指示发送到的区域或网络接口。没有路由。如果您有多个接口,则应将其发送到多个接口。这样做的方法是:ping(6)ip%zone。现在在同一网络上可能是一个接收数据包并可能将其转发到另一个区域的路由器,如果另一个区域上的某个节点已订阅该地址,并且该数据包的TTL> 1.没有涉及路由表在组播路由中,除了组播路由器。

由于这个原始问题是从2012年开始的,因此大约在那个时候用户内核空间被修复,使得发送没有区域标识符的组播数据包是非法的。所以原问题中的ping6甚至不起作用。

IPv4的情况很糟糕,因为除非正确实现所使用的软件,否则很难绑定到传出多播的特定接口。

© www.soinside.com 2019 - 2024. All rights reserved.