linux-cvs-patches
[Top] [All Lists]

CVS Update@linux-mips.org: linux

To: linux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: linux
From: ralf@linux-mips.org
Date: Thu, 20 Jan 2005 02:19:33 +0000
Reply-to: linux-mips@linux-mips.org
Sender: linux-cvs-patches-bounce@linux-mips.org
CVSROOT:        /home/cvs
Module name:    linux
Changes by:     ralf@ftp.linux-mips.org 05/01/20 02:19:27

Modified files:
        .              : Tag: linux_2_4 Makefile 
        Documentation  : Tag: linux_2_4 Changes Configure.help 
        arch/i386      : Tag: linux_2_4 defconfig 
        arch/mips      : Tag: linux_2_4 defconfig-bosporus 
                         defconfig-mtx-1 
        arch/mips64    : Tag: linux_2_4 defconfig defconfig-ip27 
        arch/ppc       : Tag: linux_2_4 defconfig 
        arch/ppc/configs: Tag: linux_2_4 apus_defconfig briq_defconfig 
                          common_defconfig ibmchrp_defconfig 
                          pal4_defconfig pmac_defconfig pplus_defconfig 
                          prpmc750_defconfig 
        arch/s390      : Tag: linux_2_4 defconfig 
        arch/sparc64   : Tag: linux_2_4 defconfig 
        drivers/char   : Tag: linux_2_4 tty_io.c 
        drivers/net    : Tag: linux_2_4 tg3.c 
        include/linux  : Tag: linux_2_4 if_arp.h if_ether.h netfilter.h 
                         sctp.h 
        include/linux/netfilter_ipv4: Tag: linux_2_4 ip_conntrack_core.h 
                                      ip_nat.h 
        include/net    : Tag: linux_2_4 inet_ecn.h ip.h ip_vs.h 
        include/net/sctp: Tag: linux_2_4 command.h compat.h constants.h 
                          sctp.h sm.h structs.h tsnmap.h ulpevent.h 
                          ulpqueue.h 
        init           : Tag: linux_2_4 do_mounts.c 
        net            : Tag: linux_2_4 netsyms.c 
        net/core       : Tag: linux_2_4 neighbour.c netfilter.c 
        net/ipv4       : Tag: linux_2_4 icmp.c ip_output.c raw.c udp.c 
        net/ipv4/ipvs  : Tag: linux_2_4 ip_vs_core.c ip_vs_ctl.c 
                         ip_vs_sync.c 
        net/ipv4/netfilter: Tag: linux_2_4 Config.in ip_conntrack_core.c 
                            ip_conntrack_standalone.c 
                            ip_fw_compat_masq.c ip_nat_core.c 
                            ip_nat_rule.c ip_nat_standalone.c 
                            ip_tables.c ipt_MASQUERADE.c ipt_REJECT.c 
        net/ipv6       : Tag: linux_2_4 sit.c 
        net/ipv6/netfilter: Tag: linux_2_4 ip6_tables.c ip6t_LOG.c 
                            ip6t_dst.c ip6t_esp.c ip6t_eui64.c 
                            ip6t_frag.c ip6t_hbh.c ip6t_ipv6header.c 
                            ip6t_multiport.c ip6t_rt.c 
        net/sched      : Tag: linux_2_4 sch_dsmark.c 
        net/sctp       : Tag: linux_2_4 associola.c bind_addr.c chunk.c 
                         command.c debug.c endpointola.c input.c 
                         inqueue.c ipv6.c objcnt.c output.c outqueue.c 
                         proc.c protocol.c sm_make_chunk.c 
                         sm_sideeffect.c sm_statefuns.c sm_statetable.c 
                         socket.c ssnmap.c transport.c tsnmap.c 
                         ulpevent.c ulpqueue.c 

Log message:
        Merge with Linux 2.4.29.

diff -urN linux/Makefile linux/Makefile
--- linux/Makefile      2005/01/13 10:59:02     1.119.2.32
+++ linux/Makefile      2005/01/20 02:19:21     1.119.2.33
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 29
-EXTRAVERSION = -rc2
+EXTRAVERSION =
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux/Documentation/Changes linux/Documentation/Changes
--- linux/Documentation/Changes 2003/12/15 18:19:48     1.49.2.5
+++ linux/Documentation/Changes 2005/01/20 02:19:21     1.49.2.6
@@ -52,7 +52,7 @@
 o  Gnu make               3.77                    # make --version
 o  binutils               2.9.1.0.25              # ld -v
 o  util-linux             2.10o                   # fdformat --version
-o  modutils               2.4.2                   # insmod -V
+o  modutils               2.4.10                   # insmod -V
 o  e2fsprogs              1.25                    # tune2fs
 o  jfsutils               1.0.12                  # fsck.jfs -V
 o  reiserfsprogs          3.6.3                   # reiserfsck -V 2>&1|grep 
reiserfsprogs
@@ -159,8 +159,8 @@
 Upgrade to recent modutils to fix various outstanding bugs which are
 seen more frequently under 2.4.x, and to enable auto-loading of USB
 modules.  In addition, the layout of modules under
-/lib/modules/`uname -r`/ has been made more sane.  This change also
-requires that you upgrade to a recent modutils.
+/lib/modules/`uname -r`/ has been made more sane, and EXPORT_SYMBOL_GPL 
+also requires that you upgrade to a recent modutils.
 
 Mkinitrd
 --------
diff -urN linux/Documentation/Configure.help linux/Documentation/Configure.help
--- linux/Documentation/Attic/Configure.help    2004/12/27 04:13:37     
1.109.2.54
+++ linux/Documentation/Attic/Configure.help    2005/01/20 02:19:21     
1.109.2.55
@@ -3042,19 +3042,6 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
-Local NAT support
-CONFIG_IP_NF_NAT_LOCAL
-  This option enables support for NAT of locally originated connections. 
-  Enable this if you need to use destination NAT on connections
-  originating from local processes on the nat box itself.
-
-  Please note that you will need a recent version (>= 1.2.6a)
-  of the iptables userspace program in order to use this feature.
-  See <http://www.iptables.org/> for download instructions.
-
-  If unsure, say 'N'.
-
-
 Full NAT (Network Address Translation)
 CONFIG_IP_NF_NAT
   The Full NAT option allows masquerading, port forwarding and other
diff -urN linux/arch/i386/defconfig linux/arch/i386/defconfig
--- linux/arch/i386/defconfig   2004/11/19 00:28:31     1.76.2.8
+++ linux/arch/i386/defconfig   2005/01/20 02:19:22     1.76.2.9
@@ -200,11 +200,6 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 
@@ -240,10 +235,12 @@
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
 # CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -346,11 +343,15 @@
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
 # CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_AHCI is not set
 # CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
 # CONFIG_SCSI_SATA_PROMISE is not set
 # CONFIG_SCSI_SATA_SX4 is not set
 # CONFIG_SCSI_SATA_SIL is not set
 # CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
 # CONFIG_SCSI_SATA_VIA is not set
 # CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
diff -urN linux/arch/mips/defconfig-bosporus linux/arch/mips/defconfig-bosporus
--- linux/arch/mips/Attic/defconfig-bosporus    2005/01/09 19:33:59     1.1.2.40
+++ linux/arch/mips/Attic/defconfig-bosporus    2005/01/20 02:19:22     1.1.2.41
@@ -341,7 +341,6 @@
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 # CONFIG_IP_NF_TARGET_TOS is not set
diff -urN linux/arch/mips/defconfig-mtx-1 linux/arch/mips/defconfig-mtx-1
--- linux/arch/mips/Attic/defconfig-mtx-1       2005/01/09 19:33:59     1.1.2.31
+++ linux/arch/mips/Attic/defconfig-mtx-1       2005/01/20 02:19:22     1.1.2.32
@@ -335,7 +335,6 @@
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -urN linux/arch/mips64/defconfig linux/arch/mips64/defconfig
--- linux/arch/mips64/Attic/defconfig   2004/11/29 17:47:15     1.73.2.76
+++ linux/arch/mips64/Attic/defconfig   2005/01/20 02:19:22     1.73.2.77
@@ -265,7 +265,6 @@
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_NAT_LOCAL=y
 # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -urN linux/arch/mips64/defconfig-ip27 linux/arch/mips64/defconfig-ip27
--- linux/arch/mips64/Attic/defconfig-ip27      2004/11/29 17:47:15     
1.67.2.77
+++ linux/arch/mips64/Attic/defconfig-ip27      2005/01/20 02:19:22     
1.67.2.78
@@ -265,7 +265,6 @@
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_NAT_LOCAL=y
 # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -urN linux/arch/ppc/defconfig linux/arch/ppc/defconfig
--- linux/arch/ppc/Attic/defconfig      2004/11/19 00:28:33     1.37.2.8
+++ linux/arch/ppc/Attic/defconfig      2005/01/20 02:19:22     1.37.2.9
@@ -180,7 +180,6 @@
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -urN linux/arch/ppc/configs/apus_defconfig 
linux/arch/ppc/configs/apus_defconfig
--- linux/arch/ppc/configs/apus_defconfig       2004/02/20 01:22:13     1.9.2.8
+++ linux/arch/ppc/configs/apus_defconfig       2005/01/20 02:19:23     1.9.2.9
@@ -199,7 +199,6 @@
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -urN linux/arch/ppc/configs/briq_defconfig 
linux/arch/ppc/configs/briq_defconfig
--- linux/arch/ppc/configs/Attic/briq_defconfig 2004/02/20 01:22:13     1.1.2.5
+++ linux/arch/ppc/configs/Attic/briq_defconfig 2005/01/20 02:19:23     1.1.2.6
@@ -175,7 +175,6 @@
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -urN linux/arch/ppc/configs/common_defconfig 
linux/arch/ppc/configs/common_defconfig
--- linux/arch/ppc/configs/common_defconfig     2004/02/20 01:22:13     1.20.2.8
+++ linux/arch/ppc/configs/common_defconfig     2005/01/20 02:19:23     1.20.2.9
@@ -180,7 +180,6 @@
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -urN linux/arch/ppc/configs/ibmchrp_defconfig 
linux/arch/ppc/configs/ibmchrp_defconfig
--- linux/arch/ppc/configs/ibmchrp_defconfig    2004/02/20 01:22:13     1.6.2.8
+++ linux/arch/ppc/configs/ibmchrp_defconfig    2005/01/20 02:19:23     1.6.2.9
@@ -173,7 +173,6 @@
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -urN linux/arch/ppc/configs/pal4_defconfig 
linux/arch/ppc/configs/pal4_defconfig
--- linux/arch/ppc/configs/Attic/pal4_defconfig 2004/02/20 01:22:13     1.1.2.6
+++ linux/arch/ppc/configs/Attic/pal4_defconfig 2005/01/20 02:19:23     1.1.2.7
@@ -172,7 +172,6 @@
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -urN linux/arch/ppc/configs/pmac_defconfig 
linux/arch/ppc/configs/pmac_defconfig
--- linux/arch/ppc/configs/pmac_defconfig       2004/02/20 01:22:13     1.3.2.8
+++ linux/arch/ppc/configs/pmac_defconfig       2005/01/20 02:19:23     1.3.2.9
@@ -183,7 +183,6 @@
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -urN linux/arch/ppc/configs/pplus_defconfig 
linux/arch/ppc/configs/pplus_defconfig
--- linux/arch/ppc/configs/pplus_defconfig      2004/02/20 01:22:13     1.11.2.3
+++ linux/arch/ppc/configs/pplus_defconfig      2005/01/20 02:19:23     1.11.2.4
@@ -175,7 +175,6 @@
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -urN linux/arch/ppc/configs/prpmc750_defconfig 
linux/arch/ppc/configs/prpmc750_defconfig
--- linux/arch/ppc/configs/prpmc750_defconfig   2004/02/20 01:22:13     1.7.2.2
+++ linux/arch/ppc/configs/prpmc750_defconfig   2005/01/20 02:19:23     1.7.2.3
@@ -183,7 +183,6 @@
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_NAT_FTP=m
 # CONFIG_IP_NF_MANGLE is not set
diff -urN linux/arch/s390/defconfig linux/arch/s390/defconfig
--- linux/arch/s390/defconfig   2004/11/19 00:28:34     1.7.2.7
+++ linux/arch/s390/defconfig   2005/01/20 02:19:23     1.7.2.8
@@ -199,7 +199,6 @@
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_NAT_LOCAL=y
 # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -urN linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- linux/arch/sparc64/defconfig        2004/12/27 04:13:40     1.60.2.16
+++ linux/arch/sparc64/defconfig        2005/01/20 02:19:23     1.60.2.17
@@ -253,7 +253,6 @@
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -urN linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c
--- linux/drivers/char/tty_io.c 2005/01/13 10:59:03     1.62.2.17
+++ linux/drivers/char/tty_io.c 2005/01/20 02:19:23     1.62.2.18
@@ -718,7 +718,12 @@
        wake_up_interruptible(&tty->write_wait);
 }
 
-EXPORT_SYMBOL_GPL(tty_wakeup);
+/*
+ * tty_wakeup/tty_ldisc_flush are actually _GPL exports but we can't do 
+ * that in 2.4 for modutils compat reasons.
+ */
+EXPORT_SYMBOL(tty_wakeup);
+
 
 void tty_ldisc_flush(struct tty_struct *tty)
 {
@@ -730,7 +735,12 @@
        }
 }
 
-EXPORT_SYMBOL_GPL(tty_ldisc_flush);
+
+/*
+ * tty_wakeup/tty_ldisc_flush are actually _GPL exports but we can't do 
+ * that in 2.4 for modutils compat reasons.
+ */
+EXPORT_SYMBOL(tty_ldisc_flush);
 
 void do_tty_hangup(void *data)
 {
diff -urN linux/drivers/net/tg3.c linux/drivers/net/tg3.c
--- linux/drivers/net/tg3.c     2004/11/19 00:28:39     1.1.2.17
+++ linux/drivers/net/tg3.c     2005/01/20 02:19:23     1.1.2.18
@@ -59,8 +59,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.14"
-#define DRV_MODULE_RELDATE     "November 15, 2004"
+#define DRV_MODULE_VERSION     "3.15"
+#define DRV_MODULE_RELDATE     "January 6, 2005"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -477,7 +477,8 @@
 static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
 {
        u32 frame_val;
-       int loops, ret;
+       unsigned int loops;
+       int ret;
 
        if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
                tw32_f(MAC_MI_MODE,
@@ -485,7 +486,7 @@
                udelay(80);
        }
 
-       *val = 0xffffffff;
+       *val = 0x0;
 
        frame_val  = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
                      MI_COM_PHY_ADDR_MASK);
@@ -496,7 +497,7 @@
        tw32_f(MAC_MI_COM, frame_val);
 
        loops = PHY_BUSY_LOOPS;
-       while (loops-- > 0) {
+       while (loops != 0) {
                udelay(10);
                frame_val = tr32(MAC_MI_COM);
 
@@ -505,10 +506,11 @@
                        frame_val = tr32(MAC_MI_COM);
                        break;
                }
+               loops -= 1;
        }
 
        ret = -EBUSY;
-       if (loops > 0) {
+       if (loops != 0) {
                *val = frame_val & MI_COM_DATA_MASK;
                ret = 0;
        }
@@ -524,7 +526,8 @@
 static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
 {
        u32 frame_val;
-       int loops, ret;
+       unsigned int loops;
+       int ret;
 
        if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
                tw32_f(MAC_MI_MODE,
@@ -542,7 +545,7 @@
        tw32_f(MAC_MI_COM, frame_val);
 
        loops = PHY_BUSY_LOOPS;
-       while (loops-- > 0) {
+       while (loops != 0) {
                udelay(10);
                frame_val = tr32(MAC_MI_COM);
                if ((frame_val & MI_COM_BUSY) == 0) {
@@ -550,10 +553,11 @@
                        frame_val = tr32(MAC_MI_COM);
                        break;
                }
+               loops -= 1;
        }
 
        ret = -EBUSY;
-       if (loops > 0)
+       if (loops != 0)
                ret = 0;
 
        if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
diff -urN linux/include/linux/if_arp.h linux/include/linux/if_arp.h
--- linux/include/linux/if_arp.h        2004/08/14 18:39:03     1.17.2.2
+++ linux/include/linux/if_arp.h        2005/01/20 02:19:24     1.17.2.3
@@ -40,6 +40,7 @@
 #define ARPHRD_METRICOM        23              /* Metricom STRIP (new IANA id) 
*/
 #define        ARPHRD_IEEE1394 24              /* IEEE 1394 IPv4 - RFC 2734    
*/
 #define ARPHRD_EUI64   27              /* EUI-64                       */
+#define ARPHRD_INFINIBAND      32              /* InfiniBand                   
*/
 
 /* Dummy types for non ARP hardware */
 #define ARPHRD_SLIP    256
diff -urN linux/include/linux/if_ether.h linux/include/linux/if_ether.h
--- linux/include/linux/if_ether.h      2003/08/13 17:19:29     1.10.2.3
+++ linux/include/linux/if_ether.h      2005/01/20 02:19:24     1.10.2.4
@@ -61,6 +61,8 @@
 #define ETH_P_IPV6     0x86DD          /* IPv6 over bluebook           */
 #define ETH_P_PPP_DISC 0x8863          /* PPPoE discovery messages     */
 #define ETH_P_PPP_SES  0x8864          /* PPPoE session messages       */
+#define ETH_P_MPLS_UC  0x8847          /* MPLS Unicast traffic         */
+#define ETH_P_MPLS_MC  0x8848          /* MPLS Multicast traffic       */
 #define ETH_P_ATMMPOA  0x884c          /* MultiProtocol Over ATM       */
 #define ETH_P_ATMFATE  0x8884          /* Frame-based ATM Transport
                                         * over Ethernet
diff -urN linux/include/linux/netfilter.h linux/include/linux/netfilter.h
--- linux/include/linux/netfilter.h     2004/08/14 18:39:03     1.7.2.2
+++ linux/include/linux/netfilter.h     2005/01/20 02:19:24     1.7.2.3
@@ -153,6 +153,7 @@
 extern inline struct arpt_target *
 arpt_find_target_lock(const char *name, int *error, struct semaphore *mutex);
 extern void (*ip_ct_attach)(struct sk_buff *, struct nf_ct_info *);
+extern void nf_ct_attach(struct sk_buff *, struct sk_buff *);
 
 #ifdef CONFIG_NETFILTER_DEBUG
 extern void nf_dump_skb(int pf, struct sk_buff *skb);
@@ -163,6 +164,7 @@
 
 #else /* !CONFIG_NETFILTER */
 #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
+static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
 #endif /*CONFIG_NETFILTER*/
 
 /* From arch/i386/kernel/smp.c:
diff -urN linux/include/linux/sctp.h linux/include/linux/sctp.h
--- linux/include/linux/sctp.h  2004/11/19 00:28:51     1.6.2.4
+++ linux/include/linux/sctp.h  2005/01/20 02:19:24     1.6.2.5
@@ -364,7 +364,7 @@
  */
 typedef struct sctp_abort_chunk {
         sctp_chunkhdr_t uh;
-} __attribute__((packed)) sctp_abort_chunkt_t;
+} __attribute__((packed)) sctp_abort_chunk_t;
 
 
 /* For the graceful shutdown we must carry the tag (in common header)
diff -urN linux/include/linux/netfilter_ipv4/ip_conntrack_core.h 
linux/include/linux/netfilter_ipv4/ip_conntrack_core.h
--- linux/include/linux/netfilter_ipv4/ip_conntrack_core.h      2003/08/13 
17:19:29     1.4.2.3
+++ linux/include/linux/netfilter_ipv4/ip_conntrack_core.h      2005/01/20 
02:19:24     1.4.2.4
@@ -25,9 +25,9 @@
 extern struct ip_conntrack *icmp_error_track(struct sk_buff *skb,
                                             enum ip_conntrack_info *ctinfo,
                                             unsigned int hooknum);
-extern int get_tuple(const struct iphdr *iph, size_t len,
-                    struct ip_conntrack_tuple *tuple,
-                    struct ip_conntrack_protocol *protocol);
+extern int ip_ct_get_tuple(const struct iphdr *iph, size_t len,
+                           struct ip_conntrack_tuple *tuple,
+                           struct ip_conntrack_protocol *protocol);
 
 /* Find a connection corresponding to a tuple. */
 struct ip_conntrack_tuple_hash *
diff -urN linux/include/linux/netfilter_ipv4/ip_nat.h 
linux/include/linux/netfilter_ipv4/ip_nat.h
--- linux/include/linux/netfilter_ipv4/ip_nat.h 2004/04/16 03:14:21     1.2.2.3
+++ linux/include/linux/netfilter_ipv4/ip_nat.h 2005/01/20 02:19:24     1.2.2.4
@@ -11,13 +11,8 @@
        IP_NAT_MANIP_DST
 };
 
-#ifndef CONFIG_IP_NF_NAT_LOCAL
-/* SRC manip occurs only on POST_ROUTING */
-#define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING)
-#else
 /* SRC manip occurs POST_ROUTING or LOCAL_IN */
 #define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING && (hooknum) != 
NF_IP_LOCAL_IN)
-#endif
 
 /* 2.3.19 (I hope) will define this in linux/netfilter_ipv4.h. */
 #ifndef SO_ORIGINAL_DST
diff -urN linux/include/net/inet_ecn.h linux/include/net/inet_ecn.h
--- linux/include/net/inet_ecn.h        2001/11/06 07:56:15     1.2
+++ linux/include/net/inet_ecn.h        2005/01/20 02:19:24     1.2.2.1
@@ -1,6 +1,14 @@
 #ifndef _INET_ECN_H_
 #define _INET_ECN_H_
 
+enum {
+       INET_ECN_NOT_ECT = 0,
+       INET_ECN_ECT_1 = 1,
+       INET_ECN_ECT_0 = 2,
+       INET_ECN_CE = 3,
+       INET_ECN_MASK = 3,
+};
+
 static inline int INET_ECN_is_ce(__u8 dsfield)
 {
        return (dsfield&3) == 3;
diff -urN linux/include/net/ip.h linux/include/net/ip.h
--- linux/include/net/ip.h      2004/11/19 00:28:51     1.20.2.3
+++ linux/include/net/ip.h      2005/01/20 02:19:24     1.20.2.4
@@ -102,7 +102,8 @@
                                      int getfrag (const void *,
                                                   char *,
                                                   unsigned int,
-                                                  unsigned int),
+                                                  unsigned int,
+                                                  struct sk_buff *),
                                      const void *frag,
                                      unsigned length,
                                      struct ipcm_cookie *ipc,
diff -urN linux/include/net/ip_vs.h linux/include/net/ip_vs.h
--- linux/include/net/ip_vs.h   2004/12/27 04:13:54     1.3.2.4
+++ linux/include/net/ip_vs.h   2005/01/20 02:19:24     1.3.2.5
@@ -97,6 +97,7 @@
        int             state;          /* sync daemon state */
        char            mcast_ifn[IP_VS_IFNAME_MAXLEN];
                                        /* multicast interface name */
+       int             syncid;
 
        /* virtual service options */
        u_int16_t       protocol;
@@ -213,8 +214,9 @@
 
 /* The argument to IP_VS_SO_GET_DAEMON */
 struct ip_vs_daemon_user {
-       int     state;                          /* sync daemon state */
-       char    mcast_ifn[IP_VS_IFNAME_MAXLEN]; /* multicast interface name */
+       int     state;                                  /* sync daemon state */
+       char    mcast_master_ifn[IP_VS_IFNAME_MAXLEN];  /* mcast master 
interface name */
+       char    mcast_backup_ifn[IP_VS_IFNAME_MAXLEN];  /* mcast backup 
interface name */
 };
 
 
@@ -726,9 +728,10 @@
  *      (from ip_vs_sync.c)
  */
 extern volatile int ip_vs_sync_state;
-extern char ip_vs_mcast_ifn[IP_VS_IFNAME_MAXLEN];
-extern int start_sync_thread(int state, char *mcast_ifn);
-extern int stop_sync_thread(void);
+extern char ip_vs_mcast_master_ifn[IP_VS_IFNAME_MAXLEN];
+extern char ip_vs_mcast_backup_ifn[IP_VS_IFNAME_MAXLEN];
+extern int start_sync_thread(int state, char *mcast_ifn, __u8 syncid);
+extern int stop_sync_thread(int state);
 extern void ip_vs_sync_conn(struct ip_vs_conn *cp);
 
 
diff -urN linux/include/net/sctp/command.h linux/include/net/sctp/command.h
--- linux/include/net/sctp/command.h    2004/11/19 00:28:51     1.8.2.4
+++ linux/include/net/sctp/command.h    2005/01/20 02:19:24     1.8.2.5
@@ -189,11 +189,6 @@
 } sctp_cmd_seq_t;
 
 
-/* Create a new sctp_command_sequence.
- * Return NULL if creating a new sequence fails.
- */
-sctp_cmd_seq_t *sctp_new_cmd_seq(int gfp);
-
 /* Initialize a block of memory as a command sequence.
  * Return 0 if the initialization fails.
  */
@@ -207,18 +202,10 @@
  */
 int sctp_add_cmd(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_arg_t obj);
 
-/* Rewind an sctp_cmd_seq_t to iterate from the start.
- * Return 0 if the rewind fails.
- */
-int sctp_rewind_sequence(sctp_cmd_seq_t *seq);
-
 /* Return the next command structure in an sctp_cmd_seq.
  * Return NULL at the end of the sequence.
  */
 sctp_cmd_t *sctp_next_cmd(sctp_cmd_seq_t *seq);
 
-/* Dispose of a command sequence.  */
-void sctp_free_cmd_seq(sctp_cmd_seq_t *seq);
-
 #endif /* __net_sctp_command_h__ */
 
diff -urN linux/include/net/sctp/compat.h linux/include/net/sctp/compat.h
--- linux/include/net/sctp/Attic/compat.h       2004/11/19 00:28:51     1.1.2.3
+++ linux/include/net/sctp/Attic/compat.h       2005/01/20 02:19:24     1.1.2.4
@@ -64,37 +64,6 @@
 #define __unsafe(x)
 #define dst_pmtu(x) ((x)->pmtu)
 
-#define sk_family family
-#define sk_state state
-#define sk_type type
-#define sk_socket socket
-#define sk_prot prot
-#define sk_rcvbuf rcvbuf
-#define sk_sndbuf sndbuf
-#define sk_ack_backlog ack_backlog
-#define sk_max_ack_backlog max_ack_backlog
-#define sk_write_space write_space
-#define sk_use_write_queue use_write_queue
-#define sk_err err
-#define sk_err_soft err_soft
-#define sk_error_report error_report
-#define sk_error_queue error_queue
-#define sk_shutdown shutdown
-#define sk_state_change state_change
-#define sk_receive_queue receive_queue
-#define sk_data_ready data_ready
-#define sk_no_check no_check
-#define sk_reuse reuse
-#define sk_destruct destruct
-#define sk_zapped zapped
-#define sk_protocol protocol
-#define sk_backlog_rcv backlog_rcv
-#define sk_allocation allocation
-#define sk_lingertime lingertime
-#define sk_sleep sleep
-#define sk_wmem_queued wmem_queued
-#define sk_bound_dev_if bound_dev_if
-
 /*
  * find last bit set.
  */
diff -urN linux/include/net/sctp/constants.h linux/include/net/sctp/constants.h
--- linux/include/net/sctp/constants.h  2004/11/19 00:28:51     1.8.2.4
+++ linux/include/net/sctp/constants.h  2005/01/20 02:19:24     1.8.2.5
@@ -105,9 +105,10 @@
 
 typedef enum {
        SCTP_EVENT_NO_PENDING_TSN = 0,
+       SCTP_EVENT_ICMP_PROTO_UNREACH,
 } sctp_event_other_t;
 
-#define SCTP_EVENT_OTHER_MAX           SCTP_EVENT_NO_PENDING_TSN
+#define SCTP_EVENT_OTHER_MAX           SCTP_EVENT_ICMP_PROTO_UNREACH
 #define SCTP_NUM_OTHER_TYPES           (SCTP_EVENT_OTHER_MAX + 1)
 
 /* These are primitive requests from the ULP.  */
@@ -155,10 +156,6 @@
                                - (unsigned long)(c->chunk_hdr)\
                                - sizeof(sctp_data_chunk_t)))
 
-/* This is a table of printable names of sctp_param_t's.  */
-extern const char *sctp_param_tbl[];
-
-
 #define SCTP_MAX_ERROR_CAUSE  SCTP_ERROR_NONEXIST_IP
 #define SCTP_NUM_ERROR_CAUSE  10
 
@@ -179,6 +176,7 @@
        SCTP_IERROR_IGNORE_TSN,
        SCTP_IERROR_NO_DATA,
        SCTP_IERROR_BAD_STREAM,
+       SCTP_IERROR_BAD_PORTS,
 
 } sctp_ierror_t;
 
diff -urN linux/include/net/sctp/sctp.h linux/include/net/sctp/sctp.h
--- linux/include/net/sctp/sctp.h       2004/08/14 18:39:03     1.18.2.4
+++ linux/include/net/sctp/sctp.h       2005/01/20 02:19:24     1.18.2.5
@@ -166,17 +166,9 @@
 int sctp_rcv(struct sk_buff *skb);
 void sctp_v4_err(struct sk_buff *skb, u32 info);
 void sctp_hash_established(struct sctp_association *);
-void __sctp_hash_established(struct sctp_association *);
 void sctp_unhash_established(struct sctp_association *);
-void __sctp_unhash_established(struct sctp_association *);
 void sctp_hash_endpoint(struct sctp_endpoint *);
-void __sctp_hash_endpoint(struct sctp_endpoint *);
 void sctp_unhash_endpoint(struct sctp_endpoint *);
-void __sctp_unhash_endpoint(struct sctp_endpoint *);
-struct sctp_association *__sctp_lookup_association(
-       const union sctp_addr *,
-       const union sctp_addr *,
-       struct sctp_transport **);
 struct sock *sctp_err_lookup(int family, struct sk_buff *,
                             struct sctphdr *, struct sctp_endpoint **,
                             struct sctp_association **,
@@ -185,6 +177,10 @@
                            struct sctp_association *);
 void sctp_icmp_frag_needed(struct sock *, struct sctp_association *,
                           struct sctp_transport *t, __u32 pmtu);
+void sctp_icmp_proto_unreachable(struct sock *sk,
+                                struct sctp_endpoint *ep,
+                                struct sctp_association *asoc,
+                                struct sctp_transport *t);
 
 /*
  *  Section:  Macros, externs, and inlines
@@ -332,8 +328,6 @@
 
 int sctp_v6_init(void);
 void sctp_v6_exit(void);
-void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
-                       int type, int code, int offset, __u32 info);
 
 #else /* #ifdef defined(CONFIG_IPV6) */
 
@@ -477,7 +471,8 @@
 #define _sctp_walk_params(pos, chunk, end, member)\
 for (pos.v = chunk->member;\
      pos.v <= (void *)chunk + end - sizeof(sctp_paramhdr_t) &&\
-     pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)); \
+     pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)) &&\
+     ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\
      pos.v += WORD_ROUND(ntohs(pos.p->length)))
 
 #define sctp_walk_errors(err, chunk_hdr)\
