* [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* 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 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
* [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* 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 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 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
* [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* 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 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 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
* [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