提交 72a95d14 编写于 作者: L Linus Torvalds
...@@ -478,7 +478,7 @@ static int __init esp4_init(void) ...@@ -478,7 +478,7 @@ static int __init esp4_init(void)
{ {
struct xfrm_decap_state decap; struct xfrm_decap_state decap;
if (sizeof(struct esp_decap_data) < if (sizeof(struct esp_decap_data) >
sizeof(decap.decap_data)) { sizeof(decap.decap_data)) {
extern void decap_data_too_small(void); extern void decap_data_too_small(void);
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* communicating with userspace via netlink. * communicating with userspace via netlink.
* *
* (C) 2000-2002 James Morris <jmorris@intercode.com.au> * (C) 2000-2002 James Morris <jmorris@intercode.com.au>
* (C) 2003-2005 Netfilter Core Team <coreteam@netfilter.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -17,6 +18,7 @@ ...@@ -17,6 +18,7 @@
* 2005-01-10: Added /proc counter for dropped packets; fixed so * 2005-01-10: Added /proc counter for dropped packets; fixed so
* packets aren't delivered to user space if they're going * packets aren't delivered to user space if they're going
* to be dropped. * to be dropped.
* 2005-05-26: local_bh_{disable,enable} around nf_reinject (Harald Welte)
* *
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -71,7 +73,15 @@ static DECLARE_MUTEX(ipqnl_sem); ...@@ -71,7 +73,15 @@ static DECLARE_MUTEX(ipqnl_sem);
static void static void
ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict) ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict)
{ {
/* TCP input path (and probably other bits) assume to be called
* from softirq context, not from syscall, like ipq_issue_verdict is
* called. TCP input path deadlocks with locks taken from timer
* softirq, e.g. We therefore emulate this by local_bh_disable() */
local_bh_disable();
nf_reinject(entry->skb, entry->info, verdict); nf_reinject(entry->skb, entry->info, verdict);
local_bh_enable();
kfree(entry); kfree(entry);
} }
......
...@@ -738,7 +738,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) ...@@ -738,7 +738,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
unsigned long amount; unsigned long amount;
amount = 0; amount = 0;
spin_lock_irq(&sk->sk_receive_queue.lock); spin_lock_bh(&sk->sk_receive_queue.lock);
skb = skb_peek(&sk->sk_receive_queue); skb = skb_peek(&sk->sk_receive_queue);
if (skb != NULL) { if (skb != NULL) {
/* /*
...@@ -748,7 +748,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) ...@@ -748,7 +748,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
*/ */
amount = skb->len - sizeof(struct udphdr); amount = skb->len - sizeof(struct udphdr);
} }
spin_unlock_irq(&sk->sk_receive_queue.lock); spin_unlock_bh(&sk->sk_receive_queue.lock);
return put_user(amount, (int __user *)arg); return put_user(amount, (int __user *)arg);
} }
...@@ -848,12 +848,12 @@ static int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, ...@@ -848,12 +848,12 @@ static int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
/* Clear queue. */ /* Clear queue. */
if (flags&MSG_PEEK) { if (flags&MSG_PEEK) {
int clear = 0; int clear = 0;
spin_lock_irq(&sk->sk_receive_queue.lock); spin_lock_bh(&sk->sk_receive_queue.lock);
if (skb == skb_peek(&sk->sk_receive_queue)) { if (skb == skb_peek(&sk->sk_receive_queue)) {
__skb_unlink(skb, &sk->sk_receive_queue); __skb_unlink(skb, &sk->sk_receive_queue);
clear = 1; clear = 1;
} }
spin_unlock_irq(&sk->sk_receive_queue.lock); spin_unlock_bh(&sk->sk_receive_queue.lock);
if (clear) if (clear)
kfree_skb(skb); kfree_skb(skb);
} }
...@@ -1334,7 +1334,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) ...@@ -1334,7 +1334,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
struct sk_buff_head *rcvq = &sk->sk_receive_queue; struct sk_buff_head *rcvq = &sk->sk_receive_queue;
struct sk_buff *skb; struct sk_buff *skb;
spin_lock_irq(&rcvq->lock); spin_lock_bh(&rcvq->lock);
while ((skb = skb_peek(rcvq)) != NULL) { while ((skb = skb_peek(rcvq)) != NULL) {
if (udp_checksum_complete(skb)) { if (udp_checksum_complete(skb)) {
UDP_INC_STATS_BH(UDP_MIB_INERRORS); UDP_INC_STATS_BH(UDP_MIB_INERRORS);
...@@ -1345,7 +1345,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) ...@@ -1345,7 +1345,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
break; break;
} }
} }
spin_unlock_irq(&rcvq->lock); spin_unlock_bh(&rcvq->lock);
/* nothing to see, move along */ /* nothing to see, move along */
if (skb == NULL) if (skb == NULL)
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <asm/byteorder.h> #include <asm/byteorder.h>
#if 1 /* control */ #if 0 /* control */
#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
#else #else
#define DPRINTK(format,args...) #define DPRINTK(format,args...)
...@@ -73,8 +73,13 @@ static int dsmark_graft(struct Qdisc *sch,unsigned long arg, ...@@ -73,8 +73,13 @@ static int dsmark_graft(struct Qdisc *sch,unsigned long arg,
DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",sch,p,new, DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",sch,p,new,
old); old);
if (!new)
new = &noop_qdisc; if (new == NULL) {
new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
if (new == NULL)
new = &noop_qdisc;
}
sch_tree_lock(sch); sch_tree_lock(sch);
*old = xchg(&p->q,new); *old = xchg(&p->q,new);
if (*old) if (*old)
...@@ -163,14 +168,15 @@ static void dsmark_walk(struct Qdisc *sch,struct qdisc_walker *walker) ...@@ -163,14 +168,15 @@ static void dsmark_walk(struct Qdisc *sch,struct qdisc_walker *walker)
return; return;
for (i = 0; i < p->indices; i++) { for (i = 0; i < p->indices; i++) {
if (p->mask[i] == 0xff && !p->value[i]) if (p->mask[i] == 0xff && !p->value[i])
continue; goto ignore;
if (walker->count >= walker->skip) { if (walker->count >= walker->skip) {
if (walker->fn(sch, i+1, walker) < 0) { if (walker->fn(sch, i+1, walker) < 0) {
walker->stop = 1; walker->stop = 1;
break; break;
} }
} }
walker->count++; ignore:
walker->count++;
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册