All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v2 0/7] introduce netfilter conntrack protos pernet functionality v2
@ 2009-03-11 20:57 Cyrill Gorcunov
  2009-03-11 20:57 ` [RFC v2 1/7] net: sysctl_net - use net_eq to compare nets Cyrill Gorcunov
                   ` (6 more replies)
  0 siblings, 7 replies; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-11 20:57 UTC (permalink / raw)
  To: kaber, davem, daniel.lezcano; +Cc: netdev, netfilter-devel, xemul, adobriyan

Hi all,

here is a second request for comments on netfilter conntrack
protos per-net functionality. The following protos are covered
now: dccp, sctp, udplite, tcp, udp, icmp. So I would really
like to hear kind of comments (angry screams maybe :) on the
series.

To Patric:
Patric I decided to not assign sysctls data by iterative
fasion since it could lead for harder grep'ability, and
in case if order of "enum entries" changed the sysctls
will be silently broken. To make these assignments shorter
I've added ___PERNET_TO_DAT macro which has quite a small
lifetime inside sources. If you prefer to assign them
in for(;;) -- just say the word and I'll remake it :)

So please review and comment (if possible). Thanks!
(If someone could even test it -- it would be amaizing!
 I've been playing a bit with the series in qemu+lxc)

Hope I didn't miss anything.

Cyrill

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

* [RFC v2 1/7] net: sysctl_net - use net_eq to compare nets
  2009-03-11 20:57 [RFC v2 0/7] introduce netfilter conntrack protos pernet functionality v2 Cyrill Gorcunov
@ 2009-03-11 20:57 ` Cyrill Gorcunov
  2009-03-12  8:50   ` Daniel Lezcano
  2009-03-11 20:57 ` [RFC v2 2/7] net: netfilter conntrack - add per-net functionality for DCCP protocol Cyrill Gorcunov
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-11 20:57 UTC (permalink / raw)
  To: kaber, davem, daniel.lezcano
  Cc: netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

[-- Attachment #1: net-sysctl-net-use-net_eq --]
[-- Type: text/plain, Size: 643 bytes --]

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 net/sysctl_net.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6.git/net/sysctl_net.c
===================================================================
--- linux-2.6.git.orig/net/sysctl_net.c
+++ linux-2.6.git/net/sysctl_net.c
@@ -61,7 +61,7 @@ static struct ctl_table_root net_sysctl_
 static int net_ctl_ro_header_perms(struct ctl_table_root *root,
 		struct nsproxy *namespaces, struct ctl_table *table)
 {
-	if (namespaces->net_ns == &init_net)
+	if (net_eq(namespaces->net_ns, &init_net))
 		return table->mode;
 	else
 		return table->mode & ~0222;


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

* [RFC v2 2/7] net: netfilter conntrack - add per-net functionality for DCCP protocol
  2009-03-11 20:57 [RFC v2 0/7] introduce netfilter conntrack protos pernet functionality v2 Cyrill Gorcunov
  2009-03-11 20:57 ` [RFC v2 1/7] net: sysctl_net - use net_eq to compare nets Cyrill Gorcunov
@ 2009-03-11 20:57 ` Cyrill Gorcunov
  2009-03-12  8:54   ` Daniel Lezcano
  2009-03-11 20:57 ` [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol Cyrill Gorcunov
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-11 20:57 UTC (permalink / raw)
  To: kaber, davem, daniel.lezcano
  Cc: netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

[-- Attachment #1: net-namespace-nf-conntrack-proto-dccp --]
[-- Type: text/plain, Size: 9305 bytes --]

Module specific data moved into per-net site and being allocated/freed
during net namespace creation/deletion.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 net/netfilter/nf_conntrack_proto_dccp.c |  145 +++++++++++++++++++++++---------
 1 file changed, 108 insertions(+), 37 deletions(-)

Index: linux-2.6.git/net/netfilter/nf_conntrack_proto_dccp.c
===================================================================
--- linux-2.6.git.orig/net/netfilter/nf_conntrack_proto_dccp.c
+++ linux-2.6.git/net/netfilter/nf_conntrack_proto_dccp.c
@@ -16,6 +16,9 @@
 #include <linux/skbuff.h>
 #include <linux/dccp.h>
 
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
 #include <linux/netfilter/nfnetlink_conntrack.h>
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
@@ -23,8 +26,6 @@
 
 static DEFINE_RWLOCK(dccp_lock);
 
-static int nf_ct_dccp_loose __read_mostly = 1;
-
 /* Timeouts are based on values from RFC4340:
  *
  * - REQUEST:
@@ -72,16 +73,6 @@ static int nf_ct_dccp_loose __read_mostl
 
 #define DCCP_MSL (2 * 60 * HZ)
 
-static unsigned int dccp_timeout[CT_DCCP_MAX + 1] __read_mostly = {
-	[CT_DCCP_REQUEST]	= 2 * DCCP_MSL,
-	[CT_DCCP_RESPOND]	= 4 * DCCP_MSL,
-	[CT_DCCP_PARTOPEN]	= 4 * DCCP_MSL,
-	[CT_DCCP_OPEN]		= 12 * 3600 * HZ,
-	[CT_DCCP_CLOSEREQ]	= 64 * HZ,
-	[CT_DCCP_CLOSING]	= 64 * HZ,
-	[CT_DCCP_TIMEWAIT]	= 2 * DCCP_MSL,
-};
-
 static const char * const dccp_state_names[] = {
 	[CT_DCCP_NONE]		= "NONE",
 	[CT_DCCP_REQUEST]	= "REQUEST",
@@ -393,6 +384,22 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][D
 	},
 };
 
+/* this module per-net specifics */
+static int dccp_net_id;
+struct dccp_net {
+	int dccp_loose;
+	unsigned int dccp_timeout[CT_DCCP_MAX + 1];
+#ifdef CONFIG_SYSCTL
+	struct ctl_table_header *sysctl_header;
+	struct ctl_table *sysctl_table;
+#endif
+};
+
+static inline struct dccp_net *dccp_pernet(struct net *net)
+{
+	return net_generic(net, dccp_net_id);
+}
+
 static bool dccp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
 			      struct nf_conntrack_tuple *tuple)
 {
@@ -419,6 +426,7 @@ static bool dccp_new(struct nf_conn *ct,
 		     unsigned int dataoff)
 {
 	struct net *net = nf_ct_net(ct);
+	struct dccp_net *dn;
 	struct dccp_hdr _dh, *dh;
 	const char *msg;
 	u_int8_t state;
@@ -429,7 +437,8 @@ static bool dccp_new(struct nf_conn *ct,
 	state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE];
 	switch (state) {
 	default:
-		if (nf_ct_dccp_loose == 0) {
+		dn = dccp_pernet(net);
+		if (dn->dccp_loose == 0) {
 			msg = "nf_ct_dccp: not picking up existing connection ";
 			goto out_invalid;
 		}
@@ -465,6 +474,7 @@ static int dccp_packet(struct nf_conn *c
 		       u_int8_t pf, unsigned int hooknum)
 {
 	struct net *net = nf_ct_net(ct);
+	struct dccp_net *dn;
 	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 	struct dccp_hdr _dh, *dh;
 	u_int8_t type, old_state, new_state;
@@ -542,7 +552,9 @@ static int dccp_packet(struct nf_conn *c
 	ct->proto.dccp.last_pkt = type;
 	ct->proto.dccp.state = new_state;
 	write_unlock_bh(&dccp_lock);
-	nf_ct_refresh_acct(ct, ctinfo, skb, dccp_timeout[new_state]);
+
+	dn = dccp_pernet(net);
+	nf_ct_refresh_acct(ct, ctinfo, skb, dn->dccp_timeout[new_state]);
 
 	return NF_ACCEPT;
 }
@@ -660,13 +672,11 @@ static int nlattr_to_dccp(struct nlattr 
 #endif
 
 #ifdef CONFIG_SYSCTL
-static unsigned int dccp_sysctl_table_users;
-static struct ctl_table_header *dccp_sysctl_header;
-static ctl_table dccp_sysctl_table[] = {
+/* template, data assigned later */
+static struct ctl_table dccp_sysctl_table[] = {
 	{
 		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "nf_conntrack_dccp_timeout_request",
-		.data		= &dccp_timeout[CT_DCCP_REQUEST],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -674,7 +684,6 @@ static ctl_table dccp_sysctl_table[] = {
 	{
 		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "nf_conntrack_dccp_timeout_respond",
-		.data		= &dccp_timeout[CT_DCCP_RESPOND],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -682,7 +691,6 @@ static ctl_table dccp_sysctl_table[] = {
 	{
 		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "nf_conntrack_dccp_timeout_partopen",
-		.data		= &dccp_timeout[CT_DCCP_PARTOPEN],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -690,7 +698,6 @@ static ctl_table dccp_sysctl_table[] = {
 	{
 		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "nf_conntrack_dccp_timeout_open",
-		.data		= &dccp_timeout[CT_DCCP_OPEN],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -698,7 +705,6 @@ static ctl_table dccp_sysctl_table[] = {
 	{
 		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "nf_conntrack_dccp_timeout_closereq",
-		.data		= &dccp_timeout[CT_DCCP_CLOSEREQ],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -706,7 +712,6 @@ static ctl_table dccp_sysctl_table[] = {
 	{
 		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "nf_conntrack_dccp_timeout_closing",
-		.data		= &dccp_timeout[CT_DCCP_CLOSING],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -714,7 +719,6 @@ static ctl_table dccp_sysctl_table[] = {
 	{
 		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "nf_conntrack_dccp_timeout_timewait",
-		.data		= &dccp_timeout[CT_DCCP_TIMEWAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -722,8 +726,7 @@ static ctl_table dccp_sysctl_table[] = {
 	{
 		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "nf_conntrack_dccp_loose",
-		.data		= &nf_ct_dccp_loose,
-		.maxlen		= sizeof(nf_ct_dccp_loose),
+		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
 	},
@@ -751,11 +754,6 @@ static struct nf_conntrack_l4proto dccp_
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
-#ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &dccp_sysctl_table_users,
-	.ctl_table_header	= &dccp_sysctl_header,
-	.ctl_table		= dccp_sysctl_table,
-#endif
 };
 
 static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
@@ -776,34 +774,107 @@ static struct nf_conntrack_l4proto dccp_
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
+};
+
+static __net_init int dccp_net_init(struct net *net)
+{
+	struct dccp_net *dn;
+	int err;
+
+	dn = kmalloc(sizeof(*dn), GFP_KERNEL);
+	if (!dn)
+		return -ENOMEM;
+
+	/* default values */
+	dn->dccp_loose = 1;
+	dn->dccp_timeout[CT_DCCP_REQUEST]	= 2 * DCCP_MSL;
+	dn->dccp_timeout[CT_DCCP_RESPOND]	= 4 * DCCP_MSL;
+	dn->dccp_timeout[CT_DCCP_PARTOPEN]	= 4 * DCCP_MSL;
+	dn->dccp_timeout[CT_DCCP_OPEN]		= 12 * 3600 * HZ;
+	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;
+
+	err = net_assign_generic(net, dccp_net_id, dn);
+	if (err)
+		goto out;
+
 #ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &dccp_sysctl_table_users,
-	.ctl_table_header	= &dccp_sysctl_header,
-	.ctl_table		= dccp_sysctl_table,
+	err = -ENOMEM;
+	dn->sysctl_table = kmemdup(dccp_sysctl_table,
+			sizeof(dccp_sysctl_table), GFP_KERNEL);
+	if (!dn->sysctl_table)
+		goto out;
+
+	dn->sysctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST];
+	dn->sysctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND];
+	dn->sysctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN];
+	dn->sysctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN];
+	dn->sysctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ];
+	dn->sysctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING];
+	dn->sysctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT];
+	dn->sysctl_table[7].data = &dn->dccp_loose;
+
+	dn->sysctl_header = register_net_sysctl_table(net,
+			nf_net_netfilter_sysctl_path, dn->sysctl_table);
+	if (!dn->sysctl_header) {
+		kfree(dn->sysctl_table);
+		goto out;
+	}
 #endif
+
+	return 0;
+
+out:
+	kfree(dn);
+	return err;
+}
+
+static __net_exit void dccp_net_exit(struct net *net)
+{
+	struct dccp_net *dn = dccp_pernet(net);
+#ifdef CONFIG_SYSCTL
+	unregister_net_sysctl_table(dn->sysctl_header);
+	kfree(dn->sysctl_table);
+#endif
+	kfree(dn);
+
+	net_assign_generic(net, dccp_net_id, NULL);
+}
+
+static struct pernet_operations dccp_net_ops = {
+	.init = dccp_net_init,
+	.exit = dccp_net_exit,
 };
 
 static int __init nf_conntrack_proto_dccp_init(void)
 {
 	int err;
 
-	err = nf_conntrack_l4proto_register(&dccp_proto4);
+	err = register_pernet_gen_subsys(&dccp_net_id, &dccp_net_ops);
 	if (err < 0)
 		goto err1;
 
-	err = nf_conntrack_l4proto_register(&dccp_proto6);
+	err = nf_conntrack_l4proto_register(&dccp_proto4);
 	if (err < 0)
 		goto err2;
+
+	err = nf_conntrack_l4proto_register(&dccp_proto6);
+	if (err < 0)
+		goto err3;
 	return 0;
 
-err2:
+err3:
 	nf_conntrack_l4proto_unregister(&dccp_proto4);
+err2:
+	unregister_pernet_gen_subsys(dccp_net_id, &dccp_net_ops);
 err1:
 	return err;
 }
 
 static void __exit nf_conntrack_proto_dccp_fini(void)
 {
+	unregister_pernet_gen_subsys(dccp_net_id, &dccp_net_ops);
 	nf_conntrack_l4proto_unregister(&dccp_proto6);
 	nf_conntrack_l4proto_unregister(&dccp_proto4);
 }


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

* [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol
  2009-03-11 20:57 [RFC v2 0/7] introduce netfilter conntrack protos pernet functionality v2 Cyrill Gorcunov
  2009-03-11 20:57 ` [RFC v2 1/7] net: sysctl_net - use net_eq to compare nets Cyrill Gorcunov
  2009-03-11 20:57 ` [RFC v2 2/7] net: netfilter conntrack - add per-net functionality for DCCP protocol Cyrill Gorcunov
@ 2009-03-11 20:57 ` Cyrill Gorcunov
  2009-03-12  9:03   ` Daniel Lezcano
  2009-03-16 15:35   ` Patrick McHardy
  2009-03-11 20:57 ` [RFC v2 4/7] net: netfilter conntrack - add per-net functionality for UDPLITE protocol Cyrill Gorcunov
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-11 20:57 UTC (permalink / raw)
  To: kaber, davem, daniel.lezcano
  Cc: netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

[-- Attachment #1: net-namespace-nf-conntrack-proto-sctp --]
[-- Type: text/plain, Size: 11491 bytes --]

Module specific data moved into per-net site and being allocated/freed
during net namespace creation/deletion.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 net/netfilter/nf_conntrack_proto_sctp.c |  186 +++++++++++++++++++++++++-------
 1 file changed, 146 insertions(+), 40 deletions(-)

Index: linux-2.6.git/net/netfilter/nf_conntrack_proto_sctp.c
===================================================================
--- linux-2.6.git.orig/net/netfilter/nf_conntrack_proto_sctp.c
+++ linux-2.6.git/net/netfilter/nf_conntrack_proto_sctp.c
@@ -21,6 +21,9 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
@@ -49,16 +52,6 @@ static const char *const sctp_conntrack_
 #define HOURS * 60 MINS
 #define DAYS  * 24 HOURS
 
-static unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] __read_mostly = {
-	[SCTP_CONNTRACK_CLOSED]			= 10 SECS,
-	[SCTP_CONNTRACK_COOKIE_WAIT]		= 3 SECS,
-	[SCTP_CONNTRACK_COOKIE_ECHOED]		= 3 SECS,
-	[SCTP_CONNTRACK_ESTABLISHED]		= 5 DAYS,
-	[SCTP_CONNTRACK_SHUTDOWN_SENT]		= 300 SECS / 1000,
-	[SCTP_CONNTRACK_SHUTDOWN_RECD]		= 300 SECS / 1000,
-	[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT]	= 3 SECS,
-};
-
 #define sNO SCTP_CONNTRACK_NONE
 #define	sCL SCTP_CONNTRACK_CLOSED
 #define	sCW SCTP_CONNTRACK_COOKIE_WAIT
@@ -130,6 +123,25 @@ static const u8 sctp_conntracks[2][9][SC
 	}
 };
 
+/* this module per-net specifics */
+static int sctp_net_id;
+struct sctp_net {
+	unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX];
+#ifdef CONFIG_SYSCTL
+	struct ctl_table_header *sysctl_header;
+	struct ctl_table *sysctl_table;
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	struct ctl_table_header *compat_sysctl_header;
+	struct ctl_table *compat_sysctl_table;
+#endif
+#endif
+};
+
+static inline struct sctp_net *sctp_pernet(struct net *net)
+{
+	return net_generic(net, sctp_net_id);
+}
+
 static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
 			      struct nf_conntrack_tuple *tuple)
 {
@@ -297,6 +309,7 @@ static int sctp_packet(struct nf_conn *c
 	const struct sctp_chunkhdr *sch;
 	struct sctp_chunkhdr _sch;
 	u_int32_t offset, count;
+	struct sctp_net *sn;
 	unsigned long map[256 / sizeof(unsigned long)] = { 0 };
 
 	sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
@@ -373,7 +386,8 @@ static int sctp_packet(struct nf_conn *c
 	}
 	write_unlock_bh(&sctp_lock);
 
-	nf_ct_refresh_acct(ct, ctinfo, skb, sctp_timeouts[new_state]);
+	sn = sctp_pernet(nf_ct_net(ct));
+	nf_ct_refresh_acct(ct, ctinfo, skb, sn->sctp_timeouts[new_state]);
 
 	if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
 	    dir == IP_CT_DIR_REPLY &&
@@ -540,54 +554,46 @@ static int nlattr_to_sctp(struct nlattr 
 #endif
 
 #ifdef CONFIG_SYSCTL
-static unsigned int sctp_sysctl_table_users;
-static struct ctl_table_header *sctp_sysctl_header;
+/* templates, data assigned later */
 static struct ctl_table sctp_sysctl_table[] = {
 	{
 		.procname	= "nf_conntrack_sctp_timeout_closed",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_sctp_timeout_cookie_wait",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_sctp_timeout_cookie_echoed",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_sctp_timeout_established",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_sctp_timeout_shutdown_sent",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_sctp_timeout_shutdown_recd",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_sctp_timeout_shutdown_ack_sent",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -601,49 +607,42 @@ static struct ctl_table sctp_sysctl_tabl
 static struct ctl_table sctp_compat_sysctl_table[] = {
 	{
 		.procname	= "ip_conntrack_sctp_timeout_closed",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_sctp_timeout_cookie_wait",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_sctp_timeout_cookie_echoed",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_sctp_timeout_established",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_sctp_timeout_shutdown_sent",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_sctp_timeout_shutdown_recd",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_sctp_timeout_shutdown_ack_sent",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -653,7 +652,7 @@ static struct ctl_table sctp_compat_sysc
 	}
 };
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
-#endif
+#endif /* CONFIG_SYSCTL */
 
 static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
 	.l3proto		= PF_INET,
@@ -673,14 +672,6 @@ static struct nf_conntrack_l4proto nf_co
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
-#ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &sctp_sysctl_table_users,
-	.ctl_table_header	= &sctp_sysctl_header,
-	.ctl_table		= sctp_sysctl_table,
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
-	.ctl_compat_table	= sctp_compat_sysctl_table,
-#endif
-#endif
 };
 
 static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
@@ -701,21 +692,133 @@ static struct nf_conntrack_l4proto nf_co
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
+};
+
+static __net_init int sctp_net_init(struct net *net)
+{
+	struct sctp_net *sn;
+	int err;
+
+	sn = kmalloc(sizeof(*sn), GFP_KERNEL);
+	if (!sn)
+		return -ENOMEM;
+
+	/* default values */
+	sn->sctp_timeouts[SCTP_CONNTRACK_CLOSED]	= 10 SECS;
+	sn->sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT]	= 3 SECS;
+	sn->sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED]	= 3 SECS;
+	sn->sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED]	= 5 DAYS;
+	sn->sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT]	= 300 SECS / 1000;
+	sn->sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD]	= 300 SECS / 1000;
+	sn->sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS;
+
+	err = net_assign_generic(net, sctp_net_id, sn);
+	if (err)
+		goto out;
+
 #ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &sctp_sysctl_table_users,
-	.ctl_table_header	= &sctp_sysctl_header,
-	.ctl_table		= sctp_sysctl_table,
+	err = -ENOMEM;
+	sn->sysctl_table = kmemdup(sctp_sysctl_table,
+			sizeof(sctp_sysctl_table), GFP_KERNEL);
+	if (!sn->sysctl_table)
+		goto out;
+
+#define ___PERNET_TO_DAT(i, j) \
+	sn->sysctl_table[i].data = &sn->sctp_timeouts[j]
+
+	___PERNET_TO_DAT(0, SCTP_CONNTRACK_CLOSED);
+	___PERNET_TO_DAT(1, SCTP_CONNTRACK_COOKIE_WAIT);
+	___PERNET_TO_DAT(2, SCTP_CONNTRACK_COOKIE_ECHOED);
+	___PERNET_TO_DAT(3, SCTP_CONNTRACK_ESTABLISHED);
+	___PERNET_TO_DAT(4, SCTP_CONNTRACK_SHUTDOWN_SENT);
+	___PERNET_TO_DAT(5, SCTP_CONNTRACK_SHUTDOWN_RECD);
+	___PERNET_TO_DAT(6, SCTP_CONNTRACK_SHUTDOWN_ACK_SENT);
+
+#undef ___PERNET_TO_DAT
+
+	sn->sysctl_header = register_net_sysctl_table(net,
+			nf_net_netfilter_sysctl_path, sn->sysctl_table);
+	if (!sn->sysctl_header)
+		goto out_free;
+
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	sn->compat_sysctl_table = kmemdup(sctp_compat_sysctl_table,
+			sizeof(sctp_compat_sysctl_table), GFP_KERNEL);
+	if (!sn->compat_sysctl_table)
+		goto out_sysctl;
+
+#define ___PERNET_TO_DAT(i, j) \
+	sn->compat_sysctl_table[i].data = &sn->sctp_timeouts[j]
+
+	___PERNET_TO_DAT(0, SCTP_CONNTRACK_CLOSED);
+	___PERNET_TO_DAT(1, SCTP_CONNTRACK_COOKIE_WAIT);
+	___PERNET_TO_DAT(2, SCTP_CONNTRACK_COOKIE_ECHOED);
+	___PERNET_TO_DAT(3, SCTP_CONNTRACK_ESTABLISHED);
+	___PERNET_TO_DAT(4, SCTP_CONNTRACK_SHUTDOWN_SENT);
+	___PERNET_TO_DAT(5, SCTP_CONNTRACK_SHUTDOWN_RECD);
+	___PERNET_TO_DAT(6, SCTP_CONNTRACK_SHUTDOWN_ACK_SENT);
+
+#undef ___PERNET_TO_DAT
+
+	sn->compat_sysctl_header = register_net_sysctl_table(net,
+			nf_net_ipv4_netfilter_sysctl_path, sn->compat_sysctl_table);
+	if (!sn->compat_sysctl_header)
+		goto out_free_compat;
+#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
+#endif /* CONFIG_SYSCTL */
+
+	return 0;
+
+#ifdef CONFIG_SYSCTL
+
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+out_free_compat:
+	kfree(sn->compat_sysctl_table);
+#endif
+out_sysctl:
+	unregister_net_sysctl_table(sn->sysctl_header);
+out_free:
+	kfree(sn->sysctl_table);
+#endif
+
+out:
+	kfree(sn);
+	return err;
+}
+
+static __net_exit void sctp_net_exit(struct net *net)
+{
+	struct sctp_net *sn = sctp_pernet(net);
+#ifdef CONFIG_SYSCTL
+	unregister_net_sysctl_table(sn->sysctl_header);
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	unregister_net_sysctl_table(sn->compat_sysctl_header);
+	kfree(sn->compat_sysctl_table);
+#endif
+	kfree(sn->sysctl_table);
 #endif
+	kfree(sn);
+
+	net_assign_generic(net, sctp_net_id, NULL);
+}
+
+static struct pernet_operations sctp_net_ops = {
+	.init = sctp_net_init,
+	.exit = sctp_net_exit,
 };
 
 static int __init nf_conntrack_proto_sctp_init(void)
 {
 	int ret;
 
+	ret = register_pernet_gen_subsys(&sctp_net_id, &sctp_net_ops);
+	if (ret < 0)
+		goto out;
+
 	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp4);
 	if (ret) {
 		printk("nf_conntrack_l4proto_sctp4: protocol register failed\n");
-		goto out;
+		goto cleanup_net;
 	}
 	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp6);
 	if (ret) {
@@ -727,12 +830,15 @@ static int __init nf_conntrack_proto_sct
 
  cleanup_sctp4:
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
+ cleanup_net:
+	unregister_pernet_gen_subsys(sctp_net_id, &sctp_net_ops);
  out:
 	return ret;
 }
 
 static void __exit nf_conntrack_proto_sctp_fini(void)
 {
+	unregister_pernet_gen_subsys(sctp_net_id, &sctp_net_ops);
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
 }


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

* [RFC v2 4/7] net: netfilter conntrack - add per-net functionality for UDPLITE protocol
  2009-03-11 20:57 [RFC v2 0/7] introduce netfilter conntrack protos pernet functionality v2 Cyrill Gorcunov
                   ` (2 preceding siblings ...)
  2009-03-11 20:57 ` [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol Cyrill Gorcunov
@ 2009-03-11 20:57 ` Cyrill Gorcunov
  2009-03-12  9:07   ` Daniel Lezcano
  2009-03-11 20:57 ` [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol Cyrill Gorcunov
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-11 20:57 UTC (permalink / raw)
  To: kaber, davem, daniel.lezcano
  Cc: netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

[-- Attachment #1: net-namespace-nf-conntrack-proto-udplite --]
[-- Type: text/plain, Size: 6099 bytes --]

Module specific data moved into per-net site and being allocated/freed
during net namespace creation/deletion.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 net/netfilter/nf_conntrack_proto_udplite.c |  115 ++++++++++++++++++++++++-----
 1 file changed, 96 insertions(+), 19 deletions(-)

Index: linux-2.6.git/net/netfilter/nf_conntrack_proto_udplite.c
===================================================================
--- linux-2.6.git.orig/net/netfilter/nf_conntrack_proto_udplite.c
+++ linux-2.6.git/net/netfilter/nf_conntrack_proto_udplite.c
@@ -17,6 +17,9 @@
 #include <net/ip6_checksum.h>
 #include <net/checksum.h>
 
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv6.h>
@@ -24,8 +27,21 @@
 #include <net/netfilter/nf_conntrack_ecache.h>
 #include <net/netfilter/nf_log.h>
 
-static unsigned int nf_ct_udplite_timeout __read_mostly = 30*HZ;
-static unsigned int nf_ct_udplite_timeout_stream __read_mostly = 180*HZ;
+/* this module per-net specifics */
+static int udplite_net_id;
+struct udplite_net {
+	unsigned int udplite_timeout;
+	unsigned int udplite_timeout_stream;
+#ifdef CONFIG_SYSCTL
+	struct ctl_table_header *sysctl_header;
+	struct ctl_table *sysctl_table;
+#endif
+};
+
+static inline struct udplite_net *udplite_pernet(struct net *net)
+{
+	return net_generic(net, udplite_net_id);
+}
 
 static bool udplite_pkt_to_tuple(const struct sk_buff *skb,
 				 unsigned int dataoff,
@@ -68,16 +84,18 @@ static int udplite_packet(struct nf_conn
 			  u_int8_t pf,
 			  unsigned int hooknum)
 {
+	struct udplite_net *un = udplite_pernet(nf_ct_net(ct));
+
 	/* If we've seen traffic both ways, this is some kind of UDP
 	   stream.  Extend timeout. */
 	if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
 		nf_ct_refresh_acct(ct, ctinfo, skb,
-				   nf_ct_udplite_timeout_stream);
+				   un->udplite_timeout_stream);
 		/* Also, more likely to be important, and not a probe */
 		if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
 			nf_conntrack_event_cache(IPCT_STATUS, ct);
 	} else
-		nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udplite_timeout);
+		nf_ct_refresh_acct(ct, ctinfo, skb, un->udplite_timeout);
 
 	return NF_ACCEPT;
 }
@@ -142,13 +160,11 @@ static int udplite_error(struct net *net
 }
 
 #ifdef CONFIG_SYSCTL
-static unsigned int udplite_sysctl_table_users;
-static struct ctl_table_header *udplite_sysctl_header;
+/* template, data assigned later */
 static struct ctl_table udplite_sysctl_table[] = {
 	{
 		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "nf_conntrack_udplite_timeout",
-		.data		= &nf_ct_udplite_timeout,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -156,7 +172,6 @@ static struct ctl_table udplite_sysctl_t
 	{
 		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "nf_conntrack_udplite_timeout_stream",
-		.data		= &nf_ct_udplite_timeout_stream,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -183,11 +198,6 @@ static struct nf_conntrack_l4proto nf_co
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
-#ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &udplite_sysctl_table_users,
-	.ctl_table_header	= &udplite_sysctl_header,
-	.ctl_table		= udplite_sysctl_table,
-#endif
 };
 
 static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
@@ -206,32 +216,99 @@ static struct nf_conntrack_l4proto nf_co
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
+};
+
+static __net_init int udplite_net_init(struct net *net)
+{
+	struct udplite_net *un;
+	int err;
+
+	un = kmalloc(sizeof(*un), GFP_KERNEL);
+	if (!un)
+		return -ENOMEM;
+
+	/* default values */
+	un->udplite_timeout		= 30 * HZ;
+	un->udplite_timeout_stream	= 180 * HZ;
+
+	err = net_assign_generic(net, udplite_net_id, un);
+	if (err)
+		goto out;
+
+#ifdef CONFIG_SYSCTL
+	err = -ENOMEM;
+	un->sysctl_table = kmemdup(udplite_sysctl_table,
+			sizeof(udplite_sysctl_table), GFP_KERNEL);
+	if (!un->sysctl_table)
+		goto out;
+
+	un->sysctl_table[0].data = &un->udplite_timeout;
+	un->sysctl_table[1].data = &un->udplite_timeout_stream;
+
+	un->sysctl_header = register_net_sysctl_table(net,
+			nf_net_netfilter_sysctl_path, un->sysctl_table);
+	if (!un->sysctl_header)
+		goto out_free;
+#endif /* CONFIG_SYSCTL */
+
+	return 0;
+
+#ifdef CONFIG_SYSCTL
+out_free:
+	kfree(un->sysctl_table);
+#endif
+
+out:
+	kfree(un);
+	return err;
+}
+
+static __net_exit void udplite_net_exit(struct net *net)
+{
+	struct udplite_net *un = udplite_pernet(net);
 #ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &udplite_sysctl_table_users,
-	.ctl_table_header	= &udplite_sysctl_header,
-	.ctl_table		= udplite_sysctl_table,
+	unregister_net_sysctl_table(un->sysctl_header);
+	kfree(un->sysctl_table);
 #endif
+	kfree(un);
+
+	net_assign_generic(net, udplite_net_id, NULL);
+}
+
+static struct pernet_operations udplite_net_ops = {
+	.init = udplite_net_init,
+	.exit = udplite_net_exit,
 };
 
 static int __init nf_conntrack_proto_udplite_init(void)
 {
 	int err;
 
-	err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite4);
+	err = register_pernet_gen_subsys(&udplite_net_id, &udplite_net_ops);
 	if (err < 0)
 		goto err1;
-	err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite6);
+
+	err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite4);
 	if (err < 0)
 		goto err2;
