diff options
author | Patrick McHardy <kaber@trash.net> | 2007-12-05 04:27:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:56:15 -0500 |
commit | 4b3d15ef4a88683d93d1b76351297d2298a02a99 (patch) | |
tree | ec8b02db4089a03e179a48190ded490ddc082004 /net | |
parent | 02f014d88831f73b895c1fe09badb66c88e932d3 (diff) |
[NETFILTER]: {nfnetlink,ip,ip6}_queue: kill issue_verdict
Now that issue_verdict doesn't need to free the queue entries anymore,
all it does is disable local BHs and call nf_reinject. Move the BH
disabling to the okfn invocation in nf_reinject and kill the
issue_verdict functions.
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/ipv4/netfilter/ip_queue.c | 17 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_queue.c | 12 | ||||
-rw-r--r-- | net/netfilter/nf_queue.c | 2 | ||||
-rw-r--r-- | net/netfilter/nfnetlink_queue.c | 21 |
4 files changed, 8 insertions, 44 deletions
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index f1affd2344a9..68b12ce8ba55 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -49,19 +49,6 @@ static struct sock *ipqnl __read_mostly; | |||
49 | static LIST_HEAD(queue_list); | 49 | static LIST_HEAD(queue_list); |
50 | static DEFINE_MUTEX(ipqnl_mutex); | 50 | static DEFINE_MUTEX(ipqnl_mutex); |
51 | 51 | ||
52 | static void | ||
53 | ipq_issue_verdict(struct nf_queue_entry *entry, int verdict) | ||
54 | { | ||
55 | /* TCP input path (and probably other bits) assume to be called | ||
56 | * from softirq context, not from syscall, like ipq_issue_verdict is | ||
57 | * called. TCP input path deadlocks with locks taken from timer | ||
58 | * softirq, e.g. We therefore emulate this by local_bh_disable() */ | ||
59 | |||
60 | local_bh_disable(); | ||
61 | nf_reinject(entry, verdict); | ||
62 | local_bh_enable(); | ||
63 | } | ||
64 | |||
65 | static inline void | 52 | static inline void |
66 | __ipq_enqueue_entry(struct nf_queue_entry *entry) | 53 | __ipq_enqueue_entry(struct nf_queue_entry *entry) |
67 | { | 54 | { |
@@ -138,7 +125,7 @@ __ipq_flush(ipq_cmpfn cmpfn, unsigned long data) | |||
138 | if (!cmpfn || cmpfn(entry, data)) { | 125 | if (!cmpfn || cmpfn(entry, data)) { |
139 | list_del(&entry->list); | 126 | list_del(&entry->list); |
140 | queue_total--; | 127 | queue_total--; |
141 | ipq_issue_verdict(entry, NF_DROP); | 128 | nf_reinject(entry, NF_DROP); |
142 | } | 129 | } |
143 | } | 130 | } |
144 | } | 131 | } |
@@ -345,7 +332,7 @@ ipq_set_verdict(struct ipq_verdict_msg *vmsg, unsigned int len) | |||
345 | if (ipq_mangle_ipv4(vmsg, entry) < 0) | 332 | if (ipq_mangle_ipv4(vmsg, entry) < 0) |
346 | verdict = NF_DROP; | 333 | verdict = NF_DROP; |
347 | 334 | ||
348 | ipq_issue_verdict(entry, verdict); | 335 | nf_reinject(entry, verdict); |
349 | return 0; | 336 | return 0; |
350 | } | 337 | } |
351 | } | 338 | } |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 9014adae4fb1..e5b0059582f5 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -53,14 +53,6 @@ static struct sock *ipqnl __read_mostly; | |||
53 | static LIST_HEAD(queue_list); | 53 | static LIST_HEAD(queue_list); |
54 | static DEFINE_MUTEX(ipqnl_mutex); | 54 | static DEFINE_MUTEX(ipqnl_mutex); |
55 | 55 | ||
56 | static void | ||
57 | ipq_issue_verdict(struct nf_queue_entry *entry, int verdict) | ||
58 | { | ||
59 | local_bh_disable(); | ||
60 | nf_reinject(entry, verdict); | ||
61 | local_bh_enable(); | ||
62 | } | ||
63 | |||
64 | static inline void | 56 | static inline void |
65 | __ipq_enqueue_entry(struct nf_queue_entry *entry) | 57 | __ipq_enqueue_entry(struct nf_queue_entry *entry) |
66 | { | 58 | { |
@@ -137,7 +129,7 @@ __ipq_flush(ipq_cmpfn cmpfn, unsigned long data) | |||
137 | if (!cmpfn || cmpfn(entry, data)) { | 129 | if (!cmpfn || cmpfn(entry, data)) { |
138 | list_del(&entry->list); | 130 | list_del(&entry->list); |
139 | queue_total--; | 131 | queue_total--; |
140 | ipq_issue_verdict(entry, NF_DROP); | 132 | nf_reinject(entry, NF_DROP); |
141 | } | 133 | } |
142 | } | 134 | } |
143 | } | 135 | } |
@@ -343,7 +335,7 @@ ipq_set_verdict(struct ipq_verdict_msg *vmsg, unsigned int len) | |||
343 | if (ipq_mangle_ipv6(vmsg, entry) < 0) | 335 | if (ipq_mangle_ipv6(vmsg, entry) < 0) |
344 | verdict = NF_DROP; | 336 | verdict = NF_DROP; |
345 | 337 | ||
346 | ipq_issue_verdict(entry, verdict); | 338 | nf_reinject(entry, verdict); |
347 | return 0; | 339 | return 0; |
348 | } | 340 | } |
349 | } | 341 | } |
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index d9d3dc4ce1a3..f0dc72704111 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c | |||
@@ -275,7 +275,9 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) | |||
275 | switch (verdict & NF_VERDICT_MASK) { | 275 | switch (verdict & NF_VERDICT_MASK) { |
276 | case NF_ACCEPT: | 276 | case NF_ACCEPT: |
277 | case NF_STOP: | 277 | case NF_STOP: |
278 | local_bh_disable(); | ||
278 | entry->okfn(skb); | 279 | entry->okfn(skb); |
280 | local_bh_enable(); | ||
279 | case NF_STOLEN: | 281 | case NF_STOLEN: |
280 | break; | 282 | break; |
281 | case NF_QUEUE: | 283 | case NF_QUEUE: |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index a4937649d006..d9ce3942af2a 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -202,23 +202,6 @@ instance_destroy(struct nfqnl_instance *inst) | |||
202 | _instance_destroy2(inst, 1); | 202 | _instance_destroy2(inst, 1); |
203 | } | 203 | } |
204 | 204 | ||
205 | |||
206 | |||
207 | static void | ||
208 | issue_verdict(struct nf_queue_entry *entry, int verdict) | ||
209 | { | ||
210 | QDEBUG("entering for entry %p, verdict %u\n", entry, verdict); | ||
211 | |||
212 | /* TCP input path (and probably other bits) assume to be called | ||
213 | * from softirq context, not from syscall, like issue_verdict is | ||
214 | * called. TCP input path deadlocks with locks taken from timer | ||
215 | * softirq, e.g. We therefore emulate this by local_bh_disable() */ | ||
216 | |||
217 | local_bh_disable(); | ||
218 | nf_reinject(entry, verdict); | ||
219 | local_bh_enable(); | ||
220 | } | ||
221 | |||
222 | static inline void | 205 | static inline void |
223 | __enqueue_entry(struct nfqnl_instance *queue, struct nf_queue_entry *entry) | 206 | __enqueue_entry(struct nfqnl_instance *queue, struct nf_queue_entry *entry) |
224 | { | 207 | { |
@@ -289,7 +272,7 @@ nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn, unsigned long data) | |||
289 | if (!cmpfn || cmpfn(entry, data)) { | 272 | if (!cmpfn || cmpfn(entry, data)) { |
290 | list_del(&entry->list); | 273 | list_del(&entry->list); |
291 | queue->queue_total--; | 274 | queue->queue_total--; |
292 | issue_verdict(entry, NF_DROP); | 275 | nf_reinject(entry, NF_DROP); |
293 | } | 276 | } |
294 | } | 277 | } |
295 | spin_unlock_bh(&queue->lock); | 278 | spin_unlock_bh(&queue->lock); |
@@ -761,7 +744,7 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, | |||
761 | entry->skb->mark = ntohl(*(__be32 *) | 744 | entry->skb->mark = ntohl(*(__be32 *) |
762 | nla_data(nfqa[NFQA_MARK])); | 745 | nla_data(nfqa[NFQA_MARK])); |
763 | 746 | ||
764 | issue_verdict(entry, verdict); | 747 | nf_reinject(entry, verdict); |
765 | instance_put(queue); | 748 | instance_put(queue); |
766 | return 0; | 749 | return 0; |
767 | 750 | ||