netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-2.6.26 0/3][TUN]: Make TUN devices work in net namespaces (v2).
@ 2008-04-15 11:49 Pavel Emelyanov
  2008-04-15 11:51 ` [PATCH net-2.6.26 1/3][TUN]: Introduce the tun_net structure and init/exit net ops Pavel Emelyanov
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 11:49 UTC (permalink / raw)
  To: David Miller; +Cc: Maxim Krasnyansky, Linux Netdev List

Change from v1:
* reworked to use generic net pointers.

The first version was Acked-by Maxim.

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH net-2.6.26 1/3][TUN]: Introduce the tun_net structure and init/exit net ops.
  2008-04-15 11:49 [PATCH net-2.6.26 0/3][TUN]: Make TUN devices work in net namespaces (v2) Pavel Emelyanov
@ 2008-04-15 11:51 ` Pavel Emelyanov
  2008-04-15 11:53 ` [PATCH net-2.6.26 2/3][TUN]: Make the tun_dev_list per-net Pavel Emelyanov
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 11:51 UTC (permalink / raw)
  To: David Miller; +Cc: Maxim Krasnyansky, Linux Netdev List

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>

---
 drivers/net/tun.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 52 insertions(+), 1 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 5b5d875..f359d60 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -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);
-- 
1.5.3.4



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net-2.6.26 2/3][TUN]: Make the tun_dev_list per-net.
  2008-04-15 11:49 [PATCH net-2.6.26 0/3][TUN]: Make TUN devices work in net namespaces (v2) Pavel Emelyanov
  2008-04-15 11:51 ` [PATCH net-2.6.26 1/3][TUN]: Introduce the tun_net structure and init/exit net ops Pavel Emelyanov
