fix IMQ on linux 2.6.27 and 2.6.28
[openwrt.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,