作者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