@ 2008-04-15 11:53 ` Pavel Emelyanov
  2008-04-15 11:55 ` [PATCH net-2.6.26 3/3][TUN]: Allow to register tun devices in namespace Pavel Emelyanov
  2008-04-16  7:50 ` [PATCH net-2.6.26 0/3][TUN]: Make TUN devices work in net namespaces (v2) David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 11:53 UTC (permalink / raw)
  To: David Miller; +Cc: Maxim Krasnyansky, Linux Netdev List

Remove the static tun_dev_list and replace its occurrences in
driver with per-net one.

It is used in two places - in tun_set_iff and tun_cleanup. In 
the first case it's legal to use current net_ns. In the cleanup
call - move the loop, that unregisters all devices in net exit
hook.

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

---
 drivers/net/tun.c |   37 +++++++++++++++++++------------------
 1 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index f359d60..1e655ea 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -62,6 +62,7 @@
 #include <linux/if_ether.h>
 #include <linux/if_tun.h>
 #include <linux/crc32.h>
+#include <linux/nsproxy.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 
@@ -112,7 +113,6 @@ struct tun_net {
 	struct list_head dev_list;
 };
 
-static LIST_HEAD(tun_dev_list);
 static const struct ethtool_ops tun_ethtool_ops;
 
 /* Net device open. */
@@ -479,12 +479,12 @@ static void tun_setup(struct net_device *dev)
 	dev->destructor = free_netdev;
 }
 
-static struct tun_struct *tun_get_by_name(const char *name)
+static struct tun_struct *tun_get_by_name(struct tun_net *tn, const char *name)
 {
 	struct tun_struct *tun;
 
 	ASSERT_RTNL();
-	list_for_each_entry(tun, &tun_dev_list, list) {
+	list_for_each_entry(tun, &tn->dev_list, list) {
 		if (!strncmp(tun->dev->name, name, IFNAMSIZ))
 		    return tun;
 	}
@@ -492,13 +492,15 @@ static struct tun_struct *tun_get_by_name(const char *name)
 	return NULL;
 }
 
-static int tun_set_iff(struct file *file, struct ifreq *ifr)
+static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 {
+	struct tun_net *tn;
 	struct tun_struct *tun;
 	struct net_device *dev;
 	int err;
 
-	tun = tun_get_by_name(ifr->ifr_name);
+	tn = net_generic(net, tun_net_id);
+	tun = tun_get_by_name(tn, ifr->ifr_name);
 	if (tun) {
 		if (tun->attached)
 			return -EBUSY;
@@ -511,7 +513,7 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
 		     !capable(CAP_NET_ADMIN))
 			return -EPERM;
 	}
-	else if (__dev_get_by_name(&init_net, ifr->ifr_name))
+	else if (__dev_get_by_name(net, ifr->ifr_name))
 		return -EINVAL;
 	else {
 		char *name;
@@ -564,7 +566,7 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
 		if (err < 0)
 			goto err_free_dev;
 
-		list_add(&tun->list, &tun_dev_list);
+		list_add(&tun->list, &tn->dev_list);
 	}
 
 	DBG(KERN_INFO "%s: tun_set_iff\n", tun->dev->name);
@@ -609,7 +611,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
 		ifr.ifr_name[IFNAMSIZ-1] = '\0';
 
 		rtnl_lock();
-		err = tun_set_iff(file, &ifr);
+		err = tun_set_iff(current->nsproxy->net_ns, file, &ifr);
 		rtnl_unlock();
 
 		if (err)
@@ -936,8 +938,17 @@ static int tun_init_net(struct net *net)
 static void tun_exit_net(struct net *net)
 {
 	struct tun_net *tn;
+	struct tun_struct *tun, *nxt;
 
 	tn = net_generic(net, tun_net_id);
+
+	rtnl_lock();
+	list_for_each_entry_safe(tun, nxt, &tn->dev_list, list) {
+		DBG(KERN_INFO "%s cleaned up\n", tun->dev->name);
+		unregister_netdevice(tun->dev);
+	}
+	rtnl_unlock();
+
 	kfree(tn);
 }
 
@@ -974,17 +985,7 @@ err_pernet:
 
 static void tun_cleanup(void)
 {
-	struct tun_struct *tun, *nxt;
-
 	misc_deregister(&tun_miscdev);
-
-	rtnl_lock();
-	list_for_each_entry_safe(tun, nxt, &tun_dev_list, list) {
-		DBG(KERN_INFO "%s cleaned up\n", tun->dev->name);
-		unregister_netdevice(tun->dev);
-	}
-	rtnl_unlock();
-
 	unregister_pernet_gen_device(tun_net_id, &tun_net_ops);
 }
 
-- 
1.5.3.4



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net-2.6.26 3/3][TUN]: Allow to register tun devices in namespace.
  2008-04-15 11:49 [PATCH net-2.6.26 0/3][TUN]: Make TUN devices work in net namespaces (v2) Pavel Emelyanov
  2008-04-15 11:51 ` [PATCH net-2.6.26 1/3][TUN]: Introduce the tun_net structure and init/exit net ops Pavel Emelyanov
  2008-04-15 11:53 ` [PATCH net-2.6.26 2/3][TUN]: Make the tun_dev_list per-net Pavel Emelyanov
@ 2008-04-15 11:55 ` Pavel Emelyanov
  2008-04-16  7:50 ` [PATCH net-2.6.26 0/3][TUN]: Make TUN devices work in net namespaces (v2) David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 11:55 UTC (permalink / raw)
  To: David Miller; +Cc: Maxim Krasnyansky, Linux Netdev List

This is basically means that a net is set for a new device, but
actually also involves two more steps:

1. mark the tun device as "local", i.e. do not allow for it to
   move across namespaces.

This is done so, since tun device is most often associated to some
file (and thus to some process) and moving the device alone is not
valid while keeping the file and the process outside. The need in 
ability to move a detached persistent device is to be investigated 
later.

2. get the tun device's net when tun becomes attached and put one
   when it becomes detached.

This is needed to handle the case when a task owning the tun dies,
but a files lives for some more time - in this case we must not
allow for net to be freed, since its exit hook will spoil that file's
private data by unregistering the tun from under tun_chr_close.

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

---
 drivers/net/tun.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 1e655ea..d91856b 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -477,6 +477,7 @@ static void tun_setup(struct net_device *dev)
 	dev->stop = tun_net_close;
 	dev->ethtool_ops = &tun_ethtool_ops;
 	dev->destructor = free_netdev;
+	dev->features |= NETIF_F_NETNS_LOCAL;
 }
 
 static struct tun_struct *tun_get_by_name(struct tun_net *tn, const char *name)
@@ -544,6 +545,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 		if (!dev)
 			return -ENOMEM;
 
+		dev_net_set(dev, net);
 		tun = netdev_priv(dev);
 		tun->dev = dev;
 		tun->flags = flags;
@@ -583,6 +585,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 
 	file->private_data = tun;
 	tun->attached = 1;
+	get_net(dev_net(tun->dev));
 
 	strcpy(ifr->ifr_name, tun->dev->name);
 	return 0;
@@ -798,6 +801,7 @@ static int tun_chr_close(struct inode *inode, struct file *file)
 	/* Detach from net device */
 	file->private_data = NULL;
 	tun->attached = 0;
+	put_net(dev_net(tun->dev));
 
 	/* Drop read queue */
 	skb_queue_purge(&tun->readq);
-- 
1.5.3.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net-2.6.26 0/3][TUN]: Make TUN devices work in net namespaces (v2).
  2008-04-15 11:49 [PATCH net-2.6.26 0/3][TUN]: Make TUN devices work in net namespaces (v2) Pavel Emelyanov
                   ` (2 preceding siblings ...)
  2008-04-15 11:55 ` [PATCH net-2.6.26 3/3][TUN]: Allow to register tun devices in namespace Pavel Emelyanov
@ 2008-04-16  7:50 ` David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2008-04-16  7:50 UTC (permalink / raw)
  To: xemul; +Cc: maxk, netdev

From: Pavel Emelyanov <xemul@openvz.org>
Date: Tue, 15 Apr 2008 15:49:58 +0400

> Change from v1:
> * reworked to use generic net pointers.
> 
> The first version was Acked-by Maxim.
> 
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

All applied, thanks Pavel.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-04-16  7:50 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-15 11:49 [PATCH net-2.6.26 0/3][TUN]: Make TUN devices work in net namespaces (v2) Pavel Emelyanov
2008-04-15 11:51 ` [PATCH net-2.6.26 1/3][TUN]: Introduce the tun_net structure and init/exit net ops Pavel Emelyanov
2008-04-15 11:53 ` [PATCH net-2.6.26 2/3][TUN]: Make the tun_dev_list per-net Pavel Emelyanov
2008-04-15 11:55 ` [PATCH net-2.6.26 3/3][TUN]: Allow to register tun devices in namespace Pavel Emelyanov
2008-04-16  7:50 ` [PATCH net-2.6.26 0/3][TUN]: Make TUN devices work in net namespaces (v2) David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).