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