]> git.pld-linux.org Git - packages/kernel.git/blobdiff - kernel-imq.patch
- update imq, vserver patches; drop forcedeth ugly HACK (if it's not fixed upstream...
[packages/kernel.git] / kernel-imq.patch
index 5847a95fa0bdc2e6dced711bf5c045294cd61606..ddde025f69babab00aca5c81bb09456201622d10 100644 (file)
@@ -1,7 +1,7 @@
-diff -uNr linux-2.6.39/drivers/net/imq.c linux-2.6.39-imqmq/drivers/net/imq.c
---- linux-2.6.39/drivers/net/imq.c     1970-01-01 02:00:00.000000000 +0200
-+++ linux-2.6.39-imqmq/drivers/net/imq.c       2011-05-19 11:08:03.838522212 +0300
-@@ -0,0 +1,777 @@
+diff -uNr linux-3.0/drivers/net/imq.c linux-3.0-imq/drivers/net/imq.c
+--- linux-3.0/drivers/net/imq.c        1970-01-01 02:00:00.000000000 +0200
++++ linux-3.0-imq/drivers/net/imq.c    2011-07-26 07:24:09.843279145 +0300
+@@ -0,0 +1,820 @@
 +/*
 + *             Pseudo-driver for the intermediate queue device.
 + *
@@ -105,6 +105,15 @@ diff -uNr linux-2.6.39/drivers/net/imq.c linux-2.6.39-imqmq/drivers/net/imq.c
 + *             2011/03/18 - (Jussi Kivilinna)
 + *              - Port to 2.6.38
 + *
++ *             2011/07/12 - (syoder89@gmail.com)
++ *              - Crash fix that happens when the receiving interface has more
++ *                than one queue (add missing skb_set_queue_mapping in
++ *                imq_select_queue).
++ *
++ *             2011/07/26 - (Jussi Kivilinna)
++ *              - Add queue mapping checks for packets exiting IMQ.
++ *              - Port to 3.0
++ *
 + *           Also, many thanks to pablo Sebastian Greco for making the initial
 + *           patch and to those who helped the testing.
 + *
@@ -199,78 +208,10 @@ diff -uNr linux-2.6.39/drivers/net/imq.c linux-2.6.39-imqmq/drivers/net/imq.c
 +static int numdevs = IMQ_MAX_DEVS;
 +#endif
 +
-+#define IMQ_MAX_QUEUES 32
-+static int numqueues = 1;
-+
-+/*static DEFINE_SPINLOCK(imq_nf_queue_lock);*/
-+
 +static struct net_device *imq_devs_cache[IMQ_MAX_DEVS];
 +
-+
-+static struct net_device_stats *imq_get_stats(struct net_device *dev)
-+{
-+      return &dev->stats;
-+}
-+
-+/* called for packets kfree'd in qdiscs at places other than enqueue */
-+static void imq_skb_destructor(struct sk_buff *skb)
-+{
-+      struct nf_queue_entry *entry = skb->nf_queue_entry;
-+
-+      skb->nf_queue_entry = NULL;
-+
-+      if (entry) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree(entry);
-+      }
-+
-+      skb_restore_cb(skb); /* kfree backup */
-+}
-+
-+static netdev_tx_t imq_dev_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+      struct nf_queue_entry *entry = skb->nf_queue_entry;
-+
-+      skb->nf_queue_entry = NULL;
-+      dev->trans_start = jiffies;
-+
-+      dev->stats.tx_bytes += skb->len;
-+      dev->stats.tx_packets++;
-+
-+      if (entry == NULL) {
-+              /* We don't know what is going on here.. packet is queued for
-+               * imq device, but (probably) not by us.
-+               *
-+               * If this packet was not send here by imq_nf_queue(), then
-+               * skb_save_cb() was not used and skb_free() should not show:
-+               *   WARNING: IMQ: kfree_skb: skb->cb_next:..
-+               * and/or
-+               *   WARNING: IMQ: kfree_skb: skb->nf_queue_entry...
-+               *
-+               * However if this message is shown, then IMQ is somehow broken
-+               * and you should report this to linuximq.net.
-+               */
-+
-+              /* imq_dev_xmit is black hole that eats all packets, report that
-+               * we eat this packet happily and increase dropped counters.
-+               */
-+
-+              dev->stats.tx_dropped++;
-+              dev_kfree_skb(skb);
-+
-+              return NETDEV_TX_OK;
-+      }
-+
-+      skb_restore_cb(skb); /* restore skb->cb */
-+
-+      skb->imq_flags = 0;
-+      skb->destructor = NULL;
-+
-+      nf_reinject(entry, NF_ACCEPT);
-+
-+      return NETDEV_TX_OK;
-+}
-+
++#define IMQ_MAX_QUEUES 32
++static int numqueues = 1;
 +static u32 imq_hashrnd;
 +
 +static inline __be16 pppoe_proto(const struct sk_buff *skb)
@@ -434,9 +375,97 @@ diff -uNr linux-2.6.39/drivers/net/imq.c linux-2.6.39-imqmq/drivers/net/imq.c
 +      if (unlikely(queue_index >= dev->real_num_tx_queues))
 +              queue_index = (u16)((u32)queue_index % dev->real_num_tx_queues);
 +
++      skb_set_queue_mapping(skb, queue_index);
 +      return netdev_get_tx_queue(dev, queue_index);
 +}
 +
