svn commit: r188067 - in head/sys: netinet netinet6

Randall Stewart rrs at FreeBSD.org
Tue Feb 3 03:04:04 PST 2009


Author: rrs
Date: Tue Feb  3 11:04:03 2009
New Revision: 188067
URL: http://svn.freebsd.org/changeset/base/188067

Log:
  - Cleanup checksum code.
  - Prepare for CRC offloading, add MIB counters (RS/MT).
  - Bugfix: Disable CRC computation for IPv6 addresses with local scope (MT).
  - Bugfix: Handle close() with SO_LINGER correctly when notifications
            are generated during the close() call(MT).
  - Bugfix: Generate DRY event when sender is dry during subscription.
            Only for 1-to-1 style sockets (RS/MT)
  - Bugfix: Put vtags for the correct amount of time into time-wait (MT).
  - Bugfix: Clear vtag entries correctly on expiration (MT).
  - Bugfix: shutdown() indicates ENOTCONN when called for unconnected
            1-to-1 style sockets (MT).
  - Bugfix: In sctp Auth code (PL).
  - Add support for devices that support SCTP csum offload (igb).
  - Add missing sctp_associd to mib sysctl xsctp_tcb structure (RS)
  Obtained from:	With help from Peter Lei and Michael Tuexen

Modified:
  head/sys/netinet/sctp_auth.c
  head/sys/netinet/sctp_constants.h
  head/sys/netinet/sctp_crc32.c
  head/sys/netinet/sctp_crc32.h
  head/sys/netinet/sctp_input.c
  head/sys/netinet/sctp_os_bsd.h
  head/sys/netinet/sctp_output.c
  head/sys/netinet/sctp_pcb.c
  head/sys/netinet/sctp_pcb.h
  head/sys/netinet/sctp_sysctl.c
  head/sys/netinet/sctp_uio.h
  head/sys/netinet/sctp_usrreq.c
  head/sys/netinet/sctputil.c
  head/sys/netinet/sctputil.h
  head/sys/netinet6/sctp6_usrreq.c

Modified: head/sys/netinet/sctp_auth.c
==============================================================================
--- head/sys/netinet/sctp_auth.c	Tue Feb  3 11:00:43 2009	(r188066)
+++ head/sys/netinet/sctp_auth.c	Tue Feb  3 11:04:03 2009	(r188067)
@@ -1645,8 +1645,10 @@ sctp_auth_get_cookie_params(struct sctp_
 			bcopy(p_random->random_data, new_key->key, random_len);
 	}
 #else
