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

发布于 2024-11-25 14:33:49 字数 2168 浏览 1 评论 0原文

尝试了所有可能的方法后,无法找到解决此问题的方法。我有一台有两个接口 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 路由。

Having tried all possible ways couldn't find a work around for this problem. I have a machine with two interfaces eth0 and eth2. I want all ff38:40:2001:dead:beef:cafe::/96 packets to go on eth2. I tried all the following but when I do ping6 ff38:40:2001:dead:beef:cafe::1 the packets always goes on eth0. Things I have tried and have not worked (i.e., packet still goes out on eth0).

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

My routing table is

[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

However, ping6 ff38:40:2001:dead:beef:cafe::1 -I eth2 work just fine. Moreover, I see this problem only on Linux machines (MAC is fine).

[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

Perhaps the problem has to do with the fact that there is a ff00::/8 for eth0. How do I overrule that route. I am not able to delete ff00::/8 route as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

感性 2024-12-02 14:33:49

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

背景

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 路由。

这在某种程度上与本地表的语义一致,因为它是直接通过设备路由的。感觉不太对(考虑到自动管理和“你不应该看这个表”),但这是我找到的最好的解决方案。

I'm not entirely convinced my solution is correct, but I can at least shed a little more light on what is going on.

Background

Linux actually has multiple routing tables, and they are searched one at a time in a specific priority order until a table with a matching route is found. You can optionally search some of the routing tables based on source address or protocol; see the ip-rule(8) man page.

The trouble is the "local" routing table, which has priority 0, the highest possible. The "local" table is populated automatically by the kernel and holds "obvious" interface and broadcast routes. For IPv6 under Linux, this apparently includes the entire multicast block.

The Problem

I'm going to be using the iproute2 tool rather than the more traditional route, because it will show me everything I need to know.

On my Linux box:

$ 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 

...And my multicast packets for ff15::1 (5==site-local, >link-local) end up on eth0, because the "local" routing table matches first and overrides the "main" table, even though the "main" table has a more specific route. This overriding behavior is correct in the greater scheme of policy routing, but the choice of auto-adding ff00::/8 to the local table is questionable to me.

My Solution

I don't have enough experience to know if this is a good idea, but:

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

and now my ff15::1 packets are routed through eth1.

This agrees somewhat with the semantics of the local table, in that it's routed directly through a device. It doesn't feel exactly right (considering automatic management and "you shouldn't have to look at this table"), but it's the best solution I've found.

乖不如嘢 2024-12-02 14:33:49

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

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

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

Multicast is inherently a local link "broadcast". As such you must always indicate the zone or network interface it is sent to. There is no routing.
If you have multiple interfaces, you should send it out to multiple interfaces.
The way to do it is: ping(6) ip%zone .
Now on that same network might be a router that receives the packets and might forward it to another zone, iff some node on the other zone has subscribed to that address, and the TTL of the packet is > 1. There are no routing tables involved in multicast routing, except on multicast routers.

Since this original question was from 2012, around that time user kernel space was fixed to make it illegal to send a multicast packet without a zone identifier.
So the ping6 in the original question would not even work.

The situation for IPv4 is dire, since it is hard to bind to a specific interface for the outgoing multicast, unless the software used was correctly implemented.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文