diff mbox

[RFC,3/4] net: pppol2tp - introduce net-namespace functionality

Message ID 4967accc.0c58560a.2ee6.3de4@mx.google.com
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

Cyrill Gorcunov Jan. 9, 2009, 7:51 p.m. UTC
- Each tunnel and appropriate lock are inside own namespace now.
- pppox code allows to create per-namespace sockets for
  both PX_PROTO_OE and PX_PROTO_OL2TP protocols. Actually since
  now pppox_create support net-namespaces new PPPo... protocols
  (if they ever will be) should support net-namespace too otherwise
  explicit check for &init_net would be needed.

CC: James Chapman <jchapman@katalix.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 drivers/net/pppol2tp.c |  164 ++++++++++++++++++++++++++++++++++++-------------
 drivers/net/pppox.c    |    4 -
 2 files changed, 121 insertions(+), 47 deletions(-)

Comments

James Chapman Jan. 10, 2009, 11:06 a.m. UTC | #1
Cyrill Gorcunov wrote:
> - Each tunnel and appropriate lock are inside own namespace now.
> - pppox code allows to create per-namespace sockets for
>   both PX_PROTO_OE and PX_PROTO_OL2TP protocols. Actually since
>   now pppox_create support net-namespaces new PPPo... protocols
>   (if they ever will be) should support net-namespace too otherwise
>   explicit check for &init_net would be needed.
> 
> CC: James Chapman <jchapman@katalix.com>
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> ---
>  drivers/net/pppol2tp.c |  164 ++++++++++++++++++++++++++++++++++++-------------
>  drivers/net/pppox.c    |    4 -
>  2 files changed, 121 insertions(+), 47 deletions(-)

Looks ok from a pppol2tp point of view, though I'm not an expert on the
netns stuff.

The patches don't apply against latest net-next-2.6. If you respin the
patches, I'll test them for pppol2tp.
Cyrill Gorcunov Jan. 10, 2009, 11:13 a.m. UTC | #2
[James Chapman - Sat, Jan 10, 2009 at 11:06:08AM +0000]
| Cyrill Gorcunov wrote:
| > - Each tunnel and appropriate lock are inside own namespace now.
| > - pppox code allows to create per-namespace sockets for
| >   both PX_PROTO_OE and PX_PROTO_OL2TP protocols. Actually since
| >   now pppox_create support net-namespaces new PPPo... protocols
| >   (if they ever will be) should support net-namespace too otherwise
| >   explicit check for &init_net would be needed.
| > 
| > CC: James Chapman <jchapman@katalix.com>
| > Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
| > ---
| >  drivers/net/pppol2tp.c |  164 ++++++++++++++++++++++++++++++++++++-------------
| >  drivers/net/pppox.c    |    4 -
| >  2 files changed, 121 insertions(+), 47 deletions(-)
| 
| Looks ok from a pppol2tp point of view, though I'm not an expert on the
| netns stuff.
| 
| The patches don't apply against latest net-next-2.6. If you respin the
| patches, I'll test them for pppol2tp.
| 
| -- 
| James Chapman
| Katalix Systems Ltd
| http://www.katalix.com
| Catalysts for your Embedded Linux software development
| 

Thanks James for taken look on. I'll check the latest net-next-2.6
tree and update the patches soon. Thanks!

		- Cyrill -
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Cyrill Gorcunov Jan. 10, 2009, 12:54 p.m. UTC | #3
[Cyrill Gorcunov - Sat, Jan 10, 2009 at 02:13:59PM +0300]
| [James Chapman - Sat, Jan 10, 2009 at 11:06:08AM +0000]
| | Cyrill Gorcunov wrote:
| | > - Each tunnel and appropriate lock are inside own namespace now.
| | > - pppox code allows to create per-namespace sockets for
| | >   both PX_PROTO_OE and PX_PROTO_OL2TP protocols. Actually since
| | >   now pppox_create support net-namespaces new PPPo... protocols
| | >   (if they ever will be) should support net-namespace too otherwise
| | >   explicit check for &init_net would be needed.
| | > 
| | > CC: James Chapman <jchapman@katalix.com>
| | > Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
| | > ---
| | >  drivers/net/pppol2tp.c |  164 ++++++++++++++++++++++++++++++++++++-------------
| | >  drivers/net/pppox.c    |    4 -
| | >  2 files changed, 121 insertions(+), 47 deletions(-)
| | 
| | Looks ok from a pppol2tp point of view, though I'm not an expert on the
| | netns stuff.
| | 
| | The patches don't apply against latest net-next-2.6. If you respin the
| | patches, I'll test them for pppol2tp.
| | 
| | -- 
| | James Chapman
| | Katalix Systems Ltd
| | http://www.katalix.com
| | Catalysts for your Embedded Linux software development
| | 
| 
| Thanks James for taken look on. I'll check the latest net-next-2.6
| tree and update the patches soon. Thanks!
| 
| 		- Cyrill -