-	keylen = sizeof(*p_random) + random_len + sizeof(*chunks) + num_chunks +
-	    sizeof(*hmacs) + hmacs_len;
+	keylen = sizeof(*p_random) + random_len + sizeof(*hmacs) + hmacs_len;
+	if (chunks != NULL) {
+		keylen += sizeof(*chunks) + num_chunks;
+	}
 	new_key = sctp_alloc_key(keylen);
 	if (new_key != NULL) {
 		/* copy in the RANDOM */

Modified: head/sys/netinet/sctp_constants.h
==============================================================================
--- head/sys/netinet/sctp_constants.h	Tue Feb  3 11:00:43 2009	(r188066)
+++ head/sys/netinet/sctp_constants.h	Tue Feb  3 11:04:03 2009	(r188067)
@@ -37,8 +37,15 @@ __FBSDID("$FreeBSD$");
 #define __sctp_constants_h__
 
 /* IANA assigned port number for SCTP over UDP encapsulation */
-#define SCTP_OVER_UDP_TUNNELING_PORT 9899
-
+/* For freebsd we cannot bind the port at
+ * startup. Otherwise what will happen is
+ * we really won't be bound. The user must
+ * put it into the sysctl... or we need
+ * to build a special timer for this to allow
+ * us to wait 1 second or so after the system
+ * comes up.
+ */
+#define SCTP_OVER_UDP_TUNNELING_PORT 0
 /* Number of packets to get before sack sent by default */
 #define SCTP_DEFAULT_SACK_FREQ 2
 
@@ -310,10 +317,6 @@ __FBSDID("$FreeBSD$");
 
 #define SCTP_PARTIAL_DELIVERY_SHIFT 1
 
-/* Minimum number of bytes read by user before we
- * condsider doing a rwnd update
- */
-
 /*
  * default HMAC for cookies, etc... use one of the AUTH HMAC id's
  * SCTP_HMAC is the HMAC_ID to use
@@ -323,21 +326,6 @@ __FBSDID("$FreeBSD$");
 #define SCTP_SIGNATURE_SIZE	SCTP_AUTH_DIGEST_LEN_SHA1
 #define SCTP_SIGNATURE_ALOC_SIZE SCTP_SIGNATURE_SIZE
 
-/* DEFINE HERE WHAT CRC YOU WANT TO USE */
-#define SCTP_USECRC_RFC2960  1
-/* #define SCTP_USECRC_FLETCHER 1 */
-/* #define SCTP_USECRC_SSHCRC32 1 */
-/* #define SCTP_USECRC_FASTCRC32 1 */
-/* #define SCTP_USECRC_CRC32 1 */
-/* #define SCTP_USECRC_TCP32 1 */
-/* #define SCTP_USECRC_CRC16SMAL 1 */
-/* #define SCTP_USECRC_CRC16 1 */
-/* #define SCTP_USECRC_MODADLER 1 */
-
-#ifndef SCTP_ADLER32_BASE
-#define SCTP_ADLER32_BASE 65521
-#endif
-
 /*
  * the SCTP protocol signature this includes the version number encoded in
  * the last 4 bits of the signature.
@@ -619,43 +607,16 @@ __FBSDID("$FreeBSD$");
 
 
 
-/*
- * Number of ticks before the soxwakeup() event that is delayed is sent AFTER
- * the accept() call
- */
-
-/*
- * Of course we really don't collect stale cookies, being folks of decerning
- * taste. However we do count them, if we get too many before the association
- * comes up.. we give up. Below is the constant that dictates when we give it
- * up...this is a implemenation dependent treatment. In ours we do not ask
- * for a extension of time, but just retry this many times...
- */
-
 /* max number of TSN's dup'd that I will hold */
 #define SCTP_MAX_DUP_TSNS	20
 
 /*
  * Here we define the types used when setting the retry amounts.
  */
-/* constants for type of set */
-
-/* Maximum TSN's we will summarize in a drop report */
-
 /* How many drop re-attempts we make on  INIT/COOKIE-ECHO */
 #define SCTP_RETRY_DROPPED_THRESH 4
 
 /*
- * And the max we will keep a history of in the tcb which MUST be lower than
- * 256.
- */
-
-/*
- * Here we define the default timers and the default number of attemts we
- * make for each respective side (send/init).
- */
-
-/*
  * Maxmium number of chunks a single association can have on it. Note that
  * this is a squishy number since the count can run over this if the user
  * sends a large message down .. the fragmented chunks don't count until
@@ -763,7 +724,7 @@ __FBSDID("$FreeBSD$");
 #define SCTP_DEBUG_INDATA1	0x01000000
 #define SCTP_DEBUG_INDATA2	0x02000000	/* unused */
 #define SCTP_DEBUG_INDATA3	0x04000000	/* unused */
-#define SCTP_DEBUG_INDATA4	0x08000000	/* unused */
+#define SCTP_DEBUG_CRCOFFLOAD	0x08000000	/* unused */
 #define SCTP_DEBUG_USRREQ1	0x10000000	/* unused */
 #define SCTP_DEBUG_USRREQ2	0x20000000	/* unused */
 #define SCTP_DEBUG_PEEL1	0x40000000
@@ -783,7 +744,7 @@ __FBSDID("$FreeBSD$");
 
 #define SCTP_INITIAL_CWND 4380
 
-#define SCTP_DEFAULT_MTU 1500	/* emegency default MTU */
+#define SCTP_DEFAULT_MTU 1500	/* emergency default MTU */
 /* amount peer is obligated to have in rwnd or I will abort */
 #define SCTP_MIN_RWND	1500
 
@@ -996,13 +957,6 @@ __FBSDID("$FreeBSD$");
  */
 #define SCTP_STACK_VTAG_HASH_SIZE   32
 
-
-/*
- * If we use the per-endpoint model than we do not have a hash table of
- * entries but instead have a single head pointer and we must crawl through
- * the entire list.
- */
-
 /*
  * Number of seconds of time wait for a vtag.
  */

Modified: head/sys/netinet/sctp_crc32.c
==============================================================================
--- head/sys/netinet/sctp_crc32.c	Tue Feb  3 11:00:43 2009	(r188066)
+++ head/sys/netinet/sctp_crc32.c	Tue Feb  3 11:04:03 2009	(r188067)
@@ -34,12 +34,16 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/uio.h>
+#include <netinet/sctp.h>
 #include <netinet/sctp_os.h>
 #include <netinet/sctp_crc32.h>
+#include <netinet/sctp_pcb.h>
 
-#ifndef SCTP_USE_ADLER32
-
-
+#if !defined(SCTP_WITH_NO_CSUM)
 /**
  *
  * Routine Description:
@@ -80,12 +84,14 @@ __FBSDID("$FreeBSD$");
  * The following CRC lookup table was generated automagically using the
  * following model parameters:
  *
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
  */
 
 uint32_t sctp_crc_tableil8_o32[256] =
@@ -134,12 +140,14 @@ uint32_t sctp_crc_tableil8_o32[256] =
  * The following CRC lookup table was generated automagically using the
  * following model parameters:
  *
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
  */
 
 uint32_t sctp_crc_tableil8_o40[256] =
@@ -188,12 +196,14 @@ uint32_t sctp_crc_tableil8_o40[256] =
  * The following CRC lookup table was generated automagically using the
  * following model parameters:
  *
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
  */
 
 uint32_t sctp_crc_tableil8_o48[256] =
@@ -242,12 +252,14 @@ uint32_t sctp_crc_tableil8_o48[256] =
  * The following CRC lookup table was generated automagically using the
  * following model parameters:
  *
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
  */
 
 uint32_t sctp_crc_tableil8_o56[256] =
@@ -296,12 +308,14 @@ uint32_t sctp_crc_tableil8_o56[256] =
  * The following CRC lookup table was generated automagically using the
  * following model parameters:
  *
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
  */
 
 uint32_t sctp_crc_tableil8_o64[256] =
@@ -350,12 +364,14 @@ uint32_t sctp_crc_tableil8_o64[256] =
  * The following CRC lookup table was generated automagically using the
  * following model parameters:
  *
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
  */
 
 uint32_t sctp_crc_tableil8_o72[256] =
@@ -404,12 +420,14 @@ uint32_t sctp_crc_tableil8_o72[256] =
  * The following CRC lookup table was generated automagically using the
  * following model parameters:
  *
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
  */
 
 uint32_t sctp_crc_tableil8_o80[256] =
@@ -458,12 +476,14 @@ uint32_t sctp_crc_tableil8_o80[256] =
  * The following CRC lookup table was generated automagically using the
  * following model parameters:
  *
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
  */
 
 uint32_t sctp_crc_tableil8_o88[256] =
@@ -506,6 +526,7 @@ uint32_t sctp_crc_tableil8_o88[256] =
  * end of the CRC lookup table crc_tableil8_o88
  */
 
+
 static uint32_t
 sctp_crc32c_sb8_64_bit(uint32_t crc,
     unsigned char *p_buf,
@@ -578,7 +599,7 @@ sctp_crc32c_sb8_64_bit(uint32_t crc,
  *
  *		none
  */
-uint32_t
+static uint32_t
 update_crc32(uint32_t crc32c,
     unsigned char *buffer,
     unsigned int length)
@@ -662,7 +683,7 @@ uint32_t sctp_crc_c[256] = {
 
 #define SCTP_CRC32C(c,d) (c=(c>>8)^sctp_crc_c[(c^(d))&0xFF])
 
-uint32_t
+static uint32_t
 old_update_crc32(uint32_t crc32c,
     unsigned char *buffer,
     unsigned int length)
@@ -676,8 +697,8 @@ old_update_crc32(uint32_t crc32c,
 }
 
 
-uint32_t
-sctp_csum_finalize(uint32_t crc32c)
+static uint32_t
+sctp_finalize_crc32(uint32_t crc32c)
 {
 	uint32_t result;
 
@@ -709,4 +730,88 @@ sctp_csum_finalize(uint32_t crc32c)
 	return (crc32c);
 }
 
+#endif				/* !defined(SCTP_WITH_NO_CSUM) */
+
+#if defined(SCTP_WITH_NO_CSUM)
+uint32_t
+sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
+{
+	return (0);
+}
+
+#else
+uint32_t
+sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
+{
+	/*
+	 * given a mbuf chain with a packetheader offset by 'offset'
+	 * pointing at a sctphdr (with csum set to 0) go through the chain
+	 * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also
+	 * has a side bonus as it will calculate the total length of the
+	 * mbuf chain. Note: if offset is greater than the total mbuf
+	 * length, checksum=1, pktlen=0 is returned (ie. no real error code)
+	 */
+	uint32_t base = 0xffffffff;
+	struct mbuf *at;
+
+	at = m;
+	/* find the correct mbuf and offset into mbuf */
+	while ((at != NULL) && (offset > (uint32_t) SCTP_BUF_LEN(at))) {
+		offset -= SCTP_BUF_LEN(at);	/* update remaining offset
+						 * left */
+		at = SCTP_BUF_NEXT(at);
+	}
+	while (at != NULL) {
+		if ((SCTP_BUF_LEN(at) - offset) > 0) {
+			if ((SCTP_BUF_LEN(at) - offset) < 4) {
+				/* Use old method if less than 4 bytes */
+				base = old_update_crc32(base,
+				    (unsigned char *)(SCTP_BUF_AT(at, offset)),
+				    (unsigned int)(SCTP_BUF_LEN(at) - offset));
+			} else {
+				base = update_crc32(base,
+				    (unsigned char *)(SCTP_BUF_AT(at, offset)),
+				    (unsigned int)(SCTP_BUF_LEN(at) - offset));
+			}
+			/* we only offset once into the first mbuf */
+		}
+		if (offset) {
+			if (offset < (uint32_t) SCTP_BUF_LEN(at))
+				offset = 0;
+			else
+				offset -= SCTP_BUF_LEN(at);
+		}
+		at = SCTP_BUF_NEXT(at);
+	}
+	base = sctp_finalize_crc32(base);
+	return (base);
+}
+
 #endif
+
+void
+sctp_delayed_cksum(struct mbuf *m)
+{
+	struct ip *ip;
+	uint32_t checksum;
+	uint32_t offset;
+
+	ip = mtod(m, struct ip *);
+	offset = ip->ip_hl << 2;
+	checksum = sctp_calculate_cksum(m, offset);
+	SCTP_STAT_DECR(sctps_sendhwcrc);
+	SCTP_STAT_INCR(sctps_sendswcrc);
+	offset += offsetof(struct sctphdr, checksum);
+
+	if (offset + sizeof(uint32_t) > (uint32_t) (m->m_len)) {
+		printf("delayed m_pullup, m->len: %d  off: %d  p: %d\n",
+		    (uint32_t) m->m_len, offset, ip->ip_p);
+		/*
+		 * XXX this shouldn't happen, but if it does, the correct
+		 * behavior may be to insert the checksum in the appropriate
+		 * next mbuf in the chain.
+		 */
+		return;
+	}
+	*(uint32_t *) (m->m_data + offset) = checksum;
+}

Modified: head/sys/netinet/sctp_crc32.h
==============================================================================
--- head/sys/netinet/sctp_crc32.h	Tue Feb  3 11:00:43 2009	(r188066)
+++ head/sys/netinet/sctp_crc32.h	Tue Feb  3 11:04:03 2009	(r188067)
@@ -36,16 +36,10 @@ __FBSDID("$FreeBSD$");
 #ifndef __crc32c_h__
 #define __crc32c_h__
 
-#ifndef SCTP_USE_ADLER32
-
 #if defined(_KERNEL) || defined(__Userspace__)
-uint32_t update_crc32(uint32_t, unsigned char *, unsigned int);
-
-uint32_t old_update_crc32(uint32_t, unsigned char *, unsigned int);
-
-uint32_t sctp_csum_finalize(uint32_t);
-
+uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
+void sctp_delayed_cksum(struct mbuf *);
 
 #endif				/* _KERNEL */
-#endif				/* !SCTP_USE_ADLER32 */
+
 #endif				/* __crc32c_h__ */

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c	Tue Feb  3 11:00:43 2009	(r188066)
+++ head/sys/netinet/sctp_input.c	Tue Feb  3 11:04:03 2009	(r188067)
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet/sctp_asconf.h>
 #include <netinet/sctp_bsd_addr.h>
 #include <netinet/sctp_timer.h>
+#include <netinet/sctp_crc32.h>
 #include <netinet/udp.h>
 
 
@@ -1384,14 +1385,6 @@ sctp_process_cookie_existing(struct mbuf
 			/* FOOBAR */
 			return (NULL);
 		}
-		/* pre-reserve some space */
-#ifdef INET6
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
-#else
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
-#endif
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
 		/* Set the len */
 		SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
 		ph = mtod(op_err, struct sctp_paramhdr *);
@@ -2504,15 +2497,6 @@ sctp_handle_cookie_echo(struct mbuf *m, 
 			/* FOOBAR */
 			return (NULL);
 		}
-		/* pre-reserve some space */
-#ifdef INET6
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
-#else
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
-#endif
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
-
 		/* Set the len */
 		SCTP_BUF_LEN(op_err) = sizeof(struct sctp_stale_cookie_msg);
 		scm = mtod(op_err, struct sctp_stale_cookie_msg *);
@@ -2598,9 +2582,9 @@ sctp_handle_cookie_echo(struct mbuf *m, 
 			}
 		}
 	}
-	if (to == NULL)
+	if (to == NULL) {
 		return (NULL);
-
+	}
 	cookie_len -= SCTP_SIGNATURE_SIZE;
 	if (*stcb == NULL) {
 		/* this is the "normal" case... get a new TCB */
@@ -5594,7 +5578,6 @@ sctp_input_with_port(i_pak, off, port)
 	int refcount_up = 0;
 	int length, mlen, offset;
 
-
 	if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) {
 		SCTP_RELEASE_PKT(i_pak);
 		return;
@@ -5642,6 +5625,11 @@ sctp_input_with_port(i_pak, off, port)
 		}
 		ip = mtod(m, struct ip *);
 	}
+	/* validate mbuf chain length with IP payload length */
+	if (mlen < (SCTP_GET_IPV4_LENGTH(ip) - iphlen)) {
+		SCTP_STAT_INCR(sctps_hdrops);
+		goto bad;
+	}
 	sh = (struct sctphdr *)((caddr_t)ip + iphlen);
 	ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(*sh));
 	SCTPDBG(SCTP_DEBUG_INPUT1,
@@ -5659,15 +5647,26 @@ sctp_input_with_port(i_pak, off, port)
 		goto bad;
 	}
 	/* validate SCTP checksum */
