netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/13] netfilter: fix problem with proto register
@ 2012-06-21 14:36 Gao feng
  2012-06-21 14:36 ` [PATCH 02/13] netfilter: add parameter proto for l4proto.init_net Gao feng
                   ` (12 more replies)
  0 siblings, 13 replies; 23+ messages in thread
From: Gao feng @ 2012-06-21 14:36 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, Gao feng

before commit 2c352f444ccfa966a1aa4fd8e9ee29381c467448
(netfilter: nf_conntrack: prepare namespace support for
l4 protocol trackers), we register sysctl before register
protos, so if sysctl is registered faild, the protos will
not be registered.

but now, we register protos first, and when register
sysctl failed, we can use protos too, it's different
from before.

so change to register sysctl before register protos.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/netfilter/nf_conntrack_proto.c |   36 +++++++++++++++++++++++-------------
 1 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 1ea9194..9bd88aa 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -253,18 +253,23 @@ int nf_conntrack_l3proto_register(struct net *net,
 {
 	int ret = 0;
 
-	if (net == &init_net)
-		ret = nf_conntrack_l3proto_register_net(proto);
+	if (proto->init_net) {
+		ret = proto->init_net(net);
+		if (ret < 0)
+			return ret;
+	}
 
+	ret = nf_ct_l3proto_register_sysctl(net, proto);
 	if (ret < 0)
 		return ret;
 
-	if (proto->init_net) {
-		ret = proto->init_net(net);
+	if (net == &init_net) {
+		ret = nf_conntrack_l3proto_register_net(proto);
 		if (ret < 0)
-			return ret;
+			nf_ct_l3proto_unregister_sysctl(net, proto);
 	}
-	return nf_ct_l3proto_register_sysctl(net, proto);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register);
 
@@ -454,19 +459,24 @@ int nf_conntrack_l4proto_register(struct net *net,
 				  struct nf_conntrack_l4proto *l4proto)
 {
 	int ret = 0;
-	if (net == &init_net)
-		ret = nf_conntrack_l4proto_register_net(l4proto);
 
-	if (ret < 0)
-		return ret;
-
-	if (l4proto->init_net)
+	if (l4proto->init_net) {
 		ret = l4proto->init_net(net);
+		if (ret < 0)
+			return ret;
+	}
 
+	ret = nf_ct_l4proto_register_sysctl(net, l4proto);
 	if (ret < 0)
 		return ret;
 
-	return nf_ct_l4proto_register_sysctl(net, l4proto);
+	if (net == &init_net) {
+		ret = nf_conntrack_l4proto_register_net(l4proto);
+		if (ret < 0)
+			nf_ct_l4proto_unregister_sysctl(net, l4proto);
+	}
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
 
-- 
1.7.7.6


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

* [PATCH 02/13] netfilter: add parameter proto for l4proto.init_net
  2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
@ 2012-06-21 14:36 ` Gao feng
  2012-06-21 14:36 ` [PATCH 03/13] netfilter: add nf_ct_kfree_compat_sysctl_table to make codes clear Gao feng
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Gao feng @ 2012-06-21 14:36 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, Gao feng

there are redundancy codes in l4proto's init_net functions.
we can use one init_net function and l3proto to impletment
the same thing.

So we should add l3proto as a parameter for init_net function.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/net/netfilter/nf_conntrack_l4proto.h   |    2 +-
 net/ipv4/netfilter/nf_conntrack_proto_icmp.c   |    2 +-
 net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c |    2 +-
 net/netfilter/nf_conntrack_proto.c             |    5 +++--
 net/netfilter/nf_conntrack_proto_dccp.c        |    2 +-
 net/netfilter/nf_conntrack_proto_generic.c     |    2 +-
 net/netfilter/nf_conntrack_proto_gre.c         |    2 +-
 net/netfilter/nf_conntrack_proto_sctp.c        |    4 ++--
 net/netfilter/nf_conntrack_proto_tcp.c         |    4 ++--
 net/netfilter/nf_conntrack_proto_udp.c         |    4 ++--
 net/netfilter/nf_conntrack_proto_udplite.c     |    2 +-
 11 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
index 81c52b5..5dd60f2 100644
--- a/include/net/netfilter/nf_conntrack_l4proto.h
+++ b/include/net/netfilter/nf_conntrack_l4proto.h
@@ -97,7 +97,7 @@ struct nf_conntrack_l4proto {
 #endif
 	int	*net_id;
 	/* Init l4proto pernet data */
-	int (*init_net)(struct net *net);
+	int (*init_net)(struct net *net, u_int16_t proto);
 
 	/* Protocol name */
 	const char *name;
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 041923c..76f7a2f 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -337,7 +337,7 @@ static struct ctl_table icmp_compat_sysctl_table[] = {
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif /* CONFIG_SYSCTL */
 
-static int icmp_init_net(struct net *net)
+static int icmp_init_net(struct net *net, u_int16_t proto)
 {
 	struct nf_icmp_net *in = icmp_pernet(net);
 	struct nf_proto_net *pn = (struct nf_proto_net *)in;
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 63ed012..807ae09 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -333,7 +333,7 @@ static struct ctl_table icmpv6_sysctl_table[] = {
 };
 #endif /* CONFIG_SYSCTL */
 
-static int icmpv6_init_net(struct net *net)
+static int icmpv6_init_net(struct net *net, u_int16_t proto)
 {
 	struct nf_icmp_net *in = icmpv6_pernet(net);
 	struct nf_proto_net *pn = (struct nf_proto_net *)in;
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 9bd88aa..6f4b6f3 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -461,7 +461,7 @@ int nf_conntrack_l4proto_register(struct net *net,
 	int ret = 0;
 
 	if (l4proto->init_net) {
-		ret = l4proto->init_net(net);
+		ret = l4proto->init_net(net, l4proto->l3proto);
 		if (ret < 0)
 			return ret;
 	}
@@ -515,7 +515,8 @@ int nf_conntrack_proto_init(struct net *net)
 {
 	unsigned int i;
 	int err;
-	err = nf_conntrack_l4proto_generic.init_net(net);
+	err = nf_conntrack_l4proto_generic.init_net(net,
+					nf_conntrack_l4proto_generic.l3proto);
 	if (err < 0)
 		return err;
 	err = nf_ct_l4proto_register_sysctl(net,
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index c33f76a..52da8f0 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -815,7 +815,7 @@ static struct ctl_table dccp_sysctl_table[] = {
 };
 #endif /* CONFIG_SYSCTL */
 
-static int dccp_init_net(struct net *net)
+static int dccp_init_net(struct net *net, u_int16_t proto)
 {
 	struct dccp_net *dn = dccp_pernet(net);
 	struct nf_proto_net *pn = (struct nf_proto_net *)dn;
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index bb0e74f..d1ed7b4 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -135,7 +135,7 @@ static struct ctl_table generic_compat_sysctl_table[] = {
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif /* CONFIG_SYSCTL */
 
-static int generic_init_net(struct net *net)
+static int generic_init_net(struct net *net, u_int16_t proto)
 {
 	struct nf_generic_net *gn = generic_pernet(net);
 	struct nf_proto_net *pn = (struct nf_proto_net *)gn;
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 5cac41c..b09b7af 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -348,7 +348,7 @@ gre_timeout_nla_policy[CTA_TIMEOUT_GRE_MAX+1] = {
 };
 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
 
-static int gre_init_net(struct net *net)
+static int gre_init_net(struct net *net, u_int16_t proto)
 {
 	struct netns_proto_gre *net_gre = gre_pernet(net);
 	int i;
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 8fb0582..1e7836c 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -767,7 +767,7 @@ static int sctp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn)
 	return 0;
 }
 
-static int sctpv4_init_net(struct net *net)
+static int sctpv4_init_net(struct net *net, u_int16_t proto)
 {
 	int ret;
 	struct sctp_net *sn = sctp_pernet(net);
@@ -793,7 +793,7 @@ static int sctpv4_init_net(struct net *net)
 	return ret;
 }
 
-static int sctpv6_init_net(struct net *net)
+static int sctpv6_init_net(struct net *net, u_int16_t proto)
 {
 	struct sctp_net *sn = sctp_pernet(net);
 	struct nf_proto_net *pn = (struct nf_proto_net *)sn;
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 99caa13..6db9d3c 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1593,7 +1593,7 @@ static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn)
 	return 0;
 }
 
-static int tcpv4_init_net(struct net *net)
+static int tcpv4_init_net(struct net *net, u_int16_t proto)
 {
 	int i;
 	int ret = 0;
@@ -1631,7 +1631,7 @@ static int tcpv4_init_net(struct net *net)
 	return ret;
 }
 
-static int tcpv6_init_net(struct net *net)
+static int tcpv6_init_net(struct net *net, u_int16_t proto)
 {
 	int i;
 	struct nf_tcp_net *tn = tcp_pernet(net);
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index a83cf93..2b978e6 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -283,7 +283,7 @@ static void udp_init_net_data(struct nf_udp_net *un)
 	}
 }
 
-static int udpv4_init_net(struct net *net)
+static int udpv4_init_net(struct net *net, u_int16_t proto)
 {
 	int ret;
 	struct nf_udp_net *un = udp_pernet(net);
@@ -307,7 +307,7 @@ static int udpv4_init_net(struct net *net)
 	return ret;
 }
 
-static int udpv6_init_net(struct net *net)
+static int udpv6_init_net(struct net *net, u_int16_t proto)
 {
 	struct nf_udp_net *un = udp_pernet(net);
 	struct nf_proto_net *pn = (struct nf_proto_net *)un;
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index b32e700..d33e511 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -234,7 +234,7 @@ static struct ctl_table udplite_sysctl_table[] = {
 };
 #endif /* CONFIG_SYSCTL */
 
-static int udplite_init_net(struct net *net)
+static int udplite_init_net(struct net *net, u_int16_t proto)
 {
 	int i;
 	struct udplite_net *un = udplite_pernet(net);
-- 
1.7.7.6

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

* [PATCH 03/13] netfilter: add nf_ct_kfree_compat_sysctl_table to make codes clear
  2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
  2012-06-21 14:36 ` [PATCH 02/13] netfilter: add parameter proto for l4proto.init_net Gao feng
@ 2012-06-21 14:36 ` Gao feng
  2012-06-21 14:36 ` [PATCH 04/13] netfilter: regard users as refcount for l4proto's per-net data Gao feng
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Gao feng @ 2012-06-21 14:36 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, Gao feng

add function nf_ct_kfree_compat_sysctl_table to kfree l4proto's
compat sysctl table and set the compat sysctl table point to NULL.

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

diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
index 5dd60f2..08bb571 100644
--- a/include/net/netfilter/nf_conntrack_l4proto.h
+++ b/include/net/netfilter/nf_conntrack_l4proto.h
@@ -124,6 +124,14 @@ extern int nf_conntrack_l4proto_register(struct net *net,
 extern void nf_conntrack_l4proto_unregister(struct net *net,
 					    struct nf_conntrack_l4proto *proto);
 
+static inline void nf_ct_kfree_compat_sysctl_table(struct nf_proto_net *pn)
+{
+#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
+	kfree(pn->ctl_compat_table);
+	pn->ctl_compat_table = NULL;
+#endif
+}
+
 /* Generic netlink helpers */
 extern int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb,
 				      const struct nf_conntrack_tuple *tuple);
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 6f4b6f3..9d6b6ab 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -361,8 +361,7 @@ int nf_ct_l4proto_register_sysctl(struct net *net,
 		if (err == 0)
 			goto out;
 
-		kfree(pn->ctl_compat_table);
-		pn->ctl_compat_table = NULL;
+		nf_ct_kfree_compat_sysctl_table(pn);
 		nf_ct_unregister_sysctl(&pn->ctl_table_header,
 					&pn->ctl_table,
 					&pn->users);
-- 
1.7.7.6

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

* [PATCH 04/13] netfilter: regard users as refcount for l4proto's per-net data
  2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
  2012-06-21 14:36 ` [PATCH 02/13] netfilter: add parameter proto for l4proto.init_net Gao feng
  2012-06-21 14:36 ` [PATCH 03/13] netfilter: add nf_ct_kfree_compat_sysctl_table to make codes clear Gao feng
@ 2012-06-21 14:36 ` Gao feng
  2012-06-25 11:20   ` Pablo Neira Ayuso
  2012-06-21 14:36 ` [PATCH 05/13] netfilter: fix memory leak when register sysctl failed Gao feng
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 23+ messages in thread
From: Gao feng @ 2012-06-21 14:36 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, Gao feng

Now, nf_proto_net's users is confusing.
we should regard it as the refcount for l4proto's per-net data,
because maybe there are two l4protos use the same per-net data.

so increment pn->users when nf_conntrack_l4proto_register
success, and decrement it for nf_conntrack_l4_unregister case.

because nf_conntrack_l3proto_ipv[4|6] don't use the same per-net
data,so we don't need to add a refcnt for their per-net data.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/netfilter/nf_conntrack_proto.c |   76 ++++++++++++++++++++++--------------
 1 files changed, 46 insertions(+), 30 deletions(-)

diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 9d6b6ab..63612e6 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -39,16 +39,13 @@ static int
 nf_ct_register_sysctl(struct net *net,
 		      struct ctl_table_header **header,
 		      const char *path,
-		      struct ctl_table *table,
-		      unsigned int *users)
+		      struct ctl_table *table)
 {
 	if (*header == NULL) {
 		*header = register_net_sysctl(net, path, table);
 		if (*header == NULL)
 			return -ENOMEM;
 	}
-	if (users != NULL)
-		(*users)++;
 
 	return 0;
 }
@@ -56,9 +53,9 @@ nf_ct_register_sysctl(struct net *net,
 static void
 nf_ct_unregister_sysctl(struct ctl_table_header **header,
 			struct ctl_table **table,
-			unsigned int *users)
+			unsigned int users)
 {
-	if (users != NULL && --*users > 0)
+	if (users > 0)
 		return;
 
 	unregister_net_sysctl_table(*header);
@@ -191,8 +188,7 @@ static int nf_ct_l3proto_register_sysctl(struct net *net,
 		err = nf_ct_register_sysctl(net,
 					    &in->ctl_table_header,
 					    l3proto->ctl_table_path,
-					    in->ctl_table,
-					    NULL);
+					    in->ctl_table);
 		if (err < 0) {
 			kfree(in->ctl_table);
 			in->ctl_table = NULL;
@@ -213,7 +209,7 @@ static void nf_ct_l3proto_unregister_sysctl(struct net *net,
 	if (in->ctl_table_header != NULL)
 		nf_ct_unregister_sysctl(&in->ctl_table_header,
 					&in->ctl_table,
-					NULL);
+					0);
 #endif
 }
 
@@ -329,20 +325,17 @@ static struct nf_proto_net *nf_ct_l4proto_net(struct net *net,
 
 static
 int nf_ct_l4proto_register_sysctl(struct net *net,
+				  struct nf_proto_net *pn,
 				  struct nf_conntrack_l4proto *l4proto)
 {
 	int err = 0;
-	struct nf_proto_net *pn = nf_ct_l4proto_net(net, l4proto);
-	if (pn == NULL)
-		return 0;
 
 #ifdef CONFIG_SYSCTL
 	if (pn->ctl_table != NULL) {
 		err = nf_ct_register_sysctl(net,
 					    &pn->ctl_table_header,
 					    "net/netfilter",
-					    pn->ctl_table,
-					    &pn->users);
+					    pn->ctl_table);
 		if (err < 0) {
 			if (!pn->users) {
 				kfree(pn->ctl_table);
@@ -356,15 +349,14 @@ int nf_ct_l4proto_register_sysctl(struct net *net,
 		err = nf_ct_register_sysctl(net,
 					    &pn->ctl_compat_header,
 					    "net/ipv4/netfilter",
-					    pn->ctl_compat_table,
-					    NULL);
+					    pn->ctl_compat_table);
 		if (err == 0)
 			goto out;
 
 		nf_ct_kfree_compat_sysctl_table(pn);
 		nf_ct_unregister_sysctl(&pn->ctl_table_header,
 					&pn->ctl_table,
-					&pn->users);
+					pn->users);
 	}
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 out:
@@ -374,25 +366,21 @@ out:
 
 static
 void nf_ct_l4proto_unregister_sysctl(struct net *net,
+				     struct nf_proto_net *pn,
 				     struct nf_conntrack_l4proto *l4proto)
 {
-	struct nf_proto_net *pn = nf_ct_l4proto_net(net, l4proto);
-	if (pn == NULL)
-		return;
 #ifdef CONFIG_SYSCTL
 	if (pn->ctl_table_header != NULL)
 		nf_ct_unregister_sysctl(&pn->ctl_table_header,
 					&pn->ctl_table,
-					&pn->users);
+					pn->users);
 
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 	if (l4proto->l3proto != AF_INET6 && pn->ctl_compat_header != NULL)
 		nf_ct_unregister_sysctl(&pn->ctl_compat_header,
 					&pn->ctl_compat_table,
-					NULL);
+					0);
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
-#else
-	pn->users--;
 #endif /* CONFIG_SYSCTL */
 }
 
@@ -458,23 +446,32 @@ int nf_conntrack_l4proto_register(struct net *net,
 				  struct nf_conntrack_l4proto *l4proto)
 {
 	int ret = 0;
+	struct nf_proto_net *pn = NULL;
 
 	if (l4proto->init_net) {
 		ret = l4proto->init_net(net, l4proto->l3proto);
 		if (ret < 0)
-			return ret;
+			goto out;
 	}
 
-	ret = nf_ct_l4proto_register_sysctl(net, l4proto);
+	pn = nf_ct_l4proto_net(net, l4proto);
+	if (pn == NULL)
+		goto out;
+
+	ret = nf_ct_l4proto_register_sysctl(net, pn, l4proto);
 	if (ret < 0)
-		return ret;
+		goto out;
 
 	if (net == &init_net) {
 		ret = nf_conntrack_l4proto_register_net(l4proto);
-		if (ret < 0)
-			nf_ct_l4proto_unregister_sysctl(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);
@@ -499,10 +496,18 @@ nf_conntrack_l4proto_unregister_net(struct nf_conntrack_l4proto *l4proto)
 void nf_conntrack_l4proto_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);
 
-	nf_ct_l4proto_unregister_sysctl(net, l4proto);
+	pn = nf_ct_l4proto_net(net, l4proto);
+	if (pn == NULL)
+		return;
+
+	pn->users--;
+	nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
+
 	/* Remove all contrack entries for this protocol */
 	rtnl_lock();
 	nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
@@ -514,11 +519,15 @@ int nf_conntrack_proto_init(struct net *net)
 {
 	unsigned int i;
 	int err;
+	struct nf_proto_net *pn = nf_ct_l4proto_net(net,
+					&nf_conntrack_l4proto_generic);
+
 	err = nf_conntrack_l4proto_generic.init_net(net,
 					nf_conntrack_l4proto_generic.l3proto);
 	if (err < 0)
 		return err;
 	err = nf_ct_l4proto_register_sysctl(net,
+					    pn,
 					    &nf_conntrack_l4proto_generic);
 	if (err < 0)
 		return err;
@@ -528,13 +537,20 @@ int nf_conntrack_proto_init(struct net *net)
 			rcu_assign_pointer(nf_ct_l3protos[i],
 					   &nf_conntrack_l3proto_generic);
 	}
+
+	pn->users++;
 	return 0;
 }
 
 void nf_conntrack_proto_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 */
-- 
1.7.7.6


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

* [PATCH 05/13] netfilter: fix memory leak when register sysctl failed
  2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
                   ` (2 preceding siblings ...)
  2012-06-21 14:36 ` [PATCH 04/13] netfilter: regard users as refcount for l4proto's per-net data Gao feng
@ 2012-06-21 14:36 ` Gao feng
  2012-06-21 14:36 ` [PATCH 06/13] netfilter: merge tcpv[4,6]_net_init into tcp_net_init Gao feng
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Gao feng @ 2012-06-21 14:36 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, Gao feng

in nf_ct_l4proto_register_sysctl,when register l4proto' sysctl failed,
we should free the compat sysctl table.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/netfilter/nf_conntrack_proto.c |   29 ++++++++++++++++-------------
 1 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 63612e6..42e686b 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -341,25 +341,28 @@ int nf_ct_l4proto_register_sysctl(struct net *net,
 				kfree(pn->ctl_table);
 				pn->ctl_table = NULL;
 			}
-			goto out;
 		}
 	}
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 	if (l4proto->l3proto != AF_INET6 && pn->ctl_compat_table != NULL) {
-		err = nf_ct_register_sysctl(net,
-					    &pn->ctl_compat_header,
-					    "net/ipv4/netfilter",
-					    pn->ctl_compat_table);
-		if (err == 0)
-			goto out;
-
-		nf_ct_kfree_compat_sysctl_table(pn);
-		nf_ct_unregister_sysctl(&pn->ctl_table_header,
-					&pn->ctl_table,
-					pn->users);
+		if (err < 0)
+			nf_ct_kfree_compat_sysctl_table(pn);
+		else {
+			err = nf_ct_register_sysctl(net,
+						    &pn->ctl_compat_header,
+						    "net/ipv4/netfilter",
+						    pn->ctl_compat_table);
+			if (err == 0)
+				goto out;
+
+			nf_ct_kfree_compat_sysctl_table(pn);
+			nf_ct_unregister_sysctl(&pn->ctl_table_header,
+						&pn->ctl_table,
+						pn->users);
+		}
 	}
-#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 out:
+#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif /* CONFIG_SYSCTL */
 	return err;
 }
-- 
1.7.7.6


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

* [PATCH 06/13] netfilter: merge tcpv[4,6]_net_init into tcp_net_init
  2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
                   ` (3 preceding siblings ...)
  2012-06-21 14:36 ` [PATCH 05/13] netfilter: fix memory leak when register sysctl failed Gao feng
@ 2012-06-21 14:36 ` Gao feng
  2012-06-21 14:36 ` [PATCH 07/13] netfilter: merge udpv[4,6]_net_init into udp_net_init Gao feng
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Gao feng @ 2012-06-21 14:36 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, Gao feng

merge tcpv4_net_init and tcpv6_net_init into tcp_net_init to
reduce the redundancy codes.

and use nf_proto_net.users to identify if it's the first time
we use the nf_proto_net. when it's the first time,we will
initialized it.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/netfilter/nf_conntrack_proto_tcp.c |   71 +++++++++----------------------
 1 files changed, 21 insertions(+), 50 deletions(-)

diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 6db9d3c..44f0da8 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1533,11 +1533,10 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif /* CONFIG_SYSCTL */
 
-static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn)
+static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn,
+				    struct nf_tcp_net *tn)
 {
 #ifdef CONFIG_SYSCTL
-	struct nf_tcp_net *tn = (struct nf_tcp_net *)pn;
-
 	if (pn->ctl_table)
 		return 0;
 
@@ -1564,11 +1563,11 @@ static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn)
 	return 0;
 }
 
-static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn)
+static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn,
+					   struct nf_tcp_net *tn)
 {
 #ifdef CONFIG_SYSCTL
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
-	struct nf_tcp_net *tn = (struct nf_tcp_net *)pn;
 	pn->ctl_compat_table = kmemdup(tcp_compat_sysctl_table,
 				       sizeof(tcp_compat_sysctl_table),
 				       GFP_KERNEL);
@@ -1593,18 +1592,15 @@ static int tcp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn)
 	return 0;
 }
 
-static int tcpv4_init_net(struct net *net, u_int16_t proto)
+static int tcp_init_net(struct net *net, u_int16_t proto)
 {
-	int i;
-	int ret = 0;
+	int ret;
 	struct nf_tcp_net *tn = tcp_pernet(net);
-	struct nf_proto_net *pn = (struct nf_proto_net *)tn;
+	struct nf_proto_net *pn = &tn->pn;
+
+	if (!pn->users) {
+		int i;
 
-#ifdef CONFIG_SYSCTL
-	if (!pn->ctl_table) {
-#else
-	if (!pn->users++) {
-#endif
 		for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++)
 			tn->timeouts[i] = tcp_timeouts[i];
 
@@ -1613,45 +1609,20 @@ static int tcpv4_init_net(struct net *net, u_int16_t proto)
 		tn->tcp_max_retrans = nf_ct_tcp_max_retrans;
 	}
 
-	ret = tcp_kmemdup_compat_sysctl_table(pn);
-
-	if (ret < 0)
-		return ret;
+	if (proto == AF_INET) {
+		ret = tcp_kmemdup_compat_sysctl_table(pn, tn);
+		if (ret < 0)
+			return ret;
 
-	ret = tcp_kmemdup_sysctl_table(pn);
+		ret = tcp_kmemdup_sysctl_table(pn, tn);
+		if (ret < 0)
+			nf_ct_kfree_compat_sysctl_table(pn);
+	} else
+		ret = tcp_kmemdup_sysctl_table(pn, tn);
 
-#ifdef CONFIG_SYSCTL
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
-	if (ret < 0) {
-		kfree(pn->ctl_compat_table);
-		pn->ctl_compat_table = NULL;
-	}
-#endif
-#endif
 	return ret;
 }
 
-static int tcpv6_init_net(struct net *net, u_int16_t proto)
-{
-	int i;
-	struct nf_tcp_net *tn = tcp_pernet(net);
-	struct nf_proto_net *pn = (struct nf_proto_net *)tn;
-
-#ifdef CONFIG_SYSCTL
-	if (!pn->ctl_table) {
-#else
-	if (!pn->users++) {
-#endif
-		for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++)
-			tn->timeouts[i] = tcp_timeouts[i];
-		tn->tcp_loose = nf_ct_tcp_loose;
-		tn->tcp_be_liberal = nf_ct_tcp_be_liberal;
-		tn->tcp_max_retrans = nf_ct_tcp_max_retrans;
-	}
-
-	return tcp_kmemdup_sysctl_table(pn);
-}
-
 struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
 {
 	.l3proto		= PF_INET,
@@ -1684,7 +1655,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
 		.nla_policy	= tcp_timeout_nla_policy,
 	},
 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-	.init_net		= tcpv4_init_net,
+	.init_net		= tcp_init_net,
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4);
 
@@ -1720,6 +1691,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly =
 		.nla_policy	= tcp_timeout_nla_policy,
 	},
 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-	.init_net		= tcpv6_init_net,
+	.init_net		= tcp_init_net,
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);
-- 
1.7.7.6


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

* [PATCH 07/13] netfilter: merge udpv[4,6]_net_init into udp_net_init
  2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
                   ` (4 preceding siblings ...)
  2012-06-21 14:36 ` [PATCH 06/13] netfilter: merge tcpv[4,6]_net_init into tcp_net_init Gao feng
@ 2012-06-21 14:36 ` Gao feng
  2012-06-21 14:36 ` [PATCH 08/13] netfilter: nf_conntrack_l4proto_udplite[4,6] cleanup Gao feng
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Gao feng @ 2012-06-21 14:36 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, Gao feng

merge udpv4_net_init and udpv6_net_init into udp_net_init to
reduce the redundancy codes.

and use nf_proto_net.users to identify if it's the first time
we use the nf_proto_net. when it's the first time,we will
initialized it.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/netfilter/nf_conntrack_proto_udp.c |   65 +++++++++++--------------------
 1 files changed, 23 insertions(+), 42 deletions(-)

diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index 2b978e6..e7e0434 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -235,10 +235,10 @@ static struct ctl_table udp_compat_sysctl_table[] = {
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif /* CONFIG_SYSCTL */
 
-static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn)
+static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn,
+				    struct nf_udp_net *un)
 {
 #ifdef CONFIG_SYSCTL
-	struct nf_udp_net *un = (struct nf_udp_net *)pn;
 	if (pn->ctl_table)
 		return 0;
 	pn->ctl_table = kmemdup(udp_sysctl_table,
@@ -252,11 +252,11 @@ static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn)
 	return 0;
 }
 