+
+	err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite6);
+	if (err < 0)
+		goto err3;
+
 	return 0;
-err2:
+
+err3:
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
+err2:
+	unregister_pernet_gen_subsys(udplite_net_id, &udplite_net_ops);
 err1:
 	return err;
 }
 
 static void __exit nf_conntrack_proto_udplite_exit(void)
 {
+	unregister_pernet_gen_subsys(udplite_net_id, &udplite_net_ops);
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite6);
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
 }


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

* [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol
  2009-03-11 20:57 [RFC v2 0/7] introduce netfilter conntrack protos pernet functionality v2 Cyrill Gorcunov
                   ` (3 preceding siblings ...)
  2009-03-11 20:57 ` [RFC v2 4/7] net: netfilter conntrack - add per-net functionality for UDPLITE protocol Cyrill Gorcunov
@ 2009-03-11 20:57 ` Cyrill Gorcunov
  2009-03-12  9:15   ` Daniel Lezcano
  2009-03-16 20:58   ` Cyrill Gorcunov
  2009-03-11 20:57 ` [RFC v2 6/7] net: netfilter conntrack - add per-net functionality for UDP protocol Cyrill Gorcunov
  2009-03-11 20:57 ` [RFC v2 7/7] net: netfilter conntrack - add per-net functionality for ICMP protocol Cyrill Gorcunov
  6 siblings, 2 replies; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-11 20:57 UTC (permalink / raw)
  To: kaber, davem, daniel.lezcano
  Cc: netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

[-- Attachment #1: net-namespace-nf-conntrack-proto-tcp --]
[-- Type: text/plain, Size: 18185 bytes --]

Module specific data moved into per-net site and being allocated/freed
during net namespace creation/deletion. For this reason module_init/exit
calls added.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 net/netfilter/nf_conntrack_proto_tcp.c |  290 ++++++++++++++++++++++++---------
 1 file changed, 212 insertions(+), 78 deletions(-)

Index: linux-2.6.git/net/netfilter/nf_conntrack_proto_tcp.c
===================================================================
--- linux-2.6.git.orig/net/netfilter/nf_conntrack_proto_tcp.c
+++ linux-2.6.git/net/netfilter/nf_conntrack_proto_tcp.c
@@ -18,6 +18,9 @@
 
 #include <net/tcp.h>
 
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv6.h>
@@ -29,20 +32,6 @@
 /* Protects ct->proto.tcp */
 static DEFINE_RWLOCK(tcp_lock);
 
-/* "Be conservative in what you do,
-    be liberal in what you accept from others."
-    If it's non-zero, we mark only out of window RST segments as INVALID. */
-static int nf_ct_tcp_be_liberal __read_mostly = 0;
-
-/* If it is set to zero, we disable picking up already established
-   connections. */
-static int nf_ct_tcp_loose __read_mostly = 1;
-
-/* Max number of the retransmitted packets without receiving an (acceptable)
-   ACK from the destination. If this number is reached, a shorter timer
-   will be started. */
-static int nf_ct_tcp_max_retrans __read_mostly = 3;
-
   /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
      closely.  They're more complex. --RR */
 
@@ -64,23 +53,6 @@ static const char *const tcp_conntrack_n
 #define HOURS * 60 MINS
 #define DAYS * 24 HOURS
 
-/* RFC1122 says the R2 limit should be at least 100 seconds.
-   Linux uses 15 packets as limit, which corresponds
-   to ~13-30min depending on RTO. */
-static unsigned int nf_ct_tcp_timeout_max_retrans __read_mostly    =   5 MINS;
-static unsigned int nf_ct_tcp_timeout_unacknowledged __read_mostly =   5 MINS;
-
-static unsigned int tcp_timeouts[TCP_CONNTRACK_MAX] __read_mostly = {
-	[TCP_CONNTRACK_SYN_SENT]	= 2 MINS,
-	[TCP_CONNTRACK_SYN_RECV]	= 60 SECS,
-	[TCP_CONNTRACK_ESTABLISHED]	= 5 DAYS,
-	[TCP_CONNTRACK_FIN_WAIT]	= 2 MINS,
-	[TCP_CONNTRACK_CLOSE_WAIT]	= 60 SECS,
-	[TCP_CONNTRACK_LAST_ACK]	= 30 SECS,
-	[TCP_CONNTRACK_TIME_WAIT]	= 2 MINS,
-	[TCP_CONNTRACK_CLOSE]		= 10 SECS,
-};
-
 #define sNO TCP_CONNTRACK_NONE
 #define sSS TCP_CONNTRACK_SYN_SENT
 #define sSR TCP_CONNTRACK_SYN_RECV
@@ -258,6 +230,51 @@ static const u8 tcp_conntracks[2][6][TCP
 	}
 };
 
+/* per-net specifics */
+static int tcp_net_id;
+struct tcp_net {
+	/*
+	 * "Be conservative in what you do,
+	 * be liberal in what you accept from others."
+	 * If it's non-zero, we mark only out of window
+	 * RST segments as INVALID.
+	 */
+	int tcp_be_liberal;
+	/*
+	 * If it is set to zero, we disable picking up
+	 * already established connections.
+	 */
+	int tcp_loose;
+	/*
+	 * Max number of the retransmitted packets without
+	 * receiving an (acceptable) ACK from the destination.
+	 * If this number is reached, a shorter timer will be started.
+	 */
+	int tcp_max_retrans;
+	/*
+	 * RFC1122 says the R2 limit should be at least 100 seconds.
+	 * Linux uses 15 packets as limit, which corresponds
+	 * to ~13-30min depending on RTO.
+	 */
+	unsigned int tcp_timeout_max_retrans;
+	unsigned int tcp_timeout_unacknowledged;
+
+	unsigned int tcp_timeouts[TCP_CONNTRACK_MAX];
+#ifdef CONFIG_SYSCTL
+	struct ctl_table_header *sysctl_header;
+	struct ctl_table *sysctl_table;
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	struct ctl_table_header *compat_sysctl_header;
+	struct ctl_table *compat_sysctl_table;
+#endif
+#endif
+};
+
+static inline struct tcp_net *tcp_pernet(struct net *net)
+{
+	return net_generic(net, tcp_net_id);
+}
+
 static bool tcp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
 			     struct nf_conntrack_tuple *tuple)
 {
@@ -489,6 +506,7 @@ static bool tcp_in_window(const struct n
 			  u_int8_t pf)
 {
 	struct net *net = nf_ct_net(ct);
+	struct tcp_net *tn;
 	struct ip_ct_tcp_state *sender = &state->seen[dir];
 	struct ip_ct_tcp_state *receiver = &state->seen[!dir];
 	const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
@@ -666,8 +684,9 @@ static bool tcp_in_window(const struct n
 		res = true;
 	} else {
 		res = false;
+		tn = tcp_pernet(net);
 		if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
-		    nf_ct_tcp_be_liberal)
+		    tn->tcp_be_liberal)
 			res = true;
 		if (!res && LOG_INVALID(net, IPPROTO_TCP))
 			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
@@ -810,6 +829,7 @@ static int tcp_packet(struct nf_conn *ct
 		      unsigned int hooknum)
 {
 	struct net *net = nf_ct_net(ct);
+	struct tcp_net *tn;
 	struct nf_conntrack_tuple *tuple;
 	enum tcp_conntrack new_state, old_state;
 	enum ip_conntrack_dir dir;
@@ -948,6 +968,8 @@ static int tcp_packet(struct nf_conn *ct
 	ct->proto.tcp.last_index = index;
 	ct->proto.tcp.last_dir = dir;
 
+	tn = tcp_pernet(net);
+
 	pr_debug("tcp_conntracks: ");
 	nf_ct_dump_tuple(tuple);
 	pr_debug("syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
@@ -960,15 +982,15 @@ static int tcp_packet(struct nf_conn *ct
 	    && new_state == TCP_CONNTRACK_FIN_WAIT)
 		ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
 
-	if (ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans &&
-	    tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans)
-		timeout = nf_ct_tcp_timeout_max_retrans;
+	if (ct->proto.tcp.retrans >= tn->tcp_max_retrans &&
+	    tn->tcp_timeouts[new_state] > tn->tcp_timeout_max_retrans)
+		timeout = tn->tcp_timeout_max_retrans;
 	else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) &
 		 IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED &&
-		 tcp_timeouts[new_state] > nf_ct_tcp_timeout_unacknowledged)
-		timeout = nf_ct_tcp_timeout_unacknowledged;
+		 tn->tcp_timeouts[new_state] > tn->tcp_timeout_unacknowledged)
+		timeout = tn->tcp_timeout_unacknowledged;
 	else
-		timeout = tcp_timeouts[new_state];
+		timeout = tn->tcp_timeouts[new_state];
 	write_unlock_bh(&tcp_lock);
 
 	nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
@@ -1005,6 +1027,7 @@ static bool tcp_new(struct nf_conn *ct, 
 {
 	enum tcp_conntrack new_state;
 	const struct tcphdr *th;
+	struct tcp_net *tn;
 	struct tcphdr _tcph;
 	const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0];
 	const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1];
@@ -1023,6 +1046,8 @@ static bool tcp_new(struct nf_conn *ct, 
 		return false;
 	}
 
+	tn = tcp_pernet(nf_ct_net(ct));
+
 	if (new_state == TCP_CONNTRACK_SYN_SENT) {
 		/* SYN packet */
 		ct->proto.tcp.seen[0].td_end =
@@ -1036,7 +1061,7 @@ static bool tcp_new(struct nf_conn *ct, 
 
 		tcp_options(skb, dataoff, th, &ct->proto.tcp.seen[0]);
 		ct->proto.tcp.seen[1].flags = 0;
-	} else if (nf_ct_tcp_loose == 0) {
+	} else if (tn->tcp_loose == 0) {
 		/* Don't try to pick up connections. */
 		return false;
 	} else {
@@ -1184,75 +1209,64 @@ static int nlattr_to_tcp(struct nlattr *
 #endif
 
 #ifdef CONFIG_SYSCTL
-static unsigned int tcp_sysctl_table_users;
-static struct ctl_table_header *tcp_sysctl_header;
+/* templates, data assigned later */
 static struct ctl_table tcp_sysctl_table[] = {
 	{
 		.procname	= "nf_conntrack_tcp_timeout_syn_sent",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_syn_recv",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_established",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_fin_wait",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_close_wait",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_last_ack",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_time_wait",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_close",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_CLOSE],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_max_retrans",
-		.data		= &nf_ct_tcp_timeout_max_retrans,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_unacknowledged",
-		.data		= &nf_ct_tcp_timeout_unacknowledged,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -1260,7 +1274,6 @@ static struct ctl_table tcp_sysctl_table
 	{
 		.ctl_name	= NET_NF_CONNTRACK_TCP_LOOSE,
 		.procname	= "nf_conntrack_tcp_loose",
-		.data		= &nf_ct_tcp_loose,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
@@ -1268,7 +1281,6 @@ static struct ctl_table tcp_sysctl_table
 	{
 		.ctl_name	= NET_NF_CONNTRACK_TCP_BE_LIBERAL,
 		.procname       = "nf_conntrack_tcp_be_liberal",
-		.data           = &nf_ct_tcp_be_liberal,
 		.maxlen         = sizeof(unsigned int),
 		.mode           = 0644,
 		.proc_handler   = proc_dointvec,
@@ -1276,7 +1288,6 @@ static struct ctl_table tcp_sysctl_table
 	{
 		.ctl_name	= NET_NF_CONNTRACK_TCP_MAX_RETRANS,
 		.procname	= "nf_conntrack_tcp_max_retrans",
-		.data		= &nf_ct_tcp_max_retrans,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
@@ -1290,63 +1301,54 @@ static struct ctl_table tcp_sysctl_table
 static struct ctl_table tcp_compat_sysctl_table[] = {
 	{
 		.procname	= "ip_conntrack_tcp_timeout_syn_sent",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_syn_recv",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_established",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_fin_wait",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_close_wait",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_last_ack",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_time_wait",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_close",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_CLOSE],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_max_retrans",
-		.data		= &nf_ct_tcp_timeout_max_retrans,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -1354,7 +1356,6 @@ static struct ctl_table tcp_compat_sysct
 	{
 		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_LOOSE,
 		.procname	= "ip_conntrack_tcp_loose",
-		.data		= &nf_ct_tcp_loose,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
@@ -1362,7 +1363,6 @@ static struct ctl_table tcp_compat_sysct
 	{
 		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL,
 		.procname	= "ip_conntrack_tcp_be_liberal",
-		.data		= &nf_ct_tcp_be_liberal,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
@@ -1370,7 +1370,6 @@ static struct ctl_table tcp_compat_sysct
 	{
 		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS,
 		.procname	= "ip_conntrack_tcp_max_retrans",
-		.data		= &nf_ct_tcp_max_retrans,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
@@ -1401,14 +1400,6 @@ struct nf_conntrack_l4proto nf_conntrack
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
-#ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &tcp_sysctl_table_users,
-	.ctl_table_header	= &tcp_sysctl_header,
-	.ctl_table		= tcp_sysctl_table,
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
-	.ctl_compat_table	= tcp_compat_sysctl_table,
-#endif
-#endif
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4);
 
@@ -1431,10 +1422,153 @@ struct nf_conntrack_l4proto nf_conntrack
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
+};
+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);
+
+static __net_init int tcp_net_init(struct net *net)
+{
+	struct tcp_net *tn;
+	int err;
+
+	tn = kmalloc(sizeof(*tn), GFP_KERNEL);
+	if (!tn)
+		return -ENOMEM;
+
+	/* default values */
+	tn->tcp_be_liberal	= 0;
+	tn->tcp_loose		= 1;
+	tn->tcp_max_retrans	= 3;
+
+	tn->tcp_timeout_max_retrans	= 5 MINS;
+	tn->tcp_timeout_unacknowledged	= 5 MINS;
+
+	tn->tcp_timeouts[TCP_CONNTRACK_SYN_SENT]	= 2 MINS;
+	tn->tcp_timeouts[TCP_CONNTRACK_SYN_RECV]	= 60 SECS;
+	tn->tcp_timeouts[TCP_CONNTRACK_ESTABLISHED]	= 5 DAYS;
+	tn->tcp_timeouts[TCP_CONNTRACK_FIN_WAIT]	= 2 MINS;
+	tn->tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT]	= 60 SECS;
+	tn->tcp_timeouts[TCP_CONNTRACK_LAST_ACK]	= 30 SECS;
+	tn->tcp_timeouts[TCP_CONNTRACK_TIME_WAIT]	= 2 MINS;
+	tn->tcp_timeouts[TCP_CONNTRACK_CLOSE]		= 10 SECS;
+
+	err = net_assign_generic(net, tcp_net_id, tn);
+	if (err)
+		goto out;
+
+#ifdef CONFIG_SYSCTL
+	err = -ENOMEM;
+	tn->sysctl_table = kmemdup(tcp_sysctl_table,
+			sizeof(tcp_sysctl_table), GFP_KERNEL);
+	if (!tn->sysctl_table)
+		goto out;
+
+#define ___PERNET_TO_DAT(i, j) \
+	tn->sysctl_table[i].data = &tn->tcp_timeouts[j]
+
+	___PERNET_TO_DAT(0, TCP_CONNTRACK_SYN_SENT);
+	___PERNET_TO_DAT(1, TCP_CONNTRACK_SYN_RECV);
+	___PERNET_TO_DAT(2, TCP_CONNTRACK_ESTABLISHED);
+	___PERNET_TO_DAT(3, TCP_CONNTRACK_FIN_WAIT);
+	___PERNET_TO_DAT(4, TCP_CONNTRACK_CLOSE_WAIT);
+	___PERNET_TO_DAT(5, TCP_CONNTRACK_LAST_ACK);
+	___PERNET_TO_DAT(6, TCP_CONNTRACK_TIME_WAIT);
+	___PERNET_TO_DAT(7, TCP_CONNTRACK_CLOSE);
+
+#undef ___PERNET_TO_DAT
+
+	tn->sysctl_table[8].data = &tn->tcp_timeout_max_retrans;
+	tn->sysctl_table[9].data = &tn->tcp_timeout_unacknowledged;
+	tn->sysctl_table[10].data = &tn->tcp_loose;
+	tn->sysctl_table[11].data = &tn->tcp_be_liberal;
+	tn->sysctl_table[12].data = &tn->tcp_max_retrans;
+
+	tn->sysctl_header = register_net_sysctl_table(net,
+			nf_net_netfilter_sysctl_path, tn->sysctl_table);
+	if (!tn->sysctl_header)
+		goto out_free;
+
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	tn->compat_sysctl_table = kmemdup(tcp_compat_sysctl_table,
+			sizeof(tcp_compat_sysctl_table), GFP_KERNEL);
+	if (!tn->compat_sysctl_table)
+		goto out_sysctl;
+
+#define ___PERNET_TO_DAT(i, j) \
+	tn->compat_sysctl_table[i].data = &tn->tcp_timeouts[j]
+
+	___PERNET_TO_DAT(0, TCP_CONNTRACK_SYN_SENT);
+	___PERNET_TO_DAT(1, TCP_CONNTRACK_SYN_RECV);
+	___PERNET_TO_DAT(2, TCP_CONNTRACK_ESTABLISHED);
+	___PERNET_TO_DAT(3, TCP_CONNTRACK_FIN_WAIT);
+	___PERNET_TO_DAT(4, TCP_CONNTRACK_CLOSE_WAIT);
+	___PERNET_TO_DAT(5, TCP_CONNTRACK_LAST_ACK);
+	___PERNET_TO_DAT(6, TCP_CONNTRACK_TIME_WAIT);
+	___PERNET_TO_DAT(7, TCP_CONNTRACK_CLOSE);
+
+#undef ___PERNET_TO_DAT
+
+	tn->compat_sysctl_table[8].data = &tn->tcp_timeout_max_retrans;
+	tn->compat_sysctl_table[9].data = &tn->tcp_loose;
+	tn->compat_sysctl_table[10].data = &tn->tcp_be_liberal;
+	tn->compat_sysctl_table[11].data = &tn->tcp_max_retrans;
+
+	tn->compat_sysctl_header = register_net_sysctl_table(net,
+			nf_net_ipv4_netfilter_sysctl_path,
+			tn->compat_sysctl_table);
+	if (!tn->compat_sysctl_header)
+		goto out_free_compat;
+#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
+#endif /* CONFIG_SYSCTL */
+
+	return 0;
+
+#ifdef CONFIG_SYSCTL
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+out_free_compat:
+	kfree(tn->compat_sysctl_table);
+#endif
+out_sysctl:
+	unregister_net_sysctl_table(tn->sysctl_header);
+out_free:
+	kfree(tn->sysctl_table);
+#endif
+
+out:
+	kfree(tn);
+	return err;
+}
+
+static __net_exit void tcp_net_exit(struct net *net)
+{
+	struct tcp_net *tn = tcp_pernet(net);
 #ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &tcp_sysctl_table_users,
-	.ctl_table_header	= &tcp_sysctl_header,
-	.ctl_table		= tcp_sysctl_table,
+	unregister_net_sysctl_table(tn->sysctl_header);
+	kfree(tn->sysctl_table);
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	unregister_net_sysctl_table(tn->compat_sysctl_header);
+	kfree(tn->compat_sysctl_table);
 #endif
+#endif
+	kfree(tn);
+
+	net_assign_generic(net, tcp_net_id, NULL);
 };
-EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);
+
+static struct pernet_operations tcp_net_ops = {
+	.init = tcp_net_init,
+	.exit = tcp_net_exit,
+};
+
+static int __init nf_ct_tcp_proto_init(void)
+{
+	return register_pernet_gen_subsys(&tcp_net_id, &tcp_net_ops);
+}
+
+static void __exit nf_ct_tcp_proto_fini(void)
+{
+	unregister_pernet_gen_subsys(tcp_net_id, &tcp_net_ops);
+}
+
+module_init(nf_ct_tcp_proto_init);
+module_exit(nf_ct_tcp_proto_fini);
+MODULE_LICENSE("GPL");


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

* [RFC v2 6/7] net: netfilter conntrack - add per-net functionality for UDP protocol
  2009-03-11 20:57 [RFC v2 0/7] introduce netfilter conntrack protos pernet functionality v2 Cyrill Gorcunov
                   ` (4 preceding siblings ...)
  2009-03-11 20:57 ` [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol Cyrill Gorcunov
@ 2009-03-11 20:57 ` Cyrill Gorcunov
  2009-03-12  9:49   ` Daniel Lezcano
  2009-03-11 20:57 ` [RFC v2 7/7] net: netfilter conntrack - add per-net functionality for ICMP protocol Cyrill Gorcunov
  6 siblings, 1 reply; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-11 20:57 UTC (permalink / raw)
  To: kaber, davem, daniel.lezcano
  Cc: netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

[-- Attachment #1: net-namespace-nf-conntrack-proto-udp --]
[-- Type: text/plain, Size: 6876 bytes --]

Module specific data moved into per-net site and being allocated/freed
during net namespace creation/deletion. For this reason module_init/exit
calls added.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 net/netfilter/nf_conntrack_proto_udp.c |  152 ++++++++++++++++++++++++++++-----
 1 file changed, 130 insertions(+), 22 deletions(-)

Index: linux-2.6.git/net/netfilter/nf_conntrack_proto_udp.c
===================================================================
--- linux-2.6.git.orig/net/netfilter/nf_conntrack_proto_udp.c
+++ linux-2.6.git/net/netfilter/nf_conntrack_proto_udp.c
@@ -16,6 +16,9 @@
 #include <net/ip6_checksum.h>
 #include <net/checksum.h>
 
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv6.h>
@@ -23,8 +26,25 @@
 #include <net/netfilter/nf_conntrack_ecache.h>
 #include <net/netfilter/nf_log.h>
 
-static unsigned int nf_ct_udp_timeout __read_mostly = 30*HZ;
-static unsigned int nf_ct_udp_timeout_stream __read_mostly = 180*HZ;
+/* per-net specifics */
+static int udp_net_id;
+struct udp_net {
+	unsigned int udp_timeout;
+	unsigned int udp_timeout_stream;
+#ifdef CONFIG_SYSCTL
+	struct ctl_table_header *sysctl_header;
+	struct ctl_table *sysctl_table;
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	struct ctl_table_header *compat_sysctl_header;
+	struct ctl_table *compat_sysctl_table;
+#endif
+#endif
+};
+
+static inline struct udp_net *udp_pernet(struct net *net)
+{
+	return net_generic(net, udp_net_id);
+}
 
 static bool udp_pkt_to_tuple(const struct sk_buff *skb,
 			     unsigned int dataoff,
@@ -69,15 +89,17 @@ static int udp_packet(struct nf_conn *ct
 		      u_int8_t pf,
 		      unsigned int hooknum)
 {
+	struct udp_net *un = udp_pernet(nf_ct_net(ct));
+
 	/* If we've seen traffic both ways, this is some kind of UDP
 	   stream.  Extend timeout. */
 	if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
-		nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout_stream);
+		nf_ct_refresh_acct(ct, ctinfo, skb, un->udp_timeout_stream);
 		/* Also, more likely to be important, and not a probe */
 		if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
 			nf_conntrack_event_cache(IPCT_STATUS, ct);
 	} else
-		nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout);
+		nf_ct_refresh_acct(ct, ctinfo, skb, un->udp_timeout);
 
 	return NF_ACCEPT;
 }
