Skip to content
Snippets Groups Projects
ipip.c 26.9 KiB
Newer Older

	for (prio = 1; prio < 4; prio++) {
		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");