++static struct net_device_stats *imq_get_stats(struct net_device *dev)
++{
++      return &dev->stats;
++}
++
++/* called for packets kfree'd in qdiscs at places other than enqueue */
++static void imq_skb_destructor(struct sk_buff *skb)
++{
++      struct nf_queue_entry *entry = skb->nf_queue_entry;
++
++      skb->nf_queue_entry = NULL;
++
++      if (entry) {
++              nf_queue_entry_release_refs(entry);
++              kfree(entry);
++      }
++
++      skb_restore_cb(skb); /* kfree backup */
++}
++
++static void imq_done_check_queue_mapping(struct sk_buff *skb,
++                                       struct net_device *dev)
++{
++      unsigned int queue_index;
++
++      /* Don't let queue_mapping be left too large after exiting IMQ */
++      if (likely(skb->dev != dev && skb->dev != NULL)) {
++              queue_index = skb_get_queue_mapping(skb);
++              if (unlikely(queue_index >= skb->dev->real_num_tx_queues)) {
++                      queue_index = (u16)((u32)queue_index %
++                                              skb->dev->real_num_tx_queues);
++                      skb_set_queue_mapping(skb, queue_index);
++              }
++      } else {
++              /* skb->dev was IMQ device itself or NULL, be on safe side and
++               * just clear queue mapping.
++               */
++              skb_set_queue_mapping(skb, 0);
++      }
++}
++
++static netdev_tx_t imq_dev_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++      struct nf_queue_entry *entry = skb->nf_queue_entry;
++
++      skb->nf_queue_entry = NULL;
++      dev->trans_start = jiffies;
++
++      dev->stats.tx_bytes += skb->len;
++      dev->stats.tx_packets++;
++
++      if (unlikely(entry == NULL)) {
++              /* We don't know what is going on here.. packet is queued for
++               * imq device, but (probably) not by us.
++               *
++               * If this packet was not send here by imq_nf_queue(), then
++               * skb_save_cb() was not used and skb_free() should not show:
++               *   WARNING: IMQ: kfree_skb: skb->cb_next:..
++               * and/or
++               *   WARNING: IMQ: kfree_skb: skb->nf_queue_entry...
++               *
++               * However if this message is shown, then IMQ is somehow broken
++               * and you should report this to linuximq.net.
++               */
++
++              /* imq_dev_xmit is black hole that eats all packets, report that
++               * we eat this packet happily and increase dropped counters.
++               */
++
++              dev->stats.tx_dropped++;
++              dev_kfree_skb(skb);
++
++              return NETDEV_TX_OK;
++      }
++
++      skb_restore_cb(skb); /* restore skb->cb */
++
++      skb->imq_flags = 0;
++      skb->destructor = NULL;
++
++      imq_done_check_queue_mapping(skb, dev);
++
++      nf_reinject(entry, NF_ACCEPT);
++
++      return NETDEV_TX_OK;
++}
++
 +static int imq_nf_queue(struct nf_queue_entry *entry, unsigned queue_num)
 +{
 +      struct net_device *dev;
@@ -446,6 +475,7 @@ diff -uNr linux-2.6.39/drivers/net/imq.c linux-2.6.39-imqmq/drivers/net/imq.c
 +      spinlock_t *root_lock;
 +      int users, index;
 +      int retval = -EINVAL;
++      unsigned int orig_queue_index;
 +
 +      index = entry->skb->imq_flags & IMQ_F_IFMASK;
 +      if (unlikely(index > numdevs - 1)) {
@@ -503,10 +533,22 @@ diff -uNr linux-2.6.39/drivers/net/imq.c linux-2.6.39-imqmq/drivers/net/imq.c
 +      dev->stats.rx_bytes += skb->len;
 +      dev->stats.rx_packets++;
 +
++      if (!skb->dev) {
++              /* skb->dev == NULL causes problems, try the find cause. */
++              if (net_ratelimit()) {
++                      dev_warn(&dev->dev,
++                               "received packet with skb->dev == NULL\n");
++                      dump_stack();
++              }
++
++              skb->dev = dev;
++      }
++
 +      /* Disables softirqs for lock below */
 +      rcu_read_lock_bh();
 +
 +      /* Multi-queue selection */
++      orig_queue_index = skb_get_queue_mapping(skb);
 +      txq = imq_select_queue(dev, skb);
 +
 +      q = rcu_dereference(txq->qdisc);
@@ -551,6 +593,7 @@ diff -uNr linux-2.6.39/drivers/net/imq.c linux-2.6.39-imqmq/drivers/net/imq.c
 +      }
 +
 +packet_not_eaten_by_imq_dev:
++      skb_set_queue_mapping(skb, orig_queue_index);
 +      rcu_read_unlock_bh();
 +
 +      /* cloned? restore original */
@@ -779,10 +822,10 @@ diff -uNr linux-2.6.39/drivers/net/imq.c linux-2.6.39-imqmq/drivers/net/imq.c
 +MODULE_LICENSE("GPL");
 +MODULE_ALIAS_RTNL_LINK("imq");
 +
-diff -uNr linux-2.6.39/drivers/net/Kconfig linux-2.6.39-imqmq/drivers/net/Kconfig
---- linux-2.6.39/drivers/net/Kconfig   2011-05-19 07:06:34.000000000 +0300
-+++ linux-2.6.39-imqmq/drivers/net/Kconfig     2011-05-19 11:08:04.281864473 +0300
-@@ -124,6 +124,129 @@
+diff -uNr linux-3.0/drivers/net/Kconfig linux-3.0-imq/drivers/net/Kconfig
+--- linux-3.0/drivers/net/Kconfig      2011-07-22 05:17:23.000000000 +0300
++++ linux-3.0-imq/drivers/net/Kconfig  2011-07-26 06:31:36.176747906 +0300
+@@ -124,6 +124,125 @@
          To compile this driver as a module, choose M here: the module
          will be called eql.  If unsure, say N.
  
@@ -807,115 +850,111 @@ diff -uNr linux-2.6.39/drivers/net/Kconfig linux-2.6.39-imqmq/drivers/net/Kconfi
 +      depends on IMQ
 +      default IMQ_BEHAVIOR_AB
 +      help
++        This setting defines how IMQ behaves in respect to its
++        hooking in PREROUTING and POSTROUTING.
 +
-+              This settings defines how IMQ behaves in respect to its
-+              hooking in PREROUTING and POSTROUTING.
-+
-+              IMQ can work in any of the following ways:
++        IMQ can work in any of the following ways:
 +
-+                  PREROUTING   |      POSTROUTING
-+              -----------------|-------------------
-+              #1  After NAT    |      After NAT
-+              #2  After NAT    |      Before NAT
-+              #3  Before NAT   |      After NAT
-+              #4  Before NAT   |      Before NAT
++            PREROUTING   |      POSTROUTING
++        -----------------|-------------------
++        #1  After NAT    |      After NAT
++        #2  After NAT    |      Before NAT
++        #3  Before NAT   |      After NAT
++        #4  Before NAT   |      Before NAT
 +
-+              The default behavior is to hook before NAT on PREROUTING
-+              and after NAT on POSTROUTING (#3).
++        The default behavior is to hook before NAT on PREROUTING
++        and after NAT on POSTROUTING (#3).
 +
-+              This settings are specially usefull when trying to use IMQ
-+              to shape NATed clients.
++        This settings are specially usefull when trying to use IMQ
++        to shape NATed clients.
 +
-+              More information can be found at: www.linuximq.net
++        More information can be found at: www.linuximq.net
 +
-+              If not sure leave the default settings alone.
++        If not sure leave the default settings alone.
 +
 +config IMQ_BEHAVIOR_AA
 +      bool "IMQ AA"
 +      help
-+              This settings defines how IMQ behaves in respect to its
-+              hooking in PREROUTING and POSTROUTING.
++        This setting defines how IMQ behaves in respect to its
++        hooking in PREROUTING and POSTROUTING.
 +
-+              Choosing this option will make IMQ hook like this:
++        Choosing this option will make IMQ hook like this:
 +
-+              PREROUTING:   After NAT
-+              POSTROUTING:  After NAT
++        PREROUTING:   After NAT
++        POSTROUTING:  After NAT
 +
-+              More information can be found at: www.linuximq.net
++        More information can be found at: www.linuximq.net
 +
-+              If not sure leave the default settings alone.
++        If not sure leave the default settings alone.
 +
 +config IMQ_BEHAVIOR_AB
 +      bool "IMQ AB"
 +      help
-+              This settings defines how IMQ behaves in respect to its
-+              hooking in PREROUTING and POSTROUTING.
++        This setting defines how IMQ behaves in respect to its
++        hooking in PREROUTING and POSTROUTING.
 +
-+              Choosing this option will make IMQ hook like this:
++        Choosing this option will make IMQ hook like this:
 +
-+              PREROUTING:   After NAT
-+              POSTROUTING:  Before NAT
++        PREROUTING:   After NAT
++        POSTROUTING:  Before NAT
 +
-+              More information can be found at: www.linuximq.net
++        More information can be found at: www.linuximq.net
 +
-+              If not sure leave the default settings alone.
++        If not sure leave the default settings alone.
 +
 +config IMQ_BEHAVIOR_BA
 +      bool "IMQ BA"
 +      help
-+              This settings defines how IMQ behaves in respect to its
-+              hooking in PREROUTING and POSTROUTING.
++        This setting defines how IMQ behaves in respect to its
++        hooking in PREROUTING and POSTROUTING.
 +
-+              Choosing this option will make IMQ hook like this:
++        Choosing this option will make IMQ hook like this:
 +
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  After NAT
++        PREROUTING:   Before NAT
++        POSTROUTING:  After NAT
 +
-+              More information can be found at: www.linuximq.net
++        More information can be found at: www.linuximq.net
 +
-+              If not sure leave the default settings alone.
++        If not sure leave the default settings alone.
 +
 +config IMQ_BEHAVIOR_BB
 +      bool "IMQ BB"
 +      help
-+              This settings defines how IMQ behaves in respect to its
-+              hooking in PREROUTING and POSTROUTING.
++        This setting defines how IMQ behaves in respect to its
++        hooking in PREROUTING and POSTROUTING.
 +
-+              Choosing this option will make IMQ hook like this:
++        Choosing this option will make IMQ hook like this:
 +
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  Before NAT
++        PREROUTING:   Before NAT
++        POSTROUTING:  Before NAT
 +
-+              More information can be found at: www.linuximq.net
++        More information can be found at: www.linuximq.net
 +
-+              If not sure leave the default settings alone.
++        If not sure leave the default settings alone.
 +
 +endchoice
 +
 +config IMQ_NUM_DEVS
-+
 +      int "Number of IMQ devices"
 +      range 2 16
 +      depends on IMQ
 +      default "16"
 +      help
++        This setting defines how many IMQ devices will be created.
 +
-+              This settings defines how many IMQ devices will be
-+              created.
++        The default value is 16.
 +
-+              The default value is 16.
++        More information can be found at: www.linuximq.net
 +
-+              More information can be found at: www.linuximq.net
-+
-+              If not sure leave the default settings alone.
++        If not sure leave the default settings alone.
 +
  config TUN
        tristate "Universal TUN/TAP device driver support"
        select CRC32
-diff -uNr linux-2.6.39/drivers/net/Makefile linux-2.6.39-imqmq/drivers/net/Makefile
---- linux-2.6.39/drivers/net/Makefile  2011-05-19 07:06:34.000000000 +0300
-+++ linux-2.6.39-imqmq/drivers/net/Makefile    2011-05-19 11:08:04.281864473 +0300
-@@ -175,6 +175,7 @@
+diff -uNr linux-3.0/drivers/net/Makefile linux-3.0-imq/drivers/net/Makefile
+--- linux-3.0/drivers/net/Makefile     2011-07-22 05:17:23.000000000 +0300
++++ linux-3.0-imq/drivers/net/Makefile 2011-07-24 12:06:25.922003276 +0300
+@@ -176,6 +176,7 @@
  obj-$(CONFIG_XEN_NETDEV_BACKEND) += xen-netback/
  
  obj-$(CONFIG_DUMMY) += dummy.o
@@ -923,9 +962,9 @@ diff -uNr linux-2.6.39/drivers/net/Makefile linux-2.6.39-imqmq/drivers/net/Makef
  obj-$(CONFIG_IFB) += ifb.o
  obj-$(CONFIG_MACVLAN) += macvlan.o
  obj-$(CONFIG_MACVTAP) += macvtap.o
-diff -uNr linux-2.6.39/include/linux/imq.h linux-2.6.39-imqmq/include/linux/imq.h
---- linux-2.6.39/include/linux/imq.h   1970-01-01 02:00:00.000000000 +0200
-+++ linux-2.6.39-imqmq/include/linux/imq.h     2011-05-19 11:08:04.281864473 +0300
+diff -uNr linux-3.0/include/linux/imq.h linux-3.0-imq/include/linux/imq.h
+--- linux-3.0/include/linux/imq.h      1970-01-01 02:00:00.000000000 +0200
++++ linux-3.0-imq/include/linux/imq.h  2011-07-24 12:06:25.932003270 +0300
 @@ -0,0 +1,13 @@
 +#ifndef _IMQ_H
 +#define _IMQ_H
@@ -940,9 +979,9 @@ diff -uNr linux-2.6.39/include/linux/imq.h linux-2.6.39-imqmq/include/linux/imq.
 +
 +#endif /* _IMQ_H */
 +
-diff -uNr linux-2.6.39/include/linux/netfilter/xt_IMQ.h linux-2.6.39-imqmq/include/linux/netfilter/xt_IMQ.h
---- linux-2.6.39/include/linux/netfilter/xt_IMQ.h      1970-01-01 02:00:00.000000000 +0200
-+++ linux-2.6.39-imqmq/include/linux/netfilter/xt_IMQ.h        2011-05-19 11:08:04.281864473 +0300
+diff -uNr linux-3.0/include/linux/netfilter/xt_IMQ.h linux-3.0-imq/include/linux/netfilter/xt_IMQ.h
+--- linux-3.0/include/linux/netfilter/xt_IMQ.h 1970-01-01 02:00:00.000000000 +0200
++++ linux-3.0-imq/include/linux/netfilter/xt_IMQ.h     2011-07-24 12:06:25.932003270 +0300
 @@ -0,0 +1,9 @@
 +#ifndef _XT_IMQ_H
 +#define _XT_IMQ_H
@@ -953,10 +992,10 @@ diff -uNr linux-2.6.39/include/linux/netfilter/xt_IMQ.h linux-2.6.39-imqmq/inclu
 +
 +#endif /* _XT_IMQ_H */
 +
-diff -uNr linux-2.6.39/include/linux/netfilter.h linux-2.6.39-imqmq/include/linux/netfilter.h
---- linux-2.6.39/include/linux/netfilter.h     2011-05-19 07:06:34.000000000 +0300
-+++ linux-2.6.39-imqmq/include/linux/netfilter.h       2011-05-19 11:08:04.285197874 +0300
-@@ -21,7 +21,8 @@
+diff -uNr linux-3.0/include/linux/netfilter.h linux-3.0-imq/include/linux/netfilter.h
+--- linux-3.0/include/linux/netfilter.h        2011-07-22 05:17:23.000000000 +0300
++++ linux-3.0-imq/include/linux/netfilter.h    2011-07-24 12:06:25.955336605 +0300
+@@ -22,7 +22,8 @@
  #define NF_QUEUE 3
  #define NF_REPEAT 4
  #define NF_STOP 5
@@ -966,9 +1005,9 @@ diff -uNr linux-2.6.39/include/linux/netfilter.h linux-2.6.39-imqmq/include/linu
  
  /* we overload the higher bits for encoding auxiliary data such as the queue
   * number or errno values. Not nice, but better than additional function
-diff -uNr linux-2.6.39/include/linux/netfilter_ipv4/ipt_IMQ.h linux-2.6.39-imqmq/include/linux/netfilter_ipv4/ipt_IMQ.h
---- linux-2.6.39/include/linux/netfilter_ipv4/ipt_IMQ.h        1970-01-01 02:00:00.000000000 +0200
-+++ linux-2.6.39-imqmq/include/linux/netfilter_ipv4/ipt_IMQ.h  2011-05-19 11:08:04.285197874 +0300
+diff -uNr linux-3.0/include/linux/netfilter_ipv4/ipt_IMQ.h linux-3.0-imq/include/linux/netfilter_ipv4/ipt_IMQ.h
+--- linux-3.0/include/linux/netfilter_ipv4/ipt_IMQ.h   1970-01-01 02:00:00.000000000 +0200
++++ linux-3.0-imq/include/linux/netfilter_ipv4/ipt_IMQ.h       2011-07-24 12:06:25.955336605 +0300
 @@ -0,0 +1,10 @@
 +#ifndef _IPT_IMQ_H
 +#define _IPT_IMQ_H
@@ -980,9 +1019,9 @@ diff -uNr linux-2.6.39/include/linux/netfilter_ipv4/ipt_IMQ.h linux-2.6.39-imqmq
 +
 +#endif /* _IPT_IMQ_H */
 +
-diff -uNr linux-2.6.39/include/linux/netfilter_ipv6/ip6t_IMQ.h linux-2.6.39-imqmq/include/linux/netfilter_ipv6/ip6t_IMQ.h
---- linux-2.6.39/include/linux/netfilter_ipv6/ip6t_IMQ.h       1970-01-01 02:00:00.000000000 +0200
-+++ linux-2.6.39-imqmq/include/linux/netfilter_ipv6/ip6t_IMQ.h 2011-05-19 11:08:04.285197874 +0300
+diff -uNr linux-3.0/include/linux/netfilter_ipv6/ip6t_IMQ.h linux-3.0-imq/include/linux/netfilter_ipv6/ip6t_IMQ.h
+--- linux-3.0/include/linux/netfilter_ipv6/ip6t_IMQ.h  1970-01-01 02:00:00.000000000 +0200
++++ linux-3.0-imq/include/linux/netfilter_ipv6/ip6t_IMQ.h      2011-07-24 12:06:25.955336605 +0300
 @@ -0,0 +1,10 @@
 +#ifndef _IP6T_IMQ_H
 +#define _IP6T_IMQ_H
@@ -994,9 +1033,9 @@ diff -uNr linux-2.6.39/include/linux/netfilter_ipv6/ip6t_IMQ.h linux-2.6.39-imqm
 +
 +#endif /* _IP6T_IMQ_H */
 +
-diff -uNr linux-2.6.39/include/linux/skbuff.h linux-2.6.39-imqmq/include/linux/skbuff.h
---- linux-2.6.39/include/linux/skbuff.h        2011-05-19 07:06:34.000000000 +0300
-+++ linux-2.6.39-imqmq/include/linux/skbuff.h  2011-05-19 11:08:04.288531274 +0300
+diff -uNr linux-3.0/include/linux/skbuff.h linux-3.0-imq/include/linux/skbuff.h
+--- linux-3.0/include/linux/skbuff.h   2011-07-22 05:17:23.000000000 +0300
++++ linux-3.0-imq/include/linux/skbuff.h       2011-07-24 12:06:25.968669945 +0300
 @@ -29,6 +29,9 @@
  #include <linux/rcupdate.h>
  #include <linux/dmaengine.h>
@@ -1051,7 +1090,7 @@ diff -uNr linux-2.6.39/include/linux/skbuff.h linux-2.6.39-imqmq/include/linux/s
  extern void kfree_skb(struct sk_buff *skb);
  extern void consume_skb(struct sk_buff *skb);
  extern void          __kfree_skb(struct sk_buff *skb);
-@@ -2129,6 +2148,10 @@
+@@ -2134,6 +2153,10 @@
        dst->nfct_reasm = src->nfct_reasm;
        nf_conntrack_get_reasm(src->nfct_reasm);
  #endif
@@ -1062,9 +1101,9 @@ diff -uNr linux-2.6.39/include/linux/skbuff.h linux-2.6.39-imqmq/include/linux/s
  #ifdef CONFIG_BRIDGE_NETFILTER
        dst->nf_bridge  = src->nf_bridge;
        nf_bridge_get(src->nf_bridge);
-diff -uNr linux-2.6.39/include/net/netfilter/nf_queue.h linux-2.6.39-imqmq/include/net/netfilter/nf_queue.h
---- linux-2.6.39/include/net/netfilter/nf_queue.h      2011-05-19 07:06:34.000000000 +0300
-+++ linux-2.6.39-imqmq/include/net/netfilter/nf_queue.h        2011-05-19 11:08:04.288531274 +0300
+diff -uNr linux-3.0/include/net/netfilter/nf_queue.h linux-3.0-imq/include/net/netfilter/nf_queue.h
+--- linux-3.0/include/net/netfilter/nf_queue.h 2011-07-22 05:17:23.000000000 +0300
++++ linux-3.0-imq/include/net/netfilter/nf_queue.h     2011-07-24 12:06:25.975336612 +0300
 @@ -30,5 +30,11 @@
                                       const struct nf_queue_handler *qh);
  extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
@@ -1077,9 +1116,9 @@ diff -uNr linux-2.6.39/include/net/netfilter/nf_queue.h linux-2.6.39-imqmq/inclu
 +#endif
  
  #endif /* _NF_QUEUE_H */
-diff -uNr linux-2.6.39/net/core/dev.c linux-2.6.39-imqmq/net/core/dev.c
---- linux-2.6.39/net/core/dev.c        2011-05-19 07:06:34.000000000 +0300
-+++ linux-2.6.39-imqmq/net/core/dev.c  2011-05-19 11:08:04.288531274 +0300
+diff -uNr linux-3.0/net/core/dev.c linux-3.0-imq/net/core/dev.c
+--- linux-3.0/net/core/dev.c   2011-07-22 05:17:23.000000000 +0300
++++ linux-3.0-imq/net/core/dev.c       2011-07-26 07:52:00.513207402 +0300
 @@ -98,6 +98,9 @@
  #include <net/net_namespace.h>
  #include <net/sock.h>
@@ -1090,7 +1129,7 @@ diff -uNr linux-2.6.39/net/core/dev.c linux-2.6.39-imqmq/net/core/dev.c
  #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
  #include <linux/stat.h>
-@@ -2099,12 +2102,21 @@
+@@ -2108,7 +2111,12 @@
                if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
                        skb_dst_drop(skb);
  
@@ -1103,29 +1142,10 @@ diff -uNr linux-2.6.39/net/core/dev.c linux-2.6.39-imqmq/net/core/dev.c
                        dev_queue_xmit_nit(skb, dev);
  
                skb_orphan_try(skb);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+              features = skb->dev ? netif_skb_features(skb) : dev->features;
-+#else
-               features = netif_skb_features(skb);
-+#endif
-               if (vlan_tx_tag_present(skb) &&
-                   !(features & NETIF_F_HW_VLAN_TX)) {
-@@ -2269,8 +2281,7 @@
- #endif
- }
--static struct netdev_queue *dev_pick_tx(struct net_device *dev,
--                                      struct sk_buff *skb)
-+static struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb)
- {
-       int queue_index;
-       const struct net_device_ops *ops = dev->netdev_ops;
-diff -uNr linux-2.6.39/net/core/skbuff.c linux-2.6.39-imqmq/net/core/skbuff.c
---- linux-2.6.39/net/core/skbuff.c     2011-05-19 07:06:34.000000000 +0300
-+++ linux-2.6.39-imqmq/net/core/skbuff.c       2011-05-19 11:08:04.288531274 +0300
-@@ -72,6 +72,9 @@
+diff -uNr linux-3.0/net/core/skbuff.c linux-3.0-imq/net/core/skbuff.c
+--- linux-3.0/net/core/skbuff.c        2011-07-22 05:17:23.000000000 +0300
++++ linux-3.0-imq/net/core/skbuff.c    2011-07-24 12:06:26.008669943 +0300
+@@ -73,6 +73,9 @@
  
  static struct kmem_cache *skbuff_head_cache __read_mostly;
  static struct kmem_cache *skbuff_fclone_cache __read_mostly;
@@ -1135,7 +1155,7 @@ diff -uNr linux-2.6.39/net/core/skbuff.c linux-2.6.39-imqmq/net/core/skbuff.c
  
  static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
                                  struct pipe_buffer *buf)
-@@ -91,6 +94,82 @@
+@@ -92,6 +95,82 @@
        return 1;
  }
  