-static int udp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn)
+static int udp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn,
+					   struct nf_udp_net *un)
 {
 #ifdef CONFIG_SYSCTL
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
-	struct nf_udp_net *un = (struct nf_udp_net *)pn;
 	pn->ctl_compat_table = kmemdup(udp_compat_sysctl_table,
 				       sizeof(udp_compat_sysctl_table),
 				       GFP_KERNEL);
@@ -270,50 +270,31 @@ static int udp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn)
 	return 0;
 }
 
-static void udp_init_net_data(struct nf_udp_net *un)
-{
-	int i;
-#ifdef CONFIG_SYSCTL
-	if (!un->pn.ctl_table) {
-#else
-	if (!un->pn.users++) {
-#endif
-		for (i = 0; i < UDP_CT_MAX; i++)
-			un->timeouts[i] = udp_timeouts[i];
-	}
-}
-
-static int udpv4_init_net(struct net *net, u_int16_t proto)
+static int udp_init_net(struct net *net, u_int16_t proto)
 {
 	int ret;
 	struct nf_udp_net *un = udp_pernet(net);
-	struct nf_proto_net *pn = (struct nf_proto_net *)un;
-
-	udp_init_net_data(un);
+	struct nf_proto_net *pn = &un->pn;
 
-	ret = udp_kmemdup_compat_sysctl_table(pn);
-	if (ret < 0)
-		return ret;
+	if (!pn->users) {
+		int i;
 
-	ret = udp_kmemdup_sysctl_table(pn);
-#ifdef CONFIG_SYSCTL
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
-	if (ret < 0) {
-		kfree(pn->ctl_compat_table);
-		pn->ctl_compat_table = NULL;
+		for (i = 0; i < UDP_CT_MAX; i++)
+			un->timeouts[i] = udp_timeouts[i];
 	}
-#endif
-#endif
-	return ret;
-}
 
-static int udpv6_init_net(struct net *net, u_int16_t proto)
-{
-	struct nf_udp_net *un = udp_pernet(net);
-	struct nf_proto_net *pn = (struct nf_proto_net *)un;
+	if (proto == AF_INET) {
+		ret = udp_kmemdup_compat_sysctl_table(pn, un);
+		if (ret < 0)
+			return ret;
 
-	udp_init_net_data(un);
-	return udp_kmemdup_sysctl_table(pn);
+		ret = udp_kmemdup_sysctl_table(pn, un);
+		if (ret < 0)
+			nf_ct_kfree_compat_sysctl_table(pn);
+	} else
+		ret = udp_kmemdup_sysctl_table(pn, un);
+
+	return ret;
 }
 
 struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly =
@@ -343,7 +324,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly =
 		.nla_policy	= udp_timeout_nla_policy,
 	},
 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-	.init_net		= udpv4_init_net,
+	.init_net		= udp_init_net,
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp4);
 