James I just fetched latest net-next-2.6 with
commit

---
commit 3c92ec8ae91ecf59d88c798301833d7cf83f2179
Merge: c4c9f01... ca9153a...
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Sun Dec 28 16:54:33 2008 -0800

    Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
---

and patches are being applied on top without problems.
Maybe you have some other commits which are not propogated
to net-next-2.6 yet?

		- Cyrill -
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
James Chapman Jan. 10, 2009, 1:13 p.m. UTC | #4
Cyrill Gorcunov wrote:
> [Cyrill Gorcunov - Sat, Jan 10, 2009 at 02:13:59PM +0300]
> | [James Chapman - Sat, Jan 10, 2009 at 11:06:08AM +0000]
> | | Cyrill Gorcunov wrote:
> | | > - Each tunnel and appropriate lock are inside own namespace now.
> | | > - pppox code allows to create per-namespace sockets for
> | | >   both PX_PROTO_OE and PX_PROTO_OL2TP protocols. Actually since
> | | >   now pppox_create support net-namespaces new PPPo... protocols
> | | >   (if they ever will be) should support net-namespace too otherwise
> | | >   explicit check for &init_net would be needed.
> | | > 
> | | > CC: James Chapman <jchapman@katalix.com>
> | | > Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> | | > ---
> | | >  drivers/net/pppol2tp.c |  164 ++++++++++++++++++++++++++++++++++++-------------
> | | >  drivers/net/pppox.c    |    4 -
> | | >  2 files changed, 121 insertions(+), 47 deletions(-)
> | | 
> | | Looks ok from a pppol2tp point of view, though I'm not an expert on the
> | | netns stuff.
> | | 
> | | The patches don't apply against latest net-next-2.6. If you respin the
> | | patches, I'll test them for pppol2tp.
> | | 
> | | -- 
> | | James Chapman
> | | Katalix Systems Ltd
> | | http://www.katalix.com
> | | Catalysts for your Embedded Linux software development
> | | 
> | 
> | Thanks James for taken look on. I'll check the latest net-next-2.6
> | tree and update the patches soon. Thanks!
> | 
> | 		- Cyrill -
> 
> James I just fetched latest net-next-2.6 with
> commit
> 
> ---
> commit 3c92ec8ae91ecf59d88c798301833d7cf83f2179
> Merge: c4c9f01... ca9153a...
> Author: Linus Torvalds <torvalds@linux-foundation.org>
> Date:   Sun Dec 28 16:54:33 2008 -0800
> 
>     Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
> ---
> 
> and patches are being applied on top without problems.
> Maybe you have some other commits which are not propogated
> to net-next-2.6 yet?

My mistake. I missed one of the patches when applying the series.
James Chapman Jan. 10, 2009, 3:05 p.m. UTC | #5
Cyrill Gorcunov wrote:
> [Cyrill Gorcunov - Sat, Jan 10, 2009 at 02:13:59PM +0300]
> | [James Chapman - Sat, Jan 10, 2009 at 11:06:08AM +0000]
> | | Cyrill Gorcunov wrote:
> | | > - Each tunnel and appropriate lock are inside own namespace now.
> | | > - pppox code allows to create per-namespace sockets for
> | | >   both PX_PROTO_OE and PX_PROTO_OL2TP protocols. Actually since
> | | >   now pppox_create support net-namespaces new PPPo... protocols
> | | >   (if they ever will be) should support net-namespace too otherwise
> | | >   explicit check for &init_net would be needed.

