带桥接器的 TAP 接口上无法 Ping 工作

带桥接器的 TAP 接口上无法 Ping 工作

我正在尝试了解 Linux 桥接和本地 IP 规则,

我的 Linux 笔记本电脑上有以下拓扑。

               br0 
     ___________|__________
     |                    |    
  |tap0                  tap1|
  |________Application_______| 

上面的应用程序正在创建 2 个 tap 接口 tap0 和 tap1

我创建了桥并将分接头接口插入桥:

brctl addif br0 tap0
brctl addif br0 tap1

为了使 ping 正常工作,我需要向接口添加 ip 地址,因此我添加192.168.13.1 to tap0192.168.13.2 to tap1

对于这两个接口,应用程序从一个接口读取并写入另一个接口。

现在如果我运行“ping 192.168.13.2 -I tap0”

PING 192.168.13.2 (192.168.13.2) from 192.168.13.1 tap0: 56(84) bytes of data.
From 192.168.13.1 icmp_seq=1 Destination Host Unreachable

tcpdump 显示无法解析 arp,因此我添加了静态 ARP 条目:

arp -i tap0 -s 192.168.13.1 62:34:58:e7:8a:3a
arp -i tap1 -s 192.168.13.2 4a:6d:fa:51:7d:2d

brctl showmacs br0
port no mac addr        is local?   ageing timer
  2 4a:6d:fa:51:7d:2d   yes        0.00
  2 4a:6d:fa:51:7d:2d   yes        0.00
  1 62:34:58:e7:8a:3a   yes        0.00
  1 62:34:58:e7:8a:3a   yes        0.00

网桥似乎也已经获知了 MAC 地址。

但是,应用程序和 tcpdump 仍然收到 42 字节的数据包,显示 ARP 数据包尚未解析,并且 ping 给出主机不可达的消息。

我当前的路由表是:

ip route ls table main
169.254.0.0/16 dev virbr0  scope link  metric 1000 linkdown 
192.168.13.0/24 dev tap1  proto kernel  scope link  src 192.168.13.2 
192.168.13.0/24 dev tap0  proto kernel  scope link  src 192.168.13.1 
192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 linkdown 

我当前的本地路由表:

broadcast 192.168.13.0 dev tap1  proto kernel  scope link  src 192.168.13.2 
broadcast 192.168.13.0 dev tap0  proto kernel  scope link  src 192.168.13.1 
local 192.168.13.1 dev tap0  proto kernel  scope host  src 192.168.13.1 
local 192.168.13.2 dev tap1  proto kernel  scope host  src 192.168.13.2 
broadcast 192.168.13.255 dev tap1  proto kernel  scope link  src 192.168.13.2 
broadcast 192.168.13.255 dev tap0  proto kernel  scope link  src 192.168.13.1 

我感觉路由可能不适合这里:因为这是一个第 2 层广播域。但由于我对 Linux 桥接不太熟悉,我需要一些建议才能继续。

我们如何才能使 tap0 和 tap1 之间能够 ping 通?

谢谢 Nayan

答案1

我认为你没有理解tun/tap 接口,这就是你遇到的问题的根源。让我来解释一下。

考虑一下tap0接口作为虚拟导线的末端,有两边:可见的一边:tap0以及电线看不见的那一面应用程序:这个不可见的方面必须完全由应用程序处理。应用程序将接收以太网帧作为在文件描述符上读取的数据有效负载,如果需要,将此数据解码为以太网(因为它处于分接模式),然后解码为 ARP 或 IP,然后对任何需要的事件做出反应。简而言之,您的应用程序需要 TCP/IP 网络堆栈,才能响应 ping。

使用 tun/tap 设备的应用程序示例包括开放VPN或者 QEMU+VM+OS 的组合(QEMU 用于将该数据有效负载呈现给 VM 操作系统的网络设备驱动程序,就像该驱动程序从实际网络设备看到的方式一样)。

当你奴役tap0点击1对于桥梁来说,它们成为桥梁端口:这是一个提示他们不应该收到 IP(为 24 端口交换机的每个端口分配一个 IP 是否有意义?):这些 IP 大多被忽略,除非作为属于主机的 IP:带有范围本地因此被添加到当地的路由表。您可以将这些 IP 添加到环回接口的结果相同。除此之外,没有路由可以使用这些接口桥接端口,现在重要的是它们的主br0

你应该做的是在桥上添加一个 IP(然后路由将使用br0接口)或者你可以创建一个韦特配对,将一端连接到网桥,并在另一端添加 IP:路由将使用韦特与其上的 IP 进行接口(并且让桥接器不带 IP,在我看来这样更干净)。

现在,剩下的部分完全取决于您的应用程序:它必须自己处理那些 192.168.13.1 和 192.168.13.2 IP,包括首先回复它们的 ARP 请求,然后再回复 ICMP 回显请求。


如果您现在发现应用程序的作用不仅仅是创建 tun/tap 接口,那么您应该忘记使用应用程序和 tun/tap 接口:使用网络命名空间根据需要复制尽可能多的网络堆栈,在需要的地方创建网桥,并且韦特这些命名空间中的接口。所有这些都可以使用ip netnsip link add ... type veth ...

以下是教程前三部分的链接,利用韦特与网络命名空间的接口(可惜他们没有使用ip netns更容易完成工作的东西):

在未命名的 Linux 网络命名空间中使用 veth 设备、Linux 网桥和 VLAN 的乐趣 –

相关内容