netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work in net namespaces.
@ 2008-04-15 13:58 Pavel Emelyanov
  2008-04-15 13:59 ` [PATCH net-2.6.26 1/7][IP6TUNNEL]: Introduce empty ip6_tnl_net structure and net ops Pavel Emelyanov
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 13:58 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List

This is the last tunnel to virtualize.

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

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

* [PATCH net-2.6.26 1/7][IP6TUNNEL]: Introduce empty ip6_tnl_net structure and net ops.
  2008-04-15 13:58 [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work in net namespaces Pavel Emelyanov
@ 2008-04-15 13:59 ` Pavel Emelyanov
  2008-04-15 14:00 ` [PATCH net-2.6.26 2/7][IP6TUNNEL]: Add (ip6_tnl_)net argument to some calls Pavel Emelyanov
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 13:59 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List

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

---
 net/ipv6/ip6_tunnel.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 61517fe..2365eb0 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -52,6 +52,8 @@
 #include <net/xfrm.h>
 #include <net/dsfield.h>
 #include <net/inet_ecn.h>
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
 
 MODULE_AUTHOR("Ville Nuorvala");
 MODULE_DESCRIPTION("IPv6 tunneling device");
@@ -78,6 +80,10 @@ static int ip6_fb_tnl_dev_init(struct net_device *dev);
 static int ip6_tnl_dev_init(struct net_device *dev);
 static void ip6_tnl_dev_setup(struct net_device *dev);
 
+static int ip6_tnl_net_id;
+struct ip6_tnl_net {
+};
+
 /* the IPv6 tunnel fallback device */
 static struct net_device *ip6_fb_tnl_dev;
 
@@ -1384,6 +1390,41 @@ static struct xfrm6_tunnel ip6ip6_handler = {
 	.priority	=	1,
 };
 
+static int ip6_tnl_init_net(struct net *net)
+{
+	int err;
+	struct ip6_tnl_net *ip6n;
+
+	err = -ENOMEM;
+	ip6n = kmalloc(sizeof(struct ip6_tnl_net), GFP_KERNEL);
+	if (ip6n == NULL)
+		goto err_alloc;
+
+	err = net_assign_generic(net, ip6_tnl_net_id, ip6n);
+	if (err < 0)
+		goto err_assign;
+
+	return 0;
+
+err_assign:
+	kfree(ip6n);
+err_alloc:
+	return err;
+}
+
+static void ip6_tnl_exit_net(struct net *net)
+{
+	struct ip6_tnl_net *ip6n;
+
+	ip6n = net_generic(net, ip6_tnl_net_id);
+	kfree(ip6n);
+}
+
+static struct pernet_operations ip6_tnl_net_ops = {
+	.init = ip6_tnl_init_net,
+	.exit = ip6_tnl_exit_net,
+};
+
 /**
  * ip6_tunnel_init - register protocol and reserve needed resources
  *
@@ -1418,7 +1459,13 @@ static int __init ip6_tunnel_init(void)
 		free_netdev(ip6_fb_tnl_dev);
 		goto fail;
 	}
+
+	err = register_pernet_gen_device(&ip6_tnl_net_id, &ip6_tnl_net_ops);
+	if (err < 0)
+		goto err_pernet;
 	return 0;
+err_pernet:
+	unregister_netdevice(ip6_fb_tnl_dev);
 fail:
 	xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6);
 unreg_ip4ip6:
@@ -1456,6 +1503,8 @@ static void __exit ip6_tunnel_cleanup(void)
 	rtnl_lock();
 	ip6_tnl_destroy_tunnels();
 	rtnl_unlock();
+
+	unregister_pernet_gen_device(ip6_tnl_net_id, &ip6_tnl_net_ops);
 }
 
 module_init(ip6_tunnel_init);
-- 
1.5.3.4


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

* [PATCH net-2.6.26 2/7][IP6TUNNEL]: Add (ip6_tnl_)net argument to some calls.
  2008-04-15 13:58 [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work in net namespaces Pavel Emelyanov
  2008-04-15 13:59 ` [PATCH net-2.6.26 1/7][IP6TUNNEL]: Introduce empty ip6_tnl_net structure and net ops Pavel Emelyanov