+	SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
+	    "sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
+	    m->m_pkthdr.len,
+	    if_name(m->m_pkthdr.rcvif),
+	    m->m_pkthdr.csum_flags);
+	if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
+		SCTP_STAT_INCR(sctps_recvhwcrc);
+		goto sctp_skip_csum_4;
+	}
 	check = sh->checksum;	/* save incoming checksum */
 	if ((check == 0) && (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback)) &&
 	    ((ip->ip_src.s_addr == ip->ip_dst.s_addr) ||
 	    (SCTP_IS_IT_LOOPBACK(m)))
 	    ) {
+		SCTP_STAT_INCR(sctps_recvnocrc);
 		goto sctp_skip_csum_4;
 	}
 	sh->checksum = 0;	/* prepare for calc */
-	calc_check = sctp_calculate_sum(m, &mlen, iphlen);
+	calc_check = sctp_calculate_cksum(m, iphlen);
+	SCTP_STAT_INCR(sctps_recvswcrc);
 	if (calc_check != check) {
 		SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x  m:%p mlen:%d iphlen:%d\n",
 		    calc_check, check, m, mlen, iphlen);
@@ -5699,11 +5698,6 @@ sctp_skip_csum_4:
 		SCTP_STAT_INCR(sctps_hdrops);
 		goto bad;
 	}