@@ -1218,7 +1238,7 @@ diff -uNr linux-2.6.39/net/core/skbuff.c linux-2.6.39-imqmq/net/core/skbuff.c
  
  /* Pipe buffer operations for a socket. */
  static const struct pipe_buf_operations sock_pipe_buf_ops = {
-@@ -379,6 +458,26 @@
+@@ -380,6 +459,26 @@
                WARN_ON(in_irq());
                skb->destructor(skb);
        }
@@ -1245,7 +1265,7 @@ diff -uNr linux-2.6.39/net/core/skbuff.c linux-2.6.39-imqmq/net/core/skbuff.c
  #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
        nf_conntrack_put(skb->nfct);
  #endif
-@@ -517,6 +616,9 @@
+@@ -518,6 +617,9 @@
        new->sp                 = secpath_get(old->sp);
  #endif
        memcpy(new->cb, old->cb, sizeof(old->cb));
@@ -1255,7 +1275,7 @@ diff -uNr linux-2.6.39/net/core/skbuff.c linux-2.6.39-imqmq/net/core/skbuff.c
        new->csum               = old->csum;
        new->local_df           = old->local_df;
        new->pkt_type           = old->pkt_type;
-@@ -2780,6 +2882,13 @@
+@@ -2781,6 +2883,13 @@
                                                0,
                                                SLAB_HWCACHE_ALIGN|SLAB_PANIC,
                                                NULL);