@@ -374,6 +355,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly =
 		.nla_policy	= udp_timeout_nla_policy,
 	},
 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-	.init_net		= udpv6_init_net,
+	.init_net		= udp_init_net,
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp6);
-- 
1.7.7.6


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

* [PATCH 08/13] netfilter: nf_conntrack_l4proto_udplite[4,6] cleanup
  2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
                   ` (5 preceding siblings ...)
  2012-06-21 14:36 ` [PATCH 07/13] netfilter: merge udpv[4,6]_net_init into udp_net_init Gao feng
@ 2012-06-21 14:36 ` Gao feng
  2012-06-21 14:36 ` [PATCH 09/13] netfilter: merge sctpv[4,6]_net_init into sctp_net_init Gao feng
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Gao feng @ 2012-06-21 14:36 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, Gao feng

some cleanup for nf_conntrack_l4proto_udplite[4,6],
make codes more clearer and ready for moving the
sysctl code to nf_conntrack_proto_*_sysctl.c to
reduce the ifdef pollution.

and use nf_proto_net.users to identify if it's the first time
we use the nf_proto_net. when it's the first time,we will
initialized it.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/netfilter/nf_conntrack_proto_udplite.c |   43 +++++++++++++++++-----------
 1 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index d33e511..4b66df2 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -234,29 +234,38 @@ static struct ctl_table udplite_sysctl_table[] = {
 };
 #endif /* CONFIG_SYSCTL */
 
-static int udplite_init_net(struct net *net, u_int16_t proto)
+static int udplite_kmemdup_sysctl_table(struct nf_proto_net *pn,
+					struct udplite_net *un)
 {
-	int i;
-	struct udplite_net *un = udplite_pernet(net);
-	struct nf_proto_net *pn = (struct nf_proto_net *)un;
 #ifdef CONFIG_SYSCTL
-	if (!pn->ctl_table) {
-#else
-	if (!pn->users++) {
+	if (pn->ctl_table)
+		return 0;
+
+	pn->ctl_table = kmemdup(udplite_sysctl_table,
+				sizeof(udplite_sysctl_table),
+				GFP_KERNEL);
+	if (!pn->ctl_table)
+		return -ENOMEM;
+
+	pn->ctl_table[0].data = &un->timeouts[UDPLITE_CT_UNREPLIED];
+	pn->ctl_table[1].data = &un->timeouts[UDPLITE_CT_REPLIED];
 #endif
+	return 0;
+}
+
+static int udplite_init_net(struct net *net, u_int16_t proto)
+{
+	struct udplite_net *un = udplite_pernet(net);
+	struct nf_proto_net *pn = &un->pn;
+
+	if (!pn->users) {
+		int i;
+
 		for (i = 0 ; i < UDPLITE_CT_MAX; i++)
 			un->timeouts[i] = udplite_timeouts[i];
-#ifdef CONFIG_SYSCTL
-		pn->ctl_table = kmemdup(udplite_sysctl_table,
-					sizeof(udplite_sysctl_table),
-					GFP_KERNEL);
-		if (!pn->ctl_table)
-			return -ENOMEM;
-		pn->ctl_table[0].data = &un->timeouts[UDPLITE_CT_UNREPLIED];
-		pn->ctl_table[1].data = &un->timeouts[UDPLITE_CT_REPLIED];
-#endif
 	}
-	return 0;
+
+	return udplite_kmemdup_sysctl_table(pn, un);
 }
 
 static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
-- 
1.7.7.6


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

* [PATCH 09/13] netfilter: merge sctpv[4,6]_net_init into sctp_net_init
  2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
                   ` (6 preceding siblings ...)
  2012-06-21 14:36 ` [PATCH 08/13] netfilter: nf_conntrack_l4proto_udplite[4,6] cleanup Gao feng
@ 2012-06-21 14:36 ` Gao feng
  2012-06-21 14:36 ` [PATCH 10/13] netfilter: nf_conntrack_l4proto_generic cleanup Gao feng
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Gao feng @ 2012-06-21 14:36 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, Gao feng

merge sctpv4_net_init and sctpv6_net_init into sctp_net_init to
reduce the redundancy codes.

and use nf_proto_net.users to identify if it's the first time
we use the nf_proto_net. when it's the first time,we will
initialized it.

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

diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 1e7836c..c746d61 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -707,23 +707,10 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif
 
-static void sctp_init_net_data(struct sctp_net *sn)
-{
-	int i;
-#ifdef CONFIG_SYSCTL
-	if (!sn->pn.ctl_table) {
-#else
-	if (!sn->pn.users++) {
-#endif
-		for (i = 0; i < SCTP_CONNTRACK_MAX; i++)
-			sn->timeouts[i] = sctp_timeouts[i];
-	}
-}
-
-static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn)
+static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn,
+				     struct sctp_net *sn)
 {
 #ifdef CONFIG_SYSCTL
-	struct sctp_net *sn = (struct sctp_net *)pn;
 	if (pn->ctl_table)
 		return 0;
 
@@ -744,11 +731,11 @@ static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn)
 	return 0;
 }
 