-	/* validate mbuf chain length with IP payload length */
-	if (mlen < (SCTP_GET_IPV4_LENGTH(ip) - iphlen)) {
-		SCTP_STAT_INCR(sctps_hdrops);
-		goto bad;
-	}
 	/*
 	 * Locate pcb and tcb for datagram sctp_findassociation_addr() wants
 	 * IP/SCTP/first chunk header...

Modified: head/sys/netinet/sctp_os_bsd.h
==============================================================================
--- head/sys/netinet/sctp_os_bsd.h	Tue Feb  3 11:00:43 2009	(r188066)
+++ head/sys/netinet/sctp_os_bsd.h	Tue Feb  3 11:04:03 2009	(r188067)
@@ -154,11 +154,8 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
 #define MOD_IPSEC ipsec
 
 /* then define the macro(s) that hook into the vimage macros */
-#if defined(__FreeBSD__) && __FreeBSD_version >= 800056
 #define MODULE_GLOBAL(__MODULE, __SYMBOL) V_ ## __SYMBOL
-#else
-#define MODULE_GLOBAL(__MODULE, __SYMBOL) (__SYMBOL)
-#endif
+
 /*
  *
  */

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c	Tue Feb  3 11:00:43 2009	(r188066)
+++ head/sys/netinet/sctp_output.c	Tue Feb  3 11:04:03 2009	(r188067)
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet/sctp_indata.h>
 #include <netinet/sctp_bsd_addr.h>
 #include <netinet/sctp_input.h>