@@ -487,10 +482,9 @@
 for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
            sizeof(sctp_chunkhdr_t));\
      (void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\
-     (void *)err <= (void *)chunk_hdr + end - \
-                   WORD_ROUND(ntohs(err->length));\
-     err = (sctp_errhdr_t *)((void *)err + \
-           WORD_ROUND(ntohs(err->length))))
+     (void *)err <= (void *)chunk_hdr + end - WORD_ROUND(ntohs(err->length)) 
&&\
+     ntohs(err->length) >= sizeof(sctp_errhdr_t); \
+     err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length))))
 
 #define sctp_walk_fwdtsn(pos, chunk)\
 _sctp_walk_fwdtsn((pos), (chunk), ntohs((chunk)->chunk_hdr->length) - 
sizeof(struct sctp_fwdtsn_chunk))
@@ -622,7 +616,7 @@
 #define sctp_sstate(sk, state) __sctp_sstate((sk), (SCTP_SS_##state))
 int static inline __sctp_sstate(const struct sock *sk, sctp_sock_state_t state)
 {
-       return sk->sk_state == state;
+       return sk->state == state;
 }
 
 /* Map v4-mapped v6 address back to v4 address */
diff -urN linux/include/net/sctp/sm.h linux/include/net/sctp/sm.h
--- linux/include/net/sctp/sm.h 2004/11/19 00:28:51     1.16.2.4
+++ linux/include/net/sctp/sm.h 2005/01/20 02:19:24     1.16.2.5
@@ -128,9 +128,9 @@
 sctp_state_fn_t sctp_sf_do_ecn_cwr;
 sctp_state_fn_t sctp_sf_do_ecne;
 sctp_state_fn_t sctp_sf_ootb;
-sctp_state_fn_t sctp_sf_shut_8_4_5;
 sctp_state_fn_t sctp_sf_pdiscard;
 sctp_state_fn_t sctp_sf_violation;
+sctp_state_fn_t sctp_sf_violation_chunklen;
 sctp_state_fn_t sctp_sf_discard_chunk;
 sctp_state_fn_t sctp_sf_do_5_2_1_siminit;
 sctp_state_fn_t sctp_sf_do_5_2_2_dupinit;
@@ -138,7 +138,6 @@
 sctp_state_fn_t sctp_sf_unk_chunk;
 sctp_state_fn_t sctp_sf_do_8_5_1_E_sa;
 sctp_state_fn_t sctp_sf_cookie_echoed_err;
-sctp_state_fn_t sctp_sf_do_5_2_6_stale;
 sctp_state_fn_t sctp_sf_do_asconf;
 sctp_state_fn_t sctp_sf_do_asconf_ack;
 sctp_state_fn_t sctp_sf_do_9_2_reshutack;
@@ -167,6 +166,7 @@
 sctp_state_fn_t sctp_sf_do_9_2_start_shutdown;
 sctp_state_fn_t sctp_sf_do_9_2_shutdown_ack;
 sctp_state_fn_t sctp_sf_ignore_other;
+sctp_state_fn_t sctp_sf_cookie_wait_icmp_abort;
 
 /* Prototypes for timeout event state functions.  */
 sctp_state_fn_t sctp_sf_do_6_3_3_rtx;
@@ -200,19 +200,10 @@
 struct sctp_chunk *sctp_make_cwr(const struct sctp_association *,
                                 const __u32 lowest_tsn,
                                 const struct sctp_chunk *);
-struct sctp_chunk *sctp_make_datafrag(struct sctp_association *,
-                                const struct sctp_sndrcvinfo *sinfo,
-                                int len, const __u8 *data,
-                                __u8 flags, __u16 ssn);
 struct sctp_chunk * sctp_make_datafrag_empty(struct sctp_association *,
                                        const struct sctp_sndrcvinfo *sinfo,
                                        int len, const __u8 flags,
                                        __u16 ssn);
-struct sctp_chunk *sctp_make_data(struct sctp_association *,
-                            const struct sctp_sndrcvinfo *sinfo,
-                            int len, const __u8 *data);
-struct sctp_chunk *sctp_make_data_empty(struct sctp_association *,
-                                  const struct sctp_sndrcvinfo *, int len);
 struct sctp_chunk *sctp_make_ecne(const struct sctp_association *,
                                  const __u32);
 struct sctp_chunk *sctp_make_sack(const struct sctp_association *);
@@ -232,6 +223,10 @@
 struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *,
                                   const struct sctp_chunk *,
                                   const struct msghdr *);
+struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *,
+                                  const struct sctp_chunk *,
+                                  const __u8 *,
+                                  const size_t );
 struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *,
                                  const struct sctp_transport *,
                                  const void *payload,
@@ -246,17 +241,12 @@
                                 const void *payload,
                                 size_t paylen);
 
-struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
-                                   union sctp_addr *addr,
-                                   int vparam_len);
 struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *,
                                              union sctp_addr *,
                                              struct sockaddr *,
                                              int, __u16);
 struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
                                             union sctp_addr *addr);
-struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *asoc,
-                                       __u32 serial, int vparam_len);
 struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
                                       struct sctp_chunk *asconf);
 int sctp_process_asconf_ack(struct sctp_association *asoc,
@@ -268,6 +258,8 @@
 void sctp_chunk_assign_tsn(struct sctp_chunk *);
 void sctp_chunk_assign_ssn(struct sctp_chunk *);
 
+void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error);
+
 /* Prototypes for statetable processing. */
 
 int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
@@ -277,71 +269,26 @@
                void *event_arg,
                int gfp);
 
-int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
-                     sctp_state_t state,
-                      struct sctp_endpoint *,
-                      struct sctp_association *asoc,
-                      void *event_arg,
-                      sctp_disposition_t status,
-                     sctp_cmd_seq_t *commands,
-                      int gfp);
-
 /* 2nd level prototypes */
-int sctp_cmd_interpreter(sctp_event_t, sctp_subtype_t, sctp_state_t,
-                        struct sctp_endpoint *, struct sctp_association *,
-                        void *event_arg, sctp_disposition_t,
-                        sctp_cmd_seq_t *retval, int gfp);
-
-
-int sctp_gen_sack(struct sctp_association *, int force, sctp_cmd_seq_t *);
 void sctp_generate_t3_rtx_event(unsigned long peer);
 void sctp_generate_heartbeat_event(unsigned long peer);
 
-sctp_sackhdr_t *sctp_sm_pull_sack(struct sctp_chunk *);
-struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *,
-                                      const struct sctp_association *,
-                                      struct sctp_chunk *chunk,
-                                      const void *payload,
-                                      size_t paylen);
-struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *,
-                                     const struct sctp_chunk *);
 void sctp_ootb_pkt_free(struct sctp_packet *);
 
-struct sctp_cookie_param *
-sctp_pack_cookie(const struct sctp_endpoint *, const struct sctp_association *,
-                const struct sctp_chunk *, int *cookie_len,
-                const __u8 *, int addrs_len);
 struct sctp_association *sctp_unpack_cookie(const struct sctp_endpoint *,
                                       const struct sctp_association *,
                                       struct sctp_chunk *, int gfp, int *err,
                                       struct sctp_chunk **err_chk_p);
 int sctp_addip_addr_config(struct sctp_association *, sctp_param_t,
                           struct sockaddr_storage*, int);
-void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
-                               const struct sctp_association *asoc,
-                               const struct sctp_chunk *chunk,
-                               sctp_cmd_seq_t *commands,
-                               struct sctp_chunk *err_chunk);
-int sctp_eat_data(const struct sctp_association *asoc,
-                 struct sctp_chunk *chunk,
-                 sctp_cmd_seq_t *commands);
 
 /* 3rd level prototypes */
 __u32 sctp_generate_tag(const struct sctp_endpoint *);
 __u32 sctp_generate_tsn(const struct sctp_endpoint *);
 
 /* Extern declarations for major data structures.  */
-const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t, sctp_state_t);
-extern const sctp_sm_table_entry_t
-primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES];
-extern const sctp_sm_table_entry_t
-other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES];
-extern const sctp_sm_table_entry_t
-timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES];
 extern sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES];
 
-/* These are some handy utility macros... */
-
 
 /* Get the size of a DATA chunk payload. */
 static inline __u16 sctp_data_size(struct sctp_chunk *chunk)
diff -urN linux/include/net/sctp/structs.h linux/include/net/sctp/structs.h
--- linux/include/net/sctp/structs.h    2004/11/19 00:28:52     1.22.2.4
+++ linux/include/net/sctp/structs.h    2005/01/20 02:19:24     1.22.2.5
@@ -322,10 +322,19 @@
        /* This holds the originating address of the INIT packet.  */
        union sctp_addr peer_addr;
 
+       /* IG Section 2.35.3 
+        * Include the source port of the INIT-ACK
+        */
+       __u16           my_port;
+
        __u8 prsctp_capable;
 
+       /* Padding for future use */
+       __u8 padding;           
+
        __u32 adaption_ind;     
 
+
        /* This is a shim for my peer's INIT packet, followed by
         * a copy of the raw address list of the association.
         * The length of the raw address list is saved in the
@@ -406,7 +415,6 @@
        int malloced;
 };
 
-struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *, __u16, __u16);
 struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, int gfp);
 void sctp_ssnmap_free(struct sctp_ssnmap *map);
 void sctp_ssnmap_clear(struct sctp_ssnmap *map);
@@ -538,12 +546,9 @@
 struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *,
                                            struct sctp_sndrcvinfo *,
                                            struct msghdr *, int len);
-struct sctp_datamsg *sctp_datamsg_new(int gfp);
 void sctp_datamsg_put(struct sctp_datamsg *);
-void sctp_datamsg_hold(struct sctp_datamsg *);
 void sctp_datamsg_free(struct sctp_datamsg *);
 void sctp_datamsg_track(struct sctp_chunk *);
-void sctp_datamsg_assign(struct sctp_datamsg *, struct sctp_chunk *);
 void sctp_chunk_fail(struct sctp_chunk *, int error);
 int sctp_chunk_abandoned(struct sctp_chunk *);
 
@@ -651,8 +656,6 @@
 void sctp_chunk_put(struct sctp_chunk *);
 int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len,
                          struct iovec *data);
-struct sctp_chunk *sctp_make_chunk(const struct sctp_association *, __u8 type,
-                                  __u8 flags, int size);
 void sctp_chunk_free(struct sctp_chunk *);
 void  *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data);
 struct sctp_chunk *sctp_chunkify(struct sk_buff *,
@@ -853,12 +856,6 @@
        /* Error count : The current error count for this destination.  */
        unsigned short error_count;
 
-       /* Error       : Current error threshold for this destination
-        * Threshold   : i.e. what value marks the destination down if
-        *             : errorCount reaches this value.
-        */
-       unsigned short error_threshold;
-
        /* This is the max_retrans value for the transport and will
         * be initialized to proto.max_retrans.path.  This can be changed
         * using SCTP_SET_PEER_ADDR_PARAMS socket option.
@@ -922,15 +919,12 @@
 };
 
 struct sctp_transport *sctp_transport_new(const union sctp_addr *, int);
-struct sctp_transport *sctp_transport_init(struct sctp_transport *,
-                                          const union sctp_addr *, int);
 void sctp_transport_set_owner(struct sctp_transport *,
                              struct sctp_association *);
 void sctp_transport_route(struct sctp_transport *, union sctp_addr *,
                          struct sctp_opt *);
 void sctp_transport_pmtu(struct sctp_transport *);
 void sctp_transport_free(struct sctp_transport *);
-void sctp_transport_destroy(struct sctp_transport *);
 void sctp_transport_reset_timers(struct sctp_transport *);
 void sctp_transport_hold(struct sctp_transport *);
 void sctp_transport_put(struct sctp_transport *);
@@ -961,7 +955,6 @@
        int malloced;        /* Is this structure kfree()able?  */
 };
 
-struct sctp_inq *sctp_inq_new(void);
 void sctp_inq_init(struct sctp_inq *);
 void sctp_inq_free(struct sctp_inq *);
 void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet);
@@ -1029,7 +1022,6 @@
        char malloced;
 };
 
-struct sctp_outq *sctp_outq_new(struct sctp_association *);
 void sctp_outq_init(struct sctp_association *, struct sctp_outq *);
 void sctp_outq_teardown(struct sctp_outq *);
 void sctp_outq_free(struct sctp_outq*);
@@ -1070,7 +1062,6 @@
        int malloced;        /* Are we kfree()able?  */
 };
 
-struct sctp_bind_addr *sctp_bind_addr_new(int gfp_mask);
 void sctp_bind_addr_init(struct sctp_bind_addr *, __u16 port);
 void sctp_bind_addr_free(struct sctp_bind_addr *);
 int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
@@ -1220,8 +1211,6 @@
 
 /* These are function signatures for manipulating endpoints.  */
 struct sctp_endpoint *sctp_endpoint_new(struct sock *, int);
-struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *,
-                                        struct sock *, int gfp);
 void sctp_endpoint_free(struct sctp_endpoint *);
 void sctp_endpoint_put(struct sctp_endpoint *);
 void sctp_endpoint_hold(struct sctp_endpoint *);
@@ -1243,8 +1232,6 @@
 int sctp_process_init(struct sctp_association *, sctp_cid_t cid,
                      const union sctp_addr *peer,
                      sctp_init_chunk_t *init, int gfp);
-int sctp_process_param(struct sctp_association *, union sctp_params param,
-                      const union sctp_addr *from, int gfp);
 __u32 sctp_generate_tag(const struct sctp_endpoint *);
 __u32 sctp_generate_tsn(const struct sctp_endpoint *);
 
@@ -1693,10 +1680,6 @@
 struct sctp_association *
 sctp_association_new(const struct sctp_endpoint *, const struct sock *,
                     sctp_scope_t scope, int gfp);
-struct sctp_association *
-sctp_association_init(struct sctp_association *, const struct sctp_endpoint *,
-                     const struct sock *, sctp_scope_t scope,
-                     int gfp);
 void sctp_association_free(struct sctp_association *);
 void sctp_association_put(struct sctp_association *);
 void sctp_association_hold(struct sctp_association *);
@@ -1725,7 +1708,6 @@
                       struct sctp_association *new);
 
 __u32 sctp_association_get_next_tsn(struct sctp_association *);
-__u32 sctp_association_get_tsn_block(struct sctp_association *, int);
 
 void sctp_assoc_sync_pmtu(struct sctp_association *);
 void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned);
@@ -1739,7 +1721,6 @@
 int sctp_cmp_addr_exact(const union sctp_addr *ss1,
                        const union sctp_addr *ss2);
 struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc);
-struct sctp_chunk *sctp_get_no_prepend(struct sctp_association *asoc);
 
 /* A convenience structure to parse out SCTP specific CMSGs. */
 typedef struct sctp_cmsgs {
diff -urN linux/include/net/sctp/tsnmap.h linux/include/net/sctp/tsnmap.h
--- linux/include/net/sctp/tsnmap.h     2004/08/14 18:39:03     1.4.2.3
+++ linux/include/net/sctp/tsnmap.h     2005/01/20 02:19:24     1.4.2.4
@@ -120,12 +120,6 @@
        __u32 start;
 };
 
-/* Create a new tsnmap.  */
-struct sctp_tsnmap *sctp_tsnmap_new(__u16 len, __u32 init_tsn, int gfp);
-
-/* Dispose of a tsnmap.  */
-void sctp_tsnmap_free(struct sctp_tsnmap *);
-
 /* This macro assists in creation of external storage for variable length
  * internal buffers.  We double allocate so the overflow map works.
  */
@@ -210,14 +204,4 @@
 /* Is there a gap in the TSN map? */
 int sctp_tsnmap_has_gap(const struct sctp_tsnmap *);
 
-/* Initialize a gap ack block interator from user-provided memory.  */
-void sctp_tsnmap_iter_init(const struct sctp_tsnmap *,
-                          struct sctp_tsnmap_iter *);
-
-/* Get the next gap ack blocks.  We return 0 if there are no more
- * gap ack blocks.
- */
-int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *,
-       struct sctp_tsnmap_iter *,__u16 *start, __u16 *end);
-
 #endif /* __sctp_tsnmap_h__ */
diff -urN linux/include/net/sctp/ulpevent.h linux/include/net/sctp/ulpevent.h
--- linux/include/net/sctp/ulpevent.h   2004/11/19 00:28:52     1.5.2.4
+++ linux/include/net/sctp/ulpevent.h   2005/01/20 02:19:24     1.5.2.5
@@ -77,8 +77,6 @@
        return (struct sctp_ulpevent *)skb->cb;
 }
 
-struct sctp_ulpevent *sctp_ulpevent_new(int size, int flags, int gfp);
-void sctp_ulpevent_init(struct sctp_ulpevent *, int flags);
 void sctp_ulpevent_free(struct sctp_ulpevent *);
 int sctp_ulpevent_is_notification(const struct sctp_ulpevent *);
 void sctp_queue_purge_ulpevents(struct sk_buff_head *list);
diff -urN linux/include/net/sctp/ulpqueue.h linux/include/net/sctp/ulpqueue.h
--- linux/include/net/sctp/ulpqueue.h   2004/08/14 18:39:03     1.5.2.2
+++ linux/include/net/sctp/ulpqueue.h   2005/01/20 02:19:24     1.5.2.3
@@ -57,7 +57,6 @@
 };
 
 /* Prototypes. */
-struct sctp_ulpq *sctp_ulpq_new(struct sctp_association *asoc, int gfp);
 struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *,
                                 struct sctp_association *);
 void sctp_ulpq_free(struct sctp_ulpq *);
diff -urN linux/init/do_mounts.c linux/init/do_mounts.c
--- linux/init/do_mounts.c      2004/12/27 04:13:54     1.1.2.9
+++ linux/init/do_mounts.c      2005/01/20 02:19:24     1.1.2.10
@@ -348,7 +348,6 @@
 {
        char *fs_names = __getname();
        char *p;
-       int tries = 10;
 
        get_fs_names(fs_names);
 retry:
@@ -368,18 +367,11 @@
                 * Allow the user to distinguish between failed open
                 * and bad superblock on root device.
                 */
-               if (--tries) {
-                       printk ("VFS: Cannot open root device \"%s\" or %s, "
-                               "retrying in 1s.\n",
-                               root_device_name, kdevname (ROOT_DEV));
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(HZ);
-                       goto retry;
-               }
                printk ("VFS: Cannot open root device \"%s\" or %s\n",
                        root_device_name, kdevname (ROOT_DEV));
                printk ("Please append a correct \"root=\" boot option\n");
-               break;
+               panic("VFS: Unable to mount root fs on %s",
+                       kdevname(ROOT_DEV));
        }
        panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
 out:
diff -urN linux/net/netsyms.c linux/net/netsyms.c
--- linux/net/Attic/netsyms.c   2004/12/27 04:13:55     1.53.2.13
+++ linux/net/Attic/netsyms.c   2005/01/20 02:19:24     1.53.2.14
@@ -607,6 +607,7 @@
 EXPORT_SYMBOL(nf_setsockopt);
 EXPORT_SYMBOL(nf_getsockopt);
 EXPORT_SYMBOL(ip_ct_attach);
+EXPORT_SYMBOL(nf_ct_attach);
 #ifdef CONFIG_INET
 #include <linux/netfilter_ipv4.h>
 EXPORT_SYMBOL(ip_route_me_harder);
diff -urN linux/net/core/neighbour.c linux/net/core/neighbour.c
--- linux/net/core/neighbour.c  2004/11/19 00:28:53     1.18.2.6
+++ linux/net/core/neighbour.c  2005/01/20 02:19:25     1.18.2.7
@@ -427,11 +427,12 @@
 
        n->confirmed = jiffies - (n->parms->base_reachable_time<<1);
 
-       hash_val = tbl->hash(pkey, dev) & tbl->hash_mask;
-
        write_lock_bh(&tbl->lock);
        if (atomic_read(&tbl->entries) > (tbl->hash_mask + 1))
                neigh_hash_grow(tbl, (tbl->hash_mask + 1) << 1);
