對於 veth 對,ping 無法辨識介面名稱並且 tc qdisc netem 不起作用
我有帶有 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 對的主要使用方式。