-static int sctp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn)
+static int sctp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn,
+					    struct sctp_net *sn)
 {
 #ifdef CONFIG_SYSCTL
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
-	struct sctp_net *sn = (struct sctp_net *)pn;
 	pn->ctl_compat_table = kmemdup(sctp_compat_sysctl_table,
 				       sizeof(sctp_compat_sysctl_table),
 				       GFP_KERNEL);
@@ -767,41 +754,33 @@ static int sctp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn)
 	return 0;
 }
 
-static int sctpv4_init_net(struct net *net, u_int16_t proto)
+static int sctp_init_net(struct net *net, u_int16_t proto)
 {
 	int ret;
 	struct sctp_net *sn = sctp_pernet(net);
-	struct nf_proto_net *pn = (struct nf_proto_net *)sn;
+	struct nf_proto_net *pn = &sn->pn;
 
-	sctp_init_net_data(sn);
+	if (!pn->users) {
+		int i;
 
-	ret = sctp_kmemdup_compat_sysctl_table(pn);
-	if (ret < 0)
-		return ret;
+		for (i = 0; i < SCTP_CONNTRACK_MAX; i++)
+			sn->timeouts[i] = sctp_timeouts[i];
+	}
 
-	ret = sctp_kmemdup_sysctl_table(pn);
+	if (proto == AF_INET) {
+		ret = sctp_kmemdup_compat_sysctl_table(pn, sn);
+		if (ret < 0)
+			return ret;
 
-#ifdef CONFIG_SYSCTL
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
-	if (ret < 0) {
+		ret = sctp_kmemdup_sysctl_table(pn, sn);
+		if (ret < 0)
+			nf_ct_kfree_compat_sysctl_table(pn);
+	} else
+		ret = sctp_kmemdup_sysctl_table(pn, sn);
 
-		kfree(pn->ctl_compat_table);
-		pn->ctl_compat_table = NULL;
-	}
-#endif
-#endif
 	return ret;
 }
 
-static int sctpv6_init_net(struct net *net, u_int16_t proto)
-{
-	struct sctp_net *sn = sctp_pernet(net);
-	struct nf_proto_net *pn = (struct nf_proto_net *)sn;
-
-	sctp_init_net_data(sn);
-	return sctp_kmemdup_sysctl_table(pn);
-}
-
 static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
 	.l3proto		= PF_INET,
 	.l4proto 		= IPPROTO_SCTP,
@@ -833,7 +812,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
 	},
 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
 	.net_id			= &sctp_net_id,
-	.init_net		= sctpv4_init_net,
+	.init_net		= sctp_init_net,
 };
 
 static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
@@ -867,7 +846,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
 #endif
 	.net_id			= &sctp_net_id,
-	.init_net		= sctpv6_init_net,
+	.init_net		= sctp_init_net,
 };
 
 static int sctp_net_init(struct net *net)
-- 
1.7.7.6

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

* [PATCH 10/13] netfilter: nf_conntrack_l4proto_generic cleanup
  2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
                   ` (7 preceding siblings ...)
  2012-06-21 14:36 ` [PATCH 09/13] netfilter: merge sctpv[4,6]_net_init into sctp_net_init Gao feng
@ 2012-06-21 14:36 ` Gao feng
  2012-06-21 14:36 ` [PATCH 11/13] netfilter: nf_conntrack_l4proto_dccp[4,6] cleanup Gao feng
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Gao feng @ 2012-06-21 14:36 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, Gao feng

some cleanup of nf_conntrack_l4proto_generic,
split the code to make it more clearer.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/netfilter/nf_conntrack_proto_generic.c |   39 ++++++++++++++++++++++-----
 1 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index d1ed7b4..7c11c54 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -135,34 +135,57 @@ static struct ctl_table generic_compat_sysctl_table[] = {
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif /* CONFIG_SYSCTL */
 
-static int generic_init_net(struct net *net, u_int16_t proto)
+static int generic_kmemdup_sysctl_table(struct nf_proto_net *pn,
+					struct nf_generic_net *gn)
 {
-	struct nf_generic_net *gn = generic_pernet(net);
-	struct nf_proto_net *pn = (struct nf_proto_net *)gn;
-	gn->timeout = nf_ct_generic_timeout;
 #ifdef CONFIG_SYSCTL
 	pn->ctl_table = kmemdup(generic_sysctl_table,
 				sizeof(generic_sysctl_table),
 				GFP_KERNEL);
 	if (!pn->ctl_table)
 		return -ENOMEM;
+
 	pn->ctl_table[0].data = &gn->timeout;
+#endif
+	return 0;
+}
 
+static int generic_kmemdup_compat_sysctl_table(struct nf_proto_net *pn,
+					       struct nf_generic_net *gn)
+{
+#ifdef CONFIG_SYSCTL
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 	pn->ctl_compat_table = kmemdup(generic_compat_sysctl_table,
 				       sizeof(generic_compat_sysctl_table),
 				       GFP_KERNEL);
-	if (!pn->ctl_compat_table) {
-		kfree(pn->ctl_table);
-		pn->ctl_table = NULL;
+	if (!pn->ctl_compat_table)
 		return -ENOMEM;
-	}
+
 	pn->ctl_compat_table[0].data = &gn->timeout;
 #endif
 #endif
 	return 0;
 }
 
+static int generic_init_net(struct net *net, u_int16_t proto)
+{
+	int ret;
+	struct nf_generic_net *gn = generic_pernet(net);
+	struct nf_proto_net *pn = &gn->pn;
+
+	gn->timeout = nf_ct_generic_timeout;
+
+	ret = generic_kmemdup_compat_sysctl_table(pn, gn);
+	if (ret < 0)
+		return ret;
+
+	ret = generic_kmemdup_sysctl_table(pn, gn);
+	if (ret < 0)
+		nf_ct_kfree_compat_sysctl_table(pn);
+
+	return ret;
+}
+
 struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
 {
 	.l3proto		= PF_UNSPEC,
-- 
1.7.7.6


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

* [PATCH 11/13] netfilter: nf_conntrack_l4proto_dccp[4,6] cleanup
  2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
                   ` (8 preceding siblings ...)
  2012-06-21 14:36 ` [PATCH 10/13] netfilter: nf_conntrack_l4proto_generic cleanup Gao feng
@ 2012-06-21 14:36 ` Gao feng
  2012-06-21 14:36 ` [PATCH 12/13] netfilter: nf_conntrack_l4proto_icmp cleanup Gao feng
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 23+ messages in thread
From: Gao feng @ 2012-06-21 14:36 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, Gao feng

some cleanup of nf_conntrack_l4proto_dccp[4,6],
make codes more clearer and ready for moving the
sysctl code to nf_conntrack_proto_*_sysctl.c to
reduce the ifdef pollution.

and use nf_proto_net.users to identify if it's the first time
we use the nf_proto_net. when it's the first time,we will
initialized it.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/netfilter/nf_conntrack_proto_dccp.c |   54 +++++++++++++++++--------------
 1 files changed, 30 insertions(+), 24 deletions(-)

diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index 52da8f0..6535326 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -387,7 +387,7 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] =
 /* this module per-net specifics */
 static int dccp_net_id __read_mostly;
 struct dccp_net {
-	struct nf_proto_net np;
+	struct nf_proto_net pn;
 	int dccp_loose;
 	unsigned int dccp_timeout[CT_DCCP_MAX + 1];
 };
@@ -815,16 +815,37 @@ static struct ctl_table dccp_sysctl_table[] = {
 };
 #endif /* CONFIG_SYSCTL */
 
+static int dccp_kmemdup_sysctl_table(struct nf_proto_net *pn,
+				     struct dccp_net *dn)
+{
+#ifdef CONFIG_SYSCTL
+	if (pn->ctl_table)
+		return 0;
+
+	pn->ctl_table = kmemdup(dccp_sysctl_table,
+				sizeof(dccp_sysctl_table),
+				GFP_KERNEL);
+	if (!pn->ctl_table)
+		return -ENOMEM;
+
+	pn->ctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST];
+	pn->ctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND];
+	pn->ctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN];
+	pn->ctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN];
+	pn->ctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ];
+	pn->ctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING];
+	pn->ctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT];
+	pn->ctl_table[7].data = &dn->dccp_loose;
+#endif
+	return 0;
+}
+
 static int dccp_init_net(struct net *net, u_int16_t proto)
 {
 	struct dccp_net *dn = dccp_pernet(net);
-	struct nf_proto_net *pn = (struct nf_proto_net *)dn;
+	struct nf_proto_net *pn = &dn->pn;
 
-#ifdef CONFIG_SYSCTL
-	if (!pn->ctl_table) {
-#else
-	if (!pn->users++) {
-#endif
+	if (!pn->users) {
 		/* default values */
 		dn->dccp_loose = 1;
 		dn->dccp_timeout[CT_DCCP_REQUEST]	= 2 * DCCP_MSL;
@@ -834,24 +855,9 @@ static int dccp_init_net(struct net *net, u_int16_t proto)
 		dn->dccp_timeout[CT_DCCP_CLOSEREQ]	= 64 * HZ;
 		dn->dccp_timeout[CT_DCCP_CLOSING]	= 64 * HZ;
 		dn->dccp_timeout[CT_DCCP_TIMEWAIT]	= 2 * DCCP_MSL;
-#ifdef CONFIG_SYSCTL
-		pn->ctl_table = kmemdup(dccp_sysctl_table,
-					sizeof(dccp_sysctl_table),
-					GFP_KERNEL);
-		if (!pn->ctl_table)
-			return -ENOMEM;
-
-		pn->ctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST];
-		pn->ctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND];
-		pn->ctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN];
-		pn->ctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN];
-		pn->ctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ];
-		pn->ctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING];
-		pn->ctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT];
-		pn->ctl_table[7].data = &dn->dccp_loose;
-#endif
 	}
