aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-07-08 01:35:56 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-11 01:18:02 -0400
commitb560580a13b180bc1e3cad7ffbc93388cc39be5d (patch)
tree9ad6fd7a93c75ef4776239b4f43bde27737aa04b /net
parent31f15875c5ad98a13b528aaf19c839e22b43dc9a (diff)
[NETFILTER]: nf_conntrack_expect: maintain per conntrack expectation list
This patch brings back the per-conntrack expectation list that was removed around 2.6.10 to avoid walking all expectations on expectation eviction and conntrack destruction. As these were the last users of the global expectation list, this patch also kills that. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nf_conntrack_core.c18
-rw-r--r--net/netfilter/nf_conntrack_expect.c40
-rw-r--r--net/netfilter/nf_conntrack_helper.c13
-rw-r--r--net/netfilter/nf_conntrack_netlink.c4
4 files changed, 39 insertions, 36 deletions
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index ed44a09ae739..d1fc019760a1 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -502,12 +502,9 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
502 __set_bit(IPS_EXPECTED_BIT, &conntrack->status); 502 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
503 conntrack->master = exp->master; 503 conntrack->master = exp->master;
504 if (exp->helper) { 504 if (exp->helper) {
505 help = nf_ct_ext_add(conntrack, NF_CT_EXT_HELPER, 505 help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
506 GFP_ATOMIC);
507 if (help) 506 if (help)
508 rcu_assign_pointer(help->helper, exp->helper); 507 rcu_assign_pointer(help->helper, exp->helper);
509 else
510 DEBUGP("failed to add helper extension area");
511 } 508 }
512 509
513#ifdef CONFIG_NF_CONNTRACK_MARK 510#ifdef CONFIG_NF_CONNTRACK_MARK
@@ -523,14 +520,9 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
523 520
524 helper = __nf_ct_helper_find(&repl_tuple); 521 helper = __nf_ct_helper_find(&repl_tuple);
525 if (helper) { 522 if (helper) {
526 help = nf_ct_ext_add(conntrack, NF_CT_EXT_HELPER, 523 help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
527 GFP_ATOMIC);
528 if (help) 524 if (help)
529 /* not in hash table yet, so not strictly
530 necessary */
531 rcu_assign_pointer(help->helper, helper); 525 rcu_assign_pointer(help->helper, helper);
532 else
533 DEBUGP("failed to add helper extension area");
534 } 526 }
535 NF_CT_STAT_INC(new); 527 NF_CT_STAT_INC(new);
536 } 528 }
@@ -721,11 +713,9 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
721 } 713 }
722 714
723 if (help == NULL) { 715 if (help == NULL) {
724 help = nf_ct_ext_add(ct, NF_CT_EXT_HELPER, GFP_ATOMIC); 716 help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
725 if (help == NULL) { 717 if (help == NULL)
726 DEBUGP("failed to add helper extension area");
727 goto out; 718 goto out;
728 }
729 } else { 719 } else {
730 memset(&help->help, 0, sizeof(help->help)); 720 memset(&help->help, 0, sizeof(help->help));
731 } 721 }
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index c5006b0a4e65..5ef0dd439e76 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -27,9 +27,6 @@
27#include <net/netfilter/nf_conntrack_helper.h> 27#include <net/netfilter/nf_conntrack_helper.h>
28#include <net/netfilter/nf_conntrack_tuple.h> 28#include <net/netfilter/nf_conntrack_tuple.h>
29 29
30LIST_HEAD(nf_ct_expect_list);
31EXPORT_SYMBOL_GPL(nf_ct_expect_list);
32
33struct hlist_head *nf_ct_expect_hash __read_mostly; 30struct hlist_head *nf_ct_expect_hash __read_mostly;
34EXPORT_SYMBOL_GPL(nf_ct_expect_hash); 31EXPORT_SYMBOL_GPL(nf_ct_expect_hash);
35 32
@@ -52,13 +49,14 @@ void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
52 NF_CT_ASSERT(master_help); 49 NF_CT_ASSERT(master_help);
53 NF_CT_ASSERT(!timer_pending(&exp->timeout)); 50 NF_CT_ASSERT(!timer_pending(&exp->timeout));
54 51
55 list_del(&exp->list);
56 hlist_del(&exp->hnode); 52 hlist_del(&exp->hnode);
57 nf_ct_expect_count--; 53 nf_ct_expect_count--;
58 54
59 NF_CT_STAT_INC(expect_delete); 55 hlist_del(&exp->lnode);
60 master_help->expecting--; 56 master_help->expecting--;
61 nf_ct_expect_put(exp); 57 nf_ct_expect_put(exp);
58
59 NF_CT_STAT_INC(expect_delete);
62} 60}
63EXPORT_SYMBOL_GPL(nf_ct_unlink_expect); 61EXPORT_SYMBOL_GPL(nf_ct_unlink_expect);
64 62
@@ -153,17 +151,18 @@ nf_ct_find_expectation(const struct nf_conntrack_tuple *tuple)
153/* delete all expectations for this conntrack */ 151/* delete all expectations for this conntrack */
154void nf_ct_remove_expectations(struct nf_conn *ct) 152void nf_ct_remove_expectations(struct nf_conn *ct)
155{ 153{
156 struct nf_conntrack_expect *i, *tmp;
157 struct nf_conn_help *help = nfct_help(ct); 154 struct nf_conn_help *help = nfct_help(ct);
155 struct nf_conntrack_expect *exp;
156 struct hlist_node *n, *next;
158 157
159 /* Optimization: most connection never expect any others. */ 158 /* Optimization: most connection never expect any others. */
160 if (!help || help->expecting == 0) 159 if (!help || help->expecting == 0)
161 return; 160 return;
162 161
163 list_for_each_entry_safe(i, tmp, &nf_ct_expect_list, list) { 162 hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) {
164 if (i->master == ct && del_timer(&i->timeout)) { 163 if (del_timer(&exp->timeout)) {
165 nf_ct_unlink_expect(i); 164 nf_ct_unlink_expect(exp);
166 nf_ct_expect_put(i); 165 nf_ct_expect_put(exp);
167 } 166 }
168 } 167 }
169} 168}
@@ -289,9 +288,10 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
289 unsigned int h = nf_ct_expect_dst_hash(&exp->tuple); 288 unsigned int h = nf_ct_expect_dst_hash(&exp->tuple);
290 289
291 atomic_inc(&exp->use); 290 atomic_inc(&exp->use);
291
292 hlist_add_head(&exp->lnode, &master_help->expectations);
292 master_help->expecting++; 293 master_help->expecting++;
293 294
294 list_add(&exp->list, &nf_ct_expect_list);
295 hlist_add_head(&exp->hnode, &nf_ct_expect_hash[h]); 295 hlist_add_head(&exp->hnode, &nf_ct_expect_hash[h]);
296 nf_ct_expect_count++; 296 nf_ct_expect_count++;
297 297
@@ -308,16 +308,16 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
308/* Race with expectations being used means we could have none to find; OK. */ 308/* Race with expectations being used means we could have none to find; OK. */
309static void evict_oldest_expect(struct nf_conn *master) 309static void evict_oldest_expect(struct nf_conn *master)
310{ 310{
311 struct nf_conntrack_expect *i; 311 struct nf_conn_help *master_help = nfct_help(master);
312 struct nf_conntrack_expect *exp = NULL;
313 struct hlist_node *n;
312 314
313 list_for_each_entry_reverse(i, &nf_ct_expect_list, list) { 315 hlist_for_each_entry(exp, n, &master_help->expectations, lnode)
314 if (i->master == master) { 316 ; /* nothing */
315 if (del_timer(&i->timeout)) { 317
316 nf_ct_unlink_expect(i); 318 if (exp && del_timer(&exp->timeout)) {
317 nf_ct_expect_put(i); 319 nf_ct_unlink_expect(exp);
318 } 320 nf_ct_expect_put(exp);
319 break;
320 }
321 } 321 }
322} 322}
323 323
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index cc8ae7404ac4..66c209d7e09d 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -87,6 +87,19 @@ __nf_conntrack_helper_find_byname(const char *name)
87} 87}
88EXPORT_SYMBOL_GPL(__nf_conntrack_helper_find_byname); 88EXPORT_SYMBOL_GPL(__nf_conntrack_helper_find_byname);
89 89
90struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp)
91{
92 struct nf_conn_help *help;
93
94 help = nf_ct_ext_add(ct, NF_CT_EXT_HELPER, gfp);
95 if (help)
96 INIT_HLIST_HEAD(&help->expectations);
97 else
98 pr_debug("failed to add helper extension area");
99 return help;
100}
101EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add);
102
90static inline int unhelp(struct nf_conntrack_tuple_hash *i, 103static inline int unhelp(struct nf_conntrack_tuple_hash *i,
91 const struct nf_conntrack_helper *me) 104 const struct nf_conntrack_helper *me)
92{ 105{
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 60af9b6b9e00..6f89b105a205 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -868,7 +868,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
868 /* need to zero data of old helper */ 868 /* need to zero data of old helper */
869 memset(&help->help, 0, sizeof(help->help)); 869 memset(&help->help, 0, sizeof(help->help));
870 } else { 870 } else {
871 help = nf_ct_ext_add(ct, NF_CT_EXT_HELPER, GFP_KERNEL); 871 help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
872 if (help == NULL) 872 if (help == NULL)
873 return -ENOMEM; 873 return -ENOMEM;
874 } 874 }
@@ -989,7 +989,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
989 989
990 helper = nf_ct_helper_find_get(rtuple); 990 helper = nf_ct_helper_find_get(rtuple);
991 if (helper) { 991 if (helper) {
992 help = nf_ct_ext_add(ct, NF_CT_EXT_HELPER, GFP_KERNEL); 992 help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
993 if (help == NULL) { 993 if (help == NULL) {
994 nf_ct_helper_put(helper); 994 nf_ct_helper_put(helper);
995 err = -ENOMEM; 995 err = -ENOMEM;