* [patch 00/38][IPV6] ipv6 per network namespace
@ 2007-12-03 16:16 Daniel Lezcano
2007-12-03 16:16 ` [patch 01/38][IPV6] net-2.6.25 - make netns cleanup to run in a separate queue Daniel Lezcano
` (37 more replies)
0 siblings, 38 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
This patchset provides the changes to make the ipv6 protocol to handle
multiple network namespaces.
There is a pre-requesite which is already merged in net-2.6.25, it is
the separate workq for the network namespace cleanup. It will
disappear when Denis will rebase the patchset to the latest
net-2.6.25.
The sysctl per net is not yet implemented (coming soon), the patchset
adds a check to activate the network namespace only if sysctl is
disabled. It will be reverted as soon as we handle sysctl.
This subset makes per namespace:
* inet6_addr
* ip6_fib
* fib6_rules
* rt6_stats
* rt6_info
* route6
* addrconf
* ndisc
The patchset is a little big, but it is difficult to check and test without
a minimal subset of features of the protocol. So at this point we are able to
create routes and addresses per namespaces, we can check the procfs files,
setup interfaces, check the address autoconfiguration is done and the
different routes are created, etc ...
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 01/38][IPV6] net-2.6.25 - make netns cleanup to run in a separate queue
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 02/38][IPV6] Makefile - Activate netns configuration when sysctl is off Daniel Lezcano
` (36 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: ebiederm-aS9lmoZGLiVWk0Htik3J/w,
containers-qjLDD68F18O7TbgM5vRIOg, Denis V. Lunev,
xemul-GEFAQzZX7r8dnm+yROfE0A, Benjamin Thery
[-- Attachment #1: create-workq-for-the-namespace.patch --]
[-- Type: text/plain, Size: 1905 bytes --]
This patch adds a separate workqueue for cleaning up a network
namespace. If we use the keventd workqueue to execute cleanup_net(),
there is a problem to unregister devices in IPv6. Indeed the code
that cleans up also schedule work in keventd: as long as cleanup_net()
hasn't return, dst_gc_task() cannot run and as long as dst_gc_task() has
not run, there are still some references pending on the net devices and
cleanup_net() can not unregister and exit the keventd workqueue.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
Acked-by: Denis V. Lunev <den-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
Acked-By: Kirill Korotaev <dev-3ImXcnM4P+0@public.gmane.org>
---
net/core/net_namespace.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
Index: linux-2.6-netns/net/core/net_namespace.c
===================================================================
--- linux-2.6-netns.orig/net/core/net_namespace.c
+++ linux-2.6-netns/net/core/net_namespace.c
@@ -58,6 +58,7 @@ out_undo:
#ifdef CONFIG_NET_NS
static struct kmem_cache *net_cachep;
+static struct workqueue_struct *netns_wq;
static struct net *net_alloc(void)
{
@@ -149,7 +150,7 @@ void __put_net(struct net *net)
{
/* Cleanup the network namespace in process context */
INIT_WORK(&net->work, cleanup_net);
- schedule_work(&net->work);
+ queue_work(netns_wq, &net->work);
}
EXPORT_SYMBOL_GPL(__put_net);
@@ -171,7 +172,13 @@ static int __init net_ns_init(void)
net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
SMP_CACHE_BYTES,
SLAB_PANIC, NULL);
+
+ /* Create workqueue for cleanup */
+ netns_wq = create_singlethread_workqueue("netns");
+ if (!netns_wq)
+ panic("Could not create netns workq");
#endif
+
mutex_lock(&net_mutex);
err = setup_net(&init_net);
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 02/38][IPV6] Makefile - Activate netns configuration when sysctl is off
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
2007-12-03 16:16 ` [patch 01/38][IPV6] net-2.6.25 - make netns cleanup to run in a separate queue Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 03/38][IPV6] inet6_addr - isolate inet6 addresses from proc file Daniel Lezcano
` (35 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: disable-config-net-ns-if-config-sysctl-is-on.patch --]
[-- Type: text/plain, Size: 853 bytes --]
Sysctl per namespace is not yet finished, like sysfs. In order
to avoid problems related with that, I disable netns if sysctl
is compiled in the kernel.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux-2.6-netns/net/Kconfig
===================================================================
--- linux-2.6-netns.orig/net/Kconfig
+++ linux-2.6-netns/net/Kconfig
@@ -30,7 +30,7 @@ menu "Networking options"
config NET_NS
bool "Network namespace support"
default n
- depends on EXPERIMENTAL && !SYSFS
+ depends on EXPERIMENTAL && !SYSFS && !SYSCTL
help
Allow user space to create what appear to be multiple instances
of the network stack.
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 03/38][IPV6] inet6_addr - isolate inet6 addresses from proc file
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
2007-12-03 16:16 ` [patch 01/38][IPV6] net-2.6.25 - make netns cleanup to run in a separate queue Daniel Lezcano
2007-12-03 16:16 ` [patch 02/38][IPV6] Makefile - Activate netns configuration when sysctl is off Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 04/38][IPV6] inet6_addr - check ipv6 address per namespace Daniel Lezcano
` (34 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: inet6-addr-handle-procfs.patch --]
[-- Type: text/plain, Size: 3021 bytes --]
Make /proc/net/if_inet6 show only inet6 addresses belonging
to the namespace.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/addrconf.c | 48 +++++++++++++++++++++++++++++++++++++++---------
1 file changed, 39 insertions(+), 9 deletions(-)
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -2699,6 +2699,7 @@ static void addrconf_dad_run(struct inet
#ifdef CONFIG_PROC_FS
struct if6_iter_state {
+ struct seq_net_private p;
int bucket;
};
@@ -2706,11 +2707,16 @@ static struct inet6_ifaddr *if6_get_firs
{
struct inet6_ifaddr *ifa = NULL;
struct if6_iter_state *state = seq->private;
+ struct net *net = state->p.net;
for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) {
ifa = inet6_addr_lst[state->bucket];
- if (ifa)
- break;
+
+ while (ifa && ifa->idev->dev->nd_net != net)
+ ifa = ifa->lst_next;
+ if (!ifa)
+ continue;
+ break;
}
return ifa;
}
@@ -2718,13 +2724,22 @@ static struct inet6_ifaddr *if6_get_firs
static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa)
{
struct if6_iter_state *state = seq->private;
+ struct net *net = state->p.net;
ifa = ifa->lst_next;
try_again:
+ if (ifa) {
+ if (ifa->idev->dev->nd_net != net) {
+ ifa = ifa->lst_next;
+ goto try_again;
+ }
+ }
+
if (!ifa && ++state->bucket < IN6_ADDR_HSIZE) {
ifa = inet6_addr_lst[state->bucket];
goto try_again;
}
+
return ifa;
}
@@ -2781,8 +2796,8 @@ static const struct seq_operations if6_s
static int if6_seq_open(struct inode *inode, struct file *file)
{
- return seq_open_private(file, &if6_seq_ops,
- sizeof(struct if6_iter_state));
+ return seq_open_net(inode, file, &if6_seq_ops,
+ sizeof(struct if6_iter_state));
}
static const struct file_operations if6_fops = {
@@ -2790,19 +2805,34 @@ static const struct file_operations if6_
.open = if6_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release_private,
+ .release = seq_release_net,
+};
+
+static int if6_proc_net_init(struct net *net)
+{
+ if (!proc_net_fops_create(net, "if_inet6", S_IRUGO, &if6_fops))
+ return -ENOMEM;
+ return 0;
+}
+
+static void if6_proc_net_exit(struct net *net)
+{
+ proc_net_remove(net, "if_inet6");
+}
+
+static struct pernet_operations if6_proc_net_ops = {
+ .init = if6_proc_net_init,
+ .exit = if6_proc_net_exit,
};
int __init if6_proc_init(void)
{
- if (!proc_net_fops_create(&init_net, "if_inet6", S_IRUGO, &if6_fops))
- return -ENOMEM;
- return 0;
+ return register_pernet_subsys(&if6_proc_net_ops);
}
void if6_proc_exit(void)
{
- proc_net_remove(&init_net, "if_inet6");
+ unregister_pernet_subsys(&if6_proc_net_ops);
}
#endif /* CONFIG_PROC_FS */
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 04/38][IPV6] inet6_addr - check ipv6 address per namespace
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (2 preceding siblings ...)
2007-12-03 16:16 ` [patch 03/38][IPV6] inet6_addr - isolate inet6 addresses from proc file Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 05/38][IPV6] inet6_addr - make use of the new ipv6_chk_addr function Daniel Lezcano
` (33 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: inet6-addr-ipv6-chk-addr.patch --]
[-- Type: text/plain, Size: 2662 bytes --]
When a new address is added, we must check if the new address does
not already exists.
This patch makes this check to be aware of a network namespace,
so the check will look if the address already exists for the specified
network namespace. While the addresses are browsed, the addresses
which do not belong to the namespace are discarded.
The modifications are trivial here and they do not touch the
callers of the function ipv6_chk_addr.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/addrconf.h | 11 ++++++++++-
net/ipv6/addrconf.c | 7 +++++--
2 files changed, 15 insertions(+), 3 deletions(-)
Index: linux-2.6-netns/include/net/addrconf.h
===================================================================
--- linux-2.6-netns.orig/include/net/addrconf.h
+++ linux-2.6-netns/include/net/addrconf.h
@@ -58,9 +58,18 @@ extern int addrconf_add_ifaddr(void __
extern int addrconf_del_ifaddr(void __user *arg);
extern int addrconf_set_dstaddr(void __user *arg);
-extern int ipv6_chk_addr(struct in6_addr *addr,
+extern int __ipv6_chk_addr(struct net *net,
+ struct in6_addr *addr,
struct net_device *dev,
int strict);
+
+static inline int ipv6_chk_addr(struct in6_addr *addr,
+ struct net_device *dev,
+ int strict)
+{
+ return __ipv6_chk_addr(&init_net, addr, dev, strict);
+}
+
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
extern int ipv6_chk_home_addr(struct in6_addr *addr);
#endif
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -1181,13 +1181,16 @@ static int ipv6_count_addresses(struct i
return cnt;
}
-int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev, int strict)
+int __ipv6_chk_addr(struct net *net, struct in6_addr *addr,
+ struct net_device *dev, int strict)
{
struct inet6_ifaddr * ifp;
u8 hash = ipv6_addr_hash(addr);
read_lock_bh(&addrconf_hash_lock);
for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
+ if (ifp->idev->dev->nd_net != net)
+ continue;
if (ipv6_addr_equal(&ifp->addr, addr) &&
!(ifp->flags&IFA_F_TENTATIVE)) {
if (dev == NULL || ifp->idev->dev == dev ||
@@ -1199,7 +1202,7 @@ int ipv6_chk_addr(struct in6_addr *addr,
return ifp != NULL;
}
-EXPORT_SYMBOL(ipv6_chk_addr);
+EXPORT_SYMBOL(__ipv6_chk_addr);
static
int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev)
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 05/38][IPV6] inet6_addr - make use of the new ipv6_chk_addr function
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (3 preceding siblings ...)
2007-12-03 16:16 ` [patch 04/38][IPV6] inet6_addr - check ipv6 address per namespace Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 06/38][IPV6] inet6_addr - ipv6_chk_same_addr namespace aware Daniel Lezcano
` (32 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: inet6-addr-ipv6-chk-addr-2.patch --]
[-- Type: text/plain, Size: 7443 bytes --]
The previous patch changed the ipv6_chk_addr API and tried
to be focused on the network namespace check. A wrapper avoided
to have the differents caller to be modified.
This patch removes the wrapper and propagate the function API
change to all callers.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/addrconf.h | 9 +--------
net/ipv6/addrconf.c | 4 ++--
net/ipv6/af_inet6.c | 2 +-
net/ipv6/anycast.c | 2 +-
net/ipv6/datagram.c | 2 +-
net/ipv6/icmp.c | 2 +-
net/ipv6/ip6_tunnel.c | 8 ++++----
net/ipv6/ndisc.c | 2 +-
net/ipv6/raw.c | 2 +-
net/sctp/ipv6.c | 5 +++--
10 files changed, 16 insertions(+), 22 deletions(-)
Index: linux-2.6-netns/include/net/addrconf.h
===================================================================
--- linux-2.6-netns.orig/include/net/addrconf.h
+++ linux-2.6-netns/include/net/addrconf.h
@@ -58,18 +58,11 @@ extern int addrconf_add_ifaddr(void __
extern int addrconf_del_ifaddr(void __user *arg);
extern int addrconf_set_dstaddr(void __user *arg);
-extern int __ipv6_chk_addr(struct net *net,
+extern int ipv6_chk_addr(struct net *net,
struct in6_addr *addr,
struct net_device *dev,
int strict);
-static inline int ipv6_chk_addr(struct in6_addr *addr,
- struct net_device *dev,
- int strict)
-{
- return __ipv6_chk_addr(&init_net, addr, dev, strict);
-}
-
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
extern int ipv6_chk_home_addr(struct in6_addr *addr);
#endif
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -1181,7 +1181,7 @@ static int ipv6_count_addresses(struct i
return cnt;
}
-int __ipv6_chk_addr(struct net *net, struct in6_addr *addr,
+int ipv6_chk_addr(struct net *net, struct in6_addr *addr,
struct net_device *dev, int strict)
{
struct inet6_ifaddr * ifp;
@@ -1202,7 +1202,7 @@ int __ipv6_chk_addr(struct net *net, str
return ifp != NULL;
}
-EXPORT_SYMBOL(__ipv6_chk_addr);
+EXPORT_SYMBOL(ipv6_chk_addr);
static
int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev)
Index: linux-2.6-netns/net/ipv6/af_inet6.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/af_inet6.c
+++ linux-2.6-netns/net/ipv6/af_inet6.c
@@ -314,7 +314,7 @@ int inet6_bind(struct socket *sock, stru
*/
v4addr = LOOPBACK4_IPV6;
if (!(addr_type & IPV6_ADDR_MULTICAST)) {
- if (!ipv6_chk_addr(&addr->sin6_addr, dev, 0)) {
+ if (!ipv6_chk_addr(&init_net, &addr->sin6_addr, dev, 0)) {
if (dev)
dev_put(dev);
err = -EADDRNOTAVAIL;
Index: linux-2.6-netns/net/ipv6/anycast.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/anycast.c
+++ linux-2.6-netns/net/ipv6/anycast.c
@@ -89,7 +89,7 @@ int ipv6_sock_ac_join(struct sock *sk, i
return -EPERM;
if (ipv6_addr_is_multicast(addr))
return -EINVAL;
- if (ipv6_chk_addr(addr, NULL, 0))
+ if (ipv6_chk_addr(&init_net, addr, NULL, 0))
return -EINVAL;
pac = sock_kmalloc(sk, sizeof(struct ipv6_ac_socklist), GFP_KERNEL);
Index: linux-2.6-netns/net/ipv6/datagram.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/datagram.c
+++ linux-2.6-netns/net/ipv6/datagram.c
@@ -550,7 +550,7 @@ int datagram_send_ctl(struct msghdr *msg
return -ENODEV;
}
}
- if (!ipv6_chk_addr(&src_info->ipi6_addr, dev, 0)) {
+ if (!ipv6_chk_addr(&init_net, &src_info->ipi6_addr, dev, 0)) {
if (dev)
dev_put(dev);
err = -EINVAL;
Index: linux-2.6-netns/net/ipv6/icmp.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/icmp.c
+++ linux-2.6-netns/net/ipv6/icmp.c
@@ -331,7 +331,7 @@ void icmpv6_send(struct sk_buff *skb, in
*/
addr_type = ipv6_addr_type(&hdr->daddr);
- if (ipv6_chk_addr(&hdr->daddr, skb->dev, 0))
+ if (ipv6_chk_addr(&init_net, &hdr->daddr, skb->dev, 0))
saddr = &hdr->daddr;
/*
Index: linux-2.6-netns/net/ipv6/ip6_tunnel.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_tunnel.c
+++ linux-2.6-netns/net/ipv6/ip6_tunnel.c
@@ -654,8 +654,8 @@ static inline int ip6_tnl_rcv_ctl(struct
ldev = dev_get_by_index(&init_net, p->link);
if ((ipv6_addr_is_multicast(&p->laddr) ||
- likely(ipv6_chk_addr(&p->laddr, ldev, 0))) &&
- likely(!ipv6_chk_addr(&p->raddr, NULL, 0)))
+ likely(ipv6_chk_addr(&init_net, &p->laddr, ldev, 0))) &&
+ likely(!ipv6_chk_addr(&init_net, &p->raddr, NULL, 0)))
ret = 1;
if (ldev)
@@ -789,12 +789,12 @@ static inline int ip6_tnl_xmit_ctl(struc
if (p->link)
ldev = dev_get_by_index(&init_net, p->link);
- if (unlikely(!ipv6_chk_addr(&p->laddr, ldev, 0)))
+ if (unlikely(!ipv6_chk_addr(&init_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(&p->raddr, NULL, 0)))
+ unlikely(ipv6_chk_addr(&init_net, &p->raddr, NULL, 0)))
printk(KERN_WARNING
"%s xmit: Routing loop! "
"Remote address found on this node!\n",
Index: linux-2.6-netns/net/ipv6/ndisc.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ndisc.c
+++ linux-2.6-netns/net/ipv6/ndisc.c
@@ -654,7 +654,7 @@ static void ndisc_solicit(struct neighbo
struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
int probes = atomic_read(&neigh->probes);
- if (skb && ipv6_chk_addr(&ipv6_hdr(skb)->saddr, dev, 1))
+ if (skb && ipv6_chk_addr(&init_net, &ipv6_hdr(skb)->saddr, dev, 1))
saddr = &ipv6_hdr(skb)->saddr;
if ((probes -= neigh->parms->ucast_probes) < 0) {
Index: linux-2.6-netns/net/ipv6/raw.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/raw.c
+++ linux-2.6-netns/net/ipv6/raw.c
@@ -298,7 +298,7 @@ static int rawv6_bind(struct sock *sk, s
v4addr = LOOPBACK4_IPV6;
if (!(addr_type & IPV6_ADDR_MULTICAST)) {
err = -EADDRNOTAVAIL;
- if (!ipv6_chk_addr(&addr->sin6_addr, dev, 0)) {
+ if (!ipv6_chk_addr(&init_net, &addr->sin6_addr, dev, 0)) {
if (dev)
dev_put(dev);
goto out;
Index: linux-2.6-netns/net/sctp/ipv6.c
===================================================================
--- linux-2.6-netns.orig/net/sctp/ipv6.c
+++ linux-2.6-netns/net/sctp/ipv6.c
@@ -558,7 +558,7 @@ static int sctp_v6_available(union sctp_
if (!(type & IPV6_ADDR_UNICAST))
return 0;
- return ipv6_chk_addr(in6, NULL, 0);
+ return ipv6_chk_addr(&init_net, in6, NULL, 0);
}
/* This function checks if the address is a valid address to be used for
@@ -860,7 +860,8 @@ static int sctp_inet6_bind_verify(struct
dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id);
if (!dev)
return 0;
- if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) {
+ if (!ipv6_chk_addr(&init_net, &addr->v6.sin6_addr,
+ dev, 0)) {
dev_put(dev);
return 0;
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 06/38][IPV6] inet6_addr - ipv6_chk_same_addr namespace aware
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (4 preceding siblings ...)
2007-12-03 16:16 ` [patch 05/38][IPV6] inet6_addr - make use of the new ipv6_chk_addr function Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 07/38][IPV6] inet6_addr - ipv6_get_ifaddr " Daniel Lezcano
` (31 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: inet6-addr-ipv6-chk-same-addr.patch --]
[-- Type: text/plain, Size: 1929 bytes --]
This patch makes ipv6_chk_same_addr function to be aware of the network
namespace. The addresses not belonging to the network namespace are
discarded.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/addrconf.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -141,7 +141,8 @@ static void ipv6_ifa_notify(int event, s
static void inet6_prefix_notify(int event, struct inet6_dev *idev,
struct prefix_info *pinfo);
-static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev);
+static int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
+ struct net_device *dev);
static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
@@ -535,7 +536,7 @@ ipv6_add_addr(struct inet6_dev *idev, co
write_lock(&addrconf_hash_lock);
/* Ignore adding duplicate addresses on an interface */
- if (ipv6_chk_same_addr(addr, idev->dev)) {
+ if (ipv6_chk_same_addr(idev->dev->nd_net, addr, idev->dev)) {
ADBG(("ipv6_add_addr: already assigned\n"));
err = -EEXIST;
goto out;
@@ -1205,12 +1206,15 @@ int ipv6_chk_addr(struct net *net, struc
EXPORT_SYMBOL(ipv6_chk_addr);
static
-int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev)
+int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
+ struct net_device *dev)
{
struct inet6_ifaddr * ifp;
u8 hash = ipv6_addr_hash(addr);
for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
+ if (ifp->idev->dev->nd_net != net)
+ continue;
if (ipv6_addr_equal(&ifp->addr, addr)) {
if (dev == NULL || ifp->idev->dev == dev)
break;
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 07/38][IPV6] inet6_addr - ipv6_get_ifaddr namespace aware
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (5 preceding siblings ...)
2007-12-03 16:16 ` [patch 06/38][IPV6] inet6_addr - ipv6_chk_same_addr namespace aware Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 08/38][IPV6] inet6_addr - remove ipv6_get_ifaddr wrapper Daniel Lezcano
` (30 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: inet6-addr-ipv6-get-ifaddr.patch --]
[-- Type: text/plain, Size: 2561 bytes --]
The inet6_addr_lst is browsed taking into account the network
namespace specified as parameter. If an address does not belong
to the specified namespace, it is ignored.
In order to reduce the scope of the patch, a wrapper has been
created to not impact all the callers.
The next patch will remove this wrapper and change all the wrappers
to take into account this new parameter.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/addrconf.h | 15 ++++++++++++---
net/ipv6/addrconf.c | 5 ++++-
2 files changed, 16 insertions(+), 4 deletions(-)
Index: linux-2.6-netns/include/net/addrconf.h
===================================================================
--- linux-2.6-netns.orig/include/net/addrconf.h
+++ linux-2.6-netns/include/net/addrconf.h
@@ -66,9 +66,18 @@ extern int ipv6_chk_addr(struct net *n
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
extern int ipv6_chk_home_addr(struct in6_addr *addr);
#endif
-extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr,
- struct net_device *dev,
- int strict);
+extern struct inet6_ifaddr *__ipv6_get_ifaddr(struct net *net,
+ struct in6_addr *addr,
+ struct net_device *dev,
+ int strict);
+
+static inline struct inet6_ifaddr *ipv6_get_ifaddr(struct in6_addr *addr,
+ struct net_device *dev,
+ int strict)
+{
+ return __ipv6_get_ifaddr(&init_net, addr, dev, strict);
+}
+
extern int ipv6_get_saddr(struct dst_entry *dst,
struct in6_addr *daddr,
struct in6_addr *saddr);
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -1223,13 +1223,16 @@ int ipv6_chk_same_addr(struct net *net,
return ifp != NULL;
}
-struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device *dev, int strict)
+struct inet6_ifaddr * __ipv6_get_ifaddr(struct net *net, struct in6_addr *addr,
+ struct net_device *dev, int strict)
{
struct inet6_ifaddr * ifp;
u8 hash = ipv6_addr_hash(addr);
read_lock_bh(&addrconf_hash_lock);
for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
+ if (ifp->idev->dev->nd_net != net)
+ continue;
if (ipv6_addr_equal(&ifp->addr, addr)) {
if (dev == NULL || ifp->idev->dev == dev ||
!(ifp->scope&(IFA_LINK|IFA_HOST) || strict)) {
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 08/38][IPV6] inet6_addr - remove ipv6_get_ifaddr wrapper
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (6 preceding siblings ...)
2007-12-03 16:16 ` [patch 07/38][IPV6] inet6_addr - ipv6_get_ifaddr " Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 09/38][IPV6] inet6_addr - make ipv6_chk_home_addr namespace aware Daniel Lezcano
` (29 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: inet6-addr-ipv6-get-ifaddr-2.patch --]
[-- Type: text/plain, Size: 5108 bytes --]
The previous patch introduced a new parameter to the ipv6_get_ifaddr
function and made a wrapper around it in order to reduce the impact
of the patch and to facilitate code review.
This patch removes the wrapper and propagate the function change to
all callers.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/addrconf.h | 15 ++++-----------
net/ipv6/addrconf.c | 10 +++++-----
net/ipv6/ip6_output.c | 3 ++-
net/ipv6/ndisc.c | 9 +++++----
4 files changed, 16 insertions(+), 21 deletions(-)
Index: linux-2.6-netns/include/net/addrconf.h
===================================================================
--- linux-2.6-netns.orig/include/net/addrconf.h
+++ linux-2.6-netns/include/net/addrconf.h
@@ -66,17 +66,10 @@ extern int ipv6_chk_addr(struct net *n
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
extern int ipv6_chk_home_addr(struct in6_addr *addr);
#endif
-extern struct inet6_ifaddr *__ipv6_get_ifaddr(struct net *net,
- struct in6_addr *addr,
- struct net_device *dev,
- int strict);
-
-static inline struct inet6_ifaddr *ipv6_get_ifaddr(struct in6_addr *addr,
- struct net_device *dev,
- int strict)
-{
- return __ipv6_get_ifaddr(&init_net, addr, dev, strict);
-}
+extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
+ struct in6_addr *addr,
+ struct net_device *dev,
+ int strict);
extern int ipv6_get_saddr(struct dst_entry *dst,
struct in6_addr *daddr,
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -1223,8 +1223,8 @@ int ipv6_chk_same_addr(struct net *net,
return ifp != NULL;
}
-struct inet6_ifaddr * __ipv6_get_ifaddr(struct net *net, struct in6_addr *addr,
- struct net_device *dev, int strict)
+struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr,
+ struct net_device *dev, int strict)
{
struct inet6_ifaddr * ifp;
u8 hash = ipv6_addr_hash(addr);
@@ -1715,7 +1715,7 @@ void addrconf_prefix_rcv(struct net_devi
ok:
- ifp = ipv6_get_ifaddr(&addr, dev, 1);
+ ifp = ipv6_get_ifaddr(dev->nd_net, &addr, dev, 1);
if (ifp == NULL && valid_lft) {
int max_addresses = in6_dev->cnf.max_addresses;
@@ -3103,7 +3103,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, s
/* We ignore other flags so far. */
ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS);
- ifa = ipv6_get_ifaddr(pfx, dev, 1);
+ ifa = ipv6_get_ifaddr(net, pfx, dev, 1);
if (ifa == NULL) {
/*
* It would be best to check for !NLM_F_CREATE here but
@@ -3410,7 +3410,7 @@ static int inet6_rtm_getaddr(struct sk_b
if (ifm->ifa_index)
dev = __dev_get_by_index(&init_net, ifm->ifa_index);
- if ((ifa = ipv6_get_ifaddr(addr, dev, 1)) == NULL) {
+ if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) {
err = -EADDRNOTAVAIL;
goto errout;
}
Index: linux-2.6-netns/net/ipv6/ip6_output.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_output.c
+++ linux-2.6-netns/net/ipv6/ip6_output.c
@@ -936,7 +936,8 @@ static int ip6_dst_lookup_tail(struct so
struct flowi fl_gw;
int redirect;
- ifp = ipv6_get_ifaddr(&fl->fl6_src, (*dst)->dev, 1);
+ ifp = ipv6_get_ifaddr(&init_net, &fl->fl6_src,
+ (*dst)->dev, 1);
redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
if (ifp)
Index: linux-2.6-netns/net/ipv6/ndisc.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ndisc.c
+++ linux-2.6-netns/net/ipv6/ndisc.c
@@ -557,7 +557,7 @@ static void ndisc_send_na(struct net_dev
};
/* for anycast or proxy, solicited_addr != src_addr */
- ifp = ipv6_get_ifaddr(solicited_addr, dev, 1);
+ ifp = ipv6_get_ifaddr(&init_net, solicited_addr, dev, 1);
if (ifp) {
src_addr = solicited_addr;
if (ifp->flags & IFA_F_OPTIMISTIC)
@@ -617,7 +617,8 @@ void ndisc_send_rs(struct net_device *de
* supress the inclusion of the sllao.
*/
if (send_sllao) {
- struct inet6_ifaddr *ifp = ipv6_get_ifaddr(saddr, dev, 1);
+ struct inet6_ifaddr *ifp = ipv6_get_ifaddr(&init_net, saddr,
+ dev, 1);
if (ifp) {
if (ifp->flags & IFA_F_OPTIMISTIC) {
send_sllao = 0;
@@ -742,7 +743,7 @@ static void ndisc_recv_ns(struct sk_buff
inc = ipv6_addr_is_multicast(daddr);
- if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) {
+ if ((ifp = ipv6_get_ifaddr(&init_net, &msg->target, dev, 1)) != NULL) {
if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) {
if (dad) {
@@ -900,7 +901,7 @@ static void ndisc_recv_na(struct sk_buff
return;
}
}
- if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1))) {
+ if ((ifp = ipv6_get_ifaddr(&init_net, &msg->target, dev, 1))) {
if (ifp->flags & IFA_F_TENTATIVE) {
addrconf_dad_failure(ifp);
return;
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 09/38][IPV6] inet6_addr - make ipv6_chk_home_addr namespace aware
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (7 preceding siblings ...)
2007-12-03 16:16 ` [patch 08/38][IPV6] inet6_addr - remove ipv6_get_ifaddr wrapper Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 10/38][IPV6] ip6_fib - make mindless changes Daniel Lezcano
` (28 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: inet6-addr-ipv6-chk-home-addr.patch --]
[-- Type: text/plain, Size: 2313 bytes --]
Looks if the address is belonging to the network namespace, otherwise
discard the address for the check.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/addrconf.h | 3 ++-
net/ipv6/addrconf.c | 4 +++-
net/ipv6/exthdrs.c | 2 +-
3 files changed, 6 insertions(+), 3 deletions(-)
Index: linux-2.6-netns/include/net/addrconf.h
===================================================================
--- linux-2.6-netns.orig/include/net/addrconf.h
+++ linux-2.6-netns/include/net/addrconf.h
@@ -64,7 +64,8 @@ extern int ipv6_chk_addr(struct net *n
int strict);
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
-extern int ipv6_chk_home_addr(struct in6_addr *addr);
+extern int ipv6_chk_home_addr(struct net *net,
+ struct in6_addr *addr);
#endif
extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
struct in6_addr *addr,
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -2848,13 +2848,15 @@ void if6_proc_exit(void)
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
/* Check if address is a home address configured on any interface. */
-int ipv6_chk_home_addr(struct in6_addr *addr)
+int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr)
{
int ret = 0;
struct inet6_ifaddr * ifp;
u8 hash = ipv6_addr_hash(addr);
read_lock_bh(&addrconf_hash_lock);
for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) {
+ if (ifp->idev->dev->nd_net != net)
+ continue;
if (ipv6_addr_cmp(&ifp->addr, addr) == 0 &&
(ifp->flags & IFA_F_HOMEADDRESS)) {
ret = 1;
Index: linux-2.6-netns/net/ipv6/exthdrs.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/exthdrs.c
+++ linux-2.6-netns/net/ipv6/exthdrs.c
@@ -467,7 +467,7 @@ looped_back:
kfree_skb(skb);
return -1;
}
- if (!ipv6_chk_home_addr(addr)) {
+ if (!ipv6_chk_home_addr(&init_net, addr)) {
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
IPSTATS_MIB_INADDRERRORS);
kfree_skb(skb);
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 10/38][IPV6] ip6_fib - make mindless changes
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (8 preceding siblings ...)
2007-12-03 16:16 ` [patch 09/38][IPV6] inet6_addr - make ipv6_chk_home_addr namespace aware Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 11/38][IPV6] ip6_fib - dynamically allocate fib tables Daniel Lezcano
` (27 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: ip6-fib-dynamic-make-mindless-changes.patch --]
[-- Type: text/plain, Size: 2407 bytes --]
This patch changes all references to the static global variables
fib6_main_tbl and fib6_local_tbl by a pointer. That provides the
minimal changes to dynamically allocate these tables for the network
namespaces.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/ip6_fib.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -166,7 +166,7 @@ static __inline__ void rt6_release(struc
dst_free(&rt->u.dst);
}
-static struct fib6_table fib6_main_tbl = {
+static struct fib6_table __fib6_main_tbl = {
.tb6_id = RT6_TABLE_MAIN,
.tb6_root = {
.leaf = &ip6_null_entry,
@@ -174,6 +174,8 @@ static struct fib6_table fib6_main_tbl =
},
};
+static struct fib6_table *fib6_main_tbl = &__fib6_main_tbl;
+
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
#define FIB_TABLE_HASHSZ 256
#else
@@ -201,7 +203,7 @@ static void fib6_link_table(struct fib6_
}
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
-static struct fib6_table fib6_local_tbl = {
+static struct fib6_table __fib6_local_tbl = {
.tb6_id = RT6_TABLE_LOCAL,
.tb6_root = {
.leaf = &ip6_null_entry,
@@ -209,6 +211,8 @@ static struct fib6_table fib6_local_tbl
},
};
+static struct fib6_table *fib6_local_tbl = &__fib6_local_tbl;
+
static struct fib6_table *fib6_alloc_table(u32 id)
{
struct fib6_table *table;
@@ -263,8 +267,8 @@ struct fib6_table *fib6_get_table(u32 id
static void __init fib6_tables_init(void)
{
- fib6_link_table(&fib6_main_tbl);
- fib6_link_table(&fib6_local_tbl);
+ fib6_link_table(fib6_main_tbl);
+ fib6_link_table(fib6_local_tbl);
}
#else
@@ -276,18 +280,18 @@ struct fib6_table *fib6_new_table(u32 id
struct fib6_table *fib6_get_table(u32 id)
{
- return &fib6_main_tbl;
+ return fib6_main_tbl;
}
struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags,
pol_lookup_t lookup)
{
- return (struct dst_entry *) lookup(&fib6_main_tbl, fl, flags);
+ return (struct dst_entry *) lookup(fib6_main_tbl, fl, flags);
}
static void __init fib6_tables_init(void)
{
- fib6_link_table(&fib6_main_tbl);
+ fib6_link_table(fib6_main_tbl);
}
#endif
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 11/38][IPV6] ip6_fib - dynamically allocate fib tables
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (9 preceding siblings ...)
2007-12-03 16:16 ` [patch 10/38][IPV6] ip6_fib - make mindless changes Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 12/38][IPV6] ip6_fib - move the fib table to the network namespace Daniel Lezcano
` (26 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: ip6-fib-dynamic-allocation.patch --]
[-- Type: text/plain, Size: 2763 bytes --]
The fib tables are dynamically allocated in init and exit functions.
That provides the ability to do multiple instanciations of these tables.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/ip6_fib.c | 43 +++++++++++++++++++++++++------------------
1 file changed, 25 insertions(+), 18 deletions(-)
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -166,22 +166,14 @@ static __inline__ void rt6_release(struc
dst_free(&rt->u.dst);
}
-static struct fib6_table __fib6_main_tbl = {
- .tb6_id = RT6_TABLE_MAIN,
- .tb6_root = {
- .leaf = &ip6_null_entry,
- .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO,
- },
-};
-
-static struct fib6_table *fib6_main_tbl = &__fib6_main_tbl;
+static struct fib6_table *fib6_main_tbl;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
#define FIB_TABLE_HASHSZ 256
#else
#define FIB_TABLE_HASHSZ 1
#endif
-static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
+static struct hlist_head *fib_table_hash;
static void fib6_link_table(struct fib6_table *tb)
{
@@ -203,15 +195,8 @@ static void fib6_link_table(struct fib6_
}
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
-static struct fib6_table __fib6_local_tbl = {
- .tb6_id = RT6_TABLE_LOCAL,
- .tb6_root = {
- .leaf = &ip6_null_entry,
- .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO,
- },
-};
-static struct fib6_table *fib6_local_tbl = &__fib6_local_tbl;
+static struct fib6_table *fib6_local_tbl;
static struct fib6_table *fib6_alloc_table(u32 id)
{
@@ -1489,6 +1474,28 @@ void __init fib6_init(void)
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
NULL);
+ fib_table_hash = kzalloc(sizeof(*fib_table_hash)*FIB_TABLE_HASHSZ, GFP_KERNEL);
+ if (!fib_table_hash)
+ panic("IPV6: Failed to allocate fib_table_hash.\n");
+
+ fib6_main_tbl = kzalloc(sizeof(*fib6_main_tbl), GFP_KERNEL);
+ if (!fib6_main_tbl)
+ panic("IPV6: Failed to allocate fib6_main_tbl.\n");
+
+ fib6_main_tbl->tb6_id = RT6_TABLE_MAIN;
+ fib6_main_tbl->tb6_root.leaf = &ip6_null_entry;
+ fib6_main_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
+
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+ fib6_local_tbl = kzalloc(sizeof(*fib6_local_tbl), GFP_KERNEL);
+ if (!fib6_local_tbl)
+ panic("IPV6: Failed to allocate fib6_local_tbl.\n");
+
+ fib6_local_tbl->tb6_id = RT6_TABLE_LOCAL;
+ fib6_local_tbl->tb6_root.leaf = &ip6_null_entry;
+ fib6_local_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
+#endif
+
fib6_tables_init();
__rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib);
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 12/38][IPV6] ip6_fib - move the fib table to the network namespace
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (10 preceding siblings ...)
2007-12-03 16:16 ` [patch 11/38][IPV6] ip6_fib - dynamically allocate fib tables Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
[not found] ` <20071203162453.368428873-WECHFHqYCmGD/CxQmPlnQ0FT0OZdM7KVQQ4Iyu8u01E@public.gmane.org>
2007-12-03 16:16 ` [patch 13/38][IPV6] ip6_fib - make the fib table per " Daniel Lezcano
` (25 subsequent siblings)
37 siblings, 1 reply; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: ip6-fib-init-net.patch --]
[-- Type: text/plain, Size: 7681 bytes --]
Move the global definition of the fib table to the network namespace
structure and make their access to the initial network namespace.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/net_namespace.h | 9 +++
net/ipv6/ip6_fib.c | 110 ++++++++++++++++++++++++++++----------------
2 files changed, 80 insertions(+), 39 deletions(-)
Index: linux-2.6-netns/include/net/net_namespace.h
===================================================================
--- linux-2.6-netns.orig/include/net/net_namespace.h
+++ linux-2.6-netns/include/net/net_namespace.h
@@ -44,6 +44,15 @@ struct net {
struct fib_rules_ops *fib4_rules_ops;
#endif /* CONFIG_IP_MULTIPLE_TABLES */
+ /* ipv6 routing table */
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ struct hlist_head *fib_table_hash;
+ struct fib6_table *fib6_main_tbl;
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+ struct fib6_table *fib6_local_tbl;
+#endif /* CONFIG_IPV6_MULTIPLE_TABLES */
+#endif /* CONFIG_IPV6 */
+
struct sock *rtnl; /* rtnetlink socket */
/* List of all packet sockets. */
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -166,14 +166,11 @@ static __inline__ void rt6_release(struc
dst_free(&rt->u.dst);
}
-static struct fib6_table *fib6_main_tbl;
-
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
#define FIB_TABLE_HASHSZ 256
#else
#define FIB_TABLE_HASHSZ 1
#endif
-static struct hlist_head *fib_table_hash;
static void fib6_link_table(struct fib6_table *tb)
{
@@ -191,13 +188,11 @@ static void fib6_link_table(struct fib6_
* No protection necessary, this is the only list mutatation
* operation, tables never disappear once they exist.
*/
- hlist_add_head_rcu(&tb->tb6_hlist, &fib_table_hash[h]);
+ hlist_add_head_rcu(&tb->tb6_hlist, &init_net.fib_table_hash[h]);
}
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
-static struct fib6_table *fib6_local_tbl;
-
static struct fib6_table *fib6_alloc_table(u32 id)
{
struct fib6_table *table;
@@ -232,6 +227,7 @@ struct fib6_table *fib6_new_table(u32 id
struct fib6_table *fib6_get_table(u32 id)
{
struct fib6_table *tb;
+ struct hlist_head *head;
struct hlist_node *node;
unsigned int h;
@@ -239,7 +235,8 @@ struct fib6_table *fib6_get_table(u32 id
id = RT6_TABLE_MAIN;
h = id & (FIB_TABLE_HASHSZ - 1);
rcu_read_lock();
- hlist_for_each_entry_rcu(tb, node, &fib_table_hash[h], tb6_hlist) {
+ head = &init_net.fib_table_hash[h];
+ hlist_for_each_entry_rcu(tb, node, head, tb6_hlist) {
if (tb->tb6_id == id) {
rcu_read_unlock();
return tb;
@@ -252,8 +249,8 @@ struct fib6_table *fib6_get_table(u32 id
static void __init fib6_tables_init(void)
{
- fib6_link_table(fib6_main_tbl);
- fib6_link_table(fib6_local_tbl);
+ fib6_link_table(init_net.fib6_main_tbl);
+ fib6_link_table(init_net.fib6_local_tbl);
}
#else
@@ -265,18 +262,18 @@ struct fib6_table *fib6_new_table(u32 id
struct fib6_table *fib6_get_table(u32 id)
{
- return fib6_main_tbl;
+ return init_net.fib6_main_tbl;
}
struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags,
pol_lookup_t lookup)
{
- return (struct dst_entry *) lookup(fib6_main_tbl, fl, flags);
+ return (struct dst_entry *) lookup(init_net.fib6_main_tbl, fl, flags);
}
static void __init fib6_tables_init(void)
{
- fib6_link_table(fib6_main_tbl);
+ fib6_link_table(init_net.fib6_main_tbl);
}
#endif
@@ -357,6 +354,7 @@ static int inet6_dump_fib(struct sk_buff
struct fib6_walker_t *w;
struct fib6_table *tb;
struct hlist_node *node;
+ struct hlist_head *head;
int res = 0;
if (net != &init_net)
@@ -390,7 +388,8 @@ static int inet6_dump_fib(struct sk_buff
for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
e = 0;
- hlist_for_each_entry(tb, node, &fib_table_hash[h], tb6_hlist) {
+ head = &init_net.fib_table_hash[h];
+ hlist_for_each_entry(tb, node, head, tb6_hlist) {
if (e < s_e)
goto next;
res = fib6_dump_table(tb, skb, cb);
@@ -1363,12 +1362,13 @@ void fib6_clean_all(int (*func)(struct r
{
struct fib6_table *table;
struct hlist_node *node;
+ struct hlist_head *head;
unsigned int h;
rcu_read_lock();
for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
- hlist_for_each_entry_rcu(table, node, &fib_table_hash[h],
- tb6_hlist) {
+ head = &init_net.fib_table_hash[h];
+ hlist_for_each_entry_rcu(table, node, head, tb6_hlist) {
write_lock_bh(&table->tb6_lock);
fib6_clean_tree(&table->tb6_root, func, prune, arg);
write_unlock_bh(&table->tb6_lock);
@@ -1467,42 +1467,74 @@ void fib6_run_gc(unsigned long dummy)
spin_unlock_bh(&fib6_gc_lock);
}
-void __init fib6_init(void)
+static int fib6_net_init(struct net *net)
{
- fib6_node_kmem = kmem_cache_create("fib6_nodes",
- sizeof(struct fib6_node),
- 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
- NULL);
+ int ret;
- fib_table_hash = kzalloc(sizeof(*fib_table_hash)*FIB_TABLE_HASHSZ, GFP_KERNEL);
- if (!fib_table_hash)
- panic("IPV6: Failed to allocate fib_table_hash.\n");
-
- fib6_main_tbl = kzalloc(sizeof(*fib6_main_tbl), GFP_KERNEL);
- if (!fib6_main_tbl)
- panic("IPV6: Failed to allocate fib6_main_tbl.\n");
-
- fib6_main_tbl->tb6_id = RT6_TABLE_MAIN;
- fib6_main_tbl->tb6_root.leaf = &ip6_null_entry;
- fib6_main_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
+ if (net != &init_net)
+ return -EPERM;
+
+ ret = -ENOMEM;
+ net->fib_table_hash = kzalloc(sizeof(*net->fib_table_hash)*FIB_TABLE_HASHSZ,
+ GFP_KERNEL);
+ if (!net->fib_table_hash)
+ goto out;
+
+ net->fib6_main_tbl = kzalloc(sizeof(*net->fib6_main_tbl), GFP_KERNEL);
+ if (!net->fib6_main_tbl)
+ goto out_fib6_main_tbl;
+
+ net->fib6_main_tbl->tb6_id = RT6_TABLE_MAIN;
+ net->fib6_main_tbl->tb6_root.leaf = &ip6_null_entry;
+ net->fib6_main_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
- fib6_local_tbl = kzalloc(sizeof(*fib6_local_tbl), GFP_KERNEL);
- if (!fib6_local_tbl)
- panic("IPV6: Failed to allocate fib6_local_tbl.\n");
-
- fib6_local_tbl->tb6_id = RT6_TABLE_LOCAL;
- fib6_local_tbl->tb6_root.leaf = &ip6_null_entry;
- fib6_local_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
+ net->fib6_local_tbl = kzalloc(sizeof(*net->fib6_local_tbl), GFP_KERNEL);
+ if (!net->fib6_local_tbl) {
+ kfree(net->fib6_main_tbl);
+ goto out_fib6_main_tbl;
+ }
+ net->fib6_local_tbl->tb6_id = RT6_TABLE_LOCAL;
+ net->fib6_local_tbl->tb6_root.leaf = &ip6_null_entry;
+ net->fib6_local_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
#endif
fib6_tables_init();
- __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib);
+out_fib6_main_tbl:
+ kfree(net->fib_table_hash);
+out:
+ return ret;
+ }
+
+static void fib6_net_exit(struct net *net)
+{
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+ kfree(net->fib6_local_tbl);
+#endif
+ kfree(net->fib6_main_tbl);
+ kfree(net->fib_table_hash);
+}
+
+static struct pernet_operations fib6_net_ops = {
+ .init = fib6_net_init,
+ .exit = fib6_net_exit,
+};
+
+void __init fib6_init(void)
+{
+ fib6_node_kmem = kmem_cache_create("fib6_nodes",
+ sizeof(struct fib6_node),
+ 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
+ NULL);
+
+ register_pernet_subsys(&fib6_net_ops);
+ __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib);
}
void fib6_gc_cleanup(void)
{
del_timer(&ip6_fib_timer);
+ unregister_pernet_subsys(&fib6_net_ops);
kmem_cache_destroy(fib6_node_kmem);
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 13/38][IPV6] ip6_fib - make the fib table per network namespace
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (11 preceding siblings ...)
2007-12-03 16:16 ` [patch 12/38][IPV6] ip6_fib - move the fib table to the network namespace Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 14/38][IPV6] ip6_fib - make fib6_clean_all per namespace Daniel Lezcano
` (24 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: ip6-fib-per-network-namespace.patch --]
[-- Type: text/plain, Size: 7481 bytes --]
The patch makes the ip6 fib being accessed relatively
to the network namespace.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/ip6_fib.h | 4 ++--
net/ipv6/fib6_rules.c | 4 ++--
net/ipv6/ip6_fib.c | 46 +++++++++++++++++++++-------------------------
net/ipv6/route.c | 12 ++++++------
4 files changed, 31 insertions(+), 35 deletions(-)
Index: linux-2.6-netns/include/net/ip6_fib.h
===================================================================
--- linux-2.6-netns.orig/include/net/ip6_fib.h
+++ linux-2.6-netns/include/net/ip6_fib.h
@@ -194,8 +194,8 @@ typedef struct rt6_info *(*pol_lookup_t)
* exported functions
*/
-extern struct fib6_table * fib6_get_table(u32 id);
-extern struct fib6_table * fib6_new_table(u32 id);
+extern struct fib6_table * fib6_get_table(struct net *net, u32 id);
+extern struct fib6_table * fib6_new_table(struct net *net, u32 id);
extern struct dst_entry * fib6_rule_lookup(struct flowi *fl, int flags,
pol_lookup_t lookup);
Index: linux-2.6-netns/net/ipv6/fib6_rules.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/fib6_rules.c
+++ linux-2.6-netns/net/ipv6/fib6_rules.c
@@ -71,7 +71,7 @@ static int fib6_rule_action(struct fib_r
goto discard_pkt;
}
- table = fib6_get_table(rule->table);
+ table = fib6_get_table(&init_net, rule->table);
if (table)
rt = lookup(table, flp, flags);
@@ -151,7 +151,7 @@ static int fib6_rule_configure(struct fi
if (rule->table == RT6_TABLE_UNSPEC)
goto errout;
- if (fib6_new_table(rule->table) == NULL) {
+ if (fib6_new_table(&init_net, rule->table) == NULL) {
err = -ENOBUFS;
goto errout;
}
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -172,7 +172,7 @@ static __inline__ void rt6_release(struc
#define FIB_TABLE_HASHSZ 1
#endif
-static void fib6_link_table(struct fib6_table *tb)
+static void fib6_link_table(struct net *net, struct fib6_table *tb)
{
unsigned int h;
@@ -188,7 +188,7 @@ static void fib6_link_table(struct fib6_
* No protection necessary, this is the only list mutatation
* operation, tables never disappear once they exist.
*/
- hlist_add_head_rcu(&tb->tb6_hlist, &init_net.fib_table_hash[h]);
+ hlist_add_head_rcu(&tb->tb6_hlist, &net->fib_table_hash[h]);
}
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
@@ -207,24 +207,24 @@ static struct fib6_table *fib6_alloc_tab
return table;
}
-struct fib6_table *fib6_new_table(u32 id)
+struct fib6_table *fib6_new_table(struct net *net, u32 id)
{
struct fib6_table *tb;
if (id == 0)
id = RT6_TABLE_MAIN;
- tb = fib6_get_table(id);
+ tb = fib6_get_table(net, id);
if (tb)
return tb;
tb = fib6_alloc_table(id);
if (tb != NULL)
- fib6_link_table(tb);
+ fib6_link_table(net, tb);
return tb;
}
-struct fib6_table *fib6_get_table(u32 id)
+struct fib6_table *fib6_get_table(struct net *net, u32 id)
{
struct fib6_table *tb;
struct hlist_head *head;
@@ -235,7 +235,7 @@ struct fib6_table *fib6_get_table(u32 id
id = RT6_TABLE_MAIN;
h = id & (FIB_TABLE_HASHSZ - 1);
rcu_read_lock();
- head = &init_net.fib_table_hash[h];
+ head = &net->fib_table_hash[h];
hlist_for_each_entry_rcu(tb, node, head, tb6_hlist) {
if (tb->tb6_id == id) {
rcu_read_unlock();
@@ -247,33 +247,33 @@ struct fib6_table *fib6_get_table(u32 id
return NULL;
}
-static void __init fib6_tables_init(void)
+static void __init fib6_tables_init(struct net *net)
{
- fib6_link_table(init_net.fib6_main_tbl);
- fib6_link_table(init_net.fib6_local_tbl);
+ fib6_link_table(net, net->fib6_main_tbl);
+ fib6_link_table(net, net->fib6_local_tbl);
}
#else
-struct fib6_table *fib6_new_table(u32 id)
+struct fib6_table *fib6_new_table(struct net *net, u32 id)
{
- return fib6_get_table(id);
+ return fib6_get_table(net, id);
}
-struct fib6_table *fib6_get_table(u32 id)
+struct fib6_table *fib6_get_table(struct net *net, u32 id)
{
- return init_net.fib6_main_tbl;
+ return net->fib6_main_tbl;
}
struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags,
pol_lookup_t lookup)
{
- return (struct dst_entry *) lookup(init_net.fib6_main_tbl, fl, flags);
+ return (struct dst_entry *) lookup(fl->fl_net->fib6_main_tbl, fl, flags);
}
-static void __init fib6_tables_init(void)
+static void __init fib6_tables_init(struct net *net)
{
- fib6_link_table(init_net.fib6_main_tbl);
+ fib6_link_table(net, net->fib6_main_tbl);
}
#endif
@@ -357,9 +357,6 @@ static int inet6_dump_fib(struct sk_buff
struct hlist_head *head;
int res = 0;
- if (net != &init_net)
- return 0;
-
s_h = cb->args[0];
s_e = cb->args[1];
@@ -388,7 +385,7 @@ static int inet6_dump_fib(struct sk_buff
for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
e = 0;
- head = &init_net.fib_table_hash[h];
+ head = &net->fib_table_hash[h];
hlist_for_each_entry(tb, node, head, tb6_hlist) {
if (e < s_e)
goto next;
@@ -1471,9 +1468,6 @@ static int fib6_net_init(struct net *net
{
int ret;
- if (net != &init_net)
- return -EPERM;
-
ret = -ENOMEM;
net->fib_table_hash = kzalloc(sizeof(*net->fib_table_hash)*FIB_TABLE_HASHSZ,
GFP_KERNEL);
@@ -1499,7 +1493,9 @@ static int fib6_net_init(struct net *net
net->fib6_local_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
#endif
- fib6_tables_init();
+ fib6_tables_init(net);
+
+ return 0;
out_fib6_main_tbl:
kfree(net->fib_table_hash);
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -1075,7 +1075,7 @@ int ip6_route_add(struct fib6_config *cf
if (cfg->fc_metric == 0)
cfg->fc_metric = IP6_RT_PRIO_USER;
- table = fib6_new_table(cfg->fc_table);
+ table = fib6_new_table(&init_net, cfg->fc_table);
if (table == NULL) {
err = -ENOBUFS;
goto out;
@@ -1283,7 +1283,7 @@ static int ip6_route_del(struct fib6_con
struct rt6_info *rt;
int err = -ESRCH;
- table = fib6_get_table(cfg->fc_table);
+ table = fib6_get_table(&init_net, cfg->fc_table);
if (table == NULL)
return err;
@@ -1598,7 +1598,7 @@ static struct rt6_info *rt6_get_route_in
struct rt6_info *rt = NULL;
struct fib6_table *table;
- table = fib6_get_table(RT6_TABLE_INFO);
+ table = fib6_get_table(&init_net, RT6_TABLE_INFO);
if (table == NULL)
return NULL;
@@ -1653,7 +1653,7 @@ struct rt6_info *rt6_get_dflt_router(str
struct rt6_info *rt;
struct fib6_table *table;
- table = fib6_get_table(RT6_TABLE_DFLT);
+ table = fib6_get_table(&init_net, RT6_TABLE_DFLT);
if (table == NULL)
return NULL;
@@ -1695,7 +1695,7 @@ void rt6_purge_dflt_routers(void)
struct fib6_table *table;
/* NOTE: Keep consistent with rt6_get_dflt_router */
- table = fib6_get_table(RT6_TABLE_DFLT);
+ table = fib6_get_table(&init_net, RT6_TABLE_DFLT);
if (table == NULL)
return;
@@ -1857,7 +1857,7 @@ struct rt6_info *addrconf_dst_alloc(stru
ipv6_addr_copy(&rt->rt6i_dst.addr, addr);
rt->rt6i_dst.plen = 128;
- rt->rt6i_table = fib6_get_table(RT6_TABLE_LOCAL);
+ rt->rt6i_table = fib6_get_table(&init_net, RT6_TABLE_LOCAL);
atomic_set(&rt->u.dst.__refcnt, 1);
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 14/38][IPV6] ip6_fib - make fib6_clean_all per namespace
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (12 preceding siblings ...)
2007-12-03 16:16 ` [patch 13/38][IPV6] ip6_fib - make the fib table per " Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 15/38][IPV6] ip6_fib - pass the network namespace parameter to timer callback Daniel Lezcano
` (23 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: ip6-fib-make-fib6_clean_all-per-namespace.patch --]
[-- Type: text/plain, Size: 3993 bytes --]
The function fib6_clean_all takes the network namespace
as parameter. This is useful for example to flush the routes
related to a specific network namespace.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/ip6_fib.h | 3 ++-
net/ipv6/ip6_fib.c | 7 ++++---
net/ipv6/route.c | 22 +++++++++++++++++-----
3 files changed, 23 insertions(+), 9 deletions(-)
Index: linux-2.6-netns/include/net/ip6_fib.h
===================================================================
--- linux-2.6-netns.orig/include/net/ip6_fib.h
+++ linux-2.6-netns/include/net/ip6_fib.h
@@ -207,7 +207,8 @@ struct fib6_node *fib6_locate(struct fi
struct in6_addr *daddr, int dst_len,
struct in6_addr *saddr, int src_len);
-extern void fib6_clean_all(int (*func)(struct rt6_info *, void *arg),
+extern void fib6_clean_all(struct net *net,
+ int (*func)(struct rt6_info *, void *arg),
int prune, void *arg);
extern int fib6_add(struct fib6_node *root,
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -1354,7 +1354,7 @@ static void fib6_clean_tree(struct fib6_
fib6_walk(&c.w);
}
-void fib6_clean_all(int (*func)(struct rt6_info *, void *arg),
+void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg),
int prune, void *arg)
{
struct fib6_table *table;
@@ -1364,7 +1364,7 @@ void fib6_clean_all(int (*func)(struct r
rcu_read_lock();
for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
- head = &init_net.fib_table_hash[h];
+ head = &net->fib_table_hash[h];
hlist_for_each_entry_rcu(table, node, head, tb6_hlist) {
write_lock_bh(&table->tb6_lock);
fib6_clean_tree(&table->tb6_root, func, prune, arg);
@@ -1453,7 +1453,8 @@ void fib6_run_gc(unsigned long dummy)
gc_args.more = 0;
ndisc_dst_gc(&gc_args.more);
- fib6_clean_all(fib6_age, 0, NULL);
+
+ fib6_clean_all(&init_net, fib6_age, 0, NULL);
if (gc_args.more)
mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval);
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -1876,7 +1876,7 @@ static int fib6_ifdown(struct rt6_info *
void rt6_ifdown(struct net_device *dev)
{
- fib6_clean_all(fib6_ifdown, 0, dev);
+ fib6_clean_all(dev->nd_net, fib6_ifdown, 0, dev);
}
struct rt6_mtu_change_arg
@@ -1932,7 +1932,7 @@ void rt6_mtu_change(struct net_device *d
.mtu = mtu,
};
- fib6_clean_all(rt6_mtu_change_route, 0, &arg);
+ fib6_clean_all(dev->nd_net, rt6_mtu_change_route, 0, &arg);
}
static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
@@ -2318,13 +2318,25 @@ static int rt6_info_route(struct rt6_inf
static int ipv6_route_show(struct seq_file *m, void *v)
{
- fib6_clean_all(rt6_info_route, 0, m);
+ struct net *net = (struct net *)m->private;
+ fib6_clean_all(net, rt6_info_route, 0, m);
return 0;
}
static int ipv6_route_open(struct inode *inode, struct file *file)
{
- return single_open(file, ipv6_route_show, NULL);
+ struct net *net = get_proc_net(inode);
+ if (!net)
+ return -ENXIO;
+ return single_open(file, ipv6_route_show, net);
+}
+
+static int ipv6_route_release(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq = file->private_data;
+ struct net *net = seq->private;
+ put_net(net);
+ return single_release(inode, file);
}
static const struct file_operations ipv6_route_proc_fops = {
@@ -2332,7 +2344,7 @@ static const struct file_operations ipv6
.open = ipv6_route_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = single_release,
+ .release = ipv6_route_release,
};
static int rt6_stats_seq_show(struct seq_file *seq, void *v)
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 15/38][IPV6] ip6_fib - pass the network namespace parameter to timer callback
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (13 preceding siblings ...)
2007-12-03 16:16 ` [patch 14/38][IPV6] ip6_fib - make fib6_clean_all per namespace Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 16/38][IPV6] ip6_fib - make ip6 fib gc timer mindless changes Daniel Lezcano
` (22 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: ip6-fib-add-net-to-gc-timer-parameter.patch --]
[-- Type: text/plain, Size: 5105 bytes --]
The fib tables are now relative to the inetwork namespace. When the
garbage collector timer expires, we must have a network namespace
parameter in order to retrieve the tables. For now this is the
init_net, but we should be able to have a timer per namespace and
use the timer callback parameter to pass the network namespace from
the expired timer.
The timer callback, fib6_run_gc, is actually used to be called
synchronously by some functions and asynchronously when the timer
expires.
When the timer expires, the delay specified for fib6_run_gc parameter
is always zero. So, I changed fib6_run_gc to not be a timer callback
but a function called by the timer callback and I added a timer callback
where its work is just to retrieve from the data arg of the timer the
network namespace and call fib6_run_gc with zero expiring time and
the network namespace parameters. That makes the code cleaner for the
fib6_run_gc callers.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/ip6_fib.h | 2 +-
net/ipv6/ip6_fib.c | 17 ++++++++++++-----
net/ipv6/ndisc.c | 5 +++--
net/ipv6/route.c | 7 +++++--
4 files changed, 21 insertions(+), 10 deletions(-)
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -93,7 +93,9 @@ static int fib6_walk_continue(struct fib
static __u32 rt_sernum;
-static DEFINE_TIMER(ip6_fib_timer, fib6_run_gc, 0, 0);
+static void fib6_gc_timer_cb(unsigned long arg);
+
+static DEFINE_TIMER(ip6_fib_timer, fib6_gc_timer_cb, 0, (unsigned long)&init_net);
static struct fib6_walker_t fib6_walker_list = {
.prev = &fib6_walker_list,
@@ -1436,11 +1438,11 @@ static int fib6_age(struct rt6_info *rt,
static DEFINE_SPINLOCK(fib6_gc_lock);
-void fib6_run_gc(unsigned long dummy)
+void fib6_run_gc(unsigned long expires, struct net *net)
{
- if (dummy != ~0UL) {
+ if (expires != ~0UL) {
spin_lock_bh(&fib6_gc_lock);
- gc_args.timeout = dummy ? (int)dummy : ip6_rt_gc_interval;
+ gc_args.timeout = expires ? (int)expires : ip6_rt_gc_interval;
} else {
local_bh_disable();
if (!spin_trylock(&fib6_gc_lock)) {
@@ -1454,7 +1456,7 @@ void fib6_run_gc(unsigned long dummy)
ndisc_dst_gc(&gc_args.more);
- fib6_clean_all(&init_net, fib6_age, 0, NULL);
+ fib6_clean_all(net, fib6_age, 0, NULL);
if (gc_args.more)
mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval);
@@ -1465,6 +1467,11 @@ void fib6_run_gc(unsigned long dummy)
spin_unlock_bh(&fib6_gc_lock);
}
+static void fib6_gc_timer_cb(unsigned long arg)
+{
+ fib6_run_gc(0, (struct net *)arg);
+}
+
static int fib6_net_init(struct net *net)
{
int ret;
Index: linux-2.6-netns/include/net/ip6_fib.h
===================================================================
--- linux-2.6-netns.orig/include/net/ip6_fib.h
+++ linux-2.6-netns/include/net/ip6_fib.h
@@ -221,7 +221,7 @@ extern int fib6_del(struct rt6_info *r
extern void inet6_rt_notify(int event, struct rt6_info *rt,
struct nl_info *info);
-extern void fib6_run_gc(unsigned long dummy);
+extern void fib6_run_gc(unsigned long expires, struct net *net);
extern void fib6_gc_cleanup(void);
Index: linux-2.6-netns/net/ipv6/ndisc.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ndisc.c
+++ linux-2.6-netns/net/ipv6/ndisc.c
@@ -1614,6 +1614,7 @@ int ndisc_rcv(struct sk_buff *skb)
static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct net_device *dev = ptr;
+ struct net *net = dev->nd_net;
if (dev->nd_net != &init_net)
return NOTIFY_DONE;
@@ -1621,11 +1622,11 @@ static int ndisc_netdev_event(struct not
switch (event) {
case NETDEV_CHANGEADDR:
neigh_changeaddr(&nd_tbl, dev);
- fib6_run_gc(~0UL);
+ fib6_run_gc(~0UL, net);
break;
case NETDEV_DOWN:
neigh_ifdown(&nd_tbl, dev);
- fib6_run_gc(~0UL);
+ fib6_run_gc(~0UL, net);
break;
default:
break;
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -1001,7 +1001,7 @@ static int ip6_dst_gc(void)
goto out;
expire++;
- fib6_run_gc(expire);
+ fib6_run_gc(expire, &init_net);
last_gc = now;
if (atomic_read(&ip6_dst_ops.entries) < ip6_dst_ops.gc_thresh)
expire = ip6_rt_gc_timeout>>1;
@@ -2381,9 +2381,12 @@ static
int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
+ unsigned long expires;
+
if (write) {
+ expires = flush_delay <= 0 ? ~0UL : (unsigned long)flush_delay;
proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
- fib6_run_gc(flush_delay <= 0 ? ~0UL : (unsigned long)flush_delay);
+ fib6_run_gc(expires, &init_net);
return 0;
} else
return -EINVAL;
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 16/38][IPV6] ip6_fib - make ip6 fib gc timer mindless changes
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (14 preceding siblings ...)
2007-12-03 16:16 ` [patch 15/38][IPV6] ip6_fib - pass the network namespace parameter to timer callback Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 17/38][IPV6] ip6_fib - dynamically allocate the ip6 fib gc timer Daniel Lezcano
` (21 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: ip6-fib-make-gc-timer-mindless-changes.patch --]
[-- Type: text/plain, Size: 2634 bytes --]
The patch prepares to dynamically allocate the ip6_fib_timer timer.
It changes all reference to the global static variable to a
globally defined pointer to the global static variable.
That makes all the code use a pointer instead of a static variable.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/ip6_fib.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -95,7 +95,8 @@ static __u32 rt_sernum;
static void fib6_gc_timer_cb(unsigned long arg);
-static DEFINE_TIMER(ip6_fib_timer, fib6_gc_timer_cb, 0, (unsigned long)&init_net);
+static DEFINE_TIMER(__ip6_fib_timer, fib6_gc_timer_cb, 0, (unsigned long)&init_net);
+static struct timer_list *ip6_fib_timer = &__ip6_fib_timer;
static struct fib6_walker_t fib6_walker_list = {
.prev = &fib6_walker_list,
@@ -666,15 +667,15 @@ static int fib6_add_rt2node(struct fib6_
static __inline__ void fib6_start_gc(struct rt6_info *rt)
{
- if (ip6_fib_timer.expires == 0 &&
+ if (ip6_fib_timer->expires == 0 &&
(rt->rt6i_flags & (RTF_EXPIRES|RTF_CACHE)))
- mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval);
+ mod_timer(ip6_fib_timer, jiffies + ip6_rt_gc_interval);
}
void fib6_force_start_gc(void)
{
- if (ip6_fib_timer.expires == 0)
- mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval);
+ if (ip6_fib_timer->expires == 0)
+ mod_timer(ip6_fib_timer, jiffies + ip6_rt_gc_interval);
}
/*
@@ -1446,7 +1447,7 @@ void fib6_run_gc(unsigned long expires,
} else {
local_bh_disable();
if (!spin_trylock(&fib6_gc_lock)) {
- mod_timer(&ip6_fib_timer, jiffies + HZ);
+ mod_timer(ip6_fib_timer, jiffies + HZ);
local_bh_enable();
return;
}
@@ -1459,10 +1460,10 @@ void fib6_run_gc(unsigned long expires,
fib6_clean_all(net, fib6_age, 0, NULL);
if (gc_args.more)
- mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval);
+ mod_timer(ip6_fib_timer, jiffies + ip6_rt_gc_interval);
else {
- del_timer(&ip6_fib_timer);
- ip6_fib_timer.expires = 0;
+ del_timer(ip6_fib_timer);
+ ip6_fib_timer->expires = 0;
}
spin_unlock_bh(&fib6_gc_lock);
}
@@ -1538,7 +1539,7 @@ void __init fib6_init(void)
void fib6_gc_cleanup(void)
{
- del_timer(&ip6_fib_timer);
+ del_timer(ip6_fib_timer);
unregister_pernet_subsys(&fib6_net_ops);
kmem_cache_destroy(fib6_node_kmem);
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 17/38][IPV6] ip6_fib - dynamically allocate the ip6 fib gc timer
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (15 preceding siblings ...)
2007-12-03 16:16 ` [patch 16/38][IPV6] ip6_fib - make ip6 fib gc timer mindless changes Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 18/38][IPV6] ip6_fib - move the ip6 fib gc timer to the network namespace Daniel Lezcano
` (20 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: ip6-fib-dynamically-allocate-gc-timer.patch --]
[-- Type: text/plain, Size: 1776 bytes --]
The ip6_fib_timer gc timer is dynamically allocated and initialized in
the ip6 fib init function. There are no more references to a
static global variable.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/ip6_fib.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -93,10 +93,7 @@ static int fib6_walk_continue(struct fib
static __u32 rt_sernum;
-static void fib6_gc_timer_cb(unsigned long arg);
-
-static DEFINE_TIMER(__ip6_fib_timer, fib6_gc_timer_cb, 0, (unsigned long)&init_net);
-static struct timer_list *ip6_fib_timer = &__ip6_fib_timer;
+static struct timer_list *ip6_fib_timer;
static struct fib6_walker_t fib6_walker_list = {
.prev = &fib6_walker_list,
@@ -1533,6 +1530,15 @@ void __init fib6_init(void)
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
NULL);
+ ip6_fib_timer = kzalloc(sizeof(*ip6_fib_timer), GFP_KERNEL);
+ if (!ip6_fib_timer)
+ panic("IPV6: failed to allocate the gc timer\n");
+
+ ip6_fib_timer->function = fib6_gc_timer_cb;
+ ip6_fib_timer->expires = 0;
+ ip6_fib_timer->data = (unsigned long)&init_net;
+ ip6_fib_timer->base = &boot_tvec_bases;
+
register_pernet_subsys(&fib6_net_ops);
__rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib);
}
@@ -1540,6 +1546,7 @@ void __init fib6_init(void)
void fib6_gc_cleanup(void)
{
del_timer(ip6_fib_timer);
+ kfree(ip6_fib_timer);
unregister_pernet_subsys(&fib6_net_ops);
kmem_cache_destroy(fib6_node_kmem);
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 18/38][IPV6] ip6_fib - move the ip6 fib gc timer to the network namespace
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (16 preceding siblings ...)
2007-12-03 16:16 ` [patch 17/38][IPV6] ip6_fib - dynamically allocate the ip6 fib gc timer Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 19/38][IPV6] ip6_fib - make the ip6 fib gc timer handle several network namespaces Daniel Lezcano
` (19 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: ip6-fib-gc-timer-init-net.patch --]
[-- Type: text/plain, Size: 3999 bytes --]
Move the timer definition inside the network namespace structure.
The gc timer is no longer referenced as a global variable but is now
relative to the init_net.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/net_namespace.h | 2 ++
net/ipv6/ip6_fib.c | 37 +++++++++++++++++++------------------
2 files changed, 21 insertions(+), 18 deletions(-)
Index: linux-2.6-netns/include/net/net_namespace.h
===================================================================
--- linux-2.6-netns.orig/include/net/net_namespace.h
+++ linux-2.6-netns/include/net/net_namespace.h
@@ -51,6 +51,8 @@ struct net {
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
struct fib6_table *fib6_local_tbl;
#endif /* CONFIG_IPV6_MULTIPLE_TABLES */
+
+ struct timer_list *ip6_fib_timer;
#endif /* CONFIG_IPV6 */
struct sock *rtnl; /* rtnetlink socket */
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -93,8 +93,6 @@ static int fib6_walk_continue(struct fib
static __u32 rt_sernum;
-static struct timer_list *ip6_fib_timer;
-
static struct fib6_walker_t fib6_walker_list = {
.prev = &fib6_walker_list,
.next = &fib6_walker_list,
@@ -664,15 +662,15 @@ static int fib6_add_rt2node(struct fib6_
static __inline__ void fib6_start_gc(struct rt6_info *rt)
{
- if (ip6_fib_timer->expires == 0 &&
+ if (init_net.ip6_fib_timer->expires == 0 &&
(rt->rt6i_flags & (RTF_EXPIRES|RTF_CACHE)))
- mod_timer(ip6_fib_timer, jiffies + ip6_rt_gc_interval);
+ mod_timer(init_net.ip6_fib_timer, jiffies + ip6_rt_gc_interval);
}
void fib6_force_start_gc(void)
{
- if (ip6_fib_timer->expires == 0)
- mod_timer(ip6_fib_timer, jiffies + ip6_rt_gc_interval);
+ if (init_net.ip6_fib_timer->expires == 0)
+ mod_timer(init_net.ip6_fib_timer, jiffies + ip6_rt_gc_interval);
}
/*
@@ -1444,7 +1442,7 @@ void fib6_run_gc(unsigned long expires,
} else {
local_bh_disable();
if (!spin_trylock(&fib6_gc_lock)) {
- mod_timer(ip6_fib_timer, jiffies + HZ);
+ mod_timer(init_net.ip6_fib_timer, jiffies + HZ);
local_bh_enable();
return;
}
@@ -1457,10 +1455,10 @@ void fib6_run_gc(unsigned long expires,
fib6_clean_all(net, fib6_age, 0, NULL);
if (gc_args.more)
- mod_timer(ip6_fib_timer, jiffies + ip6_rt_gc_interval);
+ mod_timer(init_net.ip6_fib_timer, jiffies + ip6_rt_gc_interval);
else {
- del_timer(ip6_fib_timer);
- ip6_fib_timer->expires = 0;
+ del_timer(init_net.ip6_fib_timer);
+ init_net.ip6_fib_timer->expires = 0;
}
spin_unlock_bh(&fib6_gc_lock);
}
@@ -1525,19 +1523,22 @@ static struct pernet_operations fib6_net
void __init fib6_init(void)
{
+ struct timer_list *timer;
+
fib6_node_kmem = kmem_cache_create("fib6_nodes",
sizeof(struct fib6_node),
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
NULL);
- ip6_fib_timer = kzalloc(sizeof(*ip6_fib_timer), GFP_KERNEL);
- if (!ip6_fib_timer)
+ timer = kzalloc(sizeof(*timer), GFP_KERNEL);
+ if (!timer)
panic("IPV6: failed to allocate the gc timer\n");
- ip6_fib_timer->function = fib6_gc_timer_cb;
- ip6_fib_timer->expires = 0;
- ip6_fib_timer->data = (unsigned long)&init_net;
- ip6_fib_timer->base = &boot_tvec_bases;
+ timer->function = fib6_gc_timer_cb;
+ timer->expires = 0;
+ timer->data = (unsigned long)&init_net;
+ timer->base = &boot_tvec_bases;
+ init_net.ip6_fib_timer = timer;
register_pernet_subsys(&fib6_net_ops);
__rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib);
@@ -1545,8 +1546,8 @@ void __init fib6_init(void)
void fib6_gc_cleanup(void)
{
- del_timer(ip6_fib_timer);
- kfree(ip6_fib_timer);
+ del_timer(init_net.ip6_fib_timer);
+ kfree(init_net.ip6_fib_timer);
unregister_pernet_subsys(&fib6_net_ops);
kmem_cache_destroy(fib6_node_kmem);
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 19/38][IPV6] ip6_fib - make the ip6 fib gc timer handle several network namespaces
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (17 preceding siblings ...)
2007-12-03 16:16 ` [patch 18/38][IPV6] ip6_fib - move the ip6 fib gc timer to the network namespace Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 20/38][IPV6] fib6_rules - make fib_rules per network namespace Daniel Lezcano
` (18 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: ip6-fib-gc-timer-per-namespace.patch --]
[-- Type: text/plain, Size: 2574 bytes --]
Move the timer initialization at the network namespace creation
and store the network namespace in the timer argument.
That enables multiple timers (one per network namespace) to do garbage
collecting.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/ip6_fib.c | 32 +++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -1471,12 +1471,23 @@ static void fib6_gc_timer_cb(unsigned lo
static int fib6_net_init(struct net *net)
{
int ret;
+ struct timer_list *timer;
ret = -ENOMEM;
+ timer = kzalloc(sizeof(*timer), GFP_KERNEL);
+ if (!timer)
+ goto out;
+
+ timer->function = fib6_gc_timer_cb;
+ timer->expires = 0;
+ timer->data = (unsigned long)net;
+ timer->base = &boot_tvec_bases;
+ net->ip6_fib_timer = timer;
+
net->fib_table_hash = kzalloc(sizeof(*net->fib_table_hash)*FIB_TABLE_HASHSZ,
GFP_KERNEL);
if (!net->fib_table_hash)
- goto out;
+ goto out_timer;
net->fib6_main_tbl = kzalloc(sizeof(*net->fib6_main_tbl), GFP_KERNEL);
if (!net->fib6_main_tbl)
@@ -1503,12 +1514,17 @@ static int fib6_net_init(struct net *net
out_fib6_main_tbl:
kfree(net->fib_table_hash);
+out_timer:
+ kfree(timer);
out:
return ret;
}
static void fib6_net_exit(struct net *net)
{
+ del_timer(net->ip6_fib_timer);
+ kfree(net->ip6_fib_timer);
+
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
kfree(net->fib6_local_tbl);
#endif
@@ -1523,31 +1539,17 @@ static struct pernet_operations fib6_net
void __init fib6_init(void)
{
- struct timer_list *timer;
-
fib6_node_kmem = kmem_cache_create("fib6_nodes",
sizeof(struct fib6_node),
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
NULL);
- timer = kzalloc(sizeof(*timer), GFP_KERNEL);
- if (!timer)
- panic("IPV6: failed to allocate the gc timer\n");
-
- timer->function = fib6_gc_timer_cb;
- timer->expires = 0;
- timer->data = (unsigned long)&init_net;
- timer->base = &boot_tvec_bases;
- init_net.ip6_fib_timer = timer;
-
register_pernet_subsys(&fib6_net_ops);
__rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib);
}
void fib6_gc_cleanup(void)
{
- del_timer(init_net.ip6_fib_timer);
- kfree(init_net.ip6_fib_timer);
unregister_pernet_subsys(&fib6_net_ops);
kmem_cache_destroy(fib6_node_kmem);
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 20/38][IPV6] fib6_rules - make fib_rules per network namespace
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (18 preceding siblings ...)
2007-12-03 16:16 ` [patch 19/38][IPV6] ip6_fib - make the ip6 fib gc timer handle several network namespaces Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 21/38][IPV6] rt6_stats - make mindless changes for rt6_stats Daniel Lezcano
` (17 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: fib6-rules-per-network-namespace.patch --]
[-- Type: text/plain, Size: 1444 bytes --]
This patch makes the fib6_rules per network namespace.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/fib6_rules.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
Index: linux-2.6-netns/net/ipv6/fib6_rules.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/fib6_rules.c
+++ linux-2.6-netns/net/ipv6/fib6_rules.c
@@ -53,6 +53,7 @@ static int fib6_rule_action(struct fib_r
int flags, struct fib_lookup_arg *arg)
{
struct rt6_info *rt = NULL;
+ struct net *net = flp->fl_net;
struct fib6_table *table;
pol_lookup_t lookup = arg->lookup_ptr;
@@ -71,7 +72,7 @@ static int fib6_rule_action(struct fib_r
goto discard_pkt;
}
- table = fib6_get_table(&init_net, rule->table);
+ table = fib6_get_table(net, rule->table);
if (table)
rt = lookup(table, flp, flags);
@@ -145,13 +146,14 @@ static int fib6_rule_configure(struct fi
struct nlattr **tb)
{
int err = -EINVAL;
+ struct net *net = skb->sk->sk_net;
struct fib6_rule *rule6 = (struct fib6_rule *) rule;
if (rule->action == FR_ACT_TO_TBL) {
if (rule->table == RT6_TABLE_UNSPEC)
goto errout;
- if (fib6_new_table(&init_net, rule->table) == NULL) {
+ if (fib6_new_table(net, rule->table) == NULL) {
err = -ENOBUFS;
goto errout;
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 21/38][IPV6] rt6_stats - make mindless changes for rt6_stats
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (19 preceding siblings ...)
2007-12-03 16:16 ` [patch 20/38][IPV6] fib6_rules - make fib_rules per network namespace Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 22/38][IPV6] rt6_stats - dynamically allocate the rt6_stats Daniel Lezcano
` (16 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: rt6-stats-dynamic-make-mindless-changes.patch --]
[-- Type: text/plain, Size: 3268 bytes --]
Change the global reference to the rt6_stats variable to
a pointer. These are the mindless changes to bring dynamic
allocation to the rt6_stats structure.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/ipv6.h | 2 +-
net/ipv6/ip6_fib.c | 13 +++++++------
net/ipv6/route.c | 8 ++++----
3 files changed, 12 insertions(+), 11 deletions(-)
Index: linux-2.6-netns/include/net/ipv6.h
===================================================================
--- linux-2.6-netns.orig/include/net/ipv6.h
+++ linux-2.6-netns/include/net/ipv6.h
@@ -620,7 +620,7 @@ extern void ipv6_misc_proc_exit(void);
extern int snmp6_register_dev(struct inet6_dev *idev);
extern int snmp6_unregister_dev(struct inet6_dev *idev);
-extern struct rt6_statistics rt6_stats;
+extern struct rt6_statistics *rt6_stats;
#else
static inline int snmp6_register_dev(struct inet6_dev *idev)
{
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -48,7 +48,8 @@
#define RT6_TRACE(x...) do { ; } while (0)
#endif
-struct rt6_statistics rt6_stats;
+static struct rt6_statistics __rt6_stats;
+struct rt6_statistics *rt6_stats = &__rt6_stats;
static struct kmem_cache * fib6_node_kmem __read_mostly;
@@ -650,10 +651,10 @@ static int fib6_add_rt2node(struct fib6_
rt->rt6i_node = fn;
atomic_inc(&rt->rt6i_ref);
inet6_rt_notify(RTM_NEWROUTE, rt, info);
- rt6_stats.fib_rt_entries++;
+ rt6_stats->fib_rt_entries++;
if ((fn->fn_flags & RTN_RTINFO) == 0) {
- rt6_stats.fib_route_nodes++;
+ rt6_stats->fib_route_nodes++;
fn->fn_flags |= RTN_RTINFO;
}
@@ -1088,8 +1089,8 @@ static void fib6_del_route(struct fib6_n
/* Unlink it */
*rtp = rt->u.dst.rt6_next;
rt->rt6i_node = NULL;
- rt6_stats.fib_rt_entries--;
- rt6_stats.fib_discarded_routes++;
+ rt6_stats->fib_rt_entries--;
+ rt6_stats->fib_discarded_routes++;
/* Reset round-robin state, if necessary */
if (fn->rr_ptr == rt)
@@ -1115,7 +1116,7 @@ static void fib6_del_route(struct fib6_n
/* If it was last route, expunge its radix tree node */
if (fn->leaf == NULL) {
fn->fn_flags &= ~RTN_RTINFO;
- rt6_stats.fib_route_nodes--;
+ rt6_stats->fib_route_nodes--;
fn = fib6_repair_tree(fn);
}
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -2350,11 +2350,11 @@ static const struct file_operations ipv6
static int rt6_stats_seq_show(struct seq_file *seq, void *v)
{
seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
- rt6_stats.fib_nodes, rt6_stats.fib_route_nodes,
- rt6_stats.fib_rt_alloc, rt6_stats.fib_rt_entries,
- rt6_stats.fib_rt_cache,
+ rt6_stats->fib_nodes, rt6_stats->fib_route_nodes,
+ rt6_stats->fib_rt_alloc, rt6_stats->fib_rt_entries,
+ rt6_stats->fib_rt_cache,
atomic_read(&ip6_dst_ops.entries),
- rt6_stats.fib_discarded_routes);
+ rt6_stats->fib_discarded_routes);
return 0;
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 22/38][IPV6] rt6_stats - dynamically allocate the rt6_stats
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (20 preceding siblings ...)
2007-12-03 16:16 ` [patch 21/38][IPV6] rt6_stats - make mindless changes for rt6_stats Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 23/38][IPV6] rt6_stats - make the rt6_stats relative to the namespace Daniel Lezcano
` (15 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: rt6-stats-dynamic-allocation.patch --]
[-- Type: text/plain, Size: 1469 bytes --]
This patch allocates the rt6_stats struct dynamically when
the fib6 is initialized. That provides the ability to create
several instances of this structure for the network namespaces.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/ip6_fib.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -48,8 +48,7 @@
#define RT6_TRACE(x...) do { ; } while (0)
#endif
-static struct rt6_statistics __rt6_stats;
-struct rt6_statistics *rt6_stats = &__rt6_stats;
+struct rt6_statistics *rt6_stats;
static struct kmem_cache * fib6_node_kmem __read_mostly;
@@ -1544,6 +1543,10 @@ void __init fib6_init(void)
sizeof(struct fib6_node),
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
NULL);
+
+ rt6_stats = kzalloc(sizeof(*rt6_stats), GFP_KERNEL);
+ if (!rt6_stats)
+ panic("IPV6: failed to allocate rt6_stats.\n");
register_pernet_subsys(&fib6_net_ops);
__rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib);
@@ -1552,5 +1555,6 @@ void __init fib6_init(void)
void fib6_gc_cleanup(void)
{
unregister_pernet_subsys(&fib6_net_ops);
+ kfree(rt6_stats);
kmem_cache_destroy(fib6_node_kmem);
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 23/38][IPV6] rt6_stats - make the rt6_stats relative to the namespace
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (21 preceding siblings ...)
2007-12-03 16:16 ` [patch 22/38][IPV6] rt6_stats - dynamically allocate the rt6_stats Daniel Lezcano
@ 2007-12-03 16:16 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 24/38][IPV6] rt6_stats - make rt6_stats per namespace Daniel Lezcano
` (14 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:16 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: rt6-stats-init-net.patch --]
[-- Type: text/plain, Size: 4482 bytes --]
This patch moves the rt6_stats structure inside the network
namespace structure. That allows to reference the rt6_stats
relatively from a network namespace.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/ipv6.h | 1 -
include/net/net_namespace.h | 1 +
net/ipv6/ip6_fib.c | 18 ++++++++----------
net/ipv6/route.c | 12 +++++++-----
4 files changed, 16 insertions(+), 16 deletions(-)
Index: linux-2.6-netns/include/net/ipv6.h
===================================================================
--- linux-2.6-netns.orig/include/net/ipv6.h
+++ linux-2.6-netns/include/net/ipv6.h
@@ -620,7 +620,6 @@ extern void ipv6_misc_proc_exit(void);
extern int snmp6_register_dev(struct inet6_dev *idev);
extern int snmp6_unregister_dev(struct inet6_dev *idev);
-extern struct rt6_statistics *rt6_stats;
#else
static inline int snmp6_register_dev(struct inet6_dev *idev)
{
Index: linux-2.6-netns/include/net/net_namespace.h
===================================================================
--- linux-2.6-netns.orig/include/net/net_namespace.h
+++ linux-2.6-netns/include/net/net_namespace.h
@@ -46,6 +46,7 @@ struct net {
/* ipv6 routing table */
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ struct rt6_statistics *rt6_stats;
struct hlist_head *fib_table_hash;
struct fib6_table *fib6_main_tbl;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -48,8 +48,6 @@
#define RT6_TRACE(x...) do { ; } while (0)
#endif
-struct rt6_statistics *rt6_stats;
-
static struct kmem_cache * fib6_node_kmem __read_mostly;
enum fib_walk_state_t
@@ -650,10 +648,10 @@ static int fib6_add_rt2node(struct fib6_
rt->rt6i_node = fn;
atomic_inc(&rt->rt6i_ref);
inet6_rt_notify(RTM_NEWROUTE, rt, info);
- rt6_stats->fib_rt_entries++;
+ init_net.rt6_stats->fib_rt_entries++;
if ((fn->fn_flags & RTN_RTINFO) == 0) {
- rt6_stats->fib_route_nodes++;
+ init_net.rt6_stats->fib_route_nodes++;
fn->fn_flags |= RTN_RTINFO;
}
@@ -1088,8 +1086,8 @@ static void fib6_del_route(struct fib6_n
/* Unlink it */
*rtp = rt->u.dst.rt6_next;
rt->rt6i_node = NULL;
- rt6_stats->fib_rt_entries--;
- rt6_stats->fib_discarded_routes++;
+ init_net.rt6_stats->fib_rt_entries--;
+ init_net.rt6_stats->fib_discarded_routes++;
/* Reset round-robin state, if necessary */
if (fn->rr_ptr == rt)
@@ -1115,7 +1113,7 @@ static void fib6_del_route(struct fib6_n
/* If it was last route, expunge its radix tree node */
if (fn->leaf == NULL) {
fn->fn_flags &= ~RTN_RTINFO;
- rt6_stats->fib_route_nodes--;
+ init_net.rt6_stats->fib_route_nodes--;
fn = fib6_repair_tree(fn);
}
@@ -1544,8 +1542,8 @@ void __init fib6_init(void)
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
NULL);
- rt6_stats = kzalloc(sizeof(*rt6_stats), GFP_KERNEL);
- if (!rt6_stats)
+ init_net.rt6_stats = kzalloc(sizeof(*init_net.rt6_stats), GFP_KERNEL);
+ if (!init_net.rt6_stats)
panic("IPV6: failed to allocate rt6_stats.\n");
register_pernet_subsys(&fib6_net_ops);
@@ -1555,6 +1553,6 @@ void __init fib6_init(void)
void fib6_gc_cleanup(void)
{
unregister_pernet_subsys(&fib6_net_ops);
- kfree(rt6_stats);
+ kfree(init_net.rt6_stats);
kmem_cache_destroy(fib6_node_kmem);
}
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -2350,11 +2350,13 @@ static const struct file_operations ipv6
static int rt6_stats_seq_show(struct seq_file *seq, void *v)
{
seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
- rt6_stats->fib_nodes, rt6_stats->fib_route_nodes,
- rt6_stats->fib_rt_alloc, rt6_stats->fib_rt_entries,
- rt6_stats->fib_rt_cache,
- atomic_read(&ip6_dst_ops.entries),
- rt6_stats->fib_discarded_routes);
+ init_net.rt6_stats->fib_nodes,
+ init_net.rt6_stats->fib_route_nodes,
+ init_net.rt6_stats->fib_rt_alloc,
+ init_net.rt6_stats->fib_rt_entries,
+ init_net.rt6_stats->fib_rt_cache,
+ atomic_read(&ip6_dst_ops.entries),
+ init_net.rt6_stats->fib_discarded_routes);
return 0;
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 24/38][IPV6] rt6_stats - make rt6_stats per namespace
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (22 preceding siblings ...)
2007-12-03 16:16 ` [patch 23/38][IPV6] rt6_stats - make the rt6_stats relative to the namespace Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 25/38][IPV6] route6 - create route6 proc files for the namespace Daniel Lezcano
` (13 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: rt6-stats-per-namespace.patch --]
[-- Type: text/plain, Size: 3531 bytes --]
The rt6_stats is now per namespace with this patch. It is
allocated when a network namespace is created and freed
when the network namespace exits and references are relative
to the network namespace.
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
---
net/ipv6/ip6_fib.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -601,6 +601,7 @@ static int fib6_add_rt2node(struct fib6_
{
struct rt6_info *iter = NULL;
struct rt6_info **ins;
+ struct net *net = &init_net;
ins = &fn->leaf;
@@ -648,10 +649,10 @@ static int fib6_add_rt2node(struct fib6_
rt->rt6i_node = fn;
atomic_inc(&rt->rt6i_ref);
inet6_rt_notify(RTM_NEWROUTE, rt, info);
- init_net.rt6_stats->fib_rt_entries++;
+ net->rt6_stats->fib_rt_entries++;
if ((fn->fn_flags & RTN_RTINFO) == 0) {
- init_net.rt6_stats->fib_route_nodes++;
+ net->rt6_stats->fib_route_nodes++;
fn->fn_flags |= RTN_RTINFO;
}
@@ -1080,14 +1081,15 @@ static void fib6_del_route(struct fib6_n
{
struct fib6_walker_t *w;
struct rt6_info *rt = *rtp;
+ struct net *net = &init_net;
RT6_TRACE("fib6_del_route\n");
/* Unlink it */
*rtp = rt->u.dst.rt6_next;
rt->rt6i_node = NULL;
- init_net.rt6_stats->fib_rt_entries--;
- init_net.rt6_stats->fib_discarded_routes++;
+ net->rt6_stats->fib_rt_entries--;
+ net->rt6_stats->fib_discarded_routes++;
/* Reset round-robin state, if necessary */
if (fn->rr_ptr == rt)
@@ -1113,7 +1115,7 @@ static void fib6_del_route(struct fib6_n
/* If it was last route, expunge its radix tree node */
if (fn->leaf == NULL) {
fn->fn_flags &= ~RTN_RTINFO;
- init_net.rt6_stats->fib_route_nodes--;
+ net->rt6_stats->fib_route_nodes--;
fn = fib6_repair_tree(fn);
}
@@ -1482,10 +1484,14 @@ static int fib6_net_init(struct net *net
timer->base = &boot_tvec_bases;
net->ip6_fib_timer = timer;
+ net->rt6_stats = kzalloc(sizeof(*net->rt6_stats), GFP_KERNEL);
+ if (!net->rt6_stats)
+ goto out_timer;
+
net->fib_table_hash = kzalloc(sizeof(*net->fib_table_hash)*FIB_TABLE_HASHSZ,
GFP_KERNEL);
if (!net->fib_table_hash)
- goto out_timer;
+ goto out_rt6_stats;
net->fib6_main_tbl = kzalloc(sizeof(*net->fib6_main_tbl), GFP_KERNEL);
if (!net->fib6_main_tbl)
@@ -1512,6 +1518,8 @@ static int fib6_net_init(struct net *net
out_fib6_main_tbl:
kfree(net->fib_table_hash);
+out_rt6_stats:
+ kfree(net->rt6_stats);
out_timer:
kfree(timer);
out:
@@ -1528,6 +1536,7 @@ static void fib6_net_exit(struct net *ne
#endif
kfree(net->fib6_main_tbl);
kfree(net->fib_table_hash);
+ kfree(net->rt6_stats);
}
static struct pernet_operations fib6_net_ops = {
@@ -1542,10 +1551,6 @@ void __init fib6_init(void)
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
NULL);
- init_net.rt6_stats = kzalloc(sizeof(*init_net.rt6_stats), GFP_KERNEL);
- if (!init_net.rt6_stats)
- panic("IPV6: failed to allocate rt6_stats.\n");
-
register_pernet_subsys(&fib6_net_ops);
__rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib);
}
@@ -1553,6 +1558,5 @@ void __init fib6_init(void)
void fib6_gc_cleanup(void)
{
unregister_pernet_subsys(&fib6_net_ops);
- kfree(init_net.rt6_stats);
kmem_cache_destroy(fib6_node_kmem);
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 25/38][IPV6] route6 - create route6 proc files for the namespace
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (23 preceding siblings ...)
2007-12-03 16:17 ` [patch 24/38][IPV6] rt6_stats - make rt6_stats per namespace Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 26/38][IPV6] route6 - Pass the network namespace parameter to rt6_lookup Daniel Lezcano
` (12 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: route6-procfs.patch --]
[-- Type: text/plain, Size: 1995 bytes --]
Make /proc/net/ipv6_route and /proc/net/rt6_stats to be per namespace.
These proc files are now created when the network namespace is initialized.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/route.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -2486,6 +2486,24 @@ ctl_table ipv6_route_table[] = {
#endif
+static int ip6_route_net_init(struct net *net)
+{
+ proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops);
+ proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
+ return 0;
+}
+
+static void ip6_route_net_exit(struct net *net)
+{
+ proc_net_remove(net, "ipv6_route");
+ proc_net_remove(net, "rt6_stats");
+}
+
+static struct pernet_operations ip6_route_net_ops = {
+ .init = ip6_route_net_init,
+ .exit = ip6_route_net_exit,
+};
+
void __init ip6_route_init(void)
{
ip6_dst_ops.kmem_cachep =
@@ -2493,9 +2511,8 @@ void __init ip6_route_init(void)
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep;
+ register_pernet_subsys(&ip6_route_net_ops);
fib6_init();
- proc_net_fops_create(&init_net, "ipv6_route", 0, &ipv6_route_proc_fops);
- proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
#ifdef CONFIG_XFRM
xfrm6_init();
#endif
@@ -2510,13 +2527,11 @@ void __init ip6_route_init(void)
void ip6_route_cleanup(void)
{
+ unregister_pernet_subsys(&ip6_route_net_ops);
+
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
fib6_rules_cleanup();
#endif
-#ifdef CONFIG_PROC_FS
- proc_net_remove(&init_net, "ipv6_route");
- proc_net_remove(&init_net, "rt6_stats");
-#endif
#ifdef CONFIG_XFRM
xfrm6_fini();
#endif
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 26/38][IPV6] route6 - Pass the network namespace parameter to rt6_lookup
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (24 preceding siblings ...)
2007-12-03 16:17 ` [patch 25/38][IPV6] route6 - create route6 proc files for the namespace Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 27/38][IPV6] route6 - Make proc entry /proc/net/rt6_stats per namespace Daniel Lezcano
` (11 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: route6-pass-network-namespace-to-rt6_lookup.patch --]
[-- Type: text/plain, Size: 5814 bytes --]
Add a network namespace parameter to rt6_lookup().
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/ip6_route.h | 3 ++-
net/ipv6/addrconf.c | 4 ++--
net/ipv6/anycast.c | 2 +-
net/ipv6/ip6_tunnel.c | 4 ++--
net/ipv6/mcast.c | 4 ++--
net/ipv6/route.c | 9 +++++----
net/ipv6/sit.c | 4 ++--
7 files changed, 16 insertions(+), 14 deletions(-)
Index: linux-2.6-netns/include/net/ip6_route.h
===================================================================
--- linux-2.6-netns.orig/include/net/ip6_route.h
+++ linux-2.6-netns/include/net/ip6_route.h
@@ -73,7 +73,8 @@ extern void rt6_sndmsg(int type, struc
int dstlen, int srclen,
int metric, __u32 flags);
-extern struct rt6_info *rt6_lookup(struct in6_addr *daddr,
+extern struct rt6_info *rt6_lookup(struct net *net,
+ struct in6_addr *daddr,
struct in6_addr *saddr,
int oif, int flags);
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -728,7 +728,7 @@ static void ipv6_del_addr(struct inet6_i
struct rt6_info *rt;
ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len);
- rt = rt6_lookup(&prefix, NULL, ifp->idev->dev->ifindex, 1);
+ rt = rt6_lookup(&init_net, &prefix, NULL, ifp->idev->dev->ifindex, 1);
if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
if (onlink == 0) {
@@ -1672,7 +1672,7 @@ void addrconf_prefix_rcv(struct net_devi
if (pinfo->onlink) {
struct rt6_info *rt;
- rt = rt6_lookup(&pinfo->prefix, NULL, dev->ifindex, 1);
+ rt = rt6_lookup(&init_net, &pinfo->prefix, NULL, dev->ifindex, 1);
if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
if (rt->rt6i_flags&RTF_EXPIRES) {
Index: linux-2.6-netns/net/ipv6/anycast.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/anycast.c
+++ linux-2.6-netns/net/ipv6/anycast.c
@@ -101,7 +101,7 @@ int ipv6_sock_ac_join(struct sock *sk, i
if (ifindex == 0) {
struct rt6_info *rt;
- rt = rt6_lookup(addr, NULL, 0, 0);
+ rt = rt6_lookup(&init_net, addr, NULL, 0, 0);
if (rt) {
dev = rt->rt6i_dev;
dev_hold(dev);
Index: linux-2.6-netns/net/ipv6/ip6_tunnel.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_tunnel.c
+++ linux-2.6-netns/net/ipv6/ip6_tunnel.c
@@ -602,7 +602,7 @@ ip6ip6_err(struct sk_buff *skb, struct i
skb_reset_network_header(skb2);
/* Try to guess incoming interface */
- rt = rt6_lookup(&ipv6_hdr(skb2)->saddr, NULL, 0, 0);
+ rt = rt6_lookup(&init_net, &ipv6_hdr(skb2)->saddr, NULL, 0, 0);
if (rt && rt->rt6i_dev)
skb2->dev = rt->rt6i_dev;
@@ -1112,7 +1112,7 @@ static void ip6_tnl_link_config(struct i
int strict = (ipv6_addr_type(&p->raddr) &
(IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL));
- struct rt6_info *rt = rt6_lookup(&p->raddr, &p->laddr,
+ struct rt6_info *rt = rt6_lookup(&init_net, &p->raddr, &p->laddr,
p->link, strict);
if (rt == NULL)
Index: linux-2.6-netns/net/ipv6/mcast.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/mcast.c
+++ linux-2.6-netns/net/ipv6/mcast.c
@@ -208,7 +208,7 @@ int ipv6_sock_mc_join(struct sock *sk, i
if (ifindex == 0) {
struct rt6_info *rt;
- rt = rt6_lookup(addr, NULL, 0, 0);
+ rt = rt6_lookup(&init_net, addr, NULL, 0, 0);
if (rt) {
dev = rt->rt6i_dev;
dev_hold(dev);
@@ -294,7 +294,7 @@ static struct inet6_dev *ip6_mc_find_dev
if (ifindex == 0) {
struct rt6_info *rt;
- rt = rt6_lookup(group, NULL, 0, 0);
+ rt = rt6_lookup(&init_net, group, NULL, 0, 0);
if (rt) {
dev = rt->rt6i_dev;
dev_hold(dev);
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -553,11 +553,12 @@ out:
}
-struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr,
+struct rt6_info *rt6_lookup(struct net *net,
+ struct in6_addr *daddr, struct in6_addr *saddr,
int oif, int strict)
{
struct flowi fl = {
- .fl_net = &init_net,
+ .fl_net = net,
.oif = oif,
.nl_u = {
.ip6_u = {
@@ -1164,7 +1165,7 @@ int ip6_route_add(struct fib6_config *cf
if (!(gwa_type&IPV6_ADDR_UNICAST))
goto out;
- grt = rt6_lookup(gw_addr, NULL, cfg->fc_ifindex, 1);
+ grt = rt6_lookup(&init_net, gw_addr, NULL, cfg->fc_ifindex, 1);
err = -EHOSTUNREACH;
if (grt == NULL)
@@ -1486,7 +1487,7 @@ void rt6_pmtu_discovery(struct in6_addr
struct rt6_info *rt, *nrt;
int allfrag = 0;
- rt = rt6_lookup(daddr, saddr, dev->ifindex, 0);
+ rt = rt6_lookup(dev->nd_net, daddr, saddr, dev->ifindex, 0);
if (rt == NULL)
return;
Index: linux-2.6-netns/net/ipv6/sit.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/sit.c
+++ linux-2.6-netns/net/ipv6/sit.c
@@ -341,11 +341,11 @@ out:
skb_reset_network_header(skb2);
/* Try to guess incoming interface */
- rt6i = rt6_lookup(&iph6->saddr, NULL, NULL, 0);
+ rt6i = rt6_lookup(&init_net, &iph6->saddr, NULL, NULL, 0);
if (rt6i && rt6i->rt6i_dev) {
skb2->dev = rt6i->rt6i_dev;
- rt6i = rt6_lookup(&iph6->daddr, &iph6->saddr, NULL, 0);
+ rt6i = rt6_lookup(&init_net, &iph6->daddr, &iph6->saddr, NULL, 0);
if (rt6i && rt6i->rt6i_dev && rt6i->rt6i_dev->type == ARPHRD_SIT) {
struct ip_tunnel *t = netdev_priv(rt6i->rt6i_dev);
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 27/38][IPV6] route6 - Make proc entry /proc/net/rt6_stats per namespace
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (25 preceding siblings ...)
2007-12-03 16:17 ` [patch 26/38][IPV6] route6 - Pass the network namespace parameter to rt6_lookup Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 28/38][IPV6] route6 - Pass network namespace to rt6_add_route_info and rt6_get_route_info Daniel Lezcano
` (10 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: route6-make-proc-entry-rt6_stats-per-namespace.patch --]
[-- Type: text/plain, Size: 2058 bytes --]
Make the proc entry /proc/net/rt6_stats work in all network namespace.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/route.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -2350,21 +2350,31 @@ static const struct file_operations ipv6
static int rt6_stats_seq_show(struct seq_file *seq, void *v)
{
+ struct net *net = (struct net*)seq->private;
seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
- init_net.rt6_stats->fib_nodes,
- init_net.rt6_stats->fib_route_nodes,
- init_net.rt6_stats->fib_rt_alloc,
- init_net.rt6_stats->fib_rt_entries,
- init_net.rt6_stats->fib_rt_cache,
+ net->rt6_stats->fib_nodes,
+ net->rt6_stats->fib_route_nodes,
+ net->rt6_stats->fib_rt_alloc,
+ net->rt6_stats->fib_rt_entries,
+ net->rt6_stats->fib_rt_cache,
atomic_read(&ip6_dst_ops.entries),
- init_net.rt6_stats->fib_discarded_routes);
+ net->rt6_stats->fib_discarded_routes);
return 0;
}
static int rt6_stats_seq_open(struct inode *inode, struct file *file)
{
- return single_open(file, rt6_stats_seq_show, NULL);
+ struct net *net = get_proc_net(inode);
+ return single_open(file, rt6_stats_seq_show, net);
+}
+
+static int rt6_stats_seq_release(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq = file->private_data;
+ struct net *net = (struct net *)seq->private;
+ put_net(net);
+ return single_release(inode, file);
}
static const struct file_operations rt6_stats_seq_fops = {
@@ -2372,7 +2382,7 @@ static const struct file_operations rt6_
.open = rt6_stats_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = single_release,
+ .release = rt6_stats_seq_release,
};
#endif /* CONFIG_PROC_FS */
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 28/38][IPV6] route6 - Pass network namespace to rt6_add_route_info and rt6_get_route_info
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (26 preceding siblings ...)
2007-12-03 16:17 ` [patch 27/38][IPV6] route6 - Make proc entry /proc/net/rt6_stats per namespace Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 29/38][IPV6] route6 - Pass the network namespace parameter to rt6_purge_dflt_routers Daniel Lezcano
` (9 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: route6-pass-network-namespace-to-rt6_x_route_info.patch --]
[-- Type: text/plain, Size: 3607 bytes --]
Add a network namespace parameter to rt6_add_route_info() and
rt6_get_route_info to enable them to handle multiple network namespaces.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/route.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -95,10 +95,12 @@ static void ip6_link_failure(struct sk_
static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
#ifdef CONFIG_IPV6_ROUTE_INFO
-static struct rt6_info *rt6_add_route_info(struct in6_addr *prefix, int prefixlen,
+static struct rt6_info *rt6_add_route_info(struct net *net,
+ struct in6_addr *prefix, int prefixlen,
struct in6_addr *gwaddr, int ifindex,
unsigned pref);
-static struct rt6_info *rt6_get_route_info(struct in6_addr *prefix, int prefixlen,
+static struct rt6_info *rt6_get_route_info(struct net *net,
+ struct in6_addr *prefix, int prefixlen,
struct in6_addr *gwaddr, int ifindex);
#endif
@@ -442,6 +444,7 @@ static struct rt6_info *rt6_select(struc
int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
struct in6_addr *gwaddr)
{
+ struct net *net = dev->nd_net;
struct route_info *rinfo = (struct route_info *) opt;
struct in6_addr prefix_buf, *prefix;
unsigned int pref;
@@ -489,7 +492,8 @@ int rt6_route_rcv(struct net_device *dev
prefix = &prefix_buf;
}
- rt = rt6_get_route_info(prefix, rinfo->prefix_len, gwaddr, dev->ifindex);
+ rt = rt6_get_route_info(net, prefix, rinfo->prefix_len, gwaddr,
+ dev->ifindex);
if (rt && !lifetime) {
ip6_del_rt(rt);
@@ -497,7 +501,7 @@ int rt6_route_rcv(struct net_device *dev
}
if (!rt && lifetime)
- rt = rt6_add_route_info(prefix, rinfo->prefix_len, gwaddr, dev->ifindex,
+ rt = rt6_add_route_info(net, prefix, rinfo->prefix_len, gwaddr, dev->ifindex,
pref);
else if (rt)
rt->rt6i_flags = RTF_ROUTEINFO |
@@ -1592,14 +1596,15 @@ static struct rt6_info * ip6_rt_copy(str
}
#ifdef CONFIG_IPV6_ROUTE_INFO
-static struct rt6_info *rt6_get_route_info(struct in6_addr *prefix, int prefixlen,
+static struct rt6_info *rt6_get_route_info(struct net *net,
+ struct in6_addr *prefix, int prefixlen,
struct in6_addr *gwaddr, int ifindex)
{
struct fib6_node *fn;
struct rt6_info *rt = NULL;
struct fib6_table *table;
- table = fib6_get_table(&init_net, RT6_TABLE_INFO);
+ table = fib6_get_table(net, RT6_TABLE_INFO);
if (table == NULL)
return NULL;
@@ -1623,7 +1628,8 @@ out:
return rt;
}
-static struct rt6_info *rt6_add_route_info(struct in6_addr *prefix, int prefixlen,
+static struct rt6_info *rt6_add_route_info(struct net *net,
+ struct in6_addr *prefix, int prefixlen,
struct in6_addr *gwaddr, int ifindex,
unsigned pref)
{
@@ -1634,6 +1640,9 @@ static struct rt6_info *rt6_add_route_in
.fc_dst_len = prefixlen,
.fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
RTF_UP | RTF_PREF(pref),
+ .fc_nlinfo.pid = 0,
+ .fc_nlinfo.nlh = NULL,
+ .fc_nlinfo.net = net,
};
ipv6_addr_copy(&cfg.fc_dst, prefix);
@@ -1645,7 +1654,7 @@ static struct rt6_info *rt6_add_route_in
ip6_route_add(&cfg);
- return rt6_get_route_info(prefix, prefixlen, gwaddr, ifindex);
+ return rt6_get_route_info(net, prefix, prefixlen, gwaddr, ifindex);
}
#endif
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 29/38][IPV6] route6 - Pass the network namespace parameter to rt6_purge_dflt_routers
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (27 preceding siblings ...)
2007-12-03 16:17 ` [patch 28/38][IPV6] route6 - Pass network namespace to rt6_add_route_info and rt6_get_route_info Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 30/38][IPV6] route6 - make route6 per namespace Daniel Lezcano
` (8 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: route6-pass-network-namespace-to-rt6_purge_dflt_routers.patch --]
[-- Type: text/plain, Size: 2191 bytes --]
Add a network namespace parameter to rt6_purge_dflt_routers.
This is needed to call fib6_get_table with the appropriate
network namespace.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/ip6_route.h | 2 +-
net/ipv6/addrconf.c | 4 ++--
net/ipv6/route.c | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
Index: linux-2.6-netns/include/net/ip6_route.h
===================================================================
--- linux-2.6-netns.orig/include/net/ip6_route.h
+++ linux-2.6-netns/include/net/ip6_route.h
@@ -99,7 +99,7 @@ extern struct rt6_info * rt6_add_dflt_ro
struct net_device *dev,
unsigned int pref);
-extern void rt6_purge_dflt_routers(void);
+extern void rt6_purge_dflt_routers(struct net *net);
extern int rt6_route_rcv(struct net_device *dev,
u8 *opt, int len,
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -3797,7 +3797,7 @@ int addrconf_sysctl_forward(ctl_table *c
addrconf_forward_change();
}
if (*valp)
- rt6_purge_dflt_routers();
+ rt6_purge_dflt_routers(&init_net);
}
return ret;
@@ -3850,7 +3850,7 @@ static int addrconf_sysctl_forward_strat
}
if (*valp)
- rt6_purge_dflt_routers();
+ rt6_purge_dflt_routers(&init_net);
} else
*valp = new;
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -1699,13 +1699,13 @@ struct rt6_info *rt6_add_dflt_router(str
return rt6_get_dflt_router(gwaddr, dev);
}
-void rt6_purge_dflt_routers(void)
+void rt6_purge_dflt_routers(struct net *net)
{
struct rt6_info *rt;
struct fib6_table *table;
/* NOTE: Keep consistent with rt6_get_dflt_router */
- table = fib6_get_table(&init_net, RT6_TABLE_DFLT);
+ table = fib6_get_table(net, RT6_TABLE_DFLT);
if (table == NULL)
return;
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 30/38][IPV6] route6 - make route6 per namespace
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (28 preceding siblings ...)
2007-12-03 16:17 ` [patch 29/38][IPV6] route6 - Pass the network namespace parameter to rt6_purge_dflt_routers Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 31/38][IPV6] rt6_info - make rt6_info accessed as a pointer Daniel Lezcano
` (7 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: route6-per-namespace.patch --]
[-- Type: text/plain, Size: 11023 bytes --]
This patch makes the routing engine use the network namespaces
to access routing informations:
Add a network namespace parameter to ipv6_route_ioctl and
propagate the network namespace value to all the routing code
that have not yet been changed.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/ip6_route.h | 4 ++
net/ipv6/addrconf.c | 9 ++++++
net/ipv6/af_inet6.c | 3 +-
net/ipv6/route.c | 68 ++++++++++++++++++++++++------------------------
4 files changed, 49 insertions(+), 35 deletions(-)
Index: linux-2.6-netns/include/net/ip6_route.h
===================================================================
--- linux-2.6-netns.orig/include/net/ip6_route.h
+++ linux-2.6-netns/include/net/ip6_route.h
@@ -53,7 +53,9 @@ extern struct dst_entry * ip6_route_outp
extern void ip6_route_init(void);
extern void ip6_route_cleanup(void);
-extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg);
+extern int ipv6_route_ioctl(struct net *net,
+ unsigned int cmd,
+ void __user *arg);
extern int ip6_route_add(struct fib6_config *cfg);
extern int ip6_ins_rt(struct rt6_info *);
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -1530,6 +1530,9 @@ addrconf_prefix_route(struct in6_addr *p
.fc_expires = expires,
.fc_dst_len = plen,
.fc_flags = RTF_UP | flags,
+ .fc_nlinfo.pid = 0,
+ .fc_nlinfo.nlh = NULL,
+ .fc_nlinfo.net = &init_net,
};
ipv6_addr_copy(&cfg.fc_dst, pfx);
@@ -1556,6 +1559,9 @@ static void addrconf_add_mroute(struct n
.fc_ifindex = dev->ifindex,
.fc_dst_len = 8,
.fc_flags = RTF_UP,
+ .fc_nlinfo.pid = 0,
+ .fc_nlinfo.nlh = NULL,
+ .fc_nlinfo.net = &init_net,
};
ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0);
@@ -1572,6 +1578,9 @@ static void sit_route_add(struct net_dev
.fc_ifindex = dev->ifindex,
.fc_dst_len = 96,
.fc_flags = RTF_UP | RTF_NONEXTHOP,
+ .fc_nlinfo.pid = 0,
+ .fc_nlinfo.nlh = NULL,
+ .fc_nlinfo.net = &init_net,
};
/* prefix length - 96 bits "::d.d.d.d" */
Index: linux-2.6-netns/net/ipv6/af_inet6.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/af_inet6.c
+++ linux-2.6-netns/net/ipv6/af_inet6.c
@@ -441,6 +441,7 @@ EXPORT_SYMBOL(inet6_getname);
int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
+ struct net *net = sk->sk_net;
switch(cmd)
{
@@ -453,7 +454,7 @@ int inet6_ioctl(struct socket *sock, uns
case SIOCADDRT:
case SIOCDELRT:
- return(ipv6_route_ioctl(cmd,(void __user *)arg));
+ return(ipv6_route_ioctl(net, cmd,(void __user *)arg));
case SIOCSIFADDR:
return addrconf_add_ifaddr((void __user *) arg);
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -610,10 +610,11 @@ static int __ip6_ins_rt(struct rt6_info
int ip6_ins_rt(struct rt6_info *rt)
{
+ struct net *net = rt->rt6i_dev->nd_net;
struct nl_info info = {
.nlh = NULL,
.pid = 0,
- .net = &init_net,
+ .net = net,
};
return __ip6_ins_rt(rt, &info);
}
@@ -752,7 +753,7 @@ void ip6_route_input(struct sk_buff *skb
struct ipv6hdr *iph = ipv6_hdr(skb);
int flags = RT6_LOOKUP_F_HAS_SADDR;
struct flowi fl = {
- .fl_net = &init_net,
+ .fl_net = skb->dev->nd_net,
.iif = skb->dev->ifindex,
.nl_u = {
.ip6_u = {
@@ -1055,6 +1056,7 @@ int ipv6_get_hoplimit(struct net_device
int ip6_route_add(struct fib6_config *cfg)
{
int err;
+ struct net *net = cfg->fc_nlinfo.net;
struct rt6_info *rt = NULL;
struct net_device *dev = NULL;
struct inet6_dev *idev = NULL;
@@ -1069,7 +1071,7 @@ int ip6_route_add(struct fib6_config *cf
#endif
if (cfg->fc_ifindex) {
err = -ENODEV;
- dev = dev_get_by_index(&init_net, cfg->fc_ifindex);
+ dev = dev_get_by_index(net, cfg->fc_ifindex);
if (!dev)
goto out;
idev = in6_dev_get(dev);
@@ -1080,7 +1082,7 @@ int ip6_route_add(struct fib6_config *cf
if (cfg->fc_metric == 0)
cfg->fc_metric = IP6_RT_PRIO_USER;
- table = fib6_new_table(&init_net, cfg->fc_table);
+ table = fib6_new_table(net, cfg->fc_table);
if (table == NULL) {
err = -ENOBUFS;
goto out;
@@ -1127,12 +1129,12 @@ int ip6_route_add(struct fib6_config *cf
if ((cfg->fc_flags & RTF_REJECT) ||
(dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) {
/* hold loopback dev/idev if we haven't done so. */
- if (dev != init_net.loopback_dev) {
+ if (dev != net->loopback_dev) {
if (dev) {
dev_put(dev);
in6_dev_put(idev);
}
- dev = init_net.loopback_dev;
+ dev = net->loopback_dev;
dev_hold(dev);
idev = in6_dev_get(dev);
if (!idev) {
@@ -1169,7 +1171,7 @@ int ip6_route_add(struct fib6_config *cf
if (!(gwa_type&IPV6_ADDR_UNICAST))
goto out;
- grt = rt6_lookup(&init_net, gw_addr, NULL, cfg->fc_ifindex, 1);
+ grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1);
err = -EHOSTUNREACH;
if (grt == NULL)
@@ -1273,10 +1275,11 @@ static int __ip6_del_rt(struct rt6_info
int ip6_del_rt(struct rt6_info *rt)
{
+ struct net *net = rt->rt6i_dev->nd_net;
struct nl_info info = {
.nlh = NULL,
.pid = 0,
- .net = &init_net,
+ .net = net,
};
return __ip6_del_rt(rt, &info);
}
@@ -1288,7 +1291,7 @@ static int ip6_route_del(struct fib6_con
struct rt6_info *rt;
int err = -ESRCH;
- table = fib6_get_table(&init_net, cfg->fc_table);
+ table = fib6_get_table(cfg->fc_nlinfo.net, cfg->fc_table);
if (table == NULL)
return err;
@@ -1389,7 +1392,7 @@ static struct rt6_info *ip6_route_redire
int flags = RT6_LOOKUP_F_HAS_SADDR;
struct ip6rd_flowi rdfl = {
.fl = {
- .fl_net = &init_net,
+ .fl_net = dev->nd_net,
.oif = dev->ifindex,
.nl_u = {
.ip6_u = {
@@ -1663,7 +1666,7 @@ struct rt6_info *rt6_get_dflt_router(str
struct rt6_info *rt;
struct fib6_table *table;
- table = fib6_get_table(&init_net, RT6_TABLE_DFLT);
+ table = fib6_get_table(dev->nd_net, RT6_TABLE_DFLT);
if (table == NULL)
return NULL;
@@ -1690,6 +1693,9 @@ struct rt6_info *rt6_add_dflt_router(str
.fc_ifindex = dev->ifindex,
.fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
+ .fc_nlinfo.pid = 0,
+ .fc_nlinfo.nlh = NULL,
+ .fc_nlinfo.net = dev->nd_net,
};
ipv6_addr_copy(&cfg.fc_gateway, gwaddr);
@@ -1722,7 +1728,8 @@ restart:
read_unlock_bh(&table->tb6_lock);
}
-static void rtmsg_to_fib6_config(struct in6_rtmsg *rtmsg,
+static void rtmsg_to_fib6_config(struct net *net,
+ struct in6_rtmsg *rtmsg,
struct fib6_config *cfg)
{
memset(cfg, 0, sizeof(*cfg));
@@ -1735,12 +1742,16 @@ static void rtmsg_to_fib6_config(struct
cfg->fc_src_len = rtmsg->rtmsg_src_len;
cfg->fc_flags = rtmsg->rtmsg_flags;
+ cfg->fc_nlinfo.pid = 0;
+ cfg->fc_nlinfo.nlh = NULL;
+ cfg->fc_nlinfo.net = net;
+
ipv6_addr_copy(&cfg->fc_dst, &rtmsg->rtmsg_dst);
ipv6_addr_copy(&cfg->fc_src, &rtmsg->rtmsg_src);
ipv6_addr_copy(&cfg->fc_gateway, &rtmsg->rtmsg_gateway);
}
-int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
+int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg)
{
struct fib6_config cfg;
struct in6_rtmsg rtmsg;
@@ -1756,7 +1767,7 @@ int ipv6_route_ioctl(unsigned int cmd, v
if (err)
return -EFAULT;
- rtmsg_to_fib6_config(&rtmsg, &cfg);
+ rtmsg_to_fib6_config(net, &rtmsg, &cfg);
rtnl_lock();
switch (cmd) {
@@ -1836,18 +1847,19 @@ struct rt6_info *addrconf_dst_alloc(stru
const struct in6_addr *addr,
int anycast)
{
+ struct net *net = idev->dev->nd_net;
struct rt6_info *rt = ip6_dst_alloc();
if (rt == NULL)
return ERR_PTR(-ENOMEM);
- dev_hold(init_net.loopback_dev);
+ dev_hold(net->loopback_dev);
in6_dev_hold(idev);
rt->u.dst.flags = DST_HOST;
rt->u.dst.input = ip6_input;
rt->u.dst.output = ip6_output;
- rt->rt6i_dev = init_net.loopback_dev;
+ rt->rt6i_dev = net->loopback_dev;
rt->rt6i_idev = idev;
rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst));
@@ -1867,7 +1879,7 @@ struct rt6_info *addrconf_dst_alloc(stru
ipv6_addr_copy(&rt->rt6i_dst.addr, addr);
rt->rt6i_dst.plen = 128;
- rt->rt6i_table = fib6_get_table(&init_net, RT6_TABLE_LOCAL);
+ rt->rt6i_table = fib6_get_table(net, RT6_TABLE_LOCAL);
atomic_set(&rt->u.dst.__refcnt, 1);
@@ -2025,13 +2037,9 @@ errout:
static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
{
- struct net *net = skb->sk->sk_net;
struct fib6_config cfg;
int err;
- if (net != &init_net)
- return -EINVAL;
-
err = rtm_to_fib6_config(skb, nlh, &cfg);
if (err < 0)
return err;
@@ -2041,13 +2049,9 @@ static int inet6_rtm_delroute(struct sk_
static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
{
- struct net *net = skb->sk->sk_net;
struct fib6_config cfg;
int err;
- if (net != &init_net)
- return -EINVAL;
-
err = rtm_to_fib6_config(skb, nlh, &cfg);
if (err < 0)
return err;
@@ -2190,16 +2194,13 @@ static int inet6_rtm_getroute(struct sk_
struct flowi fl;
int err, iif = 0;
- if (net != &init_net)
- return -EINVAL;
-
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
if (err < 0)
goto errout;
err = -EINVAL;
memset(&fl, 0, sizeof(fl));
- fl.fl_net = &init_net;
+ fl.fl_net = net;
if (tb[RTA_SRC]) {
if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr))
@@ -2223,7 +2224,7 @@ static int inet6_rtm_getroute(struct sk_
if (iif) {
struct net_device *dev;
- dev = __dev_get_by_index(&init_net, iif);
+ dev = __dev_get_by_index(net, iif);
if (!dev) {
err = -ENODEV;
goto errout;
@@ -2253,7 +2254,7 @@ static int inet6_rtm_getroute(struct sk_
goto errout;
}
- err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
+ err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
errout:
return err;
}
@@ -2263,6 +2264,7 @@ void inet6_rt_notify(int event, struct r
struct sk_buff *skb;
u32 pid = info->pid, seq = info->nlh ? info->nlh->nlmsg_seq : 0;
struct nlmsghdr *nlh = info->nlh;
+ struct net *net = info->net;
int err = -ENOBUFS;
skb = nlmsg_new(rt6_nlmsg_size(), gfp_any());
@@ -2276,10 +2278,10 @@ void inet6_rt_notify(int event, struct r
kfree_skb(skb);
goto errout;
}
- err = rtnl_notify(skb, &init_net, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
+ err = rtnl_notify(skb, net, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
errout:
if (err < 0)
- rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_ROUTE, err);
+ rtnl_set_sk_err(net, RTNLGRP_IPV6_ROUTE, err);
}
/*
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 31/38][IPV6] rt6_info - make rt6_info accessed as a pointer
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (29 preceding siblings ...)
2007-12-03 16:17 ` [patch 30/38][IPV6] route6 - make route6 per namespace Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 32/38][IPV6] rt6_info - dynamically allocate rt6_info Daniel Lezcano
` (6 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: rt6-info-entries-dynamic-make-mindless-changes.patch --]
[-- Type: text/plain, Size: 10693 bytes --]
This patch make mindless changes and prepares the code to use dynamic
allocation for rt6_info structure. The code accesses the rt6_info
structure as a pointer instead of a global static variable.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/ip6_route.h | 6 +++---
net/ipv6/addrconf.c | 12 ++++++------
net/ipv6/fib6_rules.c | 12 ++++++------
net/ipv6/ip6_fib.c | 20 ++++++++++----------
net/ipv6/route.c | 36 +++++++++++++++++++++---------------
5 files changed, 46 insertions(+), 40 deletions(-)
Index: linux-2.6-netns/include/net/ip6_route.h
===================================================================
--- linux-2.6-netns.orig/include/net/ip6_route.h
+++ linux-2.6-netns/include/net/ip6_route.h
@@ -36,11 +36,11 @@ struct route_info {
#define RT6_LOOKUP_F_REACHABLE 0x2
#define RT6_LOOKUP_F_HAS_SADDR 0x4
-extern struct rt6_info ip6_null_entry;
+extern struct rt6_info *ip6_null_entry;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
-extern struct rt6_info ip6_prohibit_entry;
-extern struct rt6_info ip6_blk_hole_entry;
+extern struct rt6_info *ip6_prohibit_entry;
+extern struct rt6_info *ip6_blk_hole_entry;
#endif
extern int ip6_rt_gc_interval;
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -4265,13 +4265,13 @@ int __init addrconf_init(void)
if (err)
return err;
- ip6_null_entry.u.dst.dev = init_net.loopback_dev;
- ip6_null_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev);
+ ip6_null_entry->u.dst.dev = init_net.loopback_dev;
+ ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
- ip6_prohibit_entry.u.dst.dev = init_net.loopback_dev;
- ip6_prohibit_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev);
- ip6_blk_hole_entry.u.dst.dev = init_net.loopback_dev;
- ip6_blk_hole_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev);
+ ip6_prohibit_entry->u.dst.dev = init_net.loopback_dev;
+ ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
+ ip6_blk_hole_entry->u.dst.dev = init_net.loopback_dev;
+ ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
#endif
register_netdevice_notifier(&ipv6_dev_notf);
Index: linux-2.6-netns/net/ipv6/fib6_rules.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/fib6_rules.c
+++ linux-2.6-netns/net/ipv6/fib6_rules.c
@@ -45,8 +45,8 @@ struct dst_entry *fib6_rule_lookup(struc
if (arg.result)
return arg.result;
- dst_hold(&ip6_null_entry.u.dst);
- return &ip6_null_entry.u.dst;
+ dst_hold(&ip6_null_entry->u.dst);
+ return &ip6_null_entry->u.dst;
}
static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
@@ -61,14 +61,14 @@ static int fib6_rule_action(struct fib_r
case FR_ACT_TO_TBL:
break;
case FR_ACT_UNREACHABLE:
- rt = &ip6_null_entry;
+ rt = ip6_null_entry;
goto discard_pkt;
default:
case FR_ACT_BLACKHOLE:
- rt = &ip6_blk_hole_entry;
+ rt = ip6_blk_hole_entry;
goto discard_pkt;
case FR_ACT_PROHIBIT:
- rt = &ip6_prohibit_entry;
+ rt = ip6_prohibit_entry;
goto discard_pkt;
}
@@ -76,7 +76,7 @@ static int fib6_rule_action(struct fib_r
if (table)
rt = lookup(table, flp, flags);
- if (rt != &ip6_null_entry) {
+ if (rt != ip6_null_entry) {
struct fib6_rule *r = (struct fib6_rule *)rule;
/*
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -196,7 +196,7 @@ static struct fib6_table *fib6_alloc_tab
table = kzalloc(sizeof(*table), GFP_ATOMIC);
if (table != NULL) {
table->tb6_id = id;
- table->tb6_root.leaf = &ip6_null_entry;
+ table->tb6_root.leaf = ip6_null_entry;
table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
}
@@ -713,8 +713,8 @@ int fib6_add(struct fib6_node *root, str
if (sfn == NULL)
goto st_failure;
- sfn->leaf = &ip6_null_entry;
- atomic_inc(&ip6_null_entry.rt6i_ref);
+ sfn->leaf = ip6_null_entry;
+ atomic_inc(&ip6_null_entry->rt6i_ref);
sfn->fn_flags = RTN_ROOT;
sfn->fn_sernum = fib6_new_sernum();
@@ -773,7 +773,7 @@ out:
#if RT6_DEBUG >= 2
if (!pn->leaf) {
BUG_TRAP(pn->leaf != NULL);
- pn->leaf = &ip6_null_entry;
+ pn->leaf = ip6_null_entry;
}
#endif
atomic_inc(&pn->leaf->rt6i_ref);
@@ -958,7 +958,7 @@ struct fib6_node * fib6_locate(struct fi
static struct rt6_info * fib6_find_prefix(struct fib6_node *fn)
{
if (fn->fn_flags&RTN_ROOT)
- return &ip6_null_entry;
+ return ip6_null_entry;
while(fn) {
if(fn->left)
@@ -1008,7 +1008,7 @@ static struct fib6_node * fib6_repair_tr
#if RT6_DEBUG >= 2
if (fn->leaf==NULL) {
BUG_TRAP(fn->leaf);
- fn->leaf = &ip6_null_entry;
+ fn->leaf = ip6_null_entry;
}
#endif
atomic_inc(&fn->leaf->rt6i_ref);
@@ -1110,7 +1110,7 @@ static void fib6_del_route(struct fib6_n
rt->u.dst.rt6_next = NULL;
if (fn->leaf == NULL && fn->fn_flags&RTN_TL_ROOT)
- fn->leaf = &ip6_null_entry;
+ fn->leaf = ip6_null_entry;
/* If it was last route, expunge its radix tree node */
if (fn->leaf == NULL) {
@@ -1153,7 +1153,7 @@ int fib6_del(struct rt6_info *rt, struct
return -ENOENT;
}
#endif
- if (fn == NULL || rt == &ip6_null_entry)
+ if (fn == NULL || rt == ip6_null_entry)
return -ENOENT;
BUG_TRAP(fn->fn_flags&RTN_RTINFO);
@@ -1498,7 +1498,7 @@ static int fib6_net_init(struct net *net
goto out_fib6_main_tbl;
net->fib6_main_tbl->tb6_id = RT6_TABLE_MAIN;
- net->fib6_main_tbl->tb6_root.leaf = &ip6_null_entry;
+ net->fib6_main_tbl->tb6_root.leaf = ip6_null_entry;
net->fib6_main_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
@@ -1508,7 +1508,7 @@ static int fib6_net_init(struct net *net
goto out_fib6_main_tbl;
}
net->fib6_local_tbl->tb6_id = RT6_TABLE_LOCAL;
- net->fib6_local_tbl->tb6_root.leaf = &ip6_null_entry;
+ net->fib6_local_tbl->tb6_root.leaf = ip6_null_entry;
net->fib6_local_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
#endif
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -132,7 +132,7 @@ static struct dst_ops ip6_dst_blackhole_
.entry_size = sizeof(struct rt6_info),
};
-struct rt6_info ip6_null_entry = {
+static struct rt6_info __ip6_null_entry = {
.u = {
.dst = {
.__refcnt = ATOMIC_INIT(1),
@@ -143,7 +143,7 @@ struct rt6_info ip6_null_entry = {
.input = ip6_pkt_discard,
.output = ip6_pkt_discard_out,
.ops = &ip6_dst_ops,
- .path = (struct dst_entry*)&ip6_null_entry,
+ .path = (struct dst_entry*)&__ip6_null_entry,
}
},
.rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
@@ -151,12 +151,14 @@ struct rt6_info ip6_null_entry = {
.rt6i_ref = ATOMIC_INIT(1),
};
+struct rt6_info *ip6_null_entry = &__ip6_null_entry;
+
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
static int ip6_pkt_prohibit(struct sk_buff *skb);
static int ip6_pkt_prohibit_out(struct sk_buff *skb);
-struct rt6_info ip6_prohibit_entry = {
+struct rt6_info __ip6_prohibit_entry = {
.u = {
.dst = {
.__refcnt = ATOMIC_INIT(1),
@@ -167,7 +169,7 @@ struct rt6_info ip6_prohibit_entry = {
.input = ip6_pkt_prohibit,
.output = ip6_pkt_prohibit_out,
.ops = &ip6_dst_ops,
- .path = (struct dst_entry*)&ip6_prohibit_entry,
+ .path = (struct dst_entry*)&__ip6_prohibit_entry,
}
},
.rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
@@ -175,7 +177,9 @@ struct rt6_info ip6_prohibit_entry = {
.rt6i_ref = ATOMIC_INIT(1),
};
-struct rt6_info ip6_blk_hole_entry = {
+struct rt6_info *ip6_prohibit_entry = &__ip6_prohibit_entry;
+
+static struct rt6_info __ip6_blk_hole_entry = {
.u = {
.dst = {
.__refcnt = ATOMIC_INIT(1),
@@ -186,7 +190,7 @@ struct rt6_info ip6_blk_hole_entry = {
.input = dst_discard,
.output = dst_discard,
.ops = &ip6_dst_ops,
- .path = (struct dst_entry*)&ip6_blk_hole_entry,
+ .path = (struct dst_entry*)&__ip6_blk_hole_entry,
}
},
.rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
@@ -194,6 +198,8 @@ struct rt6_info ip6_blk_hole_entry = {
.rt6i_ref = ATOMIC_INIT(1),
};
+struct rt6_info *ip6_blk_hole_entry = &__ip6_blk_hole_entry;
+
#endif
/* allocate dst with ip6_dst_ops */
@@ -276,7 +282,7 @@ static __inline__ struct rt6_info *rt6_d
return local;
if (strict)
- return &ip6_null_entry;
+ return ip6_null_entry;
}
return rt;
}
@@ -437,7 +443,7 @@ static struct rt6_info *rt6_select(struc
RT6_TRACE("%s() => %p\n",
__FUNCTION__, match);
- return (match ? match : &ip6_null_entry);
+ return (match ? match : ip6_null_entry);
}
#ifdef CONFIG_IPV6_ROUTE_INFO
@@ -522,7 +528,7 @@ int rt6_route_rcv(struct net_device *dev
#define BACKTRACK(saddr) \
do { \
- if (rt == &ip6_null_entry) { \
+ if (rt == ip6_null_entry) { \
struct fib6_node *pn; \
while (1) { \
if (fn->fn_flags & RTN_TL_ROOT) \
@@ -691,7 +697,7 @@ restart_2:
restart:
rt = rt6_select(fn, oif, strict | reachable);
BACKTRACK(&fl->fl6_src);
- if (rt == &ip6_null_entry ||
+ if (rt == ip6_null_entry ||
rt->rt6i_flags & RTF_CACHE)
goto out;
@@ -709,7 +715,7 @@ restart:
}
dst_release(&rt->u.dst);
- rt = nrt ? : &ip6_null_entry;
+ rt = nrt ? : ip6_null_entry;
dst_hold(&rt->u.dst);
if (nrt) {
@@ -1259,7 +1265,7 @@ static int __ip6_del_rt(struct rt6_info
int err;
struct fib6_table *table;
- if (rt == &ip6_null_entry)
+ if (rt == ip6_null_entry)
return -ENOENT;
table = rt->rt6i_table;
@@ -1374,7 +1380,7 @@ restart:
}
if (!rt)
- rt = &ip6_null_entry;
+ rt = ip6_null_entry;
BACKTRACK(&fl->fl6_src);
out:
dst_hold(&rt->u.dst);
@@ -1419,7 +1425,7 @@ void rt6_redirect(struct in6_addr *dest,
rt = ip6_route_redirect(dest, src, saddr, neigh->dev);
- if (rt == &ip6_null_entry) {
+ if (rt == ip6_null_entry) {
if (net_ratelimit())
printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop "
"for redirect target\n");
@@ -1889,7 +1895,7 @@ struct rt6_info *addrconf_dst_alloc(stru
static int fib6_ifdown(struct rt6_info *rt, void *arg)
{
if (((void*)rt->rt6i_dev == arg || arg == NULL) &&
- rt != &ip6_null_entry) {
+ rt != ip6_null_entry) {
RT6_TRACE("deleted by ifdown %p\n", rt);
return -1;
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 32/38][IPV6] rt6_info - dynamically allocate rt6_info
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (30 preceding siblings ...)
2007-12-03 16:17 ` [patch 31/38][IPV6] rt6_info - make rt6_info accessed as a pointer Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 33/38][IPV6] rt6_info - move rt6_info structure inside the namespace Daniel Lezcano
` (5 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: rt6-info-entries-dynamic-allocation.patch --]
[-- Type: text/plain, Size: 4812 bytes --]
The rt6_info structure are no longer a global static variable but
a dynamically allocated structure.
In order to facilitate future multiple instanciations of rt6_info
structures when multiple network namespaces will be supported, a
global static variable is still present as template for rt6_info
structure initialization.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/route.c | 67 ++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 47 insertions(+), 20 deletions(-)
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -132,7 +132,7 @@ static struct dst_ops ip6_dst_blackhole_
.entry_size = sizeof(struct rt6_info),
};
-static struct rt6_info __ip6_null_entry = {
+static struct rt6_info ip6_null_entry_template = {
.u = {
.dst = {
.__refcnt = ATOMIC_INIT(1),
@@ -143,7 +143,6 @@ static struct rt6_info __ip6_null_entry
.input = ip6_pkt_discard,
.output = ip6_pkt_discard_out,
.ops = &ip6_dst_ops,
- .path = (struct dst_entry*)&__ip6_null_entry,
}
},
.rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
@@ -151,35 +150,34 @@ static struct rt6_info __ip6_null_entry
.rt6i_ref = ATOMIC_INIT(1),
};
-struct rt6_info *ip6_null_entry = &__ip6_null_entry;
+struct rt6_info *ip6_null_entry;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
static int ip6_pkt_prohibit(struct sk_buff *skb);
static int ip6_pkt_prohibit_out(struct sk_buff *skb);
-struct rt6_info __ip6_prohibit_entry = {
+struct rt6_info ip6_prohibit_entry_template = {
.u = {
.dst = {
- .__refcnt = ATOMIC_INIT(1),
- .__use = 1,
- .obsolete = -1,
- .error = -EACCES,
- .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
- .input = ip6_pkt_prohibit,
- .output = ip6_pkt_prohibit_out,
- .ops = &ip6_dst_ops,
- .path = (struct dst_entry*)&__ip6_prohibit_entry,
+ .__refcnt = ATOMIC_INIT(1),
+ .__use = 1,
+ .obsolete = -1,
+ .error = -EACCES,
+ .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
+ .input = ip6_pkt_prohibit,
+ .output = ip6_pkt_prohibit_out,
+ .ops = &ip6_dst_ops,
}
},
- .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
- .rt6i_metric = ~(u32) 0,
- .rt6i_ref = ATOMIC_INIT(1),
+ .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
+ .rt6i_metric = ~(u32) 0,
+ .rt6i_ref = ATOMIC_INIT(1),
};
-struct rt6_info *ip6_prohibit_entry = &__ip6_prohibit_entry;
+struct rt6_info *ip6_prohibit_entry;
-static struct rt6_info __ip6_blk_hole_entry = {
+static struct rt6_info ip6_blk_hole_entry_template = {
.u = {
.dst = {
.__refcnt = ATOMIC_INIT(1),
@@ -190,7 +188,6 @@ static struct rt6_info __ip6_blk_hole_en
.input = dst_discard,
.output = dst_discard,
.ops = &ip6_dst_ops,
- .path = (struct dst_entry*)&__ip6_blk_hole_entry,
}
},
.rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
@@ -198,7 +195,7 @@ static struct rt6_info __ip6_blk_hole_en
.rt6i_ref = ATOMIC_INIT(1),
};
-struct rt6_info *ip6_blk_hole_entry = &__ip6_blk_hole_entry;
+struct rt6_info *ip6_blk_hole_entry;
#endif
@@ -2534,6 +2531,32 @@ static struct pernet_operations ip6_rout
void __init ip6_route_init(void)
{
+ ip6_null_entry = kzalloc(sizeof(*ip6_null_entry), GFP_KERNEL);
+ if (!ip6_null_entry)
+ panic("IPV6: cannot allocate ip6_null_entry\n");
+
+ memcpy(ip6_null_entry, &ip6_null_entry_template,
+ sizeof(*ip6_null_entry));
+ ip6_null_entry->u.dst.path = (struct dst_entry*)ip6_null_entry;
+
+ #ifdef CONFIG_IPV6_MULTIPLE_TABLES
+ ip6_prohibit_entry = kzalloc(sizeof(*ip6_prohibit_entry), GFP_KERNEL);
+ if (!ip6_prohibit_entry)
+ panic("IPV6: cannot allocate ip6_prohibit_entry\n");
+
+ memcpy(ip6_prohibit_entry, &ip6_prohibit_entry_template,
+ sizeof(*ip6_prohibit_entry));
+ ip6_prohibit_entry->u.dst.path = (struct dst_entry*)ip6_prohibit_entry;
+
+ ip6_blk_hole_entry = kzalloc(sizeof(*ip6_blk_hole_entry), GFP_KERNEL);
+ if (!ip6_blk_hole_entry)
+ panic("IPV6: panic cannot allocate ip6_blk_hole_entry\n");
+
+ memcpy(ip6_blk_hole_entry, &ip6_blk_hole_entry_template,
+ sizeof(*ip6_blk_hole_entry));
+ ip6_blk_hole_entry->u.dst.path = (struct dst_entry*)ip6_blk_hole_entry;
+ #endif
+
ip6_dst_ops.kmem_cachep =
kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
@@ -2566,4 +2589,8 @@ void ip6_route_cleanup(void)
rt6_ifdown(NULL);
fib6_gc_cleanup();
kmem_cache_destroy(ip6_dst_ops.kmem_cachep);
+
+ kfree(ip6_null_entry);
+ kfree(ip6_prohibit_entry);
+ kfree(ip6_blk_hole_entry);
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 33/38][IPV6] rt6_info - move rt6_info structure inside the namespace
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (31 preceding siblings ...)
2007-12-03 16:17 ` [patch 32/38][IPV6] rt6_info - dynamically allocate rt6_info Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 34/38][IPV6] addrconf - Pass the proper network namespace parameters to addrconf Daniel Lezcano
` (4 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: rt6-info-entries-per-namespace.patch --]
[-- Type: text/plain, Size: 19052 bytes --]
The rt6_info structures are moved inside the network namespace
structure. All references to these structures are now relative
to the initial network namespace.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/net_namespace.h | 3 +
net/ipv6/addrconf.c | 12 ++--
net/ipv6/fib6_rules.c | 13 ++--
net/ipv6/ip6_fib.c | 47 ++++++++-------
net/ipv6/route.c | 132 +++++++++++++++++++++++++-------------------
5 files changed, 117 insertions(+), 90 deletions(-)
Index: linux-2.6-netns/include/net/net_namespace.h
===================================================================
--- linux-2.6-netns.orig/include/net/net_namespace.h
+++ linux-2.6-netns/include/net/net_namespace.h
@@ -47,9 +47,12 @@ struct net {
/* ipv6 routing table */
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct rt6_statistics *rt6_stats;
+ struct rt6_info *ip6_null_entry;
struct hlist_head *fib_table_hash;
struct fib6_table *fib6_main_tbl;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+ struct rt6_info *ip6_prohibit_entry;
+ struct rt6_info *ip6_blk_hole_entry;
struct fib6_table *fib6_local_tbl;
#endif /* CONFIG_IPV6_MULTIPLE_TABLES */
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -4265,13 +4265,13 @@ int __init addrconf_init(void)
if (err)
return err;
- ip6_null_entry->u.dst.dev = init_net.loopback_dev;
- ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
+ init_net.ip6_null_entry->u.dst.dev = init_net.loopback_dev;
+ init_net.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
- ip6_prohibit_entry->u.dst.dev = init_net.loopback_dev;
- ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
- ip6_blk_hole_entry->u.dst.dev = init_net.loopback_dev;
- ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
+ init_net.ip6_prohibit_entry->u.dst.dev = init_net.loopback_dev;
+ init_net.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
+ init_net.ip6_blk_hole_entry->u.dst.dev = init_net.loopback_dev;
+ init_net.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
#endif
register_netdevice_notifier(&ipv6_dev_notf);
Index: linux-2.6-netns/net/ipv6/fib6_rules.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/fib6_rules.c
+++ linux-2.6-netns/net/ipv6/fib6_rules.c
@@ -34,6 +34,7 @@ static struct fib_rules_ops fib6_rules_o
struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags,
pol_lookup_t lookup)
{
+ struct net *net = fl->fl_net;
struct fib_lookup_arg arg = {
.lookup_ptr = lookup,
};
@@ -45,8 +46,8 @@ struct dst_entry *fib6_rule_lookup(struc
if (arg.result)
return arg.result;
- dst_hold(&ip6_null_entry->u.dst);
- return &ip6_null_entry->u.dst;
+ dst_hold(&net->ip6_null_entry->u.dst);
+ return &net->ip6_null_entry->u.dst;
}
static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
@@ -61,14 +62,14 @@ static int fib6_rule_action(struct fib_r
case FR_ACT_TO_TBL:
break;
case FR_ACT_UNREACHABLE:
- rt = ip6_null_entry;
+ rt = net->ip6_null_entry;
goto discard_pkt;
default:
case FR_ACT_BLACKHOLE:
- rt = ip6_blk_hole_entry;
+ rt = net->ip6_blk_hole_entry;
goto discard_pkt;
case FR_ACT_PROHIBIT:
- rt = ip6_prohibit_entry;
+ rt = net->ip6_prohibit_entry;
goto discard_pkt;
}
@@ -76,7 +77,7 @@ static int fib6_rule_action(struct fib_r
if (table)
rt = lookup(table, flp, flags);
- if (rt != ip6_null_entry) {
+ if (rt != net->ip6_null_entry) {
struct fib6_rule *r = (struct fib6_rule *)rule;
/*
Index: linux-2.6-netns/net/ipv6/ip6_fib.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ip6_fib.c
+++ linux-2.6-netns/net/ipv6/ip6_fib.c
@@ -77,8 +77,8 @@ static DEFINE_RWLOCK(fib6_walker_lock);
#endif
static void fib6_prune_clones(struct fib6_node *fn, struct rt6_info *rt);
-static struct rt6_info * fib6_find_prefix(struct fib6_node *fn);
-static struct fib6_node * fib6_repair_tree(struct fib6_node *fn);
+static struct rt6_info * fib6_find_prefix(struct net *net, struct fib6_node *fn);
+static struct fib6_node * fib6_repair_tree(struct net *net, struct fib6_node *fn);
static int fib6_walk(struct fib6_walker_t *w);
static int fib6_walk_continue(struct fib6_walker_t *w);
@@ -189,14 +189,14 @@ static void fib6_link_table(struct net *
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
-static struct fib6_table *fib6_alloc_table(u32 id)
+static struct fib6_table *fib6_alloc_table(struct net *net, u32 id)
{
struct fib6_table *table;
table = kzalloc(sizeof(*table), GFP_ATOMIC);
if (table != NULL) {
table->tb6_id = id;
- table->tb6_root.leaf = ip6_null_entry;
+ table->tb6_root.leaf = net->ip6_null_entry;
table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
}
@@ -213,7 +213,7 @@ struct fib6_table *fib6_new_table(struct
if (tb)
return tb;
- tb = fib6_alloc_table(id);
+ tb = fib6_alloc_table(net, id);
if (tb != NULL)
fib6_link_table(net, tb);
@@ -681,6 +681,7 @@ void fib6_force_start_gc(void)
int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info)
{
struct fib6_node *fn, *pn = NULL;
+ struct net *net = info->net;
int err = -ENOMEM;
fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr),
@@ -713,8 +714,8 @@ int fib6_add(struct fib6_node *root, str
if (sfn == NULL)
goto st_failure;
- sfn->leaf = ip6_null_entry;
- atomic_inc(&ip6_null_entry->rt6i_ref);
+ sfn->leaf = net->ip6_null_entry;
+ atomic_inc(&net->ip6_null_entry->rt6i_ref);
sfn->fn_flags = RTN_ROOT;
sfn->fn_sernum = fib6_new_sernum();
@@ -769,11 +770,11 @@ out:
* super-tree leaf node we have to find a new one for it.
*/
if (pn != fn && !pn->leaf && !(pn->fn_flags & RTN_RTINFO)) {
- pn->leaf = fib6_find_prefix(pn);
+ pn->leaf = fib6_find_prefix(net, pn);
#if RT6_DEBUG >= 2
if (!pn->leaf) {
BUG_TRAP(pn->leaf != NULL);
- pn->leaf = ip6_null_entry;
+ pn->leaf = net->ip6_null_entry;
}
#endif
atomic_inc(&pn->leaf->rt6i_ref);
@@ -789,7 +790,7 @@ out:
*/
st_failure:
if (fn && !(fn->fn_flags & (RTN_RTINFO|RTN_ROOT)))
- fib6_repair_tree(fn);
+ fib6_repair_tree(net, fn);
dst_free(&rt->u.dst);
return err;
#endif
@@ -854,7 +855,6 @@ static struct fib6_node * fib6_lookup_1(
if (fn->fn_flags & RTN_ROOT)
break;
-
fn = fn->parent;
}
@@ -955,10 +955,10 @@ struct fib6_node * fib6_locate(struct fi
*
*/
-static struct rt6_info * fib6_find_prefix(struct fib6_node *fn)
+static struct rt6_info * fib6_find_prefix(struct net *net, struct fib6_node *fn)
{
if (fn->fn_flags&RTN_ROOT)
- return ip6_null_entry;
+ return net->ip6_null_entry;
while(fn) {
if(fn->left)
@@ -977,7 +977,7 @@ static struct rt6_info * fib6_find_prefi
* is the node we want to try and remove.
*/
-static struct fib6_node * fib6_repair_tree(struct fib6_node *fn)
+static struct fib6_node * fib6_repair_tree(struct net *net, struct fib6_node *fn)
{
int children;
int nstate;
@@ -1004,11 +1004,11 @@ static struct fib6_node * fib6_repair_tr
|| (children && fn->fn_flags&RTN_ROOT)
#endif
) {
- fn->leaf = fib6_find_prefix(fn);
+ fn->leaf = fib6_find_prefix(net, fn);
#if RT6_DEBUG >= 2
if (fn->leaf==NULL) {
BUG_TRAP(fn->leaf);
- fn->leaf = ip6_null_entry;
+ fn->leaf = net->ip6_null_entry;
}
#endif
atomic_inc(&fn->leaf->rt6i_ref);
@@ -1079,9 +1079,9 @@ static struct fib6_node * fib6_repair_tr
static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
struct nl_info *info)
{
+ struct net *net = info->net;
struct fib6_walker_t *w;
struct rt6_info *rt = *rtp;
- struct net *net = &init_net;
RT6_TRACE("fib6_del_route\n");
@@ -1110,13 +1110,13 @@ static void fib6_del_route(struct fib6_n
rt->u.dst.rt6_next = NULL;
if (fn->leaf == NULL && fn->fn_flags&RTN_TL_ROOT)
- fn->leaf = ip6_null_entry;
+ fn->leaf = net->ip6_null_entry;
/* If it was last route, expunge its radix tree node */
if (fn->leaf == NULL) {
fn->fn_flags &= ~RTN_RTINFO;
net->rt6_stats->fib_route_nodes--;
- fn = fib6_repair_tree(fn);
+ fn = fib6_repair_tree(net, fn);
}
if (atomic_read(&rt->rt6i_ref) != 1) {
@@ -1128,7 +1128,7 @@ static void fib6_del_route(struct fib6_n
*/
while (fn) {
if (!(fn->fn_flags&RTN_RTINFO) && fn->leaf == rt) {
- fn->leaf = fib6_find_prefix(fn);
+ fn->leaf = fib6_find_prefix(net, fn);
atomic_inc(&fn->leaf->rt6i_ref);
rt6_release(rt);
}
@@ -1144,6 +1144,7 @@ static void fib6_del_route(struct fib6_n
int fib6_del(struct rt6_info *rt, struct nl_info *info)
{
+ struct net *net = info->net;
struct fib6_node *fn = rt->rt6i_node;
struct rt6_info **rtp;
@@ -1153,7 +1154,7 @@ int fib6_del(struct rt6_info *rt, struct
return -ENOENT;
}
#endif
- if (fn == NULL || rt == ip6_null_entry)
+ if (fn == NULL || rt == net->ip6_null_entry)
return -ENOENT;
BUG_TRAP(fn->fn_flags&RTN_RTINFO);
@@ -1498,7 +1499,7 @@ static int fib6_net_init(struct net *net
goto out_fib6_main_tbl;
net->fib6_main_tbl->tb6_id = RT6_TABLE_MAIN;
- net->fib6_main_tbl->tb6_root.leaf = ip6_null_entry;
+ net->fib6_main_tbl->tb6_root.leaf = net->ip6_null_entry;
net->fib6_main_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
@@ -1508,7 +1509,7 @@ static int fib6_net_init(struct net *net
goto out_fib6_main_tbl;
}
net->fib6_local_tbl->tb6_id = RT6_TABLE_LOCAL;
- net->fib6_local_tbl->tb6_root.leaf = ip6_null_entry;
+ net->fib6_local_tbl->tb6_root.leaf = net->ip6_null_entry;
net->fib6_local_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
#endif
Index: linux-2.6-netns/net/ipv6/route.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/route.c
+++ linux-2.6-netns/net/ipv6/route.c
@@ -150,8 +150,6 @@ static struct rt6_info ip6_null_entry_te
.rt6i_ref = ATOMIC_INIT(1),
};
-struct rt6_info *ip6_null_entry;
-
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
static int ip6_pkt_prohibit(struct sk_buff *skb);
@@ -175,8 +173,6 @@ struct rt6_info ip6_prohibit_entry_templ
.rt6i_ref = ATOMIC_INIT(1),
};
-struct rt6_info *ip6_prohibit_entry;
-
static struct rt6_info ip6_blk_hole_entry_template = {
.u = {
.dst = {
@@ -195,8 +191,6 @@ static struct rt6_info ip6_blk_hole_entr
.rt6i_ref = ATOMIC_INIT(1),
};
-struct rt6_info *ip6_blk_hole_entry;
-
#endif
/* allocate dst with ip6_dst_ops */
@@ -250,7 +244,8 @@ static inline int rt6_need_strict(struct
* Route lookup. Any table->tb6_lock is implied.
*/
-static __inline__ struct rt6_info *rt6_device_match(struct rt6_info *rt,
+static __inline__ struct rt6_info *rt6_device_match(struct net *net,
+ struct rt6_info *rt,
int oif,
int strict)
{
@@ -279,7 +274,7 @@ static __inline__ struct rt6_info *rt6_d
return local;
if (strict)
- return ip6_null_entry;
+ return net->ip6_null_entry;
}
return rt;
}
@@ -412,7 +407,8 @@ static struct rt6_info *find_rr_leaf(str
return match;
}
-static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict)
+static struct rt6_info *rt6_select(struct net *net,
+ struct fib6_node *fn, int oif, int strict)
{
struct rt6_info *match, *rt0;
@@ -440,7 +436,7 @@ static struct rt6_info *rt6_select(struc
RT6_TRACE("%s() => %p\n",
__FUNCTION__, match);
- return (match ? match : ip6_null_entry);
+ return (match ? match : net->ip6_null_entry);
}
#ifdef CONFIG_IPV6_ROUTE_INFO
@@ -523,9 +519,9 @@ int rt6_route_rcv(struct net_device *dev
}
#endif
-#define BACKTRACK(saddr) \
+#define BACKTRACK(__net, saddr) \
do { \
- if (rt == ip6_null_entry) { \
+ if (rt == __net->ip6_null_entry) { \
struct fib6_node *pn; \
while (1) { \
if (fn->fn_flags & RTN_TL_ROOT) \
@@ -544,6 +540,7 @@ do { \
static struct rt6_info *ip6_pol_route_lookup(struct fib6_table *table,
struct flowi *fl, int flags)
{
+ struct net *net = fl->fl_net;
struct fib6_node *fn;
struct rt6_info *rt;
@@ -551,8 +548,8 @@ static struct rt6_info *ip6_pol_route_lo
fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
restart:
rt = fn->leaf;
- rt = rt6_device_match(rt, fl->oif, flags);
- BACKTRACK(&fl->fl6_src);
+ rt = rt6_device_match(net, rt, fl->oif, flags);
+ BACKTRACK(net, &fl->fl6_src);
out:
dst_use(&rt->u.dst, jiffies);
read_unlock_bh(&table->tb6_lock);
@@ -676,6 +673,7 @@ static struct rt6_info *rt6_alloc_clone(
static struct rt6_info *ip6_pol_route(struct fib6_table *table, int oif,
struct flowi *fl, int flags)
{
+ struct net *net = fl->fl_net;
struct fib6_node *fn;
struct rt6_info *rt, *nrt;
int strict = 0;
@@ -692,9 +690,9 @@ restart_2:
fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
restart:
- rt = rt6_select(fn, oif, strict | reachable);
- BACKTRACK(&fl->fl6_src);
- if (rt == ip6_null_entry ||
+ rt = rt6_select(net, fn, oif, strict | reachable);
+ BACKTRACK(net, &fl->fl6_src);
+ if (rt == net->ip6_null_entry ||
rt->rt6i_flags & RTF_CACHE)
goto out;
@@ -712,7 +710,7 @@ restart:
}
dst_release(&rt->u.dst);
- rt = nrt ? : ip6_null_entry;
+ rt = nrt ? : net->ip6_null_entry;
dst_hold(&rt->u.dst);
if (nrt) {
@@ -1261,8 +1259,9 @@ static int __ip6_del_rt(struct rt6_info
{
int err;
struct fib6_table *table;
+ struct net *net = rt->rt6i_dev->nd_net;
- if (rt == ip6_null_entry)
+ if (rt == net->ip6_null_entry)
return -ENOENT;
table = rt->rt6i_table;
@@ -1341,6 +1340,7 @@ static struct rt6_info *__ip6_route_redi
struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl;
struct rt6_info *rt;
struct fib6_node *fn;
+ struct net *net = fl->fl_net;
/*
* Get the "current" route for this destination and
@@ -1377,8 +1377,8 @@ restart:
}
if (!rt)
- rt = ip6_null_entry;
- BACKTRACK(&fl->fl6_src);
+ rt = net->ip6_null_entry;
+ BACKTRACK(fl->fl_net, &fl->fl6_src);
out:
dst_hold(&rt->u.dst);
@@ -1419,10 +1419,11 @@ void rt6_redirect(struct in6_addr *dest,
{
struct rt6_info *rt, *nrt = NULL;
struct netevent_redirect netevent;
+ struct net *net = neigh->dev->nd_net;
rt = ip6_route_redirect(dest, src, saddr, neigh->dev);
- if (rt == ip6_null_entry) {
+ if (rt == net->ip6_null_entry) {
if (net_ratelimit())
printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop "
"for redirect target\n");
@@ -1891,8 +1892,10 @@ struct rt6_info *addrconf_dst_alloc(stru
static int fib6_ifdown(struct rt6_info *rt, void *arg)
{
+ struct net *net = rt->rt6i_dev->nd_net;
+
if (((void*)rt->rt6i_dev == arg || arg == NULL) &&
- rt != ip6_null_entry) {
+ rt != net->ip6_null_entry) {
RT6_TRACE("deleted by ifdown %p\n", rt);
return -1;
}
@@ -2513,15 +2516,63 @@ ctl_table ipv6_route_table[] = {
static int ip6_route_net_init(struct net *net)
{
+ int ret = 0;
+
+ ret = -ENOMEM;
+ net->ip6_null_entry = kzalloc(sizeof(*net->ip6_null_entry), GFP_KERNEL);
+ if (!net->ip6_null_entry)
+ goto out;
+
+ memcpy(net->ip6_null_entry, &ip6_null_entry_template,
+ sizeof(*net->ip6_null_entry));
+ net->ip6_null_entry->u.dst.path = (struct dst_entry*)net->ip6_null_entry;
+
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+ net->ip6_prohibit_entry = kzalloc(sizeof(*net->ip6_prohibit_entry),
+ GFP_KERNEL);
+ if (!net->ip6_prohibit_entry)
+ goto out_ip6_prohibit_entry;
+
+ memcpy(net->ip6_prohibit_entry, &ip6_prohibit_entry_template,
+ sizeof(*net->ip6_prohibit_entry));
+ net->ip6_prohibit_entry->u.dst.path =
+ (struct dst_entry*)net->ip6_prohibit_entry;
+
+ net->ip6_blk_hole_entry = kzalloc(sizeof(*net->ip6_blk_hole_entry),
+ GFP_KERNEL);
+ if (!net->ip6_blk_hole_entry) {
+ kfree(net->ip6_prohibit_entry);
+ goto out_ip6_prohibit_entry;
+ }
+
+ memcpy(net->ip6_blk_hole_entry, &ip6_blk_hole_entry_template,
+ sizeof(*net->ip6_blk_hole_entry));
+ net->ip6_blk_hole_entry->u.dst.path =
+ (struct dst_entry*)net->ip6_blk_hole_entry;
+#endif
+
proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops);
proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
- return 0;
+
+ ret = 0;
+out:
+ return ret;
+
+out_ip6_prohibit_entry:
+ kfree(net->ip6_null_entry);
+ goto out;
}
static void ip6_route_net_exit(struct net *net)
{
proc_net_remove(net, "ipv6_route");
proc_net_remove(net, "rt6_stats");
+
+ kfree(net->ip6_null_entry);
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+ kfree(net->ip6_prohibit_entry);
+ kfree(net->ip6_blk_hole_entry);
+#endif
}
static struct pernet_operations ip6_route_net_ops = {
@@ -2531,38 +2582,13 @@ static struct pernet_operations ip6_rout
void __init ip6_route_init(void)
{
- ip6_null_entry = kzalloc(sizeof(*ip6_null_entry), GFP_KERNEL);
- if (!ip6_null_entry)
- panic("IPV6: cannot allocate ip6_null_entry\n");
-
- memcpy(ip6_null_entry, &ip6_null_entry_template,
- sizeof(*ip6_null_entry));
- ip6_null_entry->u.dst.path = (struct dst_entry*)ip6_null_entry;
-
- #ifdef CONFIG_IPV6_MULTIPLE_TABLES
- ip6_prohibit_entry = kzalloc(sizeof(*ip6_prohibit_entry), GFP_KERNEL);
- if (!ip6_prohibit_entry)
- panic("IPV6: cannot allocate ip6_prohibit_entry\n");
-
- memcpy(ip6_prohibit_entry, &ip6_prohibit_entry_template,
- sizeof(*ip6_prohibit_entry));
- ip6_prohibit_entry->u.dst.path = (struct dst_entry*)ip6_prohibit_entry;
-
- ip6_blk_hole_entry = kzalloc(sizeof(*ip6_blk_hole_entry), GFP_KERNEL);
- if (!ip6_blk_hole_entry)
- panic("IPV6: panic cannot allocate ip6_blk_hole_entry\n");
-
- memcpy(ip6_blk_hole_entry, &ip6_blk_hole_entry_template,
- sizeof(*ip6_blk_hole_entry));
- ip6_blk_hole_entry->u.dst.path = (struct dst_entry*)ip6_blk_hole_entry;
- #endif
+ register_pernet_subsys(&ip6_route_net_ops);
ip6_dst_ops.kmem_cachep =
kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep;
- register_pernet_subsys(&ip6_route_net_ops);
fib6_init();
#ifdef CONFIG_XFRM
xfrm6_init();
@@ -2578,8 +2604,6 @@ void __init ip6_route_init(void)
void ip6_route_cleanup(void)
{
- unregister_pernet_subsys(&ip6_route_net_ops);
-
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
fib6_rules_cleanup();
#endif
@@ -2590,7 +2614,5 @@ void ip6_route_cleanup(void)
fib6_gc_cleanup();
kmem_cache_destroy(ip6_dst_ops.kmem_cachep);
- kfree(ip6_null_entry);
- kfree(ip6_prohibit_entry);
- kfree(ip6_blk_hole_entry);
+ unregister_pernet_subsys(&ip6_route_net_ops);
}
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 34/38][IPV6] addrconf - Pass the proper network namespace parameters to addrconf
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (32 preceding siblings ...)
2007-12-03 16:17 ` [patch 33/38][IPV6] rt6_info - move rt6_info structure inside the namespace Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 35/38][IPV6] addrconf - Add a network namespace parameter to addrconf_forward_change Daniel Lezcano
` (3 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: addrconf-per-network-namespace.patch --]
[-- Type: text/plain, Size: 7723 bytes --]
This patch propagateis the network namespace pointer to the functions
which need it, which means adding a new parameter to these functions,
and make them use it instead of using the initial network namespace.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
include/net/addrconf.h | 9 ++++---
net/ipv6/addrconf.c | 63 +++++++++++++++++++++++++++++++++++--------------
net/ipv6/af_inet6.c | 6 ++--
3 files changed, 54 insertions(+), 24 deletions(-)
Index: linux-2.6-netns/include/net/addrconf.h
===================================================================
--- linux-2.6-netns.orig/include/net/addrconf.h
+++ linux-2.6-netns/include/net/addrconf.h
@@ -54,9 +54,12 @@ struct prefix_info {
extern int addrconf_init(void);
extern void addrconf_cleanup(void);
-extern int addrconf_add_ifaddr(void __user *arg);
-extern int addrconf_del_ifaddr(void __user *arg);
-extern int addrconf_set_dstaddr(void __user *arg);
+extern int addrconf_add_ifaddr(struct net *net,
+ void __user *arg);
+extern int addrconf_del_ifaddr(struct net *net,
+ void __user *arg);
+extern int addrconf_set_dstaddr(struct net *net,
+ void __user *arg);
extern int ipv6_chk_addr(struct net *net,
struct in6_addr *addr,
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -1847,7 +1847,7 @@ ok:
* Special case for SIT interfaces where we create a new "virtual"
* device.
*/
-int addrconf_set_dstaddr(void __user *arg)
+int addrconf_set_dstaddr(struct net *net, void __user *arg)
{
struct in6_ifreq ireq;
struct net_device *dev;
@@ -1859,7 +1859,7 @@ int addrconf_set_dstaddr(void __user *ar
if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
goto err_exit;
- dev = __dev_get_by_index(&init_net, ireq.ifr6_ifindex);
+ dev = __dev_get_by_index(net, ireq.ifr6_ifindex);
err = -ENODEV;
if (dev == NULL)
@@ -1890,7 +1890,7 @@ int addrconf_set_dstaddr(void __user *ar
if (err == 0) {
err = -ENOBUFS;
- if ((dev = __dev_get_by_name(&init_net, p.name)) == NULL)
+ if ((dev = __dev_get_by_name(net, p.name)) == NULL)
goto err_exit;
err = dev_open(dev);
}
@@ -1905,8 +1905,9 @@ err_exit:
/*
* Manual configuration of address on an interface
*/
-static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen,
- __u8 ifa_flags, __u32 prefered_lft, __u32 valid_lft)
+static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx,
+ int plen, __u8 ifa_flags, __u32 prefered_lft,
+ __u32 valid_lft)
{
struct inet6_ifaddr *ifp;
struct inet6_dev *idev;
@@ -1920,7 +1921,7 @@ static int inet6_addr_add(int ifindex, s
if (!valid_lft || prefered_lft > valid_lft)
return -EINVAL;
- if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL)
+ if ((dev = __dev_get_by_index(net, ifindex)) == NULL)
return -ENODEV;
if ((idev = addrconf_add_dev(dev)) == NULL)
@@ -1965,13 +1966,14 @@ static int inet6_addr_add(int ifindex, s
return PTR_ERR(ifp);
}
-static int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen)
+static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx,
+ int plen)
{
struct inet6_ifaddr *ifp;
struct inet6_dev *idev;
struct net_device *dev;
- if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL)
+ if ((dev = __dev_get_by_index(net, ifindex)) == NULL)
return -ENODEV;
if ((idev = __in6_dev_get(dev)) == NULL)
@@ -1999,7 +2001,7 @@ static int inet6_addr_del(int ifindex, s
}
-int addrconf_add_ifaddr(void __user *arg)
+int addrconf_add_ifaddr(struct net *net, void __user *arg)
{
struct in6_ifreq ireq;
int err;
@@ -2011,13 +2013,14 @@ int addrconf_add_ifaddr(void __user *arg
return -EFAULT;
rtnl_lock();
- err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen,
- IFA_F_PERMANENT, INFINITY_LIFE_TIME, INFINITY_LIFE_TIME);
+ err = inet6_addr_add(net, ireq.ifr6_ifindex, &ireq.ifr6_addr,
+ ireq.ifr6_prefixlen, IFA_F_PERMANENT,
+ INFINITY_LIFE_TIME, INFINITY_LIFE_TIME);
rtnl_unlock();
return err;
}
-int addrconf_del_ifaddr(void __user *arg)
+int addrconf_del_ifaddr(struct net *net, void __user *arg)
{
struct in6_ifreq ireq;
int err;
@@ -2029,7 +2032,8 @@ int addrconf_del_ifaddr(void __user *arg
return -EFAULT;
rtnl_lock();
- err = inet6_addr_del(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen);
+ err = inet6_addr_del(net, ireq.ifr6_ifindex, &ireq.ifr6_addr,
+ ireq.ifr6_prefixlen);
rtnl_unlock();
return err;
}
@@ -3031,7 +3035,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, s
if (pfx == NULL)
return -EINVAL;
- return inet6_addr_del(ifm->ifa_index, pfx, ifm->ifa_prefixlen);
+ return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen);
}
static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags,
@@ -3107,7 +3111,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, s
valid_lft = INFINITY_LIFE_TIME;
}
- dev = __dev_get_by_index(&init_net, ifm->ifa_index);
+ dev = __dev_get_by_index(net, ifm->ifa_index);
if (dev == NULL)
return -ENODEV;
@@ -3120,8 +3124,9 @@ inet6_rtm_newaddr(struct sk_buff *skb, s
* It would be best to check for !NLM_F_CREATE here but
* userspace alreay relies on not having to provide this.
*/
- return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen,
- ifa_flags, preferred_lft, valid_lft);
+ return inet6_addr_add(net, ifm->ifa_index, pfx,
+ ifm->ifa_prefixlen, ifa_flags, preferred_lft,
+ valid_lft);
}
if (nlh->nlmsg_flags & NLM_F_EXCL ||
@@ -4226,6 +4231,22 @@ int unregister_inet6addr_notifier(struct
EXPORT_SYMBOL(unregister_inet6addr_notifier);
+
+static int addrconf_net_init(struct net *net)
+{
+ return 0;
+}
+
+static void addrconf_net_exit(struct net *net)
+{
+ ;
+}
+
+static struct pernet_operations addrconf_net_ops = {
+ .init = addrconf_net_init,
+ .exit = addrconf_net_exit,
+};
+
/*
* Init / cleanup code
*/
@@ -4274,6 +4295,10 @@ int __init addrconf_init(void)
init_net.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
#endif
+ err = register_pernet_device(&addrconf_net_ops);
+ if (err)
+ return err;
+
register_netdevice_notifier(&ipv6_dev_notf);
addrconf_verify(0);
@@ -4300,6 +4325,7 @@ int __init addrconf_init(void)
return 0;
errout:
unregister_netdevice_notifier(&ipv6_dev_notf);
+ unregister_pernet_device(&addrconf_net_ops);
return err;
}
@@ -4350,6 +4376,7 @@ void __exit addrconf_cleanup(void)
write_unlock_bh(&addrconf_hash_lock);
del_timer(&addr_chk_timer);
-
rtnl_unlock();
+
+ unregister_pernet_subsys(&addrconf_net_ops);
}
Index: linux-2.6-netns/net/ipv6/af_inet6.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/af_inet6.c
+++ linux-2.6-netns/net/ipv6/af_inet6.c
@@ -457,11 +457,11 @@ int inet6_ioctl(struct socket *sock, uns
return(ipv6_route_ioctl(net, cmd,(void __user *)arg));
case SIOCSIFADDR:
- return addrconf_add_ifaddr((void __user *) arg);
+ return addrconf_add_ifaddr(net, (void __user *) arg);
case SIOCDIFADDR:
- return addrconf_del_ifaddr((void __user *) arg);
+ return addrconf_del_ifaddr(net, (void __user *) arg);
case SIOCSIFDSTADDR:
- return addrconf_set_dstaddr((void __user *) arg);
+ return addrconf_set_dstaddr(net, (void __user *) arg);
default:
if (!sk->sk_prot->ioctl)
return -ENOIOCTLCMD;
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 35/38][IPV6] addrconf - Add a network namespace parameter to addrconf_forward_change
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (33 preceding siblings ...)
2007-12-03 16:17 ` [patch 34/38][IPV6] addrconf - Pass the proper network namespace parameters to addrconf Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 36/38][IPV6] addrconf - make addrconf per namespace Daniel Lezcano
` (2 subsequent siblings)
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: addrconf-forward-per-namespace.patch --]
[-- Type: text/plain, Size: 1439 bytes --]
Add a network namespace parameter to addrconf_forward_change to
remove reference to init_net and make it more generic.
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/addrconf.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -451,13 +451,13 @@ static void dev_forward_change(struct in
}
-static void addrconf_forward_change(void)
+static void addrconf_forward_change(struct net *net)
{
struct net_device *dev;
struct inet6_dev *idev;
read_lock(&dev_base_lock);
- for_each_netdev(&init_net, dev) {
+ for_each_netdev(net, dev) {
rcu_read_lock();
idev = __in6_dev_get(dev);
if (idev) {
@@ -3808,7 +3808,7 @@ int addrconf_sysctl_forward(ctl_table *c
}
} else {
ipv6_devconf_dflt.forwarding = ipv6_devconf.forwarding;
- addrconf_forward_change();
+ addrconf_forward_change(&init_net);
}
if (*valp)
rt6_purge_dflt_routers(&init_net);
@@ -3860,7 +3860,7 @@ static int addrconf_sysctl_forward_strat
dev_forward_change(idev);
} else {
*valp = new;
- addrconf_forward_change();
+ addrconf_forward_change(&init_net);
}
if (*valp)
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 36/38][IPV6] addrconf - make addrconf per namespace
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (34 preceding siblings ...)
2007-12-03 16:17 ` [patch 35/38][IPV6] addrconf - Add a network namespace parameter to addrconf_forward_change Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 37/38][IPV6] ndisc - dynamically allocate default neigh_parms for ndisc Daniel Lezcano
2007-12-03 16:17 ` [patch 38/38][IPV6] ndisc - make ndisc handle multiple network namespaces Daniel Lezcano
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: addrconf-truly-per-namespace.patch --]
[-- Type: text/plain, Size: 14269 bytes --]
All the infrastructure to propagate the network namespace
information is ready. Make use of it.
There is a special case here between the initial network namespace
and the other namespaces:
* When ipv6 is initialized at boot time (aka in the init_net), it
registers to the notifier callback. So addrconf_notify will be called
as many time as there are network devices setup on the system and the
function will add ipv6 addresses to the network devices. But the first
device which needs to have its ipv6 address setup is the loopback,
unfortunatly this is not the case. So the loopback address is setup
manually in the ipv6 init function.
* With the network namespace, this ordering problem does not appears
because notifier is already setup and active, so as soon as we register
the loopback the ipv6 address is setup and it will be the first device.
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
---
net/ipv6/addrconf.c | 175 ++++++++++++++++++++++++----------------------------
1 file changed, 81 insertions(+), 94 deletions(-)
Index: linux-2.6-netns/net/ipv6/addrconf.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/addrconf.c
+++ linux-2.6-netns/net/ipv6/addrconf.c
@@ -726,9 +726,9 @@ static void ipv6_del_addr(struct inet6_i
if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) {
struct in6_addr prefix;
struct rt6_info *rt;
-
+ struct net *net = ifp->idev->dev->nd_net;
ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len);
- rt = rt6_lookup(&init_net, &prefix, NULL, ifp->idev->dev->ifindex, 1);
+ rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1);
if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
if (onlink == 0) {
@@ -880,6 +880,7 @@ int ipv6_dev_get_saddr(struct net_device
{
struct ipv6_saddr_score hiscore;
struct inet6_ifaddr *ifa_result = NULL;
+ struct net *net = daddr_dev->nd_net;
int daddr_type = __ipv6_addr_type(daddr);
int daddr_scope = __ipv6_addr_src_scope(daddr_type);
int daddr_ifindex = daddr_dev ? daddr_dev->ifindex : 0;
@@ -891,7 +892,7 @@ int ipv6_dev_get_saddr(struct net_device
read_lock(&dev_base_lock);
rcu_read_lock();
- for_each_netdev(&init_net, dev) {
+ for_each_netdev(net, dev) {
struct inet6_dev *idev;
struct inet6_ifaddr *ifa;
@@ -1532,7 +1533,7 @@ addrconf_prefix_route(struct in6_addr *p
.fc_flags = RTF_UP | flags,
.fc_nlinfo.pid = 0,
.fc_nlinfo.nlh = NULL,
- .fc_nlinfo.net = &init_net,
+ .fc_nlinfo.net = dev->nd_net,
};
ipv6_addr_copy(&cfg.fc_dst, pfx);
@@ -1561,7 +1562,7 @@ static void addrconf_add_mroute(struct n
.fc_flags = RTF_UP,
.fc_nlinfo.pid = 0,
.fc_nlinfo.nlh = NULL,
- .fc_nlinfo.net = &init_net,
+ .fc_nlinfo.net = dev->nd_net,
};
ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0);
@@ -1580,7 +1581,7 @@ static void sit_route_add(struct net_dev
.fc_flags = RTF_UP | RTF_NONEXTHOP,
.fc_nlinfo.pid = 0,
.fc_nlinfo.nlh = NULL,
- .fc_nlinfo.net = &init_net,
+ .fc_nlinfo.net = dev->nd_net,
};
/* prefix length - 96 bits "::d.d.d.d" */
@@ -1681,7 +1682,7 @@ void addrconf_prefix_rcv(struct net_devi
if (pinfo->onlink) {
struct rt6_info *rt;
- rt = rt6_lookup(&init_net, &pinfo->prefix, NULL, dev->ifindex, 1);
+ rt = rt6_lookup(dev->nd_net, &pinfo->prefix, NULL, dev->ifindex, 1);
if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
if (rt->rt6i_flags&RTF_EXPIRES) {
@@ -2044,6 +2045,7 @@ static void sit_add_v4_addrs(struct inet
struct inet6_ifaddr * ifp;
struct in6_addr addr;
struct net_device *dev;
+ struct net *net = idev->dev->nd_net;
int scope;
ASSERT_RTNL();
@@ -2070,7 +2072,7 @@ static void sit_add_v4_addrs(struct inet
return;
}
- for_each_netdev(&init_net, dev) {
+ for_each_netdev(net, dev) {
struct in_device * in_dev = __in_dev_get_rtnl(dev);
if (in_dev && (dev->flags & IFF_UP)) {
struct in_ifaddr * ifa;
@@ -2223,15 +2225,16 @@ ipv6_inherit_linklocal(struct inet6_dev
static void ip6_tnl_add_linklocal(struct inet6_dev *idev)
{
struct net_device *link_dev;
+ struct net *net = idev->dev->nd_net;
/* first try to inherit the link-local address from the link device */
if (idev->dev->iflink &&
- (link_dev = __dev_get_by_index(&init_net, idev->dev->iflink))) {
+ (link_dev = __dev_get_by_index(net, idev->dev->iflink))) {
if (!ipv6_inherit_linklocal(idev, link_dev))
return;
}
/* then try to inherit it from any device */
- for_each_netdev(&init_net, link_dev) {
+ for_each_netdev(net, link_dev) {
if (!ipv6_inherit_linklocal(idev, link_dev))
return;
}
@@ -2264,9 +2267,6 @@ static int addrconf_notify(struct notifi
int run_pending = 0;
int err;
- if (dev->nd_net != &init_net)
- return NOTIFY_DONE;
-
switch(event) {
case NETDEV_REGISTER:
if (!idev && dev->mtu >= IPV6_MIN_MTU) {
@@ -3023,9 +3023,6 @@ inet6_rtm_deladdr(struct sk_buff *skb, s
struct in6_addr *pfx;
int err;
- if (net != &init_net)
- return -EINVAL;
-
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
if (err < 0)
return err;
@@ -3088,9 +3085,6 @@ inet6_rtm_newaddr(struct sk_buff *skb, s
u8 ifa_flags;
int err;
- if (net != &init_net)
- return -EINVAL;
-
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
if (err < 0)
return err;
@@ -3291,12 +3285,13 @@ static int inet6_dump_addr(struct sk_buf
struct inet6_ifaddr *ifa;
struct ifmcaddr6 *ifmca;
struct ifacaddr6 *ifaca;
+ struct net *net = skb->sk->sk_net;
s_idx = cb->args[0];
s_ip_idx = ip_idx = cb->args[1];
idx = 0;
- for_each_netdev(&init_net, dev) {
+ for_each_netdev(net, dev) {
if (idx < s_idx)
goto cont;
if (idx > s_idx)
@@ -3365,35 +3360,23 @@ done:
static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
{
- struct net *net = skb->sk->sk_net;
enum addr_type_t type = UNICAST_ADDR;
- if (net != &init_net)
- return 0;
-
return inet6_dump_addr(skb, cb, type);
}
static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
{
- struct net *net = skb->sk->sk_net;
enum addr_type_t type = MULTICAST_ADDR;
- if (net != &init_net)
- return 0;
-
return inet6_dump_addr(skb, cb, type);
}
static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
{
- struct net *net = skb->sk->sk_net;
enum addr_type_t type = ANYCAST_ADDR;
- if (net != &init_net)
- return 0;
-
return inet6_dump_addr(skb, cb, type);
}
@@ -3409,9 +3392,6 @@ static int inet6_rtm_getaddr(struct sk_b
struct sk_buff *skb;
int err;
- if (net != &init_net)
- return -EINVAL;
-
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
if (err < 0)
goto errout;
@@ -3424,7 +3404,7 @@ static int inet6_rtm_getaddr(struct sk_b
ifm = nlmsg_data(nlh);
if (ifm->ifa_index)
- dev = __dev_get_by_index(&init_net, ifm->ifa_index);
+ dev = __dev_get_by_index(net, ifm->ifa_index);
if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) {
err = -EADDRNOTAVAIL;
@@ -3444,7 +3424,7 @@ static int inet6_rtm_getaddr(struct sk_b
kfree_skb(skb);
goto errout_ifa;
}
- err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
+ err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
errout_ifa:
in6_ifa_put(ifa);
errout:
@@ -3454,6 +3434,7 @@ errout:
static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
{
struct sk_buff *skb;
+ struct net *net = ifa->idev->dev->nd_net;
int err = -ENOBUFS;
skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
@@ -3467,10 +3448,10 @@ static void inet6_ifa_notify(int event,
kfree_skb(skb);
goto errout;
}
- err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
+ err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
errout:
if (err < 0)
- rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err);
+ rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err);
}
static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
@@ -3635,12 +3616,9 @@ static int inet6_dump_ifinfo(struct sk_b
struct net_device *dev;
struct inet6_dev *idev;
- if (net != &init_net)
- return 0;
-
read_lock(&dev_base_lock);
idx = 0;
- for_each_netdev(&init_net, dev) {
+ for_each_netdev(net, dev) {
if (idx < s_idx)
goto cont;
if ((idev = in6_dev_get(dev)) == NULL)
@@ -3662,6 +3640,7 @@ cont:
void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
{
struct sk_buff *skb;
+ struct net *net = idev->dev->nd_net;
int err = -ENOBUFS;
skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC);
@@ -3675,10 +3654,10 @@ void inet6_ifinfo_notify(int event, stru
kfree_skb(skb);
goto errout;
}
- err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
+ err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
errout:
if (err < 0)
- rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err);
+ rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err);
}
static inline size_t inet6_prefix_nlmsg_size(void)
@@ -3731,6 +3710,7 @@ static void inet6_prefix_notify(int even
struct prefix_info *pinfo)
{
struct sk_buff *skb;
+ struct net *net = idev->dev->nd_net;
int err = -ENOBUFS;
skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC);
@@ -3744,10 +3724,10 @@ static void inet6_prefix_notify(int even
kfree_skb(skb);
goto errout;
}
- err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
+ err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
errout:
if (err < 0)
- rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_PREFIX, err);
+ rtnl_set_sk_err(net, RTNLGRP_IPV6_PREFIX, err);
}
static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
@@ -4234,12 +4214,41 @@ EXPORT_SYMBOL(unregister_inet6addr_notif
static int addrconf_net_init(struct net *net)
{
- return 0;
+ int err = 0;
+
+ net->ip6_null_entry->u.dst.dev = net->loopback_dev;
+ net->ip6_null_entry->rt6i_idev = in6_dev_get(net->loopback_dev);
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+ net->ip6_prohibit_entry->u.dst.dev = net->loopback_dev;
+ net->ip6_prohibit_entry->rt6i_idev = in6_dev_get(net->loopback_dev);
+ net->ip6_blk_hole_entry->u.dst.dev = net->loopback_dev;
+ net->ip6_blk_hole_entry->rt6i_idev = in6_dev_get(net->loopback_dev);
+#endif
+ return err;
}
static void addrconf_net_exit(struct net *net)
{
- ;
+ struct net_device *dev;
+
+ /*
+ * Remove loopback references from default routing entries
+ */
+ in6_dev_put(net->ip6_null_entry->rt6i_idev);
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+ in6_dev_put(net->ip6_prohibit_entry->rt6i_idev);
+ in6_dev_put(net->ip6_blk_hole_entry->rt6i_idev);
+#endif
+
+ rtnl_lock();
+ /* clean dev list */
+ for_each_netdev(net, dev) {
+ if (__in6_dev_get(dev) == NULL)
+ continue;
+ addrconf_ifdown(dev, 1);
+ }
+ addrconf_ifdown(net->loopback_dev, 2);
+ rtnl_unlock();
}
static struct pernet_operations addrconf_net_ops = {
@@ -4261,40 +4270,31 @@ int __init addrconf_init(void)
return err;
}
- /* The addrconf netdev notifier requires that loopback_dev
- * has it's ipv6 private information allocated and setup
- * before it can bring up and give link-local addresses
- * to other devices which are up.
- *
- * Unfortunately, loopback_dev is not necessarily the first
- * entry in the global dev_base list of net devices. In fact,
- * it is likely to be the very last entry on that list.
- * So this causes the notifier registry below to try and
- * give link-local addresses to all devices besides loopback_dev
- * first, then loopback_dev, which cases all the non-loopback_dev
- * devices to fail to get a link-local address.
- *
- * So, as a temporary fix, allocate the ipv6 structure for
- * loopback_dev first by hand.
- * Longer term, all of the dependencies ipv6 has upon the loopback
- * device and it being up should be removed.
- */
- rtnl_lock();
- if (!ipv6_add_dev(init_net.loopback_dev))
- err = -ENOMEM;
- rtnl_unlock();
- if (err)
+ /* The addrconf netdev notifier requires that loopback_dev
+ * has it's ipv6 private information allocated and setup
+ * before it can bring up and give link-local addresses
+ * to other devices which are up.
+ *
+ * Unfortunately, loopback_dev is not necessarily the first
+ * entry in the global dev_base list of net devices. In fact,
+ * it is likely to be the very last entry on that list.
+ * So this causes the notifier registry below to try and
+ * give link-local addresses to all devices besides loopback_dev
+ * first, then loopback_dev, which cases all the non-loopback_dev
+ * devices to fail to get a link-local address.
+ *
+ * So, as a temporary fix, allocate the ipv6 structure for
+ * loopback_dev first by hand.
+ * Longer term, all of the dependencies ipv6 has upon the loopback
+ * device and it being up should be removed.
+ */
+ rtnl_lock();
+ if (!ipv6_add_dev(init_net.loopback_dev))
+ err = -ENOMEM;
+ rtnl_unlock();
+ if (err)
return err;
- init_net.ip6_null_entry->u.dst.dev = init_net.loopback_dev;
- init_net.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
-#ifdef CONFIG_IPV6_MULTIPLE_TABLES
- init_net.ip6_prohibit_entry->u.dst.dev = init_net.loopback_dev;
- init_net.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
- init_net.ip6_blk_hole_entry->u.dst.dev = init_net.loopback_dev;
- init_net.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
-#endif
-
err = register_pernet_device(&addrconf_net_ops);
if (err)
return err;
@@ -4332,7 +4332,6 @@ errout:
void __exit addrconf_cleanup(void)
{
- struct net_device *dev;
struct inet6_ifaddr *ifa;
int i;
@@ -4346,20 +4345,8 @@ void __exit addrconf_cleanup(void)
rtnl_lock();
/*
- * clean dev list.
- */
-
- for_each_netdev(&init_net, dev) {
- if (__in6_dev_get(dev) == NULL)
- continue;
- addrconf_ifdown(dev, 1);
- }
- addrconf_ifdown(init_net.loopback_dev, 2);
-
- /*
* Check hash table.
*/
-
write_lock_bh(&addrconf_hash_lock);
for (i=0; i < IN6_ADDR_HSIZE; i++) {
for (ifa=inet6_addr_lst[i]; ifa; ) {
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 37/38][IPV6] ndisc - dynamically allocate default neigh_parms for ndisc
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (35 preceding siblings ...)
2007-12-03 16:17 ` [patch 36/38][IPV6] addrconf - make addrconf per namespace Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
2007-12-03 16:17 ` [patch 38/38][IPV6] ndisc - make ndisc handle multiple network namespaces Daniel Lezcano
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: IPv6-ndisc-dynamic-allocation-of-neigh_parms.patch --]
[-- Type: text/plain, Size: 2624 bytes --]
This patch dynamically allocates default neigh_parms for IPv6 network
discovery and store them in struct net. That provides the basic changes
needed to support ndisc for multiple network namespaces.
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
---
include/net/net_namespace.h | 3 +++
net/ipv6/ndisc.c | 38 +++++++++++++++++++++++++++++++-------
2 files changed, 34 insertions(+), 7 deletions(-)
Index: linux-2.6-netns/include/net/net_namespace.h
===================================================================
--- linux-2.6-netns.orig/include/net/net_namespace.h
+++ linux-2.6-netns/include/net/net_namespace.h
@@ -83,6 +83,9 @@ struct net {
unsigned int fib_info_hash_size;
unsigned int fib_info_cnt;
struct hlist_head *fib_info_devhash;
+
+ /* IPv6 ndisc.c */
+ struct neigh_parms *ndisc_neigh_parms_default;
};
#ifdef CONFIG_NET
Index: linux-2.6-netns/net/ipv6/ndisc.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ndisc.c
+++ linux-2.6-netns/net/ipv6/ndisc.c
@@ -1764,23 +1764,47 @@ int __init ndisc_init(struct net_proto_f
neigh_table_init(&nd_tbl);
+ init_net.ndisc_neigh_parms_default =
+ neigh_parms_alloc_default(&nd_tbl, &init_net);
+ if (!init_net.ndisc_neigh_parms_default) {
+ err = -ENOMEM;
+ goto out_neigh_parms;
+ }
+
#ifdef CONFIG_SYSCTL
- neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH,
- "ipv6",
- &ndisc_ifinfo_sysctl_change,
- &ndisc_ifinfo_sysctl_strategy);
+ if ((err = neigh_sysctl_register(NULL,
+ init_net.ndisc_neigh_parms_default,
+ NET_IPV6, NET_IPV6_NEIGH,
+ "ipv6",
+ &ndisc_ifinfo_sysctl_change,
+ &ndisc_ifinfo_sysctl_strategy)))
+ goto out_sysctl;
#endif
-
register_netdevice_notifier(&ndisc_netdev_notifier);
- return 0;
+out:
+ return err;
+#ifdef CONFIG_SYSCTL
+out_sysctl:
+ neigh_parms_release(&nd_tbl, init_net.ndisc_neigh_parms_default);
+#endif
+out_neigh_parms:
+ sock_release(ndisc_socket);
+ goto out;
}
void ndisc_cleanup(void)
{
+ struct neigh_parms *parms = init_net.ndisc_neigh_parms_default;
+
unregister_netdevice_notifier(&ndisc_netdev_notifier);
+
+ if (parms) {
#ifdef CONFIG_SYSCTL
- neigh_sysctl_unregister(&nd_tbl.parms);
+ neigh_sysctl_unregister(parms);
#endif
+ neigh_parms_release(&nd_tbl, parms);
+ init_net.ndisc_neigh_parms_default = NULL;
+ }
neigh_table_clear(&nd_tbl);
sock_release(ndisc_socket);
ndisc_socket = NULL; /* For safety. */
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* [patch 38/38][IPV6] ndisc - make ndisc handle multiple network namespaces
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
` (36 preceding siblings ...)
2007-12-03 16:17 ` [patch 37/38][IPV6] ndisc - dynamically allocate default neigh_parms for ndisc Daniel Lezcano
@ 2007-12-03 16:17 ` Daniel Lezcano
37 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-03 16:17 UTC (permalink / raw)
To: den-3ImXcnM4P+0
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, xemul-GEFAQzZX7r8dnm+yROfE0A
[-- Attachment #1: IPv6-ndisc-make-ndisc-handle-multiple-network-namespace.patch --]
[-- Type: text/plain, Size: 4892 bytes --]
Make ndisc handle multiple network namespaces:
Remove references to init_net, add network namespace parameters and add
pernet_operations for ndisc
Signed-off-by: Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org>
---
net/ipv6/ndisc.c | 90 +++++++++++++++++++++++++++++++++----------------------
1 file changed, 55 insertions(+), 35 deletions(-)
Index: linux-2.6-netns/net/ipv6/ndisc.c
===================================================================
--- linux-2.6-netns.orig/net/ipv6/ndisc.c
+++ linux-2.6-netns/net/ipv6/ndisc.c
@@ -442,12 +442,12 @@ static void pndisc_destructor(struct pne
* Send a Neighbour Advertisement
*/
-static inline void ndisc_flow_init(struct flowi *fl, u8 type,
+static inline void ndisc_flow_init(struct net *net, struct flowi *fl, u8 type,
struct in6_addr *saddr, struct in6_addr *daddr,
int oif)
{
memset(fl, 0, sizeof(*fl));
- fl->fl_net = &init_net;
+ fl->fl_net = net;
ipv6_addr_copy(&fl->fl6_src, saddr);
ipv6_addr_copy(&fl->fl6_dst, daddr);
fl->proto = IPPROTO_ICMPV6;
@@ -475,7 +475,7 @@ static void __ndisc_send(struct net_devi
type = icmp6h->icmp6_type;
- ndisc_flow_init(&fl, type, saddr, daddr,
+ ndisc_flow_init(dev->nd_net, &fl, type, saddr, daddr,
dev->ifindex);
dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
@@ -791,7 +791,7 @@ static void ndisc_recv_ns(struct sk_buff
if (ipv6_chk_acast_addr(dev, &msg->target) ||
(idev->cnf.forwarding &&
(ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) &&
- (pneigh = pneigh_lookup(&nd_tbl, &init_net,
+ (pneigh = pneigh_lookup(&nd_tbl, dev->nd_net,
&msg->target, dev, 0)) != NULL)) {
if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
skb->pkt_type != PACKET_HOST &&
@@ -932,7 +932,7 @@ static void ndisc_recv_na(struct sk_buff
*/
if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp &&
- pneigh_lookup(&nd_tbl, &init_net, &msg->target, dev, 0)) {
+ pneigh_lookup(&nd_tbl, dev->nd_net, &msg->target, dev, 0)) {
/* XXX: idev->cnf.prixy_ndp */
goto out;
}
@@ -1440,8 +1440,8 @@ void ndisc_send_redirect(struct sk_buff
return;
}
- ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &ipv6_hdr(skb)->saddr,
- dev->ifindex);
+ ndisc_flow_init(dev->nd_net, &fl, NDISC_REDIRECT, &saddr_buf,
+ &ipv6_hdr(skb)->saddr, dev->ifindex);
dst = ip6_route_output(NULL, &fl);
if (dst == NULL)
@@ -1616,9 +1616,6 @@ static int ndisc_netdev_event(struct not
struct net_device *dev = ptr;
struct net *net = dev->nd_net;
- if (dev->nd_net != &init_net)
- return NOTIFY_DONE;
-
switch (event) {
case NETDEV_CHANGEADDR:
neigh_changeaddr(&nd_tbl, dev);
@@ -1735,6 +1732,52 @@ static int ndisc_ifinfo_sysctl_strategy(
#endif
+static int ndisc_net_init(struct net *net)
+{
+ int err = 0;
+
+ net->ndisc_neigh_parms_default =
+ neigh_parms_alloc_default(&nd_tbl, net);
+ if (!net->ndisc_neigh_parms_default) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+#ifdef CONFIG_SYSCTL
+ if ((err = neigh_sysctl_register(NULL,
+ net->ndisc_neigh_parms_default,
+ NET_IPV6, NET_IPV6_NEIGH,
+ "ipv6",
+ &ndisc_ifinfo_sysctl_change,
+ &ndisc_ifinfo_sysctl_strategy)))
+ goto out_sysctl;
+#endif
+out:
+ return err;
+#ifdef CONFIG_SYSCTL
+out_sysctl:
+ neigh_parms_release(&nd_tbl, net->ndisc_neigh_parms_default);
+ goto out;
+#endif
+}
+
+static void ndisc_net_exit(struct net *net)
+{
+ struct neigh_parms *parms = net->ndisc_neigh_parms_default;
+ if (parms) {
+#ifdef CONFIG_SYSCTL
+ neigh_sysctl_unregister(parms);
+#endif
+ neigh_parms_release(&nd_tbl, parms);
+ net->ndisc_neigh_parms_default = NULL;
+ }
+}
+
+static struct pernet_operations ndisc_net_ops = {
+ .init = ndisc_net_init,
+ .exit = ndisc_net_exit,
+};
+
int __init ndisc_init(struct net_proto_family *ops)
{
struct ipv6_pinfo *np;
@@ -1764,32 +1807,9 @@ int __init ndisc_init(struct net_proto_f
neigh_table_init(&nd_tbl);
- init_net.ndisc_neigh_parms_default =
- neigh_parms_alloc_default(&nd_tbl, &init_net);
- if (!init_net.ndisc_neigh_parms_default) {
- err = -ENOMEM;
- goto out_neigh_parms;
- }
-
-#ifdef CONFIG_SYSCTL
- if ((err = neigh_sysctl_register(NULL,
- init_net.ndisc_neigh_parms_default,
- NET_IPV6, NET_IPV6_NEIGH,
- "ipv6",
- &ndisc_ifinfo_sysctl_change,
- &ndisc_ifinfo_sysctl_strategy)))
- goto out_sysctl;
-#endif
+ register_pernet_subsys(&ndisc_net_ops);
register_netdevice_notifier(&ndisc_netdev_notifier);
-out:
- return err;
-#ifdef CONFIG_SYSCTL
-out_sysctl:
- neigh_parms_release(&nd_tbl, init_net.ndisc_neigh_parms_default);
-#endif
-out_neigh_parms:
- sock_release(ndisc_socket);
- goto out;
+ return 0;
}
void ndisc_cleanup(void)
--
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [patch 12/38][IPV6] ip6_fib - move the fib table to the network namespace
[not found] ` <20071203162453.368428873-WECHFHqYCmGD/CxQmPlnQ0FT0OZdM7KVQQ4Iyu8u01E@public.gmane.org>
@ 2007-12-04 19:28 ` Brian Haley
[not found] ` <4755AA47.3000501-VXdhtT5mjnY@public.gmane.org>
0 siblings, 1 reply; 41+ messages in thread
From: Brian Haley @ 2007-12-04 19:28 UTC (permalink / raw)
To: Daniel Lezcano
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
xemul-GEFAQzZX7r8dnm+yROfE0A, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
den-3ImXcnM4P+0
Hi Daniel,
Daniel Lezcano wrote:
> Move the global definition of the fib table to the network namespace
> structure and make their access to the initial network namespace.
....
> -void __init fib6_init(void)
> +static int fib6_net_init(struct net *net)
> {
> - fib6_node_kmem = kmem_cache_create("fib6_nodes",
> - sizeof(struct fib6_node),
> - 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
> - NULL);
> + int ret;
>
> - fib_table_hash = kzalloc(sizeof(*fib_table_hash)*FIB_TABLE_HASHSZ, GFP_KERNEL);
> - if (!fib_table_hash)
> - panic("IPV6: Failed to allocate fib_table_hash.\n");
> -
> - fib6_main_tbl = kzalloc(sizeof(*fib6_main_tbl), GFP_KERNEL);
> - if (!fib6_main_tbl)
> - panic("IPV6: Failed to allocate fib6_main_tbl.\n");
> -
> - fib6_main_tbl->tb6_id = RT6_TABLE_MAIN;
> - fib6_main_tbl->tb6_root.leaf = &ip6_null_entry;
> - fib6_main_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
> + if (net != &init_net)
> + return -EPERM;
> +
> + ret = -ENOMEM;
> + net->fib_table_hash = kzalloc(sizeof(*net->fib_table_hash)*FIB_TABLE_HASHSZ,
> + GFP_KERNEL);
> + if (!net->fib_table_hash)
> + goto out;
So originally, the fib_table_hash was global with no allocation
necessary. Then in patch 11 you changed it to be dynamic and panic() on
failure. Now it just gracefully returns. Do you really want to do that
for the init_net namespace? Won't the next routine that tries to access
this NULL pointer oops? Same for fib6_main_table, fib6_local_table,
fib6_stats, etc. Or did I miss where the callers error-out on an ENOMEM?
-Brian
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [patch 12/38][IPV6] ip6_fib - move the fib table to the network namespace
[not found] ` <4755AA47.3000501-VXdhtT5mjnY@public.gmane.org>
@ 2007-12-05 10:05 ` Daniel Lezcano
0 siblings, 0 replies; 41+ messages in thread
From: Daniel Lezcano @ 2007-12-05 10:05 UTC (permalink / raw)
To: Brian Haley
Cc: containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
xemul-GEFAQzZX7r8dnm+yROfE0A, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
den-3ImXcnM4P+0
Brian Haley wrote:
> Hi Daniel,
>
> Daniel Lezcano wrote:
>> Move the global definition of the fib table to the network namespace
>> structure and make their access to the initial network namespace.
> ....
>> -void __init fib6_init(void)
>> +static int fib6_net_init(struct net *net)
>> {
>> - fib6_node_kmem = kmem_cache_create("fib6_nodes",
>> - sizeof(struct fib6_node),
>> - 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
>> - NULL);
>> + int ret;
>>
>> - fib_table_hash =
>> kzalloc(sizeof(*fib_table_hash)*FIB_TABLE_HASHSZ, GFP_KERNEL);
>> - if (!fib_table_hash)
>> - panic("IPV6: Failed to allocate fib_table_hash.\n");
>> -
>> - fib6_main_tbl = kzalloc(sizeof(*fib6_main_tbl), GFP_KERNEL);
>> - if (!fib6_main_tbl)
>> - panic("IPV6: Failed to allocate fib6_main_tbl.\n");
>> -
>> - fib6_main_tbl->tb6_id = RT6_TABLE_MAIN;
>> - fib6_main_tbl->tb6_root.leaf = &ip6_null_entry;
>> - fib6_main_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT |
>> RTN_RTINFO;
>> + if (net != &init_net)
>> + return -EPERM;
>> +
>> + ret = -ENOMEM;
>> + net->fib_table_hash =
>> kzalloc(sizeof(*net->fib_table_hash)*FIB_TABLE_HASHSZ,
>> + GFP_KERNEL);
>> + if (!net->fib_table_hash)
>> + goto out;
>
> So originally, the fib_table_hash was global with no allocation
> necessary. Then in patch 11 you changed it to be dynamic and panic() on
> failure. Now it just gracefully returns. Do you really want to do that
> for the init_net namespace? Won't the next routine that tries to access
> this NULL pointer oops? Same for fib6_main_table, fib6_local_table,
> fib6_stats, etc. Or did I miss where the callers error-out on an ENOMEM?
Yes, you are right, this is not consistent and we should not panic
neither ignore the error. I should have modified the ip6_route_init and
returned an error in case of register_pernet_subsys failure. So the ipv6
initialization can fails safely.
I will post some modifications around that for net-2.6.25 for netdev@.
Thanks for catching that.
-- Daniel
^ permalink raw reply [flat|nested] 41+ messages in thread
end of thread, other threads:[~2007-12-05 10:05 UTC | newest]
Thread overview: 41+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-03 16:16 [patch 00/38][IPV6] ipv6 per network namespace Daniel Lezcano
2007-12-03 16:16 ` [patch 01/38][IPV6] net-2.6.25 - make netns cleanup to run in a separate queue Daniel Lezcano
2007-12-03 16:16 ` [patch 02/38][IPV6] Makefile - Activate netns configuration when sysctl is off Daniel Lezcano
2007-12-03 16:16 ` [patch 03/38][IPV6] inet6_addr - isolate inet6 addresses from proc file Daniel Lezcano
2007-12-03 16:16 ` [patch 04/38][IPV6] inet6_addr - check ipv6 address per namespace Daniel Lezcano
2007-12-03 16:16 ` [patch 05/38][IPV6] inet6_addr - make use of the new ipv6_chk_addr function Daniel Lezcano
2007-12-03 16:16 ` [patch 06/38][IPV6] inet6_addr - ipv6_chk_same_addr namespace aware Daniel Lezcano
2007-12-03 16:16 ` [patch 07/38][IPV6] inet6_addr - ipv6_get_ifaddr " Daniel Lezcano
2007-12-03 16:16 ` [patch 08/38][IPV6] inet6_addr - remove ipv6_get_ifaddr wrapper Daniel Lezcano
2007-12-03 16:16 ` [patch 09/38][IPV6] inet6_addr - make ipv6_chk_home_addr namespace aware Daniel Lezcano
2007-12-03 16:16 ` [patch 10/38][IPV6] ip6_fib - make mindless changes Daniel Lezcano
2007-12-03 16:16 ` [patch 11/38][IPV6] ip6_fib - dynamically allocate fib tables Daniel Lezcano
2007-12-03 16:16 ` [patch 12/38][IPV6] ip6_fib - move the fib table to the network namespace Daniel Lezcano
[not found] ` <20071203162453.368428873-WECHFHqYCmGD/CxQmPlnQ0FT0OZdM7KVQQ4Iyu8u01E@public.gmane.org>
2007-12-04 19:28 ` Brian Haley
[not found] ` <4755AA47.3000501-VXdhtT5mjnY@public.gmane.org>
2007-12-05 10:05 ` Daniel Lezcano
2007-12-03 16:16 ` [patch 13/38][IPV6] ip6_fib - make the fib table per " Daniel Lezcano
2007-12-03 16:16 ` [patch 14/38][IPV6] ip6_fib - make fib6_clean_all per namespace Daniel Lezcano
2007-12-03 16:16 ` [patch 15/38][IPV6] ip6_fib - pass the network namespace parameter to timer callback Daniel Lezcano
2007-12-03 16:16 ` [patch 16/38][IPV6] ip6_fib - make ip6 fib gc timer mindless changes Daniel Lezcano
2007-12-03 16:16 ` [patch 17/38][IPV6] ip6_fib - dynamically allocate the ip6 fib gc timer Daniel Lezcano
2007-12-03 16:16 ` [patch 18/38][IPV6] ip6_fib - move the ip6 fib gc timer to the network namespace Daniel Lezcano
2007-12-03 16:16 ` [patch 19/38][IPV6] ip6_fib - make the ip6 fib gc timer handle several network namespaces Daniel Lezcano
2007-12-03 16:16 ` [patch 20/38][IPV6] fib6_rules - make fib_rules per network namespace Daniel Lezcano
2007-12-03 16:16 ` [patch 21/38][IPV6] rt6_stats - make mindless changes for rt6_stats Daniel Lezcano
2007-12-03 16:16 ` [patch 22/38][IPV6] rt6_stats - dynamically allocate the rt6_stats Daniel Lezcano
2007-12-03 16:16 ` [patch 23/38][IPV6] rt6_stats - make the rt6_stats relative to the namespace Daniel Lezcano
2007-12-03 16:17 ` [patch 24/38][IPV6] rt6_stats - make rt6_stats per namespace Daniel Lezcano
2007-12-03 16:17 ` [patch 25/38][IPV6] route6 - create route6 proc files for the namespace Daniel Lezcano
2007-12-03 16:17 ` [patch 26/38][IPV6] route6 - Pass the network namespace parameter to rt6_lookup Daniel Lezcano
2007-12-03 16:17 ` [patch 27/38][IPV6] route6 - Make proc entry /proc/net/rt6_stats per namespace Daniel Lezcano
2007-12-03 16:17 ` [patch 28/38][IPV6] route6 - Pass network namespace to rt6_add_route_info and rt6_get_route_info Daniel Lezcano
2007-12-03 16:17 ` [patch 29/38][IPV6] route6 - Pass the network namespace parameter to rt6_purge_dflt_routers Daniel Lezcano
2007-12-03 16:17 ` [patch 30/38][IPV6] route6 - make route6 per namespace Daniel Lezcano
2007-12-03 16:17 ` [patch 31/38][IPV6] rt6_info - make rt6_info accessed as a pointer Daniel Lezcano
2007-12-03 16:17 ` [patch 32/38][IPV6] rt6_info - dynamically allocate rt6_info Daniel Lezcano
2007-12-03 16:17 ` [patch 33/38][IPV6] rt6_info - move rt6_info structure inside the namespace Daniel Lezcano
2007-12-03 16:17 ` [patch 34/38][IPV6] addrconf - Pass the proper network namespace parameters to addrconf Daniel Lezcano
2007-12-03 16:17 ` [patch 35/38][IPV6] addrconf - Add a network namespace parameter to addrconf_forward_change Daniel Lezcano
2007-12-03 16:17 ` [patch 36/38][IPV6] addrconf - make addrconf per namespace Daniel Lezcano
2007-12-03 16:17 ` [patch 37/38][IPV6] ndisc - dynamically allocate default neigh_parms for ndisc Daniel Lezcano
2007-12-03 16:17 ` [patch 38/38][IPV6] ndisc - make ndisc handle multiple network namespaces Daniel Lezcano
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.