Skip to content
Snippets Groups Projects
ipip.c 26.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • 		int h;
    		for (h = 0; h < HASH_SIZE; h++) {
    
    Eric Dumazet's avatar
    Eric Dumazet committed
    			struct ip_tunnel *t;
    
    Eric Dumazet's avatar
    Eric Dumazet committed
    			t = rtnl_dereference(ipn->tunnels[prio][h]);
    
    			while (t != NULL) {
    				unregister_netdevice_queue(t->dev, head);
    
    Eric Dumazet's avatar
    Eric Dumazet committed
    				t = rtnl_dereference(t->next);
    
    static int __net_init ipip_init_net(struct net *net)
    
    	struct ipip_net *ipn = net_generic(net, ipip_net_id);
    
    	struct ip_tunnel *t;
    
    	ipn->tunnels[0] = ipn->tunnels_wc;
    	ipn->tunnels[1] = ipn->tunnels_l;
    	ipn->tunnels[2] = ipn->tunnels_r;
    	ipn->tunnels[3] = ipn->tunnels_r_l;
    
    
    	ipn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel),
    					   "tunl0",
    					   ipip_tunnel_setup);
    	if (!ipn->fb_tunnel_dev) {
    		err = -ENOMEM;
    		goto err_alloc_dev;
    	}
    
    	dev_net_set(ipn->fb_tunnel_dev, net);
    
    	err = ipip_fb_tunnel_init(ipn->fb_tunnel_dev);
    	if (err)
    		goto err_reg_dev;
    
    
    	if ((err = register_netdev(ipn->fb_tunnel_dev)))
    		goto err_reg_dev;
    
    
    	t = netdev_priv(ipn->fb_tunnel_dev);
    
    	strcpy(t->parms.name, ipn->fb_tunnel_dev->name);
    
    	ipip_dev_free(ipn->fb_tunnel_dev);
    
    err_alloc_dev:
    	/* nothing */
    
    static void __net_exit ipip_exit_net(struct net *net)
    
    	struct ipip_net *ipn = net_generic(net, ipip_net_id);
    
    	LIST_HEAD(list);
    
    	ipip_destroy_tunnels(ipn, &list);
    	unregister_netdevice_queue(ipn->fb_tunnel_dev, &list);
    	unregister_netdevice_many(&list);
    
    }
    
    static struct pernet_operations ipip_net_ops = {
    	.init = ipip_init_net,
    	.exit = ipip_exit_net,
    
    	.id   = &ipip_net_id,
    	.size = sizeof(struct ipip_net),
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    static int __init ipip_init(void)
    {
    	int err;
    
    	printk(banner);
    
    
    	err = register_pernet_device(&ipip_net_ops);
    	if (err < 0)
    		return err;
    	err = xfrm4_tunnel_register(&ipip_handler, AF_INET);
    	if (err < 0) {
    
    		pr_info("%s: can't register tunnel\n", __func__);
    
    		goto xfrm_tunnel_failed;
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	}
    
    	err = rtnl_link_register(&ipip_link_ops);
    	if (err < 0)
    		goto rtnl_link_failed;
    
    out:
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	return err;
    
    
    rtnl_link_failed:
    	xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
    xfrm_tunnel_failed:
    	unregister_pernet_device(&ipip_net_ops);
    	goto out;
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    static void __exit ipip_fini(void)
    {
    
    	rtnl_link_unregister(&ipip_link_ops);
    
    	if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET))
    
    		pr_info("%s: can't deregister tunnel\n", __func__);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    
    
    	unregister_pernet_device(&ipip_net_ops);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    module_init(ipip_init);
    module_exit(ipip_fini);
    MODULE_LICENSE("GPL");