歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 編寫一個Linux虛擬網卡來實現類NVI

編寫一個Linux虛擬網卡來實現類NVI

日期:2017/2/28 14:43:13   编辑:Linux教程

我們可以在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);

Copyright © Linux教程網 All Rights Reserved