+
+       hash_val = tbl->hash(pkey, dev) & tbl->hash_mask;
+
        for (n1 = tbl->hash_buckets[hash_val]; n1; n1 = n1->next) {
                if (dev == n1->dev &&
                    memcmp(n1->primary_key, pkey, key_len) == 0) {
diff -urN linux/net/core/netfilter.c linux/net/core/netfilter.c
--- linux/net/core/netfilter.c  2003/08/13 17:19:30     1.12.2.3
+++ linux/net/core/netfilter.c  2005/01/20 02:19:25     1.12.2.4
@@ -622,12 +622,21 @@
 }
 #endif /*CONFIG_INET*/
 
-/* This does not belong here, but ipt_REJECT needs it if connection
-   tracking in use: without this, connection may not be in hash table,
-   and hence manufactured ICMP or RST packets will not be associated
-   with it. */
+/* This does not belong here, but locally generated errors need it if 
connection
+   tracking in use: without this, connection may not be in hash table, and 
hence
+   manufactured ICMP or RST packets will not be associated with it. */
 void (*ip_ct_attach)(struct sk_buff *, struct nf_ct_info *);
 
+void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb)
+{
+       void (*attach)(struct sk_buff *, struct nf_ct_info *);
+
+       if (skb->nfct && (attach = ip_ct_attach) != NULL) {
+               mb(); /* Just to be sure: must be read before executing this */
+               attach(new, skb->nfct);
+       }
+}
+
 void __init netfilter_init(void)
 {
        int i, h;
diff -urN linux/net/ipv4/icmp.c linux/net/ipv4/icmp.c
--- linux/net/ipv4/icmp.c       2004/04/16 03:14:22     1.30.2.7
+++ linux/net/ipv4/icmp.c       2005/01/20 02:19:25     1.30.2.8
@@ -281,12 +281,16 @@
  *     Checksum each fragment, and on the first include the headers and final 
checksum.
  */
  
-static int icmp_glue_bits(const void *p, char *to, unsigned int offset, 
unsigned int fraglen)
+static int icmp_glue_bits(const void *p, char *to, unsigned int offset,
+                          unsigned int fraglen, struct sk_buff *skb)
 {
        struct icmp_bxm *icmp_param = (struct icmp_bxm *)p;
        struct icmphdr *icmph;
        unsigned int csum;
 
+       if (icmp_pointers[icmp_param->data.icmph.type].error)
+               nf_ct_attach(skb, icmp_param->skb);
+
        if (offset) {
                icmp_param->csum=skb_copy_and_csum_bits(icmp_param->skb,
                                                        
icmp_param->offset+(offset-icmp_param->head_len), 
diff -urN linux/net/ipv4/ip_output.c linux/net/ipv4/ip_output.c
--- linux/net/ipv4/ip_output.c  2004/11/19 00:28:53     1.33.2.6
+++ linux/net/ipv4/ip_output.c  2005/01/20 02:19:25     1.33.2.7
@@ -438,7 +438,8 @@
                  int getfrag (const void *,
                               char *,
                               unsigned int,    
-                              unsigned int),
+                              unsigned int,
+                              struct sk_buff *),
                  const void *frag,
                  unsigned length,
                  struct ipcm_cookie *ipc,
@@ -607,7 +608,7 @@
                 *      User data callback
                 */
 
-               if (getfrag(frag, data, offset, fraglen-fragheaderlen)) {
+               if (getfrag(frag, data, offset, fraglen-fragheaderlen, skb)) {
                        err = -EFAULT;
                        kfree_skb(skb);
                        goto error;
@@ -647,7 +648,8 @@
                  int getfrag (const void *,
                               char *,
                               unsigned int,    
-                              unsigned int),
+                              unsigned int,
+                              struct sk_buff *),
                  const void *frag,
                  unsigned length,
                  struct ipcm_cookie *ipc,
@@ -721,10 +723,10 @@
                iph->daddr=rt->rt_dst;
                iph->check=0;
                iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
-               err = getfrag(frag, ((char *)iph)+iph->ihl*4,0, 
length-iph->ihl*4);
+               err = getfrag(frag, ((char *)iph)+iph->ihl*4,0, 
length-iph->ihl*4, skb);
        }
        else
-               err = getfrag(frag, (void *)iph, 0, length);
+               err = getfrag(frag, (void *)iph, 0, length, skb);
 
        if (err)
                goto error_fault;
@@ -921,7 +923,7 @@
  *     Fetch data from kernel space and fill in checksum if needed.
  */
 static int ip_reply_glue_bits(const void *dptr, char *to, unsigned int offset, 
-                             unsigned int fraglen)
+                             unsigned int fraglen, struct sk_buff *skb)
 {
         struct ip_reply_arg *dp = (struct ip_reply_arg*)dptr;
        u16 *pktp = (u16 *)to;
diff -urN linux/net/ipv4/raw.c linux/net/ipv4/raw.c
--- linux/net/ipv4/raw.c        2004/08/14 18:39:04     1.27.2.3
+++ linux/net/ipv4/raw.c        2005/01/20 02:19:25     1.27.2.4
@@ -266,7 +266,7 @@
  */
   
 static int raw_getfrag(const void *p, char *to, unsigned int offset,
-                       unsigned int fraglen)
+                      unsigned int fraglen, struct sk_buff *skb)
 {
        struct rawfakehdr *rfh = (struct rawfakehdr *) p;
        return memcpy_fromiovecend(to, rfh->iov, offset, fraglen);
@@ -277,7 +277,7 @@
  */
  
 static int raw_getrawfrag(const void *p, char *to, unsigned int offset,
-                               unsigned int fraglen)
+                               unsigned int fraglen, struct sk_buff *skb)
 {
        struct rawfakehdr *rfh = (struct rawfakehdr *) p;
 
diff -urN linux/net/ipv4/udp.c linux/net/ipv4/udp.c
--- linux/net/ipv4/udp.c        2004/12/27 04:13:56     1.35.2.8
+++ linux/net/ipv4/udp.c        2005/01/20 02:19:25     1.35.2.9
@@ -389,7 +389,8 @@
  *     Copy and checksum a UDP packet from user space into a buffer.
  */
  
-static int udp_getfrag(const void *p, char * to, unsigned int offset, unsigned 
int fraglen) 
+static int udp_getfrag(const void *p, char * to, unsigned int offset,
+                       unsigned int fraglen, struct sk_buff *skb)
 {
        struct udpfakehdr *ufh = (struct udpfakehdr *)p;
        if (offset==0) {
@@ -416,7 +417,8 @@
  *     Copy a UDP packet from user space into a buffer without checksumming.
  */
  
-static int udp_getfrag_nosum(const void *p, char * to, unsigned int offset, 
unsigned int fraglen) 
+static int udp_getfrag_nosum(const void *p, char * to, unsigned int offset,
+                             unsigned int fraglen, struct sk_buff *skb) 
 {
        struct udpfakehdr *ufh = (struct udpfakehdr *)p;
 
diff -urN linux/net/ipv4/ipvs/ip_vs_core.c linux/net/ipv4/ipvs/ip_vs_core.c
--- linux/net/ipv4/ipvs/ip_vs_core.c    2003/11/17 01:07:47     1.4.2.1
+++ linux/net/ipv4/ipvs/ip_vs_core.c    2005/01/20 02:19:25     1.4.2.2
@@ -1131,7 +1131,7 @@
        /* increase its packet counter and check if it is needed
           to be synchronized */
        atomic_inc(&cp->in_pkts);
-       if (ip_vs_sync_state == IP_VS_STATE_MASTER &&
+       if (ip_vs_sync_state & IP_VS_STATE_MASTER &&
            (cp->protocol != IPPROTO_TCP ||
             cp->state == IP_VS_S_ESTABLISHED) &&
            (atomic_read(&cp->in_pkts) % 50 == sysctl_ip_vs_sync_threshold))
diff -urN linux/net/ipv4/ipvs/ip_vs_ctl.c linux/net/ipv4/ipvs/ip_vs_ctl.c
--- linux/net/ipv4/ipvs/ip_vs_ctl.c     2004/12/27 04:13:56     1.6.2.3
+++ linux/net/ipv4/ipvs/ip_vs_ctl.c     2005/01/20 02:19:25     1.6.2.4
@@ -1731,10 +1731,11 @@
                ret = ip_vs_set_timeouts(urule);
                goto out_unlock;
        } else if (cmd == IP_VS_SO_SET_STARTDAEMON) {
-               ret = start_sync_thread(urule->state, urule->mcast_ifn);
+               ret = start_sync_thread(urule->state, urule->mcast_ifn,
+                                       urule->syncid);
                goto out_unlock;
        } else if (cmd == IP_VS_SO_SET_STOPDAEMON) {
-               ret = stop_sync_thread();
+               ret = stop_sync_thread(urule->state);
                goto out_unlock;
        } else if (cmd == IP_VS_SO_SET_ZERO) {
                /* if no service address is set, zero counters in all */
@@ -2082,7 +2083,10 @@
                        goto out;
                }
                u.state = ip_vs_sync_state;
-               strcpy(u.mcast_ifn, ip_vs_mcast_ifn);
+               if (ip_vs_sync_state & IP_VS_STATE_MASTER)
+                       strcpy(u.mcast_master_ifn, ip_vs_mcast_master_ifn);
+               if (ip_vs_sync_state & IP_VS_STATE_BACKUP)
+                       strcpy(u.mcast_backup_ifn, ip_vs_mcast_backup_ifn);
                if (copy_to_user(user, &u, sizeof(u)) != 0)
                        ret = -EFAULT;
        }
diff -urN linux/net/ipv4/ipvs/ip_vs_sync.c linux/net/ipv4/ipvs/ip_vs_sync.c
--- linux/net/ipv4/ipvs/ip_vs_sync.c    2004/11/19 00:29:04     1.4.2.3
+++ linux/net/ipv4/ipvs/ip_vs_sync.c    2005/01/20 02:19:25     1.4.2.4
@@ -13,6 +13,9 @@
  *              through multicast
  *
  * Changes:
+ *     Alexandre Cassen        :       Added master & backup support at a time.
+ *     Alexandre Cassen        :       Added SyncID support for incoming sync
+ *                                     messages filtering.
  *     Justin Ossevoort        :       Fix endian problem on sync message size.
  */
 
@@ -74,7 +77,7 @@
        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-      |  Count Conns  |   Reserved    |            Size               |
+      |  Count Conns  |    Sync ID    |            Size               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                                                               |
       |                    IPVS Sync Connection (1)                   |
@@ -86,11 +89,16 @@
       |                                                               |
       |                    IPVS Sync Connection (n)                   |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Count Conns : Number of IPVS sync Connection entries.
+   Sync ID     : IPVS sync group we belong to.
+   Size        : Size of packet.
+
 */
 #define SYNC_MESG_MAX_SIZE      (24*50+4)
 struct ip_vs_sync_mesg {
        __u8                    nr_conns;
-       __u8                    reserved;
+       __u8                    syncid;
        __u16                   size;
 
        /* ip_vs_sync_conn entries start here */
@@ -116,6 +124,18 @@
 static struct ip_vs_sync_buff   *curr_sb = NULL;
 static spinlock_t curr_sb_lock = SPIN_LOCK_UNLOCKED;
 
+/* ipvs sync daemon state */
+volatile int ip_vs_sync_state = IP_VS_STATE_NONE;
+volatile int ip_vs_master_syncid = 0;
+volatile int ip_vs_backup_syncid = 0;
+
+/* multicast interface name */
+char ip_vs_mcast_master_ifn[IP_VS_IFNAME_MAXLEN];
+char ip_vs_mcast_backup_ifn[IP_VS_IFNAME_MAXLEN];
+
+/* multicast addr */
+static struct sockaddr_in mcast_addr;
+
 static inline void sb_queue_tail(struct ip_vs_sync_buff *sb)
 {
        spin_lock(&ip_vs_sync_lock);
@@ -153,6 +173,7 @@
                return NULL;
        }
        sb->mesg->nr_conns = 0;
+       sb->mesg->syncid = ip_vs_master_syncid;
        sb->mesg->size = 4;
        sb->head = (unsigned char *)sb->mesg + 4;
        sb->end = (unsigned char *)sb->mesg + SYNC_MESG_MAX_SIZE;
@@ -265,6 +286,13 @@
                return;
        }
 
+       /* SyncID sanity check */
+       if (ip_vs_backup_syncid != 0 && m->syncid != ip_vs_backup_syncid) {
+               IP_VS_DBG(7, "Ignoring incoming msg with syncid = %d\n",
+                         m->syncid);
+               return;
+       }
+
        p = (char *)buffer + sizeof(struct ip_vs_sync_mesg);
        for (i=0; i<m->nr_conns; i++) {
                s = (struct ip_vs_sync_conn *)p;
@@ -308,16 +336,6 @@
 }
 
 
-/* ipvs sync daemon state */
-volatile int ip_vs_sync_state = IP_VS_STATE_NONE;
-
-/* multicast interface name */
-char ip_vs_mcast_ifn[IP_VS_IFNAME_MAXLEN];
-
-/* multicast addr */
-static struct sockaddr_in mcast_addr;
-
-
 /*
  *      Setup loopback of outgoing multicasts on a sending socket
  */
@@ -429,7 +447,7 @@
                return NULL;
        }
 
-       if (set_mcast_if(sock->sk, ip_vs_mcast_ifn) < 0) {
+       if (set_mcast_if(sock->sk, ip_vs_mcast_master_ifn) < 0) {
                IP_VS_ERR("Error setting outbound mcast interface\n");
                goto error;
        }
@@ -437,7 +455,7 @@
        set_mcast_loop(sock->sk, 0);
        set_mcast_ttl(sock->sk, 1);
 
-       if (bind_mcastif_addr(sock, ip_vs_mcast_ifn) < 0) {
+       if (bind_mcastif_addr(sock, ip_vs_mcast_master_ifn) < 0) {
                IP_VS_ERR("Error binding address of the mcast interface\n");
                goto error;
        }
@@ -483,7 +501,7 @@
        /* join the multicast group */
        if (join_mcast_group(sock->sk,
                             (struct in_addr*)&mcast_addr.sin_addr,
-                            ip_vs_mcast_ifn) < 0) {
+                            ip_vs_mcast_backup_ifn) < 0) {
                IP_VS_ERR("Error joining to the multicast group\n");
                goto error;
        }
@@ -571,10 +589,12 @@
 
 
 static DECLARE_WAIT_QUEUE_HEAD(sync_wait);
-static pid_t sync_pid = 0;
+static pid_t sync_master_pid = 0;
+static pid_t sync_backup_pid = 0;
 
 static DECLARE_WAIT_QUEUE_HEAD(stop_sync_wait);
-static int stop_sync = 0;
+static int stop_master_sync = 0;
+static int stop_backup_sync = 0;
 
 static void sync_master_loop(void)
 {
@@ -586,6 +606,10 @@
        if (!sock)
                return;
 
+       IP_VS_INFO("sync thread started: state = MASTER, mcast_ifn = %s, "
+                  "syncid = %d\n",
+                  ip_vs_mcast_master_ifn, ip_vs_master_syncid);
+
        for (;;) {
                while ((sb=sb_dequeue())) {
                        ip_vs_send_sync_msg(sock, sb->mesg);
@@ -598,7 +622,7 @@
                        ip_vs_sync_buff_release(sb);
                }
 
-               if (stop_sync)
+               if (stop_master_sync)
                        break;
 
                __set_current_state(TASK_INTERRUPTIBLE);
@@ -637,6 +661,10 @@
        if (!sock)
                goto out;
 
+       IP_VS_INFO("sync thread started: state = BACKUP, mcast_ifn = %s, "
+                  "syncid = %d\n",
+                  ip_vs_mcast_backup_ifn, ip_vs_backup_syncid);
+
        for (;;) {
                /* do you have data now? */
                while (!skb_queue_empty(&(sock->sk->receive_queue))) {
@@ -652,7 +680,7 @@
                        local_bh_enable();
                }
 
-               if (stop_sync)
+               if (stop_backup_sync)
                        break;
 
                __set_current_state(TASK_INTERRUPTIBLE);
@@ -667,12 +695,31 @@
        kfree(buf);
 }
 
+static void sync_pid_set(int sync_state, pid_t sync_pid)
+{
+       if (sync_state == IP_VS_STATE_MASTER)
+               sync_master_pid = sync_pid;
+       else if (sync_state == IP_VS_STATE_BACKUP)
+               sync_backup_pid = sync_pid;
+}
+
+static void sync_stop_set(int sync_state, int set)
+{
+       if (sync_state == IP_VS_STATE_MASTER)
+               stop_master_sync = set;
+       else if (sync_state == IP_VS_STATE_BACKUP)
+               stop_backup_sync = set;
+       else {
+               stop_master_sync = set;
+               stop_backup_sync = set;
+       }
+}
 
 static int sync_thread(void *startup)
 {
        DECLARE_WAITQUEUE(wait, current);
        mm_segment_t oldmm;
-       int state;
+       int state = IP_VS_STATE_NONE;
 
        MOD_INC_USE_COUNT;
        daemonize();
@@ -680,12 +727,15 @@
        oldmm = get_fs();
        set_fs(KERNEL_DS);
 
-       if (ip_vs_sync_state == IP_VS_STATE_MASTER)
+       if (ip_vs_sync_state & IP_VS_STATE_MASTER && !sync_master_pid) {
+               state = IP_VS_STATE_MASTER;
                sprintf(current->comm, "ipvs_syncmaster");
-       else if (ip_vs_sync_state == IP_VS_STATE_BACKUP)
+       } else if (ip_vs_sync_state & IP_VS_STATE_BACKUP) {
+               state = IP_VS_STATE_BACKUP;
                sprintf(current->comm, "ipvs_syncbackup");
-       else IP_VS_BUG();
+       } else IP_VS_BUG();
 
+       /* Block all signals */
        spin_lock_irq(&current->sigmask_lock);
        siginitsetinv(&current->blocked, 0);
        recalc_sigpending(current);
@@ -698,9 +748,7 @@
 
        add_wait_queue(&sync_wait, &wait);
 
-       state = ip_vs_sync_state;
-       sync_pid = current->pid;
-       IP_VS_INFO("sync thread started.\n");
+       sync_pid_set(state, current->pid);
        complete((struct completion *)startup);
 
        /* processing master/backup loop here */
@@ -713,13 +761,13 @@
        remove_wait_queue(&sync_wait, &wait);
 
        /* thread exits */
-       sync_pid = 0;
+       sync_pid_set(state, 0);
        IP_VS_INFO("sync thread stopped!\n");
 
        set_fs(oldmm);
        MOD_DEC_USE_COUNT;
 
-       stop_sync = 0;
+       sync_stop_set(state, 0);
        wake_up(&stop_sync_wait);
 
        return 0;
@@ -745,20 +793,27 @@
 }
 
 
-int start_sync_thread(int state, char *mcast_ifn)
+int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
 {
        DECLARE_COMPLETION(startup);
        pid_t pid;
 
-       if (sync_pid)
+       if ((state == IP_VS_STATE_MASTER && sync_master_pid) ||
+           (state == IP_VS_STATE_BACKUP && sync_backup_pid))
                return -EEXIST;
 
        IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid);
        IP_VS_DBG(7, "Each ip_vs_sync_conn entry need %d bytes\n",
                  sizeof(struct ip_vs_sync_conn));
 
-       ip_vs_sync_state = state;
-       strcpy(ip_vs_mcast_ifn, mcast_ifn);
+       ip_vs_sync_state |= state;
+       if (state == IP_VS_STATE_MASTER) {
+               strcpy(ip_vs_mcast_master_ifn, mcast_ifn);
+               ip_vs_master_syncid = syncid;
+       } else {
+               strcpy(ip_vs_mcast_backup_ifn, mcast_ifn);
+               ip_vs_backup_syncid = syncid;
+       }
 
   repeat:
        if ((pid = kernel_thread(fork_sync_thread, &startup, 0)) < 0) {
@@ -775,20 +830,22 @@
 }
 
 
-int stop_sync_thread(void)
+int stop_sync_thread(int state)
 {
        DECLARE_WAITQUEUE(wait, current);
 
-       if (!sync_pid)
+       if ((state == IP_VS_STATE_MASTER && !sync_master_pid) ||
+           (state == IP_VS_STATE_BACKUP && !sync_backup_pid))
                return -ESRCH;
 
        IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid);
-       IP_VS_INFO("stopping sync thread %d ...\n", sync_pid);
+       IP_VS_INFO("stopping sync thread %d ...\n",
+                  (state == IP_VS_STATE_MASTER) ? sync_master_pid : 
sync_backup_pid);
 
        __set_current_state(TASK_UNINTERRUPTIBLE);
        add_wait_queue(&stop_sync_wait, &wait);
-       ip_vs_sync_state = IP_VS_STATE_NONE;
-       stop_sync = 1;
+       sync_stop_set(state, 1);
+       ip_vs_sync_state -= state;
        wake_up(&sync_wait);
        schedule();
        __set_current_state(TASK_RUNNING);
@@ -797,7 +854,8 @@
        /* Note: no need to reap the sync thread, because its parent
           process is the init process */
 
-       if (stop_sync)
+       if ((state == IP_VS_STATE_MASTER && stop_master_sync) ||
+           (state == IP_VS_STATE_BACKUP && stop_backup_sync))
                IP_VS_BUG();
 
        return 0;
diff -urN linux/net/ipv4/netfilter/Config.in linux/net/ipv4/netfilter/Config.in
--- linux/net/ipv4/netfilter/Attic/Config.in    2003/08/13 17:19:30     1.5.2.6
+++ linux/net/ipv4/netfilter/Attic/Config.in    2005/01/20 02:19:25     1.5.2.7
@@ -66,7 +66,6 @@
           define_tristate CONFIG_IP_NF_NAT_AMANDA $CONFIG_IP_NF_NAT
         fi
       fi
-      bool '    NAT of local connections (READ HELP)' CONFIG_IP_NF_NAT_LOCAL
       if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
         dep_tristate '    Basic SNMP-ALG support (EXPERIMENTAL)' 
CONFIG_IP_NF_NAT_SNMP_BASIC $CONFIG_IP_NF_NAT
       fi
diff -urN linux/net/ipv4/netfilter/ip_conntrack_core.c 
linux/net/ipv4/netfilter/ip_conntrack_core.c
--- linux/net/ipv4/netfilter/ip_conntrack_core.c        2004/11/19 00:29:04     
1.13.2.11
+++ linux/net/ipv4/netfilter/ip_conntrack_core.c        2005/01/20 02:19:25     
1.13.2.12
@@ -122,9 +122,9 @@
 }
 
 inline int
-get_tuple(const struct iphdr *iph, size_t len,
-         struct ip_conntrack_tuple *tuple,
-         struct ip_conntrack_protocol *protocol)
+ip_ct_get_tuple(const struct iphdr *iph, size_t len,
+                struct ip_conntrack_tuple *tuple,
+                struct ip_conntrack_protocol *protocol)
 {
        int ret;
 
@@ -546,7 +546,7 @@
        innerproto = ip_ct_find_proto(inner->protocol);
        /* Are they talking about one of our connections? */
        if (inner->ihl * 4 + 8 > datalen
-           || !get_tuple(inner, datalen, &origtuple, innerproto)) {
+           || !ip_ct_get_tuple(inner, datalen, &origtuple, innerproto)) {
                DEBUGP("icmp_error: ! get_tuple p=%u (%u*4+%u dlen=%u)\n",
                       inner->protocol, inner->ihl, 8,
                       datalen);
@@ -757,7 +757,7 @@
 
        IP_NF_ASSERT((skb->nh.iph->frag_off & htons(IP_OFFSET)) == 0);
 
-       if (!get_tuple(skb->nh.iph, skb->len, &tuple, proto))
+       if (!ip_ct_get_tuple(skb->nh.iph, skb->len, &tuple, proto))
                return NULL;
 
        /* look for tuple match */
diff -urN linux/net/ipv4/netfilter/ip_conntrack_standalone.c 
linux/net/ipv4/netfilter/ip_conntrack_standalone.c
--- linux/net/ipv4/netfilter/ip_conntrack_standalone.c  2004/11/19 00:29:04     
1.11.2.10
+++ linux/net/ipv4/netfilter/ip_conntrack_standalone.c  2005/01/20 02:19:25     
1.11.2.11
@@ -468,6 +468,7 @@
 EXPORT_SYMBOL(ip_conntrack_protocol_register);
 EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
 EXPORT_SYMBOL(invert_tuplepr);
+EXPORT_SYMBOL(ip_ct_get_tuple);
 EXPORT_SYMBOL(ip_conntrack_alter_reply);
 EXPORT_SYMBOL(ip_conntrack_destroyed);
 EXPORT_SYMBOL(ip_conntrack_get);
diff -urN linux/net/ipv4/netfilter/ip_fw_compat_masq.c 
linux/net/ipv4/netfilter/ip_fw_compat_masq.c
--- linux/net/ipv4/netfilter/Attic/ip_fw_compat_masq.c  2004/08/14 18:39:05     
1.7.2.4
+++ linux/net/ipv4/netfilter/Attic/ip_fw_compat_masq.c  2005/01/20 02:19:25     
1.7.2.5
@@ -157,7 +157,7 @@
        case IPPROTO_UDP:
                IP_NF_ASSERT(((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) == 
0);
 
-               if (!get_tuple(iph, (*pskb)->len, &tuple, protocol)) {
+               if (!ip_ct_get_tuple(iph, (*pskb)->len, &tuple, protocol)) {
                        if (net_ratelimit())
                                printk("ip_fw_compat_masq: Can't get tuple\n");
                        return NF_ACCEPT;
diff -urN linux/net/ipv4/netfilter/ip_nat_core.c 
linux/net/ipv4/netfilter/ip_nat_core.c
--- linux/net/ipv4/netfilter/ip_nat_core.c      2004/08/14 18:39:05     1.9.2.10
+++ linux/net/ipv4/netfilter/ip_nat_core.c      2005/01/20 02:19:25     1.9.2.11
@@ -198,7 +198,6 @@
                return NULL;
 }
 
-#ifdef CONFIG_IP_NF_NAT_LOCAL
 /* If it's really a local destination manip, it may need to do a
    source manip too. */
 static int
@@ -217,7 +216,6 @@
        ip_rt_put(rt);
        return 1;
 }
-#endif
 
 /* Simple way to iterate through all. */
 static inline int fake_cmp(const struct ip_nat_hash *i,
@@ -317,7 +315,6 @@
                         * do_extra_mangle last time. */
                        *other_ipp = saved_ip;
 
-#ifdef CONFIG_IP_NF_NAT_LOCAL
                        if (hooknum == NF_IP_LOCAL_OUT
                            && *var_ipp != orig_dstip
                            && !do_extra_mangle(*var_ipp, other_ipp)) {
@@ -328,7 +325,6 @@
                                 * anyway. */
                                continue;
                        }
-#endif
 
                        /* Count how many others map onto this. */
                        score = count_maps(tuple->src.ip, tuple->dst.ip,
@@ -372,13 +368,11 @@
                else {
                        /* Only do extra mangle when required (breaks
                            socket binding) */
-#ifdef CONFIG_IP_NF_NAT_LOCAL
                        if (tuple->dst.ip != mr->range[0].min_ip
                            && hooknum == NF_IP_LOCAL_OUT
                            && !do_extra_mangle(mr->range[0].min_ip,
                                                &tuple->src.ip))
                                return NULL;
-#endif
                        tuple->dst.ip = mr->range[0].min_ip;
                }
        }
@@ -501,10 +495,8 @@
 static unsigned int opposite_hook[NF_IP_NUMHOOKS]
 = { [NF_IP_PRE_ROUTING] = NF_IP_POST_ROUTING,
     [NF_IP_POST_ROUTING] = NF_IP_PRE_ROUTING,
-#ifdef CONFIG_IP_NF_NAT_LOCAL
     [NF_IP_LOCAL_OUT] = NF_IP_LOCAL_IN,
     [NF_IP_LOCAL_IN] = NF_IP_LOCAL_OUT,
-#endif
 };
 
 unsigned int
@@ -868,6 +860,23 @@
        /* not reached */
 }
 
+static inline int tuple_src_equal_dst(const struct ip_conntrack_tuple *t1,
+                                      const struct ip_conntrack_tuple *t2)
+{
+       if (t1->dst.protonum != t2->dst.protonum || t1->src.ip != t2->dst.ip)
+               return 0;
+       if (t1->dst.protonum != IPPROTO_ICMP)
+               return t1->src.u.all == t2->dst.u.all;
+       else {
+               struct ip_conntrack_tuple inv;
+
+               /* ICMP tuples are asymetric */
+               invert_tuplepr(&inv, t1);
+               return inv.src.u.all == t2->src.u.all &&
+                      inv.dst.u.all == t2->dst.u.all;
+       }
+}
+
 unsigned int
 icmp_reply_translation(struct sk_buff *skb,
                       struct ip_conntrack *conntrack,
@@ -880,6 +889,7 @@
        size_t datalen = skb->len - ((void *)inner - (void *)iph);
        unsigned int i;
        struct ip_nat_info *info = &conntrack->nat.info;
+       struct ip_conntrack_tuple *cttuple, innertuple;
 
        IP_NF_ASSERT(skb->len >= iph->ihl*4 + sizeof(struct icmphdr));
        /* Must be RELATED */
@@ -914,6 +924,11 @@
           such addresses are not too uncommon, as Alan Cox points
           out) */
 
+       if (!ip_ct_get_tuple(inner, datalen, &innertuple,
+                            ip_ct_find_proto(inner->protocol)))
+               return 0;
+       cttuple = &conntrack->tuplehash[dir].tuple;
+
        READ_LOCK(&ip_nat_lock);
        for (i = 0; i < info->num_manips; i++) {
                DEBUGP("icmp_reply: manip %u dir %s hook %u\n",
@@ -923,35 +938,49 @@
                if (info->manips[i].direction != dir)
                        continue;
 
-               /* Mapping the inner packet is just like a normal
-                  packet, except it was never src/dst reversed, so
-                  where we would normally apply a dst manip, we apply
-                  a src, and vice versa. */
-               if (info->manips[i].hooknum == hooknum) {
-                       DEBUGP("icmp_reply: inner %s -> %u.%u.%u.%u %u\n",
-                              info->manips[i].maniptype == IP_NAT_MANIP_SRC
-                              ? "DST" : "SRC",
-                              NIPQUAD(info->manips[i].manip.ip),
-                              ntohs(info->manips[i].manip.u.udp.port));
-                       manip_pkt(inner->protocol, inner,
-                                 skb->len - ((void *)inner - (void *)iph),
-                                 &info->manips[i].manip,
-                                 !info->manips[i].maniptype,
-                                 &skb->nfcache);
-                       /* Outer packet needs to have IP header NATed like
-                          it's a reply. */
-
-                       /* Use mapping to map outer packet: 0 give no
-                           per-proto mapping */
-                       DEBUGP("icmp_reply: outer %s -> %u.%u.%u.%u\n",
-                              info->manips[i].maniptype == IP_NAT_MANIP_SRC
-                              ? "SRC" : "DST",
-                              NIPQUAD(info->manips[i].manip.ip));
-                       manip_pkt(0, iph, skb->len,
-                                 &info->manips[i].manip,
-                                 info->manips[i].maniptype,
-                                 &skb->nfcache);
+               /* Mapping the inner packet is just like a normal packet, except
+                * it was never src/dst reversed, so where we would normally
+                * apply a dst manip, we apply a src, and vice versa. */
+
+               /* Only true for forwarded packets, locally generated packets
+                * never hit PRE_ROUTING, we need to apply their PRE_ROUTING
+                * manips in LOCAL_OUT. */
+               if (hooknum == NF_IP_LOCAL_OUT &&
+                   info->manips[i].hooknum == NF_IP_PRE_ROUTING)
+                       hooknum = info->manips[i].hooknum;
+
+               if (info->manips[i].hooknum != hooknum)
+                       continue;
+
+               /* ICMP errors may be generated locally for packets that
+                * don't have all NAT manips applied yet. Verify manips
+                * have been applied before reversing them */
+               if (info->manips[i].maniptype == IP_NAT_MANIP_SRC) {
+                       if (!tuple_src_equal_dst(cttuple, &innertuple))
+                               continue;
+               } else {
+                       if (!tuple_src_equal_dst(&innertuple, cttuple))
+                               continue;
                }
+
+               DEBUGP("icmp_reply: inner %s -> %u.%u.%u.%u %u\n",
+                      info->manips[i].maniptype == IP_NAT_MANIP_SRC
+                      ? "DST" : "SRC", NIPQUAD(info->manips[i].manip.ip),
+                      ntohs(info->manips[i].manip.u.udp.port));
+               manip_pkt(inner->protocol, inner,
+                         skb->len - ((void *)inner - (void *)iph),
+                         &info->manips[i].manip, !info->manips[i].maniptype,
+                         &skb->nfcache);
+               /* Outer packet needs to have IP header NATed like
+                   it's a reply. */
+
+               /* Use mapping to map outer packet: 0 give no
+                          per-proto mapping */
+               DEBUGP("icmp_reply: outer %s -> %u.%u.%u.%u\n",
+                      info->manips[i].maniptype == IP_NAT_MANIP_SRC
+                      ? "SRC" : "DST", NIPQUAD(info->manips[i].manip.ip));
+               manip_pkt(0, iph, skb->len, &info->manips[i].manip,
+                         info->manips[i].maniptype, &skb->nfcache);
        }
        READ_UNLOCK(&ip_nat_lock);
 
diff -urN linux/net/ipv4/netfilter/ip_nat_rule.c 
linux/net/ipv4/netfilter/ip_nat_rule.c
--- linux/net/ipv4/netfilter/ip_nat_rule.c      2004/08/14 18:39:05     1.4.2.6
+++ linux/net/ipv4/netfilter/ip_nat_rule.c      2005/01/20 02:19:25     1.4.2.7
@@ -138,12 +138,8 @@
        struct ip_conntrack *ct;
        enum ip_conntrack_info ctinfo;
 
-#ifdef CONFIG_IP_NF_NAT_LOCAL
        IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
                     || hooknum == NF_IP_LOCAL_OUT);
-#else
-       IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING);
-#endif
 
        ct = ip_conntrack_get(*pskb, &ctinfo);
 
@@ -221,13 +217,6 @@
                return 0;
        }
        
-#ifndef CONFIG_IP_NF_NAT_LOCAL
-       if (hook_mask & (1 << NF_IP_LOCAL_OUT)) {
-               DEBUGP("DNAT: CONFIG_IP_NF_NAT_LOCAL not enabled\n");
-               return 0;
-       }
-#endif
-
        return 1;
 }
 
diff -urN linux/net/ipv4/netfilter/ip_nat_standalone.c 
linux/net/ipv4/netfilter/ip_nat_standalone.c
--- linux/net/ipv4/netfilter/ip_nat_standalone.c        2004/04/16 03:14:22     
1.12.2.9
+++ linux/net/ipv4/netfilter/ip_nat_standalone.c        2005/01/20 02:19:25     
1.12.2.10
@@ -114,16 +114,7 @@
                WRITE_LOCK(&ip_nat_lock);
                /* Seen it before?  This can happen for loopback, retrans,
                   or local packets.. */
-               if (!(info->initialized & (1 << maniptype))
-#ifndef CONFIG_IP_NF_NAT_LOCAL
-                   /* If this session has already been confirmed we must not
-                    * touch it again even if there is no mapping set up.
-                    * Can only happen on local->local traffic with
-                    * CONFIG_IP_NF_NAT_LOCAL disabled.
-                    */
-                   && !(ct->status & IPS_CONFIRMED)
-#endif
-                   ) {
+               if (!(info->initialized & (1 << maniptype))) {
                        unsigned int ret;
 
                        if (ct->master
@@ -132,15 +123,14 @@
                                ret = call_expect(master_ct(ct), pskb, 
                                                  hooknum, ct, info);
                        } else {
-#ifdef CONFIG_IP_NF_NAT_LOCAL
                                /* LOCAL_IN hook doesn't have a chain!  */
                                if (hooknum == NF_IP_LOCAL_IN)
                                        ret = alloc_null_binding(ct, info,
                                                                 hooknum);
                                else
-#endif
-                               ret = ip_nat_rule_find(pskb, hooknum, in, out,
-                                                      ct, info);
+                                       ret = ip_nat_rule_find(pskb, hooknum,
+                                                              in, out,
+                                                              ct, info);
                        }
 
                        if (ret != NF_ACCEPT) {
@@ -166,6 +156,29 @@
 }
 
 static unsigned int
+ip_nat_in(unsigned int hooknum,
+          struct sk_buff **pskb,
+          const struct net_device *in,
+          const struct net_device *out,
+          int (*okfn)(struct sk_buff *))
+{
+       u_int32_t saddr, daddr;
+       unsigned int ret;
+
+       saddr = (*pskb)->nh.iph->saddr;
+       daddr = (*pskb)->nh.iph->daddr;
+
+       ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
+       if (ret != NF_DROP && ret != NF_STOLEN
+           && ((*pskb)->nh.iph->saddr != saddr
+               || (*pskb)->nh.iph->daddr != daddr)) {
+               dst_release((*pskb)->dst);
+               (*pskb)->dst = NULL;
+       }
+       return ret;
+}
+
+static unsigned int
 ip_nat_out(unsigned int hooknum,
           struct sk_buff **pskb,
           const struct net_device *in,
@@ -197,7 +210,6 @@
        return ip_nat_fn(hooknum, pskb, in, out, okfn);
 }
 
-#ifdef CONFIG_IP_NF_NAT_LOCAL
 static unsigned int
 ip_nat_local_fn(unsigned int hooknum,
                struct sk_buff **pskb,
@@ -223,25 +235,21 @@
                return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
        return ret;
 }
-#endif
 
 /* We must be after connection tracking and before packet filtering. */
 
 /* Before packet filtering, change destination */
 static struct nf_hook_ops ip_nat_in_ops
-= { { NULL, NULL }, ip_nat_fn, PF_INET, NF_IP_PRE_ROUTING, NF_IP_PRI_NAT_DST };
+= { { NULL, NULL }, ip_nat_in, PF_INET, NF_IP_PRE_ROUTING, NF_IP_PRI_NAT_DST };
 /* After packet filtering, change source */
 static struct nf_hook_ops ip_nat_out_ops
 = { { NULL, NULL }, ip_nat_out, PF_INET, NF_IP_POST_ROUTING, 
NF_IP_PRI_NAT_SRC};
-
-#ifdef CONFIG_IP_NF_NAT_LOCAL
 /* Before packet filtering, change destination */
 static struct nf_hook_ops ip_nat_local_out_ops
 = { { NULL, NULL }, ip_nat_local_fn, PF_INET, NF_IP_LOCAL_OUT, 
NF_IP_PRI_NAT_DST };
 /* After packet filtering, change source for reply packets of LOCAL_OUT DNAT */
 static struct nf_hook_ops ip_nat_local_in_ops
 = { { NULL, NULL }, ip_nat_fn, PF_INET, NF_IP_LOCAL_IN, NF_IP_PRI_NAT_SRC };
-#endif
 
 /* Protocol registration. */
 int ip_nat_protocol_register(struct ip_nat_protocol *proto)
@@ -306,7 +314,6 @@
                printk("ip_nat_init: can't register out hook.\n");
                goto cleanup_inops;
        }
-#ifdef CONFIG_IP_NF_NAT_LOCAL
        ret = nf_register_hook(&ip_nat_local_out_ops);
        if (ret < 0) {
                printk("ip_nat_init: can't register local out hook.\n");
@@ -317,16 +324,13 @@
                printk("ip_nat_init: can't register local in hook.\n");
                goto cleanup_localoutops;
        }
-#endif
        return ret;
 
  cleanup:
-#ifdef CONFIG_IP_NF_NAT_LOCAL
        nf_unregister_hook(&ip_nat_local_in_ops);
  cleanup_localoutops:
        nf_unregister_hook(&ip_nat_local_out_ops);
  cleanup_outops:
-#endif
        nf_unregister_hook(&ip_nat_out_ops);
  cleanup_inops:
        nf_unregister_hook(&ip_nat_in_ops);
diff -urN linux/net/ipv4/netfilter/ip_tables.c 
linux/net/ipv4/netfilter/ip_tables.c
--- linux/net/ipv4/netfilter/ip_tables.c        2004/08/14 18:39:05     1.14.2.8
+++ linux/net/ipv4/netfilter/ip_tables.c        2005/01/20 02:19:25     1.14.2.9
@@ -1274,7 +1274,7 @@
                               sizeof(info.underflow));
                        info.num_entries = t->private->number;
                        info.size = t->private->size;
-                       strcpy(info.name, name);
+                       memcpy(info.name, name, sizeof(info.name));
 
                        if (copy_to_user(user, &info, *len) != 0)
                                ret = -EFAULT;
diff -urN linux/net/ipv4/netfilter/ipt_MASQUERADE.c 
linux/net/ipv4/netfilter/ipt_MASQUERADE.c
--- linux/net/ipv4/netfilter/ipt_MASQUERADE.c   2004/08/14 18:39:05     1.9.2.4
+++ linux/net/ipv4/netfilter/ipt_MASQUERADE.c   2005/01/20 02:19:25     1.9.2.5
@@ -125,35 +125,58 @@
 }
 
 static inline int
-device_cmp(const struct ip_conntrack *i, void *_ina)
+device_cmp(const struct ip_conntrack *i, void *ifindex)
 {
-       int ret = 0;
-       struct in_ifaddr *ina = _ina;
+       int ret;
 
        READ_LOCK(&masq_lock);
-       /* If it's masquerading out this interface with a different address,
-        * or we don't know the new address of this interface. */
-       if (i->nat.masq_index == ina->ifa_dev->dev->ifindex
-           && i->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != ina->ifa_address)
-               ret = 1;
+       ret = (i->nat.masq_index == (int)(long)ifindex);
        READ_UNLOCK(&masq_lock);
 
        return ret;
 }
 
+static int masq_device_event(struct notifier_block *this,
+                            unsigned long event,
+                            void *ptr)
+{
+       struct net_device *dev = ptr;
+
+       if (event == NETDEV_DOWN) {
+               /* Device was downed.  Search entire table for
+                  conntracks which were associated with that device,
+                  and forget them. */
+               IP_NF_ASSERT(dev->ifindex != 0);
+ 
+               ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
+       }
+
+       return NOTIFY_DONE;
+}
+
+
 static int masq_inet_event(struct notifier_block *this,
                           unsigned long event,
                           void *ptr)
 {
-       /* For some configurations, interfaces often come back with
-        * the same address.  If not, clean up old conntrack
-        * entries. */
-       if (event == NETDEV_UP)
-               ip_ct_selective_cleanup(device_cmp, ptr);
+       struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
+
+       if (event == NETDEV_DOWN) {
+               /* IP address was deleted.  Search entire table for
+                  conntracks which were associated with that device,
+                  and forget them. */
+               IP_NF_ASSERT(dev->ifindex != 0);
+
+               ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
+       }
 
        return NOTIFY_DONE;
 }
 
+static struct notifier_block masq_dev_notifier = {
+       .notifier_call  = masq_device_event,
+};
+
 static struct notifier_block masq_inet_notifier = {
        .notifier_call = masq_inet_event
 };
@@ -168,9 +191,12 @@
 
        ret = ipt_register_target(&masquerade);
 
-       if (ret == 0)
+       if (ret == 0) {
+               /* Register for device down reports */
+               register_netdevice_notifier(&masq_dev_notifier);
                /* Register IP address change reports */
                register_inetaddr_notifier(&masq_inet_notifier);
+       }
 
        return ret;
 }
@@ -178,6 +204,7 @@
 static void __exit fini(void)
 {
        ipt_unregister_target(&masquerade);
+       unregister_netdevice_notifier(&masq_dev_notifier);
        unregister_inetaddr_notifier(&masq_inet_notifier);      
 }
 
diff -urN linux/net/ipv4/netfilter/ipt_REJECT.c 
linux/net/ipv4/netfilter/ipt_REJECT.c
--- linux/net/ipv4/netfilter/ipt_REJECT.c       2004/08/14 18:39:05     1.13.2.7
+++ linux/net/ipv4/netfilter/ipt_REJECT.c       2005/01/20 02:19:25     1.13.2.8
@@ -22,18 +22,6 @@
 #define DEBUGP(format, args...)
 #endif
 
-/* If the original packet is part of a connection, but the connection
-   is not confirmed, our manufactured reply will not be associated
-   with it, so we need to do this manually. */
-static void connection_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct)
-{
-       void (*attach)(struct sk_buff *, struct nf_ct_info *);
-
-       /* Avoid module unload race with ip_ct_attach being NULLed out */
-       if (nfct && (attach = ip_ct_attach) != NULL)
-               attach(new_skb, nfct);
-}
-
 static inline struct rtable *route_reverse(struct sk_buff *skb, int hook)
 {
        struct iphdr *iph = skb->nh.iph;
@@ -187,7 +175,7 @@
        if (nskb->len > nskb->dst->pmtu)
                goto free_nskb;
 
-       connection_attach(nskb, oldskb->nfct);
+       nf_ct_attach(nskb, oldskb);
 
        NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
                ip_finish_output);
@@ -323,7 +311,7 @@
        icmph->checksum = ip_compute_csum((unsigned char *)icmph,
                                          length - sizeof(struct iphdr));
 
-       connection_attach(nskb, skb_in->nfct);
+       nf_ct_attach(nskb, skb_in);
 
        NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
                ip_finish_output);
diff -urN linux/net/ipv6/sit.c linux/net/ipv6/sit.c
--- linux/net/ipv6/sit.c        2004/11/19 00:29:05     1.23.2.7
+++ linux/net/ipv6/sit.c        2005/01/20 02:19:25     1.23.2.8
@@ -139,10 +139,10 @@
 {
        struct ip_tunnel **tp = ipip6_bucket(t);
 
-       write_lock_bh(&ipip6_lock);
        t->next = *tp;
-       write_unlock_bh(&ipip6_lock);
+       write_lock_bh(&ipip6_lock);
        *tp = t;
+       write_unlock_bh(&ipip6_lock);
 }
 
 struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int 
create)
diff -urN linux/net/ipv6/netfilter/ip6_tables.c 
linux/net/ipv6/netfilter/ip6_tables.c
--- linux/net/ipv6/netfilter/ip6_tables.c       2004/08/14 18:39:05     1.9.2.8
+++ linux/net/ipv6/netfilter/ip6_tables.c       2005/01/20 02:19:25     1.9.2.9
@@ -149,14 +149,15 @@
 /* Returns whether matches rule or not. */
 static inline int
 ip6_packet_match(const struct sk_buff *skb,
-                const struct ipv6hdr *ipv6,
                 const char *indev,
                 const char *outdev,
                 const struct ip6t_ip6 *ip6info,
-                int isfrag)
+                unsigned int *protoff,
+                int *fragoff)
 {
        size_t i;
        unsigned long ret;
+       const struct ipv6hdr *ipv6 = skb->nh.ipv6h;
 
 #define FWINV(bool,invflg) ((bool) ^ !!(ip6info->invflags & invflg))
 
@@ -210,6 +211,7 @@
                struct ipv6_opt_hdr *hdrptr;
                u_int16_t ptr;          /* Header offset in skb */
                u_int16_t hdrlen;       /* Header */
+               u_int16_t foff = 0;
 
                ptr = IPV6_HDR_LEN;
 
@@ -229,6 +231,16 @@
 
                        /* Size calculation */
                        if (currenthdr == IPPROTO_FRAGMENT) {
+                               unsigned int foff_off;
+
+                               foff_off = ptr + offsetof(struct frag_hdr,
+                                                         frag_off);
+                               if (skb->len - foff_off < sizeof(foff))
+                                       return 0;
+
+                               foff = ntohs(*(u_int16_t *)(skb->data
+                                                           + foff_off))
+                                      & ~0x7;
                                hdrlen = 8;
                        } else if (currenthdr == IPPROTO_AH)
                                hdrlen = (hdrptr->hdrlen+2)<<2;
@@ -240,8 +252,16 @@
                        /* ptr is too large */
                        if ( ptr > skb->len ) 
                                return 0;
+                       if (foff) {
+                               if (ip6t_ext_hdr(currenthdr))
+                                       return 0;
+                               break;
+                       }
                }
 
+               *protoff = ptr;
+               *fragoff = foff;
+
                /* currenthdr contains the protocol header */
 
                dprintf("Packet protocol %hi ?= %s%hi.\n",
@@ -329,10 +349,8 @@
              void *userdata)
 {
        static const char nulldevname[IFNAMSIZ] = { 0 };
-       u_int16_t offset = 0;
-       struct ipv6hdr *ipv6;
-       void *protohdr;
-       u_int16_t datalen;
+       int offset = 0;
+       unsigned int protoff = 0;
        int hotdrop = 0;
        /* Initializing verdict to NF_DROP keeps gcc happy. */
        unsigned int verdict = NF_DROP;
@@ -341,9 +359,6 @@
        struct ip6t_entry *e, *back;
 
        /* Initialization */
-       ipv6 = (*pskb)->nh.ipv6h;
-       protohdr = (u_int32_t *)((char *)ipv6 + IPV6_HDR_LEN);
-       datalen = (*pskb)->len - IPV6_HDR_LEN;
        indev = in ? in->name : nulldevname;
        outdev = out ? out->name : nulldevname;
 
@@ -381,17 +396,20 @@
                IP_NF_ASSERT(e);
                IP_NF_ASSERT(back);
                (*pskb)->nfcache |= e->nfcache;
-               if (ip6_packet_match(*pskb, ipv6, indev, outdev, 
-                       &e->ipv6, offset)) {
+               if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6,
+                                    &protoff, &offset)) {
                        struct ip6t_entry_target *t;
 
                        if (IP6T_MATCH_ITERATE(e, do_match,
                                               *pskb, in, out,
-                                              offset, protohdr,
-                                              datalen, &hotdrop) != 0)
+                                              offset,
+                                              (void *)((*pskb)->data
+                                                       + protoff),
+                                              (*pskb)->len - protoff,
+                                              &hotdrop) != 0)
                                goto no_match;
 