Ok, I tested this in my L2TP setup. The first ppp session setup fails
because the PPPIOCNEWUNIT ioctl returns -EEXIST. I think the problem is
 the logic in ppp_create_interface(), which does the following to create
a new ppp interface:

        /* Initialize the new ppp unit */
        ppp->file.index = unit;
        sprintf(dev->name, "ppp%d", unit);

        ret = register_netdev(dev);

Looks like there is more work to do in the ppp changes.
Cyrill Gorcunov Jan. 10, 2009, 3:19 p.m. UTC | #6
[James Chapman - Sat, Jan 10, 2009 at 03:05:13PM +0000]
| Cyrill Gorcunov wrote:
| > [Cyrill Gorcunov - Sat, Jan 10, 2009 at 02:13:59PM +0300]
| > | [James Chapman - Sat, Jan 10, 2009 at 11:06:08AM +0000]
| > | | Cyrill Gorcunov wrote:
| > | | > - Each tunnel and appropriate lock are inside own namespace now.
| > | | > - pppox code allows to create per-namespace sockets for
| > | | >   both PX_PROTO_OE and PX_PROTO_OL2TP protocols. Actually since
| > | | >   now pppox_create support net-namespaces new PPPo... protocols
| > | | >   (if they ever will be) should support net-namespace too otherwise
| > | | >   explicit check for &init_net would be needed.
| 
| Ok, I tested this in my L2TP setup. The first ppp session setup fails
| because the PPPIOCNEWUNIT ioctl returns -EEXIST. I think the problem is
|  the logic in ppp_create_interface(), which does the following to create
| a new ppp interface:
| 
|         /* Initialize the new ppp unit */
|         ppp->file.index = unit;
|         sprintf(dev->name, "ppp%d", unit);
| 
|         ret = register_netdev(dev);
| 
| Looks like there is more work to do in the ppp changes.
| 
| -- 
| James Chapman
| Katalix Systems Ltd
| http://www.katalix.com
| Catalysts for your Embedded Linux software development
| 

Thanks a lot James for testing!!! Will keep you in touch.
Thanks again!

		- Cyrill -
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Cyrill Gorcunov Jan. 10, 2009, 4:12 p.m. UTC | #7
[Cyrill Gorcunov - Sat, Jan 10, 2009 at 06:19:58PM +0300]
| [James Chapman - Sat, Jan 10, 2009 at 03:05:13PM +0000]
| | Cyrill Gorcunov wrote:
| | > [Cyrill Gorcunov - Sat, Jan 10, 2009 at 02:13:59PM +0300]
| | > | [James Chapman - Sat, Jan 10, 2009 at 11:06:08AM +0000]
| | > | | Cyrill Gorcunov wrote:
| | > | | > - Each tunnel and appropriate lock are inside own namespace now.
| | > | | > - pppox code allows to create per-namespace sockets for
| | > | | >   both PX_PROTO_OE and PX_PROTO_OL2TP protocols. Actually since
| | > | | >   now pppox_create support net-namespaces new PPPo... protocols
| | > | | >   (if they ever will be) should support net-namespace too otherwise
| | > | | >   explicit check for &init_net would be needed.
| | 
| | Ok, I tested this in my L2TP setup. The first ppp session setup fails
| | because the PPPIOCNEWUNIT ioctl returns -EEXIST. I think the problem is
| |  the logic in ppp_create_interface(), which does the following to create
| | a new ppp interface:
| | 
| |         /* Initialize the new ppp unit */
| |         ppp->file.index = unit;
| |         sprintf(dev->name, "ppp%d", unit);
| | 
| |         ret = register_netdev(dev);
| | 
| | Looks like there is more work to do in the ppp changes.
| | 
| | -- 
| | James Chapman
| | Katalix Systems Ltd
| | http://www.katalix.com
| | Catalysts for your Embedded Linux software development
| |
...

