summaryrefslogtreecommitdiffstats
path: root/target/linux/generic-2.6/patches-2.6.27/151-netfilter_imq_2.6.27.patch
blob: 9390db7424af657e764af3f1b221cfd617834006 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
--- a/drivers/net/imq.c
+++ b/drivers/net/imq.c
@@ -178,10 +178,11 @@ static int imq_nf_queue(struct nf_queue_
 	struct sk_buff *skb2 = NULL;
 	struct Qdisc *q;
 	unsigned int index = entry->skb->imq_flags & IMQ_F_IFMASK;
-	int ret = -1;
+	struct netdev_queue *txq;
+	int ret = -EINVAL;
 
 	if (index > numdevs)
-		return -1;
+		return ret;
 
 	/* check for imq device by index from cache */
 	dev = imq_devs_cache[index];
@@ -194,7 +195,7 @@ static int imq_nf_queue(struct nf_queue_
 		if (!dev) {
 			/* not found ?!*/
 			BUG();
-			return -1;
+			return ret;
 		}
 
 		imq_devs_cache[index] = dev;
@@ -212,17 +213,19 @@ static int imq_nf_queue(struct nf_queue_
 		skb2 = entry->skb;
 		entry->skb = skb_clone(entry->skb, GFP_ATOMIC);
 		if (!entry->skb)
-			return -1;
+			return -ENOMEM;
 	}
 	entry->skb->nf_queue_entry = entry;
 
 	dev->stats.rx_bytes += entry->skb->len;
 	dev->stats.rx_packets++;
 
-	spin_lock_bh(&dev->queue_lock);
-	q = dev->qdisc;
+	txq = netdev_get_tx_queue(dev, 0);
+	__netif_tx_lock_bh(txq);
+	q = txq->qdisc;
+
 	if (q->enqueue) {
-		q->enqueue(skb_get(entry->skb), q);
+		qdisc_enqueue_root(skb_get(entry->skb), q);
 		if (skb_shared(entry->skb)) {
 			entry->skb->destructor = imq_skb_destructor;
 			kfree_skb(entry->skb);
@@ -231,7 +234,7 @@ static int imq_nf_queue(struct nf_queue_
 	}
 	if (!test_and_set_bit(1, &priv->tasklet_pending))
 		tasklet_schedule(&priv->tasklet);
-	spin_unlock_bh(&dev->queue_lock);
+	__netif_tx_unlock_bh(txq);
 
 	if (skb2)
 		kfree_skb(ret ? entry->skb : skb2);
@@ -248,11 +251,13 @@ static void qdisc_run_tasklet(unsigned l
 {
 	struct net_device *dev = (struct net_device *)arg;
 	struct imq_private *priv = netdev_priv(dev);
+	struct netdev_queue *txq;
 
-	spin_lock(&dev->queue_lock);
-	qdisc_run(dev);
+	netif_tx_lock(dev);
+	txq = netdev_get_tx_queue(dev, 0);
+	qdisc_run(txq->qdisc);
 	clear_bit(1, &priv->tasklet_pending);
-	spin_unlock(&dev->queue_lock);
+	netif_tx_unlock(dev);
 }
 
 static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff *pskb,