+#include <netinet/sctp_crc32.h>
 #include <netinet/udp.h>
 #include <machine/in_cksum.h>
 
@@ -5213,6 +5214,9 @@ sctp_lowlevel_chunk_output(struct sctp_i
     int ecn_ok,
     struct sctp_tmit_chunk *chk,
     int out_of_asoc_ok,
+    uint16_t src_port,
+    uint16_t dest_port,
+    uint32_t v_tag,
     uint16_t port,
     int so_locked,
 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
@@ -5237,7 +5241,6 @@ sctp_lowlevel_chunk_output(struct sctp_i
 	struct mbuf *newm;
 	struct sctphdr *sctphdr;
 	int packet_length;
-	uint32_t csum;
 	int ret;
 	uint32_t vrf_id;
 	sctp_route_t *ro = NULL;
@@ -5263,51 +5266,27 @@ sctp_lowlevel_chunk_output(struct sctp_i
 	if ((auth != NULL) && (stcb != NULL)) {
 		sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb, auth_keyid);
 	}
-	/* Calculate the csum and fill in the length of the packet */
-	sctphdr = mtod(m, struct sctphdr *);
-	if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
-	    (stcb) &&
-	    (to->sa_family == AF_INET) &&
-	    (stcb->asoc.loopback_scope)) {
-		sctphdr->checksum = 0;
-		/*
-		 * This can probably now be taken out since my audit shows
-		 * no more bad pktlen's coming in. But we will wait a while
-		 * yet.
-		 */
-		packet_length = sctp_calculate_len(m);
-	} else {
-		sctphdr->checksum = 0;
-		csum = sctp_calculate_sum(m, &packet_length, 0);
-		sctphdr->checksum = csum;
-	}
-
 	if (to->sa_family == AF_INET) {
 		struct ip *ip = NULL;
 		sctp_route_t iproute;
 		uint8_t tos_value;
+		int len;
 
+		len = sizeof(struct ip) + sizeof(struct sctphdr);
 		if (port) {
-			newm = sctp_get_mbuf_for_msg(sizeof(struct ip) + sizeof(struct udphdr), 1, M_DONTWAIT, 1, MT_DATA);
-		} else {
-			newm = sctp_get_mbuf_for_msg(sizeof(struct ip), 1, M_DONTWAIT, 1, MT_DATA);
+			len += sizeof(struct udphdr);
 		}
+		newm = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
 		if (newm == NULL) {
 			sctp_m_freem(m);
 			SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
 			return (ENOMEM);
 		}
-		if (port) {
-			SCTP_ALIGN_TO_END(newm, sizeof(struct ip) + sizeof(struct udphdr));
-			SCTP_BUF_LEN(newm) = sizeof(struct ip) + sizeof(struct udphdr);
-			packet_length += sizeof(struct ip) + sizeof(struct udphdr);
-		} else {
-			SCTP_ALIGN_TO_END(newm, sizeof(struct ip));
-			SCTP_BUF_LEN(newm) = sizeof(struct ip);
-			packet_length += sizeof(struct ip);
-		}
+		SCTP_ALIGN_TO_END(newm, len);
+		SCTP_BUF_LEN(newm) = len;
 		SCTP_BUF_NEXT(newm) = m;
 		m = newm;
+		packet_length = sctp_calculate_len(m);
 		ip = mtod(m, struct ip *);
 		ip->ip_v = IPVERSION;
 		ip->ip_hl = (sizeof(struct ip) >> 2);
@@ -5401,12 +5380,21 @@ sctp_lowlevel_chunk_output(struct sctp_i
 			}
 		}
 		if (port) {
-			udp = (struct udphdr *)(ip + 1);
+			udp = (struct udphdr *)((caddr_t)ip + sizeof(struct ip));
 			udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
 			udp->uh_dport = port;
 			udp->uh_ulen = htons(packet_length - sizeof(struct ip));
 			udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
+			sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr));
+		} else {
+			sctphdr = (struct sctphdr *)((caddr_t)ip + sizeof(struct ip));
 		}