-	return 0;
+
+	return dccp_kmemdup_sysctl_table(pn, dn);
 }
 
 static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = {
-- 
1.7.7.6

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

* [PATCH 12/13] netfilter: nf_conntrack_l4proto_icmp cleanup
  2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
                   ` (9 preceding siblings ...)
  2012-06-21 14:36 ` [PATCH 11/13] netfilter: nf_conntrack_l4proto_dccp[4,6] cleanup Gao feng
@ 2012-06-21 14:36 ` Gao feng
  2012-06-21 14:36 ` [PATCH 13/13] netfilter: nf_conntrack_l4proto_icmpv6 cleanup Gao feng
  2012-06-25 11:12 ` [PATCH 01/13] netfilter: fix problem with proto register Pablo Neira Ayuso
  12 siblings, 0 replies; 23+ messages in thread
From: Gao feng @ 2012-06-21 14:36 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, Gao feng

add two functions icmp_kmemdup_sysctl_table and
icmp_kmemdup_compat_sysctl_table to make codes more
clearer.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/ipv4/netfilter/nf_conntrack_proto_icmp.c |   41 ++++++++++++++++++++------
 1 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 76f7a2f..9c2095c 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -337,34 +337,57 @@ static struct ctl_table icmp_compat_sysctl_table[] = {
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif /* CONFIG_SYSCTL */
 
-static int icmp_init_net(struct net *net, u_int16_t proto)
+static int icmp_kmemdup_sysctl_table(struct nf_proto_net *pn,
+				     struct nf_icmp_net *in)
 {
-	struct nf_icmp_net *in = icmp_pernet(net);
-	struct nf_proto_net *pn = (struct nf_proto_net *)in;
-	in->timeout = nf_ct_icmp_timeout;
-
 #ifdef CONFIG_SYSCTL
 	pn->ctl_table = kmemdup(icmp_sysctl_table,
 				sizeof(icmp_sysctl_table),
 				GFP_KERNEL);
 	if (!pn->ctl_table)
 		return -ENOMEM;
+
 	pn->ctl_table[0].data = &in->timeout;
+#endif
+	return 0;
+}
+
+static int icmp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn,
+					    struct nf_icmp_net *in)
+{
+#ifdef CONFIG_SYSCTL
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 	pn->ctl_compat_table = kmemdup(icmp_compat_sysctl_table,
 				       sizeof(icmp_compat_sysctl_table),
 				       GFP_KERNEL);
-	if (!pn->ctl_compat_table) {
-		kfree(pn->ctl_table);
-		pn->ctl_table = NULL;
+	if (!pn->ctl_compat_table)
 		return -ENOMEM;
-	}
+
 	pn->ctl_compat_table[0].data = &in->timeout;
 #endif
 #endif
 	return 0;
 }
 
+static int icmp_init_net(struct net *net, u_int16_t proto)
+{
+	int ret;
+	struct nf_icmp_net *in = icmp_pernet(net);
+	struct nf_proto_net *pn = &in->pn;
+
+	in->timeout = nf_ct_icmp_timeout;
+
+	ret = icmp_kmemdup_compat_sysctl_table(pn, in);
+	if (ret < 0)
+		return ret;
+
+	ret = icmp_kmemdup_sysctl_table(pn, in);
+	if (ret < 0)
+		nf_ct_kfree_compat_sysctl_table(pn);
+
+	return ret;
+}
+
 struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly =
 {
 	.l3proto		= PF_INET,
-- 
1.7.7.6


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

* [PATCH 13/13] netfilter: nf_conntrack_l4proto_icmpv6 cleanup
  2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
                   ` (10 preceding siblings ...)
  2012-06-21 14:36 ` [PATCH 12/13] netfilter: nf_conntrack_l4proto_icmp cleanup Gao feng
@ 2012-06-21 14:36 ` Gao feng
  2012-06-25 11:12 ` [PATCH 01/13] netfilter: fix problem with proto register Pablo Neira Ayuso
  12 siblings, 0 replies; 23+ messages in thread
From: Gao feng @ 2012-06-21 14:36 UTC (permalink / raw)
  To: pablo; +Cc: netdev, netfilter-devel, Gao feng

add function icmpv6_kmemdup_sysctl_table to make codes
more clearer.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c |   17 +++++++++++++----
 1 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 807ae09..9fc5cf5 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -333,22 +333,31 @@ static struct ctl_table icmpv6_sysctl_table[] = {
 };
 #endif /* CONFIG_SYSCTL */
 
-static int icmpv6_init_net(struct net *net, u_int16_t proto)
+static int icmpv6_kmemdup_sysctl_table(struct nf_proto_net *pn,
+				       struct nf_icmp_net *in)
 {
-	struct nf_icmp_net *in = icmpv6_pernet(net);
-	struct nf_proto_net *pn = (struct nf_proto_net *)in;
-	in->timeout = nf_ct_icmpv6_timeout;
 #ifdef CONFIG_SYSCTL
 	pn->ctl_table = kmemdup(icmpv6_sysctl_table,
 				sizeof(icmpv6_sysctl_table),
 				GFP_KERNEL);
 	if (!pn->ctl_table)
 		return -ENOMEM;
+
 	pn->ctl_table[0].data = &in->timeout;
 #endif
 	return 0;
 }
 
+static int icmpv6_init_net(struct net *net, u_int16_t proto)
+{
+	struct nf_icmp_net *in = icmpv6_pernet(net);
+	struct nf_proto_net *pn = &in->pn;
+
+	in->timeout = nf_ct_icmpv6_timeout;
+
+	return icmpv6_kmemdup_sysctl_table(pn, in);
+}
+
 struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly =
 {
 	.l3proto		= PF_INET6,
-- 
1.7.7.6


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

* Re: [PATCH 01/13] netfilter: fix problem with proto register
  2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
                   ` (11 preceding siblings ...)
  2012-06-21 14:36 ` [PATCH 13/13] netfilter: nf_conntrack_l4proto_icmpv6 cleanup Gao feng
@ 2012-06-25 11:12 ` Pablo Neira Ayuso
  2012-06-26  3:40   ` Gao feng
  12 siblings, 1 reply; 23+ messages in thread
From: Pablo Neira Ayuso @ 2012-06-25 11:12 UTC (permalink / raw)
  To: Gao feng; +Cc: netdev, netfilter-devel

On Thu, Jun 21, 2012 at 10:36:38PM +0800, Gao feng wrote:
> before commit 2c352f444ccfa966a1aa4fd8e9ee29381c467448
> (netfilter: nf_conntrack: prepare namespace support for
> l4 protocol trackers), we register sysctl before register
> protos, so if sysctl is registered faild, the protos will
> not be registered.
> 
> but now, we register protos first, and when register
> sysctl failed, we can use protos too, it's different
> from before.

No, this has to be an all-or-nothing game. If one fails, everything
else that you've registered has to be unregistered.

> so change to register sysctl before register protos.
> 
> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
> ---
>  net/netfilter/nf_conntrack_proto.c |   36 +++++++++++++++++++++++-------------
>  1 files changed, 23 insertions(+), 13 deletions(-)
> 
> diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
> index 1ea9194..9bd88aa 100644
> --- a/net/netfilter/nf_conntrack_proto.c
> +++ b/net/netfilter/nf_conntrack_proto.c
> @@ -253,18 +253,23 @@ int nf_conntrack_l3proto_register(struct net *net,
>  {
>  	int ret = 0;
>  
> -	if (net == &init_net)
> -		ret = nf_conntrack_l3proto_register_net(proto);
> +	if (proto->init_net) {
> +		ret = proto->init_net(net);
> +		if (ret < 0)
> +			return ret;
> +	}
>  
> +	ret = nf_ct_l3proto_register_sysctl(net, proto);
>  	if (ret < 0)
>  		return ret;

This is still wrong.

If nf_ct_l3proto_register_sysctl fails, we'll leak the memory that has
been reserved by proto->init_net.

> -	if (proto->init_net) {
> -		ret = proto->init_net(net);
> +	if (net == &init_net) {
> +		ret = nf_conntrack_l3proto_register_net(proto);
>  		if (ret < 0)
> -			return ret;
> +			nf_ct_l3proto_unregister_sysctl(net, proto);
>  	}
> -	return nf_ct_l3proto_register_sysctl(net, proto);
> +
> +	return ret;
>  }
>  EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register);
>  
> @@ -454,19 +459,24 @@ int nf_conntrack_l4proto_register(struct net *net,
>  				  struct nf_conntrack_l4proto *l4proto)
>  {
>  	int ret = 0;
> -	if (net == &init_net)
> -		ret = nf_conntrack_l4proto_register_net(l4proto);
>  
> -	if (ret < 0)
> -		return ret;
> -
> -	if (l4proto->init_net)
> +	if (l4proto->init_net) {
>  		ret = l4proto->init_net(net);
> +		if (ret < 0)
> +			return ret;
> +	}
>  
> +	ret = nf_ct_l4proto_register_sysctl(net, l4proto);
>  	if (ret < 0)
>  		return ret;
>  
> -	return nf_ct_l4proto_register_sysctl(net, l4proto);
> +	if (net == &init_net) {
> +		ret = nf_conntrack_l4proto_register_net(l4proto);
> +		if (ret < 0)
> +			nf_ct_l4proto_unregister_sysctl(net, l4proto);
> +	}
> +
> +	return ret;
>  }
>  EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
>  
> -- 
> 1.7.7.6
> 
> --
> 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] 23+ messages in thread

* Re: [PATCH 04/13] netfilter: regard users as refcount for l4proto's per-net data
  2012-06-21 14:36 ` [PATCH 04/13] netfilter: regard users as refcount for l4proto's per-net data Gao feng
@ 2012-06-25 11:20   ` Pablo Neira Ayuso
  2012-06-26  3:58     ` Gao feng
  0 siblings, 1 reply; 23+ messages in thread
From: Pablo Neira Ayuso @ 2012-06-25 11:20 UTC (permalink / raw)
  To: Gao feng; +Cc: netdev, netfilter-devel

On Thu, Jun 21, 2012 at 10:36:41PM +0800, Gao feng wrote:
> Now, nf_proto_net's users is confusing.
> we should regard it as the refcount for l4proto's per-net data,
> because maybe there are two l4protos use the same per-net data.
> 
> so increment pn->users when nf_conntrack_l4proto_register
> success, and decrement it for nf_conntrack_l4_unregister case.
> 
> because nf_conntrack_l3proto_ipv[4|6] don't use the same per-net
> data,so we don't need to add a refcnt for their per-net data.
> 
> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
> ---
>  net/netfilter/nf_conntrack_proto.c |   76 ++++++++++++++++++++++--------------
>  1 files changed, 46 insertions(+), 30 deletions(-)
> 
> diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
> index 9d6b6ab..63612e6 100644
> --- a/net/netfilter/nf_conntrack_proto.c
> +++ b/net/netfilter/nf_conntrack_proto.c
[...]
> @@ -458,23 +446,32 @@ int nf_conntrack_l4proto_register(struct net *net,
>  				  struct nf_conntrack_l4proto *l4proto)
>  {
>  	int ret = 0;
> +	struct nf_proto_net *pn = NULL;
>  
>  	if (l4proto->init_net) {
>  		ret = l4proto->init_net(net, l4proto->l3proto);
>  		if (ret < 0)
> -			return ret;
> +			goto out;
>  	}
>  
> -	ret = nf_ct_l4proto_register_sysctl(net, l4proto);
> +	pn = nf_ct_l4proto_net(net, l4proto);
> +	if (pn == NULL)
> +		goto out;

Same thing here, we're leaking memory allocated by l4proto->init_net.

> +	ret = nf_ct_l4proto_register_sysctl(net, pn, l4proto);
>  	if (ret < 0)
> -		return ret;
> +		goto out;
>  
>  	if (net == &init_net) {
>  		ret = nf_conntrack_l4proto_register_net(l4proto);
> -		if (ret < 0)
> -			nf_ct_l4proto_unregister_sysctl(net, l4proto);
> +		if (ret < 0) {
> +			nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
> +			goto out;

Better replace the two lines above by:

goto out_register_net;

and then...

> +		}
>  	}
>  
> +	pn->users++;

out_register_net:
        nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);

> +out:
>  	return ret;

I think that this change is similar to patch 1/1, I think you should
send it as a separated patch.

>  }
>  EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
> @@ -499,10 +496,18 @@ nf_conntrack_l4proto_unregister_net(struct nf_conntrack_l4proto *l4proto)
>  void nf_conntrack_l4proto_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);
>  
> -	nf_ct_l4proto_unregister_sysctl(net, l4proto);
> +	pn = nf_ct_l4proto_net(net, l4proto);
> +	if (pn == NULL)
> +		return;
> +
> +	pn->users--;
> +	nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
> +
>  	/* Remove all contrack entries for this protocol */
>  	rtnl_lock();
>  	nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
> @@ -514,11 +519,15 @@ int nf_conntrack_proto_init(struct net *net)
>  {
>  	unsigned int i;
>  	int err;
> +	struct nf_proto_net *pn = nf_ct_l4proto_net(net,
> +					&nf_conntrack_l4proto_generic);
> +
>  	err = nf_conntrack_l4proto_generic.init_net(net,
>  					nf_conntrack_l4proto_generic.l3proto);
>  	if (err < 0)
>  		return err;
>  	err = nf_ct_l4proto_register_sysctl(net,
> +					    pn,
>  					    &nf_conntrack_l4proto_generic);
>  	if (err < 0)
>  		return err;
> @@ -528,13 +537,20 @@ int nf_conntrack_proto_init(struct net *net)
>  			rcu_assign_pointer(nf_ct_l3protos[i],
>  					   &nf_conntrack_l3proto_generic);
>  	}
> +
> +	pn->users++;
>  	return 0;
>  }
>  
>  void nf_conntrack_proto_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 */
> -- 
> 1.7.7.6
> 

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

