Networking

對於 veth 對,ping 無法辨識介面名稱並且 tc qdisc netem 不起作用

  • April 12, 2019

我有帶有 hwe 核心 4.13.0-39-generic 的 Ubuntu 16.04 LTS。我在預設網路命名空間中配置 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 不適用於我的介面。

所以總的來說,我看到我的配置在某種程度上被破壞了。

我在下面回答我自己的問題。

**最簡單的規避(我的方法):**將一對 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 對的主要使用方式。

引用自:https://unix.stackexchange.com/questions/511783