aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2009-02-21 16:33:24 +0000
committerFelix Fietkau <nbd@openwrt.org>2009-02-21 16:33:24 +0000
commit0e461e45dbd71b34ab409034b3c09520aeaea431 (patch)
treef7744aedcd15d214c9c505e6e7db05aa61fbf179
parent2fc5d9bb16e2c15a0c454533e26b019b48ec6d58 (diff)
downloadupstream-0e461e45dbd71b34ab409034b3c09520aeaea431.tar.gz
upstream-0e461e45dbd71b34ab409034b3c09520aeaea431.tar.bz2
upstream-0e461e45dbd71b34ab409034b3c09520aeaea431.zip
fix IMQ on linux 2.6.27 and 2.6.28
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@14599 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r--package/kernel/modules/netfilter.mk2
-rw-r--r--target/linux/generic-2.6/patches-2.6.27/151-netfilter_imq_2.6.27.patch75
-rw-r--r--target/linux/generic-2.6/patches-2.6.28/151-netfilter_imq_2.6.28.patch114
3 files changed, 190 insertions, 1 deletions
diff --git a/package/kernel/modules/netfilter.mk b/package/kernel/modules/netfilter.mk
index d757b9e976..5817595649 100644
--- a/package/kernel/modules/netfilter.mk
+++ b/package/kernel/modules/netfilter.mk
@@ -237,7 +237,7 @@ define KernelPackage/ipt-imq
imq \
$(IPT_IMQ-m) \
))
- DEPENDS:= kmod-ipt-core @!LINUX_2_6_27 @!LINUX_2_6_28
+ DEPENDS:= kmod-ipt-core
endef
define KernelPackage/ipt-imq/description
diff --git a/target/linux/generic-2.6/patches-2.6.27/151-netfilter_imq_2.6.27.patch b/target/linux/generic-2.6/patches-2.6.27/151-netfilter_imq_2.6.27.patch
new file mode 100644
index 0000000000..9390db7424
--- /dev/null
+++ b/target/linux/generic-2.6/patches-2.6.27/151-netfilter_imq_2.6.27.patch
@@ -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,
diff --git a/target/linux/generic-2.6/patches-2.6.28/151-netfilter_imq_2.6.28.patch b/target/linux/generic-2.6/patches-2.6.28/151-netfilter_imq_2.6.28.patch
new file mode 100644
index 0000000000..c531042444
--- /dev/null
+++ b/target/linux/generic-2.6/patches-2.6.28/151-netfilter_imq_2.6.28.patch
@@ -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