+
+		sctphdr->src_port = src_port;
+		sctphdr->dest_port = dest_port;
+		sctphdr->v_tag = v_tag;
+		sctphdr->checksum = 0;
+
 		/*
 		 * If source address selection fails and we find no route
 		 * then the ip_output should fail as well with a
@@ -5517,7 +5505,25 @@ sctp_lowlevel_chunk_output(struct sctp_i
 #endif
 		SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
 		if (port) {
+			if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+			    (stcb) &&
+			    (stcb->asoc.loopback_scope))) {
+				sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip) + sizeof(struct udphdr));
+				SCTP_STAT_INCR(sctps_sendswcrc);
+			} else {
+				SCTP_STAT_INCR(sctps_sendnocrc);
+			}
 			SCTP_ENABLE_UDP_CSUM(o_pak);
+		} else {
+			if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+			    (stcb) &&
+			    (stcb->asoc.loopback_scope))) {
+				m->m_pkthdr.csum_flags = CSUM_SCTP;
+				m->m_pkthdr.csum_data = 0;	/* FIXME MT */
+				SCTP_STAT_INCR(sctps_sendhwcrc);
+			} else {
+				SCTP_STAT_INCR(sctps_sendnocrc);
+			}
 		}
 		/* send it out.  table id is taken from stcb */
 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@@ -5591,6 +5597,7 @@ sctp_lowlevel_chunk_output(struct sctp_i
 		struct sockaddr_in6 lsa6_storage;
 		int error;
 		u_short prev_port = 0;
+		int len;
 
 		if (net != NULL) {
 			flowlabel = net->tos_flowlabel;
@@ -5598,27 +5605,21 @@ sctp_lowlevel_chunk_output(struct sctp_i
 			flowlabel = ((struct in6pcb *)inp)->in6p_flowinfo;
 		}
 
+		len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr);
 		if (port) {
-			newm = sctp_get_mbuf_for_msg(sizeof(struct ip6_hdr) + sizeof(struct udphdr), 1, M_DONTWAIT, 1, MT_DATA);
-		} else {
-			newm = sctp_get_mbuf_for_msg(sizeof(struct ip6_hdr), 1, M_DONTWAIT, 1, MT_DATA);
+			len += sizeof(struct udphdr);
 		}
+		newm = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
 		if (newm == NULL) {
 			sctp_m_freem(m);
 			SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
 			return (ENOMEM);
 		}
-		if (port) {
-			SCTP_ALIGN_TO_END(newm, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
-			SCTP_BUF_LEN(newm) = sizeof(struct ip6_hdr) + sizeof(struct udphdr);
-			packet_length += sizeof(struct ip6_hdr) + sizeof(struct udphdr);
-		} else {
-			SCTP_ALIGN_TO_END(newm, sizeof(struct ip6_hdr));
-			SCTP_BUF_LEN(newm) = sizeof(struct ip6_hdr);
-			packet_length += sizeof(struct ip6_hdr);
-		}
+		SCTP_ALIGN_TO_END(newm, len);
+		SCTP_BUF_LEN(newm) = len;
 		SCTP_BUF_NEXT(newm) = m;
 		m = newm;
+		packet_length = sctp_calculate_len(m);
 
 		ip6h = mtod(m, struct ip6_hdr *);
 		/*
@@ -5763,12 +5764,21 @@ sctp_lowlevel_chunk_output(struct sctp_i
 		ip6h->ip6_src = lsa6->sin6_addr;
 
 		if (port) {
-			udp = (struct udphdr *)(ip6h + 1);
+			udp = (struct udphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr));
 			udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
 			udp->uh_dport = port;
 			udp->uh_ulen = htons(packet_length - sizeof(struct ip6_hdr));
 			udp->uh_sum = 0;
+			sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr));
+		} else {
+			sctphdr = (struct sctphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr));
 		}
+
+		sctphdr->src_port = src_port;
+		sctphdr->dest_port = dest_port;
+		sctphdr->v_tag = v_tag;
+		sctphdr->checksum = 0;
+
 		/*
 		 * We set the hop limit now since there is a good chance
 		 * that our ro pointer is now filled
@@ -5805,9 +5815,27 @@ sctp_lowlevel_chunk_output(struct sctp_i
 #endif
 		SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
 		if (port) {
+			if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+			    (stcb) &&
+			    (stcb->asoc.loopback_scope))) {
+				sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
+				SCTP_STAT_INCR(sctps_sendswcrc);
+			} else {
+				SCTP_STAT_INCR(sctps_sendnocrc);
+			}
 			if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), packet_length - sizeof(struct ip6_hdr))) == 0) {
 				udp->uh_sum = 0xffff;
 			}
+		} else {
+			if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+			    (stcb) &&
+			    (stcb->asoc.loopback_scope))) {
+				m->m_pkthdr.csum_flags = CSUM_SCTP;
+				m->m_pkthdr.csum_data = 0;	/* FIXME MT */
+				SCTP_STAT_INCR(sctps_sendhwcrc);
+			} else {
+				SCTP_STAT_INCR(sctps_sendnocrc);
+			}
 		}
 		/* send it out. table id is taken from stcb */
 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@@ -5905,7 +5933,7 @@ sctp_send_initiate(struct sctp_inpcb *in
 {
 	struct mbuf *m, *m_at, *mp_last;
 	struct sctp_nets *net;
-	struct sctp_init_msg *initm;
+	struct sctp_init_chunk *init;
 	struct sctp_supported_addr_param *sup_addr;
 	struct sctp_adaptation_layer_indication *ali;
 	struct sctp_ecn_supported_param *ecn;
@@ -5961,7 +5989,7 @@ sctp_send_initiate(struct sctp_inpcb *in
 		SCTPDBG(SCTP_DEBUG_OUTPUT4, "Sending INIT - mbuf?\n");
 		return;
 	}
-	SCTP_BUF_LEN(m) = sizeof(struct sctp_init_msg);
+	SCTP_BUF_LEN(m) = sizeof(struct sctp_init_chunk);
 	/*
 	 * assume peer supports asconf in order to be able to queue local
 	 * address changes while an INIT is in flight and before the assoc
@@ -5969,28 +5997,24 @@ sctp_send_initiate(struct sctp_inpcb *in
 	 */
 	stcb->asoc.peer_supports_asconf = 1;
 	/* Now lets put the SCTP header in place */
-	initm = mtod(m, struct sctp_init_msg *);
-	initm->sh.src_port = inp->sctp_lport;
-	initm->sh.dest_port = stcb->rport;
-	initm->sh.v_tag = 0;
-	initm->sh.checksum = 0;	/* calculate later */
+	init = mtod(m, struct sctp_init_chunk *);
 	/* now the chunk header */
-	initm->msg.ch.chunk_type = SCTP_INITIATION;
-	initm->msg.ch.chunk_flags = 0;
+	init->ch.chunk_type = SCTP_INITIATION;
+	init->ch.chunk_flags = 0;
 	/* fill in later from mbuf we build */
-	initm->msg.ch.chunk_length = 0;
+	init->ch.chunk_length = 0;
 	/* place in my tag */
-	initm->msg.init.initiate_tag = htonl(stcb->asoc.my_vtag);
+	init->init.initiate_tag = htonl(stcb->asoc.my_vtag);
 	/* set up some of the credits. */
-	initm->msg.init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(inp->sctp_socket),
+	init->init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(inp->sctp_socket),
 	    SCTP_MINIMAL_RWND));
 