Btw James did connection work without these patches? On
pure net-next-2.6 tree? I've some bad feeling that this
fail is related to different patch. Just to be sure.
 
		- Cyrill -
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
James Chapman Jan. 10, 2009, 6:14 p.m. UTC | #8
Cyrill Gorcunov wrote:
> [Cyrill Gorcunov - Sat, Jan 10, 2009 at 06:19:58PM +0300]
> | [James Chapman - Sat, Jan 10, 2009 at 03:05:13PM +0000]
> | | Cyrill Gorcunov wrote:
> | | > [Cyrill Gorcunov - Sat, Jan 10, 2009 at 02:13:59PM +0300]
> | | > | [James Chapman - Sat, Jan 10, 2009 at 11:06:08AM +0000]
> | | > | | Cyrill Gorcunov wrote:
> | | > | | > - Each tunnel and appropriate lock are inside own namespace now.
> | | > | | > - pppox code allows to create per-namespace sockets for
> | | > | | >   both PX_PROTO_OE and PX_PROTO_OL2TP protocols. Actually since
> | | > | | >   now pppox_create support net-namespaces new PPPo... protocols
> | | > | | >   (if they ever will be) should support net-namespace too otherwise
> | | > | | >   explicit check for &init_net would be needed.
> | | 
> | | Ok, I tested this in my L2TP setup. The first ppp session setup fails
> | | because the PPPIOCNEWUNIT ioctl returns -EEXIST. I think the problem is
> | |  the logic in ppp_create_interface(), which does the following to create
> | | a new ppp interface:
> | | 
> | |         /* Initialize the new ppp unit */
> | |         ppp->file.index = unit;
> | |         sprintf(dev->name, "ppp%d", unit);
> | | 
> | |         ret = register_netdev(dev);
> | | 
> | | Looks like there is more work to do in the ppp changes.
> | | 
> | |
> ...
> 
> Btw James did connection work without these patches? On
> pure net-next-2.6 tree? I've some bad feeling that this
> fail is related to different patch. Just to be sure.

If you mean, does pppol2tp work with the patches applied when no
namespace is configured, yes it does.

But to test this patch, I ran two l2tp daemons (in different namespaces
on the same box) and used the veth device to connect them. The failure
happened on the first l2tp session create because each side tried to
create a ppp interface called ppp0.

Should all interface names be unique across the system even when netns
is used? If so, then ppp_generic needs to assign system-wide unique ppp
unit numbers.
Cyrill Gorcunov Jan. 10, 2009, 6:51 p.m. UTC | #9
[James Chapman - Sat, Jan 10, 2009 at 06:14:33PM +0000]
| Cyrill Gorcunov wrote:
| > [Cyrill Gorcunov - Sat, Jan 10, 2009 at 06:19:58PM +0300]
| > | [James Chapman - Sat, Jan 10, 2009 at 03:05:13PM +0000]
| > | | Cyrill Gorcunov wrote:
| > | | > [Cyrill Gorcunov - Sat, Jan 10, 2009 at 02:13:59PM +0300]
| > | | > | [James Chapman - Sat, Jan 10, 2009 at 11:06:08AM +0000]
| > | | > | | Cyrill Gorcunov wrote:
| > | | > | | > - Each tunnel and appropriate lock are inside own namespace now.
| > | | > | | > - pppox code allows to create per-namespace sockets for
| > | | > | | >   both PX_PROTO_OE and PX_PROTO_OL2TP protocols. Actually since
| > | | > | | >   now pppox_create support net-namespaces new PPPo... protocols
| > | | > | | >   (if they ever will be) should support net-namespace too otherwise
| > | | > | | >   explicit check for &init_net would be needed.
| > | | 
| > | | Ok, I tested this in my L2TP setup. The first ppp session setup fails
| > | | because the PPPIOCNEWUNIT ioctl returns -EEXIST. I think the problem is
| > | |  the logic in ppp_create_interface(), which does the following to create
| > | | a new ppp interface:
| > | | 
| > | |         /* Initialize the new ppp unit */
| > | |         ppp->file.index = unit;
| > | |         sprintf(dev->name, "ppp%d", unit);
| > | | 
| > | |         ret = register_netdev(dev);
| > | | 
| > | | Looks like there is more work to do in the ppp changes.
| > | | 
| > | |
| > ...
| > 
| > Btw James did connection work without these patches? On
| > pure net-next-2.6 tree? I've some bad feeling that this
| > fail is related to different patch. Just to be sure.
| 
| If you mean, does pppol2tp work with the patches applied when no
| namespace is configured, yes it does.
| 

James I just found that my previous commits in net-next-2.6 could
be breaking the user side apps. I mean when cardmap was here
ppp_create_interface does not fail if user-side application
has asked not for'new' (ie -1) unit but some predefined number not
being used before so any PPPIOCNEWUNIT ioctl call with new unit number was
serviced by ppp module successfully. As only I've introduced idr
technique I missed such a case and now any PPPIOCNEWUNIT call
will not mark unit as 'reserved'. That is why I asked if l2tp
does work without these 'namespace' related patches.

I'm investigating this issue now. It seems idr can't guarantee
to allocate predefined id number (it could be 'equal' or 'above').
Maybe we would have to revert these commits
(commits 7a95d267fb62cd6b80ef73be0592bbbe1dbd5df7 and 
 ab5024ab23b78c86a0a1425defcdde48710fe449).
But this issue is not related to what you have now.

|
| But to test this patch, I ran two l2tp daemons (in different namespaces
| on the same box) and used the veth device to connect them. The failure
| happened on the first l2tp session create because each side tried to
| create a ppp interface called ppp0.
| 
| Should all interface names be unique across the system even when netns
| is used? If so, then ppp_generic needs to assign system-wide unique ppp
| unit numbers.
| 

I don't think it should be like that since net_device is 'net-namespace'
bound. At least register_netdevice() retrieve *net from device being
registered so I suppose devices with same names but in different
namespace could take place. I'll recheck.

Thanks for testing James!

| 
| -- 
| James Chapman
| Katalix Systems Ltd
| http://www.katalix.com
| Catalysts for your Embedded Linux software development
| 

		- Cyrill -
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller Jan. 11, 2009, 7:36 a.m. UTC | #10
From: Cyrill Gorcunov <gorcunov@gmail.com>
Date: Sat, 10 Jan 2009 15:54:44 +0300

> Maybe you have some other commits which are not propogated
> to net-next-2.6 yet?

net-next-2.6 is a throw away tree that is a clone of essentially
2.6.28 after Linus first took the net-next-2.6

It has not been updated for weeks, all development has been
occurring in the net-2.6 tree
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

Index: linux-2.6.git/drivers/net/pppol2tp.c
===================================================================
--- linux-2.6.git.orig/drivers/net/pppol2tp.c
+++ linux-2.6.git/drivers/net/pppol2tp.c
@@ -90,7 +90,9 @@ 
 #include <linux/hash.h>
 #include <linux/sort.h>
 #include <linux/proc_fs.h>
+#include <linux/nsproxy.h>
 #include <net/net_namespace.h>
+#include <net/netns/generic.h>
 #include <net/dst.h>
 #include <net/ip.h>
 #include <net/udp.h>
@@ -204,6 +206,7 @@  struct pppol2tp_tunnel
 	struct sock		*sock;		/* Parent socket */
 	struct list_head	list;		/* Keep a list of all open
 						 * prepared sockets */
+	struct net		*pppol2tp_net;	/* the net we belong to */
 
 	atomic_t		ref_count;
 };
@@ -227,8 +230,20 @@  static atomic_t pppol2tp_tunnel_count;
 static atomic_t pppol2tp_session_count;
 static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL };
 static struct proto_ops pppol2tp_ops;
-static LIST_HEAD(pppol2tp_tunnel_list);
-static DEFINE_RWLOCK(pppol2tp_tunnel_list_lock);
+
+/* per-net private data for this module */
+static unsigned int pppol2tp_net_id;
+struct pppol2tp_net {
+	struct list_head pppol2tp_tunnel_list;
+	rwlock_t pppol2tp_tunnel_list_lock;
+};
+
+static inline struct pppol2tp_net *pppol2tp_pernet(struct net *net)
+{
+	BUG_ON(!net);
+
+	return net_generic(net, pppol2tp_net_id);
+}
 
 /* Helpers to obtain tunnel/session contexts from sockets.
  */
