Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79d17604 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by David S. Miller
Browse files

[TUN]: Introduce the tun_net structure and init/exit net ops.



This is the first step in making tuntap devices work in net 
namespaces. The structure mentioned is pointed by generic
net pointer with tun_net_id id, and tun driver fills one on 
its load. It will contain only the tun devices list.

So declare this structure and introduce net init and exit hooks.

Signed-off-by: default avatarPavel Emelyanov <xemul@openvz.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 17515408
Loading
Loading
Loading
Loading
+52 −1
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@
#include <linux/if_tun.h>
#include <linux/crc32.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>

#include <asm/system.h>
#include <asm/uaccess.h>
@@ -106,6 +107,11 @@ struct tun_struct {

/* Network device part of the driver */

static unsigned int tun_net_id;
struct tun_net {
	struct list_head dev_list;
};

static LIST_HEAD(tun_dev_list);
static const struct ethtool_ops tun_ethtool_ops;

@@ -909,6 +915,37 @@ static const struct ethtool_ops tun_ethtool_ops = {
	.set_rx_csum	= tun_set_rx_csum
};

static int tun_init_net(struct net *net)
{
	struct tun_net *tn;

	tn = kmalloc(sizeof(*tn), GFP_KERNEL);
	if (tn == NULL)
		return -ENOMEM;

	INIT_LIST_HEAD(&tn->dev_list);

	if (net_assign_generic(net, tun_net_id, tn)) {
		kfree(tn);
		return -ENOMEM;
	}

	return 0;
}

static void tun_exit_net(struct net *net)
{
	struct tun_net *tn;

	tn = net_generic(net, tun_net_id);
	kfree(tn);
}

static struct pernet_operations tun_net_ops = {
	.init = tun_init_net,
	.exit = tun_exit_net,
};

static int __init tun_init(void)
{
	int ret = 0;
@@ -916,9 +953,22 @@ static int __init tun_init(void)
	printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
	printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT);

	ret = register_pernet_gen_device(&tun_net_id, &tun_net_ops);
	if (ret) {
		printk(KERN_ERR "tun: Can't register pernet ops\n");
		goto err_pernet;
	}

	ret = misc_register(&tun_miscdev);
	if (ret)
	if (ret) {
		printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR);
		goto err_misc;
	}
	return 0;

err_misc:
	unregister_pernet_gen_device(tun_net_id, &tun_net_ops);
err_pernet:
	return ret;
}

@@ -935,6 +985,7 @@ static void tun_cleanup(void)
	}
	rtnl_unlock();

	unregister_pernet_gen_device(tun_net_id, &tun_net_ops);
}

module_init(tun_init);