-	initm->msg.init.num_outbound_streams = htons(stcb->asoc.pre_open_streams);
-	initm->msg.init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams);
-	initm->msg.init.initial_tsn = htonl(stcb->asoc.init_seq_number);
+	init->init.num_outbound_streams = htons(stcb->asoc.pre_open_streams);
+	init->init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams);
+	init->init.initial_tsn = htonl(stcb->asoc.init_seq_number);
 	/* now the address restriction */
-	sup_addr = (struct sctp_supported_addr_param *)((caddr_t)initm +
-	    sizeof(*initm));
+	sup_addr = (struct sctp_supported_addr_param *)((caddr_t)init +
+	    sizeof(*init));
 	sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
 #ifdef INET6
 	/* we support 2 types: IPv6/IPv4 */
@@ -6004,7 +6028,6 @@ sctp_send_initiate(struct sctp_inpcb *in
 	sup_addr->addr_type[1] = htons(0);	/* this is the padding */
 #endif
 	SCTP_BUF_LEN(m) += sizeof(*sup_addr) + sizeof(uint16_t);
-
 	/* adaptation layer indication parameter */
 	ali = (struct sctp_adaptation_layer_indication *)((caddr_t)sup_addr + sizeof(*sup_addr) + sizeof(uint16_t));
 	ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
@@ -6013,6 +6036,16 @@ sctp_send_initiate(struct sctp_inpcb *in
 	SCTP_BUF_LEN(m) += sizeof(*ali);
 	ecn = (struct sctp_ecn_supported_param *)((caddr_t)ali + sizeof(*ali));
 
+	if (SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly)) {
+		/* Add NAT friendly parameter */
+		struct sctp_paramhdr *ph;
+
+		ph = (struct sctp_paramhdr *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
+		ph->param_type = htons(SCTP_HAS_NAT_SUPPORT);
+		ph->param_length = htons(sizeof(struct sctp_paramhdr));
+		SCTP_BUF_LEN(m) += sizeof(struct sctp_paramhdr);
+		ecn = (struct sctp_ecn_supported_param *)((caddr_t)ph + sizeof(*ph));
+	}
 	/* now any cookie time extensions */
 	if (stcb->asoc.cookie_preserve_req) {
 		struct sctp_cookie_perserve_param *cookie_preserve;
@@ -6052,19 +6085,22 @@ sctp_send_initiate(struct sctp_inpcb *in
 	pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN;
 	pr_supported->chunk_types[num_ext++] = SCTP_PACKET_DROPPED;
 	pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
-	if (!SCTP_BASE_SYSCTL(sctp_auth_disable))
+	if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) {
 		pr_supported->chunk_types[num_ext++] = SCTP_AUTHENTICATION;
+	}
 	/*
 	 * EY  if the initiator supports nr_sacks, need to report that to
 	 * responder in INIT chunk
 	 */
-	if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off))
+	if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off)) {
 		pr_supported->chunk_types[num_ext++] = SCTP_NR_SELECTIVE_ACK;
+	}
 	p_len = sizeof(*pr_supported) + num_ext;
 	pr_supported->ph.param_length = htons(p_len);
 	bzero((caddr_t)pr_supported + p_len, SCTP_SIZE32(p_len) - p_len);
 	SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
 