* Re: [PATCH 01/13] netfilter: fix problem with proto register
  2012-06-25 11:12 ` [PATCH 01/13] netfilter: fix problem with proto register Pablo Neira Ayuso
@ 2012-06-26  3:40   ` Gao feng
  2012-06-26 14:36     ` Pablo Neira Ayuso
  0 siblings, 1 reply; 23+ messages in thread
From: Gao feng @ 2012-06-26  3:40 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netdev, netfilter-devel

Hi Pablo:

于 2012年06月25日 19:12, Pablo Neira Ayuso 写道:
> On Thu, Jun 21, 2012 at 10:36:38PM +0800, Gao feng wrote:
>> before commit 2c352f444ccfa966a1aa4fd8e9ee29381c467448
>> (netfilter: nf_conntrack: prepare namespace support for
>> l4 protocol trackers), we register sysctl before register
>> protos, so if sysctl is registered faild, the protos will
>> not be registered.
>>
>> but now, we register protos first, and when register
>> sysctl failed, we can use protos too, it's different
>> from before.
> 
> No, this has to be an all-or-nothing game. If one fails, everything
> else that you've registered has to be unregistered.

indeed,this is an all-or-nothing game right now,please look at the ipv4_net_init,
when we register nf_conntrack_l3proto_ipv4 failed,we will unregister the already
registered l4protoes, and in nf_conntrack_l4proto_unregister,we will call
nf_ct_l4proto_unregister_sysctl to free the sysctl table.

> 
>> so change to register sysctl before register protos.
>>
>> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
>> ---
>>  net/netfilter/nf_conntrack_proto.c |   36 +++++++++++++++++++++++-------------
>>  1 files changed, 23 insertions(+), 13 deletions(-)
>>
>> diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
>> index 1ea9194..9bd88aa 100644
>> --- a/net/netfilter/nf_conntrack_proto.c
>> +++ b/net/netfilter/nf_conntrack_proto.c
>> @@ -253,18 +253,23 @@ int nf_conntrack_l3proto_register(struct net *net,
>>  {
>>  	int ret = 0;
>>  
>> -	if (net == &init_net)
>> -		ret = nf_conntrack_l3proto_register_net(proto);
>> +	if (proto->init_net) {
>> +		ret = proto->init_net(net);
>> +		if (ret < 0)
>> +			return ret;
>> +	}
>>  
>> +	ret = nf_ct_l3proto_register_sysctl(net, proto);
>>  	if (ret < 0)
>>  		return ret;
> 
> This is still wrong.
> 
> If nf_ct_l3proto_register_sysctl fails, we'll leak the memory that has
> been reserved by proto->init_net.
> 

we have freed the memory in nf_ct_l[3,4]proto_register_sysctl when we
call nf_ct_register_sysctl failed, so there is no need to free this memory
in nf_conntrack_l[3,4]proto_register.

>> -	if (proto->init_net) {
>> -		ret = proto->init_net(net);
>> +	if (net == &init_net) {
>> +		ret = nf_conntrack_l3proto_register_net(proto);
>>  		if (ret < 0)
>> -			return ret;
>> +			nf_ct_l3proto_unregister_sysctl(net, proto);
>>  	}
>> -	return nf_ct_l3proto_register_sysctl(net, proto);
>> +
>> +	return ret;
>>  }
>>  EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register);
>>  
>> @@ -454,19 +459,24 @@ int nf_conntrack_l4proto_register(struct net *net,
>>  				  struct nf_conntrack_l4proto *l4proto)
>>  {
>>  	int ret = 0;
>> -	if (net == &init_net)
>> -		ret = nf_conntrack_l4proto_register_net(l4proto);
>>  
>> -	if (ret < 0)
>> -		return ret;
>> -
>> -	if (l4proto->init_net)
>> +	if (l4proto->init_net) {
>>  		ret = l4proto->init_net(net);
>> +		if (ret < 0)
>> +			return ret;
>> +	}
>>  
>> +	ret = nf_ct_l4proto_register_sysctl(net, l4proto);
>>  	if (ret < 0)
>>  		return ret;
>>  
>> -	return nf_ct_l4proto_register_sysctl(net, l4proto);
>> +	if (net == &init_net) {
>> +		ret = nf_conntrack_l4proto_register_net(l4proto);
>> +		if (ret < 0)
>> +			nf_ct_l4proto_unregister_sysctl(net, l4proto);
>> +	}
>> +
>> +	return ret;
>>  }
>>  EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
>>  
>> -- 
>> 1.7.7.6
>>
>> --
>> 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
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

* Re: [PATCH 04/13] netfilter: regard users as refcount for l4proto's per-net data
  2012-06-25 11:20   ` Pablo Neira Ayuso
@ 2012-06-26  3:58     ` Gao feng
  2012-06-26 14:47       ` Pablo Neira Ayuso
  0 siblings, 1 reply; 23+ messages in thread
From: Gao feng @ 2012-06-26  3:58 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netdev, netfilter-devel

Hi Pablo:
于 2012年06月25日 19:20, Pablo Neira Ayuso 写道:
> On Thu, Jun 21, 2012 at 10:36:41PM +0800, Gao feng wrote:
>> Now, nf_proto_net's users is confusing.
>> we should regard it as the refcount for l4proto's per-net data,
>> because maybe there are two l4protos use the same per-net data.
>>
>> so increment pn->users when nf_conntrack_l4proto_register
>> success, and decrement it for nf_conntrack_l4_unregister case.
>>
>> because nf_conntrack_l3proto_ipv[4|6] don't use the same per-net
>> data,so we don't need to add a refcnt for their per-net data.
>>
>> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
>> ---
>>  net/netfilter/nf_conntrack_proto.c |   76 ++++++++++++++++++++++--------------
>>  1 files changed, 46 insertions(+), 30 deletions(-)
>>
>> diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
>> index 9d6b6ab..63612e6 100644
>> --- a/net/netfilter/nf_conntrack_proto.c
>> +++ b/net/netfilter/nf_conntrack_proto.c
> [...]
>> @@ -458,23 +446,32 @@ int nf_conntrack_l4proto_register(struct net *net,
>>  				  struct nf_conntrack_l4proto *l4proto)
>>  {
>>  	int ret = 0;
>> +	struct nf_proto_net *pn = NULL;
>>  
>>  	if (l4proto->init_net) {
>>  		ret = l4proto->init_net(net, l4proto->l3proto);
>>  		if (ret < 0)
>> -			return ret;
>> +			goto out;
>>  	}
>>  
>> -	ret = nf_ct_l4proto_register_sysctl(net, l4proto);
>> +	pn = nf_ct_l4proto_net(net, l4proto);
>> +	if (pn == NULL)
>> +		goto out;
> 
> Same thing here, we're leaking memory allocated by l4proto->init_net.

if pn is NULL,init_net can't allocate memory for pn->ctl_table.
So I think it's not memory leak here.

> 
>> +	ret = nf_ct_l4proto_register_sysctl(net, pn, l4proto);
>>  	if (ret < 0)
>> -		return ret;
>> +		goto out;
>>  
>>  	if (net == &init_net) {
>>  		ret = nf_conntrack_l4proto_register_net(l4proto);
>> -		if (ret < 0)
>> -			nf_ct_l4proto_unregister_sysctl(net, l4proto);
>> +		if (ret < 0) {
>> +			nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
>> +			goto out;
> 
> Better replace the two lines above by:
> 
> goto out_register_net;
> 
> and then...
> 
>> +		}
>>  	}
>>  
>> +	pn->users++;
> 
> out_register_net:
>         nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
> 
>> +out:
>>  	return ret;
> 
> I think that this change is similar to patch 1/1, I think you should
> send it as a separated patch.
> 

Yes, It looks better.
should I change this and rebase whole patchset or
maybe you just apply this patchset and then I send a cleanup patch to do this?

>>  }
>>  EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
>> @@ -499,10 +496,18 @@ nf_conntrack_l4proto_unregister_net(struct nf_conntrack_l4proto *l4proto)
>>  void nf_conntrack_l4proto_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);
>>  
>> -	nf_ct_l4proto_unregister_sysctl(net, l4proto);
>> +	pn = nf_ct_l4proto_net(net, l4proto);
>> +	if (pn == NULL)
>> +		return;
>> +
>> +	pn->users--;
>> +	nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
>> +
>>  	/* Remove all contrack entries for this protocol */
>>  	rtnl_lock();
>>  	nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
>> @@ -514,11 +519,15 @@ int nf_conntrack_proto_init(struct net *net)
>>  {
>>  	unsigned int i;
>>  	int err;
>> +	struct nf_proto_net *pn = nf_ct_l4proto_net(net,
>> +					&nf_conntrack_l4proto_generic);
>> +
>>  	err = nf_conntrack_l4proto_generic.init_net(net,
>>  					nf_conntrack_l4proto_generic.l3proto);
>>  	if (err < 0)
>>  		return err;
>>  	err = nf_ct_l4proto_register_sysctl(net,
>> +					    pn,
>>  					    &nf_conntrack_l4proto_generic);
>>  	if (err < 0)
>>  		return err;
>> @@ -528,13 +537,20 @@ int nf_conntrack_proto_init(struct net *net)
>>  			rcu_assign_pointer(nf_ct_l3protos[i],
>>  					   &nf_conntrack_l3proto_generic);
>>  	}
>> +
>> +	pn->users++;
>>  	return 0;
>>  }
>>  
>>  void nf_conntrack_proto_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 */
>> -- 
>> 1.7.7.6
>>
> 

