netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations
@ 2012-12-28  2:36 Gao feng
  2012-12-28  2:36 ` [PATCH 02/19] netfilter: expect: move initial codes out of pernet_operations Gao feng
                   ` (20 more replies)
  0 siblings, 21 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

canqun zhang reported a panic BUG,kernel may panic when
unloading nf_conntrack module.

It's because we reset nf_ct_destroy to NULL when we deal
with init_net,it's too early.Some packets belongs to other
netns still refers to the conntrack.when these packets need
to be freed, kfree_skb will call nf_ct_destroy which is
NULL.

fix this bug by moving the nf_conntrack initialize and cleanup
codes out of the pernet operations,this job should be done
in module_init/exit.We can't use init_net to identify if
it's the right time.

Reported-by: canqun zhang <canqunzhang@gmail.com>
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/net/netfilter/nf_conntrack_core.h | 10 +++-
 net/netfilter/nf_conntrack_core.c         | 99 ++++++++++++-------------------
 net/netfilter/nf_conntrack_standalone.c   | 29 ++++++---
 3 files changed, 67 insertions(+), 71 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index d8f5b9f..ec51a3c 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -25,8 +25,14 @@ extern unsigned int nf_conntrack_in(struct net *net,
 				    unsigned int hooknum,
 				    struct sk_buff *skb);
 
-extern int nf_conntrack_init(struct net *net);
-extern void nf_conntrack_cleanup(struct net *net);
+extern int nf_conntrack_init_net(struct net *net);
+extern void nf_conntrack_cleanup_net(struct net *net);
+
+extern int nf_conntrack_init_start(void);
+extern void nf_conntrack_cleanup_start(void);
+
+extern void nf_conntrack_init_end(void);
+extern void nf_conntrack_cleanup_end(void);
 
 extern int nf_conntrack_proto_init(struct net *net);
 extern void nf_conntrack_proto_fini(struct net *net);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 08cdc71..ffb2463 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1331,18 +1331,23 @@ static int untrack_refs(void)
 	return cnt;
 }
 
-static void nf_conntrack_cleanup_init_net(void)
+void nf_conntrack_cleanup_start(void)
 {
-	while (untrack_refs() > 0)
-		schedule();
-
-#ifdef CONFIG_NF_CONNTRACK_ZONES
-	nf_ct_extend_unregister(&nf_ct_zone_extend);
-#endif
+	RCU_INIT_POINTER(ip_ct_attach, NULL);
 }
 
-static void nf_conntrack_cleanup_net(struct net *net)
+/*
+ * Mishearing the voices in his head, our hero wonders how he's
+ * supposed to kill the mall.
+ */
+void nf_conntrack_cleanup_net(struct net *net)
 {
+	/*
+	 * This makes sure all current packets have passed through
+	 * netfilter framework.  Roll on, two-stage module
+	 * delete...
+	 */
+	synchronize_net();
  i_see_dead_people:
 	nf_ct_iterate_cleanup(net, kill_all, NULL);
 	nf_ct_release_dying_list(net);
@@ -1352,6 +1357,7 @@ static void nf_conntrack_cleanup_net(struct net *net)
 	}
 
 	nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
+	nf_conntrack_proto_fini(net);
 	nf_conntrack_helper_fini(net);
 	nf_conntrack_timeout_fini(net);
 	nf_conntrack_ecache_fini(net);
@@ -1363,24 +1369,15 @@ static void nf_conntrack_cleanup_net(struct net *net)
 	free_percpu(net->ct.stat);
 }
 
-/* Mishearing the voices in his head, our hero wonders how he's
-   supposed to kill the mall. */
-void nf_conntrack_cleanup(struct net *net)
+void nf_conntrack_cleanup_end(void)
 {
-	if (net_eq(net, &init_net))
-		RCU_INIT_POINTER(ip_ct_attach, NULL);
-
-	/* This makes sure all current packets have passed through
-	   netfilter framework.  Roll on, two-stage module
-	   delete... */
-	synchronize_net();
-	nf_conntrack_proto_fini(net);
-	nf_conntrack_cleanup_net(net);
+	RCU_INIT_POINTER(nf_ct_destroy, NULL);
+	while (untrack_refs() > 0)
+		schedule();
 
-	if (net_eq(net, &init_net)) {
-		RCU_INIT_POINTER(nf_ct_destroy, NULL);
-		nf_conntrack_cleanup_init_net();
-	}
+#ifdef CONFIG_NF_CONNTRACK_ZONES
+	nf_ct_extend_unregister(&nf_ct_zone_extend);
+#endif
 }
 
 void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
@@ -1473,7 +1470,7 @@ void nf_ct_untracked_status_or(unsigned long bits)
 }
 EXPORT_SYMBOL_GPL(nf_ct_untracked_status_or);
 
-static int nf_conntrack_init_init_net(void)
+int nf_conntrack_init_start(void)
 {
 	int max_factor = 8;
 	int ret, cpu;
@@ -1527,7 +1524,7 @@ err_extend:
 #define UNCONFIRMED_NULLS_VAL	((1<<30)+0)
 #define DYING_NULLS_VAL		((1<<30)+1)
 
-static int nf_conntrack_init_net(struct net *net)
+int nf_conntrack_init_net(struct net *net)
 {
 	int ret;
 
@@ -1580,7 +1577,12 @@ static int nf_conntrack_init_net(struct net *net)
 	ret = nf_conntrack_helper_init(net);
 	if (ret < 0)
 		goto err_helper;
+	ret = nf_conntrack_proto_init(net);
+	if (ret < 0)
+		goto out_proto;
 	return 0;
+out_proto:
+	nf_conntrack_helper_fini(net);
 err_helper:
 	nf_conntrack_timeout_fini(net);
 err_timeout:
@@ -1603,42 +1605,17 @@ err_stat:
 	return ret;
 }
 
+void nf_conntrack_init_end(void)
+{
+	/* For use by REJECT target */
+	RCU_INIT_POINTER(ip_ct_attach, nf_conntrack_attach);
+	RCU_INIT_POINTER(nf_ct_destroy, destroy_conntrack);
+
+	/* Howto get NAT offsets */
+	RCU_INIT_POINTER(nf_ct_nat_offset, NULL);
+}
+
 s16 (*nf_ct_nat_offset)(const struct nf_conn *ct,
 			enum ip_conntrack_dir dir,
 			u32 seq);
 EXPORT_SYMBOL_GPL(nf_ct_nat_offset);
-
-int nf_conntrack_init(struct net *net)
-{
-	int ret;
-
-	if (net_eq(net, &init_net)) {
-		ret = nf_conntrack_init_init_net();
-		if (ret < 0)
-			goto out_init_net;
-	}
-	ret = nf_conntrack_proto_init(net);
-	if (ret < 0)
-		goto out_proto;
-	ret = nf_conntrack_init_net(net);
-	if (ret < 0)
-		goto out_net;
-
-	if (net_eq(net, &init_net)) {
-		/* For use by REJECT target */
-		RCU_INIT_POINTER(ip_ct_attach, nf_conntrack_attach);
-		RCU_INIT_POINTER(nf_ct_destroy, destroy_conntrack);
-
-		/* Howto get NAT offsets */
-		RCU_INIT_POINTER(nf_ct_nat_offset, NULL);
-	}
-	return 0;
-
-out_net:
-	nf_conntrack_proto_fini(net);
-out_proto:
-	if (net_eq(net, &init_net))
-		nf_conntrack_cleanup_init_net();
-out_init_net:
-	return ret;
-}
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 363285d..00bf93c 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -530,11 +530,11 @@ static void nf_conntrack_standalone_fini_sysctl(struct net *net)
 }
 #endif /* CONFIG_SYSCTL */
 
-static int nf_conntrack_net_init(struct net *net)
+static int nf_conntrack_pernet_init(struct net *net)
 {
 	int ret;
 
-	ret = nf_conntrack_init(net);
+	ret = nf_conntrack_init_net(net);
 	if (ret < 0)
 		goto out_init;
 	ret = nf_conntrack_standalone_init_proc(net);
@@ -550,31 +550,44 @@ static int nf_conntrack_net_init(struct net *net)
 out_sysctl:
 	nf_conntrack_standalone_fini_proc(net);
 out_proc:
-	nf_conntrack_cleanup(net);
+	nf_conntrack_cleanup_net(net);
 out_init:
 	return ret;
 }
 
-static void nf_conntrack_net_exit(struct net *net)
+static void nf_conntrack_pernet_exit(struct net *net)
 {
 	nf_conntrack_standalone_fini_sysctl(net);
 	nf_conntrack_standalone_fini_proc(net);
-	nf_conntrack_cleanup(net);
+	nf_conntrack_cleanup_net(net);
 }
 
 static struct pernet_operations nf_conntrack_net_ops = {
-	.init = nf_conntrack_net_init,
-	.exit = nf_conntrack_net_exit,
+	.init = nf_conntrack_pernet_init,
+	.exit = nf_conntrack_pernet_exit,
 };
 
 static int __init nf_conntrack_standalone_init(void)
 {
-	return register_pernet_subsys(&nf_conntrack_net_ops);
+	int ret = nf_conntrack_init_start();
+	if (ret < 0)
+		goto out_start;
+	ret = register_pernet_subsys(&nf_conntrack_net_ops);
+	if (ret < 0)
+		goto out_pernet;
+	nf_conntrack_init_end();
+	return 0;
+out_pernet:
+	nf_conntrack_cleanup_end();
+out_start:
+	return ret;
 }
 
 static void __exit nf_conntrack_standalone_fini(void)
 {
+	nf_conntrack_cleanup_start();
 	unregister_pernet_subsys(&nf_conntrack_net_ops);
+	nf_conntrack_cleanup_end();
 }
 
 module_init(nf_conntrack_standalone_init);
-- 
1.7.11.7

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

* [PATCH 02/19] netfilter: expect: move initial codes out of pernet_operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 03/19] netfilter: acct: " Gao feng
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Move the global initial codes to the module_init/exit context.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/net/netfilter/nf_conntrack_expect.h |  7 ++--
 net/netfilter/nf_conntrack_core.c           | 14 ++++++--
 net/netfilter/nf_conntrack_expect.c         | 52 ++++++++++++++---------------
 3 files changed, 41 insertions(+), 32 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h
index cc13f37..cbbae76 100644
--- a/include/net/netfilter/nf_conntrack_expect.h
+++ b/include/net/netfilter/nf_conntrack_expect.h
@@ -69,8 +69,11 @@ struct nf_conntrack_expect_policy {
 
 #define NF_CT_EXPECT_CLASS_DEFAULT	0
 
-int nf_conntrack_expect_init(struct net *net);
-void nf_conntrack_expect_fini(struct net *net);
+int nf_conntrack_expect_pernet_init(struct net *net);
+void nf_conntrack_expect_pernet_fini(struct net *net);
+
+int nf_conntrack_expect_init(void);
+void nf_conntrack_expect_fini(void);
 
 struct nf_conntrack_expect *
 __nf_ct_expect_find(struct net *net, u16 zone,
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index ffb2463..96b281f 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1363,7 +1363,7 @@ void nf_conntrack_cleanup_net(struct net *net)
 	nf_conntrack_ecache_fini(net);
 	nf_conntrack_tstamp_fini(net);
 	nf_conntrack_acct_fini(net);
-	nf_conntrack_expect_fini(net);
+	nf_conntrack_expect_pernet_fini(net);
 	kmem_cache_destroy(net->ct.nf_conntrack_cachep);
 	kfree(net->ct.slabname);
 	free_percpu(net->ct.stat);
@@ -1378,6 +1378,7 @@ void nf_conntrack_cleanup_end(void)
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 	nf_ct_extend_unregister(&nf_ct_zone_extend);
 #endif
+	nf_conntrack_expect_fini();
 }
 
 void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
@@ -1497,6 +1498,11 @@ int nf_conntrack_init_start(void)
 	printk(KERN_INFO "nf_conntrack version %s (%u buckets, %d max)\n",
 	       NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
 	       nf_conntrack_max);
+
+	ret = nf_conntrack_expect_init();
+	if (ret < 0)
+		goto err_expect;
+
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 	ret = nf_ct_extend_register(&nf_ct_zone_extend);
 	if (ret < 0)
@@ -1514,7 +1520,9 @@ int nf_conntrack_init_start(void)
 
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 err_extend:
+	nf_conntrack_expect_fini();
 #endif
+err_expect:
 	return ret;
 }
 
@@ -1559,7 +1567,7 @@ int nf_conntrack_init_net(struct net *net)
 		printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
 		goto err_hash;
 	}
-	ret = nf_conntrack_expect_init(net);
+	ret = nf_conntrack_expect_pernet_init(net);
 	if (ret < 0)
 		goto err_expect;
 	ret = nf_conntrack_acct_init(net);
@@ -1592,7 +1600,7 @@ err_ecache:
 err_tstamp:
 	nf_conntrack_acct_fini(net);
 err_acct:
-	nf_conntrack_expect_fini(net);
+	nf_conntrack_expect_pernet_fini(net);
 err_expect:
 	nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
 err_hash:
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 527651a..0557acc 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -587,53 +587,51 @@ static void exp_proc_remove(struct net *net)
 
 module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0400);
 
-int nf_conntrack_expect_init(struct net *net)
+int nf_conntrack_expect_pernet_init(struct net *net)
 {
 	int err = -ENOMEM;
 
-	if (net_eq(net, &init_net)) {
-		if (!nf_ct_expect_hsize) {
-			nf_ct_expect_hsize = net->ct.htable_size / 256;
-			if (!nf_ct_expect_hsize)
-				nf_ct_expect_hsize = 1;
-		}
-		nf_ct_expect_max = nf_ct_expect_hsize * 4;
-	}
-
 	net->ct.expect_count = 0;
 	net->ct.expect_hash = nf_ct_alloc_hashtable(&nf_ct_expect_hsize, 0);
 	if (net->ct.expect_hash == NULL)
 		goto err1;
 
-	if (net_eq(net, &init_net)) {
-		nf_ct_expect_cachep = kmem_cache_create("nf_conntrack_expect",
-					sizeof(struct nf_conntrack_expect),
-					0, 0, NULL);
-		if (!nf_ct_expect_cachep)
-			goto err2;
-	}
-
 	err = exp_proc_init(net);
 	if (err < 0)
-		goto err3;
+		goto err2;
 
 	return 0;
 
-err3:
-	if (net_eq(net, &init_net))
-		kmem_cache_destroy(nf_ct_expect_cachep);
 err2:
 	nf_ct_free_hashtable(net->ct.expect_hash, nf_ct_expect_hsize);
 err1:
 	return err;
 }
 
-void nf_conntrack_expect_fini(struct net *net)
+void nf_conntrack_expect_pernet_fini(struct net *net)
 {
 	exp_proc_remove(net);
-	if (net_eq(net, &init_net)) {
-		rcu_barrier(); /* Wait for call_rcu() before destroy */
-		kmem_cache_destroy(nf_ct_expect_cachep);
-	}
 	nf_ct_free_hashtable(net->ct.expect_hash, nf_ct_expect_hsize);
 }
+
+int nf_conntrack_expect_init(void)
+{
+	if (!nf_ct_expect_hsize) {
+		nf_ct_expect_hsize = nf_conntrack_htable_size / 256;
+		if (!nf_ct_expect_hsize)
+			nf_ct_expect_hsize = 1;
+	}
+	nf_ct_expect_max = nf_ct_expect_hsize * 4;
+	nf_ct_expect_cachep = kmem_cache_create("nf_conntrack_expect",
+				sizeof(struct nf_conntrack_expect),
+				0, 0, NULL);
+	if (!nf_ct_expect_cachep)
+		return -ENOMEM;
+	return 0;
+}
+
+void nf_conntrack_expect_fini(void)
+{
+	rcu_barrier(); /* Wait for call_rcu() before destroy */
+	kmem_cache_destroy(nf_ct_expect_cachep);
+}
-- 
1.7.11.7

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

