···3 * communicating with userspace via netlink.4 *5 * (C) 2000-2002 James Morris <jmorris@intercode.com.au>06 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License version 2 as···18 * 2005-01-10: Added /proc counter for dropped packets; fixed so19 * packets aren't delivered to user space if they're going 20 * to be dropped. 021 *22 */23#include <linux/module.h>···73static void74ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict)75{00000076 nf_reinject(entry->skb, entry->info, verdict);0077 kfree(entry);78}79
···3 * communicating with userspace via netlink.4 *5 * (C) 2000-2002 James Morris <jmorris@intercode.com.au>6+ * (C) 2003-2005 Netfilter Core Team <coreteam@netfilter.org>7 *8 * This program is free software; you can redistribute it and/or modify9 * it under the terms of the GNU General Public License version 2 as···17 * 2005-01-10: Added /proc counter for dropped packets; fixed so18 * packets aren't delivered to user space if they're going 19 * to be dropped. 20+ * 2005-05-26: local_bh_{disable,enable} around nf_reinject (Harald Welte)21 *22 */23#include <linux/module.h>···71static void72ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict)73{74+ /* TCP input path (and probably other bits) assume to be called75+ * from softirq context, not from syscall, like ipq_issue_verdict is76+ * called. TCP input path deadlocks with locks taken from timer77+ * softirq, e.g. We therefore emulate this by local_bh_disable() */78+79+ local_bh_disable();80 nf_reinject(entry->skb, entry->info, verdict);81+ local_bh_enable();82+83 kfree(entry);84}85
+6-6
net/ipv4/udp.c
···738 unsigned long amount;739740 amount = 0;741- spin_lock_irq(&sk->sk_receive_queue.lock);742 skb = skb_peek(&sk->sk_receive_queue);743 if (skb != NULL) {744 /*···748 */749 amount = skb->len - sizeof(struct udphdr);750 }751- spin_unlock_irq(&sk->sk_receive_queue.lock);752 return put_user(amount, (int __user *)arg);753 }754···848 /* Clear queue. */849 if (flags&MSG_PEEK) {850 int clear = 0;851- spin_lock_irq(&sk->sk_receive_queue.lock);852 if (skb == skb_peek(&sk->sk_receive_queue)) {853 __skb_unlink(skb, &sk->sk_receive_queue);854 clear = 1;855 }856- spin_unlock_irq(&sk->sk_receive_queue.lock);857 if (clear)858 kfree_skb(skb);859 }···1334 struct sk_buff_head *rcvq = &sk->sk_receive_queue;1335 struct sk_buff *skb;13361337- spin_lock_irq(&rcvq->lock);1338 while ((skb = skb_peek(rcvq)) != NULL) {1339 if (udp_checksum_complete(skb)) {1340 UDP_INC_STATS_BH(UDP_MIB_INERRORS);···1345 break;1346 }1347 }1348- spin_unlock_irq(&rcvq->lock);13491350 /* nothing to see, move along */1351 if (skb == NULL)
···738 unsigned long amount;739740 amount = 0;741+ spin_lock_bh(&sk->sk_receive_queue.lock);742 skb = skb_peek(&sk->sk_receive_queue);743 if (skb != NULL) {744 /*···748 */749 amount = skb->len - sizeof(struct udphdr);750 }751+ spin_unlock_bh(&sk->sk_receive_queue.lock);752 return put_user(amount, (int __user *)arg);753 }754···848 /* Clear queue. */849 if (flags&MSG_PEEK) {850 int clear = 0;851+ spin_lock_bh(&sk->sk_receive_queue.lock);852 if (skb == skb_peek(&sk->sk_receive_queue)) {853 __skb_unlink(skb, &sk->sk_receive_queue);854 clear = 1;855 }856+ spin_unlock_bh(&sk->sk_receive_queue.lock);857 if (clear)858 kfree_skb(skb);859 }···1334 struct sk_buff_head *rcvq = &sk->sk_receive_queue;1335 struct sk_buff *skb;13361337+ spin_lock_bh(&rcvq->lock);1338 while ((skb = skb_peek(rcvq)) != NULL) {1339 if (udp_checksum_complete(skb)) {1340 UDP_INC_STATS_BH(UDP_MIB_INERRORS);···1345 break;1346 }1347 }1348+ spin_unlock_bh(&rcvq->lock);13491350 /* nothing to see, move along */1351 if (skb == NULL)
+11-5
net/sched/sch_dsmark.c
···18#include <asm/byteorder.h>192021-#if 1 /* control */22#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)23#else24#define DPRINTK(format,args...)···7374 DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",sch,p,new,75 old);76- if (!new)77- new = &noop_qdisc;0000078 sch_tree_lock(sch);79 *old = xchg(&p->q,new);80 if (*old)···168 return;169 for (i = 0; i < p->indices; i++) {170 if (p->mask[i] == 0xff && !p->value[i])171- continue;172 if (walker->count >= walker->skip) {173 if (walker->fn(sch, i+1, walker) < 0) {174 walker->stop = 1;175 break;176 }177 }178- walker->count++;0179 }180}181
···18#include <asm/byteorder.h>192021+#if 0 /* control */22#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)23#else24#define DPRINTK(format,args...)···7374 DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",sch,p,new,75 old);76+77+ if (new == NULL) {78+ new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);79+ if (new == NULL)80+ new = &noop_qdisc;81+ }82+83 sch_tree_lock(sch);84 *old = xchg(&p->q,new);85 if (*old)···163 return;164 for (i = 0; i < p->indices; i++) {165 if (p->mask[i] == 0xff && !p->value[i])166+ goto ignore;167 if (walker->count >= walker->skip) {168 if (walker->fn(sch, i+1, walker) < 0) {169 walker->stop = 1;170 break;171 }172 }173+ignore: 174+ walker->count++;175 }176}177