如何找出網路介面丟棄數據包的原因?
Linux 上有沒有辦法獲取有關數據包被丟棄的各種原因的統計資訊?
在多個伺服器上的所有網路介面 (openSUSE 12.3) 上,
ifconfig
並netstat -i
在接收時報告丟棄的數據包。當我執行 atcpdump
時,丟棄的數據包數量停止增加,這意味著介面隊列未滿並丟棄數據。所以發生這種情況肯定有其他原因(例如收到多播pkts,而介面不是該多播組的一部分)。我在哪裡可以找到這樣的資訊?(/proc?/sys?一些日誌?)
統計資訊範例(合併 /sys/class/net/<dev>/statistics 和 ethtool 輸出):
alloc_rx_buff_failed: 0 collisions: 0 dropped_smbus: 0 multicast: 1644 rx_align_errors: 0 rx_broadcast: 23626 rx_bytes: 1897203 rx_compressed: 0 rx_crc_errors: 0 rx_csum_offload_errors: 0 rx_csum_offload_good: 0 rx_dropped: 4738 rx_errors: 0 rx_fifo_errors: 0 rx_flow_control_xoff: 0 rx_flow_control_xon: 0 rx_frame_errors: 0 rx_length_errors: 0 rx_long_byte_count: 1998731 rx_long_length_errors: 0 rx_missed_errors: 0 rx_multicast: 1644 rx_no_buffer_count: 0 rx_over_errors: 0 rx_packets: 25382 rx_short_length_errors: 0 rx_smbus: 0 tx_aborted_errors: 0 tx_abort_late_coll: 0 tx_broadcast: 7 tx_bytes: 11300 tx_carrier_errors: 0 tx_compressed: 0 tx_deferred_ok: 0 tx_dropped: 0 tx_errors: 0 tx_fifo_errors: 0 tx_flow_control_xoff: 0 tx_flow_control_xon: 0 tx_heartbeat_errors: 0 tx_multicast: 43 tx_multi_coll_ok: 0 tx_packets: 63 tx_restart_queue: 0 tx_single_coll_ok: 0 tx_smbus: 0 tx_tcp_seg_failed: 0 tx_tcp_seg_good: 0 tx_timeout_count: 0 tx_window_errors: 0
嘗試
/sys/class/net/eth0/statistics/
(即 foreth0
),它並不完美,但它通過傳輸/接收以及載波、視窗、fifo、crc、幀、長度(以及更多)類型的錯誤來分解錯誤。丟棄與“忽略”不同,
netstat
顯示介面級別的統計資訊,被更高級別(第 3 層,IP 堆棧)忽略的多播數據包不會顯示為丟棄(儘管它可能在某些情況下顯示為“過濾”網卡統計資訊)。各種解除安裝功能可能會使統計數據有些複雜。如果您有以下情況,您可以獲得更多統計資訊
ethtool
:# ethtool -S eth0 rx_packets: 60666755 tx_packets: 2206194 rx_bytes: 6630349870 tx_bytes: 815877983 rx_broadcast: 58230114 tx_broadcast: 9307 rx_multicast: 8406 tx_multicast: 17 rx_errors: 0 tx_errors: 0 tx_dropped: 0 multicast: 8406 collisions: 0 rx_length_errors: 0 rx_over_errors: 0 rx_crc_errors: 0 rx_frame_errors: 0 rx_no_buffer_count: 0 rx_missed_errors: 0 tx_aborted_errors: 0 tx_carrier_errors: 0 tx_fifo_errors: 0 tx_heartbeat_errors: 0 [...]
一些統計數據取決於 NIC 驅動程序,其確切含義也是如此。以上來自英特爾
e1000
。在查看了少數驅動程序後,有些驅動程序收集的統計資訊比其他驅動程序多得多(ethtool 可用的統計資訊往往保存在單獨的源文件中,例如drivers/net/ethernet/intel/e1000/e1000_ethtool.c
,如果您需要翻找)。
ethtool -i eth0
將顯示驅動程序詳細資訊,的輸出lspci -v
應該更詳細,雖然也有點混亂。更新 在
tg3.c
函式tg3_rx()
中,只有一個地方看起來可能帶有 atp->rx_dropped++
,但程式碼中到處都是goto
s,因此除了顯而易見的原因之外,還有其他幾個原因,即任何帶有goto drop_it
or的地方goto drop_it_no_recycle
。(請注意,drop counter 是少數幾個由驅動程序維護的計數器之一,其餘由設備本身維護。)我手頭的驅動源是3.123。我最好的猜測是這段程式碼:
if (len > (tp->dev->mtu + ETH_HLEN) && skb->protocol != htons(ETH_P_8021Q)) { dev_kfree_skb(skb); goto drop_it_no_recycle; }
檢查 MTU,可能的原因是巨型幀,或稍大的乙太網幀以允許封裝。我無法解釋為什麼
tcpdump
會改變行為,改變介面 MTU 是未知的。另請注意,tcpdump
如果啟用了TSO / LRO ,您可能會“看到”比 MTU 更大的數據包(解釋)。