* [PATCH 03/19] netfilter: acct: move initial codes out of pernet_operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
  2012-12-28  2:36 ` [PATCH 02/19] netfilter: expect: move initial codes out of pernet_operations Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 04/19] netfilter: tstamp: " Gao feng
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Move the global initial codes to the module_init/exit context.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/net/netfilter/nf_conntrack_acct.h |  6 +++--
 net/netfilter/nf_conntrack_acct.c         | 37 ++++++++++++-------------------
 net/netfilter/nf_conntrack_core.c         | 15 +++++++++----
 3 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack_acct.h b/include/net/netfilter/nf_conntrack_acct.h
index 463ae8e..2bdb7a1 100644
--- a/include/net/netfilter/nf_conntrack_acct.h
+++ b/include/net/netfilter/nf_conntrack_acct.h
@@ -57,7 +57,9 @@ static inline void nf_ct_set_acct(struct net *net, bool enable)
 	net->ct.sysctl_acct = enable;
 }
 
-extern int nf_conntrack_acct_init(struct net *net);
-extern void nf_conntrack_acct_fini(struct net *net);
+extern int nf_conntrack_acct_pernet_init(struct net *net);
+extern void nf_conntrack_acct_pernet_fini(struct net *net);
 
+extern int nf_conntrack_acct_init(void);
+extern void nf_conntrack_acct_fini(void);
 #endif /* _NF_CONNTRACK_ACCT_H */
diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c
index 7df424e..8138555 100644
--- a/net/netfilter/nf_conntrack_acct.c
+++ b/net/netfilter/nf_conntrack_acct.c
@@ -106,36 +106,27 @@ static void nf_conntrack_acct_fini_sysctl(struct net *net)
 }
 #endif
 
-int nf_conntrack_acct_init(struct net *net)
+int nf_conntrack_acct_pernet_init(struct net *net)
 {
-	int ret;
-
 	net->ct.sysctl_acct = nf_ct_acct;
 
-	if (net_eq(net, &init_net)) {
-		ret = nf_ct_extend_register(&acct_extend);
-		if (ret < 0) {
-			printk(KERN_ERR "nf_conntrack_acct: Unable to register extension\n");
-			goto out_extend_register;
-		}
-	}
-
-	ret = nf_conntrack_acct_init_sysctl(net);
-	if (ret < 0)
-		goto out_sysctl;
+	return nf_conntrack_acct_init_sysctl(net);
+}
 
-	return 0;
+void nf_conntrack_acct_pernet_fini(struct net *net)
+{
+	nf_conntrack_acct_fini_sysctl(net);
+}
 
-out_sysctl:
-	if (net_eq(net, &init_net))
-		nf_ct_extend_unregister(&acct_extend);
-out_extend_register:
+int nf_conntrack_acct_init(void)
+{
+	int ret = nf_ct_extend_register(&acct_extend);
+	if (ret < 0)
+		pr_err("nf_conntrack_acct: Unable to register extension\n");
 	return ret;
 }
 
-void nf_conntrack_acct_fini(struct net *net)
+void nf_conntrack_acct_fini(void)
 {
-	nf_conntrack_acct_fini_sysctl(net);
-	if (net_eq(net, &init_net))
-		nf_ct_extend_unregister(&acct_extend);
+	nf_ct_extend_unregister(&acct_extend);
 }
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 96b281f..feb08d0 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1362,7 +1362,7 @@ void nf_conntrack_cleanup_net(struct net *net)
 	nf_conntrack_timeout_fini(net);
 	nf_conntrack_ecache_fini(net);
 	nf_conntrack_tstamp_fini(net);
-	nf_conntrack_acct_fini(net);
+	nf_conntrack_acct_pernet_fini(net);
 	nf_conntrack_expect_pernet_fini(net);
 	kmem_cache_destroy(net->ct.nf_conntrack_cachep);
 	kfree(net->ct.slabname);
@@ -1378,6 +1378,7 @@ void nf_conntrack_cleanup_end(void)
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 	nf_ct_extend_unregister(&nf_ct_zone_extend);
 #endif
+	nf_conntrack_acct_fini();
 	nf_conntrack_expect_fini();
 }
 
@@ -1503,6 +1504,10 @@ int nf_conntrack_init_start(void)
 	if (ret < 0)
 		goto err_expect;
 
+	ret = nf_conntrack_acct_init();
+	if (ret < 0)
+		goto err_acct;
+
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 	ret = nf_ct_extend_register(&nf_ct_zone_extend);
 	if (ret < 0)
@@ -1520,8 +1525,10 @@ int nf_conntrack_init_start(void)
 
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 err_extend:
-	nf_conntrack_expect_fini();
+	nf_conntrack_acct_fini();
 #endif
+err_acct:
+	nf_conntrack_expect_fini();
 err_expect:
 	return ret;
 }
@@ -1570,7 +1577,7 @@ int nf_conntrack_init_net(struct net *net)
 	ret = nf_conntrack_expect_pernet_init(net);
 	if (ret < 0)
 		goto err_expect;
-	ret = nf_conntrack_acct_init(net);
+	ret = nf_conntrack_acct_pernet_init(net);
 	if (ret < 0)
 		goto err_acct;
 	ret = nf_conntrack_tstamp_init(net);
@@ -1598,7 +1605,7 @@ err_timeout:
 err_ecache:
 	nf_conntrack_tstamp_fini(net);
 err_tstamp:
-	nf_conntrack_acct_fini(net);
+	nf_conntrack_acct_pernet_fini(net);
 err_acct:
 	nf_conntrack_expect_pernet_fini(net);
 err_expect:
-- 
1.7.11.7

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

* [PATCH 04/19] netfilter: tstamp: move initial codes out of pernet_operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
  2012-12-28  2:36 ` [PATCH 02/19] netfilter: expect: move initial codes out of pernet_operations Gao feng
  2012-12-28  2:36 ` [PATCH 03/19] netfilter: acct: " Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 05/19] netfilter: ecache: " Gao feng
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Move the global initial codes to the module_init/exit context.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/net/netfilter/nf_conntrack_timestamp.h | 21 ++++++++++++---
 net/netfilter/nf_conntrack_core.c              | 15 ++++++++---
 net/netfilter/nf_conntrack_timestamp.c         | 37 +++++++++-----------------
 3 files changed, 41 insertions(+), 32 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack_timestamp.h b/include/net/netfilter/nf_conntrack_timestamp.h
index fc9c82b..b004614 100644
--- a/include/net/netfilter/nf_conntrack_timestamp.h
+++ b/include/net/netfilter/nf_conntrack_timestamp.h
@@ -48,15 +48,28 @@ static inline void nf_ct_set_tstamp(struct net *net, bool enable)
 }
 
 #ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
-extern int nf_conntrack_tstamp_init(struct net *net);
-extern void nf_conntrack_tstamp_fini(struct net *net);
+extern int nf_conntrack_tstamp_pernet_init(struct net *net);
+extern void nf_conntrack_tstamp_pernet_fini(struct net *net);
+
+extern int nf_conntrack_tstamp_init(void);
+extern void nf_conntrack_tstamp_fini(void);
 #else
-static inline int nf_conntrack_tstamp_init(struct net *net)
+static inline int nf_conntrack_tstamp_pernet_init(struct net *net)
+{
+	return 0;
+}
+
+static inline void nf_conntrack_tstamp_pernet_fini(struct net *net)
+{
+	return;
+}
+
+static inline int nf_conntrack_tstamp_init(void)
 {
 	return 0;
 }
 
-static inline void nf_conntrack_tstamp_fini(struct net *net)
+static inline void nf_conntrack_tstamp_fini(void)
 {
 	return;
 }
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index feb08d0..b8fb65a 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1361,7 +1361,7 @@ void nf_conntrack_cleanup_net(struct net *net)
 	nf_conntrack_helper_fini(net);
 	nf_conntrack_timeout_fini(net);
 	nf_conntrack_ecache_fini(net);
-	nf_conntrack_tstamp_fini(net);
+	nf_conntrack_tstamp_pernet_fini(net);
 	nf_conntrack_acct_pernet_fini(net);
 	nf_conntrack_expect_pernet_fini(net);
 	kmem_cache_destroy(net->ct.nf_conntrack_cachep);
@@ -1378,6 +1378,7 @@ void nf_conntrack_cleanup_end(void)
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 	nf_ct_extend_unregister(&nf_ct_zone_extend);
 #endif
+	nf_conntrack_tstamp_fini();
 	nf_conntrack_acct_fini();
 	nf_conntrack_expect_fini();
 }
@@ -1508,6 +1509,10 @@ int nf_conntrack_init_start(void)
 	if (ret < 0)
 		goto err_acct;
 
+	ret = nf_conntrack_tstamp_init();
+	if (ret < 0)
+		goto err_tstamp;
+
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 	ret = nf_ct_extend_register(&nf_ct_zone_extend);
 	if (ret < 0)
@@ -1525,8 +1530,10 @@ int nf_conntrack_init_start(void)
 
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 err_extend:
-	nf_conntrack_acct_fini();
+	nf_conntrack_tstamp_fini();
 #endif
+err_tstamp:
+	nf_conntrack_acct_fini();
 err_acct:
 	nf_conntrack_expect_fini();
 err_expect:
@@ -1580,7 +1587,7 @@ int nf_conntrack_init_net(struct net *net)
 	ret = nf_conntrack_acct_pernet_init(net);
 	if (ret < 0)
 		goto err_acct;
-	ret = nf_conntrack_tstamp_init(net);
+	ret = nf_conntrack_tstamp_pernet_init(net);
 	if (ret < 0)
 		goto err_tstamp;
 	ret = nf_conntrack_ecache_init(net);
@@ -1603,7 +1610,7 @@ err_helper:
 err_timeout:
 	nf_conntrack_ecache_fini(net);
 err_ecache:
-	nf_conntrack_tstamp_fini(net);
+	nf_conntrack_tstamp_pernet_fini(net);
 err_tstamp:
 	nf_conntrack_acct_pernet_fini(net);
 err_acct:
diff --git a/net/netfilter/nf_conntrack_timestamp.c b/net/netfilter/nf_conntrack_timestamp.c
index 7ea8026..2df0135 100644
--- a/net/netfilter/nf_conntrack_timestamp.c
+++ b/net/netfilter/nf_conntrack_timestamp.c
@@ -88,37 +88,26 @@ static void nf_conntrack_tstamp_fini_sysctl(struct net *net)
 }
 #endif
 
-int nf_conntrack_tstamp_init(struct net *net)
+int nf_conntrack_tstamp_pernet_init(struct net *net)
 {
-	int ret;
-
 	net->ct.sysctl_tstamp = nf_ct_tstamp;
+	return nf_conntrack_tstamp_init_sysctl(net);
+}
 
-	if (net_eq(net, &init_net)) {
-		ret = nf_ct_extend_register(&tstamp_extend);
-		if (ret < 0) {
-			printk(KERN_ERR "nf_ct_tstamp: Unable to register "
-					"extension\n");
-			goto out_extend_register;
-		}
-	}
+void nf_conntrack_tstamp_pernet_fini(struct net *net)
+{
+	nf_conntrack_tstamp_fini_sysctl(net);
+}
 
-	ret = nf_conntrack_tstamp_init_sysctl(net);
+int nf_conntrack_tstamp_init(void)
+{
+	int ret = nf_ct_extend_register(&tstamp_extend);
 	if (ret < 0)
-		goto out_sysctl;
-
-	return 0;
-
-out_sysctl:
-	if (net_eq(net, &init_net))
-		nf_ct_extend_unregister(&tstamp_extend);
-out_extend_register:
+		pr_err("nf_ct_tstamp: Unable to register extension\n");
 	return ret;
 }
 
-void nf_conntrack_tstamp_fini(struct net *net)
+void nf_conntrack_tstamp_fini(void)
 {
-	nf_conntrack_tstamp_fini_sysctl(net);
-	if (net_eq(net, &init_net))
-		nf_ct_extend_unregister(&tstamp_extend);
+	nf_ct_extend_unregister(&tstamp_extend);
 }
-- 
1.7.11.7

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

* [PATCH 05/19] netfilter: ecache: move initial codes out of pernet_operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (2 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 04/19] netfilter: tstamp: " Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 06/19] netfilter: timeout: " Gao feng
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Move the global initial codes to the module_init/exit context.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/net/netfilter/nf_conntrack_ecache.h | 19 +++++++++++----
 net/netfilter/nf_conntrack_core.c           | 14 +++++++----
 net/netfilter/nf_conntrack_ecache.c         | 37 ++++++++++-------------------
 3 files changed, 38 insertions(+), 32 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h
index 5654d29..092dc65 100644
--- a/include/net/netfilter/nf_conntrack_ecache.h
+++ b/include/net/netfilter/nf_conntrack_ecache.h
@@ -207,9 +207,11 @@ nf_ct_expect_event(enum ip_conntrack_expect_events event,
 	nf_ct_expect_event_report(event, exp, 0, 0);
 }
 
-extern int nf_conntrack_ecache_init(struct net *net);
-extern void nf_conntrack_ecache_fini(struct net *net);
+extern int nf_conntrack_ecache_pernet_init(struct net *net);
+extern void nf_conntrack_ecache_pernet_fini(struct net *net);
 
+extern int nf_conntrack_ecache_init(void);
+extern void nf_conntrack_ecache_fini(void);
 #else /* CONFIG_NF_CONNTRACK_EVENTS */
 
 static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
@@ -232,12 +234,21 @@ static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e,
  					     u32 portid,
  					     int report) {}
 
-static inline int nf_conntrack_ecache_init(struct net *net)
+static inline int nf_conntrack_ecache_pernet_init(struct net *net)
 {
 	return 0;
 }
 
-static inline void nf_conntrack_ecache_fini(struct net *net)
+static inline void nf_conntrack_ecache_pernet_fini(struct net *net)
+{
+}
+
+static inline int nf_conntrack_ecache_init(void)
+{
+	return 0;
+}
+
+static inline void nf_conntrack_ecache_fini(void)
 {
 }
 #endif /* CONFIG_NF_CONNTRACK_EVENTS */
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index b8fb65a..b34bc9a 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1360,7 +1360,7 @@ void nf_conntrack_cleanup_net(struct net *net)
 	nf_conntrack_proto_fini(net);
 	nf_conntrack_helper_fini(net);
 	nf_conntrack_timeout_fini(net);
-	nf_conntrack_ecache_fini(net);
+	nf_conntrack_ecache_pernet_fini(net);
 	nf_conntrack_tstamp_pernet_fini(net);
 	nf_conntrack_acct_pernet_fini(net);
 	nf_conntrack_expect_pernet_fini(net);
@@ -1378,6 +1378,7 @@ void nf_conntrack_cleanup_end(void)
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 	nf_ct_extend_unregister(&nf_ct_zone_extend);
 #endif
+	nf_conntrack_ecache_fini();
 	nf_conntrack_tstamp_fini();
 	nf_conntrack_acct_fini();
 	nf_conntrack_expect_fini();
@@ -1512,6 +1513,9 @@ int nf_conntrack_init_start(void)
 	ret = nf_conntrack_tstamp_init();
 	if (ret < 0)
 		goto err_tstamp;
+	ret = nf_conntrack_ecache_init();
+	if (ret < 0)
+		goto err_ecache;
 
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 	ret = nf_ct_extend_register(&nf_ct_zone_extend);
@@ -1530,8 +1534,10 @@ int nf_conntrack_init_start(void)
 
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 err_extend:
-	nf_conntrack_tstamp_fini();
+	nf_conntrack_ecache_fini();
 #endif
+err_ecache:
+	nf_conntrack_tstamp_fini();
 err_tstamp:
 	nf_conntrack_acct_fini();
 err_acct:
@@ -1590,7 +1596,7 @@ int nf_conntrack_init_net(struct net *net)
 	ret = nf_conntrack_tstamp_pernet_init(net);
 	if (ret < 0)
 		goto err_tstamp;
-	ret = nf_conntrack_ecache_init(net);
+	ret = nf_conntrack_ecache_pernet_init(net);
 	if (ret < 0)
 		goto err_ecache;
 	ret = nf_conntrack_timeout_init(net);
@@ -1608,7 +1614,7 @@ out_proto:
 err_helper:
 	nf_conntrack_timeout_fini(net);
 err_timeout:
-	nf_conntrack_ecache_fini(net);
+	nf_conntrack_ecache_pernet_fini(net);
 err_ecache:
 	nf_conntrack_tstamp_pernet_fini(net);
 err_tstamp:
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index faa978f..b5d2eb8 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -233,38 +233,27 @@ static void nf_conntrack_event_fini_sysctl(struct net *net)
 }
 #endif /* CONFIG_SYSCTL */
 
-int nf_conntrack_ecache_init(struct net *net)
+int nf_conntrack_ecache_pernet_init(struct net *net)
 {
-	int ret;
-
 	net->ct.sysctl_events = nf_ct_events;
 	net->ct.sysctl_events_retry_timeout = nf_ct_events_retry_timeout;
+	return nf_conntrack_event_init_sysctl(net);
+}
 
-	if (net_eq(net, &init_net)) {
-		ret = nf_ct_extend_register(&event_extend);
-		if (ret < 0) {
-			printk(KERN_ERR "nf_ct_event: Unable to register "
-					"event extension.\n");
-			goto out_extend_register;
-		}
-	}
+void nf_conntrack_ecache_pernet_fini(struct net *net)
+{
+	nf_conntrack_event_fini_sysctl(net);
+}
 
-	ret = nf_conntrack_event_init_sysctl(net);
+int nf_conntrack_ecache_init(void)
+{
+	int ret = nf_ct_extend_register(&event_extend);
 	if (ret < 0)
-		goto out_sysctl;
-
-	return 0;
-
-out_sysctl:
-	if (net_eq(net, &init_net))
-		nf_ct_extend_unregister(&event_extend);
-out_extend_register:
+		pr_err("nf_ct_event: Unable to register event extension.\n");
 	return ret;
 }
 
-void nf_conntrack_ecache_fini(struct net *net)
+void nf_conntrack_ecache_fini(void)
 {
-	nf_conntrack_event_fini_sysctl(net);
-	if (net_eq(net, &init_net))
-		nf_ct_extend_unregister(&event_extend);
+	nf_ct_extend_unregister(&event_extend);
 }
-- 
1.7.11.7

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

* [PATCH 06/19] netfilter: timeout: move initial codes out of pernet_operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (3 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 05/19] netfilter: ecache: " Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 07/19] netfilter: helper: " Gao feng
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Move the global initial codes to the module_init/exit context.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/net/netfilter/nf_conntrack_timeout.h |  8 ++++----
 net/netfilter/nf_conntrack_core.c            | 15 ++++++++-------
 net/netfilter/nf_conntrack_timeout.c         | 23 +++++++----------------
 3 files changed, 19 insertions(+), 27 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack_timeout.h b/include/net/netfilter/nf_conntrack_timeout.h
index e41e472..d23aceb 100644
--- a/include/net/netfilter/nf_conntrack_timeout.h
+++ b/include/net/netfilter/nf_conntrack_timeout.h
@@ -76,15 +76,15 @@ nf_ct_timeout_lookup(struct net *net, struct nf_conn *ct,
 }
 
 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
-extern int nf_conntrack_timeout_init(struct net *net);
-extern void nf_conntrack_timeout_fini(struct net *net);
+extern int nf_conntrack_timeout_init(void);
+extern void nf_conntrack_timeout_fini(void);
 #else
-static inline int nf_conntrack_timeout_init(struct net *net)
+static inline int nf_conntrack_timeout_init(void)
 {
         return 0;
 }
 
-static inline void nf_conntrack_timeout_fini(struct net *net)
+static inline void nf_conntrack_timeout_fini(void)
 {
         return;
 }
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index b34bc9a..a9a23c4 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1359,7 +1359,6 @@ void nf_conntrack_cleanup_net(struct net *net)
 	nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
 	nf_conntrack_proto_fini(net);
 	nf_conntrack_helper_fini(net);
-	nf_conntrack_timeout_fini(net);
 	nf_conntrack_ecache_pernet_fini(net);
 	nf_conntrack_tstamp_pernet_fini(net);
 	nf_conntrack_acct_pernet_fini(net);
@@ -1378,6 +1377,7 @@ void nf_conntrack_cleanup_end(void)
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 	nf_ct_extend_unregister(&nf_ct_zone_extend);
 #endif
+	nf_conntrack_timeout_fini();
 	nf_conntrack_ecache_fini();
 	nf_conntrack_tstamp_fini();
 	nf_conntrack_acct_fini();
@@ -1517,6 +1517,10 @@ int nf_conntrack_init_start(void)
 	if (ret < 0)
 		goto err_ecache;
 
+	ret = nf_conntrack_timeout_init();
+	if (ret < 0)
+		goto err_timeout;
+
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 	ret = nf_ct_extend_register(&nf_ct_zone_extend);
 	if (ret < 0)
@@ -1534,8 +1538,10 @@ int nf_conntrack_init_start(void)
 
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 err_extend:
-	nf_conntrack_ecache_fini();
+	nf_conntrack_timeout_fini();
 #endif
+err_timeout:
+	nf_conntrack_ecache_fini();
 err_ecache:
 	nf_conntrack_tstamp_fini();
 err_tstamp:
@@ -1599,9 +1605,6 @@ int nf_conntrack_init_net(struct net *net)
 	ret = nf_conntrack_ecache_pernet_init(net);
 	if (ret < 0)
 		goto err_ecache;
-	ret = nf_conntrack_timeout_init(net);
-	if (ret < 0)
-		goto err_timeout;
 	ret = nf_conntrack_helper_init(net);
 	if (ret < 0)
 		goto err_helper;
@@ -1612,8 +1615,6 @@ int nf_conntrack_init_net(struct net *net)
 out_proto:
 	nf_conntrack_helper_fini(net);
 err_helper:
-	nf_conntrack_timeout_fini(net);
-err_timeout:
 	nf_conntrack_ecache_pernet_fini(net);
 err_ecache:
 	nf_conntrack_tstamp_pernet_fini(net);
diff --git a/net/netfilter/nf_conntrack_timeout.c b/net/netfilter/nf_conntrack_timeout.c
index a878ce5..93da609 100644
--- a/net/netfilter/nf_conntrack_timeout.c
+++ b/net/netfilter/nf_conntrack_timeout.c
@@ -37,24 +37,15 @@ static struct nf_ct_ext_type timeout_extend __read_mostly = {
 	.id	= NF_CT_EXT_TIMEOUT,
 };
 
-int nf_conntrack_timeout_init(struct net *net)
+int nf_conntrack_timeout_init(void)
 {
-	int ret = 0;
-
-	if (net_eq(net, &init_net)) {
-		ret = nf_ct_extend_register(&timeout_extend);
-		if (ret < 0) {
-			printk(KERN_ERR "nf_ct_timeout: Unable to register "
-					"timeout extension.\n");
-			return ret;
-		}
-	}
-
-	return 0;
+	int ret = nf_ct_extend_register(&timeout_extend);
+	if (ret < 0)
+		pr_err("nf_ct_timeout: Unable to register timeout extension.\n");
+	return ret;
 }
 
-void nf_conntrack_timeout_fini(struct net *net)
+void nf_conntrack_timeout_fini(void)
 {
-	if (net_eq(net, &init_net))
-		nf_ct_extend_unregister(&timeout_extend);
+	nf_ct_extend_unregister(&timeout_extend);
 }
-- 
1.7.11.7

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

* [PATCH 07/19] netfilter: helper: move initial codes out of pernet_operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (4 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 06/19] netfilter: timeout: " Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 08/19] netfilter: proto: " Gao feng
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Move the global initial codes to the module_init/exit context.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/net/netfilter/nf_conntrack_helper.h |  7 ++--
 net/netfilter/nf_conntrack_core.c           | 15 +++++---
 net/netfilter/nf_conntrack_helper.c         | 53 ++++++++++++++---------------
 3 files changed, 41 insertions(+), 34 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index 9aad956..ce27edf 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -82,8 +82,11 @@ static inline void *nfct_help_data(const struct nf_conn *ct)
 	return (void *)help->data;
 }
 
-extern int nf_conntrack_helper_init(struct net *net);
-extern void nf_conntrack_helper_fini(struct net *net);
+extern int nf_conntrack_helper_pernet_init(struct net *net);
+extern void nf_conntrack_helper_pernet_fini(struct net *net);
+
+extern int nf_conntrack_helper_init(void);
+extern void nf_conntrack_helper_fini(void);
 
 extern int nf_conntrack_broadcast_help(struct sk_buff *skb,
 				       unsigned int protoff,
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index a9a23c4..06ed86f 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1358,7 +1358,7 @@ void nf_conntrack_cleanup_net(struct net *net)
 
 	nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
 	nf_conntrack_proto_fini(net);
-	nf_conntrack_helper_fini(net);
+	nf_conntrack_helper_pernet_fini(net);
 	nf_conntrack_ecache_pernet_fini(net);
 	nf_conntrack_tstamp_pernet_fini(net);
 	nf_conntrack_acct_pernet_fini(net);
@@ -1377,6 +1377,7 @@ void nf_conntrack_cleanup_end(void)
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 	nf_ct_extend_unregister(&nf_ct_zone_extend);
 #endif
+	nf_conntrack_helper_fini();
 	nf_conntrack_timeout_fini();
 	nf_conntrack_ecache_fini();
 	nf_conntrack_tstamp_fini();
@@ -1521,6 +1522,10 @@ int nf_conntrack_init_start(void)
 	if (ret < 0)
 		goto err_timeout;
 
+	ret = nf_conntrack_helper_init();
+	if (ret < 0)
+		goto err_helper;
+
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 	ret = nf_ct_extend_register(&nf_ct_zone_extend);
 	if (ret < 0)
@@ -1538,8 +1543,10 @@ int nf_conntrack_init_start(void)
 
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 err_extend:
-	nf_conntrack_timeout_fini();
+	nf_conntrack_helper_fini();
 #endif
+err_helper:
+	nf_conntrack_timeout_fini();
 err_timeout:
 	nf_conntrack_ecache_fini();
 err_ecache:
@@ -1605,7 +1612,7 @@ int nf_conntrack_init_net(struct net *net)
 	ret = nf_conntrack_ecache_pernet_init(net);
 	if (ret < 0)
 		goto err_ecache;
-	ret = nf_conntrack_helper_init(net);
+	ret = nf_conntrack_helper_pernet_init(net);
 	if (ret < 0)
 		goto err_helper;
 	ret = nf_conntrack_proto_init(net);
@@ -1613,7 +1620,7 @@ int nf_conntrack_init_net(struct net *net)
 		goto out_proto;
 	return 0;
 out_proto:
-	nf_conntrack_helper_fini(net);
+	nf_conntrack_helper_pernet_fini(net);
 err_helper:
 	nf_conntrack_ecache_pernet_fini(net);
 err_ecache:
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 884f2b3..ad4c747 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -423,44 +423,41 @@ static struct nf_ct_ext_type helper_extend __read_mostly = {
 	.id	= NF_CT_EXT_HELPER,
 };
 
-int nf_conntrack_helper_init(struct net *net)
+int nf_conntrack_helper_pernet_init(struct net *net)
 {
-	int err;
-
 	net->ct.auto_assign_helper_warned = false;
 	net->ct.sysctl_auto_assign_helper = nf_ct_auto_assign_helper;
+	return nf_conntrack_helper_init_sysctl(net);
+}
 
-	if (net_eq(net, &init_net)) {
-		nf_ct_helper_hsize = 1; /* gets rounded up to use one page */
-		nf_ct_helper_hash =
-			nf_ct_alloc_hashtable(&nf_ct_helper_hsize, 0);
-		if (!nf_ct_helper_hash)
-			return -ENOMEM;
+void nf_conntrack_helper_pernet_fini(struct net *net)
+{
+	nf_conntrack_helper_fini_sysctl(net);
+}
 
-		err = nf_ct_extend_register(&helper_extend);
-		if (err < 0)
-			goto err1;
+int nf_conntrack_helper_init(void)
+{
+	int ret;
+	nf_ct_helper_hsize = 1; /* gets rounded up to use one page */
+	nf_ct_helper_hash =
+		nf_ct_alloc_hashtable(&nf_ct_helper_hsize, 0);
+	if (!nf_ct_helper_hash)
+		return -ENOMEM;
+
+	ret = nf_ct_extend_register(&helper_extend);
+	if (ret < 0) {
+		pr_err("nf_ct_helper: Unable to register helper extension.\n");
+		goto out_extend;
 	}
-
-	err = nf_conntrack_helper_init_sysctl(net);
-	if (err < 0)
-		goto out_sysctl;
-
 	return 0;
 
-out_sysctl:
-	if (net_eq(net, &init_net))
-		nf_ct_extend_unregister(&helper_extend);
-err1:
+out_extend:
 	nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_hsize);
-	return err;
+	return ret;
 }
 
-void nf_conntrack_helper_fini(struct net *net)
+void nf_conntrack_helper_fini(void)
 {
-	nf_conntrack_helper_fini_sysctl(net);
-	if (net_eq(net, &init_net)) {
-		nf_ct_extend_unregister(&helper_extend);
-		nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_hsize);
-	}
+	nf_ct_extend_unregister(&helper_extend);
+	nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_hsize);
 }
-- 
1.7.11.7

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

* [PATCH 08/19] netfilter: proto: move initial codes out of pernet_operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (5 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 07/19] netfilter: helper: " Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 09/19] netfilter: l3proto: prepare reworking l3proto support for netns Gao feng
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Move the global initial codes to the module_init/exit context.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/net/netfilter/nf_conntrack_core.h |  7 +++++--
 net/netfilter/nf_conntrack_core.c         | 13 +++++++++---
 net/netfilter/nf_conntrack_proto.c        | 35 +++++++++++++++++--------------
 3 files changed, 34 insertions(+), 21 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index ec51a3c..5ea7518 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -34,8 +34,11 @@ extern void nf_conntrack_cleanup_start(void);
 extern void nf_conntrack_init_end(void);
 extern void nf_conntrack_cleanup_end(void);
 
-extern int nf_conntrack_proto_init(struct net *net);
-extern void nf_conntrack_proto_fini(struct net *net);
+extern int nf_conntrack_proto_pernet_init(struct net *net);
+extern void nf_conntrack_proto_pernet_fini(struct net *net);
+
+extern int nf_conntrack_proto_init(void);
+extern void nf_conntrack_proto_fini(void);
 
 extern bool
 nf_ct_get_tuple(const struct sk_buff *skb,
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 06ed86f..fc0805e 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1357,7 +1357,7 @@ void nf_conntrack_cleanup_net(struct net *net)
 	}
 
 	nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
-	nf_conntrack_proto_fini(net);
+	nf_conntrack_proto_pernet_fini(net);
 	nf_conntrack_helper_pernet_fini(net);
 	nf_conntrack_ecache_pernet_fini(net);
 	nf_conntrack_tstamp_pernet_fini(net);
@@ -1377,6 +1377,7 @@ void nf_conntrack_cleanup_end(void)
 #ifdef CONFIG_NF_CONNTRACK_ZONES
 	nf_ct_extend_unregister(&nf_ct_zone_extend);
 #endif
+	nf_conntrack_proto_fini();
 	nf_conntrack_helper_fini();
 	nf_conntrack_timeout_fini();
 	nf_conntrack_ecache_fini();
@@ -1531,6 +1532,10 @@ int nf_conntrack_init_start(void)
 	if (ret < 0)
 		goto err_extend;
 #endif
+	ret = nf_conntrack_proto_init();
+	if (ret < 0)
+		goto err_proto;
+
 	/* Set up fake conntrack: to never be deleted, not in any hashes */
 	for_each_possible_cpu(cpu) {
 		struct nf_conn *ct = &per_cpu(nf_conntrack_untracked, cpu);
@@ -1541,10 +1546,12 @@ int nf_conntrack_init_start(void)
 	nf_ct_untracked_status_or(IPS_CONFIRMED | IPS_UNTRACKED);
 	return 0;
 
+err_proto:
 #ifdef CONFIG_NF_CONNTRACK_ZONES
+	nf_ct_extend_unregister(&nf_ct_zone_extend);
 err_extend:
-	nf_conntrack_helper_fini();
 #endif
+	nf_conntrack_helper_fini();
 err_helper:
 	nf_conntrack_timeout_fini();
 err_timeout:
@@ -1615,7 +1622,7 @@ int nf_conntrack_init_net(struct net *net)
 	ret = nf_conntrack_helper_pernet_init(net);
 	if (ret < 0)
 		goto err_helper;
-	ret = nf_conntrack_proto_init(net);
+	ret = nf_conntrack_proto_pernet_init(net);
 	if (ret < 0)
 		goto out_proto;
 	return 0;
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 51e928d..3d01b90 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -503,9 +503,8 @@ void nf_conntrack_l4proto_unregister(struct net *net,
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister);
 
-int nf_conntrack_proto_init(struct net *net)
+int nf_conntrack_proto_pernet_init(struct net *net)
 {
-	unsigned int i;
 	int err;
 	struct nf_proto_net *pn = nf_ct_l4proto_net(net,
 					&nf_conntrack_l4proto_generic);
@@ -520,29 +519,33 @@ int nf_conntrack_proto_init(struct net *net)
 	if (err < 0)
 		return err;
 
-	if (net == &init_net) {
-		for (i = 0; i < AF_MAX; i++)
-			rcu_assign_pointer(nf_ct_l3protos[i],
-					   &nf_conntrack_l3proto_generic);
-	}
-
 	pn->users++;
 	return 0;
 }
 
-void nf_conntrack_proto_fini(struct net *net)
+void nf_conntrack_proto_pernet_fini(struct net *net)
 {
-	unsigned int i;
 	struct nf_proto_net *pn = nf_ct_l4proto_net(net,
 					&nf_conntrack_l4proto_generic);
-
 	pn->users--;
 	nf_ct_l4proto_unregister_sysctl(net,
 					pn,
 					&nf_conntrack_l4proto_generic);
-	if (net == &init_net) {
-		/* free l3proto protocol tables */
-		for (i = 0; i < PF_MAX; i++)
-			kfree(nf_ct_protos[i]);
-	}
+}
+
+int nf_conntrack_proto_init(void)
+{
+	unsigned int i;
+	for (i = 0; i < AF_MAX; i++)
+		rcu_assign_pointer(nf_ct_l3protos[i],
+				   &nf_conntrack_l3proto_generic);
+	return 0;
+}
+
+void nf_conntrack_proto_fini(void)
+{
+	unsigned int i;
+	/* free l3proto protocol tables */
+	for (i = 0; i < PF_MAX; i++)
+		kfree(nf_ct_protos[i]);
 }
-- 
1.7.11.7

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

* [PATCH 09/19] netfilter: l3proto: prepare reworking l3proto support for netns
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (6 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 08/19] netfilter: proto: " Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 10/19] netfilter: ipv4: register ipv4 in module_init Gao feng
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Prepare to move the code that register/unregister l3proto
to the module_init/exit context.

This patch deletes the codes that register/unregister l3proto,
this code will be added in next two patch.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/net/netfilter/nf_conntrack_l3proto.h   | 20 ++++++++++++-----
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c |  6 ++---
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |  6 ++---
 net/netfilter/nf_conntrack_proto.c             | 31 ++++++++++----------------
 4 files changed, 33 insertions(+), 30 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index 6f7c13f..f3834d5 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -76,11 +76,21 @@ struct nf_conntrack_l3proto {
 
 extern struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX];
 
-/* Protocol registration. */
-extern int nf_conntrack_l3proto_register(struct net *net,
-					 struct nf_conntrack_l3proto *proto);
-extern void nf_conntrack_l3proto_unregister(struct net *net,
-					    struct nf_conntrack_l3proto *proto);
+/* Protocol pernet registration. */
+extern int
+nf_conntrack_l3proto_pernet_register(struct net *net,
+				     struct nf_conntrack_l3proto *proto);
+extern void
+nf_conntrack_l3proto_pernet_unregister(struct net *net,
+				       struct nf_conntrack_l3proto *proto);
+
+/* Protocol global registration. */
+extern int
+nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
+
+extern void
+nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
+
 extern struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto);
 extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p);
 
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index fcdd0c2..afd3a96 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -438,8 +438,8 @@ static int ipv4_net_init(struct net *net)
 		pr_err("nf_conntrack_l4proto_icmp4 :protocol register failed\n");
 		goto out_icmp;
 	}
-	ret = nf_conntrack_l3proto_register(net,
-					    &nf_conntrack_l3proto_ipv4);
+	ret = nf_conntrack_l3proto_pernet_register(net,
+					&nf_conntrack_l3proto_ipv4);
 	if (ret < 0) {
 		pr_err("nf_conntrack_l3proto_ipv4 :protocol register failed\n");
 		goto out_ipv4;
@@ -460,7 +460,7 @@ out_tcp:
 
 static void ipv4_net_exit(struct net *net)
 {
-	nf_conntrack_l3proto_unregister(net,
+	nf_conntrack_l3proto_pernet_unregister(net,
 					&nf_conntrack_l3proto_ipv4);
 	nf_conntrack_l4proto_unregister(net,
 					&nf_conntrack_l4proto_icmp);
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 00ee17c..469a15f 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -439,8 +439,8 @@ static int ipv6_net_init(struct net *net)
 		printk(KERN_ERR "nf_conntrack_l4proto_icmp6: protocol register failed\n");
 		goto cleanup_udp6;
 	}
-	ret = nf_conntrack_l3proto_register(net,
-					    &nf_conntrack_l3proto_ipv6);
+	ret = nf_conntrack_l3proto_pernet_register(net,
+						&nf_conntrack_l3proto_ipv6);
 	if (ret < 0) {
 		printk(KERN_ERR "nf_conntrack_l3proto_ipv6: protocol register failed\n");
 		goto cleanup_icmpv6;
@@ -461,7 +461,7 @@ static int ipv6_net_init(struct net *net)
 
 static void ipv6_net_exit(struct net *net)
 {
-	nf_conntrack_l3proto_unregister(net,
+	nf_conntrack_l3proto_pernet_unregister(net,
 					&nf_conntrack_l3proto_ipv6);
 	nf_conntrack_l4proto_unregister(net,
 					&nf_conntrack_l4proto_icmpv6);
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 3d01b90..5a625a6 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -212,8 +212,8 @@ static void nf_ct_l3proto_unregister_sysctl(struct net *net,
 #endif
 }
 
-static int
-nf_conntrack_l3proto_register_net(struct nf_conntrack_l3proto *proto)
+int
+nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
 {
 	int ret = 0;
 	struct nf_conntrack_l3proto *old;
@@ -242,9 +242,10 @@ out_unlock:
 	return ret;
 
 }
+EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register);
 
-int nf_conntrack_l3proto_register(struct net *net,
-				  struct nf_conntrack_l3proto *proto)
+int nf_conntrack_l3proto_pernet_register(struct net *net,
+					 struct nf_conntrack_l3proto *proto)
 {
 	int ret = 0;
 
@@ -258,18 +259,12 @@ int nf_conntrack_l3proto_register(struct net *net,
 	if (ret < 0)
 		return ret;
 
-	if (net == &init_net) {
-		ret = nf_conntrack_l3proto_register_net(proto);
-		if (ret < 0)
-			nf_ct_l3proto_unregister_sysctl(net, proto);
-	}
-
 	return ret;
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register);
+EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_pernet_register);
 
-static void
-nf_conntrack_l3proto_unregister_net(struct nf_conntrack_l3proto *proto)
+void
+nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
 {
 	BUG_ON(proto->l3proto >= AF_MAX);
 
@@ -283,19 +278,17 @@ nf_conntrack_l3proto_unregister_net(struct nf_conntrack_l3proto *proto)
 
 	synchronize_rcu();
 }
+EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister);
 
-void nf_conntrack_l3proto_unregister(struct net *net,
-				     struct nf_conntrack_l3proto *proto)
+void nf_conntrack_l3proto_pernet_unregister(struct net *net,
+					struct nf_conntrack_l3proto *proto)
 {
-	if (net == &init_net)
-		nf_conntrack_l3proto_unregister_net(proto);
-
 	nf_ct_l3proto_unregister_sysctl(net, proto);
 
 	/* Remove all contrack entries for this protocol */
 	nf_ct_iterate_cleanup(net, kill_l3proto, proto);
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister);
+EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_pernet_unregister);
 
 static struct nf_proto_net *nf_ct_l4proto_net(struct net *net,
 					      struct nf_conntrack_l4proto *l4proto)
-- 
1.7.11.7

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

* [PATCH 10/19] netfilter: ipv4: register ipv4 in module_init
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (7 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 09/19] netfilter: l3proto: prepare reworking l3proto support for netns Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 10/19] netfilter: ipv4: register l3proto " Gao feng
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

register nf_conntrack_l3proto_ipv4 in module_init,
and unregister it in module_exit.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index afd3a96..a942add 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -500,6 +500,10 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
 		pr_err("nf_conntrack_ipv4: can't register hooks.\n");
 		goto cleanup_pernet;
 	}
+
+	ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv4);
+	if (ret < 0)
+		goto cleanup_proto;
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
 	ret = nf_conntrack_ipv4_compat_init();
 	if (ret < 0)
@@ -508,8 +512,10 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
 	return ret;
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
  cleanup_hooks:
-	nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
+	nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
 #endif
+ cleanup_proto:
+	nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
  cleanup_pernet:
 	unregister_pernet_subsys(&ipv4_net_ops);
  cleanup_sockopt:
@@ -523,6 +529,7 @@ static void __exit nf_conntrack_l3proto_ipv4_fini(void)
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
 	nf_conntrack_ipv4_compat_fini();
 #endif
+	nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
 	nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
 	unregister_pernet_subsys(&ipv4_net_ops);
 	nf_unregister_sockopt(&so_getorigdst);
-- 
1.7.11.7

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

* [PATCH 10/19] netfilter: ipv4: register l3proto ipv4 in module_init
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (8 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 10/19] netfilter: ipv4: register ipv4 in module_init Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 11/19] netfilter: ipv6: register l3proto ipv6 " Gao feng
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

register nf_conntrack_l3proto_ipv4 in module_init,
and unregister it in module_exit.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index afd3a96..a942add 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -500,6 +500,10 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
 		pr_err("nf_conntrack_ipv4: can't register hooks.\n");
 		goto cleanup_pernet;
 	}
+
+	ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv4);
+	if (ret < 0)
+		goto cleanup_proto;
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
 	ret = nf_conntrack_ipv4_compat_init();
 	if (ret < 0)
@@ -508,8 +512,10 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
 	return ret;
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
  cleanup_hooks:
-	nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
+	nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
 #endif
+ cleanup_proto:
+	nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
  cleanup_pernet:
 	unregister_pernet_subsys(&ipv4_net_ops);
  cleanup_sockopt:
@@ -523,6 +529,7 @@ static void __exit nf_conntrack_l3proto_ipv4_fini(void)
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
 	nf_conntrack_ipv4_compat_fini();
 #endif
+	nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
 	nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
 	unregister_pernet_subsys(&ipv4_net_ops);
 	nf_unregister_sockopt(&so_getorigdst);
-- 
1.7.11.7

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

* [PATCH 11/19] netfilter: ipv6: register l3proto ipv6 in module_init
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (9 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 10/19] netfilter: ipv4: register l3proto " Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 12/19] netfilter: l4proto: prepare reworking l4proto support for netns Gao feng
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

register nf_conntrack_l3proto_ipv6 in module_init,
and unregister it in module_exit.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 469a15f..07ec50b 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -499,8 +499,13 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
 		       "hook.\n");
 		goto cleanup_ipv6;
 	}
+	ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv6);
+	if (ret < 0)
+		goto cleanup_proto;
 	return ret;
 
+ cleanup_proto:
+	nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
  cleanup_ipv6:
 	unregister_pernet_subsys(&ipv6_net_ops);
  cleanup_pernet:
@@ -511,6 +516,7 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
 static void __exit nf_conntrack_l3proto_ipv6_fini(void)
 {
 	synchronize_net();
+	nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
 	nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
 	unregister_pernet_subsys(&ipv6_net_ops);
 	nf_unregister_sockopt(&so_getorigdst6);
-- 
1.7.11.7

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

* [PATCH 12/19] netfilter: l4proto: prepare reworking l4proto support for netns
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (10 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 11/19] netfilter: ipv6: register l3proto ipv6 " Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 13/19] netfilter: ipv4: move registration codes out of pernet_operations Gao feng
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Prepare to move the code that register/unregister l4proto
to the module_init/exit context.

This patch deletes the codes that register/unregister l4proto,
this code will be added in next patches.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/net/netfilter/nf_conntrack_l4proto.h   | 18 ++++++++++----
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 24 +++++++++----------
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 24 +++++++++----------
 net/netfilter/nf_conntrack_proto.c             | 33 ++++++++++----------------
 net/netfilter/nf_conntrack_proto_dccp.c        | 20 ++++++++--------
 net/netfilter/nf_conntrack_proto_gre.c         |  6 +++--
 net/netfilter/nf_conntrack_proto_sctp.c        | 14 +++++------
 net/netfilter/nf_conntrack_proto_udplite.c     | 17 +++++++------
 8 files changed, 80 insertions(+), 76 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
index c3be4ae..c001ef7 100644
--- a/include/net/netfilter/nf_conntrack_l4proto.h
+++ b/include/net/netfilter/nf_conntrack_l4proto.h
@@ -121,11 +121,19 @@ extern struct nf_conntrack_l4proto *
 nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t l4proto);
 extern void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p);
 
-/* Protocol registration. */
-extern int nf_conntrack_l4proto_register(struct net *net,
-					 struct nf_conntrack_l4proto *proto);
-extern void nf_conntrack_l4proto_unregister(struct net *net,
-					    struct nf_conntrack_l4proto *proto);
+/* Protocol pernet registration. */
+extern int
+nf_conntrack_l4proto_pernet_register(struct net *net,
+				struct nf_conntrack_l4proto *proto);
+extern void
+nf_conntrack_l4proto_pernet_unregister(struct net *net,
+				struct nf_conntrack_l4proto *proto);
+
+/* Protocol global registration. */
+extern int
+nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *proto);
+extern void
+nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *proto);
 
 static inline void nf_ct_kfree_compat_sysctl_table(struct nf_proto_net *pn)
 {
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index a942add..933da838 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -420,20 +420,20 @@ static int ipv4_net_init(struct net *net)
 {
 	int ret = 0;
 
-	ret = nf_conntrack_l4proto_register(net,
-					    &nf_conntrack_l4proto_tcp4);
+	ret = nf_conntrack_l4proto_pernet_register(net,
+					&nf_conntrack_l4proto_tcp4);
 	if (ret < 0) {
 		pr_err("nf_conntrack_l4proto_tcp4 :protocol register failed\n");
 		goto out_tcp;
 	}
-	ret = nf_conntrack_l4proto_register(net,
-					    &nf_conntrack_l4proto_udp4);
+	ret = nf_conntrack_l4proto_pernet_register(net,
+					&nf_conntrack_l4proto_udp4);
 	if (ret < 0) {
 		pr_err("nf_conntrack_l4proto_udp4 :protocol register failed\n");
 		goto out_udp;
 	}
-	ret = nf_conntrack_l4proto_register(net,
-					    &nf_conntrack_l4proto_icmp);
+	ret = nf_conntrack_l4proto_pernet_register(net,
+					&nf_conntrack_l4proto_icmp);
 	if (ret < 0) {
 		pr_err("nf_conntrack_l4proto_icmp4 :protocol register failed\n");
 		goto out_icmp;
@@ -446,13 +446,13 @@ static int ipv4_net_init(struct net *net)
 	}
 	return 0;
 out_ipv4:
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_icmp);
 out_icmp:
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_udp4);
 out_udp:
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_tcp4);
 out_tcp:
 	return ret;
@@ -462,11 +462,11 @@ static void ipv4_net_exit(struct net *net)
 {
 	nf_conntrack_l3proto_pernet_unregister(net,
 					&nf_conntrack_l3proto_ipv4);
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_icmp);
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_udp4);
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_tcp4);
 }
 
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 07ec50b..8db8182 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -421,20 +421,20 @@ static int ipv6_net_init(struct net *net)
 {
 	int ret = 0;
 
-	ret = nf_conntrack_l4proto_register(net,
-					    &nf_conntrack_l4proto_tcp6);
+	ret = nf_conntrack_l4proto_pernet_register(net,
+					&nf_conntrack_l4proto_tcp6);
 	if (ret < 0) {
 		printk(KERN_ERR "nf_conntrack_l4proto_tcp6: protocol register failed\n");
 		goto out;
 	}
-	ret = nf_conntrack_l4proto_register(net,
-					    &nf_conntrack_l4proto_udp6);
+	ret = nf_conntrack_l4proto_pernet_register(net,
+					&nf_conntrack_l4proto_udp6);
 	if (ret < 0) {
 		printk(KERN_ERR "nf_conntrack_l4proto_udp6: protocol register failed\n");
 		goto cleanup_tcp6;
 	}
-	ret = nf_conntrack_l4proto_register(net,
-					    &nf_conntrack_l4proto_icmpv6);
+	ret = nf_conntrack_l4proto_pernet_register(net,
+					&nf_conntrack_l4proto_icmpv6);
 	if (ret < 0) {
 		printk(KERN_ERR "nf_conntrack_l4proto_icmp6: protocol register failed\n");
 		goto cleanup_udp6;
@@ -447,13 +447,13 @@ static int ipv6_net_init(struct net *net)
 	}
 	return 0;
  cleanup_icmpv6:
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_icmpv6);
  cleanup_udp6:
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_udp6);
  cleanup_tcp6:
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_tcp6);
  out:
 	return ret;
@@ -463,11 +463,11 @@ static void ipv6_net_exit(struct net *net)
 {
 	nf_conntrack_l3proto_pernet_unregister(net,
 					&nf_conntrack_l3proto_ipv6);
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_icmpv6);
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_udp6);
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_tcp6);
 }
 
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 5a625a6..ff38923 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -369,8 +369,8 @@ void nf_ct_l4proto_unregister_sysctl(struct net *net,
 
 /* FIXME: Allow NULL functions and sub in pointers to generic for
    them. --RR */
-static int
-nf_conntrack_l4proto_register_net(struct nf_conntrack_l4proto *l4proto)
+int
+nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
 {
 	int ret = 0;
 
@@ -424,9 +424,10 @@ out_unlock:
 	mutex_unlock(&nf_ct_proto_mutex);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
 
-int nf_conntrack_l4proto_register(struct net *net,
-				  struct nf_conntrack_l4proto *l4proto)
+int nf_conntrack_l4proto_pernet_register(struct net *net,
+					struct nf_conntrack_l4proto *l4proto)
 {
 	int ret = 0;
 	struct nf_proto_net *pn = NULL;
@@ -445,22 +446,14 @@ int nf_conntrack_l4proto_register(struct net *net,
 	if (ret < 0)
 		goto out;
 
-	if (net == &init_net) {
-		ret = nf_conntrack_l4proto_register_net(l4proto);
-		if (ret < 0) {
-			nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
-			goto out;
-		}
-	}
-
 	pn->users++;
 out:
 	return ret;
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_pernet_register);
 
-static void
-nf_conntrack_l4proto_unregister_net(struct nf_conntrack_l4proto *l4proto)
+void
+nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
 {
 	BUG_ON(l4proto->l3proto >= PF_MAX);
 
@@ -475,15 +468,13 @@ nf_conntrack_l4proto_unregister_net(struct nf_conntrack_l4proto *l4proto)
 
 	synchronize_rcu();
 }
+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister);
 
-void nf_conntrack_l4proto_unregister(struct net *net,
-				     struct nf_conntrack_l4proto *l4proto)
+void nf_conntrack_l4proto_pernet_unregister(struct net *net,
+					struct nf_conntrack_l4proto *l4proto)
 {
 	struct nf_proto_net *pn = NULL;
 
-	if (net == &init_net)
-		nf_conntrack_l4proto_unregister_net(l4proto);
-
 	pn = nf_ct_l4proto_net(net, l4proto);
 	if (pn == NULL)
 		return;
@@ -494,7 +485,7 @@ void nf_conntrack_l4proto_unregister(struct net *net,
 	/* Remove all contrack entries for this protocol */
 	nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister);
+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_pernet_unregister);
 
 int nf_conntrack_proto_pernet_init(struct net *net)
 {
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index a8ae287..3850d68 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -935,32 +935,32 @@ static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
 static __net_init int dccp_net_init(struct net *net)
 {
 	int ret = 0;
-	ret = nf_conntrack_l4proto_register(net,
-					    &dccp_proto4);
+	ret = nf_conntrack_l4proto_pernet_register(net,
+						   &dccp_proto4);
 	if (ret < 0) {
 		pr_err("nf_conntrack_l4proto_dccp4 :protocol register failed.\n");
 		goto out;
 	}
-	ret = nf_conntrack_l4proto_register(net,
-					    &dccp_proto6);
+	ret = nf_conntrack_l4proto_pernet_register(net,
+						   &dccp_proto6);
 	if (ret < 0) {
 		pr_err("nf_conntrack_l4proto_dccp6 :protocol register failed.\n");
 		goto cleanup_dccp4;
 	}
 	return 0;
 cleanup_dccp4:
-	nf_conntrack_l4proto_unregister(net,
-					&dccp_proto4);
+	nf_conntrack_l4proto_pernet_unregister(net,
+					       &dccp_proto4);
 out:
 	return ret;
 }
 
 static __net_exit void dccp_net_exit(struct net *net)
 {
-	nf_conntrack_l4proto_unregister(net,
-					&dccp_proto6);
-	nf_conntrack_l4proto_unregister(net,
-					&dccp_proto4);
+	nf_conntrack_l4proto_pernet_unregister(net,
+					       &dccp_proto6);
+	nf_conntrack_l4proto_pernet_unregister(net,
+					       &dccp_proto4);
 }
 
 static struct pernet_operations dccp_net_ops = {
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index b09b7af..f5f14c2 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -397,7 +397,8 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = {
 static int proto_gre_net_init(struct net *net)
 {
 	int ret = 0;
-	ret = nf_conntrack_l4proto_register(net, &nf_conntrack_l4proto_gre4);
+	ret = nf_conntrack_l4proto_pernet_register(net,
+						&nf_conntrack_l4proto_gre4);
 	if (ret < 0)
 		pr_err("nf_conntrack_l4proto_gre4 :protocol register failed.\n");
 	return ret;
@@ -405,7 +406,8 @@ static int proto_gre_net_init(struct net *net)
 
 static void proto_gre_net_exit(struct net *net)
 {
-	nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_gre4);
+	nf_conntrack_l4proto_pernet_unregister(net,
+					       &nf_conntrack_l4proto_gre4);
 	nf_ct_gre_keymap_flush(net);
 }
 
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index c746d61..0aa91dd 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -853,14 +853,14 @@ static int sctp_net_init(struct net *net)
 {
 	int ret = 0;
 
-	ret = nf_conntrack_l4proto_register(net,
-					    &nf_conntrack_l4proto_sctp4);
+	ret = nf_conntrack_l4proto_pernet_register(net,
+						&nf_conntrack_l4proto_sctp4);
 	if (ret < 0) {
 		pr_err("nf_conntrack_l4proto_sctp4 :protocol register failed.\n");
 		goto out;
 	}
-	ret = nf_conntrack_l4proto_register(net,
-					    &nf_conntrack_l4proto_sctp6);
+	ret = nf_conntrack_l4proto_pernet_register(net,
+						&nf_conntrack_l4proto_sctp6);
 	if (ret < 0) {
 		pr_err("nf_conntrack_l4proto_sctp6 :protocol register failed.\n");
 		goto cleanup_sctp4;
@@ -868,7 +868,7 @@ static int sctp_net_init(struct net *net)
 	return 0;
 
 cleanup_sctp4:
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_sctp4);
 out:
 	return ret;
@@ -876,9 +876,9 @@ out:
 
 static void sctp_net_exit(struct net *net)
 {
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_sctp6);
-	nf_conntrack_l4proto_unregister(net,
+	nf_conntrack_l4proto_pernet_unregister(net,
 					&nf_conntrack_l4proto_sctp4);
 }
 
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index 4b66df2..56e53c0 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -336,14 +336,14 @@ static int udplite_net_init(struct net *net)
 {
 	int ret = 0;
 
-	ret = nf_conntrack_l4proto_register(net,
-					    &nf_conntrack_l4proto_udplite4);
+	ret = nf_conntrack_l4proto_pernet_register(net,
+					&nf_conntrack_l4proto_udplite4);
 	if (ret < 0) {
 		pr_err("nf_conntrack_l4proto_udplite4 :protocol register failed.\n");
 		goto out;
 	}
-	ret = nf_conntrack_l4proto_register(net,
-					    &nf_conntrack_l4proto_udplite6);
+	ret = nf_conntrack_l4proto_pernet_register(net,
+					&nf_conntrack_l4proto_udplite6);
 	if (ret < 0) {
 		pr_err("nf_conntrack_l4proto_udplite4 :protocol register failed.\n");
 		goto cleanup_udplite4;
@@ -351,15 +351,18 @@ static int udplite_net_init(struct net *net)
 	return 0;
 
 cleanup_udplite4:
-	nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite4);
+	nf_conntrack_l4proto_pernet_unregister(net,
+					&nf_conntrack_l4proto_udplite4);
 out:
 	return ret;
 }
 
 static void udplite_net_exit(struct net *net)
 {
-	nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite6);
-	nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite4);
+	nf_conntrack_l4proto_pernet_unregister(net,
+					&nf_conntrack_l4proto_udplite6);
+	nf_conntrack_l4proto_pernet_unregister(net,
+					&nf_conntrack_l4proto_udplite4);
 }
 
 static struct pernet_operations udplite_net_ops = {
-- 
1.7.11.7


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

* [PATCH 13/19] netfilter: ipv4: move registration codes out of pernet_operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (11 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 12/19] netfilter: l4proto: prepare reworking l4proto support for netns Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 14/19] netfilter: ipv6: " Gao feng
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Move the proto (un)registration codes to the module_init/exit context.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 933da838..39521ca 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -501,6 +501,18 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
 		goto cleanup_pernet;
 	}
 
+	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp4);
+	if (ret < 0)
+		goto cleanup_tcp4;
+
+	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp4);
+	if (ret < 0)
+		goto cleanup_udp4;
+
+	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmp);
+	if (ret < 0)
+		goto cleanup_icmp;
+
 	ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv4);
 	if (ret < 0)
 		goto cleanup_proto;
@@ -515,6 +527,12 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
 	nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
 #endif
  cleanup_proto:
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp);
+ cleanup_icmp:
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4);
+ cleanup_udp4:
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
+ cleanup_tcp4:
 	nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
  cleanup_pernet:
 	unregister_pernet_subsys(&ipv4_net_ops);
@@ -529,7 +547,11 @@ static void __exit nf_conntrack_l3proto_ipv4_fini(void)
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
 	nf_conntrack_ipv4_compat_fini();
 #endif
+
 	nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp);
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4);
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
 	nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
 	unregister_pernet_subsys(&ipv4_net_ops);
 	nf_unregister_sockopt(&so_getorigdst);
-- 
1.7.11.7


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

* [PATCH 14/19] netfilter: ipv6: move registration codes out of pernet_operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (12 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 13/19] netfilter: ipv4: move registration codes out of pernet_operations Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 15/19] netfilter: sctp: " Gao feng
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Move the proto (un)registration codes to the module_init/exit context.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 8db8182..6787ab1 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -499,12 +499,31 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
 		       "hook.\n");
 		goto cleanup_ipv6;
 	}
+
+	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6);
+	if (ret < 0)
+		goto cleanup_tcp6;
+
+	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6);
+	if (ret < 0)
+		goto cleanup_udp6;
+
+	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmpv6);
+	if (ret < 0)
+		goto cleanup_icmpv6;
+
 	ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv6);
 	if (ret < 0)
 		goto cleanup_proto;
 	return ret;
 
  cleanup_proto:
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
+ cleanup_icmpv6:
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
+ cleanup_udp6:
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
+ cleanup_tcp6:
 	nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
  cleanup_ipv6:
 	unregister_pernet_subsys(&ipv6_net_ops);
@@ -516,6 +535,9 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
 static void __exit nf_conntrack_l3proto_ipv6_fini(void)
 {
 	synchronize_net();
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
 	nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
 	nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
 	unregister_pernet_subsys(&ipv6_net_ops);
-- 
1.7.11.7


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

* [PATCH 15/19] netfilter: sctp: move registration codes out of pernet_operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (13 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 14/19] netfilter: ipv6: " Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 16/19] netfilter: udplite: " Gao feng
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Move the proto (un)registration codes to the module_init/exit context.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/netfilter/nf_conntrack_proto_sctp.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 0aa91dd..62ef799 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -891,11 +891,32 @@ static struct pernet_operations sctp_net_ops = {
 
 static int __init nf_conntrack_proto_sctp_init(void)
 {
-	return register_pernet_subsys(&sctp_net_ops);
+	int ret;
+	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp4);
+	if (ret < 0)
+		goto out_sctp4;
+
+	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp6);
+	if (ret < 0)
+		goto out_sctp6;
+
+	ret = register_pernet_subsys(&sctp_net_ops);
+	if (ret < 0)
+		goto out_pernet;
+
+	return 0;
+out_pernet:
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
+out_sctp6:
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
+out_sctp4:
+	return ret;
 }
 
 static void __exit nf_conntrack_proto_sctp_fini(void)
 {
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
 	unregister_pernet_subsys(&sctp_net_ops);
 }
 
-- 
1.7.11.7

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

* [PATCH 16/19] netfilter: udplite: move registration codes out of pernet_operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (14 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 15/19] netfilter: sctp: " Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 17/19] netfilter: dccp: " Gao feng
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Move the proto (un)registration codes to the module_init/exit context.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/netfilter/nf_conntrack_proto_udplite.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index 56e53c0..6ad1e5c 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -374,11 +374,32 @@ static struct pernet_operations udplite_net_ops = {
 
 static int __init nf_conntrack_proto_udplite_init(void)
 {
-	return register_pernet_subsys(&udplite_net_ops);
+	int ret;
+	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite4);
+	if (ret < 0)
+		goto out_udplite4;
+
+	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite6);
+	if (ret < 0)
+		goto out_udplite6;
+
+	ret = register_pernet_subsys(&udplite_net_ops);
+	if (ret < 0)
+		goto out_pernet;
+
+	return 0;
+out_pernet:
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite6);
+out_udplite6:
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
+out_udplite4:
+	return ret;
 }
 
 static void __exit nf_conntrack_proto_udplite_exit(void)
 {
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite6);
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
 	unregister_pernet_subsys(&udplite_net_ops);
 }
 
-- 
1.7.11.7

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

* [PATCH 17/19] netfilter: dccp: move registration codes out of pernet_operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (15 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 16/19] netfilter: udplite: " Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 18/19] netfilter: gre: " Gao feng
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Move the proto (un)registration codes to the module_init/exit context.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/netfilter/nf_conntrack_proto_dccp.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index 3850d68..5f84e2b 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -972,11 +972,32 @@ static struct pernet_operations dccp_net_ops = {
 
 static int __init nf_conntrack_proto_dccp_init(void)
 {
-	return register_pernet_subsys(&dccp_net_ops);
+	int ret;
+	ret = nf_conntrack_l4proto_register(&dccp_proto4);
+	if (ret < 0)
+		goto out_dccp4;
+
+	ret = nf_conntrack_l4proto_register(&dccp_proto6);
+	if (ret < 0)
+		goto out_dccp6;
+
+	ret = register_pernet_subsys(&dccp_net_ops);
+	if (ret < 0)
+		goto out_pernet;
+
+	return 0;
+out_pernet:
+	nf_conntrack_l4proto_unregister(&dccp_proto6);
+out_dccp6:
+	nf_conntrack_l4proto_unregister(&dccp_proto4);
+out_dccp4:
+	return ret;
 }
 
 static void __exit nf_conntrack_proto_dccp_fini(void)
 {
+	nf_conntrack_l4proto_unregister(&dccp_proto6);
+	nf_conntrack_l4proto_unregister(&dccp_proto4);
 	unregister_pernet_subsys(&dccp_net_ops);
 }
 
-- 
1.7.11.7


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

* [PATCH 18/19] netfilter: gre: move registration codes out of pernet_operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (16 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 17/19] netfilter: dccp: " Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2012-12-28  2:36 ` [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto Gao feng
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Move the proto (un)registration codes to the module_init/exit context.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/netfilter/nf_conntrack_proto_gre.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index f5f14c2..ea1f651 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -420,11 +420,25 @@ static struct pernet_operations proto_gre_net_ops = {
 
 static int __init nf_ct_proto_gre_init(void)
 {
-	return register_pernet_subsys(&proto_gre_net_ops);
+	int ret;
+	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_gre4);
+	if (ret < 0)
+		goto out_gre4;
+
+	ret = register_pernet_subsys(&proto_gre_net_ops);
+	if (ret < 0)
+		goto out_pernet;
+
+	return 0;
+out_pernet:
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
+out_gre4:
+	return ret;
 }
 
 static void __exit nf_ct_proto_gre_fini(void)
 {
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
 	unregister_pernet_subsys(&proto_gre_net_ops);
 }
 
-- 
1.7.11.7

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

* [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (17 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 18/19] netfilter: gre: " Gao feng
@ 2012-12-28  2:36 ` Gao feng
  2013-01-05  3:50   ` Pablo Neira Ayuso
  2012-12-28  3:52 ` [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations canqun zhang
  2013-01-10 16:41 ` Pablo Neira Ayuso
  20 siblings, 1 reply; 39+ messages in thread
From: Gao feng @ 2012-12-28  2:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, canqunzhang, kaber, pablo, ebiederm, Gao feng

Currectly we unregister proto before all conntrack entries of
this proto being destroyed. so in function destroy_conntrack
we can't find proper l4proto to call l4proto->destroy.
this will cause resource leak.

Because only nf_conntrack_l4proto_gre4 has its own destroy
pointer. fix this problem by marking gre4 proto disabled,
so this proto will not be found. after all contrack entries
of this proto being destroyed, we can unregister this proto
safely.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/net/netfilter/nf_conntrack.h         |  2 +-
 include/net/netfilter/nf_conntrack_l4proto.h |  9 ++++++
 net/netfilter/nf_conntrack_core.c            |  9 ++++--
 net/netfilter/nf_conntrack_proto.c           | 43 +++++++++++++++++++++++++---
 net/netfilter/nf_conntrack_proto_gre.c       |  3 +-
 5 files changed, 57 insertions(+), 9 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index caca0c4..9ba61fe 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -248,7 +248,7 @@ static inline struct nf_conn *nf_ct_untracked_get(void)
 extern void nf_ct_untracked_status_or(unsigned long bits);
 
 /* Iterate over all conntracks: if iter returns true, it's deleted. */
-extern void
+extern bool
 nf_ct_iterate_cleanup(struct net *net, int (*iter)(struct nf_conn *i, void *data), void *data);
 extern void nf_conntrack_free(struct nf_conn *ct);
 extern struct nf_conn *
diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
index c001ef7..967ae91 100644
--- a/include/net/netfilter/nf_conntrack_l4proto.h
+++ b/include/net/netfilter/nf_conntrack_l4proto.h
@@ -23,6 +23,10 @@ struct nf_conntrack_l4proto {
 	/* L4 Protocol number. */
 	u_int8_t l4proto;
 
+	/* under unregistration, proto is unavailable, only being set
+	 * by gre4 proto */
+	bool disabled;
+
 	/* Try to fill in the third arg: dataoff is offset past network protocol
            hdr.  Return true if possible. */
 	bool (*pkt_to_tuple)(const struct sk_buff *skb, unsigned int dataoff,
@@ -115,6 +119,9 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_generic;
 #define MAX_NF_CT_PROTO 256
 
 extern struct nf_conntrack_l4proto *
+__nf_ct_l4proto_find_all(u_int16_t l3proto, u_int8_t l4proto);
+
+extern struct nf_conntrack_l4proto *
 __nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto);
 
 extern struct nf_conntrack_l4proto *
@@ -134,6 +141,8 @@ extern int
 nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *proto);
 extern void
 nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *proto);
+extern void
+nf_conntrack_l4proto_disable(struct nf_conntrack_l4proto *proto);
 
 static inline void nf_ct_kfree_compat_sysctl_table(struct nf_proto_net *pn)
 {
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index fc0805e..788e6fe 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -208,7 +208,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
 	 * destroy_conntrack() MUST NOT be called with a write lock
 	 * to nf_conntrack_lock!!! -HW */
 	rcu_read_lock();
-	l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
+	l4proto = __nf_ct_l4proto_find_all(nf_ct_l3num(ct), nf_ct_protonum(ct));
 	if (l4proto && l4proto->destroy)
 		l4proto->destroy(ct);
 
@@ -1237,21 +1237,24 @@ found:
 	return ct;
 }
 
-void nf_ct_iterate_cleanup(struct net *net,
+bool nf_ct_iterate_cleanup(struct net *net,
 			   int (*iter)(struct nf_conn *i, void *data),
 			   void *data)
 {
 	struct nf_conn *ct;
 	unsigned int bucket = 0;
+	bool ret = true;
 
 	while ((ct = get_next_corpse(net, iter, data, &bucket)) != NULL) {
 		/* Time to push up daises... */
 		if (del_timer(&ct->timeout))
 			death_by_timeout((unsigned long)ct);
 		/* ... else the timer will get him soon. */
-
+		if (atomic_read(&ct->ct_general.use) > 1)
+			ret = false;
 		nf_ct_put(ct);
 	}
+	return ret;
 }
 EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup);
 
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index ff38923..0f6251e 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -65,13 +65,26 @@ nf_ct_unregister_sysctl(struct ctl_table_header **header,
 #endif
 
 struct nf_conntrack_l4proto *
-__nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto)
+__nf_ct_l4proto_find_all(u_int16_t l3proto, u_int8_t l4proto)
 {
 	if (unlikely(l3proto >= AF_MAX || nf_ct_protos[l3proto] == NULL))
 		return &nf_conntrack_l4proto_generic;
 
 	return rcu_dereference(nf_ct_protos[l3proto][l4proto]);
 }
+EXPORT_SYMBOL_GPL(__nf_ct_l4proto_find_all);
+
+struct nf_conntrack_l4proto *
+__nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto)
+{
+	struct nf_conntrack_l4proto *proto;
+	proto = __nf_ct_l4proto_find_all(l3proto, l4proto);
+
+	if (proto->disabled)
+		return &nf_conntrack_l4proto_generic;
+
+	return proto;
+}
 EXPORT_SYMBOL_GPL(__nf_ct_l4proto_find);
 
 /* this is guaranteed to always return a valid protocol helper, since
@@ -457,6 +470,10 @@ nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
 {
 	BUG_ON(l4proto->l3proto >= PF_MAX);
 
+	if (l4proto->destroy && !l4proto->disabled)
+		pr_warn("unregister l4proto %s: disable proto first\n",
+			l4proto->name);
+
 	mutex_lock(&nf_ct_proto_mutex);
 	BUG_ON(rcu_dereference_protected(
 			nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
@@ -481,12 +498,30 @@ void nf_conntrack_l4proto_pernet_unregister(struct net *net,
 
 	pn->users--;
 	nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
-
-	/* Remove all contrack entries for this protocol */
-	nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
+retry:
+	/* Remove all contrack entries for this protocol.
+	 * l4proto is needed in nf_ct_destroy to destroy
+	 * conntrack's proto private data,So make sure all
+	 * conntrack entries being destroyed for this protocol.
+	 * Then the l4proto can be unregistered safely.
+	 */
+	if (!nf_ct_iterate_cleanup(net, kill_l4proto, l4proto)) {
+		schedule();
+		goto retry;
+	}
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_pernet_unregister);
 