@@ -135,19 +157,16 @@ static int udp_error(struct net *net, st
 }
 
 #ifdef CONFIG_SYSCTL
-static unsigned int udp_sysctl_table_users;
-static struct ctl_table_header *udp_sysctl_header;
+/* templates, data assigned later */
 static struct ctl_table udp_sysctl_table[] = {
 	{
 		.procname	= "nf_conntrack_udp_timeout",
-		.data		= &nf_ct_udp_timeout,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_udp_timeout_stream",
-		.data		= &nf_ct_udp_timeout_stream,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -160,14 +179,12 @@ static struct ctl_table udp_sysctl_table
 static struct ctl_table udp_compat_sysctl_table[] = {
 	{
 		.procname	= "ip_conntrack_udp_timeout",
-		.data		= &nf_ct_udp_timeout,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_udp_timeout_stream",
-		.data		= &nf_ct_udp_timeout_stream,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -195,14 +212,7 @@ struct nf_conntrack_l4proto nf_conntrack
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
-#ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &udp_sysctl_table_users,
-	.ctl_table_header	= &udp_sysctl_header,
-	.ctl_table		= udp_sysctl_table,
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
-	.ctl_compat_table	= udp_compat_sysctl_table,
-#endif
-#endif
+	.me			= THIS_MODULE,
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp4);
 
@@ -222,10 +232,108 @@ struct nf_conntrack_l4proto nf_conntrack
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
+	.me			= THIS_MODULE,
+};
+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp6);
+
+static __net_init int udp_net_init(struct net *net)
+{
+	struct udp_net *un;
+	int err;
+
+	un = kmalloc(sizeof(*un), GFP_KERNEL);
+	if (!un)
+		return -ENOMEM;
+
+	/* default values */
+	un->udp_timeout		= 30 * HZ;
+	un->udp_timeout_stream	= 180 * HZ;
+
+	err = net_assign_generic(net, udp_net_id, un);
+	if (err)
+		goto out;
+
+#ifdef CONFIG_SYSCTL
+	err = -ENOMEM;
+	un->sysctl_table = kmemdup(udp_sysctl_table,
+			sizeof(udp_sysctl_table), GFP_KERNEL);
+	if (!un->sysctl_table)
+		goto out;
+
+	un->sysctl_table[0].data = &un->udp_timeout;
+	un->sysctl_table[1].data = &un->udp_timeout_stream;
+
+	un->sysctl_header = register_net_sysctl_table(net,
+			nf_net_netfilter_sysctl_path, un->sysctl_table);
+	if (!un->sysctl_header)
+		goto out_free;
+
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	un->compat_sysctl_table = kmemdup(udp_compat_sysctl_table,
+			sizeof(udp_compat_sysctl_table), GFP_KERNEL);
+	if (!un->compat_sysctl_table)
+		goto out_sysctl;
+
+	un->compat_sysctl_table[0].data = &un->udp_timeout;
+	un->compat_sysctl_table[1].data = &un->udp_timeout_stream;
+
+	un->compat_sysctl_header = register_net_sysctl_table(net,
+			nf_net_ipv4_netfilter_sysctl_path,
+			un->compat_sysctl_table);
+	if (!un->compat_sysctl_header)
+		goto out_free_compat;
+#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
+#endif /* CONFIG_SYSCTL */
+
+	return 0;
+
+#ifdef CONFIG_SYSCTL
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+out_free_compat:
+	kfree(un->compat_sysctl_table);
+#endif
+out_sysctl:
+	unregister_net_sysctl_table(un->sysctl_header);
+out_free:
+	kfree(un->sysctl_table);
+#endif
+
+out:
+	kfree(un);
+	return err;
+}
+
+static __net_exit void udp_net_exit(struct net *net)
+{
+	struct udp_net *un = udp_pernet(net);
 #ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &udp_sysctl_table_users,
-	.ctl_table_header	= &udp_sysctl_header,
-	.ctl_table		= udp_sysctl_table,
+	unregister_net_sysctl_table(un->sysctl_header);
+	kfree(un->sysctl_table);
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	unregister_net_sysctl_table(un->compat_sysctl_header);
+	kfree(un->compat_sysctl_table);
 #endif
+#endif
+	kfree(un);
+
+	net_assign_generic(net, udp_net_id, NULL);
+}
+
+static struct pernet_operations udp_net_ops = {
+	.init = udp_net_init,
+	.exit = udp_net_exit,
 };
-EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp6);
+
+int __init nf_ct_udp_proto_init(void)
+{
+	return register_pernet_gen_subsys(&udp_net_id, &udp_net_ops);
+}
+
+void __exit nf_ct_udp_proto_fini(void)
+{
+	unregister_pernet_gen_subsys(udp_net_id, &udp_net_ops);
+}
+
+module_init(nf_ct_udp_proto_init);
+module_exit(nf_ct_udp_proto_fini);
+MODULE_LICENSE("GPL");


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

