fix IMQ on linux 2.6.27 and 2.6.28
SVN-Revision: 14599
This commit is contained in:
		@@ -237,7 +237,7 @@ define KernelPackage/ipt-imq
 | 
				
			|||||||
	imq \
 | 
						imq \
 | 
				
			||||||
	$(IPT_IMQ-m) \
 | 
						$(IPT_IMQ-m) \
 | 
				
			||||||
  ))
 | 
					  ))
 | 
				
			||||||
  DEPENDS:= kmod-ipt-core @!LINUX_2_6_27 @!LINUX_2_6_28
 | 
					  DEPENDS:= kmod-ipt-core
 | 
				
			||||||
endef
 | 
					endef
 | 
				
			||||||
 | 
					
 | 
				
			||||||
define KernelPackage/ipt-imq/description
 | 
					define KernelPackage/ipt-imq/description
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,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,
 | 
				
			||||||
@@ -0,0 +1,114 @@
 | 
				
			|||||||
 | 
					--- 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 +253,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,
 | 
				
			||||||
 | 
					--- a/net/ipv4/netfilter/ipt_IMQ.c
 | 
				
			||||||
 | 
					+++ b/net/ipv4/netfilter/ipt_IMQ.c
 | 
				
			||||||
 | 
					@@ -7,29 +7,23 @@
 | 
				
			||||||
 | 
					 #include <linux/netfilter_ipv4/ipt_IMQ.h>
 | 
				
			||||||
 | 
					 #include <linux/imq.h>
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-static unsigned int imq_target(struct sk_buff *pskb,
 | 
				
			||||||
 | 
					-			       const struct net_device *in,
 | 
				
			||||||
 | 
					-			       const struct net_device *out,
 | 
				
			||||||
 | 
					-			       unsigned int hooknum,
 | 
				
			||||||
 | 
					-			       const struct xt_target *target,
 | 
				
			||||||
 | 
					-			       const void *targinfo)
 | 
				
			||||||
 | 
					+static unsigned int
 | 
				
			||||||
 | 
					+imq_target(struct sk_buff *pskb,
 | 
				
			||||||
 | 
					+           const struct xt_target_param *par)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					-	struct ipt_imq_info *mr = (struct ipt_imq_info *)targinfo;
 | 
				
			||||||
 | 
					+	struct ipt_imq_info *mr = (struct ipt_imq_info *)par->targinfo;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	pskb->imq_flags = mr->todev | IMQ_F_ENQUEUE;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	return XT_CONTINUE;
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-static bool imq_checkentry(const char *tablename,
 | 
				
			||||||
 | 
					-			  const void *e,
 | 
				
			||||||
 | 
					-			  const struct xt_target *target,
 | 
				
			||||||
 | 
					-			  void *targinfo,
 | 
				
			||||||
 | 
					-			  unsigned int hook_mask)
 | 
				
			||||||
 | 
					+static bool
 | 
				
			||||||
 | 
					+imq_checkentry(const struct xt_tgchk_param *par)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					 	struct ipt_imq_info *mr;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	mr = (struct ipt_imq_info *)targinfo;
 | 
				
			||||||
 | 
					+	mr = (struct ipt_imq_info *)par->targinfo;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	if (mr->todev > IMQ_MAX_DEVS) {
 | 
				
			||||||
 | 
					 		printk(KERN_WARNING
 | 
				
			||||||
		Reference in New Issue
	
	Block a user