netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/53] xfrm: initialise xfrm_policy_gc_work statically
@ 2008-11-25 17:26 Alexey Dobriyan
  2008-11-25 17:26 ` [PATCH 02/53] netns xfrm: add netns boilerplate Alexey Dobriyan
  2008-11-26  1:14 ` [PATCH 01/53] xfrm: initialise xfrm_policy_gc_work statically David Miller
  0 siblings, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/xfrm/xfrm_policy.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 1785488..ea3456d 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -55,7 +55,6 @@ static struct xfrm_policy_afinfo *xfrm_policy_afinfo[NPROTO];
 
 static struct kmem_cache *xfrm_dst_cache __read_mostly;
 
-static struct work_struct xfrm_policy_gc_work;
 static HLIST_HEAD(xfrm_policy_gc_list);
 static DEFINE_SPINLOCK(xfrm_policy_gc_lock);
 
@@ -296,6 +295,7 @@ static void xfrm_policy_gc_task(struct work_struct *work)
 	hlist_for_each_entry_safe(policy, entry, tmp, &gc_list, bydst)
 		xfrm_policy_gc_kill(policy);
 }
+static DECLARE_WORK(xfrm_policy_gc_work, xfrm_policy_gc_task);
 
 /* Rule must be locked. Release descentant resources, announce
  * entry dead. The rule must be unlinked from lists to the moment.
@@ -2425,7 +2425,6 @@ static void __init xfrm_policy_init(void)
 	}
 
 	INIT_LIST_HEAD(&xfrm_policy_all);
-	INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task);
 	register_netdevice_notifier(&xfrm_dev_notifier);
 }
 
-- 
1.5.6.5


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

* [PATCH 02/53] netns xfrm: add netns boilerplate
  2008-11-25 17:26 [PATCH 01/53] xfrm: initialise xfrm_policy_gc_work statically Alexey Dobriyan
@ 2008-11-25 17:26 ` Alexey Dobriyan
  2008-11-25 17:26   ` [PATCH 03/53] netns xfrm: add struct xfrm_state::xs_net Alexey Dobriyan
  2008-11-26  1:14   ` [PATCH 02/53] netns xfrm: add netns boilerplate David Miller
  2008-11-26  1:14 ` [PATCH 01/53] xfrm: initialise xfrm_policy_gc_work statically David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/net_namespace.h |    4 +++
 include/net/netns/xfrm.h    |    7 ++++++
 include/net/xfrm.h          |    3 +-
 net/xfrm/xfrm_policy.c      |   45 ++++++++++++++++++++++++++++++++++++++----
 net/xfrm/xfrm_state.c       |    7 +++++-
 5 files changed, 59 insertions(+), 7 deletions(-)
 create mode 100644 include/net/netns/xfrm.h

diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 3195577..6fc13d9 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -19,6 +19,7 @@
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 #include <net/netns/conntrack.h>
 #endif
+#include <net/netns/xfrm.h>
 
 struct proc_dir_entry;
 struct net_device;
@@ -74,6 +75,9 @@ struct net {
 	struct netns_ct		ct;
 #endif
 #endif
+#ifdef CONFIG_XFRM
+	struct netns_xfrm	xfrm;
+#endif
 	struct net_generic	*gen;
 };
 
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
new file mode 100644
index 0000000..1cb0024
--- /dev/null
+++ b/include/net/netns/xfrm.h
@@ -0,0 +1,7 @@
+#ifndef __NETNS_XFRM_H
+#define __NETNS_XFRM_H
+
+struct netns_xfrm {
+};
+
+#endif
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 45e11b3..9107d6f 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1269,7 +1269,8 @@ struct xfrm6_tunnel {
 
 extern void xfrm_init(void);
 extern void xfrm4_init(void);
-extern void xfrm_state_init(void);
+extern int xfrm_state_init(struct net *net);
+extern void xfrm_state_fini(struct net *net);
 extern void xfrm4_state_init(void);
 #ifdef CONFIG_XFRM
 extern int xfrm6_init(void);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index ea3456d..8e7671b 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2394,12 +2394,13 @@ static int __init xfrm_statistics_init(void)
 }
 #endif
 
-static void __init xfrm_policy_init(void)
+static int __net_init xfrm_policy_init(struct net *net)
 {
 	unsigned int hmask, sz;
 	int dir;
 
-	xfrm_dst_cache = kmem_cache_create("xfrm_dst_cache",
+	if (net_eq(net, &init_net))
+		xfrm_dst_cache = kmem_cache_create("xfrm_dst_cache",
 					   sizeof(struct xfrm_dst),
 					   0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
 					   NULL);
@@ -2425,16 +2426,50 @@ static void __init xfrm_policy_init(void)
 	}
 
 	INIT_LIST_HEAD(&xfrm_policy_all);
-	register_netdevice_notifier(&xfrm_dev_notifier);
+	if (net_eq(net, &init_net))
+		register_netdevice_notifier(&xfrm_dev_notifier);
+	return 0;
+}
+
+static void xfrm_policy_fini(struct net *net)
+{
 }
 
+static int __net_init xfrm_net_init(struct net *net)
+{
+	int rv;
+
+	rv = xfrm_state_init(net);
+	if (rv < 0)
+		goto out_state;
+	rv = xfrm_policy_init(net);
+	if (rv < 0)
+		goto out_policy;
+	return 0;
+
+out_policy:
+	xfrm_state_fini(net);
+out_state:
+	return rv;
+}
+
+static void __net_exit xfrm_net_exit(struct net *net)
+{
+	xfrm_policy_fini(net);
+	xfrm_state_fini(net);
+}
+
+static struct pernet_operations __net_initdata xfrm_net_ops = {
+	.init = xfrm_net_init,
+	.exit = xfrm_net_exit,
+};
+
 void __init xfrm_init(void)
 {
+	register_pernet_subsys(&xfrm_net_ops);
 #ifdef CONFIG_XFRM_STATISTICS
 	xfrm_statistics_init();
 #endif
-	xfrm_state_init();
-	xfrm_policy_init();
 	xfrm_input_init();
 #ifdef CONFIG_XFRM_STATISTICS
 	xfrm_proc_init();
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index cd9d917..268fe3f 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2080,7 +2080,7 @@ error:
 
 EXPORT_SYMBOL(xfrm_init_state);
 
-void __init xfrm_state_init(void)
+int __net_init xfrm_state_init(struct net *net)
 {
 	unsigned int sz;
 
@@ -2094,6 +2094,11 @@ void __init xfrm_state_init(void)
 	xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
 
 	INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task);
+	return 0;
+}
+
+void xfrm_state_fini(struct net *net)
+{
 }
 
 #ifdef CONFIG_AUDITSYSCALL
-- 
1.5.6.5


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

* [PATCH 03/53] netns xfrm: add struct xfrm_state::xs_net
  2008-11-25 17:26 ` [PATCH 02/53] netns xfrm: add netns boilerplate Alexey Dobriyan
@ 2008-11-25 17:26   ` Alexey Dobriyan
  2008-11-25 17:26     ` [PATCH 04/53] netns xfrm: per-netns xfrm_state_all list Alexey Dobriyan
  2008-11-26  1:15     ` [PATCH 03/53] netns xfrm: add struct xfrm_state::xs_net David Miller
  2008-11-26  1:14   ` [PATCH 02/53] netns xfrm: add netns boilerplate David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

To avoid unnecessary complications with passing netns around.

* set once, very early after allocating
* once set, never changes

For a while create every xfrm_state in init_net.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h    |   10 +++++++++-
 net/ipv4/ipcomp.c     |    2 +-
 net/ipv6/ipcomp6.c    |    2 +-
 net/key/af_key.c      |    2 +-
 net/xfrm/xfrm_state.c |    9 +++++----
 net/xfrm/xfrm_user.c  |    4 ++--
 6 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 9107d6f..9da8903 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -130,6 +130,9 @@ struct xfrm_state_walk {
 /* Full description of state of transformer. */
 struct xfrm_state
 {
+#ifdef CONFIG_NET_NS
+	struct net		*xs_net;
+#endif
 	union {
 		struct hlist_node	gclist;
 		struct hlist_node	bydst;
@@ -223,6 +226,11 @@ struct xfrm_state
 	void			*data;
 };
 
+static inline struct net *xs_net(struct xfrm_state *x)
+{
+	return read_pnet(&x->xs_net);
+}
+
 /* xflags - make enum if more show up */
 #define XFRM_TIME_DEFER	1
 
@@ -1296,7 +1304,7 @@ extern void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto);
 extern int xfrm_state_walk(struct xfrm_state_walk *walk,
 			   int (*func)(struct xfrm_state *, int, void*), void *);
 extern void xfrm_state_walk_done(struct xfrm_state_walk *walk);
-extern struct xfrm_state *xfrm_state_alloc(void);
+extern struct xfrm_state *xfrm_state_alloc(struct net *net);
 extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, 
 					  struct flowi *fl, struct xfrm_tmpl *tmpl,
 					  struct xfrm_policy *pol, int *err,
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index ec8264a..0a35f1b 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -49,7 +49,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
 {
 	struct xfrm_state *t;
 
-	t = xfrm_state_alloc();
+	t = xfrm_state_alloc(&init_net);
 	if (t == NULL)
 		goto out;
 
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index d4576a9..c369638 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -76,7 +76,7 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
 {
 	struct xfrm_state *t = NULL;
 
-	t = xfrm_state_alloc();
+	t = xfrm_state_alloc(&init_net);
 	if (!t)
 		goto out;
 
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 5b22e01..bde8aad 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1122,7 +1122,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
 	     (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
 		return ERR_PTR(-EINVAL);
 
-	x = xfrm_state_alloc();
+	x = xfrm_state_alloc(&init_net);
 	if (x == NULL)
 		return ERR_PTR(-ENOBUFS);
 
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 268fe3f..81bde76 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -504,13 +504,14 @@ out:
 
 static void xfrm_replay_timer_handler(unsigned long data);
 
-struct xfrm_state *xfrm_state_alloc(void)
+struct xfrm_state *xfrm_state_alloc(struct net *net)
 {
 	struct xfrm_state *x;
 
 	x = kzalloc(sizeof(struct xfrm_state), GFP_ATOMIC);
 
 	if (x) {
+		write_pnet(&x->xs_net, net);
 		atomic_set(&x->refcnt, 1);
 		atomic_set(&x->tunnel_users, 0);
 		INIT_LIST_HEAD(&x->km.all);
@@ -835,7 +836,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 			error = -EEXIST;
 			goto out;
 		}
-		x = xfrm_state_alloc();
+		x = xfrm_state_alloc(&init_net);
 		if (x == NULL) {
 			error = -ENOMEM;
 			goto out;
@@ -1017,7 +1018,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
 	if (!create)
 		return NULL;
 
-	x = xfrm_state_alloc();
+	x = xfrm_state_alloc(&init_net);
 	if (likely(x)) {
 		switch (family) {
 		case AF_INET:
@@ -1125,7 +1126,7 @@ EXPORT_SYMBOL(xfrm_state_add);
 static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
 {
 	int err = -ENOMEM;
-	struct xfrm_state *x = xfrm_state_alloc();
+	struct xfrm_state *x = xfrm_state_alloc(&init_net);
 	if (!x)
 		goto error;
 
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index ee15d5d..65cdaa5 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -320,7 +320,7 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
 					       struct nlattr **attrs,
 					       int *errp)
 {
-	struct xfrm_state *x = xfrm_state_alloc();
+	struct xfrm_state *x = xfrm_state_alloc(&init_net);
 	int err = -ENOMEM;
 
 	if (!x)
@@ -1663,7 +1663,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
 	struct nlattr *rt = attrs[XFRMA_TMPL];
 
 	struct xfrm_user_acquire *ua = nlmsg_data(nlh);
-	struct xfrm_state *x = xfrm_state_alloc();
+	struct xfrm_state *x = xfrm_state_alloc(&init_net);
 	int err = -ENOMEM;
 
 	if (!x)
-- 
1.5.6.5


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

* [PATCH 04/53] netns xfrm: per-netns xfrm_state_all list
  2008-11-25 17:26   ` [PATCH 03/53] netns xfrm: add struct xfrm_state::xs_net Alexey Dobriyan
@ 2008-11-25 17:26     ` Alexey Dobriyan
  2008-11-25 17:26       ` [PATCH 05/53] netns xfrm: per-netns xfrm_state_bydst hash Alexey Dobriyan
  2008-11-26  1:16       ` [PATCH 04/53] netns xfrm: per-netns xfrm_state_all list David Miller
  2008-11-26  1:15     ` [PATCH 03/53] netns xfrm: add struct xfrm_state::xs_net David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

This is done to get
a) simple "something leaked" check
b) cover possible DoSes when other netns puts many, many xfrm_states
   onto a list.
c) not miss "alien xfrm_state" check in some of list iterators in future.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    3 +++
 net/xfrm/xfrm_state.c    |   14 ++++++++------
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 1cb0024..6ae234a 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -1,7 +1,10 @@
 #ifndef __NETNS_XFRM_H
 #define __NETNS_XFRM_H
 
+#include <linux/list.h>
+
 struct netns_xfrm {
+	struct list_head	state_all;
 };
 
 #endif
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 81bde76..85bb854 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -50,7 +50,6 @@ static DEFINE_SPINLOCK(xfrm_state_lock);
  * Main use is finding SA after policy selected tunnel or transport mode.
  * Also, it can be used by ah/esp icmp error handler to find offending SA.
  */
-static LIST_HEAD(xfrm_state_all);
 static struct hlist_head *xfrm_state_bydst __read_mostly;
 static struct hlist_head *xfrm_state_bysrc __read_mostly;
 static struct hlist_head *xfrm_state_byspi __read_mostly;
@@ -855,7 +854,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 
 		if (km_query(x, tmpl, pol) == 0) {
 			x->km.state = XFRM_STATE_ACQ;
-			list_add(&x->km.all, &xfrm_state_all);
+			list_add(&x->km.all, &init_net.xfrm.state_all);
 			hlist_add_head(&x->bydst, xfrm_state_bydst+h);
 			h = xfrm_src_hash(daddr, saddr, family);
 			hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
@@ -924,7 +923,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
 
 	x->genid = ++xfrm_state_genid;
 
-	list_add(&x->km.all, &xfrm_state_all);
+	list_add(&x->km.all, &init_net.xfrm.state_all);
 
 	h = xfrm_dst_hash(&x->id.daddr, &x->props.saddr,
 			  x->props.reqid, x->props.family);
@@ -1053,7 +1052,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
 		xfrm_state_hold(x);
 		x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
 		add_timer(&x->timer);
-		list_add(&x->km.all, &xfrm_state_all);
+		list_add(&x->km.all, &init_net.xfrm.state_all);
 		hlist_add_head(&x->bydst, xfrm_state_bydst+h);
 		h = xfrm_src_hash(daddr, saddr, family);
 		hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
@@ -1559,10 +1558,10 @@ int xfrm_state_walk(struct xfrm_state_walk *walk,
 
 	spin_lock_bh(&xfrm_state_lock);
 	if (list_empty(&walk->all))
-		x = list_first_entry(&xfrm_state_all, struct xfrm_state_walk, all);
+		x = list_first_entry(&init_net.xfrm.state_all, struct xfrm_state_walk, all);
 	else
 		x = list_entry(&walk->all, struct xfrm_state_walk, all);
-	list_for_each_entry_from(x, &xfrm_state_all, all) {
+	list_for_each_entry_from(x, &init_net.xfrm.state_all, all) {
 		if (x->state == XFRM_STATE_DEAD)
 			continue;
 		state = container_of(x, struct xfrm_state, km);
@@ -2085,6 +2084,8 @@ int __net_init xfrm_state_init(struct net *net)
 {
 	unsigned int sz;
 
+	INIT_LIST_HEAD(&net->xfrm.state_all);
+
 	sz = sizeof(struct hlist_head) * 8;
 
 	xfrm_state_bydst = xfrm_hash_alloc(sz);
@@ -2100,6 +2101,7 @@ int __net_init xfrm_state_init(struct net *net)
 
 void xfrm_state_fini(struct net *net)
 {
+	WARN_ON(!list_empty(&net->xfrm.state_all));
 }
 
 #ifdef CONFIG_AUDITSYSCALL
-- 
1.5.6.5


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

* [PATCH 05/53] netns xfrm: per-netns xfrm_state_bydst hash
  2008-11-25 17:26     ` [PATCH 04/53] netns xfrm: per-netns xfrm_state_all list Alexey Dobriyan
@ 2008-11-25 17:26       ` Alexey Dobriyan
  2008-11-25 17:26         ` [PATCH 06/53] netns xfrm: per-netns xfrm_state_bysrc hash Alexey Dobriyan
  2008-11-26  1:17         ` [PATCH 05/53] netns xfrm: per-netns xfrm_state_bydst hash David Miller
  2008-11-26  1:16       ` [PATCH 04/53] netns xfrm: per-netns xfrm_state_all list David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    9 ++++++++
 net/xfrm/xfrm_state.c    |   50 +++++++++++++++++++++++----------------------
 2 files changed, 35 insertions(+), 24 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 6ae234a..02487b3 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -5,6 +5,15 @@
 
 struct netns_xfrm {
 	struct list_head	state_all;
+	/*
+	 * Hash table to find appropriate SA towards given target (endpoint of
+	 * tunnel or destination of transport mode) allowed by selector.
+	 *
+	 * Main use is finding SA after policy selected tunnel or transport
+	 * mode. Also, it can be used by ah/esp icmp error handler to find
+	 * offending SA.
+	 */
+	struct hlist_head	*state_bydst;
 };
 
 #endif
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 85bb854..08b7889 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -44,13 +44,6 @@ u32 sysctl_xfrm_acq_expires __read_mostly = 30;
 
 static DEFINE_SPINLOCK(xfrm_state_lock);
 
-/* Hash table to find appropriate SA towards given target (endpoint
- * of tunnel or destination of transport mode) allowed by selector.
- *
- * Main use is finding SA after policy selected tunnel or transport mode.
- * Also, it can be used by ah/esp icmp error handler to find offending SA.
- */
-static struct hlist_head *xfrm_state_bydst __read_mostly;
 static struct hlist_head *xfrm_state_bysrc __read_mostly;
 static struct hlist_head *xfrm_state_byspi __read_mostly;
 static unsigned int xfrm_state_hmask __read_mostly;
@@ -157,15 +150,15 @@ static void xfrm_hash_resize(struct work_struct *__unused)
 
 	nhashmask = (nsize / sizeof(struct hlist_head)) - 1U;
 	for (i = xfrm_state_hmask; i >= 0; i--)
-		xfrm_hash_transfer(xfrm_state_bydst+i, ndst, nsrc, nspi,
+		xfrm_hash_transfer(init_net.xfrm.state_bydst+i, ndst, nsrc, nspi,
 				   nhashmask);
 
-	odst = xfrm_state_bydst;
+	odst = init_net.xfrm.state_bydst;
 	osrc = xfrm_state_bysrc;
 	ospi = xfrm_state_byspi;
 	ohashmask = xfrm_state_hmask;
 
-	xfrm_state_bydst = ndst;
+	init_net.xfrm.state_bydst = ndst;
 	xfrm_state_bysrc = nsrc;
 	xfrm_state_byspi = nspi;
 	xfrm_state_hmask = nhashmask;
@@ -595,7 +588,7 @@ xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
 		struct hlist_node *entry;
 		struct xfrm_state *x;
 
-		hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
+		hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+i, bydst) {
 			if (xfrm_id_proto_match(x->id.proto, proto) &&
 			   (err = security_xfrm_state_delete(x)) != 0) {
 				xfrm_audit_state_delete(x, 0,
@@ -630,7 +623,7 @@ int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
 		struct hlist_node *entry;
 		struct xfrm_state *x;
 restart:
-		hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
+		hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+i, bydst) {
 			if (!xfrm_state_kern(x) &&
 			    xfrm_id_proto_match(x->id.proto, proto)) {
 				xfrm_state_hold(x);
@@ -785,7 +778,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 
 	spin_lock_bh(&xfrm_state_lock);
 	h = xfrm_dst_hash(daddr, saddr, tmpl->reqid, family);
-	hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) {
+	hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) {
 		if (x->props.family == family &&
 		    x->props.reqid == tmpl->reqid &&
 		    !(x->props.flags & XFRM_STATE_WILDRECV) &&
@@ -855,7 +848,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 		if (km_query(x, tmpl, pol) == 0) {
 			x->km.state = XFRM_STATE_ACQ;
 			list_add(&x->km.all, &init_net.xfrm.state_all);
-			hlist_add_head(&x->bydst, xfrm_state_bydst+h);
+			hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h);
 			h = xfrm_src_hash(daddr, saddr, family);
 			hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
 			if (x->id.spi) {
@@ -895,7 +888,7 @@ xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 
 	spin_lock(&xfrm_state_lock);
 	h = xfrm_dst_hash(daddr, saddr, reqid, family);
-	hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) {
+	hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) {
 		if (x->props.family == family &&
 		    x->props.reqid == reqid &&
 		    !(x->props.flags & XFRM_STATE_WILDRECV) &&
@@ -927,7 +920,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
 
 	h = xfrm_dst_hash(&x->id.daddr, &x->props.saddr,
 			  x->props.reqid, x->props.family);
-	hlist_add_head(&x->bydst, xfrm_state_bydst+h);
+	hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h);
 
 	h = xfrm_src_hash(&x->id.daddr, &x->props.saddr, x->props.family);
 	hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
@@ -960,7 +953,7 @@ static void __xfrm_state_bump_genids(struct xfrm_state *xnew)
 	unsigned int h;
 
 	h = xfrm_dst_hash(&xnew->id.daddr, &xnew->props.saddr, reqid, family);
-	hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) {
+	hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) {
 		if (x->props.family	== family &&
 		    x->props.reqid	== reqid &&
 		    !xfrm_addr_cmp(&x->id.daddr, &xnew->id.daddr, family) &&
@@ -985,7 +978,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
 	struct hlist_node *entry;
 	struct xfrm_state *x;
 
-	hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) {
+	hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) {
 		if (x->props.reqid  != reqid ||
 		    x->props.mode   != mode ||
 		    x->props.family != family ||
@@ -1053,7 +1046,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
 		x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
 		add_timer(&x->timer);
 		list_add(&x->km.all, &init_net.xfrm.state_all);
-		hlist_add_head(&x->bydst, xfrm_state_bydst+h);
+		hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h);
 		h = xfrm_src_hash(daddr, saddr, family);
 		hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
 
@@ -1208,7 +1201,7 @@ struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m)
 	if (m->reqid) {
 		h = xfrm_dst_hash(&m->old_daddr, &m->old_saddr,
 				  m->reqid, m->old_family);
-		hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) {
+		hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) {
 			if (x->props.mode != m->mode ||
 			    x->id.proto != m->proto)
 				continue;
@@ -1457,7 +1450,7 @@ static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq)
 		struct hlist_node *entry;
 		struct xfrm_state *x;
 
-		hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
+		hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+i, bydst) {
 			if (x->km.seq == seq &&
 			    x->km.state == XFRM_STATE_ACQ) {
 				xfrm_state_hold(x);
@@ -2088,20 +2081,29 @@ int __net_init xfrm_state_init(struct net *net)
 
 	sz = sizeof(struct hlist_head) * 8;
 
-	xfrm_state_bydst = xfrm_hash_alloc(sz);
+	net->xfrm.state_bydst = xfrm_hash_alloc(sz);
+	if (!net->xfrm.state_bydst)
+		goto out_bydst;
 	xfrm_state_bysrc = xfrm_hash_alloc(sz);
 	xfrm_state_byspi = xfrm_hash_alloc(sz);
-	if (!xfrm_state_bydst || !xfrm_state_bysrc || !xfrm_state_byspi)
-		panic("XFRM: Cannot allocate bydst/bysrc/byspi hashes.");
 	xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
 
 	INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task);
 	return 0;
+
+out_bydst:
+	return -ENOMEM;
 }
 
 void xfrm_state_fini(struct net *net)
 {
+	unsigned int sz;
+
 	WARN_ON(!list_empty(&net->xfrm.state_all));
+
+	sz = (xfrm_state_hmask + 1) * sizeof(struct hlist_head);
+	WARN_ON(!hlist_empty(net->xfrm.state_bydst));
+	xfrm_hash_free(net->xfrm.state_bydst, sz);
 }
 
 #ifdef CONFIG_AUDITSYSCALL
-- 
1.5.6.5


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

* [PATCH 06/53] netns xfrm: per-netns xfrm_state_bysrc hash
  2008-11-25 17:26       ` [PATCH 05/53] netns xfrm: per-netns xfrm_state_bydst hash Alexey Dobriyan
@ 2008-11-25 17:26         ` Alexey Dobriyan
  2008-11-25 17:26           ` [PATCH 07/53] netns xfrm: per-netns xfrm_state_byspi hash Alexey Dobriyan
  2008-11-26  1:17           ` [PATCH 06/53] netns xfrm: per-netns xfrm_state_bysrc hash David Miller
  2008-11-26  1:17         ` [PATCH 05/53] netns xfrm: per-netns xfrm_state_bydst hash David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    1 +
 net/xfrm/xfrm_state.c    |   23 ++++++++++++++---------
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 02487b3..bfcd5a3 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -14,6 +14,7 @@ struct netns_xfrm {
 	 * offending SA.
 	 */
 	struct hlist_head	*state_bydst;
+	struct hlist_head	*state_bysrc;
 };
 
 #endif
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 08b7889..52d828b 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -44,7 +44,6 @@ u32 sysctl_xfrm_acq_expires __read_mostly = 30;
 
 static DEFINE_SPINLOCK(xfrm_state_lock);
 
-static struct hlist_head *xfrm_state_bysrc __read_mostly;
 static struct hlist_head *xfrm_state_byspi __read_mostly;
 static unsigned int xfrm_state_hmask __read_mostly;
 static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
@@ -154,12 +153,12 @@ static void xfrm_hash_resize(struct work_struct *__unused)
 				   nhashmask);
 
 	odst = init_net.xfrm.state_bydst;
-	osrc = xfrm_state_bysrc;
+	osrc = init_net.xfrm.state_bysrc;
 	ospi = xfrm_state_byspi;
 	ohashmask = xfrm_state_hmask;
 
 	init_net.xfrm.state_bydst = ndst;
-	xfrm_state_bysrc = nsrc;
+	init_net.xfrm.state_bysrc = nsrc;
 	xfrm_state_byspi = nspi;
 	xfrm_state_hmask = nhashmask;
 
@@ -712,7 +711,7 @@ static struct xfrm_state *__xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm
 	struct xfrm_state *x;
 	struct hlist_node *entry;
 
-	hlist_for_each_entry(x, entry, xfrm_state_bysrc+h, bysrc) {
+	hlist_for_each_entry(x, entry, init_net.xfrm.state_bysrc+h, bysrc) {
 		if (x->props.family != family ||
 		    x->id.proto     != proto)
 			continue;
@@ -850,7 +849,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 			list_add(&x->km.all, &init_net.xfrm.state_all);
 			hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h);
 			h = xfrm_src_hash(daddr, saddr, family);
-			hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
+			hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h);
 			if (x->id.spi) {
 				h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family);
 				hlist_add_head(&x->byspi, xfrm_state_byspi+h);
@@ -923,7 +922,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
 	hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h);
 
 	h = xfrm_src_hash(&x->id.daddr, &x->props.saddr, x->props.family);
-	hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
+	hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h);
 
 	if (x->id.spi) {
 		h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto,
@@ -1048,7 +1047,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
 		list_add(&x->km.all, &init_net.xfrm.state_all);
 		hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h);
 		h = xfrm_src_hash(daddr, saddr, family);
-		hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
+		hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h);
 
 		xfrm_state_num++;
 
@@ -1218,7 +1217,7 @@ struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m)
 	} else {
 		h = xfrm_src_hash(&m->old_daddr, &m->old_saddr,
 				  m->old_family);
-		hlist_for_each_entry(x, entry, xfrm_state_bysrc+h, bysrc) {
+		hlist_for_each_entry(x, entry, init_net.xfrm.state_bysrc+h, bysrc) {
 			if (x->props.mode != m->mode ||
 			    x->id.proto != m->proto)
 				continue;
@@ -2084,13 +2083,17 @@ int __net_init xfrm_state_init(struct net *net)
 	net->xfrm.state_bydst = xfrm_hash_alloc(sz);
 	if (!net->xfrm.state_bydst)
 		goto out_bydst;
-	xfrm_state_bysrc = xfrm_hash_alloc(sz);
+	net->xfrm.state_bysrc = xfrm_hash_alloc(sz);
+	if (!net->xfrm.state_bysrc)
+		goto out_bysrc;
 	xfrm_state_byspi = xfrm_hash_alloc(sz);
 	xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
 
 	INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task);
 	return 0;
 
+out_bysrc:
+	xfrm_hash_free(net->xfrm.state_bydst, sz);
 out_bydst:
 	return -ENOMEM;
 }
@@ -2102,6 +2105,8 @@ void xfrm_state_fini(struct net *net)
 	WARN_ON(!list_empty(&net->xfrm.state_all));
 
 	sz = (xfrm_state_hmask + 1) * sizeof(struct hlist_head);
+	WARN_ON(!hlist_empty(net->xfrm.state_bysrc));
+	xfrm_hash_free(net->xfrm.state_bysrc, sz);
 	WARN_ON(!hlist_empty(net->xfrm.state_bydst));
 	xfrm_hash_free(net->xfrm.state_bydst, sz);
 }
-- 
1.5.6.5


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

* [PATCH 07/53] netns xfrm: per-netns xfrm_state_byspi hash
  2008-11-25 17:26         ` [PATCH 06/53] netns xfrm: per-netns xfrm_state_bysrc hash Alexey Dobriyan
@ 2008-11-25 17:26           ` Alexey Dobriyan
  2008-11-25 17:26             ` [PATCH 08/53] netns xfrm: per-netns xfrm_state_hmask Alexey Dobriyan
  2008-11-26  1:17             ` [PATCH 07/53] netns xfrm: per-netns xfrm_state_byspi hash David Miller
  2008-11-26  1:17           ` [PATCH 06/53] netns xfrm: per-netns xfrm_state_bysrc hash David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    1 +
 net/xfrm/xfrm_state.c    |   21 +++++++++++++--------
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index bfcd5a3..b05ca3f 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -15,6 +15,7 @@ struct netns_xfrm {
 	 */
 	struct hlist_head	*state_bydst;
 	struct hlist_head	*state_bysrc;
+	struct hlist_head	*state_byspi;
 };
 
 #endif
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 52d828b..66ca1ef 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -44,7 +44,6 @@ u32 sysctl_xfrm_acq_expires __read_mostly = 30;
 
 static DEFINE_SPINLOCK(xfrm_state_lock);
 
-static struct hlist_head *xfrm_state_byspi __read_mostly;
 static unsigned int xfrm_state_hmask __read_mostly;
 static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
 static unsigned int xfrm_state_num;
@@ -154,12 +153,12 @@ static void xfrm_hash_resize(struct work_struct *__unused)
 
 	odst = init_net.xfrm.state_bydst;
 	osrc = init_net.xfrm.state_bysrc;
-	ospi = xfrm_state_byspi;
+	ospi = init_net.xfrm.state_byspi;
 	ohashmask = xfrm_state_hmask;
 
 	init_net.xfrm.state_bydst = ndst;
 	init_net.xfrm.state_bysrc = nsrc;
-	xfrm_state_byspi = nspi;
+	init_net.xfrm.state_byspi = nspi;
 	xfrm_state_hmask = nhashmask;
 
 	spin_unlock_bh(&xfrm_state_lock);
@@ -679,7 +678,7 @@ static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi,
 	struct xfrm_state *x;
 	struct hlist_node *entry;
 
-	hlist_for_each_entry(x, entry, xfrm_state_byspi+h, byspi) {
+	hlist_for_each_entry(x, entry, init_net.xfrm.state_byspi+h, byspi) {
 		if (x->props.family != family ||
 		    x->id.spi       != spi ||
 		    x->id.proto     != proto)
@@ -852,7 +851,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 			hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h);
 			if (x->id.spi) {
 				h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family);
-				hlist_add_head(&x->byspi, xfrm_state_byspi+h);
+				hlist_add_head(&x->byspi, init_net.xfrm.state_byspi+h);
 			}
 			x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
 			x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
@@ -928,7 +927,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
 		h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto,
 				  x->props.family);
 
-		hlist_add_head(&x->byspi, xfrm_state_byspi+h);
+		hlist_add_head(&x->byspi, init_net.xfrm.state_byspi+h);
 	}
 
 	mod_timer(&x->timer, jiffies + HZ);
@@ -1524,7 +1523,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
 	if (x->id.spi) {
 		spin_lock_bh(&xfrm_state_lock);
 		h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, x->props.family);
-		hlist_add_head(&x->byspi, xfrm_state_byspi+h);
+		hlist_add_head(&x->byspi, init_net.xfrm.state_byspi+h);
 		spin_unlock_bh(&xfrm_state_lock);
 
 		err = 0;
@@ -2086,12 +2085,16 @@ int __net_init xfrm_state_init(struct net *net)
 	net->xfrm.state_bysrc = xfrm_hash_alloc(sz);
 	if (!net->xfrm.state_bysrc)
 		goto out_bysrc;
-	xfrm_state_byspi = xfrm_hash_alloc(sz);
+	net->xfrm.state_byspi = xfrm_hash_alloc(sz);
+	if (!net->xfrm.state_byspi)
+		goto out_byspi;
 	xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
 
 	INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task);
 	return 0;
 
+out_byspi:
+	xfrm_hash_free(net->xfrm.state_bysrc, sz);
 out_bysrc:
 	xfrm_hash_free(net->xfrm.state_bydst, sz);
 out_bydst:
@@ -2105,6 +2108,8 @@ void xfrm_state_fini(struct net *net)
 	WARN_ON(!list_empty(&net->xfrm.state_all));
 
 	sz = (xfrm_state_hmask + 1) * sizeof(struct hlist_head);
+	WARN_ON(!hlist_empty(net->xfrm.state_byspi));
+	xfrm_hash_free(net->xfrm.state_byspi, sz);
 	WARN_ON(!hlist_empty(net->xfrm.state_bysrc));
 	xfrm_hash_free(net->xfrm.state_bysrc, sz);
 	WARN_ON(!hlist_empty(net->xfrm.state_bydst));
-- 
1.5.6.5


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

* [PATCH 08/53] netns xfrm: per-netns xfrm_state_hmask
  2008-11-25 17:26           ` [PATCH 07/53] netns xfrm: per-netns xfrm_state_byspi hash Alexey Dobriyan
@ 2008-11-25 17:26             ` Alexey Dobriyan
  2008-11-25 17:26               ` [PATCH 09/53] netns xfrm: per-netns xfrm_state counts Alexey Dobriyan
  2008-11-26  1:18               ` [PATCH 08/53] netns xfrm: per-netns xfrm_state_hmask David Miller
  2008-11-26  1:17             ` [PATCH 07/53] netns xfrm: per-netns xfrm_state_byspi hash David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Since hashtables are per-netns, they can be independently resized.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    1 +
 net/xfrm/xfrm_state.c    |   31 +++++++++++++++----------------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index b05ca3f..dbbc0e9 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -16,6 +16,7 @@ struct netns_xfrm {
 	struct hlist_head	*state_bydst;
 	struct hlist_head	*state_bysrc;
 	struct hlist_head	*state_byspi;
+	unsigned int		state_hmask;
 };
 
 #endif
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 66ca1ef..de08ed9 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -44,7 +44,6 @@ u32 sysctl_xfrm_acq_expires __read_mostly = 30;
 
 static DEFINE_SPINLOCK(xfrm_state_lock);
 
-static unsigned int xfrm_state_hmask __read_mostly;
 static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
 static unsigned int xfrm_state_num;
 static unsigned int xfrm_state_genid;
@@ -64,20 +63,20 @@ static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr,
 					 u32 reqid,
 					 unsigned short family)
 {
-	return __xfrm_dst_hash(daddr, saddr, reqid, family, xfrm_state_hmask);
+	return __xfrm_dst_hash(daddr, saddr, reqid, family, init_net.xfrm.state_hmask);
 }
 
 static inline unsigned int xfrm_src_hash(xfrm_address_t *daddr,
 					 xfrm_address_t *saddr,
 					 unsigned short family)
 {
-	return __xfrm_src_hash(daddr, saddr, family, xfrm_state_hmask);
+	return __xfrm_src_hash(daddr, saddr, family, init_net.xfrm.state_hmask);
 }
 
 static inline unsigned int
 xfrm_spi_hash(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
 {
-	return __xfrm_spi_hash(daddr, spi, proto, family, xfrm_state_hmask);
+	return __xfrm_spi_hash(daddr, spi, proto, family, init_net.xfrm.state_hmask);
 }
 
 static void xfrm_hash_transfer(struct hlist_head *list,
@@ -113,7 +112,7 @@ static void xfrm_hash_transfer(struct hlist_head *list,
 
 static unsigned long xfrm_hash_new_size(void)
 {
-	return ((xfrm_state_hmask + 1) << 1) *
+	return ((init_net.xfrm.state_hmask + 1) << 1) *
 		sizeof(struct hlist_head);
 }
 
@@ -147,19 +146,19 @@ static void xfrm_hash_resize(struct work_struct *__unused)
 	spin_lock_bh(&xfrm_state_lock);
 
 	nhashmask = (nsize / sizeof(struct hlist_head)) - 1U;
-	for (i = xfrm_state_hmask; i >= 0; i--)
+	for (i = init_net.xfrm.state_hmask; i >= 0; i--)
 		xfrm_hash_transfer(init_net.xfrm.state_bydst+i, ndst, nsrc, nspi,
 				   nhashmask);
 
 	odst = init_net.xfrm.state_bydst;
 	osrc = init_net.xfrm.state_bysrc;
 	ospi = init_net.xfrm.state_byspi;
-	ohashmask = xfrm_state_hmask;
+	ohashmask = init_net.xfrm.state_hmask;
 
 	init_net.xfrm.state_bydst = ndst;
 	init_net.xfrm.state_bysrc = nsrc;
 	init_net.xfrm.state_byspi = nspi;
-	xfrm_state_hmask = nhashmask;
+	init_net.xfrm.state_hmask = nhashmask;
 
 	spin_unlock_bh(&xfrm_state_lock);
 
@@ -582,7 +581,7 @@ xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
 {
 	int i, err = 0;
 
-	for (i = 0; i <= xfrm_state_hmask; i++) {
+	for (i = 0; i <= init_net.xfrm.state_hmask; i++) {
 		struct hlist_node *entry;
 		struct xfrm_state *x;
 
@@ -617,7 +616,7 @@ int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
 	if (err)
 		goto out;
 
-	for (i = 0; i <= xfrm_state_hmask; i++) {
+	for (i = 0; i <= init_net.xfrm.state_hmask; i++) {
 		struct hlist_node *entry;
 		struct xfrm_state *x;
 restart:
@@ -652,7 +651,7 @@ void xfrm_sad_getinfo(struct xfrmk_sadinfo *si)
 {
 	spin_lock_bh(&xfrm_state_lock);
 	si->sadcnt = xfrm_state_num;
-	si->sadhcnt = xfrm_state_hmask;
+	si->sadhcnt = init_net.xfrm.state_hmask;
 	si->sadhmcnt = xfrm_state_hashmax;
 	spin_unlock_bh(&xfrm_state_lock);
 }
@@ -754,8 +753,8 @@ __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family)
 static void xfrm_hash_grow_check(int have_hash_collision)
 {
 	if (have_hash_collision &&
-	    (xfrm_state_hmask + 1) < xfrm_state_hashmax &&
-	    xfrm_state_num > xfrm_state_hmask)
+	    (init_net.xfrm.state_hmask + 1) < xfrm_state_hashmax &&
+	    xfrm_state_num > init_net.xfrm.state_hmask)
 		schedule_work(&xfrm_hash_work);
 }
 
@@ -1444,7 +1443,7 @@ static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq)
 {
 	int i;
 
-	for (i = 0; i <= xfrm_state_hmask; i++) {
+	for (i = 0; i <= init_net.xfrm.state_hmask; i++) {
 		struct hlist_node *entry;
 		struct xfrm_state *x;
 
@@ -2088,7 +2087,7 @@ int __net_init xfrm_state_init(struct net *net)
 	net->xfrm.state_byspi = xfrm_hash_alloc(sz);
 	if (!net->xfrm.state_byspi)
 		goto out_byspi;
-	xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
+	net->xfrm.state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
 
 	INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task);
 	return 0;
@@ -2107,7 +2106,7 @@ void xfrm_state_fini(struct net *net)
 
 	WARN_ON(!list_empty(&net->xfrm.state_all));
 
-	sz = (xfrm_state_hmask + 1) * sizeof(struct hlist_head);
+	sz = (net->xfrm.state_hmask + 1) * sizeof(struct hlist_head);
 	WARN_ON(!hlist_empty(net->xfrm.state_byspi));
 	xfrm_hash_free(net->xfrm.state_byspi, sz);
 	WARN_ON(!hlist_empty(net->xfrm.state_bysrc));
-- 
1.5.6.5


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

* [PATCH 09/53] netns xfrm: per-netns xfrm_state counts
  2008-11-25 17:26             ` [PATCH 08/53] netns xfrm: per-netns xfrm_state_hmask Alexey Dobriyan
@ 2008-11-25 17:26               ` Alexey Dobriyan
  2008-11-25 17:26                 ` [PATCH 10/53] netns xfrm: per-netns xfrm_hash_work Alexey Dobriyan
  2008-11-26  1:18                 ` [PATCH 09/53] netns xfrm: per-netns xfrm_state counts David Miller
  2008-11-26  1:18               ` [PATCH 08/53] netns xfrm: per-netns xfrm_state_hmask David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    1 +
 net/xfrm/xfrm_state.c    |   14 +++++++-------
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index dbbc0e9..492b471 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -17,6 +17,7 @@ struct netns_xfrm {
 	struct hlist_head	*state_bysrc;
 	struct hlist_head	*state_byspi;
 	unsigned int		state_hmask;
+	unsigned int		state_num;
 };
 
 #endif
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index de08ed9..7ecf6ee 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -45,7 +45,6 @@ u32 sysctl_xfrm_acq_expires __read_mostly = 30;
 static DEFINE_SPINLOCK(xfrm_state_lock);
 
 static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
-static unsigned int xfrm_state_num;
 static unsigned int xfrm_state_genid;
 
 static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
@@ -548,7 +547,7 @@ int __xfrm_state_delete(struct xfrm_state *x)
 		hlist_del(&x->bysrc);
 		if (x->id.spi)
 			hlist_del(&x->byspi);
-		xfrm_state_num--;
+		init_net.xfrm.state_num--;
 		spin_unlock(&xfrm_state_lock);
 
 		/* All xfrm_state objects are created by xfrm_state_alloc.
@@ -650,7 +649,7 @@ EXPORT_SYMBOL(xfrm_state_flush);
 void xfrm_sad_getinfo(struct xfrmk_sadinfo *si)
 {
 	spin_lock_bh(&xfrm_state_lock);
-	si->sadcnt = xfrm_state_num;
+	si->sadcnt = init_net.xfrm.state_num;
 	si->sadhcnt = init_net.xfrm.state_hmask;
 	si->sadhmcnt = xfrm_state_hashmax;
 	spin_unlock_bh(&xfrm_state_lock);
@@ -754,7 +753,7 @@ static void xfrm_hash_grow_check(int have_hash_collision)
 {
 	if (have_hash_collision &&
 	    (init_net.xfrm.state_hmask + 1) < xfrm_state_hashmax &&
-	    xfrm_state_num > init_net.xfrm.state_hmask)
+	    init_net.xfrm.state_num > init_net.xfrm.state_hmask)
 		schedule_work(&xfrm_hash_work);
 }
 
@@ -855,7 +854,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 			x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
 			x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
 			add_timer(&x->timer);
-			xfrm_state_num++;
+			init_net.xfrm.state_num++;
 			xfrm_hash_grow_check(x->bydst.next != NULL);
 		} else {
 			x->km.state = XFRM_STATE_DEAD;
@@ -935,7 +934,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
 
 	wake_up(&km_waitq);
 
-	xfrm_state_num++;
+	init_net.xfrm.state_num++;
 
 	xfrm_hash_grow_check(x->bydst.next != NULL);
 }
@@ -1047,7 +1046,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
 		h = xfrm_src_hash(daddr, saddr, family);
 		hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h);
 
-		xfrm_state_num++;
+		init_net.xfrm.state_num++;
 
 		xfrm_hash_grow_check(x->bydst.next != NULL);
 	}
@@ -2089,6 +2088,7 @@ int __net_init xfrm_state_init(struct net *net)
 		goto out_byspi;
 	net->xfrm.state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
 
+	net->xfrm.state_num = 0;
 	INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task);
 	return 0;
 
-- 
1.5.6.5


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

* [PATCH 10/53] netns xfrm: per-netns xfrm_hash_work
  2008-11-25 17:26               ` [PATCH 09/53] netns xfrm: per-netns xfrm_state counts Alexey Dobriyan
@ 2008-11-25 17:26                 ` Alexey Dobriyan
  2008-11-25 17:26                   ` [PATCH 11/53] netns xfrm: per-netns state GC list Alexey Dobriyan
  2008-11-26  1:19                   ` [PATCH 10/53] netns xfrm: per-netns xfrm_hash_work David Miller
  2008-11-26  1:18                 ` [PATCH 09/53] netns xfrm: per-netns xfrm_state counts David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

All of this is implicit passing which netns's hashes should be resized.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    2 ++
 net/xfrm/xfrm_state.c    |   35 +++++++++++++++++------------------
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 492b471..bd68802 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -2,6 +2,7 @@
 #define __NETNS_XFRM_H
 
 #include <linux/list.h>
+#include <linux/workqueue.h>
 
 struct netns_xfrm {
 	struct list_head	state_all;
@@ -18,6 +19,7 @@ struct netns_xfrm {
 	struct hlist_head	*state_byspi;
 	unsigned int		state_hmask;
 	unsigned int		state_num;
+	struct work_struct	state_hash_work;
 };
 
 #endif
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 7ecf6ee..1b2a72c 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -109,16 +109,16 @@ static void xfrm_hash_transfer(struct hlist_head *list,
 	}
 }
 
-static unsigned long xfrm_hash_new_size(void)
+static unsigned long xfrm_hash_new_size(unsigned int state_hmask)
 {
-	return ((init_net.xfrm.state_hmask + 1) << 1) *
-		sizeof(struct hlist_head);
+	return ((state_hmask + 1) << 1) * sizeof(struct hlist_head);
 }
 
 static DEFINE_MUTEX(hash_resize_mutex);
 
-static void xfrm_hash_resize(struct work_struct *__unused)
+static void xfrm_hash_resize(struct work_struct *work)
 {
+	struct net *net = container_of(work, struct net, xfrm.state_hash_work);
 	struct hlist_head *ndst, *nsrc, *nspi, *odst, *osrc, *ospi;
 	unsigned long nsize, osize;
 	unsigned int nhashmask, ohashmask;
@@ -126,7 +126,7 @@ static void xfrm_hash_resize(struct work_struct *__unused)
 
 	mutex_lock(&hash_resize_mutex);
 
-	nsize = xfrm_hash_new_size();
+	nsize = xfrm_hash_new_size(net->xfrm.state_hmask);
 	ndst = xfrm_hash_alloc(nsize);
 	if (!ndst)
 		goto out_unlock;
@@ -145,19 +145,19 @@ static void xfrm_hash_resize(struct work_struct *__unused)
 	spin_lock_bh(&xfrm_state_lock);
 
 	nhashmask = (nsize / sizeof(struct hlist_head)) - 1U;
-	for (i = init_net.xfrm.state_hmask; i >= 0; i--)
-		xfrm_hash_transfer(init_net.xfrm.state_bydst+i, ndst, nsrc, nspi,
+	for (i = net->xfrm.state_hmask; i >= 0; i--)
+		xfrm_hash_transfer(net->xfrm.state_bydst+i, ndst, nsrc, nspi,
 				   nhashmask);
 
-	odst = init_net.xfrm.state_bydst;
-	osrc = init_net.xfrm.state_bysrc;
-	ospi = init_net.xfrm.state_byspi;
-	ohashmask = init_net.xfrm.state_hmask;
+	odst = net->xfrm.state_bydst;
+	osrc = net->xfrm.state_bysrc;
+	ospi = net->xfrm.state_byspi;
+	ohashmask = net->xfrm.state_hmask;
 
-	init_net.xfrm.state_bydst = ndst;
-	init_net.xfrm.state_bysrc = nsrc;
-	init_net.xfrm.state_byspi = nspi;
-	init_net.xfrm.state_hmask = nhashmask;
+	net->xfrm.state_bydst = ndst;
+	net->xfrm.state_bysrc = nsrc;
+	net->xfrm.state_byspi = nspi;
+	net->xfrm.state_hmask = nhashmask;
 
 	spin_unlock_bh(&xfrm_state_lock);
 
@@ -170,8 +170,6 @@ out_unlock:
 	mutex_unlock(&hash_resize_mutex);
 }
 
-static DECLARE_WORK(xfrm_hash_work, xfrm_hash_resize);
-
 DECLARE_WAIT_QUEUE_HEAD(km_waitq);
 EXPORT_SYMBOL(km_waitq);
 
@@ -754,7 +752,7 @@ static void xfrm_hash_grow_check(int have_hash_collision)
 	if (have_hash_collision &&
 	    (init_net.xfrm.state_hmask + 1) < xfrm_state_hashmax &&
 	    init_net.xfrm.state_num > init_net.xfrm.state_hmask)
-		schedule_work(&xfrm_hash_work);
+		schedule_work(&init_net.xfrm.state_hash_work);
 }
 
 struct xfrm_state *
@@ -2089,6 +2087,7 @@ int __net_init xfrm_state_init(struct net *net)
 	net->xfrm.state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
 
 	net->xfrm.state_num = 0;
+	INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize);
 	INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task);
 	return 0;
 
-- 
1.5.6.5


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

* [PATCH 11/53] netns xfrm: per-netns state GC list
  2008-11-25 17:26                 ` [PATCH 10/53] netns xfrm: per-netns xfrm_hash_work Alexey Dobriyan
@ 2008-11-25 17:26                   ` Alexey Dobriyan
  2008-11-25 17:26                     ` [PATCH 12/53] netns xfrm: per-netns state GC work Alexey Dobriyan
  2008-11-26  1:20                     ` [PATCH 11/53] netns xfrm: per-netns state GC list David Miller
  2008-11-26  1:19                   ` [PATCH 10/53] netns xfrm: per-netns xfrm_hash_work David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

km_waitq is going to be made per-netns to disallow spurious wakeups
in __xfrm_lookup().

To not wakeup after every garbage-collected xfrm_state (which potentially
can be from different netns) make state GC list per-netns.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    1 +
 net/xfrm/xfrm_state.c    |    6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index bd68802..8ceb765 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -20,6 +20,7 @@ struct netns_xfrm {
 	unsigned int		state_hmask;
 	unsigned int		state_num;
 	struct work_struct	state_hash_work;
+	struct hlist_head	state_gc_list;
 };
 
 #endif
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 1b2a72c..864a974 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -177,7 +177,6 @@ static DEFINE_RWLOCK(xfrm_state_afinfo_lock);
 static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO];
 
 static struct work_struct xfrm_state_gc_work;
-static HLIST_HEAD(xfrm_state_gc_list);
 static DEFINE_SPINLOCK(xfrm_state_gc_lock);
 
 int __xfrm_state_delete(struct xfrm_state *x);
@@ -394,7 +393,7 @@ static void xfrm_state_gc_task(struct work_struct *data)
 	struct hlist_head gc_list;
 
 	spin_lock_bh(&xfrm_state_gc_lock);
-	hlist_move_list(&xfrm_state_gc_list, &gc_list);
+	hlist_move_list(&init_net.xfrm.state_gc_list, &gc_list);
 	spin_unlock_bh(&xfrm_state_gc_lock);
 
 	hlist_for_each_entry_safe(x, entry, tmp, &gc_list, gclist)
@@ -527,7 +526,7 @@ void __xfrm_state_destroy(struct xfrm_state *x)
 	WARN_ON(x->km.state != XFRM_STATE_DEAD);
 
 	spin_lock_bh(&xfrm_state_gc_lock);
-	hlist_add_head(&x->gclist, &xfrm_state_gc_list);
+	hlist_add_head(&x->gclist, &init_net.xfrm.state_gc_list);
 	spin_unlock_bh(&xfrm_state_gc_lock);
 	schedule_work(&xfrm_state_gc_work);
 }
@@ -2088,6 +2087,7 @@ int __net_init xfrm_state_init(struct net *net)
 
 	net->xfrm.state_num = 0;
 	INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize);
+	INIT_HLIST_HEAD(&net->xfrm.state_gc_list);
 	INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task);
 	return 0;
 
-- 
1.5.6.5


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

* [PATCH 12/53] netns xfrm: per-netns state GC work
  2008-11-25 17:26                   ` [PATCH 11/53] netns xfrm: per-netns state GC list Alexey Dobriyan
@ 2008-11-25 17:26                     ` Alexey Dobriyan
  2008-11-25 17:26                       ` [PATCH 13/53] netns xfrm: per-netns km_waitq Alexey Dobriyan
  2008-11-26  1:20                       ` [PATCH 12/53] netns xfrm: per-netns state GC work David Miller
  2008-11-26  1:20                     ` [PATCH 11/53] netns xfrm: per-netns state GC list David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

State GC is per-netns, and this is part of it.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    1 +
 net/xfrm/xfrm_state.c    |   10 +++++-----
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 8ceb765..8055535 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -21,6 +21,7 @@ struct netns_xfrm {
 	unsigned int		state_num;
 	struct work_struct	state_hash_work;
 	struct hlist_head	state_gc_list;
+	struct work_struct	state_gc_work;
 };
 
 #endif
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 864a974..69c0b06 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -176,7 +176,6 @@ EXPORT_SYMBOL(km_waitq);
 static DEFINE_RWLOCK(xfrm_state_afinfo_lock);
 static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO];
 
-static struct work_struct xfrm_state_gc_work;
 static DEFINE_SPINLOCK(xfrm_state_gc_lock);
 
 int __xfrm_state_delete(struct xfrm_state *x);
@@ -386,14 +385,15 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
 	kfree(x);
 }
 
-static void xfrm_state_gc_task(struct work_struct *data)
+static void xfrm_state_gc_task(struct work_struct *work)
 {
+	struct net *net = container_of(work, struct net, xfrm.state_gc_work);
 	struct xfrm_state *x;
 	struct hlist_node *entry, *tmp;
 	struct hlist_head gc_list;
 
 	spin_lock_bh(&xfrm_state_gc_lock);
-	hlist_move_list(&init_net.xfrm.state_gc_list, &gc_list);
+	hlist_move_list(&net->xfrm.state_gc_list, &gc_list);
 	spin_unlock_bh(&xfrm_state_gc_lock);
 
 	hlist_for_each_entry_safe(x, entry, tmp, &gc_list, gclist)
@@ -528,7 +528,7 @@ void __xfrm_state_destroy(struct xfrm_state *x)
 	spin_lock_bh(&xfrm_state_gc_lock);
 	hlist_add_head(&x->gclist, &init_net.xfrm.state_gc_list);
 	spin_unlock_bh(&xfrm_state_gc_lock);
-	schedule_work(&xfrm_state_gc_work);
+	schedule_work(&init_net.xfrm.state_gc_work);
 }
 EXPORT_SYMBOL(__xfrm_state_destroy);
 
@@ -2088,7 +2088,7 @@ int __net_init xfrm_state_init(struct net *net)
 	net->xfrm.state_num = 0;
 	INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize);
 	INIT_HLIST_HEAD(&net->xfrm.state_gc_list);
-	INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task);
+	INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task);
 	return 0;
 
 out_byspi:
-- 
1.5.6.5


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

* [PATCH 13/53] netns xfrm: per-netns km_waitq
  2008-11-25 17:26                     ` [PATCH 12/53] netns xfrm: per-netns state GC work Alexey Dobriyan
@ 2008-11-25 17:26                       ` Alexey Dobriyan
  2008-11-25 17:26                         ` [PATCH 14/53] netns xfrm: add struct xfrm_policy::xp_net Alexey Dobriyan
  2008-11-26  1:21                         ` [PATCH 13/53] netns xfrm: per-netns km_waitq David Miller
  2008-11-26  1:20                       ` [PATCH 12/53] netns xfrm: per-netns state GC work David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Dissalow spurious wakeups in __xfrm_lookup().

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    3 +++
 include/net/xfrm.h       |    1 -
 net/key/af_key.c         |    2 +-
 net/xfrm/xfrm_policy.c   |    4 ++--
 net/xfrm/xfrm_state.c    |   16 +++++++---------
 5 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 8055535..2a383c8 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -2,6 +2,7 @@
 #define __NETNS_XFRM_H
 
 #include <linux/list.h>
+#include <linux/wait.h>
 #include <linux/workqueue.h>
 
 struct netns_xfrm {
@@ -22,6 +23,8 @@ struct netns_xfrm {
 	struct work_struct	state_hash_work;
 	struct hlist_head	state_gc_list;
 	struct work_struct	state_gc_work;
+
+	wait_queue_head_t	km_waitq;
 };
 
 #endif
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 9da8903..0d4353c 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1459,7 +1459,6 @@ extern int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
 			struct xfrm_kmaddress *k);
 #endif
 
-extern wait_queue_head_t km_waitq;
 extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
 extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid);
 extern int km_report(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index bde8aad..f202ba6 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1411,7 +1411,7 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg *
 	spin_lock_bh(&x->lock);
 	if (x->km.state == XFRM_STATE_ACQ) {
 		x->km.state = XFRM_STATE_ERROR;
-		wake_up(&km_waitq);
+		wake_up(&init_net.xfrm.km_waitq);
 	}
 	spin_unlock_bh(&x->lock);
 	xfrm_state_put(x);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 8e7671b..cf2bf3a 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1691,11 +1691,11 @@ restart:
 			if (err == -EAGAIN && (flags & XFRM_LOOKUP_WAIT)) {
 				DECLARE_WAITQUEUE(wait, current);
 
-				add_wait_queue(&km_waitq, &wait);
+				add_wait_queue(&init_net.xfrm.km_waitq, &wait);
 				set_current_state(TASK_INTERRUPTIBLE);
 				schedule();
 				set_current_state(TASK_RUNNING);
-				remove_wait_queue(&km_waitq, &wait);
+				remove_wait_queue(&init_net.xfrm.km_waitq, &wait);
 
 				nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family);
 
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 69c0b06..24bd89e 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -170,9 +170,6 @@ out_unlock:
 	mutex_unlock(&hash_resize_mutex);
 }
 
-DECLARE_WAIT_QUEUE_HEAD(km_waitq);
-EXPORT_SYMBOL(km_waitq);
-
 static DEFINE_RWLOCK(xfrm_state_afinfo_lock);
 static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO];
 
@@ -399,7 +396,7 @@ static void xfrm_state_gc_task(struct work_struct *work)
 	hlist_for_each_entry_safe(x, entry, tmp, &gc_list, gclist)
 		xfrm_state_gc_destroy(x);
 
-	wake_up(&km_waitq);
+	wake_up(&net->xfrm.km_waitq);
 }
 
 static inline unsigned long make_jiffies(long secs)
@@ -470,7 +467,7 @@ resched:
 expired:
 	if (x->km.state == XFRM_STATE_ACQ && x->id.spi == 0) {
 		x->km.state = XFRM_STATE_EXPIRED;
-		wake_up(&km_waitq);
+		wake_up(&init_net.xfrm.km_waitq);
 		next = 2;
 		goto resched;
 	}
@@ -638,7 +635,7 @@ restart:
 
 out:
 	spin_unlock_bh(&xfrm_state_lock);
-	wake_up(&km_waitq);
+	wake_up(&init_net.xfrm.km_waitq);
 	return err;
 }
 EXPORT_SYMBOL(xfrm_state_flush);
@@ -929,7 +926,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
 	if (x->replay_maxage)
 		mod_timer(&x->rtimer, jiffies + x->replay_maxage);
 
-	wake_up(&km_waitq);
+	wake_up(&init_net.xfrm.km_waitq);
 
 	init_net.xfrm.state_num++;
 
@@ -1743,7 +1740,7 @@ void km_state_expired(struct xfrm_state *x, int hard, u32 pid)
 	km_state_notify(x, &c);
 
 	if (hard)
-		wake_up(&km_waitq);
+		wake_up(&init_net.xfrm.km_waitq);
 }
 
 EXPORT_SYMBOL(km_state_expired);
@@ -1794,7 +1791,7 @@ void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid)
 	km_policy_notify(pol, dir, &c);
 
 	if (hard)
-		wake_up(&km_waitq);
+		wake_up(&init_net.xfrm.km_waitq);
 }
 EXPORT_SYMBOL(km_policy_expired);
 
@@ -2089,6 +2086,7 @@ int __net_init xfrm_state_init(struct net *net)
 	INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize);
 	INIT_HLIST_HEAD(&net->xfrm.state_gc_list);
 	INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task);
+	init_waitqueue_head(&net->xfrm.km_waitq);
 	return 0;
 
 out_byspi:
-- 
1.5.6.5


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

* [PATCH 14/53] netns xfrm: add struct xfrm_policy::xp_net
  2008-11-25 17:26                       ` [PATCH 13/53] netns xfrm: per-netns km_waitq Alexey Dobriyan
@ 2008-11-25 17:26                         ` Alexey Dobriyan
  2008-11-25 17:26                           ` [PATCH 15/53] netns xfrm: per-netns policy list Alexey Dobriyan
  2008-11-26  1:21                           ` [PATCH 14/53] netns xfrm: add struct xfrm_policy::xp_net David Miller
  2008-11-26  1:21                         ` [PATCH 13/53] netns xfrm: per-netns km_waitq David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Again, to avoid complications with passing netns when not necessary.
Again, ->xp_net is set-once field, once set it never changes.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h     |   10 +++++++++-
 net/key/af_key.c       |    4 ++--
 net/xfrm/xfrm_policy.c |    5 +++--
 net/xfrm/xfrm_user.c   |    4 ++--
 4 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 0d4353c..1ab1756 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -475,6 +475,9 @@ struct xfrm_policy_walk {
 
 struct xfrm_policy
 {
+#ifdef CONFIG_NET_NS
+	struct net		*xp_net;
+#endif
 	struct hlist_node	bydst;
 	struct hlist_node	byidx;
 
@@ -499,6 +502,11 @@ struct xfrm_policy
 	struct xfrm_tmpl       	xfrm_vec[XFRM_MAX_DEPTH];
 };
 
+static inline struct net *xp_net(struct xfrm_policy *xp)
+{
+	return read_pnet(&xp->xp_net);
+}
+
 struct xfrm_kmaddress {
 	xfrm_address_t          local;
 	xfrm_address_t          remote;
@@ -1425,7 +1433,7 @@ static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
 }
 #endif
 
-struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
+struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
 
 extern void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type);
 extern int xfrm_policy_walk(struct xfrm_policy_walk *walk,
diff --git a/net/key/af_key.c b/net/key/af_key.c
index f202ba6..036315d 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2174,7 +2174,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
 	if (!pol->sadb_x_policy_dir || pol->sadb_x_policy_dir >= IPSEC_DIR_MAX)
 		return -EINVAL;
 
-	xp = xfrm_policy_alloc(GFP_KERNEL);
+	xp = xfrm_policy_alloc(&init_net, GFP_KERNEL);
 	if (xp == NULL)
 		return -ENOBUFS;
 
@@ -3141,7 +3141,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
 	    (!pol->sadb_x_policy_dir || pol->sadb_x_policy_dir > IPSEC_DIR_OUTBOUND))
 		return NULL;
 
-	xp = xfrm_policy_alloc(GFP_ATOMIC);
+	xp = xfrm_policy_alloc(&init_net, GFP_ATOMIC);
 	if (xp == NULL) {
 		*dir = -ENOBUFS;
 		return NULL;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index cf2bf3a..3eccefa 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -228,13 +228,14 @@ expired:
  * SPD calls.
  */
 
-struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp)
+struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp)
 {
 	struct xfrm_policy *policy;
 
 	policy = kzalloc(sizeof(struct xfrm_policy), gfp);
 
 	if (policy) {
+		write_pnet(&policy->xp_net, net);
 		INIT_LIST_HEAD(&policy->walk.all);
 		INIT_HLIST_NODE(&policy->bydst);
 		INIT_HLIST_NODE(&policy->byidx);
@@ -1153,7 +1154,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
 
 static struct xfrm_policy *clone_policy(struct xfrm_policy *old, int dir)
 {
-	struct xfrm_policy *newp = xfrm_policy_alloc(GFP_ATOMIC);
+	struct xfrm_policy *newp = xfrm_policy_alloc(xp_net(old), GFP_ATOMIC);
 
 	if (newp) {
 		newp->selector = old->selector;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 65cdaa5..765c01e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1080,7 +1080,7 @@ static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_i
 
 static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p, struct nlattr **attrs, int *errp)
 {
-	struct xfrm_policy *xp = xfrm_policy_alloc(GFP_KERNEL);
+	struct xfrm_policy *xp = xfrm_policy_alloc(&init_net, GFP_KERNEL);
 	int err;
 
 	if (!xp) {
@@ -2291,7 +2291,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
 	if (p->dir > XFRM_POLICY_OUT)
 		return NULL;
 
-	xp = xfrm_policy_alloc(GFP_KERNEL);
+	xp = xfrm_policy_alloc(&init_net, GFP_KERNEL);
 	if (xp == NULL) {
 		*dir = -ENOBUFS;
 		return NULL;
-- 
1.5.6.5


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

* [PATCH 15/53] netns xfrm: per-netns policy list
  2008-11-25 17:26                         ` [PATCH 14/53] netns xfrm: add struct xfrm_policy::xp_net Alexey Dobriyan
@ 2008-11-25 17:26                           ` Alexey Dobriyan
  2008-11-25 17:26                             ` [PATCH 16/53] netns xfrm: per-netns xfrm_policy_byidx hash Alexey Dobriyan
  2008-11-26  1:22                             ` [PATCH 15/53] netns xfrm: per-netns policy list David Miller
  2008-11-26  1:21                           ` [PATCH 14/53] netns xfrm: add struct xfrm_policy::xp_net David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    2 ++
 net/xfrm/xfrm_policy.c   |   12 ++++++------
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 2a383c8..6648924 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -25,6 +25,8 @@ struct netns_xfrm {
 	struct work_struct	state_gc_work;
 
 	wait_queue_head_t	km_waitq;
+
+	struct list_head	policy_all;
 };
 
 #endif
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 3eccefa..aabc7f2 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -46,7 +46,6 @@ EXPORT_SYMBOL(xfrm_cfg_mutex);
 
 static DEFINE_RWLOCK(xfrm_policy_lock);
 
-static struct list_head xfrm_policy_all;
 unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2];
 EXPORT_SYMBOL(xfrm_policy_count);
 
@@ -615,7 +614,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 	policy->curlft.use_time = 0;
 	if (!mod_timer(&policy->timer, jiffies + HZ))
 		xfrm_pol_hold(policy);
-	list_add(&policy->walk.all, &xfrm_policy_all);
+	list_add(&policy->walk.all, &init_net.xfrm.policy_all);
 	write_unlock_bh(&xfrm_policy_lock);
 
 	if (delpol)
@@ -881,10 +880,10 @@ int xfrm_policy_walk(struct xfrm_policy_walk *walk,
 
 	write_lock_bh(&xfrm_policy_lock);
 	if (list_empty(&walk->walk.all))
-		x = list_first_entry(&xfrm_policy_all, struct xfrm_policy_walk_entry, all);
+		x = list_first_entry(&init_net.xfrm.policy_all, struct xfrm_policy_walk_entry, all);
 	else
 		x = list_entry(&walk->walk.all, struct xfrm_policy_walk_entry, all);
-	list_for_each_entry_from(x, &xfrm_policy_all, all) {
+	list_for_each_entry_from(x, &init_net.xfrm.policy_all, all) {
 		if (x->dead)
 			continue;
 		pol = container_of(x, struct xfrm_policy, walk);
@@ -1086,7 +1085,7 @@ static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
 	struct hlist_head *chain = policy_hash_bysel(&pol->selector,
 						     pol->family, dir);
 
-	list_add(&pol->walk.all, &xfrm_policy_all);
+	list_add(&pol->walk.all, &init_net.xfrm.policy_all);
 	hlist_add_head(&pol->bydst, chain);
 	hlist_add_head(&pol->byidx, xfrm_policy_byidx+idx_hash(pol->index));
 	xfrm_policy_count[dir]++;
@@ -2426,7 +2425,7 @@ static int __net_init xfrm_policy_init(struct net *net)
 			panic("XFRM: failed to allocate bydst hash\n");
 	}
 
-	INIT_LIST_HEAD(&xfrm_policy_all);
+	INIT_LIST_HEAD(&net->xfrm.policy_all);
 	if (net_eq(net, &init_net))
 		register_netdevice_notifier(&xfrm_dev_notifier);
 	return 0;
@@ -2434,6 +2433,7 @@ static int __net_init xfrm_policy_init(struct net *net)
 
 static void xfrm_policy_fini(struct net *net)
 {
+	WARN_ON(!list_empty(&net->xfrm.policy_all));
 }
 
 static int __net_init xfrm_net_init(struct net *net)
-- 
1.5.6.5


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

* [PATCH 16/53] netns xfrm: per-netns xfrm_policy_byidx hash
  2008-11-25 17:26                           ` [PATCH 15/53] netns xfrm: per-netns policy list Alexey Dobriyan
@ 2008-11-25 17:26                             ` Alexey Dobriyan
  2008-11-25 17:26                               ` [PATCH 17/53] netns xfrm: per-netns xfrm_policy_byidx hashmask Alexey Dobriyan
  2008-11-26  1:22                               ` [PATCH 16/53] netns xfrm: per-netns xfrm_policy_byidx hash David Miller
  2008-11-26  1:22                             ` [PATCH 15/53] netns xfrm: per-netns policy list David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    1 +
 net/xfrm/xfrm_policy.c   |   28 ++++++++++++++++++----------
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 6648924..5cd7d06 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -27,6 +27,7 @@ struct netns_xfrm {
 	wait_queue_head_t	km_waitq;
 
 	struct list_head	policy_all;
+	struct hlist_head	*policy_byidx;
 };
 
 #endif
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index aabc7f2..700cdd7 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -329,7 +329,6 @@ struct xfrm_policy_hash {
 
 static struct hlist_head xfrm_policy_inexact[XFRM_POLICY_MAX*2];
 static struct xfrm_policy_hash xfrm_policy_bydst[XFRM_POLICY_MAX*2] __read_mostly;
-static struct hlist_head *xfrm_policy_byidx __read_mostly;
 static unsigned int xfrm_idx_hmask __read_mostly;
 static unsigned int xfrm_policy_hashmax __read_mostly = 1 * 1024 * 1024;
 
@@ -438,7 +437,7 @@ static void xfrm_byidx_resize(int total)
 	unsigned int hmask = xfrm_idx_hmask;
 	unsigned int nhashmask = xfrm_new_hash_mask(hmask);
 	unsigned int nsize = (nhashmask + 1) * sizeof(struct hlist_head);
-	struct hlist_head *oidx = xfrm_policy_byidx;
+	struct hlist_head *oidx = init_net.xfrm.policy_byidx;
 	struct hlist_head *nidx = xfrm_hash_alloc(nsize);
 	int i;
 
@@ -450,7 +449,7 @@ static void xfrm_byidx_resize(int total)
 	for (i = hmask; i >= 0; i--)
 		xfrm_idx_hash_transfer(oidx + i, nidx, nhashmask);
 
-	xfrm_policy_byidx = nidx;
+	init_net.xfrm.policy_byidx = nidx;
 	xfrm_idx_hmask = nhashmask;
 
 	write_unlock_bh(&xfrm_policy_lock);
@@ -536,7 +535,7 @@ static u32 xfrm_gen_index(int dir)
 		idx_generator += 8;
 		if (idx == 0)
 			idx = 8;
-		list = xfrm_policy_byidx + idx_hash(idx);
+		list = init_net.xfrm.policy_byidx + idx_hash(idx);
 		found = 0;
 		hlist_for_each_entry(p, entry, list, byidx) {
 			if (p->index == idx) {
@@ -609,7 +608,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 		xfrm_policy_count[dir]--;
 	}
 	policy->index = delpol ? delpol->index : xfrm_gen_index(dir);
-	hlist_add_head(&policy->byidx, xfrm_policy_byidx+idx_hash(policy->index));
+	hlist_add_head(&policy->byidx, init_net.xfrm.policy_byidx+idx_hash(policy->index));
 	policy->curlft.add_time = get_seconds();
 	policy->curlft.use_time = 0;
 	if (!mod_timer(&policy->timer, jiffies + HZ))
@@ -711,7 +710,7 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
 
 	*err = 0;
 	write_lock_bh(&xfrm_policy_lock);
-	chain = xfrm_policy_byidx + idx_hash(id);
+	chain = init_net.xfrm.policy_byidx + idx_hash(id);
 	ret = NULL;
 	hlist_for_each_entry(pol, entry, chain, byidx) {
 		if (pol->type == type && pol->index == id) {
@@ -1087,7 +1086,7 @@ static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
 
 	list_add(&pol->walk.all, &init_net.xfrm.policy_all);
 	hlist_add_head(&pol->bydst, chain);
-	hlist_add_head(&pol->byidx, xfrm_policy_byidx+idx_hash(pol->index));
+	hlist_add_head(&pol->byidx, init_net.xfrm.policy_byidx+idx_hash(pol->index));
 	xfrm_policy_count[dir]++;
 	xfrm_pol_hold(pol);
 
@@ -2408,10 +2407,10 @@ static int __net_init xfrm_policy_init(struct net *net)
 	hmask = 8 - 1;
 	sz = (hmask+1) * sizeof(struct hlist_head);
 
-	xfrm_policy_byidx = xfrm_hash_alloc(sz);
+	net->xfrm.policy_byidx = xfrm_hash_alloc(sz);
+	if (!net->xfrm.policy_byidx)
+		goto out_byidx;
 	xfrm_idx_hmask = hmask;
-	if (!xfrm_policy_byidx)
-		panic("XFRM: failed to allocate byidx hash\n");
 
 	for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) {
 		struct xfrm_policy_hash *htab;
@@ -2429,11 +2428,20 @@ static int __net_init xfrm_policy_init(struct net *net)
 	if (net_eq(net, &init_net))
 		register_netdevice_notifier(&xfrm_dev_notifier);
 	return 0;
+
+out_byidx:
+	return -ENOMEM;
 }
 
 static void xfrm_policy_fini(struct net *net)
 {
+	unsigned int sz;
+
 	WARN_ON(!list_empty(&net->xfrm.policy_all));
+
+	sz = (xfrm_idx_hmask + 1) * sizeof(struct hlist_head);
+	WARN_ON(!hlist_empty(net->xfrm.policy_byidx));
+	xfrm_hash_free(net->xfrm.policy_byidx, sz);
 }
 
 static int __net_init xfrm_net_init(struct net *net)
-- 
1.5.6.5


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

* [PATCH 17/53] netns xfrm: per-netns xfrm_policy_byidx hashmask
  2008-11-25 17:26                             ` [PATCH 16/53] netns xfrm: per-netns xfrm_policy_byidx hash Alexey Dobriyan
@ 2008-11-25 17:26                               ` Alexey Dobriyan
  2008-11-25 17:26                                 ` [PATCH 18/53] netns xfrm: per-netns inexact policies Alexey Dobriyan
  2008-11-26  1:23                                 ` [PATCH 17/53] netns xfrm: per-netns xfrm_policy_byidx hashmask David Miller
  2008-11-26  1:22                               ` [PATCH 16/53] netns xfrm: per-netns xfrm_policy_byidx hash David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Per-netns hashes are independently resizeable.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    1 +
 net/xfrm/xfrm_policy.c   |   15 +++++++--------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 5cd7d06..42dc318 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -28,6 +28,7 @@ struct netns_xfrm {
 
 	struct list_head	policy_all;
 	struct hlist_head	*policy_byidx;
+	unsigned int		policy_idx_hmask;
 };
 
 #endif
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 700cdd7..9e37a44 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -329,12 +329,11 @@ struct xfrm_policy_hash {
 
 static struct hlist_head xfrm_policy_inexact[XFRM_POLICY_MAX*2];
 static struct xfrm_policy_hash xfrm_policy_bydst[XFRM_POLICY_MAX*2] __read_mostly;
-static unsigned int xfrm_idx_hmask __read_mostly;
 static unsigned int xfrm_policy_hashmax __read_mostly = 1 * 1024 * 1024;
 
 static inline unsigned int idx_hash(u32 index)
 {
-	return __idx_hash(index, xfrm_idx_hmask);
+	return __idx_hash(index, init_net.xfrm.policy_idx_hmask);
 }
 
 static struct hlist_head *policy_hash_bysel(struct xfrm_selector *sel, unsigned short family, int dir)
@@ -434,7 +433,7 @@ static void xfrm_bydst_resize(int dir)
 
 static void xfrm_byidx_resize(int total)
 {
-	unsigned int hmask = xfrm_idx_hmask;
+	unsigned int hmask = init_net.xfrm.policy_idx_hmask;
 	unsigned int nhashmask = xfrm_new_hash_mask(hmask);
 	unsigned int nsize = (nhashmask + 1) * sizeof(struct hlist_head);
 	struct hlist_head *oidx = init_net.xfrm.policy_byidx;
@@ -450,7 +449,7 @@ static void xfrm_byidx_resize(int total)
 		xfrm_idx_hash_transfer(oidx + i, nidx, nhashmask);
 
 	init_net.xfrm.policy_byidx = nidx;
-	xfrm_idx_hmask = nhashmask;
+	init_net.xfrm.policy_idx_hmask = nhashmask;
 
 	write_unlock_bh(&xfrm_policy_lock);
 
@@ -474,7 +473,7 @@ static inline int xfrm_bydst_should_resize(int dir, int *total)
 
 static inline int xfrm_byidx_should_resize(int total)
 {
-	unsigned int hmask = xfrm_idx_hmask;
+	unsigned int hmask = init_net.xfrm.policy_idx_hmask;
 
 	if ((hmask + 1) < xfrm_policy_hashmax &&
 	    total > hmask)
@@ -492,7 +491,7 @@ void xfrm_spd_getinfo(struct xfrmk_spdinfo *si)
 	si->inscnt = xfrm_policy_count[XFRM_POLICY_IN+XFRM_POLICY_MAX];
 	si->outscnt = xfrm_policy_count[XFRM_POLICY_OUT+XFRM_POLICY_MAX];
 	si->fwdscnt = xfrm_policy_count[XFRM_POLICY_FWD+XFRM_POLICY_MAX];
-	si->spdhcnt = xfrm_idx_hmask;
+	si->spdhcnt = init_net.xfrm.policy_idx_hmask;
 	si->spdhmcnt = xfrm_policy_hashmax;
 	read_unlock_bh(&xfrm_policy_lock);
 }
@@ -2410,7 +2409,7 @@ static int __net_init xfrm_policy_init(struct net *net)
 	net->xfrm.policy_byidx = xfrm_hash_alloc(sz);
 	if (!net->xfrm.policy_byidx)
 		goto out_byidx;
-	xfrm_idx_hmask = hmask;
+	net->xfrm.policy_idx_hmask = hmask;
 
 	for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) {
 		struct xfrm_policy_hash *htab;
@@ -2439,7 +2438,7 @@ static void xfrm_policy_fini(struct net *net)
 
 	WARN_ON(!list_empty(&net->xfrm.policy_all));
 
-	sz = (xfrm_idx_hmask + 1) * sizeof(struct hlist_head);
+	sz = (net->xfrm.policy_idx_hmask + 1) * sizeof(struct hlist_head);
 	WARN_ON(!hlist_empty(net->xfrm.policy_byidx));
 	xfrm_hash_free(net->xfrm.policy_byidx, sz);
 }
-- 
1.5.6.5


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

* [PATCH 18/53] netns xfrm: per-netns inexact policies
  2008-11-25 17:26                               ` [PATCH 17/53] netns xfrm: per-netns xfrm_policy_byidx hashmask Alexey Dobriyan
@ 2008-11-25 17:26                                 ` Alexey Dobriyan
  2008-11-25 17:26                                   ` [PATCH 19/53] netns xfrm: per-netns xfrm_policy_bydst hash Alexey Dobriyan
  2008-11-26  1:23                                   ` [PATCH 18/53] netns xfrm: per-netns inexact policies David Miller
  2008-11-26  1:23                                 ` [PATCH 17/53] netns xfrm: per-netns xfrm_policy_byidx hashmask David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    2 ++
 net/xfrm/xfrm_policy.c   |   20 ++++++++++++--------
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 42dc318..c756831 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -4,6 +4,7 @@
 #include <linux/list.h>
 #include <linux/wait.h>
 #include <linux/workqueue.h>
+#include <linux/xfrm.h>
 
 struct netns_xfrm {
 	struct list_head	state_all;
@@ -29,6 +30,7 @@ struct netns_xfrm {
 	struct list_head	policy_all;
 	struct hlist_head	*policy_byidx;
 	unsigned int		policy_idx_hmask;
+	struct hlist_head	policy_inexact[XFRM_POLICY_MAX * 2];
 };
 
 #endif
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 9e37a44..ba4e95b 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -327,7 +327,6 @@ struct xfrm_policy_hash {
 	unsigned int		hmask;
 };
 
-static struct hlist_head xfrm_policy_inexact[XFRM_POLICY_MAX*2];
 static struct xfrm_policy_hash xfrm_policy_bydst[XFRM_POLICY_MAX*2] __read_mostly;
 static unsigned int xfrm_policy_hashmax __read_mostly = 1 * 1024 * 1024;
 
@@ -342,7 +341,7 @@ static struct hlist_head *policy_hash_bysel(struct xfrm_selector *sel, unsigned
 	unsigned int hash = __sel_hash(sel, family, hmask);
 
 	return (hash == hmask + 1 ?
-		&xfrm_policy_inexact[dir] :
+		&init_net.xfrm.policy_inexact[dir] :
 		xfrm_policy_bydst[dir].table + hash);
 }
 
@@ -752,7 +751,7 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
 		int i;
 
 		hlist_for_each_entry(pol, entry,
-				     &xfrm_policy_inexact[dir], bydst) {
+				     &init_net.xfrm.policy_inexact[dir], bydst) {
 			if (pol->type != type)
 				continue;
 			err = security_xfrm_policy_delete(pol->security);
@@ -810,7 +809,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
 		killed = 0;
 	again1:
 		hlist_for_each_entry(pol, entry,
-				     &xfrm_policy_inexact[dir], bydst) {
+				     &init_net.xfrm.policy_inexact[dir], bydst) {
 			if (pol->type != type)
 				continue;
 			hlist_del(&pol->bydst);
@@ -983,7 +982,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
 			break;
 		}
 	}
-	chain = &xfrm_policy_inexact[dir];
+	chain = &init_net.xfrm.policy_inexact[dir];
 	hlist_for_each_entry(pol, entry, chain, bydst) {
 		err = xfrm_policy_match(pol, fl, type, family, dir);
 		if (err) {
@@ -2152,7 +2151,7 @@ static void xfrm_prune_bundles(int (*func)(struct dst_entry *))
 		int i;
 
 		hlist_for_each_entry(pol, entry,
-				     &xfrm_policy_inexact[dir], bydst)
+				     &init_net.xfrm.policy_inexact[dir], bydst)
 			prune_one_bundle(pol, func, &gc_list);
 
 		table = xfrm_policy_bydst[dir].table;
@@ -2414,7 +2413,7 @@ static int __net_init xfrm_policy_init(struct net *net)
 	for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) {
 		struct xfrm_policy_hash *htab;
 
-		INIT_HLIST_HEAD(&xfrm_policy_inexact[dir]);
+		INIT_HLIST_HEAD(&net->xfrm.policy_inexact[dir]);
 
 		htab = &xfrm_policy_bydst[dir];
 		htab->table = xfrm_hash_alloc(sz);
@@ -2435,9 +2434,14 @@ out_byidx:
 static void xfrm_policy_fini(struct net *net)
 {
 	unsigned int sz;
+	int dir;
 
 	WARN_ON(!list_empty(&net->xfrm.policy_all));
 
+	for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) {
+		WARN_ON(!hlist_empty(&net->xfrm.policy_inexact[dir]));
+	}
+
 	sz = (net->xfrm.policy_idx_hmask + 1) * sizeof(struct hlist_head);
 	WARN_ON(!hlist_empty(net->xfrm.policy_byidx));
 	xfrm_hash_free(net->xfrm.policy_byidx, sz);
@@ -2590,7 +2594,7 @@ static struct xfrm_policy * xfrm_migrate_policy_find(struct xfrm_selector *sel,
 			break;
 		}
 	}
-	chain = &xfrm_policy_inexact[dir];
+	chain = &init_net.xfrm.policy_inexact[dir];
 	hlist_for_each_entry(pol, entry, chain, bydst) {
 		if (xfrm_migrate_selector_match(sel, &pol->selector) &&
 		    pol->type == type &&
-- 
1.5.6.5


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

* [PATCH 19/53] netns xfrm: per-netns xfrm_policy_bydst hash
  2008-11-25 17:26                                 ` [PATCH 18/53] netns xfrm: per-netns inexact policies Alexey Dobriyan
@ 2008-11-25 17:26                                   ` Alexey Dobriyan
  2008-11-25 17:26                                     ` [PATCH 20/53] netns xfrm: per-netns policy counts Alexey Dobriyan
  2008-11-26  1:23                                     ` [PATCH 19/53] netns xfrm: per-netns xfrm_policy_bydst hash David Miller
  2008-11-26  1:23                                   ` [PATCH 18/53] netns xfrm: per-netns inexact policies David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    6 +++++
 net/xfrm/xfrm_policy.c   |   57 ++++++++++++++++++++++++++-------------------
 2 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index c756831..39cfa79 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -6,6 +6,11 @@
 #include <linux/workqueue.h>
 #include <linux/xfrm.h>
 
+struct xfrm_policy_hash {
+	struct hlist_head	*table;
+	unsigned int		hmask;
+};
+
 struct netns_xfrm {
 	struct list_head	state_all;
 	/*
@@ -31,6 +36,7 @@ struct netns_xfrm {
 	struct hlist_head	*policy_byidx;
 	unsigned int		policy_idx_hmask;
 	struct hlist_head	policy_inexact[XFRM_POLICY_MAX * 2];
+	struct xfrm_policy_hash	policy_bydst[XFRM_POLICY_MAX * 2];
 };
 
 #endif
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index ba4e95b..929b2fd 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -322,12 +322,6 @@ static void xfrm_policy_kill(struct xfrm_policy *policy)
 	schedule_work(&xfrm_policy_gc_work);
 }
 
-struct xfrm_policy_hash {
-	struct hlist_head	*table;
-	unsigned int		hmask;
-};
-
-static struct xfrm_policy_hash xfrm_policy_bydst[XFRM_POLICY_MAX*2] __read_mostly;
 static unsigned int xfrm_policy_hashmax __read_mostly = 1 * 1024 * 1024;
 
 static inline unsigned int idx_hash(u32 index)
@@ -337,20 +331,20 @@ static inline unsigned int idx_hash(u32 index)
 
 static struct hlist_head *policy_hash_bysel(struct xfrm_selector *sel, unsigned short family, int dir)
 {
-	unsigned int hmask = xfrm_policy_bydst[dir].hmask;
+	unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask;
 	unsigned int hash = __sel_hash(sel, family, hmask);
 
 	return (hash == hmask + 1 ?
 		&init_net.xfrm.policy_inexact[dir] :
-		xfrm_policy_bydst[dir].table + hash);
+		init_net.xfrm.policy_bydst[dir].table + hash);
 }
 
 static struct hlist_head *policy_hash_direct(xfrm_address_t *daddr, xfrm_address_t *saddr, unsigned short family, int dir)
 {
-	unsigned int hmask = xfrm_policy_bydst[dir].hmask;
+	unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask;
 	unsigned int hash = __addr_hash(daddr, saddr, family, hmask);
 
-	return xfrm_policy_bydst[dir].table + hash;
+	return init_net.xfrm.policy_bydst[dir].table + hash;
 }
 
 static void xfrm_dst_hash_transfer(struct hlist_head *list,
@@ -407,10 +401,10 @@ static unsigned long xfrm_new_hash_mask(unsigned int old_hmask)
 
 static void xfrm_bydst_resize(int dir)
 {
-	unsigned int hmask = xfrm_policy_bydst[dir].hmask;
+	unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask;
 	unsigned int nhashmask = xfrm_new_hash_mask(hmask);
 	unsigned int nsize = (nhashmask + 1) * sizeof(struct hlist_head);
-	struct hlist_head *odst = xfrm_policy_bydst[dir].table;
+	struct hlist_head *odst = init_net.xfrm.policy_bydst[dir].table;
 	struct hlist_head *ndst = xfrm_hash_alloc(nsize);
 	int i;
 
@@ -422,8 +416,8 @@ static void xfrm_bydst_resize(int dir)
 	for (i = hmask; i >= 0; i--)
 		xfrm_dst_hash_transfer(odst + i, ndst, nhashmask);
 
-	xfrm_policy_bydst[dir].table = ndst;
-	xfrm_policy_bydst[dir].hmask = nhashmask;
+	init_net.xfrm.policy_bydst[dir].table = ndst;
+	init_net.xfrm.policy_bydst[dir].hmask = nhashmask;
 
 	write_unlock_bh(&xfrm_policy_lock);
 
@@ -458,7 +452,7 @@ static void xfrm_byidx_resize(int total)
 static inline int xfrm_bydst_should_resize(int dir, int *total)
 {
 	unsigned int cnt = xfrm_policy_count[dir];
-	unsigned int hmask = xfrm_policy_bydst[dir].hmask;
+	unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask;
 
 	if (total)
 		*total += cnt;
@@ -763,9 +757,9 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
 				return err;
 			}
 		}
-		for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
+		for (i = init_net.xfrm.policy_bydst[dir].hmask; i >= 0; i--) {
 			hlist_for_each_entry(pol, entry,
-					     xfrm_policy_bydst[dir].table + i,
+					     init_net.xfrm.policy_bydst[dir].table + i,
 					     bydst) {
 				if (pol->type != type)
 					continue;
@@ -827,10 +821,10 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
 			goto again1;
 		}
 
-		for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
+		for (i = init_net.xfrm.policy_bydst[dir].hmask; i >= 0; i--) {
 	again2:
 			hlist_for_each_entry(pol, entry,
-					     xfrm_policy_bydst[dir].table + i,
+					     init_net.xfrm.policy_bydst[dir].table + i,
 					     bydst) {
 				if (pol->type != type)
 					continue;
@@ -2154,8 +2148,8 @@ static void xfrm_prune_bundles(int (*func)(struct dst_entry *))
 				     &init_net.xfrm.policy_inexact[dir], bydst)
 			prune_one_bundle(pol, func, &gc_list);
 
-		table = xfrm_policy_bydst[dir].table;
-		for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
+		table = init_net.xfrm.policy_bydst[dir].table;
+		for (i = init_net.xfrm.policy_bydst[dir].hmask; i >= 0; i--) {
 			hlist_for_each_entry(pol, entry, table + i, bydst)
 				prune_one_bundle(pol, func, &gc_list);
 		}
@@ -2415,11 +2409,11 @@ static int __net_init xfrm_policy_init(struct net *net)
 
 		INIT_HLIST_HEAD(&net->xfrm.policy_inexact[dir]);
 
-		htab = &xfrm_policy_bydst[dir];
+		htab = &net->xfrm.policy_bydst[dir];
 		htab->table = xfrm_hash_alloc(sz);
-		htab->hmask = hmask;
 		if (!htab->table)
-			panic("XFRM: failed to allocate bydst hash\n");
+			goto out_bydst;
+		htab->hmask = hmask;
 	}
 
 	INIT_LIST_HEAD(&net->xfrm.policy_all);
@@ -2427,6 +2421,14 @@ static int __net_init xfrm_policy_init(struct net *net)
 		register_netdevice_notifier(&xfrm_dev_notifier);
 	return 0;
 
+out_bydst:
+	for (dir--; dir >= 0; dir--) {
+		struct xfrm_policy_hash *htab;
+
+		htab = &net->xfrm.policy_bydst[dir];
+		xfrm_hash_free(htab->table, sz);
+	}
+	xfrm_hash_free(net->xfrm.policy_byidx, sz);
 out_byidx:
 	return -ENOMEM;
 }
@@ -2439,7 +2441,14 @@ static void xfrm_policy_fini(struct net *net)
 	WARN_ON(!list_empty(&net->xfrm.policy_all));
 
 	for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) {
+		struct xfrm_policy_hash *htab;
+
 		WARN_ON(!hlist_empty(&net->xfrm.policy_inexact[dir]));
+
+		htab = &net->xfrm.policy_bydst[dir];
+		sz = (htab->hmask + 1);
+		WARN_ON(!hlist_empty(htab->table));
+		xfrm_hash_free(htab->table, sz);
 	}
 
 	sz = (net->xfrm.policy_idx_hmask + 1) * sizeof(struct hlist_head);
-- 
1.5.6.5


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

* [PATCH 20/53] netns xfrm: per-netns policy counts
  2008-11-25 17:26                                   ` [PATCH 19/53] netns xfrm: per-netns xfrm_policy_bydst hash Alexey Dobriyan
@ 2008-11-25 17:26                                     ` Alexey Dobriyan
  2008-11-25 17:26                                       ` [PATCH 21/53] netns xfrm: per-netns policy hash resizing work Alexey Dobriyan
  2008-11-26  1:24                                       ` [PATCH 20/53] netns xfrm: per-netns policy counts David Miller
  2008-11-26  1:23                                     ` [PATCH 19/53] netns xfrm: per-netns xfrm_policy_bydst hash David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    1 +
 include/net/xfrm.h       |    6 ++----
 net/xfrm/xfrm_policy.c   |   34 ++++++++++++++++------------------
 3 files changed, 19 insertions(+), 22 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 39cfa79..d5aadf0 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -37,6 +37,7 @@ struct netns_xfrm {
 	unsigned int		policy_idx_hmask;
 	struct hlist_head	policy_inexact[XFRM_POLICY_MAX * 2];
 	struct xfrm_policy_hash	policy_bydst[XFRM_POLICY_MAX * 2];
+	unsigned int		policy_count[XFRM_POLICY_MAX * 2];
 };
 
 #endif
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 1ab1756..8699620 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -559,8 +559,6 @@ struct xfrm_mgr
 extern int xfrm_register_km(struct xfrm_mgr *km);
 extern int xfrm_unregister_km(struct xfrm_mgr *km);
 
-extern unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2];
-
 /*
  * This structure is used for the duration where packets are being
  * transformed by IPsec.  As soon as the packet leaves IPsec the
@@ -999,7 +997,7 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir,
 	if (sk && sk->sk_policy[XFRM_POLICY_IN])
 		return __xfrm_policy_check(sk, ndir, skb, family);
 
-	return	(!xfrm_policy_count[dir] && !skb->sp) ||
+	return	(!init_net.xfrm.policy_count[dir] && !skb->sp) ||
 		(skb->dst->flags & DST_NOPOLICY) ||
 		__xfrm_policy_check(sk, ndir, skb, family);
 }
@@ -1051,7 +1049,7 @@ extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
 
 static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
 {
-	return	!xfrm_policy_count[XFRM_POLICY_OUT] ||
+	return	!init_net.xfrm.policy_count[XFRM_POLICY_OUT] ||
 		(skb->dst->flags & DST_NOXFRM) ||
 		__xfrm_route_forward(skb, family);
 }
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 929b2fd..630ec04 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -46,9 +46,6 @@ EXPORT_SYMBOL(xfrm_cfg_mutex);
 
 static DEFINE_RWLOCK(xfrm_policy_lock);
 
-unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2];
-EXPORT_SYMBOL(xfrm_policy_count);
-
 static DEFINE_RWLOCK(xfrm_policy_afinfo_lock);
 static struct xfrm_policy_afinfo *xfrm_policy_afinfo[NPROTO];
 
@@ -451,7 +448,7 @@ static void xfrm_byidx_resize(int total)
 
 static inline int xfrm_bydst_should_resize(int dir, int *total)
 {
-	unsigned int cnt = xfrm_policy_count[dir];
+	unsigned int cnt = init_net.xfrm.policy_count[dir];
 	unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask;
 
 	if (total)
@@ -478,12 +475,12 @@ static inline int xfrm_byidx_should_resize(int total)
 void xfrm_spd_getinfo(struct xfrmk_spdinfo *si)
 {
 	read_lock_bh(&xfrm_policy_lock);
-	si->incnt = xfrm_policy_count[XFRM_POLICY_IN];
-	si->outcnt = xfrm_policy_count[XFRM_POLICY_OUT];
-	si->fwdcnt = xfrm_policy_count[XFRM_POLICY_FWD];
-	si->inscnt = xfrm_policy_count[XFRM_POLICY_IN+XFRM_POLICY_MAX];
-	si->outscnt = xfrm_policy_count[XFRM_POLICY_OUT+XFRM_POLICY_MAX];
-	si->fwdscnt = xfrm_policy_count[XFRM_POLICY_FWD+XFRM_POLICY_MAX];
+	si->incnt = init_net.xfrm.policy_count[XFRM_POLICY_IN];
+	si->outcnt = init_net.xfrm.policy_count[XFRM_POLICY_OUT];
+	si->fwdcnt = init_net.xfrm.policy_count[XFRM_POLICY_FWD];
+	si->inscnt = init_net.xfrm.policy_count[XFRM_POLICY_IN+XFRM_POLICY_MAX];
+	si->outscnt = init_net.xfrm.policy_count[XFRM_POLICY_OUT+XFRM_POLICY_MAX];
+	si->fwdscnt = init_net.xfrm.policy_count[XFRM_POLICY_FWD+XFRM_POLICY_MAX];
 	si->spdhcnt = init_net.xfrm.policy_idx_hmask;
 	si->spdhmcnt = xfrm_policy_hashmax;
 	read_unlock_bh(&xfrm_policy_lock);
@@ -591,13 +588,13 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 	else
 		hlist_add_head(&policy->bydst, chain);
 	xfrm_pol_hold(policy);
-	xfrm_policy_count[dir]++;
+	init_net.xfrm.policy_count[dir]++;
 	atomic_inc(&flow_cache_genid);
 	if (delpol) {
 		hlist_del(&delpol->bydst);
 		hlist_del(&delpol->byidx);
 		list_del(&delpol->walk.all);
-		xfrm_policy_count[dir]--;
+		init_net.xfrm.policy_count[dir]--;
 	}
 	policy->index = delpol ? delpol->index : xfrm_gen_index(dir);
 	hlist_add_head(&policy->byidx, init_net.xfrm.policy_byidx+idx_hash(policy->index));
@@ -673,7 +670,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
 				hlist_del(&pol->bydst);
 				hlist_del(&pol->byidx);
 				list_del(&pol->walk.all);
-				xfrm_policy_count[dir]--;
+				init_net.xfrm.policy_count[dir]--;
 			}
 			ret = pol;
 			break;
@@ -717,7 +714,7 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
 				hlist_del(&pol->bydst);
 				hlist_del(&pol->byidx);
 				list_del(&pol->walk.all);
-				xfrm_policy_count[dir]--;
+				init_net.xfrm.policy_count[dir]--;
 			}
 			ret = pol;
 			break;
@@ -845,7 +842,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
 			}
 		}
 
-		xfrm_policy_count[dir] -= killed;
+		init_net.xfrm.policy_count[dir] -= killed;
 	}
 	atomic_inc(&flow_cache_genid);
 out:
@@ -1079,7 +1076,7 @@ static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
 	list_add(&pol->walk.all, &init_net.xfrm.policy_all);
 	hlist_add_head(&pol->bydst, chain);
 	hlist_add_head(&pol->byidx, init_net.xfrm.policy_byidx+idx_hash(pol->index));
-	xfrm_policy_count[dir]++;
+	init_net.xfrm.policy_count[dir]++;
 	xfrm_pol_hold(pol);
 
 	if (xfrm_bydst_should_resize(dir, NULL))
@@ -1095,7 +1092,7 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
 	hlist_del(&pol->bydst);
 	hlist_del(&pol->byidx);
 	list_del(&pol->walk.all);
-	xfrm_policy_count[dir]--;
+	init_net.xfrm.policy_count[dir]--;
 
 	return pol;
 }
@@ -1574,7 +1571,7 @@ restart:
 	if (!policy) {
 		/* To accelerate a bit...  */
 		if ((dst_orig->flags & DST_NOXFRM) ||
-		    !xfrm_policy_count[XFRM_POLICY_OUT])
+		    !init_net.xfrm.policy_count[XFRM_POLICY_OUT])
 			goto nopol;
 
 		policy = flow_cache_lookup(fl, dst_orig->ops->family,
@@ -2407,6 +2404,7 @@ static int __net_init xfrm_policy_init(struct net *net)
 	for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) {
 		struct xfrm_policy_hash *htab;
 
+		net->xfrm.policy_count[dir] = 0;
 		INIT_HLIST_HEAD(&net->xfrm.policy_inexact[dir]);
 
 		htab = &net->xfrm.policy_bydst[dir];
-- 
1.5.6.5


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

* [PATCH 21/53] netns xfrm: per-netns policy hash resizing work
  2008-11-25 17:26                                     ` [PATCH 20/53] netns xfrm: per-netns policy counts Alexey Dobriyan
@ 2008-11-25 17:26                                       ` Alexey Dobriyan
  2008-11-25 17:26                                         ` [PATCH 22/53] netns xfrm: propagate netns into bydst/bysrc/byspi hash functions Alexey Dobriyan
  2008-11-26  1:29                                         ` [PATCH 21/53] netns xfrm: per-netns policy hash resizing work David Miller
  2008-11-26  1:24                                       ` [PATCH 20/53] netns xfrm: per-netns policy counts David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    1 +
 net/xfrm/xfrm_policy.c   |   52 +++++++++++++++++++++++-----------------------
 2 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index d5aadf0..c53d173 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -38,6 +38,7 @@ struct netns_xfrm {
 	struct hlist_head	policy_inexact[XFRM_POLICY_MAX * 2];
 	struct xfrm_policy_hash	policy_bydst[XFRM_POLICY_MAX * 2];
 	unsigned int		policy_count[XFRM_POLICY_MAX * 2];
+	struct work_struct	policy_hash_work;
 };
 
 #endif
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 630ec04..1d30086 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -396,12 +396,12 @@ static unsigned long xfrm_new_hash_mask(unsigned int old_hmask)
 	return ((old_hmask + 1) << 1) - 1;
 }
 
-static void xfrm_bydst_resize(int dir)
+static void xfrm_bydst_resize(struct net *net, int dir)
 {
-	unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask;
+	unsigned int hmask = net->xfrm.policy_bydst[dir].hmask;
 	unsigned int nhashmask = xfrm_new_hash_mask(hmask);
 	unsigned int nsize = (nhashmask + 1) * sizeof(struct hlist_head);
-	struct hlist_head *odst = init_net.xfrm.policy_bydst[dir].table;
+	struct hlist_head *odst = net->xfrm.policy_bydst[dir].table;
 	struct hlist_head *ndst = xfrm_hash_alloc(nsize);
 	int i;
 
@@ -413,20 +413,20 @@ static void xfrm_bydst_resize(int dir)
 	for (i = hmask; i >= 0; i--)
 		xfrm_dst_hash_transfer(odst + i, ndst, nhashmask);
 
-	init_net.xfrm.policy_bydst[dir].table = ndst;
-	init_net.xfrm.policy_bydst[dir].hmask = nhashmask;
+	net->xfrm.policy_bydst[dir].table = ndst;
+	net->xfrm.policy_bydst[dir].hmask = nhashmask;
 
 	write_unlock_bh(&xfrm_policy_lock);
 
 	xfrm_hash_free(odst, (hmask + 1) * sizeof(struct hlist_head));
 }
 
-static void xfrm_byidx_resize(int total)
+static void xfrm_byidx_resize(struct net *net, int total)
 {
-	unsigned int hmask = init_net.xfrm.policy_idx_hmask;
+	unsigned int hmask = net->xfrm.policy_idx_hmask;
 	unsigned int nhashmask = xfrm_new_hash_mask(hmask);
 	unsigned int nsize = (nhashmask + 1) * sizeof(struct hlist_head);
-	struct hlist_head *oidx = init_net.xfrm.policy_byidx;
+	struct hlist_head *oidx = net->xfrm.policy_byidx;
 	struct hlist_head *nidx = xfrm_hash_alloc(nsize);
 	int i;
 
@@ -438,18 +438,18 @@ static void xfrm_byidx_resize(int total)
 	for (i = hmask; i >= 0; i--)
 		xfrm_idx_hash_transfer(oidx + i, nidx, nhashmask);
 
-	init_net.xfrm.policy_byidx = nidx;
-	init_net.xfrm.policy_idx_hmask = nhashmask;
+	net->xfrm.policy_byidx = nidx;
+	net->xfrm.policy_idx_hmask = nhashmask;
 
 	write_unlock_bh(&xfrm_policy_lock);
 
 	xfrm_hash_free(oidx, (hmask + 1) * sizeof(struct hlist_head));
 }
 
-static inline int xfrm_bydst_should_resize(int dir, int *total)
+static inline int xfrm_bydst_should_resize(struct net *net, int dir, int *total)
 {
-	unsigned int cnt = init_net.xfrm.policy_count[dir];
-	unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask;
+	unsigned int cnt = net->xfrm.policy_count[dir];
+	unsigned int hmask = net->xfrm.policy_bydst[dir].hmask;
 
 	if (total)
 		*total += cnt;
@@ -461,9 +461,9 @@ static inline int xfrm_bydst_should_resize(int dir, int *total)
 	return 0;
 }
 
-static inline int xfrm_byidx_should_resize(int total)
+static inline int xfrm_byidx_should_resize(struct net *net, int total)
 {
-	unsigned int hmask = init_net.xfrm.policy_idx_hmask;
+	unsigned int hmask = net->xfrm.policy_idx_hmask;
 
 	if ((hmask + 1) < xfrm_policy_hashmax &&
 	    total > hmask)
@@ -488,25 +488,24 @@ void xfrm_spd_getinfo(struct xfrmk_spdinfo *si)
 EXPORT_SYMBOL(xfrm_spd_getinfo);
 
 static DEFINE_MUTEX(hash_resize_mutex);
-static void xfrm_hash_resize(struct work_struct *__unused)
+static void xfrm_hash_resize(struct work_struct *work)
 {
+	struct net *net = container_of(work, struct net, xfrm.policy_hash_work);
 	int dir, total;
 
 	mutex_lock(&hash_resize_mutex);
 
 	total = 0;
 	for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) {
-		if (xfrm_bydst_should_resize(dir, &total))
-			xfrm_bydst_resize(dir);
+		if (xfrm_bydst_should_resize(net, dir, &total))
+			xfrm_bydst_resize(net, dir);
 	}
-	if (xfrm_byidx_should_resize(total))
-		xfrm_byidx_resize(total);
+	if (xfrm_byidx_should_resize(net, total))
+		xfrm_byidx_resize(net, total);
 
 	mutex_unlock(&hash_resize_mutex);
 }
 
-static DECLARE_WORK(xfrm_hash_work, xfrm_hash_resize);
-
 /* Generate new index... KAME seems to generate them ordered by cost
  * of an absolute inpredictability of ordering of rules. This will not pass. */
 static u32 xfrm_gen_index(int dir)
@@ -607,8 +606,8 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 
 	if (delpol)
 		xfrm_policy_kill(delpol);
-	else if (xfrm_bydst_should_resize(dir, NULL))
-		schedule_work(&xfrm_hash_work);
+	else if (xfrm_bydst_should_resize(&init_net, dir, NULL))
+		schedule_work(&init_net.xfrm.policy_hash_work);
 
 	read_lock_bh(&xfrm_policy_lock);
 	gc_list = NULL;
@@ -1079,8 +1078,8 @@ static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
 	init_net.xfrm.policy_count[dir]++;
 	xfrm_pol_hold(pol);
 
-	if (xfrm_bydst_should_resize(dir, NULL))
-		schedule_work(&xfrm_hash_work);
+	if (xfrm_bydst_should_resize(&init_net, dir, NULL))
+		schedule_work(&init_net.xfrm.policy_hash_work);
 }
 
 static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
@@ -2415,6 +2414,7 @@ static int __net_init xfrm_policy_init(struct net *net)
 	}
 
 	INIT_LIST_HEAD(&net->xfrm.policy_all);
+	INIT_WORK(&net->xfrm.policy_hash_work, xfrm_hash_resize);
 	if (net_eq(net, &init_net))
 		register_netdevice_notifier(&xfrm_dev_notifier);
 	return 0;
-- 
1.5.6.5


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

* [PATCH 22/53] netns xfrm: propagate netns into bydst/bysrc/byspi hash functions
  2008-11-25 17:26                                       ` [PATCH 21/53] netns xfrm: per-netns policy hash resizing work Alexey Dobriyan
@ 2008-11-25 17:26                                         ` Alexey Dobriyan
  2008-11-25 17:26                                           ` [PATCH 23/53] netns xfrm: trivial netns propagations Alexey Dobriyan
  2008-11-26  1:29                                           ` [PATCH 22/53] netns xfrm: propagate netns into bydst/bysrc/byspi hash functions David Miller
  2008-11-26  1:29                                         ` [PATCH 21/53] netns xfrm: per-netns policy hash resizing work David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/xfrm/xfrm_state.c |   44 +++++++++++++++++++++++---------------------
 1 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 24bd89e..72b2956 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -57,25 +57,27 @@ static void xfrm_audit_state_replay(struct xfrm_state *x,
 #define xfrm_audit_state_replay(x, s, sq)	do { ; } while (0)
 #endif /* CONFIG_AUDITSYSCALL */
 
-static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr,
+static inline unsigned int xfrm_dst_hash(struct net *net,
+					 xfrm_address_t *daddr,
 					 xfrm_address_t *saddr,
 					 u32 reqid,
 					 unsigned short family)
 {
-	return __xfrm_dst_hash(daddr, saddr, reqid, family, init_net.xfrm.state_hmask);
+	return __xfrm_dst_hash(daddr, saddr, reqid, family, net->xfrm.state_hmask);
 }
 
-static inline unsigned int xfrm_src_hash(xfrm_address_t *daddr,
+static inline unsigned int xfrm_src_hash(struct net *net,
+					 xfrm_address_t *daddr,
 					 xfrm_address_t *saddr,
 					 unsigned short family)
 {
-	return __xfrm_src_hash(daddr, saddr, family, init_net.xfrm.state_hmask);
+	return __xfrm_src_hash(daddr, saddr, family, net->xfrm.state_hmask);
 }
 
 static inline unsigned int
-xfrm_spi_hash(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
+xfrm_spi_hash(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
 {
-	return __xfrm_spi_hash(daddr, spi, proto, family, init_net.xfrm.state_hmask);
+	return __xfrm_spi_hash(daddr, spi, proto, family, net->xfrm.state_hmask);
 }
 
 static void xfrm_hash_transfer(struct hlist_head *list,
@@ -666,7 +668,7 @@ xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl,
 
 static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
 {
-	unsigned int h = xfrm_spi_hash(daddr, spi, proto, family);
+	unsigned int h = xfrm_spi_hash(&init_net, daddr, spi, proto, family);
 	struct xfrm_state *x;
 	struct hlist_node *entry;
 
@@ -698,7 +700,7 @@ static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi,
 
 static struct xfrm_state *__xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family)
 {
-	unsigned int h = xfrm_src_hash(daddr, saddr, family);
+	unsigned int h = xfrm_src_hash(&init_net, daddr, saddr, family);
 	struct xfrm_state *x;
 	struct hlist_node *entry;
 
@@ -767,7 +769,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 	to_put = NULL;
 
 	spin_lock_bh(&xfrm_state_lock);
-	h = xfrm_dst_hash(daddr, saddr, tmpl->reqid, family);
+	h = xfrm_dst_hash(&init_net, daddr, saddr, tmpl->reqid, family);
 	hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) {
 		if (x->props.family == family &&
 		    x->props.reqid == tmpl->reqid &&
@@ -839,10 +841,10 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 			x->km.state = XFRM_STATE_ACQ;
 			list_add(&x->km.all, &init_net.xfrm.state_all);
 			hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h);
-			h = xfrm_src_hash(daddr, saddr, family);
+			h = xfrm_src_hash(&init_net, daddr, saddr, family);
 			hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h);
 			if (x->id.spi) {
-				h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family);
+				h = xfrm_spi_hash(&init_net, &x->id.daddr, x->id.spi, x->id.proto, family);
 				hlist_add_head(&x->byspi, init_net.xfrm.state_byspi+h);
 			}
 			x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
@@ -877,7 +879,7 @@ xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 	struct hlist_node *entry;
 
 	spin_lock(&xfrm_state_lock);
-	h = xfrm_dst_hash(daddr, saddr, reqid, family);
+	h = xfrm_dst_hash(&init_net, daddr, saddr, reqid, family);
 	hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) {
 		if (x->props.family == family &&
 		    x->props.reqid == reqid &&
@@ -908,15 +910,15 @@ static void __xfrm_state_insert(struct xfrm_state *x)
 
 	list_add(&x->km.all, &init_net.xfrm.state_all);
 
-	h = xfrm_dst_hash(&x->id.daddr, &x->props.saddr,
+	h = xfrm_dst_hash(&init_net, &x->id.daddr, &x->props.saddr,
 			  x->props.reqid, x->props.family);
 	hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h);
 
-	h = xfrm_src_hash(&x->id.daddr, &x->props.saddr, x->props.family);
+	h = xfrm_src_hash(&init_net, &x->id.daddr, &x->props.saddr, x->props.family);
 	hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h);
 
 	if (x->id.spi) {
-		h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto,
+		h = xfrm_spi_hash(&init_net, &x->id.daddr, x->id.spi, x->id.proto,
 				  x->props.family);
 
 		hlist_add_head(&x->byspi, init_net.xfrm.state_byspi+h);
@@ -942,7 +944,7 @@ static void __xfrm_state_bump_genids(struct xfrm_state *xnew)
 	struct hlist_node *entry;
 	unsigned int h;
 
-	h = xfrm_dst_hash(&xnew->id.daddr, &xnew->props.saddr, reqid, family);
+	h = xfrm_dst_hash(&init_net, &xnew->id.daddr, &xnew->props.saddr, reqid, family);
 	hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) {
 		if (x->props.family	== family &&
 		    x->props.reqid	== reqid &&
@@ -964,7 +966,7 @@ EXPORT_SYMBOL(xfrm_state_insert);
 /* xfrm_state_lock is held */
 static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create)
 {
-	unsigned int h = xfrm_dst_hash(daddr, saddr, reqid, family);
+	unsigned int h = xfrm_dst_hash(&init_net, daddr, saddr, reqid, family);
 	struct hlist_node *entry;
 	struct xfrm_state *x;
 
@@ -1037,7 +1039,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
 		add_timer(&x->timer);
 		list_add(&x->km.all, &init_net.xfrm.state_all);
 		hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h);
-		h = xfrm_src_hash(daddr, saddr, family);
+		h = xfrm_src_hash(&init_net, daddr, saddr, family);
 		hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h);
 
 		init_net.xfrm.state_num++;
@@ -1189,7 +1191,7 @@ struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m)
 	struct hlist_node *entry;
 
 	if (m->reqid) {
-		h = xfrm_dst_hash(&m->old_daddr, &m->old_saddr,
+		h = xfrm_dst_hash(&init_net, &m->old_daddr, &m->old_saddr,
 				  m->reqid, m->old_family);
 		hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) {
 			if (x->props.mode != m->mode ||
@@ -1206,7 +1208,7 @@ struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m)
 			return x;
 		}
 	} else {
-		h = xfrm_src_hash(&m->old_daddr, &m->old_saddr,
+		h = xfrm_src_hash(&init_net, &m->old_daddr, &m->old_saddr,
 				  m->old_family);
 		hlist_for_each_entry(x, entry, init_net.xfrm.state_bysrc+h, bysrc) {
 			if (x->props.mode != m->mode ||
@@ -1514,7 +1516,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
 	}
 	if (x->id.spi) {
 		spin_lock_bh(&xfrm_state_lock);
-		h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, x->props.family);
+		h = xfrm_spi_hash(&init_net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family);
 		hlist_add_head(&x->byspi, init_net.xfrm.state_byspi+h);
 		spin_unlock_bh(&xfrm_state_lock);
 
-- 
1.5.6.5


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

* [PATCH 23/53] netns xfrm: trivial netns propagations
  2008-11-25 17:26                                         ` [PATCH 22/53] netns xfrm: propagate netns into bydst/bysrc/byspi hash functions Alexey Dobriyan
@ 2008-11-25 17:26                                           ` Alexey Dobriyan
  2008-11-25 17:26                                             ` [PATCH 24/53] netns xfrm: state flush in netns Alexey Dobriyan
  2008-11-26  1:29                                             ` [PATCH 23/53] netns xfrm: trivial netns propagations David Miller
  2008-11-26  1:29                                           ` [PATCH 22/53] netns xfrm: propagate netns into bydst/bysrc/byspi hash functions David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Take netns from xfrm_state or xfrm_policy.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/xfrm/xfrm_policy.c |   15 +++++++-----
 net/xfrm/xfrm_state.c  |   59 +++++++++++++++++++++++++++--------------------
 2 files changed, 43 insertions(+), 31 deletions(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 1d30086..3d931f5 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1069,29 +1069,32 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc
 
 static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
 {
+	struct net *net = xp_net(pol);
 	struct hlist_head *chain = policy_hash_bysel(&pol->selector,
 						     pol->family, dir);
 
-	list_add(&pol->walk.all, &init_net.xfrm.policy_all);
+	list_add(&pol->walk.all, &net->xfrm.policy_all);
 	hlist_add_head(&pol->bydst, chain);
-	hlist_add_head(&pol->byidx, init_net.xfrm.policy_byidx+idx_hash(pol->index));
-	init_net.xfrm.policy_count[dir]++;
+	hlist_add_head(&pol->byidx, net->xfrm.policy_byidx+idx_hash(pol->index));
+	net->xfrm.policy_count[dir]++;
 	xfrm_pol_hold(pol);
 
-	if (xfrm_bydst_should_resize(&init_net, dir, NULL))
-		schedule_work(&init_net.xfrm.policy_hash_work);
+	if (xfrm_bydst_should_resize(net, dir, NULL))
+		schedule_work(&net->xfrm.policy_hash_work);
 }
 
 static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
 						int dir)
 {
+	struct net *net = xp_net(pol);
+
 	if (hlist_unhashed(&pol->bydst))
 		return NULL;
 
 	hlist_del(&pol->bydst);
 	hlist_del(&pol->byidx);
 	list_del(&pol->walk.all);
-	init_net.xfrm.policy_count[dir]--;
+	net->xfrm.policy_count[dir]--;
 
 	return pol;
 }
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 72b2956..f3f635d 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -412,6 +412,7 @@ static inline unsigned long make_jiffies(long secs)
 static void xfrm_timer_handler(unsigned long data)
 {
 	struct xfrm_state *x = (struct xfrm_state*)data;
+	struct net *net = xs_net(x);
 	unsigned long now = get_seconds();
 	long next = LONG_MAX;
 	int warn = 0;
@@ -469,7 +470,7 @@ resched:
 expired:
 	if (x->km.state == XFRM_STATE_ACQ && x->id.spi == 0) {
 		x->km.state = XFRM_STATE_EXPIRED;
-		wake_up(&init_net.xfrm.km_waitq);
+		wake_up(&net->xfrm.km_waitq);
 		next = 2;
 		goto resched;
 	}
@@ -522,17 +523,20 @@ EXPORT_SYMBOL(xfrm_state_alloc);
 
 void __xfrm_state_destroy(struct xfrm_state *x)
 {
+	struct net *net = xs_net(x);
+
 	WARN_ON(x->km.state != XFRM_STATE_DEAD);
 
 	spin_lock_bh(&xfrm_state_gc_lock);
-	hlist_add_head(&x->gclist, &init_net.xfrm.state_gc_list);
+	hlist_add_head(&x->gclist, &net->xfrm.state_gc_list);
 	spin_unlock_bh(&xfrm_state_gc_lock);
-	schedule_work(&init_net.xfrm.state_gc_work);
+	schedule_work(&net->xfrm.state_gc_work);
 }
 EXPORT_SYMBOL(__xfrm_state_destroy);
 
 int __xfrm_state_delete(struct xfrm_state *x)
 {
+	struct net *net = xs_net(x);
 	int err = -ESRCH;
 
 	if (x->km.state != XFRM_STATE_DEAD) {
@@ -543,7 +547,7 @@ int __xfrm_state_delete(struct xfrm_state *x)
 		hlist_del(&x->bysrc);
 		if (x->id.spi)
 			hlist_del(&x->byspi);
-		init_net.xfrm.state_num--;
+		net->xfrm.state_num--;
 		spin_unlock(&xfrm_state_lock);
 
 		/* All xfrm_state objects are created by xfrm_state_alloc.
@@ -745,12 +749,12 @@ __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family)
 						  x->id.proto, family);
 }
 
-static void xfrm_hash_grow_check(int have_hash_collision)
+static void xfrm_hash_grow_check(struct net *net, int have_hash_collision)
 {
 	if (have_hash_collision &&
-	    (init_net.xfrm.state_hmask + 1) < xfrm_state_hashmax &&
-	    init_net.xfrm.state_num > init_net.xfrm.state_hmask)
-		schedule_work(&init_net.xfrm.state_hash_work);
+	    (net->xfrm.state_hmask + 1) < xfrm_state_hashmax &&
+	    net->xfrm.state_num > net->xfrm.state_hmask)
+		schedule_work(&net->xfrm.state_hash_work);
 }
 
 struct xfrm_state *
@@ -851,7 +855,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 			x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
 			add_timer(&x->timer);
 			init_net.xfrm.state_num++;
-			xfrm_hash_grow_check(x->bydst.next != NULL);
+			xfrm_hash_grow_check(&init_net, x->bydst.next != NULL);
 		} else {
 			x->km.state = XFRM_STATE_DEAD;
 			to_put = x;
@@ -904,48 +908,50 @@ EXPORT_SYMBOL(xfrm_stateonly_find);
 
 static void __xfrm_state_insert(struct xfrm_state *x)
 {
+	struct net *net = xs_net(x);
 	unsigned int h;
 
 	x->genid = ++xfrm_state_genid;
 
-	list_add(&x->km.all, &init_net.xfrm.state_all);
+	list_add(&x->km.all, &net->xfrm.state_all);
 
-	h = xfrm_dst_hash(&init_net, &x->id.daddr, &x->props.saddr,
+	h = xfrm_dst_hash(net, &x->id.daddr, &x->props.saddr,
 			  x->props.reqid, x->props.family);
-	hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h);
+	hlist_add_head(&x->bydst, net->xfrm.state_bydst+h);
 
-	h = xfrm_src_hash(&init_net, &x->id.daddr, &x->props.saddr, x->props.family);
-	hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h);
+	h = xfrm_src_hash(net, &x->id.daddr, &x->props.saddr, x->props.family);
+	hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h);
 
 	if (x->id.spi) {
-		h = xfrm_spi_hash(&init_net, &x->id.daddr, x->id.spi, x->id.proto,
+		h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto,
 				  x->props.family);
 
-		hlist_add_head(&x->byspi, init_net.xfrm.state_byspi+h);
+		hlist_add_head(&x->byspi, net->xfrm.state_byspi+h);
 	}
 
 	mod_timer(&x->timer, jiffies + HZ);
 	if (x->replay_maxage)
 		mod_timer(&x->rtimer, jiffies + x->replay_maxage);
 
-	wake_up(&init_net.xfrm.km_waitq);
+	wake_up(&net->xfrm.km_waitq);
 
-	init_net.xfrm.state_num++;
+	net->xfrm.state_num++;
 
-	xfrm_hash_grow_check(x->bydst.next != NULL);
+	xfrm_hash_grow_check(net, x->bydst.next != NULL);
 }
 
 /* xfrm_state_lock is held */
 static void __xfrm_state_bump_genids(struct xfrm_state *xnew)
 {
+	struct net *net = xs_net(xnew);
 	unsigned short family = xnew->props.family;
 	u32 reqid = xnew->props.reqid;
 	struct xfrm_state *x;
 	struct hlist_node *entry;
 	unsigned int h;
 
-	h = xfrm_dst_hash(&init_net, &xnew->id.daddr, &xnew->props.saddr, reqid, family);
-	hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) {
+	h = xfrm_dst_hash(net, &xnew->id.daddr, &xnew->props.saddr, reqid, family);
+	hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
 		if (x->props.family	== family &&
 		    x->props.reqid	== reqid &&
 		    !xfrm_addr_cmp(&x->id.daddr, &xnew->id.daddr, family) &&
@@ -1044,7 +1050,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
 
 		init_net.xfrm.state_num++;
 
-		xfrm_hash_grow_check(x->bydst.next != NULL);
+		xfrm_hash_grow_check(&init_net, x->bydst.next != NULL);
 	}
 
 	return x;
@@ -1109,8 +1115,9 @@ EXPORT_SYMBOL(xfrm_state_add);
 #ifdef CONFIG_XFRM_MIGRATE
 static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
 {
+	struct net *net = xs_net(orig);
 	int err = -ENOMEM;
-	struct xfrm_state *x = xfrm_state_alloc(&init_net);
+	struct xfrm_state *x = xfrm_state_alloc(net);
 	if (!x)
 		goto error;
 
@@ -1734,6 +1741,7 @@ EXPORT_SYMBOL(km_state_notify);
 
 void km_state_expired(struct xfrm_state *x, int hard, u32 pid)
 {
+	struct net *net = xs_net(x);
 	struct km_event c;
 
 	c.data.hard = hard;
@@ -1742,7 +1750,7 @@ void km_state_expired(struct xfrm_state *x, int hard, u32 pid)
 	km_state_notify(x, &c);
 
 	if (hard)
-		wake_up(&init_net.xfrm.km_waitq);
+		wake_up(&net->xfrm.km_waitq);
 }
 
 EXPORT_SYMBOL(km_state_expired);
@@ -1785,6 +1793,7 @@ EXPORT_SYMBOL(km_new_mapping);
 
 void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid)
 {
+	struct net *net = xp_net(pol);
 	struct km_event c;
 
 	c.data.hard = hard;
@@ -1793,7 +1802,7 @@ void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid)
 	km_policy_notify(pol, dir, &c);
 
 	if (hard)
-		wake_up(&init_net.xfrm.km_waitq);
+		wake_up(&net->xfrm.km_waitq);
 }
 EXPORT_SYMBOL(km_policy_expired);
 
-- 
1.5.6.5


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

* [PATCH 24/53] netns xfrm: state flush in netns
  2008-11-25 17:26                                           ` [PATCH 23/53] netns xfrm: trivial netns propagations Alexey Dobriyan
@ 2008-11-25 17:26                                             ` Alexey Dobriyan
  2008-11-25 17:26                                               ` [PATCH 25/53] netns xfrm: state lookup " Alexey Dobriyan
  2008-11-26  1:30                                               ` [PATCH 24/53] netns xfrm: state flush " David Miller
  2008-11-26  1:29                                             ` [PATCH 23/53] netns xfrm: trivial netns propagations David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h    |    2 +-
 net/key/af_key.c      |    2 +-
 net/xfrm/xfrm_state.c |   18 +++++++++---------
 net/xfrm/xfrm_user.c  |    2 +-
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 8699620..e4bb672 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1363,7 +1363,7 @@ struct xfrmk_spdinfo {
 
 extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
 extern int xfrm_state_delete(struct xfrm_state *x);
-extern int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
+extern int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info);
 extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si);
 extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si);
 extern int xfrm_replay_check(struct xfrm_state *x,
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 036315d..e5d595a 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1732,7 +1732,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
 	audit_info.loginuid = audit_get_loginuid(current);
 	audit_info.sessionid = audit_get_sessionid(current);
 	audit_info.secid = 0;
-	err = xfrm_state_flush(proto, &audit_info);
+	err = xfrm_state_flush(&init_net, proto, &audit_info);
 	if (err)
 		return err;
 	c.data.proto = proto;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index f3f635d..5f4c534 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -576,15 +576,15 @@ EXPORT_SYMBOL(xfrm_state_delete);
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 static inline int
-xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
+xfrm_state_flush_secctx_check(struct net *net, u8 proto, struct xfrm_audit *audit_info)
 {
 	int i, err = 0;
 
-	for (i = 0; i <= init_net.xfrm.state_hmask; i++) {
+	for (i = 0; i <= net->xfrm.state_hmask; i++) {
 		struct hlist_node *entry;
 		struct xfrm_state *x;
 
-		hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+i, bydst) {
+		hlist_for_each_entry(x, entry, net->xfrm.state_bydst+i, bydst) {
 			if (xfrm_id_proto_match(x->id.proto, proto) &&
 			   (err = security_xfrm_state_delete(x)) != 0) {
 				xfrm_audit_state_delete(x, 0,
@@ -600,26 +600,26 @@ xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
 }
 #else
 static inline int
-xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
+xfrm_state_flush_secctx_check(struct net *net, u8 proto, struct xfrm_audit *audit_info)
 {
 	return 0;
 }
 #endif
 
-int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
+int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info)
 {
 	int i, err = 0;
 
 	spin_lock_bh(&xfrm_state_lock);
-	err = xfrm_state_flush_secctx_check(proto, audit_info);
+	err = xfrm_state_flush_secctx_check(net, proto, audit_info);
 	if (err)
 		goto out;
 
-	for (i = 0; i <= init_net.xfrm.state_hmask; i++) {
+	for (i = 0; i <= net->xfrm.state_hmask; i++) {
 		struct hlist_node *entry;
 		struct xfrm_state *x;
 restart:
-		hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+i, bydst) {
+		hlist_for_each_entry(x, entry, net->xfrm.state_bydst+i, bydst) {
 			if (!xfrm_state_kern(x) &&
 			    xfrm_id_proto_match(x->id.proto, proto)) {
 				xfrm_state_hold(x);
@@ -641,7 +641,7 @@ restart:
 
 out:
 	spin_unlock_bh(&xfrm_state_lock);
-	wake_up(&init_net.xfrm.km_waitq);
+	wake_up(&net->xfrm.km_waitq);
 	return err;
 }
 EXPORT_SYMBOL(xfrm_state_flush);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 765c01e..49a7e89 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1398,7 +1398,7 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 	audit_info.loginuid = NETLINK_CB(skb).loginuid;
 	audit_info.sessionid = NETLINK_CB(skb).sessionid;
 	audit_info.secid = NETLINK_CB(skb).sid;
-	err = xfrm_state_flush(p->proto, &audit_info);
+	err = xfrm_state_flush(&init_net, p->proto, &audit_info);
 	if (err)
 		return err;
 	c.data.proto = p->proto;
-- 
1.5.6.5


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

* [PATCH 25/53] netns xfrm: state lookup in netns
  2008-11-25 17:26                                             ` [PATCH 24/53] netns xfrm: state flush in netns Alexey Dobriyan
@ 2008-11-25 17:26                                               ` Alexey Dobriyan
  2008-11-25 17:26                                                 ` [PATCH 26/53] netns xfrm: fixup xfrm_alloc_spi() Alexey Dobriyan
  2008-11-26  1:30                                                 ` [PATCH 25/53] netns xfrm: state lookup in netns David Miller
  2008-11-26  1:30                                               ` [PATCH 24/53] netns xfrm: state flush " David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h     |    4 ++--
 net/ipv4/ah4.c         |    2 +-
 net/ipv4/esp4.c        |    2 +-
 net/ipv4/ipcomp.c      |    4 ++--
 net/ipv6/ah6.c         |    2 +-
 net/ipv6/esp6.c        |    2 +-
 net/ipv6/ipcomp6.c     |    4 ++--
 net/ipv6/xfrm6_input.c |    2 +-
 net/key/af_key.c       |    2 +-
 net/xfrm/xfrm_input.c  |    2 +-
 net/xfrm/xfrm_state.c  |   34 +++++++++++++++++++---------------
 net/xfrm/xfrm_user.c   |   12 ++++++------
 12 files changed, 38 insertions(+), 34 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index e4bb672..15136c5 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1323,8 +1323,8 @@ extern int xfrm_state_check_expire(struct xfrm_state *x);
 extern void xfrm_state_insert(struct xfrm_state *x);
 extern int xfrm_state_add(struct xfrm_state *x);
 extern int xfrm_state_update(struct xfrm_state *x);
-extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family);
-extern struct xfrm_state *xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family);
+extern struct xfrm_state *xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family);
+extern struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family);
 #ifdef CONFIG_XFRM_SUB_POLICY
 extern int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src,
 			  int n, unsigned short family);
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 992ecd8..750426b 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -209,7 +209,7 @@ static void ah4_err(struct sk_buff *skb, u32 info)
 	    icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
 		return;
 
-	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET);
+	x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET);
 	if (!x)
 		return;
 	printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/%08x\n",
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 95a9c65..3595012 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -421,7 +421,7 @@ static void esp4_err(struct sk_buff *skb, u32 info)
 	    icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
 		return;
 
-	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET);
+	x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET);
 	if (!x)
 		return;
 	NETDEBUG(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%08x\n",
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 0a35f1b..3262ce0 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -35,7 +35,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
 		return;
 
 	spi = htonl(ntohs(ipch->cpi));
-	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr,
+	x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr,
 			      spi, IPPROTO_COMP, AF_INET);
 	if (!x)
 		return;
@@ -85,7 +85,7 @@ static int ipcomp_tunnel_attach(struct xfrm_state *x)
 	int err = 0;
 	struct xfrm_state *t;
 
-	t = xfrm_state_lookup((xfrm_address_t *)&x->id.daddr.a4,
+	t = xfrm_state_lookup(&init_net, (xfrm_address_t *)&x->id.daddr.a4,
 			      x->props.saddr.a4, IPPROTO_IPIP, AF_INET);
 	if (!t) {
 		t = ipcomp_tunnel_create(x);
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 13e330d..6ae014b 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -415,7 +415,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 	    type != ICMPV6_PKT_TOOBIG)
 		return;
 
-	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6);
+	x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6);
 	if (!x)
 		return;
 
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index c02a630..68f2af8 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -364,7 +364,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 	    type != ICMPV6_PKT_TOOBIG)
 		return;
 
-	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);
+	x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);
 	if (!x)
 		return;
 	printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n",
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index c369638..3a0b3be 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -63,7 +63,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 		return;
 
 	spi = htonl(ntohs(ipcomph->cpi));
-	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6);
+	x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6);
 	if (!x)
 		return;
 
@@ -114,7 +114,7 @@ static int ipcomp6_tunnel_attach(struct xfrm_state *x)
 
 	spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr);
 	if (spi)
-		t = xfrm_state_lookup((xfrm_address_t *)&x->id.daddr,
+		t = xfrm_state_lookup(&init_net, (xfrm_address_t *)&x->id.daddr,
 					      spi, IPPROTO_IPV6, AF_INET6);
 	if (!t) {
 		t = ipcomp6_tunnel_create(x);
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index a71c7dd..b69766a 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -100,7 +100,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 			break;
 		}
 
-		x = xfrm_state_lookup_byaddr(dst, src, proto, AF_INET6);
+		x = xfrm_state_lookup_byaddr(&init_net, dst, src, proto, AF_INET6);
 		if (!x)
 			continue;
 
diff --git a/net/key/af_key.c b/net/key/af_key.c
index e5d595a..449a5d0 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -683,7 +683,7 @@ static struct  xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **
 	if (!xaddr)
 		return NULL;
 
-	return xfrm_state_lookup(xaddr, sa->sadb_sa_spi, proto, family);
+	return xfrm_state_lookup(&init_net, xaddr, sa->sadb_sa_spi, proto, family);
 }
 
 #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1)))
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 7527940..c08a93e 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -151,7 +151,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 			goto drop;
 		}
 
-		x = xfrm_state_lookup(daddr, spi, nexthdr, family);
+		x = xfrm_state_lookup(&init_net, daddr, spi, nexthdr, family);
 		if (x == NULL) {
 			XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES);
 			xfrm_audit_state_notfound(skb, family, spi, seq);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 5f4c534..afde474 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -670,13 +670,13 @@ xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl,
 	return 0;
 }
 
-static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
+static struct xfrm_state *__xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
 {
-	unsigned int h = xfrm_spi_hash(&init_net, daddr, spi, proto, family);
+	unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family);
 	struct xfrm_state *x;
 	struct hlist_node *entry;
 
-	hlist_for_each_entry(x, entry, init_net.xfrm.state_byspi+h, byspi) {
+	hlist_for_each_entry(x, entry, net->xfrm.state_byspi+h, byspi) {
 		if (x->props.family != family ||
 		    x->id.spi       != spi ||
 		    x->id.proto     != proto)
@@ -702,13 +702,13 @@ static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi,
 	return NULL;
 }
 
-static struct xfrm_state *__xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family)
+static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family)
 {
-	unsigned int h = xfrm_src_hash(&init_net, daddr, saddr, family);
+	unsigned int h = xfrm_src_hash(net, daddr, saddr, family);
 	struct xfrm_state *x;
 	struct hlist_node *entry;
 
-	hlist_for_each_entry(x, entry, init_net.xfrm.state_bysrc+h, bysrc) {
+	hlist_for_each_entry(x, entry, net->xfrm.state_bysrc+h, bysrc) {
 		if (x->props.family != family ||
 		    x->id.proto     != proto)
 			continue;
@@ -740,11 +740,13 @@ static struct xfrm_state *__xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm
 static inline struct xfrm_state *
 __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family)
 {
+	struct net *net = xs_net(x);
+
 	if (use_spi)
-		return __xfrm_state_lookup(&x->id.daddr, x->id.spi,
+		return __xfrm_state_lookup(net, &x->id.daddr, x->id.spi,
 					   x->id.proto, family);
 	else
-		return __xfrm_state_lookup_byaddr(&x->id.daddr,
+		return __xfrm_state_lookup_byaddr(net, &x->id.daddr,
 						  &x->props.saddr,
 						  x->id.proto, family);
 }
@@ -818,7 +820,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 	x = best;
 	if (!x && !error && !acquire_in_progress) {
 		if (tmpl->id.spi &&
-		    (x0 = __xfrm_state_lookup(daddr, tmpl->id.spi,
+		    (x0 = __xfrm_state_lookup(&init_net, daddr, tmpl->id.spi,
 					      tmpl->id.proto, family)) != NULL) {
 			to_put = x0;
 			error = -EEXIST;
@@ -1361,26 +1363,27 @@ int xfrm_state_check_expire(struct xfrm_state *x)
 EXPORT_SYMBOL(xfrm_state_check_expire);
 
 struct xfrm_state *
-xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto,
+xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto,
 		  unsigned short family)
 {
 	struct xfrm_state *x;
 
 	spin_lock_bh(&xfrm_state_lock);
-	x = __xfrm_state_lookup(daddr, spi, proto, family);
+	x = __xfrm_state_lookup(net, daddr, spi, proto, family);
 	spin_unlock_bh(&xfrm_state_lock);
 	return x;
 }
 EXPORT_SYMBOL(xfrm_state_lookup);
 
 struct xfrm_state *
-xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr,
+xfrm_state_lookup_byaddr(struct net *net,
+			 xfrm_address_t *daddr, xfrm_address_t *saddr,
 			 u8 proto, unsigned short family)
 {
 	struct xfrm_state *x;
 
 	spin_lock_bh(&xfrm_state_lock);
-	x = __xfrm_state_lookup_byaddr(daddr, saddr, proto, family);
+	x = __xfrm_state_lookup_byaddr(net, daddr, saddr, proto, family);
 	spin_unlock_bh(&xfrm_state_lock);
 	return x;
 }
@@ -1486,6 +1489,7 @@ EXPORT_SYMBOL(xfrm_get_acqseq);
 
 int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
 {
+	struct net *net = xs_net(x);
 	unsigned int h;
 	struct xfrm_state *x0;
 	int err = -ENOENT;
@@ -1503,7 +1507,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
 	err = -ENOENT;
 
 	if (minspi == maxspi) {
-		x0 = xfrm_state_lookup(&x->id.daddr, minspi, x->id.proto, x->props.family);
+		x0 = xfrm_state_lookup(net, &x->id.daddr, minspi, x->id.proto, x->props.family);
 		if (x0) {
 			xfrm_state_put(x0);
 			goto unlock;
@@ -1513,7 +1517,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
 		u32 spi = 0;
 		for (h=0; h<high-low+1; h++) {
 			spi = low + net_random()%(high-low+1);
-			x0 = xfrm_state_lookup(&x->id.daddr, htonl(spi), x->id.proto, x->props.family);
+			x0 = xfrm_state_lookup(net, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
 			if (x0 == NULL) {
 				x->id.spi = htonl(spi);
 				break;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 49a7e89..e02ef33 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -440,7 +440,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
 
 	if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) {
 		err = -ESRCH;
-		x = xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family);
+		x = xfrm_state_lookup(&init_net, &p->daddr, p->spi, p->proto, p->family);
 	} else {
 		xfrm_address_t *saddr = NULL;
 
@@ -451,8 +451,8 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
 		}
 
 		err = -ESRCH;
-		x = xfrm_state_lookup_byaddr(&p->daddr, saddr, p->proto,
-					     p->family);
+		x = xfrm_state_lookup_byaddr(&init_net, &p->daddr, saddr,
+					     p->proto, p->family);
 	}
 
  out:
@@ -1468,7 +1468,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (r_skb == NULL)
 		return -ENOMEM;
 
-	x = xfrm_state_lookup(&id->daddr, id->spi, id->proto, id->family);
+	x = xfrm_state_lookup(&init_net, &id->daddr, id->spi, id->proto, id->family);
 	if (x == NULL) {
 		kfree_skb(r_skb);
 		return -ESRCH;
@@ -1509,7 +1509,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (!(nlh->nlmsg_flags&NLM_F_REPLACE))
 		return err;
 
-	x = xfrm_state_lookup(&p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family);
+	x = xfrm_state_lookup(&init_net, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family);
 	if (x == NULL)
 		return -ESRCH;
 
@@ -1628,7 +1628,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
 	struct xfrm_user_expire *ue = nlmsg_data(nlh);
 	struct xfrm_usersa_info *p = &ue->state;
 
-	x = xfrm_state_lookup(&p->id.daddr, p->id.spi, p->id.proto, p->family);
+	x = xfrm_state_lookup(&init_net, &p->id.daddr, p->id.spi, p->id.proto, p->family);
 
 	err = -ENOENT;
 	if (x == NULL)
-- 
1.5.6.5


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

* [PATCH 26/53] netns xfrm: fixup xfrm_alloc_spi()
  2008-11-25 17:26                                               ` [PATCH 25/53] netns xfrm: state lookup " Alexey Dobriyan
@ 2008-11-25 17:26                                                 ` Alexey Dobriyan
  2008-11-25 17:26                                                   ` [PATCH 27/53] netns xfrm: finding states in netns Alexey Dobriyan
  2008-11-26  1:31                                                   ` [PATCH 26/53] netns xfrm: fixup xfrm_alloc_spi() David Miller
  2008-11-26  1:30                                                 ` [PATCH 25/53] netns xfrm: state lookup in netns David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/xfrm/xfrm_state.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index afde474..cd51e4e 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1527,8 +1527,8 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
 	}
 	if (x->id.spi) {
 		spin_lock_bh(&xfrm_state_lock);
-		h = xfrm_spi_hash(&init_net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family);
-		hlist_add_head(&x->byspi, init_net.xfrm.state_byspi+h);
+		h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family);
+		hlist_add_head(&x->byspi, net->xfrm.state_byspi+h);
 		spin_unlock_bh(&xfrm_state_lock);
 
 		err = 0;
-- 
1.5.6.5


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

* [PATCH 27/53] netns xfrm: finding states in netns
  2008-11-25 17:26                                                 ` [PATCH 26/53] netns xfrm: fixup xfrm_alloc_spi() Alexey Dobriyan
@ 2008-11-25 17:26                                                   ` Alexey Dobriyan
  2008-11-25 17:27                                                     ` [PATCH 28/53] netns xfrm: state walking " Alexey Dobriyan
  2008-11-26  1:31                                                     ` [PATCH 27/53] netns xfrm: finding states " David Miller
  2008-11-26  1:31                                                   ` [PATCH 26/53] netns xfrm: fixup xfrm_alloc_spi() David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:26 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h    |    7 +++--
 net/core/pktgen.c     |    3 +-
 net/key/af_key.c      |    6 ++--
 net/xfrm/xfrm_state.c |   73 +++++++++++++++++++++++++-----------------------
 net/xfrm/xfrm_user.c  |    4 +-
 5 files changed, 49 insertions(+), 44 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 15136c5..4cbd055 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1315,7 +1315,8 @@ extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t
 					  struct flowi *fl, struct xfrm_tmpl *tmpl,
 					  struct xfrm_policy *pol, int *err,
 					  unsigned short family);
-extern struct xfrm_state * xfrm_stateonly_find(xfrm_address_t *daddr,
+extern struct xfrm_state * xfrm_stateonly_find(struct net *net,
+					       xfrm_address_t *daddr,
 					       xfrm_address_t *saddr,
 					       unsigned short family,
 					       u8 mode, u8 proto, u32 reqid);
@@ -1361,7 +1362,7 @@ struct xfrmk_spdinfo {
 	u32 spdhmcnt;
 };
 
-extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
+extern struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 seq);
 extern int xfrm_state_delete(struct xfrm_state *x);
 extern int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info);
 extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si);
@@ -1446,7 +1447,7 @@ struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err);
 int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
 u32 xfrm_get_acqseq(void);
 extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
-struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
+struct xfrm_state * xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto,
 				  xfrm_address_t *daddr, xfrm_address_t *saddr,
 				  int create, unsigned short family);
 extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 15e0c2c..6549848 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2165,7 +2165,8 @@ static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
 	struct xfrm_state *x = pkt_dev->flows[flow].x;
 	if (!x) {
 		/*slow path: we dont already have xfrm_state*/
-		x = xfrm_stateonly_find((xfrm_address_t *)&pkt_dev->cur_daddr,
+		x = xfrm_stateonly_find(&init_net,
+					(xfrm_address_t *)&pkt_dev->cur_daddr,
 					(xfrm_address_t *)&pkt_dev->cur_saddr,
 					AF_INET,
 					pkt_dev->ipsmode,
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 449a5d0..4ef0827 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1348,7 +1348,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
 	}
 
 	if (hdr->sadb_msg_seq) {
-		x = xfrm_find_acq_byseq(hdr->sadb_msg_seq);
+		x = xfrm_find_acq_byseq(&init_net, hdr->sadb_msg_seq);
 		if (x && xfrm_addr_cmp(&x->id.daddr, xdaddr, family)) {
 			xfrm_state_put(x);
 			x = NULL;
@@ -1356,7 +1356,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
 	}
 
 	if (!x)
-		x = xfrm_find_acq(mode, reqid, proto, xdaddr, xsaddr, 1, family);
+		x = xfrm_find_acq(&init_net, mode, reqid, proto, xdaddr, xsaddr, 1, family);
 
 	if (x == NULL)
 		return -ENOENT;
@@ -1404,7 +1404,7 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg *
 	if (hdr->sadb_msg_seq == 0 || hdr->sadb_msg_errno == 0)
 		return 0;
 
-	x = xfrm_find_acq_byseq(hdr->sadb_msg_seq);
+	x = xfrm_find_acq_byseq(&init_net, hdr->sadb_msg_seq);
 	if (x == NULL)
 		return 0;
 
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index cd51e4e..0d974fc 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -765,6 +765,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 		struct xfrm_policy *pol, int *err,
 		unsigned short family)
 {
+	struct net *net = xp_net(pol);
 	unsigned int h;
 	struct hlist_node *entry;
 	struct xfrm_state *x, *x0, *to_put;
@@ -775,8 +776,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 	to_put = NULL;
 
 	spin_lock_bh(&xfrm_state_lock);
-	h = xfrm_dst_hash(&init_net, daddr, saddr, tmpl->reqid, family);
-	hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) {
+	h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, family);
+	hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
 		if (x->props.family == family &&
 		    x->props.reqid == tmpl->reqid &&
 		    !(x->props.flags & XFRM_STATE_WILDRECV) &&
@@ -820,13 +821,13 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 	x = best;
 	if (!x && !error && !acquire_in_progress) {
 		if (tmpl->id.spi &&
-		    (x0 = __xfrm_state_lookup(&init_net, daddr, tmpl->id.spi,
+		    (x0 = __xfrm_state_lookup(net, daddr, tmpl->id.spi,
 					      tmpl->id.proto, family)) != NULL) {
 			to_put = x0;
 			error = -EEXIST;
 			goto out;
 		}
-		x = xfrm_state_alloc(&init_net);
+		x = xfrm_state_alloc(net);
 		if (x == NULL) {
 			error = -ENOMEM;
 			goto out;
@@ -845,19 +846,19 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 
 		if (km_query(x, tmpl, pol) == 0) {
 			x->km.state = XFRM_STATE_ACQ;
-			list_add(&x->km.all, &init_net.xfrm.state_all);
-			hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h);
-			h = xfrm_src_hash(&init_net, daddr, saddr, family);
-			hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h);
+			list_add(&x->km.all, &net->xfrm.state_all);
+			hlist_add_head(&x->bydst, net->xfrm.state_bydst+h);
+			h = xfrm_src_hash(net, daddr, saddr, family);
+			hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h);
 			if (x->id.spi) {
-				h = xfrm_spi_hash(&init_net, &x->id.daddr, x->id.spi, x->id.proto, family);
-				hlist_add_head(&x->byspi, init_net.xfrm.state_byspi+h);
+				h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, family);
+				hlist_add_head(&x->byspi, net->xfrm.state_byspi+h);
 			}
 			x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
 			x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
 			add_timer(&x->timer);
-			init_net.xfrm.state_num++;
-			xfrm_hash_grow_check(&init_net, x->bydst.next != NULL);
+			net->xfrm.state_num++;
+			xfrm_hash_grow_check(net, x->bydst.next != NULL);
 		} else {
 			x->km.state = XFRM_STATE_DEAD;
 			to_put = x;
@@ -877,7 +878,8 @@ out:
 }
 
 struct xfrm_state *
-xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
+xfrm_stateonly_find(struct net *net,
+		    xfrm_address_t *daddr, xfrm_address_t *saddr,
 		    unsigned short family, u8 mode, u8 proto, u32 reqid)
 {
 	unsigned int h;
@@ -885,8 +887,8 @@ xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 	struct hlist_node *entry;
 
 	spin_lock(&xfrm_state_lock);
-	h = xfrm_dst_hash(&init_net, daddr, saddr, reqid, family);
-	hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) {
+	h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
+	hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
 		if (x->props.family == family &&
 		    x->props.reqid == reqid &&
 		    !(x->props.flags & XFRM_STATE_WILDRECV) &&
@@ -972,13 +974,13 @@ void xfrm_state_insert(struct xfrm_state *x)
 EXPORT_SYMBOL(xfrm_state_insert);
 
 /* xfrm_state_lock is held */
-static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create)
+static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family, u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create)
 {
-	unsigned int h = xfrm_dst_hash(&init_net, daddr, saddr, reqid, family);
+	unsigned int h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
 	struct hlist_node *entry;
 	struct xfrm_state *x;
 
-	hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) {
+	hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
 		if (x->props.reqid  != reqid ||
 		    x->props.mode   != mode ||
 		    x->props.family != family ||
@@ -1010,7 +1012,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
 	if (!create)
 		return NULL;
 
-	x = xfrm_state_alloc(&init_net);
+	x = xfrm_state_alloc(net);
 	if (likely(x)) {
 		switch (family) {
 		case AF_INET:
@@ -1045,23 +1047,24 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
 		xfrm_state_hold(x);
 		x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
 		add_timer(&x->timer);
-		list_add(&x->km.all, &init_net.xfrm.state_all);
-		hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h);
-		h = xfrm_src_hash(&init_net, daddr, saddr, family);
-		hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h);
+		list_add(&x->km.all, &net->xfrm.state_all);
+		hlist_add_head(&x->bydst, net->xfrm.state_bydst+h);
+		h = xfrm_src_hash(net, daddr, saddr, family);
+		hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h);
 
-		init_net.xfrm.state_num++;
+		net->xfrm.state_num++;
 
-		xfrm_hash_grow_check(&init_net, x->bydst.next != NULL);
+		xfrm_hash_grow_check(net, x->bydst.next != NULL);
 	}
 
 	return x;
 }
 
-static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq);
+static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq);
 
 int xfrm_state_add(struct xfrm_state *x)
 {
+	struct net *net = xs_net(x);
 	struct xfrm_state *x1, *to_put;
 	int family;
 	int err;
@@ -1082,7 +1085,7 @@ int xfrm_state_add(struct xfrm_state *x)
 	}
 
 	if (use_spi && x->km.seq) {
-		x1 = __xfrm_find_acq_byseq(x->km.seq);
+		x1 = __xfrm_find_acq_byseq(net, x->km.seq);
 		if (x1 && ((x1->id.proto != x->id.proto) ||
 		    xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) {
 			to_put = x1;
@@ -1091,7 +1094,7 @@ int xfrm_state_add(struct xfrm_state *x)
 	}
 
 	if (use_spi && !x1)
-		x1 = __find_acq_core(family, x->props.mode, x->props.reqid,
+		x1 = __find_acq_core(net, family, x->props.mode, x->props.reqid,
 				     x->id.proto,
 				     &x->id.daddr, &x->props.saddr, 0);
 
@@ -1390,14 +1393,14 @@ xfrm_state_lookup_byaddr(struct net *net,
 EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
 
 struct xfrm_state *
-xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
+xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto,
 	      xfrm_address_t *daddr, xfrm_address_t *saddr,
 	      int create, unsigned short family)
 {
 	struct xfrm_state *x;
 
 	spin_lock_bh(&xfrm_state_lock);
-	x = __find_acq_core(family, mode, reqid, proto, daddr, saddr, create);
+	x = __find_acq_core(net, family, mode, reqid, proto, daddr, saddr, create);
 	spin_unlock_bh(&xfrm_state_lock);
 
 	return x;
@@ -1444,15 +1447,15 @@ EXPORT_SYMBOL(xfrm_state_sort);
 
 /* Silly enough, but I'm lazy to build resolution list */
 
-static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq)
+static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq)
 {
 	int i;
 
-	for (i = 0; i <= init_net.xfrm.state_hmask; i++) {
+	for (i = 0; i <= net->xfrm.state_hmask; i++) {
 		struct hlist_node *entry;
 		struct xfrm_state *x;
 
-		hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+i, bydst) {
+		hlist_for_each_entry(x, entry, net->xfrm.state_bydst+i, bydst) {
 			if (x->km.seq == seq &&
 			    x->km.state == XFRM_STATE_ACQ) {
 				xfrm_state_hold(x);
@@ -1463,12 +1466,12 @@ static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq)
 	return NULL;
 }
 
-struct xfrm_state *xfrm_find_acq_byseq(u32 seq)
+struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 seq)
 {
 	struct xfrm_state *x;
 
 	spin_lock_bh(&xfrm_state_lock);
-	x = __xfrm_find_acq_byseq(seq);
+	x = __xfrm_find_acq_byseq(net, seq);
 	spin_unlock_bh(&xfrm_state_lock);
 	return x;
 }
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index e02ef33..3d57744 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -837,7 +837,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
 
 	x = NULL;
 	if (p->info.seq) {
-		x = xfrm_find_acq_byseq(p->info.seq);
+		x = xfrm_find_acq_byseq(&init_net, p->info.seq);
 		if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) {
 			xfrm_state_put(x);
 			x = NULL;
@@ -845,7 +845,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
 	}
 
 	if (!x)
-		x = xfrm_find_acq(p->info.mode, p->info.reqid,
+		x = xfrm_find_acq(&init_net, p->info.mode, p->info.reqid,
 				  p->info.id.proto, daddr,
 				  &p->info.saddr, 1,
 				  family);
-- 
1.5.6.5


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

* [PATCH 28/53] netns xfrm: state walking in netns
  2008-11-25 17:26                                                   ` [PATCH 27/53] netns xfrm: finding states in netns Alexey Dobriyan
@ 2008-11-25 17:27                                                     ` Alexey Dobriyan
  2008-11-25 17:27                                                       ` [PATCH 29/53] netns xfrm: propagate netns into policy byidx hash Alexey Dobriyan
  2008-11-26  1:32                                                       ` [PATCH 28/53] netns xfrm: state walking in netns David Miller
  2008-11-26  1:31                                                     ` [PATCH 27/53] netns xfrm: finding states " David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h    |    2 +-
 net/key/af_key.c      |    2 +-
 net/xfrm/xfrm_state.c |    6 +++---
 net/xfrm/xfrm_user.c  |    2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 4cbd055..40ed487 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1307,7 +1307,7 @@ extern int xfrm_proc_init(void);
 #endif
 
 extern void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto);
-extern int xfrm_state_walk(struct xfrm_state_walk *walk,
+extern int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
 			   int (*func)(struct xfrm_state *, int, void*), void *);
 extern void xfrm_state_walk_done(struct xfrm_state_walk *walk);
 extern struct xfrm_state *xfrm_state_alloc(struct net *net);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 4ef0827..b74d939 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1776,7 +1776,7 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr)
 
 static int pfkey_dump_sa(struct pfkey_sock *pfk)
 {
-	return xfrm_state_walk(&pfk->dump.u.state, dump_sa, (void *) pfk);
+	return xfrm_state_walk(&init_net, &pfk->dump.u.state, dump_sa, (void *) pfk);
 }
 
 static void pfkey_dump_sa_done(struct pfkey_sock *pfk)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 0d974fc..ea340bb 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1544,7 +1544,7 @@ unlock:
 }
 EXPORT_SYMBOL(xfrm_alloc_spi);
 
-int xfrm_state_walk(struct xfrm_state_walk *walk,
+int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
 		    int (*func)(struct xfrm_state *, int, void*),
 		    void *data)
 {
@@ -1557,10 +1557,10 @@ int xfrm_state_walk(struct xfrm_state_walk *walk,
 
 	spin_lock_bh(&xfrm_state_lock);
 	if (list_empty(&walk->all))
-		x = list_first_entry(&init_net.xfrm.state_all, struct xfrm_state_walk, all);
+		x = list_first_entry(&net->xfrm.state_all, struct xfrm_state_walk, all);
 	else
 		x = list_entry(&walk->all, struct xfrm_state_walk, all);
-	list_for_each_entry_from(x, &init_net.xfrm.state_all, all) {
+	list_for_each_entry_from(x, &net->xfrm.state_all, all) {
 		if (x->state == XFRM_STATE_DEAD)
 			continue;
 		state = container_of(x, struct xfrm_state, km);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 3d57744..787b0ee 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -631,7 +631,7 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
 		xfrm_state_walk_init(walk, 0);
 	}
 
-	(void) xfrm_state_walk(walk, dump_one_state, &info);
+	(void) xfrm_state_walk(&init_net, walk, dump_one_state, &info);
 
 	return skb->len;
 }
-- 
1.5.6.5


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

* [PATCH 29/53] netns xfrm: propagate netns into policy byidx hash
  2008-11-25 17:27                                                     ` [PATCH 28/53] netns xfrm: state walking " Alexey Dobriyan
@ 2008-11-25 17:27                                                       ` Alexey Dobriyan
  2008-11-25 17:27                                                         ` [PATCH 30/53] netns xfrm: policy insertion in netns Alexey Dobriyan
  2008-11-26  1:32                                                         ` [PATCH 29/53] netns xfrm: propagate netns into policy byidx hash David Miller
  2008-11-26  1:32                                                       ` [PATCH 28/53] netns xfrm: state walking in netns David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/xfrm/xfrm_policy.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 3d931f5..aefbb56 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -321,9 +321,9 @@ static void xfrm_policy_kill(struct xfrm_policy *policy)
 
 static unsigned int xfrm_policy_hashmax __read_mostly = 1 * 1024 * 1024;
 
-static inline unsigned int idx_hash(u32 index)
+static inline unsigned int idx_hash(struct net *net, u32 index)
 {
-	return __idx_hash(index, init_net.xfrm.policy_idx_hmask);
+	return __idx_hash(index, net->xfrm.policy_idx_hmask);
 }
 
 static struct hlist_head *policy_hash_bysel(struct xfrm_selector *sel, unsigned short family, int dir)
@@ -523,7 +523,7 @@ static u32 xfrm_gen_index(int dir)
 		idx_generator += 8;
 		if (idx == 0)
 			idx = 8;
-		list = init_net.xfrm.policy_byidx + idx_hash(idx);
+		list = init_net.xfrm.policy_byidx + idx_hash(&init_net, idx);
 		found = 0;
 		hlist_for_each_entry(p, entry, list, byidx) {
 			if (p->index == idx) {
@@ -596,7 +596,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 		init_net.xfrm.policy_count[dir]--;
 	}
 	policy->index = delpol ? delpol->index : xfrm_gen_index(dir);
-	hlist_add_head(&policy->byidx, init_net.xfrm.policy_byidx+idx_hash(policy->index));
+	hlist_add_head(&policy->byidx, init_net.xfrm.policy_byidx+idx_hash(&init_net, policy->index));
 	policy->curlft.add_time = get_seconds();
 	policy->curlft.use_time = 0;
 	if (!mod_timer(&policy->timer, jiffies + HZ))
@@ -698,7 +698,7 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
 
 	*err = 0;
 	write_lock_bh(&xfrm_policy_lock);
-	chain = init_net.xfrm.policy_byidx + idx_hash(id);
+	chain = init_net.xfrm.policy_byidx + idx_hash(&init_net, id);
 	ret = NULL;
 	hlist_for_each_entry(pol, entry, chain, byidx) {
 		if (pol->type == type && pol->index == id) {
@@ -1075,7 +1075,7 @@ static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
 
 	list_add(&pol->walk.all, &net->xfrm.policy_all);
 	hlist_add_head(&pol->bydst, chain);
-	hlist_add_head(&pol->byidx, net->xfrm.policy_byidx+idx_hash(pol->index));
+	hlist_add_head(&pol->byidx, net->xfrm.policy_byidx+idx_hash(net, pol->index));
 	net->xfrm.policy_count[dir]++;
 	xfrm_pol_hold(pol);
 
-- 
1.5.6.5


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

* [PATCH 30/53] netns xfrm: policy insertion in netns
  2008-11-25 17:27                                                       ` [PATCH 29/53] netns xfrm: propagate netns into policy byidx hash Alexey Dobriyan
@ 2008-11-25 17:27                                                         ` Alexey Dobriyan
  2008-11-25 17:27                                                           ` [PATCH 31/53] netns xfrm: policy flushing " Alexey Dobriyan
  2008-11-26  1:33                                                           ` [PATCH 30/53] netns xfrm: policy insertion " David Miller
  2008-11-26  1:32                                                         ` [PATCH 29/53] netns xfrm: propagate netns into policy byidx hash David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/xfrm/xfrm_policy.c |   46 ++++++++++++++++++++++++----------------------
 1 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index aefbb56..11fee87 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -326,22 +326,22 @@ static inline unsigned int idx_hash(struct net *net, u32 index)
 	return __idx_hash(index, net->xfrm.policy_idx_hmask);
 }
 
-static struct hlist_head *policy_hash_bysel(struct xfrm_selector *sel, unsigned short family, int dir)
+static struct hlist_head *policy_hash_bysel(struct net *net, struct xfrm_selector *sel, unsigned short family, int dir)
 {
-	unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask;
+	unsigned int hmask = net->xfrm.policy_bydst[dir].hmask;
 	unsigned int hash = __sel_hash(sel, family, hmask);
 
 	return (hash == hmask + 1 ?
-		&init_net.xfrm.policy_inexact[dir] :
-		init_net.xfrm.policy_bydst[dir].table + hash);
+		&net->xfrm.policy_inexact[dir] :
+		net->xfrm.policy_bydst[dir].table + hash);
 }
 
-static struct hlist_head *policy_hash_direct(xfrm_address_t *daddr, xfrm_address_t *saddr, unsigned short family, int dir)
+static struct hlist_head *policy_hash_direct(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, unsigned short family, int dir)
 {
-	unsigned int hmask = init_net.xfrm.policy_bydst[dir].hmask;
+	unsigned int hmask = net->xfrm.policy_bydst[dir].hmask;
 	unsigned int hash = __addr_hash(daddr, saddr, family, hmask);
 
-	return init_net.xfrm.policy_bydst[dir].table + hash;
+	return net->xfrm.policy_bydst[dir].table + hash;
 }
 
 static void xfrm_dst_hash_transfer(struct hlist_head *list,
@@ -508,7 +508,7 @@ static void xfrm_hash_resize(struct work_struct *work)
 
 /* Generate new index... KAME seems to generate them ordered by cost
  * of an absolute inpredictability of ordering of rules. This will not pass. */
-static u32 xfrm_gen_index(int dir)
+static u32 xfrm_gen_index(struct net *net, int dir)
 {
 	static u32 idx_generator;
 
@@ -523,7 +523,7 @@ static u32 xfrm_gen_index(int dir)
 		idx_generator += 8;
 		if (idx == 0)
 			idx = 8;
-		list = init_net.xfrm.policy_byidx + idx_hash(&init_net, idx);
+		list = net->xfrm.policy_byidx + idx_hash(net, idx);
 		found = 0;
 		hlist_for_each_entry(p, entry, list, byidx) {
 			if (p->index == idx) {
@@ -553,6 +553,7 @@ static inline int selector_cmp(struct xfrm_selector *s1, struct xfrm_selector *s
 
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 {
+	struct net *net = xp_net(policy);
 	struct xfrm_policy *pol;
 	struct xfrm_policy *delpol;
 	struct hlist_head *chain;
@@ -560,7 +561,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 	struct dst_entry *gc_list;
 
 	write_lock_bh(&xfrm_policy_lock);
-	chain = policy_hash_bysel(&policy->selector, policy->family, dir);
+	chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
 	delpol = NULL;
 	newpos = NULL;
 	hlist_for_each_entry(pol, entry, chain, bydst) {
@@ -587,27 +588,27 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 	else
 		hlist_add_head(&policy->bydst, chain);
 	xfrm_pol_hold(policy);
-	init_net.xfrm.policy_count[dir]++;
+	net->xfrm.policy_count[dir]++;
 	atomic_inc(&flow_cache_genid);
 	if (delpol) {
 		hlist_del(&delpol->bydst);
 		hlist_del(&delpol->byidx);
 		list_del(&delpol->walk.all);
-		init_net.xfrm.policy_count[dir]--;
+		net->xfrm.policy_count[dir]--;
 	}
-	policy->index = delpol ? delpol->index : xfrm_gen_index(dir);
-	hlist_add_head(&policy->byidx, init_net.xfrm.policy_byidx+idx_hash(&init_net, policy->index));
+	policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir);
+	hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index));
 	policy->curlft.add_time = get_seconds();
 	policy->curlft.use_time = 0;
 	if (!mod_timer(&policy->timer, jiffies + HZ))
 		xfrm_pol_hold(policy);
-	list_add(&policy->walk.all, &init_net.xfrm.policy_all);
+	list_add(&policy->walk.all, &net->xfrm.policy_all);
 	write_unlock_bh(&xfrm_policy_lock);
 
 	if (delpol)
 		xfrm_policy_kill(delpol);
-	else if (xfrm_bydst_should_resize(&init_net, dir, NULL))
-		schedule_work(&init_net.xfrm.policy_hash_work);
+	else if (xfrm_bydst_should_resize(net, dir, NULL))
+		schedule_work(&net->xfrm.policy_hash_work);
 
 	read_lock_bh(&xfrm_policy_lock);
 	gc_list = NULL;
@@ -652,7 +653,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
 
 	*err = 0;
 	write_lock_bh(&xfrm_policy_lock);
-	chain = policy_hash_bysel(sel, sel->family, dir);
+	chain = policy_hash_bysel(&init_net, sel, sel->family, dir);
 	ret = NULL;
 	hlist_for_each_entry(pol, entry, chain, bydst) {
 		if (pol->type == type &&
@@ -955,7 +956,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
 		return NULL;
 
 	read_lock_bh(&xfrm_policy_lock);
-	chain = policy_hash_direct(daddr, saddr, family, dir);
+	chain = policy_hash_direct(&init_net, daddr, saddr, family, dir);
 	ret = NULL;
 	hlist_for_each_entry(pol, entry, chain, bydst) {
 		err = xfrm_policy_match(pol, fl, type, family, dir);
@@ -1070,7 +1071,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc
 static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
 {
 	struct net *net = xp_net(pol);
-	struct hlist_head *chain = policy_hash_bysel(&pol->selector,
+	struct hlist_head *chain = policy_hash_bysel(net, &pol->selector,
 						     pol->family, dir);
 
 	list_add(&pol->walk.all, &net->xfrm.policy_all);
@@ -1116,6 +1117,7 @@ EXPORT_SYMBOL(xfrm_policy_delete);
 
 int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
 {
+	struct net *net = xp_net(pol);
 	struct xfrm_policy *old_pol;
 
 #ifdef CONFIG_XFRM_SUB_POLICY
@@ -1128,7 +1130,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
 	sk->sk_policy[dir] = pol;
 	if (pol) {
 		pol->curlft.add_time = get_seconds();
-		pol->index = xfrm_gen_index(XFRM_POLICY_MAX+dir);
+		pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir);
 		__xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
 	}
 	if (old_pol)
@@ -2595,7 +2597,7 @@ static struct xfrm_policy * xfrm_migrate_policy_find(struct xfrm_selector *sel,
 	u32 priority = ~0U;
 
 	read_lock_bh(&xfrm_policy_lock);
-	chain = policy_hash_direct(&sel->daddr, &sel->saddr, sel->family, dir);
+	chain = policy_hash_direct(&init_net, &sel->daddr, &sel->saddr, sel->family, dir);
 	hlist_for_each_entry(pol, entry, chain, bydst) {
 		if (xfrm_migrate_selector_match(sel, &pol->selector) &&
 		    pol->type == type) {
-- 
1.5.6.5


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

* [PATCH 31/53] netns xfrm: policy flushing in netns
  2008-11-25 17:27                                                         ` [PATCH 30/53] netns xfrm: policy insertion in netns Alexey Dobriyan
@ 2008-11-25 17:27                                                           ` Alexey Dobriyan
  2008-11-25 17:27                                                             ` [PATCH 32/53] netns xfrm: finding policy " Alexey Dobriyan
  2008-11-26  1:33                                                             ` [PATCH 31/53] netns xfrm: policy flushing " David Miller
  2008-11-26  1:33                                                           ` [PATCH 30/53] netns xfrm: policy insertion " David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h     |    2 +-
 net/key/af_key.c       |    2 +-
 net/xfrm/xfrm_policy.c |   22 +++++++++++-----------
 net/xfrm/xfrm_user.c   |    2 +-
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 40ed487..766cc71 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1444,7 +1444,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
 					  struct xfrm_sec_ctx *ctx, int delete,
 					  int *err);
 struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err);
-int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
+int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info);
 u32 xfrm_get_acqseq(void);
 extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
 struct xfrm_state * xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto,
diff --git a/net/key/af_key.c b/net/key/af_key.c
index b74d939..0f44856 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2686,7 +2686,7 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg
 	audit_info.loginuid = audit_get_loginuid(current);
 	audit_info.sessionid = audit_get_sessionid(current);
 	audit_info.secid = 0;
-	err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
+	err = xfrm_policy_flush(&init_net, XFRM_POLICY_TYPE_MAIN, &audit_info);
 	if (err)
 		return err;
 	c.data.type = XFRM_POLICY_TYPE_MAIN;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 11fee87..7c264a7 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -732,7 +732,7 @@ EXPORT_SYMBOL(xfrm_policy_byid);
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 static inline int
-xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
+xfrm_policy_flush_secctx_check(struct net *net, u8 type, struct xfrm_audit *audit_info)
 {
 	int dir, err = 0;
 
@@ -742,7 +742,7 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
 		int i;
 
 		hlist_for_each_entry(pol, entry,
-				     &init_net.xfrm.policy_inexact[dir], bydst) {
+				     &net->xfrm.policy_inexact[dir], bydst) {
 			if (pol->type != type)
 				continue;
 			err = security_xfrm_policy_delete(pol->security);
@@ -754,9 +754,9 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
 				return err;
 			}
 		}
-		for (i = init_net.xfrm.policy_bydst[dir].hmask; i >= 0; i--) {
+		for (i = net->xfrm.policy_bydst[dir].hmask; i >= 0; i--) {
 			hlist_for_each_entry(pol, entry,
-					     init_net.xfrm.policy_bydst[dir].table + i,
+					     net->xfrm.policy_bydst[dir].table + i,
 					     bydst) {
 				if (pol->type != type)
 					continue;
@@ -776,19 +776,19 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
 }
 #else
 static inline int
-xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
+xfrm_policy_flush_secctx_check(struct net *net, u8 type, struct xfrm_audit *audit_info)
 {
 	return 0;
 }
 #endif
 
-int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
+int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
 {
 	int dir, err = 0;
 
 	write_lock_bh(&xfrm_policy_lock);
 
-	err = xfrm_policy_flush_secctx_check(type, audit_info);
+	err = xfrm_policy_flush_secctx_check(net, type, audit_info);
 	if (err)
 		goto out;
 
@@ -800,7 +800,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
 		killed = 0;
 	again1:
 		hlist_for_each_entry(pol, entry,
-				     &init_net.xfrm.policy_inexact[dir], bydst) {
+				     &net->xfrm.policy_inexact[dir], bydst) {
 			if (pol->type != type)
 				continue;
 			hlist_del(&pol->bydst);
@@ -818,10 +818,10 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
 			goto again1;
 		}
 
-		for (i = init_net.xfrm.policy_bydst[dir].hmask; i >= 0; i--) {
+		for (i = net->xfrm.policy_bydst[dir].hmask; i >= 0; i--) {
 	again2:
 			hlist_for_each_entry(pol, entry,
-					     init_net.xfrm.policy_bydst[dir].table + i,
+					     net->xfrm.policy_bydst[dir].table + i,
 					     bydst) {
 				if (pol->type != type)
 					continue;
@@ -842,7 +842,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
 			}
 		}
 
-		init_net.xfrm.policy_count[dir] -= killed;
+		net->xfrm.policy_count[dir] -= killed;
 	}
 	atomic_inc(&flow_cache_genid);
 out:
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 787b0ee..d4983e8 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1546,7 +1546,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 	audit_info.loginuid = NETLINK_CB(skb).loginuid;
 	audit_info.sessionid = NETLINK_CB(skb).sessionid;
 	audit_info.secid = NETLINK_CB(skb).sid;
-	err = xfrm_policy_flush(type, &audit_info);
+	err = xfrm_policy_flush(&init_net, type, &audit_info);
 	if (err)
 		return err;
 	c.data.type = type;
-- 
1.5.6.5


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

* [PATCH 32/53] netns xfrm: finding policy in netns
  2008-11-25 17:27                                                           ` [PATCH 31/53] netns xfrm: policy flushing " Alexey Dobriyan
@ 2008-11-25 17:27                                                             ` Alexey Dobriyan
  2008-11-25 17:27                                                               ` [PATCH 33/53] netns xfrm: policy walking " Alexey Dobriyan
  2008-11-26  1:34                                                               ` [PATCH 32/53] netns xfrm: finding policy " David Miller
  2008-11-26  1:33                                                             ` [PATCH 31/53] netns xfrm: policy flushing " David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Add netns parameter to xfrm_policy_bysel_ctx(), xfrm_policy_byidx().

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h     |    4 ++--
 net/key/af_key.c       |    6 +++---
 net/xfrm/xfrm_policy.c |   14 +++++++-------
 net/xfrm/xfrm_user.c   |    8 ++++----
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 766cc71..ec2b7a9 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1439,11 +1439,11 @@ extern int xfrm_policy_walk(struct xfrm_policy_walk *walk,
 	int (*func)(struct xfrm_policy *, int, int, void*), void *);
 extern void xfrm_policy_walk_done(struct xfrm_policy_walk *walk);
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
-struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
+struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u8 type, int dir,
 					  struct xfrm_selector *sel,
 					  struct xfrm_sec_ctx *ctx, int delete,
 					  int *err);
-struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err);
+struct xfrm_policy *xfrm_policy_byid(struct net *net, u8, int dir, u32 id, int delete, int *err);
 int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info);
 u32 xfrm_get_acqseq(void);
 extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 0f44856..ca26811 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2324,7 +2324,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
 			return err;
 	}
 
-	xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN,
+	xp = xfrm_policy_bysel_ctx(&init_net, XFRM_POLICY_TYPE_MAIN,
 				   pol->sadb_x_policy_dir - 1, &sel, pol_ctx,
 				   1, &err);
 	security_xfrm_policy_free(pol_ctx);
@@ -2571,8 +2571,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
 		return -EINVAL;
 
 	delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2);
-	xp = xfrm_policy_byid(XFRM_POLICY_TYPE_MAIN, dir, pol->sadb_x_policy_id,
-			      delete, &err);
+	xp = xfrm_policy_byid(&init_net, XFRM_POLICY_TYPE_MAIN, dir,
+			      pol->sadb_x_policy_id, delete, &err);
 	if (xp == NULL)
 		return -ENOENT;
 
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 7c264a7..96895ef 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -642,7 +642,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 }
 EXPORT_SYMBOL(xfrm_policy_insert);
 
-struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
+struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u8 type, int dir,
 					  struct xfrm_selector *sel,
 					  struct xfrm_sec_ctx *ctx, int delete,
 					  int *err)
@@ -653,7 +653,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
 
 	*err = 0;
 	write_lock_bh(&xfrm_policy_lock);
-	chain = policy_hash_bysel(&init_net, sel, sel->family, dir);
+	chain = policy_hash_bysel(net, sel, sel->family, dir);
 	ret = NULL;
 	hlist_for_each_entry(pol, entry, chain, bydst) {
 		if (pol->type == type &&
@@ -670,7 +670,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
 				hlist_del(&pol->bydst);
 				hlist_del(&pol->byidx);
 				list_del(&pol->walk.all);
-				init_net.xfrm.policy_count[dir]--;
+				net->xfrm.policy_count[dir]--;
 			}
 			ret = pol;
 			break;
@@ -686,8 +686,8 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
 }
 EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
 
-struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
-				     int *err)
+struct xfrm_policy *xfrm_policy_byid(struct net *net, u8 type, int dir, u32 id,
+				     int delete, int *err)
 {
 	struct xfrm_policy *pol, *ret;
 	struct hlist_head *chain;
@@ -699,7 +699,7 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
 
 	*err = 0;
 	write_lock_bh(&xfrm_policy_lock);
-	chain = init_net.xfrm.policy_byidx + idx_hash(&init_net, id);
+	chain = net->xfrm.policy_byidx + idx_hash(net, id);
 	ret = NULL;
 	hlist_for_each_entry(pol, entry, chain, byidx) {
 		if (pol->type == type && pol->index == id) {
@@ -714,7 +714,7 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
 				hlist_del(&pol->bydst);
 				hlist_del(&pol->byidx);
 				list_del(&pol->walk.all);
-				init_net.xfrm.policy_count[dir]--;
+				net->xfrm.policy_count[dir]--;
 			}
 			ret = pol;
 			break;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index d4983e8..efd6ab5 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1330,7 +1330,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 		return err;
 
 	if (p->index)
-		xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err);
+		xp = xfrm_policy_byid(&init_net, type, p->dir, p->index, delete, &err);
 	else {
 		struct nlattr *rt = attrs[XFRMA_SEC_CTX];
 		struct xfrm_sec_ctx *ctx;
@@ -1347,7 +1347,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 			if (err)
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, ctx,
+		xp = xfrm_policy_bysel_ctx(&init_net, type, p->dir, &p->sel, ctx,
 					   delete, &err);
 		security_xfrm_policy_free(ctx);
 	}
@@ -1571,7 +1571,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
 		return err;
 
 	if (p->index)
-		xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err);
+		xp = xfrm_policy_byid(&init_net, type, p->dir, p->index, 0, &err);
 	else {
 		struct nlattr *rt = attrs[XFRMA_SEC_CTX];
 		struct xfrm_sec_ctx *ctx;
@@ -1588,7 +1588,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
 			if (err)
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, ctx, 0, &err);
+		xp = xfrm_policy_bysel_ctx(&init_net, type, p->dir, &p->sel, ctx, 0, &err);
 		security_xfrm_policy_free(ctx);
 	}
 	if (xp == NULL)
-- 
1.5.6.5


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

* [PATCH 33/53] netns xfrm: policy walking in netns
  2008-11-25 17:27                                                             ` [PATCH 32/53] netns xfrm: finding policy " Alexey Dobriyan
@ 2008-11-25 17:27                                                               ` Alexey Dobriyan
  2008-11-25 17:27                                                                 ` [PATCH 34/53] netns xfrm: lookup " Alexey Dobriyan
  2008-11-26  1:34                                                                 ` [PATCH 33/53] netns xfrm: policy walking " David Miller
  2008-11-26  1:34                                                               ` [PATCH 32/53] netns xfrm: finding policy " David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h     |    2 +-
 net/key/af_key.c       |    4 ++--
 net/xfrm/xfrm_policy.c |    6 +++---
 net/xfrm/xfrm_user.c   |    2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index ec2b7a9..1dc4ff0 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1435,7 +1435,7 @@ static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
 struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
 
 extern void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type);
-extern int xfrm_policy_walk(struct xfrm_policy_walk *walk,
+extern int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
 	int (*func)(struct xfrm_policy *, int, int, void*), void *);
 extern void xfrm_policy_walk_done(struct xfrm_policy_walk *walk);
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index ca26811..a0d8498 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1846,7 +1846,7 @@ static u32 gen_reqid(void)
 		if (reqid == 0)
 			reqid = IPSEC_MANUAL_REQID_MAX+1;
 		xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN);
-		rc = xfrm_policy_walk(&walk, check_reqid, (void*)&reqid);
+		rc = xfrm_policy_walk(&init_net, &walk, check_reqid, (void*)&reqid);
 		xfrm_policy_walk_done(&walk);
 		if (rc != -EEXIST)
 			return reqid;
@@ -2633,7 +2633,7 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr)
 
 static int pfkey_dump_sp(struct pfkey_sock *pfk)
 {
-	return xfrm_policy_walk(&pfk->dump.u.policy, dump_sp, (void *) pfk);
+	return xfrm_policy_walk(&init_net, &pfk->dump.u.policy, dump_sp, (void *) pfk);
 }
 
 static void pfkey_dump_sp_done(struct pfkey_sock *pfk)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 96895ef..6165218 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -851,7 +851,7 @@ out:
 }
 EXPORT_SYMBOL(xfrm_policy_flush);
 
-int xfrm_policy_walk(struct xfrm_policy_walk *walk,
+int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
 		     int (*func)(struct xfrm_policy *, int, int, void*),
 		     void *data)
 {
@@ -868,10 +868,10 @@ int xfrm_policy_walk(struct xfrm_policy_walk *walk,
 
 	write_lock_bh(&xfrm_policy_lock);
 	if (list_empty(&walk->walk.all))
-		x = list_first_entry(&init_net.xfrm.policy_all, struct xfrm_policy_walk_entry, all);
+		x = list_first_entry(&net->xfrm.policy_all, struct xfrm_policy_walk_entry, all);
 	else
 		x = list_entry(&walk->walk.all, struct xfrm_policy_walk_entry, all);
-	list_for_each_entry_from(x, &init_net.xfrm.policy_all, all) {
+	list_for_each_entry_from(x, &net->xfrm.policy_all, all) {
 		if (x->dead)
 			continue;
 		pol = container_of(x, struct xfrm_policy, walk);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index efd6ab5..f6e0272 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1279,7 +1279,7 @@ static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb)
 		xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY);
 	}
 
-	(void) xfrm_policy_walk(walk, dump_one_policy, &info);
+	(void) xfrm_policy_walk(&init_net, walk, dump_one_policy, &info);
 
 	return skb->len;
 }
-- 
1.5.6.5


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

* [PATCH 34/53] netns xfrm: lookup in netns
  2008-11-25 17:27                                                               ` [PATCH 33/53] netns xfrm: policy walking " Alexey Dobriyan
@ 2008-11-25 17:27                                                                 ` Alexey Dobriyan
  2008-11-25 17:27                                                                   ` [PATCH 35/53] netns xfrm: xfrm_policy_check " Alexey Dobriyan
  2008-11-26  1:35                                                                   ` [PATCH 34/53] netns xfrm: lookup " David Miller
  2008-11-26  1:34                                                                 ` [PATCH 33/53] netns xfrm: policy walking " David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Pass netns to xfrm_lookup()/__xfrm_lookup(). For that pass netns
to flow_cache_lookup() and resolver callback.

Take it from socket or netdevice. Stub DECnet to init_net.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/dst.h                |   16 ++++++++--------
 include/net/flow.h               |    9 +++++----
 net/core/flow.c                  |    4 ++--
 net/dccp/ipv6.c                  |   10 +++++-----
 net/decnet/dn_route.c            |    6 +++---
 net/ipv4/icmp.c                  |    4 ++--
 net/ipv4/netfilter.c             |    4 ++--
 net/ipv4/route.c                 |    2 +-
 net/ipv6/af_inet6.c              |    2 +-
 net/ipv6/datagram.c              |    3 ++-
 net/ipv6/icmp.c                  |    6 +++---
 net/ipv6/inet6_connection_sock.c |    2 +-
 net/ipv6/ip6_tunnel.c            |    5 +++--
 net/ipv6/mcast.c                 |    4 ++--
 net/ipv6/ndisc.c                 |    4 ++--
 net/ipv6/netfilter.c             |    2 +-
 net/ipv6/netfilter/ip6t_REJECT.c |    2 +-
 net/ipv6/raw.c                   |    3 ++-
 net/ipv6/syncookies.c            |    2 +-
 net/ipv6/tcp_ipv6.c              |   11 ++++++-----
 net/ipv6/udp.c                   |    3 ++-
 net/xfrm/xfrm_policy.c           |   38 ++++++++++++++++++++------------------
 22 files changed, 75 insertions(+), 67 deletions(-)

diff --git a/include/net/dst.h b/include/net/dst.h
index 6c77879..6be3b08 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -291,21 +291,21 @@ enum {
 
 struct flowi;
 #ifndef CONFIG_XFRM
-static inline int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
-		       struct sock *sk, int flags)
+static inline int xfrm_lookup(struct net *net, struct dst_entry **dst_p,
+			      struct flowi *fl, struct sock *sk, int flags)
 {
 	return 0;
 } 
-static inline int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
-				struct sock *sk, int flags)
+static inline int __xfrm_lookup(struct net *net, struct dst_entry **dst_p,
+				struct flowi *fl, struct sock *sk, int flags)
 {
 	return 0;
 }
 #else
-extern int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
-		       struct sock *sk, int flags);
-extern int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
-			 struct sock *sk, int flags);
+extern int xfrm_lookup(struct net *net, struct dst_entry **dst_p,
+		       struct flowi *fl, struct sock *sk, int flags);
+extern int __xfrm_lookup(struct net *net, struct dst_entry **dst_p,
+			 struct flowi *fl, struct sock *sk, int flags);
 #endif
 #endif
 
diff --git a/include/net/flow.h b/include/net/flow.h
index b45a5e4..809970b 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -84,12 +84,13 @@ struct flowi {
 #define FLOW_DIR_OUT	1
 #define FLOW_DIR_FWD	2
 
+struct net;
 struct sock;
-typedef int (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir,
-			       void **objp, atomic_t **obj_refp);
+typedef int (*flow_resolve_t)(struct net *net, struct flowi *key, u16 family,
+			      u8 dir, void **objp, atomic_t **obj_refp);
 
-extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
-	 		       flow_resolve_t resolver);
+extern void *flow_cache_lookup(struct net *net, struct flowi *key, u16 family,
+			       u8 dir, flow_resolve_t resolver);
 extern void flow_cache_flush(void);
 extern atomic_t flow_cache_genid;
 
diff --git a/net/core/flow.c b/net/core/flow.c
index d323388..9601587 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -165,7 +165,7 @@ static int flow_key_compare(struct flowi *key1, struct flowi *key2)
 	return 0;
 }
 
-void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
+void *flow_cache_lookup(struct net *net, struct flowi *key, u16 family, u8 dir,
 			flow_resolve_t resolver)
 {
 	struct flow_cache_entry *fle, **head;
@@ -225,7 +225,7 @@ nocache:
 		void *obj;
 		atomic_t *obj_ref;
 
-		err = resolver(key, family, dir, &obj, &obj_ref);
+		err = resolver(net, key, family, dir, &obj, &obj_ref);
 
 		if (fle && !err) {
 			fle->genid = atomic_read(&flow_cache_genid);
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index f033e84..b963f35 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -168,7 +168,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 				goto out;
 			}
 
-			err = xfrm_lookup(&dst, &fl, sk, 0);
+			err = xfrm_lookup(net, &dst, &fl, sk, 0);
 			if (err < 0) {
 				sk->sk_err_soft = -err;
 				goto out;
@@ -279,7 +279,7 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req)
 	if (final_p)
 		ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-	err = xfrm_lookup(&dst, &fl, sk, 0);
+	err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0);
 	if (err < 0)
 		goto done;
 
@@ -343,7 +343,7 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
 
 	/* sk = NULL, but it is safe for now. RST socket required. */
 	if (!ip6_dst_lookup(ctl_sk, &skb->dst, &fl)) {
-		if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
+		if (xfrm_lookup(net, &skb->dst, &fl, NULL, 0) >= 0) {
 			ip6_xmit(ctl_sk, skb, &fl, NULL, 0);
 			DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
 			DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
@@ -569,7 +569,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
 		if (final_p)
 			ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-		if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+		if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0)
 			goto out;
 	}
 
@@ -1004,7 +1004,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
 	if (final_p)
 		ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-	err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT);
+	err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT);
 	if (err < 0) {
 		if (err == -EREMOTE)
 			err = ip6_dst_blackhole(sk, &dst, &fl);
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 768df00..eeaa3d8 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1184,7 +1184,7 @@ static int dn_route_output_key(struct dst_entry **pprt, struct flowi *flp, int f
 
 	err = __dn_route_output_key(pprt, flp, flags);
 	if (err == 0 && flp->proto) {
-		err = xfrm_lookup(pprt, flp, NULL, 0);
+		err = xfrm_lookup(&init_net, pprt, flp, NULL, 0);
 	}
 	return err;
 }
@@ -1195,8 +1195,8 @@ int dn_route_output_sock(struct dst_entry **pprt, struct flowi *fl, struct sock
 
 	err = __dn_route_output_key(pprt, fl, flags & MSG_TRYHARD);
 	if (err == 0 && fl->proto) {
-		err = xfrm_lookup(pprt, fl, sk, (flags & MSG_DONTWAIT) ?
-						0 : XFRM_LOOKUP_WAIT);
+		err = xfrm_lookup(&init_net, pprt, fl, sk,
+				 (flags & MSG_DONTWAIT) ? 0 : XFRM_LOOKUP_WAIT);
 	}
 	return err;
 }
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 21e497e..893e070 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -562,7 +562,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
 		/* No need to clone since we're just using its address. */
 		rt2 = rt;
 
-		err = xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
+		err = xfrm_lookup(net, (struct dst_entry **)&rt, &fl, NULL, 0);
 		switch (err) {
 		case 0:
 			if (rt != rt2)
@@ -601,7 +601,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
 		if (err)
 			goto relookup_failed;
 
-		err = xfrm_lookup((struct dst_entry **)&rt2, &fl, NULL,
+		err = xfrm_lookup(net, (struct dst_entry **)&rt2, &fl, NULL,
 				  XFRM_LOOKUP_ICMP);
 		switch (err) {
 		case 0:
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 6efdb70..c99eecf 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -66,7 +66,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
 #ifdef CONFIG_XFRM
 	if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
 	    xfrm_decode_session(skb, &fl, AF_INET) == 0)
-		if (xfrm_lookup(&skb->dst, &fl, skb->sk, 0))
+		if (xfrm_lookup(net, &skb->dst, &fl, skb->sk, 0))
 			return -1;
 #endif
 
@@ -97,7 +97,7 @@ int ip_xfrm_me_harder(struct sk_buff *skb)
 		dst = ((struct xfrm_dst *)dst)->route;
 	dst_hold(dst);
 
-	if (xfrm_lookup(&dst, &fl, skb->sk, 0) < 0)
+	if (xfrm_lookup(dev_net(dst->dev), &dst, &fl, skb->sk, 0) < 0)
 		return -1;
 
 	dst_release(skb->dst);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 4e6959c..77bfba9 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2761,7 +2761,7 @@ int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp,
 			flp->fl4_src = (*rp)->rt_src;
 		if (!flp->fl4_dst)
 			flp->fl4_dst = (*rp)->rt_dst;
-		err = __xfrm_lookup((struct dst_entry **)rp, flp, sk,
+		err = __xfrm_lookup(net, (struct dst_entry **)rp, flp, sk,
 				    flags ? XFRM_LOOKUP_WAIT : 0);
 		if (err == -EREMOTE)
 			err = ipv4_dst_blackhole(net, rp, flp);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 01edac8..437b750 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -637,7 +637,7 @@ int inet6_sk_rebuild_header(struct sock *sk)
 		if (final_p)
 			ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+		if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) {
 			sk->sk_err_soft = -err;
 			return err;
 		}
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index e44deb8..e2bdc6d 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -175,7 +175,8 @@ ipv4_connected:
 	if (final_p)
 		ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-	if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) {
+	err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT);
+	if (err < 0) {
 		if (err == -EREMOTE)
 			err = ip6_dst_blackhole(sk, &dst, &fl);
 		if (err < 0)
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index a77b8d1..4f43384 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -427,7 +427,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
 	/* No need to clone since we're just using its address. */
 	dst2 = dst;
 
-	err = xfrm_lookup(&dst, &fl, sk, 0);
+	err = xfrm_lookup(net, &dst, &fl, sk, 0);
 	switch (err) {
 	case 0:
 		if (dst != dst2)
@@ -446,7 +446,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
 	if (ip6_dst_lookup(sk, &dst2, &fl))
 		goto relookup_failed;
 
-	err = xfrm_lookup(&dst2, &fl, sk, XFRM_LOOKUP_ICMP);
+	err = xfrm_lookup(net, &dst2, &fl, sk, XFRM_LOOKUP_ICMP);
 	switch (err) {
 	case 0:
 		dst_release(dst);
@@ -552,7 +552,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
 	err = ip6_dst_lookup(sk, &dst, &fl);
 	if (err)
 		goto out;
-	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+	if ((err = xfrm_lookup(net, &dst, &fl, sk, 0)) < 0)
 		goto out;
 
 	if (ipv6_addr_is_multicast(&fl.fl6_dst))
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 16d43f2..3c3732d 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -219,7 +219,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
 		if (final_p)
 			ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+		if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) {
 			sk->sk_route_caps = 0;
 			kfree_skb(skb);
 			return err;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index ef249ab..58e2b0d 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -846,6 +846,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
 			 int encap_limit,
 			 __u32 *pmtu)
 {
+	struct net *net = dev_net(dev);
 	struct ip6_tnl *t = netdev_priv(dev);
 	struct net_device_stats *stats = &t->dev->stats;
 	struct ipv6hdr *ipv6h = ipv6_hdr(skb);
@@ -861,9 +862,9 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
 	if ((dst = ip6_tnl_dst_check(t)) != NULL)
 		dst_hold(dst);
 	else {
-		dst = ip6_route_output(dev_net(dev), NULL, fl);
+		dst = ip6_route_output(net, NULL, fl);
 
-		if (dst->error || xfrm_lookup(&dst, fl, NULL, 0) < 0)
+		if (dst->error || xfrm_lookup(net, &dst, fl, NULL, 0) < 0)
 			goto tx_err_link_failure;
 	}
 
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 870a1d6..0f38960 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1466,7 +1466,7 @@ static void mld_sendpack(struct sk_buff *skb)
 			 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
 			 skb->dev->ifindex);
 
-	err = xfrm_lookup(&skb->dst, &fl, NULL, 0);
+	err = xfrm_lookup(net, &skb->dst, &fl, NULL, 0);
 	if (err)
 		goto err_out;
 
@@ -1831,7 +1831,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
 			 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
 			 skb->dev->ifindex);
 
-	err = xfrm_lookup(&skb->dst, &fl, NULL, 0);
+	err = xfrm_lookup(net, &skb->dst, &fl, NULL, 0);
 	if (err)
 		goto err_out;
 
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index af6705f..e4acc21 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -524,7 +524,7 @@ void ndisc_send_skb(struct sk_buff *skb,
 		return;
 	}
 
-	err = xfrm_lookup(&dst, &fl, NULL, 0);
+	err = xfrm_lookup(net, &dst, &fl, NULL, 0);
 	if (err < 0) {
 		kfree_skb(skb);
 		return;
@@ -1524,7 +1524,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
 	if (dst == NULL)
 		return;
 
-	err = xfrm_lookup(&dst, &fl, NULL, 0);
+	err = xfrm_lookup(net, &dst, &fl, NULL, 0);
 	if (err)
 		return;
 
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index fd5b3a4..627e21d 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -29,7 +29,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
 #ifdef CONFIG_XFRM
 	if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
 	    xfrm_decode_session(skb, &fl, AF_INET6) == 0)
-		if (xfrm_lookup(&skb->dst, &fl, skb->sk, 0))
+		if (xfrm_lookup(net, &skb->dst, &fl, skb->sk, 0))
 			return -1;
 #endif
 
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 0981b4c..5a2d0a4 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -97,7 +97,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
 	dst = ip6_route_output(net, NULL, &fl);
 	if (dst == NULL)
 		return;
-	if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0))
+	if (dst->error || xfrm_lookup(net, &dst, &fl, NULL, 0))
 		return;
 
 	hh_len = (dst->dev->hard_header_len + 15)&~15;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 2ba04d4..61f6827 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -860,7 +860,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
 	if (final_p)
 		ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-	if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) {
+	err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT);
+	if (err < 0) {
 		if (err == -EREMOTE)
 			err = ip6_dst_blackhole(sk, &dst, &fl);
 		if (err < 0)
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 676c80b..711175e 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -259,7 +259,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
 
 		if (final_p)
 			ipv6_addr_copy(&fl.fl6_dst, final_p);
-		if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+		if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0)
 			goto out_free;
 	}
 
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index a5d750a..f259c96 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -260,7 +260,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
 	if (final_p)
 		ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-	if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) {
+	err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT);
+	if (err < 0) {
 		if (err == -EREMOTE)
 			err = ip6_dst_blackhole(sk, &dst, &fl);
 		if (err < 0)
@@ -390,7 +391,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 				goto out;
 			}
 
-			if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+			if ((err = xfrm_lookup(net, &dst, &fl, sk, 0)) < 0) {
 				sk->sk_err_soft = -err;
 				goto out;
 			}
@@ -492,7 +493,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
 		goto done;
 	if (final_p)
 		ipv6_addr_copy(&fl.fl6_dst, final_p);
-	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+	if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0)
 		goto done;
 
 	skb = tcp_make_synack(sk, dst, req);
@@ -1018,7 +1019,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
 	 * namespace
 	 */
 	if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) {
-		if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
+		if (xfrm_lookup(net, &buff->dst, &fl, NULL, 0) >= 0) {
 			ip6_xmit(ctl_sk, buff, &fl, NULL, 0);
 			TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
 			if (rst)
@@ -1316,7 +1317,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 		if (final_p)
 			ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-		if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+		if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0)
 			goto out;
 	}
 
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index fd2d9ad..38390dd 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -849,7 +849,8 @@ do_udp_sendmsg:
 	if (final_p)
 		ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-	if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) {
+	err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT);
+	if (err < 0) {
 		if (err == -EREMOTE)
 			err = ip6_dst_blackhole(sk, &dst, &fl);
 		if (err < 0)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 6165218..7c88a25 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -940,7 +940,8 @@ static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl,
 	return ret;
 }
 
-static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
+static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type,
+						     struct flowi *fl,
 						     u16 family, u8 dir)
 {
 	int err;
@@ -956,7 +957,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
 		return NULL;
 
 	read_lock_bh(&xfrm_policy_lock);
-	chain = policy_hash_direct(&init_net, daddr, saddr, family, dir);
+	chain = policy_hash_direct(net, daddr, saddr, family, dir);
 	ret = NULL;
 	hlist_for_each_entry(pol, entry, chain, bydst) {
 		err = xfrm_policy_match(pol, fl, type, family, dir);
@@ -973,7 +974,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
 			break;
 		}
 	}
-	chain = &init_net.xfrm.policy_inexact[dir];
+	chain = &net->xfrm.policy_inexact[dir];
 	hlist_for_each_entry(pol, entry, chain, bydst) {
 		err = xfrm_policy_match(pol, fl, type, family, dir);
 		if (err) {
@@ -996,14 +997,14 @@ fail:
 	return ret;
 }
 
-static int xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
-			       void **objp, atomic_t **obj_refp)
+static int xfrm_policy_lookup(struct net *net, struct flowi *fl, u16 family,
+			      u8 dir, void **objp, atomic_t **obj_refp)
 {
 	struct xfrm_policy *pol;
 	int err = 0;
 
 #ifdef CONFIG_XFRM_SUB_POLICY
-	pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_SUB, fl, family, dir);
+	pol = xfrm_policy_lookup_bytype(net, XFRM_POLICY_TYPE_SUB, fl, family, dir);
 	if (IS_ERR(pol)) {
 		err = PTR_ERR(pol);
 		pol = NULL;
@@ -1011,7 +1012,7 @@ static int xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
 	if (pol || err)
 		goto end;
 #endif
-	pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN, fl, family, dir);
+	pol = xfrm_policy_lookup_bytype(net, XFRM_POLICY_TYPE_MAIN, fl, family, dir);
 	if (IS_ERR(pol)) {
 		err = PTR_ERR(pol);
 		pol = NULL;
@@ -1537,7 +1538,7 @@ static int stale_bundle(struct dst_entry *dst);
  * At the moment we eat a raw IP route. Mostly to speed up lookups
  * on interfaces with disabled IPsec.
  */
-int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
+int __xfrm_lookup(struct net *net, struct dst_entry **dst_p, struct flowi *fl,
 		  struct sock *sk, int flags)
 {
 	struct xfrm_policy *policy;
@@ -1575,10 +1576,10 @@ restart:
 	if (!policy) {
 		/* To accelerate a bit...  */
 		if ((dst_orig->flags & DST_NOXFRM) ||
-		    !init_net.xfrm.policy_count[XFRM_POLICY_OUT])
+		    !net->xfrm.policy_count[XFRM_POLICY_OUT])
 			goto nopol;
 
-		policy = flow_cache_lookup(fl, dst_orig->ops->family,
+		policy = flow_cache_lookup(net, fl, dst_orig->ops->family,
 					   dir, xfrm_policy_lookup);
 		err = PTR_ERR(policy);
 		if (IS_ERR(policy)) {
@@ -1635,7 +1636,8 @@ restart:
 
 #ifdef CONFIG_XFRM_SUB_POLICY
 		if (pols[0]->type != XFRM_POLICY_TYPE_MAIN) {
-			pols[1] = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN,
+			pols[1] = xfrm_policy_lookup_bytype(net,
+							    XFRM_POLICY_TYPE_MAIN,
 							    fl, family,
 							    XFRM_POLICY_OUT);
 			if (pols[1]) {
@@ -1683,11 +1685,11 @@ restart:
 			if (err == -EAGAIN && (flags & XFRM_LOOKUP_WAIT)) {
 				DECLARE_WAITQUEUE(wait, current);
 
-				add_wait_queue(&init_net.xfrm.km_waitq, &wait);
+				add_wait_queue(&net->xfrm.km_waitq, &wait);
 				set_current_state(TASK_INTERRUPTIBLE);
 				schedule();
 				set_current_state(TASK_RUNNING);
-				remove_wait_queue(&init_net.xfrm.km_waitq, &wait);
+				remove_wait_queue(&net->xfrm.km_waitq, &wait);
 
 				nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family);
 
@@ -1781,10 +1783,10 @@ nopol:
 }
 EXPORT_SYMBOL(__xfrm_lookup);
 
-int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
+int xfrm_lookup(struct net *net, struct dst_entry **dst_p, struct flowi *fl,
 		struct sock *sk, int flags)
 {
-	int err = __xfrm_lookup(dst_p, fl, sk, flags);
+	int err = __xfrm_lookup(net, dst_p, fl, sk, flags);
 
 	if (err == -EREMOTE) {
 		dst_release(*dst_p);
@@ -1936,7 +1938,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 	}
 
 	if (!pol)
-		pol = flow_cache_lookup(&fl, family, fl_dir,
+		pol = flow_cache_lookup(&init_net, &fl, family, fl_dir,
 					xfrm_policy_lookup);
 
 	if (IS_ERR(pol)) {
@@ -1959,7 +1961,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 	npols ++;
 #ifdef CONFIG_XFRM_SUB_POLICY
 	if (pols[0]->type != XFRM_POLICY_TYPE_MAIN) {
-		pols[1] = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN,
+		pols[1] = xfrm_policy_lookup_bytype(&init_net, XFRM_POLICY_TYPE_MAIN,
 						    &fl, family,
 						    XFRM_POLICY_IN);
 		if (pols[1]) {
@@ -2049,7 +2051,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
 		return 0;
 	}
 
-	return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0;
+	return xfrm_lookup(&init_net, &skb->dst, &fl, NULL, 0) == 0;
 }
 EXPORT_SYMBOL(__xfrm_route_forward);
 
-- 
1.5.6.5


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

* [PATCH 35/53] netns xfrm: xfrm_policy_check in netns
  2008-11-25 17:27                                                                 ` [PATCH 34/53] netns xfrm: lookup " Alexey Dobriyan
@ 2008-11-25 17:27                                                                   ` Alexey Dobriyan
  2008-11-25 17:27                                                                     ` [PATCH 36/53] netns xfrm: xfrm_route_forward() " Alexey Dobriyan
  2008-11-26  1:35                                                                     ` [PATCH 35/53] netns xfrm: xfrm_policy_check " David Miller
  2008-11-26  1:35                                                                   ` [PATCH 34/53] netns xfrm: lookup " David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h     |    3 ++-
 net/xfrm/xfrm_policy.c |    5 +++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 1dc4ff0..158848f 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -992,12 +992,13 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir,
 				       struct sk_buff *skb,
 				       unsigned int family, int reverse)
 {
+	struct net *net = dev_net(skb->dev);
 	int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
 
 	if (sk && sk->sk_policy[XFRM_POLICY_IN])
 		return __xfrm_policy_check(sk, ndir, skb, family);
 
-	return	(!init_net.xfrm.policy_count[dir] && !skb->sp) ||
+	return	(!net->xfrm.policy_count[dir] && !skb->sp) ||
 		(skb->dst->flags & DST_NOPOLICY) ||
 		__xfrm_policy_check(sk, ndir, skb, family);
 }
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 7c88a25..8097c99 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1894,6 +1894,7 @@ static inline int secpath_has_nontransport(struct sec_path *sp, int k, int *idxp
 int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 			unsigned short family)
 {
+	struct net *net = dev_net(skb->dev);
 	struct xfrm_policy *pol;
 	struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
 	int npols = 0;
@@ -1938,7 +1939,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 	}
 
 	if (!pol)
-		pol = flow_cache_lookup(&init_net, &fl, family, fl_dir,
+		pol = flow_cache_lookup(net, &fl, family, fl_dir,
 					xfrm_policy_lookup);
 
 	if (IS_ERR(pol)) {
@@ -1961,7 +1962,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 	npols ++;
 #ifdef CONFIG_XFRM_SUB_POLICY
 	if (pols[0]->type != XFRM_POLICY_TYPE_MAIN) {
-		pols[1] = xfrm_policy_lookup_bytype(&init_net, XFRM_POLICY_TYPE_MAIN,
+		pols[1] = xfrm_policy_lookup_bytype(net, XFRM_POLICY_TYPE_MAIN,
 						    &fl, family,
 						    XFRM_POLICY_IN);
 		if (pols[1]) {
-- 
1.5.6.5


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

* [PATCH 36/53] netns xfrm: xfrm_route_forward() in netns
  2008-11-25 17:27                                                                   ` [PATCH 35/53] netns xfrm: xfrm_policy_check " Alexey Dobriyan
@ 2008-11-25 17:27                                                                     ` Alexey Dobriyan
  2008-11-25 17:27                                                                       ` [PATCH 37/53] netns xfrm: flushing/pruning bundles " Alexey Dobriyan
  2008-11-26  1:36                                                                       ` [PATCH 36/53] netns xfrm: xfrm_route_forward() " David Miller
  2008-11-26  1:35                                                                     ` [PATCH 35/53] netns xfrm: xfrm_policy_check " David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h     |    4 +++-
 net/xfrm/xfrm_policy.c |    3 ++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 158848f..36c8cff 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1050,7 +1050,9 @@ extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
 
 static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
 {
-	return	!init_net.xfrm.policy_count[XFRM_POLICY_OUT] ||
+	struct net *net = dev_net(skb->dev);
+
+	return	!net->xfrm.policy_count[XFRM_POLICY_OUT] ||
 		(skb->dst->flags & DST_NOXFRM) ||
 		__xfrm_route_forward(skb, family);
 }
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 8097c99..54b50a2 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2044,6 +2044,7 @@ EXPORT_SYMBOL(__xfrm_policy_check);
 
 int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
 {
+	struct net *net = dev_net(skb->dev);
 	struct flowi fl;
 
 	if (xfrm_decode_session(skb, &fl, family) < 0) {
@@ -2052,7 +2053,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
 		return 0;
 	}
 
-	return xfrm_lookup(&init_net, &skb->dst, &fl, NULL, 0) == 0;
+	return xfrm_lookup(net, &skb->dst, &fl, NULL, 0) == 0;
 }
 EXPORT_SYMBOL(__xfrm_route_forward);
 
-- 
1.5.6.5


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

* [PATCH 37/53] netns xfrm: flushing/pruning bundles in netns
  2008-11-25 17:27                                                                     ` [PATCH 36/53] netns xfrm: xfrm_route_forward() " Alexey Dobriyan
@ 2008-11-25 17:27                                                                       ` Alexey Dobriyan
  2008-11-25 17:27                                                                         ` [PATCH 38/53] netns xfrm: dst garbage-collecting " Alexey Dobriyan
  2008-11-26  1:36                                                                         ` [PATCH 37/53] netns xfrm: flushing/pruning bundles " David Miller
  2008-11-26  1:36                                                                       ` [PATCH 36/53] netns xfrm: xfrm_route_forward() " David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Allow netdevice notifier as result.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/xfrm/xfrm_policy.c |   19 ++++++++-----------
 1 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 54b50a2..49e0898 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2137,7 +2137,7 @@ static void prune_one_bundle(struct xfrm_policy *pol, int (*func)(struct dst_ent
 	write_unlock(&pol->lock);
 }
 
-static void xfrm_prune_bundles(int (*func)(struct dst_entry *))
+static void xfrm_prune_bundles(struct net *net, int (*func)(struct dst_entry *))
 {
 	struct dst_entry *gc_list = NULL;
 	int dir;
@@ -2150,11 +2150,11 @@ static void xfrm_prune_bundles(int (*func)(struct dst_entry *))
 		int i;
 
 		hlist_for_each_entry(pol, entry,
-				     &init_net.xfrm.policy_inexact[dir], bydst)
+				     &net->xfrm.policy_inexact[dir], bydst)
 			prune_one_bundle(pol, func, &gc_list);
 
-		table = init_net.xfrm.policy_bydst[dir].table;
-		for (i = init_net.xfrm.policy_bydst[dir].hmask; i >= 0; i--) {
+		table = net->xfrm.policy_bydst[dir].table;
+		for (i = net->xfrm.policy_bydst[dir].hmask; i >= 0; i--) {
 			hlist_for_each_entry(pol, entry, table + i, bydst)
 				prune_one_bundle(pol, func, &gc_list);
 		}
@@ -2175,12 +2175,12 @@ static int unused_bundle(struct dst_entry *dst)
 
 static void __xfrm_garbage_collect(void)
 {
-	xfrm_prune_bundles(unused_bundle);
+	xfrm_prune_bundles(&init_net, unused_bundle);
 }
 
-static int xfrm_flush_bundles(void)
+static int xfrm_flush_bundles(struct net *net)
 {
-	xfrm_prune_bundles(stale_bundle);
+	xfrm_prune_bundles(net, stale_bundle);
 	return 0;
 }
 
@@ -2366,12 +2366,9 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void
 {
 	struct net_device *dev = ptr;
 
-	if (!net_eq(dev_net(dev), &init_net))
-		return NOTIFY_DONE;
-
 	switch (event) {
 	case NETDEV_DOWN:
-		xfrm_flush_bundles();
+		xfrm_flush_bundles(dev_net(dev));
 	}
 	return NOTIFY_DONE;
 }
-- 
1.5.6.5


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

* [PATCH 38/53] netns xfrm: dst garbage-collecting in netns
  2008-11-25 17:27                                                                       ` [PATCH 37/53] netns xfrm: flushing/pruning bundles " Alexey Dobriyan
@ 2008-11-25 17:27                                                                         ` Alexey Dobriyan
  2008-11-25 17:27                                                                           ` [PATCH 39/53] netns xfrm: xfrm_input() fixup Alexey Dobriyan
  2008-11-26  1:37                                                                           ` [PATCH 38/53] netns xfrm: dst garbage-collecting in netns David Miller
  2008-11-26  1:36                                                                         ` [PATCH 37/53] netns xfrm: flushing/pruning bundles " David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Pass netns pointer to struct xfrm_policy_afinfo::garbage_collect()

	[This needs more thoughts on what to do with dst_ops]
	[Currently stub to init_net]

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h      |    2 +-
 net/ipv4/xfrm4_policy.c |    2 +-
 net/ipv6/xfrm6_policy.c |    2 +-
 net/xfrm/xfrm_policy.c  |    4 ++--
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 36c8cff..bd25150 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -265,7 +265,7 @@ struct xfrm_dst;
 struct xfrm_policy_afinfo {
 	unsigned short		family;
 	struct dst_ops		*dst_ops;
-	void			(*garbage_collect)(void);
+	void			(*garbage_collect)(struct net *net);
 	struct dst_entry	*(*dst_lookup)(int tos, xfrm_address_t *saddr,
 					       xfrm_address_t *daddr);
 	int			(*get_saddr)(xfrm_address_t *saddr, xfrm_address_t *daddr);
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 84dbb5a..a881ca3 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -187,7 +187,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
 
 static inline int xfrm4_garbage_collect(struct dst_ops *ops)
 {
-	xfrm4_policy_afinfo.garbage_collect();
+	xfrm4_policy_afinfo.garbage_collect(&init_net);
 	return (atomic_read(&xfrm4_dst_ops.entries) > xfrm4_dst_ops.gc_thresh*2);
 }
 
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 3b67ce7..2df8a78 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -220,7 +220,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
 
 static inline int xfrm6_garbage_collect(struct dst_ops *ops)
 {
-	xfrm6_policy_afinfo.garbage_collect();
+	xfrm6_policy_afinfo.garbage_collect(&init_net);
 	return (atomic_read(&xfrm6_dst_ops.entries) > xfrm6_dst_ops.gc_thresh*2);
 }
 
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 49e0898..7ebbdd6 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2173,9 +2173,9 @@ static int unused_bundle(struct dst_entry *dst)
 	return !atomic_read(&dst->__refcnt);
 }
 
-static void __xfrm_garbage_collect(void)
+static void __xfrm_garbage_collect(struct net *net)
 {
-	xfrm_prune_bundles(&init_net, unused_bundle);
+	xfrm_prune_bundles(net, unused_bundle);
 }
 
 static int xfrm_flush_bundles(struct net *net)
-- 
1.5.6.5


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

* [PATCH 39/53] netns xfrm: xfrm_input() fixup
  2008-11-25 17:27                                                                         ` [PATCH 38/53] netns xfrm: dst garbage-collecting " Alexey Dobriyan
@ 2008-11-25 17:27                                                                           ` Alexey Dobriyan
  2008-11-25 17:27                                                                             ` [PATCH 40/53] netns xfrm: per-netns NETLINK_XFRM socket Alexey Dobriyan
  2008-11-26  1:38                                                                             ` [PATCH 39/53] netns xfrm: xfrm_input() fixup David Miller
  2008-11-26  1:37                                                                           ` [PATCH 38/53] netns xfrm: dst garbage-collecting in netns David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/xfrm/xfrm_input.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index c08a93e..a714dce 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -104,6 +104,7 @@ EXPORT_SYMBOL(xfrm_prepare_input);
 
 int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 {
+	struct net *net = dev_net(skb->dev);
 	int err;
 	__be32 seq;
 	struct xfrm_state *x;
@@ -151,7 +152,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 			goto drop;
 		}
 
-		x = xfrm_state_lookup(&init_net, daddr, spi, nexthdr, family);
+		x = xfrm_state_lookup(net, daddr, spi, nexthdr, family);
 		if (x == NULL) {
 			XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES);
 			xfrm_audit_state_notfound(skb, family, spi, seq);
-- 
1.5.6.5


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

* [PATCH 40/53] netns xfrm: per-netns NETLINK_XFRM socket
  2008-11-25 17:27                                                                           ` [PATCH 39/53] netns xfrm: xfrm_input() fixup Alexey Dobriyan
@ 2008-11-25 17:27                                                                             ` Alexey Dobriyan
  2008-11-25 17:27                                                                               ` [PATCH 41/53] netns xfrm: xfrm_user module in netns Alexey Dobriyan
  2008-11-26  1:38                                                                               ` [PATCH 40/53] netns xfrm: per-netns NETLINK_XFRM socket David Miller
  2008-11-26  1:38                                                                             ` [PATCH 39/53] netns xfrm: xfrm_input() fixup David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Stub senders to init_net's one temporarily.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/xfrm.h |    2 +
 include/net/xfrm.h       |    7 ++-
 net/xfrm/xfrm_output.c   |    3 +-
 net/xfrm/xfrm_state.c    |    7 +--
 net/xfrm/xfrm_user.c     |  108 +++++++++++++++++++++++++++++++---------------
 5 files changed, 83 insertions(+), 44 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index c53d173..09f3060 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -39,6 +39,8 @@ struct netns_xfrm {
 	struct xfrm_policy_hash	policy_bydst[XFRM_POLICY_MAX * 2];
 	unsigned int		policy_count[XFRM_POLICY_MAX * 2];
 	struct work_struct	policy_hash_work;
+
+	struct sock		*nlsk;
 };
 
 #endif
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index bd25150..e027179 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -48,7 +48,6 @@ DECLARE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics);
 #define XFRM_INC_STATS_USER(field)
 #endif
 
-extern struct sock *xfrm_nl;
 extern u32 sysctl_xfrm_aevent_etime;
 extern u32 sysctl_xfrm_aevent_rseqth;
 extern int sysctl_xfrm_larval_drop;
@@ -1516,18 +1515,20 @@ static inline int xfrm_policy_id2dir(u32 index)
 	return index & 7;
 }
 
-static inline int xfrm_aevent_is_on(void)
+#ifdef CONFIG_XFRM
+static inline int xfrm_aevent_is_on(struct net *net)
 {
 	struct sock *nlsk;
 	int ret = 0;
 
 	rcu_read_lock();
-	nlsk = rcu_dereference(xfrm_nl);
+	nlsk = rcu_dereference(net->xfrm.nlsk);
 	if (nlsk)
 		ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
 	rcu_read_unlock();
 	return ret;
 }
+#endif
 
 static inline int xfrm_alg_len(struct xfrm_algo *alg)
 {
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index dc50f1e..ba90e5e 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -41,6 +41,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
 {
 	struct dst_entry *dst = skb->dst;
 	struct xfrm_state *x = dst->xfrm;
+	struct net *net = xs_net(x);
 
 	if (err <= 0)
 		goto resume;
@@ -74,7 +75,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
 				err = -EOVERFLOW;
 				goto error;
 			}
-			if (xfrm_aevent_is_on())
+			if (xfrm_aevent_is_on(net))
 				xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
 		}
 
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index ea340bb..21db37a 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -24,9 +24,6 @@
 
 #include "xfrm_hash.h"
 
-struct sock *xfrm_nl;
-EXPORT_SYMBOL(xfrm_nl);
-
 u32 sysctl_xfrm_aevent_etime __read_mostly = XFRM_AE_ETIME;
 EXPORT_SYMBOL(sysctl_xfrm_aevent_etime);
 
@@ -1659,7 +1656,7 @@ static void xfrm_replay_timer_handler(unsigned long data)
 	spin_lock(&x->lock);
 
 	if (x->km.state == XFRM_STATE_VALID) {
-		if (xfrm_aevent_is_on())
+		if (xfrm_aevent_is_on(xs_net(x)))
 			xfrm_replay_notify(x, XFRM_REPLAY_TIMEOUT);
 		else
 			x->xflags |= XFRM_TIME_DEFER;
@@ -1715,7 +1712,7 @@ void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
 		x->replay.bitmap |= (1U << diff);
 	}
 
-	if (xfrm_aevent_is_on())
+	if (xfrm_aevent_is_on(xs_net(x)))
 		xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
 }
 
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index f6e0272..8b5b01d 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -703,6 +703,7 @@ nla_put_failure:
 static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = sock_net(skb->sk);
 	struct sk_buff *r_skb;
 	u32 *flags = nlmsg_data(nlh);
 	u32 spid = NETLINK_CB(skb).pid;
@@ -715,7 +716,7 @@ static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (build_spdinfo(r_skb, spid, seq, *flags) < 0)
 		BUG();
 
-	return nlmsg_unicast(xfrm_nl, r_skb, spid);
+	return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid);
 }
 
 static inline size_t xfrm_sadinfo_msgsize(void)
@@ -756,6 +757,7 @@ nla_put_failure:
 static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = sock_net(skb->sk);
 	struct sk_buff *r_skb;
 	u32 *flags = nlmsg_data(nlh);
 	u32 spid = NETLINK_CB(skb).pid;
@@ -768,12 +770,13 @@ static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (build_sadinfo(r_skb, spid, seq, *flags) < 0)
 		BUG();
 
-	return nlmsg_unicast(xfrm_nl, r_skb, spid);
+	return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid);
 }
 
 static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = &init_net;
 	struct xfrm_usersa_id *p = nlmsg_data(nlh);
 	struct xfrm_state *x;
 	struct sk_buff *resp_skb;
@@ -787,7 +790,7 @@ static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (IS_ERR(resp_skb)) {
 		err = PTR_ERR(resp_skb);
 	} else {
-		err = nlmsg_unicast(xfrm_nl, resp_skb, NETLINK_CB(skb).pid);
+		err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).pid);
 	}
 	xfrm_state_put(x);
 out_noput:
@@ -820,6 +823,7 @@ static int verify_userspi_info(struct xfrm_userspi_info *p)
 static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = &init_net;
 	struct xfrm_state *x;
 	struct xfrm_userspi_info *p;
 	struct sk_buff *resp_skb;
@@ -837,7 +841,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
 
 	x = NULL;
 	if (p->info.seq) {
-		x = xfrm_find_acq_byseq(&init_net, p->info.seq);
+		x = xfrm_find_acq_byseq(net, p->info.seq);
 		if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) {
 			xfrm_state_put(x);
 			x = NULL;
@@ -845,7 +849,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
 	}
 
 	if (!x)
-		x = xfrm_find_acq(&init_net, p->info.mode, p->info.reqid,
+		x = xfrm_find_acq(net, p->info.mode, p->info.reqid,
 				  p->info.id.proto, daddr,
 				  &p->info.saddr, 1,
 				  family);
@@ -863,7 +867,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
 		goto out;
 	}
 
-	err = nlmsg_unicast(xfrm_nl, resp_skb, NETLINK_CB(skb).pid);
+	err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).pid);
 
 out:
 	xfrm_state_put(x);
@@ -1311,6 +1315,7 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
 static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = &init_net;
 	struct xfrm_policy *xp;
 	struct xfrm_userpolicy_id *p;
 	u8 type = XFRM_POLICY_TYPE_MAIN;
@@ -1330,7 +1335,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 		return err;
 
 	if (p->index)
-		xp = xfrm_policy_byid(&init_net, type, p->dir, p->index, delete, &err);
+		xp = xfrm_policy_byid(net, type, p->dir, p->index, delete, &err);
 	else {
 		struct nlattr *rt = attrs[XFRMA_SEC_CTX];
 		struct xfrm_sec_ctx *ctx;
@@ -1347,7 +1352,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 			if (err)
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(&init_net, type, p->dir, &p->sel, ctx,
+		xp = xfrm_policy_bysel_ctx(net, type, p->dir, &p->sel, ctx,
 					   delete, &err);
 		security_xfrm_policy_free(ctx);
 	}
@@ -1361,7 +1366,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 		if (IS_ERR(resp_skb)) {
 			err = PTR_ERR(resp_skb);
 		} else {
-			err = nlmsg_unicast(xfrm_nl, resp_skb,
+			err = nlmsg_unicast(net->xfrm.nlsk, resp_skb,
 					    NETLINK_CB(skb).pid);
 		}
 	} else {
@@ -1457,6 +1462,7 @@ nla_put_failure:
 static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = &init_net;
 	struct xfrm_state *x;
 	struct sk_buff *r_skb;
 	int err;
@@ -1468,7 +1474,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (r_skb == NULL)
 		return -ENOMEM;
 
-	x = xfrm_state_lookup(&init_net, &id->daddr, id->spi, id->proto, id->family);
+	x = xfrm_state_lookup(net, &id->daddr, id->spi, id->proto, id->family);
 	if (x == NULL) {
 		kfree_skb(r_skb);
 		return -ESRCH;
@@ -1486,7 +1492,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
 
 	if (build_aevent(r_skb, x, &c) < 0)
 		BUG();
-	err = nlmsg_unicast(xfrm_nl, r_skb, NETLINK_CB(skb).pid);
+	err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).pid);
 	spin_unlock_bh(&x->lock);
 	xfrm_state_put(x);
 	return err;
@@ -1869,6 +1875,7 @@ static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
 			     struct xfrm_migrate *m, int num_migrate,
 			     struct xfrm_kmaddress *k)
 {
+	struct net *net = &init_net;
 	struct sk_buff *skb;
 
 	skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate, !!k), GFP_ATOMIC);
@@ -1879,7 +1886,7 @@ static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
 	if (build_migrate(skb, m, num_migrate, k, sel, dir, type) < 0)
 		BUG();
 
-	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_MIGRATE, GFP_ATOMIC);
+	return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_MIGRATE, GFP_ATOMIC);
 }
 #else
 static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
@@ -1968,6 +1975,7 @@ static struct xfrm_link {
 
 static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
+	struct net *net = sock_net(skb->sk);
 	struct nlattr *attrs[XFRMA_MAX+1];
 	struct xfrm_link *link;
 	int type, err;
@@ -1989,7 +1997,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 		if (link->dump == NULL)
 			return -EINVAL;
 
-		return netlink_dump_start(xfrm_nl, skb, nlh, link->dump, link->done);
+		return netlink_dump_start(net->xfrm.nlsk, skb, nlh, link->dump, link->done);
 	}
 
 	err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX,
@@ -2033,6 +2041,7 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_eve
 
 static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c)
 {
+	struct net *net = &init_net;
 	struct sk_buff *skb;
 
 	skb = nlmsg_new(xfrm_expire_msgsize(), GFP_ATOMIC);
@@ -2042,11 +2051,12 @@ static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c)
 	if (build_expire(skb, x, c) < 0)
 		BUG();
 
-	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC);
+	return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC);
 }
 
 static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c)
 {
+	struct net *net = &init_net;
 	struct sk_buff *skb;
 
 	skb = nlmsg_new(xfrm_aevent_msgsize(), GFP_ATOMIC);
@@ -2056,11 +2066,12 @@ static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c)
 	if (build_aevent(skb, x, c) < 0)
 		BUG();
 
-	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_AEVENTS, GFP_ATOMIC);
+	return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_AEVENTS, GFP_ATOMIC);
 }
 
 static int xfrm_notify_sa_flush(struct km_event *c)
 {
+	struct net *net = &init_net;
 	struct xfrm_usersa_flush *p;
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
@@ -2081,7 +2092,7 @@ static int xfrm_notify_sa_flush(struct km_event *c)
 
 	nlmsg_end(skb, nlh);
 
-	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
+	return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
 }
 
 static inline size_t xfrm_sa_len(struct xfrm_state *x)
@@ -2111,6 +2122,7 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x)
 
 static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c)
 {
+	struct net *net = &init_net;
 	struct xfrm_usersa_info *p;
 	struct xfrm_usersa_id *id;
 	struct nlmsghdr *nlh;
@@ -2155,7 +2167,7 @@ static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c)
 
 	nlmsg_end(skb, nlh);
 
-	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
+	return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
 
 nla_put_failure:
 	/* Somebody screwed up with xfrm_sa_len! */
@@ -2235,6 +2247,7 @@ nlmsg_failure:
 static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
 			     struct xfrm_policy *xp, int dir)
 {
+	struct net *net = xs_net(x);
 	struct sk_buff *skb;
 
 	skb = nlmsg_new(xfrm_acquire_msgsize(x, xp), GFP_ATOMIC);
@@ -2244,7 +2257,7 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
 	if (build_acquire(skb, x, xt, xp, dir) < 0)
 		BUG();
 
-	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_ACQUIRE, GFP_ATOMIC);
+	return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_ACQUIRE, GFP_ATOMIC);
 }
 
 /* User gives us xfrm_user_policy_info followed by an array of 0
@@ -2344,6 +2357,7 @@ nlmsg_failure:
 
 static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
 {
+	struct net *net = &init_net;
 	struct sk_buff *skb;
 
 	skb = nlmsg_new(xfrm_polexpire_msgsize(xp), GFP_ATOMIC);
@@ -2353,11 +2367,12 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve
 	if (build_polexpire(skb, xp, dir, c) < 0)
 		BUG();
 
-	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC);
+	return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC);
 }
 
 static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c)
 {
+	struct net *net = &init_net;
 	struct xfrm_userpolicy_info *p;
 	struct xfrm_userpolicy_id *id;
 	struct nlmsghdr *nlh;
@@ -2408,7 +2423,7 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
 
 	nlmsg_end(skb, nlh);
 
-	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
+	return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
 
 nlmsg_failure:
 	kfree_skb(skb);
@@ -2417,6 +2432,7 @@ nlmsg_failure:
 
 static int xfrm_notify_policy_flush(struct km_event *c)
 {
+	struct net *net = &init_net;
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
 
@@ -2432,7 +2448,7 @@ static int xfrm_notify_policy_flush(struct km_event *c)
 
 	nlmsg_end(skb, nlh);
 
-	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
+	return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
 
 nlmsg_failure:
 	kfree_skb(skb);
@@ -2491,6 +2507,7 @@ nla_put_failure:
 static int xfrm_send_report(u8 proto, struct xfrm_selector *sel,
 			    xfrm_address_t *addr)
 {
+	struct net *net = &init_net;
 	struct sk_buff *skb;
 
 	skb = nlmsg_new(xfrm_report_msgsize(), GFP_ATOMIC);
@@ -2500,7 +2517,7 @@ static int xfrm_send_report(u8 proto, struct xfrm_selector *sel,
 	if (build_report(skb, proto, sel, addr) < 0)
 		BUG();
 
-	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_REPORT, GFP_ATOMIC);
+	return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_REPORT, GFP_ATOMIC);
 }
 
 static inline size_t xfrm_mapping_msgsize(void)
@@ -2536,6 +2553,7 @@ static int build_mapping(struct sk_buff *skb, struct xfrm_state *x,
 static int xfrm_send_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
 			     __be16 sport)
 {
+	struct net *net = xs_net(x);
 	struct sk_buff *skb;
 
 	if (x->id.proto != IPPROTO_ESP)
@@ -2551,7 +2569,7 @@ static int xfrm_send_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
 	if (build_mapping(skb, x, ipaddr, sport) < 0)
 		BUG();
 
-	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_MAPPING, GFP_ATOMIC);
+	return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_MAPPING, GFP_ATOMIC);
 }
 
 static struct xfrm_mgr netlink_mgr = {
@@ -2565,33 +2583,53 @@ static struct xfrm_mgr netlink_mgr = {
 	.new_mapping	= xfrm_send_mapping,
 };
 
-static int __init xfrm_user_init(void)
+static int __net_init xfrm_user_net_init(struct net *net)
 {
 	struct sock *nlsk;
 
-	printk(KERN_INFO "Initializing XFRM netlink socket\n");
-
-	nlsk = netlink_kernel_create(&init_net, NETLINK_XFRM, XFRMNLGRP_MAX,
+	nlsk = netlink_kernel_create(net, NETLINK_XFRM, XFRMNLGRP_MAX,
 				     xfrm_netlink_rcv, NULL, THIS_MODULE);
 	if (nlsk == NULL)
 		return -ENOMEM;
-	rcu_assign_pointer(xfrm_nl, nlsk);
-
-	xfrm_register_km(&netlink_mgr);
-
+	rcu_assign_pointer(net->xfrm.nlsk, nlsk);
 	return 0;
 }
 
-static void __exit xfrm_user_exit(void)
+static void __net_exit xfrm_user_net_exit(struct net *net)
 {
-	struct sock *nlsk = xfrm_nl;
+	struct sock *nlsk = net->xfrm.nlsk;
 
-	xfrm_unregister_km(&netlink_mgr);
-	rcu_assign_pointer(xfrm_nl, NULL);
+	rcu_assign_pointer(net->xfrm.nlsk, NULL);
 	synchronize_rcu();
 	netlink_kernel_release(nlsk);
 }
 
+static struct pernet_operations xfrm_user_net_ops = {
+	.init = xfrm_user_net_init,
+	.exit = xfrm_user_net_exit,
+};
+
+static int __init xfrm_user_init(void)
+{
+	int rv;
+
+	printk(KERN_INFO "Initializing XFRM netlink socket\n");
+
+	rv = register_pernet_subsys(&xfrm_user_net_ops);
+	if (rv < 0)
+		return rv;
+	rv = xfrm_register_km(&netlink_mgr);
+	if (rv < 0)
+		unregister_pernet_subsys(&xfrm_user_net_ops);
+	return rv;
+}
+
+static void __exit xfrm_user_exit(void)
+{
+	xfrm_unregister_km(&netlink_mgr);
+	unregister_pernet_subsys(&xfrm_user_net_ops);
+}
+
 module_init(xfrm_user_init);
 module_exit(xfrm_user_exit);
 MODULE_LICENSE("GPL");
-- 
1.5.6.5


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

* [PATCH 41/53] netns xfrm: xfrm_user module in netns
  2008-11-25 17:27                                                                             ` [PATCH 40/53] netns xfrm: per-netns NETLINK_XFRM socket Alexey Dobriyan
@ 2008-11-25 17:27                                                                               ` Alexey Dobriyan
  2008-11-25 17:27                                                                                 ` [PATCH 42/53] netns xfrm: pass netns with KM notifications Alexey Dobriyan
       [not found]                                                                                 ` <1227634045-27534-41-git-send-email-adobriyan-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2008-11-26  1:38                                                                               ` [PATCH 40/53] netns xfrm: per-netns NETLINK_XFRM socket David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Grab netns either from netlink socket, state or policy.

SA and SPD flush are in init_net for now, this requires little
attention, see below.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/xfrm/xfrm_user.c |   76 +++++++++++++++++++++++++++++--------------------
 1 files changed, 45 insertions(+), 31 deletions(-)

diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 8b5b01d..ab8b138 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -316,11 +316,12 @@ static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs)
 		x->replay_maxdiff = nla_get_u32(rt);
 }
 
-static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
+static struct xfrm_state *xfrm_state_construct(struct net *net,
+					       struct xfrm_usersa_info *p,
 					       struct nlattr **attrs,
 					       int *errp)
 {
-	struct xfrm_state *x = xfrm_state_alloc(&init_net);
+	struct xfrm_state *x = xfrm_state_alloc(net);
 	int err = -ENOMEM;
 
 	if (!x)
@@ -391,6 +392,7 @@ error_no_put:
 static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = sock_net(skb->sk);
 	struct xfrm_usersa_info *p = nlmsg_data(nlh);
 	struct xfrm_state *x;
 	int err;
@@ -403,7 +405,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (err)
 		return err;
 
-	x = xfrm_state_construct(p, attrs, &err);
+	x = xfrm_state_construct(net, p, attrs, &err);
 	if (!x)
 		return err;
 
@@ -431,7 +433,8 @@ out:
 	return err;
 }
 
-static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
+static struct xfrm_state *xfrm_user_state_lookup(struct net *net,
+						 struct xfrm_usersa_id *p,
 						 struct nlattr **attrs,
 						 int *errp)
 {
@@ -440,7 +443,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
 
 	if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) {
 		err = -ESRCH;
-		x = xfrm_state_lookup(&init_net, &p->daddr, p->spi, p->proto, p->family);
+		x = xfrm_state_lookup(net, &p->daddr, p->spi, p->proto, p->family);
 	} else {
 		xfrm_address_t *saddr = NULL;
 
@@ -451,7 +454,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
 		}
 
 		err = -ESRCH;
-		x = xfrm_state_lookup_byaddr(&init_net, &p->daddr, saddr,
+		x = xfrm_state_lookup_byaddr(net, &p->daddr, saddr,
 					     p->proto, p->family);
 	}
 
@@ -464,6 +467,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
 static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = sock_net(skb->sk);
 	struct xfrm_state *x;
 	int err = -ESRCH;
 	struct km_event c;
@@ -472,7 +476,7 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 	u32 sessionid = NETLINK_CB(skb).sessionid;
 	u32 sid = NETLINK_CB(skb).sid;
 
-	x = xfrm_user_state_lookup(p, attrs, &err);
+	x = xfrm_user_state_lookup(net, p, attrs, &err);
 	if (x == NULL)
 		return err;
 
@@ -615,6 +619,7 @@ static int xfrm_dump_sa_done(struct netlink_callback *cb)
 
 static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
 {
+	struct net *net = sock_net(skb->sk);
 	struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1];
 	struct xfrm_dump_info info;
 
@@ -631,7 +636,7 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
 		xfrm_state_walk_init(walk, 0);
 	}
 
-	(void) xfrm_state_walk(&init_net, walk, dump_one_state, &info);
+	(void) xfrm_state_walk(net, walk, dump_one_state, &info);
 
 	return skb->len;
 }
@@ -776,13 +781,13 @@ static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
 static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
-	struct net *net = &init_net;
+	struct net *net = sock_net(skb->sk);
 	struct xfrm_usersa_id *p = nlmsg_data(nlh);
 	struct xfrm_state *x;
 	struct sk_buff *resp_skb;
 	int err = -ESRCH;
 
-	x = xfrm_user_state_lookup(p, attrs, &err);
+	x = xfrm_user_state_lookup(net, p, attrs, &err);
 	if (x == NULL)
 		goto out_noput;
 
@@ -823,7 +828,7 @@ static int verify_userspi_info(struct xfrm_userspi_info *p)
 static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
-	struct net *net = &init_net;
+	struct net *net = sock_net(skb->sk);
 	struct xfrm_state *x;
 	struct xfrm_userspi_info *p;
 	struct sk_buff *resp_skb;
@@ -1082,9 +1087,9 @@ static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_i
 	p->share = XFRM_SHARE_ANY; /* XXX xp->share */
 }
 
-static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p, struct nlattr **attrs, int *errp)
+static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_userpolicy_info *p, struct nlattr **attrs, int *errp)
 {
-	struct xfrm_policy *xp = xfrm_policy_alloc(&init_net, GFP_KERNEL);
+	struct xfrm_policy *xp = xfrm_policy_alloc(net, GFP_KERNEL);
 	int err;
 
 	if (!xp) {
@@ -1114,6 +1119,7 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p,
 static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = sock_net(skb->sk);
 	struct xfrm_userpolicy_info *p = nlmsg_data(nlh);
 	struct xfrm_policy *xp;
 	struct km_event c;
@@ -1130,7 +1136,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (err)
 		return err;
 
-	xp = xfrm_policy_construct(p, attrs, &err);
+	xp = xfrm_policy_construct(net, p, attrs, &err);
 	if (!xp)
 		return err;
 
@@ -1267,6 +1273,7 @@ static int xfrm_dump_policy_done(struct netlink_callback *cb)
 
 static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb)
 {
+	struct net *net = sock_net(skb->sk);
 	struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
 	struct xfrm_dump_info info;
 
@@ -1283,7 +1290,7 @@ static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb)
 		xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY);
 	}
 
-	(void) xfrm_policy_walk(&init_net, walk, dump_one_policy, &info);
+	(void) xfrm_policy_walk(net, walk, dump_one_policy, &info);
 
 	return skb->len;
 }
@@ -1315,7 +1322,7 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
 static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
-	struct net *net = &init_net;
+	struct net *net = sock_net(skb->sk);
 	struct xfrm_policy *xp;
 	struct xfrm_userpolicy_id *p;
 	u8 type = XFRM_POLICY_TYPE_MAIN;
@@ -1395,6 +1402,7 @@ out:
 static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = sock_net(skb->sk);
 	struct km_event c;
 	struct xfrm_usersa_flush *p = nlmsg_data(nlh);
 	struct xfrm_audit audit_info;
@@ -1403,7 +1411,7 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 	audit_info.loginuid = NETLINK_CB(skb).loginuid;
 	audit_info.sessionid = NETLINK_CB(skb).sessionid;
 	audit_info.secid = NETLINK_CB(skb).sid;
-	err = xfrm_state_flush(&init_net, p->proto, &audit_info);
+	err = xfrm_state_flush(net, p->proto, &audit_info);
 	if (err)
 		return err;
 	c.data.proto = p->proto;
@@ -1462,7 +1470,7 @@ nla_put_failure:
 static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
-	struct net *net = &init_net;
+	struct net *net = sock_net(skb->sk);
 	struct xfrm_state *x;
 	struct sk_buff *r_skb;
 	int err;
@@ -1501,6 +1509,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
 static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = sock_net(skb->sk);
 	struct xfrm_state *x;
 	struct km_event c;
 	int err = - EINVAL;
@@ -1515,7 +1524,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (!(nlh->nlmsg_flags&NLM_F_REPLACE))
 		return err;
 
-	x = xfrm_state_lookup(&init_net, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family);
+	x = xfrm_state_lookup(net, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family);
 	if (x == NULL)
 		return -ESRCH;
 
@@ -1540,6 +1549,7 @@ out:
 static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = sock_net(skb->sk);
 	struct km_event c;
 	u8 type = XFRM_POLICY_TYPE_MAIN;
 	int err;
@@ -1552,7 +1562,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 	audit_info.loginuid = NETLINK_CB(skb).loginuid;
 	audit_info.sessionid = NETLINK_CB(skb).sessionid;
 	audit_info.secid = NETLINK_CB(skb).sid;
-	err = xfrm_policy_flush(&init_net, type, &audit_info);
+	err = xfrm_policy_flush(net, type, &audit_info);
 	if (err)
 		return err;
 	c.data.type = type;
@@ -1566,6 +1576,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = sock_net(skb->sk);
 	struct xfrm_policy *xp;
 	struct xfrm_user_polexpire *up = nlmsg_data(nlh);
 	struct xfrm_userpolicy_info *p = &up->pol;
@@ -1577,7 +1588,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
 		return err;
 
 	if (p->index)
-		xp = xfrm_policy_byid(&init_net, type, p->dir, p->index, 0, &err);
+		xp = xfrm_policy_byid(net, type, p->dir, p->index, 0, &err);
 	else {
 		struct nlattr *rt = attrs[XFRMA_SEC_CTX];
 		struct xfrm_sec_ctx *ctx;
@@ -1594,7 +1605,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
 			if (err)
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(&init_net, type, p->dir, &p->sel, ctx, 0, &err);
+		xp = xfrm_policy_bysel_ctx(net, type, p->dir, &p->sel, ctx, 0, &err);
 		security_xfrm_policy_free(ctx);
 	}
 	if (xp == NULL)
@@ -1629,12 +1640,13 @@ out:
 static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = sock_net(skb->sk);
 	struct xfrm_state *x;
 	int err;
 	struct xfrm_user_expire *ue = nlmsg_data(nlh);
 	struct xfrm_usersa_info *p = &ue->state;
 
-	x = xfrm_state_lookup(&init_net, &p->id.daddr, p->id.spi, p->id.proto, p->family);
+	x = xfrm_state_lookup(net, &p->id.daddr, p->id.spi, p->id.proto, p->family);
 
 	err = -ENOENT;
 	if (x == NULL)
@@ -1663,13 +1675,14 @@ out:
 static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct nlattr **attrs)
 {
+	struct net *net = sock_net(skb->sk);
 	struct xfrm_policy *xp;
 	struct xfrm_user_tmpl *ut;
 	int i;
 	struct nlattr *rt = attrs[XFRMA_TMPL];
 
 	struct xfrm_user_acquire *ua = nlmsg_data(nlh);
-	struct xfrm_state *x = xfrm_state_alloc(&init_net);
+	struct xfrm_state *x = xfrm_state_alloc(net);
 	int err = -ENOMEM;
 
 	if (!x)
@@ -1683,7 +1696,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
 	}
 
 	/*   build an XP */
-	xp = xfrm_policy_construct(&ua->policy, attrs, &err);
+	xp = xfrm_policy_construct(net, &ua->policy, attrs, &err);
 	if (!xp) {
 		kfree(x);
 		return err;
@@ -2041,7 +2054,7 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_eve
 
 static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c)
 {
-	struct net *net = &init_net;
+	struct net *net = xs_net(x);
 	struct sk_buff *skb;
 
 	skb = nlmsg_new(xfrm_expire_msgsize(), GFP_ATOMIC);
@@ -2056,7 +2069,7 @@ static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c)
 
 static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c)
 {
-	struct net *net = &init_net;
+	struct net *net = xs_net(x);
 	struct sk_buff *skb;
 
 	skb = nlmsg_new(xfrm_aevent_msgsize(), GFP_ATOMIC);
@@ -2122,7 +2135,7 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x)
 
 static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c)
 {
-	struct net *net = &init_net;
+	struct net *net = xs_net(x);
 	struct xfrm_usersa_info *p;
 	struct xfrm_usersa_id *id;
 	struct nlmsghdr *nlh;
@@ -2266,6 +2279,7 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
 static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
 					       u8 *data, int len, int *dir)
 {
+	struct net *net = sock_net(sk);
 	struct xfrm_userpolicy_info *p = (struct xfrm_userpolicy_info *)data;
 	struct xfrm_user_tmpl *ut = (struct xfrm_user_tmpl *) (p + 1);
 	struct xfrm_policy *xp;
@@ -2304,7 +2318,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
 	if (p->dir > XFRM_POLICY_OUT)
 		return NULL;
 
-	xp = xfrm_policy_alloc(&init_net, GFP_KERNEL);
+	xp = xfrm_policy_alloc(net, GFP_KERNEL);
 	if (xp == NULL) {
 		*dir = -ENOBUFS;
 		return NULL;
@@ -2357,7 +2371,7 @@ nlmsg_failure:
 
 static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
 {
-	struct net *net = &init_net;
+	struct net *net = xp_net(xp);
 	struct sk_buff *skb;
 
 	skb = nlmsg_new(xfrm_polexpire_msgsize(xp), GFP_ATOMIC);
@@ -2372,7 +2386,7 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve
 
 static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c)
 {
-	struct net *net = &init_net;
+	struct net *net = xp_net(xp);
 	struct xfrm_userpolicy_info *p;
 	struct xfrm_userpolicy_id *id;
 	struct nlmsghdr *nlh;
-- 
1.5.6.5


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

* [PATCH 42/53] netns xfrm: pass netns with KM notifications
  2008-11-25 17:27                                                                               ` [PATCH 41/53] netns xfrm: xfrm_user module in netns Alexey Dobriyan
@ 2008-11-25 17:27                                                                                 ` Alexey Dobriyan
  2008-11-25 17:27                                                                                   ` [PATCH 43/53] netns xfrm: KM reporting in netns Alexey Dobriyan
  2008-11-26  1:50                                                                                   ` [PATCH 42/53] netns xfrm: pass netns with KM notifications David Miller
       [not found]                                                                                 ` <1227634045-27534-41-git-send-email-adobriyan-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

SA and SPD flush are executed with NULL SA and SPD respectively, for
these cases pass netns explicitly from userspace socket.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h   |    1 +
 net/key/af_key.c     |    2 ++
 net/xfrm/xfrm_user.c |    6 ++++--
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index e027179..52e784f 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -256,6 +256,7 @@ struct km_event
 	u32	seq;
 	u32	pid;
 	u32	event;
+	struct net *net;
 };
 
 struct net_device;
diff --git a/net/key/af_key.c b/net/key/af_key.c
index a0d8498..ea7755a 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1739,6 +1739,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
 	c.seq = hdr->sadb_msg_seq;
 	c.pid = hdr->sadb_msg_pid;
 	c.event = XFRM_MSG_FLUSHSA;
+	c.net = &init_net;
 	km_state_notify(NULL, &c);
 
 	return 0;
@@ -2693,6 +2694,7 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg
 	c.event = XFRM_MSG_FLUSHPOLICY;
 	c.pid = hdr->sadb_msg_pid;
 	c.seq = hdr->sadb_msg_seq;
+	c.net = &init_net;
 	km_policy_notify(NULL, 0, &c);
 
 	return 0;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index ab8b138..3e32ec2 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1418,6 +1418,7 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 	c.event = nlh->nlmsg_type;
 	c.seq = nlh->nlmsg_seq;
 	c.pid = nlh->nlmsg_pid;
+	c.net = net;
 	km_state_notify(NULL, &c);
 
 	return 0;
@@ -1569,6 +1570,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 	c.event = nlh->nlmsg_type;
 	c.seq = nlh->nlmsg_seq;
 	c.pid = nlh->nlmsg_pid;
+	c.net = net;
 	km_policy_notify(NULL, 0, &c);
 	return 0;
 }
@@ -2084,7 +2086,7 @@ static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c)
 
 static int xfrm_notify_sa_flush(struct km_event *c)
 {
-	struct net *net = &init_net;
+	struct net *net = c->net;
 	struct xfrm_usersa_flush *p;
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
@@ -2446,7 +2448,7 @@ nlmsg_failure:
 
 static int xfrm_notify_policy_flush(struct km_event *c)
 {
-	struct net *net = &init_net;
+	struct net *net = c->net;
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
 
-- 
1.5.6.5


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

* [PATCH 43/53] netns xfrm: KM reporting in netns
  2008-11-25 17:27                                                                                 ` [PATCH 42/53] netns xfrm: pass netns with KM notifications Alexey Dobriyan
@ 2008-11-25 17:27                                                                                   ` Alexey Dobriyan
  2008-11-25 17:27                                                                                     ` [PATCH 44/53] netns xfrm: ->dst_lookup " Alexey Dobriyan
  2008-11-26  1:51                                                                                     ` [PATCH 43/53] netns xfrm: KM reporting " David Miller
  2008-11-26  1:50                                                                                   ` [PATCH 42/53] netns xfrm: pass netns with KM notifications David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h    |    4 ++--
 net/ipv6/mip6.c       |    3 ++-
 net/xfrm/xfrm_state.c |    4 ++--
 net/xfrm/xfrm_user.c  |    5 ++---
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 52e784f..f3ea160 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -552,7 +552,7 @@ struct xfrm_mgr
 	struct xfrm_policy	*(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
 	int			(*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
 	int			(*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c);
-	int			(*report)(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
+	int			(*report)(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
 	int			(*migrate)(struct xfrm_selector *sel, u8 dir, u8 type, struct xfrm_migrate *m, int num_bundles, struct xfrm_kmaddress *k);
 };
 
@@ -1471,7 +1471,7 @@ extern int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
 
 extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
 extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid);
-extern int km_report(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
+extern int km_report(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
 
 extern void xfrm_input_init(void);
 extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 31295c8..f995e19 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -205,6 +205,7 @@ static inline int mip6_report_rl_allow(struct timeval *stamp,
 
 static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct flowi *fl)
 {
+	struct net *net = xs_net(x);
 	struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
 	struct ipv6_destopt_hao *hao = NULL;
 	struct xfrm_selector sel;
@@ -247,7 +248,7 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct
 		sel.sport_mask = htons(~0);
 	sel.ifindex = fl->oif;
 
-	err = km_report(IPPROTO_DSTOPTS, &sel,
+	err = km_report(net, IPPROTO_DSTOPTS, &sel,
 			(hao ? (xfrm_address_t *)&hao->addr : NULL));
 
  out:
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 21db37a..d594b5a 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1833,7 +1833,7 @@ int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
 EXPORT_SYMBOL(km_migrate);
 #endif
 
-int km_report(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr)
+int km_report(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr)
 {
 	int err = -EINVAL;
 	int ret;
@@ -1842,7 +1842,7 @@ int km_report(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr)
 	read_lock(&xfrm_km_lock);
 	list_for_each_entry(km, &xfrm_km_list, list) {
 		if (km->report) {
-			ret = km->report(proto, sel, addr);
+			ret = km->report(net, proto, sel, addr);
 			if (!ret)
 				err = ret;
 		}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 3e32ec2..b7240d5 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2520,10 +2520,9 @@ nla_put_failure:
 	return -EMSGSIZE;
 }
 
-static int xfrm_send_report(u8 proto, struct xfrm_selector *sel,
-			    xfrm_address_t *addr)
+static int xfrm_send_report(struct net *net, u8 proto,
+			    struct xfrm_selector *sel, xfrm_address_t *addr)
 {
-	struct net *net = &init_net;
 	struct sk_buff *skb;
 
 	skb = nlmsg_new(xfrm_report_msgsize(), GFP_ATOMIC);
-- 
1.5.6.5


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

* [PATCH 44/53] netns xfrm: ->dst_lookup in netns
  2008-11-25 17:27                                                                                   ` [PATCH 43/53] netns xfrm: KM reporting in netns Alexey Dobriyan
@ 2008-11-25 17:27                                                                                     ` Alexey Dobriyan
  2008-11-25 17:27                                                                                       ` [PATCH 45/53] netns xfrm: ->get_saddr " Alexey Dobriyan
  2008-11-26  1:51                                                                                       ` [PATCH 44/53] netns xfrm: ->dst_lookup " David Miller
  2008-11-26  1:51                                                                                     ` [PATCH 43/53] netns xfrm: KM reporting " David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h      |    3 ++-
 net/ipv4/xfrm4_policy.c |    7 ++++---
 net/ipv6/xfrm6_policy.c |    7 ++++---
 net/xfrm/xfrm_policy.c  |    7 ++++---
 4 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index f3ea160..b16d4c0 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -266,7 +266,8 @@ struct xfrm_policy_afinfo {
 	unsigned short		family;
 	struct dst_ops		*dst_ops;
 	void			(*garbage_collect)(struct net *net);
-	struct dst_entry	*(*dst_lookup)(int tos, xfrm_address_t *saddr,
+	struct dst_entry	*(*dst_lookup)(struct net *net, int tos,
+					       xfrm_address_t *saddr,
 					       xfrm_address_t *daddr);
 	int			(*get_saddr)(xfrm_address_t *saddr, xfrm_address_t *daddr);
 	struct dst_entry	*(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy);
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index a881ca3..e1cf9ed 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -18,7 +18,8 @@
 static struct dst_ops xfrm4_dst_ops;
 static struct xfrm_policy_afinfo xfrm4_policy_afinfo;
 
-static struct dst_entry *xfrm4_dst_lookup(int tos, xfrm_address_t *saddr,
+static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos,
+					  xfrm_address_t *saddr,
 					  xfrm_address_t *daddr)
 {
 	struct flowi fl = {
@@ -36,7 +37,7 @@ static struct dst_entry *xfrm4_dst_lookup(int tos, xfrm_address_t *saddr,
 	if (saddr)
 		fl.fl4_src = saddr->a4;
 
-	err = __ip_route_output_key(&init_net, &rt, &fl);
+	err = __ip_route_output_key(net, &rt, &fl);
 	dst = &rt->u.dst;
 	if (err)
 		dst = ERR_PTR(err);
@@ -48,7 +49,7 @@ static int xfrm4_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
 	struct dst_entry *dst;
 	struct rtable *rt;
 
-	dst = xfrm4_dst_lookup(0, NULL, daddr);
+	dst = xfrm4_dst_lookup(&init_net, 0, NULL, daddr);
 	if (IS_ERR(dst))
 		return -EHOSTUNREACH;
 
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 2df8a78..d7a5b8b 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -27,7 +27,8 @@
 static struct dst_ops xfrm6_dst_ops;
 static struct xfrm_policy_afinfo xfrm6_policy_afinfo;
 
-static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr,
+static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos,
+					  xfrm_address_t *saddr,
 					  xfrm_address_t *daddr)
 {
 	struct flowi fl = {};
@@ -38,7 +39,7 @@ static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr,
 	if (saddr)
 		memcpy(&fl.fl6_src, saddr, sizeof(fl.fl6_src));
 
-	dst = ip6_route_output(&init_net, NULL, &fl);
+	dst = ip6_route_output(net, NULL, &fl);
 
 	err = dst->error;
 	if (dst->error) {
@@ -54,7 +55,7 @@ static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
 	struct dst_entry *dst;
 	struct net_device *dev;
 
-	dst = xfrm6_dst_lookup(0, NULL, daddr);
+	dst = xfrm6_dst_lookup(&init_net, 0, NULL, daddr);
 	if (IS_ERR(dst))
 		return -EHOSTUNREACH;
 
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 7ebbdd6..2b0a80b 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -92,7 +92,7 @@ int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
 	return 0;
 }
 
-static inline struct dst_entry *__xfrm_dst_lookup(int tos,
+static inline struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos,
 						  xfrm_address_t *saddr,
 						  xfrm_address_t *daddr,
 						  int family)
@@ -104,7 +104,7 @@ static inline struct dst_entry *__xfrm_dst_lookup(int tos,
 	if (unlikely(afinfo == NULL))
 		return ERR_PTR(-EAFNOSUPPORT);
 
-	dst = afinfo->dst_lookup(tos, saddr, daddr);
+	dst = afinfo->dst_lookup(net, tos, saddr, daddr);
 
 	xfrm_policy_put_afinfo(afinfo);
 
@@ -116,6 +116,7 @@ static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos,
 						xfrm_address_t *prev_daddr,
 						int family)
 {
+	struct net *net = xs_net(x);
 	xfrm_address_t *saddr = &x->props.saddr;
 	xfrm_address_t *daddr = &x->id.daddr;
 	struct dst_entry *dst;
@@ -129,7 +130,7 @@ static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos,
 		daddr = x->coaddr;
 	}
 
-	dst = __xfrm_dst_lookup(tos, saddr, daddr, family);
+	dst = __xfrm_dst_lookup(net, tos, saddr, daddr, family);
 
 	if (!IS_ERR(dst)) {
 		if (prev_saddr != saddr)
-- 
1.5.6.5


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

* [PATCH 45/53] netns xfrm: ->get_saddr in netns
  2008-11-25 17:27                                                                                     ` [PATCH 44/53] netns xfrm: ->dst_lookup " Alexey Dobriyan
@ 2008-11-25 17:27                                                                                       ` Alexey Dobriyan
  2008-11-25 17:27                                                                                         ` [PATCH 46/53] netns xfrm: flush SA/SPDs on netns stop Alexey Dobriyan
  2008-11-26  1:56                                                                                         ` [PATCH 45/53] netns xfrm: ->get_saddr in netns David Miller
  2008-11-26  1:51                                                                                       ` [PATCH 44/53] netns xfrm: ->dst_lookup " David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h      |    2 +-
 net/ipv4/xfrm4_policy.c |    5 +++--
 net/ipv6/xfrm6_policy.c |    5 +++--
 net/xfrm/xfrm_policy.c  |    7 ++++---
 4 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index b16d4c0..d076f3d 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -269,7 +269,7 @@ struct xfrm_policy_afinfo {
 	struct dst_entry	*(*dst_lookup)(struct net *net, int tos,
 					       xfrm_address_t *saddr,
 					       xfrm_address_t *daddr);
-	int			(*get_saddr)(xfrm_address_t *saddr, xfrm_address_t *daddr);
+	int			(*get_saddr)(struct net *net, xfrm_address_t *saddr, xfrm_address_t *daddr);
 	struct dst_entry	*(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy);
 	void			(*decode_session)(struct sk_buff *skb,
 						  struct flowi *fl,
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index e1cf9ed..2ad24ba 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -44,12 +44,13 @@ static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos,
 	return dst;
 }
 
-static int xfrm4_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
+static int xfrm4_get_saddr(struct net *net,
+			   xfrm_address_t *saddr, xfrm_address_t *daddr)
 {
 	struct dst_entry *dst;
 	struct rtable *rt;
 
-	dst = xfrm4_dst_lookup(&init_net, 0, NULL, daddr);
+	dst = xfrm4_dst_lookup(net, 0, NULL, daddr);
 	if (IS_ERR(dst))
 		return -EHOSTUNREACH;
 
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index d7a5b8b..97ab068 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -50,12 +50,13 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos,
 	return dst;
 }
 
-static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
+static int xfrm6_get_saddr(struct net *net,
+			   xfrm_address_t *saddr, xfrm_address_t *daddr)
 {
 	struct dst_entry *dst;
 	struct net_device *dev;
 
-	dst = xfrm6_dst_lookup(&init_net, 0, NULL, daddr);
+	dst = xfrm6_dst_lookup(net, 0, NULL, daddr);
 	if (IS_ERR(dst))
 		return -EHOSTUNREACH;
 
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 2b0a80b..7c7bb54 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1187,7 +1187,7 @@ int __xfrm_sk_clone_policy(struct sock *sk)
 }
 
 static int
-xfrm_get_saddr(xfrm_address_t *local, xfrm_address_t *remote,
+xfrm_get_saddr(struct net *net, xfrm_address_t *local, xfrm_address_t *remote,
 	       unsigned short family)
 {
 	int err;
@@ -1195,7 +1195,7 @@ xfrm_get_saddr(xfrm_address_t *local, xfrm_address_t *remote,
 
 	if (unlikely(afinfo == NULL))
 		return -EINVAL;
-	err = afinfo->get_saddr(local, remote);
+	err = afinfo->get_saddr(net, local, remote);
 	xfrm_policy_put_afinfo(afinfo);
 	return err;
 }
@@ -1207,6 +1207,7 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, struct flowi *fl,
 		      struct xfrm_state **xfrm,
 		      unsigned short family)
 {
+	struct net *net = xp_net(policy);
 	int nx;
 	int i, error;
 	xfrm_address_t *daddr = xfrm_flowi_daddr(fl, family);
@@ -1225,7 +1226,7 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, struct flowi *fl,
 			local = &tmpl->saddr;
 			family = tmpl->encap_family;
 			if (xfrm_addr_any(local, family)) {
-				error = xfrm_get_saddr(&tmp, remote, family);
+				error = xfrm_get_saddr(net, &tmp, remote, family);
 				if (error)
 					goto fail;
 				local = &tmp;
-- 
1.5.6.5


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

* [PATCH 46/53] netns xfrm: flush SA/SPDs on netns stop
  2008-11-25 17:27                                                                                       ` [PATCH 45/53] netns xfrm: ->get_saddr " Alexey Dobriyan
@ 2008-11-25 17:27                                                                                         ` Alexey Dobriyan
  2008-11-25 17:27                                                                                           ` [PATCH 47/53] netns PF_KEY: part 1 Alexey Dobriyan
  2008-11-26  1:57                                                                                           ` [PATCH 46/53] netns xfrm: flush SA/SPDs on netns stop David Miller
  2008-11-26  1:56                                                                                         ` [PATCH 45/53] netns xfrm: ->get_saddr in netns David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

SA/SPD doesn't pin netns (and it shouldn't), so get rid of them by hand.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/xfrm/xfrm_policy.c |   14 ++++++++++++++
 net/xfrm/xfrm_state.c  |    8 ++++++++
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 7c7bb54..fcf8c92 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2441,9 +2441,23 @@ out_byidx:
 
 static void xfrm_policy_fini(struct net *net)
 {
+	struct xfrm_audit audit_info;
 	unsigned int sz;
 	int dir;
 
+	flush_work(&net->xfrm.policy_hash_work);
+#ifdef CONFIG_XFRM_SUB_POLICY
+	audit_info.loginuid = -1;
+	audit_info.sessionid = -1;
+	audit_info.secid = 0;
+	xfrm_policy_flush(net, XFRM_POLICY_TYPE_SUB, &audit_info);
+#endif
+	audit_info.loginuid = -1;
+	audit_info.sessionid = -1;
+	audit_info.secid = 0;
+	xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info);
+	flush_work(&xfrm_policy_gc_work);
+
 	WARN_ON(!list_empty(&net->xfrm.policy_all));
 
 	for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) {
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index d594b5a..662e47b 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2114,8 +2114,16 @@ out_bydst:
 
 void xfrm_state_fini(struct net *net)
 {
+	struct xfrm_audit audit_info;
 	unsigned int sz;
 
+	flush_work(&net->xfrm.state_hash_work);
+	audit_info.loginuid = -1;
+	audit_info.sessionid = -1;
+	audit_info.secid = 0;
+	xfrm_state_flush(net, IPSEC_PROTO_ANY, &audit_info);
+	flush_work(&net->xfrm.state_gc_work);
+
 	WARN_ON(!list_empty(&net->xfrm.state_all));
 
 	sz = (net->xfrm.state_hmask + 1) * sizeof(struct hlist_head);
-- 
1.5.6.5


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

* [PATCH 47/53] netns PF_KEY: part 1
  2008-11-25 17:27                                                                                         ` [PATCH 46/53] netns xfrm: flush SA/SPDs on netns stop Alexey Dobriyan
@ 2008-11-25 17:27                                                                                           ` Alexey Dobriyan
  2008-11-25 17:27                                                                                             ` [PATCH 48/53] netns PF_KEY: part 2 Alexey Dobriyan
  2008-11-26  1:58                                                                                             ` [PATCH 47/53] netns PF_KEY: part 1 David Miller
  2008-11-26  1:57                                                                                           ` [PATCH 46/53] netns xfrm: flush SA/SPDs on netns stop David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

* netns boilerplate
* keep per-netns socket list
* keep per-netns number of sockets

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/key/af_key.c |   88 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 73 insertions(+), 15 deletions(-)

diff --git a/net/key/af_key.c b/net/key/af_key.c
index ea7755a..e80b264 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -27,6 +27,7 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <net/net_namespace.h>
+#include <net/netns/generic.h>
 #include <net/xfrm.h>
 
 #include <net/sock.h>
@@ -34,15 +35,16 @@
 #define _X2KEY(x) ((x) == XFRM_INF ? 0 : (x))
 #define _KEY2X(x) ((x) == 0 ? XFRM_INF : (x))
 
-
-/* List of all pfkey sockets. */
-static HLIST_HEAD(pfkey_table);
+static int pfkey_net_id;
+struct netns_pfkey {
+	/* List of all pfkey sockets. */
+	struct hlist_head table;
+	atomic_t socks_nr;
+};
 static DECLARE_WAIT_QUEUE_HEAD(pfkey_table_wait);
 static DEFINE_RWLOCK(pfkey_table_lock);
 static atomic_t pfkey_table_users = ATOMIC_INIT(0);
 
-static atomic_t pfkey_socks_nr = ATOMIC_INIT(0);
-
 struct pfkey_sock {
 	/* struct sock must be the first member of struct pfkey_sock */
 	struct sock	sk;
@@ -89,6 +91,9 @@ static void pfkey_terminate_dump(struct pfkey_sock *pfk)
 
 static void pfkey_sock_destruct(struct sock *sk)
 {
+	struct net *net = sock_net(sk);
+	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
+
 	pfkey_terminate_dump(pfkey_sk(sk));
 	skb_queue_purge(&sk->sk_receive_queue);
 
@@ -100,7 +105,7 @@ static void pfkey_sock_destruct(struct sock *sk)
 	WARN_ON(atomic_read(&sk->sk_rmem_alloc));
 	WARN_ON(atomic_read(&sk->sk_wmem_alloc));
 
-	atomic_dec(&pfkey_socks_nr);
+	atomic_dec(&net_pfkey->socks_nr);
 }
 
 static void pfkey_table_grab(void)
@@ -151,8 +156,11 @@ static const struct proto_ops pfkey_ops;
 
 static void pfkey_insert(struct sock *sk)
 {
+	struct net *net = sock_net(sk);
+	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
+
 	pfkey_table_grab();
-	sk_add_node(sk, &pfkey_table);
+	sk_add_node(sk, &net_pfkey->table);
 	pfkey_table_ungrab();
 }
 
@@ -171,12 +179,10 @@ static struct proto key_proto = {
 
 static int pfkey_create(struct net *net, struct socket *sock, int protocol)
 {
+	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
 	struct sock *sk;
 	int err;
 
-	if (net != &init_net)
-		return -EAFNOSUPPORT;
-
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 	if (sock->type != SOCK_RAW)
@@ -195,7 +201,7 @@ static int pfkey_create(struct net *net, struct socket *sock, int protocol)
 	sk->sk_family = PF_KEY;
 	sk->sk_destruct = pfkey_sock_destruct;
 
-	atomic_inc(&pfkey_socks_nr);
+	atomic_inc(&net_pfkey->socks_nr);
 
 	pfkey_insert(sk);
 
@@ -257,6 +263,8 @@ static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2,
 static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
 			   int broadcast_flags, struct sock *one_sk)
 {
+	struct net *net = &init_net;
+	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
 	struct sock *sk;
 	struct hlist_node *node;
 	struct sk_buff *skb2 = NULL;
@@ -269,7 +277,7 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
 		return -ENOMEM;
 
 	pfkey_lock_table();
-	sk_for_each(sk, node, &pfkey_table) {
+	sk_for_each(sk, node, &net_pfkey->table) {
 		struct pfkey_sock *pfk = pfkey_sk(sk);
 		int err2;
 
@@ -2943,7 +2951,10 @@ static int key_notify_sa_expire(struct xfrm_state *x, struct km_event *c)
 
 static int pfkey_send_notify(struct xfrm_state *x, struct km_event *c)
 {
-	if (atomic_read(&pfkey_socks_nr) == 0)
+	struct net *net = &init_net;
+	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
+
+	if (atomic_read(&net_pfkey->socks_nr) == 0)
 		return 0;
 
 	switch (c->event) {
@@ -3647,6 +3658,8 @@ static int pfkey_seq_show(struct seq_file *f, void *v)
 
 static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos)
 {
+	struct net *net = &init_net;
+	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
 	struct sock *s;
 	struct hlist_node *node;
 	loff_t pos = *ppos;
@@ -3655,7 +3668,7 @@ static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos)
 	if (pos == 0)
 		return SEQ_START_TOKEN;
 
-	sk_for_each(s, node, &pfkey_table)
+	sk_for_each(s, node, &net_pfkey->table)
 		if (pos-- == 1)
 			return s;
 
@@ -3664,9 +3677,12 @@ static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos)
 
 static void *pfkey_seq_next(struct seq_file *f, void *v, loff_t *ppos)
 {
+	struct net *net = &init_net;
+	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
+
 	++*ppos;
 	return (v == SEQ_START_TOKEN) ?
-		sk_head(&pfkey_table) :
+		sk_head(&net_pfkey->table) :
 			sk_next((struct sock *)v);
 }
 
@@ -3731,8 +3747,45 @@ static struct xfrm_mgr pfkeyv2_mgr =
 	.migrate	= pfkey_send_migrate,
 };
 
+static int __net_init pfkey_net_init(struct net *net)
+{
+	struct netns_pfkey *net_pfkey;
+	int rv;
+
+	net_pfkey = kmalloc(sizeof(struct netns_pfkey), GFP_KERNEL);
+	if (!net_pfkey) {
+		rv = -ENOMEM;
+		goto out_kmalloc;
+	}
+	INIT_HLIST_HEAD(&net_pfkey->table);
+	atomic_set(&net_pfkey->socks_nr, 0);
+	rv = net_assign_generic(net, pfkey_net_id, net_pfkey);
+	if (rv < 0)
+		goto out_assign;
+	return 0;
+
+out_assign:
+	kfree(net_pfkey);
+out_kmalloc:
+	return rv;
+}
+
+static void __net_exit pfkey_net_exit(struct net *net)
+{
+	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
+
+	BUG_ON(!hlist_empty(&net_pfkey->table));
+	kfree(net_pfkey);
+}
+
+static struct pernet_operations pfkey_net_ops = {
+	.init = pfkey_net_init,
+	.exit = pfkey_net_exit,
+};
+
 static void __exit ipsec_pfkey_exit(void)
 {
+	unregister_pernet_gen_subsys(pfkey_net_id, &pfkey_net_ops);
 	xfrm_unregister_km(&pfkeyv2_mgr);
 	pfkey_exit_proc();
 	sock_unregister(PF_KEY);
@@ -3755,8 +3808,13 @@ static int __init ipsec_pfkey_init(void)
 	err = xfrm_register_km(&pfkeyv2_mgr);
 	if (err != 0)
 		goto out_remove_proc_entry;
+	err = register_pernet_gen_subsys(&pfkey_net_id, &pfkey_net_ops);
+	if (err != 0)
+		goto out_xfrm_unregister_km;
 out:
 	return err;
+out_xfrm_unregister_km:
+	xfrm_unregister_km(&pfkeyv2_mgr);
 out_remove_proc_entry:
 	pfkey_exit_proc();
 out_sock_unregister:
-- 
1.5.6.5


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

* [PATCH 48/53] netns PF_KEY: part 2
  2008-11-25 17:27                                                                                           ` [PATCH 47/53] netns PF_KEY: part 1 Alexey Dobriyan
@ 2008-11-25 17:27                                                                                             ` Alexey Dobriyan
  2008-11-25 17:27                                                                                               ` [PATCH 49/53] netns PF_KEY: per-netns /proc/pfkey Alexey Dobriyan
  2008-11-26  1:58                                                                                               ` [PATCH 48/53] netns PF_KEY: part 2 David Miller
  2008-11-26  1:58                                                                                             ` [PATCH 47/53] netns PF_KEY: part 1 David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

* interaction with userspace -- take netns from userspace socket.
* in ->notify hook take netns either from SA or explicitly passed --
	we don't know if SA/SPD flush is coming.
* stub policy migration with init_net for now.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/key/af_key.c |  105 +++++++++++++++++++++++++++++++-----------------------
 1 files changed, 60 insertions(+), 45 deletions(-)

diff --git a/net/key/af_key.c b/net/key/af_key.c
index e80b264..bb78ef9 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -261,9 +261,9 @@ static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2,
 #define BROADCAST_REGISTERED	2
 #define BROADCAST_PROMISC_ONLY	4
 static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
-			   int broadcast_flags, struct sock *one_sk)
+			   int broadcast_flags, struct sock *one_sk,
+			   struct net *net)
 {
-	struct net *net = &init_net;
 	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
 	struct sock *sk;
 	struct hlist_node *node;
@@ -336,7 +336,7 @@ static int pfkey_do_dump(struct pfkey_sock *pfk)
 		hdr->sadb_msg_seq = 0;
 		hdr->sadb_msg_errno = rc;
 		pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
-				&pfk->sk);
+				&pfk->sk, sock_net(&pfk->sk));
 		pfk->dump.skb = NULL;
 	}
 
@@ -375,7 +375,7 @@ static int pfkey_error(struct sadb_msg *orig, int err, struct sock *sk)
 	hdr->sadb_msg_len = (sizeof(struct sadb_msg) /
 			     sizeof(uint64_t));
 
-	pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ONE, sk);
+	pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ONE, sk, sock_net(sk));
 
 	return 0;
 }
@@ -653,7 +653,7 @@ int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, xfrm_address_t *xaddr)
 				      xaddr);
 }
 
-static struct  xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs)
+static struct  xfrm_state *pfkey_xfrm_state_lookup(struct net *net, struct sadb_msg *hdr, void **ext_hdrs)
 {
 	struct sadb_sa *sa;
 	struct sadb_address *addr;
@@ -691,7 +691,7 @@ static struct  xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **
 	if (!xaddr)
 		return NULL;
 
-	return xfrm_state_lookup(&init_net, xaddr, sa->sadb_sa_spi, proto, family);
+	return xfrm_state_lookup(net, xaddr, sa->sadb_sa_spi, proto, family);
 }
 
 #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1)))
@@ -1066,7 +1066,8 @@ static inline struct sk_buff *pfkey_xfrm_state2msg_expire(struct xfrm_state *x,
 	return __pfkey_xfrm_state2msg(x, 0, hsc);
 }
 
-static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
+static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
+						struct sadb_msg *hdr,
 						void **ext_hdrs)
 {
 	struct xfrm_state *x;
@@ -1130,7 +1131,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
 	     (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
 		return ERR_PTR(-EINVAL);
 
-	x = xfrm_state_alloc(&init_net);
+	x = xfrm_state_alloc(net);
 	if (x == NULL)
 		return ERR_PTR(-ENOBUFS);
 
@@ -1306,6 +1307,7 @@ static int pfkey_reserved(struct sock *sk, struct sk_buff *skb, struct sadb_msg
 
 static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
+	struct net *net = sock_net(sk);
 	struct sk_buff *resp_skb;
 	struct sadb_x_sa2 *sa2;
 	struct sadb_address *saddr, *daddr;
@@ -1356,7 +1358,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
 	}
 
 	if (hdr->sadb_msg_seq) {
-		x = xfrm_find_acq_byseq(&init_net, hdr->sadb_msg_seq);
+		x = xfrm_find_acq_byseq(net, hdr->sadb_msg_seq);
 		if (x && xfrm_addr_cmp(&x->id.daddr, xdaddr, family)) {
 			xfrm_state_put(x);
 			x = NULL;
@@ -1364,7 +1366,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
 	}
 
 	if (!x)
-		x = xfrm_find_acq(&init_net, mode, reqid, proto, xdaddr, xsaddr, 1, family);
+		x = xfrm_find_acq(net, mode, reqid, proto, xdaddr, xsaddr, 1, family);
 
 	if (x == NULL)
 		return -ENOENT;
@@ -1397,13 +1399,14 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
 
 	xfrm_state_put(x);
 
-	pfkey_broadcast(resp_skb, GFP_KERNEL, BROADCAST_ONE, sk);
+	pfkey_broadcast(resp_skb, GFP_KERNEL, BROADCAST_ONE, sk, net);
 
 	return 0;
 }
 
 static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
+	struct net *net = sock_net(sk);
 	struct xfrm_state *x;
 
 	if (hdr->sadb_msg_len != sizeof(struct sadb_msg)/8)
@@ -1412,14 +1415,14 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg *
 	if (hdr->sadb_msg_seq == 0 || hdr->sadb_msg_errno == 0)
 		return 0;
 
-	x = xfrm_find_acq_byseq(&init_net, hdr->sadb_msg_seq);
+	x = xfrm_find_acq_byseq(net, hdr->sadb_msg_seq);
 	if (x == NULL)
 		return 0;
 
 	spin_lock_bh(&x->lock);
 	if (x->km.state == XFRM_STATE_ACQ) {
 		x->km.state = XFRM_STATE_ERROR;
-		wake_up(&init_net.xfrm.km_waitq);
+		wake_up(&net->xfrm.km_waitq);
 	}
 	spin_unlock_bh(&x->lock);
 	xfrm_state_put(x);
@@ -1484,18 +1487,19 @@ static int key_notify_sa(struct xfrm_state *x, struct km_event *c)
 	hdr->sadb_msg_seq = c->seq;
 	hdr->sadb_msg_pid = c->pid;
 
-	pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
+	pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xs_net(x));
 
 	return 0;
 }
 
 static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
+	struct net *net = sock_net(sk);
 	struct xfrm_state *x;
 	int err;
 	struct km_event c;
 
-	x = pfkey_msg2xfrm_state(hdr, ext_hdrs);
+	x = pfkey_msg2xfrm_state(net, hdr, ext_hdrs);
 	if (IS_ERR(x))
 		return PTR_ERR(x);
 
@@ -1529,6 +1533,7 @@ out:
 
 static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
+	struct net *net = sock_net(sk);
 	struct xfrm_state *x;
 	struct km_event c;
 	int err;
@@ -1538,7 +1543,7 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
 				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]))
 		return -EINVAL;
 
-	x = pfkey_xfrm_state_lookup(hdr, ext_hdrs);
+	x = pfkey_xfrm_state_lookup(net, hdr, ext_hdrs);
 	if (x == NULL)
 		return -ESRCH;
 
@@ -1570,6 +1575,7 @@ out:
 
 static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
+	struct net *net = sock_net(sk);
 	__u8 proto;
 	struct sk_buff *out_skb;
 	struct sadb_msg *out_hdr;
@@ -1580,7 +1586,7 @@ static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
 				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]))
 		return -EINVAL;
 
-	x = pfkey_xfrm_state_lookup(hdr, ext_hdrs);
+	x = pfkey_xfrm_state_lookup(net, hdr, ext_hdrs);
 	if (x == NULL)
 		return -ESRCH;
 
@@ -1598,7 +1604,7 @@ static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
 	out_hdr->sadb_msg_reserved = 0;
 	out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
 	out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
-	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk);
+	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk));
 
 	return 0;
 }
@@ -1699,7 +1705,7 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, struct sadb_msg
 		return -ENOBUFS;
 	}
 
-	pfkey_broadcast(supp_skb, GFP_KERNEL, BROADCAST_REGISTERED, sk);
+	pfkey_broadcast(supp_skb, GFP_KERNEL, BROADCAST_REGISTERED, sk, sock_net(sk));
 
 	return 0;
 }
@@ -1721,13 +1727,14 @@ static int key_notify_sa_flush(struct km_event *c)
 	hdr->sadb_msg_errno = (uint8_t) 0;
 	hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
 
-	pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
+	pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net);
 
 	return 0;
 }
 
 static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
+	struct net *net = sock_net(sk);
 	unsigned proto;
 	struct km_event c;
 	struct xfrm_audit audit_info;
@@ -1740,14 +1747,14 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
 	audit_info.loginuid = audit_get_loginuid(current);
 	audit_info.sessionid = audit_get_sessionid(current);
 	audit_info.secid = 0;
-	err = xfrm_state_flush(&init_net, proto, &audit_info);
+	err = xfrm_state_flush(net, proto, &audit_info);
 	if (err)
 		return err;
 	c.data.proto = proto;
 	c.seq = hdr->sadb_msg_seq;
 	c.pid = hdr->sadb_msg_pid;
 	c.event = XFRM_MSG_FLUSHSA;
-	c.net = &init_net;
+	c.net = net;
 	km_state_notify(NULL, &c);
 
 	return 0;
@@ -1777,7 +1784,7 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr)
 
 	if (pfk->dump.skb)
 		pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
-				&pfk->sk);
+				&pfk->sk, sock_net(&pfk->sk));
 	pfk->dump.skb = out_skb;
 
 	return 0;
@@ -1785,7 +1792,8 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr)
 
 static int pfkey_dump_sa(struct pfkey_sock *pfk)
 {
-	return xfrm_state_walk(&init_net, &pfk->dump.u.state, dump_sa, (void *) pfk);
+	struct net *net = sock_net(&pfk->sk);
+	return xfrm_state_walk(net, &pfk->dump.u.state, dump_sa, (void *) pfk);
 }
 
 static void pfkey_dump_sa_done(struct pfkey_sock *pfk)
@@ -1826,7 +1834,7 @@ static int pfkey_promisc(struct sock *sk, struct sk_buff *skb, struct sadb_msg *
 			return -EINVAL;
 		pfk->promisc = satype;
 	}
-	pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, BROADCAST_ALL, NULL);
+	pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, BROADCAST_ALL, NULL, sock_net(sk));
 	return 0;
 }
 
@@ -1842,7 +1850,7 @@ static int check_reqid(struct xfrm_policy *xp, int dir, int count, void *ptr)
 	return 0;
 }
 
-static u32 gen_reqid(void)
+static u32 gen_reqid(struct net *net)
 {
 	struct xfrm_policy_walk walk;
 	u32 start;
@@ -1855,7 +1863,7 @@ static u32 gen_reqid(void)
 		if (reqid == 0)
 			reqid = IPSEC_MANUAL_REQID_MAX+1;
 		xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN);
-		rc = xfrm_policy_walk(&init_net, &walk, check_reqid, (void*)&reqid);
+		rc = xfrm_policy_walk(net, &walk, check_reqid, (void*)&reqid);
 		xfrm_policy_walk_done(&walk);
 		if (rc != -EEXIST)
 			return reqid;
@@ -1866,6 +1874,7 @@ static u32 gen_reqid(void)
 static int
 parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
 {
+	struct net *net = xp_net(xp);
 	struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr;
 	int mode;
 
@@ -1885,7 +1894,7 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
 		t->reqid = rq->sadb_x_ipsecrequest_reqid;
 		if (t->reqid > IPSEC_MANUAL_REQID_MAX)
 			t->reqid = 0;
-		if (!t->reqid && !(t->reqid = gen_reqid()))
+		if (!t->reqid && !(t->reqid = gen_reqid(net)))
 			return -ENOBUFS;
 	}
 
@@ -2156,7 +2165,7 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c
 	out_hdr->sadb_msg_errno = 0;
 	out_hdr->sadb_msg_seq = c->seq;
 	out_hdr->sadb_msg_pid = c->pid;
-	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
+	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp));
 out:
 	return 0;
 
@@ -2164,6 +2173,7 @@ out:
 
 static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
+	struct net *net = sock_net(sk);
 	int err = 0;
 	struct sadb_lifetime *lifetime;
 	struct sadb_address *sa;
@@ -2183,7 +2193,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
 	if (!pol->sadb_x_policy_dir || pol->sadb_x_policy_dir >= IPSEC_DIR_MAX)
 		return -EINVAL;
 
-	xp = xfrm_policy_alloc(&init_net, GFP_KERNEL);
+	xp = xfrm_policy_alloc(net, GFP_KERNEL);
 	if (xp == NULL)
 		return -ENOBUFS;
 
@@ -2284,6 +2294,7 @@ out:
 
 static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
+	struct net *net = sock_net(sk);
 	int err;
 	struct sadb_address *sa;
 	struct sadb_x_policy *pol;
@@ -2333,7 +2344,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
 			return err;
 	}
 
-	xp = xfrm_policy_bysel_ctx(&init_net, XFRM_POLICY_TYPE_MAIN,
+	xp = xfrm_policy_bysel_ctx(net, XFRM_POLICY_TYPE_MAIN,
 				   pol->sadb_x_policy_dir - 1, &sel, pol_ctx,
 				   1, &err);
 	security_xfrm_policy_free(pol_ctx);
@@ -2381,7 +2392,7 @@ static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, struct sadb
 	out_hdr->sadb_msg_errno = 0;
 	out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
 	out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
-	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk);
+	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, xp_net(xp));
 	err = 0;
 
 out:
@@ -2566,6 +2577,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
 
 static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
+	struct net *net = sock_net(sk);
 	unsigned int dir;
 	int err = 0, delete;
 	struct sadb_x_policy *pol;
@@ -2580,7 +2592,7 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
 		return -EINVAL;
 
 	delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2);
-	xp = xfrm_policy_byid(&init_net, XFRM_POLICY_TYPE_MAIN, dir,
+	xp = xfrm_policy_byid(net, XFRM_POLICY_TYPE_MAIN, dir,
 			      pol->sadb_x_policy_id, delete, &err);
 	if (xp == NULL)
 		return -ENOENT;
@@ -2634,7 +2646,7 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr)
 
 	if (pfk->dump.skb)
 		pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
-				&pfk->sk);
+				&pfk->sk, sock_net(&pfk->sk));
 	pfk->dump.skb = out_skb;
 
 	return 0;
@@ -2642,7 +2654,8 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr)
 
 static int pfkey_dump_sp(struct pfkey_sock *pfk)
 {
-	return xfrm_policy_walk(&init_net, &pfk->dump.u.policy, dump_sp, (void *) pfk);
+	struct net *net = sock_net(&pfk->sk);
+	return xfrm_policy_walk(net, &pfk->dump.u.policy, dump_sp, (void *) pfk);
 }
 
 static void pfkey_dump_sp_done(struct pfkey_sock *pfk)
@@ -2681,13 +2694,14 @@ static int key_notify_policy_flush(struct km_event *c)
 	hdr->sadb_msg_version = PF_KEY_V2;
 	hdr->sadb_msg_errno = (uint8_t) 0;
 	hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
-	pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL);
+	pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net);
 	return 0;
 
 }
 
 static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
+	struct net *net = sock_net(sk);
 	struct km_event c;
 	struct xfrm_audit audit_info;
 	int err;
@@ -2695,14 +2709,14 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg
 	audit_info.loginuid = audit_get_loginuid(current);
 	audit_info.sessionid = audit_get_sessionid(current);
 	audit_info.secid = 0;
-	err = xfrm_policy_flush(&init_net, XFRM_POLICY_TYPE_MAIN, &audit_info);
+	err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info);
 	if (err)
 		return err;
 	c.data.type = XFRM_POLICY_TYPE_MAIN;
 	c.event = XFRM_MSG_FLUSHPOLICY;
 	c.pid = hdr->sadb_msg_pid;
 	c.seq = hdr->sadb_msg_seq;
-	c.net = &init_net;
+	c.net = net;
 	km_policy_notify(NULL, 0, &c);
 
 	return 0;
@@ -2742,7 +2756,7 @@ static int pfkey_process(struct sock *sk, struct sk_buff *skb, struct sadb_msg *
 	int err;
 
 	pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL,
-			BROADCAST_PROMISC_ONLY, NULL);
+			BROADCAST_PROMISC_ONLY, NULL, sock_net(sk));
 
 	memset(ext_hdrs, 0, sizeof(ext_hdrs));
 	err = parse_exthdrs(skb, hdr, ext_hdrs);
@@ -2945,13 +2959,13 @@ static int key_notify_sa_expire(struct xfrm_state *x, struct km_event *c)
 	out_hdr->sadb_msg_seq = 0;
 	out_hdr->sadb_msg_pid = 0;
 
-	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL);
+	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_net(x));
 	return 0;
 }
 
 static int pfkey_send_notify(struct xfrm_state *x, struct km_event *c)
 {
-	struct net *net = &init_net;
+	struct net *net = x ? xs_net(x) : c->net;
 	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
 
 	if (atomic_read(&net_pfkey->socks_nr) == 0)
@@ -3116,12 +3130,13 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
 		       xfrm_ctx->ctx_len);
 	}
 
-	return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL);
+	return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_net(x));
 }
 
 static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
 						u8 *data, int len, int *dir)
 {
+	struct net *net = sock_net(sk);
 	struct xfrm_policy *xp;
 	struct sadb_x_policy *pol = (struct sadb_x_policy*)data;
 	struct sadb_x_sec_ctx *sec_ctx;
@@ -3154,7 +3169,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
 	    (!pol->sadb_x_policy_dir || pol->sadb_x_policy_dir > IPSEC_DIR_OUTBOUND))
 		return NULL;
 
-	xp = xfrm_policy_alloc(&init_net, GFP_ATOMIC);
+	xp = xfrm_policy_alloc(net, GFP_ATOMIC);
 	if (xp == NULL) {
 		*dir = -ENOBUFS;
 		return NULL;
@@ -3313,7 +3328,7 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
 	n_port->sadb_x_nat_t_port_port = sport;
 	n_port->sadb_x_nat_t_port_reserved = 0;
 
-	return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL);
+	return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, xs_net(x));
 }
 
 #ifdef CONFIG_NET_KEY_MIGRATE
@@ -3504,7 +3519,7 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
 	}
 
 	/* broadcast migrate message to sockets */
-	pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
+	pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, &init_net);
 
 	return 0;
 
-- 
1.5.6.5


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

* [PATCH 49/53] netns PF_KEY: per-netns /proc/pfkey
  2008-11-25 17:27                                                                                             ` [PATCH 48/53] netns PF_KEY: part 2 Alexey Dobriyan
@ 2008-11-25 17:27                                                                                               ` Alexey Dobriyan
  2008-11-25 17:27                                                                                                 ` [PATCH 50/53] netns xfrm: AH/ESP in netns! Alexey Dobriyan
  2008-11-26  1:59                                                                                                 ` [PATCH 49/53] netns PF_KEY: per-netns /proc/pfkey David Miller
  2008-11-26  1:58                                                                                               ` [PATCH 48/53] netns PF_KEY: part 2 David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/key/af_key.c |   34 +++++++++++++++++-----------------
 1 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/net/key/af_key.c b/net/key/af_key.c
index bb78ef9..f8bd8df 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3673,7 +3673,7 @@ static int pfkey_seq_show(struct seq_file *f, void *v)
 
 static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos)
 {
-	struct net *net = &init_net;
+	struct net *net = seq_file_net(f);
 	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
 	struct sock *s;
 	struct hlist_node *node;
@@ -3692,7 +3692,7 @@ static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos)
 
 static void *pfkey_seq_next(struct seq_file *f, void *v, loff_t *ppos)
 {
-	struct net *net = &init_net;
+	struct net *net = seq_file_net(f);
 	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
 
 	++*ppos;
@@ -3715,38 +3715,39 @@ static struct seq_operations pfkey_seq_ops = {
 
 static int pfkey_seq_open(struct inode *inode, struct file *file)
 {
-	return seq_open(file, &pfkey_seq_ops);
+	return seq_open_net(inode, file, &pfkey_seq_ops,
+			    sizeof(struct seq_net_private));
 }
 
 static struct file_operations pfkey_proc_ops = {
 	.open	 = pfkey_seq_open,
 	.read	 = seq_read,
 	.llseek	 = seq_lseek,
-	.release = seq_release,
+	.release = seq_release_net,
 };
 
-static int pfkey_init_proc(void)
+static int __net_init pfkey_init_proc(struct net *net)
 {
 	struct proc_dir_entry *e;
 
-	e = proc_net_fops_create(&init_net, "pfkey", 0, &pfkey_proc_ops);
+	e = proc_net_fops_create(net, "pfkey", 0, &pfkey_proc_ops);
 	if (e == NULL)
 		return -ENOMEM;
 
 	return 0;
 }
 
-static void pfkey_exit_proc(void)
+static void pfkey_exit_proc(struct net *net)
 {
-	proc_net_remove(&init_net, "pfkey");
+	proc_net_remove(net, "pfkey");
 }
 #else
-static inline int pfkey_init_proc(void)
+static int __net_init pfkey_init_proc(struct net *net)
 {
 	return 0;
 }
 
-static inline void pfkey_exit_proc(void)
+static void pfkey_exit_proc(struct net *net)
 {
 }
 #endif
@@ -3777,8 +3778,12 @@ static int __net_init pfkey_net_init(struct net *net)
 	rv = net_assign_generic(net, pfkey_net_id, net_pfkey);
 	if (rv < 0)
 		goto out_assign;
+	rv = pfkey_init_proc(net);
+	if (rv < 0)
+		goto out_proc;
 	return 0;
 
+out_proc:
 out_assign:
 	kfree(net_pfkey);
 out_kmalloc:
@@ -3789,6 +3794,7 @@ static void __net_exit pfkey_net_exit(struct net *net)
 {
 	struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
 
+	pfkey_exit_proc(net);
 	BUG_ON(!hlist_empty(&net_pfkey->table));
 	kfree(net_pfkey);
 }
@@ -3802,7 +3808,6 @@ static void __exit ipsec_pfkey_exit(void)
 {
 	unregister_pernet_gen_subsys(pfkey_net_id, &pfkey_net_ops);
 	xfrm_unregister_km(&pfkeyv2_mgr);
-	pfkey_exit_proc();
 	sock_unregister(PF_KEY);
 	proto_unregister(&key_proto);
 }
@@ -3817,12 +3822,9 @@ static int __init ipsec_pfkey_init(void)
 	err = sock_register(&pfkey_family_ops);
 	if (err != 0)
 		goto out_unregister_key_proto;
-	err = pfkey_init_proc();
-	if (err != 0)
-		goto out_sock_unregister;
 	err = xfrm_register_km(&pfkeyv2_mgr);
 	if (err != 0)
-		goto out_remove_proc_entry;
+		goto out_sock_unregister;
 	err = register_pernet_gen_subsys(&pfkey_net_id, &pfkey_net_ops);
 	if (err != 0)
 		goto out_xfrm_unregister_km;
@@ -3830,8 +3832,6 @@ out:
 	return err;
 out_xfrm_unregister_km:
 	xfrm_unregister_km(&pfkeyv2_mgr);
-out_remove_proc_entry:
-	pfkey_exit_proc();
 out_sock_unregister:
 	sock_unregister(PF_KEY);
 out_unregister_key_proto:
-- 
1.5.6.5


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

* [PATCH 50/53] netns xfrm: AH/ESP in netns!
  2008-11-25 17:27                                                                                               ` [PATCH 49/53] netns PF_KEY: per-netns /proc/pfkey Alexey Dobriyan
@ 2008-11-25 17:27                                                                                                 ` Alexey Dobriyan
  2008-11-25 17:27                                                                                                   ` [PATCH 51/53] netns xfrm: per-netns MIBs Alexey Dobriyan
  2008-11-26  1:59                                                                                                   ` [PATCH 50/53] netns xfrm: AH/ESP in netns! David Miller
  2008-11-26  1:59                                                                                                 ` [PATCH 49/53] netns PF_KEY: per-netns /proc/pfkey David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 net/ipv4/ah4.c  |    4 +++-
 net/ipv4/esp4.c |    4 +++-
 net/ipv6/ah6.c  |    3 ++-
 net/ipv6/esp6.c |    3 ++-
 4 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 750426b..e878e49 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -201,6 +201,7 @@ out:
 
 static void ah4_err(struct sk_buff *skb, u32 info)
 {
+	struct net *net = dev_net(skb->dev);
 	struct iphdr *iph = (struct iphdr *)skb->data;
 	struct ip_auth_hdr *ah = (struct ip_auth_hdr *)(skb->data+(iph->ihl<<2));
 	struct xfrm_state *x;
@@ -209,7 +210,7 @@ static void ah4_err(struct sk_buff *skb, u32 info)
 	    icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
 		return;
 
-	x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET);
+	x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET);
 	if (!x)
 		return;
 	printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/%08x\n",
@@ -314,6 +315,7 @@ static struct net_protocol ah4_protocol = {
 	.handler	=	xfrm4_rcv,
 	.err_handler	=	ah4_err,
 	.no_policy	=	1,
+	.netns_ok	=	1,
 };
 
 static int __init ah4_init(void)
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 3595012..18bb383 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -413,6 +413,7 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
 
 static void esp4_err(struct sk_buff *skb, u32 info)
 {
+	struct net *net = dev_net(skb->dev);
 	struct iphdr *iph = (struct iphdr *)skb->data;
 	struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data+(iph->ihl<<2));
 	struct xfrm_state *x;
@@ -421,7 +422,7 @@ static void esp4_err(struct sk_buff *skb, u32 info)
 	    icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
 		return;
 
-	x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET);
+	x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET);
 	if (!x)
 		return;
 	NETDEBUG(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%08x\n",
@@ -618,6 +619,7 @@ static struct net_protocol esp4_protocol = {
 	.handler	=	xfrm4_rcv,
 	.err_handler	=	esp4_err,
 	.no_policy	=	1,
+	.netns_ok	=	1,
 };
 
 static int __init esp4_init(void)
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 6ae014b..52449f7 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -407,6 +407,7 @@ out:
 static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 		    int type, int code, int offset, __be32 info)
 {
+	struct net *net = dev_net(skb->dev);
 	struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
 	struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset);
 	struct xfrm_state *x;
@@ -415,7 +416,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 	    type != ICMPV6_PKT_TOOBIG)
 		return;
 
-	x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6);
+	x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6);
 	if (!x)
 		return;
 
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 68f2af8..c2f2501 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -356,6 +356,7 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
 static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 		     int type, int code, int offset, __be32 info)
 {
+	struct net *net = dev_net(skb->dev);
 	struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
 	struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset);
 	struct xfrm_state *x;
@@ -364,7 +365,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 	    type != ICMPV6_PKT_TOOBIG)
 		return;
 
-	x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);
+	x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);
 	if (!x)
 		return;
 	printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n",
-- 
1.5.6.5


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

* [PATCH 51/53] netns xfrm: per-netns MIBs
  2008-11-25 17:27                                                                                                 ` [PATCH 50/53] netns xfrm: AH/ESP in netns! Alexey Dobriyan
@ 2008-11-25 17:27                                                                                                   ` Alexey Dobriyan
  2008-11-25 17:27                                                                                                     ` [PATCH 52/53] netns xfrm: /proc/net/xfrm_stat in netns Alexey Dobriyan
  2008-11-26  1:59                                                                                                     ` [PATCH 51/53] netns xfrm: per-netns MIBs David Miller
  2008-11-26  1:59                                                                                                   ` [PATCH 50/53] netns xfrm: AH/ESP in netns! David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/netns/mib.h |    3 ++
 include/net/xfrm.h      |   13 +++----
 net/ipv6/xfrm6_input.c  |    9 +++--
 net/xfrm/xfrm_input.c   |   22 ++++++------
 net/xfrm/xfrm_output.c  |   15 ++++----
 net/xfrm/xfrm_policy.c  |   82 +++++++++++++++++++++++++++--------------------
 net/xfrm/xfrm_proc.c    |    2 +-
 7 files changed, 81 insertions(+), 65 deletions(-)

diff --git a/include/net/netns/mib.h b/include/net/netns/mib.h
index 10cb7c3..0b44112 100644
--- a/include/net/netns/mib.h
+++ b/include/net/netns/mib.h
@@ -20,6 +20,9 @@ struct netns_mib {
 	DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics);
 	DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics);
 #endif
+#ifdef CONFIG_XFRM_STATISTICS
+	DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics);
+#endif
 };
 
 #endif
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index d076f3d..78ec3e8 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -38,14 +38,13 @@
 	MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
 
 #ifdef CONFIG_XFRM_STATISTICS
-DECLARE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics);
-#define XFRM_INC_STATS(field)		SNMP_INC_STATS(xfrm_statistics, field)
-#define XFRM_INC_STATS_BH(field)	SNMP_INC_STATS_BH(xfrm_statistics, field)
-#define XFRM_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(xfrm_statistics, field)
+#define XFRM_INC_STATS(net, field)	SNMP_INC_STATS((net)->mib.xfrm_statistics, field)
+#define XFRM_INC_STATS_BH(net, field)	SNMP_INC_STATS_BH((net)->mib.xfrm_statistics, field)
+#define XFRM_INC_STATS_USER(net, field)	SNMP_INC_STATS_USER((net)-mib.xfrm_statistics, field)
 #else
-#define XFRM_INC_STATS(field)
-#define XFRM_INC_STATS_BH(field)
-#define XFRM_INC_STATS_USER(field)
+#define XFRM_INC_STATS(net, field)	((void)(net))
+#define XFRM_INC_STATS_BH(net, field)	((void)(net))
+#define XFRM_INC_STATS_USER(net, field)	((void)(net))
 #endif
 
 extern u32 sysctl_xfrm_aevent_etime;
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index b69766a..9084582 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -58,6 +58,7 @@ EXPORT_SYMBOL(xfrm6_rcv);
 int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 		     xfrm_address_t *saddr, u8 proto)
 {
+	struct net *net = dev_net(skb->dev);
 	struct xfrm_state *x = NULL;
 	int i = 0;
 
@@ -67,7 +68,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 
 		sp = secpath_dup(skb->sp);
 		if (!sp) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMINERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR);
 			goto drop;
 		}
 		if (skb->sp)
@@ -76,7 +77,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 	}
 
 	if (1 + skb->sp->len == XFRM_MAX_DEPTH) {
-		XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR);
+		XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
 		goto drop;
 	}
 
@@ -100,7 +101,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 			break;
 		}
 
-		x = xfrm_state_lookup_byaddr(&init_net, dst, src, proto, AF_INET6);
+		x = xfrm_state_lookup_byaddr(net, dst, src, proto, AF_INET6);
 		if (!x)
 			continue;
 
@@ -122,7 +123,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 	}
 
 	if (!x) {
-		XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES);
+		XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
 		xfrm_audit_state_notfound_simple(skb, AF_INET6);
 		goto drop;
 	}
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index a714dce..b4a1317 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -128,7 +128,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 
 		sp = secpath_dup(skb->sp);
 		if (!sp) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMINERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR);
 			goto drop;
 		}
 		if (skb->sp)
@@ -142,19 +142,19 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 
 	seq = 0;
 	if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) {
-		XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
+		XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
 		goto drop;
 	}
 
 	do {
 		if (skb->sp->len == XFRM_MAX_DEPTH) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
 			goto drop;
 		}
 
 		x = xfrm_state_lookup(net, daddr, spi, nexthdr, family);
 		if (x == NULL) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
 			xfrm_audit_state_notfound(skb, family, spi, seq);
 			goto drop;
 		}
@@ -163,22 +163,22 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 
 		spin_lock(&x->lock);
 		if (unlikely(x->km.state != XFRM_STATE_VALID)) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEINVALID);
 			goto drop_unlock;
 		}
 
 		if ((x->encap ? x->encap->encap_type : 0) != encap_type) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMISMATCH);
 			goto drop_unlock;
 		}
 
 		if (x->props.replay_window && xfrm_replay_check(x, skb, seq)) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMINSTATESEQERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
 			goto drop_unlock;
 		}
 
 		if (xfrm_state_check_expire(x)) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEEXPIRED);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEEXPIRED);
 			goto drop_unlock;
 		}
 
@@ -199,7 +199,7 @@ resume:
 							 x->type->proto);
 				x->stats.integrity_failed++;
 			}
-			XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEPROTOERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR);
 			goto drop_unlock;
 		}
 
@@ -225,7 +225,7 @@ resume:
 		}
 
 		if (inner_mode->input(x, skb)) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMODEERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR);
 			goto drop;
 		}
 
@@ -243,7 +243,7 @@ resume:
 
 		err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
 		if (err < 0) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
 			goto drop;
 		}
 	} while (!err);
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index ba90e5e..c235597 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -49,27 +49,27 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
 	do {
 		err = xfrm_state_check_space(x, skb);
 		if (err) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
 			goto error_nolock;
 		}
 
 		err = x->outer_mode->output(x, skb);
 		if (err) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEMODEERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEMODEERROR);
 			goto error_nolock;
 		}
 
 		spin_lock_bh(&x->lock);
 		err = xfrm_state_check_expire(x);
 		if (err) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEEXPIRED);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEEXPIRED);
 			goto error;
 		}
 
 		if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
 			XFRM_SKB_CB(skb)->seq.output = ++x->replay.oseq;
 			if (unlikely(x->replay.oseq == 0)) {
-				XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATESEQERROR);
+				XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATESEQERROR);
 				x->replay.oseq--;
 				xfrm_audit_state_replay_overflow(x, skb);
 				err = -EOVERFLOW;
@@ -90,12 +90,12 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
 
 resume:
 		if (err) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEPROTOERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEPROTOERROR);
 			goto error_nolock;
 		}
 
 		if (!(skb->dst = dst_pop(dst))) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
 			err = -EHOSTUNREACH;
 			goto error_nolock;
 		}
@@ -179,6 +179,7 @@ static int xfrm_output_gso(struct sk_buff *skb)
 
 int xfrm_output(struct sk_buff *skb)
 {
+	struct net *net = dev_net(skb->dst->dev);
 	int err;
 
 	if (skb_is_gso(skb))
@@ -187,7 +188,7 @@ int xfrm_output(struct sk_buff *skb)
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		err = skb_checksum_help(skb);
 		if (err) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
 			kfree_skb(skb);
 			return err;
 		}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index fcf8c92..e239a25 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -36,11 +36,6 @@
 
 int sysctl_xfrm_larval_drop __read_mostly = 1;
 
-#ifdef CONFIG_XFRM_STATISTICS
-DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics) __read_mostly;
-EXPORT_SYMBOL(xfrm_statistics);
-#endif
-
 DEFINE_MUTEX(xfrm_cfg_mutex);
 EXPORT_SYMBOL(xfrm_cfg_mutex);
 
@@ -1570,7 +1565,7 @@ restart:
 		policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
 		err = PTR_ERR(policy);
 		if (IS_ERR(policy)) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
 			goto dropdst;
 		}
 	}
@@ -1585,7 +1580,7 @@ restart:
 					   dir, xfrm_policy_lookup);
 		err = PTR_ERR(policy);
 		if (IS_ERR(policy)) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
 			goto dropdst;
 		}
 	}
@@ -1608,7 +1603,7 @@ restart:
 	default:
 	case XFRM_POLICY_BLOCK:
 		/* Prohibit the flow */
-		XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK);
+		XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLBLOCK);
 		err = -EPERM;
 		goto error;
 
@@ -1628,7 +1623,7 @@ restart:
 		 */
 		dst = xfrm_find_bundle(fl, policy, family);
 		if (IS_ERR(dst)) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
 			err = PTR_ERR(dst);
 			goto error;
 		}
@@ -1644,12 +1639,12 @@ restart:
 							    XFRM_POLICY_OUT);
 			if (pols[1]) {
 				if (IS_ERR(pols[1])) {
-					XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR);
+					XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
 					err = PTR_ERR(pols[1]);
 					goto error;
 				}
 				if (pols[1]->action == XFRM_POLICY_BLOCK) {
-					XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK);
+					XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLBLOCK);
 					err = -EPERM;
 					goto error;
 				}
@@ -1680,7 +1675,7 @@ restart:
 				/* EREMOTE tells the caller to generate
 				 * a one-shot blackhole route.
 				 */
-				XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES);
+				XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
 				xfrm_pol_put(policy);
 				return -EREMOTE;
 			}
@@ -1696,7 +1691,7 @@ restart:
 				nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family);
 
 				if (nx == -EAGAIN && signal_pending(current)) {
-					XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES);
+					XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
 					err = -ERESTART;
 					goto error;
 				}
@@ -1708,7 +1703,7 @@ restart:
 				err = nx;
 			}
 			if (err < 0) {
-				XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES);
+				XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
 				goto error;
 			}
 		}
@@ -1721,7 +1716,7 @@ restart:
 		dst = xfrm_bundle_create(policy, xfrm, nx, fl, dst_orig);
 		err = PTR_ERR(dst);
 		if (IS_ERR(dst)) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLEGENERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLEGENERROR);
 			goto error;
 		}
 
@@ -1742,9 +1737,9 @@ restart:
 			dst_free(dst);
 
 			if (pol_dead)
-				XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLDEAD);
+				XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLDEAD);
 			else
-				XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
+				XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
 			err = -EHOSTUNREACH;
 			goto error;
 		}
@@ -1756,7 +1751,7 @@ restart:
 		if (unlikely(err)) {
 			write_unlock_bh(&policy->lock);
 			dst_free(dst);
-			XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
 			goto error;
 		}
 
@@ -1912,7 +1907,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 	fl_dir = policy_to_flow_dir(dir);
 
 	if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) {
-		XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
+		XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
 		return 0;
 	}
 
@@ -1925,7 +1920,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 		for (i=skb->sp->len-1; i>=0; i--) {
 			struct xfrm_state *x = skb->sp->xvec[i];
 			if (!xfrm_selector_match(&x->sel, &fl, family)) {
-				XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH);
+				XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMISMATCH);
 				return 0;
 			}
 		}
@@ -1935,7 +1930,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 	if (sk && sk->sk_policy[dir]) {
 		pol = xfrm_sk_policy_lookup(sk, dir, &fl);
 		if (IS_ERR(pol)) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR);
 			return 0;
 		}
 	}
@@ -1945,14 +1940,14 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 					xfrm_policy_lookup);
 
 	if (IS_ERR(pol)) {
-		XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);
+		XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR);
 		return 0;
 	}
 
 	if (!pol) {
 		if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) {
 			xfrm_secpath_reject(xerr_idx, skb, &fl);
-			XFRM_INC_STATS(LINUX_MIB_XFRMINNOPOLS);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOPOLS);
 			return 0;
 		}
 		return 1;
@@ -1969,7 +1964,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 						    XFRM_POLICY_IN);
 		if (pols[1]) {
 			if (IS_ERR(pols[1])) {
-				XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);
+				XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR);
 				return 0;
 			}
 			pols[1]->curlft.use_time = get_seconds();
@@ -1993,11 +1988,11 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 		for (pi = 0; pi < npols; pi++) {
 			if (pols[pi] != pol &&
 			    pols[pi]->action != XFRM_POLICY_ALLOW) {
-				XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK);
+				XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLBLOCK);
 				goto reject;
 			}
 			if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH) {
-				XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR);
+				XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
 				goto reject_error;
 			}
 			for (i = 0; i < pols[pi]->xfrm_nr; i++)
@@ -2021,20 +2016,20 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 				if (k < -1)
 					/* "-2 - errored_index" returned */
 					xerr_idx = -(2+k);
-				XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH);
+				XFRM_INC_STATS(net, LINUX_MIB_XFRMINTMPLMISMATCH);
 				goto reject;
 			}
 		}
 
 		if (secpath_has_nontransport(sp, k, &xerr_idx)) {
-			XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH);
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMINTMPLMISMATCH);
 			goto reject;
 		}
 
 		xfrm_pols_put(pols, npols);
 		return 1;
 	}
-	XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK);
+	XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLBLOCK);
 
 reject:
 	xfrm_secpath_reject(xerr_idx, skb, &fl);
@@ -2051,7 +2046,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
 
 	if (xfrm_decode_session(skb, &fl, family) < 0) {
 		/* XXX: we should have something like FWDHDRERROR here. */
-		XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
+		XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
 		return 0;
 	}
 
@@ -2380,13 +2375,27 @@ static struct notifier_block xfrm_dev_notifier = {
 };
 
 #ifdef CONFIG_XFRM_STATISTICS
-static int __init xfrm_statistics_init(void)
+static int __net_init xfrm_statistics_init(struct net *net)
 {
-	if (snmp_mib_init((void **)xfrm_statistics,
+	if (snmp_mib_init((void **)net->mib.xfrm_statistics,
 			  sizeof(struct linux_xfrm_mib)) < 0)
 		return -ENOMEM;
 	return 0;
 }
+
+static void xfrm_statistics_fini(struct net *net)
+{
+	snmp_mib_free((void **)net->mib.xfrm_statistics);
+}
+#else
+static int __net_init xfrm_statistics_init(struct net *net)
+{
+	return 0;
+}
+
+static void xfrm_statistics_fini(struct net *net)
+{
+}
 #endif
 
 static int __net_init xfrm_policy_init(struct net *net)
@@ -2480,6 +2489,9 @@ static int __net_init xfrm_net_init(struct net *net)
 {
 	int rv;
 
+	rv = xfrm_statistics_init(net);
+	if (rv < 0)
+		goto out_statistics;
 	rv = xfrm_state_init(net);
 	if (rv < 0)
 		goto out_state;
@@ -2491,6 +2503,8 @@ static int __net_init xfrm_net_init(struct net *net)
 out_policy:
 	xfrm_state_fini(net);
 out_state:
+	xfrm_statistics_fini(net);
+out_statistics:
 	return rv;
 }
 
@@ -2498,6 +2512,7 @@ static void __net_exit xfrm_net_exit(struct net *net)
 {
 	xfrm_policy_fini(net);
 	xfrm_state_fini(net);
+	xfrm_statistics_fini(net);
 }
 
 static struct pernet_operations __net_initdata xfrm_net_ops = {
@@ -2508,9 +2523,6 @@ static struct pernet_operations __net_initdata xfrm_net_ops = {
 void __init xfrm_init(void)
 {
 	register_pernet_subsys(&xfrm_net_ops);
-#ifdef CONFIG_XFRM_STATISTICS
-	xfrm_statistics_init();
-#endif
 	xfrm_input_init();
 #ifdef CONFIG_XFRM_STATISTICS
 	xfrm_proc_init();
diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c
index 2b0db13..27a2ab9 100644
--- a/net/xfrm/xfrm_proc.c
+++ b/net/xfrm/xfrm_proc.c
@@ -62,7 +62,7 @@ static int xfrm_statistics_seq_show(struct seq_file *seq, void *v)
 	int i;
 	for (i=0; xfrm_mib_list[i].name; i++)
 		seq_printf(seq, "%-24s\t%lu\n", xfrm_mib_list[i].name,
-			   fold_field((void **)xfrm_statistics,
+			   fold_field((void **)init_net.mib.xfrm_statistics,
 				      xfrm_mib_list[i].entry));
 	return 0;
 }
-- 
1.5.6.5


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

* [PATCH 52/53] netns xfrm: /proc/net/xfrm_stat in netns
  2008-11-25 17:27                                                                                                   ` [PATCH 51/53] netns xfrm: per-netns MIBs Alexey Dobriyan
@ 2008-11-25 17:27                                                                                                     ` Alexey Dobriyan
  2008-11-25 17:27                                                                                                       ` [PATCH 53/53] netns xfrm: per-netns sysctls Alexey Dobriyan
  2008-11-26  2:00                                                                                                       ` [PATCH 52/53] netns xfrm: /proc/net/xfrm_stat in netns David Miller
  2008-11-26  1:59                                                                                                     ` [PATCH 51/53] netns xfrm: per-netns MIBs David Miller
  1 sibling, 2 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/xfrm.h     |    3 ++-
 net/xfrm/xfrm_policy.c |   11 +++++++----
 net/xfrm/xfrm_proc.c   |   26 ++++++++++++--------------
 3 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 78ec3e8..1554ccd 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1306,7 +1306,8 @@ static inline void xfrm6_fini(void)
 #endif
 
 #ifdef CONFIG_XFRM_STATISTICS
-extern int xfrm_proc_init(void);
+extern int xfrm_proc_init(struct net *net);
+extern void xfrm_proc_fini(struct net *net);
 #endif
 
 extern void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index e239a25..38822b3 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2377,14 +2377,20 @@ static struct notifier_block xfrm_dev_notifier = {
 #ifdef CONFIG_XFRM_STATISTICS
 static int __net_init xfrm_statistics_init(struct net *net)
 {
+	int rv;
+
 	if (snmp_mib_init((void **)net->mib.xfrm_statistics,
 			  sizeof(struct linux_xfrm_mib)) < 0)
 		return -ENOMEM;
-	return 0;
+	rv = xfrm_proc_init(net);
+	if (rv < 0)
+		snmp_mib_free((void **)net->mib.xfrm_statistics);
+	return rv;
 }
 
 static void xfrm_statistics_fini(struct net *net)
 {
+	xfrm_proc_fini(net);
 	snmp_mib_free((void **)net->mib.xfrm_statistics);
 }
 #else
@@ -2524,9 +2530,6 @@ void __init xfrm_init(void)
 {
 	register_pernet_subsys(&xfrm_net_ops);
 	xfrm_input_init();
-#ifdef CONFIG_XFRM_STATISTICS
-	xfrm_proc_init();
-#endif
 }
 
 #ifdef CONFIG_AUDITSYSCALL
diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c
index 27a2ab9..284eaef 100644
--- a/net/xfrm/xfrm_proc.c
+++ b/net/xfrm/xfrm_proc.c
@@ -59,17 +59,18 @@ fold_field(void *mib[], int offt)
 
 static int xfrm_statistics_seq_show(struct seq_file *seq, void *v)
 {
+	struct net *net = seq->private;
 	int i;
 	for (i=0; xfrm_mib_list[i].name; i++)
 		seq_printf(seq, "%-24s\t%lu\n", xfrm_mib_list[i].name,
-			   fold_field((void **)init_net.mib.xfrm_statistics,
+			   fold_field((void **)net->mib.xfrm_statistics,
 				      xfrm_mib_list[i].entry));
 	return 0;
 }
 
 static int xfrm_statistics_seq_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, xfrm_statistics_seq_show, NULL);
+	return single_open_net(inode, file, xfrm_statistics_seq_show);
 }
 
 static struct file_operations xfrm_statistics_seq_fops = {
@@ -77,21 +78,18 @@ static struct file_operations xfrm_statistics_seq_fops = {
 	.open	 = xfrm_statistics_seq_open,
 	.read	 = seq_read,
 	.llseek	 = seq_lseek,
-	.release = single_release,
+	.release = single_release_net,
 };
 
-int __init xfrm_proc_init(void)
+int __net_init xfrm_proc_init(struct net *net)
 {
-	int rc = 0;
-
-	if (!proc_net_fops_create(&init_net, "xfrm_stat", S_IRUGO,
+	if (!proc_net_fops_create(net, "xfrm_stat", S_IRUGO,
 				  &xfrm_statistics_seq_fops))
-		goto stat_fail;
-
- out:
-	return rc;
+		return -ENOMEM;
+	return 0;
+}
 
- stat_fail:
-	rc = -ENOMEM;
-	goto out;
+void xfrm_proc_fini(struct net *net)
+{
+	proc_net_remove(net, "xfrm_stat");
 }
-- 
1.5.6.5


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

* [PATCH 53/53] netns xfrm: per-netns sysctls
  2008-11-25 17:27                                                                                                     ` [PATCH 52/53] netns xfrm: /proc/net/xfrm_stat in netns Alexey Dobriyan
@ 2008-11-25 17:27                                                                                                       ` Alexey Dobriyan
  2008-11-26  2:00                                                                                                         ` David Miller
  2008-11-26  2:00                                                                                                       ` [PATCH 52/53] netns xfrm: /proc/net/xfrm_stat in netns David Miller
  1 sibling, 1 reply; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-25 17:27 UTC (permalink / raw)
  To: davem; +Cc: herbert, kuznet, netdev, containers, Alexey Dobriyan

Make
	net.core.xfrm_aevent_etime
	net.core.xfrm_acq_expires
	net.core.xfrm_aevent_rseqth
	net.core.xfrm_larval_drop

sysctls per-netns.

For that make net_core_path[] global, register it to prevent two
/proc/net/core antries and change initcall position -- xfrm_init() is called
from fs_initcall, so this one should be fs_initcall at least.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 include/net/ip.h           |    1 +
 include/net/netns/xfrm.h   |   10 +++++
 include/net/xfrm.h         |   14 +++++---
 net/core/sysctl_net_core.c |   42 +++-------------------
 net/xfrm/Makefile          |    4 +-
 net/xfrm/xfrm_policy.c     |   10 ++++--
 net/xfrm/xfrm_state.c      |   16 ++------
 net/xfrm/xfrm_sysctl.c     |   85 ++++++++++++++++++++++++++++++++++++++++++++
 net/xfrm/xfrm_user.c       |    4 +-
 9 files changed, 125 insertions(+), 61 deletions(-)
 create mode 100644 net/xfrm/xfrm_sysctl.c

diff --git a/include/net/ip.h b/include/net/ip.h
index bc026ec..406f523 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -187,6 +187,7 @@ extern void inet_get_local_port_range(int *low, int *high);
 extern int sysctl_ip_default_ttl;
 extern int sysctl_ip_nonlocal_bind;
 
+extern struct ctl_path net_core_path[];
 extern struct ctl_path net_ipv4_ctl_path[];
 
 /* From inetpeer.c */
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 09f3060..1ba9127 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -6,6 +6,8 @@
 #include <linux/workqueue.h>
 #include <linux/xfrm.h>
 
+struct ctl_table_header;
+
 struct xfrm_policy_hash {
 	struct hlist_head	*table;
 	unsigned int		hmask;
@@ -41,6 +43,14 @@ struct netns_xfrm {
 	struct work_struct	policy_hash_work;
 
 	struct sock		*nlsk;
+
+	u32			sysctl_aevent_etime;
+	u32			sysctl_aevent_rseqth;
+	int			sysctl_larval_drop;
+	u32			sysctl_acq_expires;
+#ifdef CONFIG_SYSCTL
+	struct ctl_table_header	*sysctl_hdr;
+#endif
 };
 
 #endif
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 1554ccd..2e9f5c0 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -47,11 +47,6 @@
 #define XFRM_INC_STATS_USER(net, field)	((void)(net))
 #endif
 
-extern u32 sysctl_xfrm_aevent_etime;
-extern u32 sysctl_xfrm_aevent_rseqth;
-extern int sysctl_xfrm_larval_drop;
-extern u32 sysctl_xfrm_acq_expires;
-
 extern struct mutex xfrm_cfg_mutex;
 
 /* Organization of SPD aka "XFRM rules"
@@ -1310,6 +1305,15 @@ extern int xfrm_proc_init(struct net *net);
 extern void xfrm_proc_fini(struct net *net);
 #endif
 
+extern int xfrm_sysctl_init(struct net *net);
+#ifdef CONFIG_SYSCTL
+extern void xfrm_sysctl_fini(struct net *net);
+#else
+static inline void xfrm_sysctl_fini(struct net *net)
+{
+}
+#endif
+
 extern void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto);
 extern int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
 			   int (*func)(struct xfrm_state *, int, void*), void *);
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index 2bc0384..83d3398 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -12,7 +12,6 @@
 #include <linux/netdevice.h>
 #include <linux/init.h>
 #include <net/sock.h>
-#include <net/xfrm.h>
 
 static struct ctl_table net_core_table[] = {
 #ifdef CONFIG_NET
@@ -89,40 +88,6 @@ static struct ctl_table net_core_table[] = {
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec
 	},
-#ifdef CONFIG_XFRM
-	{
-		.ctl_name	= NET_CORE_AEVENT_ETIME,
-		.procname	= "xfrm_aevent_etime",
-		.data		= &sysctl_xfrm_aevent_etime,
-		.maxlen		= sizeof(u32),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec
-	},
-	{
-		.ctl_name	= NET_CORE_AEVENT_RSEQTH,
-		.procname	= "xfrm_aevent_rseqth",
-		.data		= &sysctl_xfrm_aevent_rseqth,
-		.maxlen		= sizeof(u32),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec
-	},
-	{
-		.ctl_name	= CTL_UNNUMBERED,
-		.procname	= "xfrm_larval_drop",
-		.data		= &sysctl_xfrm_larval_drop,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec
-	},
-	{
-		.ctl_name	= CTL_UNNUMBERED,
-		.procname	= "xfrm_acq_expires",
-		.data		= &sysctl_xfrm_acq_expires,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec
-	},
-#endif /* CONFIG_XFRM */
 #endif /* CONFIG_NET */
 	{
 		.ctl_name	= NET_CORE_BUDGET,
@@ -155,7 +120,7 @@ static struct ctl_table netns_core_table[] = {
 	{ .ctl_name = 0 }
 };
 
-static __net_initdata struct ctl_path net_core_path[] = {
+__net_initdata struct ctl_path net_core_path[] = {
 	{ .procname = "net", .ctl_name = CTL_NET, },
 	{ .procname = "core", .ctl_name = NET_CORE, },
 	{ },
@@ -207,8 +172,11 @@ static __net_initdata struct pernet_operations sysctl_core_ops = {
 
 static __init int sysctl_core_init(void)
 {
+	static struct ctl_table empty[1];
+
+	register_sysctl_paths(net_core_path, empty);
 	register_net_sysctl_rotable(net_core_path, net_core_table);
 	return register_pernet_subsys(&sysctl_core_ops);
 }
 
-__initcall(sysctl_core_init);
+fs_initcall(sysctl_core_init);
diff --git a/net/xfrm/Makefile b/net/xfrm/Makefile
index 0f439a7..c631047 100644
--- a/net/xfrm/Makefile
+++ b/net/xfrm/Makefile
@@ -3,8 +3,8 @@
 #
 
 obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_hash.o \
-		      xfrm_input.o xfrm_output.o xfrm_algo.o
+		      xfrm_input.o xfrm_output.o xfrm_algo.o \
+		      xfrm_sysctl.o
 obj-$(CONFIG_XFRM_STATISTICS) += xfrm_proc.o
 obj-$(CONFIG_XFRM_USER) += xfrm_user.o
 obj-$(CONFIG_XFRM_IPCOMP) += xfrm_ipcomp.o
-
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 38822b3..393cc65 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -34,8 +34,6 @@
 
 #include "xfrm_hash.h"
 
-int sysctl_xfrm_larval_drop __read_mostly = 1;
-
 DEFINE_MUTEX(xfrm_cfg_mutex);
 EXPORT_SYMBOL(xfrm_cfg_mutex);
 
@@ -1671,7 +1669,7 @@ restart:
 
 		if (unlikely(nx<0)) {
 			err = nx;
-			if (err == -EAGAIN && sysctl_xfrm_larval_drop) {
+			if (err == -EAGAIN && net->xfrm.sysctl_larval_drop) {
 				/* EREMOTE tells the caller to generate
 				 * a one-shot blackhole route.
 				 */
@@ -2504,8 +2502,13 @@ static int __net_init xfrm_net_init(struct net *net)
 	rv = xfrm_policy_init(net);
 	if (rv < 0)
 		goto out_policy;
+	rv = xfrm_sysctl_init(net);
+	if (rv < 0)
+		goto out_sysctl;
 	return 0;
 
+out_sysctl:
+	xfrm_policy_fini(net);
 out_policy:
 	xfrm_state_fini(net);
 out_state:
@@ -2516,6 +2519,7 @@ out_statistics:
 
 static void __net_exit xfrm_net_exit(struct net *net)
 {
+	xfrm_sysctl_fini(net);
 	xfrm_policy_fini(net);
 	xfrm_state_fini(net);
 	xfrm_statistics_fini(net);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 662e47b..2fd57f8 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -24,14 +24,6 @@
 
 #include "xfrm_hash.h"
 
-u32 sysctl_xfrm_aevent_etime __read_mostly = XFRM_AE_ETIME;
-EXPORT_SYMBOL(sysctl_xfrm_aevent_etime);
-
-u32 sysctl_xfrm_aevent_rseqth __read_mostly = XFRM_AE_SEQT_SIZE;
-EXPORT_SYMBOL(sysctl_xfrm_aevent_rseqth);
-
-u32 sysctl_xfrm_acq_expires __read_mostly = 30;
-
 /* Each xfrm_state may be linked to two tables:
 
    1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl)
@@ -851,8 +843,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 				h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, family);
 				hlist_add_head(&x->byspi, net->xfrm.state_byspi+h);
 			}
-			x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
-			x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
+			x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires;
+			x->timer.expires = jiffies + net->xfrm.sysctl_acq_expires*HZ;
 			add_timer(&x->timer);
 			net->xfrm.state_num++;
 			xfrm_hash_grow_check(net, x->bydst.next != NULL);
@@ -1040,9 +1032,9 @@ static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family
 		x->props.family = family;
 		x->props.mode = mode;
 		x->props.reqid = reqid;
-		x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
+		x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires;
 		xfrm_state_hold(x);
-		x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
+		x->timer.expires = jiffies + net->xfrm.sysctl_acq_expires*HZ;
 		add_timer(&x->timer);
 		list_add(&x->km.all, &net->xfrm.state_all);
 		hlist_add_head(&x->bydst, net->xfrm.state_bydst+h);
diff --git a/net/xfrm/xfrm_sysctl.c b/net/xfrm/xfrm_sysctl.c
new file mode 100644
index 0000000..2e6ffb6
--- /dev/null
+++ b/net/xfrm/xfrm_sysctl.c
@@ -0,0 +1,85 @@
+#include <linux/sysctl.h>
+#include <net/net_namespace.h>
+#include <net/xfrm.h>
+
+static void __xfrm_sysctl_init(struct net *net)
+{
+	net->xfrm.sysctl_aevent_etime = XFRM_AE_ETIME;
+	net->xfrm.sysctl_aevent_rseqth = XFRM_AE_SEQT_SIZE;
+	net->xfrm.sysctl_larval_drop = 1;
+	net->xfrm.sysctl_acq_expires = 30;
+}
+
+#ifdef CONFIG_SYSCTL
+static struct ctl_table xfrm_table[] = {
+	{
+		.ctl_name	= NET_CORE_AEVENT_ETIME,
+		.procname	= "xfrm_aevent_etime",
+		.maxlen		= sizeof(u32),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec
+	},
+	{
+		.ctl_name	= NET_CORE_AEVENT_RSEQTH,
+		.procname	= "xfrm_aevent_rseqth",
+		.maxlen		= sizeof(u32),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec
+	},
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "xfrm_larval_drop",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec
+	},
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "xfrm_acq_expires",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec
+	},
+	{}
+};
+
+int __net_init xfrm_sysctl_init(struct net *net)
+{
+	struct ctl_table *table;
+
+	__xfrm_sysctl_init(net);
+
+	table = kmemdup(xfrm_table, sizeof(xfrm_table), GFP_KERNEL);
+	if (!table)
+		goto out_kmemdup;
+	table[0].data = &net->xfrm.sysctl_aevent_etime;
+	table[1].data = &net->xfrm.sysctl_aevent_rseqth;
+	table[2].data = &net->xfrm.sysctl_larval_drop;
+	table[3].data = &net->xfrm.sysctl_acq_expires;
+
+	net->xfrm.sysctl_hdr = register_net_sysctl_table(net, net_core_path, table);
+	if (!net->xfrm.sysctl_hdr)
+		goto out_register;
+	return 0;
+
+out_register:
+	kfree(table);
+out_kmemdup:
+	return -ENOMEM;
+}
+
+void xfrm_sysctl_fini(struct net *net)
+{
+	struct ctl_table *table;
+
+	table = net->xfrm.sysctl_hdr->ctl_table_arg;
+	unregister_net_sysctl_table(net->xfrm.sysctl_hdr);
+	kfree(table);
+}
+#else
+int __net_init xfrm_sysctl_init(struct net *net)
+{
+	__xfrm_sysctl_init(net);
+	return 0;
+}
+#endif
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index b7240d5..38ffaf3 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -368,9 +368,9 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
 		goto error;
 
 	x->km.seq = p->seq;
-	x->replay_maxdiff = sysctl_xfrm_aevent_rseqth;
+	x->replay_maxdiff = net->xfrm.sysctl_aevent_rseqth;
 	/* sysctl_xfrm_aevent_etime is in 100ms units */
-	x->replay_maxage = (sysctl_xfrm_aevent_etime*HZ)/XFRM_AE_ETH_M;
+	x->replay_maxage = (net->xfrm.sysctl_aevent_etime*HZ)/XFRM_AE_ETH_M;
 	x->preplay.bitmap = 0;
 	x->preplay.seq = x->replay.seq+x->replay_maxdiff;
 	x->preplay.oseq = x->replay.oseq +x->replay_maxdiff;
-- 
1.5.6.5


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

* Re: [PATCH 01/53] xfrm: initialise xfrm_policy_gc_work statically
  2008-11-25 17:26 [PATCH 01/53] xfrm: initialise xfrm_policy_gc_work statically Alexey Dobriyan
  2008-11-25 17:26 ` [PATCH 02/53] netns xfrm: add netns boilerplate Alexey Dobriyan
@ 2008-11-26  1:14 ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:14 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:33 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 02/53] netns xfrm: add netns boilerplate
  2008-11-25 17:26 ` [PATCH 02/53] netns xfrm: add netns boilerplate Alexey Dobriyan
  2008-11-25 17:26   ` [PATCH 03/53] netns xfrm: add struct xfrm_state::xs_net Alexey Dobriyan
@ 2008-11-26  1:14   ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:14 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:34 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 03/53] netns xfrm: add struct xfrm_state::xs_net
  2008-11-25 17:26   ` [PATCH 03/53] netns xfrm: add struct xfrm_state::xs_net Alexey Dobriyan
  2008-11-25 17:26     ` [PATCH 04/53] netns xfrm: per-netns xfrm_state_all list Alexey Dobriyan
@ 2008-11-26  1:15     ` David Miller
  2008-11-26  4:25       ` Alexey Dobriyan
  1 sibling, 1 reply; 107+ messages in thread
From: David Miller @ 2008-11-26  1:15 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:35 +0300

> To avoid unnecessary complications with passing netns around.
> 
> * set once, very early after allocating
> * once set, never changes
> 
> For a while create every xfrm_state in init_net.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

> @@ -223,6 +226,11 @@ struct xfrm_state
>  	void			*data;
>  };
>  
> +static inline struct net *xs_net(struct xfrm_state *x)
> +{
> +	return read_pnet(&x->xs_net);
> +}
> +
>  /* xflags - make enum if more show up */

Look mom, no ifdefs!  Amazing!

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

* Re: [PATCH 04/53] netns xfrm: per-netns xfrm_state_all list
  2008-11-25 17:26     ` [PATCH 04/53] netns xfrm: per-netns xfrm_state_all list Alexey Dobriyan
  2008-11-25 17:26       ` [PATCH 05/53] netns xfrm: per-netns xfrm_state_bydst hash Alexey Dobriyan
@ 2008-11-26  1:16       ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:16 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:36 +0300

> This is done to get
> a) simple "something leaked" check
> b) cover possible DoSes when other netns puts many, many xfrm_states
>    onto a list.
> c) not miss "alien xfrm_state" check in some of list iterators in future.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 05/53] netns xfrm: per-netns xfrm_state_bydst hash
  2008-11-25 17:26       ` [PATCH 05/53] netns xfrm: per-netns xfrm_state_bydst hash Alexey Dobriyan
  2008-11-25 17:26         ` [PATCH 06/53] netns xfrm: per-netns xfrm_state_bysrc hash Alexey Dobriyan
@ 2008-11-26  1:17         ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:17 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:37 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 06/53] netns xfrm: per-netns xfrm_state_bysrc hash
  2008-11-25 17:26         ` [PATCH 06/53] netns xfrm: per-netns xfrm_state_bysrc hash Alexey Dobriyan
  2008-11-25 17:26           ` [PATCH 07/53] netns xfrm: per-netns xfrm_state_byspi hash Alexey Dobriyan
@ 2008-11-26  1:17           ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:17 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:38 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 07/53] netns xfrm: per-netns xfrm_state_byspi hash
  2008-11-25 17:26           ` [PATCH 07/53] netns xfrm: per-netns xfrm_state_byspi hash Alexey Dobriyan
  2008-11-25 17:26             ` [PATCH 08/53] netns xfrm: per-netns xfrm_state_hmask Alexey Dobriyan
@ 2008-11-26  1:17             ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:17 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:39 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 08/53] netns xfrm: per-netns xfrm_state_hmask
  2008-11-25 17:26             ` [PATCH 08/53] netns xfrm: per-netns xfrm_state_hmask Alexey Dobriyan
  2008-11-25 17:26               ` [PATCH 09/53] netns xfrm: per-netns xfrm_state counts Alexey Dobriyan
@ 2008-11-26  1:18               ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:18 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:40 +0300

> Since hashtables are per-netns, they can be independently resized.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 09/53] netns xfrm: per-netns xfrm_state counts
  2008-11-25 17:26               ` [PATCH 09/53] netns xfrm: per-netns xfrm_state counts Alexey Dobriyan
  2008-11-25 17:26                 ` [PATCH 10/53] netns xfrm: per-netns xfrm_hash_work Alexey Dobriyan
@ 2008-11-26  1:18                 ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:18 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:41 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 10/53] netns xfrm: per-netns xfrm_hash_work
  2008-11-25 17:26                 ` [PATCH 10/53] netns xfrm: per-netns xfrm_hash_work Alexey Dobriyan
  2008-11-25 17:26                   ` [PATCH 11/53] netns xfrm: per-netns state GC list Alexey Dobriyan
@ 2008-11-26  1:19                   ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:19 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:42 +0300

> All of this is implicit passing which netns's hashes should be resized.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 11/53] netns xfrm: per-netns state GC list
  2008-11-25 17:26                   ` [PATCH 11/53] netns xfrm: per-netns state GC list Alexey Dobriyan
  2008-11-25 17:26                     ` [PATCH 12/53] netns xfrm: per-netns state GC work Alexey Dobriyan
@ 2008-11-26  1:20                     ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:20 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:43 +0300

> km_waitq is going to be made per-netns to disallow spurious wakeups
> in __xfrm_lookup().
> 
> To not wakeup after every garbage-collected xfrm_state (which potentially
> can be from different netns) make state GC list per-netns.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 12/53] netns xfrm: per-netns state GC work
  2008-11-25 17:26                     ` [PATCH 12/53] netns xfrm: per-netns state GC work Alexey Dobriyan
  2008-11-25 17:26                       ` [PATCH 13/53] netns xfrm: per-netns km_waitq Alexey Dobriyan
@ 2008-11-26  1:20                       ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:20 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:44 +0300

> State GC is per-netns, and this is part of it.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 13/53] netns xfrm: per-netns km_waitq
  2008-11-25 17:26                       ` [PATCH 13/53] netns xfrm: per-netns km_waitq Alexey Dobriyan
  2008-11-25 17:26                         ` [PATCH 14/53] netns xfrm: add struct xfrm_policy::xp_net Alexey Dobriyan
@ 2008-11-26  1:21                         ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:21 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:45 +0300

> Dissalow spurious wakeups in __xfrm_lookup().
  ^^^^^^^^

typo, which I fixed...

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied, thanks.

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

* Re: [PATCH 14/53] netns xfrm: add struct xfrm_policy::xp_net
  2008-11-25 17:26                         ` [PATCH 14/53] netns xfrm: add struct xfrm_policy::xp_net Alexey Dobriyan
  2008-11-25 17:26                           ` [PATCH 15/53] netns xfrm: per-netns policy list Alexey Dobriyan
@ 2008-11-26  1:21                           ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:21 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:46 +0300

> Again, to avoid complications with passing netns when not necessary.
> Again, ->xp_net is set-once field, once set it never changes.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 15/53] netns xfrm: per-netns policy list
  2008-11-25 17:26                           ` [PATCH 15/53] netns xfrm: per-netns policy list Alexey Dobriyan
  2008-11-25 17:26                             ` [PATCH 16/53] netns xfrm: per-netns xfrm_policy_byidx hash Alexey Dobriyan
@ 2008-11-26  1:22                             ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:22 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:47 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied, thanks.

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

* Re: [PATCH 16/53] netns xfrm: per-netns xfrm_policy_byidx hash
  2008-11-25 17:26                             ` [PATCH 16/53] netns xfrm: per-netns xfrm_policy_byidx hash Alexey Dobriyan
  2008-11-25 17:26                               ` [PATCH 17/53] netns xfrm: per-netns xfrm_policy_byidx hashmask Alexey Dobriyan
@ 2008-11-26  1:22                               ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:22 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:48 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 17/53] netns xfrm: per-netns xfrm_policy_byidx hashmask
  2008-11-25 17:26                               ` [PATCH 17/53] netns xfrm: per-netns xfrm_policy_byidx hashmask Alexey Dobriyan
  2008-11-25 17:26                                 ` [PATCH 18/53] netns xfrm: per-netns inexact policies Alexey Dobriyan
@ 2008-11-26  1:23                                 ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:23 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:49 +0300

> Per-netns hashes are independently resizeable.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 18/53] netns xfrm: per-netns inexact policies
  2008-11-25 17:26                                 ` [PATCH 18/53] netns xfrm: per-netns inexact policies Alexey Dobriyan
  2008-11-25 17:26                                   ` [PATCH 19/53] netns xfrm: per-netns xfrm_policy_bydst hash Alexey Dobriyan
@ 2008-11-26  1:23                                   ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:23 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:50 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 19/53] netns xfrm: per-netns xfrm_policy_bydst hash
  2008-11-25 17:26                                   ` [PATCH 19/53] netns xfrm: per-netns xfrm_policy_bydst hash Alexey Dobriyan
  2008-11-25 17:26                                     ` [PATCH 20/53] netns xfrm: per-netns policy counts Alexey Dobriyan
@ 2008-11-26  1:23                                     ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:23 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:51 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 20/53] netns xfrm: per-netns policy counts
  2008-11-25 17:26                                     ` [PATCH 20/53] netns xfrm: per-netns policy counts Alexey Dobriyan
  2008-11-25 17:26                                       ` [PATCH 21/53] netns xfrm: per-netns policy hash resizing work Alexey Dobriyan
@ 2008-11-26  1:24                                       ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:24 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:52 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 21/53] netns xfrm: per-netns policy hash resizing work
  2008-11-25 17:26                                       ` [PATCH 21/53] netns xfrm: per-netns policy hash resizing work Alexey Dobriyan
  2008-11-25 17:26                                         ` [PATCH 22/53] netns xfrm: propagate netns into bydst/bysrc/byspi hash functions Alexey Dobriyan
@ 2008-11-26  1:29                                         ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:29 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:53 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 22/53] netns xfrm: propagate netns into bydst/bysrc/byspi hash functions
  2008-11-25 17:26                                         ` [PATCH 22/53] netns xfrm: propagate netns into bydst/bysrc/byspi hash functions Alexey Dobriyan
  2008-11-25 17:26                                           ` [PATCH 23/53] netns xfrm: trivial netns propagations Alexey Dobriyan
@ 2008-11-26  1:29                                           ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:29 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:54 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 23/53] netns xfrm: trivial netns propagations
  2008-11-25 17:26                                           ` [PATCH 23/53] netns xfrm: trivial netns propagations Alexey Dobriyan
  2008-11-25 17:26                                             ` [PATCH 24/53] netns xfrm: state flush in netns Alexey Dobriyan
@ 2008-11-26  1:29                                             ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:29 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:55 +0300

> Take netns from xfrm_state or xfrm_policy.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 24/53] netns xfrm: state flush in netns
  2008-11-25 17:26                                             ` [PATCH 24/53] netns xfrm: state flush in netns Alexey Dobriyan
  2008-11-25 17:26                                               ` [PATCH 25/53] netns xfrm: state lookup " Alexey Dobriyan
@ 2008-11-26  1:30                                               ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:30 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:56 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 25/53] netns xfrm: state lookup in netns
  2008-11-25 17:26                                               ` [PATCH 25/53] netns xfrm: state lookup " Alexey Dobriyan
  2008-11-25 17:26                                                 ` [PATCH 26/53] netns xfrm: fixup xfrm_alloc_spi() Alexey Dobriyan
@ 2008-11-26  1:30                                                 ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:30 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:57 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 26/53] netns xfrm: fixup xfrm_alloc_spi()
  2008-11-25 17:26                                                 ` [PATCH 26/53] netns xfrm: fixup xfrm_alloc_spi() Alexey Dobriyan
  2008-11-25 17:26                                                   ` [PATCH 27/53] netns xfrm: finding states in netns Alexey Dobriyan
@ 2008-11-26  1:31                                                   ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:31 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:58 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 27/53] netns xfrm: finding states in netns
  2008-11-25 17:26                                                   ` [PATCH 27/53] netns xfrm: finding states in netns Alexey Dobriyan
  2008-11-25 17:27                                                     ` [PATCH 28/53] netns xfrm: state walking " Alexey Dobriyan
@ 2008-11-26  1:31                                                     ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:31 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:26:59 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 28/53] netns xfrm: state walking in netns
  2008-11-25 17:27                                                     ` [PATCH 28/53] netns xfrm: state walking " Alexey Dobriyan
  2008-11-25 17:27                                                       ` [PATCH 29/53] netns xfrm: propagate netns into policy byidx hash Alexey Dobriyan
@ 2008-11-26  1:32                                                       ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:32 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:00 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 29/53] netns xfrm: propagate netns into policy byidx hash
  2008-11-25 17:27                                                       ` [PATCH 29/53] netns xfrm: propagate netns into policy byidx hash Alexey Dobriyan
  2008-11-25 17:27                                                         ` [PATCH 30/53] netns xfrm: policy insertion in netns Alexey Dobriyan
@ 2008-11-26  1:32                                                         ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:32 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:01 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 30/53] netns xfrm: policy insertion in netns
  2008-11-25 17:27                                                         ` [PATCH 30/53] netns xfrm: policy insertion in netns Alexey Dobriyan
  2008-11-25 17:27                                                           ` [PATCH 31/53] netns xfrm: policy flushing " Alexey Dobriyan
@ 2008-11-26  1:33                                                           ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:33 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:02 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 31/53] netns xfrm: policy flushing in netns
  2008-11-25 17:27                                                           ` [PATCH 31/53] netns xfrm: policy flushing " Alexey Dobriyan
  2008-11-25 17:27                                                             ` [PATCH 32/53] netns xfrm: finding policy " Alexey Dobriyan
@ 2008-11-26  1:33                                                             ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:33 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:03 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 32/53] netns xfrm: finding policy in netns
  2008-11-25 17:27                                                             ` [PATCH 32/53] netns xfrm: finding policy " Alexey Dobriyan
  2008-11-25 17:27                                                               ` [PATCH 33/53] netns xfrm: policy walking " Alexey Dobriyan
@ 2008-11-26  1:34                                                               ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:34 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:04 +0300

> Add netns parameter to xfrm_policy_bysel_ctx(), xfrm_policy_byidx().
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 33/53] netns xfrm: policy walking in netns
  2008-11-25 17:27                                                               ` [PATCH 33/53] netns xfrm: policy walking " Alexey Dobriyan
  2008-11-25 17:27                                                                 ` [PATCH 34/53] netns xfrm: lookup " Alexey Dobriyan
@ 2008-11-26  1:34                                                                 ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:34 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:05 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 34/53] netns xfrm: lookup in netns
  2008-11-25 17:27                                                                 ` [PATCH 34/53] netns xfrm: lookup " Alexey Dobriyan
  2008-11-25 17:27                                                                   ` [PATCH 35/53] netns xfrm: xfrm_policy_check " Alexey Dobriyan
@ 2008-11-26  1:35                                                                   ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:35 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:06 +0300

> Pass netns to xfrm_lookup()/__xfrm_lookup(). For that pass netns
> to flow_cache_lookup() and resolver callback.
> 
> Take it from socket or netdevice. Stub DECnet to init_net.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 35/53] netns xfrm: xfrm_policy_check in netns
  2008-11-25 17:27                                                                   ` [PATCH 35/53] netns xfrm: xfrm_policy_check " Alexey Dobriyan
  2008-11-25 17:27                                                                     ` [PATCH 36/53] netns xfrm: xfrm_route_forward() " Alexey Dobriyan
@ 2008-11-26  1:35                                                                     ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:35 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:07 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 36/53] netns xfrm: xfrm_route_forward() in netns
  2008-11-25 17:27                                                                     ` [PATCH 36/53] netns xfrm: xfrm_route_forward() " Alexey Dobriyan
  2008-11-25 17:27                                                                       ` [PATCH 37/53] netns xfrm: flushing/pruning bundles " Alexey Dobriyan
@ 2008-11-26  1:36                                                                       ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:36 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:08 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 37/53] netns xfrm: flushing/pruning bundles in netns
  2008-11-25 17:27                                                                       ` [PATCH 37/53] netns xfrm: flushing/pruning bundles " Alexey Dobriyan
  2008-11-25 17:27                                                                         ` [PATCH 38/53] netns xfrm: dst garbage-collecting " Alexey Dobriyan
@ 2008-11-26  1:36                                                                         ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:36 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:09 +0300

> Allow netdevice notifier as result.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 38/53] netns xfrm: dst garbage-collecting in netns
  2008-11-25 17:27                                                                         ` [PATCH 38/53] netns xfrm: dst garbage-collecting " Alexey Dobriyan
  2008-11-25 17:27                                                                           ` [PATCH 39/53] netns xfrm: xfrm_input() fixup Alexey Dobriyan
@ 2008-11-26  1:37                                                                           ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:37 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:10 +0300

> Pass netns pointer to struct xfrm_policy_afinfo::garbage_collect()
> 
> 	[This needs more thoughts on what to do with dst_ops]
> 	[Currently stub to init_net]

Yes, this dst_ops issue has been brought up a few times.

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 39/53] netns xfrm: xfrm_input() fixup
  2008-11-25 17:27                                                                           ` [PATCH 39/53] netns xfrm: xfrm_input() fixup Alexey Dobriyan
  2008-11-25 17:27                                                                             ` [PATCH 40/53] netns xfrm: per-netns NETLINK_XFRM socket Alexey Dobriyan
@ 2008-11-26  1:38                                                                             ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:38 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:11 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 40/53] netns xfrm: per-netns NETLINK_XFRM socket
  2008-11-25 17:27                                                                             ` [PATCH 40/53] netns xfrm: per-netns NETLINK_XFRM socket Alexey Dobriyan
  2008-11-25 17:27                                                                               ` [PATCH 41/53] netns xfrm: xfrm_user module in netns Alexey Dobriyan
@ 2008-11-26  1:38                                                                               ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:38 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:12 +0300

> Stub senders to init_net's one temporarily.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 41/53] netns xfrm: xfrm_user module in netns
       [not found]                                                                                 ` <1227634045-27534-41-git-send-email-adobriyan-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2008-11-26  1:50                                                                                   ` David Miller
  0 siblings, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:50 UTC (permalink / raw)
  To: adobriyan-Re5JQEeQqe8AvxtiuMwx3w
  Cc: kuznet-v/Mj1YrvjDBInbfyfbPRSQ,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q,
	netdev-u79uwXL29TY76Z2rM5mHXA

From: Alexey Dobriyan <adobriyan-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Tue, 25 Nov 2008 20:27:13 +0300

> Grab netns either from netlink socket, state or policy.
> 
> SA and SPD flush are in init_net for now, this requires little
> attention, see below.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Applied.

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

* Re: [PATCH 42/53] netns xfrm: pass netns with KM notifications
  2008-11-25 17:27                                                                                 ` [PATCH 42/53] netns xfrm: pass netns with KM notifications Alexey Dobriyan
  2008-11-25 17:27                                                                                   ` [PATCH 43/53] netns xfrm: KM reporting in netns Alexey Dobriyan
@ 2008-11-26  1:50                                                                                   ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:50 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:14 +0300

> SA and SPD flush are executed with NULL SA and SPD respectively, for
> these cases pass netns explicitly from userspace socket.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 43/53] netns xfrm: KM reporting in netns
  2008-11-25 17:27                                                                                   ` [PATCH 43/53] netns xfrm: KM reporting in netns Alexey Dobriyan
  2008-11-25 17:27                                                                                     ` [PATCH 44/53] netns xfrm: ->dst_lookup " Alexey Dobriyan
@ 2008-11-26  1:51                                                                                     ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:51 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:15 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 44/53] netns xfrm: ->dst_lookup in netns
  2008-11-25 17:27                                                                                     ` [PATCH 44/53] netns xfrm: ->dst_lookup " Alexey Dobriyan
  2008-11-25 17:27                                                                                       ` [PATCH 45/53] netns xfrm: ->get_saddr " Alexey Dobriyan
@ 2008-11-26  1:51                                                                                       ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:51 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:16 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 45/53] netns xfrm: ->get_saddr in netns
  2008-11-25 17:27                                                                                       ` [PATCH 45/53] netns xfrm: ->get_saddr " Alexey Dobriyan
  2008-11-25 17:27                                                                                         ` [PATCH 46/53] netns xfrm: flush SA/SPDs on netns stop Alexey Dobriyan
@ 2008-11-26  1:56                                                                                         ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:56 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:17 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 46/53] netns xfrm: flush SA/SPDs on netns stop
  2008-11-25 17:27                                                                                         ` [PATCH 46/53] netns xfrm: flush SA/SPDs on netns stop Alexey Dobriyan
  2008-11-25 17:27                                                                                           ` [PATCH 47/53] netns PF_KEY: part 1 Alexey Dobriyan
@ 2008-11-26  1:57                                                                                           ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:57 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:18 +0300

> SA/SPD doesn't pin netns (and it shouldn't), so get rid of them by hand.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 47/53] netns PF_KEY: part 1
  2008-11-25 17:27                                                                                           ` [PATCH 47/53] netns PF_KEY: part 1 Alexey Dobriyan
  2008-11-25 17:27                                                                                             ` [PATCH 48/53] netns PF_KEY: part 2 Alexey Dobriyan
@ 2008-11-26  1:58                                                                                             ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:58 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:19 +0300

> * netns boilerplate
> * keep per-netns socket list
> * keep per-netns number of sockets
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 48/53] netns PF_KEY: part 2
  2008-11-25 17:27                                                                                             ` [PATCH 48/53] netns PF_KEY: part 2 Alexey Dobriyan
  2008-11-25 17:27                                                                                               ` [PATCH 49/53] netns PF_KEY: per-netns /proc/pfkey Alexey Dobriyan
@ 2008-11-26  1:58                                                                                               ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:58 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:20 +0300

> * interaction with userspace -- take netns from userspace socket.
> * in ->notify hook take netns either from SA or explicitly passed --
> 	we don't know if SA/SPD flush is coming.
> * stub policy migration with init_net for now.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 49/53] netns PF_KEY: per-netns /proc/pfkey
  2008-11-25 17:27                                                                                               ` [PATCH 49/53] netns PF_KEY: per-netns /proc/pfkey Alexey Dobriyan
  2008-11-25 17:27                                                                                                 ` [PATCH 50/53] netns xfrm: AH/ESP in netns! Alexey Dobriyan
@ 2008-11-26  1:59                                                                                                 ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:59 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:21 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 50/53] netns xfrm: AH/ESP in netns!
  2008-11-25 17:27                                                                                                 ` [PATCH 50/53] netns xfrm: AH/ESP in netns! Alexey Dobriyan
  2008-11-25 17:27                                                                                                   ` [PATCH 51/53] netns xfrm: per-netns MIBs Alexey Dobriyan
@ 2008-11-26  1:59                                                                                                   ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:59 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:22 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Yahoo!  Applied.

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

* Re: [PATCH 51/53] netns xfrm: per-netns MIBs
  2008-11-25 17:27                                                                                                   ` [PATCH 51/53] netns xfrm: per-netns MIBs Alexey Dobriyan
  2008-11-25 17:27                                                                                                     ` [PATCH 52/53] netns xfrm: /proc/net/xfrm_stat in netns Alexey Dobriyan
@ 2008-11-26  1:59                                                                                                     ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  1:59 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:23 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 52/53] netns xfrm: /proc/net/xfrm_stat in netns
  2008-11-25 17:27                                                                                                     ` [PATCH 52/53] netns xfrm: /proc/net/xfrm_stat in netns Alexey Dobriyan
  2008-11-25 17:27                                                                                                       ` [PATCH 53/53] netns xfrm: per-netns sysctls Alexey Dobriyan
@ 2008-11-26  2:00                                                                                                       ` David Miller
  1 sibling, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  2:00 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:24 +0300

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

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

* Re: [PATCH 53/53] netns xfrm: per-netns sysctls
  2008-11-25 17:27                                                                                                       ` [PATCH 53/53] netns xfrm: per-netns sysctls Alexey Dobriyan
@ 2008-11-26  2:00                                                                                                         ` David Miller
  0 siblings, 0 replies; 107+ messages in thread
From: David Miller @ 2008-11-26  2:00 UTC (permalink / raw)
  To: adobriyan; +Cc: herbert, kuznet, netdev, containers

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 25 Nov 2008 20:27:25 +0300

> Make
> 	net.core.xfrm_aevent_etime
> 	net.core.xfrm_acq_expires
> 	net.core.xfrm_aevent_rseqth
> 	net.core.xfrm_larval_drop
> 
> sysctls per-netns.
> 
> For that make net_core_path[] global, register it to prevent two
> /proc/net/core antries and change initcall position -- xfrm_init() is called
> from fs_initcall, so this one should be fs_initcall at least.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied.

Thanks a lot Alexey.

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

* Re: [PATCH 03/53] netns xfrm: add struct xfrm_state::xs_net
  2008-11-26  1:15     ` [PATCH 03/53] netns xfrm: add struct xfrm_state::xs_net David Miller
@ 2008-11-26  4:25       ` Alexey Dobriyan
  0 siblings, 0 replies; 107+ messages in thread
From: Alexey Dobriyan @ 2008-11-26  4:25 UTC (permalink / raw)
  To: David Miller; +Cc: herbert, kuznet, netdev, containers

On Tue, Nov 25, 2008 at 05:15:36PM -0800, David Miller wrote:
> From: Alexey Dobriyan <adobriyan@gmail.com>
> Date: Tue, 25 Nov 2008 20:26:35 +0300
> 
> > To avoid unnecessary complications with passing netns around.
> > 
> > * set once, very early after allocating
> > * once set, never changes
> > 
> > For a while create every xfrm_state in init_net.
> > 
> > Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
> 
> Applied.
> 
> > @@ -223,6 +226,11 @@ struct xfrm_state
> >  	void			*data;
> >  };
> >  
> > +static inline struct net *xs_net(struct xfrm_state *x)
> > +{
> > +	return read_pnet(&x->xs_net);
> > +}
> > +
> >  /* xflags - make enum if more show up */
> 
> Look mom, no ifdefs!  Amazing!

There're gone and won't return, honey.

In fact, I don't like pnet only a little now and thinking about:

	net = read_net(foo->foo_net);
	write_net(foo->foo_net, net);

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

end of thread, other threads:[~2008-11-26  4:21 UTC | newest]

Thread overview: 107+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-25 17:26 [PATCH 01/53] xfrm: initialise xfrm_policy_gc_work statically Alexey Dobriyan
2008-11-25 17:26 ` [PATCH 02/53] netns xfrm: add netns boilerplate Alexey Dobriyan
2008-11-25 17:26   ` [PATCH 03/53] netns xfrm: add struct xfrm_state::xs_net Alexey Dobriyan
2008-11-25 17:26     ` [PATCH 04/53] netns xfrm: per-netns xfrm_state_all list Alexey Dobriyan
2008-11-25 17:26       ` [PATCH 05/53] netns xfrm: per-netns xfrm_state_bydst hash Alexey Dobriyan
2008-11-25 17:26         ` [PATCH 06/53] netns xfrm: per-netns xfrm_state_bysrc hash Alexey Dobriyan
2008-11-25 17:26           ` [PATCH 07/53] netns xfrm: per-netns xfrm_state_byspi hash Alexey Dobriyan
2008-11-25 17:26             ` [PATCH 08/53] netns xfrm: per-netns xfrm_state_hmask Alexey Dobriyan
2008-11-25 17:26               ` [PATCH 09/53] netns xfrm: per-netns xfrm_state counts Alexey Dobriyan
2008-11-25 17:26                 ` [PATCH 10/53] netns xfrm: per-netns xfrm_hash_work Alexey Dobriyan
2008-11-25 17:26                   ` [PATCH 11/53] netns xfrm: per-netns state GC list Alexey Dobriyan
2008-11-25 17:26                     ` [PATCH 12/53] netns xfrm: per-netns state GC work Alexey Dobriyan
2008-11-25 17:26                       ` [PATCH 13/53] netns xfrm: per-netns km_waitq Alexey Dobriyan
2008-11-25 17:26                         ` [PATCH 14/53] netns xfrm: add struct xfrm_policy::xp_net Alexey Dobriyan
2008-11-25 17:26                           ` [PATCH 15/53] netns xfrm: per-netns policy list Alexey Dobriyan
2008-11-25 17:26                             ` [PATCH 16/53] netns xfrm: per-netns xfrm_policy_byidx hash Alexey Dobriyan
2008-11-25 17:26                               ` [PATCH 17/53] netns xfrm: per-netns xfrm_policy_byidx hashmask Alexey Dobriyan
2008-11-25 17:26                                 ` [PATCH 18/53] netns xfrm: per-netns inexact policies Alexey Dobriyan
2008-11-25 17:26                                   ` [PATCH 19/53] netns xfrm: per-netns xfrm_policy_bydst hash Alexey Dobriyan
2008-11-25 17:26                                     ` [PATCH 20/53] netns xfrm: per-netns policy counts Alexey Dobriyan
2008-11-25 17:26                                       ` [PATCH 21/53] netns xfrm: per-netns policy hash resizing work Alexey Dobriyan
2008-11-25 17:26                                         ` [PATCH 22/53] netns xfrm: propagate netns into bydst/bysrc/byspi hash functions Alexey Dobriyan
2008-11-25 17:26                                           ` [PATCH 23/53] netns xfrm: trivial netns propagations Alexey Dobriyan
2008-11-25 17:26                                             ` [PATCH 24/53] netns xfrm: state flush in netns Alexey Dobriyan
2008-11-25 17:26                                               ` [PATCH 25/53] netns xfrm: state lookup " Alexey Dobriyan
2008-11-25 17:26                                                 ` [PATCH 26/53] netns xfrm: fixup xfrm_alloc_spi() Alexey Dobriyan
2008-11-25 17:26                                                   ` [PATCH 27/53] netns xfrm: finding states in netns Alexey Dobriyan
2008-11-25 17:27                                                     ` [PATCH 28/53] netns xfrm: state walking " Alexey Dobriyan
2008-11-25 17:27                                                       ` [PATCH 29/53] netns xfrm: propagate netns into policy byidx hash Alexey Dobriyan
2008-11-25 17:27                                                         ` [PATCH 30/53] netns xfrm: policy insertion in netns Alexey Dobriyan
2008-11-25 17:27                                                           ` [PATCH 31/53] netns xfrm: policy flushing " Alexey Dobriyan
2008-11-25 17:27                                                             ` [PATCH 32/53] netns xfrm: finding policy " Alexey Dobriyan
2008-11-25 17:27                                                               ` [PATCH 33/53] netns xfrm: policy walking " Alexey Dobriyan
2008-11-25 17:27                                                                 ` [PATCH 34/53] netns xfrm: lookup " Alexey Dobriyan
2008-11-25 17:27                                                                   ` [PATCH 35/53] netns xfrm: xfrm_policy_check " Alexey Dobriyan
2008-11-25 17:27                                                                     ` [PATCH 36/53] netns xfrm: xfrm_route_forward() " Alexey Dobriyan
2008-11-25 17:27                                                                       ` [PATCH 37/53] netns xfrm: flushing/pruning bundles " Alexey Dobriyan
2008-11-25 17:27                                                                         ` [PATCH 38/53] netns xfrm: dst garbage-collecting " Alexey Dobriyan
2008-11-25 17:27                                                                           ` [PATCH 39/53] netns xfrm: xfrm_input() fixup Alexey Dobriyan
2008-11-25 17:27                                                                             ` [PATCH 40/53] netns xfrm: per-netns NETLINK_XFRM socket Alexey Dobriyan
2008-11-25 17:27                                                                               ` [PATCH 41/53] netns xfrm: xfrm_user module in netns Alexey Dobriyan
2008-11-25 17:27                                                                                 ` [PATCH 42/53] netns xfrm: pass netns with KM notifications Alexey Dobriyan
2008-11-25 17:27                                                                                   ` [PATCH 43/53] netns xfrm: KM reporting in netns Alexey Dobriyan
2008-11-25 17:27                                                                                     ` [PATCH 44/53] netns xfrm: ->dst_lookup " Alexey Dobriyan
2008-11-25 17:27                                                                                       ` [PATCH 45/53] netns xfrm: ->get_saddr " Alexey Dobriyan
2008-11-25 17:27                                                                                         ` [PATCH 46/53] netns xfrm: flush SA/SPDs on netns stop Alexey Dobriyan
2008-11-25 17:27                                                                                           ` [PATCH 47/53] netns PF_KEY: part 1 Alexey Dobriyan
2008-11-25 17:27                                                                                             ` [PATCH 48/53] netns PF_KEY: part 2 Alexey Dobriyan
2008-11-25 17:27                                                                                               ` [PATCH 49/53] netns PF_KEY: per-netns /proc/pfkey Alexey Dobriyan
2008-11-25 17:27                                                                                                 ` [PATCH 50/53] netns xfrm: AH/ESP in netns! Alexey Dobriyan
2008-11-25 17:27                                                                                                   ` [PATCH 51/53] netns xfrm: per-netns MIBs Alexey Dobriyan
2008-11-25 17:27                                                                                                     ` [PATCH 52/53] netns xfrm: /proc/net/xfrm_stat in netns Alexey Dobriyan
2008-11-25 17:27                                                                                                       ` [PATCH 53/53] netns xfrm: per-netns sysctls Alexey Dobriyan
2008-11-26  2:00                                                                                                         ` David Miller
2008-11-26  2:00                                                                                                       ` [PATCH 52/53] netns xfrm: /proc/net/xfrm_stat in netns David Miller
2008-11-26  1:59                                                                                                     ` [PATCH 51/53] netns xfrm: per-netns MIBs David Miller
2008-11-26  1:59                                                                                                   ` [PATCH 50/53] netns xfrm: AH/ESP in netns! David Miller
2008-11-26  1:59                                                                                                 ` [PATCH 49/53] netns PF_KEY: per-netns /proc/pfkey David Miller
2008-11-26  1:58                                                                                               ` [PATCH 48/53] netns PF_KEY: part 2 David Miller
2008-11-26  1:58                                                                                             ` [PATCH 47/53] netns PF_KEY: part 1 David Miller
2008-11-26  1:57                                                                                           ` [PATCH 46/53] netns xfrm: flush SA/SPDs on netns stop David Miller
2008-11-26  1:56                                                                                         ` [PATCH 45/53] netns xfrm: ->get_saddr in netns David Miller
2008-11-26  1:51                                                                                       ` [PATCH 44/53] netns xfrm: ->dst_lookup " David Miller
2008-11-26  1:51                                                                                     ` [PATCH 43/53] netns xfrm: KM reporting " David Miller
2008-11-26  1:50                                                                                   ` [PATCH 42/53] netns xfrm: pass netns with KM notifications David Miller
     [not found]                                                                                 ` <1227634045-27534-41-git-send-email-adobriyan-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2008-11-26  1:50                                                                                   ` [PATCH 41/53] netns xfrm: xfrm_user module in netns David Miller
2008-11-26  1:38                                                                               ` [PATCH 40/53] netns xfrm: per-netns NETLINK_XFRM socket David Miller
2008-11-26  1:38                                                                             ` [PATCH 39/53] netns xfrm: xfrm_input() fixup David Miller
2008-11-26  1:37                                                                           ` [PATCH 38/53] netns xfrm: dst garbage-collecting in netns David Miller
2008-11-26  1:36                                                                         ` [PATCH 37/53] netns xfrm: flushing/pruning bundles " David Miller
2008-11-26  1:36                                                                       ` [PATCH 36/53] netns xfrm: xfrm_route_forward() " David Miller
2008-11-26  1:35                                                                     ` [PATCH 35/53] netns xfrm: xfrm_policy_check " David Miller
2008-11-26  1:35                                                                   ` [PATCH 34/53] netns xfrm: lookup " David Miller
2008-11-26  1:34                                                                 ` [PATCH 33/53] netns xfrm: policy walking " David Miller
2008-11-26  1:34                                                               ` [PATCH 32/53] netns xfrm: finding policy " David Miller
2008-11-26  1:33                                                             ` [PATCH 31/53] netns xfrm: policy flushing " David Miller
2008-11-26  1:33                                                           ` [PATCH 30/53] netns xfrm: policy insertion " David Miller
2008-11-26  1:32                                                         ` [PATCH 29/53] netns xfrm: propagate netns into policy byidx hash David Miller
2008-11-26  1:32                                                       ` [PATCH 28/53] netns xfrm: state walking in netns David Miller
2008-11-26  1:31                                                     ` [PATCH 27/53] netns xfrm: finding states " David Miller
2008-11-26  1:31                                                   ` [PATCH 26/53] netns xfrm: fixup xfrm_alloc_spi() David Miller
2008-11-26  1:30                                                 ` [PATCH 25/53] netns xfrm: state lookup in netns David Miller
2008-11-26  1:30                                               ` [PATCH 24/53] netns xfrm: state flush " David Miller
2008-11-26  1:29                                             ` [PATCH 23/53] netns xfrm: trivial netns propagations David Miller
2008-11-26  1:29                                           ` [PATCH 22/53] netns xfrm: propagate netns into bydst/bysrc/byspi hash functions David Miller
2008-11-26  1:29                                         ` [PATCH 21/53] netns xfrm: per-netns policy hash resizing work David Miller
2008-11-26  1:24                                       ` [PATCH 20/53] netns xfrm: per-netns policy counts David Miller
2008-11-26  1:23                                     ` [PATCH 19/53] netns xfrm: per-netns xfrm_policy_bydst hash David Miller
2008-11-26  1:23                                   ` [PATCH 18/53] netns xfrm: per-netns inexact policies David Miller
2008-11-26  1:23                                 ` [PATCH 17/53] netns xfrm: per-netns xfrm_policy_byidx hashmask David Miller
2008-11-26  1:22                               ` [PATCH 16/53] netns xfrm: per-netns xfrm_policy_byidx hash David Miller
2008-11-26  1:22                             ` [PATCH 15/53] netns xfrm: per-netns policy list David Miller
2008-11-26  1:21                           ` [PATCH 14/53] netns xfrm: add struct xfrm_policy::xp_net David Miller
2008-11-26  1:21                         ` [PATCH 13/53] netns xfrm: per-netns km_waitq David Miller
2008-11-26  1:20                       ` [PATCH 12/53] netns xfrm: per-netns state GC work David Miller
2008-11-26  1:20                     ` [PATCH 11/53] netns xfrm: per-netns state GC list David Miller
2008-11-26  1:19                   ` [PATCH 10/53] netns xfrm: per-netns xfrm_hash_work David Miller
2008-11-26  1:18                 ` [PATCH 09/53] netns xfrm: per-netns xfrm_state counts David Miller
2008-11-26  1:18               ` [PATCH 08/53] netns xfrm: per-netns xfrm_state_hmask David Miller
2008-11-26  1:17             ` [PATCH 07/53] netns xfrm: per-netns xfrm_state_byspi hash David Miller
2008-11-26  1:17           ` [PATCH 06/53] netns xfrm: per-netns xfrm_state_bysrc hash David Miller
2008-11-26  1:17         ` [PATCH 05/53] netns xfrm: per-netns xfrm_state_bydst hash David Miller
2008-11-26  1:16       ` [PATCH 04/53] netns xfrm: per-netns xfrm_state_all list David Miller
2008-11-26  1:15     ` [PATCH 03/53] netns xfrm: add struct xfrm_state::xs_net David Miller
2008-11-26  4:25       ` Alexey Dobriyan
2008-11-26  1:14   ` [PATCH 02/53] netns xfrm: add netns boilerplate David Miller
2008-11-26  1:14 ` [PATCH 01/53] xfrm: initialise xfrm_policy_gc_work statically David Miller

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