aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netfilter/nf_conntrack_core.h4
-rw-r--r--include/net/netns/conntrack.h6
-rw-r--r--net/netfilter/nf_conntrack_core.c17
-rw-r--r--net/netfilter/nf_conntrack_proto.c46
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c38
5 files changed, 78 insertions, 33 deletions
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index aced085132e7..d8f5b9f52169 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -28,8 +28,8 @@ extern unsigned int nf_conntrack_in(struct net *net,
28extern int nf_conntrack_init(struct net *net); 28extern int nf_conntrack_init(struct net *net);
29extern void nf_conntrack_cleanup(struct net *net); 29extern void nf_conntrack_cleanup(struct net *net);
30 30
31extern int nf_conntrack_proto_init(void); 31extern int nf_conntrack_proto_init(struct net *net);
32extern void nf_conntrack_proto_fini(void); 32extern void nf_conntrack_proto_fini(struct net *net);
33 33
34extern bool 34extern bool
35nf_ct_get_tuple(const struct sk_buff *skb, 35nf_ct_get_tuple(const struct sk_buff *skb,
diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h
index b2dbcc5cd813..0ef8592d48bf 100644
--- a/include/net/netns/conntrack.h
+++ b/include/net/netns/conntrack.h
@@ -20,7 +20,13 @@ struct nf_proto_net {
20 unsigned int users; 20 unsigned int users;
21}; 21};
22 22
23struct nf_generic_net {
24 struct nf_proto_net pn;
25 unsigned int timeout;
26};
27
23struct nf_ip_net { 28struct nf_ip_net {
29 struct nf_generic_net generic;
24#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 30#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
25 struct ctl_table_header *ctl_table_header; 31 struct ctl_table_header *ctl_table_header;
26 struct ctl_table *ctl_table; 32 struct ctl_table *ctl_table;
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index ac3af97cc468..068f2e0ec58e 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1333,7 +1333,6 @@ static void nf_conntrack_cleanup_init_net(void)
1333 while (untrack_refs() > 0) 1333 while (untrack_refs() > 0)
1334 schedule(); 1334 schedule();
1335 1335
1336 nf_conntrack_proto_fini();
1337#ifdef CONFIG_NF_CONNTRACK_ZONES 1336#ifdef CONFIG_NF_CONNTRACK_ZONES
1338 nf_ct_extend_unregister(&nf_ct_zone_extend); 1337 nf_ct_extend_unregister(&nf_ct_zone_extend);
1339#endif 1338#endif
@@ -1372,7 +1371,7 @@ void nf_conntrack_cleanup(struct net *net)
1372 netfilter framework. Roll on, two-stage module 1371 netfilter framework. Roll on, two-stage module
1373 delete... */ 1372 delete... */
1374 synchronize_net(); 1373 synchronize_net();
1375 1374 nf_conntrack_proto_fini(net);
1376 nf_conntrack_cleanup_net(net); 1375 nf_conntrack_cleanup_net(net);
1377 1376
1378 if (net_eq(net, &init_net)) { 1377 if (net_eq(net, &init_net)) {
@@ -1496,11 +1495,6 @@ static int nf_conntrack_init_init_net(void)
1496 printk(KERN_INFO "nf_conntrack version %s (%u buckets, %d max)\n", 1495 printk(KERN_INFO "nf_conntrack version %s (%u buckets, %d max)\n",
1497 NF_CONNTRACK_VERSION, nf_conntrack_htable_size, 1496 NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
1498 nf_conntrack_max); 1497 nf_conntrack_max);
1499
1500 ret = nf_conntrack_proto_init();
1501 if (ret < 0)
1502 goto err_proto;
1503
1504#ifdef CONFIG_NF_CONNTRACK_ZONES 1498#ifdef CONFIG_NF_CONNTRACK_ZONES
1505 ret = nf_ct_extend_register(&nf_ct_zone_extend); 1499 ret = nf_ct_extend_register(&nf_ct_zone_extend);
1506 if (ret < 0) 1500 if (ret < 0)
@@ -1518,9 +1512,7 @@ static int nf_conntrack_init_init_net(void)
1518 1512
1519#ifdef CONFIG_NF_CONNTRACK_ZONES 1513#ifdef CONFIG_NF_CONNTRACK_ZONES
1520err_extend: 1514err_extend:
1521 nf_conntrack_proto_fini();
1522#endif 1515#endif
1523err_proto:
1524 return ret; 1516 return ret;
1525} 1517}
1526 1518
@@ -1583,9 +1575,7 @@ static int nf_conntrack_init_net(struct net *net)
1583 ret = nf_conntrack_helper_init(net); 1575 ret = nf_conntrack_helper_init(net);
1584 if (ret < 0) 1576 if (ret < 0)
1585 goto err_helper; 1577 goto err_helper;
1586
1587 return 0; 1578 return 0;
1588
1589err_helper: 1579err_helper:
1590 nf_conntrack_timeout_fini(net); 1580 nf_conntrack_timeout_fini(net);
1591err_timeout: 1581err_timeout:
@@ -1622,6 +1612,9 @@ int nf_conntrack_init(struct net *net)
1622 if (ret < 0) 1612 if (ret < 0)
1623 goto out_init_net; 1613 goto out_init_net;
1624 } 1614 }
1615 ret = nf_conntrack_proto_init(net);
1616 if (ret < 0)
1617 goto out_proto;
1625 ret = nf_conntrack_init_net(net); 1618 ret = nf_conntrack_init_net(net);
1626 if (ret < 0) 1619 if (ret < 0)
1627 goto out_net; 1620 goto out_net;
@@ -1637,6 +1630,8 @@ int nf_conntrack_init(struct net *net)
1637 return 0; 1630 return 0;
1638 1631
1639out_net: 1632out_net:
1633 nf_conntrack_proto_fini(net);
1634out_proto:
1640 if (net_eq(net, &init_net)) 1635 if (net_eq(net, &init_net))
1641 nf_conntrack_cleanup_init_net(); 1636 nf_conntrack_cleanup_init_net();
1642out_init_net: 1637out_init_net:
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index a8daf0faadb7..b095b4aefd7c 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -302,10 +302,16 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister);
302static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, 302static struct nf_proto_net *nf_ct_l4proto_net(struct net *net,
303 struct nf_conntrack_l4proto *l4proto) 303 struct nf_conntrack_l4proto *l4proto)
304{ 304{
305 if (l4proto->net_id) 305 switch (l4proto->l4proto) {
306 return net_generic(net, *l4proto->net_id); 306 case 255: /* l4proto_generic */
307 else 307 return (struct nf_proto_net *)&net->ct.nf_ct_proto.generic;
308 return NULL; 308 default:
309 if (l4proto->net_id)
310 return net_generic(net, *l4proto->net_id);
311 else
312 return NULL;
313 }
314 return NULL;
309} 315}
310 316
311static 317static
@@ -487,28 +493,34 @@ void nf_conntrack_l4proto_unregister(struct net *net,
487} 493}
488EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister); 494EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister);
489 495
490int nf_conntrack_proto_init(void) 496int nf_conntrack_proto_init(struct net *net)
491{ 497{
492 unsigned int i; 498 unsigned int i;
493 int err; 499 int err;
494 500 err = nf_conntrack_l4proto_generic.init_net(net);
495 err = nf_ct_l4proto_register_sysctl(&init_net, &nf_conntrack_l4proto_generic); 501 if (err < 0)
502 return err;
503 err = nf_ct_l4proto_register_sysctl(net,
504 &nf_conntrack_l4proto_generic);
496 if (err < 0) 505 if (err < 0)
497 return err; 506 return err;
498 507
499 for (i = 0; i < AF_MAX; i++) 508 if (net == &init_net) {
500 rcu_assign_pointer(nf_ct_l3protos[i], 509 for (i = 0; i < AF_MAX; i++)
501 &nf_conntrack_l3proto_generic); 510 rcu_assign_pointer(nf_ct_l3protos[i],
511 &nf_conntrack_l3proto_generic);
512 }
502 return 0; 513 return 0;
503} 514}
504 515
505void nf_conntrack_proto_fini(void) 516void nf_conntrack_proto_fini(struct net *net)
506{ 517{
507 unsigned int i; 518 unsigned int i;
508 519 nf_ct_l4proto_unregister_sysctl(net,
509 nf_ct_l4proto_unregister_sysctl(&init_net, &nf_conntrack_l4proto_generic); 520 &nf_conntrack_l4proto_generic);
510 521 if (net == &init_net) {
511 /* free l3proto protocol tables */ 522 /* free l3proto protocol tables */
512 for (i = 0; i < PF_MAX; i++) 523 for (i = 0; i < PF_MAX; i++)
513 kfree(nf_ct_protos[i]); 524 kfree(nf_ct_protos[i]);
525 }
514} 526}
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index d8923d54b358..19bc880eb4e2 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -14,6 +14,11 @@
14 14
15static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ; 15static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ;
16 16
17static inline struct nf_generic_net *generic_pernet(struct net *net)
18{
19 return &net->ct.nf_ct_proto.generic;
20}
21
17static bool generic_pkt_to_tuple(const struct sk_buff *skb, 22static bool generic_pkt_to_tuple(const struct sk_buff *skb,
18 unsigned int dataoff, 23 unsigned int dataoff,
19 struct nf_conntrack_tuple *tuple) 24 struct nf_conntrack_tuple *tuple)
@@ -42,7 +47,7 @@ static int generic_print_tuple(struct seq_file *s,
42 47
43static unsigned int *generic_get_timeouts(struct net *net) 48static unsigned int *generic_get_timeouts(struct net *net)
44{ 49{
45 return &nf_ct_generic_timeout; 50 return &(generic_pernet(net)->timeout);
46} 51}
47 52
48/* Returns verdict for packet, or -1 for invalid. */ 53/* Returns verdict for packet, or -1 for invalid. */
@@ -110,7 +115,6 @@ static struct ctl_table_header *generic_sysctl_header;
110static struct ctl_table generic_sysctl_table[] = { 115static struct ctl_table generic_sysctl_table[] = {
111 { 116 {
112 .procname = "nf_conntrack_generic_timeout", 117 .procname = "nf_conntrack_generic_timeout",
113 .data = &nf_ct_generic_timeout,
114 .maxlen = sizeof(unsigned int), 118 .maxlen = sizeof(unsigned int),
115 .mode = 0644, 119 .mode = 0644,
116 .proc_handler = proc_dointvec_jiffies, 120 .proc_handler = proc_dointvec_jiffies,
@@ -121,7 +125,6 @@ static struct ctl_table generic_sysctl_table[] = {
121static struct ctl_table generic_compat_sysctl_table[] = { 125static struct ctl_table generic_compat_sysctl_table[] = {
122 { 126 {
123 .procname = "ip_conntrack_generic_timeout", 127 .procname = "ip_conntrack_generic_timeout",
124 .data = &nf_ct_generic_timeout,
125 .maxlen = sizeof(unsigned int), 128 .maxlen = sizeof(unsigned int),
126 .mode = 0644, 129 .mode = 0644,
127 .proc_handler = proc_dointvec_jiffies, 130 .proc_handler = proc_dointvec_jiffies,
@@ -131,6 +134,34 @@ static struct ctl_table generic_compat_sysctl_table[] = {
131#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 134#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
132#endif /* CONFIG_SYSCTL */ 135#endif /* CONFIG_SYSCTL */
133 136
137static int generic_init_net(struct net *net)
138{
139 struct nf_generic_net *gn = generic_pernet(net);
140 struct nf_proto_net *pn = (struct nf_proto_net *)gn;
141 gn->timeout = nf_ct_generic_timeout;
142#ifdef CONFIG_SYSCTL
143 pn->ctl_table = kmemdup(generic_sysctl_table,
144 sizeof(generic_sysctl_table),
145 GFP_KERNEL);
146 if (!pn->ctl_table)
147 return -ENOMEM;
148 pn->ctl_table[0].data = &gn->timeout;
149
150#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
151 pn->ctl_compat_table = kmemdup(generic_compat_sysctl_table,
152 sizeof(generic_compat_sysctl_table),
153 GFP_KERNEL);
154 if (!pn->ctl_compat_table) {
155 kfree(pn->ctl_table);
156 pn->ctl_table = NULL;
157 return -ENOMEM;
158 }
159 pn->ctl_compat_table[0].data = &gn->timeout;
160#endif
161#endif
162 return 0;
163}
164
134struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly = 165struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
135{ 166{
136 .l3proto = PF_UNSPEC, 167 .l3proto = PF_UNSPEC,
@@ -158,4 +189,5 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
158 .ctl_compat_table = generic_compat_sysctl_table, 189 .ctl_compat_table = generic_compat_sysctl_table,
159#endif 190#endif
160#endif 191#endif
192 .init_net = generic_init_net,
161}; 193};