--
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] 23+ messages in thread

* Re: [PATCH 01/13] netfilter: fix problem with proto register
  2012-06-26  3:40   ` Gao feng
@ 2012-06-26 14:36     ` Pablo Neira Ayuso
  2012-06-27  1:38       ` Gao feng
  0 siblings, 1 reply; 23+ messages in thread
From: Pablo Neira Ayuso @ 2012-06-26 14:36 UTC (permalink / raw)
  To: Gao feng; +Cc: netdev, netfilter-devel

On Tue, Jun 26, 2012 at 11:40:14AM +0800, Gao feng wrote:
> Hi Pablo:
> 
> 于 2012年06月25日 19:12, Pablo Neira Ayuso 写道:
> > On Thu, Jun 21, 2012 at 10:36:38PM +0800, Gao feng wrote:
> >> before commit 2c352f444ccfa966a1aa4fd8e9ee29381c467448
> >> (netfilter: nf_conntrack: prepare namespace support for
> >> l4 protocol trackers), we register sysctl before register
> >> protos, so if sysctl is registered faild, the protos will
> >> not be registered.
> >>
> >> but now, we register protos first, and when register
> >> sysctl failed, we can use protos too, it's different
> >> from before.
> > 
> > No, this has to be an all-or-nothing game. If one fails, everything
> > else that you've registered has to be unregistered.
> 
> indeed,this is an all-or-nothing game right now,please look at the ipv4_net_init,
> when we register nf_conntrack_l3proto_ipv4 failed,we will unregister the already
> registered l4protoes, and in nf_conntrack_l4proto_unregister,we will call
> nf_ct_l4proto_unregister_sysctl to free the sysctl table.

I see proto->init_net allocates in->ctl_table, then
nf_ct_l3proto_register_sysctl release it if it fails. I got confused
because I did not see where that memory was being freed. Then, it's
good.

Still one more thing:

> >> so change to register sysctl before register protos.
> >>
> >> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
> >> ---
> >>  net/netfilter/nf_conntrack_proto.c |   36 +++++++++++++++++++++++-------------
> >>  1 files changed, 23 insertions(+), 13 deletions(-)
> >>
> >> diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
> >> index 1ea9194..9bd88aa 100644
> >> --- a/net/netfilter/nf_conntrack_proto.c
> >> +++ b/net/netfilter/nf_conntrack_proto.c
> >> @@ -253,18 +253,23 @@ int nf_conntrack_l3proto_register(struct net *net,
> >>  {
> >>  	int ret = 0;
> >>  
> >> -	if (net == &init_net)
> >> -		ret = nf_conntrack_l3proto_register_net(proto);
> >> +	if (proto->init_net) {

I think proto->init_net has to be mandatory since all protocol support
pernet already. We can add BUG_ON at the beginning of the function if
proto->init_net is not defined.

I can manually add that to the patch if you see no inconvenience with
it.
--
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] 23+ messages in thread

* Re: [PATCH 04/13] netfilter: regard users as refcount for l4proto's per-net data
  2012-06-26  3:58     ` Gao feng
@ 2012-06-26 14:47       ` Pablo Neira Ayuso
  2012-06-27  1:34         ` Gao feng
  0 siblings, 1 reply; 23+ messages in thread
From: Pablo Neira Ayuso @ 2012-06-26 14:47 UTC (permalink / raw)
  To: Gao feng; +Cc: netdev, netfilter-devel

On Tue, Jun 26, 2012 at 11:58:45AM +0800, Gao feng wrote:
> Hi Pablo:
> 于 2012年06月25日 19:20, Pablo Neira Ayuso 写道:
> > On Thu, Jun 21, 2012 at 10:36:41PM +0800, Gao feng wrote:
> >> Now, nf_proto_net's users is confusing.
> >> we should regard it as the refcount for l4proto's per-net data,
> >> because maybe there are two l4protos use the same per-net data.
> >>
> >> so increment pn->users when nf_conntrack_l4proto_register
> >> success, and decrement it for nf_conntrack_l4_unregister case.
> >>
> >> because nf_conntrack_l3proto_ipv[4|6] don't use the same per-net
> >> data,so we don't need to add a refcnt for their per-net data.
> >>
> >> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
> >> ---
> >>  net/netfilter/nf_conntrack_proto.c |   76 ++++++++++++++++++++++--------------
> >>  1 files changed, 46 insertions(+), 30 deletions(-)
> >>
> >> diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
> >> index 9d6b6ab..63612e6 100644
> >> --- a/net/netfilter/nf_conntrack_proto.c
> >> +++ b/net/netfilter/nf_conntrack_proto.c
> > [...]
> >> @@ -458,23 +446,32 @@ int nf_conntrack_l4proto_register(struct net *net,
> >>  				  struct nf_conntrack_l4proto *l4proto)
> >>  {
> >>  	int ret = 0;
> >> +	struct nf_proto_net *pn = NULL;
> >>  
> >>  	if (l4proto->init_net) {
> >>  		ret = l4proto->init_net(net, l4proto->l3proto);
> >>  		if (ret < 0)
> >> -			return ret;
> >> +			goto out;
> >>  	}
> >>  
> >> -	ret = nf_ct_l4proto_register_sysctl(net, l4proto);
> >> +	pn = nf_ct_l4proto_net(net, l4proto);
> >> +	if (pn == NULL)
> >> +		goto out;
> > 
> > Same thing here, we're leaking memory allocated by l4proto->init_net.
> 
> if pn is NULL,init_net can't allocate memory for pn->ctl_table.
> So I think it's not memory leak here.

Sorry, I meant to say the line below. But we've already clarified
this in patch 1/1.

> >> +	ret = nf_ct_l4proto_register_sysctl(net, pn, l4proto);
> >>  	if (ret < 0)
> >> -		return ret;
> >> +		goto out;
> >>  
> >>  	if (net == &init_net) {
> >>  		ret = nf_conntrack_l4proto_register_net(l4proto);
> >> -		if (ret < 0)
> >> -			nf_ct_l4proto_unregister_sysctl(net, l4proto);
> >> +		if (ret < 0) {
> >> +			nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
> >> +			goto out;
> > 
> > Better replace the two lines above by:
> > 
> > goto out_register_net;
> > 
> > and then...
> > 
> >> +		}
> >>  	}
> >>  
> >> +	pn->users++;
> > 
> > out_register_net:
> >         nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
> > 
> >> +out:
> >>  	return ret;
> > 
> > I think that this change is similar to patch 1/1, I think you should
> > send it as a separated patch.
> > 
> 
> Yes, It looks better.
> should I change this and rebase whole patchset or
> maybe you just apply this patchset and then I send a cleanup patch to do this?

This patch includes changes that are not included in the description,
so you have two choices:

1) You resend me this patch with appropriate description (including
the fact that you're fixing the same thing that patch 1/1 does). This
option still I don't like too much, since making two different things
in one single patch is nasty, but well if you push me...

2) you split the patch in two, with the appropriate descriptions each
and you'll make me happy.
--
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] 23+ messages in thread

* Re: [PATCH 04/13] netfilter: regard users as refcount for l4proto's per-net data
  2012-06-26 14:47       ` Pablo Neira Ayuso
@ 2012-06-27  1:34         ` Gao feng
  2012-06-27  9:05           ` Pablo Neira Ayuso
  0 siblings, 1 reply; 23+ messages in thread
From: Gao feng @ 2012-06-27  1:34 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netdev, netfilter-devel

于 2012年06月26日 22:47, Pablo Neira Ayuso 写道:
> On Tue, Jun 26, 2012 at 11:58:45AM +0800, Gao feng wrote:
>> Hi Pablo:
>> 于 2012年06月25日 19:20, Pablo Neira Ayuso 写道:
>>> On Thu, Jun 21, 2012 at 10:36:41PM +0800, Gao feng wrote:
>>>> Now, nf_proto_net's users is confusing.
>>>> we should regard it as the refcount for l4proto's per-net data,
>>>> because maybe there are two l4protos use the same per-net data.
>>>>
>>>> so increment pn->users when nf_conntrack_l4proto_register
>>>> success, and decrement it for nf_conntrack_l4_unregister case.
>>>>
>>>> because nf_conntrack_l3proto_ipv[4|6] don't use the same per-net
>>>> data,so we don't need to add a refcnt for their per-net data.
>>>>
>>>> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
>>>> ---
>>>>  net/netfilter/nf_conntrack_proto.c |   76 ++++++++++++++++++++++--------------
>>>>  1 files changed, 46 insertions(+), 30 deletions(-)
>>>>
>>>> diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
>>>> index 9d6b6ab..63612e6 100644
>>>> --- a/net/netfilter/nf_conntrack_proto.c
>>>> +++ b/net/netfilter/nf_conntrack_proto.c
>>> [...]
>>>> @@ -458,23 +446,32 @@ int nf_conntrack_l4proto_register(struct net *net,
>>>>  				  struct nf_conntrack_l4proto *l4proto)
>>>>  {
>>>>  	int ret = 0;
>>>> +	struct nf_proto_net *pn = NULL;
>>>>  
>>>>  	if (l4proto->init_net) {
>>>>  		ret = l4proto->init_net(net, l4proto->l3proto);
>>>>  		if (ret < 0)
>>>> -			return ret;
>>>> +			goto out;
>>>>  	}
>>>>  
>>>> -	ret = nf_ct_l4proto_register_sysctl(net, l4proto);
>>>> +	pn = nf_ct_l4proto_net(net, l4proto);
>>>> +	if (pn == NULL)
>>>> +		goto out;
>>>
>>> Same thing here, we're leaking memory allocated by l4proto->init_net.
>>
>> if pn is NULL,init_net can't allocate memory for pn->ctl_table.
>> So I think it's not memory leak here.
> 
> Sorry, I meant to say the line below. But we've already clarified
> this in patch 1/1.
> 
>>>> +	ret = nf_ct_l4proto_register_sysctl(net, pn, l4proto);
>>>>  	if (ret < 0)
>>>> -		return ret;
>>>> +		goto out;
>>>>  
>>>>  	if (net == &init_net) {
>>>>  		ret = nf_conntrack_l4proto_register_net(l4proto);
>>>> -		if (ret < 0)
>>>> -			nf_ct_l4proto_unregister_sysctl(net, l4proto);
>>>> +		if (ret < 0) {
>>>> +			nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
>>>> +			goto out;
>>>
>>> Better replace the two lines above by:
>>>
>>> goto out_register_net;
>>>
>>> and then...
>>>
>>>> +		}
>>>>  	}
>>>>  
>>>> +	pn->users++;
>>>
>>> out_register_net:
>>>         nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
>>>
>>>> +out:
>>>>  	return ret;
>>>
>>> I think that this change is similar to patch 1/1, I think you should
>>> send it as a separated patch.
>>>
>>
>> Yes, It looks better.
>> should I change this and rebase whole patchset or
>> maybe you just apply this patchset and then I send a cleanup patch to do this?
> 
> This patch includes changes that are not included in the description,
> so you have two choices:
> 
> 1) You resend me this patch with appropriate description (including
> the fact that you're fixing the same thing that patch 1/1 does). This
> option still I don't like too much, since making two different things
> in one single patch is nasty, but well if you push me...

Sorry, I don't know which the same thing I fixed in this patch and 1/13 patch.
the 1/13 patch only change the proto's registration order. and this patch doesn't
change the registration order.

This patch is used to try to make variable "users" clear.

> 
> 2) you split the patch in two, with the appropriate descriptions each
> and you'll make me happy.
> --
> 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
> 

--
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] 23+ messages in thread

* Re: [PATCH 01/13] netfilter: fix problem with proto register
  2012-06-26 14:36     ` Pablo Neira Ayuso
