我有兩個透過 veth-pair 連接的 Linux 容器。在一個容器的 veth 介面上,我設定了 tc qdisc netem 延遲並將流量從它發送到另一個容器。如果我使用 tcpdump/wireshark 觀察兩側的流量,可以看到發送方和接收方的相同資料包的時間戳不會因所選延遲而有所不同。
我想更詳細地了解 libpcap 在哪一點將時間戳記放入與 tc qdisc 相對應的出口流量中。我在互聯網上搜索了方案/圖像但沒有找到。我發現了這個話題(wireshark抓包點)但它建議透過多一個容器/介面來引入一種間接。對於我的情況來說,這不是一個可能的解決方案。有沒有辦法解決這個問題,不引入額外的中間介面(即不改變拓撲),只透過在已經給定的 veth 介面處記錄,但以這樣的方式可以看到延遲?
更新:
我太快了,所以搞錯了。下面給出的我的解決方案(與@AB答案的第一個解決方案變體相同)和@AB的IFB解決方案(我已經檢查過)都無法解決我的問題。問題在於a1-eth0
拓撲中發送方介面的傳輸佇列溢位:
[a1-br0 ---3Gbps---a1-eth0]---100Mbps---r1---100Mbps---r2
我太快了,只檢查了a1-eth0
與路由器之間的連結是否有 10 毫秒的延遲r1
。今天,我嘗試提高延遲:100ms、200ms,結果(我得到的每個資料包延遲和速率圖)對於上面的拓撲和正常拓撲開始有所不同:
[a1-eth0]---100Mbps---r1---100Mbps---r2
所以,當然,為了準確的測試,我不能有額外的連結:也不能由 Linux 橋引入,也不能由這個 IFB 引入,也不能由任何其他第三系統引入。我測試擁塞控制方案。我想在特定的拓撲中做到這一點。我不能僅僅為了繪圖而改變拓撲——我的意思是如果同時我的速率和延遲結果/圖改變。
更新2:
所以看起來解決方案已經找到,如下所示(NFLOG 解決方案)。
更新3:
這裡描述了 NFLOG 解決方案的一些缺點(大鏈路層標頭和零負載的出口 TCP 封包的錯誤 TCP 校驗和),並提出了一個更好的 NFQUEUE 解決方案,它不存在任何這些問題:零長度出口資料包的 TCP 校驗和錯誤(使用 iptables 擷取)。然而,對於我的任務(擁塞控制方案的測試),NFLOG 和 NFQUEUE 都不適合。正如同一個連結所解釋的那樣,當從內核的 iptables 捕獲資料包時,發送速率會受到限制(這就是我的理解)。因此,當您透過從介面擷取(即定期)在傳送方進行記錄時,您將獲得 2 GB 轉儲,而如果您透過從 iptables 擷取在傳送方進行記錄,您將獲得 1 GB 轉儲。大致說來。
更新4:
最後,在我的專案中,我使用我自己的答案中描述的 Linux 橋接解決方案。
答案1
根據Netfilter 和通用網路中的封包流原理圖,tcpdump 捕獲(AF_PACKET) 後出口(qdisc)。因此,您在 tcpdump 中看不到延遲是正常的:延遲在初始捕獲時已經存在。
您必須提前一步捕獲它,因此涉及第三個系統:
S1:system1,在傳出介面上執行 tcpdump
R:路由器(或網橋,根據您的方便,這不會改變任何內容),執行 qdisc netem
S2:system2,在傳入介面上執行 tcpdump
__________________ ________________ __________________
| | | | | |
| (S1) -- tcpdump -+---+- (R) -- netem -+---+- tcpdump -- (S2) |
|__________________| |________________| |__________________|
這意味著 3 個網絡堆疊涉及到,無論是真實的、虛擬機器、網路命名空間(包括ip網路,LXC,...)
或者,也可以透過使用欺騙和移動路由器(或網橋)上的每個特殊設置IFB與介面鏡像流量:允許透過一種技巧(專用於這種情況)在入口之後而不是出口處插入 netem:
_______ ______________________________________________ _______
| | | | | |
| (S1) -+---+- tcpdump -- ifb0 -- netem -- (R) -- tcpdump -+---+- (S2) |
|_______| |______________________________________________| |_______|
有一個基本的 IFB 使用範例TC 鏡像線上說明頁:
使用 ifb 接口,可以透過 sfq 實例發送入口流量:
# modprobe ifb # ip link set ifb0 up # tc qdisc add dev ifb0 root sfq # tc qdisc add dev eth0 handle ffff: ingress # tc filter add dev eth0 parent ffff: u32 \ match u32 0 0 \ action mirred egress redirect dev ifb0
只需使用內特姆在 ifb0 而不是 sfq 上(並且在非初始網路命名空間中,ip link add name ifbX type ifb
工作正常,無需 modprobe)。
這仍然需要 3 個網路堆疊才能正常運作。
使用神經網路日誌
經過 JenyaKh 的建議後,事實證明可以使用以下命令捕獲資料包tcp轉儲,前出口(因此在 qdisc 之前)然後在出口(在 qdisc 之後):透過使用iptables(或者nftables)將完整資料包記錄到 netlink 日誌基礎設施,並且仍然使用tcp轉儲,然後再使用tcp轉儲在出口接口上。這僅需要 S1 上的設定(並且不再需要路由器/網橋)。
所以與iptables在 S1 上,類似:
iptables -A OUTPUT -o eth0 -j NFLOG --nflog-group 1
可能應該添加特定的過濾器以匹配所做的測試,因為tcp轉儲過濾器僅限於 nflog 介面(wireshark 應該可以更好地處理它)。
如果需要捕獲答案(此處在不同的組中完成,因此需要額外的tcp轉儲):
iptables -A INPUT -i eth0 -j NFLOG --nflog-group 2
根據需要,也可以將它們移動到原始/輸出和原始/預路由反而。
和tcp轉儲:
# tcpdump -i nflog:1 -n -tt ...
如果使用不同的群組 (= 2) 作為輸入:
# tcpdump -i nflog:2 -n -tt ...
然後同時,像往常一樣:
# tcpdump -i eth0 -n -tt ...
答案2
更新:
所以我最終使用了這個解決方案。它存在於我的解決方案中。畢竟它對我來說效果很好。
我(主題啟動者)已經使用 Linux 橋解決了我的問題。這裡 [https://www.linuxquestions.org/questions/linux-networking-3/transferring-all-traffic-through-an-extra-interface-4175656515] 我寫道我設法使用 Linux 橋接器,但排除了這種可能性:「但這個解決方案不適合我的需求,因為實際上h1-br0 和h1-eth0 介面之間有一條額外的乙太網路連結。我需要這個東西來進行效能測量,所以我不能有任何額外的以太網鏈路。
a1
-----------------
|a1-br0---a1-eth0|---------local network
------------------
為什麼我首先拒絕該解決方案?最初,我的拓樸是:
a1---3Gbps---r1---100Mbps---r2
在連結上,r1---r2
我將網路速率設定為 100 Mbps,在連結上a1---r1
沒有速率限制。由於r1
將其連接到路由器的路由器的傳輸佇列是 1000 個資料包,因此當從 發送流量到 時r2
,我遇到了佇列溢出的影響(某些資料包被丟棄)。這沒關係。這就是現實世界中路由器隊列在出現瓶頸鏈路時溢出的情況。a1
r2
現在我做了所有這些研究來添加延遲和速率限制a1---r1
。所以我想出了這個使用 Linux 橋的解決方案。但我認為這個解決方案行不通。下面您可以看到 Linux 橋接器的新拓樸:
[a1-br0 ---3Gbps---a1-eth0]---100Mbps---r1---100Mbps---r2
所以我的解決方案的問題是我預計隊列溢位現在會出現在介面的傳輸佇列中a1-eth0
。也就是說,這和上圖中的溢出是在r1
連接到的介面處是一樣的r2
。類似地。
我不想要這種溢出。因為在正常拓撲中(不使用 Linux 橋來進行延遲測量),我們不會出現任何傳輸佇列溢位a1-eth0
:
[a1-eth0]---100Mbps---r1---100Mbps---r2
但昨天我再次使用 Linux 橋接器創建了拓撲(上面繪製的第三個拓撲),並在拓撲中啟動了從a1
到 的流量r2
。我檢查了以 500ms 間隔循環a1-eth0
呼叫命令的傳輸佇列的積壓(佇列中的當前資料包數量)以及使用類似命令的傳輸佇列的積壓。tc -s qdisc show dev a1-eth0
a1-br0
這就是我看到的a1-eth0
,我收到的訊息:
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 9461862 bytes 6393 pkt (dropped 0, overlimits 0 requeues 0)
backlog 133380b 90p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 15280534 bytes 10323 pkt (dropped 0, overlimits 0 requeues 0)
backlog 133380b 90p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 21110722 bytes 14257 pkt (dropped 0, overlimits 0 requeues 0)
backlog 118560b 80p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 26952766 bytes 18199 pkt (dropped 0, overlimits 0 requeues 0)
backlog 102258b 69p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 32788882 bytes 22137 pkt (dropped 0, overlimits 0 requeues 0)
backlog 103740b 70p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 38635372 bytes 26082 pkt (dropped 0, overlimits 0 requeues 0)
backlog 102258b 69p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 44477416 bytes 30024 pkt (dropped 0, overlimits 0 requeues 0)
backlog 102258b 69p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 50332798 bytes 33975 pkt (dropped 0, overlimits 0 requeues 0)
backlog 102258b 69p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 56157058 bytes 37905 pkt (dropped 0, overlimits 0 requeues 0)
backlog 125970b 85p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 61969532 bytes 41828 pkt (dropped 0, overlimits 0 requeues 0)
backlog 133380b 90p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 67784900 bytes 45752 pkt (dropped 0, overlimits 0 requeues 0)
backlog 133380b 90p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 73600268 bytes 49676 pkt (dropped 0, overlimits 0 requeues 0)
backlog 133380b 90p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 79415636 bytes 53600 pkt (dropped 0, overlimits 0 requeues 0)
backlog 133380b 90p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 85244342 bytes 57533 pkt (dropped 0, overlimits 0 requeues 0)
backlog 120042b 81p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 91080458 bytes 61471 pkt (dropped 0, overlimits 0 requeues 0)
backlog 102258b 69p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 96923984 bytes 65414 pkt (dropped 0, overlimits 0 requeues 0)
backlog 102258b 69p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 102761582 bytes 69353 pkt (dropped 0, overlimits 0 requeues 0)
backlog 102258b 69p requeues 0
qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
Sent 108606590 bytes 73297 pkt (dropped 0, overlimits 0 requeues 0)
backlog 103740b 70p requeues 0
這就是我看到的a1-br0
,我收到的訊息:
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc noqueue 0: root refcnt 2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
因此可以看出,沒有發生溢出a1-eth0
,實際上它「看起來」不像a1-br0
發送任何內容,儘管實際上它發送了。因此a1-bro
和之間的連結a1-eth0
不同於a1
和 router之間的連結(veth 對連結) r1
。我不知道為什麼會這樣。這很奇怪,因為我檢查過我可以將 netem 延遲設定設為a1-br0
-- 所以它就像一個正常的介面。
無論如何,我檢查了橋接解決方案是否滿足我的所有需求。我還沒有探索它為什麼有效(我的意思是我上面解釋的意義上的——隊列溢出等)。
這是我在主機上運行的命令a1
以供參考。不過,我知道如果沒有上下文,很難完全理解它們。但是,也許,它會對將來的某人有所幫助:
brctl addbr a1-br0
brctl addif a1-br0 a1-eth0
ip link set dev a1-br0 up
ip addr add dev a1-br0 11.0.0.1/30
ip addr flush dev a1-eth0
route add default gw 11.0.0.2 dev a1-br0
ifconfig a1-eth0 0.0.0.0 up
ethtool -K a1-br0 tx off sg off tso off ufo off
我應用了命令的具有 IP 位址的拓撲也顯示在此:透過 Linux 路由器的一個介面 ping 該路由器的另一個接口。這是拓樸:
------ ------ ------
| a1 | | r1 | | r2 |
| | a1-eth0-----------r1-eth0 | |r1-eth1--------------r2-eth1| |
-----(11.0.0.1/30) (11.0.0.2/30)----(11.0.0.9/30) (11.0.0.10/30)-----