Has*_*ell 2 linux routing bridge iproute2 policy-routing
我正在尝试了解 linux 桥接和本地 ip 规则,
我的 linux 笔记本电脑上有以下拓扑。
br0
___________|__________
| |
|tap0 tap1|
|________Application_______|
Run Code Online (Sandbox Code Playgroud)
上面的应用程序正在创建 2 个 tap 接口 tap0 和 tap1
我创建了桥接器并将抽头接口插入桥接器:
brctl addif br0 tap0
brctl addif br0 tap1
Run Code Online (Sandbox Code Playgroud)
为了 ping 工作,我需要向接口添加 ip 地址,所以我添加192.168.13.1 to tap0
和192.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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
网桥似乎也学习了 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
Run Code Online (Sandbox Code Playgroud)
我当前的本地路由表:
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
Run Code Online (Sandbox Code Playgroud)
我有一种感觉,路由可能不会在这里出现:因为这是一个第 2 层广播域。但由于我不熟悉 linux 桥接,我需要一些建议才能继续。
我们如何使tap0 和tap1 之间的ping 工作。
谢谢纳扬
我认为您没有掌握tun/tap interfaces的作用和用途是什么,这就是您出现问题的原因。让我解释。
考虑tap0中接口为虚拟线的与两侧的端:可见侧:tap0中,并且导线的不可见侧中的应用:这种无形的一侧具有由应用完全处理。应用程序将接收以太网帧作为在文件描述符上读取的数据有效负载,如果需要,将此数据解码为以太网(因为它处于 Tap 模式),然后解码为 ARP 或 IP,然后将对任何需要的事件做出反应。简而言之,您的应用程序需要 TCP/IP 网络堆栈,才能响应 ping。
使用 tun/tap 设备的此类应用程序的示例是openvpn或 QEMU+VM+OS 的组合(QEMU 在这里将这些数据负载呈现给 VM 操作系统的网络设备驱动程序,就像该驱动程序从实际网络设备看到的一样)。
当您将tap0和tap1 绑定到网桥时,它们将成为网桥端口:暗示它们不应接收 IP(为 24 端口交换机的每个端口分配一个 IP 是否有意义?):这些 IP 大多被忽略,除了作为属于主机的 IP:因此将具有本地作用域的路由添加到本地路由表中。您可以将这些 IP 添加到lo环回接口,结果相同。除此之外,没有任何路由可以与这些接口桥接端口一起使用,现在重要的是它们的主br0。
您应该做的是在网桥本身上添加一个 IP(然后路由将使用br0接口),或者您可以创建一个veth对,将一侧绑定到网桥,然后在另一侧添加一个 IP:路由将使用带有 IP的veth接口(并且让网桥没有 IP,这样更干净,恕我直言)。
现在剩下的部分完全取决于您的应用程序:它必须自己处理那些 192.168.13.1 和 192.168.13.2 IP,包括在回复 ICMP 回声请求之前首先回复它们的 ARP 请求。
如果您现在发现应用程序的作用不仅仅是创建 tun/tap 接口,那么您应该忘记使用应用程序和 tun/tap 接口:使用根据需要复制尽可能多的网络堆栈的网络命名空间,在需要的地方创建网桥和veth接口跨越这些命名空间。都可以用ip netns
和来测试。ip link
add ... type veth ...
以下是使用网桥和veth接口与网络命名空间的教程前 3 部分的一些链接(可惜它们不使用ip netns
,这更容易完成工作):
在未命名的 Linux 网络命名空间中使用 veth-devices、Linux 网桥和 VLAN 的乐趣 – I II III