@@ -1269,33 +1289,51 @@ diff -uNr linux-2.6.39/net/core/skbuff.c linux-2.6.39-imqmq/net/core/skbuff.c
  }
  
  /**
-diff -uNr linux-2.6.39/net/netfilter/core.c linux-2.6.39-imqmq/net/netfilter/core.c
---- linux-2.6.39/net/netfilter/core.c  2011-05-19 07:06:34.000000000 +0300
-+++ linux-2.6.39-imqmq/net/netfilter/core.c    2011-05-19 11:13:19.891558119 +0300
-@@ -191,6 +191,20 @@
-                       kfree_skb(skb);
-               }
-               ret = 0;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      } else if ((verdict & NF_VERDICT_MASK) == NF_IMQ_QUEUE) {
-+              ret = nf_imq_queue(skb, elem, pf, hook, indev, outdev, okfn,
-+                             verdict >> NF_VERDICT_QBITS);
-+              if (ret < 0) {
-+                      if (ret == -ECANCELED)
-+                              goto next_hook;
-+                      if (ret == -ESRCH &&
-+                         (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
-+                              goto next_hook;
-+                      kfree_skb(skb);
-+              }
-+              ret = 0;
-+#endif
+diff -uNr linux-3.0/net/ipv6/ip6_output.c linux-3.0-imq/net/ipv6/ip6_output.c
+--- linux-3.0/net/ipv6/ip6_output.c    2011-07-22 05:17:23.000000000 +0300
++++ linux-3.0-imq/net/ipv6/ip6_output.c        2011-07-24 16:46:04.789482257 +0300
+@@ -101,9 +101,6 @@
+       struct dst_entry *dst = skb_dst(skb);
+       struct net_device *dev = dst->dev;
+-      skb->protocol = htons(ETH_P_IPV6);
+-      skb->dev = dev;
+-
+       if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {
+               struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
+@@ -165,6 +162,11 @@
+               return 0;
        }
-       rcu_read_unlock();
-       return ret;
-diff -uNr linux-2.6.39/net/netfilter/Kconfig linux-2.6.39-imqmq/net/netfilter/Kconfig
---- linux-2.6.39/net/netfilter/Kconfig 2011-05-19 07:06:34.000000000 +0300
-+++ linux-2.6.39-imqmq/net/netfilter/Kconfig   2011-05-19 11:08:04.288531274 +0300
++      /* IMQ-patch: moved setting skb->dev and skb->protocol from
++       * ip6_finish_output2 to fix crashing at netif_skb_features(). */
++      skb->protocol = htons(ETH_P_IPV6);
++      skb->dev = dev;
++
+       return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, dev,
+                           ip6_finish_output,
+                           !(IP6CB(skb)->flags & IP6SKB_REROUTED));
+diff -uNr linux-3.0/net/netfilter/core.c linux-3.0-imq/net/netfilter/core.c
+--- linux-3.0/net/netfilter/core.c     2011-07-22 05:17:23.000000000 +0300
++++ linux-3.0-imq/net/netfilter/core.c 2011-07-24 12:53:52.972141108 +0300
+@@ -179,9 +179,11 @@
+               ret = NF_DROP_GETERR(verdict);
+               if (ret == 0)
+                       ret = -EPERM;
+-      } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
++      } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE ||
++                 (verdict & NF_VERDICT_MASK) == NF_IMQ_QUEUE) {
+               ret = nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
+-                             verdict >> NF_VERDICT_QBITS);
++                             verdict >> NF_VERDICT_QBITS,
++                             verdict & NF_VERDICT_MASK);
+               if (ret < 0) {
+                       if (ret == -ECANCELED)
+                               goto next_hook;
+diff -uNr linux-3.0/net/netfilter/Kconfig linux-3.0-imq/net/netfilter/Kconfig
+--- linux-3.0/net/netfilter/Kconfig    2011-07-22 05:17:23.000000000 +0300
++++ linux-3.0-imq/net/netfilter/Kconfig        2011-07-24 12:06:26.035336611 +0300
 @@ -507,6 +507,18 @@
          For more information on the LEDs available on your system, see
          Documentation/leds-class.txt
@@ -1315,9 +1353,9 @@ diff -uNr linux-2.6.39/net/netfilter/Kconfig linux-2.6.39-imqmq/net/netfilter/Kc
  config NETFILTER_XT_TARGET_MARK
        tristate '"MARK" target support'
        depends on NETFILTER_ADVANCED
-diff -uNr linux-2.6.39/net/netfilter/Makefile linux-2.6.39-imqmq/net/netfilter/Makefile
---- linux-2.6.39/net/netfilter/Makefile        2011-05-19 07:06:34.000000000 +0300
-+++ linux-2.6.39-imqmq/net/netfilter/Makefile  2011-05-19 11:08:04.291864674 +0300
+diff -uNr linux-3.0/net/netfilter/Makefile linux-3.0-imq/net/netfilter/Makefile
+--- linux-3.0/net/netfilter/Makefile   2011-07-22 05:17:23.000000000 +0300
++++ linux-3.0-imq/net/netfilter/Makefile       2011-07-24 12:06:26.042003277 +0300
 @@ -56,6 +56,7 @@
  obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
  obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
@@ -1326,28 +1364,21 @@ diff -uNr linux-2.6.39/net/netfilter/Makefile linux-2.6.39-imqmq/net/netfilter/M
  obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
  obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
  obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
-diff -uNr linux-2.6.39/net/netfilter/nf_internals.h linux-2.6.39-imqmq/net/netfilter/nf_internals.h
---- linux-2.6.39/net/netfilter/nf_internals.h  2011-05-19 07:06:34.000000000 +0300
-+++ linux-2.6.39-imqmq/net/netfilter/nf_internals.h    2011-05-19 11:08:04.291864674 +0300
-@@ -30,6 +30,15 @@
+diff -uNr linux-3.0/net/netfilter/nf_internals.h linux-3.0-imq/net/netfilter/nf_internals.h
+--- linux-3.0/net/netfilter/nf_internals.h     2011-07-22 05:17:23.000000000 +0300
++++ linux-3.0-imq/net/netfilter/nf_internals.h 2011-07-24 12:54:17.615475634 +0300
+@@ -29,7 +29,7 @@
+                   struct net_device *indev,
                    struct net_device *outdev,
                    int (*okfn)(struct sk_buff *),
-                   unsigned int queuenum);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern int nf_imq_queue(struct sk_buff *skb,
-+                  struct list_head *elem,
-+                  u_int8_t pf, unsigned int hook,
-+                  struct net_device *indev,
-+                  struct net_device *outdev,
-+                  int (*okfn)(struct sk_buff *),
-+                  unsigned int queuenum);
-+#endif
+-                  unsigned int queuenum);
++                  unsigned int queuenum, unsigned int queuetype);
  extern int __init netfilter_queue_init(void);
  
  /* nf_log.c */
