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

我们可以在Linux上使用loopback接口来模拟两个阶段的路由抉择,第一个阶段是走一遍PRE/POST ROUTING流程,将NAT实施完毕,第二阶段完成单纯路由转发。然而需要在Netfilter上挂钩子,以便取消关联在skb上的路由项,并且取消关联在skb上的conntrack信息,因为在第二阶段的单纯路由流程里面,,我不希望再有什么基于conntrack的动作,因此如果需要有基于conntrack的操作,务必在第一阶段内和NAT一并完成。

回过头来看loopback的实现,不是那么完美,因为像在Netfilter上挂载钩子完成的这种事完全可以在虚拟网卡的xmit操作中完成,因此有必要重新写一个虚拟网卡,之所以最终还是考虑重新写,是因为这个模块超级简单,基本可以照搬loopback.c的实现,所不同的是xmit的操作:

static netdev_tx_t nvi_xmit(struct sk_buff *skb, struct net_device *dev){ int len; //注意,我把原始的数据包入接口写在了skb的mark中了,为何能这么做呢?因为… struct net_device * real_dev = dev_get_by_index(dev_net(dev), skb->mark); skb_orphan(skb); skb->protocol = eth_type_trans(skb, real_dev); //取消关联的路由项,以便可以在ip_input的时候重新policy routing skb_dst_drop(skb); //取消conntrack,因为它的任务在第一阶段已经完成了 skb->nfct = &nf_conntrack_untracked.ct_general; skb->nfctinfo = IP_CT_NEW; nf_conntrack_get(skb->nfct);

len = skb->len; if (likely(netif_rx(skb) == NET_RX_SUCCESS)) { …//做点什么好呢?统计? } else { …//… } return NETDEV_TX_OK;}

对NVI接口的注册也非常简单:

dev = alloc_netdev(0, “nvi”, nvi_setup);

相关阅读:Linux实现基于Loopback的NVI(NAT Virtual Interface)

更多详情见请继续阅读下一页的精彩内容:

于是渐渐开始有些伤怀。

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

相关文章:

你感兴趣的文章:

标签云: