* [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces.
@ 2008-04-15 12:25 Pavel Emelyanov
2008-04-15 12:26 ` [PATCH net-2.6.26 1/8][IPIP]: Introduce empty ipip_net structure and net init/exit ops Pavel Emelyanov
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 12:25 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List
Make yet another useful virtual device work in namespaces.
This set is also isolated from the other "make xxx device work
in net namespaces" ones.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net-2.6.26 1/8][IPIP]: Introduce empty ipip_net structure and net init/exit ops.
2008-04-15 12:25 [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces Pavel Emelyanov
@ 2008-04-15 12:26 ` Pavel Emelyanov
2008-04-15 12:29 ` [PATCH net-2.6.26 2/8][IPIP]: Make the fallback tunnel device per-net Pavel Emelyanov
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 12:26 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
net/ipv4/ipip.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 894bce9..e39a4c2 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -115,10 +115,16 @@
#include <net/ipip.h>
#include <net/inet_ecn.h>
#include <net/xfrm.h>
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
#define HASH_SIZE 16
#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
+static int ipip_net_id;
+struct ipip_net {
+};
+
static int ipip_fb_tunnel_init(struct net_device *dev);
static int ipip_tunnel_init(struct net_device *dev);
static void ipip_tunnel_setup(struct net_device *dev);
@@ -867,6 +873,41 @@ static struct xfrm_tunnel ipip_handler = {
static char banner[] __initdata =
KERN_INFO "IPv4 over IPv4 tunneling driver\n";
+static int ipip_init_net(struct net *net)
+{
+ int err;
+ struct ipip_net *ipn;
+
+ err = -ENOMEM;
+ ipn = kmalloc(sizeof(struct ipip_net), GFP_KERNEL);
+ if (ipn == NULL)
+ goto err_alloc;
+
+ err = net_assign_generic(net, ipip_net_id, ipn);
+ if (err < 0)
+ goto err_assign;
+
+ return 0;
+
+err_assign:
+ kfree(ipn);
+err_alloc:
+ return err;
+}
+
+static void ipip_exit_net(struct net *net)
+{
+ struct ipip_net *ipn;
+
+ ipn = net_generic(net, ipip_net_id);
+ kfree(ipn);
+}
+
+static struct pernet_operations ipip_net_ops = {
+ .init = ipip_init_net,
+ .exit = ipip_exit_net,
+};
+
static int __init ipip_init(void)
{
int err;
@@ -890,6 +931,10 @@ static int __init ipip_init(void)
if ((err = register_netdev(ipip_fb_tunnel_dev)))
goto err2;
+
+ err = register_pernet_gen_device(&ipip_net_id, &ipip_net_ops);
+ if (err)
+ goto err3;
out:
return err;
err2:
@@ -897,6 +942,9 @@ static int __init ipip_init(void)
err1:
xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
goto out;
+err3:
+ unregister_netdevice(ipip_fb_tunnel_dev);
+ goto err1;
}
static void __exit ipip_destroy_tunnels(void)
@@ -922,6 +970,8 @@ static void __exit ipip_fini(void)
ipip_destroy_tunnels();
unregister_netdevice(ipip_fb_tunnel_dev);
rtnl_unlock();
+
+ unregister_pernet_gen_device(ipip_net_id, &ipip_net_ops);
}
module_init(ipip_init);
--
1.5.3.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-2.6.26 2/8][IPIP]: Make the fallback tunnel device per-net.
2008-04-15 12:25 [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces Pavel Emelyanov
2008-04-15 12:26 ` [PATCH net-2.6.26 1/8][IPIP]: Introduce empty ipip_net structure and net init/exit ops Pavel Emelyanov
@ 2008-04-15 12:29 ` Pavel Emelyanov
2008-04-15 12:31 ` [PATCH net-2.6.26 3/8][IPIP]: Add net/ipip_net argument to some functions Pavel Emelyanov
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 12:29 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List
Create on in ipip_init_net(), use it all over the code (the
proper place to get the net from already exists) and destroy
in ipip_net_exit().
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
net/ipv4/ipip.c | 67 ++++++++++++++++++++++++++++--------------------------
1 files changed, 35 insertions(+), 32 deletions(-)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index e39a4c2..e657a66 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -123,14 +123,13 @@
static int ipip_net_id;
struct ipip_net {
+ struct net_device *fb_tunnel_dev;
};
static int ipip_fb_tunnel_init(struct net_device *dev);
static int ipip_tunnel_init(struct net_device *dev);
static void ipip_tunnel_setup(struct net_device *dev);
-static struct net_device *ipip_fb_tunnel_dev;
-
static struct ip_tunnel *tunnels_r_l[HASH_SIZE];
static struct ip_tunnel *tunnels_r[HASH_SIZE];
static struct ip_tunnel *tunnels_l[HASH_SIZE];
@@ -257,7 +256,10 @@ failed_free:
static void ipip_tunnel_uninit(struct net_device *dev)
{
- if (dev == ipip_fb_tunnel_dev) {
+ struct net *net = dev_net(dev);
+ struct ipip_net *ipn = net_generic(net, ipip_net_id);
+
+ if (dev == ipn->fb_tunnel_dev) {
write_lock_bh(&ipip_lock);
tunnels_wc[0] = NULL;
write_unlock_bh(&ipip_lock);
@@ -693,11 +695,13 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
int err = 0;
struct ip_tunnel_parm p;
struct ip_tunnel *t;
+ struct net *net = dev_net(dev);
+ struct ipip_net *ipn = net_generic(net, ipip_net_id);
switch (cmd) {
case SIOCGETTUNNEL:
t = NULL;
- if (dev == ipip_fb_tunnel_dev) {
+ if (dev == ipn->fb_tunnel_dev) {
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
err = -EFAULT;
break;
@@ -730,7 +734,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
t = ipip_tunnel_locate(&p, cmd == SIOCADDTUNNEL);
- if (dev != ipip_fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
+ if (dev != ipn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
if (t != NULL) {
if (t->dev != dev) {
err = -EEXIST;
@@ -776,7 +780,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
if (!capable(CAP_NET_ADMIN))
goto done;
- if (dev == ipip_fb_tunnel_dev) {
+ if (dev == ipn->fb_tunnel_dev) {
err = -EFAULT;
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
goto done;
@@ -784,7 +788,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
if ((t = ipip_tunnel_locate(&p, 0)) == NULL)
goto done;
err = -EPERM;
- if (t->dev == ipip_fb_tunnel_dev)
+ if (t->dev == ipn->fb_tunnel_dev)
goto done;
dev = t->dev;
}
@@ -847,7 +851,7 @@ static int ipip_tunnel_init(struct net_device *dev)
return 0;
}
-static int __init ipip_fb_tunnel_init(struct net_device *dev)
+static int ipip_fb_tunnel_init(struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
struct iphdr *iph = &tunnel->parms.iph;
@@ -887,8 +891,26 @@ static int ipip_init_net(struct net *net)
if (err < 0)
goto err_assign;
+ ipn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel),
+ "tunl0",
+ ipip_tunnel_setup);
+ if (!ipn->fb_tunnel_dev) {
+ err = -ENOMEM;
+ goto err_alloc_dev;
+ }
+
+ ipn->fb_tunnel_dev->init = ipip_fb_tunnel_init;
+ dev_net_set(ipn->fb_tunnel_dev, net);
+
+ if ((err = register_netdev(ipn->fb_tunnel_dev)))
+ goto err_reg_dev;
+
return 0;
+err_reg_dev:
+ free_netdev(ipn->fb_tunnel_dev);
+err_alloc_dev:
+ /* nothing */
err_assign:
kfree(ipn);
err_alloc:
@@ -900,6 +922,9 @@ static void ipip_exit_net(struct net *net)
struct ipip_net *ipn;
ipn = net_generic(net, ipip_net_id);
+ rtnl_lock();
+ unregister_netdevice(ipn->fb_tunnel_dev);
+ rtnl_unlock();
kfree(ipn);
}
@@ -919,32 +944,11 @@ static int __init ipip_init(void)
return -EAGAIN;
}
- ipip_fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel),
- "tunl0",
- ipip_tunnel_setup);
- if (!ipip_fb_tunnel_dev) {
- err = -ENOMEM;
- goto err1;
- }
-
- ipip_fb_tunnel_dev->init = ipip_fb_tunnel_init;
-
- if ((err = register_netdev(ipip_fb_tunnel_dev)))
- goto err2;
-
err = register_pernet_gen_device(&ipip_net_id, &ipip_net_ops);
if (err)
- goto err3;
- out:
+ xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
+
return err;
- err2:
- free_netdev(ipip_fb_tunnel_dev);
- err1:
- xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
- goto out;
-err3:
- unregister_netdevice(ipip_fb_tunnel_dev);
- goto err1;
}
static void __exit ipip_destroy_tunnels(void)
@@ -968,7 +972,6 @@ static void __exit ipip_fini(void)
rtnl_lock();
ipip_destroy_tunnels();
- unregister_netdevice(ipip_fb_tunnel_dev);
rtnl_unlock();
unregister_pernet_gen_device(ipip_net_id, &ipip_net_ops);
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-2.6.26 3/8][IPIP]: Add net/ipip_net argument to some functions.
2008-04-15 12:25 [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces Pavel Emelyanov
2008-04-15 12:26 ` [PATCH net-2.6.26 1/8][IPIP]: Introduce empty ipip_net structure and net init/exit ops Pavel Emelyanov
2008-04-15 12:29 ` [PATCH net-2.6.26 2/8][IPIP]: Make the fallback tunnel device per-net Pavel Emelyanov
@ 2008-04-15 12:31 ` Pavel Emelyanov
2008-04-15 12:33 ` [PATCH net-2.6.26 4/8][IPIP]: Use proper net in hash-lookup functions Pavel Emelyanov
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 12:31 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List
The hashes of tunnels will be per-net too, so prepare all the
functions that uses them for this change by adding an argument.
Use init_net temporarily in places, where the net does not exist
explicitly yet.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
net/ipv4/ipip.c | 44 +++++++++++++++++++++++++-------------------
1 files changed, 25 insertions(+), 19 deletions(-)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index e657a66..bc4d4cb 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -138,7 +138,8 @@ static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunne
static DEFINE_RWLOCK(ipip_lock);
-static struct ip_tunnel * ipip_tunnel_lookup(__be32 remote, __be32 local)
+static struct ip_tunnel * ipip_tunnel_lookup(struct net *net,
+ __be32 remote, __be32 local)
{
unsigned h0 = HASH(remote);
unsigned h1 = HASH(local);
@@ -162,7 +163,8 @@ static struct ip_tunnel * ipip_tunnel_lookup(__be32 remote, __be32 local)
return NULL;
}
-static struct ip_tunnel **__ipip_bucket(struct ip_tunnel_parm *parms)
+static struct ip_tunnel **__ipip_bucket(struct ipip_net *ipn,
+ struct ip_tunnel_parm *parms)
{
__be32 remote = parms->iph.daddr;
__be32 local = parms->iph.saddr;
@@ -180,16 +182,17 @@ static struct ip_tunnel **__ipip_bucket(struct ip_tunnel_parm *parms)
return &tunnels[prio][h];
}
-static inline struct ip_tunnel **ipip_bucket(struct ip_tunnel *t)
+static inline struct ip_tunnel **ipip_bucket(struct ipip_net *ipn,
+ struct ip_tunnel *t)
{
- return __ipip_bucket(&t->parms);
+ return __ipip_bucket(ipn, &t->parms);
}
-static void ipip_tunnel_unlink(struct ip_tunnel *t)
+static void ipip_tunnel_unlink(struct ipip_net *ipn, struct ip_tunnel *t)
{
struct ip_tunnel **tp;
- for (tp = ipip_bucket(t); *tp; tp = &(*tp)->next) {
+ for (tp = ipip_bucket(ipn, t); *tp; tp = &(*tp)->next) {
if (t == *tp) {
write_lock_bh(&ipip_lock);
*tp = t->next;
@@ -199,9 +202,9 @@ static void ipip_tunnel_unlink(struct ip_tunnel *t)
}
}
-static void ipip_tunnel_link(struct ip_tunnel *t)
+static void ipip_tunnel_link(struct ipip_net *ipn, struct ip_tunnel *t)
{
- struct ip_tunnel **tp = ipip_bucket(t);
+ struct ip_tunnel **tp = ipip_bucket(ipn, t);
t->next = *tp;
write_lock_bh(&ipip_lock);
@@ -209,15 +212,17 @@ static void ipip_tunnel_link(struct ip_tunnel *t)
write_unlock_bh(&ipip_lock);
}
-static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create)
+static struct ip_tunnel * ipip_tunnel_locate(struct net *net,
+ struct ip_tunnel_parm *parms, int create)
{
__be32 remote = parms->iph.daddr;
__be32 local = parms->iph.saddr;
struct ip_tunnel *t, **tp, *nt;
struct net_device *dev;
char name[IFNAMSIZ];
+ struct ipip_net *ipn = net_generic(net, ipip_net_id);
- for (tp = __ipip_bucket(parms); (t = *tp) != NULL; tp = &t->next) {
+ for (tp = __ipip_bucket(ipn, parms); (t = *tp) != NULL; tp = &t->next) {
if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr)
return t;
}
@@ -246,7 +251,7 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c
goto failed_free;
dev_hold(dev);
- ipip_tunnel_link(nt);
+ ipip_tunnel_link(ipn, nt);
return nt;
failed_free:
@@ -264,7 +269,7 @@ static void ipip_tunnel_uninit(struct net_device *dev)
tunnels_wc[0] = NULL;
write_unlock_bh(&ipip_lock);
} else
- ipip_tunnel_unlink(netdev_priv(dev));
+ ipip_tunnel_unlink(ipn, netdev_priv(dev));
dev_put(dev);
}
@@ -313,7 +318,7 @@ static int ipip_err(struct sk_buff *skb, u32 info)
err = -ENOENT;
read_lock(&ipip_lock);
- t = ipip_tunnel_lookup(iph->daddr, iph->saddr);
+ t = ipip_tunnel_lookup(&init_net, iph->daddr, iph->saddr);
if (t == NULL || t->parms.iph.daddr == 0)
goto out;
@@ -473,7 +478,8 @@ static int ipip_rcv(struct sk_buff *skb)
const struct iphdr *iph = ip_hdr(skb);
read_lock(&ipip_lock);
- if ((tunnel = ipip_tunnel_lookup(iph->saddr, iph->daddr)) != NULL) {
+ if ((tunnel = ipip_tunnel_lookup(&init_net,
+ iph->saddr, iph->daddr)) != NULL) {
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
read_unlock(&ipip_lock);
kfree_skb(skb);
@@ -706,7 +712,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
err = -EFAULT;
break;
}
- t = ipip_tunnel_locate(&p, 0);
+ t = ipip_tunnel_locate(net, &p, 0);
}
if (t == NULL)
t = netdev_priv(dev);
@@ -732,7 +738,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
if (p.iph.ttl)
p.iph.frag_off |= htons(IP_DF);
- t = ipip_tunnel_locate(&p, cmd == SIOCADDTUNNEL);
+ t = ipip_tunnel_locate(net, &p, cmd == SIOCADDTUNNEL);
if (dev != ipn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
if (t != NULL) {
@@ -747,12 +753,12 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
break;
}
t = netdev_priv(dev);
- ipip_tunnel_unlink(t);
+ ipip_tunnel_unlink(ipn, t);
t->parms.iph.saddr = p.iph.saddr;
t->parms.iph.daddr = p.iph.daddr;
memcpy(dev->dev_addr, &p.iph.saddr, 4);
memcpy(dev->broadcast, &p.iph.daddr, 4);
- ipip_tunnel_link(t);
+ ipip_tunnel_link(ipn, t);
netdev_state_change(dev);
}
}
@@ -785,7 +791,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
goto done;
err = -ENOENT;
- if ((t = ipip_tunnel_locate(&p, 0)) == NULL)
+ if ((t = ipip_tunnel_locate(net, &p, 0)) == NULL)
goto done;
err = -EPERM;
if (t->dev == ipn->fb_tunnel_dev)
--
1.5.3.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-2.6.26 4/8][IPIP]: Use proper net in hash-lookup functions.
2008-04-15 12:25 [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces Pavel Emelyanov
` (2 preceding siblings ...)
2008-04-15 12:31 ` [PATCH net-2.6.26 3/8][IPIP]: Add net/ipip_net argument to some functions Pavel Emelyanov
@ 2008-04-15 12:33 ` Pavel Emelyanov
2008-04-15 12:36 ` [PATCH net-2.6.26 5/8][IPIP]: Make tunnels hashes per net Pavel Emelyanov
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 12:33 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List
This is the part#2 of the previous patch - get the proper
net for these functions.
I make it in a separate patch, so that this change does not
get lost in a large previous patch.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
net/ipv4/ipip.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index bc4d4cb..da71470 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -318,7 +318,7 @@ static int ipip_err(struct sk_buff *skb, u32 info)
err = -ENOENT;
read_lock(&ipip_lock);
- t = ipip_tunnel_lookup(&init_net, iph->daddr, iph->saddr);
+ t = ipip_tunnel_lookup(dev_net(skb->dev), iph->daddr, iph->saddr);
if (t == NULL || t->parms.iph.daddr == 0)
goto out;
@@ -478,7 +478,7 @@ static int ipip_rcv(struct sk_buff *skb)
const struct iphdr *iph = ip_hdr(skb);
read_lock(&ipip_lock);
- if ((tunnel = ipip_tunnel_lookup(&init_net,
+ if ((tunnel = ipip_tunnel_lookup(dev_net(skb->dev),
iph->saddr, iph->daddr)) != NULL) {
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
read_unlock(&ipip_lock);
--
1.5.3.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-2.6.26 5/8][IPIP]: Make tunnels hashes per net.
2008-04-15 12:25 [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces Pavel Emelyanov
` (3 preceding siblings ...)
2008-04-15 12:33 ` [PATCH net-2.6.26 4/8][IPIP]: Use proper net in hash-lookup functions Pavel Emelyanov
@ 2008-04-15 12:36 ` Pavel Emelyanov
2008-04-15 12:38 ` [PATCH net-2.6.26 6/8][IPIP]: Use proper net in (mostly) routing calls Pavel Emelyanov
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 12:36 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List
Either net or ipip_net already exists in all the required
places, so just use one.
Besides, tune net_init and net_exit calls to respectively
initialize the hashes and destroy devices.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
net/ipv4/ipip.c | 68 +++++++++++++++++++++++++++++-------------------------
1 files changed, 36 insertions(+), 32 deletions(-)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index da71470..9c2939b 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -123,6 +123,12 @@
static int ipip_net_id;
struct ipip_net {
+ struct ip_tunnel *tunnels_r_l[HASH_SIZE];
+ struct ip_tunnel *tunnels_r[HASH_SIZE];
+ struct ip_tunnel *tunnels_l[HASH_SIZE];
+ struct ip_tunnel *tunnels_wc[1];
+ struct ip_tunnel **tunnels[4];
+
struct net_device *fb_tunnel_dev;
};
@@ -130,12 +136,6 @@ static int ipip_fb_tunnel_init(struct net_device *dev);
static int ipip_tunnel_init(struct net_device *dev);
static void ipip_tunnel_setup(struct net_device *dev);
-static struct ip_tunnel *tunnels_r_l[HASH_SIZE];
-static struct ip_tunnel *tunnels_r[HASH_SIZE];
-static struct ip_tunnel *tunnels_l[HASH_SIZE];
-static struct ip_tunnel *tunnels_wc[1];
-static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunnels_r_l };
-
static DEFINE_RWLOCK(ipip_lock);
static struct ip_tunnel * ipip_tunnel_lookup(struct net *net,
@@ -144,21 +144,22 @@ static struct ip_tunnel * ipip_tunnel_lookup(struct net *net,
unsigned h0 = HASH(remote);
unsigned h1 = HASH(local);
struct ip_tunnel *t;
+ struct ipip_net *ipn = net_generic(net, ipip_net_id);
- for (t = tunnels_r_l[h0^h1]; t; t = t->next) {
+ for (t = ipn->tunnels_r_l[h0^h1]; t; t = t->next) {
if (local == t->parms.iph.saddr &&
remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP))
return t;
}
- for (t = tunnels_r[h0]; t; t = t->next) {
+ for (t = ipn->tunnels_r[h0]; t; t = t->next) {
if (remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP))
return t;
}
- for (t = tunnels_l[h1]; t; t = t->next) {
+ for (t = ipn->tunnels_l[h1]; t; t = t->next) {
if (local == t->parms.iph.saddr && (t->dev->flags&IFF_UP))
return t;
}
- if ((t = tunnels_wc[0]) != NULL && (t->dev->flags&IFF_UP))
+ if ((t = ipn->tunnels_wc[0]) != NULL && (t->dev->flags&IFF_UP))
return t;
return NULL;
}
@@ -179,7 +180,7 @@ static struct ip_tunnel **__ipip_bucket(struct ipip_net *ipn,
prio |= 1;
h ^= HASH(local);
}
- return &tunnels[prio][h];
+ return &ipn->tunnels[prio][h];
}
static inline struct ip_tunnel **ipip_bucket(struct ipip_net *ipn,
@@ -266,7 +267,7 @@ static void ipip_tunnel_uninit(struct net_device *dev)
if (dev == ipn->fb_tunnel_dev) {
write_lock_bh(&ipip_lock);
- tunnels_wc[0] = NULL;
+ ipn->tunnels_wc[0] = NULL;
write_unlock_bh(&ipip_lock);
} else
ipip_tunnel_unlink(ipn, netdev_priv(dev));
@@ -861,6 +862,7 @@ static int ipip_fb_tunnel_init(struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
struct iphdr *iph = &tunnel->parms.iph;
+ struct ipip_net *ipn = net_generic(dev_net(dev), ipip_net_id);
tunnel->dev = dev;
strcpy(tunnel->parms.name, dev->name);
@@ -870,7 +872,7 @@ static int ipip_fb_tunnel_init(struct net_device *dev)
iph->ihl = 5;
dev_hold(dev);
- tunnels_wc[0] = tunnel;
+ ipn->tunnels_wc[0] = tunnel;
return 0;
}
@@ -883,13 +885,27 @@ static struct xfrm_tunnel ipip_handler = {
static char banner[] __initdata =
KERN_INFO "IPv4 over IPv4 tunneling driver\n";
+static void ipip_destroy_tunnels(struct ipip_net *ipn)
+{
+ int prio;
+
+ for (prio = 1; prio < 4; prio++) {
+ int h;
+ for (h = 0; h < HASH_SIZE; h++) {
+ struct ip_tunnel *t;
+ while ((t = ipn->tunnels[prio][h]) != NULL)
+ unregister_netdevice(t->dev);
+ }
+ }
+}
+
static int ipip_init_net(struct net *net)
{
int err;
struct ipip_net *ipn;
err = -ENOMEM;
- ipn = kmalloc(sizeof(struct ipip_net), GFP_KERNEL);
+ ipn = kzalloc(sizeof(struct ipip_net), GFP_KERNEL);
if (ipn == NULL)
goto err_alloc;
@@ -897,6 +913,11 @@ static int ipip_init_net(struct net *net)
if (err < 0)
goto err_assign;
+ ipn->tunnels[0] = ipn->tunnels_wc;
+ ipn->tunnels[1] = ipn->tunnels_l;
+ ipn->tunnels[2] = ipn->tunnels_r;
+ ipn->tunnels[3] = ipn->tunnels_r_l;
+
ipn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel),
"tunl0",
ipip_tunnel_setup);
@@ -929,6 +950,7 @@ static void ipip_exit_net(struct net *net)
ipn = net_generic(net, ipip_net_id);
rtnl_lock();
+ ipip_destroy_tunnels(ipn);
unregister_netdevice(ipn->fb_tunnel_dev);
rtnl_unlock();
kfree(ipn);
@@ -957,29 +979,11 @@ static int __init ipip_init(void)
return err;
}
-static void __exit ipip_destroy_tunnels(void)
-{
- int prio;
-
- for (prio = 1; prio < 4; prio++) {
- int h;
- for (h = 0; h < HASH_SIZE; h++) {
- struct ip_tunnel *t;
- while ((t = tunnels[prio][h]) != NULL)
- unregister_netdevice(t->dev);
- }
- }
-}
-
static void __exit ipip_fini(void)
{
if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET))
printk(KERN_INFO "ipip close: can't deregister tunnel\n");
- rtnl_lock();
- ipip_destroy_tunnels();
- rtnl_unlock();
-
unregister_pernet_gen_device(ipip_net_id, &ipip_net_ops);
}
--
1.5.3.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-2.6.26 6/8][IPIP]: Use proper net in (mostly) routing calls.
2008-04-15 12:25 [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces Pavel Emelyanov
` (4 preceding siblings ...)
2008-04-15 12:36 ` [PATCH net-2.6.26 5/8][IPIP]: Make tunnels hashes per net Pavel Emelyanov
@ 2008-04-15 12:38 ` Pavel Emelyanov
2008-04-15 12:39 ` [PATCH net-2.6.26 7/8][IPIP]: Allow to create IPIP tunnels in net namespaces Pavel Emelyanov
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 12:38 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List
There are some ip_route_output_key() calls in there that require
a proper net so give one to them.
Besides - give a proper net to a single __get_dev_by_index call
in ipip_tunnel_bind_dev().
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
net/ipv4/ipip.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 9c2939b..1de39e1 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -415,7 +415,7 @@ out:
fl.fl4_daddr = eiph->saddr;
fl.fl4_tos = RT_TOS(eiph->tos);
fl.proto = IPPROTO_IPIP;
- if (ip_route_output_key(&init_net, &rt, &key)) {
+ if (ip_route_output_key(dev_net(skb->dev), &rt, &key)) {
kfree_skb(skb2);
return 0;
}
@@ -428,7 +428,7 @@ out:
fl.fl4_daddr = 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);
kfree_skb(skb2);
@@ -558,7 +558,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
.saddr = tiph->saddr,
.tos = RT_TOS(tos) } },
.proto = IPPROTO_IPIP };
- if (ip_route_output_key(&init_net, &rt, &fl)) {
+ if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
tunnel->stat.tx_carrier_errors++;
goto tx_error_icmp;
}
@@ -679,7 +679,7 @@ static void ipip_tunnel_bind_dev(struct net_device *dev)
.tos = RT_TOS(iph->tos) } },
.proto = IPPROTO_IPIP };
struct rtable *rt;
- if (!ip_route_output_key(&init_net, &rt, &fl)) {
+ if (!ip_route_output_key(dev_net(dev), &rt, &fl)) {
tdev = rt->u.dst.dev;
ip_rt_put(rt);
}
@@ -687,7 +687,7 @@ static void ipip_tunnel_bind_dev(struct net_device *dev)
}
if (!tdev && tunnel->parms.link)
- tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
+ tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link);
if (tdev) {
dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
--
1.5.3.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-2.6.26 7/8][IPIP]: Allow to create IPIP tunnels in net namespaces.
2008-04-15 12:25 [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces Pavel Emelyanov
` (5 preceding siblings ...)
2008-04-15 12:38 ` [PATCH net-2.6.26 6/8][IPIP]: Use proper net in (mostly) routing calls Pavel Emelyanov
@ 2008-04-15 12:39 ` Pavel Emelyanov
2008-04-15 12:41 ` [PATCH net-2.6.26 8/8][IPIP]: Allow for IPPROTO_IPIP protocol in namespaces Pavel Emelyanov
2008-04-16 8:08 ` [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces David Miller
8 siblings, 0 replies; 10+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 12:39 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List
Set the proper net before calling register_netdev and disable
the tunnel device netns changing.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
net/ipv4/ipip.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 1de39e1..149111f 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -239,6 +239,8 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net,
if (dev == NULL)
return NULL;
+ dev_net_set(dev, net);
+
if (strchr(name, '%')) {
if (dev_alloc_name(dev, name) < 0)
goto failed_free;
@@ -839,6 +841,7 @@ static void ipip_tunnel_setup(struct net_device *dev)
dev->flags = IFF_NOARP;
dev->iflink = 0;
dev->addr_len = 4;
+ dev->features |= NETIF_F_NETNS_LOCAL;
}
static int ipip_tunnel_init(struct net_device *dev)
--
1.5.3.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-2.6.26 8/8][IPIP]: Allow for IPPROTO_IPIP protocol in namespaces.
2008-04-15 12:25 [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces Pavel Emelyanov
` (6 preceding siblings ...)
2008-04-15 12:39 ` [PATCH net-2.6.26 7/8][IPIP]: Allow to create IPIP tunnels in net namespaces Pavel Emelyanov
@ 2008-04-15 12:41 ` Pavel Emelyanov
2008-04-16 8:08 ` [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces David Miller
8 siblings, 0 replies; 10+ messages in thread
From: Pavel Emelyanov @ 2008-04-15 12:41 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List
This one was disabled by default for sanity.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
net/ipv4/tunnel4.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c
index 978b3fd..cc4cd0e 100644
--- a/net/ipv4/tunnel4.c
+++ b/net/ipv4/tunnel4.c
@@ -136,6 +136,7 @@ static struct net_protocol tunnel4_protocol = {
.handler = tunnel4_rcv,
.err_handler = tunnel4_err,
.no_policy = 1,
+ .netns_ok = 1,
};
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
--
1.5.3.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces.
2008-04-15 12:25 [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces Pavel Emelyanov
` (7 preceding siblings ...)
2008-04-15 12:41 ` [PATCH net-2.6.26 8/8][IPIP]: Allow for IPPROTO_IPIP protocol in namespaces Pavel Emelyanov
@ 2008-04-16 8:08 ` David Miller
8 siblings, 0 replies; 10+ messages in thread
From: David Miller @ 2008-04-16 8:08 UTC (permalink / raw)
To: xemul; +Cc: netdev
From: Pavel Emelyanov <xemul@openvz.org>
Date: Tue, 15 Apr 2008 16:25:00 +0400
> Make yet another useful virtual device work in namespaces.
>
> This set is also isolated from the other "make xxx device work
> in net namespaces" ones.
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Applied and pushed to net-2.6.26, thanks Pavel.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2008-04-16 8:08 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-15 12:25 [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces Pavel Emelyanov
2008-04-15 12:26 ` [PATCH net-2.6.26 1/8][IPIP]: Introduce empty ipip_net structure and net init/exit ops Pavel Emelyanov
2008-04-15 12:29 ` [PATCH net-2.6.26 2/8][IPIP]: Make the fallback tunnel device per-net Pavel Emelyanov
2008-04-15 12:31 ` [PATCH net-2.6.26 3/8][IPIP]: Add net/ipip_net argument to some functions Pavel Emelyanov
2008-04-15 12:33 ` [PATCH net-2.6.26 4/8][IPIP]: Use proper net in hash-lookup functions Pavel Emelyanov
2008-04-15 12:36 ` [PATCH net-2.6.26 5/8][IPIP]: Make tunnels hashes per net Pavel Emelyanov
2008-04-15 12:38 ` [PATCH net-2.6.26 6/8][IPIP]: Use proper net in (mostly) routing calls Pavel Emelyanov
2008-04-15 12:39 ` [PATCH net-2.6.26 7/8][IPIP]: Allow to create IPIP tunnels in net namespaces Pavel Emelyanov
2008-04-15 12:41 ` [PATCH net-2.6.26 8/8][IPIP]: Allow for IPPROTO_IPIP protocol in namespaces Pavel Emelyanov
2008-04-16 8:08 ` [PATCH net-2.6.26 0/8][IPIP]: Make IPIP tunnel work in net namespaces David Miller
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.