+
 	/* ECN nonce: And now tell the peer we support ECN nonce */
 	if (SCTP_BASE_SYSCTL(sctp_ecn_nonce)) {
 		ecn_nonce = (struct sctp_ecn_nonce_supported_param *)
@@ -6073,15 +6109,6 @@ sctp_send_initiate(struct sctp_inpcb *in
 		ecn_nonce->ph.param_length = htons(sizeof(*ecn_nonce));
 		SCTP_BUF_LEN(m) += sizeof(*ecn_nonce);
 	}
-	if (SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly)) {
-		/* Add NAT friendly parameter */
-		struct sctp_paramhdr *ph;
-
-		ph = (struct sctp_paramhdr *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
-		ph->param_type = htons(SCTP_HAS_NAT_SUPPORT);
-		ph->param_length = htons(sizeof(struct sctp_paramhdr));
-		SCTP_BUF_LEN(m) += sizeof(sizeof(struct sctp_paramhdr));
-	}
 	/* add authentication parameters */
 	if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) {
 		struct sctp_auth_random *randp;
@@ -6160,7 +6187,7 @@ sctp_send_initiate(struct sctp_inpcb *in
 			mp_last = m_at;
 		p_len += SCTP_BUF_LEN(m_at);
 	}
-	initm->msg.ch.chunk_length = htons((p_len - sizeof(struct sctphdr)));
+	init->ch.chunk_length = htons(p_len);
 	/*
 	 * We sifa 0 here to NOT set IP_DF if its IPv4, we ignore the return
 	 * here since the timer will drive a retranmission.
@@ -6185,7 +6212,9 @@ sctp_send_initiate(struct sctp_inpcb *in
 	SCTPDBG(SCTP_DEBUG_OUTPUT4, "Sending INIT - calls lowlevel_output\n");
 	ret = sctp_lowlevel_chunk_output(inp, stcb, net,
 	    (struct sockaddr *)&net->ro._l_addr,
-	    m, 0, NULL, 0, 0, 0, NULL, 0, net->port, so_locked, NULL);
+	    m, 0, NULL, 0, 0, 0, NULL, 0,
+	    inp->sctp_lport, stcb->rport, htonl(0),
+	    net->port, so_locked, NULL);
 	SCTPDBG(SCTP_DEBUG_OUTPUT4, "lowlevel_output - %d\n", ret);
 	SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
 	sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, net);
@@ -6711,7 +6740,7 @@ sctp_send_initiate_ack(struct sctp_inpcb
 {
 	struct sctp_association *asoc;
 	struct mbuf *m, *m_at, *m_tmp, *m_cookie, *op_err, *mp_last;
-	struct sctp_init_msg *initackm_out;
+	struct sctp_init_ack_chunk *initack;
 	struct sctp_adaptation_layer_indication *ali;
 	struct sctp_ecn_supported_param *ecn;
 	struct sctp_prsctp_supported_param *prsctp;
@@ -6776,7 +6805,7 @@ do_a_abort:
 			sctp_m_freem(op_err);
 		return;
 	}
-	SCTP_BUF_LEN(m) = sizeof(struct sctp_init_msg);
+	SCTP_BUF_LEN(m) = sizeof(struct sctp_init_chunk);
 
 	/* the time I built cookie */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list