-                       ADD_COUNTER(e->counters, ntohs(ipv6->payload_len) + 
IPV6_HDR_LEN, 1);
+                       ADD_COUNTER(e->counters, 
ntohs((*pskb)->nh.ipv6h->payload_len) + IPV6_HDR_LEN, 1);
 
                        t = ip6t_get_target(e);
                        IP_NF_ASSERT(t->u.kernel.target);
@@ -447,11 +465,6 @@
                                ((struct ip6t_entry *)table_base)->comefrom
                                        = 0x57acc001;
 #endif
-                               /* Target might have changed stuff. */
-                               ipv6 = (*pskb)->nh.ipv6h;
-                               protohdr = (u_int32_t *)((void *)ipv6 + 
IPV6_HDR_LEN);
-                               datalen = (*pskb)->len - IPV6_HDR_LEN;
-
                                if (verdict == IP6T_CONTINUE)
                                        e = (void *)e + e->next_offset;
                                else
@@ -1343,7 +1356,7 @@
                               sizeof(info.underflow));
                        info.num_entries = t->private->number;
                        info.size = t->private->size;
-                       strcpy(info.name, name);
+                       memcpy(info.name, name, sizeof(info.name));
 
                        if (copy_to_user(user, &info, *len) != 0)
                                ret = -EFAULT;
@@ -1567,10 +1580,8 @@
          u_int16_t datalen,
          int *hotdrop)
 {
-       const struct tcphdr *tcp;
+       const struct tcphdr *tcp = hdr;
        const struct ip6t_tcp *tcpinfo = matchinfo;
-       int tcpoff;
-       u8 nexthdr = skb->nh.ipv6h->nexthdr;
 
        /* To quote Alan:
 
@@ -1591,24 +1602,6 @@
                return 0;
        }
 
-       tcpoff = (u8*)(skb->nh.ipv6h + 1) - skb->data;
-       tcpoff = ipv6_skip_exthdr(skb, tcpoff, &nexthdr, skb->len - tcpoff);
-       if (tcpoff < 0 || tcpoff > skb->len) {
-               duprintf("tcp_match: cannot skip exthdr. Dropping.\n");
-               *hotdrop = 1;
-               return 0;
-       } else if (nexthdr == IPPROTO_FRAGMENT)
-               return 0;
-       else if (nexthdr != IPPROTO_TCP ||
-                skb->len - tcpoff < sizeof(struct tcphdr)) {
-               /* cannot be occured */
-               duprintf("tcp_match: cannot get TCP header. Dropping.\n");
-               *hotdrop = 1;
-               return 0;
-       }
-
-       tcp = (struct tcphdr *)(skb->data + tcpoff);
-
        /* FIXME: Try tcp doff >> packet len against various stacks --RR */
 
 #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg))
@@ -1659,10 +1652,8 @@
          u_int16_t datalen,
          int *hotdrop)
 {
-       const struct udphdr *udp;
+       const struct udphdr *udp = hdr;
        const struct ip6t_udp *udpinfo = matchinfo;
-       int udpoff;
-       u8 nexthdr = skb->nh.ipv6h->nexthdr;
 
        if (offset == 0 && datalen < sizeof(struct udphdr)) {
                /* We've been asked to examine this packet, and we
@@ -1672,23 +1663,6 @@
                return 0;
        }
 
-       udpoff = (u8*)(skb->nh.ipv6h + 1) - skb->data;
-       udpoff = ipv6_skip_exthdr(skb, udpoff, &nexthdr, skb->len - udpoff);
-       if (udpoff < 0 || udpoff > skb->len) {
-               duprintf("udp_match: cannot skip exthdr. Dropping.\n");
-               *hotdrop = 1;
-               return 0;
-       } else if (nexthdr == IPPROTO_FRAGMENT)
-               return 0;
-       else if (nexthdr != IPPROTO_UDP ||
-                skb->len - udpoff < sizeof(struct udphdr)) {
-               duprintf("udp_match: cannot get UDP header. Dropping.\n");
-               *hotdrop = 1;
-               return 0;
-       }
-
-       udp = (struct udphdr *)(skb->data + udpoff);
-
        /* Must not be a fragment. */
        return !offset
                && port_match(udpinfo->spts[0], udpinfo->spts[1],
diff -urN linux/net/ipv6/netfilter/ip6t_LOG.c 
linux/net/ipv6/netfilter/ip6t_LOG.c
--- linux/net/ipv6/netfilter/ip6t_LOG.c 2004/11/19 00:29:05     1.1.2.3
+++ linux/net/ipv6/netfilter/ip6t_LOG.c 2005/01/20 02:19:25     1.1.2.4
@@ -35,54 +35,40 @@
        ntohs((addr).s6_addr16[6]), \
        ntohs((addr).s6_addr16[7])
 
-struct esphdr {
-       __u32   spi;
-}; /* FIXME evil kludge */
-        
-/* Use lock to serialize, so printks don't overlap */
-static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
+/* FIXME evil kludge */
 
-/* takes in current header and pointer to the header */
-/* if another header exists, sets hdrptr to the next header
-   and returns the new header value, else returns 0 */
-static u_int8_t ip6_nexthdr(u_int8_t currenthdr, u_int8_t **hdrptr)
-{
-       u_int8_t hdrlen, nexthdr = 0;
+struct ahhdr {
+       __u8  nexthdr;
+       __u8  hdrlen;
+       __u16 reserved;
+       __u32 spi;
+       __u32 seq_no;
+};
 
-       switch(currenthdr){
-               case IPPROTO_AH:
-               /* whoever decided to do the length of AUTH for ipv6
-               in 32bit units unlike other headers should be beaten...
-               repeatedly...with a large stick...no, an even LARGER
-               stick...no, you're still not thinking big enough */
-                       nexthdr = **hdrptr;
-                       hdrlen = (*hdrptr)[1] * 4 + 8;
-                       *hdrptr = *hdrptr + hdrlen;
-                       break;
-               /*stupid rfc2402 */
-               case IPPROTO_DSTOPTS:
-               case IPPROTO_ROUTING:
-               case IPPROTO_HOPOPTS:
-                       nexthdr = **hdrptr;
-                       hdrlen = (*hdrptr)[1] * 8 + 8;
-                       *hdrptr = *hdrptr + hdrlen;
-                       break;
-               case IPPROTO_FRAGMENT:
-                       nexthdr = **hdrptr;
-                       *hdrptr = *hdrptr + 8;
-                       break;
-       }       
-       return nexthdr;
+struct esphdr {
+       __u32 spi;
+       __u32 seq_no;
+};
 
-}
+/* Use lock to serialize, so printks don't overlap */
+static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
 
 /* One level of recursion won't kill us */
 static void dump_packet(const struct ip6t_log_info *info,
-                       struct ipv6hdr *ipv6h, int recurse)
+                       const struct sk_buff *skb, unsigned int ip6hoff,
+                       int recurse)
 {
-       u_int8_t currenthdr = ipv6h->nexthdr;
-       u_int8_t *hdrptr;
+       u_int8_t currenthdr;
        int fragment;
+       struct ipv6hdr *ipv6h;
+       unsigned int ptr;
+       unsigned int hdrlen = 0;
+
+       if (skb->len - ip6hoff < sizeof(*ipv6h)) {
+               printk("TRUNCATED");
+               return;
+       }
+       ipv6h = (struct ipv6hdr *)(skb->data + ip6hoff);
 
        /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 
DST=0000.0000.0000.0000.0000.0000.0000.0000" */
        printk("SRC=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", 
NIP6(ipv6h->saddr));
@@ -96,60 +82,131 @@
               (ntohl(*(u_int32_t *)ipv6h) & 0x000fffff));
 
        fragment = 0;
-       hdrptr = (u_int8_t *)(ipv6h + 1);
-       while (currenthdr) {
-               if ((currenthdr == IPPROTO_TCP) ||
-                   (currenthdr == IPPROTO_UDP) ||
-                   (currenthdr == IPPROTO_ICMPV6))
-                       break;
+       ptr = ip6hoff + sizeof(struct ipv6hdr);
+       currenthdr = ipv6h->nexthdr;
+       while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) {
+               struct ipv6_opt_hdr *hdr;
+
+               if (skb->len - ptr < sizeof(*hdr)) {
+                       printk("TRUNCATED");
+                       return;
+               }
+               hdr = (struct ipv6_opt_hdr *)(skb->data + ptr);
+
                /* Max length: 48 "OPT (...) " */
-               printk("OPT ( ");
+               if (info->logflags & IP6T_LOG_IPOPT)
+                       printk("OPT ( ");
+
                switch (currenthdr) {
                case IPPROTO_FRAGMENT: {
-                       struct frag_hdr *fhdr = (struct frag_hdr *)hdrptr;
+                       struct frag_hdr *fhdr;
 
-                       /* Max length: 11 "FRAG:65535 " */
-                       printk("FRAG:%u ", ntohs(fhdr->frag_off) & 0xFFF8);
+                       printk("FRAG:");
+                       if (skb->len - ptr < sizeof(*fhdr)) {
+                               printk("TRUNCATED ");
+                               return;
+                       }
+                       fhdr = (struct frag_hdr *)(skb->data + ptr);
+
+                       /* Max length: 6 "65535 " */
+                       printk("%u ", ntohs(fhdr->frag_off) & 0xFFF8);
 
                        /* Max length: 11 "INCOMPLETE " */
                        if (fhdr->frag_off & htons(0x0001))
                                printk("INCOMPLETE ");
 
-                       printk("ID:%08x ", fhdr->identification);
+                       printk("ID:%08x ", ntohl(fhdr->identification));
 
                        if (ntohs(fhdr->frag_off) & 0xFFF8)
                                fragment = 1;
 
+                       hdrlen = 8;
+
                        break;
                }
                case IPPROTO_DSTOPTS:
                case IPPROTO_ROUTING:
                case IPPROTO_HOPOPTS:
+                       if (fragment) {
+                               if (info->logflags & IP6T_LOG_IPOPT)
+                                       printk(")");
+                               return;
+                       }
+                       hdrlen = ipv6_optlen(hdr);
                        break;
                /* Max Length */
                case IPPROTO_AH:
+                       if (info->logflags & IP6T_LOG_IPOPT) {
+                               struct ahhdr *ah;
+
+                               /* Max length: 3 "AH " */
+                               printk("AH ");
+
+                               if (fragment) {
+                                       printk(")");
+                                       return;
+                               }
+
+                               if (skb->len - ptr < sizeof(*ah)) {
+                                       /*
+                                        * Max length: 26 "INCOMPLETE [65535    
+                                        *  bytes] )"
+                                        */
+                                       printk("INCOMPLETE [%u bytes] )",
+                                              skb->len - ptr);
+                                       return;
+                               }
+                               ah = (struct ahhdr *)(skb->data + ptr);
+
+                               /* Length: 15 "SPI=0xF1234567 */
+                               printk("SPI=0x%x ", ntohl(ah->spi));
+
+                       }
+
+                       hdrlen = (hdr->hdrlen+2)<<2;
+                       break;
                case IPPROTO_ESP:
                        if (info->logflags & IP6T_LOG_IPOPT) {
-                               struct esphdr *esph = (struct esphdr *)hdrptr;
-                               int esp = (currenthdr == IPPROTO_ESP);
+                               struct esphdr *esph;
 
                                /* Max length: 4 "ESP " */
-                               printk("%s ",esp ? "ESP" : "AH");
+                               printk("ESP ");
+
+                               if (fragment) {
+                                       printk(")");
+                                       return;
+                               }
+
+                               /*
+                                * Max length: 26 "INCOMPLETE [65535 bytes] )"
+                                */
+                               if (skb->len - ptr < sizeof(*esph)) {
+                                       printk("INCOMPLETE [%u bytes] )",
+                                              skb->len - ptr);
+                                       return;
+                               }
+                               esph = (struct esphdr *)(skb->data + ptr);
+
+                               /* Length: 16 "SPI=0xF1234567 )" */
+                               printk("SPI=0x%x )", ntohl(esph->spi) );
 
-                               /* Length: 15 "SPI=0xF1234567 " */
-                               printk("SPI=0x%x ", ntohl(esph->spi) );
-                               break;
                        }
+                       return;
                default:
-                       break;
+                       /* Max length: 20 "Unknown Ext Hdr 255" */
+                       printk("Unknown Ext Hdr %u", currenthdr);
+                       return;
                }
-               printk(") ");
-               currenthdr = ip6_nexthdr(currenthdr, &hdrptr);
+               if (info->logflags & IP6T_LOG_IPOPT)
+                       printk(") ");
+
+               currenthdr = hdr->nexthdr;
+               ptr += hdrlen;
        }
 
        switch (currenthdr) {
        case IPPROTO_TCP: {
-               struct tcphdr *tcph = (struct tcphdr *)hdrptr;
+               struct tcphdr *tcph;
 
                /* Max length: 10 "PROTO=TCP " */
                printk("PROTO=TCP ");
@@ -157,6 +214,13 @@
                if (fragment)
                        break;
 
+               /* Max length: 25 "INCOMPLETE [65535 bytes] " */
+               if (skb->len - ptr < sizeof(*tcph)) {
+                       printk("INCOMPLETE [%u bytes] ", skb->len - ptr);
+                       return;
+               }
+               tcph = (struct tcphdr *)(skb->data + ptr);
+
                /* Max length: 20 "SPT=65535 DPT=65535 " */
                printk("SPT=%u DPT=%u ",
                       ntohs(tcph->source), ntohs(tcph->dest));
@@ -166,7 +230,7 @@
                               ntohl(tcph->seq), ntohl(tcph->ack_seq));
                /* Max length: 13 "WINDOW=65535 " */
                printk("WINDOW=%u ", ntohs(tcph->window));
-               /* Max length: 9 "RES=0x3F " */
+               /* Max length: 9 "RES=0x3C " */
                printk("RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(tcph) & 
TCP_RESERVED_BITS) >> 22));
                /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
                if (tcph->cwr)
@@ -189,19 +253,29 @@
                printk("URGP=%u ", ntohs(tcph->urg_ptr));
 
                if ((info->logflags & IP6T_LOG_TCPOPT)
-                   && tcph->doff * 4 != sizeof(struct tcphdr)) {
+                   && tcph->doff * 4 > sizeof(struct tcphdr)) {
+                       u_int8_t *op;
                        unsigned int i;
+                       unsigned int optsize = tcph->doff * 4
+                                              - sizeof(struct tcphdr);
+
+                       if (skb->len - ptr - sizeof(struct tcphdr) < optsize) {
+                               printk("OPT (TRUNCATED)");
+                               return;
+                       }
+                       op = (u_int8_t *)(skb->data + ptr
+                                         + sizeof(struct tcphdr));
 
                        /* Max length: 127 "OPT (" 15*4*2chars ") " */
                        printk("OPT (");
-                       for (i =sizeof(struct tcphdr); i < tcph->doff * 4; i++)
-                               printk("%02X", ((u_int8_t *)tcph)[i]);
+                       for (i =0; i < optsize; i++)
+                               printk("%02X", op[i]);
                        printk(") ");
                }
                break;
        }
        case IPPROTO_UDP: {
-               struct udphdr *udph = (struct udphdr *)hdrptr;
+               struct udphdr *udph;
 
                /* Max length: 10 "PROTO=UDP " */
                printk("PROTO=UDP ");
@@ -209,6 +283,13 @@
                if (fragment)
                        break;
 
+               /* Max length: 25 "INCOMPLETE [65535 bytes] " */
+               if (skb->len - ptr < sizeof(*udph)) {
+                       printk("INCOMPLETE [%u bytes] ", skb->len - ptr);
+                       return;
+               }
+               udph = (struct udphdr *)(skb->data + ptr);
+
                /* Max length: 20 "SPT=65535 DPT=65535 " */
                printk("SPT=%u DPT=%u LEN=%u ",
                       ntohs(udph->source), ntohs(udph->dest),
@@ -216,7 +297,7 @@
                break;
        }
        case IPPROTO_ICMPV6: {
-               struct icmp6hdr *icmp6h = (struct icmp6hdr *)hdrptr;
+               struct icmp6hdr *icmp6h;
 
                /* Max length: 13 "PROTO=ICMPv6 " */
                printk("PROTO=ICMPv6 ");
@@ -224,6 +305,13 @@
                if (fragment)
                        break;
 
+               /* Max length: 25 "INCOMPLETE [65535 bytes] " */
+               if (skb->len - ptr < sizeof(*icmp6h)) {
+                       printk("INCOMPLETE [%u bytes] ", skb->len - ptr);
+                       return;
+               }
+               icmp6h = (struct icmp6hdr *)(skb->data + ptr);
+
                /* Max length: 18 "TYPE=255 CODE=255 " */
                printk("TYPE=%u CODE=%u ", icmp6h->icmp6_type, 
icmp6h->icmp6_code);
 
@@ -250,7 +338,8 @@
                        /* Max length: 3+maxlen */
                        if (recurse) {
                                printk("[");
-                               dump_packet(info, (struct ipv6hdr *)(icmp6h + 
1), 0);
+                               dump_packet(info, skb, ptr + sizeof(*icmp6h),
+                                           0);
                                printk("] ");
                        }
 
@@ -260,7 +349,7 @@
                }
                break;
        }
-       /* Max length: 10 "PROTO 255 " */
+       /* Max length: 10 "PROTO=255 " */
        default:
                printk("PROTO=%u ", currenthdr);
        }
@@ -326,7 +415,8 @@
                        printk(" ");
        }
 
-       dump_packet(loginfo, ipv6h, 1);
+       dump_packet(loginfo, (*pskb), (u8*)(*pskb)->nh.ipv6h - (*pskb)->data,
+                   1);
        printk("\n");
        spin_unlock_bh(&log_lock);
 
diff -urN linux/net/ipv6/netfilter/ip6t_dst.c 
linux/net/ipv6/netfilter/ip6t_dst.c
--- linux/net/ipv6/netfilter/ip6t_dst.c 2003/07/05 03:23:48     1.3.2.1
+++ linux/net/ipv6/netfilter/ip6t_dst.c 2005/01/20 02:19:25     1.3.2.2
@@ -11,8 +11,6 @@
 #include <linux/netfilter_ipv6/ip6_tables.h>
 #include <linux/netfilter_ipv6/ip6t_opts.h>
 
-#define LOW(n)         (n & 0x00FF)
-
 #define HOPBYHOP       0
 
 EXPORT_NO_SYMBOLS;
@@ -40,8 +38,8 @@
  *     0       -> invariant
  *     1       -> can change the routing
  *  (Type & 0x1F) Type
- *      0      -> PAD0 (only 1 byte!)
- *      1      -> PAD1 LENGTH info (total length = length + 2)
+ *      0      -> Pad1 (only 1 byte!)
+ *      1      -> PadN LENGTH info (total length = length + 2)
  *      C0 | 2 -> JUMBO 4 x x x x ( xxxx > 64k )
  *      5      -> RTALERT 2 x x
  */
@@ -64,7 +62,8 @@
        unsigned int ptr;
        unsigned int hdrlen = 0;
        unsigned int ret = 0;
-       u_int16_t *optdesc = NULL;
+       u8 *opttype = NULL;
+       unsigned int optlen;
        
        /* type of the 1st exthdr */
        nexthdr = skb->nh.ipv6h->nexthdr;
@@ -91,7 +90,7 @@
                      break;
               }
 
-              hdr=(void *)(skb->data)+ptr;
+             hdr = (void *)(skb->data + ptr);
 
               /* Calculate the header length */
                 if (nexthdr == NEXTHDR_FRAGMENT) {
@@ -153,7 +152,7 @@
                        return 0;
        }
 
-       optsh=(void *)(skb->data)+ptr;
+       optsh = (void *)(skb->data + ptr);
 
        DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, optsh->hdrlen);
 
