aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-01-31 07:38:38 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-31 22:27:54 -0500
commit76507f69c44ed199a1a68086145398459e55835d (patch)
tree2e83a70fa50f3432ca63eeef84e038c72d254d10 /net/ipv4
parent7d0742da1c8f5df3a34030f0170b30d1a052be80 (diff)
[NETFILTER]: nf_conntrack: use RCU for conntrack hash
Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index 2fdcd9233a03..0ee87edbd286 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -39,12 +39,14 @@ struct ct_iter_state {
39static struct hlist_node *ct_get_first(struct seq_file *seq) 39static struct hlist_node *ct_get_first(struct seq_file *seq)
40{ 40{
41 struct ct_iter_state *st = seq->private; 41 struct ct_iter_state *st = seq->private;
42 struct hlist_node *n;
42 43
43 for (st->bucket = 0; 44 for (st->bucket = 0;
44 st->bucket < nf_conntrack_htable_size; 45 st->bucket < nf_conntrack_htable_size;
45 st->bucket++) { 46 st->bucket++) {
46 if (!hlist_empty(&nf_conntrack_hash[st->bucket])) 47 n = rcu_dereference(nf_conntrack_hash[st->bucket].first);
47 return nf_conntrack_hash[st->bucket].first; 48 if (n)
49 return n;
48 } 50 }
49 return NULL; 51 return NULL;
50} 52}
@@ -54,11 +56,11 @@ static struct hlist_node *ct_get_next(struct seq_file *seq,
54{ 56{
55 struct ct_iter_state *st = seq->private; 57 struct ct_iter_state *st = seq->private;
56 58
57 head = head->next; 59 head = rcu_dereference(head->next);
58 while (head == NULL) { 60 while (head == NULL) {
59 if (++st->bucket >= nf_conntrack_htable_size) 61 if (++st->bucket >= nf_conntrack_htable_size)
60 return NULL; 62 return NULL;
61 head = nf_conntrack_hash[st->bucket].first; 63 head = rcu_dereference(nf_conntrack_hash[st->bucket].first);
62 } 64 }
63 return head; 65 return head;
64} 66}
@@ -74,8 +76,9 @@ static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
74} 76}
75 77
76static void *ct_seq_start(struct seq_file *seq, loff_t *pos) 78static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
79 __acquires(RCU)
77{ 80{
78 read_lock_bh(&nf_conntrack_lock); 81 rcu_read_lock();
79 return ct_get_idx(seq, *pos); 82 return ct_get_idx(seq, *pos);
80} 83}
81 84
@@ -86,8 +89,9 @@ static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
86} 89}
87 90
88static void ct_seq_stop(struct seq_file *s, void *v) 91static void ct_seq_stop(struct seq_file *s, void *v)
92 __releases(RCU)
89{ 93{
90 read_unlock_bh(&nf_conntrack_lock); 94 rcu_read_unlock();
91} 95}
92 96
93static int ct_seq_show(struct seq_file *s, void *v) 97static int ct_seq_show(struct seq_file *s, void *v)
@@ -226,6 +230,7 @@ static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
226} 230}
227 231
228static void *exp_seq_start(struct seq_file *seq, loff_t *pos) 232static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
233 __acquires(RCU)
229{ 234{
230 rcu_read_lock(); 235 rcu_read_lock();
231 return ct_expect_get_idx(seq, *pos); 236 return ct_expect_get_idx(seq, *pos);
@@ -238,6 +243,7 @@ static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
238} 243}
239 244
240static void exp_seq_stop(struct seq_file *seq, void *v) 245static void exp_seq_stop(struct seq_file *seq, void *v)
246 __releases(RCU)
241{ 247{
242 rcu_read_unlock(); 248 rcu_read_unlock();
243} 249}