* [RFC v2 7/7] net: netfilter conntrack - add per-net functionality for ICMP protocol
  2009-03-11 20:57 [RFC v2 0/7] introduce netfilter conntrack protos pernet functionality v2 Cyrill Gorcunov
                   ` (5 preceding siblings ...)
  2009-03-11 20:57 ` [RFC v2 6/7] net: netfilter conntrack - add per-net functionality for UDP protocol Cyrill Gorcunov
@ 2009-03-11 20:57 ` Cyrill Gorcunov
  2009-03-12  9:51   ` Daniel Lezcano
  6 siblings, 1 reply; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-11 20:57 UTC (permalink / raw)
  To: kaber, davem, daniel.lezcano
  Cc: netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

[-- Attachment #1: net-namespace-nf-conntrack-proto-icmp --]
[-- Type: text/plain, Size: 5390 bytes --]

Module specific data moved into per-net site and being allocated/freed
during net namespace creation/deletion. For this reason module_init/exit
calls added.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 net/ipv4/netfilter/nf_conntrack_proto_icmp.c |  128 +++++++++++++++++++++++++--
 1 file changed, 120 insertions(+), 8 deletions(-)

Index: linux-2.6.git/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
===================================================================
--- linux-2.6.git.orig/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ linux-2.6.git/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 #include <linux/timer.h>
 #include <linux/netfilter.h>
+#include <linux/module.h>
 #include <linux/in.h>
 #include <linux/icmp.h>
 #include <linux/seq_file.h>
@@ -20,7 +21,27 @@
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/nf_log.h>
 
-static unsigned int nf_ct_icmp_timeout __read_mostly = 30*HZ;
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
+/* per-net specifics */
+static int icmp_net_id;
+struct icmp_net {
+	unsigned int icmp_timeout;
+#ifdef CONFIG_SYSCTL
+	struct ctl_table_header *sysctl_header;
+	struct ctl_table *sysctl_table;
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	struct ctl_table_header *compat_sysctl_header;
+	struct ctl_table *compat_sysctl_table;
+#endif
+#endif
+};
+
+static inline struct icmp_net *icmp_pernet(struct net *net)
+{
+	return net_generic(net, icmp_net_id);
+}
 
 static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
 			      struct nf_conntrack_tuple *tuple)