@@ -169,7 +168,6 @@
                            ((optinfo->hdrlen == hdrlen) ^
                            !!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
 
-       temp = len = 0;
        ptr += 2;
        hdrlen -= 2;
        if ( !(optinfo->flags & IP6T_OPTS_OPTS) ){
@@ -180,48 +178,52 @@
                DEBUGP("Strict ");
                DEBUGP("#%d ",optinfo->optsnr);
                for(temp=0; temp<optinfo->optsnr; temp++){
-                       optdesc = (void *)(skb->data)+ptr;
+                       /* type field exists ? */
+                       if (ptr > skb->len - 1 || hdrlen < 1)
+                               break;
+                       opttype = (void *)(skb->data + ptr);
+
                        /* Type check */
-                       if ( (unsigned char)*optdesc != 
-                               (optinfo->opts[temp] & 0xFF00)>>8 ){
+                       if (*opttype != (optinfo->opts[temp] & 0xFF00)>>8){
                                DEBUGP("Tbad %02X %02X\n",
-                                               (unsigned char)*optdesc,
-                                               (optinfo->opts[temp] &
-                                                0xFF00)>>8);
+                                      *opttype,
+                                      (optinfo->opts[temp] & 0xFF00)>>8);
                                return 0;
                        } else {
                                DEBUGP("Tok ");
                        }
                        /* Length check */
-                       if (((optinfo->opts[temp] & 0x00FF) != 0xFF) &&
-                               (unsigned char)*optdesc != 0){
-                               if ( ntohs((u16)*optdesc) != 
-                                               optinfo->opts[temp] ){
-                                       DEBUGP("Lbad %02X %04X %04X\n",
-                                                       (unsigned char)*optdesc,
-                                                       ntohs((u16)*optdesc),
-                                                       optinfo->opts[temp]);
+                       if (*opttype) {
+                               u16 spec_len;
+
+                               /* length field exists ? */
+                               if (ptr > skb->len - 2 || hdrlen < 2)
+                                       break;
+                               optlen = *((u8 *)(skb->data + ptr + 1));
+                               spec_len = optinfo->opts[temp] & 0x00FF;
+
+                               if (spec_len != 0x00FF && spec_len != optlen) {
+                                       DEBUGP("Lbad %02X %04X\n", optlen,
+                                              spec_len);
                                        return 0;
-                               } else {
-                                       DEBUGP("Lok ");
                                }
-                       }
-                       /* Step to the next */
-                       if ((unsigned char)*optdesc == 0){
-                               DEBUGP("PAD0 \n");
-                               ptr++;
-                               hdrlen--;
+                               DEBUGP("Lok ");
+                               optlen += 2;
                        } else {
-                               ptr += LOW(ntohs(*optdesc));
-                               hdrlen -= LOW(ntohs(*optdesc));
-                               DEBUGP("len%04X \n", 
-                                       LOW(ntohs(*optdesc)));
+                               DEBUGP("Pad1\n");
+                               optlen = 1;
                        }
-                       if (ptr > skb->len || ( !hdrlen && 
-                               (temp != optinfo->optsnr - 1))) {
+
+                       /* Step to the next */
+                       DEBUGP("len%04X \n", optlen);
+
+                       if ((ptr > skb->len - optlen || hdrlen < optlen) &&
+                           (temp < optinfo->optsnr - 1)) {
                                DEBUGP("new pointer is too large! \n");
                                break;
                        }
+                       ptr += optlen;
+                       hdrlen -= optlen;
                }
                if (temp == optinfo->optsnr)
                        return ret;
diff -urN linux/net/ipv6/netfilter/ip6t_esp.c 
linux/net/ipv6/netfilter/ip6t_esp.c
--- linux/net/ipv6/netfilter/ip6t_esp.c 2003/08/13 17:19:31     1.4.2.2
+++ linux/net/ipv6/netfilter/ip6t_esp.c 2005/01/20 02:19:25     1.4.2.3
@@ -22,6 +22,7 @@
 
 struct esphdr {
        __u32   spi;
+       __u32   seq_no;
 };
 
 /* Returns 1 if the spi is matched by the range, 0 otherwise */
diff -urN linux/net/ipv6/netfilter/ip6t_eui64.c 
linux/net/ipv6/netfilter/ip6t_eui64.c
--- linux/net/ipv6/netfilter/ip6t_eui64.c       2002/09/11 12:45:45     1.1.2.1
+++ linux/net/ipv6/netfilter/ip6t_eui64.c       2005/01/20 02:19:25     1.1.2.2
@@ -58,7 +58,7 @@
 {
        if (hook_mask
            & ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) |
-               (1 << NF_IP6_PRE_ROUTING) )) {
+               (1 << NF_IP6_FORWARD))) {
                printk("ip6t_eui64: only valid for PRE_ROUTING, LOCAL_IN or 
FORWARD.\n");
                return 0;
        }
diff -urN linux/net/ipv6/netfilter/ip6t_frag.c 
linux/net/ipv6/netfilter/ip6t_frag.c
--- linux/net/ipv6/netfilter/ip6t_frag.c        2003/08/13 17:19:31     1.4.2.2
+++ linux/net/ipv6/netfilter/ip6t_frag.c        2005/01/20 02:19:25     1.4.2.3
@@ -6,8 +6,6 @@
 #include <net/checksum.h>
 #include <net/ipv6.h>
 
-#include <asm/byteorder.h>
-
 #include <linux/netfilter_ipv6/ip6_tables.h>
 #include <linux/netfilter_ipv6/ip6t_frag.h>
 
@@ -22,28 +20,7 @@
 #define DEBUGP(format, args...)
 #endif
 
-#if 0
-#if     BYTE_ORDER == BIG_ENDIAN
-#define IP6F_OFF_MASK       0xfff8  /* mask out offset from _offlg */
-#define IP6F_RESERVED_MASK  0x0006  /* reserved bits in ip6f_offlg */
-#define IP6F_MORE_FRAG      0x0001  /* more-fragments flag */
-#else   /* BYTE_ORDER == LITTLE_ENDIAN */
-#define IP6F_OFF_MASK       0xf8ff  /* mask out offset from _offlg */
-#define IP6F_RESERVED_MASK  0x0600  /* reserved bits in ip6f_offlg */
-#define IP6F_MORE_FRAG      0x0100  /* more-fragments flag */
-#endif
-#endif
-
-#define IP6F_OFF_MASK       0xf8ff  /* mask out offset from _offlg */
-#define IP6F_RESERVED_MASK  0x0600  /* reserved bits in ip6f_offlg */
-#define IP6F_MORE_FRAG      0x0100  /* more-fragments flag */
-
-struct fraghdr {
-       __u8    nexthdr;
-       __u8    hdrlen;
-       __u16   info;
-       __u32   id;
-};
+#define IP6_MF 0x0001
 
 /* Returns 1 if the id is matched by the range, 0 otherwise */
 static inline int
@@ -67,7 +44,7 @@
       u_int16_t datalen,
       int *hotdrop)
 {
-       struct fraghdr *frag = NULL;
+       struct frag_hdr *frag = NULL;
        const struct ip6t_frag *fraginfo = matchinfo;
        unsigned int temp;
        int len;
@@ -100,7 +77,7 @@
                      break;
               }
 
-              hdr=(struct ipv6_opt_hdr *)skb->data+ptr;
+              hdr=(struct ipv6_opt_hdr *)(skb->data+ptr);
 
               /* Calculate the header length */
                 if (nexthdr == NEXTHDR_FRAGMENT) {
@@ -143,59 +120,62 @@
        /* FRAG header not found */
        if ( temp != MASK_FRAGMENT ) return 0;
 
-       if (len < (int)sizeof(struct fraghdr)){
+       if (len < sizeof(struct frag_hdr)){
               *hotdrop = 1;
                        return 0;
        }
 
-       frag = (struct fraghdr *) (skb->data + ptr);
+       frag = (struct frag_hdr *) (skb->data + ptr);
 
-       DEBUGP("IPv6 FRAG LEN %u %u ", hdrlen, frag->hdrlen);
-       DEBUGP("INFO %04X ", frag->info);
-       DEBUGP("OFFSET %04X ", frag->info & IP6F_OFF_MASK);
-       DEBUGP("RES %04X ", frag->info & IP6F_RESERVED_MASK);
-       DEBUGP("MF %04X ", frag->info & IP6F_MORE_FRAG);
-       DEBUGP("ID %u %08X\n", ntohl(frag->id), ntohl(frag->id));
+       DEBUGP("INFO %04X ", frag->frag_off);
+       DEBUGP("OFFSET %04X ", ntohs(frag->frag_off) & ~0x7);
+       DEBUGP("RES %02X %04X", frag->reserved, ntohs(frag->frag_off) & 0x6);
+       DEBUGP("MF %04X ", frag->frag_off & htons(IP6_MF));
+       DEBUGP("ID %u %08X\n", ntohl(frag->identification),
+             ntohl(frag->identification));
 
        DEBUGP("IPv6 FRAG id %02X ",
                        (id_match(fraginfo->ids[0], fraginfo->ids[1],
-                           ntohl(frag->id),
+                           ntohl(frag->identification),
                            !!(fraginfo->invflags & IP6T_FRAG_INV_IDS))));
-       DEBUGP("len %02X %04X %02X ",
-                       fraginfo->hdrlen, hdrlen,
-                       (!fraginfo->hdrlen ||
-                           (fraginfo->hdrlen == hdrlen) ^
-                           !!(fraginfo->invflags & IP6T_FRAG_INV_LEN)));
-       DEBUGP("res %02X %02X %02X ", 
-                       (fraginfo->flags & IP6T_FRAG_RES), frag->info & 
IP6F_RESERVED_MASK,
-                       !((fraginfo->flags & IP6T_FRAG_RES) && (frag->info & 
IP6F_RESERVED_MASK)));
+       DEBUGP("res %02X %02X%04X %02X ", 
+                       (fraginfo->flags & IP6T_FRAG_RES), frag->reserved,
+               ntohs(frag->frag_off) & 0x6,
+                       !((fraginfo->flags & IP6T_FRAG_RES)
+                       && (frag->reserved || (ntohs(frag->frag_off) & 0x6))));
        DEBUGP("first %02X %02X %02X ", 
-                       (fraginfo->flags & IP6T_FRAG_FST), frag->info & 
IP6F_OFF_MASK,
-                       !((fraginfo->flags & IP6T_FRAG_FST) && (frag->info & 
IP6F_OFF_MASK)));
+                       (fraginfo->flags & IP6T_FRAG_FST),
+               ntohs(frag->frag_off) & ~0x7,
+                       !((fraginfo->flags & IP6T_FRAG_FST)
+                       && (ntohs(frag->frag_off) & ~0x7)));
        DEBUGP("mf %02X %02X %02X ", 
-                       (fraginfo->flags & IP6T_FRAG_MF), frag->info & 
IP6F_MORE_FRAG,
-                       !((fraginfo->flags & IP6T_FRAG_MF) && !((frag->info & 
IP6F_MORE_FRAG))));
+                       (fraginfo->flags & IP6T_FRAG_MF),
+               ntohs(frag->frag_off) & IP6_MF,
+                       !((fraginfo->flags & IP6T_FRAG_MF)
+                       && !((ntohs(frag->frag_off) & IP6_MF))));
        DEBUGP("last %02X %02X %02X\n", 
-                       (fraginfo->flags & IP6T_FRAG_NMF), frag->info & 
IP6F_MORE_FRAG,
-                       !((fraginfo->flags & IP6T_FRAG_NMF) && (frag->info & 
IP6F_MORE_FRAG)));
+                       (fraginfo->flags & IP6T_FRAG_NMF),
+               ntohs(frag->frag_off) & IP6_MF,
+                       !((fraginfo->flags & IP6T_FRAG_NMF)
+                       && (ntohs(frag->frag_off) & IP6_MF)));
 
        return (frag != NULL)
                        &&
                        (id_match(fraginfo->ids[0], fraginfo->ids[1],
-                           ntohl(frag->id),
+                         ntohl(frag->identification),
                            !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)))
                &&
-               (!fraginfo->hdrlen ||
-                           (fraginfo->hdrlen == hdrlen) ^
-                           !!(fraginfo->invflags & IP6T_FRAG_INV_LEN))
-               &&
-               !((fraginfo->flags & IP6T_FRAG_RES) && (frag->info & 
IP6F_RESERVED_MASK))
+               !((fraginfo->flags & IP6T_FRAG_RES)
+                       && (frag->reserved || (ntohs(frag->frag_off) & 0x6)))
                &&
-               !((fraginfo->flags & IP6T_FRAG_FST) && (frag->info & 
IP6F_OFF_MASK))
+               !((fraginfo->flags & IP6T_FRAG_FST)
+                       && (ntohs(frag->frag_off) & ~0x7))
                &&
-               !((fraginfo->flags & IP6T_FRAG_MF) && !((frag->info & 
IP6F_MORE_FRAG)))
+               !((fraginfo->flags & IP6T_FRAG_MF)
+                       && !(ntohs(frag->frag_off) & IP6_MF))
                &&
-               !((fraginfo->flags & IP6T_FRAG_NMF) && (frag->info & 
IP6F_MORE_FRAG));
+               !((fraginfo->flags & IP6T_FRAG_NMF)
+                       && (ntohs(frag->frag_off) & IP6_MF));
 }
 
 /* Called when user tries to insert an entry of this type. */
diff -urN linux/net/ipv6/netfilter/ip6t_hbh.c 
linux/net/ipv6/netfilter/ip6t_hbh.c
--- linux/net/ipv6/netfilter/ip6t_hbh.c 2003/07/05 03:23:48     1.3.2.1
+++ linux/net/ipv6/netfilter/ip6t_hbh.c 2005/01/20 02:19:25     1.3.2.2
@@ -11,8 +11,6 @@
 #include <linux/netfilter_ipv6/ip6_tables.h>
 #include <linux/netfilter_ipv6/ip6t_opts.h>
 
-#define LOW(n)         (n & 0x00FF)
-
 #define HOPBYHOP       1
 
 EXPORT_NO_SYMBOLS;
@@ -40,8 +38,8 @@
  *     0       -> invariant
  *     1       -> can change the routing
  *  (Type & 0x1F) Type
- *      0      -> PAD0 (only 1 byte!)
- *      1      -> PAD1 LENGTH info (total length = length + 2)
+ *      0      -> Pad1 (only 1 byte!)
+ *      1      -> PadN LENGTH info (total length = length + 2)
  *      C0 | 2 -> JUMBO 4 x x x x ( xxxx > 64k )
  *      5      -> RTALERT 2 x x
  */
@@ -64,7 +62,8 @@
        unsigned int ptr;
        unsigned int hdrlen = 0;
        unsigned int ret = 0;
-       u_int16_t *optdesc = NULL;
+       u8 *opttype = NULL;
+       unsigned int optlen;
        
        /* type of the 1st exthdr */
        nexthdr = skb->nh.ipv6h->nexthdr;
@@ -91,7 +90,7 @@
                      break;
               }
 
-              hdr=(void *)(skb->data)+ptr;
+             hdr = (void *)(skb->data + ptr);
 
               /* Calculate the header length */
                 if (nexthdr == NEXTHDR_FRAGMENT) {
@@ -153,7 +152,7 @@
                        return 0;
        }
 
-       optsh=(void *)(skb->data)+ptr;
+       optsh = (void *)(skb->data + ptr);
 
        DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, optsh->hdrlen);
 
@@ -169,7 +168,6 @@
                            ((optinfo->hdrlen == hdrlen) ^
                            !!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
 
-       temp = len = 0;
        ptr += 2;
        hdrlen -= 2;
        if ( !(optinfo->flags & IP6T_OPTS_OPTS) ){
@@ -180,48 +178,52 @@
                DEBUGP("Strict ");
                DEBUGP("#%d ",optinfo->optsnr);
                for(temp=0; temp<optinfo->optsnr; temp++){
-                       optdesc = (void *)(skb->data)+ptr;
+                       /* type field exists ? */
+                       if (ptr > skb->len - 1 || hdrlen < 1)
+                               break;
+                       opttype = (void *)(skb->data + ptr);
+
                        /* Type check */
-                       if ( (unsigned char)*optdesc != 
-                               (optinfo->opts[temp] & 0xFF00)>>8 ){
+                       if (*opttype != (optinfo->opts[temp] & 0xFF00)>>8){
                                DEBUGP("Tbad %02X %02X\n",
-                                               (unsigned char)*optdesc,
-                                               (optinfo->opts[temp] &
-                                                0xFF00)>>8);
+                                      *opttype,
+                                      (optinfo->opts[temp] & 0xFF00)>>8);
                                return 0;
                        } else {
                                DEBUGP("Tok ");
                        }
                        /* Length check */
-                       if (((optinfo->opts[temp] & 0x00FF) != 0xFF) &&
-                               (unsigned char)*optdesc != 0){
-                               if ( ntohs((u16)*optdesc) != 
-                                               optinfo->opts[temp] ){
-                                       DEBUGP("Lbad %02X %04X %04X\n",
-                                                       (unsigned char)*optdesc,
-                                                       ntohs((u16)*optdesc),
-                                                       optinfo->opts[temp]);
+                       if (*opttype) {
+                               u16 spec_len;
+
+                               /* length field exists ? */
+                               if (ptr > skb->len - 2 || hdrlen < 2)
+                                       break;
+                               optlen = *((u8 *)(skb->data + ptr + 1));
+                               spec_len = optinfo->opts[temp] & 0x00FF;
+
+                               if (spec_len != 0x00FF && spec_len != optlen) {
+                                       DEBUGP("Lbad %02X %04X\n", optlen,
+                                              spec_len);
                                        return 0;
-                               } else {
-                                       DEBUGP("Lok ");
                                }
-                       }
-                       /* Step to the next */
-                       if ((unsigned char)*optdesc == 0){
-                               DEBUGP("PAD0 \n");
-                               ptr++;
-                               hdrlen--;
+                               DEBUGP("Lok ");
+                               optlen += 2;
                        } else {
-                               ptr += LOW(ntohs(*optdesc));
-                               hdrlen -= LOW(ntohs(*optdesc));
-                               DEBUGP("len%04X \n", 
-                                       LOW(ntohs(*optdesc)));
+                               DEBUGP("Pad1\n");
+                               optlen = 1;
                        }
-                       if (ptr > skb->len || ( !hdrlen && 
-                               (temp != optinfo->optsnr - 1))) {
+
+                       /* Step to the next */
+                       DEBUGP("len%04X \n", optlen);
+
+                       if ((ptr > skb->len - optlen || hdrlen < optlen) &&
+                           (temp < optinfo->optsnr - 1)) {
                                DEBUGP("new pointer is too large! \n");
                                break;
                        }
+                       ptr += optlen;
+                       hdrlen -= optlen;
                }
                if (temp == optinfo->optsnr)
                        return ret;
diff -urN linux/net/ipv6/netfilter/ip6t_ipv6header.c 
linux/net/ipv6/netfilter/ip6t_ipv6header.c
--- linux/net/ipv6/netfilter/ip6t_ipv6header.c  2003/11/17 01:07:48     1.4.2.3
+++ linux/net/ipv6/netfilter/ip6t_ipv6header.c  2005/01/20 02:19:25     1.4.2.4
@@ -63,7 +63,7 @@
                        break;
                }
 
-               hdr=(struct ipv6_opt_hdr *)skb->data+ptr;
+               hdr=(struct ipv6_opt_hdr *)(skb->data+ptr);
 
                /* Calculate the header length */
                 if (nexthdr == NEXTHDR_FRAGMENT) {
@@ -107,10 +107,14 @@
                temp |= MASK_PROTO;
 
        if (info->modeflag)
-               return (!( (temp & info->matchflags)
-                       ^ info->matchflags) ^ info->invflags);
-       else
-               return (!( temp ^ info->matchflags) ^ info->invflags);
+               return !((temp ^ info->matchflags ^ info->invflags)
+                        & info->matchflags);
+       else {
+               if (info->invflags)
+                       return temp != info->matchflags;
+               else
+                       return temp == info->matchflags;
+       }
 }
 
 static int
@@ -120,11 +124,17 @@
                      unsigned int matchsize,
                      unsigned int hook_mask)
 {
+       const struct ip6t_ipv6header_info *info = matchinfo;
+
        /* Check for obvious errors */
        /* This match is valid in all hooks! */
-       if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_ipv6header_info))) {
+       if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_ipv6header_info)))
+               return 0;
+
+       /* invflags is 0 or 0xff in hard mode */
+       if ((!info->modeflag) && info->invflags != 0x00
+                             && info->invflags != 0xFF)
                return 0;
-       }
 
        return 1;
 }
diff -urN linux/net/ipv6/netfilter/ip6t_multiport.c 
linux/net/ipv6/netfilter/ip6t_multiport.c
--- linux/net/ipv6/netfilter/ip6t_multiport.c   2001/11/06 07:56:17     1.2
+++ linux/net/ipv6/netfilter/ip6t_multiport.c   2005/01/20 02:19:25     1.2.2.1
@@ -74,9 +74,12 @@
 {
        const struct ip6t_multiport *multiinfo = matchinfo;
 
+       if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_multiport)))
+               return 0;
+
        /* Must specify proto == TCP/UDP, no unknown flags or bad count */
        return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
-               && !(ip->flags & IP6T_INV_PROTO)
+               && !(ip->invflags & IP6T_INV_PROTO)
                && matchsize == IP6T_ALIGN(sizeof(struct ip6t_multiport))
                && (multiinfo->flags == IP6T_MULTIPORT_SOURCE
                    || multiinfo->flags == IP6T_MULTIPORT_DESTINATION
diff -urN linux/net/ipv6/netfilter/ip6t_rt.c linux/net/ipv6/netfilter/ip6t_rt.c
--- linux/net/ipv6/netfilter/ip6t_rt.c  2003/08/13 17:19:31     1.4.2.2
+++ linux/net/ipv6/netfilter/ip6t_rt.c  2005/01/20 02:19:25     1.4.2.3
@@ -78,7 +78,7 @@
                      break;
               }
 
-              hdr=(struct ipv6_opt_hdr *)skb->data+ptr;
+              hdr=(struct ipv6_opt_hdr *)(skb->data+ptr);
 
               /* Calculate the header length */
                 if (nexthdr == NEXTHDR_FRAGMENT) {
@@ -135,11 +135,11 @@
 
        DEBUGP("IPv6 RT LEN %u %u ", hdrlen, route->hdrlen);
        DEBUGP("TYPE %04X ", route->type);
-       DEBUGP("SGS_LEFT %u %08X\n", ntohl(route->segments_left), 
ntohl(route->segments_left));
+       DEBUGP("SGS_LEFT %u %02X\n", route->segments_left, 
route->segments_left);
 
        DEBUGP("IPv6 RT segsleft %02X ",
                        (segsleft_match(rtinfo->segsleft[0], 
rtinfo->segsleft[1],
-                           ntohl(route->segments_left),
+                           route->segments_left,
                            !!(rtinfo->invflags & IP6T_RT_INV_SGS))));
        DEBUGP("type %02X %02X %02X ",
                        rtinfo->rt_type, route->type, 
@@ -158,7 +158,7 @@
        ret = (route != NULL)
                        &&
                        (segsleft_match(rtinfo->segsleft[0], 
rtinfo->segsleft[1],
-                           ntohl(route->segments_left),
+                           route->segments_left,
                            !!(rtinfo->invflags & IP6T_RT_INV_SGS)))
                &&
                (!(rtinfo->flags & IP6T_RT_LEN) ||
diff -urN linux/net/sched/sch_dsmark.c linux/net/sched/sch_dsmark.c
--- linux/net/sched/sch_dsmark.c        2004/11/19 00:29:09     1.7.2.6
+++ linux/net/sched/sch_dsmark.c        2005/01/20 02:19:26     1.7.2.7
@@ -13,6 +13,7 @@
 #include <linux/rtnetlink.h>
 #include <net/pkt_sched.h>
 #include <net/dsfield.h>
+#include <net/inet_ecn.h>
 #include <asm/byteorder.h>
 
 
@@ -196,10 +197,12 @@
        if (p->set_tc_index) {
                switch (skb->protocol) {
                        case __constant_htons(ETH_P_IP):
-                               skb->tc_index = ipv4_get_dsfield(skb->nh.iph);
+                               skb->tc_index = ipv4_get_dsfield(skb->nh.iph)
+                                       & ~INET_ECN_MASK;
                                break;
                        case __constant_htons(ETH_P_IPV6):
-                               skb->tc_index = ipv6_get_dsfield(skb->nh.ipv6h);
+                               skb->tc_index = ipv6_get_dsfield(skb->nh.ipv6h)
+                                       & ~INET_ECN_MASK;
                                break;
                        default:
                                skb->tc_index = 0;
diff -urN linux/net/sctp/associola.c linux/net/sctp/associola.c
--- linux/net/sctp/associola.c  2004/11/19 00:29:09     1.19.2.5
+++ linux/net/sctp/associola.c  2005/01/20 02:19:26     1.19.2.6
@@ -66,33 +66,8 @@
 
 /* 1st Level Abstractions. */
 
-/* Allocate and initialize a new association */
-struct sctp_association *sctp_association_new(const struct sctp_endpoint *ep,
-                                        const struct sock *sk,
-                                        sctp_scope_t scope, int gfp)
-{
-       struct sctp_association *asoc;
-
-       asoc = t_new(struct sctp_association, gfp);
-       if (!asoc)
-               goto fail;
-
-       if (!sctp_association_init(asoc, ep, sk, scope, gfp))
-               goto fail_init;
-
-       asoc->base.malloced = 1;
-       SCTP_DBG_OBJCNT_INC(assoc);
-
-       return asoc;
-
-fail_init:
-       kfree(asoc);
-fail:
-       return NULL;
-}
-
 /* Initialize a new association from provided memory. */
-struct sctp_association *sctp_association_init(struct sctp_association *asoc,
+static struct sctp_association *sctp_association_init(struct sctp_association 
*asoc,
                                          const struct sctp_endpoint *ep,
                                          const struct sock *sk,
                                          sctp_scope_t scope,
@@ -182,10 +157,10 @@
         * RFC 6 - A SCTP receiver MUST be able to receive a minimum of
         * 1500 bytes in one SCTP packet.
         */
-       if (sk->sk_rcvbuf < SCTP_DEFAULT_MINWINDOW)
+       if (sk->rcvbuf < SCTP_DEFAULT_MINWINDOW)
                asoc->rwnd = SCTP_DEFAULT_MINWINDOW;
        else
-               asoc->rwnd = sk->sk_rcvbuf;
+               asoc->rwnd = sk->rcvbuf;
 
        asoc->a_rwnd = asoc->rwnd;
 
@@ -204,6 +179,7 @@
        asoc->c.peer_vtag = 0;
        asoc->c.my_ttag   = 0;
        asoc->c.peer_ttag = 0;
+       asoc->c.my_port = ep->base.bind_addr.port;
 
        asoc->c.initial_tsn = sctp_generate_tsn(ep);
 
@@ -296,6 +272,31 @@
        return NULL;
 }
 
+/* Allocate and initialize a new association */
+struct sctp_association *sctp_association_new(const struct sctp_endpoint *ep,
+                                        const struct sock *sk,
+                                        sctp_scope_t scope, int gfp)
+{
+       struct sctp_association *asoc;
+
+       asoc = t_new(struct sctp_association, gfp);
+       if (!asoc)
+               goto fail;
+
+       if (!sctp_association_init(asoc, ep, sk, scope, gfp))
+               goto fail_init;
+
+       asoc->base.malloced = 1;
+       SCTP_DBG_OBJCNT_INC(assoc);
+
+       return asoc;
+
+fail_init:
+       kfree(asoc);
+fail:
+       return NULL;
+}
+
 /* Free this association if possible.  There may still be users, so
  * the actual deallocation may be delayed.
  */
@@ -310,7 +311,7 @@
 
        /* Decrement the backlog value for a TCP-style listening socket. */
        if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))
-               sk->sk_ack_backlog--;
+               sk->ack_backlog--;
 
        /* Mark as dead, so other users can know this structure is
         * going away.
@@ -496,7 +497,6 @@
 
        peer->partial_bytes_acked = 0;
        peer->flight_size = 0;
-       peer->error_threshold = peer->max_retrans;
 
        /* By default, enable heartbeat for peer address. */
        peer->hb_allowed = 1;
@@ -507,7 +507,7 @@
        peer->hb_interval = 
SCTP_MSECS_TO_JIFFIES(sp->paddrparam.spp_hbinterval);
 
        /* Set the path max_retrans.  */
-       peer->max_retrans = asoc->max_retrans;
+       peer->max_retrans = sp->paddrparam.spp_pathmaxrxt;
 
        /* Set the transport's RTO.initial value */
        peer->rto = asoc->rto_initial;
@@ -710,18 +710,6 @@
        return retval;
 }
 
-/* Allocate 'num' TSNs by incrementing the association's TSN by num. */
-__u32 sctp_association_get_tsn_block(struct sctp_association *asoc, int num)
-{
-       __u32 retval = asoc->next_tsn;
-
-       asoc->next_tsn += num;
-       asoc->unack_data += num;
-
-       return retval;
-}
-
-
 /* Compare two addresses to see if they match.  Wildcard addresses
  * only match themselves.
  */
@@ -756,14 +744,6 @@
        return chunk;
 }
 
-/* Use this function for the packet prepend callback when no ECNE
- * packet is desired (e.g. some packets don't like to be bundled).
- */
-struct sctp_chunk *sctp_get_no_prepend(struct sctp_association *asoc)
-{
-       return NULL;
-}
-
 /*
  * Find which transport this TSN was sent on.
  */
@@ -877,7 +857,8 @@
        struct sctp_chunk *chunk;
        struct sock *sk;
        struct sctp_inq *inqueue;
-       int state, subtype;
+       int state;
+       sctp_subtype_t subtype;
        int error = 0;
 
        /* The association should be held so we should be safe. */
@@ -887,7 +868,7 @@
        inqueue = &asoc->base.inqueue;
        while (NULL != (chunk = sctp_inq_pop(inqueue))) {
                state = asoc->state;
-               subtype = chunk->chunk_hdr->type;
+               subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
 
                /* Remember where the last DATA chunk came from so we
                 * know where to send the SACK.
@@ -901,7 +882,7 @@
                        chunk->transport->last_time_heard = jiffies;
 
                /* Run through the state machine. */
-               error = sctp_do_sm(SCTP_EVENT_T_CHUNK, SCTP_ST_CHUNK(subtype),
+               error = sctp_do_sm(SCTP_EVENT_T_CHUNK, subtype,
                                   state, ep, asoc, chunk, GFP_ATOMIC);
 
                /* Check to see if the association is freed in response to
@@ -930,7 +911,7 @@
 
        /* Decrement the backlog value for a TCP-style socket. */
        if (sctp_style(oldsk, TCP))
-               oldsk->sk_ack_backlog--;
+               oldsk->ack_backlog--;
 
        /* Release references to the old endpoint and the sock.  */
        sctp_endpoint_put(assoc->ep);
@@ -1112,7 +1093,7 @@
        case SCTP_STATE_SHUTDOWN_SENT:
                if ((asoc->rwnd > asoc->a_rwnd) &&
                    ((asoc->rwnd - asoc->a_rwnd) >=
-                    min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pmtu)))
+                    min_t(__u32, (asoc->base.sk->rcvbuf >> 1), asoc->pmtu)))
                        return 1;
                break;
        default:
@@ -1195,7 +1176,7 @@
         * the endpoint.
         */
        scope = sctp_scope(&asoc->peer.active_path->ipaddr);
-       flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0;
+       flags = (PF_INET6 == asoc->base.sk->family) ? SCTP_ADDR6_ALLOWED : 0;
        if (asoc->peer.ipv4_address)
                flags |= SCTP_ADDR4_PEERSUPP;
        if (asoc->peer.ipv6_address)
diff -urN linux/net/sctp/bind_addr.c linux/net/sctp/bind_addr.c
--- linux/net/sctp/bind_addr.c  2004/04/16 03:14:22     1.13.2.2
+++ linux/net/sctp/bind_addr.c  2005/01/20 02:19:26     1.13.2.3
@@ -104,23 +104,6 @@
        return error;
 }
 
-/* Create a new SCTP_bind_addr from nothing.  */
-struct sctp_bind_addr *sctp_bind_addr_new(int gfp)
-{
-       struct sctp_bind_addr *retval;
-
-       retval = t_new(struct sctp_bind_addr, gfp);
-       if (!retval)
-               goto nomem;
-
-       sctp_bind_addr_init(retval, 0);
-       retval->malloced = 1;
-       SCTP_DBG_OBJCNT_INC(bind_addr);
-
-nomem:
-       return retval;
-}
-
 /* Initialize the SCTP_bind_addr structure for either an endpoint or
  * an association.
  */
diff -urN linux/net/sctp/chunk.c linux/net/sctp/chunk.c
--- linux/net/sctp/chunk.c      2004/08/14 18:39:05     1.2.2.2
+++ linux/net/sctp/chunk.c      2005/01/20 02:19:26     1.2.2.3
@@ -51,7 +51,7 @@
  */
 
 /* Initialize datamsg from memory. */
-void sctp_datamsg_init(struct sctp_datamsg *msg)
+static void sctp_datamsg_init(struct sctp_datamsg *msg)
 {
        atomic_set(&msg->refcnt, 1);
        msg->send_failed = 0;
@@ -62,7 +62,7 @@
 }
 
 /* Allocate and initialize datamsg. */
-struct sctp_datamsg *sctp_datamsg_new(int gfp)
+SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(int gfp)
 {
        struct sctp_datamsg *msg;
        msg = kmalloc(sizeof(struct sctp_datamsg), gfp);
@@ -124,7 +124,7 @@
 }
 
 /* Hold a reference. */
-void sctp_datamsg_hold(struct sctp_datamsg *msg)
+static void sctp_datamsg_hold(struct sctp_datamsg *msg)
 {
        atomic_inc(&msg->refcnt);
 }
@@ -151,7 +151,7 @@
 }
 
 /* Assign a chunk to this datamsg. */