+void nf_conntrack_l4proto_disable(struct nf_conntrack_l4proto *proto)
+{
+	mutex_lock(&nf_ct_proto_mutex);
+	proto->disabled = true;
+	mutex_unlock(&nf_ct_proto_mutex);
+
+	synchronize_rcu();
+}
+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_disable);
+
 int nf_conntrack_proto_pernet_init(struct net *net)
 {
 	int err;
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index ea1f651..2730f0d 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -438,8 +438,9 @@ out_gre4:
 
 static void __exit nf_ct_proto_gre_fini(void)
 {
-	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
+	nf_conntrack_l4proto_disable(&nf_conntrack_l4proto_gre4);
 	unregister_pernet_subsys(&proto_gre_net_ops);
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
 }
 
 module_init(nf_ct_proto_gre_init);
-- 
1.7.11.7


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

* Re: [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (18 preceding siblings ...)
  2012-12-28  2:36 ` [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto Gao feng
@ 2012-12-28  3:52 ` canqun zhang
  2012-12-28  4:48   ` Eric W. Biederman
  2012-12-28  7:16   ` Gao feng
  2013-01-10 16:41 ` Pablo Neira Ayuso
  20 siblings, 2 replies; 39+ messages in thread
From: canqun zhang @ 2012-12-28  3:52 UTC (permalink / raw)
  To: Gao feng; +Cc: netfilter-devel, netdev, Patrick McHardy, pablo, ebiederm

Hi all
As discussed above,if the host machine create several linux
containers, there will be several  net namespaces.Resources with "nf
conntrack" are registered or unregistered on the first net
namespace(init_net),But init_net is not unregistered lastly,so
cleanuping other net namespaces  will triger painic.
If net namespaces are created  with the order of 1,2,...n,they should
be cleaned with the order of n,...2,1,so in this case init_net will be
unregistered lastly.
I fixed it up (see below). I have taken a lot of test!

diff -r 6a1a258923f5 -r 2667e89e6f50 net/core/net_namespace.c
--- a/net/core/net_namespace.c  Fri Dec 28 11:01:17 2012 +0800
+++ b/net/core/net_namespace.c  Fri Dec 28 11:05:12 2012 +0800
@@ -450,7 +450,7 @@

        list_del(&ops->list);
        for_each_net(net)
-               list_add_tail(&net->exit_list, &net_exit_list);
+              list_add(&net->exit_list, &net_exit_list);
        ops_exit_list(ops, &net_exit_list);
        ops_free_list(ops, &net_exit_lis

2012/12/28 Gao feng <gaofeng@cn.fujitsu.com>:
> canqun zhang reported a panic BUG,kernel may panic when
> unloading nf_conntrack module.
>
> It's because we reset nf_ct_destroy to NULL when we deal
> with init_net,it's too early.Some packets belongs to other
> netns still refers to the conntrack.when these packets need
> to be freed, kfree_skb will call nf_ct_destroy which is
> NULL.
>
> fix this bug by moving the nf_conntrack initialize and cleanup
> codes out of the pernet operations,this job should be done
> in module_init/exit.We can't use init_net to identify if
> it's the right time.
>
> Reported-by: canqun zhang <canqunzhang@gmail.com>
> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
> ---
>  include/net/netfilter/nf_conntrack_core.h | 10 +++-
>  net/netfilter/nf_conntrack_core.c         | 99 ++++++++++++-------------------
>  net/netfilter/nf_conntrack_standalone.c   | 29 ++++++---
>  3 files changed, 67 insertions(+), 71 deletions(-)
>
> diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
> index d8f5b9f..ec51a3c 100644
> --- a/include/net/netfilter/nf_conntrack_core.h
> +++ b/include/net/netfilter/nf_conntrack_core.h
> @@ -25,8 +25,14 @@ extern unsigned int nf_conntrack_in(struct net *net,
>                                     unsigned int hooknum,
>                                     struct sk_buff *skb);
>
> -extern int nf_conntrack_init(struct net *net);
> -extern void nf_conntrack_cleanup(struct net *net);
> +extern int nf_conntrack_init_net(struct net *net);
> +extern void nf_conntrack_cleanup_net(struct net *net);
> +
> +extern int nf_conntrack_init_start(void);
> +extern void nf_conntrack_cleanup_start(void);
> +
> +extern void nf_conntrack_init_end(void);
> +extern void nf_conntrack_cleanup_end(void);
>
>  extern int nf_conntrack_proto_init(struct net *net);
>  extern void nf_conntrack_proto_fini(struct net *net);
> diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
> index 08cdc71..ffb2463 100644
> --- a/net/netfilter/nf_conntrack_core.c
> +++ b/net/netfilter/nf_conntrack_core.c
> @@ -1331,18 +1331,23 @@ static int untrack_refs(void)
>         return cnt;
>  }
>
> -static void nf_conntrack_cleanup_init_net(void)
> +void nf_conntrack_cleanup_start(void)
>  {
> -       while (untrack_refs() > 0)
> -               schedule();
> -
> -#ifdef CONFIG_NF_CONNTRACK_ZONES
> -       nf_ct_extend_unregister(&nf_ct_zone_extend);
> -#endif
> +       RCU_INIT_POINTER(ip_ct_attach, NULL);
>  }
>
> -static void nf_conntrack_cleanup_net(struct net *net)
> +/*
> + * Mishearing the voices in his head, our hero wonders how he's
> + * supposed to kill the mall.
> + */
> +void nf_conntrack_cleanup_net(struct net *net)
>  {
> +       /*
> +        * This makes sure all current packets have passed through
> +        * netfilter framework.  Roll on, two-stage module
> +        * delete...
> +        */
> +       synchronize_net();
>   i_see_dead_people:
>         nf_ct_iterate_cleanup(net, kill_all, NULL);
>         nf_ct_release_dying_list(net);
> @@ -1352,6 +1357,7 @@ static void nf_conntrack_cleanup_net(struct net *net)
>         }
>
>         nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
> +       nf_conntrack_proto_fini(net);
>         nf_conntrack_helper_fini(net);
>         nf_conntrack_timeout_fini(net);
>         nf_conntrack_ecache_fini(net);
> @@ -1363,24 +1369,15 @@ static void nf_conntrack_cleanup_net(struct net *net)
>         free_percpu(net->ct.stat);
>  }
>
> -/* Mishearing the voices in his head, our hero wonders how he's
> -   supposed to kill the mall. */
> -void nf_conntrack_cleanup(struct net *net)
> +void nf_conntrack_cleanup_end(void)
>  {
> -       if (net_eq(net, &init_net))
> -               RCU_INIT_POINTER(ip_ct_attach, NULL);
> -
> -       /* This makes sure all current packets have passed through
> -          netfilter framework.  Roll on, two-stage module
> -          delete... */
> -       synchronize_net();
> -       nf_conntrack_proto_fini(net);
> -       nf_conntrack_cleanup_net(net);
> +       RCU_INIT_POINTER(nf_ct_destroy, NULL);
> +       while (untrack_refs() > 0)
> +               schedule();
>
> -       if (net_eq(net, &init_net)) {
> -               RCU_INIT_POINTER(nf_ct_destroy, NULL);
> -               nf_conntrack_cleanup_init_net();
> -       }
> +#ifdef CONFIG_NF_CONNTRACK_ZONES
> +       nf_ct_extend_unregister(&nf_ct_zone_extend);
> +#endif
>  }
>
>  void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
> @@ -1473,7 +1470,7 @@ void nf_ct_untracked_status_or(unsigned long bits)
>  }
>  EXPORT_SYMBOL_GPL(nf_ct_untracked_status_or);
>
> -static int nf_conntrack_init_init_net(void)
> +int nf_conntrack_init_start(void)
>  {
>         int max_factor = 8;
>         int ret, cpu;
> @@ -1527,7 +1524,7 @@ err_extend:
>  #define UNCONFIRMED_NULLS_VAL  ((1<<30)+0)
>  #define DYING_NULLS_VAL                ((1<<30)+1)
>
> -static int nf_conntrack_init_net(struct net *net)
> +int nf_conntrack_init_net(struct net *net)
>  {
>         int ret;
>
> @@ -1580,7 +1577,12 @@ static int nf_conntrack_init_net(struct net *net)
>         ret = nf_conntrack_helper_init(net);
>         if (ret < 0)
>                 goto err_helper;
> +       ret = nf_conntrack_proto_init(net);
> +       if (ret < 0)
> +               goto out_proto;
>         return 0;
> +out_proto:
> +       nf_conntrack_helper_fini(net);
>  err_helper:
>         nf_conntrack_timeout_fini(net);
>  err_timeout:
> @@ -1603,42 +1605,17 @@ err_stat:
>         return ret;
>  }
>
> +void nf_conntrack_init_end(void)
> +{
> +       /* For use by REJECT target */
> +       RCU_INIT_POINTER(ip_ct_attach, nf_conntrack_attach);
> +       RCU_INIT_POINTER(nf_ct_destroy, destroy_conntrack);
> +
> +       /* Howto get NAT offsets */
> +       RCU_INIT_POINTER(nf_ct_nat_offset, NULL);
> +}
> +
>  s16 (*nf_ct_nat_offset)(const struct nf_conn *ct,
>                         enum ip_conntrack_dir dir,
>                         u32 seq);
>  EXPORT_SYMBOL_GPL(nf_ct_nat_offset);
> -
> -int nf_conntrack_init(struct net *net)
> -{
> -       int ret;
> -
> -       if (net_eq(net, &init_net)) {
> -               ret = nf_conntrack_init_init_net();
> -               if (ret < 0)
> -                       goto out_init_net;
> -       }
> -       ret = nf_conntrack_proto_init(net);
> -       if (ret < 0)
> -               goto out_proto;
> -       ret = nf_conntrack_init_net(net);
> -       if (ret < 0)
> -               goto out_net;
> -
> -       if (net_eq(net, &init_net)) {
> -               /* For use by REJECT target */
> -               RCU_INIT_POINTER(ip_ct_attach, nf_conntrack_attach);
> -               RCU_INIT_POINTER(nf_ct_destroy, destroy_conntrack);
> -
> -               /* Howto get NAT offsets */
> -               RCU_INIT_POINTER(nf_ct_nat_offset, NULL);
> -       }
> -       return 0;
> -
> -out_net:
> -       nf_conntrack_proto_fini(net);
> -out_proto:
> -       if (net_eq(net, &init_net))
> -               nf_conntrack_cleanup_init_net();
> -out_init_net:
> -       return ret;
> -}
> diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
> index 363285d..00bf93c 100644
> --- a/net/netfilter/nf_conntrack_standalone.c
> +++ b/net/netfilter/nf_conntrack_standalone.c
> @@ -530,11 +530,11 @@ static void nf_conntrack_standalone_fini_sysctl(struct net *net)
>  }
>  #endif /* CONFIG_SYSCTL */
>
> -static int nf_conntrack_net_init(struct net *net)
> +static int nf_conntrack_pernet_init(struct net *net)
>  {
>         int ret;
>
> -       ret = nf_conntrack_init(net);
> +       ret = nf_conntrack_init_net(net);
>         if (ret < 0)
>                 goto out_init;
>         ret = nf_conntrack_standalone_init_proc(net);
> @@ -550,31 +550,44 @@ static int nf_conntrack_net_init(struct net *net)
>  out_sysctl:
>         nf_conntrack_standalone_fini_proc(net);
>  out_proc:
> -       nf_conntrack_cleanup(net);
> +       nf_conntrack_cleanup_net(net);
>  out_init:
>         return ret;
>  }
>
> -static void nf_conntrack_net_exit(struct net *net)
> +static void nf_conntrack_pernet_exit(struct net *net)
>  {
>         nf_conntrack_standalone_fini_sysctl(net);
>         nf_conntrack_standalone_fini_proc(net);
> -       nf_conntrack_cleanup(net);
> +       nf_conntrack_cleanup_net(net);
>  }
>
>  static struct pernet_operations nf_conntrack_net_ops = {
> -       .init = nf_conntrack_net_init,
> -       .exit = nf_conntrack_net_exit,
> +       .init = nf_conntrack_pernet_init,
> +       .exit = nf_conntrack_pernet_exit,
>  };
>
>  static int __init nf_conntrack_standalone_init(void)
>  {
> -       return register_pernet_subsys(&nf_conntrack_net_ops);
> +       int ret = nf_conntrack_init_start();
> +       if (ret < 0)
> +               goto out_start;
> +       ret = register_pernet_subsys(&nf_conntrack_net_ops);
> +       if (ret < 0)
> +               goto out_pernet;
> +       nf_conntrack_init_end();
> +       return 0;
> +out_pernet:
> +       nf_conntrack_cleanup_end();
> +out_start:
> +       return ret;
>  }
>
>  static void __exit nf_conntrack_standalone_fini(void)
>  {
> +       nf_conntrack_cleanup_start();
>         unregister_pernet_subsys(&nf_conntrack_net_ops);
> +       nf_conntrack_cleanup_end();
>  }
>
>  module_init(nf_conntrack_standalone_init);
> --
> 1.7.11.7
>

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

* Re: [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations
  2012-12-28  3:52 ` [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations canqun zhang
@ 2012-12-28  4:48   ` Eric W. Biederman
  2012-12-28  5:32     ` canqun zhang
  2012-12-28 11:58     ` Pablo Neira Ayuso
  2012-12-28  7:16   ` Gao feng
  1 sibling, 2 replies; 39+ messages in thread
From: Eric W. Biederman @ 2012-12-28  4:48 UTC (permalink / raw)
  To: canqun zhang; +Cc: Gao feng, netfilter-devel, netdev, Patrick McHardy, pablo

canqun zhang <canqunzhang@gmail.com> writes:

> Hi all
> As discussed above,if the host machine create several linux
> containers, there will be several  net namespaces.Resources with "nf
> conntrack" are registered or unregistered on the first net
> namespace(init_net),But init_net is not unregistered lastly,so
> cleanuping other net namespaces  will triger painic.
> If net namespaces are created  with the order of 1,2,...n,they should
> be cleaned with the order of n,...2,1,so in this case init_net will be
> unregistered lastly.

No.  Network namespaces in general can be cleaned up in any order.

In particular you should never ever expect to see the order
n,n-1,n-2,...,2,1.

It may make sense to special case init_net in the cleanup order
but I would really rather not.

Now init_net is special and really should never be cleaned up
for non-modular code.  So it almost makes sense to special
case init_net.

Does anyone know why Alexy decided to do this only for init_net?

My inclination is that Gao Feng is on the rigt path by just removing
the strange init_net special case and performing the work once
per module load, and once per module unload.

> I fixed it up (see below). I have taken a lot of test!

Thank you.

It is nice to see that we have exposed this mis-assumption.

I am inclined to leave the order of this list as is so that
other assumptions of network namespace unregistration order
are exposed.

Unless there is a truly good reason to perform magic on init_net.

Eric

> diff -r 6a1a258923f5 -r 2667e89e6f50 net/core/net_namespace.c
> --- a/net/core/net_namespace.c  Fri Dec 28 11:01:17 2012 +0800
> +++ b/net/core/net_namespace.c  Fri Dec 28 11:05:12 2012 +0800
> @@ -450,7 +450,7 @@
>
>         list_del(&ops->list);
>         for_each_net(net)
> -               list_add_tail(&net->exit_list, &net_exit_list);
> +              list_add(&net->exit_list, &net_exit_list);
>         ops_exit_list(ops, &net_exit_list);
>         ops_free_list(ops, &net_exit_lis
>

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

* Re: [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations
  2012-12-28  4:48   ` Eric W. Biederman
@ 2012-12-28  5:32     ` canqun zhang
  2012-12-28  6:00       ` Eric W. Biederman
  2012-12-28 11:58     ` Pablo Neira Ayuso
  1 sibling, 1 reply; 39+ messages in thread
From: canqun zhang @ 2012-12-28  5:32 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Gao feng, netfilter-devel, netdev, Patrick McHardy, pablo

yes,Network namespaces in general can be cleaned up in any order,but
when doing /etc/ini.d/iptables restart, the system need cleaning up
all net namespace,and init_net should be cleanup lastly.init_net is
the first namespace,other net namespace is copied for it ,and it is
diuty for Initializing resources,so It in itself is special.

2012/12/28 Eric W. Biederman <ebiederm@xmission.com>:
> canqun zhang <canqunzhang@gmail.com> writes:
>
>> Hi all
>> As discussed above,if the host machine create several linux
>> containers, there will be several  net namespaces.Resources with "nf
>> conntrack" are registered or unregistered on the first net
>> namespace(init_net),But init_net is not unregistered lastly,so
>> cleanuping other net namespaces  will triger painic.
>> If net namespaces are created  with the order of 1,2,...n,they should
>> be cleaned with the order of n,...2,1,so in this case init_net will be
>> unregistered lastly.
>
> No.  Network namespaces in general can be cleaned up in any order.
>
> In particular you should never ever expect to see the order
> n,n-1,n-2,...,2,1.
>
> It may make sense to special case init_net in the cleanup order
> but I would really rather not.
>
> Now init_net is special and really should never be cleaned up
> for non-modular code.  So it almost makes sense to special
> case init_net.
>
> Does anyone know why Alexy decided to do this only for init_net?
>
> My inclination is that Gao Feng is on the rigt path by just removing
> the strange init_net special case and performing the work once
> per module load, and once per module unload.
>
>> I fixed it up (see below). I have taken a lot of test!
>
> Thank you.
>
> It is nice to see that we have exposed this mis-assumption.
>
> I am inclined to leave the order of this list as is so that
> other assumptions of network namespace unregistration order
> are exposed.
>
> Unless there is a truly good reason to perform magic on init_net.
>
> Eric
>
>> diff -r 6a1a258923f5 -r 2667e89e6f50 net/core/net_namespace.c
>> --- a/net/core/net_namespace.c  Fri Dec 28 11:01:17 2012 +0800
>> +++ b/net/core/net_namespace.c  Fri Dec 28 11:05:12 2012 +0800
>> @@ -450,7 +450,7 @@
>>
>>         list_del(&ops->list);
>>         for_each_net(net)
>> -               list_add_tail(&net->exit_list, &net_exit_list);
>> +              list_add(&net->exit_list, &net_exit_list);
>>         ops_exit_list(ops, &net_exit_list);
>>         ops_free_list(ops, &net_exit_lis
>>
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations
  2012-12-28  5:32     ` canqun zhang
@ 2012-12-28  6:00       ` Eric W. Biederman
  0 siblings, 0 replies; 39+ messages in thread
From: Eric W. Biederman @ 2012-12-28  6:00 UTC (permalink / raw)
  To: canqun zhang; +Cc: Gao feng, netfilter-devel, netdev, Patrick McHardy, pablo

canqun zhang <canqunzhang@gmail.com> writes:

> yes,Network namespaces in general can be cleaned up in any order,but
> when doing /etc/ini.d/iptables restart, the system need cleaning up
> all net namespace,and init_net should be cleanup lastly.init_net is
> the first namespace,other net namespace is copied for it ,and it is
> diuty for Initializing resources,so It in itself is special.

"other net namespaces is copied for it"  I don't have a clue what
you mean by that.  Every network namespace starts out in a default
state not in a copied state.

Nowhere else in the network stack does &init_net have the duty
of initializing or cleaning up resources.

That /etc/init.d/iptables restart removes modules in general is a little
dubious.  That /etc/init.d/iptables restart removes modules when there
are other existing network namespaces using those modules is down right
dangerous.  Dangerous in the anyone can ssh into the machine way.  I
suspect it has taken 5 years for this bug to show up because it is so
idiotic to remove code that someone else is using.

I won't argue that making it so that &init_net is the last network
namespace to go will solve this problem.  But I can't see how adding
the guarantee that &init_net will always be cleaned up last is a good
long term solution.

Removing the init_net special case gives a simpler mental model, and
less to learn and maintain about network namespaces.

Eric
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations
  2012-12-28  3:52 ` [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations canqun zhang
  2012-12-28  4:48   ` Eric W. Biederman
@ 2012-12-28  7:16   ` Gao feng
  2012-12-28  8:48     ` canqun zhang
  1 sibling, 1 reply; 39+ messages in thread
From: Gao feng @ 2012-12-28  7:16 UTC (permalink / raw)
  To: canqun zhang; +Cc: netfilter-devel, netdev, Patrick McHardy, pablo, ebiederm

On 12/28/12 11:52, canqun zhang wrote:
> Hi all
> As discussed above,if the host machine create several linux
> containers, there will be several  net namespaces.Resources with "nf
> conntrack" are registered or unregistered on the first net
> namespace(init_net),But init_net is not unregistered lastly,so
> cleanuping other net namespaces  will triger painic.
> If net namespaces are created  with the order of 1,2,...n,they should
> be cleaned with the order of n,...2,1,so in this case init_net will be
> unregistered lastly.
> I fixed it up (see below). I have taken a lot of test!
> 

I thinks this BUG is a netfilter BUG,not a netns BUG.
Other subsystems implemented netns support don't use init_net to
do some special works((un)register/(un)set).

In fact,we can't use init_net to do this job well.such as function
nf_conntrack_clean,we shoud set ip_ct_attach to NULL before any
netns doing cleanup jobs, and set nf_ct_destroy to NULL after all of
netns finish these cleanup jobs.

So I think finally we still need this patchset,And this is a regular
way to fix this problem.

Can you help me to test if the panic bug is fixed by this patchset?
and then give me your tested-by?

thank you very much!

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

* Re: [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations
  2012-12-28  7:16   ` Gao feng
@ 2012-12-28  8:48     ` canqun zhang
  2013-01-10  1:03       ` Gao feng
  0 siblings, 1 reply; 39+ messages in thread
From: canqun zhang @ 2012-12-28  8:48 UTC (permalink / raw)
  To: Gao feng
  Cc: netfilter-devel, netdev, Patrick McHardy, pablo, Eric W. Biederman

ok, I can help you take a test, please send a big patch container this
patchset  to my email.


2012/12/28 Gao feng <gaofeng@cn.fujitsu.com>:
> On 12/28/12 11:52, canqun zhang wrote:
>> Hi all
>> As discussed above,if the host machine create several linux
>> containers, there will be several  net namespaces.Resources with "nf
>> conntrack" are registered or unregistered on the first net
>> namespace(init_net),But init_net is not unregistered lastly,so
>> cleanuping other net namespaces  will triger painic.
>> If net namespaces are created  with the order of 1,2,...n,they should
>> be cleaned with the order of n,...2,1,so in this case init_net will be
>> unregistered lastly.
>> I fixed it up (see below). I have taken a lot of test!
>>
>
> I thinks this BUG is a netfilter BUG,not a netns BUG.
> Other subsystems implemented netns support don't use init_net to
> do some special works((un)register/(un)set).
>
> In fact,we can't use init_net to do this job well.such as function
> nf_conntrack_clean,we shoud set ip_ct_attach to NULL before any
> netns doing cleanup jobs, and set nf_ct_destroy to NULL after all of
> netns finish these cleanup jobs.
>
> So I think finally we still need this patchset,And this is a regular
> way to fix this problem.
>
> Can you help me to test if the panic bug is fixed by this patchset?
> and then give me your tested-by?
>
> thank you very much!

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

* Re: [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations
  2012-12-28  4:48   ` Eric W. Biederman
  2012-12-28  5:32     ` canqun zhang
@ 2012-12-28 11:58     ` Pablo Neira Ayuso
  1 sibling, 0 replies; 39+ messages in thread
From: Pablo Neira Ayuso @ 2012-12-28 11:58 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: canqun zhang, Gao feng, netfilter-devel, netdev, Patrick McHardy

On Thu, Dec 27, 2012 at 08:48:44PM -0800, Eric W. Biederman wrote:
[...]
> Does anyone know why Alexy decided to do this only for init_net?

Not myself.

[...]
> My inclination is that Gao Feng is on the rigt path by just removing
> the strange init_net special case and performing the work once
> per module load, and once per module unload.

That makes sense to me, I'll check Gao's patchset asap to come back to
him with some feedback. Thanks.

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

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
  2012-12-28  2:36 ` [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto Gao feng
@ 2013-01-05  3:50   ` Pablo Neira Ayuso
  2013-01-07  1:27     ` Gao feng
  0 siblings, 1 reply; 39+ messages in thread
From: Pablo Neira Ayuso @ 2013-01-05  3:50 UTC (permalink / raw)
  To: Gao feng; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm

[-- Attachment #1: Type: text/plain, Size: 429 bytes --]

Hi Gao,

On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
> Currectly we unregister proto before all conntrack entries of
> this proto being destroyed. so in function destroy_conntrack
> we can't find proper l4proto to call l4proto->destroy.
> this will cause resource leak.

Good catch.

But better to remove the entries before unregistering the protocol
tracker, so l4proto->destroy is always called.

Patch attached.

[-- Attachment #2: 0001-netfilter-nf_conntrack-fix-memory-leak-during-unregi.patch --]
[-- Type: text/x-diff, Size: 1523 bytes --]

>From 1c082b3ef4c9bf8bfd0159142ce6ffc49aa7bab2 Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Fri, 4 Jan 2013 22:09:44 +0100
Subject: [PATCH] netfilter: nf_conntrack: fix memory leak during
 unregistration with GRE entries

Protocol trackers are unregistered before conntrack entries of that
type are removed. For that reason, l4proto->destroy is never called
and that results in leaking the keymap.

Fix this by releasing entries before unregistering protocols.

Reported-by: Gao feng <gaofeng@cn.fujitsu.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_conntrack_proto.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 51e928d..29cd353 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -488,6 +488,9 @@ void nf_conntrack_l4proto_unregister(struct net *net,
 {
 	struct nf_proto_net *pn = NULL;
 
+	/* Remove all contrack entries before unregistration */
+	nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
+
 	if (net == &init_net)
 		nf_conntrack_l4proto_unregister_net(l4proto);
 
@@ -497,9 +500,6 @@ void nf_conntrack_l4proto_unregister(struct net *net,
 
 	pn->users--;
 	nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
-
-	/* Remove all contrack entries for this protocol */
-	nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister);
 
-- 
1.7.10.4


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

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
  2013-01-05  3:50   ` Pablo Neira Ayuso
@ 2013-01-07  1:27     ` Gao feng
  2013-01-07  2:15       ` Pablo Neira Ayuso
  0 siblings, 1 reply; 39+ messages in thread
From: Gao feng @ 2013-01-07  1:27 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm

Hi Pablo,

On 01/05/13 11:50, Pablo Neira Ayuso wrote:
> Hi Gao,
> 
> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
>> Currectly we unregister proto before all conntrack entries of
>> this proto being destroyed. so in function destroy_conntrack
>> we can't find proper l4proto to call l4proto->destroy.
>> this will cause resource leak.
> 
> Good catch.
> 
> But better to remove the entries before unregistering the protocol
> tracker, so l4proto->destroy is always called.
> 

I think the reason we unregister proto before remove all entries
is to avoid new entry for this protocol being created.

If we remove all contrack entries before unregistration, there maybe
some new entries being created between nf_ct_iterate_cleanup and
nf_conntrack_l4proto_unregister_net.this will cause some terrible things.

SO I think we should make proto unavailable first,remove all entries next,
and remove proto from nf_ct_protos arrays finally.

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

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
  2013-01-07  1:27     ` Gao feng
@ 2013-01-07  2:15       ` Pablo Neira Ayuso
  2013-01-07  2:38         ` Pablo Neira Ayuso
  0 siblings, 1 reply; 39+ messages in thread
From: Pablo Neira Ayuso @ 2013-01-07  2:15 UTC (permalink / raw)
  To: Gao feng; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm

Hi Gao,

On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
> Hi Pablo,
> 
> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
> > Hi Gao,
> > 
> > On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
> >> Currectly we unregister proto before all conntrack entries of
> >> this proto being destroyed. so in function destroy_conntrack
> >> we can't find proper l4proto to call l4proto->destroy.
> >> this will cause resource leak.
> > 
> > Good catch.
> > 
> > But better to remove the entries before unregistering the protocol
> > tracker, so l4proto->destroy is always called.
> > 
> 
> I think the reason we unregister proto before remove all entries
> is to avoid new entry for this protocol being created.
> 
> If we remove all contrack entries before unregistration, there maybe
> some new entries being created between nf_ct_iterate_cleanup and
> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.

Leaks are less likely to happen, but may well still happen while
racing with protocol removal, agreed.

> SO I think we should make proto unavailable first,remove all entries next,
> and remove proto from nf_ct_protos arrays finally.

Your proposal adds a branch in the packet path to fix an issue that is
specific of the GRE protocol tracker. In the current code, this fixes
the memory leak while removing the nf_conntrack_proto_gre module,
which is a rare operation.

We have to come with a less intrusive solution.

Regards.

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

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
  2013-01-07  2:15       ` Pablo Neira Ayuso
@ 2013-01-07  2:38         ` Pablo Neira Ayuso
  2013-01-07  2:59           ` Gao feng
  0 siblings, 1 reply; 39+ messages in thread
From: Pablo Neira Ayuso @ 2013-01-07  2:38 UTC (permalink / raw)
  To: Gao feng; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm

On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
> Hi Gao,
> 
> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
> > Hi Pablo,
> > 
> > On 01/05/13 11:50, Pablo Neira Ayuso wrote:
> > > Hi Gao,
> > > 
> > > On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
> > >> Currectly we unregister proto before all conntrack entries of
> > >> this proto being destroyed. so in function destroy_conntrack
> > >> we can't find proper l4proto to call l4proto->destroy.
> > >> this will cause resource leak.
> > > 
> > > Good catch.
> > > 
> > > But better to remove the entries before unregistering the protocol
> > > tracker, so l4proto->destroy is always called.
> > > 
> > 
> > I think the reason we unregister proto before remove all entries
> > is to avoid new entry for this protocol being created.
> > 
> > If we remove all contrack entries before unregistration, there maybe
> > some new entries being created between nf_ct_iterate_cleanup and
> > nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
> 
> Leaks are less likely to happen, but may well still happen while
> racing with protocol removal, agreed.
> 
> > SO I think we should make proto unavailable first,remove all entries next,
> > and remove proto from nf_ct_protos arrays finally.
> 
> Your proposal adds a branch in the packet path to fix an issue that is
> specific of the GRE protocol tracker. In the current code, this fixes
> the memory leak while removing the nf_conntrack_proto_gre module,
> which is a rare operation.
> 
> We have to come with a less intrusive solution.

Wait. The existing code is calling nf_ct_gre_keymap_flush in
proto_gre_net_exit path, so those keymap objects are not leaked.

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

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
  2013-01-07  2:38         ` Pablo Neira Ayuso
@ 2013-01-07  2:59           ` Gao feng
  2013-01-07  3:05             ` Gao feng
  0 siblings, 1 reply; 39+ messages in thread
From: Gao feng @ 2013-01-07  2:59 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm

On 01/07/13 10:38, Pablo Neira Ayuso wrote:
> On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
>> Hi Gao,
>>
>> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
>>> Hi Pablo,
>>>
>>> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
>>>> Hi Gao,
>>>>
>>>> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
>>>>> Currectly we unregister proto before all conntrack entries of
>>>>> this proto being destroyed. so in function destroy_conntrack
>>>>> we can't find proper l4proto to call l4proto->destroy.
>>>>> this will cause resource leak.
>>>>
>>>> Good catch.
>>>>
>>>> But better to remove the entries before unregistering the protocol
>>>> tracker, so l4proto->destroy is always called.
>>>>
>>>
>>> I think the reason we unregister proto before remove all entries
>>> is to avoid new entry for this protocol being created.
>>>
>>> If we remove all contrack entries before unregistration, there maybe
>>> some new entries being created between nf_ct_iterate_cleanup and
>>> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
>>
>> Leaks are less likely to happen, but may well still happen while
>> racing with protocol removal, agreed.
>>
>>> SO I think we should make proto unavailable first,remove all entries next,
>>> and remove proto from nf_ct_protos arrays finally.
>>
>> Your proposal adds a branch in the packet path to fix an issue that is
>> specific of the GRE protocol tracker. In the current code, this fixes
>> the memory leak while removing the nf_conntrack_proto_gre module,
>> which is a rare operation.
>>
>> We have to come with a less intrusive solution.
> 
> Wait. The existing code is calling nf_ct_gre_keymap_flush in
> proto_gre_net_exit path, so those keymap objects are not leaked.

Agree, it looks like nf_ct_gre_keymap_flush is added to solve this
problem.

Please ignore this patch.

Thanks!

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

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
  2013-01-07  2:59           ` Gao feng
@ 2013-01-07  3:05             ` Gao feng
  2013-01-07  3:27               ` Pablo Neira Ayuso
  0 siblings, 1 reply; 39+ messages in thread
From: Gao feng @ 2013-01-07  3:05 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm

On 01/07/13 10:59, Gao feng wrote:
> On 01/07/13 10:38, Pablo Neira Ayuso wrote:
>> On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
>>> Hi Gao,
>>>
>>> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
>>>> Hi Pablo,
>>>>
>>>> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
>>>>> Hi Gao,
>>>>>
>>>>> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
>>>>>> Currectly we unregister proto before all conntrack entries of
>>>>>> this proto being destroyed. so in function destroy_conntrack
>>>>>> we can't find proper l4proto to call l4proto->destroy.
>>>>>> this will cause resource leak.
>>>>>
>>>>> Good catch.
>>>>>
>>>>> But better to remove the entries before unregistering the protocol
>>>>> tracker, so l4proto->destroy is always called.
>>>>>
>>>>
>>>> I think the reason we unregister proto before remove all entries
>>>> is to avoid new entry for this protocol being created.
>>>>
>>>> If we remove all contrack entries before unregistration, there maybe
>>>> some new entries being created between nf_ct_iterate_cleanup and
>>>> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
>>>
>>> Leaks are less likely to happen, but may well still happen while
>>> racing with protocol removal, agreed.
>>>
>>>> SO I think we should make proto unavailable first,remove all entries next,
>>>> and remove proto from nf_ct_protos arrays finally.
>>>
>>> Your proposal adds a branch in the packet path to fix an issue that is
>>> specific of the GRE protocol tracker. In the current code, this fixes
>>> the memory leak while removing the nf_conntrack_proto_gre module,
>>> which is a rare operation.
>>>
>>> We have to come with a less intrusive solution.
>>
>> Wait. The existing code is calling nf_ct_gre_keymap_flush in
>> proto_gre_net_exit path, so those keymap objects are not leaked.
> 
> Agree, it looks like nf_ct_gre_keymap_flush is added to solve this
> problem.
> 
> Please ignore this patch.

I mean ignore the codes of gre part.
I still think nf_ct_iterate_cleanup doesn't make sure all entries being
destroyed.

I will resend this patch.

Thanks!

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

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
  2013-01-07  3:05             ` Gao feng
@ 2013-01-07  3:27               ` Pablo Neira Ayuso
  2013-01-07  3:43                 ` Gao feng
  0 siblings, 1 reply; 39+ messages in thread
From: Pablo Neira Ayuso @ 2013-01-07  3:27 UTC (permalink / raw)
  To: Gao feng; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm

On Mon, Jan 07, 2013 at 11:05:12AM +0800, Gao feng wrote:
> On 01/07/13 10:59, Gao feng wrote:
> > On 01/07/13 10:38, Pablo Neira Ayuso wrote:
> >> On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
> >>> Hi Gao,
> >>>
> >>> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
> >>>> Hi Pablo,
> >>>>
> >>>> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
> >>>>> Hi Gao,
> >>>>>
> >>>>> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
> >>>>>> Currectly we unregister proto before all conntrack entries of
> >>>>>> this proto being destroyed. so in function destroy_conntrack
> >>>>>> we can't find proper l4proto to call l4proto->destroy.
> >>>>>> this will cause resource leak.
> >>>>>
> >>>>> Good catch.
> >>>>>
> >>>>> But better to remove the entries before unregistering the protocol
> >>>>> tracker, so l4proto->destroy is always called.
> >>>>>
> >>>>
> >>>> I think the reason we unregister proto before remove all entries
> >>>> is to avoid new entry for this protocol being created.
> >>>>
> >>>> If we remove all contrack entries before unregistration, there maybe
> >>>> some new entries being created between nf_ct_iterate_cleanup and
> >>>> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
> >>>
> >>> Leaks are less likely to happen, but may well still happen while
> >>> racing with protocol removal, agreed.
> >>>
> >>>> SO I think we should make proto unavailable first,remove all entries next,
> >>>> and remove proto from nf_ct_protos arrays finally.
> >>>
> >>> Your proposal adds a branch in the packet path to fix an issue that is
> >>> specific of the GRE protocol tracker. In the current code, this fixes
> >>> the memory leak while removing the nf_conntrack_proto_gre module,
> >>> which is a rare operation.
> >>>
> >>> We have to come with a less intrusive solution.
> >>
> >> Wait. The existing code is calling nf_ct_gre_keymap_flush in
> >> proto_gre_net_exit path, so those keymap objects are not leaked.
> > 
> > Agree, it looks like nf_ct_gre_keymap_flush is added to solve this
> > problem.
> > 
> > Please ignore this patch.
> 
> I mean ignore the codes of gre part.
> I still think nf_ct_iterate_cleanup doesn't make sure all entries being
> destroyed.

There is another round of nf_ct_iterate cleanup in
nf_conntrack_cleanup_net. So I don't see any possible leak so far. Let
me know if you find anything.

Thanks.

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

* Re: [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto
  2013-01-07  3:27               ` Pablo Neira Ayuso
@ 2013-01-07  3:43                 ` Gao feng
  0 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2013-01-07  3:43 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm

On 01/07/13 11:27, Pablo Neira Ayuso wrote:
> On Mon, Jan 07, 2013 at 11:05:12AM +0800, Gao feng wrote:
>> On 01/07/13 10:59, Gao feng wrote:
>>> On 01/07/13 10:38, Pablo Neira Ayuso wrote:
>>>> On Mon, Jan 07, 2013 at 03:15:17AM +0100, Pablo Neira Ayuso wrote:
>>>>> Hi Gao,
>>>>>
>>>>> On Mon, Jan 07, 2013 at 09:27:37AM +0800, Gao feng wrote:
>>>>>> Hi Pablo,
>>>>>>
>>>>>> On 01/05/13 11:50, Pablo Neira Ayuso wrote:
>>>>>>> Hi Gao,
>>>>>>>
>>>>>>> On Fri, Dec 28, 2012 at 10:36:46AM +0800, Gao feng wrote:
>>>>>>>> Currectly we unregister proto before all conntrack entries of
>>>>>>>> this proto being destroyed. so in function destroy_conntrack
>>>>>>>> we can't find proper l4proto to call l4proto->destroy.
>>>>>>>> this will cause resource leak.
>>>>>>>
>>>>>>> Good catch.
>>>>>>>
>>>>>>> But better to remove the entries before unregistering the protocol
>>>>>>> tracker, so l4proto->destroy is always called.
>>>>>>>
>>>>>>
>>>>>> I think the reason we unregister proto before remove all entries
>>>>>> is to avoid new entry for this protocol being created.
>>>>>>
>>>>>> If we remove all contrack entries before unregistration, there maybe
>>>>>> some new entries being created between nf_ct_iterate_cleanup and
>>>>>> nf_conntrack_l4proto_unregister_net.this will cause some terrible things.
>>>>>
>>>>> Leaks are less likely to happen, but may well still happen while
>>>>> racing with protocol removal, agreed.
>>>>>
>>>>>> SO I think we should make proto unavailable first,remove all entries next,
>>>>>> and remove proto from nf_ct_protos arrays finally.
>>>>>
>>>>> Your proposal adds a branch in the packet path to fix an issue that is
>>>>> specific of the GRE protocol tracker. In the current code, this fixes
>>>>> the memory leak while removing the nf_conntrack_proto_gre module,
>>>>> which is a rare operation.
>>>>>
>>>>> We have to come with a less intrusive solution.
>>>>
>>>> Wait. The existing code is calling nf_ct_gre_keymap_flush in
>>>> proto_gre_net_exit path, so those keymap objects are not leaked.
>>>
>>> Agree, it looks like nf_ct_gre_keymap_flush is added to solve this
>>> problem.
>>>
>>> Please ignore this patch.
>>
>> I mean ignore the codes of gre part.
>> I still think nf_ct_iterate_cleanup doesn't make sure all entries being
>> destroyed.
> 
> There is another round of nf_ct_iterate cleanup in
> nf_conntrack_cleanup_net. So I don't see any possible leak so far. Let
> me know if you find anything.
> 

Ok,I am wrong...
Please ignore this patch. ;)

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

* Re: [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations
  2012-12-28  8:48     ` canqun zhang
@ 2013-01-10  1:03       ` Gao feng
  0 siblings, 0 replies; 39+ messages in thread
From: Gao feng @ 2013-01-10  1:03 UTC (permalink / raw)
  To: canqun zhang
  Cc: netfilter-devel, netdev, Patrick McHardy, pablo, Eric W. Biederman

Hi canqun,

On 2012/12/28 16:48, canqun zhang wrote:
> ok, I can help you take a test, please send a big patch container this
> patchset  to my email.
> 

Can you give me your tested-by to this patchset besides patch [19/19]?
Thanks!

> 
> 2012/12/28 Gao feng <gaofeng@cn.fujitsu.com>:
>> On 12/28/12 11:52, canqun zhang wrote:
>>> Hi all
>>> As discussed above,if the host machine create several linux
>>> containers, there will be several  net namespaces.Resources with "nf
>>> conntrack" are registered or unregistered on the first net
>>> namespace(init_net),But init_net is not unregistered lastly,so
>>> cleanuping other net namespaces  will triger painic.
>>> If net namespaces are created  with the order of 1,2,...n,they should
>>> be cleaned with the order of n,...2,1,so in this case init_net will be
>>> unregistered lastly.
>>> I fixed it up (see below). I have taken a lot of test!
>>>
>>
>> I thinks this BUG is a netfilter BUG,not a netns BUG.
>> Other subsystems implemented netns support don't use init_net to
>> do some special works((un)register/(un)set).
>>
>> In fact,we can't use init_net to do this job well.such as function
>> nf_conntrack_clean,we shoud set ip_ct_attach to NULL before any
>> netns doing cleanup jobs, and set nf_ct_destroy to NULL after all of
>> netns finish these cleanup jobs.
>>
>> So I think finally we still need this patchset,And this is a regular
>> way to fix this problem.
>>
>> Can you help me to test if the panic bug is fixed by this patchset?
>> and then give me your tested-by?
>>
>> thank you very much!
> --
> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


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

* Re: [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations
  2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
                   ` (19 preceding siblings ...)
  2012-12-28  3:52 ` [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations canqun zhang
@ 2013-01-10 16:41 ` Pablo Neira Ayuso
  2013-01-11  1:01   ` Gao feng
  20 siblings, 1 reply; 39+ messages in thread
From: Pablo Neira Ayuso @ 2013-01-10 16:41 UTC (permalink / raw)
  To: Gao feng; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm

[-- Attachment #1: Type: text/plain, Size: 937 bytes --]

Hi Gao,

On Fri, Dec 28, 2012 at 10:36:27AM +0800, Gao feng wrote:
> canqun zhang reported a panic BUG,kernel may panic when
> unloading nf_conntrack module.
> 
> It's because we reset nf_ct_destroy to NULL when we deal
> with init_net,it's too early.Some packets belongs to other
> netns still refers to the conntrack.when these packets need
> to be freed, kfree_skb will call nf_ct_destroy which is
> NULL.
> 
> fix this bug by moving the nf_conntrack initialize and cleanup
> codes out of the pernet operations,this job should be done
> in module_init/exit.We can't use init_net to identify if
> it's the right time.

First off, thanks for looking into this.

I want to get this fix into 3.8 and -stable but this patch includes a
rework whose scope is net-next (upcoming 3.9).

The attached patch aims to fix the issue according to your patch
description. Once this is in, we can revisit your code refactoring
proposal.

Let me know.

[-- Attachment #2: 0001-netfilter-nf_conntrack-fix-BUG_ON-while-removing-nf_.patch --]
[-- Type: text/x-diff, Size: 2758 bytes --]

>From a211bd666fbfe17ae7171a50ad92fedc7b9e19fa Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Thu, 10 Jan 2013 16:12:01 +0100
Subject: [PATCH] netfilter: nf_conntrack: fix BUG_ON while removing
 nf_conntrack with netns

canqun zhang reported that we're hitting BUG_ON in the
nf_conntrack_destroy path when calling kfree_skb while
rmmod'ing the nf_conntrack module.

Currently, the nf_ct_destroy hook is being set to NULL in the
destroy path of conntrack.init_net. However, this is a problem
since init_net may be destroyed before any other existing netns
(we cannot assume any specific ordering while releasing existing
netns according to what I read in recent emails).

Thanks to Gao feng for initial patch to address this issue.

Reported-by: canqun zhang <canqunzhang@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/net/netfilter/nf_conntrack_core.h |    2 ++
 net/netfilter/nf_conntrack_core.c         |    9 +++++----
 net/netfilter/nf_conntrack_standalone.c   |    1 +
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index d8f5b9f..e98aeb3 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -31,6 +31,8 @@ extern void nf_conntrack_cleanup(struct net *net);
 extern int nf_conntrack_proto_init(struct net *net);
 extern void nf_conntrack_proto_fini(struct net *net);
 
+extern void nf_conntrack_cleanup_end(void);
+
 extern bool
 nf_ct_get_tuple(const struct sk_buff *skb,
 		unsigned int nhoff,
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 016d95e..e4a0c4f 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1376,11 +1376,12 @@ void nf_conntrack_cleanup(struct net *net)
 	synchronize_net();
 	nf_conntrack_proto_fini(net);
 	nf_conntrack_cleanup_net(net);
+}
 
-	if (net_eq(net, &init_net)) {
-		RCU_INIT_POINTER(nf_ct_destroy, NULL);
-		nf_conntrack_cleanup_init_net();
-	}
+void nf_conntrack_cleanup_end(void)
+{
+	RCU_INIT_POINTER(nf_ct_destroy, NULL);
+	nf_conntrack_cleanup_init_net();
 }
 
 void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 363285d..e7185c6 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -575,6 +575,7 @@ static int __init nf_conntrack_standalone_init(void)
 static void __exit nf_conntrack_standalone_fini(void)
 {
 	unregister_pernet_subsys(&nf_conntrack_net_ops);
+	nf_conntrack_cleanup_end();
 }
 
 module_init(nf_conntrack_standalone_init);
-- 
1.7.10.4


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

* Re: [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations
  2013-01-10 16:41 ` Pablo Neira Ayuso
@ 2013-01-11  1:01   ` Gao feng
  2013-01-13 15:07     ` Pablo Neira Ayuso
  0 siblings, 1 reply; 39+ messages in thread
From: Gao feng @ 2013-01-11  1:01 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm

On 2013/01/11 00:41, Pablo Neira Ayuso wrote:
> First off, thanks for looking into this.
> 
> I want to get this fix into 3.8 and -stable but this patch includes a
> rework whose scope is net-next (upcoming 3.9).
> 
> The attached patch aims to fix the issue according to your patch
> description. Once this is in, we can revisit your code refactoring
> proposal.
> 
> Let me know.
> 

Yes,I'm happy this bug being fixed in 3.8.
So what I should do is waiting for below patch being accepted and
then rebase my patchset? It's OK.
Thanks!

> 
> 0001-netfilter-nf_conntrack-fix-BUG_ON-while-removing-nf_.patch
> 
> 
>>From a211bd666fbfe17ae7171a50ad92fedc7b9e19fa Mon Sep 17 00:00:00 2001
> From: Pablo Neira Ayuso <pablo@netfilter.org>
> Date: Thu, 10 Jan 2013 16:12:01 +0100
> Subject: [PATCH] netfilter: nf_conntrack: fix BUG_ON while removing
>  nf_conntrack with netns
> 
> canqun zhang reported that we're hitting BUG_ON in the
> nf_conntrack_destroy path when calling kfree_skb while
> rmmod'ing the nf_conntrack module.
> 
> Currently, the nf_ct_destroy hook is being set to NULL in the
> destroy path of conntrack.init_net. However, this is a problem
> since init_net may be destroyed before any other existing netns
> (we cannot assume any specific ordering while releasing existing
> netns according to what I read in recent emails).
> 
> Thanks to Gao feng for initial patch to address this issue.
> 
> Reported-by: canqun zhang <canqunzhang@gmail.com>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---

Acked-by: Gao feng <gaofeng@cn.fujitsu.com>

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

* Re: [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations
  2013-01-11  1:01   ` Gao feng
@ 2013-01-13 15:07     ` Pablo Neira Ayuso
  0 siblings, 0 replies; 39+ messages in thread
From: Pablo Neira Ayuso @ 2013-01-13 15:07 UTC (permalink / raw)
  To: Gao feng; +Cc: netfilter-devel, netdev, canqunzhang, kaber, ebiederm

On Fri, Jan 11, 2013 at 09:01:36AM +0800, Gao feng wrote:
> On 2013/01/11 00:41, Pablo Neira Ayuso wrote:
> > First off, thanks for looking into this.
> > 
> > I want to get this fix into 3.8 and -stable but this patch includes a
> > rework whose scope is net-next (upcoming 3.9).
> > 
> > The attached patch aims to fix the issue according to your patch
> > description. Once this is in, we can revisit your code refactoring
> > proposal.
> > 
> > Let me know.
> > 
> 
> Yes,I'm happy this bug being fixed in 3.8.
> So what I should do is waiting for below patch being accepted and
> then rebase my patchset? It's OK.

Yes, you'll have to rebase upon nf-next. First, I have to ask David to
pull from nf to get this fixes, so you'll have to wait a bit. If any
doubt, contact me.

While at it, please, merge patches 09, 10 and 11 in one single patch.

And 12 to 18. We need that the repository has to remain consistent
between two patches.

No problem if the patch seems big as soon as changes belong to the
same scope.

> Thanks!
[...]
> Acked-by: Gao feng <gaofeng@cn.fujitsu.com>

And this patch applied, thanks a lot Gao.

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

end of thread, other threads:[~2013-01-13 15:07 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-28  2:36 [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations Gao feng
2012-12-28  2:36 ` [PATCH 02/19] netfilter: expect: move initial codes out of pernet_operations Gao feng
2012-12-28  2:36 ` [PATCH 03/19] netfilter: acct: " Gao feng
2012-12-28  2:36 ` [PATCH 04/19] netfilter: tstamp: " Gao feng
2012-12-28  2:36 ` [PATCH 05/19] netfilter: ecache: " Gao feng
2012-12-28  2:36 ` [PATCH 06/19] netfilter: timeout: " Gao feng
2012-12-28  2:36 ` [PATCH 07/19] netfilter: helper: " Gao feng
2012-12-28  2:36 ` [PATCH 08/19] netfilter: proto: " Gao feng
2012-12-28  2:36 ` [PATCH 09/19] netfilter: l3proto: prepare reworking l3proto support for netns Gao feng
2012-12-28  2:36 ` [PATCH 10/19] netfilter: ipv4: register ipv4 in module_init Gao feng
2012-12-28  2:36 ` [PATCH 10/19] netfilter: ipv4: register l3proto " Gao feng
2012-12-28  2:36 ` [PATCH 11/19] netfilter: ipv6: register l3proto ipv6 " Gao feng
2012-12-28  2:36 ` [PATCH 12/19] netfilter: l4proto: prepare reworking l4proto support for netns Gao feng
2012-12-28  2:36 ` [PATCH 13/19] netfilter: ipv4: move registration codes out of pernet_operations Gao feng
2012-12-28  2:36 ` [PATCH 14/19] netfilter: ipv6: " Gao feng
2012-12-28  2:36 ` [PATCH 15/19] netfilter: sctp: " Gao feng
2012-12-28  2:36 ` [PATCH 16/19] netfilter: udplite: " Gao feng
2012-12-28  2:36 ` [PATCH 17/19] netfilter: dccp: " Gao feng
2012-12-28  2:36 ` [PATCH 18/19] netfilter: gre: " Gao feng
2012-12-28  2:36 ` [PATCH 19/19] netfilter: gre: fix resource leak when unregister gre proto Gao feng
2013-01-05  3:50   ` Pablo Neira Ayuso
2013-01-07  1:27     ` Gao feng
2013-01-07  2:15       ` Pablo Neira Ayuso
2013-01-07  2:38         ` Pablo Neira Ayuso
2013-01-07  2:59           ` Gao feng
2013-01-07  3:05             ` Gao feng
2013-01-07  3:27               ` Pablo Neira Ayuso
2013-01-07  3:43                 ` Gao feng
2012-12-28  3:52 ` [PATCH 01/19] netfilter: move nf_conntrack initialize out of pernet operations canqun zhang
2012-12-28  4:48   ` Eric W. Biederman
2012-12-28  5:32     ` canqun zhang
2012-12-28  6:00       ` Eric W. Biederman
2012-12-28 11:58     ` Pablo Neira Ayuso
2012-12-28  7:16   ` Gao feng
2012-12-28  8:48     ` canqun zhang
2013-01-10  1:03       ` Gao feng
2013-01-10 16:41 ` Pablo Neira Ayuso
2013-01-11  1:01   ` Gao feng
2013-01-13 15:07     ` Pablo Neira Ayuso

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).