作者Andyleee (帕格尼尼 阿瑪迪斯)
看板LinuxDev
標題[問題] kernel mode發送自定封包問題
時間Tue Sep 20 18:50:14 2011
各位好, 我想請教一個kernel module發送封包的問題
情境如下:
1. 一台linux主機有2張分屬2個ip domain的網卡
2. 若從網卡1收到的封包, 在ip header後插上自訂protocol header, 然後從網卡2送出
3. 若從網卡2收到的封包, 在ip header後移除自訂protocol header, 然後從網卡1送出
我一開始把此機制實作在user space, 也就是開2個raw socket, 收到網卡1來的封包
就加上自訂protocol header, 然後從網卡2 raw socket送出; 收到網卡2來的封包,
就移除自訂protocol header, 然後從網卡1 raw socket送出
後來我認為把機制實作在kernel space, 應該可以加快處理速度, 所以寫了1個
net filter module, 並hook在pre_routing的位置;當module收到ip封包(sk_buff), 檢查
ip的protocol欄位, 如果是UDP/TCP, 就用alloc_skb創出一個新的sk_buff, memcpy原有
封包資料並在適當位置插上自訂protocol header, 最後呼叫
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, mskb, NULL, mskb->dst->dev, dst_output)
自網卡2送出
反之, 若module收到ip封包(sk_buff), 檢查ip的protocol欄位發現其為自訂protocol
的代表號, 就用alloc_skb創出一個新的sk_buff, 並將原有的sk_buff除了自訂header
以外的所有資料作memcpy, 最後呼叫
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, mskb, NULL, mskb->dst->dev, dst_output)
自網卡1送出, 而hook到的所有sk_buff, 因為被新的sk_buff替代, 所以我都用
NF_DROP處理
令我大失所望的是, kernel space傳輸機制不但沒有加快處理速度, 反而還可能較
user space的機制稍慢, 請問各位高手可能問提出在哪呢?是因為我每hook到一個
封包就呼叫一次alloc_skb太花時間嗎? 還是
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, mskb, NULL, mskb->dst->dev, dst_output)
的效率不好呢?
我的環境CentOS 5.5, kernel version 2.6.18
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.96.101.33
1F:→ chucklee:通常skb->data到skb->head之間會預留一小塊空間 09/24 14:25
2F:→ chucklee:如果自訂的protocol header不大 可以直接把ip header 09/24 14:26
3F:→ chucklee:往前移 直接把你的protocol寫進原本的skb裡 09/24 14:26
4F:→ chucklee:為了安全起見 可以再去改skb的底層 把需要空間留下來 09/24 14:29
※ 編輯: Andyleee 來自: 220.135.253.175 (09/25 23:24)
5F:→ Andyleee:恩我也也有想到這方法, 但header有點大似乎塞不下XD 09/25 23:25
6F:→ Andyleee:但用netfilter加速的方式請問chuck大認為理論上ok嗎? 09/25 23:26
7F:→ Andyleee:如果理論上會比較快, 我再設法尋找其變慢的原因 09/25 23:27
8F:→ chucklee:改一個參數可以把保留空間變大 SKB_PAD的樣子 09/27 11:56
9F:→ chucklee:我沒有弄netfilter的經驗 不知道速度的影響大不大 09/27 11:59
10F:→ chucklee:之前做過類似的事 是在ip_input處理完直接丟去ip_output 09/27 12:03
11F:推 hn12303158:chucklee感謝你的經驗~ 我再試試 09/27 14:25