-void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chunk)
+static void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk 
*chunk)
 {
        sctp_datamsg_hold(msg);
        chunk->msg = msg;
diff -urN linux/net/sctp/command.c linux/net/sctp/command.c
--- linux/net/sctp/command.c    2003/11/17 01:07:48     1.4.2.1
+++ linux/net/sctp/command.c    2005/01/20 02:19:26     1.4.2.2
@@ -42,17 +42,6 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
-/* Create a new sctp_command_sequence.  */
-sctp_cmd_seq_t *sctp_new_cmd_seq(int gfp)
-{
-       sctp_cmd_seq_t *retval = t_new(sctp_cmd_seq_t, gfp);
-
-       if (retval)
-               sctp_init_cmd_seq(retval);
-
-       return retval;
-}
-
 /* Initialize a block of memory as a command sequence. */
 int sctp_init_cmd_seq(sctp_cmd_seq_t *seq)
 {
@@ -77,13 +66,6 @@
        return 0;
 }
 
-/* Rewind an sctp_cmd_seq_t to iterate from the start.  */
-int sctp_rewind_sequence(sctp_cmd_seq_t *seq)
-{
-       seq->next_cmd = 0;
-       return 1;               /* We always succeed. */
-}
-
 /* Return the next command structure in a sctp_cmd_seq.
  * Returns NULL at the end of the sequence.
  */
@@ -97,8 +79,3 @@
        return retval;
 }
 
-/* Dispose of a command sequence.  */
-void sctp_free_cmd_seq(sctp_cmd_seq_t *seq)
-{
-       kfree(seq);
-}
diff -urN linux/net/sctp/debug.c linux/net/sctp/debug.c
--- linux/net/sctp/debug.c      2004/08/14 18:39:05     1.5.2.3
+++ linux/net/sctp/debug.c      2005/01/20 02:19:26     1.5.2.4
@@ -98,23 +98,6 @@
        return "unknown chunk";
 }
 
-/* These are printable form of variable-length parameters. */
-const char *sctp_param_tbl[SCTP_PARAM_ECN_CAPABLE + 1] = {
-       "",
-       "PARAM_HEARTBEAT_INFO",
-       "",
-       "",
-       "",
-       "PARAM_IPV4_ADDRESS",
-       "PARAM_IPV6_ADDRESS",
-       "PARAM_STATE_COOKIE",
-       "PARAM_UNRECOGNIZED_PARAMETERS",
-       "PARAM_COOKIE_PRESERVATIVE",
-       "",
-       "PARAM_HOST_NAME_ADDRESS",
-       "PARAM_SUPPORTED_ADDRESS_TYPES",
-};
-
 /* These are printable forms of the states.  */
 const char *sctp_state_tbl[SCTP_STATE_NUM_STATES] = {
        "STATE_EMPTY",
@@ -171,6 +154,7 @@
 
 static const char *sctp_other_tbl[] = {
        "NO_PENDING_TSN",
+        "ICMP_PROTO_UNREACH",
 };
 
 /* Lookup "other" debug name. */
@@ -178,7 +162,7 @@
 {
        if (id.other < 0)
                return "illegal 'other' event";
-       if (id.other < SCTP_EVENT_OTHER_MAX)
+       if (id.other <= SCTP_EVENT_OTHER_MAX)
                return sctp_other_tbl[id.other];
        return "unknown 'other' event";
 }
diff -urN linux/net/sctp/endpointola.c linux/net/sctp/endpointola.c
--- linux/net/sctp/endpointola.c        2004/04/16 03:14:22     1.14.2.2
+++ linux/net/sctp/endpointola.c        2005/01/20 02:19:26     1.14.2.3
@@ -63,34 +63,11 @@
 /* Forward declarations for internal helpers. */
 static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep);
 
-/* Create a sctp_endpoint with all that boring stuff initialized.
- * Returns NULL if there isn't enough memory.
- */
-struct sctp_endpoint *sctp_endpoint_new(struct sock *sk, int gfp)
-{
-       struct sctp_endpoint *ep;
-
-       /* Build a local endpoint. */
-       ep = t_new(struct sctp_endpoint, gfp);
-       if (!ep)
-               goto fail;
-       if (!sctp_endpoint_init(ep, sk, gfp))
-               goto fail_init;
-       ep->base.malloced = 1;
-       SCTP_DBG_OBJCNT_INC(ep);
-       return ep;
-
-fail_init:
-       kfree(ep);
-fail:
-       return NULL;
-}
-
 /*
  * Initialize the base fields of the endpoint structure.
  */
-struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
-                                        struct sock *sk, int gfp)
+static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
+                                               struct sock *sk, int gfp)
 {
        struct sctp_opt *sp = sctp_sk(sk);
        memset(ep, 0, sizeof(struct sctp_endpoint));
@@ -148,8 +125,8 @@
                sp->autoclose * HZ;
 
        /* Use SCTP specific send buffer space queues.  */
-       sk->sk_write_space = sctp_write_space;
-       sk->sk_use_write_queue = 1;
+       sk->write_space = sctp_write_space;
+       sk->use_write_queue = 1;
 
        /* Initialize the secret key used with cookie. */
        get_random_bytes(&ep->secret_key[0], SCTP_SECRET_SIZE);
@@ -160,6 +137,29 @@
        return ep;
 }
 
+/* Create a sctp_endpoint with all that boring stuff initialized.
+ * Returns NULL if there isn't enough memory.
+ */
+struct sctp_endpoint *sctp_endpoint_new(struct sock *sk, int gfp)
+{
+       struct sctp_endpoint *ep;
+
+       /* Build a local endpoint. */
+       ep = t_new(struct sctp_endpoint, gfp);
+       if (!ep)
+               goto fail;
+       if (!sctp_endpoint_init(ep, sk, gfp))
+               goto fail_init;
+       ep->base.malloced = 1;
+       SCTP_DBG_OBJCNT_INC(ep);
+       return ep;
+
+fail_init:
+       kfree(ep);
+fail:
+       return NULL;
+}
+
 /* Add an association to an endpoint.  */
 void sctp_endpoint_add_asoc(struct sctp_endpoint *ep,
                            struct sctp_association *asoc)
@@ -171,7 +171,7 @@
 
        /* Increment the backlog value for a TCP-style listening socket. */
        if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))
-               sk->sk_ack_backlog++;
+               sk->ack_backlog++;
 }
 
 /* Free the endpoint structure.  Delay cleanup until
@@ -184,11 +184,11 @@
 }
 
 /* Final destructor for endpoint.  */
-void sctp_endpoint_destroy(struct sctp_endpoint *ep)
+static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
 {
        SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return);
 
-       ep->base.sk->sk_state = SCTP_SS_CLOSED;
+       ep->base.sk->state = SCTP_SS_CLOSED;
 
        /* Unlink this endpoint, so we can't find it again! */
        sctp_unhash_endpoint(ep);
@@ -257,7 +257,7 @@
  * We do a linear search of the associations for this endpoint.
  * We return the matching transport address too.
  */
-struct sctp_association *__sctp_endpoint_lookup_assoc(
+static struct sctp_association *__sctp_endpoint_lookup_assoc(
        const struct sctp_endpoint *ep,
        const union sctp_addr *paddr,
        struct sctp_transport **transport)
@@ -345,7 +345,7 @@
        sk = ep->base.sk;
 
        while (NULL != (chunk = sctp_inq_pop(inqueue))) {
-               subtype.chunk = chunk->chunk_hdr->type;
+               subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
 
                /* We might have grown an association since last we
                 * looked, so try again.
diff -urN linux/net/sctp/input.c linux/net/sctp/input.c
--- linux/net/sctp/input.c      2004/04/16 03:14:22     1.17.2.2
+++ linux/net/sctp/input.c      2005/01/20 02:19:26     1.17.2.3
@@ -63,11 +63,15 @@
 
 /* Forward declarations for internal helpers. */
 static int sctp_rcv_ootb(struct sk_buff *);
-struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
+static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
                                      const union sctp_addr *laddr,
                                      const union sctp_addr *paddr,
                                      struct sctp_transport **transportp);
-struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr);
+static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr 
*laddr);
+static struct sctp_association *__sctp_lookup_association(
+                                       const union sctp_addr *local,
+                                       const union sctp_addr *peer,
+                                       struct sctp_transport **pt);
 
 
 /* Calculate the SCTP checksum of an SCTP packet.  */
@@ -130,6 +134,10 @@
 
        skb_pull(skb, sizeof(struct sctphdr));
 
+       /* Make sure we at least have chunk headers worth of data left. */
+       if (skb->len < sizeof(struct sctp_chunkhdr))
+               goto discard_it;
+
        family = ipver2af(skb->nh.iph->version);
        af = sctp_get_af_specific(family);
        if (unlikely(!af))
@@ -278,6 +286,31 @@
        }
 }
 
+/*
+ * SCTP Implementer's Guide, 2.37 ICMP handling procedures
+ *
+ * ICMP8) If the ICMP code is a "Unrecognized next header type encountered"
+ *        or a "Protocol Unreachable" treat this message as an abort
+ *        with the T bit set.
+ *
+ * This function sends an event to the state machine, which will abort the
+ * association.
+ *
+ */
+void sctp_icmp_proto_unreachable(struct sock *sk,
+                           struct sctp_endpoint *ep,
+                           struct sctp_association *asoc,
+                           struct sctp_transport *t)
+{
+       SCTP_DEBUG_PRINTK("%s\n",  __FUNCTION__);
+
+       sctp_do_sm(SCTP_EVENT_T_OTHER,
+                  SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
+                  asoc->state, asoc->ep, asoc, NULL,
+                  GFP_ATOMIC);
+
+}
+
 /* Common lookup code for icmp/icmpv6 error handler. */
 struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
                             struct sctphdr *sctphdr,
@@ -320,11 +353,12 @@
        }
 
        if (asoc) {
+               sk = asoc->base.sk;
+
                if (ntohl(sctphdr->vtag) != asoc->c.peer_vtag) {
                        ICMP_INC_STATS_BH(IcmpInErrors);
                        goto out;
                }
-               sk = asoc->base.sk;
        } else
                sk = ep->base.sk;
 
@@ -426,7 +460,13 @@
                        sctp_icmp_frag_needed(sk, asoc, transport, info);
                        goto out_unlock;
                }
-
+               else {
+                       if (ICMP_PROT_UNREACH == code) {
+                               sctp_icmp_proto_unreachable(sk, ep, asoc,
+                                                           transport);
+                               goto out_unlock;
+                       }
+               }
                err = icmp_err_convert[code].errno;
                break;
        case ICMP_TIME_EXCEEDED:
@@ -444,10 +484,10 @@
 
        inet = inet_sk(sk);
        if (!sock_owned_by_user(sk) && inet->recverr) {
-               sk->sk_err = err;
-               sk->sk_error_report(sk);
+               sk->err = err;
+               sk->error_report(sk);
        } else {  /* Only an error on timeout */
-               sk->sk_err_soft = err;
+               sk->err_soft = err;
        }
 
 out_unlock:
@@ -473,10 +513,10 @@
        sctp_errhdr_t *err;
 
        ch = (sctp_chunkhdr_t *) skb->data;
+       ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length));
 
        /* Scan through all the chunks in the packet.  */
-       do {
-               ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length));
+       while (ch_end > (__u8 *)ch && ch_end < skb->tail) {
 
                /* RFC 8.4, 2) If the OOTB packet contains an ABORT chunk, the
                 * receiver MUST silently discard the OOTB packet and take no
@@ -507,7 +547,8 @@
                }
 
                ch = (sctp_chunkhdr_t *) ch_end;
-       } while (ch_end < skb->tail);
+               ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length));
+       }
 
        return 0;
 
@@ -516,7 +557,7 @@
 }
 
 /* Insert endpoint into the hash table.  */
-void __sctp_hash_endpoint(struct sctp_endpoint *ep)
+static void __sctp_hash_endpoint(struct sctp_endpoint *ep)
 {
        struct sctp_ep_common **epp;
        struct sctp_ep_common *epb;
@@ -546,7 +587,7 @@
 }
 
 /* Remove endpoint from the hash table.  */
-void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
+static void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
 {
        struct sctp_hashbucket *head;
        struct sctp_ep_common *epb;
@@ -578,7 +619,7 @@
 }
 
 /* Look up an endpoint. */
-struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr)
+static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr 
*laddr)
 {
        struct sctp_hashbucket *head;
        struct sctp_ep_common *epb;
@@ -604,16 +645,8 @@
        return ep;
 }
 
-/* Add an association to the hash. Local BH-safe. */
-void sctp_hash_established(struct sctp_association *asoc)
-{
-       sctp_local_bh_disable();
-       __sctp_hash_established(asoc);
-       sctp_local_bh_enable();
-}
-
 /* Insert association into the hash table.  */
-void __sctp_hash_established(struct sctp_association *asoc)
+static void __sctp_hash_established(struct sctp_association *asoc)
 {
        struct sctp_ep_common **epp;
        struct sctp_ep_common *epb;
@@ -636,16 +669,16 @@
        sctp_write_unlock(&head->lock);
 }
 
-/* Remove association from the hash table.  Local BH-safe. */
-void sctp_unhash_established(struct sctp_association *asoc)
+/* Add an association to the hash. Local BH-safe. */
+void sctp_hash_established(struct sctp_association *asoc)
 {
        sctp_local_bh_disable();
-       __sctp_unhash_established(asoc);
+       __sctp_hash_established(asoc);
        sctp_local_bh_enable();
 }
 
 /* Remove association from the hash table.  */
-void __sctp_unhash_established(struct sctp_association *asoc)
+static void __sctp_unhash_established(struct sctp_association *asoc)
 {
        struct sctp_hashbucket *head;
        struct sctp_ep_common *epb;
@@ -669,8 +702,16 @@
        sctp_write_unlock(&head->lock);
 }
 
+/* Remove association from the hash table.  Local BH-safe. */
+void sctp_unhash_established(struct sctp_association *asoc)
+{
+       sctp_local_bh_disable();
+       __sctp_unhash_established(asoc);
+       sctp_local_bh_enable();
+}
+
 /* Look up an association. */
-struct sctp_association *__sctp_lookup_association(
+static struct sctp_association *__sctp_lookup_association(
                                        const union sctp_addr *local,
                                        const union sctp_addr *peer,
                                        struct sctp_transport **pt)
@@ -707,8 +748,9 @@
 }
 
 /* Look up an association. BH-safe. */
+SCTP_STATIC
 struct sctp_association *sctp_lookup_association(const union sctp_addr *laddr,
-                                           const union sctp_addr *paddr,
+                                                const union sctp_addr *paddr,
                                            struct sctp_transport **transportp)
 {
        struct sctp_association *asoc;
@@ -778,6 +820,14 @@
                return NULL;
        }
 
+       /* The code below will attempt to walk the chunk and extract
+        * parameter information.  Before we do that, we need to verify
+        * that the chunk length doesn't cause overflow.  Otherwise, we'll
+        * walk off the end.
+        */
+       if (WORD_ROUND(ntohs(ch->length)) > skb->len)
+               return NULL;
+
        /*
         * This code will NOT touch anything inside the chunk--it is
         * strictly READ-ONLY.
@@ -815,7 +865,7 @@
 }
 
 /* Lookup an association for an inbound skb. */
-struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
+static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
                                      const union sctp_addr *paddr,
                                      const union sctp_addr *laddr,
                                      struct sctp_transport **transportp)
diff -urN linux/net/sctp/inqueue.c linux/net/sctp/inqueue.c
--- linux/net/sctp/inqueue.c    2004/11/19 00:29:09     1.4.2.3
+++ linux/net/sctp/inqueue.c    2005/01/20 02:19:26     1.4.2.4
@@ -62,19 +62,6 @@
        queue->malloced = 0;
 }
 
-/* Create an initialized sctp_inq.  */
-struct sctp_inq *sctp_inq_new(void)
-{
-       struct sctp_inq *retval;
-
-       retval = t_new(struct sctp_inq, GFP_ATOMIC);
-       if (retval) {
-               sctp_inq_init(retval);
-               retval->malloced = 1;
-       }
-        return retval;
-}
-
 /* Release the memory associated with an SCTP inqueue.  */
 void sctp_inq_free(struct sctp_inq *queue)
 {
@@ -160,14 +147,36 @@
        }
 
         chunk->chunk_hdr = ch;
-        chunk->chunk_end = ((__u8 *) ch)
-               + WORD_ROUND(ntohs(ch->length));
+        chunk->chunk_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
+       /* In the unlikely case of an IP reassembly, the skb could be
+        * non-linear. If so, update chunk_end so that it doesn't go past
+        * the skb->tail.
+        */
+       if (unlikely(skb_is_nonlinear(chunk->skb))) {
+               if (chunk->chunk_end > chunk->skb->tail)
+                       chunk->chunk_end = chunk->skb->tail;
+       }
        skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t));
        chunk->subh.v = NULL; /* Subheader is no longer valid.  */
 
        if (chunk->chunk_end < chunk->skb->tail) {
                /* This is not a singleton */
                chunk->singleton = 0;
+       } else if (chunk->chunk_end > chunk->skb->tail) {
+                /* RFC 2960, Section 6.10  Bundling
+                *
+                * Partial chunks MUST NOT be placed in an SCTP packet.
+                * If the receiver detects a partial chunk, it MUST drop
+                * the chunk.  
+                *
+                * Since the end of the chunk is past the end of our buffer
+                * (which contains the whole packet, we can freely discard
+                * the whole packet.
+                */
+               sctp_chunk_free(chunk);
+               chunk = queue->in_progress = NULL;
+
+               return NULL;
        } else {
                /* We are at the end of the packet, so mark the chunk
                 * in case we need to send a SACK.
diff -urN linux/net/sctp/ipv6.c linux/net/sctp/ipv6.c
--- linux/net/sctp/ipv6.c       2004/11/19 00:29:09     1.19.2.4
+++ linux/net/sctp/ipv6.c       2005/01/20 02:19:26     1.19.2.5
@@ -95,8 +95,8 @@
        ntohs((addr)->s6_addr16[7])
 
 /* ICMP error handler. */
-void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
-                int type, int code, int offset, __u32 info)
+SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+                            int type, int code, int offset, __u32 info)
 {
        struct inet6_dev *idev;
        struct ipv6hdr *iph = (struct ipv6hdr *)skb->data;
@@ -133,6 +133,12 @@
        case ICMPV6_PKT_TOOBIG:
                sctp_icmp_frag_needed(sk, asoc, transport, ntohl(info));
                goto out_unlock;
+       case ICMPV6_PARAMPROB:
+               if (ICMPV6_UNK_NEXTHDR == code) {
+                       sctp_icmp_proto_unreachable(sk, ep, asoc, transport);
+                       goto out_unlock;
+               }
+               break;
        default:
                break;
        }
@@ -140,10 +146,10 @@
        np = inet6_sk(sk);
        icmpv6_err_convert(type, code, &err);
        if (!sock_owned_by_user(sk) && np->recverr) {
-               sk->sk_err = err;
-               sk->sk_error_report(sk);
+               sk->err = err;
+               sk->error_report(sk);
        } else {  /* Only an error on timeout */
-               sk->sk_err_soft = err;
+               sk->err_soft = err;
        }
 
 out_unlock:
@@ -163,7 +169,7 @@
 
        memset(&fl, 0, sizeof(fl));
 
-       fl.proto = sk->sk_protocol;
+       fl.proto = sk->protocol;
 
        /* Fill in the dest address from the route entry passed with the skb
         * and the source address from the transport.
@@ -176,7 +182,7 @@
        if (ipv6_addr_type(fl.fl6_src) & IPV6_ADDR_LINKLOCAL)
                fl.oif = transport->saddr.v6.sin6_scope_id;
        else
-               fl.oif = sk->sk_bound_dev_if;
+               fl.oif = sk->bound_dev_if;
        fl.uli_u.ports.sport = sk->sport;
        fl.uli_u.ports.dport = transport->ipaddr.v6.sin6_port;
 
@@ -199,9 +205,9 @@
 /* Returns the dst cache entry for the given source and destination ip
  * addresses.
  */
-struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
-                                 union sctp_addr *daddr,
-                                 union sctp_addr *saddr)
+static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
+                                        union sctp_addr *daddr,
+                                        union sctp_addr *saddr)
 {
        struct dst_entry *dst;
        struct flowi fl;
@@ -262,8 +268,10 @@
 /* Fills in the source address(saddr) based on the destination address(daddr)
  * and asoc's bind address list.
  */
-void sctp_v6_get_saddr(struct sctp_association *asoc, struct dst_entry *dst,
-                      union sctp_addr *daddr, union sctp_addr *saddr)
+static void sctp_v6_get_saddr(struct sctp_association *asoc,
+                             struct dst_entry *dst,
+                             union sctp_addr *daddr,
+                             union sctp_addr *saddr)
 {
        struct sctp_bind_addr *bp;
        rwlock_t *addr_lock;
@@ -588,8 +596,8 @@
 }
 
 /* Create and initialize a new sk for the socket to be returned by accept(). */
-struct sock *sctp_v6_create_accept_sk(struct sock *sk,
-                                     struct sctp_association *asoc)
+static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
+                                            struct sctp_association *asoc)
 {
        struct sock *newsk;
        struct inet_opt *newinet;
@@ -602,18 +610,18 @@
        sock_init_data(NULL, newsk);
        sk_set_owner(newsk, THIS_MODULE);
 
-       newsk->sk_type = SOCK_STREAM;
+       newsk->type = SOCK_STREAM;
 
-       newsk->sk_prot = sk->sk_prot;
-       newsk->sk_no_check = sk->sk_no_check;
-       newsk->sk_reuse = sk->sk_reuse;
-
-       newsk->sk_destruct = inet_sock_destruct;
-       newsk->sk_zapped = 0;
-       newsk->sk_family = PF_INET6;
-       newsk->sk_protocol = IPPROTO_SCTP;
-       newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
-       newsk->sk_shutdown = sk->sk_shutdown;
+       newsk->prot = sk->prot;
+       newsk->no_check = sk->no_check;
+       newsk->reuse = sk->reuse;
+
+       newsk->destruct = inet_sock_destruct;
+       newsk->zapped = 0;
+       newsk->family = PF_INET6;
+       newsk->protocol = IPPROTO_SCTP;
+       newsk->backlog_rcv = sk->prot->backlog_rcv;
+       newsk->shutdown = sk->shutdown;
 
        newinet = inet_sk(newsk);
        newnp = inet6_sk(newsk);
@@ -648,7 +656,7 @@
        atomic_inc(&inet_sock_nr);
 #endif
 
-       if (newsk->sk_prot->init(newsk)) {
+       if (newsk->prot->init(newsk)) {
                inet_sock_release(newsk);
                newsk = NULL;
        }
@@ -823,8 +831,8 @@
                         */
 
                        if (addr->v6.sin6_scope_id)
-                               sk->sk_bound_dev_if = addr->v6.sin6_scope_id;
-                       if (!sk->sk_bound_dev_if)
+                               sk->bound_dev_if = addr->v6.sin6_scope_id;
+                       if (!sk->bound_dev_if)
                                return 0;
                }
                af = opt->pf->af;
@@ -853,8 +861,8 @@
                         */
 
                        if (addr->v6.sin6_scope_id)
-                               sk->sk_bound_dev_if = addr->v6.sin6_scope_id;
-                       if (!sk->sk_bound_dev_if)
+                               sk->bound_dev_if = addr->v6.sin6_scope_id;
+                       if (!sk->bound_dev_if)
                                return 0;
                }
                af = opt->pf->af;
diff -urN linux/net/sctp/objcnt.c linux/net/sctp/objcnt.c
--- linux/net/sctp/objcnt.c     2004/08/14 18:39:05     1.4.2.3
+++ linux/net/sctp/objcnt.c     2005/01/20 02:19:26     1.4.2.4
@@ -61,7 +61,7 @@
 /* An array to make it easy to pretty print the debug information
  * to the proc fs.
  */
-sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
+static sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
        SCTP_DBG_OBJCNT_ENTRY(sock),
        SCTP_DBG_OBJCNT_ENTRY(ep),
        SCTP_DBG_OBJCNT_ENTRY(assoc),
