[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: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
17515408a1
commit
79d1760491
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user