2014-03-13 98 views
1

我在Ubuntu主機上運行3個QEMU-KVM虛擬機。每個VM都有一個virt-io nic,並通過主機操作系統中的br0橋連接。每個NIC的MTU配置爲1500.該平臺運行基於消息隊列的應用程序:一個VM作爲生產者,一個VM作爲消息隊列服務器,最後一個VM作爲消費者。QEMU-KVM客戶操作系統不尊重MTU設置

我的問題是:當訪客虛擬機變忙時,消息隊列服務器虛擬機可能偶然發送大小爲2k,4k或5k的數據包。它超過了NIC的MTU值,1500!據我所知,在發送之前,Linux IP協議棧應該將IP構件的尺寸減小到小於MTU的尺寸。爲什麼這個虛擬機在忙時發送大數據包?

下面是平臺的體系結構:

[w2: celery caller (message queue producer) ] 
    | (messages in TCP) 
    V 
[w3: rabbitmq server] 
    | (messages in TCP) 
    V 
[w4: celeryd (message queue consumer)] 

下面是屏幕在W3捕獲,MTU是1500,並用大小發送分組> 2000 screen captured at w3

下面是屏幕在W4捕獲,MTU是1500並接收大小> 2000的數據包 enter image description here

回答

2

謝謝大家,我現在找到了答案。

guest虛擬機操作系統中的virtio-NIC支持TCP分段卸載(TSO),默認情況下啓用。 NIC的TSO功能是TCP層不執行幀分段,並且分段是 由NIC驅動程序或硬件脫機執行。 TSO用於在發送大數據包並卸載TCP發送器程序的工作負載時提高性能,NIC驅動程序將在此模式下接收大數據包,並將其分段爲較小的有效負載,IP標頭和TCP標頭。這種卸載處理的好處是驅動程序可以很好地使用硬件或在分段過程中重新使用緩衝區頭緩衝區。

下面是支持TSO功能驅動程序代碼,

Atheros NIC driver source

在其發送功能,它會調用atl1c_tso_csum(),檢查發送緩衝器的標誌& SKB_GSO_TCPV4。 如果緩衝區包含SKB_GSO_TCPV4標誌,則將其分段,添加ip標頭並添加tcp標頭。

但是,virtio NIC支持TSO功能,因爲virtio NIC數據包正在發送到主機操作系統。其驅動程序的tx功能只需發送 整個數據包並實現更高的網絡帶寬。

注意:關閉來賓虛擬機中的TSO標誌後,tcpdump上不會看到大數據包。這裏是命令:

$ethtool -k eth0 
Offload parameters for eth0: 
rx-checksumming: on 
tx-checksumming: on 
scatter-gather: on 
tcp-segmentation-offload: off 
udp-fragmentation-offload: on 
generic-segmentation-offload: on 
generic-receive-offload: on 
large-receive-offload: off 
rx-vlan-offload: off 
tx-vlan-offload: off 
ntuple-filters: off 
receive-hashing: off 
$ethtool -K eth0 tso off 
$ 

文獻2: https://blogs.gnome.org/markmc/category/virtio/

+1

TSO = TCP分段卸載,而不是脫機。 – osgx

+0

我曾經遇到同樣的問題:http://stackoverflow.com/questions/2350985/length-of-captured-packets-more-than-mtu – kumar

相關問題