diff -urN linux/net/sctp/output.c linux/net/sctp/output.c
--- linux/net/sctp/output.c     2004/11/19 00:29:09     1.13.2.4
+++ linux/net/sctp/output.c     2005/01/20 02:19:26     1.13.2.5
@@ -161,7 +161,7 @@
                if (!packet->has_cookie_echo) {
                        error = sctp_packet_transmit(packet);
                        if (error < 0)
-                               chunk->skb->sk->sk_err = -error;
+                               chunk->skb->sk->err = -error;
 
                        /* If we have an empty packet, then we can NOT ever
                         * return PMTU_FULL.
diff -urN linux/net/sctp/outqueue.c linux/net/sctp/outqueue.c
--- linux/net/sctp/outqueue.c   2004/11/19 00:29:09     1.15.2.5
+++ linux/net/sctp/outqueue.c   2005/01/20 02:19:26     1.15.2.6
@@ -200,19 +200,6 @@
        return 0;
 }
 
-/* Generate a new outqueue.  */
-struct sctp_outq *sctp_outq_new(struct sctp_association *asoc)
-{
-       struct sctp_outq *q;
-
-       q = t_new(struct sctp_outq, GFP_KERNEL);
-       if (q) {
-               sctp_outq_init(asoc, q);
-               q->malloced = 1;
-       }
-       return q;
-}
-
 /* Initialize an existing sctp_outq.  This does the boring stuff.
  * You still need to define handlers if you really want to DO
  * something with this structure...
@@ -372,7 +359,7 @@
 /* Insert a chunk into the sorted list based on the TSNs.  The retransmit list
  * and the abandoned list are in ascending order.
  */
-void sctp_insert_list(struct list_head *head, struct list_head *new)
+static void sctp_insert_list(struct list_head *head, struct list_head *new)
 {
        struct list_head *pos;
        struct sctp_chunk *nchunk, *lchunk;
@@ -510,7 +497,7 @@
        error = sctp_outq_flush(q, /* rtx_timeout */ 1);
 
        if (error)
-               q->asoc->base.sk->sk_err = -error;
+               q->asoc->base.sk->err = -error;
 }
 
 /*
diff -urN linux/net/sctp/proc.c linux/net/sctp/proc.c
--- linux/net/sctp/proc.c       2004/04/16 03:14:22     1.5.2.2
+++ linux/net/sctp/proc.c       2005/01/20 02:19:26     1.5.2.3
@@ -177,7 +177,7 @@
                        ep = sctp_ep(epb);
                        sk = epb->sk;
                        seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d ", ep, sk,
-                                  sctp_sk(sk)->type, sk->sk_state, hash,
+                                  sctp_sk(sk)->type, sk->state, hash,
                                   epb->bind_addr.port);
                        sctp_seq_dump_local_addrs(seq, epb);
                        seq_printf(seq, "\n");
@@ -240,7 +240,7 @@
                        sk = epb->sk;
                        seq_printf(seq,
                                   "%8p %8p %-3d %-3d %-2d %-4d %-5d %-5d ",
-                                  assoc, sk, sctp_sk(sk)->type, sk->sk_state,
+                                  assoc, sk, sctp_sk(sk)->type, sk->state,
                                   assoc->state, hash, epb->bind_addr.port,
                                   assoc->peer.port);
                        sctp_seq_dump_local_addrs(seq, epb);
diff -urN linux/net/sctp/protocol.c linux/net/sctp/protocol.c
--- linux/net/sctp/protocol.c   2004/11/19 00:29:09     1.22.2.4
+++ linux/net/sctp/protocol.c   2005/01/20 02:19:26     1.22.2.5
@@ -93,7 +93,7 @@
 }
 
 /* Set up the proc fs entry for the SCTP protocol. */
-__init int sctp_proc_init(void)
+static __init int sctp_proc_init(void)
 {
        if (!proc_net_sctp) {
                struct proc_dir_entry *ent;
@@ -122,7 +122,7 @@
  * Note: Do not make this __exit as it is used in the init error
  * path.
  */
-void sctp_proc_exit(void)
+static void sctp_proc_exit(void)
 {
        sctp_snmp_proc_exit();
        sctp_eps_proc_exit();
@@ -428,9 +428,9 @@
  * addresses. If an association is passed, trys to get a dst entry with a
  * source address that matches an address in the bind address list.
  */
-struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
-                                 union sctp_addr *daddr,
-                                 union sctp_addr *saddr)
+static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
+                                        union sctp_addr *daddr,
+                                        union sctp_addr *saddr)
 {
        struct rtable *rt;
        struct rt_key key;
@@ -520,10 +520,10 @@
 /* For v4, the source address is cached in the route entry(dst). So no need
  * to cache it separately and hence this is an empty routine.
  */
-void sctp_v4_get_saddr(struct sctp_association *asoc,
-                      struct dst_entry *dst,
-                      union sctp_addr *daddr,
-                      union sctp_addr *saddr)
+static void sctp_v4_get_saddr(struct sctp_association *asoc,
+                             struct dst_entry *dst,
+                             union sctp_addr *daddr,
+                             union sctp_addr *saddr)
 {
        struct rtable *rt = (struct rtable *)dst;
 
@@ -547,8 +547,8 @@
 }
 
 /* Create and initialize a new sk for the socket returned by accept(). */
-struct sock *sctp_v4_create_accept_sk(struct sock *sk,
-                                     struct sctp_association *asoc)
+static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
+                                            struct sctp_association *asoc)
 {
        struct sock *newsk;
        struct inet_opt *inet = inet_sk(sk);
@@ -561,18 +561,18 @@
        sock_init_data(NULL, newsk);
        sk_set_owner(newsk, THIS_MODULE);
 
-       newsk->sk_type = SOCK_STREAM;
+       newsk->type = SOCK_STREAM;
 
-       newsk->sk_prot = sk->sk_prot;
-       newsk->sk_no_check = sk->sk_no_check;
-       newsk->sk_reuse = sk->sk_reuse;
-       newsk->sk_shutdown = sk->sk_shutdown;
-
-       newsk->sk_destruct = inet_sock_destruct;
-       newsk->sk_zapped = 0;
-       newsk->sk_family = PF_INET;
-       newsk->sk_protocol = IPPROTO_SCTP;
-       newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
+       newsk->prot = sk->prot;
+       newsk->no_check = sk->no_check;
+       newsk->reuse = sk->reuse;
+       newsk->shutdown = sk->shutdown;
+
+       newsk->destruct = inet_sock_destruct;
+       newsk->zapped = 0;
+       newsk->family = PF_INET;
+       newsk->protocol = IPPROTO_SCTP;
+       newsk->backlog_rcv = sk->prot->backlog_rcv;
 
        newinet = inet_sk(newsk);
 
@@ -597,7 +597,7 @@
        atomic_inc(&inet_sock_nr);
 #endif
 
-       if (newsk->sk_prot->init(newsk)) {
+       if (newsk->prot->init(newsk)) {
                inet_sock_release(newsk);
                newsk = NULL;
        }
@@ -638,7 +638,7 @@
  * Initialize the control inode/socket with a control endpoint data
  * structure.  This endpoint is reserved exclusively for the OOTB processing.
  */
-int sctp_ctl_sock_init(void)
+static int sctp_ctl_sock_init(void)
 {
        int err;
        sa_family_t family;
@@ -655,7 +655,7 @@
                       "SCTP: Failed to create the SCTP control socket.\n");
                return err;
        }
-       sctp_ctl_socket->sk->sk_allocation = GFP_ATOMIC;
+       sctp_ctl_socket->sk->allocation = GFP_ATOMIC;
        inet_sk(sctp_ctl_socket->sk)->ttl = MAXTTL;
 
        return 0;
@@ -807,7 +807,7 @@
        return ip_queue_xmit(skb, ipfragok);
 }
 
-struct sctp_af sctp_ipv4_specific;
+static struct sctp_af sctp_ipv4_specific;
 
 static struct sctp_pf sctp_pf_inet = {
        .event_msgname = sctp_inet_event_msgname,
@@ -828,7 +828,7 @@
 };
 
 /* Socket operations.  */
-struct proto_ops inet_seqpacket_ops = {
+static struct proto_ops inet_seqpacket_ops = {
        .family      = PF_INET,
        .release     = inet_release,       /* Needs to be wrapped... */
        .bind        = inet_bind,
@@ -877,7 +877,7 @@
 };
 
 /* IPv4 address related functions.  */
-struct sctp_af sctp_ipv4_specific = {
+static struct sctp_af sctp_ipv4_specific = {
        .sctp_xmit      = sctp_v4_xmit,
        .setsockopt     = ip_setsockopt,
        .getsockopt     = ip_getsockopt,
@@ -948,7 +948,7 @@
 }
 
 /* Initialize the universe into something sensible.  */
-__init int sctp_init(void)
+SCTP_STATIC __init int sctp_init(void)
 {
        int i;
        int status = 0;
@@ -1161,7 +1161,7 @@
 }
 
 /* Exit handler for the SCTP protocol.  */
-__exit void sctp_exit(void)
+SCTP_STATIC __exit void sctp_exit(void)
 {
        /* BUG.  This should probably do something useful like clean
         * up all the remaining associations and all that memory.
diff -urN linux/net/sctp/sm_make_chunk.c linux/net/sctp/sm_make_chunk.c
--- linux/net/sctp/sm_make_chunk.c      2004/11/19 00:29:09     1.20.2.4
+++ linux/net/sctp/sm_make_chunk.c      2005/01/20 02:19:26     1.20.2.5
@@ -67,6 +67,19 @@
 
 extern kmem_cache_t *sctp_chunk_cachep;
 
+SCTP_STATIC
+struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
+                                  __u8 type, __u8 flags, int paylen);
+static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
+                                       const struct sctp_association *asoc,
+                                       const struct sctp_chunk *init_chunk,
+                                       int *cookie_len,
+                                       const __u8 *raw_addrs, int addrs_len);
+static int sctp_process_param(struct sctp_association *asoc,
+                             union sctp_params param,
+                             const union sctp_addr *peer_addr,
+                             int gfp);
+
 /* What was the inbound interface for this chunk? */
 int sctp_chunk_iif(const struct sctp_chunk *chunk)
 {
@@ -559,52 +572,6 @@
        return retval;
 }
 
-/* Make a DATA chunk for the given association.  Populate the data
- * payload.
- */
-struct sctp_chunk *sctp_make_datafrag(struct sctp_association *asoc,
-                                const struct sctp_sndrcvinfo *sinfo,
-                                int data_len, const __u8 *data,
-                                __u8 flags, __u16 ssn)
-{
-       struct sctp_chunk *retval;
-
-       retval = sctp_make_datafrag_empty(asoc, sinfo, data_len, flags, ssn);
-       if (retval)
-               sctp_addto_chunk(retval, data_len, data);
-
-       return retval;
-}
-
-/* Make a DATA chunk for the given association to ride on stream id
- * 'stream', with a payload id of 'payload', and a body of 'data'.
- */
-struct sctp_chunk *sctp_make_data(struct sctp_association *asoc,
-                            const struct sctp_sndrcvinfo *sinfo,
-                            int data_len, const __u8 *data)
-{
-       struct sctp_chunk *retval = NULL;
-
-       retval = sctp_make_data_empty(asoc, sinfo, data_len);
-       if (retval)
-               sctp_addto_chunk(retval, data_len, data);
-        return retval;
-}
-
-/* Make a DATA chunk for the given association to ride on stream id
- * 'stream', with a payload id of 'payload', and a body big enough to
- * hold 'data_len' octets of data.  We use this version when we need
- * to build the message AFTER allocating memory.
- */
-struct sctp_chunk *sctp_make_data_empty(struct sctp_association *asoc,
-                                  const struct sctp_sndrcvinfo *sinfo,
-                                  int data_len)
-{
-       __u8 flags = SCTP_DATA_NOT_FRAG;
-
-       return sctp_make_datafrag_empty(asoc, sinfo, data_len, flags, 0);
-}
-
 /* Create a selective ackowledgement (SACK) for the given
  * association.  This reports on which TSN's we've seen to date,
  * including duplicates and gaps.
@@ -881,6 +848,31 @@
        return retval;
 }
 
+/* Make an ABORT chunk with a PROTOCOL VIOLATION cause code. */ 
+struct sctp_chunk *sctp_make_abort_violation(
+       const struct sctp_association *asoc,
+       const struct sctp_chunk *chunk,
+       const __u8   *payload,
+       const size_t paylen)
+{
+       struct sctp_chunk  *retval;
+       struct sctp_paramhdr phdr;
+
+       retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen
+                                       + sizeof(sctp_chunkhdr_t));
+       if (!retval)
+               goto end;
+
+       sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, payload, paylen);
+
+       phdr.type = htons(chunk->chunk_hdr->type);
+       phdr.length = chunk->chunk_hdr->length;
+       sctp_addto_chunk(retval, sizeof(sctp_paramhdr_t), &phdr);
+
+end:
+       return retval;
+}
+
 /* Make a HEARTBEAT chunk.  */
 struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
                                  const struct sctp_transport *transport,
@@ -933,7 +925,7 @@
 /* Create an Operation Error chunk with the specified space reserved.
  * This routine can be used for containing multiple causes in the chunk.
  */
-struct sctp_chunk *sctp_make_op_error_space(
+static struct sctp_chunk *sctp_make_op_error_space(
        const struct sctp_association *asoc,
        const struct sctp_chunk *chunk,
        size_t size)
@@ -1034,7 +1026,6 @@
        SCTP_DBG_OBJCNT_INC(chunk);
        atomic_set(&retval->refcnt, 1);
 
-
 nodata:
        return retval;
 }
@@ -1062,6 +1053,7 @@
 /* Create a new chunk, setting the type and flags headers from the
  * arguments, reserving enough space for a 'paylen' byte payload.
  */
+SCTP_STATIC
 struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
                                   __u8 type, __u8 flags, int paylen)
 {
@@ -1261,7 +1253,7 @@
 /* Build a cookie representing asoc.
  * This INCLUDES the param header needed to put the cookie in the INIT ACK.
  */
-sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
+static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
                                      const struct sctp_association *asoc,
                                      const struct sctp_chunk *init_chunk,
                                      int *cookie_len,
@@ -1409,6 +1401,24 @@
        }
 
 no_hmac:
+       /* IG Section 2.35.2:
+        *  3) Compare the port numbers and the verification tag contained
+        *     within the COOKIE ECHO chunk to the actual port numbers and the
+        *     verification tag within the SCTP common header of the received
+        *     packet. If these values do not match the packet MUST be silently
+        *     discarded,
+        */
+       if (ntohl(chunk->sctp_hdr->vtag) != bear_cookie->my_vtag) {
+               *error = -SCTP_IERROR_BAD_TAG;
+               goto fail;
+       }
+
+       if (ntohs(chunk->sctp_hdr->source) != 
bear_cookie->peer_addr.v4.sin_port ||
+           ntohs(chunk->sctp_hdr->dest) != bear_cookie->my_port) {
+               *error = -SCTP_IERROR_BAD_PORTS;
+               goto fail;
+       }
+
        /* Check to see if the cookie is stale.  If there is already
         * an association, there is no need to check cookie's expiration
         * for init collision case of lost COOKIE ACK.
@@ -1547,6 +1557,30 @@
        return 0;
 }
 
+static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
+                                       struct sctp_paramhdr *param,
+                                       const struct sctp_chunk *chunk,
+                                       struct sctp_chunk **errp)
+{
+       char            error[] = "The following parameter had invalid length:";
+       size_t          payload_len = WORD_ROUND(sizeof(error)) + 
+                                               sizeof(sctp_paramhdr_t);
+
+
+       /* Create an error chunk and fill it in with our payload. */
+       if (!*errp)
+               *errp = sctp_make_op_error_space(asoc, chunk, payload_len);
+
+       if (*errp) {
+               sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION, error,
+                               sizeof(error));
+               sctp_addto_chunk(*errp, sizeof(sctp_paramhdr_t), param);
+       }
+
+       return 0;
+}
+
+
 /* Do not attempt to handle the HOST_NAME parm.  However, do
  * send back an indicator to the peer.
  */
@@ -1725,6 +1759,18 @@
 
        } /* for (loop through all parameters) */
 
+       /* There is a possibility that a parameter length was bad and
+        * in that case we would have stoped walking the parameters.
+        * The current param.p would point at the bad one.
+        * Current consensus on the mailing list is to generate a PROTOCOL
+        * VIOLATION error.  We build the ERROR chunk here and let the normal
+        * error handling code build and send the packet.
+        */
+       if (param.v < (void*)chunk->chunk_end - sizeof(sctp_paramhdr_t)) {
+               sctp_process_inv_paramlength(asoc, param.p, chunk, errp);
+               return 0;
+       }
+
        /* The only missing mandatory param possible today is
         * the state cookie for an INIT-ACK chunk.
         */
@@ -1896,8 +1942,10 @@
  * work we do.  In particular, we should not build transport
  * structures for the addresses.
  */
-int sctp_process_param(struct sctp_association *asoc, union sctp_params param,
-                      const union sctp_addr *peer_addr, int gfp)
+static int sctp_process_param(struct sctp_association *asoc,
+                             union sctp_params param,
+                             const union sctp_addr *peer_addr,
+                             int gfp)
 {
        union sctp_addr addr;
        int i;
@@ -1913,7 +1961,7 @@
         */
        switch (param.p->type) {
        case SCTP_PARAM_IPV6_ADDRESS:
-               if (PF_INET6 != asoc->base.sk->sk_family)
+               if (PF_INET6 != asoc->base.sk->family)
                        break;
                /* Fall through. */
        case SCTP_PARAM_IPV4_ADDRESS:
@@ -2062,8 +2110,9 @@
  *
  * Address Parameter and other parameter will not be wrapped in this function 
  */
-struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
-                                   union sctp_addr *addr, int vparam_len)
+static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
+                                          union sctp_addr *addr,
+                                          int vparam_len)
 {
        sctp_addiphdr_t asconf;
        struct sctp_chunk *retval;
@@ -2232,8 +2281,8 @@
  *
  * Create an ASCONF_ACK chunk with enough space for the parameter responses. 
  */
-struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *asoc,
-                                       __u32 serial, int vparam_len)
+static struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association 
*asoc,
+                                              __u32 serial, int vparam_len)
 {
        sctp_addiphdr_t         asconf;
        struct sctp_chunk       *retval;
diff -urN linux/net/sctp/sm_sideeffect.c linux/net/sctp/sm_sideeffect.c
--- linux/net/sctp/sm_sideeffect.c      2004/11/19 00:29:09     1.20.2.4
+++ linux/net/sctp/sm_sideeffect.c      2005/01/20 02:19:26     1.20.2.5
@@ -55,6 +55,24 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
+static int sctp_cmd_interpreter(sctp_event_t event_type,
+                               sctp_subtype_t subtype,
+                               sctp_state_t state,
+                               struct sctp_endpoint *ep,
+                               struct sctp_association *asoc,
+                               void *event_arg,
+                               sctp_disposition_t status,
+                               sctp_cmd_seq_t *commands,
+                               int gfp);
+static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
+                            sctp_state_t state,
+                            struct sctp_endpoint *ep,
+                            struct sctp_association *asoc,
+                            void *event_arg,
+                            sctp_disposition_t status,
+                            sctp_cmd_seq_t *commands,
+                            int gfp);
+
 /********************************************************************
  * Helper functions
  ********************************************************************/
@@ -134,8 +152,8 @@
 }
 
 /* Generate SACK if necessary.  We call this at the end of a packet.  */
-int sctp_gen_sack(struct sctp_association *asoc, int force,
-                 sctp_cmd_seq_t *commands)
+static int sctp_gen_sack(struct sctp_association *asoc, int force,
+                        sctp_cmd_seq_t *commands)
 {
        __u32 ctsn, max_tsn_seen;
        struct sctp_chunk *sack;
@@ -229,7 +247,7 @@
                           transport, GFP_ATOMIC);
 
        if (error)
-               asoc->base.sk->sk_err = -error;
+               asoc->base.sk->err = -error;
 
 out_unlock:
        sctp_bh_unlock_sock(asoc->base.sk);
@@ -269,38 +287,38 @@
                           (void *)timeout_type, GFP_ATOMIC);
 
        if (error)
-               asoc->base.sk->sk_err = -error;
+               asoc->base.sk->err = -error;
 
 out_unlock:
        sctp_bh_unlock_sock(asoc->base.sk);
        sctp_association_put(asoc);
 }
 
-void sctp_generate_t1_cookie_event(unsigned long data)
+static void sctp_generate_t1_cookie_event(unsigned long data)
 {
        struct sctp_association *asoc = (struct sctp_association *) data;
        sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T1_COOKIE);
 }
 
-void sctp_generate_t1_init_event(unsigned long data)
+static void sctp_generate_t1_init_event(unsigned long data)
 {
        struct sctp_association *asoc = (struct sctp_association *) data;
        sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T1_INIT);
 }
 
-void sctp_generate_t2_shutdown_event(unsigned long data)
+static void sctp_generate_t2_shutdown_event(unsigned long data)
 {
        struct sctp_association *asoc = (struct sctp_association *) data;
        sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T2_SHUTDOWN);
 }
 
-void sctp_generate_t4_rto_event(unsigned long data)
+static void sctp_generate_t4_rto_event(unsigned long data)
 {
        struct sctp_association *asoc = (struct sctp_association *) data;
        sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T4_RTO);
 }
 
-void sctp_generate_t5_shutdown_guard_event(unsigned long data)
+static void sctp_generate_t5_shutdown_guard_event(unsigned long data)
 {
         struct sctp_association *asoc = (struct sctp_association *)data;
         sctp_generate_timeout_event(asoc,
@@ -308,7 +326,7 @@
 
 } /* sctp_generate_t5_shutdown_guard_event() */
 
-void sctp_generate_autoclose_event(unsigned long data)
+static void sctp_generate_autoclose_event(unsigned long data)
 {
        struct sctp_association *asoc = (struct sctp_association *) data;
        sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_AUTOCLOSE);
@@ -345,7 +363,7 @@
                           transport, GFP_ATOMIC);
 
          if (error)
-                asoc->base.sk->sk_err = -error;
+                asoc->base.sk->err = -error;
 
 out_unlock:
        sctp_bh_unlock_sock(asoc->base.sk);
@@ -353,7 +371,7 @@
 }
 
 /* Inject a SACK Timeout event into the state machine.  */
-void sctp_generate_sack_event(unsigned long data)
+static void sctp_generate_sack_event(unsigned long data)
 {
        struct sctp_association *asoc = (struct sctp_association *) data;
        sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_SACK);
@@ -397,7 +415,7 @@
        asoc->overall_error_count++;
 
        if (transport->active &&
-           (transport->error_count++ >= transport->error_threshold)) {
+           (transport->error_count++ >= transport->max_retrans)) {
                SCTP_DEBUG_PRINTK("transport_strike: transport "
                                  "IP:%d.%d.%d.%d failed.\n",
                                  NIPQUAD(transport->ipaddr.v4.sin_addr));
@@ -460,9 +478,9 @@
        sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
                        SCTP_STATE(SCTP_STATE_CLOSED));
 
-       /* Set sk_err to ECONNRESET on a 1-1 style socket. */
+       /* Set sk->err to ECONNRESET on a 1-1 style socket. */
        if (!sctp_style(asoc->base.sk, UDP))
-               asoc->base.sk->sk_err = ECONNRESET; 
+               asoc->base.sk->err = ECONNRESET; 
 
        /* SEND_FAILED sent later when cleaning up the association. */
        asoc->outqueue.error = error;
@@ -648,16 +666,16 @@
        asoc->state = state;
 
        if (sctp_style(sk, TCP)) {
-               /* Change the sk->sk_state of a TCP-style socket that has 
+               /* Change the sk->state of a TCP-style socket that has 
                 * sucessfully completed a connect() call.
                 */
                if (sctp_state(asoc, ESTABLISHED) && sctp_sstate(sk, CLOSED))
-                       sk->sk_state = SCTP_SS_ESTABLISHED;
+                       sk->state = SCTP_SS_ESTABLISHED;
 
                /* Set the RCV_SHUTDOWN flag when a SHUTDOWN is received. */
                if (sctp_state(asoc, SHUTDOWN_RECEIVED) &&
                    sctp_sstate(sk, ESTABLISHED))
-                       sk->sk_shutdown |= RCV_SHUTDOWN;
+                       sk->shutdown |= RCV_SHUTDOWN;
        }
 
        if (sctp_state(asoc, ESTABLISHED) ||
@@ -676,7 +694,7 @@
                 * notifications.
                 */
                if (!sctp_style(sk, UDP))
-                       sk->sk_state_change(sk);
+                       sk->state_change(sk);
        }
 }
 
@@ -691,7 +709,7 @@
         * can pick it up later.
         */ 
        if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING) &&
-           (!asoc->temp) && (sk->sk_shutdown != SHUTDOWN_MASK))
+           (!asoc->temp) && (sk->shutdown != SHUTDOWN_MASK))
                return;
 
        sctp_unhash_established(asoc);
@@ -857,14 +875,14 @@
 /*****************************************************************
  * This the master state function side effect processing function.
  *****************************************************************/
-int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
-                     sctp_state_t state,
-                     struct sctp_endpoint *ep,
-                     struct sctp_association *asoc,
-                     void *event_arg,
-                     sctp_disposition_t status,
-                     sctp_cmd_seq_t *commands,
-                     int gfp)
+static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
+                            sctp_state_t state,
+                            struct sctp_endpoint *ep,
+                            struct sctp_association *asoc,
+                            void *event_arg,
+                            sctp_disposition_t status,
+                            sctp_cmd_seq_t *commands,
+                            int gfp)
 {
        int error;
 
@@ -944,11 +962,15 @@
  ********************************************************************/
 
 /* This is the side-effect interpreter.  */
-int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
-                        sctp_state_t state, struct sctp_endpoint *ep,
-                        struct sctp_association *asoc, void *event_arg,
-                        sctp_disposition_t status, sctp_cmd_seq_t *commands,
-                        int gfp)
+static int sctp_cmd_interpreter(sctp_event_t event_type,
+                               sctp_subtype_t subtype,
+                               sctp_state_t state,
+                               struct sctp_endpoint *ep,
+                               struct sctp_association *asoc,
+                               void *event_arg,
+                               sctp_disposition_t status,
+                               sctp_cmd_seq_t *commands,
+                               int gfp)
 {
        int error = 0;
        int force;
diff -urN linux/net/sctp/sm_statefuns.c linux/net/sctp/sm_statefuns.c
--- linux/net/sctp/sm_statefuns.c       2004/11/19 00:29:09     1.20.2.4
+++ linux/net/sctp/sm_statefuns.c       2005/01/20 02:19:26     1.20.2.5
@@ -65,6 +65,53 @@
 #include <net/sctp/sm.h>
 #include <net/sctp/structs.h>
 
+static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
+                                 const struct sctp_association *asoc,
+                                 struct sctp_chunk *chunk,
+                                 const void *payload,
+                                 size_t paylen);
+static int sctp_eat_data(const struct sctp_association *asoc,
+                        struct sctp_chunk *chunk,
+                        sctp_cmd_seq_t *commands);
+static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association 
*asoc,
+                                            const struct sctp_chunk *chunk);
+static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
+                                      const struct sctp_association *asoc,
+                                      const struct sctp_chunk *chunk,
+                                      sctp_cmd_seq_t *commands,
+                                      struct sctp_chunk *err_chunk);
+static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint 
*ep,
+                                                const struct sctp_association 
*asoc,
+                                                const sctp_subtype_t type,
+                                                void *arg,
+                                                sctp_cmd_seq_t *commands);
+static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
+                                            const struct sctp_association 
*asoc,
+                                            const sctp_subtype_t type,
+                                            void *arg,
+                                            sctp_cmd_seq_t *commands);
+static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
+
+
+/* Small helper function that checks if the chunk length
+ * is of the appropriate length.  The 'required_length' argument
+ * is set to be the size of a specific chunk we are testing.
+ * Return Values:  1 = Valid length
+ *                0 = Invalid length
+ *
+ */
+static inline int
+sctp_chunk_length_valid(struct sctp_chunk *chunk,
+                          __u16 required_length)
+{
+       __u16 chunk_length = ntohs(chunk->chunk_hdr->length);
+
+       if (unlikely(chunk_length < required_length))
+               return 0;
+
+       return 1;
+}
+
 /**********************************************************
  * These are the state functions for handling chunk events.
  **********************************************************/
@@ -199,9 +246,14 @@
        /* 6.10 Bundling
         * An endpoint MUST NOT bundle INIT, INIT ACK or
         * SHUTDOWN COMPLETE with any other chunks.
+        * 
+        * IG Section 2.11.2
+        * Furthermore, we require that the receiver of an INIT chunk MUST
+        * enforce these rules by silently discarding an arriving packet
+        * with an INIT chunk that is bundled with other chunks.
         */
        if (!chunk->singleton)
-               return SCTP_DISPOSITION_VIOLATION;
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
        /* If the packet is an OOTB packet which is temporarily on the
         * control endpoint, respond with an ABORT.
@@ -216,7 +268,7 @@
         */
        if (!sctp_sstate(sk, LISTENING) ||
            (sctp_style(sk, TCP) &&
-            (sk->sk_ack_backlog >= sk->sk_max_ack_backlog)))
+            (sk->ack_backlog >= sk->max_ack_backlog)))
                return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
 
        /* 3.1 A packet containing an INIT chunk MUST have a zero Verification
@@ -225,6 +277,14 @@
        if (chunk->sctp_hdr->vtag != 0)
                return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
 
+       /* Make sure that the INIT chunk has a valid length.
+        * Normally, this would cause an ABORT with a Protocol Violation
+        * error, but since we don't have an association, we'll
+        * just discard the packet.
+        */
+       if (!sctp_chunk_length_valid(chunk, sizeof(sctp_init_chunk_t)))
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
        /* Verify the INIT chunk before processing it. */
        err_chunk = NULL;
        if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
@@ -376,6 +436,13 @@
        struct sctp_packet *packet;
        sctp_disposition_t ret;
 
+       if (!sctp_vtag_verify(chunk, asoc))
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+       /* Make sure that the INIT-ACK chunk has a valid length */
+       if (!sctp_chunk_length_valid(chunk, sizeof(sctp_initack_chunk_t)))
+               return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+                                                 commands);
        /* 6.10 Bundling
         * An endpoint MUST NOT bundle INIT, INIT ACK or
         * SHUTDOWN COMPLETE with any other chunks.
@@ -383,9 +450,6 @@
        if (!chunk->singleton)
                return SCTP_DISPOSITION_VIOLATION;
 
-       if (!sctp_vtag_verify(chunk, asoc))
-               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
-
        /* Grab the INIT header.  */
        chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
 
@@ -542,6 +606,14 @@
        if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
                return sctp_sf_ootb(ep, asoc, type, arg, commands);
 
+       /* Make sure that the COOKIE_ECHO chunk has a valid length.
+        * In this case, we check that we have enough for at least a
+        * chunk header.  More detailed verification is done
+        * in sctp_unpack_cookie().
+        */
+       if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
        /* "Decode" the chunk.  We have no optional parameters so we
         * are in good shape.
         */
@@ -687,6 +759,13 @@
        if (!sctp_vtag_verify(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+       /* Verify that the chunk length for the COOKIE-ACK is OK.
+        * If we don't do this, any bundled chunks may be junked.
+        */
+       if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
+               return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+                                                 commands);
+
        /* Reset init error count upon receipt of COOKIE-ACK,
         * to avoid problems with the managemement of this
         * counter in stale cookie situations when a transition back
@@ -748,11 +827,11 @@
 }
 
 /* Generate and sendout a heartbeat packet.  */
-sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
-                                    const struct sctp_association *asoc,
-                                    const sctp_subtype_t type,
-                                    void *arg,
-                                    sctp_cmd_seq_t *commands)
+static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
+                                           const struct sctp_association *asoc,
+                                           const sctp_subtype_t type,
+                                           void *arg,
+                                           sctp_cmd_seq_t *commands)
 {
        struct sctp_transport *transport = (struct sctp_transport *) arg;
        struct sctp_chunk *reply;
@@ -859,6 +938,11 @@
        if (!sctp_vtag_verify(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+       /* Make sure that the HEARTBEAT chunk has a valid length. */
+       if (!sctp_chunk_length_valid(chunk, sizeof(sctp_heartbeat_chunk_t)))
+               return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+                                                 commands);
+
        /* 8.3 The receiver of the HEARTBEAT should immediately
         * respond with a HEARTBEAT ACK that contains the Heartbeat
         * Information field copied from the received HEARTBEAT chunk.
@@ -922,6 +1006,11 @@
        if (!sctp_vtag_verify(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+       /* Make sure that the HEARTBEAT-ACK chunk has a valid length.  */
+       if (!sctp_chunk_length_valid(chunk, sizeof(sctp_heartbeat_chunk_t)))
+               return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+                                                 commands);
+
        hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
        from_addr = hbinfo->daddr;
        link = sctp_assoc_lookup_paddr(asoc, &from_addr);
@@ -1165,9 +1254,14 @@
        /* 6.10 Bundling
         * An endpoint MUST NOT bundle INIT, INIT ACK or
         * SHUTDOWN COMPLETE with any other chunks.
+        *
+        * IG Section 2.11.2
+        * Furthermore, we require that the receiver of an INIT chunk MUST
+        * enforce these rules by silently discarding an arriving packet
+        * with an INIT chunk that is bundled with other chunks.
         */
        if (!chunk->singleton)
-               return SCTP_DISPOSITION_VIOLATION;
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
        /* 3.1 A packet containing an INIT chunk MUST have a zero Verification
         * Tag. 
@@ -1175,6 +1269,13 @@
        if (chunk->sctp_hdr->vtag != 0)
                return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
 
+       /* Make sure that the INIT chunk has a valid length.
+        * In this case, we generate a protocol violation since we have
+        * an association established.
+        */
+       if (!sctp_chunk_length_valid(chunk, sizeof(sctp_init_chunk_t)))
+               return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+                                                 commands);
        /* Grab the INIT header.  */
        chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
 
@@ -1718,6 +1819,15 @@
        char action;
        struct sctp_chunk *err_chk_p;
 
+       /* Make sure that the chunk has a valid length from the protocol
+        * perspective.  In this case check to make sure we have at least
+        * enough for the chunk header.  Cookie length verification is
+        * done later.
+        */
+       if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
+               return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+                                                 commands);
+
        /* "Decode" the chunk.  We have no optional parameters so we
         * are in good shape.
         */
@@ -1815,6 +1925,19 @@
        if (!sctp_vtag_verify_either(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+       /* Make sure that the ABORT chunk has a valid length.
+        * Since this is an ABORT chunk, we have to discard it
+        * because of the following text:
+        * RFC 2960, Section 3.3.7
+        *    If an endpoint receives an ABORT with a format error or for an
+        *    association that doesn't exist, it MUST silently discard it.
+        * Becasue the length is "invalid", we can't really discard just
+        * as we do not know its true length.  So, to be safe, discard the
+        * packet.
+        */
+       if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
        /* Stop the T5-shutdown guard timer.  */
        sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                        SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
@@ -1838,6 +1961,19 @@
        if (!sctp_vtag_verify_either(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+       /* Make sure that the ABORT chunk has a valid length.
+        * Since this is an ABORT chunk, we have to discard it
+        * because of the following text:
+        * RFC 2960, Section 3.3.7
+        *    If an endpoint receives an ABORT with a format error or for an
+        *    association that doesn't exist, it MUST silently discard it.
+        * Becasue the length is "invalid", we can't really discard just
+        * as we do not know its true length.  So, to be safe, discard the
+        * packet.
+        */
+       if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
        /* Stop the T2-shutdown timer. */
        sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                        SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
@@ -1890,6 +2026,16 @@
        struct sctp_chunk *chunk = arg;
        sctp_errhdr_t *err;
 
+       if (!sctp_vtag_verify(chunk, asoc))
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+       /* Make sure that the ERROR chunk has a valid length.
+        * The parameter walking depends on this as well.
+        */
+       if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t)))
+               return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+                                                 commands);
+
        /* Process the error here */
        /* FUTURE FIXME:  When PR-SCTP related and other optional
         * parms are emitted, this will have to change to handle multiple
@@ -1900,6 +2046,12 @@
                        return sctp_sf_do_5_2_6_stale(ep, asoc, type, 
                                                        arg, commands);
        }
+
+       /* It is possible to have malformed error causes, and that
+        * will cause us to end the walk early.  However, since
+        * we are discarding the packet, there should be no adverse
+        * affects.
+        */
        return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 }
 
@@ -1928,11 +2080,11 @@
  *
  * The return value is the disposition of the chunk.
  */
-sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
-                                         const struct sctp_association *asoc,
-                                         const sctp_subtype_t type,
-                                         void *arg,
-                                         sctp_cmd_seq_t *commands)
+static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint 
*ep,
+                                                const struct sctp_association 
*asoc,
+                                                const sctp_subtype_t type,
+                                                void *arg,
+                                                sctp_cmd_seq_t *commands)
 {
        struct sctp_chunk *chunk = arg;
        time_t stale;
@@ -2064,12 +2216,24 @@
        if (!sctp_vtag_verify_either(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
-       /* Check that chunk header looks valid.  */
+       /* Make sure that the ABORT chunk has a valid length.
+        * Since this is an ABORT chunk, we have to discard it
+        * because of the following text:
+        * RFC 2960, Section 3.3.7
+        *    If an endpoint receives an ABORT with a format error or for an
+        *    association that doesn't exist, it MUST silently discard it.
+        * Becasue the length is "invalid", we can't really discard just
+        * as we do not know its true length.  So, to be safe, discard the
+        * packet.
+        */
+       if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+       /* See if we have an error cause code in the chunk.  */
        len = ntohs(chunk->chunk_hdr->length);
        if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
                error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
 
-
        /* ASSOC_FAILED will DELETE_TCB. */
        sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error));
        SCTP_INC_STATS(SctpAborteds);
@@ -2096,27 +2260,44 @@
        if (!sctp_vtag_verify_either(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
-       sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
-                       SCTP_STATE(SCTP_STATE_CLOSED));
-       SCTP_INC_STATS(SctpAborteds);
-       sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
-                       SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+       /* Make sure that the ABORT chunk has a valid length.
+        * Since this is an ABORT chunk, we have to discard it
+        * because of the following text:
+        * RFC 2960, Section 3.3.7
+        *    If an endpoint receives an ABORT with a format error or for an
+        *    association that doesn't exist, it MUST silently discard it.
+        * Becasue the length is "invalid", we can't really discard just
+        * as we do not know its true length.  So, to be safe, discard the
+        * packet.
+        */
+       if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
-       /* Check that chunk header looks valid.  */
+       /* See if we have an error cause code in the chunk.  */
        len = ntohs(chunk->chunk_hdr->length);
        if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
                error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
 
-       /* CMD_INIT_FAILED will DELETE_TCB. */
-       sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_U32(error));
+       sctp_stop_t1_and_abort(commands, error);
 
        return SCTP_DISPOSITION_ABORT;
 }
 
 /*
+ * Process an incoming ICMP as an ABORT.  (COOKIE-WAIT state)
+ */
+sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint 
*ep,
+                                       const struct sctp_association *asoc,
+                                       const sctp_subtype_t type,
+                                       void *arg,
+                                       sctp_cmd_seq_t *commands)
+{
+       sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR);
+       return SCTP_DISPOSITION_ABORT;
+}
+
+/*
  * Process an ABORT.  (COOKIE-ECHOED state)

[%d lines skipped]
436diff -urN linux/net/sctp/sm_statetable.c linux/net/sctp/sm_statetable.c
--- linux/net/sctp/sm_statetable.c      2004/08/14 18:39:05     1.10.2.3
+++ linux/net/sctp/sm_statetable.c      2005/01/20 02:19:26     1.10.2.4
@@ -50,6 +50,17 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
+static const sctp_sm_table_entry_t
+primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES];
+static const sctp_sm_table_entry_t
+other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES];
+static const sctp_sm_table_entry_t
+timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES];
+
+static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
+                                                           sctp_state_t state);
+
+
 static const sctp_sm_table_entry_t bug = {
        .fn = sctp_sf_bug,
        .name = "sctp_sf_bug"
@@ -419,7 +430,7 @@
  *
  * For base protocol (RFC 2960).
  */
