Linux核心VPN實現源碼分析(二)

來源:互聯網
上載者:User
2.  IPIP協議





    Linux
2.6定義
了一種新的協議類型
--即本章講解的IPIP

IPPROTO_IPIP

,其主要實現主要基於兩個檔案
new_tunnel.c

ipip.c。現在開始分析源碼。



 

 

    IPIP
模組載入與卸載。

static int __init ipip_init(void)<br />{<br />int err;<br />printk(banner);<br />if (xfrm4_tunnel_register(&ipip_handler, AF_INET)) {<br />printk(KERN_INFO "ipip init: can't register tunnel/n");<br />return -EAGAIN;<br />}<br />err = register_pernet_gen_device(&ipip_net_id, &ipip_net_ops);<br />if (err)<br />xfrm4_tunnel_deregister(&ipip_handler, AF_INET);<br />return err;<br />}<br />

    首先是將ipip協議使用

xfrm4_tunnel_register

按照ip協議類型和優先順序加入到ip隧道中,然後在函數內部調用register_pernet_gen_device()函數來初始化全域的init_net網路空間結構。

    可以看到他向register_pernet_gen_device傳遞了二個參數結構ipip_net_id和ipip_net_ops

static struct pernet_operations ipip_net_ops = {<br />.init = ipip_init_net,<br />.exit = ipip_exit_net,<br />};

   我們再看看register_pernet_gen_device是如何?的。

int register_pernet_gen_device(int *id, struct pernet_operations *ops)<br />{<br />int error;<br />mutex_lock(&net_mutex);<br />again:<br />error = ida_get_new_above(&net_generic_ids, 1, id);<br />if (error) {<br />if (error == -EAGAIN) {<br />ida_pre_get(&net_generic_ids, GFP_KERNEL);<br />goto again;<br />}<br />goto out;<br />}<br />error = register_pernet_operations(&pernet_list, ops);<br />if (error)<br />ida_remove(&net_generic_ids, *id);<br />else if (first_device == &pernet_list)<br />first_device = &ops->list;<br />out:<br />mutex_unlock(&net_mutex);<br />return error;<br />

    首先判斷ipip_net_ops的init鉤子是否鏈入了,我們看到上面他的結構中是ipip_init_net函數,那麼就要進一步調用這個函數初始化我們這裡的init_net網路命名空間。

    static int ipip_init_net(struct net *net)<br />{<br />int err;<br />struct ipip_net *ipn;<br />err = -ENOMEM;<br />ipn = kzalloc(sizeof(struct ipip_net), GFP_KERNEL);<br />if (ipn == NULL)<br />goto err_alloc;<br />err = net_assign_generic(net, ipip_net_id, ipn);<br />if (err < 0)<br />goto err_assign;<br />ipn->tunnels[0] = ipn->tunnels_wc;<br />ipn->tunnels[1] = ipn->tunnels_l;<br />ipn->tunnels[2] = ipn->tunnels_r;<br />ipn->tunnels[3] = ipn->tunnels_r_l;<br />ipn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel),<br /> "tunl0",<br /> ipip_tunnel_setup);<br />if (!ipn->fb_tunnel_dev) {<br />err = -ENOMEM;<br />goto err_alloc_dev;<br />}<br />dev_net_set(ipn->fb_tunnel_dev, net);<br />ipip_fb_tunnel_init(ipn->fb_tunnel_dev);<br />if ((err = register_netdev(ipn->fb_tunnel_dev)))<br />goto err_reg_dev;<br />return 0;<br />err_reg_dev:<br />free_netdev(ipn->fb_tunnel_dev);<br />err_alloc_dev:<br />/* nothing */<br />err_assign:<br />kfree(ipn);<br />err_alloc:<br />return err;<br />} 

    初始化網路裝置參數,並註冊網路裝置,至此,初始化過程完畢。

    卸載網路裝置恰恰即上述過程的逆過程。

static void ipip_exit_net(struct net *net)<br />{<br />struct ipip_net *ipn;<br />ipn = net_generic(net, ipip_net_id);<br />rtnl_lock();<br />ipip_destroy_tunnels(ipn);<br />unregister_netdevice(ipn->fb_tunnel_dev);<br />rtnl_unlock();<br />kfree(ipn);<br />}




 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.