我有 Ubuntu 16.04 LTS 和 hwe 内核 4.13.0-39-generic。我在默认网络命名空间中配置 veth 对,如下所示:
$ sudo ip link add h1-eth0 type veth peer name h2-eth0
$ sudo ip link set dev h1-eth0 up
$ sudo ip link set dev h2-eth0 up
$ sudo ip addr add 10.0.0.1/24 dev h1-eth0
$ sudo ip addr add 10.0.0.2/24 dev h2-eth0
这是我在上述配置后得到的设置:
$ ifconfig
...
h1-eth0 Link encap:Ethernet HWaddr ea:ee:1e:bb:66:55
inet addr:10.0.0.1 Bcast:0.0.0.0 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
...
h2-eth0 Link encap:Ethernet HWaddr ba:aa:99:77:ff:78
inet addr:10.0.0.2 Bcast:0.0.0.0 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
...
$ ip route show
10.0.0.0/24 dev h1-eth0 proto kernel scope link src 10.0.0.1
10.0.0.0/24 dev h2-eth0 proto kernel scope link src 10.0.0.2
...
现在我可以从一个接口 ping 另一个接口,如下所示:
$ ping -I 10.0.0.1 -c1 10.0.0.2
PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 : 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.046 ms
--- 10.0.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.046/0.046/0.046/0.000 ms
但第一个问题是,当我尝试使用接口名称而不是 IP 地址进行 ping 操作时,ping 失败:
$ ping -I h1-eth0 -c1 10.0.0.2
PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 h1-eth0: 56(84) bytes of data.
From 10.0.0.1 icmp_seq=1 Destination Host Unreachable
--- 10.0.0.2 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
如果 h1-eth0 的 IP 地址为 10.0.0.1,这怎么会成为问题呢?
我认为第二个问题是相关的。我将接口配置如下:
$ sudo tc qdisc add dev h1-eth0 root netem delay 60ms
$ sudo tc qdisc add dev h2-eth0 root netem delay 60ms
$ tc qdisc show
qdisc netem 8006: dev h2-eth0 root refcnt 2 limit 1000 delay 60.0ms
qdisc netem 8005: dev h1-eth0 root refcnt 2 limit 1000 delay 60.0ms
现在我再次 ping 延迟:
$ ping -I 10.0.0.1 -c4 10.0.0.2
PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 : 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.033 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.034 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.059 ms
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=0.027 ms
--- 10.0.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3063ms
rtt min/avg/max/mdev = 0.027/0.038/0.059/0.013 ms
并且可以看出rtt并不是预期的60ms*2=120ms。所以看起来 tc qdisc netem 不适用于我的接口。
总的来说,我发现我的配置在某种程度上被破坏了。
答案1
我在下面回答我自己的问题。
最简单的规避(我的方法):将 veth 对之一放入另一个网络命名空间。我们就这样称呼它吧test
。
$ sudo ip netns add test
$ sudo ip link add h1-eth0 type veth peer name h2-eth0 netns test
$ sudo ip link set dev h1-eth0 up
$ sudo ip netns exec test ip link set dev h2-eth0 up
$ sudo ip addr add 10.0.0.1/24 dev h1-eth0
$ sudo ip netns exec test ip addr add 10.0.0.2/24 dev h2-eth0
$ sudo tc qdisc add dev h1-eth0 root netem delay 60ms
$ sudo ip netns exec test tc qdisc add dev h2-eth0 root netem delay 60ms
现在我们检查:
$ ping -I h1-eth0 -c1 10.0.0.2
PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 h1-eth0: 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=120 ms
--- 10.0.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 120.056/120.056/120.056/0.000 ms
$ sudo ip netns exec test ping -I h2-eth0 -c1 10.0.0.1
PING 10.0.0.1 (10.0.0.1) from 10.0.0.2 h2-eth0: 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=120 ms
--- 10.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 120.146/120.146/120.146/0.000 ms
其他方法
我发现我的问题已经被提出但还没有得到回答:https://serverfault.com/questions/585246/network-level-of-veth-doesnt-respond-to-arp。从那里我们可以看出问题出在 ARP 上。
这里提出了与 ARP 问题相关的问题如果请求的 IP 地址与另一个(禁用的)接口关联,Linux 不会回复 ARP 请求消息话题发起者得到了一些解释,但问题仍然没有解决。
问题在于,地址 10.0.0.1 和 10.0.0.2 不仅出现在主路由表中,而且出现在本地路由表中,并且本地路由表的优先级高于主路由表。下面是我的问题中的初始设置的表格,即不将 veth 对的一端放入另一个网络命名空间test
:
$ ip route show table local
broadcast 10.0.0.0 dev h1-eth0 proto kernel scope link src 10.0.0.1
broadcast 10.0.0.0 dev h2-eth0 proto kernel scope link src 10.0.0.2
local 10.0.0.1 dev h1-eth0 proto kernel scope host src 10.0.0.1
local 10.0.0.2 dev h2-eth0 proto kernel scope host src 10.0.0.2
broadcast 10.0.0.255 dev h1-eth0 proto kernel scope link src 10.0.0.1
broadcast 10.0.0.255 dev h2-eth0 proto kernel scope link src 10.0.0.2
...
$ ip route show table main
10.0.0.0/24 dev h1-eth0 proto kernel scope link src 10.0.0.1
10.0.0.0/24 dev h2-eth0 proto kernel scope link src 10.0.0.2
...
当 veth 对的一端位于另一个网络命名空间中时,我们不会出现两个地址同时放入本地路由表中的情况。所以,这可能就是为什么我们没有这样的问题。我尝试从本地路由表中删除地址(仅删除其中一个或两者 - 以不同的组合),但它没有帮助。总的来说,我不完全了解情况,所以我将坚持将 veth 对的末端设置到不同的网络命名空间中。更重要的是,据我所知,这就是 veth 对的主要使用方式。