-diff -uNr linux-2.6.39/net/netfilter/nf_queue.c linux-2.6.39-imqmq/net/netfilter/nf_queue.c
---- linux-2.6.39/net/netfilter/nf_queue.c      2011-05-19 07:06:34.000000000 +0300
-+++ linux-2.6.39-imqmq/net/netfilter/nf_queue.c        2011-05-19 11:22:38.189467462 +0300
+diff -uNr linux-3.0/net/netfilter/nf_queue.c linux-3.0-imq/net/netfilter/nf_queue.c
+--- linux-3.0/net/netfilter/nf_queue.c 2011-07-22 05:17:23.000000000 +0300
++++ linux-3.0-imq/net/netfilter/nf_queue.c     2011-07-24 13:05:00.682173434 +0300
 @@ -22,6 +22,26 @@
  
  static DEFINE_MUTEX(queue_handler_mutex);
@@ -1398,133 +1429,73 @@ diff -uNr linux-2.6.39/net/netfilter/nf_queue.c linux-2.6.39-imqmq/net/netfilter
                      int (*okfn)(struct sk_buff *),
 -                    unsigned int queuenum)
 +                    unsigned int queuenum,
-+                    bool imq_queue)
++                    unsigned int queuetype)
  {
        int status = -ENOENT;
        struct nf_queue_entry *entry = NULL;
-@@ -137,7 +159,14 @@
+@@ -137,7 +159,17 @@
        /* QUEUE == DROP if no one is waiting, to be safe. */
        rcu_read_lock();
  
 -      qh = rcu_dereference(queue_handler[pf]);
++      if (queuetype == NF_IMQ_QUEUE) {
 +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      if (imq_queue)
 +              qh = rcu_dereference(queue_imq_handler);
-+      else
-+              qh = rcu_dereference(queue_handler[pf]);
 +#else
-+      qh = rcu_dereference(queue_handler[pf]);
++              BUG();
++              goto err_unlock;
 +#endif
++      } else {
++              qh = rcu_dereference(queue_handler[pf]);
++      }
++
        if (!qh) {
                status = -ESRCH;
                goto err_unlock;
-@@ -203,13 +232,14 @@
-       return status;
- }
--int nf_queue(struct sk_buff *skb,
--           struct list_head *elem,
--           u_int8_t pf, unsigned int hook,
--           struct net_device *indev,
--           struct net_device *outdev,
--           int (*okfn)(struct sk_buff *),
+@@ -209,7 +241,8 @@
+            struct net_device *indev,
+            struct net_device *outdev,
+            int (*okfn)(struct sk_buff *),
 -           unsigned int queuenum)
-+static int _nf_queue(struct sk_buff *skb,
-+                   struct list_head *elem,
-+                   u_int8_t pf, unsigned int hook,
-+                   struct net_device *indev,
-+                   struct net_device *outdev,
-+                   int (*okfn)(struct sk_buff *),
-+                   unsigned int queuenum,
-+                   bool imq_queue)
++           unsigned int queuenum,
++           unsigned int queuetype)
  {
        struct sk_buff *segs;
        int err;
-@@ -217,7 +247,7 @@
+@@ -217,7 +250,7 @@
  
        if (!skb_is_gso(skb))
                return __nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
 -                                queuenum);
