Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Feb 2008 10:48:45 +0000 (21:48 +1100)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Feb 2008 10:48:45 +0000 (21:48 +1100)
* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
  block: kill swap_io_context()
  as-iosched: fix inconsistent ioc->lock context
  ide-cd: fix leftover data BUG
  block: make elevator lib checkpatch compliant
  cfq-iosched: make checkpatch compliant
  block: make core bits checkpatch compliant
  block: new end request handling interface should take unsigned byte counts
  unexport add_disk_randomness
  block/sunvdc.c:print_version() must be __devinit
  splice: always updated atime in direct splice

316 files changed:
Documentation/DocBook/rapidio.tmpl
Documentation/filesystems/proc.txt
Documentation/networking/xfrm_proc.txt
MAINTAINERS
arch/m68knommu/Kconfig
arch/m68knommu/Makefile
arch/m68knommu/kernel/time.c
arch/m68knommu/platform/5206/config.c
arch/m68knommu/platform/5206e/config.c
arch/m68knommu/platform/520x/config.c
arch/m68knommu/platform/523x/config.c
arch/m68knommu/platform/5249/config.c
arch/m68knommu/platform/5272/config.c
arch/m68knommu/platform/527x/config.c
arch/m68knommu/platform/528x/config.c
arch/m68knommu/platform/5307/Makefile
arch/m68knommu/platform/5307/config.c
arch/m68knommu/platform/5307/entry.S [deleted file]
arch/m68knommu/platform/5307/head.S [deleted file]
arch/m68knommu/platform/5307/pit.c [deleted file]
arch/m68knommu/platform/5307/timers.c [deleted file]
arch/m68knommu/platform/5307/vectors.c [deleted file]
arch/m68knommu/platform/532x/config.c
arch/m68knommu/platform/5407/config.c
arch/m68knommu/platform/68328/timers.c
arch/m68knommu/platform/68360/config.c
arch/m68knommu/platform/coldfire/Makefile [new file with mode: 0644]
arch/m68knommu/platform/coldfire/dma.c [new file with mode: 0644]
arch/m68knommu/platform/coldfire/entry.S [new file with mode: 0644]
arch/m68knommu/platform/coldfire/head.S [new file with mode: 0644]
arch/m68knommu/platform/coldfire/pit.c [new file with mode: 0644]
arch/m68knommu/platform/coldfire/timers.c [new file with mode: 0644]
arch/m68knommu/platform/coldfire/vectors.c [new file with mode: 0644]
arch/powerpc/platforms/pasemi/iommu.c
arch/sparc/lib/rwsem.S
arch/sparc64/lib/GENbzero.S
arch/sparc64/lib/NGbzero.S
arch/sparc64/lib/rwsem.S
arch/x86/Makefile
drivers/net/bnx2.c
drivers/net/bnx2.h
drivers/net/bnx2_fw.h
drivers/net/bnx2_fw2.h
drivers/net/dl2k.h
drivers/net/macvlan.c
drivers/net/usb/asix.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/cdc_subset.c
drivers/net/usb/dm9601.c
drivers/net/usb/gl620a.c
drivers/net/usb/mcs7830.c
drivers/net/usb/net1080.c
drivers/net/usb/plusb.c
drivers/net/usb/rndis_host.c
drivers/net/usb/usbnet.c
drivers/net/usb/usbnet.h [deleted file]
drivers/net/usb/zaurus.c
drivers/net/wireless/Kconfig
drivers/net/wireless/Makefile
drivers/net/wireless/ath5k/base.c
drivers/net/wireless/ath5k/debug.c
drivers/net/wireless/ath5k/debug.h
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43/xmit.h
drivers/net/wireless/b43legacy/b43legacy.h
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/b43legacy/phy.c
drivers/net/wireless/b43legacy/pio.c
drivers/net/wireless/b43legacy/radio.c
drivers/net/wireless/hostap/hostap_80211.h
drivers/net/wireless/hostap/hostap_cs.c
drivers/net/wireless/iwlwifi/iwl-3945-hw.h
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-3945.h
drivers/net/wireless/iwlwifi/iwl-4965-hw.h
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-4965.h
drivers/net/wireless/iwlwifi/iwl-helpers.h
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwlwifi/iwl4965-base.c
drivers/net/wireless/libertas/assoc.c
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/if_cs.c
drivers/net/wireless/rndis_wlan.c [new file with mode: 0644]
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rtl8180_dev.c
drivers/serial/68328serial.c
drivers/serial/Kconfig
drivers/serial/Makefile
drivers/serial/mcf.c
include/asm-alpha/socket.h
include/asm-arm/socket.h
include/asm-avr32/socket.h
include/asm-blackfin/socket.h
include/asm-cris/socket.h
include/asm-frv/socket.h
include/asm-h8300/socket.h
include/asm-ia64/socket.h
include/asm-m32r/socket.h
include/asm-m68k/socket.h
include/asm-m68knommu/cacheflush.h
include/asm-m68knommu/mcfcache.h
include/asm-m68knommu/mcfuart.h
include/asm-mips/socket.h
include/asm-parisc/socket.h
include/asm-powerpc/socket.h
include/asm-s390/socket.h
include/asm-sh/socket.h
include/asm-sparc/socket.h
include/asm-sparc64/socket.h
include/asm-v850/socket.h
include/asm-x86/socket.h
include/asm-xtensa/socket.h
include/linux/inetdevice.h
include/linux/input.h
include/linux/ipv6.h
include/linux/netdevice.h
include/linux/netfilter/nf_conntrack_pptp.h
include/linux/netfilter/nf_conntrack_sip.h
include/linux/netfilter/x_tables.h
include/linux/netfilter/xt_conntrack.h
include/linux/netfilter/xt_hashlimit.h
include/linux/netfilter/xt_owner.h
include/linux/netfilter_arp/arp_tables.h
include/linux/netfilter_ipv4/ip_tables.h
include/linux/netfilter_ipv6/ip6_tables.h
include/linux/netlink.h
include/linux/pfkeyv2.h
include/linux/pkt_cls.h
include/linux/pkt_sched.h
include/linux/rfkill.h
include/linux/skbuff.h
include/linux/snmp.h
include/linux/sysctl.h
include/linux/types.h
include/linux/usb/rndis_host.h [new file with mode: 0644]
include/linux/usb/usbnet.h [new file with mode: 0644]
include/linux/xfrm.h
include/net/arp.h
include/net/esp.h
include/net/inet6_hashtables.h
include/net/inet_hashtables.h
include/net/ip_fib.h
include/net/net_namespace.h
include/net/netfilter/nf_conntrack.h
include/net/netfilter/nf_conntrack_core.h
include/net/netfilter/nf_conntrack_expect.h
include/net/netfilter/nf_conntrack_helper.h
include/net/netfilter/nf_conntrack_l3proto.h
include/net/netfilter/nf_conntrack_l4proto.h
include/net/netfilter/nf_conntrack_tuple.h
include/net/netfilter/nf_log.h
include/net/netns/ipv4.h
include/net/netns/ipv6.h
include/net/netns/x_tables.h [new file with mode: 0644]
include/net/pkt_cls.h
include/net/raw.h
include/net/route.h
include/net/sock.h
include/net/xfrm.h
kernel/audit.c
net/802/tr.c
net/8021q/vlan_dev.c
net/9p/conv.c
net/ax25/af_ax25.c
net/bluetooth/hci_sysfs.c
net/bridge/br_netfilter.c
net/bridge/netfilter/ebt_802_3.c
net/bridge/netfilter/ebt_among.c
net/bridge/netfilter/ebt_arp.c
net/bridge/netfilter/ebt_arpreply.c
net/bridge/netfilter/ebt_dnat.c
net/bridge/netfilter/ebt_ip.c
net/bridge/netfilter/ebt_limit.c
net/bridge/netfilter/ebt_log.c
net/bridge/netfilter/ebt_mark.c
net/bridge/netfilter/ebt_mark_m.c
net/bridge/netfilter/ebt_pkttype.c
net/bridge/netfilter/ebt_redirect.c
net/bridge/netfilter/ebt_snat.c
net/bridge/netfilter/ebt_stp.c
net/bridge/netfilter/ebt_ulog.c
net/bridge/netfilter/ebt_vlan.c
net/core/dev.c
net/core/dev_mcast.c
net/core/pktgen.c
net/core/sock.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/ipv4/Kconfig
net/ipv4/ah4.c
net/ipv4/arp.c
net/ipv4/devinet.c
net/ipv4/esp4.c
net/ipv4/fib_frontend.c
net/ipv4/fib_hash.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_diag.c
net/ipv4/inet_hashtables.c
net/ipv4/ip_output.c
net/ipv4/ipcomp.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/arptable_filter.c
net/ipv4/netfilter/ip_queue.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/netfilter/ipt_recent.c
net/ipv4/netfilter/iptable_filter.c
net/ipv4/netfilter/iptable_mangle.c
net/ipv4/netfilter/iptable_raw.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
net/ipv4/netfilter/nf_conntrack_proto_icmp.c
net/ipv4/netfilter/nf_nat_core.c
net/ipv4/netfilter/nf_nat_h323.c
net/ipv4/netfilter/nf_nat_helper.c
net/ipv4/netfilter/nf_nat_pptp.c
net/ipv4/netfilter/nf_nat_proto_gre.c
net/ipv4/netfilter/nf_nat_proto_icmp.c
net/ipv4/netfilter/nf_nat_proto_tcp.c
net/ipv4/netfilter/nf_nat_proto_udp.c
net/ipv4/netfilter/nf_nat_rule.c
net/ipv4/netfilter/nf_nat_sip.c
net/ipv4/netfilter/nf_nat_snmp_basic.c
net/ipv4/netfilter/nf_nat_tftp.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv4/xfrm4_policy.c
net/ipv4/xfrm4_tunnel.c
net/ipv6/Kconfig
net/ipv6/ah6.c
net/ipv6/esp6.c
net/ipv6/inet6_hashtables.c
net/ipv6/ip6_output.c
net/ipv6/ipcomp6.c
net/ipv6/mip6.c
net/ipv6/netfilter/ip6_queue.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6table_filter.c
net/ipv6/netfilter/ip6table_mangle.c
net/ipv6/netfilter/ip6table_raw.c
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/raw.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/ipv6/xfrm6_policy.c
net/ipv6/xfrm6_tunnel.c
net/mac80211/rx.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_expect.c
net/netfilter/nf_conntrack_h323_asn1.c
net/netfilter/nf_conntrack_h323_main.c
net/netfilter/nf_conntrack_h323_types.c
net/netfilter/nf_conntrack_helper.c
net/netfilter/nf_conntrack_irc.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_pptp.c
net/netfilter/nf_conntrack_proto_generic.c
net/netfilter/nf_conntrack_proto_gre.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_conntrack_proto_udp.c
net/netfilter/nf_conntrack_proto_udplite.c
net/netfilter/nf_conntrack_sane.c
net/netfilter/nf_conntrack_sip.c
net/netfilter/nf_conntrack_standalone.c
net/netfilter/nf_conntrack_tftp.c
net/netfilter/nf_log.c
net/netfilter/nfnetlink_log.c
net/netfilter/nfnetlink_queue.c
net/netfilter/x_tables.c
net/netfilter/xt_TCPMSS.c
net/netfilter/xt_connlimit.c
net/netfilter/xt_conntrack.c
net/netfilter/xt_hashlimit.c
net/netfilter/xt_iprange.c
net/netfilter/xt_owner.c
net/netlink/af_netlink.c
net/rfkill/rfkill-input.c
net/rfkill/rfkill.c
net/rxrpc/ar-call.c
net/rxrpc/ar-internal.h
net/rxrpc/ar-proc.c
net/sched/Kconfig
net/sched/Makefile
net/sched/cls_api.c
net/sched/cls_basic.c
net/sched/cls_flow.c [new file with mode: 0644]
net/sched/cls_fw.c
net/sched/cls_route.c
net/sched/cls_tcindex.c
net/sched/cls_u32.c
net/sched/sch_ingress.c
net/sched/sch_sfq.c
net/sched/sch_teql.c
net/sctp/sm_make_chunk.c
net/x25/af_x25.c
net/xfrm/xfrm_algo.c
net/xfrm/xfrm_input.c
net/xfrm/xfrm_output.c
net/xfrm/xfrm_proc.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
security/selinux/ss/services.c

index 1becf27ba27ea60e9b1dc75dac3be7caccdc5e66..a8b88c47e80951e0a93b61d831bd9a198fe5f07f 100644 (file)
 !Idrivers/rapidio/rio-sysfs.c
      </sect1>
      <sect1><title>PPC32 support</title>
-!Iarch/ppc/kernel/rio.c
-!Earch/ppc/syslib/ppc85xx_rio.c
-!Iarch/ppc/syslib/ppc85xx_rio.c
+!Iarch/powerpc/kernel/rio.c
+!Earch/powerpc/sysdev/fsl_rio.c
+!Iarch/powerpc/sysdev/fsl_rio.c
      </sect1>
   </chapter>
 
index 4413a2d4646fc4fd5305cb60e06a57bd5243bd16..11fe51c036bf36a3fc243b6620fd098929966e9a 100644 (file)
@@ -1919,11 +1919,6 @@ max_size
 Maximum size  of  the routing cache. Old entries will be purged once the cache
 reached has this size.
 
-max_delay, min_delay
---------------------
-
-Delays for flushing the routing cache.
-
 redirect_load, redirect_number
 ------------------------------
 
index 53c1a58b02f1b3b5cf4010a693ba2cef496fc010..d0d8bafa9016b7f435ac5529ca6d6e1c736b42dc 100644 (file)
@@ -26,8 +26,9 @@ XfrmInStateProtoError:
        e.g. SA key is wrong
 XfrmInStateModeError:
        Transformation mode specific error
-XfrmInSeqOutOfWindow:
-       Sequence out of window
+XfrmInStateSeqError:
+       Sequence error
+       i.e. Sequence number is out of window
 XfrmInStateExpired:
        State is expired
 XfrmInStateMismatch:
@@ -60,6 +61,9 @@ XfrmOutStateProtoError:
        Transformation protocol specific error
 XfrmOutStateModeError:
        Transformation mode specific error
+XfrmOutStateSeqError:
+       Sequence error
+       i.e. Sequence number overflow
 XfrmOutStateExpired:
        State is expired
 XfrmOutPolBlock:
index 093cf04e9ca6290822a0f4efdc137ee087450723..91082e60d2897df6675edad92af8105a2979a19a 100644 (file)
@@ -4085,6 +4085,12 @@ L:       video4linux-list@redhat.com
 W:     http://www.linux-projects.org
 S:     Maintained
 
+USB WIRELESS RNDIS DRIVER (rndis_wlan)
+P:     Jussi Kivilinna
+M:     jussi.kivilinna@mbnet.fi
+L:     linux-wireless@vger.kernel.org
+S:     Maintained
+
 USB ZC0301 DRIVER
 P:     Luca Risolia
 M:     luca.risolia@studio.unibo.it
index f4b582cbb5678a541e9a972ef8f31d27399d69a9..bd9213749ac27e228e6ac2dc07603bca7ef2f70a 100644 (file)
@@ -53,6 +53,10 @@ config GENERIC_CALIBRATE_DELAY
        bool
        default y
 
+config GENERIC_TIME
+       bool
+       default y
+
 config TIME_LOW_RES
        bool
        default y
index 30aa2553693d116702684f904a262016b1472ca4..e0b5f62e395caff7ee475a660482e2cdd8b24883 100644 (file)
@@ -61,17 +61,17 @@ MODEL := $(model-y)
 # for the selected cpu. ONLY need to define this for the non-base member
 # of the family.
 #
-cpuclass-$(CONFIG_M5206)       := 5307
-cpuclass-$(CONFIG_M5206e)      := 5307
-cpuclass-$(CONFIG_M520x)       := 5307
-cpuclass-$(CONFIG_M523x)       := 5307
-cpuclass-$(CONFIG_M5249)       := 5307
-cpuclass-$(CONFIG_M527x)       := 5307
-cpuclass-$(CONFIG_M5272)       := 5307
-cpuclass-$(CONFIG_M528x)       := 5307
-cpuclass-$(CONFIG_M5307)       := 5307
-cpuclass-$(CONFIG_M532x)       := 5307
-cpuclass-$(CONFIG_M5407)       := 5307
+cpuclass-$(CONFIG_M5206)       := coldfire
+cpuclass-$(CONFIG_M5206e)      := coldfire
+cpuclass-$(CONFIG_M520x)       := coldfire
+cpuclass-$(CONFIG_M523x)       := coldfire
+cpuclass-$(CONFIG_M5249)       := coldfire
+cpuclass-$(CONFIG_M527x)       := coldfire
+cpuclass-$(CONFIG_M5272)       := coldfire
+cpuclass-$(CONFIG_M528x)       := coldfire
+cpuclass-$(CONFIG_M5307)       := coldfire
+cpuclass-$(CONFIG_M532x)       := coldfire
+cpuclass-$(CONFIG_M5407)       := coldfire
 cpuclass-$(CONFIG_M68328)      := 68328
 cpuclass-$(CONFIG_M68EZ328)    := 68328
 cpuclass-$(CONFIG_M68VZ328)    := 68328
index 77e5375a2dd505ecc90e0dee224ed953e043ab56..89cdbcaeb45f00e5a1b7e44a78d4e9389853b4dc 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/timex.h>
 
 #include <asm/machdep.h>
-#include <asm/io.h>
 #include <asm/irq_regs.h>
 
 #define        TICK_SIZE (tick_nsec / 1000)
@@ -66,29 +65,6 @@ irqreturn_t arch_timer_interrupt(int irq, void *dummy)
          else
            last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
        }
-#ifdef CONFIG_HEARTBEAT
-       /* use power LED as a heartbeat instead -- much more useful
-          for debugging -- based on the version for PReP by Cort */
-       /* acts like an actual heart beat -- ie thump-thump-pause... */
-       if (mach_heartbeat) {
-           static unsigned cnt = 0, period = 0, dist = 0;
-
-           if (cnt == 0 || cnt == dist)
-               mach_heartbeat( 1 );
-           else if (cnt == 7 || cnt == dist+7)
-               mach_heartbeat( 0 );
-
-           if (++cnt > period) {
-               cnt = 0;
-               /* The hyperbolic function below modifies the heartbeat period
-                * length in dependency of the current (5min) load. It goes
-                * through the points f(0)=126, f(1)=86, f(5)=51,
-                * f(inf)->30. */
-               period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
-               dist = period / 4;
-           }
-       }
-#endif /* CONFIG_HEARTBEAT */
 
        write_sequnlock(&xtime_lock);
        return(IRQ_HANDLED);
@@ -112,60 +88,3 @@ void time_init(void)
        hw_timer_init();
 }
 
-/*
- * This version of gettimeofday has near microsecond resolution.
- */
-void do_gettimeofday(struct timeval *tv)
-{
-       unsigned long flags;
-       unsigned long seq;
-       unsigned long usec, sec;
-
-       do {
-               seq = read_seqbegin_irqsave(&xtime_lock, flags);
-               usec = hw_timer_offset();
-               sec = xtime.tv_sec;
-               usec += (xtime.tv_nsec / 1000);
-       } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
-       while (usec >= 1000000) {
-               usec -= 1000000;
-               sec++;
-       }
-
-       tv->tv_sec = sec;
-       tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
-       time_t wtm_sec, sec = tv->tv_sec;
-       long wtm_nsec, nsec = tv->tv_nsec;
-
-       if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-               return -EINVAL;
-
-       write_seqlock_irq(&xtime_lock);
-       /*
-        * This is revolting. We need to set the xtime.tv_usec
-        * correctly. However, the value in this location is
-        * is value at the last tick.
-        * Discover what correction gettimeofday
-        * would have done, and then undo it!
-        */
-       nsec -= (hw_timer_offset() * 1000);
-
-       wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
-       wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
-       set_normalized_timespec(&xtime, sec, nsec);
-       set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
-       ntp_clear();
-       write_sequnlock_irq(&xtime_lock);
-       clock_was_set();
-       return 0;
-}
-EXPORT_SYMBOL(do_settimeofday);
index b3c4dd4cc13546146be2726de69a53f747ba83f2..53a5920c2b71ad68185ae2fe5ef08c6647c5af86 100644 (file)
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/dma.h>
+#include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
-#include <asm/mcftimer.h>
 #include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
+#include <asm/mcfuart.h>
 
 /***************************************************************************/
 
@@ -26,15 +25,51 @@ void coldfire_reset(void);
 
 /***************************************************************************/
 
-/*
- *     DMA channel base address table.
- */
-unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
-        MCF_MBAR + MCFDMA_BASE0,
-        MCF_MBAR + MCFDMA_BASE1,
+static struct mcf_platform_uart m5206_uart_platform[] = {
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE1,
+               .irq            = 73,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE2,
+               .irq            = 74,
+       },
+       { },
+};
+
+static struct platform_device m5206_uart = {
+       .name                   = "mcfuart",
+       .id                     = 0,
+       .dev.platform_data      = m5206_uart_platform,
+};
+
+static struct platform_device *m5206_devices[] __initdata = {
+       &m5206_uart,
 };
 
-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+/***************************************************************************/
+
+static void __init m5206_uart_init_line(int line, int irq)
+{
+       if (line == 0) {
+               writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+               writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
+       } else if (line == 1) {
+               writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+               writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
+       }
+}
+
+static void __init m5206_uarts_init(void)
+{
+       const int nrlines = ARRAY_SIZE(m5206_uart_platform);
+       int line;
+
+       for (line = 0; (line < nrlines); line++)
+               m5206_uart_init_line(line, m5206_uart_platform[line].irq);
+}
 
 /***************************************************************************/
 
@@ -74,24 +109,21 @@ void mcf_settimericr(unsigned int timer, unsigned int level)
 
 /***************************************************************************/
 
-int mcf_timerirqpending(int timer)
+void __init config_BSP(char *commandp, int size)
 {
-       unsigned int imr = 0;
-
-       switch (timer) {
-       case 1:  imr = MCFSIM_IMR_TIMER1; break;
-       case 2:  imr = MCFSIM_IMR_TIMER2; break;
-       default: break;
-       }
-       return (mcf_getipr() & imr);
+       mcf_setimr(MCFSIM_IMR_MASKALL);
+       mach_reset = coldfire_reset;
 }
 
 /***************************************************************************/
 
-void config_BSP(char *commandp, int size)
+static int __init init_BSP(void)
 {
-       mcf_setimr(MCFSIM_IMR_MASKALL);
-       mach_reset = coldfire_reset;
+       m5206_uarts_init();
+       platform_add_devices(m5206_devices, ARRAY_SIZE(m5206_devices));
+       return 0;
 }
 
+arch_initcall(init_BSP);
+
 /***************************************************************************/
index f84a4aea8cb68669f62e1119ced59f7b6be27130..a6692e958f6b93265380bfe7631b57d2fae5fe01 100644 (file)
@@ -10,8 +10,9 @@
 
 #include <linux/kernel.h>
 #include <linux/param.h>
+#include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/dma.h>
+#include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
@@ -23,15 +24,51 @@ void coldfire_reset(void);
 
 /***************************************************************************/
 
-/*
- *     DMA channel base address table.
- */
-unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
-        MCF_MBAR + MCFDMA_BASE0,
-        MCF_MBAR + MCFDMA_BASE1,
+static struct mcf_platform_uart m5206e_uart_platform[] = {
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE1,
+               .irq            = 73,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE2,
+               .irq            = 74,
+       },
+       { },
+};
+
+static struct platform_device m5206e_uart = {
+       .name                   = "mcfuart",
+       .id                     = 0,
+       .dev.platform_data      = m5206e_uart_platform,
 };
 
-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+static struct platform_device *m5206e_devices[] __initdata = {
+       &m5206e_uart,
+};
+
+/***************************************************************************/
+
+static void __init m5206_uart_init_line(int line, int irq)
+{
+       if (line == 0) {
+               writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+               writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
+       } else if (line == 1) {
+               writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+               writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
+       }
+}
+
+static void __init m5206e_uarts_init(void)
+{
+       const int nrlines = ARRAY_SIZE(m5206e_uart_platform);
+       int line;
+
+       for (line = 0; (line < nrlines); line++)
+               m5206e_uart_init_line(line, m5206e_uart_platform[line].irq);
+}
 
 /***************************************************************************/
 
@@ -71,21 +108,7 @@ void mcf_settimericr(unsigned int timer, unsigned int level)
 
 /***************************************************************************/
 
-int mcf_timerirqpending(int timer)
-{
-       unsigned int imr = 0;
-
-       switch (timer) {
-       case 1:  imr = MCFSIM_IMR_TIMER1; break;
-       case 2:  imr = MCFSIM_IMR_TIMER2; break;
-       default: break;
-       }
-       return (mcf_getipr() & imr);
-}
-
-/***************************************************************************/
-
-void config_BSP(char *commandp, int size)
+void __init config_BSP(char *commandp, int size)
 {
        mcf_setimr(MCFSIM_IMR_MASKALL);
 
@@ -99,3 +122,14 @@ void config_BSP(char *commandp, int size)
 }
 
 /***************************************************************************/
+
+static int __init init_BSP(void)
+{
+       m5206e_uarts_init();
+       platform_add_devices(m5206e_devices, ARRAY_SIZE(m5206e_devices));
+       return 0;
+}
+
+arch_initcall(init_BSP);
+
+/***************************************************************************/
index 6edbd41261cc0253fd48f19646614f632543d335..06d887cdcbfbcc2c8aaf441a5f2e5a1e8c5bcd1f 100644 (file)
@@ -5,7 +5,7 @@
  *
  *  Copyright (C) 2005,      Freescale (www.freescale.com)
  *  Copyright (C) 2005,      Intec Automation (mike@steroidmicros.com)
- *  Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com)
  *  Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
  */
 
 
 #include <linux/kernel.h>
 #include <linux/param.h>
+#include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <asm/machdep.h>
-#include <asm/dma.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfuart.h>
 
 /***************************************************************************/
 
-/*
- *     DMA channel base address table.
- */
-unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+void coldfire_reset(void);
 
 /***************************************************************************/
 
-void coldfire_reset(void);
+static struct mcf_platform_uart m520x_uart_platform[] = {
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE1,
+               .irq            = MCFINT_VECBASE + MCFINT_UART0,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE2,
+               .irq            = MCFINT_VECBASE + MCFINT_UART1,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE3,
+               .irq            = MCFINT_VECBASE + MCFINT_UART2,
+       },
+       { },
+};
+
+static struct platform_device m520x_uart = {
+       .name                   = "mcfuart",
+       .id                     = 0,
+       .dev.platform_data      = m520x_uart_platform,
+};
+
+static struct platform_device *m520x_devices[] __initdata = {
+       &m520x_uart,
+};
+
+/***************************************************************************/
+
+#define        INTC0   (MCF_MBAR + MCFICM_INTC0)
+
+static void __init m520x_uart_init_line(int line, int irq)
+{
+       u32 imr;
+       u16 par;
+       u8 par2;
+
+       writeb(0x03, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
+
+       imr = readl(INTC0 + MCFINTC_IMRL);
+       imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
+       writel(imr, INTC0 + MCFINTC_IMRL);
+
+       switch (line) {
+       case 0:
+               par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
+               par |= MCF_GPIO_PAR_UART_PAR_UTXD0 |
+                      MCF_GPIO_PAR_UART_PAR_URXD0;
+               writew(par, MCF_IPSBAR + MCF_GPIO_PAR_UART);
+               break;
+       case 1:
+               par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
+               par |= MCF_GPIO_PAR_UART_PAR_UTXD1 |
+                      MCF_GPIO_PAR_UART_PAR_URXD1;
+               writew(par, MCF_IPSBAR + MCF_GPIO_PAR_UART);
+               break;
+       case 2:
+               par2 = readb(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+               par2 &= ~0x0F;
+               par2 |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 |
+                       MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2;
+               writeb(par2, MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+               break;
+       }
+}
+
+static void __init m520x_uarts_init(void)
+{
+       const int nrlines = ARRAY_SIZE(m520x_uart_platform);
+       int line;
+
+       for (line = 0; (line < nrlines); line++)
+               m520x_uart_init_line(line, m520x_uart_platform[line].irq);
+}
 
 /***************************************************************************/
 
@@ -42,9 +114,20 @@ void mcf_autovector(unsigned int vec)
 
 /***************************************************************************/
 
-void config_BSP(char *commandp, int size)
+void __init config_BSP(char *commandp, int size)
 {
        mach_reset = coldfire_reset;
+       m520x_uarts_init();
 }
 
 /***************************************************************************/
+
+static int __init init_BSP(void)
+{
+       platform_add_devices(m520x_devices, ARRAY_SIZE(m520x_devices));
+       return 0;
+}
+
+arch_initcall(init_BSP);
+
+/***************************************************************************/
index e7f80c8e8636f2234c8322555c6a7ce01e1e68a8..13f02611ea23a8c866755af5b0fe8585e2d60de2 100644 (file)
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/dma.h>
+#include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
+#include <asm/mcfuart.h>
 
 /***************************************************************************/
 
@@ -28,14 +28,58 @@ void coldfire_reset(void);
 
 /***************************************************************************/
 
-/*
- *     DMA channel base address table.
- */
-unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
-        MCF_MBAR + MCFDMA_BASE0,
+static struct mcf_platform_uart m523x_uart_platform[] = {
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE1,
+               .irq            = MCFINT_VECBASE + MCFINT_UART0,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE2,
+               .irq            = MCFINT_VECBASE + MCFINT_UART0 + 1,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE3,
+               .irq            = MCFINT_VECBASE + MCFINT_UART0 + 2,
+       },
+       { },
+};
+
+static struct platform_device m523x_uart = {
+       .name                   = "mcfuart",
+       .id                     = 0,
+       .dev.platform_data      = m523x_uart_platform,
+};
+
+static struct platform_device *m523x_devices[] __initdata = {
+       &m523x_uart,
 };
 
-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+/***************************************************************************/
+
+#define        INTC0   (MCF_MBAR + MCFICM_INTC0)
+
+static void __init m523x_uart_init_line(int line, int irq)
+{
+       u32 imr;
+
+       if ((line < 0) || (line > 2))
+               return;
+
+       writeb(0x30+line, (INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line));
+
+       imr = readl(INTC0 + MCFINTC_IMRL);
+       imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
+       writel(imr, INTC0 + MCFINTC_IMRL);
+}
+
+static void __init m523x_uarts_init(void)
+{
+       const int nrlines = ARRAY_SIZE(m523x_uart_platform);
+       int line;
+
+       for (line = 0; (line < nrlines); line++)
+               m523x_uart_init_line(line, m523x_uart_platform[line].irq);
+}
 
 /***************************************************************************/
 
@@ -49,15 +93,26 @@ void mcf_disableall(void)
 
 void mcf_autovector(unsigned int vec)
 {
-       /* Everything is auto-vectored on the 5272 */
+       /* Everything is auto-vectored on the 523x */
 }
 
 /***************************************************************************/
 
-void config_BSP(char *commandp, int size)
+void __init config_BSP(char *commandp, int size)
 {
        mcf_disableall();
        mach_reset = coldfire_reset;
+       m523x_uarts_init();
 }
 
 /***************************************************************************/
+
+static int __init init_BSP(void)
+{
+       platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices));
+       return 0;
+}
+
+arch_initcall(init_BSP);
+
+/***************************************************************************/
index d4d39435cb15ce54bc33950027fd0f1072405aac..d299f7b8768a9981640733e60b51b5bb106a3bfb 100644 (file)
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/dma.h>
+#include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
+#include <asm/mcfuart.h>
 
 /***************************************************************************/
 
@@ -24,17 +24,51 @@ void coldfire_reset(void);
 
 /***************************************************************************/
 
-/*
- *     DMA channel base address table.
- */
-unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
-        MCF_MBAR + MCFDMA_BASE0,
-        MCF_MBAR + MCFDMA_BASE1,
-        MCF_MBAR + MCFDMA_BASE2,
-        MCF_MBAR + MCFDMA_BASE3,
+static struct mcf_platform_uart m5249_uart_platform[] = {
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE1,
+               .irq            = 73,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE2,
+               .irq            = 74,
+       }
+};
+
+static struct platform_device m5249_uart = {
+       .name                   = "mcfuart",
+       .id                     = 0,
+       .dev.platform_data      = m5249_uart_platform,
+};
+
+static struct platform_device *m5249_devices[] __initdata = {
+       &m5249_uart,
 };
 
-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+/***************************************************************************/
+
+static void __init m5249_uart_init_line(int line, int irq)
+{
+       if (line == 0) {
+               writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+               writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
+       } else if (line == 1) {
+               writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+               writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
+       }
+}
+
+static void __init m5249_uarts_init(void)
+{
+       const int nrlines = ARRAY_SIZE(m5249_uart_platform);
+       int line;
+
+       for (line = 0; (line < nrlines); line++)
+               m5249_uart_init_line(line, m5249_uart_platform[line].irq);
+}
+
 
 /***************************************************************************/
 
@@ -71,24 +105,21 @@ void mcf_settimericr(unsigned int timer, unsigned int level)
 
 /***************************************************************************/
 
-int mcf_timerirqpending(int timer)
+void __init config_BSP(char *commandp, int size)
 {
-       unsigned int imr = 0;
-
-       switch (timer) {
-       case 1:  imr = MCFSIM_IMR_TIMER1; break;
-       case 2:  imr = MCFSIM_IMR_TIMER2; break;
-       default: break;
-       }
-       return (mcf_getipr() & imr);
+       mcf_setimr(MCFSIM_IMR_MASKALL);
+       mach_reset = coldfire_reset;
 }
 
 /***************************************************************************/
 
-void config_BSP(char *commandp, int size)
+static int __init init_BSP(void)
 {
-       mcf_setimr(MCFSIM_IMR_MASKALL);
-       mach_reset = coldfire_reset;
+       m5249_uarts_init();
+       platform_add_devices(m5249_devices, ARRAY_SIZE(m5249_devices));
+       return 0;
 }
 
+arch_initcall(init_BSP);
+
 /***************************************************************************/
index 634a6375e4a5f3a4f4f4f6e7428e16fe29ccf14d..2aca599a1ca714ae2b70ec3d6d89f2ce74dc631f 100644 (file)
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/dma.h>
+#include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
+#include <asm/mcfuart.h>
 
 /***************************************************************************/
 
@@ -37,14 +37,57 @@ unsigned char ledbank = 0xff;
 
 /***************************************************************************/
 
-/*
- *     DMA channel base address table.
- */
-unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
-        MCF_MBAR + MCFDMA_BASE0,
+static struct mcf_platform_uart m5272_uart_platform[] = {
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE1,
+               .irq            = 73,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE2,
+               .irq            = 74,
+       },
+       { },
 };
 
-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+static struct platform_device m5272_uart = {
+       .name                   = "mcfuart",
+       .id                     = 0,
+       .dev.platform_data      = m5272_uart_platform,
+};
+
+static struct platform_device *m5272_devices[] __initdata = {
+       &m5272_uart,
+};
+
+/***************************************************************************/
+
+static void __init m5272_uart_init_line(int line, int irq)
+{
+       u32 v;
+
+       if ((line >= 0) && (line < 2)) {
+               v = (line) ? 0x0e000000 : 0xe0000000;
+               writel(v, MCF_MBAR + MCFSIM_ICR2);
+
+               /* Enable the output lines for the serial ports */
+               v = readl(MCF_MBAR + MCFSIM_PBCNT);
+               v = (v & ~0x000000ff) | 0x00000055;
+               writel(v, MCF_MBAR + MCFSIM_PBCNT);
+
+               v = readl(MCF_MBAR + MCFSIM_PDCNT);
+               v = (v & ~0x000003fc) | 0x000002a8;
+               writel(v, MCF_MBAR + MCFSIM_PDCNT);
+       }
+}
+
+static void __init m5272_uarts_init(void)
+{
+       const int nrlines = ARRAY_SIZE(m5272_uart_platform);
+       int line;
+
+       for (line = 0; (line < nrlines); line++)
+               m5272_uart_init_line(line, m5272_uart_platform[line].irq);
+}
 
 /***************************************************************************/
 
@@ -80,20 +123,7 @@ void mcf_settimericr(int timer, int level)
 
 /***************************************************************************/
 
-int mcf_timerirqpending(int timer)
-{
-       volatile unsigned long *icrp;
-
-       if ((timer >= 1 ) && (timer <= 4)) {
-               icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-               return (*icrp & (0x8 << ((4 - timer) * 4)));
-       }
-       return 0;
-}
-
-/***************************************************************************/
-
-void config_BSP(char *commandp, int size)
+void __init config_BSP(char *commandp, int size)
 {
 #if defined (CONFIG_MOD5272)
        volatile unsigned char  *pivrp;
@@ -125,3 +155,14 @@ void config_BSP(char *commandp, int size)
 }
 
 /***************************************************************************/
+
+static int __init init_BSP(void)
+{
+       m5272_uarts_init();
+       platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices));
+       return 0;
+}
+
+arch_initcall(init_BSP);
+
+/***************************************************************************/
index 9cbfbc68ae4f3a083417236191b67c9c983f59c8..73cd1aef4a9020c64133ea3c6b39a30669b2f57d 100644 (file)
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/dma.h>
+#include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
+#include <asm/mcfuart.h>
 
 /***************************************************************************/
 
@@ -28,14 +28,72 @@ void coldfire_reset(void);
 
 /***************************************************************************/
 
-/*
- *     DMA channel base address table.
- */
-unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
-        MCF_MBAR + MCFDMA_BASE0,
+static struct mcf_platform_uart m527x_uart_platform[] = {
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE1,
+               .irq            = MCFINT_VECBASE + MCFINT_UART0,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE2,
+               .irq            = MCFINT_VECBASE + MCFINT_UART1,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE3,
+               .irq            = MCFINT_VECBASE + MCFINT_UART2,
+       },
+       { },
 };
 
-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+static struct platform_device m527x_uart = {
+       .name                   = "mcfuart",
+       .id                     = 0,
+       .dev.platform_data      = m527x_uart_platform,
+};
+
+static struct platform_device *m527x_devices[] __initdata = {
+       &m527x_uart,
+};
+
+/***************************************************************************/
+
+#define        INTC0   (MCF_MBAR + MCFICM_INTC0)
+
+static void __init m527x_uart_init_line(int line, int irq)
+{
+       u16 sepmask;
+       u32 imr;
+
+       if ((line < 0) || (line > 2))
+               return;
+
+       /* level 6, line based priority */
+       writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
+
+       imr = readl(INTC0 + MCFINTC_IMRL);
+       imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
+       writel(imr, INTC0 + MCFINTC_IMRL);
+
+       /*
+        * External Pin Mask Setting & Enable External Pin for Interface
+        */
+       sepmask = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
+       if (line == 0)
+               sepmask |= UART0_ENABLE_MASK;
+       else if (line == 1)
+               sepmask |= UART1_ENABLE_MASK;
+       else if (line == 2)
+               sepmask |= UART2_ENABLE_MASK;
+       writew(sepmask, MCF_IPSBAR + MCF_GPIO_PAR_UART);
+}
+
+static void __init m527x_uarts_init(void)
+{
+       const int nrlines = ARRAY_SIZE(m527x_uart_platform);
+       int line;
+
+       for (line = 0; (line < nrlines); line++)
+               m527x_uart_init_line(line, m527x_uart_platform[line].irq);
+}
 
 /***************************************************************************/
 
@@ -54,10 +112,21 @@ void mcf_autovector(unsigned int vec)
 
 /***************************************************************************/
 
-void config_BSP(char *commandp, int size)
+void __init config_BSP(char *commandp, int size)
 {
        mcf_disableall();
        mach_reset = coldfire_reset;
 }
 
 /***************************************************************************/
+
+static int __init init_BSP(void)
+{
+       m527x_uarts_init();
+       platform_add_devices(m527x_devices, ARRAY_SIZE(m527x_devices));
+       return 0;
+}
+
+arch_initcall(init_BSP);
+
+/***************************************************************************/
index acbd43486d97a457a3b0ce5c68123830274dc9d2..036e1b73d94400b8619db75d71e271a5ce2592e3 100644 (file)
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/dma.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
+#include <asm/mcfuart.h>
+#include <asm/mcfqspi.h>
 
 /***************************************************************************/
 
@@ -28,14 +32,67 @@ void coldfire_reset(void);
 
 /***************************************************************************/
 
-/*
- *     DMA channel base address table.
- */
-unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
-        MCF_MBAR + MCFDMA_BASE0,
+static struct mcf_platform_uart m528x_uart_platform[] = {
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE1,
+               .irq            = MCFINT_VECBASE + MCFINT_UART0,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE2,
+               .irq            = MCFINT_VECBASE + MCFINT_UART0 + 1,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE3,
+               .irq            = MCFINT_VECBASE + MCFINT_UART0 + 2,
+       },
+       { },
 };
 
-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+static struct platform_device m528x_uart = {
+       .name                   = "mcfuart",
+       .id                     = 0,
+       .dev.platform_data      = m528x_uart_platform,
+};
+
+static struct platform_device *m528x_devices[] __initdata = {
+       &m528x_uart,
+};
+
+/***************************************************************************/
+
+#define        INTC0   (MCF_MBAR + MCFICM_INTC0)
+
+static void __init m528x_uart_init_line(int line, int irq)
+{
+       u8 port;
+       u32 imr;
+
+       if ((line < 0) || (line > 2))
+               return;
+
+       /* level 6, line based priority */
+       writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
+
+       imr = readl(INTC0 + MCFINTC_IMRL);
+       imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
+       writel(imr, INTC0 + MCFINTC_IMRL);
+
+       /* make sure PUAPAR is set for UART0 and UART1 */
+       if (line < 2) {
+               port = readb(MCF_MBAR + MCF5282_GPIO_PUAPAR);
+               port |= (0x03 << (line * 2));
+               writeb(port, MCF_MBAR + MCF5282_GPIO_PUAPAR);
+       }
+}
+
+static void __init m528x_uarts_init(void)
+{
+       const int nrlines = ARRAY_SIZE(m528x_uart_platform);
+       int line;
+
+       for (line = 0; (line < nrlines); line++)
+               m528x_uart_init_line(line, m528x_uart_platform[line].irq);
+}
 
 /***************************************************************************/
 
@@ -54,10 +111,21 @@ void mcf_autovector(unsigned int vec)
 
 /***************************************************************************/
 
-void config_BSP(char *commandp, int size)
+void __init config_BSP(char *commandp, int size)
 {
        mcf_disableall();
        mach_reset = coldfire_reset;
 }
 
 /***************************************************************************/
+
+static int __init init_BSP(void)
+{
+       m528x_uarts_init();
+       platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
+       return 0;
+}
+
+arch_initcall(init_BSP);
+
+/***************************************************************************/
index 5b600530c8d2400a798c44bbf05ddd8135690bb0..580fd6658d7c204a1f86baff20ef0ba39b08b220 100644 (file)
@@ -16,17 +16,5 @@ ifdef CONFIG_FULLDEBUG
 EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
 endif
 
-obj-$(CONFIG_COLDFIRE) += entry.o vectors.o
-obj-$(CONFIG_M5206)    += timers.o
-obj-$(CONFIG_M5206e)   += timers.o
-obj-$(CONFIG_M520x)    += pit.o
-obj-$(CONFIG_M523x)    += pit.o
-obj-$(CONFIG_M5249)    += timers.o
-obj-$(CONFIG_M527x)     += pit.o
-obj-$(CONFIG_M5272)    += timers.o
-obj-$(CONFIG_M5307)    += config.o timers.o
-obj-$(CONFIG_M532x)    += timers.o
-obj-$(CONFIG_M528x)     += pit.o
-obj-$(CONFIG_M5407)    += timers.o
+obj-y  += config.o
 
-extra-y := head.o
index 6040821e637d40af16f2648438aac1ddd3ca632d..92dc862fa826edb5432875d585a99d266f2d80ca 100644 (file)
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/dma.h>
+#include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
+#include <asm/mcfuart.h>
 #include <asm/mcfwdebug.h>
 
 /***************************************************************************/
@@ -38,17 +38,51 @@ unsigned char ledbank = 0xff;
 
 /***************************************************************************/
 
-/*
- *     DMA channel base address table.
- */
-unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
-        MCF_MBAR + MCFDMA_BASE0,
-        MCF_MBAR + MCFDMA_BASE1,
-        MCF_MBAR + MCFDMA_BASE2,
-        MCF_MBAR + MCFDMA_BASE3,
+static struct mcf_platform_uart m5307_uart_platform[] = {
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE1,
+               .irq            = 73,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE2,
+               .irq            = 74,
+       },
+       { },
+};
+
+static struct platform_device m5307_uart = {
+       .name                   = "mcfuart",
+       .id                     = 0,
+       .dev.platform_data      = m5307_uart_platform,
 };
 
-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+static struct platform_device *m5307_devices[] __initdata = {
+       &m5307_uart,
+};
+
+/***************************************************************************/
+
+static void __init m5307_uart_init_line(int line, int irq)
+{
+       if (line == 0) {
+               writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+               writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
+       } else if (line == 1) {
+               writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+               writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
+       }
+}
+
+static void __init m5307_uarts_init(void)
+{
+       const int nrlines = ARRAY_SIZE(m5307_uart_platform);
+       int line;
+
+       for (line = 0; (line < nrlines); line++)
+               m5307_uart_init_line(line, m5307_uart_platform[line].irq);
+}
 
 /***************************************************************************/
 
@@ -85,21 +119,7 @@ void mcf_settimericr(unsigned int timer, unsigned int level)
 
 /***************************************************************************/
 
-int mcf_timerirqpending(int timer)
-{
-       unsigned int imr = 0;
-
-       switch (timer) {
-       case 1:  imr = MCFSIM_IMR_TIMER1; break;
-       case 2:  imr = MCFSIM_IMR_TIMER2; break;
-       default: break;
-       }
-       return (mcf_getipr() & imr);
-}
-
-/***************************************************************************/
-
-void config_BSP(char *commandp, int size)
+void __init config_BSP(char *commandp, int size)
 {
        mcf_setimr(MCFSIM_IMR_MASKALL);
 
@@ -117,7 +137,7 @@ void config_BSP(char *commandp, int size)
 
        mach_reset = coldfire_reset;
 
-#ifdef MCF_BDM_DISABLE
+#ifdef CONFIG_BDM_DISABLE
        /*
         * Disable the BDM clocking.  This also turns off most of the rest of
         * the BDM device.  This is good for EMC reasons. This option is not
@@ -128,3 +148,14 @@ void config_BSP(char *commandp, int size)
 }
 
 /***************************************************************************/
+
+static int __init init_BSP(void)
+{
+       m5307_uarts_init();
+       platform_add_devices(m5307_devices, ARRAY_SIZE(m5307_devices));
+       return 0;
+}
+
+arch_initcall(init_BSP);
+
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/5307/entry.S b/arch/m68knommu/platform/5307/entry.S
deleted file mode 100644 (file)
index b333731..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- *  linux/arch/m68knommu/platform/5307/entry.S
- *
- *  Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com)
- *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
- *                      Kenneth Albanowski <kjahds@kjahds.com>,
- *  Copyright (C) 2000  Lineo Inc. (www.lineo.com)
- *  Copyright (C) 2004-2006  Macq Electronique SA. (www.macqel.com)
- *
- * Based on:
- *
- *  linux/arch/m68k/kernel/entry.S
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file README.legal in the main directory of this archive
- * for more details.
- *
- * Linux/m68k support by Hamish Macdonald
- *
- * 68060 fixes by Jesper Skov
- * ColdFire support by Greg Ungerer (gerg@snapgear.com)
- * 5307 fixes by David W. Miller
- * linux 2.4 support David McCullough <davidm@snapgear.com>
- * Bug, speed and maintainability fixes by Philippe De Muyter <phdm@macqel.be>
- */
-
-#include <linux/sys.h>
-#include <linux/linkage.h>
-#include <asm/unistd.h>
-#include <asm/thread_info.h>
-#include <asm/errno.h>
-#include <asm/setup.h>
-#include <asm/segment.h>
-#include <asm/asm-offsets.h>
-#include <asm/entry.h>
-
-.bss
-
-sw_ksp:
-.long  0
-
-sw_usp:
-.long  0
-
-.text
-
-.globl system_call
-.globl resume
-.globl ret_from_exception
-.globl ret_from_signal
-.globl sys_call_table
-.globl ret_from_interrupt
-.globl inthandler
-.globl fasthandler
-
-enosys:
-       mov.l   #sys_ni_syscall,%d3
-       bra     1f
-
-ENTRY(system_call)
-       SAVE_ALL
-       move    #0x2000,%sr             /* enable intrs again */
-
-       cmpl    #NR_syscalls,%d0
-       jcc     enosys
-       lea     sys_call_table,%a0
-       lsll    #2,%d0                  /* movel %a0@(%d0:l:4),%d3 */
-       movel   %a0@(%d0),%d3
-       jeq     enosys
-
-1:
-       movel   %sp,%d2                 /* get thread_info pointer */
-       andl    #-THREAD_SIZE,%d2       /* at start of kernel stack */
-       movel   %d2,%a0
-       movel   %a0@,%a1                /* save top of frame */
-       movel   %sp,%a1@(TASK_THREAD+THREAD_ESP0)
-       btst    #(TIF_SYSCALL_TRACE%8),%a0@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
-       bnes    1f
-
-       movel   %d3,%a0
-       jbsr    %a0@
-       movel   %d0,%sp@(PT_D0)         /* save the return value */
-       jra     ret_from_exception
-1:
-       movel   #-ENOSYS,%d2            /* strace needs -ENOSYS in PT_D0 */
-       movel   %d2,PT_D0(%sp)          /* on syscall entry */
-       subql   #4,%sp
-       SAVE_SWITCH_STACK
-       jbsr    syscall_trace
-       RESTORE_SWITCH_STACK
-       addql   #4,%sp
-       movel   %d3,%a0
-       jbsr    %a0@
-       movel   %d0,%sp@(PT_D0)         /* save the return value */
-       subql   #4,%sp                  /* dummy return address */
-       SAVE_SWITCH_STACK
-       jbsr    syscall_trace
-
-ret_from_signal:
-       RESTORE_SWITCH_STACK
-       addql   #4,%sp
-
-ret_from_exception:
-       btst    #5,%sp@(PT_SR)          /* check if returning to kernel */
-       jeq     Luser_return            /* if so, skip resched, signals */
-
-Lkernel_return:
-       moveml  %sp@,%d1-%d5/%a0-%a2
-       lea     %sp@(32),%sp            /* space for 8 regs */
-       movel   %sp@+,%d0
-       addql   #4,%sp                  /* orig d0 */
-       addl    %sp@+,%sp               /* stk adj */
-       rte
-
-Luser_return:
-       movel   %sp,%d1                 /* get thread_info pointer */
-       andl    #-THREAD_SIZE,%d1       /* at base of kernel stack */
-       movel   %d1,%a0
-       movel   %a0@(TI_FLAGS),%d1      /* get thread_info->flags */
-       andl    #_TIF_WORK_MASK,%d1
-       jne     Lwork_to_do             /* still work to do */
-
-Lreturn:
-       move    #0x2700,%sr             /* disable intrs */
-       movel   sw_usp,%a0              /* get usp */
-       movel   %sp@(PT_PC),%a0@-       /* copy exception program counter */
-       movel   %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */
-       moveml  %sp@,%d1-%d5/%a0-%a2
-       lea     %sp@(32),%sp            /* space for 8 regs */
-       movel   %sp@+,%d0
-       addql   #4,%sp                  /* orig d0 */
-       addl    %sp@+,%sp               /* stk adj */
-       addql   #8,%sp                  /* remove exception */
-       movel   %sp,sw_ksp              /* save ksp */
-       subql   #8,sw_usp               /* set exception */
-       movel   sw_usp,%sp              /* restore usp */
-       rte
-
-Lwork_to_do:
-       movel   %a0@(TI_FLAGS),%d1      /* get thread_info->flags */
-       btst    #TIF_NEED_RESCHED,%d1
-       jne     reschedule
-
-       /* GERG: do we need something here for TRACEing?? */
-
-Lsignal_return:
-       subql   #4,%sp                  /* dummy return address */
-       SAVE_SWITCH_STACK
-       pea     %sp@(SWITCH_STACK_SIZE)
-       clrl    %sp@-
-       jsr     do_signal
-       addql   #8,%sp
-       RESTORE_SWITCH_STACK
-       addql   #4,%sp
-       jmp     Lreturn
-
-/*
- * This is the generic interrupt handler (for all hardware interrupt
- * sources). Calls upto high level code to do all the work.
- */
-ENTRY(inthandler)
-       SAVE_ALL
-       moveq   #-1,%d0
-       movel   %d0,%sp@(PT_ORIG_D0)
-
-       movew   %sp@(PT_FORMATVEC),%d0  /* put exception # in d0 */
-       andl    #0x03fc,%d0             /* mask out vector only */
-
-       movel   %sp,%sp@-               /* push regs arg */
-       lsrl    #2,%d0                  /* calculate real vector # */
-       movel   %d0,%sp@-               /* push vector number */
-       jbsr    do_IRQ                  /* call high level irq handler */
-       lea     %sp@(8),%sp             /* pop args off stack */
-
-       bra     ret_from_interrupt      /* this was fallthrough */
-
-/*
- * This is the fast interrupt handler (for certain hardware interrupt
- * sources). Unlike the normal interrupt handler it just uses the
- * current stack (doesn't care if it is user or kernel). It also
- * doesn't bother doing the bottom half handlers.
- */
-ENTRY(fasthandler)
-       SAVE_LOCAL
-
-       movew   %sp@(PT_FORMATVEC),%d0
-       andl    #0x03fc,%d0             /* mask out vector only */
-
-       movel   %sp,%sp@-               /* push regs arg */
-       lsrl    #2,%d0                  /* calculate real vector # */
-       movel   %d0,%sp@-               /* push vector number */
-       jbsr    do_IRQ                  /* call high level irq handler */
-       lea     %sp@(8),%sp             /* pop args off stack */
-
-       RESTORE_LOCAL
-
-ENTRY(ret_from_interrupt)
-       jeq     2f
-1:
-       RESTORE_ALL
-2:
-       moveb   %sp@(PT_SR),%d0
-       andl    #0x7,%d0
-       jhi     1b
-
-       /* check if we need to do software interrupts */
-       movel   irq_stat+CPUSTAT_SOFTIRQ_PENDING,%d0
-       jeq     ret_from_exception
-
-       pea     ret_from_exception
-       jmp     do_softirq
-
-/*
- * Beware - when entering resume, prev (the current task) is
- * in a0, next (the new task) is in a1,so don't change these
- * registers until their contents are no longer needed.
- * This is always called in supervisor mode, so don't bother to save
- * and restore sr; user's process sr is actually in the stack.
- */
-ENTRY(resume)
-       movel   %a0, %d1                        /* get prev thread in d1 */
-
-       movel   sw_usp,%d0                      /* save usp */
-       movel   %d0,%a0@(TASK_THREAD+THREAD_USP)
-
-       SAVE_SWITCH_STACK
-       movel   %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */
-       movel   %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
-       RESTORE_SWITCH_STACK
-
-       movel   %a1@(TASK_THREAD+THREAD_USP),%a0 /* restore thread user stack */
-       movel   %a0, sw_usp
-       rts
diff --git a/arch/m68knommu/platform/5307/head.S b/arch/m68knommu/platform/5307/head.S
deleted file mode 100644 (file)
index b9aa0ca..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/*****************************************************************************/
-
-/*
- *     head.S -- common startup code for ColdFire CPUs.
- *
- *     (C) Copyright 1999-2006, Greg Ungerer <gerg@snapgear.com>.
- */
-
-/*****************************************************************************/
-
-#include <linux/sys.h>
-#include <linux/linkage.h>
-#include <asm/asm-offsets.h>
-#include <asm/coldfire.h>
-#include <asm/mcfcache.h>
-#include <asm/mcfsim.h>
-
-/*****************************************************************************/
-
-/*
- *     If we don't have a fixed memory size, then lets build in code
- *     to auto detect the DRAM size. Obviously this is the prefered
- *     method, and should work for most boards. It won't work for those
- *     that do not have their RAM starting at address 0, and it only
- *     works on SDRAM (not boards fitted with SRAM).
- */
-#if CONFIG_RAMSIZE != 0
-.macro GET_MEM_SIZE
-       movel   #CONFIG_RAMSIZE,%d0     /* hard coded memory size */
-.endm
-
-#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
-      defined(CONFIG_M5249) || defined(CONFIG_M527x) || \
-      defined(CONFIG_M528x) || defined(CONFIG_M5307) || \
-      defined(CONFIG_M5407)
-/*
- *     Not all these devices have exactly the same DRAM controller,
- *     but the DCMR register is virtually identical - give or take
- *     a couple of bits. The only exception is the 5272 devices, their
- *     DRAM controller is quite different.
- */
-.macro GET_MEM_SIZE
-       movel   MCF_MBAR+MCFSIM_DMR0,%d0 /* get mask for 1st bank */
-       btst    #0,%d0                  /* check if region enabled */
-       beq     1f
-       andl    #0xfffc0000,%d0
-       beq     1f
-       addl    #0x00040000,%d0         /* convert mask to size */
-1:
-       movel   MCF_MBAR+MCFSIM_DMR1,%d1 /* get mask for 2nd bank */
-       btst    #0,%d1                  /* check if region enabled */
-       beq     2f
-       andl    #0xfffc0000, %d1
-       beq     2f
-       addl    #0x00040000,%d1
-       addl    %d1,%d0                 /* total mem size in d0 */
-2:
-.endm
-
-#elif defined(CONFIG_M5272)
-.macro GET_MEM_SIZE
-       movel   MCF_MBAR+MCFSIM_CSOR7,%d0 /* get SDRAM address mask */
-       andil   #0xfffff000,%d0         /* mask out chip select options */
-       negl    %d0                     /* negate bits */
-.endm
-
-#elif defined(CONFIG_M520x)
-.macro GET_MEM_SIZE
-       clrl    %d0
-       movel   MCF_MBAR+MCFSIM_SDCS0, %d2 /* Get SDRAM chip select 0 config */
-       andl    #0x1f, %d2              /* Get only the chip select size */
-       beq     3f                      /* Check if it is enabled */
-       addql   #1, %d2                 /* Form exponent */
-       moveql  #1, %d0
-       lsll    %d2, %d0                /* 2 ^ exponent */
-3:
-       movel   MCF_MBAR+MCFSIM_SDCS1, %d2 /* Get SDRAM chip select 1 config */
-       andl    #0x1f, %d2              /* Get only the chip select size */
-       beq     4f                      /* Check if it is enabled */
-       addql   #1, %d2                 /* Form exponent */
-       moveql  #1, %d1
-       lsll    %d2, %d1                /* 2 ^ exponent */
-       addl    %d1, %d0                /* Total size of SDRAM in d0 */
-4:
-.endm
-
-#else
-#error "ERROR: I don't know how to probe your boards memory size?"
-#endif
-
-/*****************************************************************************/
-
-/*
- *     Boards and platforms can do specific early hardware setup if
- *     they need to. Most don't need this, define away if not required.
- */
-#ifndef PLATFORM_SETUP
-#define        PLATFORM_SETUP
-#endif
-
-/*****************************************************************************/
-
-.global        _start
-.global _rambase
-.global _ramvec
-.global        _ramstart
-.global        _ramend
-
-/*****************************************************************************/
-
-.data
-
-/*
- *     During startup we store away the RAM setup. These are not in the
- *     bss, since their values are determined and written before the bss
- *     has been cleared.
- */
-_rambase:
-.long  0
-_ramvec:
-.long  0
-_ramstart:
-.long  0
-_ramend:
-.long  0
-
-/*****************************************************************************/
-
-.text
-
-/*
- *     This is the codes first entry point. This is where it all
- *     begins...
- */
-
-_start:
-       nop                                     /* filler */
-       movew   #0x2700, %sr                    /* no interrupts */
-
-       /*
-        *      Do any platform or board specific setup now. Most boards
-        *      don't need anything. Those exceptions are define this in
-        *      their board specific includes.
-        */
-       PLATFORM_SETUP
-
-       /*
-        *      Create basic memory configuration. Set VBR accordingly,
-        *      and size memory.
-        */
-       movel   #CONFIG_VECTORBASE,%a7
-       movec   %a7,%VBR                        /* set vectors addr */
-       movel   %a7,_ramvec
-
-       movel   #CONFIG_RAMBASE,%a7             /* mark the base of RAM */
-       movel   %a7,_rambase
-
-       GET_MEM_SIZE                            /* macro code determines size */
-       addl    %a7,%d0
-       movel   %d0,_ramend                     /* set end ram addr */
-
-       /*
-        *      Now that we know what the memory is, lets enable cache
-        *      and get things moving. This is Coldfire CPU specific.
-        */
-       CACHE_ENABLE                            /* enable CPU cache */
-
-
-#ifdef CONFIG_ROMFS_FS
-       /*
-        *      Move ROM filesystem above bss :-)
-        */
-       lea     _sbss,%a0                       /* get start of bss */
-       lea     _ebss,%a1                       /* set up destination  */
-       movel   %a0,%a2                         /* copy of bss start */
-
-       movel   8(%a0),%d0                      /* get size of ROMFS */
-       addql   #8,%d0                          /* allow for rounding */
-       andl    #0xfffffffc, %d0                /* whole words */
-
-       addl    %d0,%a0                         /* copy from end */
-       addl    %d0,%a1                         /* copy from end */
-       movel   %a1,_ramstart                   /* set start of ram */
-
-_copy_romfs:
-       movel   -(%a0),%d0                      /* copy dword */
-       movel   %d0,-(%a1)
-       cmpl    %a0,%a2                         /* check if at end */
-       bne     _copy_romfs
-
-#else /* CONFIG_ROMFS_FS */
-       lea     _ebss,%a1
-       movel   %a1,_ramstart
-#endif /* CONFIG_ROMFS_FS */
-
-
-       /*
-        *      Zero out the bss region.
-        */
-       lea     _sbss,%a0                       /* get start of bss */
-       lea     _ebss,%a1                       /* get end of bss */
-       clrl    %d0                             /* set value */
-_clear_bss:
-       movel   %d0,(%a0)+                      /* clear each word */
-       cmpl    %a0,%a1                         /* check if at end */
-       bne     _clear_bss
-
-       /*
-        *      Load the current task pointer and stack.
-        */
-       lea     init_thread_union,%a0
-       lea     THREAD_SIZE(%a0),%sp
-
-       /*
-        *      Assember start up done, start code proper.
-        */
-       jsr     start_kernel                    /* start Linux kernel */
-
-_exit:
-       jmp     _exit                           /* should never get here */
-
-/*****************************************************************************/
diff --git a/arch/m68knommu/platform/5307/pit.c b/arch/m68knommu/platform/5307/pit.c
deleted file mode 100644 (file)
index 173b754..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/***************************************************************************/
-
-/*
- *     pit.c -- Freescale ColdFire PIT timer. Currently this type of
- *              hardware timer only exists in the Freescale ColdFire
- *              5270/5271, 5282 and other CPUs.
- *
- *     Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com)
- *     Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
- */
-
-/***************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/param.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <asm/machdep.h>
-#include <asm/io.h>
-#include <asm/coldfire.h>
-#include <asm/mcfpit.h>
-#include <asm/mcfsim.h>
-
-/***************************************************************************/
-
-/*
- *     By default use timer1 as the system clock timer.
- */
-#define        TA(a)   (MCF_IPSBAR + MCFPIT_BASE1 + (a))
-
-/***************************************************************************/
-
-static irqreturn_t hw_tick(int irq, void *dummy)
-{
-       unsigned short pcsr;
-
-       /* Reset the ColdFire timer */
-       pcsr = __raw_readw(TA(MCFPIT_PCSR));
-       __raw_writew(pcsr | MCFPIT_PCSR_PIF, TA(MCFPIT_PCSR));
-
-       return arch_timer_interrupt(irq, dummy);
-}
-
-/***************************************************************************/
-
-static struct irqaction coldfire_pit_irq = {
-       .name    = "timer",
-       .flags   = IRQF_DISABLED | IRQF_TIMER,
-       .handler = hw_tick,
-};
-
-void hw_timer_init(void)
-{
-       volatile unsigned char *icrp;
-       volatile unsigned long *imrp;
-
-       setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &coldfire_pit_irq);
-
-       icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
-               MCFINTC_ICR0 + MCFINT_PIT1);
-       *icrp = ICR_INTRCONF;
-
-       imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR);
-       *imrp &= ~MCFPIT_IMR_IBIT;
-
-       /* Set up PIT timer 1 as poll clock */
-       __raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR));
-       __raw_writew(((MCF_CLK / 2) / 64) / HZ, TA(MCFPIT_PMR));
-       __raw_writew(MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW |
-               MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64, TA(MCFPIT_PCSR));
-}
-
-/***************************************************************************/
-
-unsigned long hw_timer_offset(void)
-{
-       volatile unsigned long *ipr;
-       unsigned long pmr, pcntr, offset;
-
-       ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR);
-
-       pmr = __raw_readw(TA(MCFPIT_PMR));
-       pcntr = __raw_readw(TA(MCFPIT_PCNTR));
-
-       /*
-        * If we are still in the first half of the upcount and a
-        * timer interrupt is pending, then add on a ticks worth of time.
-        */
-       offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr;
-       if ((offset < (1000000 / HZ / 2)) && (*ipr & MCFPIT_IMR_IBIT))
-               offset += 1000000 / HZ;
-       return offset;  
-}
-
-/***************************************************************************/
diff --git a/arch/m68knommu/platform/5307/timers.c b/arch/m68knommu/platform/5307/timers.c
deleted file mode 100644 (file)
index 489dec8..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/***************************************************************************/
-
-/*
- *     timers.c -- generic ColdFire hardware timer support.
- *
- *     Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com)
- */
-
-/***************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <asm/io.h>
-#include <asm/traps.h>
-#include <asm/machdep.h>
-#include <asm/coldfire.h>
-#include <asm/mcftimer.h>
-#include <asm/mcfsim.h>
-
-/***************************************************************************/
-
-/*
- *     By default use timer1 as the system clock timer.
- */
-#define        TA(a)   (MCF_MBAR + MCFTIMER_BASE1 + (a))
-
-/*
- *     Default the timer and vector to use for ColdFire. Some ColdFire
- *     CPU's and some boards may want different. Their sub-architecture
- *     startup code (in config.c) can change these if they want.
- */
-unsigned int   mcf_timervector = 29;
-unsigned int   mcf_profilevector = 31;
-unsigned int   mcf_timerlevel = 5;
-
-/*
- *     These provide the underlying interrupt vector support.
- *     Unfortunately it is a little different on each ColdFire.
- */
-extern void mcf_settimericr(int timer, int level);
-extern int mcf_timerirqpending(int timer);
-
-#if defined(CONFIG_M532x)
-#define        __raw_readtrr   __raw_readl
-#define        __raw_writetrr  __raw_writel
-#else
-#define        __raw_readtrr   __raw_readw
-#define        __raw_writetrr  __raw_writew
-#endif
-
-/***************************************************************************/
-
-static irqreturn_t hw_tick(int irq, void *dummy)
-{
-       /* Reset the ColdFire timer */
-       __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER));
-
-       return arch_timer_interrupt(irq, dummy);
-}
-
-/***************************************************************************/
-
-static struct irqaction coldfire_timer_irq = {
-       .name    = "timer",
-       .flags   = IRQF_DISABLED | IRQF_TIMER,
-       .handler = hw_tick,
-};
-
-/***************************************************************************/
-
-static int ticks_per_intr;
-
-void hw_timer_init(void)
-{
-       setup_irq(mcf_timervector, &coldfire_timer_irq);
-
-       __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
-       ticks_per_intr = (MCF_BUSCLK / 16) / HZ;
-       __raw_writetrr(ticks_per_intr - 1, TA(MCFTIMER_TRR));
-       __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
-               MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR));
-
-       mcf_settimericr(1, mcf_timerlevel);
-
-#ifdef CONFIG_HIGHPROFILE
-       coldfire_profile_init();
-#endif
-}
-
-/***************************************************************************/
-
-unsigned long hw_timer_offset(void)
-{
-       unsigned long tcn, offset;
-
-       tcn = __raw_readw(TA(MCFTIMER_TCN));
-       offset = ((tcn + 1) * (1000000 / HZ)) / ticks_per_intr;
-
-       /* Check if we just wrapped the counters and maybe missed a tick */
-       if ((offset < (1000000 / HZ / 2)) && mcf_timerirqpending(1))
-               offset += 1000000 / HZ;
-       return offset;
-}
-
-/***************************************************************************/
-#ifdef CONFIG_HIGHPROFILE
-/***************************************************************************/
-
-/*
- *     By default use timer2 as the profiler clock timer.
- */
-#define        PA(a)   (MCF_MBAR + MCFTIMER_BASE2 + (a))
-
-/*
- *     Choose a reasonably fast profile timer. Make it an odd value to
- *     try and get good coverage of kernel operations.
- */
-#define        PROFILEHZ       1013
-
-/*
- *     Use the other timer to provide high accuracy profiling info.
- */
-irqreturn_t coldfire_profile_tick(int irq, void *dummy)
-{
-       /* Reset ColdFire timer2 */
-       __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, PA(MCFTIMER_TER));
-       if (current->pid)
-               profile_tick(CPU_PROFILING, regs);
-       return IRQ_HANDLED;
-}
-
-/***************************************************************************/
-
-void coldfire_profile_init(void)
-{
-       printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ);
-
-       /* Set up TIMER 2 as high speed profile clock */
-       __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR));
-
-       __raw_writetrr(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR));
-       __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
-               MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR));
-
-       request_irq(mcf_profilevector, coldfire_profile_tick,
-               (IRQF_DISABLED | IRQ_FLG_FAST), "profile timer", NULL);
-       mcf_settimericr(2, 7);
-}
-
-/***************************************************************************/
-#endif /* CONFIG_HIGHPROFILE */
-/***************************************************************************/
diff --git a/arch/m68knommu/platform/5307/vectors.c b/arch/m68knommu/platform/5307/vectors.c
deleted file mode 100644 (file)
index 6cf8946..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/***************************************************************************/
-
-/*
- *     linux/arch/m68knommu/platform/5307/vectors.c
- *
- *     Copyright (C) 1999-2007, Greg Ungerer <gerg@snapgear.com>
- */
-
-/***************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <asm/traps.h>
-#include <asm/machdep.h>
-#include <asm/coldfire.h>
-#include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
-#include <asm/mcfwdebug.h>
-
-/***************************************************************************/
-
-#ifdef TRAP_DBG_INTERRUPT
-
-asmlinkage void dbginterrupt_c(struct frame *fp)
-{
-       extern void dump(struct pt_regs *fp);
-       printk(KERN_DEBUG "%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__);
-       dump((struct pt_regs *) fp);
-       asm("halt");
-}
-
-#endif
-
-/***************************************************************************/
-
-extern e_vector        *_ramvec;
-
-void set_evector(int vecnum, void (*handler)(void))
-{
-       if (vecnum >= 0 && vecnum <= 255)
-               _ramvec[vecnum] = handler;
-}
-
-/***************************************************************************/
-
-/* Assembler routines */
-asmlinkage void buserr(void);
-asmlinkage void trap(void);
-asmlinkage void system_call(void);
-asmlinkage void inthandler(void);
-
-void __init init_vectors(void)
-{
-       int i;
-
-       /*
-        *      There is a common trap handler and common interrupt
-        *      handler that handle almost every vector. We treat
-        *      the system call and bus error special, they get their
-        *      own first level handlers.
-        */
-       for (i = 3; (i <= 23); i++)
-               _ramvec[i] = trap;
-       for (i = 33; (i <= 63); i++)
-               _ramvec[i] = trap;
-       for (i = 24; (i <= 31); i++)
-               _ramvec[i] = inthandler;
-       for (i = 64; (i < 255); i++)
-               _ramvec[i] = inthandler;
-       _ramvec[255] = 0;
-
-       _ramvec[2] = buserr;
-       _ramvec[32] = system_call;
-
-#ifdef TRAP_DBG_INTERRUPT
-       _ramvec[12] = dbginterrupt;
-#endif
-}
-
-/***************************************************************************/
-
-void enable_vector(unsigned int irq)
-{
-       /* Currently no action on ColdFire */
-}
-
-void disable_vector(unsigned int irq)
-{
-       /* Currently no action on ColdFire */
-}
-
-void ack_vector(unsigned int irq)
-{
-       /* Currently no action on ColdFire */
-}
-
-/***************************************************************************/
-
-void coldfire_reset(void)
-{
-       HARD_RESET_NOW();
-}
-
-/***************************************************************************/
index f77328b7b6db0439dcf63d2877bfef40e737ac76..4f44b632045b4b8230177bbffc6d864318ba01d0 100644 (file)
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/dma.h>
+#include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
+#include <asm/mcfuart.h>
 #include <asm/mcfdma.h>
 #include <asm/mcfwdebug.h>
 
@@ -38,11 +39,60 @@ extern unsigned int mcf_timerlevel;
 
 /***************************************************************************/
 
-/*
- *     DMA channel base address table.
- */
-unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { };
-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+static struct mcf_platform_uart m532x_uart_platform[] = {
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE1,
+               .irq            = MCFINT_VECBASE + MCFINT_UART0,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE2,
+               .irq            = MCFINT_VECBASE + MCFINT_UART1,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE3,
+               .irq            = MCFINT_VECBASE + MCFINT_UART2,
+       },
+       { },
+};
+
+static struct platform_device m532x_uart = {
+       .name                   = "mcfuart",
+       .id                     = 0,
+       .dev.platform_data      = m532x_uart_platform,
+};
+
+static struct platform_device *m532x_devices[] __initdata = {
+       &m532x_uart,
+};
+
+/***************************************************************************/
+
+static void __init m532x_uart_init_line(int line, int irq)
+{
+       if (line == 0) {
+               MCF_INTC0_ICR26 = 0x3;
+               MCF_INTC0_CIMR = 26;
+               /* GPIO initialization */
+               MCF_GPIO_PAR_UART |= 0x000F;
+       } else if (line == 1) {
+               MCF_INTC0_ICR27 = 0x3;
+               MCF_INTC0_CIMR = 27;
+               /* GPIO initialization */
+               MCF_GPIO_PAR_UART |= 0x0FF0;
+       } else if (line == 2) {
+               MCF_INTC0_ICR28 = 0x3;
+               MCF_INTC0_CIMR = 28;
+       }
+}
+
+static void __init m532x_uarts_init(void)
+{
+       const int nrlines = ARRAY_SIZE(m532x_uart_platform);
+       int line;
+
+       for (line = 0; (line < nrlines); line++)
+               m532x_uart_init_line(line, m532x_uart_platform[line].irq);
+}
 
 /***************************************************************************/
 
@@ -66,21 +116,7 @@ void mcf_settimericr(unsigned int timer, unsigned int level)
 
 /***************************************************************************/
 
-int mcf_timerirqpending(int timer)
-{
-       unsigned int imr = 0;
-
-       switch (timer) {
-       case 1:  imr = 0x1; break;
-       case 2:  imr = 0x2; break;
-       default: break;
-       }
-       return (mcf_getiprh() & imr);
-}
-
-/***************************************************************************/
-
-void config_BSP(char *commandp, int size)
+void __init config_BSP(char *commandp, int size)
 {
        mcf_setimr(MCFSIM_IMR_MASKALL);
 
@@ -99,7 +135,7 @@ void config_BSP(char *commandp, int size)
        mcf_profilevector = 64+33;
        mach_reset = coldfire_reset;
 
-#ifdef MCF_BDM_DISABLE
+#ifdef CONFIG_BDM_DISABLE
        /*
         * Disable the BDM clocking.  This also turns off most of the rest of
         * the BDM device.  This is good for EMC reasons. This option is not
@@ -110,9 +146,19 @@ void config_BSP(char *commandp, int size)
 }
 
 /***************************************************************************/
-/* Board initialization */
 
-/********************************************************************/
+static int __init init_BSP(void)
+{
+       m532x_uarts_init();
+       platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
+       return 0;
+}
+
+arch_initcall(init_BSP);
+
+/***************************************************************************/
+/* Board initialization */
+/***************************************************************************/
 /* 
  * PLL min/max specifications
  */
index 2d3b62eba7ca8c75040912d25ab33bec477f6bee..648b8b778211639fbf54ef9e7fae9d0e9e708e01 100644 (file)
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/dma.h>
+#include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
+#include <asm/mcfuart.h>
 
 /***************************************************************************/
 
@@ -29,17 +29,51 @@ extern unsigned int mcf_timerlevel;
 
 /***************************************************************************/
 
-/*
- *     DMA channel base address table.
- */
-unsigned int   dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
-        MCF_MBAR + MCFDMA_BASE0,
-        MCF_MBAR + MCFDMA_BASE1,
-        MCF_MBAR + MCFDMA_BASE2,
-        MCF_MBAR + MCFDMA_BASE3,
+static struct mcf_platform_uart m5407_uart_platform[] = {
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE1,
+               .irq            = 73,
+       },
+       {
+               .mapbase        = MCF_MBAR + MCFUART_BASE2,
+               .irq            = 74,
+       },
+       { },
+};
+
+static struct platform_device m5407_uart = {
+       .name                   = "mcfuart",
+       .id                     = 0,
+       .dev.platform_data      = m5407_uart_platform,
 };
 
-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+static struct platform_device *m5407_devices[] __initdata = {
+       &m5407_uart,
+};
+
+/***************************************************************************/
+
+static void __init m5407_uart_init_line(int line, int irq)
+{
+       if (line == 0) {
+               writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+               writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
+       } else if (line == 1) {
+               writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+               writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+               mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
+       }
+}
+
+static void __init m5407_uarts_init(void)
+{
+       const int nrlines = ARRAY_SIZE(m5407_uart_platform);
+       int line;
+
+       for (line = 0; (line < nrlines); line++)
+               m5407_uart_init_line(line, m5407_uart_platform[line].irq);
+}
 
 /***************************************************************************/
 
@@ -76,21 +110,7 @@ void mcf_settimericr(unsigned int timer, unsigned int level)
 
 /***************************************************************************/
 
-int mcf_timerirqpending(int timer)
-{
-       unsigned int imr = 0;
-
-       switch (timer) {
-       case 1:  imr = MCFSIM_IMR_TIMER1; break;
-       case 2:  imr = MCFSIM_IMR_TIMER2; break;
-       default: break;
-       }
-       return (mcf_getipr() & imr);
-}
-
-/***************************************************************************/
-
-void config_BSP(char *commandp, int size)
+void __init config_BSP(char *commandp, int size)
 {
        mcf_setimr(MCFSIM_IMR_MASKALL);
 
@@ -105,3 +125,14 @@ void config_BSP(char *commandp, int size)
 }
 
 /***************************************************************************/
+
+static int __init init_BSP(void)
+{
+       m5407_uarts_init();
+       platform_add_devices(m5407_devices, ARRAY_SIZE(m5407_devices));
+       return 0;
+}
+
+arch_initcall(init_BSP);
+
+/***************************************************************************/
index 04cbc661d4bdc16faf3e09f932186114b2fe4295..9159fd05c9ac7638e64af74f8f9502936142d721 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/clocksource.h>
 #include <asm/setup.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #define TICKS_PER_JIFFY        10
 #endif
 
+static u32 m68328_tick_cnt;
+
+/***************************************************************************/
+
+static irqreturn_t hw_tick(int irq, void *dummy)
+{
+       /* Reset Timer1 */
+       TSTAT &= 0;
+
+       m68328_tick_cnt += TICKS_PER_JIFFY;
+       return arch_timer_interrupt(irq, dummy);
+}
+
 /***************************************************************************/
 
 static irqreturn_t hw_tick(int irq, void *dummy)
@@ -69,6 +83,33 @@ static struct irqaction m68328_timer_irq = {
        .handler = hw_tick,
 };
 
+/***************************************************************************/
+
+static cycle_t m68328_read_clk(void)
+{
+       unsigned long flags;
+       u32 cycles;
+
+       local_irq_save(flags);
+       cycles = m68328_tick_cnt + TCN;
+       local_irq_restore(flags);
+
+       return cycles;
+}
+
+/***************************************************************************/
+
+static struct clocksource m68328_clk = {
+       .name   = "timer",
+       .rating = 250,
+       .read   = m68328_read_clk,
+       .shift  = 20,
+       .mask   = CLOCKSOURCE_MASK(32),
+       .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/***************************************************************************/
+
 void hw_timer_init(void)
 {
        /* disable timer 1 */
@@ -84,19 +125,8 @@ void hw_timer_init(void)
 
        /* Enable timer 1 */
        TCTL |= TCTL_TEN;
-}
-
-/***************************************************************************/
-
-unsigned long hw_timer_offset(void)
-{
-       unsigned long ticks = TCN, offset = 0;
-
-       /* check for pending interrupt */
-       if (ticks < (TICKS_PER_JIFFY >> 1) && (ISR & (1 << TMR_IRQ_NUM)))
-               offset = 1000000 / HZ;
-       ticks = (ticks * 1000000 / HZ) / TICKS_PER_JIFFY;
-       return ticks + offset;
+       m68328_clk.mult = clocksource_hz2mult(TICKS_PER_JIFFY*HZ, m68328_clk.shift);
+       clocksource_register(&m68328_clk);
 }
 
 /***************************************************************************/
index 2b3196af811f3b92ee9b20e532a7d46acbb91310..ac629fa300994c2ba8b1328ab5a7d29b84ded27e 100644 (file)
@@ -103,11 +103,6 @@ void hw_timer_init(void)
   pquicc->timer_tgcr  = tgcr_save;
 }
 
-unsigned long hw_timer_offset(void)
-{
-  return 0;
-}
-
 void BSP_gettod (int *yearp, int *monp, int *dayp,
                   int *hourp, int *minp, int *secp)
 {
diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile
new file mode 100644 (file)
index 0000000..e5fff29
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Makefile for the m68knommu kernel.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs. You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+ifdef CONFIG_FULLDEBUG
+AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+obj-$(CONFIG_COLDFIRE) += dma.o entry.o vectors.o
+obj-$(CONFIG_M5206)    += timers.o
+obj-$(CONFIG_M5206e)   += timers.o
+obj-$(CONFIG_M520x)    += pit.o
+obj-$(CONFIG_M523x)    += pit.o
+obj-$(CONFIG_M5249)    += timers.o
+obj-$(CONFIG_M527x)    += pit.o
+obj-$(CONFIG_M5272)    += timers.o
+obj-$(CONFIG_M528x)    += pit.o
+obj-$(CONFIG_M5307)    += timers.o
+obj-$(CONFIG_M532x)    += timers.o
+obj-$(CONFIG_M5407)    += timers.o
+
+extra-y := head.o
diff --git a/arch/m68knommu/platform/coldfire/dma.c b/arch/m68knommu/platform/coldfire/dma.c
new file mode 100644 (file)
index 0000000..2b30cf1
--- /dev/null
@@ -0,0 +1,39 @@
+/***************************************************************************/
+
+/*
+ *     dma.c -- Freescale ColdFire DMA support
+ *
+ *     Copyright (C) 2007, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <asm/dma.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+
+/***************************************************************************/
+
+/*
+ *      DMA channel base address table.
+ */
+unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
+#ifdef MCFDMA_BASE0
+       MCF_MBAR + MCFDMA_BASE0,
+#endif
+#ifdef MCFDMA_BASE1
+       MCF_MBAR + MCFDMA_BASE1,
+#endif
+#ifdef MCFDMA_BASE2
+       MCF_MBAR + MCFDMA_BASE2,
+#endif
+#ifdef MCFDMA_BASE3
+       MCF_MBAR + MCFDMA_BASE3,
+#endif
+};
+
+unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/coldfire/entry.S b/arch/m68knommu/platform/coldfire/entry.S
new file mode 100644 (file)
index 0000000..b333731
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ *  linux/arch/m68knommu/platform/5307/entry.S
+ *
+ *  Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 2000  Lineo Inc. (www.lineo.com)
+ *  Copyright (C) 2004-2006  Macq Electronique SA. (www.macqel.com)
+ *
+ * Based on:
+ *
+ *  linux/arch/m68k/kernel/entry.S
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ * ColdFire support by Greg Ungerer (gerg@snapgear.com)
+ * 5307 fixes by David W. Miller
+ * linux 2.4 support David McCullough <davidm@snapgear.com>
+ * Bug, speed and maintainability fixes by Philippe De Muyter <phdm@macqel.be>
+ */
+
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/unistd.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/asm-offsets.h>
+#include <asm/entry.h>
+
+.bss
+
+sw_ksp:
+.long  0
+
+sw_usp:
+.long  0
+
+.text
+
+.globl system_call
+.globl resume
+.globl ret_from_exception
+.globl ret_from_signal
+.globl sys_call_table
+.globl ret_from_interrupt
+.globl inthandler
+.globl fasthandler
+
+enosys:
+       mov.l   #sys_ni_syscall,%d3
+       bra     1f
+
+ENTRY(system_call)
+       SAVE_ALL
+       move    #0x2000,%sr             /* enable intrs again */
+
+       cmpl    #NR_syscalls,%d0
+       jcc     enosys
+       lea     sys_call_table,%a0
+       lsll    #2,%d0                  /* movel %a0@(%d0:l:4),%d3 */
+       movel   %a0@(%d0),%d3
+       jeq     enosys
+
+1:
+       movel   %sp,%d2                 /* get thread_info pointer */
+       andl    #-THREAD_SIZE,%d2       /* at start of kernel stack */
+       movel   %d2,%a0
+       movel   %a0@,%a1                /* save top of frame */
+       movel   %sp,%a1@(TASK_THREAD+THREAD_ESP0)
+       btst    #(TIF_SYSCALL_TRACE%8),%a0@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
+       bnes    1f
+
+       movel   %d3,%a0
+       jbsr    %a0@
+       movel   %d0,%sp@(PT_D0)         /* save the return value */
+       jra     ret_from_exception
+1:
+       movel   #-ENOSYS,%d2            /* strace needs -ENOSYS in PT_D0 */
+       movel   %d2,PT_D0(%sp)          /* on syscall entry */
+       subql   #4,%sp
+       SAVE_SWITCH_STACK
+       jbsr    syscall_trace
+       RESTORE_SWITCH_STACK
+       addql   #4,%sp
+       movel   %d3,%a0
+       jbsr    %a0@
+       movel   %d0,%sp@(PT_D0)         /* save the return value */
+       subql   #4,%sp                  /* dummy return address */
+       SAVE_SWITCH_STACK
+       jbsr    syscall_trace
+
+ret_from_signal:
+       RESTORE_SWITCH_STACK
+       addql   #4,%sp
+
+ret_from_exception:
+       btst    #5,%sp@(PT_SR)          /* check if returning to kernel */
+       jeq     Luser_return            /* if so, skip resched, signals */
+
+Lkernel_return:
+       moveml  %sp@,%d1-%d5/%a0-%a2
+       lea     %sp@(32),%sp            /* space for 8 regs */
+       movel   %sp@+,%d0
+       addql   #4,%sp                  /* orig d0 */
+       addl    %sp@+,%sp               /* stk adj */
+       rte
+
+Luser_return:
+       movel   %sp,%d1                 /* get thread_info pointer */
+       andl    #-THREAD_SIZE,%d1       /* at base of kernel stack */
+       movel   %d1,%a0
+       movel   %a0@(TI_FLAGS),%d1      /* get thread_info->flags */
+       andl    #_TIF_WORK_MASK,%d1
+       jne     Lwork_to_do             /* still work to do */
+
+Lreturn:
+       move    #0x2700,%sr             /* disable intrs */
+       movel   sw_usp,%a0              /* get usp */
+       movel   %sp@(PT_PC),%a0@-       /* copy exception program counter */
+       movel   %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */
+       moveml  %sp@,%d1-%d5/%a0-%a2
+       lea     %sp@(32),%sp            /* space for 8 regs */
+       movel   %sp@+,%d0
+       addql   #4,%sp                  /* orig d0 */
+       addl    %sp@+,%sp               /* stk adj */
+       addql   #8,%sp                  /* remove exception */
+       movel   %sp,sw_ksp              /* save ksp */
+       subql   #8,sw_usp               /* set exception */
+       movel   sw_usp,%sp              /* restore usp */
+       rte
+
+Lwork_to_do:
+       movel   %a0@(TI_FLAGS),%d1      /* get thread_info->flags */
+       btst    #TIF_NEED_RESCHED,%d1
+       jne     reschedule
+
+       /* GERG: do we need something here for TRACEing?? */
+
+Lsignal_return:
+       subql   #4,%sp                  /* dummy return address */
+       SAVE_SWITCH_STACK
+       pea     %sp@(SWITCH_STACK_SIZE)
+       clrl    %sp@-
+       jsr     do_signal
+       addql   #8,%sp
+       RESTORE_SWITCH_STACK
+       addql   #4,%sp
+       jmp     Lreturn
+
+/*
+ * This is the generic interrupt handler (for all hardware interrupt
+ * sources). Calls upto high level code to do all the work.
+ */
+ENTRY(inthandler)
+       SAVE_ALL
+       moveq   #-1,%d0
+       movel   %d0,%sp@(PT_ORIG_D0)
+
+       movew   %sp@(PT_FORMATVEC),%d0  /* put exception # in d0 */
+       andl    #0x03fc,%d0             /* mask out vector only */
+
+       movel   %sp,%sp@-               /* push regs arg */
+       lsrl    #2,%d0                  /* calculate real vector # */
+       movel   %d0,%sp@-               /* push vector number */
+       jbsr    do_IRQ                  /* call high level irq handler */
+       lea     %sp@(8),%sp             /* pop args off stack */
+
+       bra     ret_from_interrupt      /* this was fallthrough */
+
+/*
+ * This is the fast interrupt handler (for certain hardware interrupt
+ * sources). Unlike the normal interrupt handler it just uses the
+ * current stack (doesn't care if it is user or kernel). It also
+ * doesn't bother doing the bottom half handlers.
+ */
+ENTRY(fasthandler)
+       SAVE_LOCAL
+
+       movew   %sp@(PT_FORMATVEC),%d0
+       andl    #0x03fc,%d0             /* mask out vector only */
+
+       movel   %sp,%sp@-               /* push regs arg */
+       lsrl    #2,%d0                  /* calculate real vector # */
+       movel   %d0,%sp@-               /* push vector number */
+       jbsr    do_IRQ                  /* call high level irq handler */
+       lea     %sp@(8),%sp             /* pop args off stack */
+
+       RESTORE_LOCAL
+
+ENTRY(ret_from_interrupt)
+       jeq     2f
+1:
+       RESTORE_ALL
+2:
+       moveb   %sp@(PT_SR),%d0
+       andl    #0x7,%d0
+       jhi     1b
+
+       /* check if we need to do software interrupts */
+       movel   irq_stat+CPUSTAT_SOFTIRQ_PENDING,%d0
+       jeq     ret_from_exception
+
+       pea     ret_from_exception
+       jmp     do_softirq
+
+/*
+ * Beware - when entering resume, prev (the current task) is
+ * in a0, next (the new task) is in a1,so don't change these
+ * registers until their contents are no longer needed.
+ * This is always called in supervisor mode, so don't bother to save
+ * and restore sr; user's process sr is actually in the stack.
+ */
+ENTRY(resume)
+       movel   %a0, %d1                        /* get prev thread in d1 */
+
+       movel   sw_usp,%d0                      /* save usp */
+       movel   %d0,%a0@(TASK_THREAD+THREAD_USP)
+
+       SAVE_SWITCH_STACK
+       movel   %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */
+       movel   %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
+       RESTORE_SWITCH_STACK
+
+       movel   %a1@(TASK_THREAD+THREAD_USP),%a0 /* restore thread user stack */
+       movel   %a0, sw_usp
+       rts
diff --git a/arch/m68knommu/platform/coldfire/head.S b/arch/m68knommu/platform/coldfire/head.S
new file mode 100644 (file)
index 0000000..b9aa0ca
--- /dev/null
@@ -0,0 +1,222 @@
+/*****************************************************************************/
+
+/*
+ *     head.S -- common startup code for ColdFire CPUs.
+ *
+ *     (C) Copyright 1999-2006, Greg Ungerer <gerg@snapgear.com>.
+ */
+
+/*****************************************************************************/
+
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/coldfire.h>
+#include <asm/mcfcache.h>
+#include <asm/mcfsim.h>
+
+/*****************************************************************************/
+
+/*
+ *     If we don't have a fixed memory size, then lets build in code
+ *     to auto detect the DRAM size. Obviously this is the prefered
+ *     method, and should work for most boards. It won't work for those
+ *     that do not have their RAM starting at address 0, and it only
+ *     works on SDRAM (not boards fitted with SRAM).
+ */
+#if CONFIG_RAMSIZE != 0
+.macro GET_MEM_SIZE
+       movel   #CONFIG_RAMSIZE,%d0     /* hard coded memory size */
+.endm
+
+#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
+      defined(CONFIG_M5249) || defined(CONFIG_M527x) || \
+      defined(CONFIG_M528x) || defined(CONFIG_M5307) || \
+      defined(CONFIG_M5407)
+/*
+ *     Not all these devices have exactly the same DRAM controller,
+ *     but the DCMR register is virtually identical - give or take
+ *     a couple of bits. The only exception is the 5272 devices, their
+ *     DRAM controller is quite different.
+ */
+.macro GET_MEM_SIZE
+       movel   MCF_MBAR+MCFSIM_DMR0,%d0 /* get mask for 1st bank */
+       btst    #0,%d0                  /* check if region enabled */
+       beq     1f
+       andl    #0xfffc0000,%d0
+       beq     1f
+       addl    #0x00040000,%d0         /* convert mask to size */
+1:
+       movel   MCF_MBAR+MCFSIM_DMR1,%d1 /* get mask for 2nd bank */
+       btst    #0,%d1                  /* check if region enabled */
+       beq     2f
+       andl    #0xfffc0000, %d1
+       beq     2f
+       addl    #0x00040000,%d1
+       addl    %d1,%d0                 /* total mem size in d0 */
+2:
+.endm
+
+#elif defined(CONFIG_M5272)
+.macro GET_MEM_SIZE
+       movel   MCF_MBAR+MCFSIM_CSOR7,%d0 /* get SDRAM address mask */
+       andil   #0xfffff000,%d0         /* mask out chip select options */
+       negl    %d0                     /* negate bits */
+.endm
+
+#elif defined(CONFIG_M520x)
+.macro GET_MEM_SIZE
+       clrl    %d0
+       movel   MCF_MBAR+MCFSIM_SDCS0, %d2 /* Get SDRAM chip select 0 config */
+       andl    #0x1f, %d2              /* Get only the chip select size */
+       beq     3f                      /* Check if it is enabled */
+       addql   #1, %d2                 /* Form exponent */
+       moveql  #1, %d0
+       lsll    %d2, %d0                /* 2 ^ exponent */
+3:
+       movel   MCF_MBAR+MCFSIM_SDCS1, %d2 /* Get SDRAM chip select 1 config */
+       andl    #0x1f, %d2              /* Get only the chip select size */
+       beq     4f                      /* Check if it is enabled */
+       addql   #1, %d2                 /* Form exponent */
+       moveql  #1, %d1
+       lsll    %d2, %d1                /* 2 ^ exponent */
+       addl    %d1, %d0                /* Total size of SDRAM in d0 */
+4:
+.endm
+
+#else
+#error "ERROR: I don't know how to probe your boards memory size?"
+#endif
+
+/*****************************************************************************/
+
+/*
+ *     Boards and platforms can do specific early hardware setup if
+ *     they need to. Most don't need this, define away if not required.
+ */
+#ifndef PLATFORM_SETUP
+#define        PLATFORM_SETUP
+#endif
+
+/*****************************************************************************/
+
+.global        _start
+.global _rambase
+.global _ramvec
+.global        _ramstart
+.global        _ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *     During startup we store away the RAM setup. These are not in the
+ *     bss, since their values are determined and written before the bss
+ *     has been cleared.
+ */
+_rambase:
+.long  0
+_ramvec:
+.long  0
+_ramstart:
+.long  0
+_ramend:
+.long  0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *     This is the codes first entry point. This is where it all
+ *     begins...
+ */
+
+_start:
+       nop                                     /* filler */
+       movew   #0x2700, %sr                    /* no interrupts */
+
+       /*
+        *      Do any platform or board specific setup now. Most boards
+        *      don't need anything. Those exceptions are define this in
+        *      their board specific includes.
+        */
+       PLATFORM_SETUP
+
+       /*
+        *      Create basic memory configuration. Set VBR accordingly,
+        *      and size memory.
+        */
+       movel   #CONFIG_VECTORBASE,%a7
+       movec   %a7,%VBR                        /* set vectors addr */
+       movel   %a7,_ramvec
+
+       movel   #CONFIG_RAMBASE,%a7             /* mark the base of RAM */
+       movel   %a7,_rambase
+
+       GET_MEM_SIZE                            /* macro code determines size */
+       addl    %a7,%d0
+       movel   %d0,_ramend                     /* set end ram addr */
+
+       /*
+        *      Now that we know what the memory is, lets enable cache
+        *      and get things moving. This is Coldfire CPU specific.
+        */
+       CACHE_ENABLE                            /* enable CPU cache */
+
+
+#ifdef CONFIG_ROMFS_FS
+       /*
+        *      Move ROM filesystem above bss :-)
+        */
+       lea     _sbss,%a0                       /* get start of bss */
+       lea     _ebss,%a1                       /* set up destination  */
+       movel   %a0,%a2                         /* copy of bss start */
+
+       movel   8(%a0),%d0                      /* get size of ROMFS */
+       addql   #8,%d0                          /* allow for rounding */
+       andl    #0xfffffffc, %d0                /* whole words */
+
+       addl    %d0,%a0                         /* copy from end */
+       addl    %d0,%a1                         /* copy from end */
+       movel   %a1,_ramstart                   /* set start of ram */
+
+_copy_romfs:
+       movel   -(%a0),%d0                      /* copy dword */
+       movel   %d0,-(%a1)
+       cmpl    %a0,%a2                         /* check if at end */
+       bne     _copy_romfs
+
+#else /* CONFIG_ROMFS_FS */
+       lea     _ebss,%a1
+       movel   %a1,_ramstart
+#endif /* CONFIG_ROMFS_FS */
+
+
+       /*
+        *      Zero out the bss region.
+        */
+       lea     _sbss,%a0                       /* get start of bss */
+       lea     _ebss,%a1                       /* get end of bss */
+       clrl    %d0                             /* set value */
+_clear_bss:
+       movel   %d0,(%a0)+                      /* clear each word */
+       cmpl    %a0,%a1                         /* check if at end */
+       bne     _clear_bss
+
+       /*
+        *      Load the current task pointer and stack.
+        */
+       lea     init_thread_union,%a0
+       lea     THREAD_SIZE(%a0),%sp
+
+       /*
+        *      Assember start up done, start code proper.
+        */
+       jsr     start_kernel                    /* start Linux kernel */
+
+_exit:
+       jmp     _exit                           /* should never get here */
+
+/*****************************************************************************/
diff --git a/arch/m68knommu/platform/coldfire/pit.c b/arch/m68knommu/platform/coldfire/pit.c
new file mode 100644 (file)
index 0000000..4290638
--- /dev/null
@@ -0,0 +1,113 @@
+/***************************************************************************/
+
+/*
+ *     pit.c -- Freescale ColdFire PIT timer. Currently this type of
+ *              hardware timer only exists in the Freescale ColdFire
+ *              5270/5271, 5282 and 5208 CPUs. No doubt newer ColdFire
+ *              family members will probably use it too.
+ *
+ *     Copyright (C) 1999-2008, Greg Ungerer (gerg@snapgear.com)
+ *     Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clocksource.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/coldfire.h>
+#include <asm/mcfpit.h>
+#include <asm/mcfsim.h>
+
+/***************************************************************************/
+
+/*
+ *     By default use timer1 as the system clock timer.
+ */
+#define        FREQ    ((MCF_CLK / 2) / 64)
+#define        TA(a)   (MCF_IPSBAR + MCFPIT_BASE1 + (a))
+#define        INTC0   (MCF_IPSBAR + MCFICM_INTC0)
+
+static u32 pit_cycles_per_jiffy;
+static u32 pit_cnt;
+
+/***************************************************************************/
+
+static irqreturn_t pit_tick(int irq, void *dummy)
+{
+       u16 pcsr;
+
+       /* Reset the ColdFire timer */
+       pcsr = __raw_readw(TA(MCFPIT_PCSR));
+       __raw_writew(pcsr | MCFPIT_PCSR_PIF, TA(MCFPIT_PCSR));
+
+       pit_cnt += pit_cycles_per_jiffy;
+       return arch_timer_interrupt(irq, dummy);
+}
+
+/***************************************************************************/
+
+static struct irqaction pit_irq = {
+       .name    = "timer",
+       .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .handler = pit_tick,
+};
+
+/***************************************************************************/
+
+static cycle_t pit_read_clk(void)
+{
+       unsigned long flags;
+       u32 cycles;
+       u16 pcntr;
+
+       local_irq_save(flags);
+       pcntr = __raw_readw(TA(MCFPIT_PCNTR));
+       cycles = pit_cnt;
+       local_irq_restore(flags);
+
+       return cycles + pit_cycles_per_jiffy - pcntr;
+}
+
+/***************************************************************************/
+
+static struct clocksource pit_clk = {
+       .name   = "pit",
+       .rating = 250,
+       .read   = pit_read_clk,
+       .shift  = 20,
+       .mask   = CLOCKSOURCE_MASK(32),
+       .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/***************************************************************************/
+
+void hw_timer_init(void)
+{
+       u32 imr;
+
+       setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &pit_irq);
+
+       __raw_writeb(ICR_INTRCONF, INTC0 + MCFINTC_ICR0 + MCFINT_PIT1);
+       imr = __raw_readl(INTC0 + MCFPIT_IMR);
+       imr &= ~MCFPIT_IMR_IBIT;
+       __raw_writel(imr, INTC0 + MCFPIT_IMR);
+
+       /* Set up PIT timer 1 as poll clock */
+       pit_cycles_per_jiffy = FREQ / HZ;
+       __raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR));
+       __raw_writew(pit_cycles_per_jiffy, TA(MCFPIT_PMR));
+       __raw_writew(MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW |
+               MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64, TA(MCFPIT_PCSR));
+
+       pit_clk.mult = clocksource_hz2mult(FREQ, pit_clk.shift);
+       clocksource_register(&pit_clk);
+}
+
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/coldfire/timers.c b/arch/m68knommu/platform/coldfire/timers.c
new file mode 100644 (file)
index 0000000..a60213e
--- /dev/null
@@ -0,0 +1,175 @@
+/***************************************************************************/
+
+/*
+ *     timers.c -- generic ColdFire hardware timer support.
+ *
+ *     Copyright (C) 1999-2008, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/profile.h>
+#include <linux/clocksource.h>
+#include <asm/io.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+
+/***************************************************************************/
+
+/*
+ *     By default use timer1 as the system clock timer.
+ */
+#define        FREQ    (MCF_BUSCLK / 16)
+#define        TA(a)   (MCF_MBAR + MCFTIMER_BASE1 + (a))
+
+/*
+ *     Default the timer and vector to use for ColdFire. Some ColdFire
+ *     CPU's and some boards may want different. Their sub-architecture
+ *     startup code (in config.c) can change these if they want.
+ */
+unsigned int   mcf_timervector = 29;
+unsigned int   mcf_profilevector = 31;
+unsigned int   mcf_timerlevel = 5;
+
+/*
+ *     These provide the underlying interrupt vector support.
+ *     Unfortunately it is a little different on each ColdFire.
+ */
+extern void mcf_settimericr(int timer, int level);
+void coldfire_profile_init(void);
+
+#if defined(CONFIG_M532x)
+#define        __raw_readtrr   __raw_readl
+#define        __raw_writetrr  __raw_writel
+#else
+#define        __raw_readtrr   __raw_readw
+#define        __raw_writetrr  __raw_writew
+#endif
+
+static u32 mcftmr_cycles_per_jiffy;
+static u32 mcftmr_cnt;
+
+/***************************************************************************/
+
+static irqreturn_t mcftmr_tick(int irq, void *dummy)
+{
+       /* Reset the ColdFire timer */
+       __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER));
+
+       mcftmr_cnt += mcftmr_cycles_per_jiffy;
+       return arch_timer_interrupt(irq, dummy);
+}
+
+/***************************************************************************/
+
+static struct irqaction mcftmr_timer_irq = {
+       .name    = "timer",
+       .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .handler = mcftmr_tick,
+};
+
+/***************************************************************************/
+
+static cycle_t mcftmr_read_clk(void)
+{
+       unsigned long flags;
+       u32 cycles;
+       u16 tcn;
+
+       local_irq_save(flags);
+       tcn = __raw_readw(TA(MCFTIMER_TCN));
+       cycles = mcftmr_cnt;
+       local_irq_restore(flags);
+
+       return cycles + tcn;
+}
+
+/***************************************************************************/
+
+static struct clocksource mcftmr_clk = {
+       .name   = "tmr",
+       .rating = 250,
+       .read   = mcftmr_read_clk,
+       .shift  = 20,
+       .mask   = CLOCKSOURCE_MASK(32),
+       .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/***************************************************************************/
+
+void hw_timer_init(void)
+{
+       setup_irq(mcf_timervector, &mcftmr_timer_irq);
+
+       __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
+       mcftmr_cycles_per_jiffy = FREQ / HZ;
+       __raw_writetrr(mcftmr_cycles_per_jiffy, TA(MCFTIMER_TRR));
+       __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+               MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR));
+
+       mcftmr_clk.mult = clocksource_hz2mult(FREQ, mcftmr_clk.shift);
+       clocksource_register(&mcftmr_clk);
+
+       mcf_settimericr(1, mcf_timerlevel);
+
+#ifdef CONFIG_HIGHPROFILE
+       coldfire_profile_init();
+#endif
+}
+
+/***************************************************************************/
+#ifdef CONFIG_HIGHPROFILE
+/***************************************************************************/
+
+/*
+ *     By default use timer2 as the profiler clock timer.
+ */
+#define        PA(a)   (MCF_MBAR + MCFTIMER_BASE2 + (a))
+
+/*
+ *     Choose a reasonably fast profile timer. Make it an odd value to
+ *     try and get good coverage of kernel operations.
+ */
+#define        PROFILEHZ       1013
+
+/*
+ *     Use the other timer to provide high accuracy profiling info.
+ */
+irqreturn_t coldfire_profile_tick(int irq, void *dummy)
+{
+       /* Reset ColdFire timer2 */
+       __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, PA(MCFTIMER_TER));
+       if (current->pid)
+               profile_tick(CPU_PROFILING, regs);
+       return IRQ_HANDLED;
+}
+
+/***************************************************************************/
+
+void coldfire_profile_init(void)
+{
+       printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ);
+
+       /* Set up TIMER 2 as high speed profile clock */
+       __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR));
+
+       __raw_writetrr(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR));
+       __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
+               MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR));
+
+       request_irq(mcf_profilevector, coldfire_profile_tick,
+               (IRQF_DISABLED | IRQ_FLG_FAST), "profile timer", NULL);
+       mcf_settimericr(2, 7);
+}
+
+/***************************************************************************/
+#endif /* CONFIG_HIGHPROFILE */
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/coldfire/vectors.c b/arch/m68knommu/platform/coldfire/vectors.c
new file mode 100644 (file)
index 0000000..6cf8946
--- /dev/null
@@ -0,0 +1,105 @@
+/***************************************************************************/
+
+/*
+ *     linux/arch/m68knommu/platform/5307/vectors.c
+ *
+ *     Copyright (C) 1999-2007, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/mcfwdebug.h>
+
+/***************************************************************************/
+
+#ifdef TRAP_DBG_INTERRUPT
+
+asmlinkage void dbginterrupt_c(struct frame *fp)
+{
+       extern void dump(struct pt_regs *fp);
+       printk(KERN_DEBUG "%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__);
+       dump((struct pt_regs *) fp);
+       asm("halt");
+}
+
+#endif
+
+/***************************************************************************/
+
+extern e_vector        *_ramvec;
+
+void set_evector(int vecnum, void (*handler)(void))
+{
+       if (vecnum >= 0 && vecnum <= 255)
+               _ramvec[vecnum] = handler;
+}
+
+/***************************************************************************/
+
+/* Assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void __init init_vectors(void)
+{
+       int i;
+
+       /*
+        *      There is a common trap handler and common interrupt
+        *      handler that handle almost every vector. We treat
+        *      the system call and bus error special, they get their
+        *      own first level handlers.
+        */
+       for (i = 3; (i <= 23); i++)
+               _ramvec[i] = trap;
+       for (i = 33; (i <= 63); i++)
+               _ramvec[i] = trap;
+       for (i = 24; (i <= 31); i++)
+               _ramvec[i] = inthandler;
+       for (i = 64; (i < 255); i++)
+               _ramvec[i] = inthandler;
+       _ramvec[255] = 0;
+
+       _ramvec[2] = buserr;
+       _ramvec[32] = system_call;
+
+#ifdef TRAP_DBG_INTERRUPT
+       _ramvec[12] = dbginterrupt;
+#endif
+}
+
+/***************************************************************************/
+
+void enable_vector(unsigned int irq)
+{
+       /* Currently no action on ColdFire */
+}
+
+void disable_vector(unsigned int irq)
+{
+       /* Currently no action on ColdFire */
+}
+
+void ack_vector(unsigned int irq)
+{
+       /* Currently no action on ColdFire */
+}
+
+/***************************************************************************/
+
+void coldfire_reset(void)
+{
+       HARD_RESET_NOW();
+}
+
+/***************************************************************************/
index c5cfd4b04a830d81ef1ca59ced3db5a35a6590bb..5803f11c77fc07cc961f2610a9f0ec1b9f7aeef7 100644 (file)
@@ -184,7 +184,7 @@ static void pci_dma_dev_setup_pasemi(struct pci_dev *dev)
        if (dev->vendor == 0x1959 && dev->device == 0xa007 &&
            !firmware_has_feature(FW_FEATURE_LPAR)) {
                dev->dev.archdata.dma_ops = &dma_direct_ops;
-               dev->dev.archdata.dma_data = 0;
+               return;
        }
 #endif
 
index 20657744c86444904958afde1576161636bfb067..f406b1f22791a8f65de6ba133c85cec37c6ad557 100644 (file)
@@ -7,7 +7,7 @@
 #include <asm/ptrace.h>
 #include <asm/psr.h>
 
-       .section .sched.text
+       .section .sched.text, "ax"
        .align  4
 
        .globl          ___down_read
index f9c71d64eba1c2c42dbcefac3e7762d0ba471d2f..6a4f956a2f7a4a99d7388d0dafed55e65b506c30 100644 (file)
@@ -10,7 +10,7 @@
        .align 4;               \
 99:    retl;                   \
         mov    %o1, %o0;       \
-       .section __ex_table;    \
+       .section __ex_table,"a";\
        .align 4;               \
        .word 98b, 99b;         \
        .text;                  \
index f10e4529ee3743b770730de61d03c02ad08aa961..814d5f7a45e1c3e9fe132f094d48a5ce7f050e08 100644 (file)
@@ -10,7 +10,7 @@
        .align 4;               \
 99:    retl;                   \
         mov    %o1, %o0;       \
-       .section __ex_table;    \
+       .section __ex_table,"a";\
        .align 4;               \
        .word 98b, 99b;         \
        .text;                  \
index 75f0e6b951d61b9ff5ef5ecf4187bac65ea785bf..1a4cc5654de4668a5d751644115031e87555a53d 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <asm/rwsem-const.h>
 
-       .section        .sched.text
+       .section        .sched.text, "ax"
 
        .globl          __down_read
 __down_read:
index da8f4129780bd8d25801eeee7742986ec92dddbc..8978e98bed5b60dfa8fb34eca332c68d5f941fb0 100644 (file)
@@ -143,7 +143,7 @@ mcore-$(CONFIG_X86_ES7000)  := arch/x86/mach-default/
 
 # RDC R-321x subarch support
 mflags-$(CONFIG_X86_RDC321X)   := -Iinclude/asm-x86/mach-rdc321x
-mcore-$(CONFIG_X86_RDC321X)    := arch/x86/mach-default
+mcore-$(CONFIG_X86_RDC321X)    := arch/x86/mach-default/
 core-$(CONFIG_X86_RDC321X)     += arch/x86/mach-rdc321x/
 
 # default subarch .h files
index 34aebc6e75896011fae724cf0d44b8b19868c31c..8b552c6dd2e7b053248eff254abc103cbef38e87 100644 (file)
@@ -56,8 +56,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.7.2"
-#define DRV_MODULE_RELDATE     "January 21, 2008"
+#define DRV_MODULE_VERSION     "1.7.3"
+#define DRV_MODULE_RELDATE     "January 29, 2008"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -265,6 +265,18 @@ bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val)
        spin_unlock_bh(&bp->indirect_lock);
 }
 
+static void
+bnx2_shmem_wr(struct bnx2 *bp, u32 offset, u32 val)
+{
+       bnx2_reg_wr_ind(bp, bp->shmem_base + offset, val);
+}
+
+static u32
+bnx2_shmem_rd(struct bnx2 *bp, u32 offset)
+{
+       return (bnx2_reg_rd_ind(bp, bp->shmem_base + offset));
+}
+
 static void
 bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
 {
@@ -685,7 +697,7 @@ bnx2_report_fw_link(struct bnx2 *bp)
        else
                fw_link_status = BNX2_LINK_STATUS_LINK_DOWN;
 
-       REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status);
+       bnx2_shmem_wr(bp, BNX2_LINK_STATUS, fw_link_status);
 }
 
 static char *
@@ -980,6 +992,42 @@ bnx2_copper_linkup(struct bnx2 *bp)
        return 0;
 }
 
+static void
+bnx2_init_rx_context0(struct bnx2 *bp)
+{
+       u32 val, rx_cid_addr = GET_CID_ADDR(RX_CID);
+
+       val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
+       val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
+       val |= 0x02 << 8;
+
+       if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+               u32 lo_water, hi_water;
+
+               if (bp->flow_ctrl & FLOW_CTRL_TX)
+                       lo_water = BNX2_L2CTX_LO_WATER_MARK_DEFAULT;
+               else
+                       lo_water = BNX2_L2CTX_LO_WATER_MARK_DIS;
+               if (lo_water >= bp->rx_ring_size)
+                       lo_water = 0;
+
+               hi_water = bp->rx_ring_size / 4;
+
+               if (hi_water <= lo_water)
+                       lo_water = 0;
+
+               hi_water /= BNX2_L2CTX_HI_WATER_MARK_SCALE;
+               lo_water /= BNX2_L2CTX_LO_WATER_MARK_SCALE;
+
+               if (hi_water > 0xf)
+                       hi_water = 0xf;
+               else if (hi_water == 0)
+                       lo_water = 0;
+               val |= lo_water | (hi_water << BNX2_L2CTX_HI_WATER_MARK_SHIFT);
+       }
+       bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val);
+}
+
 static int
 bnx2_set_mac_link(struct bnx2 *bp)
 {
@@ -1044,6 +1092,9 @@ bnx2_set_mac_link(struct bnx2 *bp)
        /* Acknowledge the interrupt. */
        REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE);
 
+       if (CHIP_NUM(bp) == CHIP_NUM_5709)
+               bnx2_init_rx_context0(bp);
+
        return 0;
 }
 
@@ -1378,14 +1429,14 @@ bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
 
        if (pause_adv & (ADVERTISE_1000XPAUSE | ADVERTISE_PAUSE_CAP))
                speed_arg |= BNX2_NETLINK_SET_LINK_FC_SYM_PAUSE;
-       if (pause_adv & (ADVERTISE_1000XPSE_ASYM | ADVERTISE_1000XPSE_ASYM))
+       if (pause_adv & (ADVERTISE_1000XPSE_ASYM | ADVERTISE_PAUSE_ASYM))
                speed_arg |= BNX2_NETLINK_SET_LINK_FC_ASYM_PAUSE;
 
        if (port == PORT_TP)
                speed_arg |= BNX2_NETLINK_SET_LINK_PHY_APP_REMOTE |
                             BNX2_NETLINK_SET_LINK_ETH_AT_WIRESPEED;
 
-       REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB_ARG0, speed_arg);
+       bnx2_shmem_wr(bp, BNX2_DRV_MB_ARG0, speed_arg);
 
        spin_unlock_bh(&bp->phy_lock);
        bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_CMD_SET_LINK, 0);
@@ -1530,9 +1581,9 @@ bnx2_set_default_remote_link(struct bnx2 *bp)
        u32 link;
 
        if (bp->phy_port == PORT_TP)
-               link = REG_RD_IND(bp, bp->shmem_base + BNX2_RPHY_COPPER_LINK);
+               link = bnx2_shmem_rd(bp, BNX2_RPHY_COPPER_LINK);
        else
-               link = REG_RD_IND(bp, bp->shmem_base + BNX2_RPHY_SERDES_LINK);
+               link = bnx2_shmem_rd(bp, BNX2_RPHY_SERDES_LINK);
 
        if (link & BNX2_NETLINK_SET_LINK_ENABLE_AUTONEG) {
                bp->req_line_speed = 0;
@@ -1584,7 +1635,7 @@ bnx2_set_default_link(struct bnx2 *bp)
 
                bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
 
-               reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
+               reg = bnx2_shmem_rd(bp, BNX2_PORT_HW_CFG_CONFIG);
                reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
                if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
                        bp->autoneg = 0;
@@ -1616,7 +1667,7 @@ bnx2_remote_phy_event(struct bnx2 *bp)
        u8 link_up = bp->link_up;
        u8 old_port;
 
-       msg = REG_RD_IND(bp, bp->shmem_base + BNX2_LINK_STATUS);
+       msg = bnx2_shmem_rd(bp, BNX2_LINK_STATUS);
 
        if (msg & BNX2_LINK_STATUS_HEART_BEAT_EXPIRED)
                bnx2_send_heart_beat(bp);
@@ -1693,7 +1744,7 @@ bnx2_set_remote_link(struct bnx2 *bp)
 {
        u32 evt_code;
 
-       evt_code = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_EVT_CODE_MB);
+       evt_code = bnx2_shmem_rd(bp, BNX2_FW_EVT_CODE_MB);
        switch (evt_code) {
                case BNX2_FW_EVT_CODE_LINK_EVENT:
                        bnx2_remote_phy_event(bp);
@@ -1905,14 +1956,13 @@ bnx2_init_5708s_phy(struct bnx2 *bp)
                bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
        }
 
-       val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) &
+       val = bnx2_shmem_rd(bp, BNX2_PORT_HW_CFG_CONFIG) &
              BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK;
 
        if (val) {
                u32 is_backplane;
 
-               is_backplane = REG_RD_IND(bp, bp->shmem_base +
-                                         BNX2_SHARED_HW_CFG_CONFIG);
+               is_backplane = bnx2_shmem_rd(bp, BNX2_SHARED_HW_CFG_CONFIG);
                if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) {
                        bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
                                       BCM5708S_BLK_ADDR_TX_MISC);
@@ -2111,13 +2161,13 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
        bp->fw_wr_seq++;
        msg_data |= bp->fw_wr_seq;
 
-       REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
+       bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data);
 
        /* wait for an acknowledgement. */
        for (i = 0; i < (FW_ACK_TIME_OUT_MS / 10); i++) {
                msleep(10);
 
-               val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB);
+               val = bnx2_shmem_rd(bp, BNX2_FW_MB);
 
                if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ))
                        break;
@@ -2134,7 +2184,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
                msg_data &= ~BNX2_DRV_MSG_CODE;
                msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
 
-               REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
+               bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data);
 
                return -EBUSY;
        }
@@ -2226,7 +2276,7 @@ bnx2_init_context(struct bnx2 *bp)
 
                        /* Zero out the context. */
                        for (offset = 0; offset < PHY_CTX_SIZE; offset += 4)
-                               CTX_WR(bp, vcid_addr, offset, 0);
+                               bnx2_ctx_wr(bp, vcid_addr, offset, 0);
                }
        }
 }
@@ -2251,11 +2301,12 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp)
        good_mbuf_cnt = 0;
 
        /* Allocate a bunch of mbufs and save the good ones in an array. */
-       val = REG_RD_IND(bp, BNX2_RBUF_STATUS1);
+       val = bnx2_reg_rd_ind(bp, BNX2_RBUF_STATUS1);
        while (val & BNX2_RBUF_STATUS1_FREE_COUNT) {
-               REG_WR_IND(bp, BNX2_RBUF_COMMAND, BNX2_RBUF_COMMAND_ALLOC_REQ);
+               bnx2_reg_wr_ind(bp, BNX2_RBUF_COMMAND,
+                               BNX2_RBUF_COMMAND_ALLOC_REQ);
 
-               val = REG_RD_IND(bp, BNX2_RBUF_FW_BUF_ALLOC);
+               val = bnx2_reg_rd_ind(bp, BNX2_RBUF_FW_BUF_ALLOC);
 
                val &= BNX2_RBUF_FW_BUF_ALLOC_VALUE;
 
@@ -2265,7 +2316,7 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp)
                        good_mbuf_cnt++;
                }
 
-               val = REG_RD_IND(bp, BNX2_RBUF_STATUS1);
+               val = bnx2_reg_rd_ind(bp, BNX2_RBUF_STATUS1);
        }
 
        /* Free the good ones back to the mbuf pool thus discarding
@@ -2276,7 +2327,7 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp)
                val = good_mbuf[good_mbuf_cnt];
                val = (val << 9) | val | 1;
 
-               REG_WR_IND(bp, BNX2_RBUF_FW_BUF_FREE, val);
+               bnx2_reg_wr_ind(bp, BNX2_RBUF_FW_BUF_FREE, val);
        }
        kfree(good_mbuf);
        return 0;
@@ -3151,10 +3202,10 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
        int rc;
 
        /* Halt the CPU. */
-       val = REG_RD_IND(bp, cpu_reg->mode);
+       val = bnx2_reg_rd_ind(bp, cpu_reg->mode);
        val |= cpu_reg->mode_value_halt;
-       REG_WR_IND(bp, cpu_reg->mode, val);
-       REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear);
+       bnx2_reg_wr_ind(bp, cpu_reg->mode, val);
+       bnx2_reg_wr_ind(bp, cpu_reg->state, cpu_reg->state_value_clear);
 
        /* Load the Text area. */
        offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
@@ -3167,7 +3218,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
                        return rc;
 
                for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
-                       REG_WR_IND(bp, offset, le32_to_cpu(fw->text[j]));
+                       bnx2_reg_wr_ind(bp, offset, le32_to_cpu(fw->text[j]));
                }
        }
 
@@ -3177,7 +3228,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
                int j;
 
                for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
-                       REG_WR_IND(bp, offset, fw->data[j]);
+                       bnx2_reg_wr_ind(bp, offset, fw->data[j]);
                }
        }
 
@@ -3187,7 +3238,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
                int j;
 
                for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
-                       REG_WR_IND(bp, offset, 0);
+                       bnx2_reg_wr_ind(bp, offset, 0);
                }
        }
 
@@ -3197,7 +3248,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
                int j;
 
                for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
-                       REG_WR_IND(bp, offset, 0);
+                       bnx2_reg_wr_ind(bp, offset, 0);
                }
        }
 
@@ -3208,19 +3259,19 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
                int j;
 
                for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
-                       REG_WR_IND(bp, offset, fw->rodata[j]);
+                       bnx2_reg_wr_ind(bp, offset, fw->rodata[j]);
                }
        }
 
        /* Clear the pre-fetch instruction. */
-       REG_WR_IND(bp, cpu_reg->inst, 0);
-       REG_WR_IND(bp, cpu_reg->pc, fw->start_addr);
+       bnx2_reg_wr_ind(bp, cpu_reg->inst, 0);
+       bnx2_reg_wr_ind(bp, cpu_reg->pc, fw->start_addr);
 
        /* Start the CPU. */
-       val = REG_RD_IND(bp, cpu_reg->mode);
+       val = bnx2_reg_rd_ind(bp, cpu_reg->mode);
        val &= ~cpu_reg->mode_value_halt;
-       REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear);
-       REG_WR_IND(bp, cpu_reg->mode, val);
+       bnx2_reg_wr_ind(bp, cpu_reg->state, cpu_reg->state_value_clear);
+       bnx2_reg_wr_ind(bp, cpu_reg->mode, val);
 
        return 0;
 }
@@ -3833,7 +3884,7 @@ bnx2_init_nvram(struct bnx2 *bp)
        }
 
 get_flash_size:
-       val = REG_RD_IND(bp, bp->shmem_base + BNX2_SHARED_HW_CFG_CONFIG2);
+       val = bnx2_shmem_rd(bp, BNX2_SHARED_HW_CFG_CONFIG2);
        val &= BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK;
        if (val)
                bp->flash_size = val;
@@ -4142,14 +4193,14 @@ bnx2_init_remote_phy(struct bnx2 *bp)
        if (!(bp->phy_flags & BNX2_PHY_FLAG_SERDES))
                return;
 
-       val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_CAP_MB);
+       val = bnx2_shmem_rd(bp, BNX2_FW_CAP_MB);
        if ((val & BNX2_FW_CAP_SIGNATURE_MASK) != BNX2_FW_CAP_SIGNATURE)
                return;
 
        if (val & BNX2_FW_CAP_REMOTE_PHY_CAPABLE) {
                bp->phy_flags |= BNX2_PHY_FLAG_REMOTE_PHY_CAP;
 
-               val = REG_RD_IND(bp, bp->shmem_base + BNX2_LINK_STATUS);
+               val = bnx2_shmem_rd(bp, BNX2_LINK_STATUS);
                if (val & BNX2_LINK_STATUS_SERDES_LINK)
                        bp->phy_port = PORT_FIBRE;
                else
@@ -4167,8 +4218,7 @@ bnx2_init_remote_phy(struct bnx2 *bp)
                        }
                        sig = BNX2_DRV_ACK_CAP_SIGNATURE |
                              BNX2_FW_CAP_REMOTE_PHY_CAPABLE;
-                       REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_ACK_CAP_MB,
-                                  sig);
+                       bnx2_shmem_wr(bp, BNX2_DRV_ACK_CAP_MB, sig);
                }
        }
 }
@@ -4204,8 +4254,8 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
 
        /* Deposit a driver reset signature so the firmware knows that
         * this is a soft reset. */
-       REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE,
-                  BNX2_DRV_RESET_SIGNATURE_MAGIC);
+       bnx2_shmem_wr(bp, BNX2_DRV_RESET_SIGNATURE,
+                     BNX2_DRV_RESET_SIGNATURE_MAGIC);
 
        /* Do a dummy read to force the chip to complete all current transaction
         * before we issue a reset. */
@@ -4438,18 +4488,21 @@ bnx2_init_chip(struct bnx2 *bp)
        }
 
        if (bp->flags & BNX2_FLAG_USING_MSIX) {
+               u32 base = ((BNX2_TX_VEC - 1) * BNX2_HC_SB_CONFIG_SIZE) +
+                          BNX2_HC_SB_CONFIG_1;
+
                REG_WR(bp, BNX2_HC_MSIX_BIT_VECTOR,
                       BNX2_HC_MSIX_BIT_VECTOR_VAL);
 
-               REG_WR(bp, BNX2_HC_SB_CONFIG_1,
+               REG_WR(bp, base,
                        BNX2_HC_SB_CONFIG_1_TX_TMR_MODE |
                        BNX2_HC_SB_CONFIG_1_ONE_SHOT);
 
-               REG_WR(bp, BNX2_HC_TX_QUICK_CONS_TRIP_1,
+               REG_WR(bp, base + BNX2_HC_TX_QUICK_CONS_TRIP_OFF,
                        (bp->tx_quick_cons_trip_int << 16) |
                         bp->tx_quick_cons_trip);
 
-               REG_WR(bp, BNX2_HC_TX_TICKS_1,
+               REG_WR(bp, base + BNX2_HC_TX_TICKS_OFF,
                        (bp->tx_ticks_int << 16) | bp->tx_ticks);
 
                val |= BNX2_HC_CONFIG_SB_ADDR_INC_128B;
@@ -4509,6 +4562,7 @@ static void
 bnx2_init_tx_context(struct bnx2 *bp, u32 cid)
 {
        u32 val, offset0, offset1, offset2, offset3;
+       u32 cid_addr = GET_CID_ADDR(cid);
 
        if (CHIP_NUM(bp) == CHIP_NUM_5709) {
                offset0 = BNX2_L2CTX_TYPE_XI;
@@ -4522,16 +4576,16 @@ bnx2_init_tx_context(struct bnx2 *bp, u32 cid)
                offset3 = BNX2_L2CTX_TBDR_BHADDR_LO;
        }
        val = BNX2_L2CTX_TYPE_TYPE_L2 | BNX2_L2CTX_TYPE_SIZE_L2;
-       CTX_WR(bp, GET_CID_ADDR(cid), offset0, val);
+       bnx2_ctx_wr(bp, cid_addr, offset0, val);
 
        val = BNX2_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16);
-       CTX_WR(bp, GET_CID_ADDR(cid), offset1, val);
+       bnx2_ctx_wr(bp, cid_addr, offset1, val);
 
        val = (u64) bp->tx_desc_mapping >> 32;
-       CTX_WR(bp, GET_CID_ADDR(cid), offset2, val);
+       bnx2_ctx_wr(bp, cid_addr, offset2, val);
 
        val = (u64) bp->tx_desc_mapping & 0xffffffff;
-       CTX_WR(bp, GET_CID_ADDR(cid), offset3, val);
+       bnx2_ctx_wr(bp, cid_addr, offset3, val);
 }
 
 static void
@@ -4601,36 +4655,38 @@ bnx2_init_rx_ring(struct bnx2 *bp)
        bnx2_init_rxbd_rings(bp->rx_desc_ring, bp->rx_desc_mapping,
                             bp->rx_buf_use_size, bp->rx_max_ring);
 
-       CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, 0);
+       bnx2_init_rx_context0(bp);
+
+       if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+               val = REG_RD(bp, BNX2_MQ_MAP_L2_5);
+               REG_WR(bp, BNX2_MQ_MAP_L2_5, val | BNX2_MQ_MAP_L2_5_ARM);
+       }
+
+       bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, 0);
        if (bp->rx_pg_ring_size) {
                bnx2_init_rxbd_rings(bp->rx_pg_desc_ring,
                                     bp->rx_pg_desc_mapping,
                                     PAGE_SIZE, bp->rx_max_pg_ring);
                val = (bp->rx_buf_use_size << 16) | PAGE_SIZE;
-               CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, val);
-               CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_RBDC_KEY,
+               bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, val);
+               bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_RBDC_KEY,
                       BNX2_L2CTX_RBDC_JUMBO_KEY);
 
                val = (u64) bp->rx_pg_desc_mapping[0] >> 32;
-               CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_HI, val);
+               bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_HI, val);
 
                val = (u64) bp->rx_pg_desc_mapping[0] & 0xffffffff;
-               CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_LO, val);
+               bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_LO, val);
 
                if (CHIP_NUM(bp) == CHIP_NUM_5709)
                        REG_WR(bp, BNX2_MQ_MAP_L2_3, BNX2_MQ_MAP_L2_3_DEFAULT);
        }
 
-       val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
-       val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
-       val |= 0x02 << 8;
-       CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val);
-
        val = (u64) bp->rx_desc_mapping[0] >> 32;
-       CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val);
+       bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val);
 
        val = (u64) bp->rx_desc_mapping[0] & 0xffffffff;
-       CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val);
+       bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val);
 
        ring_prod = prod = bnapi->rx_pg_prod;
        for (i = 0; i < bp->rx_pg_ring_size; i++) {
@@ -5003,9 +5059,9 @@ bnx2_do_mem_test(struct bnx2 *bp, u32 start, u32 size)
 
                for (offset = 0; offset < size; offset += 4) {
 
-                       REG_WR_IND(bp, start + offset, test_pattern[i]);
+                       bnx2_reg_wr_ind(bp, start + offset, test_pattern[i]);
 
-                       if (REG_RD_IND(bp, start + offset) !=
+                       if (bnx2_reg_rd_ind(bp, start + offset) !=
                                test_pattern[i]) {
                                return -ENODEV;
                        }
@@ -5315,7 +5371,7 @@ bnx2_5706_serdes_has_link(struct bnx2 *bp)
        bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
        bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
 
-       if (an_dbg & MISC_SHDW_AN_DBG_NOSYNC)
+       if (an_dbg & (MISC_SHDW_AN_DBG_NOSYNC | MISC_SHDW_AN_DBG_RUDI_INVALID))
                return 0;
 
        bnx2_write_phy(bp, MII_BNX2_DSP_ADDRESS, MII_EXPAND_REG1);
@@ -5440,7 +5496,8 @@ bnx2_timer(unsigned long data)
 
        bnx2_send_heart_beat(bp);
 
-       bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT);
+       bp->stats_blk->stat_FwRxDrop =
+               bnx2_reg_rd_ind(bp, BNX2_FW_RX_DROP_COUNT);
 
        /* workaround occasional corrupted counters */
        if (CHIP_NUM(bp) == CHIP_NUM_5708 && bp->stats_ticks)
@@ -7155,20 +7212,20 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 
        bnx2_init_nvram(bp);
 
-       reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE);
+       reg = bnx2_reg_rd_ind(bp, BNX2_SHM_HDR_SIGNATURE);
 
        if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) ==
            BNX2_SHM_HDR_SIGNATURE_SIG) {
                u32 off = PCI_FUNC(pdev->devfn) << 2;
 
-               bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0 + off);
+               bp->shmem_base = bnx2_reg_rd_ind(bp, BNX2_SHM_HDR_ADDR_0 + off);
        } else
                bp->shmem_base = HOST_VIEW_SHMEM_BASE;
 
        /* Get the permanent MAC address.  First we need to make sure the
         * firmware is actually running.
         */
-       reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE);
+       reg = bnx2_shmem_rd(bp, BNX2_DEV_INFO_SIGNATURE);
 
        if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
            BNX2_DEV_INFO_SIGNATURE_MAGIC) {
@@ -7177,7 +7234,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                goto err_out_unmap;
        }
 
-       reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);
+       reg = bnx2_shmem_rd(bp, BNX2_DEV_INFO_BC_REV);
        for (i = 0, j = 0; i < 3; i++) {
                u8 num, k, skip0;
 
@@ -7191,7 +7248,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                if (i != 2)
                        bp->fw_version[j++] = '.';
        }
-       reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_FEATURE);
+       reg = bnx2_shmem_rd(bp, BNX2_PORT_FEATURE);
        if (reg & BNX2_PORT_FEATURE_WOL_ENABLED)
                bp->wol = 1;
 
@@ -7199,34 +7256,33 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                bp->flags |= BNX2_FLAG_ASF_ENABLE;
 
                for (i = 0; i < 30; i++) {
-                       reg = REG_RD_IND(bp, bp->shmem_base +
-                                            BNX2_BC_STATE_CONDITION);
+                       reg = bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION);
                        if (reg & BNX2_CONDITION_MFW_RUN_MASK)
                                break;
                        msleep(10);
                }
        }
-       reg = REG_RD_IND(bp, bp->shmem_base + BNX2_BC_STATE_CONDITION);
+       reg = bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION);
        reg &= BNX2_CONDITION_MFW_RUN_MASK;
        if (reg != BNX2_CONDITION_MFW_RUN_UNKNOWN &&
            reg != BNX2_CONDITION_MFW_RUN_NONE) {
                int i;
-               u32 addr = REG_RD_IND(bp, bp->shmem_base + BNX2_MFW_VER_PTR);
+               u32 addr = bnx2_shmem_rd(bp, BNX2_MFW_VER_PTR);
 
                bp->fw_version[j++] = ' ';
                for (i = 0; i < 3; i++) {
-                       reg = REG_RD_IND(bp, addr + i * 4);
+                       reg = bnx2_reg_rd_ind(bp, addr + i * 4);
                        reg = swab32(reg);
                        memcpy(&bp->fw_version[j], &reg, 4);
                        j += 4;
                }
        }
 
-       reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER);
+       reg = bnx2_shmem_rd(bp, BNX2_PORT_HW_CFG_MAC_UPPER);
        bp->mac_addr[0] = (u8) (reg >> 8);
        bp->mac_addr[1] = (u8) reg;
 
-       reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER);
+       reg = bnx2_shmem_rd(bp, BNX2_PORT_HW_CFG_MAC_LOWER);
        bp->mac_addr[2] = (u8) (reg >> 24);
        bp->mac_addr[3] = (u8) (reg >> 16);
        bp->mac_addr[4] = (u8) (reg >> 8);
@@ -7265,8 +7321,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
        bp->phy_port = PORT_TP;
        if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
                bp->phy_port = PORT_FIBRE;
-               reg = REG_RD_IND(bp, bp->shmem_base +
-                                    BNX2_SHARED_HW_CFG_CONFIG);
+               reg = bnx2_shmem_rd(bp, BNX2_SHARED_HW_CFG_CONFIG);
                if (!(reg & BNX2_SHARED_HW_CFG_GIG_LINK_ON_VAUX)) {
                        bp->flags |= BNX2_FLAG_NO_WOL;
                        bp->wol = 0;
index d8e034700c363420e1aef24dd27a01bf56358da8..3aa0364942e294047096f544b1644430f6483bb5 100644 (file)
@@ -348,6 +348,12 @@ struct l2_fhdr {
 #define BNX2_L2CTX_BD_PRE_READ                         0x00000000
 #define BNX2_L2CTX_CTX_SIZE                            0x00000000
 #define BNX2_L2CTX_CTX_TYPE                            0x00000000
+#define BNX2_L2CTX_LO_WATER_MARK_DEFAULT                32
+#define BNX2_L2CTX_LO_WATER_MARK_SCALE                  4
+#define BNX2_L2CTX_LO_WATER_MARK_DIS                    0
+#define BNX2_L2CTX_HI_WATER_MARK_SHIFT                  4
+#define BNX2_L2CTX_HI_WATER_MARK_SCALE                  16
+#define BNX2_L2CTX_WATER_MARKS_MSK                      0x000000ff
 #define BNX2_L2CTX_CTX_TYPE_SIZE_L2                     ((0x20/20)<<16)
 #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE             (0xf<<28)
 #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_UNDEFINED   (0<<28)
@@ -4494,6 +4500,9 @@ struct l2_fhdr {
 #define BNX2_MQ_MAP_L2_3_ENA                            (0x1L<<31)
 #define BNX2_MQ_MAP_L2_3_DEFAULT                        0x82004646
 
+#define BNX2_MQ_MAP_L2_5                               0x00003d34
+#define BNX2_MQ_MAP_L2_5_ARM                            (0x3L<<26)
+
 /*
  *  tsch_reg definition
  *  offset: 0x4c00
@@ -5510,6 +5519,15 @@ struct l2_fhdr {
 #define BNX2_HC_PERIODIC_TICKS_8_HC_PERIODIC_TICKS      (0xffffL<<0)
 #define BNX2_HC_PERIODIC_TICKS_8_HC_INT_PERIODIC_TICKS  (0xffffL<<16)
 
+#define BNX2_HC_SB_CONFIG_SIZE (BNX2_HC_SB_CONFIG_2 - BNX2_HC_SB_CONFIG_1)
+#define BNX2_HC_COMP_PROD_TRIP_OFF     (BNX2_HC_COMP_PROD_TRIP_1 -     \
+                                        BNX2_HC_SB_CONFIG_1)
+#define BNX2_HC_COM_TICKS_OFF  (BNX2_HC_COM_TICKS_1 - BNX2_HC_SB_CONFIG_1)
+#define BNX2_HC_CMD_TICKS_OFF  (BNX2_HC_CMD_TICKS_1 - BNX2_HC_SB_CONFIG_1)
+#define BNX2_HC_TX_QUICK_CONS_TRIP_OFF (BNX2_HC_TX_QUICK_CONS_TRIP_1 - \
+                                        BNX2_HC_SB_CONFIG_1)
+#define BNX2_HC_TX_TICKS_OFF   (BNX2_HC_TX_TICKS_1 - BNX2_HC_SB_CONFIG_1)
+
 
 /*
  *  txp_reg definition
@@ -6346,11 +6364,12 @@ struct l2_fhdr {
 #define MII_BNX2_DSP_EXPAND_REG                         0x0f00
 #define MII_EXPAND_REG1                                  (MII_BNX2_DSP_EXPAND_REG | 1)
 #define MII_EXPAND_REG1_RUDI_C                    0x20
-#define MII_EXPAND_SERDES_CTL                    (MII_BNX2_DSP_EXPAND_REG | 2)
+#define MII_EXPAND_SERDES_CTL                    (MII_BNX2_DSP_EXPAND_REG | 3)
 
 #define MII_BNX2_MISC_SHADOW                   0x1c
 #define MISC_SHDW_AN_DBG                        0x6800
 #define MISC_SHDW_AN_DBG_NOSYNC                          0x0002
+#define MISC_SHDW_AN_DBG_RUDI_INVALID            0x0100
 #define MISC_SHDW_MODE_CTL                      0x7c00
 #define MISC_SHDW_MODE_CTL_SIG_DET               0x0010
 
@@ -6395,7 +6414,7 @@ struct l2_fhdr {
 
 #define RX_COPY_THRESH                 128
 
-#define BNX2_MISC_ENABLE_DEFAULT       0x7ffffff
+#define BNX2_MISC_ENABLE_DEFAULT       0x17ffffff
 
 #define DMA_READ_CHANS 5
 #define DMA_WRITE_CHANS        3
@@ -6795,9 +6814,6 @@ struct bnx2 {
        int                     irq_nvecs;
 };
 
-static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset);
-static void bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val);
-
 #define REG_RD(bp, offset)                                     \
        readl(bp->regview + offset)
 
@@ -6807,19 +6823,6 @@ static void bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val);
 #define REG_WR16(bp, offset, val)                              \
        writew(val, bp->regview + offset)
 
-#define REG_RD_IND(bp, offset)                                 \
-       bnx2_reg_rd_ind(bp, offset)
-
-#define REG_WR_IND(bp, offset, val)                            \
-       bnx2_reg_wr_ind(bp, offset, val)
-
-/* Indirect context access.  Unlike the MBQ_WR, these macros will not
- * trigger a chip event. */
-static void bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val);
-
-#define CTX_WR(bp, cid_addr, offset, val)                      \
-       bnx2_ctx_wr(bp, cid_addr, offset, val)
-
 struct cpu_reg {
        u32 mode;
        u32 mode_value_halt;
index c1ad4dd38c32e4d87613e7d79f519ae337178964..3b839d4626fe8ab9132ba1cfd7a4b3b19762bfc9 100644 (file)
@@ -2168,760 +2168,761 @@ static struct fw_info bnx2_cp_fw_06 = {
 };
 
 static u8 bnx2_RXP_b06FwText[] = {
-       0xec, 0x5b, 0x6d, 0x6c, 0x5c, 0x57, 0x5a, 0x7e, 0xef, 0x99, 0xb1, 0x3d,
-       0x76, 0x6c, 0xe7, 0xda, 0x99, 0xa6, 0x93, 0xe2, 0x6e, 0x67, 0xec, 0x6b,
-       0x7b, 0xba, 0x36, 0xe5, 0x3a, 0x4c, 0x5b, 0xaf, 0x18, 0xb6, 0xc3, 0x1d,
-       0x27, 0x75, 0x77, 0x83, 0xe4, 0xb6, 0x61, 0x37, 0x82, 0xae, 0xb0, 0x66,
-       0x12, 0x51, 0x84, 0x10, 0x21, 0x82, 0xaa, 0x2c, 0x5d, 0x65, 0x34, 0x76,
-       0x53, 0xb7, 0x3b, 0xf1, 0x0c, 0x89, 0x4b, 0xf8, 0xd8, 0x1f, 0xee, 0xd8,
-       0x4e, 0x0a, 0x9a, 0x78, 0xba, 0xcb, 0x8f, 0x5d, 0x56, 0x4d, 0x63, 0xd2,
-       0x12, 0xfa, 0x03, 0x89, 0x16, 0x56, 0x50, 0x89, 0x85, 0x86, 0x24, 0xdb,
-       0x14, 0x09, 0x41, 0x77, 0x01, 0x6d, 0xa1, 0x69, 0x2f, 0xcf, 0x73, 0xee,
-       0xbd, 0xc9, 0xc4, 0x35, 0x6c, 0x7f, 0xf0, 0xf3, 0x1e, 0xc9, 0xba, 0xf7,
-       0x9e, 0xf3, 0x9e, 0xf7, 0xbc, 0xdf, 0x1f, 0x67, 0x92, 0xdf, 0xe8, 0x96,
-       0x2e, 0xf1, 0x47, 0x0f, 0xfe, 0x32, 0x87, 0x9f, 0x3c, 0x72, 0xef, 0x3d,
-       0xf6, 0x3d, 0xfc, 0x8e, 0xb4, 0x49, 0x94, 0x4f, 0x43, 0xc2, 0x11, 0x8e,
-       0x70, 0x84, 0x23, 0x1c, 0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70,
-       0x84, 0x23, 0x1c, 0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70, 0x84,
-       0x23, 0x1c, 0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70, 0x84, 0x23,
-       0x1c, 0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70, 0x84, 0x23, 0x1c,
-       0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70, 0x84, 0x23, 0x1c, 0xe1,
-       0x08, 0x47, 0x38, 0xc2, 0xf1, 0xff, 0x39, 0x22, 0x22, 0x26, 0x9f, 0x3d,
-       0xfe, 0x9f, 0xc4, 0x54, 0x56, 0x8e, 0x38, 0x96, 0xc4, 0x22, 0xd9, 0xd5,
-       0x27, 0x8a, 0x96, 0x48, 0xae, 0x31, 0x96, 0xcc, 0xcb, 0x87, 0x6e, 0x29,
-       0x1e, 0x15, 0xce, 0xdf, 0x99, 0xbd, 0x7e, 0xf4, 0xdc, 0xfd, 0xa9, 0xf7,
-       0x96, 0x23, 0x12, 0x33, 0xb3, 0x6f, 0x4c, 0x98, 0x23, 0x12, 0x1b, 0xc0,
-       0x9e, 0xaf, 0x8d, 0xbe, 0xbc, 0x5d, 0x7a, 0x03, 0x5c, 0x22, 0xf5, 0x4a,
-       0xca, 0xde, 0x2b, 0x63, 0xe6, 0x05, 0x89, 0x4a, 0x0e, 0x67, 0x9c, 0x6e,
-       0x88, 0x94, 0x2b, 0x06, 0x71, 0x48, 0xb9, 0x11, 0x93, 0x4b, 0x11, 0x42,
-       0x7d, 0xcb, 0x70, 0xaa, 0x1f, 0xb9, 0xb9, 0x28, 0xce, 0xb5, 0xf0, 0xde,
-       0x0c, 0xe6, 0x63, 0xa2, 0xb2, 0xa9, 0x84, 0x13, 0x99, 0x96, 0xc2, 0x92,
-       0xeb, 0xce, 0xdb, 0xb7, 0x03, 0x47, 0xbf, 0xcc, 0x5b, 0xde, 0xb7, 0x63,
-       0x7f, 0xda, 0x9c, 0x92, 0x1d, 0x98, 0x8b, 0x88, 0xb2, 0xee, 0xc0, 0xdf,
-       0x57, 0x0d, 0x67, 0xa5, 0x5b, 0xca, 0x55, 0xc9, 0x39, 0x76, 0x0c, 0xf3,
-       0x09, 0x99, 0xab, 0x26, 0x0d, 0xe7, 0xa4, 0x21, 0xc5, 0x0c, 0xde, 0x9b,
-       0xae, 0x38, 0xf6, 0x47, 0xae, 0x63, 0x11, 0xff, 0x92, 0xe1, 0x9c, 0xf9,
-       0xc8, 0x55, 0x96, 0x65, 0x16, 0x84, 0xdf, 0x09, 0x29, 0x37, 0x89, 0x87,
-       0xef, 0xc4, 0x73, 0xc9, 0x3d, 0x37, 0x9a, 0x90, 0x6f, 0x34, 0xe3, 0xf2,
-       0xf5, 0xa6, 0x29, 0x2f, 0x35, 0x07, 0xe4, 0x7c, 0xd3, 0x75, 0xbf, 0x6e,
-       0xbb, 0xee, 0x1b, 0xf8, 0xfb, 0x81, 0x7d, 0x83, 0x66, 0x8c, 0x92, 0x31,
-       0xd5, 0xfc, 0xc3, 0x6e, 0xe9, 0x4d, 0x25, 0x45, 0x75, 0xe3, 0xcc, 0x84,
-       0xcc, 0x57, 0x2b, 0xc6, 0xc3, 0x67, 0x16, 0x8d, 0x99, 0x33, 0x35, 0x23,
-       0x7f, 0x26, 0x8a, 0x39, 0x29, 0x95, 0xed, 0x17, 0x8d, 0x7c, 0x73, 0xc1,
-       0x78, 0xe4, 0x4c, 0xaf, 0xa6, 0xad, 0x5c, 0xdd, 0x09, 0xda, 0xae, 0x83,
-       0x26, 0xca, 0x34, 0x65, 0xfe, 0x3c, 0xc4, 0xec, 0x54, 0xc8, 0x57, 0xbb,
-       0xe4, 0xe2, 0x5c, 0x77, 0x5d, 0x95, 0x75, 0x8f, 0x3a, 0x19, 0xcb, 0x2c,
-       0x0b, 0xe9, 0xd3, 0x73, 0xe7, 0x23, 0xa0, 0x39, 0x2f, 0xa7, 0x41, 0x7f,
-       0xb7, 0x91, 0x3f, 0x15, 0x05, 0x1d, 0x32, 0x10, 0x11, 0xee, 0x1b, 0x4e,
-       0x14, 0xa4, 0x81, 0x33, 0xc4, 0x54, 0x59, 0xca, 0x11, 0x34, 0x83, 0x96,
-       0x6f, 0x54, 0xc1, 0x43, 0x15, 0x3c, 0x54, 0xc9, 0x5b, 0x52, 0xce, 0x8d,
-       0x06, 0xbc, 0xb9, 0xee, 0x5f, 0xdb, 0xa4, 0x3d, 0x95, 0xcc, 0xa9, 0x80,
-       0x4f, 0xd7, 0xfd, 0xbe, 0x4d, 0x5e, 0xc9, 0x8f, 0xeb, 0xbe, 0x64, 0x53,
-       0x86, 0xee, 0x79, 0x65, 0x55, 0xc0, 0x8b, 0x05, 0xfc, 0x94, 0xef, 0x22,
-       0x78, 0x58, 0x00, 0x7f, 0xa7, 0xc1, 0x5b, 0x0d, 0x74, 0xfc, 0xa8, 0xf3,
-       0x4a, 0x46, 0x7e, 0xf4, 0x86, 0xbc, 0x92, 0x94, 0x71, 0x61, 0x55, 0x41,
-       0xd6, 0xdb, 0xa4, 0xb0, 0x6c, 0xca, 0xec, 0x6a, 0xb0, 0x3f, 0xd0, 0xfb,
-       0x61, 0xd9, 0x57, 0xed, 0x87, 0x6c, 0x28, 0xcb, 0x94, 0x2d, 0x42, 0xbd,
-       0x95, 0xd3, 0x4a, 0xc4, 0x28, 0xd8, 0x47, 0xb5, 0xbe, 0x57, 0x2d, 0xc9,
-       0x15, 0x6c, 0xca, 0x51, 0x92, 0x05, 0xbb, 0x94, 0x88, 0xc2, 0xbe, 0x56,
-       0xad, 0x92, 0x19, 0x15, 0xca, 0x31, 0x95, 0xf8, 0x32, 0x64, 0x79, 0xa8,
-       0x22, 0xb9, 0xcf, 0x55, 0x02, 0x19, 0x7b, 0xf2, 0xfd, 0x7c, 0xe5, 0xa7,
-       0x7b, 0xa4, 0x4b, 0x7d, 0xaa, 0x4d, 0x7e, 0x15, 0x7b, 0x89, 0xfb, 0x96,
-       0xbd, 0xd8, 0xe7, 0xc1, 0x79, 0x7b, 0x53, 0x07, 0x44, 0x08, 0x5b, 0x1e,
-       0x6a, 0xf3, 0x7c, 0xc2, 0x70, 0xac, 0x52, 0x22, 0x02, 0xb8, 0x82, 0x94,
-       0x27, 0xfc, 0xb9, 0x36, 0xc7, 0xba, 0x1e, 0x99, 0xb7, 0x53, 0xc9, 0xb2,
-       0x5c, 0x8f, 0x5c, 0xb4, 0xf5, 0x5c, 0xa7, 0x63, 0xb9, 0xb2, 0x06, 0xec,
-       0xcf, 0xc0, 0xfe, 0x2f, 0x80, 0xa3, 0x5f, 0xae, 0xe8, 0xf9, 0x1e, 0xec,
-       0x4f, 0xb7, 0x01, 0x67, 0x97, 0xa4, 0xd2, 0x75, 0xcc, 0x5f, 0xf4, 0xe6,
-       0xfb, 0x3c, 0xbc, 0xe5, 0xa1, 0x2e, 0x8d, 0x5b, 0xe4, 0x45, 0x6f, 0xfe,
-       0x36, 0x0f, 0x77, 0xf9, 0x6e, 0xcc, 0x03, 0xff, 0xc8, 0xf4, 0xa8, 0xa1,
-       0xe7, 0x77, 0xd1, 0x7f, 0x7e, 0xa9, 0x72, 0x3d, 0xb2, 0x66, 0xbb, 0x92,
-       0x9f, 0x18, 0x99, 0x1e, 0x31, 0x3c, 0x7c, 0xc7, 0xbc, 0x7d, 0x77, 0x7a,
-       0xf8, 0x46, 0xa6, 0xd3, 0x86, 0x87, 0x6f, 0xb5, 0xa2, 0xf7, 0x4a, 0xa1,
-       0x42, 0xd8, 0x91, 0x69, 0xcb, 0xb8, 0x53, 0x66, 0xfb, 0x46, 0xa6, 0x07,
-       0x0d, 0xf5, 0xa9, 0x6d, 0x1e, 0x1f, 0xa9, 0x80, 0x86, 0x6d, 0x9a, 0x06,
-       0x9e, 0xab, 0xe7, 0x87, 0x1d, 0xab, 0x7c, 0xf7, 0x36, 0x7d, 0x3e, 0xcf,
-       0xd4, 0x73, 0x77, 0x93, 0x2e, 0x9e, 0x5d, 0x9c, 0xb8, 0xe5, 0xdc, 0x1f,
-       0xbf, 0x29, 0x9f, 0xad, 0xce, 0xe4, 0x79, 0x12, 0x8b, 0x66, 0xa3, 0x13,
-       0xf3, 0x95, 0xc3, 0xe2, 0x54, 0x93, 0x32, 0x37, 0xde, 0x29, 0xb3, 0xe6,
-       0xd0, 0xec, 0x3e, 0x61, 0xac, 0x89, 0x4d, 0x14, 0x7d, 0x1d, 0xe6, 0xc5,
-       0x90, 0x39, 0xf0, 0xb8, 0xaf, 0x21, 0x31, 0x03, 0xf0, 0x43, 0x8d, 0xa8,
-       0x3c, 0xdb, 0x34, 0xa4, 0x5d, 0xfb, 0x67, 0xca, 0xdc, 0x80, 0x1d, 0x3e,
-       0x5d, 0xa5, 0x1d, 0xd3, 0x66, 0x25, 0x57, 0x87, 0x9d, 0x9e, 0xd7, 0xbe,
-       0xda, 0x45, 0xbd, 0x96, 0x4a, 0x02, 0x57, 0xcc, 0x5a, 0x66, 0x5d, 0x3a,
-       0x24, 0x37, 0x23, 0x25, 0xae, 0xfb, 0xbe, 0x93, 0x58, 0x91, 0x73, 0xb0,
-       0x01, 0x31, 0x9d, 0x0c, 0xe7, 0x09, 0xdf, 0x02, 0x6b, 0x7a, 0x7e, 0x17,
-       0x81, 0xdf, 0x15, 0x33, 0x84, 0x95, 0x92, 0x93, 0xa1, 0xef, 0xc1, 0x16,
-       0x9b, 0xbb, 0x7a, 0xbc, 0xd8, 0x86, 0xd8, 0x12, 0xef, 0x86, 0x8f, 0x7f,
-       0x0a, 0xfe, 0x37, 0x60, 0x38, 0xa7, 0x5c, 0xb7, 0x68, 0x4b, 0x5c, 0x09,
-       0xfd, 0x0f, 0xbe, 0xde, 0xe4, 0x5a, 0x37, 0xe6, 0xc5, 0x9c, 0xb3, 0xfb,
-       0xc0, 0x9f, 0xeb, 0x4e, 0xdb, 0x49, 0x29, 0xdb, 0xdb, 0xb1, 0xaf, 0x4d,
-       0xfa, 0x2c, 0xda, 0x3b, 0x7d, 0x7a, 0x1b, 0xce, 0x33, 0xf8, 0xdd, 0x8b,
-       0xf3, 0x7a, 0x30, 0x97, 0x98, 0xa3, 0x1f, 0x67, 0xc6, 0xc0, 0xbf, 0x17,
-       0x2f, 0x45, 0xde, 0x06, 0xad, 0xdc, 0xa3, 0xe1, 0x62, 0x1d, 0xd9, 0x8c,
-       0x5c, 0xab, 0xec, 0x92, 0x4b, 0x71, 0xf2, 0x0f, 0x9c, 0x55, 0xc4, 0xc4,
-       0xb8, 0x01, 0xfa, 0x13, 0x7e, 0xdc, 0xdb, 0xe1, 0x7f, 0x1b, 0x77, 0x79,
-       0x67, 0x88, 0x19, 0xc9, 0xf6, 0x4a, 0x5e, 0xcf, 0x89, 0x52, 0x13, 0xdb,
-       0xfc, 0xf5, 0x5e, 0x63, 0xef, 0x29, 0x25, 0xa3, 0xf7, 0x21, 0x66, 0xe1,
-       0xac, 0x8b, 0x96, 0xeb, 0x5e, 0xb4, 0xbf, 0x0f, 0x9f, 0x57, 0xd2, 0x66,
-       0xfd, 0x63, 0xaf, 0x74, 0x41, 0x9e, 0x55, 0xa3, 0x45, 0x86, 0x09, 0x39,
-       0x56, 0xe5, 0x9e, 0x92, 0x44, 0x2d, 0xc2, 0x10, 0xfe, 0xef, 0x01, 0x17,
-       0x91, 0x0e, 0xf8, 0xe2, 0x05, 0x3b, 0x4e, 0x7a, 0xb7, 0x7b, 0xf0, 0x7d,
-       0x38, 0x83, 0xb4, 0xd3, 0xf7, 0x5c, 0xed, 0x7b, 0x4e, 0x44, 0xe5, 0xa6,
-       0x96, 0xe0, 0x49, 0xe3, 0x94, 0xb7, 0xd3, 0x87, 0x50, 0x2f, 0x73, 0xa3,
-       0x25, 0x53, 0x69, 0x5d, 0x8b, 0xe4, 0x2b, 0x77, 0xc9, 0xbc, 0x8d, 0xf3,
-       0xac, 0x28, 0x68, 0x66, 0x9c, 0x19, 0x2e, 0x45, 0x14, 0x3c, 0xac, 0x9f,
-       0xb2, 0x0a, 0x68, 0x7d, 0x0b, 0xe7, 0x95, 0x8c, 0xa8, 0xc5, 0x33, 0xbe,
-       0xe4, 0xcb, 0x87, 0x76, 0x67, 0x8b, 0x53, 0xe9, 0xe6, 0x37, 0xe8, 0xe8,
-       0xd2, 0x74, 0x44, 0xb2, 0x5a, 0x77, 0x86, 0xca, 0x52, 0x96, 0x6d, 0x3e,
-       0x3d, 0xb7, 0xe0, 0x01, 0x1f, 0xdc, 0x6b, 0x61, 0x6f, 0x0c, 0x34, 0xf6,
-       0xb4, 0xd0, 0xdf, 0x45, 0x78, 0xc8, 0x2a, 0xe6, 0x9f, 0xa1, 0xf9, 0x36,
-       0x3c, 0xbe, 0x03, 0x59, 0x7d, 0x1b, 0xb2, 0xfa, 0xc0, 0x1d, 0xdd, 0x4d,
-       0x1c, 0x19, 0xe0, 0x60, 0x1e, 0x62, 0xbc, 0x62, 0x8c, 0x32, 0x6f, 0xe0,
-       0x82, 0x1f, 0xa8, 0x48, 0xb6, 0x5b, 0xf2, 0xa6, 0xce, 0x01, 0x80, 0x9d,
-       0x14, 0x1d, 0xe3, 0x2d, 0xf2, 0xe8, 0x7f, 0x5b, 0x29, 0x6d, 0x37, 0x85,
-       0x1a, 0xf3, 0xc0, 0x57, 0x40, 0xdb, 0x46, 0x4a, 0x69, 0xd6, 0xba, 0x21,
-       0x73, 0x89, 0xb5, 0x65, 0xdf, 0x90, 0xb5, 0x8a, 0xda, 0xd9, 0x2e, 0xdb,
-       0x65, 0x06, 0x32, 0xaa, 0x4f, 0x22, 0x7f, 0x8e, 0x77, 0x4b, 0xe4, 0x1e,
-       0xe6, 0x81, 0x04, 0x68, 0xdd, 0x48, 0x99, 0x72, 0xdd, 0x55, 0x23, 0xd8,
-       0x3f, 0x0e, 0x3d, 0xec, 0xa7, 0x4e, 0x95, 0x0f, 0x47, 0x98, 0x08, 0x65,
-       0xde, 0xdf, 0x2e, 0xc4, 0xcd, 0xb5, 0xb1, 0x84, 0x29, 0x9c, 0xef, 0x84,
-       0x5e, 0xb9, 0x97, 0xfc, 0x79, 0x7b, 0x3e, 0xce, 0x5f, 0xb0, 0x4e, 0x99,
-       0x51, 0x76, 0xb0, 0x31, 0xf0, 0xe8, 0xd8, 0x3f, 0xeb, 0xcb, 0xe6, 0x76,
-       0xb9, 0x64, 0x8a, 0x51, 0xb7, 0x6f, 0x6b, 0x91, 0x1f, 0x79, 0xee, 0xdb,
-       0xc4, 0x33, 0x71, 0x6c, 0xcd, 0xf7, 0xc1, 0x1a, 0xcf, 0xf4, 0xce, 0x9e,
-       0xb7, 0x36, 0x52, 0x51, 0xb9, 0x55, 0xbe, 0xd0, 0xa5, 0x14, 0x2b, 0xb4,
-       0x8d, 0x76, 0x29, 0xa0, 0xfe, 0xb0, 0x77, 0x23, 0xa8, 0x3c, 0xa2, 0x64,
-       0xe2, 0x3e, 0xe2, 0xfc, 0x3b, 0xf2, 0x34, 0x99, 0x54, 0x86, 0x14, 0xec,
-       0xce, 0x16, 0x7d, 0x71, 0xae, 0xd5, 0xb6, 0xbf, 0xed, 0xdb, 0xf6, 0x07,
-       0xee, 0xc4, 0xee, 0x40, 0xef, 0x90, 0xd7, 0xc7, 0xf6, 0x08, 0xf4, 0xfc,
-       0x7f, 0xed, 0xa1, 0xad, 0xc4, 0x36, 0xed, 0x29, 0x6d, 0xb1, 0x67, 0x87,
-       0xc8, 0x17, 0xe8, 0x43, 0x3d, 0x7e, 0xcc, 0x08, 0x7c, 0x2a, 0xc0, 0x03,
-       0xdd, 0x68, 0x5b, 0xe5, 0xdc, 0x56, 0xbe, 0x48, 0x1c, 0xc4, 0xc5, 0xbd,
-       0x84, 0x09, 0x72, 0x2a, 0xd4, 0x21, 0x5b, 0xe6, 0x55, 0x8c, 0x69, 0xbc,
-       0x2b, 0xc4, 0xa1, 0xd6, 0xfc, 0xca, 0x39, 0x13, 0xdf, 0x53, 0x78, 0x5a,
-       0x52, 0x68, 0xd0, 0x9f, 0xb8, 0x9f, 0xf9, 0xf6, 0x5d, 0x3f, 0x7e, 0x76,
-       0xcf, 0x46, 0xb3, 0x71, 0xc4, 0x4f, 0x99, 0x29, 0x57, 0x8e, 0xba, 0x11,
-       0x4b, 0x4a, 0x77, 0x64, 0x69, 0x1f, 0xdd, 0x93, 0x88, 0x91, 0x33, 0xe5,
-       0x06, 0xeb, 0x22, 0x84, 0x31, 0xec, 0x43, 0x8e, 0x8e, 0xa9, 0xc5, 0x58,
-       0xe9, 0xc7, 0xb2, 0x8c, 0xcb, 0x49, 0x49, 0x36, 0xde, 0x43, 0xdd, 0x61,
-       0x8a, 0xa3, 0x6d, 0xed, 0xf9, 0x5d, 0xa4, 0xb7, 0x8c, 0x1a, 0x22, 0x9a,
-       0x95, 0xa8, 0xca, 0xb6, 0xc7, 0xe6, 0x32, 0xdd, 0xe2, 0x64, 0xa6, 0x77,
-       0xa9, 0xf5, 0x7d, 0xbb, 0x22, 0xeb, 0x3b, 0x67, 0xdb, 0xb2, 0xa5, 0x5d,
-       0x6a, 0x51, 0x64, 0xa5, 0x22, 0x0a, 0x75, 0x4d, 0xe2, 0xa0, 0xe0, 0x7b,
-       0xfd, 0xd1, 0x47, 0x55, 0x36, 0x02, 0xdd, 0xca, 0x53, 0xab, 0x99, 0x28,
-       0x6b, 0xc6, 0xe4, 0x8c, 0x3c, 0x85, 0x3a, 0xf1, 0x49, 0x99, 0xab, 0x80,
-       0x2e, 0xcd, 0x77, 0x02, 0xfc, 0x0e, 0x00, 0x37, 0x69, 0x8f, 0x23, 0xc6,
-       0x7a, 0xb4, 0x83, 0xe6, 0x5c, 0x9e, 0x75, 0x52, 0x86, 0x79, 0xe5, 0x3d,
-       0xd8, 0x0f, 0xfd, 0xe5, 0x5f, 0x64, 0xcd, 0xea, 0x94, 0x82, 0x17, 0x1f,
-       0x68, 0xaf, 0x58, 0x7b, 0xd7, 0x5f, 0xbb, 0x8a, 0x35, 0xda, 0xef, 0xb6,
-       0x16, 0x1d, 0x7e, 0x55, 0xd7, 0x3a, 0x17, 0x6d, 0xbe, 0x13, 0xf6, 0x2f,
-       0x27, 0x3c, 0xd8, 0xd7, 0x27, 0xd6, 0xac, 0x47, 0xb7, 0x4b, 0x97, 0x49,
-       0xbd, 0xe1, 0x9c, 0x38, 0x63, 0x2c, 0xd6, 0x2f, 0xf9, 0xb8, 0xbe, 0x0b,
-       0x5c, 0xdd, 0xa4, 0x1b, 0x23, 0x8a, 0x75, 0xd0, 0x87, 0x9a, 0xa7, 0x70,
-       0x23, 0xd6, 0x10, 0xf6, 0x65, 0x1f, 0xd7, 0xb7, 0x5a, 0x70, 0x71, 0x8d,
-       0x4f, 0x9e, 0x89, 0xb3, 0xbb, 0xc8, 0x1b, 0xf9, 0xa1, 0x0e, 0xa8, 0x8f,
-       0xb4, 0x31, 0x83, 0xd8, 0x3e, 0xd3, 0xd4, 0xb5, 0x9d, 0x91, 0xaf, 0xa2,
-       0xe6, 0x6a, 0x3e, 0x0f, 0x1a, 0x59, 0xc3, 0x0e, 0xfa, 0xf5, 0x35, 0xed,
-       0x68, 0x43, 0xdb, 0x23, 0xe3, 0x4e, 0x59, 0xdb, 0xd5, 0x6b, 0x9e, 0x5d,
-       0x59, 0xd4, 0xcd, 0x6b, 0x32, 0xd8, 0xa8, 0x6c, 0xf7, 0xfe, 0xaf, 0xb6,
-       0x29, 0x11, 0xad, 0x4f, 0xe6, 0x37, 0xda, 0xd8, 0xed, 0x88, 0xeb, 0xee,
-       0x0f, 0x99, 0x67, 0x66, 0x98, 0x83, 0x66, 0x98, 0x3b, 0x0c, 0x3f, 0x1e,
-       0x26, 0x5b, 0x70, 0x24, 0x81, 0xa3, 0xee, 0xdb, 0xef, 0x73, 0x3e, 0xae,
-       0xa0, 0xfe, 0x0c, 0x62, 0xea, 0xef, 0xdf, 0x71, 0xeb, 0xfa, 0x47, 0x3e,
-       0x7d, 0xed, 0x3a, 0x1e, 0xc3, 0xd6, 0x41, 0x7f, 0x72, 0x56, 0xc1, 0xbe,
-       0xf2, 0x0d, 0x4f, 0x1f, 0xf0, 0x7d, 0xd8, 0x1e, 0x5f, 0x03, 0xdd, 0x7a,
-       0xf5, 0xb7, 0x27, 0x03, 0xea, 0x34, 0x47, 0xbe, 0x73, 0x51, 0xd2, 0xd2,
-       0x9c, 0xc6, 0x7e, 0x39, 0xcc, 0xdc, 0x58, 0x00, 0x1f, 0x07, 0xcd, 0x31,
-       0x73, 0x8e, 0xb8, 0xe3, 0x02, 0x9c, 0xa8, 0x25, 0xb3, 0x1d, 0xbe, 0x9e,
-       0xbf, 0xc9, 0xf3, 0x81, 0x7b, 0x1b, 0xbf, 0xf1, 0xfc, 0xa6, 0x4f, 0xcf,
-       0x95, 0x5e, 0x8f, 0x9e, 0x60, 0x7d, 0xd0, 0xbc, 0xf5, 0xbb, 0xbe, 0xcb,
-       0x97, 0x27, 0xde, 0x9f, 0xf4, 0xe9, 0xa2, 0x6e, 0x5a, 0x69, 0xa2, 0x5e,
-       0xfe, 0x1d, 0x78, 0x74, 0xad, 0x51, 0x52, 0x59, 0xd4, 0x2e, 0x19, 0xe6,
-       0xac, 0xd4, 0x64, 0x4e, 0x2c, 0xe8, 0x24, 0x65, 0xcf, 0x62, 0xd7, 0xbb,
-       0x15, 0xea, 0xf9, 0x3a, 0x62, 0x35, 0xf5, 0xfe, 0xbe, 0xcc, 0x57, 0x86,
-       0xec, 0x76, 0x83, 0xfe, 0x9a, 0x4a, 0x9f, 0x96, 0x31, 0xfb, 0xb4, 0xae,
-       0xa1, 0x52, 0xc9, 0x63, 0x42, 0xd9, 0x5e, 0x97, 0x61, 0x5d, 0xdb, 0xbc,
-       0x2f, 0x16, 0xe4, 0x32, 0x53, 0x85, 0x8f, 0xed, 0xfe, 0x57, 0x57, 0xd7,
-       0xa4, 0x08, 0x6f, 0xef, 0x6c, 0x81, 0xeb, 0x75, 0x8d, 0x87, 0xf8, 0x5a,
-       0x71, 0x19, 0xd2, 0xb1, 0x3b, 0xc0, 0x67, 0xc9, 0x42, 0x33, 0xc0, 0x19,
-       0x45, 0x5c, 0x46, 0x0c, 0xd8, 0xfd, 0x05, 0x5f, 0x1f, 0x7c, 0x7f, 0xd3,
-       0x65, 0x2d, 0xa4, 0xb2, 0xa7, 0xfc, 0xb9, 0x3f, 0xa3, 0x0c, 0xf0, 0x1d,
-       0xc8, 0xfd, 0x79, 0x3f, 0xde, 0x94, 0x8c, 0x5c, 0x93, 0x32, 0xa0, 0xad,
-       0x40, 0xff, 0xda, 0x3e, 0xe1, 0x33, 0xd5, 0xcf, 0x22, 0x66, 0xf5, 0x79,
-       0xf5, 0x03, 0x7a, 0xb0, 0x5c, 0x93, 0x73, 0x1b, 0x1d, 0x8e, 0xdd, 0xe6,
-       0xfb, 0xd2, 0x3e, 0xcc, 0xcd, 0xe0, 0x8f, 0xb2, 0x23, 0xcc, 0x7e, 0xbc,
-       0xe7, 0x7c, 0x38, 0x99, 0x74, 0x90, 0xbb, 0x72, 0xfb, 0xa7, 0xf0, 0x6d,
-       0xf8, 0x7d, 0x96, 0x96, 0x7b, 0x0d, 0xb5, 0x0a, 0xe4, 0x39, 0x0c, 0x7e,
-       0x92, 0x32, 0xd5, 0x84, 0xce, 0x6f, 0xc4, 0xb3, 0x1b, 0x30, 0xa5, 0x9b,
-       0x30, 0x5e, 0xec, 0x9b, 0x6a, 0xbe, 0xe5, 0x32, 0x1e, 0xfc, 0x89, 0xf6,
-       0x97, 0x24, 0x68, 0x0f, 0x7a, 0xb5, 0x9c, 0xf1, 0x70, 0x75, 0xda, 0x78,
-       0xa4, 0xca, 0x3d, 0xea, 0x6b, 0xfd, 0x62, 0x25, 0x1d, 0x85, 0x3a, 0x75,
-       0x77, 0x2f, 0xce, 0x3c, 0x06, 0xdb, 0x28, 0x19, 0x33, 0xa3, 0xdb, 0xa5,
-       0x90, 0xee, 0x07, 0xcd, 0xf7, 0xe3, 0xd9, 0x8e, 0xf9, 0x9f, 0xc2, 0x3c,
-       0xec, 0x28, 0x4d, 0xff, 0xe8, 0xd4, 0xbd, 0xe4, 0xac, 0x49, 0x1a, 0x87,
-       0x7d, 0xdb, 0xfa, 0x8e, 0xe9, 0xd9, 0xd2, 0x13, 0xf8, 0xde, 0x86, 0xf9,
-       0x5f, 0xc0, 0x13, 0xb9, 0x6c, 0x77, 0x30, 0x4f, 0x1f, 0x9c, 0xc4, 0xfc,
-       0xbd, 0xc0, 0xf1, 0xdb, 0x78, 0xbf, 0x0b, 0xef, 0xbf, 0xb5, 0x69, 0xef,
-       0x6f, 0xf2, 0x6c, 0xcc, 0x3b, 0x9b, 0xe6, 0x83, 0xf8, 0xcd, 0xf3, 0x44,
-       0xfa, 0xd6, 0xc1, 0xf8, 0x7a, 0x4c, 0x76, 0x9c, 0xee, 0x12, 0x55, 0xf7,
-       0x62, 0xb8, 0xaa, 0x9b, 0xd2, 0x7f, 0x9a, 0xf1, 0xfb, 0xaf, 0xb0, 0xc7,
-       0x12, 0xb5, 0x0e, 0xa5, 0x51, 0xb7, 0xda, 0x47, 0x0f, 0x1c, 0x19, 0x5c,
-       0xe6, 0x73, 0xf6, 0xc8, 0x44, 0x83, 0x30, 0x7c, 0x7f, 0xec, 0xc8, 0x60,
-       0xe3, 0x6f, 0x01, 0x0b, 0xb9, 0x54, 0x03, 0xfc, 0x84, 0xff, 0xd3, 0x4d,
-       0x67, 0x6a, 0xd9, 0xe2, 0x4c, 0xfa, 0xfd, 0x81, 0x23, 0x4e, 0x8d, 0x75,
-       0x42, 0x2a, 0x21, 0xba, 0x16, 0x9f, 0x3d, 0x52, 0x44, 0x7e, 0x8c, 0x68,
-       0x5a, 0x82, 0x75, 0xae, 0x51, 0x0f, 0x5b, 0xd1, 0x46, 0xba, 0x5a, 0xf1,
-       0x30, 0xcf, 0x10, 0xcf, 0x63, 0xc0, 0x93, 0x06, 0x1e, 0xe6, 0x1b, 0x8f,
-       0xde, 0xe4, 0xf2, 0x56, 0xb4, 0x11, 0x17, 0xcf, 0x0a, 0xf0, 0xf5, 0x8b,
-       0x3a, 0xfd, 0x26, 0xe9, 0x35, 0x59, 0xdb, 0x7a, 0xb1, 0xa6, 0x4d, 0x0a,
-       0x27, 0x99, 0xb3, 0x77, 0xfb, 0xdf, 0x71, 0x93, 0x3d, 0x77, 0x52, 0x71,
-       0x9e, 0x4f, 0xac, 0x65, 0xee, 0xc4, 0x1c, 0xbe, 0x57, 0x02, 0x58, 0xe5,
-       0xc3, 0xf6, 0xb4, 0xf0, 0xdd, 0xe6, 0xcb, 0x9a, 0x67, 0x06, 0xbd, 0x67,
-       0x2b, 0x2d, 0x00, 0x85, 0x1e, 0xfa, 0x6e, 0xe8, 0x21, 0xe0, 0x13, 0x0b,
-       0xeb, 0xa4, 0x2d, 0x0d, 0x5e, 0x03, 0xda, 0x3e, 0xa9, 0xfe, 0xb8, 0x37,
-       0x8d, 0xbf, 0xe0, 0xbc, 0x40, 0x06, 0xa4, 0x8b, 0x4f, 0xd8, 0xf2, 0xc7,
-       0x7a, 0xe7, 0x34, 0xfc, 0x8e, 0xf7, 0x1e, 0xae, 0xbb, 0x66, 0x53, 0xf6,
-       0x1d, 0xd0, 0x3b, 0x79, 0x31, 0xd0, 0x4b, 0x28, 0xd6, 0x74, 0x49, 0xf6,
-       0xac, 0x87, 0xe4, 0x6d, 0xe0, 0xca, 0xa1, 0xaf, 0xf4, 0x7a, 0xa3, 0x59,
-       0xc4, 0xc7, 0x0d, 0xd8, 0xe7, 0x45, 0x8b, 0xf7, 0x2f, 0x51, 0xe6, 0x3b,
-       0x29, 0x37, 0xfe, 0x19, 0x30, 0xac, 0xaf, 0x6e, 0xde, 0xad, 0x2c, 0x03,
-       0x66, 0x05, 0x6b, 0xc7, 0xbc, 0xb8, 0xcc, 0xd8, 0xee, 0x2a, 0xd4, 0x1e,
-       0x45, 0xeb, 0xbf, 0x5d, 0xd6, 0x59, 0x37, 0x61, 0xb7, 0xba, 0x0b, 0x41,
-       0xce, 0x59, 0x4a, 0x2d, 0x2c, 0x23, 0x86, 0xd7, 0x2c, 0xb5, 0x43, 0x69,
-       0x8b, 0x4c, 0xd5, 0x10, 0x93, 0xd0, 0xf5, 0xa6, 0x92, 0xcb, 0xf2, 0x03,
-       0xad, 0x87, 0x36, 0x6b, 0xcc, 0xec, 0x57, 0x5f, 0xa4, 0x5d, 0x69, 0xca,
-       0x23, 0x27, 0x90, 0x97, 0xc7, 0x1f, 0x46, 0xce, 0x81, 0xbc, 0x4e, 0x94,
-       0xd0, 0xc9, 0xd3, 0x46, 0x36, 0x7e, 0xbd, 0x68, 0x79, 0x7d, 0x80, 0xce,
-       0x67, 0xe2, 0xf1, 0x18, 0x39, 0xd1, 0xad, 0xe3, 0x4c, 0x41, 0xc7, 0x9b,
-       0x21, 0x73, 0x46, 0x75, 0xa1, 0xc6, 0x40, 0x01, 0x8a, 0x0a, 0xc7, 0x1c,
-       0x11, 0x19, 0x5c, 0x44, 0x5c, 0x41, 0x1c, 0x1e, 0x5c, 0x47, 0x74, 0x3b,
-       0x41, 0x78, 0x25, 0xd1, 0x13, 0x11, 0x69, 0x3b, 0xc1, 0xfb, 0x10, 0xd9,
-       0x89, 0x7e, 0x8c, 0x38, 0x07, 0xa3, 0x78, 0x4e, 0xe1, 0x6f, 0x0f, 0x6a,
-       0x2b, 0x13, 0x35, 0xf2, 0x16, 0xf0, 0x80, 0xe5, 0x9e, 0xad, 0xe0, 0xbb,
-       0xfb, 0xa4, 0x2b, 0x86, 0x3d, 0x84, 0x8f, 0x82, 0x8e, 0x9d, 0xa0, 0xc7,
-       0x3b, 0x9f, 0x38, 0xa2, 0x27, 0x44, 0x86, 0x16, 0xa5, 0x5f, 0xe9, 0x3d,
-       0x51, 0x29, 0x66, 0xb8, 0xd6, 0x0d, 0x78, 0xee, 0xc3, 0x9a, 0xde, 0xe7,
-       0xdd, 0x2b, 0x15, 0x6e, 0xd2, 0x8d, 0x39, 0x03, 0xef, 0xa8, 0xa7, 0x32,
-       0xa6, 0x0c, 0xd5, 0x3d, 0xd8, 0xc1, 0xf5, 0x43, 0x78, 0x92, 0x57, 0x8f,
-       0x36, 0x85, 0x9a, 0xb8, 0x00, 0xa9, 0x46, 0x47, 0x78, 0x3f, 0x43, 0x18,
-       0xf6, 0xb5, 0xdd, 0x1a, 0xc6, 0x1c, 0xa1, 0xfc, 0xbc, 0x39, 0xa5, 0xfe,
-       0xb7, 0x7b, 0x97, 0xd6, 0x9a, 0x42, 0xfb, 0x0a, 0xf6, 0x7f, 0x45, 0xfb,
-       0x8a, 0xa8, 0xa4, 0xef, 0x2b, 0xf8, 0x5e, 0xe1, 0x77, 0x90, 0x8b, 0x7f,
-       0xed, 0x0e, 0x2f, 0xde, 0xbb, 0x32, 0x67, 0xf3, 0x0e, 0xc3, 0x95, 0x8b,
-       0x76, 0xc9, 0x78, 0xf0, 0x96, 0x3a, 0x33, 0xad, 0xf3, 0x73, 0x11, 0xb2,
-       0xbf, 0xdc, 0xd0, 0x3d, 0x9b, 0x5c, 0x6a, 0xc4, 0xe4, 0xca, 0x6a, 0x97,
-       0x5c, 0x5e, 0xf6, 0x6c, 0xfe, 0xf2, 0x32, 0xed, 0xdc, 0x94, 0xef, 0xad,
-       0x5a, 0x58, 0x4b, 0xe3, 0xaf, 0x5f, 0xde, 0x59, 0xbd, 0xb5, 0xee, 0x3c,
-       0xdf, 0x7c, 0x00, 0xb4, 0xf4, 0x4b, 0xc4, 0x72, 0x75, 0xff, 0x95, 0x47,
-       0xee, 0x2b, 0xc9, 0x94, 0x14, 0xaa, 0x43, 0xe8, 0x01, 0x91, 0x9c, 0xa3,
-       0xcc, 0x41, 0xd0, 0x7f, 0xf5, 0x33, 0xa8, 0x4d, 0x52, 0x70, 0x9e, 0x21,
-       0x7d, 0x8f, 0xf8, 0x33, 0xd1, 0x7e, 0x69, 0xb7, 0xbe, 0xdc, 0xe7, 0xe5,
-       0x2a, 0xd3, 0xeb, 0x53, 0xad, 0x20, 0x5f, 0xbf, 0x0e, 0xdc, 0xe3, 0xb0,
-       0x53, 0xda, 0xa6, 0x0d, 0x9b, 0x35, 0x65, 0x6d, 0x34, 0x55, 0x2b, 0x09,
-       0xe3, 0x43, 0x06, 0x67, 0x7e, 0x08, 0x9e, 0xd3, 0x90, 0x47, 0xa7, 0xae,
-       0x85, 0x72, 0x0a, 0xba, 0x5d, 0x9c, 0x97, 0x42, 0xf3, 0x57, 0x80, 0x2f,
-       0x27, 0xb3, 0xcd, 0x49, 0x9c, 0x75, 0x1c, 0x76, 0x3b, 0xda, 0x2f, 0x5d,
-       0x3c, 0x27, 0x03, 0x1a, 0xef, 0x97, 0xe2, 0xc9, 0x79, 0x39, 0x58, 0x25,
-       0x9d, 0xc8, 0x25, 0x76, 0x2a, 0x9d, 0x97, 0xb1, 0xe4, 0x2a, 0x6a, 0x27,
-       0xcf, 0x1f, 0xb3, 0x52, 0x3c, 0x05, 0x1c, 0x55, 0xde, 0x03, 0x0c, 0xc1,
-       0x6e, 0xc6, 0x74, 0x5f, 0x33, 0xab, 0xe3, 0x0e, 0xe7, 0xdf, 0x84, 0x9e,
-       0x86, 0x4a, 0x7b, 0x00, 0x57, 0x40, 0x0f, 0x34, 0x83, 0x7a, 0x79, 0xa5,
-       0x8a, 0x7e, 0xcf, 0x8e, 0xb0, 0xf6, 0x52, 0xea, 0x9e, 0x01, 0xa9, 0x57,
-       0xc7, 0x4c, 0xa5, 0x58, 0x53, 0x51, 0x17, 0x5c, 0xa3, 0x7f, 0x27, 0x54,
-       0xd4, 0x1a, 0x90, 0xd5, 0x6a, 0x09, 0x7d, 0xb3, 0xf2, 0xef, 0x35, 0x4a,
-       0x62, 0x5a, 0x5e, 0xdc, 0xcb, 0x29, 0xf2, 0x8d, 0xfa, 0xb3, 0xf9, 0x59,
-       0xd0, 0x98, 0x4b, 0x9a, 0x72, 0x14, 0xf4, 0xe1, 0x7d, 0x05, 0x36, 0xbe,
-       0xc8, 0x1a, 0x2e, 0x87, 0xb5, 0xac, 0x1c, 0x3e, 0x33, 0x03, 0x1a, 0x7a,
-       0x65, 0xe8, 0x77, 0xe9, 0x63, 0x07, 0x30, 0xc7, 0xef, 0x14, 0xec, 0xf5,
-       0x31, 0xbc, 0x13, 0x36, 0x81, 0x27, 0xe5, 0x30, 0x80, 0xa7, 0x09, 0x5a,
-       0x62, 0x5e, 0x6f, 0xb2, 0x3f, 0x29, 0xf5, 0x93, 0xf7, 0xc9, 0xec, 0xca,
-       0x7d, 0xc0, 0xff, 0x36, 0xfa, 0x02, 0xe4, 0xb7, 0x15, 0x9e, 0xc5, 0xfa,
-       0x8f, 0xe7, 0x74, 0xf4, 0x6b, 0xdf, 0x58, 0xe4, 0x3c, 0x9f, 0xfb, 0xb0,
-       0x1f, 0x3d, 0x46, 0x35, 0x27, 0xc5, 0x2a, 0xcf, 0x82, 0xee, 0x50, 0x4f,
-       0x15, 0x4e, 0xce, 0xf8, 0x3a, 0xee, 0x97, 0x7c, 0xbc, 0xc4, 0xfe, 0x02,
-       0x79, 0x62, 0x79, 0xc2, 0xa9, 0xa4, 0x4c, 0x47, 0x11, 0x57, 0x5a, 0x98,
-       0x1b, 0xbc, 0xb9, 0x98, 0x58, 0x8b, 0xe8, 0x6d, 0xb3, 0x5c, 0x3b, 0xea,
-       0xdf, 0x1d, 0x10, 0xd7, 0x5b, 0x32, 0x05, 0x1b, 0x1b, 0x5a, 0x1c, 0x47,
-       0x2d, 0xfc, 0x5d, 0xd4, 0x92, 0x77, 0xfa, 0x32, 0x98, 0xf4, 0x6d, 0xa3,
-       0xab, 0xc5, 0x26, 0xa0, 0xe7, 0x2a, 0x74, 0x5f, 0x85, 0x1d, 0x20, 0x56,
-       0xbf, 0x74, 0xc3, 0x3e, 0x26, 0x5b, 0x6a, 0xcc, 0x1e, 0xf9, 0x8b, 0x5a,
-       0x2a, 0xbd, 0x01, 0xfb, 0x79, 0x07, 0xbd, 0xc0, 0x06, 0x7a, 0xd5, 0xcb,
-       0xe8, 0xeb, 0x56, 0x2a, 0xfb, 0x41, 0x3f, 0x6b, 0x4a, 0x7e, 0x27, 0x74,
-       0xad, 0xd3, 0x61, 0x1d, 0xbb, 0x43, 0xdf, 0xed, 0xca, 0xfe, 0x7e, 0xf6,
-       0x9a, 0xec, 0xcb, 0x79, 0x0f, 0x7d, 0x05, 0x7a, 0xdc, 0x30, 0xb9, 0x1e,
-       0xec, 0x63, 0x2f, 0x10, 0xd8, 0x0f, 0x69, 0xa1, 0xfd, 0x70, 0x0f, 0x61,
-       0xfa, 0xb5, 0x9f, 0x14, 0x34, 0x3e, 0xda, 0xec, 0x8b, 0x7d, 0x9e, 0x9f,
-       0xe9, 0x3a, 0xcb, 0xbc, 0x24, 0x81, 0xfd, 0xbe, 0xef, 0xb2, 0xaf, 0x73,
-       0x46, 0x11, 0xbb, 0x9b, 0xae, 0x3c, 0x67, 0xdf, 0xea, 0x77, 0x7b, 0xab,
-       0x81, 0x9c, 0x28, 0xc7, 0xfd, 0x72, 0xac, 0x99, 0x82, 0x4f, 0x50, 0x86,
-       0x56, 0x8b, 0x0c, 0x45, 0xfe, 0xa8, 0x2a, 0xf2, 0x62, 0x95, 0x6b, 0x5a,
-       0x86, 0x09, 0x27, 0xd2, 0xa5, 0xef, 0xd2, 0x0b, 0xf2, 0x1d, 0x39, 0xb8,
-       0x24, 0x72, 0x06, 0xeb, 0x6b, 0x55, 0xfa, 0xea, 0x38, 0xea, 0xd7, 0x6d,
-       0x52, 0x5f, 0x46, 0x4f, 0x56, 0x95, 0x59, 0xe7, 0x5e, 0xe6, 0x9b, 0x98,
-       0x5c, 0xd6, 0x77, 0xb2, 0x22, 0x23, 0x67, 0xa3, 0x12, 0x3d, 0x8b, 0xe6,
-       0x0f, 0xb2, 0x3f, 0x37, 0x1a, 0xdc, 0xd1, 0x7a, 0x3e, 0x5f, 0xae, 0x60,
-       0x6f, 0x75, 0x48, 0xc7, 0xc9, 0x72, 0xa3, 0x28, 0x85, 0x1a, 0xcf, 0xc2,
-       0x73, 0x39, 0x89, 0xb5, 0x8c, 0xcc, 0x9d, 0x1c, 0x97, 0xa7, 0x71, 0x06,
-       0xfa, 0x3f, 0x9c, 0x31, 0x25, 0xa5, 0x33, 0x98, 0x6f, 0x5c, 0x95, 0xe5,
-       0xd5, 0xa2, 0xd4, 0x6b, 0xe7, 0x5d, 0xaf, 0x8f, 0x20, 0x3e, 0x7c, 0x2f,
-       0xb7, 0xf6, 0xb2, 0xfb, 0xd9, 0xcf, 0xa0, 0x57, 0xb5, 0xf0, 0x0d, 0x99,
-       0x35, 0xe6, 0x66, 0x6f, 0xbd, 0x33, 0x6e, 0xed, 0x61, 0xa7, 0x65, 0xa1,
-       0x9a, 0x91, 0xf2, 0xc9, 0x71, 0x7d, 0xd7, 0xd0, 0x91, 0x3d, 0xfc, 0xc4,
-       0x35, 0xe4, 0x8a, 0x69, 0x7d, 0x67, 0x7c, 0x5d, 0x1e, 0xb2, 0x17, 0xe4,
-       0x90, 0xb5, 0x4f, 0x8e, 0xa1, 0xbe, 0xfe, 0x1c, 0x7a, 0xfd, 0x64, 0x1f,
-       0xf5, 0x08, 0x7a, 0x2d, 0xf6, 0xa0, 0xae, 0x4c, 0xd9, 0x9f, 0x36, 0x9f,
-       0x65, 0x97, 0xd0, 0x60, 0x9e, 0xfc, 0x2f, 0x37, 0x87, 0xbc, 0x77, 0x0d,
-       0xbd, 0x63, 0x4e, 0xc3, 0x19, 0x1e, 0x5c, 0x8d, 0x70, 0x63, 0xe6, 0x73,
-       0x84, 0x5b, 0x36, 0x7c, 0x38, 0x03, 0x70, 0x11, 0xb9, 0x60, 0x47, 0x61,
-       0x23, 0xd3, 0xe0, 0x13, 0x31, 0x7e, 0xa2, 0xc7, 0xaf, 0x83, 0x3b, 0x91,
-       0x5b, 0x6f, 0xee, 0x7f, 0xd5, 0xdf, 0xff, 0xb4, 0xbf, 0xff, 0xe2, 0x8d,
-       0xfd, 0x41, 0x7e, 0xfd, 0xd0, 0x95, 0x16, 0xba, 0x5e, 0xad, 0x78, 0xf0,
-       0x0b, 0x3e, 0x5d, 0x17, 0x6f, 0xd0, 0x15, 0xc0, 0x43, 0x9e, 0x9a, 0x67,
-       0xc6, 0x66, 0xc6, 0xe8, 0x21, 0xc8, 0xd1, 0x95, 0xbc, 0x0d, 0xdf, 0xa8,
-       0xa6, 0x26, 0x4b, 0xfa, 0x4e, 0x4d, 0xc9, 0x46, 0x7c, 0x41, 0xa6, 0xad,
-       0xd4, 0xe4, 0x9c, 0x44, 0x60, 0xcb, 0x8c, 0x2d, 0x11, 0xa9, 0x33, 0xe6,
-       0xe0, 0x59, 0xb0, 0xb7, 0xa6, 0xf5, 0x4a, 0x0b, 0xad, 0x91, 0x17, 0x48,
-       0xa3, 0x47, 0x6b, 0x6c, 0xf8, 0x26, 0xad, 0x1e, 0xbc, 0x47, 0xeb, 0x95,
-       0x4a, 0x0b, 0xfc, 0xd9, 0xa8, 0x0f, 0x1f, 0x6d, 0x81, 0xa7, 0x3d, 0xb3,
-       0xae, 0xa0, 0x3d, 0x93, 0xb6, 0x9f, 0x80, 0x6f, 0x48, 0xac, 0x33, 0x7b,
-       0xf8, 0xc8, 0xdd, 0xc3, 0xae, 0xc4, 0x50, 0x6f, 0xb4, 0x63, 0xed, 0x72,
-       0x8d, 0xb5, 0x88, 0x1a, 0x6c, 0x97, 0x11, 0xd8, 0x2c, 0x75, 0xe7, 0xdd,
-       0x0d, 0x3e, 0xa4, 0x6b, 0x02, 0x57, 0x0e, 0xd9, 0xa4, 0xe5, 0x3f, 0xdd,
-       0x17, 0xe3, 0x23, 0x76, 0x59, 0x46, 0xcd, 0x76, 0x9c, 0x5f, 0x6f, 0x6a,
-       0x9c, 0x69, 0xd2, 0x72, 0x7a, 0x74, 0xc8, 0xfc, 0x73, 0xf0, 0x39, 0x55,
-       0x33, 0xa4, 0x6e, 0xa5, 0x12, 0xe7, 0x80, 0x63, 0x0f, 0x74, 0x53, 0x1f,
-       0x27, 0x3d, 0x22, 0x07, 0x61, 0xdf, 0x75, 0x9d, 0x17, 0x69, 0xc7, 0xa9,
-       0xe9, 0x12, 0x6a, 0x9d, 0x3f, 0xd6, 0xb9, 0xcd, 0x75, 0xaf, 0x21, 0xbf,
-       0x4d, 0x6f, 0xb2, 0x3d, 0x75, 0xd6, 0xb3, 0x3d, 0x75, 0x16, 0x3d, 0xf0,
-       0xf1, 0x98, 0x74, 0xac, 0xc1, 0x7f, 0x5e, 0xd8, 0xe9, 0xd5, 0x73, 0x2f,
-       0x24, 0x8d, 0xfc, 0x49, 0xc4, 0xbb, 0xe3, 0x51, 0xb1, 0x8e, 0xeb, 0x7c,
-       0x00, 0x79, 0x4f, 0xc9, 0xdc, 0x29, 0xc6, 0x54, 0x4b, 0x86, 0x8f, 0x53,
-       0x1f, 0xac, 0x6b, 0x96, 0x27, 0x8a, 0xf0, 0x91, 0x79, 0xc4, 0x05, 0xb5,
-       0xf6, 0xae, 0x14, 0x2d, 0xca, 0xa1, 0x57, 0xba, 0xd6, 0xd0, 0x8f, 0xaf,
-       0x21, 0x36, 0xac, 0x25, 0xa4, 0x0d, 0xbe, 0xa5, 0xce, 0xc6, 0x8d, 0xf2,
-       0xd2, 0x0f, 0xe1, 0x0f, 0xfc, 0x0d, 0x07, 0xb5, 0xe5, 0xd9, 0x84, 0x41,
-       0xdf, 0x52, 0x67, 0x69, 0xe7, 0x28, 0xa7, 0xce, 0xd2, 0xce, 0x49, 0x47,
-       0xe0, 0x2f, 0x78, 0x3f, 0x3b, 0xae, 0xef, 0xa9, 0xaf, 0xd9, 0xe4, 0xe5,
-       0x6f, 0xc4, 0xa9, 0xb1, 0x46, 0x24, 0x3f, 0xd2, 0x87, 0x5a, 0x66, 0xbb,
-       0x63, 0x0f, 0x4f, 0x5e, 0x96, 0x4f, 0xca, 0xd7, 0xed, 0x9f, 0x80, 0x2f,
-       0xf2, 0xd1, 0xca, 0x17, 0x79, 0xea, 0x95, 0x36, 0xcd, 0x57, 0xc0, 0x0f,
-       0x04, 0x0d, 0x7e, 0x06, 0x8f, 0x27, 0x80, 0xff, 0x31, 0xc4, 0x80, 0x01,
-       0x3c, 0x0f, 0xe0, 0x89, 0x94, 0x76, 0x96, 0xbc, 0x93, 0xd7, 0x77, 0x50,
-       0x37, 0x06, 0x7c, 0xce, 0xe2, 0xfd, 0x15, 0x99, 0x5b, 0x72, 0x8f, 0x22,
-       0xaf, 0xf2, 0x0e, 0xbd, 0xdf, 0xbb, 0x0f, 0xde, 0xcc, 0xfb, 0x2b, 0xe2,
-       0xc9, 0x27, 0x65, 0xd6, 0x05, 0xef, 0xab, 0x9b, 0x65, 0xd1, 0x1a, 0x3b,
-       0x12, 0xba, 0x0e, 0x3f, 0xd8, 0x60, 0x9c, 0xa0, 0x8c, 0xde, 0x11, 0x67,
-       0x89, 0xf7, 0x5f, 0x1e, 0xbe, 0xd9, 0x46, 0x10, 0x37, 0x5a, 0xf7, 0xd8,
-       0x80, 0x1b, 0x00, 0x1c, 0xe9, 0xda, 0xa0, 0xfc, 0x10, 0x73, 0x76, 0xb5,
-       0xc4, 0x9a, 0xd6, 0x7d, 0x93, 0xf2, 0x0c, 0xea, 0x80, 0x57, 0xed, 0x5b,
-       0xe4, 0x3a, 0xcb, 0x5a, 0xa8, 0xde, 0x98, 0x81, 0x4f, 0xb6, 0x21, 0x96,
-       0x99, 0x72, 0xb9, 0xd2, 0x2e, 0x75, 0xd4, 0x3b, 0x2b, 0xab, 0x8c, 0x85,
-       0xa4, 0xbd, 0x0b, 0xf3, 0x5e, 0xfc, 0x62, 0xac, 0xbd, 0x5c, 0x41, 0x9e,
-       0x85, 0x6f, 0x5f, 0xae, 0xc4, 0xf1, 0x1c, 0xc0, 0xd3, 0xc2, 0x33, 0x89,
-       0x67, 0x1a, 0xcf, 0x71, 0x3c, 0xc7, 0xf1, 0xb4, 0xb0, 0x37, 0x81, 0x67,
-       0xd0, 0x33, 0x10, 0xd7, 0x4d, 0xbe, 0xcb, 0xfa, 0x3c, 0xd4, 0x8a, 0x16,
-       0x73, 0x5a, 0xd4, 0xce, 0xa3, 0x8f, 0x70, 0xc6, 0x75, 0xad, 0x87, 0xfc,
-       0xf6, 0x91, 0x6b, 0x5a, 0xec, 0xcb, 0x4b, 0xc6, 0x9e, 0x51, 0xe6, 0x85,
-       0x1a, 0xf2, 0xc2, 0x7f, 0xec, 0x40, 0xff, 0x68, 0xee, 0xd5, 0x77, 0x47,
-       0x4b, 0xf8, 0xe6, 0x3b, 0x7a, 0xde, 0xf8, 0x3c, 0xf2, 0x14, 0xe3, 0xa7,
-       0x8b, 0x3d, 0x05, 0xc4, 0xf1, 0xed, 0xf0, 0xbf, 0x1c, 0xe2, 0x36, 0xde,
-       0x97, 0x37, 0x76, 0x78, 0x39, 0x15, 0xf5, 0xbb, 0xda, 0x7c, 0x5f, 0x63,
-       0x63, 0xcf, 0x56, 0xbd, 0x41, 0x0f, 0x70, 0xa4, 0x6a, 0xcb, 0xf0, 0xc1,
-       0x37, 0xed, 0xa3, 0xba, 0xb6, 0xa3, 0x2e, 0x9e, 0x46, 0x8d, 0x9a, 0x5f,
-       0x64, 0x0d, 0xf3, 0x14, 0xfa, 0x12, 0xf4, 0x67, 0x71, 0xf6, 0xe4, 0xcc,
-       0x05, 0xba, 0x16, 0x8d, 0x4b, 0x17, 0xf3, 0xc0, 0x15, 0x9c, 0x07, 0xbe,
-       0x56, 0x5c, 0xc8, 0xec, 0x41, 0xd4, 0x84, 0xae, 0x1b, 0xb5, 0xf6, 0x48,
-       0xf2, 0x11, 0xc6, 0x1c, 0xc1, 0x7e, 0x53, 0xbc, 0x7b, 0x75, 0xc4, 0xdd,
-       0x19, 0xfd, 0xfb, 0x30, 0x8c, 0x6b, 0x1c, 0x7b, 0x6f, 0x13, 0xef, 0xb7,
-       0x5c, 0xde, 0x69, 0x8b, 0xec, 0x59, 0xf4, 0x6a, 0x5a, 0x65, 0xb5, 0xe2,
-       0xfb, 0x49, 0x1f, 0x1f, 0xd7, 0x95, 0xff, 0xdb, 0xc6, 0x4e, 0xc8, 0x08,
-       0xfe, 0x00, 0x1d, 0x1f, 0x43, 0xfd, 0x7c, 0x01, 0x7a, 0x79, 0x15, 0x3a,
-       0x79, 0xad, 0x42, 0x5b, 0x1f, 0x83, 0xdd, 0x43, 0x86, 0x33, 0xfa, 0x0c,
-       0x7d, 0xf6, 0x85, 0x0a, 0x62, 0x27, 0xe3, 0x9f, 0xfa, 0x52, 0x9c, 0xf5,
-       0x21, 0xf3, 0xa0, 0x87, 0x67, 0xc0, 0x83, 0x93, 0x60, 0x6d, 0x87, 0xa6,
-       0xa7, 0xae, 0xef, 0xc1, 0x28, 0x27, 0xd8, 0x20, 0x7f, 0x23, 0xd0, 0x30,
-       0x5f, 0x8c, 0xeb, 0x7b, 0x78, 0xc5, 0x39, 0xf2, 0x31, 0x2e, 0xce, 0x62,
-       0xb0, 0xaf, 0x0f, 0xfb, 0x3a, 0x5b, 0x70, 0xdd, 0xbe, 0x89, 0x07, 0xe5,
-       0xf3, 0xc0, 0xf5, 0xcd, 0x75, 0x7f, 0xca, 0x2c, 0xdd, 0xb8, 0x1b, 0x66,
-       0xfe, 0xa5, 0x6e, 0x32, 0xd8, 0x1f, 0xe8, 0x67, 0xc0, 0xef, 0x05, 0x52,
-       0x0b, 0xe8, 0x23, 0x20, 0x7f, 0xea, 0x68, 0x92, 0xf1, 0x09, 0xf8, 0x6d,
-       0xa9, 0x55, 0x3a, 0x44, 0xf5, 0xb3, 0x37, 0x66, 0xad, 0xdc, 0x7a, 0xe6,
-       0x2f, 0xfa, 0x67, 0xa2, 0x9f, 0x3e, 0xc1, 0xba, 0x59, 0xe7, 0x19, 0xc0,
-       0x74, 0x6f, 0xa2, 0xed, 0xe7, 0x7c, 0x38, 0xae, 0xa7, 0xa5, 0x84, 0x3a,
-       0x34, 0xbf, 0x88, 0x8a, 0x1e, 0xf1, 0x5b, 0x65, 0xf9, 0xbb, 0x16, 0xef,
-       0xf0, 0xc6, 0x92, 0x73, 0xa0, 0xb1, 0x64, 0xe6, 0x78, 0x6f, 0x06, 0x1c,
-       0xbb, 0x36, 0xe1, 0x98, 0xf2, 0x71, 0x4c, 0x49, 0xf9, 0xd4, 0x34, 0x7c,
-       0x2d, 0x87, 0xfc, 0x3e, 0x64, 0x3e, 0x28, 0x9f, 0x41, 0x73, 0x8d, 0xb9,
-       0x33, 0xe3, 0xd0, 0x93, 0xeb, 0xee, 0xb1, 0xf7, 0x83, 0xee, 0x97, 0x91,
-       0x5b, 0x83, 0x9a, 0xa7, 0x9c, 0x88, 0x20, 0x87, 0x1d, 0xd6, 0xbf, 0xc3,
-       0x96, 0x4c, 0x13, 0xf6, 0xaa, 0x8c, 0xb1, 0x34, 0xda, 0x7b, 0xe4, 0xb7,
-       0x05, 0xe4, 0x2a, 0xf2, 0xd9, 0x23, 0x65, 0xd3, 0x78, 0x20, 0x82, 0xba,
-       0xc6, 0x59, 0xa4, 0x1f, 0xc9, 0x70, 0x24, 0xdb, 0x8e, 0x9a, 0xd4, 0x95,
-       0xef, 0xd9, 0xfc, 0x77, 0x09, 0x0b, 0x72, 0xa1, 0x61, 0xe2, 0x79, 0x0e,
-       0x7a, 0xf8, 0x3d, 0xbc, 0xff, 0x53, 0x3f, 0xea, 0x3e, 0xac, 0xe4, 0x60,
-       0xbb, 0x69, 0x5d, 0xcf, 0xb0, 0x8e, 0xa8, 0x23, 0xdf, 0x2a, 0xe4, 0x1a,
-       0xd4, 0x55, 0x93, 0xac, 0x5d, 0x9f, 0x59, 0xb9, 0x2a, 0xaf, 0x2d, 0xf1,
-       0x77, 0x50, 0xe6, 0xe5, 0x7d, 0x8c, 0x07, 0xe6, 0x7c, 0x06, 0x73, 0xab,
-       0x8c, 0x65, 0xf8, 0x6e, 0xc2, 0x81, 0xfa, 0x51, 0x23, 0xa0, 0xd6, 0xbe,
-       0x6c, 0xa5, 0xc1, 0xe7, 0x55, 0xb9, 0xb0, 0x14, 0x95, 0x15, 0x8b, 0x75,
-       0x91, 0x24, 0x1d, 0xc0, 0x5e, 0x58, 0xfd, 0x07, 0xcf, 0x26, 0x08, 0x8f,
-       0x9e, 0xa7, 0x84, 0xba, 0xee, 0x41, 0xbd, 0xf7, 0x47, 0xe9, 0x99, 0x34,
-       0xb5, 0xf6, 0x79, 0x45, 0xb9, 0x40, 0x7f, 0xd2, 0xbf, 0x51, 0xb0, 0x36,
-       0x78, 0x0a, 0x36, 0xcb, 0xda, 0x9d, 0xfd, 0x00, 0xde, 0x1b, 0x5c, 0x27,
-       0xef, 0x78, 0x2e, 0x0f, 0x41, 0x36, 0xf4, 0x7b, 0xde, 0x89, 0x21, 0x8f,
-       0x2a, 0xfa, 0x7a, 0x59, 0xc7, 0x82, 0x72, 0xb5, 0x88, 0x9c, 0x82, 0x18,
-       0x60, 0xef, 0x82, 0x2d, 0xce, 0x40, 0x97, 0x93, 0x80, 0xdb, 0x94, 0x4b,
-       0xd6, 0xcb, 0xba, 0x2e, 0x53, 0xa7, 0x6f, 0xde, 0xdf, 0x14, 0xe0, 0x3f,
-       0x6a, 0x1d, 0xb6, 0x05, 0x1f, 0x52, 0xeb, 0x71, 0x3c, 0x11, 0x8f, 0xd7,
-       0xd1, 0x5f, 0x54, 0x78, 0x3f, 0x84, 0xde, 0xa0, 0xc2, 0xbb, 0x93, 0x34,
-       0x9e, 0xe3, 0xbc, 0x2f, 0xf2, 0xe3, 0x1a, 0xf1, 0x93, 0x8e, 0x20, 0xbe,
-       0xb0, 0x96, 0x64, 0x7c, 0x09, 0xea, 0x49, 0xcf, 0x16, 0x8e, 0x55, 0x19,
-       0x43, 0x68, 0xd7, 0x43, 0x88, 0x5b, 0xb4, 0x05, 0xaf, 0x96, 0x5c, 0xad,
-       0x79, 0x32, 0x9b, 0x6b, 0x9e, 0xd7, 0x39, 0x62, 0xaf, 0x58, 0xb0, 0x31,
-       0xca, 0x0e, 0x6b, 0x3a, 0x07, 0x9c, 0x93, 0x9c, 0x7e, 0x52, 0x66, 0xaf,
-       0x48, 0x6e, 0x75, 0x5c, 0x9e, 0xd3, 0x71, 0x2b, 0x88, 0x59, 0xac, 0x21,
-       0xf9, 0xfb, 0x71, 0x5a, 0x9e, 0x3d, 0x79, 0x55, 0x9c, 0xe7, 0x19, 0xb7,
-       0xc6, 0x12, 0x9d, 0x06, 0x63, 0x95, 0x2b, 0x0d, 0xe4, 0xa6, 0x07, 0x6d,
-       0xfe, 0x5b, 0x80, 0x08, 0x7a, 0x3a, 0x57, 0xda, 0x27, 0x52, 0x76, 0xd2,
-       0x18, 0x3a, 0xd0, 0x69, 0x30, 0x37, 0x8e, 0x99, 0x8f, 0x4b, 0x70, 0x1f,
-       0xd5, 0x21, 0x8f, 0xeb, 0xbb, 0x0a, 0xb8, 0xed, 0xe2, 0x07, 0xfa, 0x77,
-       0x94, 0x6b, 0x19, 0xca, 0x1a, 0xdf, 0xeb, 0x9c, 0x2f, 0xc5, 0xae, 0x65,
-       0xda, 0xa4, 0x7c, 0x9b, 0xeb, 0x1e, 0x9a, 0x98, 0xd8, 0xe1, 0xfd, 0x7b,
-       0x91, 0x23, 0xb7, 0x79, 0xb1, 0xa0, 0xe0, 0x7f, 0xaf, 0xe1, 0x49, 0xdb,
-       0x66, 0xbe, 0x65, 0x7e, 0xa4, 0xde, 0xf0, 0x5c, 0xe5, 0x3b, 0x73, 0xef,
-       0x02, 0x72, 0x2f, 0xf3, 0xe5, 0x76, 0xc9, 0xf3, 0x77, 0x3e, 0xa5, 0xe7,
-       0x4b, 0x5e, 0x2d, 0xed, 0xc3, 0xd5, 0x66, 0x65, 0xae, 0xc6, 0x1a, 0xea,
-       0x02, 0x72, 0xd9, 0x28, 0x6c, 0x95, 0x39, 0xed, 0x28, 0xf2, 0x39, 0x7f,
-       0x9f, 0xc6, 0xda, 0x32, 0xf7, 0xa5, 0xd2, 0x49, 0xd5, 0xfa, 0xbb, 0xd2,
-       0xd5, 0x38, 0xef, 0xa3, 0xce, 0x8d, 0x42, 0xef, 0xbf, 0xc3, 0xde, 0x62,
-       0x58, 0xdb, 0x88, 0xf3, 0x02, 0x65, 0xef, 0xfd, 0x7e, 0x2d, 0x7d, 0x9e,
-       0x0f, 0xb0, 0x0e, 0xf8, 0x3c, 0xe4, 0xb2, 0xd7, 0xbe, 0xca, 0xdc, 0xfd,
-       0x6f, 0xca, 0x1a, 0x4b, 0x3f, 0x6e, 0xd0, 0xb7, 0xf1, 0xbd, 0x1a, 0x91,
-       0xe5, 0x38, 0xf9, 0x87, 0xbc, 0x0c, 0xfa, 0xce, 0x56, 0x72, 0xd8, 0x2c,
-       0x83, 0x3f, 0x80, 0x0c, 0x28, 0xcb, 0x40, 0x06, 0x7c, 0x9f, 0x86, 0xbe,
-       0xd8, 0x33, 0x0c, 0xe9, 0x3e, 0xb2, 0xdc, 0xf4, 0xce, 0x2e, 0x57, 0x5b,
-       0x69, 0x26, 0xbd, 0xd4, 0xe9, 0x39, 0xc9, 0x6b, 0xfd, 0x2e, 0x48, 0xbe,
-       0x76, 0x4e, 0xf6, 0xd4, 0x16, 0xe4, 0x21, 0xeb, 0x01, 0xf0, 0x7b, 0xc9,
-       0x2d, 0x5a, 0xba, 0x57, 0x99, 0x2c, 0xe0, 0xec, 0xe2, 0xff, 0x74, 0x6e,
-       0xb5, 0xbf, 0x6d, 0x55, 0x67, 0xfc, 0xf1, 0xb5, 0x9d, 0xa4, 0xa1, 0x09,
-       0xb7, 0xae, 0x93, 0xb8, 0x69, 0x0a, 0x76, 0x7c, 0xdb, 0x46, 0x24, 0xad,
-       0x6e, 0x43, 0x46, 0xa3, 0x2e, 0x53, 0x4c, 0x12, 0xba, 0x74, 0xeb, 0x44,
-       0xda, 0x75, 0x5d, 0x37, 0xd0, 0x64, 0x9c, 0xb4, 0x14, 0x98, 0x54, 0x28,
-       0xac, 0x43, 0x08, 0xa9, 0xc6, 0x6d, 0x35, 0xa6, 0xa5, 0x71, 0xfa, 0x46,
-       0x10, 0x5f, 0xb0, 0x92, 0xb4, 0x65, 0x52, 0x84, 0x5b, 0x04, 0xdb, 0x3e,
-       0xb0, 0xd1, 0xa5, 0x8c, 0x3f, 0x60, 0xfb, 0x30, 0x26, 0xb1, 0x29, 0x2b,
-       0xb0, 0xb1, 0x7d, 0xea, 0x07, 0x26, 0x75, 0xda, 0x8a, 0xf7, 0xfb, 0x3d,
-       0xe7, 0x5e, 0xc7, 0x36, 0x41, 0x48, 0x8b, 0x14, 0xf9, 0x9e, 0x97, 0x7b,
-       0xee, 0xb9, 0xe7, 0x79, 0x7f, 0x9e, 0xdf, 0xed, 0x59, 0x27, 0x9f, 0xc0,
-       0xef, 0x38, 0x35, 0x67, 0x4b, 0xda, 0xee, 0x97, 0x9f, 0x6a, 0x2e, 0x9f,
-       0xf1, 0x49, 0x00, 0x3e, 0xa9, 0xc1, 0x16, 0x48, 0x8b, 0x13, 0xbb, 0x21,
-       0xf4, 0x29, 0xc3, 0xa0, 0x75, 0xdc, 0xf8, 0xcd, 0xb6, 0x19, 0xdf, 0x74,
-       0x06, 0xbe, 0xbb, 0xbb, 0xad, 0xc5, 0xcf, 0xf9, 0x1a, 0xff, 0xf6, 0x7d,
-       0xaf, 0x86, 0xd6, 0x2f, 0xd3, 0xd8, 0xcf, 0x9b, 0xaa, 0x67, 0x1d, 0xf0,
-       0x12, 0x73, 0xd3, 0x31, 0xcd, 0x3f, 0x84, 0xa7, 0xa8, 0xa3, 0xae, 0x40,
-       0x47, 0x0d, 0x50, 0x77, 0x0d, 0xce, 0xb9, 0xcc, 0x0f, 0x44, 0xe5, 0x0f,
-       0x93, 0xd4, 0xc3, 0x71, 0xf9, 0xfd, 0xe4, 0xb3, 0xd8, 0x4f, 0xa2, 0xc0,
-       0x1c, 0xe5, 0xf5, 0xe9, 0xac, 0x62, 0x92, 0x86, 0xd5, 0x07, 0x7e, 0x5a,
-       0xed, 0x40, 0xdc, 0xca, 0xad, 0x0d, 0xab, 0xbe, 0x39, 0xa2, 0xb5, 0xdd,
-       0xb8, 0xd5, 0x21, 0xd7, 0xcf, 0x1b, 0x1d, 0x1b, 0x9e, 0x8a, 0x06, 0x86,
-       0xe7, 0x69, 0x97, 0x92, 0xb1, 0x8c, 0x55, 0x2f, 0x07, 0xa3, 0xcc, 0x3d,
-       0xa7, 0xa8, 0x9f, 0x61, 0x0b, 0xbb, 0xed, 0x8c, 0xd5, 0xe0, 0xd9, 0x9f,
-       0x58, 0x8d, 0x9e, 0x3d, 0xe2, 0xe9, 0x59, 0x8e, 0xa5, 0x40, 0x53, 0xda,
-       0xa2, 0xc4, 0xf4, 0x88, 0x95, 0x84, 0xcd, 0xc3, 0xf5, 0x02, 0xd7, 0x8f,
-       0xcb, 0xd1, 0x85, 0xc3, 0xf0, 0xbf, 0xbb, 0xed, 0xbd, 0xb4, 0xab, 0xf6,
-       0x00, 0xf1, 0x38, 0x78, 0xfe, 0x86, 0x9a, 0xb5, 0x1e, 0xf6, 0xd6, 0xe2,
-       0x38, 0xe4, 0x7c, 0x8a, 0xf5, 0xda, 0x7a, 0xe6, 0x73, 0x74, 0xaf, 0xd5,
-       0x73, 0xf7, 0x94, 0x9f, 0x7b, 0x32, 0xef, 0x78, 0x58, 0x30, 0xfc, 0xc2,
-       0x17, 0xfa, 0x76, 0x84, 0xcf, 0xe4, 0xf3, 0x9a, 0x65, 0x68, 0x3f, 0xf4,
-       0xcb, 0x14, 0xff, 0xb3, 0x5e, 0xed, 0x0a, 0xf1, 0x4a, 0xb4, 0x7d, 0x05,
-       0xdb, 0xf4, 0x35, 0x6f, 0xbd, 0xad, 0xad, 0xd2, 0x18, 0xad, 0x98, 0xcf,
-       0xdc, 0x0a, 0xdb, 0x71, 0xc9, 0x2e, 0xf0, 0xb7, 0x54, 0x8a, 0x38, 0x75,
-       0xb2, 0xd7, 0x5e, 0x5f, 0xb3, 0xc6, 0x16, 0xf4, 0x19, 0x9f, 0x20, 0x38,
-       0x15, 0xf0, 0x7c, 0x8b, 0xbb, 0xe9, 0x37, 0x79, 0xd7, 0x0d, 0x9a, 0x93,
-       0x89, 0x5b, 0xed, 0x35, 0xef, 0x71, 0x77, 0xd9, 0x0e, 0xc7, 0x2d, 0xea,
-       0xce, 0x60, 0x54, 0x9a, 0xc9, 0x43, 0x25, 0xf5, 0xe3, 0x43, 0x8e, 0xc1,
-       0x5c, 0x44, 0x9d, 0xf1, 0x56, 0xe6, 0xec, 0xdf, 0xd1, 0x73, 0x6b, 0xa2,
-       0x4f, 0x80, 0x6b, 0xf0, 0xc9, 0xe7, 0xf2, 0xbd, 0xcc, 0xf5, 0x62, 0xfd,
-       0x46, 0xae, 0xef, 0x7a, 0xe7, 0x9c, 0x70, 0xb3, 0xd6, 0x7d, 0x92, 0x39,
-       0x6f, 0xf8, 0x6f, 0xc8, 0x01, 0xef, 0x35, 0xa3, 0x3d, 0x4f, 0x9b, 0xf0,
-       0x45, 0xeb, 0xf8, 0xb6, 0xa1, 0x4b, 0x6d, 0xc3, 0x89, 0x3c, 0xf9, 0x93,
-       0x7c, 0xe9, 0xf3, 0xa3, 0xaf, 0xf3, 0xc8, 0xa3, 0xd4, 0xb3, 0xfd, 0x72,
-       0x26, 0xcf, 0xb3, 0x49, 0x69, 0x4d, 0x6b, 0xe3, 0xd9, 0x71, 0xc5, 0x64,
-       0x75, 0x4e, 0x25, 0x5e, 0xce, 0xca, 0xa0, 0x5c, 0x71, 0x79, 0x66, 0x89,
-       0x42, 0x3a, 0xd8, 0x54, 0xf1, 0xfe, 0xfb, 0xf5, 0xcc, 0xc2, 0xea, 0x33,
-       0xc6, 0x30, 0xf7, 0x79, 0x8f, 0xde, 0xcd, 0x7a, 0xb6, 0xe9, 0x2a, 0xfa,
-       0x7c, 0x53, 0xcf, 0x29, 0x0c, 0x9d, 0xc8, 0xfa, 0x7e, 0x38, 0xc2, 0x7b,
-       0xf8, 0x5c, 0xfa, 0x7c, 0x7c, 0x16, 0x79, 0xaf, 0x13, 0x16, 0xbb, 0x57,
-       0x82, 0x3b, 0x20, 0xfa, 0x3b, 0x58, 0x47, 0x0e, 0x40, 0x56, 0x37, 0x1a,
-       0x0c, 0xcc, 0x98, 0xf1, 0x35, 0xd2, 0xd6, 0x55, 0x9c, 0x23, 0x62, 0x15,
-       0xf8, 0xd1, 0x27, 0x5e, 0xba, 0x8d, 0xf5, 0xd2, 0x9e, 0xbf, 0xde, 0x87,
-       0xf5, 0x1d, 0xaf, 0xae, 0x3e, 0xb9, 0x8d, 0xbc, 0x3a, 0xa2, 0xf5, 0x41,
-       0xde, 0x43, 0x39, 0xe6, 0x99, 0x91, 0x2e, 0xef, 0xe3, 0x7e, 0xb6, 0xb7,
-       0xd4, 0xd0, 0x31, 0xe9, 0xed, 0xcf, 0x1f, 0x0f, 0x4b, 0xb8, 0x95, 0x3a,
-       0x2e, 0x2a, 0xc9, 0x29, 0xc6, 0x2c, 0xb0, 0x5d, 0x63, 0x5c, 0xeb, 0xcb,
-       0x75, 0x71, 0xfa, 0xff, 0xd4, 0xc5, 0x69, 0xeb, 0x23, 0xe5, 0x9d, 0xb0,
-       0xe6, 0xb1, 0xbe, 0x98, 0xae, 0x85, 0x2a, 0xba, 0xfa, 0xb5, 0xfb, 0x68,
-       0x99, 0x8e, 0x3f, 0xc9, 0xd3, 0x5e, 0xa5, 0x34, 0xa7, 0xfc, 0xb7, 0x49,
-       0x9e, 0x2d, 0xf7, 0x78, 0x85, 0x7b, 0x1c, 0x5c, 0x74, 0x89, 0x83, 0xf9,
-       0x96, 0xca, 0xf0, 0xa9, 0x3c, 0x75, 0x4c, 0x93, 0xcc, 0x4d, 0xfb, 0x7a,
-       0x66, 0xd4, 0xf3, 0x71, 0x73, 0x6b, 0xeb, 0x54, 0xcf, 0xc0, 0xbb, 0x71,
-       0x86, 0x3d, 0xfb, 0xd2, 0x21, 0xb3, 0xe7, 0x69, 0x77, 0x93, 0xe8, 0x8b,
-       0x06, 0x66, 0xe7, 0x59, 0x9b, 0x24, 0x16, 0x65, 0x50, 0x58, 0xf7, 0x1f,
-       0xb6, 0x4f, 0x40, 0xde, 0x62, 0xf2, 0xe1, 0x24, 0x7d, 0xfa, 0x3a, 0xf8,
-       0xc6, 0xcd, 0x35, 0xe7, 0xbb, 0xbd, 0xec, 0x13, 0x56, 0xd3, 0xbd, 0xa3,
-       0x4d, 0x1a, 0xc9, 0xe7, 0x8e, 0x7d, 0x5d, 0xe8, 0x83, 0xf1, 0x3a, 0x83,
-       0x58, 0x80, 0xb1, 0x47, 0x5c, 0x63, 0x8f, 0xd9, 0x02, 0xfb, 0x9a, 0xbc,
-       0xbc, 0x52, 0x93, 0xf2, 0x0a, 0xf9, 0x2d, 0xad, 0xfe, 0xf7, 0x80, 0xea,
-       0xac, 0xdc, 0x64, 0xb7, 0xc1, 0xb1, 0xd8, 0x31, 0xe5, 0x3d, 0xa9, 0xe2,
-       0xbd, 0x98, 0xef, 0x4b, 0xb6, 0x19, 0xdf, 0xca, 0x56, 0x7d, 0x13, 0xd6,
-       0x79, 0xb4, 0x2b, 0x5c, 0x9f, 0xbc, 0x41, 0x1e, 0xa1, 0xce, 0xf3, 0xe7,
-       0xf9, 0xf4, 0xf0, 0xdb, 0x9c, 0x4f, 0xfe, 0xaf, 0xc4, 0x22, 0xf8, 0xb2,
-       0xea, 0xf7, 0xf9, 0x72, 0xc7, 0xb1, 0x4a, 0x9b, 0x40, 0xb9, 0xab, 0xac,
-       0x4f, 0xda, 0x12, 0x99, 0x5a, 0xa6, 0xcb, 0x50, 0x2f, 0xf7, 0xff, 0x3c,
-       0x73, 0xbb, 0x90, 0xb7, 0x95, 0x68, 0x73, 0x4c, 0x69, 0x93, 0x06, 0x6d,
-       0x22, 0x4a, 0x1b, 0xc6, 0x7b, 0x4f, 0x79, 0xfc, 0xd6, 0x84, 0xf3, 0x62,
-       0xae, 0x16, 0xba, 0x6e, 0x1f, 0x75, 0xfe, 0x33, 0x6d, 0x5a, 0x1f, 0x74,
-       0xa8, 0xfb, 0x56, 0x43, 0x9f, 0xb1, 0xbd, 0x59, 0xfd, 0x11, 0x13, 0x6f,
-       0xc5, 0x35, 0x0f, 0x1a, 0x84, 0x7e, 0x9e, 0x9d, 0x84, 0xaf, 0x46, 0xdc,
-       0x5b, 0x15, 0xad, 0x1e, 0xf7, 0xce, 0xeb, 0x55, 0xa5, 0x0d, 0x65, 0x80,
-       0x7a, 0x73, 0x0d, 0xd6, 0xdb, 0x13, 0xed, 0x01, 0x7f, 0xbd, 0x82, 0xfe,
-       0x8d, 0x1a, 0x4f, 0x04, 0x21, 0xf3, 0x37, 0x26, 0x5b, 0xbd, 0x18, 0xce,
-       0x41, 0x1b, 0x71, 0xeb, 0x64, 0x84, 0x31, 0x05, 0xda, 0x5d, 0x52, 0x37,
-       0x85, 0xf8, 0x15, 0x7a, 0x7c, 0x51, 0xed, 0x51, 0x0f, 0xc6, 0xef, 0x20,
-       0xce, 0x0f, 0xd7, 0x87, 0x71, 0x5f, 0xb7, 0xc1, 0x22, 0x44, 0x37, 0xe9,
-       0x99, 0xce, 0x4e, 0x26, 0x62, 0x87, 0xc4, 0xeb, 0x1b, 0x73, 0x55, 0x1f,
-       0x2c, 0xef, 0xeb, 0x01, 0xd9, 0x53, 0xb6, 0x17, 0x8c, 0xa3, 0xe1, 0xc3,
-       0x4f, 0x1b, 0x7b, 0x90, 0x2b, 0xf4, 0x28, 0x3e, 0x2a, 0x38, 0xb0, 0x80,
-       0xb3, 0xa4, 0x4f, 0xba, 0x04, 0x3f, 0xdc, 0xc5, 0x19, 0xd2, 0xef, 0x2e,
-       0x1d, 0x3f, 0xe9, 0xa6, 0x58, 0x1f, 0x83, 0x3e, 0x38, 0x2e, 0xc3, 0x88,
-       0x0b, 0x86, 0x83, 0xcd, 0xcc, 0x2b, 0xc3, 0x37, 0xcc, 0x7a, 0xb9, 0xc7,
-       0x1e, 0xe6, 0x4c, 0xe5, 0xec, 0x3c, 0xf7, 0x4e, 0xd9, 0x36, 0xb1, 0xf7,
-       0xec, 0x24, 0xf7, 0x6b, 0xf2, 0x10, 0x6c, 0x5b, 0x53, 0x2e, 0x7e, 0x79,
-       0x16, 0x7d, 0xf8, 0xed, 0x87, 0x3c, 0x70, 0x2e, 0x7e, 0xe7, 0x97, 0xe4,
-       0xbd, 0xf3, 0xbe, 0x6d, 0x0f, 0xc8, 0xbb, 0x4e, 0xe9, 0xf8, 0x09, 0x77,
-       0x2d, 0xcf, 0xc0, 0xcd, 0xb2, 0x66, 0xed, 0x38, 0x6e, 0x4e, 0x4a, 0xa5,
-       0x45, 0x77, 0x71, 0xad, 0xa5, 0xb4, 0xa4, 0xfc, 0x7f, 0x80, 0x33, 0xbc,
-       0x76, 0xaf, 0x25, 0x86, 0x7e, 0xa4, 0xcd, 0xe7, 0x6b, 0x7f, 0x95, 0xb6,
-       0xc0, 0xd7, 0x7f, 0xe4, 0x47, 0xf2, 0xe5, 0x92, 0xec, 0x54, 0xfd, 0xbf,
-       0xd2, 0x7d, 0x95, 0xba, 0xdf, 0xf7, 0x6f, 0xa9, 0xdf, 0xc9, 0x8b, 0x31,
-       0x8d, 0x0f, 0x36, 0x4d, 0xd5, 0xea, 0x84, 0x1f, 0x78, 0x75, 0x85, 0x95,
-       0x78, 0xef, 0x80, 0xa7, 0x17, 0x52, 0xea, 0x3b, 0xa7, 0x6c, 0xea, 0x07,
-       0xee, 0xa7, 0x51, 0xc6, 0x67, 0x6e, 0x83, 0x26, 0xbe, 0x0e, 0x66, 0xdc,
-       0xe7, 0xeb, 0x8e, 0x66, 0xcf, 0x17, 0xb6, 0xa4, 0xf3, 0x2c, 0x7d, 0x27,
-       0x07, 0x7a, 0xb4, 0x45, 0xd2, 0x63, 0x41, 0x49, 0x9e, 0x6d, 0x89, 0x19,
-       0x5f, 0x97, 0xfc, 0x07, 0x79, 0xd3, 0x3e, 0xb6, 0x37, 0xa0, 0xff, 0x4e,
-       0xe1, 0xb3, 0x0d, 0x3f, 0x43, 0x9e, 0xf7, 0xf9, 0x63, 0x76, 0x0d, 0x8f,
-       0xee, 0xf0, 0x78, 0x94, 0xe3, 0x96, 0xa9, 0x7f, 0x60, 0x6e, 0xe7, 0x59,
-       0xee, 0xd1, 0xdc, 0xd7, 0x79, 0xd6, 0xc4, 0xeb, 0xd5, 0xf7, 0xf5, 0x94,
-       0xef, 0xc3, 0x78, 0x97, 0x62, 0xc3, 0xb0, 0xf6, 0xce, 0x7e, 0xf8, 0x74,
-       0x3d, 0xb4, 0x39, 0xb4, 0xdf, 0x1b, 0xdd, 0x9d, 0x42, 0x7e, 0x4f, 0x78,
-       0x3c, 0x47, 0x7d, 0x13, 0xf1, 0xf4, 0xcd, 0xb2, 0x7d, 0x19, 0x36, 0xf8,
-       0x13, 0xe6, 0x44, 0x2a, 0xec, 0xcb, 0x43, 0xe6, 0xdd, 0xaa, 0xec, 0xcb,
-       0x9d, 0xde, 0x3a, 0xfe, 0x98, 0xaf, 0x57, 0xfc, 0xb6, 0xaf, 0x57, 0x6a,
-       0x7d, 0x5a, 0x9f, 0xf6, 0xd5, 0xb8, 0xaf, 0xca, 0x98, 0x2f, 0xb7, 0x62,
-       0xde, 0x25, 0x83, 0x98, 0x8d, 0x3e, 0x65, 0x22, 0x6b, 0x30, 0xd3, 0xd6,
-       0x19, 0x8b, 0xb8, 0x0f, 0xe7, 0x67, 0x32, 0x14, 0xb9, 0xad, 0xb1, 0xf5,
-       0xa9, 0x99, 0x51, 0xcd, 0xf3, 0xcc, 0xba, 0x9e, 0xde, 0x89, 0xee, 0x86,
-       0x5c, 0xcd, 0x47, 0x96, 0x31, 0x45, 0x4f, 0x1e, 0x1b, 0x82, 0x1d, 0x4a,
-       0x69, 0xbd, 0xec, 0x71, 0xec, 0xb7, 0x5f, 0xf1, 0x5c, 0xab, 0x9c, 0xe7,
-       0x64, 0x97, 0x5d, 0xd2, 0xda, 0x4d, 0xc3, 0x40, 0xf6, 0x58, 0xc3, 0x69,
-       0x9f, 0xef, 0xc9, 0x4f, 0x4f, 0x1e, 0x1b, 0x9f, 0x2e, 0x0d, 0x86, 0xb6,
-       0x75, 0xdb, 0x39, 0x59, 0x0f, 0x9a, 0x0f, 0xca, 0xa3, 0x8a, 0x1d, 0x7e,
-       0x0d, 0xe3, 0xfb, 0x18, 0x5f, 0x26, 0x42, 0x8a, 0x09, 0x4e, 0xc4, 0x26,
-       0x20, 0x8b, 0x19, 0x37, 0xd1, 0x35, 0x14, 0x5c, 0xcd, 0xdc, 0x0d, 0x62,
-       0x66, 0xfa, 0x59, 0xc4, 0x14, 0x3c, 0x2b, 0x87, 0xdc, 0x8d, 0xee, 0xa2,
-       0x64, 0x3d, 0x4c, 0x3e, 0x6b, 0x42, 0xf5, 0x32, 0xe1, 0x86, 0x1a, 0x86,
-       0x8a, 0x46, 0x06, 0x46, 0x82, 0xa9, 0x55, 0x27, 0x9d, 0x68, 0xc3, 0xce,
-       0x22, 0x64, 0xbc, 0x08, 0xfd, 0x5f, 0x8c, 0x05, 0x86, 0x15, 0x9b, 0xf6,
-       0x55, 0x19, 0x6a, 0xa5, 0x9f, 0x4f, 0x7d, 0xf2, 0x35, 0xb9, 0x61, 0x6f,
-       0x96, 0x1b, 0x5d, 0xc4, 0x63, 0xf6, 0xa2, 0x4d, 0x5d, 0xd2, 0x8f, 0xbe,
-       0x24, 0xfa, 0x1a, 0x94, 0x1f, 0x35, 0x3e, 0x83, 0xce, 0xba, 0x61, 0x53,
-       0x57, 0xdd, 0xc5, 0x5f, 0xbc, 0xeb, 0x9f, 0x41, 0x13, 0x62, 0x3b, 0xb6,
-       0xa0, 0x4d, 0x1d, 0x67, 0xd7, 0xf4, 0xb7, 0xa3, 0x7d, 0x2f, 0xd6, 0xa8,
-       0xd3, 0xf7, 0xb3, 0x9c, 0x6d, 0xa6, 0xce, 0x59, 0x35, 0x67, 0x4d, 0x4d,
-       0xfb, 0xdd, 0x16, 0x83, 0x4f, 0xb8, 0x45, 0x7a, 0x67, 0x53, 0xb2, 0xab,
-       0xad, 0xba, 0xfd, 0xcf, 0x9a, 0x76, 0xb3, 0xac, 0x6a, 0x21, 0x19, 0x9e,
-       0x68, 0xad, 0xee, 0xf7, 0xf9, 0xc9, 0x6f, 0xb7, 0xe1, 0x7d, 0x13, 0x30,
-       0x78, 0x49, 0x8d, 0xa5, 0x6e, 0x44, 0xf9, 0xac, 0xbf, 0xd6, 0xdc, 0xc3,
-       0x6b, 0xde, 0xc3, 0x7b, 0x99, 0xd7, 0xfb, 0x37, 0xfb, 0x71, 0x0f, 0x73,
-       0x02, 0xcc, 0x6b, 0x90, 0x67, 0x57, 0x8a, 0xb3, 0x38, 0xe7, 0xf3, 0xf9,
-       0x86, 0x74, 0x99, 0xf7, 0x7c, 0xbd, 0x12, 0x2b, 0x63, 0xd5, 0x76, 0xe6,
-       0xfd, 0x9c, 0x30, 0x69, 0xa7, 0x35, 0xa9, 0xd8, 0x75, 0xd0, 0xf9, 0x20,
-       0xe8, 0xfc, 0x40, 0x90, 0x71, 0x61, 0xa3, 0x47, 0x6b, 0x47, 0x86, 0x8b,
-       0x6f, 0x43, 0xc6, 0xc9, 0xa3, 0xf0, 0x29, 0x8a, 0x96, 0x87, 0xcf, 0xe8,
-       0x83, 0x4d, 0x73, 0x25, 0xa8, 0x79, 0x07, 0xc4, 0xf7, 0x73, 0xd7, 0x64,
-       0x78, 0x92, 0x39, 0x01, 0xf2, 0x33, 0xe3, 0xfa, 0x14, 0xc6, 0x6e, 0x62,
-       0xae, 0x0b, 0x19, 0x1e, 0x05, 0xbf, 0x86, 0xc4, 0x99, 0xda, 0x22, 0xd9,
-       0xb1, 0x51, 0xf5, 0x01, 0x3a, 0x61, 0xa3, 0x4e, 0xb8, 0x23, 0x72, 0xf2,
-       0xf2, 0xdd, 0x90, 0x55, 0xc6, 0xfd, 0x9a, 0xd3, 0x28, 0x85, 0xd5, 0x37,
-       0xa7, 0xcf, 0xc1, 0x3c, 0x9c, 0xa9, 0x31, 0x1b, 0xb9, 0x7d, 0x24, 0x26,
-       0xcd, 0x23, 0x32, 0x3d, 0x63, 0x2b, 0xde, 0x25, 0x25, 0xb7, 0x4b, 0xa4,
-       0x5d, 0x66, 0x5f, 0x1c, 0xba, 0x8a, 0xbe, 0x7c, 0x2e, 0x62, 0xce, 0x72,
-       0x74, 0x1d, 0x63, 0xe2, 0xe4, 0x54, 0xe5, 0x1a, 0x8a, 0x91, 0xc1, 0xd8,
-       0xa5, 0x16, 0x23, 0x33, 0x8c, 0x8f, 0x3f, 0x2a, 0xa5, 0xa2, 0x7c, 0x26,
-       0xe7, 0xb2, 0x76, 0x4b, 0x1e, 0xe1, 0xde, 0xfe, 0xe3, 0xf1, 0xf2, 0x4b,
-       0x58, 0x2f, 0x2e, 0x9d, 0xaf, 0x8f, 0x6a, 0x5c, 0x7f, 0xa2, 0x2a, 0x86,
-       0x35, 0xf9, 0x02, 0x13, 0xc7, 0x5e, 0x93, 0x89, 0x05, 0xd2, 0x87, 0x36,
-       0x3e, 0x20, 0x3f, 0x77, 0xba, 0xed, 0xc7, 0xb4, 0xd6, 0x98, 0x48, 0xb1,
-       0x3e, 0xd3, 0xe8, 0x24, 0xed, 0x39, 0x09, 0xf5, 0x7f, 0x03, 0xd7, 0x8c,
-       0x6b, 0x73, 0x6e, 0xb7, 0xfb, 0x98, 0xf8, 0x38, 0x90, 0x8d, 0xa9, 0xfa,
-       0xc0, 0xad, 0xd2, 0xb5, 0x7d, 0x9c, 0x63, 0x70, 0x20, 0x12, 0x20, 0xad,
-       0x3e, 0xb8, 0x8b, 0xf8, 0x99, 0xea, 0xfc, 0xdf, 0xfd, 0x47, 0xf6, 0xf6,
-       0x25, 0x5e, 0x64, 0x0c, 0x1b, 0x76, 0x0e, 0xac, 0x33, 0xef, 0x9a, 0xcd,
-       0xae, 0x11, 0xad, 0x9f, 0x1d, 0xfd, 0xbb, 0x43, 0x3c, 0x44, 0x22, 0x56,
-       0x6f, 0x31, 0x0f, 0x4e, 0x1d, 0xc7, 0x9a, 0x0a, 0x73, 0x6e, 0xc4, 0xf2,
-       0x37, 0xc8, 0xa5, 0x1e, 0x4b, 0xee, 0x0f, 0xa5, 0xe2, 0x96, 0x6c, 0x8a,
-       0x9f, 0x15, 0x3c, 0x93, 0xf5, 0x95, 0x85, 0x44, 0x96, 0xf3, 0x43, 0x53,
-       0x5c, 0x2f, 0xae, 0xf1, 0x4a, 0x72, 0x53, 0xa9, 0xf4, 0x94, 0x2b, 0x81,
-       0xe4, 0xd6, 0x8f, 0x4b, 0xac, 0x85, 0x5b, 0xaf, 0x7f, 0x11, 0x4e, 0x41,
-       0xbf, 0x1d, 0x98, 0x30, 0x98, 0xc3, 0x89, 0xa3, 0x9d, 0x0b, 0x6c, 0xa7,
-       0x77, 0x99, 0xf6, 0x61, 0xb4, 0xeb, 0x3c, 0xac, 0xd3, 0x0f, 0x8f, 0x76,
-       0x16, 0x9e, 0x58, 0x67, 0xe2, 0xef, 0x25, 0xc5, 0x7f, 0xbd, 0x53, 0x15,
-       0xd3, 0xa4, 0x02, 0x63, 0xf9, 0xd1, 0xc0, 0x68, 0xde, 0xea, 0x69, 0x00,
-       0xad, 0xe6, 0x5d, 0xe6, 0x6a, 0xfc, 0x9c, 0x15, 0xf3, 0xfd, 0x22, 0x4f,
-       0x2a, 0x46, 0x8a, 0x35, 0x45, 0x4b, 0x7d, 0xa1, 0x83, 0xf3, 0xcc, 0xf1,
-       0x47, 0x54, 0x1f, 0x1c, 0x5a, 0x68, 0x96, 0x9c, 0xbd, 0x56, 0x72, 0x2a,
-       0xe3, 0x51, 0xd5, 0x01, 0x96, 0xb3, 0x15, 0x7d, 0xdc, 0xf7, 0x43, 0x8a,
-       0x8b, 0x78, 0x23, 0xdf, 0x8e, 0x36, 0x73, 0xcd, 0xdb, 0x6b, 0xfa, 0x2b,
-       0xeb, 0xb2, 0x09, 0xdb, 0xb2, 0x6a, 0x6b, 0xb2, 0xec, 0xab, 0xad, 0xc5,
-       0x9e, 0x92, 0x6b, 0xe4, 0x9b, 0xa2, 0x9f, 0x73, 0x77, 0xbd, 0x9c, 0xfb,
-       0xf7, 0xb1, 0x26, 0xd7, 0x96, 0x74, 0x68, 0xa0, 0xa1, 0xe7, 0xc4, 0x64,
-       0xf0, 0xe6, 0x72, 0xfe, 0x14, 0xed, 0x85, 0x72, 0xad, 0x1c, 0x63, 0xcf,
-       0xc0, 0x17, 0xc9, 0xc1, 0xaf, 0xc8, 0x7a, 0xdf, 0x1f, 0x70, 0xbc, 0x7c,
-       0xff, 0x97, 0xec, 0xa9, 0x51, 0xeb, 0xec, 0x56, 0x55, 0x9d, 0xfd, 0x7b,
-       0xb8, 0x97, 0x35, 0xf6, 0x6c, 0xa9, 0x0e, 0xbc, 0x5b, 0x47, 0x9c, 0x48,
-       0x79, 0x3e, 0x75, 0xbc, 0xea, 0x72, 0x5d, 0x6b, 0xa7, 0xb7, 0x56, 0x10,
-       0x7a, 0x7e, 0x7c, 0xd2, 0x9f, 0x73, 0x5c, 0xea, 0x7b, 0x13, 0xb1, 0xa0,
-       0xc5, 0x39, 0x46, 0xdf, 0x0f, 0xb9, 0xc7, 0xa1, 0xc7, 0xa9, 0xf3, 0xf9,
-       0xde, 0x0e, 0x7c, 0x3d, 0xea, 0x02, 0xea, 0x73, 0xb5, 0x01, 0xf1, 0x1c,
-       0x74, 0xfd, 0x70, 0xd1, 0x7c, 0xeb, 0xf5, 0xf5, 0x60, 0x62, 0x3a, 0xa3,
-       0xba, 0x01, 0xfe, 0x5e, 0xf1, 0x0d, 0xe6, 0x83, 0x5e, 0x94, 0x40, 0x65,
-       0x9d, 0x86, 0xb1, 0x19, 0x6b, 0x1a, 0x4d, 0xd0, 0x0d, 0x22, 0x57, 0xc0,
-       0x1b, 0x57, 0xe7, 0xc9, 0xaf, 0xc1, 0x56, 0x13, 0x5f, 0x2d, 0x6e, 0xb7,
-       0xa4, 0x55, 0x6b, 0x9f, 0x39, 0x27, 0x42, 0xff, 0x64, 0x30, 0xd9, 0x0b,
-       0x3f, 0x5b, 0xb1, 0x07, 0xcc, 0x57, 0x8e, 0x23, 0x1e, 0xab, 0xcc, 0xb1,
-       0x40, 0xbe, 0xc6, 0xd8, 0x9f, 0x81, 0x5f, 0xb9, 0x5c, 0xf7, 0xc8, 0x15,
-       0x4e, 0x6a, 0x6e, 0x73, 0x76, 0xbe, 0x49, 0x75, 0xec, 0x6c, 0x61, 0x04,
-       0xe7, 0x22, 0x9b, 0xad, 0x81, 0x9c, 0xd7, 0x1f, 0x96, 0x42, 0x81, 0x6d,
-       0xe9, 0xa8, 0xd3, 0x73, 0xf7, 0x6b, 0x3b, 0xb6, 0xcc, 0xc1, 0x57, 0x2c,
-       0x2c, 0x38, 0xf8, 0xef, 0xc2, 0x7f, 0x0f, 0xfe, 0x77, 0xcb, 0xd0, 0x14,
-       0xfd, 0x57, 0xd6, 0x72, 0x9a, 0x6a, 0x9e, 0x4f, 0x1f, 0xa9, 0x43, 0x71,
-       0x60, 0x39, 0x2f, 0xce, 0xc9, 0x15, 0x6a, 0xe5, 0x84, 0x79, 0x52, 0x5f,
-       0x47, 0x30, 0x5f, 0xea, 0xd7, 0xfa, 0x2a, 0x6b, 0x58, 0x96, 0x57, 0xf7,
-       0x22, 0x4f, 0x37, 0xca, 0xa1, 0x82, 0x5f, 0xbb, 0x8a, 0xc9, 0xa3, 0xe5,
-       0xda, 0x95, 0xa4, 0x83, 0x03, 0xb7, 0x1e, 0xcc, 0x4c, 0x2a, 0x9e, 0xc0,
-       0xb2, 0x06, 0xae, 0x3d, 0x38, 0xb1, 0xf0, 0xee, 0x83, 0xcb, 0x98, 0x70,
-       0x8c, 0x2d, 0xac, 0x84, 0x19, 0x22, 0x96, 0xee, 0x33, 0xf2, 0x10, 0x0d,
-       0x27, 0xf6, 0xed, 0xc7, 0x3c, 0xc4, 0xd9, 0x6d, 0xb0, 0x97, 0xf1, 0xcb,
-       0x7e, 0x3c, 0x4a, 0x1c, 0x29, 0xef, 0xab, 0xc4, 0x7e, 0x84, 0x70, 0xfe,
-       0x12, 0xb0, 0x9c, 0x2c, 0xf6, 0x71, 0xa1, 0xdd, 0xf8, 0x81, 0xc4, 0x99,
-       0x26, 0x2a, 0xb0, 0x47, 0x3e, 0xd6, 0xf4, 0x65, 0xac, 0x95, 0x96, 0xdf,
-       0x14, 0x1f, 0x96, 0x5f, 0x16, 0x47, 0x21, 0xdf, 0x13, 0x58, 0xf3, 0x80,
-       0xfc, 0xa2, 0xb8, 0x4f, 0xde, 0x2a, 0x8e, 0xc9, 0x9b, 0xc5, 0xdd, 0x88,
-       0xa9, 0x46, 0x88, 0xf5, 0xf4, 0xb0, 0xd2, 0x83, 0x32, 0x7e, 0x4e, 0x31,
-       0x80, 0x37, 0xe9, 0xf7, 0x1c, 0x55, 0x3f, 0x9b, 0xf8, 0xfa, 0xc4, 0xaf,
-       0x18, 0xcf, 0x13, 0x9b, 0x59, 0x28, 0xfa, 0x18, 0x8e, 0x89, 0x0e, 0x3c,
-       0xdb, 0xe6, 0xb7, 0x29, 0xc3, 0xe7, 0x22, 0x81, 0x91, 0x73, 0xa1, 0xc0,
-       0x03, 0xfa, 0x9d, 0x0b, 0xeb, 0x9d, 0x25, 0x39, 0xe9, 0x3a, 0xe4, 0xcd,
-       0xfe, 0x61, 0xc8, 0xc2, 0x08, 0x54, 0xfd, 0x2e, 0x67, 0xad, 0x80, 0xa4,
-       0xa9, 0x4f, 0xe0, 0x67, 0x26, 0x4f, 0xbb, 0x92, 0xc9, 0xcf, 0x05, 0x0c,
-       0x1e, 0xcd, 0x46, 0xbb, 0x07, 0xed, 0x57, 0xbd, 0xf6, 0x0e, 0xc9, 0xcc,
-       0x48, 0xea, 0x43, 0xf5, 0x87, 0x5f, 0xf1, 0xfa, 0xfa, 0xd1, 0x07, 0xce,
-       0xbc, 0xc0, 0xbe, 0x0b, 0x5e, 0x1f, 0xcf, 0x84, 0xb5, 0xfa, 0xb8, 0xf2,
-       0x55, 0xc6, 0x1e, 0x13, 0xfd, 0xae, 0x41, 0x6b, 0xf1, 0x4b, 0xed, 0x46,
-       0xb7, 0x11, 0x13, 0xf8, 0x8f, 0x76, 0xc6, 0x60, 0x05, 0xc8, 0xd7, 0x5d,
-       0xd0, 0x89, 0x7f, 0xd9, 0xbc, 0xdc, 0xb6, 0x06, 0x3e, 0xad, 0xc0, 0x68,
-       0x7f, 0x2a, 0x9d, 0x0b, 0xff, 0xf2, 0xf0, 0xbc, 0x07, 0xf1, 0x6e, 0x38,
-       0xab, 0x3c, 0x71, 0xe3, 0x71, 0xc8, 0x76, 0x93, 0xac, 0x3d, 0x43, 0x7a,
-       0x75, 0x43, 0x57, 0xa7, 0x20, 0xb7, 0xae, 0xcc, 0x17, 0x43, 0x81, 0xe1,
-       0x7c, 0x4a, 0x0c, 0x9e, 0xda, 0x92, 0x74, 0x34, 0x25, 0xa7, 0xfa, 0x12,
-       0x5d, 0xcc, 0x43, 0x66, 0x7a, 0x5d, 0xb9, 0x58, 0xa4, 0x3d, 0xce, 0xca,
-       0xa5, 0xbe, 0x84, 0x5b, 0x10, 0xe2, 0x62, 0x5c, 0xb9, 0x04, 0xd9, 0xfc,
-       0xdd, 0xb9, 0xdd, 0xf2, 0x68, 0x5e, 0xfd, 0xe0, 0xee, 0xb0, 0xbc, 0x20,
-       0x17, 0xfb, 0x5e, 0xb8, 0x79, 0xd1, 0x7d, 0x04, 0x67, 0x4a, 0x3e, 0xcc,
-       0x74, 0x98, 0x7d, 0x2b, 0x0e, 0x49, 0x98, 0x0f, 0xd1, 0x9a, 0x9a, 0x53,
-       0x2f, 0x43, 0xfb, 0x23, 0x5e, 0x5c, 0x0e, 0x9f, 0x3b, 0xe0, 0x9a, 0x7a,
-       0x4a, 0xc0, 0xdf, 0x67, 0x18, 0x7e, 0x0c, 0xef, 0xf3, 0x69, 0xe3, 0xaf,
-       0xd3, 0x1e, 0x18, 0x9a, 0x69, 0x96, 0xd0, 0x85, 0xaf, 0x80, 0xae, 0x21,
-       0x39, 0xd8, 0x5b, 0x2a, 0x7d, 0xc7, 0x0d, 0xc5, 0x27, 0x10, 0xa3, 0x60,
-       0xff, 0xb2, 0xe6, 0x74, 0x0b, 0x68, 0xd2, 0x20, 0xd1, 0xd3, 0xfe, 0xf3,
-       0xea, 0x3d, 0x2c, 0xc3, 0x99, 0x35, 0xc6, 0x96, 0xf9, 0xd8, 0x06, 0x7f,
-       0x3d, 0x83, 0x29, 0xeb, 0xb4, 0x7a, 0x03, 0xde, 0x77, 0x12, 0x5e, 0x7b,
-       0x6b, 0xe0, 0xfe, 0x50, 0xab, 0x84, 0x9c, 0x67, 0xd7, 0x13, 0x1b, 0xb9,
-       0x98, 0xf7, 0xfb, 0xe1, 0x27, 0x86, 0x7c, 0x7f, 0x58, 0xb6, 0x2d, 0x9f,
-       0xb5, 0x6c, 0xeb, 0x5c, 0xf8, 0xae, 0xb7, 0x66, 0xca, 0x9b, 0x8b, 0x98,
-       0x23, 0xb6, 0x5a, 0xed, 0x93, 0x99, 0xfb, 0x5f, 0x79, 0xba, 0x37, 0xf1,
-       0x9a, 0xe2, 0x64, 0xcb, 0xf7, 0x70, 0x1c, 0x31, 0x64, 0x51, 0xef, 0x89,
-       0xed, 0x01, 0x7d, 0xd3, 0xb1, 0x7b, 0xec, 0x39, 0x2b, 0x18, 0x30, 0xfe,
-       0x48, 0x9d, 0xfc, 0x28, 0x0a, 0xbb, 0xcd, 0x6f, 0x58, 0x98, 0xff, 0x72,
-       0x6f, 0x7b, 0x7e, 0x0a, 0xfb, 0x12, 0x2f, 0x26, 0xad, 0x34, 0xf6, 0xc7,
-       0x33, 0x20, 0x06, 0xd4, 0x02, 0x9d, 0xda, 0xf1, 0x7e, 0x88, 0x9f, 0x7a,
-       0xfd, 0xf7, 0x5f, 0x03, 0x1d, 0xc6, 0xfd, 0x1b, 0x5c, 0x98, 0x58, 0xcc,
-       0x85, 0x0c, 0x7a, 0x18, 0xd8, 0x4a, 0xb9, 0xf5, 0xb1, 0xb1, 0x3e, 0x9e,
-       0x8e, 0x18, 0xa5, 0x18, 0xfc, 0x40, 0xca, 0x04, 0x79, 0xb3, 0x0d, 0xfd,
-       0xab, 0x6e, 0xa5, 0xf4, 0xd5, 0xfd, 0xbe, 0x8f, 0xcb, 0xd8, 0xee, 0x89,
-       0xfc, 0x3e, 0x83, 0xcd, 0xb3, 0x96, 0x24, 0xd5, 0x91, 0xb4, 0x4f, 0x62,
-       0xbf, 0x43, 0xa1, 0x44, 0x21, 0x2b, 0x31, 0x99, 0x83, 0xbe, 0xb8, 0x0a,
-       0xd9, 0x7f, 0xab, 0xc8, 0xef, 0x6d, 0x53, 0x72, 0x28, 0x0f, 0x83, 0x3e,
-       0xa3, 0xdf, 0x7e, 0x41, 0xef, 0x0f, 0xc8, 0x6c, 0x3e, 0xd1, 0x35, 0x07,
-       0xfe, 0x9b, 0xcb, 0x13, 0x5f, 0xd4, 0x1d, 0x1f, 0xc1, 0x8a, 0x8b, 0xf9,
-       0x8d, 0xb0, 0x0f, 0x92, 0xba, 0x08, 0xff, 0xe7, 0x62, 0xb1, 0x0b, 0x7c,
-       0x86, 0xf1, 0xa2, 0x83, 0x5f, 0xe8, 0xcc, 0x62, 0x1f, 0xe4, 0x9c, 0x7b,
-       0xb1, 0x65, 0x7e, 0x33, 0xce, 0x8e, 0x38, 0x22, 0xc5, 0x8f, 0x7f, 0x86,
-       0xf3, 0xf5, 0xdf, 0x7b, 0xbb, 0xda, 0xe9, 0x39, 0xdd, 0x17, 0xec, 0x32,
-       0x62, 0x80, 0x4c, 0xaf, 0xb1, 0xdb, 0x43, 0x91, 0x16, 0x19, 0xba, 0x87,
-       0x76, 0xbc, 0x55, 0x63, 0x44, 0xe5, 0xc5, 0x08, 0xc7, 0x7f, 0xbb, 0xde,
-       0xd0, 0x2f, 0x5c, 0xd3, 0x7e, 0x1b, 0xbf, 0xcd, 0xd2, 0xe6, 0xf0, 0xd7,
-       0xc6, 0xef, 0xb5, 0xf5, 0xac, 0xef, 0xb6, 0x39, 0x49, 0x3c, 0xeb, 0xd7,
-       0x5e, 0xbe, 0x00, 0xd7, 0x73, 0xbc, 0x67, 0x9d, 0xf7, 0x5c, 0xae, 0xdb,
-       0x8c, 0x75, 0x9a, 0xbc, 0x67, 0x35, 0x6b, 0x7e, 0xd2, 0x3c, 0x0b, 0x31,
-       0x6e, 0xfe, 0x4f, 0xeb, 0x79, 0x86, 0xfc, 0xde, 0xb8, 0xba, 0xfd, 0xc7,
-       0xf5, 0xc4, 0xcd, 0xb5, 0x39, 0xcd, 0x8a, 0xf1, 0xbc, 0xd1, 0xda, 0x8a,
-       0x6b, 0x3e, 0x93, 0x73, 0x4c, 0x3e, 0x7c, 0xb6, 0xc8, 0xf5, 0xd9, 0x4e,
-       0xc9, 0x31, 0xcd, 0x67, 0x18, 0x2c, 0xdf, 0x6c, 0xfe, 0x3e, 0x99, 0x38,
-       0xa7, 0xf8, 0xba, 0xe9, 0x9c, 0xc5, 0xef, 0x5e, 0xf8, 0xbd, 0x1c, 0x7d,
-       0x89, 0x51, 0x19, 0xc7, 0xf9, 0x5d, 0x82, 0x4f, 0xb5, 0x68, 0xbe, 0x8b,
-       0xc5, 0xdf, 0x01, 0x9c, 0x4b, 0x08, 0x32, 0x46, 0x19, 0xa5, 0x4c, 0xe1,
-       0xfc, 0xc6, 0x6c, 0x79, 0xaf, 0x8f, 0xf2, 0xdc, 0x27, 0x97, 0xcb, 0xf2,
-       0x9c, 0x85, 0x3c, 0x53, 0x96, 0xb3, 0x90, 0x69, 0xc3, 0xd7, 0xfb, 0x11,
-       0x63, 0xa4, 0x62, 0xb0, 0x57, 0xea, 0x43, 0xbc, 0x0c, 0xbe, 0xb6, 0xbd,
-       0x6f, 0xa5, 0x02, 0x9a, 0xc3, 0xc9, 0xcc, 0xd4, 0x79, 0xdf, 0x01, 0xe0,
-       0xfa, 0xf2, 0x73, 0x32, 0x34, 0xd3, 0x88, 0x7d, 0x6f, 0xe8, 0xe0, 0x99,
-       0x65, 0x2e, 0xf3, 0xdf, 0xe7, 0x45, 0xe2, 0x4d, 0xe9, 0xcf, 0xf2, 0x9a,
-       0x71, 0xde, 0x7a, 0xcc, 0xe9, 0x07, 0x9d, 0x1b, 0xb1, 0x3e, 0xf7, 0xb8,
-       0xd2, 0x3c, 0x8e, 0x87, 0x2a, 0xf0, 0xa9, 0x3e, 0xbd, 0x57, 0xeb, 0x33,
-       0x33, 0xbd, 0x8d, 0xde, 0xfb, 0xf1, 0x1c, 0xc8, 0xf7, 0x31, 0xf0, 0x2d,
-       0x7d, 0x62, 0xf2, 0x4b, 0x4a, 0xcf, 0x61, 0x36, 0x4f, 0xfe, 0x0d, 0x69,
-       0x0e, 0x23, 0x03, 0xdb, 0xb2, 0x57, 0xe7, 0xc7, 0x96, 0xe5, 0xbb, 0x23,
-       0xa0, 0x71, 0x77, 0x26, 0xbf, 0x4a, 0x3a, 0x55, 0x07, 0x75, 0x78, 0xbc,
-       0x0d, 0x7b, 0xa1, 0x58, 0xee, 0x03, 0x72, 0xb4, 0xd8, 0x0f, 0x3a, 0xc4,
-       0xe4, 0x29, 0xf8, 0xcd, 0xcf, 0x14, 0xef, 0x90, 0xa5, 0x08, 0xf6, 0x55,
-       0x96, 0xb1, 0x41, 0xf9, 0xf1, 0xdc, 0x06, 0xef, 0x3a, 0xe1, 0x2e, 0x59,
-       0xdb, 0xb1, 0x07, 0xca, 0x13, 0xe5, 0x8a, 0xf3, 0x82, 0x88, 0x45, 0xb8,
-       0xee, 0x11, 0xa3, 0xdb, 0xb0, 0x6e, 0x21, 0x42, 0xf9, 0xe5, 0xde, 0x42,
-       0x9e, 0xcc, 0x32, 0xae, 0xe2, 0x3b, 0x1b, 0x9b, 0x94, 0xae, 0x3a, 0x8b,
-       0x84, 0xe2, 0x40, 0x97, 0xcf, 0xc0, 0x5f, 0xc7, 0x97, 0x4b, 0xff, 0x3b,
-       0x0a, 0xea, 0x51, 0xd8, 0xca, 0x3c, 0x6c, 0x65, 0x1e, 0x36, 0x12, 0xb2,
-       0xf0, 0x56, 0x1e, 0x36, 0x32, 0x0f, 0x1b, 0x09, 0x7d, 0xf6, 0x06, 0x62,
-       0xbb, 0xab, 0xe0, 0x21, 0xe3, 0x6b, 0x1f, 0xa6, 0xaf, 0x8d, 0xbf, 0xff,
-       0x01, 0x88, 0x97, 0xee, 0xe9, 0xc4, 0x71, 0x00, 0x00, 0x00 };
+       0xec, 0x5b, 0x5d, 0x70, 0x5c, 0xd7, 0x5d, 0xff, 0xdf, 0xb3, 0x2b, 0x69,
+       0x2d, 0x4b, 0xf2, 0x95, 0xbc, 0x71, 0x56, 0xa9, 0x92, 0xec, 0x5a, 0x57,
+       0xd2, 0xa6, 0x12, 0xe1, 0xca, 0x6c, 0x12, 0x75, 0xd8, 0x69, 0xb6, 0xbb,
+       0xb2, 0xa3, 0xb4, 0x66, 0x46, 0x49, 0x0d, 0xcd, 0xb4, 0x65, 0x10, 0xbb,
+       0x0e, 0xa4, 0x0f, 0x0c, 0xc6, 0x40, 0x26, 0x80, 0xc1, 0xcb, 0x4a, 0x71,
+       0x94, 0x74, 0xad, 0xdd, 0xda, 0x0a, 0x86, 0x69, 0x61, 0x94, 0xd5, 0x87,
+       0x53, 0x66, 0xad, 0x4d, 0xcb, 0x4b, 0x99, 0xd6, 0xb1, 0xea, 0xb8, 0x26,
+       0x0f, 0x3c, 0xa4, 0x94, 0xce, 0x64, 0x20, 0x33, 0x35, 0xb2, 0x63, 0xfb,
+       0x81, 0x8f, 0xc0, 0x4c, 0x49, 0x20, 0x6e, 0x2e, 0xbf, 0xdf, 0xb9, 0xf7,
+       0xca, 0x2b, 0x45, 0xd0, 0x3c, 0xf0, 0x78, 0xcf, 0x8c, 0xe6, 0xde, 0x7b,
+       0xce, 0xff, 0xfc, 0xcf, 0xff, 0xfb, 0xe3, 0xac, 0xfd, 0x3b, 0x1d, 0xd2,
+       0x2e, 0xde, 0xe8, 0xc4, 0x5f, 0xea, 0xc8, 0x33, 0x47, 0x47, 0xef, 0x1f,
+       0xbd, 0x9f, 0xdf, 0x21, 0xc3, 0x08, 0xf3, 0x69, 0x48, 0x30, 0x82, 0x11,
+       0x8c, 0x60, 0x04, 0x23, 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c,
+       0x60, 0x04, 0x23, 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c, 0x60,
+       0x04, 0x23, 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c, 0x60, 0x04,
+       0x23, 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c, 0x60, 0x04, 0x23,
+       0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c, 0x60, 0x04, 0x23, 0x18,
+       0xc1, 0x08, 0x46, 0x30, 0xfe, 0x3f, 0x47, 0x48, 0xc4, 0xe4, 0xb3, 0xd3,
+       0xfb, 0x93, 0x88, 0x4a, 0xc7, 0x8f, 0x66, 0x2d, 0x89, 0x84, 0xd2, 0x97,
+       0x9e, 0x2e, 0x58, 0x22, 0x99, 0xfa, 0x70, 0x3c, 0x27, 0x3f, 0x71, 0x8a,
+       0xd1, 0xb0, 0x70, 0xfe, 0xee, 0xf4, 0xad, 0xe3, 0xe7, 0x1f, 0x4a, 0xbc,
+       0xb3, 0x10, 0x92, 0x88, 0x99, 0x7e, 0x63, 0xd4, 0x1c, 0x94, 0x48, 0x1f,
+       0xf6, 0x7c, 0x6d, 0x68, 0x6d, 0x97, 0x74, 0xf9, 0xb8, 0x44, 0x6a, 0xe5,
+       0x84, 0x7d, 0x40, 0x86, 0xcd, 0x8b, 0x12, 0x96, 0x0c, 0xce, 0x58, 0xa9,
+       0x8b, 0x94, 0xca, 0x06, 0x71, 0x48, 0xa9, 0x1e, 0x91, 0x2b, 0x21, 0x42,
+       0x7d, 0xcb, 0xc8, 0x56, 0x3e, 0x70, 0x32, 0x61, 0x9c, 0x6b, 0xe1, 0xbd,
+       0xe1, 0xcf, 0x47, 0x44, 0xa5, 0x13, 0xc9, 0x6c, 0x68, 0x42, 0x6a, 0xf3,
+       0x8e, 0x33, 0x63, 0x7f, 0x0c, 0x38, 0x7a, 0x64, 0xc6, 0x72, 0xbf, 0xb3,
+       0xf6, 0xc7, 0xcd, 0x71, 0xb9, 0x13, 0x73, 0x21, 0x51, 0xd6, 0x5d, 0xf8,
+       0x8b, 0x1b, 0xb9, 0xd3, 0x5f, 0x36, 0xb2, 0x8b, 0x1d, 0x52, 0xaa, 0x38,
+       0x52, 0xb0, 0x25, 0x93, 0xb5, 0x77, 0x60, 0xfd, 0x03, 0xa7, 0xb0, 0xb1,
+       0x67, 0xd8, 0xcc, 0x49, 0x8b, 0x64, 0xa2, 0x31, 0xc0, 0xcc, 0x1b, 0xb9,
+       0xb3, 0x7f, 0xdd, 0x21, 0xed, 0xa0, 0x27, 0xc5, 0xef, 0x0f, 0x9c, 0x90,
+       0x65, 0x61, 0x9d, 0xe7, 0xe3, 0xbb, 0x41, 0xbc, 0x7c, 0x27, 0xce, 0x2b,
+       0xce, 0xf9, 0xa1, 0x98, 0x7c, 0xb3, 0x11, 0x95, 0x6f, 0x34, 0x4c, 0x79,
+       0xa5, 0xd1, 0x27, 0x17, 0x1a, 0x8e, 0xf3, 0x0d, 0xdb, 0x71, 0xde, 0xc0,
+       0xdf, 0x7f, 0xd8, 0x1b, 0x3c, 0x60, 0x14, 0x8d, 0xf1, 0xc6, 0x57, 0x3b,
+       0xa4, 0x2b, 0x11, 0x17, 0xd5, 0x21, 0xd3, 0x95, 0x98, 0xcc, 0x54, 0xca,
+       0xc6, 0x63, 0x67, 0xe7, 0x8c, 0xc9, 0xb3, 0x55, 0x9c, 0x19, 0xc6, 0x9c,
+       0x14, 0x4b, 0xf6, 0xcb, 0x46, 0xae, 0x31, 0x6b, 0x3c, 0x7e, 0xb6, 0x0b,
+       0x34, 0xf2, 0xfc, 0x3d, 0x46, 0xf6, 0xf4, 0x2d, 0xc9, 0xda, 0x94, 0x71,
+       0xc2, 0xfc, 0x3c, 0xc4, 0x9e, 0x2d, 0x93, 0xe6, 0x56, 0x8f, 0x5e, 0xc7,
+       0x51, 0x69, 0xe7, 0x78, 0x36, 0x65, 0x99, 0x25, 0x21, 0x7d, 0x7a, 0xee,
+       0x82, 0x4b, 0xf3, 0x8a, 0x91, 0x3d, 0xdb, 0x61, 0xe4, 0xce, 0x84, 0x41,
+       0x87, 0xf4, 0x85, 0x84, 0xfb, 0x06, 0x62, 0x79, 0xa9, 0xe3, 0x0c, 0x31,
+       0x55, 0x9a, 0x72, 0x05, 0xcd, 0xa0, 0xe5, 0x9b, 0x15, 0xf0, 0x50, 0x01,
+       0x0f, 0x15, 0xf2, 0x16, 0x97, 0xf3, 0x43, 0x3e, 0x6f, 0x8e, 0xf3, 0x77,
+       0x36, 0x69, 0x4f, 0xc4, 0x33, 0xca, 0xe7, 0xd3, 0x71, 0xfe, 0xdd, 0x26,
+       0xaf, 0xe4, 0xc7, 0x71, 0x5e, 0xb1, 0x63, 0xa0, 0xdd, 0xb9, 0xa0, 0xac,
+       0x32, 0x78, 0xb1, 0x80, 0x9f, 0xb2, 0x9e, 0x03, 0x0f, 0xb3, 0xe0, 0x6f,
+       0x05, 0xbc, 0x55, 0x41, 0xc7, 0x4f, 0x3b, 0xaf, 0x68, 0xe4, 0x86, 0x36,
+       0xe4, 0x15, 0xa7, 0x8c, 0xf3, 0x4b, 0x0a, 0xb2, 0xde, 0x29, 0xf9, 0x05,
+       0x53, 0xa6, 0x96, 0xfc, 0xfd, 0xbe, 0x1d, 0x1c, 0x91, 0x83, 0x95, 0x1e,
+       0xc8, 0x86, 0xb2, 0x4c, 0xd8, 0x22, 0x0e, 0x64, 0x54, 0x4a, 0x2a, 0x11,
+       0x23, 0x6f, 0x1f, 0xd7, 0xfa, 0x5f, 0xb2, 0x24, 0x93, 0xb7, 0x29, 0x47,
+       0x89, 0xe7, 0xed, 0x62, 0x2c, 0x0c, 0x7b, 0x5b, 0xb2, 0x8a, 0x66, 0x58,
+       0x28, 0xc7, 0x44, 0xec, 0xf7, 0x21, 0xcb, 0x27, 0xcb, 0x92, 0xf9, 0x74,
+       0xd9, 0x97, 0xb1, 0x2b, 0xdf, 0xcf, 0x94, 0x3f, 0xd5, 0x29, 0xed, 0xea,
+       0x9e, 0x16, 0xf9, 0x0d, 0xec, 0x25, 0xee, 0x4d, 0x7b, 0xb1, 0xcf, 0x85,
+       0x73, 0xf7, 0x26, 0x9e, 0x10, 0x21, 0x6c, 0xa9, 0xbf, 0x45, 0xfb, 0x88,
+       0x18, 0x59, 0xab, 0x18, 0x0b, 0x01, 0x2e, 0x2f, 0xa5, 0x51, 0x6f, 0xae,
+       0x25, 0x6b, 0xdd, 0x0a, 0xcd, 0xd8, 0x89, 0x78, 0x49, 0x6e, 0x85, 0x2e,
+       0xdb, 0x7a, 0x6e, 0x47, 0xd6, 0x72, 0x64, 0x19, 0xd8, 0x9f, 0x83, 0x3f,
+       0x5c, 0x04, 0x47, 0x5f, 0x2a, 0xeb, 0xf9, 0x4e, 0xec, 0x4f, 0xb6, 0x00,
+       0x67, 0xbb, 0x24, 0x92, 0x35, 0xcc, 0x5f, 0x76, 0xe7, 0xbb, 0x5d, 0xbc,
+       0xa5, 0xfe, 0x76, 0x8d, 0x5b, 0xe4, 0x65, 0x77, 0xfe, 0x0e, 0x17, 0x77,
+       0xe9, 0x3e, 0xcc, 0x03, 0xff, 0xe0, 0xc4, 0x90, 0xa1, 0xe7, 0x7b, 0xe9,
+       0x4f, 0xbf, 0x5e, 0xbe, 0x15, 0x5a, 0xb6, 0x1d, 0xc9, 0x8d, 0x0e, 0x4e,
+       0x0c, 0x1a, 0x2e, 0xbe, 0x13, 0xee, 0xbe, 0xbb, 0x5d, 0x7c, 0x83, 0x13,
+       0x49, 0xc3, 0xc5, 0xb7, 0x54, 0xd6, 0x7b, 0x25, 0x5f, 0x26, 0xec, 0xe0,
+       0x84, 0x65, 0xdc, 0x2d, 0x53, 0xdd, 0x83, 0x13, 0x7b, 0x0d, 0x75, 0xcf,
+       0x4e, 0x97, 0x8f, 0x84, 0x4f, 0xc3, 0x4e, 0x4d, 0x03, 0xcf, 0xd5, 0xf3,
+       0x03, 0x59, 0xab, 0x74, 0xdf, 0x4e, 0x7d, 0x3e, 0xcf, 0xd4, 0x73, 0xf7,
+       0x91, 0x2e, 0x9e, 0x5d, 0x18, 0xdd, 0x74, 0xee, 0xcf, 0xdc, 0x96, 0xcf,
+       0x76, 0x67, 0xf2, 0x3c, 0x89, 0x84, 0xd3, 0xe1, 0xd1, 0x99, 0xf2, 0x11,
+       0xc9, 0x56, 0xe2, 0x32, 0x3d, 0xb2, 0x43, 0xa6, 0xcc, 0xfe, 0xa9, 0x83,
+       0xc2, 0xd8, 0x13, 0x19, 0x2d, 0x78, 0x3a, 0xcc, 0x89, 0x21, 0xd3, 0xe0,
+       0xf1, 0x60, 0x5d, 0x22, 0x06, 0xe0, 0xfb, 0xeb, 0x61, 0x79, 0xbe, 0x61,
+       0x48, 0xab, 0xf6, 0xcf, 0x84, 0xb9, 0x06, 0x3b, 0x7c, 0xb6, 0x42, 0x3b,
+       0xa6, 0xcd, 0x4a, 0xa6, 0x06, 0x3b, 0xbd, 0xa0, 0x7d, 0xb5, 0x9d, 0x7a,
+       0x2d, 0x16, 0x05, 0xae, 0x98, 0xb6, 0xcc, 0x9a, 0xb4, 0x49, 0x66, 0x52,
+       0x8a, 0x5c, 0xf7, 0x7c, 0x27, 0xb6, 0x28, 0xdf, 0x85, 0x0d, 0x88, 0x99,
+       0x4d, 0x71, 0x9e, 0xf0, 0x4d, 0xb0, 0xa6, 0xeb, 0x77, 0x21, 0xf8, 0x5d,
+       0x21, 0x45, 0x58, 0x29, 0xea, 0x58, 0xd1, 0x80, 0x2d, 0x36, 0xee, 0xee,
+       0x74, 0x63, 0x5d, 0x04, 0xfe, 0xd9, 0x01, 0x1f, 0xbf, 0x07, 0xfe, 0xd7,
+       0x67, 0x64, 0xcf, 0x38, 0x0e, 0x62, 0x4f, 0x54, 0x09, 0xfd, 0x0f, 0xbe,
+       0xde, 0xe0, 0x5a, 0x07, 0xe6, 0xc5, 0x9c, 0xb6, 0xbb, 0xc1, 0x9f, 0xe3,
+       0x4c, 0xd8, 0x71, 0x29, 0xd9, 0xbb, 0xb0, 0xaf, 0x45, 0xba, 0x2d, 0xda,
+       0x3b, 0x7d, 0x7a, 0x27, 0xce, 0x33, 0xf8, 0xdd, 0x85, 0xf3, 0x3a, 0x31,
+       0x17, 0x9b, 0xa6, 0x1f, 0xa7, 0x18, 0xb3, 0xdc, 0xf8, 0x29, 0x72, 0x15,
+       0xb4, 0x72, 0x8f, 0x86, 0x8b, 0xb4, 0xa5, 0x53, 0x72, 0xa3, 0xdc, 0x2b,
+       0x57, 0xa2, 0xe4, 0x1f, 0x38, 0x2b, 0x88, 0x87, 0x51, 0x03, 0xf4, 0x93,
+       0x6e, 0xc6, 0xbf, 0xdd, 0xde, 0xb7, 0x71, 0xaf, 0x7b, 0x86, 0x98, 0xa1,
+       0x74, 0x97, 0xe4, 0xf4, 0x9c, 0x28, 0x35, 0xba, 0xd3, 0x5b, 0xef, 0x32,
+       0x0e, 0x9c, 0x51, 0x32, 0xf4, 0x20, 0x62, 0x16, 0xce, 0xba, 0x6c, 0x39,
+       0xce, 0x65, 0xfb, 0xc7, 0xf0, 0x79, 0x25, 0x2d, 0xd6, 0x7a, 0x97, 0xb4,
+       0x43, 0x9e, 0x15, 0xa3, 0x49, 0x86, 0x31, 0x39, 0x51, 0xe1, 0x9e, 0xa2,
+       0x84, 0x2d, 0xc2, 0x10, 0xfe, 0x47, 0x80, 0x0b, 0x49, 0x1b, 0x7c, 0xf1,
+       0xa2, 0x1d, 0x25, 0xbd, 0xbb, 0x5c, 0xf8, 0x6e, 0x9c, 0x41, 0xda, 0xe9,
+       0x7b, 0x8e, 0xf6, 0xbd, 0x6c, 0x48, 0x65, 0xc6, 0xe7, 0xe1, 0x49, 0x23,
+       0x94, 0x77, 0xb6, 0x1b, 0xa1, 0x5f, 0xa6, 0x87, 0x8a, 0xa6, 0xd2, 0xba,
+       0x16, 0xc9, 0x95, 0xef, 0x95, 0x19, 0x1b, 0xe7, 0x59, 0x61, 0xd0, 0xcc,
+       0x38, 0x33, 0x50, 0x0c, 0x29, 0x78, 0x58, 0x0f, 0x65, 0xe5, 0xd3, 0xfa,
+       0x16, 0xce, 0x2b, 0x1a, 0x61, 0x8b, 0x67, 0xfc, 0xb2, 0x27, 0x1f, 0xda,
+       0x9d, 0x2d, 0xd9, 0x72, 0x07, 0xbf, 0x41, 0x47, 0xbb, 0xa6, 0x23, 0x94,
+       0xd6, 0xba, 0x33, 0x54, 0xda, 0x8f, 0xff, 0x04, 0xdd, 0x84, 0x07, 0x7c,
+       0x70, 0xaf, 0x85, 0xbd, 0x11, 0xd0, 0xd8, 0xd9, 0x44, 0x7f, 0x3b, 0xe1,
+       0x21, 0xab, 0x88, 0x77, 0x86, 0xe6, 0xdb, 0x70, 0xf9, 0xf6, 0x65, 0xf5,
+       0x2a, 0x64, 0xf5, 0xbe, 0x33, 0xb4, 0x8f, 0x38, 0x52, 0xc0, 0x01, 0xb9,
+       0x9b, 0x8c, 0x57, 0x8c, 0x51, 0xe6, 0x06, 0x2e, 0xf8, 0x81, 0x0a, 0xa5,
+       0x3b, 0x24, 0x67, 0xea, 0x1c, 0x00, 0xd8, 0x31, 0xd1, 0x31, 0xde, 0x22,
+       0x8f, 0xde, 0xb7, 0x95, 0xd0, 0x76, 0x93, 0xaf, 0x32, 0x0f, 0xfc, 0x31,
+       0x68, 0x5b, 0x4b, 0x28, 0xcd, 0x5a, 0x07, 0x64, 0x2e, 0x91, 0x96, 0xf4,
+       0x1b, 0xb2, 0x5c, 0x56, 0x7b, 0x5a, 0x65, 0x97, 0x4c, 0x42, 0x46, 0xb5,
+       0x31, 0xe4, 0xaf, 0x91, 0x0e, 0x09, 0xdd, 0xcf, 0x3c, 0x10, 0x03, 0xad,
+       0x6b, 0x09, 0x53, 0x6e, 0x39, 0x6a, 0x10, 0xfb, 0x47, 0xa0, 0x87, 0x43,
+       0xd4, 0xa9, 0xf2, 0xe0, 0x08, 0x13, 0xa2, 0xcc, 0x7b, 0x5a, 0x85, 0xb8,
+       0xb9, 0x36, 0x1c, 0x33, 0x85, 0xf3, 0xc8, 0x95, 0x93, 0xdc, 0x4b, 0xfe,
+       0xdc, 0x3d, 0x1f, 0xe6, 0xcf, 0x5f, 0xa7, 0xcc, 0x28, 0x3b, 0xd8, 0x18,
+       0x78, 0xcc, 0xda, 0xbf, 0xe0, 0xc9, 0xe6, 0x4e, 0xb9, 0x62, 0x8a, 0x51,
+       0xb3, 0xef, 0x68, 0x92, 0x1f, 0x79, 0xee, 0xde, 0xc2, 0x33, 0x71, 0x6c,
+       0xcf, 0xf7, 0xe1, 0x2a, 0xcf, 0x74, 0xcf, 0x9e, 0xb1, 0xd6, 0x12, 0x61,
+       0xd9, 0x2c, 0x5f, 0xe8, 0x52, 0x0a, 0x65, 0xda, 0x46, 0xab, 0xe4, 0x51,
+       0x8f, 0xd8, 0xfb, 0x10, 0x54, 0x1e, 0x57, 0x32, 0xfa, 0x20, 0x71, 0xfe,
+       0x23, 0x79, 0x1a, 0x8b, 0x2b, 0x43, 0xf2, 0x3a, 0xf7, 0xfb, 0xfa, 0xe2,
+       0x5c, 0xb3, 0x6d, 0xbf, 0xea, 0xd9, 0xf6, 0xfb, 0xce, 0xe8, 0x3e, 0x5f,
+       0xef, 0x90, 0xd7, 0x87, 0xf6, 0x08, 0xf4, 0xfc, 0x7f, 0xed, 0xa1, 0xad,
+       0x44, 0xb6, 0xec, 0x29, 0x6e, 0xb3, 0x67, 0xb7, 0xc8, 0x2f, 0xd1, 0x87,
+       0xba, 0xbd, 0x98, 0xe1, 0xfb, 0x94, 0x8f, 0x07, 0xba, 0xd1, 0xb6, 0xca,
+       0xb9, 0xed, 0x7c, 0x91, 0x38, 0x88, 0x8b, 0x7b, 0x09, 0xe3, 0xe7, 0x54,
+       0xa8, 0x43, 0xb6, 0xcd, 0xab, 0x18, 0x13, 0x78, 0x57, 0x88, 0x43, 0xcd,
+       0xf9, 0x95, 0x73, 0x26, 0xbe, 0xc7, 0xf1, 0xb4, 0x24, 0x5f, 0xa7, 0x3f,
+       0x71, 0x3f, 0xf3, 0xed, 0x4d, 0x2f, 0x7e, 0x76, 0x4c, 0x85, 0xd3, 0x51,
+       0xc4, 0x4f, 0x99, 0x2c, 0x95, 0x8f, 0xa3, 0x26, 0x92, 0xe2, 0x5d, 0x69,
+       0xda, 0x47, 0xc7, 0x18, 0x62, 0xe4, 0x64, 0xa9, 0xce, 0xba, 0x08, 0x61,
+       0x0c, 0xfb, 0x90, 0xa3, 0x23, 0x6a, 0x2e, 0x52, 0xfc, 0x58, 0x9a, 0x71,
+       0x39, 0x2e, 0xf1, 0xfa, 0x3b, 0xa8, 0x3b, 0x4c, 0xc9, 0x6a, 0x5b, 0xfb,
+       0xb3, 0x5e, 0xd2, 0x5b, 0x42, 0x0d, 0x11, 0x4e, 0x4b, 0x58, 0xa5, 0x5b,
+       0x23, 0xd3, 0xa9, 0x0e, 0xd4, 0x5a, 0x13, 0xbd, 0x6a, 0xf5, 0x60, 0x6f,
+       0x68, 0x75, 0xcf, 0x54, 0x4b, 0xba, 0xd8, 0xab, 0xe6, 0x44, 0x16, 0xcb,
+       0xa2, 0x50, 0xd7, 0xc4, 0x0e, 0x0b, 0xbe, 0x57, 0x3f, 0xfb, 0x59, 0x95,
+       0x0e, 0x41, 0xb7, 0x72, 0x6c, 0x29, 0x15, 0x66, 0x0d, 0x19, 0x9f, 0x94,
+       0x63, 0xa8, 0x1b, 0x9f, 0x91, 0xe9, 0x32, 0xe8, 0xd2, 0x7c, 0xc7, 0xc0,
+       0x6f, 0x1f, 0x70, 0x93, 0xf6, 0x28, 0x62, 0xac, 0x4b, 0x3b, 0x68, 0xce,
+       0xe4, 0x58, 0x27, 0xa5, 0x98, 0x57, 0xde, 0x81, 0xfd, 0xd0, 0x5f, 0xfe,
+       0x59, 0x96, 0xad, 0x1d, 0x92, 0x77, 0xe3, 0x03, 0xed, 0x15, 0x6b, 0x37,
+       0xbd, 0xb5, 0x6b, 0x58, 0xa3, 0xfd, 0xee, 0x6c, 0xd2, 0xe1, 0x97, 0x75,
+       0xad, 0x73, 0xd9, 0xe6, 0x3b, 0x61, 0xff, 0x76, 0xd4, 0x85, 0x7d, 0x7d,
+       0x74, 0xd9, 0xfa, 0xdc, 0x2e, 0x69, 0x37, 0xa9, 0x37, 0x9c, 0x13, 0x65,
+       0x8c, 0xc5, 0xfa, 0x15, 0x0f, 0xd7, 0x5b, 0xc0, 0xd5, 0x41, 0xba, 0x31,
+       0xc2, 0x58, 0x07, 0x7d, 0xa8, 0x79, 0xf2, 0x1b, 0xb1, 0x86, 0xb0, 0xdf,
+       0xf1, 0x70, 0x7d, 0xab, 0x09, 0x17, 0xd7, 0xf8, 0xe4, 0x99, 0x38, 0xbb,
+       0x9d, 0xbc, 0x91, 0x1f, 0xea, 0x80, 0xfa, 0x48, 0x1a, 0x93, 0x88, 0xed,
+       0x93, 0x0d, 0x5d, 0xdb, 0x19, 0xb9, 0x0a, 0x6a, 0xae, 0xc6, 0x8b, 0xa0,
+       0x11, 0xb5, 0x58, 0x63, 0xd0, 0xab, 0xb7, 0x69, 0x47, 0x6b, 0xda, 0x1e,
+       0x19, 0x77, 0x4a, 0xda, 0xae, 0x2e, 0xb9, 0x76, 0x65, 0x51, 0x37, 0x97,
+       0x64, 0x6f, 0xbd, 0xba, 0xcb, 0xfd, 0xbf, 0xdb, 0xa6, 0x84, 0xb4, 0x3e,
+       0x99, 0xdf, 0x68, 0x63, 0x77, 0x22, 0xae, 0x3b, 0xef, 0x32, 0xcf, 0x4c,
+       0x32, 0x07, 0x4d, 0x32, 0x77, 0x18, 0x5e, 0x3c, 0x8c, 0x37, 0xe1, 0x88,
+       0x03, 0xc7, 0x8a, 0x67, 0xbf, 0x73, 0x1e, 0x2e, 0xbf, 0xfe, 0xf4, 0x63,
+       0xea, 0x9f, 0xdf, 0xb5, 0x79, 0x5d, 0x99, 0xee, 0x77, 0xab, 0x8e, 0xc7,
+       0xb0, 0x75, 0xd0, 0x1f, 0x9f, 0x52, 0xb0, 0xaf, 0x5c, 0xdd, 0xd5, 0x07,
+       0x7c, 0x1f, 0xb6, 0xc7, 0x57, 0x5f, 0xb7, 0x6e, 0xfd, 0xed, 0xca, 0x80,
+       0x3a, 0xcd, 0x90, 0xef, 0x4c, 0x98, 0xb4, 0x34, 0x26, 0xb0, 0x5f, 0x8e,
+       0x30, 0x37, 0xe6, 0xc1, 0xc7, 0x61, 0x73, 0xd8, 0x9c, 0x26, 0xee, 0xa8,
+       0x00, 0x27, 0x6a, 0xc9, 0x74, 0x9b, 0xa7, 0xe7, 0x6f, 0xf3, 0x7c, 0xe0,
+       0xde, 0xc9, 0x6f, 0x3c, 0xbf, 0xed, 0xd1, 0x73, 0xa3, 0xcb, 0xa5, 0xc7,
+       0x5f, 0x1f, 0x34, 0x37, 0x7f, 0xaf, 0xf4, 0x7a, 0xf2, 0xc4, 0xfb, 0x33,
+       0x1e, 0x5d, 0xd4, 0x4d, 0x33, 0x4d, 0xd4, 0xcb, 0xbb, 0xc0, 0xa3, 0x6b,
+       0x8d, 0xa2, 0x4a, 0xa3, 0x76, 0x49, 0x31, 0x67, 0x25, 0xc6, 0x32, 0x62,
+       0x41, 0x27, 0x09, 0x7b, 0x0a, 0xbb, 0x6e, 0x96, 0xa9, 0xe7, 0x5b, 0x88,
+       0xd5, 0xd4, 0xfb, 0x7b, 0x32, 0x53, 0xee, 0xb7, 0x5b, 0x0d, 0xfa, 0x6b,
+       0x22, 0xb9, 0x22, 0xc3, 0xf6, 0x8a, 0xae, 0xa1, 0x12, 0xf1, 0x13, 0x42,
+       0xd9, 0xde, 0x92, 0x01, 0x5d, 0xdb, 0xbc, 0x27, 0x16, 0xe4, 0x32, 0x59,
+       0x81, 0x8f, 0xed, 0xfb, 0x57, 0x47, 0xd7, 0xa4, 0x08, 0x6f, 0xd7, 0xb7,
+       0xc1, 0xf5, 0xba, 0xc6, 0x43, 0x7c, 0xcd, 0xb8, 0x0c, 0x69, 0xdb, 0xe7,
+       0xe3, 0xb3, 0x64, 0xb6, 0xe1, 0xe3, 0x0c, 0x23, 0x2e, 0x23, 0x06, 0xec,
+       0xfb, 0xbc, 0x67, 0x2f, 0x7c, 0xff, 0xbe, 0xc3, 0x5a, 0x48, 0xa5, 0xbf,
+       0xea, 0xcd, 0x7d, 0x8f, 0x32, 0xc0, 0xb7, 0x2f, 0xf7, 0x17, 0xbd, 0x78,
+       0x53, 0x34, 0x32, 0x0d, 0xca, 0x80, 0xb6, 0x02, 0xfd, 0x6b, 0xfb, 0x84,
+       0xcf, 0x54, 0x3e, 0x89, 0x98, 0xd5, 0xed, 0xd6, 0x0f, 0xe8, 0xaf, 0x32,
+       0x0d, 0xce, 0xad, 0xb5, 0x65, 0xed, 0x16, 0xcf, 0x97, 0x0e, 0x62, 0x6e,
+       0x12, 0x7f, 0x94, 0x1d, 0x61, 0x0e, 0xe1, 0x3d, 0xe3, 0xc1, 0xc9, 0x58,
+       0x16, 0xb9, 0x2b, 0x73, 0x68, 0x1c, 0xdf, 0x86, 0xd7, 0x67, 0x69, 0xb9,
+       0x57, 0x51, 0xab, 0x40, 0x9e, 0x03, 0xe0, 0x27, 0x2e, 0xe3, 0x0d, 0xe8,
+       0x7c, 0x23, 0x9e, 0x6d, 0xc0, 0x14, 0x6f, 0xc3, 0xb8, 0xb1, 0x6f, 0xbc,
+       0xf1, 0xa6, 0xc3, 0x78, 0xf0, 0x57, 0xda, 0x5f, 0xe2, 0xa0, 0xdd, 0xef,
+       0xd5, 0x32, 0xc6, 0x63, 0x95, 0x09, 0xe3, 0xf1, 0x0a, 0xf7, 0xa8, 0xaf,
+       0xf5, 0x88, 0x15, 0xcf, 0x2a, 0xd4, 0xa9, 0xfb, 0xba, 0x70, 0xe6, 0x09,
+       0xd8, 0x46, 0xd1, 0x98, 0x1c, 0xda, 0x25, 0xf9, 0x64, 0x0f, 0x68, 0x7e,
+       0x08, 0xcf, 0x56, 0xcc, 0xff, 0x3c, 0xe6, 0x61, 0x47, 0x49, 0xfa, 0xc7,
+       0x0e, 0xdd, 0x5b, 0x4e, 0x99, 0xa4, 0x71, 0xc0, 0xb3, 0xad, 0x37, 0x4d,
+       0xd7, 0x96, 0x9e, 0xc6, 0xf7, 0x4e, 0xcc, 0x7f, 0x01, 0x4f, 0xe4, 0xb2,
+       0x7d, 0xfe, 0x3c, 0x7d, 0x70, 0x0c, 0xf3, 0x0f, 0x00, 0xc7, 0x1f, 0xe0,
+       0xfd, 0x5e, 0xbc, 0xff, 0xde, 0x96, 0xbd, 0xbf, 0xcb, 0xb3, 0x31, 0x9f,
+       0xdd, 0x32, 0xef, 0xc7, 0x6f, 0x9e, 0x27, 0xd2, 0xbd, 0x0a, 0xc6, 0x57,
+       0x23, 0xb2, 0x7b, 0xa5, 0x5d, 0x54, 0xcd, 0x8d, 0xe1, 0xaa, 0x66, 0x4a,
+       0xcf, 0x0a, 0xe3, 0xf7, 0x0f, 0xb0, 0xc7, 0x12, 0xb5, 0x0a, 0xa5, 0x51,
+       0xb7, 0xda, 0x47, 0x9f, 0x39, 0xba, 0x77, 0x81, 0xcf, 0xe2, 0xd1, 0xd1,
+       0x3a, 0x61, 0xf8, 0x7e, 0xec, 0xe8, 0xde, 0xfa, 0x3f, 0x00, 0x16, 0x72,
+       0xa9, 0xf8, 0xf8, 0x09, 0x7f, 0x7e, 0xcb, 0x99, 0x5a, 0xb6, 0x38, 0x93,
+       0x7e, 0xff, 0xcc, 0xd1, 0x6c, 0x95, 0x75, 0x42, 0x22, 0x26, 0xba, 0x16,
+       0x2f, 0x1e, 0x2d, 0x20, 0x3f, 0x86, 0x34, 0x2d, 0xfe, 0x3a, 0xd7, 0xa8,
+       0x87, 0xed, 0x68, 0x23, 0x5d, 0xcd, 0x78, 0x98, 0x67, 0x88, 0xe7, 0x18,
+       0xf0, 0x24, 0x81, 0x87, 0xf9, 0xc6, 0xa5, 0x37, 0xbe, 0xb0, 0x1d, 0x6d,
+       0xc4, 0xc5, 0xb3, 0x7c, 0x7c, 0x3d, 0xa2, 0x56, 0x7e, 0x48, 0x7a, 0x4d,
+       0xd6, 0xb6, 0x6e, 0xac, 0x69, 0x91, 0xfc, 0x69, 0xe6, 0xec, 0x7d, 0xde,
+       0x37, 0xca, 0x18, 0xf4, 0xdc, 0x71, 0xc5, 0x79, 0x3e, 0xb1, 0x96, 0x62,
+       0xb9, 0x82, 0xef, 0x45, 0x1f, 0x56, 0x79, 0xb0, 0x9d, 0x4d, 0x7c, 0xb7,
+       0x78, 0xb2, 0xe6, 0x99, 0x7e, 0xef, 0xd9, 0x4c, 0x0b, 0x40, 0xa1, 0x87,
+       0xee, 0x0d, 0x3d, 0xf8, 0x7c, 0x62, 0x61, 0x95, 0xb4, 0x25, 0xc1, 0xab,
+       0x4f, 0xdb, 0x47, 0xd5, 0x1f, 0xf7, 0x26, 0xf1, 0xe7, 0x9f, 0xe7, 0xcb,
+       0x80, 0x74, 0xf1, 0x09, 0x5b, 0xfe, 0x50, 0xef, 0x9c, 0x84, 0xdf, 0xf1,
+       0x1e, 0xc4, 0x71, 0x96, 0x6d, 0xca, 0xbe, 0x0d, 0x7a, 0x27, 0x2f, 0x06,
+       0x7a, 0x09, 0xc5, 0x9a, 0x2e, 0xce, 0x9e, 0xf5, 0x49, 0xb9, 0x0a, 0x5c,
+       0x19, 0xf4, 0x95, 0x6e, 0x6f, 0x34, 0x85, 0xf8, 0xb8, 0x06, 0xfb, 0xbc,
+       0x6c, 0xf1, 0x3e, 0x26, 0xcc, 0x7c, 0x27, 0xa5, 0xfa, 0xbf, 0x00, 0x86,
+       0xf5, 0xd5, 0xed, 0xbb, 0x96, 0x05, 0xc0, 0x2c, 0x62, 0xed, 0x84, 0x1b,
+       0x97, 0x19, 0xdb, 0x1d, 0x85, 0xda, 0xa3, 0x60, 0xfd, 0xb7, 0xc3, 0x3a,
+       0xeb, 0x36, 0xec, 0x76, 0x77, 0x21, 0xc8, 0x39, 0xf3, 0x89, 0xd9, 0x05,
+       0xc4, 0xf0, 0xaa, 0xa5, 0x76, 0x2b, 0x6d, 0x91, 0x89, 0x2a, 0x62, 0x12,
+       0xba, 0xde, 0x44, 0x7c, 0x41, 0xfe, 0x53, 0xeb, 0xa1, 0xc5, 0x1a, 0x36,
+       0x7b, 0xd4, 0xe7, 0x68, 0x57, 0x9a, 0xf2, 0xd0, 0x29, 0xe4, 0xe5, 0x91,
+       0xc7, 0x90, 0x73, 0x20, 0xaf, 0x53, 0x45, 0x74, 0xf2, 0xb4, 0x91, 0x37,
+       0x7e, 0xab, 0x60, 0xb9, 0x7d, 0x80, 0xce, 0x67, 0xe2, 0xf2, 0x18, 0x3a,
+       0xd5, 0xa1, 0xe3, 0x4c, 0x5e, 0xc7, 0x9b, 0x7e, 0x73, 0x52, 0xb5, 0xa3,
+       0xc6, 0x40, 0x01, 0x8a, 0x0a, 0xc7, 0x1c, 0x14, 0xd9, 0x3b, 0x87, 0xb8,
+       0x82, 0x38, 0xbc, 0x77, 0x15, 0xd1, 0xed, 0x14, 0xe1, 0x95, 0x84, 0x4f,
+       0x85, 0xa4, 0xe5, 0x14, 0xef, 0x43, 0x64, 0x0f, 0xfa, 0x31, 0xe2, 0xdc,
+       0x1b, 0xc6, 0x73, 0x1c, 0x7f, 0xfb, 0x51, 0x5b, 0x99, 0xa8, 0x91, 0xb7,
+       0x81, 0x07, 0x2c, 0xf7, 0x6c, 0x07, 0x6f, 0x76, 0x4b, 0x7b, 0x04, 0x7b,
+       0x08, 0x1f, 0x06, 0x1d, 0x7b, 0x40, 0x8f, 0x7b, 0x3e, 0x71, 0x84, 0x4f,
+       0x89, 0xf4, 0xcf, 0x49, 0x8f, 0xd2, 0x7b, 0xc2, 0x52, 0x48, 0x71, 0xad,
+       0x03, 0xf0, 0xdc, 0x87, 0x35, 0xbd, 0xcf, 0xbd, 0x57, 0xca, 0xdf, 0xa6,
+       0x1b, 0x73, 0x06, 0xde, 0x51, 0x4f, 0xa5, 0x4c, 0xe9, 0xaf, 0xb9, 0xb0,
+       0x7b, 0x57, 0xbf, 0xd4, 0xcd, 0xbb, 0x29, 0x65, 0xb9, 0xb4, 0x29, 0xd4,
+       0xc4, 0x79, 0x48, 0x35, 0x3c, 0xc8, 0xfb, 0x19, 0xc2, 0xb0, 0xaf, 0x35,
+       0x35, 0x8c, 0x39, 0x48, 0xf9, 0xb9, 0x73, 0x4a, 0xfd, 0x6f, 0xf7, 0x2e,
+       0xcd, 0x35, 0x85, 0xf6, 0x15, 0xec, 0xff, 0x43, 0xed, 0x2b, 0xa2, 0xe2,
+       0x9e, 0xaf, 0xe0, 0x7b, 0x91, 0xdf, 0x7e, 0x2e, 0xfe, 0xed, 0xbb, 0xdc,
+       0x78, 0xef, 0xc8, 0xb4, 0xcd, 0x3b, 0x0c, 0x47, 0x2e, 0xdb, 0x45, 0xe3,
+       0x91, 0x4d, 0x75, 0x66, 0x52, 0xe7, 0xe7, 0x02, 0x64, 0xbf, 0x5e, 0xd7,
+       0x3d, 0x9b, 0x5c, 0xa9, 0x47, 0xe4, 0xea, 0x52, 0xbb, 0xac, 0x2f, 0xb8,
+       0x36, 0xbf, 0xbe, 0x40, 0x3b, 0x37, 0xe5, 0xed, 0x25, 0x0b, 0x6b, 0x49,
+       0xfc, 0xf5, 0xc8, 0xf5, 0xa5, 0xcd, 0x75, 0xe7, 0x85, 0xc6, 0xc3, 0xa0,
+       0xa5, 0x47, 0x42, 0x96, 0xa3, 0xfb, 0xaf, 0x1c, 0x72, 0x5f, 0x51, 0xc6,
+       0x25, 0x5f, 0xe9, 0x47, 0x0f, 0x88, 0xe4, 0x1c, 0x66, 0x0e, 0x82, 0xfe,
+       0x2b, 0x9f, 0x40, 0x6d, 0x92, 0x80, 0xf3, 0xf4, 0xeb, 0x7b, 0xc5, 0x4f,
+       0x85, 0x7b, 0xa4, 0xd5, 0xfa, 0xa3, 0x6e, 0x37, 0x57, 0x99, 0x6e, 0x9f,
+       0x6a, 0xf9, 0xf9, 0xfa, 0x75, 0xe0, 0x1e, 0x81, 0x9d, 0xd2, 0x36, 0x6d,
+       0xd8, 0xac, 0x29, 0xcb, 0x43, 0x89, 0x6a, 0x51, 0x18, 0x1f, 0x52, 0x38,
+       0xd3, 0xc0, 0xbe, 0x24, 0xe4, 0xb1, 0x43, 0xd7, 0x42, 0x19, 0x05, 0xdd,
+       0xce, 0xcd, 0x48, 0xbe, 0xf1, 0x9b, 0x98, 0xcf, 0xc8, 0x54, 0x63, 0x0c,
+       0x67, 0x9d, 0xa4, 0xdd, 0xf6, 0x48, 0x3b, 0xcf, 0x49, 0x81, 0xc6, 0x87,
+       0xa4, 0x70, 0x7a, 0x46, 0x0e, 0x57, 0x48, 0x27, 0xef, 0x19, 0x13, 0xc9,
+       0x9c, 0x0c, 0xc7, 0x97, 0x50, 0x3b, 0xb9, 0xfe, 0x98, 0x96, 0xc2, 0x19,
+       0xe0, 0xa8, 0xf0, 0x1e, 0xa0, 0x1f, 0x76, 0x33, 0xac, 0xfb, 0x9a, 0x29,
+       0x1d, 0x77, 0x38, 0xff, 0x43, 0xe8, 0xa9, 0xbf, 0xb8, 0x1f, 0x70, 0x79,
+       0xf4, 0x40, 0x93, 0xa8, 0x97, 0x17, 0x2b, 0xe8, 0xf7, 0xec, 0x10, 0x6b,
+       0x2f, 0xa5, 0xee, 0xef, 0x93, 0x5a, 0x65, 0xd8, 0x54, 0x8a, 0x35, 0x15,
+       0x75, 0xc1, 0x35, 0xfa, 0x77, 0x4c, 0x85, 0xad, 0x3e, 0x59, 0xaa, 0x14,
+       0xd1, 0x37, 0x2b, 0xef, 0x5e, 0x03, 0x16, 0x60, 0xb9, 0x71, 0x2f, 0xa3,
+       0xc8, 0x37, 0xea, 0xcf, 0xc6, 0x27, 0x41, 0x63, 0x26, 0x6e, 0xca, 0x71,
+       0xd0, 0x87, 0xf7, 0x45, 0xd8, 0xf8, 0x1c, 0x6b, 0xb8, 0x0c, 0xd6, 0xd2,
+       0x72, 0xe4, 0xec, 0x24, 0x68, 0xe8, 0x92, 0xfe, 0x3f, 0xa1, 0x8f, 0x3d,
+       0x81, 0x39, 0x7e, 0x27, 0x60, 0xaf, 0x5f, 0xc4, 0x3b, 0x61, 0x63, 0x78,
+       0x52, 0x0e, 0x7d, 0x78, 0x9a, 0xa0, 0x25, 0xe2, 0xf6, 0x26, 0x87, 0xe2,
+       0x52, 0x3b, 0xfd, 0xa0, 0x4c, 0x2d, 0x3e, 0x08, 0xfc, 0x3f, 0x42, 0x5f,
+       0x80, 0xfc, 0xb6, 0xc8, 0xb3, 0x58, 0xff, 0xf1, 0x9c, 0x9d, 0x3d, 0xda,
+       0x37, 0xe6, 0x38, 0xcf, 0xe7, 0x41, 0xec, 0x47, 0x8f, 0x51, 0xc9, 0x48,
+       0xa1, 0xc2, 0xb3, 0xa0, 0x3b, 0xd4, 0x53, 0xf9, 0xd3, 0x93, 0x9e, 0x8e,
+       0x7b, 0x24, 0x17, 0x2d, 0xb2, 0xbf, 0x40, 0x9e, 0x58, 0x18, 0xcd, 0x96,
+       0x13, 0x66, 0x56, 0x11, 0x57, 0x52, 0x98, 0x1b, 0xdc, 0xb9, 0x88, 0x58,
+       0x73, 0xe8, 0x6d, 0xd3, 0x5c, 0x3b, 0xee, 0xdd, 0x1d, 0x10, 0xd7, 0x9b,
+       0x32, 0x0e, 0x1b, 0xeb, 0x9f, 0x1b, 0x41, 0x2d, 0xfc, 0x16, 0x6a, 0xc9,
+       0x84, 0x27, 0x83, 0x31, 0xcf, 0x36, 0xda, 0x9b, 0x6c, 0x02, 0x7a, 0xae,
+       0x40, 0xf7, 0x15, 0xd8, 0x01, 0x62, 0xf5, 0x2b, 0x1b, 0xf6, 0x31, 0xd6,
+       0x54, 0x63, 0x76, 0xca, 0xdf, 0x54, 0x13, 0xc9, 0x35, 0xd8, 0xcf, 0x75,
+       0xf4, 0x02, 0x6b, 0xe8, 0x55, 0xd7, 0xd1, 0xd7, 0x2d, 0x96, 0x0f, 0x81,
+       0x7e, 0xd6, 0x94, 0xfc, 0x8e, 0xe9, 0x5a, 0xa7, 0xcd, 0x7a, 0xe1, 0x2e,
+       0x7d, 0xb7, 0x2b, 0x4f, 0xf4, 0xb0, 0xd7, 0x64, 0x5f, 0xce, 0x7b, 0xe9,
+       0xab, 0xd0, 0xe3, 0x9a, 0xc9, 0x75, 0x7f, 0x1f, 0x7b, 0x01, 0xdf, 0x7e,
+       0x48, 0x0b, 0xed, 0x87, 0x7b, 0x08, 0xd3, 0xa3, 0xfd, 0x24, 0xaf, 0xf1,
+       0xd1, 0x66, 0xeb, 0xdd, 0xae, 0x9f, 0xe9, 0x3a, 0xcb, 0xbc, 0x22, 0xbe,
+       0xfd, 0xbe, 0xe7, 0xb0, 0xaf, 0xcb, 0x0e, 0x21, 0x76, 0x37, 0x1c, 0x79,
+       0xc1, 0xde, 0xec, 0x77, 0x07, 0x2a, 0xbe, 0x9c, 0x28, 0xc7, 0x43, 0x72,
+       0xa2, 0x91, 0x80, 0x4f, 0x50, 0x86, 0x56, 0x93, 0x0c, 0x45, 0xbe, 0x5e,
+       0x11, 0x79, 0xb9, 0xc2, 0x35, 0x2d, 0xc3, 0x58, 0x36, 0xd4, 0xce, 0xbb,
+       0x75, 0xd8, 0xe5, 0xdf, 0xcb, 0xe1, 0x79, 0x91, 0xb3, 0x58, 0x5f, 0xae,
+       0xd0, 0x57, 0x47, 0x50, 0xbf, 0xee, 0x94, 0xda, 0x02, 0x7a, 0xb2, 0x8a,
+       0x4c, 0x65, 0x1f, 0x60, 0xbe, 0x89, 0xc8, 0xba, 0xbe, 0x93, 0x15, 0x19,
+       0x3c, 0x17, 0x96, 0xf0, 0x39, 0x34, 0x7f, 0x90, 0xfd, 0xf9, 0x21, 0xff,
+       0x8e, 0xd6, 0xf5, 0xf9, 0x52, 0x19, 0x7b, 0x2b, 0xfd, 0x3a, 0x4e, 0x96,
+       0xea, 0x05, 0xc9, 0x57, 0x79, 0x16, 0x9e, 0x0b, 0x71, 0xac, 0xa5, 0x64,
+       0xfa, 0xf4, 0x88, 0x3c, 0x8b, 0x33, 0xd0, 0xff, 0xe1, 0x8c, 0x71, 0x29,
+       0x9e, 0xc5, 0x7c, 0xfd, 0x9a, 0x2c, 0x2c, 0x15, 0xa4, 0x56, 0xbd, 0xd0,
+       0x74, 0xf7, 0x8e, 0xef, 0x85, 0xe6, 0x5e, 0xf6, 0x10, 0xfb, 0x19, 0xf4,
+       0xaa, 0x16, 0xbe, 0x21, 0xb3, 0xfa, 0xf4, 0xd4, 0xe6, 0x3b, 0xe3, 0xe6,
+       0x1e, 0x76, 0x42, 0x66, 0x2b, 0x29, 0x29, 0x9d, 0x1e, 0xd1, 0x77, 0x0d,
+       0x6d, 0xe9, 0xea, 0xd3, 0x37, 0x90, 0x2b, 0x26, 0xf4, 0x9d, 0xf1, 0x2d,
+       0x79, 0xd4, 0x9e, 0x95, 0x27, 0xad, 0x83, 0x72, 0x02, 0xf5, 0xf5, 0xa7,
+       0xd1, 0xeb, 0xc7, 0xbb, 0xa9, 0x47, 0xd0, 0x6b, 0xb1, 0x07, 0x75, 0x64,
+       0xdc, 0xfe, 0xb8, 0xf9, 0x3c, 0x24, 0x7b, 0xb5, 0xce, 0x3c, 0xf9, 0x5f,
+       0x4e, 0x06, 0x79, 0xef, 0x06, 0x7a, 0xc7, 0x8c, 0x86, 0x33, 0x5c, 0xb8,
+       0x2a, 0xe1, 0x86, 0xcd, 0x17, 0x08, 0xb7, 0x60, 0x78, 0x70, 0x06, 0xe0,
+       0x42, 0x72, 0xd1, 0x0e, 0xc3, 0x46, 0x26, 0xc0, 0x27, 0x62, 0xfc, 0x68,
+       0xa7, 0x57, 0x07, 0xef, 0x40, 0x6e, 0xbd, 0xbd, 0xff, 0x35, 0x6f, 0xff,
+       0xb3, 0xde, 0xfe, 0xcb, 0x1b, 0xfb, 0xfd, 0xfc, 0xfa, 0x13, 0x47, 0x9a,
+       0xe8, 0x7a, 0xad, 0xec, 0xc2, 0xcf, 0x7a, 0x74, 0x5d, 0xde, 0xa0, 0xcb,
+       0x87, 0x87, 0x3c, 0x35, 0xcf, 0x8c, 0xcd, 0x8c, 0xd1, 0xfd, 0x90, 0xa3,
+       0x23, 0x39, 0x1b, 0xbe, 0x51, 0x49, 0x8c, 0x15, 0xf5, 0x9d, 0x9a, 0x92,
+       0xb5, 0xe8, 0xac, 0x4c, 0x58, 0x89, 0xb1, 0x69, 0x09, 0xc1, 0x96, 0x19,
+       0x5b, 0x42, 0x52, 0x63, 0xcc, 0xc1, 0x33, 0x6f, 0x6f, 0x4f, 0xeb, 0xd5,
+       0x26, 0x5a, 0x43, 0x2f, 0x91, 0x46, 0x97, 0xd6, 0xc8, 0xc0, 0x6d, 0x5a,
+       0x5d, 0x78, 0x97, 0xd6, 0xab, 0xe5, 0x26, 0xf8, 0x73, 0x61, 0x0f, 0x3e,
+       0xdc, 0x04, 0x4f, 0x7b, 0x66, 0x5d, 0x41, 0x7b, 0x26, 0x6d, 0x3f, 0x0b,
+       0xdf, 0x90, 0xc8, 0x8e, 0x74, 0xf5, 0xe8, 0x7d, 0x03, 0x8e, 0x44, 0x50,
+       0x6f, 0xb4, 0x62, 0x6d, 0xbd, 0xca, 0x5a, 0x44, 0xed, 0x6d, 0x95, 0x41,
+       0xd8, 0x2c, 0x75, 0xe7, 0xde, 0x0d, 0x3e, 0xaa, 0x6b, 0x02, 0x47, 0x9e,
+       0xb4, 0x49, 0xcb, 0x8f, 0x9d, 0x97, 0xa3, 0x83, 0x76, 0x49, 0x86, 0xcc,
+       0x56, 0x9c, 0x5f, 0x6b, 0x68, 0x9c, 0x49, 0xd2, 0xb2, 0x32, 0xd4, 0x6f,
+       0x7e, 0x0f, 0x7c, 0x8e, 0x57, 0x0d, 0xa9, 0x59, 0x89, 0xd8, 0x79, 0xe0,
+       0xd8, 0x0f, 0xdd, 0xd4, 0x46, 0x48, 0x8f, 0xc8, 0x61, 0xd8, 0x77, 0x4d,
+       0xe7, 0x45, 0xda, 0x71, 0x62, 0xa2, 0x88, 0x5a, 0xe7, 0x2f, 0x75, 0x6e,
+       0x73, 0x9c, 0x1b, 0xc8, 0x6f, 0x13, 0x5b, 0x6c, 0x4f, 0x9d, 0x73, 0x6d,
+       0x4f, 0x9d, 0x43, 0x0f, 0x7c, 0x32, 0x22, 0x6d, 0xcb, 0xf0, 0x9f, 0x97,
+       0xf6, 0xb8, 0xf5, 0xdc, 0x4b, 0xfc, 0xdd, 0x09, 0xf1, 0xee, 0x64, 0x58,
+       0xac, 0x93, 0x3a, 0x1f, 0x40, 0xde, 0xe3, 0x32, 0x7d, 0x86, 0x31, 0xd5,
+       0x92, 0x81, 0x93, 0xd4, 0x07, 0xeb, 0x9a, 0x85, 0xd1, 0x02, 0x7c, 0x64,
+       0x06, 0x71, 0x41, 0x2d, 0xdf, 0x94, 0x82, 0x45, 0x39, 0x74, 0x49, 0xfb,
+       0x32, 0xfa, 0xf1, 0x65, 0xc4, 0x86, 0xe5, 0x98, 0xb4, 0xc0, 0xb7, 0xd4,
+       0xb9, 0xa8, 0x51, 0x9a, 0x7f, 0x17, 0xfe, 0xc0, 0xdf, 0x70, 0x50, 0x5b,
+       0x9e, 0x8b, 0x19, 0xf4, 0x2d, 0x75, 0x8e, 0x76, 0x8e, 0x72, 0xea, 0x1c,
+       0xed, 0x9c, 0x74, 0xf8, 0xfe, 0x82, 0xf7, 0x73, 0x23, 0xfa, 0x9e, 0xfa,
+       0x86, 0x4d, 0x5e, 0x7e, 0x20, 0xd9, 0x2a, 0x6b, 0x44, 0xf2, 0x23, 0xdd,
+       0xa8, 0x65, 0x76, 0x65, 0xed, 0x81, 0xb1, 0x75, 0xf9, 0xa8, 0x7c, 0xdd,
+       0xf9, 0x11, 0xf8, 0x22, 0x1f, 0xcd, 0x7c, 0x91, 0xa7, 0x2e, 0x69, 0xd1,
+       0x7c, 0xf9, 0xfc, 0x40, 0xd0, 0xe0, 0x67, 0xef, 0xc9, 0x18, 0xf0, 0x7f,
+       0x11, 0x31, 0xa0, 0x0f, 0xcf, 0x27, 0xf0, 0x44, 0x4a, 0x3b, 0x47, 0xde,
+       0xc9, 0xeb, 0x75, 0xd4, 0x8d, 0x3e, 0x9f, 0x53, 0x78, 0x7f, 0x55, 0xa6,
+       0xe7, 0x9d, 0xe3, 0xc8, 0xab, 0xbc, 0x43, 0xef, 0x71, 0xef, 0x83, 0xb7,
+       0xf2, 0xfe, 0xaa, 0xb8, 0xf2, 0x49, 0x98, 0x35, 0xc1, 0xfb, 0xd2, 0x56,
+       0x59, 0x34, 0xc7, 0x8e, 0x98, 0xae, 0xc3, 0x0f, 0xd7, 0x19, 0x27, 0x28,
+       0xa3, 0xeb, 0x92, 0x9d, 0xe7, 0xfd, 0x97, 0x8b, 0x6f, 0xaa, 0xee, 0xc7,
+       0x8d, 0xe6, 0x3d, 0x36, 0xe0, 0xfa, 0x00, 0x47, 0xba, 0xd6, 0x28, 0x3f,
+       0xc4, 0x9c, 0xde, 0xa6, 0x58, 0xd3, 0xbc, 0x6f, 0x4c, 0x9e, 0x43, 0x1d,
+       0xf0, 0x9a, 0xbd, 0x49, 0xae, 0x53, 0xac, 0x85, 0x6a, 0xf5, 0x49, 0xf8,
+       0x64, 0x0b, 0x62, 0x99, 0x29, 0xeb, 0xe5, 0x56, 0xa9, 0xa1, 0xde, 0x59,
+       0x5c, 0x62, 0x2c, 0x24, 0xed, 0xed, 0x98, 0x77, 0xe3, 0x17, 0x63, 0xed,
+       0x7a, 0x19, 0x79, 0x16, 0xbe, 0xbd, 0x5e, 0x8e, 0xe2, 0xd9, 0x87, 0xa7,
+       0x85, 0x67, 0x1c, 0xcf, 0x24, 0x9e, 0x23, 0x78, 0x8e, 0xe0, 0x69, 0x61,
+       0x6f, 0x0c, 0x4f, 0xbf, 0x67, 0x20, 0xae, 0xdb, 0x7c, 0x97, 0xf4, 0x79,
+       0xa8, 0x15, 0x2d, 0xe6, 0xb4, 0xb0, 0x9d, 0x43, 0x1f, 0x91, 0x1d, 0x61,
+       0xad, 0xc7, 0x9a, 0xef, 0x03, 0xc7, 0xb4, 0xd8, 0x97, 0x17, 0x8d, 0xfd,
+       0x43, 0xcc, 0x0b, 0x55, 0xe4, 0x85, 0xf7, 0x76, 0xa3, 0x7f, 0x34, 0x0f,
+       0xe8, 0xbb, 0xa3, 0x79, 0x7c, 0xf3, 0x1d, 0x3d, 0x6f, 0x74, 0x06, 0x79,
+       0x8a, 0xf1, 0xd3, 0xc1, 0x9e, 0x3c, 0xe2, 0xf8, 0x2e, 0xf8, 0x5f, 0x06,
+       0x71, 0x1b, 0xef, 0x0b, 0x97, 0x76, 0xbb, 0x39, 0x15, 0xf9, 0x56, 0x6d,
+       0xbd, 0xaf, 0xb1, 0xb1, 0x67, 0xbb, 0xde, 0xa0, 0x13, 0x38, 0x12, 0xd5,
+       0x05, 0xf8, 0xe0, 0xf7, 0xed, 0xe3, 0xba, 0xb6, 0xa3, 0x2e, 0x9e, 0x45,
+       0x8d, 0x9a, 0x9b, 0x63, 0x0d, 0x73, 0x0c, 0x7d, 0x09, 0xfa, 0xb3, 0x28,
+       0x7b, 0x72, 0xe6, 0x02, 0x5d, 0x8b, 0x46, 0xa5, 0x9d, 0x79, 0xe0, 0x06,
+       0xce, 0x03, 0x5f, 0x8b, 0x0e, 0x64, 0xf6, 0x08, 0x6a, 0x42, 0xc7, 0x09,
+       0x5b, 0xfb, 0x25, 0xfe, 0x38, 0x63, 0x8e, 0x60, 0xbf, 0x29, 0xee, 0xbd,
+       0x3a, 0xe2, 0xee, 0xa4, 0xfe, 0xbd, 0x18, 0xc6, 0x65, 0x63, 0xef, 0x1d,
+       0xc0, 0xc5, 0x79, 0xde, 0x69, 0x8b, 0xec, 0x9f, 0x73, 0x6b, 0x5a, 0x65,
+       0x35, 0xe3, 0xfb, 0x39, 0x0f, 0x1f, 0xd7, 0x95, 0xf7, 0xdb, 0xc6, 0x1e,
+       0xc8, 0x08, 0xfe, 0x00, 0x1d, 0x9f, 0x40, 0xfd, 0x7c, 0x11, 0x7a, 0x79,
+       0x0d, 0x3a, 0xb9, 0x54, 0xa6, 0xad, 0x0f, 0xc3, 0xee, 0x21, 0xc3, 0x49,
+       0xe2, 0x1a, 0xd1, 0x67, 0x5f, 0x2c, 0x23, 0x76, 0x32, 0xfe, 0xa9, 0x5f,
+       0x8d, 0xb2, 0x3e, 0x64, 0x1e, 0x74, 0xf1, 0xf4, 0xb9, 0x70, 0xe2, 0xaf,
+       0xed, 0xd6, 0xf4, 0xd4, 0xf4, 0x3d, 0x18, 0xe5, 0x04, 0x1b, 0xe4, 0x6f,
+       0x04, 0x1a, 0xe6, 0x0b, 0x51, 0x7d, 0x0f, 0xaf, 0x38, 0x47, 0x3e, 0x46,
+       0x24, 0x3b, 0xe7, 0xef, 0xeb, 0xc6, 0xbe, 0x1d, 0x4d, 0xb8, 0xee, 0xdc,
+       0xc2, 0x83, 0xf2, 0x78, 0xe0, 0xfa, 0xd6, 0xba, 0x3f, 0x61, 0x16, 0x37,
+       0xee, 0x86, 0x99, 0x7f, 0xa9, 0x9b, 0x14, 0xf6, 0xfb, 0xfa, 0xe9, 0xf3,
+       0x7a, 0x81, 0xc4, 0x6c, 0x51, 0x58, 0xab, 0x50, 0x47, 0x63, 0xf0, 0x6b,
+       0x13, 0xf8, 0x6d, 0xa9, 0x96, 0xdb, 0x44, 0xf5, 0xb0, 0x37, 0x66, 0xad,
+       0xdc, 0x7c, 0xe6, 0xaf, 0x78, 0x67, 0xa2, 0x9f, 0x3e, 0xc5, 0xba, 0x59,
+       0xe7, 0x19, 0xc0, 0x74, 0x6c, 0xa1, 0xed, 0x17, 0x3d, 0x38, 0xae, 0x27,
+       0xa5, 0x88, 0x3a, 0x34, 0x37, 0x87, 0x8a, 0x1e, 0xf1, 0x5b, 0xa5, 0xf9,
+       0xbb, 0x16, 0xef, 0xf0, 0x86, 0xe3, 0xd3, 0xa0, 0xb1, 0x68, 0x66, 0x78,
+       0x6f, 0x06, 0x1c, 0xbd, 0x5b, 0x70, 0x8c, 0x7b, 0x38, 0xc6, 0xa5, 0x74,
+       0x66, 0x02, 0xbe, 0x96, 0x41, 0x7e, 0xef, 0x37, 0x1f, 0x91, 0x4f, 0xa0,
+       0xb9, 0xc6, 0xdc, 0xd9, 0x11, 0xe8, 0xc9, 0x71, 0xf6, 0xdb, 0x87, 0x40,
+       0xf7, 0x77, 0x90, 0x5b, 0xfd, 0x9a, 0xa7, 0x14, 0x0b, 0x21, 0x87, 0x1d,
+       0xd1, 0xbf, 0xc3, 0x16, 0x4d, 0x13, 0xf6, 0xaa, 0x8c, 0xe1, 0x24, 0xda,
+       0x7b, 0xe4, 0xb7, 0x59, 0xe4, 0x2a, 0xf2, 0xd9, 0x29, 0x25, 0xd3, 0x78,
+       0x38, 0x84, 0xba, 0x26, 0x3b, 0x47, 0x3f, 0x92, 0x81, 0x50, 0xba, 0x15,
+       0x35, 0xa9, 0x23, 0x6f, 0xdb, 0xfc, 0x77, 0x0a, 0xb3, 0x72, 0xb1, 0x6e,
+       0xe2, 0xf9, 0x5d, 0xe8, 0xe1, 0x4f, 0xf1, 0xfe, 0x76, 0x0f, 0xea, 0x3e,
+       0xac, 0x64, 0x60, 0xbb, 0x49, 0x5d, 0xcf, 0xb0, 0x8e, 0xa8, 0x21, 0xdf,
+       0x2a, 0xe4, 0x1a, 0xd4, 0x55, 0x63, 0xac, 0x5d, 0x9f, 0x5b, 0xbc, 0x26,
+       0x97, 0xe6, 0xf9, 0x3b, 0x28, 0xf3, 0xf2, 0x41, 0xc6, 0x03, 0x73, 0x26,
+       0x85, 0xb9, 0x25, 0xc6, 0x32, 0x7c, 0x37, 0xe0, 0x40, 0x3d, 0xa8, 0x11,
+       0x50, 0x6b, 0xaf, 0x5b, 0x49, 0xf0, 0x79, 0x4d, 0x2e, 0xce, 0x87, 0x65,
+       0xd1, 0x62, 0x5d, 0x24, 0xf1, 0x2c, 0x60, 0x2f, 0x2e, 0xfd, 0x93, 0x6b,
+       0x13, 0x84, 0x47, 0xcf, 0x53, 0x44, 0x5d, 0xf7, 0x88, 0xde, 0xfb, 0xd3,
+       0xf4, 0x4c, 0x9a, 0x9a, 0xfb, 0xbc, 0x82, 0x5c, 0xa4, 0x3f, 0xe9, 0xdf,
+       0x28, 0x58, 0x1b, 0x1c, 0x83, 0xcd, 0xb2, 0x76, 0x67, 0x3f, 0x80, 0xf7,
+       0x3a, 0xd7, 0xc9, 0x3b, 0x9e, 0x0b, 0xfd, 0x90, 0x0d, 0xfd, 0x9e, 0x77,
+       0x62, 0xc8, 0xa3, 0x8a, 0xbe, 0x5e, 0xd2, 0xb1, 0xa0, 0x54, 0x29, 0x20,
+       0xa7, 0x20, 0x06, 0xd8, 0xbd, 0xb0, 0xc5, 0x49, 0xe8, 0x72, 0x0c, 0x70,
+       0x5b, 0x72, 0xc9, 0x6a, 0x49, 0xd7, 0x65, 0x6a, 0xe5, 0xf6, 0xfd, 0x4d,
+       0x1e, 0xfe, 0xa3, 0x56, 0x61, 0x5b, 0xf0, 0x21, 0xb5, 0x1a, 0xc5, 0x13,
+       0xf1, 0x78, 0x15, 0xfd, 0x45, 0x99, 0xf7, 0x43, 0xe8, 0x0d, 0xca, 0xbc,
+       0x3b, 0x49, 0xe2, 0x39, 0xc2, 0xfb, 0x22, 0x2f, 0xae, 0x11, 0x3f, 0xe9,
+       0xf0, 0xe3, 0x0b, 0x6b, 0x49, 0xc6, 0x17, 0xbf, 0x9e, 0x74, 0x6d, 0xe1,
+       0x44, 0x85, 0x31, 0x84, 0x76, 0xdd, 0x8f, 0xb8, 0x45, 0x5b, 0x70, 0x6b,
+       0xc9, 0xa5, 0xaa, 0x2b, 0xb3, 0xe9, 0xc6, 0x05, 0x9d, 0x23, 0x0e, 0x88,
+       0x05, 0x1b, 0xa3, 0xec, 0xb0, 0xa6, 0x73, 0xc0, 0x79, 0xc9, 0xe8, 0x27,
+       0x65, 0xf6, 0xaa, 0x64, 0x96, 0x46, 0xe4, 0x05, 0x1d, 0xb7, 0xfc, 0x98,
+       0xc5, 0x1a, 0x92, 0xbf, 0x1f, 0x27, 0xe5, 0xf9, 0xd3, 0xd7, 0x24, 0xfb,
+       0x22, 0xe3, 0xd6, 0x70, 0x6c, 0x87, 0xc1, 0x58, 0xe5, 0x48, 0x1d, 0xb9,
+       0xe9, 0x11, 0x9b, 0xff, 0x16, 0x20, 0x84, 0x9e, 0xce, 0x91, 0xd6, 0xd1,
+       0x84, 0x1d, 0x37, 0xfa, 0x9f, 0xd8, 0x61, 0x30, 0x37, 0x0e, 0x9b, 0x4f,
+       0x89, 0x7f, 0x1f, 0xd5, 0x26, 0x4f, 0xe9, 0xbb, 0x0a, 0xb8, 0xed, 0xdc,
+       0xfb, 0xfa, 0x77, 0x94, 0x1b, 0x29, 0xca, 0x1a, 0xdf, 0xab, 0x9c, 0x2f,
+       0x46, 0x6e, 0xa4, 0x5a, 0xa4, 0x74, 0x87, 0xe3, 0x3c, 0x39, 0xfa, 0xc0,
+       0x6e, 0xf7, 0xdf, 0x8b, 0x3c, 0x7d, 0x87, 0x1b, 0x0b, 0x7e, 0xcd, 0xfb,
+       0xfe, 0x3a, 0x9e, 0xb4, 0x6d, 0xe6, 0x5b, 0xe6, 0x47, 0xea, 0x0d, 0xcf,
+       0x25, 0xbe, 0x33, 0xf7, 0xce, 0x22, 0xf7, 0x32, 0x5f, 0xee, 0x92, 0x1c,
+       0x7f, 0xe7, 0x53, 0x7a, 0xbe, 0xe8, 0xd6, 0xd2, 0x1e, 0x5c, 0x75, 0x4a,
+       0xa6, 0xab, 0xac, 0xa1, 0x2e, 0x22, 0x97, 0x0d, 0xc1, 0x56, 0x99, 0xd3,
+       0x8e, 0x23, 0x9f, 0xf3, 0xf7, 0x69, 0xac, 0x2d, 0x70, 0x5f, 0x22, 0x19,
+       0x57, 0xcd, 0xbf, 0x2b, 0xdd, 0x8c, 0xf2, 0x3e, 0xea, 0xfc, 0x10, 0xf4,
+       0xfe, 0x15, 0xf6, 0x16, 0x03, 0xda, 0x46, 0xb2, 0x2f, 0x51, 0xf6, 0xee,
+       0xef, 0xd7, 0xd2, 0xed, 0xfa, 0x00, 0xeb, 0x80, 0xcf, 0x40, 0x2e, 0x07,
+       0xec, 0x6b, 0xcc, 0xdd, 0xff, 0xa6, 0xac, 0xe1, 0xe4, 0x53, 0x06, 0x7d,
+       0x1b, 0xdf, 0x4b, 0x21, 0x59, 0x88, 0x92, 0x7f, 0xc8, 0xcb, 0xa0, 0xef,
+       0x6c, 0x27, 0x87, 0xad, 0x32, 0xf8, 0x0b, 0xc8, 0x80, 0xb2, 0xf4, 0x65,
+       0xc0, 0xf7, 0x09, 0xe8, 0x8b, 0x3d, 0x43, 0xbf, 0xee, 0x23, 0x4b, 0x0d,
+       0xf7, 0xec, 0x52, 0xa5, 0x99, 0x66, 0xd2, 0x4b, 0x9d, 0x9e, 0x97, 0x9c,
+       0xd6, 0xef, 0xac, 0xe4, 0xaa, 0xe7, 0x65, 0x7f, 0x75, 0x56, 0x1e, 0xb5,
+       0x1e, 0x06, 0xbf, 0x57, 0x9c, 0x82, 0xa5, 0x7b, 0x95, 0xb1, 0x3c, 0xce,
+       0x2e, 0x8c, 0xf4, 0xca, 0x4d, 0xd4, 0x1d, 0xcf, 0x2e, 0x9a, 0xf2, 0x3f,
+       0x9d, 0x5b, 0x5f, 0x6c, 0x5b, 0xd5, 0x19, 0xff, 0x7c, 0x6d, 0x27, 0x69,
+       0x68, 0xc2, 0xad, 0xeb, 0x24, 0x6e, 0x9a, 0x51, 0x3b, 0xbe, 0x6d, 0x23,
+       0x92, 0xa2, 0xdb, 0x10, 0x68, 0xd4, 0x65, 0x8a, 0x71, 0x42, 0x17, 0xb6,
+       0x22, 0xd2, 0xae, 0xab, 0x2a, 0x8d, 0x81, 0xe5, 0xa6, 0x7f, 0xd8, 0xc3,
+       0x0a, 0x85, 0x75, 0x08, 0x21, 0xd5, 0xb8, 0xe9, 0xd6, 0x69, 0x21, 0x4e,
+       0xff, 0x2d, 0x8c, 0x87, 0xcd, 0x4a, 0xd2, 0x96, 0x4d, 0x11, 0x2e, 0x88,
+       0xb2, 0x3d, 0x6c, 0xa3, 0x4a, 0x01, 0xed, 0x79, 0x7b, 0x99, 0x34, 0x36,
+       0x65, 0x05, 0x36, 0x5e, 0x36, 0xf5, 0x81, 0x07, 0xa6, 0xd1, 0x79, 0xbf,
+       0xdf, 0x77, 0xee, 0x75, 0x6c, 0x13, 0x84, 0xb4, 0x48, 0x91, 0xef, 0x39,
+       0xf7, 0xdc, 0x73, 0xce, 0x3d, 0xdf, 0xff, 0xef, 0xfb, 0xdd, 0x8c, 0x3d,
+       0x28, 0x3f, 0xd2, 0x5c, 0x3e, 0xe3, 0x93, 0x00, 0x7c, 0x52, 0x83, 0x2d,
+       0x90, 0x36, 0x27, 0x76, 0x53, 0xe8, 0x53, 0x86, 0x41, 0xeb, 0xb8, 0xf1,
+       0x9b, 0x6d, 0x73, 0x7f, 0xcb, 0x59, 0xf8, 0xee, 0xee, 0x7d, 0x6d, 0x7e,
+       0xce, 0xd7, 0xf8, 0xb7, 0x7f, 0xf2, 0x6a, 0x68, 0x83, 0x32, 0x83, 0xfd,
+       0xbc, 0xa1, 0x7a, 0xd6, 0x01, 0x2f, 0x31, 0x37, 0x1d, 0xd3, 0xfc, 0x43,
+       0x78, 0x9a, 0x3a, 0xea, 0x2a, 0x74, 0xd4, 0x10, 0x75, 0xd7, 0xf0, 0xbc,
+       0xcb, 0xfc, 0x40, 0x54, 0xfe, 0x38, 0x45, 0x3d, 0x1c, 0x97, 0x3f, 0x4c,
+       0x3d, 0x8b, 0xfd, 0x24, 0x8a, 0xcc, 0x51, 0xde, 0x98, 0xc9, 0xd1, 0x4f,
+       0x52, 0x7f, 0x3e, 0xed, 0x3e, 0xad, 0x76, 0x20, 0x6e, 0xe5, 0xd7, 0x87,
+       0x55, 0xdf, 0x1c, 0xd3, 0xda, 0x6e, 0xdc, 0xea, 0x92, 0x1b, 0x17, 0x8c,
+       0x8e, 0x0d, 0x4f, 0x47, 0x03, 0x23, 0x0b, 0xb4, 0x4b, 0xc9, 0x58, 0xd6,
+       0x6a, 0x94, 0x43, 0x51, 0xe6, 0x9e, 0x53, 0xd4, 0xcf, 0xb0, 0x85, 0xbd,
+       0x76, 0xd6, 0x6a, 0xf2, 0xec, 0x4f, 0xac, 0x4e, 0xcf, 0x1e, 0xf3, 0xf4,
+       0x2c, 0xef, 0xa5, 0x68, 0x03, 0x20, 0x93, 0x89, 0x99, 0x51, 0x2b, 0x09,
+       0x9b, 0x87, 0xeb, 0x45, 0xce, 0x1f, 0x97, 0xe3, 0x8b, 0x47, 0xe1, 0x7f,
+       0xf7, 0xda, 0x7b, 0x69, 0x57, 0xed, 0x21, 0xe2, 0x71, 0xb0, 0xfe, 0x97,
+       0xea, 0xe6, 0x7a, 0xd4, 0x9b, 0x8b, 0xf7, 0x21, 0xe7, 0xd3, 0xac, 0xd7,
+       0x36, 0x32, 0x9f, 0xa3, 0x7b, 0xad, 0x1d, 0xbb, 0xa7, 0xb2, 0xee, 0x64,
+       0xc1, 0xf1, 0xb0, 0x61, 0xf8, 0x85, 0x2f, 0xf4, 0x8d, 0x08, 0xd7, 0xe4,
+       0x7a, 0xad, 0x92, 0xde, 0x0f, 0xfd, 0x32, 0xcd, 0xff, 0x9c, 0x57, 0xbb,
+       0x42, 0xbc, 0x12, 0xed, 0x5c, 0xc5, 0x36, 0x7d, 0xc5, 0x9b, 0xaf, 0xbf,
+       0x5d, 0x9a, 0xa3, 0x55, 0xe3, 0x99, 0x5b, 0x61, 0x3b, 0x2e, 0xb9, 0x45,
+       0xfe, 0x96, 0xcb, 0x11, 0xa7, 0x41, 0xf6, 0xda, 0x1b, 0xeb, 0xe6, 0xd8,
+       0x86, 0x3e, 0xe3, 0x13, 0x04, 0xa7, 0x03, 0x9e, 0x6f, 0xb1, 0x89, 0x7e,
+       0x93, 0x77, 0xdd, 0xa4, 0x39, 0x99, 0xb8, 0xd5, 0x59, 0xf7, 0x1e, 0x9b,
+       0x2a, 0x76, 0x38, 0x6e, 0x51, 0x77, 0x36, 0x46, 0xa5, 0x95, 0x3c, 0x54,
+       0x56, 0x3f, 0x3e, 0xe4, 0x18, 0xcc, 0x45, 0xd4, 0x39, 0xd2, 0xce, 0x9c,
+       0xfd, 0x5b, 0x7a, 0x6e, 0x2d, 0xf4, 0x09, 0x70, 0x0d, 0x3e, 0xf9, 0x4c,
+       0xbe, 0x97, 0xb9, 0x5e, 0xcc, 0xdf, 0xcc, 0xf9, 0x5d, 0xef, 0x9c, 0x13,
+       0x6e, 0xce, 0xba, 0x5f, 0xb2, 0x17, 0x0c, 0xff, 0xa5, 0x1d, 0xf0, 0x5e,
+       0x2b, 0xda, 0x0b, 0xb4, 0x09, 0x9f, 0x37, 0x8f, 0x6f, 0x1b, 0x7a, 0xd4,
+       0x36, 0x9c, 0x2a, 0x90, 0x3f, 0xc9, 0x97, 0x3e, 0x3f, 0xfa, 0x3a, 0x8f,
+       0x3c, 0x4a, 0x3d, 0x3b, 0x28, 0x67, 0x0b, 0x3c, 0x9b, 0x94, 0xd6, 0xb4,
+       0x36, 0x9f, 0x3b, 0xa8, 0x98, 0xac, 0xee, 0xe9, 0xc4, 0x4b, 0x39, 0x19,
+       0x96, 0xab, 0x2e, 0xcf, 0x2c, 0x51, 0xcc, 0x04, 0x5b, 0xaa, 0xde, 0x7f,
+       0xbf, 0x9e, 0x59, 0x58, 0x7d, 0xc6, 0x18, 0xc6, 0x3e, 0xef, 0xd1, 0xbb,
+       0x55, 0xcf, 0x36, 0x53, 0x43, 0x9f, 0xaf, 0xeb, 0x39, 0x85, 0xa1, 0x13,
+       0x59, 0xdf, 0x0f, 0x47, 0xf8, 0x0c, 0xd7, 0xa5, 0xcf, 0xc7, 0xb5, 0xc8,
+       0x7b, 0xdd, 0xb0, 0xd8, 0xfd, 0x12, 0xdc, 0x09, 0xd1, 0xdf, 0xc9, 0x3a,
+       0x72, 0x00, 0xb2, 0xba, 0xd9, 0x60, 0x60, 0xc6, 0x8d, 0xaf, 0x91, 0xb1,
+       0xae, 0xe1, 0x1c, 0x11, 0xab, 0xc0, 0x8f, 0x3e, 0xf5, 0x93, 0xdb, 0x98,
+       0x2f, 0xe3, 0xf9, 0xeb, 0x03, 0x98, 0xdf, 0xf1, 0xea, 0xea, 0x53, 0xdb,
+       0xc9, 0xab, 0xa3, 0x5a, 0x1f, 0xe4, 0x33, 0x94, 0x63, 0x9e, 0x19, 0xe9,
+       0xf2, 0x1e, 0x9e, 0x67, 0x7b, 0x5b, 0x1d, 0x1d, 0x93, 0xde, 0xfe, 0xfc,
+       0xfb, 0x61, 0x09, 0xb7, 0x53, 0xc7, 0x45, 0x25, 0x39, 0xcd, 0x98, 0x05,
+       0xb6, 0x6b, 0x9c, 0x73, 0x7d, 0xb1, 0x2e, 0xce, 0xfc, 0x9f, 0xba, 0x38,
+       0x63, 0x7d, 0xa4, 0xbc, 0x13, 0xd6, 0x3c, 0xd6, 0xe7, 0xd3, 0xb5, 0x58,
+       0x43, 0x57, 0xbf, 0x76, 0x1f, 0xad, 0xd0, 0xf1, 0x87, 0x05, 0xda, 0xab,
+       0x94, 0xe6, 0x94, 0xff, 0x3e, 0xc5, 0xb3, 0xe5, 0x1e, 0xaf, 0x72, 0x8f,
+       0xc3, 0x4b, 0x8a, 0x83, 0x7c, 0x58, 0x65, 0xf8, 0x74, 0x81, 0x3a, 0xa6,
+       0x45, 0xe6, 0x67, 0x7c, 0x3d, 0x33, 0xe6, 0xf9, 0xb8, 0xf9, 0xf5, 0x0d,
+       0xaa, 0x67, 0xe0, 0xdd, 0x38, 0x23, 0x9e, 0x7d, 0xe9, 0x92, 0xb9, 0x0b,
+       0xb4, 0xbb, 0x49, 0xf4, 0x45, 0x03, 0x73, 0x0b, 0xac, 0x4d, 0x12, 0x8b,
+       0x32, 0x2c, 0xac, 0xfb, 0x8f, 0xd8, 0xa7, 0x20, 0x6f, 0x31, 0x79, 0x7f,
+       0x8a, 0x3e, 0x7d, 0x03, 0x7c, 0xe3, 0xd6, 0xba, 0xf3, 0xdd, 0x51, 0xf1,
+       0x09, 0x6b, 0xe9, 0x1e, 0xef, 0x90, 0x66, 0xf2, 0xb9, 0x63, 0xdf, 0x10,
+       0xfa, 0x60, 0xbc, 0xce, 0x22, 0x16, 0x60, 0xec, 0x11, 0xd7, 0xd8, 0x63,
+       0xae, 0xc8, 0xbe, 0x16, 0x2f, 0xaf, 0xd4, 0xa2, 0xbc, 0x42, 0x7e, 0xcb,
+       0xa8, 0xff, 0x3d, 0xa4, 0x3a, 0x2b, 0x3f, 0xd5, 0x6b, 0x70, 0x2c, 0x76,
+       0x4c, 0x79, 0x4f, 0x6a, 0x78, 0x2f, 0xe6, 0xad, 0x3d, 0xd6, 0x61, 0x7c,
+       0x2b, 0x5b, 0xf5, 0x4d, 0x58, 0xc7, 0xd1, 0xae, 0x70, 0x7e, 0xf2, 0x06,
+       0x79, 0x84, 0x3a, 0xcf, 0x1f, 0xe7, 0xd3, 0xc3, 0x6f, 0x73, 0x3c, 0xf9,
+       0xbf, 0x1a, 0x8b, 0xe0, 0xcb, 0xaa, 0xdf, 0xe7, 0xcb, 0x1d, 0xef, 0x55,
+       0xdb, 0x04, 0xca, 0x5d, 0x75, 0x7d, 0xd2, 0x96, 0xc8, 0xf4, 0x0a, 0x5d,
+       0xd2, 0xfd, 0xdc, 0xff, 0xf3, 0xcc, 0xed, 0x42, 0xde, 0x56, 0xa3, 0xcd,
+       0x09, 0xa5, 0x4d, 0x06, 0xb4, 0x89, 0x28, 0x6d, 0x18, 0xef, 0x3d, 0xe5,
+       0xf1, 0x5b, 0x0b, 0xce, 0x8b, 0xb9, 0x5a, 0xe8, 0xba, 0x7d, 0xd4, 0xf9,
+       0xcf, 0x76, 0x68, 0x7d, 0xd0, 0xa1, 0xee, 0x5b, 0x0b, 0x7d, 0xc6, 0xf6,
+       0x56, 0xf5, 0x47, 0x4c, 0xbc, 0x15, 0xd7, 0x3c, 0x68, 0x10, 0xfa, 0x79,
+       0x6e, 0x0a, 0xbe, 0x1a, 0x71, 0x6f, 0x35, 0xb4, 0xfa, 0x8e, 0x77, 0x5e,
+       0xf3, 0x4a, 0x1b, 0xca, 0x00, 0xf5, 0xe6, 0x3a, 0xcc, 0xb7, 0x27, 0xda,
+       0x07, 0xfe, 0xfa, 0x19, 0xfa, 0x37, 0x6b, 0x3c, 0x11, 0x84, 0xcc, 0xdf,
+       0x9c, 0x6a, 0xf7, 0x62, 0x38, 0x07, 0x6d, 0xc4, 0xad, 0x53, 0x11, 0xc6,
+       0x14, 0x68, 0xf7, 0x48, 0xc3, 0x34, 0xe2, 0x57, 0xe8, 0xf1, 0x25, 0xb5,
+       0x47, 0x7d, 0xb8, 0x7f, 0x07, 0x71, 0x7e, 0xb8, 0x3e, 0x8a, 0xe7, 0x7a,
+       0x0d, 0x16, 0x21, 0xba, 0x45, 0xcf, 0x74, 0x6e, 0x2a, 0x11, 0x3b, 0x2c,
+       0x5e, 0xdf, 0xb8, 0xab, 0xfa, 0x60, 0x65, 0x5f, 0x0f, 0xca, 0x9e, 0x8a,
+       0xbd, 0x60, 0x1c, 0x0d, 0x1f, 0x7e, 0xc6, 0xd8, 0x83, 0x7c, 0xb1, 0x4f,
+       0xf1, 0x51, 0xc1, 0xa1, 0x45, 0x9c, 0x25, 0x7d, 0xd2, 0x65, 0xf8, 0xe1,
+       0x2e, 0xce, 0x90, 0x7e, 0x77, 0xf9, 0xe4, 0xa4, 0x9b, 0x62, 0x7d, 0x0c,
+       0xfa, 0xe0, 0xa4, 0x8c, 0x20, 0x2e, 0x18, 0x09, 0xb6, 0x32, 0xaf, 0x0c,
+       0xdf, 0x30, 0xe7, 0xe5, 0x1e, 0xfb, 0x98, 0x33, 0x95, 0x73, 0x0b, 0xdc,
+       0x3b, 0x65, 0xdb, 0xc4, 0xde, 0x73, 0x53, 0xdc, 0xaf, 0xc9, 0x43, 0xb0,
+       0x6d, 0x4d, 0xbb, 0xf8, 0xe5, 0x59, 0x0c, 0xe0, 0x77, 0x10, 0xf2, 0xc0,
+       0xb1, 0xf8, 0x5d, 0x58, 0x96, 0x77, 0x2f, 0xf8, 0xb6, 0x3d, 0x20, 0x6f,
+       0x3b, 0xe5, 0x93, 0xa7, 0xdc, 0xf5, 0x3c, 0x03, 0x37, 0xc7, 0x9a, 0xb5,
+       0xe3, 0xb8, 0x79, 0x29, 0x97, 0x97, 0xdc, 0xa5, 0xf5, 0x96, 0xd2, 0x92,
+       0xf2, 0xbf, 0x8c, 0x33, 0xbc, 0x7e, 0xaf, 0x25, 0x86, 0x7e, 0xa4, 0xcd,
+       0x67, 0x6b, 0x7f, 0xd5, 0xb6, 0xc0, 0xd7, 0x7f, 0xe4, 0x47, 0xf2, 0xe5,
+       0xb2, 0xec, 0x52, 0xfd, 0xbf, 0xda, 0x73, 0xd5, 0xba, 0xdf, 0xf7, 0x6f,
+       0xa9, 0xdf, 0xb5, 0xfe, 0xa3, 0xf1, 0xc1, 0x96, 0xe9, 0x7a, 0x9d, 0xf0,
+       0x98, 0x57, 0x57, 0x58, 0x8d, 0xf7, 0x0e, 0x78, 0x7a, 0x21, 0xa5, 0xbe,
+       0x73, 0xca, 0xa6, 0x7e, 0xe0, 0x7e, 0x9a, 0xe5, 0xe0, 0xec, 0x6d, 0xd0,
+       0xc4, 0xd7, 0xc1, 0x8c, 0xfb, 0x7c, 0xdd, 0xd1, 0xea, 0xf9, 0xc2, 0x96,
+       0x74, 0x9f, 0xa3, 0xef, 0xe4, 0x40, 0x8f, 0xb6, 0x49, 0x66, 0x3c, 0x28,
+       0xc9, 0x73, 0x1b, 0x62, 0xc6, 0xd7, 0x25, 0xff, 0x41, 0xde, 0xb4, 0x4f,
+       0x7d, 0x51, 0xf4, 0xdf, 0x29, 0x5c, 0xdb, 0xf0, 0x33, 0xe4, 0x79, 0x9f,
+       0x7f, 0xcf, 0xae, 0xe3, 0xd1, 0x9d, 0x1e, 0x8f, 0xf2, 0xbe, 0x65, 0xea,
+       0x1f, 0x18, 0xdb, 0x7d, 0x8e, 0x7b, 0x34, 0xcf, 0x75, 0x9f, 0x33, 0xf1,
+       0x7a, 0xed, 0x73, 0x7d, 0x95, 0xe7, 0x70, 0xbf, 0x47, 0xb1, 0x61, 0x98,
+       0x7b, 0xd7, 0x20, 0x7c, 0xba, 0x3e, 0xda, 0x1c, 0xda, 0xef, 0xcd, 0xee,
+       0x2e, 0x21, 0xbf, 0x27, 0x3c, 0x9e, 0xa3, 0xbe, 0x89, 0x78, 0xfa, 0x66,
+       0xc5, 0xbe, 0x8c, 0x18, 0xfc, 0x09, 0x73, 0x22, 0x55, 0xf6, 0xe5, 0x71,
+       0xf3, 0x6e, 0x35, 0xf6, 0xe5, 0x4e, 0x6f, 0x1e, 0xff, 0x9e, 0xaf, 0x57,
+       0xfc, 0xb6, 0xaf, 0x57, 0xea, 0x7d, 0x5a, 0x9f, 0xf6, 0xb5, 0xb8, 0xaf,
+       0xea, 0x98, 0x2f, 0xbf, 0x6a, 0xde, 0x25, 0x8b, 0x98, 0x8d, 0x3e, 0x65,
+       0x22, 0x67, 0x30, 0xd3, 0xd6, 0x59, 0x8b, 0xb8, 0x0f, 0xe7, 0xc7, 0x92,
+       0x8e, 0xdc, 0xd6, 0xd8, 0xfa, 0xf4, 0xec, 0x98, 0xe6, 0x79, 0xe6, 0x5c,
+       0x4f, 0xef, 0x44, 0x77, 0x43, 0xae, 0x5e, 0x89, 0xac, 0x60, 0x8a, 0x66,
+       0x4e, 0xa4, 0x61, 0x87, 0x52, 0x5a, 0x2f, 0xfb, 0x2e, 0xf6, 0x3b, 0xa8,
+       0x78, 0xae, 0x35, 0xce, 0x73, 0xf2, 0x90, 0x5d, 0xd6, 0xda, 0x4d, 0xd3,
+       0x50, 0xf1, 0x44, 0xd3, 0x8b, 0x3e, 0xdf, 0x93, 0x9f, 0x66, 0x4e, 0x1c,
+       0x9c, 0x29, 0x0f, 0x87, 0xb6, 0xf7, 0xda, 0x79, 0x21, 0x66, 0x7f, 0x58,
+       0x8e, 0x28, 0x76, 0xf8, 0x15, 0xdc, 0xdf, 0xc7, 0xf8, 0x32, 0x11, 0x52,
+       0x4c, 0x70, 0x22, 0x36, 0x01, 0x59, 0xcc, 0xba, 0xc4, 0xf8, 0xaf, 0x55,
+       0xac, 0xff, 0x9c, 0xd0, 0xcf, 0x22, 0xa6, 0xe0, 0x59, 0x39, 0xec, 0x6e,
+       0x76, 0x97, 0xc4, 0xf8, 0xbf, 0x59, 0xad, 0x09, 0x35, 0xca, 0x84, 0x1b,
+       0x6a, 0x4a, 0x97, 0x8c, 0x0c, 0x8c, 0x06, 0x53, 0x6b, 0x26, 0x9d, 0x68,
+       0xd3, 0xae, 0x12, 0x64, 0xbc, 0x04, 0xfd, 0x5f, 0x8a, 0x05, 0x46, 0x14,
+       0x9b, 0xf6, 0x65, 0x49, 0xb7, 0xd3, 0xcf, 0xa7, 0x3e, 0xf9, 0x8a, 0xdc,
+       0xb4, 0xb7, 0xca, 0xcd, 0x1e, 0xe2, 0x31, 0xfb, 0xd1, 0xa6, 0x2e, 0x19,
+       0x44, 0x5f, 0x12, 0x7d, 0x4d, 0xca, 0x8f, 0x1a, 0x9f, 0x41, 0x67, 0xdd,
+       0xb4, 0xa9, 0xab, 0xee, 0xe2, 0x2f, 0xde, 0xf5, 0x6f, 0xa0, 0x09, 0xb1,
+       0x1d, 0xdb, 0xd0, 0xa6, 0x8e, 0xb3, 0xeb, 0xfa, 0x3b, 0xd1, 0xbe, 0x17,
+       0x73, 0x34, 0xe8, 0xfb, 0x59, 0xce, 0x76, 0x53, 0xe7, 0xac, 0x19, 0xb3,
+       0xae, 0xae, 0xfd, 0xfb, 0x36, 0x83, 0x4f, 0xf8, 0x94, 0xf4, 0xce, 0xa5,
+       0xe4, 0xe1, 0x8e, 0xda, 0xf6, 0xbf, 0xea, 0xda, 0xad, 0xb2, 0xa6, 0x8d,
+       0x64, 0x38, 0xd6, 0x5e, 0xdb, 0xef, 0xf3, 0x93, 0xdf, 0xee, 0xc0, 0xfb,
+       0x42, 0x66, 0xac, 0xa4, 0xc6, 0x52, 0x37, 0xa3, 0x5c, 0xeb, 0xc3, 0xba,
+       0x67, 0x78, 0xcd, 0x67, 0xf8, 0x2c, 0xf3, 0x7a, 0xb7, 0xd9, 0x8f, 0x67,
+       0x98, 0x13, 0x60, 0x5e, 0x83, 0x3c, 0xbb, 0x5a, 0x9c, 0xc5, 0x31, 0x9f,
+       0xcd, 0x37, 0x64, 0x2a, 0xbc, 0xe7, 0xeb, 0x95, 0x58, 0x05, 0xab, 0xb6,
+       0xab, 0xe0, 0xe7, 0x84, 0x49, 0x3b, 0xad, 0x49, 0xc5, 0x6e, 0x80, 0xce,
+       0x87, 0x40, 0xe7, 0x07, 0x83, 0x8c, 0x0b, 0x9b, 0x3d, 0x5a, 0x3b, 0x32,
+       0x52, 0xfa, 0x0d, 0x64, 0x9c, 0x3c, 0x0a, 0x9f, 0xa2, 0x64, 0x79, 0xf8,
+       0x8c, 0x01, 0xd8, 0x34, 0x57, 0x82, 0x9a, 0x77, 0x40, 0x7c, 0x3f, 0x7f,
+       0x5d, 0x46, 0xa6, 0x98, 0x13, 0x20, 0x3f, 0x33, 0xae, 0x4f, 0xe1, 0xde,
+       0x2d, 0x8c, 0x75, 0x21, 0xc3, 0x63, 0xe0, 0xd7, 0x90, 0x38, 0xd3, 0xdb,
+       0x24, 0x37, 0x3e, 0xa6, 0x3e, 0x40, 0x37, 0x6c, 0xd4, 0x29, 0x77, 0x54,
+       0x26, 0xaf, 0x6c, 0x82, 0xac, 0x32, 0xee, 0xd7, 0x9c, 0x46, 0x39, 0xac,
+       0xbe, 0x39, 0x7d, 0x0e, 0xe6, 0xe1, 0x4c, 0x8d, 0xd9, 0xc8, 0xed, 0xa1,
+       0x98, 0xb4, 0x8e, 0xca, 0xcc, 0xac, 0xad, 0x78, 0x97, 0x94, 0xdc, 0x2e,
+       0x93, 0x76, 0xd9, 0x7d, 0x71, 0xe8, 0x2a, 0xfa, 0xf2, 0x3f, 0x88, 0x98,
+       0xb3, 0xdc, 0xbd, 0x81, 0x31, 0x71, 0x72, 0xba, 0x7a, 0x0e, 0xc5, 0xc8,
+       0xe0, 0xde, 0x2f, 0xdb, 0x8c, 0xcc, 0x30, 0x3e, 0xfe, 0xa0, 0x9c, 0x8a,
+       0x72, 0x4d, 0x8e, 0x65, 0xed, 0x96, 0x3c, 0xc2, 0xbd, 0xfd, 0xc7, 0xe3,
+       0xe5, 0x97, 0x31, 0x5f, 0x5c, 0xba, 0x5f, 0x1d, 0xd3, 0xb8, 0xfe, 0x54,
+       0x4d, 0x0c, 0x6b, 0xf2, 0x05, 0x26, 0x8e, 0xbd, 0x2e, 0x13, 0x8b, 0xa4,
+       0x0f, 0x6d, 0x7c, 0x40, 0x7e, 0xe1, 0xf4, 0xda, 0x4f, 0x68, 0xad, 0x31,
+       0x91, 0x62, 0x7d, 0xa6, 0xd9, 0x49, 0xda, 0xf3, 0x12, 0x1a, 0xfc, 0x1a,
+       0xae, 0x19, 0xd7, 0xe6, 0xdd, 0x5e, 0xf7, 0x09, 0xf1, 0x71, 0x20, 0x9b,
+       0x53, 0x8d, 0x81, 0x4f, 0xca, 0xd7, 0xf7, 0x71, 0x8c, 0xc1, 0x81, 0x48,
+       0x80, 0xb4, 0x7a, 0xef, 0x2e, 0xe2, 0x67, 0x6a, 0xf3, 0x7f, 0x0f, 0x1c,
+       0xdb, 0x3b, 0x90, 0x38, 0xc3, 0x18, 0x36, 0xec, 0x3c, 0xba, 0xc1, 0xbc,
+       0x6b, 0x2e, 0xb7, 0x4e, 0xb4, 0x7e, 0x76, 0xfc, 0x1f, 0x0e, 0xf1, 0x10,
+       0x89, 0x58, 0xa3, 0xc5, 0x3c, 0x38, 0x75, 0x1c, 0x6b, 0x2a, 0xcc, 0xb9,
+       0x11, 0xcb, 0xdf, 0x24, 0x97, 0xfb, 0x2c, 0x79, 0x20, 0x94, 0x8a, 0x5b,
+       0xb2, 0x25, 0x7e, 0x4e, 0xb0, 0x26, 0xeb, 0x2b, 0x8b, 0x89, 0x1c, 0xc7,
+       0x87, 0xa6, 0x39, 0x5f, 0x5c, 0xe3, 0x95, 0xe4, 0x96, 0x72, 0xf9, 0x29,
+       0x57, 0x02, 0xc9, 0x7b, 0x3e, 0x2c, 0xb3, 0x16, 0x6e, 0xbd, 0xfa, 0x79,
+       0x38, 0x05, 0xea, 0x0a, 0x7b, 0xc2, 0x60, 0x0e, 0x27, 0x8f, 0x77, 0x2f,
+       0xb2, 0xfd, 0xe4, 0x43, 0xa6, 0x7d, 0x06, 0xed, 0x06, 0x0f, 0xeb, 0x34,
+       0x75, 0xbc, 0xbb, 0x78, 0x6c, 0x83, 0x89, 0xbf, 0x97, 0x15, 0xff, 0xf5,
+       0x56, 0x4d, 0x4c, 0x93, 0x0a, 0x8c, 0x17, 0xc6, 0x02, 0x63, 0x05, 0xab,
+       0xaf, 0x09, 0xb4, 0x5a, 0x70, 0x99, 0xab, 0xf1, 0x73, 0x56, 0xcc, 0xf7,
+       0x8b, 0x3c, 0xa9, 0x18, 0x29, 0xd6, 0x14, 0x2d, 0xf5, 0x85, 0x0e, 0x2d,
+       0x30, 0xc7, 0x1f, 0x51, 0x7d, 0x70, 0x78, 0xb1, 0x55, 0xf2, 0xf6, 0x7a,
+       0xc9, 0xab, 0x8c, 0x47, 0x55, 0x07, 0x58, 0xce, 0x3d, 0xe8, 0xe3, 0xbe,
+       0x1f, 0x57, 0x5c, 0xc4, 0xeb, 0x85, 0x4e, 0xb4, 0x99, 0x6b, 0xde, 0x51,
+       0xd7, 0x5f, 0x5d, 0x97, 0x4d, 0xd8, 0x96, 0x55, 0x5f, 0x93, 0x65, 0x5f,
+       0x7d, 0x2d, 0xf6, 0xb4, 0x5c, 0x27, 0xdf, 0x94, 0xfc, 0x9c, 0xbb, 0xeb,
+       0xe5, 0xdc, 0x1f, 0xc3, 0x9c, 0x9c, 0x5b, 0x32, 0xa1, 0xa1, 0xa6, 0xbe,
+       0x53, 0x53, 0xc1, 0x5b, 0x2b, 0xf9, 0x53, 0xb4, 0x17, 0x2b, 0xb5, 0x72,
+       0xdc, 0x7b, 0x06, 0xbe, 0x48, 0x1e, 0x7e, 0x45, 0xce, 0xfb, 0xfe, 0x80,
+       0xf7, 0x2b, 0xcf, 0x7f, 0xc1, 0x9e, 0x9a, 0xb5, 0xce, 0x6e, 0xd5, 0xd4,
+       0xd9, 0xbf, 0x8d, 0x67, 0x59, 0x63, 0xcf, 0x95, 0x1b, 0xc0, 0xbb, 0x0d,
+       0xc4, 0x89, 0x54, 0xc6, 0x53, 0xc7, 0xab, 0x2e, 0xd7, 0xb9, 0x76, 0x79,
+       0x73, 0x05, 0xa1, 0xe7, 0x0f, 0x4e, 0xf9, 0x63, 0x4e, 0x4a, 0x63, 0x7f,
+       0x22, 0x16, 0xb4, 0x38, 0xc6, 0xe8, 0xfb, 0xb4, 0x7b, 0x12, 0x7a, 0x9c,
+       0x3a, 0x9f, 0xef, 0xed, 0xc0, 0xd7, 0xa3, 0x2e, 0xa0, 0x3e, 0x57, 0x1b,
+       0x10, 0xcf, 0x43, 0xd7, 0x8f, 0x94, 0x34, 0x97, 0x1f, 0xfb, 0x6a, 0x30,
+       0x31, 0x93, 0x55, 0xdd, 0x00, 0x7f, 0xaf, 0xf4, 0x26, 0xf3, 0x41, 0x67,
+       0x24, 0x50, 0x5d, 0xa7, 0x61, 0x6c, 0xc6, 0x9a, 0x46, 0x0b, 0x74, 0x83,
+       0xc8, 0x55, 0xf0, 0xc6, 0x6b, 0x0b, 0xe4, 0xd7, 0x60, 0xbb, 0x89, 0xaf,
+       0x96, 0x76, 0x58, 0xd2, 0xae, 0xb5, 0xcf, 0xbc, 0x13, 0xa1, 0x7f, 0x32,
+       0x9c, 0xec, 0x87, 0x9f, 0xad, 0xd8, 0x03, 0xe6, 0x2b, 0x0f, 0x22, 0x1e,
+       0xab, 0xce, 0xb1, 0x40, 0xbe, 0xc6, 0xd9, 0x9f, 0x85, 0x5f, 0xb9, 0x52,
+       0xf7, 0xc8, 0x17, 0x27, 0x35, 0xb7, 0x39, 0xb7, 0xd0, 0xa2, 0x3a, 0x76,
+       0xae, 0x38, 0x86, 0x73, 0x91, 0xad, 0xd6, 0x50, 0xde, 0xeb, 0x0f, 0x4b,
+       0xb1, 0xc8, 0xb6, 0x74, 0x35, 0xe8, 0xb9, 0xfb, 0xb5, 0x1d, 0x5b, 0xe6,
+       0xe1, 0x2b, 0x16, 0x17, 0x1d, 0xfc, 0xf7, 0xe0, 0xbf, 0x0f, 0xff, 0xbb,
+       0x25, 0x3d, 0x4d, 0xff, 0x95, 0xb5, 0x9c, 0x96, 0xba, 0xf5, 0xe9, 0x23,
+       0x75, 0x29, 0x0e, 0x2c, 0xef, 0xc5, 0x39, 0xf9, 0x62, 0xbd, 0x9c, 0x30,
+       0x4f, 0xea, 0xeb, 0x08, 0xe6, 0x4b, 0xfd, 0x5a, 0x5f, 0x75, 0x0d, 0xcb,
+       0xf2, 0xea, 0x5e, 0xe4, 0xe9, 0x66, 0x39, 0x5c, 0xf4, 0x6b, 0x57, 0x31,
+       0x39, 0x52, 0xa9, 0x5d, 0x49, 0x26, 0x38, 0xf4, 0xc9, 0x23, 0xd9, 0x29,
+       0xc5, 0x13, 0x58, 0xd6, 0xd0, 0xf5, 0x47, 0x26, 0x16, 0xdf, 0x7e, 0x64,
+       0x05, 0x13, 0x8e, 0x7b, 0x8b, 0xab, 0x61, 0x86, 0x88, 0xa5, 0xe3, 0xb7,
+       0x72, 0xea, 0xbb, 0x61, 0xdf, 0x7e, 0xcc, 0x43, 0x9c, 0x1d, 0xf4, 0x4c,
+       0xf3, 0x0a, 0x76, 0xd7, 0xc4, 0xa3, 0xc4, 0x91, 0xf2, 0xb9, 0x6a, 0xec,
+       0x47, 0x08, 0xe7, 0x2f, 0x01, 0xcb, 0xc9, 0x61, 0x1f, 0x3f, 0xed, 0x34,
+       0x7e, 0x20, 0x71, 0xa6, 0x89, 0x2a, 0xec, 0x91, 0x8f, 0x35, 0x7d, 0x09,
+       0x73, 0x65, 0xe4, 0x77, 0xa5, 0x47, 0xe5, 0x57, 0xa5, 0x31, 0xc8, 0xf7,
+       0x04, 0xe6, 0x3c, 0x20, 0x6f, 0x96, 0xf6, 0xc9, 0xb5, 0xd2, 0xb8, 0xbc,
+       0x51, 0xda, 0x8d, 0x98, 0x6a, 0x94, 0x58, 0x4f, 0x0f, 0x2b, 0x3d, 0x2c,
+       0x07, 0xcf, 0x2b, 0x06, 0xf0, 0x16, 0xfd, 0x9e, 0xe3, 0xea, 0x67, 0x13,
+       0x5f, 0x9f, 0xf8, 0x35, 0xe3, 0x79, 0x62, 0x33, 0x8b, 0x25, 0x1f, 0xc3,
+       0x71, 0xb4, 0x0b, 0x6b, 0xdb, 0xfc, 0x36, 0x65, 0xe4, 0x7c, 0x24, 0x30,
+       0x7a, 0x3e, 0x14, 0x78, 0x50, 0xbf, 0x73, 0x61, 0xbd, 0xb3, 0x2c, 0x93,
+       0xae, 0x43, 0xde, 0x1c, 0x1c, 0x81, 0x2c, 0x8c, 0x42, 0xd5, 0x3f, 0xe4,
+       0xac, 0x17, 0x90, 0x34, 0xf5, 0x11, 0xfc, 0xcc, 0xe4, 0x8b, 0xae, 0x64,
+       0x0b, 0xf3, 0x01, 0x83, 0x47, 0xb3, 0xd1, 0xee, 0x43, 0xfb, 0xe7, 0x5e,
+       0x7b, 0xa7, 0x64, 0x67, 0x25, 0xf5, 0xbe, 0xfa, 0xc3, 0x2f, 0x7b, 0x7d,
+       0x83, 0xe8, 0x03, 0x67, 0x5e, 0x64, 0xdf, 0x45, 0xaf, 0x8f, 0x67, 0xc2,
+       0x5a, 0x7d, 0x5c, 0xf9, 0x2a, 0x6b, 0x8f, 0x8b, 0x7e, 0xd7, 0xa0, 0xb5,
+       0xf8, 0x0f, 0x3a, 0x8d, 0x6e, 0x23, 0x26, 0xf0, 0x9f, 0x9d, 0x8c, 0xc1,
+       0x8a, 0x90, 0xaf, 0xbb, 0xa0, 0x13, 0xff, 0xba, 0x75, 0xa5, 0x6d, 0x0d,
+       0x7d, 0x5c, 0x85, 0xd1, 0xfe, 0x58, 0xba, 0x17, 0xff, 0xed, 0xe1, 0x79,
+       0x9f, 0xc0, 0xbb, 0xe1, 0xac, 0x0a, 0xc4, 0x8d, 0xc7, 0x21, 0xdb, 0x2d,
+       0xb2, 0xfe, 0x2c, 0xe9, 0xd5, 0x0b, 0x5d, 0x9d, 0x82, 0xdc, 0xba, 0xb2,
+       0x50, 0x0a, 0x05, 0x46, 0x0a, 0x29, 0x31, 0x78, 0x6a, 0x4b, 0x32, 0xd1,
+       0x94, 0x9c, 0x1e, 0x48, 0xf4, 0x30, 0x0f, 0x99, 0xed, 0x77, 0xe5, 0x52,
+       0x89, 0xf6, 0x38, 0x27, 0x97, 0x07, 0x12, 0x6e, 0x51, 0x88, 0x8b, 0x71,
+       0xe5, 0x32, 0x64, 0xf3, 0x9d, 0xf3, 0xbb, 0xe5, 0x48, 0x41, 0xfd, 0xe0,
+       0xde, 0xb0, 0xbc, 0x20, 0x97, 0x06, 0x5e, 0xb8, 0x75, 0xc9, 0x3d, 0x84,
+       0x33, 0x25, 0x1f, 0x1e, 0xee, 0x32, 0xfb, 0x56, 0x1c, 0x92, 0x30, 0x1f,
+       0xa2, 0x35, 0x35, 0xa7, 0x51, 0xd2, 0xfb, 0x23, 0x5e, 0x5c, 0x0e, 0x9f,
+       0x3b, 0x30, 0x60, 0xea, 0x29, 0x01, 0x7f, 0x9f, 0x61, 0xf8, 0x31, 0x7c,
+       0xce, 0xa7, 0x8d, 0x3f, 0x4f, 0x67, 0x20, 0x3d, 0xdb, 0x2a, 0xa1, 0x8b,
+       0xf7, 0x81, 0xae, 0x21, 0x39, 0xd4, 0x5f, 0x2e, 0x7f, 0xd3, 0x0d, 0xc5,
+       0x27, 0x10, 0xa3, 0x60, 0xff, 0xb2, 0xee, 0xc5, 0x36, 0xd0, 0xa4, 0x49,
+       0xa2, 0x2f, 0xfa, 0xeb, 0x35, 0x7a, 0x58, 0x86, 0x8b, 0xeb, 0x8c, 0x2d,
+       0xf3, 0xb1, 0x0d, 0xfe, 0x7c, 0x06, 0x53, 0xd6, 0x6d, 0xf5, 0x07, 0xbc,
+       0xef, 0x24, 0xbc, 0xf6, 0x3d, 0x81, 0x07, 0x42, 0xed, 0x12, 0x72, 0x9e,
+       0xdf, 0x48, 0x6c, 0xe4, 0x52, 0xc1, 0xef, 0x87, 0x9f, 0x18, 0xf2, 0xfd,
+       0x61, 0xd9, 0xbe, 0x72, 0xd6, 0xb2, 0xbd, 0x7b, 0xf1, 0x5b, 0xde, 0x9c,
+       0x29, 0x6f, 0x2c, 0x62, 0x8e, 0xd8, 0x5a, 0xb5, 0x4f, 0x66, 0xec, 0xa7,
+       0xf2, 0x74, 0x7f, 0xe2, 0x15, 0xc5, 0xc9, 0x56, 0x9e, 0xe1, 0x7d, 0xc4,
+       0x90, 0x25, 0x7d, 0x26, 0xb6, 0x07, 0xf4, 0xcd, 0xc4, 0xee, 0xb6, 0xe7,
+       0xad, 0x60, 0xc0, 0xf8, 0x23, 0x0d, 0xf2, 0xbd, 0x28, 0xec, 0x36, 0xbf,
+       0x61, 0x61, 0xfe, 0xcb, 0xbd, 0xed, 0xf9, 0x29, 0xec, 0x4b, 0x9c, 0x49,
+       0x5a, 0x13, 0xd8, 0x1f, 0xcf, 0x80, 0x18, 0x50, 0x0b, 0x74, 0xea, 0xc4,
+       0xfb, 0x21, 0x7e, 0xea, 0xf7, 0xdf, 0x7f, 0x1d, 0x74, 0x18, 0xf7, 0x6f,
+       0x70, 0x61, 0x62, 0x31, 0x17, 0x32, 0xec, 0x61, 0x60, 0xab, 0xe5, 0xd6,
+       0xc7, 0xc6, 0xfa, 0x78, 0x3a, 0x62, 0x94, 0x62, 0xf0, 0x03, 0x29, 0x13,
+       0xe4, 0xcd, 0x0e, 0xf4, 0xaf, 0xf9, 0x24, 0xa5, 0xaf, 0xee, 0xf7, 0x7d,
+       0x58, 0xc1, 0x76, 0x4f, 0x14, 0xf6, 0x19, 0x6c, 0x9e, 0xb5, 0x2c, 0xa9,
+       0xae, 0xa4, 0x3d, 0x89, 0xfd, 0xa6, 0x43, 0x89, 0x62, 0x4e, 0x62, 0x32,
+       0x0f, 0x7d, 0xf1, 0x1a, 0x64, 0xff, 0x5a, 0x29, 0x1e, 0x48, 0x63, 0x4f,
+       0x87, 0x0b, 0x43, 0x32, 0x31, 0xab, 0xdf, 0x7e, 0x41, 0xef, 0x0f, 0xc9,
+       0x5c, 0x21, 0xd1, 0x33, 0x0f, 0xfe, 0x9b, 0x2f, 0x10, 0x5f, 0xd4, 0x1b,
+       0x1f, 0xc5, 0x8c, 0x4b, 0x85, 0xcd, 0xb0, 0x0f, 0x92, 0xba, 0x04, 0xff,
+       0xe7, 0x52, 0xa9, 0x07, 0x7c, 0x86, 0xfb, 0x25, 0x07, 0xbf, 0xd0, 0x99,
+       0xa5, 0x01, 0xc8, 0x39, 0xf7, 0x62, 0xcb, 0xc2, 0x56, 0x9c, 0x1d, 0x71,
+       0x44, 0x8a, 0x1f, 0xff, 0x2f, 0xce, 0xd7, 0x7f, 0xef, 0x1d, 0x6a, 0xa7,
+       0xe7, 0x75, 0x5f, 0xb0, 0xcb, 0x88, 0x01, 0xb2, 0xfd, 0xc6, 0x6e, 0xa7,
+       0x23, 0x6d, 0x92, 0xbe, 0x9b, 0x76, 0xbc, 0x5d, 0x63, 0x44, 0xe5, 0xc5,
+       0x08, 0xef, 0xbf, 0xb3, 0xd1, 0xd0, 0x2f, 0x5c, 0xd7, 0xbe, 0x8e, 0xdf,
+       0x56, 0xe9, 0x70, 0xf8, 0x6b, 0xe3, 0xf7, 0xed, 0x8d, 0xac, 0xef, 0x76,
+       0x38, 0x49, 0xac, 0xf5, 0x5b, 0x2f, 0x5f, 0x80, 0xeb, 0x79, 0x3e, 0xb3,
+       0xc1, 0x5b, 0x97, 0xf3, 0xb6, 0x62, 0x9e, 0x16, 0x6f, 0xad, 0x56, 0xcd,
+       0x4f, 0x9a, 0xb5, 0x10, 0xe3, 0x16, 0xfe, 0xb2, 0x51, 0xbf, 0x35, 0x86,
+       0xbd, 0xa8, 0x6d, 0xff, 0x79, 0x23, 0x71, 0x73, 0x1d, 0x4e, 0xab, 0x62,
+       0x3c, 0x6f, 0xb6, 0xb7, 0xe3, 0x9a, 0x6b, 0x72, 0x8c, 0xc9, 0x87, 0xcf,
+       0x95, 0x38, 0x3f, 0xdb, 0x29, 0x39, 0xa1, 0xf9, 0x0c, 0x83, 0xe5, 0x9b,
+       0x2b, 0xdc, 0x2f, 0x13, 0xe7, 0x15, 0x5f, 0x37, 0x93, 0xb7, 0xf8, 0xdd,
+       0x0b, 0xbf, 0x97, 0xa3, 0x2f, 0x31, 0x26, 0x07, 0x71, 0x7e, 0x97, 0xe1,
+       0x53, 0x2d, 0x99, 0xef, 0x62, 0xf1, 0x77, 0x00, 0xe7, 0x12, 0x82, 0x8c,
+       0x51, 0x46, 0x29, 0x53, 0x38, 0xbf, 0x71, 0x5b, 0xde, 0x1d, 0xa0, 0x3c,
+       0x0f, 0xc8, 0x95, 0x8a, 0x3c, 0xe7, 0x20, 0xcf, 0x94, 0xe5, 0x1c, 0x64,
+       0xda, 0xf0, 0xf5, 0x7e, 0x7e, 0x67, 0x1d, 0x83, 0xbd, 0x52, 0x1f, 0xe2,
+       0x25, 0xf0, 0xb5, 0xed, 0x7d, 0x2b, 0x15, 0xd0, 0x1c, 0x4e, 0x76, 0xb6,
+       0xc1, 0xfb, 0x0e, 0x00, 0xd7, 0x57, 0x9e, 0x93, 0xf4, 0x6c, 0x33, 0xbf,
+       0xe7, 0xea, 0xe2, 0x99, 0x65, 0xaf, 0xf0, 0xdf, 0xe7, 0x45, 0xe2, 0x4d,
+       0xe9, 0xcf, 0xf2, 0x9a, 0x71, 0xde, 0x26, 0x8c, 0x19, 0x04, 0x9d, 0x9b,
+       0x31, 0x3f, 0xf7, 0xb8, 0xda, 0x38, 0xde, 0x0f, 0x55, 0xe1, 0x53, 0x7d,
+       0x7a, 0xaf, 0xd5, 0x35, 0xb3, 0xfd, 0xcd, 0xde, 0xfb, 0xf1, 0x1c, 0x94,
+       0xef, 0xc1, 0xb7, 0xf4, 0x89, 0xc9, 0x2f, 0x29, 0x3d, 0x87, 0xb9, 0x02,
+       0xf9, 0x37, 0xa4, 0x39, 0x8c, 0x2c, 0x6c, 0xcb, 0x5e, 0x1d, 0x1f, 0x5b,
+       0x91, 0xef, 0xae, 0x80, 0xc6, 0xdd, 0xd9, 0xc2, 0x1a, 0xe9, 0x56, 0x1d,
+       0xd4, 0xe5, 0xf1, 0x36, 0xec, 0x85, 0x62, 0xb9, 0x0f, 0xc8, 0xf1, 0xd2,
+       0x20, 0xe8, 0x10, 0x93, 0xa7, 0xe0, 0x37, 0x3f, 0x53, 0xba, 0x43, 0x96,
+       0x23, 0xd8, 0x57, 0x45, 0xc6, 0x86, 0xe5, 0xfb, 0xf3, 0x09, 0xef, 0x3a,
+       0xe1, 0x2e, 0x5b, 0x3b, 0xb0, 0x07, 0xca, 0x13, 0xe5, 0x8a, 0xe3, 0x82,
+       0x88, 0x45, 0x38, 0xef, 0xd3, 0x46, 0xb7, 0x61, 0xde, 0x62, 0x84, 0xf2,
+       0xcb, 0xbd, 0x85, 0x3c, 0x99, 0x65, 0x5c, 0xc5, 0x77, 0x36, 0x36, 0x29,
+       0x53, 0x73, 0x16, 0x09, 0xc5, 0x81, 0xae, 0x9c, 0x81, 0x3f, 0x8f, 0x2f,
+       0x97, 0xfe, 0x77, 0x14, 0xd4, 0xa3, 0xb0, 0x95, 0x05, 0xd8, 0xca, 0x02,
+       0x6c, 0x24, 0x64, 0xe1, 0x5a, 0x01, 0x36, 0xb2, 0x00, 0x1b, 0x09, 0x7d,
+       0xf6, 0x3a, 0x62, 0xbb, 0xd7, 0xc0, 0x43, 0xc6, 0xd7, 0x3e, 0x4a, 0x5f,
+       0x1b, 0x7f, 0xff, 0x03, 0x4c, 0x03, 0x3a, 0xe1, 0xd4, 0x71, 0x00, 0x00,
+       0x00 };
 
 static const u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
 static const u32 bnx2_RXP_b06FwRodata[(0x24/4) + 1] = {
-       0x08004580, 0x08004580, 0x080044f8, 0x08004530, 0x08004564, 0x08004588,
-       0x08004588, 0x08004588, 0x08004468, 0x00000000 };
+       0x08004590, 0x08004590, 0x08004508, 0x08004540, 0x08004574, 0x08004598,
+       0x08004598, 0x08004598, 0x08004478, 0x00000000 };
 
 static struct fw_info bnx2_rxp_fw_06 = {
-       /* Firmware version: 4.0.5 */
+       /* Firmware version: 4.1.1 */
        .ver_major                      = 0x4,
-       .ver_minor                      = 0x0,
-       .ver_fix                        = 0x5,
+       .ver_minor                      = 0x1,
+       .ver_fix                        = 0x1,
 
        .start_addr                     = 0x080031d0,
 
        .text_addr                      = 0x08000000,
-       .text_len                       = 0x71c0,
+       .text_len                       = 0x71d0,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_RXP_b06FwText,
        .gz_text_len                    = sizeof(bnx2_RXP_b06FwText),
@@ -2931,22 +2932,22 @@ static struct fw_info bnx2_rxp_fw_06 = {
        .data_index                     = 0x0,
        .data                           = bnx2_RXP_b06FwData,
 
-       .sbss_addr                      = 0x08007200,
+       .sbss_addr                      = 0x08007220,
        .sbss_len                       = 0x58,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x08007258,
+       .bss_addr                       = 0x08007278,
        .bss_len                        = 0x44c,
        .bss_index                      = 0x0,
 
-       .rodata_addr                    = 0x080071c0,
+       .rodata_addr                    = 0x080071d0,
        .rodata_len                     = 0x24,
        .rodata_index                   = 0x0,
        .rodata                         = bnx2_RXP_b06FwRodata,
 };
 
 static u8 bnx2_rv2p_proc1[] = {
-       /* Date:        12/07/2007 14:57 */
+       /* Date:        12/07/2007 15:02 */
        0xd5, 0x56, 0x41, 0x6b, 0x13, 0x51, 0x10, 0x9e, 0xdd, 0x6c, 0xbb, 0xdb,
        0x64, 0xb3, 0x59, 0xaa, 0xd6, 0x50, 0x53, 0x93, 0x06, 0x2f, 0xad, 0x29,
        0x6d, 0xaa, 0x82, 0x42, 0xa1, 0x92, 0x4b, 0xc1, 0xf6, 0x20, 0xf5, 0x22,
@@ -3032,7 +3033,7 @@ static u8 bnx2_rv2p_proc1[] = {
        0xa7, 0xd8, 0x0d, 0x00, 0x00, 0x00 };
 
 static u8 bnx2_rv2p_proc2[] = {
-       /* Date:        12/07/2007 14:57 */
+       /* Date:        12/07/2007 15:02 */
        0xed, 0x59, 0x5d, 0x6c, 0x54, 0xc7, 0x15, 0x9e, 0xbd, 0xbb, 0x7b, 0xf7,
        0x7a, 0x7d, 0xf7, 0xae, 0x71, 0xa8, 0xff, 0xf9, 0xb3, 0x09, 0xd8, 0xa9,
        0x21, 0xce, 0x9a, 0x98, 0x02, 0x55, 0x63, 0x39, 0x95, 0x81, 0xa6, 0x55,
index 13b222eb2f63efc064a896aa321e020354d5b56b..e6ffa2769f3d471d92d54cb67998a88d38aeedfa 100644 (file)
@@ -3173,250 +3173,250 @@ static struct fw_info bnx2_rxp_fw_09 = {
 };
 
 static u8 bnx2_xi_rv2p_proc1[] = {
-       /* Date:        12/07/2007 16:21 */
-       0xc5, 0x56, 0xcd, 0x6b, 0x13, 0x51, 0x10, 0x9f, 0xdd, 0xa4, 0xd9, 0x34,
-       0xd9, 0x64, 0x97, 0xaa, 0x25, 0xb4, 0x91, 0xa6, 0x55, 0x0f, 0x69, 0x23,
-       0xb6, 0xea, 0xc1, 0x43, 0xc1, 0xda, 0x8b, 0xa0, 0x9e, 0x7a, 0x10, 0xf1,
-       0xdb, 0x20, 0x05, 0xf1, 0x8f, 0x70, 0x51, 0xab, 0x20, 0x78, 0x28, 0x6a,
-       0xb0, 0x0a, 0xea, 0x49, 0x45, 0x3c, 0x34, 0x07, 0x41, 0x50, 0x14, 0x14,
-       0x3c, 0xe9, 0x4d, 0xf0, 0xe3, 0x50, 0x15, 0x3f, 0x0e, 0x7a, 0x13, 0x8f,
-       0xda, 0xf8, 0xde, 0xcc, 0xef, 0xd9, 0xdd, 0x4d, 0xd3, 0x14, 0x0f, 0xba,
-       0xd0, 0xfc, 0xfa, 0xde, 0x9b, 0x37, 0x6f, 0xe6, 0x37, 0xf3, 0x66, 0x9e,
-       0x4f, 0x44, 0x36, 0x05, 0xf5, 0x3e, 0x85, 0x94, 0xb5, 0x12, 0x69, 0x05,
-       0x16, 0xd1, 0x5d, 0x97, 0x31, 0xd8, 0x40, 0xf2, 0x0d, 0x09, 0x04, 0x43,
-       0xbe, 0xfa, 0xfd, 0x4e, 0x5b, 0x4b, 0x1a, 0x13, 0xb4, 0xb5, 0x5f, 0xe3,
-       0x36, 0x7a, 0x5c, 0x2a, 0x28, 0xfc, 0xd5, 0xa0, 0x40, 0x8f, 0xd7, 0xcc,
-       0xde, 0xaf, 0x67, 0x59, 0xef, 0x3b, 0xec, 0x7f, 0x9d, 0x10, 0xdc, 0x52,
-       0x49, 0x8b, 0x1e, 0x20, 0xad, 0xf7, 0x19, 0x5e, 0x4e, 0xeb, 0x71, 0xd1,
-       0x0a, 0xd6, 0xe3, 0x7c, 0x5b, 0xe6, 0xe7, 0xa6, 0x3d, 0x3d, 0x4f, 0xef,
-       0xc7, 0xf5, 0xd8, 0xcb, 0x9c, 0xae, 0xa7, 0x59, 0xaf, 0xac, 0x77, 0x65,
-       0x4e, 0xf3, 0x3e, 0xd7, 0x12, 0x7d, 0xea, 0x8f, 0xf7, 0x6f, 0x56, 0x7a,
-       0x60, 0x37, 0x89, 0x9e, 0x43, 0x25, 0x3d, 0x3f, 0x06, 0xb9, 0x51, 0xc8,
-       0x15, 0x9b, 0xe4, 0xe6, 0xa6, 0x35, 0x3a, 0x54, 0xad, 0x68, 0x7f, 0xfa,
-       0x95, 0xa1, 0xae, 0xf0, 0xd3, 0x27, 0xfe, 0x4e, 0xc2, 0xec, 0x77, 0x83,
-       0xfa, 0x1f, 0x65, 0xdb, 0xa0, 0x96, 0x9b, 0x53, 0x7e, 0x1b, 0x7f, 0x8d,
-       0xbc, 0xc8, 0x39, 0xac, 0xe7, 0xad, 0x5a, 0x37, 0x7e, 0x85, 0xfd, 0xc9,
-       0x86, 0xfc, 0x89, 0xf9, 0xd9, 0xe4, 0x57, 0x98, 0xa7, 0xf4, 0x22, 0x76,
-       0xeb, 0x73, 0x94, 0x0d, 0x7c, 0x4e, 0x0a, 0xfc, 0xa6, 0x62, 0xfb, 0x52,
-       0x2d, 0xf6, 0x7d, 0x6a, 0x2c, 0xf8, 0x69, 0xd6, 0xf5, 0xfc, 0xd3, 0x85,
-       0xf9, 0x72, 0x74, 0x5d, 0xfc, 0xef, 0x80, 0xff, 0x8f, 0xe0, 0xdf, 0x0e,
-       0x5a, 0x6b, 0x17, 0x78, 0x3d, 0xc9, 0xfb, 0x7b, 0x95, 0x3d, 0x1a, 0x57,
-       0x03, 0xfb, 0x81, 0x07, 0x81, 0x07, 0x80, 0xab, 0x80, 0x2b, 0x81, 0x2b,
-       0x80, 0x5d, 0xc0, 0xcb, 0x40, 0x1f, 0xe8, 0x01, 0xf3, 0xc0, 0x8b, 0x40,
-       0x17, 0x98, 0x05, 0xd6, 0x80, 0x57, 0x81, 0x69, 0xe0, 0x31, 0xe0, 0x23,
-       0xe0, 0x13, 0xe0, 0x37, 0xe0, 0x39, 0xa3, 0xcf, 0xc2, 0xb9, 0x40, 0x42,
-       0x3e, 0x58, 0x31, 0x9e, 0xae, 0x21, 0xef, 0x35, 0xcf, 0x58, 0x2f, 0x1b,
-       0x39, 0xc4, 0x97, 0x79, 0x9a, 0x81, 0x5c, 0xd7, 0xec, 0x8d, 0xd8, 0xfd,
-       0x28, 0xb5, 0xbd, 0x17, 0xf1, 0xb8, 0x79, 0xec, 0xcf, 0xe1, 0xed, 0x1e,
-       0x9f, 0x93, 0x4f, 0xc9, 0xbc, 0x31, 0x6b, 0x8f, 0x27, 0x78, 0x34, 0x23,
-       0xf8, 0x39, 0xd3, 0xa9, 0x7e, 0x1b, 0x8d, 0xc9, 0xac, 0x8c, 0x8f, 0xe4,
-       0x0c, 0xcf, 0x46, 0x8f, 0xb1, 0xa7, 0x9d, 0x1d, 0xad, 0xce, 0x33, 0x76,
-       0xb5, 0x3b, 0x57, 0xb0, 0x6a, 0x47, 0xfd, 0xbf, 0x32, 0x2c, 0x98, 0x1c,
-       0x61, 0xa8, 0xb8, 0xa9, 0xa4, 0xc6, 0xcd, 0xee, 0x33, 0x73, 0x8e, 0x46,
-       0xb7, 0x50, 0xe3, 0xfb, 0x92, 0xa4, 0x5a, 0x4a, 0xeb, 0xfd, 0xd9, 0x38,
-       0x2f, 0x72, 0x3d, 0x47, 0x5e, 0x30, 0x16, 0xae, 0x3c, 0x17, 0xf9, 0x57,
-       0x25, 0x97, 0x71, 0xf7, 0x10, 0xc5, 0x3e, 0xb3, 0x2e, 0xf7, 0x31, 0x60,
-       0xbb, 0x7f, 0x58, 0x41, 0xdd, 0x9c, 0x83, 0x7d, 0xc7, 0x4d, 0x1c, 0x7d,
-       0xb6, 0x73, 0x80, 0x64, 0x3c, 0x51, 0x96, 0xf5, 0x89, 0x32, 0xee, 0xf3,
-       0x40, 0x34, 0x1f, 0xe4, 0x5e, 0x24, 0x10, 0xef, 0x7d, 0xb8, 0x17, 0xf1,
-       0x7b, 0x9c, 0x9e, 0xbd, 0x31, 0x1d, 0xce, 0x97, 0x02, 0x55, 0x47, 0x60,
-       0x4f, 0x53, 0x9c, 0x4d, 0x3d, 0x36, 0xf9, 0xce, 0xd3, 0xb3, 0x41, 0x22,
-       0xc2, 0xdf, 0x18, 0x55, 0xc2, 0x71, 0xb2, 0x16, 0xc9, 0x97, 0x76, 0xe7,
-       0x44, 0xf4, 0xe5, 0x55, 0x04, 0xa8, 0x39, 0x8f, 0x1d, 0xf8, 0x35, 0x86,
-       0x3c, 0xee, 0x6d, 0xca, 0x63, 0x53, 0xe7, 0x25, 0x9f, 0x5b, 0xd5, 0xaf,
-       0xbf, 0xaf, 0xcf, 0x22, 0x17, 0x84, 0xf2, 0xd3, 0xd4, 0x43, 0xf0, 0xe4,
-       0xb0, 0x5c, 0x71, 0xee, 0x9e, 0xc4, 0x4d, 0xea, 0xb8, 0x4a, 0xc6, 0x20,
-       0x6a, 0xa7, 0x63, 0xfc, 0xeb, 0x0b, 0xd7, 0xc1, 0x75, 0x2d, 0xe2, 0x15,
-       0xae, 0xbb, 0x71, 0x5e, 0xa2, 0x79, 0x2f, 0xf1, 0xcf, 0x80, 0xa7, 0xde,
-       0x36, 0x75, 0xa1, 0x13, 0x72, 0xdd, 0x4b, 0xc8, 0x89, 0xde, 0xf1, 0x72,
-       0xb8, 0x8e, 0xf8, 0x0d, 0xd4, 0xc1, 0x3f, 0x71, 0x78, 0xd8, 0x22, 0x0e,
-       0xa3, 0xff, 0x37, 0x0e, 0xe8, 0xa7, 0xed, 0xe2, 0x40, 0xb1, 0x38, 0xfc,
-       0x98, 0x5f, 0x5e, 0x1c, 0x08, 0x3c, 0x51, 0x8b, 0x38, 0xa4, 0xc0, 0xd7,
-       0xd7, 0xf9, 0xa5, 0xe3, 0x90, 0x85, 0xdc, 0xe7, 0x90, 0x1c, 0xdb, 0x3d,
-       0x2a, 0xf7, 0xd4, 0xa9, 0x7e, 0x89, 0xf1, 0x3b, 0x52, 0xd1, 0xf5, 0xe7,
-       0x04, 0xd5, 0xe1, 0xff, 0x9b, 0x08, 0x0f, 0x39, 0x65, 0x9f, 0xbc, 0x23,
-       0x6e, 0xd7, 0x0d, 0x5f, 0xb2, 0x5c, 0xaa, 0x08, 0xde, 0x62, 0x79, 0x3f,
-       0xc4, 0x5b, 0x94, 0x5f, 0xe1, 0xcd, 0xa7, 0x9b, 0x7f, 0xea, 0x92, 0xc7,
-       0xfa, 0x86, 0x51, 0xd7, 0x0f, 0xa3, 0xbe, 0x7e, 0xc8, 0x48, 0xfd, 0xae,
-       0xee, 0xe4, 0x3a, 0x4b, 0xdd, 0xa8, 0xb3, 0xd5, 0x9c, 0x8c, 0x7b, 0x72,
-       0xf2, 0x6e, 0x19, 0x76, 0x5c, 0x96, 0xeb, 0xc9, 0x09, 0x76, 0x67, 0xf5,
-       0xbe, 0x02, 0x7d, 0xdc, 0xc5, 0xe2, 0x95, 0x19, 0x57, 0xea, 0xed, 0xcc,
-       0x73, 0xd4, 0x7f, 0xcf, 0xf0, 0x04, 0x7f, 0x37, 0xe9, 0xf9, 0x6e, 0x55,
-       0xef, 0xc2, 0xfc, 0x2a, 0x99, 0x41, 0xb1, 0xef, 0x3a, 0xac, 0x2f, 0x99,
-       0x7d, 0x7d, 0x9a, 0xcf, 0x07, 0xf3, 0xa6, 0xbf, 0x0c, 0x6c, 0xd7, 0xf6,
-       0x78, 0x94, 0x77, 0x24, 0x9e, 0x82, 0x4a, 0xce, 0x76, 0xf4, 0xb6, 0xe2,
-       0x94, 0x2d, 0xe3, 0xa9, 0x93, 0xac, 0x66, 0xd7, 0x94, 0x99, 0x1f, 0xe7,
-       0x44, 0x9e, 0xb8, 0xf3, 0x94, 0xe7, 0xf3, 0xf5, 0x84, 0xcc, 0x3b, 0x3b,
-       0x0d, 0x1f, 0x1e, 0xfb, 0x57, 0x13, 0x3e, 0xf6, 0x5f, 0x12, 0xdc, 0xab,
-       0x9e, 0x22, 0xfa, 0xcb, 0xd4, 0x5c, 0xe9, 0x3f, 0x33, 0x6e, 0x9a, 0x91,
-       0x98, 0x0f, 0x7b, 0xa3, 0xf4, 0x91, 0x0e, 0xd4, 0xff, 0xce, 0x50, 0x9c,
-       0xe2, 0x7d, 0x79, 0xb9, 0xf1, 0x0a, 0xf7, 0x0b, 0xd3, 0x47, 0xe2, 0x7d,
-       0x21, 0x87, 0x3c, 0xbb, 0xdc, 0x26, 0x1f, 0x4d, 0x9d, 0xbd, 0x80, 0x7b,
-       0xb0, 0x58, 0x3f, 0xd6, 0x98, 0x6f, 0xf1, 0x8e, 0x28, 0x22, 0xff, 0x4c,
-       0xdf, 0x5c, 0xec, 0xbd, 0x20, 0xf2, 0xcb, 0x7b, 0x27, 0xf8, 0x2d, 0xde,
-       0x09, 0xff, 0xec, 0x3d, 0x50, 0x58, 0x88, 0xa3, 0xc9, 0xd3, 0x70, 0x1c,
-       0xc3, 0xf9, 0x1a, 0xef, 0xd7, 0x4b, 0xf5, 0xe9, 0x3c, 0x78, 0x9e, 0x04,
-       0xcf, 0x49, 0xea, 0x48, 0x30, 0x31, 0x6e, 0xf2, 0x14, 0xeb, 0xb5, 0xa7,
-       0x6c, 0x16, 0x77, 0x3b, 0xce, 0x58, 0x1a, 0xf3, 0xee, 0x19, 0x91, 0x4b,
-       0xca, 0x7c, 0xc1, 0xe0, 0xd9, 0x53, 0xf2, 0x3e, 0xb4, 0xe9, 0x37, 0xf9,
-       0x0f, 0x65, 0x7b, 0x50, 0x0d, 0x00, 0x00, 0x00 };
+       /* Date:        01/14/2008 15:44 */
+       0xc5, 0x56, 0xcd, 0x6b, 0x13, 0x51, 0x10, 0x9f, 0xdd, 0x7c, 0x6c, 0x9a,
+       0x6c, 0xb2, 0xa1, 0x6a, 0x09, 0x35, 0xd2, 0x58, 0x7a, 0x30, 0x6d, 0xc4,
+       0x56, 0x3d, 0x78, 0x28, 0x54, 0x7a, 0x11, 0xac, 0xa7, 0x1e, 0x44, 0xc4,
+       0xcf, 0x20, 0x05, 0xf5, 0x8f, 0x70, 0x51, 0xab, 0x20, 0x78, 0x28, 0x68,
+       0xb4, 0x7e, 0xa0, 0x27, 0x15, 0xf1, 0x90, 0x1c, 0x04, 0x05, 0x45, 0x50,
+       0xf0, 0xa4, 0x37, 0x41, 0xbd, 0x54, 0xc5, 0x0f, 0xf0, 0xe2, 0x45, 0x8f,
+       0xda, 0xf8, 0xde, 0xcc, 0xef, 0xd9, 0xdd, 0x4d, 0xd2, 0x14, 0x0f, 0x1a,
+       0x68, 0x7f, 0xec, 0xdb, 0xdf, 0x9b, 0x37, 0xf3, 0x9b, 0x79, 0x33, 0x9b,
+       0x27, 0x22, 0x9b, 0xfc, 0xc6, 0x80, 0x42, 0x72, 0xad, 0x58, 0x4a, 0x81,
+       0x45, 0x74, 0xcf, 0x65, 0xf4, 0x37, 0x91, 0xfc, 0x46, 0x04, 0xfc, 0x91,
+       0xbc, 0xfa, 0xff, 0x9d, 0x26, 0x4a, 0x1a, 0x63, 0x34, 0xb1, 0x5e, 0xe3,
+       0x24, 0x3d, 0x29, 0x15, 0x14, 0xfe, 0x6a, 0x92, 0xaf, 0x9f, 0x87, 0xea,
+       0x0f, 0x1a, 0x19, 0xb6, 0xfb, 0x0e, 0xfb, 0xdf, 0xc4, 0x04, 0xb7, 0x55,
+       0x52, 0x62, 0x07, 0x48, 0x1b, 0xf3, 0x0c, 0xaf, 0xe6, 0xf4, 0x73, 0xd1,
+       0xf2, 0x37, 0xe2, 0x7c, 0x5b, 0xd6, 0x17, 0xe6, 0x3c, 0xbd, 0x4e, 0xef,
+       0x27, 0xf5, 0xb3, 0x97, 0x3e, 0xdd, 0x48, 0xb1, 0x5d, 0x79, 0xdf, 0x9b,
+       0x3e, 0xcd, 0xfb, 0x5c, 0x4b, 0xec, 0xa9, 0x3f, 0xde, 0xbf, 0x55, 0xd9,
+       0x81, 0xdf, 0x24, 0x76, 0x0e, 0x96, 0xf4, 0xfa, 0x76, 0xf0, 0xc6, 0xc1,
+       0x2b, 0xb6, 0xf0, 0x16, 0xe6, 0x34, 0x3a, 0x54, 0xad, 0xe8, 0x78, 0x06,
+       0x49, 0xe2, 0x49, 0xd0, 0x4c, 0xca, 0x15, 0x9d, 0x06, 0x84, 0xfd, 0x6e,
+       0x58, 0xef, 0x57, 0xbe, 0x0d, 0x6b, 0xde, 0x82, 0x8a, 0xdb, 0xc4, 0x1b,
+       0xe6, 0x39, 0x15, 0x63, 0x57, 0xf3, 0xde, 0x2a, 0x9e, 0x89, 0x2f, 0x18,
+       0x57, 0x26, 0x10, 0x57, 0x24, 0xde, 0x96, 0xf8, 0x82, 0x7a, 0xa5, 0xda,
+       0xf8, 0xaf, 0xcf, 0x51, 0xbe, 0xf0, 0x39, 0x49, 0xe8, 0x9c, 0x8c, 0xec,
+       0x4b, 0x76, 0x88, 0xfb, 0x93, 0x35, 0xb3, 0x21, 0xec, 0x3f, 0x91, 0xb6,
+       0xf7, 0x54, 0xf9, 0x8d, 0xf5, 0x72, 0x3b, 0x1d, 0x12, 0xd0, 0xe1, 0x31,
+       0xe2, 0x9b, 0xa2, 0x21, 0xbb, 0xc0, 0xef, 0xe3, 0xbc, 0x7f, 0xad, 0xf2,
+       0x47, 0xe3, 0x3a, 0xe0, 0x7a, 0xe0, 0x01, 0xe0, 0x7e, 0xe0, 0x1a, 0xe0,
+       0x6a, 0xe0, 0x2a, 0x60, 0x2f, 0xf0, 0x32, 0x30, 0x0f, 0xf4, 0x80, 0x39,
+       0xe0, 0x05, 0xa0, 0x0b, 0xcc, 0x00, 0x6b, 0xc0, 0xab, 0xc0, 0x14, 0xf0,
+       0x28, 0xf0, 0x21, 0xf0, 0x31, 0xf0, 0x0b, 0xf0, 0x1c, 0xd0, 0xb1, 0x60,
+       0x0f, 0xa8, 0x7e, 0x3e, 0xee, 0x47, 0x48, 0xa7, 0xeb, 0xa8, 0x7f, 0xad,
+       0x33, 0xde, 0x97, 0x0d, 0x0f, 0xf9, 0x65, 0x9d, 0x2e, 0x83, 0xd7, 0x5b,
+       0xbf, 0x19, 0xb9, 0x27, 0xa5, 0xae, 0xf7, 0x23, 0x9a, 0x37, 0x8f, 0xe3,
+       0x39, 0xb4, 0xc3, 0xe3, 0x73, 0x72, 0x49, 0x59, 0x37, 0x6e, 0xed, 0xf1,
+       0x04, 0x8f, 0xa4, 0x05, 0x3f, 0xa7, 0x7b, 0xd4, 0xff, 0x66, 0x73, 0x26,
+       0x23, 0xcf, 0x87, 0xb3, 0x46, 0x67, 0x63, 0xc7, 0xf8, 0xd3, 0xcd, 0x8f,
+       0x4e, 0xe7, 0x19, 0xbf, 0xba, 0x9d, 0x2b, 0x58, 0xb5, 0xc3, 0xf1, 0x5f,
+       0x19, 0x15, 0x8c, 0x8f, 0x31, 0x54, 0xdc, 0x64, 0x5c, 0xe3, 0x56, 0xf7,
+       0xb9, 0x39, 0x47, 0xa3, 0x5b, 0xa8, 0xf1, 0x7d, 0x89, 0x53, 0x2d, 0xa9,
+       0xed, 0xfe, 0x6c, 0x9e, 0x17, 0x5e, 0xff, 0xe1, 0x97, 0x8c, 0x85, 0x2b,
+       0x2f, 0x84, 0xff, 0xba, 0xe4, 0x32, 0xee, 0x1e, 0xa1, 0xc8, 0xcf, 0xbc,
+       0x97, 0xfb, 0xe8, 0xb3, 0xdf, 0x3f, 0x2c, 0xbf, 0x61, 0xce, 0xc1, 0xbe,
+       0xe3, 0x26, 0x8f, 0x79, 0xf6, 0x73, 0x90, 0xe4, 0x79, 0xba, 0x2c, 0xef,
+       0xa7, 0xcb, 0xb8, 0xcf, 0x83, 0xe1, 0x7a, 0x90, 0x7b, 0x11, 0x43, 0xbe,
+       0xf7, 0xe2, 0x5e, 0x44, 0xef, 0x71, 0xaa, 0x7e, 0x73, 0x2e, 0x58, 0x2f,
+       0x05, 0xaa, 0x8e, 0xc1, 0x9f, 0x96, 0x3c, 0x9b, 0xbe, 0x6c, 0xea, 0x9d,
+       0x97, 0xeb, 0x7e, 0x2c, 0xa4, 0xdf, 0x76, 0xaa, 0x04, 0xf3, 0x64, 0xb5,
+       0xa9, 0x97, 0x6e, 0xe7, 0x84, 0xec, 0xe5, 0x54, 0x06, 0xa8, 0xb5, 0x8e,
+       0x1d, 0xc4, 0x35, 0x81, 0x3a, 0x5e, 0xdb, 0x52, 0xc7, 0xa6, 0xdf, 0x4b,
+       0x3d, 0x77, 0xea, 0x5f, 0x7f, 0xdf, 0xa7, 0x85, 0xe7, 0x07, 0xea, 0xd3,
+       0xf4, 0x43, 0xe8, 0xe4, 0x30, 0xaf, 0xb8, 0x70, 0x5f, 0xf2, 0x26, 0xfd,
+       0x5c, 0x15, 0xa3, 0x1f, 0xf6, 0xd3, 0x31, 0xf1, 0x0d, 0x04, 0xfb, 0xe7,
+       0x50, 0x87, 0x7c, 0x05, 0xfb, 0x6e, 0x54, 0x97, 0x70, 0xdd, 0x4b, 0xfe,
+       0xd3, 0xd0, 0xa9, 0xbf, 0x4b, 0x5f, 0xe8, 0x01, 0x6f, 0xcd, 0x32, 0x3c,
+       0xb1, 0x3b, 0x59, 0x0e, 0xf6, 0x11, 0xaf, 0x89, 0xfe, 0x87, 0x7d, 0x7d,
+       0xf5, 0x47, 0x1d, 0xf2, 0x30, 0xfe, 0x7f, 0xf3, 0x80, 0xf9, 0x52, 0xb4,
+       0x24, 0x0f, 0x09, 0x5a, 0x99, 0xbe, 0x84, 0xf8, 0xa9, 0x83, 0xbe, 0x49,
+       0xe8, 0xf0, 0x6d, 0x71, 0x79, 0x7d, 0x33, 0xe0, 0x7d, 0x0d, 0xf0, 0xb8,
+       0x2e, 0xc6, 0xe5, 0xfe, 0x39, 0xd5, 0x2f, 0x11, 0xdd, 0xc6, 0x2a, 0xba,
+       0xaf, 0x9c, 0xa0, 0x06, 0xe2, 0x7a, 0x1b, 0x8a, 0x2f, 0xab, 0xfc, 0x93,
+       0xef, 0x84, 0x3b, 0x0d, 0xa3, 0x83, 0xbc, 0x2e, 0x55, 0x04, 0x6f, 0x33,
+       0x3f, 0x1f, 0xd0, 0x23, 0xac, 0x9b, 0xe8, 0x91, 0xa7, 0x5b, 0x7f, 0xfa,
+       0x8d, 0xc7, 0xf6, 0x46, 0xd1, 0xaf, 0x0f, 0xa1, 0x6f, 0x7e, 0x48, 0x4b,
+       0x5f, 0xae, 0x4e, 0x71, 0xff, 0xa4, 0x3e, 0xf4, 0xcf, 0x6a, 0x56, 0x9e,
+       0xfb, 0xb3, 0xf2, 0x1d, 0x36, 0xea, 0xb8, 0xcc, 0xeb, 0xcf, 0x0a, 0xf6,
+       0x65, 0xf4, 0xbe, 0x02, 0x7d, 0xdc, 0xc5, 0xf4, 0xca, 0xbc, 0x2b, 0x7d,
+       0x74, 0xfe, 0x05, 0xfa, 0xba, 0x67, 0x74, 0x42, 0xbc, 0x5b, 0xf4, 0x7a,
+       0x1f, 0x7f, 0xf2, 0x2c, 0xe9, 0xab, 0x38, 0xc3, 0xe2, 0xdf, 0x0d, 0x78,
+       0x5f, 0x32, 0xfb, 0x06, 0xb4, 0x9e, 0x4f, 0x16, 0xcd, 0xdc, 0x18, 0xdc,
+       0xa1, 0xfd, 0xf1, 0x28, 0xe7, 0x48, 0x3e, 0x05, 0x15, 0xcf, 0x76, 0xf4,
+       0xb6, 0xe2, 0xac, 0x2d, 0xcf, 0xb3, 0x27, 0xd9, 0xcc, 0xae, 0x59, 0xb3,
+       0x3e, 0xc9, 0x05, 0x3a, 0x7d, 0xf7, 0x19, 0xaf, 0xe7, 0x1a, 0x31, 0x59,
+       0x77, 0xa6, 0x8c, 0x1e, 0x1e, 0xc7, 0x57, 0x13, 0x3d, 0xf6, 0x5d, 0x14,
+       0xdc, 0x4b, 0x3b, 0x19, 0xd3, 0x35, 0x57, 0xe6, 0xca, 0xbc, 0x9b, 0x62,
+       0x24, 0xd6, 0xc3, 0xde, 0x2c, 0xf3, 0x21, 0x81, 0xbe, 0xde, 0x13, 0xc8,
+       0x53, 0x74, 0xde, 0xae, 0x34, 0x5f, 0xc1, 0x39, 0x60, 0xe6, 0x43, 0xb4,
+       0xdf, 0x67, 0x51, 0x67, 0xd7, 0xba, 0xd4, 0xa3, 0xe9, 0x9f, 0x97, 0x16,
+       0xe5, 0x1e, 0xb4, 0x9b, 0xb3, 0x1a, 0x73, 0x1d, 0xbe, 0x0f, 0x8a, 0xa8,
+       0x3f, 0x33, 0x0f, 0xdb, 0x7d, 0x07, 0x08, 0x7f, 0x65, 0xf3, 0x3f, 0xdf,
+       0x61, 0xfe, 0xff, 0xb3, 0x39, 0x5f, 0x58, 0xca, 0xa3, 0xa9, 0xd3, 0x60,
+       0x1e, 0x83, 0xf5, 0x1a, 0x9d, 0xc3, 0xcb, 0xcd, 0xdf, 0x1c, 0x74, 0x3e,
+       0x06, 0x9d, 0xe3, 0x94, 0x88, 0xb1, 0x30, 0x6e, 0xfc, 0x14, 0xdb, 0xb5,
+       0x67, 0x6d, 0xa6, 0xbb, 0x89, 0x33, 0x96, 0xc6, 0x9c, 0x7b, 0x46, 0x78,
+       0x71, 0x59, 0x2f, 0x18, 0x3c, 0x7b, 0x4a, 0xbe, 0xfb, 0x6c, 0xfa, 0x0d,
+       0x6d, 0x29, 0x98, 0xe1, 0x30, 0x0d, 0x00, 0x00, 0x00 };
 
 static u8 bnx2_xi_rv2p_proc2[] = {
-       /* Date:        12/07/2007 16:21 */
-       0xad, 0x58, 0x5d, 0x6c, 0xd3, 0x55, 0x14, 0xbf, 0xfd, 0x58, 0xdb, 0xb5,
+       /* Date:        01/14/2008 15:44 */
+       0xad, 0x58, 0x5d, 0x6c, 0xd3, 0x55, 0x14, 0xbf, 0xfd, 0x58, 0xdb, 0x75,
        0xff, 0xb6, 0x63, 0x9b, 0xdd, 0xa7, 0x6e, 0x6e, 0x61, 0x6c, 0xd8, 0xcd,
        0xd1, 0x8d, 0x4f, 0x4d, 0x5c, 0x86, 0x19, 0x20, 0x26, 0x8c, 0x61, 0xd4,
-       0x37, 0xd8, 0x90, 0xb2, 0xb1, 0x8d, 0x2c, 0x8c, 0xf0, 0xc0, 0x8b, 0x0d,
+       0x37, 0xd8, 0x90, 0xb2, 0xb2, 0x8d, 0x2c, 0x8c, 0xf0, 0xc0, 0x8b, 0x0d,
        0xd3, 0xf1, 0xd2, 0x07, 0x47, 0xb2, 0x0d, 0x8d, 0xc1, 0x45, 0x7d, 0x40,
-       0x9f, 0xec, 0x83, 0x32, 0x30, 0xc6, 0xc4, 0xe8, 0x42, 0xf0, 0x01, 0x48,
+       0x9f, 0xec, 0x83, 0x52, 0x30, 0xc6, 0xc4, 0xe8, 0x42, 0xf0, 0x01, 0x48,
        0x30, 0xc6, 0x68, 0x48, 0x08, 0xea, 0x32, 0x10, 0x75, 0x0c, 0xfb, 0x64,
-       0x98, 0xf7, 0x9e, 0xdf, 0xb9, 0xff, 0xfe, 0xff, 0x6d, 0x27, 0x18, 0xec,
+       0x98, 0xf7, 0x9e, 0xdf, 0xb9, 0xff, 0xfe, 0xff, 0x5d, 0x27, 0x18, 0xec,
        0x43, 0x4f, 0xef, 0xbd, 0xe7, 0x9e, 0x7b, 0x3e, 0x7e, 0xe7, 0x9c, 0x7b,
-       0x5b, 0x24, 0x84, 0x70, 0x8a, 0x44, 0xaa, 0x46, 0x52, 0x11, 0x70, 0xb8,
-       0x04, 0x3e, 0x6b, 0x8b, 0x88, 0x5c, 0x4b, 0xf9, 0xe4, 0x77, 0x81, 0x78,
-       0xc9, 0x59, 0x4e, 0x63, 0xb7, 0x50, 0x34, 0x2c, 0x44, 0xc2, 0x4a, 0x4b,
-       0x98, 0x5e, 0x65, 0xfa, 0x3b, 0xd3, 0xc7, 0x1d, 0xa0, 0x57, 0x78, 0xbc,
-       0x85, 0xc7, 0xd7, 0x78, 0xfc, 0x23, 0xd3, 0x8d, 0x3c, 0xbf, 0x99, 0x69,
-       0x92, 0xe9, 0x76, 0x5e, 0x9f, 0x65, 0x2a, 0x3f, 0x09, 0x43, 0x7e, 0xc9,
-       0xe5, 0x26, 0xad, 0xa7, 0x81, 0xe9, 0x26, 0xe8, 0xbb, 0xa7, 0x56, 0xf1,
-       0x2d, 0x2c, 0x67, 0xf8, 0x30, 0x7f, 0x7d, 0x02, 0xb4, 0x06, 0xbb, 0x3e,
-       0x4e, 0x3c, 0xad, 0xf7, 0x83, 0xf4, 0x06, 0x41, 0xfb, 0xd8, 0xfe, 0x8e,
-       0x28, 0x91, 0xe4, 0x7e, 0x27, 0xc6, 0x5d, 0x0d, 0xca, 0x0f, 0xc5, 0xc2,
-       0xed, 0x54, 0x72, 0x5a, 0x7c, 0x9e, 0xf3, 0x98, 0x7f, 0x35, 0x0c, 0xfa,
-       0x9a, 0x1f, 0xf4, 0x17, 0x7f, 0xa1, 0xfc, 0x5e, 0x5e, 0x8e, 0x07, 0x58,
-       0xbe, 0xc1, 0x6a, 0x07, 0xb0, 0x7f, 0xce, 0x80, 0x1e, 0x2f, 0xd7, 0x42,
+       0x5b, 0x2c, 0x84, 0x70, 0x8a, 0x44, 0xaa, 0x56, 0x52, 0x61, 0x38, 0x5c,
+       0x02, 0x9f, 0xb5, 0xc5, 0x44, 0xae, 0xa5, 0x7c, 0xf2, 0xbb, 0x40, 0xbc,
+       0xe4, 0xac, 0xa0, 0xb1, 0x5b, 0x28, 0x1a, 0x12, 0x22, 0x61, 0xa5, 0xa5,
+       0x4c, 0xaf, 0x32, 0xfd, 0x9d, 0xe9, 0xe3, 0x0e, 0xd0, 0x2b, 0x3c, 0xde,
+       0xc2, 0xe3, 0x6b, 0x3c, 0xfe, 0x91, 0xe9, 0x46, 0x9e, 0xdf, 0xcc, 0x34,
+       0xc9, 0x74, 0x3b, 0xaf, 0xa7, 0x99, 0xca, 0x4f, 0xc2, 0x90, 0x5f, 0x72,
+       0xb9, 0x59, 0xeb, 0x69, 0x60, 0xba, 0x19, 0xfa, 0xee, 0xa9, 0x53, 0x7c,
+       0xf3, 0x4b, 0x59, 0x3e, 0xcc, 0x5f, 0x9f, 0x00, 0xad, 0xc5, 0xae, 0x8f,
+       0x13, 0x4f, 0xeb, 0xfd, 0x20, 0x7d, 0x01, 0xd0, 0x7e, 0xb6, 0xbf, 0x33,
+       0x42, 0x24, 0xb9, 0xdf, 0x89, 0x71, 0x77, 0xa3, 0xf2, 0x43, 0x89, 0x70,
+       0x3b, 0x95, 0x9c, 0x56, 0x9f, 0xe7, 0x3c, 0xe6, 0x5f, 0x0d, 0x81, 0xbe,
+       0xe6, 0x07, 0xfd, 0xc5, 0x5f, 0x28, 0xbf, 0x97, 0x96, 0x62, 0x45, 0x2c,
+       0xdf, 0x60, 0xb5, 0x8b, 0xb0, 0x7f, 0xd6, 0x80, 0x1e, 0x2f, 0xd7, 0x41,
        0xbf, 0xef, 0x9f, 0x52, 0xf3, 0x2e, 0x91, 0x60, 0x39, 0x42, 0x68, 0x3d,
-       0x79, 0x7d, 0x10, 0xfb, 0x56, 0xad, 0xc1, 0xea, 0x5b, 0x71, 0x8c, 0xab,
-       0x3e, 0x28, 0xa2, 0xb8, 0x9c, 0x4e, 0x69, 0xfe, 0x7c, 0x72, 0xdd, 0x52,
-       0x2e, 0xe4, 0x8b, 0x3a, 0x1f, 0x29, 0x93, 0x88, 0x82, 0x8a, 0xe6, 0xec,
-       0x73, 0x20, 0x7f, 0x6a, 0xb5, 0x9a, 0x77, 0x8a, 0x1e, 0x97, 0x9a, 0xf7,
-       0x88, 0x9e, 0x01, 0xed, 0x5f, 0xac, 0xc7, 0x3d, 0x44, 0xca, 0x7b, 0xc7,
-       0x95, 0x9d, 0x61, 0xb1, 0xcf, 0x19, 0x26, 0x7e, 0xf8, 0xc5, 0xe5, 0x33,
-       0x3e, 0x03, 0xff, 0x97, 0x35, 0x06, 0xd9, 0x12, 0x6f, 0xc3, 0xbe, 0xd2,
-       0x18, 0xe8, 0x64, 0xac, 0x40, 0x91, 0x68, 0x7c, 0x94, 0x86, 0x2d, 0x37,
-       0xd7, 0xf9, 0x88, 0x2f, 0xd1, 0xac, 0xe3, 0xa7, 0xe3, 0xa5, 0xe2, 0xf8,
-       0x89, 0x8c, 0x23, 0xbb, 0xa5, 0x1e, 0x7e, 0xfd, 0x75, 0xb5, 0xe2, 0x97,
-       0xce, 0xad, 0xc3, 0x39, 0x19, 0xfd, 0xac, 0xf1, 0xff, 0xe8, 0x3f, 0xc4,
-       0x5f, 0xc9, 0xeb, 0x60, 0xbf, 0xd4, 0x4a, 0xbf, 0x28, 0x5a, 0xed, 0x48,
-       0x34, 0xdb, 0xe3, 0x71, 0x7d, 0x22, 0x4c, 0xbf, 0x6f, 0x75, 0x16, 0x91,
-       0x5f, 0x77, 0x61, 0xfe, 0x54, 0xd7, 0x39, 0xc4, 0x63, 0x07, 0xd9, 0x2f,
-       0xfc, 0x6f, 0x7c, 0x8a, 0x5d, 0xbd, 0x41, 0x35, 0x7e, 0xa5, 0x3d, 0x7e,
-       0x01, 0xeb, 0x05, 0x63, 0xf0, 0xeb, 0x2e, 0x96, 0xba, 0xc3, 0xe5, 0x50,
-       0x24, 0xe9, 0x19, 0xa3, 0xa1, 0x31, 0x47, 0xeb, 0x86, 0x38, 0x99, 0xc2,
-       0xfa, 0xe1, 0x80, 0x1a, 0xef, 0x8a, 0x2e, 0x60, 0x1c, 0x1d, 0x18, 0xe7,
-       0x8d, 0x4e, 0xf8, 0xe1, 0x96, 0x13, 0xf2, 0x18, 0x5e, 0x7e, 0x37, 0xc5,
-       0xc1, 0x21, 0x8c, 0x2e, 0xd0, 0x37, 0x69, 0xfd, 0x6f, 0x47, 0x92, 0xec,
-       0xee, 0x0a, 0xb9, 0xcf, 0x81, 0x91, 0x71, 0x6d, 0xe2, 0x56, 0xe3, 0xfe,
-       0x61, 0xf1, 0x3b, 0x6e, 0x68, 0xbc, 0xb2, 0xff, 0xd9, 0xbf, 0xef, 0x89,
-       0x6c, 0x9c, 0x82, 0x76, 0x35, 0x80, 0x7a, 0xea, 0xb3, 0xf1, 0xaa, 0xf1,
-       0x69, 0xf7, 0x33, 0xc7, 0xc7, 0x82, 0x17, 0x22, 0x12, 0x27, 0x36, 0xdc,
-       0x30, 0x4e, 0x2b, 0xa4, 0xbf, 0x74, 0xfc, 0x95, 0x20, 0xaf, 0x18, 0x64,
-       0x79, 0x03, 0x6c, 0xd7, 0x10, 0xdb, 0x75, 0xc7, 0xaf, 0xfd, 0xaa, 0xed,
-       0x01, 0x3d, 0x69, 0xb3, 0xc7, 0x21, 0xf1, 0x64, 0xc7, 0x21, 0xeb, 0x93,
-       0xfc, 0xa6, 0x0e, 0x3f, 0xaa, 0xea, 0x41, 0x4d, 0x3b, 0x1b, 0x14, 0x9f,
-       0x27, 0x36, 0x9d, 0xb2, 0xe3, 0x50, 0xe7, 0xe3, 0x9e, 0x5a, 0x2d, 0x5f,
-       0xe1, 0x32, 0x2d, 0x71, 0x89, 0xb8, 0x9d, 0x4e, 0x59, 0xf3, 0xb3, 0x32,
-       0x4f, 0x7e, 0xda, 0xf3, 0x42, 0xfb, 0xe5, 0x70, 0x90, 0x0a, 0x54, 0xfb,
-       0xe5, 0x79, 0xfb, 0x79, 0xc0, 0xb7, 0xd7, 0xc4, 0x4f, 0xe9, 0x06, 0xf6,
-       0x1f, 0xd3, 0xc8, 0x46, 0x25, 0xaf, 0x9b, 0xe5, 0xb7, 0xb2, 0x7c, 0xc3,
-       0x92, 0x77, 0x4a, 0xbf, 0x4e, 0x33, 0xdf, 0x74, 0xdc, 0x32, 0x79, 0xa7,
-       0xfd, 0x47, 0xe7, 0x47, 0x2f, 0xcf, 0xab, 0xfd, 0x55, 0x0f, 0xc8, 0xc3,
-       0x4d, 0xa6, 0xbc, 0xef, 0xcc, 0x7c, 0x53, 0xeb, 0x01, 0xf1, 0x1c, 0x0f,
-       0xed, 0xf5, 0xe4, 0x4f, 0x59, 0x4f, 0xc8, 0x0e, 0x9f, 0x71, 0x8e, 0xeb,
-       0xc7, 0xa8, 0x3a, 0xa7, 0x9c, 0xf5, 0x2e, 0x67, 0xbd, 0x65, 0xbf, 0x6a,
-       0xe6, 0x3a, 0xb3, 0xd7, 0x5a, 0x2f, 0xd6, 0x5a, 0xf2, 0x5e, 0x8d, 0x1b,
-       0x97, 0x73, 0xfb, 0x85, 0xcd, 0x9f, 0x09, 0x41, 0xfe, 0xf7, 0x72, 0x7c,
+       0x79, 0x7d, 0x10, 0xfb, 0x56, 0xad, 0xc1, 0xea, 0x5b, 0x31, 0x8c, 0xab,
+       0x3f, 0x28, 0xa6, 0xb8, 0x9c, 0x4e, 0x69, 0xfe, 0x7c, 0x72, 0xdd, 0x52,
+       0x2e, 0xe4, 0x8b, 0x7a, 0x1f, 0x29, 0x93, 0x88, 0x80, 0x8a, 0x96, 0xdc,
+       0x73, 0x20, 0x7f, 0x6a, 0xb5, 0x9a, 0x77, 0x8a, 0x5e, 0x97, 0x9a, 0xf7,
+       0x88, 0xde, 0xb8, 0xf6, 0x2f, 0xd6, 0x63, 0x1e, 0x22, 0x15, 0x7d, 0xe3,
+       0xca, 0xce, 0x90, 0xd8, 0xe7, 0x0c, 0x11, 0x3f, 0xfc, 0xe2, 0xf2, 0x19,
+       0x9f, 0x81, 0xff, 0xcb, 0x5a, 0x83, 0x6c, 0x89, 0xb5, 0x63, 0x5f, 0x59,
+       0x14, 0x74, 0x32, 0x5a, 0xa0, 0x48, 0x24, 0x36, 0x4a, 0xc3, 0xd6, 0x9b,
+       0xeb, 0x7c, 0xc4, 0x97, 0x68, 0xd1, 0xf1, 0xd3, 0xf1, 0x52, 0x71, 0xfc,
+       0x44, 0xc6, 0x91, 0xdd, 0xd2, 0x00, 0xbf, 0xfe, 0xba, 0x5a, 0xf1, 0x4b,
+       0xe7, 0xd6, 0xe3, 0x9c, 0xac, 0x7e, 0xd6, 0xf8, 0x7f, 0xf4, 0x1f, 0xe2,
+       0xaf, 0xe4, 0x75, 0xb2, 0x5f, 0xea, 0xa4, 0x5f, 0x14, 0xad, 0x71, 0x24,
+       0x5a, 0xec, 0xf1, 0xb8, 0x3e, 0x11, 0xa2, 0xdf, 0xb7, 0xba, 0x8a, 0xc9,
+       0xaf, 0xbb, 0x30, 0x7f, 0xaa, 0xfb, 0x1c, 0xe2, 0xb1, 0x83, 0xec, 0x17,
+       0xfe, 0x37, 0x3e, 0xc5, 0xae, 0xbe, 0x80, 0x1a, 0xbf, 0xd2, 0x11, 0xbb,
+       0x80, 0xf5, 0x82, 0x31, 0xf8, 0x75, 0x17, 0x4b, 0xdd, 0xe1, 0x72, 0x28,
+       0x92, 0xf4, 0x8c, 0xd1, 0xd0, 0x98, 0xa5, 0x75, 0x43, 0x9c, 0x4c, 0x61,
+       0xfd, 0x70, 0x91, 0x1a, 0xef, 0x8a, 0xcc, 0x63, 0x1c, 0x89, 0x8f, 0xf3,
+       0x46, 0x27, 0xfc, 0x70, 0xcb, 0x09, 0x79, 0x0c, 0x2f, 0xbf, 0x9b, 0xe2,
+       0xe0, 0x10, 0x46, 0x37, 0xe8, 0x9b, 0xb4, 0xfe, 0xb7, 0x23, 0x49, 0x76,
+       0x77, 0x07, 0xdd, 0xe7, 0xc0, 0xc8, 0xb8, 0x36, 0x71, 0xab, 0x71, 0xff,
+       0xb0, 0xf8, 0x1d, 0x37, 0x34, 0x5e, 0xd9, 0xff, 0xec, 0xdf, 0xf7, 0x44,
+       0x2e, 0x4e, 0x41, 0xbb, 0x1b, 0x41, 0x3d, 0x0d, 0xb9, 0x78, 0xd5, 0xf8,
+       0xb4, 0xfb, 0x99, 0xe3, 0x63, 0xc1, 0x0b, 0x11, 0x89, 0x13, 0x1b, 0x6e,
+       0x18, 0xa7, 0x95, 0xd2, 0x5f, 0x3a, 0xfe, 0x4a, 0x90, 0x57, 0x0c, 0xb2,
+       0xbc, 0x38, 0xdb, 0x35, 0xc4, 0x76, 0xdd, 0xf1, 0x6b, 0xbf, 0x6a, 0x7b,
+       0x40, 0x4f, 0xda, 0xec, 0x71, 0x48, 0x3c, 0xd9, 0x71, 0xc8, 0xfa, 0x24,
+       0xbf, 0xa9, 0xc7, 0x8f, 0xea, 0x06, 0x50, 0xd3, 0xce, 0x46, 0xc5, 0xe7,
+       0x89, 0x4e, 0xa7, 0xec, 0x38, 0xd4, 0xf9, 0xb8, 0xa7, 0x4e, 0xcb, 0x57,
+       0xb8, 0xcc, 0x48, 0x5c, 0x22, 0x6e, 0xa7, 0x53, 0xd6, 0xfc, 0xac, 0xca,
+       0x93, 0x9f, 0xf6, 0xbc, 0xd0, 0x7e, 0x39, 0x1c, 0xa0, 0x02, 0xd5, 0x71,
+       0x79, 0xce, 0x7e, 0x1e, 0xf0, 0xed, 0x35, 0xf1, 0x53, 0xb6, 0x81, 0xfd,
+       0xc7, 0x34, 0xbc, 0x51, 0xc9, 0xeb, 0x61, 0xf9, 0x6d, 0x2c, 0xdf, 0xb0,
+       0xe4, 0x9d, 0xd2, 0xaf, 0xcb, 0xcc, 0x37, 0x1d, 0xb7, 0x6c, 0xde, 0x69,
+       0xff, 0xd1, 0xf9, 0x91, 0xcb, 0x73, 0x6a, 0x7f, 0xf5, 0x03, 0xf2, 0x70,
+       0x93, 0x29, 0xef, 0x3b, 0x33, 0xdf, 0xd4, 0x7a, 0x91, 0x78, 0x8e, 0x87,
+       0xf6, 0x7a, 0xf2, 0xa7, 0xac, 0x27, 0x64, 0x87, 0xcf, 0x38, 0xc7, 0xf5,
+       0x63, 0x54, 0x9d, 0x53, 0xc1, 0x7a, 0x57, 0xb0, 0xde, 0xb2, 0x5f, 0xb5,
+       0x70, 0x9d, 0xd9, 0x6b, 0xad, 0x17, 0x6b, 0x2d, 0x79, 0xaf, 0xc6, 0x4d,
+       0x4b, 0xcb, 0xfb, 0x85, 0xcd, 0x9f, 0x09, 0x41, 0xfe, 0xf7, 0x72, 0x7c,
        0x3c, 0x79, 0xfa, 0x8b, 0xe6, 0x07, 0xbe, 0xb6, 0x11, 0xbf, 0xcf, 0xc4,
-       0xbf, 0xdd, 0xde, 0xca, 0x3c, 0x75, 0x27, 0xdb, 0x7e, 0xf8, 0xb3, 0xd7,
-       0x19, 0x24, 0xbe, 0x1b, 0x23, 0x6a, 0xdf, 0x49, 0x87, 0xf6, 0x53, 0x07,
-       0xea, 0x90, 0x03, 0xf6, 0x56, 0xb3, 0xbd, 0x72, 0xb9, 0x99, 0xf0, 0xef,
+       0xbf, 0xdd, 0xde, 0xaa, 0x3c, 0x75, 0x27, 0xd7, 0x7e, 0xf8, 0xb3, 0xcf,
+       0x19, 0x20, 0xbe, 0x1b, 0x23, 0x6a, 0xdf, 0x49, 0x87, 0xf6, 0x53, 0x27,
+       0xea, 0x90, 0x03, 0xf6, 0xd6, 0xb0, 0xbd, 0x72, 0xb9, 0x85, 0xf0, 0xef,
        0xbb, 0x31, 0x62, 0xb5, 0xd7, 0xf8, 0x97, 0xf3, 0xec, 0xb8, 0x19, 0xe1,
-       0x3e, 0xd6, 0x87, 0xbc, 0xf0, 0xed, 0xff, 0x5c, 0xeb, 0xc3, 0xe7, 0x86,
-       0xf5, 0xf9, 0x4a, 0x5e, 0x95, 0x98, 0x1f, 0x55, 0xfb, 0x1f, 0x13, 0x0c,
-       0x33, 0x31, 0xdc, 0x88, 0xfa, 0x77, 0xe7, 0x00, 0xf4, 0x1f, 0x6e, 0xd0,
+       0x3e, 0xd6, 0x8f, 0xbc, 0xf0, 0xed, 0xff, 0x5c, 0xeb, 0xc3, 0xe7, 0x86,
+       0xf4, 0xf9, 0x4a, 0x5e, 0xb5, 0x98, 0x1b, 0x55, 0xfb, 0x1f, 0x13, 0x0c,
+       0x33, 0x31, 0xdc, 0x84, 0xfa, 0x77, 0xe7, 0x00, 0xf4, 0x1f, 0x6e, 0xd4,
        0x7d, 0x1c, 0x38, 0x16, 0x5c, 0xff, 0xbf, 0x9e, 0xc8, 0xe7, 0x97, 0x41,
-       0x07, 0xf8, 0x4a, 0xd9, 0xae, 0x22, 0xb6, 0x2b, 0x2a, 0xb2, 0xeb, 0xec,
-       0x5e, 0xca, 0x97, 0x0e, 0xe6, 0x7b, 0x56, 0xd7, 0xe3, 0x1c, 0x3e, 0xd8,
-       0x5f, 0xc0, 0xe7, 0xe7, 0xf3, 0x57, 0x3e, 0xb9, 0xb3, 0x8c, 0xa3, 0x7e,
-       0xe6, 0x73, 0xe7, 0xa9, 0xf3, 0x18, 0xa5, 0xd7, 0x50, 0x9d, 0x3f, 0x73,
-       0x7c, 0x56, 0xf1, 0x05, 0x4d, 0x9c, 0xdb, 0xed, 0xfa, 0xe9, 0xfe, 0xa3,
-       0xfb, 0x5f, 0xf1, 0x45, 0xc4, 0xc1, 0xd0, 0x4a, 0x7e, 0x76, 0xab, 0xe9,
-       0x99, 0xc5, 0x59, 0x1d, 0x27, 0x83, 0xec, 0x9c, 0x1f, 0x55, 0xe7, 0x7f,
-       0x98, 0xe5, 0x7f, 0xa7, 0xc5, 0xff, 0xe0, 0x7f, 0x22, 0xfa, 0xa8, 0x7e,
-       0xcf, 0xd7, 0x97, 0xbf, 0xb8, 0x9f, 0x9b, 0x27, 0x6a, 0xfe, 0xc2, 0x43,
-       0xfb, 0x63, 0x77, 0x9b, 0xd5, 0xfe, 0x7a, 0x31, 0x97, 0x42, 0x7e, 0x75,
-       0x33, 0x0e, 0xf7, 0x71, 0xbd, 0xbe, 0xe1, 0x57, 0x13, 0x3e, 0xd1, 0xb7,
-       0x93, 0xfc, 0x21, 0x22, 0x01, 0xf8, 0xa7, 0xef, 0x45, 0xed, 0x4f, 0xcc,
-       0x57, 0x52, 0xbf, 0x75, 0x89, 0x6e, 0xaf, 0x41, 0xfc, 0x95, 0x41, 0xd0,
-       0x08, 0xd7, 0xf9, 0x39, 0xb3, 0x8f, 0x81, 0x9e, 0xf6, 0xe8, 0xba, 0x8c,
-       0x7e, 0xfe, 0x95, 0x47, 0x31, 0xc8, 0x20, 0x35, 0xa1, 0x3e, 0x77, 0x36,
-       0x18, 0xb4, 0xde, 0xd3, 0x04, 0x3c, 0x89, 0x3a, 0xdd, 0xe7, 0xf0, 0xe1,
-       0x3e, 0x50, 0x99, 0xe9, 0x77, 0xd6, 0x7e, 0x58, 0x68, 0xe9, 0x07, 0xfa,
+       0x07, 0xf8, 0xca, 0xd8, 0xae, 0x62, 0xb6, 0x2b, 0x22, 0x72, 0xeb, 0xec,
+       0x5e, 0xca, 0x97, 0x4e, 0xe6, 0x7b, 0x56, 0xd7, 0xe3, 0x65, 0x7c, 0xb0,
+       0xbf, 0x80, 0xcf, 0xcf, 0xe7, 0xaf, 0x7c, 0x72, 0xd3, 0x8c, 0xa3, 0x01,
+       0xe6, 0x73, 0xe7, 0xa9, 0xf3, 0x18, 0x65, 0xd6, 0x50, 0x9d, 0x3f, 0x73,
+       0x3c, 0xad, 0xf8, 0x02, 0x26, 0xce, 0xed, 0x76, 0xfd, 0x74, 0xff, 0xd1,
+       0xfd, 0xaf, 0xf8, 0xc2, 0xe2, 0x60, 0x70, 0x25, 0x3f, 0xbb, 0xd5, 0xf4,
+       0xcc, 0x42, 0x5a, 0xc7, 0xc9, 0x20, 0x3b, 0xe7, 0x46, 0xd5, 0xf9, 0x1f,
+       0xe6, 0xf8, 0xdf, 0x69, 0xf1, 0x3f, 0xf8, 0x9f, 0x88, 0x3c, 0xaa, 0xdf,
+       0xf3, 0xf5, 0xe5, 0x2f, 0xee, 0x2f, 0xcf, 0x13, 0x35, 0x7f, 0xe1, 0xa1,
+       0xfd, 0xb1, 0xbb, 0xdd, 0x6a, 0x7f, 0x83, 0x98, 0x4d, 0x21, 0xbf, 0x7a,
+       0x18, 0x87, 0xfb, 0xb8, 0x5e, 0xdf, 0xf0, 0xab, 0x09, 0x9f, 0xe8, 0xdf,
+       0x49, 0xfe, 0x10, 0xe1, 0x22, 0xf8, 0xa7, 0xff, 0x45, 0xed, 0x4f, 0xcc,
+       0x57, 0x51, 0xbf, 0x75, 0x89, 0x1e, 0xaf, 0x41, 0xfc, 0x55, 0x01, 0xd0,
+       0x30, 0xd7, 0xf9, 0x59, 0xb3, 0x8f, 0x81, 0x9e, 0xf6, 0xe8, 0xba, 0x8c,
+       0x7e, 0xfe, 0x95, 0x47, 0x31, 0xc8, 0x20, 0x35, 0xa3, 0x3e, 0x77, 0x35,
+       0x1a, 0xb4, 0xde, 0xdb, 0x0c, 0x3c, 0x89, 0x7a, 0xdd, 0xe7, 0xf0, 0xe1,
+       0x3e, 0x50, 0x95, 0xed, 0x77, 0xd6, 0x7e, 0x58, 0x68, 0xe9, 0x07, 0xfa,
        0x3c, 0xed, 0x47, 0x2d, 0x97, 0x86, 0xb2, 0xaf, 0x58, 0xfb, 0xa1, 0xee,
-       0x13, 0x4b, 0xdc, 0x27, 0x4a, 0xc4, 0xc5, 0x14, 0xec, 0x9a, 0x4b, 0x65,
-       0xe3, 0x4f, 0x9f, 0xa7, 0xe5, 0x41, 0x6f, 0x6d, 0x47, 0x46, 0x3e, 0xce,
-       0x3f, 0xc0, 0x7a, 0xfe, 0x4c, 0xf7, 0xd8, 0x08, 0xdb, 0xa3, 0xe4, 0x62,
-       0x7e, 0x3b, 0xf7, 0xe7, 0x84, 0x39, 0xb6, 0xf7, 0xd5, 0x6e, 0xd2, 0xab,
-       0x98, 0xf1, 0x16, 0xb1, 0xe4, 0x03, 0xf8, 0x4b, 0x5b, 0x41, 0x27, 0x5b,
-       0x75, 0x1c, 0x74, 0xbc, 0x74, 0x7c, 0x10, 0xc7, 0xc8, 0x3a, 0x62, 0x6b,
-       0xef, 0x5b, 0x47, 0x7d, 0xa4, 0xb5, 0x6f, 0x51, 0xe3, 0x0f, 0xfb, 0x77,
-       0x47, 0x15, 0xff, 0xeb, 0xe2, 0x2a, 0xe1, 0x50, 0x88, 0x1f, 0x98, 0x66,
-       0xfa, 0x15, 0x07, 0xc0, 0xcc, 0x57, 0x8e, 0x5f, 0x01, 0x4f, 0xb7, 0xe9,
-       0x7a, 0xae, 0xe3, 0x65, 0xcd, 0xd7, 0x78, 0x0e, 0x6e, 0x33, 0x75, 0x59,
-       0xdb, 0xa9, 0xf8, 0xa3, 0x8c, 0x47, 0x9f, 0xe8, 0xdc, 0x86, 0x7b, 0x6e,
-       0xc8, 0x8b, 0xba, 0x1f, 0xf2, 0x5a, 0xe3, 0x25, 0x71, 0x51, 0xe8, 0x55,
-       0xc3, 0xea, 0xe2, 0x42, 0xb2, 0xe7, 0xd4, 0xa5, 0x6f, 0x69, 0xf9, 0xfd,
-       0xe9, 0x00, 0xe6, 0xcb, 0x76, 0x86, 0xc9, 0x1f, 0x53, 0xc0, 0xf3, 0xbb,
-       0x93, 0xa0, 0xef, 0x88, 0x17, 0xb0, 0xbf, 0xf8, 0x04, 0xdd, 0x03, 0x7d,
-       0x65, 0x8c, 0xcf, 0x72, 0xd4, 0x89, 0xe4, 0x34, 0xdd, 0x4b, 0x96, 0x97,
-       0x45, 0x50, 0x51, 0x8f, 0xd9, 0x6f, 0x80, 0x4f, 0xb7, 0x25, 0xce, 0x0f,
-       0xc2, 0x2b, 0xdd, 0x2b, 0x25, 0x1e, 0xb1, 0x9d, 0x71, 0xeb, 0xcb, 0xc6,
-       0xad, 0xf6, 0x47, 0xb9, 0x33, 0x2f, 0x4e, 0x37, 0xd8, 0x71, 0xea, 0x61,
-       0x9c, 0xde, 0x33, 0xfb, 0x7b, 0xae, 0x5c, 0xf4, 0xf9, 0x8b, 0xff, 0x1b,
-       0x6e, 0x41, 0xb7, 0xd7, 0xab, 0xf3, 0xcb, 0x72, 0xea, 0x71, 0x8d, 0x2d,
-       0xce, 0x4d, 0xf7, 0xb5, 0x5e, 0x27, 0x3c, 0xd6, 0xf5, 0x66, 0xb3, 0x9f,
-       0x1d, 0xe1, 0x77, 0x5e, 0xda, 0xa0, 0x1f, 0xb1, 0x3b, 0x49, 0x1a, 0x1a,
-       0x15, 0x67, 0x15, 0x5f, 0x63, 0xec, 0x08, 0xd7, 0xdb, 0x4b, 0x2e, 0xd4,
-       0x9b, 0xfe, 0x03, 0x18, 0x5f, 0xe6, 0xfa, 0x71, 0x77, 0x0d, 0xd5, 0xe5,
-       0xd8, 0x91, 0xf3, 0x5a, 0x1e, 0xc9, 0x31, 0xd2, 0x5c, 0xd7, 0x9f, 0x77,
-       0x71, 0xbd, 0x25, 0xbf, 0xb9, 0x63, 0x7f, 0xd0, 0x7d, 0xc6, 0x2d, 0x3a,
-       0x9f, 0x54, 0xb4, 0x42, 0xd6, 0x6f, 0x3e, 0xff, 0x19, 0xd0, 0x1e, 0x2f,
-       0xa8, 0x68, 0xb2, 0xc7, 0x43, 0x98, 0x76, 0x61, 0xe4, 0xa9, 0x63, 0x39,
-       0xbd, 0x18, 0x7b, 0xf9, 0x5e, 0x36, 0xcd, 0x7e, 0x0a, 0x91, 0x3f, 0x8a,
-       0xa4, 0x9d, 0x8a, 0x86, 0x63, 0xa3, 0xb3, 0xd0, 0x7f, 0x68, 0x2b, 0xec,
-       0x5b, 0x62, 0xbb, 0x99, 0x86, 0xde, 0x1e, 0x23, 0xfc, 0x85, 0xc6, 0xf1,
-       0x0e, 0x09, 0x79, 0xc6, 0x60, 0xc7, 0x50, 0x1a, 0xe3, 0xa5, 0xcd, 0xa0,
-       0x7f, 0x6d, 0xc1, 0xbe, 0xa3, 0xc7, 0xd9, 0x1f, 0x5b, 0xf3, 0xef, 0xeb,
-       0xbf, 0x07, 0xbe, 0xe1, 0x46, 0x75, 0xfe, 0xe0, 0x0c, 0xbf, 0x5f, 0xc4,
-       0x80, 0x4b, 0x8d, 0x07, 0x8c, 0x34, 0x8f, 0x0f, 0x71, 0x7d, 0xbf, 0xcd,
-       0xef, 0x8d, 0xa1, 0xac, 0xf7, 0xc6, 0x02, 0xee, 0x99, 0x33, 0xe9, 0x24,
-       0x70, 0x91, 0x28, 0xcc, 0x7e, 0xaf, 0xaa, 0x71, 0x75, 0xac, 0x8c, 0xe3,
-       0x54, 0xba, 0x1e, 0x74, 0x72, 0x3d, 0xde, 0x09, 0x43, 0xc7, 0xd8, 0x2f,
-       0xed, 0x14, 0xa7, 0x96, 0xc5, 0xd9, 0x95, 0xde, 0xc9, 0xe0, 0x9b, 0xe2,
-       0x73, 0x23, 0xdc, 0x4f, 0x22, 0xc8, 0x3f, 0x51, 0x9e, 0xe4, 0x77, 0xcb,
-       0x04, 0xee, 0x9d, 0x53, 0x06, 0x68, 0x24, 0xa8, 0xf5, 0x45, 0x3e, 0x26,
-       0x52, 0xc8, 0x3b, 0xac, 0x3b, 0x2c, 0xeb, 0x7c, 0x1f, 0xc9, 0x79, 0xe7,
-       0x28, 0xba, 0xe4, 0x28, 0x71, 0x68, 0x3b, 0xb1, 0xda, 0x17, 0x54, 0xf8,
-       0xbd, 0x69, 0xe6, 0xd5, 0x02, 0xf9, 0xad, 0x6a, 0x26, 0x4d, 0xfa, 0x57,
-       0x8a, 0x12, 0xea, 0xc3, 0x15, 0xa1, 0x45, 0xf8, 0x31, 0x36, 0xcd, 0xfe,
-       0x1f, 0xd9, 0x04, 0x7a, 0x8c, 0xf1, 0xa7, 0x71, 0x75, 0x65, 0xa3, 0x41,
-       0xfb, 0xe6, 0x47, 0x71, 0x8e, 0xbe, 0x47, 0x64, 0xbf, 0xc7, 0x35, 0x1e,
-       0x2b, 0xda, 0x50, 0x48, 0xfb, 0x8f, 0xaa, 0x73, 0x82, 0x12, 0x47, 0x4a,
-       0x7f, 0xe9, 0x13, 0xce, 0x47, 0x3b, 0x4e, 0x15, 0x8e, 0x75, 0x7e, 0x58,
-       0xf1, 0x9d, 0x9d, 0xef, 0x19, 0xbc, 0x86, 0xe8, 0x5e, 0x2e, 0x8b, 0x5c,
-       0x82, 0xdf, 0x4d, 0x7c, 0x3f, 0x58, 0x29, 0x7e, 0x6f, 0x23, 0x7e, 0x31,
-       0xd6, 0xdb, 0x18, 0x18, 0x43, 0x5f, 0x1c, 0x67, 0x1c, 0x2d, 0x34, 0xf2,
-       0xfd, 0x87, 0xf5, 0xfb, 0x8d, 0xdf, 0x67, 0xc0, 0x9b, 0xd7, 0x88, 0xcf,
-       0x32, 0xbe, 0x18, 0xf7, 0x87, 0xd8, 0xee, 0xdb, 0xb0, 0xdb, 0xd0, 0x76,
-       0x0f, 0x98, 0x76, 0xeb, 0xfb, 0x95, 0x55, 0x4e, 0xb1, 0xc4, 0xad, 0xa2,
-       0xab, 0x8c, 0x2b, 0x54, 0xcf, 0x0a, 0xd8, 0x4e, 0xc9, 0xd7, 0xa6, 0xec,
-       0x09, 0xb1, 0x3d, 0x41, 0x71, 0xb0, 0xc5, 0xba, 0x2f, 0xc0, 0xfb, 0xfc,
-       0x72, 0x1f, 0xe6, 0x51, 0x17, 0x8c, 0x15, 0xfc, 0xa9, 0xfc, 0xa6, 0xe5,
-       0x66, 0xe7, 0xbd, 0xd5, 0x7f, 0x74, 0x23, 0xa5, 0x0f, 0xea, 0x9b, 0x8c,
-       0x53, 0x33, 0xfe, 0x3f, 0xd0, 0xf5, 0xed, 0x2e, 0xdd, 0x5f, 0xfd, 0x67,
-       0x86, 0x51, 0x9f, 0xce, 0x0c, 0x9f, 0xe5, 0x77, 0x07, 0xfb, 0xa5, 0x9b,
-       0xfe, 0xb7, 0x90, 0xb1, 0xab, 0xb3, 0xd7, 0x37, 0xbb, 0x1e, 0x55, 0x16,
-       0x3d, 0xf4, 0xb9, 0xff, 0x00, 0x0e, 0x4b, 0x7c, 0x26, 0x30, 0x14, 0x00,
+       0x13, 0x8b, 0xdc, 0x27, 0x4a, 0xc5, 0xc5, 0x14, 0xec, 0x9a, 0x4d, 0xe5,
+       0xe2, 0x4f, 0x9f, 0xa7, 0xe5, 0x41, 0x6f, 0x6d, 0x47, 0x56, 0x3e, 0xce,
+       0x3f, 0xc0, 0x7a, 0xfe, 0x4c, 0xf7, 0xd8, 0x30, 0xdb, 0xa3, 0xe4, 0x62,
+       0x7e, 0x3b, 0xf7, 0xe7, 0x84, 0x39, 0xb6, 0xf7, 0xd5, 0x1e, 0xd2, 0xab,
+       0x84, 0xf1, 0x16, 0xb6, 0xe4, 0x03, 0xf8, 0xcb, 0xda, 0x40, 0x27, 0xdb,
+       0x74, 0x1c, 0x74, 0xbc, 0x74, 0x7c, 0x10, 0xc7, 0xf0, 0x3a, 0x62, 0xeb,
+       0xe8, 0x5f, 0x47, 0x7d, 0xa4, 0xad, 0x7f, 0x41, 0xe3, 0x0f, 0xfb, 0x77,
+       0x47, 0x14, 0xff, 0xeb, 0xe2, 0x2a, 0xe1, 0x50, 0x88, 0x1f, 0x98, 0x66,
+       0xfb, 0x15, 0x07, 0xc0, 0xcc, 0x57, 0x8e, 0x5f, 0x01, 0x4f, 0xb7, 0xeb,
+       0x7a, 0xae, 0xe3, 0x65, 0xcd, 0xd7, 0xd8, 0x32, 0xdc, 0x66, 0xeb, 0xb2,
+       0xb6, 0x53, 0xf1, 0x47, 0x18, 0x8f, 0x3e, 0xd1, 0xb5, 0x0d, 0xf7, 0xdc,
+       0xa0, 0x17, 0x75, 0x3f, 0xe8, 0xb5, 0xc6, 0x4b, 0xe2, 0xa2, 0xd0, 0xab,
+       0x86, 0x35, 0x25, 0x85, 0x64, 0xcf, 0xa9, 0x4b, 0xdf, 0xd2, 0xf2, 0xfb,
+       0xd3, 0x45, 0x98, 0x2f, 0xdf, 0x19, 0x22, 0x7f, 0x4c, 0x01, 0xcf, 0xef,
+       0x4e, 0x82, 0xbe, 0x23, 0x5e, 0xc0, 0xfe, 0x92, 0x13, 0x74, 0x0f, 0xf4,
+       0x95, 0x33, 0x3e, 0x2b, 0x50, 0x27, 0x92, 0xd3, 0x74, 0x2f, 0x59, 0x5a,
+       0x12, 0x01, 0x45, 0x3d, 0x66, 0xbf, 0x01, 0x3e, 0xdd, 0x96, 0x38, 0x3f,
+       0x08, 0xaf, 0x74, 0xaf, 0x94, 0x78, 0xc4, 0x76, 0xc6, 0xad, 0x2f, 0x17,
+       0xb7, 0xda, 0x1f, 0x15, 0xce, 0xbc, 0x38, 0xdd, 0x60, 0xc7, 0xa9, 0x87,
+       0x71, 0x7a, 0xcf, 0xec, 0xef, 0xcb, 0xe5, 0xa2, 0xcf, 0x5f, 0xfc, 0xdf,
+       0x70, 0x0b, 0xba, 0xbd, 0x41, 0x9d, 0x5f, 0xbe, 0xac, 0x1e, 0xd7, 0xda,
+       0xe2, 0xdc, 0x7c, 0x5f, 0xeb, 0x75, 0xc2, 0x63, 0x5d, 0x6f, 0x31, 0xfb,
+       0xd9, 0x11, 0x7e, 0xe7, 0x65, 0x0c, 0xfa, 0x11, 0xbd, 0x93, 0xa4, 0xa1,
+       0x51, 0x79, 0x56, 0xf1, 0x35, 0x45, 0x8f, 0x70, 0xbd, 0xbd, 0xe4, 0x42,
+       0xbd, 0x19, 0x38, 0x80, 0xf1, 0x65, 0xae, 0x1f, 0x77, 0xd7, 0x50, 0x5d,
+       0x8e, 0x1e, 0x39, 0xaf, 0xe5, 0x91, 0x1c, 0x23, 0xc3, 0x75, 0xfd, 0x79,
+       0x17, 0xd7, 0x5b, 0xf2, 0x9b, 0x3b, 0xfa, 0x07, 0xdd, 0x67, 0xdc, 0xa2,
+       0xeb, 0x49, 0x45, 0x2b, 0x65, 0xfd, 0xe6, 0xf3, 0x9f, 0x01, 0xed, 0xf5,
+       0x82, 0x8a, 0x66, 0x7b, 0x3c, 0x84, 0x69, 0x17, 0x46, 0x9e, 0x7a, 0x96,
+       0xd3, 0x87, 0xb1, 0x97, 0xef, 0x65, 0xd3, 0xec, 0xa7, 0x20, 0xf9, 0xa3,
+       0x58, 0xda, 0xa9, 0x68, 0x28, 0x3a, 0x9a, 0x86, 0xfe, 0x43, 0x5b, 0x61,
+       0xdf, 0x22, 0xdb, 0xcd, 0x34, 0xf8, 0xf6, 0x18, 0xe1, 0x2f, 0x38, 0x8e,
+       0x77, 0x48, 0xd0, 0x33, 0x06, 0x3b, 0x86, 0x32, 0x18, 0x2f, 0x6e, 0x06,
+       0xfd, 0x6b, 0x0b, 0xf6, 0x1d, 0x3d, 0xce, 0xfe, 0xd8, 0x9a, 0x7f, 0xdf,
+       0xc0, 0x3d, 0xf0, 0x0d, 0x37, 0xa9, 0xf3, 0x07, 0x67, 0xf8, 0xfd, 0x22,
+       0xe2, 0x2e, 0x35, 0x8e, 0x1b, 0x19, 0x1e, 0x1f, 0xe2, 0xfa, 0x7e, 0x9b,
+       0xdf, 0x1b, 0x43, 0x39, 0xef, 0x8d, 0x79, 0xdc, 0x33, 0x67, 0x32, 0x49,
+       0xe0, 0x22, 0x51, 0x98, 0xfb, 0x5e, 0x55, 0xe3, 0x9a, 0x68, 0x39, 0xc7,
+       0xa9, 0x6c, 0x3d, 0xe8, 0xe4, 0x7a, 0xbc, 0x13, 0x86, 0x8e, 0xb1, 0x5f,
+       0x3a, 0x28, 0x4e, 0xad, 0x0b, 0xe9, 0x95, 0xde, 0xc9, 0xe0, 0x9b, 0xe2,
+       0x73, 0xc3, 0xdc, 0x4f, 0xc2, 0xc8, 0x3f, 0x51, 0x91, 0xe4, 0x77, 0xcb,
+       0x04, 0xee, 0x9d, 0x53, 0x06, 0x68, 0x38, 0xa0, 0xf5, 0x45, 0x3e, 0x26,
+       0x52, 0xc8, 0x3b, 0xac, 0x3b, 0x2c, 0xeb, 0x7c, 0x1f, 0x59, 0xf6, 0xce,
+       0x51, 0x74, 0xd1, 0x51, 0xea, 0xd0, 0x76, 0x62, 0xb5, 0x3f, 0xa0, 0xf0,
+       0x7b, 0xd3, 0xcc, 0xab, 0x79, 0xf2, 0x5b, 0xf5, 0x4c, 0x86, 0xf4, 0xaf,
+       0x12, 0xa5, 0xd4, 0x87, 0x2b, 0x83, 0x0b, 0xf0, 0x63, 0x74, 0x9a, 0xfd,
+       0x3f, 0xb2, 0x09, 0xf4, 0x18, 0xe3, 0x4f, 0xe3, 0xea, 0xca, 0x46, 0x83,
+       0xf6, 0xcd, 0x8d, 0xe2, 0x1c, 0x7d, 0x8f, 0xc8, 0x7d, 0x8f, 0x6b, 0x3c,
+       0x56, 0xb6, 0xa3, 0x90, 0x0e, 0x1c, 0x55, 0xe7, 0x04, 0x24, 0x8e, 0x94,
+       0xfe, 0xd2, 0x27, 0x9c, 0x8f, 0x76, 0x9c, 0x2a, 0x1c, 0xeb, 0xfc, 0xb0,
+       0xe2, 0x3b, 0x37, 0xdf, 0xb3, 0x78, 0x0d, 0xd2, 0xbd, 0x5c, 0x16, 0xb9,
+       0x04, 0xbf, 0x9b, 0xf8, 0x7e, 0xb0, 0x52, 0xfc, 0xde, 0x46, 0xfc, 0xa2,
+       0xac, 0xb7, 0x11, 0x1f, 0x43, 0x5f, 0x1c, 0x67, 0x1c, 0xcd, 0x37, 0xf1,
+       0xfd, 0x87, 0xf5, 0xfb, 0x8d, 0xdf, 0x67, 0xc0, 0x9b, 0xd7, 0x88, 0xa5,
+       0x19, 0x5f, 0x8c, 0xfb, 0x43, 0x6c, 0xf7, 0x6d, 0xd8, 0x6d, 0x68, 0xbb,
+       0xe3, 0xa6, 0xdd, 0xfa, 0x7e, 0x65, 0x95, 0x53, 0x22, 0x71, 0xab, 0xe8,
+       0x2a, 0xe3, 0x0a, 0xd5, 0xb3, 0x02, 0xb6, 0x53, 0xf2, 0xb5, 0x2b, 0x7b,
+       0x82, 0x6c, 0x4f, 0x40, 0x1c, 0x6c, 0xb5, 0xee, 0x2b, 0xe2, 0x7d, 0x7e,
+       0xb9, 0x0f, 0xf3, 0xa8, 0x0b, 0xc6, 0x0a, 0xfe, 0x54, 0x7e, 0xd3, 0x72,
+       0x73, 0xf3, 0xde, 0xea, 0x3f, 0xba, 0x91, 0xd2, 0x07, 0xf5, 0x4d, 0xc6,
+       0xa9, 0x05, 0xff, 0x1f, 0xe8, 0xfa, 0x76, 0x97, 0xee, 0xaf, 0xfe, 0x33,
+       0xc3, 0xa8, 0x4f, 0x67, 0x86, 0xcf, 0xf2, 0xbb, 0x83, 0xfd, 0xd2, 0x43,
+       0xff, 0x5b, 0xc8, 0xd8, 0xd5, 0xdb, 0xeb, 0x9b, 0x5d, 0x8f, 0x6a, 0x8b,
+       0x1e, 0xfa, 0xdc, 0x7f, 0x00, 0x5a, 0x33, 0xe6, 0xc0, 0x30, 0x14, 0x00,
        0x00, 0x00 };
 
 static u8 bnx2_TPAT_b09FwText[] = {
index d66c605b4075bc3650f2717af9dc4ea583754fa5..266ec8777ca81797f0dfd92b22875229644e5584 100644 (file)
@@ -388,8 +388,8 @@ enum _mii_mssr {
        MII_MSSR_CFG_RES = 0x4000,
        MII_MSSR_LOCAL_RCV_STATUS = 0x2000,
        MII_MSSR_REMOTE_RCVR = 0x1000,
-       MII_MSSR_LP_1000BT_HD = 0x0800,
-       MII_MSSR_LP_1000BT_FD = 0x0400,
+       MII_MSSR_LP_1000BT_FD = 0x0800,
+       MII_MSSR_LP_1000BT_HD = 0x0400,
        MII_MSSR_IDLE_ERR_COUNT = 0x00ff,
 };
 
index 6ef6b8b39e71dd5001d1f87c5bc3753ba045b790..f651a816b280bfcb04d1d6fdda8d12e2819b4ce5 100644 (file)
@@ -508,7 +508,7 @@ static int __init macvlan_init_module(void)
                goto err1;
        return 0;
 err1:
-       macvlan_handle_frame_hook = macvlan_handle_frame;
+       macvlan_handle_frame_hook = NULL;
        unregister_netdevice_notifier(&macvlan_notifier_block);
        return err;
 }
index 569028b2baf2d8930a21bca17b775c764f793c39..6f245cfb662419f3f173a65073d873f4195768db 100644 (file)
@@ -33,8 +33,7 @@
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/crc32.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
 
 #define DRIVER_VERSION "14-Jun-2006"
 static const char driver_name [] = "asix";
index a42acc3cc60983233b2a57d92512abcc9918fa60..a934428a5890ba26adf4df7e00588d57a08ef786 100644 (file)
@@ -31,8 +31,7 @@
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/cdc.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
 
 
 #if defined(CONFIG_USB_NET_RNDIS_HOST) || defined(CONFIG_USB_NET_RNDIS_HOST_MODULE)
@@ -228,15 +227,16 @@ next_desc:
                buf += buf [0];
        }
 
-       /* Microsoft ActiveSync based RNDIS devices lack the CDC descriptors,
-        * so we'll hard-wire the interfaces and not check for descriptors.
+       /* Microsoft ActiveSync based and some regular RNDIS devices lack the
+        * CDC descriptors, so we'll hard-wire the interfaces and not check
+        * for descriptors.
         */
-       if (is_activesync(&intf->cur_altsetting->desc) && !info->u) {
+       if (rndis && !info->u) {
                info->control = usb_ifnum_to_if(dev->udev, 0);
                info->data = usb_ifnum_to_if(dev->udev, 1);
                if (!info->control || !info->data) {
                        dev_dbg(&intf->dev,
-                               "activesync: master #0/%p slave #1/%p\n",
+                               "rndis: master #0/%p slave #1/%p\n",
                                info->control,
                                info->data);
                        goto bad_desc;
@@ -316,7 +316,6 @@ void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf)
 }
 EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
 
-\f
 /*-------------------------------------------------------------------------
  *
  * Communications Device Class, Ethernet Control model
index 943988ed01d8492f1787add1db757f4faf3af2a4..0ec7936cbe2139d3085d5388165f4b308c611b17 100644 (file)
@@ -26,8 +26,7 @@
 #include <linux/workqueue.h>
 #include <linux/mii.h>
 #include <linux/usb.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
 
 
 /*
index 633a511d6cb671151aa7c62e8bbf796f828f09d5..4b131a6c6b70bfcd7d169f9110c7b7fb2c343341 100644 (file)
@@ -20,8 +20,7 @@
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/crc32.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
 
 /* datasheet:
  http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-P01-930914.pdf
index 031cf5ca4dbb1eddb846665e4606f290eec863fc..f7ccfad9384e60024bccb27ce03a8391089a52a5 100644 (file)
@@ -29,8 +29,7 @@
 #include <linux/workqueue.h>
 #include <linux/mii.h>
 #include <linux/usb.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
 
 
 /*
index 5ea7411e13375812f13aa3cb6ccd3a81d50c47bb..c3d119f997f5d69e725b8c25346db8e9a6125989 100644 (file)
@@ -31,8 +31,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/usb.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
 
 /* requests */
 #define MCS7830_RD_BMREQ       (USB_DIR_IN  | USB_TYPE_VENDOR | \
index 19bf8dae70c9ddb3081fdec476b2757c4bc1000a..034e8a73ca6b487dc7ab32e02ba11d77d71ab72e 100644 (file)
 #include <linux/workqueue.h>
 #include <linux/mii.h>
 #include <linux/usb.h>
+#include <linux/usb/usbnet.h>
 
 #include <asm/unaligned.h>
 
-#include "usbnet.h"
-
 
 /*
  * Netchip 1080 driver ... http://www.netchip.com
index 45300939d185403e46bd7a73388c7c4e2e85398e..08555f8b15f41c7b86833a2ee7e3729ffdd3556f 100644 (file)
@@ -28,8 +28,7 @@
 #include <linux/workqueue.h>
 #include <linux/mii.h>
 #include <linux/usb.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
 
 
 /*
index 1ebe3259be0d1dd937c9807249b3d657e8ef15a6..a61324757b179b04d67673d26c2484580d5a8676 100644 (file)
@@ -29,8 +29,8 @@
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/cdc.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
+#include <linux/usb/rndis_host.h>
 
 
 /*
  * currently rare) "Ethernet Emulation Model" (EEM).
  */
 
-/*
- * CONTROL uses CDC "encapsulated commands" with funky notifications.
- *  - control-out:  SEND_ENCAPSULATED
- *  - interrupt-in:  RESPONSE_AVAILABLE
- *  - control-in:  GET_ENCAPSULATED
- *
- * We'll try to ignore the RESPONSE_AVAILABLE notifications.
- *
- * REVISIT some RNDIS implementations seem to have curious issues still
- * to be resolved.
- */
-struct rndis_msg_hdr {
-       __le32  msg_type;                       /* RNDIS_MSG_* */
-       __le32  msg_len;
-       // followed by data that varies between messages
-       __le32  request_id;
-       __le32  status;
-       // ... and more
-} __attribute__ ((packed));
-
-/* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */
-#define        CONTROL_BUFFER_SIZE             1025
-
-/* RNDIS defines an (absurdly huge) 10 second control timeout,
- * but ActiveSync seems to use a more usual 5 second timeout
- * (which matches the USB 2.0 spec).
- */
-#define        RNDIS_CONTROL_TIMEOUT_MS        (5 * 1000)
-
-
-#define ccpu2 __constant_cpu_to_le32
-
-#define RNDIS_MSG_COMPLETION   ccpu2(0x80000000)
-
-/* codes for "msg_type" field of rndis messages;
- * only the data channel uses packet messages (maybe batched);
- * everything else goes on the control channel.
- */
-#define RNDIS_MSG_PACKET       ccpu2(0x00000001)       /* 1-N packets */
-#define RNDIS_MSG_INIT         ccpu2(0x00000002)
-#define RNDIS_MSG_INIT_C       (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION)
-#define RNDIS_MSG_HALT         ccpu2(0x00000003)
-#define RNDIS_MSG_QUERY                ccpu2(0x00000004)
-#define RNDIS_MSG_QUERY_C      (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION)
-#define RNDIS_MSG_SET          ccpu2(0x00000005)
-#define RNDIS_MSG_SET_C                (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION)
-#define RNDIS_MSG_RESET                ccpu2(0x00000006)
-#define RNDIS_MSG_RESET_C      (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION)
-#define RNDIS_MSG_INDICATE     ccpu2(0x00000007)
-#define RNDIS_MSG_KEEPALIVE    ccpu2(0x00000008)
-#define RNDIS_MSG_KEEPALIVE_C  (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION)
-
-/* codes for "status" field of completion messages */
-#define        RNDIS_STATUS_SUCCESS            ccpu2(0x00000000)
-#define        RNDIS_STATUS_FAILURE            ccpu2(0xc0000001)
-#define        RNDIS_STATUS_INVALID_DATA       ccpu2(0xc0010015)
-#define        RNDIS_STATUS_NOT_SUPPORTED      ccpu2(0xc00000bb)
-#define        RNDIS_STATUS_MEDIA_CONNECT      ccpu2(0x4001000b)
-#define        RNDIS_STATUS_MEDIA_DISCONNECT   ccpu2(0x4001000c)
-
-
-struct rndis_data_hdr {
-       __le32  msg_type;               /* RNDIS_MSG_PACKET */
-       __le32  msg_len;                // rndis_data_hdr + data_len + pad
-       __le32  data_offset;            // 36 -- right after header
-       __le32  data_len;               // ... real packet size
-
-       __le32  oob_data_offset;        // zero
-       __le32  oob_data_len;           // zero
-       __le32  num_oob;                // zero
-       __le32  packet_data_offset;     // zero
-
-       __le32  packet_data_len;        // zero
-       __le32  vc_handle;              // zero
-       __le32  reserved;               // zero
-} __attribute__ ((packed));
-
-struct rndis_init {            /* OUT */
-       // header and:
-       __le32  msg_type;                       /* RNDIS_MSG_INIT */
-       __le32  msg_len;                        // 24
-       __le32  request_id;
-       __le32  major_version;                  // of rndis (1.0)
-       __le32  minor_version;
-       __le32  max_transfer_size;
-} __attribute__ ((packed));
-
-struct rndis_init_c {          /* IN */
-       // header and:
-       __le32  msg_type;                       /* RNDIS_MSG_INIT_C */
-       __le32  msg_len;
-       __le32  request_id;
-       __le32  status;
-       __le32  major_version;                  // of rndis (1.0)
-       __le32  minor_version;
-       __le32  device_flags;
-       __le32  medium;                         // zero == 802.3
-       __le32  max_packets_per_message;
-       __le32  max_transfer_size;
-       __le32  packet_alignment;               // max 7; (1<<n) bytes
-       __le32  af_list_offset;                 // zero
-       __le32  af_list_size;                   // zero
-} __attribute__ ((packed));
-
-struct rndis_halt {            /* OUT (no reply) */
-       // header and:
-       __le32  msg_type;                       /* RNDIS_MSG_HALT */
-       __le32  msg_len;
-       __le32  request_id;
-} __attribute__ ((packed));
-
-struct rndis_query {           /* OUT */
-       // header and:
-       __le32  msg_type;                       /* RNDIS_MSG_QUERY */
-       __le32  msg_len;
-       __le32  request_id;
-       __le32  oid;
-       __le32  len;
-       __le32  offset;
-/*?*/  __le32  handle;                         // zero
-} __attribute__ ((packed));
-
-struct rndis_query_c {         /* IN */
-       // header and:
-       __le32  msg_type;                       /* RNDIS_MSG_QUERY_C */
-       __le32  msg_len;
-       __le32  request_id;
-       __le32  status;
-       __le32  len;
-       __le32  offset;
-} __attribute__ ((packed));
-
-struct rndis_set {             /* OUT */
-       // header and:
-       __le32  msg_type;                       /* RNDIS_MSG_SET */
-       __le32  msg_len;
-       __le32  request_id;
-       __le32  oid;
-       __le32  len;
-       __le32  offset;
-/*?*/  __le32  handle;                         // zero
-} __attribute__ ((packed));
-
-struct rndis_set_c {           /* IN */
-       // header and:
-       __le32  msg_type;                       /* RNDIS_MSG_SET_C */
-       __le32  msg_len;
-       __le32  request_id;
-       __le32  status;
-} __attribute__ ((packed));
-
-struct rndis_reset {           /* IN */
-       // header and:
-       __le32  msg_type;                       /* RNDIS_MSG_RESET */
-       __le32  msg_len;
-       __le32  reserved;
-} __attribute__ ((packed));
-
-struct rndis_reset_c {         /* OUT */
-       // header and:
-       __le32  msg_type;                       /* RNDIS_MSG_RESET_C */
-       __le32  msg_len;
-       __le32  status;
-       __le32  addressing_lost;
-} __attribute__ ((packed));
-
-struct rndis_indicate {                /* IN (unrequested) */
-       // header and:
-       __le32  msg_type;                       /* RNDIS_MSG_INDICATE */
-       __le32  msg_len;
-       __le32  status;
-       __le32  length;
-       __le32  offset;
-/**/   __le32  diag_status;
-       __le32  error_offset;
-/**/   __le32  message;
-} __attribute__ ((packed));
-
-struct rndis_keepalive {       /* OUT (optionally IN) */
-       // header and:
-       __le32  msg_type;                       /* RNDIS_MSG_KEEPALIVE */
-       __le32  msg_len;
-       __le32  request_id;
-} __attribute__ ((packed));
-
-struct rndis_keepalive_c {     /* IN (optionally OUT) */
-       // header and:
-       __le32  msg_type;                       /* RNDIS_MSG_KEEPALIVE_C */
-       __le32  msg_len;
-       __le32  request_id;
-       __le32  status;
-} __attribute__ ((packed));
-
-/* NOTE:  about 30 OIDs are "mandatory" for peripherals to support ... and
- * there are gobs more that may optionally be supported.  We'll avoid as much
- * of that mess as possible.
- */
-#define OID_802_3_PERMANENT_ADDRESS    ccpu2(0x01010101)
-#define OID_GEN_MAXIMUM_FRAME_SIZE     ccpu2(0x00010106)
-#define OID_GEN_CURRENT_PACKET_FILTER  ccpu2(0x0001010e)
-
 /*
  * RNDIS notifications from device: command completion; "reverse"
  * keepalives; etc
  */
-static void rndis_status(struct usbnet *dev, struct urb *urb)
+void rndis_status(struct usbnet *dev, struct urb *urb)
 {
        devdbg(dev, "rndis status urb, len %d stat %d",
                urb->actual_length, urb->status);
        // FIXME for keepalives, respond immediately (asynchronously)
        // if not an RNDIS status, do like cdc_status(dev,urb) does
 }
+EXPORT_SYMBOL_GPL(rndis_status);
 
 /*
  * RPC done RNDIS-style.  Caller guarantees:
@@ -278,7 +78,7 @@ static void rndis_status(struct usbnet *dev, struct urb *urb)
  * Call context is likely probe(), before interface name is known,
  * which is why we won't try to use it in the diagnostics.
  */
-static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
+int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
 {
        struct cdc_state        *info = (void *) &dev->data;
        int                     master_ifnum;
@@ -347,10 +147,26 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
                                        request_id, xid);
                                /* then likely retry */
                        } else switch (buf->msg_type) {
-                       case RNDIS_MSG_INDICATE: {      /* fault */
-                               // struct rndis_indicate *msg = (void *)buf;
-                               dev_info(&info->control->dev,
-                                       "rndis fault indication\n");
+                       case RNDIS_MSG_INDICATE: {      /* fault/event */
+                               struct rndis_indicate *msg = (void *)buf;
+                               int state = 0;
+
+                               switch (msg->status) {
+                               case RNDIS_STATUS_MEDIA_CONNECT:
+                                       state = 1;
+                               case RNDIS_STATUS_MEDIA_DISCONNECT:
+                                       dev_info(&info->control->dev,
+                                               "rndis media %sconnect\n",
+                                               !state?"dis":"");
+                                       if (dev->driver_info->link_change)
+                                               dev->driver_info->link_change(
+                                                       dev, state);
+                                       break;
+                               default:
+                                       dev_info(&info->control->dev,
+                                               "rndis indication: 0x%08x\n",
+                                               le32_to_cpu(msg->status));
+                               }
                                }
                                break;
                        case RNDIS_MSG_KEEPALIVE: {     /* ping */
@@ -387,6 +203,7 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
        dev_dbg(&info->control->dev, "rndis response timeout\n");
        return -ETIMEDOUT;
 }
+EXPORT_SYMBOL_GPL(rndis_command);
 
 /*
  * rndis_query:
@@ -453,7 +270,8 @@ response_error:
        return -EDOM;
 }
 
-static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
+int
+generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
 {
        int                     retval;
        struct net_device       *net = dev->net;
@@ -467,8 +285,9 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
                struct rndis_query_c    *get_c;
                struct rndis_set        *set;
                struct rndis_set_c      *set_c;
+               struct rndis_halt       *halt;
        } u;
-       u32                     tmp;
+       u32                     tmp, *phym;
        int                     reply_len;
        unsigned char           *bp;
 
@@ -517,7 +336,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
                                "dev can't take %u byte packets (max %u)\n",
                                dev->hard_mtu, tmp);
                        retval = -EINVAL;
-                       goto fail_and_release;
+                       goto halt_fail_and_release;
                }
                dev->hard_mtu = tmp;
                net->mtu = dev->hard_mtu - net->hard_header_len;
@@ -533,13 +352,43 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
                dev->hard_mtu, tmp, dev->rx_urb_size,
                1 << le32_to_cpu(u.init_c->packet_alignment));
 
+       /* module has some device initialization code needs to be done right
+        * after RNDIS_INIT */
+       if (dev->driver_info->early_init &&
+                       dev->driver_info->early_init(dev) != 0)
+               goto halt_fail_and_release;
+
+       /* Check physical medium */
+       reply_len = sizeof *phym;
+       retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM,
+                       0, (void **) &phym, &reply_len);
+       if (retval != 0)
+               /* OID is optional so don't fail here. */
+               *phym = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED;
+       if ((flags & FLAG_RNDIS_PHYM_WIRELESS) &&
+                       *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
+               if (netif_msg_probe(dev))
+                       dev_dbg(&intf->dev, "driver requires wireless "
+                               "physical medium, but device is not.\n");
+               retval = -ENODEV;
+               goto halt_fail_and_release;
+       }
+       if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) &&
+                       *phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
+               if (netif_msg_probe(dev))
+                       dev_dbg(&intf->dev, "driver requires non-wireless "
+                               "physical medium, but device is wireless.\n");
+               retval = -ENODEV;
+               goto halt_fail_and_release;
+       }
+
        /* Get designated host ethernet address */
        reply_len = ETH_ALEN;
        retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS,
                        48, (void **) &bp, &reply_len);
        if (unlikely(retval< 0)) {
                dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval);
-               goto fail_and_release;
+               goto halt_fail_and_release;
        }
        memcpy(net->dev_addr, bp, ETH_ALEN);
 
@@ -550,12 +399,12 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
        u.set->oid = OID_GEN_CURRENT_PACKET_FILTER;
        u.set->len = ccpu2(4);
        u.set->offset = ccpu2((sizeof *u.set) - 8);
-       *(__le32 *)(u.buf + sizeof *u.set) = ccpu2(DEFAULT_FILTER);
+       *(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER;
 
        retval = rndis_command(dev, u.header);
        if (unlikely(retval < 0)) {
                dev_err(&intf->dev, "rndis set packet filter, %d\n", retval);
-               goto fail_and_release;
+               goto halt_fail_and_release;
        }
 
        retval = 0;
@@ -563,6 +412,11 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
        kfree(u.buf);
        return retval;
 
+halt_fail_and_release:
+       memset(u.halt, 0, sizeof *u.halt);
+       u.halt->msg_type = RNDIS_MSG_HALT;
+       u.halt->msg_len = ccpu2(sizeof *u.halt);
+       (void) rndis_command(dev, (void *)u.halt);
 fail_and_release:
        usb_set_intfdata(info->data, NULL);
        usb_driver_release_interface(driver_of(intf), info->data);
@@ -571,13 +425,19 @@ fail:
        kfree(u.buf);
        return retval;
 }
+EXPORT_SYMBOL_GPL(generic_rndis_bind);
+
+static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       return generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_NOT_WIRELESS);
+}
 
-static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
+void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
 {
        struct rndis_halt       *halt;
 
        /* try to clear any rndis state/activity (no i/o from stack!) */
-       halt = kzalloc(sizeof *halt, GFP_KERNEL);
+       halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
        if (halt) {
                halt->msg_type = RNDIS_MSG_HALT;
                halt->msg_len = ccpu2(sizeof *halt);
@@ -585,13 +445,14 @@ static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
                kfree(halt);
        }
 
-       return usbnet_cdc_unbind(dev, intf);
+       usbnet_cdc_unbind(dev, intf);
 }
+EXPORT_SYMBOL_GPL(rndis_unbind);
 
 /*
  * DATA -- host must not write zlps
  */
-static int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 {
        /* peripheral may have batched packets to us... */
        while (likely(skb->len)) {
@@ -633,8 +494,9 @@ static int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
        /* caller will usbnet_skb_return the remaining packet */
        return 1;
 }
+EXPORT_SYMBOL_GPL(rndis_rx_fixup);
 
-static struct sk_buff *
+struct sk_buff *
 rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
 {
        struct rndis_data_hdr   *hdr;
@@ -679,6 +541,7 @@ fill:
        /* FIXME make the last packet always be short ... */
        return skb;
 }
+EXPORT_SYMBOL_GPL(rndis_tx_fixup);
 
 
 static const struct driver_info        rndis_info = {
index 8ed1fc5cbc7025127ec289b494f433e6545f7ed3..8463efb9e0b119417b8199c78c53d6a0151ffe43 100644 (file)
@@ -41,8 +41,7 @@
 #include <linux/workqueue.h>
 #include <linux/mii.h>
 #include <linux/usb.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
 
 #define DRIVER_VERSION         "22-Aug-2005"
 
@@ -1204,6 +1203,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
                if ((dev->driver_info->flags & FLAG_ETHER) != 0
                                && (net->dev_addr [0] & 0x02) == 0)
                        strcpy (net->name, "eth%d");
+               /* WLAN devices should always be named "wlan%d" */
+               if ((dev->driver_info->flags & FLAG_WLAN) != 0)
+                       strcpy(net->name, "wlan%d");
 
                /* maybe the remote can't receive an Ethernet MTU */
                if (net->mtu > (dev->hard_mtu - net->hard_header_len))
diff --git a/drivers/net/usb/usbnet.h b/drivers/net/usb/usbnet.h
deleted file mode 100644 (file)
index 1fae434..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * USB Networking Link Interface
- *
- * Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net>
- * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef        __USBNET_H
-#define        __USBNET_H
-
-
-/* interface from usbnet core to each USB networking link we handle */
-struct usbnet {
-       /* housekeeping */
-       struct usb_device       *udev;
-       struct usb_interface    *intf;
-       struct driver_info      *driver_info;
-       const char              *driver_name;
-       wait_queue_head_t       *wait;
-       struct mutex            phy_mutex;
-       unsigned char           suspend_count;
-
-       /* i/o info: pipes etc */
-       unsigned                in, out;
-       struct usb_host_endpoint *status;
-       unsigned                maxpacket;
-       struct timer_list       delay;
-
-       /* protocol/interface state */
-       struct net_device       *net;
-       struct net_device_stats stats;
-       int                     msg_enable;
-       unsigned long           data [5];
-       u32                     xid;
-       u32                     hard_mtu;       /* count any extra framing */
-       size_t                  rx_urb_size;    /* size for rx urbs */
-       struct mii_if_info      mii;
-
-       /* various kinds of pending driver work */
-       struct sk_buff_head     rxq;
-       struct sk_buff_head     txq;
-       struct sk_buff_head     done;
-       struct urb              *interrupt;
-       struct tasklet_struct   bh;
-
-       struct work_struct      kevent;
-       unsigned long           flags;
-#              define EVENT_TX_HALT    0
-#              define EVENT_RX_HALT    1
-#              define EVENT_RX_MEMORY  2
-#              define EVENT_STS_SPLIT  3
-#              define EVENT_LINK_RESET 4
-};
-
-static inline struct usb_driver *driver_of(struct usb_interface *intf)
-{
-       return to_usb_driver(intf->dev.driver);
-}
-
-/* interface from the device/framing level "minidriver" to core */
-struct driver_info {
-       char            *description;
-
-       int             flags;
-/* framing is CDC Ethernet, not writing ZLPs (hw issues), or optionally: */
-#define FLAG_FRAMING_NC        0x0001          /* guard against device dropouts */
-#define FLAG_FRAMING_GL        0x0002          /* genelink batches packets */
-#define FLAG_FRAMING_Z 0x0004          /* zaurus adds a trailer */
-#define FLAG_FRAMING_RN        0x0008          /* RNDIS batches, plus huge header */
-
-#define FLAG_NO_SETINT 0x0010          /* device can't set_interface() */
-#define FLAG_ETHER     0x0020          /* maybe use "eth%d" names */
-
-#define FLAG_FRAMING_AX 0x0040         /* AX88772/178 packets */
-
-       /* init device ... can sleep, or cause probe() failure */
-       int     (*bind)(struct usbnet *, struct usb_interface *);
-
-       /* cleanup device ... can sleep, but can't fail */
-       void    (*unbind)(struct usbnet *, struct usb_interface *);
-
-       /* reset device ... can sleep */
-       int     (*reset)(struct usbnet *);
-
-       /* see if peer is connected ... can sleep */
-       int     (*check_connect)(struct usbnet *);
-
-       /* for status polling */
-       void    (*status)(struct usbnet *, struct urb *);
-
-       /* link reset handling, called from defer_kevent */
-       int     (*link_reset)(struct usbnet *);
-
-       /* fixup rx packet (strip framing) */
-       int     (*rx_fixup)(struct usbnet *dev, struct sk_buff *skb);
-
-       /* fixup tx packet (add framing) */
-       struct sk_buff  *(*tx_fixup)(struct usbnet *dev,
-                               struct sk_buff *skb, gfp_t flags);
-
-       /* for new devices, use the descriptor-reading code instead */
-       int             in;             /* rx endpoint */
-       int             out;            /* tx endpoint */
-
-       unsigned long   data;           /* Misc driver specific data */
-};
-
-/* Minidrivers are just drivers using the "usbnet" core as a powerful
- * network-specific subroutine library ... that happens to do pretty
- * much everything except custom framing and chip-specific stuff.
- */
-extern int usbnet_probe(struct usb_interface *, const struct usb_device_id *);
-extern int usbnet_suspend (struct usb_interface *, pm_message_t );
-extern int usbnet_resume (struct usb_interface *);
-extern void usbnet_disconnect(struct usb_interface *);
-
-
-/* Drivers that reuse some of the standard USB CDC infrastructure
- * (notably, using multiple interfaces according to the CDC
- * union descriptor) get some helper code.
- */
-struct cdc_state {
-       struct usb_cdc_header_desc      *header;
-       struct usb_cdc_union_desc       *u;
-       struct usb_cdc_ether_desc       *ether;
-       struct usb_interface            *control;
-       struct usb_interface            *data;
-};
-
-extern int usbnet_generic_cdc_bind (struct usbnet *, struct usb_interface *);
-extern void usbnet_cdc_unbind (struct usbnet *, struct usb_interface *);
-
-/* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
-#define        DEFAULT_FILTER  (USB_CDC_PACKET_TYPE_BROADCAST \
-                       |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
-                       |USB_CDC_PACKET_TYPE_PROMISCUOUS \
-                       |USB_CDC_PACKET_TYPE_DIRECTED)
-
-
-/* we record the state for each of our queued skbs */
-enum skb_state {
-       illegal = 0,
-       tx_start, tx_done,
-       rx_start, rx_done, rx_cleanup
-};
-
-struct skb_data {      /* skb->cb is one of these */
-       struct urb              *urb;
-       struct usbnet           *dev;
-       enum skb_state          state;
-       size_t                  length;
-};
-
-
-extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *);
-extern void usbnet_defer_kevent (struct usbnet *, int);
-extern void usbnet_skb_return (struct usbnet *, struct sk_buff *);
-extern void usbnet_unlink_rx_urbs(struct usbnet *);
-
-extern int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd);
-extern int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd);
-extern u32 usbnet_get_link (struct net_device *net);
-extern u32 usbnet_get_msglevel (struct net_device *);
-extern void usbnet_set_msglevel (struct net_device *, u32);
-extern void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);
-extern int usbnet_nway_reset(struct net_device *net);
-
-/* messaging support includes the interface name, so it must not be
- * used before it has one ... notably, in minidriver bind() calls.
- */
-#ifdef DEBUG
-#define devdbg(usbnet, fmt, arg...) \
-       printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
-#else
-#define devdbg(usbnet, fmt, arg...) do {} while(0)
-#endif
-
-#define deverr(usbnet, fmt, arg...) \
-       printk(KERN_ERR "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
-#define devwarn(usbnet, fmt, arg...) \
-       printk(KERN_WARNING "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
-
-#define devinfo(usbnet, fmt, arg...) \
-       printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net->name , ## arg); \
-
-
-#endif /* __USBNET_H */
index 9f98e8ce487ab389694353ae31de484537087cad..e24f7b3ace4bd470fcfbf65dffc69bf2df20f383 100644 (file)
@@ -29,8 +29,7 @@
 #include <linux/crc32.h>
 #include <linux/usb.h>
 #include <linux/usb/cdc.h>
-
-#include "usbnet.h"
+#include <linux/usb/usbnet.h>
 
 
 /*
index f372960904b21a6d7364a8e5e70785878290341e..714a6ca30ad2abe7314768f1ab9031da6b4b04c6 100644 (file)
@@ -545,6 +545,34 @@ config USB_ZD1201
          To compile this driver as a module, choose M here: the
          module will be called zd1201.
 
+config USB_NET_RNDIS_WLAN
+       tristate "Wireless RNDIS USB support"
+       depends on USB && WLAN_80211 && EXPERIMENTAL
+       select USB_USBNET
+       select USB_NET_CDCETHER
+       select USB_NET_RNDIS_HOST
+       select WIRELESS_EXT
+       ---help---
+         This is a driver for wireless RNDIS devices.
+         These are USB based adapters found in devices such as:
+
+         Buffalo WLI-U2-KG125S
+         U.S. Robotics USR5421
+         Belkin F5D7051
+         Linksys WUSB54GSv2
+         Linksys WUSB54GSC
+         Asus WL169gE
+         Eminent EM4045
+         BT Voyager 1055
+         Linksys WUSB54GSv1
+         U.S. Robotics USR5420
+         BUFFALO WLI-USB-G54
+
+         All of these devices are based on Broadcom 4320 chip which is the
+         only wireless RNDIS chip known to date.
+
+         If you choose to build a module, it'll be called rndis_wlan.
+
 config RTL8180
        tristate "Realtek 8180/8185 PCI support"
        depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
index 6af7b158624ec07797998e93e2ce25653e6aad64..091dfe2e574e7104e52d4e7f15fdedca86b722f1 100644 (file)
@@ -44,6 +44,8 @@ obj-$(CONFIG_ZD1211RW)                += zd1211rw/
 obj-$(CONFIG_PCMCIA_RAYCS)     += ray_cs.o
 obj-$(CONFIG_PCMCIA_WL3501)    += wl3501_cs.o
 
+obj-$(CONFIG_USB_NET_RNDIS_WLAN)       += rndis_wlan.o
+
 obj-$(CONFIG_USB_ZD1201)       += zd1201.o
 obj-$(CONFIG_LIBERTAS)         += libertas/
 
index 72bcf321d1ce26dbd6c4b741bd9115919d0c361d..d6599d219193aab8aa1abb3ed85d8908a332bbe9 100644 (file)
@@ -1980,7 +1980,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
        struct ath5k_buf *bf = sc->bbuf;
        struct ath5k_hw *ah = sc->ah;
 
-       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "in beacon_send\n");
+       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
 
        if (unlikely(bf->skb == NULL || sc->opmode == IEEE80211_IF_TYPE_STA ||
                        sc->opmode == IEEE80211_IF_TYPE_MNTR)) {
@@ -1996,10 +1996,10 @@ ath5k_beacon_send(struct ath5k_softc *sc)
         */
        if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) {
                sc->bmisscount++;
-               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
+               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
                        "missed %u consecutive beacons\n", sc->bmisscount);
                if (sc->bmisscount > 3) {               /* NB: 3 is a guess */
-                       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
+                       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
                                "stuck beacon time (%u missed)\n",
                                sc->bmisscount);
                        tasklet_schedule(&sc->restq);
@@ -2007,7 +2007,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
                return;
        }
        if (unlikely(sc->bmisscount != 0)) {
-               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
+               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
                        "resume beacon xmit after %u misses\n",
                        sc->bmisscount);
                sc->bmisscount = 0;
@@ -2027,7 +2027,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
 
        ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr);
        ath5k_hw_tx_start(ah, sc->bhalq);
-       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "TXDP[%u] = %llx (%p)\n",
+       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
                sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
 
        sc->bsent++;
index 4ba649e20269fcd357457555e0b5de90f057ffd5..bb581ef6d1efa51ae0bbca075498fabea129685f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007 Bruno Randolf <bruno@thinktube.com>
+ * Copyright (c) 2007-2008 Bruno Randolf <bruno@thinktube.com>
  *
  *  This file is free software: you may copy, redistribute and/or modify it
  *  under the terms of the GNU General Public License as published by the
@@ -200,7 +200,7 @@ static ssize_t read_file_tsf(struct file *file, char __user *user_buf,
 {
        struct ath5k_softc *sc = file->private_data;
        char buf[100];
-       snprintf(buf, 100, "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah));
+       snprintf(buf, sizeof(buf), "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah));
        return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
 }
 
@@ -209,7 +209,12 @@ static ssize_t write_file_tsf(struct file *file,
                                 size_t count, loff_t *ppos)
 {
        struct ath5k_softc *sc = file->private_data;
-       if (strncmp(userbuf, "reset", 5) == 0) {
+       char buf[20];
+
+       if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+               return -EFAULT;
+
+       if (strncmp(buf, "reset", 5) == 0) {
                ath5k_hw_reset_tsf(sc->ah);
                printk(KERN_INFO "debugfs reset TSF\n");
        }
@@ -231,8 +236,8 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
 {
        struct ath5k_softc *sc = file->private_data;
        struct ath5k_hw *ah = sc->ah;
-       char buf[1000];
-       int len = 0;
+       char buf[500];
+       unsigned int len = 0;
        unsigned int v;
        u64 tsf;
 
@@ -277,11 +282,15 @@ static ssize_t write_file_beacon(struct file *file,
 {
        struct ath5k_softc *sc = file->private_data;
        struct ath5k_hw *ah = sc->ah;
+       char buf[20];
+
+       if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+               return -EFAULT;
 
-       if (strncmp(userbuf, "disable", 7) == 0) {
+       if (strncmp(buf, "disable", 7) == 0) {
                AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
                printk(KERN_INFO "debugfs disable beacons\n");
-       } else if (strncmp(userbuf, "enable", 6) == 0) {
+       } else if (strncmp(buf, "enable", 6) == 0) {
                AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
                printk(KERN_INFO "debugfs enable beacons\n");
        }
@@ -314,6 +323,82 @@ static const struct file_operations fops_reset = {
 };
 
 
+/* debugfs: debug level */
+
+static struct {
+       enum ath5k_debug_level level;
+       const char *name;
+       const char *desc;
+} dbg_info[] = {
+       { ATH5K_DEBUG_RESET,    "reset",        "reset and initialization" },
+       { ATH5K_DEBUG_INTR,     "intr",         "interrupt handling" },
+       { ATH5K_DEBUG_MODE,     "mode",         "mode init/setup" },
+       { ATH5K_DEBUG_XMIT,     "xmit",         "basic xmit operation" },
+       { ATH5K_DEBUG_BEACON,   "beacon",       "beacon handling" },
+       { ATH5K_DEBUG_CALIBRATE, "calib",       "periodic calibration" },
+       { ATH5K_DEBUG_TXPOWER,  "txpower",      "transmit power setting" },
+       { ATH5K_DEBUG_LED,      "led",          "LED mamagement" },
+       { ATH5K_DEBUG_DUMP_RX,  "dumprx",       "print received skb content" },
+       { ATH5K_DEBUG_DUMP_TX,  "dumptx",       "print transmit skb content" },
+       { ATH5K_DEBUG_DUMPMODES, "dumpmodes",   "dump modes" },
+       { ATH5K_DEBUG_TRACE,    "trace",        "trace function calls" },
+       { ATH5K_DEBUG_ANY,      "all",          "show all debug levels" },
+};
+
+static ssize_t read_file_debug(struct file *file, char __user *user_buf,
+                                  size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       char buf[700];
+       unsigned int len = 0;
+       unsigned int i;
+
+       len += snprintf(buf+len, sizeof(buf)-len,
+               "DEBUG LEVEL: 0x%08x\n\n", sc->debug.level);
+
+       for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) {
+               len += snprintf(buf+len, sizeof(buf)-len,
+                       "%10s %c 0x%08x - %s\n", dbg_info[i].name,
+                       sc->debug.level & dbg_info[i].level ? '+' : ' ',
+                       dbg_info[i].level, dbg_info[i].desc);
+       }
+       len += snprintf(buf+len, sizeof(buf)-len,
+               "%10s %c 0x%08x - %s\n", dbg_info[i].name,
+               sc->debug.level == dbg_info[i].level ? '+' : ' ',
+               dbg_info[i].level, dbg_info[i].desc);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_debug(struct file *file,
+                                const char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       unsigned int i;
+       char buf[20];
+
+       if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+               return -EFAULT;
+
+       for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
+               if (strncmp(buf, dbg_info[i].name,
+                                       strlen(dbg_info[i].name)) == 0) {
+                       sc->debug.level ^= dbg_info[i].level; /* toggle bit */
+                       break;
+               }
+       }
+       return count;
+}
+
+static const struct file_operations fops_debug = {
+       .read = read_file_debug,
+       .write = write_file_debug,
+       .open = ath5k_debugfs_open,
+       .owner = THIS_MODULE,
+};
+
+
 /* init */
 
 void
@@ -326,26 +411,24 @@ void
 ath5k_debug_init_device(struct ath5k_softc *sc)
 {
        sc->debug.level = ath5k_debug;
+
        sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
-                       ath5k_global_debugfs);
-       sc->debug.debugfs_debug = debugfs_create_u32("debug",
-                       0666, sc->debug.debugfs_phydir, &sc->debug.level);
+                               ath5k_global_debugfs);
+
+       sc->debug.debugfs_debug = debugfs_create_file("debug", 0666,
+                               sc->debug.debugfs_phydir, sc, &fops_debug);
 
        sc->debug.debugfs_registers = debugfs_create_file("registers", 0444,
-                               sc->debug.debugfs_phydir,
-                               sc, &fops_registers);
+                               sc->debug.debugfs_phydir, sc, &fops_registers);
 
        sc->debug.debugfs_tsf = debugfs_create_file("tsf", 0666,
-                               sc->debug.debugfs_phydir,
-                               sc, &fops_tsf);
+                               sc->debug.debugfs_phydir, sc, &fops_tsf);
 
        sc->debug.debugfs_beacon = debugfs_create_file("beacon", 0666,
-                               sc->debug.debugfs_phydir,
-                               sc, &fops_beacon);
+                               sc->debug.debugfs_phydir, sc, &fops_beacon);
 
        sc->debug.debugfs_reset = debugfs_create_file("reset", 0222,
-                               sc->debug.debugfs_phydir,
-                               sc, &fops_reset);
+                               sc->debug.debugfs_phydir, sc, &fops_reset);
 }
 
 void
@@ -415,8 +498,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
        struct ath5k_buf *bf;
        int status;
 
-       if (likely(!(sc->debug.level &
-           (ATH5K_DEBUG_RESET | ATH5K_DEBUG_FATAL))))
+       if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
                return;
 
        printk(KERN_DEBUG "rx queue %x, link %p\n",
@@ -426,7 +508,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
        list_for_each_entry(bf, &sc->rxbuf, list) {
                ds = bf->desc;
                status = ah->ah_proc_rx_desc(ah, ds);
-               if (!status || (sc->debug.level & ATH5K_DEBUG_FATAL))
+               if (!status)
                        ath5k_debug_printrxbuf(bf, status == 0);
        }
        spin_unlock_bh(&sc->rxbuflock);
index 2b491cbc8c802dd2958c1b00f92a0ab4c3c4f92f..c4fd8c43df0c913515f7ee80262de128015ccd47 100644 (file)
@@ -91,7 +91,6 @@ struct ath5k_dbg_info {
  * @ATH5K_DEBUG_MODE: mode init/setup
  * @ATH5K_DEBUG_XMIT: basic xmit operation
  * @ATH5K_DEBUG_BEACON: beacon handling
- * @ATH5K_DEBUG_BEACON_PROC: beacon ISR proc
  * @ATH5K_DEBUG_CALIBRATE: periodic calibration
  * @ATH5K_DEBUG_TXPOWER: transmit power setting
  * @ATH5K_DEBUG_LED: led management
@@ -99,7 +98,6 @@ struct ath5k_dbg_info {
  * @ATH5K_DEBUG_DUMP_TX: print transmit skb content
  * @ATH5K_DEBUG_DUMPMODES: dump modes
  * @ATH5K_DEBUG_TRACE: trace function calls
- * @ATH5K_DEBUG_FATAL: fatal errors
  * @ATH5K_DEBUG_ANY: show at any debug level
  *
  * The debug level is used to control the amount and type of debugging output
@@ -115,15 +113,13 @@ enum ath5k_debug_level {
        ATH5K_DEBUG_MODE        = 0x00000004,
        ATH5K_DEBUG_XMIT        = 0x00000008,
        ATH5K_DEBUG_BEACON      = 0x00000010,
-       ATH5K_DEBUG_BEACON_PROC = 0x00000020,
-       ATH5K_DEBUG_CALIBRATE   = 0x00000100,
-       ATH5K_DEBUG_TXPOWER     = 0x00000200,
-       ATH5K_DEBUG_LED         = 0x00000400,
-       ATH5K_DEBUG_DUMP_RX     = 0x00001000,
-       ATH5K_DEBUG_DUMP_TX     = 0x00002000,
-       ATH5K_DEBUG_DUMPMODES   = 0x00004000,
-       ATH5K_DEBUG_TRACE       = 0x00010000,
-       ATH5K_DEBUG_FATAL       = 0x80000000,
+       ATH5K_DEBUG_CALIBRATE   = 0x00000020,
+       ATH5K_DEBUG_TXPOWER     = 0x00000040,
+       ATH5K_DEBUG_LED         = 0x00000080,
+       ATH5K_DEBUG_DUMP_RX     = 0x00000100,
+       ATH5K_DEBUG_DUMP_TX     = 0x00000200,
+       ATH5K_DEBUG_DUMPMODES   = 0x00000400,
+       ATH5K_DEBUG_TRACE       = 0x00001000,
        ATH5K_DEBUG_ANY         = 0xffffffff
 };
 
index 3e73d2a523aa98563ada01db749da1ccaaa7b5a5..8a708b77925df438ab5eb959b15edd025da31c96 100644 (file)
@@ -1114,7 +1114,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
 {
        const struct b43_dma_ops *ops = ring->ops;
        u8 *header;
-       int slot;
+       int slot, old_top_slot, old_used_slots;
        int err;
        struct b43_dmadesc_generic *desc;
        struct b43_dmadesc_meta *meta;
@@ -1126,6 +1126,9 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
 #define SLOTS_PER_PACKET  2
        B43_WARN_ON(skb_shinfo(skb)->nr_frags);
 
+       old_top_slot = ring->current_slot;
+       old_used_slots = ring->used_slots;
+
        /* Get a slot for the header. */
        slot = request_slot(ring);
        desc = ops->idx2desc(ring, slot, &meta_hdr);
@@ -1133,13 +1136,21 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
 
        header = &(ring->txhdr_cache[slot * hdrsize]);
        cookie = generate_cookie(ring, slot);
-       b43_generate_txhdr(ring->dev, header,
-                          skb->data, skb->len, ctl, cookie);
+       err = b43_generate_txhdr(ring->dev, header,
+                                skb->data, skb->len, ctl, cookie);
+       if (unlikely(err)) {
+               ring->current_slot = old_top_slot;
+               ring->used_slots = old_used_slots;
+               return err;
+       }
 
        meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
                                           hdrsize, 1);
-       if (dma_mapping_error(meta_hdr->dmaaddr))
+       if (dma_mapping_error(meta_hdr->dmaaddr)) {
+               ring->current_slot = old_top_slot;
+               ring->used_slots = old_used_slots;
                return -EIO;
+       }
        ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr,
                             hdrsize, 1, 0, 0);
 
@@ -1157,6 +1168,8 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
        if (dma_mapping_error(meta->dmaaddr)) {
                bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
                if (!bounce_skb) {
+                       ring->current_slot = old_top_slot;
+                       ring->used_slots = old_used_slots;
                        err = -ENOMEM;
                        goto out_unmap_hdr;
                }
@@ -1167,6 +1180,8 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
                meta->skb = skb;
                meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
                if (dma_mapping_error(meta->dmaaddr)) {
+                       ring->current_slot = old_top_slot;
+                       ring->used_slots = old_used_slots;
                        err = -EIO;
                        goto out_free_bounce;
                }
@@ -1252,6 +1267,13 @@ int b43_dma_tx(struct b43_wldev *dev,
        B43_WARN_ON(ring->stopped);
 
        err = dma_tx_fragment(ring, skb, ctl);
+       if (unlikely(err == -ENOKEY)) {
+               /* Drop this packet, as we don't have the encryption key
+                * anymore and must not transmit it unencrypted. */
+               dev_kfree_skb_any(skb);
+               err = 0;
+               goto out_unlock;
+       }
        if (unlikely(err)) {
                b43err(dev->wl, "DMA tx mapping failure\n");
                goto out_unlock;
index 88d2c15d3fbeccc5332cf55e3582a71e5174e3ef..64c154d080d865fdde6a792e7ea5008af459a25b 100644 (file)
@@ -3532,8 +3532,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
        b43_bluetooth_coext_enable(dev);
 
        ssb_bus_powerup(bus, 1);        /* Enable dynamic PCTL */
-       memset(wl->bssid, 0, ETH_ALEN);
-       memset(wl->mac_addr, 0, ETH_ALEN);
        b43_upload_card_macaddress(dev);
        b43_security_init(dev);
        b43_rng_init(wl);
@@ -3630,6 +3628,15 @@ static int b43_op_start(struct ieee80211_hw *hw)
        struct b43_wldev *dev = wl->current_dev;
        int did_init = 0;
        int err = 0;
+       bool do_rfkill_exit = 0;
+
+       /* Kill all old instance specific information to make sure
+        * the card won't use it in the short timeframe between start
+        * and mac80211 reconfiguring it. */
+       memset(wl->bssid, 0, ETH_ALEN);
+       memset(wl->mac_addr, 0, ETH_ALEN);
+       wl->filter_flags = 0;
+       wl->radiotap_enabled = 0;
 
        /* First register RFkill.
         * LEDs that are registered later depend on it. */
@@ -3639,8 +3646,10 @@ static int b43_op_start(struct ieee80211_hw *hw)
 
        if (b43_status(dev) < B43_STAT_INITIALIZED) {
                err = b43_wireless_core_init(dev);
-               if (err)
+               if (err) {
+                       do_rfkill_exit = 1;
                        goto out_mutex_unlock;
+               }
                did_init = 1;
        }
 
@@ -3649,6 +3658,7 @@ static int b43_op_start(struct ieee80211_hw *hw)
                if (err) {
                        if (did_init)
                                b43_wireless_core_exit(dev);
+                       do_rfkill_exit = 1;
                        goto out_mutex_unlock;
                }
        }
@@ -3656,6 +3666,9 @@ static int b43_op_start(struct ieee80211_hw *hw)
  out_mutex_unlock:
        mutex_unlock(&wl->mutex);
 
+       if (do_rfkill_exit)
+               b43_rfkill_exit(dev);
+
        return err;
 }
 
index 3fc53e8b4416092c26a2f2bbb7ead93b4ecda98b..7caa26eb410588a8b4de1a03328141db52888787 100644 (file)
@@ -178,12 +178,12 @@ static u8 b43_calc_fallback_rate(u8 bitrate)
 }
 
 /* Generate a TX data header. */
-void b43_generate_txhdr(struct b43_wldev *dev,
-                       u8 *_txhdr,
-                       const unsigned char *fragment_data,
-                       unsigned int fragment_len,
-                       const struct ieee80211_tx_control *txctl,
-                       u16 cookie)
+int b43_generate_txhdr(struct b43_wldev *dev,
+                      u8 *_txhdr,
+                      const unsigned char *fragment_data,
+                      unsigned int fragment_len,
+                      const struct ieee80211_tx_control *txctl,
+                      u16 cookie)
 {
        struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
        const struct b43_phy *phy = &dev->phy;
@@ -237,7 +237,15 @@ void b43_generate_txhdr(struct b43_wldev *dev,
 
                B43_WARN_ON(key_idx >= dev->max_nr_keys);
                key = &(dev->key[key_idx]);
-               B43_WARN_ON(!key->keyconf);
+
+               if (unlikely(!key->keyconf)) {
+                       /* This key is invalid. This might only happen
+                        * in a short timeframe after machine resume before
+                        * we were able to reconfigure keys.
+                        * Drop this packet completely. Do not transmit it
+                        * unencrypted to avoid leaking information. */
+                       return -ENOKEY;
+               }
 
                /* Hardware appends ICV. */
                plcp_fragment_len += txctl->icv_len;
@@ -408,6 +416,7 @@ void b43_generate_txhdr(struct b43_wldev *dev,
        txhdr->phy_ctl = cpu_to_le16(phy_ctl);
        txhdr->extra_ft = extra_ft;
 
+       return 0;
 }
 
 static s8 b43_rssi_postprocess(struct b43_wldev *dev,
index ca2a2ab8654c5d7102e07e7c5698d89c536b7680..41765039552bdf6792bd7b4e3cae14ba02fec0ef 100644 (file)
@@ -174,11 +174,11 @@ size_t b43_txhdr_size(struct b43_wldev *dev)
 }
 
 
-void b43_generate_txhdr(struct b43_wldev *dev,
-                       u8 * txhdr,
-                       const unsigned char *fragment_data,
-                       unsigned int fragment_len,
-                       const struct ieee80211_tx_control *txctl, u16 cookie);
+int b43_generate_txhdr(struct b43_wldev *dev,
+                      u8 * txhdr,
+                      const unsigned char *fragment_data,
+                      unsigned int fragment_len,
+                      const struct ieee80211_tx_control *txctl, u16 cookie);
 
 /* Transmit Status */
 struct b43_txstatus {
index 93419adb925e41454bf369e944eb536b3581ceb6..c80edd2b90444f9342fa41ab64a23e0f5d75689d 100644 (file)
@@ -23,7 +23,7 @@
 #include "phy.h"
 
 
-#define B43legacy_IRQWAIT_MAX_RETRIES  100
+#define B43legacy_IRQWAIT_MAX_RETRIES  20
 
 #define B43legacy_RX_MAX_SSI           60 /* best guess at max ssi */
 
@@ -40,9 +40,8 @@
 #define B43legacy_MMIO_DMA4_IRQ_MASK   0x44
 #define B43legacy_MMIO_DMA5_REASON     0x48
 #define B43legacy_MMIO_DMA5_IRQ_MASK   0x4C
-#define B43legacy_MMIO_MACCTL          0x120
-#define B43legacy_MMIO_STATUS_BITFIELD 0x120
-#define B43legacy_MMIO_STATUS2_BITFIELD        0x124
+#define B43legacy_MMIO_MACCTL          0x120   /* MAC control */
+#define B43legacy_MMIO_MACCMD          0x124   /* MAC command */
 #define B43legacy_MMIO_GEN_IRQ_REASON  0x128
 #define B43legacy_MMIO_GEN_IRQ_MASK    0x12C
 #define B43legacy_MMIO_RAM_CONTROL     0x130
 #define B43legacy_RADIOCTL_ID          0x01
 
 /* MAC Control bitfield */
+#define B43legacy_MACCTL_ENABLED       0x00000001 /* MAC Enabled */
+#define B43legacy_MACCTL_PSM_RUN       0x00000002 /* Run Microcode */
+#define B43legacy_MACCTL_PSM_JMP0      0x00000004 /* Microcode jump to 0 */
+#define B43legacy_MACCTL_SHM_ENABLED   0x00000100 /* SHM Enabled */
 #define B43legacy_MACCTL_IHR_ENABLED   0x00000400 /* IHR Region Enabled */
+#define B43legacy_MACCTL_BE            0x00010000 /* Big Endian mode */
 #define B43legacy_MACCTL_INFRA         0x00020000 /* Infrastructure mode */
 #define B43legacy_MACCTL_AP            0x00040000 /* AccessPoint mode */
+#define B43legacy_MACCTL_RADIOLOCK     0x00080000 /* Radio lock */
 #define B43legacy_MACCTL_BEACPROMISC   0x00100000 /* Beacon Promiscuous */
 #define B43legacy_MACCTL_KEEP_BADPLCP  0x00200000 /* Keep bad PLCP frames */
 #define B43legacy_MACCTL_KEEP_CTL      0x00400000 /* Keep control frames */
 #define B43legacy_MACCTL_KEEP_BAD      0x00800000 /* Keep bad frames (FCS) */
 #define B43legacy_MACCTL_PROMISC       0x01000000 /* Promiscuous mode */
+#define B43legacy_MACCTL_HWPS          0x02000000 /* Hardware Power Saving */
+#define B43legacy_MACCTL_AWAKE         0x04000000 /* Device is awake */
+#define B43legacy_MACCTL_TBTTHOLD      0x10000000 /* TBTT Hold */
 #define B43legacy_MACCTL_GMODE         0x80000000 /* G Mode */
 
-/* StatusBitField */
-#define B43legacy_SBF_MAC_ENABLED      0x00000001
-#define B43legacy_SBF_CORE_READY       0x00000004
-#define B43legacy_SBF_400              0x00000400 /*FIXME: fix name*/
-#define B43legacy_SBF_XFER_REG_BYTESWAP        0x00010000
-#define B43legacy_SBF_MODE_NOTADHOC    0x00020000
-#define B43legacy_SBF_MODE_AP          0x00040000
-#define B43legacy_SBF_RADIOREG_LOCK    0x00080000
-#define B43legacy_SBF_MODE_MONITOR     0x00400000
-#define B43legacy_SBF_MODE_PROMISC     0x01000000
-#define B43legacy_SBF_PS1              0x02000000
-#define B43legacy_SBF_PS2              0x04000000
-#define B43legacy_SBF_NO_SSID_BCAST    0x08000000
-#define B43legacy_SBF_TIME_UPDATE      0x10000000
-
 /* 802.11 core specific TM State Low flags */
 #define B43legacy_TMSLOW_GMODE         0x20000000 /* G Mode Enable */
 #define B43legacy_TMSLOW_PLLREFSEL     0x00200000 /* PLL Freq Ref Select */
index 4ed4243feeaa7cf659910b40e8f6bccbdbe8c2db..aa20d5d56e2f479d625c2411c53228ebaa3876e9 100644 (file)
@@ -225,8 +225,8 @@ static void b43legacy_ram_write(struct b43legacy_wldev *dev, u16 offset,
 
        B43legacy_WARN_ON(offset % 4 != 0);
 
-       status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
-       if (status & B43legacy_SBF_XFER_REG_BYTESWAP)
+       status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+       if (status & B43legacy_MACCTL_BE)
                val = swab32(val);
 
        b43legacy_write32(dev, B43legacy_MMIO_RAM_CONTROL, offset);
@@ -434,9 +434,9 @@ static void b43legacy_time_lock(struct b43legacy_wldev *dev)
 {
        u32 status;
 
-       status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
-       status |= B43legacy_SBF_TIME_UPDATE;
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+       status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+       status |= B43legacy_MACCTL_TBTTHOLD;
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
        mmiowb();
 }
 
@@ -444,9 +444,9 @@ static void b43legacy_time_unlock(struct b43legacy_wldev *dev)
 {
        u32 status;
 
-       status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
-       status &= ~B43legacy_SBF_TIME_UPDATE;
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+       status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+       status &= ~B43legacy_MACCTL_TBTTHOLD;
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
 }
 
 static void b43legacy_tsf_write_locked(struct b43legacy_wldev *dev, u64 tsf)
@@ -647,7 +647,7 @@ void b43legacy_dummy_transmission(struct b43legacy_wldev *dev)
                b43legacy_ram_write(dev, i * 4, buffer[i]);
 
        /* dummy read follows */
-       b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
+       b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
 
        b43legacy_write16(dev, 0x0568, 0x0000);
        b43legacy_write16(dev, 0x07C0, 0x0000);
@@ -794,9 +794,9 @@ static void b43legacy_jssi_write(struct b43legacy_wldev *dev, u32 jssi)
 static void b43legacy_generate_noise_sample(struct b43legacy_wldev *dev)
 {
        b43legacy_jssi_write(dev, 0x7F7F7F7F);
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD,
+       b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
                          b43legacy_read32(dev,
-                         B43legacy_MMIO_STATUS2_BITFIELD)
+                         B43legacy_MMIO_MACCMD)
                          | (1 << 4));
        B43legacy_WARN_ON(dev->noisecalc.channel_at_start !=
                            dev->phy.channel);
@@ -895,8 +895,8 @@ static void handle_irq_atim_end(struct b43legacy_wldev *dev)
 {
        if (!dev->reg124_set_0x4) /*FIXME rename this variable*/
                return;
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD,
-                         b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD)
+       b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
+                         b43legacy_read32(dev, B43legacy_MMIO_MACCMD)
                          | 0x4);
 }
 
@@ -1106,9 +1106,9 @@ static void b43legacy_update_templates(struct b43legacy_wldev *dev)
        b43legacy_write_probe_resp_template(dev, 0x268, 0x4A,
                                            B43legacy_CCK_RATE_11MB);
 
-       status = b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD);
+       status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
        status |= 0x03;
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD, status);
+       b43legacy_write32(dev, B43legacy_MMIO_MACCMD, status);
 }
 
 static void b43legacy_refresh_templates(struct b43legacy_wldev *dev,
@@ -1166,7 +1166,7 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev)
                return;
 
        dev->irq_savedstate &= ~B43legacy_IRQ_BEACON;
-       status = b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD);
+       status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
 
        if (!dev->cached_beacon || ((status & 0x1) && (status & 0x2))) {
                /* ACK beacon IRQ. */
@@ -1182,14 +1182,14 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev)
                b43legacy_write_beacon_template(dev, 0x68, 0x18,
                                                B43legacy_CCK_RATE_1MB);
                status |= 0x1;
-               b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD,
+               b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
                                  status);
        }
        if (!(status & 0x2)) {
                b43legacy_write_beacon_template(dev, 0x468, 0x1A,
                                                B43legacy_CCK_RATE_1MB);
                status |= 0x2;
-               b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD,
+               b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
                                  status);
        }
 }
@@ -1548,9 +1548,20 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
        u16 fwpatch;
        u16 fwdate;
        u16 fwtime;
-       u32 tmp;
+       u32 tmp, macctl;
        int err = 0;
 
+       /* Jump the microcode PSM to offset 0 */
+       macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+       B43legacy_WARN_ON(macctl & B43legacy_MACCTL_PSM_RUN);
+       macctl |= B43legacy_MACCTL_PSM_JMP0;
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
+       /* Zero out all microcode PSM registers and shared memory. */
+       for (i = 0; i < 64; i++)
+               b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, i, 0);
+       for (i = 0; i < 4096; i += 2)
+               b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, i, 0);
+
        /* Upload Microcode. */
        data = (__be32 *) (dev->fw.ucode->data + hdr_len);
        len = (dev->fw.ucode->size - hdr_len) / sizeof(__be32);
@@ -1581,7 +1592,12 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
 
        b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON,
                          B43legacy_IRQ_ALL);
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 0x00020402);
+
+       /* Start the microcode PSM */
+       macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+       macctl &= ~B43legacy_MACCTL_PSM_JMP0;
+       macctl |= B43legacy_MACCTL_PSM_RUN;
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
 
        /* Wait for the microcode to load and respond */
        i = 0;
@@ -1594,9 +1610,13 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
                        b43legacyerr(dev->wl, "Microcode not responding\n");
                        b43legacy_print_fw_helptext(dev->wl);
                        err = -ENODEV;
-                       goto out;
+                       goto error;
+               }
+               msleep_interruptible(50);
+               if (signal_pending(current)) {
+                       err = -EINTR;
+                       goto error;
                }
-               udelay(10);
        }
        /* dummy read follows */
        b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
@@ -1617,9 +1637,8 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
                             " is supported. You must change your firmware"
                             " files.\n");
                b43legacy_print_fw_helptext(dev->wl);
-               b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 0);
                err = -EOPNOTSUPP;
-               goto out;
+               goto error;
        }
        b43legacydbg(dev->wl, "Loading firmware version 0x%X, patch level %u "
               "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch,
@@ -1629,7 +1648,14 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
        dev->fw.rev = fwrev;
        dev->fw.patch = fwpatch;
 
-out:
+       return 0;
+
+error:
+       macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+       macctl &= ~B43legacy_MACCTL_PSM_RUN;
+       macctl |= B43legacy_MACCTL_PSM_JMP0;
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
+
        return err;
 }
 
@@ -1736,9 +1762,9 @@ static int b43legacy_gpio_init(struct b43legacy_wldev *dev)
        u32 mask;
        u32 set;
 
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
                          b43legacy_read32(dev,
-                         B43legacy_MMIO_STATUS_BITFIELD)
+                         B43legacy_MMIO_MACCTL)
                          & 0xFFFF3FFF);
 
        b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK,
@@ -1798,14 +1824,14 @@ void b43legacy_mac_enable(struct b43legacy_wldev *dev)
        B43legacy_WARN_ON(dev->mac_suspended < 0);
        B43legacy_WARN_ON(irqs_disabled());
        if (dev->mac_suspended == 0) {
-               b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,
+               b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
                                  b43legacy_read32(dev,
-                                 B43legacy_MMIO_STATUS_BITFIELD)
-                                 | B43legacy_SBF_MAC_ENABLED);
+                                 B43legacy_MMIO_MACCTL)
+                                 | B43legacy_MACCTL_ENABLED);
                b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON,
                                  B43legacy_IRQ_MAC_SUSPENDED);
                /* the next two are dummy reads */
-               b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
+               b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
                b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
                b43legacy_power_saving_ctl_bits(dev, -1, -1);
 
@@ -1836,10 +1862,10 @@ void b43legacy_mac_suspend(struct b43legacy_wldev *dev)
                dev->irq_savedstate = tmp;
 
                b43legacy_power_saving_ctl_bits(dev, -1, 1);
-               b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,
+               b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
                                  b43legacy_read32(dev,
-                                 B43legacy_MMIO_STATUS_BITFIELD)
-                                 & ~B43legacy_SBF_MAC_ENABLED);
+                                 B43legacy_MMIO_MACCTL)
+                                 & ~B43legacy_MACCTL_ENABLED);
                b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
                for (i = 40; i; i--) {
                        tmp = b43legacy_read32(dev,
@@ -2007,12 +2033,15 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
        struct b43legacy_phy *phy = &dev->phy;
        int err;
        int tmp;
-       u32 value32;
+       u32 value32, macctl;
        u16 value16;
 
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,
-                         B43legacy_SBF_CORE_READY
-                         | B43legacy_SBF_400);
+       /* Initialize the MAC control */
+       macctl = B43legacy_MACCTL_IHR_ENABLED | B43legacy_MACCTL_SHM_ENABLED;
+       if (dev->phy.gmode)
+               macctl |= B43legacy_MACCTL_GMODE;
+       macctl |= B43legacy_MACCTL_INFRA;
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
 
        err = b43legacy_request_firmware(dev);
        if (err)
@@ -2052,12 +2081,12 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
        if (dev->dev->id.revision < 5)
                b43legacy_write32(dev, 0x010C, 0x01000000);
 
-       value32 = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
-       value32 &= ~B43legacy_SBF_MODE_NOTADHOC;
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value32);
-       value32 = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
-       value32 |= B43legacy_SBF_MODE_NOTADHOC;
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value32);
+       value32 = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+       value32 &= ~B43legacy_MACCTL_INFRA;
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value32);
+       value32 = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+       value32 |= B43legacy_MACCTL_INFRA;
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value32);
 
        if (b43legacy_using_pio(dev)) {
                b43legacy_write32(dev, 0x0210, 0x00000100);
@@ -2951,12 +2980,19 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev)
 {
        struct b43legacy_wl *wl = dev->wl;
        struct b43legacy_phy *phy = &dev->phy;
+       u32 macctl;
 
        B43legacy_WARN_ON(b43legacy_status(dev) > B43legacy_STAT_INITIALIZED);
        if (b43legacy_status(dev) != B43legacy_STAT_INITIALIZED)
                return;
        b43legacy_set_status(dev, B43legacy_STAT_UNINIT);
 
+       /* Stop the microcode PSM. */
+       macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+       macctl &= ~B43legacy_MACCTL_PSM_RUN;
+       macctl |= B43legacy_MACCTL_PSM_JMP0;
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
+
        mutex_unlock(&wl->mutex);
        /* Must unlock as it would otherwise deadlock. No races here.
         * Cancel possibly pending workqueues. */
@@ -3221,6 +3257,7 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
        struct b43legacy_wldev *dev = wl->current_dev;
        int did_init = 0;
        int err = 0;
+       bool do_rfkill_exit = 0;
 
        /* First register RFkill.
         * LEDs that are registered later depend on it. */
@@ -3230,8 +3267,10 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
 
        if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) {
                err = b43legacy_wireless_core_init(dev);
-               if (err)
+               if (err) {
+                       do_rfkill_exit = 1;
                        goto out_mutex_unlock;
+               }
                did_init = 1;
        }
 
@@ -3240,6 +3279,7 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
                if (err) {
                        if (did_init)
                                b43legacy_wireless_core_exit(dev);
+                       do_rfkill_exit = 1;
                        goto out_mutex_unlock;
                }
        }
@@ -3247,6 +3287,9 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
 out_mutex_unlock:
        mutex_unlock(&wl->mutex);
 
+       if (do_rfkill_exit)
+               b43legacy_rfkill_exit(dev);
+
        return err;
 }
 
index c16febbdbf5d7da9023ec33b855bc198bd4ac206..8e5c09b818715e87baf89a3c012d2cf8a1110c32 100644 (file)
@@ -140,7 +140,7 @@ void b43legacy_phy_calibrate(struct b43legacy_wldev *dev)
 {
        struct b43legacy_phy *phy = &dev->phy;
 
-       b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); /* Dummy read. */
+       b43legacy_read32(dev, B43legacy_MMIO_MACCTL); /* Dummy read. */
        if (phy->calibrated)
                return;
        if (phy->type == B43legacy_PHYTYPE_G && phy->rev == 1) {
@@ -2231,16 +2231,16 @@ bit26 = 1;
                 *      or the latest PS-Poll packet sent was successful,
                 *      set bit26  */
        }
-       status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
+       status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
        if (bit25)
-               status |= B43legacy_SBF_PS1;
+               status |= B43legacy_MACCTL_HWPS;
        else
-               status &= ~B43legacy_SBF_PS1;
+               status &= ~B43legacy_MACCTL_HWPS;
        if (bit26)
-               status |= B43legacy_SBF_PS2;
+               status |= B43legacy_MACCTL_AWAKE;
        else
-               status &= ~B43legacy_SBF_PS2;
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+               status &= ~B43legacy_MACCTL_AWAKE;
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
        if (bit26 && dev->dev->id.revision >= 5) {
                for (i = 0; i < 100; i++) {
                        if (b43legacy_shm_read32(dev, B43legacy_SHM_SHARED,
index de843ac147ae4016625bd12401d0bd02243d017f..e4f4c5c39e334ebf4c37c0e903b66ec989f71b82 100644 (file)
@@ -334,9 +334,9 @@ struct b43legacy_pioqueue *b43legacy_setup_pioqueue(struct b43legacy_wldev *dev,
        tasklet_init(&queue->txtask, tx_tasklet,
                     (unsigned long)queue);
 
-       value = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
-       value &= ~B43legacy_SBF_XFER_REG_BYTESWAP;
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value);
+       value = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+       value &= ~B43legacy_MACCTL_BE;
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value);
 
        qsize = b43legacy_read16(dev, queue->mmio_base
                                 + B43legacy_PIO_TXQBUFSIZE);
index 318a270cf9b424d5b12fac7a6086c4f9b7f7ea3e..955832e8654f18dd12e537a973a8345ee6bc1e1c 100644 (file)
@@ -91,10 +91,10 @@ void b43legacy_radio_lock(struct b43legacy_wldev *dev)
 {
        u32 status;
 
-       status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
-       B43legacy_WARN_ON(status & B43legacy_SBF_RADIOREG_LOCK);
-       status |= B43legacy_SBF_RADIOREG_LOCK;
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+       status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+       B43legacy_WARN_ON(status & B43legacy_MACCTL_RADIOLOCK);
+       status |= B43legacy_MACCTL_RADIOLOCK;
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
        mmiowb();
        udelay(10);
 }
@@ -104,10 +104,10 @@ void b43legacy_radio_unlock(struct b43legacy_wldev *dev)
        u32 status;
 
        b43legacy_read16(dev, B43legacy_MMIO_PHY_VER); /* dummy read */
-       status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
-       B43legacy_WARN_ON(!(status & B43legacy_SBF_RADIOREG_LOCK));
-       status &= ~B43legacy_SBF_RADIOREG_LOCK;
-       b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
+       status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
+       B43legacy_WARN_ON(!(status & B43legacy_MACCTL_RADIOLOCK));
+       status &= ~B43legacy_MACCTL_RADIOLOCK;
+       b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
        mmiowb();
 }
 
index d6b9362a3d5cd00f2d046f2afa86b071841b799c..3694b1eba521cbca531bb56574abb643da79f9a8 100644 (file)
@@ -71,11 +71,6 @@ struct hostap_80211_rx_status {
        u16 rate; /* in 100 kbps */
 };
 
-
-void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
-                    struct hostap_80211_rx_status *rx_stats);
-
-
 /* prism2_rx_80211 'type' argument */
 enum {
        PRISM2_RX_MONITOR, PRISM2_RX_MGMT, PRISM2_RX_NON_ASSOC,
index 07593803065ae142277cc33b276c0e64e9a7e339..437a9bcc9bd3793cee25bce11c381fdae75ab2f3 100644 (file)
@@ -891,6 +891,9 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
        PCMCIA_DEVICE_PROD_ID123(
                "The Linksys Group, Inc.", "Wireless Network CF Card", "ISL37300P",
                0xa5f472c2, 0x9c05598d, 0xc9049a39),
+       PCMCIA_DEVICE_PROD_ID123(
+               "Wireless LAN" , "11Mbps PC Card", "Version 01.02",
+               0x4b8870ff, 0x70e946d1, 0x4b74baa0),
        PCMCIA_DEVICE_NULL
 };
 MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
index 6e0187393af473f01df67b9a7817bca1371bf9e6..571815d7e8bf8909327e07f07453fd36396883e2 100644 (file)
@@ -373,7 +373,7 @@ struct iwl3945_eeprom {
 #define CSR_INT_BIT_HW_ERR       (1 << 29) /* DMA hardware error FH_INT[31] */
 #define CSR_INT_BIT_DNLD         (1 << 28) /* uCode Download */
 #define CSR_INT_BIT_FH_TX        (1 << 27) /* Tx DMA FH_INT[1:0] */
-#define CSR_INT_BIT_MAC_CLK_ACTV (1 << 26) /* NIC controller's clock toggled on/off */
+#define CSR_INT_BIT_SCD          (1 << 26) /* TXQ pointer advanced */
 #define CSR_INT_BIT_SW_ERR       (1 << 25) /* uCode error */
 #define CSR_INT_BIT_RF_KILL      (1 << 7)  /* HW RFKILL switch GP_CNTRL[27] toggled */
 #define CSR_INT_BIT_CT_KILL      (1 << 6)  /* Critical temp (chip too hot) rfkill */
index 76c4ed1135f272dd587e2ce44aa597689ad1e65f..4fdeb53232486a1fac23eae1735c53fc338fd8f8 100644 (file)
@@ -2369,18 +2369,4 @@ struct pci_device_id iwl3945_hw_card_ids[] = {
        {0}
 };
 
-/*
- * Clear the OWNER_MSK, to establish driver (instead of uCode running on
- * embedded controller) as EEPROM reader; each read is a series of pulses
- * to/from the EEPROM chip, not a single event, so even reads could conflict
- * if they weren't arbitrated by some ownership mechanism.  Here, the driver
- * simply claims ownership, which should be safe when this function is called
- * (i.e. before loading uCode!).
- */
-inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
-{
-       _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
-       return 0;
-}
-
 MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids);
index 20b925f57e355f2bd5fb36b1884aa5359ecf0d95..1da14f9bbe0f02fb1b2142f0ed1e0302bd86478b 100644 (file)
@@ -671,7 +671,6 @@ extern int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel);
 /*
  * Forward declare iwl-3945.c functions for iwl-base.c
  */
-extern int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv);
 extern __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv);
 extern int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv);
 extern void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv);
@@ -791,7 +790,6 @@ struct iwl3945_priv {
        u16 active_rate_basic;
 
        u8 call_post_assoc_from_beacon;
-       u8 assoc_station_added;
        /* Rate scaling data */
        s8 data_retry_limit;
        u8 retry_rate;
index ff71c09ab1a7f73d053e855ee17c2c3f03e8974f..ffe1e9dfdec7bc5da5b2e0c909a41f7f710c4a8d 100644 (file)
@@ -465,7 +465,7 @@ struct iwl4965_eeprom {
 #define CSR_INT_BIT_HW_ERR       (1 << 29) /* DMA hardware error FH_INT[31] */
 #define CSR_INT_BIT_DNLD         (1 << 28) /* uCode Download */
 #define CSR_INT_BIT_FH_TX        (1 << 27) /* Tx DMA FH_INT[1:0] */
-#define CSR_INT_BIT_MAC_CLK_ACTV (1 << 26) /* NIC controller's clock toggled on/off */
+#define CSR_INT_BIT_SCD          (1 << 26) /* TXQ pointer advanced */
 #define CSR_INT_BIT_SW_ERR       (1 << 25) /* uCode error */
 #define CSR_INT_BIT_RF_KILL      (1 << 7)  /* HW RFKILL switch GP_CNTRL[27] toggled */
 #define CSR_INT_BIT_CT_KILL      (1 << 6)  /* Critical temp (chip too hot) rfkill */
index 04db34ba814be632871270d17d890bf6e3cacaf6..569347ff377b18e7cb494152734f471f454fd3f0 100644 (file)
@@ -4961,11 +4961,4 @@ int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv)
        return rc;
 }
 
-inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv)
-{
-       iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
-               CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-}
-
-
 MODULE_DEVICE_TABLE(pci, iwl4965_hw_card_ids);
index 78bc148c9f7f4c9cc1566790c52ce25f742ae573..9cb82be0ff80a19b0e5b7fa179625bcb2f21c086 100644 (file)
@@ -750,7 +750,6 @@ struct iwl4965_priv;
  * Forward declare iwl-4965.c functions for iwl-base.c
  */
 extern int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv);
-extern void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv);
 
 extern int iwl4965_tx_queue_update_wr_ptr(struct iwl4965_priv *priv,
                                          struct iwl4965_tx_queue *txq,
index cd2eb184831068c74d3318ab35681e326a6e849d..cb009f4c401fd9db96d5b2129eed5e02980f41d9 100644 (file)
@@ -246,10 +246,10 @@ static inline int iwl_check_bits(unsigned long field, unsigned long mask)
 static inline unsigned long elapsed_jiffies(unsigned long start,
                                            unsigned long end)
 {
-       if (end > start)
+       if (end >= start)
                return end - start;
 
-       return end + (MAX_JIFFY_OFFSET - start);
+       return end + (MAX_JIFFY_OFFSET - start) + 1;
 }
 
 static inline u8 iwl_get_dma_hi_address(dma_addr_t addr)
index 748ac1222abb908d2c18a79c35a389a393bab250..33239f197984302f53125191546a176f67b46892 100644 (file)
@@ -1557,6 +1557,20 @@ static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac)
        memcpy(mac, priv->eeprom.mac_address, 6);
 }
 
+/*
+ * Clear the OWNER_MSK, to establish driver (instead of uCode running on
+ * embedded controller) as EEPROM reader; each read is a series of pulses
+ * to/from the EEPROM chip, not a single event, so even reads could conflict
+ * if they weren't arbitrated by some ownership mechanism.  Here, the driver
+ * simply claims ownership, which should be safe when this function is called
+ * (i.e. before loading uCode!).
+ */
+static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
+{
+       _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
+       return 0;
+}
+
 /**
  * iwl3945_eeprom_init - read EEPROM contents
  *
@@ -2792,7 +2806,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
 #endif
 
        /* drop all data frame if we are not associated */
-       if (!iwl3945_is_associated(priv) && !priv->assoc_id &&
+       if ((!iwl3945_is_associated(priv) || !priv->assoc_id) &&
            ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
                IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
                goto drop_unlock;
@@ -4745,8 +4759,9 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
 #ifdef CONFIG_IWL3945_DEBUG
        if (iwl3945_debug_level & (IWL_DL_ISR)) {
                /* NIC fires this, but we don't use it, redundant with WAKEUP */
-               if (inta & CSR_INT_BIT_MAC_CLK_ACTV)
-                       IWL_DEBUG_ISR("Microcode started or stopped.\n");
+               if (inta & CSR_INT_BIT_SCD)
+                       IWL_DEBUG_ISR("Scheduler finished to transmit "
+                                     "the frame/frames.\n");
 
                /* Alive notification via Rx interrupt will do the real work */
                if (inta & CSR_INT_BIT_ALIVE)
@@ -4754,7 +4769,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
        }
 #endif
        /* Safely ignore these bits for debug checks below */
-       inta &= ~(CSR_INT_BIT_MAC_CLK_ACTV | CSR_INT_BIT_ALIVE);
+       inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
 
        /* HW RF KILL switch toggled (4965 only) */
        if (inta & CSR_INT_BIT_RF_KILL) {
@@ -4890,8 +4905,11 @@ static irqreturn_t iwl3945_isr(int irq, void *data)
        IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
                      inta, inta_mask, inta_fh);
 
+       inta &= ~CSR_INT_BIT_SCD;
+
        /* iwl3945_irq_tasklet() will service interrupts and re-enable them */
-       tasklet_schedule(&priv->irq_tasklet);
+       if (likely(inta || inta_fh))
+               tasklet_schedule(&priv->irq_tasklet);
 unplugged:
        spin_unlock(&priv->lock);
 
@@ -5146,6 +5164,15 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
        return 0;
 }
 
+/*
+ * iwl3945_free_channel_map - undo allocations in iwl3945_init_channel_map
+ */
+static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
+{
+       kfree(priv->channel_info);
+       priv->channel_count = 0;
+}
+
 /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
  * sending probe req.  This should be set long enough to hear probe responses
  * from more than one AP.  */
@@ -5471,6 +5498,17 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
        return 0;
 }
 
+/*
+ * iwl3945_free_geos - undo allocations in iwl3945_init_geos
+ */
+static void iwl3945_free_geos(struct iwl3945_priv *priv)
+{
+       kfree(priv->modes);
+       kfree(priv->ieee_channels);
+       kfree(priv->ieee_rates);
+       clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
+}
+
 /******************************************************************************
  *
  * uCode download functions
@@ -6130,15 +6168,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
        /* Clear out the uCode error bit if it is set */
        clear_bit(STATUS_FW_ERROR, &priv->status);
 
-       rc = iwl3945_init_channel_map(priv);
-       if (rc) {
-               IWL_ERROR("initializing regulatory failed: %d\n", rc);
-               return;
-       }
-
-       iwl3945_init_geos(priv);
-       iwl3945_reset_channel_flag(priv);
-
        if (iwl3945_is_rfkill(priv))
                return;
 
@@ -6599,7 +6628,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
         * that based on the direct_mask added to each channel entry */
        scan->tx_cmd.len = cpu_to_le16(
                iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
-                       IWL_MAX_SCAN_SIZE - sizeof(scan), 0));
+                       IWL_MAX_SCAN_SIZE - sizeof(*scan), 0));
        scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
        scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
        scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
@@ -7120,7 +7149,7 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
 {
        int rc = 0;
 
-       if (priv->status & STATUS_EXIT_PENDING)
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        /* The following should be done only at AP bring up */
@@ -8614,11 +8643,24 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
        SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
 
+       err = iwl3945_init_channel_map(priv);
+       if (err) {
+               IWL_ERROR("initializing regulatory failed: %d\n", err);
+               goto out_remove_sysfs;
+       }
+
+       err = iwl3945_init_geos(priv);
+       if (err) {
+               IWL_ERROR("initializing geos failed: %d\n", err);
+               goto out_free_channel_map;
+       }
+       iwl3945_reset_channel_flag(priv);
+
        iwl3945_rate_control_register(priv->hw);
        err = ieee80211_register_hw(priv->hw);
        if (err) {
                IWL_ERROR("Failed to register network device (error %d)\n", err);
-               goto out_remove_sysfs;
+               goto out_free_geos;
        }
 
        priv->hw->conf.beacon_int = 100;
@@ -8628,6 +8670,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
        return 0;
 
+ out_free_geos:
+       iwl3945_free_geos(priv);
+ out_free_channel_map:
+       iwl3945_free_channel_map(priv);
  out_remove_sysfs:
        sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
 
@@ -8702,10 +8748,8 @@ static void iwl3945_pci_remove(struct pci_dev *pdev)
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
 
-       kfree(priv->channel_info);
-
-       kfree(priv->ieee_channels);
-       kfree(priv->ieee_rates);
+       iwl3945_free_channel_map(priv);
+       iwl3945_free_geos(priv);
 
        if (priv->ibss_beacon)
                dev_kfree_skb(priv->ibss_beacon);
index c86da5cd1df19466fe230393a98e74e3475ede16..bf3a60c037aa915b8a6f67fe2a045221b26d9770 100644 (file)
@@ -1639,6 +1639,12 @@ static void get_eeprom_mac(struct iwl4965_priv *priv, u8 *mac)
        memcpy(mac, priv->eeprom.mac_address, 6);
 }
 
+static inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv)
+{
+       iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+               CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+}
+
 /**
  * iwl4965_eeprom_init - read EEPROM contents
  *
@@ -2927,8 +2933,10 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv,
 #endif
 
        /* drop all data frame if we are not associated */
-       if (!iwl4965_is_associated(priv) && !priv->assoc_id &&
-           ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
+       if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
+          (!iwl4965_is_associated(priv) ||
+           !priv->assoc_id ||
+           !priv->assoc_station_added)) {
                IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n");
                goto drop_unlock;
        }
@@ -5131,8 +5139,9 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv)
 #ifdef CONFIG_IWL4965_DEBUG
        if (iwl4965_debug_level & (IWL_DL_ISR)) {
                /* NIC fires this, but we don't use it, redundant with WAKEUP */
-               if (inta & CSR_INT_BIT_MAC_CLK_ACTV)
-                       IWL_DEBUG_ISR("Microcode started or stopped.\n");
+               if (inta & CSR_INT_BIT_SCD)
+                       IWL_DEBUG_ISR("Scheduler finished to transmit "
+                                     "the frame/frames.\n");
 
                /* Alive notification via Rx interrupt will do the real work */
                if (inta & CSR_INT_BIT_ALIVE)
@@ -5140,7 +5149,7 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv)
        }
 #endif
        /* Safely ignore these bits for debug checks below */
-       inta &= ~(CSR_INT_BIT_MAC_CLK_ACTV | CSR_INT_BIT_ALIVE);
+       inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
 
        /* HW RF KILL switch toggled */
        if (inta & CSR_INT_BIT_RF_KILL) {
@@ -5269,8 +5278,11 @@ static irqreturn_t iwl4965_isr(int irq, void *data)
        IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
                      inta, inta_mask, inta_fh);
 
+       inta &= ~CSR_INT_BIT_SCD;
+
        /* iwl4965_irq_tasklet() will service interrupts and re-enable them */
-       tasklet_schedule(&priv->irq_tasklet);
+       if (likely(inta || inta_fh))
+               tasklet_schedule(&priv->irq_tasklet);
 
  unplugged:
        spin_unlock(&priv->lock);
@@ -5576,6 +5588,15 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv)
        return 0;
 }
 
+/*
+ * iwl4965_free_channel_map - undo allocations in iwl4965_init_channel_map
+ */
+static void iwl4965_free_channel_map(struct iwl4965_priv *priv)
+{
+       kfree(priv->channel_info);
+       priv->channel_count = 0;
+}
+
 /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
  * sending probe req.  This should be set long enough to hear probe responses
  * from more than one AP.  */
@@ -5909,6 +5930,17 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv)
        return 0;
 }
 
+/*
+ * iwl4965_free_geos - undo allocations in iwl4965_init_geos
+ */
+static void iwl4965_free_geos(struct iwl4965_priv *priv)
+{
+       kfree(priv->modes);
+       kfree(priv->ieee_channels);
+       kfree(priv->ieee_rates);
+       clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
+}
+
 /******************************************************************************
  *
  * uCode download functions
@@ -6560,15 +6592,6 @@ static void iwl4965_alive_start(struct iwl4965_priv *priv)
        /* Clear out the uCode error bit if it is set */
        clear_bit(STATUS_FW_ERROR, &priv->status);
 
-       rc = iwl4965_init_channel_map(priv);
-       if (rc) {
-               IWL_ERROR("initializing regulatory failed: %d\n", rc);
-               return;
-       }
-
-       iwl4965_init_geos(priv);
-       iwl4965_reset_channel_flag(priv);
-
        if (iwl4965_is_rfkill(priv))
                return;
 
@@ -7023,7 +7046,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
         * that based on the direct_mask added to each channel entry */
        scan->tx_cmd.len = cpu_to_le16(
                iwl4965_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
-                       IWL_MAX_SCAN_SIZE - sizeof(scan), 0));
+                       IWL_MAX_SCAN_SIZE - sizeof(*scan), 0));
        scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
        scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
        scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
@@ -7448,7 +7471,7 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw,
 
        if (priv->vif) {
                IWL_DEBUG_MAC80211("leave - vif != NULL\n");
-               return 0;
+               return -EOPNOTSUPP;
        }
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -7580,7 +7603,7 @@ static void iwl4965_config_ap(struct iwl4965_priv *priv)
 {
        int rc = 0;
 
-       if (priv->status & STATUS_EXIT_PENDING)
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        /* The following should be done only at AP bring up */
@@ -9198,11 +9221,24 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
        SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
 
+       err = iwl4965_init_channel_map(priv);
+       if (err) {
+               IWL_ERROR("initializing regulatory failed: %d\n", err);
+               goto out_remove_sysfs;
+       }
+
+       err = iwl4965_init_geos(priv);
+       if (err) {
+               IWL_ERROR("initializing geos failed: %d\n", err);
+               goto out_free_channel_map;
+       }
+       iwl4965_reset_channel_flag(priv);
+
        iwl4965_rate_control_register(priv->hw);
        err = ieee80211_register_hw(priv->hw);
        if (err) {
                IWL_ERROR("Failed to register network device (error %d)\n", err);
-               goto out_remove_sysfs;
+               goto out_free_geos;
        }
 
        priv->hw->conf.beacon_int = 100;
@@ -9212,6 +9248,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
        return 0;
 
+ out_free_geos:
+       iwl4965_free_geos(priv);
+ out_free_channel_map:
+       iwl4965_free_channel_map(priv);
  out_remove_sysfs:
        sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
 
@@ -9286,10 +9326,8 @@ static void iwl4965_pci_remove(struct pci_dev *pdev)
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
 
-       kfree(priv->channel_info);
-
-       kfree(priv->ieee_channels);
-       kfree(priv->ieee_rates);
+       iwl4965_free_channel_map(priv);
+       iwl4965_free_geos(priv);
 
        if (priv->ibss_beacon)
                dev_kfree_skb(priv->ibss_beacon);
index c622e9b63cd1cc62a0233e9fb30a8d6ae1853440..87e145ffe8f1a6e72bd6cdf9045e2901b79b89d1 100644 (file)
 #include "cmd.h"
 
 
-static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const u8 bssid_any[ETH_ALEN]  __attribute__ ((aligned (2))) =
+       { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+static const u8 bssid_off[ETH_ALEN]  __attribute__ ((aligned (2))) =
+       { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
 
 static int assoc_helper_essid(struct lbs_private *priv,
index 58d7ef6b5ff5b127591c65bd9d60ffb731c87e9d..5a69f2b608655aee1305177d11851047e589c222 100644 (file)
@@ -349,7 +349,7 @@ struct assoc_request {
        u8 channel;
        u8 band;
        u8 mode;
-       u8 bssid[ETH_ALEN];
+       u8 bssid[ETH_ALEN] __attribute__ ((aligned (2)));
 
        /** WEP keys */
        struct enc_key wep_keys[4];
index 4b5ab9a6b97b78687e56d1e5070addd9c7a1d8d9..5a9cadb97503fbf6ab8b4ba68a18d7da4a5e2ed6 100644 (file)
@@ -249,14 +249,14 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
        lbs_deb_enter(LBS_DEB_CS);
 
        int_cause = if_cs_read16(card, IF_CS_C_INT_CAUSE);
-       if(int_cause == 0x0) {
+       if (int_cause == 0x0) {
                /* Not for us */
                return IRQ_NONE;
 
        } else if (int_cause == 0xffff) {
                /* Read in junk, the card has probably been removed */
                card->priv->surpriseremoved = 1;
-
+               return IRQ_HANDLED;
        } else {
                if (int_cause & IF_CS_H_IC_TX_OVER)
                        lbs_host_to_card_done(card->priv);
@@ -717,8 +717,8 @@ static void if_cs_release(struct pcmcia_device *p_dev)
 
        lbs_deb_enter(LBS_DEB_CS);
 
-       pcmcia_disable_device(p_dev);
        free_irq(p_dev->irq.AssignedIRQ, card);
+       pcmcia_disable_device(p_dev);
        if (card->iobase)
                ioport_unmap(card->iobase);
 
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
new file mode 100644 (file)
index 0000000..d3ecf89
--- /dev/null
@@ -0,0 +1,2757 @@
+/*
+ * Driver for RNDIS based wireless USB devices.
+ *
+ * Copyright (C) 2007 by Bjorge Dijkstra <bjd@jooz.net>
+ * Copyright (C) 2008 by Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Portions of this file are based on NDISwrapper project,
+ *  Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
+ *  http://ndiswrapper.sourceforge.net/
+ */
+
+// #define     DEBUG                   // error path messages, extra info
+// #define     VERBOSE                 // more; success messages
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <linux/wireless.h>
+#include <linux/if_arp.h>
+#include <linux/ctype.h>
+#include <linux/spinlock.h>
+#include <net/iw_handler.h>
+#include <net/ieee80211.h>
+#include <linux/usb/usbnet.h>
+#include <linux/usb/rndis_host.h>
+
+
+/* NOTE: All these are settings for Broadcom chipset */
+static char modparam_country[4] = "EU";
+module_param_string(country, modparam_country, 4, 0444);
+MODULE_PARM_DESC(country, "Country code (ISO 3166-1 alpha-2), default: EU");
+
+static int modparam_frameburst = 1;
+module_param_named(frameburst, modparam_frameburst, int, 0444);
+MODULE_PARM_DESC(frameburst, "enable frame bursting (default: on)");
+
+static int modparam_afterburner = 0;
+module_param_named(afterburner, modparam_afterburner, int, 0444);
+MODULE_PARM_DESC(afterburner,
+       "enable afterburner aka '125 High Speed Mode' (default: off)");
+
+static int modparam_power_save = 0;
+module_param_named(power_save, modparam_power_save, int, 0444);
+MODULE_PARM_DESC(power_save,
+       "set power save mode: 0=off, 1=on, 2=fast (default: off)");
+
+static int modparam_power_output = 3;
+module_param_named(power_output, modparam_power_output, int, 0444);
+MODULE_PARM_DESC(power_output,
+       "set power output: 0=25%, 1=50%, 2=75%, 3=100% (default: 100%)");
+
+static int modparam_roamtrigger = -70;
+module_param_named(roamtrigger, modparam_roamtrigger, int, 0444);
+MODULE_PARM_DESC(roamtrigger,
+       "set roaming dBm trigger: -80=optimize for distance, "
+                               "-60=bandwidth (default: -70)");
+
+static int modparam_roamdelta = 1;
+module_param_named(roamdelta, modparam_roamdelta, int, 0444);
+MODULE_PARM_DESC(roamdelta,
+       "set roaming tendency: 0=aggressive, 1=moderate, "
+                               "2=conservative (default: moderate)");
+
+static int modparam_workaround_interval = 500;
+module_param_named(workaround_interval, modparam_workaround_interval,
+                                                       int, 0444);
+MODULE_PARM_DESC(workaround_interval,
+       "set stall workaround interval in msecs (default: 500)");
+
+
+/* various RNDIS OID defs */
+#define OID_GEN_LINK_SPEED                     ccpu2(0x00010107)
+#define OID_GEN_RNDIS_CONFIG_PARAMETER         ccpu2(0x0001021b)
+
+#define OID_GEN_XMIT_OK                                ccpu2(0x00020101)
+#define OID_GEN_RCV_OK                         ccpu2(0x00020102)
+#define OID_GEN_XMIT_ERROR                     ccpu2(0x00020103)
+#define OID_GEN_RCV_ERROR                      ccpu2(0x00020104)
+#define OID_GEN_RCV_NO_BUFFER                  ccpu2(0x00020105)
+
+#define OID_802_3_PERMANENT_ADDRESS            ccpu2(0x01010101)
+#define OID_802_3_CURRENT_ADDRESS              ccpu2(0x01010102)
+#define OID_802_3_MULTICAST_LIST               ccpu2(0x01010103)
+#define OID_802_3_MAXIMUM_LIST_SIZE            ccpu2(0x01010104)
+
+#define OID_802_11_BSSID                       ccpu2(0x0d010101)
+#define OID_802_11_SSID                                ccpu2(0x0d010102)
+#define OID_802_11_INFRASTRUCTURE_MODE         ccpu2(0x0d010108)
+#define OID_802_11_ADD_WEP                     ccpu2(0x0d010113)
+#define OID_802_11_REMOVE_WEP                  ccpu2(0x0d010114)
+#define OID_802_11_DISASSOCIATE                        ccpu2(0x0d010115)
+#define OID_802_11_AUTHENTICATION_MODE         ccpu2(0x0d010118)
+#define OID_802_11_PRIVACY_FILTER              ccpu2(0x0d010119)
+#define OID_802_11_BSSID_LIST_SCAN             ccpu2(0x0d01011a)
+#define OID_802_11_ENCRYPTION_STATUS           ccpu2(0x0d01011b)
+#define OID_802_11_ADD_KEY                     ccpu2(0x0d01011d)
+#define OID_802_11_REMOVE_KEY                  ccpu2(0x0d01011e)
+#define OID_802_11_PMKID                       ccpu2(0x0d010123)
+#define OID_802_11_NETWORK_TYPES_SUPPORTED     ccpu2(0x0d010203)
+#define OID_802_11_NETWORK_TYPE_IN_USE         ccpu2(0x0d010204)
+#define OID_802_11_TX_POWER_LEVEL              ccpu2(0x0d010205)
+#define OID_802_11_RSSI                                ccpu2(0x0d010206)
+#define OID_802_11_RSSI_TRIGGER                        ccpu2(0x0d010207)
+#define OID_802_11_FRAGMENTATION_THRESHOLD     ccpu2(0x0d010209)
+#define OID_802_11_RTS_THRESHOLD               ccpu2(0x0d01020a)
+#define OID_802_11_SUPPORTED_RATES             ccpu2(0x0d01020e)
+#define OID_802_11_CONFIGURATION               ccpu2(0x0d010211)
+#define OID_802_11_BSSID_LIST                  ccpu2(0x0d010217)
+
+
+/* Typical noise/maximum signal level values taken from ndiswrapper iw_ndis.h */
+#define        WL_NOISE        -96     /* typical noise level in dBm */
+#define        WL_SIGMAX       -32     /* typical maximum signal level in dBm */
+
+
+/* Assume that Broadcom 4320 (only chipset at time of writing known to be
+ * based on wireless rndis) has default txpower of 13dBm.
+ * This value is from Linksys WUSB54GSC User Guide, Appendix F: Specifications.
+ *   13dBm == 19.9mW
+ */
+#define BCM4320_DEFAULT_TXPOWER 20
+
+
+/* codes for "status" field of completion messages */
+#define RNDIS_STATUS_ADAPTER_NOT_READY         ccpu2(0xc0010011)
+#define RNDIS_STATUS_ADAPTER_NOT_OPEN          ccpu2(0xc0010012)
+
+
+/* NDIS data structures. Taken from wpa_supplicant driver_ndis.c
+ * slightly modified for datatype endianess, etc
+ */
+#define NDIS_802_11_LENGTH_SSID 32
+#define NDIS_802_11_LENGTH_RATES 8
+#define NDIS_802_11_LENGTH_RATES_EX 16
+
+struct NDIS_802_11_SSID {
+       __le32 SsidLength;
+       u8 Ssid[NDIS_802_11_LENGTH_SSID];
+} __attribute__((packed));
+
+enum NDIS_802_11_NETWORK_TYPE {
+       Ndis802_11FH,
+       Ndis802_11DS,
+       Ndis802_11OFDM5,
+       Ndis802_11OFDM24,
+       Ndis802_11NetworkTypeMax
+};
+
+struct NDIS_802_11_CONFIGURATION_FH {
+       __le32 Length;
+       __le32 HopPattern;
+       __le32 HopSet;
+       __le32 DwellTime;
+} __attribute__((packed));
+
+struct NDIS_802_11_CONFIGURATION {
+       __le32 Length;
+       __le32 BeaconPeriod;
+       __le32 ATIMWindow;
+       __le32 DSConfig;
+       struct NDIS_802_11_CONFIGURATION_FH FHConfig;
+} __attribute__((packed));
+
+enum NDIS_802_11_NETWORK_INFRASTRUCTURE {
+       Ndis802_11IBSS,
+       Ndis802_11Infrastructure,
+       Ndis802_11AutoUnknown,
+       Ndis802_11InfrastructureMax
+};
+
+enum NDIS_802_11_AUTHENTICATION_MODE {
+       Ndis802_11AuthModeOpen,
+       Ndis802_11AuthModeShared,
+       Ndis802_11AuthModeAutoSwitch,
+       Ndis802_11AuthModeWPA,
+       Ndis802_11AuthModeWPAPSK,
+       Ndis802_11AuthModeWPANone,
+       Ndis802_11AuthModeWPA2,
+       Ndis802_11AuthModeWPA2PSK,
+       Ndis802_11AuthModeMax
+};
+
+enum NDIS_802_11_ENCRYPTION_STATUS {
+       Ndis802_11WEPEnabled,
+       Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
+       Ndis802_11WEPDisabled,
+       Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
+       Ndis802_11WEPKeyAbsent,
+       Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
+       Ndis802_11WEPNotSupported,
+       Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
+       Ndis802_11Encryption2Enabled,
+       Ndis802_11Encryption2KeyAbsent,
+       Ndis802_11Encryption3Enabled,
+       Ndis802_11Encryption3KeyAbsent
+};
+
+enum NDIS_802_11_PRIVACY_FILTER {
+       Ndis802_11PrivFilterAcceptAll,
+       Ndis802_11PrivFilter8021xWEP
+};
+
+struct NDIS_WLAN_BSSID_EX {
+       __le32 Length;
+       u8 MacAddress[6];
+       u8 Padding[2];
+       struct NDIS_802_11_SSID Ssid;
+       __le32 Privacy;
+       __le32 Rssi;
+       enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
+       struct NDIS_802_11_CONFIGURATION Configuration;
+       enum NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
+       u8 SupportedRates[NDIS_802_11_LENGTH_RATES_EX];
+       __le32 IELength;
+       u8 IEs[0];
+} __attribute__((packed));
+
+struct NDIS_802_11_BSSID_LIST_EX {
+       __le32 NumberOfItems;
+       struct NDIS_WLAN_BSSID_EX Bssid[0];
+} __attribute__((packed));
+
+struct NDIS_802_11_FIXED_IEs {
+       u8 Timestamp[8];
+       __le16 BeaconInterval;
+       __le16 Capabilities;
+} __attribute__((packed));
+
+struct NDIS_802_11_WEP {
+       __le32 Length;
+       __le32 KeyIndex;
+       __le32 KeyLength;
+       u8 KeyMaterial[32];
+} __attribute__((packed));
+
+struct NDIS_802_11_KEY {
+       __le32 Length;
+       __le32 KeyIndex;
+       __le32 KeyLength;
+       u8 Bssid[6];
+       u8 Padding[6];
+       __le64 KeyRSC;
+       u8 KeyMaterial[32];
+} __attribute__((packed));
+
+struct NDIS_802_11_REMOVE_KEY {
+       __le32 Length;
+       __le32 KeyIndex;
+       u8 Bssid[6];
+} __attribute__((packed));
+
+struct RNDIS_CONFIG_PARAMETER_INFOBUFFER {
+       __le32 ParameterNameOffset;
+       __le32 ParameterNameLength;
+       __le32 ParameterType;
+       __le32 ParameterValueOffset;
+       __le32 ParameterValueLength;
+} __attribute__((packed));
+
+/* these have to match what is in wpa_supplicant */
+enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
+enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, CIPHER_WEP104 }
+       wpa_cipher;
+enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, KEY_MGMT_802_1X_NO_WPA,
+       KEY_MGMT_WPA_NONE } wpa_key_mgmt;
+
+/*
+ *  private data
+ */
+#define NET_TYPE_11FB  0
+
+#define CAP_MODE_80211A                1
+#define CAP_MODE_80211B                2
+#define CAP_MODE_80211G                4
+#define CAP_MODE_MASK          7
+#define CAP_SUPPORT_TXPOWER    8
+
+#define WORK_CONNECTION_EVENT  (1<<0)
+#define WORK_SET_MULTICAST_LIST        (1<<1)
+
+/* RNDIS device private data */
+struct rndis_wext_private {
+       char name[32];
+
+       struct usbnet *usbdev;
+
+       struct workqueue_struct *workqueue;
+       struct delayed_work stats_work;
+       struct work_struct work;
+       struct mutex command_lock;
+       spinlock_t stats_lock;
+       unsigned long work_pending;
+
+       struct iw_statistics iwstats;
+       struct iw_statistics privstats;
+
+       int  nick_len;
+       char nick[32];
+
+       int caps;
+       int multicast_size;
+
+       /* module parameters */
+       char param_country[4];
+       int  param_frameburst;
+       int  param_afterburner;
+       int  param_power_save;
+       int  param_power_output;
+       int  param_roamtrigger;
+       int  param_roamdelta;
+       u32  param_workaround_interval;
+
+       /* hardware state */
+       int radio_on;
+       int infra_mode;
+       struct NDIS_802_11_SSID essid;
+
+       /* encryption stuff */
+       int  encr_tx_key_index;
+       char encr_keys[4][32];
+       int  encr_key_len[4];
+       int  wpa_version;
+       int  wpa_keymgmt;
+       int  wpa_authalg;
+       int  wpa_ie_len;
+       u8  *wpa_ie;
+       int  wpa_cipher_pair;
+       int  wpa_cipher_group;
+};
+
+
+static const int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+                               2447, 2452, 2457, 2462, 2467, 2472, 2484 };
+
+static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 };
+
+static const int bcm4320_power_output[4] = { 25, 50, 75, 100 };
+
+static const unsigned char zero_bssid[ETH_ALEN] = {0,};
+static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff,
+                                                       0xff, 0xff, 0xff };
+
+
+static struct rndis_wext_private *get_rndis_wext_priv(struct usbnet *dev)
+{
+       return (struct rndis_wext_private *)dev->driver_priv;
+}
+
+
+static u32 get_bcm4320_power(struct rndis_wext_private *priv)
+{
+       return BCM4320_DEFAULT_TXPOWER *
+               bcm4320_power_output[priv->param_power_output] / 100;
+}
+
+
+/* translate error code */
+static int rndis_error_status(__le32 rndis_status)
+{
+       int ret = -EINVAL;
+       switch (rndis_status) {
+       case RNDIS_STATUS_SUCCESS:
+               ret = 0;
+               break;
+       case RNDIS_STATUS_FAILURE:
+       case RNDIS_STATUS_INVALID_DATA:
+               ret = -EINVAL;
+               break;
+       case RNDIS_STATUS_NOT_SUPPORTED:
+               ret = -EOPNOTSUPP;
+               break;
+       case RNDIS_STATUS_ADAPTER_NOT_READY:
+       case RNDIS_STATUS_ADAPTER_NOT_OPEN:
+               ret = -EBUSY;
+               break;
+       }
+       return ret;
+}
+
+
+static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+       union {
+               void                    *buf;
+               struct rndis_msg_hdr    *header;
+               struct rndis_query      *get;
+               struct rndis_query_c    *get_c;
+       } u;
+       int ret, buflen;
+
+       buflen = *len + sizeof(*u.get);
+       if (buflen < CONTROL_BUFFER_SIZE)
+               buflen = CONTROL_BUFFER_SIZE;
+       u.buf = kmalloc(buflen, GFP_KERNEL);
+       if (!u.buf)
+               return -ENOMEM;
+       memset(u.get, 0, sizeof *u.get);
+       u.get->msg_type = RNDIS_MSG_QUERY;
+       u.get->msg_len = ccpu2(sizeof *u.get);
+       u.get->oid = oid;
+
+       mutex_lock(&priv->command_lock);
+       ret = rndis_command(dev, u.header);
+       mutex_unlock(&priv->command_lock);
+
+       if (ret == 0) {
+               ret = le32_to_cpu(u.get_c->len);
+               *len = (*len > ret) ? ret : *len;
+               memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len);
+               ret = rndis_error_status(u.get_c->status);
+       }
+
+       kfree(u.buf);
+       return ret;
+}
+
+
+static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+       union {
+               void                    *buf;
+               struct rndis_msg_hdr    *header;
+               struct rndis_set        *set;
+               struct rndis_set_c      *set_c;
+       } u;
+       int ret, buflen;
+
+       buflen = len + sizeof(*u.set);
+       if (buflen < CONTROL_BUFFER_SIZE)
+               buflen = CONTROL_BUFFER_SIZE;
+       u.buf = kmalloc(buflen, GFP_KERNEL);
+       if (!u.buf)
+               return -ENOMEM;
+
+       memset(u.set, 0, sizeof *u.set);
+       u.set->msg_type = RNDIS_MSG_SET;
+       u.set->msg_len = cpu_to_le32(sizeof(*u.set) + len);
+       u.set->oid = oid;
+       u.set->len = cpu_to_le32(len);
+       u.set->offset = ccpu2(sizeof(*u.set) - 8);
+       u.set->handle = ccpu2(0);
+       memcpy(u.buf + sizeof(*u.set), data, len);
+
+       mutex_lock(&priv->command_lock);
+       ret = rndis_command(dev, u.header);
+       mutex_unlock(&priv->command_lock);
+
+       if (ret == 0)
+               ret = rndis_error_status(u.set_c->status);
+
+       kfree(u.buf);
+       return ret;
+}
+
+
+/*
+ * Specs say that we can only set config parameters only soon after device
+ * initialization.
+ *   value_type: 0 = u32, 2 = unicode string
+ */
+static int rndis_set_config_parameter(struct usbnet *dev, char *param,
+                                               int value_type, void *value)
+{
+       struct RNDIS_CONFIG_PARAMETER_INFOBUFFER *infobuf;
+       int value_len, info_len, param_len, ret, i;
+       __le16 *unibuf;
+       __le32 *dst_value;
+
+       if (value_type == 0)
+               value_len = sizeof(__le32);
+       else if (value_type == 2)
+               value_len = strlen(value) * sizeof(__le16);
+       else
+               return -EINVAL;
+
+       param_len = strlen(param) * sizeof(__le16);
+       info_len = sizeof(*infobuf) + param_len + value_len;
+
+#ifdef DEBUG
+       info_len += 12;
+#endif
+       infobuf = kmalloc(info_len, GFP_KERNEL);
+       if (!infobuf)
+               return -ENOMEM;
+
+#ifdef DEBUG
+       info_len -= 12;
+       /* extra 12 bytes are for padding (debug output) */
+       memset(infobuf, 0xCC, info_len + 12);
+#endif
+
+       if (value_type == 2)
+               devdbg(dev, "setting config parameter: %s, value: %s",
+                                               param, (u8 *)value);
+       else
+               devdbg(dev, "setting config parameter: %s, value: %d",
+                                               param, *(u32 *)value);
+
+       infobuf->ParameterNameOffset = cpu_to_le32(sizeof(*infobuf));
+       infobuf->ParameterNameLength = cpu_to_le32(param_len);
+       infobuf->ParameterType = cpu_to_le32(value_type);
+       infobuf->ParameterValueOffset = cpu_to_le32(sizeof(*infobuf) +
+                                                               param_len);
+       infobuf->ParameterValueLength = cpu_to_le32(value_len);
+
+       /* simple string to unicode string conversion */
+       unibuf = (void *)infobuf + sizeof(*infobuf);
+       for (i = 0; i < param_len / sizeof(__le16); i++)
+               unibuf[i] = cpu_to_le16(param[i]);
+
+       if (value_type == 2) {
+               unibuf = (void *)infobuf + sizeof(*infobuf) + param_len;
+               for (i = 0; i < value_len / sizeof(__le16); i++)
+                       unibuf[i] = cpu_to_le16(((u8 *)value)[i]);
+       } else {
+               dst_value = (void *)infobuf + sizeof(*infobuf) + param_len;
+               *dst_value = cpu_to_le32(*(u32 *)value);
+       }
+
+#ifdef DEBUG
+       devdbg(dev, "info buffer (len: %d):", info_len);
+       for (i = 0; i < info_len; i += 12) {
+               u32 *tmp = (u32 *)((u8 *)infobuf + i);
+               devdbg(dev, "%08X:%08X:%08X",
+                       cpu_to_be32(tmp[0]),
+                       cpu_to_be32(tmp[1]),
+                       cpu_to_be32(tmp[2]));
+       }
+#endif
+
+       ret = rndis_set_oid(dev, OID_GEN_RNDIS_CONFIG_PARAMETER,
+                                                       infobuf, info_len);
+       if (ret != 0)
+               devdbg(dev, "setting rndis config paramater failed, %d.", ret);
+
+       kfree(infobuf);
+       return ret;
+}
+
+static int rndis_set_config_parameter_str(struct usbnet *dev,
+                                               char *param, char *value)
+{
+       return(rndis_set_config_parameter(dev, param, 2, value));
+}
+
+/*static int rndis_set_config_parameter_u32(struct usbnet *dev,
+                                               char *param, u32 value)
+{
+       return(rndis_set_config_parameter(dev, param, 0, &value));
+}*/
+
+
+/*
+ * data conversion functions
+ */
+static int level_to_qual(int level)
+{
+       int qual = 100 * (level - WL_NOISE) / (WL_SIGMAX - WL_NOISE);
+       return qual >= 0 ? (qual <= 100 ? qual : 100) : 0;
+}
+
+
+static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq)
+{
+       freq->e = 0;
+       freq->i = 0;
+       freq->flags = 0;
+
+       /* see comment in wireless.h above the "struct iw_freq"
+        * definition for an explanation of this if
+        * NOTE: 1000000 is due to the kHz
+        */
+       if (dsconfig > 1000000) {
+               freq->m = dsconfig / 10;
+               freq->e = 1;
+       } else
+               freq->m = dsconfig;
+
+       /* convert from kHz to Hz */
+       freq->e += 3;
+}
+
+
+static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
+{
+       if (freq->m < 1000 && freq->e == 0) {
+               if (freq->m >= 1 &&
+                       freq->m <= (sizeof(freq_chan) / sizeof(freq_chan[0])))
+                       *dsconfig = freq_chan[freq->m - 1] * 1000;
+               else
+                       return -1;
+       } else {
+               int i;
+               *dsconfig = freq->m;
+               for (i = freq->e; i > 0; i--)
+                       *dsconfig *= 10;
+               *dsconfig /= 1000;
+       }
+
+       return 0;
+}
+
+
+/*
+ * common functions
+ */
+static int
+add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index);
+
+static int get_essid(struct usbnet *usbdev, struct NDIS_802_11_SSID *ssid)
+{
+       int ret, len;
+
+       len = sizeof(*ssid);
+       ret = rndis_query_oid(usbdev, OID_802_11_SSID, ssid, &len);
+
+       if (ret != 0)
+               ssid->SsidLength = 0;
+
+#ifdef DEBUG
+       {
+               unsigned char tmp[NDIS_802_11_LENGTH_SSID + 1];
+
+               memcpy(tmp, ssid->Ssid, le32_to_cpu(ssid->SsidLength));
+               tmp[le32_to_cpu(ssid->SsidLength)] = 0;
+               devdbg(usbdev, "get_essid: '%s', ret: %d", tmp, ret);
+       }
+#endif
+       return ret;
+}
+
+
+static int set_essid(struct usbnet *usbdev, struct NDIS_802_11_SSID *ssid)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       int ret;
+
+       ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid));
+       if (ret == 0) {
+               memcpy(&priv->essid, ssid, sizeof(priv->essid));
+               priv->radio_on = 1;
+               devdbg(usbdev, "set_essid: radio_on = 1");
+       }
+
+       return ret;
+}
+
+
+static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
+{
+       int ret, len;
+
+       len = ETH_ALEN;
+       ret = rndis_query_oid(usbdev, OID_802_11_BSSID, bssid, &len);
+
+       if (ret != 0)
+               memset(bssid, 0, ETH_ALEN);
+
+       return ret;
+}
+
+
+static int is_associated(struct usbnet *usbdev)
+{
+       u8 bssid[ETH_ALEN];
+       int ret;
+
+       ret = get_bssid(usbdev, bssid);
+
+       return(ret == 0 && memcmp(bssid, zero_bssid, ETH_ALEN) != 0);
+}
+
+
+static int disassociate(struct usbnet *usbdev, int reset_ssid)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct NDIS_802_11_SSID ssid;
+       int i, ret = 0;
+
+       if (priv->radio_on) {
+               ret = rndis_set_oid(usbdev, OID_802_11_DISASSOCIATE, NULL, 0);
+               if (ret == 0) {
+                       priv->radio_on = 0;
+                       devdbg(usbdev, "disassociate: radio_on = 0");
+
+                       if (reset_ssid)
+                               msleep(100);
+               }
+       }
+
+       /* disassociate causes radio to be turned off; if reset_ssid
+        * is given, set random ssid to enable radio */
+       if (reset_ssid) {
+               ssid.SsidLength = cpu_to_le32(sizeof(ssid.Ssid));
+               get_random_bytes(&ssid.Ssid[2], sizeof(ssid.Ssid)-2);
+               ssid.Ssid[0] = 0x1;
+               ssid.Ssid[1] = 0xff;
+               for (i = 2; i < sizeof(ssid.Ssid); i++)
+                       ssid.Ssid[i] = 0x1 + (ssid.Ssid[i] * 0xfe / 0xff);
+               ret = set_essid(usbdev, &ssid);
+       }
+       return ret;
+}
+
+
+static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       __le32 tmp;
+       int auth_mode, ret;
+
+       devdbg(usbdev, "set_auth_mode: wpa_version=0x%x authalg=0x%x "
+               "keymgmt=0x%x", wpa_version, authalg, priv->wpa_keymgmt);
+
+       if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) {
+               if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
+                       auth_mode = Ndis802_11AuthModeWPA2;
+               else
+                       auth_mode = Ndis802_11AuthModeWPA2PSK;
+       } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) {
+               if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
+                       auth_mode = Ndis802_11AuthModeWPA;
+               else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK)
+                       auth_mode = Ndis802_11AuthModeWPAPSK;
+               else
+                       auth_mode = Ndis802_11AuthModeWPANone;
+       } else if (authalg & IW_AUTH_ALG_SHARED_KEY) {
+               if (authalg & IW_AUTH_ALG_OPEN_SYSTEM)
+                       auth_mode = Ndis802_11AuthModeAutoSwitch;
+               else
+                       auth_mode = Ndis802_11AuthModeShared;
+       } else
+               auth_mode = Ndis802_11AuthModeOpen;
+
+       tmp = cpu_to_le32(auth_mode);
+       ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp,
+                                                               sizeof(tmp));
+       if (ret != 0) {
+               devwarn(usbdev, "setting auth mode failed (%08X)", ret);
+               return ret;
+       }
+
+       priv->wpa_version = wpa_version;
+       priv->wpa_authalg = authalg;
+       return 0;
+}
+
+
+static int set_priv_filter(struct usbnet *usbdev)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       __le32 tmp;
+
+       devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version);
+
+       if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 ||
+           priv->wpa_version & IW_AUTH_WPA_VERSION_WPA)
+               tmp = cpu_to_le32(Ndis802_11PrivFilter8021xWEP);
+       else
+               tmp = cpu_to_le32(Ndis802_11PrivFilterAcceptAll);
+
+       return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp,
+                                                               sizeof(tmp));
+}
+
+
+static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       __le32 tmp;
+       int encr_mode, ret;
+
+       devdbg(usbdev, "set_encr_mode: cipher_pair=0x%x cipher_group=0x%x",
+               pairwise,
+               groupwise);
+
+       if (pairwise & IW_AUTH_CIPHER_CCMP)
+               encr_mode = Ndis802_11Encryption3Enabled;
+       else if (pairwise & IW_AUTH_CIPHER_TKIP)
+               encr_mode = Ndis802_11Encryption2Enabled;
+       else if (pairwise &
+                (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
+               encr_mode = Ndis802_11Encryption1Enabled;
+       else if (groupwise & IW_AUTH_CIPHER_CCMP)
+               encr_mode = Ndis802_11Encryption3Enabled;
+       else if (groupwise & IW_AUTH_CIPHER_TKIP)
+               encr_mode = Ndis802_11Encryption2Enabled;
+       else
+               encr_mode = Ndis802_11EncryptionDisabled;
+
+       tmp = cpu_to_le32(encr_mode);
+       ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp,
+                                                               sizeof(tmp));
+       if (ret != 0) {
+               devwarn(usbdev, "setting encr mode failed (%08X)", ret);
+               return ret;
+       }
+
+       priv->wpa_cipher_pair = pairwise;
+       priv->wpa_cipher_group = groupwise;
+       return 0;
+}
+
+
+static int set_assoc_params(struct usbnet *usbdev)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+       set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg);
+       set_priv_filter(usbdev);
+       set_encr_mode(usbdev, priv->wpa_cipher_pair, priv->wpa_cipher_group);
+
+       return 0;
+}
+
+
+static int set_infra_mode(struct usbnet *usbdev, int mode)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       __le32 tmp;
+       int ret, i;
+
+       devdbg(usbdev, "set_infra_mode: infra_mode=0x%x", priv->infra_mode);
+
+       tmp = cpu_to_le32(mode);
+       ret = rndis_set_oid(usbdev, OID_802_11_INFRASTRUCTURE_MODE, &tmp,
+                                                               sizeof(tmp));
+       if (ret != 0) {
+               devwarn(usbdev, "setting infra mode failed (%08X)", ret);
+               return ret;
+       }
+
+       /* NDIS drivers clear keys when infrastructure mode is
+        * changed. But Linux tools assume otherwise. So set the
+        * keys */
+       if (priv->wpa_keymgmt == 0 ||
+               priv->wpa_keymgmt == IW_AUTH_KEY_MGMT_802_1X) {
+               for (i = 0; i < 4; i++) {
+                       if (priv->encr_key_len[i] > 0)
+                               add_wep_key(usbdev, priv->encr_keys[i],
+                                               priv->encr_key_len[i], i);
+               }
+       }
+
+       priv->infra_mode = mode;
+       return 0;
+}
+
+
+static void set_default_iw_params(struct usbnet *usbdev)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+       priv->wpa_keymgmt = 0;
+       priv->wpa_version = 0;
+
+       set_infra_mode(usbdev, Ndis802_11Infrastructure);
+       set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
+                               IW_AUTH_ALG_OPEN_SYSTEM);
+       set_priv_filter(usbdev);
+       set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE);
+}
+
+
+static int deauthenticate(struct usbnet *usbdev)
+{
+       int ret;
+
+       ret = disassociate(usbdev, 1);
+       set_default_iw_params(usbdev);
+       return ret;
+}
+
+
+/* index must be 0 - N, as per NDIS  */
+static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct NDIS_802_11_WEP ndis_key;
+       int ret;
+
+       if (key_len <= 0 || key_len > 32 || index < 0 || index >= 4)
+               return -EINVAL;
+
+       memset(&ndis_key, 0, sizeof(ndis_key));
+
+       ndis_key.Length = cpu_to_le32(sizeof(ndis_key));
+       ndis_key.KeyLength = cpu_to_le32(key_len);
+       ndis_key.KeyIndex = cpu_to_le32(index);
+       memcpy(&ndis_key.KeyMaterial, key, key_len);
+
+       if (index == priv->encr_tx_key_index) {
+               ndis_key.KeyIndex |= cpu_to_le32(1 << 31);
+               ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104,
+                                               IW_AUTH_CIPHER_NONE);
+               if (ret)
+                       devwarn(usbdev, "encryption couldn't be enabled (%08X)",
+                                                                       ret);
+       }
+
+       ret = rndis_set_oid(usbdev, OID_802_11_ADD_WEP, &ndis_key,
+                                                       sizeof(ndis_key));
+       if (ret != 0) {
+               devwarn(usbdev, "adding encryption key %d failed (%08X)",
+                                                       index+1, ret);
+               return ret;
+       }
+
+       priv->encr_key_len[index] = key_len;
+       memcpy(&priv->encr_keys[index], key, key_len);
+
+       return 0;
+}
+
+
+/* remove_key is for both wep and wpa */
+static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct NDIS_802_11_REMOVE_KEY remove_key;
+       __le32 keyindex;
+       int ret;
+
+       if (priv->encr_key_len[index] == 0)
+               return 0;
+
+       priv->encr_key_len[index] = 0;
+       memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index]));
+
+       if (priv->wpa_cipher_pair == IW_AUTH_CIPHER_TKIP ||
+           priv->wpa_cipher_pair == IW_AUTH_CIPHER_CCMP ||
+           priv->wpa_cipher_group == IW_AUTH_CIPHER_TKIP ||
+           priv->wpa_cipher_group == IW_AUTH_CIPHER_CCMP) {
+               remove_key.Length = cpu_to_le32(sizeof(remove_key));
+               remove_key.KeyIndex = cpu_to_le32(index);
+               if (bssid) {
+                       /* pairwise key */
+                       if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0)
+                               remove_key.KeyIndex |= cpu_to_le32(1 << 30);
+                       memcpy(remove_key.Bssid, bssid,
+                                       sizeof(remove_key.Bssid));
+               } else
+                       memset(remove_key.Bssid, 0xff,
+                                               sizeof(remove_key.Bssid));
+
+               ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_KEY, &remove_key,
+                                                       sizeof(remove_key));
+               if (ret != 0)
+                       return ret;
+       } else {
+               keyindex = cpu_to_le32(index);
+               ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_WEP, &keyindex,
+                                                       sizeof(keyindex));
+               if (ret != 0) {
+                       devwarn(usbdev,
+                               "removing encryption key %d failed (%08X)",
+                               index, ret);
+                       return ret;
+               }
+       }
+
+       /* if it is transmit key, disable encryption */
+       if (index == priv->encr_tx_key_index)
+               set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE);
+
+       return 0;
+}
+
+
+static void set_multicast_list(struct usbnet *usbdev)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct dev_mc_list *mclist;
+       __le32 filter;
+       int ret, i, size;
+       char *buf;
+
+       filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
+
+       if (usbdev->net->flags & IFF_PROMISC) {
+               filter |= RNDIS_PACKET_TYPE_PROMISCUOUS |
+                       RNDIS_PACKET_TYPE_ALL_LOCAL;
+       } else if (usbdev->net->flags & IFF_ALLMULTI ||
+                  usbdev->net->mc_count > priv->multicast_size) {
+               filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
+       } else if (usbdev->net->mc_count > 0) {
+               size = min(priv->multicast_size, usbdev->net->mc_count);
+               buf = kmalloc(size * ETH_ALEN, GFP_KERNEL);
+               if (!buf) {
+                       devwarn(usbdev,
+                               "couldn't alloc %d bytes of memory",
+                               size * ETH_ALEN);
+                       return;
+               }
+
+               mclist = usbdev->net->mc_list;
+               for (i = 0; i < size && mclist; mclist = mclist->next) {
+                       if (mclist->dmi_addrlen != ETH_ALEN)
+                               continue;
+
+                       memcpy(buf + i * ETH_ALEN, mclist->dmi_addr, ETH_ALEN);
+                       i++;
+               }
+
+               ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf,
+                                                               i * ETH_ALEN);
+               if (ret == 0 && i > 0)
+                       filter |= RNDIS_PACKET_TYPE_MULTICAST;
+               else
+                       filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
+
+               devdbg(usbdev, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d",
+                                               i, priv->multicast_size, ret);
+
+               kfree(buf);
+       }
+
+       ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
+                                                       sizeof(filter));
+       if (ret < 0) {
+               devwarn(usbdev, "couldn't set packet filter: %08x",
+                                                       le32_to_cpu(filter));
+       }
+
+       devdbg(usbdev, "OID_GEN_CURRENT_PACKET_FILTER(%08x) -> %d",
+                                               le32_to_cpu(filter), ret);
+}
+
+
+/*
+ * wireless extension handlers
+ */
+
+static int rndis_iw_commit(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       /* dummy op */
+       return 0;
+}
+
+
+static int rndis_iw_get_range(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct iw_range *range = (struct iw_range *)extra;
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       int len, ret, i, j, num, has_80211g_rates;
+       u8 rates[8];
+       __le32 tx_power;
+
+       devdbg(usbdev, "SIOCGIWRANGE");
+
+       /* clear iw_range struct */
+       memset(range, 0, sizeof(*range));
+       wrqu->data.length = sizeof(*range);
+
+       range->txpower_capa = IW_TXPOW_MWATT;
+       range->num_txpower = 1;
+       if (priv->caps & CAP_SUPPORT_TXPOWER) {
+               len = sizeof(tx_power);
+               ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
+                                               &tx_power, &len);
+               if (ret == 0 && le32_to_cpu(tx_power) != 0xFF)
+                       range->txpower[0] = le32_to_cpu(tx_power);
+               else
+                       range->txpower[0] = get_bcm4320_power(priv);
+       } else
+               range->txpower[0] = get_bcm4320_power(priv);
+
+       len = sizeof(rates);
+       ret = rndis_query_oid(usbdev, OID_802_11_SUPPORTED_RATES, &rates,
+                                                               &len);
+       has_80211g_rates = 0;
+       if (ret == 0) {
+               j = 0;
+               for (i = 0; i < len; i++) {
+                       if (rates[i] == 0)
+                               break;
+                       range->bitrate[j] = (rates[i] & 0x7f) * 500000;
+                       /* check for non 802.11b rates */
+                       if (range->bitrate[j] == 6000000 ||
+                               range->bitrate[j] == 9000000 ||
+                               (range->bitrate[j] >= 12000000 &&
+                               range->bitrate[j] != 22000000))
+                               has_80211g_rates = 1;
+                       j++;
+               }
+               range->num_bitrates = j;
+       } else
+               range->num_bitrates = 0;
+
+       /* fill in 802.11g rates */
+       if (has_80211g_rates) {
+               num = range->num_bitrates;
+               for (i = 0; i < sizeof(rates_80211g); i++) {
+                       for (j = 0; j < num; j++) {
+                               if (range->bitrate[j] ==
+                                       rates_80211g[i] * 1000000)
+                                       break;
+                       }
+                       if (j == num)
+                               range->bitrate[range->num_bitrates++] =
+                                       rates_80211g[i] * 1000000;
+                       if (range->num_bitrates == IW_MAX_BITRATES)
+                               break;
+               }
+
+               /* estimated max real througput in bps */
+               range->throughput = 54 * 1000 * 1000 / 2;
+
+               /* ~35% more with afterburner */
+               if (priv->param_afterburner)
+                       range->throughput = range->throughput / 100 * 135;
+       } else {
+               /* estimated max real througput in bps */
+               range->throughput = 11 * 1000 * 1000 / 2;
+       }
+
+       range->num_channels = (sizeof(freq_chan)/sizeof(freq_chan[0]));
+
+       for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])) &&
+                       i < IW_MAX_FREQUENCIES; i++) {
+               range->freq[i].i = i + 1;
+               range->freq[i].m = freq_chan[i] * 100000;
+               range->freq[i].e = 1;
+       }
+       range->num_frequency = i;
+
+       range->min_rts = 0;
+       range->max_rts = 2347;
+       range->min_frag = 256;
+       range->max_frag = 2346;
+
+       range->max_qual.qual = 100;
+       range->max_qual.level = 154;
+       range->max_qual.updated = IW_QUAL_QUAL_UPDATED
+                               | IW_QUAL_LEVEL_UPDATED
+                               | IW_QUAL_NOISE_INVALID;
+
+       range->we_version_compiled = WIRELESS_EXT;
+       range->we_version_source = WIRELESS_EXT;
+
+       range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+                       IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+       return 0;
+}
+
+
+static int rndis_iw_get_name(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+       strcpy(wrqu->name, priv->name);
+       return 0;
+}
+
+
+static int rndis_iw_set_essid(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
+{
+       struct NDIS_802_11_SSID ssid;
+       int length = wrqu->essid.length;
+       struct usbnet *usbdev = dev->priv;
+
+       devdbg(usbdev, "SIOCSIWESSID: [flags:%d,len:%d] '%.32s'",
+               wrqu->essid.flags, wrqu->essid.length, essid);
+
+       if (length > NDIS_802_11_LENGTH_SSID)
+               length = NDIS_802_11_LENGTH_SSID;
+
+       ssid.SsidLength = cpu_to_le32(length);
+       if (length > 0)
+               memcpy(ssid.Ssid, essid, length);
+       else
+               memset(ssid.Ssid, 0, NDIS_802_11_LENGTH_SSID);
+
+       set_assoc_params(usbdev);
+
+       if (!wrqu->essid.flags || length == 0)
+               return disassociate(usbdev, 1);
+       else
+               return set_essid(usbdev, &ssid);
+}
+
+
+static int rndis_iw_get_essid(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
+{
+       struct NDIS_802_11_SSID ssid;
+       struct usbnet *usbdev = dev->priv;
+       int ret;
+
+       ret = get_essid(usbdev, &ssid);
+
+       if (ret == 0 && le32_to_cpu(ssid.SsidLength) > 0) {
+               wrqu->essid.flags = 1;
+               wrqu->essid.length = le32_to_cpu(ssid.SsidLength);
+               memcpy(essid, ssid.Ssid, wrqu->essid.length);
+               essid[wrqu->essid.length] = 0;
+       } else {
+               memset(essid, 0, sizeof(NDIS_802_11_LENGTH_SSID));
+               wrqu->essid.flags = 0;
+               wrqu->essid.length = 0;
+       }
+       devdbg(usbdev, "SIOCGIWESSID: %s", essid);
+       return ret;
+}
+
+
+static int rndis_iw_get_bssid(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       unsigned char bssid[ETH_ALEN];
+       int ret;
+       DECLARE_MAC_BUF(mac);
+
+       ret = get_bssid(usbdev, bssid);
+
+       if (ret == 0)
+               devdbg(usbdev, "SIOCGIWAP: %s", print_mac(mac, bssid));
+       else
+               devdbg(usbdev, "SIOCGIWAP: <not associated>");
+
+       wrqu->ap_addr.sa_family = ARPHRD_ETHER;
+       memcpy(wrqu->ap_addr.sa_data, bssid, ETH_ALEN);
+
+       return ret;
+}
+
+
+static int rndis_iw_set_bssid(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       u8 *bssid = (u8 *)wrqu->ap_addr.sa_data;
+       DECLARE_MAC_BUF(mac);
+       int ret;
+
+       devdbg(usbdev, "SIOCSIWAP: %s", print_mac(mac, bssid));
+
+       ret = rndis_set_oid(usbdev, OID_802_11_BSSID, bssid, ETH_ALEN);
+
+       /* user apps may set ap's mac address, which is not required;
+        * they may fail to work if this function fails, so return
+        * success */
+       if (ret)
+               devwarn(usbdev, "setting AP mac address failed (%08X)", ret);
+
+       return 0;
+}
+
+
+static int rndis_iw_set_auth(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct iw_param *p = &wrqu->param;
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       int ret = -ENOTSUPP;
+
+       switch (p->flags & IW_AUTH_INDEX) {
+       case IW_AUTH_WPA_VERSION:
+               devdbg(usbdev, "SIOCSIWAUTH: WPA_VERSION, %08x", p->value);
+               priv->wpa_version = p->value;
+               ret = 0;
+               break;
+
+       case IW_AUTH_CIPHER_PAIRWISE:
+               devdbg(usbdev, "SIOCSIWAUTH: CIPHER_PAIRWISE, %08x", p->value);
+               priv->wpa_cipher_pair = p->value;
+               ret = 0;
+               break;
+
+       case IW_AUTH_CIPHER_GROUP:
+               devdbg(usbdev, "SIOCSIWAUTH: CIPHER_GROUP, %08x", p->value);
+               priv->wpa_cipher_group = p->value;
+               ret = 0;
+               break;
+
+       case IW_AUTH_KEY_MGMT:
+               devdbg(usbdev, "SIOCSIWAUTH: KEY_MGMT, %08x", p->value);
+               priv->wpa_keymgmt = p->value;
+               ret = 0;
+               break;
+
+       case IW_AUTH_TKIP_COUNTERMEASURES:
+               devdbg(usbdev, "SIOCSIWAUTH: TKIP_COUNTERMEASURES, %08x",
+                                                               p->value);
+               ret = 0;
+               break;
+
+       case IW_AUTH_DROP_UNENCRYPTED:
+               devdbg(usbdev, "SIOCSIWAUTH: DROP_UNENCRYPTED, %08x", p->value);
+               ret = 0;
+               break;
+
+       case IW_AUTH_80211_AUTH_ALG:
+               devdbg(usbdev, "SIOCSIWAUTH: 80211_AUTH_ALG, %08x", p->value);
+               priv->wpa_authalg = p->value;
+               ret = 0;
+               break;
+
+       case IW_AUTH_WPA_ENABLED:
+               devdbg(usbdev, "SIOCSIWAUTH: WPA_ENABLED, %08x", p->value);
+               if (wrqu->param.value)
+                       deauthenticate(usbdev);
+               ret = 0;
+               break;
+
+       case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+               devdbg(usbdev, "SIOCSIWAUTH: RX_UNENCRYPTED_EAPOL, %08x",
+                                                               p->value);
+               ret = 0;
+               break;
+
+       case IW_AUTH_ROAMING_CONTROL:
+               devdbg(usbdev, "SIOCSIWAUTH: ROAMING_CONTROL, %08x", p->value);
+               ret = 0;
+               break;
+
+       case IW_AUTH_PRIVACY_INVOKED:
+               devdbg(usbdev, "SIOCSIWAUTH: invalid cmd %d",
+                               wrqu->param.flags & IW_AUTH_INDEX);
+               return -EOPNOTSUPP;
+
+       default:
+               devdbg(usbdev, "SIOCSIWAUTH: UNKNOWN  %08x, %08x",
+                       p->flags & IW_AUTH_INDEX, p->value);
+       }
+       return ret;
+}
+
+
+static int rndis_iw_get_auth(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct iw_param *p = &wrqu->param;
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+       switch (p->flags & IW_AUTH_INDEX) {
+       case IW_AUTH_WPA_VERSION:
+               p->value = priv->wpa_version;
+               break;
+       case IW_AUTH_CIPHER_PAIRWISE:
+               p->value = priv->wpa_cipher_pair;
+               break;
+       case IW_AUTH_CIPHER_GROUP:
+               p->value = priv->wpa_cipher_group;
+               break;
+       case IW_AUTH_KEY_MGMT:
+               p->value = priv->wpa_keymgmt;
+               break;
+       case IW_AUTH_80211_AUTH_ALG:
+               p->value = priv->wpa_authalg;
+               break;
+       default:
+               devdbg(usbdev, "SIOCGIWAUTH: invalid cmd %d",
+                               wrqu->param.flags & IW_AUTH_INDEX);
+               return -EOPNOTSUPP;
+       }
+       return 0;
+}
+
+
+static int rndis_iw_get_mode(struct net_device *dev,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+       switch (priv->infra_mode) {
+       case Ndis802_11IBSS:
+               wrqu->mode = IW_MODE_ADHOC;
+               break;
+       case Ndis802_11Infrastructure:
+               wrqu->mode = IW_MODE_INFRA;
+               break;
+       /*case Ndis802_11AutoUnknown:*/
+       default:
+               wrqu->mode = IW_MODE_AUTO;
+               break;
+       }
+       devdbg(usbdev, "SIOCGIWMODE: %08x", wrqu->mode);
+       return 0;
+}
+
+
+static int rndis_iw_set_mode(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       int mode;
+
+       devdbg(usbdev, "SIOCSIWMODE: %08x", wrqu->mode);
+
+       switch (wrqu->mode) {
+       case IW_MODE_ADHOC:
+               mode = Ndis802_11IBSS;
+               break;
+       case IW_MODE_INFRA:
+               mode = Ndis802_11Infrastructure;
+               break;
+       /*case IW_MODE_AUTO:*/
+       default:
+               mode = Ndis802_11AutoUnknown;
+               break;
+       }
+
+       return set_infra_mode(usbdev, mode);
+}
+
+
+static int rndis_iw_set_encode(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       int ret, index, key_len;
+       u8 *key;
+
+       index = (wrqu->encoding.flags & IW_ENCODE_INDEX);
+
+       /* iwconfig gives index as 1 - N */
+       if (index > 0)
+               index--;
+       else
+               index = priv->encr_tx_key_index;
+
+       if (index < 0 || index >= 4) {
+               devwarn(usbdev, "encryption index out of range (%u)", index);
+               return -EINVAL;
+       }
+
+       /* remove key if disabled */
+       if (wrqu->data.flags & IW_ENCODE_DISABLED) {
+               if (remove_key(usbdev, index, NULL))
+                       return -EINVAL;
+               else
+                       return 0;
+       }
+
+       /* global encryption state (for all keys) */
+       if (wrqu->data.flags & IW_ENCODE_OPEN)
+               ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
+                                               IW_AUTH_ALG_OPEN_SYSTEM);
+       else /*if (wrqu->data.flags & IW_ENCODE_RESTRICTED)*/
+               ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
+                                               IW_AUTH_ALG_SHARED_KEY);
+       if (ret != 0)
+               return ret;
+
+       if (wrqu->data.length > 0) {
+               key_len = wrqu->data.length;
+               key = extra;
+       } else {
+               /* must be set as tx key */
+               if (priv->encr_key_len[index] == 0)
+                       return -EINVAL;
+               key_len = priv->encr_key_len[index];
+               key = priv->encr_keys[index];
+               priv->encr_tx_key_index = index;
+       }
+
+       if (add_wep_key(usbdev, key, key_len, index) != 0)
+               return -EINVAL;
+
+       if (index == priv->encr_tx_key_index)
+               /* ndis drivers want essid to be set after setting encr */
+               set_essid(usbdev, &priv->essid);
+
+       return 0;
+}
+
+
+static int rndis_iw_set_encode_ext(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct NDIS_802_11_KEY ndis_key;
+       int i, keyidx, ret;
+       u8 *addr;
+
+       keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX;
+
+       /* iwconfig gives index as 1 - N */
+       if (keyidx)
+               keyidx--;
+       else
+               keyidx = priv->encr_tx_key_index;
+
+       if (keyidx < 0 || keyidx >= 4)
+               return -EINVAL;
+
+       if (ext->alg == WPA_ALG_WEP) {
+               if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+                       priv->encr_tx_key_index = keyidx;
+               return add_wep_key(usbdev, ext->key, ext->key_len, keyidx);
+       }
+
+       if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) ||
+           ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0)
+               return remove_key(usbdev, keyidx, NULL);
+
+       if (ext->key_len > sizeof(ndis_key.KeyMaterial))
+               return -1;
+
+       memset(&ndis_key, 0, sizeof(ndis_key));
+
+       ndis_key.Length = cpu_to_le32(sizeof(ndis_key) -
+                               sizeof(ndis_key.KeyMaterial) + ext->key_len);
+       ndis_key.KeyLength = cpu_to_le32(ext->key_len);
+       ndis_key.KeyIndex = cpu_to_le32(keyidx);
+
+       if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+               for (i = 0; i < 6; i++)
+                       ndis_key.KeyRSC |=
+                               cpu_to_le64(ext->rx_seq[i] << (i * 8));
+               ndis_key.KeyIndex |= cpu_to_le32(1 << 29);
+       }
+
+       addr = ext->addr.sa_data;
+       if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+               /* group key */
+               if (priv->infra_mode == Ndis802_11IBSS)
+                       memset(ndis_key.Bssid, 0xff, ETH_ALEN);
+               else
+                       get_bssid(usbdev, ndis_key.Bssid);
+       } else {
+               /* pairwise key */
+               ndis_key.KeyIndex |= cpu_to_le32(1 << 30);
+               memcpy(ndis_key.Bssid, addr, ETH_ALEN);
+       }
+
+       if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+               ndis_key.KeyIndex |= cpu_to_le32(1 << 31);
+
+       if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) {
+               /* wpa_supplicant gives us the Michael MIC RX/TX keys in
+                * different order than NDIS spec, so swap the order here. */
+               memcpy(ndis_key.KeyMaterial, ext->key, 16);
+               memcpy(ndis_key.KeyMaterial + 16, ext->key + 24, 8);
+               memcpy(ndis_key.KeyMaterial + 24, ext->key + 16, 8);
+       } else
+               memcpy(ndis_key.KeyMaterial, ext->key, ext->key_len);
+
+       ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
+                                       le32_to_cpu(ndis_key.Length));
+       devdbg(usbdev, "SIOCSIWENCODEEXT: OID_802_11_ADD_KEY -> %08X", ret);
+       if (ret != 0)
+               return ret;
+
+       priv->encr_key_len[keyidx] = ext->key_len;
+       memcpy(&priv->encr_keys[keyidx], ndis_key.KeyMaterial, ext->key_len);
+       if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+               priv->encr_tx_key_index = keyidx;
+
+       return 0;
+}
+
+
+static int rndis_iw_set_scan(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct iw_param *param = &wrqu->param;
+       struct usbnet *usbdev = dev->priv;
+       union iwreq_data evt;
+       int ret = -EINVAL;
+       __le32 tmp;
+
+       devdbg(usbdev, "SIOCSIWSCAN");
+
+       if (param->flags == 0) {
+               tmp = ccpu2(1);
+               ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
+                                                               sizeof(tmp));
+               evt.data.flags = 0;
+               evt.data.length = 0;
+               wireless_send_event(dev, SIOCGIWSCAN, &evt, NULL);
+       }
+       return ret;
+}
+
+
+static char *rndis_translate_scan(struct net_device *dev,
+    char *cev, char *end_buf, struct NDIS_WLAN_BSSID_EX *bssid)
+{
+#ifdef DEBUG
+       struct usbnet *usbdev = dev->priv;
+#endif
+       struct ieee80211_info_element *ie;
+       char *current_val;
+       int bssid_len, ie_len, i;
+       u32 beacon, atim;
+       struct iw_event iwe;
+       unsigned char sbuf[32];
+       DECLARE_MAC_BUF(mac);
+
+       bssid_len = le32_to_cpu(bssid->Length);
+
+       devdbg(usbdev, "BSSID %s", print_mac(mac, bssid->MacAddress));
+       iwe.cmd = SIOCGIWAP;
+       iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+       memcpy(iwe.u.ap_addr.sa_data, bssid->MacAddress, ETH_ALEN);
+       cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN);
+
+       devdbg(usbdev, "SSID(%d) %s",
+               le32_to_cpu(bssid->Ssid.SsidLength),
+               bssid->Ssid.Ssid);
+       iwe.cmd = SIOCGIWESSID;
+       iwe.u.essid.length = le32_to_cpu(bssid->Ssid.SsidLength);
+       iwe.u.essid.flags = 1;
+       cev = iwe_stream_add_point(cev, end_buf, &iwe,
+                                               bssid->Ssid.Ssid);
+
+       devdbg(usbdev, "MODE %d",
+                       le32_to_cpu(bssid->InfrastructureMode));
+       iwe.cmd = SIOCGIWMODE;
+       switch (le32_to_cpu(bssid->InfrastructureMode)) {
+       case Ndis802_11IBSS:
+               iwe.u.mode = IW_MODE_ADHOC;
+               break;
+       case Ndis802_11Infrastructure:
+               iwe.u.mode = IW_MODE_INFRA;
+               break;
+       /*case Ndis802_11AutoUnknown:*/
+       default:
+               iwe.u.mode = IW_MODE_AUTO;
+               break;
+       }
+       cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN);
+
+       devdbg(usbdev, "FREQ %d kHz",
+               le32_to_cpu(bssid->Configuration.DSConfig));
+       iwe.cmd = SIOCGIWFREQ;
+       dsconfig_to_freq(le32_to_cpu(bssid->Configuration.DSConfig),
+                                                               &iwe.u.freq);
+       cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN);
+
+       devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->Rssi));
+       iwe.cmd = IWEVQUAL;
+       iwe.u.qual.qual  = level_to_qual(le32_to_cpu(bssid->Rssi));
+       iwe.u.qual.level = le32_to_cpu(bssid->Rssi);
+       iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
+                       | IW_QUAL_LEVEL_UPDATED
+                       | IW_QUAL_NOISE_INVALID;
+       cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);
+
+       devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->Privacy));
+       iwe.cmd = SIOCGIWENCODE;
+       iwe.u.data.length = 0;
+       if (le32_to_cpu(bssid->Privacy) == Ndis802_11PrivFilterAcceptAll)
+               iwe.u.data.flags = IW_ENCODE_DISABLED;
+       else
+               iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+
+       cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL);
+
+       devdbg(usbdev, "RATES:");
+       current_val = cev + IW_EV_LCP_LEN;
+       iwe.cmd = SIOCGIWRATE;
+       for (i = 0; i < sizeof(bssid->SupportedRates); i++) {
+               if (bssid->SupportedRates[i] & 0x7f) {
+                       iwe.u.bitrate.value =
+                               ((bssid->SupportedRates[i] & 0x7f) *
+                               500000);
+                       devdbg(usbdev, " %d", iwe.u.bitrate.value);
+                       current_val = iwe_stream_add_value(cev,
+                               current_val, end_buf, &iwe,
+                               IW_EV_PARAM_LEN);
+               }
+       }
+
+       if ((current_val - cev) > IW_EV_LCP_LEN)
+               cev = current_val;
+
+       beacon = le32_to_cpu(bssid->Configuration.BeaconPeriod);
+       devdbg(usbdev, "BCN_INT %d", beacon);
+       iwe.cmd = IWEVCUSTOM;
+       snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
+       iwe.u.data.length = strlen(sbuf);
+       cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf);
+
+       atim = le32_to_cpu(bssid->Configuration.ATIMWindow);
+       devdbg(usbdev, "ATIM %d", atim);
+       iwe.cmd = IWEVCUSTOM;
+       snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
+       iwe.u.data.length = strlen(sbuf);
+       cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf);
+
+       ie = (void *)(bssid->IEs + sizeof(struct NDIS_802_11_FIXED_IEs));
+       ie_len = min(bssid_len - (int)sizeof(*bssid),
+                                       (int)le32_to_cpu(bssid->IELength));
+       ie_len -= sizeof(struct NDIS_802_11_FIXED_IEs);
+       while (ie_len >= sizeof(*ie) && sizeof(*ie) + ie->len <= ie_len) {
+               if ((ie->id == MFIE_TYPE_GENERIC && ie->len >= 4 &&
+                               memcmp(ie->data, "\x00\x50\xf2\x01", 4) == 0) ||
+                               ie->id == MFIE_TYPE_RSN) {
+                       devdbg(usbdev, "IE: WPA%d",
+                                       (ie->id == MFIE_TYPE_RSN) ? 2 : 1);
+                       iwe.cmd = IWEVGENIE;
+                       iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN);
+                       cev = iwe_stream_add_point(cev, end_buf, &iwe,
+                                                               (u8 *)ie);
+               }
+
+               ie_len -= sizeof(*ie) + ie->len;
+               ie = (struct ieee80211_info_element *)&ie->data[ie->len];
+       }
+
+       return cev;
+}
+
+
+static int rndis_iw_get_scan(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       void *buf = NULL;
+       char *cev = extra;
+       struct NDIS_802_11_BSSID_LIST_EX *bssid_list;
+       struct NDIS_WLAN_BSSID_EX *bssid;
+       int ret = -EINVAL, len, count, bssid_len;
+
+       devdbg(usbdev, "SIOCGIWSCAN");
+
+       len = CONTROL_BUFFER_SIZE;
+       buf = kmalloc(len, GFP_KERNEL);
+       if (!buf) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
+
+       if (ret != 0)
+               goto out;
+
+       bssid_list = buf;
+       bssid = bssid_list->Bssid;
+       bssid_len = le32_to_cpu(bssid->Length);
+       count = le32_to_cpu(bssid_list->NumberOfItems);
+       devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
+
+       while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
+               cev = rndis_translate_scan(dev, cev, extra + IW_SCAN_MAX_DATA,
+                                                                       bssid);
+               bssid = (void *)bssid + bssid_len;
+               bssid_len = le32_to_cpu(bssid->Length);
+               count--;
+       }
+
+out:
+       wrqu->data.length = cev - extra;
+       wrqu->data.flags = 0;
+       kfree(buf);
+       return ret;
+}
+
+
+static int rndis_iw_set_genie(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       int ret = 0;
+
+#ifdef DEBUG
+       int j;
+       u8 *gie = extra;
+       for (j = 0; j < wrqu->data.length; j += 8)
+               devdbg(usbdev,
+                       "SIOCSIWGENIE %04x - "
+                       "%02x %02x %02x %02x %02x %02x %02x %02x", j,
+                       gie[j + 0], gie[j + 1], gie[j + 2], gie[j + 3],
+                       gie[j + 4], gie[j + 5], gie[j + 6], gie[j + 7]);
+#endif
+       /* clear existing IEs */
+       if (priv->wpa_ie_len) {
+               kfree(priv->wpa_ie);
+               priv->wpa_ie_len = 0;
+       }
+
+       /* set new IEs */
+       priv->wpa_ie = kmalloc(wrqu->data.length, GFP_KERNEL);
+       if (priv->wpa_ie) {
+               priv->wpa_ie_len = wrqu->data.length;
+               memcpy(priv->wpa_ie, extra, priv->wpa_ie_len);
+       } else
+               ret = -ENOMEM;
+       return ret;
+}
+
+
+static int rndis_iw_get_genie(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+       devdbg(usbdev, "SIOCGIWGENIE");
+
+       if (priv->wpa_ie_len == 0 || priv->wpa_ie == NULL) {
+               wrqu->data.length = 0;
+               return 0;
+       }
+
+       if (wrqu->data.length < priv->wpa_ie_len)
+               return -E2BIG;
+
+       wrqu->data.length = priv->wpa_ie_len;
+       memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
+
+       return 0;
+}
+
+
+static int rndis_iw_set_rts(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       __le32 tmp;
+       devdbg(usbdev, "SIOCSIWRTS");
+
+       tmp = cpu_to_le32(wrqu->rts.value);
+       return rndis_set_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp,
+                                                               sizeof(tmp));
+}
+
+
+static int rndis_iw_get_rts(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       __le32 tmp;
+       int len, ret;
+
+       len = sizeof(tmp);
+       ret = rndis_query_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp, &len);
+       if (ret == 0) {
+               wrqu->rts.value = le32_to_cpu(tmp);
+               wrqu->rts.flags = 1;
+               wrqu->rts.disabled = 0;
+       }
+
+       devdbg(usbdev, "SIOCGIWRTS: %d", wrqu->rts.value);
+
+       return ret;
+}
+
+
+static int rndis_iw_set_frag(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       __le32 tmp;
+
+       devdbg(usbdev, "SIOCSIWFRAG");
+
+       tmp = cpu_to_le32(wrqu->frag.value);
+       return rndis_set_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp,
+                                                               sizeof(tmp));
+}
+
+
+static int rndis_iw_get_frag(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       __le32 tmp;
+       int len, ret;
+
+       len = sizeof(tmp);
+       ret = rndis_query_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp,
+                                                                       &len);
+       if (ret == 0) {
+               wrqu->frag.value = le32_to_cpu(tmp);
+               wrqu->frag.flags = 1;
+               wrqu->frag.disabled = 0;
+       }
+       devdbg(usbdev, "SIOCGIWFRAG: %d", wrqu->frag.value);
+       return ret;
+}
+
+
+static int rndis_iw_set_nick(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+       devdbg(usbdev, "SIOCSIWNICK");
+
+       priv->nick_len = wrqu->data.length;
+       if (priv->nick_len > 32)
+               priv->nick_len = 32;
+
+       memcpy(priv->nick, extra, priv->nick_len);
+       return 0;
+}
+
+
+static int rndis_iw_get_nick(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+       wrqu->data.flags = 1;
+       wrqu->data.length = priv->nick_len;
+       memcpy(extra, priv->nick, priv->nick_len);
+
+       devdbg(usbdev, "SIOCGIWNICK: '%s'", priv->nick);
+
+       return 0;
+}
+
+
+static int rndis_iw_set_freq(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct NDIS_802_11_CONFIGURATION config;
+       unsigned int dsconfig;
+       int len, ret;
+
+       /* this OID is valid only when not associated */
+       if (is_associated(usbdev))
+               return 0;
+
+       dsconfig = 0;
+       if (freq_to_dsconfig(&wrqu->freq, &dsconfig))
+               return -EINVAL;
+
+       len = sizeof(config);
+       ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
+       if (ret != 0) {
+               devdbg(usbdev, "SIOCSIWFREQ: querying configuration failed");
+               return 0;
+       }
+
+       config.DSConfig = cpu_to_le32(dsconfig);
+
+       devdbg(usbdev, "SIOCSIWFREQ: %d * 10^%d", wrqu->freq.m, wrqu->freq.e);
+       return rndis_set_oid(usbdev, OID_802_11_CONFIGURATION, &config,
+                                                               sizeof(config));
+}
+
+
+static int rndis_iw_get_freq(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct NDIS_802_11_CONFIGURATION config;
+       int len, ret;
+
+       len = sizeof(config);
+       ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
+       if (ret == 0)
+               dsconfig_to_freq(le32_to_cpu(config.DSConfig), &wrqu->freq);
+
+       devdbg(usbdev, "SIOCGIWFREQ: %d", wrqu->freq.m);
+       return ret;
+}
+
+
+static int rndis_iw_get_txpower(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       __le32 tx_power;
+       int ret = 0, len;
+
+       if (priv->radio_on) {
+               if (priv->caps & CAP_SUPPORT_TXPOWER) {
+                       len = sizeof(tx_power);
+                       ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
+                                                       &tx_power, &len);
+                       if (ret != 0)
+                               return ret;
+               } else
+                       /* fake incase not supported */
+                       tx_power = cpu_to_le32(get_bcm4320_power(priv));
+
+               wrqu->txpower.flags = IW_TXPOW_MWATT;
+               wrqu->txpower.value = le32_to_cpu(tx_power);
+               wrqu->txpower.disabled = 0;
+       } else {
+               wrqu->txpower.flags = IW_TXPOW_MWATT;
+               wrqu->txpower.value = 0;
+               wrqu->txpower.disabled = 1;
+       }
+
+       devdbg(usbdev, "SIOCGIWTXPOW: %d", wrqu->txpower.value);
+
+       return ret;
+}
+
+
+static int rndis_iw_set_txpower(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       __le32 tx_power = 0;
+       int ret = 0;
+
+       if (!wrqu->txpower.disabled) {
+               if (wrqu->txpower.flags == IW_TXPOW_MWATT)
+                       tx_power = cpu_to_le32(wrqu->txpower.value);
+               else { /* wrqu->txpower.flags == IW_TXPOW_DBM */
+                       if (wrqu->txpower.value > 20)
+                               tx_power = cpu_to_le32(128);
+                       else if (wrqu->txpower.value < -43)
+                               tx_power = cpu_to_le32(127);
+                       else {
+                               signed char tmp;
+                               tmp = wrqu->txpower.value;
+                               tmp = -12 - tmp;
+                               tmp <<= 2;
+                               tx_power = cpu_to_le32((unsigned char)tmp);
+                       }
+               }
+       }
+
+       devdbg(usbdev, "SIOCSIWTXPOW: %d", le32_to_cpu(tx_power));
+
+       if (le32_to_cpu(tx_power) != 0) {
+               if (priv->caps & CAP_SUPPORT_TXPOWER) {
+                       /* turn radio on first */
+                       if (!priv->radio_on)
+                               disassociate(usbdev, 1);
+
+                       ret = rndis_set_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
+                                               &tx_power, sizeof(tx_power));
+                       if (ret != 0)
+                               ret = -EOPNOTSUPP;
+                       return ret;
+               } else {
+                       /* txpower unsupported, just turn radio on */
+                       if (!priv->radio_on)
+                               return disassociate(usbdev, 1);
+                       return 0; /* all ready on */
+               }
+       }
+
+       /* tx_power == 0, turn off radio */
+       return disassociate(usbdev, 0);
+}
+
+
+static int rndis_iw_get_rate(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       __le32 tmp;
+       int ret, len;
+
+       len = sizeof(tmp);
+       ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &tmp, &len);
+       if (ret == 0) {
+               wrqu->bitrate.value = le32_to_cpu(tmp) * 100;
+               wrqu->bitrate.disabled = 0;
+               wrqu->bitrate.flags = 1;
+       }
+       return ret;
+}
+
+
+static int rndis_iw_set_mlme(struct net_device *dev,
+    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct iw_mlme *mlme = (struct iw_mlme *)extra;
+       unsigned char bssid[ETH_ALEN];
+
+       get_bssid(usbdev, bssid);
+
+       if (memcmp(bssid, mlme->addr.sa_data, ETH_ALEN))
+               return -EINVAL;
+
+       switch (mlme->cmd) {
+       case IW_MLME_DEAUTH:
+               return deauthenticate(usbdev);
+       case IW_MLME_DISASSOC:
+               return disassociate(usbdev, priv->radio_on);
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       return 0;
+}
+
+
+static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->stats_lock, flags);
+       memcpy(&priv->iwstats, &priv->privstats, sizeof(priv->iwstats));
+       spin_unlock_irqrestore(&priv->stats_lock, flags);
+
+       return &priv->iwstats;
+}
+
+
+#define IW_IOCTL(x) [(x) - SIOCSIWCOMMIT]
+static const iw_handler rndis_iw_handler[] =
+{
+       IW_IOCTL(SIOCSIWCOMMIT)    = rndis_iw_commit,
+       IW_IOCTL(SIOCGIWNAME)      = rndis_iw_get_name,
+       IW_IOCTL(SIOCSIWFREQ)      = rndis_iw_set_freq,
+       IW_IOCTL(SIOCGIWFREQ)      = rndis_iw_get_freq,
+       IW_IOCTL(SIOCSIWMODE)      = rndis_iw_set_mode,
+       IW_IOCTL(SIOCGIWMODE)      = rndis_iw_get_mode,
+       IW_IOCTL(SIOCGIWRANGE)     = rndis_iw_get_range,
+       IW_IOCTL(SIOCSIWAP)        = rndis_iw_set_bssid,
+       IW_IOCTL(SIOCGIWAP)        = rndis_iw_get_bssid,
+       IW_IOCTL(SIOCSIWSCAN)      = rndis_iw_set_scan,
+       IW_IOCTL(SIOCGIWSCAN)      = rndis_iw_get_scan,
+       IW_IOCTL(SIOCSIWESSID)     = rndis_iw_set_essid,
+       IW_IOCTL(SIOCGIWESSID)     = rndis_iw_get_essid,
+       IW_IOCTL(SIOCSIWNICKN)     = rndis_iw_set_nick,
+       IW_IOCTL(SIOCGIWNICKN)     = rndis_iw_get_nick,
+       IW_IOCTL(SIOCGIWRATE)      = rndis_iw_get_rate,
+       IW_IOCTL(SIOCSIWRTS)       = rndis_iw_set_rts,
+       IW_IOCTL(SIOCGIWRTS)       = rndis_iw_get_rts,
+       IW_IOCTL(SIOCSIWFRAG)      = rndis_iw_set_frag,
+       IW_IOCTL(SIOCGIWFRAG)      = rndis_iw_get_frag,
+       IW_IOCTL(SIOCSIWTXPOW)     = rndis_iw_set_txpower,
+       IW_IOCTL(SIOCGIWTXPOW)     = rndis_iw_get_txpower,
+       IW_IOCTL(SIOCSIWENCODE)    = rndis_iw_set_encode,
+       IW_IOCTL(SIOCSIWENCODEEXT) = rndis_iw_set_encode_ext,
+       IW_IOCTL(SIOCSIWAUTH)      = rndis_iw_set_auth,
+       IW_IOCTL(SIOCGIWAUTH)      = rndis_iw_get_auth,
+       IW_IOCTL(SIOCSIWGENIE)     = rndis_iw_set_genie,
+       IW_IOCTL(SIOCGIWGENIE)     = rndis_iw_get_genie,
+       IW_IOCTL(SIOCSIWMLME)      = rndis_iw_set_mlme,
+};
+
+static const iw_handler rndis_wext_private_handler[] = {
+};
+
+static const struct iw_priv_args rndis_wext_private_args[] = {
+};
+
+
+static const struct iw_handler_def rndis_iw_handlers = {
+       .num_standard = ARRAY_SIZE(rndis_iw_handler),
+       .num_private  = ARRAY_SIZE(rndis_wext_private_handler),
+       .num_private_args = ARRAY_SIZE(rndis_wext_private_args),
+       .standard = (iw_handler *)rndis_iw_handler,
+       .private  = (iw_handler *)rndis_wext_private_handler,
+       .private_args = (struct iw_priv_args *)rndis_wext_private_args,
+       .get_wireless_stats = rndis_get_wireless_stats,
+};
+
+
+static void rndis_wext_worker(struct work_struct *work)
+{
+       struct rndis_wext_private *priv =
+               container_of(work, struct rndis_wext_private, work);
+       struct usbnet *usbdev = priv->usbdev;
+       union iwreq_data evt;
+       unsigned char bssid[ETH_ALEN];
+       int ret;
+
+       if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) {
+               ret = get_bssid(usbdev, bssid);
+
+               if (!ret) {
+                       evt.data.flags = 0;
+                       evt.data.length = 0;
+                       memcpy(evt.ap_addr.sa_data, bssid, ETH_ALEN);
+                       wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
+               }
+       }
+
+       if (test_and_clear_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
+               set_multicast_list(usbdev);
+}
+
+static void rndis_wext_set_multicast_list(struct net_device *dev)
+{
+       struct usbnet *usbdev = dev->priv;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+
+       set_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending);
+       queue_work(priv->workqueue, &priv->work);
+}
+
+static void rndis_wext_link_change(struct usbnet *dev, int state)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+       union iwreq_data evt;
+
+       if (state) {
+               /* queue work to avoid recursive calls into rndis_command */
+               set_bit(WORK_CONNECTION_EVENT, &priv->work_pending);
+               queue_work(priv->workqueue, &priv->work);
+       } else {
+               evt.data.flags = 0;
+               evt.data.length = 0;
+               memset(evt.ap_addr.sa_data, 0, ETH_ALEN);
+               wireless_send_event(dev->net, SIOCGIWAP, &evt, NULL);
+       }
+}
+
+
+static int rndis_wext_get_caps(struct usbnet *dev)
+{
+       struct {
+               __le32  num_items;
+               __le32  items[8];
+       } networks_supported;
+       int len, retval, i, n;
+       __le32 tx_power;
+       struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+
+       /* determine if supports setting txpower */
+       len = sizeof(tx_power);
+       retval = rndis_query_oid(dev, OID_802_11_TX_POWER_LEVEL, &tx_power,
+                                                               &len);
+       if (retval == 0 && le32_to_cpu(tx_power) != 0xFF)
+               priv->caps |= CAP_SUPPORT_TXPOWER;
+
+       /* determine supported modes */
+       len = sizeof(networks_supported);
+       retval = rndis_query_oid(dev, OID_802_11_NETWORK_TYPES_SUPPORTED,
+                                               &networks_supported, &len);
+       if (retval >= 0) {
+               n = le32_to_cpu(networks_supported.num_items);
+               if (n > 8)
+                       n = 8;
+               for (i = 0; i < n; i++) {
+                       switch (le32_to_cpu(networks_supported.items[i])) {
+                       case Ndis802_11FH:
+                       case Ndis802_11DS:
+                               priv->caps |= CAP_MODE_80211B;
+                               break;
+                       case Ndis802_11OFDM5:
+                               priv->caps |= CAP_MODE_80211A;
+                               break;
+                       case Ndis802_11OFDM24:
+                               priv->caps |= CAP_MODE_80211G;
+                               break;
+                       }
+               }
+               if (priv->caps & CAP_MODE_80211A)
+                       strcat(priv->name, "a");
+               if (priv->caps & CAP_MODE_80211B)
+                       strcat(priv->name, "b");
+               if (priv->caps & CAP_MODE_80211G)
+                       strcat(priv->name, "g");
+       }
+
+       return retval;
+}
+
+
+#define STATS_UPDATE_JIFFIES (HZ)
+static void rndis_update_wireless_stats(struct work_struct *work)
+{
+       struct rndis_wext_private *priv =
+               container_of(work, struct rndis_wext_private, stats_work.work);
+       struct usbnet *usbdev = priv->usbdev;
+       struct iw_statistics iwstats;
+       __le32 rssi, tmp;
+       int len, ret, bitrate, j;
+       unsigned long flags;
+       int update_jiffies = STATS_UPDATE_JIFFIES;
+       void *buf;
+
+       spin_lock_irqsave(&priv->stats_lock, flags);
+       memcpy(&iwstats, &priv->privstats, sizeof(iwstats));
+       spin_unlock_irqrestore(&priv->stats_lock, flags);
+
+       /* only update stats when connected */
+       if (!is_associated(usbdev)) {
+               iwstats.qual.qual = 0;
+               iwstats.qual.level = 0;
+               iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
+                               | IW_QUAL_LEVEL_UPDATED
+                               | IW_QUAL_NOISE_INVALID
+                               | IW_QUAL_QUAL_INVALID
+                               | IW_QUAL_LEVEL_INVALID;
+               goto end;
+       }
+
+       len = sizeof(rssi);
+       ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
+
+       devdbg(usbdev, "stats: OID_802_11_RSSI -> %d, rssi:%d", ret,
+                                                       le32_to_cpu(rssi));
+       if (ret == 0) {
+               memset(&iwstats.qual, 0, sizeof(iwstats.qual));
+               iwstats.qual.qual  = level_to_qual(le32_to_cpu(rssi));
+               iwstats.qual.level = le32_to_cpu(rssi);
+               iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
+                               | IW_QUAL_LEVEL_UPDATED
+                               | IW_QUAL_NOISE_INVALID;
+       }
+
+       memset(&iwstats.discard, 0, sizeof(iwstats.discard));
+
+       len = sizeof(tmp);
+       ret = rndis_query_oid(usbdev, OID_GEN_XMIT_ERROR, &tmp, &len);
+       if (ret == 0)
+               iwstats.discard.misc += le32_to_cpu(tmp);
+
+       len = sizeof(tmp);
+       ret = rndis_query_oid(usbdev, OID_GEN_RCV_ERROR, &tmp, &len);
+       if (ret == 0)
+               iwstats.discard.misc += le32_to_cpu(tmp);
+
+       len = sizeof(tmp);
+       ret = rndis_query_oid(usbdev, OID_GEN_RCV_NO_BUFFER, &tmp, &len);
+       if (ret == 0)
+               iwstats.discard.misc += le32_to_cpu(tmp);
+
+       /* Workaround transfer stalls on poor quality links. */
+       len = sizeof(tmp);
+       ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &tmp, &len);
+       if (ret == 0) {
+               bitrate = le32_to_cpu(tmp) * 100;
+               if (bitrate > 11000000)
+                       goto end;
+
+               /* Decrease stats worker interval to catch stalls.
+                * faster. Faster than 400-500ms causes packet loss,
+                * Slower doesn't catch stalls fast enough.
+                */
+               j = msecs_to_jiffies(priv->param_workaround_interval);
+               if (j > STATS_UPDATE_JIFFIES)
+                       j = STATS_UPDATE_JIFFIES;
+               else if (j <= 0)
+                       j = 1;
+               update_jiffies = j;
+
+               /* Send scan OID. Use of both OIDs is required to get device
+                * working.
+                */
+               tmp = ccpu2(1);
+               rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
+                                                               sizeof(tmp));
+
+               len = CONTROL_BUFFER_SIZE;
+               buf = kmalloc(len, GFP_KERNEL);
+               if (!buf)
+                       goto end;
+
+               rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
+               kfree(buf);
+       }
+end:
+       spin_lock_irqsave(&priv->stats_lock, flags);
+       memcpy(&priv->privstats, &iwstats, sizeof(iwstats));
+       spin_unlock_irqrestore(&priv->stats_lock, flags);
+
+       if (update_jiffies >= HZ)
+               update_jiffies = round_jiffies_relative(update_jiffies);
+       else {
+               j = round_jiffies_relative(update_jiffies);
+               if (abs(j - update_jiffies) <= 10)
+                       update_jiffies = j;
+       }
+
+       queue_delayed_work(priv->workqueue, &priv->stats_work, update_jiffies);
+}
+
+
+static int bcm4320_early_init(struct usbnet *dev)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+       char buf[8];
+
+       /* Early initialization settings, setting these won't have effect
+        * if called after generic_rndis_bind().
+        */
+
+       priv->param_country[0] = modparam_country[0];
+       priv->param_country[1] = modparam_country[1];
+       priv->param_country[2] = 0;
+       priv->param_frameburst   = modparam_frameburst;
+       priv->param_afterburner  = modparam_afterburner;
+       priv->param_power_save   = modparam_power_save;
+       priv->param_power_output = modparam_power_output;
+       priv->param_roamtrigger  = modparam_roamtrigger;
+       priv->param_roamdelta    = modparam_roamdelta;
+       priv->param_workaround_interval = modparam_workaround_interval;
+
+       priv->param_country[0] = toupper(priv->param_country[0]);
+       priv->param_country[1] = toupper(priv->param_country[1]);
+       /* doesn't support EU as country code, use FI instead */
+       if (!strcmp(priv->param_country, "EU"))
+               strcpy(priv->param_country, "FI");
+
+       if (priv->param_power_save < 0)
+               priv->param_power_save = 0;
+       else if (priv->param_power_save > 2)
+               priv->param_power_save = 2;
+
+       if (priv->param_roamtrigger < -80)
+               priv->param_roamtrigger = -80;
+       else if (priv->param_roamtrigger > -60)
+               priv->param_roamtrigger = -60;
+
+       if (priv->param_roamdelta < 0)
+               priv->param_roamdelta = 0;
+       else if (priv->param_roamdelta > 2)
+               priv->param_roamdelta = 2;
+
+       if (priv->param_workaround_interval < 0)
+               priv->param_workaround_interval = 500;
+
+       rndis_set_config_parameter_str(dev, "Country", priv->param_country);
+       rndis_set_config_parameter_str(dev, "FrameBursting",
+                                       priv->param_frameburst ? "1" : "0");
+       rndis_set_config_parameter_str(dev, "Afterburner",
+                                       priv->param_afterburner ? "1" : "0");
+       sprintf(buf, "%d", priv->param_power_save);
+       rndis_set_config_parameter_str(dev, "PowerSaveMode", buf);
+       sprintf(buf, "%d", priv->param_power_output);
+       rndis_set_config_parameter_str(dev, "PwrOut", buf);
+       sprintf(buf, "%d", priv->param_roamtrigger);
+       rndis_set_config_parameter_str(dev, "RoamTrigger", buf);
+       sprintf(buf, "%d", priv->param_roamdelta);
+       rndis_set_config_parameter_str(dev, "RoamDelta", buf);
+
+       return 0;
+}
+
+
+static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       struct net_device *net = dev->net;
+       struct rndis_wext_private *priv;
+       int retval, len;
+       __le32 tmp;
+
+       /* allocate rndis private data */
+       priv = kmalloc(sizeof(struct rndis_wext_private), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       /* These have to be initialized before calling generic_rndis_bind().
+        * Otherwise we'll be in big trouble in rndis_wext_early_init().
+        */
+       dev->driver_priv = priv;
+       memset(priv, 0, sizeof(*priv));
+       memset(priv->name, 0, sizeof(priv->name));
+       strcpy(priv->name, "IEEE802.11");
+       net->wireless_handlers = &rndis_iw_handlers;
+       priv->usbdev = dev;
+
+       mutex_init(&priv->command_lock);
+       spin_lock_init(&priv->stats_lock);
+
+       /* try bind rndis_host */
+       retval = generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_WIRELESS);
+       if (retval < 0)
+               goto fail;
+
+       /* generic_rndis_bind set packet filter to multicast_all+
+        * promisc mode which doesn't work well for our devices (device
+        * picks up rssi to closest station instead of to access point).
+        *
+        * rndis_host wants to avoid all OID as much as possible
+        * so do promisc/multicast handling in rndis_wext.
+        */
+       dev->net->set_multicast_list = rndis_wext_set_multicast_list;
+       tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
+       retval = rndis_set_oid(dev, OID_GEN_CURRENT_PACKET_FILTER, &tmp,
+                                                               sizeof(tmp));
+
+       len = sizeof(tmp);
+       retval = rndis_query_oid(dev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp, &len);
+       priv->multicast_size = le32_to_cpu(tmp);
+       if (retval < 0 || priv->multicast_size < 0)
+               priv->multicast_size = 0;
+       if (priv->multicast_size > 0)
+               dev->net->flags |= IFF_MULTICAST;
+       else
+               dev->net->flags &= ~IFF_MULTICAST;
+
+       priv->iwstats.qual.qual = 0;
+       priv->iwstats.qual.level = 0;
+       priv->iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
+                                       | IW_QUAL_LEVEL_UPDATED
+                                       | IW_QUAL_NOISE_INVALID
+                                       | IW_QUAL_QUAL_INVALID
+                                       | IW_QUAL_LEVEL_INVALID;
+
+       rndis_wext_get_caps(dev);
+       set_default_iw_params(dev);
+
+       /* turn radio on */
+       priv->radio_on = 1;
+       disassociate(dev, 1);
+
+       /* because rndis_command() sleeps we need to use workqueue */
+       priv->workqueue = create_singlethread_workqueue("rndis_wlan");
+       INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats);
+       queue_delayed_work(priv->workqueue, &priv->stats_work,
+               round_jiffies_relative(STATS_UPDATE_JIFFIES));
+       INIT_WORK(&priv->work, rndis_wext_worker);
+
+       return 0;
+
+fail:
+       kfree(priv);
+       return retval;
+}
+
+
+static void rndis_wext_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+       struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+
+       /* turn radio off */
+       disassociate(dev, 0);
+
+       cancel_delayed_work_sync(&priv->stats_work);
+       cancel_work_sync(&priv->work);
+       flush_workqueue(priv->workqueue);
+       destroy_workqueue(priv->workqueue);
+
+       if (priv && priv->wpa_ie_len)
+               kfree(priv->wpa_ie);
+       kfree(priv);
+
+       rndis_unbind(dev, intf);
+}
+
+
+static int rndis_wext_reset(struct usbnet *dev)
+{
+       return deauthenticate(dev);
+}
+
+
+static const struct driver_info        bcm4320b_info = {
+       .description =  "Wireless RNDIS device, BCM4320b based",
+       .flags =        FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
+       .bind =         rndis_wext_bind,
+       .unbind =       rndis_wext_unbind,
+       .status =       rndis_status,
+       .rx_fixup =     rndis_rx_fixup,
+       .tx_fixup =     rndis_tx_fixup,
+       .reset =        rndis_wext_reset,
+       .early_init =   bcm4320_early_init,
+       .link_change =  rndis_wext_link_change,
+};
+
+static const struct driver_info        bcm4320a_info = {
+       .description =  "Wireless RNDIS device, BCM4320a based",
+       .flags =        FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
+       .bind =         rndis_wext_bind,
+       .unbind =       rndis_wext_unbind,
+       .status =       rndis_status,
+       .rx_fixup =     rndis_rx_fixup,
+       .tx_fixup =     rndis_tx_fixup,
+       .reset =        rndis_wext_reset,
+       .early_init =   bcm4320_early_init,
+       .link_change =  rndis_wext_link_change,
+};
+
+static const struct driver_info rndis_wext_info = {
+       .description =  "Wireless RNDIS device",
+       .flags =        FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
+       .bind =         rndis_wext_bind,
+       .unbind =       rndis_wext_unbind,
+       .status =       rndis_status,
+       .rx_fixup =     rndis_rx_fixup,
+       .tx_fixup =     rndis_tx_fixup,
+       .reset =        rndis_wext_reset,
+       .early_init =   bcm4320_early_init,
+       .link_change =  rndis_wext_link_change,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static const struct usb_device_id products [] = {
+#define        RNDIS_MASTER_INTERFACE \
+       .bInterfaceClass        = USB_CLASS_COMM, \
+       .bInterfaceSubClass     = 2 /* ACM */, \
+       .bInterfaceProtocol     = 0x0ff
+
+/* INF driver for these devices have DriverVer >= 4.xx.xx.xx and many custom
+ * parameters available. Chipset marked as 'BCM4320SKFBG' in NDISwrapper-wiki.
+ */
+{
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x0411,
+       .idProduct              = 0x00bc,       /* Buffalo WLI-U2-KG125S */
+       RNDIS_MASTER_INTERFACE,
+       .driver_info            = (unsigned long) &bcm4320b_info,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x0baf,
+       .idProduct              = 0x011b,       /* U.S. Robotics USR5421 */
+       RNDIS_MASTER_INTERFACE,
+       .driver_info            = (unsigned long) &bcm4320b_info,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x050d,
+       .idProduct              = 0x011b,       /* Belkin F5D7051 */
+       RNDIS_MASTER_INTERFACE,
+       .driver_info            = (unsigned long) &bcm4320b_info,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x1799,       /* Belkin has two vendor ids */
+       .idProduct              = 0x011b,       /* Belkin F5D7051 */
+       RNDIS_MASTER_INTERFACE,
+       .driver_info            = (unsigned long) &bcm4320b_info,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x13b1,
+       .idProduct              = 0x0014,       /* Linksys WUSB54GSv2 */
+       RNDIS_MASTER_INTERFACE,
+       .driver_info            = (unsigned long) &bcm4320b_info,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x13b1,
+       .idProduct              = 0x0026,       /* Linksys WUSB54GSC */
+       RNDIS_MASTER_INTERFACE,
+       .driver_info            = (unsigned long) &bcm4320b_info,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x0b05,
+       .idProduct              = 0x1717,       /* Asus WL169gE */
+       RNDIS_MASTER_INTERFACE,
+       .driver_info            = (unsigned long) &bcm4320b_info,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x0a5c,
+       .idProduct              = 0xd11b,       /* Eminent EM4045 */
+       RNDIS_MASTER_INTERFACE,
+       .driver_info            = (unsigned long) &bcm4320b_info,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x1690,
+       .idProduct              = 0x0715,       /* BT Voyager 1055 */
+       RNDIS_MASTER_INTERFACE,
+       .driver_info            = (unsigned long) &bcm4320b_info,
+},
+/* These devices have DriverVer < 4.xx.xx.xx and do not have any custom
+ * parameters available, hardware probably contain older firmware version with
+ * no way of updating. Chipset marked as 'BCM4320????' in NDISwrapper-wiki.
+ */
+{
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x13b1,
+       .idProduct              = 0x000e,       /* Linksys WUSB54GSv1 */
+       RNDIS_MASTER_INTERFACE,
+       .driver_info            = (unsigned long) &bcm4320a_info,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x0baf,
+       .idProduct              = 0x0111,       /* U.S. Robotics USR5420 */
+       RNDIS_MASTER_INTERFACE,
+       .driver_info            = (unsigned long) &bcm4320a_info,
+}, {
+       .match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+                         | USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor               = 0x0411,
+       .idProduct              = 0x004b,       /* BUFFALO WLI-USB-G54 */
+       RNDIS_MASTER_INTERFACE,
+       .driver_info            = (unsigned long) &bcm4320a_info,
+},
+/* Generic Wireless RNDIS devices that we don't have exact
+ * idVendor/idProduct/chip yet.
+ */
+{
+       /* RNDIS is MSFT's un-official variant of CDC ACM */
+       USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
+       .driver_info = (unsigned long) &rndis_wext_info,
+}, {
+       /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
+       USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
+       .driver_info = (unsigned long) &rndis_wext_info,
+},
+       { },            // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver rndis_wlan_driver = {
+       .name =         "rndis_wlan",
+       .id_table =     products,
+       .probe =        usbnet_probe,
+       .disconnect =   usbnet_disconnect,
+       .suspend =      usbnet_suspend,
+       .resume =       usbnet_resume,
+};
+
+static int __init rndis_wlan_init(void)
+{
+       return usb_register(&rndis_wlan_driver);
+}
+module_init(rndis_wlan_init);
+
+static void __exit rndis_wlan_exit(void)
+{
+       usb_deregister(&rndis_wlan_driver);
+}
+module_exit(rndis_wlan_exit);
+
+MODULE_AUTHOR("Bjorge Dijkstra");
+MODULE_AUTHOR("Jussi Kivilinna");
+MODULE_DESCRIPTION("Driver for RNDIS based USB Wireless adapters");
+MODULE_LICENSE("GPL");
+
index ab52f221cd718c06411d50c76b06c308be7b4f3b..b31f0c26c32b7bb889ba789a562aeb7ae3f889ba 100644 (file)
@@ -1736,7 +1736,8 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
                        WARNING(rt2x00dev,
                                "TX status report missed for entry %p\n",
                                entry_done);
-                       rt2x00lib_txdone(entry_done, TX_FAIL_OTHER, 0);
+                       rt2x00pci_txdone(rt2x00dev, entry_done, TX_FAIL_OTHER,
+                                        0);
                        entry_done = rt2x00_get_data_entry_done(ring);
                }
 
index 07f37b0ccf913e56a3c83b1f7db39d90404decf0..27ebd689aa2127f9bbf0e47f29114c9c98dabbd9 100644 (file)
@@ -36,6 +36,7 @@ MODULE_LICENSE("GPL");
 static struct pci_device_id rtl8180_table[] __devinitdata = {
        /* rtl8185 */
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) },
+       { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x700f) },
        { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x701f) },
 
        /* rtl8180 */
index aad4012bbb30510a66c2f7983f07473a9885f5d4..0d99120ab5a26bb3bc0540cb60f0139ed7d800a9 100644 (file)
@@ -1410,7 +1410,7 @@ rs68328_init(void)
 
            if (request_irq(uart_irqs[i],
                            rs_interrupt,
-                           IRQ_FLG_STD,
+                           IRQF_DISABLED,
                            "M68328_UART", NULL))
                 panic("Unable to attach 68328 serial interrupt\n");
        }
index d962b74e311433fd9fe477b1dbce6c901fd3ec3b..8a053ea21e1d57f9a8e3f41ac6e5dbced679504c 100644 (file)
@@ -960,6 +960,30 @@ config SERIAL_COLDFIRE
          This driver supports the built-in serial ports of the Motorola ColdFire
          family of CPUs.
 
+config SERIAL_MCF
+       bool "Coldfire serial support (new style driver)"
+       depends on COLDFIRE
+       select SERIAL_CORE
+       help
+         This new serial driver supports the Freescale Coldfire serial ports
+         using the new serial driver subsystem.
+
+config SERIAL_MCF_BAUDRATE
+       int "Default baudrate for Coldfire serial ports"
+       depends on SERIAL_MCF
+       default 19200
+       help
+         This setting lets you define what the default baudrate is for the
+         ColdFire serial ports. The usual default varies from board to board,
+         and this setting is a way of catering for that.
+
+config SERIAL_MCF_CONSOLE
+       bool "Coldfire serial console support"
+       depends on SERIAL_MCF
+       select SERIAL_CORE_CONSOLE
+       help
+         Enable a ColdFire internal serial port to be the system console.
+
 config SERIAL_68360_SMC
        bool "68360 SMC uart support"
        depends on M68360
index 7eb45534778e5b3011d381a2987ce8670210c58f..2dd41b4cc8dbf1cc930b852a8d4c0fea67d94db0 100644 (file)
@@ -39,6 +39,7 @@ obj-$(CONFIG_SERIAL_MUX) += mux.o
 obj-$(CONFIG_SERIAL_68328) += 68328serial.o
 obj-$(CONFIG_SERIAL_68360) += 68360serial.o
 obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o
+obj-$(CONFIG_SERIAL_MCF) += mcf.o
 obj-$(CONFIG_V850E_UART) += v850e_uart.o
 obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
 obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o
index a7d4360ea7df4957ba3fe6df381b1a6631951795..051fcc2f5ba8a97509789f613de8470a0965faff 100644 (file)
@@ -69,7 +69,7 @@ static unsigned int mcf_tx_empty(struct uart_port *port)
 
 static unsigned int mcf_get_mctrl(struct uart_port *port)
 {
-       struct mcf_uart *pp = (struct mcf_uart *) port;
+       struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
        unsigned long flags;
        unsigned int sigs;
 
@@ -87,7 +87,7 @@ static unsigned int mcf_get_mctrl(struct uart_port *port)
 
 static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs)
 {
-       struct mcf_uart *pp = (struct mcf_uart *) port;
+       struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
        unsigned long flags;
 
        spin_lock_irqsave(&port->lock, flags);
@@ -104,7 +104,7 @@ static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs)
 
 static void mcf_start_tx(struct uart_port *port)
 {
-       struct mcf_uart *pp = (struct mcf_uart *) port;
+       struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
        unsigned long flags;
 
        spin_lock_irqsave(&port->lock, flags);
@@ -117,7 +117,7 @@ static void mcf_start_tx(struct uart_port *port)
 
 static void mcf_stop_tx(struct uart_port *port)
 {
-       struct mcf_uart *pp = (struct mcf_uart *) port;
+       struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
        unsigned long flags;
 
        spin_lock_irqsave(&port->lock, flags);
@@ -130,7 +130,7 @@ static void mcf_stop_tx(struct uart_port *port)
 
 static void mcf_stop_rx(struct uart_port *port)
 {
-       struct mcf_uart *pp = (struct mcf_uart *) port;
+       struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
        unsigned long flags;
 
        spin_lock_irqsave(&port->lock, flags);
@@ -163,7 +163,7 @@ static void mcf_enable_ms(struct uart_port *port)
 
 static int mcf_startup(struct uart_port *port)
 {
-       struct mcf_uart *pp = (struct mcf_uart *) port;
+       struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
        unsigned long flags;
 
        spin_lock_irqsave(&port->lock, flags);
@@ -189,7 +189,7 @@ static int mcf_startup(struct uart_port *port)
 
 static void mcf_shutdown(struct uart_port *port)
 {
-       struct mcf_uart *pp = (struct mcf_uart *) port;
+       struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
        unsigned long flags;
 
        spin_lock_irqsave(&port->lock, flags);
@@ -273,7 +273,7 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
 
 static void mcf_rx_chars(struct mcf_uart *pp)
 {
-       struct uart_port *port = (struct uart_port *) pp;
+       struct uart_port *port = &pp->port;
        unsigned char status, ch, flag;
 
        while ((status = readb(port->membase + MCFUART_USR)) & MCFUART_USR_RXREADY) {
@@ -319,7 +319,7 @@ static void mcf_rx_chars(struct mcf_uart *pp)
 
 static void mcf_tx_chars(struct mcf_uart *pp)
 {
-       struct uart_port *port = (struct uart_port *) pp;
+       struct uart_port *port = &pp->port;
        struct circ_buf *xmit = &port->info->xmit;
 
        if (port->x_char) {
@@ -352,7 +352,7 @@ static void mcf_tx_chars(struct mcf_uart *pp)
 static irqreturn_t mcf_interrupt(int irq, void *data)
 {
        struct uart_port *port = data;
-       struct mcf_uart *pp = (struct mcf_uart *) port;
+       struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
        unsigned int isr;
 
        isr = readb(port->membase + MCFUART_UISR) & pp->imr;
index 1fede7f928600bd5e4b82ddbfe04c615c8f8b2f8..08c9793199290fefc36f027da65f7e7e50f9cd43 100644 (file)
@@ -60,4 +60,6 @@
 #define SO_SECURITY_ENCRYPTION_TRANSPORT       20
 #define SO_SECURITY_ENCRYPTION_NETWORK         21
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
index 65a1a64bf9340b2b8ec8d4321d26c1deb968739a..6817be9573a6bf65d29ef5092a4a869017cf87bc 100644 (file)
@@ -52,4 +52,6 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
index a0d0507a5034969b70bbc1139631ef5f4cdc077d..35863f260929abe002d57f154c3d5749b2ce1d69 100644 (file)
@@ -52,4 +52,6 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* __ASM_AVR32_SOCKET_H */
index 5213c96521860dc83b3ab8755f971ca2ac5c6887..2ca702e44d4759420051ed73dc9c3662eb2fb5c4 100644 (file)
@@ -50,4 +50,7 @@
 #define SO_PASSSEC             34
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
+
+#define SO_MARK                        36
+
 #endif                         /* _ASM_SOCKET_H */
index 5b18dfdf1748f2c6538ab3ca2c65d7ef3468e342..9df0ca82f5dedf90437954406dc201e1d073f898 100644 (file)
@@ -54,6 +54,8 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
 
 
index a823befd11dd8f8ce35c0d3080717032d4c16d87..e51ca67b9356c5dfac236509c2ea00387a3ee911 100644 (file)
@@ -52,5 +52,7 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
 
index 39911d8c968406c5040dab05d8c8d5b792d09bec..da2520dbf2547e2643af27749b178e7e5a4dd0eb 100644 (file)
@@ -52,4 +52,6 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
index 9e42ce43cfbeaf92007e07119af6d82c16df5bae..d5ef0aa3e312e82630c0f7d636f6d0c9d2156b95 100644 (file)
@@ -61,4 +61,6 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_IA64_SOCKET_H */
index 793d5d30c8505f03ddb1c0e8801c771177f7e82e..9a0e200122249e5cae09d90d73b01d820dbe9e83 100644 (file)
@@ -52,4 +52,6 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_M32R_SOCKET_H */
index 6d21b90863ad1220d8f614e7b071f7bbc62d8f89..dbc64e92c41ac572bd80b99790f80977ed5e8c75 100644 (file)
@@ -52,4 +52,6 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
index 163dcb1a9689d3687aa6e5775bcaf82eee65932f..29bc0aad2ebc7fb5c69bdcf34ebbd739a9a9f18a 100644 (file)
@@ -53,7 +53,7 @@ static inline void __flush_cache_all(void)
 #endif /* CONFIG_M5407 */
 #if defined(CONFIG_M527x) || defined(CONFIG_M528x)
        __asm__ __volatile__ (
-               "movel  #0x81400100, %%d0\n\t"
+               "movel  #0x81000200, %%d0\n\t"
                "movec  %%d0, %%CACR\n\t"
                "nop\n\t"
                : : : "d0" );
index 7b61a8a529f52063fa01b760a78ca125b4e3235a..c042634fadaa0cecb2c83d0ea9e3feac3ecc91d5 100644 (file)
@@ -60,7 +60,7 @@
        nop
        movel   #0x0000c020, %d0        /* Set SDRAM cached only */
        movec   %d0, %ACR0
-       movel   #0xff00c000, %d0        /* Cache Flash also */
+       movel   #0x00000000, %d0        /* No other regions cached */
        movec   %d0, %ACR1
        movel   #0x80000200, %d0        /* Setup cache mask */
        movec   %d0, %CACR              /* Enable cache */
index 873d0805219ce7a635751df3367b87c2f773b07f..1319a81814b15cb840f61987fc37842145b58668 100644 (file)
@@ -12,7 +12,6 @@
 #define        mcfuart_h
 /****************************************************************************/
 
-
 /*
  *     Define the base address of the UARTS within the MBAR address
  *     space.
@@ -33,7 +32,7 @@
 #define MCFUART_BASE2          0x240           /* Base address of UART2 */
 #define MCFUART_BASE3          0x280           /* Base address of UART3 */
 #elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407)
-#if defined(CONFIG_NETtel) || defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3)
+#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
 #define MCFUART_BASE1          0x200           /* Base address of UART1 */
 #define MCFUART_BASE2          0x1c0           /* Base address of UART2 */
 #else
index 95945689b1c669193b20765a1d202bebecca8b1a..63f60254d308741efde979586ccdd9456ac47811 100644 (file)
@@ -73,6 +73,8 @@ To add: #define SO_REUSEPORT 0x0200   /* Allow local address and port reuse.  */
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #ifdef __KERNEL__
 
 /** sock_type - Socket types
index 99e868f6a8f52fa5e13082c62306a61c53e96186..69a7a0d30b025335f927979f1eb14e7750d3c09a 100644 (file)
@@ -52,4 +52,6 @@
 #define SO_PEERSEC             0x401d
 #define SO_PASSSEC             0x401e
 
+#define SO_MARK                        0x401f
+
 #endif /* _ASM_SOCKET_H */
index 403e9fde2eb52eea67537b823bfe9f33925a6042..f5a4e168e498b6641c3c1ea3b0afac640a233015 100644 (file)
@@ -59,4 +59,6 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_POWERPC_SOCKET_H */
index 1161ebe3dec9530cc0ac416722ad6c15a79de8e5..c786ab623b2d2d0f3f63aedfa5873248f40b156d 100644 (file)
@@ -60,4 +60,6 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
index c48d6fc9da3866da5fc5fa3e70d5ec76f654801b..6d4bf6512959ef0a8b2e610e4fd2aeb99c88e5bf 100644 (file)
@@ -52,4 +52,6 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* __ASM_SH_SOCKET_H */
index 7c1423997cf0d41bbd0f6830e8e5993fefaec360..2e2bd0b7c8e3e34616c6621b8e7dbd2cc7683567 100644 (file)
@@ -52,6 +52,8 @@
 #define SO_TIMESTAMPNS         0x0021
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        0x0022
+
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION             0x5001
 #define SO_SECURITY_ENCRYPTION_TRANSPORT       0x5002
index 986441dcb8f03ba39eab3e3a972ca0e5159b7bbf..44a625af6e317e91758494fd906a3ef1597cdc79 100644 (file)
@@ -57,4 +57,5 @@
 #define SO_SECURITY_ENCRYPTION_TRANSPORT       0x5002
 #define SO_SECURITY_ENCRYPTION_NETWORK         0x5004
 
+#define SO_MARK                        0x0022
 #endif /* _ASM_SOCKET_H */
index a4c2493b025feffb3ddb596e4a0072c28b88eb89..e199a2bf12aa62d80e77ab2ccd02486a59269a29 100644 (file)
@@ -52,4 +52,6 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* __V850_SOCKET_H__ */
index 99ca648b94c54122057342ec4bcef093b0d0fbe6..80af9c4ccad7f05cd09db4d0d212ec2a0753ed04 100644 (file)
@@ -52,4 +52,6 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
index 1f5aeacb9da27ead7b2623a74f7a557717bfc2c0..6100682b1da22248debf67ccf0cfca02a524180f 100644 (file)
@@ -63,4 +63,6 @@
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _XTENSA_SOCKET_H */
index 8d9eaaebded7e753c6a79af7fb03064fea39cd90..fc4e3db649e895eaa4d82d1f37af40170166100a 100644 (file)
@@ -17,8 +17,6 @@ struct ipv4_devconf
        DECLARE_BITMAP(state, __NET_IPV4_CONF_MAX - 1);
 };
 
-extern struct ipv4_devconf ipv4_devconf;
-
 struct in_device
 {
        struct net_device       *dev;
index 2075d6da2a313d9791ea1e714cb5beb18c91f7e6..056a17a4f34f5bbf4e31f8bd9ea6c1ccd0e0c9fe 100644 (file)
@@ -371,6 +371,8 @@ struct input_absinfo {
 #define KEY_BRIGHTNESS_ZERO    244     /* brightness off, use ambient */
 #define KEY_DISPLAY_OFF                245     /* display device to off state */
 
+#define KEY_WIMAX              246
+
 #define BTN_MISC               0x100
 #define BTN_0                  0x100
 #define BTN_1                  0x101
index 5d35a4cc3bfff3a965132151db9f0ccd1c13df7e..4aaefc349a4b1d8d2cac828c0737c0a60a35a10d 100644 (file)
@@ -457,14 +457,22 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk)
 #define inet_v6_ipv6only(__sk)         0
 #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
 
-#define INET6_MATCH(__sk, __hash, __saddr, __daddr, __ports, __dif)\
-       (((__sk)->sk_hash == (__hash))                          && \
+#define INET6_MATCH(__sk, __net, __hash, __saddr, __daddr, __ports, __dif)\
+       (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net))   && \
         ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports))      && \
         ((__sk)->sk_family             == AF_INET6)            && \
         ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr))     && \
         ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr)) && \
         (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
 
+#define INET6_TW_MATCH(__sk, __net, __hash, __saddr, __daddr, __ports, __dif) \
+       (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net))   && \
+        (*((__portpair *)&(inet_twsk(__sk)->tw_dport)) == (__ports))   && \
+        ((__sk)->sk_family            == PF_INET6)                     && \
+        (ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_daddr, (__saddr)))   && \
+        (ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_rcv_saddr, (__daddr))) && \
+        (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
+
 #endif /* __KERNEL__ */
 
 #endif /* _IPV6_H */
index b0813c3286b1bbfd035415c86cf592f39a52245b..047d432bde5551784534de19482b46d3d3eb83da 100644 (file)
@@ -1414,12 +1414,16 @@ extern void             dev_set_rx_mode(struct net_device *dev);
 extern void            __dev_set_rx_mode(struct net_device *dev);
 extern int             dev_unicast_delete(struct net_device *dev, void *addr, int alen);
 extern int             dev_unicast_add(struct net_device *dev, void *addr, int alen);
+extern int             dev_unicast_sync(struct net_device *to, struct net_device *from);
+extern void            dev_unicast_unsync(struct net_device *to, struct net_device *from);
 extern int             dev_mc_delete(struct net_device *dev, void *addr, int alen, int all);
 extern int             dev_mc_add(struct net_device *dev, void *addr, int alen, int newonly);
 extern int             dev_mc_sync(struct net_device *to, struct net_device *from);
 extern void            dev_mc_unsync(struct net_device *to, struct net_device *from);
 extern int             __dev_addr_delete(struct dev_addr_list **list, int *count, void *addr, int alen, int all);
 extern int             __dev_addr_add(struct dev_addr_list **list, int *count, void *addr, int alen, int newonly);
+extern int             __dev_addr_sync(struct dev_addr_list **to, int *to_count, struct dev_addr_list **from, int *from_count);
+extern void            __dev_addr_unsync(struct dev_addr_list **to, int *to_count, struct dev_addr_list **from, int *from_count);
 extern void            dev_set_promiscuity(struct net_device *dev, int inc);
 extern void            dev_set_allmulti(struct net_device *dev, int inc);
 extern void            netdev_state_change(struct net_device *dev);
index 23435496d24abde8f909854a0866d6b25edafc6a..3bbde0c3a8a62cae3a01bb060cf0ffddbf93287f 100644 (file)
@@ -4,7 +4,7 @@
 
 #include <linux/netfilter/nf_conntrack_common.h>
 
-extern const char *pptp_msg_name[];
+extern const char *const pptp_msg_name[];
 
 /* state of the control session */
 enum pptp_ctrlsess_state {
index 9fff19779bd5ee5a6b3eb6290b1af22fe1c5f415..8e5ce1ca7bfcd48276c5b17c8572824abb3f7ea1 100644 (file)
@@ -30,9 +30,9 @@ extern unsigned int (*nf_nat_sdp_hook)(struct sk_buff *skb,
                                       struct nf_conntrack_expect *exp,
                                       const char *dptr);
 
-extern int ct_sip_get_info(struct nf_conn *ct, const char *dptr, size_t dlen,
-                          unsigned int *matchoff, unsigned int *matchlen,
-                          enum sip_header_pos pos);
+extern int ct_sip_get_info(const struct nf_conn *ct, const char *dptr,
+                           size_t dlen, unsigned int *matchoff,
+                           unsigned int *matchlen, enum sip_header_pos pos);
 extern int ct_sip_lnlen(const char *line, const char *limit);
 extern const char *ct_sip_search(const char *needle, const char *haystack,
                                 size_t needle_len, size_t haystack_len,
index b99ede51318a25c9d895259fc0eabbeebe0a9635..b2c62cc618f5314f5ce0717008bd2af29e064d80 100644 (file)
@@ -214,7 +214,7 @@ struct xt_match
        /* Free to use by each match */
        unsigned long data;
 
-       char *table;
+       const char *table;
        unsigned int matchsize;
        unsigned int compatsize;
        unsigned int hooks;
@@ -261,7 +261,7 @@ struct xt_target
        /* Set this to THIS_MODULE if you are a module, otherwise NULL */
        struct module *me;
 
-       char *table;
+       const char *table;
        unsigned int targetsize;
        unsigned int compatsize;
        unsigned int hooks;
@@ -277,7 +277,7 @@ struct xt_table
        struct list_head list;
 
        /* A unique name... */
-       char name[XT_TABLE_MAXNAMELEN];
+       const char name[XT_TABLE_MAXNAMELEN];
 
        /* What hooks you will enter on */
        unsigned int valid_hooks;
@@ -335,9 +335,10 @@ extern int xt_check_target(const struct xt_target *target, unsigned short family
                           unsigned int size, const char *table, unsigned int hook,
                           unsigned short proto, int inv_proto);
 
-extern int xt_register_table(struct xt_table *table,
-                            struct xt_table_info *bootstrap,
-                            struct xt_table_info *newinfo);
+extern struct xt_table *xt_register_table(struct net *net,
+                                         struct xt_table *table,
+                                         struct xt_table_info *bootstrap,
+                                         struct xt_table_info *newinfo);
 extern void *xt_unregister_table(struct xt_table *table);
 
 extern struct xt_table_info *xt_replace_table(struct xt_table *table,
@@ -352,11 +353,12 @@ extern struct xt_target *xt_request_find_target(int af, const char *name,
 extern int xt_find_revision(int af, const char *name, u8 revision, int target,
                            int *err);
 
-extern struct xt_table *xt_find_table_lock(int af, const char *name);
+extern struct xt_table *xt_find_table_lock(struct net *net, int af,
+                                          const char *name);
 extern void xt_table_unlock(struct xt_table *t);
 
-extern int xt_proto_init(int af);
-extern void xt_proto_fini(int af);
+extern int xt_proto_init(struct net *net, int af);
+extern void xt_proto_fini(struct net *net, int af);
 
 extern struct xt_table_info *xt_alloc_table_info(unsigned int size);
 extern void xt_free_table_info(struct xt_table_info *info);
@@ -430,15 +432,15 @@ extern short xt_compat_calc_jump(int af, unsigned int offset);
 
 extern int xt_compat_match_offset(struct xt_match *match);
 extern int xt_compat_match_from_user(struct xt_entry_match *m,
-                                    void **dstptr, int *size);
+                                    void **dstptr, unsigned int *size);
 extern int xt_compat_match_to_user(struct xt_entry_match *m,
-                                  void __user **dstptr, int *size);
+                                  void __user **dstptr, unsigned int *size);
 
 extern int xt_compat_target_offset(struct xt_target *target);
 extern void xt_compat_target_from_user(struct xt_entry_target *t,
-                                      void **dstptr, int *size);
+                                      void **dstptr, unsigned int *size);
 extern int xt_compat_target_to_user(struct xt_entry_target *t,
-                                   void __user **dstptr, int *size);
+                                   void __user **dstptr, unsigned int *size);
 
 #endif /* CONFIG_COMPAT */
 #endif /* __KERNEL__ */
index d2492a3329bed137c9c46f7354a0b1f0599e005f..f3fd83e46babdf422bf6952f0c21214fdac57d98 100644 (file)
@@ -6,9 +6,6 @@
 #define _XT_CONNTRACK_H
 
 #include <linux/netfilter/nf_conntrack_tuple_common.h>
-#ifdef __KERNEL__
-#      include <linux/in.h>
-#endif
 
 #define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
 #define XT_CONNTRACK_STATE_INVALID (1 << 0)
 #define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
 
 /* flags, invflags: */
-#define XT_CONNTRACK_STATE     0x01
-#define XT_CONNTRACK_PROTO     0x02
-#define XT_CONNTRACK_ORIGSRC   0x04
-#define XT_CONNTRACK_ORIGDST   0x08
-#define XT_CONNTRACK_REPLSRC   0x10
-#define XT_CONNTRACK_REPLDST   0x20
-#define XT_CONNTRACK_STATUS    0x40
-#define XT_CONNTRACK_EXPIRES   0x80
+enum {
+       XT_CONNTRACK_STATE        = 1 << 0,
+       XT_CONNTRACK_PROTO        = 1 << 1,
+       XT_CONNTRACK_ORIGSRC      = 1 << 2,
+       XT_CONNTRACK_ORIGDST      = 1 << 3,
+       XT_CONNTRACK_REPLSRC      = 1 << 4,
+       XT_CONNTRACK_REPLDST      = 1 << 5,
+       XT_CONNTRACK_STATUS       = 1 << 6,
+       XT_CONNTRACK_EXPIRES      = 1 << 7,
+       XT_CONNTRACK_ORIGSRC_PORT = 1 << 8,
+       XT_CONNTRACK_ORIGDST_PORT = 1 << 9,
+       XT_CONNTRACK_REPLSRC_PORT = 1 << 10,
+       XT_CONNTRACK_REPLDST_PORT = 1 << 11,
+       XT_CONNTRACK_DIRECTION    = 1 << 12,
+};
 
 /* This is exposed to userspace, so remains frozen in time. */
 struct ip_conntrack_old_tuple
@@ -70,8 +74,10 @@ struct xt_conntrack_mtinfo1 {
        union nf_inet_addr repldst_addr, repldst_mask;
        u_int32_t expires_min, expires_max;
        u_int16_t l4proto;
+       __be16 origsrc_port, origdst_port;
+       __be16 replsrc_port, repldst_port;
+       u_int16_t match_flags, invert_flags;
        u_int8_t state_mask, status_mask;
-       u_int8_t match_flags, invert_flags;
 };
 
 #endif /*_XT_CONNTRACK_H*/
index c19972e4564da6182cf4fc3b9799ba2f44aa8e58..58b818ee41caa25f9d18a9c265fb2f7325f80826 100644 (file)
@@ -9,13 +9,16 @@
 /* details of this structure hidden by the implementation */
 struct xt_hashlimit_htable;
 
-#define XT_HASHLIMIT_HASH_DIP  0x0001
-#define XT_HASHLIMIT_HASH_DPT  0x0002
-#define XT_HASHLIMIT_HASH_SIP  0x0004
-#define XT_HASHLIMIT_HASH_SPT  0x0008
+enum {
+       XT_HASHLIMIT_HASH_DIP = 1 << 0,
+       XT_HASHLIMIT_HASH_DPT = 1 << 1,
+       XT_HASHLIMIT_HASH_SIP = 1 << 2,
+       XT_HASHLIMIT_HASH_SPT = 1 << 3,
+       XT_HASHLIMIT_INVERT   = 1 << 4,
+};
 
 struct hashlimit_cfg {
-       u_int32_t mode;   /* bitmask of IPT_HASHLIMIT_HASH_* */
+       u_int32_t mode;   /* bitmask of XT_HASHLIMIT_HASH_* */
        u_int32_t avg;    /* Average secs between packets * scale */
        u_int32_t burst;  /* Period multiplier for upper limit. */
 
@@ -37,4 +40,28 @@ struct xt_hashlimit_info {
                struct xt_hashlimit_info *master;
        } u;
 };
+
+struct hashlimit_cfg1 {
+       u_int32_t mode;   /* bitmask of XT_HASHLIMIT_HASH_* */
+       u_int32_t avg;    /* Average secs between packets * scale */
+       u_int32_t burst;  /* Period multiplier for upper limit. */
+
+       /* user specified */
+       u_int32_t size;         /* how many buckets */
+       u_int32_t max;          /* max number of entries */
+       u_int32_t gc_interval;  /* gc interval */
+       u_int32_t expire;       /* when do entries expire? */
+
+       u_int8_t srcmask, dstmask;
+};
+
+struct xt_hashlimit_mtinfo1 {
+       char name[IFNAMSIZ];
+       struct hashlimit_cfg1 cfg;
+
+       /* Used internally by the kernel */
+       struct xt_hashlimit_htable *hinfo __attribute__((aligned(8)));
+       struct xt_hashlimit_mtinfo1 *master __attribute__((aligned(8)));
+};
+
 #endif /*_XT_HASHLIMIT_H*/
index eacd34efebd51ec818eb94ccf55e4dd6b63c3e97..c84e52cfe415f55ee22563d464cf6b7311bb4df2 100644 (file)
@@ -8,8 +8,8 @@ enum {
 };
 
 struct xt_owner_match_info {
-       u_int32_t uid;
-       u_int32_t gid;
+       u_int32_t uid_min, uid_max;
+       u_int32_t gid_min, gid_max;
        u_int8_t match, invert;
 };
 
index 53dd4df27aa1a881722f8c6a055de3b1e1b7e946..db223ca92c8b00bdbdf10c59007a136aaba1e7eb 100644 (file)
@@ -271,8 +271,9 @@ struct arpt_error
        xt_register_target(tgt); })
 #define arpt_unregister_target(tgt) xt_unregister_target(tgt)
 
-extern int arpt_register_table(struct arpt_table *table,
-                              const struct arpt_replace *repl);
+extern struct arpt_table *arpt_register_table(struct net *net,
+                                             struct arpt_table *table,
+                                             const struct arpt_replace *repl);
 extern void arpt_unregister_table(struct arpt_table *table);
 extern unsigned int arpt_do_table(struct sk_buff *skb,
                                  unsigned int hook,
index 45fcad91e67b4df4246b47c425e941e06f3c1117..bfc889f9027660c60ad4d8c69c238963fd6648ca 100644 (file)
@@ -244,8 +244,9 @@ ipt_get_target(struct ipt_entry *e)
 #include <linux/init.h>
 extern void ipt_init(void) __init;
 
-extern int ipt_register_table(struct xt_table *table,
-                             const struct ipt_replace *repl);
+extern struct xt_table *ipt_register_table(struct net *net,
+                                          struct xt_table *table,
+                                          const struct ipt_replace *repl);
 extern void ipt_unregister_table(struct xt_table *table);
 
 /* Standard entry. */
index 110801d699ee95ab2f649f20a482bf179a1f7bbd..f2507dcc57507871a9f19ccba25a083e03766049 100644 (file)
@@ -305,8 +305,9 @@ ip6t_get_target(struct ip6t_entry *e)
 #include <linux/init.h>
 extern void ip6t_init(void) __init;
 
-extern int ip6t_register_table(struct xt_table *table,
-                              const struct ip6t_replace *repl);
+extern struct xt_table *ip6t_register_table(struct net *net,
+                                           struct xt_table *table,
+                                           const struct ip6t_replace *repl);
 extern void ip6t_unregister_table(struct xt_table *table);
 extern unsigned int ip6t_do_table(struct sk_buff *skb,
                                  unsigned int hook,
index bd13b6f4a98ec0932503273858988795bcc5bf35..fb0713b6ffaf910d6d5d58462d29f5fe2db03f8f 100644 (file)
@@ -219,7 +219,7 @@ struct netlink_callback
        int             (*dump)(struct sk_buff * skb, struct netlink_callback *cb);
        int             (*done)(struct netlink_callback *cb);
        int             family;
-       long            args[5];
+       long            args[6];
 };
 
 struct netlink_notify
index d9db5f62ee4878d1cb71f6da1587a76cbce50ff5..6db69ff5d83eb9f2b6bf137556246ea48cdba03a 100644 (file)
@@ -298,6 +298,12 @@ struct sadb_x_sec_ctx {
 #define SADB_X_EALG_BLOWFISHCBC                7
 #define SADB_EALG_NULL                 11
 #define SADB_X_EALG_AESCBC             12
+#define SADB_X_EALG_AES_CCM_ICV8       14
+#define SADB_X_EALG_AES_CCM_ICV12      15
+#define SADB_X_EALG_AES_CCM_ICV16      16
+#define SADB_X_EALG_AES_GCM_ICV8       18
+#define SADB_X_EALG_AES_GCM_ICV12      19
+#define SADB_X_EALG_AES_GCM_ICV16      20
 #define SADB_X_EALG_CAMELLIACBC                22
 #define SADB_EALG_MAX                   253 /* last EALG */
 /* private allocations should use 249-255 (RFC2407) */
index 30b8571e6b34c25b2311291ad460e2d1754e7862..1c1dba9ea5fba9f0f2916b26e51da13ed14286a9 100644 (file)
@@ -328,6 +328,56 @@ enum
 
 #define TCA_TCINDEX_MAX     (__TCA_TCINDEX_MAX - 1)
 
+/* Flow filter */
+
+enum
+{
+       FLOW_KEY_SRC,
+       FLOW_KEY_DST,
+       FLOW_KEY_PROTO,
+       FLOW_KEY_PROTO_SRC,
+       FLOW_KEY_PROTO_DST,
+       FLOW_KEY_IIF,
+       FLOW_KEY_PRIORITY,
+       FLOW_KEY_MARK,
+       FLOW_KEY_NFCT,
+       FLOW_KEY_NFCT_SRC,
+       FLOW_KEY_NFCT_DST,
+       FLOW_KEY_NFCT_PROTO_SRC,
+       FLOW_KEY_NFCT_PROTO_DST,
+       FLOW_KEY_RTCLASSID,
+       FLOW_KEY_SKUID,
+       FLOW_KEY_SKGID,
+       __FLOW_KEY_MAX,
+};
+
+#define FLOW_KEY_MAX   (__FLOW_KEY_MAX - 1)
+
+enum
+{
+       FLOW_MODE_MAP,
+       FLOW_MODE_HASH,
+};
+
+enum
+{
+       TCA_FLOW_UNSPEC,
+       TCA_FLOW_KEYS,
+       TCA_FLOW_MODE,
+       TCA_FLOW_BASECLASS,
+       TCA_FLOW_RSHIFT,
+       TCA_FLOW_ADDEND,
+       TCA_FLOW_MASK,
+       TCA_FLOW_XOR,
+       TCA_FLOW_DIVISOR,
+       TCA_FLOW_ACT,
+       TCA_FLOW_POLICE,
+       TCA_FLOW_EMATCHES,
+       __TCA_FLOW_MAX
+};
+
+#define TCA_FLOW_MAX   (__TCA_FLOW_MAX - 1)
+
 /* Basic filter */
 
 enum
index 32761352e858cd4c95b15ab215b8c39be9fe756e..dbb7ac37960d2a092d4250235aa3a37e5a97e61c 100644 (file)
@@ -150,6 +150,11 @@ struct tc_sfq_qopt
        unsigned        flows;          /* Maximal number of flows  */
 };
 
+struct tc_sfq_xstats
+{
+       __s32           allot;
+};
+
 /*
  *  NOTE: limit, divisor and flows are hardwired to code at the moment.
  *
index 0ce5e0b52dbdef816607be8beae4c1b620b8b95a..e3ab21d7fc7f1973ec9483885012d83e800e1eb9 100644 (file)
  * RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
  * RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
  * RFKILL_TYPE_UWB: switch is on a ultra wideband device.
+ * RFKILL_TYPE_WIMAX: switch is on a WiMAX device.
  */
 enum rfkill_type {
        RFKILL_TYPE_WLAN ,
        RFKILL_TYPE_BLUETOOTH,
        RFKILL_TYPE_UWB,
+       RFKILL_TYPE_WIMAX,
        RFKILL_TYPE_MAX,
 };
 
index c618fbf7d173c4974da2adf399edf51a2c5034cc..dfe975a9967ef16767be9040283ab8c34bb39e93 100644 (file)
@@ -108,9 +108,6 @@ struct nf_bridge_info {
        atomic_t use;
        struct net_device *physindev;
        struct net_device *physoutdev;
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-       struct net_device *netoutdev;
-#endif
        unsigned int mask;
        unsigned long data[32 / sizeof(unsigned long)];
 };
index 86d3effb283626f8b053db379ceacca52c6bef06..5df62ef1280c176d2299d61dd6e3148161bd3b63 100644 (file)
@@ -227,7 +227,7 @@ enum
        LINUX_MIB_XFRMINNOSTATES,               /* XfrmInNoStates */
        LINUX_MIB_XFRMINSTATEPROTOERROR,        /* XfrmInStateProtoError */
        LINUX_MIB_XFRMINSTATEMODEERROR,         /* XfrmInStateModeError */
-       LINUX_MIB_XFRMINSEQOUTOFWINDOW,         /* XfrmInSeqOutOfWindow */
+       LINUX_MIB_XFRMINSTATESEQERROR,          /* XfrmInStateSeqError */
        LINUX_MIB_XFRMINSTATEEXPIRED,           /* XfrmInStateExpired */
        LINUX_MIB_XFRMINSTATEMISMATCH,          /* XfrmInStateMismatch */
        LINUX_MIB_XFRMINSTATEINVALID,           /* XfrmInStateInvalid */
@@ -241,6 +241,7 @@ enum
        LINUX_MIB_XFRMOUTNOSTATES,              /* XfrmOutNoStates */
        LINUX_MIB_XFRMOUTSTATEPROTOERROR,       /* XfrmOutStateProtoError */
        LINUX_MIB_XFRMOUTSTATEMODEERROR,        /* XfrmOutStateModeError */
+       LINUX_MIB_XFRMOUTSTATESEQERROR,         /* XfrmOutStateSeqError */
        LINUX_MIB_XFRMOUTSTATEEXPIRED,          /* XfrmOutStateExpired */
        LINUX_MIB_XFRMOUTPOLBLOCK,              /* XfrmOutPolBlock */
        LINUX_MIB_XFRMOUTPOLDEAD,               /* XfrmOutPolDead */
index 89faebfe48b8aa4a29b7f4ac3d756aedb71b4251..bf4ae4e138f747d79c2903b7a09771f5145112c4 100644 (file)
@@ -440,8 +440,8 @@ enum
 
 enum {
        NET_IPV4_ROUTE_FLUSH=1,
-       NET_IPV4_ROUTE_MIN_DELAY=2,
-       NET_IPV4_ROUTE_MAX_DELAY=3,
+       NET_IPV4_ROUTE_MIN_DELAY=2, /* obsolete since 2.6.25 */
+       NET_IPV4_ROUTE_MAX_DELAY=3, /* obsolete since 2.6.25 */
        NET_IPV4_ROUTE_GC_THRESH=4,
        NET_IPV4_ROUTE_MAX_SIZE=5,
        NET_IPV4_ROUTE_GC_MIN_INTERVAL=6,
index f4f8d19158e4bb80d7ef39080ec1fabf4584cf7a..b94c0e4efe2487a027dbc70ae9ed36336f392345 100644 (file)
@@ -126,7 +126,7 @@ typedef             __s64           int64_t;
 #endif
 
 /* this is a special 64bit data type that is 8-byte aligned */
-#define aligned_u64 unsigned long long __attribute__((aligned(8)))
+#define aligned_u64 __u64 __attribute__((aligned(8)))
 #define aligned_be64 __be64 __attribute__((aligned(8)))
 #define aligned_le64 __le64 __attribute__((aligned(8)))
 
diff --git a/include/linux/usb/rndis_host.h b/include/linux/usb/rndis_host.h
new file mode 100644 (file)
index 0000000..edc1d4a
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * Host Side support for RNDIS Networking Links
+ * Copyright (C) 2005 by David Brownell
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef        __RNDIS_HOST_H
+#define        __RNDIS_HOST_H
+
+
+/*
+ * CONTROL uses CDC "encapsulated commands" with funky notifications.
+ *  - control-out:  SEND_ENCAPSULATED
+ *  - interrupt-in:  RESPONSE_AVAILABLE
+ *  - control-in:  GET_ENCAPSULATED
+ *
+ * We'll try to ignore the RESPONSE_AVAILABLE notifications.
+ *
+ * REVISIT some RNDIS implementations seem to have curious issues still
+ * to be resolved.
+ */
+struct rndis_msg_hdr {
+       __le32  msg_type;                       /* RNDIS_MSG_* */
+       __le32  msg_len;
+       // followed by data that varies between messages
+       __le32  request_id;
+       __le32  status;
+       // ... and more
+} __attribute__ ((packed));
+
+/* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */
+#define        CONTROL_BUFFER_SIZE             1025
+
+/* RNDIS defines an (absurdly huge) 10 second control timeout,
+ * but ActiveSync seems to use a more usual 5 second timeout
+ * (which matches the USB 2.0 spec).
+ */
+#define        RNDIS_CONTROL_TIMEOUT_MS        (5 * 1000)
+
+
+#define ccpu2 __constant_cpu_to_le32
+
+#define RNDIS_MSG_COMPLETION   ccpu2(0x80000000)
+
+/* codes for "msg_type" field of rndis messages;
+ * only the data channel uses packet messages (maybe batched);
+ * everything else goes on the control channel.
+ */
+#define RNDIS_MSG_PACKET       ccpu2(0x00000001)       /* 1-N packets */
+#define RNDIS_MSG_INIT         ccpu2(0x00000002)
+#define RNDIS_MSG_INIT_C       (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_HALT         ccpu2(0x00000003)
+#define RNDIS_MSG_QUERY                ccpu2(0x00000004)
+#define RNDIS_MSG_QUERY_C      (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_SET          ccpu2(0x00000005)
+#define RNDIS_MSG_SET_C                (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_RESET                ccpu2(0x00000006)
+#define RNDIS_MSG_RESET_C      (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_INDICATE     ccpu2(0x00000007)
+#define RNDIS_MSG_KEEPALIVE    ccpu2(0x00000008)
+#define RNDIS_MSG_KEEPALIVE_C  (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION)
+
+/* codes for "status" field of completion messages */
+#define        RNDIS_STATUS_SUCCESS            ccpu2(0x00000000)
+#define        RNDIS_STATUS_FAILURE            ccpu2(0xc0000001)
+#define        RNDIS_STATUS_INVALID_DATA       ccpu2(0xc0010015)
+#define        RNDIS_STATUS_NOT_SUPPORTED      ccpu2(0xc00000bb)
+#define        RNDIS_STATUS_MEDIA_CONNECT      ccpu2(0x4001000b)
+#define        RNDIS_STATUS_MEDIA_DISCONNECT   ccpu2(0x4001000c)
+
+/* codes for OID_GEN_PHYSICAL_MEDIUM */
+#define        RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED       ccpu2(0x00000000)
+#define        RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN      ccpu2(0x00000001)
+#define        RNDIS_PHYSICAL_MEDIUM_CABLE_MODEM       ccpu2(0x00000002)
+#define        RNDIS_PHYSICAL_MEDIUM_PHONE_LINE        ccpu2(0x00000003)
+#define        RNDIS_PHYSICAL_MEDIUM_POWER_LINE        ccpu2(0x00000004)
+#define        RNDIS_PHYSICAL_MEDIUM_DSL               ccpu2(0x00000005)
+#define        RNDIS_PHYSICAL_MEDIUM_FIBRE_CHANNEL     ccpu2(0x00000006)
+#define        RNDIS_PHYSICAL_MEDIUM_1394              ccpu2(0x00000007)
+#define        RNDIS_PHYSICAL_MEDIUM_WIRELESS_WAN      ccpu2(0x00000008)
+#define        RNDIS_PHYSICAL_MEDIUM_MAX               ccpu2(0x00000009)
+
+struct rndis_data_hdr {
+       __le32  msg_type;               /* RNDIS_MSG_PACKET */
+       __le32  msg_len;                // rndis_data_hdr + data_len + pad
+       __le32  data_offset;            // 36 -- right after header
+       __le32  data_len;               // ... real packet size
+
+       __le32  oob_data_offset;        // zero
+       __le32  oob_data_len;           // zero
+       __le32  num_oob;                // zero
+       __le32  packet_data_offset;     // zero
+
+       __le32  packet_data_len;        // zero
+       __le32  vc_handle;              // zero
+       __le32  reserved;               // zero
+} __attribute__ ((packed));
+
+struct rndis_init {            /* OUT */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_INIT */
+       __le32  msg_len;                        // 24
+       __le32  request_id;
+       __le32  major_version;                  // of rndis (1.0)
+       __le32  minor_version;
+       __le32  max_transfer_size;
+} __attribute__ ((packed));
+
+struct rndis_init_c {          /* IN */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_INIT_C */
+       __le32  msg_len;
+       __le32  request_id;
+       __le32  status;
+       __le32  major_version;                  // of rndis (1.0)
+       __le32  minor_version;
+       __le32  device_flags;
+       __le32  medium;                         // zero == 802.3
+       __le32  max_packets_per_message;
+       __le32  max_transfer_size;
+       __le32  packet_alignment;               // max 7; (1<<n) bytes
+       __le32  af_list_offset;                 // zero
+       __le32  af_list_size;                   // zero
+} __attribute__ ((packed));
+
+struct rndis_halt {            /* OUT (no reply) */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_HALT */
+       __le32  msg_len;
+       __le32  request_id;
+} __attribute__ ((packed));
+
+struct rndis_query {           /* OUT */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_QUERY */
+       __le32  msg_len;
+       __le32  request_id;
+       __le32  oid;
+       __le32  len;
+       __le32  offset;
+/*?*/  __le32  handle;                         // zero
+} __attribute__ ((packed));
+
+struct rndis_query_c {         /* IN */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_QUERY_C */
+       __le32  msg_len;
+       __le32  request_id;
+       __le32  status;
+       __le32  len;
+       __le32  offset;
+} __attribute__ ((packed));
+
+struct rndis_set {             /* OUT */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_SET */
+       __le32  msg_len;
+       __le32  request_id;
+       __le32  oid;
+       __le32  len;
+       __le32  offset;
+/*?*/  __le32  handle;                         // zero
+} __attribute__ ((packed));
+
+struct rndis_set_c {           /* IN */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_SET_C */
+       __le32  msg_len;
+       __le32  request_id;
+       __le32  status;
+} __attribute__ ((packed));
+
+struct rndis_reset {           /* IN */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_RESET */
+       __le32  msg_len;
+       __le32  reserved;
+} __attribute__ ((packed));
+
+struct rndis_reset_c {         /* OUT */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_RESET_C */
+       __le32  msg_len;
+       __le32  status;
+       __le32  addressing_lost;
+} __attribute__ ((packed));
+
+struct rndis_indicate {                /* IN (unrequested) */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_INDICATE */
+       __le32  msg_len;
+       __le32  status;
+       __le32  length;
+       __le32  offset;
+/**/   __le32  diag_status;
+       __le32  error_offset;
+/**/   __le32  message;
+} __attribute__ ((packed));
+
+struct rndis_keepalive {       /* OUT (optionally IN) */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_KEEPALIVE */
+       __le32  msg_len;
+       __le32  request_id;
+} __attribute__ ((packed));
+
+struct rndis_keepalive_c {     /* IN (optionally OUT) */
+       // header and:
+       __le32  msg_type;                       /* RNDIS_MSG_KEEPALIVE_C */
+       __le32  msg_len;
+       __le32  request_id;
+       __le32  status;
+} __attribute__ ((packed));
+
+/* NOTE:  about 30 OIDs are "mandatory" for peripherals to support ... and
+ * there are gobs more that may optionally be supported.  We'll avoid as much
+ * of that mess as possible.
+ */
+#define OID_802_3_PERMANENT_ADDRESS    ccpu2(0x01010101)
+#define OID_GEN_MAXIMUM_FRAME_SIZE     ccpu2(0x00010106)
+#define OID_GEN_CURRENT_PACKET_FILTER  ccpu2(0x0001010e)
+#define OID_GEN_PHYSICAL_MEDIUM                ccpu2(0x00010202)
+
+/* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */
+#define RNDIS_PACKET_TYPE_DIRECTED             ccpu2(0x00000001)
+#define RNDIS_PACKET_TYPE_MULTICAST            ccpu2(0x00000002)
+#define RNDIS_PACKET_TYPE_ALL_MULTICAST                ccpu2(0x00000004)
+#define RNDIS_PACKET_TYPE_BROADCAST            ccpu2(0x00000008)
+#define RNDIS_PACKET_TYPE_SOURCE_ROUTING       ccpu2(0x00000010)
+#define RNDIS_PACKET_TYPE_PROMISCUOUS          ccpu2(0x00000020)
+#define RNDIS_PACKET_TYPE_SMT                  ccpu2(0x00000040)
+#define RNDIS_PACKET_TYPE_ALL_LOCAL            ccpu2(0x00000080)
+#define RNDIS_PACKET_TYPE_GROUP                        ccpu2(0x00001000)
+#define RNDIS_PACKET_TYPE_ALL_FUNCTIONAL       ccpu2(0x00002000)
+#define RNDIS_PACKET_TYPE_FUNCTIONAL           ccpu2(0x00004000)
+#define RNDIS_PACKET_TYPE_MAC_FRAME            ccpu2(0x00008000)
+
+/* default filter used with RNDIS devices */
+#define RNDIS_DEFAULT_FILTER ( \
+       RNDIS_PACKET_TYPE_DIRECTED | \
+       RNDIS_PACKET_TYPE_BROADCAST | \
+       RNDIS_PACKET_TYPE_ALL_MULTICAST | \
+       RNDIS_PACKET_TYPE_PROMISCUOUS)
+
+/* Flags to require specific physical medium type for generic_rndis_bind() */
+#define FLAG_RNDIS_PHYM_NOT_WIRELESS   0x0001
+#define FLAG_RNDIS_PHYM_WIRELESS       0x0002
+
+
+extern void rndis_status(struct usbnet *dev, struct urb *urb);
+extern int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf);
+extern int
+generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags);
+extern void rndis_unbind(struct usbnet *dev, struct usb_interface *intf);
+extern int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb);
+extern struct sk_buff *
+rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags);
+
+#endif /* __RNDIS_HOST_H */
+
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
new file mode 100644 (file)
index 0000000..e0501da
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * USB Networking Link Interface
+ *
+ * Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net>
+ * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef        __USBNET_H
+#define        __USBNET_H
+
+
+/* interface from usbnet core to each USB networking link we handle */
+struct usbnet {
+       /* housekeeping */
+       struct usb_device       *udev;
+       struct usb_interface    *intf;
+       struct driver_info      *driver_info;
+       const char              *driver_name;
+       void                    *driver_priv;
+       wait_queue_head_t       *wait;
+       struct mutex            phy_mutex;
+       unsigned char           suspend_count;
+
+       /* i/o info: pipes etc */
+       unsigned                in, out;
+       struct usb_host_endpoint *status;
+       unsigned                maxpacket;
+       struct timer_list       delay;
+
+       /* protocol/interface state */
+       struct net_device       *net;
+       struct net_device_stats stats;
+       int                     msg_enable;
+       unsigned long           data [5];
+       u32                     xid;
+       u32                     hard_mtu;       /* count any extra framing */
+       size_t                  rx_urb_size;    /* size for rx urbs */
+       struct mii_if_info      mii;
+
+       /* various kinds of pending driver work */
+       struct sk_buff_head     rxq;
+       struct sk_buff_head     txq;
+       struct sk_buff_head     done;
+       struct urb              *interrupt;
+       struct tasklet_struct   bh;
+
+       struct work_struct      kevent;
+       unsigned long           flags;
+#              define EVENT_TX_HALT    0
+#              define EVENT_RX_HALT    1
+#              define EVENT_RX_MEMORY  2
+#              define EVENT_STS_SPLIT  3
+#              define EVENT_LINK_RESET 4
+};
+
+static inline struct usb_driver *driver_of(struct usb_interface *intf)
+{
+       return to_usb_driver(intf->dev.driver);
+}
+
+/* interface from the device/framing level "minidriver" to core */
+struct driver_info {
+       char            *description;
+
+       int             flags;
+/* framing is CDC Ethernet, not writing ZLPs (hw issues), or optionally: */
+#define FLAG_FRAMING_NC        0x0001          /* guard against device dropouts */
+#define FLAG_FRAMING_GL        0x0002          /* genelink batches packets */
+#define FLAG_FRAMING_Z 0x0004          /* zaurus adds a trailer */
+#define FLAG_FRAMING_RN        0x0008          /* RNDIS batches, plus huge header */
+
+#define FLAG_NO_SETINT 0x0010          /* device can't set_interface() */
+#define FLAG_ETHER     0x0020          /* maybe use "eth%d" names */
+
+#define FLAG_FRAMING_AX 0x0040         /* AX88772/178 packets */
+#define FLAG_WLAN      0x0080          /* use "wlan%d" names */
+
+
+       /* init device ... can sleep, or cause probe() failure */
+       int     (*bind)(struct usbnet *, struct usb_interface *);
+
+       /* cleanup device ... can sleep, but can't fail */
+       void    (*unbind)(struct usbnet *, struct usb_interface *);
+
+       /* reset device ... can sleep */
+       int     (*reset)(struct usbnet *);
+
+       /* see if peer is connected ... can sleep */
+       int     (*check_connect)(struct usbnet *);
+
+       /* for status polling */
+       void    (*status)(struct usbnet *, struct urb *);
+
+       /* link reset handling, called from defer_kevent */
+       int     (*link_reset)(struct usbnet *);
+
+       /* fixup rx packet (strip framing) */
+       int     (*rx_fixup)(struct usbnet *dev, struct sk_buff *skb);
+
+       /* fixup tx packet (add framing) */
+       struct sk_buff  *(*tx_fixup)(struct usbnet *dev,
+                               struct sk_buff *skb, gfp_t flags);
+
+       /* early initialization code, can sleep. This is for minidrivers
+        * having 'subminidrivers' that need to do extra initialization
+        * right after minidriver have initialized hardware. */
+       int     (*early_init)(struct usbnet *dev);
+
+       /* called by minidriver when link state changes, state: 0=disconnect,
+        * 1=connect */
+       void    (*link_change)(struct usbnet *dev, int state);
+
+       /* for new devices, use the descriptor-reading code instead */
+       int             in;             /* rx endpoint */
+       int             out;            /* tx endpoint */
+
+       unsigned long   data;           /* Misc driver specific data */
+};
+
+/* Minidrivers are just drivers using the "usbnet" core as a powerful
+ * network-specific subroutine library ... that happens to do pretty
+ * much everything except custom framing and chip-specific stuff.
+ */
+extern int usbnet_probe(struct usb_interface *, const struct usb_device_id *);
+extern int usbnet_suspend (struct usb_interface *, pm_message_t );
+extern int usbnet_resume (struct usb_interface *);
+extern void usbnet_disconnect(struct usb_interface *);
+
+
+/* Drivers that reuse some of the standard USB CDC infrastructure
+ * (notably, using multiple interfaces according to the CDC
+ * union descriptor) get some helper code.
+ */
+struct cdc_state {
+       struct usb_cdc_header_desc      *header;
+       struct usb_cdc_union_desc       *u;
+       struct usb_cdc_ether_desc       *ether;
+       struct usb_interface            *control;
+       struct usb_interface            *data;
+};
+
+extern int usbnet_generic_cdc_bind (struct usbnet *, struct usb_interface *);
+extern void usbnet_cdc_unbind (struct usbnet *, struct usb_interface *);
+
+/* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
+#define        DEFAULT_FILTER  (USB_CDC_PACKET_TYPE_BROADCAST \
+                       |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
+                       |USB_CDC_PACKET_TYPE_PROMISCUOUS \
+                       |USB_CDC_PACKET_TYPE_DIRECTED)
+
+
+/* we record the state for each of our queued skbs */
+enum skb_state {
+       illegal = 0,
+       tx_start, tx_done,
+       rx_start, rx_done, rx_cleanup
+};
+
+struct skb_data {      /* skb->cb is one of these */
+       struct urb              *urb;
+       struct usbnet           *dev;
+       enum skb_state          state;
+       size_t                  length;
+};
+
+
+extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *);
+extern void usbnet_defer_kevent (struct usbnet *, int);
+extern void usbnet_skb_return (struct usbnet *, struct sk_buff *);
+extern void usbnet_unlink_rx_urbs(struct usbnet *);
+
+extern int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd);
+extern int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd);
+extern u32 usbnet_get_link (struct net_device *net);
+extern u32 usbnet_get_msglevel (struct net_device *);
+extern void usbnet_set_msglevel (struct net_device *, u32);
+extern void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);
+extern int usbnet_nway_reset(struct net_device *net);
+
+/* messaging support includes the interface name, so it must not be
+ * used before it has one ... notably, in minidriver bind() calls.
+ */
+#ifdef DEBUG
+#define devdbg(usbnet, fmt, arg...) \
+       printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
+#else
+#define devdbg(usbnet, fmt, arg...) do {} while(0)
+#endif
+
+#define deverr(usbnet, fmt, arg...) \
+       printk(KERN_ERR "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
+#define devwarn(usbnet, fmt, arg...) \
+       printk(KERN_WARNING "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
+
+#define devinfo(usbnet, fmt, arg...) \
+       printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net->name , ## arg); \
+
+
+#endif /* __USBNET_H */
index 9b5b00c4ef9dee3e8f6bace149b16d4a91f87eab..e31b8c84f2c9da7e865d379d32ccabdc9bd463cb 100644 (file)
@@ -96,6 +96,13 @@ struct xfrm_algo {
        char            alg_key[0];
 };
 
+struct xfrm_algo_aead {
+       char    alg_name[64];
+       int     alg_key_len;    /* in bits */
+       int     alg_icv_len;    /* in bits */
+       char    alg_key[0];
+};
+
 struct xfrm_stats {
        __u32   replay_window;
        __u32   replay;
@@ -270,6 +277,7 @@ enum xfrm_attr_type_t {
        XFRMA_LASTUSED,
        XFRMA_POLICY_TYPE,      /* struct xfrm_userpolicy_type */
        XFRMA_MIGRATE,
+       XFRMA_ALG_AEAD,         /* struct xfrm_algo_aead */
        __XFRMA_MAX
 
 #define XFRMA_MAX (__XFRMA_MAX - 1)
index 752eb47b2678b0ceecabd1c44190e16cd59fde66..c236270ec95ee63566e67f52004636004f912c6a 100644 (file)
@@ -13,15 +13,17 @@ extern int  arp_find(unsigned char *haddr, struct sk_buff *skb);
 extern int     arp_ioctl(struct net *net, unsigned int cmd, void __user *arg);
 extern void     arp_send(int type, int ptype, __be32 dest_ip,
                         struct net_device *dev, __be32 src_ip,
-                        unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th);
+                        const unsigned char *dest_hw,
+                        const unsigned char *src_hw, const unsigned char *th);
 extern int     arp_bind_neighbour(struct dst_entry *dst);
 extern int     arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir);
 extern void    arp_ifdown(struct net_device *dev);
 
 extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
                                  struct net_device *dev, __be32 src_ip,
-                                 unsigned char *dest_hw, unsigned char *src_hw,
-                                 unsigned char *target_hw);
+                                 const unsigned char *dest_hw,
+                                 const unsigned char *src_hw,
+                                 const unsigned char *target_hw);
 extern void arp_xmit(struct sk_buff *skb);
 
 extern struct neigh_ops arp_broken_ops;
index c05f529bff2824c9bc6f92a0a454b0f2260cc884..d58451331dbde8a0d9b4231a61bd4957f62cdeec 100644 (file)
@@ -1,58 +1,20 @@
 #ifndef _NET_ESP_H
 #define _NET_ESP_H
 
-#include <linux/crypto.h>
-#include <net/xfrm.h>
-#include <linux/scatterlist.h>
+#include <linux/skbuff.h>
 
-#define ESP_NUM_FAST_SG                4
+struct crypto_aead;
 
-struct esp_data
-{
-       struct scatterlist              sgbuf[ESP_NUM_FAST_SG];
-
-       /* Confidentiality */
-       struct {
-               int                     padlen;         /* 0..255 */
-               /* ivlen is offset from enc_data, where encrypted data start.
-                * It is logically different of crypto_tfm_alg_ivsize(tfm).
-                * We assume that it is either zero (no ivec), or
-                * >= crypto_tfm_alg_ivsize(tfm). */
-               int                     ivlen;
-               int                     ivinitted;
-               u8                      *ivec;          /* ivec buffer */
-               struct crypto_blkcipher *tfm;           /* crypto handle */
-       } conf;
-
-       /* Integrity. It is active when icv_full_len != 0 */
-       struct {
-               u8                      *work_icv;
-               int                     icv_full_len;
-               int                     icv_trunc_len;
-               struct crypto_hash      *tfm;
-       } auth;
+struct esp_data {
+       /* 0..255 */
+       int padlen;
+
+       /* Confidentiality & Integrity */
+       struct crypto_aead *aead;
 };
 
 extern void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len);
 
-static inline int esp_mac_digest(struct esp_data *esp, struct sk_buff *skb,
-                                int offset, int len)
-{
-       struct hash_desc desc;
-       int err;
-
-       desc.tfm = esp->auth.tfm;
-       desc.flags = 0;
-
-       err = crypto_hash_init(&desc);
-       if (unlikely(err))
-               return err;
-       err = skb_icv_walk(skb, &desc, offset, len, crypto_hash_update);
-       if (unlikely(err))
-               return err;
-       return crypto_hash_final(&desc, esp->auth.work_icv);
-}
-
 struct ip_esp_hdr;
 
 static inline struct ip_esp_hdr *ip_esp_hdr(const struct sk_buff *skb)
index 668056b4bb0b9982b249b96bf8c33ceb5435c912..fdff630708ce864470a3f422cd9a1f0deea3fabe 100644 (file)
@@ -57,34 +57,37 @@ extern void __inet6_hash(struct inet_hashinfo *hashinfo, struct sock *sk);
  *
  * The sockhash lock must be held as a reader here.
  */
-extern struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
+extern struct sock *__inet6_lookup_established(struct net *net,
+                                          struct inet_hashinfo *hashinfo,
                                           const struct in6_addr *saddr,
                                           const __be16 sport,
                                           const struct in6_addr *daddr,
                                           const u16 hnum,
                                           const int dif);
 
-extern struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
+extern struct sock *inet6_lookup_listener(struct net *net,
+                                         struct inet_hashinfo *hashinfo,
                                          const struct in6_addr *daddr,
                                          const unsigned short hnum,
                                          const int dif);
 
-static inline struct sock *__inet6_lookup(struct inet_hashinfo *hashinfo,
+static inline struct sock *__inet6_lookup(struct net *net,
+                                         struct inet_hashinfo *hashinfo,
                                          const struct in6_addr *saddr,
                                          const __be16 sport,
                                          const struct in6_addr *daddr,
                                          const u16 hnum,
                                          const int dif)
 {
-       struct sock *sk = __inet6_lookup_established(hashinfo, saddr, sport,
-                                                    daddr, hnum, dif);
+       struct sock *sk = __inet6_lookup_established(net, hashinfo, saddr,
+                                               sport, daddr, hnum, dif);
        if (sk)
                return sk;
 
-       return inet6_lookup_listener(hashinfo, daddr, hnum, dif);
+       return inet6_lookup_listener(net, hashinfo, daddr, hnum, dif);
 }
 
-extern struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
+extern struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
                                 const struct in6_addr *saddr, const __be16 sport,
                                 const struct in6_addr *daddr, const __be16 dport,
                                 const int dif);
index 761bdc01425d796b6669bcaa73243d33abf7aab2..c23c4ed30724f37e985aa65eb627bd841c5cd962 100644 (file)
@@ -74,6 +74,7 @@ struct inet_ehash_bucket {
  * ports are created in O(1) time?  I thought so. ;-)  -DaveM
  */
 struct inet_bind_bucket {
+       struct net              *ib_net;
        unsigned short          port;
        signed short            fastreuse;
        struct hlist_node       node;
@@ -194,6 +195,7 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
 
 extern struct inet_bind_bucket *
                    inet_bind_bucket_create(struct kmem_cache *cachep,
+                                           struct net *net,
                                            struct inet_bind_hashbucket *head,
                                            const unsigned short snum);
 extern void inet_bind_bucket_destroy(struct kmem_cache *cachep,
@@ -300,15 +302,17 @@ out:
                wake_up(&hashinfo->lhash_wait);
 }
 
-extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
+extern struct sock *__inet_lookup_listener(struct net *net,
+                                          struct inet_hashinfo *hashinfo,
                                           const __be32 daddr,
                                           const unsigned short hnum,
                                           const int dif);
 
-static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo,
-                                               __be32 daddr, __be16 dport, int dif)
+static inline struct sock *inet_lookup_listener(struct net *net,
+               struct inet_hashinfo *hashinfo,
+               __be32 daddr, __be16 dport, int dif)
 {
-       return __inet_lookup_listener(hashinfo, daddr, ntohs(dport), dif);
+       return __inet_lookup_listener(net, hashinfo, daddr, ntohs(dport), dif);
 }
 
 /* Socket demux engine toys. */
@@ -342,26 +346,26 @@ typedef __u64 __bitwise __addrpair;
                                   (((__force __u64)(__be32)(__daddr)) << 32) | \
                                   ((__force __u64)(__be32)(__saddr)));
 #endif /* __BIG_ENDIAN */
-#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
-       (((__sk)->sk_hash == (__hash))                          &&      \
+#define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
+       (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net))   &&      \
         ((*((__addrpair *)&(inet_sk(__sk)->daddr))) == (__cookie))     &&      \
         ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports))      &&      \
         (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
-#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
-       (((__sk)->sk_hash == (__hash))                          &&      \
+#define INET_TW_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
+       (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net))   &&      \
         ((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) &&     \
         ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&      \
         (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
 #else /* 32-bit arch */
 #define INET_ADDR_COOKIE(__name, __saddr, __daddr)
-#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)   \
-       (((__sk)->sk_hash == (__hash))                          &&      \
+#define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)    \
+       (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net))   &&      \
         (inet_sk(__sk)->daddr          == (__saddr))           &&      \
         (inet_sk(__sk)->rcv_saddr      == (__daddr))           &&      \
         ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports))      &&      \
         (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
-#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif) \
-       (((__sk)->sk_hash == (__hash))                          &&      \
+#define INET_TW_MATCH(__sk, __net, __hash,__cookie, __saddr, __daddr, __ports, __dif)  \
+       (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net))   &&      \
         (inet_twsk(__sk)->tw_daddr     == (__saddr))           &&      \
         (inet_twsk(__sk)->tw_rcv_saddr == (__daddr))           &&      \
         ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&      \
@@ -374,32 +378,36 @@ typedef __u64 __bitwise __addrpair;
  *
  * Local BH must be disabled here.
  */
-extern struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
+extern struct sock * __inet_lookup_established(struct net *net,
+               struct inet_hashinfo *hashinfo,
                const __be32 saddr, const __be16 sport,
                const __be32 daddr, const u16 hnum, const int dif);
 
 static inline struct sock *
-       inet_lookup_established(struct inet_hashinfo *hashinfo,
+       inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo,
                                const __be32 saddr, const __be16 sport,
                                const __be32 daddr, const __be16 dport,
                                const int dif)
 {
-       return __inet_lookup_established(hashinfo, saddr, sport, daddr,
+       return __inet_lookup_established(net, hashinfo, saddr, sport, daddr,
                                         ntohs(dport), dif);
 }
 
-static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo,
+static inline struct sock *__inet_lookup(struct net *net,
+                                        struct inet_hashinfo *hashinfo,
                                         const __be32 saddr, const __be16 sport,
                                         const __be32 daddr, const __be16 dport,
                                         const int dif)
 {
        u16 hnum = ntohs(dport);
-       struct sock *sk = __inet_lookup_established(hashinfo, saddr, sport, daddr,
-                                                   hnum, dif);
-       return sk ? : __inet_lookup_listener(hashinfo, daddr, hnum, dif);
+       struct sock *sk = __inet_lookup_established(net, hashinfo,
+                               saddr, sport, daddr, hnum, dif);
+
+       return sk ? : __inet_lookup_listener(net, hashinfo, daddr, hnum, dif);
 }
 
-static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
+static inline struct sock *inet_lookup(struct net *net,
+                                      struct inet_hashinfo *hashinfo,
                                       const __be32 saddr, const __be16 sport,
                                       const __be32 daddr, const __be16 dport,
                                       const int dif)
@@ -407,12 +415,17 @@ static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
        struct sock *sk;
 
        local_bh_disable();
-       sk = __inet_lookup(hashinfo, saddr, sport, daddr, dport, dif);
+       sk = __inet_lookup(net, hashinfo, saddr, sport, daddr, dport, dif);
        local_bh_enable();
 
        return sk;
 }
 
+extern int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+               struct sock *sk,
+               int (*check_established)(struct inet_timewait_death_row *,
+                       struct sock *, __u16, struct inet_timewait_sock **),
+               void (*hash)(struct inet_hashinfo *, struct sock *));
 extern int inet_hash_connect(struct inet_timewait_death_row *death_row,
                             struct sock *sk);
 #endif /* _INET_HASHTABLES_H */
index 9daa60b544ba8839f8ca690fe2173ac5506d0922..90d1175f63dec46938ef08b5b6a9fdfc0cd297c5 100644 (file)
@@ -69,6 +69,7 @@ struct fib_nh {
 struct fib_info {
        struct hlist_node       fib_hash;
        struct hlist_node       fib_lhash;
+       struct net              *fib_net;
        int                     fib_treeref;
        atomic_t                fib_clntref;
        int                     fib_dead;
@@ -218,7 +219,8 @@ extern void fib_select_default(struct net *net, const struct flowi *flp,
 
 /* Exported by fib_semantics.c */
 extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
-extern int fib_sync_down(__be32 local, struct net_device *dev, int force);
+extern int fib_sync_down_dev(struct net_device *dev, int force);
+extern int fib_sync_down_addr(struct net *net, __be32 local);
 extern int fib_sync_up(struct net_device *dev);
 extern __be32  __fib_res_prefsrc(struct fib_result *res);
 extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
index b8c1d60ba9e45dbde637576c43b83311d1e531ea..28738b7d53eb2a0748cecad1076a9726da8d936f 100644 (file)
@@ -12,6 +12,7 @@
 #include <net/netns/packet.h>
 #include <net/netns/ipv4.h>
 #include <net/netns/ipv6.h>
+#include <net/netns/x_tables.h>
 
 struct proc_dir_entry;
 struct net_device;
@@ -56,6 +57,9 @@ struct net {
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
        struct netns_ipv6       ipv6;
 #endif
+#ifdef CONFIG_NETFILTER
+       struct netns_xt         xt;
+#endif
 };
 
 #ifdef CONFIG_NET
index 857d89951790ab2b35c37c38b9628689e1296536..90b3e7f5df5fdf5fd34cb7469bc45a6957ae98c4 100644 (file)
@@ -129,6 +129,8 @@ struct nf_conn
 
        /* Extensions */
        struct nf_ct_ext *ext;
+
+       struct rcu_head rcu;
 };
 
 static inline struct nf_conn *
@@ -143,7 +145,7 @@ nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash)
 
 /* Alter reply tuple (maybe alter helper). */
 extern void
-nf_conntrack_alter_reply(struct nf_conn *conntrack,
+nf_conntrack_alter_reply(struct nf_conn *ct,
                         const struct nf_conntrack_tuple *newreply);
 
 /* Is this tuple taken? (ignoring any belonging to the given
@@ -171,13 +173,12 @@ static inline void nf_ct_put(struct nf_conn *ct)
 extern int nf_ct_l3proto_try_module_get(unsigned short l3proto);
 extern void nf_ct_l3proto_module_put(unsigned short l3proto);
 
-extern struct hlist_head *nf_ct_alloc_hashtable(int *sizep, int *vmalloced);
+extern struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced);
 extern void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced,
-                                int size);
+                                unsigned int size);
 
 extern struct nf_conntrack_tuple_hash *
-__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
-                   const struct nf_conn *ignored_conntrack);
+__nf_conntrack_find(const struct nf_conntrack_tuple *tuple);
 
 extern void nf_conntrack_hash_insert(struct nf_conn *ct);
 
@@ -215,9 +216,9 @@ static inline void nf_ct_refresh(struct nf_conn *ct,
 
 /* These are for NAT.  Icky. */
 /* Update TCP window tracking data when NAT mangles the packet */
-extern void nf_conntrack_tcp_update(struct sk_buff *skb,
+extern void nf_conntrack_tcp_update(const struct sk_buff *skb,
                                    unsigned int dataoff,
-                                   struct nf_conn *conntrack,
+                                   struct nf_conn *ct,
                                    int dir);
 
 /* Fake conntrack entry for untracked connections */
index 7ad0828f05cfef3c8e322886c02efcffa0fac516..9ee26469c759ed06a74ff1754a991259bd96b0cc 100644 (file)
@@ -68,11 +68,11 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb)
 
 int
 print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
-           struct nf_conntrack_l3proto *l3proto,
-           struct nf_conntrack_l4proto *proto);
+            const struct nf_conntrack_l3proto *l3proto,
+            const struct nf_conntrack_l4proto *proto);
 
 extern struct hlist_head *nf_conntrack_hash;
-extern rwlock_t nf_conntrack_lock ;
+extern spinlock_t nf_conntrack_lock ;
 extern struct hlist_head unconfirmed;
 
 #endif /* _NF_CONNTRACK_CORE_H */
index 6c3fd254c28ef148a8f9f04f2c35c19bbc8f7f7b..cb608a1b44e59812876c1c3db00b2150fc538e1c 100644 (file)
@@ -49,6 +49,8 @@ struct nf_conntrack_expect
        /* Direction relative to the master connection. */
        enum ip_conntrack_dir dir;
 #endif
+
+       struct rcu_head rcu;
 };
 
 #define NF_CT_EXPECT_PERMANENT 0x1
index 2f3af00643cf92166c1898740d45c56334d0c55c..4ca125e9b3ce30870cfde5182d4b8000c4925920 100644 (file)
@@ -42,13 +42,9 @@ struct nf_conntrack_helper
 extern struct nf_conntrack_helper *
 __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple);
 
-extern struct nf_conntrack_helper *
-nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple);
-
 extern struct nf_conntrack_helper *
 __nf_conntrack_helper_find_byname(const char *name);
 
-extern void nf_ct_helper_put(struct nf_conntrack_helper *helper);
 extern int nf_conntrack_helper_register(struct nf_conntrack_helper *);
 extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);
 
index d5526bcce147ab906c884e33b38c4cc9ba977b1d..b886e3ae6cad69bf78df1819456cd661daf95387 100644 (file)
@@ -43,7 +43,7 @@ struct nf_conntrack_l3proto
                           const struct nf_conntrack_tuple *);
 
        /* Returns verdict for packet, or -1 for invalid. */
-       int (*packet)(struct nf_conn *conntrack,
+       int (*packet)(struct nf_conn *ct,
                      const struct sk_buff *skb,
                      enum ip_conntrack_info ctinfo);
 
@@ -51,7 +51,7 @@ struct nf_conntrack_l3proto
         * Called when a new connection for this protocol found;
         * returns TRUE if it's OK.  If so, packet() called next.
         */
-       int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb);
+       int (*new)(struct nf_conn *ct, const struct sk_buff *skb);
 
        /*
         * Called before tracking. 
index fb50c217ba0af56f447ec44d84255bacd2d1061f..efc16eccddb1b1e09c638f0b9bab2428f1f9fc1d 100644 (file)
@@ -23,9 +23,6 @@ struct nf_conntrack_l4proto
        /* L4 Protocol number. */
        u_int8_t l4proto;
 
-       /* Protocol name */
-       const char *name;
-
        /* Try to fill in the third arg: dataoff is offset past network protocol
            hdr.  Return true if possible. */
        int (*pkt_to_tuple)(const struct sk_buff *skb,
@@ -38,15 +35,8 @@ struct nf_conntrack_l4proto
        int (*invert_tuple)(struct nf_conntrack_tuple *inverse,
                            const struct nf_conntrack_tuple *orig);
 
-       /* Print out the per-protocol part of the tuple. Return like seq_* */
-       int (*print_tuple)(struct seq_file *s,
-                          const struct nf_conntrack_tuple *);
-
-       /* Print out the private part of the conntrack. */
-       int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
-
        /* Returns verdict for packet, or -1 for invalid. */
-       int (*packet)(struct nf_conn *conntrack,
+       int (*packet)(struct nf_conn *ct,
                      const struct sk_buff *skb,
                      unsigned int dataoff,
                      enum ip_conntrack_info ctinfo,
@@ -55,16 +45,23 @@ struct nf_conntrack_l4proto
 
        /* Called when a new connection for this protocol found;
         * returns TRUE if it's OK.  If so, packet() called next. */
-       int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb,
+       int (*new)(struct nf_conn *ct, const struct sk_buff *skb,
                   unsigned int dataoff);
 
        /* Called when a conntrack entry is destroyed */
-       void (*destroy)(struct nf_conn *conntrack);
+       void (*destroy)(struct nf_conn *ct);
 
        int (*error)(struct sk_buff *skb, unsigned int dataoff,
                     enum ip_conntrack_info *ctinfo,
                     int pf, unsigned int hooknum);
 
+       /* Print out the per-protocol part of the tuple. Return like seq_* */
+       int (*print_tuple)(struct seq_file *s,
+                          const struct nf_conntrack_tuple *);
+
+       /* Print out the private part of the conntrack. */
+       int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
+
        /* convert protoinfo to nfnetink attributes */
        int (*to_nlattr)(struct sk_buff *skb, struct nlattr *nla,
                         const struct nf_conn *ct);
@@ -87,6 +84,8 @@ struct nf_conntrack_l4proto
        struct ctl_table        *ctl_compat_table;
 #endif
 #endif
+       /* Protocol name */
+       const char *name;
 
        /* Module (if any) which this is connected to. */
        struct module *me;
index 45cb17cdcfd0c8555edcb280f9db61ca94d1f080..e69ab2e875973f205cd9e569c82dbfb6e08ab0d4 100644 (file)
@@ -132,34 +132,33 @@ struct nf_conntrack_tuple_hash
 
 #endif /* __KERNEL__ */
 
-static inline int nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1,
-                                       const struct nf_conntrack_tuple *t2)
+static inline int __nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1,
+                                         const struct nf_conntrack_tuple *t2)
 { 
        return (t1->src.u3.all[0] == t2->src.u3.all[0] &&
                t1->src.u3.all[1] == t2->src.u3.all[1] &&
                t1->src.u3.all[2] == t2->src.u3.all[2] &&
                t1->src.u3.all[3] == t2->src.u3.all[3] &&
                t1->src.u.all == t2->src.u.all &&
-               t1->src.l3num == t2->src.l3num &&
-               t1->dst.protonum == t2->dst.protonum);
+               t1->src.l3num == t2->src.l3num);
 }
 
-static inline int nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1,
-                                       const struct nf_conntrack_tuple *t2)
+static inline int __nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1,
+                                         const struct nf_conntrack_tuple *t2)
 {
        return (t1->dst.u3.all[0] == t2->dst.u3.all[0] &&
                t1->dst.u3.all[1] == t2->dst.u3.all[1] &&
                t1->dst.u3.all[2] == t2->dst.u3.all[2] &&
                t1->dst.u3.all[3] == t2->dst.u3.all[3] &&
                t1->dst.u.all == t2->dst.u.all &&
-               t1->src.l3num == t2->src.l3num &&
                t1->dst.protonum == t2->dst.protonum);
 }
 
 static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1,
                                    const struct nf_conntrack_tuple *t2)
 {
-       return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2);
+       return __nf_ct_tuple_src_equal(t1, t2) &&
+              __nf_ct_tuple_dst_equal(t1, t2);
 }
 
 static inline int nf_ct_tuple_mask_equal(const struct nf_conntrack_tuple_mask *m1,
@@ -199,7 +198,7 @@ static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
                                       const struct nf_conntrack_tuple_mask *mask)
 {
        return nf_ct_tuple_src_mask_cmp(t, tuple, mask) &&
-              nf_ct_tuple_dst_equal(t, tuple);
+              __nf_ct_tuple_dst_equal(t, tuple);
 }
 
 #endif /* _NF_CONNTRACK_TUPLE_H */
index 037e82403f916244926973a4e7c2c35774fea00e..8c6b5ae45534463591cce0f86e371f46d655b484 100644 (file)
@@ -54,6 +54,6 @@ void nf_log_packet(int pf,
                   const struct net_device *in,
                   const struct net_device *out,
                   const struct nf_loginfo *li,
-                  const char *fmt, ...);
+                  const char *fmt, ...) __attribute__ ((format(printf,7,8)));
 
 #endif /* _NF_LOG_H */
index 15a0b052df222f9e9930d50be7ee448c5371e7b8..a9b4f608629444e432d00787b818b75a47538b1e 100644 (file)
@@ -27,5 +27,11 @@ struct netns_ipv4 {
        struct sock             *fibnl;
 
        struct netns_frags      frags;
+#ifdef CONFIG_NETFILTER
+       struct xt_table         *iptable_filter;
+       struct xt_table         *iptable_mangle;
+       struct xt_table         *iptable_raw;
+       struct xt_table         *arptable_filter;
+#endif
 };
 #endif
index 187c4248df220f51c4511d910fd09395b25bce88..1dd7de4e419548672c937aeb489575dd7a96a32c 100644 (file)
@@ -31,5 +31,10 @@ struct netns_ipv6 {
        struct ipv6_devconf     *devconf_all;
        struct ipv6_devconf     *devconf_dflt;
        struct netns_frags      frags;
+#ifdef CONFIG_NETFILTER
+       struct xt_table         *ip6table_filter;
+       struct xt_table         *ip6table_mangle;
+       struct xt_table         *ip6table_raw;
+#endif
 };
 #endif
diff --git a/include/net/netns/x_tables.h b/include/net/netns/x_tables.h
new file mode 100644 (file)
index 0000000..0cb63ed
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __NETNS_X_TABLES_H
+#define __NETNS_X_TABLES_H
+
+#include <linux/list.h>
+#include <linux/net.h>
+
+struct netns_xt {
+       struct list_head tables[NPROTO];
+};
+#endif
index 8716eb757d514f076f33a60e550096f1ede1d0dc..d349c66ef8281029689dd7859f88b9c7afd63928 100644 (file)
@@ -131,14 +131,14 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
 
 extern int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
                             struct nlattr *rate_tlv, struct tcf_exts *exts,
-                            struct tcf_ext_map *map);
+                            const struct tcf_ext_map *map);
 extern void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts);
 extern void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
                             struct tcf_exts *src);
 extern int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
-                        struct tcf_ext_map *map);
+                        const struct tcf_ext_map *map);
 extern int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
-                              struct tcf_ext_map *map);
+                              const struct tcf_ext_map *map);
 
 /**
  * struct tcf_pkt_info - packet information
index cca81d8b2d8ba2052e75539aa314cec10d066833..1828f81fe37474ca6a3228188133d1b86d817a37 100644 (file)
@@ -41,7 +41,6 @@ extern void raw_proc_exit(void);
 struct raw_iter_state {
        struct seq_net_private p;
        int bucket;
-       unsigned short family;
        struct raw_hashinfo *h;
 };
 
@@ -49,8 +48,8 @@ struct raw_iter_state {
 void *raw_seq_start(struct seq_file *seq, loff_t *pos);
 void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos);
 void raw_seq_stop(struct seq_file *seq, void *v);
-int raw_seq_open(struct inode *ino, struct file *file, struct raw_hashinfo *h,
-               unsigned short family);
+int raw_seq_open(struct inode *ino, struct file *file,
+                struct raw_hashinfo *h, const struct seq_operations *ops);
 
 #endif
 
index 4eabf008413bfb18390fd552e88a49f4fcf44e28..eadad590142992fdcf3ae92f49a624821ec3d275 100644 (file)
@@ -27,6 +27,7 @@
 #include <net/dst.h>
 #include <net/inetpeer.h>
 #include <net/flow.h>
+#include <net/sock.h>
 #include <linux/in_route.h>
 #include <linux/rtnetlink.h>
 #include <linux/route.h>
@@ -61,6 +62,7 @@ struct rtable
 
        struct in_device        *idev;
        
+       int                     rt_genid;
        unsigned                rt_flags;
        __u16                   rt_type;
 
@@ -149,6 +151,7 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
                                   int flags)
 {
        struct flowi fl = { .oif = oif,
+                           .mark = sk->sk_mark,
                            .nl_u = { .ip4_u = { .daddr = dst,
                                                 .saddr = src,
                                                 .tos   = tos } },
index 902324488d0f7d2fb9a485258f59efa827344b0f..e3fb4c047f4c99b1bdb73471010916243e733bbf 100644 (file)
@@ -262,6 +262,8 @@ struct sock {
        __u32                   sk_sndmsg_off;
        int                     sk_write_pending;
        void                    *sk_security;
+       __u32                   sk_mark;
+       /* XXX 4 bytes hole on 64 bit */
        void                    (*sk_state_change)(struct sock *sk);
        void                    (*sk_data_ready)(struct sock *sk, int bytes);
        void                    (*sk_write_space)(struct sock *sk);
index 5ebb9ba479b107edfb11c582390c478100bee7f3..ac72116636ca7f46bfb486079fd244d7b5433f9f 100644 (file)
@@ -159,6 +159,7 @@ struct xfrm_state
        struct xfrm_algo        *aalg;
        struct xfrm_algo        *ealg;
        struct xfrm_algo        *calg;
+       struct xfrm_algo_aead   *aead;
 
        /* Data for encapsulator */
        struct xfrm_encap_tmpl  *encap;
@@ -201,7 +202,7 @@ struct xfrm_state
 
        /* Reference to data common to all the instances of this
         * transformer. */
-       struct xfrm_type        *type;
+       const struct xfrm_type  *type;
        struct xfrm_mode        *inner_mode;
        struct xfrm_mode        *outer_mode;
 
@@ -278,7 +279,7 @@ struct xfrm_state_afinfo {
        unsigned int            proto;
        unsigned int            eth_proto;
        struct module           *owner;
-       struct xfrm_type        *type_map[IPPROTO_MAX];
+       const struct xfrm_type  *type_map[IPPROTO_MAX];
        struct xfrm_mode        *mode_map[XFRM_MODE_MAX];
        int                     (*init_flags)(struct xfrm_state *x);
        void                    (*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
@@ -321,8 +322,8 @@ struct xfrm_type
        u32                     (*get_mtu)(struct xfrm_state *, int size);
 };
 
-extern int xfrm_register_type(struct xfrm_type *type, unsigned short family);
-extern int xfrm_unregister_type(struct xfrm_type *type, unsigned short family);
+extern int xfrm_register_type(const struct xfrm_type *type, unsigned short family);
+extern int xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);
 
 struct xfrm_mode {
        /*
@@ -1108,6 +1109,10 @@ static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
 /*
  * xfrm algorithm information
  */
+struct xfrm_algo_aead_info {
+       u16 icv_truncbits;
+};
+
 struct xfrm_algo_auth_info {
        u16 icv_truncbits;
        u16 icv_fullbits;
@@ -1127,6 +1132,7 @@ struct xfrm_algo_desc {
        char *compat;
        u8 available:1;
        union {
+               struct xfrm_algo_aead_info aead;
                struct xfrm_algo_auth_info auth;
                struct xfrm_algo_encr_info encr;
                struct xfrm_algo_comp_info comp;
@@ -1343,6 +1349,8 @@ extern struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
 extern struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe);
 extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe);
 extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe);
+extern struct xfrm_algo_desc *xfrm_aead_get_byname(char *name, int icv_len,
+                                                  int probe);
 
 struct hash_desc;
 struct scatterlist;
index f93c2713017da93b90e5e8d67d029c1b754ffaa0..801c946dd24b639520e6037b63dd96860c2e60d9 100644 (file)
@@ -1200,13 +1200,17 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
 static inline int audit_expand(struct audit_buffer *ab, int extra)
 {
        struct sk_buff *skb = ab->skb;
-       int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
-                                  ab->gfp_mask);
+       int oldtail = skb_tailroom(skb);
+       int ret = pskb_expand_head(skb, 0, extra, ab->gfp_mask);
+       int newtail = skb_tailroom(skb);
+
        if (ret < 0) {
                audit_log_lost("out of memory in audit_expand");
                return 0;
        }
-       return skb_tailroom(skb);
+
+       skb->truesize += newtail - oldtail;
+       return newtail;
 }
 
 /*
index 3f16b1720554ffc147ff634b7f1564d871ab10fb..18c66475d8c39f8cd9c28a4d5ea0a0b5bc84491e 100644 (file)
@@ -76,7 +76,7 @@ static DEFINE_SPINLOCK(rif_lock);
 
 static struct timer_list rif_timer;
 
-int sysctl_tr_rif_timeout = 60*10*HZ;
+static int sysctl_tr_rif_timeout = 60*10*HZ;
 
 static inline unsigned long rif_hash(const unsigned char *addr)
 {
index 8059fa42b0859a1217946d91fde310d21baaba32..77f04e49a1a077013d2be6a1acd8f32c65559dc5 100644 (file)
@@ -563,6 +563,7 @@ static int vlan_dev_stop(struct net_device *dev)
        struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
 
        dev_mc_unsync(real_dev, dev);
+       dev_unicast_unsync(real_dev, dev);
        if (dev->flags & IFF_ALLMULTI)
                dev_set_allmulti(real_dev, -1);
        if (dev->flags & IFF_PROMISC)
@@ -634,9 +635,10 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
                dev_set_promiscuity(real_dev, dev->flags & IFF_PROMISC ? 1 : -1);
 }
 
-static void vlan_dev_set_multicast_list(struct net_device *vlan_dev)
+static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
 {
        dev_mc_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev);
+       dev_unicast_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev);
 }
 
 /*
@@ -702,7 +704,8 @@ void vlan_setup(struct net_device *dev)
        dev->open               = vlan_dev_open;
        dev->stop               = vlan_dev_stop;
        dev->set_mac_address    = vlan_dev_set_mac_address;
-       dev->set_multicast_list = vlan_dev_set_multicast_list;
+       dev->set_rx_mode        = vlan_dev_set_rx_mode;
+       dev->set_multicast_list = vlan_dev_set_rx_mode;
        dev->change_rx_flags    = vlan_dev_change_rx_flags;
        dev->do_ioctl           = vlan_dev_ioctl;
        dev->destructor         = free_netdev;
index aa2aa9884f955d37b6c7bd2c4d6923dccf2932f6..3fe35d532c87a0c2f17afb2baf961077a954f96e 100644 (file)
@@ -128,11 +128,6 @@ static char *buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
        return ret;
 }
 
-static inline void buf_put_string(struct cbuf *buf, const char *s)
-{
-       buf_put_stringn(buf, s, strlen(s));
-}
-
 static u8 buf_get_int8(struct cbuf *buf)
 {
        u8 ret = 0;
index 1bc0e85f04a5112afbfa5be6140d59ba4f38f2b0..8fc64e3150a26cd437aeee127806cab19cda110d 100644 (file)
@@ -1037,16 +1037,13 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        int err = 0;
 
        if (addr_len != sizeof(struct sockaddr_ax25) &&
-           addr_len != sizeof(struct full_sockaddr_ax25)) {
-               /* support for old structure may go away some time */
+           addr_len != sizeof(struct full_sockaddr_ax25))
+               /* support for old structure may go away some time
+                * ax25_bind(): uses old (6 digipeater) socket structure.
+                */
                if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
-                   (addr_len > sizeof(struct full_sockaddr_ax25))) {
+                   (addr_len > sizeof(struct full_sockaddr_ax25)))
                        return -EINVAL;
-       }
-
-               printk(KERN_WARNING "ax25_bind(): %s uses old (6 digipeater) socket structure.\n",
-                       current->comm);
-       }
 
        if (addr->fsa_ax25.sax25_family != AF_AX25)
                return -EINVAL;
index 17f7fb7205535ce35f0fc9a7b96cdbf9d261c820..e13cf5ef144cd59a8a8f7eee15ae24d7826020ba 100644 (file)
@@ -12,6 +12,8 @@
 #undef  BT_DBG
 #define BT_DBG(D...)
 #endif
+static struct workqueue_struct *btaddconn;
+static struct workqueue_struct *btdelconn;
 
 static inline char *typetostr(int type)
 {
@@ -279,6 +281,8 @@ static void add_conn(struct work_struct *work)
        struct hci_conn *conn = container_of(work, struct hci_conn, work);
        int i;
 
+       flush_workqueue(btdelconn);
+
        if (device_add(&conn->dev) < 0) {
                BT_ERR("Failed to register connection device");
                return;
@@ -313,7 +317,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
 
        INIT_WORK(&conn->work, add_conn);
 
-       schedule_work(&conn->work);
+       queue_work(btaddconn, &conn->work);
 }
 
 static int __match_tty(struct device *dev, void *data)
@@ -349,7 +353,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
 
        INIT_WORK(&conn->work, del_conn);
 
-       schedule_work(&conn->work);
+       queue_work(btdelconn, &conn->work);
 }
 
 int hci_register_sysfs(struct hci_dev *hdev)
@@ -398,28 +402,54 @@ int __init bt_sysfs_init(void)
 {
        int err;
 
+       btaddconn = create_singlethread_workqueue("btaddconn");
+       if (!btaddconn) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       btdelconn = create_singlethread_workqueue("btdelconn");
+       if (!btdelconn) {
+               err = -ENOMEM;
+               goto out_del;
+       }
+
        bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0);
-       if (IS_ERR(bt_platform))
-               return PTR_ERR(bt_platform);
+       if (IS_ERR(bt_platform)) {
+               err = PTR_ERR(bt_platform);
+               goto out_platform;
+       }
 
        err = bus_register(&bt_bus);
-       if (err < 0) {
-               platform_device_unregister(bt_platform);
-               return err;
-       }
+       if (err < 0)
+               goto out_bus;
 
        bt_class = class_create(THIS_MODULE, "bluetooth");
        if (IS_ERR(bt_class)) {
-               bus_unregister(&bt_bus);
-               platform_device_unregister(bt_platform);
-               return PTR_ERR(bt_class);
+               err = PTR_ERR(bt_class);
+               goto out_class;
        }
 
        return 0;
+
+out_class:
+       bus_unregister(&bt_bus);
+out_bus:
+       platform_device_unregister(bt_platform);
+out_platform:
+       destroy_workqueue(btdelconn);
+out_del:
+       destroy_workqueue(btaddconn);
+out:
+       return err;
 }
 
 void bt_sysfs_cleanup(void)
 {
+       destroy_workqueue(btaddconn);
+
+       destroy_workqueue(btdelconn);
+
        class_destroy(bt_class);
 
        bus_unregister(&bt_bus);
index 80014bab81b0afdb43b02ea5724afe24e747a546..1c0efd8ad9f311ef2ed676891d5b0c28a858d1fa 100644 (file)
@@ -828,10 +828,6 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
        nf_bridge_pull_encap_header(skb);
        nf_bridge_save_header(skb);
 
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-       if (nf_bridge->netoutdev)
-               realoutdev = nf_bridge->netoutdev;
-#endif
        NF_HOOK(pf, NF_INET_POST_ROUTING, skb, NULL, realoutdev,
                br_nf_dev_queue_xmit);
 
index 41a78072cd0eb1f4eed32752b2708ee6369788ee..98534025360f8a4d8c45766921a2791fc80d2218 100644 (file)
@@ -15,8 +15,8 @@
 static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *in,
    const struct net_device *out, const void *data, unsigned int datalen)
 {
-       struct ebt_802_3_info *info = (struct ebt_802_3_info *)data;
-       struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb);
+       const struct ebt_802_3_info *info = data;
+       const struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb);
        __be16 type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type;
 
        if (info->bitmask & EBT_802_3_SAP) {
@@ -40,7 +40,7 @@ static struct ebt_match filter_802_3;
 static int ebt_802_3_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_802_3_info *info = (struct ebt_802_3_info *)data;
+       const struct ebt_802_3_info *info = data;
 
        if (datalen < sizeof(struct ebt_802_3_info))
                return -EINVAL;
@@ -50,8 +50,7 @@ static int ebt_802_3_check(const char *tablename, unsigned int hookmask,
        return 0;
 }
 
-static struct ebt_match filter_802_3 =
-{
+static struct ebt_match filter_802_3 __read_mostly = {
        .name           = EBT_802_3_MATCH,
        .match          = ebt_filter_802_3,
        .check          = ebt_802_3_check,
@@ -70,4 +69,5 @@ static void __exit ebt_802_3_fini(void)
 
 module_init(ebt_802_3_init);
 module_exit(ebt_802_3_fini);
+MODULE_DESCRIPTION("Ebtables: DSAP/SSAP field and SNAP type matching");
 MODULE_LICENSE("GPL");
index 6436d30a550eac56f42a2d2a8a44aab7295cb9fa..70b6dca5ea755502a74e294546156a8bea345509 100644 (file)
@@ -25,7 +25,7 @@ static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
        const struct ebt_mac_wormhash_tuple *p;
        int start, limit, i;
        uint32_t cmp[2] = { 0, 0 };
-       int key = (const unsigned char) mac[5];
+       int key = ((const unsigned char *)mac)[5];
 
        memcpy(((char *) cmp) + 2, mac, 6);
        start = wh->table[key];
@@ -73,15 +73,18 @@ static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash
 static int get_ip_dst(const struct sk_buff *skb, __be32 *addr)
 {
        if (eth_hdr(skb)->h_proto == htons(ETH_P_IP)) {
-               struct iphdr _iph, *ih;
+               const struct iphdr *ih;
+               struct iphdr _iph;
 
                ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
                if (ih == NULL)
                        return -1;
                *addr = ih->daddr;
        } else if (eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
-               struct arphdr _arph, *ah;
-               __be32 buf, *bp;
+               const struct arphdr *ah;
+               struct arphdr _arph;
+               const __be32 *bp;
+               __be32 buf;
 
                ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
                if (ah == NULL ||
@@ -101,15 +104,18 @@ static int get_ip_dst(const struct sk_buff *skb, __be32 *addr)
 static int get_ip_src(const struct sk_buff *skb, __be32 *addr)
 {
        if (eth_hdr(skb)->h_proto == htons(ETH_P_IP)) {
-               struct iphdr _iph, *ih;
+               const struct iphdr *ih;
+               struct iphdr _iph;
 
                ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
                if (ih == NULL)
                        return -1;
                *addr = ih->saddr;
        } else if (eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
-               struct arphdr _arph, *ah;
-               __be32 buf, *bp;
+               const struct arphdr *ah;
+               struct arphdr _arph;
+               const __be32 *bp;
+               __be32 buf;
 
                ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
                if (ah == NULL ||
@@ -130,7 +136,7 @@ static int ebt_filter_among(const struct sk_buff *skb,
                            const struct net_device *out, const void *data,
                            unsigned int datalen)
 {
-       struct ebt_among_info *info = (struct ebt_among_info *) data;
+       const struct ebt_among_info *info = data;
        const char *dmac, *smac;
        const struct ebt_mac_wormhash *wh_dst, *wh_src;
        __be32 dip = 0, sip = 0;
@@ -175,7 +181,7 @@ static int ebt_among_check(const char *tablename, unsigned int hookmask,
                           const struct ebt_entry *e, void *data,
                           unsigned int datalen)
 {
-       struct ebt_among_info *info = (struct ebt_among_info *) data;
+       const struct ebt_among_info *info = data;
        int expected_length = sizeof(struct ebt_among_info);
        const struct ebt_mac_wormhash *wh_dst, *wh_src;
        int err;
@@ -206,7 +212,7 @@ static int ebt_among_check(const char *tablename, unsigned int hookmask,
        return 0;
 }
 
-static struct ebt_match filter_among = {
+static struct ebt_match filter_among __read_mostly = {
        .name           = EBT_AMONG_MATCH,
        .match          = ebt_filter_among,
        .check          = ebt_among_check,
@@ -225,4 +231,5 @@ static void __exit ebt_among_fini(void)
 
 module_init(ebt_among_init);
 module_exit(ebt_among_fini);
+MODULE_DESCRIPTION("Ebtables: Combined MAC/IP address list matching");
 MODULE_LICENSE("GPL");
index 18141392a9b4eb87a45afc11902ae89249c7e7ac..7c535be75665ce8dd32c23818c866ed972601976 100644 (file)
@@ -18,8 +18,9 @@
 static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in,
    const struct net_device *out, const void *data, unsigned int datalen)
 {
-       struct ebt_arp_info *info = (struct ebt_arp_info *)data;
-       struct arphdr _arph, *ah;
+       const struct ebt_arp_info *info = data;
+       const struct arphdr *ah;
+       struct arphdr _arph;
 
        ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
        if (ah == NULL)
@@ -35,7 +36,8 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
                return EBT_NOMATCH;
 
        if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) {
-               __be32 saddr, daddr, *sap, *dap;
+               const __be32 *sap, *dap;
+               __be32 saddr, daddr;
 
                if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP))
                        return EBT_NOMATCH;
@@ -61,7 +63,8 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
        }
 
        if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) {
-               unsigned char _mac[ETH_ALEN], *mp;
+               const unsigned char *mp;
+               unsigned char _mac[ETH_ALEN];
                uint8_t verdict, i;
 
                if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER))
@@ -100,7 +103,7 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
 static int ebt_arp_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_arp_info *info = (struct ebt_arp_info *)data;
+       const struct ebt_arp_info *info = data;
 
        if (datalen != EBT_ALIGN(sizeof(struct ebt_arp_info)))
                return -EINVAL;
@@ -113,8 +116,7 @@ static int ebt_arp_check(const char *tablename, unsigned int hookmask,
        return 0;
 }
 
-static struct ebt_match filter_arp =
-{
+static struct ebt_match filter_arp __read_mostly = {
        .name           = EBT_ARP_MATCH,
        .match          = ebt_filter_arp,
        .check          = ebt_arp_check,
@@ -133,4 +135,5 @@ static void __exit ebt_arp_fini(void)
 
 module_init(ebt_arp_init);
 module_exit(ebt_arp_fini);
+MODULE_DESCRIPTION("Ebtables: ARP protocol packet match");
 MODULE_LICENSE("GPL");
index 48a80e4232879c5afe409fc5697e4167cfe8969f..0c4279590fc70c25a60b3b18e5ce38f5a6126c29 100644 (file)
@@ -19,10 +19,13 @@ static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr,
    const struct net_device *in, const struct net_device *out,
    const void *data, unsigned int datalen)
 {
-       struct ebt_arpreply_info *info = (struct ebt_arpreply_info *)data;
-       __be32 _sip, *siptr, _dip, *diptr;
-       struct arphdr _ah, *ap;
-       unsigned char _sha[ETH_ALEN], *shp;
+       struct ebt_arpreply_info *info = (void *)data;
+       const __be32 *siptr, *diptr;
+       __be32 _sip, _dip;
+       const struct arphdr *ap;
+       struct arphdr _ah;
+       const unsigned char *shp;
+       unsigned char _sha[ETH_ALEN];
 
        ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
        if (ap == NULL)
@@ -58,7 +61,7 @@ static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr,
 static int ebt_target_reply_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_arpreply_info *info = (struct ebt_arpreply_info *)data;
+       const struct ebt_arpreply_info *info = data;
 
        if (datalen != EBT_ALIGN(sizeof(struct ebt_arpreply_info)))
                return -EINVAL;
@@ -73,8 +76,7 @@ static int ebt_target_reply_check(const char *tablename, unsigned int hookmask,
        return 0;
 }
 
-static struct ebt_target reply_target =
-{
+static struct ebt_target reply_target __read_mostly = {
        .name           = EBT_ARPREPLY_TARGET,
        .target         = ebt_target_reply,
        .check          = ebt_target_reply_check,
@@ -93,4 +95,5 @@ static void __exit ebt_arpreply_fini(void)
 
 module_init(ebt_arpreply_init);
 module_exit(ebt_arpreply_fini);
+MODULE_DESCRIPTION("Ebtables: ARP reply target");
 MODULE_LICENSE("GPL");
index 74262e9a566a3f7baf63779f948fb16f4dfd282f..e700cbf634c24826c9b257364b77a969d884af1a 100644 (file)
@@ -18,7 +18,7 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
    const struct net_device *in, const struct net_device *out,
    const void *data, unsigned int datalen)
 {
-       struct ebt_nat_info *info = (struct ebt_nat_info *)data;
+       const struct ebt_nat_info *info = data;
 
        if (skb_make_writable(skb, 0))
                return NF_DROP;
@@ -30,7 +30,7 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
 static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_nat_info *info = (struct ebt_nat_info *)data;
+       const struct ebt_nat_info *info = data;
 
        if (BASE_CHAIN && info->target == EBT_RETURN)
                return -EINVAL;
@@ -46,8 +46,7 @@ static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask,
        return 0;
 }
 
-static struct ebt_target dnat =
-{
+static struct ebt_target dnat __read_mostly = {
        .name           = EBT_DNAT_TARGET,
        .target         = ebt_target_dnat,
        .check          = ebt_target_dnat_check,
@@ -66,4 +65,5 @@ static void __exit ebt_dnat_fini(void)
 
 module_init(ebt_dnat_init);
 module_exit(ebt_dnat_fini);
+MODULE_DESCRIPTION("Ebtables: Destination MAC address translation");
 MODULE_LICENSE("GPL");
index 69f7f0ab9c76ae5fa5d4cdd7ef2264417a675ba3..65caa00dcf2a348d0c321a42add55acd40177339 100644 (file)
@@ -28,9 +28,11 @@ static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
    const struct net_device *out, const void *data,
    unsigned int datalen)
 {
-       struct ebt_ip_info *info = (struct ebt_ip_info *)data;
-       struct iphdr _iph, *ih;
-       struct tcpudphdr _ports, *pptr;
+       const struct ebt_ip_info *info = data;
+       const struct iphdr *ih;
+       struct iphdr _iph;
+       const struct tcpudphdr *pptr;
+       struct tcpudphdr _ports;
 
        ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
        if (ih == NULL)
@@ -79,7 +81,7 @@ static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
 static int ebt_ip_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_ip_info *info = (struct ebt_ip_info *)data;
+       const struct ebt_ip_info *info = data;
 
        if (datalen != EBT_ALIGN(sizeof(struct ebt_ip_info)))
                return -EINVAL;
@@ -105,8 +107,7 @@ static int ebt_ip_check(const char *tablename, unsigned int hookmask,
        return 0;
 }
 
-static struct ebt_match filter_ip =
-{
+static struct ebt_match filter_ip __read_mostly = {
        .name           = EBT_IP_MATCH,
        .match          = ebt_filter_ip,
        .check          = ebt_ip_check,
@@ -125,4 +126,5 @@ static void __exit ebt_ip_fini(void)
 
 module_init(ebt_ip_init);
 module_exit(ebt_ip_fini);
+MODULE_DESCRIPTION("Ebtables: IPv4 protocol packet match");
 MODULE_LICENSE("GPL");
index d48fa5cb26cf325c59c46b8fe9700d32e32081b8..8cbdc01c253e49274b1c0e83d63e98b5100fe37b 100644 (file)
@@ -69,7 +69,7 @@ user2credits(u_int32_t user)
 static int ebt_limit_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_limit_info *info = (struct ebt_limit_info *)data;
+       struct ebt_limit_info *info = data;
 
        if (datalen != EBT_ALIGN(sizeof(struct ebt_limit_info)))
                return -EINVAL;
@@ -90,8 +90,7 @@ static int ebt_limit_check(const char *tablename, unsigned int hookmask,
        return 0;
 }
 
-static struct ebt_match ebt_limit_reg =
-{
+static struct ebt_match ebt_limit_reg __read_mostly = {
        .name           = EBT_LIMIT_MATCH,
        .match          = ebt_limit_match,
        .check          = ebt_limit_check,
@@ -110,4 +109,5 @@ static void __exit ebt_limit_fini(void)
 
 module_init(ebt_limit_init);
 module_exit(ebt_limit_fini);
+MODULE_DESCRIPTION("Ebtables: Rate-limit match");
 MODULE_LICENSE("GPL");
index 3be9e9898553b1d129700929dac0177853c0b377..0b209e4aad0a0a76e53c9cbc7c89d950eda92af7 100644 (file)
@@ -24,7 +24,7 @@ static DEFINE_SPINLOCK(ebt_log_lock);
 static int ebt_log_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_log_info *info = (struct ebt_log_info *)data;
+       struct ebt_log_info *info = data;
 
        if (datalen != EBT_ALIGN(sizeof(struct ebt_log_info)))
                return -EINVAL;
@@ -50,7 +50,7 @@ struct arppayload
        unsigned char ip_dst[4];
 };
 
-static void print_MAC(unsigned char *p)
+static void print_MAC(const unsigned char *p)
 {
        int i;
 
@@ -84,7 +84,8 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
 
        if ((bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto ==
           htons(ETH_P_IP)){
-               struct iphdr _iph, *ih;
+               const struct iphdr *ih;
+               struct iphdr _iph;
 
                ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
                if (ih == NULL) {
@@ -99,7 +100,8 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
                    ih->protocol == IPPROTO_UDPLITE ||
                    ih->protocol == IPPROTO_SCTP ||
                    ih->protocol == IPPROTO_DCCP) {
-                       struct tcpudphdr _ports, *pptr;
+                       const struct tcpudphdr *pptr;
+                       struct tcpudphdr _ports;
 
                        pptr = skb_header_pointer(skb, ih->ihl*4,
                                                  sizeof(_ports), &_ports);
@@ -116,7 +118,8 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
        if ((bitmask & EBT_LOG_ARP) &&
            ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) ||
             (eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) {
-               struct arphdr _arph, *ah;
+               const struct arphdr *ah;
+               struct arphdr _arph;
 
                ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
                if (ah == NULL) {
@@ -132,7 +135,8 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
                if (ah->ar_hrd == htons(1) &&
                    ah->ar_hln == ETH_ALEN &&
                    ah->ar_pln == sizeof(__be32)) {
-                       struct arppayload _arpp, *ap;
+                       const struct arppayload *ap;
+                       struct arppayload _arpp;
 
                        ap = skb_header_pointer(skb, sizeof(_arph),
                                                sizeof(_arpp), &_arpp);
@@ -160,7 +164,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
    const struct net_device *in, const struct net_device *out,
    const void *data, unsigned int datalen)
 {
-       struct ebt_log_info *info = (struct ebt_log_info *)data;
+       const struct ebt_log_info *info = data;
        struct nf_loginfo li;
 
        li.type = NF_LOG_TYPE_LOG;
@@ -208,4 +212,5 @@ static void __exit ebt_log_fini(void)
 
 module_init(ebt_log_init);
 module_exit(ebt_log_fini);
+MODULE_DESCRIPTION("Ebtables: Packet logging to syslog");
 MODULE_LICENSE("GPL");
index 6cba54309c099db7c3229df9c624107f749b922c..36723f47db0a7824bad1a64e47970b8fcd86911f 100644 (file)
@@ -21,7 +21,7 @@ static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr,
    const struct net_device *in, const struct net_device *out,
    const void *data, unsigned int datalen)
 {
-       struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+       const struct ebt_mark_t_info *info = data;
        int action = info->target & -16;
 
        if (action == MARK_SET_VALUE)
@@ -39,7 +39,7 @@ static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr,
 static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+       const struct ebt_mark_t_info *info = data;
        int tmp;
 
        if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
@@ -57,8 +57,7 @@ static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
        return 0;
 }
 
-static struct ebt_target mark_target =
-{
+static struct ebt_target mark_target __read_mostly = {
        .name           = EBT_MARK_TARGET,
        .target         = ebt_target_mark,
        .check          = ebt_target_mark_check,
@@ -77,4 +76,5 @@ static void __exit ebt_mark_fini(void)
 
 module_init(ebt_mark_init);
 module_exit(ebt_mark_fini);
+MODULE_DESCRIPTION("Ebtables: Packet mark modification");
 MODULE_LICENSE("GPL");
index 6b0d2169af74e379b468ea47dc8b47d6e26d5add..9b0a4543861fc02b148fb95c071db1d9228f8d6d 100644 (file)
@@ -16,7 +16,7 @@ static int ebt_filter_mark(const struct sk_buff *skb,
    const struct net_device *in, const struct net_device *out, const void *data,
    unsigned int datalen)
 {
-       struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data;
+       const struct ebt_mark_m_info *info = data;
 
        if (info->bitmask & EBT_MARK_OR)
                return !(!!(skb->mark & info->mask) ^ info->invert);
@@ -26,7 +26,7 @@ static int ebt_filter_mark(const struct sk_buff *skb,
 static int ebt_mark_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data;
+       const struct ebt_mark_m_info *info = data;
 
        if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_m_info)))
                return -EINVAL;
@@ -39,8 +39,7 @@ static int ebt_mark_check(const char *tablename, unsigned int hookmask,
        return 0;
 }
 
-static struct ebt_match filter_mark =
-{
+static struct ebt_match filter_mark __read_mostly = {
        .name           = EBT_MARK_MATCH,
        .match          = ebt_filter_mark,
        .check          = ebt_mark_check,
@@ -59,4 +58,5 @@ static void __exit ebt_mark_m_fini(void)
 
 module_init(ebt_mark_m_init);
 module_exit(ebt_mark_m_fini);
+MODULE_DESCRIPTION("Ebtables: Packet mark match");
 MODULE_LICENSE("GPL");
index 4fffd70e4da7355724d11db8a28d69d7744b45c4..676db32df3d1641237954f461793d5625f5aef19 100644 (file)
@@ -18,7 +18,7 @@ static int ebt_filter_pkttype(const struct sk_buff *skb,
    const void *data,
    unsigned int datalen)
 {
-       struct ebt_pkttype_info *info = (struct ebt_pkttype_info *)data;
+       const struct ebt_pkttype_info *info = data;
 
        return (skb->pkt_type != info->pkt_type) ^ info->invert;
 }
@@ -26,7 +26,7 @@ static int ebt_filter_pkttype(const struct sk_buff *skb,
 static int ebt_pkttype_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_pkttype_info *info = (struct ebt_pkttype_info *)data;
+       const struct ebt_pkttype_info *info = data;
 
        if (datalen != EBT_ALIGN(sizeof(struct ebt_pkttype_info)))
                return -EINVAL;
@@ -36,8 +36,7 @@ static int ebt_pkttype_check(const char *tablename, unsigned int hookmask,
        return 0;
 }
 
-static struct ebt_match filter_pkttype =
-{
+static struct ebt_match filter_pkttype __read_mostly = {
        .name           = EBT_PKTTYPE_MATCH,
        .match          = ebt_filter_pkttype,
        .check          = ebt_pkttype_check,
@@ -56,4 +55,5 @@ static void __exit ebt_pkttype_fini(void)
 
 module_init(ebt_pkttype_init);
 module_exit(ebt_pkttype_fini);
+MODULE_DESCRIPTION("Ebtables: Link layer packet type match");
 MODULE_LICENSE("GPL");
index 422cb834cff997eda08de86f2360c506d76b21c3..bfdf2fb60b1f0cbd16050390e01aba0bdbb9886a 100644 (file)
@@ -19,7 +19,7 @@ static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr,
    const struct net_device *in, const struct net_device *out,
    const void *data, unsigned int datalen)
 {
-       struct ebt_redirect_info *info = (struct ebt_redirect_info *)data;
+       const struct ebt_redirect_info *info = data;
 
        if (skb_make_writable(skb, 0))
                return NF_DROP;
@@ -36,7 +36,7 @@ static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr,
 static int ebt_target_redirect_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_redirect_info *info = (struct ebt_redirect_info *)data;
+       const struct ebt_redirect_info *info = data;
 
        if (datalen != EBT_ALIGN(sizeof(struct ebt_redirect_info)))
                return -EINVAL;
@@ -51,8 +51,7 @@ static int ebt_target_redirect_check(const char *tablename, unsigned int hookmas
        return 0;
 }
 
-static struct ebt_target redirect_target =
-{
+static struct ebt_target redirect_target __read_mostly = {
        .name           = EBT_REDIRECT_TARGET,
        .target         = ebt_target_redirect,
        .check          = ebt_target_redirect_check,
@@ -71,4 +70,5 @@ static void __exit ebt_redirect_fini(void)
 
 module_init(ebt_redirect_init);
 module_exit(ebt_redirect_fini);
+MODULE_DESCRIPTION("Ebtables: Packet redirection to localhost");
 MODULE_LICENSE("GPL");
index 425ac920904d7b5ddb6090e9ab338073b0ae7318..e252dabbb143c80536473c77542b4ecf685c7bc2 100644 (file)
@@ -20,7 +20,7 @@ static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr,
    const struct net_device *in, const struct net_device *out,
    const void *data, unsigned int datalen)
 {
-       struct ebt_nat_info *info = (struct ebt_nat_info *) data;
+       const struct ebt_nat_info *info = data;
 
        if (skb_make_writable(skb, 0))
                return NF_DROP;
@@ -28,7 +28,8 @@ static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr,
        memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN);
        if (!(info->target & NAT_ARP_BIT) &&
            eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
-               struct arphdr _ah, *ap;
+               const struct arphdr *ap;
+               struct arphdr _ah;
 
                ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
                if (ap == NULL)
@@ -45,7 +46,7 @@ out:
 static int ebt_target_snat_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_nat_info *info = (struct ebt_nat_info *) data;
+       const struct ebt_nat_info *info = data;
        int tmp;
 
        if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info)))
@@ -67,8 +68,7 @@ static int ebt_target_snat_check(const char *tablename, unsigned int hookmask,
        return 0;
 }
 
-static struct ebt_target snat =
-{
+static struct ebt_target snat __read_mostly = {
        .name           = EBT_SNAT_TARGET,
        .target         = ebt_target_snat,
        .check          = ebt_target_snat_check,
@@ -87,4 +87,5 @@ static void __exit ebt_snat_fini(void)
 
 module_init(ebt_snat_init);
 module_exit(ebt_snat_fini);
+MODULE_DESCRIPTION("Ebtables: Source MAC address translation");
 MODULE_LICENSE("GPL");
index 31b77367319cb3949e5c9f61f27ce3c184225067..40f36d37607d6a8dee0aca874003a2086ecd160d 100644 (file)
@@ -40,10 +40,10 @@ struct stp_config_pdu {
 #define NR16(p) (p[0] << 8 | p[1])
 #define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3])
 
-static int ebt_filter_config(struct ebt_stp_info *info,
-   struct stp_config_pdu *stpc)
+static int ebt_filter_config(const struct ebt_stp_info *info,
+   const struct stp_config_pdu *stpc)
 {
-       struct ebt_stp_config_info *c;
+       const struct ebt_stp_config_info *c;
        uint16_t v16;
        uint32_t v32;
        int verdict, i;
@@ -122,9 +122,10 @@ static int ebt_filter_config(struct ebt_stp_info *info,
 static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in,
    const struct net_device *out, const void *data, unsigned int datalen)
 {
-       struct ebt_stp_info *info = (struct ebt_stp_info *)data;
-       struct stp_header _stph, *sp;
-       uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
+       const struct ebt_stp_info *info = data;
+       const struct stp_header *sp;
+       struct stp_header _stph;
+       const uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
 
        sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph);
        if (sp == NULL)
@@ -140,7 +141,8 @@ static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in
 
        if (sp->type == BPDU_TYPE_CONFIG &&
            info->bitmask & EBT_STP_CONFIG_MASK) {
-               struct stp_config_pdu _stpc, *st;
+               const struct stp_config_pdu *st;
+               struct stp_config_pdu _stpc;
 
                st = skb_header_pointer(skb, sizeof(_stph),
                                        sizeof(_stpc), &_stpc);
@@ -154,10 +156,10 @@ static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in
 static int ebt_stp_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_stp_info *info = (struct ebt_stp_info *)data;
-       int len = EBT_ALIGN(sizeof(struct ebt_stp_info));
-       uint8_t bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
-       uint8_t msk[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+       const struct ebt_stp_info *info = data;
+       const unsigned int len = EBT_ALIGN(sizeof(struct ebt_stp_info));
+       const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00};
+       const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
        if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK ||
            !(info->bitmask & EBT_STP_MASK))
@@ -172,8 +174,7 @@ static int ebt_stp_check(const char *tablename, unsigned int hookmask,
        return 0;
 }
 
-static struct ebt_match filter_stp =
-{
+static struct ebt_match filter_stp __read_mostly = {
        .name           = EBT_STP_MATCH,
        .match          = ebt_filter_stp,
        .check          = ebt_stp_check,
@@ -192,4 +193,5 @@ static void __exit ebt_stp_fini(void)
 
 module_init(ebt_stp_init);
 module_exit(ebt_stp_fini);
+MODULE_DESCRIPTION("Ebtables: Spanning Tree Protocol packet match");
 MODULE_LICENSE("GPL");
index 8e7b00b68d3868107dd52f01a82a9262f2f34f49..2d4c9ef909fc6b691e221295a50c6961144a2ea0 100644 (file)
@@ -249,7 +249,7 @@ static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
    const struct net_device *in, const struct net_device *out,
    const void *data, unsigned int datalen)
 {
-       struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
+       const struct ebt_ulog_info *uloginfo = data;
 
        ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL);
 }
@@ -258,7 +258,7 @@ static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
 static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
+       struct ebt_ulog_info *uloginfo = data;
 
        if (datalen != EBT_ALIGN(sizeof(struct ebt_ulog_info)) ||
            uloginfo->nlgroup > 31)
@@ -272,7 +272,7 @@ static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
        return 0;
 }
 
-static struct ebt_watcher ulog = {
+static struct ebt_watcher ulog __read_mostly = {
        .name           = EBT_ULOG_WATCHER,
        .watcher        = ebt_ulog,
        .check          = ebt_ulog_check,
@@ -340,5 +340,4 @@ module_init(ebt_ulog_init);
 module_exit(ebt_ulog_fini);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
-MODULE_DESCRIPTION("ebtables userspace logging module for bridged Ethernet"
-                  " frames");
+MODULE_DESCRIPTION("Ebtables: Packet logging to netlink using ULOG");
index 0ddf7499d4962f34a28e4d5c87a0ce1e944593e4..ab60b0dade80439ea9a7c1ac3a261366ec5ee850 100644 (file)
@@ -31,8 +31,7 @@ static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "debug=1 is turn on debug messages");
 MODULE_AUTHOR("Nick Fedchik <nick@fedchik.org.ua>");
-MODULE_DESCRIPTION("802.1Q match module (ebtables extension), v"
-                  MODULE_VERS);
+MODULE_DESCRIPTION("Ebtables: 802.1Q VLAN tag match");
 MODULE_LICENSE("GPL");
 
 
@@ -46,8 +45,9 @@ ebt_filter_vlan(const struct sk_buff *skb,
                const struct net_device *out,
                const void *data, unsigned int datalen)
 {
-       struct ebt_vlan_info *info = (struct ebt_vlan_info *) data;
-       struct vlan_hdr _frame, *fp;
+       const struct ebt_vlan_info *info = data;
+       const struct vlan_hdr *fp;
+       struct vlan_hdr _frame;
 
        unsigned short TCI;     /* Whole TCI, given from parsed frame */
        unsigned short id;      /* VLAN ID, given from frame TCI */
@@ -91,7 +91,7 @@ ebt_check_vlan(const char *tablename,
               unsigned int hooknr,
               const struct ebt_entry *e, void *data, unsigned int datalen)
 {
-       struct ebt_vlan_info *info = (struct ebt_vlan_info *) data;
+       struct ebt_vlan_info *info = data;
 
        /* Parameters buffer overflow check */
        if (datalen != EBT_ALIGN(sizeof(struct ebt_vlan_info))) {
@@ -169,7 +169,7 @@ ebt_check_vlan(const char *tablename,
        return 0;
 }
 
-static struct ebt_match filter_vlan = {
+static struct ebt_match filter_vlan __read_mostly = {
        .name           = EBT_VLAN_MATCH,
        .match          = ebt_filter_vlan,
        .check          = ebt_check_vlan,
index c9c593e1ba6fd4d26d8580bb12f1fccb99126484..edaff2720e1098fea7cbd10d79574548c90db4b1 100644 (file)
@@ -2962,6 +2962,102 @@ int dev_unicast_add(struct net_device *dev, void *addr, int alen)
 }
 EXPORT_SYMBOL(dev_unicast_add);
 
+int __dev_addr_sync(struct dev_addr_list **to, int *to_count,
+                   struct dev_addr_list **from, int *from_count)
+{
+       struct dev_addr_list *da, *next;
+       int err = 0;
+
+       da = *from;
+       while (da != NULL) {
+               next = da->next;
+               if (!da->da_synced) {
+                       err = __dev_addr_add(to, to_count,
+                                            da->da_addr, da->da_addrlen, 0);
+                       if (err < 0)
+                               break;
+                       da->da_synced = 1;
+                       da->da_users++;
+               } else if (da->da_users == 1) {
+                       __dev_addr_delete(to, to_count,
+                                         da->da_addr, da->da_addrlen, 0);
+                       __dev_addr_delete(from, from_count,
+                                         da->da_addr, da->da_addrlen, 0);
+               }
+               da = next;
+       }
+       return err;
+}
+
+void __dev_addr_unsync(struct dev_addr_list **to, int *to_count,
+                      struct dev_addr_list **from, int *from_count)
+{
+       struct dev_addr_list *da, *next;
+
+       da = *from;
+       while (da != NULL) {
+               next = da->next;
+               if (da->da_synced) {
+                       __dev_addr_delete(to, to_count,
+                                         da->da_addr, da->da_addrlen, 0);
+                       da->da_synced = 0;
+                       __dev_addr_delete(from, from_count,
+                                         da->da_addr, da->da_addrlen, 0);
+               }
+               da = next;
+       }
+}
+
+/**
+ *     dev_unicast_sync - Synchronize device's unicast list to another device
+ *     @to: destination device
+ *     @from: source device
+ *
+ *     Add newly added addresses to the destination device and release
+ *     addresses that have no users left. The source device must be
+ *     locked by netif_tx_lock_bh.
+ *
+ *     This function is intended to be called from the dev->set_rx_mode
+ *     function of layered software devices.
+ */
+int dev_unicast_sync(struct net_device *to, struct net_device *from)
+{
+       int err = 0;
+
+       netif_tx_lock_bh(to);
+       err = __dev_addr_sync(&to->uc_list, &to->uc_count,
+                             &from->uc_list, &from->uc_count);
+       if (!err)
+               __dev_set_rx_mode(to);
+       netif_tx_unlock_bh(to);
+       return err;
+}
+EXPORT_SYMBOL(dev_unicast_sync);
+
+/**
+ *     dev_unicast_unsync - Remove synchronized addresses from the destination
+ *                          device
+ *     @to: destination device
+ *     @from: source device
+ *
+ *     Remove all addresses that were added to the destination device by
+ *     dev_unicast_sync(). This function is intended to be called from the
+ *     dev->stop function of layered software devices.
+ */
+void dev_unicast_unsync(struct net_device *to, struct net_device *from)
+{
+       netif_tx_lock_bh(from);
+       netif_tx_lock_bh(to);
+
+       __dev_addr_unsync(&to->uc_list, &to->uc_count,
+                         &from->uc_list, &from->uc_count);
+       __dev_set_rx_mode(to);
+
+       netif_tx_unlock_bh(to);
+       netif_tx_unlock_bh(from);
+}
+EXPORT_SYMBOL(dev_unicast_unsync);
+
 static void __dev_addr_discard(struct dev_addr_list **list)
 {
        struct dev_addr_list *tmp;
index cadbfbf7e7f57a687f4f134030b106a4781f4715..cec582563e0dcdbfcf15aa535115b62d35d29041 100644 (file)
@@ -113,32 +113,15 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
  *     locked by netif_tx_lock_bh.
  *
  *     This function is intended to be called from the dev->set_multicast_list
- *     function of layered software devices.
+ *     or dev->set_rx_mode function of layered software devices.
  */
 int dev_mc_sync(struct net_device *to, struct net_device *from)
 {
-       struct dev_addr_list *da, *next;
        int err = 0;
 
        netif_tx_lock_bh(to);
-       da = from->mc_list;
-       while (da != NULL) {
-               next = da->next;
-               if (!da->da_synced) {
-                       err = __dev_addr_add(&to->mc_list, &to->mc_count,
-                                            da->da_addr, da->da_addrlen, 0);
-                       if (err < 0)
-                               break;
-                       da->da_synced = 1;
-                       da->da_users++;
-               } else if (da->da_users == 1) {
-                       __dev_addr_delete(&to->mc_list, &to->mc_count,
-                                         da->da_addr, da->da_addrlen, 0);
-                       __dev_addr_delete(&from->mc_list, &from->mc_count,
-                                         da->da_addr, da->da_addrlen, 0);
-               }
-               da = next;
-       }
+       err = __dev_addr_sync(&to->mc_list, &to->mc_count,
+                             &from->mc_list, &from->mc_count);
        if (!err)
                __dev_set_rx_mode(to);
        netif_tx_unlock_bh(to);
@@ -160,23 +143,11 @@ EXPORT_SYMBOL(dev_mc_sync);
  */
 void dev_mc_unsync(struct net_device *to, struct net_device *from)
 {
-       struct dev_addr_list *da, *next;
-
        netif_tx_lock_bh(from);
        netif_tx_lock_bh(to);
 
-       da = from->mc_list;
-       while (da != NULL) {
-               next = da->next;
-               if (da->da_synced) {
-                       __dev_addr_delete(&to->mc_list, &to->mc_count,
-                                         da->da_addr, da->da_addrlen, 0);
-                       da->da_synced = 0;
-                       __dev_addr_delete(&from->mc_list, &from->mc_count,
-                                         da->da_addr, da->da_addrlen, 0);
-               }
-               da = next;
-       }
+       __dev_addr_unsync(&to->mc_list, &to->mc_count,
+                         &from->mc_list, &from->mc_count);
        __dev_set_rx_mode(to);
 
        netif_tx_unlock_bh(to);
index eebccdbdbacafb1c913be9dc6ec51b57875afc46..bfcdfaebca5c809b79b9076b56748e9b342cd776 100644 (file)
 
 #define VERSION  "pktgen v2.69: Packet Generator for packet performance testing.\n"
 
-/* The buckets are exponential in 'width' */
-#define LAT_BUCKETS_MAX 32
 #define IP_NAME_SZ 32
 #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */
 #define MPLS_STACK_BOTTOM htonl(0x00000100)
@@ -2044,7 +2042,6 @@ static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us)
        __u64 now;
 
        start = now = getCurUs();
-       printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now));
        while (now < spin_until_us) {
                /* TODO: optimize sleeping behavior */
                if (spin_until_us - now > jiffies_to_usecs(1) + 1)
index 1c4b1cd16d654f1a6737a6bfed3ca6d445f3e8c4..433715fb141a5e0dd6eb092568f63c20c8a2fa86 100644 (file)
@@ -667,6 +667,13 @@ set_rcvbuf:
                else
                        clear_bit(SOCK_PASSSEC, &sock->flags);
                break;
+       case SO_MARK:
+               if (!capable(CAP_NET_ADMIN))
+                       ret = -EPERM;
+               else {
+                       sk->sk_mark = val;
+               }
+               break;
 
                /* We implement the SO_SNDLOWAT etc to
                   not be settable (1003.1g 5.3) */
@@ -836,6 +843,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
        case SO_PEERSEC:
                return security_socket_getpeersec_stream(sock, optval, optlen, len);
 
+       case SO_MARK:
+               v.val = sk->sk_mark;
+               break;
+
        default:
                return -ENOPROTOOPT;
        }
index 9e38b0d6195ce637355762471cb988e8ea4527fa..c982ad88223dd6c5827116a7f362744c7e2ad3c0 100644 (file)
@@ -218,7 +218,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
                return;
        }
 
-       sk = inet_lookup(&dccp_hashinfo, iph->daddr, dh->dccph_dport,
+       sk = inet_lookup(&init_net, &dccp_hashinfo, iph->daddr, dh->dccph_dport,
                         iph->saddr, dh->dccph_sport, inet_iif(skb));
        if (sk == NULL) {
                ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
@@ -436,7 +436,7 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
        if (req != NULL)
                return dccp_check_req(sk, skb, req, prev);
 
-       nsk = inet_lookup_established(&dccp_hashinfo,
+       nsk = inet_lookup_established(&init_net, &dccp_hashinfo,
                                      iph->saddr, dh->dccph_sport,
                                      iph->daddr, dh->dccph_dport,
                                      inet_iif(skb));
@@ -817,7 +817,7 @@ static int dccp_v4_rcv(struct sk_buff *skb)
 
        /* Step 2:
         *      Look up flow ID in table and get corresponding socket */
-       sk = __inet_lookup(&dccp_hashinfo,
+       sk = __inet_lookup(&init_net, &dccp_hashinfo,
                           iph->saddr, dh->dccph_sport,
                           iph->daddr, dh->dccph_dport, inet_iif(skb));
        /*
index f42b75ce7f5ce3c0065cb6b987f291d8bf32a99e..ed0a0053a797ffdf74d9e07b8f9fdfdabd04a62c 100644 (file)
@@ -101,8 +101,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        int err;
        __u64 seq;
 
-       sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
-                         &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
+       sk = inet6_lookup(&init_net, &dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
+                       &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
 
        if (sk == NULL) {
                ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
@@ -366,7 +366,7 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
        if (req != NULL)
                return dccp_check_req(sk, skb, req, prev);
 
-       nsk = __inet6_lookup_established(&dccp_hashinfo,
+       nsk = __inet6_lookup_established(&init_net, &dccp_hashinfo,
                                         &iph->saddr, dh->dccph_sport,
                                         &iph->daddr, ntohs(dh->dccph_dport),
                                         inet6_iif(skb));
@@ -797,7 +797,7 @@ static int dccp_v6_rcv(struct sk_buff *skb)
 
        /* Step 2:
         *      Look up flow ID in table and get corresponding socket */
-       sk = __inet6_lookup(&dccp_hashinfo, &ipv6_hdr(skb)->saddr,
+       sk = __inet6_lookup(&init_net, &dccp_hashinfo, &ipv6_hdr(skb)->saddr,
                            dh->dccph_sport,
                            &ipv6_hdr(skb)->daddr, ntohs(dh->dccph_dport),
                            inet6_iif(skb));
index 24e2b7294bf89e46874cd7dd7dd30f2d08c15c5f..19880b086e712f4e29932debfdc0b06714fef6e7 100644 (file)
@@ -343,6 +343,7 @@ config INET_ESP
        tristate "IP: ESP transformation"
        select XFRM
        select CRYPTO
+       select CRYPTO_AEAD
        select CRYPTO_HMAC
        select CRYPTO_MD5
        select CRYPTO_CBC
index d76803a3dcae843f1ebf07794fdd0da6c34b9498..9d4555ec0b59136eb4e1ba259531c5d57cd7d451 100644 (file)
@@ -300,7 +300,7 @@ static void ah_destroy(struct xfrm_state *x)
 }
 
 
-static struct xfrm_type ah_type =
+static const struct xfrm_type ah_type =
 {
        .description    = "AH4",
        .owner          = THIS_MODULE,
index 5976c598cc4ba5e5cee2e7f089dc9cbd84f70a9a..8e17f65f400215a72c3ac3effb908071255d2747 100644 (file)
@@ -558,8 +558,9 @@ static inline int arp_fwd_proxy(struct in_device *in_dev, struct rtable *rt)
  */
 struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
                           struct net_device *dev, __be32 src_ip,
-                          unsigned char *dest_hw, unsigned char *src_hw,
-                          unsigned char *target_hw)
+                          const unsigned char *dest_hw,
+                          const unsigned char *src_hw,
+                          const unsigned char *target_hw)
 {
        struct sk_buff *skb;
        struct arphdr *arp;
@@ -672,8 +673,8 @@ void arp_xmit(struct sk_buff *skb)
  */
 void arp_send(int type, int ptype, __be32 dest_ip,
              struct net_device *dev, __be32 src_ip,
-             unsigned char *dest_hw, unsigned char *src_hw,
-             unsigned char *target_hw)
+             const unsigned char *dest_hw, const unsigned char *src_hw,
+             const unsigned char *target_hw)
 {
        struct sk_buff *skb;
 
index 21f71bf912d5b1621ec81fc4807dcde7f7355166..f282b26f63eb7c20d0b456e104b1a8772b009bb8 100644 (file)
@@ -64,7 +64,7 @@
 #include <net/rtnetlink.h>
 #include <net/net_namespace.h>
 
-struct ipv4_devconf ipv4_devconf = {
+static struct ipv4_devconf ipv4_devconf = {
        .data = {
                [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
                [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
@@ -485,46 +485,41 @@ errout:
        return err;
 }
 
-static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
+static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh)
 {
        struct nlattr *tb[IFA_MAX+1];
        struct in_ifaddr *ifa;
        struct ifaddrmsg *ifm;
        struct net_device *dev;
        struct in_device *in_dev;
-       int err = -EINVAL;
+       int err;
 
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy);
        if (err < 0)
                goto errout;
 
        ifm = nlmsg_data(nlh);
-       if (ifm->ifa_prefixlen > 32 || tb[IFA_LOCAL] == NULL) {
-               err = -EINVAL;
+       err = -EINVAL;
+       if (ifm->ifa_prefixlen > 32 || tb[IFA_LOCAL] == NULL)
                goto errout;
-       }
 
-       dev = __dev_get_by_index(&init_net, ifm->ifa_index);
-       if (dev == NULL) {
-               err = -ENODEV;
+       dev = __dev_get_by_index(net, ifm->ifa_index);
+       err = -ENODEV;
+       if (dev == NULL)
                goto errout;
-       }
 
        in_dev = __in_dev_get_rtnl(dev);
-       if (in_dev == NULL) {
-               err = -ENOBUFS;
+       err = -ENOBUFS;
+       if (in_dev == NULL)
                goto errout;
-       }
 
        ifa = inet_alloc_ifa();
-       if (ifa == NULL) {
+       if (ifa == NULL)
                /*
                 * A potential indev allocation can be left alive, it stays
                 * assigned to its device and is destroy with it.
                 */
-               err = -ENOBUFS;
                goto errout;
-       }
 
        ipv4_devconf_setall(in_dev);
        in_dev_hold(in_dev);
@@ -568,7 +563,7 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
        if (net != &init_net)
                return -EINVAL;
 
-       ifa = rtm_to_ifaddr(nlh);
+       ifa = rtm_to_ifaddr(net, nlh);
        if (IS_ERR(ifa))
                return PTR_ERR(ifa);
 
@@ -1182,7 +1177,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
 
        s_ip_idx = ip_idx = cb->args[1];
        idx = 0;
-       for_each_netdev(&init_net, dev) {
+       for_each_netdev(net, dev) {
                if (idx < s_idx)
                        goto cont;
                if (idx > s_idx)
@@ -1216,7 +1211,9 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh,
        struct sk_buff *skb;
        u32 seq = nlh ? nlh->nlmsg_seq : 0;
        int err = -ENOBUFS;
+       struct net *net;
 
+       net = ifa->ifa_dev->dev->nd_net;
        skb = nlmsg_new(inet_nlmsg_size(), GFP_KERNEL);
        if (skb == NULL)
                goto errout;
@@ -1228,10 +1225,10 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh,
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, &init_net, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
+       err = rtnl_notify(skb, net, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
 errout:
        if (err < 0)
-               rtnl_set_sk_err(&init_net, RTNLGRP_IPV4_IFADDR, err);
+               rtnl_set_sk_err(net, RTNLGRP_IPV4_IFADDR, err);
 }
 
 #ifdef CONFIG_SYSCTL
index 28ea5c77ca238a72a424ae292c2decc622c2d70e..258d17631b4bb9b1767b8a8afa8582250f046a3a 100644 (file)
+#include <crypto/aead.h>
+#include <crypto/authenc.h>
 #include <linux/err.h>
 #include <linux/module.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/esp.h>
 #include <linux/scatterlist.h>
-#include <linux/crypto.h>
 #include <linux/kernel.h>
 #include <linux/pfkeyv2.h>
-#include <linux/random.h>
+#include <linux/rtnetlink.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/in6.h>
 #include <net/icmp.h>
 #include <net/protocol.h>
 #include <net/udp.h>
 
+struct esp_skb_cb {
+       struct xfrm_skb_cb xfrm;
+       void *tmp;
+};
+
+#define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
+
+/*
+ * Allocate an AEAD request structure with extra space for SG and IV.
+ *
+ * For alignment considerations the IV is placed at the front, followed
+ * by the request and finally the SG list.
+ *
+ * TODO: Use spare space in skb for this where possible.
+ */
+static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags)
+{
+       unsigned int len;
+
+       len = crypto_aead_ivsize(aead);
+       if (len) {
+               len += crypto_aead_alignmask(aead) &
+                      ~(crypto_tfm_ctx_alignment() - 1);
+               len = ALIGN(len, crypto_tfm_ctx_alignment());
+       }
+
+       len += sizeof(struct aead_givcrypt_request) + crypto_aead_reqsize(aead);
+       len = ALIGN(len, __alignof__(struct scatterlist));
+
+       len += sizeof(struct scatterlist) * nfrags;
+
+       return kmalloc(len, GFP_ATOMIC);
+}
+
+static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp)
+{
+       return crypto_aead_ivsize(aead) ?
+              PTR_ALIGN((u8 *)tmp, crypto_aead_alignmask(aead) + 1) : tmp;
+}
+
+static inline struct aead_givcrypt_request *esp_tmp_givreq(
+       struct crypto_aead *aead, u8 *iv)
+{
+       struct aead_givcrypt_request *req;
+
+       req = (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead),
+                               crypto_tfm_ctx_alignment());
+       aead_givcrypt_set_tfm(req, aead);
+       return req;
+}
+
+static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv)
+{
+       struct aead_request *req;
+
+       req = (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead),
+                               crypto_tfm_ctx_alignment());
+       aead_request_set_tfm(req, aead);
+       return req;
+}
+
+static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
+                                            struct aead_request *req)
+{
+       return (void *)ALIGN((unsigned long)(req + 1) +
+                            crypto_aead_reqsize(aead),
+                            __alignof__(struct scatterlist));
+}
+
+static inline struct scatterlist *esp_givreq_sg(
+       struct crypto_aead *aead, struct aead_givcrypt_request *req)
+{
+       return (void *)ALIGN((unsigned long)(req + 1) +
+                            crypto_aead_reqsize(aead),
+                            __alignof__(struct scatterlist));
+}
+
+static void esp_output_done(struct crypto_async_request *base, int err)
+{
+       struct sk_buff *skb = base->data;
+
+       kfree(ESP_SKB_CB(skb)->tmp);
+       xfrm_output_resume(skb, err);
+}
+
 static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
 {
        int err;
        struct ip_esp_hdr *esph;
-       struct crypto_blkcipher *tfm;
-       struct blkcipher_desc desc;
+       struct crypto_aead *aead;
+       struct aead_givcrypt_request *req;
+       struct scatterlist *sg;
+       struct scatterlist *asg;
        struct esp_data *esp;
        struct sk_buff *trailer;
+       void *tmp;
+       u8 *iv;
        u8 *tail;
        int blksize;
        int clen;
@@ -36,18 +127,27 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
        clen = skb->len;
 
        esp = x->data;
-       alen = esp->auth.icv_trunc_len;
-       tfm = esp->conf.tfm;
-       desc.tfm = tfm;
-       desc.flags = 0;
-       blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
+       aead = esp->aead;
+       alen = crypto_aead_authsize(aead);
+
+       blksize = ALIGN(crypto_aead_blocksize(aead), 4);
        clen = ALIGN(clen + 2, blksize);
-       if (esp->conf.padlen)
-               clen = ALIGN(clen, esp->conf.padlen);
+       if (esp->padlen)
+               clen = ALIGN(clen, esp->padlen);
+
+       if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0)
+               goto error;
+       nfrags = err;
 
-       if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0)
+       tmp = esp_alloc_tmp(aead, nfrags + 1);
+       if (!tmp)
                goto error;
 
+       iv = esp_tmp_iv(aead, tmp);
+       req = esp_tmp_givreq(aead, iv);
+       asg = esp_givreq_sg(aead, req);
+       sg = asg + 1;
+
        /* Fill padding... */
        tail = skb_tail_pointer(trailer);
        do {
@@ -56,28 +156,34 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
                        tail[i] = i + 1;
        } while (0);
        tail[clen - skb->len - 2] = (clen - skb->len) - 2;
-       pskb_put(skb, trailer, clen - skb->len);
+       tail[clen - skb->len - 1] = *skb_mac_header(skb);
+       pskb_put(skb, trailer, clen - skb->len + alen);
 
        skb_push(skb, -skb_network_offset(skb));
        esph = ip_esp_hdr(skb);
-       *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb);
        *skb_mac_header(skb) = IPPROTO_ESP;
 
-       spin_lock_bh(&x->lock);
-
        /* this is non-NULL only with UDP Encapsulation */
        if (x->encap) {
                struct xfrm_encap_tmpl *encap = x->encap;
                struct udphdr *uh;
                __be32 *udpdata32;
+               unsigned int sport, dport;
+               int encap_type;
+
+               spin_lock_bh(&x->lock);
+               sport = encap->encap_sport;
+               dport = encap->encap_dport;
+               encap_type = encap->encap_type;
+               spin_unlock_bh(&x->lock);
 
                uh = (struct udphdr *)esph;
-               uh->source = encap->encap_sport;
-               uh->dest = encap->encap_dport;
-               uh->len = htons(skb->len + alen - skb_transport_offset(skb));
+               uh->source = sport;
+               uh->dest = dport;
+               uh->len = htons(skb->len - skb_transport_offset(skb));
                uh->check = 0;
 
-               switch (encap->encap_type) {
+               switch (encap_type) {
                default:
                case UDP_ENCAP_ESPINUDP:
                        esph = (struct ip_esp_hdr *)(uh + 1);
@@ -95,131 +201,45 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
        esph->spi = x->id.spi;
        esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
 
-       if (esp->conf.ivlen) {
-               if (unlikely(!esp->conf.ivinitted)) {
-                       get_random_bytes(esp->conf.ivec, esp->conf.ivlen);
-                       esp->conf.ivinitted = 1;
-               }
-               crypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
-       }
-
-       do {
-               struct scatterlist *sg = &esp->sgbuf[0];
-
-               if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
-                       sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
-                       if (!sg)
-                               goto unlock;
-               }
-               sg_init_table(sg, nfrags);
-               skb_to_sgvec(skb, sg,
-                            esph->enc_data +
-                            esp->conf.ivlen -
-                            skb->data, clen);
-               err = crypto_blkcipher_encrypt(&desc, sg, sg, clen);
-               if (unlikely(sg != &esp->sgbuf[0]))
-                       kfree(sg);
-       } while (0);
-
-       if (unlikely(err))
-               goto unlock;
-
-       if (esp->conf.ivlen) {
-               memcpy(esph->enc_data, esp->conf.ivec, esp->conf.ivlen);
-               crypto_blkcipher_get_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
-       }
+       sg_init_table(sg, nfrags);
+       skb_to_sgvec(skb, sg,
+                    esph->enc_data + crypto_aead_ivsize(aead) - skb->data,
+                    clen + alen);
+       sg_init_one(asg, esph, sizeof(*esph));
+
+       aead_givcrypt_set_callback(req, 0, esp_output_done, skb);
+       aead_givcrypt_set_crypt(req, sg, sg, clen, iv);
+       aead_givcrypt_set_assoc(req, asg, sizeof(*esph));
+       aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq);
+
+       ESP_SKB_CB(skb)->tmp = tmp;
+       err = crypto_aead_givencrypt(req);
+       if (err == -EINPROGRESS)
+               goto error;
 
-       if (esp->auth.icv_full_len) {
-               err = esp_mac_digest(esp, skb, (u8 *)esph - skb->data,
-                                    sizeof(*esph) + esp->conf.ivlen + clen);
-               memcpy(pskb_put(skb, trailer, alen), esp->auth.work_icv, alen);
-       }
+       if (err == -EBUSY)
+               err = NET_XMIT_DROP;
 
-unlock:
-       spin_unlock_bh(&x->lock);
+       kfree(tmp);
 
 error:
        return err;
 }
 
-/*
- * Note: detecting truncated vs. non-truncated authentication data is very
- * expensive, so we only support truncated data, which is the recommended
- * and common case.
- */
-static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
+static int esp_input_done2(struct sk_buff *skb, int err)
 {
        struct iphdr *iph;
-       struct ip_esp_hdr *esph;
+       struct xfrm_state *x = xfrm_input_state(skb);
        struct esp_data *esp = x->data;
-       struct crypto_blkcipher *tfm = esp->conf.tfm;
-       struct blkcipher_desc desc = { .tfm = tfm };
-       struct sk_buff *trailer;
-       int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
-       int alen = esp->auth.icv_trunc_len;
-       int elen = skb->len - sizeof(*esph) - esp->conf.ivlen - alen;
-       int nfrags;
+       struct crypto_aead *aead = esp->aead;
+       int alen = crypto_aead_authsize(aead);
+       int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead);
+       int elen = skb->len - hlen;
        int ihl;
        u8 nexthdr[2];
-       struct scatterlist *sg;
        int padlen;
-       int err = -EINVAL;
-
-       if (!pskb_may_pull(skb, sizeof(*esph)))
-               goto out;
-
-       if (elen <= 0 || (elen & (blksize-1)))
-               goto out;
-
-       if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
-               goto out;
-       nfrags = err;
-
-       skb->ip_summed = CHECKSUM_NONE;
-
-       spin_lock(&x->lock);
-
-       /* If integrity check is required, do this. */
-       if (esp->auth.icv_full_len) {
-               u8 sum[alen];
 
-               err = esp_mac_digest(esp, skb, 0, skb->len - alen);
-               if (err)
-                       goto unlock;
-
-               if (skb_copy_bits(skb, skb->len - alen, sum, alen))
-                       BUG();
-
-               if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
-                       err = -EBADMSG;
-                       goto unlock;
-               }
-       }
-
-       esph = (struct ip_esp_hdr *)skb->data;
-
-       /* Get ivec. This can be wrong, check against another impls. */
-       if (esp->conf.ivlen)
-               crypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen);
-
-       sg = &esp->sgbuf[0];
-
-       if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
-               err = -ENOMEM;
-               sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
-               if (!sg)
-                       goto unlock;
-       }
-       sg_init_table(sg, nfrags);
-       skb_to_sgvec(skb, sg,
-                    sizeof(*esph) + esp->conf.ivlen,
-                    elen);
-       err = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
-       if (unlikely(sg != &esp->sgbuf[0]))
-               kfree(sg);
-
-unlock:
-       spin_unlock(&x->lock);
+       kfree(ESP_SKB_CB(skb)->tmp);
 
        if (unlikely(err))
                goto out;
@@ -229,15 +249,11 @@ unlock:
 
        err = -EINVAL;
        padlen = nexthdr[0];
-       if (padlen+2 >= elen)
+       if (padlen + 2 + alen >= elen)
                goto out;
 
        /* ... check padding bits here. Silly. :-) */
 
-       /* RFC4303: Drop dummy packets without any error */
-       if (nexthdr[1] == IPPROTO_NONE)
-               goto out;
-
        iph = ip_hdr(skb);
        ihl = iph->ihl * 4;
 
@@ -279,10 +295,87 @@ unlock:
        }
 
        pskb_trim(skb, skb->len - alen - padlen - 2);
-       __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen);
+       __skb_pull(skb, hlen);
        skb_set_transport_header(skb, -ihl);
 
-       return nexthdr[1];
+       err = nexthdr[1];
+
+       /* RFC4303: Drop dummy packets without any error */
+       if (err == IPPROTO_NONE)
+               err = -EINVAL;
+
+out:
+       return err;
+}
+
+static void esp_input_done(struct crypto_async_request *base, int err)
+{
+       struct sk_buff *skb = base->data;
+
+       xfrm_input_resume(skb, esp_input_done2(skb, err));
+}
+
+/*
+ * Note: detecting truncated vs. non-truncated authentication data is very
+ * expensive, so we only support truncated data, which is the recommended
+ * and common case.
+ */
+static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+       struct ip_esp_hdr *esph;
+       struct esp_data *esp = x->data;
+       struct crypto_aead *aead = esp->aead;
+       struct aead_request *req;
+       struct sk_buff *trailer;
+       int elen = skb->len - sizeof(*esph) - crypto_aead_ivsize(aead);
+       int nfrags;
+       void *tmp;
+       u8 *iv;
+       struct scatterlist *sg;
+       struct scatterlist *asg;
+       int err = -EINVAL;
+
+       if (!pskb_may_pull(skb, sizeof(*esph)))
+               goto out;
+
+       if (elen <= 0)
+               goto out;
+
+       if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
+               goto out;
+       nfrags = err;
+
+       err = -ENOMEM;
+       tmp = esp_alloc_tmp(aead, nfrags + 1);
+       if (!tmp)
+               goto out;
+
+       ESP_SKB_CB(skb)->tmp = tmp;
+       iv = esp_tmp_iv(aead, tmp);
+       req = esp_tmp_req(aead, iv);
+       asg = esp_req_sg(aead, req);
+       sg = asg + 1;
+
+       skb->ip_summed = CHECKSUM_NONE;
+
+       esph = (struct ip_esp_hdr *)skb->data;
+
+       /* Get ivec. This can be wrong, check against another impls. */
+       iv = esph->enc_data;
+
+       sg_init_table(sg, nfrags);
+       skb_to_sgvec(skb, sg, sizeof(*esph) + crypto_aead_ivsize(aead), elen);
+       sg_init_one(asg, esph, sizeof(*esph));
+
+       aead_request_set_callback(req, 0, esp_input_done, skb);
+       aead_request_set_crypt(req, sg, sg, elen, iv);
+       aead_request_set_assoc(req, asg, sizeof(*esph));
+
+       err = crypto_aead_decrypt(req);
+       if (err == -EINPROGRESS)
+               goto out;
+
+       err = esp_input_done2(skb, err);
 
 out:
        return err;
@@ -291,11 +384,11 @@ out:
 static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
 {
        struct esp_data *esp = x->data;
-       u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
-       u32 align = max_t(u32, blksize, esp->conf.padlen);
+       u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4);
+       u32 align = max_t(u32, blksize, esp->padlen);
        u32 rem;
 
-       mtu -= x->props.header_len + esp->auth.icv_trunc_len;
+       mtu -= x->props.header_len + crypto_aead_authsize(esp->aead);
        rem = mtu & (align - 1);
        mtu &= ~(align - 1);
 
@@ -342,80 +435,143 @@ static void esp_destroy(struct xfrm_state *x)
        if (!esp)
                return;
 
-       crypto_free_blkcipher(esp->conf.tfm);
-       esp->conf.tfm = NULL;
-       kfree(esp->conf.ivec);
-       esp->conf.ivec = NULL;
-       crypto_free_hash(esp->auth.tfm);
-       esp->auth.tfm = NULL;
-       kfree(esp->auth.work_icv);
-       esp->auth.work_icv = NULL;
+       crypto_free_aead(esp->aead);
        kfree(esp);
 }
 
-static int esp_init_state(struct xfrm_state *x)
+static int esp_init_aead(struct xfrm_state *x)
 {
-       struct esp_data *esp = NULL;
-       struct crypto_blkcipher *tfm;
-       u32 align;
+       struct esp_data *esp = x->data;
+       struct crypto_aead *aead;
+       int err;
+
+       aead = crypto_alloc_aead(x->aead->alg_name, 0, 0);
+       err = PTR_ERR(aead);
+       if (IS_ERR(aead))
+               goto error;
+
+       esp->aead = aead;
+
+       err = crypto_aead_setkey(aead, x->aead->alg_key,
+                                (x->aead->alg_key_len + 7) / 8);
+       if (err)
+               goto error;
+
+       err = crypto_aead_setauthsize(aead, x->aead->alg_icv_len / 8);
+       if (err)
+               goto error;
+
+error:
+       return err;
+}
 
+static int esp_init_authenc(struct xfrm_state *x)
+{
+       struct esp_data *esp = x->data;
+       struct crypto_aead *aead;
+       struct crypto_authenc_key_param *param;
+       struct rtattr *rta;
+       char *key;
+       char *p;
+       char authenc_name[CRYPTO_MAX_ALG_NAME];
+       unsigned int keylen;
+       int err;
+
+       err = -EINVAL;
        if (x->ealg == NULL)
                goto error;
 
-       esp = kzalloc(sizeof(*esp), GFP_KERNEL);
-       if (esp == NULL)
-               return -ENOMEM;
+       err = -ENAMETOOLONG;
+       if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME, "authenc(%s,%s)",
+                    x->aalg ? x->aalg->alg_name : "digest_null",
+                    x->ealg->alg_name) >= CRYPTO_MAX_ALG_NAME)
+               goto error;
+
+       aead = crypto_alloc_aead(authenc_name, 0, 0);
+       err = PTR_ERR(aead);
+       if (IS_ERR(aead))
+               goto error;
+
+       esp->aead = aead;
+
+       keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) +
+                (x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param));
+       err = -ENOMEM;
+       key = kmalloc(keylen, GFP_KERNEL);
+       if (!key)
+               goto error;
+
+       p = key;
+       rta = (void *)p;
+       rta->rta_type = CRYPTO_AUTHENC_KEYA_PARAM;
+       rta->rta_len = RTA_LENGTH(sizeof(*param));
+       param = RTA_DATA(rta);
+       p += RTA_SPACE(sizeof(*param));
 
        if (x->aalg) {
                struct xfrm_algo_desc *aalg_desc;
-               struct crypto_hash *hash;
 
-               hash = crypto_alloc_hash(x->aalg->alg_name, 0,
-                                        CRYPTO_ALG_ASYNC);
-               if (IS_ERR(hash))
-                       goto error;
-
-               esp->auth.tfm = hash;
-               if (crypto_hash_setkey(hash, x->aalg->alg_key,
-                                      (x->aalg->alg_key_len + 7) / 8))
-                       goto error;
+               memcpy(p, x->aalg->alg_key, (x->aalg->alg_key_len + 7) / 8);
+               p += (x->aalg->alg_key_len + 7) / 8;
 
                aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
                BUG_ON(!aalg_desc);
 
+               err = -EINVAL;
                if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
-                   crypto_hash_digestsize(hash)) {
+                   crypto_aead_authsize(aead)) {
                        NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n",
                                 x->aalg->alg_name,
-                                crypto_hash_digestsize(hash),
+                                crypto_aead_authsize(aead),
                                 aalg_desc->uinfo.auth.icv_fullbits/8);
-                       goto error;
+                       goto free_key;
                }
 
-               esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
-               esp->auth.icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8;
-
-               esp->auth.work_icv = kmalloc(esp->auth.icv_full_len, GFP_KERNEL);
-               if (!esp->auth.work_icv)
-                       goto error;
+               err = crypto_aead_setauthsize(
+                       aead, aalg_desc->uinfo.auth.icv_truncbits / 8);
+               if (err)
+                       goto free_key;
        }
 
-       tfm = crypto_alloc_blkcipher(x->ealg->alg_name, 0, CRYPTO_ALG_ASYNC);
-       if (IS_ERR(tfm))
-               goto error;
-       esp->conf.tfm = tfm;
-       esp->conf.ivlen = crypto_blkcipher_ivsize(tfm);
-       esp->conf.padlen = 0;
-       if (esp->conf.ivlen) {
-               esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL);
-               if (unlikely(esp->conf.ivec == NULL))
-                       goto error;
-               esp->conf.ivinitted = 0;
-       }
-       if (crypto_blkcipher_setkey(tfm, x->ealg->alg_key,
-                                   (x->ealg->alg_key_len + 7) / 8))
+       param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8);
+       memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8);
+
+       err = crypto_aead_setkey(aead, key, keylen);
+
+free_key:
+       kfree(key);
+
+error:
+       return err;
+}
+
+static int esp_init_state(struct xfrm_state *x)
+{
+       struct esp_data *esp;
+       struct crypto_aead *aead;
+       u32 align;
+       int err;
+
+       esp = kzalloc(sizeof(*esp), GFP_KERNEL);
+       if (esp == NULL)
+               return -ENOMEM;
+
+       x->data = esp;
+
+       if (x->aead)
+               err = esp_init_aead(x);
+       else
+               err = esp_init_authenc(x);
+
+       if (err)
                goto error;
-       x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
+
+       aead = esp->aead;
+
+       esp->padlen = 0;
+
+       x->props.header_len = sizeof(struct ip_esp_hdr) +
+                             crypto_aead_ivsize(aead);
        if (x->props.mode == XFRM_MODE_TUNNEL)
                x->props.header_len += sizeof(struct iphdr);
        else if (x->props.mode == XFRM_MODE_BEET)
@@ -434,21 +590,17 @@ static int esp_init_state(struct xfrm_state *x)
                        break;
                }
        }
-       x->data = esp;
-       align = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
-       if (esp->conf.padlen)
-               align = max_t(u32, align, esp->conf.padlen);
-       x->props.trailer_len = align + 1 + esp->auth.icv_trunc_len;
-       return 0;
+
+       align = ALIGN(crypto_aead_blocksize(aead), 4);
+       if (esp->padlen)
+               align = max_t(u32, align, esp->padlen);
+       x->props.trailer_len = align + 1 + crypto_aead_authsize(esp->aead);
 
 error:
-       x->data = esp;
-       esp_destroy(x);
-       x->data = NULL;
-       return -EINVAL;
+       return err;
 }
 
-static struct xfrm_type esp_type =
+static const struct xfrm_type esp_type =
 {
        .description    = "ESP4",
        .owner          = THIS_MODULE,
index d28261826bc2b35b775946a378cef1959fa99077..86ff2711fc957977f179da841a0ffc3b698e75ac 100644 (file)
@@ -808,7 +808,7 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
                           First of all, we scan fib_info list searching
                           for stray nexthop entries, then ignite fib_flush.
                        */
-                       if (fib_sync_down(ifa->ifa_local, NULL, 0))
+                       if (fib_sync_down_addr(dev->nd_net, ifa->ifa_local))
                                fib_flush(dev->nd_net);
                }
        }
@@ -898,7 +898,7 @@ static void nl_fib_lookup_exit(struct net *net)
 
 static void fib_disable_ip(struct net_device *dev, int force)
 {
-       if (fib_sync_down(0, dev, force))
+       if (fib_sync_down_dev(dev, force))
                fib_flush(dev->nd_net);
        rt_cache_flush(0);
        arp_ifdown(dev);
@@ -975,6 +975,7 @@ static struct notifier_block fib_netdev_notifier = {
 
 static int __net_init ip_fib_net_init(struct net *net)
 {
+       int err;
        unsigned int i;
 
        net->ipv4.fib_table_hash = kzalloc(
@@ -985,7 +986,14 @@ static int __net_init ip_fib_net_init(struct net *net)
        for (i = 0; i < FIB_TABLE_HASHSZ; i++)
                INIT_HLIST_HEAD(&net->ipv4.fib_table_hash[i]);
 
-       return fib4_rules_init(net);
+       err = fib4_rules_init(net);
+       if (err < 0)
+               goto fail;
+       return 0;
+
+fail:
+       kfree(net->ipv4.fib_table_hash);
+       return err;
 }
 
 static void __net_exit ip_fib_net_exit(struct net *net)
index a15b2f1b2721d8d4239c81f4eddf13f3fccd6947..76b9c684cccd2ac6d159ea597c0e734ed26f4b05 100644 (file)
@@ -424,19 +424,43 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
 
        if (fa && fa->fa_tos == tos &&
            fa->fa_info->fib_priority == fi->fib_priority) {
-               struct fib_alias *fa_orig;
+               struct fib_alias *fa_first, *fa_match;
 
                err = -EEXIST;
                if (cfg->fc_nlflags & NLM_F_EXCL)
                        goto out;
 
+               /* We have 2 goals:
+                * 1. Find exact match for type, scope, fib_info to avoid
+                * duplicate routes
+                * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it
+                */
+               fa_match = NULL;
+               fa_first = fa;
+               fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
+               list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
+                       if (fa->fa_tos != tos)
+                               break;
+                       if (fa->fa_info->fib_priority != fi->fib_priority)
+                               break;
+                       if (fa->fa_type == cfg->fc_type &&
+                           fa->fa_scope == cfg->fc_scope &&
+                           fa->fa_info == fi) {
+                               fa_match = fa;
+                               break;
+                       }
+               }
+
                if (cfg->fc_nlflags & NLM_F_REPLACE) {
                        struct fib_info *fi_drop;
                        u8 state;
 
-                       if (fi->fib_treeref > 1)
+                       fa = fa_first;
+                       if (fa_match) {
+                               if (fa == fa_match)
+                                       err = 0;
                                goto out;
-
+                       }
                        write_lock_bh(&fib_hash_lock);
                        fi_drop = fa->fa_info;
                        fa->fa_info = fi;
@@ -459,20 +483,11 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
                 * uses the same scope, type, and nexthop
                 * information.
                 */
-               fa_orig = fa;
-               fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
-               list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
-                       if (fa->fa_tos != tos)
-                               break;
-                       if (fa->fa_info->fib_priority != fi->fib_priority)
-                               break;
-                       if (fa->fa_type == cfg->fc_type &&
-                           fa->fa_scope == cfg->fc_scope &&
-                           fa->fa_info == fi)
-                               goto out;
-               }
+               if (fa_match)
+                       goto out;
+
                if (!(cfg->fc_nlflags & NLM_F_APPEND))
-                       fa = fa_orig;
+                       fa = fa_first;
        }
 
        err = -ENOENT;
index c7912866d98719d248c796c89b1a1ef9d899e92a..a13c84763d4c10e503e418f2e6afef3e353193c3 100644 (file)
@@ -229,6 +229,8 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi)
        head = &fib_info_hash[hash];
 
        hlist_for_each_entry(fi, node, head, fib_hash) {
+               if (fi->fib_net != nfi->fib_net)
+                       continue;
                if (fi->fib_nhs != nfi->fib_nhs)
                        continue;
                if (nfi->fib_protocol == fi->fib_protocol &&
@@ -687,6 +689,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
        struct fib_info *fi = NULL;
        struct fib_info *ofi;
        int nhs = 1;
+       struct net *net = cfg->fc_nlinfo.nl_net;
 
        /* Fast check to catch the most weird cases */
        if (fib_props[cfg->fc_type].scope > cfg->fc_scope)
@@ -727,6 +730,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
                goto failure;
        fib_info_cnt++;
 
+       fi->fib_net = net;
        fi->fib_protocol = cfg->fc_protocol;
        fi->fib_flags = cfg->fc_flags;
        fi->fib_priority = cfg->fc_priority;
@@ -798,8 +802,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
                if (nhs != 1 || nh->nh_gw)
                        goto err_inval;
                nh->nh_scope = RT_SCOPE_NOWHERE;
-               nh->nh_dev = dev_get_by_index(cfg->fc_nlinfo.nl_net,
-                                             fi->fib_nh->nh_oif);
+               nh->nh_dev = dev_get_by_index(net, fi->fib_nh->nh_oif);
                err = -ENODEV;
                if (nh->nh_dev == NULL)
                        goto failure;
@@ -813,8 +816,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
        if (fi->fib_prefsrc) {
                if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
                    fi->fib_prefsrc != cfg->fc_dst)
-                       if (inet_addr_type(cfg->fc_nlinfo.nl_net,
-                                          fi->fib_prefsrc) != RTN_LOCAL)
+                       if (inet_addr_type(net, fi->fib_prefsrc) != RTN_LOCAL)
                                goto err_inval;
        }
 
@@ -1031,70 +1033,74 @@ nla_put_failure:
      referring to it.
    - device went down -> we must shutdown all nexthops going via it.
  */
-
-int fib_sync_down(__be32 local, struct net_device *dev, int force)
+int fib_sync_down_addr(struct net *net, __be32 local)
 {
        int ret = 0;
-       int scope = RT_SCOPE_NOWHERE;
-
-       if (force)
-               scope = -1;
+       unsigned int hash = fib_laddr_hashfn(local);
+       struct hlist_head *head = &fib_info_laddrhash[hash];
+       struct hlist_node *node;
+       struct fib_info *fi;
 
-       if (local && fib_info_laddrhash) {
-               unsigned int hash = fib_laddr_hashfn(local);
-               struct hlist_head *head = &fib_info_laddrhash[hash];
-               struct hlist_node *node;
-               struct fib_info *fi;
+       if (fib_info_laddrhash == NULL || local == 0)
+               return 0;
 
-               hlist_for_each_entry(fi, node, head, fib_lhash) {
-                       if (fi->fib_prefsrc == local) {
-                               fi->fib_flags |= RTNH_F_DEAD;
-                               ret++;
-                       }
+       hlist_for_each_entry(fi, node, head, fib_lhash) {
+               if (fi->fib_net != net)
+                       continue;
+               if (fi->fib_prefsrc == local) {
+                       fi->fib_flags |= RTNH_F_DEAD;
+                       ret++;
                }
        }
+       return ret;
+}
 
-       if (dev) {
-               struct fib_info *prev_fi = NULL;
-               unsigned int hash = fib_devindex_hashfn(dev->ifindex);
-               struct hlist_head *head = &fib_info_devhash[hash];
-               struct hlist_node *node;
-               struct fib_nh *nh;
+int fib_sync_down_dev(struct net_device *dev, int force)
+{
+       int ret = 0;
+       int scope = RT_SCOPE_NOWHERE;
+       struct fib_info *prev_fi = NULL;
+       unsigned int hash = fib_devindex_hashfn(dev->ifindex);
+       struct hlist_head *head = &fib_info_devhash[hash];
+       struct hlist_node *node;
+       struct fib_nh *nh;
 
-               hlist_for_each_entry(nh, node, head, nh_hash) {
-                       struct fib_info *fi = nh->nh_parent;
-                       int dead;
+       if (force)
+               scope = -1;
 
-                       BUG_ON(!fi->fib_nhs);
-                       if (nh->nh_dev != dev || fi == prev_fi)
-                               continue;
-                       prev_fi = fi;
-                       dead = 0;
-                       change_nexthops(fi) {
-                               if (nh->nh_flags&RTNH_F_DEAD)
-                                       dead++;
-                               else if (nh->nh_dev == dev &&
-                                        nh->nh_scope != scope) {
-                                       nh->nh_flags |= RTNH_F_DEAD;
+       hlist_for_each_entry(nh, node, head, nh_hash) {
+               struct fib_info *fi = nh->nh_parent;
+               int dead;
+
+               BUG_ON(!fi->fib_nhs);
+               if (nh->nh_dev != dev || fi == prev_fi)
+                       continue;
+               prev_fi = fi;
+               dead = 0;
+               change_nexthops(fi) {
+                       if (nh->nh_flags&RTNH_F_DEAD)
+                               dead++;
+                       else if (nh->nh_dev == dev &&
+                                       nh->nh_scope != scope) {
+                               nh->nh_flags |= RTNH_F_DEAD;
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
-                                       spin_lock_bh(&fib_multipath_lock);
-                                       fi->fib_power -= nh->nh_power;
-                                       nh->nh_power = 0;
-                                       spin_unlock_bh(&fib_multipath_lock);
+                               spin_lock_bh(&fib_multipath_lock);
+                               fi->fib_power -= nh->nh_power;
+                               nh->nh_power = 0;
+                               spin_unlock_bh(&fib_multipath_lock);
 #endif
-                                       dead++;
-                               }
+                               dead++;
+                       }
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
-                               if (force > 1 && nh->nh_dev == dev) {
-                                       dead = fi->fib_nhs;
-                                       break;
-                               }
-#endif
-                       } endfor_nexthops(fi)
-                       if (dead == fi->fib_nhs) {
-                               fi->fib_flags |= RTNH_F_DEAD;
-                               ret++;
+                       if (force > 1 && nh->nh_dev == dev) {
+                               dead = fi->fib_nhs;
+                               break;
                        }
+#endif
+               } endfor_nexthops(fi)
+               if (dead == fi->fib_nhs) {
+                       fi->fib_flags |= RTNH_F_DEAD;
+                       ret++;
                }
        }
 
index f2f47033f31f3a211a1cba23438500c0a1076be9..35851c96bdfb2e6f00eb3681b4d9a090a0163a42 100644 (file)
@@ -1205,20 +1205,45 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
         * and we need to allocate a new one of those as well.
         */
 
-       if (fa && fa->fa_info->fib_priority == fi->fib_priority) {
-               struct fib_alias *fa_orig;
+       if (fa && fa->fa_tos == tos &&
+           fa->fa_info->fib_priority == fi->fib_priority) {
+               struct fib_alias *fa_first, *fa_match;
 
                err = -EEXIST;
                if (cfg->fc_nlflags & NLM_F_EXCL)
                        goto out;
 
+               /* We have 2 goals:
+                * 1. Find exact match for type, scope, fib_info to avoid
+                * duplicate routes
+                * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it
+                */
+               fa_match = NULL;
+               fa_first = fa;
+               fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
+               list_for_each_entry_continue(fa, fa_head, fa_list) {
+                       if (fa->fa_tos != tos)
+                               break;
+                       if (fa->fa_info->fib_priority != fi->fib_priority)
+                               break;
+                       if (fa->fa_type == cfg->fc_type &&
+                           fa->fa_scope == cfg->fc_scope &&
+                           fa->fa_info == fi) {
+                               fa_match = fa;
+                               break;
+                       }
+               }
+
                if (cfg->fc_nlflags & NLM_F_REPLACE) {
                        struct fib_info *fi_drop;
                        u8 state;
 
-                       if (fi->fib_treeref > 1)
+                       fa = fa_first;
+                       if (fa_match) {
+                               if (fa == fa_match)
+                                       err = 0;
                                goto out;
-
+                       }
                        err = -ENOBUFS;
                        new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
                        if (new_fa == NULL)
@@ -1230,7 +1255,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
                        new_fa->fa_type = cfg->fc_type;
                        new_fa->fa_scope = cfg->fc_scope;
                        state = fa->fa_state;
-                       new_fa->fa_state &= ~FA_S_ACCESSED;
+                       new_fa->fa_state = state & ~FA_S_ACCESSED;
 
                        list_replace_rcu(&fa->fa_list, &new_fa->fa_list);
                        alias_free_mem_rcu(fa);
@@ -1247,20 +1272,11 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
                 * uses the same scope, type, and nexthop
                 * information.
                 */
-               fa_orig = fa;
-               list_for_each_entry(fa, fa_orig->fa_list.prev, fa_list) {
-                       if (fa->fa_tos != tos)
-                               break;
-                       if (fa->fa_info->fib_priority != fi->fib_priority)
-                               break;
-                       if (fa->fa_type == cfg->fc_type &&
-                           fa->fa_scope == cfg->fc_scope &&
-                           fa->fa_info == fi)
-                               goto out;
-               }
+               if (fa_match)
+                       goto out;
 
                if (!(cfg->fc_nlflags & NLM_F_APPEND))
-                       fa = fa_orig;
+                       fa = fa_first;
        }
        err = -ENOENT;
        if (!(cfg->fc_nlflags & NLM_F_CREATE))
@@ -1600,9 +1616,8 @@ static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg)
        pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t);
 
        fa_to_delete = NULL;
-       fa_head = fa->fa_list.prev;
-
-       list_for_each_entry(fa, fa_head, fa_list) {
+       fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
+       list_for_each_entry_continue(fa, fa_head, fa_list) {
                struct fib_info *fi = fa->fa_info;
 
                if (fa->fa_tos != tos)
@@ -1743,6 +1758,19 @@ static struct leaf *trie_nextleaf(struct leaf *l)
        return leaf_walk_rcu(p, c);
 }
 
+static struct leaf *trie_leafindex(struct trie *t, int index)
+{
+       struct leaf *l = trie_firstleaf(t);
+
+       while (index-- > 0) {
+               l = trie_nextleaf(l);
+               if (!l)
+                       break;
+       }
+       return l;
+}
+
+
 /*
  * Caller must hold RTNL.
  */
@@ -1848,7 +1876,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah,
        struct fib_alias *fa;
        __be32 xkey = htonl(key);
 
-       s_i = cb->args[4];
+       s_i = cb->args[5];
        i = 0;
 
        /* rcu_read_lock is hold by caller */
@@ -1869,12 +1897,12 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah,
                                  plen,
                                  fa->fa_tos,
                                  fa->fa_info, NLM_F_MULTI) < 0) {
-                       cb->args[4] = i;
+                       cb->args[5] = i;
                        return -1;
                }
                i++;
        }
-       cb->args[4] = i;
+       cb->args[5] = i;
        return skb->len;
 }
 
@@ -1885,7 +1913,7 @@ static int fn_trie_dump_leaf(struct leaf *l, struct fib_table *tb,
        struct hlist_node *node;
        int i, s_i;
 
-       s_i = cb->args[3];
+       s_i = cb->args[4];
        i = 0;
 
        /* rcu_read_lock is hold by caller */
@@ -1896,19 +1924,19 @@ static int fn_trie_dump_leaf(struct leaf *l, struct fib_table *tb,
                }
 
                if (i > s_i)
-                       cb->args[4] = 0;
+                       cb->args[5] = 0;
 
                if (list_empty(&li->falh))
                        continue;
 
                if (fn_trie_dump_fa(l->key, li->plen, &li->falh, tb, skb, cb) < 0) {
-                       cb->args[3] = i;
+                       cb->args[4] = i;
                        return -1;
                }
                i++;
        }
 
-       cb->args[3] = i;
+       cb->args[4] = i;
        return skb->len;
 }
 
@@ -1918,35 +1946,37 @@ static int fn_trie_dump(struct fib_table *tb, struct sk_buff *skb,
        struct leaf *l;
        struct trie *t = (struct trie *) tb->tb_data;
        t_key key = cb->args[2];
+       int count = cb->args[3];
 
        rcu_read_lock();
        /* Dump starting at last key.
         * Note: 0.0.0.0/0 (ie default) is first key.
         */
-       if (!key)
+       if (count == 0)
                l = trie_firstleaf(t);
        else {
+               /* Normally, continue from last key, but if that is missing
+                * fallback to using slow rescan
+                */
                l = fib_find_node(t, key);
-               if (!l) {
-                       /* The table changed during the dump, rather than
-                        * giving partial data, just make application retry.
-                        */
-                       rcu_read_unlock();
-                       return -EBUSY;
-               }
+               if (!l)
+                       l = trie_leafindex(t, count);
        }
 
        while (l) {
                cb->args[2] = l->key;
                if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) {
+                       cb->args[3] = count;
                        rcu_read_unlock();
                        return -1;
                }
 
+               ++count;
                l = trie_nextleaf(l);
-               memset(&cb->args[3], 0,
-                      sizeof(cb->args) - 3*sizeof(cb->args[0]));
+               memset(&cb->args[4], 0,
+                      sizeof(cb->args) - 4*sizeof(cb->args[0]));
        }
+       cb->args[3] = count;
        rcu_read_unlock();
 
        return skb->len;
index 7801cceb2d1b7844e11227322490dd14af5722df..de5a41de191a675e69701fd5416bda497da62aaf 100644 (file)
@@ -87,6 +87,7 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo,
        struct hlist_node *node;
        struct inet_bind_bucket *tb;
        int ret;
+       struct net *net = sk->sk_net;
 
        local_bh_disable();
        if (!snum) {
@@ -100,7 +101,7 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo,
                        head = &hashinfo->bhash[inet_bhashfn(rover, hashinfo->bhash_size)];
                        spin_lock(&head->lock);
                        inet_bind_bucket_for_each(tb, node, &head->chain)
-                               if (tb->port == rover)
+                               if (tb->ib_net == net && tb->port == rover)
                                        goto next;
                        break;
                next:
@@ -127,7 +128,7 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo,
                head = &hashinfo->bhash[inet_bhashfn(snum, hashinfo->bhash_size)];
                spin_lock(&head->lock);
                inet_bind_bucket_for_each(tb, node, &head->chain)
-                       if (tb->port == snum)
+                       if (tb->ib_net == net && tb->port == snum)
                                goto tb_found;
        }
        tb = NULL;
@@ -147,7 +148,8 @@ tb_found:
        }
 tb_not_found:
        ret = 1;
-       if (!tb && (tb = inet_bind_bucket_create(hashinfo->bind_bucket_cachep, head, snum)) == NULL)
+       if (!tb && (tb = inet_bind_bucket_create(hashinfo->bind_bucket_cachep,
+                                       net, head, snum)) == NULL)
                goto fail_unlock;
        if (hlist_empty(&tb->owners)) {
                if (sk->sk_reuse && sk->sk_state != TCP_LISTEN)
index 605ed2cd79724b461e933ed4e00ca694f0797bf9..da97695e70963917f98d38cf426caefc6072c069 100644 (file)
@@ -259,20 +259,22 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
        const struct inet_diag_handler *handler;
 
        handler = inet_diag_lock_handler(nlh->nlmsg_type);
-       if (!handler)
-               return -ENOENT;
+       if (IS_ERR(handler)) {
+               err = PTR_ERR(handler);
+               goto unlock;
+       }
 
        hashinfo = handler->idiag_hashinfo;
        err = -EINVAL;
 
        if (req->idiag_family == AF_INET) {
-               sk = inet_lookup(hashinfo, req->id.idiag_dst[0],
+               sk = inet_lookup(&init_net, hashinfo, req->id.idiag_dst[0],
                                 req->id.idiag_dport, req->id.idiag_src[0],
                                 req->id.idiag_sport, req->id.idiag_if);
        }
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
        else if (req->idiag_family == AF_INET6) {
-               sk = inet6_lookup(hashinfo,
+               sk = inet6_lookup(&init_net, hashinfo,
                                  (struct in6_addr *)req->id.idiag_dst,
                                  req->id.idiag_dport,
                                  (struct in6_addr *)req->id.idiag_src,
@@ -708,8 +710,8 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
        struct inet_hashinfo *hashinfo;
 
        handler = inet_diag_lock_handler(cb->nlh->nlmsg_type);
-       if (!handler)
-               goto no_handler;
+       if (IS_ERR(handler))
+               goto unlock;
 
        hashinfo = handler->idiag_hashinfo;
 
@@ -838,7 +840,6 @@ done:
        cb->args[2] = num;
 unlock:
        inet_diag_unlock_handler(handler);
-no_handler:
        return skb->len;
 }
 
index 619c63c6948aa1cac403c3a7e94a5dc550acba1b..48d45008f749664699856fa9d7ee8b465f4377c2 100644 (file)
  * The bindhash mutex for snum's hash chain must be held here.
  */
 struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
+                                                struct net *net,
                                                 struct inet_bind_hashbucket *head,
                                                 const unsigned short snum)
 {
        struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC);
 
        if (tb != NULL) {
+               tb->ib_net       = net;
                tb->port      = snum;
                tb->fastreuse = 0;
                INIT_HLIST_HEAD(&tb->owners);
@@ -125,7 +127,8 @@ EXPORT_SYMBOL(inet_listen_wlock);
  * remote address for the connection. So always assume those are both
  * wildcarded during the search since they can never be otherwise.
  */
-static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
+static struct sock *inet_lookup_listener_slow(struct net *net,
+                                             const struct hlist_head *head,
                                              const __be32 daddr,
                                              const unsigned short hnum,
                                              const int dif)
@@ -137,7 +140,8 @@ static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
        sk_for_each(sk, node, head) {
                const struct inet_sock *inet = inet_sk(sk);
 
-               if (inet->num == hnum && !ipv6_only_sock(sk)) {
+               if (sk->sk_net == net && inet->num == hnum &&
+                               !ipv6_only_sock(sk)) {
                        const __be32 rcv_saddr = inet->rcv_saddr;
                        int score = sk->sk_family == PF_INET ? 1 : 0;
 
@@ -163,7 +167,8 @@ static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
 }
 
 /* Optimize the common listener case. */
-struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
+struct sock *__inet_lookup_listener(struct net *net,
+                                   struct inet_hashinfo *hashinfo,
                                    const __be32 daddr, const unsigned short hnum,
                                    const int dif)
 {
@@ -178,9 +183,9 @@ struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
                if (inet->num == hnum && !sk->sk_node.next &&
                    (!inet->rcv_saddr || inet->rcv_saddr == daddr) &&
                    (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
-                   !sk->sk_bound_dev_if)
+                   !sk->sk_bound_dev_if && sk->sk_net == net)
                        goto sherry_cache;
-               sk = inet_lookup_listener_slow(head, daddr, hnum, dif);
+               sk = inet_lookup_listener_slow(net, head, daddr, hnum, dif);
        }
        if (sk) {
 sherry_cache:
@@ -191,7 +196,8 @@ sherry_cache:
 }
 EXPORT_SYMBOL_GPL(__inet_lookup_listener);
 
-struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
+struct sock * __inet_lookup_established(struct net *net,
+                                 struct inet_hashinfo *hashinfo,
                                  const __be32 saddr, const __be16 sport,
                                  const __be32 daddr, const u16 hnum,
                                  const int dif)
@@ -210,13 +216,15 @@ struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
        prefetch(head->chain.first);
        read_lock(lock);
        sk_for_each(sk, node, &head->chain) {
-               if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
+               if (INET_MATCH(sk, net, hash, acookie,
+                                       saddr, daddr, ports, dif))
                        goto hit; /* You sunk my battleship! */
        }
 
        /* Must check for a TIME_WAIT'er before going to listener hash. */
        sk_for_each(sk, node, &head->twchain) {
-               if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
+               if (INET_TW_MATCH(sk, net, hash, acookie,
+                                       saddr, daddr, ports, dif))
                        goto hit;
        }
        sk = NULL;
@@ -247,6 +255,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
        struct sock *sk2;
        const struct hlist_node *node;
        struct inet_timewait_sock *tw;
+       struct net *net = sk->sk_net;
 
        prefetch(head->chain.first);
        write_lock(lock);
@@ -255,7 +264,8 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
        sk_for_each(sk2, node, &head->twchain) {
                tw = inet_twsk(sk2);
 
-               if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {
+               if (INET_TW_MATCH(sk2, net, hash, acookie,
+                                       saddr, daddr, ports, dif)) {
                        if (twsk_unique(sk, sk2, twp))
                                goto unique;
                        else
@@ -266,7 +276,8 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
 
        /* And established part... */
        sk_for_each(sk2, node, &head->chain) {
-               if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
+               if (INET_MATCH(sk2, net, hash, acookie,
+                                       saddr, daddr, ports, dif))
                        goto not_unique;
        }
 
@@ -348,17 +359,18 @@ void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk)
 }
 EXPORT_SYMBOL_GPL(__inet_hash);
 
-/*
- * Bind a port for a connect operation and hash it.
- */
-int inet_hash_connect(struct inet_timewait_death_row *death_row,
-                     struct sock *sk)
+int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+               struct sock *sk,
+               int (*check_established)(struct inet_timewait_death_row *,
+                       struct sock *, __u16, struct inet_timewait_sock **),
+               void (*hash)(struct inet_hashinfo *, struct sock *))
 {
        struct inet_hashinfo *hinfo = death_row->hashinfo;
        const unsigned short snum = inet_sk(sk)->num;
        struct inet_bind_hashbucket *head;
        struct inet_bind_bucket *tb;
        int ret;
+       struct net *net = sk->sk_net;
 
        if (!snum) {
                int i, remaining, low, high, port;
@@ -381,19 +393,19 @@ int inet_hash_connect(struct inet_timewait_death_row *death_row,
                         * unique enough.
                         */
                        inet_bind_bucket_for_each(tb, node, &head->chain) {
-                               if (tb->port == port) {
+                               if (tb->ib_net == net && tb->port == port) {
                                        BUG_TRAP(!hlist_empty(&tb->owners));
                                        if (tb->fastreuse >= 0)
                                                goto next_port;
-                                       if (!__inet_check_established(death_row,
-                                                                     sk, port,
-                                                                     &tw))
+                                       if (!check_established(death_row, sk,
+                                                               port, &tw))
                                                goto ok;
                                        goto next_port;
                                }
                        }
 
-                       tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep, head, port);
+                       tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
+                                       net, head, port);
                        if (!tb) {
                                spin_unlock(&head->lock);
                                break;
@@ -415,7 +427,7 @@ ok:
                inet_bind_hash(sk, tb, port);
                if (sk_unhashed(sk)) {
                        inet_sk(sk)->sport = htons(port);
-                       __inet_hash_nolisten(hinfo, sk);
+                       hash(hinfo, sk);
                }
                spin_unlock(&head->lock);
 
@@ -432,17 +444,28 @@ ok:
        tb  = inet_csk(sk)->icsk_bind_hash;
        spin_lock_bh(&head->lock);
        if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
-               __inet_hash_nolisten(hinfo, sk);
+               hash(hinfo, sk);
                spin_unlock_bh(&head->lock);
                return 0;
        } else {
                spin_unlock(&head->lock);
                /* No definite answer... Walk to established hash table */
-               ret = __inet_check_established(death_row, sk, snum, NULL);
+               ret = check_established(death_row, sk, snum, NULL);
 out:
                local_bh_enable();
                return ret;
        }
 }
+EXPORT_SYMBOL_GPL(__inet_hash_connect);
+
+/*
+ * Bind a port for a connect operation and hash it.
+ */
+int inet_hash_connect(struct inet_timewait_death_row *death_row,
+                     struct sock *sk)
+{
+       return __inet_hash_connect(death_row, sk,
+                       __inet_check_established, __inet_hash_nolisten);
+}
 
 EXPORT_SYMBOL_GPL(inet_hash_connect);
index 18070ca65771c853dea40e08b02bb1e809b70535..341779e685d913d41ac14ae59a141ab32dca847f 100644 (file)
@@ -168,6 +168,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
        }
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
 
        /* Send it out. */
        return ip_local_out(skb);
@@ -385,6 +386,7 @@ packet_routed:
                             (skb_shinfo(skb)->gso_segs ?: 1) - 1);
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
 
        return ip_local_out(skb);
 
@@ -476,6 +478,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
        if (skb_shinfo(skb)->frag_list) {
                struct sk_buff *frag;
                int first_len = skb_pagelen(skb);
+               int truesizes = 0;
 
                if (first_len - hlen > mtu ||
                    ((first_len - hlen) & 7) ||
@@ -499,7 +502,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
                                sock_hold(skb->sk);
                                frag->sk = skb->sk;
                                frag->destructor = sock_wfree;
-                               skb->truesize -= frag->truesize;
+                               truesizes += frag->truesize;
                        }
                }
 
@@ -510,6 +513,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
                frag = skb_shinfo(skb)->frag_list;
                skb_shinfo(skb)->frag_list = NULL;
                skb->data_len = first_len - skb_headlen(skb);
+               skb->truesize -= truesizes;
                skb->len = first_len;
                iph->tot_len = htons(first_len);
                iph->frag_off = htons(IP_MF);
@@ -1284,6 +1288,7 @@ int ip_push_pending_frames(struct sock *sk)
        iph->daddr = rt->rt_dst;
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
        skb->dst = dst_clone(&rt->u.dst);
 
        if (iph->protocol == IPPROTO_ICMP)
index f4af99ad8fdb6015de40393d52b5bde5bd6c42c7..ae1f45fc23b966869eb7a3b0bf1dbb06712cd7c8 100644 (file)
@@ -74,6 +74,7 @@ out:
 
 static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
 {
+       int nexthdr;
        int err = -ENOMEM;
        struct ip_comp_hdr *ipch;
 
@@ -84,13 +85,15 @@ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
 
        /* Remove ipcomp header and decompress original payload */
        ipch = (void *)skb->data;
+       nexthdr = ipch->nexthdr;
+
        skb->transport_header = skb->network_header + sizeof(*ipch);
        __skb_pull(skb, sizeof(*ipch));
        err = ipcomp_decompress(x, skb);
        if (err)
                goto out;
 
-       err = ipch->nexthdr;
+       err = nexthdr;
 
 out:
        return err;
@@ -434,7 +437,7 @@ error:
        goto out;
 }
 
-static struct xfrm_type ipcomp_type = {
+static const struct xfrm_type ipcomp_type = {
        .description    = "IPCOMP4",
        .owner          = THIS_MODULE,
        .proto          = IPPROTO_COMP,
index b4a810c28ac85c3f79e6e350ea985b8a85ba380d..a7591ce344d2c18a747c717ded8fa96671e2dcc8 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mutex.h>
 #include <linux/err.h>
 #include <net/compat.h>
+#include <net/sock.h>
 #include <asm/uaccess.h>
 
 #include <linux/netfilter/x_tables.h>
@@ -850,7 +851,7 @@ static int compat_table_info(const struct xt_table_info *info,
 }
 #endif
 
-static int get_info(void __user *user, int *len, int compat)
+static int get_info(struct net *net, void __user *user, int *len, int compat)
 {
        char name[ARPT_TABLE_MAXNAMELEN];
        struct arpt_table *t;
@@ -870,7 +871,7 @@ static int get_info(void __user *user, int *len, int compat)
        if (compat)
                xt_compat_lock(NF_ARP);
 #endif
-       t = try_then_request_module(xt_find_table_lock(NF_ARP, name),
+       t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name),
                                    "arptable_%s", name);
        if (t && !IS_ERR(t)) {
                struct arpt_getinfo info;
@@ -908,7 +909,8 @@ static int get_info(void __user *user, int *len, int compat)
        return ret;
 }
 
-static int get_entries(struct arpt_get_entries __user *uptr, int *len)
+static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
+                      int *len)
 {
        int ret;
        struct arpt_get_entries get;
@@ -926,7 +928,7 @@ static int get_entries(struct arpt_get_entries __user *uptr, int *len)
                return -EINVAL;
        }
 
-       t = xt_find_table_lock(NF_ARP, get.name);
+       t = xt_find_table_lock(net, NF_ARP, get.name);
        if (t && !IS_ERR(t)) {
                struct xt_table_info *private = t->private;
                duprintf("t->private->number = %u\n",
@@ -947,7 +949,8 @@ static int get_entries(struct arpt_get_entries __user *uptr, int *len)
        return ret;
 }
 
-static int __do_replace(const char *name, unsigned int valid_hooks,
+static int __do_replace(struct net *net, const char *name,
+                       unsigned int valid_hooks,
                        struct xt_table_info *newinfo,
                        unsigned int num_counters,
                        void __user *counters_ptr)
@@ -966,7 +969,7 @@ static int __do_replace(const char *name, unsigned int valid_hooks,
                goto out;
        }
 
-       t = try_then_request_module(xt_find_table_lock(NF_ARP, name),
+       t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name),
                                    "arptable_%s", name);
        if (!t || IS_ERR(t)) {
                ret = t ? PTR_ERR(t) : -ENOENT;
@@ -1019,7 +1022,7 @@ static int __do_replace(const char *name, unsigned int valid_hooks,
        return ret;
 }
 
-static int do_replace(void __user *user, unsigned int len)
+static int do_replace(struct net *net, void __user *user, unsigned int len)
 {
        int ret;
        struct arpt_replace tmp;
@@ -1053,7 +1056,7 @@ static int do_replace(void __user *user, unsigned int len)
 
        duprintf("arp_tables: Translated table\n");
 
-       ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+       ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
                           tmp.num_counters, tmp.counters);
        if (ret)
                goto free_newinfo_untrans;
@@ -1080,7 +1083,8 @@ static inline int add_counter_to_entry(struct arpt_entry *e,
        return 0;
 }
 
-static int do_add_counters(void __user *user, unsigned int len, int compat)
+static int do_add_counters(struct net *net, void __user *user, unsigned int len,
+                          int compat)
 {
        unsigned int i;
        struct xt_counters_info tmp;
@@ -1132,7 +1136,7 @@ static int do_add_counters(void __user *user, unsigned int len, int compat)
                goto free;
        }
 
-       t = xt_find_table_lock(NF_ARP, name);
+       t = xt_find_table_lock(net, NF_ARP, name);
        if (!t || IS_ERR(t)) {
                ret = t ? PTR_ERR(t) : -ENOENT;
                goto free;
@@ -1435,7 +1439,8 @@ struct compat_arpt_replace {
        struct compat_arpt_entry        entries[0];
 };
 
-static int compat_do_replace(void __user *user, unsigned int len)
+static int compat_do_replace(struct net *net, void __user *user,
+                            unsigned int len)
 {
        int ret;
        struct compat_arpt_replace tmp;
@@ -1471,7 +1476,7 @@ static int compat_do_replace(void __user *user, unsigned int len)
 
        duprintf("compat_do_replace: Translated table\n");
 
-       ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+       ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
                           tmp.num_counters, compat_ptr(tmp.counters));
        if (ret)
                goto free_newinfo_untrans;
@@ -1494,11 +1499,11 @@ static int compat_do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user,
 
        switch (cmd) {
        case ARPT_SO_SET_REPLACE:
-               ret = compat_do_replace(user, len);
+               ret = compat_do_replace(sk->sk_net, user, len);
                break;
 
        case ARPT_SO_SET_ADD_COUNTERS:
-               ret = do_add_counters(user, len, 1);
+               ret = do_add_counters(sk->sk_net, user, len, 1);
                break;
 
        default:
@@ -1584,7 +1589,8 @@ struct compat_arpt_get_entries {
        struct compat_arpt_entry entrytable[0];
 };
 
-static int compat_get_entries(struct compat_arpt_get_entries __user *uptr,
+static int compat_get_entries(struct net *net,
+                             struct compat_arpt_get_entries __user *uptr,
                              int *len)
 {
        int ret;
@@ -1604,7 +1610,7 @@ static int compat_get_entries(struct compat_arpt_get_entries __user *uptr,
        }
 
        xt_compat_lock(NF_ARP);
-       t = xt_find_table_lock(NF_ARP, get.name);
+       t = xt_find_table_lock(net, NF_ARP, get.name);
        if (t && !IS_ERR(t)) {
                struct xt_table_info *private = t->private;
                struct xt_table_info info;
@@ -1641,10 +1647,10 @@ static int compat_do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user,
 
        switch (cmd) {
        case ARPT_SO_GET_INFO:
-               ret = get_info(user, len, 1);
+               ret = get_info(sk->sk_net, user, len, 1);
                break;
        case ARPT_SO_GET_ENTRIES:
-               ret = compat_get_entries(user, len);
+               ret = compat_get_entries(sk->sk_net, user, len);
                break;
        default:
                ret = do_arpt_get_ctl(sk, cmd, user, len);
@@ -1662,11 +1668,11 @@ static int do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned
 
        switch (cmd) {
        case ARPT_SO_SET_REPLACE:
-               ret = do_replace(user, len);
+               ret = do_replace(sk->sk_net, user, len);
                break;
 
        case ARPT_SO_SET_ADD_COUNTERS:
-               ret = do_add_counters(user, len, 0);
+               ret = do_add_counters(sk->sk_net, user, len, 0);
                break;
 
        default:
@@ -1686,11 +1692,11 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
 
        switch (cmd) {
        case ARPT_SO_GET_INFO:
-               ret = get_info(user, len, 0);
+               ret = get_info(sk->sk_net, user, len, 0);
                break;
 
        case ARPT_SO_GET_ENTRIES:
-               ret = get_entries(user, len);
+               ret = get_entries(sk->sk_net, user, len);
                break;
 
        case ARPT_SO_GET_REVISION_TARGET: {
@@ -1719,19 +1725,21 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
        return ret;
 }
 
-int arpt_register_table(struct arpt_table *table,
-                       const struct arpt_replace *repl)
+struct arpt_table *arpt_register_table(struct net *net,
+                                      struct arpt_table *table,
+                                      const struct arpt_replace *repl)
 {
        int ret;
        struct xt_table_info *newinfo;
        struct xt_table_info bootstrap
                = { 0, 0, 0, { 0 }, { 0 }, { } };
        void *loc_cpu_entry;
+       struct xt_table *new_table;
 
        newinfo = xt_alloc_table_info(repl->size);
        if (!newinfo) {
                ret = -ENOMEM;
-               return ret;
+               goto out;
        }
 
        /* choose the copy on our node/cpu */
@@ -1745,24 +1753,27 @@ int arpt_register_table(struct arpt_table *table,
                              repl->underflow);
 
        duprintf("arpt_register_table: translate table gives %d\n", ret);
-       if (ret != 0) {
-               xt_free_table_info(newinfo);
-               return ret;
-       }
+       if (ret != 0)
+               goto out_free;
 
-       ret = xt_register_table(table, &bootstrap, newinfo);
-       if (ret != 0) {
-               xt_free_table_info(newinfo);
-               return ret;
+       new_table = xt_register_table(net, table, &bootstrap, newinfo);
+       if (IS_ERR(new_table)) {
+               ret = PTR_ERR(new_table);
+               goto out_free;
        }
+       return new_table;
 
-       return 0;
+out_free:
+       xt_free_table_info(newinfo);
+out:
+       return ERR_PTR(ret);
 }
 
 void arpt_unregister_table(struct arpt_table *table)
 {
        struct xt_table_info *private;
        void *loc_cpu_entry;
+       struct module *table_owner = table->me;
 
        private = xt_unregister_table(table);
 
@@ -1770,6 +1781,8 @@ void arpt_unregister_table(struct arpt_table *table)
        loc_cpu_entry = private->entries[raw_smp_processor_id()];
        ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size,
                           cleanup_entry, NULL);
+       if (private->number > private->initial_entries)
+               module_put(table_owner);
        xt_free_table_info(private);
 }
 
@@ -1809,11 +1822,26 @@ static struct nf_sockopt_ops arpt_sockopts = {
        .owner          = THIS_MODULE,
 };
 
+static int __net_init arp_tables_net_init(struct net *net)
+{
+       return xt_proto_init(net, NF_ARP);
+}
+
+static void __net_exit arp_tables_net_exit(struct net *net)
+{
+       xt_proto_fini(net, NF_ARP);
+}
+
+static struct pernet_operations arp_tables_net_ops = {
+       .init = arp_tables_net_init,
+       .exit = arp_tables_net_exit,
+};
+
 static int __init arp_tables_init(void)
 {
        int ret;
 
-       ret = xt_proto_init(NF_ARP);
+       ret = register_pernet_subsys(&arp_tables_net_ops);
        if (ret < 0)
                goto err1;
 
@@ -1838,7 +1866,7 @@ err4:
 err3:
        xt_unregister_target(&arpt_standard_target);
 err2:
-       xt_proto_fini(NF_ARP);
+       unregister_pernet_subsys(&arp_tables_net_ops);
 err1:
        return ret;
 }
@@ -1848,7 +1876,7 @@ static void __exit arp_tables_fini(void)
        nf_unregister_sockopt(&arpt_sockopts);
        xt_unregister_target(&arpt_error_target);
        xt_unregister_target(&arpt_standard_target);
-       xt_proto_fini(NF_ARP);
+       unregister_pernet_subsys(&arp_tables_net_ops);
 }
 
 EXPORT_SYMBOL(arpt_register_table);
index 7201511d54d2dbc0da216b4ae8ff04d0483dd733..4e9c496a30c29a1cdce4518a05a37918abcb4b33 100644 (file)
@@ -20,7 +20,7 @@ static struct
        struct arpt_replace repl;
        struct arpt_standard entries[3];
        struct arpt_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
        .repl = {
                .name = "filter",
                .valid_hooks = FILTER_VALID_HOOKS,
@@ -61,7 +61,7 @@ static unsigned int arpt_hook(unsigned int hook,
                              const struct net_device *out,
                              int (*okfn)(struct sk_buff *))
 {
-       return arpt_do_table(skb, hook, in, out, &packet_filter);
+       return arpt_do_table(skb, hook, in, out, init_net.ipv4.arptable_filter);
 }
 
 static struct nf_hook_ops arpt_ops[] __read_mostly = {
@@ -85,12 +85,31 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = {
        },
 };
 
+static int __net_init arptable_filter_net_init(struct net *net)
+{
+       /* Register table */
+       net->ipv4.arptable_filter =
+               arpt_register_table(net, &packet_filter, &initial_table.repl);
+       if (IS_ERR(net->ipv4.arptable_filter))
+               return PTR_ERR(net->ipv4.arptable_filter);
+       return 0;
+}
+
+static void __net_exit arptable_filter_net_exit(struct net *net)
+{
+       arpt_unregister_table(net->ipv4.arptable_filter);
+}
+
+static struct pernet_operations arptable_filter_net_ops = {
+       .init = arptable_filter_net_init,
+       .exit = arptable_filter_net_exit,
+};
+
 static int __init arptable_filter_init(void)
 {
        int ret;
 
-       /* Register table */
-       ret = arpt_register_table(&packet_filter, &initial_table.repl);
+       ret = register_pernet_subsys(&arptable_filter_net_ops);
        if (ret < 0)
                return ret;
 
@@ -100,14 +119,14 @@ static int __init arptable_filter_init(void)
        return ret;
 
 cleanup_table:
-       arpt_unregister_table(&packet_filter);
+       unregister_pernet_subsys(&arptable_filter_net_ops);
        return ret;
 }
 
 static void __exit arptable_filter_fini(void)
 {
        nf_unregister_hooks(arpt_ops, ARRAY_SIZE(arpt_ops));
-       arpt_unregister_table(&packet_filter);
+       unregister_pernet_subsys(&arptable_filter_net_ops);
 }
 
 module_init(arptable_filter_init);
index 5109839da222b28f6f1c255d16f45d729cf87ff2..6bda1102851b8d94d7aabf2859bff378b53970e7 100644 (file)
@@ -512,6 +512,7 @@ static struct notifier_block ipq_nl_notifier = {
        .notifier_call  = ipq_rcv_nl_event,
 };
 
+#ifdef CONFIG_SYSCTL
 static struct ctl_table_header *ipq_sysctl_header;
 
 static ctl_table ipq_table[] = {
@@ -525,7 +526,9 @@ static ctl_table ipq_table[] = {
        },
        { .ctl_name = 0 }
 };
+#endif
 
+#ifdef CONFIG_PROC_FS
 static int ip_queue_show(struct seq_file *m, void *v)
 {
        read_lock_bh(&queue_lock);
@@ -562,6 +565,7 @@ static const struct file_operations ip_queue_proc_fops = {
        .release        = single_release,
        .owner          = THIS_MODULE,
 };
+#endif
 
 static const struct nf_queue_handler nfqh = {
        .name   = "ip_queue",
@@ -571,7 +575,7 @@ static const struct nf_queue_handler nfqh = {
 static int __init ip_queue_init(void)
 {
        int status = -ENOMEM;
-       struct proc_dir_entry *proc;
+       struct proc_dir_entry *proc __maybe_unused;
 
        netlink_register_notifier(&ipq_nl_notifier);
        ipqnl = netlink_kernel_create(&init_net, NETLINK_FIREWALL, 0,
@@ -581,6 +585,7 @@ static int __init ip_queue_init(void)
                goto cleanup_netlink_notifier;
        }
 
+#ifdef CONFIG_PROC_FS
        proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net);
        if (proc) {
                proc->owner = THIS_MODULE;
@@ -589,10 +594,11 @@ static int __init ip_queue_init(void)
                printk(KERN_ERR "ip_queue: failed to create proc entry\n");
                goto cleanup_ipqnl;
        }
-
+#endif
        register_netdevice_notifier(&ipq_dev_notifier);
+#ifdef CONFIG_SYSCTL
        ipq_sysctl_header = register_sysctl_paths(net_ipv4_ctl_path, ipq_table);
-
+#endif
        status = nf_register_queue_handler(PF_INET, &nfqh);
        if (status < 0) {
                printk(KERN_ERR "ip_queue: failed to register queue handler\n");
@@ -601,10 +607,12 @@ static int __init ip_queue_init(void)
        return status;
 
 cleanup_sysctl:
+#ifdef CONFIG_SYSCTL
        unregister_sysctl_table(ipq_sysctl_header);
+#endif
        unregister_netdevice_notifier(&ipq_dev_notifier);
        proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
-cleanup_ipqnl:
+cleanup_ipqnl: __maybe_unused
        netlink_kernel_release(ipqnl);
        mutex_lock(&ipqnl_mutex);
        mutex_unlock(&ipqnl_mutex);
@@ -620,7 +628,9 @@ static void __exit ip_queue_fini(void)
        synchronize_net();
        ipq_flush(NULL, 0);
 
+#ifdef CONFIG_SYSCTL
        unregister_sysctl_table(ipq_sysctl_header);
+#endif
        unregister_netdevice_notifier(&ipq_dev_notifier);
        proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
 
index 982b7f9862918cd3c25d1ad9e11c95985fc2e459..600737f122d2eee84f269f3abffe2b02880d454b 100644 (file)
@@ -291,7 +291,7 @@ static void trace_packet(struct sk_buff *skb,
                         unsigned int hook,
                         const struct net_device *in,
                         const struct net_device *out,
-                        char *tablename,
+                        const char *tablename,
                         struct xt_table_info *private,
                         struct ipt_entry *e)
 {
@@ -1092,7 +1092,7 @@ static int compat_table_info(const struct xt_table_info *info,
 }
 #endif
 
-static int get_info(void __user *user, int *len, int compat)
+static int get_info(struct net *net, void __user *user, int *len, int compat)
 {
        char name[IPT_TABLE_MAXNAMELEN];
        struct xt_table *t;
@@ -1112,7 +1112,7 @@ static int get_info(void __user *user, int *len, int compat)
        if (compat)
                xt_compat_lock(AF_INET);
 #endif
-       t = try_then_request_module(xt_find_table_lock(AF_INET, name),
+       t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
                                    "iptable_%s", name);
        if (t && !IS_ERR(t)) {
                struct ipt_getinfo info;
@@ -1152,7 +1152,7 @@ static int get_info(void __user *user, int *len, int compat)
 }
 
 static int
-get_entries(struct ipt_get_entries __user *uptr, int *len)
+get_entries(struct net *net, struct ipt_get_entries __user *uptr, int *len)
 {
        int ret;
        struct ipt_get_entries get;
@@ -1170,7 +1170,7 @@ get_entries(struct ipt_get_entries __user *uptr, int *len)
                return -EINVAL;
        }
 
-       t = xt_find_table_lock(AF_INET, get.name);
+       t = xt_find_table_lock(net, AF_INET, get.name);
        if (t && !IS_ERR(t)) {
                struct xt_table_info *private = t->private;
                duprintf("t->private->number = %u\n", private->number);
@@ -1191,7 +1191,7 @@ get_entries(struct ipt_get_entries __user *uptr, int *len)
 }
 
 static int
-__do_replace(const char *name, unsigned int valid_hooks,
+__do_replace(struct net *net, const char *name, unsigned int valid_hooks,
             struct xt_table_info *newinfo, unsigned int num_counters,
             void __user *counters_ptr)
 {
@@ -1208,7 +1208,7 @@ __do_replace(const char *name, unsigned int valid_hooks,
                goto out;
        }
 
-       t = try_then_request_module(xt_find_table_lock(AF_INET, name),
+       t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
                                    "iptable_%s", name);
        if (!t || IS_ERR(t)) {
                ret = t ? PTR_ERR(t) : -ENOENT;
@@ -1261,7 +1261,7 @@ __do_replace(const char *name, unsigned int valid_hooks,
 }
 
 static int
-do_replace(void __user *user, unsigned int len)
+do_replace(struct net *net, void __user *user, unsigned int len)
 {
        int ret;
        struct ipt_replace tmp;
@@ -1295,7 +1295,7 @@ do_replace(void __user *user, unsigned int len)
 
        duprintf("ip_tables: Translated table\n");
 
-       ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+       ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
                           tmp.num_counters, tmp.counters);
        if (ret)
                goto free_newinfo_untrans;
@@ -1331,7 +1331,7 @@ add_counter_to_entry(struct ipt_entry *e,
 }
 
 static int
-do_add_counters(void __user *user, unsigned int len, int compat)
+do_add_counters(struct net *net, void __user *user, unsigned int len, int compat)
 {
        unsigned int i;
        struct xt_counters_info tmp;
@@ -1383,7 +1383,7 @@ do_add_counters(void __user *user, unsigned int len, int compat)
                goto free;
        }
 
-       t = xt_find_table_lock(AF_INET, name);
+       t = xt_find_table_lock(net, AF_INET, name);
        if (!t || IS_ERR(t)) {
                ret = t ? PTR_ERR(t) : -ENOENT;
                goto free;
@@ -1429,7 +1429,7 @@ struct compat_ipt_replace {
 
 static int
 compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
-                         compat_uint_t *size, struct xt_counters *counters,
+                         unsigned int *size, struct xt_counters *counters,
                          unsigned int *i)
 {
        struct ipt_entry_target *t;
@@ -1476,7 +1476,7 @@ compat_find_calc_match(struct ipt_entry_match *m,
                       const char *name,
                       const struct ipt_ip *ip,
                       unsigned int hookmask,
-                      int *size, int *i)
+                      int *size, unsigned int *i)
 {
        struct xt_match *match;
 
@@ -1534,7 +1534,8 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
        struct ipt_entry_target *t;
        struct xt_target *target;
        unsigned int entry_offset;
-       int ret, off, h, j;
+       unsigned int j;
+       int ret, off, h;
 
        duprintf("check_compat_entry_size_and_hooks %p\n", e);
        if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0
@@ -1647,7 +1648,8 @@ static int
 compat_check_entry(struct ipt_entry *e, const char *name,
                                     unsigned int *i)
 {
-       int j, ret;
+       unsigned int j;
+       int ret;
 
        j = 0;
        ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip,
@@ -1789,7 +1791,7 @@ out_unlock:
 }
 
 static int
-compat_do_replace(void __user *user, unsigned int len)
+compat_do_replace(struct net *net, void __user *user, unsigned int len)
 {
        int ret;
        struct compat_ipt_replace tmp;
@@ -1826,7 +1828,7 @@ compat_do_replace(void __user *user, unsigned int len)
 
        duprintf("compat_do_replace: Translated table\n");
 
-       ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+       ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
                           tmp.num_counters, compat_ptr(tmp.counters));
        if (ret)
                goto free_newinfo_untrans;
@@ -1850,11 +1852,11 @@ compat_do_ipt_set_ctl(struct sock *sk,  int cmd, void __user *user,
 
        switch (cmd) {
        case IPT_SO_SET_REPLACE:
-               ret = compat_do_replace(user, len);
+               ret = compat_do_replace(sk->sk_net, user, len);
                break;
 
        case IPT_SO_SET_ADD_COUNTERS:
-               ret = do_add_counters(user, len, 1);
+               ret = do_add_counters(sk->sk_net, user, len, 1);
                break;
 
        default:
@@ -1903,7 +1905,8 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
 }
 
 static int
-compat_get_entries(struct compat_ipt_get_entries __user *uptr, int *len)
+compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
+                  int *len)
 {
        int ret;
        struct compat_ipt_get_entries get;
@@ -1924,7 +1927,7 @@ compat_get_entries(struct compat_ipt_get_entries __user *uptr, int *len)
        }
 
        xt_compat_lock(AF_INET);
-       t = xt_find_table_lock(AF_INET, get.name);
+       t = xt_find_table_lock(net, AF_INET, get.name);
        if (t && !IS_ERR(t)) {
                struct xt_table_info *private = t->private;
                struct xt_table_info info;
@@ -1960,10 +1963,10 @@ compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 
        switch (cmd) {
        case IPT_SO_GET_INFO:
-               ret = get_info(user, len, 1);
+               ret = get_info(sk->sk_net, user, len, 1);
                break;
        case IPT_SO_GET_ENTRIES:
-               ret = compat_get_entries(user, len);
+               ret = compat_get_entries(sk->sk_net, user, len);
                break;
        default:
                ret = do_ipt_get_ctl(sk, cmd, user, len);
@@ -1982,11 +1985,11 @@ do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
 
        switch (cmd) {
        case IPT_SO_SET_REPLACE:
-               ret = do_replace(user, len);
+               ret = do_replace(sk->sk_net, user, len);
                break;
 
        case IPT_SO_SET_ADD_COUNTERS:
-               ret = do_add_counters(user, len, 0);
+               ret = do_add_counters(sk->sk_net, user, len, 0);
                break;
 
        default:
@@ -2007,11 +2010,11 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 
        switch (cmd) {
        case IPT_SO_GET_INFO:
-               ret = get_info(user, len, 0);
+               ret = get_info(sk->sk_net, user, len, 0);
                break;
 
        case IPT_SO_GET_ENTRIES:
-               ret = get_entries(user, len);
+               ret = get_entries(sk->sk_net, user, len);
                break;
 
        case IPT_SO_GET_REVISION_MATCH:
@@ -2048,17 +2051,21 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
        return ret;
 }
 
-int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl)
+struct xt_table *ipt_register_table(struct net *net, struct xt_table *table,
+                                   const struct ipt_replace *repl)
 {
        int ret;
        struct xt_table_info *newinfo;
        struct xt_table_info bootstrap
                = { 0, 0, 0, { 0 }, { 0 }, { } };
        void *loc_cpu_entry;
+       struct xt_table *new_table;
 
        newinfo = xt_alloc_table_info(repl->size);
-       if (!newinfo)
-               return -ENOMEM;
+       if (!newinfo) {
+               ret = -ENOMEM;
+               goto out;
+       }
 
        /* choose the copy on our node/cpu, but dont care about preemption */
        loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
@@ -2069,30 +2076,36 @@ int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl)
                              repl->num_entries,
                              repl->hook_entry,
                              repl->underflow);
-       if (ret != 0) {
-               xt_free_table_info(newinfo);
-               return ret;
-       }
+       if (ret != 0)
+               goto out_free;
 
-       ret = xt_register_table(table, &bootstrap, newinfo);
-       if (ret != 0) {
-               xt_free_table_info(newinfo);
-               return ret;
+       new_table = xt_register_table(net, table, &bootstrap, newinfo);
+       if (IS_ERR(new_table)) {
+               ret = PTR_ERR(new_table);
+               goto out_free;
        }
 
-       return 0;
+       return new_table;
+
+out_free:
+       xt_free_table_info(newinfo);
+out:
+       return ERR_PTR(ret);
 }
 
 void ipt_unregister_table(struct xt_table *table)
 {
        struct xt_table_info *private;
        void *loc_cpu_entry;
+       struct module *table_owner = table->me;
 
        private = xt_unregister_table(table);
 
        /* Decrease module usage counts and free resources */
        loc_cpu_entry = private->entries[raw_smp_processor_id()];
        IPT_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL);
+       if (private->number > private->initial_entries)
+               module_put(table_owner);
        xt_free_table_info(private);
 }
 
@@ -2200,11 +2213,26 @@ static struct xt_match icmp_matchstruct __read_mostly = {
        .family         = AF_INET,
 };
 
+static int __net_init ip_tables_net_init(struct net *net)
+{
+       return xt_proto_init(net, AF_INET);
+}
+
+static void __net_exit ip_tables_net_exit(struct net *net)
+{
+       xt_proto_fini(net, AF_INET);
+}
+
+static struct pernet_operations ip_tables_net_ops = {
+       .init = ip_tables_net_init,
+       .exit = ip_tables_net_exit,
+};
+
 static int __init ip_tables_init(void)
 {
        int ret;
 
-       ret = xt_proto_init(AF_INET);
+       ret = register_pernet_subsys(&ip_tables_net_ops);
        if (ret < 0)
                goto err1;
 
@@ -2234,7 +2262,7 @@ err4:
 err3:
        xt_unregister_target(&ipt_standard_target);
 err2:
-       xt_proto_fini(AF_INET);
+       unregister_pernet_subsys(&ip_tables_net_ops);
 err1:
        return ret;
 }
@@ -2247,7 +2275,7 @@ static void __exit ip_tables_fini(void)
        xt_unregister_target(&ipt_error_target);
        xt_unregister_target(&ipt_standard_target);
 
-       xt_proto_fini(AF_INET);
+       unregister_pernet_subsys(&ip_tables_net_ops);
 }
 
 EXPORT_SYMBOL(ipt_register_table);
index 1b31f7d14d46b6c87de794f1cd4d4700c0a6ce1e..c6cf84c776116a6db394da69947547d20e324b17 100644 (file)
@@ -76,13 +76,6 @@ clusterip_config_put(struct clusterip_config *c)
                kfree(c);
 }
 
-/* increase the count of entries(rules) using/referencing this config */
-static inline void
-clusterip_config_entry_get(struct clusterip_config *c)
-{
-       atomic_inc(&c->entries);
-}
-
 /* decrease the count of entries using/referencing this config.  If last
  * entry(rule) is removed, remove the config from lists, but don't free it
  * yet, since proc-files could still be holding references */
index e3154a99c08ae9d975378b80684b8f361fd07839..68cbe3ca01ced13ea0cc77d7d3f6057fa63855d3 100644 (file)
@@ -212,11 +212,11 @@ recent_mt(const struct sk_buff *skb, const struct net_device *in,
                recent_entry_remove(t, e);
                ret = !ret;
        } else if (info->check_set & (IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) {
-               unsigned long t = jiffies - info->seconds * HZ;
+               unsigned long time = jiffies - info->seconds * HZ;
                unsigned int i, hits = 0;
 
                for (i = 0; i < e->nstamps; i++) {
-                       if (info->seconds && time_after(t, e->stamps[i]))
+                       if (info->seconds && time_after(time, e->stamps[i]))
                                continue;
                        if (++hits >= info->hit_count) {
                                ret = !ret;
@@ -320,6 +320,7 @@ struct recent_iter_state {
 };
 
 static void *recent_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(recent_lock)
 {
        struct recent_iter_state *st = seq->private;
        const struct recent_table *t = st->table;
@@ -352,6 +353,7 @@ static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void recent_seq_stop(struct seq_file *s, void *v)
+       __releases(recent_lock)
 {
        spin_unlock_bh(&recent_lock);
 }
index 29bb4f9fbda0f7f7d4fcc5cce744e557907f0e86..69f3d7e6e96f794a4cecd47c8896e473c3dd59df 100644 (file)
@@ -28,7 +28,7 @@ static struct
        struct ipt_replace repl;
        struct ipt_standard entries[3];
        struct ipt_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
        .repl = {
                .name = "filter",
                .valid_hooks = FILTER_VALID_HOOKS,
@@ -69,7 +69,7 @@ ipt_hook(unsigned int hook,
         const struct net_device *out,
         int (*okfn)(struct sk_buff *))
 {
-       return ipt_do_table(skb, hook, in, out, &packet_filter);
+       return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter);
 }
 
 static unsigned int
@@ -88,7 +88,7 @@ ipt_local_out_hook(unsigned int hook,
                return NF_ACCEPT;
        }
 
-       return ipt_do_table(skb, hook, in, out, &packet_filter);
+       return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter);
 }
 
 static struct nf_hook_ops ipt_ops[] __read_mostly = {
@@ -119,6 +119,26 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
 static int forward = NF_ACCEPT;
 module_param(forward, bool, 0000);
 
+static int __net_init iptable_filter_net_init(struct net *net)
+{
+       /* Register table */
+       net->ipv4.iptable_filter =
+               ipt_register_table(net, &packet_filter, &initial_table.repl);
+       if (IS_ERR(net->ipv4.iptable_filter))
+               return PTR_ERR(net->ipv4.iptable_filter);
+       return 0;
+}
+
+static void __net_exit iptable_filter_net_exit(struct net *net)
+{
+       ipt_unregister_table(net->ipv4.iptable_filter);
+}
+
+static struct pernet_operations iptable_filter_net_ops = {
+       .init = iptable_filter_net_init,
+       .exit = iptable_filter_net_exit,
+};
+
 static int __init iptable_filter_init(void)
 {
        int ret;
@@ -131,8 +151,7 @@ static int __init iptable_filter_init(void)
        /* Entry 1 is the FORWARD hook */
        initial_table.entries[1].target.verdict = -forward - 1;
 
-       /* Register table */
-       ret = ipt_register_table(&packet_filter, &initial_table.repl);
+       ret = register_pernet_subsys(&iptable_filter_net_ops);
        if (ret < 0)
                return ret;
 
@@ -144,14 +163,14 @@ static int __init iptable_filter_init(void)
        return ret;
 
  cleanup_table:
-       ipt_unregister_table(&packet_filter);
+       unregister_pernet_subsys(&iptable_filter_net_ops);
        return ret;
 }
 
 static void __exit iptable_filter_fini(void)
 {
        nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
-       ipt_unregister_table(&packet_filter);
+       unregister_pernet_subsys(&iptable_filter_net_ops);
 }
 
 module_init(iptable_filter_init);
index 5c4be202430c8b7dbcabea9306ae8989b8d29f1d..c55a210853a7a5e92d10cecf30dabe645a6355c3 100644 (file)
@@ -33,7 +33,7 @@ static struct
        struct ipt_replace repl;
        struct ipt_standard entries[5];
        struct ipt_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
        .repl = {
                .name = "mangle",
                .valid_hooks = MANGLE_VALID_HOOKS,
@@ -80,7 +80,7 @@ ipt_route_hook(unsigned int hook,
         const struct net_device *out,
         int (*okfn)(struct sk_buff *))
 {
-       return ipt_do_table(skb, hook, in, out, &packet_mangler);
+       return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle);
 }
 
 static unsigned int
@@ -112,7 +112,7 @@ ipt_local_hook(unsigned int hook,
        daddr = iph->daddr;
        tos = iph->tos;
 
-       ret = ipt_do_table(skb, hook, in, out, &packet_mangler);
+       ret = ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle);
        /* Reroute for ANY change. */
        if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) {
                iph = ip_hdr(skb);
@@ -166,12 +166,31 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
        },
 };
 
+static int __net_init iptable_mangle_net_init(struct net *net)
+{
+       /* Register table */
+       net->ipv4.iptable_mangle =
+               ipt_register_table(net, &packet_mangler, &initial_table.repl);
+       if (IS_ERR(net->ipv4.iptable_mangle))
+               return PTR_ERR(net->ipv4.iptable_mangle);
+       return 0;
+}
+
+static void __net_exit iptable_mangle_net_exit(struct net *net)
+{
+       ipt_unregister_table(net->ipv4.iptable_mangle);
+}
+
+static struct pernet_operations iptable_mangle_net_ops = {
+       .init = iptable_mangle_net_init,
+       .exit = iptable_mangle_net_exit,
+};
+
 static int __init iptable_mangle_init(void)
 {
        int ret;
 
-       /* Register table */
-       ret = ipt_register_table(&packet_mangler, &initial_table.repl);
+       ret = register_pernet_subsys(&iptable_mangle_net_ops);
        if (ret < 0)
                return ret;
 
@@ -183,14 +202,14 @@ static int __init iptable_mangle_init(void)
        return ret;
 
  cleanup_table:
-       ipt_unregister_table(&packet_mangler);
+       unregister_pernet_subsys(&iptable_mangle_net_ops);
        return ret;
 }
 
 static void __exit iptable_mangle_fini(void)
 {
        nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
-       ipt_unregister_table(&packet_mangler);
+       unregister_pernet_subsys(&iptable_mangle_net_ops);
 }
 
 module_init(iptable_mangle_init);
index dc34aa274533b8d5893fd6d4bd3642a003c19e28..e41fe8ca4e1c87b9538961411504e1e7777c27b3 100644 (file)
@@ -14,7 +14,7 @@ static struct
        struct ipt_replace repl;
        struct ipt_standard entries[2];
        struct ipt_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
        .repl = {
                .name = "raw",
                .valid_hooks = RAW_VALID_HOOKS,
@@ -52,7 +52,7 @@ ipt_hook(unsigned int hook,
         const struct net_device *out,
         int (*okfn)(struct sk_buff *))
 {
-       return ipt_do_table(skb, hook, in, out, &packet_raw);
+       return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw);
 }
 
 static unsigned int
@@ -70,7 +70,7 @@ ipt_local_hook(unsigned int hook,
                               "packet.\n");
                return NF_ACCEPT;
        }
-       return ipt_do_table(skb, hook, in, out, &packet_raw);
+       return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw);
 }
 
 /* 'raw' is the very first table. */
@@ -91,12 +91,31 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
        },
 };
 
+static int __net_init iptable_raw_net_init(struct net *net)
+{
+       /* Register table */
+       net->ipv4.iptable_raw =
+               ipt_register_table(net, &packet_raw, &initial_table.repl);
+       if (IS_ERR(net->ipv4.iptable_raw))
+               return PTR_ERR(net->ipv4.iptable_raw);
+       return 0;
+}
+
+static void __net_exit iptable_raw_net_exit(struct net *net)
+{
+       ipt_unregister_table(net->ipv4.iptable_raw);
+}
+
+static struct pernet_operations iptable_raw_net_ops = {
+       .init = iptable_raw_net_init,
+       .exit = iptable_raw_net_exit,
+};
+
 static int __init iptable_raw_init(void)
 {
        int ret;
 
-       /* Register table */
-       ret = ipt_register_table(&packet_raw, &initial_table.repl);
+       ret = register_pernet_subsys(&iptable_raw_net_ops);
        if (ret < 0)
                return ret;
 
@@ -108,14 +127,14 @@ static int __init iptable_raw_init(void)
        return ret;
 
  cleanup_table:
-       ipt_unregister_table(&packet_raw);
+       unregister_pernet_subsys(&iptable_raw_net_ops);
        return ret;
 }
 
 static void __exit iptable_raw_fini(void)
 {
        nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
-       ipt_unregister_table(&packet_raw);
+       unregister_pernet_subsys(&iptable_raw_net_ops);
 }
 
 module_init(iptable_raw_init);
index ac3d61d8026e2d6d0052b0ca2d30b20433224413..a65b845c5f1596ec5d7732b6d84508f1133eef3f 100644 (file)
@@ -27,7 +27,8 @@
 static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
                             struct nf_conntrack_tuple *tuple)
 {
-       __be32 _addrs[2], *ap;
+       const __be32 *ap;
+       __be32 _addrs[2];
        ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr),
                                sizeof(u_int32_t) * 2, _addrs);
        if (ap == NULL)
@@ -76,7 +77,8 @@ static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
 static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
                            unsigned int *dataoff, u_int8_t *protonum)
 {
-       struct iphdr _iph, *iph;
+       const struct iphdr *iph;
+       struct iphdr _iph;
 
        iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
        if (iph == NULL)
@@ -111,8 +113,8 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
 {
        struct nf_conn *ct;
        enum ip_conntrack_info ctinfo;
-       struct nf_conn_help *help;
-       struct nf_conntrack_helper *helper;
+       const struct nf_conn_help *help;
+       const struct nf_conntrack_helper *helper;
 
        /* This is where we call the helper: as the packet goes out. */
        ct = nf_ct_get(skb, &ctinfo);
@@ -299,8 +301,8 @@ static ctl_table ip_ct_sysctl_table[] = {
 static int
 getorigdst(struct sock *sk, int optval, void __user *user, int *len)
 {
-       struct inet_sock *inet = inet_sk(sk);
-       struct nf_conntrack_tuple_hash *h;
+       const struct inet_sock *inet = inet_sk(sk);
+       const struct nf_conntrack_tuple_hash *h;
        struct nf_conntrack_tuple tuple;
 
        NF_CT_TUPLE_U_BLANK(&tuple);
index 543c02b74c96be28532e1c30a01929cea0a70547..089252e82c01fb93b55efa15c0e7a7f74d36398d 100644 (file)
@@ -39,12 +39,14 @@ struct ct_iter_state {
 static struct hlist_node *ct_get_first(struct seq_file *seq)
 {
        struct ct_iter_state *st = seq->private;
+       struct hlist_node *n;
 
        for (st->bucket = 0;
             st->bucket < nf_conntrack_htable_size;
             st->bucket++) {
-               if (!hlist_empty(&nf_conntrack_hash[st->bucket]))
-                       return nf_conntrack_hash[st->bucket].first;
+               n = rcu_dereference(nf_conntrack_hash[st->bucket].first);
+               if (n)
+                       return n;
        }
        return NULL;
 }
@@ -54,11 +56,11 @@ static struct hlist_node *ct_get_next(struct seq_file *seq,
 {
        struct ct_iter_state *st = seq->private;
 
-       head = head->next;
+       head = rcu_dereference(head->next);
        while (head == NULL) {
                if (++st->bucket >= nf_conntrack_htable_size)
                        return NULL;
-               head = nf_conntrack_hash[st->bucket].first;
+               head = rcu_dereference(nf_conntrack_hash[st->bucket].first);
        }
        return head;
 }
@@ -74,8 +76,9 @@ static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(RCU)
 {
-       read_lock_bh(&nf_conntrack_lock);
+       rcu_read_lock();
        return ct_get_idx(seq, *pos);
 }
 
@@ -86,16 +89,17 @@ static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
 }
 
 static void ct_seq_stop(struct seq_file *s, void *v)
+       __releases(RCU)
 {
-       read_unlock_bh(&nf_conntrack_lock);
+       rcu_read_unlock();
 }
 
 static int ct_seq_show(struct seq_file *s, void *v)
 {
        const struct nf_conntrack_tuple_hash *hash = v;
        const struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
-       struct nf_conntrack_l3proto *l3proto;
-       struct nf_conntrack_l4proto *l4proto;
+       const struct nf_conntrack_l3proto *l3proto;
+       const struct nf_conntrack_l4proto *l4proto;
 
        NF_CT_ASSERT(ct);
 
@@ -191,10 +195,12 @@ struct ct_expect_iter_state {
 static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
 {
        struct ct_expect_iter_state *st = seq->private;
+       struct hlist_node *n;
 
        for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
-               if (!hlist_empty(&nf_ct_expect_hash[st->bucket]))
-                       return nf_ct_expect_hash[st->bucket].first;
+               n = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
+               if (n)
+                       return n;
        }
        return NULL;
 }
@@ -204,11 +210,11 @@ static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
 {
        struct ct_expect_iter_state *st = seq->private;
 
-       head = head->next;
+       head = rcu_dereference(head->next);
        while (head == NULL) {
                if (++st->bucket >= nf_ct_expect_hsize)
                        return NULL;
-               head = nf_ct_expect_hash[st->bucket].first;
+               head = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
        }
        return head;
 }
@@ -224,8 +230,9 @@ static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(RCU)
 {
-       read_lock_bh(&nf_conntrack_lock);
+       rcu_read_lock();
        return ct_expect_get_idx(seq, *pos);
 }
 
@@ -236,14 +243,15 @@ static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void exp_seq_stop(struct seq_file *seq, void *v)
+       __releases(RCU)
 {
-       read_unlock_bh(&nf_conntrack_lock);
+       rcu_read_unlock();
 }
 
 static int exp_seq_show(struct seq_file *s, void *v)
 {
        struct nf_conntrack_expect *exp;
-       struct hlist_node *n = v;
+       const struct hlist_node *n = v;
 
        exp = hlist_entry(n, struct nf_conntrack_expect, hnode);
 
@@ -324,7 +332,7 @@ static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
 static int ct_cpu_seq_show(struct seq_file *seq, void *v)
 {
        unsigned int nr_conntracks = atomic_read(&nf_conntrack_count);
-       struct ip_conntrack_stat *st = v;
+       const struct ip_conntrack_stat *st = v;
 
        if (v == SEQ_START_TOKEN) {
                seq_printf(seq, "entries  searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error  expect_new expect_create expect_delete\n");
index 4004a04c551014205886bc3768523a77f2ccdd2b..6873fddb3529936a9ef7af490573eb9dc9aec45f 100644 (file)
@@ -26,7 +26,8 @@ static int icmp_pkt_to_tuple(const struct sk_buff *skb,
                             unsigned int dataoff,
                             struct nf_conntrack_tuple *tuple)
 {
-       struct icmphdr _hdr, *hp;
+       const struct icmphdr *hp;
+       struct icmphdr _hdr;
 
        hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
        if (hp == NULL)
@@ -100,7 +101,7 @@ static int icmp_packet(struct nf_conn *ct,
 }
 
 /* Called when a new connection for this protocol found. */
-static int icmp_new(struct nf_conn *conntrack,
+static int icmp_new(struct nf_conn *ct,
                    const struct sk_buff *skb, unsigned int dataoff)
 {
        static const u_int8_t valid_new[] = {
@@ -110,15 +111,15 @@ static int icmp_new(struct nf_conn *conntrack,
                [ICMP_ADDRESS] = 1
        };
 
-       if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
-           || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
+       if (ct->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
+           || !valid_new[ct->tuplehash[0].tuple.dst.u.icmp.type]) {
                /* Can't create a new ICMP `conn' with this. */
                pr_debug("icmp: can't create new conn with type %u\n",
-                        conntrack->tuplehash[0].tuple.dst.u.icmp.type);
-               NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
+                        ct->tuplehash[0].tuple.dst.u.icmp.type);
+               NF_CT_DUMP_TUPLE(&ct->tuplehash[0].tuple);
                return 0;
        }
-       atomic_set(&conntrack->proto.icmp.count, 0);
+       atomic_set(&ct->proto.icmp.count, 0);
        return 1;
 }
 
@@ -129,8 +130,8 @@ icmp_error_message(struct sk_buff *skb,
                 unsigned int hooknum)
 {
        struct nf_conntrack_tuple innertuple, origtuple;
-       struct nf_conntrack_l4proto *innerproto;
-       struct nf_conntrack_tuple_hash *h;
+       const struct nf_conntrack_l4proto *innerproto;
+       const struct nf_conntrack_tuple_hash *h;
 
        NF_CT_ASSERT(skb->nfct == NULL);
 
@@ -176,7 +177,8 @@ static int
 icmp_error(struct sk_buff *skb, unsigned int dataoff,
           enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
 {
-       struct icmphdr _ih, *icmph;
+       const struct icmphdr *icmph;
+       struct icmphdr _ih;
 
        /* Not enough header? */
        icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih);
index e53ae1ef8f5e1f0dae45e5d191b079c681a0dcb3..dd07362d2b8f42e5303419d509a0a1136e51cd42 100644 (file)
@@ -31,7 +31,7 @@
 #include <net/netfilter/nf_conntrack_l3proto.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 
-static DEFINE_RWLOCK(nf_nat_lock);
+static DEFINE_SPINLOCK(nf_nat_lock);
 
 static struct nf_conntrack_l3proto *l3proto __read_mostly;
 
@@ -154,8 +154,8 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple,
        struct nf_conn *ct;
        struct hlist_node *n;
 
-       read_lock_bh(&nf_nat_lock);
-       hlist_for_each_entry(nat, n, &bysource[h], bysource) {
+       rcu_read_lock();
+       hlist_for_each_entry_rcu(nat, n, &bysource[h], bysource) {
                ct = nat->ct;
                if (same_src(ct, tuple)) {
                        /* Copy source part from reply tuple. */
@@ -164,12 +164,12 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple,
                        result->dst = tuple->dst;
 
                        if (in_range(result, range)) {
-                               read_unlock_bh(&nf_nat_lock);
+                               rcu_read_unlock();
                                return 1;
                        }
                }
        }
-       read_unlock_bh(&nf_nat_lock);
+       rcu_read_unlock();
        return 0;
 }
 
@@ -330,12 +330,12 @@ nf_nat_setup_info(struct nf_conn *ct,
                unsigned int srchash;
 
                srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
-               write_lock_bh(&nf_nat_lock);
+               spin_lock_bh(&nf_nat_lock);
                /* nf_conntrack_alter_reply might re-allocate exntension aera */
                nat = nfct_nat(ct);
                nat->ct = ct;
-               hlist_add_head(&nat->bysource, &bysource[srchash]);
-               write_unlock_bh(&nf_nat_lock);
+               hlist_add_head_rcu(&nat->bysource, &bysource[srchash]);
+               spin_unlock_bh(&nf_nat_lock);
        }
 
        /* It's done. */
@@ -521,14 +521,14 @@ int nf_nat_protocol_register(const struct nf_nat_protocol *proto)
 {
        int ret = 0;
 
-       write_lock_bh(&nf_nat_lock);
+       spin_lock_bh(&nf_nat_lock);
        if (nf_nat_protos[proto->protonum] != &nf_nat_unknown_protocol) {
                ret = -EBUSY;
                goto out;
        }
        rcu_assign_pointer(nf_nat_protos[proto->protonum], proto);
  out:
-       write_unlock_bh(&nf_nat_lock);
+       spin_unlock_bh(&nf_nat_lock);
        return ret;
 }
 EXPORT_SYMBOL(nf_nat_protocol_register);
@@ -536,10 +536,10 @@ EXPORT_SYMBOL(nf_nat_protocol_register);
 /* Noone stores the protocol anywhere; simply delete it. */
 void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto)
 {
-       write_lock_bh(&nf_nat_lock);
+       spin_lock_bh(&nf_nat_lock);
        rcu_assign_pointer(nf_nat_protos[proto->protonum],
                           &nf_nat_unknown_protocol);
-       write_unlock_bh(&nf_nat_lock);
+       spin_unlock_bh(&nf_nat_lock);
        synchronize_rcu();
 }
 EXPORT_SYMBOL(nf_nat_protocol_unregister);
@@ -594,10 +594,10 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
 
        NF_CT_ASSERT(nat->ct->status & IPS_NAT_DONE_MASK);
 
-       write_lock_bh(&nf_nat_lock);
-       hlist_del(&nat->bysource);
+       spin_lock_bh(&nf_nat_lock);
+       hlist_del_rcu(&nat->bysource);
        nat->ct = NULL;
-       write_unlock_bh(&nf_nat_lock);
+       spin_unlock_bh(&nf_nat_lock);
 }
 
 static void nf_nat_move_storage(struct nf_conn *conntrack, void *old)
@@ -609,10 +609,10 @@ static void nf_nat_move_storage(struct nf_conn *conntrack, void *old)
        if (!ct || !(ct->status & IPS_NAT_DONE_MASK))
                return;
 
-       write_lock_bh(&nf_nat_lock);
+       spin_lock_bh(&nf_nat_lock);
        hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource);
        new_nat->ct = ct;
-       write_unlock_bh(&nf_nat_lock);
+       spin_unlock_bh(&nf_nat_lock);
 }
 
 static struct nf_ct_ext_type nat_extend __read_mostly = {
@@ -646,17 +646,13 @@ static int __init nf_nat_init(void)
        }
 
        /* Sew in builtin protocols. */
-       write_lock_bh(&nf_nat_lock);
+       spin_lock_bh(&nf_nat_lock);
        for (i = 0; i < MAX_IP_NAT_PROTO; i++)
                rcu_assign_pointer(nf_nat_protos[i], &nf_nat_unknown_protocol);
        rcu_assign_pointer(nf_nat_protos[IPPROTO_TCP], &nf_nat_protocol_tcp);
        rcu_assign_pointer(nf_nat_protos[IPPROTO_UDP], &nf_nat_protocol_udp);
        rcu_assign_pointer(nf_nat_protos[IPPROTO_ICMP], &nf_nat_protocol_icmp);
-       write_unlock_bh(&nf_nat_lock);
-
-       for (i = 0; i < nf_nat_htable_size; i++) {
-               INIT_HLIST_HEAD(&bysource[i]);
-       }
+       spin_unlock_bh(&nf_nat_lock);
 
        /* Initialize fake conntrack so that NAT will skip it */
        nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK;
index a121989fdad7c5c38363fe77d447c43dc07038b5..ee47bf28c82547463629288cc16249bcceb1e20c 100644 (file)
@@ -32,7 +32,8 @@ static int set_addr(struct sk_buff *skb,
                __be32 ip;
                __be16 port;
        } __attribute__ ((__packed__)) buf;
-       struct tcphdr _tcph, *th;
+       const struct tcphdr *th;
+       struct tcphdr _tcph;
 
        buf.ip = ip;
        buf.port = port;
@@ -99,7 +100,7 @@ static int set_sig_addr(struct sk_buff *skb, struct nf_conn *ct,
                        unsigned char **data,
                        TransportAddress *taddr, int count)
 {
-       struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
+       const struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
        int dir = CTINFO2DIR(ctinfo);
        int i;
        __be16 port;
index 4c0232842e75408759a7a6324c3a2a4ea3452b1e..ca57f47bbd255b14f2a6fd9d8c6b04a7918a3ab5 100644 (file)
@@ -44,8 +44,7 @@ adjust_tcp_sequence(u32 seq,
        struct nf_nat_seq *this_way, *other_way;
        struct nf_conn_nat *nat = nfct_nat(ct);
 
-       pr_debug("adjust_tcp_sequence: seq = %u, sizediff = %d\n",
-                ntohl(seq), seq);
+       pr_debug("adjust_tcp_sequence: seq = %u, sizediff = %d\n", seq, seq);
 
        dir = CTINFO2DIR(ctinfo);
 
index e63b944a2ebbd85a03f8ed5cdb4e3ba810ea0efb..3a1e6d6afc0af3d8d2a7fda4cfc4a9e7bf290994 100644 (file)
@@ -40,11 +40,11 @@ MODULE_ALIAS("ip_nat_pptp");
 static void pptp_nat_expected(struct nf_conn *ct,
                              struct nf_conntrack_expect *exp)
 {
-       struct nf_conn *master = ct->master;
+       const struct nf_conn *master = ct->master;
        struct nf_conntrack_expect *other_exp;
        struct nf_conntrack_tuple t;
-       struct nf_ct_pptp_master *ct_pptp_info;
-       struct nf_nat_pptp *nat_pptp_info;
+       const struct nf_ct_pptp_master *ct_pptp_info;
+       const struct nf_nat_pptp *nat_pptp_info;
        struct nf_nat_range range;
 
        ct_pptp_info = &nfct_help(master)->help.ct_pptp_info;
@@ -186,7 +186,7 @@ static void
 pptp_exp_gre(struct nf_conntrack_expect *expect_orig,
             struct nf_conntrack_expect *expect_reply)
 {
-       struct nf_conn *ct = expect_orig->master;
+       const struct nf_conn *ct = expect_orig->master;
        struct nf_ct_pptp_master *ct_pptp_info;
        struct nf_nat_pptp *nat_pptp_info;
 
@@ -217,7 +217,7 @@ pptp_inbound_pkt(struct sk_buff *skb,
                 struct PptpControlHeader *ctlh,
                 union pptp_ctrl_union *pptpReq)
 {
-       struct nf_nat_pptp *nat_pptp_info;
+       const struct nf_nat_pptp *nat_pptp_info;
        u_int16_t msg;
        __be16 new_pcid;
        unsigned int pcid_off;
index 9fa272e73113f6bdda3e8908677b76169ca63201..a1e4da16da2e8a411fc39b6009c4b4f1151d0a09 100644 (file)
@@ -59,7 +59,7 @@ static int
 gre_unique_tuple(struct nf_conntrack_tuple *tuple,
                 const struct nf_nat_range *range,
                 enum nf_nat_manip_type maniptype,
-                const struct nf_conn *conntrack)
+                const struct nf_conn *ct)
 {
        static u_int16_t key;
        __be16 *keyptr;
@@ -67,7 +67,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
 
        /* If there is no master conntrack we are not PPTP,
           do not change tuples */
-       if (!conntrack->master)
+       if (!ct->master)
                return 0;
 
        if (maniptype == IP_NAT_MANIP_SRC)
@@ -76,7 +76,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
                keyptr = &tuple->dst.u.gre.key;
 
        if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
-               pr_debug("%p: NATing GRE PPTP\n", conntrack);
+               pr_debug("%p: NATing GRE PPTP\n", ct);
                min = 1;
                range_size = 0xffff;
        } else {
@@ -88,11 +88,11 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
 
        for (i = 0; i < range_size; i++, key++) {
                *keyptr = htons(min + key % range_size);
-               if (!nf_nat_used_tuple(tuple, conntrack))
+               if (!nf_nat_used_tuple(tuple, ct))
                        return 1;
        }
 
-       pr_debug("%p: no NAT mapping\n", conntrack);
+       pr_debug("%p: no NAT mapping\n", ct);
        return 0;
 }
 
@@ -104,7 +104,7 @@ gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
 {
        struct gre_hdr *greh;
        struct gre_hdr_pptp *pgreh;
-       struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
+       const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
        unsigned int hdroff = iphdroff + iph->ihl * 4;
 
        /* pgreh includes two optional 32bit fields which are not required
@@ -148,12 +148,12 @@ static const struct nf_nat_protocol gre = {
 #endif
 };
 
-int __init nf_nat_proto_gre_init(void)
+static int __init nf_nat_proto_gre_init(void)
 {
        return nf_nat_protocol_register(&gre);
 }
 
-void __exit nf_nat_proto_gre_fini(void)
+static void __exit nf_nat_proto_gre_fini(void)
 {
        nf_nat_protocol_unregister(&gre);
 }
index a0e44c953cb6352248a6fa89e3eddc7846b0ec86..03a02969aa5710fde9a897a2d913396b17b94bee 100644 (file)
@@ -57,7 +57,7 @@ icmp_manip_pkt(struct sk_buff *skb,
               const struct nf_conntrack_tuple *tuple,
               enum nf_nat_manip_type maniptype)
 {
-       struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
+       const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
        struct icmphdr *hdr;
        unsigned int hdroff = iphdroff + iph->ihl*4;
 
index da23e9fbe6790b9ba957cb98b8b7d36e14b65fad..ffd5d1589eca55bfd167f452ba0a3eb5efc9926a 100644 (file)
@@ -93,7 +93,7 @@ tcp_manip_pkt(struct sk_buff *skb,
              const struct nf_conntrack_tuple *tuple,
              enum nf_nat_manip_type maniptype)
 {
-       struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
+       const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
        struct tcphdr *hdr;
        unsigned int hdroff = iphdroff + iph->ihl*4;
        __be32 oldip, newip;
index 10df4db078afd1693b62d95faa2aa2f848bee815..4b8f49910ff2cb112cd80030ef5e8112d3fa70cc 100644 (file)
@@ -91,7 +91,7 @@ udp_manip_pkt(struct sk_buff *skb,
              const struct nf_conntrack_tuple *tuple,
              enum nf_nat_manip_type maniptype)
 {
-       struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
+       const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
        struct udphdr *hdr;
        unsigned int hdroff = iphdroff + iph->ihl*4;
        __be32 oldip, newip;
index 519182269e76d1418c0ef6830b073c330e7e4dcc..f8fda57ba20b6bc92ed0753da70ca72ef73fc555 100644 (file)
@@ -58,13 +58,14 @@ static struct
        .term = IPT_ERROR_INIT,                 /* ERROR */
 };
 
-static struct xt_table nat_table = {
+static struct xt_table __nat_table = {
        .name           = "nat",
        .valid_hooks    = NAT_VALID_HOOKS,
        .lock           = RW_LOCK_UNLOCKED,
        .me             = THIS_MODULE,
        .af             = AF_INET,
 };
+static struct xt_table *nat_table;
 
 /* Source NAT */
 static unsigned int ipt_snat_target(struct sk_buff *skb,
@@ -214,7 +215,7 @@ int nf_nat_rule_find(struct sk_buff *skb,
 {
        int ret;
 
-       ret = ipt_do_table(skb, hooknum, in, out, &nat_table);
+       ret = ipt_do_table(skb, hooknum, in, out, nat_table);
 
        if (ret == NF_ACCEPT) {
                if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
@@ -248,9 +249,10 @@ int __init nf_nat_rule_init(void)
 {
        int ret;
 
-       ret = ipt_register_table(&nat_table, &nat_initial_table.repl);
-       if (ret != 0)
-               return ret;
+       nat_table = ipt_register_table(&init_net, &__nat_table,
+                                      &nat_initial_table.repl);
+       if (IS_ERR(nat_table))
+               return PTR_ERR(nat_table);
        ret = xt_register_target(&ipt_snat_reg);
        if (ret != 0)
                goto unregister_table;
@@ -264,7 +266,7 @@ int __init nf_nat_rule_init(void)
  unregister_snat:
        xt_unregister_target(&ipt_snat_reg);
  unregister_table:
-       ipt_unregister_table(&nat_table);
+       ipt_unregister_table(nat_table);
 
        return ret;
 }
@@ -273,5 +275,5 @@ void nf_nat_rule_cleanup(void)
 {
        xt_unregister_target(&ipt_dnat_reg);
        xt_unregister_target(&ipt_snat_reg);
-       ipt_unregister_table(&nat_table);
+       ipt_unregister_table(nat_table);
 }
index 606a170bf4cae443895733f5401d82926996743e..b4c8d4968bb2f5ad52aa0446e4aeab51d8b98756 100644 (file)
@@ -35,9 +35,9 @@ struct addr_map {
        } addr[IP_CT_DIR_MAX];
 };
 
-static void addr_map_init(struct nf_conn *ct, struct addr_map *map)
+static void addr_map_init(const struct nf_conn *ct, struct addr_map *map)
 {
-       struct nf_conntrack_tuple *t;
+       const struct nf_conntrack_tuple *t;
        enum ip_conntrack_dir dir;
        unsigned int n;
 
index 07f2a49926d4ae1c5ffe6227e0058ff3b19dff05..540ce6ae887c0a797f8db68cb99a0be8c69c98ac 100644 (file)
@@ -260,7 +260,7 @@ static unsigned char asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc)
 {
        unsigned char ch;
 
-       if (eoc == 0) {
+       if (eoc == NULL) {
                if (!asn1_octet_decode(ctx, &ch))
                        return 0;
 
index 1360a94766dd6321d7f1a07d719d88adce5a44f1..b096e81500aea2b86ffa6a2e0111d94307edf2a9 100644 (file)
@@ -24,7 +24,7 @@ static unsigned int help(struct sk_buff *skb,
                         enum ip_conntrack_info ctinfo,
                         struct nf_conntrack_expect *exp)
 {
-       struct nf_conn *ct = exp->master;
+       const struct nf_conn *ct = exp->master;
 
        exp->saved_proto.udp.port
                = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
index 85c08696abbe40b4a38de040fe59788a5ff4138e..a3002fe65b7f4a345c1333c4d7f36392bee3b172 100644 (file)
@@ -352,6 +352,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
        skb_reserve(skb, hh_len);
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
        skb->dst = dst_clone(&rt->u.dst);
 
        skb_reset_network_header(skb);
@@ -544,6 +545,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 
        {
                struct flowi fl = { .oif = ipc.oif,
+                                   .mark = sk->sk_mark,
                                    .nl_u = { .ip4_u =
                                              { .daddr = daddr,
                                                .saddr = saddr,
@@ -860,8 +862,7 @@ static struct sock *raw_get_first(struct seq_file *seq)
                struct hlist_node *node;
 
                sk_for_each(sk, node, &state->h->ht[state->bucket])
-                       if (sk->sk_net == state->p.net &&
-                                       sk->sk_family == state->family)
+                       if (sk->sk_net == state->p.net)
                                goto found;
        }
        sk = NULL;
@@ -877,8 +878,7 @@ static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk)
                sk = sk_next(sk);
 try_again:
                ;
-       } while (sk && sk->sk_net != state->p.net &&
-                       sk->sk_family != state->family);
+       } while (sk && sk->sk_net != state->p.net);
 
        if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
                sk = sk_head(&state->h->ht[state->bucket]);
@@ -927,7 +927,7 @@ void raw_seq_stop(struct seq_file *seq, void *v)
 }
 EXPORT_SYMBOL_GPL(raw_seq_stop);
 
-static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i)
+static void raw_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
 {
        struct inet_sock *inet = inet_sk(sp);
        __be32 dest = inet->daddr,
@@ -935,33 +935,23 @@ static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i)
        __u16 destp = 0,
              srcp  = inet->num;
 
-       sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
+       seq_printf(seq, "%4d: %08X:%04X %08X:%04X"
                " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d",
                i, src, srcp, dest, destp, sp->sk_state,
                atomic_read(&sp->sk_wmem_alloc),
                atomic_read(&sp->sk_rmem_alloc),
                0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
                atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
-       return tmpbuf;
 }
 
-#define TMPSZ 128
-
 static int raw_seq_show(struct seq_file *seq, void *v)
 {
-       char tmpbuf[TMPSZ+1];
-
        if (v == SEQ_START_TOKEN)
-               seq_printf(seq, "%-*s\n", TMPSZ-1,
-                              "  sl  local_address rem_address   st tx_queue "
-                              "rx_queue tr tm->when retrnsmt   uid  timeout "
-                              "inode  drops");
-       else {
-               struct raw_iter_state *state = raw_seq_private(seq);
-
-               seq_printf(seq, "%-*s\n", TMPSZ-1,
-                          get_raw_sock(v, tmpbuf, state->bucket));
-       }
+               seq_printf(seq, "  sl  local_address rem_address   st tx_queue "
+                               "rx_queue tr tm->when retrnsmt   uid  timeout "
+                               "inode  drops\n");
+       else
+               raw_sock_seq_show(seq, v, raw_seq_private(seq)->bucket);
        return 0;
 }
 
@@ -972,27 +962,25 @@ static const struct seq_operations raw_seq_ops = {
        .show  = raw_seq_show,
 };
 
-int raw_seq_open(struct inode *ino, struct file *file, struct raw_hashinfo *h,
-               unsigned short family)
+int raw_seq_open(struct inode *ino, struct file *file,
+                struct raw_hashinfo *h, const struct seq_operations *ops)
 {
        int err;
        struct raw_iter_state *i;
 
-       err = seq_open_net(ino, file, &raw_seq_ops,
-                       sizeof(struct raw_iter_state));
+       err = seq_open_net(ino, file, ops, sizeof(struct raw_iter_state));
        if (err < 0)
                return err;
 
        i = raw_seq_private((struct seq_file *)file->private_data);
        i->h = h;
-       i->family = family;
        return 0;
 }
 EXPORT_SYMBOL_GPL(raw_seq_open);
 
 static int raw_v4_seq_open(struct inode *inode, struct file *file)
 {
-       return raw_seq_open(inode, file, &raw_v4_hashinfo, PF_INET);
+       return raw_seq_open(inode, file, &raw_v4_hashinfo, &raw_seq_ops);
 }
 
 static const struct file_operations raw_seq_fops = {
index 896c768e41a2d90baef4b4a3783be0164678ff9e..8842ecb9be484e279a603053912c0f850b4eb11b 100644 (file)
 
 #define RT_GC_TIMEOUT (300*HZ)
 
-static int ip_rt_min_delay             = 2 * HZ;
-static int ip_rt_max_delay             = 10 * HZ;
 static int ip_rt_max_size;
 static int ip_rt_gc_timeout            = RT_GC_TIMEOUT;
 static int ip_rt_gc_interval           = 60 * HZ;
@@ -133,12 +131,9 @@ static int ip_rt_mtu_expires               = 10 * 60 * HZ;
 static int ip_rt_min_pmtu              = 512 + 20 + 20;
 static int ip_rt_min_advmss            = 256;
 static int ip_rt_secret_interval       = 10 * 60 * HZ;
-static int ip_rt_flush_expected;
-static unsigned long rt_deadline;
 
 #define RTprint(a...)  printk(KERN_DEBUG a)
 
-static struct timer_list rt_flush_timer;
 static void rt_worker_func(struct work_struct *work);
 static DECLARE_DELAYED_WORK(expires_work, rt_worker_func);
 static struct timer_list rt_secret_timer;
@@ -169,6 +164,7 @@ static struct dst_ops ipv4_dst_ops = {
        .update_pmtu =          ip_rt_update_pmtu,
        .local_out =            ip_local_out,
        .entry_size =           sizeof(struct rtable),
+       .entries =              ATOMIC_INIT(0),
 };
 
 #define ECN_OR_COST(class)     TC_PRIO_##class
@@ -259,19 +255,16 @@ static inline void rt_hash_lock_init(void)
 static struct rt_hash_bucket   *rt_hash_table;
 static unsigned                        rt_hash_mask;
 static unsigned int            rt_hash_log;
-static unsigned int            rt_hash_rnd;
+static atomic_t                        rt_genid;
 
 static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
 #define RT_CACHE_STAT_INC(field) \
        (__raw_get_cpu_var(rt_cache_stat).field++)
 
-static int rt_intern_hash(unsigned hash, struct rtable *rth,
-                               struct rtable **res);
-
 static unsigned int rt_hash_code(u32 daddr, u32 saddr)
 {
-       return (jhash_2words(daddr, saddr, rt_hash_rnd)
-               & rt_hash_mask);
+       return jhash_2words(daddr, saddr, atomic_read(&rt_genid))
+               & rt_hash_mask;
 }
 
 #define rt_hash(daddr, saddr, idx) \
@@ -281,27 +274,28 @@ static unsigned int rt_hash_code(u32 daddr, u32 saddr)
 #ifdef CONFIG_PROC_FS
 struct rt_cache_iter_state {
        int bucket;
+       int genid;
 };
 
-static struct rtable *rt_cache_get_first(struct seq_file *seq)
+static struct rtable *rt_cache_get_first(struct rt_cache_iter_state *st)
 {
        struct rtable *r = NULL;
-       struct rt_cache_iter_state *st = seq->private;
 
        for (st->bucket = rt_hash_mask; st->bucket >= 0; --st->bucket) {
                rcu_read_lock_bh();
-               r = rt_hash_table[st->bucket].chain;
-               if (r)
-                       break;
+               r = rcu_dereference(rt_hash_table[st->bucket].chain);
+               while (r) {
+                       if (r->rt_genid == st->genid)
+                               return r;
+                       r = rcu_dereference(r->u.dst.rt_next);
+               }
                rcu_read_unlock_bh();
        }
-       return rcu_dereference(r);
+       return r;
 }
 
-static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r)
+static struct rtable *rt_cache_get_next(struct rt_cache_iter_state *st, struct rtable *r)
 {
-       struct rt_cache_iter_state *st = seq->private;
-
        r = r->u.dst.rt_next;
        while (!r) {
                rcu_read_unlock_bh();
@@ -313,29 +307,38 @@ static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r)
        return rcu_dereference(r);
 }
 
-static struct rtable *rt_cache_get_idx(struct seq_file *seq, loff_t pos)
+static struct rtable *rt_cache_get_idx(struct rt_cache_iter_state *st, loff_t pos)
 {
-       struct rtable *r = rt_cache_get_first(seq);
+       struct rtable *r = rt_cache_get_first(st);
 
        if (r)
-               while (pos && (r = rt_cache_get_next(seq, r)))
+               while (pos && (r = rt_cache_get_next(st, r))) {
+                       if (r->rt_genid != st->genid)
+                               continue;
                        --pos;
+               }
        return pos ? NULL : r;
 }
 
 static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
 {
-       return *pos ? rt_cache_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+       struct rt_cache_iter_state *st = seq->private;
+
+       if (*pos)
+               return rt_cache_get_idx(st, *pos - 1);
+       st->genid = atomic_read(&rt_genid);
+       return SEQ_START_TOKEN;
 }
 
 static void *rt_cache_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-       struct rtable *r = NULL;
+       struct rtable *r;
+       struct rt_cache_iter_state *st = seq->private;
 
        if (v == SEQ_START_TOKEN)
-               r = rt_cache_get_first(seq);
+               r = rt_cache_get_first(st);
        else
-               r = rt_cache_get_next(seq, v);
+               r = rt_cache_get_next(st, v);
        ++*pos;
        return r;
 }
@@ -708,6 +711,11 @@ static void rt_check_expire(void)
                        continue;
                spin_lock_bh(rt_hash_lock_addr(i));
                while ((rth = *rthp) != NULL) {
+                       if (rth->rt_genid != atomic_read(&rt_genid)) {
+                               *rthp = rth->u.dst.rt_next;
+                               rt_free(rth);
+                               continue;
+                       }
                        if (rth->u.dst.expires) {
                                /* Entry is expired even if it is in use */
                                if (time_before_eq(jiffies, rth->u.dst.expires)) {
@@ -732,83 +740,45 @@ static void rt_check_expire(void)
 
 /*
  * rt_worker_func() is run in process context.
- * If a whole flush was scheduled, it is done.
- * Else, we call rt_check_expire() to scan part of the hash table
+ * we call rt_check_expire() to scan part of the hash table
  */
 static void rt_worker_func(struct work_struct *work)
 {
-       if (ip_rt_flush_expected) {
-               ip_rt_flush_expected = 0;
-               rt_do_flush(1);
-       } else
-               rt_check_expire();
+       rt_check_expire();
        schedule_delayed_work(&expires_work, ip_rt_gc_interval);
 }
 
-/* This can run from both BH and non-BH contexts, the latter
- * in the case of a forced flush event.
+/*
+ * Pertubation of rt_genid by a small quantity [1..256]
+ * Using 8 bits of shuffling ensure we can call rt_cache_invalidate()
+ * many times (2^24) without giving recent rt_genid.
+ * Jenkins hash is strong enough that litle changes of rt_genid are OK.
  */
-static void rt_run_flush(unsigned long process_context)
+static void rt_cache_invalidate(void)
 {
-       rt_deadline = 0;
-
-       get_random_bytes(&rt_hash_rnd, 4);
+       unsigned char shuffle;
 
-       rt_do_flush(process_context);
+       get_random_bytes(&shuffle, sizeof(shuffle));
+       atomic_add(shuffle + 1U, &rt_genid);
 }
 
-static DEFINE_SPINLOCK(rt_flush_lock);
-
+/*
+ * delay < 0  : invalidate cache (fast : entries will be deleted later)
+ * delay >= 0 : invalidate & flush cache (can be long)
+ */
 void rt_cache_flush(int delay)
 {
-       unsigned long now = jiffies;
-       int user_mode = !in_softirq();
-
-       if (delay < 0)
-               delay = ip_rt_min_delay;
-
-       spin_lock_bh(&rt_flush_lock);
-
-       if (del_timer(&rt_flush_timer) && delay > 0 && rt_deadline) {
-               long tmo = (long)(rt_deadline - now);
-
-               /* If flush timer is already running
-                  and flush request is not immediate (delay > 0):
-
-                  if deadline is not achieved, prolongate timer to "delay",
-                  otherwise fire it at deadline time.
-                */
-
-               if (user_mode && tmo < ip_rt_max_delay-ip_rt_min_delay)
-                       tmo = 0;
-
-               if (delay > tmo)
-                       delay = tmo;
-       }
-
-       if (delay <= 0) {
-               spin_unlock_bh(&rt_flush_lock);
-               rt_run_flush(user_mode);
-               return;
-       }
-
-       if (rt_deadline == 0)
-               rt_deadline = now + ip_rt_max_delay;
-
-       mod_timer(&rt_flush_timer, now+delay);
-       spin_unlock_bh(&rt_flush_lock);
+       rt_cache_invalidate();
+       if (delay >= 0)
+               rt_do_flush(!in_softirq());
 }
 
 /*
- * We change rt_hash_rnd and ask next rt_worker_func() invocation
- * to perform a flush in process context
+ * We change rt_genid and let gc do the cleanup
  */
 static void rt_secret_rebuild(unsigned long dummy)
 {
-       get_random_bytes(&rt_hash_rnd, 4);
-       ip_rt_flush_expected = 1;
-       cancel_delayed_work(&expires_work);
-       schedule_delayed_work(&expires_work, HZ/10);
+       rt_cache_invalidate();
        mod_timer(&rt_secret_timer, jiffies + ip_rt_secret_interval);
 }
 
@@ -885,7 +855,8 @@ static int rt_garbage_collect(struct dst_ops *ops)
                        rthp = &rt_hash_table[k].chain;
                        spin_lock_bh(rt_hash_lock_addr(k));
                        while ((rth = *rthp) != NULL) {
-                               if (!rt_may_expire(rth, tmo, expire)) {
+                               if (rth->rt_genid == atomic_read(&rt_genid) &&
+                                       !rt_may_expire(rth, tmo, expire)) {
                                        tmo >>= 1;
                                        rthp = &rth->u.dst.rt_next;
                                        continue;
@@ -966,6 +937,11 @@ restart:
 
        spin_lock_bh(rt_hash_lock_addr(hash));
        while ((rth = *rthp) != NULL) {
+               if (rth->rt_genid != atomic_read(&rt_genid)) {
+                       *rthp = rth->u.dst.rt_next;
+                       rt_free(rth);
+                       continue;
+               }
                if (compare_keys(&rth->fl, &rt->fl) && compare_netns(rth, rt)) {
                        /* Put it first */
                        *rthp = rth->u.dst.rt_next;
@@ -1131,17 +1107,19 @@ void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more)
 
 static void rt_del(unsigned hash, struct rtable *rt)
 {
-       struct rtable **rthp;
+       struct rtable **rthp, *aux;
 
+       rthp = &rt_hash_table[hash].chain;
        spin_lock_bh(rt_hash_lock_addr(hash));
        ip_rt_put(rt);
-       for (rthp = &rt_hash_table[hash].chain; *rthp;
-            rthp = &(*rthp)->u.dst.rt_next)
-               if (*rthp == rt) {
-                       *rthp = rt->u.dst.rt_next;
-                       rt_free(rt);
-                       break;
+       while ((aux = *rthp) != NULL) {
+               if (aux == rt || (aux->rt_genid != atomic_read(&rt_genid))) {
+                       *rthp = aux->u.dst.rt_next;
+                       rt_free(aux);
+                       continue;
                }
+               rthp = &aux->u.dst.rt_next;
+       }
        spin_unlock_bh(rt_hash_lock_addr(hash));
 }
 
@@ -1186,7 +1164,8 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
                                if (rth->fl.fl4_dst != daddr ||
                                    rth->fl.fl4_src != skeys[i] ||
                                    rth->fl.oif != ikeys[k] ||
-                                   rth->fl.iif != 0) {
+                                   rth->fl.iif != 0 ||
+                                   rth->rt_genid != atomic_read(&rt_genid)) {
                                        rthp = &rth->u.dst.rt_next;
                                        continue;
                                }
@@ -1224,7 +1203,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
                                rt->u.dst.neighbour     = NULL;
                                rt->u.dst.hh            = NULL;
                                rt->u.dst.xfrm          = NULL;
-
+                               rt->rt_genid            = atomic_read(&rt_genid);
                                rt->rt_flags            |= RTCF_REDIRECTED;
 
                                /* Gateway is different ... */
@@ -1445,7 +1424,8 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
                            rth->rt_src  == iph->saddr &&
                            rth->fl.iif == 0 &&
                            !(dst_metric_locked(&rth->u.dst, RTAX_MTU)) &&
-                           rth->u.dst.dev->nd_net == net) {
+                           rth->u.dst.dev->nd_net == net &&
+                           rth->rt_genid == atomic_read(&rt_genid)) {
                                unsigned short mtu = new_mtu;
 
                                if (new_mtu < 68 || new_mtu >= old_mtu) {
@@ -1680,8 +1660,9 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        rth->fl.oif     = 0;
        rth->rt_gateway = daddr;
        rth->rt_spec_dst= spec_dst;
-       rth->rt_type    = RTN_MULTICAST;
+       rth->rt_genid   = atomic_read(&rt_genid);
        rth->rt_flags   = RTCF_MULTICAST;
+       rth->rt_type    = RTN_MULTICAST;
        if (our) {
                rth->u.dst.input= ip_local_deliver;
                rth->rt_flags |= RTCF_LOCAL;
@@ -1820,6 +1801,7 @@ static inline int __mkroute_input(struct sk_buff *skb,
 
        rth->u.dst.input = ip_forward;
        rth->u.dst.output = ip_output;
+       rth->rt_genid = atomic_read(&rt_genid);
 
        rt_set_nexthop(rth, res, itag);
 
@@ -1980,6 +1962,7 @@ local_input:
                goto e_nobufs;
 
        rth->u.dst.output= ip_rt_bug;
+       rth->rt_genid = atomic_read(&rt_genid);
 
        atomic_set(&rth->u.dst.__refcnt, 1);
        rth->u.dst.flags= DST_HOST;
@@ -2071,7 +2054,8 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                    rth->fl.oif == 0 &&
                    rth->fl.mark == skb->mark &&
                    rth->fl.fl4_tos == tos &&
-                   rth->u.dst.dev->nd_net == net) {
+                   rth->u.dst.dev->nd_net == net &&
+                   rth->rt_genid == atomic_read(&rt_genid)) {
                        dst_use(&rth->u.dst, jiffies);
                        RT_CACHE_STAT_INC(in_hit);
                        rcu_read_unlock();
@@ -2199,6 +2183,7 @@ static inline int __mkroute_output(struct rtable **result,
        rth->rt_spec_dst= fl->fl4_src;
 
        rth->u.dst.output=ip_output;
+       rth->rt_genid = atomic_read(&rt_genid);
 
        RT_CACHE_STAT_INC(out_slow_tot);
 
@@ -2471,7 +2456,8 @@ int __ip_route_output_key(struct net *net, struct rtable **rp,
                    rth->fl.mark == flp->mark &&
                    !((rth->fl.fl4_tos ^ flp->fl4_tos) &
                            (IPTOS_RT_MASK | RTO_ONLINK)) &&
-                   rth->u.dst.dev->nd_net == net) {
+                   rth->u.dst.dev->nd_net == net &&
+                   rth->rt_genid == atomic_read(&rt_genid)) {
                        dst_use(&rth->u.dst, jiffies);
                        RT_CACHE_STAT_INC(out_hit);
                        rcu_read_unlock_bh();
@@ -2498,6 +2484,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
        .check                  =       ipv4_dst_check,
        .update_pmtu            =       ipv4_rt_blackhole_update_pmtu,
        .entry_size             =       sizeof(struct rtable),
+       .entries                =       ATOMIC_INIT(0),
 };
 
 
@@ -2525,6 +2512,7 @@ static int ipv4_dst_blackhole(struct rtable **rp, struct flowi *flp, struct sock
                rt->idev = ort->idev;
                if (rt->idev)
                        in_dev_hold(rt->idev);
+               rt->rt_genid = atomic_read(&rt_genid);
                rt->rt_flags = ort->rt_flags;
                rt->rt_type = ort->rt_type;
                rt->rt_dst = ort->rt_dst;
@@ -2779,6 +2767,8 @@ int ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb)
                     rt = rcu_dereference(rt->u.dst.rt_next), idx++) {
                        if (idx < s_idx)
                                continue;
+                       if (rt->rt_genid != atomic_read(&rt_genid))
+                               continue;
                        skb->dst = dst_clone(&rt->u.dst);
                        if (rt_fill_info(skb, NETLINK_CB(cb->skb).pid,
                                         cb->nlh->nlmsg_seq, RTM_NEWROUTE,
@@ -2847,24 +2837,6 @@ ctl_table ipv4_route_table[] = {
                .proc_handler   = &ipv4_sysctl_rtcache_flush,
                .strategy       = &ipv4_sysctl_rtcache_flush_strategy,
        },
-       {
-               .ctl_name       = NET_IPV4_ROUTE_MIN_DELAY,
-               .procname       = "min_delay",
-               .data           = &ip_rt_min_delay,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
-       },
-       {
-               .ctl_name       = NET_IPV4_ROUTE_MAX_DELAY,
-               .procname       = "max_delay",
-               .data           = &ip_rt_max_delay,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
-       },
        {
                .ctl_name       = NET_IPV4_ROUTE_GC_THRESH,
                .procname       = "gc_thresh",
@@ -3023,8 +2995,8 @@ int __init ip_rt_init(void)
 {
        int rc = 0;
 
-       rt_hash_rnd = (int) ((num_physpages ^ (num_physpages>>8)) ^
-                            (jiffies ^ (jiffies >> 7)));
+       atomic_set(&rt_genid, (int) ((num_physpages ^ (num_physpages>>8)) ^
+                            (jiffies ^ (jiffies >> 7))));
 
 #ifdef CONFIG_NET_CLS_ROUTE
        ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct));
@@ -3057,7 +3029,6 @@ int __init ip_rt_init(void)
        devinet_init();
        ip_fib_init();
 
-       setup_timer(&rt_flush_timer, rt_run_flush, 0);
        setup_timer(&rt_secret_timer, rt_secret_rebuild, 0);
 
        /* All the timers, started at system startup tend
index 82cdf23837e3e8b9766ba5f7dbb28634a20c2675..88286f35d1e266ec6aad248c5328d17891cdcc0c 100644 (file)
@@ -185,7 +185,7 @@ static int strategy_allowed_congestion_control(ctl_table *table, int __user *nam
 
        tcp_get_available_congestion_control(tbl.data, tbl.maxlen);
        ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen);
-       if (ret == 0 && newval && newlen)
+       if (ret == 1 && newval && newlen)
                ret = tcp_set_allowed_congestion_control(tbl.data);
        kfree(tbl.data);
 
index fa2c85ca5bc39c32947f499ef6f531d840cc925e..19c449f62672d7cf41f03a65f6d6dbc0cc3b3c04 100644 (file)
@@ -2153,7 +2153,7 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int fast_rexmit)
                tp->lost_skb_hint = skb;
                tp->lost_cnt_hint = cnt;
 
-               if (tcp_is_fack(tp) ||
+               if (tcp_is_fack(tp) || tcp_is_reno(tp) ||
                    (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
                        cnt += tcp_skb_pcount(skb);
 
index 9aea88b8d4fc6a9b5dd9f12c0160129770f47011..77c1939a2b0d50b2dee673fa450a410cd82bc9c9 100644 (file)
@@ -369,8 +369,8 @@ void tcp_v4_err(struct sk_buff *skb, u32 info)
                return;
        }
 
-       sk = inet_lookup(&tcp_hashinfo, iph->daddr, th->dest, iph->saddr,
-                        th->source, inet_iif(skb));
+       sk = inet_lookup(skb->dev->nd_net, &tcp_hashinfo, iph->daddr, th->dest,
+                       iph->saddr, th->source, inet_iif(skb));
        if (!sk) {
                ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
                return;
@@ -1503,8 +1503,8 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
        if (req)
                return tcp_check_req(sk, skb, req, prev);
 
-       nsk = inet_lookup_established(&tcp_hashinfo, iph->saddr, th->source,
-                                     iph->daddr, th->dest, inet_iif(skb));
+       nsk = inet_lookup_established(sk->sk_net, &tcp_hashinfo, iph->saddr,
+                       th->source, iph->daddr, th->dest, inet_iif(skb));
 
        if (nsk) {
                if (nsk->sk_state != TCP_TIME_WAIT) {
@@ -1661,8 +1661,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
        TCP_SKB_CB(skb)->flags   = iph->tos;
        TCP_SKB_CB(skb)->sacked  = 0;
 
-       sk = __inet_lookup(&tcp_hashinfo, iph->saddr, th->source,
-                          iph->daddr, th->dest, inet_iif(skb));
+       sk = __inet_lookup(skb->dev->nd_net, &tcp_hashinfo, iph->saddr,
+                       th->source, iph->daddr, th->dest, inet_iif(skb));
        if (!sk)
                goto no_tcp_socket;
 
@@ -1735,7 +1735,8 @@ do_time_wait:
        }
        switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
        case TCP_TW_SYN: {
-               struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo,
+               struct sock *sk2 = inet_lookup_listener(skb->dev->nd_net,
+                                                       &tcp_hashinfo,
                                                        iph->daddr, th->dest,
                                                        inet_iif(skb));
                if (sk2) {
index 89f0188885c7e1962f2916d4f4084faf22063701..ed750f9ceb07caed9ed5479740e664c6a319bc8f 100644 (file)
@@ -2564,5 +2564,4 @@ EXPORT_SYMBOL(tcp_connect);
 EXPORT_SYMBOL(tcp_make_synack);
 EXPORT_SYMBOL(tcp_simple_retransmit);
 EXPORT_SYMBOL(tcp_sync_mss);
-EXPORT_SYMBOL(sysctl_tcp_tso_win_divisor);
 EXPORT_SYMBOL(tcp_mtup_init);
index 2fb8d731026b7c325288a4966e7f6f08a95392a8..7ea1b67b6de1cccbbc5d4332ef45df04578b8aae 100644 (file)
@@ -130,14 +130,14 @@ EXPORT_SYMBOL(sysctl_udp_wmem_min);
 atomic_t udp_memory_allocated;
 EXPORT_SYMBOL(udp_memory_allocated);
 
-static inline int __udp_lib_lport_inuse(__u16 num,
+static inline int __udp_lib_lport_inuse(struct net *net, __u16 num,
                                        const struct hlist_head udptable[])
 {
        struct sock *sk;
        struct hlist_node *node;
 
        sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)])
-               if (sk->sk_hash == num)
+               if (sk->sk_net == net && sk->sk_hash == num)
                        return 1;
        return 0;
 }
@@ -159,6 +159,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
        struct hlist_head *head;
        struct sock *sk2;
        int    error = 1;
+       struct net *net = sk->sk_net;
 
        write_lock_bh(&udp_hash_lock);
 
@@ -198,7 +199,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
                /* 2nd pass: find hole in shortest hash chain */
                rover = best;
                for (i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++) {
-                       if (! __udp_lib_lport_inuse(rover, udptable))
+                       if (! __udp_lib_lport_inuse(net, rover, udptable))
                                goto gotit;
                        rover += UDP_HTABLE_SIZE;
                        if (rover > high)
@@ -218,6 +219,7 @@ gotit:
                sk_for_each(sk2, node, head)
                        if (sk2->sk_hash == snum                             &&
                            sk2 != sk                                        &&
+                           sk2->sk_net == net                               &&
                            (!sk2->sk_reuse        || !sk->sk_reuse)         &&
                            (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
                             || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
@@ -261,9 +263,9 @@ static inline int udp_v4_get_port(struct sock *sk, unsigned short snum)
 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
  * harder than this. -DaveM
  */
-static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
-                                     __be32 daddr, __be16 dport,
-                                     int dif, struct hlist_head udptable[])
+static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
+               __be16 sport, __be32 daddr, __be16 dport,
+               int dif, struct hlist_head udptable[])
 {
        struct sock *sk, *result = NULL;
        struct hlist_node *node;
@@ -274,7 +276,8 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
        sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
                struct inet_sock *inet = inet_sk(sk);
 
-               if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) {
+               if (sk->sk_net == net && sk->sk_hash == hnum &&
+                               !ipv6_only_sock(sk)) {
                        int score = (sk->sk_family == PF_INET ? 1 : 0);
                        if (inet->rcv_saddr) {
                                if (inet->rcv_saddr != daddr)
@@ -361,8 +364,8 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct hlist_head udptable[])
        int harderr;
        int err;
 
-       sk = __udp4_lib_lookup(iph->daddr, uh->dest, iph->saddr, uh->source,
-                              skb->dev->ifindex, udptable                  );
+       sk = __udp4_lib_lookup(skb->dev->nd_net, iph->daddr, uh->dest,
+                       iph->saddr, uh->source, skb->dev->ifindex, udptable);
        if (sk == NULL) {
                ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
                return; /* No socket for error */
@@ -1185,8 +1188,8 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
        if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
                return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
 
-       sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
-                              inet_iif(skb), udptable);
+       sk = __udp4_lib_lookup(skb->dev->nd_net, saddr, uh->source, daddr,
+                       uh->dest, inet_iif(skb), udptable);
 
        if (sk != NULL) {
                int ret = 0;
index 3783e3ee56a424f185beb18c38a7cf00cb11c24f..10ed70491434fe9240445ae71cff6c46259e9d74 100644 (file)
@@ -247,6 +247,7 @@ static struct dst_ops xfrm4_dst_ops = {
        .local_out =            __ip_local_out,
        .gc_thresh =            1024,
        .entry_size =           sizeof(struct xfrm_dst),
+       .entries =              ATOMIC_INIT(0),
 };
 
 static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
index 326845195620dd07851907fdf03d65cadb0be220..41f5982d20876ecb7ab1df92f5533d451b932ee2 100644 (file)
@@ -38,7 +38,7 @@ static void ipip_destroy(struct xfrm_state *x)
 {
 }
 
-static struct xfrm_type ipip_type = {
+static const struct xfrm_type ipip_type = {
        .description    = "IPIP",
        .owner          = THIS_MODULE,
        .proto          = IPPROTO_IPIP,
@@ -50,7 +50,7 @@ static struct xfrm_type ipip_type = {
 
 static int xfrm_tunnel_rcv(struct sk_buff *skb)
 {
-       return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr);
+       return xfrm4_rcv_spi(skb, IPPROTO_IPIP, ip_hdr(skb)->saddr);
 }
 
 static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
index eb0b8085949b64620241de94be4815a1a303887d..3ffb0323668cc8fe40cba537589f061a68923a6c 100644 (file)
@@ -85,6 +85,7 @@ config INET6_ESP
        depends on IPV6
        select XFRM
        select CRYPTO
+       select CRYPTO_AEAD
        select CRYPTO_HMAC
        select CRYPTO_MD5
        select CRYPTO_CBC
index fb0d07a15e934678c8c91fbfa5bcf0be5718a50a..379c8e04c36c6ccf17e84abf860fd734fb5945be 100644 (file)
@@ -515,7 +515,7 @@ static void ah6_destroy(struct xfrm_state *x)
        kfree(ahp);
 }
 
-static struct xfrm_type ah6_type =
+static const struct xfrm_type ah6_type =
 {
        .description    = "AH6",
        .owner          = THIS_MODULE,
index 5bd5292ad9fa9021cf31899355db8cd60857a165..8e0f1428c7167ac85dbdc0b5e4a33426e9e44a5d 100644 (file)
  *     This file is derived from net/ipv4/esp.c
  */
 
+#include <crypto/aead.h>
+#include <crypto/authenc.h>
 #include <linux/err.h>
 #include <linux/module.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/esp.h>
 #include <linux/scatterlist.h>
-#include <linux/crypto.h>
 #include <linux/kernel.h>
 #include <linux/pfkeyv2.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <net/icmp.h>
 #include <net/ipv6.h>
 #include <net/protocol.h>
 #include <linux/icmpv6.h>
 
+struct esp_skb_cb {
+       struct xfrm_skb_cb xfrm;
+       void *tmp;
+};
+
+#define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
+
+/*
+ * Allocate an AEAD request structure with extra space for SG and IV.
+ *
+ * For alignment considerations the IV is placed at the front, followed
+ * by the request and finally the SG list.
+ *
+ * TODO: Use spare space in skb for this where possible.
+ */
+static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags)
+{
+       unsigned int len;
+
+       len = crypto_aead_ivsize(aead);
+       if (len) {
+               len += crypto_aead_alignmask(aead) &
+                      ~(crypto_tfm_ctx_alignment() - 1);
+               len = ALIGN(len, crypto_tfm_ctx_alignment());
+       }
+
+       len += sizeof(struct aead_givcrypt_request) + crypto_aead_reqsize(aead);
+       len = ALIGN(len, __alignof__(struct scatterlist));
+
+       len += sizeof(struct scatterlist) * nfrags;
+
+       return kmalloc(len, GFP_ATOMIC);
+}
+
+static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp)
+{
+       return crypto_aead_ivsize(aead) ?
+              PTR_ALIGN((u8 *)tmp, crypto_aead_alignmask(aead) + 1) : tmp;
+}
+
+static inline struct aead_givcrypt_request *esp_tmp_givreq(
+       struct crypto_aead *aead, u8 *iv)
+{
+       struct aead_givcrypt_request *req;
+
+       req = (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead),
+                               crypto_tfm_ctx_alignment());
+       aead_givcrypt_set_tfm(req, aead);
+       return req;
+}
+
+static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv)
+{
+       struct aead_request *req;
+
+       req = (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead),
+                               crypto_tfm_ctx_alignment());
+       aead_request_set_tfm(req, aead);
+       return req;
+}
+
+static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
+                                            struct aead_request *req)
+{
+       return (void *)ALIGN((unsigned long)(req + 1) +
+                            crypto_aead_reqsize(aead),
+                            __alignof__(struct scatterlist));
+}
+
+static inline struct scatterlist *esp_givreq_sg(
+       struct crypto_aead *aead, struct aead_givcrypt_request *req)
+{
+       return (void *)ALIGN((unsigned long)(req + 1) +
+                            crypto_aead_reqsize(aead),
+                            __alignof__(struct scatterlist));
+}
+
+static void esp_output_done(struct crypto_async_request *base, int err)
+{
+       struct sk_buff *skb = base->data;
+
+       kfree(ESP_SKB_CB(skb)->tmp);
+       xfrm_output_resume(skb, err);
+}
+
 static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
 {
        int err;
        struct ip_esp_hdr *esph;
-       struct crypto_blkcipher *tfm;
-       struct blkcipher_desc desc;
+       struct crypto_aead *aead;
+       struct aead_givcrypt_request *req;
+       struct scatterlist *sg;
+       struct scatterlist *asg;
        struct sk_buff *trailer;
+       void *tmp;
        int blksize;
        int clen;
        int alen;
        int nfrags;
+       u8 *iv;
        u8 *tail;
        struct esp_data *esp = x->data;
 
@@ -60,18 +151,26 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
        /* Round to block size */
        clen = skb->len;
 
-       alen = esp->auth.icv_trunc_len;
-       tfm = esp->conf.tfm;
-       desc.tfm = tfm;
-       desc.flags = 0;
-       blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
+       aead = esp->aead;
+       alen = crypto_aead_authsize(aead);
+
+       blksize = ALIGN(crypto_aead_blocksize(aead), 4);
        clen = ALIGN(clen + 2, blksize);
-       if (esp->conf.padlen)
-               clen = ALIGN(clen, esp->conf.padlen);
+       if (esp->padlen)
+               clen = ALIGN(clen, esp->padlen);
 
-       if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0) {
+       if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0)
                goto error;
-       }
+       nfrags = err;
+
+       tmp = esp_alloc_tmp(aead, nfrags + 1);
+       if (!tmp)
+               goto error;
+
+       iv = esp_tmp_iv(aead, tmp);
+       req = esp_tmp_givreq(aead, iv);
+       asg = esp_givreq_sg(aead, req);
+       sg = asg + 1;
 
        /* Fill padding... */
        tail = skb_tail_pointer(trailer);
@@ -81,86 +180,113 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
                        tail[i] = i + 1;
        } while (0);
        tail[clen-skb->len - 2] = (clen - skb->len) - 2;
-       pskb_put(skb, trailer, clen - skb->len);
+       tail[clen - skb->len - 1] = *skb_mac_header(skb);
+       pskb_put(skb, trailer, clen - skb->len + alen);
 
        skb_push(skb, -skb_network_offset(skb));
        esph = ip_esp_hdr(skb);
-       *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb);
        *skb_mac_header(skb) = IPPROTO_ESP;
 
        esph->spi = x->id.spi;
        esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
 
-       spin_lock_bh(&x->lock);
+       sg_init_table(sg, nfrags);
+       skb_to_sgvec(skb, sg,
+                    esph->enc_data + crypto_aead_ivsize(aead) - skb->data,
+                    clen + alen);
+       sg_init_one(asg, esph, sizeof(*esph));
 
-       if (esp->conf.ivlen) {
-               if (unlikely(!esp->conf.ivinitted)) {
-                       get_random_bytes(esp->conf.ivec, esp->conf.ivlen);
-                       esp->conf.ivinitted = 1;
-               }
-               crypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
-       }
+       aead_givcrypt_set_callback(req, 0, esp_output_done, skb);
+       aead_givcrypt_set_crypt(req, sg, sg, clen, iv);
+       aead_givcrypt_set_assoc(req, asg, sizeof(*esph));
+       aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq);
 
-       do {
-               struct scatterlist *sg = &esp->sgbuf[0];
+       ESP_SKB_CB(skb)->tmp = tmp;
+       err = crypto_aead_givencrypt(req);
+       if (err == -EINPROGRESS)
+               goto error;
 
-               if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
-                       sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
-                       if (!sg)
-                               goto unlock;
-               }
-               sg_init_table(sg, nfrags);
-               skb_to_sgvec(skb, sg,
-                            esph->enc_data +
-                            esp->conf.ivlen -
-                            skb->data, clen);
-               err = crypto_blkcipher_encrypt(&desc, sg, sg, clen);
-               if (unlikely(sg != &esp->sgbuf[0]))
-                       kfree(sg);
-       } while (0);
+       if (err == -EBUSY)
+               err = NET_XMIT_DROP;
+
+       kfree(tmp);
+
+error:
+       return err;
+}
+
+static int esp_input_done2(struct sk_buff *skb, int err)
+{
+       struct xfrm_state *x = xfrm_input_state(skb);
+       struct esp_data *esp = x->data;
+       struct crypto_aead *aead = esp->aead;
+       int alen = crypto_aead_authsize(aead);
+       int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead);
+       int elen = skb->len - hlen;
+       int hdr_len = skb_network_header_len(skb);
+       int padlen;
+       u8 nexthdr[2];
+
+       kfree(ESP_SKB_CB(skb)->tmp);
 
        if (unlikely(err))
-               goto unlock;
+               goto out;
 
-       if (esp->conf.ivlen) {
-               memcpy(esph->enc_data, esp->conf.ivec, esp->conf.ivlen);
-               crypto_blkcipher_get_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
-       }
+       if (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2))
+               BUG();
 
-       if (esp->auth.icv_full_len) {
-               err = esp_mac_digest(esp, skb, (u8 *)esph - skb->data,
-                                    sizeof(*esph) + esp->conf.ivlen + clen);
-               memcpy(pskb_put(skb, trailer, alen), esp->auth.work_icv, alen);
+       err = -EINVAL;
+       padlen = nexthdr[0];
+       if (padlen + 2 + alen >= elen) {
+               LIMIT_NETDEBUG(KERN_WARNING "ipsec esp packet is garbage "
+                              "padlen=%d, elen=%d\n", padlen + 2, elen - alen);
+               goto out;
        }
 
-unlock:
-       spin_unlock_bh(&x->lock);
+       /* ... check padding bits here. Silly. :-) */
 
-error:
+       pskb_trim(skb, skb->len - alen - padlen - 2);
+       __skb_pull(skb, hlen);
+       skb_set_transport_header(skb, -hdr_len);
+
+       err = nexthdr[1];
+
+       /* RFC4303: Drop dummy packets without any error */
+       if (err == IPPROTO_NONE)
+               err = -EINVAL;
+
+out:
        return err;
 }
 
+static void esp_input_done(struct crypto_async_request *base, int err)
+{
+       struct sk_buff *skb = base->data;
+
+       xfrm_input_resume(skb, esp_input_done2(skb, err));
+}
+
 static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
 {
-       struct ipv6hdr *iph;
        struct ip_esp_hdr *esph;
        struct esp_data *esp = x->data;
-       struct crypto_blkcipher *tfm = esp->conf.tfm;
-       struct blkcipher_desc desc = { .tfm = tfm };
+       struct crypto_aead *aead = esp->aead;
+       struct aead_request *req;
        struct sk_buff *trailer;
-       int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
-       int alen = esp->auth.icv_trunc_len;
-       int elen = skb->len - sizeof(*esph) - esp->conf.ivlen - alen;
-       int hdr_len = skb_network_header_len(skb);
+       int elen = skb->len - sizeof(*esph) - crypto_aead_ivsize(aead);
        int nfrags;
        int ret = 0;
+       void *tmp;
+       u8 *iv;
+       struct scatterlist *sg;
+       struct scatterlist *asg;
 
        if (!pskb_may_pull(skb, sizeof(*esph))) {
                ret = -EINVAL;
                goto out;
        }
 
-       if (elen <= 0 || (elen & (blksize-1))) {
+       if (elen <= 0) {
                ret = -EINVAL;
                goto out;
        }
@@ -170,86 +296,38 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
                goto out;
        }
 
-       skb->ip_summed = CHECKSUM_NONE;
-
-       spin_lock(&x->lock);
-
-       /* If integrity check is required, do this. */
-       if (esp->auth.icv_full_len) {
-               u8 sum[alen];
-
-               ret = esp_mac_digest(esp, skb, 0, skb->len - alen);
-               if (ret)
-                       goto unlock;
+       ret = -ENOMEM;
+       tmp = esp_alloc_tmp(aead, nfrags + 1);
+       if (!tmp)
+               goto out;
 
-               if (skb_copy_bits(skb, skb->len - alen, sum, alen))
-                       BUG();
+       ESP_SKB_CB(skb)->tmp = tmp;
+       iv = esp_tmp_iv(aead, tmp);
+       req = esp_tmp_req(aead, iv);
+       asg = esp_req_sg(aead, req);
+       sg = asg + 1;
 
-               if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
-                       ret = -EBADMSG;
-                       goto unlock;
-               }
-       }
+       skb->ip_summed = CHECKSUM_NONE;
 
        esph = (struct ip_esp_hdr *)skb->data;
-       iph = ipv6_hdr(skb);
 
        /* Get ivec. This can be wrong, check against another impls. */
-       if (esp->conf.ivlen)
-               crypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen);
-
-       {
-               struct scatterlist *sg = &esp->sgbuf[0];
-
-               if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
-                       sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
-                       if (!sg) {
-                               ret = -ENOMEM;
-                               goto unlock;
-                       }
-               }
-               sg_init_table(sg, nfrags);
-               skb_to_sgvec(skb, sg,
-                            sizeof(*esph) + esp->conf.ivlen,
-                            elen);
-               ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
-               if (unlikely(sg != &esp->sgbuf[0]))
-                       kfree(sg);
-       }
+       iv = esph->enc_data;
 
-unlock:
-       spin_unlock(&x->lock);
+       sg_init_table(sg, nfrags);
+       skb_to_sgvec(skb, sg, sizeof(*esph) + crypto_aead_ivsize(aead), elen);
+       sg_init_one(asg, esph, sizeof(*esph));
 
-       if (unlikely(ret))
-               goto out;
-
-       {
-               u8 nexthdr[2];
-               u8 padlen;
-
-               if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
-                       BUG();
-
-               padlen = nexthdr[0];
-               if (padlen+2 >= elen) {
-                       LIMIT_NETDEBUG(KERN_WARNING "ipsec esp packet is garbage padlen=%d, elen=%d\n", padlen+2, elen);
-                       ret = -EINVAL;
-                       goto out;
-               }
-               /* ... check padding bits here. Silly. :-) */
+       aead_request_set_callback(req, 0, esp_input_done, skb);
+       aead_request_set_crypt(req, sg, sg, elen, iv);
+       aead_request_set_assoc(req, asg, sizeof(*esph));
 
-               /* RFC4303: Drop dummy packets without any error */
-               if (nexthdr[1] == IPPROTO_NONE) {
-                       ret = -EINVAL;
-                       goto out;
-               }
+       ret = crypto_aead_decrypt(req);
+       if (ret == -EINPROGRESS)
+               goto out;
 
-               pskb_trim(skb, skb->len - alen - padlen - 2);
-               ret = nexthdr[1];
-       }
+       ret = esp_input_done2(skb, ret);
 
-       __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen);
-       skb_set_transport_header(skb, -hdr_len);
 out:
        return ret;
 }
@@ -257,11 +335,11 @@ out:
 static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
 {
        struct esp_data *esp = x->data;
-       u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
-       u32 align = max_t(u32, blksize, esp->conf.padlen);
+       u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4);
+       u32 align = max_t(u32, blksize, esp->padlen);
        u32 rem;
 
-       mtu -= x->props.header_len + esp->auth.icv_trunc_len;
+       mtu -= x->props.header_len + crypto_aead_authsize(esp->aead);
        rem = mtu & (align - 1);
        mtu &= ~(align - 1);
 
@@ -300,81 +378,146 @@ static void esp6_destroy(struct xfrm_state *x)
        if (!esp)
                return;
 
-       crypto_free_blkcipher(esp->conf.tfm);
-       esp->conf.tfm = NULL;
-       kfree(esp->conf.ivec);
-       esp->conf.ivec = NULL;
-       crypto_free_hash(esp->auth.tfm);
-       esp->auth.tfm = NULL;
-       kfree(esp->auth.work_icv);
-       esp->auth.work_icv = NULL;
+       crypto_free_aead(esp->aead);
        kfree(esp);
 }
 
-static int esp6_init_state(struct xfrm_state *x)
+static int esp_init_aead(struct xfrm_state *x)
+{
+       struct esp_data *esp = x->data;
+       struct crypto_aead *aead;
+       int err;
+
+       aead = crypto_alloc_aead(x->aead->alg_name, 0, 0);
+       err = PTR_ERR(aead);
+       if (IS_ERR(aead))
+               goto error;
+
+       esp->aead = aead;
+
+       err = crypto_aead_setkey(aead, x->aead->alg_key,
+                                (x->aead->alg_key_len + 7) / 8);
+       if (err)
+               goto error;
+
+       err = crypto_aead_setauthsize(aead, x->aead->alg_icv_len / 8);
+       if (err)
+               goto error;
+
+error:
+       return err;
+}
+
+static int esp_init_authenc(struct xfrm_state *x)
 {
-       struct esp_data *esp = NULL;
-       struct crypto_blkcipher *tfm;
+       struct esp_data *esp = x->data;
+       struct crypto_aead *aead;
+       struct crypto_authenc_key_param *param;
+       struct rtattr *rta;
+       char *key;
+       char *p;
+       char authenc_name[CRYPTO_MAX_ALG_NAME];
+       unsigned int keylen;
+       int err;
 
+       err = -EINVAL;
        if (x->ealg == NULL)
                goto error;
 
-       if (x->encap)
+       err = -ENAMETOOLONG;
+       if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME, "authenc(%s,%s)",
+                    x->aalg ? x->aalg->alg_name : "digest_null",
+                    x->ealg->alg_name) >= CRYPTO_MAX_ALG_NAME)
                goto error;
 
-       esp = kzalloc(sizeof(*esp), GFP_KERNEL);
-       if (esp == NULL)
-               return -ENOMEM;
+       aead = crypto_alloc_aead(authenc_name, 0, 0);
+       err = PTR_ERR(aead);
+       if (IS_ERR(aead))
+               goto error;
+
+       esp->aead = aead;
+
+       keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) +
+                (x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param));
+       err = -ENOMEM;
+       key = kmalloc(keylen, GFP_KERNEL);
+       if (!key)
+               goto error;
+
+       p = key;
+       rta = (void *)p;
+       rta->rta_type = CRYPTO_AUTHENC_KEYA_PARAM;
+       rta->rta_len = RTA_LENGTH(sizeof(*param));
+       param = RTA_DATA(rta);
+       p += RTA_SPACE(sizeof(*param));
 
        if (x->aalg) {
                struct xfrm_algo_desc *aalg_desc;
-               struct crypto_hash *hash;
-
-               hash = crypto_alloc_hash(x->aalg->alg_name, 0,
-                                        CRYPTO_ALG_ASYNC);
-               if (IS_ERR(hash))
-                       goto error;
 
-               esp->auth.tfm = hash;
-               if (crypto_hash_setkey(hash, x->aalg->alg_key,
-                                      (x->aalg->alg_key_len + 7) / 8))
-                       goto error;
+               memcpy(p, x->aalg->alg_key, (x->aalg->alg_key_len + 7) / 8);
+               p += (x->aalg->alg_key_len + 7) / 8;
 
                aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
                BUG_ON(!aalg_desc);
 
+               err = -EINVAL;
                if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
-                   crypto_hash_digestsize(hash)) {
+                   crypto_aead_authsize(aead)) {
                        NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n",
                                 x->aalg->alg_name,
-                                crypto_hash_digestsize(hash),
+                                crypto_aead_authsize(aead),
                                 aalg_desc->uinfo.auth.icv_fullbits/8);
-                       goto error;
+                       goto free_key;
                }
 
-               esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
-               esp->auth.icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8;
-
-               esp->auth.work_icv = kmalloc(esp->auth.icv_full_len, GFP_KERNEL);
-               if (!esp->auth.work_icv)
-                       goto error;
-       }
-       tfm = crypto_alloc_blkcipher(x->ealg->alg_name, 0, CRYPTO_ALG_ASYNC);
-       if (IS_ERR(tfm))
-               goto error;
-       esp->conf.tfm = tfm;
-       esp->conf.ivlen = crypto_blkcipher_ivsize(tfm);
-       esp->conf.padlen = 0;
-       if (esp->conf.ivlen) {
-               esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL);
-               if (unlikely(esp->conf.ivec == NULL))
-                       goto error;
-               esp->conf.ivinitted = 0;
+               err = crypto_aead_setauthsize(
+                       aead, aalg_desc->uinfo.auth.icv_truncbits / 8);
+               if (err)
+                       goto free_key;
        }
-       if (crypto_blkcipher_setkey(tfm, x->ealg->alg_key,
-                                   (x->ealg->alg_key_len + 7) / 8))
+
+       param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8);
+       memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8);
+
+       err = crypto_aead_setkey(aead, key, keylen);
+
+free_key:
+       kfree(key);
+
+error:
+       return err;
+}
+
+static int esp6_init_state(struct xfrm_state *x)
+{
+       struct esp_data *esp;
+       struct crypto_aead *aead;
+       u32 align;
+       int err;
+
+       if (x->encap)
+               return -EINVAL;
+
+       esp = kzalloc(sizeof(*esp), GFP_KERNEL);
+       if (esp == NULL)
+               return -ENOMEM;
+
+       x->data = esp;
+
+       if (x->aead)
+               err = esp_init_aead(x);
+       else
+               err = esp_init_authenc(x);
+
+       if (err)
                goto error;
-       x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
+
+       aead = esp->aead;
+
+       esp->padlen = 0;
+
+       x->props.header_len = sizeof(struct ip_esp_hdr) +
+                             crypto_aead_ivsize(aead);
        switch (x->props.mode) {
        case XFRM_MODE_BEET:
        case XFRM_MODE_TRANSPORT:
@@ -385,17 +528,17 @@ static int esp6_init_state(struct xfrm_state *x)
        default:
                goto error;
        }
-       x->data = esp;
-       return 0;
+
+       align = ALIGN(crypto_aead_blocksize(aead), 4);
+       if (esp->padlen)
+               align = max_t(u32, align, esp->padlen);
+       x->props.trailer_len = align + 1 + crypto_aead_authsize(esp->aead);
 
 error:
-       x->data = esp;
-       esp6_destroy(x);
-       x->data = NULL;
-       return -EINVAL;
+       return err;
 }
 
-static struct xfrm_type esp6_type =
+static const struct xfrm_type esp6_type =
 {
        .description    = "ESP6",
        .owner          = THIS_MODULE,
index a66a7d8e281133f7f8a6000cf482b35bfe5c4cd9..d325a995890911ec0f4418c2f00f0034231111e0 100644 (file)
@@ -54,7 +54,8 @@ EXPORT_SYMBOL(__inet6_hash);
  *
  * The sockhash lock must be held as a reader here.
  */
-struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
+struct sock *__inet6_lookup_established(struct net *net,
+                                       struct inet_hashinfo *hashinfo,
                                           const struct in6_addr *saddr,
                                           const __be16 sport,
                                           const struct in6_addr *daddr,
@@ -75,22 +76,13 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
        read_lock(lock);
        sk_for_each(sk, node, &head->chain) {
                /* For IPV6 do the cheaper port and family tests first. */
-               if (INET6_MATCH(sk, hash, saddr, daddr, ports, dif))
+               if (INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif))
                        goto hit; /* You sunk my battleship! */
        }
        /* Must check for a TIME_WAIT'er before going to listener hash. */
        sk_for_each(sk, node, &head->twchain) {
-               const struct inet_timewait_sock *tw = inet_twsk(sk);
-
-               if(*((__portpair *)&(tw->tw_dport))     == ports        &&
-                  sk->sk_family                == PF_INET6) {
-                       const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
-
-                       if (ipv6_addr_equal(&tw6->tw_v6_daddr, saddr)   &&
-                           ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr)       &&
-                           (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif))
-                               goto hit;
-               }
+               if (INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif))
+                       goto hit;
        }
        read_unlock(lock);
        return NULL;
@@ -102,9 +94,9 @@ hit:
 }
 EXPORT_SYMBOL(__inet6_lookup_established);
 
-struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
-                                  const struct in6_addr *daddr,
-                                  const unsigned short hnum, const int dif)
+struct sock *inet6_lookup_listener(struct net *net,
+               struct inet_hashinfo *hashinfo, const struct in6_addr *daddr,
+               const unsigned short hnum, const int dif)
 {
        struct sock *sk;
        const struct hlist_node *node;
@@ -113,7 +105,8 @@ struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
 
        read_lock(&hashinfo->lhash_lock);
        sk_for_each(sk, node, &hashinfo->listening_hash[inet_lhashfn(hnum)]) {
-               if (inet_sk(sk)->num == hnum && sk->sk_family == PF_INET6) {
+               if (sk->sk_net == net && inet_sk(sk)->num == hnum &&
+                               sk->sk_family == PF_INET6) {
                        const struct ipv6_pinfo *np = inet6_sk(sk);
 
                        score = 1;
@@ -145,7 +138,7 @@ struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
 
 EXPORT_SYMBOL_GPL(inet6_lookup_listener);
 
-struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
+struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
                          const struct in6_addr *saddr, const __be16 sport,
                          const struct in6_addr *daddr, const __be16 dport,
                          const int dif)
@@ -153,7 +146,7 @@ struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
        struct sock *sk;
 
        local_bh_disable();
-       sk = __inet6_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif);
+       sk = __inet6_lookup(net, hashinfo, saddr, sport, daddr, ntohs(dport), dif);
        local_bh_enable();
 
        return sk;
@@ -179,21 +172,16 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
        struct sock *sk2;
        const struct hlist_node *node;
        struct inet_timewait_sock *tw;
+       struct net *net = sk->sk_net;
 
        prefetch(head->chain.first);
        write_lock(lock);
 
        /* Check TIME-WAIT sockets first. */
        sk_for_each(sk2, node, &head->twchain) {
-               const struct inet6_timewait_sock *tw6 = inet6_twsk(sk2);
-
                tw = inet_twsk(sk2);
 
-               if(*((__portpair *)&(tw->tw_dport)) == ports             &&
-                  sk2->sk_family              == PF_INET6       &&
-                  ipv6_addr_equal(&tw6->tw_v6_daddr, saddr)     &&
-                  ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
-                  (!sk2->sk_bound_dev_if || sk2->sk_bound_dev_if == dif)) {
+               if (INET6_TW_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) {
                        if (twsk_unique(sk, sk2, twp))
                                goto unique;
                        else
@@ -204,7 +192,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
 
        /* And established part... */
        sk_for_each(sk2, node, &head->chain) {
-               if (INET6_MATCH(sk2, hash, saddr, daddr, ports, dif))
+               if (INET6_MATCH(sk2, net, hash, saddr, daddr, ports, dif))
                        goto not_unique;
        }
 
@@ -248,97 +236,8 @@ static inline u32 inet6_sk_port_offset(const struct sock *sk)
 int inet6_hash_connect(struct inet_timewait_death_row *death_row,
                       struct sock *sk)
 {
-       struct inet_hashinfo *hinfo = death_row->hashinfo;
-       const unsigned short snum = inet_sk(sk)->num;
-       struct inet_bind_hashbucket *head;
-       struct inet_bind_bucket *tb;
-       int ret;
-
-       if (snum == 0) {
-               int i, port, low, high, remaining;
-               static u32 hint;
-               const u32 offset = hint + inet6_sk_port_offset(sk);
-               struct hlist_node *node;
-               struct inet_timewait_sock *tw = NULL;
-
-               inet_get_local_port_range(&low, &high);
-               remaining = (high - low) + 1;
-
-               local_bh_disable();
-               for (i = 1; i <= remaining; i++) {
-                       port = low + (i + offset) % remaining;
-                       head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
-                       spin_lock(&head->lock);
-
-                       /* Does not bother with rcv_saddr checks,
-                        * because the established check is already
-                        * unique enough.
-                        */
-                       inet_bind_bucket_for_each(tb, node, &head->chain) {
-                               if (tb->port == port) {
-                                       BUG_TRAP(!hlist_empty(&tb->owners));
-                                       if (tb->fastreuse >= 0)
-                                               goto next_port;
-                                       if (!__inet6_check_established(death_row,
-                                                                      sk, port,
-                                                                      &tw))
-                                               goto ok;
-                                       goto next_port;
-                               }
-                       }
-
-                       tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
-                                                    head, port);
-                       if (!tb) {
-                               spin_unlock(&head->lock);
-                               break;
-                       }
-                       tb->fastreuse = -1;
-                       goto ok;
-
-               next_port:
-                       spin_unlock(&head->lock);
-               }
-               local_bh_enable();
-
-               return -EADDRNOTAVAIL;
-
-ok:
-               hint += i;
-
-               /* Head lock still held and bh's disabled */
-               inet_bind_hash(sk, tb, port);
-               if (sk_unhashed(sk)) {
-                       inet_sk(sk)->sport = htons(port);
-                       __inet6_hash(hinfo, sk);
-               }
-               spin_unlock(&head->lock);
-
-               if (tw) {
-                       inet_twsk_deschedule(tw, death_row);
-                       inet_twsk_put(tw);
-               }
-
-               ret = 0;
-               goto out;
-       }
-
-       head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)];
-       tb   = inet_csk(sk)->icsk_bind_hash;
-       spin_lock_bh(&head->lock);
-
-       if (sk_head(&tb->owners) == sk && sk->sk_bind_node.next == NULL) {
-               __inet6_hash(hinfo, sk);
-               spin_unlock_bh(&head->lock);
-               return 0;
-       } else {
-               spin_unlock(&head->lock);
-               /* No definite answer... Walk to established hash table */
-               ret = __inet6_check_established(death_row, sk, snum, NULL);
-out:
-               local_bh_enable();
-               return ret;
-       }
+       return __inet_hash_connect(death_row, sk,
+                       __inet6_check_established, __inet6_hash);
 }
 
 EXPORT_SYMBOL_GPL(inet6_hash_connect);
index 15c4f6cee3e6e54daf41bec34d5015fb7a5fdf4b..9ac6ca2521c32fba05dd4c99e9f8e68bbf762c32 100644 (file)
@@ -257,6 +257,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
        ipv6_addr_copy(&hdr->daddr, first_hop);
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
 
        mtu = dst_mtu(dst);
        if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) {
@@ -636,6 +637,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 
        if (skb_shinfo(skb)->frag_list) {
                int first_len = skb_pagelen(skb);
+               int truesizes = 0;
 
                if (first_len - hlen > mtu ||
                    ((first_len - hlen) & 7) ||
@@ -658,7 +660,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
                                sock_hold(skb->sk);
                                frag->sk = skb->sk;
                                frag->destructor = sock_wfree;
-                               skb->truesize -= frag->truesize;
+                               truesizes += frag->truesize;
                        }
                }
 
@@ -689,6 +691,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 
                first_len = skb_pagelen(skb);
                skb->data_len = first_len - skb_headlen(skb);
+               skb->truesize -= truesizes;
                skb->len = first_len;
                ipv6_hdr(skb)->payload_len = htons(first_len -
                                                   sizeof(struct ipv6hdr));
@@ -1437,6 +1440,7 @@ int ip6_push_pending_frames(struct sock *sk)
        ipv6_addr_copy(&hdr->daddr, final_dst);
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
 
        skb->dst = dst_clone(&rt->u.dst);
        IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
index b276d04d6db52ea7dc2c1529d3351cc5a6e5b0aa..b90039593a7f0873c0d8af1b7c67144a2a34f531 100644 (file)
@@ -64,6 +64,7 @@ static LIST_HEAD(ipcomp6_tfms_list);
 
 static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
 {
+       int nexthdr;
        int err = -ENOMEM;
        struct ip_comp_hdr *ipch;
        int plen, dlen;
@@ -79,6 +80,8 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
 
        /* Remove ipcomp header and decompress original payload */
        ipch = (void *)skb->data;
+       nexthdr = ipch->nexthdr;
+
        skb->transport_header = skb->network_header + sizeof(*ipch);
        __skb_pull(skb, sizeof(*ipch));
 
@@ -108,7 +111,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
        skb->truesize += dlen - plen;
        __skb_put(skb, dlen - plen);
        skb_copy_to_linear_data(skb, scratch, dlen);
-       err = ipch->nexthdr;
+       err = nexthdr;
 
 out_put_cpu:
        put_cpu();
@@ -450,7 +453,7 @@ error:
        goto out;
 }
 
-static struct xfrm_type ipcomp6_type =
+static const struct xfrm_type ipcomp6_type =
 {
        .description    = "IPCOMP6",
        .owner          = THIS_MODULE,
index 49d396620eac97e42d6c4602ac178d3cdfd9f1b8..cd8a5bda13cd7a5caad4ac6c8280764e123cb7d7 100644 (file)
@@ -330,7 +330,7 @@ static void mip6_destopt_destroy(struct xfrm_state *x)
 {
 }
 
-static struct xfrm_type mip6_destopt_type =
+static const struct xfrm_type mip6_destopt_type =
 {
        .description    = "MIP6DESTOPT",
        .owner          = THIS_MODULE,
@@ -462,7 +462,7 @@ static void mip6_rthdr_destroy(struct xfrm_state *x)
 {
 }
 
-static struct xfrm_type mip6_rthdr_type =
+static const struct xfrm_type mip6_rthdr_type =
 {
        .description    = "MIP6RT",
        .owner          = THIS_MODULE,
index 56b4ea6d29ed3c9780f0081d1a922899f92ba6f7..e869916b05f1c0b94e267016d69e0e7ff8446919 100644 (file)
@@ -515,6 +515,7 @@ static struct notifier_block ipq_nl_notifier = {
        .notifier_call  = ipq_rcv_nl_event,
 };
 
+#ifdef CONFIG_SYSCTL
 static struct ctl_table_header *ipq_sysctl_header;
 
 static ctl_table ipq_table[] = {
@@ -528,7 +529,9 @@ static ctl_table ipq_table[] = {
        },
        { .ctl_name = 0 }
 };
+#endif
 
+#ifdef CONFIG_PROC_FS
 static int ip6_queue_show(struct seq_file *m, void *v)
 {
        read_lock_bh(&queue_lock);
@@ -565,6 +568,7 @@ static const struct file_operations ip6_queue_proc_fops = {
        .release        = single_release,
        .owner          = THIS_MODULE,
 };
+#endif
 
 static const struct nf_queue_handler nfqh = {
        .name   = "ip6_queue",
@@ -574,7 +578,7 @@ static const struct nf_queue_handler nfqh = {
 static int __init ip6_queue_init(void)
 {
        int status = -ENOMEM;
-       struct proc_dir_entry *proc;
+       struct proc_dir_entry *proc __maybe_unused;
 
        netlink_register_notifier(&ipq_nl_notifier);
        ipqnl = netlink_kernel_create(&init_net, NETLINK_IP6_FW, 0,
@@ -584,6 +588,7 @@ static int __init ip6_queue_init(void)
                goto cleanup_netlink_notifier;
        }
 
+#ifdef CONFIG_PROC_FS
        proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net);
        if (proc) {
                proc->owner = THIS_MODULE;
@@ -592,10 +597,11 @@ static int __init ip6_queue_init(void)
                printk(KERN_ERR "ip6_queue: failed to create proc entry\n");
                goto cleanup_ipqnl;
        }
-
+#endif
        register_netdevice_notifier(&ipq_dev_notifier);
+#ifdef CONFIG_SYSCTL
        ipq_sysctl_header = register_sysctl_paths(net_ipv6_ctl_path, ipq_table);
-
+#endif
        status = nf_register_queue_handler(PF_INET6, &nfqh);
        if (status < 0) {
                printk(KERN_ERR "ip6_queue: failed to register queue handler\n");
@@ -604,11 +610,13 @@ static int __init ip6_queue_init(void)
        return status;
 
 cleanup_sysctl:
+#ifdef CONFIG_SYSCTL
        unregister_sysctl_table(ipq_sysctl_header);
+#endif
        unregister_netdevice_notifier(&ipq_dev_notifier);
        proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
 
-cleanup_ipqnl:
+cleanup_ipqnl: __maybe_unused
        netlink_kernel_release(ipqnl);
        mutex_lock(&ipqnl_mutex);
        mutex_unlock(&ipqnl_mutex);
@@ -624,7 +632,9 @@ static void __exit ip6_queue_fini(void)
        synchronize_net();
        ipq_flush(NULL, 0);
 
+#ifdef CONFIG_SYSCTL
        unregister_sysctl_table(ipq_sysctl_header);
+#endif
        unregister_netdevice_notifier(&ipq_dev_notifier);
        proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
 
index dd7860fea61f98752bed17073cc92dd2d52808e3..bf9bb6e55bb54ca4db20ca77d6f7c54543caf512 100644 (file)
@@ -320,7 +320,7 @@ static void trace_packet(struct sk_buff *skb,
                         unsigned int hook,
                         const struct net_device *in,
                         const struct net_device *out,
-                        char *tablename,
+                        const char *tablename,
                         struct xt_table_info *private,
                         struct ip6t_entry *e)
 {
@@ -1118,7 +1118,7 @@ static int compat_table_info(const struct xt_table_info *info,
 }
 #endif
 
-static int get_info(void __user *user, int *len, int compat)
+static int get_info(struct net *net, void __user *user, int *len, int compat)
 {
        char name[IP6T_TABLE_MAXNAMELEN];
        struct xt_table *t;
@@ -1138,7 +1138,7 @@ static int get_info(void __user *user, int *len, int compat)
        if (compat)
                xt_compat_lock(AF_INET6);
 #endif
-       t = try_then_request_module(xt_find_table_lock(AF_INET6, name),
+       t = try_then_request_module(xt_find_table_lock(net, AF_INET6, name),
                                    "ip6table_%s", name);
        if (t && !IS_ERR(t)) {
                struct ip6t_getinfo info;
@@ -1178,7 +1178,7 @@ static int get_info(void __user *user, int *len, int compat)
 }
 
 static int
-get_entries(struct ip6t_get_entries __user *uptr, int *len)
+get_entries(struct net *net, struct ip6t_get_entries __user *uptr, int *len)
 {
        int ret;
        struct ip6t_get_entries get;
@@ -1196,7 +1196,7 @@ get_entries(struct ip6t_get_entries __user *uptr, int *len)
                return -EINVAL;
        }
 
-       t = xt_find_table_lock(AF_INET6, get.name);
+       t = xt_find_table_lock(net, AF_INET6, get.name);
        if (t && !IS_ERR(t)) {
                struct xt_table_info *private = t->private;
                duprintf("t->private->number = %u\n", private->number);
@@ -1217,7 +1217,7 @@ get_entries(struct ip6t_get_entries __user *uptr, int *len)
 }
 
 static int
-__do_replace(const char *name, unsigned int valid_hooks,
+__do_replace(struct net *net, const char *name, unsigned int valid_hooks,
             struct xt_table_info *newinfo, unsigned int num_counters,
             void __user *counters_ptr)
 {
@@ -1235,7 +1235,7 @@ __do_replace(const char *name, unsigned int valid_hooks,
                goto out;
        }
 
-       t = try_then_request_module(xt_find_table_lock(AF_INET6, name),
+       t = try_then_request_module(xt_find_table_lock(net, AF_INET6, name),
                                    "ip6table_%s", name);
        if (!t || IS_ERR(t)) {
                ret = t ? PTR_ERR(t) : -ENOENT;
@@ -1288,7 +1288,7 @@ __do_replace(const char *name, unsigned int valid_hooks,
 }
 
 static int
-do_replace(void __user *user, unsigned int len)
+do_replace(struct net *net, void __user *user, unsigned int len)
 {
        int ret;
        struct ip6t_replace tmp;
@@ -1322,7 +1322,7 @@ do_replace(void __user *user, unsigned int len)
 
        duprintf("ip_tables: Translated table\n");
 
-       ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+       ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
                           tmp.num_counters, tmp.counters);
        if (ret)
                goto free_newinfo_untrans;
@@ -1358,7 +1358,8 @@ add_counter_to_entry(struct ip6t_entry *e,
 }
 
 static int
-do_add_counters(void __user *user, unsigned int len, int compat)
+do_add_counters(struct net *net, void __user *user, unsigned int len,
+               int compat)
 {
        unsigned int i;
        struct xt_counters_info tmp;
@@ -1410,7 +1411,7 @@ do_add_counters(void __user *user, unsigned int len, int compat)
                goto free;
        }
 
-       t = xt_find_table_lock(AF_INET6, name);
+       t = xt_find_table_lock(net, AF_INET6, name);
        if (!t || IS_ERR(t)) {
                ret = t ? PTR_ERR(t) : -ENOENT;
                goto free;
@@ -1456,7 +1457,7 @@ struct compat_ip6t_replace {
 
 static int
 compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
-                         compat_uint_t *size, struct xt_counters *counters,
+                         unsigned int *size, struct xt_counters *counters,
                          unsigned int *i)
 {
        struct ip6t_entry_target *t;
@@ -1503,7 +1504,7 @@ compat_find_calc_match(struct ip6t_entry_match *m,
                       const char *name,
                       const struct ip6t_ip6 *ipv6,
                       unsigned int hookmask,
-                      int *size, int *i)
+                      int *size, unsigned int *i)
 {
        struct xt_match *match;
 
@@ -1561,7 +1562,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
        struct ip6t_entry_target *t;
        struct xt_target *target;
        unsigned int entry_offset;
-       int ret, off, h, j;
+       unsigned int j;
+       int ret, off, h;
 
        duprintf("check_compat_entry_size_and_hooks %p\n", e);
        if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0
@@ -1673,7 +1675,8 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
 static int compat_check_entry(struct ip6t_entry *e, const char *name,
                                     unsigned int *i)
 {
-       int j, ret;
+       unsigned int j;
+       int ret;
 
        j = 0;
        ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6,
@@ -1815,7 +1818,7 @@ out_unlock:
 }
 
 static int
-compat_do_replace(void __user *user, unsigned int len)
+compat_do_replace(struct net *net, void __user *user, unsigned int len)
 {
        int ret;
        struct compat_ip6t_replace tmp;
@@ -1852,7 +1855,7 @@ compat_do_replace(void __user *user, unsigned int len)
 
        duprintf("compat_do_replace: Translated table\n");
 
-       ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+       ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
                           tmp.num_counters, compat_ptr(tmp.counters));
        if (ret)
                goto free_newinfo_untrans;
@@ -1876,11 +1879,11 @@ compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user,
 
        switch (cmd) {
        case IP6T_SO_SET_REPLACE:
-               ret = compat_do_replace(user, len);
+               ret = compat_do_replace(sk->sk_net, user, len);
                break;
 
        case IP6T_SO_SET_ADD_COUNTERS:
-               ret = do_add_counters(user, len, 1);
+               ret = do_add_counters(sk->sk_net, user, len, 1);
                break;
 
        default:
@@ -1929,7 +1932,8 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
 }
 
 static int
-compat_get_entries(struct compat_ip6t_get_entries __user *uptr, int *len)
+compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr,
+                  int *len)
 {
        int ret;
        struct compat_ip6t_get_entries get;
@@ -1950,7 +1954,7 @@ compat_get_entries(struct compat_ip6t_get_entries __user *uptr, int *len)
        }
 
        xt_compat_lock(AF_INET6);
-       t = xt_find_table_lock(AF_INET6, get.name);
+       t = xt_find_table_lock(net, AF_INET6, get.name);
        if (t && !IS_ERR(t)) {
                struct xt_table_info *private = t->private;
                struct xt_table_info info;
@@ -1986,10 +1990,10 @@ compat_do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 
        switch (cmd) {
        case IP6T_SO_GET_INFO:
-               ret = get_info(user, len, 1);
+               ret = get_info(sk->sk_net, user, len, 1);
                break;
        case IP6T_SO_GET_ENTRIES:
-               ret = compat_get_entries(user, len);
+               ret = compat_get_entries(sk->sk_net, user, len);
                break;
        default:
                ret = do_ip6t_get_ctl(sk, cmd, user, len);
@@ -2008,11 +2012,11 @@ do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
 
        switch (cmd) {
        case IP6T_SO_SET_REPLACE:
-               ret = do_replace(user, len);
+               ret = do_replace(sk->sk_net, user, len);
                break;
 
        case IP6T_SO_SET_ADD_COUNTERS:
-               ret = do_add_counters(user, len, 0);
+               ret = do_add_counters(sk->sk_net, user, len, 0);
                break;
 
        default:
@@ -2033,11 +2037,11 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 
        switch (cmd) {
        case IP6T_SO_GET_INFO:
-               ret = get_info(user, len, 0);
+               ret = get_info(sk->sk_net, user, len, 0);
                break;
 
        case IP6T_SO_GET_ENTRIES:
-               ret = get_entries(user, len);
+               ret = get_entries(sk->sk_net, user, len);
                break;
 
        case IP6T_SO_GET_REVISION_MATCH:
@@ -2074,17 +2078,21 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
        return ret;
 }
 
-int ip6t_register_table(struct xt_table *table, const struct ip6t_replace *repl)
+struct xt_table *ip6t_register_table(struct net *net, struct xt_table *table,
+                                    const struct ip6t_replace *repl)
 {
        int ret;
        struct xt_table_info *newinfo;
        struct xt_table_info bootstrap
                = { 0, 0, 0, { 0 }, { 0 }, { } };
        void *loc_cpu_entry;
+       struct xt_table *new_table;
 
        newinfo = xt_alloc_table_info(repl->size);
-       if (!newinfo)
-               return -ENOMEM;
+       if (!newinfo) {
+               ret = -ENOMEM;
+               goto out;
+       }
 
        /* choose the copy on our node/cpu, but dont care about preemption */
        loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
@@ -2095,30 +2103,35 @@ int ip6t_register_table(struct xt_table *table, const struct ip6t_replace *repl)
                              repl->num_entries,
                              repl->hook_entry,
                              repl->underflow);
-       if (ret != 0) {
-               xt_free_table_info(newinfo);
-               return ret;
-       }
+       if (ret != 0)
+               goto out_free;
 
-       ret = xt_register_table(table, &bootstrap, newinfo);
-       if (ret != 0) {
-               xt_free_table_info(newinfo);
-               return ret;
+       new_table = xt_register_table(net, table, &bootstrap, newinfo);
+       if (IS_ERR(new_table)) {
+               ret = PTR_ERR(new_table);
+               goto out_free;
        }
+       return new_table;
 
-       return 0;
+out_free:
+       xt_free_table_info(newinfo);
+out:
+       return ERR_PTR(ret);
 }
 
 void ip6t_unregister_table(struct xt_table *table)
 {
        struct xt_table_info *private;
        void *loc_cpu_entry;
+       struct module *table_owner = table->me;
 
        private = xt_unregister_table(table);
 
        /* Decrease module usage counts and free resources */
        loc_cpu_entry = private->entries[raw_smp_processor_id()];
        IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL);
+       if (private->number > private->initial_entries)
+               module_put(table_owner);
        xt_free_table_info(private);
 }
 
@@ -2225,11 +2238,26 @@ static struct xt_match icmp6_matchstruct __read_mostly = {
        .family         = AF_INET6,
 };
 
+static int __net_init ip6_tables_net_init(struct net *net)
+{
+       return xt_proto_init(net, AF_INET6);
+}
+
+static void __net_exit ip6_tables_net_exit(struct net *net)
+{
+       xt_proto_fini(net, AF_INET6);
+}
+
+static struct pernet_operations ip6_tables_net_ops = {
+       .init = ip6_tables_net_init,
+       .exit = ip6_tables_net_exit,
+};
+
 static int __init ip6_tables_init(void)
 {
        int ret;
 
-       ret = xt_proto_init(AF_INET6);
+       ret = register_pernet_subsys(&ip6_tables_net_ops);
        if (ret < 0)
                goto err1;
 
@@ -2259,7 +2287,7 @@ err4:
 err3:
        xt_unregister_target(&ip6t_standard_target);
 err2:
-       xt_proto_fini(AF_INET6);
+       unregister_pernet_subsys(&ip6_tables_net_ops);
 err1:
        return ret;
 }
@@ -2271,7 +2299,8 @@ static void __exit ip6_tables_fini(void)
        xt_unregister_match(&icmp6_matchstruct);
        xt_unregister_target(&ip6t_error_target);
        xt_unregister_target(&ip6t_standard_target);
-       xt_proto_fini(AF_INET6);
+
+       unregister_pernet_subsys(&ip6_tables_net_ops);
 }
 
 /*
index 87d38d08aad090e92f7f2dc022d203a7fb5ad54e..2d9cd095a72cd51ba8039b2a6b6a6ec4cf7a9c35 100644 (file)
@@ -26,7 +26,7 @@ static struct
        struct ip6t_replace repl;
        struct ip6t_standard entries[3];
        struct ip6t_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
        .repl = {
                .name = "filter",
                .valid_hooks = FILTER_VALID_HOOKS,
@@ -67,7 +67,7 @@ ip6t_hook(unsigned int hook,
         const struct net_device *out,
         int (*okfn)(struct sk_buff *))
 {
-       return ip6t_do_table(skb, hook, in, out, &packet_filter);
+       return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_filter);
 }
 
 static unsigned int
@@ -87,7 +87,7 @@ ip6t_local_out_hook(unsigned int hook,
        }
 #endif
 
-       return ip6t_do_table(skb, hook, in, out, &packet_filter);
+       return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_filter);
 }
 
 static struct nf_hook_ops ip6t_ops[] __read_mostly = {
@@ -118,6 +118,26 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
 static int forward = NF_ACCEPT;
 module_param(forward, bool, 0000);
 
+static int __net_init ip6table_filter_net_init(struct net *net)
+{
+       /* Register table */
+       net->ipv6.ip6table_filter =
+               ip6t_register_table(net, &packet_filter, &initial_table.repl);
+       if (IS_ERR(net->ipv6.ip6table_filter))
+               return PTR_ERR(net->ipv6.ip6table_filter);
+       return 0;
+}
+
+static void __net_exit ip6table_filter_net_exit(struct net *net)
+{
+       ip6t_unregister_table(net->ipv6.ip6table_filter);
+}
+
+static struct pernet_operations ip6table_filter_net_ops = {
+       .init = ip6table_filter_net_init,
+       .exit = ip6table_filter_net_exit,
+};
+
 static int __init ip6table_filter_init(void)
 {
        int ret;
@@ -130,8 +150,7 @@ static int __init ip6table_filter_init(void)
        /* Entry 1 is the FORWARD hook */
        initial_table.entries[1].target.verdict = -forward - 1;
 
-       /* Register table */
-       ret = ip6t_register_table(&packet_filter, &initial_table.repl);
+       ret = register_pernet_subsys(&ip6table_filter_net_ops);
        if (ret < 0)
                return ret;
 
@@ -143,14 +162,14 @@ static int __init ip6table_filter_init(void)
        return ret;
 
  cleanup_table:
-       ip6t_unregister_table(&packet_filter);
+       unregister_pernet_subsys(&ip6table_filter_net_ops);
        return ret;
 }
 
 static void __exit ip6table_filter_fini(void)
 {
        nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
-       ip6t_unregister_table(&packet_filter);
+       unregister_pernet_subsys(&ip6table_filter_net_ops);
 }
 
 module_init(ip6table_filter_init);
index d6082600bc5db6d260183e0da010252e6413a157..035343a90ffe198c04acef90a3a33c7a59caea6e 100644 (file)
@@ -26,7 +26,7 @@ static struct
        struct ip6t_replace repl;
        struct ip6t_standard entries[5];
        struct ip6t_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
        .repl = {
                .name = "mangle",
                .valid_hooks = MANGLE_VALID_HOOKS,
@@ -73,7 +73,7 @@ ip6t_route_hook(unsigned int hook,
         const struct net_device *out,
         int (*okfn)(struct sk_buff *))
 {
-       return ip6t_do_table(skb, hook, in, out, &packet_mangler);
+       return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle);
 }
 
 static unsigned int
@@ -108,7 +108,7 @@ ip6t_local_hook(unsigned int hook,
        /* flowlabel and prio (includes version, which shouldn't change either */
        flowlabel = *((u_int32_t *)ipv6_hdr(skb));
 
-       ret = ip6t_do_table(skb, hook, in, out, &packet_mangler);
+       ret = ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle);
 
        if (ret != NF_DROP && ret != NF_STOLEN
                && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr))
@@ -158,12 +158,31 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
        },
 };
 
+static int __net_init ip6table_mangle_net_init(struct net *net)
+{
+       /* Register table */
+       net->ipv6.ip6table_mangle =
+               ip6t_register_table(net, &packet_mangler, &initial_table.repl);
+       if (IS_ERR(net->ipv6.ip6table_mangle))
+               return PTR_ERR(net->ipv6.ip6table_mangle);
+       return 0;
+}
+
+static void __net_exit ip6table_mangle_net_exit(struct net *net)
+{
+       ip6t_unregister_table(net->ipv6.ip6table_mangle);
+}
+
+static struct pernet_operations ip6table_mangle_net_ops = {
+       .init = ip6table_mangle_net_init,
+       .exit = ip6table_mangle_net_exit,
+};
+
 static int __init ip6table_mangle_init(void)
 {
        int ret;
 
-       /* Register table */
-       ret = ip6t_register_table(&packet_mangler, &initial_table.repl);
+       ret = register_pernet_subsys(&ip6table_mangle_net_ops);
        if (ret < 0)
                return ret;
 
@@ -175,14 +194,14 @@ static int __init ip6table_mangle_init(void)
        return ret;
 
  cleanup_table:
-       ip6t_unregister_table(&packet_mangler);
+       unregister_pernet_subsys(&ip6table_mangle_net_ops);
        return ret;
 }
 
 static void __exit ip6table_mangle_fini(void)
 {
        nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
-       ip6t_unregister_table(&packet_mangler);
+       unregister_pernet_subsys(&ip6table_mangle_net_ops);
 }
 
 module_init(ip6table_mangle_init);
index eccbaaa104af264a3308208178abce7c30a0c64b..5cd84203abfe80bc06b2e2ae10ccd74150a0b6ed 100644 (file)
@@ -13,7 +13,7 @@ static struct
        struct ip6t_replace repl;
        struct ip6t_standard entries[2];
        struct ip6t_error term;
-} initial_table __initdata = {
+} initial_table __net_initdata = {
        .repl = {
                .name = "raw",
                .valid_hooks = RAW_VALID_HOOKS,
@@ -51,7 +51,7 @@ ip6t_hook(unsigned int hook,
         const struct net_device *out,
         int (*okfn)(struct sk_buff *))
 {
-       return ip6t_do_table(skb, hook, in, out, &packet_raw);
+       return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_raw);
 }
 
 static struct nf_hook_ops ip6t_ops[] __read_mostly = {
@@ -71,12 +71,31 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
        },
 };
 
+static int __net_init ip6table_raw_net_init(struct net *net)
+{
+       /* Register table */
+       net->ipv6.ip6table_raw =
+               ip6t_register_table(net, &packet_raw, &initial_table.repl);
+       if (IS_ERR(net->ipv6.ip6table_raw))
+               return PTR_ERR(net->ipv6.ip6table_raw);
+       return 0;
+}
+
+static void __net_exit ip6table_raw_net_exit(struct net *net)
+{
+       ip6t_unregister_table(net->ipv6.ip6table_raw);
+}
+
+static struct pernet_operations ip6table_raw_net_ops = {
+       .init = ip6table_raw_net_init,
+       .exit = ip6table_raw_net_exit,
+};
+
 static int __init ip6table_raw_init(void)
 {
        int ret;
 
-       /* Register table */
-       ret = ip6t_register_table(&packet_raw, &initial_table.repl);
+       ret = register_pernet_subsys(&ip6table_raw_net_ops);
        if (ret < 0)
                return ret;
 
@@ -88,14 +107,14 @@ static int __init ip6table_raw_init(void)
        return ret;
 
  cleanup_table:
-       ip6t_unregister_table(&packet_raw);
+       unregister_pernet_subsys(&ip6table_raw_net_ops);
        return ret;
 }
 
 static void __exit ip6table_raw_fini(void)
 {
        nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
-       ip6t_unregister_table(&packet_raw);
+       unregister_pernet_subsys(&ip6table_raw_net_ops);
 }
 
 module_init(ip6table_raw_init);
index 2d7b0246475d898848290fc38120cd41d1d73aa9..3717bdf34f6edbe63e5615d1320d4f56bdce47fd 100644 (file)
@@ -30,7 +30,8 @@
 static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
                             struct nf_conntrack_tuple *tuple)
 {
-       u_int32_t _addrs[8], *ap;
+       const u_int32_t *ap;
+       u_int32_t _addrs[8];
 
        ap = skb_header_pointer(skb, nhoff + offsetof(struct ipv6hdr, saddr),
                                sizeof(_addrs), _addrs);
@@ -146,8 +147,8 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
                                 int (*okfn)(struct sk_buff *))
 {
        struct nf_conn *ct;
-       struct nf_conn_help *help;
-       struct nf_conntrack_helper *helper;
+       const struct nf_conn_help *help;
+       const struct nf_conntrack_helper *helper;
        enum ip_conntrack_info ctinfo;
        unsigned int ret, protoff;
        unsigned int extoff = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
index da924c6b5f065676f526d723aa5501191ead8862..0897d0f4c4a2d19dfec220d2b6855627526d65b3 100644 (file)
@@ -32,7 +32,8 @@ static int icmpv6_pkt_to_tuple(const struct sk_buff *skb,
                               unsigned int dataoff,
                               struct nf_conntrack_tuple *tuple)
 {
-       struct icmp6hdr _hdr, *hp;
+       const struct icmp6hdr *hp;
+       struct icmp6hdr _hdr;
 
        hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
        if (hp == NULL)
@@ -45,7 +46,7 @@ static int icmpv6_pkt_to_tuple(const struct sk_buff *skb,
 }
 
 /* Add 1; spaces filled with 0. */
-static u_int8_t invmap[] = {
+static const u_int8_t invmap[] = {
        [ICMPV6_ECHO_REQUEST - 128]     = ICMPV6_ECHO_REPLY + 1,
        [ICMPV6_ECHO_REPLY - 128]       = ICMPV6_ECHO_REQUEST + 1,
        [ICMPV6_NI_QUERY - 128]         = ICMPV6_NI_QUERY + 1,
@@ -101,24 +102,24 @@ static int icmpv6_packet(struct nf_conn *ct,
 }
 
 /* Called when a new connection for this protocol found. */
-static int icmpv6_new(struct nf_conn *conntrack,
+static int icmpv6_new(struct nf_conn *ct,
                      const struct sk_buff *skb,
                      unsigned int dataoff)
 {
-       static u_int8_t valid_new[] = {
+       static const u_int8_t valid_new[] = {
                [ICMPV6_ECHO_REQUEST - 128] = 1,
                [ICMPV6_NI_QUERY - 128] = 1
        };
-       int type = conntrack->tuplehash[0].tuple.dst.u.icmp.type - 128;
+       int type = ct->tuplehash[0].tuple.dst.u.icmp.type - 128;
 
        if (type < 0 || type >= sizeof(valid_new) || !valid_new[type]) {
                /* Can't create a new ICMPv6 `conn' with this. */
                pr_debug("icmpv6: can't create new conn with type %u\n",
                         type + 128);
-               NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
+               NF_CT_DUMP_TUPLE(&ct->tuplehash[0].tuple);
                return 0;
        }
-       atomic_set(&conntrack->proto.icmp.count, 0);
+       atomic_set(&ct->proto.icmp.count, 0);
        return 1;
 }
 
@@ -129,8 +130,8 @@ icmpv6_error_message(struct sk_buff *skb,
                     unsigned int hooknum)
 {
        struct nf_conntrack_tuple intuple, origtuple;
-       struct nf_conntrack_tuple_hash *h;
-       struct nf_conntrack_l4proto *inproto;
+       const struct nf_conntrack_tuple_hash *h;
+       const struct nf_conntrack_l4proto *inproto;
 
        NF_CT_ASSERT(skb->nfct == NULL);
 
@@ -176,7 +177,8 @@ static int
 icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
             enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
 {
-       struct icmp6hdr _ih, *icmp6h;
+       const struct icmp6hdr *icmp6h;
+       struct icmp6hdr _ih;
 
        icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
        if (icmp6h == NULL) {
index 022da6ce4c0f3a4548b8ba01fa860d4c8982d116..2a0d698b24d5b3404305c1ebacb7306080bd0a52 100644 (file)
@@ -39,6 +39,7 @@
 #include <net/rawv6.h>
 #include <net/ndisc.h>
 #include <net/addrconf.h>
+#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
 #include <linux/sysctl.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
@@ -680,21 +681,6 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
        nf_conntrack_put_reasm(skb);
 }
 
-int nf_ct_frag6_kfree_frags(struct sk_buff *skb)
-{
-       struct sk_buff *s, *s2;
-
-       for (s = NFCT_FRAG6_CB(skb)->orig; s; s = s2) {
-
-               s2 = s->next;
-               kfree_skb(s);
-       }
-
-       kfree_skb(skb);
-
-       return 0;
-}
-
 int nf_ct_frag6_init(void)
 {
        nf_frags.hashfn = nf_hashfn;
index 4d880551fe6ab327260a09401d2a5a4f3c9e7315..8897ccf8086afacfc643163e89b740cc4a6df13c 100644 (file)
@@ -641,6 +641,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
        skb_reserve(skb, hh_len);
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
        skb->dst = dst_clone(&rt->u.dst);
 
        skb_put(skb, length);
@@ -767,6 +768,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
         */
        memset(&fl, 0, sizeof(fl));
 
+       fl.mark = sk->sk_mark;
+
        if (sin6) {
                if (addr_len < SIN6_LEN_RFC2133)
                        return -EINVAL;
@@ -1259,7 +1262,7 @@ static const struct seq_operations raw6_seq_ops = {
 
 static int raw6_seq_open(struct inode *inode, struct file *file)
 {
-       return raw_seq_open(inode, file, &raw_v6_hashinfo, PF_INET6);
+       return raw_seq_open(inode, file, &raw_v6_hashinfo, &raw6_seq_ops);
 }
 
 static const struct file_operations raw6_seq_fops = {
index 4004c5f0b8d78eec1ad2ae6fbd2a3494645dac5c..513f72e3db0da00dc8f54bd9df7878054e92be33 100644 (file)
@@ -107,6 +107,7 @@ static struct dst_ops ip6_dst_ops = {
        .update_pmtu            =       ip6_rt_update_pmtu,
        .local_out              =       ip6_local_out,
        .entry_size             =       sizeof(struct rt6_info),
+       .entries                =       ATOMIC_INIT(0),
 };
 
 static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -120,6 +121,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
        .check                  =       ip6_dst_check,
        .update_pmtu            =       ip6_rt_blackhole_update_pmtu,
        .entry_size             =       sizeof(struct rt6_info),
+       .entries                =       ATOMIC_INIT(0),
 };
 
 struct rt6_info ip6_null_entry = {
@@ -1907,7 +1909,7 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
         */
        if (rt->rt6i_dev == arg->dev &&
            !dst_metric_locked(&rt->u.dst, RTAX_MTU) &&
-           (dst_mtu(&rt->u.dst) > arg->mtu ||
+           (dst_mtu(&rt->u.dst) >= arg->mtu ||
             (dst_mtu(&rt->u.dst) < arg->mtu &&
              dst_mtu(&rt->u.dst) == idev->cnf.mtu6))) {
                rt->u.dst.metrics[RTAX_MTU-1] = arg->mtu;
@@ -1960,6 +1962,7 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
 
        cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
        cfg->fc_nlinfo.nlh = nlh;
+       cfg->fc_nlinfo.nl_net = skb->sk->sk_net;
 
        if (tb[RTA_GATEWAY]) {
                nla_memcpy(&cfg->fc_gateway, tb[RTA_GATEWAY], 16);
index 00c08399837d00e31d91b26906392367a2bc3a26..59d0029e93a7b3f6123a0a7353eee918e1bd425b 100644 (file)
@@ -330,8 +330,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        struct tcp_sock *tp;
        __u32 seq;
 
-       sk = inet6_lookup(&tcp_hashinfo, &hdr->daddr, th->dest, &hdr->saddr,
-                         th->source, skb->dev->ifindex);
+       sk = inet6_lookup(skb->dev->nd_net, &tcp_hashinfo, &hdr->daddr,
+                       th->dest, &hdr->saddr, th->source, skb->dev->ifindex);
 
        if (sk == NULL) {
                ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
@@ -1208,9 +1208,9 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
        if (req)
                return tcp_check_req(sk, skb, req, prev);
 
-       nsk = __inet6_lookup_established(&tcp_hashinfo, &ipv6_hdr(skb)->saddr,
-                                        th->source, &ipv6_hdr(skb)->daddr,
-                                        ntohs(th->dest), inet6_iif(skb));
+       nsk = __inet6_lookup_established(sk->sk_net, &tcp_hashinfo,
+                       &ipv6_hdr(skb)->saddr, th->source,
+                       &ipv6_hdr(skb)->daddr, ntohs(th->dest), inet6_iif(skb));
 
        if (nsk) {
                if (nsk->sk_state != TCP_TIME_WAIT) {
@@ -1710,9 +1710,10 @@ static int tcp_v6_rcv(struct sk_buff *skb)
        TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb));
        TCP_SKB_CB(skb)->sacked = 0;
 
-       sk = __inet6_lookup(&tcp_hashinfo, &ipv6_hdr(skb)->saddr, th->source,
-                           &ipv6_hdr(skb)->daddr, ntohs(th->dest),
-                           inet6_iif(skb));
+       sk = __inet6_lookup(skb->dev->nd_net, &tcp_hashinfo,
+                       &ipv6_hdr(skb)->saddr, th->source,
+                       &ipv6_hdr(skb)->daddr, ntohs(th->dest),
+                       inet6_iif(skb));
 
        if (!sk)
                goto no_tcp_socket;
@@ -1792,7 +1793,7 @@ do_time_wait:
        {
                struct sock *sk2;
 
-               sk2 = inet6_lookup_listener(&tcp_hashinfo,
+               sk2 = inet6_lookup_listener(skb->dev->nd_net, &tcp_hashinfo,
                                            &ipv6_hdr(skb)->daddr,
                                            ntohs(th->dest), inet6_iif(skb));
                if (sk2 != NULL) {
index bd4b9df8f614018322c6b9176f136d30db3dafac..53739de829db07eb8ad1c3b9ab2b25d4e2b162c5 100644 (file)
@@ -56,7 +56,8 @@ static inline int udp_v6_get_port(struct sock *sk, unsigned short snum)
        return udp_get_port(sk, snum, ipv6_rcv_saddr_equal);
 }
 
-static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,
+static struct sock *__udp6_lib_lookup(struct net *net,
+                                     struct in6_addr *saddr, __be16 sport,
                                      struct in6_addr *daddr, __be16 dport,
                                      int dif, struct hlist_head udptable[])
 {
@@ -69,7 +70,8 @@ static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,
        sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
                struct inet_sock *inet = inet_sk(sk);
 
-               if (sk->sk_hash == hnum && sk->sk_family == PF_INET6) {
+               if (sk->sk_net == net && sk->sk_hash == hnum &&
+                               sk->sk_family == PF_INET6) {
                        struct ipv6_pinfo *np = inet6_sk(sk);
                        int score = 0;
                        if (inet->dport) {
@@ -233,7 +235,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        struct sock *sk;
        int err;
 
-       sk = __udp6_lib_lookup(daddr, uh->dest,
+       sk = __udp6_lib_lookup(skb->dev->nd_net, daddr, uh->dest,
                               saddr, uh->source, inet6_iif(skb), udptable);
        if (sk == NULL)
                return;
@@ -478,7 +480,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
         * check socket cache ... must talk to Alan about his plans
         * for sock caches... i'll skip this for now.
         */
-       sk = __udp6_lib_lookup(saddr, uh->source,
+       sk = __udp6_lib_lookup(skb->dev->nd_net, saddr, uh->source,
                               daddr, uh->dest, inet6_iif(skb), udptable);
 
        if (sk == NULL) {
index c25a6b527fc4e083184e718720f184a752625bc6..7d20199ee1f39cb98c4622042fe9460e4dbd42a7 100644 (file)
@@ -272,6 +272,7 @@ static struct dst_ops xfrm6_dst_ops = {
        .local_out =            __ip6_local_out,
        .gc_thresh =            1024,
        .entry_size =           sizeof(struct xfrm_dst),
+       .entries =              ATOMIC_INIT(0),
 };
 
 static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
index fae90ff310875eac20da4de63c56469ce53237eb..639fe8a6ff1e996c9bcec6c36cb7e70b88d63be8 100644 (file)
@@ -319,7 +319,7 @@ static void xfrm6_tunnel_destroy(struct xfrm_state *x)
        xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr);
 }
 
-static struct xfrm_type xfrm6_tunnel_type = {
+static const struct xfrm_type xfrm6_tunnel_type = {
        .description    = "IP6IP6",
        .owner          = THIS_MODULE,
        .proto          = IPPROTO_IPV6,
index 89e1e3070ec17e048bf9b79606d7b07935c14990..d44c87269bcb782d697e0370ef21fcc3c2ea15e4 100644 (file)
@@ -340,9 +340,42 @@ static u32 ieee80211_rx_load_stats(struct ieee80211_local *local,
        return load;
 }
 
+static ieee80211_txrx_result
+ieee80211_rx_h_verify_ip_alignment(struct ieee80211_txrx_data *rx)
+{
+       int hdrlen;
+
+       /*
+        * Drivers are required to align the payload data in a way that
+        * guarantees that the contained IP header is aligned to a four-
+        * byte boundary. In the case of regular frames, this simply means
+        * aligning the payload to a four-byte boundary (because either
+        * the IP header is directly contained, or IV/RFC1042 headers that
+        * have a length divisible by four are in front of it.
+        *
+        * With A-MSDU frames, however, the payload data address must
+        * yield two modulo four because there are 14-byte 802.3 headers
+        * within the A-MSDU frames that push the IP header further back
+        * to a multiple of four again. Thankfully, the specs were sane
+        * enough this time around to require padding each A-MSDU subframe
+        * to a length that is a multiple of four.
+        *
+        * Padding like atheros hardware adds which is inbetween the 802.11
+        * header and the payload is not supported, the driver is required
+        * to move the 802.11 header further back in that case.
+        */
+       hdrlen = ieee80211_get_hdrlen(rx->fc);
+       if (rx->flags & IEEE80211_TXRXD_RX_AMSDU)
+               hdrlen += ETH_HLEN;
+       WARN_ON_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3);
+
+       return TXRX_CONTINUE;
+}
+
 ieee80211_rx_handler ieee80211_rx_pre_handlers[] =
 {
        ieee80211_rx_h_parse_qos,
+       ieee80211_rx_h_verify_ip_alignment,
        NULL
 };
 
@@ -1679,7 +1712,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
        struct ieee80211_sub_if_data *prev = NULL;
        struct sk_buff *skb_new;
        u8 *bssid;
-       int hdrlen;
 
        hdr = (struct ieee80211_hdr *) skb->data;
        memset(&rx, 0, sizeof(rx));
@@ -1691,18 +1723,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
        rx.fc = le16_to_cpu(hdr->frame_control);
        type = rx.fc & IEEE80211_FCTL_FTYPE;
 
-       /*
-        * Drivers are required to align the payload data to a four-byte
-        * boundary, so the last two bits of the address where it starts
-        * may not be set. The header is required to be directly before
-        * the payload data, padding like atheros hardware adds which is
-        * inbetween the 802.11 header and the payload is not supported,
-        * the driver is required to move the 802.11 header further back
-        * in that case.
-        */
-       hdrlen = ieee80211_get_hdrlen(rx.fc);
-       WARN_ON_ONCE(((unsigned long)(skb->data + hdrlen)) & 3);
-
        if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT)
                local->dot11ReceivedFragmentCount++;
 
@@ -1952,7 +1972,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
                goto end_reorder;
 
        /* null data frames are excluded */
-       if (unlikely(fc & IEEE80211_STYPE_QOS_NULLFUNC))
+       if (unlikely(fc & IEEE80211_STYPE_NULLFUNC))
                goto end_reorder;
 
        /* new un-ordered ampdu frame - process it */
index 078fff0335ad2170ca06a60ad781fcfa0d08018e..327e847d2702d8e647ca656b5e89db6ba2ca74fd 100644 (file)
@@ -40,7 +40,7 @@
 
 #define NF_CONNTRACK_VERSION   "0.5.0"
 
-DEFINE_RWLOCK(nf_conntrack_lock);
+DEFINE_SPINLOCK(nf_conntrack_lock);
 EXPORT_SYMBOL_GPL(nf_conntrack_lock);
 
 /* nf_conntrack_standalone needs this */
@@ -73,15 +73,19 @@ static unsigned int nf_conntrack_hash_rnd;
 static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple,
                                  unsigned int size, unsigned int rnd)
 {
-       unsigned int a, b;
-
-       a = jhash2(tuple->src.u3.all, ARRAY_SIZE(tuple->src.u3.all),
-                  (tuple->src.l3num << 16) | tuple->dst.protonum);
-       b = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
-                  ((__force __u16)tuple->src.u.all << 16) |
-                   (__force __u16)tuple->dst.u.all);
-
-       return ((u64)jhash_2words(a, b, rnd) * size) >> 32;
+       unsigned int n;
+       u_int32_t h;
+
+       /* The direction must be ignored, so we hash everything up to the
+        * destination ports (which is a multiple of 4) and treat the last
+        * three bytes manually.
+        */
+       n = (sizeof(tuple->src) + sizeof(tuple->dst.u3)) / sizeof(u32);
+       h = jhash2((u32 *)tuple, n,
+                  rnd ^ (((__force __u16)tuple->dst.u.all << 16) |
+                         tuple->dst.protonum));
+
+       return ((u64)h * size) >> 32;
 }
 
 static inline u_int32_t hash_conntrack(const struct nf_conntrack_tuple *tuple)
@@ -166,8 +170,8 @@ static void
 clean_from_lists(struct nf_conn *ct)
 {
        pr_debug("clean_from_lists(%p)\n", ct);
-       hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
-       hlist_del(&ct->tuplehash[IP_CT_DIR_REPLY].hnode);
+       hlist_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
+       hlist_del_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode);
 
        /* Destroy all pending expectations */
        nf_ct_remove_expectations(ct);
@@ -199,7 +203,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
 
        rcu_read_unlock();
 
-       write_lock_bh(&nf_conntrack_lock);
+       spin_lock_bh(&nf_conntrack_lock);
        /* Expectations will have been removed in clean_from_lists,
         * except TFTP can create an expectation on the first packet,
         * before connection is in the list, so we need to clean here,
@@ -213,7 +217,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
        }
 
        NF_CT_STAT_INC(delete);
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
 
        if (ct->master)
                nf_ct_put(ct->master);
@@ -236,26 +240,24 @@ static void death_by_timeout(unsigned long ul_conntrack)
                rcu_read_unlock();
        }
 
-       write_lock_bh(&nf_conntrack_lock);
+       spin_lock_bh(&nf_conntrack_lock);
        /* Inside lock so preempt is disabled on module removal path.
         * Otherwise we can get spurious warnings. */
        NF_CT_STAT_INC(delete_list);
        clean_from_lists(ct);
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
        nf_ct_put(ct);
 }
 
 struct nf_conntrack_tuple_hash *
-__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
-                   const struct nf_conn *ignored_conntrack)
+__nf_conntrack_find(const struct nf_conntrack_tuple *tuple)
 {
        struct nf_conntrack_tuple_hash *h;
        struct hlist_node *n;
        unsigned int hash = hash_conntrack(tuple);
 
-       hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) {
-               if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
-                   nf_ct_tuple_equal(tuple, &h->tuple)) {
+       hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) {
+               if (nf_ct_tuple_equal(tuple, &h->tuple)) {
                        NF_CT_STAT_INC(found);
                        return h;
                }
@@ -271,12 +273,16 @@ struct nf_conntrack_tuple_hash *
 nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple)
 {
        struct nf_conntrack_tuple_hash *h;
+       struct nf_conn *ct;
 
-       read_lock_bh(&nf_conntrack_lock);
-       h = __nf_conntrack_find(tuple, NULL);
-       if (h)
-               atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
-       read_unlock_bh(&nf_conntrack_lock);
+       rcu_read_lock();
+       h = __nf_conntrack_find(tuple);
+       if (h) {
+               ct = nf_ct_tuplehash_to_ctrack(h);
+               if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
+                       h = NULL;
+       }
+       rcu_read_unlock();
 
        return h;
 }
@@ -286,10 +292,10 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
                                       unsigned int hash,
                                       unsigned int repl_hash)
 {
-       hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
-                      &nf_conntrack_hash[hash]);
-       hlist_add_head(&ct->tuplehash[IP_CT_DIR_REPLY].hnode,
-                      &nf_conntrack_hash[repl_hash]);
+       hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
+                          &nf_conntrack_hash[hash]);
+       hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode,
+                          &nf_conntrack_hash[repl_hash]);
 }
 
 void nf_conntrack_hash_insert(struct nf_conn *ct)
@@ -299,9 +305,9 @@ void nf_conntrack_hash_insert(struct nf_conn *ct)
        hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
        repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
 
-       write_lock_bh(&nf_conntrack_lock);
+       spin_lock_bh(&nf_conntrack_lock);
        __nf_conntrack_hash_insert(ct, hash, repl_hash);
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_hash_insert);
 
@@ -338,7 +344,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
        NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
        pr_debug("Confirming conntrack %p\n", ct);
 
-       write_lock_bh(&nf_conntrack_lock);
+       spin_lock_bh(&nf_conntrack_lock);
 
        /* See if there's one in the list already, including reverse:
           NAT could have grabbed it without realizing, since we're
@@ -364,7 +370,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
        atomic_inc(&ct->ct_general.use);
        set_bit(IPS_CONFIRMED_BIT, &ct->status);
        NF_CT_STAT_INC(insert);
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
        help = nfct_help(ct);
        if (help && help->helper)
                nf_conntrack_event_cache(IPCT_HELPER, skb);
@@ -379,7 +385,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
 
 out:
        NF_CT_STAT_INC(insert_failed);
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
        return NF_DROP;
 }
 EXPORT_SYMBOL_GPL(__nf_conntrack_confirm);
@@ -391,12 +397,22 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
                         const struct nf_conn *ignored_conntrack)
 {
        struct nf_conntrack_tuple_hash *h;
+       struct hlist_node *n;
+       unsigned int hash = hash_conntrack(tuple);
 
-       read_lock_bh(&nf_conntrack_lock);
-       h = __nf_conntrack_find(tuple, ignored_conntrack);
-       read_unlock_bh(&nf_conntrack_lock);
+       rcu_read_lock();
+       hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) {
+               if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
+                   nf_ct_tuple_equal(tuple, &h->tuple)) {
+                       NF_CT_STAT_INC(found);
+                       rcu_read_unlock();
+                       return 1;
+               }
+               NF_CT_STAT_INC(searched);
+       }
+       rcu_read_unlock();
 
-       return h != NULL;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
 
@@ -404,7 +420,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
 
 /* There's a small race here where we may free a just-assured
    connection.  Too bad: we're in trouble anyway. */
-static int early_drop(unsigned int hash)
+static noinline int early_drop(unsigned int hash)
 {
        /* Use oldest entry, which is roughly LRU */
        struct nf_conntrack_tuple_hash *h;
@@ -413,21 +429,23 @@ static int early_drop(unsigned int hash)
        unsigned int i, cnt = 0;
        int dropped = 0;
 
-       read_lock_bh(&nf_conntrack_lock);
+       rcu_read_lock();
        for (i = 0; i < nf_conntrack_htable_size; i++) {
-               hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) {
+               hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash],
+                                        hnode) {
                        tmp = nf_ct_tuplehash_to_ctrack(h);
                        if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
                                ct = tmp;
                        cnt++;
                }
+
+               if (ct && unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
+                       ct = NULL;
                if (ct || cnt >= NF_CT_EVICTION_RANGE)
                        break;
                hash = (hash + 1) % nf_conntrack_htable_size;
        }
-       if (ct)
-               atomic_inc(&ct->ct_general.use);
-       read_unlock_bh(&nf_conntrack_lock);
+       rcu_read_unlock();
 
        if (!ct)
                return dropped;
@@ -444,7 +462,7 @@ static int early_drop(unsigned int hash)
 struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
                                   const struct nf_conntrack_tuple *repl)
 {
-       struct nf_conn *conntrack = NULL;
+       struct nf_conn *ct = NULL;
 
        if (unlikely(!nf_conntrack_hash_rnd_initted)) {
                get_random_bytes(&nf_conntrack_hash_rnd, 4);
@@ -454,8 +472,8 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
        /* We don't want any race condition at early drop stage */
        atomic_inc(&nf_conntrack_count);
 
-       if (nf_conntrack_max
-           && atomic_read(&nf_conntrack_count) > nf_conntrack_max) {
+       if (nf_conntrack_max &&
+           unlikely(atomic_read(&nf_conntrack_count) > nf_conntrack_max)) {
                unsigned int hash = hash_conntrack(orig);
                if (!early_drop(hash)) {
                        atomic_dec(&nf_conntrack_count);
@@ -467,30 +485,37 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
                }
        }
 
-       conntrack = kmem_cache_zalloc(nf_conntrack_cachep, GFP_ATOMIC);
-       if (conntrack == NULL) {
+       ct = kmem_cache_zalloc(nf_conntrack_cachep, GFP_ATOMIC);
+       if (ct == NULL) {
                pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n");
                atomic_dec(&nf_conntrack_count);
                return ERR_PTR(-ENOMEM);
        }
 
-       atomic_set(&conntrack->ct_general.use, 1);
-       conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
-       conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
+       atomic_set(&ct->ct_general.use, 1);
+       ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
+       ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
        /* Don't set timer yet: wait for confirmation */
-       setup_timer(&conntrack->timeout, death_by_timeout,
-                   (unsigned long)conntrack);
+       setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
+       INIT_RCU_HEAD(&ct->rcu);
 
-       return conntrack;
+       return ct;
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
 
-void nf_conntrack_free(struct nf_conn *conntrack)
+static void nf_conntrack_free_rcu(struct rcu_head *head)
 {
-       nf_ct_ext_free(conntrack);
-       kmem_cache_free(nf_conntrack_cachep, conntrack);
+       struct nf_conn *ct = container_of(head, struct nf_conn, rcu);
+
+       nf_ct_ext_free(ct);
+       kmem_cache_free(nf_conntrack_cachep, ct);
        atomic_dec(&nf_conntrack_count);
 }
+
+void nf_conntrack_free(struct nf_conn *ct)
+{
+       call_rcu(&ct->rcu, nf_conntrack_free_rcu);
+}
 EXPORT_SYMBOL_GPL(nf_conntrack_free);
 
 /* Allocate a new conntrack: we return -ENOMEM if classification
@@ -502,7 +527,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
               struct sk_buff *skb,
               unsigned int dataoff)
 {
-       struct nf_conn *conntrack;
+       struct nf_conn *ct;
        struct nf_conn_help *help;
        struct nf_conntrack_tuple repl_tuple;
        struct nf_conntrack_expect *exp;
@@ -512,46 +537,46 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
                return NULL;
        }
 
-       conntrack = nf_conntrack_alloc(tuple, &repl_tuple);
-       if (conntrack == NULL || IS_ERR(conntrack)) {
+       ct = nf_conntrack_alloc(tuple, &repl_tuple);
+       if (ct == NULL || IS_ERR(ct)) {
                pr_debug("Can't allocate conntrack.\n");
-               return (struct nf_conntrack_tuple_hash *)conntrack;
+               return (struct nf_conntrack_tuple_hash *)ct;
        }
 
-       if (!l4proto->new(conntrack, skb, dataoff)) {
-               nf_conntrack_free(conntrack);
+       if (!l4proto->new(ct, skb, dataoff)) {
+               nf_conntrack_free(ct);
                pr_debug("init conntrack: can't track with proto module\n");
                return NULL;
        }
 
-       write_lock_bh(&nf_conntrack_lock);
+       spin_lock_bh(&nf_conntrack_lock);
        exp = nf_ct_find_expectation(tuple);
        if (exp) {
                pr_debug("conntrack: expectation arrives ct=%p exp=%p\n",
-                        conntrack, exp);
+                        ct, exp);
                /* Welcome, Mr. Bond.  We've been expecting you... */
-               __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
-               conntrack->master = exp->master;
+               __set_bit(IPS_EXPECTED_BIT, &ct->status);
+               ct->master = exp->master;
                if (exp->helper) {
-                       help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
+                       help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
                        if (help)
                                rcu_assign_pointer(help->helper, exp->helper);
                }
 
 #ifdef CONFIG_NF_CONNTRACK_MARK
-               conntrack->mark = exp->master->mark;
+               ct->mark = exp->master->mark;
 #endif
 #ifdef CONFIG_NF_CONNTRACK_SECMARK
-               conntrack->secmark = exp->master->secmark;
+               ct->secmark = exp->master->secmark;
 #endif
-               nf_conntrack_get(&conntrack->master->ct_general);
+               nf_conntrack_get(&ct->master->ct_general);
                NF_CT_STAT_INC(expect_new);
        } else {
                struct nf_conntrack_helper *helper;
 
                helper = __nf_ct_helper_find(&repl_tuple);
                if (helper) {
-                       help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
+                       help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
                        if (help)
                                rcu_assign_pointer(help->helper, helper);
                }
@@ -559,18 +584,17 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
        }
 
        /* Overload tuple linked list to put us in unconfirmed list. */
-       hlist_add_head(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
-                      &unconfirmed);
+       hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode, &unconfirmed);
 
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
 
        if (exp) {
                if (exp->expectfn)
-                       exp->expectfn(conntrack, exp);
+                       exp->expectfn(ct, exp);
                nf_ct_expect_put(exp);
        }
 
-       return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
+       return &ct->tuplehash[IP_CT_DIR_ORIGINAL];
 }
 
 /* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
@@ -729,7 +753,6 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
        struct nf_conn_help *help = nfct_help(ct);
        struct nf_conntrack_helper *helper;
 
-       write_lock_bh(&nf_conntrack_lock);
        /* Should be unconfirmed, so not in hash table yet */
        NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
 
@@ -738,8 +761,9 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
 
        ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
        if (ct->master || (help && help->expecting != 0))
-               goto out;
+               return;
 
+       rcu_read_lock();
        helper = __nf_ct_helper_find(newreply);
        if (helper == NULL) {
                if (help)
@@ -757,7 +781,7 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
 
        rcu_assign_pointer(help->helper, helper);
 out:
-       write_unlock_bh(&nf_conntrack_lock);
+       rcu_read_unlock();
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
 
@@ -773,13 +797,11 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
        NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct);
        NF_CT_ASSERT(skb);
 
-       write_lock_bh(&nf_conntrack_lock);
+       spin_lock_bh(&nf_conntrack_lock);
 
        /* Only update if this is not a fixed timeout */
-       if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) {
-               write_unlock_bh(&nf_conntrack_lock);
-               return;
-       }
+       if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status))
+               goto acct;
 
        /* If not in hash table, timer will not be active yet */
        if (!nf_ct_is_confirmed(ct)) {
@@ -799,6 +821,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
                }
        }
 
+acct:
 #ifdef CONFIG_NF_CT_ACCT
        if (do_acct) {
                ct->counters[CTINFO2DIR(ctinfo)].packets++;
@@ -811,7 +834,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
        }
 #endif
 
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
 
        /* must be unlocked when calling event cache */
        if (event)
@@ -879,14 +902,6 @@ static void nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
        nf_conntrack_get(nskb->nfct);
 }
 
-static inline int
-do_iter(const struct nf_conntrack_tuple_hash *i,
-       int (*iter)(struct nf_conn *i, void *data),
-       void *data)
-{
-       return iter(nf_ct_tuplehash_to_ctrack(i), data);
-}
-
 /* Bring out ya dead! */
 static struct nf_conn *
 get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
@@ -896,7 +911,7 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
        struct nf_conn *ct;
        struct hlist_node *n;
 
-       write_lock_bh(&nf_conntrack_lock);
+       spin_lock_bh(&nf_conntrack_lock);
        for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
                hlist_for_each_entry(h, n, &nf_conntrack_hash[*bucket], hnode) {
                        ct = nf_ct_tuplehash_to_ctrack(h);
@@ -909,11 +924,11 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
                if (iter(ct, data))
                        set_bit(IPS_DYING_BIT, &ct->status);
        }
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
        return NULL;
 found:
        atomic_inc(&ct->ct_general.use);
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
        return ct;
 }
 
@@ -939,7 +954,7 @@ static int kill_all(struct nf_conn *i, void *data)
        return 1;
 }
 
-void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, int size)
+void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, unsigned int size)
 {
        if (vmalloced)
                vfree(hash);
@@ -988,7 +1003,7 @@ void nf_conntrack_cleanup(void)
        nf_conntrack_expect_fini();
 }
 
-struct hlist_head *nf_ct_alloc_hashtable(int *sizep, int *vmalloced)
+struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced)
 {
        struct hlist_head *hash;
        unsigned int size, i;
@@ -1015,8 +1030,8 @@ EXPORT_SYMBOL_GPL(nf_ct_alloc_hashtable);
 
 int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
 {
-       int i, bucket, hashsize, vmalloced;
-       int old_vmalloced, old_size;
+       int i, bucket, vmalloced, old_vmalloced;
+       unsigned int hashsize, old_size;
        int rnd;
        struct hlist_head *hash, *old_hash;
        struct nf_conntrack_tuple_hash *h;
@@ -1025,7 +1040,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
        if (!nf_conntrack_htable_size)
                return param_set_uint(val, kp);
 
-       hashsize = simple_strtol(val, NULL, 0);
+       hashsize = simple_strtoul(val, NULL, 0);
        if (!hashsize)
                return -EINVAL;
 
@@ -1037,12 +1052,17 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
         * use a newrandom seed */
        get_random_bytes(&rnd, 4);
 
-       write_lock_bh(&nf_conntrack_lock);
+       /* Lookups in the old hash might happen in parallel, which means we
+        * might get false negatives during connection lookup. New connections
+        * created because of a false negative won't make it into the hash
+        * though since that required taking the lock.
+        */
+       spin_lock_bh(&nf_conntrack_lock);
        for (i = 0; i < nf_conntrack_htable_size; i++) {
                while (!hlist_empty(&nf_conntrack_hash[i])) {
                        h = hlist_entry(nf_conntrack_hash[i].first,
                                        struct nf_conntrack_tuple_hash, hnode);
-                       hlist_del(&h->hnode);
+                       hlist_del_rcu(&h->hnode);
                        bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
                        hlist_add_head(&h->hnode, &hash[bucket]);
                }
@@ -1055,7 +1075,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
        nf_conntrack_vmalloc = vmalloced;
        nf_conntrack_hash = hash;
        nf_conntrack_hash_rnd = rnd;
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
 
        nf_ct_free_hashtable(old_hash, old_vmalloced, old_size);
        return 0;
index e0cd9d00aa61e872f2f769c142e065a529fcdf23..e06bf0028bb18eaea80e40fb633d4aac495a038f 100644 (file)
@@ -50,7 +50,7 @@ void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
        NF_CT_ASSERT(master_help);
        NF_CT_ASSERT(!timer_pending(&exp->timeout));
 
-       hlist_del(&exp->hnode);
+       hlist_del_rcu(&exp->hnode);
        nf_ct_expect_count--;
 
        hlist_del(&exp->lnode);
@@ -65,9 +65,9 @@ static void nf_ct_expectation_timed_out(unsigned long ul_expect)
 {
        struct nf_conntrack_expect *exp = (void *)ul_expect;
 
-       write_lock_bh(&nf_conntrack_lock);
+       spin_lock_bh(&nf_conntrack_lock);
        nf_ct_unlink_expect(exp);
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
        nf_ct_expect_put(exp);
 }
 
@@ -97,7 +97,7 @@ __nf_ct_expect_find(const struct nf_conntrack_tuple *tuple)
                return NULL;
 
        h = nf_ct_expect_dst_hash(tuple);
-       hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) {
+       hlist_for_each_entry_rcu(i, n, &nf_ct_expect_hash[h], hnode) {
                if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask))
                        return i;
        }
@@ -111,11 +111,11 @@ nf_ct_expect_find_get(const struct nf_conntrack_tuple *tuple)
 {
        struct nf_conntrack_expect *i;
 
-       read_lock_bh(&nf_conntrack_lock);
+       rcu_read_lock();
        i = __nf_ct_expect_find(tuple);
-       if (i)
-               atomic_inc(&i->use);
-       read_unlock_bh(&nf_conntrack_lock);
+       if (i && !atomic_inc_not_zero(&i->use))
+               i = NULL;
+       rcu_read_unlock();
 
        return i;
 }
@@ -201,12 +201,12 @@ static inline int expect_matches(const struct nf_conntrack_expect *a,
 /* Generally a bad idea to call this: could have matched already. */
 void nf_ct_unexpect_related(struct nf_conntrack_expect *exp)
 {
-       write_lock_bh(&nf_conntrack_lock);
+       spin_lock_bh(&nf_conntrack_lock);
        if (del_timer(&exp->timeout)) {
                nf_ct_unlink_expect(exp);
                nf_ct_expect_put(exp);
        }
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
 }
 EXPORT_SYMBOL_GPL(nf_ct_unexpect_related);
 
@@ -223,6 +223,7 @@ struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me)
 
        new->master = me;
        atomic_set(&new->use, 1);
+       INIT_RCU_HEAD(&new->rcu);
        return new;
 }
 EXPORT_SYMBOL_GPL(nf_ct_expect_alloc);
@@ -278,10 +279,18 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
 }
 EXPORT_SYMBOL_GPL(nf_ct_expect_init);
 
+static void nf_ct_expect_free_rcu(struct rcu_head *head)
+{
+       struct nf_conntrack_expect *exp;
+
+       exp = container_of(head, struct nf_conntrack_expect, rcu);
+       kmem_cache_free(nf_ct_expect_cachep, exp);
+}
+
 void nf_ct_expect_put(struct nf_conntrack_expect *exp)
 {
        if (atomic_dec_and_test(&exp->use))
-               kmem_cache_free(nf_ct_expect_cachep, exp);
+               call_rcu(&exp->rcu, nf_ct_expect_free_rcu);
 }
 EXPORT_SYMBOL_GPL(nf_ct_expect_put);
 
@@ -295,7 +304,7 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
        hlist_add_head(&exp->lnode, &master_help->expectations);
        master_help->expecting++;
 
-       hlist_add_head(&exp->hnode, &nf_ct_expect_hash[h]);
+       hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]);
        nf_ct_expect_count++;
 
        setup_timer(&exp->timeout, nf_ct_expectation_timed_out,
@@ -346,7 +355,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
 
        NF_CT_ASSERT(master_help);
 
-       write_lock_bh(&nf_conntrack_lock);
+       spin_lock_bh(&nf_conntrack_lock);
        if (!master_help->helper) {
                ret = -ESHUTDOWN;
                goto out;
@@ -381,7 +390,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
        nf_ct_expect_event(IPEXP_NEW, expect);
        ret = 0;
 out:
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
        return ret;
 }
 EXPORT_SYMBOL_GPL(nf_ct_expect_related);
@@ -394,10 +403,12 @@ struct ct_expect_iter_state {
 static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
 {
        struct ct_expect_iter_state *st = seq->private;
+       struct hlist_node *n;
 
        for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
-               if (!hlist_empty(&nf_ct_expect_hash[st->bucket]))
-                       return nf_ct_expect_hash[st->bucket].first;
+               n = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
+               if (n)
+                       return n;
        }
        return NULL;
 }
@@ -407,11 +418,11 @@ static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
 {
        struct ct_expect_iter_state *st = seq->private;
 
-       head = head->next;
+       head = rcu_dereference(head->next);
        while (head == NULL) {
                if (++st->bucket >= nf_ct_expect_hsize)
                        return NULL;
-               head = nf_ct_expect_hash[st->bucket].first;
+               head = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
        }
        return head;
 }
@@ -427,8 +438,9 @@ static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(RCU)
 {
-       read_lock_bh(&nf_conntrack_lock);
+       rcu_read_lock();
        return ct_expect_get_idx(seq, *pos);
 }
 
@@ -439,8 +451,9 @@ static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void exp_seq_stop(struct seq_file *seq, void *v)
+       __releases(RCU)
 {
-       read_unlock_bh(&nf_conntrack_lock);
+       rcu_read_unlock();
 }
 
 static int exp_seq_show(struct seq_file *s, void *v)
index ff66fba514fd0c2ffe64a78e51bafb5761ceee54..867882313e499931b9e89416326937398a655ccb 100644 (file)
@@ -87,7 +87,7 @@ typedef struct field_t {
        unsigned char ub;
        unsigned short attr;
        unsigned short offset;
-       struct field_t *fields;
+       const struct field_t *fields;
 } field_t;
 
 /* Bit Stream */
@@ -96,7 +96,7 @@ typedef struct {
        unsigned char *beg;
        unsigned char *end;
        unsigned char *cur;
-       unsigned bit;
+       unsigned int bit;
 } bitstr_t;
 
 /* Tool Functions */
@@ -104,29 +104,29 @@ typedef struct {
 #define INC_BITS(bs,b) if(((bs)->bit+=(b))>7){(bs)->cur+=(bs)->bit>>3;(bs)->bit&=7;}
 #define BYTE_ALIGN(bs) if((bs)->bit){(bs)->cur++;(bs)->bit=0;}
 #define CHECK_BOUND(bs,n) if((bs)->cur+(n)>(bs)->end)return(H323_ERROR_BOUND)
-static unsigned get_len(bitstr_t * bs);
-static unsigned get_bit(bitstr_t * bs);
-static unsigned get_bits(bitstr_t * bs, unsigned b);
-static unsigned get_bitmap(bitstr_t * bs, unsigned b);
-static unsigned get_uint(bitstr_t * bs, int b);
+static unsigned int get_len(bitstr_t *bs);
+static unsigned int get_bit(bitstr_t *bs);
+static unsigned int get_bits(bitstr_t *bs, unsigned int b);
+static unsigned int get_bitmap(bitstr_t *bs, unsigned int b);
+static unsigned int get_uint(bitstr_t *bs, int b);
 
 /* Decoder Functions */
-static int decode_nul(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_bool(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_oid(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_int(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_enum(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_seq(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_choice(bitstr_t * bs, field_t * f, char *base, int level);
+static int decode_nul(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_bool(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_oid(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_int(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_enum(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_bitstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_numstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_octstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_bmpstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_seq(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_seqof(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_choice(bitstr_t *bs, const struct field_t *f, char *base, int level);
 
 /* Decoder Functions Vector */
-typedef int (*decoder_t) (bitstr_t *, field_t *, char *, int);
-static decoder_t Decoders[] = {
+typedef int (*decoder_t)(bitstr_t *, const struct field_t *, char *, int);
+static const decoder_t Decoders[] = {
        decode_nul,
        decode_bool,
        decode_oid,
@@ -150,9 +150,9 @@ static decoder_t Decoders[] = {
  * Functions
  ****************************************************************************/
 /* Assume bs is aligned && v < 16384 */
-unsigned get_len(bitstr_t * bs)
+static unsigned int get_len(bitstr_t *bs)
 {
-       unsigned v;
+       unsigned int v;
 
        v = *bs->cur++;
 
@@ -166,9 +166,9 @@ unsigned get_len(bitstr_t * bs)
 }
 
 /****************************************************************************/
-unsigned get_bit(bitstr_t * bs)
+static unsigned int get_bit(bitstr_t *bs)
 {
-       unsigned b = (*bs->cur) & (0x80 >> bs->bit);
+       unsigned int b = (*bs->cur) & (0x80 >> bs->bit);
 
        INC_BIT(bs);
 
@@ -177,9 +177,9 @@ unsigned get_bit(bitstr_t * bs)
 
 /****************************************************************************/
 /* Assume b <= 8 */
-unsigned get_bits(bitstr_t * bs, unsigned b)
+static unsigned int get_bits(bitstr_t *bs, unsigned int b)
 {
-       unsigned v, l;
+       unsigned int v, l;
 
        v = (*bs->cur) & (0xffU >> bs->bit);
        l = b + bs->bit;
@@ -203,9 +203,9 @@ unsigned get_bits(bitstr_t * bs, unsigned b)
 
 /****************************************************************************/
 /* Assume b <= 32 */
-unsigned get_bitmap(bitstr_t * bs, unsigned b)
+static unsigned int get_bitmap(bitstr_t *bs, unsigned int b)
 {
-       unsigned v, l, shift, bytes;
+       unsigned int v, l, shift, bytes;
 
        if (!b)
                return 0;
@@ -213,18 +213,18 @@ unsigned get_bitmap(bitstr_t * bs, unsigned b)
        l = bs->bit + b;
 
        if (l < 8) {
-               v = (unsigned(*bs->cur) << (bs->bit + 24);
+               v = (unsigned int)(*bs->cur) << (bs->bit + 24);
                bs->bit = l;
        } else if (l == 8) {
-               v = (unsigned(*bs->cur++) << (bs->bit + 24);
+               v = (unsigned int)(*bs->cur++) << (bs->bit + 24);
                bs->bit = 0;
        } else {
                for (bytes = l >> 3, shift = 24, v = 0; bytes;
                     bytes--, shift -= 8)
-                       v |= (unsigned(*bs->cur++) << shift;
+                       v |= (unsigned int)(*bs->cur++) << shift;
 
                if (l < 32) {
-                       v |= (unsigned(*bs->cur) << shift;
+                       v |= (unsigned int)(*bs->cur) << shift;
                        v <<= bs->bit;
                } else if (l > 32) {
                        v <<= bs->bit;
@@ -242,9 +242,9 @@ unsigned get_bitmap(bitstr_t * bs, unsigned b)
 /****************************************************************************
  * Assume bs is aligned and sizeof(unsigned int) == 4
  ****************************************************************************/
-unsigned get_uint(bitstr_t * bs, int b)
+static unsigned int get_uint(bitstr_t *bs, int b)
 {
-       unsigned v = 0;
+       unsigned int v = 0;
 
        switch (b) {
        case 4:
@@ -264,7 +264,8 @@ unsigned get_uint(bitstr_t * bs, int b)
 }
 
 /****************************************************************************/
-int decode_nul(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_nul(bitstr_t *bs, const struct field_t *f,
+                      char *base, int level)
 {
        PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
 
@@ -272,7 +273,8 @@ int decode_nul(bitstr_t * bs, field_t * f, char *base, int level)
 }
 
 /****************************************************************************/
-int decode_bool(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_bool(bitstr_t *bs, const struct field_t *f,
+                       char *base, int level)
 {
        PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
 
@@ -283,7 +285,8 @@ int decode_bool(bitstr_t * bs, field_t * f, char *base, int level)
 }
 
 /****************************************************************************/
-int decode_oid(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_oid(bitstr_t *bs, const struct field_t *f,
+                      char *base, int level)
 {
        int len;
 
@@ -299,9 +302,10 @@ int decode_oid(bitstr_t * bs, field_t * f, char *base, int level)
 }
 
 /****************************************************************************/
-int decode_int(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_int(bitstr_t *bs, const struct field_t *f,
+                      char *base, int level)
 {
-       unsigned len;
+       unsigned int len;
 
        PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
 
@@ -318,9 +322,9 @@ int decode_int(bitstr_t * bs, field_t * f, char *base, int level)
                len = get_bits(bs, 2) + 1;
                BYTE_ALIGN(bs);
                if (base && (f->attr & DECODE)) {       /* timeToLive */
-                       unsigned v = get_uint(bs, len) + f->lb;
+                       unsigned int v = get_uint(bs, len) + f->lb;
                        PRINT(" = %u", v);
-                       *((unsigned *) (base + f->offset)) = v;
+                       *((unsigned int *)(base + f->offset)) = v;
                }
                bs->cur += len;
                break;
@@ -342,7 +346,8 @@ int decode_int(bitstr_t * bs, field_t * f, char *base, int level)
 }
 
 /****************************************************************************/
-int decode_enum(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_enum(bitstr_t *bs, const struct field_t *f,
+                       char *base, int level)
 {
        PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
 
@@ -357,9 +362,10 @@ int decode_enum(bitstr_t * bs, field_t * f, char *base, int level)
 }
 
 /****************************************************************************/
-int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_bitstr(bitstr_t *bs, const struct field_t *f,
+                         char *base, int level)
 {
-       unsigned len;
+       unsigned int len;
 
        PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
 
@@ -390,9 +396,10 @@ int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level)
 }
 
 /****************************************************************************/
-int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_numstr(bitstr_t *bs, const struct field_t *f,
+                         char *base, int level)
 {
-       unsigned len;
+       unsigned int len;
 
        PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
 
@@ -407,9 +414,10 @@ int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level)
 }
 
 /****************************************************************************/
-int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_octstr(bitstr_t *bs, const struct field_t *f,
+                         char *base, int level)
 {
-       unsigned len;
+       unsigned int len;
 
        PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
 
@@ -424,7 +432,7 @@ int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level)
                                             bs->cur[0], bs->cur[1],
                                             bs->cur[2], bs->cur[3],
                                             bs->cur[4] * 256 + bs->cur[5]));
-                               *((unsigned *) (base + f->offset)) =
+                               *((unsigned int *)(base + f->offset)) =
                                    bs->cur - bs->buf;
                        }
                }
@@ -455,9 +463,10 @@ int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level)
 }
 
 /****************************************************************************/
-int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_bmpstr(bitstr_t *bs, const struct field_t *f,
+                         char *base, int level)
 {
-       unsigned len;
+       unsigned int len;
 
        PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
 
@@ -480,11 +489,12 @@ int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level)
 }
 
 /****************************************************************************/
-int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_seq(bitstr_t *bs, const struct field_t *f,
+                      char *base, int level)
 {
-       unsigned ext, bmp, i, opt, len = 0, bmp2, bmp2_len;
+       unsigned int ext, bmp, i, opt, len = 0, bmp2, bmp2_len;
        int err;
-       field_t *son;
+       const struct field_t *son;
        unsigned char *beg = NULL;
 
        PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -498,7 +508,7 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
        /* Get fields bitmap */
        bmp = get_bitmap(bs, f->sz);
        if (base)
-               *(unsigned *) base = bmp;
+               *(unsigned int *)base = bmp;
 
        /* Decode the root components */
        for (i = opt = 0, son = f->fields; i < f->lb; i++, son++) {
@@ -550,7 +560,7 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
        bmp2 = get_bitmap(bs, bmp2_len);
        bmp |= bmp2 >> f->sz;
        if (base)
-               *(unsigned *) base = bmp;
+               *(unsigned int *)base = bmp;
        BYTE_ALIGN(bs);
 
        /* Decode the extension components */
@@ -596,11 +606,12 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
 }
 
 /****************************************************************************/
-int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_seqof(bitstr_t *bs, const struct field_t *f,
+                        char *base, int level)
 {
-       unsigned count, effective_count = 0, i, len = 0;
+       unsigned int count, effective_count = 0, i, len = 0;
        int err;
-       field_t *son;
+       const struct field_t *son;
        unsigned char *beg = NULL;
 
        PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -636,8 +647,8 @@ int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level)
        /* Write Count */
        if (base) {
                effective_count = count > f->ub ? f->ub : count;
-               *(unsigned *) base = effective_count;
-               base += sizeof(unsigned);
+               *(unsigned int *)base = effective_count;
+               base += sizeof(unsigned int);
        }
 
        /* Decode nested field */
@@ -685,11 +696,12 @@ int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level)
 
 
 /****************************************************************************/
-int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_choice(bitstr_t *bs, const struct field_t *f,
+                         char *base, int level)
 {
-       unsigned type, ext, len = 0;
+       unsigned int type, ext, len = 0;
        int err;
-       field_t *son;
+       const struct field_t *son;
        unsigned char *beg = NULL;
 
        PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -710,7 +722,7 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
 
        /* Write Type */
        if (base)
-               *(unsigned *) base = type;
+               *(unsigned int *)base = type;
 
        /* Check Range */
        if (type >= f->ub) {    /* Newer version? */
@@ -754,9 +766,9 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
 }
 
 /****************************************************************************/
-int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage * ras)
+int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage *ras)
 {
-       static field_t ras_message = {
+       static const struct field_t ras_message = {
                FNAME("RasMessage") CHOICE, 5, 24, 32, DECODE | EXT,
                0, _RasMessage
        };
@@ -771,9 +783,9 @@ int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage * ras)
 
 /****************************************************************************/
 static int DecodeH323_UserInformation(unsigned char *buf, unsigned char *beg,
-                                     size_t sz, H323_UserInformation * uuie)
+                                     size_t sz, H323_UserInformation *uuie)
 {
-       static field_t h323_userinformation = {
+       static const struct field_t h323_userinformation = {
                FNAME("H323-UserInformation") SEQ, 1, 2, 2, DECODE | EXT,
                0, _H323_UserInformation
        };
@@ -792,7 +804,7 @@ int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz,
                                         MultimediaSystemControlMessage *
                                         mscm)
 {
-       static field_t multimediasystemcontrolmessage = {
+       static const struct field_t multimediasystemcontrolmessage = {
                FNAME("MultimediaSystemControlMessage") CHOICE, 2, 4, 4,
                DECODE | EXT, 0, _MultimediaSystemControlMessage
        };
@@ -807,7 +819,7 @@ int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz,
 }
 
 /****************************************************************************/
-int DecodeQ931(unsigned char *buf, size_t sz, Q931 * q931)
+int DecodeQ931(unsigned char *buf, size_t sz, Q931 *q931)
 {
        unsigned char *p = buf;
        int len;
index 872c1aa3124c2945fae2d8a5be2672d1242a447e..62137879e6aa66e5b9668fac44996f458c46e253 100644 (file)
@@ -114,7 +114,8 @@ static int get_tpkt_data(struct sk_buff *skb, unsigned int protoff,
 {
        struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
        int dir = CTINFO2DIR(ctinfo);
-       struct tcphdr _tcph, *th;
+       const struct tcphdr *th;
+       struct tcphdr _tcph;
        int tcpdatalen;
        int tcpdataoff;
        unsigned char *tpkt;
@@ -212,11 +213,11 @@ static int get_tpkt_data(struct sk_buff *skb, unsigned int protoff,
 }
 
 /****************************************************************************/
-static int get_h245_addr(struct nf_conn *ct, unsigned char *data,
+static int get_h245_addr(struct nf_conn *ct, const unsigned char *data,
                         H245_TransportAddress *taddr,
                         union nf_inet_addr *addr, __be16 *port)
 {
-       unsigned char *p;
+       const unsigned char *p;
        int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
        int len;
 
@@ -625,7 +626,7 @@ int get_h225_addr(struct nf_conn *ct, unsigned char *data,
                  TransportAddress *taddr,
                  union nf_inet_addr *addr, __be16 *port)
 {
-       unsigned char *p;
+       const unsigned char *p;
        int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
        int len;
 
@@ -704,9 +705,8 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
 
 /* If the calling party is on the same side of the forward-to party,
  * we don't need to track the second call */
-static int callforward_do_filter(union nf_inet_addr *src,
-                                union nf_inet_addr *dst,
-                                int family)
+static int callforward_do_filter(const union nf_inet_addr *src,
+                                 const union nf_inet_addr *dst, int family)
 {
        const struct nf_afinfo *afinfo;
        struct flowi fl1, fl2;
@@ -1185,7 +1185,8 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
 static unsigned char *get_udp_data(struct sk_buff *skb, unsigned int protoff,
                                   int *datalen)
 {
-       struct udphdr _uh, *uh;
+       const struct udphdr *uh;
+       struct udphdr _uh;
        int dataoff;
 
        uh = skb_header_pointer(skb, protoff, sizeof(_uh), &_uh);
@@ -1415,7 +1416,7 @@ static int process_rcf(struct sk_buff *skb, struct nf_conn *ct,
                nf_ct_refresh(ct, skb, info->timeout * HZ);
 
                /* Set expect timeout */
-               read_lock_bh(&nf_conntrack_lock);
+               spin_lock_bh(&nf_conntrack_lock);
                exp = find_expect(ct, &ct->tuplehash[dir].tuple.dst.u3,
                                  info->sig_port[!dir]);
                if (exp) {
@@ -1425,7 +1426,7 @@ static int process_rcf(struct sk_buff *skb, struct nf_conn *ct,
                        NF_CT_DUMP_TUPLE(&exp->tuple);
                        set_expect_timeout(exp, info->timeout);
                }
-               read_unlock_bh(&nf_conntrack_lock);
+               spin_unlock_bh(&nf_conntrack_lock);
        }
 
        return 0;
@@ -1468,7 +1469,7 @@ static int process_arq(struct sk_buff *skb, struct nf_conn *ct,
                       enum ip_conntrack_info ctinfo,
                       unsigned char **data, AdmissionRequest *arq)
 {
-       struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
+       const struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
        int dir = CTINFO2DIR(ctinfo);
        __be16 port;
        union nf_inet_addr addr;
index 3a21fdf1a2654ce8bedbccf8fda781da59919e0a..d880f3523c1de8aaccdcca90e3036cdc50015b9c 100644 (file)
@@ -5,22 +5,22 @@
  * This source code is licensed under General Public License version 2.
  */
 
-static field_t _TransportAddress_ipAddress[] = {       /* SEQUENCE */
+static const struct field_t _TransportAddress_ipAddress[] = {  /* SEQUENCE */
        {FNAME("ip") OCTSTR, FIXD, 4, 0, DECODE,
         offsetof(TransportAddress_ipAddress, ip), NULL},
        {FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _TransportAddress_ipSourceRoute_route[] = {     /* SEQUENCE OF */
+static const struct field_t _TransportAddress_ipSourceRoute_route[] = {        /* SEQUENCE OF */
        {FNAME("item") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
 };
 
-static field_t _TransportAddress_ipSourceRoute_routing[] = {   /* CHOICE */
+static const struct field_t _TransportAddress_ipSourceRoute_routing[] = {      /* CHOICE */
        {FNAME("strict") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("loose") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _TransportAddress_ipSourceRoute[] = {   /* SEQUENCE */
+static const struct field_t _TransportAddress_ipSourceRoute[] = {      /* SEQUENCE */
        {FNAME("ip") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
        {FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
        {FNAME("route") SEQOF, SEMI, 0, 0, SKIP, 0,
@@ -29,37 +29,37 @@ static field_t _TransportAddress_ipSourceRoute[] = {        /* SEQUENCE */
         _TransportAddress_ipSourceRoute_routing},
 };
 
-static field_t _TransportAddress_ipxAddress[] = {      /* SEQUENCE */
+static const struct field_t _TransportAddress_ipxAddress[] = { /* SEQUENCE */
        {FNAME("node") OCTSTR, FIXD, 6, 0, SKIP, 0, NULL},
        {FNAME("netnum") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
        {FNAME("port") OCTSTR, FIXD, 2, 0, SKIP, 0, NULL},
 };
 
-static field_t _TransportAddress_ip6Address[] = {      /* SEQUENCE */
+static const struct field_t _TransportAddress_ip6Address[] = { /* SEQUENCE */
        {FNAME("ip") OCTSTR, FIXD, 16, 0, DECODE,
         offsetof(TransportAddress_ip6Address, ip), NULL},
        {FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _H221NonStandard[] = {  /* SEQUENCE */
+static const struct field_t _H221NonStandard[] = {     /* SEQUENCE */
        {FNAME("t35CountryCode") INT, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("t35Extension") INT, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("manufacturerCode") INT, WORD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _NonStandardIdentifier[] = {    /* CHOICE */
+static const struct field_t _NonStandardIdentifier[] = {       /* CHOICE */
        {FNAME("object") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("h221NonStandard") SEQ, 0, 3, 3, SKIP | EXT, 0,
         _H221NonStandard},
 };
 
-static field_t _NonStandardParameter[] = {     /* SEQUENCE */
+static const struct field_t _NonStandardParameter[] = {        /* SEQUENCE */
        {FNAME("nonStandardIdentifier") CHOICE, 1, 2, 2, SKIP | EXT, 0,
         _NonStandardIdentifier},
        {FNAME("data") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _TransportAddress[] = { /* CHOICE */
+static const struct field_t _TransportAddress[] = {    /* CHOICE */
        {FNAME("ipAddress") SEQ, 0, 2, 2, DECODE,
         offsetof(TransportAddress, ipAddress), _TransportAddress_ipAddress},
        {FNAME("ipSourceRoute") SEQ, 0, 4, 4, SKIP | EXT, 0,
@@ -75,7 +75,7 @@ static field_t _TransportAddress[] = {        /* CHOICE */
         _NonStandardParameter},
 };
 
-static field_t _AliasAddress[] = {     /* CHOICE */
+static const struct field_t _AliasAddress[] = {        /* CHOICE */
        {FNAME("dialedDigits") NUMDGT, 7, 1, 0, SKIP, 0, NULL},
        {FNAME("h323-ID") BMPSTR, BYTE, 1, 0, SKIP, 0, NULL},
        {FNAME("url-ID") IA5STR, WORD, 1, 0, SKIP, 0, NULL},
@@ -85,78 +85,78 @@ static field_t _AliasAddress[] = {  /* CHOICE */
        {FNAME("mobileUIM") CHOICE, 1, 2, 2, SKIP | EXT, 0, NULL},
 };
 
-static field_t _Setup_UUIE_sourceAddress[] = { /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_sourceAddress[] = {    /* SEQUENCE OF */
        {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
 };
 
-static field_t _VendorIdentifier[] = { /* SEQUENCE */
+static const struct field_t _VendorIdentifier[] = {    /* SEQUENCE */
        {FNAME("vendor") SEQ, 0, 3, 3, SKIP | EXT, 0, _H221NonStandard},
        {FNAME("productId") OCTSTR, BYTE, 1, 0, SKIP | OPT, 0, NULL},
        {FNAME("versionId") OCTSTR, BYTE, 1, 0, SKIP | OPT, 0, NULL},
 };
 
-static field_t _GatekeeperInfo[] = {   /* SEQUENCE */
+static const struct field_t _GatekeeperInfo[] = {      /* SEQUENCE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
 };
 
-static field_t _H310Caps[] = { /* SEQUENCE */
+static const struct field_t _H310Caps[] = {    /* SEQUENCE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
        {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _H320Caps[] = { /* SEQUENCE */
+static const struct field_t _H320Caps[] = {    /* SEQUENCE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
        {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _H321Caps[] = { /* SEQUENCE */
+static const struct field_t _H321Caps[] = {    /* SEQUENCE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
        {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _H322Caps[] = { /* SEQUENCE */
+static const struct field_t _H322Caps[] = {    /* SEQUENCE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
        {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _H323Caps[] = { /* SEQUENCE */
+static const struct field_t _H323Caps[] = {    /* SEQUENCE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
        {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _H324Caps[] = { /* SEQUENCE */
+static const struct field_t _H324Caps[] = {    /* SEQUENCE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
        {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _VoiceCaps[] = {        /* SEQUENCE */
+static const struct field_t _VoiceCaps[] = {   /* SEQUENCE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
        {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _T120OnlyCaps[] = {     /* SEQUENCE */
+static const struct field_t _T120OnlyCaps[] = {        /* SEQUENCE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
        {FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _SupportedProtocols[] = {       /* CHOICE */
+static const struct field_t _SupportedProtocols[] = {  /* CHOICE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP, 0,
         _NonStandardParameter},
        {FNAME("h310") SEQ, 1, 1, 3, SKIP | EXT, 0, _H310Caps},
@@ -171,29 +171,29 @@ static field_t _SupportedProtocols[] = {  /* CHOICE */
        {FNAME("t38FaxAnnexbOnly") SEQ, 2, 5, 5, SKIP | EXT, 0, NULL},
 };
 
-static field_t _GatewayInfo_protocol[] = {     /* SEQUENCE OF */
+static const struct field_t _GatewayInfo_protocol[] = {        /* SEQUENCE OF */
        {FNAME("item") CHOICE, 4, 9, 11, SKIP | EXT, 0, _SupportedProtocols},
 };
 
-static field_t _GatewayInfo[] = {      /* SEQUENCE */
+static const struct field_t _GatewayInfo[] = { /* SEQUENCE */
        {FNAME("protocol") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
         _GatewayInfo_protocol},
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
 };
 
-static field_t _McuInfo[] = {  /* SEQUENCE */
+static const struct field_t _McuInfo[] = {     /* SEQUENCE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
        {FNAME("protocol") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
 };
 
-static field_t _TerminalInfo[] = {     /* SEQUENCE */
+static const struct field_t _TerminalInfo[] = {        /* SEQUENCE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
 };
 
-static field_t _EndpointType[] = {     /* SEQUENCE */
+static const struct field_t _EndpointType[] = {        /* SEQUENCE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
        {FNAME("vendor") SEQ, 2, 3, 3, SKIP | EXT | OPT, 0,
@@ -210,19 +210,19 @@ static field_t _EndpointType[] = {        /* SEQUENCE */
         0, NULL},
 };
 
-static field_t _Setup_UUIE_destinationAddress[] = {    /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_destinationAddress[] = {       /* SEQUENCE OF */
        {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
 };
 
-static field_t _Setup_UUIE_destExtraCallInfo[] = {     /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_destExtraCallInfo[] = {        /* SEQUENCE OF */
        {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
 };
 
-static field_t _Setup_UUIE_destExtraCRV[] = {  /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_destExtraCRV[] = {     /* SEQUENCE OF */
        {FNAME("item") INT, WORD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _Setup_UUIE_conferenceGoal[] = {        /* CHOICE */
+static const struct field_t _Setup_UUIE_conferenceGoal[] = {   /* CHOICE */
        {FNAME("create") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("join") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("invite") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -231,12 +231,12 @@ static field_t _Setup_UUIE_conferenceGoal[] = {   /* CHOICE */
         0, NULL},
 };
 
-static field_t _Q954Details[] = {      /* SEQUENCE */
+static const struct field_t _Q954Details[] = { /* SEQUENCE */
        {FNAME("conferenceCalling") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("threePartyService") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _QseriesOptions[] = {   /* SEQUENCE */
+static const struct field_t _QseriesOptions[] = {      /* SEQUENCE */
        {FNAME("q932Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("q951Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("q952Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -247,32 +247,32 @@ static field_t _QseriesOptions[] = {      /* SEQUENCE */
        {FNAME("q954Info") SEQ, 0, 2, 2, SKIP | EXT, 0, _Q954Details},
 };
 
-static field_t _CallType[] = { /* CHOICE */
+static const struct field_t _CallType[] = {    /* CHOICE */
        {FNAME("pointToPoint") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("oneToN") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("nToOne") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("nToN") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _H245_NonStandardIdentifier_h221NonStandard[] = {       /* SEQUENCE */
+static const struct field_t _H245_NonStandardIdentifier_h221NonStandard[] = {  /* SEQUENCE */
        {FNAME("t35CountryCode") INT, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("t35Extension") INT, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("manufacturerCode") INT, WORD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _H245_NonStandardIdentifier[] = {       /* CHOICE */
+static const struct field_t _H245_NonStandardIdentifier[] = {  /* CHOICE */
        {FNAME("object") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("h221NonStandard") SEQ, 0, 3, 3, SKIP, 0,
         _H245_NonStandardIdentifier_h221NonStandard},
 };
 
-static field_t _H245_NonStandardParameter[] = {        /* SEQUENCE */
+static const struct field_t _H245_NonStandardParameter[] = {   /* SEQUENCE */
        {FNAME("nonStandardIdentifier") CHOICE, 1, 2, 2, SKIP, 0,
         _H245_NonStandardIdentifier},
        {FNAME("data") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _H261VideoCapability[] = {      /* SEQUENCE */
+static const struct field_t _H261VideoCapability[] = { /* SEQUENCE */
        {FNAME("qcifMPI") INT, 2, 1, 0, SKIP | OPT, 0, NULL},
        {FNAME("cifMPI") INT, 2, 1, 0, SKIP | OPT, 0, NULL},
        {FNAME("temporalSpatialTradeOffCapability") BOOL, FIXD, 0, 0, SKIP, 0,
@@ -282,7 +282,7 @@ static field_t _H261VideoCapability[] = {   /* SEQUENCE */
        {FNAME("videoBadMBsCap") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _H262VideoCapability[] = {      /* SEQUENCE */
+static const struct field_t _H262VideoCapability[] = { /* SEQUENCE */
        {FNAME("profileAndLevel-SPatML") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("profileAndLevel-MPatLL") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("profileAndLevel-MPatML") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -304,7 +304,7 @@ static field_t _H262VideoCapability[] = {   /* SEQUENCE */
        {FNAME("videoBadMBsCap") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _H263VideoCapability[] = {      /* SEQUENCE */
+static const struct field_t _H263VideoCapability[] = { /* SEQUENCE */
        {FNAME("sqcifMPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
        {FNAME("qcifMPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
        {FNAME("cifMPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
@@ -330,7 +330,7 @@ static field_t _H263VideoCapability[] = {   /* SEQUENCE */
        {FNAME("h263Options") SEQ, 5, 29, 31, SKIP | EXT | OPT, 0, NULL},
 };
 
-static field_t _IS11172VideoCapability[] = {   /* SEQUENCE */
+static const struct field_t _IS11172VideoCapability[] = {      /* SEQUENCE */
        {FNAME("constrainedBitstream") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("videoBitRate") INT, CONS, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("vbvBufferSize") INT, CONS, 0, 0, SKIP | OPT, 0, NULL},
@@ -341,7 +341,7 @@ static field_t _IS11172VideoCapability[] = {        /* SEQUENCE */
        {FNAME("videoBadMBsCap") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _VideoCapability[] = {  /* CHOICE */
+static const struct field_t _VideoCapability[] = {     /* CHOICE */
        {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
         _H245_NonStandardParameter},
        {FNAME("h261VideoCapability") SEQ, 2, 5, 6, SKIP | EXT, 0,
@@ -355,12 +355,12 @@ static field_t _VideoCapability[] = {     /* CHOICE */
        {FNAME("genericVideoCapability") SEQ, 5, 6, 6, SKIP | EXT, 0, NULL},
 };
 
-static field_t _AudioCapability_g7231[] = {    /* SEQUENCE */
+static const struct field_t _AudioCapability_g7231[] = {       /* SEQUENCE */
        {FNAME("maxAl-sduAudioFrames") INT, BYTE, 1, 0, SKIP, 0, NULL},
        {FNAME("silenceSuppression") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _IS11172AudioCapability[] = {   /* SEQUENCE */
+static const struct field_t _IS11172AudioCapability[] = {      /* SEQUENCE */
        {FNAME("audioLayer1") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("audioLayer2") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("audioLayer3") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -372,7 +372,7 @@ static field_t _IS11172AudioCapability[] = {        /* SEQUENCE */
        {FNAME("bitRate") INT, WORD, 1, 0, SKIP, 0, NULL},
 };
 
-static field_t _IS13818AudioCapability[] = {   /* SEQUENCE */
+static const struct field_t _IS13818AudioCapability[] = {      /* SEQUENCE */
        {FNAME("audioLayer1") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("audioLayer2") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("audioLayer3") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -396,7 +396,7 @@ static field_t _IS13818AudioCapability[] = {        /* SEQUENCE */
        {FNAME("bitRate") INT, WORD, 1, 0, SKIP, 0, NULL},
 };
 
-static field_t _AudioCapability[] = {  /* CHOICE */
+static const struct field_t _AudioCapability[] = {     /* CHOICE */
        {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
         _H245_NonStandardParameter},
        {FNAME("g711Alaw64k") INT, BYTE, 1, 0, SKIP, 0, NULL},
@@ -424,7 +424,7 @@ static field_t _AudioCapability[] = {       /* CHOICE */
        {FNAME("g729Extensions") SEQ, 1, 8, 8, SKIP | EXT, 0, NULL},
 };
 
-static field_t _DataProtocolCapability[] = {   /* CHOICE */
+static const struct field_t _DataProtocolCapability[] = {      /* CHOICE */
        {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
         _H245_NonStandardParameter},
        {FNAME("v14buffered") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -442,7 +442,7 @@ static field_t _DataProtocolCapability[] = {        /* CHOICE */
        {FNAME("udp") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _T84Profile_t84Restricted[] = { /* SEQUENCE */
+static const struct field_t _T84Profile_t84Restricted[] = {    /* SEQUENCE */
        {FNAME("qcif") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("cif") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("ccir601Seq") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -464,25 +464,25 @@ static field_t _T84Profile_t84Restricted[] = {    /* SEQUENCE */
        {FNAME("digPhotoHighProg") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _T84Profile[] = {       /* CHOICE */
+static const struct field_t _T84Profile[] = {  /* CHOICE */
        {FNAME("t84Unrestricted") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("t84Restricted") SEQ, 0, 19, 19, SKIP | EXT, 0,
         _T84Profile_t84Restricted},
 };
 
-static field_t _DataApplicationCapability_application_t84[] = {        /* SEQUENCE */
+static const struct field_t _DataApplicationCapability_application_t84[] = {   /* SEQUENCE */
        {FNAME("t84Protocol") CHOICE, 3, 7, 14, SKIP | EXT, 0,
         _DataProtocolCapability},
        {FNAME("t84Profile") CHOICE, 1, 2, 2, SKIP, 0, _T84Profile},
 };
 
-static field_t _DataApplicationCapability_application_nlpid[] = {      /* SEQUENCE */
+static const struct field_t _DataApplicationCapability_application_nlpid[] = { /* SEQUENCE */
        {FNAME("nlpidProtocol") CHOICE, 3, 7, 14, SKIP | EXT, 0,
         _DataProtocolCapability},
        {FNAME("nlpidData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _DataApplicationCapability_application[] = {    /* CHOICE */
+static const struct field_t _DataApplicationCapability_application[] = {       /* CHOICE */
        {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
         _H245_NonStandardParameter},
        {FNAME("t120") CHOICE, 3, 7, 14, DECODE | EXT,
@@ -509,20 +509,20 @@ static field_t _DataApplicationCapability_application[] = {       /* CHOICE */
        {FNAME("genericDataCapability") SEQ, 5, 6, 6, SKIP | EXT, 0, NULL},
 };
 
-static field_t _DataApplicationCapability[] = {        /* SEQUENCE */
+static const struct field_t _DataApplicationCapability[] = {   /* SEQUENCE */
        {FNAME("application") CHOICE, 4, 10, 14, DECODE | EXT,
         offsetof(DataApplicationCapability, application),
         _DataApplicationCapability_application},
        {FNAME("maxBitRate") INT, CONS, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _EncryptionMode[] = {   /* CHOICE */
+static const struct field_t _EncryptionMode[] = {      /* CHOICE */
        {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
         _H245_NonStandardParameter},
        {FNAME("h233Encryption") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _DataType[] = { /* CHOICE */
+static const struct field_t _DataType[] = {    /* CHOICE */
        {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
         _H245_NonStandardParameter},
        {FNAME("nullData") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -538,7 +538,7 @@ static field_t _DataType[] = {      /* CHOICE */
        {FNAME("multiplexedStream") SEQ, 0, 2, 2, SKIP | EXT, 0, NULL},
 };
 
-static field_t _H222LogicalChannelParameters[] = {     /* SEQUENCE */
+static const struct field_t _H222LogicalChannelParameters[] = {        /* SEQUENCE */
        {FNAME("resourceID") INT, WORD, 0, 0, SKIP, 0, NULL},
        {FNAME("subChannelID") INT, WORD, 0, 0, SKIP, 0, NULL},
        {FNAME("pcr-pid") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
@@ -546,12 +546,12 @@ static field_t _H222LogicalChannelParameters[] = {        /* SEQUENCE */
        {FNAME("streamDescriptors") OCTSTR, SEMI, 0, 0, SKIP | OPT, 0, NULL},
 };
 
-static field_t _H223LogicalChannelParameters_adaptationLayerType_al3[] = {     /* SEQUENCE */
+static const struct field_t _H223LogicalChannelParameters_adaptationLayerType_al3[] = {        /* SEQUENCE */
        {FNAME("controlFieldOctets") INT, 2, 0, 0, SKIP, 0, NULL},
        {FNAME("sendBufferSize") INT, CONS, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _H223LogicalChannelParameters_adaptationLayerType[] = { /* CHOICE */
+static const struct field_t _H223LogicalChannelParameters_adaptationLayerType[] = {    /* CHOICE */
        {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
         _H245_NonStandardParameter},
        {FNAME("al1Framed") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -565,53 +565,53 @@ static field_t _H223LogicalChannelParameters_adaptationLayerType[] = {    /* CHOICE
        {FNAME("al3M") SEQ, 0, 5, 6, SKIP | EXT, 0, NULL},
 };
 
-static field_t _H223LogicalChannelParameters[] = {     /* SEQUENCE */
+static const struct field_t _H223LogicalChannelParameters[] = {        /* SEQUENCE */
        {FNAME("adaptationLayerType") CHOICE, 3, 6, 9, SKIP | EXT, 0,
         _H223LogicalChannelParameters_adaptationLayerType},
        {FNAME("segmentableFlag") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _CRCLength[] = {        /* CHOICE */
+static const struct field_t _CRCLength[] = {   /* CHOICE */
        {FNAME("crc8bit") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("crc16bit") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("crc32bit") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _V76HDLCParameters[] = {        /* SEQUENCE */
+static const struct field_t _V76HDLCParameters[] = {   /* SEQUENCE */
        {FNAME("crcLength") CHOICE, 2, 3, 3, SKIP | EXT, 0, _CRCLength},
        {FNAME("n401") INT, WORD, 1, 0, SKIP, 0, NULL},
        {FNAME("loopbackTestProcedure") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _V76LogicalChannelParameters_suspendResume[] = {        /* CHOICE */
+static const struct field_t _V76LogicalChannelParameters_suspendResume[] = {   /* CHOICE */
        {FNAME("noSuspendResume") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("suspendResumewAddress") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("suspendResumewoAddress") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _V76LogicalChannelParameters_mode_eRM_recovery[] = {    /* CHOICE */
+static const struct field_t _V76LogicalChannelParameters_mode_eRM_recovery[] = {       /* CHOICE */
        {FNAME("rej") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("sREJ") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("mSREJ") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _V76LogicalChannelParameters_mode_eRM[] = {     /* SEQUENCE */
+static const struct field_t _V76LogicalChannelParameters_mode_eRM[] = {        /* SEQUENCE */
        {FNAME("windowSize") INT, 7, 1, 0, SKIP, 0, NULL},
        {FNAME("recovery") CHOICE, 2, 3, 3, SKIP | EXT, 0,
         _V76LogicalChannelParameters_mode_eRM_recovery},
 };
 
-static field_t _V76LogicalChannelParameters_mode[] = { /* CHOICE */
+static const struct field_t _V76LogicalChannelParameters_mode[] = {    /* CHOICE */
        {FNAME("eRM") SEQ, 0, 2, 2, SKIP | EXT, 0,
         _V76LogicalChannelParameters_mode_eRM},
        {FNAME("uNERM") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _V75Parameters[] = {    /* SEQUENCE */
+static const struct field_t _V75Parameters[] = {       /* SEQUENCE */
        {FNAME("audioHeaderPresent") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _V76LogicalChannelParameters[] = {      /* SEQUENCE */
+static const struct field_t _V76LogicalChannelParameters[] = { /* SEQUENCE */
        {FNAME("hdlcParameters") SEQ, 0, 3, 3, SKIP | EXT, 0,
         _V76HDLCParameters},
        {FNAME("suspendResume") CHOICE, 2, 3, 3, SKIP | EXT, 0,
@@ -622,38 +622,38 @@ static field_t _V76LogicalChannelParameters[] = { /* SEQUENCE */
        {FNAME("v75Parameters") SEQ, 0, 1, 1, SKIP | EXT, 0, _V75Parameters},
 };
 
-static field_t _H2250LogicalChannelParameters_nonStandard[] = {        /* SEQUENCE OF */
+static const struct field_t _H2250LogicalChannelParameters_nonStandard[] = {   /* SEQUENCE OF */
        {FNAME("item") SEQ, 0, 2, 2, SKIP, 0, _H245_NonStandardParameter},
 };
 
-static field_t _UnicastAddress_iPAddress[] = { /* SEQUENCE */
+static const struct field_t _UnicastAddress_iPAddress[] = {    /* SEQUENCE */
        {FNAME("network") OCTSTR, FIXD, 4, 0, DECODE,
         offsetof(UnicastAddress_iPAddress, network), NULL},
        {FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _UnicastAddress_iPXAddress[] = {        /* SEQUENCE */
+static const struct field_t _UnicastAddress_iPXAddress[] = {   /* SEQUENCE */
        {FNAME("node") OCTSTR, FIXD, 6, 0, SKIP, 0, NULL},
        {FNAME("netnum") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
        {FNAME("tsapIdentifier") OCTSTR, FIXD, 2, 0, SKIP, 0, NULL},
 };
 
-static field_t _UnicastAddress_iP6Address[] = {        /* SEQUENCE */
+static const struct field_t _UnicastAddress_iP6Address[] = {   /* SEQUENCE */
        {FNAME("network") OCTSTR, FIXD, 16, 0, DECODE,
         offsetof(UnicastAddress_iP6Address, network), NULL},
        {FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _UnicastAddress_iPSourceRouteAddress_routing[] = {      /* CHOICE */
+static const struct field_t _UnicastAddress_iPSourceRouteAddress_routing[] = { /* CHOICE */
        {FNAME("strict") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("loose") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _UnicastAddress_iPSourceRouteAddress_route[] = {        /* SEQUENCE OF */
+static const struct field_t _UnicastAddress_iPSourceRouteAddress_route[] = {   /* SEQUENCE OF */
        {FNAME("item") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
 };
 
-static field_t _UnicastAddress_iPSourceRouteAddress[] = {      /* SEQUENCE */
+static const struct field_t _UnicastAddress_iPSourceRouteAddress[] = { /* SEQUENCE */
        {FNAME("routing") CHOICE, 1, 2, 2, SKIP, 0,
         _UnicastAddress_iPSourceRouteAddress_routing},
        {FNAME("network") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
@@ -662,7 +662,7 @@ static field_t _UnicastAddress_iPSourceRouteAddress[] = {   /* SEQUENCE */
         _UnicastAddress_iPSourceRouteAddress_route},
 };
 
-static field_t _UnicastAddress[] = {   /* CHOICE */
+static const struct field_t _UnicastAddress[] = {      /* CHOICE */
        {FNAME("iPAddress") SEQ, 0, 2, 2, DECODE | EXT,
         offsetof(UnicastAddress, iPAddress), _UnicastAddress_iPAddress},
        {FNAME("iPXAddress") SEQ, 0, 3, 3, SKIP | EXT, 0,
@@ -676,17 +676,17 @@ static field_t _UnicastAddress[] = {      /* CHOICE */
        {FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0, NULL},
 };
 
-static field_t _MulticastAddress_iPAddress[] = {       /* SEQUENCE */
+static const struct field_t _MulticastAddress_iPAddress[] = {  /* SEQUENCE */
        {FNAME("network") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
        {FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _MulticastAddress_iP6Address[] = {      /* SEQUENCE */
+static const struct field_t _MulticastAddress_iP6Address[] = { /* SEQUENCE */
        {FNAME("network") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
        {FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _MulticastAddress[] = { /* CHOICE */
+static const struct field_t _MulticastAddress[] = {    /* CHOICE */
        {FNAME("iPAddress") SEQ, 0, 2, 2, SKIP | EXT, 0,
         _MulticastAddress_iPAddress},
        {FNAME("iP6Address") SEQ, 0, 2, 2, SKIP | EXT, 0,
@@ -695,14 +695,14 @@ static field_t _MulticastAddress[] = {    /* CHOICE */
        {FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0, NULL},
 };
 
-static field_t _H245_TransportAddress[] = {    /* CHOICE */
+static const struct field_t _H245_TransportAddress[] = {       /* CHOICE */
        {FNAME("unicastAddress") CHOICE, 3, 5, 7, DECODE | EXT,
         offsetof(H245_TransportAddress, unicastAddress), _UnicastAddress},
        {FNAME("multicastAddress") CHOICE, 1, 2, 4, SKIP | EXT, 0,
         _MulticastAddress},
 };
 
-static field_t _H2250LogicalChannelParameters[] = {    /* SEQUENCE */
+static const struct field_t _H2250LogicalChannelParameters[] = {       /* SEQUENCE */
        {FNAME("nonStandard") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
         _H2250LogicalChannelParameters_nonStandard},
        {FNAME("sessionID") INT, BYTE, 0, 0, SKIP, 0, NULL},
@@ -728,7 +728,7 @@ static field_t _H2250LogicalChannelParameters[] = { /* SEQUENCE */
        {FNAME("source") SEQ, 0, 2, 2, SKIP | EXT | OPT, 0, NULL},
 };
 
-static field_t _OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters[] = {   /* CHOICE */
+static const struct field_t _OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters[] = {      /* CHOICE */
        {FNAME("h222LogicalChannelParameters") SEQ, 3, 5, 5, SKIP | EXT, 0,
         _H222LogicalChannelParameters},
        {FNAME("h223LogicalChannelParameters") SEQ, 0, 2, 2, SKIP | EXT, 0,
@@ -742,7 +742,7 @@ static field_t _OpenLogicalChannel_forwardLogicalChannelParameters_multiplexPara
        {FNAME("none") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _OpenLogicalChannel_forwardLogicalChannelParameters[] = {       /* SEQUENCE */
+static const struct field_t _OpenLogicalChannel_forwardLogicalChannelParameters[] = {  /* SEQUENCE */
        {FNAME("portNumber") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("dataType") CHOICE, 3, 6, 9, DECODE | EXT,
         offsetof(OpenLogicalChannel_forwardLogicalChannelParameters,
@@ -756,7 +756,7 @@ static field_t _OpenLogicalChannel_forwardLogicalChannelParameters[] = {    /* SEQU
        {FNAME("replacementFor") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
 };
 
-static field_t _OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters[] = {   /* CHOICE */
+static const struct field_t _OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters[] = {      /* CHOICE */
        {FNAME("h223LogicalChannelParameters") SEQ, 0, 2, 2, SKIP | EXT, 0,
         _H223LogicalChannelParameters},
        {FNAME("v76LogicalChannelParameters") SEQ, 0, 5, 5, SKIP | EXT, 0,
@@ -767,7 +767,7 @@ static field_t _OpenLogicalChannel_reverseLogicalChannelParameters_multiplexPara
          h2250LogicalChannelParameters), _H2250LogicalChannelParameters},
 };
 
-static field_t _OpenLogicalChannel_reverseLogicalChannelParameters[] = {       /* SEQUENCE */
+static const struct field_t _OpenLogicalChannel_reverseLogicalChannelParameters[] = {  /* SEQUENCE */
        {FNAME("dataType") CHOICE, 3, 6, 9, SKIP | EXT, 0, _DataType},
        {FNAME("multiplexParameters") CHOICE, 1, 2, 3, DECODE | EXT | OPT,
         offsetof(OpenLogicalChannel_reverseLogicalChannelParameters,
@@ -778,23 +778,23 @@ static field_t _OpenLogicalChannel_reverseLogicalChannelParameters[] = {  /* SEQU
        {FNAME("replacementFor") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
 };
 
-static field_t _NetworkAccessParameters_distribution[] = {     /* CHOICE */
+static const struct field_t _NetworkAccessParameters_distribution[] = {        /* CHOICE */
        {FNAME("unicast") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("multicast") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _Q2931Address_address[] = {     /* CHOICE */
+static const struct field_t _Q2931Address_address[] = {        /* CHOICE */
        {FNAME("internationalNumber") NUMSTR, 4, 1, 0, SKIP, 0, NULL},
        {FNAME("nsapAddress") OCTSTR, 5, 1, 0, SKIP, 0, NULL},
 };
 
-static field_t _Q2931Address[] = {     /* SEQUENCE */
+static const struct field_t _Q2931Address[] = {        /* SEQUENCE */
        {FNAME("address") CHOICE, 1, 2, 2, SKIP | EXT, 0,
         _Q2931Address_address},
        {FNAME("subaddress") OCTSTR, 5, 1, 0, SKIP | OPT, 0, NULL},
 };
 
-static field_t _NetworkAccessParameters_networkAddress[] = {   /* CHOICE */
+static const struct field_t _NetworkAccessParameters_networkAddress[] = {      /* CHOICE */
        {FNAME("q2931Address") SEQ, 1, 2, 2, SKIP | EXT, 0, _Q2931Address},
        {FNAME("e164Address") NUMDGT, 7, 1, 0, SKIP, 0, NULL},
        {FNAME("localAreaAddress") CHOICE, 1, 2, 2, DECODE | EXT,
@@ -802,7 +802,7 @@ static field_t _NetworkAccessParameters_networkAddress[] = {        /* CHOICE */
         _H245_TransportAddress},
 };
 
-static field_t _NetworkAccessParameters[] = {  /* SEQUENCE */
+static const struct field_t _NetworkAccessParameters[] = {     /* SEQUENCE */
        {FNAME("distribution") CHOICE, 1, 2, 2, SKIP | EXT | OPT, 0,
         _NetworkAccessParameters_distribution},
        {FNAME("networkAddress") CHOICE, 2, 3, 3, DECODE | EXT,
@@ -814,7 +814,7 @@ static field_t _NetworkAccessParameters[] = {       /* SEQUENCE */
         NULL},
 };
 
-static field_t _OpenLogicalChannel[] = {       /* SEQUENCE */
+static const struct field_t _OpenLogicalChannel[] = {  /* SEQUENCE */
        {FNAME("forwardLogicalChannelNumber") INT, WORD, 1, 0, SKIP, 0, NULL},
        {FNAME("forwardLogicalChannelParameters") SEQ, 1, 3, 5, DECODE | EXT,
         offsetof(OpenLogicalChannel, forwardLogicalChannelParameters),
@@ -829,13 +829,13 @@ static field_t _OpenLogicalChannel[] = {  /* SEQUENCE */
        {FNAME("encryptionSync") SEQ, 2, 4, 4, STOP | EXT | OPT, 0, NULL},
 };
 
-static field_t _Setup_UUIE_fastStart[] = {     /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_fastStart[] = {        /* SEQUENCE OF */
        {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
         sizeof(OpenLogicalChannel), _OpenLogicalChannel}
        ,
 };
 
-static field_t _Setup_UUIE[] = {       /* SEQUENCE */
+static const struct field_t _Setup_UUIE[] = {  /* SEQUENCE */
        {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("h245Address") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
         offsetof(Setup_UUIE, h245Address), _TransportAddress},
@@ -894,13 +894,13 @@ static field_t _Setup_UUIE[] = {  /* SEQUENCE */
         NULL},
 };
 
-static field_t _CallProceeding_UUIE_fastStart[] = {    /* SEQUENCE OF */
+static const struct field_t _CallProceeding_UUIE_fastStart[] = {       /* SEQUENCE OF */
        {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
         sizeof(OpenLogicalChannel), _OpenLogicalChannel}
        ,
 };
 
-static field_t _CallProceeding_UUIE[] = {      /* SEQUENCE */
+static const struct field_t _CallProceeding_UUIE[] = { /* SEQUENCE */
        {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT, 0,
         _EndpointType},
@@ -920,13 +920,13 @@ static field_t _CallProceeding_UUIE[] = { /* SEQUENCE */
        {FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
 };
 
-static field_t _Connect_UUIE_fastStart[] = {   /* SEQUENCE OF */
+static const struct field_t _Connect_UUIE_fastStart[] = {      /* SEQUENCE OF */
        {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
         sizeof(OpenLogicalChannel), _OpenLogicalChannel}
        ,
 };
 
-static field_t _Connect_UUIE[] = {     /* SEQUENCE */
+static const struct field_t _Connect_UUIE[] = {        /* SEQUENCE */
        {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("h245Address") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
         offsetof(Connect_UUIE, h245Address), _TransportAddress},
@@ -954,13 +954,13 @@ static field_t _Connect_UUIE[] = {        /* SEQUENCE */
        {FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
 };
 
-static field_t _Alerting_UUIE_fastStart[] = {  /* SEQUENCE OF */
+static const struct field_t _Alerting_UUIE_fastStart[] = {     /* SEQUENCE OF */
        {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
         sizeof(OpenLogicalChannel), _OpenLogicalChannel}
        ,
 };
 
-static field_t _Alerting_UUIE[] = {    /* SEQUENCE */
+static const struct field_t _Alerting_UUIE[] = {       /* SEQUENCE */
        {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT, 0,
         _EndpointType},
@@ -986,7 +986,7 @@ static field_t _Alerting_UUIE[] = { /* SEQUENCE */
        {FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
 };
 
-static field_t _Information_UUIE[] = { /* SEQUENCE */
+static const struct field_t _Information_UUIE[] = {    /* SEQUENCE */
        {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL},
        {FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
@@ -996,7 +996,7 @@ static field_t _Information_UUIE[] = {      /* SEQUENCE */
        {FNAME("circuitInfo") SEQ, 3, 3, 3, SKIP | EXT | OPT, 0, NULL},
 };
 
-static field_t _ReleaseCompleteReason[] = {    /* CHOICE */
+static const struct field_t _ReleaseCompleteReason[] = {       /* CHOICE */
        {FNAME("noBandwidth") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("gatekeeperResources") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("unreachableDestination") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -1022,7 +1022,7 @@ static field_t _ReleaseCompleteReason[] = {       /* CHOICE */
        {FNAME("tunnelledSignallingRejected") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _ReleaseComplete_UUIE[] = {     /* SEQUENCE */
+static const struct field_t _ReleaseComplete_UUIE[] = {        /* SEQUENCE */
        {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("reason") CHOICE, 4, 12, 22, SKIP | EXT | OPT, 0,
         _ReleaseCompleteReason},
@@ -1039,11 +1039,11 @@ static field_t _ReleaseComplete_UUIE[] = {      /* SEQUENCE */
        {FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
 };
 
-static field_t _Facility_UUIE_alternativeAliasAddress[] = {    /* SEQUENCE OF */
+static const struct field_t _Facility_UUIE_alternativeAliasAddress[] = {       /* SEQUENCE OF */
        {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
 };
 
-static field_t _FacilityReason[] = {   /* CHOICE */
+static const struct field_t _FacilityReason[] = {      /* CHOICE */
        {FNAME("routeCallToGatekeeper") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("callForwarded") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("routeCallToMC") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -1057,13 +1057,13 @@ static field_t _FacilityReason[] = {    /* CHOICE */
        {FNAME("transportedInformation") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _Facility_UUIE_fastStart[] = {  /* SEQUENCE OF */
+static const struct field_t _Facility_UUIE_fastStart[] = {     /* SEQUENCE OF */
        {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
         sizeof(OpenLogicalChannel), _OpenLogicalChannel}
        ,
 };
 
-static field_t _Facility_UUIE[] = {    /* SEQUENCE */
+static const struct field_t _Facility_UUIE[] = {       /* SEQUENCE */
        {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("alternativeAddress") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
         offsetof(Facility_UUIE, alternativeAddress), _TransportAddress},
@@ -1094,17 +1094,17 @@ static field_t _Facility_UUIE[] = {     /* SEQUENCE */
         NULL},
 };
 
-static field_t _CallIdentifier[] = {   /* SEQUENCE */
+static const struct field_t _CallIdentifier[] = {      /* SEQUENCE */
        {FNAME("guid") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
 };
 
-static field_t _SecurityServiceMode[] = {      /* CHOICE */
+static const struct field_t _SecurityServiceMode[] = { /* CHOICE */
        {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0, _NonStandardParameter},
        {FNAME("none") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("default") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _SecurityCapabilities[] = {     /* SEQUENCE */
+static const struct field_t _SecurityCapabilities[] = {        /* SEQUENCE */
        {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
        {FNAME("encryption") CHOICE, 2, 3, 3, SKIP | EXT, 0,
@@ -1115,30 +1115,30 @@ static field_t _SecurityCapabilities[] = {      /* SEQUENCE */
         _SecurityServiceMode},
 };
 
-static field_t _H245Security[] = {     /* CHOICE */
+static const struct field_t _H245Security[] = {        /* CHOICE */
        {FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0, _NonStandardParameter},
        {FNAME("noSecurity") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("tls") SEQ, 1, 4, 4, SKIP | EXT, 0, _SecurityCapabilities},
        {FNAME("ipsec") SEQ, 1, 4, 4, SKIP | EXT, 0, _SecurityCapabilities},
 };
 
-static field_t _DHset[] = {    /* SEQUENCE */
+static const struct field_t _DHset[] = {       /* SEQUENCE */
        {FNAME("halfkey") BITSTR, WORD, 0, 0, SKIP, 0, NULL},
        {FNAME("modSize") BITSTR, WORD, 0, 0, SKIP, 0, NULL},
        {FNAME("generator") BITSTR, WORD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _TypedCertificate[] = { /* SEQUENCE */
+static const struct field_t _TypedCertificate[] = {    /* SEQUENCE */
        {FNAME("type") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("certificate") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _H235_NonStandardParameter[] = {        /* SEQUENCE */
+static const struct field_t _H235_NonStandardParameter[] = {   /* SEQUENCE */
        {FNAME("nonStandardIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("data") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _ClearToken[] = {       /* SEQUENCE */
+static const struct field_t _ClearToken[] = {  /* SEQUENCE */
        {FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("timeStamp") INT, CONS, 1, 0, SKIP | OPT, 0, NULL},
        {FNAME("password") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
@@ -1154,120 +1154,120 @@ static field_t _ClearToken[] = {      /* SEQUENCE */
        {FNAME("sendersID") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
 };
 
-static field_t _Progress_UUIE_tokens[] = {     /* SEQUENCE OF */
+static const struct field_t _Progress_UUIE_tokens[] = {        /* SEQUENCE OF */
        {FNAME("item") SEQ, 8, 9, 11, SKIP | EXT, 0, _ClearToken},
 };
 
-static field_t _Params[] = {   /* SEQUENCE */
+static const struct field_t _Params[] = {      /* SEQUENCE */
        {FNAME("ranInt") INT, UNCO, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("iv8") OCTSTR, FIXD, 8, 0, SKIP | OPT, 0, NULL},
        {FNAME("iv16") OCTSTR, FIXD, 16, 0, SKIP | OPT, 0, NULL},
 };
 
-static field_t _CryptoH323Token_cryptoEPPwdHash_token[] = {    /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoEPPwdHash_token[] = {       /* SEQUENCE */
        {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
        {FNAME("hash") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _CryptoH323Token_cryptoEPPwdHash[] = {  /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoEPPwdHash[] = {     /* SEQUENCE */
        {FNAME("alias") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
        {FNAME("timeStamp") INT, CONS, 1, 0, SKIP, 0, NULL},
        {FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
         _CryptoH323Token_cryptoEPPwdHash_token},
 };
 
-static field_t _CryptoH323Token_cryptoGKPwdHash_token[] = {    /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoGKPwdHash_token[] = {       /* SEQUENCE */
        {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
        {FNAME("hash") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _CryptoH323Token_cryptoGKPwdHash[] = {  /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoGKPwdHash[] = {     /* SEQUENCE */
        {FNAME("gatekeeperId") BMPSTR, 7, 1, 0, SKIP, 0, NULL},
        {FNAME("timeStamp") INT, CONS, 1, 0, SKIP, 0, NULL},
        {FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
         _CryptoH323Token_cryptoGKPwdHash_token},
 };
 
-static field_t _CryptoH323Token_cryptoEPPwdEncr[] = {  /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoEPPwdEncr[] = {     /* SEQUENCE */
        {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
        {FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _CryptoH323Token_cryptoGKPwdEncr[] = {  /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoGKPwdEncr[] = {     /* SEQUENCE */
        {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
        {FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _CryptoH323Token_cryptoEPCert[] = {     /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoEPCert[] = {        /* SEQUENCE */
        {FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
        {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
        {FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _CryptoH323Token_cryptoGKCert[] = {     /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoGKCert[] = {        /* SEQUENCE */
        {FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
        {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
        {FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _CryptoH323Token_cryptoFastStart[] = {  /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoFastStart[] = {     /* SEQUENCE */
        {FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
        {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
        {FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _CryptoToken_cryptoEncryptedToken_token[] = {   /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoEncryptedToken_token[] = {      /* SEQUENCE */
        {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
        {FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _CryptoToken_cryptoEncryptedToken[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoEncryptedToken[] = {    /* SEQUENCE */
        {FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
         _CryptoToken_cryptoEncryptedToken_token},
 };
 
-static field_t _CryptoToken_cryptoSignedToken_token[] = {      /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoSignedToken_token[] = { /* SEQUENCE */
        {FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
        {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
        {FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _CryptoToken_cryptoSignedToken[] = {    /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoSignedToken[] = {       /* SEQUENCE */
        {FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("token") SEQ, 0, 4, 4, SKIP, 0,
         _CryptoToken_cryptoSignedToken_token},
 };
 
-static field_t _CryptoToken_cryptoHashedToken_token[] = {      /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoHashedToken_token[] = { /* SEQUENCE */
        {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
        {FNAME("hash") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _CryptoToken_cryptoHashedToken[] = {    /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoHashedToken[] = {       /* SEQUENCE */
        {FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("hashedVals") SEQ, 8, 9, 11, SKIP | EXT, 0, _ClearToken},
        {FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
         _CryptoToken_cryptoHashedToken_token},
 };
 
-static field_t _CryptoToken_cryptoPwdEncr[] = {        /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoPwdEncr[] = {   /* SEQUENCE */
        {FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
        {FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _CryptoToken[] = {      /* CHOICE */
+static const struct field_t _CryptoToken[] = { /* CHOICE */
        {FNAME("cryptoEncryptedToken") SEQ, 0, 2, 2, SKIP, 0,
         _CryptoToken_cryptoEncryptedToken},
        {FNAME("cryptoSignedToken") SEQ, 0, 2, 2, SKIP, 0,
@@ -1278,7 +1278,7 @@ static field_t _CryptoToken[] = { /* CHOICE */
         _CryptoToken_cryptoPwdEncr},
 };
 
-static field_t _CryptoH323Token[] = {  /* CHOICE */
+static const struct field_t _CryptoH323Token[] = {     /* CHOICE */
        {FNAME("cryptoEPPwdHash") SEQ, 0, 3, 3, SKIP, 0,
         _CryptoH323Token_cryptoEPPwdHash},
        {FNAME("cryptoGKPwdHash") SEQ, 0, 3, 3, SKIP, 0,
@@ -1297,17 +1297,17 @@ static field_t _CryptoH323Token[] = {   /* CHOICE */
         _CryptoToken},
 };
 
-static field_t _Progress_UUIE_cryptoTokens[] = {       /* SEQUENCE OF */
+static const struct field_t _Progress_UUIE_cryptoTokens[] = {  /* SEQUENCE OF */
        {FNAME("item") CHOICE, 3, 8, 8, SKIP | EXT, 0, _CryptoH323Token},
 };
 
-static field_t _Progress_UUIE_fastStart[] = {  /* SEQUENCE OF */
+static const struct field_t _Progress_UUIE_fastStart[] = {     /* SEQUENCE OF */
        {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
         sizeof(OpenLogicalChannel), _OpenLogicalChannel}
        ,
 };
 
-static field_t _Progress_UUIE[] = {    /* SEQUENCE */
+static const struct field_t _Progress_UUIE[] = {       /* SEQUENCE */
        {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT, 0,
         _EndpointType},
@@ -1328,7 +1328,7 @@ static field_t _Progress_UUIE[] = {       /* SEQUENCE */
        {FNAME("fastConnectRefused") NUL, FIXD, 0, 0, SKIP | OPT, 0, NULL},
 };
 
-static field_t _H323_UU_PDU_h323_message_body[] = {    /* CHOICE */
+static const struct field_t _H323_UU_PDU_h323_message_body[] = {       /* CHOICE */
        {FNAME("setup") SEQ, 7, 13, 39, DECODE | EXT,
         offsetof(H323_UU_PDU_h323_message_body, setup), _Setup_UUIE},
        {FNAME("callProceeding") SEQ, 1, 3, 12, DECODE | EXT,
@@ -1352,7 +1352,7 @@ static field_t _H323_UU_PDU_h323_message_body[] = {       /* CHOICE */
        {FNAME("notify") SEQ, 2, 4, 4, SKIP | EXT, 0, NULL},
 };
 
-static field_t _RequestMessage[] = {   /* CHOICE */
+static const struct field_t _RequestMessage[] = {      /* CHOICE */
        {FNAME("nonStandard") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
        {FNAME("masterSlaveDetermination") SEQ, 0, 2, 2, STOP | EXT, 0, NULL},
        {FNAME("terminalCapabilitySet") SEQ, 3, 5, 5, STOP | EXT, 0, NULL},
@@ -1372,7 +1372,7 @@ static field_t _RequestMessage[] = {      /* CHOICE */
         NULL},
 };
 
-static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters[] = {        /* CHOICE */
+static const struct field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters[] = {   /* CHOICE */
        {FNAME("h222LogicalChannelParameters") SEQ, 3, 5, 5, SKIP | EXT, 0,
         _H222LogicalChannelParameters},
        {FNAME("h2250LogicalChannelParameters") SEQ, 10, 11, 14, DECODE | EXT,
@@ -1381,7 +1381,7 @@ static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexP
          h2250LogicalChannelParameters), _H2250LogicalChannelParameters},
 };
 
-static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters[] = {    /* SEQUENCE */
+static const struct field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters[] = {       /* SEQUENCE */
        {FNAME("reverseLogicalChannelNumber") INT, WORD, 1, 0, SKIP, 0, NULL},
        {FNAME("portNumber") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
        {FNAME("multiplexParameters") CHOICE, 0, 1, 2, DECODE | EXT | OPT,
@@ -1391,11 +1391,11 @@ static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters[] = {     /* S
        {FNAME("replacementFor") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
 };
 
-static field_t _H2250LogicalChannelAckParameters_nonStandard[] = {     /* SEQUENCE OF */
+static const struct field_t _H2250LogicalChannelAckParameters_nonStandard[] = {        /* SEQUENCE OF */
        {FNAME("item") SEQ, 0, 2, 2, SKIP, 0, _H245_NonStandardParameter},
 };
 
-static field_t _H2250LogicalChannelAckParameters[] = { /* SEQUENCE */
+static const struct field_t _H2250LogicalChannelAckParameters[] = {    /* SEQUENCE */
        {FNAME("nonStandard") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
         _H2250LogicalChannelAckParameters_nonStandard},
        {FNAME("sessionID") INT, 8, 1, 0, SKIP | OPT, 0, NULL},
@@ -1410,14 +1410,14 @@ static field_t _H2250LogicalChannelAckParameters[] = {  /* SEQUENCE */
        {FNAME("portNumber") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
 };
 
-static field_t _OpenLogicalChannelAck_forwardMultiplexAckParameters[] = {      /* CHOICE */
+static const struct field_t _OpenLogicalChannelAck_forwardMultiplexAckParameters[] = { /* CHOICE */
        {FNAME("h2250LogicalChannelAckParameters") SEQ, 5, 5, 7, DECODE | EXT,
         offsetof(OpenLogicalChannelAck_forwardMultiplexAckParameters,
                  h2250LogicalChannelAckParameters),
         _H2250LogicalChannelAckParameters},
 };
 
-static field_t _OpenLogicalChannelAck[] = {    /* SEQUENCE */
+static const struct field_t _OpenLogicalChannelAck[] = {       /* SEQUENCE */
        {FNAME("forwardLogicalChannelNumber") INT, WORD, 1, 0, SKIP, 0, NULL},
        {FNAME("reverseLogicalChannelParameters") SEQ, 2, 3, 4,
         DECODE | EXT | OPT, offsetof(OpenLogicalChannelAck,
@@ -1433,7 +1433,7 @@ static field_t _OpenLogicalChannelAck[] = {       /* SEQUENCE */
        {FNAME("encryptionSync") SEQ, 2, 4, 4, STOP | EXT | OPT, 0, NULL},
 };
 
-static field_t _ResponseMessage[] = {  /* CHOICE */
+static const struct field_t _ResponseMessage[] = {     /* CHOICE */
        {FNAME("nonStandard") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
        {FNAME("masterSlaveDeterminationAck") SEQ, 0, 1, 1, STOP | EXT, 0,
         NULL},
@@ -1469,7 +1469,7 @@ static field_t _ResponseMessage[] = {     /* CHOICE */
        {FNAME("logicalChannelRateReject") SEQ, 1, 4, 4, STOP | EXT, 0, NULL},
 };
 
-static field_t _MultimediaSystemControlMessage[] = {   /* CHOICE */
+static const struct field_t _MultimediaSystemControlMessage[] = {      /* CHOICE */
        {FNAME("request") CHOICE, 4, 11, 15, DECODE | EXT,
         offsetof(MultimediaSystemControlMessage, request), _RequestMessage},
        {FNAME("response") CHOICE, 5, 19, 24, DECODE | EXT,
@@ -1479,14 +1479,14 @@ static field_t _MultimediaSystemControlMessage[] = {    /* CHOICE */
        {FNAME("indication") CHOICE, 4, 14, 23, STOP | EXT, 0, NULL},
 };
 
-static field_t _H323_UU_PDU_h245Control[] = {  /* SEQUENCE OF */
+static const struct field_t _H323_UU_PDU_h245Control[] = {     /* SEQUENCE OF */
        {FNAME("item") CHOICE, 2, 4, 4, DECODE | OPEN | EXT,
         sizeof(MultimediaSystemControlMessage),
         _MultimediaSystemControlMessage}
        ,
 };
 
-static field_t _H323_UU_PDU[] = {      /* SEQUENCE */
+static const struct field_t _H323_UU_PDU[] = { /* SEQUENCE */
        {FNAME("h323-message-body") CHOICE, 3, 7, 13, DECODE | EXT,
         offsetof(H323_UU_PDU, h323_message_body),
         _H323_UU_PDU_h323_message_body},
@@ -1507,13 +1507,13 @@ static field_t _H323_UU_PDU[] = {       /* SEQUENCE */
        {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
 };
 
-static field_t _H323_UserInformation[] = {     /* SEQUENCE */
+static const struct field_t _H323_UserInformation[] = {        /* SEQUENCE */
        {FNAME("h323-uu-pdu") SEQ, 1, 2, 11, DECODE | EXT,
         offsetof(H323_UserInformation, h323_uu_pdu), _H323_UU_PDU},
        {FNAME("user-data") SEQ, 0, 2, 2, STOP | EXT | OPT, 0, NULL},
 };
 
-static field_t _GatekeeperRequest[] = {        /* SEQUENCE */
+static const struct field_t _GatekeeperRequest[] = {   /* SEQUENCE */
        {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
        {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
@@ -1537,7 +1537,7 @@ static field_t _GatekeeperRequest[] = {   /* SEQUENCE */
        {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
 };
 
-static field_t _GatekeeperConfirm[] = {        /* SEQUENCE */
+static const struct field_t _GatekeeperConfirm[] = {   /* SEQUENCE */
        {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
        {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
@@ -1557,23 +1557,23 @@ static field_t _GatekeeperConfirm[] = { /* SEQUENCE */
        {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
 };
 
-static field_t _RegistrationRequest_callSignalAddress[] = {    /* SEQUENCE OF */
+static const struct field_t _RegistrationRequest_callSignalAddress[] = {       /* SEQUENCE OF */
        {FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
         sizeof(TransportAddress), _TransportAddress}
        ,
 };
 
-static field_t _RegistrationRequest_rasAddress[] = {   /* SEQUENCE OF */
+static const struct field_t _RegistrationRequest_rasAddress[] = {      /* SEQUENCE OF */
        {FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
         sizeof(TransportAddress), _TransportAddress}
        ,
 };
 
-static field_t _RegistrationRequest_terminalAlias[] = {        /* SEQUENCE OF */
+static const struct field_t _RegistrationRequest_terminalAlias[] = {   /* SEQUENCE OF */
        {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
 };
 
-static field_t _RegistrationRequest[] = {      /* SEQUENCE */
+static const struct field_t _RegistrationRequest[] = { /* SEQUENCE */
        {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
        {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
@@ -1621,17 +1621,17 @@ static field_t _RegistrationRequest[] = {       /* SEQUENCE */
        {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
 };
 
-static field_t _RegistrationConfirm_callSignalAddress[] = {    /* SEQUENCE OF */
+static const struct field_t _RegistrationConfirm_callSignalAddress[] = {       /* SEQUENCE OF */
        {FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
         sizeof(TransportAddress), _TransportAddress}
        ,
 };
 
-static field_t _RegistrationConfirm_terminalAlias[] = {        /* SEQUENCE OF */
+static const struct field_t _RegistrationConfirm_terminalAlias[] = {   /* SEQUENCE OF */
        {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
 };
 
-static field_t _RegistrationConfirm[] = {      /* SEQUENCE */
+static const struct field_t _RegistrationConfirm[] = { /* SEQUENCE */
        {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
        {FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
@@ -1667,13 +1667,13 @@ static field_t _RegistrationConfirm[] = {       /* SEQUENCE */
        {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
 };
 
-static field_t _UnregistrationRequest_callSignalAddress[] = {  /* SEQUENCE OF */
+static const struct field_t _UnregistrationRequest_callSignalAddress[] = {     /* SEQUENCE OF */
        {FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
         sizeof(TransportAddress), _TransportAddress}
        ,
 };
 
-static field_t _UnregistrationRequest[] = {    /* SEQUENCE */
+static const struct field_t _UnregistrationRequest[] = {       /* SEQUENCE */
        {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
        {FNAME("callSignalAddress") SEQOF, SEMI, 0, 10, DECODE,
         offsetof(UnregistrationRequest, callSignalAddress),
@@ -1694,24 +1694,24 @@ static field_t _UnregistrationRequest[] = {     /* SEQUENCE */
        {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
 };
 
-static field_t _CallModel[] = {        /* CHOICE */
+static const struct field_t _CallModel[] = {   /* CHOICE */
        {FNAME("direct") NUL, FIXD, 0, 0, SKIP, 0, NULL},
        {FNAME("gatekeeperRouted") NUL, FIXD, 0, 0, SKIP, 0, NULL},
 };
 
-static field_t _AdmissionRequest_destinationInfo[] = { /* SEQUENCE OF */
+static const struct field_t _AdmissionRequest_destinationInfo[] = {    /* SEQUENCE OF */
        {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
 };
 
-static field_t _AdmissionRequest_destExtraCallInfo[] = {       /* SEQUENCE OF */
+static const struct field_t _AdmissionRequest_destExtraCallInfo[] = {  /* SEQUENCE OF */
        {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
 };
 
-static field_t _AdmissionRequest_srcInfo[] = { /* SEQUENCE OF */
+static const struct field_t _AdmissionRequest_srcInfo[] = {    /* SEQUENCE OF */
        {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
 };
 
-static field_t _AdmissionRequest[] = { /* SEQUENCE */
+static const struct field_t _AdmissionRequest[] = {    /* SEQUENCE */
        {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
        {FNAME("callType") CHOICE, 2, 4, 4, SKIP | EXT, 0, _CallType},
        {FNAME("callModel") CHOICE, 1, 2, 2, SKIP | EXT | OPT, 0, _CallModel},
@@ -1755,7 +1755,7 @@ static field_t _AdmissionRequest[] = {    /* SEQUENCE */
        {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
 };
 
-static field_t _AdmissionConfirm[] = { /* SEQUENCE */
+static const struct field_t _AdmissionConfirm[] = {    /* SEQUENCE */
        {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
        {FNAME("bandWidth") INT, CONS, 0, 0, SKIP, 0, NULL},
        {FNAME("callModel") CHOICE, 1, 2, 2, SKIP | EXT, 0, _CallModel},
@@ -1790,11 +1790,11 @@ static field_t _AdmissionConfirm[] = {  /* SEQUENCE */
        {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
 };
 
-static field_t _LocationRequest_destinationInfo[] = {  /* SEQUENCE OF */
+static const struct field_t _LocationRequest_destinationInfo[] = {     /* SEQUENCE OF */
        {FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
 };
 
-static field_t _LocationRequest[] = {  /* SEQUENCE */
+static const struct field_t _LocationRequest[] = {     /* SEQUENCE */
        {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
        {FNAME("endpointIdentifier") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
        {FNAME("destinationInfo") SEQOF, SEMI, 0, 0, SKIP, 0,
@@ -1818,7 +1818,7 @@ static field_t _LocationRequest[] = {     /* SEQUENCE */
        {FNAME("circuitInfo") SEQ, 3, 3, 3, STOP | EXT | OPT, 0, NULL},
 };
 
-static field_t _LocationConfirm[] = {  /* SEQUENCE */
+static const struct field_t _LocationConfirm[] = {     /* SEQUENCE */
        {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
        {FNAME("callSignalAddress") CHOICE, 3, 7, 7, DECODE | EXT,
         offsetof(LocationConfirm, callSignalAddress), _TransportAddress},
@@ -1844,13 +1844,13 @@ static field_t _LocationConfirm[] = {   /* SEQUENCE */
        {FNAME("serviceControl") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
 };
 
-static field_t _InfoRequestResponse_callSignalAddress[] = {    /* SEQUENCE OF */
+static const struct field_t _InfoRequestResponse_callSignalAddress[] = {       /* SEQUENCE OF */
        {FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
         sizeof(TransportAddress), _TransportAddress}
        ,
 };
 
-static field_t _InfoRequestResponse[] = {      /* SEQUENCE */
+static const struct field_t _InfoRequestResponse[] = { /* SEQUENCE */
        {FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
         _NonStandardParameter},
        {FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
@@ -1873,7 +1873,7 @@ static field_t _InfoRequestResponse[] = { /* SEQUENCE */
        {FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
 };
 
-static field_t _RasMessage[] = {       /* CHOICE */
+static const struct field_t _RasMessage[] = {  /* CHOICE */
        {FNAME("gatekeeperRequest") SEQ, 4, 8, 18, DECODE | EXT,
         offsetof(RasMessage, gatekeeperRequest), _GatekeeperRequest},
        {FNAME("gatekeeperConfirm") SEQ, 2, 5, 14, DECODE | EXT,
index 96aa637c09327e6c79a85ec6a76cd86228aa908a..b1fd21cc1dbc2e613ea15e6813bb550bcc6ce7cb 100644 (file)
@@ -28,6 +28,7 @@
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/nf_conntrack_extend.h>
 
+static DEFINE_MUTEX(nf_ct_helper_mutex);
 static struct hlist_head *nf_ct_helper_hash __read_mostly;
 static unsigned int nf_ct_helper_hsize __read_mostly;
 static unsigned int nf_ct_helper_count __read_mostly;
@@ -54,42 +55,13 @@ __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
                return NULL;
 
        h = helper_hash(tuple);
-       hlist_for_each_entry(helper, n, &nf_ct_helper_hash[h], hnode) {
+       hlist_for_each_entry_rcu(helper, n, &nf_ct_helper_hash[h], hnode) {
                if (nf_ct_tuple_src_mask_cmp(tuple, &helper->tuple, &mask))
                        return helper;
        }
        return NULL;
 }
-
-struct nf_conntrack_helper *
-nf_ct_helper_find_get(const struct nf_conntrack_tuple *tuple)
-{
-       struct nf_conntrack_helper *helper;
-
-       /* need nf_conntrack_lock to assure that helper exists until
-        * try_module_get() is called */
-       read_lock_bh(&nf_conntrack_lock);
-
-       helper = __nf_ct_helper_find(tuple);
-       if (helper) {
-               /* need to increase module usage count to assure helper will
-                * not go away while the caller is e.g. busy putting a
-                * conntrack in the hash that uses the helper */
-               if (!try_module_get(helper->me))
-                       helper = NULL;
-       }
-
-       read_unlock_bh(&nf_conntrack_lock);
-
-       return helper;
-}
-EXPORT_SYMBOL_GPL(nf_ct_helper_find_get);
-
-void nf_ct_helper_put(struct nf_conntrack_helper *helper)
-{
-       module_put(helper->me);
-}
-EXPORT_SYMBOL_GPL(nf_ct_helper_put);
+EXPORT_SYMBOL_GPL(__nf_ct_helper_find);
 
 struct nf_conntrack_helper *
 __nf_conntrack_helper_find_byname(const char *name)
@@ -99,7 +71,7 @@ __nf_conntrack_helper_find_byname(const char *name)
        unsigned int i;
 
        for (i = 0; i < nf_ct_helper_hsize; i++) {
-               hlist_for_each_entry(h, n, &nf_ct_helper_hash[i], hnode) {
+               hlist_for_each_entry_rcu(h, n, &nf_ct_helper_hash[i], hnode) {
                        if (!strcmp(h->name, name))
                                return h;
                }
@@ -140,10 +112,10 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
 
        BUG_ON(me->timeout == 0);
 
-       write_lock_bh(&nf_conntrack_lock);
-       hlist_add_head(&me->hnode, &nf_ct_helper_hash[h]);
+       mutex_lock(&nf_ct_helper_mutex);
+       hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
        nf_ct_helper_count++;
-       write_unlock_bh(&nf_conntrack_lock);
+       mutex_unlock(&nf_ct_helper_mutex);
 
        return 0;
 }
@@ -156,10 +128,17 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
        struct hlist_node *n, *next;
        unsigned int i;
 
-       /* Need write lock here, to delete helper. */
-       write_lock_bh(&nf_conntrack_lock);
-       hlist_del(&me->hnode);
+       mutex_lock(&nf_ct_helper_mutex);
+       hlist_del_rcu(&me->hnode);
        nf_ct_helper_count--;
+       mutex_unlock(&nf_ct_helper_mutex);
+
+       /* Make sure every nothing is still using the helper unless its a
+        * connection in the hash.
+        */
+       synchronize_rcu();
+
+       spin_lock_bh(&nf_conntrack_lock);
 
        /* Get rid of expectations */
        for (i = 0; i < nf_ct_expect_hsize; i++) {
@@ -181,10 +160,7 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
                hlist_for_each_entry(h, n, &nf_conntrack_hash[i], hnode)
                        unhelp(h, me);
        }
-       write_unlock_bh(&nf_conntrack_lock);
-
-       /* Someone could be still looking at the helper in a bh. */
-       synchronize_net();
+       spin_unlock_bh(&nf_conntrack_lock);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
 
index dfaed4ba83cd542783945e55c7a0edb13add4e11..c336b07a0d4c49e51cee1d9f6d3934fe79531c0a 100644 (file)
@@ -23,7 +23,7 @@
 
 #define MAX_PORTS 8
 static unsigned short ports[MAX_PORTS];
-static int ports_c;
+static unsigned int ports_c;
 static unsigned int max_dcc_channels = 8;
 static unsigned int dcc_timeout __read_mostly = 300;
 /* This is slow, but it's simple. --RR */
index 38141f104db7cfda21817140dce88f1d02bb0747..4a1b42b2b7a5bc55b7f4cdce9000a968caef2562 100644 (file)
@@ -491,11 +491,6 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
                    && ctnetlink_dump_helpinfo(skb, ct) < 0)
                        goto nla_put_failure;
 
-#ifdef CONFIG_NF_CONNTRACK_MARK
-               if ((events & IPCT_MARK || ct->mark)
-                   && ctnetlink_dump_mark(skb, ct) < 0)
-                       goto nla_put_failure;
-#endif
 #ifdef CONFIG_NF_CONNTRACK_SECMARK
                if ((events & IPCT_SECMARK || ct->secmark)
                    && ctnetlink_dump_secmark(skb, ct) < 0)
@@ -516,6 +511,12 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
                        goto nla_put_failure;
        }
 
+#ifdef CONFIG_NF_CONNTRACK_MARK
+       if ((events & IPCT_MARK || ct->mark)
+           && ctnetlink_dump_mark(skb, ct) < 0)
+               goto nla_put_failure;
+#endif
+
        nlh->nlmsg_len = skb->tail - b;
        nfnetlink_send(skb, 0, group, 0);
        return NOTIFY_DONE;
@@ -545,12 +546,12 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
        struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
        u_int8_t l3proto = nfmsg->nfgen_family;
 
-       read_lock_bh(&nf_conntrack_lock);
+       rcu_read_lock();
        last = (struct nf_conn *)cb->args[1];
        for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
 restart:
-               hlist_for_each_entry(h, n, &nf_conntrack_hash[cb->args[0]],
-                                    hnode) {
+               hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[cb->args[0]],
+                                        hnode) {
                        if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
                                continue;
                        ct = nf_ct_tuplehash_to_ctrack(h);
@@ -568,7 +569,8 @@ restart:
                                                cb->nlh->nlmsg_seq,
                                                IPCTNL_MSG_CT_NEW,
                                                1, ct) < 0) {
-                               nf_conntrack_get(&ct->ct_general);
+                               if (!atomic_inc_not_zero(&ct->ct_general.use))
+                                       continue;
                                cb->args[1] = (unsigned long)ct;
                                goto out;
                        }
@@ -584,7 +586,7 @@ restart:
                }
        }
 out:
-       read_unlock_bh(&nf_conntrack_lock);
+       rcu_read_unlock();
        if (last)
                nf_ct_put(last);
 
@@ -1167,11 +1169,12 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
                ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));
 #endif
 
-       helper = nf_ct_helper_find_get(rtuple);
+       rcu_read_lock();
+       helper = __nf_ct_helper_find(rtuple);
        if (helper) {
                help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
                if (help == NULL) {
-                       nf_ct_helper_put(helper);
+                       rcu_read_unlock();
                        err = -ENOMEM;
                        goto err;
                }
@@ -1187,9 +1190,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
 
        add_timer(&ct->timeout);
        nf_conntrack_hash_insert(ct);
-
-       if (helper)
-               nf_ct_helper_put(helper);
+       rcu_read_unlock();
 
        return 0;
 
@@ -1220,11 +1221,11 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
                        return err;
        }
 
-       write_lock_bh(&nf_conntrack_lock);
+       spin_lock_bh(&nf_conntrack_lock);
        if (cda[CTA_TUPLE_ORIG])
-               h = __nf_conntrack_find(&otuple, NULL);
+               h = __nf_conntrack_find(&otuple);
        else if (cda[CTA_TUPLE_REPLY])
-               h = __nf_conntrack_find(&rtuple, NULL);
+               h = __nf_conntrack_find(&rtuple);
 
        if (h == NULL) {
                struct nf_conntrack_tuple master;
@@ -1237,9 +1238,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
                                                    CTA_TUPLE_MASTER,
                                                    u3);
                        if (err < 0)
-                               return err;
+                               goto out_unlock;
 
-                       master_h = __nf_conntrack_find(&master, NULL);
+                       master_h = __nf_conntrack_find(&master);
                        if (master_h == NULL) {
                                err = -ENOENT;
                                goto out_unlock;
@@ -1248,7 +1249,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
                        atomic_inc(&master_ct->ct_general.use);
                }
 
-               write_unlock_bh(&nf_conntrack_lock);
+               spin_unlock_bh(&nf_conntrack_lock);
                err = -ENOENT;
                if (nlh->nlmsg_flags & NLM_F_CREATE)
                        err = ctnetlink_create_conntrack(cda,
@@ -1281,7 +1282,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
        }
 
 out_unlock:
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
        return err;
 }
 
@@ -1472,7 +1473,7 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
        struct hlist_node *n;
        u_int8_t l3proto = nfmsg->nfgen_family;
 
-       read_lock_bh(&nf_conntrack_lock);
+       rcu_read_lock();
        last = (struct nf_conntrack_expect *)cb->args[1];
        for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) {
 restart:
@@ -1489,7 +1490,8 @@ restart:
                                                    cb->nlh->nlmsg_seq,
                                                    IPCTNL_MSG_EXP_NEW,
                                                    1, exp) < 0) {
-                               atomic_inc(&exp->use);
+                               if (!atomic_inc_not_zero(&exp->use))
+                                       continue;
                                cb->args[1] = (unsigned long)exp;
                                goto out;
                        }
@@ -1500,7 +1502,7 @@ restart:
                }
        }
 out:
-       read_unlock_bh(&nf_conntrack_lock);
+       rcu_read_unlock();
        if (last)
                nf_ct_expect_put(last);
 
@@ -1613,10 +1615,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                struct nf_conn_help *m_help;
 
                /* delete all expectations for this helper */
-               write_lock_bh(&nf_conntrack_lock);
+               spin_lock_bh(&nf_conntrack_lock);
                h = __nf_conntrack_helper_find_byname(name);
                if (!h) {
-                       write_unlock_bh(&nf_conntrack_lock);
+                       spin_unlock_bh(&nf_conntrack_lock);
                        return -EINVAL;
                }
                for (i = 0; i < nf_ct_expect_hsize; i++) {
@@ -1631,10 +1633,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                                }
                        }
                }
-               write_unlock_bh(&nf_conntrack_lock);
+               spin_unlock_bh(&nf_conntrack_lock);
        } else {
                /* This basically means we have to flush everything*/
-               write_lock_bh(&nf_conntrack_lock);
+               spin_lock_bh(&nf_conntrack_lock);
                for (i = 0; i < nf_ct_expect_hsize; i++) {
                        hlist_for_each_entry_safe(exp, n, next,
                                                  &nf_ct_expect_hash[i],
@@ -1645,7 +1647,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                                }
                        }
                }
-               write_unlock_bh(&nf_conntrack_lock);
+               spin_unlock_bh(&nf_conntrack_lock);
        }
 
        return 0;
@@ -1731,11 +1733,11 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
        if (err < 0)
                return err;
 
-       write_lock_bh(&nf_conntrack_lock);
+       spin_lock_bh(&nf_conntrack_lock);
        exp = __nf_ct_expect_find(&tuple);
 
        if (!exp) {
-               write_unlock_bh(&nf_conntrack_lock);
+               spin_unlock_bh(&nf_conntrack_lock);
                err = -ENOENT;
                if (nlh->nlmsg_flags & NLM_F_CREATE)
                        err = ctnetlink_create_expect(cda, u3);
@@ -1745,7 +1747,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
        err = -EEXIST;
        if (!(nlh->nlmsg_flags & NLM_F_EXCL))
                err = ctnetlink_change_expect(exp, cda);
-       write_unlock_bh(&nf_conntrack_lock);
+       spin_unlock_bh(&nf_conntrack_lock);
 
        return err;
 }
index 099b6df3e2b55cfcd69bbe0cddf97bc6c714e858..b5cb8e831230dbb643323e7a1cda152de22f595b 100644 (file)
@@ -67,7 +67,7 @@ EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
 
 #ifdef DEBUG
 /* PptpControlMessageType names */
-const char *pptp_msg_name[] = {
+const char *const pptp_msg_name[] = {
        "UNKNOWN_MESSAGE",
        "START_SESSION_REQUEST",
        "START_SESSION_REPLY",
@@ -136,7 +136,7 @@ static void pptp_expectfn(struct nf_conn *ct,
 
 static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
 {
-       struct nf_conntrack_tuple_hash *h;
+       const struct nf_conntrack_tuple_hash *h;
        struct nf_conntrack_expect *exp;
        struct nf_conn *sibling;
 
@@ -168,7 +168,7 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
 /* timeout GRE data connections */
 static void pptp_destroy_siblings(struct nf_conn *ct)
 {
-       struct nf_conn_help *help = nfct_help(ct);
+       const struct nf_conn_help *help = nfct_help(ct);
        struct nf_conntrack_tuple t;
 
        nf_ct_gre_keymap_destroy(ct);
@@ -497,9 +497,11 @@ conntrack_pptp_help(struct sk_buff *skb, unsigned int protoff,
 
 {
        int dir = CTINFO2DIR(ctinfo);
-       struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info;
-       struct tcphdr _tcph, *tcph;
-       struct pptp_pkt_hdr _pptph, *pptph;
+       const struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info;
+       const struct tcphdr *tcph;
+       struct tcphdr _tcph;
+       const struct pptp_pkt_hdr *pptph;
+       struct pptp_pkt_hdr _pptph;
        struct PptpControlHeader _ctlh, *ctlh;
        union pptp_ctrl_union _pptpReq, *pptpReq;
        unsigned int tcplen = skb->len - protoff;
index 22c5dcb6306aad685f1aa0c4d8b31ff4e8d31aa9..55458915575f20d604205f038cde9b457df4856a 100644 (file)
@@ -41,19 +41,19 @@ static int generic_print_tuple(struct seq_file *s,
 }
 
 /* Returns verdict for packet, or -1 for invalid. */
-static int packet(struct nf_conn *conntrack,
+static int packet(struct nf_conn *ct,
                  const struct sk_buff *skb,
                  unsigned int dataoff,
                  enum ip_conntrack_info ctinfo,
                  int pf,
                  unsigned int hooknum)
 {
-       nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_generic_timeout);
+       nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_generic_timeout);
        return NF_ACCEPT;
 }
 
 /* Called when a new connection for this protocol found. */
-static int new(struct nf_conn *conntrack, const struct sk_buff *skb,
+static int new(struct nf_conn *ct, const struct sk_buff *skb,
               unsigned int dataoff)
 {
        return 1;
index 4a185f6aa65a907235c7ac7c2ae9629aa37c242a..e10024a1b6662e971ac565639d10c1bd16a85793 100644 (file)
@@ -161,9 +161,11 @@ static int gre_pkt_to_tuple(const struct sk_buff *skb,
                           unsigned int dataoff,
                           struct nf_conntrack_tuple *tuple)
 {
-       struct gre_hdr_pptp _pgrehdr, *pgrehdr;
+       const struct gre_hdr_pptp *pgrehdr;
+       struct gre_hdr_pptp _pgrehdr;
        __be16 srckey;
-       struct gre_hdr _grehdr, *grehdr;
+       const struct gre_hdr *grehdr;
+       struct gre_hdr _grehdr;
 
        /* first only delinearize old RFC1701 GRE header */
        grehdr = skb_header_pointer(skb, dataoff, sizeof(_grehdr), &_grehdr);
index 21d29e782baf3ae0970efac12e8587b934fa1f47..f9a08370dbb31f3998ea719c0271a44d5bc1d7d9 100644 (file)
@@ -25,7 +25,7 @@
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
 
-/* Protects conntrack->proto.sctp */
+/* Protects ct->proto.sctp */
 static DEFINE_RWLOCK(sctp_lock);
 
 /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
@@ -624,7 +624,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
 #endif
 };
 
-int __init nf_conntrack_proto_sctp_init(void)
+static int __init nf_conntrack_proto_sctp_init(void)
 {
        int ret;
 
@@ -647,7 +647,7 @@ int __init nf_conntrack_proto_sctp_init(void)
        return ret;
 }
 
-void __exit nf_conntrack_proto_sctp_fini(void)
+static void __exit nf_conntrack_proto_sctp_fini(void)
 {
        nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
        nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
index 64c9b910419c052395b1e431b84e262f11fa13b5..3e0cccae563648b735f125cde27125367e6d0f4e 100644 (file)
@@ -26,7 +26,7 @@
 #include <net/netfilter/nf_conntrack_ecache.h>
 #include <net/netfilter/nf_log.h>
 
-/* Protects conntrack->proto.tcp */
+/* Protects ct->proto.tcp */
 static DEFINE_RWLOCK(tcp_lock);
 
 /* "Be conservative in what you do,
@@ -46,7 +46,7 @@ static int nf_ct_tcp_max_retrans __read_mostly = 3;
   /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
      closely.  They're more complex. --RR */
 
-static const char *tcp_conntrack_names[] = {
+static const char *const tcp_conntrack_names[] = {
        "NONE",
        "SYN_SENT",
        "SYN_RECV",
@@ -261,7 +261,8 @@ static int tcp_pkt_to_tuple(const struct sk_buff *skb,
                            unsigned int dataoff,
                            struct nf_conntrack_tuple *tuple)
 {
-       struct tcphdr _hdr, *hp;
+       const struct tcphdr *hp;
+       struct tcphdr _hdr;
 
        /* Actually only need first 8 bytes. */
        hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
@@ -292,13 +293,12 @@ static int tcp_print_tuple(struct seq_file *s,
 }
 
 /* Print out the private part of the conntrack. */
-static int tcp_print_conntrack(struct seq_file *s,
-                              const struct nf_conn *conntrack)
+static int tcp_print_conntrack(struct seq_file *s, const struct nf_conn *ct)
 {
        enum tcp_conntrack state;
 
        read_lock_bh(&tcp_lock);
-       state = conntrack->proto.tcp.state;
+       state = ct->proto.tcp.state;
        read_unlock_bh(&tcp_lock);
 
        return seq_printf(s, "%s ", tcp_conntrack_names[state]);
@@ -344,7 +344,7 @@ static unsigned int get_conntrack_index(const struct tcphdr *tcph)
 static inline __u32 segment_seq_plus_len(__u32 seq,
                                         size_t len,
                                         unsigned int dataoff,
-                                        struct tcphdr *tcph)
+                                        const struct tcphdr *tcph)
 {
        /* XXX Should I use payload length field in IP/IPv6 header ?
         * - YK */
@@ -363,11 +363,11 @@ static inline __u32 segment_seq_plus_len(__u32 seq,
  */
 static void tcp_options(const struct sk_buff *skb,
                        unsigned int dataoff,
-                       struct tcphdr *tcph,
+                       const struct tcphdr *tcph,
                        struct ip_ct_tcp_state *state)
 {
        unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
-       unsigned char *ptr;
+       const unsigned char *ptr;
        int length = (tcph->doff*4) - sizeof(struct tcphdr);
 
        if (!length)
@@ -418,10 +418,10 @@ static void tcp_options(const struct sk_buff *skb,
 }
 
 static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
-                    struct tcphdr *tcph, __u32 *sack)
+                     const struct tcphdr *tcph, __u32 *sack)
 {
        unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
-       unsigned char *ptr;
+       const unsigned char *ptr;
        int length = (tcph->doff*4) - sizeof(struct tcphdr);
        __u32 tmp;
 
@@ -478,18 +478,18 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
        }
 }
 
-static int tcp_in_window(struct nf_conn *ct,
+static int tcp_in_window(const struct nf_conn *ct,
                         struct ip_ct_tcp *state,
                         enum ip_conntrack_dir dir,
                         unsigned int index,
                         const struct sk_buff *skb,
                         unsigned int dataoff,
-                        struct tcphdr *tcph,
+                        const struct tcphdr *tcph,
                         int pf)
 {
        struct ip_ct_tcp_state *sender = &state->seen[dir];
        struct ip_ct_tcp_state *receiver = &state->seen[!dir];
-       struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
+       const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
        __u32 seq, ack, sack, end, win, swin;
        int res;
 
@@ -687,14 +687,14 @@ static int tcp_in_window(struct nf_conn *ct,
 #ifdef CONFIG_NF_NAT_NEEDED
 /* Update sender->td_end after NAT successfully mangled the packet */
 /* Caller must linearize skb at tcp header. */
-void nf_conntrack_tcp_update(struct sk_buff *skb,
+void nf_conntrack_tcp_update(const struct sk_buff *skb,
                             unsigned int dataoff,
-                            struct nf_conn *conntrack,
+                            struct nf_conn *ct,
                             int dir)
 {
-       struct tcphdr *tcph = (void *)skb->data + dataoff;
-       struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[dir];
-       struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[!dir];
+       const struct tcphdr *tcph = (const void *)skb->data + dataoff;
+       const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[dir];
+       const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[!dir];
        __u32 end;
 
        end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph);
@@ -703,9 +703,9 @@ void nf_conntrack_tcp_update(struct sk_buff *skb,
        /*
         * We have to worry for the ack in the reply packet only...
         */
-       if (after(end, conntrack->proto.tcp.seen[dir].td_end))
-               conntrack->proto.tcp.seen[dir].td_end = end;
-       conntrack->proto.tcp.last_end = end;
+       if (after(end, ct->proto.tcp.seen[dir].td_end))
+               ct->proto.tcp.seen[dir].td_end = end;
+       ct->proto.tcp.last_end = end;
        write_unlock_bh(&tcp_lock);
        pr_debug("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
                 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
@@ -727,7 +727,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update);
 #define        TH_CWR  0x80
 
 /* table of valid flag combinations - PUSH, ECE and CWR are always valid */
-static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG) + 1] =
+static const u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG) + 1] =
 {
        [TH_SYN]                        = 1,
        [TH_SYN|TH_URG]                 = 1,
@@ -747,7 +747,8 @@ static int tcp_error(struct sk_buff *skb,
                     int pf,
                     unsigned int hooknum)
 {
-       struct tcphdr _tcph, *th;
+       const struct tcphdr *th;
+       struct tcphdr _tcph;
        unsigned int tcplen = skb->len - dataoff;
        u_int8_t tcpflags;
 
@@ -794,7 +795,7 @@ static int tcp_error(struct sk_buff *skb,
 }
 
 /* Returns verdict for packet, or -1 for invalid. */
-static int tcp_packet(struct nf_conn *conntrack,
+static int tcp_packet(struct nf_conn *ct,
                      const struct sk_buff *skb,
                      unsigned int dataoff,
                      enum ip_conntrack_info ctinfo,
@@ -804,7 +805,8 @@ static int tcp_packet(struct nf_conn *conntrack,
        struct nf_conntrack_tuple *tuple;
        enum tcp_conntrack new_state, old_state;
        enum ip_conntrack_dir dir;
-       struct tcphdr *th, _tcph;
+       const struct tcphdr *th;
+       struct tcphdr _tcph;
        unsigned long timeout;
        unsigned int index;
 
@@ -812,26 +814,24 @@ static int tcp_packet(struct nf_conn *conntrack,
        BUG_ON(th == NULL);
 
        write_lock_bh(&tcp_lock);
-       old_state = conntrack->proto.tcp.state;
+       old_state = ct->proto.tcp.state;
        dir = CTINFO2DIR(ctinfo);
        index = get_conntrack_index(th);
        new_state = tcp_conntracks[dir][index][old_state];
-       tuple = &conntrack->tuplehash[dir].tuple;
+       tuple = &ct->tuplehash[dir].tuple;
 
        switch (new_state) {
        case TCP_CONNTRACK_SYN_SENT:
                if (old_state < TCP_CONNTRACK_TIME_WAIT)
                        break;
-               if ((conntrack->proto.tcp.seen[!dir].flags &
-                       IP_CT_TCP_FLAG_CLOSE_INIT)
-                   || (conntrack->proto.tcp.last_dir == dir
-                       && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
+               if ((ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_CLOSE_INIT)
+                   || (ct->proto.tcp.last_dir == dir
+                       && ct->proto.tcp.last_index == TCP_RST_SET)) {
                        /* Attempt to reopen a closed/aborted connection.
                         * Delete this connection and look up again. */
                        write_unlock_bh(&tcp_lock);
-                       if (del_timer(&conntrack->timeout))
-                               conntrack->timeout.function((unsigned long)
-                                                           conntrack);
+                       if (del_timer(&ct->timeout))
+                               ct->timeout.function((unsigned long)ct);
                        return -NF_REPEAT;
                }
                /* Fall through */
@@ -843,10 +843,9 @@ static int tcp_packet(struct nf_conn *conntrack,
                 * c) ACK in reply direction after initial SYN in original.
                 */
                if (index == TCP_SYNACK_SET
-                   && conntrack->proto.tcp.last_index == TCP_SYN_SET
-                   && conntrack->proto.tcp.last_dir != dir
-                   && ntohl(th->ack_seq) ==
-                            conntrack->proto.tcp.last_end) {
+                   && ct->proto.tcp.last_index == TCP_SYN_SET
+                   && ct->proto.tcp.last_dir != dir
+                   && ntohl(th->ack_seq) == ct->proto.tcp.last_end) {
                        /* This SYN/ACK acknowledges a SYN that we earlier
                         * ignored as invalid. This means that the client and
                         * the server are both in sync, while the firewall is
@@ -858,15 +857,14 @@ static int tcp_packet(struct nf_conn *conntrack,
                        if (LOG_INVALID(IPPROTO_TCP))
                                nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                          "nf_ct_tcp: killing out of sync session ");
-                       if (del_timer(&conntrack->timeout))
-                               conntrack->timeout.function((unsigned long)
-                                                           conntrack);
+                       if (del_timer(&ct->timeout))
+                               ct->timeout.function((unsigned long)ct);
                        return -NF_DROP;
                }
-               conntrack->proto.tcp.last_index = index;
-               conntrack->proto.tcp.last_dir = dir;
-               conntrack->proto.tcp.last_seq = ntohl(th->seq);
-               conntrack->proto.tcp.last_end =
+               ct->proto.tcp.last_index = index;
+               ct->proto.tcp.last_dir = dir;
+               ct->proto.tcp.last_seq = ntohl(th->seq);
+               ct->proto.tcp.last_end =
                    segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
 
                write_unlock_bh(&tcp_lock);
@@ -885,11 +883,11 @@ static int tcp_packet(struct nf_conn *conntrack,
                return -NF_ACCEPT;
        case TCP_CONNTRACK_CLOSE:
                if (index == TCP_RST_SET
-                   && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
-                        && conntrack->proto.tcp.last_index == TCP_SYN_SET)
-                       || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
-                           && conntrack->proto.tcp.last_index == TCP_ACK_SET))
-                   && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
+                   && ((test_bit(IPS_SEEN_REPLY_BIT, &ct->status)
+                        && ct->proto.tcp.last_index == TCP_SYN_SET)
+                       || (!test_bit(IPS_ASSURED_BIT, &ct->status)
+                           && ct->proto.tcp.last_index == TCP_ACK_SET))
+                   && ntohl(th->ack_seq) == ct->proto.tcp.last_end) {
                        /* RST sent to invalid SYN or ACK we had let through
                         * at a) and c) above:
                         *
@@ -907,15 +905,15 @@ static int tcp_packet(struct nf_conn *conntrack,
                break;
        }
 
-       if (!tcp_in_window(conntrack, &conntrack->proto.tcp, dir, index,
+       if (!tcp_in_window(ct, &ct->proto.tcp, dir, index,
                           skb, dataoff, th, pf)) {
                write_unlock_bh(&tcp_lock);
                return -NF_ACCEPT;
        }
      in_window:
        /* From now on we have got in-window packets */
-       conntrack->proto.tcp.last_index = index;
-       conntrack->proto.tcp.last_dir = dir;
+       ct->proto.tcp.last_index = index;
+       ct->proto.tcp.last_dir = dir;
 
        pr_debug("tcp_conntracks: ");
        NF_CT_DUMP_TUPLE(tuple);
@@ -924,12 +922,12 @@ static int tcp_packet(struct nf_conn *conntrack,
                 (th->fin ? 1 : 0), (th->rst ? 1 : 0),
                 old_state, new_state);
 
-       conntrack->proto.tcp.state = new_state;
+       ct->proto.tcp.state = new_state;
        if (old_state != new_state
            && (new_state == TCP_CONNTRACK_FIN_WAIT
                || new_state == TCP_CONNTRACK_CLOSE))
-               conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
-       timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans
+               ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
+       timeout = ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans
                  && tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
                  ? nf_ct_tcp_timeout_max_retrans : tcp_timeouts[new_state];
        write_unlock_bh(&tcp_lock);
@@ -938,41 +936,41 @@ static int tcp_packet(struct nf_conn *conntrack,
        if (new_state != old_state)
                nf_conntrack_event_cache(IPCT_PROTOINFO, skb);
 
-       if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
+       if (!test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
                /* If only reply is a RST, we can consider ourselves not to
                   have an established connection: this is a fairly common
                   problem case, so we can delete the conntrack
                   immediately.  --RR */
                if (th->rst) {
-                       if (del_timer(&conntrack->timeout))
-                               conntrack->timeout.function((unsigned long)
-                                                           conntrack);
+                       if (del_timer(&ct->timeout))
+                               ct->timeout.function((unsigned long)ct);
                        return NF_ACCEPT;
                }
-       } else if (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
+       } else if (!test_bit(IPS_ASSURED_BIT, &ct->status)
                   && (old_state == TCP_CONNTRACK_SYN_RECV
                       || old_state == TCP_CONNTRACK_ESTABLISHED)
                   && new_state == TCP_CONNTRACK_ESTABLISHED) {
                /* Set ASSURED if we see see valid ack in ESTABLISHED
                   after SYN_RECV or a valid answer for a picked up
                   connection. */
-               set_bit(IPS_ASSURED_BIT, &conntrack->status);
+               set_bit(IPS_ASSURED_BIT, &ct->status);
                nf_conntrack_event_cache(IPCT_STATUS, skb);
        }
-       nf_ct_refresh_acct(conntrack, ctinfo, skb, timeout);
+       nf_ct_refresh_acct(ct, ctinfo, skb, timeout);
 
        return NF_ACCEPT;
 }
 
 /* Called when a new connection for this protocol found. */
-static int tcp_new(struct nf_conn *conntrack,
+static int tcp_new(struct nf_conn *ct,
                   const struct sk_buff *skb,
                   unsigned int dataoff)
 {
        enum tcp_conntrack new_state;
-       struct tcphdr *th, _tcph;
-       struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[0];
-       struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[1];
+       const struct tcphdr *th;
+       struct tcphdr _tcph;
+       const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0];
+       const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1];
 
        th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
        BUG_ON(th == NULL);
@@ -990,17 +988,17 @@ static int tcp_new(struct nf_conn *conntrack,
 
        if (new_state == TCP_CONNTRACK_SYN_SENT) {
                /* SYN packet */
-               conntrack->proto.tcp.seen[0].td_end =
+               ct->proto.tcp.seen[0].td_end =
                        segment_seq_plus_len(ntohl(th->seq), skb->len,
                                             dataoff, th);
-               conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
-               if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
-                       conntrack->proto.tcp.seen[0].td_maxwin = 1;
-               conntrack->proto.tcp.seen[0].td_maxend =
-                       conntrack->proto.tcp.seen[0].td_end;
-
-               tcp_options(skb, dataoff, th, &conntrack->proto.tcp.seen[0]);
-               conntrack->proto.tcp.seen[1].flags = 0;
+               ct->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
+               if (ct->proto.tcp.seen[0].td_maxwin == 0)
+                       ct->proto.tcp.seen[0].td_maxwin = 1;
+               ct->proto.tcp.seen[0].td_maxend =
+                       ct->proto.tcp.seen[0].td_end;
+
+               tcp_options(skb, dataoff, th, &ct->proto.tcp.seen[0]);
+               ct->proto.tcp.seen[1].flags = 0;
        } else if (nf_ct_tcp_loose == 0) {
                /* Don't try to pick up connections. */
                return 0;
@@ -1010,32 +1008,32 @@ static int tcp_new(struct nf_conn *conntrack,
                 * its history is lost for us.
                 * Let's try to use the data from the packet.
                 */
-               conntrack->proto.tcp.seen[0].td_end =
+               ct->proto.tcp.seen[0].td_end =
                        segment_seq_plus_len(ntohl(th->seq), skb->len,
                                             dataoff, th);
-               conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
-               if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
-                       conntrack->proto.tcp.seen[0].td_maxwin = 1;
-               conntrack->proto.tcp.seen[0].td_maxend =
-                       conntrack->proto.tcp.seen[0].td_end +
-                       conntrack->proto.tcp.seen[0].td_maxwin;
-               conntrack->proto.tcp.seen[0].td_scale = 0;
+               ct->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
+               if (ct->proto.tcp.seen[0].td_maxwin == 0)
+                       ct->proto.tcp.seen[0].td_maxwin = 1;
+               ct->proto.tcp.seen[0].td_maxend =
+                       ct->proto.tcp.seen[0].td_end +
+                       ct->proto.tcp.seen[0].td_maxwin;
+               ct->proto.tcp.seen[0].td_scale = 0;
 
                /* We assume SACK and liberal window checking to handle
                 * window scaling */
-               conntrack->proto.tcp.seen[0].flags =
-               conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM |
-                                                    IP_CT_TCP_FLAG_BE_LIBERAL;
+               ct->proto.tcp.seen[0].flags =
+               ct->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM |
+                                             IP_CT_TCP_FLAG_BE_LIBERAL;
        }
 
-       conntrack->proto.tcp.seen[1].td_end = 0;
-       conntrack->proto.tcp.seen[1].td_maxend = 0;
-       conntrack->proto.tcp.seen[1].td_maxwin = 1;
-       conntrack->proto.tcp.seen[1].td_scale = 0;
+       ct->proto.tcp.seen[1].td_end = 0;
+       ct->proto.tcp.seen[1].td_maxend = 0;
+       ct->proto.tcp.seen[1].td_maxwin = 1;
+       ct->proto.tcp.seen[1].td_scale = 0;
 
        /* tcp_packet will set them */
-       conntrack->proto.tcp.state = TCP_CONNTRACK_NONE;
-       conntrack->proto.tcp.last_index = TCP_NONE_SET;
+       ct->proto.tcp.state = TCP_CONNTRACK_NONE;
+       ct->proto.tcp.last_index = TCP_NONE_SET;
 
        pr_debug("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
                 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
@@ -1098,16 +1096,16 @@ static const struct nla_policy tcp_nla_policy[CTA_PROTOINFO_TCP_MAX+1] = {
 
 static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
 {
-       struct nlattr *attr = cda[CTA_PROTOINFO_TCP];
+       struct nlattr *pattr = cda[CTA_PROTOINFO_TCP];
        struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1];
        int err;
 
        /* updates could not contain anything about the private
         * protocol info, in that case skip the parsing */
-       if (!attr)
+       if (!pattr)
                return 0;
 
-       err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr, tcp_nla_policy);
+       err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, pattr, tcp_nla_policy);
        if (err < 0)
                return err;
 
index 3848754110820894c241d568779c1643fc3623bf..b8a35cc06416e8e70e23036f70b83ca4727ad6c4 100644 (file)
@@ -30,7 +30,8 @@ static int udp_pkt_to_tuple(const struct sk_buff *skb,
                             unsigned int dataoff,
                             struct nf_conntrack_tuple *tuple)
 {
-       struct udphdr _hdr, *hp;
+       const struct udphdr *hp;
+       struct udphdr _hdr;
 
        /* Actually only need first 8 bytes. */
        hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
@@ -61,7 +62,7 @@ static int udp_print_tuple(struct seq_file *s,
 }
 
 /* Returns verdict for packet, and may modify conntracktype */
-static int udp_packet(struct nf_conn *conntrack,
+static int udp_packet(struct nf_conn *ct,
                      const struct sk_buff *skb,
                      unsigned int dataoff,
                      enum ip_conntrack_info ctinfo,
@@ -70,20 +71,19 @@ static int udp_packet(struct nf_conn *conntrack,
 {
        /* If we've seen traffic both ways, this is some kind of UDP
           stream.  Extend timeout. */
-       if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
-               nf_ct_refresh_acct(conntrack, ctinfo, skb,
-                                  nf_ct_udp_timeout_stream);
+       if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
+               nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout_stream);
                /* Also, more likely to be important, and not a probe */
-               if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status))
+               if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
                        nf_conntrack_event_cache(IPCT_STATUS, skb);
        } else
-               nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_udp_timeout);
+               nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout);
 
        return NF_ACCEPT;
 }
 
 /* Called when a new connection for this protocol found. */
-static int udp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
+static int udp_new(struct nf_conn *ct, const struct sk_buff *skb,
                   unsigned int dataoff)
 {
        return 1;
@@ -95,7 +95,8 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff,
                     unsigned int hooknum)
 {
        unsigned int udplen = skb->len - dataoff;
-       struct udphdr _hdr, *hdr;
+       const struct udphdr *hdr;
+       struct udphdr _hdr;
 
        /* Header is too small? */
        hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
index 070056d9bcd6f52dd7459c98df33ce8585d24f52..9dd03c7aeac6da64283e8cfe847204e77701e31e 100644 (file)
@@ -31,7 +31,8 @@ static int udplite_pkt_to_tuple(const struct sk_buff *skb,
                                unsigned int dataoff,
                                struct nf_conntrack_tuple *tuple)
 {
-       struct udphdr _hdr, *hp;
+       const struct udphdr *hp;
+       struct udphdr _hdr;
 
        hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
        if (hp == NULL)
@@ -60,7 +61,7 @@ static int udplite_print_tuple(struct seq_file *s,
 }
 
 /* Returns verdict for packet, and may modify conntracktype */
-static int udplite_packet(struct nf_conn *conntrack,
+static int udplite_packet(struct nf_conn *ct,
                          const struct sk_buff *skb,
                          unsigned int dataoff,
                          enum ip_conntrack_info ctinfo,
@@ -69,21 +70,20 @@ static int udplite_packet(struct nf_conn *conntrack,
 {
        /* If we've seen traffic both ways, this is some kind of UDP
           stream.  Extend timeout. */
-       if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
-               nf_ct_refresh_acct(conntrack, ctinfo, skb,
+       if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
+               nf_ct_refresh_acct(ct, ctinfo, skb,
                                   nf_ct_udplite_timeout_stream);
                /* Also, more likely to be important, and not a probe */
-               if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status))
+               if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
                        nf_conntrack_event_cache(IPCT_STATUS, skb);
        } else
-               nf_ct_refresh_acct(conntrack, ctinfo, skb,
-                                  nf_ct_udplite_timeout);
+               nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udplite_timeout);
 
        return NF_ACCEPT;
 }
 
 /* Called when a new connection for this protocol found. */
-static int udplite_new(struct nf_conn *conntrack, const struct sk_buff *skb,
+static int udplite_new(struct nf_conn *ct, const struct sk_buff *skb,
                       unsigned int dataoff)
 {
        return 1;
@@ -95,7 +95,8 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
                         unsigned int hooknum)
 {
        unsigned int udplen = skb->len - dataoff;
-       struct udphdr _hdr, *hdr;
+       const struct udphdr *hdr;
+       struct udphdr _hdr;
        unsigned int cscov;
 
        /* Header is too small? */
index b5a16c6e21c297df32297abfce82c4e894a31fe4..a70051d741a7014827c8c98aa7e2c0e05358ceb6 100644 (file)
@@ -62,8 +62,9 @@ static int help(struct sk_buff *skb,
                enum ip_conntrack_info ctinfo)
 {
        unsigned int dataoff, datalen;
-       struct tcphdr _tcph, *th;
-       char *sb_ptr;
+       const struct tcphdr *th;
+       struct tcphdr _tcph;
+       void *sb_ptr;
        int ret = NF_ACCEPT;
        int dir = CTINFO2DIR(ctinfo);
        struct nf_ct_sane_master *ct_sane_info;
@@ -99,7 +100,7 @@ static int help(struct sk_buff *skb,
                if (datalen != sizeof(struct sane_request))
                        goto out;
 
-               req = (struct sane_request *)sb_ptr;
+               req = sb_ptr;
                if (req->RPC_code != htonl(SANE_NET_START)) {
                        /* Not an interesting command */
                        ct_sane_info->state = SANE_STATE_NORMAL;
@@ -123,7 +124,7 @@ static int help(struct sk_buff *skb,
                goto out;
        }
 
-       reply = (struct sane_reply_net_start *)sb_ptr;
+       reply = sb_ptr;
        if (reply->status != htonl(SANE_STATUS_SUCCESS)) {
                /* saned refused the command */
                pr_debug("nf_ct_sane: unsuccessful SANE_STATUS = %u\n",
index 47d8947cf26348124698a0c90cbdc0323766b1d2..c521c891d35167d25369aa992d12ead46847db17 100644 (file)
@@ -28,7 +28,7 @@ MODULE_ALIAS("ip_conntrack_sip");
 
 #define MAX_PORTS      8
 static unsigned short ports[MAX_PORTS];
-static int ports_c;
+static unsigned int ports_c;
 module_param_array(ports, ushort, &ports_c, 0400);
 MODULE_PARM_DESC(ports, "port numbers of SIP servers");
 
@@ -48,10 +48,10 @@ unsigned int (*nf_nat_sdp_hook)(struct sk_buff *skb,
                                const char *dptr) __read_mostly;
 EXPORT_SYMBOL_GPL(nf_nat_sdp_hook);
 
-static int digits_len(struct nf_conn *, const char *, const char *, int *);
-static int epaddr_len(struct nf_conn *, const char *, const char *, int *);
-static int skp_digits_len(struct nf_conn *, const char *, const char *, int *);
-static int skp_epaddr_len(struct nf_conn *, const char *, const char *, int *);
+static int digits_len(const struct nf_conn *, const char *, const char *, int *);
+static int epaddr_len(const struct nf_conn *, const char *, const char *, int *);
+static int skp_digits_len(const struct nf_conn *, const char *, const char *, int *);
+static int skp_epaddr_len(const struct nf_conn *, const char *, const char *, int *);
 
 struct sip_header_nfo {
        const char      *lname;
@@ -61,7 +61,7 @@ struct sip_header_nfo {
        size_t          snlen;
        size_t          ln_strlen;
        int             case_sensitive;
-       int             (*match_len)(struct nf_conn *, const char *,
+       int             (*match_len)(const struct nf_conn *, const char *,
                                     const char *, int *);
 };
 
@@ -225,7 +225,7 @@ const char *ct_sip_search(const char *needle, const char *haystack,
 }
 EXPORT_SYMBOL_GPL(ct_sip_search);
 
-static int digits_len(struct nf_conn *ct, const char *dptr,
+static int digits_len(const struct nf_conn *ct, const char *dptr,
                      const char *limit, int *shift)
 {
        int len = 0;
@@ -237,7 +237,7 @@ static int digits_len(struct nf_conn *ct, const char *dptr,
 }
 
 /* get digits length, skipping blank spaces. */
-static int skp_digits_len(struct nf_conn *ct, const char *dptr,
+static int skp_digits_len(const struct nf_conn *ct, const char *dptr,
                          const char *limit, int *shift)
 {
        for (; dptr <= limit && *dptr == ' '; dptr++)
@@ -246,8 +246,9 @@ static int skp_digits_len(struct nf_conn *ct, const char *dptr,
        return digits_len(ct, dptr, limit, shift);
 }
 
-static int parse_addr(struct nf_conn *ct, const char *cp, const char **endp,
-                     union nf_inet_addr *addr, const char *limit)
+static int parse_addr(const struct nf_conn *ct, const char *cp,
+                      const char **endp, union nf_inet_addr *addr,
+                      const char *limit)
 {
        const char *end;
        int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
@@ -272,7 +273,7 @@ static int parse_addr(struct nf_conn *ct, const char *cp, const char **endp,
 }
 
 /* skip ip address. returns its length. */
-static int epaddr_len(struct nf_conn *ct, const char *dptr,
+static int epaddr_len(const struct nf_conn *ct, const char *dptr,
                      const char *limit, int *shift)
 {
        union nf_inet_addr addr;
@@ -292,7 +293,7 @@ static int epaddr_len(struct nf_conn *ct, const char *dptr,
 }
 
 /* get address length, skiping user info. */
-static int skp_epaddr_len(struct nf_conn *ct, const char *dptr,
+static int skp_epaddr_len(const struct nf_conn *ct, const char *dptr,
                          const char *limit, int *shift)
 {
        const char *start = dptr;
@@ -319,7 +320,7 @@ static int skp_epaddr_len(struct nf_conn *ct, const char *dptr,
 }
 
 /* Returns 0 if not found, -1 error parsing. */
-int ct_sip_get_info(struct nf_conn *ct,
+int ct_sip_get_info(const struct nf_conn *ct,
                    const char *dptr, size_t dlen,
                    unsigned int *matchoff,
                    unsigned int *matchlen,
@@ -407,7 +408,7 @@ static int sip_help(struct sk_buff *skb,
        unsigned int dataoff, datalen;
        const char *dptr;
        int ret = NF_ACCEPT;
-       int matchoff, matchlen;
+       unsigned int matchoff, matchlen;
        u_int16_t port;
        enum sip_header_pos pos;
        typeof(nf_nat_sip_hook) nf_nat_sip;
index 696074a037c1a10a1e1177854a2f303da8434541..e88e96af613d68938fe989034299be0f2c9fee5f 100644 (file)
@@ -31,8 +31,8 @@ MODULE_LICENSE("GPL");
 #ifdef CONFIG_PROC_FS
 int
 print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
-           struct nf_conntrack_l3proto *l3proto,
-           struct nf_conntrack_l4proto *l4proto)
+            const struct nf_conntrack_l3proto *l3proto,
+            const struct nf_conntrack_l4proto *l4proto)
 {
        return l3proto->print_tuple(s, tuple) || l4proto->print_tuple(s, tuple);
 }
@@ -58,12 +58,14 @@ struct ct_iter_state {
 static struct hlist_node *ct_get_first(struct seq_file *seq)
 {
        struct ct_iter_state *st = seq->private;
+       struct hlist_node *n;
 
        for (st->bucket = 0;
             st->bucket < nf_conntrack_htable_size;
             st->bucket++) {
-               if (!hlist_empty(&nf_conntrack_hash[st->bucket]))
-                       return nf_conntrack_hash[st->bucket].first;
+               n = rcu_dereference(nf_conntrack_hash[st->bucket].first);
+               if (n)
+                       return n;
        }
        return NULL;
 }
@@ -73,11 +75,11 @@ static struct hlist_node *ct_get_next(struct seq_file *seq,
 {
        struct ct_iter_state *st = seq->private;
 
-       head = head->next;
+       head = rcu_dereference(head->next);
        while (head == NULL) {
                if (++st->bucket >= nf_conntrack_htable_size)
                        return NULL;
-               head = nf_conntrack_hash[st->bucket].first;
+               head = rcu_dereference(nf_conntrack_hash[st->bucket].first);
        }
        return head;
 }
@@ -93,8 +95,9 @@ static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(RCU)
 {
-       read_lock_bh(&nf_conntrack_lock);
+       rcu_read_lock();
        return ct_get_idx(seq, *pos);
 }
 
@@ -105,79 +108,80 @@ static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
 }
 
 static void ct_seq_stop(struct seq_file *s, void *v)
+       __releases(RCU)
 {
-       read_unlock_bh(&nf_conntrack_lock);
+       rcu_read_unlock();
 }
 
 /* return 0 on success, 1 in case of error */
 static int ct_seq_show(struct seq_file *s, void *v)
 {
        const struct nf_conntrack_tuple_hash *hash = v;
-       const struct nf_conn *conntrack = nf_ct_tuplehash_to_ctrack(hash);
-       struct nf_conntrack_l3proto *l3proto;
-       struct nf_conntrack_l4proto *l4proto;
+       const struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
+       const struct nf_conntrack_l3proto *l3proto;
+       const struct nf_conntrack_l4proto *l4proto;
 
-       NF_CT_ASSERT(conntrack);
+       NF_CT_ASSERT(ct);
 
        /* we only want to print DIR_ORIGINAL */
        if (NF_CT_DIRECTION(hash))
                return 0;
 
-       l3proto = __nf_ct_l3proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+       l3proto = __nf_ct_l3proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL]
                                       .tuple.src.l3num);
 
        NF_CT_ASSERT(l3proto);
-       l4proto = __nf_ct_l4proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+       l4proto = __nf_ct_l4proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL]
                                   .tuple.src.l3num,
-                                  conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+                                  ct->tuplehash[IP_CT_DIR_ORIGINAL]
                                   .tuple.dst.protonum);
        NF_CT_ASSERT(l4proto);
 
        if (seq_printf(s, "%-8s %u %-8s %u %ld ",
                       l3proto->name,
-                      conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num,
+                      ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num,
                       l4proto->name,
-                      conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
-                      timer_pending(&conntrack->timeout)
-                      ? (long)(conntrack->timeout.expires - jiffies)/HZ : 0) != 0)
+                      ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
+                      timer_pending(&ct->timeout)
+                      ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0)
                return -ENOSPC;
 
-       if (l4proto->print_conntrack && l4proto->print_conntrack(s, conntrack))
+       if (l4proto->print_conntrack && l4proto->print_conntrack(s, ct))
                return -ENOSPC;
 
-       if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+       if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
                        l3proto, l4proto))
                return -ENOSPC;
 
-       if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_ORIGINAL]))
+       if (seq_print_counters(s, &ct->counters[IP_CT_DIR_ORIGINAL]))
                return -ENOSPC;
 
-       if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
+       if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
                if (seq_printf(s, "[UNREPLIED] "))
                        return -ENOSPC;
 
-       if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
+       if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple,
                        l3proto, l4proto))
                return -ENOSPC;
 
-       if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_REPLY]))
+       if (seq_print_counters(s, &ct->counters[IP_CT_DIR_REPLY]))
                return -ENOSPC;
 
-       if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
+       if (test_bit(IPS_ASSURED_BIT, &ct->status))
                if (seq_printf(s, "[ASSURED] "))
                        return -ENOSPC;
 
 #if defined(CONFIG_NF_CONNTRACK_MARK)
-       if (seq_printf(s, "mark=%u ", conntrack->mark))
+       if (seq_printf(s, "mark=%u ", ct->mark))
                return -ENOSPC;
 #endif
 
 #ifdef CONFIG_NF_CONNTRACK_SECMARK
-       if (seq_printf(s, "secmark=%u ", conntrack->secmark))
+       if (seq_printf(s, "secmark=%u ", ct->secmark))
                return -ENOSPC;
 #endif
 
-       if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use)))
+       if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use)))
                return -ENOSPC;
 
        return 0;
@@ -242,7 +246,7 @@ static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
 static int ct_cpu_seq_show(struct seq_file *seq, void *v)
 {
        unsigned int nr_conntracks = atomic_read(&nf_conntrack_count);
-       struct ip_conntrack_stat *st = v;
+       const struct ip_conntrack_stat *st = v;
 
        if (v == SEQ_START_TOKEN) {
                seq_printf(seq, "entries  searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error  expect_new expect_create expect_delete\n");
@@ -380,7 +384,7 @@ static ctl_table nf_ct_netfilter_table[] = {
        { .ctl_name = 0 }
 };
 
-struct ctl_path nf_ct_path[] = {
+static struct ctl_path nf_ct_path[] = {
        { .procname = "net", .ctl_name = CTL_NET, },
        { }
 };
index e894aa1ff3ad4a683bd05a8f028504342c21589c..bd2e800f23cc8bc1c9fb8708c3b6e6426dfbaa8f 100644 (file)
@@ -25,7 +25,7 @@ MODULE_ALIAS("ip_conntrack_tftp");
 
 #define MAX_PORTS 8
 static unsigned short ports[MAX_PORTS];
-static int ports_c;
+static unsigned int ports_c;
 module_param_array(ports, ushort, &ports_c, 0400);
 MODULE_PARM_DESC(ports, "Port numbers of TFTP servers");
 
@@ -39,7 +39,8 @@ static int tftp_help(struct sk_buff *skb,
                     struct nf_conn *ct,
                     enum ip_conntrack_info ctinfo)
 {
-       struct tftphdr _tftph, *tfh;
+       const struct tftphdr *tfh;
+       struct tftphdr _tftph;
        struct nf_conntrack_expect *exp;
        struct nf_conntrack_tuple *tuple;
        unsigned int ret = NF_ACCEPT;
index 4f5f2885fcac31de3d43f2eceba9c8ba8ebf75eb..cec9976aecbf5c5e8592c8c841d57532f8748655 100644 (file)
@@ -103,6 +103,7 @@ EXPORT_SYMBOL(nf_log_packet);
 
 #ifdef CONFIG_PROC_FS
 static void *seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(RCU)
 {
        rcu_read_lock();
 
@@ -123,6 +124,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
 }
 
 static void seq_stop(struct seq_file *s, void *v)
+       __releases(RCU)
 {
        rcu_read_unlock();
 }
index 5013cb97ce2ba82c481023ba552461f5185bbc8d..7efa40d47393727447fd1bdbf88d579914e5cfc4 100644 (file)
@@ -467,7 +467,7 @@ __build_packet_message(struct nfulnl_instance *inst,
                read_lock_bh(&skb->sk->sk_callback_lock);
                if (skb->sk->sk_socket && skb->sk->sk_socket->file) {
                        __be32 uid = htonl(skb->sk->sk_socket->file->f_uid);
-                       __be32 gid = htons(skb->sk->sk_socket->file->f_gid);
+                       __be32 gid = htonl(skb->sk->sk_socket->file->f_gid);
                        /* need to unlock here since NLA_PUT may goto */
                        read_unlock_bh(&skb->sk->sk_callback_lock);
                        NLA_PUT_BE32(inst->skb, NFULA_UID, uid);
@@ -866,6 +866,7 @@ static struct hlist_node *get_idx(struct iter_state *st, loff_t pos)
 }
 
 static void *seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(instances_lock)
 {
        read_lock_bh(&instances_lock);
        return get_idx(seq->private, *pos);
@@ -878,6 +879,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
 }
 
 static void seq_stop(struct seq_file *s, void *v)
+       __releases(instances_lock)
 {
        read_unlock_bh(&instances_lock);
 }
index 51476f82bb54733af8f997d782284bbeafa1eae2..a48b20fe9cd6bf2759e1b723df5448c7fa903092 100644 (file)
@@ -360,7 +360,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
 
        if (data_len) {
                struct nlattr *nla;
-               int size = nla_attr_size(data_len);
+               int sz = nla_attr_size(data_len);
 
                if (skb_tailroom(skb) < nla_total_size(data_len)) {
                        printk(KERN_WARNING "nf_queue: no tailroom!\n");
@@ -369,7 +369,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
 
                nla = (struct nlattr *)skb_put(skb, nla_total_size(data_len));
                nla->nla_type = NFQA_PAYLOAD;
-               nla->nla_len = size;
+               nla->nla_len = sz;
 
                if (skb_copy_bits(entskb, 0, nla_data(nla), data_len))
                        BUG();
@@ -845,6 +845,7 @@ static struct hlist_node *get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(instances_lock)
 {
        spin_lock(&instances_lock);
        return get_idx(seq, *pos);
@@ -857,6 +858,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
 }
 
 static void seq_stop(struct seq_file *s, void *v)
+       __releases(instances_lock)
 {
        spin_unlock(&instances_lock);
 }
index 8d4fca96a4a719a054ee3ac0cb02643dc90113ba..a6792089fcf9d4d8430af560addfb8f8a758b7b5 100644 (file)
@@ -44,7 +44,6 @@ struct xt_af {
        struct mutex mutex;
        struct list_head match;
        struct list_head target;
-       struct list_head tables;
 #ifdef CONFIG_COMPAT
        struct mutex compat_mutex;
        struct compat_delta *compat_offsets;
@@ -59,12 +58,6 @@ static struct xt_af *xt;
 #define duprintf(format, args...)
 #endif
 
-enum {
-       TABLE,
-       TARGET,
-       MATCH,
-};
-
 static const char *xt_prefix[NPROTO] = {
        [AF_INET]       = "ip",
        [AF_INET6]      = "ip6",
@@ -400,7 +393,7 @@ int xt_compat_match_offset(struct xt_match *match)
 EXPORT_SYMBOL_GPL(xt_compat_match_offset);
 
 int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
-                             int *size)
+                             unsigned int *size)
 {
        struct xt_match *match = m->u.kernel.match;
        struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m;
@@ -427,7 +420,7 @@ int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
 EXPORT_SYMBOL_GPL(xt_compat_match_from_user);
 
 int xt_compat_match_to_user(struct xt_entry_match *m, void __user **dstptr,
-                           int *size)
+                           unsigned int *size)
 {
        struct xt_match *match = m->u.kernel.match;
        struct compat_xt_entry_match __user *cm = *dstptr;
@@ -494,7 +487,7 @@ int xt_compat_target_offset(struct xt_target *target)
 EXPORT_SYMBOL_GPL(xt_compat_target_offset);
 
 void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
-                               int *size)
+                               unsigned int *size)
 {
        struct xt_target *target = t->u.kernel.target;
        struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t;
@@ -520,7 +513,7 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
 EXPORT_SYMBOL_GPL(xt_compat_target_from_user);
 
 int xt_compat_target_to_user(struct xt_entry_target *t, void __user **dstptr,
-                            int *size)
+                            unsigned int *size)
 {
        struct xt_target *target = t->u.kernel.target;
        struct compat_xt_entry_target __user *ct = *dstptr;
@@ -597,14 +590,14 @@ void xt_free_table_info(struct xt_table_info *info)
 EXPORT_SYMBOL(xt_free_table_info);
 
 /* Find table by name, grabs mutex & ref.  Returns ERR_PTR() on error. */
-struct xt_table *xt_find_table_lock(int af, const char *name)
+struct xt_table *xt_find_table_lock(struct net *net, int af, const char *name)
 {
        struct xt_table *t;
 
        if (mutex_lock_interruptible(&xt[af].mutex) != 0)
                return ERR_PTR(-EINTR);
 
-       list_for_each_entry(t, &xt[af].tables, list)
+       list_for_each_entry(t, &net->xt.tables[af], list)
                if (strcmp(t->name, name) == 0 && try_module_get(t->me))
                        return t;
        mutex_unlock(&xt[af].mutex);
@@ -660,20 +653,27 @@ xt_replace_table(struct xt_table *table,
 }
 EXPORT_SYMBOL_GPL(xt_replace_table);
 
-int xt_register_table(struct xt_table *table,
-                     struct xt_table_info *bootstrap,
-                     struct xt_table_info *newinfo)
+struct xt_table *xt_register_table(struct net *net, struct xt_table *table,
+                                  struct xt_table_info *bootstrap,
+                                  struct xt_table_info *newinfo)
 {
        int ret;
        struct xt_table_info *private;
        struct xt_table *t;
 
+       /* Don't add one object to multiple lists. */
+       table = kmemdup(table, sizeof(struct xt_table), GFP_KERNEL);
+       if (!table) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
        ret = mutex_lock_interruptible(&xt[table->af].mutex);
        if (ret != 0)
-               return ret;
+               goto out_free;
 
        /* Don't autoload: we'd eat our tail... */
-       list_for_each_entry(t, &xt[table->af].tables, list) {
+       list_for_each_entry(t, &net->xt.tables[table->af], list) {
                if (strcmp(t->name, table->name) == 0) {
                        ret = -EEXIST;
                        goto unlock;
@@ -692,12 +692,16 @@ int xt_register_table(struct xt_table *table,
        /* save number of initial entries */
        private->initial_entries = private->number;
 
-       list_add(&table->list, &xt[table->af].tables);
+       list_add(&table->list, &net->xt.tables[table->af]);
+       mutex_unlock(&xt[table->af].mutex);
+       return table;
 
-       ret = 0;
  unlock:
        mutex_unlock(&xt[table->af].mutex);
-       return ret;
+out_free:
+       kfree(table);
+out:
+       return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(xt_register_table);
 
@@ -709,130 +713,204 @@ void *xt_unregister_table(struct xt_table *table)
        private = table->private;
        list_del(&table->list);
        mutex_unlock(&xt[table->af].mutex);
+       kfree(table);
 
        return private;
 }
 EXPORT_SYMBOL_GPL(xt_unregister_table);
 
 #ifdef CONFIG_PROC_FS
-static struct list_head *xt_get_idx(struct list_head *list, struct seq_file *seq, loff_t pos)
+struct xt_names_priv {
+       struct seq_net_private p;
+       int af;
+};
+static void *xt_table_seq_start(struct seq_file *seq, loff_t *pos)
 {
-       struct list_head *head = list->next;
+       struct xt_names_priv *priv = seq->private;
+       struct net *net = priv->p.net;
+       int af = priv->af;
 
-       if (!head || list_empty(list))
-               return NULL;
+       mutex_lock(&xt[af].mutex);
+       return seq_list_start(&net->xt.tables[af], *pos);
+}
 
-       while (pos && (head = head->next)) {
-               if (head == list)
-                       return NULL;
-               pos--;
-       }
-       return pos ? NULL : head;
-}
-
-static struct list_head *type2list(u_int16_t af, u_int16_t type)
-{
-       struct list_head *list;
-
-       switch (type) {
-       case TARGET:
-               list = &xt[af].target;
-               break;
-       case MATCH:
-               list = &xt[af].match;
-               break;
-       case TABLE:
-               list = &xt[af].tables;
-               break;
-       default:
-               list = NULL;
-               break;
-       }
+static void *xt_table_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       struct xt_names_priv *priv = seq->private;
+       struct net *net = priv->p.net;
+       int af = priv->af;
 
-       return list;
+       return seq_list_next(v, &net->xt.tables[af], pos);
 }
 
-static void *xt_tgt_seq_start(struct seq_file *seq, loff_t *pos)
+static void xt_table_seq_stop(struct seq_file *seq, void *v)
 {
-       struct proc_dir_entry *pde = (struct proc_dir_entry *) seq->private;
-       u_int16_t af = (unsigned long)pde->data & 0xffff;
-       u_int16_t type = (unsigned long)pde->data >> 16;
-       struct list_head *list;
+       struct xt_names_priv *priv = seq->private;
+       int af = priv->af;
 
-       if (af >= NPROTO)
-               return NULL;
+       mutex_unlock(&xt[af].mutex);
+}
 
-       list = type2list(af, type);
-       if (!list)
-               return NULL;
+static int xt_table_seq_show(struct seq_file *seq, void *v)
+{
+       struct xt_table *table = list_entry(v, struct xt_table, list);
 
-       if (mutex_lock_interruptible(&xt[af].mutex) != 0)
-               return NULL;
+       if (strlen(table->name))
+               return seq_printf(seq, "%s\n", table->name);
+       else
+               return 0;
+}
+
+static const struct seq_operations xt_table_seq_ops = {
+       .start  = xt_table_seq_start,
+       .next   = xt_table_seq_next,
+       .stop   = xt_table_seq_stop,
+       .show   = xt_table_seq_show,
+};
 
-       return xt_get_idx(list, seq, *pos);
+static int xt_table_open(struct inode *inode, struct file *file)
+{
+       int ret;
+       struct xt_names_priv *priv;
+
+       ret = seq_open_net(inode, file, &xt_table_seq_ops,
+                          sizeof(struct xt_names_priv));
+       if (!ret) {
+               priv = ((struct seq_file *)file->private_data)->private;
+               priv->af = (unsigned long)PDE(inode)->data;
+       }
+       return ret;
 }
 
-static void *xt_tgt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+static const struct file_operations xt_table_ops = {
+       .owner   = THIS_MODULE,
+       .open    = xt_table_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = seq_release,
+};
+
+static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos)
 {
-       struct proc_dir_entry *pde = seq->private;
-       u_int16_t af = (unsigned long)pde->data & 0xffff;
-       u_int16_t type = (unsigned long)pde->data >> 16;
-       struct list_head *list;
+       struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
+       u_int16_t af = (unsigned long)pde->data;
 
-       if (af >= NPROTO)
-               return NULL;
+       mutex_lock(&xt[af].mutex);
+       return seq_list_start(&xt[af].match, *pos);
+}
 
-       list = type2list(af, type);
-       if (!list)
-               return NULL;
+static void *xt_match_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
+       u_int16_t af = (unsigned long)pde->data;
 
-       (*pos)++;
-       return xt_get_idx(list, seq, *pos);
+       return seq_list_next(v, &xt[af].match, pos);
 }
 
-static void xt_tgt_seq_stop(struct seq_file *seq, void *v)
+static void xt_match_seq_stop(struct seq_file *seq, void *v)
 {
        struct proc_dir_entry *pde = seq->private;
-       u_int16_t af = (unsigned long)pde->data & 0xffff;
+       u_int16_t af = (unsigned long)pde->data;
 
        mutex_unlock(&xt[af].mutex);
 }
 
-static int xt_name_seq_show(struct seq_file *seq, void *v)
+static int xt_match_seq_show(struct seq_file *seq, void *v)
 {
-       char *name = (char *)v + sizeof(struct list_head);
+       struct xt_match *match = list_entry(v, struct xt_match, list);
 
-       if (strlen(name))
-               return seq_printf(seq, "%s\n", name);
+       if (strlen(match->name))
+               return seq_printf(seq, "%s\n", match->name);
        else
                return 0;
 }
 
-static const struct seq_operations xt_tgt_seq_ops = {
-       .start  = xt_tgt_seq_start,
-       .next   = xt_tgt_seq_next,
-       .stop   = xt_tgt_seq_stop,
-       .show   = xt_name_seq_show,
+static const struct seq_operations xt_match_seq_ops = {
+       .start  = xt_match_seq_start,
+       .next   = xt_match_seq_next,
+       .stop   = xt_match_seq_stop,
+       .show   = xt_match_seq_show,
 };
 
-static int xt_tgt_open(struct inode *inode, struct file *file)
+static int xt_match_open(struct inode *inode, struct file *file)
 {
        int ret;
 
-       ret = seq_open(file, &xt_tgt_seq_ops);
+       ret = seq_open(file, &xt_match_seq_ops);
        if (!ret) {
                struct seq_file *seq = file->private_data;
-               struct proc_dir_entry *pde = PDE(inode);
 
-               seq->private = pde;
+               seq->private = PDE(inode);
        }
+       return ret;
+}
+
+static const struct file_operations xt_match_ops = {
+       .owner   = THIS_MODULE,
+       .open    = xt_match_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = seq_release,
+};
+
+static void *xt_target_seq_start(struct seq_file *seq, loff_t *pos)
+{
+       struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
+       u_int16_t af = (unsigned long)pde->data;
+
+       mutex_lock(&xt[af].mutex);
+       return seq_list_start(&xt[af].target, *pos);
+}
+
+static void *xt_target_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
+       u_int16_t af = (unsigned long)pde->data;
+
+       return seq_list_next(v, &xt[af].target, pos);
+}
+
+static void xt_target_seq_stop(struct seq_file *seq, void *v)
+{
+       struct proc_dir_entry *pde = seq->private;
+       u_int16_t af = (unsigned long)pde->data;
+
+       mutex_unlock(&xt[af].mutex);
+}
 
+static int xt_target_seq_show(struct seq_file *seq, void *v)
+{
+       struct xt_target *target = list_entry(v, struct xt_target, list);
+
+       if (strlen(target->name))
+               return seq_printf(seq, "%s\n", target->name);
+       else
+               return 0;
+}
+
+static const struct seq_operations xt_target_seq_ops = {
+       .start  = xt_target_seq_start,
+       .next   = xt_target_seq_next,
+       .stop   = xt_target_seq_stop,
+       .show   = xt_target_seq_show,
+};
+
+static int xt_target_open(struct inode *inode, struct file *file)
+{
+       int ret;
+
+       ret = seq_open(file, &xt_target_seq_ops);
+       if (!ret) {
+               struct seq_file *seq = file->private_data;
+
+               seq->private = PDE(inode);
+       }
        return ret;
 }
 
-static const struct file_operations xt_file_ops = {
+static const struct file_operations xt_target_ops = {
        .owner   = THIS_MODULE,
-       .open    = xt_tgt_open,
+       .open    = xt_target_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
        .release = seq_release,
@@ -844,7 +922,7 @@ static const struct file_operations xt_file_ops = {
 
 #endif /* CONFIG_PROC_FS */
 
-int xt_proto_init(int af)
+int xt_proto_init(struct net *net, int af)
 {
 #ifdef CONFIG_PROC_FS
        char buf[XT_FUNCTION_MAXNAMELEN];
@@ -858,25 +936,25 @@ int xt_proto_init(int af)
 #ifdef CONFIG_PROC_FS
        strlcpy(buf, xt_prefix[af], sizeof(buf));
        strlcat(buf, FORMAT_TABLES, sizeof(buf));
-       proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
+       proc = proc_net_fops_create(net, buf, 0440, &xt_table_ops);
        if (!proc)
                goto out;
-       proc->data = (void *) ((unsigned long) af | (TABLE << 16));
+       proc->data = (void *)(unsigned long)af;
 
 
        strlcpy(buf, xt_prefix[af], sizeof(buf));
        strlcat(buf, FORMAT_MATCHES, sizeof(buf));
-       proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
+       proc = proc_net_fops_create(net, buf, 0440, &xt_match_ops);
        if (!proc)
                goto out_remove_tables;
-       proc->data = (void *) ((unsigned long) af | (MATCH << 16));
+       proc->data = (void *)(unsigned long)af;
 
        strlcpy(buf, xt_prefix[af], sizeof(buf));
        strlcat(buf, FORMAT_TARGETS, sizeof(buf));
-       proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
+       proc = proc_net_fops_create(net, buf, 0440, &xt_target_ops);
        if (!proc)
                goto out_remove_matches;
-       proc->data = (void *) ((unsigned long) af | (TARGET << 16));
+       proc->data = (void *)(unsigned long)af;
 #endif
 
        return 0;
@@ -885,42 +963,54 @@ int xt_proto_init(int af)
 out_remove_matches:
        strlcpy(buf, xt_prefix[af], sizeof(buf));
        strlcat(buf, FORMAT_MATCHES, sizeof(buf));
-       proc_net_remove(&init_net, buf);
+       proc_net_remove(net, buf);
 
 out_remove_tables:
        strlcpy(buf, xt_prefix[af], sizeof(buf));
        strlcat(buf, FORMAT_TABLES, sizeof(buf));
-       proc_net_remove(&init_net, buf);
+       proc_net_remove(net, buf);
 out:
        return -1;
 #endif
 }
 EXPORT_SYMBOL_GPL(xt_proto_init);
 
-void xt_proto_fini(int af)
+void xt_proto_fini(struct net *net, int af)
 {
 #ifdef CONFIG_PROC_FS
        char buf[XT_FUNCTION_MAXNAMELEN];
 
        strlcpy(buf, xt_prefix[af], sizeof(buf));
        strlcat(buf, FORMAT_TABLES, sizeof(buf));
-       proc_net_remove(&init_net, buf);
+       proc_net_remove(net, buf);
 
        strlcpy(buf, xt_prefix[af], sizeof(buf));
        strlcat(buf, FORMAT_TARGETS, sizeof(buf));
-       proc_net_remove(&init_net, buf);
+       proc_net_remove(net, buf);
 
        strlcpy(buf, xt_prefix[af], sizeof(buf));
        strlcat(buf, FORMAT_MATCHES, sizeof(buf));
-       proc_net_remove(&init_net, buf);
+       proc_net_remove(net, buf);
 #endif /*CONFIG_PROC_FS*/
 }
 EXPORT_SYMBOL_GPL(xt_proto_fini);
 
+static int __net_init xt_net_init(struct net *net)
+{
+       int i;
+
+       for (i = 0; i < NPROTO; i++)
+               INIT_LIST_HEAD(&net->xt.tables[i]);
+       return 0;
+}
+
+static struct pernet_operations xt_net_ops = {
+       .init = xt_net_init,
+};
 
 static int __init xt_init(void)
 {
-       int i;
+       int i, rv;
 
        xt = kmalloc(sizeof(struct xt_af) * NPROTO, GFP_KERNEL);
        if (!xt)
@@ -934,13 +1024,16 @@ static int __init xt_init(void)
 #endif
                INIT_LIST_HEAD(&xt[i].target);
                INIT_LIST_HEAD(&xt[i].match);
-               INIT_LIST_HEAD(&xt[i].tables);
        }
-       return 0;
+       rv = register_pernet_subsys(&xt_net_ops);
+       if (rv < 0)
+               kfree(xt);
+       return rv;
 }
 
 static void __exit xt_fini(void)
 {
+       unregister_pernet_subsys(&xt_net_ops);
        kfree(xt);
 }
 
index 60e3767cc71deb40f61e0d8ecaf9c87a76fc8996..217e2b6863225acf4353e7cd6f4869df3ce1da56 100644 (file)
 #include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/tcp.h>
+#include <net/dst.h>
+#include <net/flow.h>
 #include <net/ipv6.h>
+#include <net/route.h>
 #include <net/tcp.h>
 
 #include <linux/netfilter_ipv4/ip_tables.h>
@@ -41,6 +44,7 @@ optlen(const u_int8_t *opt, unsigned int offset)
 static int
 tcpmss_mangle_packet(struct sk_buff *skb,
                     const struct xt_tcpmss_info *info,
+                    unsigned int in_mtu,
                     unsigned int tcphoff,
                     unsigned int minlen)
 {
@@ -76,7 +80,13 @@ tcpmss_mangle_packet(struct sk_buff *skb,
                                       dst_mtu(skb->dst));
                        return -1;
                }
-               newmss = dst_mtu(skb->dst) - minlen;
+               if (in_mtu <= minlen) {
+                       if (net_ratelimit())
+                               printk(KERN_ERR "xt_TCPMSS: unknown or "
+                                      "invalid path-MTU (%u)\n", in_mtu);
+                       return -1;
+               }
+               newmss = min(dst_mtu(skb->dst), in_mtu) - minlen;
        } else
                newmss = info->mss;
 
@@ -137,6 +147,28 @@ tcpmss_mangle_packet(struct sk_buff *skb,
        return TCPOLEN_MSS;
 }
 
+static u_int32_t tcpmss_reverse_mtu4(const struct iphdr *iph)
+{
+       struct flowi fl = {
+               .fl4_dst = iph->saddr,
+       };
+       const struct nf_afinfo *ai;
+       struct rtable *rt = NULL;
+       u_int32_t mtu     = ~0U;
+
+       rcu_read_lock();
+       ai = nf_get_afinfo(AF_INET);
+       if (ai != NULL)
+               ai->route((struct dst_entry **)&rt, &fl);
+       rcu_read_unlock();
+
+       if (rt != NULL) {
+               mtu = dst_mtu(&rt->u.dst);
+               dst_release(&rt->u.dst);
+       }
+       return mtu;
+}
+
 static unsigned int
 tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
            const struct net_device *out, unsigned int hooknum,
@@ -146,7 +178,8 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
        __be16 newlen;
        int ret;
 
-       ret = tcpmss_mangle_packet(skb, targinfo, iph->ihl * 4,
+       ret = tcpmss_mangle_packet(skb, targinfo, tcpmss_reverse_mtu4(iph),
+                                  iph->ihl * 4,
                                   sizeof(*iph) + sizeof(struct tcphdr));
        if (ret < 0)
                return NF_DROP;
@@ -160,6 +193,28 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
 }
 
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+static u_int32_t tcpmss_reverse_mtu6(const struct ipv6hdr *iph)
+{
+       struct flowi fl = {
+               .fl6_dst = iph->saddr,
+       };
+       const struct nf_afinfo *ai;
+       struct rtable *rt = NULL;
+       u_int32_t mtu     = ~0U;
+
+       rcu_read_lock();
+       ai = nf_get_afinfo(AF_INET6);
+       if (ai != NULL)
+               ai->route((struct dst_entry **)&rt, &fl);
+       rcu_read_unlock();
+
+       if (rt != NULL) {
+               mtu = dst_mtu(&rt->u.dst);
+               dst_release(&rt->u.dst);
+       }
+       return mtu;
+}
+
 static unsigned int
 tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
            const struct net_device *out, unsigned int hooknum,
@@ -174,7 +229,8 @@ tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
        tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr);
        if (tcphoff < 0)
                return NF_DROP;
-       ret = tcpmss_mangle_packet(skb, targinfo, tcphoff,
+       ret = tcpmss_mangle_packet(skb, targinfo, tcpmss_reverse_mtu6(ipv6h),
+                                  tcphoff,
                                   sizeof(*ipv6h) + sizeof(struct tcphdr));
        if (ret < 0)
                return NF_DROP;
index e00ecd974fa3cf9882b406d5c33157f1fd29d93c..3b0111933f601782887e4edc8f7500aff4a2116f 100644 (file)
@@ -120,11 +120,11 @@ static int count_them(struct xt_connlimit_data *data,
        else
                hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)];
 
-       read_lock_bh(&nf_conntrack_lock);
+       rcu_read_lock();
 
        /* check the saved connections */
        list_for_each_entry_safe(conn, tmp, hash, list) {
-               found    = __nf_conntrack_find(&conn->tuple, NULL);
+               found    = __nf_conntrack_find(&conn->tuple);
                found_ct = NULL;
 
                if (found != NULL)
@@ -163,7 +163,7 @@ static int count_them(struct xt_connlimit_data *data,
                        ++matches;
        }
 
-       read_unlock_bh(&nf_conntrack_lock);
+       rcu_read_unlock();
 
        if (addit) {
                /* save the new connection in our list */
index e92190eafcc5b2cc74ed1a748a73bc7676990472..85330856a29c52065771c413737f958639d7cd20 100644 (file)
@@ -4,7 +4,6 @@
  *
  *     (C) 2001  Marc Boucher (marc@mbsi.ca).
  *     Copyright Â© CC Computer Consultants GmbH, 2007 - 2008
- *     Jan Engelhardt <jengelh@computergmbh.de>
  *
  *     This program is free software; you can redistribute it and/or modify
  *     it under the terms of the GNU General Public License version 2 as
@@ -20,6 +19,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
 MODULE_DESCRIPTION("Xtables: connection tracking state match");
 MODULE_ALIAS("ipt_conntrack");
 MODULE_ALIAS("ip6t_conntrack");
@@ -166,6 +166,44 @@ conntrack_mt_repldst(const struct nf_conn *ct,
               &info->repldst_addr, &info->repldst_mask, family);
 }
 
+static inline bool
+ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info,
+                    const struct nf_conn *ct)
+{
+       const struct nf_conntrack_tuple *tuple;
+
+       tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
+       if ((info->match_flags & XT_CONNTRACK_PROTO) &&
+           (tuple->dst.protonum == info->l4proto) ^
+           !(info->invert_flags & XT_CONNTRACK_PROTO))
+               return false;
+
+       /* Shortcut to match all recognized protocols by using ->src.all. */
+       if ((info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) &&
+           (tuple->src.u.all == info->origsrc_port) ^
+           !(info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT))
+               return false;
+
+       if ((info->match_flags & XT_CONNTRACK_ORIGDST_PORT) &&
+           (tuple->dst.u.all == info->origdst_port) ^
+           !(info->invert_flags & XT_CONNTRACK_ORIGDST_PORT))
+               return false;
+
+       tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+
+       if ((info->match_flags & XT_CONNTRACK_REPLSRC_PORT) &&
+           (tuple->src.u.all == info->replsrc_port) ^
+           !(info->invert_flags & XT_CONNTRACK_REPLSRC_PORT))
+               return false;
+
+       if ((info->match_flags & XT_CONNTRACK_REPLDST_PORT) &&
+           (tuple->dst.u.all == info->repldst_port) ^
+           !(info->invert_flags & XT_CONNTRACK_REPLDST_PORT))
+               return false;
+
+       return true;
+}
+
 static bool
 conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
              const struct net_device *out, const struct xt_match *match,
@@ -200,10 +238,9 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
 
        if (ct == NULL)
                return info->match_flags & XT_CONNTRACK_STATE;
-
-       if ((info->match_flags & XT_CONNTRACK_PROTO) &&
-           ((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
-           info->l4proto) ^ !(info->invert_flags & XT_CONNTRACK_PROTO)))
+       if ((info->match_flags & XT_CONNTRACK_DIRECTION) &&
+           (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) ^
+           !!(info->invert_flags & XT_CONNTRACK_DIRECTION))
                return false;
 
        if (info->match_flags & XT_CONNTRACK_ORIGSRC)
@@ -226,6 +263,9 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
                    !(info->invert_flags & XT_CONNTRACK_REPLDST))
                        return false;
 
+       if (!ct_proto_port_check(info, ct))
+               return false;
+
        if ((info->match_flags & XT_CONNTRACK_STATUS) &&
            (!!(info->status_mask & ct->status) ^
            !(info->invert_flags & XT_CONNTRACK_STATUS)))
index d479ca980115af614e25ef411917d7f83c4e4044..744c7f2ab0b1feb7c01c8d05c4867160a945caf3 100644 (file)
@@ -1,9 +1,9 @@
-/* iptables match extension to limit the number of packets per second
- * seperately for each hashbucket (sourceip/sourceport/dstip/dstport)
+/*
+ *     xt_hashlimit - Netfilter module to limit the number of packets per time
+ *     seperately for each hashbucket (sourceip/sourceport/dstip/dstport)
  *
- * (C) 2003-2004 by Harald Welte <laforge@netfilter.org>
- *
- * $Id: ipt_hashlimit.c 3244 2004-10-20 16:24:29Z laforge@netfilter.org $
+ *     (C) 2003-2004 by Harald Welte <laforge@netfilter.org>
+ *     Copyright Â© CC Computer Consultants GmbH, 2007 - 2008
  *
  * Development of this code was funded by Astaro AG, http://www.astaro.com/
  */
@@ -35,6 +35,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
 MODULE_DESCRIPTION("Xtables: per hash-bucket rate-limit match");
 MODULE_ALIAS("ipt_hashlimit");
 MODULE_ALIAS("ip6t_hashlimit");
@@ -57,7 +58,7 @@ struct dsthash_dst {
                        __be32 dst[4];
                } ip6;
 #endif
-       } addr;
+       };
        __be16 src_port;
        __be16 dst_port;
 };
@@ -81,7 +82,7 @@ struct xt_hashlimit_htable {
        atomic_t use;
        int family;
 
-       struct hashlimit_cfg cfg;       /* config */
+       struct hashlimit_cfg1 cfg;      /* config */
 
        /* used internally */
        spinlock_t lock;                /* lock for list_head */
@@ -184,7 +185,7 @@ dsthash_free(struct xt_hashlimit_htable *ht, struct dsthash_ent *ent)
 }
 static void htable_gc(unsigned long htlong);
 
-static int htable_create(struct xt_hashlimit_info *minfo, int family)
+static int htable_create_v0(struct xt_hashlimit_info *minfo, int family)
 {
        struct xt_hashlimit_htable *hinfo;
        unsigned int size;
@@ -210,7 +211,18 @@ static int htable_create(struct xt_hashlimit_info *minfo, int family)
        minfo->hinfo = hinfo;
 
        /* copy match config into hashtable config */
-       memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
+       hinfo->cfg.mode        = minfo->cfg.mode;
+       hinfo->cfg.avg         = minfo->cfg.avg;
+       hinfo->cfg.burst       = minfo->cfg.burst;
+       hinfo->cfg.max         = minfo->cfg.max;
+       hinfo->cfg.gc_interval = minfo->cfg.gc_interval;
+       hinfo->cfg.expire      = minfo->cfg.expire;
+
+       if (family == AF_INET)
+               hinfo->cfg.srcmask = hinfo->cfg.dstmask = 32;
+       else
+               hinfo->cfg.srcmask = hinfo->cfg.dstmask = 128;
+
        hinfo->cfg.size = size;
        if (!hinfo->cfg.max)
                hinfo->cfg.max = 8 * hinfo->cfg.size;
@@ -246,6 +258,70 @@ static int htable_create(struct xt_hashlimit_info *minfo, int family)
        return 0;
 }
 
+static int htable_create(struct xt_hashlimit_mtinfo1 *minfo,
+                         unsigned int family)
+{
+       struct xt_hashlimit_htable *hinfo;
+       unsigned int size;
+       unsigned int i;
+
+       if (minfo->cfg.size) {
+               size = minfo->cfg.size;
+       } else {
+               size = (num_physpages << PAGE_SHIFT) / 16384 /
+                      sizeof(struct list_head);
+               if (num_physpages > 1024 * 1024 * 1024 / PAGE_SIZE)
+                       size = 8192;
+               if (size < 16)
+                       size = 16;
+       }
+       /* FIXME: don't use vmalloc() here or anywhere else -HW */
+       hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) +
+                       sizeof(struct list_head) * size);
+       if (hinfo == NULL) {
+               printk(KERN_ERR "xt_hashlimit: unable to create hashtable\n");
+               return -1;
+       }
+       minfo->hinfo = hinfo;
+
+       /* copy match config into hashtable config */
+       memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
+       hinfo->cfg.size = size;
+       if (hinfo->cfg.max == 0)
+               hinfo->cfg.max = 8 * hinfo->cfg.size;
+       else if (hinfo->cfg.max < hinfo->cfg.size)
+               hinfo->cfg.max = hinfo->cfg.size;
+
+       for (i = 0; i < hinfo->cfg.size; i++)
+               INIT_HLIST_HEAD(&hinfo->hash[i]);
+
+       atomic_set(&hinfo->use, 1);
+       hinfo->count = 0;
+       hinfo->family = family;
+       hinfo->rnd_initialized = 0;
+       spin_lock_init(&hinfo->lock);
+
+       hinfo->pde = create_proc_entry(minfo->name, 0,
+                                      family == AF_INET ? hashlimit_procdir4 :
+                                                          hashlimit_procdir6);
+       if (hinfo->pde == NULL) {
+               vfree(hinfo);
+               return -1;
+       }
+       hinfo->pde->proc_fops = &dl_file_ops;
+       hinfo->pde->data = hinfo;
+
+       setup_timer(&hinfo->timer, htable_gc, (unsigned long)hinfo);
+       hinfo->timer.expires = jiffies + msecs_to_jiffies(hinfo->cfg.gc_interval);
+       add_timer(&hinfo->timer);
+
+       spin_lock_bh(&hashlimit_lock);
+       hlist_add_head(&hinfo->node, &hashlimit_htables);
+       spin_unlock_bh(&hashlimit_lock);
+
+       return 0;
+}
+
 static bool select_all(const struct xt_hashlimit_htable *ht,
                       const struct dsthash_ent *he)
 {
@@ -388,6 +464,48 @@ static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
        dh->rateinfo.prev = now;
 }
 
+static inline __be32 maskl(__be32 a, unsigned int l)
+{
+       return htonl(ntohl(a) & ~(~(u_int32_t)0 >> l));
+}
+
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+static void hashlimit_ipv6_mask(__be32 *i, unsigned int p)
+{
+       switch (p) {
+       case 0:
+               i[0] = i[1] = 0;
+               i[2] = i[3] = 0;
+               break;
+       case 1 ... 31:
+               i[0] = maskl(i[0], p);
+               i[1] = i[2] = i[3] = 0;
+               break;
+       case 32:
+               i[1] = i[2] = i[3] = 0;
+               break;
+       case 33 ... 63:
+               i[1] = maskl(i[1], p - 32);
+               i[2] = i[3] = 0;
+               break;
+       case 64:
+               i[2] = i[3] = 0;
+               break;
+       case 65 ... 95:
+               i[2] = maskl(i[2], p - 64);
+               i[3] = 0;
+       case 96:
+               i[3] = 0;
+               break;
+       case 97 ... 127:
+               i[3] = maskl(i[3], p - 96);
+               break;
+       case 128:
+               break;
+       }
+}
+#endif
+
 static int
 hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
                   struct dsthash_dst *dst,
@@ -401,9 +519,11 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
        switch (hinfo->family) {
        case AF_INET:
                if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP)
-                       dst->addr.ip.dst = ip_hdr(skb)->daddr;
+                       dst->ip.dst = maskl(ip_hdr(skb)->daddr,
+                                     hinfo->cfg.dstmask);
                if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP)
-                       dst->addr.ip.src = ip_hdr(skb)->saddr;
+                       dst->ip.src = maskl(ip_hdr(skb)->saddr,
+                                     hinfo->cfg.srcmask);
 
                if (!(hinfo->cfg.mode &
                      (XT_HASHLIMIT_HASH_DPT | XT_HASHLIMIT_HASH_SPT)))
@@ -412,12 +532,16 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
                break;
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
        case AF_INET6:
-               if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP)
-                       memcpy(&dst->addr.ip6.dst, &ipv6_hdr(skb)->daddr,
-                              sizeof(dst->addr.ip6.dst));
-               if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP)
-                       memcpy(&dst->addr.ip6.src, &ipv6_hdr(skb)->saddr,
-                              sizeof(dst->addr.ip6.src));
+               if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP) {
+                       memcpy(&dst->ip6.dst, &ipv6_hdr(skb)->daddr,
+                              sizeof(dst->ip6.dst));
+                       hashlimit_ipv6_mask(dst->ip6.dst, hinfo->cfg.dstmask);
+               }
+               if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP) {
+                       memcpy(&dst->ip6.src, &ipv6_hdr(skb)->saddr,
+                              sizeof(dst->ip6.src));
+                       hashlimit_ipv6_mask(dst->ip6.src, hinfo->cfg.srcmask);
+               }
 
                if (!(hinfo->cfg.mode &
                      (XT_HASHLIMIT_HASH_DPT | XT_HASHLIMIT_HASH_SPT)))
@@ -457,10 +581,10 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
 }
 
 static bool
-hashlimit_mt(const struct sk_buff *skb, const struct net_device *in,
-             const struct net_device *out, const struct xt_match *match,
-             const void *matchinfo, int offset, unsigned int protoff,
-             bool *hotdrop)
+hashlimit_mt_v0(const struct sk_buff *skb, const struct net_device *in,
+                const struct net_device *out, const struct xt_match *match,
+                const void *matchinfo, int offset, unsigned int protoff,
+                bool *hotdrop)
 {
        const struct xt_hashlimit_info *r =
                ((const struct xt_hashlimit_info *)matchinfo)->u.master;
@@ -512,9 +636,62 @@ hotdrop:
 }
 
 static bool
-hashlimit_mt_check(const char *tablename, const void *inf,
-                   const struct xt_match *match, void *matchinfo,
-                   unsigned int hook_mask)
+hashlimit_mt(const struct sk_buff *skb, const struct net_device *in,
+             const struct net_device *out, const struct xt_match *match,
+             const void *matchinfo, int offset, unsigned int protoff,
+             bool *hotdrop)
+{
+       const struct xt_hashlimit_mtinfo1 *info = matchinfo;
+       struct xt_hashlimit_htable *hinfo = info->hinfo;
+       unsigned long now = jiffies;
+       struct dsthash_ent *dh;
+       struct dsthash_dst dst;
+
+       if (hashlimit_init_dst(hinfo, &dst, skb, protoff) < 0)
+               goto hotdrop;
+
+       spin_lock_bh(&hinfo->lock);
+       dh = dsthash_find(hinfo, &dst);
+       if (dh == NULL) {
+               dh = dsthash_alloc_init(hinfo, &dst);
+               if (dh == NULL) {
+                       spin_unlock_bh(&hinfo->lock);
+                       goto hotdrop;
+               }
+
+               dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire);
+               dh->rateinfo.prev = jiffies;
+               dh->rateinfo.credit = user2credits(hinfo->cfg.avg *
+                                     hinfo->cfg.burst);
+               dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg *
+                                         hinfo->cfg.burst);
+               dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
+       } else {
+               /* update expiration timeout */
+               dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire);
+               rateinfo_recalc(dh, now);
+       }
+
+       if (dh->rateinfo.credit >= dh->rateinfo.cost) {
+               /* below the limit */
+               dh->rateinfo.credit -= dh->rateinfo.cost;
+               spin_unlock_bh(&hinfo->lock);
+               return !(info->cfg.mode & XT_HASHLIMIT_INVERT);
+       }
+
+       spin_unlock_bh(&hinfo->lock);
+       /* default match is underlimit - so over the limit, we need to invert */
+       return info->cfg.mode & XT_HASHLIMIT_INVERT;
+
+ hotdrop:
+       *hotdrop = true;
+       return false;
+}
+
+static bool
+hashlimit_mt_check_v0(const char *tablename, const void *inf,
+                      const struct xt_match *match, void *matchinfo,
+                      unsigned int hook_mask)
 {
        struct xt_hashlimit_info *r = matchinfo;
 
@@ -546,7 +723,7 @@ hashlimit_mt_check(const char *tablename, const void *inf,
         * create duplicate proc files. -HW */
        mutex_lock(&hlimit_mutex);
        r->hinfo = htable_find_get(r->name, match->family);
-       if (!r->hinfo && htable_create(r, match->family) != 0) {
+       if (!r->hinfo && htable_create_v0(r, match->family) != 0) {
                mutex_unlock(&hlimit_mutex);
                return false;
        }
@@ -557,14 +734,68 @@ hashlimit_mt_check(const char *tablename, const void *inf,
        return true;
 }
 
+static bool
+hashlimit_mt_check(const char *tablename, const void *inf,
+                   const struct xt_match *match, void *matchinfo,
+                   unsigned int hook_mask)
+{
+       struct xt_hashlimit_mtinfo1 *info = matchinfo;
+
+       /* Check for overflow. */
+       if (info->cfg.burst == 0 ||
+           user2credits(info->cfg.avg * info->cfg.burst) <
+           user2credits(info->cfg.avg)) {
+               printk(KERN_ERR "xt_hashlimit: overflow, try lower: %u/%u\n",
+                      info->cfg.avg, info->cfg.burst);
+               return false;
+       }
+       if (info->cfg.gc_interval == 0 || info->cfg.expire == 0)
+               return false;
+       if (info->name[sizeof(info->name)-1] != '\0')
+               return false;
+       if (match->family == AF_INET) {
+               if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32)
+                       return false;
+       } else {
+               if (info->cfg.srcmask > 128 || info->cfg.dstmask > 128)
+                       return false;
+       }
+
+       /* This is the best we've got: We cannot release and re-grab lock,
+        * since checkentry() is called before x_tables.c grabs xt_mutex.
+        * We also cannot grab the hashtable spinlock, since htable_create will
+        * call vmalloc, and that can sleep.  And we cannot just re-search
+        * the list of htable's in htable_create(), since then we would
+        * create duplicate proc files. -HW */
+       mutex_lock(&hlimit_mutex);
+       info->hinfo = htable_find_get(info->name, match->family);
+       if (!info->hinfo && htable_create(info, match->family) != 0) {
+               mutex_unlock(&hlimit_mutex);
+               return false;
+       }
+       mutex_unlock(&hlimit_mutex);
+
+       /* Ugly hack: For SMP, we only want to use one set */
+       info->master = info;
+       return true;
+}
+
 static void
-hashlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
+hashlimit_mt_destroy_v0(const struct xt_match *match, void *matchinfo)
 {
        const struct xt_hashlimit_info *r = matchinfo;
 
        htable_put(r->hinfo);
 }
 
+static void
+hashlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
+{
+       const struct xt_hashlimit_mtinfo1 *info = matchinfo;
+
+       htable_put(info->hinfo);
+}
+
 #ifdef CONFIG_COMPAT
 struct compat_xt_hashlimit_info {
        char name[IFNAMSIZ];
@@ -592,38 +823,60 @@ static int hashlimit_mt_compat_to_user(void __user *dst, void *src)
 static struct xt_match hashlimit_mt_reg[] __read_mostly = {
        {
                .name           = "hashlimit",
+               .revision       = 0,
                .family         = AF_INET,
-               .match          = hashlimit_mt,
+               .match          = hashlimit_mt_v0,
                .matchsize      = sizeof(struct xt_hashlimit_info),
 #ifdef CONFIG_COMPAT
                .compatsize     = sizeof(struct compat_xt_hashlimit_info),
                .compat_from_user = hashlimit_mt_compat_from_user,
                .compat_to_user = hashlimit_mt_compat_to_user,
 #endif
-               .checkentry     = hashlimit_mt_check,
-               .destroy        = hashlimit_mt_destroy,
+               .checkentry     = hashlimit_mt_check_v0,
+               .destroy        = hashlimit_mt_destroy_v0,
                .me             = THIS_MODULE
        },
+       {
+               .name           = "hashlimit",
+               .revision       = 1,
+               .family         = AF_INET,
+               .match          = hashlimit_mt,
+               .matchsize      = sizeof(struct xt_hashlimit_mtinfo1),
+               .checkentry     = hashlimit_mt_check,
+               .destroy        = hashlimit_mt_destroy,
+               .me             = THIS_MODULE,
+       },
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
        {
                .name           = "hashlimit",
                .family         = AF_INET6,
-               .match          = hashlimit_mt,
+               .match          = hashlimit_mt_v0,
                .matchsize      = sizeof(struct xt_hashlimit_info),
 #ifdef CONFIG_COMPAT
                .compatsize     = sizeof(struct compat_xt_hashlimit_info),
                .compat_from_user = hashlimit_mt_compat_from_user,
                .compat_to_user = hashlimit_mt_compat_to_user,
 #endif
-               .checkentry     = hashlimit_mt_check,
-               .destroy        = hashlimit_mt_destroy,
+               .checkentry     = hashlimit_mt_check_v0,
+               .destroy        = hashlimit_mt_destroy_v0,
                .me             = THIS_MODULE
        },
+       {
+               .name           = "hashlimit",
+               .revision       = 1,
+               .family         = AF_INET6,
+               .match          = hashlimit_mt,
+               .matchsize      = sizeof(struct xt_hashlimit_mtinfo1),
+               .checkentry     = hashlimit_mt_check,
+               .destroy        = hashlimit_mt_destroy,
+               .me             = THIS_MODULE,
+       },
 #endif
 };
 
 /* PROC stuff */
 static void *dl_seq_start(struct seq_file *s, loff_t *pos)
+       __acquires(htable->lock)
 {
        struct proc_dir_entry *pde = s->private;
        struct xt_hashlimit_htable *htable = pde->data;
@@ -656,6 +909,7 @@ static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
 }
 
 static void dl_seq_stop(struct seq_file *s, void *v)
+       __releases(htable->lock)
 {
        struct proc_dir_entry *pde = s->private;
        struct xt_hashlimit_htable *htable = pde->data;
@@ -676,9 +930,9 @@ static int dl_seq_real_show(struct dsthash_ent *ent, int family,
                return seq_printf(s, "%ld %u.%u.%u.%u:%u->"
                                     "%u.%u.%u.%u:%u %u %u %u\n",
                                 (long)(ent->expires - jiffies)/HZ,
-                                NIPQUAD(ent->dst.addr.ip.src),
+                                NIPQUAD(ent->dst.ip.src),
                                 ntohs(ent->dst.src_port),
-                                NIPQUAD(ent->dst.addr.ip.dst),
+                                NIPQUAD(ent->dst.ip.dst),
                                 ntohs(ent->dst.dst_port),
                                 ent->rateinfo.credit, ent->rateinfo.credit_cap,
                                 ent->rateinfo.cost);
@@ -687,9 +941,9 @@ static int dl_seq_real_show(struct dsthash_ent *ent, int family,
                return seq_printf(s, "%ld " NIP6_FMT ":%u->"
                                     NIP6_FMT ":%u %u %u %u\n",
                                 (long)(ent->expires - jiffies)/HZ,
-                                NIP6(*(struct in6_addr *)&ent->dst.addr.ip6.src),
+                                NIP6(*(struct in6_addr *)&ent->dst.ip6.src),
                                 ntohs(ent->dst.src_port),
-                                NIP6(*(struct in6_addr *)&ent->dst.addr.ip6.dst),
+                                NIP6(*(struct in6_addr *)&ent->dst.ip6.dst),
                                 ntohs(ent->dst.dst_port),
                                 ent->rateinfo.credit, ent->rateinfo.credit_cap,
                                 ent->rateinfo.cost);
index dbea0e0893f371bc8100cfa1954fda8832de31f2..01035fc0e140637146c16b0413db56baf6aa3180 100644 (file)
@@ -101,7 +101,7 @@ iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b)
        int r;
 
        for (i = 0; i < 4; ++i) {
-               r = a->s6_addr32[i] - b->s6_addr32[i];
+               r = (__force u32)a->s6_addr32[i] - (__force u32)b->s6_addr32[i];
                if (r != 0)
                        return r;
        }
index d382f9cc38b0b5fbf90c4af50f4c5b5a2c7b2e65..9059c16144c3cb1d67fe3d6accc2f6951744e5a7 100644 (file)
@@ -4,8 +4,8 @@
  *
  * (C) 2000 Marc Boucher <marc@mbsi.ca>
  *
- * Copyright Â© CC Computer Consultants GmbH, 2007
- * Contact: <jengelh@computergmbh.de>
+ * Copyright Â© CC Computer Consultants GmbH, 2007 - 2008
+ * <jengelh@computergmbh.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -102,13 +102,15 @@ owner_mt(const struct sk_buff *skb, const struct net_device *in,
                       (XT_OWNER_UID | XT_OWNER_GID)) == 0;
 
        if (info->match & XT_OWNER_UID)
-               if ((filp->f_uid != info->uid) ^
-                   !!(info->invert & XT_OWNER_UID))
+               if ((filp->f_uid >= info->uid_min &&
+                   filp->f_uid <= info->uid_max) ^
+                   !(info->invert & XT_OWNER_UID))
                        return false;
 
        if (info->match & XT_OWNER_GID)
-               if ((filp->f_gid != info->gid) ^
-                   !!(info->invert & XT_OWNER_GID))
+               if ((filp->f_gid >= info->gid_min &&
+                   filp->f_gid <= info->gid_max) ^
+                   !(info->invert & XT_OWNER_GID))
                        return false;
 
        return true;
index 6b178e1247b5c3672e3857486d2d1346903181c2..ff9fb6ba0c5c80e9de6f8bc1b63d045f418f5c10 100644 (file)
@@ -1344,6 +1344,22 @@ static void netlink_data_ready(struct sock *sk, int len)
  *     queueing.
  */
 
+static void __netlink_release(struct sock *sk)
+{
+       /*
+        * Last sock_put should drop referrence to sk->sk_net. It has already
+        * been dropped in netlink_kernel_create. Taking referrence to stopping
+        * namespace is not an option.
+        * Take referrence to a socket to remove it from netlink lookup table
+        * _alive_ and after that destroy it in the context of init_net.
+        */
+
+       sock_hold(sk);
+       sock_release(sk->sk_socket);
+       sk->sk_net = get_net(&init_net);
+       sock_put(sk);
+}
+
 struct sock *
 netlink_kernel_create(struct net *net, int unit, unsigned int groups,
                      void (*input)(struct sk_buff *skb),
@@ -1362,8 +1378,18 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
        if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
                return NULL;
 
-       if (__netlink_create(net, sock, cb_mutex, unit) < 0)
-               goto out_sock_release;
+       /*
+        * We have to just have a reference on the net from sk, but don't
+        * get_net it. Besides, we cannot get and then put the net here.
+        * So we create one inside init_net and the move it to net.
+        */
+
+       if (__netlink_create(&init_net, sock, cb_mutex, unit) < 0)
+               goto out_sock_release_nosk;
+
+       sk = sock->sk;
+       put_net(sk->sk_net);
+       sk->sk_net = net;
 
        if (groups < 32)
                groups = 32;
@@ -1372,7 +1398,6 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
        if (!listeners)
                goto out_sock_release;
 
-       sk = sock->sk;
        sk->sk_data_ready = netlink_data_ready;
        if (input)
                nlk_sk(sk)->netlink_rcv = input;
@@ -1395,14 +1420,14 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
                nl_table[unit].registered++;
        }
        netlink_table_ungrab();
-
-       /* Do not hold an extra referrence to a namespace as this socket is
-        * internal to a namespace and does not prevent it to stop. */
-       put_net(net);
        return sk;
 
 out_sock_release:
        kfree(listeners);
+       __netlink_release(sk);
+       return NULL;
+
+out_sock_release_nosk:
        sock_release(sock);
        return NULL;
 }
@@ -1415,18 +1440,7 @@ netlink_kernel_release(struct sock *sk)
        if (sk == NULL || sk->sk_socket == NULL)
                return;
 
-       /*
-        * Last sock_put should drop referrence to sk->sk_net. It has already
-        * been dropped in netlink_kernel_create. Taking referrence to stopping
-        * namespace is not an option.
-        * Take referrence to a socket to remove it from netlink lookup table
-        * _alive_ and after that destroy it in the context of init_net.
-        */
-       sock_hold(sk);
-       sock_release(sk->sk_socket);
-
-       sk->sk_net = get_net(&init_net);
-       sock_put(sk);
+       __netlink_release(sk);
 }
 EXPORT_SYMBOL(netlink_kernel_release);
 
index d1e9d68f8ba0a003f0820f95800620d3030184cd..e4b051dbed612bc45726328f73a18c65ad81f87b 100644 (file)
@@ -84,6 +84,7 @@ static void rfkill_schedule_toggle(struct rfkill_task *task)
 static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN);
 static DEFINE_RFKILL_TASK(rfkill_bt, RFKILL_TYPE_BLUETOOTH);
 static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB);
+static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
 
 static void rfkill_event(struct input_handle *handle, unsigned int type,
                        unsigned int code, int down)
@@ -99,6 +100,9 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
                case KEY_UWB:
                        rfkill_schedule_toggle(&rfkill_uwb);
                        break;
+               case KEY_WIMAX:
+                       rfkill_schedule_toggle(&rfkill_wimax);
+                       break;
                default:
                        break;
                }
@@ -159,6 +163,11 @@ static const struct input_device_id rfkill_ids[] = {
                .evbit = { BIT_MASK(EV_KEY) },
                .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },
        },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
+       },
        { }
 };
 
index d06d338812e975081ff20f771ea2c9069abede4c..6562f868e82f07d7ce70169ef2920c41c07c1ae6 100644 (file)
@@ -126,6 +126,9 @@ static ssize_t rfkill_type_show(struct device *dev,
        case RFKILL_TYPE_UWB:
                type = "ultrawideband";
                break;
+       case RFKILL_TYPE_WIMAX:
+               type = "wimax";
+               break;
        default:
                BUG();
        }
index 3c04b00dab74930075adc8fc225225a1c8d431a4..d9231245a79aba9b3331d2a81b6bfd90820d7fd9 100644 (file)
@@ -15,7 +15,7 @@
 #include <net/af_rxrpc.h>
 #include "ar-internal.h"
 
-const char *rxrpc_call_states[] = {
+const char *const rxrpc_call_states[] = {
        [RXRPC_CALL_CLIENT_SEND_REQUEST]        = "ClSndReq",
        [RXRPC_CALL_CLIENT_AWAIT_REPLY]         = "ClAwtRpl",
        [RXRPC_CALL_CLIENT_RECV_REPLY]          = "ClRcvRpl",
index 58aaf892238ea56f52dbbaef34ea5039536a838e..1aaa2e804b0d118a78d6f94f4491b64a347f0bc5 100644 (file)
@@ -565,9 +565,9 @@ extern void __exit rxrpc_destroy_all_peers(void);
 /*
  * ar-proc.c
  */
-extern const char *rxrpc_call_states[];
-extern struct file_operations rxrpc_call_seq_fops;
-extern struct file_operations rxrpc_connection_seq_fops;
+extern const char *const rxrpc_call_states[];
+extern const struct file_operations rxrpc_call_seq_fops;
+extern const struct file_operations rxrpc_connection_seq_fops;
 
 /*
  * ar-recvmsg.c
index 2e83ce325d151e090e05cc0c18e2de55cd82a04d..83eda247fe487b1d8499926122eab8a315acd107 100644 (file)
@@ -14,7 +14,7 @@
 #include <net/af_rxrpc.h>
 #include "ar-internal.h"
 
-static const char *rxrpc_conn_states[] = {
+static const char *const rxrpc_conn_states[] = {
        [RXRPC_CONN_UNUSED]             = "Unused  ",
        [RXRPC_CONN_CLIENT]             = "Client  ",
        [RXRPC_CONN_SERVER_UNSECURED]   = "SvUnsec ",
@@ -98,7 +98,7 @@ static int rxrpc_call_seq_open(struct inode *inode, struct file *file)
        return seq_open(file, &rxrpc_call_seq_ops);
 }
 
-struct file_operations rxrpc_call_seq_fops = {
+const struct file_operations rxrpc_call_seq_fops = {
        .owner          = THIS_MODULE,
        .open           = rxrpc_call_seq_open,
        .read           = seq_read,
@@ -183,7 +183,7 @@ static int rxrpc_connection_seq_open(struct inode *inode, struct file *file)
        return seq_open(file, &rxrpc_connection_seq_ops);
 }
 
-struct file_operations rxrpc_connection_seq_fops = {
+const struct file_operations rxrpc_connection_seq_fops = {
        .owner          = THIS_MODULE,
        .open           = rxrpc_connection_seq_open,
        .read           = seq_read,
index 87af7c913d815e470e55b9274206ec5e320b1f1c..82adfe6447d7db004c7108731e0ad4c7b87f8657 100644 (file)
@@ -198,7 +198,7 @@ config NET_SCH_NETEM
 
 config NET_SCH_INGRESS
        tristate "Ingress Qdisc"
-       depends on NET_CLS_ACT || NETFILTER
+       depends on NET_CLS_ACT
        ---help---
          Say Y here if you want to use classifiers for incoming packets.
          If unsure, say Y.
@@ -307,6 +307,17 @@ config NET_CLS_RSVP6
          To compile this code as a module, choose M here: the
          module will be called cls_rsvp6.
 
+config NET_CLS_FLOW
+       tristate "Flow classifier"
+       select NET_CLS
+       ---help---
+         If you say Y here, you will be able to classify packets based on
+         a configurable combination of packet keys. This is mostly useful
+         in combination with SFQ.
+
+         To compile this code as a module, choose M here: the
+         module will be called cls_flow.
+
 config NET_EMATCH
        bool "Extended Matches"
        select NET_CLS
index 81ecbe8e7dce66d85d239857c9ee981cf886d3af..1d2b0f7df8487bbfbb633230c7dffe998f8257eb 100644 (file)
@@ -35,6 +35,7 @@ obj-$(CONFIG_NET_CLS_RSVP)    += cls_rsvp.o
 obj-$(CONFIG_NET_CLS_TCINDEX)  += cls_tcindex.o
 obj-$(CONFIG_NET_CLS_RSVP6)    += cls_rsvp6.o
 obj-$(CONFIG_NET_CLS_BASIC)    += cls_basic.o
+obj-$(CONFIG_NET_CLS_FLOW)     += cls_flow.o
 obj-$(CONFIG_NET_EMATCH)       += ematch.o
 obj-$(CONFIG_NET_EMATCH_CMP)   += em_cmp.o
 obj-$(CONFIG_NET_EMATCH_NBYTE) += em_nbyte.o
index 3377ca0d0a0c8470bc13e539fb4047820ed20b85..0fbedcabf1110759c41117253ae7cc73d6f7a768 100644 (file)
@@ -482,7 +482,7 @@ EXPORT_SYMBOL(tcf_exts_destroy);
 
 int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
                  struct nlattr *rate_tlv, struct tcf_exts *exts,
-                 struct tcf_ext_map *map)
+                 const struct tcf_ext_map *map)
 {
        memset(exts, 0, sizeof(*exts));
 
@@ -535,7 +535,7 @@ void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
 EXPORT_SYMBOL(tcf_exts_change);
 
 int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
-             struct tcf_ext_map *map)
+                 const struct tcf_ext_map *map)
 {
 #ifdef CONFIG_NET_CLS_ACT
        if (map->action && exts->action) {
@@ -571,7 +571,7 @@ EXPORT_SYMBOL(tcf_exts_dump);
 
 
 int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
-                       struct tcf_ext_map *map)
+                       const struct tcf_ext_map *map)
 {
 #ifdef CONFIG_NET_CLS_ACT
        if (exts->action)
index bfb4342ea88cfe982e6ac1b77a36c891f9cda575..956915c217d6dbc8599b3fa8248eedb8914160a3 100644 (file)
@@ -35,7 +35,7 @@ struct basic_filter
        struct list_head        link;
 };
 
-static struct tcf_ext_map basic_ext_map = {
+static const struct tcf_ext_map basic_ext_map = {
        .action = TCA_BASIC_ACT,
        .police = TCA_BASIC_POLICE
 };
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
new file mode 100644 (file)
index 0000000..5a7f6a3
--- /dev/null
@@ -0,0 +1,660 @@
+/*
+ * net/sched/cls_flow.c                Generic flow classifier
+ *
+ * Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/jhash.h>
+#include <linux/random.h>
+#include <linux/pkt_cls.h>
+#include <linux/skbuff.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+
+#include <net/pkt_cls.h>
+#include <net/ip.h>
+#include <net/route.h>
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+#include <net/netfilter/nf_conntrack.h>
+#endif
+
+struct flow_head {
+       struct list_head        filters;
+};
+
+struct flow_filter {
+       struct list_head        list;
+       struct tcf_exts         exts;
+       struct tcf_ematch_tree  ematches;
+       u32                     handle;
+
+       u32                     nkeys;
+       u32                     keymask;
+       u32                     mode;
+       u32                     mask;
+       u32                     xor;
+       u32                     rshift;
+       u32                     addend;
+       u32                     divisor;
+       u32                     baseclass;
+};
+
+static u32 flow_hashrnd __read_mostly;
+static int flow_hashrnd_initted __read_mostly;
+
+static const struct tcf_ext_map flow_ext_map = {
+       .action = TCA_FLOW_ACT,
+       .police = TCA_FLOW_POLICE,
+};
+
+static inline u32 addr_fold(void *addr)
+{
+       unsigned long a = (unsigned long)addr;
+
+       return (a & 0xFFFFFFFF) ^ (BITS_PER_LONG > 32 ? a >> 32 : 0);
+}
+
+static u32 flow_get_src(const struct sk_buff *skb)
+{
+       switch (skb->protocol) {
+       case __constant_htons(ETH_P_IP):
+               return ntohl(ip_hdr(skb)->saddr);
+       case __constant_htons(ETH_P_IPV6):
+               return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]);
+       default:
+               return addr_fold(skb->sk);
+       }
+}
+
+static u32 flow_get_dst(const struct sk_buff *skb)
+{
+       switch (skb->protocol) {
+       case __constant_htons(ETH_P_IP):
+               return ntohl(ip_hdr(skb)->daddr);
+       case __constant_htons(ETH_P_IPV6):
+               return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]);
+       default:
+               return addr_fold(skb->dst) ^ (__force u16)skb->protocol;
+       }
+}
+
+static u32 flow_get_proto(const struct sk_buff *skb)
+{
+       switch (skb->protocol) {
+       case __constant_htons(ETH_P_IP):
+               return ip_hdr(skb)->protocol;
+       case __constant_htons(ETH_P_IPV6):
+               return ipv6_hdr(skb)->nexthdr;
+       default:
+               return 0;
+       }
+}
+
+static int has_ports(u8 protocol)
+{
+       switch (protocol) {
+       case IPPROTO_TCP:
+       case IPPROTO_UDP:
+       case IPPROTO_UDPLITE:
+       case IPPROTO_SCTP:
+       case IPPROTO_DCCP:
+       case IPPROTO_ESP:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static u32 flow_get_proto_src(const struct sk_buff *skb)
+{
+       u32 res = 0;
+
+       switch (skb->protocol) {
+       case __constant_htons(ETH_P_IP): {
+               struct iphdr *iph = ip_hdr(skb);
+
+               if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
+                   has_ports(iph->protocol))
+                       res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4));
+               break;
+       }
+       case __constant_htons(ETH_P_IPV6): {
+               struct ipv6hdr *iph = ipv6_hdr(skb);
+
+               if (has_ports(iph->nexthdr))
+                       res = ntohs(*(__be16 *)&iph[1]);
+               break;
+       }
+       default:
+               res = addr_fold(skb->sk);
+       }
+
+       return res;
+}
+
+static u32 flow_get_proto_dst(const struct sk_buff *skb)
+{
+       u32 res = 0;
+
+       switch (skb->protocol) {
+       case __constant_htons(ETH_P_IP): {
+               struct iphdr *iph = ip_hdr(skb);
+
+               if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
+                   has_ports(iph->protocol))
+                       res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2));
+               break;
+       }
+       case __constant_htons(ETH_P_IPV6): {
+               struct ipv6hdr *iph = ipv6_hdr(skb);
+
+               if (has_ports(iph->nexthdr))
+                       res = ntohs(*(__be16 *)((void *)&iph[1] + 2));
+               break;
+       }
+       default:
+               res = addr_fold(skb->dst) ^ (__force u16)skb->protocol;
+       }
+
+       return res;
+}
+
+static u32 flow_get_iif(const struct sk_buff *skb)
+{
+       return skb->iif;
+}
+
+static u32 flow_get_priority(const struct sk_buff *skb)
+{
+       return skb->priority;
+}
+
+static u32 flow_get_mark(const struct sk_buff *skb)
+{
+       return skb->mark;
+}
+
+static u32 flow_get_nfct(const struct sk_buff *skb)
+{
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+       return addr_fold(skb->nfct);
+#else
+       return 0;
+#endif
+}
+
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+#define CTTUPLE(skb, member)                                           \
+({                                                                     \
+       enum ip_conntrack_info ctinfo;                                  \
+       struct nf_conn *ct = nf_ct_get(skb, &ctinfo);                   \
+       if (ct == NULL)                                                 \
+               goto fallback;                                          \
+       ct->tuplehash[CTINFO2DIR(ctinfo)].tuple.member;                 \
+})
+#else
+#define CTTUPLE(skb, member)                                           \
+({                                                                     \
+       goto fallback;                                                  \
+       0;                                                              \
+})
+#endif
+
+static u32 flow_get_nfct_src(const struct sk_buff *skb)
+{
+       switch (skb->protocol) {
+       case __constant_htons(ETH_P_IP):
+               return ntohl(CTTUPLE(skb, src.u3.ip));
+       case __constant_htons(ETH_P_IPV6):
+               return ntohl(CTTUPLE(skb, src.u3.ip6[3]));
+       }
+fallback:
+       return flow_get_src(skb);
+}
+
+static u32 flow_get_nfct_dst(const struct sk_buff *skb)
+{
+       switch (skb->protocol) {
+       case __constant_htons(ETH_P_IP):
+               return ntohl(CTTUPLE(skb, dst.u3.ip));
+       case __constant_htons(ETH_P_IPV6):
+               return ntohl(CTTUPLE(skb, dst.u3.ip6[3]));
+       }
+fallback:
+       return flow_get_dst(skb);
+}
+
+static u32 flow_get_nfct_proto_src(const struct sk_buff *skb)
+{
+       return ntohs(CTTUPLE(skb, src.u.all));
+fallback:
+       return flow_get_proto_src(skb);
+}
+
+static u32 flow_get_nfct_proto_dst(const struct sk_buff *skb)
+{
+       return ntohs(CTTUPLE(skb, dst.u.all));
+fallback:
+       return flow_get_proto_dst(skb);
+}
+
+static u32 flow_get_rtclassid(const struct sk_buff *skb)
+{
+#ifdef CONFIG_NET_CLS_ROUTE
+       if (skb->dst)
+               return skb->dst->tclassid;
+#endif
+       return 0;
+}
+
+static u32 flow_get_skuid(const struct sk_buff *skb)
+{
+       if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file)
+               return skb->sk->sk_socket->file->f_uid;
+       return 0;
+}
+
+static u32 flow_get_skgid(const struct sk_buff *skb)
+{
+       if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file)
+               return skb->sk->sk_socket->file->f_gid;
+       return 0;
+}
+
+static u32 flow_key_get(const struct sk_buff *skb, int key)
+{
+       switch (key) {
+       case FLOW_KEY_SRC:
+               return flow_get_src(skb);
+       case FLOW_KEY_DST:
+               return flow_get_dst(skb);
+       case FLOW_KEY_PROTO:
+               return flow_get_proto(skb);
+       case FLOW_KEY_PROTO_SRC:
+               return flow_get_proto_src(skb);
+       case FLOW_KEY_PROTO_DST:
+               return flow_get_proto_dst(skb);
+       case FLOW_KEY_IIF:
+               return flow_get_iif(skb);
+       case FLOW_KEY_PRIORITY:
+               return flow_get_priority(skb);
+       case FLOW_KEY_MARK:
+               return flow_get_mark(skb);
+       case FLOW_KEY_NFCT:
+               return flow_get_nfct(skb);
+       case FLOW_KEY_NFCT_SRC:
+               return flow_get_nfct_src(skb);
+       case FLOW_KEY_NFCT_DST:
+               return flow_get_nfct_dst(skb);
+       case FLOW_KEY_NFCT_PROTO_SRC:
+               return flow_get_nfct_proto_src(skb);
+       case FLOW_KEY_NFCT_PROTO_DST:
+               return flow_get_nfct_proto_dst(skb);
+       case FLOW_KEY_RTCLASSID:
+               return flow_get_rtclassid(skb);
+       case FLOW_KEY_SKUID:
+               return flow_get_skuid(skb);
+       case FLOW_KEY_SKGID:
+               return flow_get_skgid(skb);
+       default:
+               WARN_ON(1);
+               return 0;
+       }
+}
+
+static int flow_classify(struct sk_buff *skb, struct tcf_proto *tp,
+                        struct tcf_result *res)
+{
+       struct flow_head *head = tp->root;
+       struct flow_filter *f;
+       u32 keymask;
+       u32 classid;
+       unsigned int n, key;
+       int r;
+
+       list_for_each_entry(f, &head->filters, list) {
+               u32 keys[f->nkeys];
+
+               if (!tcf_em_tree_match(skb, &f->ematches, NULL))
+                       continue;
+
+               keymask = f->keymask;
+
+               for (n = 0; n < f->nkeys; n++) {
+                       key = ffs(keymask) - 1;
+                       keymask &= ~(1 << key);
+                       keys[n] = flow_key_get(skb, key);
+               }
+
+               if (f->mode == FLOW_MODE_HASH)
+                       classid = jhash2(keys, f->nkeys, flow_hashrnd);
+               else {
+                       classid = keys[0];
+                       classid = (classid & f->mask) ^ f->xor;
+                       classid = (classid >> f->rshift) + f->addend;
+               }
+
+               if (f->divisor)
+                       classid %= f->divisor;
+
+               res->class   = 0;
+               res->classid = TC_H_MAKE(f->baseclass, f->baseclass + classid);
+
+               r = tcf_exts_exec(skb, &f->exts, res);
+               if (r < 0)
+                       continue;
+               return r;
+       }
+       return -1;
+}
+
+static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = {
+       [TCA_FLOW_KEYS]         = { .type = NLA_U32 },
+       [TCA_FLOW_MODE]         = { .type = NLA_U32 },
+       [TCA_FLOW_BASECLASS]    = { .type = NLA_U32 },
+       [TCA_FLOW_RSHIFT]       = { .type = NLA_U32 },
+       [TCA_FLOW_ADDEND]       = { .type = NLA_U32 },
+       [TCA_FLOW_MASK]         = { .type = NLA_U32 },
+       [TCA_FLOW_XOR]          = { .type = NLA_U32 },
+       [TCA_FLOW_DIVISOR]      = { .type = NLA_U32 },
+       [TCA_FLOW_ACT]          = { .type = NLA_NESTED },
+       [TCA_FLOW_POLICE]       = { .type = NLA_NESTED },
+       [TCA_FLOW_EMATCHES]     = { .type = NLA_NESTED },
+};
+
+static int flow_change(struct tcf_proto *tp, unsigned long base,
+                      u32 handle, struct nlattr **tca,
+                      unsigned long *arg)
+{
+       struct flow_head *head = tp->root;
+       struct flow_filter *f;
+       struct nlattr *opt = tca[TCA_OPTIONS];
+       struct nlattr *tb[TCA_FLOW_MAX + 1];
+       struct tcf_exts e;
+       struct tcf_ematch_tree t;
+       unsigned int nkeys = 0;
+       u32 baseclass = 0;
+       u32 keymask = 0;
+       u32 mode;
+       int err;
+
+       if (opt == NULL)
+               return -EINVAL;
+
+       err = nla_parse_nested(tb, TCA_FLOW_MAX, opt, flow_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_FLOW_BASECLASS]) {
+               baseclass = nla_get_u32(tb[TCA_FLOW_BASECLASS]);
+               if (TC_H_MIN(baseclass) == 0)
+                       return -EINVAL;
+       }
+
+       if (tb[TCA_FLOW_KEYS]) {
+               keymask = nla_get_u32(tb[TCA_FLOW_KEYS]);
+               if (fls(keymask) - 1 > FLOW_KEY_MAX)
+                       return -EOPNOTSUPP;
+
+               nkeys = hweight32(keymask);
+               if (nkeys == 0)
+                       return -EINVAL;
+       }
+
+       err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map);
+       if (err < 0)
+               return err;
+
+       err = tcf_em_tree_validate(tp, tb[TCA_FLOW_EMATCHES], &t);
+       if (err < 0)
+               goto err1;
+
+       f = (struct flow_filter *)*arg;
+       if (f != NULL) {
+               err = -EINVAL;
+               if (f->handle != handle && handle)
+                       goto err2;
+
+               mode = f->mode;
+               if (tb[TCA_FLOW_MODE])
+                       mode = nla_get_u32(tb[TCA_FLOW_MODE]);
+               if (mode != FLOW_MODE_HASH && nkeys > 1)
+                       goto err2;
+       } else {
+               err = -EINVAL;
+               if (!handle)
+                       goto err2;
+               if (!tb[TCA_FLOW_KEYS])
+                       goto err2;
+
+               mode = FLOW_MODE_MAP;
+               if (tb[TCA_FLOW_MODE])
+                       mode = nla_get_u32(tb[TCA_FLOW_MODE]);
+               if (mode != FLOW_MODE_HASH && nkeys > 1)
+                       goto err2;
+
+               if (TC_H_MAJ(baseclass) == 0)
+                       baseclass = TC_H_MAKE(tp->q->handle, baseclass);
+               if (TC_H_MIN(baseclass) == 0)
+                       baseclass = TC_H_MAKE(baseclass, 1);
+
+               err = -ENOBUFS;
+               f = kzalloc(sizeof(*f), GFP_KERNEL);
+               if (f == NULL)
+                       goto err2;
+
+               f->handle = handle;
+               f->mask   = ~0U;
+       }
+
+       tcf_exts_change(tp, &f->exts, &e);
+       tcf_em_tree_change(tp, &f->ematches, &t);
+
+       tcf_tree_lock(tp);
+
+       if (tb[TCA_FLOW_KEYS]) {
+               f->keymask = keymask;
+               f->nkeys   = nkeys;
+       }
+
+       f->mode = mode;
+
+       if (tb[TCA_FLOW_MASK])
+               f->mask = nla_get_u32(tb[TCA_FLOW_MASK]);
+       if (tb[TCA_FLOW_XOR])
+               f->xor = nla_get_u32(tb[TCA_FLOW_XOR]);
+       if (tb[TCA_FLOW_RSHIFT])
+               f->rshift = nla_get_u32(tb[TCA_FLOW_RSHIFT]);
+       if (tb[TCA_FLOW_ADDEND])
+               f->addend = nla_get_u32(tb[TCA_FLOW_ADDEND]);
+
+       if (tb[TCA_FLOW_DIVISOR])
+               f->divisor = nla_get_u32(tb[TCA_FLOW_DIVISOR]);
+       if (baseclass)
+               f->baseclass = baseclass;
+
+       if (*arg == 0)
+               list_add_tail(&f->list, &head->filters);
+
+       tcf_tree_unlock(tp);
+
+       *arg = (unsigned long)f;
+       return 0;
+
+err2:
+       tcf_em_tree_destroy(tp, &t);
+err1:
+       tcf_exts_destroy(tp, &e);
+       return err;
+}
+
+static void flow_destroy_filter(struct tcf_proto *tp, struct flow_filter *f)
+{
+       tcf_exts_destroy(tp, &f->exts);
+       tcf_em_tree_destroy(tp, &f->ematches);
+       kfree(f);
+}
+
+static int flow_delete(struct tcf_proto *tp, unsigned long arg)
+{
+       struct flow_filter *f = (struct flow_filter *)arg;
+
+       tcf_tree_lock(tp);
+       list_del(&f->list);
+       tcf_tree_unlock(tp);
+       flow_destroy_filter(tp, f);
+       return 0;
+}
+
+static int flow_init(struct tcf_proto *tp)
+{
+       struct flow_head *head;
+
+       if (!flow_hashrnd_initted) {
+               get_random_bytes(&flow_hashrnd, 4);
+               flow_hashrnd_initted = 1;
+       }
+
+       head = kzalloc(sizeof(*head), GFP_KERNEL);
+       if (head == NULL)
+               return -ENOBUFS;
+       INIT_LIST_HEAD(&head->filters);
+       tp->root = head;
+       return 0;
+}
+
+static void flow_destroy(struct tcf_proto *tp)
+{
+       struct flow_head *head = tp->root;
+       struct flow_filter *f, *next;
+
+       list_for_each_entry_safe(f, next, &head->filters, list) {
+               list_del(&f->list);
+               flow_destroy_filter(tp, f);
+       }
+       kfree(head);
+}
+
+static unsigned long flow_get(struct tcf_proto *tp, u32 handle)
+{
+       struct flow_head *head = tp->root;
+       struct flow_filter *f;
+
+       list_for_each_entry(f, &head->filters, list)
+               if (f->handle == handle)
+                       return (unsigned long)f;
+       return 0;
+}
+
+static void flow_put(struct tcf_proto *tp, unsigned long f)
+{
+       return;
+}
+
+static int flow_dump(struct tcf_proto *tp, unsigned long fh,
+                    struct sk_buff *skb, struct tcmsg *t)
+{
+       struct flow_filter *f = (struct flow_filter *)fh;
+       struct nlattr *nest;
+
+       if (f == NULL)
+               return skb->len;
+
+       t->tcm_handle = f->handle;
+
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
+
+       NLA_PUT_U32(skb, TCA_FLOW_KEYS, f->keymask);
+       NLA_PUT_U32(skb, TCA_FLOW_MODE, f->mode);
+
+       if (f->mask != ~0 || f->xor != 0) {
+               NLA_PUT_U32(skb, TCA_FLOW_MASK, f->mask);
+               NLA_PUT_U32(skb, TCA_FLOW_XOR, f->xor);
+       }
+       if (f->rshift)
+               NLA_PUT_U32(skb, TCA_FLOW_RSHIFT, f->rshift);
+       if (f->addend)
+               NLA_PUT_U32(skb, TCA_FLOW_ADDEND, f->addend);
+
+       if (f->divisor)
+               NLA_PUT_U32(skb, TCA_FLOW_DIVISOR, f->divisor);
+       if (f->baseclass)
+               NLA_PUT_U32(skb, TCA_FLOW_BASECLASS, f->baseclass);
+
+       if (tcf_exts_dump(skb, &f->exts, &flow_ext_map) < 0)
+               goto nla_put_failure;
+
+       if (f->ematches.hdr.nmatches &&
+           tcf_em_tree_dump(skb, &f->ematches, TCA_FLOW_EMATCHES) < 0)
+               goto nla_put_failure;
+
+       nla_nest_end(skb, nest);
+
+       if (tcf_exts_dump_stats(skb, &f->exts, &flow_ext_map) < 0)
+               goto nla_put_failure;
+
+       return skb->len;
+
+nla_put_failure:
+       nlmsg_trim(skb, nest);
+       return -1;
+}
+
+static void flow_walk(struct tcf_proto *tp, struct tcf_walker *arg)
+{
+       struct flow_head *head = tp->root;
+       struct flow_filter *f;
+
+       list_for_each_entry(f, &head->filters, list) {
+               if (arg->count < arg->skip)
+                       goto skip;
+               if (arg->fn(tp, (unsigned long)f, arg) < 0) {
+                       arg->stop = 1;
+                       break;
+               }
+skip:
+               arg->count++;
+       }
+}
+
+static struct tcf_proto_ops cls_flow_ops __read_mostly = {
+       .kind           = "flow",
+       .classify       = flow_classify,
+       .init           = flow_init,
+       .destroy        = flow_destroy,
+       .change         = flow_change,
+       .delete         = flow_delete,
+       .get            = flow_get,
+       .put            = flow_put,
+       .dump           = flow_dump,
+       .walk           = flow_walk,
+       .owner          = THIS_MODULE,
+};
+
+static int __init cls_flow_init(void)
+{
+       return register_tcf_proto_ops(&cls_flow_ops);
+}
+
+static void __exit cls_flow_exit(void)
+{
+       unregister_tcf_proto_ops(&cls_flow_ops);
+}
+
+module_init(cls_flow_init);
+module_exit(cls_flow_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_DESCRIPTION("TC flow classifier");
index 436a6e7c438e2c8484d130ced225bf590e55e267..b0f90e593af0d510b6e61db352a8db9602830311 100644 (file)
@@ -47,7 +47,7 @@ struct fw_filter
        struct tcf_exts         exts;
 };
 
-static struct tcf_ext_map fw_ext_map = {
+static const struct tcf_ext_map fw_ext_map = {
        .action = TCA_FW_ACT,
        .police = TCA_FW_POLICE
 };
index f7e7d3955d289f5cd5585bc06bbc9285e56a9834..784dcb870b98181032e2b40d7a37ab3a60445eb1 100644 (file)
@@ -62,7 +62,7 @@ struct route4_filter
 
 #define ROUTE4_FAILURE ((struct route4_filter*)(-1L))
 
-static struct tcf_ext_map route_ext_map = {
+static const struct tcf_ext_map route_ext_map = {
        .police = TCA_ROUTE4_POLICE,
        .action = TCA_ROUTE4_ACT
 };
index ee60b2d1705de6b90a9c1f4dbe29436535a10f47..7a7bff5ded2487801e3c34941c1e12b8d77926fc 100644 (file)
@@ -55,7 +55,7 @@ struct tcindex_data {
        int fall_through;       /* 0: only classify if explicit match */
 };
 
-static struct tcf_ext_map tcindex_ext_map = {
+static const struct tcf_ext_map tcindex_ext_map = {
        .police = TCA_TCINDEX_POLICE,
        .action = TCA_TCINDEX_ACT
 };
index e8a7756891234dd2f74e23fbb3cc608ec77241da..b18fa95ef248e78f8a898248fa3466970b9f820d 100644 (file)
@@ -82,7 +82,7 @@ struct tc_u_common
        u32                     hgenerator;
 };
 
-static struct tcf_ext_map u32_ext_map = {
+static const struct tcf_ext_map u32_ext_map = {
        .action = TCA_U32_ACT,
        .police = TCA_U32_POLICE
 };
index 3f72d528273cc4f5a7ff9664d623a428ed718324..274b1ddb160c3956da169dd1bbc7da5e5f482637 100644 (file)
 #include <linux/list.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
-#include <linux/netfilter_ipv4.h>
-#include <linux/netfilter_ipv6.h>
-#include <linux/netfilter.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
 
 
-/* Thanks to Doron Oz for this hack */
-#if !defined(CONFIG_NET_CLS_ACT) && defined(CONFIG_NETFILTER)
-static int nf_registered;
-#endif
-
 struct ingress_qdisc_data {
        struct tcf_proto        *filter_list;
 };
@@ -84,11 +76,6 @@ static int ingress_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 
        result = tc_classify(skb, p->filter_list, &res);
 
-       /*
-        * Unlike normal "enqueue" functions, ingress_enqueue returns a
-        * firewall FW_* code.
-        */
-#ifdef CONFIG_NET_CLS_ACT
        sch->bstats.packets++;
        sch->bstats.bytes += skb->len;
        switch (result) {
@@ -107,71 +94,10 @@ static int ingress_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                result = TC_ACT_OK;
                break;
        }
-#else
-       result = NF_ACCEPT;
-       sch->bstats.packets++;
-       sch->bstats.bytes += skb->len;
-#endif
 
        return result;
 }
 
-#if !defined(CONFIG_NET_CLS_ACT) && defined(CONFIG_NETFILTER)
-static unsigned int ing_hook(unsigned int hook, struct sk_buff *skb,
-                            const struct net_device *indev,
-                            const struct net_device *outdev,
-                            int (*okfn)(struct sk_buff *))
-{
-
-       struct Qdisc *q;
-       struct net_device *dev = skb->dev;
-       int fwres = NF_ACCEPT;
-
-       if (dev->qdisc_ingress) {
-               spin_lock(&dev->ingress_lock);
-               if ((q = dev->qdisc_ingress) != NULL)
-                       fwres = q->enqueue(skb, q);
-               spin_unlock(&dev->ingress_lock);
-       }
-
-       return fwres;
-}
-
-/* after ipt_filter */
-static struct nf_hook_ops ing_ops[] __read_mostly = {
-       {
-               .hook           = ing_hook,
-               .owner          = THIS_MODULE,
-               .pf             = PF_INET,
-               .hooknum        = NF_INET_PRE_ROUTING,
-               .priority       = NF_IP_PRI_FILTER + 1,
-       },
-       {
-               .hook           = ing_hook,
-               .owner          = THIS_MODULE,
-               .pf             = PF_INET6,
-               .hooknum        = NF_INET_PRE_ROUTING,
-               .priority       = NF_IP6_PRI_FILTER + 1,
-       },
-};
-#endif
-
-static int ingress_init(struct Qdisc *sch, struct nlattr *opt)
-{
-#if !defined(CONFIG_NET_CLS_ACT) && defined(CONFIG_NETFILTER)
-       printk("Ingress scheduler: Classifier actions prefered over netfilter\n");
-
-       if (!nf_registered) {
-               if (nf_register_hooks(ing_ops, ARRAY_SIZE(ing_ops)) < 0) {
-                       printk("ingress qdisc registration error \n");
-                       return -EINVAL;
-               }
-               nf_registered++;
-       }
-#endif
-       return 0;
-}
-
 /* ------------------------------------------------------------- */
 
 static void ingress_destroy(struct Qdisc *sch)
@@ -213,7 +139,6 @@ static struct Qdisc_ops ingress_qdisc_ops __read_mostly = {
        .id             =       "ingress",
        .priv_size      =       sizeof(struct ingress_qdisc_data),
        .enqueue        =       ingress_enqueue,
-       .init           =       ingress_init,
        .destroy        =       ingress_destroy,
        .dump           =       ingress_dump,
        .owner          =       THIS_MODULE,
@@ -227,10 +152,6 @@ static int __init ingress_module_init(void)
 static void __exit ingress_module_exit(void)
 {
        unregister_qdisc(&ingress_qdisc_ops);
-#if !defined(CONFIG_NET_CLS_ACT) && defined(CONFIG_NETFILTER)
-       if (nf_registered)
-               nf_unregister_hooks(ing_ops, ARRAY_SIZE(ing_ops));
-#endif
 }
 
 module_init(ingress_module_init)
index 91af539ab6e69f972eb3edcea0aab2fdee6c516e..a20e2ef7704beb4142dc3ee75d67604bffa10a10 100644 (file)
@@ -95,6 +95,7 @@ struct sfq_sched_data
        int             limit;
 
 /* Variables */
+       struct tcf_proto *filter_list;
        struct timer_list perturb_timer;
        u32             perturbation;
        sfq_index       tail;           /* Index of current slot in round */
@@ -155,6 +156,39 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
        return sfq_fold_hash(q, h, h2);
 }
 
+static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
+                                int *qerr)
+{
+       struct sfq_sched_data *q = qdisc_priv(sch);
+       struct tcf_result res;
+       int result;
+
+       if (TC_H_MAJ(skb->priority) == sch->handle &&
+           TC_H_MIN(skb->priority) > 0 &&
+           TC_H_MIN(skb->priority) <= SFQ_HASH_DIVISOR)
+               return TC_H_MIN(skb->priority);
+
+       if (!q->filter_list)
+               return sfq_hash(q, skb) + 1;
+
+       *qerr = NET_XMIT_BYPASS;
+       result = tc_classify(skb, q->filter_list, &res);
+       if (result >= 0) {
+#ifdef CONFIG_NET_CLS_ACT
+               switch (result) {
+               case TC_ACT_STOLEN:
+               case TC_ACT_QUEUED:
+                       *qerr = NET_XMIT_SUCCESS;
+               case TC_ACT_SHOT:
+                       return 0;
+               }
+#endif
+               if (TC_H_MIN(res.classid) <= SFQ_HASH_DIVISOR)
+                       return TC_H_MIN(res.classid);
+       }
+       return 0;
+}
+
 static inline void sfq_link(struct sfq_sched_data *q, sfq_index x)
 {
        sfq_index p, n;
@@ -245,8 +279,18 @@ static int
 sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
        struct sfq_sched_data *q = qdisc_priv(sch);
-       unsigned hash = sfq_hash(q, skb);
+       unsigned int hash;
        sfq_index x;
+       int ret;
+
+       hash = sfq_classify(skb, sch, &ret);
+       if (hash == 0) {
+               if (ret == NET_XMIT_BYPASS)
+                       sch->qstats.drops++;
+               kfree_skb(skb);
+               return ret;
+       }
+       hash--;
 
        x = q->ht[hash];
        if (x == SFQ_DEPTH) {
@@ -289,8 +333,18 @@ static int
 sfq_requeue(struct sk_buff *skb, struct Qdisc *sch)
 {
        struct sfq_sched_data *q = qdisc_priv(sch);
-       unsigned hash = sfq_hash(q, skb);
+       unsigned int hash;
        sfq_index x;
+       int ret;
+
+       hash = sfq_classify(skb, sch, &ret);
+       if (hash == 0) {
+               if (ret == NET_XMIT_BYPASS)
+                       sch->qstats.drops++;
+               kfree_skb(skb);
+               return ret;
+       }
+       hash--;
 
        x = q->ht[hash];
        if (x == SFQ_DEPTH) {
@@ -465,6 +519,8 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt)
 static void sfq_destroy(struct Qdisc *sch)
 {
        struct sfq_sched_data *q = qdisc_priv(sch);
+
+       tcf_destroy_chain(q->filter_list);
        del_timer(&q->perturb_timer);
 }
 
@@ -490,9 +546,79 @@ nla_put_failure:
        return -1;
 }
 
+static int sfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+                           struct nlattr **tca, unsigned long *arg)
+{
+       return -EOPNOTSUPP;
+}
+
+static unsigned long sfq_get(struct Qdisc *sch, u32 classid)
+{
+       return 0;
+}
+
+static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl)
+{
+       struct sfq_sched_data *q = qdisc_priv(sch);
+
+       if (cl)
+               return NULL;
+       return &q->filter_list;
+}
+
+static int sfq_dump_class(struct Qdisc *sch, unsigned long cl,
+                         struct sk_buff *skb, struct tcmsg *tcm)
+{
+       tcm->tcm_handle |= TC_H_MIN(cl);
+       return 0;
+}
+
+static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
+                               struct gnet_dump *d)
+{
+       struct sfq_sched_data *q = qdisc_priv(sch);
+       sfq_index idx = q->ht[cl-1];
+       struct gnet_stats_queue qs = { .qlen = q->qs[idx].qlen };
+       struct tc_sfq_xstats xstats = { .allot = q->allot[idx] };
+
+       if (gnet_stats_copy_queue(d, &qs) < 0)
+               return -1;
+       return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
+}
+
+static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
+{
+       struct sfq_sched_data *q = qdisc_priv(sch);
+       unsigned int i;
+
+       if (arg->stop)
+               return;
+
+       for (i = 0; i < SFQ_HASH_DIVISOR; i++) {
+               if (q->ht[i] == SFQ_DEPTH ||
+                   arg->count < arg->skip) {
+                       arg->count++;
+                       continue;
+               }
+               if (arg->fn(sch, i + 1, arg) < 0) {
+                       arg->stop = 1;
+                       break;
+               }
+               arg->count++;
+       }
+}
+
+static const struct Qdisc_class_ops sfq_class_ops = {
+       .get            =       sfq_get,
+       .change         =       sfq_change_class,
+       .tcf_chain      =       sfq_find_tcf,
+       .dump           =       sfq_dump_class,
+       .dump_stats     =       sfq_dump_class_stats,
+       .walk           =       sfq_walk,
+};
+
 static struct Qdisc_ops sfq_qdisc_ops __read_mostly = {
-       .next           =       NULL,
-       .cl_ops         =       NULL,
+       .cl_ops         =       &sfq_class_ops,
        .id             =       "sfq",
        .priv_size      =       sizeof(struct sfq_sched_data),
        .enqueue        =       sfq_enqueue,
index 1411c7b1fbdc4de0f7103cfb559a78369a4195cc..0444fd0f0d2298228934a6f06ca54913f3280b8b 100644 (file)
@@ -71,7 +71,7 @@ struct teql_sched_data
 
 #define NEXT_SLAVE(q) (((struct teql_sched_data*)qdisc_priv(q))->next)
 
-#define FMASK (IFF_BROADCAST|IFF_POINTOPOINT|IFF_BROADCAST)
+#define FMASK (IFF_BROADCAST|IFF_POINTOPOINT)
 
 /* "teql*" qdisc routines */
 
index dd98763c8b006de560201e454b5003d1197df828..77383e9b398833e698ad3ab72597160250451443 100644 (file)
@@ -2056,7 +2056,7 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
                break;
 
        case SCTP_PARAM_HMAC_ALGO:
-               if (!sctp_auth_enable)
+               if (sctp_auth_enable)
                        break;
                /* Fall Through */
 fallthrough:
index 07fad7ccf83204c137b90fb0bfc906dd25a0dfbf..339ca4a8e89ed262295fa1851770e34a03a86738 100644 (file)
@@ -1652,7 +1652,7 @@ static int __init x25_init(void)
 
        register_netdevice_notifier(&x25_dev_notifier);
 
-       printk(KERN_INFO "X.25 for Linux. Version 0.2 for Linux 2.1.15\n");
+       printk(KERN_INFO "X.25 for Linux Version 0.2\n");
 
 #ifdef CONFIG_SYSCTL
        x25_register_sysctl();
index b5c5347aed666096c33d0fadbbab0065753ddd08..6cc15250de69949606638cd6fab4afb6a0cadee5 100644 (file)
  * that instantiated crypto transforms have correct parameters for IPsec
  * purposes.
  */
+static struct xfrm_algo_desc aead_list[] = {
+{
+       .name = "rfc4106(gcm(aes))",
+
+       .uinfo = {
+               .aead = {
+                       .icv_truncbits = 64,
+               }
+       },
+
+       .desc = {
+               .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8,
+               .sadb_alg_ivlen = 8,
+               .sadb_alg_minbits = 128,
+               .sadb_alg_maxbits = 256
+       }
+},
+{
+       .name = "rfc4106(gcm(aes))",
+
+       .uinfo = {
+               .aead = {
+                       .icv_truncbits = 96,
+               }
+       },
+
+       .desc = {
+               .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12,
+               .sadb_alg_ivlen = 8,
+               .sadb_alg_minbits = 128,
+               .sadb_alg_maxbits = 256
+       }
+},
+{
+       .name = "rfc4106(gcm(aes))",
+
+       .uinfo = {
+               .aead = {
+                       .icv_truncbits = 128,
+               }
+       },
+
+       .desc = {
+               .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16,
+               .sadb_alg_ivlen = 8,
+               .sadb_alg_minbits = 128,
+               .sadb_alg_maxbits = 256
+       }
+},
+{
+       .name = "rfc4309(ccm(aes))",
+
+       .uinfo = {
+               .aead = {
+                       .icv_truncbits = 64,
+               }
+       },
+
+       .desc = {
+               .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8,
+               .sadb_alg_ivlen = 8,
+               .sadb_alg_minbits = 128,
+               .sadb_alg_maxbits = 256
+       }
+},
+{
+       .name = "rfc4309(ccm(aes))",
+
+       .uinfo = {
+               .aead = {
+                       .icv_truncbits = 96,
+               }
+       },
+
+       .desc = {
+               .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12,
+               .sadb_alg_ivlen = 8,
+               .sadb_alg_minbits = 128,
+               .sadb_alg_maxbits = 256
+       }
+},
+{
+       .name = "rfc4309(ccm(aes))",
+
+       .uinfo = {
+               .aead = {
+                       .icv_truncbits = 128,
+               }
+       },
+
+       .desc = {
+               .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16,
+               .sadb_alg_ivlen = 8,
+               .sadb_alg_minbits = 128,
+               .sadb_alg_maxbits = 256
+       }
+},
+};
+
 static struct xfrm_algo_desc aalg_list[] = {
 {
        .name = "hmac(digest_null)",
@@ -332,6 +431,11 @@ static struct xfrm_algo_desc calg_list[] = {
 },
 };
 
+static inline int aead_entries(void)
+{
+       return ARRAY_SIZE(aead_list);
+}
+
 static inline int aalg_entries(void)
 {
        return ARRAY_SIZE(aalg_list);
@@ -354,25 +458,32 @@ struct xfrm_algo_list {
        u32 mask;
 };
 
+static const struct xfrm_algo_list xfrm_aead_list = {
+       .algs = aead_list,
+       .entries = ARRAY_SIZE(aead_list),
+       .type = CRYPTO_ALG_TYPE_AEAD,
+       .mask = CRYPTO_ALG_TYPE_MASK,
+};
+
 static const struct xfrm_algo_list xfrm_aalg_list = {
        .algs = aalg_list,
        .entries = ARRAY_SIZE(aalg_list),
        .type = CRYPTO_ALG_TYPE_HASH,
-       .mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC,
+       .mask = CRYPTO_ALG_TYPE_HASH_MASK,
 };
 
 static const struct xfrm_algo_list xfrm_ealg_list = {
        .algs = ealg_list,
        .entries = ARRAY_SIZE(ealg_list),
        .type = CRYPTO_ALG_TYPE_BLKCIPHER,
-       .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
+       .mask = CRYPTO_ALG_TYPE_BLKCIPHER_MASK,
 };
 
 static const struct xfrm_algo_list xfrm_calg_list = {
        .algs = calg_list,
        .entries = ARRAY_SIZE(calg_list),
        .type = CRYPTO_ALG_TYPE_COMPRESS,
-       .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
+       .mask = CRYPTO_ALG_TYPE_MASK,
 };
 
 static struct xfrm_algo_desc *xfrm_find_algo(
@@ -461,6 +572,33 @@ struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
 }
 EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
 
+struct xfrm_aead_name {
+       const char *name;
+       int icvbits;
+};
+
+static int xfrm_aead_name_match(const struct xfrm_algo_desc *entry,
+                               const void *data)
+{
+       const struct xfrm_aead_name *aead = data;
+       const char *name = aead->name;
+
+       return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
+              !strcmp(name, entry->name);
+}
+
+struct xfrm_algo_desc *xfrm_aead_get_byname(char *name, int icv_len, int probe)
+{
+       struct xfrm_aead_name data = {
+               .name = name,
+               .icvbits = icv_len,
+       };
+
+       return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data,
+                             probe);
+}
+EXPORT_SYMBOL_GPL(xfrm_aead_get_byname);
+
 struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
 {
        if (idx >= aalg_entries())
index 039e7019c48a4e56b40354177e553752568f6793..4d6ebc633a944d14a328606ee675ae5cc528e191 100644 (file)
@@ -81,7 +81,6 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
        *seq = *(__be32*)(skb_transport_header(skb) + offset_seq);
        return 0;
 }
-EXPORT_SYMBOL(xfrm_parse_spi);
 
 int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
 {
@@ -160,12 +159,12 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
                }
 
                if ((x->encap ? x->encap->encap_type : 0) != encap_type) {
-                       XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID);
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH);
                        goto drop_unlock;
                }
 
                if (x->props.replay_window && xfrm_replay_check(x, skb, seq)) {
-                       XFRM_INC_STATS(LINUX_MIB_XFRMINSEQOUTOFWINDOW);
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINSTATESEQERROR);
                        goto drop_unlock;
                }
 
index f4a1047a55737929efd37f989c53fc18adea6b53..fc690368325f6b86c0ee7b1e74a16ac442b3965d 100644 (file)
@@ -64,6 +64,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
                if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
                        XFRM_SKB_CB(skb)->seq = ++x->replay.oseq;
                        if (unlikely(x->replay.oseq == 0)) {
+                               XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATESEQERROR);
                                x->replay.oseq--;
                                xfrm_audit_state_replay_overflow(x, skb);
                                err = -EOVERFLOW;
index 31d035415ecd2e155b77cad6937b039b09341455..2b0db13f0cda681c9482e86a97a51cf6f9f660d4 100644 (file)
@@ -22,7 +22,7 @@ static struct snmp_mib xfrm_mib_list[] = {
        SNMP_MIB_ITEM("XfrmInNoStates", LINUX_MIB_XFRMINNOSTATES),
        SNMP_MIB_ITEM("XfrmInStateProtoError", LINUX_MIB_XFRMINSTATEPROTOERROR),
        SNMP_MIB_ITEM("XfrmInStateModeError", LINUX_MIB_XFRMINSTATEMODEERROR),
-       SNMP_MIB_ITEM("XfrmInSeqOutOfWindow", LINUX_MIB_XFRMINSEQOUTOFWINDOW),
+       SNMP_MIB_ITEM("XfrmInStateSeqError", LINUX_MIB_XFRMINSTATESEQERROR),
        SNMP_MIB_ITEM("XfrmInStateExpired", LINUX_MIB_XFRMINSTATEEXPIRED),
        SNMP_MIB_ITEM("XfrmInStateMismatch", LINUX_MIB_XFRMINSTATEMISMATCH),
        SNMP_MIB_ITEM("XfrmInStateInvalid", LINUX_MIB_XFRMINSTATEINVALID),
@@ -36,6 +36,7 @@ static struct snmp_mib xfrm_mib_list[] = {
        SNMP_MIB_ITEM("XfrmOutNoStates", LINUX_MIB_XFRMOUTNOSTATES),
        SNMP_MIB_ITEM("XfrmOutStateProtoError", LINUX_MIB_XFRMOUTSTATEPROTOERROR),
        SNMP_MIB_ITEM("XfrmOutStateModeError", LINUX_MIB_XFRMOUTSTATEMODEERROR),
+       SNMP_MIB_ITEM("XfrmOutStateSeqError", LINUX_MIB_XFRMOUTSTATESEQERROR),
        SNMP_MIB_ITEM("XfrmOutStateExpired", LINUX_MIB_XFRMOUTSTATEEXPIRED),
        SNMP_MIB_ITEM("XfrmOutPolBlock", LINUX_MIB_XFRMOUTPOLBLOCK),
        SNMP_MIB_ITEM("XfrmOutPolDead", LINUX_MIB_XFRMOUTPOLDEAD),
index 3003503d0c94937d570795fcbabf8ce155155130..3ff76e84d548258acfe13455ff91c83d5000749d 100644 (file)
@@ -216,10 +216,10 @@ static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo)
        write_unlock_bh(&xfrm_state_afinfo_lock);
 }
 
-int xfrm_register_type(struct xfrm_type *type, unsigned short family)
+int xfrm_register_type(const struct xfrm_type *type, unsigned short family)
 {
        struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
-       struct xfrm_type **typemap;
+       const struct xfrm_type **typemap;
        int err = 0;
 
        if (unlikely(afinfo == NULL))
@@ -235,10 +235,10 @@ int xfrm_register_type(struct xfrm_type *type, unsigned short family)
 }
 EXPORT_SYMBOL(xfrm_register_type);
 
-int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
+int xfrm_unregister_type(const struct xfrm_type *type, unsigned short family)
 {
        struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
-       struct xfrm_type **typemap;
+       const struct xfrm_type **typemap;
        int err = 0;
 
        if (unlikely(afinfo == NULL))
@@ -254,11 +254,11 @@ int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
 }
 EXPORT_SYMBOL(xfrm_unregister_type);
 
-static struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
+static const struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
 {
        struct xfrm_state_afinfo *afinfo;
-       struct xfrm_type **typemap;
-       struct xfrm_type *type;
+       const struct xfrm_type **typemap;
+       const struct xfrm_type *type;
        int modload_attempted = 0;
 
 retry:
@@ -281,7 +281,7 @@ retry:
        return type;
 }
 
-static void xfrm_put_type(struct xfrm_type *type)
+static void xfrm_put_type(const struct xfrm_type *type)
 {
        module_put(type->owner);
 }
@@ -1645,7 +1645,6 @@ err:
        xfrm_audit_state_replay(x, skb, net_seq);
        return -EINVAL;
 }
-EXPORT_SYMBOL(xfrm_replay_check);
 
 void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
 {
@@ -1667,7 +1666,6 @@ void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
        if (xfrm_aevent_is_on())
                xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
 }
-EXPORT_SYMBOL(xfrm_replay_advance);
 
 static LIST_HEAD(xfrm_km_list);
 static DEFINE_RWLOCK(xfrm_km_lock);
index e0ccdf26781360fc8c2860ddbb3b33ec0dafc7d0..78338079b7f579d07ad4267ae782a1bfea2613e2 100644 (file)
 #include <linux/in6.h>
 #endif
 
+static inline int aead_len(struct xfrm_algo_aead *alg)
+{
+       return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
+}
+
 static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type)
 {
        struct nlattr *rt = attrs[type];
@@ -68,6 +73,22 @@ static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type)
        return 0;
 }
 
+static int verify_aead(struct nlattr **attrs)
+{
+       struct nlattr *rt = attrs[XFRMA_ALG_AEAD];
+       struct xfrm_algo_aead *algp;
+
+       if (!rt)
+               return 0;
+
+       algp = nla_data(rt);
+       if (nla_len(rt) < aead_len(algp))
+               return -EINVAL;
+
+       algp->alg_name[CRYPTO_MAX_ALG_NAME - 1] = '\0';
+       return 0;
+}
+
 static void verify_one_addr(struct nlattr **attrs, enum xfrm_attr_type_t type,
                           xfrm_address_t **addrp)
 {
@@ -119,20 +140,28 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
        switch (p->id.proto) {
        case IPPROTO_AH:
                if (!attrs[XFRMA_ALG_AUTH]      ||
+                   attrs[XFRMA_ALG_AEAD]       ||
                    attrs[XFRMA_ALG_CRYPT]      ||
                    attrs[XFRMA_ALG_COMP])
                        goto out;
                break;
 
        case IPPROTO_ESP:
-               if ((!attrs[XFRMA_ALG_AUTH] &&
-                    !attrs[XFRMA_ALG_CRYPT])   ||
-                   attrs[XFRMA_ALG_COMP])
+               if (attrs[XFRMA_ALG_COMP])
+                       goto out;
+               if (!attrs[XFRMA_ALG_AUTH] &&
+                   !attrs[XFRMA_ALG_CRYPT] &&
+                   !attrs[XFRMA_ALG_AEAD])
+                       goto out;
+               if ((attrs[XFRMA_ALG_AUTH] ||
+                    attrs[XFRMA_ALG_CRYPT]) &&
+                   attrs[XFRMA_ALG_AEAD])
                        goto out;
                break;
 
        case IPPROTO_COMP:
                if (!attrs[XFRMA_ALG_COMP]      ||
+                   attrs[XFRMA_ALG_AEAD]       ||
                    attrs[XFRMA_ALG_AUTH]       ||
                    attrs[XFRMA_ALG_CRYPT])
                        goto out;
@@ -143,6 +172,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
        case IPPROTO_ROUTING:
                if (attrs[XFRMA_ALG_COMP]       ||
                    attrs[XFRMA_ALG_AUTH]       ||
+                   attrs[XFRMA_ALG_AEAD]       ||
                    attrs[XFRMA_ALG_CRYPT]      ||
                    attrs[XFRMA_ENCAP]          ||
                    attrs[XFRMA_SEC_CTX]        ||
@@ -155,6 +185,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
                goto out;
        }
 
+       if ((err = verify_aead(attrs)))
+               goto out;
        if ((err = verify_one_alg(attrs, XFRMA_ALG_AUTH)))
                goto out;
        if ((err = verify_one_alg(attrs, XFRMA_ALG_CRYPT)))
@@ -208,6 +240,31 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
        return 0;
 }
 
+static int attach_aead(struct xfrm_algo_aead **algpp, u8 *props,
+                      struct nlattr *rta)
+{
+       struct xfrm_algo_aead *p, *ualg;
+       struct xfrm_algo_desc *algo;
+
+       if (!rta)
+               return 0;
+
+       ualg = nla_data(rta);
+
+       algo = xfrm_aead_get_byname(ualg->alg_name, ualg->alg_icv_len, 1);
+       if (!algo)
+               return -ENOSYS;
+       *props = algo->desc.sadb_alg_id;
+
+       p = kmemdup(ualg, aead_len(ualg), GFP_KERNEL);
+       if (!p)
+               return -ENOMEM;
+
+       strcpy(p->alg_name, algo->name);
+       *algpp = p;
+       return 0;
+}
+
 static inline int xfrm_user_sec_ctx_size(struct xfrm_sec_ctx *xfrm_ctx)
 {
        int len = 0;
@@ -286,6 +343,9 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
 
        copy_from_user_state(x, p);
 
+       if ((err = attach_aead(&x->aead, &x->props.ealgo,
+                              attrs[XFRMA_ALG_AEAD])))
+               goto error;
        if ((err = attach_one_algo(&x->aalg, &x->props.aalgo,
                                   xfrm_aalg_get_byname,
                                   attrs[XFRMA_ALG_AUTH])))
@@ -510,6 +570,8 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
        if (x->lastused)
                NLA_PUT_U64(skb, XFRMA_LASTUSED, x->lastused);
 
+       if (x->aead)
+               NLA_PUT(skb, XFRMA_ALG_AEAD, aead_len(x->aead), x->aead);
        if (x->aalg)
                NLA_PUT(skb, XFRMA_ALG_AUTH, xfrm_alg_len(x->aalg), x->aalg);
        if (x->ealg)
@@ -1808,6 +1870,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
 #undef XMSGSIZE
 
 static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
+       [XFRMA_ALG_AEAD]        = { .len = sizeof(struct xfrm_algo_aead) },
        [XFRMA_ALG_AUTH]        = { .len = sizeof(struct xfrm_algo) },
        [XFRMA_ALG_CRYPT]       = { .len = sizeof(struct xfrm_algo) },
        [XFRMA_ALG_COMP]        = { .len = sizeof(struct xfrm_algo) },
@@ -1972,6 +2035,8 @@ static int xfrm_notify_sa_flush(struct km_event *c)
 static inline size_t xfrm_sa_len(struct xfrm_state *x)
 {
        size_t l = 0;
+       if (x->aead)
+               l += nla_total_size(aead_len(x->aead));
        if (x->aalg)
                l += nla_total_size(xfrm_alg_len(x->aalg));
        if (x->ealg)
index f96dec1f9258f31c88525543c59d586354619649..880d455aa659014c336965d6152575b191072cad 100644 (file)
@@ -2692,7 +2692,6 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
 
 netlbl_sid_to_secattr_failure:
        POLICY_RDUNLOCK;
-       netlbl_secattr_destroy(secattr);
        return rc;
 }
 #endif /* CONFIG_NETLABEL */