@ 2008-04-15 14:00 ` Pavel Emelyanov
  2008-04-15 14:02 ` [PATCH net-2.6.26 3/7][IP6TUNNEL]: Use proper net in hash-lookup functions Pavel Emelyanov
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 14:00 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List

Hashes and fallback device used in them will be per-net.

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

---
 net/ipv6/ip6_tunnel.c |   47 ++++++++++++++++++++++++++++-------------------
 1 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 2365eb0..fad1af8 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -136,7 +136,7 @@ static inline void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst)
  **/
 
 static struct ip6_tnl *
-ip6_tnl_lookup(struct in6_addr *remote, struct in6_addr *local)
+ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local)
 {
 	unsigned h0 = HASH(remote);
 	unsigned h1 = HASH(local);
@@ -166,7 +166,7 @@ ip6_tnl_lookup(struct in6_addr *remote, struct in6_addr *local)
  **/
 
 static struct ip6_tnl **
-ip6_tnl_bucket(struct ip6_tnl_parm *p)
+ip6_tnl_bucket(struct ip6_tnl_net *ip6n, struct ip6_tnl_parm *p)
 {
 	struct in6_addr *remote = &p->raddr;
 	struct in6_addr *local = &p->laddr;
@@ -186,9 +186,9 @@ ip6_tnl_bucket(struct ip6_tnl_parm *p)
  **/
 
 static void
-ip6_tnl_link(struct ip6_tnl *t)
+ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
 {
-	struct ip6_tnl **tp = ip6_tnl_bucket(&t->parms);
+	struct ip6_tnl **tp = ip6_tnl_bucket(ip6n, &t->parms);
 
 	t->next = *tp;
 	write_lock_bh(&ip6_tnl_lock);
@@ -202,11 +202,11 @@ ip6_tnl_link(struct ip6_tnl *t)
  **/
 
 static void
-ip6_tnl_unlink(struct ip6_tnl *t)
+ip6_tnl_unlink(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
 {
 	struct ip6_tnl **tp;
 
-	for (tp = ip6_tnl_bucket(&t->parms); *tp; tp = &(*tp)->next) {
+	for (tp = ip6_tnl_bucket(ip6n, &t->parms); *tp; tp = &(*tp)->next) {
 		if (t == *tp) {
 			write_lock_bh(&ip6_tnl_lock);
 			*tp = t->next;
@@ -228,12 +228,13 @@ ip6_tnl_unlink(struct ip6_tnl *t)
  *   created tunnel or NULL
  **/
 
-static struct ip6_tnl *ip6_tnl_create(struct ip6_tnl_parm *p)
+static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p)
 {
 	struct net_device *dev;
 	struct ip6_tnl *t;
 	char name[IFNAMSIZ];
 	int err;
+	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 
 	if (p->name[0])
 		strlcpy(name, p->name, IFNAMSIZ);
@@ -257,7 +258,7 @@ static struct ip6_tnl *ip6_tnl_create(struct ip6_tnl_parm *p)
 		goto failed_free;
 
 	dev_hold(dev);
-	ip6_tnl_link(t);
+	ip6_tnl_link(ip6n, t);
 	return t;
 
 failed_free:
@@ -280,20 +281,22 @@ failed:
  *   matching tunnel or NULL
  **/
 
-static struct ip6_tnl *ip6_tnl_locate(struct ip6_tnl_parm *p, int create)
+static struct ip6_tnl *ip6_tnl_locate(struct net *net,
+		struct ip6_tnl_parm *p, int create)
 {
 	struct in6_addr *remote = &p->raddr;
 	struct in6_addr *local = &p->laddr;
 	struct ip6_tnl *t;
+	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 
-	for (t = *ip6_tnl_bucket(p); t; t = t->next) {
+	for (t = *ip6_tnl_bucket(ip6n, p); t; t = t->next) {
 		if (ipv6_addr_equal(local, &t->parms.laddr) &&
 		    ipv6_addr_equal(remote, &t->parms.raddr))
 			return t;
 	}
 	if (!create)
 		return NULL;
-	return ip6_tnl_create(p);
+	return ip6_tnl_create(net, p);
 }
 
 /**
@@ -308,13 +311,15 @@ static void
 ip6_tnl_dev_uninit(struct net_device *dev)
 {
 	struct ip6_tnl *t = netdev_priv(dev);
+	struct net *net = dev_net(dev);
+	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 
 	if (dev == ip6_fb_tnl_dev) {
 		write_lock_bh(&ip6_tnl_lock);
 		tnls_wc[0] = NULL;
 		write_unlock_bh(&ip6_tnl_lock);
 	} else {
-		ip6_tnl_unlink(t);
+		ip6_tnl_unlink(ip6n, t);
 	}
 	ip6_tnl_dst_reset(t);
 	dev_put(dev);
@@ -407,7 +412,8 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
 	   processing of the error. */
 
 	read_lock(&ip6_tnl_lock);
-	if ((t = ip6_tnl_lookup(&ipv6h->daddr, &ipv6h->saddr)) == NULL)
+	if ((t = ip6_tnl_lookup(&init_net, &ipv6h->daddr,
+					&ipv6h->saddr)) == NULL)
 		goto out;
 
 	if (t->parms.proto != ipproto && t->parms.proto != 0)
@@ -690,7 +696,8 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
 
 	read_lock(&ip6_tnl_lock);
 
-	if ((t = ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) {
+	if ((t = ip6_tnl_lookup(&init_net, &ipv6h->saddr,
+					&ipv6h->daddr)) != NULL) {
 		if (t->parms.proto != ipproto && t->parms.proto != 0) {
 			read_unlock(&ip6_tnl_lock);
 			goto discard;
@@ -1197,6 +1204,8 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	int err = 0;
 	struct ip6_tnl_parm p;
 	struct ip6_tnl *t = NULL;
+	struct net *net = dev_net(dev);
+	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 
 	switch (cmd) {
 	case SIOCGETTUNNEL:
@@ -1205,7 +1214,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 				err = -EFAULT;
 				break;
 			}
-			t = ip6_tnl_locate(&p, 0);
+			t = ip6_tnl_locate(net, &p, 0);
 		}
 		if (t == NULL)
 			t = netdev_priv(dev);
@@ -1226,7 +1235,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 		if (p.proto != IPPROTO_IPV6 && p.proto != IPPROTO_IPIP &&
 		    p.proto != 0)
 			break;
-		t = ip6_tnl_locate(&p, cmd == SIOCADDTUNNEL);
+		t = ip6_tnl_locate(net, &p, cmd == SIOCADDTUNNEL);
 		if (dev != ip6_fb_tnl_dev && cmd == SIOCCHGTUNNEL) {
 			if (t != NULL) {
 				if (t->dev != dev) {
@@ -1236,9 +1245,9 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 			} else
 				t = netdev_priv(dev);
 
-			ip6_tnl_unlink(t);
+			ip6_tnl_unlink(ip6n, t);
 			err = ip6_tnl_change(t, &p);
-			ip6_tnl_link(t);
+			ip6_tnl_link(ip6n, t);
 			netdev_state_change(dev);
 		}
 		if (t) {
@@ -1259,7 +1268,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 			if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p)))
 				break;
 			err = -ENOENT;
-			if ((t = ip6_tnl_locate(&p, 0)) == NULL)
+			if ((t = ip6_tnl_locate(net, &p, 0)) == NULL)
 				break;
 			err = -EPERM;
 			if (t->dev == ip6_fb_tnl_dev)
-- 
1.5.3.4


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

* [PATCH net-2.6.26 3/7][IP6TUNNEL]: Use proper net in hash-lookup functions.
  2008-04-15 13:58 [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work in net namespaces Pavel Emelyanov
  2008-04-15 13:59 ` [PATCH net-2.6.26 1/7][IP6TUNNEL]: Introduce empty ip6_tnl_net structure and net ops Pavel Emelyanov
  2008-04-15 14:00 ` [PATCH net-2.6.26 2/7][IP6TUNNEL]: Add (ip6_tnl_)net argument to some calls Pavel Emelyanov
@ 2008-04-15 14:02 ` Pavel Emelyanov
  2008-04-15 14:04 ` [PATCH net-2.6.26 4/7][IP6TUNNEL]: Make the fallback tunnel device per-net Pavel Emelyanov
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 14:02 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List

Calls to ip6_tnl_lookup were stubbed with init_net - give them
a proper one.

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

---
 net/ipv6/ip6_tunnel.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index fad1af8..72485a3 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -412,7 +412,7 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
 	   processing of the error. */
 
 	read_lock(&ip6_tnl_lock);
-	if ((t = ip6_tnl_lookup(&init_net, &ipv6h->daddr,
+	if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->daddr,
 					&ipv6h->saddr)) == NULL)
 		goto out;
 
@@ -696,7 +696,7 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
 
 	read_lock(&ip6_tnl_lock);
 
-	if ((t = ip6_tnl_lookup(&init_net, &ipv6h->saddr,
+	if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr,
 					&ipv6h->daddr)) != NULL) {
 		if (t->parms.proto != ipproto && t->parms.proto != 0) {
 			read_unlock(&ip6_tnl_lock);
-- 
1.5.3.4


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

* [PATCH net-2.6.26 4/7][IP6TUNNEL]: Make the fallback tunnel device per-net.
  2008-04-15 13:58 [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work in net namespaces Pavel Emelyanov
                   ` (2 preceding siblings ...)
  2008-04-15 14:02 ` [PATCH net-2.6.26 3/7][IP6TUNNEL]: Use proper net in hash-lookup functions Pavel Emelyanov
@ 2008-04-15 14:04 ` Pavel Emelyanov
  2008-04-15 14:06 ` [PATCH net-2.6.26 5/7][IP6TUNNEL]: Make tunnels hashes per-net Pavel Emelyanov
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 14:04 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List

All the code, that reference it already has the ip6_tnl_net pointer,
so s/ip6_fb_tnl_dev/ip6n->fb_tnl_dev/ and move creation/releasing
code into net init/exit ops.

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

---
 net/ipv6/ip6_tunnel.c |   48 ++++++++++++++++++++++++------------------------
 1 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 72485a3..511a6c4 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -82,12 +82,10 @@ static void ip6_tnl_dev_setup(struct net_device *dev);
 
 static int ip6_tnl_net_id;
 struct ip6_tnl_net {
+	/* the IPv6 tunnel fallback device */
+	struct net_device *fb_tnl_dev;
 };
 
-/* the IPv6 tunnel fallback device */
-static struct net_device *ip6_fb_tnl_dev;
-
-
 /* lists for storing tunnels in use */
 static struct ip6_tnl *tnls_r_l[HASH_SIZE];
 static struct ip6_tnl *tnls_wc[1];
@@ -314,7 +312,7 @@ ip6_tnl_dev_uninit(struct net_device *dev)
 	struct net *net = dev_net(dev);
 	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 
-	if (dev == ip6_fb_tnl_dev) {
+	if (dev == ip6n->fb_tnl_dev) {
 		write_lock_bh(&ip6_tnl_lock);
 		tnls_wc[0] = NULL;
 		write_unlock_bh(&ip6_tnl_lock);
@@ -1209,7 +1207,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
 	switch (cmd) {
 	case SIOCGETTUNNEL:
-		if (dev == ip6_fb_tnl_dev) {
+		if (dev == ip6n->fb_tnl_dev) {
 			if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) {
 				err = -EFAULT;
 				break;
@@ -1236,7 +1234,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 		    p.proto != 0)
 			break;
 		t = ip6_tnl_locate(net, &p, cmd == SIOCADDTUNNEL);
-		if (dev != ip6_fb_tnl_dev && cmd == SIOCCHGTUNNEL) {
+		if (dev != ip6n->fb_tnl_dev && cmd == SIOCCHGTUNNEL) {
 			if (t != NULL) {
 				if (t->dev != dev) {
 					err = -EEXIST;
@@ -1263,7 +1261,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 		if (!capable(CAP_NET_ADMIN))
 			break;
 
-		if (dev == ip6_fb_tnl_dev) {
+		if (dev == ip6n->fb_tnl_dev) {
 			err = -EFAULT;
 			if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p)))
 				break;
@@ -1271,7 +1269,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 			if ((t = ip6_tnl_locate(net, &p, 0)) == NULL)
 				break;
 			err = -EPERM;
-			if (t->dev == ip6_fb_tnl_dev)
+			if (t->dev == ip6n->fb_tnl_dev)
 				break;
 			dev = t->dev;
 		}
@@ -1413,8 +1411,25 @@ static int ip6_tnl_init_net(struct net *net)
 	if (err < 0)
 		goto err_assign;
 
+	err = -ENOMEM;
+	ip6n->fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0",
+				      ip6_tnl_dev_setup);
+
+	if (!ip6n->fb_tnl_dev)
+		goto err_alloc_dev;
+
+	ip6n->fb_tnl_dev->init = ip6_fb_tnl_dev_init;
+	dev_net_set(ip6n->fb_tnl_dev, net);
+
+	err = register_netdev(ip6n->fb_tnl_dev);
+	if (err < 0)
+		goto err_register;
 	return 0;
 
+err_register:
+	free_netdev(ip6n->fb_tnl_dev);
+err_alloc_dev:
+	/* nothing */
 err_assign:
 	kfree(ip6n);
 err_alloc:
@@ -1455,27 +1470,12 @@ static int __init ip6_tunnel_init(void)
 		err = -EAGAIN;
 		goto unreg_ip4ip6;
 	}
-	ip6_fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0",
-				      ip6_tnl_dev_setup);
-
-	if (!ip6_fb_tnl_dev) {
-		err = -ENOMEM;
-		goto fail;
-	}
-	ip6_fb_tnl_dev->init = ip6_fb_tnl_dev_init;
-
-	if ((err = register_netdev(ip6_fb_tnl_dev))) {
-		free_netdev(ip6_fb_tnl_dev);
-		goto fail;
-	}
 
 	err = register_pernet_gen_device(&ip6_tnl_net_id, &ip6_tnl_net_ops);
 	if (err < 0)
 		goto err_pernet;
 	return 0;
 err_pernet:
-	unregister_netdevice(ip6_fb_tnl_dev);
-fail:
 	xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6);
 unreg_ip4ip6:
 	xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET);
-- 
1.5.3.4


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

* [PATCH net-2.6.26 5/7][IP6TUNNEL]: Make tunnels hashes per-net.
  2008-04-15 13:58 [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work in net namespaces Pavel Emelyanov
                   ` (3 preceding siblings ...)
  2008-04-15 14:04 ` [PATCH net-2.6.26 4/7][IP6TUNNEL]: Make the fallback tunnel device per-net Pavel Emelyanov
@ 2008-04-15 14:06 ` Pavel Emelyanov
  2008-04-15 14:08 ` [PATCH net-2.6.26 6/7][IP6TUNNEL]: Use proper net instead of init_net stubs Pavel Emelyanov
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 14:06 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List

Move hashes in the struct ip6_tnl_net, replace tnls_xxx[] with 
ip6n->tnlx_xxx[] and handle init and exit appropriately.

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

---
 net/ipv6/ip6_tunnel.c |   63 ++++++++++++++++++++++++++----------------------
 1 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 511a6c4..7d2aa6e 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -84,13 +84,12 @@ static int ip6_tnl_net_id;
 struct ip6_tnl_net {
 	/* the IPv6 tunnel fallback device */
 	struct net_device *fb_tnl_dev;
+	/* lists for storing tunnels in use */
+	struct ip6_tnl *tnls_r_l[HASH_SIZE];
+	struct ip6_tnl *tnls_wc[1];
+	struct ip6_tnl **tnls[2];
 };
 
-/* lists for storing tunnels in use */
-static struct ip6_tnl *tnls_r_l[HASH_SIZE];
-static struct ip6_tnl *tnls_wc[1];
-static struct ip6_tnl **tnls[2] = { tnls_wc, tnls_r_l };
-
 /* lock for the tunnel lists */
 static DEFINE_RWLOCK(ip6_tnl_lock);
 
@@ -139,14 +138,15 @@ ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local)
 	unsigned h0 = HASH(remote);
 	unsigned h1 = HASH(local);
 	struct ip6_tnl *t;
+	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 
-	for (t = tnls_r_l[h0 ^ h1]; t; t = t->next) {
+	for (t = ip6n->tnls_r_l[h0 ^ h1]; t; t = t->next) {
 		if (ipv6_addr_equal(local, &t->parms.laddr) &&
 		    ipv6_addr_equal(remote, &t->parms.raddr) &&
 		    (t->dev->flags & IFF_UP))
 			return t;
 	}
-	if ((t = tnls_wc[0]) != NULL && (t->dev->flags & IFF_UP))
+	if ((t = ip6n->tnls_wc[0]) != NULL && (t->dev->flags & IFF_UP))
 		return t;
 
 	return NULL;
@@ -175,7 +175,7 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n, struct ip6_tnl_parm *p)
 		prio = 1;
 		h = HASH(remote) ^ HASH(local);
 	}
-	return &tnls[prio][h];
+	return &ip6n->tnls[prio][h];
 }
 
 /**
@@ -314,7 +314,7 @@ ip6_tnl_dev_uninit(struct net_device *dev)
 
 	if (dev == ip6n->fb_tnl_dev) {
 		write_lock_bh(&ip6_tnl_lock);
-		tnls_wc[0] = NULL;
+		ip6n->tnls_wc[0] = NULL;
 		write_unlock_bh(&ip6_tnl_lock);
 	} else {
 		ip6_tnl_unlink(ip6n, t);
@@ -1378,10 +1378,13 @@ static int
 ip6_fb_tnl_dev_init(struct net_device *dev)
 {
 	struct ip6_tnl *t = netdev_priv(dev);
+	struct net *net = dev_net(dev);
+	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
+
 	ip6_tnl_dev_init_gen(dev);
 	t->parms.proto = IPPROTO_IPV6;
 	dev_hold(dev);
-	tnls_wc[0] = t;
+	ip6n->tnls_wc[0] = t;
 	return 0;
 }
 
@@ -1397,13 +1400,27 @@ static struct xfrm6_tunnel ip6ip6_handler = {
 	.priority	=	1,
 };
 
+static void ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
+{
+	int h;
+	struct ip6_tnl *t;
+
+	for (h = 0; h < HASH_SIZE; h++) {
+		while ((t = ip6n->tnls_r_l[h]) != NULL)
+			unregister_netdevice(t->dev);
+	}
+
+	t = ip6n->tnls_wc[0];
+	unregister_netdevice(t->dev);
+}
+
 static int ip6_tnl_init_net(struct net *net)
 {
 	int err;
 	struct ip6_tnl_net *ip6n;
 
 	err = -ENOMEM;
-	ip6n = kmalloc(sizeof(struct ip6_tnl_net), GFP_KERNEL);
+	ip6n = kzalloc(sizeof(struct ip6_tnl_net), GFP_KERNEL);
 	if (ip6n == NULL)
 		goto err_alloc;
 
@@ -1411,6 +1428,9 @@ static int ip6_tnl_init_net(struct net *net)
 	if (err < 0)
 		goto err_assign;
 
+	ip6n->tnls[0] = ip6n->tnls_wc;
+	ip6n->tnls[1] = ip6n->tnls_r_l;
+
 	err = -ENOMEM;
 	ip6n->fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0",
 				      ip6_tnl_dev_setup);
@@ -1441,6 +1461,9 @@ static void ip6_tnl_exit_net(struct net *net)
 	struct ip6_tnl_net *ip6n;
 
 	ip6n = net_generic(net, ip6_tnl_net_id);
+	rtnl_lock();
+	ip6_tnl_destroy_tunnels(ip6n);
+	rtnl_unlock();
 	kfree(ip6n);
 }
 
@@ -1483,20 +1506,6 @@ out:
 	return err;
 }
 
-static void __exit ip6_tnl_destroy_tunnels(void)
-{
-	int h;
-	struct ip6_tnl *t;
-
-	for (h = 0; h < HASH_SIZE; h++) {
-		while ((t = tnls_r_l[h]) != NULL)
-			unregister_netdevice(t->dev);
-	}
-
-	t = tnls_wc[0];
-	unregister_netdevice(t->dev);
-}
-
 /**
  * ip6_tunnel_cleanup - free resources and unregister protocol
  **/
@@ -1509,10 +1518,6 @@ static void __exit ip6_tunnel_cleanup(void)
 	if (xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6))
 		printk(KERN_INFO "ip6_tunnel close: can't deregister ip6ip6\n");
 
-	rtnl_lock();
-	ip6_tnl_destroy_tunnels();
-	rtnl_unlock();
-
 	unregister_pernet_gen_device(ip6_tnl_net_id, &ip6_tnl_net_ops);
 }
 
-- 
1.5.3.4


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

* [PATCH net-2.6.26 6/7][IP6TUNNEL]: Use proper net instead of init_net stubs.
  2008-04-15 13:58 [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work in net namespaces Pavel Emelyanov
                   ` (4 preceding siblings ...)
  2008-04-15 14:06 ` [PATCH net-2.6.26 5/7][IP6TUNNEL]: Make tunnels hashes per-net Pavel Emelyanov
@ 2008-04-15 14:08 ` Pavel Emelyanov
  2008-04-15 14:10 ` [PATCH net-2.6.26 7/7][IP6TUNNEL]: Allow to create IP6 tunnels in net namespaces Pavel Emelyanov
  2008-04-16  8:25 ` [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work " David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 14:08 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List

All the ip_route_output_key(), dev_get_by_...() and ipv6_chk_addr()
calls are now stubbed with init_net.

Fortunately, all the places already have where to get the proper
net from.

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

---
 net/ipv6/ip6_tunnel.c |   26 +++++++++++++++-----------
 1 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 7d2aa6e..d9b2721 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -543,7 +543,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 	fl.fl4_dst = eiph->saddr;
 	fl.fl4_tos = RT_TOS(eiph->tos);
 	fl.proto = IPPROTO_IPIP;
-	if (ip_route_output_key(&init_net, &rt, &fl))
+	if (ip_route_output_key(dev_net(skb->dev), &rt, &fl))
 		goto out;
 
 	skb2->dev = rt->u.dst.dev;
@@ -555,7 +555,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 		fl.fl4_dst = eiph->daddr;
 		fl.fl4_src = eiph->saddr;
 		fl.fl4_tos = eiph->tos;
-		if (ip_route_output_key(&init_net, &rt, &fl) ||
+		if (ip_route_output_key(dev_net(skb->dev), &rt, &fl) ||
 		    rt->u.dst.dev->type != ARPHRD_TUNNEL) {
 			ip_rt_put(rt);
 			goto out;
@@ -612,7 +612,8 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 		skb_reset_network_header(skb2);
 
 		/* Try to guess incoming interface */
-		rt = rt6_lookup(&init_net, &ipv6_hdr(skb2)->saddr, NULL, 0, 0);
+		rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr,
+				NULL, 0, 0);
 
 		if (rt && rt->rt6i_dev)
 			skb2->dev = rt->rt6i_dev;
@@ -656,16 +657,17 @@ static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
 {
 	struct ip6_tnl_parm *p = &t->parms;
 	int ret = 0;
+	struct net *net = dev_net(t->dev);
 
 	if (p->flags & IP6_TNL_F_CAP_RCV) {
 		struct net_device *ldev = NULL;
 
 		if (p->link)
-			ldev = dev_get_by_index(&init_net, p->link);
+			ldev = dev_get_by_index(net, p->link);
 
 		if ((ipv6_addr_is_multicast(&p->laddr) ||
-		     likely(ipv6_chk_addr(&init_net, &p->laddr, ldev, 0))) &&
-		    likely(!ipv6_chk_addr(&init_net, &p->raddr, NULL, 0)))
+		     likely(ipv6_chk_addr(net, &p->laddr, ldev, 0))) &&
+		    likely(!ipv6_chk_addr(net, &p->raddr, NULL, 0)))
 			ret = 1;
 
 		if (ldev)
@@ -793,19 +795,20 @@ static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
 {
 	struct ip6_tnl_parm *p = &t->parms;
 	int ret = 0;
+	struct net *net = dev_net(t->dev);
 
 	if (p->flags & IP6_TNL_F_CAP_XMIT) {
 		struct net_device *ldev = NULL;
 
 		if (p->link)
-			ldev = dev_get_by_index(&init_net, p->link);
+			ldev = dev_get_by_index(net, p->link);
 
-		if (unlikely(!ipv6_chk_addr(&init_net, &p->laddr, ldev, 0)))
+		if (unlikely(!ipv6_chk_addr(net, &p->laddr, ldev, 0)))
 			printk(KERN_WARNING
 			       "%s xmit: Local address not yet configured!\n",
 			       p->name);
 		else if (!ipv6_addr_is_multicast(&p->raddr) &&
-			 unlikely(ipv6_chk_addr(&init_net, &p->raddr, NULL, 0)))
+			 unlikely(ipv6_chk_addr(net, &p->raddr, NULL, 0)))
 			printk(KERN_WARNING
 			       "%s xmit: Routing loop! "
 			       "Remote address found on this node!\n",
@@ -858,7 +861,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
 	if ((dst = ip6_tnl_dst_check(t)) != NULL)
 		dst_hold(dst);
 	else {
-		dst = ip6_route_output(&init_net, NULL, fl);
+		dst = ip6_route_output(dev_net(dev), NULL, fl);
 
 		if (dst->error || xfrm_lookup(&dst, fl, NULL, 0) < 0)
 			goto tx_err_link_failure;
@@ -1123,7 +1126,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
 		int strict = (ipv6_addr_type(&p->raddr) &
 			      (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL));
 
-		struct rt6_info *rt = rt6_lookup(&init_net, &p->raddr, &p->laddr,
+		struct rt6_info *rt = rt6_lookup(dev_net(dev),
+						 &p->raddr, &p->laddr,
 						 p->link, strict);
 
 		if (rt == NULL)
-- 
1.5.3.4


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

* [PATCH net-2.6.26 7/7][IP6TUNNEL]: Allow to create IP6 tunnels in net namespaces.
  2008-04-15 13:58 [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work in net namespaces Pavel Emelyanov
                   ` (5 preceding siblings ...)
  2008-04-15 14:08 ` [PATCH net-2.6.26 6/7][IP6TUNNEL]: Use proper net instead of init_net stubs Pavel Emelyanov
@ 2008-04-15 14:10 ` Pavel Emelyanov
  2008-04-16  8:25 ` [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work " David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 14:10 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List

And no need in some IPPROTO_XXX enabling, since ipv6 code
doesn't have any filtering.

So, just set proper net and mark device with NETNS_LOCAL.

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

---
 net/ipv6/ip6_tunnel.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index d9b2721..2bda3ba 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -243,6 +243,8 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p)
 	if (dev == NULL)
 		goto failed;
 
+	dev_net_set(dev, net);
+
 	if (strchr(name, '%')) {
 		if (dev_alloc_name(dev, name) < 0)
 			goto failed_free;
@@ -1341,6 +1343,7 @@ static void ip6_tnl_dev_setup(struct net_device *dev)
 	dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr);
 	dev->flags |= IFF_NOARP;
 	dev->addr_len = sizeof(struct in6_addr);
+	dev->features |= NETIF_F_NETNS_LOCAL;
 }
 
 
-- 
1.5.3.4


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

* Re: [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work in net namespaces.
  2008-04-15 13:58 [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work in net namespaces Pavel Emelyanov
                   ` (6 preceding siblings ...)
  2008-04-15 14:10 ` [PATCH net-2.6.26 7/7][IP6TUNNEL]: Allow to create IP6 tunnels in net namespaces Pavel Emelyanov
@ 2008-04-16  8:25 ` David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: David Miller @ 2008-04-16  8:25 UTC (permalink / raw)
  To: xemul; +Cc: netdev

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

> This is the last tunnel to virtualize.
> 
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

All applied and pushed to net-2.6.26, thanks again.

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

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

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-15 13:58 [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work in net namespaces Pavel Emelyanov
2008-04-15 13:59 ` [PATCH net-2.6.26 1/7][IP6TUNNEL]: Introduce empty ip6_tnl_net structure and net ops Pavel Emelyanov
2008-04-15 14:00 ` [PATCH net-2.6.26 2/7][IP6TUNNEL]: Add (ip6_tnl_)net argument to some calls Pavel Emelyanov
2008-04-15 14:02 ` [PATCH net-2.6.26 3/7][IP6TUNNEL]: Use proper net in hash-lookup functions Pavel Emelyanov
2008-04-15 14:04 ` [PATCH net-2.6.26 4/7][IP6TUNNEL]: Make the fallback tunnel device per-net Pavel Emelyanov
2008-04-15 14:06 ` [PATCH net-2.6.26 5/7][IP6TUNNEL]: Make tunnels hashes per-net Pavel Emelyanov
2008-04-15 14:08 ` [PATCH net-2.6.26 6/7][IP6TUNNEL]: Use proper net instead of init_net stubs Pavel Emelyanov
2008-04-15 14:10 ` [PATCH net-2.6.26 7/7][IP6TUNNEL]: Allow to create IP6 tunnels in net namespaces Pavel Emelyanov
2008-04-16  8:25 ` [PATCH net-2.6.26 0/7][IP6TUNNEL]: Make ip6tunnel work " 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).