首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

编撰一个Linux虚拟网卡来实现类NVI

2013-10-06 
编写一个Linux虚拟网卡来实现类NVI我们可以在Linux上使用loopback接口来模拟两个阶段的路由抉择,第一个阶

编写一个Linux虚拟网卡来实现类NVI
我们可以在Linux上使用loopback接口来模拟两个阶段的路由抉择,第一个阶段是走一遍PRE/POST ROUTING流程,将NAT实施完毕,第二阶段完成单纯路由转发。然而需要在Netfilter上挂钩子,以便取消关联在skb上的路由项,并且取消关联在skb上的conntrack信息,因为在第二阶段的单纯路由流程里面,我不希望再有什么基于conntrack的动作,因此如果需要有基于conntrack的操作,务必在第一阶段内和NAT一并完成。
        回过头来看loopback的实现,不是那么完美,因为像在Netfilter上挂载钩子完成的这种事完全可以在虚拟网卡的xmit操作中完成,因此有必要重新写一个虚拟网卡,之所以最终还是考虑重新写,是因为这个模块超级简单,基本可以照搬loopback.c的实现,所不同的是xmit的操作:

int ip_output(struct sk_buff *skb){    struct net_device *orig_dev    struct net_device *dev = skb_dst(skb)->dev;    IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len);    //保存原始入网卡的dev(反正都是forward包...)    orig_dev = skb->dev    skb->dev = dev;    skb->protocol = htons(ETH_P_IP);    //在HOOK调用的时候传入indev    if (orig_dev && orig_dev->flags & IFF_LOOPBACK) {        orig_dev = NULL;    }    return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, orig_dev, dev,                ip_finish_output,                !(IPCB(skb)->flags & IPSKB_REROUTED));}
我个人觉得,对于将Linux作为路由BOX来用的人来讲,对于FORWARDING的数据包,在POSTROUTING的时候能取到数据包从哪个网卡进入,可以实施更多的控制策略,这难道不更好吗?好吧,如果非要说这样改不好,我还有更加标准的做法,那就是在conntrack结构体中注册一个新的extend,其实就是一个结构体,将原始的入网卡作为一个字段放进去,在NVI接口的xmit中,conntrack重置为nf_conntrack_untracked之前,取出这个网卡,调用eth_type_trans接口即可,这样好了吧,我没有触动Linux kernel的主协议栈,还是基于Netfilter来做扩展!事实上,Netfilter的扩展能力是无限的!

热点排行