kernel: remove imq support, refresh patches
authornbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Mon, 21 Feb 2011 02:06:51 +0000 (02:06 +0000)
committernbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Mon, 21 Feb 2011 02:06:51 +0000 (02:06 +0000)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@25641 3c298f89-4303-0410-b956-a3cf2f4a3e73

156 files changed:
include/netfilter.mk
package/kernel/modules/netfilter.mk
target/linux/ar71xx/Makefile
target/linux/ar71xx/patches-2.6.36/003-ar71xx_usb_host.patch
target/linux/ar71xx/patches-2.6.36/005-ar71xx_mac_driver.patch
target/linux/ar71xx/patches-2.6.36/102-mtd_m25p80_add_myloader_parser.patch
target/linux/ar71xx/patches-2.6.36/104-mtd_m25p80_add_redboot_parser.patch
target/linux/ar71xx/patches-2.6.36/107-mtd-SST39VF6401B-support.patch
target/linux/ar71xx/patches-2.6.36/108-mtd_fix_cfi_cmdset_0002_status_check.patch
target/linux/ar71xx/patches-2.6.36/109-mtd-wrt160nl-trx-parser.patch
target/linux/ar71xx/patches-2.6.36/110-usb-ehci-add-war-for-synopsys-hc-bug.patch
target/linux/ar71xx/patches-2.6.36/111-mtd-cfi_cmdset_0002-force-word-write.patch
target/linux/ar71xx/patches-2.6.36/400-2.6.35-fix-nand_scan_ident-options.patch
target/linux/ar71xx/patches-2.6.37/001-ar71xx_core.patch
target/linux/ar71xx/patches-2.6.37/003-ar71xx_usb_host.patch
target/linux/ar71xx/patches-2.6.37/005-ar71xx_mac_driver.patch
target/linux/ar71xx/patches-2.6.37/006-ar71xx_wdt_driver.patch
target/linux/ar71xx/patches-2.6.37/102-mtd_m25p80_add_myloader_parser.patch
target/linux/ar71xx/patches-2.6.37/104-mtd_m25p80_add_redboot_parser.patch
target/linux/ar71xx/patches-2.6.37/107-mtd-SST39VF6401B-support.patch
target/linux/ar71xx/patches-2.6.37/108-mtd_fix_cfi_cmdset_0002_status_check.patch
target/linux/ar71xx/patches-2.6.37/109-mtd-wrt160nl-trx-parser.patch
target/linux/ar71xx/patches-2.6.37/110-usb-ehci-add-war-for-synopsys-hc-bug.patch
target/linux/ar71xx/patches-2.6.37/111-mtd-cfi_cmdset_0002-force-word-write.patch
target/linux/ar71xx/patches-2.6.37/205-wndr3700-usb-led-driver.patch
target/linux/ar71xx/patches-2.6.37/207-rb750-led-driver.patch
target/linux/ar71xx/patches-2.6.37/300-mips_fw_myloader.patch
target/linux/ar71xx/patches-2.6.37/400-2.6.35-fix-nand_scan_ident-options.patch
target/linux/ar71xx/patches-2.6.37/901-get_c0_compare_irq_function.patch
target/linux/generic/config-2.6.30
target/linux/generic/config-2.6.31
target/linux/generic/config-2.6.32
target/linux/generic/config-2.6.34
target/linux/generic/config-2.6.35
target/linux/generic/config-2.6.36
target/linux/generic/config-2.6.37
target/linux/generic/config-2.6.38
target/linux/generic/patches-2.6.30/150-netfilter_imq.patch [deleted file]
target/linux/generic/patches-2.6.30/180-netfilter_depends.patch
target/linux/generic/patches-2.6.30/205-skb_padding.patch
target/linux/generic/patches-2.6.30/601-phy-add-aneg-done-function.patch
target/linux/generic/patches-2.6.30/680-phy_ar8216.patch
target/linux/generic/patches-2.6.30/690-phy_rtl8306.patch
target/linux/generic/patches-2.6.30/691-phy_rtl8366.patch
target/linux/generic/patches-2.6.30/940-wireless_mesh_header.patch
target/linux/generic/patches-2.6.30/971-ocf_20100325.patch
target/linux/generic/patches-2.6.31/150-netfilter_imq.patch [deleted file]
target/linux/generic/patches-2.6.32/014-cfi_fix_amd_extended_table_check.patch
target/linux/generic/patches-2.6.32/020-mips_multi_machine_support.patch
target/linux/generic/patches-2.6.32/040-arm-update-mach-types.patch
target/linux/generic/patches-2.6.32/100-netfilter_layer7_2.21.patch
target/linux/generic/patches-2.6.32/110-netfilter_match_speedup.patch
target/linux/generic/patches-2.6.32/150-netfilter_imq.patch [deleted file]
target/linux/generic/patches-2.6.32/180-netfilter_depends.patch
target/linux/generic/patches-2.6.32/202-mips_mem_functions_performance.patch
target/linux/generic/patches-2.6.32/203-slab_maxsize.patch
target/linux/generic/patches-2.6.32/205-skb_padding.patch
target/linux/generic/patches-2.6.32/210-mini_fo_2.6.25_fixes.patch
target/linux/generic/patches-2.6.32/212-mini_fo_2.6.26_fixes.patch
target/linux/generic/patches-2.6.32/223-kobject-add-broadcast_uevent.patch
target/linux/generic/patches-2.6.32/400-ledtrig_morse.patch
target/linux/generic/patches-2.6.32/402-ledtrig_netdev.patch
target/linux/generic/patches-2.6.32/511-yaffs-cvs-2009-04-24.patch
target/linux/generic/patches-2.6.32/903-hostap_txpower.patch
target/linux/generic/patches-2.6.32/930-kmsg_dump_backport.patch
target/linux/generic/patches-2.6.32/971-ocf_20100325.patch
target/linux/generic/patches-2.6.32/975-ssb_update.patch
target/linux/generic/patches-2.6.32/998-openwrt_lzma_options.patch
target/linux/generic/patches-2.6.34/014-cfi_fix_amd_extended_table_check.patch
target/linux/generic/patches-2.6.34/020-mips_multi_machine_support.patch
target/linux/generic/patches-2.6.34/100-netfilter_layer7_2.21.patch
target/linux/generic/patches-2.6.34/110-netfilter_match_speedup.patch
target/linux/generic/patches-2.6.34/150-netfilter_imq.patch [deleted file]
target/linux/generic/patches-2.6.34/180-netfilter_depends.patch
target/linux/generic/patches-2.6.34/202-mips_mem_functions_performance.patch
target/linux/generic/patches-2.6.34/203-slab_maxsize.patch
target/linux/generic/patches-2.6.34/205-skb_padding.patch
target/linux/generic/patches-2.6.34/210-mini_fo_2.6.25_fixes.patch
target/linux/generic/patches-2.6.34/212-mini_fo_2.6.26_fixes.patch
target/linux/generic/patches-2.6.34/223-kobject-add-broadcast_uevent.patch
target/linux/generic/patches-2.6.34/280-sched_act_connmark.patch
target/linux/generic/patches-2.6.34/400-ledtrig_morse.patch
target/linux/generic/patches-2.6.34/402-ledtrig_netdev.patch
target/linux/generic/patches-2.6.34/511-yaffs-cvs-2009-04-24.patch
target/linux/generic/patches-2.6.34/903-hostap_txpower.patch
target/linux/generic/patches-2.6.34/971-ocf_20100325.patch
target/linux/generic/patches-2.6.34/975-ssb_update.patch
target/linux/generic/patches-2.6.34/998-openwrt_lzma_options.patch
target/linux/generic/patches-2.6.35/014-cfi_fix_amd_extended_table_check.patch
target/linux/generic/patches-2.6.35/020-mips_multi_machine_support.patch
target/linux/generic/patches-2.6.35/040-arm-update-mach-types.patch
target/linux/generic/patches-2.6.35/065-rootfs_split.patch
target/linux/generic/patches-2.6.35/100-netfilter_layer7_2.21.patch
target/linux/generic/patches-2.6.35/110-netfilter_match_speedup.patch
target/linux/generic/patches-2.6.35/150-netfilter_imq.patch [deleted file]
target/linux/generic/patches-2.6.35/180-netfilter_depends.patch
target/linux/generic/patches-2.6.35/202-mips_mem_functions_performance.patch
target/linux/generic/patches-2.6.35/203-slab_maxsize.patch
target/linux/generic/patches-2.6.35/210-mini_fo_2.6.25_fixes.patch
target/linux/generic/patches-2.6.35/212-mini_fo_2.6.26_fixes.patch
target/linux/generic/patches-2.6.35/223-kobject-add-broadcast_uevent.patch
target/linux/generic/patches-2.6.35/290-sched_act_connmark.patch
target/linux/generic/patches-2.6.35/400-ledtrig_morse.patch
target/linux/generic/patches-2.6.35/402-ledtrig_netdev.patch
target/linux/generic/patches-2.6.35/511-yaffs-cvs-2009-04-24.patch
target/linux/generic/patches-2.6.35/903-hostap_txpower.patch
target/linux/generic/patches-2.6.35/971-ocf_20100325.patch
target/linux/generic/patches-2.6.35/975-ssb_update.patch
target/linux/generic/patches-2.6.35/998-openwrt_lzma_options.patch
target/linux/generic/patches-2.6.36/014-cfi_show_amd_extended_table_version.patch
target/linux/generic/patches-2.6.36/020-mips_multi_machine_support.patch
target/linux/generic/patches-2.6.36/040-arm-update-mach-types.patch
target/linux/generic/patches-2.6.36/065-rootfs_split.patch
target/linux/generic/patches-2.6.36/089-mtd-samsung-flash.patch
target/linux/generic/patches-2.6.36/100-netfilter_layer7_2.22.patch
target/linux/generic/patches-2.6.36/110-netfilter_match_speedup.patch
target/linux/generic/patches-2.6.36/150-netfilter_imq.patch [deleted file]
target/linux/generic/patches-2.6.36/180-netfilter_depends.patch
target/linux/generic/patches-2.6.36/202-mips_mem_functions_performance.patch
target/linux/generic/patches-2.6.36/203-slab_maxsize.patch
target/linux/generic/patches-2.6.36/210-mini_fo_2.6.25_fixes.patch
target/linux/generic/patches-2.6.36/212-mini_fo_2.6.26_fixes.patch
target/linux/generic/patches-2.6.36/223-kobject-add-broadcast_uevent.patch
target/linux/generic/patches-2.6.36/290-sched_act_connmark.patch
target/linux/generic/patches-2.6.36/400-ledtrig_morse.patch
target/linux/generic/patches-2.6.36/402-ledtrig_netdev.patch
target/linux/generic/patches-2.6.36/411-gpio_ioctl.patch
target/linux/generic/patches-2.6.36/511-yaffs-cvs-2009-04-24.patch
target/linux/generic/patches-2.6.36/511-yaffs-git-2010-10-20.patch
target/linux/generic/patches-2.6.36/903-hostap_txpower.patch
target/linux/generic/patches-2.6.36/971-ocf_20100325.patch
target/linux/generic/patches-2.6.36/990-arm_export_dma_set_coherent_mask.patch
target/linux/generic/patches-2.6.36/998-openwrt_lzma_options.patch
target/linux/generic/patches-2.6.37/014-cfi_show_amd_extended_table_version.patch
target/linux/generic/patches-2.6.37/020-mips_multi_machine_support.patch
target/linux/generic/patches-2.6.37/040-arm-update-mach-types.patch
target/linux/generic/patches-2.6.37/065-rootfs_split.patch
target/linux/generic/patches-2.6.37/089-mtd-samsung-flash.patch
target/linux/generic/patches-2.6.37/100-netfilter_layer7_2.22.patch
target/linux/generic/patches-2.6.37/150-netfilter_imq.patch [deleted file]
target/linux/generic/patches-2.6.37/180-netfilter_depends.patch
target/linux/generic/patches-2.6.37/202-mips_mem_functions_performance.patch
target/linux/generic/patches-2.6.37/203-slab_maxsize.patch
target/linux/generic/patches-2.6.37/210-mini_fo_2.6.25_fixes.patch
target/linux/generic/patches-2.6.37/212-mini_fo_2.6.26_fixes.patch
target/linux/generic/patches-2.6.37/223-kobject-add-broadcast_uevent.patch
target/linux/generic/patches-2.6.37/290-sched_act_connmark.patch
target/linux/generic/patches-2.6.37/400-ledtrig_morse.patch
target/linux/generic/patches-2.6.37/402-ledtrig_netdev.patch
target/linux/generic/patches-2.6.37/411-gpio_ioctl.patch
target/linux/generic/patches-2.6.37/511-yaffs-cvs-2009-04-24.patch
target/linux/generic/patches-2.6.37/511-yaffs-git-2010-10-20.patch
target/linux/generic/patches-2.6.37/903-hostap_txpower.patch
target/linux/generic/patches-2.6.37/971-ocf_20100325.patch
target/linux/generic/patches-2.6.37/998-openwrt_lzma_options.patch
target/linux/generic/patches-2.6.38/150-netfilter_imq.patch [deleted file]

index 3f892bb..424cf55 100644 (file)
@@ -107,12 +107,6 @@ $(eval $(call nf_add,IPT_FILTER,CONFIG_IP_NF_MATCH_STRING, $(P_V4)ipt_string))
 $(eval $(call nf_add,IPT_FILTER,CONFIG_NETFILTER_XT_MATCH_STRING, $(P_XT)xt_string))
 
 
 $(eval $(call nf_add,IPT_FILTER,CONFIG_NETFILTER_XT_MATCH_STRING, $(P_XT)xt_string))
 
 
-# imq
-
-$(eval $(call nf_add,IPT_IMQ,CONFIG_IP_NF_TARGET_IMQ, $(P_V4)ipt_IMQ))
-$(eval $(call nf_add,IPT_IMQ,CONFIG_NETFILTER_XT_TARGET_IMQ, $(P_XT)xt_IMQ))
-
-
 # ipopt
 
 $(eval $(call nf_add,IPT_IPOPT,CONFIG_IP_NF_TARGET_DSCP, $(P_V4)ipt_DSCP))
 # ipopt
 
 $(eval $(call nf_add,IPT_IPOPT,CONFIG_IP_NF_TARGET_DSCP, $(P_V4)ipt_DSCP))
@@ -200,7 +194,6 @@ $(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_MATCH_OWNER, $(P_V6)ip6t_owner))
 $(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_MATCH_OPTS, $(P_V6)ip6t_hbh))
 $(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_MATCH_RT, $(P_V6)ip6t_rt))
 
 $(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_MATCH_OPTS, $(P_V6)ip6t_hbh))
 $(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_MATCH_RT, $(P_V6)ip6t_rt))
 
-$(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_TARGET_IMQ, $(P_V6)ip6t_IMQ))
 $(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_TARGET_LOG, $(P_V6)ip6t_LOG))
 $(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_TARGET_REJECT, $(P_V6)ip6t_REJECT))
 $(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_TARGET_ROUTE, $(P_V6)ip6t_ROUTE))
 $(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_TARGET_LOG, $(P_V6)ip6t_LOG))
 $(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_TARGET_REJECT, $(P_V6)ip6t_REJECT))
 $(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_TARGET_ROUTE, $(P_V6)ip6t_ROUTE))
@@ -331,7 +324,6 @@ IPT_BUILTIN += $(IPT_CONNTRACK-y)
 IPT_BUILTIN += $(IPT_CONNTRACK_EXTRA-y)
 IPT_BUILTIN += $(IPT_EXTRA-y)
 IPT_BUILTIN += $(IPT_FILTER-y)
 IPT_BUILTIN += $(IPT_CONNTRACK_EXTRA-y)
 IPT_BUILTIN += $(IPT_EXTRA-y)
 IPT_BUILTIN += $(IPT_FILTER-y)
-IPT_BUILTIN += $(IPT_IMQ-y)
 IPT_BUILTIN += $(IPT_IPOPT-y)
 IPT_BUILTIN += $(IPT_IPRANGE-y)
 IPT_BUILTIN += $(IPT_IPSEC-y)
 IPT_BUILTIN += $(IPT_IPOPT-y)
 IPT_BUILTIN += $(IPT_IPRANGE-y)
 IPT_BUILTIN += $(IPT_IPSEC-y)
index e2361af..2393d70 100644 (file)
@@ -228,30 +228,6 @@ endef
 $(eval $(call KernelPackage,ipt-nathelper-extra))
 
 
 $(eval $(call KernelPackage,ipt-nathelper-extra))
 
 
-define KernelPackage/ipt-imq
-  TITLE:=Intermediate Queueing support
-  KCONFIG:= \
-       CONFIG_IMQ \
-       CONFIG_IMQ_BEHAVIOR_BA=y \
-       CONFIG_IMQ_NUM_DEVS=2 \
-       CONFIG_NETFILTER_XT_TARGET_IMQ
-  FILES:= \
-       $(LINUX_DIR)/drivers/net/imq.ko \
-       $(foreach mod,$(IPT_IMQ-m),$(LINUX_DIR)/net/$(mod).ko)
-  AUTOLOAD:=$(call AutoLoad,46,$(notdir \
-       imq \
-       $(IPT_IMQ-m) \
-  ))
-  $(call AddDepends/ipt)
-endef
-
-define KernelPackage/ipt-imq/description
- Kernel support for Intermediate Queueing devices
-endef
-
-$(eval $(call KernelPackage,ipt-imq))
-
-
 define KernelPackage/ipt-queue
   TITLE:=Module for user-space packet queueing
   KCONFIG:=$(KCONFIG_IPT_QUEUE)
 define KernelPackage/ipt-queue
   TITLE:=Module for user-space packet queueing
   KCONFIG:=$(KCONFIG_IPT_QUEUE)
index b05ad6d..b0b096a 100644 (file)
@@ -13,7 +13,7 @@ FEATURES:=squashfs jffs2 targz
 CFLAGS:=-Os -pipe -mips32r2 -mtune=mips32r2 -funit-at-a-time
 SUBTARGETS:=generic nand
 
 CFLAGS:=-Os -pipe -mips32r2 -mtune=mips32r2 -funit-at-a-time
 SUBTARGETS:=generic nand
 
-LINUX_VERSION:=2.6.32.29
+LINUX_VERSION:=2.6.37.1
 
 include $(INCLUDE_DIR)/target.mk
 
 
 include $(INCLUDE_DIR)/target.mk
 
index 9fea1b4..a75ed52 100644 (file)
@@ -30,7 +30,7 @@
        depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
 --- a/drivers/usb/host/ehci-hcd.c
 +++ b/drivers/usb/host/ehci-hcd.c
        depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
 --- a/drivers/usb/host/ehci-hcd.c
 +++ b/drivers/usb/host/ehci-hcd.c
-@@ -1197,6 +1197,11 @@ MODULE_LICENSE ("GPL");
+@@ -1210,6 +1210,11 @@ MODULE_LICENSE ("GPL");
  #define       PLATFORM_DRIVER         ehci_atmel_driver
  #endif
  
  #define       PLATFORM_DRIVER         ehci_atmel_driver
  #endif
  
index 1f27e84..01b7a2e 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/Kconfig
 +++ b/drivers/net/Kconfig
 --- a/drivers/net/Kconfig
 +++ b/drivers/net/Kconfig
-@@ -2168,6 +2168,8 @@ config ACENIC_OMIT_TIGON_I
+@@ -2045,6 +2045,8 @@ config ACENIC_OMIT_TIGON_I
  
          The safe and default value for this is N.
  
  
          The safe and default value for this is N.
  
index dcf7a6d..fb4eed4 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
-@@ -933,6 +933,16 @@ static int __devinit m25p_probe(struct s
+@@ -929,6 +929,16 @@ static int __devinit m25p_probe(struct s
                                        part_probes, &parts, 0);
                }
  
                                        part_probes, &parts, 0);
                }
  
index bb0ff7d..643b2df 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
-@@ -943,6 +943,15 @@ static int __devinit m25p_probe(struct s
+@@ -939,6 +939,15 @@ static int __devinit m25p_probe(struct s
                }
  #endif
  
                }
  #endif
  
index 246abd5..0c3814c 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/chips/jedec_probe.c
 +++ b/drivers/mtd/chips/jedec_probe.c
 --- a/drivers/mtd/chips/jedec_probe.c
 +++ b/drivers/mtd/chips/jedec_probe.c
-@@ -148,6 +148,7 @@
+@@ -149,6 +149,7 @@
  #define SST39LF160    0x2782
  #define SST39VF1601   0x234b
  #define SST39VF3201   0x235b
  #define SST39LF160    0x2782
  #define SST39VF1601   0x234b
  #define SST39VF3201   0x235b
@@ -8,7 +8,7 @@
  #define SST39WF1601   0x274b
  #define SST39WF1602   0x274a
  #define SST39LF512    0x00D4
  #define SST39WF1601   0x274b
  #define SST39WF1602   0x274a
  #define SST39LF512    0x00D4
-@@ -1568,6 +1569,18 @@ static const struct amd_flash_info jedec
+@@ -1582,6 +1583,18 @@ static const struct amd_flash_info jedec
                        ERASEINFO(0x10000,64),
                }
        }, {
                        ERASEINFO(0x10000,64),
                }
        }, {
index 64e52b3..e753285 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -1218,8 +1218,8 @@ static int __xipram do_write_oneword(str
+@@ -1215,8 +1215,8 @@ static int __xipram do_write_oneword(str
                        break;
                }
  
                        break;
                }
  
@@ -11,7 +11,7 @@
  
                /* Latency issues. Drop the lock, wait a while and retry */
                UDELAY(map, chip, adr, 1);
  
                /* Latency issues. Drop the lock, wait a while and retry */
                UDELAY(map, chip, adr, 1);
-@@ -1235,6 +1235,8 @@ static int __xipram do_write_oneword(str
+@@ -1232,6 +1232,8 @@ static int __xipram do_write_oneword(str
  
                ret = -EIO;
        }
  
                ret = -EIO;
        }
@@ -20,7 +20,7 @@
        xip_enable(map, chip, adr);
   op_done:
        chip->state = FL_READY;
        xip_enable(map, chip, adr);
   op_done:
        chip->state = FL_READY;
-@@ -1581,7 +1583,6 @@ static int cfi_amdstd_write_buffers(stru
+@@ -1578,7 +1580,6 @@ static int cfi_amdstd_write_buffers(stru
        return 0;
  }
  
        return 0;
  }
  
@@ -28,7 +28,7 @@
  /*
   * Handle devices with one erase region, that only implement
   * the chip erase command.
  /*
   * Handle devices with one erase region, that only implement
   * the chip erase command.
-@@ -1645,8 +1646,8 @@ static int __xipram do_erase_chip(struct
+@@ -1642,8 +1643,8 @@ static int __xipram do_erase_chip(struct
                        chip->erase_suspended = 0;
                }
  
                        chip->erase_suspended = 0;
                }
  
@@ -39,7 +39,7 @@
  
                if (time_after(jiffies, timeo)) {
                        printk(KERN_WARNING "MTD %s(): software timeout\n",
  
                if (time_after(jiffies, timeo)) {
                        printk(KERN_WARNING "MTD %s(): software timeout\n",
-@@ -1666,6 +1667,7 @@ static int __xipram do_erase_chip(struct
+@@ -1663,6 +1664,7 @@ static int __xipram do_erase_chip(struct
                ret = -EIO;
        }
  
                ret = -EIO;
        }
  
@@ -47,7 +47,7 @@
        chip->state = FL_READY;
        xip_enable(map, chip, adr);
        put_chip(map, chip, adr);
        chip->state = FL_READY;
        xip_enable(map, chip, adr);
        put_chip(map, chip, adr);
-@@ -1733,9 +1735,9 @@ static int __xipram do_erase_oneblock(st
+@@ -1730,9 +1732,9 @@ static int __xipram do_erase_oneblock(st
                        chip->erase_suspended = 0;
                }
  
                        chip->erase_suspended = 0;
                }
  
@@ -59,7 +59,7 @@
                }
  
                if (time_after(jiffies, timeo)) {
                }
  
                if (time_after(jiffies, timeo)) {
-@@ -1757,6 +1759,7 @@ static int __xipram do_erase_oneblock(st
+@@ -1754,6 +1756,7 @@ static int __xipram do_erase_oneblock(st
                ret = -EIO;
        }
  
                ret = -EIO;
        }
  
index c8012f5..62b414e 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
-@@ -952,6 +952,16 @@ static int __devinit m25p_probe(struct s
+@@ -948,6 +948,16 @@ static int __devinit m25p_probe(struct s
                                        part_probes, &parts, 0);
                }
  #endif
                                        part_probes, &parts, 0);
                }
  #endif
index 047239d..5d2c02e 100644 (file)
@@ -12,9 +12,9 @@
  /* makes sure the async qh will become idle */
 --- a/drivers/usb/host/ehci.h
 +++ b/drivers/usb/host/ehci.h
  /* makes sure the async qh will become idle */
 --- a/drivers/usb/host/ehci.h
 +++ b/drivers/usb/host/ehci.h
-@@ -131,6 +131,7 @@ struct ehci_hcd {                  /* one per controlle
-       unsigned                need_io_watchdog:1;
+@@ -132,6 +132,7 @@ struct ehci_hcd {                  /* one per controlle
        unsigned                broken_periodic:1;
        unsigned                broken_periodic:1;
+       unsigned                amd_l1_fix:1;
        unsigned                fs_i_thresh:1;  /* Intel iso scheduling */
 +      unsigned                has_synopsys_hc_bug:1; /* Synopsys HC */
  
        unsigned                fs_i_thresh:1;  /* Intel iso scheduling */
 +      unsigned                has_synopsys_hc_bug:1; /* Synopsys HC */
  
index 969cd1a..8333d0d 100644 (file)
@@ -35,7 +35,7 @@
  
  /* Atmel chips don't use the same PRI format as AMD chips */
  static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
  
  /* Atmel chips don't use the same PRI format as AMD chips */
  static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
-@@ -1392,6 +1396,7 @@ static int cfi_amdstd_write_words(struct
+@@ -1389,6 +1393,7 @@ static int cfi_amdstd_write_words(struct
  /*
   * FIXME: interleaved mode not tested, and probably not supported!
   */
  /*
   * FIXME: interleaved mode not tested, and probably not supported!
   */
@@ -43,7 +43,7 @@
  static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
                                    unsigned long adr, const u_char *buf,
                                    int len)
  static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
                                    unsigned long adr, const u_char *buf,
                                    int len)
-@@ -1503,7 +1508,6 @@ static int __xipram do_write_buffer(stru
+@@ -1500,7 +1505,6 @@ static int __xipram do_write_buffer(stru
        return ret;
  }
  
        return ret;
  }
  
@@ -51,7 +51,7 @@
  static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
                                    size_t *retlen, const u_char *buf)
  {
  static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
                                    size_t *retlen, const u_char *buf)
  {
-@@ -1582,6 +1586,7 @@ static int cfi_amdstd_write_buffers(stru
+@@ -1579,6 +1583,7 @@ static int cfi_amdstd_write_buffers(stru
  
        return 0;
  }
  
        return 0;
  }
index 696094f..0b36217 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/nand/rb4xx_nand.c
 +++ b/drivers/mtd/nand/rb4xx_nand.c
 --- a/drivers/mtd/nand/rb4xx_nand.c
 +++ b/drivers/mtd/nand/rb4xx_nand.c
-@@ -220,7 +220,7 @@ static int __init rb4xx_nand_probe(struc
+@@ -223,7 +223,7 @@ static int __init rb4xx_nand_probe(struc
  
        platform_set_drvdata(pdev, info);
  
  
        platform_set_drvdata(pdev, info);
  
index 4c0d395..0adb218 100644 (file)
@@ -16,7 +16,7 @@
  cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS)        += $(call cc-option,-mno-daddi,)
 --- a/arch/mips/Kconfig
 +++ b/arch/mips/Kconfig
  cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS)        += $(call cc-option,-mno-daddi,)
 --- a/arch/mips/Kconfig
 +++ b/arch/mips/Kconfig
-@@ -63,6 +63,23 @@ config AR7
+@@ -65,6 +65,23 @@ config AR7
          Support for the Texas Instruments AR7 System-on-a-Chip
          family: TNETD7100, 7200 and 7300.
  
          Support for the Texas Instruments AR7 System-on-a-Chip
          family: TNETD7100, 7200 and 7300.
  
@@ -40,7 +40,7 @@
  config BCM47XX
        bool "Broadcom BCM47XX based boards"
        select CEVT_R4K
  config BCM47XX
        bool "Broadcom BCM47XX based boards"
        select CEVT_R4K
-@@ -715,6 +732,7 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
+@@ -717,6 +734,7 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
  endchoice
  
  source "arch/mips/alchemy/Kconfig"
  endchoice
  
  source "arch/mips/alchemy/Kconfig"
index 0551442..be2e545 100644 (file)
@@ -30,7 +30,7 @@
        depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
 --- a/drivers/usb/host/ehci-hcd.c
 +++ b/drivers/usb/host/ehci-hcd.c
        depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
 --- a/drivers/usb/host/ehci-hcd.c
 +++ b/drivers/usb/host/ehci-hcd.c
-@@ -1216,6 +1216,11 @@ MODULE_LICENSE ("GPL");
+@@ -1229,6 +1229,11 @@ MODULE_LICENSE ("GPL");
  #define PLATFORM_DRIVER               ehci_octeon_driver
  #endif
  
  #define PLATFORM_DRIVER               ehci_octeon_driver
  #endif
  
index 5664463..909f2ed 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/Kconfig
 +++ b/drivers/net/Kconfig
 --- a/drivers/net/Kconfig
 +++ b/drivers/net/Kconfig
-@@ -2191,6 +2191,8 @@ config ACENIC_OMIT_TIGON_I
+@@ -2068,6 +2068,8 @@ config ACENIC_OMIT_TIGON_I
  
          The safe and default value for this is N.
  
  
          The safe and default value for this is N.
  
index ad5807e..5f5c498 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/watchdog/Kconfig
 +++ b/drivers/watchdog/Kconfig
 --- a/drivers/watchdog/Kconfig
 +++ b/drivers/watchdog/Kconfig
-@@ -927,6 +927,13 @@ config BCM63XX_WDT
+@@ -930,6 +930,13 @@ config BCM63XX_WDT
          To compile this driver as a loadable module, choose M here.
          The module will be called bcm63xx_wdt.
  
          To compile this driver as a loadable module, choose M here.
          The module will be called bcm63xx_wdt.
  
index 17a3bc2..dcf7a6d 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
-@@ -937,6 +937,16 @@ static int __devinit m25p_probe(struct s
+@@ -933,6 +933,16 @@ static int __devinit m25p_probe(struct s
                                        part_probes, &parts, 0);
                }
  
                                        part_probes, &parts, 0);
                }
  
index 2b10acb..bb0ff7d 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
-@@ -947,6 +947,15 @@ static int __devinit m25p_probe(struct s
+@@ -943,6 +943,15 @@ static int __devinit m25p_probe(struct s
                }
  #endif
  
                }
  #endif
  
index 246abd5..0c3814c 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/chips/jedec_probe.c
 +++ b/drivers/mtd/chips/jedec_probe.c
 --- a/drivers/mtd/chips/jedec_probe.c
 +++ b/drivers/mtd/chips/jedec_probe.c
-@@ -148,6 +148,7 @@
+@@ -149,6 +149,7 @@
  #define SST39LF160    0x2782
  #define SST39VF1601   0x234b
  #define SST39VF3201   0x235b
  #define SST39LF160    0x2782
  #define SST39VF1601   0x234b
  #define SST39VF3201   0x235b
@@ -8,7 +8,7 @@
  #define SST39WF1601   0x274b
  #define SST39WF1602   0x274a
  #define SST39LF512    0x00D4
  #define SST39WF1601   0x274b
  #define SST39WF1602   0x274a
  #define SST39LF512    0x00D4
-@@ -1568,6 +1569,18 @@ static const struct amd_flash_info jedec
+@@ -1582,6 +1583,18 @@ static const struct amd_flash_info jedec
                        ERASEINFO(0x10000,64),
                }
        }, {
                        ERASEINFO(0x10000,64),
                }
        }, {
index dc1bada..e8e1ec0 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -1231,8 +1231,8 @@ static int __xipram do_write_oneword(str
+@@ -1228,8 +1228,8 @@ static int __xipram do_write_oneword(str
                        break;
                }
  
                        break;
                }
  
@@ -11,7 +11,7 @@
  
                /* Latency issues. Drop the lock, wait a while and retry */
                UDELAY(map, chip, adr, 1);
  
                /* Latency issues. Drop the lock, wait a while and retry */
                UDELAY(map, chip, adr, 1);
-@@ -1248,6 +1248,8 @@ static int __xipram do_write_oneword(str
+@@ -1245,6 +1245,8 @@ static int __xipram do_write_oneword(str
  
                ret = -EIO;
        }
  
                ret = -EIO;
        }
@@ -20,7 +20,7 @@
        xip_enable(map, chip, adr);
   op_done:
        chip->state = FL_READY;
        xip_enable(map, chip, adr);
   op_done:
        chip->state = FL_READY;
-@@ -1579,7 +1581,6 @@ static int cfi_amdstd_write_buffers(stru
+@@ -1576,7 +1578,6 @@ static int cfi_amdstd_write_buffers(stru
        return 0;
  }
  
        return 0;
  }
  
@@ -28,7 +28,7 @@
  /*
   * Handle devices with one erase region, that only implement
   * the chip erase command.
  /*
   * Handle devices with one erase region, that only implement
   * the chip erase command.
-@@ -1643,8 +1644,8 @@ static int __xipram do_erase_chip(struct
+@@ -1640,8 +1641,8 @@ static int __xipram do_erase_chip(struct
                        chip->erase_suspended = 0;
                }
  
                        chip->erase_suspended = 0;
                }
  
@@ -39,7 +39,7 @@
  
                if (time_after(jiffies, timeo)) {
                        printk(KERN_WARNING "MTD %s(): software timeout\n",
  
                if (time_after(jiffies, timeo)) {
                        printk(KERN_WARNING "MTD %s(): software timeout\n",
-@@ -1664,6 +1665,7 @@ static int __xipram do_erase_chip(struct
+@@ -1661,6 +1662,7 @@ static int __xipram do_erase_chip(struct
                ret = -EIO;
        }
  
                ret = -EIO;
        }
  
@@ -47,7 +47,7 @@
        chip->state = FL_READY;
        xip_enable(map, chip, adr);
        put_chip(map, chip, adr);
        chip->state = FL_READY;
        xip_enable(map, chip, adr);
        put_chip(map, chip, adr);
-@@ -1731,9 +1733,9 @@ static int __xipram do_erase_oneblock(st
+@@ -1728,9 +1730,9 @@ static int __xipram do_erase_oneblock(st
                        chip->erase_suspended = 0;
                }
  
                        chip->erase_suspended = 0;
                }
  
@@ -59,7 +59,7 @@
                }
  
                if (time_after(jiffies, timeo)) {
                }
  
                if (time_after(jiffies, timeo)) {
-@@ -1755,6 +1757,7 @@ static int __xipram do_erase_oneblock(st
+@@ -1752,6 +1754,7 @@ static int __xipram do_erase_oneblock(st
                ret = -EIO;
        }
  
                ret = -EIO;
        }
  
index 7cd961d..c8012f5 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
-@@ -956,6 +956,16 @@ static int __devinit m25p_probe(struct s
+@@ -952,6 +952,16 @@ static int __devinit m25p_probe(struct s
                                        part_probes, &parts, 0);
                }
  #endif
                                        part_probes, &parts, 0);
                }
  #endif
index edd9e4e..905206d 100644 (file)
@@ -12,8 +12,8 @@
  /* makes sure the async qh will become idle */
 --- a/drivers/usb/host/ehci.h
 +++ b/drivers/usb/host/ehci.h
  /* makes sure the async qh will become idle */
 --- a/drivers/usb/host/ehci.h
 +++ b/drivers/usb/host/ehci.h
-@@ -133,6 +133,7 @@ struct ehci_hcd {                  /* one per controlle
-       unsigned                broken_periodic:1;
+@@ -134,6 +134,7 @@ struct ehci_hcd {                  /* one per controlle
+       unsigned                amd_l1_fix:1;
        unsigned                fs_i_thresh:1;  /* Intel iso scheduling */
        unsigned                use_dummy_qh:1; /* AMD Frame List table quirk*/
 +      unsigned                has_synopsys_hc_bug:1; /* Synopsys HC */
        unsigned                fs_i_thresh:1;  /* Intel iso scheduling */
        unsigned                use_dummy_qh:1; /* AMD Frame List table quirk*/
 +      unsigned                has_synopsys_hc_bug:1; /* Synopsys HC */
index 9dca6ea..a972f8f 100644 (file)
@@ -35,7 +35,7 @@
  
  /* Atmel chips don't use the same PRI format as AMD chips */
  static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
  
  /* Atmel chips don't use the same PRI format as AMD chips */
  static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
-@@ -1391,6 +1395,7 @@ static int cfi_amdstd_write_words(struct
+@@ -1388,6 +1392,7 @@ static int cfi_amdstd_write_words(struct
  /*
   * FIXME: interleaved mode not tested, and probably not supported!
   */
  /*
   * FIXME: interleaved mode not tested, and probably not supported!
   */
@@ -43,7 +43,7 @@
  static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
                                    unsigned long adr, const u_char *buf,
                                    int len)
  static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
                                    unsigned long adr, const u_char *buf,
                                    int len)
-@@ -1501,7 +1506,6 @@ static int __xipram do_write_buffer(stru
+@@ -1498,7 +1503,6 @@ static int __xipram do_write_buffer(stru
        return ret;
  }
  
        return ret;
  }
  
@@ -51,7 +51,7 @@
  static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
                                    size_t *retlen, const u_char *buf)
  {
  static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
                                    size_t *retlen, const u_char *buf)
  {
-@@ -1580,6 +1584,7 @@ static int cfi_amdstd_write_buffers(stru
+@@ -1577,6 +1581,7 @@ static int cfi_amdstd_write_buffers(stru
  
        return 0;
  }
  
        return 0;
  }
index cfbea70..9fb5ffa 100644 (file)
@@ -1,8 +1,8 @@
 --- a/drivers/leds/Kconfig
 +++ b/drivers/leds/Kconfig
 --- a/drivers/leds/Kconfig
 +++ b/drivers/leds/Kconfig
-@@ -347,6 +347,13 @@ config LEDS_TRIGGERS
- if LEDS_TRIGGERS
+@@ -377,6 +377,13 @@ config LEDS_TRIGGERS
+         These triggers allow kernel events to drive the LEDs and can
+         be configured via sysfs. If unsure, say Y.
  
 +config LEDS_WNDR3700_USB
 +      tristate "NETGEAR WNDR3700 USB LED driver"
  
 +config LEDS_WNDR3700_USB
 +      tristate "NETGEAR WNDR3700 USB LED driver"
index 6614fb9..34ec66d 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/leds/Kconfig
 +++ b/drivers/leds/Kconfig
 --- a/drivers/leds/Kconfig
 +++ b/drivers/leds/Kconfig
-@@ -354,6 +354,10 @@ config LEDS_WNDR3700_USB
+@@ -384,6 +384,10 @@ config LEDS_WNDR3700_USB
          This option enables support for the USB LED found on the
          NETGEAR WNDR3700 board.
  
          This option enables support for the USB LED found on the
          NETGEAR WNDR3700 board.
  
index 26e24c0..aaefb71 100644 (file)
@@ -10,7 +10,7 @@
  
 --- a/arch/mips/Kconfig
 +++ b/arch/mips/Kconfig
  
 --- a/arch/mips/Kconfig
 +++ b/arch/mips/Kconfig
-@@ -907,6 +907,9 @@ config MIPS_NILE4
+@@ -909,6 +909,9 @@ config MIPS_NILE4
  config MIPS_DISABLE_OBSOLETE_IDE
        bool
  
  config MIPS_DISABLE_OBSOLETE_IDE
        bool
  
index 696094f..0b36217 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/nand/rb4xx_nand.c
 +++ b/drivers/mtd/nand/rb4xx_nand.c
 --- a/drivers/mtd/nand/rb4xx_nand.c
 +++ b/drivers/mtd/nand/rb4xx_nand.c
-@@ -220,7 +220,7 @@ static int __init rb4xx_nand_probe(struc
+@@ -223,7 +223,7 @@ static int __init rb4xx_nand_probe(struc
  
        platform_set_drvdata(pdev, info);
  
  
        platform_set_drvdata(pdev, info);
  
index 895d3ce..38d997e 100644 (file)
@@ -8,7 +8,7 @@
  
  extern void check_wait(void);
  extern asmlinkage void r4k_wait(void);
  
  extern void check_wait(void);
  extern asmlinkage void r4k_wait(void);
-@@ -1552,6 +1553,8 @@ void __cpuinit per_cpu_trap_init(void)
+@@ -1578,6 +1579,8 @@ void __cpuinit per_cpu_trap_init(void)
        if (cpu_has_mips_r2) {
                cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
                cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
        if (cpu_has_mips_r2) {
                cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
                cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
index 4ccd376..1fe6483 100644 (file)
@@ -805,12 +805,6 @@ CONFIG_IDE_PROC_FS=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
-# CONFIG_IMQ is not set
-# CONFIG_IMQ_BEHAVIOR_AA is not set
-# CONFIG_IMQ_BEHAVIOR_AB is not set
-# CONFIG_IMQ_BEHAVIOR_BA is not set
-# CONFIG_IMQ_BEHAVIOR_BB is not set
-CONFIG_IMQ_NUM_DEVS=2
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
index d54c1d2..c31b4dd 100644 (file)
@@ -799,12 +799,6 @@ CONFIG_IDE_PROC_FS=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
-# CONFIG_IMQ is not set
-# CONFIG_IMQ_BEHAVIOR_AA is not set
-# CONFIG_IMQ_BEHAVIOR_AB is not set
-# CONFIG_IMQ_BEHAVIOR_BA is not set
-# CONFIG_IMQ_BEHAVIOR_BB is not set
-CONFIG_IMQ_NUM_DEVS=2
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
index 0bb2b66..b035981 100644 (file)
@@ -857,12 +857,6 @@ CONFIG_IDE_PROC_FS=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
-# CONFIG_IMQ is not set
-# CONFIG_IMQ_BEHAVIOR_AA is not set
-# CONFIG_IMQ_BEHAVIOR_AB is not set
-# CONFIG_IMQ_BEHAVIOR_BA is not set
-# CONFIG_IMQ_BEHAVIOR_BB is not set
-CONFIG_IMQ_NUM_DEVS=2
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
index c14a340..64c76f1 100644 (file)
@@ -894,12 +894,6 @@ CONFIG_IDE_PROC_FS=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
-# CONFIG_IMQ is not set
-# CONFIG_IMQ_BEHAVIOR_AA is not set
-# CONFIG_IMQ_BEHAVIOR_AB is not set
-# CONFIG_IMQ_BEHAVIOR_BA is not set
-# CONFIG_IMQ_BEHAVIOR_BB is not set
-CONFIG_IMQ_NUM_DEVS=2
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
index d416c6d..bf81396 100644 (file)
@@ -929,12 +929,6 @@ CONFIG_IDE_PROC_FS=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
-# CONFIG_IMQ is not set
-# CONFIG_IMQ_BEHAVIOR_AA is not set
-# CONFIG_IMQ_BEHAVIOR_AB is not set
-# CONFIG_IMQ_BEHAVIOR_BA is not set
-# CONFIG_IMQ_BEHAVIOR_BB is not set
-CONFIG_IMQ_NUM_DEVS=2
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
index d3138fc..47a35aa 100644 (file)
@@ -877,12 +877,6 @@ CONFIG_IDE_PROC_FS=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
-# CONFIG_IMQ is not set
-# CONFIG_IMQ_BEHAVIOR_AA is not set
-# CONFIG_IMQ_BEHAVIOR_AB is not set
-# CONFIG_IMQ_BEHAVIOR_BA is not set
-# CONFIG_IMQ_BEHAVIOR_BB is not set
-CONFIG_IMQ_NUM_DEVS=2
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
index 472c3a4..1899da7 100644 (file)
@@ -897,12 +897,6 @@ CONFIG_IDE_PROC_FS=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
-# CONFIG_IMQ is not set
-# CONFIG_IMQ_BEHAVIOR_AA is not set
-# CONFIG_IMQ_BEHAVIOR_AB is not set
-# CONFIG_IMQ_BEHAVIOR_BA is not set
-# CONFIG_IMQ_BEHAVIOR_BB is not set
-CONFIG_IMQ_NUM_DEVS=2
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 CONFIG_INET=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
index 499bec0..dad054e 100644 (file)
@@ -903,12 +903,6 @@ CONFIG_IDE_PROC_FS=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG_PROC is not set
 # CONFIG_IMAGE_CMDLINE_HACK is not set
-# CONFIG_IMQ_BEHAVIOR_AA is not set
-# CONFIG_IMQ_BEHAVIOR_AB is not set
-# CONFIG_IMQ_BEHAVIOR_BA is not set
-# CONFIG_IMQ_BEHAVIOR_BB is not set
-# CONFIG_IMQ is not set
-CONFIG_IMQ_NUM_DEVS=2
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 # CONFIG_INET6_IPCOMP is not set
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 # CONFIG_INET6_IPCOMP is not set
diff --git a/target/linux/generic/patches-2.6.30/150-netfilter_imq.patch b/target/linux/generic/patches-2.6.30/150-netfilter_imq.patch
deleted file mode 100644 (file)
index 3bd7a8f..0000000
+++ /dev/null
@@ -1,1260 +0,0 @@
---- /dev/null
-+++ b/drivers/net/imq.c
-@@ -0,0 +1,571 @@
-+/*
-+ *             Pseudo-driver for the intermediate queue device.
-+ *
-+ *             This program is free software; you can redistribute it and/or
-+ *             modify it under the terms of the GNU General Public License
-+ *             as published by the Free Software Foundation; either version
-+ *             2 of the License, or (at your option) any later version.
-+ *
-+ * Authors:    Patrick McHardy, <kaber@trash.net>
-+ *
-+ *            The first version was written by Martin Devera, <devik@cdi.cz>
-+ *
-+ * Credits:    Jan Rafaj <imq2t@cedric.vabo.cz>
-+ *              - Update patch to 2.4.21
-+ *             Sebastian Strollo <sstrollo@nortelnetworks.com>
-+ *              - Fix "Dead-loop on netdevice imq"-issue
-+ *             Marcel Sebek <sebek64@post.cz>
-+ *              - Update to 2.6.2-rc1
-+ *
-+ *           After some time of inactivity there is a group taking care
-+ *           of IMQ again: http://www.linuximq.net
-+ *
-+ *
-+ *           2004/06/30 - New version of IMQ patch to kernels <=2.6.7
-+ *             including the following changes:
-+ *
-+ *           - Correction of ipv6 support "+"s issue (Hasso Tepper)
-+ *           - Correction of imq_init_devs() issue that resulted in
-+ *           kernel OOPS unloading IMQ as module (Norbert Buchmuller)
-+ *           - Addition of functionality to choose number of IMQ devices
-+ *           during kernel config (Andre Correa)
-+ *           - Addition of functionality to choose how IMQ hooks on
-+ *           PRE and POSTROUTING (after or before NAT) (Andre Correa)
-+ *           - Cosmetic corrections (Norbert Buchmuller) (Andre Correa)
-+ *
-+ *
-+ *             2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were
-+ *             released with almost no problems. 2.6.14-x was released
-+ *             with some important changes: nfcache was removed; After
-+ *             some weeks of trouble we figured out that some IMQ fields
-+ *             in skb were missing in skbuff.c - skb_clone and copy_skb_header.
-+ *             These functions are correctly patched by this new patch version.
-+ *
-+ *             Thanks for all who helped to figure out all the problems with
-+ *             2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX,
-+ *             Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully
-+ *             I didn't forget anybody). I apologize again for my lack of time.
-+ *
-+ *
-+ *             2008/06/17 - 2.6.25 - Changed imq.c to use qdisc_run() instead
-+ *             of qdisc_restart() and moved qdisc_run() to tasklet to avoid
-+ *             recursive locking. New initialization routines to fix 'rmmod' not
-+ *             working anymore. Used code from ifb.c. (Jussi Kivilinna)
-+ *
-+ *             2008/08/06 - 2.6.26 - (JK)
-+ *              - Replaced tasklet with 'netif_schedule()'.
-+ *              - Cleaned up and added comments for imq_nf_queue().
-+ *
-+ *             2009/04/12
-+ *              - Add skb_save_cb/skb_restore_cb helper functions for backuping
-+ *                control buffer. This is needed because qdisc-layer on kernels
-+ *                2.6.27 and newer overwrite control buffer. (Jussi Kivilinna)
-+ *              - Add better locking for IMQ device. Hopefully this will solve
-+ *                SMP issues. (Jussi Kivilinna)
-+ *              - Port to 2.6.27
-+ *              - Port to 2.6.28
-+ *              - Port to 2.6.29 + fix rmmod not working
-+ *
-+ *             2009/04/20 - (Jussi Kivilinna)
-+ *              - Use netdevice feature flags to avoid extra packet handling
-+ *                by core networking layer and possibly increase performance.
-+ *
-+ *           Also, many thanks to pablo Sebastian Greco for making the initial
-+ *           patch and to those who helped the testing.
-+ *
-+ *             More info at: http://www.linuximq.net/ (Andre Correa)
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/moduleparam.h>
-+#include <linux/list.h>
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/if_arp.h>
-+#include <linux/netfilter.h>
-+#include <linux/netfilter_ipv4.h>
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      #include <linux/netfilter_ipv6.h>
-+#endif
-+#include <linux/imq.h>
-+#include <net/pkt_sched.h>
-+#include <net/netfilter/nf_queue.h>
-+
-+static nf_hookfn imq_nf_hook;
-+
-+static struct nf_hook_ops imq_ingress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP_PRI_LAST
-+#else
-+      .priority       = NF_IP_PRI_NAT_SRC - 1
-+#endif
-+};
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+static struct nf_hook_ops imq_ingress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP6_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP6_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP6_PRI_LAST
-+#else
-+      .priority       = NF_IP6_PRI_NAT_SRC - 1
-+#endif
-+};
-+#endif
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS;
-+#else
-+static unsigned int numdevs = IMQ_MAX_DEVS;
-+#endif
-+
-+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;
-+
-+      if (entry) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree(entry);
-+      }
-+
-+      skb_restore_cb(skb); /* kfree backup */
-+}
-+
-+static void imq_nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              spin_lock_bh(&imq_nf_queue_lock);
-+              nf_reinject(entry, verdict);
-+              spin_unlock_bh(&imq_nf_queue_lock);
-+              return;
-+      }
-+
-+      rcu_read_lock();
-+      local_bh_disable();
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      local_bh_enable();
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+
-+      rcu_read_unlock();
-+}
-+
-+static int imq_dev_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+      dev->stats.tx_bytes += skb->len;
-+      dev->stats.tx_packets++;
-+
-+      skb->imq_flags = 0;
-+      skb->destructor = NULL;
-+
-+      skb_restore_cb(skb); /* restore skb->cb */
-+
-+      dev->trans_start = jiffies;
-+      imq_nf_reinject(skb->nf_queue_entry, NF_ACCEPT);
-+      return 0;
-+}
-+
-+static int imq_nf_queue(struct nf_queue_entry *entry, unsigned queue_num)
-+{
-+      struct net_device *dev;
-+      struct sk_buff *skb_orig, *skb, *skb_shared;
-+      struct Qdisc *q;
-+      struct netdev_queue *txq;
-+      int users, index;
-+      int retval = -EINVAL;
-+
-+      index = entry->skb->imq_flags & IMQ_F_IFMASK;
-+      if (unlikely(index > numdevs - 1)) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING
-+                             "IMQ: invalid device specified, highest is %u\n",
-+                             numdevs - 1);
-+              retval = -EINVAL;
-+              goto out;
-+      }
-+
-+      /* check for imq device by index from cache */
-+      dev = imq_devs_cache[index];
-+      if (unlikely(!dev)) {
-+              char buf[8];
-+
-+              /* get device by name and cache result */
-+              snprintf(buf, sizeof(buf), "imq%d", index);
-+              dev = dev_get_by_name(&init_net, buf);
-+              if (!dev) {
-+                      /* not found ?!*/
-+                      BUG();
-+                      retval = -ENODEV;
-+                      goto out;
-+              }
-+
-+              imq_devs_cache[index] = dev;
-+              dev_put(dev);
-+      }
-+
-+      if (unlikely(!(dev->flags & IFF_UP))) {
-+              entry->skb->imq_flags = 0;
-+              imq_nf_reinject(entry, NF_ACCEPT);
-+              retval = 0;
-+              goto out;
-+      }
-+      dev->last_rx = jiffies;
-+
-+      skb = entry->skb;
-+      skb_orig = NULL;
-+
-+      /* skb has owner? => make clone */
-+      if (unlikely(skb->destructor)) {
-+              skb_orig = skb;
-+              skb = skb_clone(skb, GFP_ATOMIC);
-+              if (!skb) {
-+                      retval = -ENOMEM;
-+                      goto out;
-+              }
-+              entry->skb = skb;
-+      }
-+
-+      skb->nf_queue_entry = entry;
-+
-+      dev->stats.rx_bytes += skb->len;
-+      dev->stats.rx_packets++;
-+
-+      txq = dev_pick_tx(dev, skb);
-+
-+      q = rcu_dereference(txq->qdisc);
-+      if (unlikely(!q->enqueue))
-+              goto packet_not_eaten_by_imq_dev;
-+
-+      spin_lock_bh(qdisc_lock(q));
-+
-+      users = atomic_read(&skb->users);
-+
-+      skb_shared = skb_get(skb); /* increase reference count by one */
-+      skb_save_cb(skb_shared); /* backup skb->cb, as qdisc layer will
-+                                      overwrite it */
-+      qdisc_enqueue_root(skb_shared, q); /* might kfree_skb */
-+
-+      if (likely(atomic_read(&skb_shared->users) == users + 1)) {
-+              kfree_skb(skb_shared); /* decrease reference count by one */
-+
-+              skb->destructor = &imq_skb_destructor;
-+
-+              /* cloned? */
-+              if (skb_orig)
-+                      kfree_skb(skb_orig); /* free original */
-+
-+              spin_unlock_bh(qdisc_lock(q));
-+
-+              /* schedule qdisc dequeue */
-+              __netif_schedule(q);
-+
-+              retval = 0;
-+              goto out;
-+      } else {
-+              skb_restore_cb(skb_shared); /* restore skb->cb */
-+              /* qdisc dropped packet and decreased skb reference count of
-+               * skb, so we don't really want to and try refree as that would
-+               * actually destroy the skb. */
-+              spin_unlock_bh(qdisc_lock(q));
-+              goto packet_not_eaten_by_imq_dev;
-+      }
-+
-+packet_not_eaten_by_imq_dev:
-+      /* cloned? restore original */
-+      if (skb_orig) {
-+              kfree_skb(skb);
-+              entry->skb = skb_orig;
-+      }
-+      retval = -1;
-+out:
-+      return retval;
-+}
-+
-+static struct nf_queue_handler nfqh = {
-+      .name  = "imq",
-+      .outfn = imq_nf_queue,
-+};
-+
-+static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff *pskb,
-+                              const struct net_device *indev,
-+                              const struct net_device *outdev,
-+                              int (*okfn)(struct sk_buff *))
-+{
-+      if (pskb->imq_flags & IMQ_F_ENQUEUE)
-+              return NF_QUEUE;
-+
-+      return NF_ACCEPT;
-+}
-+
-+static int imq_close(struct net_device *dev)
-+{
-+      netif_stop_queue(dev);
-+      return 0;
-+}
-+
-+static int imq_open(struct net_device *dev)
-+{
-+      netif_start_queue(dev);
-+      return 0;
-+}
-+
-+static const struct net_device_ops imq_netdev_ops = {
-+      .ndo_open               = imq_open,
-+      .ndo_stop               = imq_close,
-+      .ndo_start_xmit         = imq_dev_xmit,
-+      .ndo_get_stats          = imq_get_stats,
-+};
-+
-+static void imq_setup(struct net_device *dev)
-+{
-+      dev->netdev_ops         = &imq_netdev_ops;
-+      dev->type               = ARPHRD_VOID;
-+      dev->mtu                = 16000;
-+      dev->tx_queue_len       = 11000;
-+      dev->flags              = IFF_NOARP;
-+      dev->features           = NETIF_F_SG | NETIF_F_FRAGLIST |
-+                                NETIF_F_GSO | NETIF_F_HW_CSUM |
-+                                NETIF_F_HIGHDMA;
-+}
-+
-+static int imq_validate(struct nlattr *tb[], struct nlattr *data[])
-+{
-+      int ret = 0;
-+
-+      if (tb[IFLA_ADDRESS]) {
-+              if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
-+                      ret = -EINVAL;
-+                      goto end;
-+              }
-+              if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) {
-+                      ret = -EADDRNOTAVAIL;
-+                      goto end;
-+              }
-+      }
-+      return 0;
-+end:
-+      printk(KERN_WARNING "IMQ: imq_validate failed (%d)\n", ret);
-+      return ret;
-+}
-+
-+static struct rtnl_link_ops imq_link_ops __read_mostly = {
-+      .kind           = "imq",
-+      .priv_size      = 0,
-+      .setup          = imq_setup,
-+      .validate       = imq_validate,
-+};
-+
-+static int __init imq_init_hooks(void)
-+{
-+      int err;
-+
-+      nf_register_queue_imq_handler(&nfqh);
-+
-+      err = nf_register_hook(&imq_ingress_ipv4);
-+      if (err)
-+              goto err1;
-+
-+      err = nf_register_hook(&imq_egress_ipv4);
-+      if (err)
-+              goto err2;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      err = nf_register_hook(&imq_ingress_ipv6);
-+      if (err)
-+              goto err3;
-+
-+      err = nf_register_hook(&imq_egress_ipv6);
-+      if (err)
-+              goto err4;
-+#endif
-+
-+      return 0;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+err4:
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+err3:
-+      nf_unregister_hook(&imq_egress_ipv4);
-+#endif
-+err2:
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+err1:
-+      nf_unregister_queue_imq_handler();
-+      return err;
-+}
-+
-+static int __init imq_init_one(int index)
-+{
-+      struct net_device *dev;
-+      int ret;
-+
-+      dev = alloc_netdev(0, "imq%d", imq_setup);
-+      if (!dev)
-+              return -ENOMEM;
-+
-+      ret = dev_alloc_name(dev, dev->name);
-+      if (ret < 0)
-+              goto fail;
-+
-+      dev->rtnl_link_ops = &imq_link_ops;
-+      ret = register_netdevice(dev);
-+      if (ret < 0)
-+              goto fail;
-+
-+      return 0;
-+fail:
-+      free_netdev(dev);
-+      return ret;
-+}
-+
-+static int __init imq_init_devs(void)
-+{
-+      int err, i;
-+
-+      if (numdevs < 1 || numdevs > IMQ_MAX_DEVS) {
-+              printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n",
-+                     IMQ_MAX_DEVS);
-+              return -EINVAL;
-+      }
-+
-+      rtnl_lock();
-+      err = __rtnl_link_register(&imq_link_ops);
-+
-+      for (i = 0; i < numdevs && !err; i++)
-+              err = imq_init_one(i);
-+
-+      if (err) {
-+              __rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+      }
-+      rtnl_unlock();
-+
-+      return err;
-+}
-+
-+static int __init imq_init_module(void)
-+{
-+      int err;
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS > 16);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS < 2);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS - 1 > IMQ_F_IFMASK);
-+#endif
-+
-+      err = imq_init_devs();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_devs(net)\n");
-+              return err;
-+      }
-+
-+      err = imq_init_hooks();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n");
-+              rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+              return err;
-+      }
-+
-+      printk(KERN_INFO "IMQ driver loaded successfully.\n");
-+
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n");
-+#endif
-+#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n");
-+#endif
-+
-+      return 0;
-+}
-+
-+static void __exit imq_unhook(void)
-+{
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+      nf_unregister_hook(&imq_egress_ipv6);
-+#endif
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+      nf_unregister_hook(&imq_egress_ipv4);
-+
-+      nf_unregister_queue_imq_handler();
-+}
-+
-+static void __exit imq_cleanup_devs(void)
-+{
-+      rtnl_link_unregister(&imq_link_ops);
-+      memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+}
-+
-+static void __exit imq_exit_module(void)
-+{
-+      imq_unhook();
-+      imq_cleanup_devs();
-+      printk(KERN_INFO "IMQ driver unloaded successfully.\n");
-+}
-+
-+module_init(imq_init_module);
-+module_exit(imq_exit_module);
-+
-+module_param(numdevs, int, 0);
-+MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will "
-+                      "be created)");
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See "
-+                      "http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS_RTNL_LINK("imq");
-+
---- a/drivers/net/Kconfig
-+++ b/drivers/net/Kconfig
-@@ -119,6 +119,129 @@ config EQUALIZER
-         To compile this driver as a module, choose M here: the module
-         will be called eql.  If unsure, say N.
-+config IMQ
-+      tristate "IMQ (intermediate queueing device) support"
-+      depends on NETDEVICES && NETFILTER
-+      ---help---
-+        The IMQ device(s) is used as placeholder for QoS queueing
-+        disciplines. Every packet entering/leaving the IP stack can be
-+        directed through the IMQ device where it's enqueued/dequeued to the
-+        attached qdisc. This allows you to treat network devices as classes
-+        and distribute bandwidth among them. Iptables is used to specify
-+        through which IMQ device, if any, packets travel.
-+
-+        More information at: http://www.linuximq.net/
-+
-+        To compile this driver as a module, choose M here: the module
-+        will be called imq.  If unsure, say N.
-+
-+choice
-+      prompt "IMQ behavior (PRE/POSTROUTING)"
-+      depends on IMQ
-+      default IMQ_BEHAVIOR_AB
-+      help
-+
-+              This settings defines how IMQ behaves in respect to its
-+              hooking in PREROUTING and POSTROUTING.
-+
-+              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
-+
-+              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.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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 settings defines how many IMQ devices will be
-+              created.
-+
-+              The default value is 16.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              If not sure leave the default settings alone.
-+
- config TUN
-       tristate "Universal TUN/TAP device driver support"
-       select CRC32
---- a/drivers/net/Makefile
-+++ b/drivers/net/Makefile
-@@ -152,6 +152,7 @@ obj-$(CONFIG_SLHC) += slhc.o
- obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o
- obj-$(CONFIG_DUMMY) += dummy.o
-+obj-$(CONFIG_IMQ) += imq.o
- obj-$(CONFIG_IFB) += ifb.o
- obj-$(CONFIG_MACVLAN) += macvlan.o
- obj-$(CONFIG_DE600) += de600.o
---- /dev/null
-+++ b/include/linux/imq.h
-@@ -0,0 +1,13 @@
-+#ifndef _IMQ_H
-+#define _IMQ_H
-+
-+/* IFMASK (16 device indexes, 0 to 15) and flag(s) fit in 5 bits */
-+#define IMQ_F_BITS    5
-+
-+#define IMQ_F_IFMASK  0x0f
-+#define IMQ_F_ENQUEUE 0x10
-+
-+#define IMQ_MAX_DEVS  (IMQ_F_IFMASK + 1)
-+
-+#endif /* _IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv4/ipt_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IPT_IMQ_H
-+#define _IPT_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ipt_imq_info xt_imq_info
-+
-+#endif /* _IPT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv6/ip6t_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IP6T_IMQ_H
-+#define _IP6T_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ip6t_imq_info xt_imq_info
-+
-+#endif /* _IP6T_IMQ_H */
-+
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -28,6 +28,9 @@
- #include <linux/rcupdate.h>
- #include <linux/dmaengine.h>
- #include <linux/hrtimer.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- /* Don't change this without changing skb_csum_unnecessary! */
- #define CHECKSUM_NONE 0
-@@ -333,6 +336,9 @@ struct sk_buff {
-        * first. This is owned by whoever has the skb queued ATM.
-        */
-       char                    cb[48];
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      void                    *cb_next;
-+#endif
-       unsigned int            len,
-                               data_len;
-@@ -363,6 +369,9 @@ struct sk_buff {
-       struct nf_conntrack     *nfct;
-       struct sk_buff          *nfct_reasm;
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      struct nf_queue_entry   *nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       struct nf_bridge_info   *nf_bridge;
- #endif
-@@ -383,6 +392,9 @@ struct sk_buff {
-       __u8                    requeue:1;
- #endif
-       /* 0/13/14 bit hole */
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      __u8                    imq_flags:IMQ_F_BITS;
-+#endif
- #ifdef CONFIG_NET_DMA
-       dma_cookie_t            dma_cookie;
-@@ -423,6 +435,12 @@ extern void skb_dma_unmap(struct device 
-                         enum dma_data_direction dir);
- #endif
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern int skb_save_cb(struct sk_buff *skb);
-+extern int skb_restore_cb(struct sk_buff *skb);
-+#endif
-+
- extern void kfree_skb(struct sk_buff *skb);
- extern void consume_skb(struct sk_buff *skb);
- extern void          __kfree_skb(struct sk_buff *skb);
-@@ -1931,6 +1949,10 @@ static inline void __nf_copy(struct sk_b
-       dst->nfct_reasm = src->nfct_reasm;
-       nf_conntrack_get_reasm(src->nfct_reasm);
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      dst->imq_flags = src->imq_flags;
-+      dst->nf_queue_entry = src->nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       dst->nf_bridge  = src->nf_bridge;
-       nf_bridge_get(src->nf_bridge);
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -96,6 +96,9 @@
- #include <net/net_namespace.h>
- #include <net/sock.h>
- #include <linux/rtnetlink.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- #include <linux/proc_fs.h>
- #include <linux/seq_file.h>
- #include <linux/stat.h>
-@@ -1678,7 +1681,11 @@ int dev_hard_start_xmit(struct sk_buff *
-       int rc;
-       if (likely(!skb->next)) {
--              if (!list_empty(&ptype_all))
-+              if (!list_empty(&ptype_all)
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+                  && !(skb->imq_flags & IMQ_F_ENQUEUE)
-+#endif
-+                  )
-                       dev_queue_xmit_nit(skb, dev);
-               if (netif_needs_gso(dev, skb)) {
-@@ -1749,8 +1756,7 @@ u16 skb_tx_hash(const struct net_device 
- }
- EXPORT_SYMBOL(skb_tx_hash);
--static struct netdev_queue *dev_pick_tx(struct net_device *dev,
--                                      struct sk_buff *skb)
-+struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb)
- {
-       const struct net_device_ops *ops = dev->netdev_ops;
-       u16 queue_index = 0;
-@@ -1763,6 +1769,7 @@ static struct netdev_queue *dev_pick_tx(
-       skb_set_queue_mapping(skb, queue_index);
-       return netdev_get_tx_queue(dev, queue_index);
- }
-+EXPORT_SYMBOL(dev_pick_tx);
- /**
-  *    dev_queue_xmit - transmit a buffer
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1102,6 +1102,7 @@ extern int               dev_alloc_name(struct net_de
- extern int            dev_open(struct net_device *dev);
- extern int            dev_close(struct net_device *dev);
- extern void           dev_disable_lro(struct net_device *dev);
-+extern struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb);
- extern int            dev_queue_xmit(struct sk_buff *skb);
- extern int            register_netdevice(struct net_device *dev);
- extern void           unregister_netdevice(struct net_device *dev);
---- /dev/null
-+++ b/include/linux/netfilter/xt_IMQ.h
-@@ -0,0 +1,9 @@
-+#ifndef _XT_IMQ_H
-+#define _XT_IMQ_H
-+
-+struct xt_imq_info {
-+      unsigned int todev;     /* target imq device */
-+};
-+
-+#endif /* _XT_IMQ_H */
-+
---- a/include/net/netfilter/nf_queue.h
-+++ b/include/net/netfilter/nf_queue.h
-@@ -13,6 +13,12 @@ struct nf_queue_entry {
-       struct net_device       *indev;
-       struct net_device       *outdev;
-       int                     (*okfn)(struct sk_buff *);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      int                     (*next_outfn)(struct nf_queue_entry *entry,
-+                                            unsigned int queuenum);
-+      unsigned int            next_queuenum;
-+#endif
- };
- #define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry))
-@@ -30,5 +36,11 @@ extern int nf_unregister_queue_handler(u
-                                      const struct nf_queue_handler *qh);
- extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
- extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
-+extern void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern void nf_register_queue_imq_handler(const struct nf_queue_handler *qh);
-+extern void nf_unregister_queue_imq_handler(void);
-+#endif
- #endif /* _NF_QUEUE_H */
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -71,6 +71,9 @@
- static struct kmem_cache *skbuff_head_cache __read_mostly;
- static struct kmem_cache *skbuff_fclone_cache __read_mostly;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static struct kmem_cache *skbuff_cb_store_cache __read_mostly;
-+#endif
- static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
-                                 struct pipe_buffer *buf)
-@@ -90,6 +93,80 @@ static int sock_pipe_buf_steal(struct pi
-       return 1;
- }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+/* Control buffer save/restore for IMQ devices */
-+struct skb_cb_table {
-+      void                    *cb_next;
-+      atomic_t                refcnt;
-+      char                    cb[48];
-+};
-+
-+static DEFINE_SPINLOCK(skb_cb_store_lock);
-+
-+int skb_save_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      next = kmem_cache_alloc(skbuff_cb_store_cache, GFP_ATOMIC);
-+      if (!next)
-+              return -ENOMEM;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(next->cb, skb->cb, sizeof(skb->cb));
-+      next->cb_next = skb->cb_next;
-+
-+      atomic_set(&next->refcnt, 1);
-+
-+      skb->cb_next = next;
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_save_cb);
-+
-+int skb_restore_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      if (!skb->cb_next)
-+              return 0;
-+
-+      next = skb->cb_next;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(skb->cb, next->cb, sizeof(skb->cb));
-+      skb->cb_next = next->cb_next;
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      if (atomic_dec_and_test(&next->refcnt)) {
-+              kmem_cache_free(skbuff_cb_store_cache, next);
-+      }
-+
-+      spin_unlock(&skb_cb_store_lock);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_restore_cb);
-+
-+static void skb_copy_stored_cb(struct sk_buff *new, struct sk_buff *old)
-+{
-+      struct skb_cb_table *next;
-+
-+      if (!old->cb_next) {
-+              new->cb_next = 0;
-+              return;
-+      }
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      next = old->cb_next;
-+      atomic_inc(&next->refcnt);
-+      new->cb_next = next;
-+
-+      spin_unlock(&skb_cb_store_lock);
-+}
-+#endif
- /* Pipe buffer operations for a socket. */
- static struct pipe_buf_operations sock_pipe_buf_ops = {
-@@ -389,6 +466,15 @@ static void skb_release_head_state(struc
-               WARN_ON(in_irq());
-               skb->destructor(skb);
-       }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      /* This should not happen. When it does, avoid memleak by restoring
-+      the chain of cb-backups. */
-+      while(skb->cb_next != NULL) {
-+              printk(KERN_WARNING "kfree_skb: skb->cb_next: %08x\n",
-+                      skb->cb_next);
-+              skb_restore_cb(skb);
-+      }
-+#endif
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-       nf_conntrack_put(skb->nfct);
-       nf_conntrack_put_reasm(skb->nfct_reasm);
-@@ -526,6 +612,9 @@ static void __copy_skb_header(struct sk_
-       new->sp                 = secpath_get(old->sp);
- #endif
-       memcpy(new->cb, old->cb, sizeof(old->cb));
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skb_copy_stored_cb(new, old);
-+#endif
-       new->csum_start         = old->csum_start;
-       new->csum_offset        = old->csum_offset;
-       new->local_df           = old->local_df;
-@@ -2769,6 +2858,13 @@ void __init skb_init(void)
-                                               0,
-                                               SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-                                               NULL);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skbuff_cb_store_cache = kmem_cache_create("skbuff_cb_store_cache",
-+                                                sizeof(struct skb_cb_table),
-+                                                0,
-+                                                SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-+                                                NULL);
-+#endif
- }
- /**
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -396,6 +396,18 @@ config NETFILTER_XT_TARGET_LED
-         For more information on the LEDs available on your system, see
-         Documentation/leds-class.txt
-+config NETFILTER_XT_TARGET_IMQ
-+        tristate '"IMQ" target support'
-+      depends on NETFILTER_XTABLES
-+      depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+      select IMQ
-+      default m if NETFILTER_ADVANCED=n
-+        help
-+          This option adds a `IMQ' target which is used to specify if and
-+          to which imq device packets should get enqueued/dequeued.
-+
-+          To compile it as a module, choose M here.  If unsure, say N.
-+
- config NETFILTER_XT_TARGET_MARK
-       tristate '"MARK" target support'
-       default m if NETFILTER_ADVANCED=n
---- a/net/netfilter/Makefile
-+++ b/net/netfilter/Makefile
-@@ -46,6 +46,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMAR
- obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
-+obj-$(CONFIG_NETFILTER_XT_TARGET_IMQ) += xt_IMQ.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
---- a/net/netfilter/nf_queue.c
-+++ b/net/netfilter/nf_queue.c
-@@ -20,6 +20,26 @@ static const struct nf_queue_handler *qu
- static DEFINE_MUTEX(queue_handler_mutex);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static const struct nf_queue_handler *queue_imq_handler;
-+
-+void nf_register_queue_imq_handler(const struct nf_queue_handler *qh)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, qh);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_register_queue_imq_handler);
-+
-+void nf_unregister_queue_imq_handler(void)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, NULL);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_unregister_queue_imq_handler);
-+#endif
-+
- /* return EBUSY when somebody else is registered, return EEXIST if the
-  * same handler is registered, return 0 in case of success. */
- int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
-@@ -80,7 +100,7 @@ void nf_unregister_queue_handlers(const 
- }
- EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);
--static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
-+void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
- {
-       /* Release those devices we held, or Alexey will kill me. */
-       if (entry->indev)
-@@ -100,6 +120,7 @@ static void nf_queue_entry_release_refs(
-       /* Drop reference to owner of hook which queued us. */
-       module_put(entry->elem->owner);
- }
-+EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
- /*
-  * Any packet that leaves via this function must come back
-@@ -121,12 +142,26 @@ static int __nf_queue(struct sk_buff *sk
- #endif
-       const struct nf_afinfo *afinfo;
-       const struct nf_queue_handler *qh;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      const struct nf_queue_handler *qih = NULL;
-+#endif
-       /* QUEUE == DROP if noone is waiting, to be safe. */
-       rcu_read_lock();
-       qh = rcu_dereference(queue_handler[pf]);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      if (pf == PF_INET || pf == PF_INET6)
-+#else
-+      if (pf == PF_INET)
-+#endif
-+              qih = rcu_dereference(queue_imq_handler);
-+
-+      if (!qh && !qih)
-+#else /* !IMQ */
-       if (!qh)
-+#endif
-               goto err_unlock;
-       afinfo = nf_get_afinfo(pf);
-@@ -145,6 +180,10 @@ static int __nf_queue(struct sk_buff *sk
-               .indev  = indev,
-               .outdev = outdev,
-               .okfn   = okfn,
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+              .next_outfn = qh ? qh->outfn : NULL,
-+              .next_queuenum = queuenum,
-+#endif
-       };
-       /* If it's going away, ignore hook. */
-@@ -170,8 +209,19 @@ static int __nf_queue(struct sk_buff *sk
-       }
- #endif
-       afinfo->saveroute(skb, entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      if (qih) {
-+              status = qih->outfn(entry, queuenum);
-+              goto imq_skip_queue;
-+      }
-+#endif
-+
-       status = qh->outfn(entry, queuenum);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+imq_skip_queue:
-+#endif
-       rcu_read_unlock();
-       if (status < 0) {
---- /dev/null
-+++ b/net/netfilter/xt_IMQ.c
-@@ -0,0 +1,73 @@
-+/*
-+ * This target marks packets to be enqueued to an imq device
-+ */
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter/x_tables.h>
-+#include <linux/netfilter/xt_IMQ.h>
-+#include <linux/imq.h>
-+
-+static unsigned int imq_target(struct sk_buff *pskb,
-+                              const struct xt_target_param *par)
-+{
-+      const struct xt_imq_info *mr = par->targinfo;
-+
-+      pskb->imq_flags = (mr->todev & IMQ_F_IFMASK) | IMQ_F_ENQUEUE;
-+
-+      return XT_CONTINUE;
-+}
-+
-+static bool imq_checkentry(const struct xt_tgchk_param *par)
-+{
-+      struct xt_imq_info *mr = par->targinfo;
-+
-+      if (mr->todev > IMQ_MAX_DEVS - 1) {
-+              printk(KERN_WARNING
-+                     "IMQ: invalid device specified, highest is %u\n",
-+                     IMQ_MAX_DEVS - 1);
-+              return 0;
-+      }
-+
-+      return 1;
-+}
-+
-+static struct xt_target xt_imq_reg[] __read_mostly = {
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET6,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+};
-+
-+static int __init imq_init(void)
-+{
-+      return xt_register_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+static void __exit imq_fini(void)
-+{
-+      xt_unregister_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+module_init(imq_init);
-+module_exit(imq_fini);
-+
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("ipt_IMQ");
-+MODULE_ALIAS("ip6t_IMQ");
-+
index fc00d15..e05ec77 100644 (file)
@@ -8,7 +8,7 @@
        depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
        depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
-@@ -505,7 +504,6 @@ config NETFILTER_XT_TARGET_SECMARK
+@@ -493,7 +492,6 @@ config NETFILTER_XT_TARGET_SECMARK
  
  config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
  
  config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
index 06b494b..cc35dcf 100644 (file)
@@ -1,6 +1,6 @@
 --- a/include/linux/skbuff.h
 +++ b/include/linux/skbuff.h
 --- a/include/linux/skbuff.h
 +++ b/include/linux/skbuff.h
-@@ -1369,11 +1369,18 @@ static inline int skb_network_offset(con
+@@ -1351,11 +1351,18 @@ static inline int skb_network_offset(con
   *
   * Various parts of the networking layer expect at least 32 bytes of
   * headroom, you should not reduce this.
   *
   * Various parts of the networking layer expect at least 32 bytes of
   * headroom, you should not reduce this.
@@ -19,7 +19,7 @@
  extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
  
  static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
  extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
  
  static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
-@@ -1463,9 +1470,9 @@ static inline void __skb_queue_purge(str
+@@ -1445,9 +1452,9 @@ static inline void __skb_queue_purge(str
  static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
                                              gfp_t gfp_mask)
  {
  static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
                                              gfp_t gfp_mask)
  {
@@ -31,7 +31,7 @@
        return skb;
  }
  
        return skb;
  }
  
-@@ -1538,7 +1545,7 @@ static inline int __skb_cow(struct sk_bu
+@@ -1520,7 +1527,7 @@ static inline int __skb_cow(struct sk_bu
                delta = headroom - skb_headroom(skb);
  
        if (delta || cloned)
                delta = headroom - skb_headroom(skb);
  
        if (delta || cloned)
@@ -42,7 +42,7 @@
  }
 --- a/net/core/skbuff.c
 +++ b/net/core/skbuff.c
  }
 --- a/net/core/skbuff.c
 +++ b/net/core/skbuff.c
-@@ -327,9 +327,9 @@ struct sk_buff *__netdev_alloc_skb(struc
+@@ -250,9 +250,9 @@ struct sk_buff *__netdev_alloc_skb(struc
        int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
        struct sk_buff *skb;
  
        int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
        struct sk_buff *skb;
  
index aac38ff..4031a7e 100644 (file)
@@ -1,6 +1,6 @@
 --- a/include/linux/phy.h
 +++ b/include/linux/phy.h
 --- a/include/linux/phy.h
 +++ b/include/linux/phy.h
-@@ -393,9 +393,18 @@ struct phy_driver {
+@@ -379,9 +379,18 @@ struct phy_driver {
         */
        int (*config_aneg)(struct phy_device *phydev);
  
         */
        int (*config_aneg)(struct phy_device *phydev);
  
@@ -21,7 +21,7 @@
  
 --- a/drivers/net/phy/phy_device.c
 +++ b/drivers/net/phy/phy_device.c
  
 --- a/drivers/net/phy/phy_device.c
 +++ b/drivers/net/phy/phy_device.c
-@@ -695,6 +695,9 @@ int genphy_update_link(struct phy_device
+@@ -590,6 +590,9 @@ int genphy_update_link(struct phy_device
  {
        int status;
  
  {
        int status;
  
index d9d3ce7..caa69d6 100644 (file)
@@ -1,7 +1,7 @@
 --- a/drivers/net/phy/Kconfig
 +++ b/drivers/net/phy/Kconfig
 --- a/drivers/net/phy/Kconfig
 +++ b/drivers/net/phy/Kconfig
-@@ -100,6 +100,10 @@ config IP175C_PHY
-       tristate "Driver for IC+ IP175C/IP178C switches"
+@@ -100,6 +100,10 @@ config IP17XX_PHY
+       tristate "Driver for IC+ IP17xx switches"
        select SWCONFIG
  
 +config AR8216_PHY
        select SWCONFIG
  
 +config AR8216_PHY
@@ -15,7 +15,7 @@
 +++ b/drivers/net/phy/Makefile
 @@ -17,6 +17,7 @@ obj-$(CONFIG_ADM6996_PHY)    += adm6996.o
  obj-$(CONFIG_MVSWITCH_PHY)    += mvswitch.o
 +++ b/drivers/net/phy/Makefile
 @@ -17,6 +17,7 @@ obj-$(CONFIG_ADM6996_PHY)    += adm6996.o
  obj-$(CONFIG_MVSWITCH_PHY)    += mvswitch.o
- obj-$(CONFIG_IP175C_PHY)      += ip175c.o
+ obj-$(CONFIG_IP17XX_PHY)      += ip17xx.o
  obj-$(CONFIG_REALTEK_PHY)     += realtek.o
 +obj-$(CONFIG_AR8216_PHY)      += ar8216.o
  obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
  obj-$(CONFIG_REALTEK_PHY)     += realtek.o
 +obj-$(CONFIG_AR8216_PHY)      += ar8216.o
  obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
index bfebbcf..259f7ec 100644 (file)
@@ -14,7 +14,7 @@
 --- a/drivers/net/phy/Makefile
 +++ b/drivers/net/phy/Makefile
 @@ -18,6 +18,7 @@ obj-$(CONFIG_MVSWITCH_PHY)   += mvswitch.o
 --- a/drivers/net/phy/Makefile
 +++ b/drivers/net/phy/Makefile
 @@ -18,6 +18,7 @@ obj-$(CONFIG_MVSWITCH_PHY)   += mvswitch.o
- obj-$(CONFIG_IP175C_PHY)      += ip175c.o
+ obj-$(CONFIG_IP17XX_PHY)      += ip17xx.o
  obj-$(CONFIG_REALTEK_PHY)     += realtek.o
  obj-$(CONFIG_AR8216_PHY)      += ar8216.o
 +obj-$(CONFIG_RTL8306_PHY)     += rtl8306.o
  obj-$(CONFIG_REALTEK_PHY)     += realtek.o
  obj-$(CONFIG_AR8216_PHY)      += ar8216.o
 +obj-$(CONFIG_RTL8306_PHY)     += rtl8306.o
index 4ce0520..62a6430 100644 (file)
@@ -32,7 +32,7 @@
  endif # PHYLIB
 --- a/drivers/net/phy/Makefile
 +++ b/drivers/net/phy/Makefile
  endif # PHYLIB
 --- a/drivers/net/phy/Makefile
 +++ b/drivers/net/phy/Makefile
-@@ -19,6 +19,9 @@ obj-$(CONFIG_IP175C_PHY)     += ip175c.o
+@@ -19,6 +19,9 @@ obj-$(CONFIG_IP17XX_PHY)     += ip17xx.o
  obj-$(CONFIG_REALTEK_PHY)     += realtek.o
  obj-$(CONFIG_AR8216_PHY)      += ar8216.o
  obj-$(CONFIG_RTL8306_PHY)     += rtl8306.o
  obj-$(CONFIG_REALTEK_PHY)     += realtek.o
  obj-$(CONFIG_AR8216_PHY)      += ar8216.o
  obj-$(CONFIG_RTL8306_PHY)     += rtl8306.o
index 202f998..581105c 100644 (file)
@@ -11,7 +11,7 @@
  #  define LL_MAX_HEADER 96
 --- a/include/linux/skbuff.h
 +++ b/include/linux/skbuff.h
  #  define LL_MAX_HEADER 96
 --- a/include/linux/skbuff.h
 +++ b/include/linux/skbuff.h
-@@ -387,7 +387,7 @@ struct sk_buff {
+@@ -378,7 +378,7 @@ struct sk_buff {
  #ifdef CONFIG_IPV6_NDISC_NODETYPE
        __u8                    ndisc_nodetype:2;
  #endif
  #ifdef CONFIG_IPV6_NDISC_NODETYPE
        __u8                    ndisc_nodetype:2;
  #endif
index ff23af8..c1bc449 100644 (file)
@@ -1,7 +1,5 @@
-Index: linux-2.6.30.10/drivers/char/random.c
-===================================================================
---- linux-2.6.30.10.orig/drivers/char/random.c 2009-12-04 07:00:07.000000000 +0100
-+++ linux-2.6.30.10/drivers/char/random.c      2010-05-15 15:44:19.000000000 +0200
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
 @@ -129,6 +129,9 @@
   *                                unsigned int value);
   *    void add_interrupt_randomness(int irq);
 @@ -129,6 +129,9 @@
   *                                unsigned int value);
   *    void add_interrupt_randomness(int irq);
@@ -26,7 +24,7 @@ Index: linux-2.6.30.10/drivers/char/random.c
   * All of these routines try to estimate how many bits of randomness a
   * particular randomness source.  They do this by keeping track of the
   * first and second order deltas of the event timings.
   * All of these routines try to estimate how many bits of randomness a
   * particular randomness source.  They do this by keeping track of the
   * first and second order deltas of the event timings.
-@@ -712,6 +722,61 @@
+@@ -712,6 +722,61 @@ void add_disk_randomness(struct gendisk 
  }
  #endif
  
  }
  #endif
  
@@ -88,11 +86,9 @@ Index: linux-2.6.30.10/drivers/char/random.c
  #define EXTRACT_SIZE 10
  
  /*********************************************************************
  #define EXTRACT_SIZE 10
  
  /*********************************************************************
-Index: linux-2.6.30.10/fs/fcntl.c
-===================================================================
---- linux-2.6.30.10.orig/fs/fcntl.c    2009-12-04 07:00:07.000000000 +0100
-+++ linux-2.6.30.10/fs/fcntl.c 2010-05-15 15:44:19.000000000 +0200
-@@ -142,6 +142,7 @@
+--- a/fs/fcntl.c
++++ b/fs/fcntl.c
+@@ -142,6 +142,7 @@ SYSCALL_DEFINE1(dup, unsigned int, filde
        }
        return ret;
  }
        }
        return ret;
  }
@@ -100,10 +96,8 @@ Index: linux-2.6.30.10/fs/fcntl.c
  
  #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
  
  
  #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
  
-Index: linux-2.6.30.10/include/linux/miscdevice.h
-===================================================================
---- linux-2.6.30.10.orig/include/linux/miscdevice.h    2009-12-04 07:00:07.000000000 +0100
-+++ linux-2.6.30.10/include/linux/miscdevice.h 2010-05-15 15:44:19.000000000 +0200
+--- a/include/linux/miscdevice.h
++++ b/include/linux/miscdevice.h
 @@ -12,6 +12,7 @@
  #define APOLLO_MOUSE_MINOR    7
  #define PC110PAD_MINOR                9
 @@ -12,6 +12,7 @@
  #define APOLLO_MOUSE_MINOR    7
  #define PC110PAD_MINOR                9
@@ -112,10 +106,8 @@ Index: linux-2.6.30.10/include/linux/miscdevice.h
  #define WATCHDOG_MINOR                130     /* Watchdog timer     */
  #define TEMP_MINOR            131     /* Temperature Sensor */
  #define RTC_MINOR             135
  #define WATCHDOG_MINOR                130     /* Watchdog timer     */
  #define TEMP_MINOR            131     /* Temperature Sensor */
  #define RTC_MINOR             135
-Index: linux-2.6.30.10/include/linux/random.h
-===================================================================
---- linux-2.6.30.10.orig/include/linux/random.h        2009-12-04 07:00:07.000000000 +0100
-+++ linux-2.6.30.10/include/linux/random.h     2010-05-15 15:44:19.000000000 +0200
+--- a/include/linux/random.h
++++ b/include/linux/random.h
 @@ -9,6 +9,7 @@
  
  #include <linux/types.h>
 @@ -9,6 +9,7 @@
  
  #include <linux/types.h>
@@ -155,7 +147,7 @@ Index: linux-2.6.30.10/include/linux/random.h
  struct rand_pool_info {
        int     entropy_count;
        int     buf_size;
  struct rand_pool_info {
        int     entropy_count;
        int     buf_size;
-@@ -50,6 +75,10 @@
+@@ -50,6 +75,10 @@ extern void add_input_randomness(unsigne
                                 unsigned int value);
  extern void add_interrupt_randomness(int irq);
  
                                 unsigned int value);
  extern void add_interrupt_randomness(int irq);
  
diff --git a/target/linux/generic/patches-2.6.31/150-netfilter_imq.patch b/target/linux/generic/patches-2.6.31/150-netfilter_imq.patch
deleted file mode 100644 (file)
index ffe80b3..0000000
+++ /dev/null
@@ -1,1260 +0,0 @@
---- /dev/null
-+++ b/drivers/net/imq.c
-@@ -0,0 +1,571 @@
-+/*
-+ *             Pseudo-driver for the intermediate queue device.
-+ *
-+ *             This program is free software; you can redistribute it and/or
-+ *             modify it under the terms of the GNU General Public License
-+ *             as published by the Free Software Foundation; either version
-+ *             2 of the License, or (at your option) any later version.
-+ *
-+ * Authors:    Patrick McHardy, <kaber@trash.net>
-+ *
-+ *            The first version was written by Martin Devera, <devik@cdi.cz>
-+ *
-+ * Credits:    Jan Rafaj <imq2t@cedric.vabo.cz>
-+ *              - Update patch to 2.4.21
-+ *             Sebastian Strollo <sstrollo@nortelnetworks.com>
-+ *              - Fix "Dead-loop on netdevice imq"-issue
-+ *             Marcel Sebek <sebek64@post.cz>
-+ *              - Update to 2.6.2-rc1
-+ *
-+ *           After some time of inactivity there is a group taking care
-+ *           of IMQ again: http://www.linuximq.net
-+ *
-+ *
-+ *           2004/06/30 - New version of IMQ patch to kernels <=2.6.7
-+ *             including the following changes:
-+ *
-+ *           - Correction of ipv6 support "+"s issue (Hasso Tepper)
-+ *           - Correction of imq_init_devs() issue that resulted in
-+ *           kernel OOPS unloading IMQ as module (Norbert Buchmuller)
-+ *           - Addition of functionality to choose number of IMQ devices
-+ *           during kernel config (Andre Correa)
-+ *           - Addition of functionality to choose how IMQ hooks on
-+ *           PRE and POSTROUTING (after or before NAT) (Andre Correa)
-+ *           - Cosmetic corrections (Norbert Buchmuller) (Andre Correa)
-+ *
-+ *
-+ *             2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were
-+ *             released with almost no problems. 2.6.14-x was released
-+ *             with some important changes: nfcache was removed; After
-+ *             some weeks of trouble we figured out that some IMQ fields
-+ *             in skb were missing in skbuff.c - skb_clone and copy_skb_header.
-+ *             These functions are correctly patched by this new patch version.
-+ *
-+ *             Thanks for all who helped to figure out all the problems with
-+ *             2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX,
-+ *             Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully
-+ *             I didn't forget anybody). I apologize again for my lack of time.
-+ *
-+ *
-+ *             2008/06/17 - 2.6.25 - Changed imq.c to use qdisc_run() instead
-+ *             of qdisc_restart() and moved qdisc_run() to tasklet to avoid
-+ *             recursive locking. New initialization routines to fix 'rmmod' not
-+ *             working anymore. Used code from ifb.c. (Jussi Kivilinna)
-+ *
-+ *             2008/08/06 - 2.6.26 - (JK)
-+ *              - Replaced tasklet with 'netif_schedule()'.
-+ *              - Cleaned up and added comments for imq_nf_queue().
-+ *
-+ *             2009/04/12
-+ *              - Add skb_save_cb/skb_restore_cb helper functions for backuping
-+ *                control buffer. This is needed because qdisc-layer on kernels
-+ *                2.6.27 and newer overwrite control buffer. (Jussi Kivilinna)
-+ *              - Add better locking for IMQ device. Hopefully this will solve
-+ *                SMP issues. (Jussi Kivilinna)
-+ *              - Port to 2.6.27
-+ *              - Port to 2.6.28
-+ *              - Port to 2.6.29 + fix rmmod not working
-+ *
-+ *             2009/04/20 - (Jussi Kivilinna)
-+ *              - Use netdevice feature flags to avoid extra packet handling
-+ *                by core networking layer and possibly increase performance.
-+ *
-+ *           Also, many thanks to pablo Sebastian Greco for making the initial
-+ *           patch and to those who helped the testing.
-+ *
-+ *             More info at: http://www.linuximq.net/ (Andre Correa)
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/moduleparam.h>
-+#include <linux/list.h>
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/if_arp.h>
-+#include <linux/netfilter.h>
-+#include <linux/netfilter_ipv4.h>
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      #include <linux/netfilter_ipv6.h>
-+#endif
-+#include <linux/imq.h>
-+#include <net/pkt_sched.h>
-+#include <net/netfilter/nf_queue.h>
-+
-+static nf_hookfn imq_nf_hook;
-+
-+static struct nf_hook_ops imq_ingress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP_PRI_LAST
-+#else
-+      .priority       = NF_IP_PRI_NAT_SRC - 1
-+#endif
-+};
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+static struct nf_hook_ops imq_ingress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP6_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP6_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP6_PRI_LAST
-+#else
-+      .priority       = NF_IP6_PRI_NAT_SRC - 1
-+#endif
-+};
-+#endif
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS;
-+#else
-+static unsigned int numdevs = IMQ_MAX_DEVS;
-+#endif
-+
-+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;
-+
-+      if (entry) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree(entry);
-+      }
-+
-+      skb_restore_cb(skb); /* kfree backup */
-+}
-+
-+static void imq_nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              spin_lock_bh(&imq_nf_queue_lock);
-+              nf_reinject(entry, verdict);
-+              spin_unlock_bh(&imq_nf_queue_lock);
-+              return;
-+      }
-+
-+      rcu_read_lock();
-+      local_bh_disable();
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      local_bh_enable();
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+
-+      rcu_read_unlock();
-+}
-+
-+static int imq_dev_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+      dev->stats.tx_bytes += skb->len;
-+      dev->stats.tx_packets++;
-+
-+      skb->imq_flags = 0;
-+      skb->destructor = NULL;
-+
-+      skb_restore_cb(skb); /* restore skb->cb */
-+
-+      dev->trans_start = jiffies;
-+      imq_nf_reinject(skb->nf_queue_entry, NF_ACCEPT);
-+      return 0;
-+}
-+
-+static int imq_nf_queue(struct nf_queue_entry *entry, unsigned queue_num)
-+{
-+      struct net_device *dev;
-+      struct sk_buff *skb_orig, *skb, *skb_shared;
-+      struct Qdisc *q;
-+      struct netdev_queue *txq;
-+      int users, index;
-+      int retval = -EINVAL;
-+
-+      index = entry->skb->imq_flags & IMQ_F_IFMASK;
-+      if (unlikely(index > numdevs - 1)) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING
-+                             "IMQ: invalid device specified, highest is %u\n",
-+                             numdevs - 1);
-+              retval = -EINVAL;
-+              goto out;
-+      }
-+
-+      /* check for imq device by index from cache */
-+      dev = imq_devs_cache[index];
-+      if (unlikely(!dev)) {
-+              char buf[8];
-+
-+              /* get device by name and cache result */
-+              snprintf(buf, sizeof(buf), "imq%d", index);
-+              dev = dev_get_by_name(&init_net, buf);
-+              if (!dev) {
-+                      /* not found ?!*/
-+                      BUG();
-+                      retval = -ENODEV;
-+                      goto out;
-+              }
-+
-+              imq_devs_cache[index] = dev;
-+              dev_put(dev);
-+      }
-+
-+      if (unlikely(!(dev->flags & IFF_UP))) {
-+              entry->skb->imq_flags = 0;
-+              imq_nf_reinject(entry, NF_ACCEPT);
-+              retval = 0;
-+              goto out;
-+      }
-+      dev->last_rx = jiffies;
-+
-+      skb = entry->skb;
-+      skb_orig = NULL;
-+
-+      /* skb has owner? => make clone */
-+      if (unlikely(skb->destructor)) {
-+              skb_orig = skb;
-+              skb = skb_clone(skb, GFP_ATOMIC);
-+              if (!skb) {
-+                      retval = -ENOMEM;
-+                      goto out;
-+              }
-+              entry->skb = skb;
-+      }
-+
-+      skb->nf_queue_entry = entry;
-+
-+      dev->stats.rx_bytes += skb->len;
-+      dev->stats.rx_packets++;
-+
-+      txq = dev_pick_tx(dev, skb);
-+
-+      q = rcu_dereference(txq->qdisc);
-+      if (unlikely(!q->enqueue))
-+              goto packet_not_eaten_by_imq_dev;
-+
-+      spin_lock_bh(qdisc_lock(q));
-+
-+      users = atomic_read(&skb->users);
-+
-+      skb_shared = skb_get(skb); /* increase reference count by one */
-+      skb_save_cb(skb_shared); /* backup skb->cb, as qdisc layer will
-+                                      overwrite it */
-+      qdisc_enqueue_root(skb_shared, q); /* might kfree_skb */
-+
-+      if (likely(atomic_read(&skb_shared->users) == users + 1)) {
-+              kfree_skb(skb_shared); /* decrease reference count by one */
-+
-+              skb->destructor = &imq_skb_destructor;
-+
-+              /* cloned? */
-+              if (skb_orig)
-+                      kfree_skb(skb_orig); /* free original */
-+
-+              spin_unlock_bh(qdisc_lock(q));
-+
-+              /* schedule qdisc dequeue */
-+              __netif_schedule(q);
-+
-+              retval = 0;
-+              goto out;
-+      } else {
-+              skb_restore_cb(skb_shared); /* restore skb->cb */
-+              /* qdisc dropped packet and decreased skb reference count of
-+               * skb, so we don't really want to and try refree as that would
-+               * actually destroy the skb. */
-+              spin_unlock_bh(qdisc_lock(q));
-+              goto packet_not_eaten_by_imq_dev;
-+      }
-+
-+packet_not_eaten_by_imq_dev:
-+      /* cloned? restore original */
-+      if (skb_orig) {
-+              kfree_skb(skb);
-+              entry->skb = skb_orig;
-+      }
-+      retval = -1;
-+out:
-+      return retval;
-+}
-+
-+static struct nf_queue_handler nfqh = {
-+      .name  = "imq",
-+      .outfn = imq_nf_queue,
-+};
-+
-+static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff *pskb,
-+                              const struct net_device *indev,
-+                              const struct net_device *outdev,
-+                              int (*okfn)(struct sk_buff *))
-+{
-+      if (pskb->imq_flags & IMQ_F_ENQUEUE)
-+              return NF_QUEUE;
-+
-+      return NF_ACCEPT;
-+}
-+
-+static int imq_close(struct net_device *dev)
-+{
-+      netif_stop_queue(dev);
-+      return 0;
-+}
-+
-+static int imq_open(struct net_device *dev)
-+{
-+      netif_start_queue(dev);
-+      return 0;
-+}
-+
-+static const struct net_device_ops imq_netdev_ops = {
-+      .ndo_open               = imq_open,
-+      .ndo_stop               = imq_close,
-+      .ndo_start_xmit         = imq_dev_xmit,
-+      .ndo_get_stats          = imq_get_stats,
-+};
-+
-+static void imq_setup(struct net_device *dev)
-+{
-+      dev->netdev_ops         = &imq_netdev_ops;
-+      dev->type               = ARPHRD_VOID;
-+      dev->mtu                = 16000;
-+      dev->tx_queue_len       = 11000;
-+      dev->flags              = IFF_NOARP;
-+      dev->features           = NETIF_F_SG | NETIF_F_FRAGLIST |
-+                                NETIF_F_GSO | NETIF_F_HW_CSUM |
-+                                NETIF_F_HIGHDMA;
-+}
-+
-+static int imq_validate(struct nlattr *tb[], struct nlattr *data[])
-+{
-+      int ret = 0;
-+
-+      if (tb[IFLA_ADDRESS]) {
-+              if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
-+                      ret = -EINVAL;
-+                      goto end;
-+              }
-+              if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) {
-+                      ret = -EADDRNOTAVAIL;
-+                      goto end;
-+              }
-+      }
-+      return 0;
-+end:
-+      printk(KERN_WARNING "IMQ: imq_validate failed (%d)\n", ret);
-+      return ret;
-+}
-+
-+static struct rtnl_link_ops imq_link_ops __read_mostly = {
-+      .kind           = "imq",
-+      .priv_size      = 0,
-+      .setup          = imq_setup,
-+      .validate       = imq_validate,
-+};
-+
-+static int __init imq_init_hooks(void)
-+{
-+      int err;
-+
-+      nf_register_queue_imq_handler(&nfqh);
-+
-+      err = nf_register_hook(&imq_ingress_ipv4);
-+      if (err)
-+              goto err1;
-+
-+      err = nf_register_hook(&imq_egress_ipv4);
-+      if (err)
-+              goto err2;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      err = nf_register_hook(&imq_ingress_ipv6);
-+      if (err)
-+              goto err3;
-+
-+      err = nf_register_hook(&imq_egress_ipv6);
-+      if (err)
-+              goto err4;
-+#endif
-+
-+      return 0;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+err4:
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+err3:
-+      nf_unregister_hook(&imq_egress_ipv4);
-+#endif
-+err2:
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+err1:
-+      nf_unregister_queue_imq_handler();
-+      return err;
-+}
-+
-+static int __init imq_init_one(int index)
-+{
-+      struct net_device *dev;
-+      int ret;
-+
-+      dev = alloc_netdev(0, "imq%d", imq_setup);
-+      if (!dev)
-+              return -ENOMEM;
-+
-+      ret = dev_alloc_name(dev, dev->name);
-+      if (ret < 0)
-+              goto fail;
-+
-+      dev->rtnl_link_ops = &imq_link_ops;
-+      ret = register_netdevice(dev);
-+      if (ret < 0)
-+              goto fail;
-+
-+      return 0;
-+fail:
-+      free_netdev(dev);
-+      return ret;
-+}
-+
-+static int __init imq_init_devs(void)
-+{
-+      int err, i;
-+
-+      if (numdevs < 1 || numdevs > IMQ_MAX_DEVS) {
-+              printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n",
-+                     IMQ_MAX_DEVS);
-+              return -EINVAL;
-+      }
-+
-+      rtnl_lock();
-+      err = __rtnl_link_register(&imq_link_ops);
-+
-+      for (i = 0; i < numdevs && !err; i++)
-+              err = imq_init_one(i);
-+
-+      if (err) {
-+              __rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+      }
-+      rtnl_unlock();
-+
-+      return err;
-+}
-+
-+static int __init imq_init_module(void)
-+{
-+      int err;
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS > 16);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS < 2);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS - 1 > IMQ_F_IFMASK);
-+#endif
-+
-+      err = imq_init_devs();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_devs(net)\n");
-+              return err;
-+      }
-+
-+      err = imq_init_hooks();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n");
-+              rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+              return err;
-+      }
-+
-+      printk(KERN_INFO "IMQ driver loaded successfully.\n");
-+
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n");
-+#endif
-+#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n");
-+#endif
-+
-+      return 0;
-+}
-+
-+static void __exit imq_unhook(void)
-+{
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+      nf_unregister_hook(&imq_egress_ipv6);
-+#endif
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+      nf_unregister_hook(&imq_egress_ipv4);
-+
-+      nf_unregister_queue_imq_handler();
-+}
-+
-+static void __exit imq_cleanup_devs(void)
-+{
-+      rtnl_link_unregister(&imq_link_ops);
-+      memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+}
-+
-+static void __exit imq_exit_module(void)
-+{
-+      imq_unhook();
-+      imq_cleanup_devs();
-+      printk(KERN_INFO "IMQ driver unloaded successfully.\n");
-+}
-+
-+module_init(imq_init_module);
-+module_exit(imq_exit_module);
-+
-+module_param(numdevs, int, 0);
-+MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will "
-+                      "be created)");
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See "
-+                      "http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS_RTNL_LINK("imq");
-+
---- a/drivers/net/Kconfig
-+++ b/drivers/net/Kconfig
-@@ -109,6 +109,129 @@ config EQUALIZER
-         To compile this driver as a module, choose M here: the module
-         will be called eql.  If unsure, say N.
-+config IMQ
-+      tristate "IMQ (intermediate queueing device) support"
-+      depends on NETDEVICES && NETFILTER
-+      ---help---
-+        The IMQ device(s) is used as placeholder for QoS queueing
-+        disciplines. Every packet entering/leaving the IP stack can be
-+        directed through the IMQ device where it's enqueued/dequeued to the
-+        attached qdisc. This allows you to treat network devices as classes
-+        and distribute bandwidth among them. Iptables is used to specify
-+        through which IMQ device, if any, packets travel.
-+
-+        More information at: http://www.linuximq.net/
-+
-+        To compile this driver as a module, choose M here: the module
-+        will be called imq.  If unsure, say N.
-+
-+choice
-+      prompt "IMQ behavior (PRE/POSTROUTING)"
-+      depends on IMQ
-+      default IMQ_BEHAVIOR_AB
-+      help
-+
-+              This settings defines how IMQ behaves in respect to its
-+              hooking in PREROUTING and POSTROUTING.
-+
-+              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
-+
-+              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.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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 settings defines how many IMQ devices will be
-+              created.
-+
-+              The default value is 16.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              If not sure leave the default settings alone.
-+
- config TUN
-       tristate "Universal TUN/TAP device driver support"
-       select CRC32
---- a/drivers/net/Makefile
-+++ b/drivers/net/Makefile
-@@ -160,6 +160,7 @@ obj-$(CONFIG_SLHC) += slhc.o
- obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o
- obj-$(CONFIG_DUMMY) += dummy.o
-+obj-$(CONFIG_IMQ) += imq.o
- obj-$(CONFIG_IFB) += ifb.o
- obj-$(CONFIG_MACVLAN) += macvlan.o
- obj-$(CONFIG_DE600) += de600.o
---- /dev/null
-+++ b/include/linux/imq.h
-@@ -0,0 +1,13 @@
-+#ifndef _IMQ_H
-+#define _IMQ_H
-+
-+/* IFMASK (16 device indexes, 0 to 15) and flag(s) fit in 5 bits */
-+#define IMQ_F_BITS    5
-+
-+#define IMQ_F_IFMASK  0x0f
-+#define IMQ_F_ENQUEUE 0x10
-+
-+#define IMQ_MAX_DEVS  (IMQ_F_IFMASK + 1)
-+
-+#endif /* _IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv4/ipt_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IPT_IMQ_H
-+#define _IPT_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ipt_imq_info xt_imq_info
-+
-+#endif /* _IPT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv6/ip6t_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IP6T_IMQ_H
-+#define _IP6T_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ip6t_imq_info xt_imq_info
-+
-+#endif /* _IP6T_IMQ_H */
-+
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -29,6 +29,9 @@
- #include <linux/rcupdate.h>
- #include <linux/dmaengine.h>
- #include <linux/hrtimer.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- /* Don't change this without changing skb_csum_unnecessary! */
- #define CHECKSUM_NONE 0
-@@ -331,6 +334,9 @@ struct sk_buff {
-        * first. This is owned by whoever has the skb queued ATM.
-        */
-       char                    cb[48];
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      void                    *cb_next;
-+#endif
-       unsigned int            len,
-                               data_len;
-@@ -363,6 +369,9 @@ struct sk_buff {
-       struct nf_conntrack     *nfct;
-       struct sk_buff          *nfct_reasm;
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      struct nf_queue_entry   *nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       struct nf_bridge_info   *nf_bridge;
- #endif
-@@ -386,6 +395,9 @@ struct sk_buff {
-       kmemcheck_bitfield_end(flags2);
-       /* 0/13/14 bit hole */
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      __u8                    imq_flags:IMQ_F_BITS;
-+#endif
- #ifdef CONFIG_NET_DMA
-       dma_cookie_t            dma_cookie;
-@@ -441,6 +453,12 @@ static inline struct rtable *skb_rtable(
-       return (struct rtable *)skb_dst(skb);
- }
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern int skb_save_cb(struct sk_buff *skb);
-+extern int skb_restore_cb(struct sk_buff *skb);
-+#endif
-+
- extern void kfree_skb(struct sk_buff *skb);
- extern void consume_skb(struct sk_buff *skb);
- extern void          __kfree_skb(struct sk_buff *skb);
-@@ -1976,6 +1994,10 @@ static inline void __nf_copy(struct sk_b
-       dst->nfct_reasm = src->nfct_reasm;
-       nf_conntrack_get_reasm(src->nfct_reasm);
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      dst->imq_flags = src->imq_flags;
-+      dst->nf_queue_entry = src->nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       dst->nf_bridge  = src->nf_bridge;
-       nf_bridge_get(src->nf_bridge);
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -96,6 +96,9 @@
- #include <net/net_namespace.h>
- #include <net/sock.h>
- #include <linux/rtnetlink.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- #include <linux/proc_fs.h>
- #include <linux/seq_file.h>
- #include <linux/stat.h>
-@@ -1687,7 +1690,11 @@ int dev_hard_start_xmit(struct sk_buff *
-       int rc;
-       if (likely(!skb->next)) {
--              if (!list_empty(&ptype_all))
-+              if (!list_empty(&ptype_all)
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+                  && !(skb->imq_flags & IMQ_F_ENQUEUE)
-+#endif
-+                  )
-                       dev_queue_xmit_nit(skb, dev);
-               if (netif_needs_gso(dev, skb)) {
-@@ -1772,8 +1779,7 @@ u16 skb_tx_hash(const struct net_device
- }
- EXPORT_SYMBOL(skb_tx_hash);
--static struct netdev_queue *dev_pick_tx(struct net_device *dev,
--                                      struct sk_buff *skb)
-+struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb)
- {
-       const struct net_device_ops *ops = dev->netdev_ops;
-       u16 queue_index = 0;
-@@ -1786,6 +1792,7 @@ static struct netdev_queue *dev_pick_tx(
-       skb_set_queue_mapping(skb, queue_index);
-       return netdev_get_tx_queue(dev, queue_index);
- }
-+EXPORT_SYMBOL(dev_pick_tx);
- /**
-  *    dev_queue_xmit - transmit a buffer
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1102,6 +1102,7 @@ extern int               dev_alloc_name(struct net_de
- extern int            dev_open(struct net_device *dev);
- extern int            dev_close(struct net_device *dev);
- extern void           dev_disable_lro(struct net_device *dev);
-+extern struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb);
- extern int            dev_queue_xmit(struct sk_buff *skb);
- extern int            register_netdevice(struct net_device *dev);
- extern void           unregister_netdevice(struct net_device *dev);
---- /dev/null
-+++ b/include/linux/netfilter/xt_IMQ.h
-@@ -0,0 +1,9 @@
-+#ifndef _XT_IMQ_H
-+#define _XT_IMQ_H
-+
-+struct xt_imq_info {
-+      unsigned int todev;     /* target imq device */
-+};
-+
-+#endif /* _XT_IMQ_H */
-+
---- a/include/net/netfilter/nf_queue.h
-+++ b/include/net/netfilter/nf_queue.h
-@@ -13,6 +13,12 @@ struct nf_queue_entry {
-       struct net_device       *indev;
-       struct net_device       *outdev;
-       int                     (*okfn)(struct sk_buff *);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      int                     (*next_outfn)(struct nf_queue_entry *entry,
-+                                            unsigned int queuenum);
-+      unsigned int            next_queuenum;
-+#endif
- };
- #define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry))
-@@ -30,5 +36,11 @@ extern int nf_unregister_queue_handler(u
-                                      const struct nf_queue_handler *qh);
- extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
- extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
-+extern void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern void nf_register_queue_imq_handler(const struct nf_queue_handler *qh);
-+extern void nf_unregister_queue_imq_handler(void);
-+#endif
- #endif /* _NF_QUEUE_H */
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -72,6 +72,9 @@
- static struct kmem_cache *skbuff_head_cache __read_mostly;
- static struct kmem_cache *skbuff_fclone_cache __read_mostly;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static struct kmem_cache *skbuff_cb_store_cache __read_mostly;
-+#endif
- static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
-                                 struct pipe_buffer *buf)
-@@ -91,6 +94,80 @@ static int sock_pipe_buf_steal(struct pi
-       return 1;
- }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+/* Control buffer save/restore for IMQ devices */
-+struct skb_cb_table {
-+      void                    *cb_next;
-+      atomic_t                refcnt;
-+      char                    cb[48];
-+};
-+
-+static DEFINE_SPINLOCK(skb_cb_store_lock);
-+
-+int skb_save_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      next = kmem_cache_alloc(skbuff_cb_store_cache, GFP_ATOMIC);
-+      if (!next)
-+              return -ENOMEM;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(next->cb, skb->cb, sizeof(skb->cb));
-+      next->cb_next = skb->cb_next;
-+
-+      atomic_set(&next->refcnt, 1);
-+
-+      skb->cb_next = next;
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_save_cb);
-+
-+int skb_restore_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      if (!skb->cb_next)
-+              return 0;
-+
-+      next = skb->cb_next;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(skb->cb, next->cb, sizeof(skb->cb));
-+      skb->cb_next = next->cb_next;
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      if (atomic_dec_and_test(&next->refcnt)) {
-+              kmem_cache_free(skbuff_cb_store_cache, next);
-+      }
-+
-+      spin_unlock(&skb_cb_store_lock);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_restore_cb);
-+
-+static void skb_copy_stored_cb(struct sk_buff *new, struct sk_buff *old)
-+{
-+      struct skb_cb_table *next;
-+
-+      if (!old->cb_next) {
-+              new->cb_next = 0;
-+              return;
-+      }
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      next = old->cb_next;
-+      atomic_inc(&next->refcnt);
-+      new->cb_next = next;
-+
-+      spin_unlock(&skb_cb_store_lock);
-+}
-+#endif
- /* Pipe buffer operations for a socket. */
- static struct pipe_buf_operations sock_pipe_buf_ops = {
-@@ -398,6 +475,15 @@ static void skb_release_head_state(struc
-               WARN_ON(in_irq());
-               skb->destructor(skb);
-       }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      /* This should not happen. When it does, avoid memleak by restoring
-+      the chain of cb-backups. */
-+      while(skb->cb_next != NULL) {
-+              printk(KERN_WARNING "kfree_skb: skb->cb_next: %08x\n",
-+                      skb->cb_next);
-+              skb_restore_cb(skb);
-+      }
-+#endif
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-       nf_conntrack_put(skb->nfct);
-       nf_conntrack_put_reasm(skb->nfct_reasm);
-@@ -535,6 +621,9 @@ static void __copy_skb_header(struct sk_
-       new->sp                 = secpath_get(old->sp);
- #endif
-       memcpy(new->cb, old->cb, sizeof(old->cb));
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+   skb_copy_stored_cb(new, old);
-+#endif
-       new->csum               = old->csum;
-       new->local_df           = old->local_df;
-       new->pkt_type           = old->pkt_type;
-@@ -2779,6 +2868,13 @@ void __init skb_init(void)
-                                               0,
-                                               SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-                                               NULL);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skbuff_cb_store_cache = kmem_cache_create("skbuff_cb_store_cache",
-+                                                sizeof(struct skb_cb_table),
-+                                                0,
-+                                                SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-+                                                NULL);
-+#endif
- }
- /**
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -396,6 +396,18 @@ config NETFILTER_XT_TARGET_LED
-         For more information on the LEDs available on your system, see
-         Documentation/leds-class.txt
-+config NETFILTER_XT_TARGET_IMQ
-+        tristate '"IMQ" target support'
-+      depends on NETFILTER_XTABLES
-+      depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+      select IMQ
-+      default m if NETFILTER_ADVANCED=n
-+        help
-+          This option adds a `IMQ' target which is used to specify if and
-+          to which imq device packets should get enqueued/dequeued.
-+
-+          To compile it as a module, choose M here.  If unsure, say N.
-+
- config NETFILTER_XT_TARGET_MARK
-       tristate '"MARK" target support'
-       default m if NETFILTER_ADVANCED=n
---- a/net/netfilter/Makefile
-+++ b/net/netfilter/Makefile
-@@ -46,6 +46,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMAR
- obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
-+obj-$(CONFIG_NETFILTER_XT_TARGET_IMQ) += xt_IMQ.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
---- a/net/netfilter/nf_queue.c
-+++ b/net/netfilter/nf_queue.c
-@@ -20,6 +20,26 @@ static const struct nf_queue_handler *qu
- static DEFINE_MUTEX(queue_handler_mutex);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static const struct nf_queue_handler *queue_imq_handler;
-+
-+void nf_register_queue_imq_handler(const struct nf_queue_handler *qh)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, qh);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_register_queue_imq_handler);
-+
-+void nf_unregister_queue_imq_handler(void)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, NULL);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_unregister_queue_imq_handler);
-+#endif
-+
- /* return EBUSY when somebody else is registered, return EEXIST if the
-  * same handler is registered, return 0 in case of success. */
- int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
-@@ -80,7 +100,7 @@ void nf_unregister_queue_handlers(const
- }
- EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);
--static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
-+void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
- {
-       /* Release those devices we held, or Alexey will kill me. */
-       if (entry->indev)
-@@ -100,6 +120,7 @@ static void nf_queue_entry_release_refs(
-       /* Drop reference to owner of hook which queued us. */
-       module_put(entry->elem->owner);
- }
-+EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
- /*
-  * Any packet that leaves via this function must come back
-@@ -121,12 +142,26 @@ static int __nf_queue(struct sk_buff *sk
- #endif
-       const struct nf_afinfo *afinfo;
-       const struct nf_queue_handler *qh;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      const struct nf_queue_handler *qih = NULL;
-+#endif
-       /* QUEUE == DROP if noone is waiting, to be safe. */
-       rcu_read_lock();
-       qh = rcu_dereference(queue_handler[pf]);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      if (pf == PF_INET || pf == PF_INET6)
-+#else
-+      if (pf == PF_INET)
-+#endif
-+              qih = rcu_dereference(queue_imq_handler);
-+
-+      if (!qh && !qih)
-+#else /* !IMQ */
-       if (!qh)
-+#endif
-               goto err_unlock;
-       afinfo = nf_get_afinfo(pf);
-@@ -145,6 +180,10 @@ static int __nf_queue(struct sk_buff *sk
-               .indev  = indev,
-               .outdev = outdev,
-               .okfn   = okfn,
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+              .next_outfn = qh ? qh->outfn : NULL,
-+              .next_queuenum = queuenum,
-+#endif
-       };
-       /* If it's going away, ignore hook. */
-@@ -170,8 +209,19 @@ static int __nf_queue(struct sk_buff *sk
-       }
- #endif
-       afinfo->saveroute(skb, entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      if (qih) {
-+              status = qih->outfn(entry, queuenum);
-+              goto imq_skip_queue;
-+      }
-+#endif
-+
-       status = qh->outfn(entry, queuenum);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+imq_skip_queue:
-+#endif
-       rcu_read_unlock();
-       if (status < 0) {
---- /dev/null
-+++ b/net/netfilter/xt_IMQ.c
-@@ -0,0 +1,73 @@
-+/*
-+ * This target marks packets to be enqueued to an imq device
-+ */
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter/x_tables.h>
-+#include <linux/netfilter/xt_IMQ.h>
-+#include <linux/imq.h>
-+
-+static unsigned int imq_target(struct sk_buff *pskb,
-+                              const struct xt_target_param *par)
-+{
-+      const struct xt_imq_info *mr = par->targinfo;
-+
-+      pskb->imq_flags = (mr->todev & IMQ_F_IFMASK) | IMQ_F_ENQUEUE;
-+
-+      return XT_CONTINUE;
-+}
-+
-+static bool imq_checkentry(const struct xt_tgchk_param *par)
-+{
-+      struct xt_imq_info *mr = par->targinfo;
-+
-+      if (mr->todev > IMQ_MAX_DEVS - 1) {
-+              printk(KERN_WARNING
-+                     "IMQ: invalid device specified, highest is %u\n",
-+                     IMQ_MAX_DEVS - 1);
-+              return 0;
-+      }
-+
-+      return 1;
-+}
-+
-+static struct xt_target xt_imq_reg[] __read_mostly = {
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET6,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+};
-+
-+static int __init imq_init(void)
-+{
-+      return xt_register_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+static void __exit imq_fini(void)
-+{
-+      xt_unregister_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+module_init(imq_init);
-+module_exit(imq_fini);
-+
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("ipt_IMQ");
-+MODULE_ALIAS("ip6t_IMQ");
-+
index 2618faf..7010d36 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -325,6 +325,8 @@ static struct cfi_fixup fixup_table[] =
+@@ -325,6 +325,8 @@ static struct cfi_fixup fixup_table[] = 
  static void cfi_fixup_major_minor(struct cfi_private *cfi,
                                  struct cfi_pri_amdstd *extp)
  {
  static void cfi_fixup_major_minor(struct cfi_private *cfi,
                                  struct cfi_pri_amdstd *extp)
  {
@@ -9,7 +9,7 @@
        if (cfi->mfr == CFI_MFR_SAMSUNG && cfi->id == 0x257e &&
            extp->MajorVersion == '0')
                extp->MajorVersion = '1';
        if (cfi->mfr == CFI_MFR_SAMSUNG && cfi->id == 0x257e &&
            extp->MajorVersion == '0')
                extp->MajorVersion = '1';
-@@ -355,6 +357,9 @@ struct mtd_info *cfi_cmdset_0002(struct
+@@ -355,6 +357,9 @@ struct mtd_info *cfi_cmdset_0002(struct 
        mtd->name    = map->name;
        mtd->writesize = 1;
  
        mtd->name    = map->name;
        mtd->writesize = 1;
  
@@ -19,7 +19,7 @@
        if (cfi->cfi_mode==CFI_MODE_CFI){
                unsigned char bootloc;
                /*
        if (cfi->cfi_mode==CFI_MODE_CFI){
                unsigned char bootloc;
                /*
-@@ -373,16 +378,24 @@ struct mtd_info *cfi_cmdset_0002(struct
+@@ -373,16 +378,24 @@ struct mtd_info *cfi_cmdset_0002(struct 
  
                cfi_fixup_major_minor(cfi, extp);
  
  
                cfi_fixup_major_minor(cfi, extp);
  
index d53c0c8..d73b2d1 100644 (file)
  
  unsigned int vced_count, vcei_count;
  
  
  unsigned int vced_count, vcei_count;
  
-@@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file
+@@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file 
        /*
         * For the first processor also print the system type
         */
        /*
         * For the first processor also print the system type
         */
index 9880ff0..dba3b32 100644 (file)
@@ -55,7 +55,7 @@
  vesper                        MACH_VESPER             VESPER                  2256
  str9                  MACH_STR9               STR9                    2257
  omap3_wl_ff           MACH_OMAP3_WL_FF        OMAP3_WL_FF             2258
  vesper                        MACH_VESPER             VESPER                  2256
  str9                  MACH_STR9               STR9                    2257
  omap3_wl_ff           MACH_OMAP3_WL_FF        OMAP3_WL_FF             2258
-@@ -2256,7 +2257,7 @@ oratisalog               MACH_ORATISALOG         ORATISALOG
+@@ -2256,7 +2257,7 @@ oratisalog               MACH_ORATISALOG         ORATISALOG      
  oratismadi            MACH_ORATISMADI         ORATISMADI              2269
  oratisot16            MACH_ORATISOT16         ORATISOT16              2270
  oratisdesk            MACH_ORATISDESK         ORATISDESK              2271
  oratismadi            MACH_ORATISMADI         ORATISMADI              2269
  oratisot16            MACH_ORATISOT16         ORATISOT16              2270
  oratisdesk            MACH_ORATISDESK         ORATISDESK              2271
  htc_excalibur_s620    MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620      2391
  htc_opal              MACH_HTC_OPAL           HTC_OPAL                2392
  touchbook             MACH_TOUCHBOOK          TOUCHBOOK               2393
  htc_excalibur_s620    MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620      2391
  htc_opal              MACH_HTC_OPAL           HTC_OPAL                2392
  touchbook             MACH_TOUCHBOOK          TOUCHBOOK               2393
-@@ -2445,7 +2446,7 @@ siogentoo1               MACH_SIOGENTOO1         SIOGENTOO1
+@@ -2445,7 +2446,7 @@ siogentoo1               MACH_SIOGENTOO1         SIOGENTOO1      
  siogentoo2            MACH_SIOGENTOO2         SIOGENTOO2              2459
  sm3k                  MACH_SM3K               SM3K                    2460
  acer_tempo_f900               MACH_ACER_TEMPO_F900    ACER_TEMPO_F900         2461
  siogentoo2            MACH_SIOGENTOO2         SIOGENTOO2              2459
  sm3k                  MACH_SM3K               SM3K                    2460
  acer_tempo_f900               MACH_ACER_TEMPO_F900    ACER_TEMPO_F900         2461
index de9c63c..be7d97f 100644 (file)
@@ -71,7 +71,7 @@
        depends on NETFILTER_ADVANCED
 --- a/net/netfilter/Makefile
 +++ b/net/netfilter/Makefile
        depends on NETFILTER_ADVANCED
 --- a/net/netfilter/Makefile
 +++ b/net/netfilter/Makefile
-@@ -89,6 +89,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT)
+@@ -89,6 +89,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) 
  obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
index 04ba710..a9eb108 100644 (file)
  
                e = (struct ipt_entry *)(loc_cpu_entry + off);
                if (copy_to_user(userptr + off
  
                e = (struct ipt_entry *)(loc_cpu_entry + off);
                if (copy_to_user(userptr + off
-@@ -1001,6 +1041,14 @@ copy_entries_to_user(unsigned int total_
-                       ret = -EFAULT;
+@@ -1002,6 +1042,14 @@ copy_entries_to_user(unsigned int total_
                        goto free_counters;
                }
                        goto free_counters;
                }
-+
 +              flags = e->ip.flags & ~IPT_F_NO_DEF_MATCH;
 +              if (copy_to_user(userptr + off
 +                               + offsetof(struct ipt_entry, ip.flags),
 +              flags = e->ip.flags & ~IPT_F_NO_DEF_MATCH;
 +              if (copy_to_user(userptr + off
 +                               + offsetof(struct ipt_entry, ip.flags),
 +                      ret = -EFAULT;
 +                      goto free_counters;
 +              }
 +                      ret = -EFAULT;
 +                      goto free_counters;
 +              }
++
                for (i = sizeof(struct ipt_entry);
                     i < e->target_offset;
                for (i = sizeof(struct ipt_entry);
                     i < e->target_offset;
+                    i += m->u.match_size) {
diff --git a/target/linux/generic/patches-2.6.32/150-netfilter_imq.patch b/target/linux/generic/patches-2.6.32/150-netfilter_imq.patch
deleted file mode 100644 (file)
index 3b46e25..0000000
+++ /dev/null
@@ -1,1336 +0,0 @@
---- /dev/null
-+++ b/drivers/net/imq.c
-@@ -0,0 +1,632 @@
-+/*
-+ *             Pseudo-driver for the intermediate queue device.
-+ *
-+ *             This program is free software; you can redistribute it and/or
-+ *             modify it under the terms of the GNU General Public License
-+ *             as published by the Free Software Foundation; either version
-+ *             2 of the License, or (at your option) any later version.
-+ *
-+ * Authors:    Patrick McHardy, <kaber@trash.net>
-+ *
-+ *            The first version was written by Martin Devera, <devik@cdi.cz>
-+ *
-+ * Credits:    Jan Rafaj <imq2t@cedric.vabo.cz>
-+ *              - Update patch to 2.4.21
-+ *             Sebastian Strollo <sstrollo@nortelnetworks.com>
-+ *              - Fix "Dead-loop on netdevice imq"-issue
-+ *             Marcel Sebek <sebek64@post.cz>
-+ *              - Update to 2.6.2-rc1
-+ *
-+ *           After some time of inactivity there is a group taking care
-+ *           of IMQ again: http://www.linuximq.net
-+ *
-+ *
-+ *           2004/06/30 - New version of IMQ patch to kernels <=2.6.7
-+ *             including the following changes:
-+ *
-+ *           - Correction of ipv6 support "+"s issue (Hasso Tepper)
-+ *           - Correction of imq_init_devs() issue that resulted in
-+ *           kernel OOPS unloading IMQ as module (Norbert Buchmuller)
-+ *           - Addition of functionality to choose number of IMQ devices
-+ *           during kernel config (Andre Correa)
-+ *           - Addition of functionality to choose how IMQ hooks on
-+ *           PRE and POSTROUTING (after or before NAT) (Andre Correa)
-+ *           - Cosmetic corrections (Norbert Buchmuller) (Andre Correa)
-+ *
-+ *
-+ *             2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were
-+ *             released with almost no problems. 2.6.14-x was released
-+ *             with some important changes: nfcache was removed; After
-+ *             some weeks of trouble we figured out that some IMQ fields
-+ *             in skb were missing in skbuff.c - skb_clone and copy_skb_header.
-+ *             These functions are correctly patched by this new patch version.
-+ *
-+ *             Thanks for all who helped to figure out all the problems with
-+ *             2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX,
-+ *             Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully
-+ *             I didn't forget anybody). I apologize again for my lack of time.
-+ *
-+ *
-+ *             2008/06/17 - 2.6.25 - Changed imq.c to use qdisc_run() instead 
-+ *             of qdisc_restart() and moved qdisc_run() to tasklet to avoid
-+ *             recursive locking. New initialization routines to fix 'rmmod' not
-+ *             working anymore. Used code from ifb.c. (Jussi Kivilinna)
-+ *
-+ *             2008/08/06 - 2.6.26 - (JK)
-+ *              - Replaced tasklet with 'netif_schedule()'.
-+ *              - Cleaned up and added comments for imq_nf_queue().
-+ *
-+ *             2009/04/12
-+ *              - Add skb_save_cb/skb_restore_cb helper functions for backuping
-+ *                control buffer. This is needed because qdisc-layer on kernels
-+ *                2.6.27 and newer overwrite control buffer. (Jussi Kivilinna)
-+ *              - Add better locking for IMQ device. Hopefully this will solve
-+ *                SMP issues. (Jussi Kivilinna)
-+ *              - Port to 2.6.27
-+ *              - Port to 2.6.28
-+ *              - Port to 2.6.29 + fix rmmod not working
-+ *
-+ *             2009/04/20 - (Jussi Kivilinna)
-+ *              - Use netdevice feature flags to avoid extra packet handling
-+ *                by core networking layer and possibly increase performance.
-+ *
-+ *             2009/09/26 - (Jussi Kivilinna)
-+ *              - Add imq_nf_reinject_lockless to fix deadlock with
-+ *                imq_nf_queue/imq_nf_reinject.
-+ *
-+ *             2009/12/08 - (Jussi Kivilinna)
-+ *              - Port to 2.6.32
-+ *              - Add check for skb->nf_queue_entry==NULL in imq_dev_xmit()
-+ *              - Also add better error checking for skb->nf_queue_entry usage
-+ *
-+ *           Also, many thanks to pablo Sebastian Greco for making the initial
-+ *           patch and to those who helped the testing.
-+ *
-+ *             More info at: http://www.linuximq.net/ (Andre Correa)
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/moduleparam.h>
-+#include <linux/list.h>
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/if_arp.h>
-+#include <linux/netfilter.h>
-+#include <linux/netfilter_ipv4.h>
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      #include <linux/netfilter_ipv6.h>
-+#endif
-+#include <linux/imq.h>
-+#include <net/pkt_sched.h>
-+#include <net/netfilter/nf_queue.h>
-+
-+static nf_hookfn imq_nf_hook;
-+
-+static struct nf_hook_ops imq_ingress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP_PRI_LAST
-+#else
-+      .priority       = NF_IP_PRI_NAT_SRC - 1
-+#endif
-+};
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+static struct nf_hook_ops imq_ingress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP6_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP6_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP6_PRI_LAST
-+#else
-+      .priority       = NF_IP6_PRI_NAT_SRC - 1
-+#endif
-+};
-+#endif
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS;
-+#else
-+static unsigned int numdevs = IMQ_MAX_DEVS;
-+#endif
-+
-+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 */
-+}
-+
-+/* locking not needed when called from imq_nf_queue */
-+static void imq_nf_reinject_lockless(struct nf_queue_entry *entry,
-+                                              unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              nf_reinject(entry, verdict);
-+              return;
-+      }
-+
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+}
-+
-+static void imq_nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              spin_lock_bh(&imq_nf_queue_lock);
-+              nf_reinject(entry, verdict);
-+              spin_unlock_bh(&imq_nf_queue_lock);
-+              return;
-+      }
-+
-+      rcu_read_lock();
-+      local_bh_disable();
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      local_bh_enable();
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+
-+      rcu_read_unlock();
-+}
-+
-+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;
-+
-+      imq_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;
-+      struct sk_buff *skb_orig, *skb, *skb_shared;
-+      struct Qdisc *q;
-+      struct netdev_queue *txq;
-+      int users, index;
-+      int retval = -EINVAL;
-+
-+      index = entry->skb->imq_flags & IMQ_F_IFMASK;
-+      if (unlikely(index > numdevs - 1)) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING
-+                             "IMQ: invalid device specified, highest is %u\n",
-+                             numdevs - 1);
-+              retval = -EINVAL;
-+              goto out;
-+      }
-+
-+      /* check for imq device by index from cache */
-+      dev = imq_devs_cache[index];
-+      if (unlikely(!dev)) {
-+              char buf[8];
-+
-+              /* get device by name and cache result */
-+              snprintf(buf, sizeof(buf), "imq%d", index);
-+              dev = dev_get_by_name(&init_net, buf);
-+              if (!dev) {
-+                      /* not found ?!*/
-+                      BUG();
-+                      retval = -ENODEV;
-+                      goto out;
-+              }
-+
-+              imq_devs_cache[index] = dev;
-+              dev_put(dev);
-+      }
-+
-+      if (unlikely(!(dev->flags & IFF_UP))) {
-+              entry->skb->imq_flags = 0;
-+              imq_nf_reinject_lockless(entry, NF_ACCEPT);
-+              retval = 0;
-+              goto out;
-+      }
-+      dev->last_rx = jiffies;
-+
-+      skb = entry->skb;
-+      skb_orig = NULL;
-+
-+      /* skb has owner? => make clone */
-+      if (unlikely(skb->destructor)) {
-+              skb_orig = skb;
-+              skb = skb_clone(skb, GFP_ATOMIC);
-+              if (!skb) {
-+                      retval = -ENOMEM;
-+                      goto out;
-+              }
-+              entry->skb = skb;
-+      }
-+
-+      skb->nf_queue_entry = entry;
-+
-+      dev->stats.rx_bytes += skb->len;
-+      dev->stats.rx_packets++;
-+
-+      txq = dev_pick_tx(dev, skb);
-+
-+      q = rcu_dereference(txq->qdisc);
-+      if (unlikely(!q->enqueue))
-+              goto packet_not_eaten_by_imq_dev;
-+
-+      spin_lock_bh(qdisc_lock(q));
-+
-+      users = atomic_read(&skb->users);
-+
-+      skb_shared = skb_get(skb); /* increase reference count by one */
-+      skb_save_cb(skb_shared); /* backup skb->cb, as qdisc layer will
-+                                      overwrite it */
-+      qdisc_enqueue_root(skb_shared, q); /* might kfree_skb */
-+
-+      if (likely(atomic_read(&skb_shared->users) == users + 1)) {
-+              kfree_skb(skb_shared); /* decrease reference count by one */
-+
-+              skb->destructor = &imq_skb_destructor;
-+
-+              /* cloned? */
-+              if (skb_orig)
-+                      kfree_skb(skb_orig); /* free original */
-+
-+              spin_unlock_bh(qdisc_lock(q));
-+
-+              /* schedule qdisc dequeue */
-+              __netif_schedule(q);
-+
-+              retval = 0;
-+              goto out;
-+      } else {
-+              skb_restore_cb(skb_shared); /* restore skb->cb */
-+              skb->nf_queue_entry = NULL;
-+              /* qdisc dropped packet and decreased skb reference count of
-+               * skb, so we don't really want to and try refree as that would
-+               * actually destroy the skb. */
-+              spin_unlock_bh(qdisc_lock(q));
-+              goto packet_not_eaten_by_imq_dev;
-+      }
-+
-+packet_not_eaten_by_imq_dev:
-+      /* cloned? restore original */
-+      if (skb_orig) {
-+              kfree_skb(skb);
-+              entry->skb = skb_orig;
-+      }
-+      retval = -1;
-+out:
-+      return retval;
-+}
-+
-+static struct nf_queue_handler nfqh = {
-+      .name  = "imq",
-+      .outfn = imq_nf_queue,
-+};
-+
-+static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff *pskb,
-+                              const struct net_device *indev,
-+                              const struct net_device *outdev,
-+                              int (*okfn)(struct sk_buff *))
-+{
-+      if (pskb->imq_flags & IMQ_F_ENQUEUE)
-+              return NF_QUEUE;
-+
-+      return NF_ACCEPT;
-+}
-+
-+static int imq_close(struct net_device *dev)
-+{
-+      netif_stop_queue(dev);
-+      return 0;
-+}
-+
-+static int imq_open(struct net_device *dev)
-+{
-+      netif_start_queue(dev);
-+      return 0;
-+}
-+
-+static const struct net_device_ops imq_netdev_ops = {
-+      .ndo_open               = imq_open,
-+      .ndo_stop               = imq_close,
-+      .ndo_start_xmit         = imq_dev_xmit,
-+      .ndo_get_stats          = imq_get_stats,
-+};
-+
-+static void imq_setup(struct net_device *dev)
-+{
-+      dev->netdev_ops         = &imq_netdev_ops;
-+      dev->type               = ARPHRD_VOID;
-+      dev->mtu                = 16000;
-+      dev->tx_queue_len       = 11000;
-+      dev->flags              = IFF_NOARP;
-+      dev->features           = NETIF_F_SG | NETIF_F_FRAGLIST |
-+                                NETIF_F_GSO | NETIF_F_HW_CSUM |
-+                                NETIF_F_HIGHDMA;
-+      dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
-+}
-+
-+static int imq_validate(struct nlattr *tb[], struct nlattr *data[])
-+{
-+      int ret = 0;
-+
-+      if (tb[IFLA_ADDRESS]) {
-+              if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
-+                      ret = -EINVAL;
-+                      goto end;
-+              }
-+              if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) {
-+                      ret = -EADDRNOTAVAIL;
-+                      goto end;
-+              }
-+      }
-+      return 0;
-+end:
-+      printk(KERN_WARNING "IMQ: imq_validate failed (%d)\n", ret);
-+      return ret;
-+}
-+
-+static struct rtnl_link_ops imq_link_ops __read_mostly = {
-+      .kind           = "imq",
-+      .priv_size      = 0,
-+      .setup          = imq_setup,
-+      .validate       = imq_validate,
-+};
-+
-+static int __init imq_init_hooks(void)
-+{
-+      int err;
-+
-+      nf_register_queue_imq_handler(&nfqh);
-+
-+      err = nf_register_hook(&imq_ingress_ipv4);
-+      if (err)
-+              goto err1;
-+
-+      err = nf_register_hook(&imq_egress_ipv4);
-+      if (err)
-+              goto err2;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      err = nf_register_hook(&imq_ingress_ipv6);
-+      if (err)
-+              goto err3;
-+
-+      err = nf_register_hook(&imq_egress_ipv6);
-+      if (err)
-+              goto err4;
-+#endif
-+
-+      return 0;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+err4:
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+err3:
-+      nf_unregister_hook(&imq_egress_ipv4);
-+#endif
-+err2:
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+err1:
-+      nf_unregister_queue_imq_handler();
-+      return err;
-+}
-+
-+static int __init imq_init_one(int index)
-+{
-+      struct net_device *dev;
-+      int ret;
-+
-+      dev = alloc_netdev(0, "imq%d", imq_setup);
-+      if (!dev)
-+              return -ENOMEM;
-+
-+      ret = dev_alloc_name(dev, dev->name);
-+      if (ret < 0)
-+              goto fail;
-+
-+      dev->rtnl_link_ops = &imq_link_ops;
-+      ret = register_netdevice(dev);
-+      if (ret < 0)
-+              goto fail;
-+
-+      return 0;
-+fail:
-+      free_netdev(dev);
-+      return ret;
-+}
-+
-+static int __init imq_init_devs(void)
-+{
-+      int err, i;
-+
-+      if (numdevs < 1 || numdevs > IMQ_MAX_DEVS) {
-+              printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n",
-+                     IMQ_MAX_DEVS);
-+              return -EINVAL;
-+      }
-+
-+      rtnl_lock();
-+      err = __rtnl_link_register(&imq_link_ops);
-+
-+      for (i = 0; i < numdevs && !err; i++)
-+              err = imq_init_one(i);
-+
-+      if (err) {
-+              __rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+      }
-+      rtnl_unlock();
-+
-+      return err;
-+}
-+
-+static int __init imq_init_module(void)
-+{
-+      int err;
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS > 16);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS < 2);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS - 1 > IMQ_F_IFMASK);
-+#endif
-+
-+      err = imq_init_devs();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_devs(net)\n");
-+              return err;
-+      }
-+
-+      err = imq_init_hooks();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n");
-+              rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+              return err;
-+      }
-+
-+      printk(KERN_INFO "IMQ driver loaded successfully.\n");
-+
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n");
-+#endif
-+#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n");
-+#endif
-+
-+      return 0;
-+}
-+
-+static void __exit imq_unhook(void)
-+{
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+      nf_unregister_hook(&imq_egress_ipv6);
-+#endif
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+      nf_unregister_hook(&imq_egress_ipv4);
-+
-+      nf_unregister_queue_imq_handler();
-+}
-+
-+static void __exit imq_cleanup_devs(void)
-+{
-+      rtnl_link_unregister(&imq_link_ops);
-+      memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+}
-+
-+static void __exit imq_exit_module(void)
-+{
-+      imq_unhook();
-+      imq_cleanup_devs();
-+      printk(KERN_INFO "IMQ driver unloaded successfully.\n");
-+}
-+
-+module_init(imq_init_module);
-+module_exit(imq_exit_module);
-+
-+module_param(numdevs, int, 0);
-+MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will "
-+                      "be created)");
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See "
-+                      "http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS_RTNL_LINK("imq");
-+
---- a/drivers/net/Kconfig
-+++ b/drivers/net/Kconfig
-@@ -109,6 +109,129 @@ config EQUALIZER
-         To compile this driver as a module, choose M here: the module
-         will be called eql.  If unsure, say N.
-+config IMQ
-+      tristate "IMQ (intermediate queueing device) support"
-+      depends on NETDEVICES && NETFILTER
-+      ---help---
-+        The IMQ device(s) is used as placeholder for QoS queueing
-+        disciplines. Every packet entering/leaving the IP stack can be
-+        directed through the IMQ device where it's enqueued/dequeued to the
-+        attached qdisc. This allows you to treat network devices as classes
-+        and distribute bandwidth among them. Iptables is used to specify
-+        through which IMQ device, if any, packets travel.
-+
-+        More information at: http://www.linuximq.net/
-+
-+        To compile this driver as a module, choose M here: the module
-+        will be called imq.  If unsure, say N.
-+
-+choice
-+      prompt "IMQ behavior (PRE/POSTROUTING)"
-+      depends on IMQ
-+      default IMQ_BEHAVIOR_AB
-+      help
-+
-+              This settings defines how IMQ behaves in respect to its
-+              hooking in PREROUTING and POSTROUTING.
-+
-+              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
-+
-+              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.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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 settings defines how many IMQ devices will be
-+              created.
-+
-+              The default value is 16.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              If not sure leave the default settings alone.
-+
- config TUN
-       tristate "Universal TUN/TAP device driver support"
-       select CRC32
---- a/drivers/net/Makefile
-+++ b/drivers/net/Makefile
-@@ -165,6 +165,7 @@ obj-$(CONFIG_SLHC) += slhc.o
- obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o
- obj-$(CONFIG_DUMMY) += dummy.o
-+obj-$(CONFIG_IMQ) += imq.o
- obj-$(CONFIG_IFB) += ifb.o
- obj-$(CONFIG_MACVLAN) += macvlan.o
- obj-$(CONFIG_DE600) += de600.o
---- /dev/null
-+++ b/include/linux/imq.h
-@@ -0,0 +1,13 @@
-+#ifndef _IMQ_H
-+#define _IMQ_H
-+
-+/* IFMASK (16 device indexes, 0 to 15) and flag(s) fit in 5 bits */
-+#define IMQ_F_BITS    5
-+
-+#define IMQ_F_IFMASK  0x0f
-+#define IMQ_F_ENQUEUE 0x10
-+
-+#define IMQ_MAX_DEVS  (IMQ_F_IFMASK + 1)
-+
-+#endif /* _IMQ_H */
-+
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1114,6 +1114,7 @@ extern int               dev_alloc_name(struct net_de
- extern int            dev_open(struct net_device *dev);
- extern int            dev_close(struct net_device *dev);
- extern void           dev_disable_lro(struct net_device *dev);
-+extern struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb);
- extern int            dev_queue_xmit(struct sk_buff *skb);
- extern int            register_netdevice(struct net_device *dev);
- extern void           unregister_netdevice(struct net_device *dev);
---- /dev/null
-+++ b/include/linux/netfilter/xt_IMQ.h
-@@ -0,0 +1,9 @@
-+#ifndef _XT_IMQ_H
-+#define _XT_IMQ_H
-+
-+struct xt_imq_info {
-+      unsigned int todev;     /* target imq device */
-+};
-+
-+#endif /* _XT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv4/ipt_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IPT_IMQ_H
-+#define _IPT_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ipt_imq_info xt_imq_info
-+
-+#endif /* _IPT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv6/ip6t_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IP6T_IMQ_H
-+#define _IP6T_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ip6t_imq_info xt_imq_info
-+
-+#endif /* _IP6T_IMQ_H */
-+
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -29,6 +29,9 @@
- #include <linux/rcupdate.h>
- #include <linux/dmaengine.h>
- #include <linux/hrtimer.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- /* Don't change this without changing skb_csum_unnecessary! */
- #define CHECKSUM_NONE 0
-@@ -330,6 +333,9 @@ struct sk_buff {
-        * first. This is owned by whoever has the skb queued ATM.
-        */
-       char                    cb[48];
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      void                    *cb_next;
-+#endif
-       unsigned int            len,
-                               data_len;
-@@ -362,6 +368,9 @@ struct sk_buff {
-       struct nf_conntrack     *nfct;
-       struct sk_buff          *nfct_reasm;
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      struct nf_queue_entry   *nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       struct nf_bridge_info   *nf_bridge;
- #endif
-@@ -383,6 +392,10 @@ struct sk_buff {
-       /* 0/14 bit hole */
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      __u8                    imq_flags:IMQ_F_BITS;
-+#endif
-+
- #ifdef CONFIG_NET_DMA
-       dma_cookie_t            dma_cookie;
- #endif
-@@ -437,6 +450,12 @@ static inline struct rtable *skb_rtable(
-       return (struct rtable *)skb_dst(skb);
- }
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern int skb_save_cb(struct sk_buff *skb);
-+extern int skb_restore_cb(struct sk_buff *skb);
-+#endif
-+
- extern void kfree_skb(struct sk_buff *skb);
- extern void consume_skb(struct sk_buff *skb);
- extern void          __kfree_skb(struct sk_buff *skb);
-@@ -1972,6 +1991,10 @@ static inline void __nf_copy(struct sk_b
-       dst->nfct_reasm = src->nfct_reasm;
-       nf_conntrack_get_reasm(src->nfct_reasm);
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      dst->imq_flags = src->imq_flags;
-+      dst->nf_queue_entry = src->nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       dst->nf_bridge  = src->nf_bridge;
-       nf_bridge_get(src->nf_bridge);
---- a/include/net/netfilter/nf_queue.h
-+++ b/include/net/netfilter/nf_queue.h
-@@ -13,6 +13,12 @@ struct nf_queue_entry {
-       struct net_device       *indev;
-       struct net_device       *outdev;
-       int                     (*okfn)(struct sk_buff *);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      int                     (*next_outfn)(struct nf_queue_entry *entry,
-+                                            unsigned int queuenum);
-+      unsigned int            next_queuenum;
-+#endif
- };
- #define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry))
-@@ -30,5 +36,11 @@ extern int nf_unregister_queue_handler(u
-                                      const struct nf_queue_handler *qh);
- extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
- extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
-+extern void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern void nf_register_queue_imq_handler(const struct nf_queue_handler *qh);
-+extern void nf_unregister_queue_imq_handler(void);
-+#endif
- #endif /* _NF_QUEUE_H */
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -96,6 +96,9 @@
- #include <net/net_namespace.h>
- #include <net/sock.h>
- #include <linux/rtnetlink.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- #include <linux/proc_fs.h>
- #include <linux/seq_file.h>
- #include <linux/stat.h>
-@@ -1704,7 +1707,11 @@ int dev_hard_start_xmit(struct sk_buff *
-       int rc;
-       if (likely(!skb->next)) {
--              if (!list_empty(&ptype_all))
-+              if (!list_empty(&ptype_all)
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+                  && !(skb->imq_flags & IMQ_F_ENQUEUE)
-+#endif
-+                  )
-                       dev_queue_xmit_nit(skb, dev);
-               if (netif_needs_gso(dev, skb)) {
-@@ -1797,8 +1804,7 @@ u16 skb_tx_hash(const struct net_device
- }
- EXPORT_SYMBOL(skb_tx_hash);
--static struct netdev_queue *dev_pick_tx(struct net_device *dev,
--                                      struct sk_buff *skb)
-+struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb)
- {
-       const struct net_device_ops *ops = dev->netdev_ops;
-       u16 queue_index = 0;
-@@ -1811,6 +1817,7 @@ static struct netdev_queue *dev_pick_tx(
-       skb_set_queue_mapping(skb, queue_index);
-       return netdev_get_tx_queue(dev, queue_index);
- }
-+EXPORT_SYMBOL(dev_pick_tx);
- static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
-                                struct net_device *dev,
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -72,6 +72,9 @@
- static struct kmem_cache *skbuff_head_cache __read_mostly;
- static struct kmem_cache *skbuff_fclone_cache __read_mostly;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static struct kmem_cache *skbuff_cb_store_cache __read_mostly;
-+#endif
- static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
-                                 struct pipe_buffer *buf)
-@@ -91,6 +94,83 @@ static int sock_pipe_buf_steal(struct pi
-       return 1;
- }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+/* Control buffer save/restore for IMQ devices */
-+struct skb_cb_table {
-+      void                    *cb_next;
-+      atomic_t                refcnt;
-+      char                    cb[48];
-+};
-+
-+static DEFINE_SPINLOCK(skb_cb_store_lock);
-+
-+int skb_save_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      next = kmem_cache_alloc(skbuff_cb_store_cache, GFP_ATOMIC);
-+      if (!next)
-+              return -ENOMEM;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(next->cb, skb->cb, sizeof(skb->cb));
-+      next->cb_next = skb->cb_next;
-+
-+      atomic_set(&next->refcnt, 1);
-+
-+      skb->cb_next = next;
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_save_cb);
-+
-+int skb_restore_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      if (!skb->cb_next)
-+              return 0;
-+
-+      next = skb->cb_next;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(skb->cb, next->cb, sizeof(skb->cb));
-+      skb->cb_next = next->cb_next;
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      if (atomic_dec_and_test(&next->refcnt)) {
-+              kmem_cache_free(skbuff_cb_store_cache, next);
-+      }
-+
-+      spin_unlock(&skb_cb_store_lock);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_restore_cb);
-+
-+static void skb_copy_stored_cb(struct sk_buff *new, const struct sk_buff *__old)
-+{
-+      struct skb_cb_table *next;
-+      struct sk_buff *old;
-+
-+      if (!__old->cb_next) {
-+              new->cb_next = NULL;
-+              return;
-+      }
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      old = (struct sk_buff *)__old;
-+
-+      next = old->cb_next;
-+      atomic_inc(&next->refcnt);
-+      new->cb_next = next;
-+
-+      spin_unlock(&skb_cb_store_lock);
-+}
-+#endif
- /* Pipe buffer operations for a socket. */
- static struct pipe_buf_operations sock_pipe_buf_ops = {
-@@ -398,6 +478,26 @@ static void skb_release_head_state(struc
-               WARN_ON(in_irq());
-               skb->destructor(skb);
-       }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      /* This should not happen. When it does, avoid memleak by restoring
-+      the chain of cb-backups. */
-+      while(skb->cb_next != NULL) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING "IMQ: kfree_skb: skb->cb_next: "
-+                              "%08x\n", (unsigned int)skb->cb_next);
-+
-+              skb_restore_cb(skb);
-+      }
-+      /* This should not happen either, nf_queue_entry is nullified in
-+       * imq_dev_xmit(). If we have non-NULL nf_queue_entry then we are
-+       * leaking entry pointers, maybe memory. We don't know if this is
-+       * pointer to already freed memory, or should this be freed.
-+       * If this happens we need to add refcounting, etc for nf_queue_entry.
-+       */
-+      if (skb->nf_queue_entry && net_ratelimit())
-+              printk(KERN_WARNING
-+                              "IMQ: kfree_skb: skb->nf_queue_entry != NULL");
-+#endif
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-       nf_conntrack_put(skb->nfct);
-       nf_conntrack_put_reasm(skb->nfct_reasm);
-@@ -535,6 +635,9 @@ static void __copy_skb_header(struct sk_
-       new->sp                 = secpath_get(old->sp);
- #endif
-       memcpy(new->cb, old->cb, sizeof(old->cb));
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skb_copy_stored_cb(new, old);
-+#endif
-       new->csum               = old->csum;
-       new->local_df           = old->local_df;
-       new->pkt_type           = old->pkt_type;
-@@ -2781,6 +2884,13 @@ void __init skb_init(void)
-                                               0,
-                                               SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-                                               NULL);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skbuff_cb_store_cache = kmem_cache_create("skbuff_cb_store_cache",
-+                                                sizeof(struct skb_cb_table),
-+                                                0,
-+                                                SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-+                                                NULL);
-+#endif
- }
- /**
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -396,6 +396,18 @@ config NETFILTER_XT_TARGET_LED
-         For more information on the LEDs available on your system, see
-         Documentation/leds-class.txt
-+config NETFILTER_XT_TARGET_IMQ
-+        tristate '"IMQ" target support'
-+      depends on NETFILTER_XTABLES
-+      depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+      select IMQ
-+      default m if NETFILTER_ADVANCED=n
-+        help
-+          This option adds a `IMQ' target which is used to specify if and
-+          to which imq device packets should get enqueued/dequeued.
-+
-+          To compile it as a module, choose M here.  If unsure, say N.
-+
- config NETFILTER_XT_TARGET_MARK
-       tristate '"MARK" target support'
-       default m if NETFILTER_ADVANCED=n
---- a/net/netfilter/Makefile
-+++ b/net/netfilter/Makefile
-@@ -46,6 +46,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMAR
- obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
-+obj-$(CONFIG_NETFILTER_XT_TARGET_IMQ) += xt_IMQ.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
---- a/net/netfilter/nf_queue.c
-+++ b/net/netfilter/nf_queue.c
-@@ -20,6 +20,26 @@ static const struct nf_queue_handler *qu
- static DEFINE_MUTEX(queue_handler_mutex);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static const struct nf_queue_handler *queue_imq_handler;
-+
-+void nf_register_queue_imq_handler(const struct nf_queue_handler *qh)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, qh);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_register_queue_imq_handler);
-+
-+void nf_unregister_queue_imq_handler(void)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, NULL);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_unregister_queue_imq_handler);
-+#endif
-+
- /* return EBUSY when somebody else is registered, return EEXIST if the
-  * same handler is registered, return 0 in case of success. */
- int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
-@@ -80,7 +100,7 @@ void nf_unregister_queue_handlers(const
- }
- EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);
--static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
-+void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
- {
-       /* Release those devices we held, or Alexey will kill me. */
-       if (entry->indev)
-@@ -100,6 +120,7 @@ static void nf_queue_entry_release_refs(
-       /* Drop reference to owner of hook which queued us. */
-       module_put(entry->elem->owner);
- }
-+EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
- /*
-  * Any packet that leaves via this function must come back
-@@ -121,12 +142,26 @@ static int __nf_queue(struct sk_buff *sk
- #endif
-       const struct nf_afinfo *afinfo;
-       const struct nf_queue_handler *qh;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      const struct nf_queue_handler *qih = NULL;
-+#endif
-       /* QUEUE == DROP if noone is waiting, to be safe. */
-       rcu_read_lock();
-       qh = rcu_dereference(queue_handler[pf]);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      if (pf == PF_INET || pf == PF_INET6)
-+#else
-+      if (pf == PF_INET)
-+#endif
-+              qih = rcu_dereference(queue_imq_handler);
-+
-+      if (!qh && !qih)
-+#else /* !IMQ */
-       if (!qh)
-+#endif
-               goto err_unlock;
-       afinfo = nf_get_afinfo(pf);
-@@ -145,6 +180,10 @@ static int __nf_queue(struct sk_buff *sk
-               .indev  = indev,
-               .outdev = outdev,
-               .okfn   = okfn,
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+              .next_outfn = qh ? qh->outfn : NULL,
-+              .next_queuenum = queuenum,
-+#endif
-       };
-       /* If it's going away, ignore hook. */
-@@ -170,8 +209,19 @@ static int __nf_queue(struct sk_buff *sk
-       }
- #endif
-       afinfo->saveroute(skb, entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      if (qih) {
-+              status = qih->outfn(entry, queuenum);
-+              goto imq_skip_queue;
-+      }
-+#endif
-+
-       status = qh->outfn(entry, queuenum);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+imq_skip_queue:
-+#endif
-       rcu_read_unlock();
-       if (status < 0) {
---- /dev/null
-+++ b/net/netfilter/xt_IMQ.c
-@@ -0,0 +1,73 @@
-+/*
-+ * This target marks packets to be enqueued to an imq device
-+ */
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter/x_tables.h>
-+#include <linux/netfilter/xt_IMQ.h>
-+#include <linux/imq.h>
-+
-+static unsigned int imq_target(struct sk_buff *pskb,
-+                              const struct xt_target_param *par)
-+{
-+      const struct xt_imq_info *mr = par->targinfo;
-+
-+      pskb->imq_flags = (mr->todev & IMQ_F_IFMASK) | IMQ_F_ENQUEUE;
-+
-+      return XT_CONTINUE;
-+}
-+
-+static bool imq_checkentry(const struct xt_tgchk_param *par)
-+{
-+      struct xt_imq_info *mr = par->targinfo;
-+
-+      if (mr->todev > IMQ_MAX_DEVS - 1) {
-+              printk(KERN_WARNING
-+                     "IMQ: invalid device specified, highest is %u\n",
-+                     IMQ_MAX_DEVS - 1);
-+              return 0;
-+      }
-+
-+      return 1;
-+}
-+
-+static struct xt_target xt_imq_reg[] __read_mostly = {
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET6,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+};
-+
-+static int __init imq_init(void)
-+{
-+      return xt_register_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+static void __exit imq_fini(void)
-+{
-+      xt_unregister_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+module_init(imq_init);
-+module_exit(imq_fini);
-+
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("ipt_IMQ");
-+MODULE_ALIAS("ip6t_IMQ");
-+
index fc00d15..e05ec77 100644 (file)
@@ -8,7 +8,7 @@
        depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
        depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
-@@ -505,7 +504,6 @@ config NETFILTER_XT_TARGET_SECMARK
+@@ -493,7 +492,6 @@ config NETFILTER_XT_TARGET_SECMARK
  
  config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
  
  config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
index e432471..6ea9ba5 100644 (file)
@@ -1,6 +1,6 @@
 --- a/arch/mips/include/asm/string.h
 +++ b/arch/mips/include/asm/string.h
 --- a/arch/mips/include/asm/string.h
 +++ b/arch/mips/include/asm/string.h
-@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__
+@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__ 
  
  #define __HAVE_ARCH_MEMSET
  extern void *memset(void *__s, int __c, size_t __count);
  
  #define __HAVE_ARCH_MEMSET
  extern void *memset(void *__s, int __c, size_t __count);
index 5bbf9f5..0c1ae72 100644 (file)
@@ -1,6 +1,6 @@
 --- a/include/linux/slab.h
 +++ b/include/linux/slab.h
 --- a/include/linux/slab.h
 +++ b/include/linux/slab.h
-@@ -124,8 +124,8 @@ int kmem_ptr_validate(struct kmem_cache
+@@ -124,8 +124,8 @@ int kmem_ptr_validate(struct kmem_cache 
   * to do various tricks to work around compiler limitations in order to
   * ensure proper constant folding.
   */
   * to do various tricks to work around compiler limitations in order to
   * ensure proper constant folding.
   */
index face44c..2405f59 100644 (file)
@@ -1,6 +1,6 @@
 --- a/include/linux/skbuff.h
 +++ b/include/linux/skbuff.h
 --- a/include/linux/skbuff.h
 +++ b/include/linux/skbuff.h
-@@ -1384,11 +1384,18 @@ static inline int skb_network_offset(con
+@@ -1365,11 +1365,18 @@ static inline int skb_network_offset(con
   *
   * Various parts of the networking layer expect at least 32 bytes of
   * headroom, you should not reduce this.
   *
   * Various parts of the networking layer expect at least 32 bytes of
   * headroom, you should not reduce this.
@@ -19,7 +19,7 @@
  extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
  
  static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
  extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
  
  static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
-@@ -1478,9 +1485,9 @@ static inline void __skb_queue_purge(str
+@@ -1459,9 +1466,9 @@ static inline void __skb_queue_purge(str
  static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
                                              gfp_t gfp_mask)
  {
  static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
                                              gfp_t gfp_mask)
  {
@@ -31,7 +31,7 @@
        return skb;
  }
  
        return skb;
  }
  
-@@ -1553,7 +1560,7 @@ static inline int __skb_cow(struct sk_bu
+@@ -1534,7 +1541,7 @@ static inline int __skb_cow(struct sk_bu
                delta = headroom - skb_headroom(skb);
  
        if (delta || cloned)
                delta = headroom - skb_headroom(skb);
  
        if (delta || cloned)
@@ -42,7 +42,7 @@
  }
 --- a/net/core/skbuff.c
 +++ b/net/core/skbuff.c
  }
 --- a/net/core/skbuff.c
 +++ b/net/core/skbuff.c
-@@ -339,9 +339,9 @@ struct sk_buff *__netdev_alloc_skb(struc
+@@ -259,9 +259,9 @@ struct sk_buff *__netdev_alloc_skb(struc
        int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
        struct sk_buff *skb;
  
        int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
        struct sk_buff *skb;
  
index b64630d..d71e3b6 100644 (file)
@@ -61,7 +61,7 @@
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd);
  
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd);
  
-@@ -501,6 +505,29 @@ static inline void double_unlock(struct
+@@ -501,6 +505,29 @@ static inline void double_unlock(struct 
  #endif  /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
  #endif /* __KERNEL__ */
  
  #endif  /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
  #endif /* __KERNEL__ */
  
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
 --- a/fs/mini_fo/aux.c
 +++ b/fs/mini_fo/aux.c
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
 --- a/fs/mini_fo/aux.c
 +++ b/fs/mini_fo/aux.c
-@@ -164,11 +164,11 @@ dentry_t *bpath_walk(super_block_t *sb,
+@@ -164,11 +164,11 @@ dentry_t *bpath_walk(super_block_t *sb, 
        err = vfs_path_lookup(mnt->mnt_root, mnt, bpath+1, 0, &nd);
  
        /* validate */
        err = vfs_path_lookup(mnt->mnt_root, mnt, bpath+1, 0, &nd);
  
        /* validate */
index b5fa64e..8bd9ba3 100644 (file)
@@ -1,6 +1,6 @@
 --- a/fs/mini_fo/super.c
 +++ b/fs/mini_fo/super.c
 --- a/fs/mini_fo/super.c
 +++ b/fs/mini_fo/super.c
-@@ -84,6 +84,7 @@ mini_fo_write_inode(inode_t *inode, int
+@@ -84,6 +84,7 @@ mini_fo_write_inode(inode_t *inode, int 
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
  
  
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
  
  
index cc4ffb2..393668b 100644 (file)
@@ -20,7 +20,7 @@
  #else
  static inline int kobject_uevent(struct kobject *kobj,
                                 enum kobject_action action)
  #else
  static inline int kobject_uevent(struct kobject *kobj,
                                 enum kobject_action action)
-@@ -224,6 +230,16 @@ static inline int add_uevent_var(struct
+@@ -224,6 +230,16 @@ static inline int add_uevent_var(struct 
  static inline int kobject_action_type(const char *buf, size_t count,
                                      enum kobject_action *type)
  { return -EINVAL; }
  static inline int kobject_action_type(const char *buf, size_t count,
                                      enum kobject_action *type)
  { return -EINVAL; }
index 4edb071..1892eb5 100644 (file)
@@ -11,7 +11,7 @@
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
-@@ -40,3 +40,4 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) +=
+@@ -40,3 +40,4 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += 
  obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)  += ledtrig-backlight.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)  += ledtrig-backlight.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
index 11b87ac..69e3f26 100644 (file)
@@ -14,7 +14,7 @@
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
-@@ -41,3 +41,4 @@ obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) +=
+@@ -41,3 +41,4 @@ obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += 
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_MORSE)      += ledtrig-morse.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_MORSE)      += ledtrig-morse.o
index c334b17..5c70e79 100644 (file)
                        dev->checkpointBlockList[i] = -1;
        }
  
                        dev->checkpointBlockList[i] = -1;
        }
  
-@@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device
+@@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device 
  
  static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
  {
  
  static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
  {
  {
        unsigned char cDelta;   /* column parity delta */
        unsigned lDelta;        /* line parity delta */
  {
        unsigned char cDelta;   /* column parity delta */
        unsigned lDelta;        /* line parity delta */
-@@ -294,8 +292,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -294,8 +292,7 @@ int yaffs_ECCCorrectOther(unsigned char 
                return 0; /* no error */
  
        if (lDelta == ~lDeltaPrime &&
                return 0; /* no error */
  
        if (lDelta == ~lDeltaPrime &&
                /* Single bit (recoverable) error in data */
  
                bit = 0;
                /* Single bit (recoverable) error in data */
  
                bit = 0;
-@@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char 
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                        return -1;
  
                data[lDelta] ^= (1 << bit);
                        return -1;
  
                data[lDelta] ^= (1 << bit);
-@@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char 
        }
  
        if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
        }
  
        if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
                /* Reccoverable error in ecc */
  
                *read_ecc = *test_ecc;
                /* Reccoverable error in ecc */
  
                *read_ecc = *test_ecc;
-@@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char 
        /* Unrecoverable error */
  
        return -1;
        /* Unrecoverable error */
  
        return -1;
  {
        unsigned char *alias;
        int ret;
  {
        unsigned char *alias;
        int ret;
-@@ -329,7 +395,7 @@ static int yaffs_readlink(struct dentry
+@@ -329,7 +395,7 @@ static int yaffs_readlink(struct dentry 
        return ret;
  }
  
        return ret;
  }
  
  static int yaffs_file_flush(struct file *file, fl_owner_t id)
  #else
  static int yaffs_file_flush(struct file *file)
  static int yaffs_file_flush(struct file *file, fl_owner_t id)
  #else
  static int yaffs_file_flush(struct file *file)
-@@ -513,8 +579,8 @@ static int yaffs_file_flush(struct file
+@@ -513,8 +579,8 @@ static int yaffs_file_flush(struct file 
        yaffs_Device *dev = obj->myDev;
  
        T(YAFFS_TRACE_OS,
        yaffs_Device *dev = obj->myDev;
  
        T(YAFFS_TRACE_OS,
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossLock(dev);
  
-@@ -535,15 +601,15 @@ static int yaffs_readpage_nolock(struct
+@@ -535,15 +601,15 @@ static int yaffs_readpage_nolock(struct 
  
        yaffs_Device *dev;
  
  
        yaffs_Device *dev;
  
        BUG_ON(!PageLocked(pg));
  #else
        if (!PageLocked(pg))
        BUG_ON(!PageLocked(pg));
  #else
        if (!PageLocked(pg))
-@@ -555,9 +621,9 @@ static int yaffs_readpage_nolock(struct
+@@ -555,9 +621,9 @@ static int yaffs_readpage_nolock(struct 
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossUnlock(dev);
  
  
        yaffs_GrossUnlock(dev);
  
-@@ -575,7 +641,7 @@ static int yaffs_readpage_nolock(struct
+@@ -575,7 +641,7 @@ static int yaffs_readpage_nolock(struct 
        flush_dcache_page(pg);
        kunmap(pg);
  
        flush_dcache_page(pg);
        kunmap(pg);
  
                if (n < step) {
                        n++;
                        continue;
                if (n < step) {
                        n++;
                        continue;
-@@ -2119,7 +2356,7 @@ static int yaffs_proc_write(struct file
+@@ -2119,7 +2356,7 @@ static int yaffs_proc_write(struct file 
        char *end;
        char *mask_name;
        const char *x;
        char *end;
        char *mask_name;
        const char *x;
        int i;
        int done = 0;
        int add, len = 0;
        int i;
        int done = 0;
        int add, len = 0;
-@@ -2129,9 +2366,8 @@ static int yaffs_proc_write(struct file
+@@ -2129,9 +2366,8 @@ static int yaffs_proc_write(struct file 
  
        while (!done && (pos < count)) {
                done = 1;
  
        while (!done && (pos < count)) {
                done = 1;
  
                switch (buf[pos]) {
                case '+':
  
                switch (buf[pos]) {
                case '+':
-@@ -2148,20 +2384,21 @@ static int yaffs_proc_write(struct file
+@@ -2148,20 +2384,21 @@ static int yaffs_proc_write(struct file 
                mask_name = NULL;
  
                mask_bitfield = simple_strtoul(buf + pos, &end, 0);
                mask_name = NULL;
  
                mask_bitfield = simple_strtoul(buf + pos, &end, 0);
                                        mask_name = mask_flags[i].mask_name;
                                        mask_bitfield = mask_flags[i].mask_bitfield;
                                        done = 0;
                                        mask_name = mask_flags[i].mask_name;
                                        mask_bitfield = mask_flags[i].mask_bitfield;
                                        done = 0;
-@@ -2172,7 +2409,7 @@ static int yaffs_proc_write(struct file
+@@ -2172,7 +2409,7 @@ static int yaffs_proc_write(struct file 
  
                if (mask_name != NULL) {
                        done = 0;
  
                if (mask_name != NULL) {
                        done = 0;
                        case '-':
                                rg &= ~mask_bitfield;
                                break;
                        case '-':
                                rg &= ~mask_bitfield;
                                break;
-@@ -2191,13 +2428,13 @@ static int yaffs_proc_write(struct file
+@@ -2191,13 +2428,13 @@ static int yaffs_proc_write(struct file 
  
        yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
  
  
        yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
  
  {
        /* Get the real object in case we were fed a hard link as an equivalent object */
        equivalentObject = yaffs_GetEquivalentObject(equivalentObject);
  {
        /* Get the real object in case we were fed a hard link as an equivalent object */
        equivalentObject = yaffs_GetEquivalentObject(equivalentObject);
-@@ -2363,33 +2396,31 @@ yaffs_Object *yaffs_Link(yaffs_Object *
+@@ -2363,33 +2396,31 @@ yaffs_Object *yaffs_Link(yaffs_Object * 
  
  }
  
  
  }
  
        int nToCopy;
        int n = nBytes;
        int nDone = 0;
        int nToCopy;
        int n = nBytes;
        int nDone = 0;
-@@ -4600,27 +4665,26 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4600,27 +4665,26 @@ int yaffs_ReadDataFromFile(yaffs_Object 
        dev = in->myDev;
  
        while (n > 0) {
        dev = in->myDev;
  
        while (n > 0) {
                        if (dev->nShortOpCaches > 0) {
  
                                /* If we can't find the data in the cache, then load it up. */
                        if (dev->nShortOpCaches > 0) {
  
                                /* If we can't find the data in the cache, then load it up. */
-@@ -4641,14 +4705,9 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4641,14 +4705,9 @@ int yaffs_ReadDataFromFile(yaffs_Object 
  
                                cache->locked = 1;
  
  
                                cache->locked = 1;
  
                                cache->locked = 0;
                        } else {
                                /* Read into the local buffer then copy..*/
                                cache->locked = 0;
                        } else {
                                /* Read into the local buffer then copy..*/
-@@ -4657,41 +4716,19 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4657,41 +4716,19 @@ int yaffs_ReadDataFromFile(yaffs_Object 
                                    yaffs_GetTempBuffer(dev, __LINE__);
                                yaffs_ReadChunkDataFromObject(in, chunk,
                                                              localBuffer);
                                    yaffs_GetTempBuffer(dev, __LINE__);
                                yaffs_ReadChunkDataFromObject(in, chunk,
                                                              localBuffer);
                }
  
                n -= nToCopy;
                }
  
                n -= nToCopy;
-@@ -4704,28 +4741,37 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4704,28 +4741,37 @@ int yaffs_ReadDataFromFile(yaffs_Object 
        return nDone;
  }
  
        return nDone;
  }
  
        int newFullChunks;
  
        yaffs_Device *dev = in->myDev;
        int newFullChunks;
  
        yaffs_Device *dev = in->myDev;
-@@ -4955,13 +4981,11 @@ int yaffs_ResizeFile(yaffs_Object * in,
+@@ -4955,13 +4981,11 @@ int yaffs_ResizeFile(yaffs_Object * in, 
  
        yaffs_CheckGarbageCollection(dev);
  
  
        yaffs_CheckGarbageCollection(dev);
  
  
        if (newSize < oldFileSize) {
  
  
        if (newSize < oldFileSize) {
  
-@@ -4994,21 +5018,20 @@ int yaffs_ResizeFile(yaffs_Object * in,
+@@ -4994,21 +5018,20 @@ int yaffs_ResizeFile(yaffs_Object * in, 
        }
  
  
        }
  
  
  {
        obj = yaffs_GetEquivalentObject(obj);
  
  {
        obj = yaffs_GetEquivalentObject(obj);
  
-@@ -5024,7 +5047,7 @@ loff_t yaffs_GetFileSize(yaffs_Object *
+@@ -5024,7 +5047,7 @@ loff_t yaffs_GetFileSize(yaffs_Object * 
  
  
  
  
  
  
  {
        int init_failed = 0;
        unsigned x;
  {
        int init_failed = 0;
        unsigned x;
-@@ -7040,6 +7126,8 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7040,6 +7126,8 @@ int yaffs_GutsInitialise(yaffs_Device * 
        dev->chunkOffset = 0;
        dev->nFreeChunks = 0;
  
        dev->chunkOffset = 0;
        dev->nFreeChunks = 0;
  
        if (dev->startBlock == 0) {
                dev->internalStartBlock = dev->startBlock + 1;
                dev->internalEndBlock = dev->endBlock + 1;
        if (dev->startBlock == 0) {
                dev->internalStartBlock = dev->startBlock + 1;
                dev->internalEndBlock = dev->endBlock + 1;
-@@ -7049,18 +7137,18 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7049,18 +7137,18 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        /* Check geometry parameters. */
  
  
        /* Check geometry parameters. */
  
                return YAFFS_FAIL;
        }
  
                return YAFFS_FAIL;
        }
  
-@@ -7070,6 +7158,12 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7070,6 +7158,12 @@ int yaffs_GutsInitialise(yaffs_Device * 
                return YAFFS_FAIL;
        }
  
                return YAFFS_FAIL;
        }
  
        /* Got the right mix of functions? */
        if (!yaffs_CheckDevFunctions(dev)) {
                /* Function missing */
        /* Got the right mix of functions? */
        if (!yaffs_CheckDevFunctions(dev)) {
                /* Function missing */
-@@ -7097,31 +7191,18 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7097,31 +7191,18 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        dev->isMounted = 1;
  
  
        dev->isMounted = 1;
  
  
        /*
         * Calculate chunkGroupBits.
  
        /*
         * Calculate chunkGroupBits.
-@@ -7133,16 +7214,15 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7133,16 +7214,15 @@ int yaffs_GutsInitialise(yaffs_Device * 
        bits = ShiftsGE(x);
  
        /* Set up tnode width if wide tnodes are enabled. */
        bits = ShiftsGE(x);
  
        /* Set up tnode width if wide tnodes are enabled. */
                dev->tnodeWidth = 16;
  
        dev->tnodeMask = (1<<dev->tnodeWidth)-1;
                dev->tnodeWidth = 16;
  
        dev->tnodeMask = (1<<dev->tnodeWidth)-1;
-@@ -7193,7 +7273,7 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7193,7 +7273,7 @@ int yaffs_GutsInitialise(yaffs_Device * 
        dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */
  
        /* Initialise temporary buffers and caches. */
        dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */
  
        /* Initialise temporary buffers and caches. */
                init_failed = 1;
  
        dev->srCache = NULL;
                init_failed = 1;
  
        dev->srCache = NULL;
-@@ -7203,25 +7283,26 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7203,25 +7283,26 @@ int yaffs_GutsInitialise(yaffs_Device * 
        if (!init_failed &&
            dev->nShortOpCaches > 0) {
                int i;
        if (!init_failed &&
            dev->nShortOpCaches > 0) {
                int i;
                        init_failed = 1;
  
                dev->srLastUse = 0;
                        init_failed = 1;
  
                dev->srLastUse = 0;
-@@ -7229,29 +7310,30 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7229,29 +7310,30 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        dev->cacheHits = 0;
  
  
        dev->cacheHits = 0;
  
                                T(YAFFS_TRACE_ALWAYS,
                                  (TSTR("yaffs: restored from checkpoint" TENDSTR)));
                        } else {
                                T(YAFFS_TRACE_ALWAYS,
                                  (TSTR("yaffs: restored from checkpoint" TENDSTR)));
                        } else {
-@@ -7273,24 +7355,25 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7273,24 +7355,25 @@ int yaffs_GutsInitialise(yaffs_Device * 
                                dev->nBackgroundDeletions = 0;
                                dev->oldestDirtySequence = 0;
  
                                dev->nBackgroundDeletions = 0;
                                dev->oldestDirtySequence = 0;
  
                /* Clean up the mess */
                T(YAFFS_TRACE_TRACING,
                  (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR)));
                /* Clean up the mess */
                T(YAFFS_TRACE_TRACING,
                  (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR)));
-@@ -7318,7 +7401,7 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7318,7 +7401,7 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
  }
  
  
  }
  
  {
        if (etags) {
                memset(etags, 0, sizeof(*etags));
  {
        if (etags) {
                memset(etags, 0, sizeof(*etags));
-@@ -169,9 +169,9 @@ static int rettags(yaffs_ExtendedTags *
+@@ -169,9 +169,9 @@ static int rettags(yaffs_ExtendedTags * 
   * Returns YAFFS_OK or YAFFS_FAIL.
   */
  int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
   * Returns YAFFS_OK or YAFFS_FAIL.
   */
  int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
 +                      yaffs_UnpackTags2(tags, &pt);
 +              }
 +      }
 +                      yaffs_UnpackTags2(tags, &pt);
 +              }
 +      }
-+
+-      if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
+-              tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
 +      if (localData)
 +              yaffs_ReleaseTempBuffer(dev, data, __LINE__);
  
 +      if (localData)
 +              yaffs_ReleaseTempBuffer(dev, data, __LINE__);
  
--      if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
 +      if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
 +      if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
-               tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
--
++              tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
        if (retval == 0)
                return YAFFS_OK;
        else
        if (retval == 0)
                return YAFFS_OK;
        else
index 22a6592..7552ceb 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/hostap/hostap_ap.c
 +++ b/drivers/net/wireless/hostap/hostap_ap.c
 --- a/drivers/net/wireless/hostap/hostap_ap.c
 +++ b/drivers/net/wireless/hostap/hostap_ap.c
-@@ -2335,13 +2335,13 @@ int prism2_ap_get_sta_qual(local_info_t
+@@ -2335,13 +2335,13 @@ int prism2_ap_get_sta_qual(local_info_t 
                addr[count].sa_family = ARPHRD_ETHER;
                memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
                if (sta->last_rx_silence == 0)
                addr[count].sa_family = ARPHRD_ETHER;
                memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
                if (sta->last_rx_silence == 0)
index b9091c7..0ac0900 100644 (file)
@@ -55,7 +55,7 @@
  #include <linux/kallsyms.h>
  #include <linux/notifier.h>
  #include <linux/module.h>
  #include <linux/kallsyms.h>
  #include <linux/notifier.h>
  #include <linux/module.h>
-@@ -74,6 +75,7 @@ NORET_TYPE void panic(const char * fmt,
+@@ -74,6 +75,7 @@ NORET_TYPE void panic(const char * fmt, 
        dump_stack();
  #endif
  
        dump_stack();
  #endif
  
index 8eff02f..0b0c1e2 100644 (file)
@@ -24,7 +24,7 @@
   * All of these routines try to estimate how many bits of randomness a
   * particular randomness source.  They do this by keeping track of the
   * first and second order deltas of the event timings.
   * All of these routines try to estimate how many bits of randomness a
   * particular randomness source.  They do this by keeping track of the
   * first and second order deltas of the event timings.
-@@ -714,6 +724,61 @@ void add_disk_randomness(struct gendisk
+@@ -714,6 +724,61 @@ void add_disk_randomness(struct gendisk 
  }
  #endif
  
  }
  #endif
  
index 373df1a..0cb8483 100644 (file)
 +static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev,
 +                      tuple_t *tuple,
 +                      void *priv)
 +static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev,
 +                      tuple_t *tuple,
 +                      void *priv)
- {
--      tuple_t tuple;
--      int res;
--      unsigned char buf[32];
++{
 +      struct ssb_sprom *sprom = priv;
 +
 +      if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
 +      struct ssb_sprom *sprom = priv;
 +
 +      if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
 +static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
 +                                      tuple_t *tuple,
 +                                      void *priv)
 +static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
 +                                      tuple_t *tuple,
 +                                      void *priv)
-+{
+ {
+-      tuple_t tuple;
+-      int res;
+-      unsigned char buf[32];
 +      struct ssb_init_invariants *iv = priv;
        struct ssb_sprom *sprom = &iv->sprom;
        struct ssb_boardinfo *bi = &iv->boardinfo;
 +      struct ssb_init_invariants *iv = priv;
        struct ssb_sprom *sprom = &iv->sprom;
        struct ssb_boardinfo *bi = &iv->boardinfo;
index f81e22f..face915 100644 (file)
@@ -1,6 +1,6 @@
 --- a/scripts/Makefile.lib
 +++ b/scripts/Makefile.lib
 --- a/scripts/Makefile.lib
 +++ b/scripts/Makefile.lib
-@@ -228,7 +228,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^)
+@@ -228,7 +228,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^) 
  
  quiet_cmd_lzma = LZMA    $@
  cmd_lzma = (cat $(filter-out FORCE,$^) | \
  
  quiet_cmd_lzma = LZMA    $@
  cmd_lzma = (cat $(filter-out FORCE,$^) | \
index 2618faf..7010d36 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -325,6 +325,8 @@ static struct cfi_fixup fixup_table[] =
+@@ -325,6 +325,8 @@ static struct cfi_fixup fixup_table[] = 
  static void cfi_fixup_major_minor(struct cfi_private *cfi,
                                  struct cfi_pri_amdstd *extp)
  {
  static void cfi_fixup_major_minor(struct cfi_private *cfi,
                                  struct cfi_pri_amdstd *extp)
  {
@@ -9,7 +9,7 @@
        if (cfi->mfr == CFI_MFR_SAMSUNG && cfi->id == 0x257e &&
            extp->MajorVersion == '0')
                extp->MajorVersion = '1';
        if (cfi->mfr == CFI_MFR_SAMSUNG && cfi->id == 0x257e &&
            extp->MajorVersion == '0')
                extp->MajorVersion = '1';
-@@ -355,6 +357,9 @@ struct mtd_info *cfi_cmdset_0002(struct
+@@ -355,6 +357,9 @@ struct mtd_info *cfi_cmdset_0002(struct 
        mtd->name    = map->name;
        mtd->writesize = 1;
  
        mtd->name    = map->name;
        mtd->writesize = 1;
  
@@ -19,7 +19,7 @@
        if (cfi->cfi_mode==CFI_MODE_CFI){
                unsigned char bootloc;
                /*
        if (cfi->cfi_mode==CFI_MODE_CFI){
                unsigned char bootloc;
                /*
-@@ -373,16 +378,24 @@ struct mtd_info *cfi_cmdset_0002(struct
+@@ -373,16 +378,24 @@ struct mtd_info *cfi_cmdset_0002(struct 
  
                cfi_fixup_major_minor(cfi, extp);
  
  
                cfi_fixup_major_minor(cfi, extp);
  
index 83e2445..ca0c10b 100644 (file)
  
  unsigned int vced_count, vcei_count;
  
  
  unsigned int vced_count, vcei_count;
  
-@@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file
+@@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file 
        /*
         * For the first processor also print the system type
         */
        /*
         * For the first processor also print the system type
         */
index a19ff62..ce88533 100644 (file)
@@ -71,7 +71,7 @@
        depends on NETFILTER_ADVANCED
 --- a/net/netfilter/Makefile
 +++ b/net/netfilter/Makefile
        depends on NETFILTER_ADVANCED
 --- a/net/netfilter/Makefile
 +++ b/net/netfilter/Makefile
-@@ -90,6 +90,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT)
+@@ -90,6 +90,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) 
  obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
index 41c487b..8178a22 100644 (file)
  
                e = (struct ipt_entry *)(loc_cpu_entry + off);
                if (copy_to_user(userptr + off
  
                e = (struct ipt_entry *)(loc_cpu_entry + off);
                if (copy_to_user(userptr + off
-@@ -1000,6 +1040,14 @@ copy_entries_to_user(unsigned int total_
-                       ret = -EFAULT;
+@@ -1001,6 +1041,14 @@ copy_entries_to_user(unsigned int total_
                        goto free_counters;
                }
                        goto free_counters;
                }
-+
 +              flags = e->ip.flags & ~IPT_F_NO_DEF_MATCH;
 +              if (copy_to_user(userptr + off
 +                               + offsetof(struct ipt_entry, ip.flags),
 +              flags = e->ip.flags & ~IPT_F_NO_DEF_MATCH;
 +              if (copy_to_user(userptr + off
 +                               + offsetof(struct ipt_entry, ip.flags),
 +                      ret = -EFAULT;
 +                      goto free_counters;
 +              }
 +                      ret = -EFAULT;
 +                      goto free_counters;
 +              }
++
                for (i = sizeof(struct ipt_entry);
                     i < e->target_offset;
                for (i = sizeof(struct ipt_entry);
                     i < e->target_offset;
+                    i += m->u.match_size) {
diff --git a/target/linux/generic/patches-2.6.34/150-netfilter_imq.patch b/target/linux/generic/patches-2.6.34/150-netfilter_imq.patch
deleted file mode 100644 (file)
index 8441e41..0000000
+++ /dev/null
@@ -1,1336 +0,0 @@
---- /dev/null
-+++ b/drivers/net/imq.c
-@@ -0,0 +1,632 @@
-+/*
-+ *             Pseudo-driver for the intermediate queue device.
-+ *
-+ *             This program is free software; you can redistribute it and/or
-+ *             modify it under the terms of the GNU General Public License
-+ *             as published by the Free Software Foundation; either version
-+ *             2 of the License, or (at your option) any later version.
-+ *
-+ * Authors:    Patrick McHardy, <kaber@trash.net>
-+ *
-+ *            The first version was written by Martin Devera, <devik@cdi.cz>
-+ *
-+ * Credits:    Jan Rafaj <imq2t@cedric.vabo.cz>
-+ *              - Update patch to 2.4.21
-+ *             Sebastian Strollo <sstrollo@nortelnetworks.com>
-+ *              - Fix "Dead-loop on netdevice imq"-issue
-+ *             Marcel Sebek <sebek64@post.cz>
-+ *              - Update to 2.6.2-rc1
-+ *
-+ *           After some time of inactivity there is a group taking care
-+ *           of IMQ again: http://www.linuximq.net
-+ *
-+ *
-+ *           2004/06/30 - New version of IMQ patch to kernels <=2.6.7
-+ *             including the following changes:
-+ *
-+ *           - Correction of ipv6 support "+"s issue (Hasso Tepper)
-+ *           - Correction of imq_init_devs() issue that resulted in
-+ *           kernel OOPS unloading IMQ as module (Norbert Buchmuller)
-+ *           - Addition of functionality to choose number of IMQ devices
-+ *           during kernel config (Andre Correa)
-+ *           - Addition of functionality to choose how IMQ hooks on
-+ *           PRE and POSTROUTING (after or before NAT) (Andre Correa)
-+ *           - Cosmetic corrections (Norbert Buchmuller) (Andre Correa)
-+ *
-+ *
-+ *             2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were
-+ *             released with almost no problems. 2.6.14-x was released
-+ *             with some important changes: nfcache was removed; After
-+ *             some weeks of trouble we figured out that some IMQ fields
-+ *             in skb were missing in skbuff.c - skb_clone and copy_skb_header.
-+ *             These functions are correctly patched by this new patch version.
-+ *
-+ *             Thanks for all who helped to figure out all the problems with
-+ *             2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX,
-+ *             Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully
-+ *             I didn't forget anybody). I apologize again for my lack of time.
-+ *
-+ *
-+ *             2008/06/17 - 2.6.25 - Changed imq.c to use qdisc_run() instead 
-+ *             of qdisc_restart() and moved qdisc_run() to tasklet to avoid
-+ *             recursive locking. New initialization routines to fix 'rmmod' not
-+ *             working anymore. Used code from ifb.c. (Jussi Kivilinna)
-+ *
-+ *             2008/08/06 - 2.6.26 - (JK)
-+ *              - Replaced tasklet with 'netif_schedule()'.
-+ *              - Cleaned up and added comments for imq_nf_queue().
-+ *
-+ *             2009/04/12
-+ *              - Add skb_save_cb/skb_restore_cb helper functions for backuping
-+ *                control buffer. This is needed because qdisc-layer on kernels
-+ *                2.6.27 and newer overwrite control buffer. (Jussi Kivilinna)
-+ *              - Add better locking for IMQ device. Hopefully this will solve
-+ *                SMP issues. (Jussi Kivilinna)
-+ *              - Port to 2.6.27
-+ *              - Port to 2.6.28
-+ *              - Port to 2.6.29 + fix rmmod not working
-+ *
-+ *             2009/04/20 - (Jussi Kivilinna)
-+ *              - Use netdevice feature flags to avoid extra packet handling
-+ *                by core networking layer and possibly increase performance.
-+ *
-+ *             2009/09/26 - (Jussi Kivilinna)
-+ *              - Add imq_nf_reinject_lockless to fix deadlock with
-+ *                imq_nf_queue/imq_nf_reinject.
-+ *
-+ *             2009/12/08 - (Jussi Kivilinna)
-+ *              - Port to 2.6.32
-+ *              - Add check for skb->nf_queue_entry==NULL in imq_dev_xmit()
-+ *              - Also add better error checking for skb->nf_queue_entry usage
-+ *
-+ *           Also, many thanks to pablo Sebastian Greco for making the initial
-+ *           patch and to those who helped the testing.
-+ *
-+ *             More info at: http://www.linuximq.net/ (Andre Correa)
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/moduleparam.h>
-+#include <linux/list.h>
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/if_arp.h>
-+#include <linux/netfilter.h>
-+#include <linux/netfilter_ipv4.h>
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      #include <linux/netfilter_ipv6.h>
-+#endif
-+#include <linux/imq.h>
-+#include <net/pkt_sched.h>
-+#include <net/netfilter/nf_queue.h>
-+
-+static nf_hookfn imq_nf_hook;
-+
-+static struct nf_hook_ops imq_ingress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP_PRI_LAST
-+#else
-+      .priority       = NF_IP_PRI_NAT_SRC - 1
-+#endif
-+};
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+static struct nf_hook_ops imq_ingress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP6_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP6_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP6_PRI_LAST
-+#else
-+      .priority       = NF_IP6_PRI_NAT_SRC - 1
-+#endif
-+};
-+#endif
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS;
-+#else
-+static unsigned int numdevs = IMQ_MAX_DEVS;
-+#endif
-+
-+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 */
-+}
-+
-+/* locking not needed when called from imq_nf_queue */
-+static void imq_nf_reinject_lockless(struct nf_queue_entry *entry,
-+                                              unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              nf_reinject(entry, verdict);
-+              return;
-+      }
-+
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+}
-+
-+static void imq_nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              spin_lock_bh(&imq_nf_queue_lock);
-+              nf_reinject(entry, verdict);
-+              spin_unlock_bh(&imq_nf_queue_lock);
-+              return;
-+      }
-+
-+      rcu_read_lock();
-+      local_bh_disable();
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      local_bh_enable();
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+
-+      rcu_read_unlock();
-+}
-+
-+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;
-+
-+      imq_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;
-+      struct sk_buff *skb_orig, *skb, *skb_shared;
-+      struct Qdisc *q;
-+      struct netdev_queue *txq;
-+      int users, index;
-+      int retval = -EINVAL;
-+
-+      index = entry->skb->imq_flags & IMQ_F_IFMASK;
-+      if (unlikely(index > numdevs - 1)) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING
-+                             "IMQ: invalid device specified, highest is %u\n",
-+                             numdevs - 1);
-+              retval = -EINVAL;
-+              goto out;
-+      }
-+
-+      /* check for imq device by index from cache */
-+      dev = imq_devs_cache[index];
-+      if (unlikely(!dev)) {
-+              char buf[8];
-+
-+              /* get device by name and cache result */
-+              snprintf(buf, sizeof(buf), "imq%d", index);
-+              dev = dev_get_by_name(&init_net, buf);
-+              if (!dev) {
-+                      /* not found ?!*/
-+                      BUG();
-+                      retval = -ENODEV;
-+                      goto out;
-+              }
-+
-+              imq_devs_cache[index] = dev;
-+              dev_put(dev);
-+      }
-+
-+      if (unlikely(!(dev->flags & IFF_UP))) {
-+              entry->skb->imq_flags = 0;
-+              imq_nf_reinject_lockless(entry, NF_ACCEPT);
-+              retval = 0;
-+              goto out;
-+      }
-+      dev->last_rx = jiffies;
-+
-+      skb = entry->skb;
-+      skb_orig = NULL;
-+
-+      /* skb has owner? => make clone */
-+      if (unlikely(skb->destructor)) {
-+              skb_orig = skb;
-+              skb = skb_clone(skb, GFP_ATOMIC);
-+              if (!skb) {
-+                      retval = -ENOMEM;
-+                      goto out;
-+              }
-+              entry->skb = skb;
-+      }
-+
-+      skb->nf_queue_entry = entry;
-+
-+      dev->stats.rx_bytes += skb->len;
-+      dev->stats.rx_packets++;
-+
-+      txq = dev_pick_tx(dev, skb);
-+
-+      q = rcu_dereference(txq->qdisc);
-+      if (unlikely(!q->enqueue))
-+              goto packet_not_eaten_by_imq_dev;
-+
-+      spin_lock_bh(qdisc_lock(q));
-+
-+      users = atomic_read(&skb->users);
-+
-+      skb_shared = skb_get(skb); /* increase reference count by one */
-+      skb_save_cb(skb_shared); /* backup skb->cb, as qdisc layer will
-+                                      overwrite it */
-+      qdisc_enqueue_root(skb_shared, q); /* might kfree_skb */
-+
-+      if (likely(atomic_read(&skb_shared->users) == users + 1)) {
-+              kfree_skb(skb_shared); /* decrease reference count by one */
-+
-+              skb->destructor = &imq_skb_destructor;
-+
-+              /* cloned? */
-+              if (skb_orig)
-+                      kfree_skb(skb_orig); /* free original */
-+
-+              spin_unlock_bh(qdisc_lock(q));
-+
-+              /* schedule qdisc dequeue */
-+              __netif_schedule(q);
-+
-+              retval = 0;
-+              goto out;
-+      } else {
-+              skb_restore_cb(skb_shared); /* restore skb->cb */
-+              skb->nf_queue_entry = NULL;
-+              /* qdisc dropped packet and decreased skb reference count of
-+               * skb, so we don't really want to and try refree as that would
-+               * actually destroy the skb. */
-+              spin_unlock_bh(qdisc_lock(q));
-+              goto packet_not_eaten_by_imq_dev;
-+      }
-+
-+packet_not_eaten_by_imq_dev:
-+      /* cloned? restore original */
-+      if (skb_orig) {
-+              kfree_skb(skb);
-+              entry->skb = skb_orig;
-+      }
-+      retval = -1;
-+out:
-+      return retval;
-+}
-+
-+static struct nf_queue_handler nfqh = {
-+      .name  = "imq",
-+      .outfn = imq_nf_queue,
-+};
-+
-+static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff *pskb,
-+                              const struct net_device *indev,
-+                              const struct net_device *outdev,
-+                              int (*okfn)(struct sk_buff *))
-+{
-+      if (pskb->imq_flags & IMQ_F_ENQUEUE)
-+              return NF_QUEUE;
-+
-+      return NF_ACCEPT;
-+}
-+
-+static int imq_close(struct net_device *dev)
-+{
-+      netif_stop_queue(dev);
-+      return 0;
-+}
-+
-+static int imq_open(struct net_device *dev)
-+{
-+      netif_start_queue(dev);
-+      return 0;
-+}
-+
-+static const struct net_device_ops imq_netdev_ops = {
-+      .ndo_open               = imq_open,
-+      .ndo_stop               = imq_close,
-+      .ndo_start_xmit         = imq_dev_xmit,
-+      .ndo_get_stats          = imq_get_stats,
-+};
-+
-+static void imq_setup(struct net_device *dev)
-+{
-+      dev->netdev_ops         = &imq_netdev_ops;
-+      dev->type               = ARPHRD_VOID;
-+      dev->mtu                = 16000;
-+      dev->tx_queue_len       = 11000;
-+      dev->flags              = IFF_NOARP;
-+      dev->features           = NETIF_F_SG | NETIF_F_FRAGLIST |
-+                                NETIF_F_GSO | NETIF_F_HW_CSUM |
-+                                NETIF_F_HIGHDMA;
-+      dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
-+}
-+
-+static int imq_validate(struct nlattr *tb[], struct nlattr *data[])
-+{
-+      int ret = 0;
-+
-+      if (tb[IFLA_ADDRESS]) {
-+              if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
-+                      ret = -EINVAL;
-+                      goto end;
-+              }
-+              if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) {
-+                      ret = -EADDRNOTAVAIL;
-+                      goto end;
-+              }
-+      }
-+      return 0;
-+end:
-+      printk(KERN_WARNING "IMQ: imq_validate failed (%d)\n", ret);
-+      return ret;
-+}
-+
-+static struct rtnl_link_ops imq_link_ops __read_mostly = {
-+      .kind           = "imq",
-+      .priv_size      = 0,
-+      .setup          = imq_setup,
-+      .validate       = imq_validate,
-+};
-+
-+static int __init imq_init_hooks(void)
-+{
-+      int err;
-+
-+      nf_register_queue_imq_handler(&nfqh);
-+
-+      err = nf_register_hook(&imq_ingress_ipv4);
-+      if (err)
-+              goto err1;
-+
-+      err = nf_register_hook(&imq_egress_ipv4);
-+      if (err)
-+              goto err2;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      err = nf_register_hook(&imq_ingress_ipv6);
-+      if (err)
-+              goto err3;
-+
-+      err = nf_register_hook(&imq_egress_ipv6);
-+      if (err)
-+              goto err4;
-+#endif
-+
-+      return 0;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+err4:
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+err3:
-+      nf_unregister_hook(&imq_egress_ipv4);
-+#endif
-+err2:
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+err1:
-+      nf_unregister_queue_imq_handler();
-+      return err;
-+}
-+
-+static int __init imq_init_one(int index)
-+{
-+      struct net_device *dev;
-+      int ret;
-+
-+      dev = alloc_netdev(0, "imq%d", imq_setup);
-+      if (!dev)
-+              return -ENOMEM;
-+
-+      ret = dev_alloc_name(dev, dev->name);
-+      if (ret < 0)
-+              goto fail;
-+
-+      dev->rtnl_link_ops = &imq_link_ops;
-+      ret = register_netdevice(dev);
-+      if (ret < 0)
-+              goto fail;
-+
-+      return 0;
-+fail:
-+      free_netdev(dev);
-+      return ret;
-+}
-+
-+static int __init imq_init_devs(void)
-+{
-+      int err, i;
-+
-+      if (numdevs < 1 || numdevs > IMQ_MAX_DEVS) {
-+              printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n",
-+                     IMQ_MAX_DEVS);
-+              return -EINVAL;
-+      }
-+
-+      rtnl_lock();
-+      err = __rtnl_link_register(&imq_link_ops);
-+
-+      for (i = 0; i < numdevs && !err; i++)
-+              err = imq_init_one(i);
-+
-+      if (err) {
-+              __rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+      }
-+      rtnl_unlock();
-+
-+      return err;
-+}
-+
-+static int __init imq_init_module(void)
-+{
-+      int err;
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS > 16);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS < 2);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS - 1 > IMQ_F_IFMASK);
-+#endif
-+
-+      err = imq_init_devs();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_devs(net)\n");
-+              return err;
-+      }
-+
-+      err = imq_init_hooks();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n");
-+              rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+              return err;
-+      }
-+
-+      printk(KERN_INFO "IMQ driver loaded successfully.\n");
-+
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n");
-+#endif
-+#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n");
-+#endif
-+
-+      return 0;
-+}
-+
-+static void __exit imq_unhook(void)
-+{
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+      nf_unregister_hook(&imq_egress_ipv6);
-+#endif
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+      nf_unregister_hook(&imq_egress_ipv4);
-+
-+      nf_unregister_queue_imq_handler();
-+}
-+
-+static void __exit imq_cleanup_devs(void)
-+{
-+      rtnl_link_unregister(&imq_link_ops);
-+      memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+}
-+
-+static void __exit imq_exit_module(void)
-+{
-+      imq_unhook();
-+      imq_cleanup_devs();
-+      printk(KERN_INFO "IMQ driver unloaded successfully.\n");
-+}
-+
-+module_init(imq_init_module);
-+module_exit(imq_exit_module);
-+
-+module_param(numdevs, int, 0);
-+MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will "
-+                      "be created)");
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See "
-+                      "http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS_RTNL_LINK("imq");
-+
---- a/drivers/net/Kconfig
-+++ b/drivers/net/Kconfig
-@@ -121,6 +121,129 @@ config EQUALIZER
-         To compile this driver as a module, choose M here: the module
-         will be called eql.  If unsure, say N.
-+config IMQ
-+      tristate "IMQ (intermediate queueing device) support"
-+      depends on NETDEVICES && NETFILTER
-+      ---help---
-+        The IMQ device(s) is used as placeholder for QoS queueing
-+        disciplines. Every packet entering/leaving the IP stack can be
-+        directed through the IMQ device where it's enqueued/dequeued to the
-+        attached qdisc. This allows you to treat network devices as classes
-+        and distribute bandwidth among them. Iptables is used to specify
-+        through which IMQ device, if any, packets travel.
-+
-+        More information at: http://www.linuximq.net/
-+
-+        To compile this driver as a module, choose M here: the module
-+        will be called imq.  If unsure, say N.
-+
-+choice
-+      prompt "IMQ behavior (PRE/POSTROUTING)"
-+      depends on IMQ
-+      default IMQ_BEHAVIOR_AB
-+      help
-+
-+              This settings defines how IMQ behaves in respect to its
-+              hooking in PREROUTING and POSTROUTING.
-+
-+              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
-+
-+              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.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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 settings defines how many IMQ devices will be
-+              created.
-+
-+              The default value is 16.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              If not sure leave the default settings alone.
-+
- config TUN
-       tristate "Universal TUN/TAP device driver support"
-       select CRC32
---- a/drivers/net/Makefile
-+++ b/drivers/net/Makefile
-@@ -169,6 +169,7 @@ obj-$(CONFIG_SLHC) += slhc.o
- obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o
- obj-$(CONFIG_DUMMY) += dummy.o
-+obj-$(CONFIG_IMQ) += imq.o
- obj-$(CONFIG_IFB) += ifb.o
- obj-$(CONFIG_MACVLAN) += macvlan.o
- obj-$(CONFIG_MACVTAP) += macvtap.o
---- /dev/null
-+++ b/include/linux/imq.h
-@@ -0,0 +1,13 @@
-+#ifndef _IMQ_H
-+#define _IMQ_H
-+
-+/* IFMASK (16 device indexes, 0 to 15) and flag(s) fit in 5 bits */
-+#define IMQ_F_BITS    5
-+
-+#define IMQ_F_IFMASK  0x0f
-+#define IMQ_F_ENQUEUE 0x10
-+
-+#define IMQ_MAX_DEVS  (IMQ_F_IFMASK + 1)
-+
-+#endif /* _IMQ_H */
-+
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1203,6 +1203,7 @@ extern int               dev_alloc_name(struct net_de
- extern int            dev_open(struct net_device *dev);
- extern int            dev_close(struct net_device *dev);
- extern void           dev_disable_lro(struct net_device *dev);
-+extern struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb);
- extern int            dev_queue_xmit(struct sk_buff *skb);
- extern int            register_netdevice(struct net_device *dev);
- extern void           unregister_netdevice_queue(struct net_device *dev,
---- /dev/null
-+++ b/include/linux/netfilter/xt_IMQ.h
-@@ -0,0 +1,9 @@
-+#ifndef _XT_IMQ_H
-+#define _XT_IMQ_H
-+
-+struct xt_imq_info {
-+      unsigned int todev;     /* target imq device */
-+};
-+
-+#endif /* _XT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv4/ipt_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IPT_IMQ_H
-+#define _IPT_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ipt_imq_info xt_imq_info
-+
-+#endif /* _IPT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv6/ip6t_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IP6T_IMQ_H
-+#define _IP6T_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ip6t_imq_info xt_imq_info
-+
-+#endif /* _IP6T_IMQ_H */
-+
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -29,6 +29,9 @@
- #include <linux/rcupdate.h>
- #include <linux/dmaengine.h>
- #include <linux/hrtimer.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- /* Don't change this without changing skb_csum_unnecessary! */
- #define CHECKSUM_NONE 0
-@@ -321,6 +324,9 @@ struct sk_buff {
-        * first. This is owned by whoever has the skb queued ATM.
-        */
-       char                    cb[48] __aligned(8);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      void                    *cb_next;
-+#endif
-       unsigned long           _skb_dst;
- #ifdef CONFIG_XFRM
-@@ -357,6 +363,9 @@ struct sk_buff {
-       struct nf_conntrack     *nfct;
-       struct sk_buff          *nfct_reasm;
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      struct nf_queue_entry   *nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       struct nf_bridge_info   *nf_bridge;
- #endif
-@@ -378,6 +387,10 @@ struct sk_buff {
-       /* 0/14 bit hole */
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      __u8                    imq_flags:IMQ_F_BITS;
-+#endif
-+
- #ifdef CONFIG_NET_DMA
-       dma_cookie_t            dma_cookie;
- #endif
-@@ -426,6 +439,12 @@ static inline struct rtable *skb_rtable(
-       return (struct rtable *)skb_dst(skb);
- }
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern int skb_save_cb(struct sk_buff *skb);
-+extern int skb_restore_cb(struct sk_buff *skb);
-+#endif
-+
- extern void kfree_skb(struct sk_buff *skb);
- extern void consume_skb(struct sk_buff *skb);
- extern void          __kfree_skb(struct sk_buff *skb);
-@@ -1970,6 +1989,10 @@ static inline void __nf_copy(struct sk_b
-       dst->nfct_reasm = src->nfct_reasm;
-       nf_conntrack_get_reasm(src->nfct_reasm);
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      dst->imq_flags = src->imq_flags;
-+      dst->nf_queue_entry = src->nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       dst->nf_bridge  = src->nf_bridge;
-       nf_bridge_get(src->nf_bridge);
---- a/include/net/netfilter/nf_queue.h
-+++ b/include/net/netfilter/nf_queue.h
-@@ -13,6 +13,12 @@ struct nf_queue_entry {
-       struct net_device       *indev;
-       struct net_device       *outdev;
-       int                     (*okfn)(struct sk_buff *);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      int                     (*next_outfn)(struct nf_queue_entry *entry,
-+                                            unsigned int queuenum);
-+      unsigned int            next_queuenum;
-+#endif
- };
- #define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry))
-@@ -30,5 +36,11 @@ extern int nf_unregister_queue_handler(u
-                                      const struct nf_queue_handler *qh);
- extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
- extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
-+extern void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern void nf_register_queue_imq_handler(const struct nf_queue_handler *qh);
-+extern void nf_unregister_queue_imq_handler(void);
-+#endif
- #endif /* _NF_QUEUE_H */
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -98,6 +98,9 @@
- #include <net/net_namespace.h>
- #include <net/sock.h>
- #include <linux/rtnetlink.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- #include <linux/proc_fs.h>
- #include <linux/seq_file.h>
- #include <linux/stat.h>
-@@ -1860,7 +1863,11 @@ int dev_hard_start_xmit(struct sk_buff *
-       int rc = NETDEV_TX_OK;
-       if (likely(!skb->next)) {
--              if (!list_empty(&ptype_all))
-+              if (!list_empty(&ptype_all)
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+                  && !(skb->imq_flags & IMQ_F_ENQUEUE)
-+#endif
-+                  )
-                       dev_queue_xmit_nit(skb, dev);
-               if (netif_needs_gso(dev, skb)) {
-@@ -1970,8 +1977,7 @@ static inline u16 dev_cap_txqueue(struct
-       return queue_index;
- }
--static struct netdev_queue *dev_pick_tx(struct net_device *dev,
--                                      struct sk_buff *skb)
-+struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb)
- {
-       int queue_index;
-       struct sock *sk = skb->sk;
-@@ -2000,6 +2006,7 @@ static struct netdev_queue *dev_pick_tx(
-       skb_set_queue_mapping(skb, queue_index);
-       return netdev_get_tx_queue(dev, queue_index);
- }
-+EXPORT_SYMBOL(dev_pick_tx);
- static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
-                                struct net_device *dev,
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -72,6 +72,9 @@
- static struct kmem_cache *skbuff_head_cache __read_mostly;
- static struct kmem_cache *skbuff_fclone_cache __read_mostly;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static struct kmem_cache *skbuff_cb_store_cache __read_mostly;
-+#endif
- static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
-                                 struct pipe_buffer *buf)
-@@ -91,6 +94,83 @@ static int sock_pipe_buf_steal(struct pi
-       return 1;
- }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+/* Control buffer save/restore for IMQ devices */
-+struct skb_cb_table {
-+      void                    *cb_next;
-+      atomic_t                refcnt;
-+      char                    cb[48];
-+};
-+
-+static DEFINE_SPINLOCK(skb_cb_store_lock);
-+
-+int skb_save_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      next = kmem_cache_alloc(skbuff_cb_store_cache, GFP_ATOMIC);
-+      if (!next)
-+              return -ENOMEM;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(next->cb, skb->cb, sizeof(skb->cb));
-+      next->cb_next = skb->cb_next;
-+
-+      atomic_set(&next->refcnt, 1);
-+
-+      skb->cb_next = next;
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_save_cb);
-+
-+int skb_restore_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      if (!skb->cb_next)
-+              return 0;
-+
-+      next = skb->cb_next;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(skb->cb, next->cb, sizeof(skb->cb));
-+      skb->cb_next = next->cb_next;
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      if (atomic_dec_and_test(&next->refcnt)) {
-+              kmem_cache_free(skbuff_cb_store_cache, next);
-+      }
-+
-+      spin_unlock(&skb_cb_store_lock);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_restore_cb);
-+
-+static void skb_copy_stored_cb(struct sk_buff *new, const struct sk_buff *__old)
-+{
-+      struct skb_cb_table *next;
-+      struct sk_buff *old;
-+
-+      if (!__old->cb_next) {
-+              new->cb_next = NULL;
-+              return;
-+      }
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      old = (struct sk_buff *)__old;
-+
-+      next = old->cb_next;
-+      atomic_inc(&next->refcnt);
-+      new->cb_next = next;
-+
-+      spin_unlock(&skb_cb_store_lock);
-+}
-+#endif
- /* Pipe buffer operations for a socket. */
- static const struct pipe_buf_operations sock_pipe_buf_ops = {
-@@ -398,6 +478,26 @@ static void skb_release_head_state(struc
-               WARN_ON(in_irq());
-               skb->destructor(skb);
-       }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      /* This should not happen. When it does, avoid memleak by restoring
-+      the chain of cb-backups. */
-+      while(skb->cb_next != NULL) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING "IMQ: kfree_skb: skb->cb_next: "
-+                              "%08x\n", (unsigned int)skb->cb_next);
-+
-+              skb_restore_cb(skb);
-+      }
-+      /* This should not happen either, nf_queue_entry is nullified in
-+       * imq_dev_xmit(). If we have non-NULL nf_queue_entry then we are
-+       * leaking entry pointers, maybe memory. We don't know if this is
-+       * pointer to already freed memory, or should this be freed.
-+       * If this happens we need to add refcounting, etc for nf_queue_entry.
-+       */
-+      if (skb->nf_queue_entry && net_ratelimit())
-+              printk(KERN_WARNING
-+                              "IMQ: kfree_skb: skb->nf_queue_entry != NULL");
-+#endif
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-       nf_conntrack_put(skb->nfct);
-       nf_conntrack_put_reasm(skb->nfct_reasm);
-@@ -538,6 +638,9 @@ static void __copy_skb_header(struct sk_
-       new->sp                 = secpath_get(old->sp);
- #endif
-       memcpy(new->cb, old->cb, sizeof(old->cb));
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skb_copy_stored_cb(new, old);
-+#endif
-       new->csum               = old->csum;
-       new->local_df           = old->local_df;
-       new->pkt_type           = old->pkt_type;
-@@ -2780,6 +2883,13 @@ void __init skb_init(void)
-                                               0,
-                                               SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-                                               NULL);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skbuff_cb_store_cache = kmem_cache_create("skbuff_cb_store_cache",
-+                                                sizeof(struct skb_cb_table),
-+                                                0,
-+                                                SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-+                                                NULL);
-+#endif
- }
- /**
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -421,6 +421,18 @@ config NETFILTER_XT_TARGET_LED
-         For more information on the LEDs available on your system, see
-         Documentation/leds-class.txt
-+config NETFILTER_XT_TARGET_IMQ
-+        tristate '"IMQ" target support'
-+      depends on NETFILTER_XTABLES
-+      depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+      select IMQ
-+      default m if NETFILTER_ADVANCED=n
-+        help
-+          This option adds a `IMQ' target which is used to specify if and
-+          to which imq device packets should get enqueued/dequeued.
-+
-+          To compile it as a module, choose M here.  If unsure, say N.
-+
- config NETFILTER_XT_TARGET_MARK
-       tristate '"MARK" target support'
-       default m if NETFILTER_ADVANCED=n
---- a/net/netfilter/Makefile
-+++ b/net/netfilter/Makefile
-@@ -47,6 +47,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSEC
- obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
-+obj-$(CONFIG_NETFILTER_XT_TARGET_IMQ) += xt_IMQ.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
---- a/net/netfilter/nf_queue.c
-+++ b/net/netfilter/nf_queue.c
-@@ -21,6 +21,26 @@ static const struct nf_queue_handler *qu
- static DEFINE_MUTEX(queue_handler_mutex);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static const struct nf_queue_handler *queue_imq_handler;
-+
-+void nf_register_queue_imq_handler(const struct nf_queue_handler *qh)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, qh);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_register_queue_imq_handler);
-+
-+void nf_unregister_queue_imq_handler(void)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, NULL);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_unregister_queue_imq_handler);
-+#endif
-+
- /* return EBUSY when somebody else is registered, return EEXIST if the
-  * same handler is registered, return 0 in case of success. */
- int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
-@@ -81,7 +101,7 @@ void nf_unregister_queue_handlers(const
- }
- EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);
--static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
-+void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
- {
-       /* Release those devices we held, or Alexey will kill me. */
-       if (entry->indev)
-@@ -101,6 +121,7 @@ static void nf_queue_entry_release_refs(
-       /* Drop reference to owner of hook which queued us. */
-       module_put(entry->elem->owner);
- }
-+EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
- /*
-  * Any packet that leaves via this function must come back
-@@ -122,12 +143,26 @@ static int __nf_queue(struct sk_buff *sk
- #endif
-       const struct nf_afinfo *afinfo;
-       const struct nf_queue_handler *qh;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      const struct nf_queue_handler *qih = NULL;
-+#endif
-       /* QUEUE == DROP if noone is waiting, to be safe. */
-       rcu_read_lock();
-       qh = rcu_dereference(queue_handler[pf]);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      if (pf == PF_INET || pf == PF_INET6)
-+#else
-+      if (pf == PF_INET)
-+#endif
-+              qih = rcu_dereference(queue_imq_handler);
-+
-+      if (!qh && !qih)
-+#else /* !IMQ */
-       if (!qh)
-+#endif
-               goto err_unlock;
-       afinfo = nf_get_afinfo(pf);
-@@ -146,6 +181,10 @@ static int __nf_queue(struct sk_buff *sk
-               .indev  = indev,
-               .outdev = outdev,
-               .okfn   = okfn,
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+              .next_outfn = qh ? qh->outfn : NULL,
-+              .next_queuenum = queuenum,
-+#endif
-       };
-       /* If it's going away, ignore hook. */
-@@ -171,8 +210,19 @@ static int __nf_queue(struct sk_buff *sk
-       }
- #endif
-       afinfo->saveroute(skb, entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      if (qih) {
-+              status = qih->outfn(entry, queuenum);
-+              goto imq_skip_queue;
-+      }
-+#endif
-+
-       status = qh->outfn(entry, queuenum);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+imq_skip_queue:
-+#endif
-       rcu_read_unlock();
-       if (status < 0) {
---- /dev/null
-+++ b/net/netfilter/xt_IMQ.c
-@@ -0,0 +1,73 @@
-+/*
-+ * This target marks packets to be enqueued to an imq device
-+ */
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter/x_tables.h>
-+#include <linux/netfilter/xt_IMQ.h>
-+#include <linux/imq.h>
-+
-+static unsigned int imq_target(struct sk_buff *pskb,
-+                              const struct xt_target_param *par)
-+{
-+      const struct xt_imq_info *mr = par->targinfo;
-+
-+      pskb->imq_flags = (mr->todev & IMQ_F_IFMASK) | IMQ_F_ENQUEUE;
-+
-+      return XT_CONTINUE;
-+}
-+
-+static bool imq_checkentry(const struct xt_tgchk_param *par)
-+{
-+      struct xt_imq_info *mr = par->targinfo;
-+
-+      if (mr->todev > IMQ_MAX_DEVS - 1) {
-+              printk(KERN_WARNING
-+                     "IMQ: invalid device specified, highest is %u\n",
-+                     IMQ_MAX_DEVS - 1);
-+              return 0;
-+      }
-+
-+      return 1;
-+}
-+
-+static struct xt_target xt_imq_reg[] __read_mostly = {
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET6,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+};
-+
-+static int __init imq_init(void)
-+{
-+      return xt_register_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+static void __exit imq_fini(void)
-+{
-+      xt_unregister_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+module_init(imq_init);
-+module_exit(imq_fini);
-+
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("ipt_IMQ");
-+MODULE_ALIAS("ip6t_IMQ");
-+
index 1bda13d..4654ea0 100644 (file)
@@ -8,7 +8,7 @@
        depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
        depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
-@@ -530,7 +529,6 @@ config NETFILTER_XT_TARGET_SECMARK
+@@ -518,7 +517,6 @@ config NETFILTER_XT_TARGET_SECMARK
  
  config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
  
  config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
index e432471..6ea9ba5 100644 (file)
@@ -1,6 +1,6 @@
 --- a/arch/mips/include/asm/string.h
 +++ b/arch/mips/include/asm/string.h
 --- a/arch/mips/include/asm/string.h
 +++ b/arch/mips/include/asm/string.h
-@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__
+@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__ 
  
  #define __HAVE_ARCH_MEMSET
  extern void *memset(void *__s, int __c, size_t __count);
  
  #define __HAVE_ARCH_MEMSET
  extern void *memset(void *__s, int __c, size_t __count);
index fe8cecf..83fd6c3 100644 (file)
@@ -1,6 +1,6 @@
 --- a/include/linux/slab.h
 +++ b/include/linux/slab.h
 --- a/include/linux/slab.h
 +++ b/include/linux/slab.h
-@@ -130,8 +130,8 @@ int kmem_ptr_validate(struct kmem_cache
+@@ -130,8 +130,8 @@ int kmem_ptr_validate(struct kmem_cache 
   * to do various tricks to work around compiler limitations in order to
   * ensure proper constant folding.
   */
   * to do various tricks to work around compiler limitations in order to
   * ensure proper constant folding.
   */
index adbe702..0260463 100644 (file)
@@ -1,6 +1,6 @@
 --- a/include/linux/skbuff.h
 +++ b/include/linux/skbuff.h
 --- a/include/linux/skbuff.h
 +++ b/include/linux/skbuff.h
-@@ -1372,11 +1372,18 @@ static inline int skb_network_offset(con
+@@ -1353,11 +1353,18 @@ static inline int skb_network_offset(con
   *
   * Various parts of the networking layer expect at least 32 bytes of
   * headroom, you should not reduce this.
   *
   * Various parts of the networking layer expect at least 32 bytes of
   * headroom, you should not reduce this.
@@ -19,7 +19,7 @@
  extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
  
  static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
  extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
  
  static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
-@@ -1466,9 +1473,9 @@ static inline void __skb_queue_purge(str
+@@ -1447,9 +1454,9 @@ static inline void __skb_queue_purge(str
  static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
                                              gfp_t gfp_mask)
  {
  static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
                                              gfp_t gfp_mask)
  {
@@ -31,7 +31,7 @@
        return skb;
  }
  
        return skb;
  }
  
-@@ -1551,7 +1558,7 @@ static inline int __skb_cow(struct sk_bu
+@@ -1532,7 +1539,7 @@ static inline int __skb_cow(struct sk_bu
                delta = headroom - skb_headroom(skb);
  
        if (delta || cloned)
                delta = headroom - skb_headroom(skb);
  
        if (delta || cloned)
@@ -42,7 +42,7 @@
  }
 --- a/net/core/skbuff.c
 +++ b/net/core/skbuff.c
  }
 --- a/net/core/skbuff.c
 +++ b/net/core/skbuff.c
-@@ -339,9 +339,9 @@ struct sk_buff *__netdev_alloc_skb(struc
+@@ -259,9 +259,9 @@ struct sk_buff *__netdev_alloc_skb(struc
        int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
        struct sk_buff *skb;
  
        int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
        struct sk_buff *skb;
  
index b64630d..d71e3b6 100644 (file)
@@ -61,7 +61,7 @@
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd);
  
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd);
  
-@@ -501,6 +505,29 @@ static inline void double_unlock(struct
+@@ -501,6 +505,29 @@ static inline void double_unlock(struct 
  #endif  /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
  #endif /* __KERNEL__ */
  
  #endif  /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
  #endif /* __KERNEL__ */
  
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
 --- a/fs/mini_fo/aux.c
 +++ b/fs/mini_fo/aux.c
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
 --- a/fs/mini_fo/aux.c
 +++ b/fs/mini_fo/aux.c
-@@ -164,11 +164,11 @@ dentry_t *bpath_walk(super_block_t *sb,
+@@ -164,11 +164,11 @@ dentry_t *bpath_walk(super_block_t *sb, 
        err = vfs_path_lookup(mnt->mnt_root, mnt, bpath+1, 0, &nd);
  
        /* validate */
        err = vfs_path_lookup(mnt->mnt_root, mnt, bpath+1, 0, &nd);
  
        /* validate */
index b5fa64e..8bd9ba3 100644 (file)
@@ -1,6 +1,6 @@
 --- a/fs/mini_fo/super.c
 +++ b/fs/mini_fo/super.c
 --- a/fs/mini_fo/super.c
 +++ b/fs/mini_fo/super.c
-@@ -84,6 +84,7 @@ mini_fo_write_inode(inode_t *inode, int
+@@ -84,6 +84,7 @@ mini_fo_write_inode(inode_t *inode, int 
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
  
  
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
  
  
index 1dc6550..d851d31 100644 (file)
@@ -20,7 +20,7 @@
  #else
  static inline int kobject_uevent(struct kobject *kobj,
                                 enum kobject_action action)
  #else
  static inline int kobject_uevent(struct kobject *kobj,
                                 enum kobject_action action)
-@@ -224,6 +230,16 @@ static inline int add_uevent_var(struct
+@@ -224,6 +230,16 @@ static inline int add_uevent_var(struct 
  static inline int kobject_action_type(const char *buf, size_t count,
                                      enum kobject_action *type)
  { return -EINVAL; }
  static inline int kobject_action_type(const char *buf, size_t count,
                                      enum kobject_action *type)
  { return -EINVAL; }
index e02d1bc..286bdae 100644 (file)
 +module_exit(connmark_cleanup_module);
 --- a/net/sched/Kconfig
 +++ b/net/sched/Kconfig
 +module_exit(connmark_cleanup_module);
 --- a/net/sched/Kconfig
 +++ b/net/sched/Kconfig
-@@ -549,6 +549,18 @@
+@@ -549,6 +549,18 @@ config NET_ACT_SKBEDIT
          To compile this code as a module, choose M here: the
          module will be called act_skbedit.
  
          To compile this code as a module, choose M here: the
          module will be called act_skbedit.
  
        depends on NET_CLS_U32 || NET_CLS_FW
 --- a/net/sched/Makefile
 +++ b/net/sched/Makefile
        depends on NET_CLS_U32 || NET_CLS_FW
 --- a/net/sched/Makefile
 +++ b/net/sched/Makefile
-@@ -15,6 +15,7 @@
+@@ -15,6 +15,7 @@ obj-$(CONFIG_NET_ACT_NAT)    += act_nat.o
  obj-$(CONFIG_NET_ACT_PEDIT)   += act_pedit.o
  obj-$(CONFIG_NET_ACT_SIMP)    += act_simple.o
  obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o
  obj-$(CONFIG_NET_ACT_PEDIT)   += act_pedit.o
  obj-$(CONFIG_NET_ACT_SIMP)    += act_simple.o
  obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o
index 3f43c90..4060e65 100644 (file)
@@ -11,7 +11,7 @@
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
-@@ -46,3 +46,4 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) +=
+@@ -46,3 +46,4 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += 
  obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)  += ledtrig-backlight.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)  += ledtrig-backlight.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
index 0015246..d2ceb08 100644 (file)
@@ -14,7 +14,7 @@
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
-@@ -47,3 +47,4 @@ obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) +=
+@@ -47,3 +47,4 @@ obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += 
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_MORSE)      += ledtrig-morse.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_MORSE)      += ledtrig-morse.o
index c334b17..5c70e79 100644 (file)
                        dev->checkpointBlockList[i] = -1;
        }
  
                        dev->checkpointBlockList[i] = -1;
        }
  
-@@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device
+@@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device 
  
  static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
  {
  
  static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
  {
  {
        unsigned char cDelta;   /* column parity delta */
        unsigned lDelta;        /* line parity delta */
  {
        unsigned char cDelta;   /* column parity delta */
        unsigned lDelta;        /* line parity delta */
-@@ -294,8 +292,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -294,8 +292,7 @@ int yaffs_ECCCorrectOther(unsigned char 
                return 0; /* no error */
  
        if (lDelta == ~lDeltaPrime &&
                return 0; /* no error */
  
        if (lDelta == ~lDeltaPrime &&
                /* Single bit (recoverable) error in data */
  
                bit = 0;
                /* Single bit (recoverable) error in data */
  
                bit = 0;
-@@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char 
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                        return -1;
  
                data[lDelta] ^= (1 << bit);
                        return -1;
  
                data[lDelta] ^= (1 << bit);
-@@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char 
        }
  
        if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
        }
  
        if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
                /* Reccoverable error in ecc */
  
                *read_ecc = *test_ecc;
                /* Reccoverable error in ecc */
  
                *read_ecc = *test_ecc;
-@@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char 
        /* Unrecoverable error */
  
        return -1;
        /* Unrecoverable error */
  
        return -1;
  {
        unsigned char *alias;
        int ret;
  {
        unsigned char *alias;
        int ret;
-@@ -329,7 +395,7 @@ static int yaffs_readlink(struct dentry
+@@ -329,7 +395,7 @@ static int yaffs_readlink(struct dentry 
        return ret;
  }
  
        return ret;
  }
  
  static int yaffs_file_flush(struct file *file, fl_owner_t id)
  #else
  static int yaffs_file_flush(struct file *file)
  static int yaffs_file_flush(struct file *file, fl_owner_t id)
  #else
  static int yaffs_file_flush(struct file *file)
-@@ -513,8 +579,8 @@ static int yaffs_file_flush(struct file
+@@ -513,8 +579,8 @@ static int yaffs_file_flush(struct file 
        yaffs_Device *dev = obj->myDev;
  
        T(YAFFS_TRACE_OS,
        yaffs_Device *dev = obj->myDev;
  
        T(YAFFS_TRACE_OS,
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossLock(dev);
  
-@@ -535,15 +601,15 @@ static int yaffs_readpage_nolock(struct
+@@ -535,15 +601,15 @@ static int yaffs_readpage_nolock(struct 
  
        yaffs_Device *dev;
  
  
        yaffs_Device *dev;
  
        BUG_ON(!PageLocked(pg));
  #else
        if (!PageLocked(pg))
        BUG_ON(!PageLocked(pg));
  #else
        if (!PageLocked(pg))
-@@ -555,9 +621,9 @@ static int yaffs_readpage_nolock(struct
+@@ -555,9 +621,9 @@ static int yaffs_readpage_nolock(struct 
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossUnlock(dev);
  
  
        yaffs_GrossUnlock(dev);
  
-@@ -575,7 +641,7 @@ static int yaffs_readpage_nolock(struct
+@@ -575,7 +641,7 @@ static int yaffs_readpage_nolock(struct 
        flush_dcache_page(pg);
        kunmap(pg);
  
        flush_dcache_page(pg);
        kunmap(pg);
  
                if (n < step) {
                        n++;
                        continue;
                if (n < step) {
                        n++;
                        continue;
-@@ -2119,7 +2356,7 @@ static int yaffs_proc_write(struct file
+@@ -2119,7 +2356,7 @@ static int yaffs_proc_write(struct file 
        char *end;
        char *mask_name;
        const char *x;
        char *end;
        char *mask_name;
        const char *x;
        int i;
        int done = 0;
        int add, len = 0;
        int i;
        int done = 0;
        int add, len = 0;
-@@ -2129,9 +2366,8 @@ static int yaffs_proc_write(struct file
+@@ -2129,9 +2366,8 @@ static int yaffs_proc_write(struct file 
  
        while (!done && (pos < count)) {
                done = 1;
  
        while (!done && (pos < count)) {
                done = 1;
  
                switch (buf[pos]) {
                case '+':
  
                switch (buf[pos]) {
                case '+':
-@@ -2148,20 +2384,21 @@ static int yaffs_proc_write(struct file
+@@ -2148,20 +2384,21 @@ static int yaffs_proc_write(struct file 
                mask_name = NULL;
  
                mask_bitfield = simple_strtoul(buf + pos, &end, 0);
                mask_name = NULL;
  
                mask_bitfield = simple_strtoul(buf + pos, &end, 0);
                                        mask_name = mask_flags[i].mask_name;
                                        mask_bitfield = mask_flags[i].mask_bitfield;
                                        done = 0;
                                        mask_name = mask_flags[i].mask_name;
                                        mask_bitfield = mask_flags[i].mask_bitfield;
                                        done = 0;
-@@ -2172,7 +2409,7 @@ static int yaffs_proc_write(struct file
+@@ -2172,7 +2409,7 @@ static int yaffs_proc_write(struct file 
  
                if (mask_name != NULL) {
                        done = 0;
  
                if (mask_name != NULL) {
                        done = 0;
                        case '-':
                                rg &= ~mask_bitfield;
                                break;
                        case '-':
                                rg &= ~mask_bitfield;
                                break;
-@@ -2191,13 +2428,13 @@ static int yaffs_proc_write(struct file
+@@ -2191,13 +2428,13 @@ static int yaffs_proc_write(struct file 
  
        yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
  
  
        yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
  
  {
        /* Get the real object in case we were fed a hard link as an equivalent object */
        equivalentObject = yaffs_GetEquivalentObject(equivalentObject);
  {
        /* Get the real object in case we were fed a hard link as an equivalent object */
        equivalentObject = yaffs_GetEquivalentObject(equivalentObject);
-@@ -2363,33 +2396,31 @@ yaffs_Object *yaffs_Link(yaffs_Object *
+@@ -2363,33 +2396,31 @@ yaffs_Object *yaffs_Link(yaffs_Object * 
  
  }
  
  
  }
  
        int nToCopy;
        int n = nBytes;
        int nDone = 0;
        int nToCopy;
        int n = nBytes;
        int nDone = 0;
-@@ -4600,27 +4665,26 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4600,27 +4665,26 @@ int yaffs_ReadDataFromFile(yaffs_Object 
        dev = in->myDev;
  
        while (n > 0) {
        dev = in->myDev;
  
        while (n > 0) {
                        if (dev->nShortOpCaches > 0) {
  
                                /* If we can't find the data in the cache, then load it up. */
                        if (dev->nShortOpCaches > 0) {
  
                                /* If we can't find the data in the cache, then load it up. */
-@@ -4641,14 +4705,9 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4641,14 +4705,9 @@ int yaffs_ReadDataFromFile(yaffs_Object 
  
                                cache->locked = 1;
  
  
                                cache->locked = 1;
  
                                cache->locked = 0;
                        } else {
                                /* Read into the local buffer then copy..*/
                                cache->locked = 0;
                        } else {
                                /* Read into the local buffer then copy..*/
-@@ -4657,41 +4716,19 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4657,41 +4716,19 @@ int yaffs_ReadDataFromFile(yaffs_Object 
                                    yaffs_GetTempBuffer(dev, __LINE__);
                                yaffs_ReadChunkDataFromObject(in, chunk,
                                                              localBuffer);
                                    yaffs_GetTempBuffer(dev, __LINE__);
                                yaffs_ReadChunkDataFromObject(in, chunk,
                                                              localBuffer);
                }
  
                n -= nToCopy;
                }
  
                n -= nToCopy;
-@@ -4704,28 +4741,37 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4704,28 +4741,37 @@ int yaffs_ReadDataFromFile(yaffs_Object 
        return nDone;
  }
  
        return nDone;
  }
  
        int newFullChunks;
  
        yaffs_Device *dev = in->myDev;
        int newFullChunks;
  
        yaffs_Device *dev = in->myDev;
-@@ -4955,13 +4981,11 @@ int yaffs_ResizeFile(yaffs_Object * in,
+@@ -4955,13 +4981,11 @@ int yaffs_ResizeFile(yaffs_Object * in, 
  
        yaffs_CheckGarbageCollection(dev);
  
  
        yaffs_CheckGarbageCollection(dev);
  
  
        if (newSize < oldFileSize) {
  
  
        if (newSize < oldFileSize) {
  
-@@ -4994,21 +5018,20 @@ int yaffs_ResizeFile(yaffs_Object * in,
+@@ -4994,21 +5018,20 @@ int yaffs_ResizeFile(yaffs_Object * in, 
        }
  
  
        }
  
  
  {
        obj = yaffs_GetEquivalentObject(obj);
  
  {
        obj = yaffs_GetEquivalentObject(obj);
  
-@@ -5024,7 +5047,7 @@ loff_t yaffs_GetFileSize(yaffs_Object *
+@@ -5024,7 +5047,7 @@ loff_t yaffs_GetFileSize(yaffs_Object * 
  
  
  
  
  
  
  {
        int init_failed = 0;
        unsigned x;
  {
        int init_failed = 0;
        unsigned x;
-@@ -7040,6 +7126,8 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7040,6 +7126,8 @@ int yaffs_GutsInitialise(yaffs_Device * 
        dev->chunkOffset = 0;
        dev->nFreeChunks = 0;
  
        dev->chunkOffset = 0;
        dev->nFreeChunks = 0;
  
        if (dev->startBlock == 0) {
                dev->internalStartBlock = dev->startBlock + 1;
                dev->internalEndBlock = dev->endBlock + 1;
        if (dev->startBlock == 0) {
                dev->internalStartBlock = dev->startBlock + 1;
                dev->internalEndBlock = dev->endBlock + 1;
-@@ -7049,18 +7137,18 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7049,18 +7137,18 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        /* Check geometry parameters. */
  
  
        /* Check geometry parameters. */
  
                return YAFFS_FAIL;
        }
  
                return YAFFS_FAIL;
        }
  
-@@ -7070,6 +7158,12 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7070,6 +7158,12 @@ int yaffs_GutsInitialise(yaffs_Device * 
                return YAFFS_FAIL;
        }
  
                return YAFFS_FAIL;
        }
  
        /* Got the right mix of functions? */
        if (!yaffs_CheckDevFunctions(dev)) {
                /* Function missing */
        /* Got the right mix of functions? */
        if (!yaffs_CheckDevFunctions(dev)) {
                /* Function missing */
-@@ -7097,31 +7191,18 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7097,31 +7191,18 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        dev->isMounted = 1;
  
  
        dev->isMounted = 1;
  
  
        /*
         * Calculate chunkGroupBits.
  
        /*
         * Calculate chunkGroupBits.
-@@ -7133,16 +7214,15 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7133,16 +7214,15 @@ int yaffs_GutsInitialise(yaffs_Device * 
        bits = ShiftsGE(x);
  
        /* Set up tnode width if wide tnodes are enabled. */
        bits = ShiftsGE(x);
  
        /* Set up tnode width if wide tnodes are enabled. */
                dev->tnodeWidth = 16;
  
        dev->tnodeMask = (1<<dev->tnodeWidth)-1;
                dev->tnodeWidth = 16;
  
        dev->tnodeMask = (1<<dev->tnodeWidth)-1;
-@@ -7193,7 +7273,7 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7193,7 +7273,7 @@ int yaffs_GutsInitialise(yaffs_Device * 
        dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */
  
        /* Initialise temporary buffers and caches. */
        dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */
  
        /* Initialise temporary buffers and caches. */
                init_failed = 1;
  
        dev->srCache = NULL;
                init_failed = 1;
  
        dev->srCache = NULL;
-@@ -7203,25 +7283,26 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7203,25 +7283,26 @@ int yaffs_GutsInitialise(yaffs_Device * 
        if (!init_failed &&
            dev->nShortOpCaches > 0) {
                int i;
        if (!init_failed &&
            dev->nShortOpCaches > 0) {
                int i;
                        init_failed = 1;
  
                dev->srLastUse = 0;
                        init_failed = 1;
  
                dev->srLastUse = 0;
-@@ -7229,29 +7310,30 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7229,29 +7310,30 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        dev->cacheHits = 0;
  
  
        dev->cacheHits = 0;
  
                                T(YAFFS_TRACE_ALWAYS,
                                  (TSTR("yaffs: restored from checkpoint" TENDSTR)));
                        } else {
                                T(YAFFS_TRACE_ALWAYS,
                                  (TSTR("yaffs: restored from checkpoint" TENDSTR)));
                        } else {
-@@ -7273,24 +7355,25 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7273,24 +7355,25 @@ int yaffs_GutsInitialise(yaffs_Device * 
                                dev->nBackgroundDeletions = 0;
                                dev->oldestDirtySequence = 0;
  
                                dev->nBackgroundDeletions = 0;
                                dev->oldestDirtySequence = 0;
  
                /* Clean up the mess */
                T(YAFFS_TRACE_TRACING,
                  (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR)));
                /* Clean up the mess */
                T(YAFFS_TRACE_TRACING,
                  (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR)));
-@@ -7318,7 +7401,7 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7318,7 +7401,7 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
  }
  
  
  }
  
  {
        if (etags) {
                memset(etags, 0, sizeof(*etags));
  {
        if (etags) {
                memset(etags, 0, sizeof(*etags));
-@@ -169,9 +169,9 @@ static int rettags(yaffs_ExtendedTags *
+@@ -169,9 +169,9 @@ static int rettags(yaffs_ExtendedTags * 
   * Returns YAFFS_OK or YAFFS_FAIL.
   */
  int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
   * Returns YAFFS_OK or YAFFS_FAIL.
   */
  int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
 +                      yaffs_UnpackTags2(tags, &pt);
 +              }
 +      }
 +                      yaffs_UnpackTags2(tags, &pt);
 +              }
 +      }
-+
+-      if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
+-              tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
 +      if (localData)
 +              yaffs_ReleaseTempBuffer(dev, data, __LINE__);
  
 +      if (localData)
 +              yaffs_ReleaseTempBuffer(dev, data, __LINE__);
  
--      if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
 +      if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
 +      if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
-               tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
--
++              tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
        if (retval == 0)
                return YAFFS_OK;
        else
        if (retval == 0)
                return YAFFS_OK;
        else
index 8aa43c5..b7e28d2 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/hostap/hostap_ap.c
 +++ b/drivers/net/wireless/hostap/hostap_ap.c
 --- a/drivers/net/wireless/hostap/hostap_ap.c
 +++ b/drivers/net/wireless/hostap/hostap_ap.c
-@@ -2336,13 +2336,13 @@ int prism2_ap_get_sta_qual(local_info_t
+@@ -2336,13 +2336,13 @@ int prism2_ap_get_sta_qual(local_info_t 
                addr[count].sa_family = ARPHRD_ETHER;
                memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
                if (sta->last_rx_silence == 0)
                addr[count].sa_family = ARPHRD_ETHER;
                memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
                if (sta->last_rx_silence == 0)
index bda6372..ccf01bd 100644 (file)
@@ -24,7 +24,7 @@
   * All of these routines try to estimate how many bits of randomness a
   * particular randomness source.  They do this by keeping track of the
   * first and second order deltas of the event timings.
   * All of these routines try to estimate how many bits of randomness a
   * particular randomness source.  They do this by keeping track of the
   * first and second order deltas of the event timings.
-@@ -714,6 +724,61 @@ void add_disk_randomness(struct gendisk
+@@ -714,6 +724,61 @@ void add_disk_randomness(struct gendisk 
  }
  #endif
  
  }
  #endif
  
index 2a5b0cd..e9b06d0 100644 (file)
        u32 pmucap;
  
        if (!(cc->capabilities & SSB_CHIPCO_CAP_PMU))
        u32 pmucap;
  
        if (!(cc->capabilities & SSB_CHIPCO_CAP_PMU))
-@@ -516,15 +516,12 @@ void ssb_pmu_init(struct ssb_chipcommon
+@@ -516,15 +516,12 @@ void ssb_pmu_init(struct ssb_chipcommon 
        ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n",
                    cc->pmu.rev, pmucap);
  
        ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n",
                    cc->pmu.rev, pmucap);
  
index 63834d6..0ac880c 100644 (file)
@@ -1,6 +1,6 @@
 --- a/scripts/Makefile.lib
 +++ b/scripts/Makefile.lib
 --- a/scripts/Makefile.lib
 +++ b/scripts/Makefile.lib
-@@ -238,7 +238,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^)
+@@ -238,7 +238,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^) 
  
  quiet_cmd_lzma = LZMA    $@
  cmd_lzma = (cat $(filter-out FORCE,$^) | \
  
  quiet_cmd_lzma = LZMA    $@
  cmd_lzma = (cat $(filter-out FORCE,$^) | \
index cd4da2c..1b028ed 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -372,6 +372,8 @@ static struct cfi_fixup fixup_table[] =
+@@ -372,6 +372,8 @@ static struct cfi_fixup fixup_table[] = 
  static void cfi_fixup_major_minor(struct cfi_private *cfi,
                                  struct cfi_pri_amdstd *extp)
  {
  static void cfi_fixup_major_minor(struct cfi_private *cfi,
                                  struct cfi_pri_amdstd *extp)
  {
@@ -9,7 +9,7 @@
        if (cfi->mfr == CFI_MFR_SAMSUNG && cfi->id == 0x257e &&
            extp->MajorVersion == '0')
                extp->MajorVersion = '1';
        if (cfi->mfr == CFI_MFR_SAMSUNG && cfi->id == 0x257e &&
            extp->MajorVersion == '0')
                extp->MajorVersion = '1';
-@@ -404,6 +406,9 @@ struct mtd_info *cfi_cmdset_0002(struct
+@@ -404,6 +406,9 @@ struct mtd_info *cfi_cmdset_0002(struct 
  
        mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot;
  
  
        mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot;
  
@@ -19,7 +19,7 @@
        if (cfi->cfi_mode==CFI_MODE_CFI){
                unsigned char bootloc;
                __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
        if (cfi->cfi_mode==CFI_MODE_CFI){
                unsigned char bootloc;
                __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
-@@ -417,16 +422,24 @@ struct mtd_info *cfi_cmdset_0002(struct
+@@ -417,16 +422,24 @@ struct mtd_info *cfi_cmdset_0002(struct 
                         */
                        cfi_fixup_major_minor(cfi, extp);
  
                         */
                        cfi_fixup_major_minor(cfi, extp);
  
index 83e2445..ca0c10b 100644 (file)
  
  unsigned int vced_count, vcei_count;
  
  
  unsigned int vced_count, vcei_count;
  
-@@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file
+@@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file 
        /*
         * For the first processor also print the system type
         */
        /*
         * For the first processor also print the system type
         */
index 014bb25..c00886e 100644 (file)
@@ -81,7 +81,7 @@
  htc_excalibur_s620    MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620      2391
  htc_opal              MACH_HTC_OPAL           HTC_OPAL                2392
  touchbook             MACH_TOUCHBOOK          TOUCHBOOK               2393
  htc_excalibur_s620    MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620      2391
  htc_opal              MACH_HTC_OPAL           HTC_OPAL                2392
  touchbook             MACH_TOUCHBOOK          TOUCHBOOK               2393
-@@ -2446,7 +2446,7 @@ siogentoo1               MACH_SIOGENTOO1         SIOGENTOO1
+@@ -2446,7 +2446,7 @@ siogentoo1               MACH_SIOGENTOO1         SIOGENTOO1      
  siogentoo2            MACH_SIOGENTOO2         SIOGENTOO2              2459
  sm3k                  MACH_SM3K               SM3K                    2460
  acer_tempo_f900               MACH_ACER_TEMPO_F900    ACER_TEMPO_F900         2461
  siogentoo2            MACH_SIOGENTOO2         SIOGENTOO2              2459
  sm3k                  MACH_SM3K               SM3K                    2460
  acer_tempo_f900               MACH_ACER_TEMPO_F900    ACER_TEMPO_F900         2461
index ed23fbb..a6766de 100644 (file)
  
  #include <asm/uaccess.h>
  
  
  #include <asm/uaccess.h>
  
-@@ -826,6 +827,13 @@ static int mtd_ioctl(struct file *file,
+@@ -826,6 +827,13 @@ static int mtd_ioctl(struct file *file, 
                file->f_pos = 0;
                break;
        }
                file->f_pos = 0;
                break;
        }
index 39ff04a..fa1274c 100644 (file)
@@ -71,7 +71,7 @@
        depends on NETFILTER_ADVANCED
 --- a/net/netfilter/Makefile
 +++ b/net/netfilter/Makefile
        depends on NETFILTER_ADVANCED
 --- a/net/netfilter/Makefile
 +++ b/net/netfilter/Makefile
-@@ -91,6 +91,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT)
+@@ -91,6 +91,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) 
  obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
index cd840cd..7affbb1 100644 (file)
  
                e = (struct ipt_entry *)(loc_cpu_entry + off);
                if (copy_to_user(userptr + off
  
                e = (struct ipt_entry *)(loc_cpu_entry + off);
                if (copy_to_user(userptr + off
-@@ -979,6 +1020,14 @@ copy_entries_to_user(unsigned int total_
-                       ret = -EFAULT;
+@@ -980,6 +1021,14 @@ copy_entries_to_user(unsigned int total_
                        goto free_counters;
                }
                        goto free_counters;
                }
-+
 +              flags = e->ip.flags & ~IPT_F_NO_DEF_MATCH;
 +              if (copy_to_user(userptr + off
 +                               + offsetof(struct ipt_entry, ip.flags),
 +              flags = e->ip.flags & ~IPT_F_NO_DEF_MATCH;
 +              if (copy_to_user(userptr + off
 +                               + offsetof(struct ipt_entry, ip.flags),
 +                      ret = -EFAULT;
 +                      goto free_counters;
 +              }
 +                      ret = -EFAULT;
 +                      goto free_counters;
 +              }
++
                for (i = sizeof(struct ipt_entry);
                     i < e->target_offset;
                for (i = sizeof(struct ipt_entry);
                     i < e->target_offset;
+                    i += m->u.match_size) {
diff --git a/target/linux/generic/patches-2.6.35/150-netfilter_imq.patch b/target/linux/generic/patches-2.6.35/150-netfilter_imq.patch
deleted file mode 100644 (file)
index 0195470..0000000
+++ /dev/null
@@ -1,1342 +0,0 @@
---- /dev/null
-+++ b/drivers/net/imq.c
-@@ -0,0 +1,638 @@
-+/*
-+ *             Pseudo-driver for the intermediate queue device.
-+ *
-+ *             This program is free software; you can redistribute it and/or
-+ *             modify it under the terms of the GNU General Public License
-+ *             as published by the Free Software Foundation; either version
-+ *             2 of the License, or (at your option) any later version.
-+ *
-+ * Authors:    Patrick McHardy, <kaber@trash.net>
-+ *
-+ *            The first version was written by Martin Devera, <devik@cdi.cz>
-+ *
-+ * Credits:    Jan Rafaj <imq2t@cedric.vabo.cz>
-+ *              - Update patch to 2.4.21
-+ *             Sebastian Strollo <sstrollo@nortelnetworks.com>
-+ *              - Fix "Dead-loop on netdevice imq"-issue
-+ *             Marcel Sebek <sebek64@post.cz>
-+ *              - Update to 2.6.2-rc1
-+ *
-+ *           After some time of inactivity there is a group taking care
-+ *           of IMQ again: http://www.linuximq.net
-+ *
-+ *
-+ *           2004/06/30 - New version of IMQ patch to kernels <=2.6.7
-+ *             including the following changes:
-+ *
-+ *           - Correction of ipv6 support "+"s issue (Hasso Tepper)
-+ *           - Correction of imq_init_devs() issue that resulted in
-+ *           kernel OOPS unloading IMQ as module (Norbert Buchmuller)
-+ *           - Addition of functionality to choose number of IMQ devices
-+ *           during kernel config (Andre Correa)
-+ *           - Addition of functionality to choose how IMQ hooks on
-+ *           PRE and POSTROUTING (after or before NAT) (Andre Correa)
-+ *           - Cosmetic corrections (Norbert Buchmuller) (Andre Correa)
-+ *
-+ *
-+ *             2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were
-+ *             released with almost no problems. 2.6.14-x was released
-+ *             with some important changes: nfcache was removed; After
-+ *             some weeks of trouble we figured out that some IMQ fields
-+ *             in skb were missing in skbuff.c - skb_clone and copy_skb_header.
-+ *             These functions are correctly patched by this new patch version.
-+ *
-+ *             Thanks for all who helped to figure out all the problems with
-+ *             2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX,
-+ *             Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully
-+ *             I didn't forget anybody). I apologize again for my lack of time.
-+ *
-+ *
-+ *             2008/06/17 - 2.6.25 - Changed imq.c to use qdisc_run() instead 
-+ *             of qdisc_restart() and moved qdisc_run() to tasklet to avoid
-+ *             recursive locking. New initialization routines to fix 'rmmod' not
-+ *             working anymore. Used code from ifb.c. (Jussi Kivilinna)
-+ *
-+ *             2008/08/06 - 2.6.26 - (JK)
-+ *              - Replaced tasklet with 'netif_schedule()'.
-+ *              - Cleaned up and added comments for imq_nf_queue().
-+ *
-+ *             2009/04/12
-+ *              - Add skb_save_cb/skb_restore_cb helper functions for backuping
-+ *                control buffer. This is needed because qdisc-layer on kernels
-+ *                2.6.27 and newer overwrite control buffer. (Jussi Kivilinna)
-+ *              - Add better locking for IMQ device. Hopefully this will solve
-+ *                SMP issues. (Jussi Kivilinna)
-+ *              - Port to 2.6.27
-+ *              - Port to 2.6.28
-+ *              - Port to 2.6.29 + fix rmmod not working
-+ *
-+ *             2009/04/20 - (Jussi Kivilinna)
-+ *              - Use netdevice feature flags to avoid extra packet handling
-+ *                by core networking layer and possibly increase performance.
-+ *
-+ *             2009/09/26 - (Jussi Kivilinna)
-+ *              - Add imq_nf_reinject_lockless to fix deadlock with
-+ *                imq_nf_queue/imq_nf_reinject.
-+ *
-+ *             2009/12/08 - (Jussi Kivilinna)
-+ *              - Port to 2.6.32
-+ *              - Add check for skb->nf_queue_entry==NULL in imq_dev_xmit()
-+ *              - Also add better error checking for skb->nf_queue_entry usage
-+ *
-+ *             2010/02/25 - (Jussi Kivilinna)
-+ *              - Port to 2.6.33
-+ *
-+ *             2010/08/12 - (Jussi Kivilinna)
-+ *              - Port to 2.6.35
-+ *
-+ *           Also, many thanks to pablo Sebastian Greco for making the initial
-+ *           patch and to those who helped the testing.
-+ *
-+ *             More info at: http://www.linuximq.net/ (Andre Correa)
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/moduleparam.h>
-+#include <linux/list.h>
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/if_arp.h>
-+#include <linux/netfilter.h>
-+#include <linux/netfilter_ipv4.h>
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      #include <linux/netfilter_ipv6.h>
-+#endif
-+#include <linux/imq.h>
-+#include <net/pkt_sched.h>
-+#include <net/netfilter/nf_queue.h>
-+
-+static nf_hookfn imq_nf_hook;
-+
-+static struct nf_hook_ops imq_ingress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP_PRI_LAST
-+#else
-+      .priority       = NF_IP_PRI_NAT_SRC - 1
-+#endif
-+};
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+static struct nf_hook_ops imq_ingress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP6_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP6_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP6_PRI_LAST
-+#else
-+      .priority       = NF_IP6_PRI_NAT_SRC - 1
-+#endif
-+};
-+#endif
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS;
-+#else
-+static unsigned int numdevs = IMQ_MAX_DEVS;
-+#endif
-+
-+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 */
-+}
-+
-+/* locking not needed when called from imq_nf_queue */
-+static void imq_nf_reinject_lockless(struct nf_queue_entry *entry,
-+                                              unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              nf_reinject(entry, verdict);
-+              return;
-+      }
-+
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+}
-+
-+static void imq_nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              spin_lock_bh(&imq_nf_queue_lock);
-+              nf_reinject(entry, verdict);
-+              spin_unlock_bh(&imq_nf_queue_lock);
-+              return;
-+      }
-+
-+      rcu_read_lock();
-+      local_bh_disable();
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      local_bh_enable();
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+
-+      rcu_read_unlock();
-+}
-+
-+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;
-+
-+      imq_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;
-+      struct sk_buff *skb_orig, *skb, *skb_shared;
-+      struct Qdisc *q;
-+      struct netdev_queue *txq;
-+      int users, index;
-+      int retval = -EINVAL;
-+
-+      index = entry->skb->imq_flags & IMQ_F_IFMASK;
-+      if (unlikely(index > numdevs - 1)) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING
-+                             "IMQ: invalid device specified, highest is %u\n",
-+                             numdevs - 1);
-+              retval = -EINVAL;
-+              goto out;
-+      }
-+
-+      /* check for imq device by index from cache */
-+      dev = imq_devs_cache[index];
-+      if (unlikely(!dev)) {
-+              char buf[8];
-+
-+              /* get device by name and cache result */
-+              snprintf(buf, sizeof(buf), "imq%d", index);
-+              dev = dev_get_by_name(&init_net, buf);
-+              if (!dev) {
-+                      /* not found ?!*/
-+                      BUG();
-+                      retval = -ENODEV;
-+                      goto out;
-+              }
-+
-+              imq_devs_cache[index] = dev;
-+              dev_put(dev);
-+      }
-+
-+      if (unlikely(!(dev->flags & IFF_UP))) {
-+              entry->skb->imq_flags = 0;
-+              imq_nf_reinject_lockless(entry, NF_ACCEPT);
-+              retval = 0;
-+              goto out;
-+      }
-+      dev->last_rx = jiffies;
-+
-+      skb = entry->skb;
-+      skb_orig = NULL;
-+
-+      /* skb has owner? => make clone */
-+      if (unlikely(skb->destructor)) {
-+              skb_orig = skb;
-+              skb = skb_clone(skb, GFP_ATOMIC);
-+              if (!skb) {
-+                      retval = -ENOMEM;
-+                      goto out;
-+              }
-+              entry->skb = skb;
-+      }
-+
-+      skb->nf_queue_entry = entry;
-+
-+      dev->stats.rx_bytes += skb->len;
-+      dev->stats.rx_packets++;
-+
-+      txq = dev_pick_tx(dev, skb);
-+
-+      q = rcu_dereference(txq->qdisc);
-+      if (unlikely(!q->enqueue))
-+              goto packet_not_eaten_by_imq_dev;
-+
-+      spin_lock_bh(qdisc_lock(q));
-+
-+      users = atomic_read(&skb->users);
-+
-+      skb_shared = skb_get(skb); /* increase reference count by one */
-+      skb_save_cb(skb_shared); /* backup skb->cb, as qdisc layer will
-+                                      overwrite it */
-+      qdisc_enqueue_root(skb_shared, q); /* might kfree_skb */
-+
-+      if (likely(atomic_read(&skb_shared->users) == users + 1)) {
-+              kfree_skb(skb_shared); /* decrease reference count by one */
-+
-+              skb->destructor = &imq_skb_destructor;
-+
-+              /* cloned? */
-+              if (skb_orig)
-+                      kfree_skb(skb_orig); /* free original */
-+
-+              spin_unlock_bh(qdisc_lock(q));
-+
-+              /* schedule qdisc dequeue */
-+              __netif_schedule(q);
-+
-+              retval = 0;
-+              goto out;
-+      } else {
-+              skb_restore_cb(skb_shared); /* restore skb->cb */
-+              skb->nf_queue_entry = NULL;
-+              /* qdisc dropped packet and decreased skb reference count of
-+               * skb, so we don't really want to and try refree as that would
-+               * actually destroy the skb. */
-+              spin_unlock_bh(qdisc_lock(q));
-+              goto packet_not_eaten_by_imq_dev;
-+      }
-+
-+packet_not_eaten_by_imq_dev:
-+      /* cloned? restore original */
-+      if (skb_orig) {
-+              kfree_skb(skb);
-+              entry->skb = skb_orig;
-+      }
-+      retval = -1;
-+out:
-+      return retval;
-+}
-+
-+static struct nf_queue_handler nfqh = {
-+      .name  = "imq",
-+      .outfn = imq_nf_queue,
-+};
-+
-+static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff *pskb,
-+                              const struct net_device *indev,
-+                              const struct net_device *outdev,
-+                              int (*okfn)(struct sk_buff *))
-+{
-+      if (pskb->imq_flags & IMQ_F_ENQUEUE)
-+              return NF_QUEUE;
-+
-+      return NF_ACCEPT;
-+}
-+
-+static int imq_close(struct net_device *dev)
-+{
-+      netif_stop_queue(dev);
-+      return 0;
-+}
-+
-+static int imq_open(struct net_device *dev)
-+{
-+      netif_start_queue(dev);
-+      return 0;
-+}
-+
-+static const struct net_device_ops imq_netdev_ops = {
-+      .ndo_open               = imq_open,
-+      .ndo_stop               = imq_close,
-+      .ndo_start_xmit         = imq_dev_xmit,
-+      .ndo_get_stats          = imq_get_stats,
-+};
-+
-+static void imq_setup(struct net_device *dev)
-+{
-+      dev->netdev_ops         = &imq_netdev_ops;
-+      dev->type               = ARPHRD_VOID;
-+      dev->mtu                = 16000;
-+      dev->tx_queue_len       = 11000;
-+      dev->flags              = IFF_NOARP;
-+      dev->features           = NETIF_F_SG | NETIF_F_FRAGLIST |
-+                                NETIF_F_GSO | NETIF_F_HW_CSUM |
-+                                NETIF_F_HIGHDMA;
-+      dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
-+}
-+
-+static int imq_validate(struct nlattr *tb[], struct nlattr *data[])
-+{
-+      int ret = 0;
-+
-+      if (tb[IFLA_ADDRESS]) {
-+              if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
-+                      ret = -EINVAL;
-+                      goto end;
-+              }
-+              if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) {
-+                      ret = -EADDRNOTAVAIL;
-+                      goto end;
-+              }
-+      }
-+      return 0;
-+end:
-+      printk(KERN_WARNING "IMQ: imq_validate failed (%d)\n", ret);
-+      return ret;
-+}
-+
-+static struct rtnl_link_ops imq_link_ops __read_mostly = {
-+      .kind           = "imq",
-+      .priv_size      = 0,
-+      .setup          = imq_setup,
-+      .validate       = imq_validate,
-+};
-+
-+static int __init imq_init_hooks(void)
-+{
-+      int err;
-+
-+      nf_register_queue_imq_handler(&nfqh);
-+
-+      err = nf_register_hook(&imq_ingress_ipv4);
-+      if (err)
-+              goto err1;
-+
-+      err = nf_register_hook(&imq_egress_ipv4);
-+      if (err)
-+              goto err2;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      err = nf_register_hook(&imq_ingress_ipv6);
-+      if (err)
-+              goto err3;
-+
-+      err = nf_register_hook(&imq_egress_ipv6);
-+      if (err)
-+              goto err4;
-+#endif
-+
-+      return 0;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+err4:
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+err3:
-+      nf_unregister_hook(&imq_egress_ipv4);
-+#endif
-+err2:
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+err1:
-+      nf_unregister_queue_imq_handler();
-+      return err;
-+}
-+
-+static int __init imq_init_one(int index)
-+{
-+      struct net_device *dev;
-+      int ret;
-+
-+      dev = alloc_netdev(0, "imq%d", imq_setup);
-+      if (!dev)
-+              return -ENOMEM;
-+
-+      ret = dev_alloc_name(dev, dev->name);
-+      if (ret < 0)
-+              goto fail;
-+
-+      dev->rtnl_link_ops = &imq_link_ops;
-+      ret = register_netdevice(dev);
-+      if (ret < 0)
-+              goto fail;
-+
-+      return 0;
-+fail:
-+      free_netdev(dev);
-+      return ret;
-+}
-+
-+static int __init imq_init_devs(void)
-+{
-+      int err, i;
-+
-+      if (numdevs < 1 || numdevs > IMQ_MAX_DEVS) {
-+              printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n",
-+                     IMQ_MAX_DEVS);
-+              return -EINVAL;
-+      }
-+
-+      rtnl_lock();
-+      err = __rtnl_link_register(&imq_link_ops);
-+
-+      for (i = 0; i < numdevs && !err; i++)
-+              err = imq_init_one(i);
-+
-+      if (err) {
-+              __rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+      }
-+      rtnl_unlock();
-+
-+      return err;
-+}
-+
-+static int __init imq_init_module(void)
-+{
-+      int err;
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS > 16);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS < 2);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS - 1 > IMQ_F_IFMASK);
-+#endif
-+
-+      err = imq_init_devs();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_devs(net)\n");
-+              return err;
-+      }
-+
-+      err = imq_init_hooks();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n");
-+              rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+              return err;
-+      }
-+
-+      printk(KERN_INFO "IMQ driver loaded successfully.\n");
-+
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n");
-+#endif
-+#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n");
-+#endif
-+
-+      return 0;
-+}
-+
-+static void __exit imq_unhook(void)
-+{
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+      nf_unregister_hook(&imq_egress_ipv6);
-+#endif
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+      nf_unregister_hook(&imq_egress_ipv4);
-+
-+      nf_unregister_queue_imq_handler();
-+}
-+
-+static void __exit imq_cleanup_devs(void)
-+{
-+      rtnl_link_unregister(&imq_link_ops);
-+      memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+}
-+
-+static void __exit imq_exit_module(void)
-+{
-+      imq_unhook();
-+      imq_cleanup_devs();
-+      printk(KERN_INFO "IMQ driver unloaded successfully.\n");
-+}
-+
-+module_init(imq_init_module);
-+module_exit(imq_exit_module);
-+
-+module_param(numdevs, int, 0);
-+MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will "
-+                      "be created)");
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See "
-+                      "http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS_RTNL_LINK("imq");
-+
---- a/drivers/net/Kconfig
-+++ b/drivers/net/Kconfig
-@@ -121,6 +121,129 @@ config EQUALIZER
-         To compile this driver as a module, choose M here: the module
-         will be called eql.  If unsure, say N.
-+config IMQ
-+      tristate "IMQ (intermediate queueing device) support"
-+      depends on NETDEVICES && NETFILTER
-+      ---help---
-+        The IMQ device(s) is used as placeholder for QoS queueing
-+        disciplines. Every packet entering/leaving the IP stack can be
-+        directed through the IMQ device where it's enqueued/dequeued to the
-+        attached qdisc. This allows you to treat network devices as classes
-+        and distribute bandwidth among them. Iptables is used to specify
-+        through which IMQ device, if any, packets travel.
-+
-+        More information at: http://www.linuximq.net/
-+
-+        To compile this driver as a module, choose M here: the module
-+        will be called imq.  If unsure, say N.
-+
-+choice
-+      prompt "IMQ behavior (PRE/POSTROUTING)"
-+      depends on IMQ
-+      default IMQ_BEHAVIOR_AB
-+      help
-+
-+              This settings defines how IMQ behaves in respect to its
-+              hooking in PREROUTING and POSTROUTING.
-+
-+              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
-+
-+              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.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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 settings defines how many IMQ devices will be
-+              created.
-+
-+              The default value is 16.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              If not sure leave the default settings alone.
-+
- config TUN
-       tristate "Universal TUN/TAP device driver support"
-       select CRC32
---- a/drivers/net/Makefile
-+++ b/drivers/net/Makefile
-@@ -169,6 +169,7 @@ obj-$(CONFIG_SLHC) += slhc.o
- obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o
- obj-$(CONFIG_DUMMY) += dummy.o
-+obj-$(CONFIG_IMQ) += imq.o
- obj-$(CONFIG_IFB) += ifb.o
- obj-$(CONFIG_MACVLAN) += macvlan.o
- obj-$(CONFIG_MACVTAP) += macvtap.o
---- /dev/null
-+++ b/include/linux/imq.h
-@@ -0,0 +1,13 @@
-+#ifndef _IMQ_H
-+#define _IMQ_H
-+
-+/* IFMASK (16 device indexes, 0 to 15) and flag(s) fit in 5 bits */
-+#define IMQ_F_BITS    5
-+
-+#define IMQ_F_IFMASK  0x0f
-+#define IMQ_F_ENQUEUE 0x10
-+
-+#define IMQ_MAX_DEVS  (IMQ_F_IFMASK + 1)
-+
-+#endif /* _IMQ_H */
-+
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1281,6 +1281,7 @@ extern int               dev_alloc_name(struct net_de
- extern int            dev_open(struct net_device *dev);
- extern int            dev_close(struct net_device *dev);
- extern void           dev_disable_lro(struct net_device *dev);
-+extern struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb);
- extern int            dev_queue_xmit(struct sk_buff *skb);
- extern int            register_netdevice(struct net_device *dev);
- extern void           unregister_netdevice_queue(struct net_device *dev,
---- /dev/null
-+++ b/include/linux/netfilter/xt_IMQ.h
-@@ -0,0 +1,9 @@
-+#ifndef _XT_IMQ_H
-+#define _XT_IMQ_H
-+
-+struct xt_imq_info {
-+      unsigned int todev;     /* target imq device */
-+};
-+
-+#endif /* _XT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv4/ipt_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IPT_IMQ_H
-+#define _IPT_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ipt_imq_info xt_imq_info
-+
-+#endif /* _IPT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv6/ip6t_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IP6T_IMQ_H
-+#define _IP6T_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ip6t_imq_info xt_imq_info
-+
-+#endif /* _IP6T_IMQ_H */
-+
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -29,6 +29,9 @@
- #include <linux/rcupdate.h>
- #include <linux/dmaengine.h>
- #include <linux/hrtimer.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- /* Don't change this without changing skb_csum_unnecessary! */
- #define CHECKSUM_NONE 0
-@@ -329,6 +332,9 @@ struct sk_buff {
-        * first. This is owned by whoever has the skb queued ATM.
-        */
-       char                    cb[48] __aligned(8);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      void                    *cb_next;
-+#endif
-       unsigned long           _skb_refdst;
- #ifdef CONFIG_XFRM
-@@ -365,6 +371,9 @@ struct sk_buff {
-       struct nf_conntrack     *nfct;
-       struct sk_buff          *nfct_reasm;
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      struct nf_queue_entry   *nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       struct nf_bridge_info   *nf_bridge;
- #endif
-@@ -391,6 +400,10 @@ struct sk_buff {
-       /* 0/14 bit hole */
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      __u8                    imq_flags:IMQ_F_BITS;
-+#endif
-+
- #ifdef CONFIG_NET_DMA
-       dma_cookie_t            dma_cookie;
- #endif
-@@ -489,6 +502,12 @@ static inline struct rtable *skb_rtable(
-       return (struct rtable *)skb_dst(skb);
- }
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern int skb_save_cb(struct sk_buff *skb);
-+extern int skb_restore_cb(struct sk_buff *skb);
-+#endif
-+
- extern void kfree_skb(struct sk_buff *skb);
- extern void consume_skb(struct sk_buff *skb);
- extern void          __kfree_skb(struct sk_buff *skb);
-@@ -2036,6 +2055,10 @@ static inline void __nf_copy(struct sk_b
-       dst->nfct_reasm = src->nfct_reasm;
-       nf_conntrack_get_reasm(src->nfct_reasm);
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      dst->imq_flags = src->imq_flags;
-+      dst->nf_queue_entry = src->nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       dst->nf_bridge  = src->nf_bridge;
-       nf_bridge_get(src->nf_bridge);
---- a/include/net/netfilter/nf_queue.h
-+++ b/include/net/netfilter/nf_queue.h
-@@ -13,6 +13,12 @@ struct nf_queue_entry {
-       struct net_device       *indev;
-       struct net_device       *outdev;
-       int                     (*okfn)(struct sk_buff *);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      int                     (*next_outfn)(struct nf_queue_entry *entry,
-+                                            unsigned int queuenum);
-+      unsigned int            next_queuenum;
-+#endif
- };
- #define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry))
-@@ -30,5 +36,11 @@ extern int nf_unregister_queue_handler(u
-                                      const struct nf_queue_handler *qh);
- extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
- extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
-+extern void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern void nf_register_queue_imq_handler(const struct nf_queue_handler *qh);
-+extern void nf_unregister_queue_imq_handler(void);
-+#endif
- #endif /* _NF_QUEUE_H */
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -98,6 +98,9 @@
- #include <net/net_namespace.h>
- #include <net/sock.h>
- #include <linux/rtnetlink.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- #include <linux/proc_fs.h>
- #include <linux/seq_file.h>
- #include <linux/stat.h>
-@@ -1931,7 +1934,11 @@ int dev_hard_start_xmit(struct sk_buff *
-       int rc = NETDEV_TX_OK;
-       if (likely(!skb->next)) {
--              if (!list_empty(&ptype_all))
-+              if (!list_empty(&ptype_all)
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+                      && !(skb->imq_flags & IMQ_F_ENQUEUE)
-+#endif
-+                 )
-                       dev_queue_xmit_nit(skb, dev);
-               /*
-@@ -2027,8 +2034,7 @@ static inline u16 dev_cap_txqueue(struct
-       return queue_index;
- }
--static struct netdev_queue *dev_pick_tx(struct net_device *dev,
--                                      struct sk_buff *skb)
-+struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb)
- {
-       int queue_index;
-       struct sock *sk = skb->sk;
-@@ -2057,6 +2063,7 @@ static struct netdev_queue *dev_pick_tx(
-       skb_set_queue_mapping(skb, queue_index);
-       return netdev_get_tx_queue(dev, queue_index);
- }
-+EXPORT_SYMBOL(dev_pick_tx);
- static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
-                                struct net_device *dev,
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -72,6 +72,9 @@
- static struct kmem_cache *skbuff_head_cache __read_mostly;
- static struct kmem_cache *skbuff_fclone_cache __read_mostly;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static struct kmem_cache *skbuff_cb_store_cache __read_mostly;
-+#endif
- static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
-                                 struct pipe_buffer *buf)
-@@ -91,6 +94,83 @@ static int sock_pipe_buf_steal(struct pi
-       return 1;
- }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+/* Control buffer save/restore for IMQ devices */
-+struct skb_cb_table {
-+      void                    *cb_next;
-+      atomic_t                refcnt;
-+      char                    cb[48];
-+};
-+
-+static DEFINE_SPINLOCK(skb_cb_store_lock);
-+
-+int skb_save_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      next = kmem_cache_alloc(skbuff_cb_store_cache, GFP_ATOMIC);
-+      if (!next)
-+              return -ENOMEM;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(next->cb, skb->cb, sizeof(skb->cb));
-+      next->cb_next = skb->cb_next;
-+
-+      atomic_set(&next->refcnt, 1);
-+
-+      skb->cb_next = next;
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_save_cb);
-+
-+int skb_restore_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      if (!skb->cb_next)
-+              return 0;
-+
-+      next = skb->cb_next;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(skb->cb, next->cb, sizeof(skb->cb));
-+      skb->cb_next = next->cb_next;
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      if (atomic_dec_and_test(&next->refcnt)) {
-+              kmem_cache_free(skbuff_cb_store_cache, next);
-+      }
-+
-+      spin_unlock(&skb_cb_store_lock);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_restore_cb);
-+
-+static void skb_copy_stored_cb(struct sk_buff *new, const struct sk_buff *__old)
-+{
-+      struct skb_cb_table *next;
-+      struct sk_buff *old;
-+
-+      if (!__old->cb_next) {
-+              new->cb_next = NULL;
-+              return;
-+      }
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      old = (struct sk_buff *)__old;
-+
-+      next = old->cb_next;
-+      atomic_inc(&next->refcnt);
-+      new->cb_next = next;
-+
-+      spin_unlock(&skb_cb_store_lock);
-+}
-+#endif
- /* Pipe buffer operations for a socket. */
- static const struct pipe_buf_operations sock_pipe_buf_ops = {
-@@ -391,6 +471,26 @@ static void skb_release_head_state(struc
-               WARN_ON(in_irq());
-               skb->destructor(skb);
-       }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      /* This should not happen. When it does, avoid memleak by restoring
-+      the chain of cb-backups. */
-+      while(skb->cb_next != NULL) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING "IMQ: kfree_skb: skb->cb_next: "
-+                              "%08x\n", (unsigned int)skb->cb_next);
-+
-+              skb_restore_cb(skb);
-+      }
-+      /* This should not happen either, nf_queue_entry is nullified in
-+       * imq_dev_xmit(). If we have non-NULL nf_queue_entry then we are
-+       * leaking entry pointers, maybe memory. We don't know if this is
-+       * pointer to already freed memory, or should this be freed.
-+       * If this happens we need to add refcounting, etc for nf_queue_entry.
-+       */
-+      if (skb->nf_queue_entry && net_ratelimit())
-+              printk(KERN_WARNING
-+                              "IMQ: kfree_skb: skb->nf_queue_entry != NULL");
-+#endif
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-       nf_conntrack_put(skb->nfct);
-       nf_conntrack_put_reasm(skb->nfct_reasm);
-@@ -526,6 +626,9 @@ static void __copy_skb_header(struct sk_
-       new->sp                 = secpath_get(old->sp);
- #endif
-       memcpy(new->cb, old->cb, sizeof(old->cb));
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skb_copy_stored_cb(new, old);
-+#endif
-       new->csum               = old->csum;
-       new->local_df           = old->local_df;
-       new->pkt_type           = old->pkt_type;
-@@ -2780,6 +2883,13 @@ void __init skb_init(void)
-                                               0,
-                                               SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-                                               NULL);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skbuff_cb_store_cache = kmem_cache_create("skbuff_cb_store_cache",
-+                                                sizeof(struct skb_cb_table),
-+                                                0,
-+                                                SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-+                                                NULL);
-+#endif
- }
- /**
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -448,6 +448,18 @@ config NETFILTER_XT_TARGET_LED
-         For more information on the LEDs available on your system, see
-         Documentation/leds-class.txt
-+config NETFILTER_XT_TARGET_IMQ
-+        tristate '"IMQ" target support'
-+      depends on NETFILTER_XTABLES
-+      depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+      select IMQ
-+      default m if NETFILTER_ADVANCED=n
-+        help
-+          This option adds a `IMQ' target which is used to specify if and
-+          to which imq device packets should get enqueued/dequeued.
-+
-+          To compile it as a module, choose M here.  If unsure, say N.
-+
- config NETFILTER_XT_TARGET_MARK
-       tristate '"MARK" target support'
-       depends on NETFILTER_ADVANCED
---- a/net/netfilter/Makefile
-+++ b/net/netfilter/Makefile
-@@ -50,6 +50,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSEC
- obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
-+obj-$(CONFIG_NETFILTER_XT_TARGET_IMQ) += xt_IMQ.o
- 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
---- a/net/netfilter/nf_queue.c
-+++ b/net/netfilter/nf_queue.c
-@@ -22,6 +22,26 @@ static const struct nf_queue_handler *qu
- static DEFINE_MUTEX(queue_handler_mutex);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static const struct nf_queue_handler *queue_imq_handler;
-+
-+void nf_register_queue_imq_handler(const struct nf_queue_handler *qh)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, qh);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_register_queue_imq_handler);
-+
-+void nf_unregister_queue_imq_handler(void)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, NULL);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_unregister_queue_imq_handler);
-+#endif
-+
- /* return EBUSY when somebody else is registered, return EEXIST if the
-  * same handler is registered, return 0 in case of success. */
- int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
-@@ -82,7 +102,7 @@ void nf_unregister_queue_handlers(const
- }
- EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);
--static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
-+void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
- {
-       /* Release those devices we held, or Alexey will kill me. */
-       if (entry->indev)
-@@ -102,6 +122,7 @@ static void nf_queue_entry_release_refs(
-       /* Drop reference to owner of hook which queued us. */
-       module_put(entry->elem->owner);
- }
-+EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
- /*
-  * Any packet that leaves via this function must come back
-@@ -123,12 +144,26 @@ static int __nf_queue(struct sk_buff *sk
- #endif
-       const struct nf_afinfo *afinfo;
-       const struct nf_queue_handler *qh;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      const struct nf_queue_handler *qih = NULL;
-+#endif
-       /* QUEUE == DROP if noone is waiting, to be safe. */
-       rcu_read_lock();
-       qh = rcu_dereference(queue_handler[pf]);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      if (pf == PF_INET || pf == PF_INET6)
-+#else
-+      if (pf == PF_INET)
-+#endif
-+              qih = rcu_dereference(queue_imq_handler);
-+
-+      if (!qh && !qih)
-+#else /* !IMQ */
-       if (!qh)
-+#endif
-               goto err_unlock;
-       afinfo = nf_get_afinfo(pf);
-@@ -147,6 +182,10 @@ static int __nf_queue(struct sk_buff *sk
-               .indev  = indev,
-               .outdev = outdev,
-               .okfn   = okfn,
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+              .next_outfn = qh ? qh->outfn : NULL,
-+              .next_queuenum = queuenum,
-+#endif
-       };
-       /* If it's going away, ignore hook. */
-@@ -173,8 +212,19 @@ static int __nf_queue(struct sk_buff *sk
- #endif
-       skb_dst_force(skb);
-       afinfo->saveroute(skb, entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      if (qih) {
-+              status = qih->outfn(entry, queuenum);
-+              goto imq_skip_queue;
-+      }
-+#endif
-+
-       status = qh->outfn(entry, queuenum);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+imq_skip_queue:
-+#endif
-       rcu_read_unlock();
-       if (status < 0) {
---- /dev/null
-+++ b/net/netfilter/xt_IMQ.c
-@@ -0,0 +1,73 @@
-+/*
-+ * This target marks packets to be enqueued to an imq device
-+ */
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter/x_tables.h>
-+#include <linux/netfilter/xt_IMQ.h>
-+#include <linux/imq.h>
-+
-+static unsigned int imq_target(struct sk_buff *pskb,
-+                              const struct xt_action_param *par)
-+{
-+      const struct xt_imq_info *mr = par->targinfo;
-+
-+      pskb->imq_flags = (mr->todev & IMQ_F_IFMASK) | IMQ_F_ENQUEUE;
-+
-+      return XT_CONTINUE;
-+}
-+
-+static int imq_checkentry(const struct xt_tgchk_param *par)
-+{
-+      struct xt_imq_info *mr = par->targinfo;
-+
-+      if (mr->todev > IMQ_MAX_DEVS - 1) {
-+              printk(KERN_WARNING
-+                     "IMQ: invalid device specified, highest is %u\n",
-+                     IMQ_MAX_DEVS - 1);
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static struct xt_target xt_imq_reg[] __read_mostly = {
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET6,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+};
-+
-+static int __init imq_init(void)
-+{
-+      return xt_register_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+static void __exit imq_fini(void)
-+{
-+      xt_unregister_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+module_init(imq_init);
-+module_exit(imq_fini);
-+
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("ipt_IMQ");
-+MODULE_ALIAS("ip6t_IMQ");
-+
index 977f892..5532e2b 100644 (file)
@@ -8,7 +8,7 @@
        depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
        depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
-@@ -562,7 +561,6 @@ config NETFILTER_XT_TARGET_SECMARK
+@@ -550,7 +549,6 @@ config NETFILTER_XT_TARGET_SECMARK
  
  config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
  
  config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
index e432471..6ea9ba5 100644 (file)
@@ -1,6 +1,6 @@
 --- a/arch/mips/include/asm/string.h
 +++ b/arch/mips/include/asm/string.h
 --- a/arch/mips/include/asm/string.h
 +++ b/arch/mips/include/asm/string.h
-@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__
+@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__ 
  
  #define __HAVE_ARCH_MEMSET
  extern void *memset(void *__s, int __c, size_t __count);
  
  #define __HAVE_ARCH_MEMSET
  extern void *memset(void *__s, int __c, size_t __count);
index fe8cecf..83fd6c3 100644 (file)
@@ -1,6 +1,6 @@
 --- a/include/linux/slab.h
 +++ b/include/linux/slab.h
 --- a/include/linux/slab.h
 +++ b/include/linux/slab.h
-@@ -130,8 +130,8 @@ int kmem_ptr_validate(struct kmem_cache
+@@ -130,8 +130,8 @@ int kmem_ptr_validate(struct kmem_cache 
   * to do various tricks to work around compiler limitations in order to
   * ensure proper constant folding.
   */
   * to do various tricks to work around compiler limitations in order to
   * ensure proper constant folding.
   */
index b64630d..d71e3b6 100644 (file)
@@ -61,7 +61,7 @@
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd);
  
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd);
  
-@@ -501,6 +505,29 @@ static inline void double_unlock(struct
+@@ -501,6 +505,29 @@ static inline void double_unlock(struct 
  #endif  /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
  #endif /* __KERNEL__ */
  
  #endif  /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
  #endif /* __KERNEL__ */
  
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
 --- a/fs/mini_fo/aux.c
 +++ b/fs/mini_fo/aux.c
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
 --- a/fs/mini_fo/aux.c
 +++ b/fs/mini_fo/aux.c
-@@ -164,11 +164,11 @@ dentry_t *bpath_walk(super_block_t *sb,
+@@ -164,11 +164,11 @@ dentry_t *bpath_walk(super_block_t *sb, 
        err = vfs_path_lookup(mnt->mnt_root, mnt, bpath+1, 0, &nd);
  
        /* validate */
        err = vfs_path_lookup(mnt->mnt_root, mnt, bpath+1, 0, &nd);
  
        /* validate */
index b5fa64e..8bd9ba3 100644 (file)
@@ -1,6 +1,6 @@
 --- a/fs/mini_fo/super.c
 +++ b/fs/mini_fo/super.c
 --- a/fs/mini_fo/super.c
 +++ b/fs/mini_fo/super.c
-@@ -84,6 +84,7 @@ mini_fo_write_inode(inode_t *inode, int
+@@ -84,6 +84,7 @@ mini_fo_write_inode(inode_t *inode, int 
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
  
  
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
  
  
index 14a3684..c09e13e 100644 (file)
@@ -20,7 +20,7 @@
  #else
  static inline int kobject_uevent(struct kobject *kobj,
                                 enum kobject_action action)
  #else
  static inline int kobject_uevent(struct kobject *kobj,
                                 enum kobject_action action)
-@@ -262,6 +268,16 @@ static inline int add_uevent_var(struct
+@@ -262,6 +268,16 @@ static inline int add_uevent_var(struct 
  static inline int kobject_action_type(const char *buf, size_t count,
                                      enum kobject_action *type)
  { return -EINVAL; }
  static inline int kobject_action_type(const char *buf, size_t count,
                                      enum kobject_action *type)
  { return -EINVAL; }
index e02d1bc..286bdae 100644 (file)
 +module_exit(connmark_cleanup_module);
 --- a/net/sched/Kconfig
 +++ b/net/sched/Kconfig
 +module_exit(connmark_cleanup_module);
 --- a/net/sched/Kconfig
 +++ b/net/sched/Kconfig
-@@ -549,6 +549,18 @@
+@@ -549,6 +549,18 @@ config NET_ACT_SKBEDIT
          To compile this code as a module, choose M here: the
          module will be called act_skbedit.
  
          To compile this code as a module, choose M here: the
          module will be called act_skbedit.
  
        depends on NET_CLS_U32 || NET_CLS_FW
 --- a/net/sched/Makefile
 +++ b/net/sched/Makefile
        depends on NET_CLS_U32 || NET_CLS_FW
 --- a/net/sched/Makefile
 +++ b/net/sched/Makefile
-@@ -15,6 +15,7 @@
+@@ -15,6 +15,7 @@ obj-$(CONFIG_NET_ACT_NAT)    += act_nat.o
  obj-$(CONFIG_NET_ACT_PEDIT)   += act_pedit.o
  obj-$(CONFIG_NET_ACT_SIMP)    += act_simple.o
  obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o
  obj-$(CONFIG_NET_ACT_PEDIT)   += act_pedit.o
  obj-$(CONFIG_NET_ACT_SIMP)    += act_simple.o
  obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o
index ef8017b..9630940 100644 (file)
@@ -11,7 +11,7 @@
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
-@@ -48,3 +48,4 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) +=
+@@ -48,3 +48,4 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += 
  obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)  += ledtrig-backlight.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)  += ledtrig-backlight.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
index 0c52f63..100dea6 100644 (file)
@@ -14,7 +14,7 @@
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
-@@ -49,3 +49,4 @@ obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) +=
+@@ -49,3 +49,4 @@ obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += 
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_MORSE)      += ledtrig-morse.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_MORSE)      += ledtrig-morse.o
index c334b17..5c70e79 100644 (file)
                        dev->checkpointBlockList[i] = -1;
        }
  
                        dev->checkpointBlockList[i] = -1;
        }
  
-@@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device
+@@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device 
  
  static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
  {
  
  static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
  {
  {
        unsigned char cDelta;   /* column parity delta */
        unsigned lDelta;        /* line parity delta */
  {
        unsigned char cDelta;   /* column parity delta */
        unsigned lDelta;        /* line parity delta */
-@@ -294,8 +292,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -294,8 +292,7 @@ int yaffs_ECCCorrectOther(unsigned char 
                return 0; /* no error */
  
        if (lDelta == ~lDeltaPrime &&
                return 0; /* no error */
  
        if (lDelta == ~lDeltaPrime &&
                /* Single bit (recoverable) error in data */
  
                bit = 0;
                /* Single bit (recoverable) error in data */
  
                bit = 0;
-@@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char 
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                        return -1;
  
                data[lDelta] ^= (1 << bit);
                        return -1;
  
                data[lDelta] ^= (1 << bit);
-@@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char 
        }
  
        if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
        }
  
        if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
                /* Reccoverable error in ecc */
  
                *read_ecc = *test_ecc;
                /* Reccoverable error in ecc */
  
                *read_ecc = *test_ecc;
-@@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char 
        /* Unrecoverable error */
  
        return -1;
        /* Unrecoverable error */
  
        return -1;
  {
        unsigned char *alias;
        int ret;
  {
        unsigned char *alias;
        int ret;
-@@ -329,7 +395,7 @@ static int yaffs_readlink(struct dentry
+@@ -329,7 +395,7 @@ static int yaffs_readlink(struct dentry 
        return ret;
  }
  
        return ret;
  }
  
  static int yaffs_file_flush(struct file *file, fl_owner_t id)
  #else
  static int yaffs_file_flush(struct file *file)
  static int yaffs_file_flush(struct file *file, fl_owner_t id)
  #else
  static int yaffs_file_flush(struct file *file)
-@@ -513,8 +579,8 @@ static int yaffs_file_flush(struct file
+@@ -513,8 +579,8 @@ static int yaffs_file_flush(struct file 
        yaffs_Device *dev = obj->myDev;
  
        T(YAFFS_TRACE_OS,
        yaffs_Device *dev = obj->myDev;
  
        T(YAFFS_TRACE_OS,
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossLock(dev);
  
-@@ -535,15 +601,15 @@ static int yaffs_readpage_nolock(struct
+@@ -535,15 +601,15 @@ static int yaffs_readpage_nolock(struct 
  
        yaffs_Device *dev;
  
  
        yaffs_Device *dev;
  
        BUG_ON(!PageLocked(pg));
  #else
        if (!PageLocked(pg))
        BUG_ON(!PageLocked(pg));
  #else
        if (!PageLocked(pg))
-@@ -555,9 +621,9 @@ static int yaffs_readpage_nolock(struct
+@@ -555,9 +621,9 @@ static int yaffs_readpage_nolock(struct 
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossUnlock(dev);
  
  
        yaffs_GrossUnlock(dev);
  
-@@ -575,7 +641,7 @@ static int yaffs_readpage_nolock(struct
+@@ -575,7 +641,7 @@ static int yaffs_readpage_nolock(struct 
        flush_dcache_page(pg);
        kunmap(pg);
  
        flush_dcache_page(pg);
        kunmap(pg);
  
                if (n < step) {
                        n++;
                        continue;
                if (n < step) {
                        n++;
                        continue;
-@@ -2119,7 +2356,7 @@ static int yaffs_proc_write(struct file
+@@ -2119,7 +2356,7 @@ static int yaffs_proc_write(struct file 
        char *end;
        char *mask_name;
        const char *x;
        char *end;
        char *mask_name;
        const char *x;
        int i;
        int done = 0;
        int add, len = 0;
        int i;
        int done = 0;
        int add, len = 0;
-@@ -2129,9 +2366,8 @@ static int yaffs_proc_write(struct file
+@@ -2129,9 +2366,8 @@ static int yaffs_proc_write(struct file 
  
        while (!done && (pos < count)) {
                done = 1;
  
        while (!done && (pos < count)) {
                done = 1;
  
                switch (buf[pos]) {
                case '+':
  
                switch (buf[pos]) {
                case '+':
-@@ -2148,20 +2384,21 @@ static int yaffs_proc_write(struct file
+@@ -2148,20 +2384,21 @@ static int yaffs_proc_write(struct file 
                mask_name = NULL;
  
                mask_bitfield = simple_strtoul(buf + pos, &end, 0);
                mask_name = NULL;
  
                mask_bitfield = simple_strtoul(buf + pos, &end, 0);
                                        mask_name = mask_flags[i].mask_name;
                                        mask_bitfield = mask_flags[i].mask_bitfield;
                                        done = 0;
                                        mask_name = mask_flags[i].mask_name;
                                        mask_bitfield = mask_flags[i].mask_bitfield;
                                        done = 0;
-@@ -2172,7 +2409,7 @@ static int yaffs_proc_write(struct file
+@@ -2172,7 +2409,7 @@ static int yaffs_proc_write(struct file 
  
                if (mask_name != NULL) {
                        done = 0;
  
                if (mask_name != NULL) {
                        done = 0;
                        case '-':
                                rg &= ~mask_bitfield;
                                break;
                        case '-':
                                rg &= ~mask_bitfield;
                                break;
-@@ -2191,13 +2428,13 @@ static int yaffs_proc_write(struct file
+@@ -2191,13 +2428,13 @@ static int yaffs_proc_write(struct file 
  
        yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
  
  
        yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
  
  {
        /* Get the real object in case we were fed a hard link as an equivalent object */
        equivalentObject = yaffs_GetEquivalentObject(equivalentObject);
  {
        /* Get the real object in case we were fed a hard link as an equivalent object */
        equivalentObject = yaffs_GetEquivalentObject(equivalentObject);
-@@ -2363,33 +2396,31 @@ yaffs_Object *yaffs_Link(yaffs_Object *
+@@ -2363,33 +2396,31 @@ yaffs_Object *yaffs_Link(yaffs_Object * 
  
  }
  
  
  }
  
        int nToCopy;
        int n = nBytes;
        int nDone = 0;
        int nToCopy;
        int n = nBytes;
        int nDone = 0;
-@@ -4600,27 +4665,26 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4600,27 +4665,26 @@ int yaffs_ReadDataFromFile(yaffs_Object 
        dev = in->myDev;
  
        while (n > 0) {
        dev = in->myDev;
  
        while (n > 0) {
                        if (dev->nShortOpCaches > 0) {
  
                                /* If we can't find the data in the cache, then load it up. */
                        if (dev->nShortOpCaches > 0) {
  
                                /* If we can't find the data in the cache, then load it up. */
-@@ -4641,14 +4705,9 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4641,14 +4705,9 @@ int yaffs_ReadDataFromFile(yaffs_Object 
  
                                cache->locked = 1;
  
  
                                cache->locked = 1;
  
                                cache->locked = 0;
                        } else {
                                /* Read into the local buffer then copy..*/
                                cache->locked = 0;
                        } else {
                                /* Read into the local buffer then copy..*/
-@@ -4657,41 +4716,19 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4657,41 +4716,19 @@ int yaffs_ReadDataFromFile(yaffs_Object 
                                    yaffs_GetTempBuffer(dev, __LINE__);
                                yaffs_ReadChunkDataFromObject(in, chunk,
                                                              localBuffer);
                                    yaffs_GetTempBuffer(dev, __LINE__);
                                yaffs_ReadChunkDataFromObject(in, chunk,
                                                              localBuffer);
                }
  
                n -= nToCopy;
                }
  
                n -= nToCopy;
-@@ -4704,28 +4741,37 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4704,28 +4741,37 @@ int yaffs_ReadDataFromFile(yaffs_Object 
        return nDone;
  }
  
        return nDone;
  }
  
        int newFullChunks;
  
        yaffs_Device *dev = in->myDev;
        int newFullChunks;
  
        yaffs_Device *dev = in->myDev;
-@@ -4955,13 +4981,11 @@ int yaffs_ResizeFile(yaffs_Object * in,
+@@ -4955,13 +4981,11 @@ int yaffs_ResizeFile(yaffs_Object * in, 
  
        yaffs_CheckGarbageCollection(dev);
  
  
        yaffs_CheckGarbageCollection(dev);
  
  
        if (newSize < oldFileSize) {
  
  
        if (newSize < oldFileSize) {
  
-@@ -4994,21 +5018,20 @@ int yaffs_ResizeFile(yaffs_Object * in,
+@@ -4994,21 +5018,20 @@ int yaffs_ResizeFile(yaffs_Object * in, 
        }
  
  
        }
  
  
  {
        obj = yaffs_GetEquivalentObject(obj);
  
  {
        obj = yaffs_GetEquivalentObject(obj);
  
-@@ -5024,7 +5047,7 @@ loff_t yaffs_GetFileSize(yaffs_Object *
+@@ -5024,7 +5047,7 @@ loff_t yaffs_GetFileSize(yaffs_Object * 
  
  
  
  
  
  
  {
        int init_failed = 0;
        unsigned x;
  {
        int init_failed = 0;
        unsigned x;
-@@ -7040,6 +7126,8 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7040,6 +7126,8 @@ int yaffs_GutsInitialise(yaffs_Device * 
        dev->chunkOffset = 0;
        dev->nFreeChunks = 0;
  
        dev->chunkOffset = 0;
        dev->nFreeChunks = 0;
  
        if (dev->startBlock == 0) {
                dev->internalStartBlock = dev->startBlock + 1;
                dev->internalEndBlock = dev->endBlock + 1;
        if (dev->startBlock == 0) {
                dev->internalStartBlock = dev->startBlock + 1;
                dev->internalEndBlock = dev->endBlock + 1;
-@@ -7049,18 +7137,18 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7049,18 +7137,18 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        /* Check geometry parameters. */
  
  
        /* Check geometry parameters. */
  
                return YAFFS_FAIL;
        }
  
                return YAFFS_FAIL;
        }
  
-@@ -7070,6 +7158,12 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7070,6 +7158,12 @@ int yaffs_GutsInitialise(yaffs_Device * 
                return YAFFS_FAIL;
        }
  
                return YAFFS_FAIL;
        }
  
        /* Got the right mix of functions? */
        if (!yaffs_CheckDevFunctions(dev)) {
                /* Function missing */
        /* Got the right mix of functions? */
        if (!yaffs_CheckDevFunctions(dev)) {
                /* Function missing */
-@@ -7097,31 +7191,18 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7097,31 +7191,18 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        dev->isMounted = 1;
  
  
        dev->isMounted = 1;
  
  
        /*
         * Calculate chunkGroupBits.
  
        /*
         * Calculate chunkGroupBits.
-@@ -7133,16 +7214,15 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7133,16 +7214,15 @@ int yaffs_GutsInitialise(yaffs_Device * 
        bits = ShiftsGE(x);
  
        /* Set up tnode width if wide tnodes are enabled. */
        bits = ShiftsGE(x);
  
        /* Set up tnode width if wide tnodes are enabled. */
                dev->tnodeWidth = 16;
  
        dev->tnodeMask = (1<<dev->tnodeWidth)-1;
                dev->tnodeWidth = 16;
  
        dev->tnodeMask = (1<<dev->tnodeWidth)-1;
-@@ -7193,7 +7273,7 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7193,7 +7273,7 @@ int yaffs_GutsInitialise(yaffs_Device * 
        dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */
  
        /* Initialise temporary buffers and caches. */
        dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */
  
        /* Initialise temporary buffers and caches. */
                init_failed = 1;
  
        dev->srCache = NULL;
                init_failed = 1;
  
        dev->srCache = NULL;
-@@ -7203,25 +7283,26 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7203,25 +7283,26 @@ int yaffs_GutsInitialise(yaffs_Device * 
        if (!init_failed &&
            dev->nShortOpCaches > 0) {
                int i;
        if (!init_failed &&
            dev->nShortOpCaches > 0) {
                int i;
                        init_failed = 1;
  
                dev->srLastUse = 0;
                        init_failed = 1;
  
                dev->srLastUse = 0;
-@@ -7229,29 +7310,30 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7229,29 +7310,30 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        dev->cacheHits = 0;
  
  
        dev->cacheHits = 0;
  
                                T(YAFFS_TRACE_ALWAYS,
                                  (TSTR("yaffs: restored from checkpoint" TENDSTR)));
                        } else {
                                T(YAFFS_TRACE_ALWAYS,
                                  (TSTR("yaffs: restored from checkpoint" TENDSTR)));
                        } else {
-@@ -7273,24 +7355,25 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7273,24 +7355,25 @@ int yaffs_GutsInitialise(yaffs_Device * 
                                dev->nBackgroundDeletions = 0;
                                dev->oldestDirtySequence = 0;
  
                                dev->nBackgroundDeletions = 0;
                                dev->oldestDirtySequence = 0;
  
                /* Clean up the mess */
                T(YAFFS_TRACE_TRACING,
                  (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR)));
                /* Clean up the mess */
                T(YAFFS_TRACE_TRACING,
                  (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR)));
-@@ -7318,7 +7401,7 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7318,7 +7401,7 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
  }
  
  
  }
  
  {
        if (etags) {
                memset(etags, 0, sizeof(*etags));
  {
        if (etags) {
                memset(etags, 0, sizeof(*etags));
-@@ -169,9 +169,9 @@ static int rettags(yaffs_ExtendedTags *
+@@ -169,9 +169,9 @@ static int rettags(yaffs_ExtendedTags * 
   * Returns YAFFS_OK or YAFFS_FAIL.
   */
  int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
   * Returns YAFFS_OK or YAFFS_FAIL.
   */
  int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
 +                      yaffs_UnpackTags2(tags, &pt);
 +              }
 +      }
 +                      yaffs_UnpackTags2(tags, &pt);
 +              }
 +      }
-+
+-      if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
+-              tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
 +      if (localData)
 +              yaffs_ReleaseTempBuffer(dev, data, __LINE__);
  
 +      if (localData)
 +              yaffs_ReleaseTempBuffer(dev, data, __LINE__);
  
--      if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
 +      if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
 +      if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
-               tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
--
++              tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
        if (retval == 0)
                return YAFFS_OK;
        else
        if (retval == 0)
                return YAFFS_OK;
        else
index 0fa81eb..5c2d382 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/hostap/hostap_ap.c
 +++ b/drivers/net/wireless/hostap/hostap_ap.c
 --- a/drivers/net/wireless/hostap/hostap_ap.c
 +++ b/drivers/net/wireless/hostap/hostap_ap.c
-@@ -2336,13 +2336,13 @@ int prism2_ap_get_sta_qual(local_info_t
+@@ -2336,13 +2336,13 @@ int prism2_ap_get_sta_qual(local_info_t 
                addr[count].sa_family = ARPHRD_ETHER;
                memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
                if (sta->last_rx_silence == 0)
                addr[count].sa_family = ARPHRD_ETHER;
                memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
                if (sta->last_rx_silence == 0)
index 3b6b7d9..fe96d79 100644 (file)
@@ -24,7 +24,7 @@
   * All of these routines try to estimate how many bits of randomness a
   * particular randomness source.  They do this by keeping track of the
   * first and second order deltas of the event timings.
   * All of these routines try to estimate how many bits of randomness a
   * particular randomness source.  They do this by keeping track of the
   * first and second order deltas of the event timings.
-@@ -715,6 +725,61 @@ void add_disk_randomness(struct gendisk
+@@ -715,6 +725,61 @@ void add_disk_randomness(struct gendisk 
  }
  #endif
  
  }
  #endif
  
index 35d0515..35c97ab 100644 (file)
        u32 pmucap;
  
        if (!(cc->capabilities & SSB_CHIPCO_CAP_PMU))
        u32 pmucap;
  
        if (!(cc->capabilities & SSB_CHIPCO_CAP_PMU))
-@@ -516,15 +516,12 @@ void ssb_pmu_init(struct ssb_chipcommon
+@@ -516,15 +516,12 @@ void ssb_pmu_init(struct ssb_chipcommon 
        ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n",
                    cc->pmu.rev, pmucap);
  
        ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n",
                    cc->pmu.rev, pmucap);
  
index 77161f6..e63d733 100644 (file)
@@ -1,6 +1,6 @@
 --- a/scripts/Makefile.lib
 +++ b/scripts/Makefile.lib
 --- a/scripts/Makefile.lib
 +++ b/scripts/Makefile.lib
-@@ -238,7 +238,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^)
+@@ -238,7 +238,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^) 
  
  quiet_cmd_lzma = LZMA    $@
  cmd_lzma = (cat $(filter-out FORCE,$^) | \
  
  quiet_cmd_lzma = LZMA    $@
  cmd_lzma = (cat $(filter-out FORCE,$^) | \
index 5e16d96..2015aa0 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -418,9 +418,9 @@ struct mtd_info *cfi_cmdset_0002(struct
+@@ -418,9 +418,9 @@ struct mtd_info *cfi_cmdset_0002(struct 
  
                        /*
                         * Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4
  
                        /*
                         * Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4
index a77913d..64b9781 100644 (file)
  
  unsigned int vced_count, vcei_count;
  
  
  unsigned int vced_count, vcei_count;
  
-@@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file
+@@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file 
        /*
         * For the first processor also print the system type
         */
        /*
         * For the first processor also print the system type
         */
index faea9a4..9c90fc7 100644 (file)
@@ -81,7 +81,7 @@
  htc_excalibur_s620    MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620      2391
  htc_opal              MACH_HTC_OPAL           HTC_OPAL                2392
  touchbook             MACH_TOUCHBOOK          TOUCHBOOK               2393
  htc_excalibur_s620    MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620      2391
  htc_opal              MACH_HTC_OPAL           HTC_OPAL                2392
  touchbook             MACH_TOUCHBOOK          TOUCHBOOK               2393
-@@ -2446,7 +2446,7 @@ siogentoo1               MACH_SIOGENTOO1         SIOGENTOO1
+@@ -2446,7 +2446,7 @@ siogentoo1               MACH_SIOGENTOO1         SIOGENTOO1      
  siogentoo2            MACH_SIOGENTOO2         SIOGENTOO2              2459
  sm3k                  MACH_SM3K               SM3K                    2460
  acer_tempo_f900               MACH_ACER_TEMPO_F900    ACER_TEMPO_F900         2461
  siogentoo2            MACH_SIOGENTOO2         SIOGENTOO2              2459
  sm3k                  MACH_SM3K               SM3K                    2460
  acer_tempo_f900               MACH_ACER_TEMPO_F900    ACER_TEMPO_F900         2461
index fac77f5..74471f1 100644 (file)
  
  #include <linux/mtd/mtd.h>
  #include <linux/mtd/map.h>
  
  #include <linux/mtd/mtd.h>
  #include <linux/mtd/map.h>
-@@ -854,6 +855,13 @@ static int mtd_ioctl(struct file *file,
+@@ -854,6 +855,13 @@ static int mtd_ioctl(struct file *file, 
                file->f_pos = 0;
                break;
        }
                file->f_pos = 0;
                break;
        }
index bdbb325..876e2dc 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -371,9 +371,34 @@ static struct cfi_fixup fixup_table[] =
+@@ -371,9 +371,34 @@ static struct cfi_fixup fixup_table[] = 
  static void cfi_fixup_major_minor(struct cfi_private *cfi,
                                  struct cfi_pri_amdstd *extp)
  {
  static void cfi_fixup_major_minor(struct cfi_private *cfi,
                                  struct cfi_pri_amdstd *extp)
  {
index 4d969e2..606ff07 100644 (file)
@@ -30,7 +30,7 @@
        depends on NETFILTER_ADVANCED
 --- a/net/netfilter/Makefile
 +++ b/net/netfilter/Makefile
        depends on NETFILTER_ADVANCED
 --- a/net/netfilter/Makefile
 +++ b/net/netfilter/Makefile
-@@ -95,6 +95,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT)
+@@ -95,6 +95,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) 
  obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
index b146502..a99eb08 100644 (file)
  
                e = (struct ipt_entry *)(loc_cpu_entry + off);
                if (copy_to_user(userptr + off
  
                e = (struct ipt_entry *)(loc_cpu_entry + off);
                if (copy_to_user(userptr + off
-@@ -983,6 +1024,14 @@ copy_entries_to_user(unsigned int total_
-                       ret = -EFAULT;
+@@ -984,6 +1025,14 @@ copy_entries_to_user(unsigned int total_
                        goto free_counters;
                }
                        goto free_counters;
                }
-+
 +              flags = e->ip.flags & ~IPT_F_NO_DEF_MATCH;
 +              if (copy_to_user(userptr + off
 +                               + offsetof(struct ipt_entry, ip.flags),
 +              flags = e->ip.flags & ~IPT_F_NO_DEF_MATCH;
 +              if (copy_to_user(userptr + off
 +                               + offsetof(struct ipt_entry, ip.flags),
 +                      ret = -EFAULT;
 +                      goto free_counters;
 +              }
 +                      ret = -EFAULT;
 +                      goto free_counters;
 +              }
++
                for (i = sizeof(struct ipt_entry);
                     i < e->target_offset;
                for (i = sizeof(struct ipt_entry);
                     i < e->target_offset;
+                    i += m->u.match_size) {
diff --git a/target/linux/generic/patches-2.6.36/150-netfilter_imq.patch b/target/linux/generic/patches-2.6.36/150-netfilter_imq.patch
deleted file mode 100644 (file)
index 2fb90cf..0000000
+++ /dev/null
@@ -1,1342 +0,0 @@
---- /dev/null
-+++ b/drivers/net/imq.c
-@@ -0,0 +1,638 @@
-+/*
-+ *             Pseudo-driver for the intermediate queue device.
-+ *
-+ *             This program is free software; you can redistribute it and/or
-+ *             modify it under the terms of the GNU General Public License
-+ *             as published by the Free Software Foundation; either version
-+ *             2 of the License, or (at your option) any later version.
-+ *
-+ * Authors:    Patrick McHardy, <kaber@trash.net>
-+ *
-+ *            The first version was written by Martin Devera, <devik@cdi.cz>
-+ *
-+ * Credits:    Jan Rafaj <imq2t@cedric.vabo.cz>
-+ *              - Update patch to 2.4.21
-+ *             Sebastian Strollo <sstrollo@nortelnetworks.com>
-+ *              - Fix "Dead-loop on netdevice imq"-issue
-+ *             Marcel Sebek <sebek64@post.cz>
-+ *              - Update to 2.6.2-rc1
-+ *
-+ *           After some time of inactivity there is a group taking care
-+ *           of IMQ again: http://www.linuximq.net
-+ *
-+ *
-+ *           2004/06/30 - New version of IMQ patch to kernels <=2.6.7
-+ *             including the following changes:
-+ *
-+ *           - Correction of ipv6 support "+"s issue (Hasso Tepper)
-+ *           - Correction of imq_init_devs() issue that resulted in
-+ *           kernel OOPS unloading IMQ as module (Norbert Buchmuller)
-+ *           - Addition of functionality to choose number of IMQ devices
-+ *           during kernel config (Andre Correa)
-+ *           - Addition of functionality to choose how IMQ hooks on
-+ *           PRE and POSTROUTING (after or before NAT) (Andre Correa)
-+ *           - Cosmetic corrections (Norbert Buchmuller) (Andre Correa)
-+ *
-+ *
-+ *             2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were
-+ *             released with almost no problems. 2.6.14-x was released
-+ *             with some important changes: nfcache was removed; After
-+ *             some weeks of trouble we figured out that some IMQ fields
-+ *             in skb were missing in skbuff.c - skb_clone and copy_skb_header.
-+ *             These functions are correctly patched by this new patch version.
-+ *
-+ *             Thanks for all who helped to figure out all the problems with
-+ *             2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX,
-+ *             Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully
-+ *             I didn't forget anybody). I apologize again for my lack of time.
-+ *
-+ *
-+ *             2008/06/17 - 2.6.25 - Changed imq.c to use qdisc_run() instead 
-+ *             of qdisc_restart() and moved qdisc_run() to tasklet to avoid
-+ *             recursive locking. New initialization routines to fix 'rmmod' not
-+ *             working anymore. Used code from ifb.c. (Jussi Kivilinna)
-+ *
-+ *             2008/08/06 - 2.6.26 - (JK)
-+ *              - Replaced tasklet with 'netif_schedule()'.
-+ *              - Cleaned up and added comments for imq_nf_queue().
-+ *
-+ *             2009/04/12
-+ *              - Add skb_save_cb/skb_restore_cb helper functions for backuping
-+ *                control buffer. This is needed because qdisc-layer on kernels
-+ *                2.6.27 and newer overwrite control buffer. (Jussi Kivilinna)
-+ *              - Add better locking for IMQ device. Hopefully this will solve
-+ *                SMP issues. (Jussi Kivilinna)
-+ *              - Port to 2.6.27
-+ *              - Port to 2.6.28
-+ *              - Port to 2.6.29 + fix rmmod not working
-+ *
-+ *             2009/04/20 - (Jussi Kivilinna)
-+ *              - Use netdevice feature flags to avoid extra packet handling
-+ *                by core networking layer and possibly increase performance.
-+ *
-+ *             2009/09/26 - (Jussi Kivilinna)
-+ *              - Add imq_nf_reinject_lockless to fix deadlock with
-+ *                imq_nf_queue/imq_nf_reinject.
-+ *
-+ *             2009/12/08 - (Jussi Kivilinna)
-+ *              - Port to 2.6.32
-+ *              - Add check for skb->nf_queue_entry==NULL in imq_dev_xmit()
-+ *              - Also add better error checking for skb->nf_queue_entry usage
-+ *
-+ *             2010/02/25 - (Jussi Kivilinna)
-+ *              - Port to 2.6.33
-+ *
-+ *             2010/08/12 - (Jussi Kivilinna)
-+ *              - Port to 2.6.35
-+ *
-+ *           Also, many thanks to pablo Sebastian Greco for making the initial
-+ *           patch and to those who helped the testing.
-+ *
-+ *             More info at: http://www.linuximq.net/ (Andre Correa)
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/moduleparam.h>
-+#include <linux/list.h>
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/if_arp.h>
-+#include <linux/netfilter.h>
-+#include <linux/netfilter_ipv4.h>
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      #include <linux/netfilter_ipv6.h>
-+#endif
-+#include <linux/imq.h>
-+#include <net/pkt_sched.h>
-+#include <net/netfilter/nf_queue.h>
-+
-+static nf_hookfn imq_nf_hook;
-+
-+static struct nf_hook_ops imq_ingress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP_PRI_LAST
-+#else
-+      .priority       = NF_IP_PRI_NAT_SRC - 1
-+#endif
-+};
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+static struct nf_hook_ops imq_ingress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP6_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP6_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP6_PRI_LAST
-+#else
-+      .priority       = NF_IP6_PRI_NAT_SRC - 1
-+#endif
-+};
-+#endif
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS;
-+#else
-+static unsigned int numdevs = IMQ_MAX_DEVS;
-+#endif
-+
-+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 */
-+}
-+
-+/* locking not needed when called from imq_nf_queue */
-+static void imq_nf_reinject_lockless(struct nf_queue_entry *entry,
-+                                              unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              nf_reinject(entry, verdict);
-+              return;
-+      }
-+
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+}
-+
-+static void imq_nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              spin_lock_bh(&imq_nf_queue_lock);
-+              nf_reinject(entry, verdict);
-+              spin_unlock_bh(&imq_nf_queue_lock);
-+              return;
-+      }
-+
-+      rcu_read_lock();
-+      local_bh_disable();
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      local_bh_enable();
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+
-+      rcu_read_unlock();
-+}
-+
-+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;
-+
-+      imq_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;
-+      struct sk_buff *skb_orig, *skb, *skb_shared;
-+      struct Qdisc *q;
-+      struct netdev_queue *txq;
-+      int users, index;
-+      int retval = -EINVAL;
-+
-+      index = entry->skb->imq_flags & IMQ_F_IFMASK;
-+      if (unlikely(index > numdevs - 1)) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING
-+                             "IMQ: invalid device specified, highest is %u\n",
-+                             numdevs - 1);
-+              retval = -EINVAL;
-+              goto out;
-+      }
-+
-+      /* check for imq device by index from cache */
-+      dev = imq_devs_cache[index];
-+      if (unlikely(!dev)) {
-+              char buf[8];
-+
-+              /* get device by name and cache result */
-+              snprintf(buf, sizeof(buf), "imq%d", index);
-+              dev = dev_get_by_name(&init_net, buf);
-+              if (!dev) {
-+                      /* not found ?!*/
-+                      BUG();
-+                      retval = -ENODEV;
-+                      goto out;
-+              }
-+
-+              imq_devs_cache[index] = dev;
-+              dev_put(dev);
-+      }
-+
-+      if (unlikely(!(dev->flags & IFF_UP))) {
-+              entry->skb->imq_flags = 0;
-+              imq_nf_reinject_lockless(entry, NF_ACCEPT);
-+              retval = 0;
-+              goto out;
-+      }
-+      dev->last_rx = jiffies;
-+
-+      skb = entry->skb;
-+      skb_orig = NULL;
-+
-+      /* skb has owner? => make clone */
-+      if (unlikely(skb->destructor)) {
-+              skb_orig = skb;
-+              skb = skb_clone(skb, GFP_ATOMIC);
-+              if (!skb) {
-+                      retval = -ENOMEM;
-+                      goto out;
-+              }
-+              entry->skb = skb;
-+      }
-+
-+      skb->nf_queue_entry = entry;
-+
-+      dev->stats.rx_bytes += skb->len;
-+      dev->stats.rx_packets++;
-+
-+      txq = dev_pick_tx(dev, skb);
-+
-+      q = rcu_dereference(txq->qdisc);
-+      if (unlikely(!q->enqueue))
-+              goto packet_not_eaten_by_imq_dev;
-+
-+      spin_lock_bh(qdisc_lock(q));
-+
-+      users = atomic_read(&skb->users);
-+
-+      skb_shared = skb_get(skb); /* increase reference count by one */
-+      skb_save_cb(skb_shared); /* backup skb->cb, as qdisc layer will
-+                                      overwrite it */
-+      qdisc_enqueue_root(skb_shared, q); /* might kfree_skb */
-+
-+      if (likely(atomic_read(&skb_shared->users) == users + 1)) {
-+              kfree_skb(skb_shared); /* decrease reference count by one */
-+
-+              skb->destructor = &imq_skb_destructor;
-+
-+              /* cloned? */
-+              if (skb_orig)
-+                      kfree_skb(skb_orig); /* free original */
-+
-+              spin_unlock_bh(qdisc_lock(q));
-+
-+              /* schedule qdisc dequeue */
-+              __netif_schedule(q);
-+
-+              retval = 0;
-+              goto out;
-+      } else {
-+              skb_restore_cb(skb_shared); /* restore skb->cb */
-+              skb->nf_queue_entry = NULL;
-+              /* qdisc dropped packet and decreased skb reference count of
-+               * skb, so we don't really want to and try refree as that would
-+               * actually destroy the skb. */
-+              spin_unlock_bh(qdisc_lock(q));
-+              goto packet_not_eaten_by_imq_dev;
-+      }
-+
-+packet_not_eaten_by_imq_dev:
-+      /* cloned? restore original */
-+      if (skb_orig) {
-+              kfree_skb(skb);
-+              entry->skb = skb_orig;
-+      }
-+      retval = -1;
-+out:
-+      return retval;
-+}
-+
-+static struct nf_queue_handler nfqh = {
-+      .name  = "imq",
-+      .outfn = imq_nf_queue,
-+};
-+
-+static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff *pskb,
-+                              const struct net_device *indev,
-+                              const struct net_device *outdev,
-+                              int (*okfn)(struct sk_buff *))
-+{
-+      if (pskb->imq_flags & IMQ_F_ENQUEUE)
-+              return NF_QUEUE;
-+
-+      return NF_ACCEPT;
-+}
-+
-+static int imq_close(struct net_device *dev)
-+{
-+      netif_stop_queue(dev);
-+      return 0;
-+}
-+
-+static int imq_open(struct net_device *dev)
-+{
-+      netif_start_queue(dev);
-+      return 0;
-+}
-+
-+static const struct net_device_ops imq_netdev_ops = {
-+      .ndo_open               = imq_open,
-+      .ndo_stop               = imq_close,
-+      .ndo_start_xmit         = imq_dev_xmit,
-+      .ndo_get_stats          = imq_get_stats,
-+};
-+
-+static void imq_setup(struct net_device *dev)
-+{
-+      dev->netdev_ops         = &imq_netdev_ops;
-+      dev->type               = ARPHRD_VOID;
-+      dev->mtu                = 16000;
-+      dev->tx_queue_len       = 11000;
-+      dev->flags              = IFF_NOARP;
-+      dev->features           = NETIF_F_SG | NETIF_F_FRAGLIST |
-+                                NETIF_F_GSO | NETIF_F_HW_CSUM |
-+                                NETIF_F_HIGHDMA;
-+      dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
-+}
-+
-+static int imq_validate(struct nlattr *tb[], struct nlattr *data[])
-+{
-+      int ret = 0;
-+
-+      if (tb[IFLA_ADDRESS]) {
-+              if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
-+                      ret = -EINVAL;
-+                      goto end;
-+              }
-+              if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) {
-+                      ret = -EADDRNOTAVAIL;
-+                      goto end;
-+              }
-+      }
-+      return 0;
-+end:
-+      printk(KERN_WARNING "IMQ: imq_validate failed (%d)\n", ret);
-+      return ret;
-+}
-+
-+static struct rtnl_link_ops imq_link_ops __read_mostly = {
-+      .kind           = "imq",
-+      .priv_size      = 0,
-+      .setup          = imq_setup,
-+      .validate       = imq_validate,
-+};
-+
-+static int __init imq_init_hooks(void)
-+{
-+      int err;
-+
-+      nf_register_queue_imq_handler(&nfqh);
-+
-+      err = nf_register_hook(&imq_ingress_ipv4);
-+      if (err)
-+              goto err1;
-+
-+      err = nf_register_hook(&imq_egress_ipv4);
-+      if (err)
-+              goto err2;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      err = nf_register_hook(&imq_ingress_ipv6);
-+      if (err)
-+              goto err3;
-+
-+      err = nf_register_hook(&imq_egress_ipv6);
-+      if (err)
-+              goto err4;
-+#endif
-+
-+      return 0;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+err4:
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+err3:
-+      nf_unregister_hook(&imq_egress_ipv4);
-+#endif
-+err2:
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+err1:
-+      nf_unregister_queue_imq_handler();
-+      return err;
-+}
-+
-+static int __init imq_init_one(int index)
-+{
-+      struct net_device *dev;
-+      int ret;
-+
-+      dev = alloc_netdev(0, "imq%d", imq_setup);
-+      if (!dev)
-+              return -ENOMEM;
-+
-+      ret = dev_alloc_name(dev, dev->name);
-+      if (ret < 0)
-+              goto fail;
-+
-+      dev->rtnl_link_ops = &imq_link_ops;
-+      ret = register_netdevice(dev);
-+      if (ret < 0)
-+              goto fail;
-+
-+      return 0;
-+fail:
-+      free_netdev(dev);
-+      return ret;
-+}
-+
-+static int __init imq_init_devs(void)
-+{
-+      int err, i;
-+
-+      if (numdevs < 1 || numdevs > IMQ_MAX_DEVS) {
-+              printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n",
-+                     IMQ_MAX_DEVS);
-+              return -EINVAL;
-+      }
-+
-+      rtnl_lock();
-+      err = __rtnl_link_register(&imq_link_ops);
-+
-+      for (i = 0; i < numdevs && !err; i++)
-+              err = imq_init_one(i);
-+
-+      if (err) {
-+              __rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+      }
-+      rtnl_unlock();
-+
-+      return err;
-+}
-+
-+static int __init imq_init_module(void)
-+{
-+      int err;
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS > 16);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS < 2);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS - 1 > IMQ_F_IFMASK);
-+#endif
-+
-+      err = imq_init_devs();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_devs(net)\n");
-+              return err;
-+      }
-+
-+      err = imq_init_hooks();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n");
-+              rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+              return err;
-+      }
-+
-+      printk(KERN_INFO "IMQ driver loaded successfully.\n");
-+
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n");
-+#endif
-+#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n");
-+#endif
-+
-+      return 0;
-+}
-+
-+static void __exit imq_unhook(void)
-+{
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+      nf_unregister_hook(&imq_egress_ipv6);
-+#endif
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+      nf_unregister_hook(&imq_egress_ipv4);
-+
-+      nf_unregister_queue_imq_handler();
-+}
-+
-+static void __exit imq_cleanup_devs(void)
-+{
-+      rtnl_link_unregister(&imq_link_ops);
-+      memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+}
-+
-+static void __exit imq_exit_module(void)
-+{
-+      imq_unhook();
-+      imq_cleanup_devs();
-+      printk(KERN_INFO "IMQ driver unloaded successfully.\n");
-+}
-+
-+module_init(imq_init_module);
-+module_exit(imq_exit_module);
-+
-+module_param(numdevs, int, 0);
-+MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will "
-+                      "be created)");
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See "
-+                      "http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS_RTNL_LINK("imq");
-+
---- a/drivers/net/Kconfig
-+++ b/drivers/net/Kconfig
-@@ -121,6 +121,129 @@ config EQUALIZER
-         To compile this driver as a module, choose M here: the module
-         will be called eql.  If unsure, say N.
-+config IMQ
-+      tristate "IMQ (intermediate queueing device) support"
-+      depends on NETDEVICES && NETFILTER
-+      ---help---
-+        The IMQ device(s) is used as placeholder for QoS queueing
-+        disciplines. Every packet entering/leaving the IP stack can be
-+        directed through the IMQ device where it's enqueued/dequeued to the
-+        attached qdisc. This allows you to treat network devices as classes
-+        and distribute bandwidth among them. Iptables is used to specify
-+        through which IMQ device, if any, packets travel.
-+
-+        More information at: http://www.linuximq.net/
-+
-+        To compile this driver as a module, choose M here: the module
-+        will be called imq.  If unsure, say N.
-+
-+choice
-+      prompt "IMQ behavior (PRE/POSTROUTING)"
-+      depends on IMQ
-+      default IMQ_BEHAVIOR_AB
-+      help
-+
-+              This settings defines how IMQ behaves in respect to its
-+              hooking in PREROUTING and POSTROUTING.
-+
-+              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
-+
-+              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.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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 settings defines how many IMQ devices will be
-+              created.
-+
-+              The default value is 16.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              If not sure leave the default settings alone.
-+
- config TUN
-       tristate "Universal TUN/TAP device driver support"
-       select CRC32
---- a/drivers/net/Makefile
-+++ b/drivers/net/Makefile
-@@ -169,6 +169,7 @@ obj-$(CONFIG_SLHC) += slhc.o
- obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o
- obj-$(CONFIG_DUMMY) += dummy.o
-+obj-$(CONFIG_IMQ) += imq.o
- obj-$(CONFIG_IFB) += ifb.o
- obj-$(CONFIG_MACVLAN) += macvlan.o
- obj-$(CONFIG_MACVTAP) += macvtap.o
---- /dev/null
-+++ b/include/linux/imq.h
-@@ -0,0 +1,13 @@
-+#ifndef _IMQ_H
-+#define _IMQ_H
-+
-+/* IFMASK (16 device indexes, 0 to 15) and flag(s) fit in 5 bits */
-+#define IMQ_F_BITS    5
-+
-+#define IMQ_F_IFMASK  0x0f
-+#define IMQ_F_ENQUEUE 0x10
-+
-+#define IMQ_MAX_DEVS  (IMQ_F_IFMASK + 1)
-+
-+#endif /* _IMQ_H */
-+
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1295,6 +1295,7 @@ extern int               dev_alloc_name(struct net_de
- extern int            dev_open(struct net_device *dev);
- extern int            dev_close(struct net_device *dev);
- extern void           dev_disable_lro(struct net_device *dev);
-+extern struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb);
- extern int            dev_queue_xmit(struct sk_buff *skb);
- extern int            register_netdevice(struct net_device *dev);
- extern void           unregister_netdevice_queue(struct net_device *dev,
---- /dev/null
-+++ b/include/linux/netfilter/xt_IMQ.h
-@@ -0,0 +1,9 @@
-+#ifndef _XT_IMQ_H
-+#define _XT_IMQ_H
-+
-+struct xt_imq_info {
-+      unsigned int todev;     /* target imq device */
-+};
-+
-+#endif /* _XT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv4/ipt_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IPT_IMQ_H
-+#define _IPT_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ipt_imq_info xt_imq_info
-+
-+#endif /* _IPT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv6/ip6t_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IP6T_IMQ_H
-+#define _IP6T_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ip6t_imq_info xt_imq_info
-+
-+#endif /* _IP6T_IMQ_H */
-+
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -29,6 +29,9 @@
- #include <linux/rcupdate.h>
- #include <linux/dmaengine.h>
- #include <linux/hrtimer.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- /* Don't change this without changing skb_csum_unnecessary! */
- #define CHECKSUM_NONE 0
-@@ -330,6 +333,9 @@ struct sk_buff {
-        * first. This is owned by whoever has the skb queued ATM.
-        */
-       char                    cb[48] __aligned(8);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      void                    *cb_next;
-+#endif
-       unsigned long           _skb_refdst;
- #ifdef CONFIG_XFRM
-@@ -366,6 +372,9 @@ struct sk_buff {
-       struct nf_conntrack     *nfct;
-       struct sk_buff          *nfct_reasm;
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      struct nf_queue_entry   *nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       struct nf_bridge_info   *nf_bridge;
- #endif
-@@ -392,6 +401,10 @@ struct sk_buff {
-       /* 0/14 bit hole */
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      __u8                    imq_flags:IMQ_F_BITS;
-+#endif
-+
- #ifdef CONFIG_NET_DMA
-       dma_cookie_t            dma_cookie;
- #endif
-@@ -490,6 +503,12 @@ static inline struct rtable *skb_rtable(
-       return (struct rtable *)skb_dst(skb);
- }
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern int skb_save_cb(struct sk_buff *skb);
-+extern int skb_restore_cb(struct sk_buff *skb);
-+#endif
-+
- extern void kfree_skb(struct sk_buff *skb);
- extern void consume_skb(struct sk_buff *skb);
- extern void          __kfree_skb(struct sk_buff *skb);
-@@ -2096,6 +2115,10 @@ static inline void __nf_copy(struct sk_b
-       dst->nfct_reasm = src->nfct_reasm;
-       nf_conntrack_get_reasm(src->nfct_reasm);
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      dst->imq_flags = src->imq_flags;
-+      dst->nf_queue_entry = src->nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       dst->nf_bridge  = src->nf_bridge;
-       nf_bridge_get(src->nf_bridge);
---- a/include/net/netfilter/nf_queue.h
-+++ b/include/net/netfilter/nf_queue.h
-@@ -13,6 +13,12 @@ struct nf_queue_entry {
-       struct net_device       *indev;
-       struct net_device       *outdev;
-       int                     (*okfn)(struct sk_buff *);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      int                     (*next_outfn)(struct nf_queue_entry *entry,
-+                                            unsigned int queuenum);
-+      unsigned int            next_queuenum;
-+#endif
- };
- #define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry))
-@@ -30,5 +36,11 @@ extern int nf_unregister_queue_handler(u
-                                      const struct nf_queue_handler *qh);
- extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
- extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
-+extern void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern void nf_register_queue_imq_handler(const struct nf_queue_handler *qh);
-+extern void nf_unregister_queue_imq_handler(void);
-+#endif
- #endif /* _NF_QUEUE_H */
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -98,6 +98,9 @@
- #include <net/net_namespace.h>
- #include <net/sock.h>
- #include <linux/rtnetlink.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- #include <linux/proc_fs.h>
- #include <linux/seq_file.h>
- #include <linux/stat.h>
-@@ -1942,7 +1945,11 @@ int dev_hard_start_xmit(struct sk_buff *
-       int rc = NETDEV_TX_OK;
-       if (likely(!skb->next)) {
--              if (!list_empty(&ptype_all))
-+              if (!list_empty(&ptype_all)
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+                      && !(skb->imq_flags & IMQ_F_ENQUEUE)
-+#endif
-+                 )
-                       dev_queue_xmit_nit(skb, dev);
-               /*
-@@ -2054,8 +2061,7 @@ static inline u16 dev_cap_txqueue(struct
-       return queue_index;
- }
--static struct netdev_queue *dev_pick_tx(struct net_device *dev,
--                                      struct sk_buff *skb)
-+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;
-@@ -2084,6 +2090,7 @@ static struct netdev_queue *dev_pick_tx(
-       skb_set_queue_mapping(skb, queue_index);
-       return netdev_get_tx_queue(dev, queue_index);
- }
-+EXPORT_SYMBOL(dev_pick_tx);
- static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
-                                struct net_device *dev,
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -72,6 +72,9 @@
- static struct kmem_cache *skbuff_head_cache __read_mostly;
- static struct kmem_cache *skbuff_fclone_cache __read_mostly;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static struct kmem_cache *skbuff_cb_store_cache __read_mostly;
-+#endif
- static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
-                                 struct pipe_buffer *buf)
-@@ -91,6 +94,83 @@ static int sock_pipe_buf_steal(struct pi
-       return 1;
- }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+/* Control buffer save/restore for IMQ devices */
-+struct skb_cb_table {
-+      void                    *cb_next;
-+      atomic_t                refcnt;
-+      char                    cb[48];
-+};
-+
-+static DEFINE_SPINLOCK(skb_cb_store_lock);
-+
-+int skb_save_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      next = kmem_cache_alloc(skbuff_cb_store_cache, GFP_ATOMIC);
-+      if (!next)
-+              return -ENOMEM;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(next->cb, skb->cb, sizeof(skb->cb));
-+      next->cb_next = skb->cb_next;
-+
-+      atomic_set(&next->refcnt, 1);
-+
-+      skb->cb_next = next;
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_save_cb);
-+
-+int skb_restore_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      if (!skb->cb_next)
-+              return 0;
-+
-+      next = skb->cb_next;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(skb->cb, next->cb, sizeof(skb->cb));
-+      skb->cb_next = next->cb_next;
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      if (atomic_dec_and_test(&next->refcnt)) {
-+              kmem_cache_free(skbuff_cb_store_cache, next);
-+      }
-+
-+      spin_unlock(&skb_cb_store_lock);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_restore_cb);
-+
-+static void skb_copy_stored_cb(struct sk_buff *new, const struct sk_buff *__old)
-+{
-+      struct skb_cb_table *next;
-+      struct sk_buff *old;
-+
-+      if (!__old->cb_next) {
-+              new->cb_next = NULL;
-+              return;
-+      }
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      old = (struct sk_buff *)__old;
-+
-+      next = old->cb_next;
-+      atomic_inc(&next->refcnt);
-+      new->cb_next = next;
-+
-+      spin_unlock(&skb_cb_store_lock);
-+}
-+#endif
- /* Pipe buffer operations for a socket. */
- static const struct pipe_buf_operations sock_pipe_buf_ops = {
-@@ -391,6 +471,26 @@ static void skb_release_head_state(struc
-               WARN_ON(in_irq());
-               skb->destructor(skb);
-       }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      /* This should not happen. When it does, avoid memleak by restoring
-+      the chain of cb-backups. */
-+      while(skb->cb_next != NULL) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING "IMQ: kfree_skb: skb->cb_next: "
-+                              "%08x\n", (unsigned int)skb->cb_next);
-+
-+              skb_restore_cb(skb);
-+      }
-+      /* This should not happen either, nf_queue_entry is nullified in
-+       * imq_dev_xmit(). If we have non-NULL nf_queue_entry then we are
-+       * leaking entry pointers, maybe memory. We don't know if this is
-+       * pointer to already freed memory, or should this be freed.
-+       * If this happens we need to add refcounting, etc for nf_queue_entry.
-+       */
-+      if (skb->nf_queue_entry && net_ratelimit())
-+              printk(KERN_WARNING
-+                              "IMQ: kfree_skb: skb->nf_queue_entry != NULL");
-+#endif
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-       nf_conntrack_put(skb->nfct);
-       nf_conntrack_put_reasm(skb->nfct_reasm);
-@@ -526,6 +626,9 @@ static void __copy_skb_header(struct sk_
-       new->sp                 = secpath_get(old->sp);
- #endif
-       memcpy(new->cb, old->cb, sizeof(old->cb));
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skb_copy_stored_cb(new, old);
-+#endif
-       new->csum               = old->csum;
-       new->local_df           = old->local_df;
-       new->pkt_type           = old->pkt_type;
-@@ -2779,6 +2882,13 @@ void __init skb_init(void)
-                                               0,
-                                               SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-                                               NULL);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skbuff_cb_store_cache = kmem_cache_create("skbuff_cb_store_cache",
-+                                                sizeof(struct skb_cb_table),
-+                                                0,
-+                                                SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-+                                                NULL);
-+#endif
- }
- /**
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -455,6 +455,18 @@ config NETFILTER_XT_TARGET_LED
-         For more information on the LEDs available on your system, see
-         Documentation/leds-class.txt
-+config NETFILTER_XT_TARGET_IMQ
-+        tristate '"IMQ" target support'
-+      depends on NETFILTER_XTABLES
-+      depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+      select IMQ
-+      default m if NETFILTER_ADVANCED=n
-+        help
-+          This option adds a `IMQ' target which is used to specify if and
-+          to which imq device packets should get enqueued/dequeued.
-+
-+          To compile it as a module, choose M here.  If unsure, say N.
-+
- config NETFILTER_XT_TARGET_MARK
-       tristate '"MARK" target support'
-       depends on NETFILTER_ADVANCED
---- a/net/netfilter/Makefile
-+++ b/net/netfilter/Makefile
-@@ -51,6 +51,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSEC
- obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
-+obj-$(CONFIG_NETFILTER_XT_TARGET_IMQ) += xt_IMQ.o
- 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
---- a/net/netfilter/nf_queue.c
-+++ b/net/netfilter/nf_queue.c
-@@ -22,6 +22,26 @@ static const struct nf_queue_handler *qu
- static DEFINE_MUTEX(queue_handler_mutex);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static const struct nf_queue_handler *queue_imq_handler;
-+
-+void nf_register_queue_imq_handler(const struct nf_queue_handler *qh)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, qh);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_register_queue_imq_handler);
-+
-+void nf_unregister_queue_imq_handler(void)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, NULL);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_unregister_queue_imq_handler);
-+#endif
-+
- /* return EBUSY when somebody else is registered, return EEXIST if the
-  * same handler is registered, return 0 in case of success. */
- int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
-@@ -82,7 +102,7 @@ void nf_unregister_queue_handlers(const
- }
- EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);
--static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
-+void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
- {
-       /* Release those devices we held, or Alexey will kill me. */
-       if (entry->indev)
-@@ -102,6 +122,7 @@ static void nf_queue_entry_release_refs(
-       /* Drop reference to owner of hook which queued us. */
-       module_put(entry->elem->owner);
- }
-+EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
- /*
-  * Any packet that leaves via this function must come back
-@@ -123,12 +144,26 @@ static int __nf_queue(struct sk_buff *sk
- #endif
-       const struct nf_afinfo *afinfo;
-       const struct nf_queue_handler *qh;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      const struct nf_queue_handler *qih = NULL;
-+#endif
-       /* QUEUE == DROP if noone is waiting, to be safe. */
-       rcu_read_lock();
-       qh = rcu_dereference(queue_handler[pf]);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      if (pf == PF_INET || pf == PF_INET6)
-+#else
-+      if (pf == PF_INET)
-+#endif
-+              qih = rcu_dereference(queue_imq_handler);
-+
-+      if (!qh && !qih)
-+#else /* !IMQ */
-       if (!qh)
-+#endif
-               goto err_unlock;
-       afinfo = nf_get_afinfo(pf);
-@@ -147,6 +182,10 @@ static int __nf_queue(struct sk_buff *sk
-               .indev  = indev,
-               .outdev = outdev,
-               .okfn   = okfn,
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+              .next_outfn = qh ? qh->outfn : NULL,
-+              .next_queuenum = queuenum,
-+#endif
-       };
-       /* If it's going away, ignore hook. */
-@@ -173,8 +212,19 @@ static int __nf_queue(struct sk_buff *sk
- #endif
-       skb_dst_force(skb);
-       afinfo->saveroute(skb, entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      if (qih) {
-+              status = qih->outfn(entry, queuenum);
-+              goto imq_skip_queue;
-+      }
-+#endif
-+
-       status = qh->outfn(entry, queuenum);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+imq_skip_queue:
-+#endif
-       rcu_read_unlock();
-       if (status < 0) {
---- /dev/null
-+++ b/net/netfilter/xt_IMQ.c
-@@ -0,0 +1,73 @@
-+/*
-+ * This target marks packets to be enqueued to an imq device
-+ */
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter/x_tables.h>
-+#include <linux/netfilter/xt_IMQ.h>
-+#include <linux/imq.h>
-+
-+static unsigned int imq_target(struct sk_buff *pskb,
-+                              const struct xt_action_param *par)
-+{
-+      const struct xt_imq_info *mr = par->targinfo;
-+
-+      pskb->imq_flags = (mr->todev & IMQ_F_IFMASK) | IMQ_F_ENQUEUE;
-+
-+      return XT_CONTINUE;
-+}
-+
-+static int imq_checkentry(const struct xt_tgchk_param *par)
-+{
-+      struct xt_imq_info *mr = par->targinfo;
-+
-+      if (mr->todev > IMQ_MAX_DEVS - 1) {
-+              printk(KERN_WARNING
-+                     "IMQ: invalid device specified, highest is %u\n",
-+                     IMQ_MAX_DEVS - 1);
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static struct xt_target xt_imq_reg[] __read_mostly = {
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET6,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+};
-+
-+static int __init imq_init(void)
-+{
-+      return xt_register_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+static void __exit imq_fini(void)
-+{
-+      xt_unregister_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+module_init(imq_init);
-+module_exit(imq_fini);
-+
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("ipt_IMQ");
-+MODULE_ALIAS("ip6t_IMQ");
-+
index 4cf9fcf..65c4d44 100644 (file)
@@ -8,7 +8,7 @@
        depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
        depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
-@@ -569,7 +568,6 @@ config NETFILTER_XT_TARGET_SECMARK
+@@ -557,7 +556,6 @@ config NETFILTER_XT_TARGET_SECMARK
  
  config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
  
  config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
index e432471..6ea9ba5 100644 (file)
@@ -1,6 +1,6 @@
 --- a/arch/mips/include/asm/string.h
 +++ b/arch/mips/include/asm/string.h
 --- a/arch/mips/include/asm/string.h
 +++ b/arch/mips/include/asm/string.h
-@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__
+@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__ 
  
  #define __HAVE_ARCH_MEMSET
  extern void *memset(void *__s, int __c, size_t __count);
  
  #define __HAVE_ARCH_MEMSET
  extern void *memset(void *__s, int __c, size_t __count);
index fe8cecf..83fd6c3 100644 (file)
@@ -1,6 +1,6 @@
 --- a/include/linux/slab.h
 +++ b/include/linux/slab.h
 --- a/include/linux/slab.h
 +++ b/include/linux/slab.h
-@@ -130,8 +130,8 @@ int kmem_ptr_validate(struct kmem_cache
+@@ -130,8 +130,8 @@ int kmem_ptr_validate(struct kmem_cache 
   * to do various tricks to work around compiler limitations in order to
   * ensure proper constant folding.
   */
   * to do various tricks to work around compiler limitations in order to
   * ensure proper constant folding.
   */
index d021ec1..826eb44 100644 (file)
@@ -61,7 +61,7 @@
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd);
  
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd);
  
-@@ -501,6 +505,29 @@ static inline void double_unlock(struct
+@@ -501,6 +505,29 @@ static inline void double_unlock(struct 
  #endif  /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
  #endif /* __KERNEL__ */
  
  #endif  /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
  #endif /* __KERNEL__ */
  
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
 --- a/fs/mini_fo/aux.c
 +++ b/fs/mini_fo/aux.c
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
 --- a/fs/mini_fo/aux.c
 +++ b/fs/mini_fo/aux.c
-@@ -164,11 +164,11 @@ dentry_t *bpath_walk(super_block_t *sb,
+@@ -164,11 +164,11 @@ dentry_t *bpath_walk(super_block_t *sb, 
        err = vfs_path_lookup(mnt->mnt_root, mnt, bpath+1, 0, &nd);
  
        /* validate */
        err = vfs_path_lookup(mnt->mnt_root, mnt, bpath+1, 0, &nd);
  
        /* validate */
index d2a843c..3750371 100644 (file)
@@ -1,6 +1,6 @@
 --- a/fs/mini_fo/super.c
 +++ b/fs/mini_fo/super.c
 --- a/fs/mini_fo/super.c
 +++ b/fs/mini_fo/super.c
-@@ -84,6 +84,7 @@ mini_fo_write_inode(inode_t *inode, int
+@@ -84,6 +84,7 @@ mini_fo_write_inode(inode_t *inode, int 
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
  
  
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
  
  
index cfe96f1..7f50a19 100644 (file)
@@ -20,7 +20,7 @@
  #else
  static inline int kobject_uevent(struct kobject *kobj,
                                 enum kobject_action action)
  #else
  static inline int kobject_uevent(struct kobject *kobj,
                                 enum kobject_action action)
-@@ -229,6 +235,16 @@ static inline int add_uevent_var(struct
+@@ -229,6 +235,16 @@ static inline int add_uevent_var(struct 
  static inline int kobject_action_type(const char *buf, size_t count,
                                      enum kobject_action *type)
  { return -EINVAL; }
  static inline int kobject_action_type(const char *buf, size_t count,
                                      enum kobject_action *type)
  { return -EINVAL; }
index e02d1bc..286bdae 100644 (file)
 +module_exit(connmark_cleanup_module);
 --- a/net/sched/Kconfig
 +++ b/net/sched/Kconfig
 +module_exit(connmark_cleanup_module);
 --- a/net/sched/Kconfig
 +++ b/net/sched/Kconfig
-@@ -549,6 +549,18 @@
+@@ -549,6 +549,18 @@ config NET_ACT_SKBEDIT
          To compile this code as a module, choose M here: the
          module will be called act_skbedit.
  
          To compile this code as a module, choose M here: the
          module will be called act_skbedit.
  
        depends on NET_CLS_U32 || NET_CLS_FW
 --- a/net/sched/Makefile
 +++ b/net/sched/Makefile
        depends on NET_CLS_U32 || NET_CLS_FW
 --- a/net/sched/Makefile
 +++ b/net/sched/Makefile
-@@ -15,6 +15,7 @@
+@@ -15,6 +15,7 @@ obj-$(CONFIG_NET_ACT_NAT)    += act_nat.o
  obj-$(CONFIG_NET_ACT_PEDIT)   += act_pedit.o
  obj-$(CONFIG_NET_ACT_SIMP)    += act_simple.o
  obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o
  obj-$(CONFIG_NET_ACT_PEDIT)   += act_pedit.o
  obj-$(CONFIG_NET_ACT_SIMP)    += act_simple.o
  obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o
index f3f342f..e3398a0 100644 (file)
@@ -11,7 +11,7 @@
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
-@@ -49,3 +49,4 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) +=
+@@ -49,3 +49,4 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += 
  obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)  += ledtrig-backlight.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)  += ledtrig-backlight.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
index 4eb139b..d229a2e 100644 (file)
@@ -14,7 +14,7 @@
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
-@@ -50,3 +50,4 @@ obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) +=
+@@ -50,3 +50,4 @@ obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += 
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_MORSE)      += ledtrig-morse.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_MORSE)      += ledtrig-morse.o
index 3b70632..6609a16 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/char/gpio_dev.c
 +++ b/drivers/char/gpio_dev.c
 --- a/drivers/char/gpio_dev.c
 +++ b/drivers/char/gpio_dev.c
-@@ -114,7 +114,7 @@ gpio_close(struct inode * inode, struct
+@@ -114,7 +114,7 @@ gpio_close(struct inode * inode, struct 
  }
  
  struct file_operations gpio_fops = {
  }
  
  struct file_operations gpio_fops = {
index c334b17..5c70e79 100644 (file)
                        dev->checkpointBlockList[i] = -1;
        }
  
                        dev->checkpointBlockList[i] = -1;
        }
  
-@@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device
+@@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device 
  
  static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
  {
  
  static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
  {
  {
        unsigned char cDelta;   /* column parity delta */
        unsigned lDelta;        /* line parity delta */
  {
        unsigned char cDelta;   /* column parity delta */
        unsigned lDelta;        /* line parity delta */
-@@ -294,8 +292,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -294,8 +292,7 @@ int yaffs_ECCCorrectOther(unsigned char 
                return 0; /* no error */
  
        if (lDelta == ~lDeltaPrime &&
                return 0; /* no error */
  
        if (lDelta == ~lDeltaPrime &&
                /* Single bit (recoverable) error in data */
  
                bit = 0;
                /* Single bit (recoverable) error in data */
  
                bit = 0;
-@@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char 
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                        return -1;
  
                data[lDelta] ^= (1 << bit);
                        return -1;
  
                data[lDelta] ^= (1 << bit);
-@@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char 
        }
  
        if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
        }
  
        if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
                /* Reccoverable error in ecc */
  
                *read_ecc = *test_ecc;
                /* Reccoverable error in ecc */
  
                *read_ecc = *test_ecc;
-@@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char 
        /* Unrecoverable error */
  
        return -1;
        /* Unrecoverable error */
  
        return -1;
  {
        unsigned char *alias;
        int ret;
  {
        unsigned char *alias;
        int ret;
-@@ -329,7 +395,7 @@ static int yaffs_readlink(struct dentry
+@@ -329,7 +395,7 @@ static int yaffs_readlink(struct dentry 
        return ret;
  }
  
        return ret;
  }
  
  static int yaffs_file_flush(struct file *file, fl_owner_t id)
  #else
  static int yaffs_file_flush(struct file *file)
  static int yaffs_file_flush(struct file *file, fl_owner_t id)
  #else
  static int yaffs_file_flush(struct file *file)
-@@ -513,8 +579,8 @@ static int yaffs_file_flush(struct file
+@@ -513,8 +579,8 @@ static int yaffs_file_flush(struct file 
        yaffs_Device *dev = obj->myDev;
  
        T(YAFFS_TRACE_OS,
        yaffs_Device *dev = obj->myDev;
  
        T(YAFFS_TRACE_OS,
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossLock(dev);
  
-@@ -535,15 +601,15 @@ static int yaffs_readpage_nolock(struct
+@@ -535,15 +601,15 @@ static int yaffs_readpage_nolock(struct 
  
        yaffs_Device *dev;
  
  
        yaffs_Device *dev;
  
        BUG_ON(!PageLocked(pg));
  #else
        if (!PageLocked(pg))
        BUG_ON(!PageLocked(pg));
  #else
        if (!PageLocked(pg))
-@@ -555,9 +621,9 @@ static int yaffs_readpage_nolock(struct
+@@ -555,9 +621,9 @@ static int yaffs_readpage_nolock(struct 
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossUnlock(dev);
  
  
        yaffs_GrossUnlock(dev);
  
-@@ -575,7 +641,7 @@ static int yaffs_readpage_nolock(struct
+@@ -575,7 +641,7 @@ static int yaffs_readpage_nolock(struct 
        flush_dcache_page(pg);
        kunmap(pg);
  
        flush_dcache_page(pg);
        kunmap(pg);
  
                if (n < step) {
                        n++;
                        continue;
                if (n < step) {
                        n++;
                        continue;
-@@ -2119,7 +2356,7 @@ static int yaffs_proc_write(struct file
+@@ -2119,7 +2356,7 @@ static int yaffs_proc_write(struct file 
        char *end;
        char *mask_name;
        const char *x;
        char *end;
        char *mask_name;
        const char *x;
        int i;
        int done = 0;
        int add, len = 0;
        int i;
        int done = 0;
        int add, len = 0;
-@@ -2129,9 +2366,8 @@ static int yaffs_proc_write(struct file
+@@ -2129,9 +2366,8 @@ static int yaffs_proc_write(struct file 
  
        while (!done && (pos < count)) {
                done = 1;
  
        while (!done && (pos < count)) {
                done = 1;
  
                switch (buf[pos]) {
                case '+':
  
                switch (buf[pos]) {
                case '+':
-@@ -2148,20 +2384,21 @@ static int yaffs_proc_write(struct file
+@@ -2148,20 +2384,21 @@ static int yaffs_proc_write(struct file 
                mask_name = NULL;
  
                mask_bitfield = simple_strtoul(buf + pos, &end, 0);
                mask_name = NULL;
  
                mask_bitfield = simple_strtoul(buf + pos, &end, 0);
                                        mask_name = mask_flags[i].mask_name;
                                        mask_bitfield = mask_flags[i].mask_bitfield;
                                        done = 0;
                                        mask_name = mask_flags[i].mask_name;
                                        mask_bitfield = mask_flags[i].mask_bitfield;
                                        done = 0;
-@@ -2172,7 +2409,7 @@ static int yaffs_proc_write(struct file
+@@ -2172,7 +2409,7 @@ static int yaffs_proc_write(struct file 
  
                if (mask_name != NULL) {
                        done = 0;
  
                if (mask_name != NULL) {
                        done = 0;
                        case '-':
                                rg &= ~mask_bitfield;
                                break;
                        case '-':
                                rg &= ~mask_bitfield;
                                break;
-@@ -2191,13 +2428,13 @@ static int yaffs_proc_write(struct file
+@@ -2191,13 +2428,13 @@ static int yaffs_proc_write(struct file 
  
        yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
  
  
        yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
  
  {
        /* Get the real object in case we were fed a hard link as an equivalent object */
        equivalentObject = yaffs_GetEquivalentObject(equivalentObject);
  {
        /* Get the real object in case we were fed a hard link as an equivalent object */
        equivalentObject = yaffs_GetEquivalentObject(equivalentObject);
-@@ -2363,33 +2396,31 @@ yaffs_Object *yaffs_Link(yaffs_Object *
+@@ -2363,33 +2396,31 @@ yaffs_Object *yaffs_Link(yaffs_Object * 
  
  }
  
  
  }
  
        int nToCopy;
        int n = nBytes;
        int nDone = 0;
        int nToCopy;
        int n = nBytes;
        int nDone = 0;
-@@ -4600,27 +4665,26 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4600,27 +4665,26 @@ int yaffs_ReadDataFromFile(yaffs_Object 
        dev = in->myDev;
  
        while (n > 0) {
        dev = in->myDev;
  
        while (n > 0) {
                        if (dev->nShortOpCaches > 0) {
  
                                /* If we can't find the data in the cache, then load it up. */
                        if (dev->nShortOpCaches > 0) {
  
                                /* If we can't find the data in the cache, then load it up. */
-@@ -4641,14 +4705,9 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4641,14 +4705,9 @@ int yaffs_ReadDataFromFile(yaffs_Object 
  
                                cache->locked = 1;
  
  
                                cache->locked = 1;
  
                                cache->locked = 0;
                        } else {
                                /* Read into the local buffer then copy..*/
                                cache->locked = 0;
                        } else {
                                /* Read into the local buffer then copy..*/
-@@ -4657,41 +4716,19 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4657,41 +4716,19 @@ int yaffs_ReadDataFromFile(yaffs_Object 
                                    yaffs_GetTempBuffer(dev, __LINE__);
                                yaffs_ReadChunkDataFromObject(in, chunk,
                                                              localBuffer);
                                    yaffs_GetTempBuffer(dev, __LINE__);
                                yaffs_ReadChunkDataFromObject(in, chunk,
                                                              localBuffer);
                }
  
                n -= nToCopy;
                }
  
                n -= nToCopy;
-@@ -4704,28 +4741,37 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4704,28 +4741,37 @@ int yaffs_ReadDataFromFile(yaffs_Object 
        return nDone;
  }
  
        return nDone;
  }
  
        int newFullChunks;
  
        yaffs_Device *dev = in->myDev;
        int newFullChunks;
  
        yaffs_Device *dev = in->myDev;
-@@ -4955,13 +4981,11 @@ int yaffs_ResizeFile(yaffs_Object * in,
+@@ -4955,13 +4981,11 @@ int yaffs_ResizeFile(yaffs_Object * in, 
  
        yaffs_CheckGarbageCollection(dev);
  
  
        yaffs_CheckGarbageCollection(dev);
  
  
        if (newSize < oldFileSize) {
  
  
        if (newSize < oldFileSize) {
  
-@@ -4994,21 +5018,20 @@ int yaffs_ResizeFile(yaffs_Object * in,
+@@ -4994,21 +5018,20 @@ int yaffs_ResizeFile(yaffs_Object * in, 
        }
  
  
        }
  
  
  {
        obj = yaffs_GetEquivalentObject(obj);
  
  {
        obj = yaffs_GetEquivalentObject(obj);
  
-@@ -5024,7 +5047,7 @@ loff_t yaffs_GetFileSize(yaffs_Object *
+@@ -5024,7 +5047,7 @@ loff_t yaffs_GetFileSize(yaffs_Object * 
  
  
  
  
  
  
  {
        int init_failed = 0;
        unsigned x;
  {
        int init_failed = 0;
        unsigned x;
-@@ -7040,6 +7126,8 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7040,6 +7126,8 @@ int yaffs_GutsInitialise(yaffs_Device * 
        dev->chunkOffset = 0;
        dev->nFreeChunks = 0;
  
        dev->chunkOffset = 0;
        dev->nFreeChunks = 0;
  
        if (dev->startBlock == 0) {
                dev->internalStartBlock = dev->startBlock + 1;
                dev->internalEndBlock = dev->endBlock + 1;
        if (dev->startBlock == 0) {
                dev->internalStartBlock = dev->startBlock + 1;
                dev->internalEndBlock = dev->endBlock + 1;
-@@ -7049,18 +7137,18 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7049,18 +7137,18 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        /* Check geometry parameters. */
  
  
        /* Check geometry parameters. */
  
                return YAFFS_FAIL;
        }
  
                return YAFFS_FAIL;
        }
  
-@@ -7070,6 +7158,12 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7070,6 +7158,12 @@ int yaffs_GutsInitialise(yaffs_Device * 
                return YAFFS_FAIL;
        }
  
                return YAFFS_FAIL;
        }
  
        /* Got the right mix of functions? */
        if (!yaffs_CheckDevFunctions(dev)) {
                /* Function missing */
        /* Got the right mix of functions? */
        if (!yaffs_CheckDevFunctions(dev)) {
                /* Function missing */
-@@ -7097,31 +7191,18 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7097,31 +7191,18 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        dev->isMounted = 1;
  
  
        dev->isMounted = 1;
  
  
        /*
         * Calculate chunkGroupBits.
  
        /*
         * Calculate chunkGroupBits.
-@@ -7133,16 +7214,15 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7133,16 +7214,15 @@ int yaffs_GutsInitialise(yaffs_Device * 
        bits = ShiftsGE(x);
  
        /* Set up tnode width if wide tnodes are enabled. */
        bits = ShiftsGE(x);
  
        /* Set up tnode width if wide tnodes are enabled. */
                dev->tnodeWidth = 16;
  
        dev->tnodeMask = (1<<dev->tnodeWidth)-1;
                dev->tnodeWidth = 16;
  
        dev->tnodeMask = (1<<dev->tnodeWidth)-1;
-@@ -7193,7 +7273,7 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7193,7 +7273,7 @@ int yaffs_GutsInitialise(yaffs_Device * 
        dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */
  
        /* Initialise temporary buffers and caches. */
        dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */
  
        /* Initialise temporary buffers and caches. */
                init_failed = 1;
  
        dev->srCache = NULL;
                init_failed = 1;
  
        dev->srCache = NULL;
-@@ -7203,25 +7283,26 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7203,25 +7283,26 @@ int yaffs_GutsInitialise(yaffs_Device * 
        if (!init_failed &&
            dev->nShortOpCaches > 0) {
                int i;
        if (!init_failed &&
            dev->nShortOpCaches > 0) {
                int i;
                        init_failed = 1;
  
                dev->srLastUse = 0;
                        init_failed = 1;
  
                dev->srLastUse = 0;
-@@ -7229,29 +7310,30 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7229,29 +7310,30 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        dev->cacheHits = 0;
  
  
        dev->cacheHits = 0;
  
                                T(YAFFS_TRACE_ALWAYS,
                                  (TSTR("yaffs: restored from checkpoint" TENDSTR)));
                        } else {
                                T(YAFFS_TRACE_ALWAYS,
                                  (TSTR("yaffs: restored from checkpoint" TENDSTR)));
                        } else {
-@@ -7273,24 +7355,25 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7273,24 +7355,25 @@ int yaffs_GutsInitialise(yaffs_Device * 
                                dev->nBackgroundDeletions = 0;
                                dev->oldestDirtySequence = 0;
  
                                dev->nBackgroundDeletions = 0;
                                dev->oldestDirtySequence = 0;
  
                /* Clean up the mess */
                T(YAFFS_TRACE_TRACING,
                  (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR)));
                /* Clean up the mess */
                T(YAFFS_TRACE_TRACING,
                  (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR)));
-@@ -7318,7 +7401,7 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7318,7 +7401,7 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
  }
  
  
  }
  
  {
        if (etags) {
                memset(etags, 0, sizeof(*etags));
  {
        if (etags) {
                memset(etags, 0, sizeof(*etags));
-@@ -169,9 +169,9 @@ static int rettags(yaffs_ExtendedTags *
+@@ -169,9 +169,9 @@ static int rettags(yaffs_ExtendedTags * 
   * Returns YAFFS_OK or YAFFS_FAIL.
   */
  int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
   * Returns YAFFS_OK or YAFFS_FAIL.
   */
  int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
 +                      yaffs_UnpackTags2(tags, &pt);
 +              }
 +      }
 +                      yaffs_UnpackTags2(tags, &pt);
 +              }
 +      }
-+
+-      if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
+-              tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
 +      if (localData)
 +              yaffs_ReleaseTempBuffer(dev, data, __LINE__);
  
 +      if (localData)
 +              yaffs_ReleaseTempBuffer(dev, data, __LINE__);
  
--      if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
 +      if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
 +      if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
-               tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
--
++              tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
        if (retval == 0)
                return YAFFS_OK;
        else
        if (retval == 0)
                return YAFFS_OK;
        else
index db889ba..a0c532a 100644 (file)
  chunk/page state.  This byte is zeroed when the page is discarded.
  Choose this option if you have existing on-NAND data in this format
  that you need to continue to support.  New data written also uses the
  chunk/page state.  This byte is zeroed when the page is discarded.
  Choose this option if you have existing on-NAND data in this format
  that you need to continue to support.  New data written also uses the
-@@ -57,7 +78,7 @@ adjusted to use the older-style format.
+@@ -57,7 +78,7 @@ adjusted to use the older-style format. 
  MTD versions in yaffs_mtdif1.c.
  */
  /* Default: Not selected */
  MTD versions in yaffs_mtdif1.c.
  */
  /* Default: Not selected */
                        yaffs_ECCOther *read_ecc,
                        const yaffs_ECCOther *test_ecc)
  {
                        yaffs_ECCOther *read_ecc,
                        const yaffs_ECCOther *test_ecc)
  {
-@@ -304,7 +301,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -304,7 +301,7 @@ int yaffs_ECCCorrectOther(unsigned char 
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                        return -1;
  
                data[lDelta] ^= (1 << bit);
                        return -1;
  
                data[lDelta] ^= (1 << bit);
-@@ -312,8 +309,8 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -312,8 +309,8 @@ int yaffs_ECCCorrectOther(unsigned char 
                return 1; /* corrected */
        }
  
                return 1; /* corrected */
        }
  
index e400531..ad44715 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/hostap/hostap_ap.c
 +++ b/drivers/net/wireless/hostap/hostap_ap.c
 --- a/drivers/net/wireless/hostap/hostap_ap.c
 +++ b/drivers/net/wireless/hostap/hostap_ap.c
-@@ -2335,13 +2335,13 @@ int prism2_ap_get_sta_qual(local_info_t
+@@ -2335,13 +2335,13 @@ int prism2_ap_get_sta_qual(local_info_t 
                addr[count].sa_family = ARPHRD_ETHER;
                memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
                if (sta->last_rx_silence == 0)
                addr[count].sa_family = ARPHRD_ETHER;
                memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
                if (sta->last_rx_silence == 0)
index e3ecbbe..ed03aa9 100644 (file)
@@ -24,7 +24,7 @@
   * All of these routines try to estimate how many bits of randomness a
   * particular randomness source.  They do this by keeping track of the
   * first and second order deltas of the event timings.
   * All of these routines try to estimate how many bits of randomness a
   * particular randomness source.  They do this by keeping track of the
   * first and second order deltas of the event timings.
-@@ -715,6 +725,61 @@ void add_disk_randomness(struct gendisk
+@@ -715,6 +725,61 @@ void add_disk_randomness(struct gendisk 
  }
  #endif
  
  }
  #endif
  
index e1fcf44..86da2f0 100644 (file)
@@ -23,7 +23,7 @@ Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
 +EXPORT_SYMBOL(dma_set_coherent_mask);
 --- a/arch/arm/mach-ixp4xx/common-pci.c
 +++ b/arch/arm/mach-ixp4xx/common-pci.c
 +EXPORT_SYMBOL(dma_set_coherent_mask);
 --- a/arch/arm/mach-ixp4xx/common-pci.c
 +++ b/arch/arm/mach-ixp4xx/common-pci.c
-@@ -513,4 +513,4 @@ int dma_set_coherent_mask(struct device
+@@ -513,4 +513,4 @@ int dma_set_coherent_mask(struct device 
  
  EXPORT_SYMBOL(ixp4xx_pci_read);
  EXPORT_SYMBOL(ixp4xx_pci_write);
  
  EXPORT_SYMBOL(ixp4xx_pci_read);
  EXPORT_SYMBOL(ixp4xx_pci_write);
index 77161f6..e63d733 100644 (file)
@@ -1,6 +1,6 @@
 --- a/scripts/Makefile.lib
 +++ b/scripts/Makefile.lib
 --- a/scripts/Makefile.lib
 +++ b/scripts/Makefile.lib
-@@ -238,7 +238,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^)
+@@ -238,7 +238,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^) 
  
  quiet_cmd_lzma = LZMA    $@
  cmd_lzma = (cat $(filter-out FORCE,$^) | \
  
  quiet_cmd_lzma = LZMA    $@
  cmd_lzma = (cat $(filter-out FORCE,$^) | \
index 38ba76d..e1981dd 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -446,9 +446,9 @@ struct mtd_info *cfi_cmdset_0002(struct
+@@ -446,9 +446,9 @@ struct mtd_info *cfi_cmdset_0002(struct 
  
                        /*
                         * Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4
  
                        /*
                         * Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4
index 729934f..ab270ff 100644 (file)
  
  unsigned int vced_count, vcei_count;
  
  
  unsigned int vced_count, vcei_count;
  
-@@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file
+@@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file 
        /*
         * For the first processor also print the system type
         */
        /*
         * For the first processor also print the system type
         */
index 835f25a..1223fb4 100644 (file)
@@ -63,7 +63,7 @@
  htc_excalibur_s620    MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620      2391
  htc_opal              MACH_HTC_OPAL           HTC_OPAL                2392
  touchbook             MACH_TOUCHBOOK          TOUCHBOOK               2393
  htc_excalibur_s620    MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620      2391
  htc_opal              MACH_HTC_OPAL           HTC_OPAL                2392
  touchbook             MACH_TOUCHBOOK          TOUCHBOOK               2393
-@@ -2446,7 +2446,7 @@ siogentoo1               MACH_SIOGENTOO1         SIOGENTOO1
+@@ -2446,7 +2446,7 @@ siogentoo1               MACH_SIOGENTOO1         SIOGENTOO1      
  siogentoo2            MACH_SIOGENTOO2         SIOGENTOO2              2459
  sm3k                  MACH_SM3K               SM3K                    2460
  acer_tempo_f900               MACH_ACER_TEMPO_F900    ACER_TEMPO_F900         2461
  siogentoo2            MACH_SIOGENTOO2         SIOGENTOO2              2459
  sm3k                  MACH_SM3K               SM3K                    2460
  acer_tempo_f900               MACH_ACER_TEMPO_F900    ACER_TEMPO_F900         2461
index a048395..e9bb121 100644 (file)
        part->name = dev->mtd.name;
 --- a/drivers/mtd/mtdchar.c
 +++ b/drivers/mtd/mtdchar.c
        part->name = dev->mtd.name;
 --- a/drivers/mtd/mtdchar.c
 +++ b/drivers/mtd/mtdchar.c
-@@ -841,6 +841,13 @@ static int mtd_ioctl(struct file *file,
+@@ -841,6 +841,13 @@ static int mtd_ioctl(struct file *file, 
                file->f_pos = 0;
                break;
        }
                file->f_pos = 0;
                break;
        }
index cb9f7bf..9b8cc81 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -392,9 +392,35 @@ static struct cfi_fixup fixup_table[] =
+@@ -392,9 +392,35 @@ static struct cfi_fixup fixup_table[] = 
  static void cfi_fixup_major_minor(struct cfi_private *cfi,
                                  struct cfi_pri_amdstd *extp)
  {
  static void cfi_fixup_major_minor(struct cfi_private *cfi,
                                  struct cfi_pri_amdstd *extp)
  {
index 88b656b..58732b8 100644 (file)
@@ -30,7 +30,7 @@
        depends on NETFILTER_ADVANCED
 --- a/net/netfilter/Makefile
 +++ b/net/netfilter/Makefile
        depends on NETFILTER_ADVANCED
 --- a/net/netfilter/Makefile
 +++ b/net/netfilter/Makefile
-@@ -95,6 +95,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT)
+@@ -95,6 +95,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) 
  obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
  obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
diff --git a/target/linux/generic/patches-2.6.37/150-netfilter_imq.patch b/target/linux/generic/patches-2.6.37/150-netfilter_imq.patch
deleted file mode 100644 (file)
index b715126..0000000
+++ /dev/null
@@ -1,1342 +0,0 @@
---- /dev/null
-+++ b/drivers/net/imq.c
-@@ -0,0 +1,638 @@
-+/*
-+ *             Pseudo-driver for the intermediate queue device.
-+ *
-+ *             This program is free software; you can redistribute it and/or
-+ *             modify it under the terms of the GNU General Public License
-+ *             as published by the Free Software Foundation; either version
-+ *             2 of the License, or (at your option) any later version.
-+ *
-+ * Authors:    Patrick McHardy, <kaber@trash.net>
-+ *
-+ *            The first version was written by Martin Devera, <devik@cdi.cz>
-+ *
-+ * Credits:    Jan Rafaj <imq2t@cedric.vabo.cz>
-+ *              - Update patch to 2.4.21
-+ *             Sebastian Strollo <sstrollo@nortelnetworks.com>
-+ *              - Fix "Dead-loop on netdevice imq"-issue
-+ *             Marcel Sebek <sebek64@post.cz>
-+ *              - Update to 2.6.2-rc1
-+ *
-+ *           After some time of inactivity there is a group taking care
-+ *           of IMQ again: http://www.linuximq.net
-+ *
-+ *
-+ *           2004/06/30 - New version of IMQ patch to kernels <=2.6.7
-+ *             including the following changes:
-+ *
-+ *           - Correction of ipv6 support "+"s issue (Hasso Tepper)
-+ *           - Correction of imq_init_devs() issue that resulted in
-+ *           kernel OOPS unloading IMQ as module (Norbert Buchmuller)
-+ *           - Addition of functionality to choose number of IMQ devices
-+ *           during kernel config (Andre Correa)
-+ *           - Addition of functionality to choose how IMQ hooks on
-+ *           PRE and POSTROUTING (after or before NAT) (Andre Correa)
-+ *           - Cosmetic corrections (Norbert Buchmuller) (Andre Correa)
-+ *
-+ *
-+ *             2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were
-+ *             released with almost no problems. 2.6.14-x was released
-+ *             with some important changes: nfcache was removed; After
-+ *             some weeks of trouble we figured out that some IMQ fields
-+ *             in skb were missing in skbuff.c - skb_clone and copy_skb_header.
-+ *             These functions are correctly patched by this new patch version.
-+ *
-+ *             Thanks for all who helped to figure out all the problems with
-+ *             2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX,
-+ *             Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully
-+ *             I didn't forget anybody). I apologize again for my lack of time.
-+ *
-+ *
-+ *             2008/06/17 - 2.6.25 - Changed imq.c to use qdisc_run() instead 
-+ *             of qdisc_restart() and moved qdisc_run() to tasklet to avoid
-+ *             recursive locking. New initialization routines to fix 'rmmod' not
-+ *             working anymore. Used code from ifb.c. (Jussi Kivilinna)
-+ *
-+ *             2008/08/06 - 2.6.26 - (JK)
-+ *              - Replaced tasklet with 'netif_schedule()'.
-+ *              - Cleaned up and added comments for imq_nf_queue().
-+ *
-+ *             2009/04/12
-+ *              - Add skb_save_cb/skb_restore_cb helper functions for backuping
-+ *                control buffer. This is needed because qdisc-layer on kernels
-+ *                2.6.27 and newer overwrite control buffer. (Jussi Kivilinna)
-+ *              - Add better locking for IMQ device. Hopefully this will solve
-+ *                SMP issues. (Jussi Kivilinna)
-+ *              - Port to 2.6.27
-+ *              - Port to 2.6.28
-+ *              - Port to 2.6.29 + fix rmmod not working
-+ *
-+ *             2009/04/20 - (Jussi Kivilinna)
-+ *              - Use netdevice feature flags to avoid extra packet handling
-+ *                by core networking layer and possibly increase performance.
-+ *
-+ *             2009/09/26 - (Jussi Kivilinna)
-+ *              - Add imq_nf_reinject_lockless to fix deadlock with
-+ *                imq_nf_queue/imq_nf_reinject.
-+ *
-+ *             2009/12/08 - (Jussi Kivilinna)
-+ *              - Port to 2.6.32
-+ *              - Add check for skb->nf_queue_entry==NULL in imq_dev_xmit()
-+ *              - Also add better error checking for skb->nf_queue_entry usage
-+ *
-+ *             2010/02/25 - (Jussi Kivilinna)
-+ *              - Port to 2.6.33
-+ *
-+ *             2010/08/12 - (Jussi Kivilinna)
-+ *              - Port to 2.6.35
-+ *
-+ *           Also, many thanks to pablo Sebastian Greco for making the initial
-+ *           patch and to those who helped the testing.
-+ *
-+ *             More info at: http://www.linuximq.net/ (Andre Correa)
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/moduleparam.h>
-+#include <linux/list.h>
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/if_arp.h>
-+#include <linux/netfilter.h>
-+#include <linux/netfilter_ipv4.h>
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      #include <linux/netfilter_ipv6.h>
-+#endif
-+#include <linux/imq.h>
-+#include <net/pkt_sched.h>
-+#include <net/netfilter/nf_queue.h>
-+
-+static nf_hookfn imq_nf_hook;
-+
-+static struct nf_hook_ops imq_ingress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP_PRI_LAST
-+#else
-+      .priority       = NF_IP_PRI_NAT_SRC - 1
-+#endif
-+};
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+static struct nf_hook_ops imq_ingress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP6_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP6_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP6_PRI_LAST
-+#else
-+      .priority       = NF_IP6_PRI_NAT_SRC - 1
-+#endif
-+};
-+#endif
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS;
-+#else
-+static unsigned int numdevs = IMQ_MAX_DEVS;
-+#endif
-+
-+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 */
-+}
-+
-+/* locking not needed when called from imq_nf_queue */
-+static void imq_nf_reinject_lockless(struct nf_queue_entry *entry,
-+                                              unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              nf_reinject(entry, verdict);
-+              return;
-+      }
-+
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+}
-+
-+static void imq_nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              spin_lock_bh(&imq_nf_queue_lock);
-+              nf_reinject(entry, verdict);
-+              spin_unlock_bh(&imq_nf_queue_lock);
-+              return;
-+      }
-+
-+      rcu_read_lock();
-+      local_bh_disable();
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      local_bh_enable();
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+
-+      rcu_read_unlock();
-+}
-+
-+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;
-+
-+      imq_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;
-+      struct sk_buff *skb_orig, *skb, *skb_shared;
-+      struct Qdisc *q;
-+      struct netdev_queue *txq;
-+      int users, index;
-+      int retval = -EINVAL;
-+
-+      index = entry->skb->imq_flags & IMQ_F_IFMASK;
-+      if (unlikely(index > numdevs - 1)) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING
-+                             "IMQ: invalid device specified, highest is %u\n",
-+                             numdevs - 1);
-+              retval = -EINVAL;
-+              goto out;
-+      }
-+
-+      /* check for imq device by index from cache */
-+      dev = imq_devs_cache[index];
-+      if (unlikely(!dev)) {
-+              char buf[8];
-+
-+              /* get device by name and cache result */
-+              snprintf(buf, sizeof(buf), "imq%d", index);
-+              dev = dev_get_by_name(&init_net, buf);
-+              if (!dev) {
-+                      /* not found ?!*/
-+                      BUG();
-+                      retval = -ENODEV;
-+                      goto out;
-+              }
-+
-+              imq_devs_cache[index] = dev;
-+              dev_put(dev);
-+      }
-+
-+      if (unlikely(!(dev->flags & IFF_UP))) {
-+              entry->skb->imq_flags = 0;
-+              imq_nf_reinject_lockless(entry, NF_ACCEPT);
-+              retval = 0;
-+              goto out;
-+      }
-+      dev->last_rx = jiffies;
-+
-+      skb = entry->skb;
-+      skb_orig = NULL;
-+
-+      /* skb has owner? => make clone */
-+      if (unlikely(skb->destructor)) {
-+              skb_orig = skb;
-+              skb = skb_clone(skb, GFP_ATOMIC);
-+              if (!skb) {
-+                      retval = -ENOMEM;
-+                      goto out;
-+              }
-+              entry->skb = skb;
-+      }
-+
-+      skb->nf_queue_entry = entry;
-+
-+      dev->stats.rx_bytes += skb->len;
-+      dev->stats.rx_packets++;
-+
-+      txq = dev_pick_tx(dev, skb);
-+
-+      q = rcu_dereference(txq->qdisc);
-+      if (unlikely(!q->enqueue))
-+              goto packet_not_eaten_by_imq_dev;
-+
-+      spin_lock_bh(qdisc_lock(q));
-+
-+      users = atomic_read(&skb->users);
-+
-+      skb_shared = skb_get(skb); /* increase reference count by one */
-+      skb_save_cb(skb_shared); /* backup skb->cb, as qdisc layer will
-+                                      overwrite it */
-+      qdisc_enqueue_root(skb_shared, q); /* might kfree_skb */
-+
-+      if (likely(atomic_read(&skb_shared->users) == users + 1)) {
-+              kfree_skb(skb_shared); /* decrease reference count by one */
-+
-+              skb->destructor = &imq_skb_destructor;
-+
-+              /* cloned? */
-+              if (skb_orig)
-+                      kfree_skb(skb_orig); /* free original */
-+
-+              spin_unlock_bh(qdisc_lock(q));
-+
-+              /* schedule qdisc dequeue */
-+              __netif_schedule(q);
-+
-+              retval = 0;
-+              goto out;
-+      } else {
-+              skb_restore_cb(skb_shared); /* restore skb->cb */
-+              skb->nf_queue_entry = NULL;
-+              /* qdisc dropped packet and decreased skb reference count of
-+               * skb, so we don't really want to and try refree as that would
-+               * actually destroy the skb. */
-+              spin_unlock_bh(qdisc_lock(q));
-+              goto packet_not_eaten_by_imq_dev;
-+      }
-+
-+packet_not_eaten_by_imq_dev:
-+      /* cloned? restore original */
-+      if (skb_orig) {
-+              kfree_skb(skb);
-+              entry->skb = skb_orig;
-+      }
-+      retval = -1;
-+out:
-+      return retval;
-+}
-+
-+static struct nf_queue_handler nfqh = {
-+      .name  = "imq",
-+      .outfn = imq_nf_queue,
-+};
-+
-+static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff *pskb,
-+                              const struct net_device *indev,
-+                              const struct net_device *outdev,
-+                              int (*okfn)(struct sk_buff *))
-+{
-+      if (pskb->imq_flags & IMQ_F_ENQUEUE)
-+              return NF_QUEUE;
-+
-+      return NF_ACCEPT;
-+}
-+
-+static int imq_close(struct net_device *dev)
-+{
-+      netif_stop_queue(dev);
-+      return 0;
-+}
-+
-+static int imq_open(struct net_device *dev)
-+{
-+      netif_start_queue(dev);
-+      return 0;
-+}
-+
-+static const struct net_device_ops imq_netdev_ops = {
-+      .ndo_open               = imq_open,
-+      .ndo_stop               = imq_close,
-+      .ndo_start_xmit         = imq_dev_xmit,
-+      .ndo_get_stats          = imq_get_stats,
-+};
-+
-+static void imq_setup(struct net_device *dev)
-+{
-+      dev->netdev_ops         = &imq_netdev_ops;
-+      dev->type               = ARPHRD_VOID;
-+      dev->mtu                = 16000;
-+      dev->tx_queue_len       = 11000;
-+      dev->flags              = IFF_NOARP;
-+      dev->features           = NETIF_F_SG | NETIF_F_FRAGLIST |
-+                                NETIF_F_GSO | NETIF_F_HW_CSUM |
-+                                NETIF_F_HIGHDMA;
-+      dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
-+}
-+
-+static int imq_validate(struct nlattr *tb[], struct nlattr *data[])
-+{
-+      int ret = 0;
-+
-+      if (tb[IFLA_ADDRESS]) {
-+              if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
-+                      ret = -EINVAL;
-+                      goto end;
-+              }
-+              if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) {
-+                      ret = -EADDRNOTAVAIL;
-+                      goto end;
-+              }
-+      }
-+      return 0;
-+end:
-+      printk(KERN_WARNING "IMQ: imq_validate failed (%d)\n", ret);
-+      return ret;
-+}
-+
-+static struct rtnl_link_ops imq_link_ops __read_mostly = {
-+      .kind           = "imq",
-+      .priv_size      = 0,
-+      .setup          = imq_setup,
-+      .validate       = imq_validate,
-+};
-+
-+static int __init imq_init_hooks(void)
-+{
-+      int err;
-+
-+      nf_register_queue_imq_handler(&nfqh);
-+
-+      err = nf_register_hook(&imq_ingress_ipv4);
-+      if (err)
-+              goto err1;
-+
-+      err = nf_register_hook(&imq_egress_ipv4);
-+      if (err)
-+              goto err2;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      err = nf_register_hook(&imq_ingress_ipv6);
-+      if (err)
-+              goto err3;
-+
-+      err = nf_register_hook(&imq_egress_ipv6);
-+      if (err)
-+              goto err4;
-+#endif
-+
-+      return 0;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+err4:
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+err3:
-+      nf_unregister_hook(&imq_egress_ipv4);
-+#endif
-+err2:
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+err1:
-+      nf_unregister_queue_imq_handler();
-+      return err;
-+}
-+
-+static int __init imq_init_one(int index)
-+{
-+      struct net_device *dev;
-+      int ret;
-+
-+      dev = alloc_netdev(0, "imq%d", imq_setup);
-+      if (!dev)
-+              return -ENOMEM;
-+
-+      ret = dev_alloc_name(dev, dev->name);
-+      if (ret < 0)
-+              goto fail;
-+
-+      dev->rtnl_link_ops = &imq_link_ops;
-+      ret = register_netdevice(dev);
-+      if (ret < 0)
-+              goto fail;
-+
-+      return 0;
-+fail:
-+      free_netdev(dev);
-+      return ret;
-+}
-+
-+static int __init imq_init_devs(void)
-+{
-+      int err, i;
-+
-+      if (numdevs < 1 || numdevs > IMQ_MAX_DEVS) {
-+              printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n",
-+                     IMQ_MAX_DEVS);
-+              return -EINVAL;
-+      }
-+
-+      rtnl_lock();
-+      err = __rtnl_link_register(&imq_link_ops);
-+
-+      for (i = 0; i < numdevs && !err; i++)
-+              err = imq_init_one(i);
-+
-+      if (err) {
-+              __rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+      }
-+      rtnl_unlock();
-+
-+      return err;
-+}
-+
-+static int __init imq_init_module(void)
-+{
-+      int err;
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS > 16);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS < 2);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS - 1 > IMQ_F_IFMASK);
-+#endif
-+
-+      err = imq_init_devs();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_devs(net)\n");
-+              return err;
-+      }
-+
-+      err = imq_init_hooks();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n");
-+              rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+              return err;
-+      }
-+
-+      printk(KERN_INFO "IMQ driver loaded successfully.\n");
-+
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n");
-+#endif
-+#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n");
-+#endif
-+
-+      return 0;
-+}
-+
-+static void __exit imq_unhook(void)
-+{
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+      nf_unregister_hook(&imq_egress_ipv6);
-+#endif
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+      nf_unregister_hook(&imq_egress_ipv4);
-+
-+      nf_unregister_queue_imq_handler();
-+}
-+
-+static void __exit imq_cleanup_devs(void)
-+{
-+      rtnl_link_unregister(&imq_link_ops);
-+      memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+}
-+
-+static void __exit imq_exit_module(void)
-+{
-+      imq_unhook();
-+      imq_cleanup_devs();
-+      printk(KERN_INFO "IMQ driver unloaded successfully.\n");
-+}
-+
-+module_init(imq_init_module);
-+module_exit(imq_exit_module);
-+
-+module_param(numdevs, int, 0);
-+MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will "
-+                      "be created)");
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See "
-+                      "http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS_RTNL_LINK("imq");
-+
---- a/drivers/net/Kconfig
-+++ b/drivers/net/Kconfig
-@@ -124,6 +124,129 @@ config EQUALIZER
-         To compile this driver as a module, choose M here: the module
-         will be called eql.  If unsure, say N.
-+config IMQ
-+      tristate "IMQ (intermediate queueing device) support"
-+      depends on NETDEVICES && NETFILTER
-+      ---help---
-+        The IMQ device(s) is used as placeholder for QoS queueing
-+        disciplines. Every packet entering/leaving the IP stack can be
-+        directed through the IMQ device where it's enqueued/dequeued to the
-+        attached qdisc. This allows you to treat network devices as classes
-+        and distribute bandwidth among them. Iptables is used to specify
-+        through which IMQ device, if any, packets travel.
-+
-+        More information at: http://www.linuximq.net/
-+
-+        To compile this driver as a module, choose M here: the module
-+        will be called imq.  If unsure, say N.
-+
-+choice
-+      prompt "IMQ behavior (PRE/POSTROUTING)"
-+      depends on IMQ
-+      default IMQ_BEHAVIOR_AB
-+      help
-+
-+              This settings defines how IMQ behaves in respect to its
-+              hooking in PREROUTING and POSTROUTING.
-+
-+              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
-+
-+              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.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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 settings defines how many IMQ devices will be
-+              created.
-+
-+              The default value is 16.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              If not sure leave the default settings alone.
-+
- config TUN
-       tristate "Universal TUN/TAP device driver support"
-       select CRC32
---- a/drivers/net/Makefile
-+++ b/drivers/net/Makefile
-@@ -173,6 +173,7 @@ obj-$(CONFIG_SLHC) += slhc.o
- obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o
- obj-$(CONFIG_DUMMY) += dummy.o
-+obj-$(CONFIG_IMQ) += imq.o
- obj-$(CONFIG_IFB) += ifb.o
- obj-$(CONFIG_MACVLAN) += macvlan.o
- obj-$(CONFIG_MACVTAP) += macvtap.o
---- /dev/null
-+++ b/include/linux/imq.h
-@@ -0,0 +1,13 @@
-+#ifndef _IMQ_H
-+#define _IMQ_H
-+
-+/* IFMASK (16 device indexes, 0 to 15) and flag(s) fit in 5 bits */
-+#define IMQ_F_BITS    5
-+
-+#define IMQ_F_IFMASK  0x0f
-+#define IMQ_F_ENQUEUE 0x10
-+
-+#define IMQ_MAX_DEVS  (IMQ_F_IFMASK + 1)
-+
-+#endif /* _IMQ_H */
-+
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1323,6 +1323,7 @@ extern int               dev_alloc_name(struct net_de
- extern int            dev_open(struct net_device *dev);
- extern int            dev_close(struct net_device *dev);
- extern void           dev_disable_lro(struct net_device *dev);
-+extern struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb);
- extern int            dev_queue_xmit(struct sk_buff *skb);
- extern int            register_netdevice(struct net_device *dev);
- extern void           unregister_netdevice_queue(struct net_device *dev,
---- /dev/null
-+++ b/include/linux/netfilter/xt_IMQ.h
-@@ -0,0 +1,9 @@
-+#ifndef _XT_IMQ_H
-+#define _XT_IMQ_H
-+
-+struct xt_imq_info {
-+      unsigned int todev;     /* target imq device */
-+};
-+
-+#endif /* _XT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv4/ipt_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IPT_IMQ_H
-+#define _IPT_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ipt_imq_info xt_imq_info
-+
-+#endif /* _IPT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv6/ip6t_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IP6T_IMQ_H
-+#define _IP6T_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ip6t_imq_info xt_imq_info
-+
-+#endif /* _IP6T_IMQ_H */
-+
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -29,6 +29,9 @@
- #include <linux/rcupdate.h>
- #include <linux/dmaengine.h>
- #include <linux/hrtimer.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- /* Don't change this without changing skb_csum_unnecessary! */
- #define CHECKSUM_NONE 0
-@@ -328,6 +331,9 @@ struct sk_buff {
-        * first. This is owned by whoever has the skb queued ATM.
-        */
-       char                    cb[48] __aligned(8);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      void                    *cb_next;
-+#endif
-       unsigned long           _skb_refdst;
- #ifdef CONFIG_XFRM
-@@ -364,6 +370,9 @@ struct sk_buff {
-       struct nf_conntrack     *nfct;
-       struct sk_buff          *nfct_reasm;
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      struct nf_queue_entry   *nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       struct nf_bridge_info   *nf_bridge;
- #endif
-@@ -390,6 +399,10 @@ struct sk_buff {
-       /* 0/14 bit hole */
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      __u8                    imq_flags:IMQ_F_BITS;
-+#endif
-+
- #ifdef CONFIG_NET_DMA
-       dma_cookie_t            dma_cookie;
- #endif
-@@ -476,6 +489,12 @@ static inline struct rtable *skb_rtable(
-       return (struct rtable *)skb_dst(skb);
- }
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern int skb_save_cb(struct sk_buff *skb);
-+extern int skb_restore_cb(struct sk_buff *skb);
-+#endif
-+
- extern void kfree_skb(struct sk_buff *skb);
- extern void consume_skb(struct sk_buff *skb);
- extern void          __kfree_skb(struct sk_buff *skb);
-@@ -2098,6 +2117,10 @@ static inline void __nf_copy(struct sk_b
-       dst->nfct_reasm = src->nfct_reasm;
-       nf_conntrack_get_reasm(src->nfct_reasm);
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      dst->imq_flags = src->imq_flags;
-+      dst->nf_queue_entry = src->nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       dst->nf_bridge  = src->nf_bridge;
-       nf_bridge_get(src->nf_bridge);
---- a/include/net/netfilter/nf_queue.h
-+++ b/include/net/netfilter/nf_queue.h
-@@ -13,6 +13,12 @@ struct nf_queue_entry {
-       struct net_device       *indev;
-       struct net_device       *outdev;
-       int                     (*okfn)(struct sk_buff *);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      int                     (*next_outfn)(struct nf_queue_entry *entry,
-+                                            unsigned int queuenum);
-+      unsigned int            next_queuenum;
-+#endif
- };
- #define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry))
-@@ -30,5 +36,11 @@ extern int nf_unregister_queue_handler(u
-                                      const struct nf_queue_handler *qh);
- extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
- extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
-+extern void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern void nf_register_queue_imq_handler(const struct nf_queue_handler *qh);
-+extern void nf_unregister_queue_imq_handler(void);
-+#endif
- #endif /* _NF_QUEUE_H */
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -98,6 +98,9 @@
- #include <net/net_namespace.h>
- #include <net/sock.h>
- #include <linux/rtnetlink.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- #include <linux/proc_fs.h>
- #include <linux/seq_file.h>
- #include <linux/stat.h>
-@@ -1995,7 +1998,11 @@ int dev_hard_start_xmit(struct sk_buff *
-       int rc = NETDEV_TX_OK;
-       if (likely(!skb->next)) {
--              if (!list_empty(&ptype_all))
-+              if (!list_empty(&ptype_all)
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+                      && !(skb->imq_flags & IMQ_F_ENQUEUE)
-+#endif
-+                 )
-                       dev_queue_xmit_nit(skb, dev);
-               /*
-@@ -2119,8 +2126,7 @@ static inline u16 dev_cap_txqueue(struct
-       return queue_index;
- }
--static struct netdev_queue *dev_pick_tx(struct net_device *dev,
--                                      struct sk_buff *skb)
-+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;
-@@ -2149,6 +2155,7 @@ static struct netdev_queue *dev_pick_tx(
-       skb_set_queue_mapping(skb, queue_index);
-       return netdev_get_tx_queue(dev, queue_index);
- }
-+EXPORT_SYMBOL(dev_pick_tx);
- static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
-                                struct net_device *dev,
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -72,6 +72,9 @@
- static struct kmem_cache *skbuff_head_cache __read_mostly;
- static struct kmem_cache *skbuff_fclone_cache __read_mostly;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static struct kmem_cache *skbuff_cb_store_cache __read_mostly;
-+#endif
- static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
-                                 struct pipe_buffer *buf)
-@@ -91,6 +94,83 @@ static int sock_pipe_buf_steal(struct pi
-       return 1;
- }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+/* Control buffer save/restore for IMQ devices */
-+struct skb_cb_table {
-+      void                    *cb_next;
-+      atomic_t                refcnt;
-+      char                    cb[48];
-+};
-+
-+static DEFINE_SPINLOCK(skb_cb_store_lock);
-+
-+int skb_save_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      next = kmem_cache_alloc(skbuff_cb_store_cache, GFP_ATOMIC);
-+      if (!next)
-+              return -ENOMEM;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(next->cb, skb->cb, sizeof(skb->cb));
-+      next->cb_next = skb->cb_next;
-+
-+      atomic_set(&next->refcnt, 1);
-+
-+      skb->cb_next = next;
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_save_cb);
-+
-+int skb_restore_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      if (!skb->cb_next)
-+              return 0;
-+
-+      next = skb->cb_next;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(skb->cb, next->cb, sizeof(skb->cb));
-+      skb->cb_next = next->cb_next;
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      if (atomic_dec_and_test(&next->refcnt)) {
-+              kmem_cache_free(skbuff_cb_store_cache, next);
-+      }
-+
-+      spin_unlock(&skb_cb_store_lock);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_restore_cb);
-+
-+static void skb_copy_stored_cb(struct sk_buff *new, const struct sk_buff *__old)
-+{
-+      struct skb_cb_table *next;
-+      struct sk_buff *old;
-+
-+      if (!__old->cb_next) {
-+              new->cb_next = NULL;
-+              return;
-+      }
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      old = (struct sk_buff *)__old;
-+
-+      next = old->cb_next;
-+      atomic_inc(&next->refcnt);
-+      new->cb_next = next;
-+
-+      spin_unlock(&skb_cb_store_lock);
-+}
-+#endif
- /* Pipe buffer operations for a socket. */
- static const struct pipe_buf_operations sock_pipe_buf_ops = {
-@@ -378,6 +458,26 @@ static void skb_release_head_state(struc
-               WARN_ON(in_irq());
-               skb->destructor(skb);
-       }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      /* This should not happen. When it does, avoid memleak by restoring
-+      the chain of cb-backups. */
-+      while(skb->cb_next != NULL) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING "IMQ: kfree_skb: skb->cb_next: "
-+                              "%08x\n", (unsigned int)skb->cb_next);
-+
-+              skb_restore_cb(skb);
-+      }
-+      /* This should not happen either, nf_queue_entry is nullified in
-+       * imq_dev_xmit(). If we have non-NULL nf_queue_entry then we are
-+       * leaking entry pointers, maybe memory. We don't know if this is
-+       * pointer to already freed memory, or should this be freed.
-+       * If this happens we need to add refcounting, etc for nf_queue_entry.
-+       */
-+      if (skb->nf_queue_entry && net_ratelimit())
-+              printk(KERN_WARNING
-+                              "IMQ: kfree_skb: skb->nf_queue_entry != NULL");
-+#endif
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-       nf_conntrack_put(skb->nfct);
-       nf_conntrack_put_reasm(skb->nfct_reasm);
-@@ -514,6 +614,9 @@ static void __copy_skb_header(struct sk_
-       new->sp                 = secpath_get(old->sp);
- #endif
-       memcpy(new->cb, old->cb, sizeof(old->cb));
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skb_copy_stored_cb(new, old);
-+#endif
-       new->csum               = old->csum;
-       new->local_df           = old->local_df;
-       new->pkt_type           = old->pkt_type;
-@@ -2765,6 +2868,13 @@ void __init skb_init(void)
-                                               0,
-                                               SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-                                               NULL);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skbuff_cb_store_cache = kmem_cache_create("skbuff_cb_store_cache",
-+                                                sizeof(struct skb_cb_table),
-+                                                0,
-+                                                SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-+                                                NULL);
-+#endif
- }
- /**
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -455,6 +455,18 @@ config NETFILTER_XT_TARGET_LED
-         For more information on the LEDs available on your system, see
-         Documentation/leds-class.txt
-+config NETFILTER_XT_TARGET_IMQ
-+        tristate '"IMQ" target support'
-+      depends on NETFILTER_XTABLES
-+      depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+      select IMQ
-+      default m if NETFILTER_ADVANCED=n
-+        help
-+          This option adds a `IMQ' target which is used to specify if and
-+          to which imq device packets should get enqueued/dequeued.
-+
-+          To compile it as a module, choose M here.  If unsure, say N.
-+
- config NETFILTER_XT_TARGET_MARK
-       tristate '"MARK" target support'
-       depends on NETFILTER_ADVANCED
---- a/net/netfilter/Makefile
-+++ b/net/netfilter/Makefile
-@@ -51,6 +51,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSEC
- obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
-+obj-$(CONFIG_NETFILTER_XT_TARGET_IMQ) += xt_IMQ.o
- 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
---- a/net/netfilter/nf_queue.c
-+++ b/net/netfilter/nf_queue.c
-@@ -22,6 +22,26 @@ static const struct nf_queue_handler __r
- static DEFINE_MUTEX(queue_handler_mutex);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static const struct nf_queue_handler *queue_imq_handler;
-+
-+void nf_register_queue_imq_handler(const struct nf_queue_handler *qh)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, qh);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_register_queue_imq_handler);
-+
-+void nf_unregister_queue_imq_handler(void)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, NULL);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_unregister_queue_imq_handler);
-+#endif
-+
- /* return EBUSY when somebody else is registered, return EEXIST if the
-  * same handler is registered, return 0 in case of success. */
- int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
-@@ -82,7 +102,7 @@ void nf_unregister_queue_handlers(const
- }
- EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);
--static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
-+void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
- {
-       /* Release those devices we held, or Alexey will kill me. */
-       if (entry->indev)
-@@ -102,6 +122,7 @@ static void nf_queue_entry_release_refs(
-       /* Drop reference to owner of hook which queued us. */
-       module_put(entry->elem->owner);
- }
-+EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
- /*
-  * Any packet that leaves via this function must come back
-@@ -123,12 +144,26 @@ static int __nf_queue(struct sk_buff *sk
- #endif
-       const struct nf_afinfo *afinfo;
-       const struct nf_queue_handler *qh;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      const struct nf_queue_handler *qih = NULL;
-+#endif
-       /* QUEUE == DROP if noone is waiting, to be safe. */
-       rcu_read_lock();
-       qh = rcu_dereference(queue_handler[pf]);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      if (pf == PF_INET || pf == PF_INET6)
-+#else
-+      if (pf == PF_INET)
-+#endif
-+              qih = rcu_dereference(queue_imq_handler);
-+
-+      if (!qh && !qih)
-+#else /* !IMQ */
-       if (!qh)
-+#endif
-               goto err_unlock;
-       afinfo = nf_get_afinfo(pf);
-@@ -147,6 +182,10 @@ static int __nf_queue(struct sk_buff *sk
-               .indev  = indev,
-               .outdev = outdev,
-               .okfn   = okfn,
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+              .next_outfn = qh ? qh->outfn : NULL,
-+              .next_queuenum = queuenum,
-+#endif
-       };
-       /* If it's going away, ignore hook. */
-@@ -173,8 +212,19 @@ static int __nf_queue(struct sk_buff *sk
- #endif
-       skb_dst_force(skb);
-       afinfo->saveroute(skb, entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      if (qih) {
-+              status = qih->outfn(entry, queuenum);
-+              goto imq_skip_queue;
-+      }
-+#endif
-+
-       status = qh->outfn(entry, queuenum);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+imq_skip_queue:
-+#endif
-       rcu_read_unlock();
-       if (status < 0) {
---- /dev/null
-+++ b/net/netfilter/xt_IMQ.c
-@@ -0,0 +1,73 @@
-+/*
-+ * This target marks packets to be enqueued to an imq device
-+ */
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter/x_tables.h>
-+#include <linux/netfilter/xt_IMQ.h>
-+#include <linux/imq.h>
-+
-+static unsigned int imq_target(struct sk_buff *pskb,
-+                              const struct xt_action_param *par)
-+{
-+      const struct xt_imq_info *mr = par->targinfo;
-+
-+      pskb->imq_flags = (mr->todev & IMQ_F_IFMASK) | IMQ_F_ENQUEUE;
-+
-+      return XT_CONTINUE;
-+}
-+
-+static int imq_checkentry(const struct xt_tgchk_param *par)
-+{
-+      struct xt_imq_info *mr = par->targinfo;
-+
-+      if (mr->todev > IMQ_MAX_DEVS - 1) {
-+              printk(KERN_WARNING
-+                     "IMQ: invalid device specified, highest is %u\n",
-+                     IMQ_MAX_DEVS - 1);
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static struct xt_target xt_imq_reg[] __read_mostly = {
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET6,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+};
-+
-+static int __init imq_init(void)
-+{
-+      return xt_register_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+static void __exit imq_fini(void)
-+{
-+      xt_unregister_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+module_init(imq_init);
-+module_exit(imq_fini);
-+
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("ipt_IMQ");
-+MODULE_ALIAS("ip6t_IMQ");
-+
index 22bf51c..d270e90 100644 (file)
@@ -8,7 +8,7 @@
        depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
        depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
-@@ -570,7 +569,6 @@ config NETFILTER_XT_TARGET_SECMARK
+@@ -558,7 +557,6 @@ config NETFILTER_XT_TARGET_SECMARK
  
  config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
  
  config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
index e432471..6ea9ba5 100644 (file)
@@ -1,6 +1,6 @@
 --- a/arch/mips/include/asm/string.h
 +++ b/arch/mips/include/asm/string.h
 --- a/arch/mips/include/asm/string.h
 +++ b/arch/mips/include/asm/string.h
-@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__
+@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__ 
  
  #define __HAVE_ARCH_MEMSET
  extern void *memset(void *__s, int __c, size_t __count);
  
  #define __HAVE_ARCH_MEMSET
  extern void *memset(void *__s, int __c, size_t __count);
index fe8cecf..83fd6c3 100644 (file)
@@ -1,6 +1,6 @@
 --- a/include/linux/slab.h
 +++ b/include/linux/slab.h
 --- a/include/linux/slab.h
 +++ b/include/linux/slab.h
-@@ -130,8 +130,8 @@ int kmem_ptr_validate(struct kmem_cache
+@@ -130,8 +130,8 @@ int kmem_ptr_validate(struct kmem_cache 
   * to do various tricks to work around compiler limitations in order to
   * ensure proper constant folding.
   */
   * to do various tricks to work around compiler limitations in order to
   * ensure proper constant folding.
   */
index d021ec1..826eb44 100644 (file)
@@ -61,7 +61,7 @@
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd);
  
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd);
  
-@@ -501,6 +505,29 @@ static inline void double_unlock(struct
+@@ -501,6 +505,29 @@ static inline void double_unlock(struct 
  #endif  /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
  #endif /* __KERNEL__ */
  
  #endif  /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
  #endif /* __KERNEL__ */
  
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
 --- a/fs/mini_fo/aux.c
 +++ b/fs/mini_fo/aux.c
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
 --- a/fs/mini_fo/aux.c
 +++ b/fs/mini_fo/aux.c
-@@ -164,11 +164,11 @@ dentry_t *bpath_walk(super_block_t *sb,
+@@ -164,11 +164,11 @@ dentry_t *bpath_walk(super_block_t *sb, 
        err = vfs_path_lookup(mnt->mnt_root, mnt, bpath+1, 0, &nd);
  
        /* validate */
        err = vfs_path_lookup(mnt->mnt_root, mnt, bpath+1, 0, &nd);
  
        /* validate */
index d2a843c..3750371 100644 (file)
@@ -1,6 +1,6 @@
 --- a/fs/mini_fo/super.c
 +++ b/fs/mini_fo/super.c
 --- a/fs/mini_fo/super.c
 +++ b/fs/mini_fo/super.c
-@@ -84,6 +84,7 @@ mini_fo_write_inode(inode_t *inode, int
+@@ -84,6 +84,7 @@ mini_fo_write_inode(inode_t *inode, int 
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
  
  
  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
  
  
index 7b36ab6..b3e4b6e 100644 (file)
@@ -20,7 +20,7 @@
  #else
  static inline int kobject_uevent(struct kobject *kobj,
                                 enum kobject_action action)
  #else
  static inline int kobject_uevent(struct kobject *kobj,
                                 enum kobject_action action)
-@@ -231,6 +237,16 @@ static inline int add_uevent_var(struct
+@@ -231,6 +237,16 @@ static inline int add_uevent_var(struct 
  static inline int kobject_action_type(const char *buf, size_t count,
                                      enum kobject_action *type)
  { return -EINVAL; }
  static inline int kobject_action_type(const char *buf, size_t count,
                                      enum kobject_action *type)
  { return -EINVAL; }
index 013c116..33429cb 100644 (file)
 +module_exit(connmark_cleanup_module);
 --- a/net/sched/Kconfig
 +++ b/net/sched/Kconfig
 +module_exit(connmark_cleanup_module);
 --- a/net/sched/Kconfig
 +++ b/net/sched/Kconfig
-@@ -559,6 +559,18 @@
+@@ -559,6 +559,18 @@ config NET_ACT_CSUM
          To compile this code as a module, choose M here: the
          module will be called act_csum.
  
          To compile this code as a module, choose M here: the
          module will be called act_csum.
  
        depends on NET_CLS_U32 || NET_CLS_FW
 --- a/net/sched/Makefile
 +++ b/net/sched/Makefile
        depends on NET_CLS_U32 || NET_CLS_FW
 --- a/net/sched/Makefile
 +++ b/net/sched/Makefile
-@@ -16,6 +16,7 @@
+@@ -16,6 +16,7 @@ obj-$(CONFIG_NET_ACT_PEDIT)  += act_pedit
  obj-$(CONFIG_NET_ACT_SIMP)    += act_simple.o
  obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o
  obj-$(CONFIG_NET_ACT_CSUM)    += act_csum.o
  obj-$(CONFIG_NET_ACT_SIMP)    += act_simple.o
  obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o
  obj-$(CONFIG_NET_ACT_CSUM)    += act_csum.o
index 8d90184..62a90a4 100644 (file)
@@ -11,7 +11,7 @@
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
-@@ -52,3 +52,4 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) +=
+@@ -52,3 +52,4 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += 
  obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)  += ledtrig-backlight.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)  += ledtrig-backlight.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
index 6406ada..5354aa1 100644 (file)
@@ -14,7 +14,7 @@
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
  endif # NEW_LEDS
 --- a/drivers/leds/Makefile
 +++ b/drivers/leds/Makefile
-@@ -53,3 +53,4 @@ obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) +=
+@@ -53,3 +53,4 @@ obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += 
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_MORSE)      += ledtrig-morse.o
  obj-$(CONFIG_LEDS_TRIGGER_GPIO)               += ledtrig-gpio.o
  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
  obj-$(CONFIG_LEDS_TRIGGER_MORSE)      += ledtrig-morse.o
index 3b70632..6609a16 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/char/gpio_dev.c
 +++ b/drivers/char/gpio_dev.c
 --- a/drivers/char/gpio_dev.c
 +++ b/drivers/char/gpio_dev.c
-@@ -114,7 +114,7 @@ gpio_close(struct inode * inode, struct
+@@ -114,7 +114,7 @@ gpio_close(struct inode * inode, struct 
  }
  
  struct file_operations gpio_fops = {
  }
  
  struct file_operations gpio_fops = {
index c334b17..5c70e79 100644 (file)
                        dev->checkpointBlockList[i] = -1;
        }
  
                        dev->checkpointBlockList[i] = -1;
        }
  
-@@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device
+@@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device 
  
  static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
  {
  
  static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
  {
  {
        unsigned char cDelta;   /* column parity delta */
        unsigned lDelta;        /* line parity delta */
  {
        unsigned char cDelta;   /* column parity delta */
        unsigned lDelta;        /* line parity delta */
-@@ -294,8 +292,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -294,8 +292,7 @@ int yaffs_ECCCorrectOther(unsigned char 
                return 0; /* no error */
  
        if (lDelta == ~lDeltaPrime &&
                return 0; /* no error */
  
        if (lDelta == ~lDeltaPrime &&
                /* Single bit (recoverable) error in data */
  
                bit = 0;
                /* Single bit (recoverable) error in data */
  
                bit = 0;
-@@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char 
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                        return -1;
  
                data[lDelta] ^= (1 << bit);
                        return -1;
  
                data[lDelta] ^= (1 << bit);
-@@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char 
        }
  
        if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
        }
  
        if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
                /* Reccoverable error in ecc */
  
                *read_ecc = *test_ecc;
                /* Reccoverable error in ecc */
  
                *read_ecc = *test_ecc;
-@@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char 
        /* Unrecoverable error */
  
        return -1;
        /* Unrecoverable error */
  
        return -1;
  {
        unsigned char *alias;
        int ret;
  {
        unsigned char *alias;
        int ret;
-@@ -329,7 +395,7 @@ static int yaffs_readlink(struct dentry
+@@ -329,7 +395,7 @@ static int yaffs_readlink(struct dentry 
        return ret;
  }
  
        return ret;
  }
  
  static int yaffs_file_flush(struct file *file, fl_owner_t id)
  #else
  static int yaffs_file_flush(struct file *file)
  static int yaffs_file_flush(struct file *file, fl_owner_t id)
  #else
  static int yaffs_file_flush(struct file *file)
-@@ -513,8 +579,8 @@ static int yaffs_file_flush(struct file
+@@ -513,8 +579,8 @@ static int yaffs_file_flush(struct file 
        yaffs_Device *dev = obj->myDev;
  
        T(YAFFS_TRACE_OS,
        yaffs_Device *dev = obj->myDev;
  
        T(YAFFS_TRACE_OS,
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossLock(dev);
  
-@@ -535,15 +601,15 @@ static int yaffs_readpage_nolock(struct
+@@ -535,15 +601,15 @@ static int yaffs_readpage_nolock(struct 
  
        yaffs_Device *dev;
  
  
        yaffs_Device *dev;
  
        BUG_ON(!PageLocked(pg));
  #else
        if (!PageLocked(pg))
        BUG_ON(!PageLocked(pg));
  #else
        if (!PageLocked(pg))
-@@ -555,9 +621,9 @@ static int yaffs_readpage_nolock(struct
+@@ -555,9 +621,9 @@ static int yaffs_readpage_nolock(struct 
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossLock(dev);
  
  
        yaffs_GrossUnlock(dev);
  
  
        yaffs_GrossUnlock(dev);
  
-@@ -575,7 +641,7 @@ static int yaffs_readpage_nolock(struct
+@@ -575,7 +641,7 @@ static int yaffs_readpage_nolock(struct 
        flush_dcache_page(pg);
        kunmap(pg);
  
        flush_dcache_page(pg);
        kunmap(pg);
  
                if (n < step) {
                        n++;
                        continue;
                if (n < step) {
                        n++;
                        continue;
-@@ -2119,7 +2356,7 @@ static int yaffs_proc_write(struct file
+@@ -2119,7 +2356,7 @@ static int yaffs_proc_write(struct file 
        char *end;
        char *mask_name;
        const char *x;
        char *end;
        char *mask_name;
        const char *x;
        int i;
        int done = 0;
        int add, len = 0;
        int i;
        int done = 0;
        int add, len = 0;
-@@ -2129,9 +2366,8 @@ static int yaffs_proc_write(struct file
+@@ -2129,9 +2366,8 @@ static int yaffs_proc_write(struct file 
  
        while (!done && (pos < count)) {
                done = 1;
  
        while (!done && (pos < count)) {
                done = 1;
  
                switch (buf[pos]) {
                case '+':
  
                switch (buf[pos]) {
                case '+':
-@@ -2148,20 +2384,21 @@ static int yaffs_proc_write(struct file
+@@ -2148,20 +2384,21 @@ static int yaffs_proc_write(struct file 
                mask_name = NULL;
  
                mask_bitfield = simple_strtoul(buf + pos, &end, 0);
                mask_name = NULL;
  
                mask_bitfield = simple_strtoul(buf + pos, &end, 0);
                                        mask_name = mask_flags[i].mask_name;
                                        mask_bitfield = mask_flags[i].mask_bitfield;
                                        done = 0;
                                        mask_name = mask_flags[i].mask_name;
                                        mask_bitfield = mask_flags[i].mask_bitfield;
                                        done = 0;
-@@ -2172,7 +2409,7 @@ static int yaffs_proc_write(struct file
+@@ -2172,7 +2409,7 @@ static int yaffs_proc_write(struct file 
  
                if (mask_name != NULL) {
                        done = 0;
  
                if (mask_name != NULL) {
                        done = 0;
                        case '-':
                                rg &= ~mask_bitfield;
                                break;
                        case '-':
                                rg &= ~mask_bitfield;
                                break;
-@@ -2191,13 +2428,13 @@ static int yaffs_proc_write(struct file
+@@ -2191,13 +2428,13 @@ static int yaffs_proc_write(struct file 
  
        yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
  
  
        yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
  
  {
        /* Get the real object in case we were fed a hard link as an equivalent object */
        equivalentObject = yaffs_GetEquivalentObject(equivalentObject);
  {
        /* Get the real object in case we were fed a hard link as an equivalent object */
        equivalentObject = yaffs_GetEquivalentObject(equivalentObject);
-@@ -2363,33 +2396,31 @@ yaffs_Object *yaffs_Link(yaffs_Object *
+@@ -2363,33 +2396,31 @@ yaffs_Object *yaffs_Link(yaffs_Object * 
  
  }
  
  
  }
  
        int nToCopy;
        int n = nBytes;
        int nDone = 0;
        int nToCopy;
        int n = nBytes;
        int nDone = 0;
-@@ -4600,27 +4665,26 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4600,27 +4665,26 @@ int yaffs_ReadDataFromFile(yaffs_Object 
        dev = in->myDev;
  
        while (n > 0) {
        dev = in->myDev;
  
        while (n > 0) {
                        if (dev->nShortOpCaches > 0) {
  
                                /* If we can't find the data in the cache, then load it up. */
                        if (dev->nShortOpCaches > 0) {
  
                                /* If we can't find the data in the cache, then load it up. */
-@@ -4641,14 +4705,9 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4641,14 +4705,9 @@ int yaffs_ReadDataFromFile(yaffs_Object 
  
                                cache->locked = 1;
  
  
                                cache->locked = 1;
  
                                cache->locked = 0;
                        } else {
                                /* Read into the local buffer then copy..*/
                                cache->locked = 0;
                        } else {
                                /* Read into the local buffer then copy..*/
-@@ -4657,41 +4716,19 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4657,41 +4716,19 @@ int yaffs_ReadDataFromFile(yaffs_Object 
                                    yaffs_GetTempBuffer(dev, __LINE__);
                                yaffs_ReadChunkDataFromObject(in, chunk,
                                                              localBuffer);
                                    yaffs_GetTempBuffer(dev, __LINE__);
                                yaffs_ReadChunkDataFromObject(in, chunk,
                                                              localBuffer);
                }
  
                n -= nToCopy;
                }
  
                n -= nToCopy;
-@@ -4704,28 +4741,37 @@ int yaffs_ReadDataFromFile(yaffs_Object
+@@ -4704,28 +4741,37 @@ int yaffs_ReadDataFromFile(yaffs_Object 
        return nDone;
  }
  
        return nDone;
  }
  
        int newFullChunks;
  
        yaffs_Device *dev = in->myDev;
        int newFullChunks;
  
        yaffs_Device *dev = in->myDev;
-@@ -4955,13 +4981,11 @@ int yaffs_ResizeFile(yaffs_Object * in,
+@@ -4955,13 +4981,11 @@ int yaffs_ResizeFile(yaffs_Object * in, 
  
        yaffs_CheckGarbageCollection(dev);
  
  
        yaffs_CheckGarbageCollection(dev);
  
  
        if (newSize < oldFileSize) {
  
  
        if (newSize < oldFileSize) {
  
-@@ -4994,21 +5018,20 @@ int yaffs_ResizeFile(yaffs_Object * in,
+@@ -4994,21 +5018,20 @@ int yaffs_ResizeFile(yaffs_Object * in, 
        }
  
  
        }
  
  
  {
        obj = yaffs_GetEquivalentObject(obj);
  
  {
        obj = yaffs_GetEquivalentObject(obj);
  
-@@ -5024,7 +5047,7 @@ loff_t yaffs_GetFileSize(yaffs_Object *
+@@ -5024,7 +5047,7 @@ loff_t yaffs_GetFileSize(yaffs_Object * 
  
  
  
  
  
  
  {
        int init_failed = 0;
        unsigned x;
  {
        int init_failed = 0;
        unsigned x;
-@@ -7040,6 +7126,8 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7040,6 +7126,8 @@ int yaffs_GutsInitialise(yaffs_Device * 
        dev->chunkOffset = 0;
        dev->nFreeChunks = 0;
  
        dev->chunkOffset = 0;
        dev->nFreeChunks = 0;
  
        if (dev->startBlock == 0) {
                dev->internalStartBlock = dev->startBlock + 1;
                dev->internalEndBlock = dev->endBlock + 1;
        if (dev->startBlock == 0) {
                dev->internalStartBlock = dev->startBlock + 1;
                dev->internalEndBlock = dev->endBlock + 1;
-@@ -7049,18 +7137,18 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7049,18 +7137,18 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        /* Check geometry parameters. */
  
  
        /* Check geometry parameters. */
  
                return YAFFS_FAIL;
        }
  
                return YAFFS_FAIL;
        }
  
-@@ -7070,6 +7158,12 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7070,6 +7158,12 @@ int yaffs_GutsInitialise(yaffs_Device * 
                return YAFFS_FAIL;
        }
  
                return YAFFS_FAIL;
        }
  
        /* Got the right mix of functions? */
        if (!yaffs_CheckDevFunctions(dev)) {
                /* Function missing */
        /* Got the right mix of functions? */
        if (!yaffs_CheckDevFunctions(dev)) {
                /* Function missing */
-@@ -7097,31 +7191,18 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7097,31 +7191,18 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        dev->isMounted = 1;
  
  
        dev->isMounted = 1;
  
  
        /*
         * Calculate chunkGroupBits.
  
        /*
         * Calculate chunkGroupBits.
-@@ -7133,16 +7214,15 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7133,16 +7214,15 @@ int yaffs_GutsInitialise(yaffs_Device * 
        bits = ShiftsGE(x);
  
        /* Set up tnode width if wide tnodes are enabled. */
        bits = ShiftsGE(x);
  
        /* Set up tnode width if wide tnodes are enabled. */
                dev->tnodeWidth = 16;
  
        dev->tnodeMask = (1<<dev->tnodeWidth)-1;
                dev->tnodeWidth = 16;
  
        dev->tnodeMask = (1<<dev->tnodeWidth)-1;
-@@ -7193,7 +7273,7 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7193,7 +7273,7 @@ int yaffs_GutsInitialise(yaffs_Device * 
        dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */
  
        /* Initialise temporary buffers and caches. */
        dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */
  
        /* Initialise temporary buffers and caches. */
                init_failed = 1;
  
        dev->srCache = NULL;
                init_failed = 1;
  
        dev->srCache = NULL;
-@@ -7203,25 +7283,26 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7203,25 +7283,26 @@ int yaffs_GutsInitialise(yaffs_Device * 
        if (!init_failed &&
            dev->nShortOpCaches > 0) {
                int i;
        if (!init_failed &&
            dev->nShortOpCaches > 0) {
                int i;
                        init_failed = 1;
  
                dev->srLastUse = 0;
                        init_failed = 1;
  
                dev->srLastUse = 0;
-@@ -7229,29 +7310,30 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7229,29 +7310,30 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
        dev->cacheHits = 0;
  
  
        dev->cacheHits = 0;
  
                                T(YAFFS_TRACE_ALWAYS,
                                  (TSTR("yaffs: restored from checkpoint" TENDSTR)));
                        } else {
                                T(YAFFS_TRACE_ALWAYS,
                                  (TSTR("yaffs: restored from checkpoint" TENDSTR)));
                        } else {
-@@ -7273,24 +7355,25 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7273,24 +7355,25 @@ int yaffs_GutsInitialise(yaffs_Device * 
                                dev->nBackgroundDeletions = 0;
                                dev->oldestDirtySequence = 0;
  
                                dev->nBackgroundDeletions = 0;
                                dev->oldestDirtySequence = 0;
  
                /* Clean up the mess */
                T(YAFFS_TRACE_TRACING,
                  (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR)));
                /* Clean up the mess */
                T(YAFFS_TRACE_TRACING,
                  (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR)));
-@@ -7318,7 +7401,7 @@ int yaffs_GutsInitialise(yaffs_Device *
+@@ -7318,7 +7401,7 @@ int yaffs_GutsInitialise(yaffs_Device * 
  
  }
  
  
  }
  
  {
        if (etags) {
                memset(etags, 0, sizeof(*etags));
  {
        if (etags) {
                memset(etags, 0, sizeof(*etags));
-@@ -169,9 +169,9 @@ static int rettags(yaffs_ExtendedTags *
+@@ -169,9 +169,9 @@ static int rettags(yaffs_ExtendedTags * 
   * Returns YAFFS_OK or YAFFS_FAIL.
   */
  int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
   * Returns YAFFS_OK or YAFFS_FAIL.
   */
  int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
 +                      yaffs_UnpackTags2(tags, &pt);
 +              }
 +      }
 +                      yaffs_UnpackTags2(tags, &pt);
 +              }
 +      }
-+
+-      if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
+-              tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
 +      if (localData)
 +              yaffs_ReleaseTempBuffer(dev, data, __LINE__);
  
 +      if (localData)
 +              yaffs_ReleaseTempBuffer(dev, data, __LINE__);
  
--      if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
 +      if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
 +      if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
-               tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
--
++              tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
        if (retval == 0)
                return YAFFS_OK;
        else
        if (retval == 0)
                return YAFFS_OK;
        else
index d03deb8..b5ceb47 100644 (file)
  chunk/page state.  This byte is zeroed when the page is discarded.
  Choose this option if you have existing on-NAND data in this format
  that you need to continue to support.  New data written also uses the
  chunk/page state.  This byte is zeroed when the page is discarded.
  Choose this option if you have existing on-NAND data in this format
  that you need to continue to support.  New data written also uses the
-@@ -57,7 +78,7 @@ adjusted to use the older-style format.
+@@ -57,7 +78,7 @@ adjusted to use the older-style format. 
  MTD versions in yaffs_mtdif1.c.
  */
  /* Default: Not selected */
  MTD versions in yaffs_mtdif1.c.
  */
  /* Default: Not selected */
                        yaffs_ECCOther *read_ecc,
                        const yaffs_ECCOther *test_ecc)
  {
                        yaffs_ECCOther *read_ecc,
                        const yaffs_ECCOther *test_ecc)
  {
-@@ -304,7 +301,7 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -304,7 +301,7 @@ int yaffs_ECCCorrectOther(unsigned char 
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                if (cDelta & 0x02)
                        bit |= 0x01;
  
                        return -1;
  
                data[lDelta] ^= (1 << bit);
                        return -1;
  
                data[lDelta] ^= (1 << bit);
-@@ -312,8 +309,8 @@ int yaffs_ECCCorrectOther(unsigned char
+@@ -312,8 +309,8 @@ int yaffs_ECCCorrectOther(unsigned char 
                return 1; /* corrected */
        }
  
                return 1; /* corrected */
        }
  
index e400531..ad44715 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/hostap/hostap_ap.c
 +++ b/drivers/net/wireless/hostap/hostap_ap.c
 --- a/drivers/net/wireless/hostap/hostap_ap.c
 +++ b/drivers/net/wireless/hostap/hostap_ap.c
-@@ -2335,13 +2335,13 @@ int prism2_ap_get_sta_qual(local_info_t
+@@ -2335,13 +2335,13 @@ int prism2_ap_get_sta_qual(local_info_t 
                addr[count].sa_family = ARPHRD_ETHER;
                memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
                if (sta->last_rx_silence == 0)
                addr[count].sa_family = ARPHRD_ETHER;
                memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
                if (sta->last_rx_silence == 0)
index 410384c..a1c088a 100644 (file)
@@ -24,7 +24,7 @@
   * All of these routines try to estimate how many bits of randomness a
   * particular randomness source.  They do this by keeping track of the
   * first and second order deltas of the event timings.
   * All of these routines try to estimate how many bits of randomness a
   * particular randomness source.  They do this by keeping track of the
   * first and second order deltas of the event timings.
-@@ -715,6 +725,61 @@ void add_disk_randomness(struct gendisk
+@@ -715,6 +725,61 @@ void add_disk_randomness(struct gendisk 
  }
  #endif
  
  }
  #endif
  
index c4cc058..c1a70f0 100644 (file)
@@ -1,6 +1,6 @@
 --- a/scripts/Makefile.lib
 +++ b/scripts/Makefile.lib
 --- a/scripts/Makefile.lib
 +++ b/scripts/Makefile.lib
-@@ -231,7 +231,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^)
+@@ -231,7 +231,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^) 
  
  quiet_cmd_lzma = LZMA    $@
  cmd_lzma = (cat $(filter-out FORCE,$^) | \
  
  quiet_cmd_lzma = LZMA    $@
  cmd_lzma = (cat $(filter-out FORCE,$^) | \
diff --git a/target/linux/generic/patches-2.6.38/150-netfilter_imq.patch b/target/linux/generic/patches-2.6.38/150-netfilter_imq.patch
deleted file mode 100644 (file)
index 8853e89..0000000
+++ /dev/null
@@ -1,1342 +0,0 @@
---- /dev/null
-+++ b/drivers/net/imq.c
-@@ -0,0 +1,638 @@
-+/*
-+ *             Pseudo-driver for the intermediate queue device.
-+ *
-+ *             This program is free software; you can redistribute it and/or
-+ *             modify it under the terms of the GNU General Public License
-+ *             as published by the Free Software Foundation; either version
-+ *             2 of the License, or (at your option) any later version.
-+ *
-+ * Authors:    Patrick McHardy, <kaber@trash.net>
-+ *
-+ *            The first version was written by Martin Devera, <devik@cdi.cz>
-+ *
-+ * Credits:    Jan Rafaj <imq2t@cedric.vabo.cz>
-+ *              - Update patch to 2.4.21
-+ *             Sebastian Strollo <sstrollo@nortelnetworks.com>
-+ *              - Fix "Dead-loop on netdevice imq"-issue
-+ *             Marcel Sebek <sebek64@post.cz>
-+ *              - Update to 2.6.2-rc1
-+ *
-+ *           After some time of inactivity there is a group taking care
-+ *           of IMQ again: http://www.linuximq.net
-+ *
-+ *
-+ *           2004/06/30 - New version of IMQ patch to kernels <=2.6.7
-+ *             including the following changes:
-+ *
-+ *           - Correction of ipv6 support "+"s issue (Hasso Tepper)
-+ *           - Correction of imq_init_devs() issue that resulted in
-+ *           kernel OOPS unloading IMQ as module (Norbert Buchmuller)
-+ *           - Addition of functionality to choose number of IMQ devices
-+ *           during kernel config (Andre Correa)
-+ *           - Addition of functionality to choose how IMQ hooks on
-+ *           PRE and POSTROUTING (after or before NAT) (Andre Correa)
-+ *           - Cosmetic corrections (Norbert Buchmuller) (Andre Correa)
-+ *
-+ *
-+ *             2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were
-+ *             released with almost no problems. 2.6.14-x was released
-+ *             with some important changes: nfcache was removed; After
-+ *             some weeks of trouble we figured out that some IMQ fields
-+ *             in skb were missing in skbuff.c - skb_clone and copy_skb_header.
-+ *             These functions are correctly patched by this new patch version.
-+ *
-+ *             Thanks for all who helped to figure out all the problems with
-+ *             2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX,
-+ *             Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully
-+ *             I didn't forget anybody). I apologize again for my lack of time.
-+ *
-+ *
-+ *             2008/06/17 - 2.6.25 - Changed imq.c to use qdisc_run() instead 
-+ *             of qdisc_restart() and moved qdisc_run() to tasklet to avoid
-+ *             recursive locking. New initialization routines to fix 'rmmod' not
-+ *             working anymore. Used code from ifb.c. (Jussi Kivilinna)
-+ *
-+ *             2008/08/06 - 2.6.26 - (JK)
-+ *              - Replaced tasklet with 'netif_schedule()'.
-+ *              - Cleaned up and added comments for imq_nf_queue().
-+ *
-+ *             2009/04/12
-+ *              - Add skb_save_cb/skb_restore_cb helper functions for backuping
-+ *                control buffer. This is needed because qdisc-layer on kernels
-+ *                2.6.27 and newer overwrite control buffer. (Jussi Kivilinna)
-+ *              - Add better locking for IMQ device. Hopefully this will solve
-+ *                SMP issues. (Jussi Kivilinna)
-+ *              - Port to 2.6.27
-+ *              - Port to 2.6.28
-+ *              - Port to 2.6.29 + fix rmmod not working
-+ *
-+ *             2009/04/20 - (Jussi Kivilinna)
-+ *              - Use netdevice feature flags to avoid extra packet handling
-+ *                by core networking layer and possibly increase performance.
-+ *
-+ *             2009/09/26 - (Jussi Kivilinna)
-+ *              - Add imq_nf_reinject_lockless to fix deadlock with
-+ *                imq_nf_queue/imq_nf_reinject.
-+ *
-+ *             2009/12/08 - (Jussi Kivilinna)
-+ *              - Port to 2.6.32
-+ *              - Add check for skb->nf_queue_entry==NULL in imq_dev_xmit()
-+ *              - Also add better error checking for skb->nf_queue_entry usage
-+ *
-+ *             2010/02/25 - (Jussi Kivilinna)
-+ *              - Port to 2.6.33
-+ *
-+ *             2010/08/12 - (Jussi Kivilinna)
-+ *              - Port to 2.6.35
-+ *
-+ *           Also, many thanks to pablo Sebastian Greco for making the initial
-+ *           patch and to those who helped the testing.
-+ *
-+ *             More info at: http://www.linuximq.net/ (Andre Correa)
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/moduleparam.h>
-+#include <linux/list.h>
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/if_arp.h>
-+#include <linux/netfilter.h>
-+#include <linux/netfilter_ipv4.h>
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      #include <linux/netfilter_ipv6.h>
-+#endif
-+#include <linux/imq.h>
-+#include <net/pkt_sched.h>
-+#include <net/netfilter/nf_queue.h>
-+
-+static nf_hookfn imq_nf_hook;
-+
-+static struct nf_hook_ops imq_ingress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv4 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP_PRI_LAST
-+#else
-+      .priority       = NF_IP_PRI_NAT_SRC - 1
-+#endif
-+};
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+static struct nf_hook_ops imq_ingress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_PRE_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      .priority       = NF_IP6_PRI_MANGLE + 1
-+#else
-+      .priority       = NF_IP6_PRI_NAT_DST + 1
-+#endif
-+};
-+
-+static struct nf_hook_ops imq_egress_ipv6 = {
-+      .hook           = imq_nf_hook,
-+      .owner          = THIS_MODULE,
-+      .pf             = PF_INET6,
-+      .hooknum        = NF_INET_POST_ROUTING,
-+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
-+      .priority       = NF_IP6_PRI_LAST
-+#else
-+      .priority       = NF_IP6_PRI_NAT_SRC - 1
-+#endif
-+};
-+#endif
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS;
-+#else
-+static unsigned int numdevs = IMQ_MAX_DEVS;
-+#endif
-+
-+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 */
-+}
-+
-+/* locking not needed when called from imq_nf_queue */
-+static void imq_nf_reinject_lockless(struct nf_queue_entry *entry,
-+                                              unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              nf_reinject(entry, verdict);
-+              return;
-+      }
-+
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+}
-+
-+static void imq_nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
-+{
-+      int status;
-+
-+      if (!entry->next_outfn) {
-+              spin_lock_bh(&imq_nf_queue_lock);
-+              nf_reinject(entry, verdict);
-+              spin_unlock_bh(&imq_nf_queue_lock);
-+              return;
-+      }
-+
-+      rcu_read_lock();
-+      local_bh_disable();
-+      status = entry->next_outfn(entry, entry->next_queuenum);
-+      local_bh_enable();
-+      if (status < 0) {
-+              nf_queue_entry_release_refs(entry);
-+              kfree_skb(entry->skb);
-+              kfree(entry);
-+      }
-+
-+      rcu_read_unlock();
-+}
-+
-+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;
-+
-+      imq_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;
-+      struct sk_buff *skb_orig, *skb, *skb_shared;
-+      struct Qdisc *q;
-+      struct netdev_queue *txq;
-+      int users, index;
-+      int retval = -EINVAL;
-+
-+      index = entry->skb->imq_flags & IMQ_F_IFMASK;
-+      if (unlikely(index > numdevs - 1)) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING
-+                             "IMQ: invalid device specified, highest is %u\n",
-+                             numdevs - 1);
-+              retval = -EINVAL;
-+              goto out;
-+      }
-+
-+      /* check for imq device by index from cache */
-+      dev = imq_devs_cache[index];
-+      if (unlikely(!dev)) {
-+              char buf[8];
-+
-+              /* get device by name and cache result */
-+              snprintf(buf, sizeof(buf), "imq%d", index);
-+              dev = dev_get_by_name(&init_net, buf);
-+              if (!dev) {
-+                      /* not found ?!*/
-+                      BUG();
-+                      retval = -ENODEV;
-+                      goto out;
-+              }
-+
-+              imq_devs_cache[index] = dev;
-+              dev_put(dev);
-+      }
-+
-+      if (unlikely(!(dev->flags & IFF_UP))) {
-+              entry->skb->imq_flags = 0;
-+              imq_nf_reinject_lockless(entry, NF_ACCEPT);
-+              retval = 0;
-+              goto out;
-+      }
-+      dev->last_rx = jiffies;
-+
-+      skb = entry->skb;
-+      skb_orig = NULL;
-+
-+      /* skb has owner? => make clone */
-+      if (unlikely(skb->destructor)) {
-+              skb_orig = skb;
-+              skb = skb_clone(skb, GFP_ATOMIC);
-+              if (!skb) {
-+                      retval = -ENOMEM;
-+                      goto out;
-+              }
-+              entry->skb = skb;
-+      }
-+
-+      skb->nf_queue_entry = entry;
-+
-+      dev->stats.rx_bytes += skb->len;
-+      dev->stats.rx_packets++;
-+
-+      txq = dev_pick_tx(dev, skb);
-+
-+      q = rcu_dereference(txq->qdisc);
-+      if (unlikely(!q->enqueue))
-+              goto packet_not_eaten_by_imq_dev;
-+
-+      spin_lock_bh(qdisc_lock(q));
-+
-+      users = atomic_read(&skb->users);
-+
-+      skb_shared = skb_get(skb); /* increase reference count by one */
-+      skb_save_cb(skb_shared); /* backup skb->cb, as qdisc layer will
-+                                      overwrite it */
-+      qdisc_enqueue_root(skb_shared, q); /* might kfree_skb */
-+
-+      if (likely(atomic_read(&skb_shared->users) == users + 1)) {
-+              kfree_skb(skb_shared); /* decrease reference count by one */
-+
-+              skb->destructor = &imq_skb_destructor;
-+
-+              /* cloned? */
-+              if (skb_orig)
-+                      kfree_skb(skb_orig); /* free original */
-+
-+              spin_unlock_bh(qdisc_lock(q));
-+
-+              /* schedule qdisc dequeue */
-+              __netif_schedule(q);
-+
-+              retval = 0;
-+              goto out;
-+      } else {
-+              skb_restore_cb(skb_shared); /* restore skb->cb */
-+              skb->nf_queue_entry = NULL;
-+              /* qdisc dropped packet and decreased skb reference count of
-+               * skb, so we don't really want to and try refree as that would
-+               * actually destroy the skb. */
-+              spin_unlock_bh(qdisc_lock(q));
-+              goto packet_not_eaten_by_imq_dev;
-+      }
-+
-+packet_not_eaten_by_imq_dev:
-+      /* cloned? restore original */
-+      if (skb_orig) {
-+              kfree_skb(skb);
-+              entry->skb = skb_orig;
-+      }
-+      retval = -1;
-+out:
-+      return retval;
-+}
-+
-+static struct nf_queue_handler nfqh = {
-+      .name  = "imq",
-+      .outfn = imq_nf_queue,
-+};
-+
-+static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff *pskb,
-+                              const struct net_device *indev,
-+                              const struct net_device *outdev,
-+                              int (*okfn)(struct sk_buff *))
-+{
-+      if (pskb->imq_flags & IMQ_F_ENQUEUE)
-+              return NF_QUEUE;
-+
-+      return NF_ACCEPT;
-+}
-+
-+static int imq_close(struct net_device *dev)
-+{
-+      netif_stop_queue(dev);
-+      return 0;
-+}
-+
-+static int imq_open(struct net_device *dev)
-+{
-+      netif_start_queue(dev);
-+      return 0;
-+}
-+
-+static const struct net_device_ops imq_netdev_ops = {
-+      .ndo_open               = imq_open,
-+      .ndo_stop               = imq_close,
-+      .ndo_start_xmit         = imq_dev_xmit,
-+      .ndo_get_stats          = imq_get_stats,
-+};
-+
-+static void imq_setup(struct net_device *dev)
-+{
-+      dev->netdev_ops         = &imq_netdev_ops;
-+      dev->type               = ARPHRD_VOID;
-+      dev->mtu                = 16000;
-+      dev->tx_queue_len       = 11000;
-+      dev->flags              = IFF_NOARP;
-+      dev->features           = NETIF_F_SG | NETIF_F_FRAGLIST |
-+                                NETIF_F_GSO | NETIF_F_HW_CSUM |
-+                                NETIF_F_HIGHDMA;
-+      dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
-+}
-+
-+static int imq_validate(struct nlattr *tb[], struct nlattr *data[])
-+{
-+      int ret = 0;
-+
-+      if (tb[IFLA_ADDRESS]) {
-+              if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
-+                      ret = -EINVAL;
-+                      goto end;
-+              }
-+              if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) {
-+                      ret = -EADDRNOTAVAIL;
-+                      goto end;
-+              }
-+      }
-+      return 0;
-+end:
-+      printk(KERN_WARNING "IMQ: imq_validate failed (%d)\n", ret);
-+      return ret;
-+}
-+
-+static struct rtnl_link_ops imq_link_ops __read_mostly = {
-+      .kind           = "imq",
-+      .priv_size      = 0,
-+      .setup          = imq_setup,
-+      .validate       = imq_validate,
-+};
-+
-+static int __init imq_init_hooks(void)
-+{
-+      int err;
-+
-+      nf_register_queue_imq_handler(&nfqh);
-+
-+      err = nf_register_hook(&imq_ingress_ipv4);
-+      if (err)
-+              goto err1;
-+
-+      err = nf_register_hook(&imq_egress_ipv4);
-+      if (err)
-+              goto err2;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      err = nf_register_hook(&imq_ingress_ipv6);
-+      if (err)
-+              goto err3;
-+
-+      err = nf_register_hook(&imq_egress_ipv6);
-+      if (err)
-+              goto err4;
-+#endif
-+
-+      return 0;
-+
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+err4:
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+err3:
-+      nf_unregister_hook(&imq_egress_ipv4);
-+#endif
-+err2:
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+err1:
-+      nf_unregister_queue_imq_handler();
-+      return err;
-+}
-+
-+static int __init imq_init_one(int index)
-+{
-+      struct net_device *dev;
-+      int ret;
-+
-+      dev = alloc_netdev(0, "imq%d", imq_setup);
-+      if (!dev)
-+              return -ENOMEM;
-+
-+      ret = dev_alloc_name(dev, dev->name);
-+      if (ret < 0)
-+              goto fail;
-+
-+      dev->rtnl_link_ops = &imq_link_ops;
-+      ret = register_netdevice(dev);
-+      if (ret < 0)
-+              goto fail;
-+
-+      return 0;
-+fail:
-+      free_netdev(dev);
-+      return ret;
-+}
-+
-+static int __init imq_init_devs(void)
-+{
-+      int err, i;
-+
-+      if (numdevs < 1 || numdevs > IMQ_MAX_DEVS) {
-+              printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n",
-+                     IMQ_MAX_DEVS);
-+              return -EINVAL;
-+      }
-+
-+      rtnl_lock();
-+      err = __rtnl_link_register(&imq_link_ops);
-+
-+      for (i = 0; i < numdevs && !err; i++)
-+              err = imq_init_one(i);
-+
-+      if (err) {
-+              __rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+      }
-+      rtnl_unlock();
-+
-+      return err;
-+}
-+
-+static int __init imq_init_module(void)
-+{
-+      int err;
-+
-+#if defined(CONFIG_IMQ_NUM_DEVS)
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS > 16);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS < 2);
-+      BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS - 1 > IMQ_F_IFMASK);
-+#endif
-+
-+      err = imq_init_devs();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_devs(net)\n");
-+              return err;
-+      }
-+
-+      err = imq_init_hooks();
-+      if (err) {
-+              printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n");
-+              rtnl_link_unregister(&imq_link_ops);
-+              memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+              return err;
-+      }
-+
-+      printk(KERN_INFO "IMQ driver loaded successfully.\n");
-+
-+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n");
-+#endif
-+#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB)
-+      printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n");
-+#else
-+      printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n");
-+#endif
-+
-+      return 0;
-+}
-+
-+static void __exit imq_unhook(void)
-+{
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      nf_unregister_hook(&imq_ingress_ipv6);
-+      nf_unregister_hook(&imq_egress_ipv6);
-+#endif
-+      nf_unregister_hook(&imq_ingress_ipv4);
-+      nf_unregister_hook(&imq_egress_ipv4);
-+
-+      nf_unregister_queue_imq_handler();
-+}
-+
-+static void __exit imq_cleanup_devs(void)
-+{
-+      rtnl_link_unregister(&imq_link_ops);
-+      memset(imq_devs_cache, 0, sizeof(imq_devs_cache));
-+}
-+
-+static void __exit imq_exit_module(void)
-+{
-+      imq_unhook();
-+      imq_cleanup_devs();
-+      printk(KERN_INFO "IMQ driver unloaded successfully.\n");
-+}
-+
-+module_init(imq_init_module);
-+module_exit(imq_exit_module);
-+
-+module_param(numdevs, int, 0);
-+MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will "
-+                      "be created)");
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See "
-+                      "http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS_RTNL_LINK("imq");
-+
---- a/drivers/net/Kconfig
-+++ b/drivers/net/Kconfig
-@@ -124,6 +124,129 @@ config EQUALIZER
-         To compile this driver as a module, choose M here: the module
-         will be called eql.  If unsure, say N.
-+config IMQ
-+      tristate "IMQ (intermediate queueing device) support"
-+      depends on NETDEVICES && NETFILTER
-+      ---help---
-+        The IMQ device(s) is used as placeholder for QoS queueing
-+        disciplines. Every packet entering/leaving the IP stack can be
-+        directed through the IMQ device where it's enqueued/dequeued to the
-+        attached qdisc. This allows you to treat network devices as classes
-+        and distribute bandwidth among them. Iptables is used to specify
-+        through which IMQ device, if any, packets travel.
-+
-+        More information at: http://www.linuximq.net/
-+
-+        To compile this driver as a module, choose M here: the module
-+        will be called imq.  If unsure, say N.
-+
-+choice
-+      prompt "IMQ behavior (PRE/POSTROUTING)"
-+      depends on IMQ
-+      default IMQ_BEHAVIOR_AB
-+      help
-+
-+              This settings defines how IMQ behaves in respect to its
-+              hooking in PREROUTING and POSTROUTING.
-+
-+              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
-+
-+              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.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   After NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  After NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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.
-+
-+              Choosing this option will make IMQ hook like this:
-+
-+              PREROUTING:   Before NAT
-+              POSTROUTING:  Before NAT
-+
-+              More information can be found at: www.linuximq.net
-+
-+              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 settings defines how many IMQ devices will be
-+              created.
-+
-+              The default value is 16.
-+
-+              More information can be found at: www.linuximq.net
-+
-+              If not sure leave the default settings alone.
-+
- config TUN
-       tristate "Universal TUN/TAP device driver support"
-       select CRC32
---- a/drivers/net/Makefile
-+++ b/drivers/net/Makefile
-@@ -173,6 +173,7 @@ obj-$(CONFIG_SLHC) += slhc.o
- obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o
- obj-$(CONFIG_DUMMY) += dummy.o
-+obj-$(CONFIG_IMQ) += imq.o
- obj-$(CONFIG_IFB) += ifb.o
- obj-$(CONFIG_MACVLAN) += macvlan.o
- obj-$(CONFIG_MACVTAP) += macvtap.o
---- /dev/null
-+++ b/include/linux/imq.h
-@@ -0,0 +1,13 @@
-+#ifndef _IMQ_H
-+#define _IMQ_H
-+
-+/* IFMASK (16 device indexes, 0 to 15) and flag(s) fit in 5 bits */
-+#define IMQ_F_BITS    5
-+
-+#define IMQ_F_IFMASK  0x0f
-+#define IMQ_F_ENQUEUE 0x10
-+
-+#define IMQ_MAX_DEVS  (IMQ_F_IFMASK + 1)
-+
-+#endif /* _IMQ_H */
-+
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1374,6 +1374,7 @@ extern int               dev_alloc_name(struct net_de
- extern int            dev_open(struct net_device *dev);
- extern int            dev_close(struct net_device *dev);
- extern void           dev_disable_lro(struct net_device *dev);
-+extern struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb);
- extern int            dev_queue_xmit(struct sk_buff *skb);
- extern int            register_netdevice(struct net_device *dev);
- extern void           unregister_netdevice_queue(struct net_device *dev,
---- /dev/null
-+++ b/include/linux/netfilter/xt_IMQ.h
-@@ -0,0 +1,9 @@
-+#ifndef _XT_IMQ_H
-+#define _XT_IMQ_H
-+
-+struct xt_imq_info {
-+      unsigned int todev;     /* target imq device */
-+};
-+
-+#endif /* _XT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv4/ipt_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IPT_IMQ_H
-+#define _IPT_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ipt_imq_info xt_imq_info
-+
-+#endif /* _IPT_IMQ_H */
-+
---- /dev/null
-+++ b/include/linux/netfilter_ipv6/ip6t_IMQ.h
-@@ -0,0 +1,10 @@
-+#ifndef _IP6T_IMQ_H
-+#define _IP6T_IMQ_H
-+
-+/* Backwards compatibility for old userspace */
-+#include <linux/netfilter/xt_IMQ.h>
-+
-+#define ip6t_imq_info xt_imq_info
-+
-+#endif /* _IP6T_IMQ_H */
-+
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -29,6 +29,9 @@
- #include <linux/rcupdate.h>
- #include <linux/dmaengine.h>
- #include <linux/hrtimer.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- /* Don't change this without changing skb_csum_unnecessary! */
- #define CHECKSUM_NONE 0
-@@ -333,6 +336,9 @@ struct sk_buff {
-        * first. This is owned by whoever has the skb queued ATM.
-        */
-       char                    cb[48] __aligned(8);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      void                    *cb_next;
-+#endif
-       unsigned long           _skb_refdst;
- #ifdef CONFIG_XFRM
-@@ -371,6 +377,9 @@ struct sk_buff {
- #ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
-       struct sk_buff          *nfct_reasm;
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      struct nf_queue_entry   *nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       struct nf_bridge_info   *nf_bridge;
- #endif
-@@ -398,6 +407,10 @@ struct sk_buff {
-       /* 0/13 bit hole */
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      __u8                    imq_flags:IMQ_F_BITS;
-+#endif
-+
- #ifdef CONFIG_NET_DMA
-       dma_cookie_t            dma_cookie;
- #endif
-@@ -484,6 +497,12 @@ static inline struct rtable *skb_rtable(
-       return (struct rtable *)skb_dst(skb);
- }
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern int skb_save_cb(struct sk_buff *skb);
-+extern int skb_restore_cb(struct sk_buff *skb);
-+#endif
-+
- extern void kfree_skb(struct sk_buff *skb);
- extern void consume_skb(struct sk_buff *skb);
- extern void          __kfree_skb(struct sk_buff *skb);
-@@ -2117,6 +2136,10 @@ static inline void __nf_copy(struct sk_b
-       dst->nfct_reasm = src->nfct_reasm;
-       nf_conntrack_get_reasm(src->nfct_reasm);
- #endif
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      dst->imq_flags = src->imq_flags;
-+      dst->nf_queue_entry = src->nf_queue_entry;
-+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
-       dst->nf_bridge  = src->nf_bridge;
-       nf_bridge_get(src->nf_bridge);
---- a/include/net/netfilter/nf_queue.h
-+++ b/include/net/netfilter/nf_queue.h
-@@ -13,6 +13,12 @@ struct nf_queue_entry {
-       struct net_device       *indev;
-       struct net_device       *outdev;
-       int                     (*okfn)(struct sk_buff *);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      int                     (*next_outfn)(struct nf_queue_entry *entry,
-+                                            unsigned int queuenum);
-+      unsigned int            next_queuenum;
-+#endif
- };
- #define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry))
-@@ -30,5 +36,11 @@ extern int nf_unregister_queue_handler(u
-                                      const struct nf_queue_handler *qh);
- extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
- extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
-+extern void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+extern void nf_register_queue_imq_handler(const struct nf_queue_handler *qh);
-+extern void nf_unregister_queue_imq_handler(void);
-+#endif
- #endif /* _NF_QUEUE_H */
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -98,6 +98,9 @@
- #include <net/net_namespace.h>
- #include <net/sock.h>
- #include <linux/rtnetlink.h>
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#include <linux/imq.h>
-+#endif
- #include <linux/proc_fs.h>
- #include <linux/seq_file.h>
- #include <linux/stat.h>
-@@ -2068,7 +2071,11 @@ int dev_hard_start_xmit(struct sk_buff *
-               if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
-                       skb_dst_drop(skb);
--              if (!list_empty(&ptype_all))
-+              if (!list_empty(&ptype_all)
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+                      && !(skb->imq_flags & IMQ_F_ENQUEUE)
-+#endif
-+                 )
-                       dev_queue_xmit_nit(skb, dev);
-               skb_orphan_try(skb);
-@@ -2230,8 +2237,7 @@ static inline int get_xps_queue(struct n
- #endif
- }
--static struct netdev_queue *dev_pick_tx(struct net_device *dev,
--                                      struct sk_buff *skb)
-+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;
-@@ -2266,6 +2272,7 @@ static struct netdev_queue *dev_pick_tx(
-       skb_set_queue_mapping(skb, queue_index);
-       return netdev_get_tx_queue(dev, queue_index);
- }
-+EXPORT_SYMBOL(dev_pick_tx);
- static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
-                                struct net_device *dev,
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -72,6 +72,9 @@
- static struct kmem_cache *skbuff_head_cache __read_mostly;
- static struct kmem_cache *skbuff_fclone_cache __read_mostly;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static struct kmem_cache *skbuff_cb_store_cache __read_mostly;
-+#endif
- static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
-                                 struct pipe_buffer *buf)
-@@ -91,6 +94,83 @@ static int sock_pipe_buf_steal(struct pi
-       return 1;
- }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+/* Control buffer save/restore for IMQ devices */
-+struct skb_cb_table {
-+      void                    *cb_next;
-+      atomic_t                refcnt;
-+      char                    cb[48];
-+};
-+
-+static DEFINE_SPINLOCK(skb_cb_store_lock);
-+
-+int skb_save_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      next = kmem_cache_alloc(skbuff_cb_store_cache, GFP_ATOMIC);
-+      if (!next)
-+              return -ENOMEM;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(next->cb, skb->cb, sizeof(skb->cb));
-+      next->cb_next = skb->cb_next;
-+
-+      atomic_set(&next->refcnt, 1);
-+
-+      skb->cb_next = next;
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_save_cb);
-+
-+int skb_restore_cb(struct sk_buff *skb)
-+{
-+      struct skb_cb_table *next;
-+
-+      if (!skb->cb_next)
-+              return 0;
-+
-+      next = skb->cb_next;
-+
-+      BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb));
-+
-+      memcpy(skb->cb, next->cb, sizeof(skb->cb));
-+      skb->cb_next = next->cb_next;
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      if (atomic_dec_and_test(&next->refcnt)) {
-+              kmem_cache_free(skbuff_cb_store_cache, next);
-+      }
-+
-+      spin_unlock(&skb_cb_store_lock);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(skb_restore_cb);
-+
-+static void skb_copy_stored_cb(struct sk_buff *new, const struct sk_buff *__old)
-+{
-+      struct skb_cb_table *next;
-+      struct sk_buff *old;
-+
-+      if (!__old->cb_next) {
-+              new->cb_next = NULL;
-+              return;
-+      }
-+
-+      spin_lock(&skb_cb_store_lock);
-+
-+      old = (struct sk_buff *)__old;
-+
-+      next = old->cb_next;
-+      atomic_inc(&next->refcnt);
-+      new->cb_next = next;
-+
-+      spin_unlock(&skb_cb_store_lock);
-+}
-+#endif
- /* Pipe buffer operations for a socket. */
- static const struct pipe_buf_operations sock_pipe_buf_ops = {
-@@ -378,6 +458,26 @@ static void skb_release_head_state(struc
-               WARN_ON(in_irq());
-               skb->destructor(skb);
-       }
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      /* This should not happen. When it does, avoid memleak by restoring
-+      the chain of cb-backups. */
-+      while(skb->cb_next != NULL) {
-+              if (net_ratelimit())
-+                      printk(KERN_WARNING "IMQ: kfree_skb: skb->cb_next: "
-+                              "%08x\n", (unsigned int)skb->cb_next);
-+
-+              skb_restore_cb(skb);
-+      }
-+      /* This should not happen either, nf_queue_entry is nullified in
-+       * imq_dev_xmit(). If we have non-NULL nf_queue_entry then we are
-+       * leaking entry pointers, maybe memory. We don't know if this is
-+       * pointer to already freed memory, or should this be freed.
-+       * If this happens we need to add refcounting, etc for nf_queue_entry.
-+       */
-+      if (skb->nf_queue_entry && net_ratelimit())
-+              printk(KERN_WARNING
-+                              "IMQ: kfree_skb: skb->nf_queue_entry != NULL");
-+#endif
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-       nf_conntrack_put(skb->nfct);
- #endif
-@@ -516,6 +616,9 @@ static void __copy_skb_header(struct sk_
-       new->sp                 = secpath_get(old->sp);
- #endif
-       memcpy(new->cb, old->cb, sizeof(old->cb));
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skb_copy_stored_cb(new, old);
-+#endif
-       new->csum               = old->csum;
-       new->local_df           = old->local_df;
-       new->pkt_type           = old->pkt_type;
-@@ -2779,6 +2882,13 @@ void __init skb_init(void)
-                                               0,
-                                               SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-                                               NULL);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      skbuff_cb_store_cache = kmem_cache_create("skbuff_cb_store_cache",
-+                                                sizeof(struct skb_cb_table),
-+                                                0,
-+                                                SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-+                                                NULL);
-+#endif
- }
- /**
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -455,6 +455,18 @@ config NETFILTER_XT_TARGET_LED
-         For more information on the LEDs available on your system, see
-         Documentation/leds-class.txt
-+config NETFILTER_XT_TARGET_IMQ
-+        tristate '"IMQ" target support'
-+      depends on NETFILTER_XTABLES
-+      depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+      select IMQ
-+      default m if NETFILTER_ADVANCED=n
-+        help
-+          This option adds a `IMQ' target which is used to specify if and
-+          to which imq device packets should get enqueued/dequeued.
-+
-+          To compile it as a module, choose M here.  If unsure, say N.
-+
- config NETFILTER_XT_TARGET_MARK
-       tristate '"MARK" target support'
-       depends on NETFILTER_ADVANCED
---- a/net/netfilter/Makefile
-+++ b/net/netfilter/Makefile
-@@ -51,6 +51,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSEC
- obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
- obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
-+obj-$(CONFIG_NETFILTER_XT_TARGET_IMQ) += xt_IMQ.o
- 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
---- a/net/netfilter/nf_queue.c
-+++ b/net/netfilter/nf_queue.c
-@@ -22,6 +22,26 @@ static const struct nf_queue_handler __r
- static DEFINE_MUTEX(queue_handler_mutex);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+static const struct nf_queue_handler *queue_imq_handler;
-+
-+void nf_register_queue_imq_handler(const struct nf_queue_handler *qh)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, qh);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_register_queue_imq_handler);
-+
-+void nf_unregister_queue_imq_handler(void)
-+{
-+      mutex_lock(&queue_handler_mutex);
-+      rcu_assign_pointer(queue_imq_handler, NULL);
-+      mutex_unlock(&queue_handler_mutex);
-+}
-+EXPORT_SYMBOL(nf_unregister_queue_imq_handler);
-+#endif
-+
- /* return EBUSY when somebody else is registered, return EEXIST if the
-  * same handler is registered, return 0 in case of success. */
- int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
-@@ -82,7 +102,7 @@ void nf_unregister_queue_handlers(const
- }
- EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);
--static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
-+void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
- {
-       /* Release those devices we held, or Alexey will kill me. */
-       if (entry->indev)
-@@ -102,6 +122,7 @@ static void nf_queue_entry_release_refs(
-       /* Drop reference to owner of hook which queued us. */
-       module_put(entry->elem->owner);
- }
-+EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
- /*
-  * Any packet that leaves via this function must come back
-@@ -123,12 +144,26 @@ static int __nf_queue(struct sk_buff *sk
- #endif
-       const struct nf_afinfo *afinfo;
-       const struct nf_queue_handler *qh;
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      const struct nf_queue_handler *qih = NULL;
-+#endif
-       /* QUEUE == DROP if noone is waiting, to be safe. */
-       rcu_read_lock();
-       qh = rcu_dereference(queue_handler[pf]);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+      if (pf == PF_INET || pf == PF_INET6)
-+#else
-+      if (pf == PF_INET)
-+#endif
-+              qih = rcu_dereference(queue_imq_handler);
-+
-+      if (!qh && !qih)
-+#else /* !IMQ */
-       if (!qh)
-+#endif
-               goto err_unlock;
-       afinfo = nf_get_afinfo(pf);
-@@ -147,6 +182,10 @@ static int __nf_queue(struct sk_buff *sk
-               .indev  = indev,
-               .outdev = outdev,
-               .okfn   = okfn,
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+              .next_outfn = qh ? qh->outfn : NULL,
-+              .next_queuenum = queuenum,
-+#endif
-       };
-       /* If it's going away, ignore hook. */
-@@ -173,8 +212,19 @@ static int __nf_queue(struct sk_buff *sk
- #endif
-       skb_dst_force(skb);
-       afinfo->saveroute(skb, entry);
-+
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+      if (qih) {
-+              status = qih->outfn(entry, queuenum);
-+              goto imq_skip_queue;
-+      }
-+#endif
-+
-       status = qh->outfn(entry, queuenum);
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+imq_skip_queue:
-+#endif
-       rcu_read_unlock();
-       if (status < 0) {
---- /dev/null
-+++ b/net/netfilter/xt_IMQ.c
-@@ -0,0 +1,73 @@
-+/*
-+ * This target marks packets to be enqueued to an imq device
-+ */
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter/x_tables.h>
-+#include <linux/netfilter/xt_IMQ.h>
-+#include <linux/imq.h>
-+
-+static unsigned int imq_target(struct sk_buff *pskb,
-+                              const struct xt_action_param *par)
-+{
-+      const struct xt_imq_info *mr = par->targinfo;
-+
-+      pskb->imq_flags = (mr->todev & IMQ_F_IFMASK) | IMQ_F_ENQUEUE;
-+
-+      return XT_CONTINUE;
-+}
-+
-+static int imq_checkentry(const struct xt_tgchk_param *par)
-+{
-+      struct xt_imq_info *mr = par->targinfo;
-+
-+      if (mr->todev > IMQ_MAX_DEVS - 1) {
-+              printk(KERN_WARNING
-+                     "IMQ: invalid device specified, highest is %u\n",
-+                     IMQ_MAX_DEVS - 1);
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static struct xt_target xt_imq_reg[] __read_mostly = {
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+      {
-+              .name           = "IMQ",
-+              .family         = AF_INET6,
-+              .checkentry     = imq_checkentry,
-+              .target         = imq_target,
-+              .targetsize     = sizeof(struct xt_imq_info),
-+              .table          = "mangle",
-+              .me             = THIS_MODULE
-+      },
-+};
-+
-+static int __init imq_init(void)
-+{
-+      return xt_register_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+static void __exit imq_fini(void)
-+{
-+      xt_unregister_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg));
-+}
-+
-+module_init(imq_init);
-+module_exit(imq_fini);
-+
-+MODULE_AUTHOR("http://www.linuximq.net");
-+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("ipt_IMQ");
-+MODULE_ALIAS("ip6t_IMQ");
-+
This page took 0.482405 seconds and 4 git commands to generate.