@@ -321,18 +336,19 @@  pppol2tp_session_find(struct pppol2tp_tu
 
 /* Lookup a tunnel by id
  */
-static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id)
+static struct pppol2tp_tunnel *pppol2tp_tunnel_find(struct net *net, u16 tunnel_id)
 {
-	struct pppol2tp_tunnel *tunnel = NULL;
+	struct pppol2tp_tunnel *tunnel;
+	struct pppol2tp_net *pn = pppol2tp_pernet(net);
 
-	read_lock_bh(&pppol2tp_tunnel_list_lock);
-	list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) {
+	read_lock_bh(&pn->pppol2tp_tunnel_list_lock);
+	list_for_each_entry(tunnel, &pn->pppol2tp_tunnel_list, list) {
 		if (tunnel->stats.tunnel_id == tunnel_id) {
-			read_unlock_bh(&pppol2tp_tunnel_list_lock);
+			read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
 			return tunnel;
 		}
 	}
-	read_unlock_bh(&pppol2tp_tunnel_list_lock);
+	read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
 
 	return NULL;
 }
@@ -1287,10 +1303,12 @@  again:
  */
 static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel)
 {
+	struct pppol2tp_net *pn = pppol2tp_pernet(tunnel->pppol2tp_net);
+
 	/* Remove from socket list */
-	write_lock_bh(&pppol2tp_tunnel_list_lock);
+	write_lock_bh(&pn->pppol2tp_tunnel_list_lock);
 	list_del_init(&tunnel->list);
-	write_unlock_bh(&pppol2tp_tunnel_list_lock);
+	write_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
 
 	atomic_dec(&pppol2tp_tunnel_count);
 	kfree(tunnel);
@@ -1444,13 +1462,14 @@  error:
 /* Internal function to prepare a tunnel (UDP) socket to have PPPoX
  * sockets attached to it.
  */
-static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
-						   int *error)
+static struct sock *pppol2tp_prepare_tunnel_socket(struct net *net,
+					int fd, u16 tunnel_id, int *error)
 {
 	int err;
 	struct socket *sock = NULL;
 	struct sock *sk;
 	struct pppol2tp_tunnel *tunnel;
+	struct pppol2tp_net *pn;
 	struct sock *ret = NULL;
 
 	/* Get the tunnel UDP socket from the fd, which was opened by
@@ -1524,11 +1543,15 @@  static struct sock *pppol2tp_prepare_tun
 	/* Misc init */
 	rwlock_init(&tunnel->hlist_lock);
 
+	/* The net we belong to */
+	tunnel->pppol2tp_net = net;
+	pn = pppol2tp_pernet(net);
+
 	/* Add tunnel to our list */
 	INIT_LIST_HEAD(&tunnel->list);
-	write_lock_bh(&pppol2tp_tunnel_list_lock);
-	list_add(&tunnel->list, &pppol2tp_tunnel_list);
-	write_unlock_bh(&pppol2tp_tunnel_list_lock);
+	write_lock_bh(&pn->pppol2tp_tunnel_list_lock);
+	list_add(&tunnel->list, &pn->pppol2tp_tunnel_list);
+	write_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
 	atomic_inc(&pppol2tp_tunnel_count);
 
 	/* Bump the reference count. The tunnel context is deleted
@@ -1629,7 +1652,8 @@  static int pppol2tp_connect(struct socke
 	 * tunnel id.
 	 */
 	if ((sp->pppol2tp.s_session == 0) && (sp->pppol2tp.d_session == 0)) {
-		tunnel_sock = pppol2tp_prepare_tunnel_socket(sp->pppol2tp.fd,
+		tunnel_sock = pppol2tp_prepare_tunnel_socket(current->nsproxy->net_ns,
+							     sp->pppol2tp.fd,
 							     sp->pppol2tp.s_tunnel,
 							     &error);
 		if (tunnel_sock == NULL)
@@ -1637,7 +1661,7 @@  static int pppol2tp_connect(struct socke
 
 		tunnel = tunnel_sock->sk_user_data;
 	} else {
-		tunnel = pppol2tp_tunnel_find(sp->pppol2tp.s_tunnel);
+		tunnel = pppol2tp_tunnel_find(current->nsproxy->net_ns, sp->pppol2tp.s_tunnel);
 
 		/* Error if we can't find the tunnel */
 		error = -ENOENT;
@@ -2347,8 +2371,9 @@  end:
 #include <linux/seq_file.h>
 
 struct pppol2tp_seq_data {
-	struct pppol2tp_tunnel *tunnel; /* current tunnel */
-	struct pppol2tp_session *session; /* NULL means get first session in tunnel */
+	struct net *seq_net;			/* net of inode */
+	struct pppol2tp_tunnel *tunnel;		/* current tunnel */
+	struct pppol2tp_session *session;	/* NULL means get first session in tunnel */
 };
 
 static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, struct pppol2tp_session *curr)
@@ -2384,17 +2409,18 @@  out:
 	return session;
 }
 
-static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr)
+static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_net *pn,
+					   struct pppol2tp_tunnel *curr)
 {
 	struct pppol2tp_tunnel *tunnel = NULL;
 
-	read_lock_bh(&pppol2tp_tunnel_list_lock);
-	if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) {
+	read_lock_bh(&pn->pppol2tp_tunnel_list_lock);
+	if (list_is_last(&curr->list, &pn->pppol2tp_tunnel_list)) {
 		goto out;
 	}
 	tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list);
 out:
