引子
本文將要描述一個我在某些linux版本以及libpcap(unix/linux平臺下網絡數據捕獲包)中發現的一個非常險惡的bug。
一個有意思的現象
一位客戶向我們報告,在一些安裝了Debian Lenny的機器上,處于主動備份模式下的網卡不能檢測到發送的數據包,邊界流量檢測器沒有任何圖形顯示。我在公司里找了幾臺與客戶硬件配置一樣的機器,開始對問題展開調查。
首先,我從自己的筆記本ping目標機器。接著,我在目標機器上使用tcpdump嗅探(sniff 竊聽網絡上流經的數據包)綁定接口收到的ICMP包。
% sudo tcpdump -i bond0 dst 172.16.209.136 and proto 1 12:57:26.275660 IP 172.16.209.1 > 172.16.209.136: ICMP echo request, id 62831, seq 54, length 64 12:57:27.275731 IP 172.16.209.1 > 172.16.209.136: ICMP echo request, id 62831, seq 55, length 64 ^C 2 packets captured 2 packets received by filter 0 packets dropped by kernel |
看來一切正常,是時候開始監聽eth0了。eth0綁定的是活躍物理網卡:
% sudo tcpdump -i eth0 dst 172.16.209.136 and proto 1 ^C 0 packets captured 2 packets received by filter 0 packets dropped by kernel |
結果,bond0嗅探的結果顯示有ICMP輸入,但是eth0綁定的物理網卡沒有任何數據包輸入。這就難怪我們的監測工具沒有輸入流量顯示,因為測量儀沒有檢測到數據包!
這是什么原因呢?
設備無關層
為了調試這個問題,我首先開始檢查網絡協議棧的設備無關層,跟蹤pcap負責處理輸入數據包的相關代碼。設備驅動通過調用設備無關層.netif_receive_skb函數處理從網絡捕獲的一組數據。
查看位于net/core/dev.c文件中的netif_receive_skb函數(簡潔起見這里只摘取重要部分):
1
2
3
4
5
6
7
8
9
10
|
int netif_receive_skb( struct sk_buff *skb) { /* ... */ orig_dev = skb_bond(skb); if (!orig_dev) return NET_RX_DROP; /* ... */ |
原文轉自:http://www.anti-gravitydesign.com