@@ -90,9 +111,10 @@ static int icmp_packet(struct nf_conn *c
 		if (atomic_dec_and_test(&ct->proto.icmp.count))
 			nf_ct_kill_acct(ct, ctinfo, skb);
 	} else {
+		struct icmp_net *in = icmp_pernet(nf_ct_net(ct));
 		atomic_inc(&ct->proto.icmp.count);
 		nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
-		nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
+		nf_ct_refresh_acct(ct, ctinfo, skb, in->icmp_timeout);
 	}
 
 	return NF_ACCEPT;
@@ -265,11 +287,10 @@ static int icmp_nlattr_to_tuple(struct n
 #endif
 
 #ifdef CONFIG_SYSCTL
-static struct ctl_table_header *icmp_sysctl_header;
+/* templates, data assigned later */
 static struct ctl_table icmp_sysctl_table[] = {
 	{
 		.procname	= "nf_conntrack_icmp_timeout",
-		.data		= &nf_ct_icmp_timeout,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -282,7 +303,6 @@ static struct ctl_table icmp_sysctl_tabl
 static struct ctl_table icmp_compat_sysctl_table[] = {
 	{
 		.procname	= "ip_conntrack_icmp_timeout",
-		.data		= &nf_ct_icmp_timeout,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -312,11 +332,103 @@ struct nf_conntrack_l4proto nf_conntrack
 	.nlattr_to_tuple	= icmp_nlattr_to_tuple,
 	.nla_policy		= icmp_nla_policy,
 #endif
+};
+
+static __net_init int icmp_net_init(struct net *net)
+{
+	struct icmp_net *in;
+	int err;
+
+	in = kmalloc(sizeof(*in), GFP_KERNEL);
+	if (!in)
+		return -ENOMEM;
+
+	/* default values */
+	in->icmp_timeout = 30 * HZ;
+
+	err = net_assign_generic(net, icmp_net_id, in);
+	if (err)
+		goto out;
+
+#ifdef CONFIG_SYSCTL
+	err = -ENOMEM;
+	in->sysctl_table = kmemdup(icmp_sysctl_table,
+			sizeof(icmp_sysctl_table), GFP_KERNEL);
+	if (!in->sysctl_table)
+		goto out;
+
+	in->sysctl_table[0].data = &in->icmp_timeout;
+
+	in->sysctl_header = register_net_sysctl_table(net,
+			nf_net_netfilter_sysctl_path, in->sysctl_table);
+	if (!in->sysctl_header)
+		goto out_free;
+
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	in->compat_sysctl_table = kmemdup(icmp_compat_sysctl_table,
+			sizeof(icmp_compat_sysctl_table), GFP_KERNEL);
+	if (!in->compat_sysctl_table)
+		goto out_sysctl;
+
+	in->compat_sysctl_table[0].data = &in->icmp_timeout;
+
+	in->compat_sysctl_header = register_net_sysctl_table(net,
+			nf_net_ipv4_netfilter_sysctl_path,
+			in->compat_sysctl_table);
+	if (!in->compat_sysctl_header)
+		goto out_free_compat;
+#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
+#endif /* CONFIG_SYSCTL */
+
+	return 0;
+
+#ifdef CONFIG_SYSCTL
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+out_free_compat:
+	kfree(in->compat_sysctl_table);
+#endif
+out_sysctl:
+	unregister_net_sysctl_table(in->sysctl_header);
+out_free:
+	kfree(in->sysctl_table);
+#endif
+
+out:
+	kfree(in);
+	return err;
+}
+
+static __net_exit void icmp_net_exit(struct net *net)
+{
+	struct icmp_net *in = icmp_pernet(net);
 #ifdef CONFIG_SYSCTL
-	.ctl_table_header	= &icmp_sysctl_header,
-	.ctl_table		= icmp_sysctl_table,
+	unregister_net_sysctl_table(in->sysctl_header);
+	kfree(in->sysctl_table);
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
-	.ctl_compat_table	= icmp_compat_sysctl_table,
+	unregister_net_sysctl_table(in->compat_sysctl_header);
+	kfree(in->compat_sysctl_table);
 #endif
 #endif
+	kfree(in);
+
+	net_assign_generic(net, icmp_net_id, NULL);
+}
+
+static struct pernet_operations icmp_net_ops = {
+	.init = icmp_net_init,
+	.exit = icmp_net_exit,
 };
+
+int __init nf_ct_icmp_proto_init(void)
+{
+	return register_pernet_gen_subsys(&icmp_net_id, &icmp_net_ops);
+}
+
+void __exit nf_ct_icmp_proto_fini(void)
+{
+	unregister_pernet_gen_subsys(icmp_net_id, &icmp_net_ops);
+}
+
+module_init(nf_ct_icmp_proto_init);
+module_exit(nf_ct_icmp_proto_fini);
+MODULE_LICENSE("GPL");


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

* Re: [RFC v2 1/7] net: sysctl_net - use net_eq to compare nets
  2009-03-11 20:57 ` [RFC v2 1/7] net: sysctl_net - use net_eq to compare nets Cyrill Gorcunov
@ 2009-03-12  8:50   ` Daniel Lezcano
  2009-03-16 15:24     ` Patrick McHardy
  0 siblings, 1 reply; 29+ messages in thread
From: Daniel Lezcano @ 2009-03-12  8:50 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: kaber, davem, netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

Cyrill Gorcunov wrote:
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> ---
>
>   
Acked-by: Daniel Lezcano <daniel.lezcano@free.fr>

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

* Re: [RFC v2 2/7] net: netfilter conntrack - add per-net functionality for DCCP protocol
  2009-03-11 20:57 ` [RFC v2 2/7] net: netfilter conntrack - add per-net functionality for DCCP protocol Cyrill Gorcunov
@ 2009-03-12  8:54   ` Daniel Lezcano
  2009-03-16 15:31     ` Patrick McHardy
  0 siblings, 1 reply; 29+ messages in thread
From: Daniel Lezcano @ 2009-03-12  8:54 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: kaber, davem, netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

Cyrill Gorcunov wrote:
> Module specific data moved into per-net site and being allocated/freed
> during net namespace creation/deletion.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> ---
>   
Acked-by: Daniel Lezcano <daniel.lezcano@free.fr>

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

* Re: [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol
  2009-03-11 20:57 ` [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol Cyrill Gorcunov
@ 2009-03-12  9:03   ` Daniel Lezcano
  2009-03-16 15:35   ` Patrick McHardy
  1 sibling, 0 replies; 29+ messages in thread
From: Daniel Lezcano @ 2009-03-12  9:03 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: kaber, davem, netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

Cyrill Gorcunov wrote:
> Module specific data moved into per-net site and being allocated/freed
> during net namespace creation/deletion.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> ---
>   
Acked-by: Daniel Lezcano <daniel.lezcano@free.fr>

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

* Re: [RFC v2 4/7] net: netfilter conntrack - add per-net functionality for UDPLITE protocol
  2009-03-11 20:57 ` [RFC v2 4/7] net: netfilter conntrack - add per-net functionality for UDPLITE protocol Cyrill Gorcunov
@ 2009-03-12  9:07   ` Daniel Lezcano
  0 siblings, 0 replies; 29+ messages in thread
From: Daniel Lezcano @ 2009-03-12  9:07 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: kaber, davem, netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

Cyrill Gorcunov wrote:
> Module specific data moved into per-net site and being allocated/freed
> during net namespace creation/deletion.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> ---
>  
Acked-by: Daniel Lezcano <daniel.lezcano@free.fr>

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

* Re: [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol
  2009-03-11 20:57 ` [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol Cyrill Gorcunov
@ 2009-03-12  9:15   ` Daniel Lezcano
  2009-03-16 20:58   ` Cyrill Gorcunov
  1 sibling, 0 replies; 29+ messages in thread
From: Daniel Lezcano @ 2009-03-12  9:15 UTC (permalink / raw)
  Cc: kaber, davem, netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

Cyrill Gorcunov wrote:
> Module specific data moved into per-net site and being allocated/freed
> during net namespace creation/deletion. For this reason module_init/exit
> calls added.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> ---
>   
Acked-by: Daniel Lezcano <daniel.lezcano@free.fr>

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

* Re: [RFC v2 6/7] net: netfilter conntrack - add per-net functionality for UDP protocol
  2009-03-11 20:57 ` [RFC v2 6/7] net: netfilter conntrack - add per-net functionality for UDP protocol Cyrill Gorcunov
@ 2009-03-12  9:49   ` Daniel Lezcano
  0 siblings, 0 replies; 29+ messages in thread
From: Daniel Lezcano @ 2009-03-12  9:49 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: kaber, davem, netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

Cyrill Gorcunov wrote:
> Module specific data moved into per-net site and being allocated/freed
> during net namespace creation/deletion. For this reason module_init/exit
> calls added.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> ---
>   
Acked-by: Daniel Lezcano <daniel.lezcano@free.fr>

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

* Re: [RFC v2 7/7] net: netfilter conntrack - add per-net functionality for ICMP protocol
  2009-03-11 20:57 ` [RFC v2 7/7] net: netfilter conntrack - add per-net functionality for ICMP protocol Cyrill Gorcunov
@ 2009-03-12  9:51   ` Daniel Lezcano
  0 siblings, 0 replies; 29+ messages in thread
From: Daniel Lezcano @ 2009-03-12  9:51 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: kaber, davem, netdev, netfilter-devel, xemul, adobriyan, Cyrill Gorcunov

Cyrill Gorcunov wrote:
> Module specific data moved into per-net site and being allocated/freed
> during net namespace creation/deletion. For this reason module_init/exit
> calls added.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> ---
>   
Acked-by: Daniel Lezcano <daniel.lezcano@free.fr>

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

* Re: [RFC v2 1/7] net: sysctl_net - use net_eq to compare nets
  2009-03-12  8:50   ` Daniel Lezcano
@ 2009-03-16 15:24     ` Patrick McHardy
  0 siblings, 0 replies; 29+ messages in thread
From: Patrick McHardy @ 2009-03-16 15:24 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Cyrill Gorcunov, davem, netdev, netfilter-devel, xemul,
	adobriyan, Cyrill Gorcunov

Daniel Lezcano wrote:
> Cyrill Gorcunov wrote:
>> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
>> ---
>>
>>   
> Acked-by: Daniel Lezcano <daniel.lezcano@free.fr>

Applied, thanks.


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

* Re: [RFC v2 2/7] net: netfilter conntrack - add per-net functionality for DCCP protocol
  2009-03-12  8:54   ` Daniel Lezcano
@ 2009-03-16 15:31     ` Patrick McHardy
  0 siblings, 0 replies; 29+ messages in thread
From: Patrick McHardy @ 2009-03-16 15:31 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Cyrill Gorcunov, davem, netdev, netfilter-devel, xemul,
	adobriyan, Cyrill Gorcunov

Daniel Lezcano wrote:
> Cyrill Gorcunov wrote:
>> Module specific data moved into per-net site and being allocated/freed
>> during net namespace creation/deletion.
>>
>> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
>> ---
>>   
> Acked-by: Daniel Lezcano <daniel.lezcano@free.fr>

Applied, thanks.

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

* Re: [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol
  2009-03-11 20:57 ` [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol Cyrill Gorcunov
  2009-03-12  9:03   ` Daniel Lezcano
@ 2009-03-16 15:35   ` Patrick McHardy
  2009-03-16 15:46     ` Cyrill Gorcunov
  1 sibling, 1 reply; 29+ messages in thread
From: Patrick McHardy @ 2009-03-16 15:35 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: davem, daniel.lezcano, netdev, netfilter-devel, xemul, adobriyan,
	Cyrill Gorcunov

Cyrill Gorcunov wrote:
> Module specific data moved into per-net site and being allocated/freed
> during net namespace creation/deletion.

> +#define ___PERNET_TO_DAT(i, j) \
> +	sn->sysctl_table[i].data = &sn->sctp_timeouts[j]
> +
> +	___PERNET_TO_DAT(0, SCTP_CONNTRACK_CLOSED);
> +	___PERNET_TO_DAT(1, SCTP_CONNTRACK_COOKIE_WAIT);
> +	___PERNET_TO_DAT(2, SCTP_CONNTRACK_COOKIE_ECHOED);
> +	___PERNET_TO_DAT(3, SCTP_CONNTRACK_ESTABLISHED);
> +	___PERNET_TO_DAT(4, SCTP_CONNTRACK_SHUTDOWN_SENT);
> +	___PERNET_TO_DAT(5, SCTP_CONNTRACK_SHUTDOWN_RECD);
> +	___PERNET_TO_DAT(6, SCTP_CONNTRACK_SHUTDOWN_ACK_SENT);
> +
> +#undef ___PERNET_TO_DAT
> +
> +	sn->sysctl_header = register_net_sysctl_table(net,
> +			nf_net_netfilter_sysctl_path, sn->sysctl_table);
> +	if (!sn->sysctl_header)
> +		goto out_free;
> +
> +#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
> +	sn->compat_sysctl_table = kmemdup(sctp_compat_sysctl_table,
> +			sizeof(sctp_compat_sysctl_table), GFP_KERNEL);
> +	if (!sn->compat_sysctl_table)
> +		goto out_sysctl;
> +
> +#define ___PERNET_TO_DAT(i, j) \
> +	sn->compat_sysctl_table[i].data = &sn->sctp_timeouts[j]
> +
> +	___PERNET_TO_DAT(0, SCTP_CONNTRACK_CLOSED);
> +	___PERNET_TO_DAT(1, SCTP_CONNTRACK_COOKIE_WAIT);
> +	___PERNET_TO_DAT(2, SCTP_CONNTRACK_COOKIE_ECHOED);
> +	___PERNET_TO_DAT(3, SCTP_CONNTRACK_ESTABLISHED);
> +	___PERNET_TO_DAT(4, SCTP_CONNTRACK_SHUTDOWN_SENT);
> +	___PERNET_TO_DAT(5, SCTP_CONNTRACK_SHUTDOWN_RECD);
> +	___PERNET_TO_DAT(6, SCTP_CONNTRACK_SHUTDOWN_ACK_SENT);
> +
> +#undef ___PERNET_TO_DAT

This is really ugly and is somewhat risky since those magic offsets need
to be kept in sync. Any chance (I don't have a suggestion currently) to
do this in a nicer way?

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

* Re: [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol
  2009-03-16 15:35   ` Patrick McHardy
@ 2009-03-16 15:46     ` Cyrill Gorcunov
  2009-03-16 15:48       ` Patrick McHardy
  0 siblings, 1 reply; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-16 15:46 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: davem, daniel.lezcano, netdev, netfilter-devel, xemul, adobriyan

[Patrick McHardy - Mon, Mar 16, 2009 at 04:35:11PM +0100]
...
> +#define ___PERNET_TO_DAT(i, j) \
>> +	sn->compat_sysctl_table[i].data = &sn->sctp_timeouts[j]
>> +
>> +	___PERNET_TO_DAT(0, SCTP_CONNTRACK_CLOSED);
>> +	___PERNET_TO_DAT(1, SCTP_CONNTRACK_COOKIE_WAIT);
>> +	___PERNET_TO_DAT(2, SCTP_CONNTRACK_COOKIE_ECHOED);
>> +	___PERNET_TO_DAT(3, SCTP_CONNTRACK_ESTABLISHED);
>> +	___PERNET_TO_DAT(4, SCTP_CONNTRACK_SHUTDOWN_SENT);
>> +	___PERNET_TO_DAT(5, SCTP_CONNTRACK_SHUTDOWN_RECD);
>> +	___PERNET_TO_DAT(6, SCTP_CONNTRACK_SHUTDOWN_ACK_SENT);
>> +
>> +#undef ___PERNET_TO_DAT
>
> This is really ugly and is somewhat risky since those magic offsets need
> to be kept in sync. Any chance (I don't have a suggestion currently) to
> do this in a nicer way?
>

Give me some time Patrick, will try. Actually initial idea
of these macros was to eliminate 'possible' problems caused
by for (;;) form (enum could be rearranged and we will fail
silently). So I guess the some 'new' form of template would
help (instead of current "ctrl table as a templae"). So
will return with new proposal. Thanks for review!

	- Cyrill -

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

* Re: [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol
  2009-03-16 15:46     ` Cyrill Gorcunov
@ 2009-03-16 15:48       ` Patrick McHardy
  2009-03-16 18:21         ` Cyrill Gorcunov
  0 siblings, 1 reply; 29+ messages in thread
From: Patrick McHardy @ 2009-03-16 15:48 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: davem, daniel.lezcano, netdev, netfilter-devel, xemul, adobriyan

Cyrill Gorcunov wrote:
> [Patrick McHardy - Mon, Mar 16, 2009 at 04:35:11PM +0100]
> ...
>> +#define ___PERNET_TO_DAT(i, j) \
>>> +	sn->compat_sysctl_table[i].data = &sn->sctp_timeouts[j]
>>> +
>>> +	___PERNET_TO_DAT(0, SCTP_CONNTRACK_CLOSED);
>>> +	___PERNET_TO_DAT(1, SCTP_CONNTRACK_COOKIE_WAIT);
>>> +	___PERNET_TO_DAT(2, SCTP_CONNTRACK_COOKIE_ECHOED);
>>> +	___PERNET_TO_DAT(3, SCTP_CONNTRACK_ESTABLISHED);
>>> +	___PERNET_TO_DAT(4, SCTP_CONNTRACK_SHUTDOWN_SENT);
>>> +	___PERNET_TO_DAT(5, SCTP_CONNTRACK_SHUTDOWN_RECD);
>>> +	___PERNET_TO_DAT(6, SCTP_CONNTRACK_SHUTDOWN_ACK_SENT);
>>> +
>>> +#undef ___PERNET_TO_DAT
>> This is really ugly and is somewhat risky since those magic offsets need
>> to be kept in sync. Any chance (I don't have a suggestion currently) to
>> do this in a nicer way?
>>
> 
> Give me some time Patrick, will try. Actually initial idea
> of these macros was to eliminate 'possible' problems caused
> by for (;;) form (enum could be rearranged and we will fail
> silently).

The state enums are pretty much set in stone as they're part of the
userspace ABI.

> So I guess the some 'new' form of template would
> help (instead of current "ctrl table as a templae"). So
> will return with new proposal. Thanks for review!

Thanks.

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

* Re: [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol
  2009-03-16 15:48       ` Patrick McHardy
@ 2009-03-16 18:21         ` Cyrill Gorcunov
  2009-03-16 18:29           ` Patrick McHardy
  0 siblings, 1 reply; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-16 18:21 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: davem, daniel.lezcano, netdev, netfilter-devel, xemul, adobriyan

[Patrick McHardy - Mon, Mar 16, 2009 at 04:48:28PM +0100]
...
>
>> Give me some time Patrick, will try. Actually initial idea
>> of these macros was to eliminate 'possible' problems caused
>> by for (;;) form (enum could be rearranged and we will fail
>> silently).
>
> The state enums are pretty much set in stone as they're part of the
> userspace ABI.
>
>> So I guess the some 'new' form of template would
>> help (instead of current "ctrl table as a templae"). So
>> will return with new proposal. Thanks for review!
>
> Thanks.
>

After playing a bit with ctrl tables (thought about additional
mapping set or say new sysctl helper structure, or even using
extra1 member from struct ctl_table as temporary index) -- 
you were right in your first propose on this patch. Iterative
fasion is only more or less convenient here indeed :)

Patrick, take a look please on the snippet below (that is how
it looks now).
...

+static __net_init int sctp_net_init(struct net *net)
+{
+	struct sctp_net *sn;
+	int err;
+
+	sn = kmalloc(sizeof(*sn), GFP_KERNEL);
+	if (!sn)
+		return -ENOMEM;
+
+	/* default values */
+	sn->sctp_timeouts[SCTP_CONNTRACK_CLOSED]	= 10 SECS;
+	sn->sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT]	= 3 SECS;
+	sn->sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED]	= 3 SECS;
+	sn->sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED]	= 5 DAYS;
+	sn->sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT]	= 300 SECS / 1000;
+	sn->sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD]	= 300 SECS / 1000;
+	sn->sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS;
+
+	err = net_assign_generic(net, sctp_net_id, sn);
+	if (err)
+		goto out;
+
+	/*
+	 * Pin per-net data to sysctl tables
+	 *
+	 * We allocate new ctrl tables from predefined templates
+	 * and then assign .data fields iteratively, we allowed
+	 * to do so since SCTP_CONNTRACK_... enum is a part of
+	 * userspace ABI and it's hardly that the enum entries
+	 * will be rearranged
+	 */
+
 #ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &sctp_sysctl_table_users,
-	.ctl_table_header	= &sctp_sysctl_header,
-	.ctl_table		= sctp_sysctl_table,
+	{
+	int i;
+	err = -ENOMEM;
+	sn->sysctl_table = kmemdup(sctp_sysctl_table,
+			sizeof(sctp_sysctl_table), GFP_KERNEL);
+	if (!sn->sysctl_table)
+		goto out;
+
+	for (i = SCTP_CONNTRACK_CLOSED; i < SCTP_CONNTRACK_MAX; i++)
+		sn->sysctl_table[i - 1].data = &sn->sctp_timeouts[i];
+
+	sn->sysctl_header = register_net_sysctl_table(net,
+			nf_net_netfilter_sysctl_path, sn->sysctl_table);
+	if (!sn->sysctl_header)
+		goto out_free;
+
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	sn->compat_sysctl_table = kmemdup(sctp_compat_sysctl_table,
+			sizeof(sctp_compat_sysctl_table), GFP_KERNEL);
+	if (!sn->compat_sysctl_table)
+		goto out_sysctl;
+
+	for (i = SCTP_CONNTRACK_CLOSED; i < SCTP_CONNTRACK_MAX; i++)
+		sn->compat_sysctl_table[err - 1].data = &sn->sctp_timeouts[i];
+
+	sn->compat_sysctl_header = register_net_sysctl_table(net,
+			nf_net_ipv4_netfilter_sysctl_path, sn->compat_sysctl_table);
+	if (!sn->compat_sysctl_header)
+		goto out_free_compat;
+#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
+	}
+#endif /* CONFIG_SYSCTL */
+
+	return 0;
+
+#ifdef CONFIG_SYSCTL
+
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+out_free_compat:
+	kfree(sn->compat_sysctl_table);
+#endif
+out_sysctl:
+	unregister_net_sysctl_table(sn->sysctl_header);
+out_free:
+	kfree(sn->sysctl_table);
+#endif
+
+out:
+	kfree(sn);
+	return err;
+}
...

If such an approach is fine -- I will fix the TCP proto
as well. Btw, this two patches (SCTP and TCP) are only
involved in such a modification, are there some problems
with patches for UDP, UDPlite and ICMP protos?

	- Cyrill -

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

* Re: [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol
  2009-03-16 18:21         ` Cyrill Gorcunov
@ 2009-03-16 18:29           ` Patrick McHardy
  2009-03-16 18:45             ` Cyrill Gorcunov
  2009-03-16 21:03             ` Cyrill Gorcunov
  0 siblings, 2 replies; 29+ messages in thread
From: Patrick McHardy @ 2009-03-16 18:29 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: davem, daniel.lezcano, netdev, netfilter-devel, xemul, adobriyan

Cyrill Gorcunov wrote:
> After playing a bit with ctrl tables (thought about additional
> mapping set or say new sysctl helper structure, or even using
> extra1 member from struct ctl_table as temporary index) -- 
> you were right in your first propose on this patch. Iterative
> fasion is only more or less convenient here indeed :)
> 
> Patrick, take a look please on the snippet below (that is how
> it looks now).
> ...

> +	for (i = SCTP_CONNTRACK_CLOSED; i < SCTP_CONNTRACK_MAX; i++)
> +		sn->sysctl_table[i - 1].data = &sn->sctp_timeouts[i];

That definitely looks nicer. Does this work (-1) for the other
protocols as well?

> If such an approach is fine -- I will fix the TCP proto
> as well. Btw, this two patches (SCTP and TCP) are only
> involved in such a modification, are there some problems
> with patches for UDP, UDPlite and ICMP protos?

Its better than the macro and I don't really see a better way, so
this is fine with me. About the other patches - I just stopped at
SCTP since it was the first one I truely didn't like :)

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

* Re: [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol
  2009-03-16 18:29           ` Patrick McHardy
@ 2009-03-16 18:45             ` Cyrill Gorcunov
  2009-03-16 21:03             ` Cyrill Gorcunov
  1 sibling, 0 replies; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-16 18:45 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: davem, daniel.lezcano, netdev, netfilter-devel, xemul, adobriyan

[Patrick McHardy - Mon, Mar 16, 2009 at 07:29:02PM +0100]
> Cyrill Gorcunov wrote:
>> After playing a bit with ctrl tables (thought about additional
>> mapping set or say new sysctl helper structure, or even using
>> extra1 member from struct ctl_table as temporary index) -- you were 
>> right in your first propose on this patch. Iterative
>> fasion is only more or less convenient here indeed :)
>>
>> Patrick, take a look please on the snippet below (that is how
>> it looks now).
>> ...
>
>> +	for (i = SCTP_CONNTRACK_CLOSED; i < SCTP_CONNTRACK_MAX; i++)
>> +		sn->sysctl_table[i - 1].data = &sn->sctp_timeouts[i];
>
> That definitely looks nicer. Does this work (-1) for the other
> protocols as well?

Yes, it's allowable for TCP_CONNTRACK_ to use the same way
referring just fine, though we use only a subset of the enum
for sysctl table.

>
>> If such an approach is fine -- I will fix the TCP proto
>> as well. Btw, this two patches (SCTP and TCP) are only
>> involved in such a modification, are there some problems
>> with patches for UDP, UDPlite and ICMP protos?
>
> Its better than the macro and I don't really see a better way, so
> this is fine with me. About the other patches - I just stopped at
> SCTP since it was the first one I truely didn't like :)
>

Ah :) Then I update only these two patches (SCTP and TCP protos)
since other are not related in this. Or I could resend the whole
series excluding the patches you've already picked up. Just say
what would be more convenient for you.

	- Cyrill -

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

* Re: [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol
  2009-03-11 20:57 ` [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol Cyrill Gorcunov
  2009-03-12  9:15   ` Daniel Lezcano
@ 2009-03-16 20:58   ` Cyrill Gorcunov
  2009-03-26 15:13     ` Patrick McHardy
  1 sibling, 1 reply; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-16 20:58 UTC (permalink / raw)
  To: kaber, davem, daniel.lezcano, netdev, netfilter-devel, xemul, adobriyan

Here is an updated version which uses iterative assignment
of sysctl data. Please review.
---

From: Cyrill Gorcunov <gorcunov@openvz.org>
Subject: [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol

Module specific data moved into per-net site and being allocated/freed
during net namespace creation/deletion. For this reason module_init/exit
calls added.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 net/netfilter/nf_conntrack_proto_tcp.c |  281 +++++++++++++++++++++++----------
 1 file changed, 203 insertions(+), 78 deletions(-)

Index: linux-2.6.git/net/netfilter/nf_conntrack_proto_tcp.c
===================================================================
--- linux-2.6.git.orig/net/netfilter/nf_conntrack_proto_tcp.c
+++ linux-2.6.git/net/netfilter/nf_conntrack_proto_tcp.c
@@ -18,6 +18,9 @@
 
 #include <net/tcp.h>
 
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv6.h>
@@ -29,20 +32,6 @@
 /* Protects ct->proto.tcp */
 static DEFINE_RWLOCK(tcp_lock);
 
-/* "Be conservative in what you do,
-    be liberal in what you accept from others."
-    If it's non-zero, we mark only out of window RST segments as INVALID. */
-static int nf_ct_tcp_be_liberal __read_mostly = 0;
-
-/* If it is set to zero, we disable picking up already established
-   connections. */
-static int nf_ct_tcp_loose __read_mostly = 1;
-
-/* Max number of the retransmitted packets without receiving an (acceptable)
-   ACK from the destination. If this number is reached, a shorter timer
-   will be started. */
-static int nf_ct_tcp_max_retrans __read_mostly = 3;
-
   /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
      closely.  They're more complex. --RR */
 
@@ -64,23 +53,6 @@ static const char *const tcp_conntrack_n
 #define HOURS * 60 MINS
 #define DAYS * 24 HOURS
 
-/* RFC1122 says the R2 limit should be at least 100 seconds.
-   Linux uses 15 packets as limit, which corresponds
-   to ~13-30min depending on RTO. */
-static unsigned int nf_ct_tcp_timeout_max_retrans __read_mostly    =   5 MINS;
-static unsigned int nf_ct_tcp_timeout_unacknowledged __read_mostly =   5 MINS;
-
-static unsigned int tcp_timeouts[TCP_CONNTRACK_MAX] __read_mostly = {
-	[TCP_CONNTRACK_SYN_SENT]	= 2 MINS,
-	[TCP_CONNTRACK_SYN_RECV]	= 60 SECS,
-	[TCP_CONNTRACK_ESTABLISHED]	= 5 DAYS,
-	[TCP_CONNTRACK_FIN_WAIT]	= 2 MINS,
-	[TCP_CONNTRACK_CLOSE_WAIT]	= 60 SECS,
-	[TCP_CONNTRACK_LAST_ACK]	= 30 SECS,
-	[TCP_CONNTRACK_TIME_WAIT]	= 2 MINS,
-	[TCP_CONNTRACK_CLOSE]		= 10 SECS,
-};
-
 #define sNO TCP_CONNTRACK_NONE
 #define sSS TCP_CONNTRACK_SYN_SENT
 #define sSR TCP_CONNTRACK_SYN_RECV
@@ -258,6 +230,51 @@ static const u8 tcp_conntracks[2][6][TCP
 	}
 };
 
+/* per-net specifics */
+static int tcp_net_id;
+struct tcp_net {
+	/*
+	 * "Be conservative in what you do,
+	 * be liberal in what you accept from others."
+	 * If it's non-zero, we mark only out of window
+	 * RST segments as INVALID.
+	 */
+	int tcp_be_liberal;
+	/*
+	 * If it is set to zero, we disable picking up
+	 * already established connections.
+	 */
+	int tcp_loose;
+	/*
+	 * Max number of the retransmitted packets without
+	 * receiving an (acceptable) ACK from the destination.
+	 * If this number is reached, a shorter timer will be started.
+	 */
+	int tcp_max_retrans;
+	/*
+	 * RFC1122 says the R2 limit should be at least 100 seconds.
+	 * Linux uses 15 packets as limit, which corresponds
+	 * to ~13-30min depending on RTO.
+	 */
+	unsigned int tcp_timeout_max_retrans;
+	unsigned int tcp_timeout_unacknowledged;
+
+	unsigned int tcp_timeouts[TCP_CONNTRACK_MAX];
+#ifdef CONFIG_SYSCTL
+	struct ctl_table_header *sysctl_header;
+	struct ctl_table *sysctl_table;
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	struct ctl_table_header *compat_sysctl_header;
+	struct ctl_table *compat_sysctl_table;
+#endif
+#endif
+};
+
+static inline struct tcp_net *tcp_pernet(struct net *net)
+{
+	return net_generic(net, tcp_net_id);
+}
+
 static bool tcp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
 			     struct nf_conntrack_tuple *tuple)
 {
@@ -489,6 +506,7 @@ static bool tcp_in_window(const struct n
 			  u_int8_t pf)
 {
 	struct net *net = nf_ct_net(ct);
+	struct tcp_net *tn;
 	struct ip_ct_tcp_state *sender = &state->seen[dir];
 	struct ip_ct_tcp_state *receiver = &state->seen[!dir];
 	const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
@@ -666,8 +684,9 @@ static bool tcp_in_window(const struct n
 		res = true;
 	} else {
 		res = false;
+		tn = tcp_pernet(net);
 		if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
-		    nf_ct_tcp_be_liberal)
+		    tn->tcp_be_liberal)
 			res = true;
 		if (!res && LOG_INVALID(net, IPPROTO_TCP))
 			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
@@ -810,6 +829,7 @@ static int tcp_packet(struct nf_conn *ct
 		      unsigned int hooknum)
 {
 	struct net *net = nf_ct_net(ct);
+	struct tcp_net *tn;
 	struct nf_conntrack_tuple *tuple;
 	enum tcp_conntrack new_state, old_state;
 	enum ip_conntrack_dir dir;
@@ -948,6 +968,8 @@ static int tcp_packet(struct nf_conn *ct
 	ct->proto.tcp.last_index = index;
 	ct->proto.tcp.last_dir = dir;
 
+	tn = tcp_pernet(net);
+
 	pr_debug("tcp_conntracks: ");
 	nf_ct_dump_tuple(tuple);
 	pr_debug("syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
@@ -960,15 +982,15 @@ static int tcp_packet(struct nf_conn *ct
 	    && new_state == TCP_CONNTRACK_FIN_WAIT)
 		ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
 
-	if (ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans &&
-	    tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans)
-		timeout = nf_ct_tcp_timeout_max_retrans;
+	if (ct->proto.tcp.retrans >= tn->tcp_max_retrans &&
+	    tn->tcp_timeouts[new_state] > tn->tcp_timeout_max_retrans)
+		timeout = tn->tcp_timeout_max_retrans;
 	else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) &
 		 IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED &&
-		 tcp_timeouts[new_state] > nf_ct_tcp_timeout_unacknowledged)
-		timeout = nf_ct_tcp_timeout_unacknowledged;
+		 tn->tcp_timeouts[new_state] > tn->tcp_timeout_unacknowledged)
+		timeout = tn->tcp_timeout_unacknowledged;
 	else
-		timeout = tcp_timeouts[new_state];
+		timeout = tn->tcp_timeouts[new_state];
 	write_unlock_bh(&tcp_lock);
 
 	nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
@@ -1005,6 +1027,7 @@ static bool tcp_new(struct nf_conn *ct, 
 {
 	enum tcp_conntrack new_state;
 	const struct tcphdr *th;
+	struct tcp_net *tn;
 	struct tcphdr _tcph;
 	const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0];
 	const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1];
@@ -1023,6 +1046,8 @@ static bool tcp_new(struct nf_conn *ct, 
 		return false;
 	}
 
+	tn = tcp_pernet(nf_ct_net(ct));
+
 	if (new_state == TCP_CONNTRACK_SYN_SENT) {
 		/* SYN packet */
 		ct->proto.tcp.seen[0].td_end =
@@ -1036,7 +1061,7 @@ static bool tcp_new(struct nf_conn *ct, 
 
 		tcp_options(skb, dataoff, th, &ct->proto.tcp.seen[0]);
 		ct->proto.tcp.seen[1].flags = 0;
-	} else if (nf_ct_tcp_loose == 0) {
+	} else if (tn->tcp_loose == 0) {
 		/* Don't try to pick up connections. */
 		return false;
 	} else {
@@ -1184,75 +1209,64 @@ static int nlattr_to_tcp(struct nlattr *
 #endif
 
 #ifdef CONFIG_SYSCTL
-static unsigned int tcp_sysctl_table_users;
-static struct ctl_table_header *tcp_sysctl_header;
+/* templates, data assigned later */
 static struct ctl_table tcp_sysctl_table[] = {
 	{
 		.procname	= "nf_conntrack_tcp_timeout_syn_sent",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_syn_recv",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_established",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_fin_wait",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_close_wait",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_last_ack",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_time_wait",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_close",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_CLOSE],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_max_retrans",
-		.data		= &nf_ct_tcp_timeout_max_retrans,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_tcp_timeout_unacknowledged",
-		.data		= &nf_ct_tcp_timeout_unacknowledged,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -1260,7 +1274,6 @@ static struct ctl_table tcp_sysctl_table
 	{
 		.ctl_name	= NET_NF_CONNTRACK_TCP_LOOSE,
 		.procname	= "nf_conntrack_tcp_loose",
-		.data		= &nf_ct_tcp_loose,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
@@ -1268,7 +1281,6 @@ static struct ctl_table tcp_sysctl_table
 	{
 		.ctl_name	= NET_NF_CONNTRACK_TCP_BE_LIBERAL,
 		.procname       = "nf_conntrack_tcp_be_liberal",
-		.data           = &nf_ct_tcp_be_liberal,
 		.maxlen         = sizeof(unsigned int),
 		.mode           = 0644,
 		.proc_handler   = proc_dointvec,
@@ -1276,7 +1288,6 @@ static struct ctl_table tcp_sysctl_table
 	{
 		.ctl_name	= NET_NF_CONNTRACK_TCP_MAX_RETRANS,
 		.procname	= "nf_conntrack_tcp_max_retrans",
-		.data		= &nf_ct_tcp_max_retrans,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
@@ -1290,63 +1301,54 @@ static struct ctl_table tcp_sysctl_table
 static struct ctl_table tcp_compat_sysctl_table[] = {
 	{
 		.procname	= "ip_conntrack_tcp_timeout_syn_sent",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_syn_recv",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_established",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_fin_wait",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_close_wait",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_last_ack",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_time_wait",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_close",
-		.data		= &tcp_timeouts[TCP_CONNTRACK_CLOSE],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_tcp_timeout_max_retrans",
-		.data		= &nf_ct_tcp_timeout_max_retrans,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -1354,7 +1356,6 @@ static struct ctl_table tcp_compat_sysct
 	{
 		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_LOOSE,
 		.procname	= "ip_conntrack_tcp_loose",
-		.data		= &nf_ct_tcp_loose,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
@@ -1362,7 +1363,6 @@ static struct ctl_table tcp_compat_sysct
 	{
 		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL,
 		.procname	= "ip_conntrack_tcp_be_liberal",
-		.data		= &nf_ct_tcp_be_liberal,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
@@ -1370,7 +1370,6 @@ static struct ctl_table tcp_compat_sysct
 	{
 		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS,
 		.procname	= "ip_conntrack_tcp_max_retrans",
-		.data		= &nf_ct_tcp_max_retrans,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
@@ -1401,14 +1400,6 @@ struct nf_conntrack_l4proto nf_conntrack
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
-#ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &tcp_sysctl_table_users,
-	.ctl_table_header	= &tcp_sysctl_header,
-	.ctl_table		= tcp_sysctl_table,
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
-	.ctl_compat_table	= tcp_compat_sysctl_table,
-#endif
-#endif
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4);
 
@@ -1431,10 +1422,144 @@ struct nf_conntrack_l4proto nf_conntrack
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
+};
+EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);
+
+static __net_init int tcp_net_init(struct net *net)
+{
+	struct tcp_net *tn;
+	int err;
+
+	tn = kmalloc(sizeof(*tn), GFP_KERNEL);
+	if (!tn)
+		return -ENOMEM;
+
+	/* default values */
+	tn->tcp_be_liberal	= 0;
+	tn->tcp_loose		= 1;
+	tn->tcp_max_retrans	= 3;
+
+	tn->tcp_timeout_max_retrans	= 5 MINS;
+	tn->tcp_timeout_unacknowledged	= 5 MINS;
+
+	tn->tcp_timeouts[TCP_CONNTRACK_SYN_SENT]	= 2 MINS;
+	tn->tcp_timeouts[TCP_CONNTRACK_SYN_RECV]	= 60 SECS;
+	tn->tcp_timeouts[TCP_CONNTRACK_ESTABLISHED]	= 5 DAYS;
+	tn->tcp_timeouts[TCP_CONNTRACK_FIN_WAIT]	= 2 MINS;
+	tn->tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT]	= 60 SECS;
+	tn->tcp_timeouts[TCP_CONNTRACK_LAST_ACK]	= 30 SECS;
+	tn->tcp_timeouts[TCP_CONNTRACK_TIME_WAIT]	= 2 MINS;
+	tn->tcp_timeouts[TCP_CONNTRACK_CLOSE]		= 10 SECS;
+
+	err = net_assign_generic(net, tcp_net_id, tn);
+	if (err)
+		goto out;
+
+	/*
+	 * Pin per-net data to sysctl tables
+	 *
+	 * We allocate new ctrl tables from predefined templates
+	 * and then assign .data fields iteratively, we allowed
+	 * to do so since TCP_CONNTRACK_... (enum tcp_conntrack)
+	 * is a part of userspace ABI and it's hardly that the enum
+	 * entries will be rearranged
+	 */
+
+#ifdef CONFIG_SYSCTL
+	{
+	int i;
+	err = -ENOMEM;
+	tn->sysctl_table = kmemdup(tcp_sysctl_table,
+			sizeof(tcp_sysctl_table), GFP_KERNEL);
+	if (!tn->sysctl_table)
+		goto out;
+
+	for (i = TCP_CONNTRACK_SYN_SENT; i < TCP_CONNTRACK_LISTEN; i++)
+		tn->sysctl_table[i - 1].data = &tn->tcp_timeouts[i];
+
+	tn->sysctl_table[8].data = &tn->tcp_timeout_max_retrans;
+	tn->sysctl_table[9].data = &tn->tcp_timeout_unacknowledged;
+	tn->sysctl_table[10].data = &tn->tcp_loose;
+	tn->sysctl_table[11].data = &tn->tcp_be_liberal;
+	tn->sysctl_table[12].data = &tn->tcp_max_retrans;
+
+	tn->sysctl_header = register_net_sysctl_table(net,
+			nf_net_netfilter_sysctl_path, tn->sysctl_table);
+	if (!tn->sysctl_header)
+		goto out_free;
+
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	tn->compat_sysctl_table = kmemdup(tcp_compat_sysctl_table,
+			sizeof(tcp_compat_sysctl_table), GFP_KERNEL);
+	if (!tn->compat_sysctl_table)
+		goto out_sysctl;
+
+	for (i = TCP_CONNTRACK_SYN_SENT; i < TCP_CONNTRACK_LISTEN; i++)
+		tn->compat_sysctl_table[i - 1].data = &tn->tcp_timeouts[i];
+
+	tn->compat_sysctl_table[8].data = &tn->tcp_timeout_max_retrans;
+	tn->compat_sysctl_table[9].data = &tn->tcp_loose;
+	tn->compat_sysctl_table[10].data = &tn->tcp_be_liberal;
+	tn->compat_sysctl_table[11].data = &tn->tcp_max_retrans;
+
+	tn->compat_sysctl_header = register_net_sysctl_table(net,
+			nf_net_ipv4_netfilter_sysctl_path,
+			tn->compat_sysctl_table);
+	if (!tn->compat_sysctl_header)
+		goto out_free_compat;
+#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
+	}
+#endif /* CONFIG_SYSCTL */
+
+	return 0;
+
+#ifdef CONFIG_SYSCTL
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+out_free_compat:
+	kfree(tn->compat_sysctl_table);
+#endif
+out_sysctl:
+	unregister_net_sysctl_table(tn->sysctl_header);
+out_free:
+	kfree(tn->sysctl_table);
+#endif
+
+out:
+	kfree(tn);
+	return err;
+}
+
+static __net_exit void tcp_net_exit(struct net *net)
+{
+	struct tcp_net *tn = tcp_pernet(net);
 #ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &tcp_sysctl_table_users,
-	.ctl_table_header	= &tcp_sysctl_header,
-	.ctl_table		= tcp_sysctl_table,
+	unregister_net_sysctl_table(tn->sysctl_header);
+	kfree(tn->sysctl_table);
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	unregister_net_sysctl_table(tn->compat_sysctl_header);
+	kfree(tn->compat_sysctl_table);
 #endif
+#endif
+	kfree(tn);
+
+	net_assign_generic(net, tcp_net_id, NULL);
 };
-EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);
+
+static struct pernet_operations tcp_net_ops = {
+	.init = tcp_net_init,
+	.exit = tcp_net_exit,
+};
+
+static int __init nf_ct_tcp_proto_init(void)
+{
+	return register_pernet_gen_subsys(&tcp_net_id, &tcp_net_ops);
+}
+
+static void __exit nf_ct_tcp_proto_fini(void)
+{
+	unregister_pernet_gen_subsys(tcp_net_id, &tcp_net_ops);
+}
+
+module_init(nf_ct_tcp_proto_init);
+module_exit(nf_ct_tcp_proto_fini);
+MODULE_LICENSE("GPL");

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

* Re: [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol
  2009-03-16 18:29           ` Patrick McHardy
  2009-03-16 18:45             ` Cyrill Gorcunov
@ 2009-03-16 21:03             ` Cyrill Gorcunov
  1 sibling, 0 replies; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-16 21:03 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: davem, daniel.lezcano, netdev, netfilter-devel, xemul, adobriyan

[Patrick McHardy - Mon, Mar 16, 2009 at 07:29:02PM +0100]
...
> Its better than the macro and I don't really see a better way, so
> this is fine with me. About the other patches - I just stopped at
> SCTP since it was the first one I truely didn't like :)
>

Here is an updated version of the patch with assignment in cycle.
Please review. If all this series become a mess which hard to unwind
(ie what version of patch is last, which is not) -- I could resend
the whole series (excluding already applied). Just say. Thanks!
---

From: Cyrill Gorcunov <gorcunov@openvz.org>
Subject: [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol

Module specific data moved into per-net site and being allocated/freed
during net namespace creation/deletion.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 net/netfilter/nf_conntrack_proto_sctp.c |  179 ++++++++++++++++++++++++--------
 1 file changed, 139 insertions(+), 40 deletions(-)

Index: linux-2.6.git/net/netfilter/nf_conntrack_proto_sctp.c
===================================================================
--- linux-2.6.git.orig/net/netfilter/nf_conntrack_proto_sctp.c
+++ linux-2.6.git/net/netfilter/nf_conntrack_proto_sctp.c
@@ -21,6 +21,9 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
@@ -49,16 +52,6 @@ static const char *const sctp_conntrack_
 #define HOURS * 60 MINS
 #define DAYS  * 24 HOURS
 
-static unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] __read_mostly = {
-	[SCTP_CONNTRACK_CLOSED]			= 10 SECS,
-	[SCTP_CONNTRACK_COOKIE_WAIT]		= 3 SECS,
-	[SCTP_CONNTRACK_COOKIE_ECHOED]		= 3 SECS,
-	[SCTP_CONNTRACK_ESTABLISHED]		= 5 DAYS,
-	[SCTP_CONNTRACK_SHUTDOWN_SENT]		= 300 SECS / 1000,
-	[SCTP_CONNTRACK_SHUTDOWN_RECD]		= 300 SECS / 1000,
-	[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT]	= 3 SECS,
-};
-
 #define sNO SCTP_CONNTRACK_NONE
 #define	sCL SCTP_CONNTRACK_CLOSED
 #define	sCW SCTP_CONNTRACK_COOKIE_WAIT
@@ -130,6 +123,25 @@ static const u8 sctp_conntracks[2][9][SC
 	}
 };
 
+/* this module per-net specifics */
+static int sctp_net_id;
+struct sctp_net {
+	unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX];
+#ifdef CONFIG_SYSCTL
+	struct ctl_table_header *sysctl_header;
+	struct ctl_table *sysctl_table;
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	struct ctl_table_header *compat_sysctl_header;
+	struct ctl_table *compat_sysctl_table;
+#endif
+#endif
+};
+
+static inline struct sctp_net *sctp_pernet(struct net *net)
+{
+	return net_generic(net, sctp_net_id);
+}
+
 static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
 			      struct nf_conntrack_tuple *tuple)
 {
@@ -297,6 +309,7 @@ static int sctp_packet(struct nf_conn *c
 	const struct sctp_chunkhdr *sch;
 	struct sctp_chunkhdr _sch;
 	u_int32_t offset, count;
+	struct sctp_net *sn;
 	unsigned long map[256 / sizeof(unsigned long)] = { 0 };
 
 	sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
@@ -373,7 +386,8 @@ static int sctp_packet(struct nf_conn *c
 	}
 	write_unlock_bh(&sctp_lock);
 
-	nf_ct_refresh_acct(ct, ctinfo, skb, sctp_timeouts[new_state]);
+	sn = sctp_pernet(nf_ct_net(ct));
+	nf_ct_refresh_acct(ct, ctinfo, skb, sn->sctp_timeouts[new_state]);
 
 	if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
 	    dir == IP_CT_DIR_REPLY &&
@@ -540,54 +554,46 @@ static int nlattr_to_sctp(struct nlattr 
 #endif
 
 #ifdef CONFIG_SYSCTL
-static unsigned int sctp_sysctl_table_users;
-static struct ctl_table_header *sctp_sysctl_header;
+/* templates, data assigned later */
 static struct ctl_table sctp_sysctl_table[] = {
 	{
 		.procname	= "nf_conntrack_sctp_timeout_closed",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_sctp_timeout_cookie_wait",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_sctp_timeout_cookie_echoed",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_sctp_timeout_established",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_sctp_timeout_shutdown_sent",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_sctp_timeout_shutdown_recd",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_sctp_timeout_shutdown_ack_sent",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -601,49 +607,42 @@ static struct ctl_table sctp_sysctl_tabl
 static struct ctl_table sctp_compat_sysctl_table[] = {
 	{
 		.procname	= "ip_conntrack_sctp_timeout_closed",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_sctp_timeout_cookie_wait",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_sctp_timeout_cookie_echoed",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_sctp_timeout_established",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_sctp_timeout_shutdown_sent",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_sctp_timeout_shutdown_recd",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "ip_conntrack_sctp_timeout_shutdown_ack_sent",
-		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -653,7 +652,7 @@ static struct ctl_table sctp_compat_sysc
 	}
 };
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
-#endif
+#endif /* CONFIG_SYSCTL */
 
 static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
 	.l3proto		= PF_INET,
@@ -673,14 +672,6 @@ static struct nf_conntrack_l4proto nf_co
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
-#ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &sctp_sysctl_table_users,
-	.ctl_table_header	= &sctp_sysctl_header,
-	.ctl_table		= sctp_sysctl_table,
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
-	.ctl_compat_table	= sctp_compat_sysctl_table,
-#endif
-#endif
 };
 
 static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
@@ -701,21 +692,126 @@ static struct nf_conntrack_l4proto nf_co
 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
 	.nla_policy		= nf_ct_port_nla_policy,
 #endif
+};
+
+static __net_init int sctp_net_init(struct net *net)
+{
+	struct sctp_net *sn;
+	int err;
+
+	sn = kmalloc(sizeof(*sn), GFP_KERNEL);
+	if (!sn)
+		return -ENOMEM;
+
+	/* default values */
+	sn->sctp_timeouts[SCTP_CONNTRACK_CLOSED]	= 10 SECS;
+	sn->sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT]	= 3 SECS;
+	sn->sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED]	= 3 SECS;
+	sn->sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED]	= 5 DAYS;
+	sn->sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT]	= 300 SECS / 1000;
+	sn->sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD]	= 300 SECS / 1000;
+	sn->sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS;
+
+	err = net_assign_generic(net, sctp_net_id, sn);
+	if (err)
+		goto out;
+
+	/*
+	 * Pin per-net data to sysctl tables
+	 *
+	 * We allocate new ctrl tables from predefined templates
+	 * and then assign .data fields iteratively, we allowed
+	 * to do so since SCTP_CONNTRACK_... (enum sctp_conntrack)
+	 * is a part of userspace ABI and it's hardly that the enum
+	 * entries will be rearranged
+	 */
+
 #ifdef CONFIG_SYSCTL
-	.ctl_table_users	= &sctp_sysctl_table_users,
-	.ctl_table_header	= &sctp_sysctl_header,
-	.ctl_table		= sctp_sysctl_table,
+	{
+	int i;
+	err = -ENOMEM;
+	sn->sysctl_table = kmemdup(sctp_sysctl_table,
+			sizeof(sctp_sysctl_table), GFP_KERNEL);
+	if (!sn->sysctl_table)
+		goto out;
+
+	for (i = SCTP_CONNTRACK_CLOSED; i < SCTP_CONNTRACK_MAX; i++)
+		sn->sysctl_table[i - 1].data = &sn->sctp_timeouts[i];
+
+	sn->sysctl_header = register_net_sysctl_table(net,
+			nf_net_netfilter_sysctl_path, sn->sysctl_table);
+	if (!sn->sysctl_header)
+		goto out_free;
+
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	sn->compat_sysctl_table = kmemdup(sctp_compat_sysctl_table,
+			sizeof(sctp_compat_sysctl_table), GFP_KERNEL);
+	if (!sn->compat_sysctl_table)
+		goto out_sysctl;
+
+	for (i = SCTP_CONNTRACK_CLOSED; i < SCTP_CONNTRACK_MAX; i++)
+		sn->compat_sysctl_table[err - 1].data = &sn->sctp_timeouts[i];
+
+	sn->compat_sysctl_header = register_net_sysctl_table(net,
+			nf_net_ipv4_netfilter_sysctl_path, sn->compat_sysctl_table);
+	if (!sn->compat_sysctl_header)
+		goto out_free_compat;
+#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
+	}
+#endif /* CONFIG_SYSCTL */
+
+	return 0;
+
+#ifdef CONFIG_SYSCTL
+
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+out_free_compat:
+	kfree(sn->compat_sysctl_table);
+#endif
+out_sysctl:
+	unregister_net_sysctl_table(sn->sysctl_header);
+out_free:
+	kfree(sn->sysctl_table);
+#endif
+
+out:
+	kfree(sn);
+	return err;
+}
+
+static __net_exit void sctp_net_exit(struct net *net)
+{
+	struct sctp_net *sn = sctp_pernet(net);
+#ifdef CONFIG_SYSCTL
+	unregister_net_sysctl_table(sn->sysctl_header);
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+	unregister_net_sysctl_table(sn->compat_sysctl_header);
+	kfree(sn->compat_sysctl_table);
 #endif
+	kfree(sn->sysctl_table);
+#endif
+	kfree(sn);
+
+	net_assign_generic(net, sctp_net_id, NULL);
+}
+
+static struct pernet_operations sctp_net_ops = {
+	.init = sctp_net_init,
+	.exit = sctp_net_exit,
 };
 
 static int __init nf_conntrack_proto_sctp_init(void)
 {
 	int ret;
 
+	ret = register_pernet_gen_subsys(&sctp_net_id, &sctp_net_ops);
+	if (ret < 0)
+		goto out;
+
 	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp4);
 	if (ret) {
 		printk("nf_conntrack_l4proto_sctp4: protocol register failed\n");
-		goto out;
+		goto cleanup_net;
 	}
 	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp6);
 	if (ret) {
@@ -727,12 +823,15 @@ static int __init nf_conntrack_proto_sct
 
  cleanup_sctp4:
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
+ cleanup_net:
+	unregister_pernet_gen_subsys(sctp_net_id, &sctp_net_ops);
  out:
 	return ret;
 }
 
 static void __exit nf_conntrack_proto_sctp_fini(void)
 {
+	unregister_pernet_gen_subsys(sctp_net_id, &sctp_net_ops);
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
 }

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

* Re: [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol
  2009-03-16 20:58   ` Cyrill Gorcunov
@ 2009-03-26 15:13     ` Patrick McHardy
  2009-03-26 15:37       ` Cyrill Gorcunov
  0 siblings, 1 reply; 29+ messages in thread
From: Patrick McHardy @ 2009-03-26 15:13 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: davem, daniel.lezcano, netdev, netfilter-devel, xemul, adobriyan

Cyrill Gorcunov wrote:
> Here is an updated version which uses iterative assignment
> of sysctl data. Please review.
> ---
> 
> From: Cyrill Gorcunov <gorcunov@openvz.org>
> Subject: [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol
> 
> Module specific data moved into per-net site and being allocated/freed
> during net namespace creation/deletion. For this reason module_init/exit
> calls added.


I guess this isn't going to get any prettier :) Could you please
send me the latest version of the missing patches against the current
nf-next tree?

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

* Re: [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol
  2009-03-26 15:13     ` Patrick McHardy
@ 2009-03-26 15:37       ` Cyrill Gorcunov
  2009-03-26 15:46         ` Patrick McHardy
  0 siblings, 1 reply; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-26 15:37 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: davem, daniel.lezcano, netdev, netfilter-devel, xemul, adobriyan

[Patrick McHardy - Thu, Mar 26, 2009 at 04:13:58PM +0100]
> Cyrill Gorcunov wrote:
>> Here is an updated version which uses iterative assignment
>> of sysctl data. Please review.
>> ---
>>
>> From: Cyrill Gorcunov <gorcunov@openvz.org>
>> Subject: [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol
>>
>> Module specific data moved into per-net site and being allocated/freed
>> during net namespace creation/deletion. For this reason module_init/exit
>> calls added.
>
>
> I guess this isn't going to get any prettier :) Could you please
> send me the latest version of the missing patches against the current
> nf-next tree?
>

Yes, no problem, wait a bit please.

Btw, I think the bestest way (and surely more clean)
would be to use some new form of the sysctl templates.

But I didn't find such a form of writting which would
sutisfy me. Since you said those enums are written in
stone it's safe to use iterative fasion indeed but
as I see you found them not that "pretty" too :)

On the other hand -- if per-net initialization is not
that critical in speed (ie some speed could be sacrificed
for the code clarity -- I could play with those templates
maybe). Just a thought.

        Cyrill

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

* Re: [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol
  2009-03-26 15:37       ` Cyrill Gorcunov
@ 2009-03-26 15:46         ` Patrick McHardy
  2009-03-26 15:51           ` Cyrill Gorcunov
  0 siblings, 1 reply; 29+ messages in thread
From: Patrick McHardy @ 2009-03-26 15:46 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: davem, daniel.lezcano, netdev, netfilter-devel, xemul, adobriyan

Cyrill Gorcunov wrote:
> Yes, no problem, wait a bit please.
> 
> Btw, I think the bestest way (and surely more clean)
> would be to use some new form of the sysctl templates.
> 
> But I didn't find such a form of writting which would
> sutisfy me. Since you said those enums are written in
> stone it's safe to use iterative fasion indeed but
> as I see you found them not that "pretty" too :)

I just like the code structure with all definitions and initializations
at the top better. But that obviously isn't possible with network
namespaces, so just ignore me :)

> On the other hand -- if per-net initialization is not
> that critical in speed (ie some speed could be sacrificed
> for the code clarity -- I could play with those templates
> maybe). Just a thought.

For now lets just get this stuff in since I think its about the last
bits for full netfilter namespace support. I'll happily take further
cleanups of course, but I don't think its worth delaying this any
longer.

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

* Re: [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol
  2009-03-26 15:46         ` Patrick McHardy
@ 2009-03-26 15:51           ` Cyrill Gorcunov
  0 siblings, 0 replies; 29+ messages in thread
From: Cyrill Gorcunov @ 2009-03-26 15:51 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: davem, daniel.lezcano, netdev, netfilter-devel, xemul, adobriyan

[Patrick McHardy - Thu, Mar 26, 2009 at 04:46:16PM +0100]
> Cyrill Gorcunov wrote:
>> Yes, no problem, wait a bit please.
>>
>> Btw, I think the bestest way (and surely more clean)
>> would be to use some new form of the sysctl templates.
>>
>> But I didn't find such a form of writting which would
>> sutisfy me. Since you said those enums are written in
>> stone it's safe to use iterative fasion indeed but
>> as I see you found them not that "pretty" too :)
>
> I just like the code structure with all definitions and initializations
> at the top better. But that obviously isn't possible with network
> namespaces, so just ignore me :)
>
>> On the other hand -- if per-net initialization is not
>> that critical in speed (ie some speed could be sacrificed
>> for the code clarity -- I could play with those templates
>> maybe). Just a thought.
>
> For now lets just get this stuff in since I think its about the last
> bits for full netfilter namespace support. I'll happily take further
> cleanups of course, but I don't think its worth delaying this any
> longer.
>

ok, I'm almost sending them (last compile test on every patch,
please give me a few minutes)

        Cyrill

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

end of thread, other threads:[~2009-03-26 15:51 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-11 20:57 [RFC v2 0/7] introduce netfilter conntrack protos pernet functionality v2 Cyrill Gorcunov
2009-03-11 20:57 ` [RFC v2 1/7] net: sysctl_net - use net_eq to compare nets Cyrill Gorcunov
2009-03-12  8:50   ` Daniel Lezcano
2009-03-16 15:24     ` Patrick McHardy
2009-03-11 20:57 ` [RFC v2 2/7] net: netfilter conntrack - add per-net functionality for DCCP protocol Cyrill Gorcunov
2009-03-12  8:54   ` Daniel Lezcano
2009-03-16 15:31     ` Patrick McHardy
2009-03-11 20:57 ` [RFC v2 3/7] net: netfilter conntrack - add per-net functionality for SCTP protocol Cyrill Gorcunov
2009-03-12  9:03   ` Daniel Lezcano
2009-03-16 15:35   ` Patrick McHardy
2009-03-16 15:46     ` Cyrill Gorcunov
2009-03-16 15:48       ` Patrick McHardy
2009-03-16 18:21         ` Cyrill Gorcunov
2009-03-16 18:29           ` Patrick McHardy
2009-03-16 18:45             ` Cyrill Gorcunov
2009-03-16 21:03             ` Cyrill Gorcunov
2009-03-11 20:57 ` [RFC v2 4/7] net: netfilter conntrack - add per-net functionality for UDPLITE protocol Cyrill Gorcunov
2009-03-12  9:07   ` Daniel Lezcano
2009-03-11 20:57 ` [RFC v2 5/7] net: netfilter conntrack - add per-net functionality for TCP protocol Cyrill Gorcunov
2009-03-12  9:15   ` Daniel Lezcano
2009-03-16 20:58   ` Cyrill Gorcunov
2009-03-26 15:13     ` Patrick McHardy
2009-03-26 15:37       ` Cyrill Gorcunov
2009-03-26 15:46         ` Patrick McHardy
2009-03-26 15:51           ` Cyrill Gorcunov
2009-03-11 20:57 ` [RFC v2 6/7] net: netfilter conntrack - add per-net functionality for UDP protocol Cyrill Gorcunov
2009-03-12  9:49   ` Daniel Lezcano
2009-03-11 20:57 ` [RFC v2 7/7] net: netfilter conntrack - add per-net functionality for ICMP protocol Cyrill Gorcunov
2009-03-12  9:51   ` Daniel Lezcano

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.