@ 2012-06-27  1:38       ` Gao feng
  2012-06-27  8:53         ` Pablo Neira Ayuso
  0 siblings, 1 reply; 23+ messages in thread
From: Gao feng @ 2012-06-27  1:38 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netdev, netfilter-devel

于 2012年06月26日 22:36, Pablo Neira Ayuso 写道:
> On Tue, Jun 26, 2012 at 11:40:14AM +0800, Gao feng wrote:
>> Hi Pablo:
>>
>> 于 2012年06月25日 19:12, Pablo Neira Ayuso 写道:
>>> On Thu, Jun 21, 2012 at 10:36:38PM +0800, Gao feng wrote:
>>>> before commit 2c352f444ccfa966a1aa4fd8e9ee29381c467448
>>>> (netfilter: nf_conntrack: prepare namespace support for
>>>> l4 protocol trackers), we register sysctl before register
>>>> protos, so if sysctl is registered faild, the protos will
>>>> not be registered.
>>>>
>>>> but now, we register protos first, and when register
>>>> sysctl failed, we can use protos too, it's different
>>>> from before.
>>>
>>> No, this has to be an all-or-nothing game. If one fails, everything
>>> else that you've registered has to be unregistered.
>>
>> indeed,this is an all-or-nothing game right now,please look at the ipv4_net_init,
>> when we register nf_conntrack_l3proto_ipv4 failed,we will unregister the already
>> registered l4protoes, and in nf_conntrack_l4proto_unregister,we will call
>> nf_ct_l4proto_unregister_sysctl to free the sysctl table.
> 
> I see proto->init_net allocates in->ctl_table, then
> nf_ct_l3proto_register_sysctl release it if it fails. I got confused
> because I did not see where that memory was being freed. Then, it's
> good.
> 
> Still one more thing:
> 
>>>> so change to register sysctl before register protos.
>>>>
>>>> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
>>>> ---
>>>>  net/netfilter/nf_conntrack_proto.c |   36 +++++++++++++++++++++++-------------
>>>>  1 files changed, 23 insertions(+), 13 deletions(-)
>>>>
>>>> diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
>>>> index 1ea9194..9bd88aa 100644
>>>> --- a/net/netfilter/nf_conntrack_proto.c
>>>> +++ b/net/netfilter/nf_conntrack_proto.c
>>>> @@ -253,18 +253,23 @@ int nf_conntrack_l3proto_register(struct net *net,
>>>>  {
>>>>  	int ret = 0;
>>>>  
>>>> -	if (net == &init_net)
>>>> -		ret = nf_conntrack_l3proto_register_net(proto);
>>>> +	if (proto->init_net) {
> 
> I think proto->init_net has to be mandatory since all protocol support
> pernet already. We can add BUG_ON at the beginning of the function if
> proto->init_net is not defined.
> 

we can add BUG_ON at nf_conntrack_l4proto_register,because all of the l4protoes
have the init_net function.

BUT nf_conntrack_l3proto_ipv6 doesn't have init_net function,because this proto
doesn't have pernet data, and nf_conntrack_l3proto_ipv4 has pernet data only when
CONFIG_NF_CONNTRACK_PROC_COMPAT is configured.

> I can manually add that to the patch if you see no inconvenience with
> it.
> --
> 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] 23+ messages in thread

* Re: [PATCH 01/13] netfilter: fix problem with proto register
  2012-06-27  1:38       ` Gao feng
@ 2012-06-27  8:53         ` Pablo Neira Ayuso
  0 siblings, 0 replies; 23+ messages in thread
From: Pablo Neira Ayuso @ 2012-06-27  8:53 UTC (permalink / raw)
  To: Gao feng; +Cc: netdev, netfilter-devel

On Wed, Jun 27, 2012 at 09:38:44AM +0800, Gao feng wrote:
> 于 2012年06月26日 22:36, Pablo Neira Ayuso 写道:
> > On Tue, Jun 26, 2012 at 11:40:14AM +0800, Gao feng wrote:
> >> Hi Pablo:
> >>
> >> 于 2012年06月25日 19:12, Pablo Neira Ayuso 写道:
> >>> On Thu, Jun 21, 2012 at 10:36:38PM +0800, Gao feng wrote:
> >>>> before commit 2c352f444ccfa966a1aa4fd8e9ee29381c467448
> >>>> (netfilter: nf_conntrack: prepare namespace support for
> >>>> l4 protocol trackers), we register sysctl before register
> >>>> protos, so if sysctl is registered faild, the protos will
> >>>> not be registered.
> >>>>
> >>>> but now, we register protos first, and when register
> >>>> sysctl failed, we can use protos too, it's different
> >>>> from before.
> >>>
> >>> No, this has to be an all-or-nothing game. If one fails, everything
> >>> else that you've registered has to be unregistered.
> >>
> >> indeed,this is an all-or-nothing game right now,please look at the ipv4_net_init,
> >> when we register nf_conntrack_l3proto_ipv4 failed,we will unregister the already
> >> registered l4protoes, and in nf_conntrack_l4proto_unregister,we will call
> >> nf_ct_l4proto_unregister_sysctl to free the sysctl table.
> > 
> > I see proto->init_net allocates in->ctl_table, then
> > nf_ct_l3proto_register_sysctl release it if it fails. I got confused
> > because I did not see where that memory was being freed. Then, it's
> > good.
> > 
> > Still one more thing:
> > 
> >>>> so change to register sysctl before register protos.
> >>>>
> >>>> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
> >>>> ---
> >>>>  net/netfilter/nf_conntrack_proto.c |   36 +++++++++++++++++++++++-------------
> >>>>  1 files changed, 23 insertions(+), 13 deletions(-)
> >>>>
> >>>> diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
> >>>> index 1ea9194..9bd88aa 100644
> >>>> --- a/net/netfilter/nf_conntrack_proto.c
> >>>> +++ b/net/netfilter/nf_conntrack_proto.c
> >>>> @@ -253,18 +253,23 @@ int nf_conntrack_l3proto_register(struct net *net,
> >>>>  {
> >>>>  	int ret = 0;
> >>>>  
> >>>> -	if (net == &init_net)
> >>>> -		ret = nf_conntrack_l3proto_register_net(proto);
> >>>> +	if (proto->init_net) {
> > 
> > I think proto->init_net has to be mandatory since all protocol support
> > pernet already. We can add BUG_ON at the beginning of the function if
> > proto->init_net is not defined.
> > 
> 
> we can add BUG_ON at nf_conntrack_l4proto_register,because all of the l4protoes
> have the init_net function.
> 
> BUT nf_conntrack_l3proto_ipv6 doesn't have init_net function,because this proto
> doesn't have pernet data, and nf_conntrack_l3proto_ipv4 has pernet data only when
> CONFIG_NF_CONNTRACK_PROC_COMPAT is configured.

OK, thanks for the clarification.
--
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] 23+ messages in thread

* Re: [PATCH 04/13] netfilter: regard users as refcount for l4proto's per-net data
  2012-06-27  1:34         ` Gao feng
@ 2012-06-27  9:05           ` Pablo Neira Ayuso
  0 siblings, 0 replies; 23+ messages in thread
From: Pablo Neira Ayuso @ 2012-06-27  9:05 UTC (permalink / raw)
  To: Gao feng; +Cc: netdev, netfilter-devel

On Wed, Jun 27, 2012 at 09:34:01AM +0800, Gao feng wrote:
[...]
> >>> I think that this change is similar to patch 1/1, I think you should
> >>> send it as a separated patch.
> >>>
> >>
> >> Yes, It looks better.
> >> should I change this and rebase whole patchset or
> >> maybe you just apply this patchset and then I send a cleanup patch to do this?
> > 
> > This patch includes changes that are not included in the description,
> > so you have two choices:
> > 
> > 1) You resend me this patch with appropriate description (including
> > the fact that you're fixing the same thing that patch 1/1 does). This
> > option still I don't like too much, since making two different things
> > in one single patch is nasty, but well if you push me...
> 
> Sorry, I don't know which the same thing I fixed in this patch and 1/13 patch.
> the 1/13 patch only change the proto's registration order. and this patch doesn't
> change the registration order.
> 
> This patch is used to try to make variable "users" clear.

Never mind, I'll take the patchset. Thanks Gao.

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

end of thread, other threads:[~2012-06-27  9:05 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-21 14:36 [PATCH 01/13] netfilter: fix problem with proto register Gao feng
2012-06-21 14:36 ` [PATCH 02/13] netfilter: add parameter proto for l4proto.init_net Gao feng
2012-06-21 14:36 ` [PATCH 03/13] netfilter: add nf_ct_kfree_compat_sysctl_table to make codes clear Gao feng
2012-06-21 14:36 ` [PATCH 04/13] netfilter: regard users as refcount for l4proto's per-net data Gao feng
2012-06-25 11:20   ` Pablo Neira Ayuso
2012-06-26  3:58     ` Gao feng
2012-06-26 14:47       ` Pablo Neira Ayuso
2012-06-27  1:34         ` Gao feng
2012-06-27  9:05           ` Pablo Neira Ayuso
2012-06-21 14:36 ` [PATCH 05/13] netfilter: fix memory leak when register sysctl failed Gao feng
2012-06-21 14:36 ` [PATCH 06/13] netfilter: merge tcpv[4,6]_net_init into tcp_net_init Gao feng
2012-06-21 14:36 ` [PATCH 07/13] netfilter: merge udpv[4,6]_net_init into udp_net_init Gao feng
2012-06-21 14:36 ` [PATCH 08/13] netfilter: nf_conntrack_l4proto_udplite[4,6] cleanup Gao feng
2012-06-21 14:36 ` [PATCH 09/13] netfilter: merge sctpv[4,6]_net_init into sctp_net_init Gao feng
2012-06-21 14:36 ` [PATCH 10/13] netfilter: nf_conntrack_l4proto_generic cleanup Gao feng
2012-06-21 14:36 ` [PATCH 11/13] netfilter: nf_conntrack_l4proto_dccp[4,6] cleanup Gao feng
2012-06-21 14:36 ` [PATCH 12/13] netfilter: nf_conntrack_l4proto_icmp cleanup Gao feng
2012-06-21 14:36 ` [PATCH 13/13] netfilter: nf_conntrack_l4proto_icmpv6 cleanup Gao feng
2012-06-25 11:12 ` [PATCH 01/13] netfilter: fix problem with proto register Pablo Neira Ayuso
2012-06-26  3:40   ` Gao feng
2012-06-26 14:36     ` Pablo Neira Ayuso
2012-06-27  1:38       ` Gao feng
2012-06-27  8:53         ` 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).