-+                                queuenum, imq_queue);
++                                queuenum, queuetype);
  
        switch (pf) {
        case NFPROTO_IPV4:
-@@ -244,7 +274,7 @@
+@@ -244,7 +277,7 @@
                segs->next = NULL;
                if (err == 0)
                        err = __nf_queue(segs, elem, pf, hook, indev,
 -                                         outdev, okfn, queuenum);
-+                                       outdev, okfn, queuenum, imq_queue);
++                                       outdev, okfn, queuenum, queuetype);
                if (err == 0)
                        queued++;
                else
-@@ -260,6 +290,32 @@
-       return err;
- }
-+int nf_queue(struct sk_buff *skb,
-+           struct list_head *elem,
-+           u_int8_t pf, unsigned int hook,
-+           struct net_device *indev,
-+           struct net_device *outdev,
-+           int (*okfn)(struct sk_buff *),
-+           unsigned int queuenum)
-+{
-+      return _nf_queue(skb, elem, pf, hook, indev, outdev, okfn, queuenum,
-+                       false);
-+}
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+int nf_imq_queue(struct sk_buff *skb,
-+           struct list_head *elem,
-+           u_int8_t pf, unsigned int hook,
-+           struct net_device *indev,
-+           struct net_device *outdev,
-+           int (*okfn)(struct sk_buff *),
-+           unsigned int queuenum)
-+{
-+      return _nf_queue(skb, elem, pf, hook, indev, outdev, okfn, queuenum,
-+                       true);
-+}
-+#endif
-+
- void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
- {
-       struct sk_buff *skb = entry->skb;
-@@ -301,7 +357,7 @@
+@@ -299,9 +332,11 @@
+               local_bh_enable();
+               break;
        case NF_QUEUE:
++      case NF_IMQ_QUEUE:
                err = __nf_queue(skb, elem, entry->pf, entry->hook,
                                 entry->indev, entry->outdev, entry->okfn,
 -                               verdict >> NF_VERDICT_QBITS);
-+                               verdict >> NF_VERDICT_QBITS, false);
++                               verdict >> NF_VERDICT_QBITS,
++                               verdict & NF_VERDICT_MASK);
                if (err < 0) {
                        if (err == -ECANCELED)
                                goto next_hook;
-@@ -311,6 +367,21 @@
-                       kfree_skb(skb);
-               }
-               break;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      case NF_IMQ_QUEUE:
-+              err = __nf_queue(skb, elem, entry->pf, entry->hook,
-+                               entry->indev, entry->outdev, entry->okfn,
-+                               verdict >> NF_VERDICT_QBITS, true);
-+              if (err < 0) {
-+                      if (err == -ECANCELED)
-+                              goto next_hook;
-+                      if (err == -ESRCH &&
-+                         (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
-+                              goto next_hook;
-+                      kfree_skb(skb);
-+              }
-+              break;
-+#endif
-       case NF_STOLEN:
-       default:
-               kfree_skb(skb);
-diff -uNr linux-2.6.39/net/netfilter/xt_IMQ.c linux-2.6.39-imqmq/net/netfilter/xt_IMQ.c
---- linux-2.6.39/net/netfilter/xt_IMQ.c        1970-01-01 02:00:00.000000000 +0200
-+++ linux-2.6.39-imqmq/net/netfilter/xt_IMQ.c  2011-05-19 11:08:04.308531677 +0300
+diff -uNr linux-3.0/net/netfilter/xt_IMQ.c linux-3.0-imq/net/netfilter/xt_IMQ.c
+--- linux-3.0/net/netfilter/xt_IMQ.c   1970-01-01 02:00:00.000000000 +0200
++++ linux-3.0-imq/net/netfilter/xt_IMQ.c       2011-07-24 12:06:26.062003279 +0300
 @@ -0,0 +1,74 @@
 +/*
 + * This target marks packets to be enqueued to an imq device
This page took 0.115401 seconds and 4 git commands to generate.