-	read_unlock_bh(&pppol2tp_tunnel_list_lock);
+	read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
 
 	return tunnel;
 }
@@ -2402,6 +2428,7 @@  out:
 static void *pppol2tp_seq_start(struct seq_file *m, loff_t *offs)
 {
 	struct pppol2tp_seq_data *pd = SEQ_START_TOKEN;
+	struct pppol2tp_net *pn;
 	loff_t pos = *offs;
 
 	if (!pos)
@@ -2409,14 +2436,15 @@  static void *pppol2tp_seq_start(struct s
 
 	BUG_ON(m->private == NULL);
 	pd = m->private;
+	pn = pppol2tp_pernet(pd->seq_net);
 
 	if (pd->tunnel == NULL) {
-		if (!list_empty(&pppol2tp_tunnel_list))
-			pd->tunnel = list_entry(pppol2tp_tunnel_list.next, struct pppol2tp_tunnel, list);
+		if (!list_empty(&pn->pppol2tp_tunnel_list))
+			pd->tunnel = list_entry(pn->pppol2tp_tunnel_list.next, struct pppol2tp_tunnel, list);
 	} else {
 		pd->session = next_session(pd->tunnel, pd->session);
 		if (pd->session == NULL) {
-			pd->tunnel = next_tunnel(pd->tunnel);
+			pd->tunnel = next_tunnel(pn, pd->tunnel);
 		}
 	}
 
@@ -2532,6 +2560,7 @@  static int pppol2tp_proc_open(struct ino
 {
 	struct seq_file *m;
 	struct pppol2tp_seq_data *pd;
+	struct net *net;
 	int ret = 0;
 
 	ret = seq_open(file, &pppol2tp_seq_ops);
@@ -2542,12 +2571,15 @@  static int pppol2tp_proc_open(struct ino
 
 	/* Allocate and fill our proc_data for access later */
 	ret = -ENOMEM;
-	m->private = kzalloc(sizeof(struct pppol2tp_seq_data), GFP_KERNEL);
+	m->private = kzalloc(sizeof(*pd), GFP_KERNEL);
 	if (m->private == NULL)
 		goto out;
 
 	pd = m->private;
-	ret = 0;
+	net = maybe_get_net(PDE_NET(PDE(inode)));
+	BUG_ON(!net);
+	pd->seq_net = net;
+	return 0;
 
 out:
 	return ret;
@@ -2558,6 +2590,9 @@  out:
 static int pppol2tp_proc_release(struct inode *inode, struct file *file)
 {
 	struct seq_file *m = (struct seq_file *)file->private_data;
+	struct pppol2tp_seq_data *pd = m->private;
+
+	put_net(pd->seq_net);
 
 	kfree(m->private);
 	m->private = NULL;
@@ -2573,8 +2608,6 @@  static struct file_operations pppol2tp_p
 	.release	= pppol2tp_proc_release,
 };
 
-static struct proc_dir_entry *pppol2tp_proc;
-
 #endif /* CONFIG_PROC_FS */
 
 /*****************************************************************************
@@ -2606,6 +2639,61 @@  static struct pppox_proto pppol2tp_proto
 	.ioctl		= pppol2tp_ioctl
 };
 
+static __net_init int pppol2tp_init_net(struct net *net)
+{
+	struct pppol2tp_net *pn;
+	struct proc_dir_entry *pde;
+	int err;
+
+	pn = kzalloc(sizeof(*pn), GFP_KERNEL);
+	if (!pn)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&pn->pppol2tp_tunnel_list);
+	rwlock_init(&pn->pppol2tp_tunnel_list_lock);
+
+	err = net_assign_generic(net, pppol2tp_net_id, pn);
+	if (err)
+		goto out;
+
+	pde = proc_net_fops_create(net, "pppol2tp", S_IRUGO, &pppol2tp_proc_fops);
+#ifdef CONFIG_PROC_FS
+	if (!pde) {
+		err = -ENOMEM;
+		goto out;
+	}
+#endif
+
+	try_module_get(THIS_MODULE);
+
+	return 0;
+
+out:
+	kfree(pn);
+	return err;
+}
+
+static __net_exit void pppol2tp_exit_net(struct net *net)
+{
+	struct pppoe_net *pn;
+
+	proc_net_remove(net, "pppol2tp");
+	pn = net_generic(net, pppol2tp_net_id);
+	/*
+	 * if someone has cached our net then
+	 * further net_generic call will return NULL
+	 */
+	net_assign_generic(net, pppol2tp_net_id, NULL);
+	kfree(pn);
+
+	module_put(THIS_MODULE);
+}
+
+static __net_initdata struct pernet_operations pppol2tp_net_ops = {
+	.init = pppol2tp_init_net,
+	.exit = pppol2tp_exit_net,
+};
+
 static int __init pppol2tp_init(void)
 {
 	int err;
@@ -2617,23 +2705,17 @@  static int __init pppol2tp_init(void)
 	if (err)
 		goto out_unregister_pppol2tp_proto;
 
-#ifdef CONFIG_PROC_FS
-	pppol2tp_proc = proc_net_fops_create(&init_net, "pppol2tp", 0,
-					     &pppol2tp_proc_fops);
-	if (!pppol2tp_proc) {
-		err = -ENOMEM;
+	err = register_pernet_gen_device(&pppol2tp_net_id, &pppol2tp_net_ops);
+	if (err)
 		goto out_unregister_pppox_proto;
-	}
-#endif /* CONFIG_PROC_FS */
+
 	printk(KERN_INFO "PPPoL2TP kernel driver, %s\n",
 	       PPPOL2TP_DRV_VERSION);
 
 out:
 	return err;
-#ifdef CONFIG_PROC_FS
 out_unregister_pppox_proto:
 	unregister_pppox_proto(PX_PROTO_OL2TP);
-#endif
 out_unregister_pppol2tp_proto:
 	proto_unregister(&pppol2tp_sk_proto);
 	goto out;
@@ -2642,10 +2724,6 @@  out_unregister_pppol2tp_proto:
 static void __exit pppol2tp_exit(void)
 {
 	unregister_pppox_proto(PX_PROTO_OL2TP);
-
-#ifdef CONFIG_PROC_FS
-	remove_proc_entry("pppol2tp", init_net.proc_net);
-#endif
 	proto_unregister(&pppol2tp_sk_proto);
 }
 
Index: linux-2.6.git/drivers/net/pppox.c
===================================================================
--- linux-2.6.git.orig/drivers/net/pppox.c
+++ linux-2.6.git/drivers/net/pppox.c
@@ -111,10 +111,6 @@  static int pppox_create(struct net *net,
 	if (protocol < 0 || protocol > PX_MAX_PROTO)
 		goto out;
 
-	/* we support net-namespaces for PPPoE only (yet) */
-	if (protocol != PX_PROTO_OE && net != &init_net)
-		return -EAFNOSUPPORT;
-
 	rc = -EPROTONOSUPPORT;
 	if (!pppox_protos[protocol])
 		request_module("pppox-proto-%d", protocol);