-const sctp_sm_table_entry_t 
chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t 
chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
        TYPE_SCTP_DATA,
        TYPE_SCTP_INIT,
        TYPE_SCTP_INIT_ACK,
@@ -482,7 +493,7 @@
 /* The primary index for this table is the chunk type.
  * The secondary index for this table is the state.
  */
-const sctp_sm_table_entry_t 
addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t 
addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
        TYPE_SCTP_ASCONF,
        TYPE_SCTP_ASCONF_ACK,
 }; /*state_fn_t addip_chunk_event_table[][] */
@@ -511,7 +522,7 @@
 /* The primary index for this table is the chunk type.
  * The secondary index for this table is the state.
  */
-const sctp_sm_table_entry_t 
prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t 
prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
        TYPE_SCTP_FWD_TSN,
 }; /*state_fn_t prsctp_chunk_event_table[][] */
 
@@ -684,7 +695,7 @@
 /* The primary index for this table is the primitive type.
  * The secondary index for this table is the state.
  */
-const sctp_sm_table_entry_t 
primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t 
primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = {
        TYPE_SCTP_PRIMITIVE_ASSOCIATE,
        TYPE_SCTP_PRIMITIVE_SHUTDOWN,
        TYPE_SCTP_PRIMITIVE_ABORT,
@@ -716,8 +727,31 @@
        {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
 }
 
-const sctp_sm_table_entry_t 
other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = {
+#define TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH  { \
+       /* SCTP_STATE_EMPTY */ \
+       {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+       /* SCTP_STATE_CLOSED */ \
+       {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+       /* SCTP_STATE_COOKIE_WAIT */ \
+       {.fn = sctp_sf_cookie_wait_icmp_abort, \
+        .name = "sctp_sf_cookie_wait_icmp_abort"}, \
+       /* SCTP_STATE_COOKIE_ECHOED */ \
+       {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+       /* SCTP_STATE_ESTABLISHED */ \
+       {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+       /* SCTP_STATE_SHUTDOWN_PENDING */ \
+       {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+       /* SCTP_STATE_SHUTDOWN_SENT */ \
+       {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+       /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
+       {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+       /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
+       {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+}
+
+static const sctp_sm_table_entry_t 
other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = {
        TYPE_SCTP_OTHER_NO_PENDING_TSN,
+       TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH,
 };
 
 #define TYPE_SCTP_EVENT_TIMEOUT_NONE { \
@@ -931,7 +965,7 @@
        {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 }
 
-const sctp_sm_table_entry_t 
timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t 
timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = {
        TYPE_SCTP_EVENT_TIMEOUT_NONE,
        TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE,
        TYPE_SCTP_EVENT_TIMEOUT_T1_INIT,
@@ -944,8 +978,8 @@
        TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE,
 };
 
-const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, 
-                                                    sctp_state_t state)
+static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, 
+                                                           sctp_state_t state)
 {
        if (state > SCTP_STATE_MAX)
                return &bug;
diff -urN linux/net/sctp/socket.c linux/net/sctp/socket.c
--- linux/net/sctp/socket.c     2004/12/27 04:13:57     1.23.2.6
+++ linux/net/sctp/socket.c     2005/01/20 02:19:26     1.23.2.7
@@ -116,7 +116,7 @@
        struct sock *sk = asoc->base.sk;
        int amt = 0;
 
-       amt = sk->sk_sndbuf - asoc->sndbuf_used;
+       amt = sk->sndbuf - asoc->sndbuf_used;
        if (amt < 0)
                amt = 0;
        return amt;
@@ -144,7 +144,7 @@
        *((struct sctp_chunk **)(chunk->skb->cb)) = chunk;
 
        asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk);
-       sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk);
+       sk->wmem_queued += SCTP_DATA_SNDSIZE(chunk);
 }
 
 /* Verify that this is a valid address. */
@@ -203,7 +203,7 @@
  * id are specified, the associations matching the address and the id should be
  * the same.
  */
-struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
+static struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
                                              struct sockaddr_storage *addr,
                                              sctp_assoc_t id)
 {
@@ -224,7 +224,7 @@
        if (id_asoc && (id_asoc != addr_asoc))
                return NULL;
 
-       sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
+       sctp_get_pf_specific(sk->family)->addr_v4map(sctp_sk(sk),
                                                (union sctp_addr *)addr);
 
        return transport;
@@ -240,7 +240,7 @@
  *             sockaddr_in6 [RFC 2553]),
  *   addr_len - the size of the address structure.
  */
-int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+SCTP_STATIC int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int 
addr_len)
 {
        int retval = 0;
 
@@ -338,8 +338,8 @@
        }
 
        /* Refresh ephemeral port.  */
-       if (!snum)
-               snum = sk->num;
+       if (!bp->port)
+               bp->port = sk->num;
 
        /* Add the address to the bind address list.  */
        sctp_local_bh_disable();
@@ -349,8 +349,6 @@
        addr->v4.sin_port = ntohs(addr->v4.sin_port);
        ret = sctp_add_bind_addr(bp, addr, GFP_ATOMIC);
        addr->v4.sin_port = htons(addr->v4.sin_port);
-       if (!ret && !bp->port)
-               bp->port = snum;
        sctp_write_unlock(&ep->base.addr_lock);
        sctp_local_bh_enable();
 
@@ -612,7 +610,7 @@
                }
 
                /* FIXME - There is probably a need to check if sk->sk_saddr and
-                * sk->sk_rcv_addr are currently set to one of the addresses to
+                * sk->rcv_addr are currently set to one of the addresses to
                 * be removed. This is something which needs to be looked into
                 * when we are fixing the outstanding issues with multi-homing
                 * socket routing and failover schemes. Refer to comments in
@@ -951,7 +949,7 @@
        SCTP_DEBUG_PRINTK("sctp_close(sk: 0x%p, timeout:%ld)\n", sk, timeout);
 
        sctp_lock_sock(sk);
-       sk->sk_shutdown = SHUTDOWN_MASK;
+       sk->shutdown = SHUTDOWN_MASK;
 
        ep = sctp_sk(sk)->ep;
 
@@ -969,7 +967,7 @@
                                sctp_unhash_established(asoc);
                                sctp_association_free(asoc);
 
-                       } else if (sk->linger && !sk->sk_lingertime)
+                       } else if (sk->linger && !sk->lingertime)
                                sctp_primitive_ABORT(asoc, NULL);
                        else
                                sctp_primitive_SHUTDOWN(asoc, NULL);
@@ -978,7 +976,7 @@
        }
 
        /* Clean up any skbs sitting on the receive queue.  */
-       sctp_queue_purge_ulpevents(&sk->sk_receive_queue);
+       sctp_queue_purge_ulpevents(&sk->receive_queue);
        sctp_queue_purge_ulpevents(&sctp_sk(sk)->pd_lobby);
 
        /* On a TCP-style socket, block for at most linger_time if set. */
@@ -1314,7 +1312,7 @@
        /* API 7.1.7, the sndbuf size per association bounds the
         * maximum size of data that can be sent in a single send call.
         */
-       if (msg_len > sk->sk_sndbuf) {
+       if (msg_len > sk->sndbuf) {
                err = -EMSGSIZE;
                goto out_free;
        }
@@ -1551,7 +1549,7 @@
                if (flags & MSG_PEEK)
                        goto out_free;
                sctp_skb_pull(skb, copied);
-               skb_queue_head(&sk->sk_receive_queue, skb);
+               skb_queue_head(&sk->receive_queue, skb);
 
                /* When only partial message is copied to the user, increase
                 * rwnd by that amount. If all the data in the skb is read,
@@ -1704,10 +1702,13 @@
        /* update default value for endpoint (all future associations) */
        if (!params.spp_assoc_id && 
            sctp_is_any(( union sctp_addr *)&params.spp_address)) {
-               if (params.spp_hbinterval)
+               /* Manual heartbeat on an endpoint is invalid. */
+               if (0xffffffff == params.spp_hbinterval)
+                       return -EINVAL;
+               else if (params.spp_hbinterval)
                        sctp_sk(sk)->paddrparam.spp_hbinterval =
                                                params.spp_hbinterval;
-               if (sctp_max_retrans_path)
+               if (params.spp_pathmaxrxt)
                        sctp_sk(sk)->paddrparam.spp_pathmaxrxt =
                                                params.spp_pathmaxrxt;
                return 0;
@@ -1749,7 +1750,8 @@
        /* spp_pathmaxrxt contains the maximum number of retransmissions
         * before this address shall be considered unreachable.
         */
-       trans->error_threshold = params.spp_pathmaxrxt;
+       if (params.spp_pathmaxrxt)
+               trans->max_retrans = params.spp_pathmaxrxt;
 
        return 0;
 }
@@ -2355,7 +2357,7 @@
        af = sctp_get_af_specific(to.sa.sa_family);
        af->to_sk_daddr(&to, sk);
 
-       timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK);
+       timeo = sock_sndtimeo(sk, sk->socket->file->f_flags & O_NONBLOCK);
        err = sctp_wait_for_connect(asoc, &timeo);
 
 out_unlock:
@@ -2401,7 +2403,7 @@
                goto out;
        }
 
-       timeo = sock_rcvtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK);
+       timeo = sock_rcvtimeo(sk, sk->socket->file->f_flags & O_NONBLOCK);
 
        error = sctp_wait_for_accept(sk, timeo);
        if (error)
@@ -2449,7 +2451,7 @@
        sp = sctp_sk(sk);
 
        /* Initialize the SCTP per socket area.  */
-       switch (sk->sk_type) {
+       switch (sk->type) {
        case SOCK_SEQPACKET:
                sp->type = SCTP_SOCKET_UDP;
                break;
@@ -2529,7 +2531,7 @@
 
        sp->adaption_ind = 0;
 
-       sp->pf = sctp_get_pf_specific(sk->sk_family);
+       sp->pf = sctp_get_pf_specific(sk->family);
 
        /* Control variables for partial data delivery. */
        sp->pd_mode           = 0;
@@ -2646,7 +2648,7 @@
        memcpy(&status.sstat_primary.spinfo_address,
               &(transport->ipaddr), sizeof(union sctp_addr));
        /* Map ipv4 address into v4-mapped-on-v6 address.  */
-       sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
+       sctp_get_pf_specific(sk->family)->addr_v4map(sctp_sk(sk),
                (union sctp_addr *)&status.sstat_primary.spinfo_address);
        status.sstat_primary.spinfo_state = transport->active;
        status.sstat_primary.spinfo_cwnd = transport->cwnd;
@@ -2800,7 +2802,7 @@
                return -EINVAL;
 
        /* Create a new socket.  */
-       err = sock_create(sk->sk_family, SOCK_SEQPACKET, IPPROTO_SCTP, &sock);
+       err = sock_create(sk->family, SOCK_SEQPACKET, IPPROTO_SCTP, &sock);
        if (err < 0)
                return err;
 
@@ -2926,7 +2928,7 @@
        /* spp_pathmaxrxt contains the maximum number of retransmissions
         * before this address shall be considered unreachable.
         */
-       params.spp_pathmaxrxt = trans->error_threshold;
+       params.spp_pathmaxrxt = trans->max_retrans;
 
 done:
        if (copy_to_user(optval, &params, len))
@@ -3014,8 +3016,8 @@
        list_for_each(pos, &asoc->peer.transport_addr_list) {
                from = list_entry(pos, struct sctp_transport, transports);
                memcpy(&temp, &from->ipaddr, sizeof(temp));
-               sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
-               addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len;
+               sctp_get_pf_specific(sk->family)->addr_v4map(sp, &temp);
+               addrlen = sctp_get_af_specific(sk->family)->sockaddr_len;
                temp.v4.sin_port = htons(temp.v4.sin_port);
                if (copy_to_user(to, &temp, addrlen))
                        return -EFAULT;
@@ -3037,6 +3039,9 @@
        struct sctp_bind_addr *bp;
        struct sctp_association *asoc;
        struct list_head *pos;
+       struct sctp_sockaddr_entry *addr;
+       rwlock_t *addr_lock;
+       unsigned long flags;
        int cnt = 0;
 
        if (len != sizeof(sctp_assoc_t))
@@ -3053,33 +3058,103 @@
         */
        if (0 == id) {
                bp = &sctp_sk(sk)->ep->base.bind_addr;
+               addr_lock = &sctp_sk(sk)->ep->base.addr_lock;
        } else {
                asoc = sctp_id2assoc(sk, id);
                if (!asoc)
                        return -EINVAL;
                bp = &asoc->base.bind_addr;
+               addr_lock = &asoc->base.addr_lock;
        }
 
+       sctp_read_lock(addr_lock);
+
+       /* If the endpoint is bound to 0.0.0.0 or ::0, count the valid
+        * addresses from the global local address list.
+        */
+       if (sctp_list_single_entry(&bp->address_list)) {
+               addr = list_entry(bp->address_list.next,
+                                 struct sctp_sockaddr_entry, list);
+               if (sctp_is_any(&addr->a)) {
+                       sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
+                       list_for_each(pos, &sctp_local_addr_list) {
+                               addr = list_entry(pos,
+                                                 struct sctp_sockaddr_entry,
+                                                 list);
+                               if ((PF_INET == sk->family) &&
+                                   (AF_INET6 == addr->a.sa.sa_family))
+                                       continue;
+                               cnt++;
+                       }
+                       sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
+                                                   flags);
+               } else {
+                       cnt = 1;
+               }
+               goto done;
+        }
+
        list_for_each(pos, &bp->address_list) {
                cnt ++;
        }
 
+done:
+       sctp_read_unlock(addr_lock);
+       return cnt;
+}
+
+/* Helper function that copies local addresses to user and returns the number
+ * of addresses copied.
+ */
+static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, int max_addrs,
+                                   void __user *to)
+{
+       struct list_head *pos;
+       struct sctp_sockaddr_entry *addr;
+       unsigned long flags;
+       union sctp_addr temp;
+       int cnt = 0;
+       int addrlen;
+
+       sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
+       list_for_each(pos, &sctp_local_addr_list) {
+               addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+               if ((PF_INET == sk->family) &&
+                   (AF_INET6 == addr->a.sa.sa_family))
+                       continue;
+               memcpy(&temp, &addr->a, sizeof(temp));
+               sctp_get_pf_specific(sk->family)->addr_v4map(sctp_sk(sk),
+                                                               &temp);
+               addrlen = 
sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;                
temp.v4.sin_port = htons(port);
+               if (copy_to_user(to, &temp, addrlen)) {
+                       sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
+                                                   flags);
+                       return -EFAULT;
+               }
+               to += addrlen;
+               cnt ++;
+               if (cnt >= max_addrs) break;
+       }
+       sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
+
        return cnt;
 }
 
 static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
-                                       char *optval, int *optlen)
+                                      char *optval, int *optlen)
 {
        struct sctp_bind_addr *bp;
        struct sctp_association *asoc;
        struct list_head *pos;
        int cnt = 0;
        struct sctp_getaddrs getaddrs;
-       struct sctp_sockaddr_entry *from;
+       struct sctp_sockaddr_entry *addr;
        void *to;
        union sctp_addr temp;
        struct sctp_opt *sp = sctp_sk(sk);
        int addrlen;
+       rwlock_t *addr_lock;
+       int err = 0;
 
        if (len != sizeof(struct sctp_getaddrs))
                return -EINVAL;
@@ -3096,33 +3171,59 @@
         */
        if (0 == getaddrs.assoc_id) {
                bp = &sctp_sk(sk)->ep->base.bind_addr;
+               addr_lock = &sctp_sk(sk)->ep->base.addr_lock;
        } else {
                asoc = sctp_id2assoc(sk, getaddrs.assoc_id);
                if (!asoc)
                        return -EINVAL;
                bp = &asoc->base.bind_addr;
+               addr_lock = &asoc->base.addr_lock;
        }
 
        to = (void *)getaddrs.addrs;
+
+       sctp_read_lock(addr_lock);
+
+       /* If the endpoint is bound to 0.0.0.0 or ::0, get the valid
+        * addresses from the global local address list.
+        */
+       if (sctp_list_single_entry(&bp->address_list)) {
+               addr = list_entry(bp->address_list.next,
+                                 struct sctp_sockaddr_entry, list);
+               if (sctp_is_any(&addr->a)) {
+                       cnt = sctp_copy_laddrs_to_user(sk, bp->port,
+                                                      getaddrs.addr_num, to);
+                       if (cnt < 0) {
+                               err = cnt;
+                               goto unlock;
+                       }
+                       goto copy_getaddrs;
+               }
+       }
+
        list_for_each(pos, &bp->address_list) {
-               from = list_entry(pos,
-                               struct sctp_sockaddr_entry,
-                               list);
-               memcpy(&temp, &from->a, sizeof(temp));
-               sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
+               addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+               memcpy(&temp, &addr->a, sizeof(temp));
+               sctp_get_pf_specific(sk->family)->addr_v4map(sp, &temp);
                addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
                temp.v4.sin_port = htons(temp.v4.sin_port);
-               if (copy_to_user(to, &temp, addrlen))
-                       return -EFAULT;
+               if (copy_to_user(to, &temp, addrlen)) {
+                       err = -EFAULT;
+                       goto unlock;
+               }
                to += addrlen;
                cnt ++;
                if (cnt >= getaddrs.addr_num) break;
        }
+
+copy_getaddrs:
        getaddrs.addr_num = cnt;
        if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs)))
-               return -EFAULT;
+               err = -EFAULT;
 
-       return 0;

[%d lines skipped]
355diff -urN linux/net/sctp/ssnmap.c linux/net/sctp/ssnmap.c
--- linux/net/sctp/ssnmap.c     2004/04/16 03:14:22     1.2.2.2
+++ linux/net/sctp/ssnmap.c     2005/01/20 02:19:26     1.2.2.3
@@ -42,6 +42,9 @@
 
 #define MAX_KMALLOC_SIZE       131072
 
+static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
+                                           __u16 out);
+
 /* Storage size needed for map includes 2 headers and then the
  * specific needs of in or out streams.
  */
@@ -87,8 +90,8 @@
 
 
 /* Initialize a block of memory as a ssnmap.  */
-struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
-                                    __u16 out)
+static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
+                                           __u16 out)
 {
        memset(map, 0x00, sctp_ssnmap_size(in, out));
 
diff -urN linux/net/sctp/transport.c linux/net/sctp/transport.c
--- linux/net/sctp/transport.c  2004/11/19 00:29:09     1.11.2.5
+++ linux/net/sctp/transport.c  2005/01/20 02:19:26     1.11.2.6
@@ -54,34 +54,10 @@
 
 /* 1st Level Abstractions.  */
 
-/* Allocate and initialize a new transport.  */
-struct sctp_transport *sctp_transport_new(const union sctp_addr *addr, int gfp)
-{
-        struct sctp_transport *transport;
-
-        transport = t_new(struct sctp_transport, gfp);
-       if (!transport)
-               goto fail;
-
-       if (!sctp_transport_init(transport, addr, gfp))
-               goto fail_init;
-
-       transport->malloced = 1;
-       SCTP_DBG_OBJCNT_INC(transport);
-
-       return transport;
-
-fail_init:
-       kfree(transport);
-
-fail:
-       return NULL;
-}
-
 /* Initialize a new transport from provided memory.  */
-struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
-                                          const union sctp_addr *addr,
-                                          int gfp)
+static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
+                                                 const union sctp_addr *addr,
+                                                 int gfp)
 {
        /* Copy in the address.  */
        peer->ipaddr = *addr;
@@ -112,7 +88,6 @@
 
        /* Initialize the default path max_retrans.  */
        peer->max_retrans = sctp_max_retrans_path;
-       peer->error_threshold = 0;
        peer->error_count = 0;
 
        INIT_LIST_HEAD(&peer->transmitted);
@@ -144,6 +119,30 @@
        return peer;
 }
 
+/* Allocate and initialize a new transport.  */
+struct sctp_transport *sctp_transport_new(const union sctp_addr *addr, int gfp)
+{
+        struct sctp_transport *transport;
+
+        transport = t_new(struct sctp_transport, gfp);
+       if (!transport)
+               goto fail;
+
+       if (!sctp_transport_init(transport, addr, gfp))
+               goto fail_init;
+
+       transport->malloced = 1;
+       SCTP_DBG_OBJCNT_INC(transport);
+
+       return transport;
+
+fail_init:
+       kfree(transport);
+
+fail:
+       return NULL;
+}
+
 /* This transport is no longer needed.  Free up if possible, or
  * delay until it last reference count.
  */
@@ -155,13 +154,23 @@
        if (del_timer(&transport->hb_timer))
                sctp_transport_put(transport);
 
+       /* Delete the T3_rtx timer if it's active.
+        * There is no point in not doing this now and letting
+        * structure hang around in memory since we know
+        * the tranport is going away.
+        */
+       if (timer_pending(&transport->T3_rtx_timer) &&
+           del_timer(&transport->T3_rtx_timer))
+               sctp_transport_put(transport);
+
+
        sctp_transport_put(transport);
 }
 
 /* Destroy the transport data structure.
  * Assumes there are no more users of this structure.
  */
-void sctp_transport_destroy(struct sctp_transport *transport)
+static void sctp_transport_destroy(struct sctp_transport *transport)
 {
        SCTP_ASSERT(transport->dead, "Transport is not dead", return);
 
diff -urN linux/net/sctp/tsnmap.c linux/net/sctp/tsnmap.c
--- linux/net/sctp/tsnmap.c     2004/08/14 18:39:05     1.5.2.3
+++ linux/net/sctp/tsnmap.c     2005/01/20 02:19:26     1.5.2.4
@@ -52,29 +52,6 @@
                                     int *started, __u16 *start,
                                     int *ended, __u16 *end);
 
-/* Create a new sctp_tsnmap.
- * Allocate room to store at least 'len' contiguous TSNs.
- */
-struct sctp_tsnmap *sctp_tsnmap_new(__u16 len, __u32 initial_tsn, int gfp)
-{
-       struct sctp_tsnmap *retval;
-
-       retval = kmalloc(sizeof(struct sctp_tsnmap) +
-                        sctp_tsnmap_storage_size(len), gfp);
-       if (!retval)
-               goto fail;
-
-       if (!sctp_tsnmap_init(retval, len, initial_tsn))
-               goto fail_map;
-       retval->malloced = 1;
-       return retval;
-
-fail_map:
-       kfree(retval);
-fail:
-       return NULL;
-}
-
 /* Initialize a block of memory as a tsnmap.  */
 struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *map, __u16 len,
                                     __u32 initial_tsn)
@@ -168,16 +145,9 @@
 }
 
 
-/* Dispose of a tsnmap.  */
-void sctp_tsnmap_free(struct sctp_tsnmap *map)
-{
-       if (map->malloced)
-               kfree(map);
-}
-
 /* Initialize a Gap Ack Block iterator from memory being provided.  */
-void sctp_tsnmap_iter_init(const struct sctp_tsnmap *map,
-                          struct sctp_tsnmap_iter *iter)
+SCTP_STATIC void sctp_tsnmap_iter_init(const struct sctp_tsnmap *map,
+                                      struct sctp_tsnmap_iter *iter)
 {
        /* Only start looking one past the Cumulative TSN Ack Point.  */
        iter->start = map->cumulative_tsn_ack_point + 1;
@@ -186,8 +156,9 @@
 /* Get the next Gap Ack Blocks. Returns 0 if there was not another block
  * to get.
  */
-int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map,
-       struct sctp_tsnmap_iter *iter, __u16 *start, __u16 *end)
+SCTP_STATIC int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map,
+                                        struct sctp_tsnmap_iter *iter,
+                                        __u16 *start, __u16 *end)
 {
        int started, ended;
        __u16 _start, _end, offset;
diff -urN linux/net/sctp/ulpevent.c linux/net/sctp/ulpevent.c
--- linux/net/sctp/ulpevent.c   2004/11/19 00:29:09     1.8.2.4
+++ linux/net/sctp/ulpevent.c   2005/01/20 02:19:26     1.8.2.5
@@ -65,8 +65,16 @@
  */
 }
 
+/* Initialize an ULP event from an given skb.  */
+SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
+{
+       memset(event, 0, sizeof(struct sctp_ulpevent));
+       event->msg_flags = msg_flags;
+}
+
 /* Create a new sctp_ulpevent.  */
-struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags, int gfp)
+SCTP_STATIC struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags,
+                                                   int gfp)
 {
        struct sctp_ulpevent *event;
        struct sk_buff *skb;
@@ -84,13 +92,6 @@
        return NULL;
 }
 
-/* Initialize an ULP event from an given skb.  */
-void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
-{
-       memset(event, 0, sizeof(struct sctp_ulpevent));
-       event->msg_flags = msg_flags;
-}
-
 /* Is this a MSG_NOTIFICATION?  */
 int sctp_ulpevent_is_notification(const struct sctp_ulpevent *event)
 {
@@ -322,7 +323,7 @@
        memcpy(&spc->spc_aaddr, aaddr, sizeof(struct sockaddr_storage));
 
        /* Map ipv4 address into v4-mapped-on-v6 address.  */
-       sctp_get_pf_specific(asoc->base.sk->sk_family)->addr_v4map(
+       sctp_get_pf_specific(asoc->base.sk->family)->addr_v4map(
                                        sctp_sk(asoc->base.sk),
                                        (union sctp_addr *)&spc->spc_aaddr);
 
diff -urN linux/net/sctp/ulpqueue.c linux/net/sctp/ulpqueue.c
--- linux/net/sctp/ulpqueue.c   2004/11/19 00:29:09     1.10.2.4
+++ linux/net/sctp/ulpqueue.c   2005/01/20 02:19:26     1.10.2.5
@@ -56,25 +56,6 @@
 
 /* 1st Level Abstractions */
 
-/* Create a new ULP queue.  */
-struct sctp_ulpq *sctp_ulpq_new(struct sctp_association *asoc, int gfp)
-{
-       struct sctp_ulpq *ulpq;
-
-       ulpq = kmalloc(sizeof(struct sctp_ulpq), gfp);
-       if (!ulpq)
-               goto fail;
-       if (!sctp_ulpq_init(ulpq, asoc))
-               goto fail_init;
-       ulpq->malloced = 1;
-       return ulpq;
-
-fail_init:
-       kfree(ulpq);
-fail:
-       return NULL;
-}
-
 /* Initialize a ULP queue from a block of memory.  */
 struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *ulpq,
                                 struct sctp_association *asoc)
@@ -92,7 +73,7 @@
 
 
 /* Flush the reassembly and ordering queues.  */
-void sctp_ulpq_flush(struct sctp_ulpq *ulpq)
+static void sctp_ulpq_flush(struct sctp_ulpq *ulpq)
 {
        struct sk_buff *skb;
        struct sctp_ulpevent *event;
@@ -163,7 +144,7 @@
        sp->pd_mode = 0;
        if (!skb_queue_empty(&sp->pd_lobby)) {
                struct list_head *list;
-               sctp_skb_list_tail(&sp->pd_lobby, &sk->sk_receive_queue);
+               sctp_skb_list_tail(&sp->pd_lobby, &sk->receive_queue);
                list = (struct list_head *)&sctp_sk(sk)->pd_lobby;
                INIT_LIST_HEAD(list);
                return 1;
@@ -189,7 +170,7 @@
        /* If the socket is just going to throw this away, do not
         * even try to deliver it.
         */
-       if (sk->dead || (sk->sk_shutdown & RCV_SHUTDOWN))
+       if (sk->dead || (sk->shutdown & RCV_SHUTDOWN))
                goto out_free;
 
        /* Check if the user wishes to receive this event.  */
@@ -202,13 +183,13 @@
         */
 
        if (!sctp_sk(sk)->pd_mode) {
-               queue = &sk->sk_receive_queue;
+               queue = &sk->receive_queue;
        } else if (ulpq->pd_mode) {
                if (event->msg_flags & MSG_NOTIFICATION)
                        queue = &sctp_sk(sk)->pd_lobby;
                else {
                        clear_pd = event->msg_flags & MSG_EOR;
-                       queue = &sk->sk_receive_queue;
+                       queue = &sk->receive_queue;
                }
        } else
                queue = &sctp_sk(sk)->pd_lobby;
@@ -229,8 +210,8 @@
        if (clear_pd)
                sctp_ulpq_clear_pd(ulpq);
 
-       if (queue == &sk->sk_receive_queue)
-               sk->sk_data_ready(sk, 0);
+       if (queue == &sk->receive_queue)
+               sk->data_ready(sk, 0);
        return 1;
 
 out_free:
@@ -837,7 +818,7 @@
 
        freed = 0;
 
-       if (skb_queue_empty(&asoc->base.sk->sk_receive_queue)) {
+       if (skb_queue_empty(&asoc->base.sk->receive_queue)) {
                freed = sctp_ulpq_renege_order(ulpq, needed);
                if (freed < needed) {
                        freed += sctp_ulpq_renege_frags(ulpq, needed - freed);
@@ -876,9 +857,9 @@
                                              SCTP_PARTIAL_DELIVERY_ABORTED,
                                              gfp);
        if (ev)
-               __skb_queue_tail(&sk->sk_receive_queue, sctp_event2skb(ev));
+               __skb_queue_tail(&sk->receive_queue, sctp_event2skb(ev));
 
        /* If there is data waiting, send it up the socket now. */
        if (sctp_ulpq_clear_pd(ulpq) || ev)
-               sk->sk_data_ready(sk, 0);
+               sk->data_ready(sk, 0);
 }

<Prev in Thread] Current Thread [Next in Thread>