[rtems-libbsd commit] Update to FreeBSD head 2016-12-10

Sebastian Huber sebh at rtems.org
Tue Jan 10 10:06:13 UTC 2017


Module:    rtems-libbsd
Branch:    master
Commit:    75b706fde4cbf82bcd41a1cec319778aa0f8eb2d
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=75b706fde4cbf82bcd41a1cec319778aa0f8eb2d

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Dec  9 14:19:03 2016 +0100

Update to FreeBSD head 2016-12-10

Git mirror commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c.

---

 freebsd-org                                       |   2 +-
 freebsd/bin/hostname/hostname.c                   |  22 +-
 freebsd/contrib/tcpdump/tcpdump.c                 |  47 ++
 freebsd/lib/libc/db/btree/bt_close.c              |   3 +-
 freebsd/lib/libc/include/libc_private.h           |   1 +
 freebsd/lib/libc/net/getaddrinfo.c                |  21 +-
 freebsd/lib/libc/net/linkaddr.c                   |  52 +-
 freebsd/lib/libc/net/name6.c                      |  21 +-
 freebsd/lib/libc/stdio/fgetln.c                   |   7 +-
 freebsd/lib/libipsec/pfkey.c                      |   1 +
 freebsd/lib/libipsec/pfkey_dump.c                 |   5 +-
 freebsd/lib/libmemstat/memstat_uma.c              |   3 -
 freebsd/sbin/dhclient/clparse.c                   |   2 +
 freebsd/sbin/dhclient/dhclient.c                  |  15 +
 freebsd/sbin/dhclient/dhcpd.h                     |   2 +
 freebsd/sbin/dhclient/dispatch.c                  |  48 +-
 freebsd/sbin/dhclient/privsep.c                   |   8 +
 freebsd/sbin/dhclient/privsep.h                   |   3 +-
 freebsd/sbin/dhclient/tables.c                    |   1 +
 freebsd/sbin/ifconfig/af_inet.c                   |   2 +-
 freebsd/sbin/ifconfig/af_inet6.c                  |   2 +-
 freebsd/sbin/ifconfig/af_link.c                   |  25 +-
 freebsd/sbin/pfctl/parse.y                        |  78 ++-
 freebsd/sbin/pfctl/pfctl.c                        |   2 +-
 freebsd/sbin/pfctl/pfctl_optimize.c               |   4 +-
 freebsd/sbin/pfctl/pfctl_parser.c                 |   8 +-
 freebsd/sbin/sysctl/sysctl.c                      |   3 -
 freebsd/sys/arm/include/machine/cpufunc.h         |  46 +-
 freebsd/sys/arm/xilinx/zy7_slcr.c                 |   5 +-
 freebsd/sys/cam/cam.h                             |   2 +-
 freebsd/sys/cam/cam_ccb.h                         |   6 +
 freebsd/sys/cam/cam_periph.h                      |   1 -
 freebsd/sys/cam/scsi/scsi_all.c                   | 123 +++-
 freebsd/sys/cam/scsi/scsi_all.h                   |  48 ++
 freebsd/sys/crypto/sha1.h                         |   2 +-
 freebsd/sys/crypto/sha2/sha256.h                  |  11 +-
 freebsd/sys/crypto/sha2/sha384.h                  |  11 +-
 freebsd/sys/crypto/sha2/sha512.h                  |  11 +-
 freebsd/sys/crypto/sha2/sha512t.h                 |  22 +-
 freebsd/sys/crypto/siphash/siphash.h              |   9 +-
 freebsd/sys/crypto/skein/skein_freebsd.h          |  15 +-
 freebsd/sys/crypto/skein/skein_port.h             |  10 +
 freebsd/sys/dev/bfe/if_bfe.c                      |   2 +
 freebsd/sys/dev/e1000/if_em.c                     |  44 +-
 freebsd/sys/dev/e1000/if_igb.c                    |  19 +-
 freebsd/sys/dev/e1000/if_lem.c                    | 175 +----
 freebsd/sys/dev/mii/rgephy.c                      |  12 +-
 freebsd/sys/dev/mii/rgephyreg.h                   |   3 +
 freebsd/sys/dev/nvme/nvme.h                       |  38 +-
 freebsd/sys/dev/pci/pci.c                         | 180 ++++-
 freebsd/sys/dev/pci/pcireg.h                      |  21 +-
 freebsd/sys/dev/pci/pcivar.h                      |  13 +-
 freebsd/sys/dev/re/if_re.c                        |  10 +-
 freebsd/sys/dev/rl/if_rlreg.h                     |   5 +
 freebsd/sys/dev/tsec/if_tsec.h                    |   7 +-
 freebsd/sys/dev/usb/controller/dwc_otg.c          |  27 +-
 freebsd/sys/dev/usb/controller/dwc_otg.h          |   7 +
 freebsd/sys/dev/usb/quirk/usb_quirk.c             |  30 +-
 freebsd/sys/dev/usb/storage/umass.c               |   2 +-
 freebsd/sys/dev/usb/usb_busdma.c                  |  14 +-
 freebsd/sys/dev/usb/usb_core.c                    |  14 +
 freebsd/sys/dev/usb/usb_core.h                    |  25 +-
 freebsd/sys/dev/usb/usb_dev.c                     |   6 +-
 freebsd/sys/dev/usb/usb_device.c                  |  61 +-
 freebsd/sys/dev/usb/usb_device.h                  |   5 +-
 freebsd/sys/dev/usb/usb_freebsd.h                 |   3 +
 freebsd/sys/dev/usb/usb_generic.c                 |  15 +-
 freebsd/sys/dev/usb/usb_hub.c                     |   8 +-
 freebsd/sys/dev/usb/usb_msctest.c                 |   8 +-
 freebsd/sys/dev/usb/usb_process.c                 |  25 +-
 freebsd/sys/dev/usb/usb_request.c                 |  21 +-
 freebsd/sys/dev/usb/usb_transfer.c                |  76 ++-
 freebsd/sys/dev/usb/usb_util.c                    |   4 +-
 freebsd/sys/dev/usb/usbdi.h                       |  57 +-
 freebsd/sys/i386/include/machine/md_var.h         |   1 +
 freebsd/sys/kern/init_main.c                      |  42 +-
 freebsd/sys/kern/kern_condvar.c                   |   4 +
 freebsd/sys/kern/kern_linker.c                    |  38 +-
 freebsd/sys/kern/kern_mib.c                       |  22 +-
 freebsd/sys/kern/kern_synch.c                     |  10 +-
 freebsd/sys/kern/kern_sysctl.c                    |   2 +-
 freebsd/sys/kern/kern_time.c                      |   2 +-
 freebsd/sys/kern/kern_timeout.c                   |   4 +-
 freebsd/sys/kern/subr_bus.c                       |  74 ++-
 freebsd/sys/kern/subr_hash.c                      |   2 +-
 freebsd/sys/kern/subr_pcpu.c                      |   2 +-
 freebsd/sys/kern/subr_prf.c                       |   6 +-
 freebsd/sys/kern/subr_sleepqueue.c                |   6 +-
 freebsd/sys/kern/subr_taskqueue.c                 |  28 +-
 freebsd/sys/kern/subr_uio.c                       |   4 +-
 freebsd/sys/kern/sys_generic.c                    |   2 +-
 freebsd/sys/kern/sys_socket.c                     |   2 +-
 freebsd/sys/kern/uipc_accf.c                      |   2 +-
 freebsd/sys/kern/uipc_domain.c                    |   2 +-
 freebsd/sys/kern/uipc_mbuf.c                      |   6 +-
 freebsd/sys/kern/uipc_mbuf2.c                     |   2 +-
 freebsd/sys/kern/uipc_sockbuf.c                   |   2 +-
 freebsd/sys/kern/uipc_socket.c                    |   5 +-
 freebsd/sys/kern/uipc_syscalls.c                  | 310 ++-------
 freebsd/sys/kern/uipc_usrreq.c                    |  16 +-
 freebsd/sys/mips/include/machine/cpufunc.h        |  10 +-
 freebsd/sys/mips/include/machine/cpuregs.h        |   8 +-
 freebsd/sys/net/altq/altq_subr.c                  |   2 +-
 freebsd/sys/net/bpf_filter.c                      |  25 +-
 freebsd/sys/net/ethernet.h                        |   2 +-
 freebsd/sys/net/if.c                              |   2 +-
 freebsd/sys/net/if_arcsubr.c                      |   2 +-
 freebsd/sys/net/if_bridge.c                       |  88 ++-
 freebsd/sys/net/if_fddisubr.c                     |   2 +-
 freebsd/sys/net/if_iso88025subr.c                 |   2 +-
 freebsd/sys/net/if_llatbl.c                       |  35 +-
 freebsd/sys/net/if_llatbl.h                       |   8 -
 freebsd/sys/net/if_loop.c                         |   5 +
 freebsd/sys/net/if_var.h                          |  10 +-
 freebsd/sys/net/pfkeyv2.h                         |  11 +-
 freebsd/sys/net/raw_usrreq.c                      |   2 +-
 freebsd/sys/net/route.c                           |   9 +-
 freebsd/sys/net/route_var.h                       |   2 +
 freebsd/sys/net/rtsock.c                          |  42 +-
 freebsd/sys/netinet/cc/cc.h                       |   1 +
 freebsd/sys/netinet/cc/cc_newreno.c               |  29 +-
 freebsd/sys/netinet/if_ether.c                    | 128 ++++
 freebsd/sys/netinet/igmp.c                        |   8 +-
 freebsd/sys/netinet/in.c                          |   8 +
 freebsd/sys/netinet/in_pcb.c                      |  10 +-
 freebsd/sys/netinet/in_var.h                      |   2 +
 freebsd/sys/netinet/ip_fastfwd.c                  | 135 ++--
 freebsd/sys/netinet/ip_icmp.c                     |   2 +
 freebsd/sys/netinet/ip_input.c                    |   2 +-
 freebsd/sys/netinet/ip_mroute.c                   |   8 +-
 freebsd/sys/netinet/ip_output.c                   |  13 +-
 freebsd/sys/netinet/raw_ip.c                      |   4 +-
 freebsd/sys/netinet/sctp_asconf.c                 |  54 +-
 freebsd/sys/netinet/sctp_asconf.h                 |   1 -
 freebsd/sys/netinet/sctp_bsd_addr.c               |  11 +-
 freebsd/sys/netinet/sctp_bsd_addr.h               |   1 -
 freebsd/sys/netinet/sctp_cc_functions.c           |  77 +--
 freebsd/sys/netinet/sctp_constants.h              |   5 +-
 freebsd/sys/netinet/sctp_crc32.c                  |   1 -
 freebsd/sys/netinet/sctp_crc32.h                  |   2 -
 freebsd/sys/netinet/sctp_header.h                 |  21 +-
 freebsd/sys/netinet/sctp_indata.c                 | 776 ++++++++++------------
 freebsd/sys/netinet/sctp_indata.h                 |  11 +-
 freebsd/sys/netinet/sctp_input.c                  | 136 ++--
 freebsd/sys/netinet/sctp_os_bsd.h                 |   1 -
 freebsd/sys/netinet/sctp_output.c                 | 386 ++++-------
 freebsd/sys/netinet/sctp_pcb.c                    | 147 ++--
 freebsd/sys/netinet/sctp_pcb.h                    |   9 +-
 freebsd/sys/netinet/sctp_peeloff.h                |   1 -
 freebsd/sys/netinet/sctp_structs.h                |  28 +-
 freebsd/sys/netinet/sctp_sysctl.c                 |   3 -
 freebsd/sys/netinet/sctp_timer.c                  |  48 +-
 freebsd/sys/netinet/sctp_uio.h                    |   3 -
 freebsd/sys/netinet/sctp_usrreq.c                 | 142 ++--
 freebsd/sys/netinet/sctp_var.h                    |   6 +-
 freebsd/sys/netinet/sctputil.c                    | 185 ++----
 freebsd/sys/netinet/sctputil.h                    |   5 -
 freebsd/sys/netinet/tcp_debug.c                   |   4 +-
 freebsd/sys/netinet/tcp_fsm.h                     |   3 +-
 freebsd/sys/netinet/tcp_hostcache.c               |  56 +-
 freebsd/sys/netinet/tcp_hostcache.h               |  28 +-
 freebsd/sys/netinet/tcp_input.c                   | 181 +++--
 freebsd/sys/netinet/tcp_lro.c                     |   1 +
 freebsd/sys/netinet/tcp_output.c                  |  92 +--
 freebsd/sys/netinet/tcp_seq.h                     |   7 +-
 freebsd/sys/netinet/tcp_subr.c                    |  50 +-
 freebsd/sys/netinet/tcp_syncache.c                |  51 +-
 freebsd/sys/netinet/tcp_timer.c                   |  20 +
 freebsd/sys/netinet/tcp_timewait.c                |   5 +
 freebsd/sys/netinet/tcp_usrreq.c                  |  53 +-
 freebsd/sys/netinet/tcp_var.h                     |  51 +-
 freebsd/sys/netinet/udp_usrreq.c                  |  11 +-
 freebsd/sys/netinet6/icmp6.c                      | 169 ++---
 freebsd/sys/netinet6/in6.c                        |  19 +-
 freebsd/sys/netinet6/in6_ifattach.c               |  25 +-
 freebsd/sys/netinet6/ip6_forward.c                |   3 +-
 freebsd/sys/netinet6/ip6_input.c                  |   4 +-
 freebsd/sys/netinet6/ip6_mroute.c                 |  13 +-
 freebsd/sys/netinet6/ip6_output.c                 |  36 +-
 freebsd/sys/netinet6/nd6.c                        | 145 ++--
 freebsd/sys/netinet6/nd6.h                        |  29 +-
 freebsd/sys/netinet6/nd6_nbr.c                    |  43 +-
 freebsd/sys/netinet6/nd6_rtr.c                    | 358 ++++++----
 freebsd/sys/netinet6/raw_ip6.c                    |   2 +-
 freebsd/sys/netinet6/sctp6_usrreq.c               |   6 -
 freebsd/sys/netinet6/sctp6_var.h                  |   1 -
 freebsd/sys/netinet6/udp6_usrreq.c                |   5 +-
 freebsd/sys/netpfil/ipfw/ip_fw2.c                 |   4 +-
 freebsd/sys/netpfil/ipfw/ip_fw_dynamic.c          |  11 +-
 freebsd/sys/netpfil/ipfw/ip_fw_pfil.c             |  24 +-
 freebsd/sys/netpfil/ipfw/ip_fw_table.c            |  50 +-
 freebsd/sys/netpfil/ipfw/nat64/nat64_translate.c  |   4 +-
 freebsd/sys/netpfil/pf/if_pflog.c                 |   2 +-
 freebsd/sys/netpfil/pf/if_pfsync.c                |   9 +-
 freebsd/sys/netpfil/pf/pf.c                       |  65 +-
 freebsd/sys/netpfil/pf/pf_if.c                    |   2 +-
 freebsd/sys/netpfil/pf/pf_ioctl.c                 |   4 +-
 freebsd/sys/netpfil/pf/pf_norm.c                  |   2 +-
 freebsd/sys/opencrypto/crypto.c                   |   4 +-
 freebsd/sys/powerpc/include/machine/cpufunc.h     |   2 +-
 freebsd/sys/powerpc/include/machine/spr.h         |   5 +
 freebsd/sys/sys/buf.h                             |  31 +-
 freebsd/sys/sys/bufobj.h                          |   5 -
 freebsd/sys/sys/bus.h                             |   4 +
 freebsd/sys/sys/capsicum.h                        |   2 +
 freebsd/sys/sys/eventhandler.h                    |   7 +
 freebsd/sys/sys/filedesc.h                        |  28 +
 freebsd/sys/sys/linker.h                          |   1 +
 freebsd/sys/sys/mbuf.h                            |   8 +-
 freebsd/sys/sys/module.h                          |   2 +-
 freebsd/sys/sys/mount.h                           |  11 +-
 freebsd/sys/sys/proc.h                            |   1 +
 freebsd/sys/sys/sf_buf.h                          |   1 +
 freebsd/sys/sys/socket.h                          |   1 +
 freebsd/sys/sys/socketvar.h                       |   3 +-
 freebsd/sys/sys/sysctl.h                          |   1 +
 freebsd/sys/sys/sysproto.h                        |   2 +-
 freebsd/sys/sys/user.h                            |   3 +-
 freebsd/sys/sys/vmmeter.h                         |  40 +-
 freebsd/sys/sys/vnode.h                           |  13 +-
 freebsd/sys/vm/uma_core.c                         |  16 +-
 freebsd/usr.bin/netstat/mbuf.c                    |   3 +
 freebsd/usr.bin/netstat/route.c                   |   2 +
 freebsd/usr.bin/vmstat/vmstat.c                   |  14 +-
 libbsd.txt                                        |   2 +-
 rtemsbsd/include/machine/rtems-bsd-kernel-space.h |   2 +
 rtemsbsd/include/rtems/bsd/sys/param.h            |   2 +-
 227 files changed, 3789 insertions(+), 2995 deletions(-)

diff --git a/freebsd-org b/freebsd-org
index 9fe7c41..80c55f0 160000
--- a/freebsd-org
+++ b/freebsd-org
@@ -1 +1 @@
-Subproject commit 9fe7c416e6abb28b1398fd3e5687099846800cfd
+Subproject commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c
diff --git a/freebsd/bin/hostname/hostname.c b/freebsd/bin/hostname/hostname.c
index 8e9fc97..61b5dba 100644
--- a/freebsd/bin/hostname/hostname.c
+++ b/freebsd/bin/hostname/hostname.c
@@ -96,7 +96,7 @@ rtems_shell_cmd_t rtems_shell_HOSTNAME_Command = {
 int
 main(int argc, char *argv[])
 {
-	int ch, sflag;
+	int ch, sflag, dflag;
 	char *p, hostname[MAXHOSTNAMELEN];
 #ifdef __rtems__
 	struct getopt_data getopt_data;
@@ -107,10 +107,11 @@ main(int argc, char *argv[])
 #endif /* __rtems__ */
 
 	sflag = 0;
+	dflag = 0;
 #ifndef __rtems__
-	while ((ch = getopt(argc, argv, "fs")) != -1)
+	while ((ch = getopt(argc, argv, "fsd")) != -1)
 #else /* __rtems__ */
-	while ((ch = getopt(argc, argv, "fms")) != -1)
+	while ((ch = getopt(argc, argv, "fdms")) != -1)
 #endif /* __rtems__ */
 		switch (ch) {
 		case 'f':
@@ -123,6 +124,9 @@ main(int argc, char *argv[])
 		case 's':
 			sflag = 1;
 			break;
+		case 'd':
+			dflag = 1;
+			break;
 #ifdef __rtems__
 		case 'm':
 			mflag = 1;
@@ -135,7 +139,7 @@ main(int argc, char *argv[])
 	argc -= optind;
 	argv += optind;
 
-	if (argc > 1)
+	if (argc > 1 || (sflag && dflag))
 		usage();
 
 	if (*argv) {
@@ -164,6 +168,10 @@ main(int argc, char *argv[])
 			p = strchr(hostname, '.');
 			if (p != NULL)
 				*p = '\0';
+		} else if (dflag) {
+			p = strchr(hostname, '.');
+			if (p != NULL)
+				strcpy(hostname, ++p);
 		}
 		(void)printf("%s\n", hostname);
 	}
@@ -174,6 +182,10 @@ static void
 usage(void)
 {
 
-	(void)fprintf(stderr, "usage: hostname [-fms] [name-of-host]\n");
+#ifndef __rtems__
+	(void)fprintf(stderr, "usage: hostname [-f] [-s | -d] [name-of-host]\n");
+#else /* __rtems__ */
+	(void)fprintf(stderr, "usage: hostname [-f] [-m | -s | -d] [name-of-host]\n");
+#endif /* __rtems__ */
 	exit(1);
 }
diff --git a/freebsd/contrib/tcpdump/tcpdump.c b/freebsd/contrib/tcpdump/tcpdump.c
index 1691451..6a74ef7 100644
--- a/freebsd/contrib/tcpdump/tcpdump.c
+++ b/freebsd/contrib/tcpdump/tcpdump.c
@@ -40,6 +40,7 @@ static const char rcsid[] _U_ =
 /* $FreeBSD$ */
 
 #ifdef __rtems__
+#define HAVE_GETOPT_LONG
 #define __need_getopt_newlib
 #include <getopt.h>
 #define setpriority(a, b, c)
@@ -84,6 +85,32 @@ extern int SIZE_BUF;
 #include <smi.h>
 #endif
 
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/crypto.h>
+#endif
+
+#ifdef HAVE_GETOPT_LONG
+#include <getopt.h>
+#else
+#include "getopt_long.h"
+#endif
+/* Capsicum-specific code requires macros from <net/bpf.h>, which will fail
+ * to compile if <pcap.h> has already been included; including the headers
+ * in the opposite order works fine.
+ */
+#ifdef __FreeBSD__
+#include <sys/capsicum.h>
+#include <sys/sysctl.h>
+#include <libgen.h>
+#endif /* __FreeBSD__ */
+#ifdef HAVE_CASPER
+#include <libcasper.h>
+#include <casper/cap_dns.h>
+#include <sys/nv.h>
+#include <sys/ioccom.h>
+#include <net/bpf.h>
+#include <fcntl.h>
+#endif	/* HAVE_CASPER */
 #include <pcap.h>
 #include <signal.h>
 #include <stdio.h>
@@ -1619,6 +1646,26 @@ main(int argc, char **argv)
 
 	if (pcap_setfilter(pd, &fcode) < 0)
 		error("%s", pcap_geterr(pd));
+#ifdef HAVE_CASPER
+	if (RFileName == NULL && VFileName == NULL) {
+		static const unsigned long cmds[] = { BIOCGSTATS, BIOCROTZBUF };
+
+		/*
+		 * The various libpcap devices use a combination of
+		 * read (bpf), ioctl (bpf, netmap), poll (netmap).
+		 * Grant the relevant access rights, sorted by name.
+		 */
+		cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ);
+		if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 &&
+		    errno != ENOSYS) {
+			error("unable to limit pcap descriptor");
+		}
+		if (cap_ioctls_limit(pcap_fileno(pd), cmds,
+		    sizeof(cmds) / sizeof(cmds[0])) < 0 && errno != ENOSYS) {
+			error("unable to limit ioctls on pcap descriptor");
+		}
+	}
+#endif
 	if (WFileName) {
 		pcap_dumper_t *p;
 		/* Do not exceed the default PATH_MAX for files. */
diff --git a/freebsd/lib/libc/db/btree/bt_close.c b/freebsd/lib/libc/db/btree/bt_close.c
index 2034f6a..a8146e5 100644
--- a/freebsd/lib/libc/db/btree/bt_close.c
+++ b/freebsd/lib/libc/db/btree/bt_close.c
@@ -136,7 +136,8 @@ __bt_sync(const DB *dbp, u_int flags)
 		return (RET_ERROR);
 	}
 
-	if (F_ISSET(t, B_INMEM | B_RDONLY) || !F_ISSET(t, B_MODIFIED))
+	if (F_ISSET(t, B_INMEM | B_RDONLY) ||
+	    !F_ISSET(t, B_MODIFIED | B_METADIRTY))
 		return (RET_SUCCESS);
 
 	if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)
diff --git a/freebsd/lib/libc/include/libc_private.h b/freebsd/lib/libc/include/libc_private.h
index 9fe6ab0..053b221 100644
--- a/freebsd/lib/libc/include/libc_private.h
+++ b/freebsd/lib/libc/include/libc_private.h
@@ -339,6 +339,7 @@ int		__sys_openat(int, const char *, int, ...);
 int		__sys_pselect(int, struct fd_set *, struct fd_set *,
 		    struct fd_set *, const struct timespec *,
 		    const __sigset_t *);
+int		__sys_ptrace(int, __pid_t, char *, int);
 int		__sys_poll(struct pollfd *, unsigned, int);
 int		__sys_ppoll(struct pollfd *, unsigned, const struct timespec *,
 		    const __sigset_t *);
diff --git a/freebsd/lib/libc/net/getaddrinfo.c b/freebsd/lib/libc/net/getaddrinfo.c
index 0fe1b5d..18aed43 100644
--- a/freebsd/lib/libc/net/getaddrinfo.c
+++ b/freebsd/lib/libc/net/getaddrinfo.c
@@ -226,6 +226,7 @@ struct ai_order {
 	struct policyqueue *aio_dstpolicy;
 	struct addrinfo *aio_ai;
 	int aio_matchlen;
+	int aio_initial_sequence;
 };
 
 static const ns_src default_dns_files[] = {
@@ -710,6 +711,7 @@ reorder(struct addrinfo *sentinel)
 		aio[i].aio_dstpolicy = match_addrselectpolicy(ai->ai_addr,
 							      &policyhead);
 		set_source(&aio[i], &policyhead);
+		aio[i].aio_initial_sequence = i;
 	}
 
 	/* perform sorting. */
@@ -949,7 +951,7 @@ matchlen(struct sockaddr *src, struct sockaddr *dst)
 
 	while (s < lim)
 		if ((r = (*d++ ^ *s++)) != 0) {
-			while (r < addrlen * 8) {
+			while ((r & 0x80) == 0) {
 				match++;
 				r <<= 1;
 			}
@@ -1068,6 +1070,23 @@ comp_dst(const void *arg1, const void *arg2)
 	}
 
 	/* Rule 10: Otherwise, leave the order unchanged. */
+
+	/* 
+	 * Note that qsort is unstable; so, we can't return zero and 
+	 * expect the order to be unchanged.
+	 * That also means we can't depend on the current position of
+	 * dst2 being after dst1.  We must enforce the initial order
+	 * with an explicit compare on the original position.
+	 * The qsort specification requires that "When the same objects 
+	 * (consisting of width bytes, irrespective of their current 
+	 * positions in the array) are passed more than once to the 
+	 * comparison function, the results shall be consistent with one 
+	 * another."  
+	 * In other words, If A < B, then we must also return B > A.
+	 */
+	if (dst2->aio_initial_sequence < dst1->aio_initial_sequence)
+		return(1);
+
 	return(-1);
 }
 
diff --git a/freebsd/lib/libc/net/linkaddr.c b/freebsd/lib/libc/net/linkaddr.c
index 1a2c3fd..dbd363d 100644
--- a/freebsd/lib/libc/net/linkaddr.c
+++ b/freebsd/lib/libc/net/linkaddr.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <net/if.h>
 #include <net/if_dl.h>
 #include <string.h>
 
@@ -124,31 +125,46 @@ char *
 link_ntoa(const struct sockaddr_dl *sdl)
 {
 	static char obuf[64];
-	char *out = obuf;
-	int i;
-	u_char *in = (u_char *)LLADDR(sdl);
-	u_char *inlim = in + sdl->sdl_alen;
-	int firsttime = 1;
+	_Static_assert(sizeof(obuf) >= IFNAMSIZ + 20, "obuf is too small");
+	char *out;
+	const u_char *in, *inlim;
+	int namelen, i, rem;
 
-	if (sdl->sdl_nlen) {
-		bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen);
-		out += sdl->sdl_nlen;
-		if (sdl->sdl_alen)
+	namelen = (sdl->sdl_nlen <= IFNAMSIZ) ? sdl->sdl_nlen : IFNAMSIZ;
+
+	out = obuf;
+	rem = sizeof(obuf);
+	if (namelen > 0) {
+		bcopy(sdl->sdl_data, out, namelen);
+		out += namelen;
+		rem -= namelen;
+		if (sdl->sdl_alen > 0) {
 			*out++ = ':';
+			rem--;
+		}
 	}
-	while (in < inlim) {
-		if (firsttime)
-			firsttime = 0;
-		else
+
+	in = (const u_char *)sdl->sdl_data + sdl->sdl_nlen;
+	inlim = in + sdl->sdl_alen;
+
+	while (in < inlim && rem > 1) {
+		if (in != (const u_char *)sdl->sdl_data + sdl->sdl_nlen) {
 			*out++ = '.';
+			rem--;
+		}
 		i = *in++;
 		if (i > 0xf) {
-			out[1] = hexlist[i & 0xf];
-			i >>= 4;
-			out[0] = hexlist[i];
-			out += 2;
-		} else
+			if (rem < 3)
+				break;
+			*out++ = hexlist[i >> 4];
+			*out++ = hexlist[i & 0xf];
+			rem -= 2;
+		} else {
+			if (rem < 2)
+				break;
 			*out++ = hexlist[i];
+			rem--;
+		}
 	}
 	*out = 0;
 	return (obuf);
diff --git a/freebsd/lib/libc/net/name6.c b/freebsd/lib/libc/net/name6.c
index a106ad9..8b8ac79 100644
--- a/freebsd/lib/libc/net/name6.c
+++ b/freebsd/lib/libc/net/name6.c
@@ -187,6 +187,7 @@ struct hp_order {
 #define aio_sa aio_un.aiou_sa
 	int aio_matchlen;
 	char *aio_h_addr;
+	int aio_initial_sequence;
 };
 
 static struct	 hostent *_hpcopy(struct hostent *, int *);
@@ -713,6 +714,7 @@ _hpreorder(struct hostent *hp)
 		aio[i].aio_dstscope = gai_addr2scopetype(sa);
 		aio[i].aio_dstpolicy = match_addrselectpolicy(sa, &policyhead);
 		set_source(&aio[i], &policyhead);
+		aio[i].aio_initial_sequence = i;
 	}
 
 	/* perform sorting. */
@@ -930,7 +932,7 @@ matchlen(struct sockaddr *src, struct sockaddr *dst)
 
 	while (s < lim)
 		if ((r = (*d++ ^ *s++)) != 0) {
-			while (r < addrlen * 8) {
+			while ((r & 0x80) == 0) {
 				match++;
 				r <<= 1;
 			}
@@ -1047,6 +1049,23 @@ comp_dst(const void *arg1, const void *arg2)
 	}
 
 	/* Rule 10: Otherwise, leave the order unchanged. */
+
+	/* 
+	 * Note that qsort is unstable; so, we can't return zero and 
+	 * expect the order to be unchanged.
+	 * That also means we can't depend on the current position of
+	 * dst2 being after dst1.  We must enforce the initial order
+	 * with an explicit compare on the original position.
+	 * The qsort specification requires that "When the same objects 
+	 * (consisting of width bytes, irrespective of their current 
+	 * positions in the array) are passed more than once to the 
+	 * comparison function, the results shall be consistent with one 
+	 * another."  
+	 * In other words, If A < B, then we must also return B > A.
+	 */
+	if (dst2->aio_initial_sequence < dst1->aio_initial_sequence)
+		return(1);
+
 	return(-1);
 }
 
diff --git a/freebsd/lib/libc/stdio/fgetln.c b/freebsd/lib/libc/stdio/fgetln.c
index 7d9f6a5..8d1235c 100644
--- a/freebsd/lib/libc/stdio/fgetln.c
+++ b/freebsd/lib/libc/stdio/fgetln.c
@@ -143,8 +143,11 @@ fgetln(FILE *fp, size_t *lenp)
 		(void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
 		    len - off);
 		off = len;
-		if (__srefill(fp))
-			break;	/* EOF or error: return partial line */
+		if (__srefill(fp)) {
+			if (__sfeof(fp))
+				break;
+			goto error;
+		}
 		if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) == NULL)
 			continue;
 
diff --git a/freebsd/lib/libipsec/pfkey.c b/freebsd/lib/libipsec/pfkey.c
index abb0cee..eeb07f8 100644
--- a/freebsd/lib/libipsec/pfkey.c
+++ b/freebsd/lib/libipsec/pfkey.c
@@ -1778,6 +1778,7 @@ pfkey_align(msg, mhp)
 		case SADB_EXT_SPIRANGE:
 		case SADB_X_EXT_POLICY:
 		case SADB_X_EXT_SA2:
+		case SADB_X_EXT_SA_REPLAY:
 			mhp[ext->sadb_ext_type] = (caddr_t)ext;
 			break;
 		case SADB_X_EXT_NAT_T_TYPE:
diff --git a/freebsd/lib/libipsec/pfkey_dump.c b/freebsd/lib/libipsec/pfkey_dump.c
index 7a5c2f2..7c6ff8d 100644
--- a/freebsd/lib/libipsec/pfkey_dump.c
+++ b/freebsd/lib/libipsec/pfkey_dump.c
@@ -221,6 +221,7 @@ pfkey_sadump(m)
 	struct sadb_key *m_auth, *m_enc;
 	struct sadb_ident *m_sid, *m_did;
 	struct sadb_sens *m_sens;
+	struct sadb_x_sa_replay *m_sa_replay;
 
 	/* check pfkey message. */
 	if (pfkey_align(m, mhp)) {
@@ -245,6 +246,7 @@ pfkey_sadump(m)
 	m_sid = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC];
 	m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_DST];
 	m_sens = (struct sadb_sens *)mhp[SADB_EXT_SENSITIVITY];
+	m_sa_replay = (struct sadb_x_sa_replay *)mhp[SADB_X_EXT_SA_REPLAY];
 
 	/* source address */
 	if (m_saddr == NULL) {
@@ -308,7 +310,8 @@ pfkey_sadump(m)
 	/* replay windoe size & flags */
 	printf("\tseq=0x%08x replay=%u flags=0x%08x ",
 		m_sa2->sadb_x_sa2_sequence,
-		m_sa->sadb_sa_replay,
+		m_sa_replay ? (m_sa_replay->sadb_x_sa_replay_replay >> 3) :
+			m_sa->sadb_sa_replay,
 		m_sa->sadb_sa_flags);
 
 	/* state */
diff --git a/freebsd/lib/libmemstat/memstat_uma.c b/freebsd/lib/libmemstat/memstat_uma.c
index 9c5e402..299386c 100644
--- a/freebsd/lib/libmemstat/memstat_uma.c
+++ b/freebsd/lib/libmemstat/memstat_uma.c
@@ -32,9 +32,6 @@
 #include <rtems/bsd/sys/cpuset.h>
 #include <sys/sysctl.h>
 
-#include <vm/vm.h>
-#include <vm/vm_page.h>
-
 #include <vm/uma.h>
 #include <vm/uma_int.h>
 
diff --git a/freebsd/sbin/dhclient/clparse.c b/freebsd/sbin/dhclient/clparse.c
index a65236f..10df53b 100644
--- a/freebsd/sbin/dhclient/clparse.c
+++ b/freebsd/sbin/dhclient/clparse.c
@@ -104,6 +104,8 @@ read_client_conf(void)
 	    [top_level_config.requested_option_count++] = DHO_HOST_NAME;
 	top_level_config.requested_options
 	    [top_level_config.requested_option_count++] = DHO_DOMAIN_SEARCH;
+	top_level_config.requested_options
+	    [top_level_config.requested_option_count++] = DHO_INTERFACE_MTU;
 
 	if ((cfile = fopen(path_dhclient_conf, "r")) != NULL) {
 		do {
diff --git a/freebsd/sbin/dhclient/dhclient.c b/freebsd/sbin/dhclient/dhclient.c
index c7b75c5..46ffaff 100644
--- a/freebsd/sbin/dhclient/dhclient.c
+++ b/freebsd/sbin/dhclient/dhclient.c
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
 #include "privsep.h"
 
 #include <sys/capsicum.h>
+#include <sys/endian.h>
 
 #include <net80211/ieee80211_freebsd.h>
 
@@ -134,6 +135,9 @@ int		 fork_privchld(int, int);
 	    ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
 #define	ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
 
+/* Minimum MTU is 68 as per RFC791, p. 24 */
+#define MIN_MTU 68
+
 static time_t	scripttime;
 
 int
@@ -800,9 +804,20 @@ dhcpack(struct packet *packet)
 void
 bind_lease(struct interface_info *ip)
 {
+	struct option_data *opt;
+
 	/* Remember the medium. */
 	ip->client->new->medium = ip->client->medium;
 
+	opt = &ip->client->new->options[DHO_INTERFACE_MTU];
+	if (opt->len == sizeof(u_int16_t)) {
+		u_int16_t mtu = be16dec(opt->data);
+		if (mtu < MIN_MTU)
+			warning("mtu size %u < %d: ignored", (unsigned)mtu, MIN_MTU);
+		else
+			interface_set_mtu_unpriv(privfd, mtu);
+	}
+
 	/* Write out the new lease. */
 	write_client_lease(ip, ip->client->new, 0);
 
diff --git a/freebsd/sbin/dhclient/dhcpd.h b/freebsd/sbin/dhclient/dhcpd.h
index 852513a..f2bc773 100644
--- a/freebsd/sbin/dhclient/dhcpd.h
+++ b/freebsd/sbin/dhclient/dhcpd.h
@@ -319,6 +319,8 @@ void cancel_timeout(void (*)(void *), void *);
 void add_protocol(char *, int, void (*)(struct protocol *), void *);
 void remove_protocol(struct protocol *);
 int interface_link_status(char *);
+void interface_set_mtu_unpriv(int, u_int16_t);
+void interface_set_mtu_priv(char *, u_int16_t); 
 
 /* hash.c */
 struct hash_table *new_hash(void);
diff --git a/freebsd/sbin/dhclient/dispatch.c b/freebsd/sbin/dhclient/dispatch.c
index 4a68c62..d37c992 100644
--- a/freebsd/sbin/dhclient/dispatch.c
+++ b/freebsd/sbin/dhclient/dispatch.c
@@ -45,6 +45,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "dhcpd.h"
+#include "privsep.h"
 
 #include <sys/ioctl.h>
 
@@ -107,8 +108,8 @@ discover_interfaces(struct interface_info *iface)
 			if (foo.sin_addr.s_addr == htonl(INADDR_LOOPBACK))
 				continue;
 			if (!iface->ifp) {
-				int len = IFNAMSIZ + ifa->ifa_addr->sa_len;
-				if ((tif = malloc(len)) == NULL)
+				if ((tif = calloc(1, sizeof(struct ifreq)))
+				    == NULL)
 					error("no space to remember ifp");
 				strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ);
 				memcpy(&tif->ifr_addr, ifa->ifa_addr,
@@ -503,3 +504,46 @@ interface_link_status(char *ifname)
 	}
 	return (1);
 }
+
+void
+interface_set_mtu_unpriv(int privfd, u_int16_t mtu)
+{
+	struct imsg_hdr hdr;
+	struct buf *buf;
+	int errs = 0;
+
+	hdr.code = IMSG_SET_INTERFACE_MTU;
+	hdr.len = sizeof(hdr) +
+		sizeof(u_int16_t);
+
+	if ((buf = buf_open(hdr.len)) == NULL)
+		error("buf_open: %m");
+
+	errs += buf_add(buf, &hdr, sizeof(hdr));
+	errs += buf_add(buf, &mtu, sizeof(mtu));
+	if (errs)
+		error("buf_add: %m");
+	
+	if (buf_close(privfd, buf) == -1)
+		error("buf_close: %m");
+}
+
+void
+interface_set_mtu_priv(char *ifname, u_int16_t mtu)
+{
+	struct ifreq ifr;
+	int sock;
+
+	if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+		error("Can't create socket");
+
+	memset(&ifr, 0, sizeof(ifr));
+
+	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+	ifr.ifr_mtu = mtu;
+
+	if (ioctl(sock, SIOCSIFMTU, &ifr) == -1)
+		warning("SIOCSIFMTU failed (%d): %s", mtu,
+			strerror(errno));
+	close(sock);
+}
diff --git a/freebsd/sbin/dhclient/privsep.c b/freebsd/sbin/dhclient/privsep.c
index aa1042f..b1cf510 100644
--- a/freebsd/sbin/dhclient/privsep.c
+++ b/freebsd/sbin/dhclient/privsep.c
@@ -113,6 +113,7 @@ dispatch_imsg(struct interface_info *ifi, int fd)
 	struct client_lease	 lease;
 	int			 ret, i, optlen;
 	struct buf		*buf;
+	u_int16_t		mtu;
 
 	buf_read(fd, &hdr, sizeof(hdr));
 
@@ -237,6 +238,13 @@ dispatch_imsg(struct interface_info *ifi, int fd)
 	case IMSG_SEND_PACKET:
 		send_packet_priv(ifi, &hdr, fd);
 		break;
+	case IMSG_SET_INTERFACE_MTU:
+		if (hdr.len < sizeof(hdr) + sizeof(u_int16_t))
+			error("corrupted message received");	
+	
+		buf_read(fd, &mtu, sizeof(u_int16_t));
+		interface_set_mtu_priv(ifi->name, mtu);
+		break;
 	default:
 		error("received unknown message, code %d", hdr.code);
 	}
diff --git a/freebsd/sbin/dhclient/privsep.h b/freebsd/sbin/dhclient/privsep.h
index d464da4..e1a7338 100644
--- a/freebsd/sbin/dhclient/privsep.h
+++ b/freebsd/sbin/dhclient/privsep.h
@@ -36,7 +36,8 @@ enum imsg_code {
 	IMSG_SCRIPT_WRITE_PARAMS,
 	IMSG_SCRIPT_GO,
 	IMSG_SCRIPT_GO_RET,
-	IMSG_SEND_PACKET
+	IMSG_SEND_PACKET,
+	IMSG_SET_INTERFACE_MTU,
 };
 
 struct imsg_hdr {
diff --git a/freebsd/sbin/dhclient/tables.c b/freebsd/sbin/dhclient/tables.c
index d73022d..6339898 100644
--- a/freebsd/sbin/dhclient/tables.c
+++ b/freebsd/sbin/dhclient/tables.c
@@ -402,6 +402,7 @@ unsigned char dhcp_option_default_priority_list[] = {
 	DHO_IRC_SERVER,
 	DHO_STREETTALK_SERVER,
 	DHO_STREETTALK_DA_SERVER,
+	DHO_DHCP_USER_CLASS_ID,
 	DHO_DOMAIN_SEARCH,
 
 	/* Presently-undefined options... */
diff --git a/freebsd/sbin/ifconfig/af_inet.c b/freebsd/sbin/ifconfig/af_inet.c
index d464df5..040da21 100644
--- a/freebsd/sbin/ifconfig/af_inet.c
+++ b/freebsd/sbin/ifconfig/af_inet.c
@@ -100,7 +100,7 @@ in_status(int s __unused, const struct ifaddrs *ifa)
 		sin = (struct sockaddr_in *)ifa->ifa_dstaddr;
 		if (sin == NULL)
 			sin = &null_sin;
-		printf(" --> %s ", inet_ntoa(sin->sin_addr));
+		printf(" --> %s", inet_ntoa(sin->sin_addr));
 	}
 
 	sin = (struct sockaddr_in *)ifa->ifa_netmask;
diff --git a/freebsd/sbin/ifconfig/af_inet6.c b/freebsd/sbin/ifconfig/af_inet6.c
index f743ee8..d3d58ad 100644
--- a/freebsd/sbin/ifconfig/af_inet6.c
+++ b/freebsd/sbin/ifconfig/af_inet6.c
@@ -250,7 +250,7 @@ in6_status(int s __unused, const struct ifaddrs *ifa)
 			if (error != 0)
 				inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf,
 					  sizeof(addr_buf));
-			printf(" --> %s ", addr_buf);
+			printf(" --> %s", addr_buf);
 		}
 	}
 
diff --git a/freebsd/sbin/ifconfig/af_link.c b/freebsd/sbin/ifconfig/af_link.c
index 1c37496..5fa2545 100644
--- a/freebsd/sbin/ifconfig/af_link.c
+++ b/freebsd/sbin/ifconfig/af_link.c
@@ -102,13 +102,24 @@ link_getaddr(const char *addr, int which)
 
 	if (which != ADDR)
 		errx(1, "can't set link-level netmask or broadcast");
-	if ((temp = malloc(strlen(addr) + 2)) == NULL)
-		errx(1, "malloc failed");
-	temp[0] = ':';
-	strcpy(temp + 1, addr);
-	sdl.sdl_len = sizeof(sdl);
-	link_addr(temp, &sdl);
-	free(temp);
+	if (!strcmp(addr, "random")) {
+		sdl.sdl_len = sizeof(sdl);
+		sdl.sdl_alen = ETHER_ADDR_LEN;
+		sdl.sdl_nlen = 0;
+		sdl.sdl_family = AF_LINK;
+		arc4random_buf(&sdl.sdl_data, ETHER_ADDR_LEN);
+		/* Non-multicast and claim it is locally administered. */
+		sdl.sdl_data[0] &= 0xfc;
+		sdl.sdl_data[0] |= 0x02;
+	} else {
+		if ((temp = malloc(strlen(addr) + 2)) == NULL)
+			errx(1, "malloc failed");
+		temp[0] = ':';
+		strcpy(temp + 1, addr);
+		sdl.sdl_len = sizeof(sdl);
+		link_addr(temp, &sdl);
+		free(temp);
+	}
 	if (sdl.sdl_alen > sizeof(sa->sa_data))
 		errx(1, "malformed link-level address");
 	sa->sa_family = AF_LINK;
diff --git a/freebsd/sbin/pfctl/parse.y b/freebsd/sbin/pfctl/parse.y
index 33edd3e..9664aaf 100644
--- a/freebsd/sbin/pfctl/parse.y
+++ b/freebsd/sbin/pfctl/parse.y
@@ -367,6 +367,8 @@ void	 decide_address_family(struct node_host *, sa_family_t *);
 void	 remove_invalid_hosts(struct node_host **, sa_family_t *);
 int	 invalid_redirect(struct node_host *, sa_family_t);
 u_int16_t parseicmpspec(char *, sa_family_t);
+int	 kw_casecmp(const void *, const void *);
+int	 map_tos(char *string, int *);
 
 static TAILQ_HEAD(loadanchorshead, loadanchors)
     loadanchorshead = TAILQ_HEAD_INITIALIZER(loadanchorshead);
@@ -2346,7 +2348,7 @@ pfrule		: action dir logquick interface route af proto fromto
 					memcpy(&r.rpool.key, $5.key,
 					    sizeof(struct pf_poolhashkey));
 			}
-			if (r.rt && r.rt != PF_FASTROUTE) {
+			if (r.rt) {
 				decide_address_family($5.host, &r.af);
 				remove_invalid_hosts(&$5.host, &r.af);
 				if ($5.host == NULL) {
@@ -3600,15 +3602,17 @@ icmp6type	: STRING			{
 		;
 
 tos	: STRING			{
-			if (!strcmp($1, "lowdelay"))
-				$$ = IPTOS_LOWDELAY;
-			else if (!strcmp($1, "throughput"))
-				$$ = IPTOS_THROUGHPUT;
-			else if (!strcmp($1, "reliability"))
-				$$ = IPTOS_RELIABILITY;
-			else if ($1[0] == '0' && $1[1] == 'x')
-				$$ = strtoul($1, NULL, 16);
-			else
+			int val;
+			char *end;
+
+			if (map_tos($1, &val))
+				$$ = val;
+			else if ($1[0] == '0' && $1[1] == 'x') {
+				errno = 0;
+				$$ = strtoul($1, &end, 16);
+				if (errno || *end != '\0')
+					$$ = 256;
+			} else
 				$$ = 256;		/* flag bad argument */
 			if ($$ < 0 || $$ > 255) {
 				yyerror("illegal tos value %s", $1);
@@ -4432,8 +4436,9 @@ route		: /* empty */			{
 			$$.pool_opts = 0;
 		}
 		| FASTROUTE {
+			/* backwards-compat */
 			$$.host = NULL;
-			$$.rt = PF_FASTROUTE;
+			$$.rt = 0;
 			$$.pool_opts = 0;
 		}
 		| ROUTETO routespec pool_opts {
@@ -6270,6 +6275,57 @@ pfctl_load_anchors(int dev, struct pfctl *pf, struct pfr_buffer *trans)
 }
 
 int
+kw_casecmp(const void *k, const void *e)
+{
+	return (strcasecmp(k, ((const struct keywords *)e)->k_name));
+}
+
+int
+map_tos(char *s, int *val)
+{
+	/* DiffServ Codepoints and other TOS mappings */
+	const struct keywords	 toswords[] = {
+		{ "af11",		IPTOS_DSCP_AF11 },
+		{ "af12",		IPTOS_DSCP_AF12 },
+		{ "af13",		IPTOS_DSCP_AF13 },
+		{ "af21",		IPTOS_DSCP_AF21 },
+		{ "af22",		IPTOS_DSCP_AF22 },
+		{ "af23",		IPTOS_DSCP_AF23 },
+		{ "af31",		IPTOS_DSCP_AF31 },
+		{ "af32",		IPTOS_DSCP_AF32 },
+		{ "af33",		IPTOS_DSCP_AF33 },
+		{ "af41",		IPTOS_DSCP_AF41 },
+		{ "af42",		IPTOS_DSCP_AF42 },
+		{ "af43",		IPTOS_DSCP_AF43 },
+		{ "critical",		IPTOS_PREC_CRITIC_ECP },
+		{ "cs0",		IPTOS_DSCP_CS0 },
+		{ "cs1",		IPTOS_DSCP_CS1 },
+		{ "cs2",		IPTOS_DSCP_CS2 },
+		{ "cs3",		IPTOS_DSCP_CS3 },
+		{ "cs4",		IPTOS_DSCP_CS4 },
+		{ "cs5",		IPTOS_DSCP_CS5 },
+		{ "cs6",		IPTOS_DSCP_CS6 },
+		{ "cs7",		IPTOS_DSCP_CS7 },
+		{ "ef",			IPTOS_DSCP_EF },
+		{ "inetcontrol",	IPTOS_PREC_INTERNETCONTROL },
+		{ "lowdelay",		IPTOS_LOWDELAY },
+		{ "netcontrol",		IPTOS_PREC_NETCONTROL },
+		{ "reliability",	IPTOS_RELIABILITY },
+		{ "throughput",		IPTOS_THROUGHPUT }
+	};
+	const struct keywords	*p;
+
+	p = bsearch(s, toswords, sizeof(toswords)/sizeof(toswords[0]),
+	    sizeof(toswords[0]), kw_casecmp);
+
+	if (p) {
+		*val = p->k_val;
+		return (1);
+	}
+	return (0);
+}
+
+int
 rt_tableid_max(void)
 {
 #ifdef __FreeBSD__
diff --git a/freebsd/sbin/pfctl/pfctl.c b/freebsd/sbin/pfctl/pfctl.c
index ab59706..f9efa09 100644
--- a/freebsd/sbin/pfctl/pfctl.c
+++ b/freebsd/sbin/pfctl/pfctl.c
@@ -1364,7 +1364,7 @@ pfctl_load_rule(struct pfctl *pf, char *path, struct pf_rule *r, int depth)
 			else
 				snprintf(&path[len], MAXPATHLEN - len,
 				    "%s", r->anchor->name);
-			name = path;
+			name = r->anchor->name;
 		} else
 			name = r->anchor->path;
 	} else
diff --git a/freebsd/sbin/pfctl/pfctl_optimize.c b/freebsd/sbin/pfctl/pfctl_optimize.c
index b8f44e8..89cebe9 100644
--- a/freebsd/sbin/pfctl/pfctl_optimize.c
+++ b/freebsd/sbin/pfctl/pfctl_optimize.c
@@ -103,7 +103,7 @@ TAILQ_HEAD(superblocks, superblock);
  * Description of the PF rule structure.
  */
 enum {
-    BARRIER,	/* the presence of the field puts the rule in it's own block */
+    BARRIER,	/* the presence of the field puts the rule in its own block */
     BREAK,	/* the field may not differ between rules in a superblock */
     NOMERGE,	/* the field may not differ between rules when combined */
     COMBINED,	/* the field may itself be combined with other rules */
@@ -127,7 +127,7 @@ static struct pf_rule_field pf_rule_desc[] = {
 
 
     /*
-     * The presence of these fields in a rule put the rule in it's own
+     * The presence of these fields in a rule put the rule in its own
      * superblock.  Thus it will not be optimized.  It also prevents the
      * rule from being re-ordered at all.
      */
diff --git a/freebsd/sbin/pfctl/pfctl_parser.c b/freebsd/sbin/pfctl/pfctl_parser.c
index 0ff7dee..cb49dc2 100644
--- a/freebsd/sbin/pfctl/pfctl_parser.c
+++ b/freebsd/sbin/pfctl/pfctl_parser.c
@@ -790,12 +790,8 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose, int numeric)
 			printf(" reply-to");
 		else if (r->rt == PF_DUPTO)
 			printf(" dup-to");
-		else if (r->rt == PF_FASTROUTE)
-			printf(" fastroute");
-		if (r->rt != PF_FASTROUTE) {
-			printf(" ");
-			print_pool(&r->rpool, 0, 0, r->af, PF_PASS);
-		}
+		printf(" ");
+		print_pool(&r->rpool, 0, 0, r->af, PF_PASS);
 	}
 	if (r->af) {
 		if (r->af == AF_INET)
diff --git a/freebsd/sbin/sysctl/sysctl.c b/freebsd/sbin/sysctl/sysctl.c
index fdbecd5..03069a3 100644
--- a/freebsd/sbin/sysctl/sysctl.c
+++ b/freebsd/sbin/sysctl/sysctl.c
@@ -677,9 +677,6 @@ S_vmtotal(size_t l2, void *p)
 }
 
 #ifdef __amd64__
-#define efi_next_descriptor(ptr, size) \
-	((struct efi_md *)(((uint8_t *) ptr) + size))
-
 static int
 S_efi_map(size_t l2, void *p)
 {
diff --git a/freebsd/sys/arm/include/machine/cpufunc.h b/freebsd/sys/arm/include/machine/cpufunc.h
index 911fc14..8a9a2a8 100644
--- a/freebsd/sys/arm/include/machine/cpufunc.h
+++ b/freebsd/sys/arm/include/machine/cpufunc.h
@@ -60,7 +60,7 @@ breakpoint(void)
 struct cpu_functions {
 
 	/* CPU functions */
-
+#if __ARM_ARCH < 6
 	void	(*cf_cpwait)		(void);
 
 	/* MMU functions */
@@ -140,6 +140,7 @@ struct cpu_functions {
 	void	(*cf_idcache_inv_all)	(void);
 	void	(*cf_idcache_wbinv_all)	(void);
 	void	(*cf_idcache_wbinv_range) (vm_offset_t, vm_size_t);
+#endif
 	void	(*cf_l2cache_wbinv_all) (void);
 	void	(*cf_l2cache_wbinv_range) (vm_offset_t, vm_size_t);
 	void	(*cf_l2cache_inv_range)	  (vm_offset_t, vm_size_t);
@@ -148,13 +149,17 @@ struct cpu_functions {
 
 	/* Other functions */
 
+#if __ARM_ARCH < 6
 	void	(*cf_drain_writebuf)	(void);
+#endif
 
 	void	(*cf_sleep)		(int mode);
 
+#if __ARM_ARCH < 6
 	/* Soft functions */
 
 	void	(*cf_context_switch)	(void);
+#endif
 
 	void	(*cf_setup)		(void);
 };
@@ -164,10 +169,8 @@ extern u_int cputype;
 
 #if __ARM_ARCH < 6
 #define	cpu_cpwait()		cpufuncs.cf_cpwait()
-#endif
 
 #define cpu_control(c, e)	cpufuncs.cf_control(c, e)
-#if __ARM_ARCH < 6
 #define cpu_setttb(t)		cpufuncs.cf_setttb(t)
 
 #define	cpu_tlb_flushID()	cpufuncs.cf_tlb_flushID()
@@ -186,6 +189,7 @@ extern u_int cputype;
 #define	cpu_idcache_wbinv_all()	cpufuncs.cf_idcache_wbinv_all()
 #define	cpu_idcache_wbinv_range(a, s) cpufuncs.cf_idcache_wbinv_range((a), (s))
 #endif
+
 #define cpu_l2cache_wbinv_all()	cpufuncs.cf_l2cache_wbinv_all()
 #define cpu_l2cache_wb_range(a, s) cpufuncs.cf_l2cache_wb_range((a), (s))
 #define cpu_l2cache_inv_range(a, s) cpufuncs.cf_l2cache_inv_range((a), (s))
@@ -274,26 +278,12 @@ void	sheeva_l2cache_wbinv_all	(void);
 #if defined(CPU_MV_PJ4B)
 void	armv6_idcache_wbinv_all		(void);
 #endif
-#if defined(CPU_MV_PJ4B) || defined(CPU_CORTEXA) || defined(CPU_KRAIT)
-void	armv7_setttb			(u_int);
-void	armv7_tlb_flushID		(void);
-void	armv7_tlb_flushID_SE		(u_int);
-void	armv7_icache_sync_range		(vm_offset_t, vm_size_t);
-void	armv7_idcache_wbinv_range	(vm_offset_t, vm_size_t);
-void	armv7_idcache_inv_all		(void);
-void	armv7_dcache_wbinv_all		(void);
+#if defined(CPU_CORTEXA8) || defined(CPU_CORTEXA_MP) || \
+    defined(CPU_MV_PJ4B) || defined(CPU_KRAIT)
 void	armv7_idcache_wbinv_all		(void);
-void	armv7_dcache_wbinv_range	(vm_offset_t, vm_size_t);
-void	armv7_dcache_inv_range		(vm_offset_t, vm_size_t);
-void	armv7_dcache_wb_range		(vm_offset_t, vm_size_t);
 void	armv7_cpu_sleep			(int);
 void	armv7_setup			(void);
-void	armv7_context_switch		(void);
 void	armv7_drain_writebuf		(void);
-void	armv7_sev			(void);
-u_int	armv7_auxctrl			(u_int, u_int);
-
-void	armadaxp_idcache_wbinv_all	(void);
 
 void 	cortexa_setup			(void);
 #endif
@@ -303,26 +293,8 @@ void	pj4bv7_setup			(void);
 #endif
 
 #if defined(CPU_ARM1176)
-void	arm11_tlb_flushID	(void);
-void	arm11_tlb_flushID_SE	(u_int);
-void	arm11_tlb_flushD	(void);
-void	arm11_tlb_flushD_SE	(u_int va);
-
-void	arm11_context_switch	(void);
-
 void	arm11_drain_writebuf	(void);
 
-void	armv6_dcache_wbinv_range	(vm_offset_t, vm_size_t);
-void	armv6_dcache_inv_range		(vm_offset_t, vm_size_t);
-void	armv6_dcache_wb_range		(vm_offset_t, vm_size_t);
-
-void	armv6_idcache_inv_all		(void);
-
-void    arm11x6_setttb                  (u_int);
-void    arm11x6_idcache_wbinv_all       (void);
-void    arm11x6_dcache_wbinv_all        (void);
-void    arm11x6_icache_sync_range       (vm_offset_t, vm_size_t);
-void    arm11x6_idcache_wbinv_range     (vm_offset_t, vm_size_t);
 void    arm11x6_setup                   (void);
 void    arm11x6_sleep                   (int);  /* no ref. for errata */
 #endif
diff --git a/freebsd/sys/arm/xilinx/zy7_slcr.c b/freebsd/sys/arm/xilinx/zy7_slcr.c
index 7ce502f..dc6475c 100644
--- a/freebsd/sys/arm/xilinx/zy7_slcr.c
+++ b/freebsd/sys/arm/xilinx/zy7_slcr.c
@@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
 #include <machine/stdarg.h>
 
 #ifndef __rtems__
-#include <dev/fdt/fdt_common.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 #endif /* __rtems__ */
@@ -639,8 +638,8 @@ zy7_slcr_attach(device_t dev)
 	/* Derive PLL frequencies from PS_CLK. */
 #ifndef __rtems__
 	node = ofw_bus_get_node(dev);
-	if (OF_getprop(node, "clock-frequency", &cell, sizeof(cell)) > 0)
-		ps_clk_frequency = fdt32_to_cpu(cell);
+	if (OF_getencprop(node, "clock-frequency", &cell, sizeof(cell)) > 0)
+		ps_clk_frequency = cell;
 	else
 #endif /* __rtems__ */
 		ps_clk_frequency = ZYNQ_DEFAULT_PS_CLK_FREQUENCY;
diff --git a/freebsd/sys/cam/cam.h b/freebsd/sys/cam/cam.h
index 5eb0a77..23feb50 100644
--- a/freebsd/sys/cam/cam.h
+++ b/freebsd/sys/cam/cam.h
@@ -294,7 +294,7 @@ typedef enum {
 	/* SIM ready to take more commands */
 	CAM_RELEASE_SIMQ	= 0x100,
 
-	/* SIM has this command in it's queue */
+	/* SIM has this command in its queue */
 	CAM_SIM_QUEUED		= 0x200,
 
 	/* Quality of service data is valid */
diff --git a/freebsd/sys/cam/cam_ccb.h b/freebsd/sys/cam/cam_ccb.h
index e00b5bd..d9b91f8 100644
--- a/freebsd/sys/cam/cam_ccb.h
+++ b/freebsd/sys/cam/cam_ccb.h
@@ -757,6 +757,9 @@ struct ccb_scsiio {
 #define		CAM_TAG_ACTION_NONE	0x00
 	u_int	   tag_id;		/* tag id from initator (target mode) */
 	u_int	   init_id;		/* initiator id of who selected */
+#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
+	struct bio *bio;		/* Associated bio */
+#endif
 #ifdef __rtems__
 	int readop;
 	rtems_blkdev_sg_buffer *sg_current;
@@ -1358,6 +1361,9 @@ cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries,
 	csio->sense_len = sense_len;
 	csio->cdb_len = cdb_len;
 	csio->tag_action = tag_action;
+#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
+	csio->bio = NULL;
+#endif
 }
 
 static __inline void
diff --git a/freebsd/sys/cam/cam_periph.h b/freebsd/sys/cam/cam_periph.h
index e28d5b1..d5a74a5 100644
--- a/freebsd/sys/cam/cam_periph.h
+++ b/freebsd/sys/cam/cam_periph.h
@@ -166,7 +166,6 @@ void		cam_periph_unmapmem(union ccb *ccb,
 				    struct cam_periph_map_info *mapinfo);
 union ccb	*cam_periph_getccb(struct cam_periph *periph,
 				   u_int32_t priority);
-void		cam_periph_ccbwait(union ccb *ccb);
 int		cam_periph_runccb(union ccb *ccb,
 				  int (*error_routine)(union ccb *ccb,
 						       cam_flags camflags,
diff --git a/freebsd/sys/cam/scsi/scsi_all.c b/freebsd/sys/cam/scsi/scsi_all.c
index 0cb7118..9e8924c 100644
--- a/freebsd/sys/cam/scsi/scsi_all.c
+++ b/freebsd/sys/cam/scsi/scsi_all.c
@@ -1063,7 +1063,7 @@ static struct asc_table_entry asc_table[] = {
 	{ SST(0x00, 0x1C, SS_RDEF,	/* XXX TBD */
 	    "Verify operation in progress") },
 	/* DT        B    */
-	{ SST(0x00, 0x1D, SS_RDEF,	/* XXX TBD */
+	{ SST(0x00, 0x1D, SS_NOP,
 	    "ATA pass through information available") },
 	/* DT   R MAEBKV  */
 	{ SST(0x00, 0x1E, SS_RDEF,	/* XXX TBD */
@@ -1072,7 +1072,7 @@ static struct asc_table_entry asc_table[] = {
 	{ SST(0x00, 0x1F, SS_RDEF,	/* XXX TBD */
 	    "Logical unit transitioning to another power condition") },
 	/* DT P      B    */
-	{ SST(0x00, 0x20, SS_RDEF,	/* XXX TBD */
+	{ SST(0x00, 0x20, SS_NOP,
 	    "Extended copy information available") },
 	/* D              */
 	{ SST(0x00, 0x21, SS_RDEF,	/* XXX TBD */
@@ -2338,7 +2338,7 @@ static struct asc_table_entry asc_table[] = {
 	{ SST(0x43, 0x00, SS_RDEF,
 	    "Message error") },
 	/* DTLPWROMAEBKVF */
-	{ SST(0x44, 0x00, SS_RDEF,
+	{ SST(0x44, 0x00, SS_FATAL | EIO,
 	    "Internal target failure") },
 	/* DT P   MAEBKVF */
 	{ SST(0x44, 0x01, SS_RDEF,	/* XXX TBD */
@@ -3199,10 +3199,10 @@ static struct asc_table_entry asc_table[] = {
 	{ SST(0x74, 0x6F, SS_RDEF,	/* XXX TBD */
 	    "External data encryption control error") },
 	/* DT   R M E  V  */
-	{ SST(0x74, 0x71, SS_RDEF,	/* XXX TBD */
+	{ SST(0x74, 0x71, SS_FATAL | EACCES,
 	    "Logical unit access not authorized") },
 	/* D              */
-	{ SST(0x74, 0x79, SS_RDEF,	/* XXX TBD */
+	{ SST(0x74, 0x79, SS_FATAL | EACCES,
 	    "Security conflict in translated device") }
 };
 
@@ -4661,6 +4661,53 @@ scsi_sense_progress_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
 	scsi_progress_sbuf(sb, progress_val);
 }
 
+void
+scsi_sense_ata_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
+			 u_int sense_len, uint8_t *cdb, int cdb_len,
+			 struct scsi_inquiry_data *inq_data,
+			 struct scsi_sense_desc_header *header)
+{
+	struct scsi_sense_ata_ret_desc *res;
+
+	res = (struct scsi_sense_ata_ret_desc *)header;
+
+	sbuf_printf(sb, "ATA status: %02x (%s%s%s%s%s%s%s%s), ",
+	    res->status,
+	    (res->status & 0x80) ? "BSY " : "",
+	    (res->status & 0x40) ? "DRDY " : "",
+	    (res->status & 0x20) ? "DF " : "",
+	    (res->status & 0x10) ? "SERV " : "",
+	    (res->status & 0x08) ? "DRQ " : "",
+	    (res->status & 0x04) ? "CORR " : "",
+	    (res->status & 0x02) ? "IDX " : "",
+	    (res->status & 0x01) ? "ERR" : "");
+	if (res->status & 1) {
+	    sbuf_printf(sb, "error: %02x (%s%s%s%s%s%s%s%s), ",
+		res->error,
+		(res->error & 0x80) ? "ICRC " : "",
+		(res->error & 0x40) ? "UNC " : "",
+		(res->error & 0x20) ? "MC " : "",
+		(res->error & 0x10) ? "IDNF " : "",
+		(res->error & 0x08) ? "MCR " : "",
+		(res->error & 0x04) ? "ABRT " : "",
+		(res->error & 0x02) ? "NM " : "",
+		(res->error & 0x01) ? "ILI" : "");
+	}
+
+	if (res->flags & SSD_DESC_ATA_FLAG_EXTEND) {
+		sbuf_printf(sb, "count: %02x%02x, ",
+		    res->count_15_8, res->count_7_0);
+		sbuf_printf(sb, "LBA: %02x%02x%02x%02x%02x%02x, ",
+		    res->lba_47_40, res->lba_39_32, res->lba_31_24,
+		    res->lba_23_16, res->lba_15_8, res->lba_7_0);
+	} else {
+		sbuf_printf(sb, "count: %02x, ", res->count_7_0);
+		sbuf_printf(sb, "LBA: %02x%02x%02x, ",
+		    res->lba_23_16, res->lba_15_8, res->lba_7_0);
+	}
+	sbuf_printf(sb, "device: %02x, ", res->device);
+}
+
 /*
  * Generic sense descriptor printing routine.  This is used when we have
  * not yet implemented a specific printing routine for this descriptor.
@@ -4707,6 +4754,7 @@ struct scsi_sense_desc_printer {
 	{SSD_DESC_FRU, scsi_sense_fru_sbuf},
 	{SSD_DESC_STREAM, scsi_sense_stream_sbuf},
 	{SSD_DESC_BLOCK, scsi_sense_block_sbuf},
+	{SSD_DESC_ATA, scsi_sense_ata_sbuf},
 	{SSD_DESC_PROGRESS, scsi_sense_progress_sbuf}
 };
 
@@ -7914,6 +7962,32 @@ scsi_report_target_group(struct ccb_scsiio *csio, u_int32_t retries,
 }
 
 void
+scsi_report_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
+		 void (*cbfcnp)(struct cam_periph *, union ccb *),
+		 u_int8_t tag_action, u_int8_t pdf,
+		 void *buf, u_int32_t alloc_len,
+		 u_int8_t sense_len, u_int32_t timeout)
+{
+	struct scsi_timestamp *scsi_cmd;
+
+	cam_fill_csio(csio,
+		      retries,
+		      cbfcnp,
+		      /*flags*/CAM_DIR_IN,
+		      tag_action,
+		      /*data_ptr*/(u_int8_t *)buf,
+		      /*dxfer_len*/alloc_len,
+		      sense_len,
+		      sizeof(*scsi_cmd),
+		      timeout);
+	scsi_cmd = (struct scsi_timestamp *)&csio->cdb_io.cdb_bytes;
+	bzero(scsi_cmd, sizeof(*scsi_cmd));
+	scsi_cmd->opcode = MAINTENANCE_IN;
+	scsi_cmd->service_action = REPORT_TIMESTAMP | pdf;
+	scsi_ulto4b(alloc_len, scsi_cmd->length);
+}
+
+void
 scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
 		 void (*cbfcnp)(struct cam_periph *, union ccb *),
 		 u_int8_t tag_action, void *buf, u_int32_t alloc_len,
@@ -7938,6 +8012,45 @@ scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
 	scsi_ulto4b(alloc_len, scsi_cmd->length);
 }
 
+void
+scsi_create_timestamp(uint8_t *timestamp_6b_buf,
+		      uint64_t timestamp)
+{
+	uint8_t buf[8];
+	scsi_u64to8b(timestamp, buf);
+	/*
+	 * Using memcopy starting at buf[2] because the set timestamp parameters
+	 * only has six bytes for the timestamp to fit into, and we don't have a
+	 * scsi_u64to6b function.
+	 */
+	memcpy(timestamp_6b_buf, &buf[2], 6);
+}
+
+void
+scsi_set_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
+		   void (*cbfcnp)(struct cam_periph *, union ccb *),
+		   u_int8_t tag_action, void *buf, u_int32_t alloc_len,
+		   u_int8_t sense_len, u_int32_t timeout)
+{
+	struct scsi_timestamp *scsi_cmd;
+
+	cam_fill_csio(csio,
+		      retries,
+		      cbfcnp,
+		      /*flags*/CAM_DIR_OUT,
+		      tag_action,
+		      /*data_ptr*/(u_int8_t *) buf,
+		      /*dxfer_len*/alloc_len,
+		      sense_len,
+		      sizeof(*scsi_cmd),
+		      timeout);
+	scsi_cmd = (struct scsi_timestamp *)&csio->cdb_io.cdb_bytes;
+	bzero(scsi_cmd, sizeof(*scsi_cmd));
+	scsi_cmd->opcode = MAINTENANCE_OUT;
+	scsi_cmd->service_action = SET_TIMESTAMP;
+	scsi_ulto4b(alloc_len, scsi_cmd->length);
+}
+
 /*
  * Syncronize the media to the contents of the cache for
  * the given lba/count pair.  Specifying 0/0 means sync
diff --git a/freebsd/sys/cam/scsi/scsi_all.h b/freebsd/sys/cam/scsi/scsi_all.h
index 1fd4540..9c1376c 100644
--- a/freebsd/sys/cam/scsi/scsi_all.h
+++ b/freebsd/sys/cam/scsi/scsi_all.h
@@ -702,7 +702,9 @@ struct scsi_control_page {
 
 struct scsi_control_ext_page {
 	uint8_t page_code;
+#define SCEP_PAGE_CODE			0x0a
 	uint8_t subpage_code;
+#define SCEP_SUBPAGE_CODE		0x01
 	uint8_t page_length[2];
 	uint8_t flags;
 #define	SCEP_TCMOS			0x04	/* Timestamp Changeable by */
@@ -2971,6 +2973,31 @@ struct scsi_target_group
 	uint8_t control;
 };
 
+struct scsi_timestamp
+{
+	uint8_t opcode;
+	uint8_t service_action;
+	uint8_t reserved1[4];
+	uint8_t length[4];
+	uint8_t reserved2;
+	uint8_t control;
+};
+
+struct scsi_set_timestamp_parameters
+{
+	uint8_t reserved1[4];
+	uint8_t timestamp[6];
+	uint8_t reserved2[4];
+};
+
+struct scsi_report_timestamp_parameter_data
+{
+	uint8_t length[2];
+	uint8_t reserved1[2];
+	uint8_t timestamp[6];
+	uint8_t reserved2[2];
+};
+
 struct scsi_target_port_descriptor {
 	uint8_t	reserved[2];
 	uint8_t	relative_target_port_identifier[2];
@@ -3682,6 +3709,10 @@ void scsi_sense_progress_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
 			      u_int sense_len, uint8_t *cdb, int cdb_len,
 			      struct scsi_inquiry_data *inq_data,
 			      struct scsi_sense_desc_header *header);
+void scsi_sense_ata_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
+			 u_int sense_len, uint8_t *cdb, int cdb_len,
+			 struct scsi_inquiry_data *inq_data,
+			 struct scsi_sense_desc_header *header);
 void scsi_sense_generic_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
 			     u_int sense_len, uint8_t *cdb, int cdb_len,
 			     struct scsi_inquiry_data *inq_data,
@@ -3962,12 +3993,29 @@ void		scsi_report_target_group(struct ccb_scsiio *csio, u_int32_t retries,
 				 u_int32_t alloc_len, u_int8_t sense_len,
 				 u_int32_t timeout);
 
+void		scsi_report_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
+				 void (*cbfcnp)(struct cam_periph *, 
+				 union ccb *), u_int8_t tag_action, 
+				 u_int8_t pdf,
+				 void *buf,
+				 u_int32_t alloc_len, u_int8_t sense_len,
+				 u_int32_t timeout);
+
 void		scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
 				 void (*cbfcnp)(struct cam_periph *, 
 				 union ccb *), u_int8_t tag_action, void *buf,
 				 u_int32_t alloc_len, u_int8_t sense_len,
 				 u_int32_t timeout);
 
+void		scsi_create_timestamp(uint8_t *timestamp_6b_buf,
+				      uint64_t timestamp);
+
+void		scsi_set_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
+				   void (*cbfcnp)(struct cam_periph *, 
+				   union ccb *), u_int8_t tag_action,
+				   void *buf, u_int32_t alloc_len,
+				   u_int8_t sense_len, u_int32_t timeout);
+
 void		scsi_synchronize_cache(struct ccb_scsiio *csio, 
 				       u_int32_t retries,
 				       void (*cbfcnp)(struct cam_periph *, 
diff --git a/freebsd/sys/crypto/sha1.h b/freebsd/sys/crypto/sha1.h
index d61709e..c1bc1a3 100644
--- a/freebsd/sys/crypto/sha1.h
+++ b/freebsd/sys/crypto/sha1.h
@@ -61,7 +61,7 @@ typedef struct sha1_ctxt SHA1_CTX;
 extern void sha1_init(struct sha1_ctxt *);
 extern void sha1_pad(struct sha1_ctxt *);
 extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);
-extern void sha1_result(struct sha1_ctxt *, char[static SHA1_RESULTLEN]);
+extern void sha1_result(struct sha1_ctxt *, char[__min_size(SHA1_RESULTLEN)]);
 
 /* compatibilty with other SHA1 source codes */
 #define SHA1Init(x)		sha1_init((x))
diff --git a/freebsd/sys/crypto/sha2/sha256.h b/freebsd/sys/crypto/sha2/sha256.h
index 17aae7d..bd31a62 100644
--- a/freebsd/sys/crypto/sha2/sha256.h
+++ b/freebsd/sys/crypto/sha2/sha256.h
@@ -59,6 +59,12 @@ __BEGIN_DECLS
 #ifndef SHA256_End
 #define SHA256_End		_libmd_SHA256_End
 #endif
+#ifndef SHA256_Fd
+#define SHA256_Fd		_libmd_SHA256_Fd
+#endif
+#ifndef SHA256_FdChunk
+#define SHA256_FdChunk		_libmd_SHA256_FdChunk
+#endif
 #ifndef SHA256_File
 #define SHA256_File		_libmd_SHA256_File
 #endif
@@ -78,10 +84,13 @@ __BEGIN_DECLS
 
 void	SHA256_Init(SHA256_CTX *);
 void	SHA256_Update(SHA256_CTX *, const void *, size_t);
-void	SHA256_Final(unsigned char [static SHA256_DIGEST_LENGTH], SHA256_CTX *);
+void	SHA256_Final(unsigned char [__min_size(SHA256_DIGEST_LENGTH)],
+    SHA256_CTX *);
 #ifndef _KERNEL
 char   *SHA256_End(SHA256_CTX *, char *);
 char   *SHA256_Data(const void *, unsigned int, char *);
+char   *SHA256_Fd(int, char *);
+char   *SHA256_FdChunk(int, char *, off_t, off_t);
 char   *SHA256_File(const char *, char *);
 char   *SHA256_FileChunk(const char *, char *, off_t, off_t);
 #endif
diff --git a/freebsd/sys/crypto/sha2/sha384.h b/freebsd/sys/crypto/sha2/sha384.h
index 63dd948..0134559 100644
--- a/freebsd/sys/crypto/sha2/sha384.h
+++ b/freebsd/sys/crypto/sha2/sha384.h
@@ -58,6 +58,12 @@ __BEGIN_DECLS
 #ifndef SHA384_End
 #define SHA384_End		_libmd_SHA384_End
 #endif
+#ifndef SHA384_Fd
+#define SHA384_Fd		_libmd_SHA384_Fd
+#endif
+#ifndef SHA384_FdChunk
+#define SHA384_FdChunk		_libmd_SHA384_FdChunk
+#endif
 #ifndef SHA384_File
 #define SHA384_File		_libmd_SHA384_File
 #endif
@@ -74,10 +80,13 @@ __BEGIN_DECLS
 
 void	SHA384_Init(SHA384_CTX *);
 void	SHA384_Update(SHA384_CTX *, const void *, size_t);
-void	SHA384_Final(unsigned char [static SHA384_DIGEST_LENGTH], SHA384_CTX *);
+void	SHA384_Final(unsigned char [__min_size(SHA384_DIGEST_LENGTH)],
+    SHA384_CTX *);
 #ifndef _KERNEL
 char   *SHA384_End(SHA384_CTX *, char *);
 char   *SHA384_Data(const void *, unsigned int, char *);
+char   *SHA384_Fd(int, char *);
+char   *SHA384_FdChunk(int, char *, off_t, off_t);
 char   *SHA384_File(const char *, char *);
 char   *SHA384_FileChunk(const char *, char *, off_t, off_t);
 #endif
diff --git a/freebsd/sys/crypto/sha2/sha512.h b/freebsd/sys/crypto/sha2/sha512.h
index b008aea..8b3e17c 100644
--- a/freebsd/sys/crypto/sha2/sha512.h
+++ b/freebsd/sys/crypto/sha2/sha512.h
@@ -58,6 +58,12 @@ __BEGIN_DECLS
 #ifndef SHA512_End
 #define SHA512_End		_libmd_SHA512_End
 #endif
+#ifndef SHA512_Fd
+#define SHA512_Fd		_libmd_SHA512_Fd
+#endif
+#ifndef SHA512_FdChunk
+#define SHA512_FdChunk		_libmd_SHA512_FdChunk
+#endif
 #ifndef SHA512_File
 #define SHA512_File		_libmd_SHA512_File
 #endif
@@ -77,10 +83,13 @@ __BEGIN_DECLS
 
 void	SHA512_Init(SHA512_CTX *);
 void	SHA512_Update(SHA512_CTX *, const void *, size_t);
-void	SHA512_Final(unsigned char [static SHA512_DIGEST_LENGTH], SHA512_CTX *);
+void	SHA512_Final(unsigned char [__min_size(SHA512_DIGEST_LENGTH)],
+    SHA512_CTX *);
 #ifndef _KERNEL
 char   *SHA512_End(SHA512_CTX *, char *);
 char   *SHA512_Data(const void *, unsigned int, char *);
+char   *SHA512_Fd(int, char *);
+char   *SHA512_FdChunk(int, char *, off_t, off_t);
 char   *SHA512_File(const char *, char *);
 char   *SHA512_FileChunk(const char *, char *, off_t, off_t);
 #endif
diff --git a/freebsd/sys/crypto/sha2/sha512t.h b/freebsd/sys/crypto/sha2/sha512t.h
index 3f0c921..1ae490f 100644
--- a/freebsd/sys/crypto/sha2/sha512t.h
+++ b/freebsd/sys/crypto/sha2/sha512t.h
@@ -55,6 +55,12 @@ __BEGIN_DECLS
 #ifndef SHA512_224_End
 #define SHA512_224_End		_libmd_SHA512_224_End
 #endif
+#ifndef SHA512_224_Fd
+#define SHA512_224_Fd		_libmd_SHA512_224_Fd
+#endif
+#ifndef SHA512_224_FdChunk
+#define SHA512_224_FdChunk	_libmd_SHA512_224_FdChunk
+#endif
 #ifndef SHA512_224_File
 #define SHA512_224_File		_libmd_SHA512_224_File
 #endif
@@ -84,6 +90,12 @@ __BEGIN_DECLS
 #ifndef SHA512_256_End
 #define SHA512_256_End		_libmd_SHA512_256_End
 #endif
+#ifndef SHA512_256_Fd
+#define SHA512_256_Fd		_libmd_SHA512_256_Fd
+#endif
+#ifndef SHA512_256_FdChunk
+#define SHA512_256_FdChunk	_libmd_SHA512_256_FdChunk
+#endif
 #ifndef SHA512_256_File
 #define SHA512_256_File		_libmd_SHA512_256_File
 #endif
@@ -103,19 +115,25 @@ __BEGIN_DECLS
 
 void	SHA512_224_Init(SHA512_CTX *);
 void	SHA512_224_Update(SHA512_CTX *, const void *, size_t);
-void	SHA512_224_Final(unsigned char [static SHA512_224_DIGEST_LENGTH], SHA512_CTX *);
+void	SHA512_224_Final(unsigned char [__min_size(SHA512_224_DIGEST_LENGTH)],
+    SHA512_CTX *);
 #ifndef _KERNEL
 char   *SHA512_224_End(SHA512_CTX *, char *);
 char   *SHA512_224_Data(const void *, unsigned int, char *);
+char   *SHA512_224_Fd(int, char *);
+char   *SHA512_224_FdChunk(int, char *, off_t, off_t);
 char   *SHA512_224_File(const char *, char *);
 char   *SHA512_224_FileChunk(const char *, char *, off_t, off_t);
 #endif
 void	SHA512_256_Init(SHA512_CTX *);
 void	SHA512_256_Update(SHA512_CTX *, const void *, size_t);
-void	SHA512_256_Final(unsigned char [static SHA512_256_DIGEST_LENGTH], SHA512_CTX *);
+void	SHA512_256_Final(unsigned char [__min_size(SHA512_256_DIGEST_LENGTH)],
+    SHA512_CTX *);
 #ifndef _KERNEL
 char   *SHA512_256_End(SHA512_CTX *, char *);
 char   *SHA512_256_Data(const void *, unsigned int, char *);
+char   *SHA512_256_Fd(int, char *);
+char   *SHA512_256_FdChunk(int, char *, off_t, off_t);
 char   *SHA512_256_File(const char *, char *);
 char   *SHA512_256_FileChunk(const char *, char *, off_t, off_t);
 #endif
diff --git a/freebsd/sys/crypto/siphash/siphash.h b/freebsd/sys/crypto/siphash/siphash.h
index 8bbda4f..235818b 100644
--- a/freebsd/sys/crypto/siphash/siphash.h
+++ b/freebsd/sys/crypto/siphash/siphash.h
@@ -68,15 +68,16 @@ typedef struct _SIPHASH_CTX {
 #define SipHash24_Init(x)	SipHash_InitX((x), 2, 4)
 #define SipHash48_Init(x)	SipHash_InitX((x), 4, 8)
 void SipHash_InitX(SIPHASH_CTX *, int, int);
-void SipHash_SetKey(SIPHASH_CTX *, const uint8_t[static SIPHASH_KEY_LENGTH]);
+void SipHash_SetKey(SIPHASH_CTX *,
+    const uint8_t[__min_size(SIPHASH_KEY_LENGTH)]);
 void SipHash_Update(SIPHASH_CTX *, const void *, size_t);
-void SipHash_Final(uint8_t[static SIPHASH_DIGEST_LENGTH], SIPHASH_CTX *);
+void SipHash_Final(uint8_t[__min_size(SIPHASH_DIGEST_LENGTH)], SIPHASH_CTX *);
 uint64_t SipHash_End(SIPHASH_CTX *);
 
 #define SipHash24(x, y, z, i)	SipHashX((x), 2, 4, (y), (z), (i));
 #define SipHash48(x, y, z, i)	SipHashX((x), 4, 8, (y), (z), (i));
-uint64_t SipHashX(SIPHASH_CTX *, int, int, const uint8_t[static SIPHASH_KEY_LENGTH], const void *,
-    size_t);
+uint64_t SipHashX(SIPHASH_CTX *, int, int,
+    const uint8_t[__min_size(SIPHASH_KEY_LENGTH)], const void *, size_t);
 
 int SipHash24_TestVectors(void);
 
diff --git a/freebsd/sys/crypto/skein/skein_freebsd.h b/freebsd/sys/crypto/skein/skein_freebsd.h
index 935fa09..676b79b 100644
--- a/freebsd/sys/crypto/skein/skein_freebsd.h
+++ b/freebsd/sys/crypto/skein/skein_freebsd.h
@@ -57,9 +57,12 @@ void SKEIN256_Update(SKEIN256_CTX *ctx, const void *in, size_t len);
 void SKEIN512_Update(SKEIN512_CTX *ctx, const void *in, size_t len);
 void SKEIN1024_Update(SKEIN1024_CTX *ctx, const void *in, size_t len);
 
-void SKEIN256_Final(unsigned char digest[static SKEIN256_DIGEST_LENGTH], SKEIN256_CTX *ctx);
-void SKEIN512_Final(unsigned char digest[static SKEIN512_DIGEST_LENGTH], SKEIN512_CTX *ctx);
-void SKEIN1024_Final(unsigned char digest[static SKEIN1024_DIGEST_LENGTH], SKEIN1024_CTX *ctx);
+void SKEIN256_Final(unsigned char digest[__min_size(SKEIN256_DIGEST_LENGTH)],
+    SKEIN256_CTX *ctx);
+void SKEIN512_Final(unsigned char digest[__min_size(SKEIN512_DIGEST_LENGTH)],
+    SKEIN512_CTX *ctx);
+void SKEIN1024_Final(unsigned char digest[__min_size(SKEIN1024_DIGEST_LENGTH)],
+    SKEIN1024_CTX *ctx);
 
 #ifndef _KERNEL
 char   *SKEIN256_End(SKEIN256_CTX *, char *);
@@ -68,6 +71,12 @@ char   *SKEIN1024_End(SKEIN1024_CTX *, char *);
 char   *SKEIN256_Data(const void *, unsigned int, char *);
 char   *SKEIN512_Data(const void *, unsigned int, char *);
 char   *SKEIN1024_Data(const void *, unsigned int, char *);
+char   *SKEIN256_Fd(int, char *);
+char   *SKEIN512_Fd(int, char *);
+char   *SKEIN1024_Fd(int, char *);
+char   *SKEIN256_FdChunk(int, char *, off_t, off_t);
+char   *SKEIN512_FdChunk(int, char *, off_t, off_t);
+char   *SKEIN1024_FdChunk(int, char *, off_t, off_t);
 char   *SKEIN256_File(const char *, char *);
 char   *SKEIN512_File(const char *, char *);
 char   *SKEIN1024_File(const char *, char *);
diff --git a/freebsd/sys/crypto/skein/skein_port.h b/freebsd/sys/crypto/skein/skein_port.h
index 7025a51..ab320b2 100644
--- a/freebsd/sys/crypto/skein/skein_port.h
+++ b/freebsd/sys/crypto/skein/skein_port.h
@@ -137,6 +137,16 @@ void    Skein_Get64_LSB_First(u64b_t *dst,const u08b_t *src,size_t wCnt)
 #define SKEIN512_End		_libmd_SKEIN512_End
 #define SKEIN1024_End		_libmd_SKEIN1024_End
 #endif
+#ifndef SKEIN256_Fd
+#define SKEIN256_Fd		_libmd_SKEIN256_Fd
+#define SKEIN512_Fd		_libmd_SKEIN512_Fd
+#define SKEIN1024_Fd		_libmd_SKEIN1024_Fd
+#endif
+#ifndef SKEIN256_FdChunk
+#define SKEIN256_FdChunk	_libmd_SKEIN256_FdChunk
+#define SKEIN512_FdChunk	_libmd_SKEIN512_FdChunk
+#define SKEIN1024_FdChunk	_libmd_SKEIN1024_FdChunk
+#endif
 #ifndef SKEIN256_File
 #define SKEIN256_File		_libmd_SKEIN256_File
 #define SKEIN512_File		_libmd_SKEIN512_File
diff --git a/freebsd/sys/dev/bfe/if_bfe.c b/freebsd/sys/dev/bfe/if_bfe.c
index c87dea1..a76bc7e 100644
--- a/freebsd/sys/dev/bfe/if_bfe.c
+++ b/freebsd/sys/dev/bfe/if_bfe.c
@@ -795,6 +795,8 @@ bfe_list_newbuf(struct bfe_softc *sc, int c)
 	int nsegs;
 
 	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+	if (m == NULL)
+		return (ENOBUFS);
 	m->m_len = m->m_pkthdr.len = MCLBYTES;
 
 	if (bus_dmamap_load_mbuf_sg(sc->bfe_rxmbuf_tag, sc->bfe_rx_sparemap,
diff --git a/freebsd/sys/dev/e1000/if_em.c b/freebsd/sys/dev/e1000/if_em.c
index fa34dd6..d8c1e5a 100644
--- a/freebsd/sys/dev/e1000/if_em.c
+++ b/freebsd/sys/dev/e1000/if_em.c
@@ -367,16 +367,10 @@ MODULE_DEPEND(em, netmap, 1, 1, 1);
 
 #define EM_TICKS_TO_USECS(ticks)	((1024 * (ticks) + 500) / 1000)
 #define EM_USECS_TO_TICKS(usecs)	((1000 * (usecs) + 512) / 1024)
-#define M_TSO_LEN			66
 
 #define MAX_INTS_PER_SEC	8000
 #define DEFAULT_ITR		(1000000000/(MAX_INTS_PER_SEC * 256))
 
-/* Allow common code without TSO */
-#ifndef CSUM_TSO
-#define CSUM_TSO	0
-#endif
-
 #define TSO_WORKAROUND	4
 
 static SYSCTL_NODE(_hw, OID_AUTO, em, CTLFLAG_RD, 0, "EM driver parameters");
@@ -1399,15 +1393,9 @@ em_init_locked(struct adapter *adapter)
 	if_clearhwassist(ifp);
 	if (if_getcapenable(ifp) & IFCAP_TXCSUM)
 		if_sethwassistbits(ifp, CSUM_TCP | CSUM_UDP, 0);
-	/* 
-	** There have proven to be problems with TSO when not
-	** at full gigabit speed, so disable the assist automatically
-	** when at lower speeds.  -jfv
-	*/
-	if (if_getcapenable(ifp) & IFCAP_TSO4) {
-		if (adapter->link_speed == SPEED_1000)
-			if_sethwassistbits(ifp, CSUM_TSO, 0);
-	}
+
+	if (if_getcapenable(ifp) & IFCAP_TSO4)
+		if_sethwassistbits(ifp, CSUM_TSO, 0);
 
 	/* Configure for OS presence */
 	em_init_manageability(adapter);
@@ -2415,6 +2403,18 @@ em_update_link_status(struct adapter *adapter)
 	if (link_check && (adapter->link_active == 0)) {
 		e1000_get_speed_and_duplex(hw, &adapter->link_speed,
 		    &adapter->link_duplex);
+		/* 
+		** There have proven to be problems with TSO when not
+		** at full gigabit speed, so disable the assist automatically
+		** when at lower speeds.  -jfv
+		*/
+		if (adapter->link_speed != SPEED_1000) {
+			if_sethwassistbits(ifp, 0, CSUM_TSO);
+			if_setcapenablebit(ifp, 0, IFCAP_TSO4);
+        		if_setcapabilitiesbit(ifp, 0, IFCAP_TSO4);
+
+		}
+
 		/* Check if we must disable SPEED_MODE bit on PCI-E */
 		if ((adapter->link_speed != SPEED_1000) &&
 		    ((hw->mac.type == e1000_82571) ||
@@ -5276,6 +5276,8 @@ em_get_wakeup(device_t dev)
 	case e1000_ich10lan:
 	case e1000_pchlan:
 	case e1000_pch2lan:
+	case e1000_pch_lpt:
+	case e1000_pch_spt:
 		apme_mask = E1000_WUC_APME;
 		adapter->has_amt = TRUE;
 		eeprom_data = E1000_READ_REG(&adapter->hw, E1000_WUC);
@@ -5324,7 +5326,7 @@ em_enable_wakeup(device_t dev)
 {
 	struct adapter	*adapter = device_get_softc(dev);
 	if_t ifp = adapter->ifp;
-	u32		pmc, ctrl, ctrl_ext, rctl;
+	u32		pmc, ctrl, ctrl_ext, rctl, wuc;
 	u16     	status;
 
 	if ((pci_find_cap(dev, PCIY_PMG, &pmc) != 0))
@@ -5334,7 +5336,9 @@ em_enable_wakeup(device_t dev)
 	ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
 	ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3);
 	E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
-	E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
+	wuc = E1000_READ_REG(&adapter->hw, E1000_WUC);
+	wuc |= E1000_WUC_PME_EN;
+ 	E1000_WRITE_REG(&adapter->hw, E1000_WUC, wuc);
 
 	if ((adapter->hw.mac.type == e1000_ich8lan) ||
 	    (adapter->hw.mac.type == e1000_pchlan) ||
@@ -5365,8 +5369,10 @@ em_enable_wakeup(device_t dev)
 		E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
 	}
 
-	if ((adapter->hw.mac.type == e1000_pchlan) ||
-	    (adapter->hw.mac.type == e1000_pch2lan)) {
+	if ((adapter->hw.mac.type == e1000_pchlan)  ||
+	    (adapter->hw.mac.type == e1000_pch2lan) ||
+	    (adapter->hw.mac.type == e1000_pch_lpt) ||
+	    (adapter->hw.mac.type == e1000_pch_spt)) {
 		if (em_enable_phy_wakeup(adapter))
 			return;
 	} else {
diff --git a/freebsd/sys/dev/e1000/if_igb.c b/freebsd/sys/dev/e1000/if_igb.c
index d683b85..2e9c725 100644
--- a/freebsd/sys/dev/e1000/if_igb.c
+++ b/freebsd/sys/dev/e1000/if_igb.c
@@ -592,11 +592,20 @@ igb_attach(device_t dev)
 		error = EIO;
 		goto err_late;
 	}
-	/* Check its sanity */
-	if (!igb_is_valid_ether_addr(adapter->hw.mac.addr)) {
-		device_printf(dev, "Invalid MAC address\n");
-		error = EIO;
-		goto err_late;
+
+ 	/* Check its sanity */
+ 	if (!igb_is_valid_ether_addr(adapter->hw.mac.addr)) {
+		if (adapter->vf_ifp) {
+			u8 addr[ETHER_ADDR_LEN];
+			arc4rand(&addr, sizeof(addr), 0);
+			addr[0] &= 0xFE;
+			addr[0] |= 0x02;
+			bcopy(addr, adapter->hw.mac.addr, sizeof(addr));
+		} else {
+			device_printf(dev, "Invalid MAC address\n");
+			error = EIO;
+			goto err_late;
+		}
 	}
 
 	/* Setup OS specific network interface */
diff --git a/freebsd/sys/dev/e1000/if_lem.c b/freebsd/sys/dev/e1000/if_lem.c
index c46c372..b3da1bd 100644
--- a/freebsd/sys/dev/e1000/if_lem.c
+++ b/freebsd/sys/dev/e1000/if_lem.c
@@ -41,7 +41,6 @@
  */
 // #define BATCH_DISPATCH
 // #define NIC_SEND_COMBINING
-// #define NIC_PARAVIRT	/* enable virtio-like synchronization */
 
 #include <rtems/bsd/local/opt_inet.h>
 #include <rtems/bsd/local/opt_inet6.h>
@@ -488,10 +487,6 @@ lem_attach(device_t dev)
 	lem_add_rx_process_limit(adapter, "batch_enable",
 	    "driver rx batch", &adapter->batch_enable, 0);
 #endif /* BATCH_DISPATCH */
-#ifdef NIC_PARAVIRT
-	lem_add_rx_process_limit(adapter, "rx_retries",
-	    "driver rx retries", &adapter->rx_retries, 0);
-#endif /* NIC_PARAVIRT */
 
         /* Sysctl for setting the interface flow control */
 	lem_set_flow_cntrl(adapter, "flow_control",
@@ -550,51 +545,16 @@ lem_attach(device_t dev)
 	 */
 	adapter->hw.mac.report_tx_early = 1;
 
-#ifdef NIC_PARAVIRT
-	device_printf(dev, "driver supports paravirt, subdev 0x%x\n",
-		adapter->hw.subsystem_device_id);
-	if (adapter->hw.subsystem_device_id == E1000_PARA_SUBDEV) {
-		uint64_t bus_addr;
-
-		device_printf(dev, "paravirt support on dev %p\n", adapter);
-		tsize = 4096; // XXX one page for the csb
-		if (lem_dma_malloc(adapter, tsize, &adapter->csb_mem, BUS_DMA_NOWAIT)) {
-			device_printf(dev, "Unable to allocate csb memory\n");
-			error = ENOMEM;
-			goto err_csb;
-		}
-		/* Setup the Base of the CSB */
-		adapter->csb = (struct paravirt_csb *)adapter->csb_mem.dma_vaddr;
-		/* force the first kick */
-		adapter->csb->host_need_txkick = 1; /* txring empty */
-		adapter->csb->guest_need_rxkick = 1; /* no rx packets */
-		bus_addr = adapter->csb_mem.dma_paddr;
-		lem_add_rx_process_limit(adapter, "csb_on",
-		    "enable paravirt.", &adapter->csb->guest_csb_on, 0);
-		lem_add_rx_process_limit(adapter, "txc_lim",
-		    "txc_lim", &adapter->csb->host_txcycles_lim, 1);
-
-		/* some stats */
-#define PA_SC(name, var, val)		\
-	lem_add_rx_process_limit(adapter, name, name, var, val)
-		PA_SC("host_need_txkick",&adapter->csb->host_need_txkick, 1);
-		PA_SC("host_rxkick_at",&adapter->csb->host_rxkick_at, ~0);
-		PA_SC("guest_need_txkick",&adapter->csb->guest_need_txkick, 0);
-		PA_SC("guest_need_rxkick",&adapter->csb->guest_need_rxkick, 1);
-		PA_SC("tdt_reg_count",&adapter->tdt_reg_count, 0);
-		PA_SC("tdt_csb_count",&adapter->tdt_csb_count, 0);
-		PA_SC("tdt_int_count",&adapter->tdt_int_count, 0);
-		PA_SC("guest_need_kick_count",&adapter->guest_need_kick_count, 0);
-		/* tell the host where the block is */
-		E1000_WRITE_REG(&adapter->hw, E1000_CSBAH,
-			(u32)(bus_addr >> 32));
-		E1000_WRITE_REG(&adapter->hw, E1000_CSBAL,
-			(u32)bus_addr);
-	}
-#endif /* NIC_PARAVIRT */
-
-	tsize = roundup2(adapter->num_tx_desc * sizeof(struct e1000_tx_desc),
-	    EM_DBA_ALIGN);
+	/*
+	 * It seems that the descriptor DMA engine on some PCI cards
+	 * fetches memory past the end of the last descriptor in the
+	 * ring.  These reads are problematic when VT-d (DMAR) busdma
+	 * is used.  Allocate the scratch space to avoid getting
+	 * faults from DMAR, by requesting scratch memory for one more
+	 * descriptor.
+	 */
+	tsize = roundup2((adapter->num_tx_desc + 1) *
+	    sizeof(struct e1000_tx_desc), EM_DBA_ALIGN);
 
 	/* Allocate Transmit Descriptor ring */
 	if (lem_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
@@ -605,8 +565,11 @@ lem_attach(device_t dev)
 	adapter->tx_desc_base = 
 	    (struct e1000_tx_desc *)adapter->txdma.dma_vaddr;
 
-	rsize = roundup2(adapter->num_rx_desc * sizeof(struct e1000_rx_desc),
-	    EM_DBA_ALIGN);
+	/*
+	 * See comment above txdma allocation for rationale behind +1.
+	 */
+	rsize = roundup2((adapter->num_rx_desc + 1) *
+	    sizeof(struct e1000_rx_desc), EM_DBA_ALIGN);
 
 	/* Allocate Receive Descriptor ring */
 	if (lem_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {
@@ -751,11 +714,6 @@ err_hw_init:
 err_rx_desc:
 	lem_dma_free(adapter, &adapter->txdma);
 err_tx_desc:
-#ifdef NIC_PARAVIRT
-	lem_dma_free(adapter, &adapter->csb_mem);
-err_csb:
-#endif /* NIC_PARAVIRT */
-
 err_pci:
 	if (adapter->ifp != (void *)NULL)
 		if_free(adapter->ifp);
@@ -843,12 +801,6 @@ lem_detach(device_t dev)
 		adapter->rx_desc_base = NULL;
 	}
 
-#ifdef NIC_PARAVIRT
-	if (adapter->csb) {
-		lem_dma_free(adapter, &adapter->csb_mem);
-		adapter->csb = NULL;
-	}
-#endif /* NIC_PARAVIRT */
 	lem_release_hw_control(adapter);
 	free(adapter->mta, M_DEVBUF);
 	EM_TX_LOCK_DESTROY(adapter);
@@ -958,16 +910,6 @@ lem_start_locked(if_t ifp)
 	}
 	if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD)
 		if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0);
-#ifdef NIC_PARAVIRT
-	if (if_getdrvflags(ifp) & IFF_DRV_OACTIVE && adapter->csb &&
-	    adapter->csb->guest_csb_on &&
-	    !(adapter->csb->guest_need_txkick & 1))  {
-		adapter->csb->guest_need_txkick = 1;
-		adapter->guest_need_kick_count++;
-		// XXX memory barrier
-		lem_txeof(adapter); // XXX possibly clear IFF_DRV_OACTIVE
-	}
-#endif /* NIC_PARAVIRT */
 
 	return;
 }
@@ -1815,24 +1757,6 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp)
 	bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
-#ifdef NIC_PARAVIRT
-	if (adapter->csb) {
-		adapter->csb->guest_tdt = i;
-		/* XXX memory barrier ? */
- 		if (adapter->csb->guest_csb_on &&
-		    !(adapter->csb->host_need_txkick & 1)) {
-			/* XXX maybe useless
-			 * clean the ring. maybe do it before ?
-			 * maybe a little bit of histeresys ?
-			 */
-			if (adapter->num_tx_desc_avail <= 64) {// XXX
-				lem_txeof(adapter);
-			}
-			return (0);
-		}
-	}
-#endif /* NIC_PARAVIRT */
-
 #ifdef NIC_SEND_COMBINING
 	if (adapter->sc_enable) {
 		if (adapter->shadow_tdt & MIT_PENDING_INT) {
@@ -2088,20 +2012,6 @@ lem_local_timer(void *arg)
 
 	lem_smartspeed(adapter);
 
-#ifdef NIC_PARAVIRT
-	/* recover space if needed */
-	if (adapter->csb && adapter->csb->guest_csb_on &&
-	    (adapter->watchdog_check == TRUE) &&
-	    (ticks - adapter->watchdog_time > EM_WATCHDOG) &&
-	    (adapter->num_tx_desc_avail != adapter->num_tx_desc) ) {
-		lem_txeof(adapter);
-		/*
-		 * lem_txeof() normally (except when space in the queue
-		 * runs low XXX) cleans watchdog_check so that
-		 * we do not hung.
-		 */
-	}
-#endif /* NIC_PARAVIRT */
 	/*
 	 * We check the watchdog: the time since
 	 * the last TX descriptor was cleaned.
@@ -3178,12 +3088,6 @@ lem_txeof(struct adapter *adapter)
          */
         if (adapter->num_tx_desc_avail > EM_TX_CLEANUP_THRESHOLD) {                
                 if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE);
-#ifdef NIC_PARAVIRT
-		if (adapter->csb) { // XXX also csb_on ?
-			adapter->csb->guest_need_txkick = 2; /* acked */
-			// XXX memory barrier
-		}
-#endif /* NIC_PARAVIRT */
                 if (adapter->num_tx_desc_avail == adapter->num_tx_desc) {
 			adapter->watchdog_check = FALSE;
 			return;
@@ -3572,15 +3476,6 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
 #ifdef BATCH_DISPATCH
 	struct mbuf *mh = NULL, *mt = NULL;
 #endif /* BATCH_DISPATCH */
-#ifdef NIC_PARAVIRT
-	int retries = 0;
-	struct paravirt_csb* csb = adapter->csb;
-	int csb_mode = csb && csb->guest_csb_on;
-
-	//ND("clear guest_rxkick at %d", adapter->next_rx_desc_to_check);
-	if (csb_mode && csb->guest_need_rxkick)
-		csb->guest_need_rxkick = 0;
-#endif /* NIC_PARAVIRT */
 	EM_RX_LOCK(adapter);
 
 #ifdef BATCH_DISPATCH
@@ -3598,45 +3493,20 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
 	}
 #endif /* DEV_NETMAP */
 
-#if 1 // XXX optimization ?
 	if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
 		if (done != NULL)
 			*done = rx_sent;
 		EM_RX_UNLOCK(adapter);
 		return (FALSE);
 	}
-#endif /* 0 */
 
 	while (count != 0 && if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
 		struct mbuf *m = NULL;
 
 		status = current_desc->status;
 		if ((status & E1000_RXD_STAT_DD) == 0) {
-#ifdef NIC_PARAVIRT
-		    if (csb_mode) {
-			/* buffer not ready yet. Retry a few times before giving up */
-			if (++retries <= adapter->rx_retries) {
-				continue;
-			}
-			if (csb->guest_need_rxkick == 0) {
-				// ND("set guest_rxkick at %d", adapter->next_rx_desc_to_check);
-				csb->guest_need_rxkick = 1;
-				// XXX memory barrier, status volatile ?
-				continue; /* double check */
-			}
-		    }
-		    /* no buffer ready, give up */
-#endif /* NIC_PARAVIRT */
 			break;
 		}
-#ifdef NIC_PARAVIRT
-		if (csb_mode) {
-			if (csb->guest_need_rxkick)
-				// ND("clear again guest_rxkick at %d", adapter->next_rx_desc_to_check);
-			csb->guest_need_rxkick = 0;
-			retries = 0;
-		}
-#endif /* NIC_PARAVIRT */
 
 		mp = adapter->rx_buffer_area[i].m_head;
 		/*
@@ -3761,18 +3631,6 @@ discard:
 		bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
-#ifdef NIC_PARAVIRT
-		if (csb_mode) {
-			/* the buffer at i has been already replaced by lem_get_buf()
-			 * so it is safe to set guest_rdt = i and possibly send a kick.
-			 * XXX see if we can optimize it later.
-			 */
-			csb->guest_rdt = i;
-			// XXX memory barrier
-			if (i == csb->host_rxkick_at)
-				E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
-		}
-#endif /* NIC_PARAVIRT */
 		/* Advance our pointers to the next descriptor. */
 		if (++i == adapter->num_rx_desc)
 			i = 0;
@@ -3819,9 +3677,6 @@ discard:
 	/* Advance the E1000's Receive Queue #0  "Tail Pointer". */
 	if (--i < 0)
 		i = adapter->num_rx_desc - 1;
-#ifdef NIC_PARAVIRT
-	if (!csb_mode) /* filter out writes */
-#endif /* NIC_PARAVIRT */
 	E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
 	if (done != NULL)
 		*done = rx_sent;
diff --git a/freebsd/sys/dev/mii/rgephy.c b/freebsd/sys/dev/mii/rgephy.c
index 067bbad..963197a 100644
--- a/freebsd/sys/dev/mii/rgephy.c
+++ b/freebsd/sys/dev/mii/rgephy.c
@@ -123,6 +123,8 @@ rgephy_attach(device_t dev)
 	flags = 0;
 	if (mii_dev_mac_match(dev, "re"))
 		flags |= MIIF_PHYPRIV0;
+	else if (mii_dev_mac_match(dev, "ure"))
+		flags |= MIIF_PHYPRIV1;
 	mii_phy_dev_attach(dev, flags, &rgephy_funcs, 0);
 
 	/* RTL8169S do not report auto-sense; add manually. */
@@ -295,7 +297,10 @@ rgephy_linkup(struct mii_softc *sc)
 				linkup++;
 		}
 	} else {
-		reg = PHY_READ(sc, RL_GMEDIASTAT);
+		if (sc->mii_flags & MIIF_PHYPRIV1)
+			reg = PHY_READ(sc, URE_GMEDIASTAT);
+		else
+			reg = PHY_READ(sc, RL_GMEDIASTAT);
 		if (reg & RL_GMEDIASTAT_LINK)
 			linkup++;
 	}
@@ -380,7 +385,10 @@ rgephy_status(struct mii_softc *sc)
 				mii->mii_media_active |= IFM_HDX;
 		}
 	} else {
-		bmsr = PHY_READ(sc, RL_GMEDIASTAT);
+		if (sc->mii_flags & MIIF_PHYPRIV1)
+			bmsr = PHY_READ(sc, URE_GMEDIASTAT);
+		else
+			bmsr = PHY_READ(sc, RL_GMEDIASTAT);
 		if (bmsr & RL_GMEDIASTAT_1000MBPS)
 			mii->mii_media_active |= IFM_1000_T;
 		else if (bmsr & RL_GMEDIASTAT_100MBPS)
diff --git a/freebsd/sys/dev/mii/rgephyreg.h b/freebsd/sys/dev/mii/rgephyreg.h
index 7c24a1f..35917da 100644
--- a/freebsd/sys/dev/mii/rgephyreg.h
+++ b/freebsd/sys/dev/mii/rgephyreg.h
@@ -199,4 +199,7 @@
 #define	EEELPAR_1000T		0x0004	/* link partner 1000baseT EEE capable */
 #define	EEELPAR_100TX		0x0002	/* link partner 100baseTX EEE capable */
 
+/* RTL8153 */
+#define	URE_GMEDIASTAT		0xe908	/* media status register */
+
 #endif /* _DEV_RGEPHY_MIIREG_H_ */
diff --git a/freebsd/sys/dev/nvme/nvme.h b/freebsd/sys/dev/nvme/nvme.h
index 755e376..9c1dab1 100644
--- a/freebsd/sys/dev/nvme/nvme.h
+++ b/freebsd/sys/dev/nvme/nvme.h
@@ -663,9 +663,27 @@ enum nvme_log_page {
 	NVME_LOG_ERROR			= 0x01,
 	NVME_LOG_HEALTH_INFORMATION	= 0x02,
 	NVME_LOG_FIRMWARE_SLOT		= 0x03,
-	/* 0x04-0x7F - reserved */
+	NVME_LOG_CHANGED_NAMESPACE	= 0x04,
+	NVME_LOG_COMMAND_EFFECT		= 0x05,
+	/* 0x06-0x7F - reserved */
 	/* 0x80-0xBF - I/O command set specific */
+	NVME_LOG_RES_NOTIFICATION	= 0x80,
 	/* 0xC0-0xFF - vendor specific */
+
+	/*
+	 * The following are Intel Specific log pages, but they seem
+	 * to be widely implemented.
+	 */
+	INTEL_LOG_READ_LAT_LOG		= 0xc1,
+	INTEL_LOG_WRITE_LAT_LOG		= 0xc2,
+	INTEL_LOG_TEMP_STATS		= 0xc5,
+	INTEL_LOG_ADD_SMART		= 0xca,
+	INTEL_LOG_DRIVE_MKT_NAME	= 0xdd,
+
+	/*
+	 * HGST log page, with lots ofs sub pages.
+	 */
+	HGST_INFO_LOG			= 0xc1,
 };
 
 struct nvme_error_information_entry {
@@ -724,8 +742,11 @@ struct nvme_health_information_page {
 	uint64_t		unsafe_shutdowns[2];
 	uint64_t		media_errors[2];
 	uint64_t		num_error_info_log_entries[2];
+	uint32_t		warning_temp_time;
+	uint32_t		error_temp_time;
+	uint16_t		temp_sensor[8];
 
-	uint8_t			reserved2[320];
+	uint8_t			reserved2[296];
 } __packed __aligned(4);
 
 struct nvme_firmware_page {
@@ -740,6 +761,19 @@ struct nvme_firmware_page {
 	uint8_t			reserved2[448];
 } __packed __aligned(4);
 
+struct intel_log_temp_stats
+{
+	uint64_t	current;
+	uint64_t	overtemp_flag_last;
+	uint64_t	overtemp_flag_life;
+	uint64_t	max_temp;
+	uint64_t	min_temp;
+	uint64_t	_rsvd[5];
+	uint64_t	max_oper_temp;
+	uint64_t	min_oper_temp;
+	uint64_t	est_offset;
+} __packed __aligned(4);
+
 #define NVME_TEST_MAX_THREADS	128
 
 struct nvme_io_test {
diff --git a/freebsd/sys/dev/pci/pci.c b/freebsd/sys/dev/pci/pci.c
index 789825d..211562f 100644
--- a/freebsd/sys/dev/pci/pci.c
+++ b/freebsd/sys/dev/pci/pci.c
@@ -3981,7 +3981,7 @@ pci_rescan_method(device_t dev)
 		if (hdrtype & PCIM_MFDEV)
 			pcifunchigh = PCIB_MAXFUNCS(pcib);
 		for (f = 0; f <= pcifunchigh; f++) {
-			if (REG(PCIR_VENDOR, 2) == 0xfff)
+			if (REG(PCIR_VENDOR, 2) == 0xffff)
 				continue;
 
 			/*
@@ -4081,6 +4081,7 @@ pci_add_child(device_t bus, struct pci_devinfo *dinfo)
 	pci_print_verbose(dinfo);
 	pci_add_resources(bus, dinfo->cfg.dev, 0, 0);
 	pci_child_added(dinfo->cfg.dev);
+	EVENTHANDLER_INVOKE(pci_add_device, dinfo->cfg.dev);
 }
 
 void
@@ -4617,6 +4618,9 @@ static const struct
 	{PCIC_CRYPTO,		PCIS_CRYPTO_ENTERTAIN,	1, "entertainment crypto"},
 	{PCIC_DASP,		-1,			0, "dasp"},
 	{PCIC_DASP,		PCIS_DASP_DPIO,		1, "DPIO module"},
+	{PCIC_DASP,		PCIS_DASP_PERFCNTRS,	1, "performance counters"},
+	{PCIC_DASP,		PCIS_DASP_COMM_SYNC,	1, "communication synchronizer"},
+	{PCIC_DASP,		PCIS_DASP_MGMT_CARD,	1, "signal processing management"},
 	{0, 0, 0,		NULL}
 };
 
@@ -5009,6 +5013,7 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
 	struct resource_list *rl = &dinfo->resources;
 	struct resource *res;
 	struct pci_map *pm;
+	uint16_t cmd;
 	pci_addr_t map, testval;
 	int mapsize;
 
@@ -5107,8 +5112,17 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
 		device_printf(child,
 		    "Lazy allocation of %#jx bytes rid %#x type %d at %#jx\n",
 		    count, *rid, type, rman_get_start(res));
+
+	/* Disable decoding via the CMD register before updating the BAR */
+	cmd = pci_read_config(child, PCIR_COMMAND, 2);
+	pci_write_config(child, PCIR_COMMAND,
+	    cmd & ~(PCI_BAR_MEM(map) ? PCIM_CMD_MEMEN : PCIM_CMD_PORTEN), 2);
+
 	map = rman_get_start(res);
 	pci_write_bar(child, pm, map);
+
+	/* Restore the original value of the CMD register */
+	pci_write_config(child, PCIR_COMMAND, cmd, 2);
 out:
 	return (res);
 }
@@ -5331,6 +5345,8 @@ pci_child_deleted(device_t dev, device_t child)
 	dinfo = device_get_ivars(child);
 	rl = &dinfo->resources;
 
+	EVENTHANDLER_INVOKE(pci_delete_device, child);
+
 	/* Turn off access to resources we're about to free */
 	if (bus_child_present(child) != 0) {
 		pci_write_config(child, PCIR_COMMAND, pci_read_config(child,
@@ -5908,3 +5924,165 @@ pci_find_pcie_root_port(device_t dev)
 		dev = pcib;
 	}
 }
+
+/*
+ * Wait for pending transactions to complete on a PCI-express function.
+ *
+ * The maximum delay is specified in milliseconds in max_delay.  Note
+ * that this function may sleep.
+ *
+ * Returns true if the function is idle and false if the timeout is
+ * exceeded.  If dev is not a PCI-express function, this returns true.
+ */
+bool
+pcie_wait_for_pending_transactions(device_t dev, u_int max_delay)
+{
+	struct pci_devinfo *dinfo = device_get_ivars(dev);
+	uint16_t sta;
+	int cap;
+
+	cap = dinfo->cfg.pcie.pcie_location;
+	if (cap == 0)
+		return (true);
+
+	sta = pci_read_config(dev, cap + PCIER_DEVICE_STA, 2);
+	while (sta & PCIEM_STA_TRANSACTION_PND) {
+		if (max_delay == 0)
+			return (false);
+
+		/* Poll once every 100 milliseconds up to the timeout. */
+		if (max_delay > 100) {
+			pause_sbt("pcietp", 100 * SBT_1MS, 0, C_HARDCLOCK);
+			max_delay -= 100;
+		} else {
+			pause_sbt("pcietp", max_delay * SBT_1MS, 0,
+			    C_HARDCLOCK);
+			max_delay = 0;
+		}
+		sta = pci_read_config(dev, cap + PCIER_DEVICE_STA, 2);
+	}
+
+	return (true);
+}
+
+/*
+ * Determine the maximum Completion Timeout in microseconds.
+ *
+ * For non-PCI-express functions this returns 0.
+ */
+int
+pcie_get_max_completion_timeout(device_t dev)
+{
+	struct pci_devinfo *dinfo = device_get_ivars(dev);
+	int cap;
+
+	cap = dinfo->cfg.pcie.pcie_location;
+	if (cap == 0)
+		return (0);
+
+	/*
+	 * Functions using the 1.x spec use the default timeout range of
+	 * 50 microseconds to 50 milliseconds.  Functions that do not
+	 * support programmable timeouts also use this range.
+	 */
+	if ((dinfo->cfg.pcie.pcie_flags & PCIEM_FLAGS_VERSION) < 2 ||
+	    (pci_read_config(dev, cap + PCIER_DEVICE_CAP2, 4) &
+	    PCIEM_CAP2_COMP_TIMO_RANGES) == 0)
+		return (50 * 1000);
+
+	switch (pci_read_config(dev, cap + PCIER_DEVICE_CTL2, 2) &
+	    PCIEM_CTL2_COMP_TIMO_VAL) {
+	case PCIEM_CTL2_COMP_TIMO_100US:
+		return (100);
+	case PCIEM_CTL2_COMP_TIMO_10MS:
+		return (10 * 1000);
+	case PCIEM_CTL2_COMP_TIMO_55MS:
+		return (55 * 1000);
+	case PCIEM_CTL2_COMP_TIMO_210MS:
+		return (210 * 1000);
+	case PCIEM_CTL2_COMP_TIMO_900MS:
+		return (900 * 1000);
+	case PCIEM_CTL2_COMP_TIMO_3500MS:
+		return (3500 * 1000);
+	case PCIEM_CTL2_COMP_TIMO_13S:
+		return (13 * 1000 * 1000);
+	case PCIEM_CTL2_COMP_TIMO_64S:
+		return (64 * 1000 * 1000);
+	default:
+		return (50 * 1000);
+	}
+}
+
+/*
+ * Perform a Function Level Reset (FLR) on a device.
+ *
+ * This function first waits for any pending transactions to complete
+ * within the timeout specified by max_delay.  If transactions are
+ * still pending, the function will return false without attempting a
+ * reset.
+ *
+ * If dev is not a PCI-express function or does not support FLR, this
+ * function returns false.
+ *
+ * Note that no registers are saved or restored.  The caller is
+ * responsible for saving and restoring any registers including
+ * PCI-standard registers via pci_save_state() and
+ * pci_restore_state().
+ */
+bool
+pcie_flr(device_t dev, u_int max_delay, bool force)
+{
+	struct pci_devinfo *dinfo = device_get_ivars(dev);
+	uint16_t cmd, ctl;
+	int compl_delay;
+	int cap;
+
+	cap = dinfo->cfg.pcie.pcie_location;
+	if (cap == 0)
+		return (false);
+
+	if (!(pci_read_config(dev, cap + PCIER_DEVICE_CAP, 4) & PCIEM_CAP_FLR))
+		return (false);
+
+	/*
+	 * Disable busmastering to prevent generation of new
+	 * transactions while waiting for the device to go idle.  If
+	 * the idle timeout fails, the command register is restored
+	 * which will re-enable busmastering.
+	 */
+	cmd = pci_read_config(dev, PCIR_COMMAND, 2);
+	pci_write_config(dev, PCIR_COMMAND, cmd & ~(PCIM_CMD_BUSMASTEREN), 2);
+	if (!pcie_wait_for_pending_transactions(dev, max_delay)) {
+		if (!force) {
+			pci_write_config(dev, PCIR_COMMAND, cmd, 2);
+			return (false);
+		}
+		pci_printf(&dinfo->cfg,
+		    "Resetting with transactions pending after %d ms\n",
+		    max_delay);
+
+		/*
+		 * Extend the post-FLR delay to cover the maximum
+		 * Completion Timeout delay of anything in flight
+		 * during the FLR delay.  Enforce a minimum delay of
+		 * at least 10ms.
+		 */
+		compl_delay = pcie_get_max_completion_timeout(dev) / 1000;
+		if (compl_delay < 10)
+			compl_delay = 10;
+	} else
+		compl_delay = 0;
+
+	/* Initiate the reset. */
+	ctl = pci_read_config(dev, cap + PCIER_DEVICE_CTL, 2);
+	pci_write_config(dev, cap + PCIER_DEVICE_CTL, ctl |
+	    PCIEM_CTL_INITIATE_FLR, 2);
+
+	/* Wait for 100ms. */
+	pause_sbt("pcieflr", (100 + compl_delay) * SBT_1MS, 0, C_HARDCLOCK);
+
+	if (pci_read_config(dev, cap + PCIER_DEVICE_STA, 2) &
+	    PCIEM_STA_TRANSACTION_PND)
+		pci_printf(&dinfo->cfg, "Transactions pending after FLR!\n");
+	return (true);
+}
diff --git a/freebsd/sys/dev/pci/pcireg.h b/freebsd/sys/dev/pci/pcireg.h
index d463b7a..291bb2e 100644
--- a/freebsd/sys/dev/pci/pcireg.h
+++ b/freebsd/sys/dev/pci/pcireg.h
@@ -885,10 +885,25 @@
 #define	PCIEM_ROOT_STA_PME_STATUS	0x00010000
 #define	PCIEM_ROOT_STA_PME_PEND		0x00020000
 #define	PCIER_DEVICE_CAP2	0x24
-#define	PCIEM_CAP2_ARI		0x20
+#define	PCIEM_CAP2_COMP_TIMO_RANGES	0x0000000f
+#define	PCIEM_CAP2_COMP_TIMO_RANGE_A	0x00000001
+#define	PCIEM_CAP2_COMP_TIMO_RANGE_B	0x00000002
+#define	PCIEM_CAP2_COMP_TIMO_RANGE_C	0x00000004
+#define	PCIEM_CAP2_COMP_TIMO_RANGE_D	0x00000008
+#define	PCIEM_CAP2_COMP_TIMO_DISABLE	0x00000010
+#define	PCIEM_CAP2_ARI			0x00000020
 #define	PCIER_DEVICE_CTL2	0x28
-#define	PCIEM_CTL2_COMP_TIMEOUT_VAL	0x000f
-#define	PCIEM_CTL2_COMP_TIMEOUT_DIS	0x0010
+#define	PCIEM_CTL2_COMP_TIMO_VAL	0x000f
+#define	PCIEM_CTL2_COMP_TIMO_50MS	0x0000
+#define	PCIEM_CTL2_COMP_TIMO_100US	0x0001
+#define	PCIEM_CTL2_COMP_TIMO_10MS	0x0002
+#define	PCIEM_CTL2_COMP_TIMO_55MS	0x0005
+#define	PCIEM_CTL2_COMP_TIMO_210MS	0x0006
+#define	PCIEM_CTL2_COMP_TIMO_900MS	0x0009
+#define	PCIEM_CTL2_COMP_TIMO_3500MS	0x000a
+#define	PCIEM_CTL2_COMP_TIMO_13S	0x000d
+#define	PCIEM_CTL2_COMP_TIMO_64S	0x000e
+#define	PCIEM_CTL2_COMP_TIMO_DISABLE	0x0010
 #define	PCIEM_CTL2_ARI			0x0020
 #define	PCIEM_CTL2_ATOMIC_REQ_ENABLE	0x0040
 #define	PCIEM_CTL2_ATOMIC_EGR_BLOCK	0x0080
diff --git a/freebsd/sys/dev/pci/pcivar.h b/freebsd/sys/dev/pci/pcivar.h
index fc3fa5f..4652715 100644
--- a/freebsd/sys/dev/pci/pcivar.h
+++ b/freebsd/sys/dev/pci/pcivar.h
@@ -31,6 +31,7 @@
 #define	_PCIVAR_H_
 
 #include <sys/queue.h>
+#include <sys/eventhandler.h>
 
 /* some PCI bus constants */
 #define	PCI_MAXMAPS_0	6	/* max. no. of memory/port maps */
@@ -594,7 +595,9 @@ uint32_t pcie_read_config(device_t dev, int reg, int width);
 void	pcie_write_config(device_t dev, int reg, uint32_t value, int width);
 uint32_t pcie_adjust_config(device_t dev, int reg, uint32_t mask,
 	    uint32_t value, int width);
-
+bool	pcie_flr(device_t dev, u_int max_delay, bool force);
+int	pcie_get_max_completion_timeout(device_t dev);
+bool	pcie_wait_for_pending_transactions(device_t dev, u_int max_delay);
 
 #ifdef BUS_SPACE_MAXADDR
 #if (BUS_SPACE_MAXADDR > 0xFFFFFFFF)
@@ -631,4 +634,12 @@ void *	vga_pci_map_bios(device_t dev, size_t *size);
 void	vga_pci_unmap_bios(device_t dev, void *bios);
 int	vga_pci_repost(device_t dev);
 
+/**
+ * Global eventhandlers invoked when PCI devices are added or removed
+ * from the system.
+ */
+typedef void (*pci_event_fn)(void *arg, device_t dev);
+EVENTHANDLER_DECLARE(pci_add_device, pci_event_fn);
+EVENTHANDLER_DECLARE(pci_delete_device, pci_event_fn);
+
 #endif /* _PCIVAR_H_ */
diff --git a/freebsd/sys/dev/re/if_re.c b/freebsd/sys/dev/re/if_re.c
index 554af66..7e0e87f 100644
--- a/freebsd/sys/dev/re/if_re.c
+++ b/freebsd/sys/dev/re/if_re.c
@@ -185,6 +185,8 @@ static const struct rl_type re_devs[] = {
 	    "RealTek 810xE PCIe 10/100baseTX" },
 	{ RT_VENDORID, RT_DEVICEID_8168, 0,
 	    "RealTek 8168/8111 B/C/CP/D/DP/E/F/G PCIe Gigabit Ethernet" },
+	{ NCUBE_VENDORID, RT_DEVICEID_8168, 0,
+	    "TP-Link TG-3468 v2 (RTL8168) Gigabit Ethernet" },
 	{ RT_VENDORID, RT_DEVICEID_8169, 0,
 	    "RealTek 8169/8169S/8169SB(L)/8110S/8110SB(L) Gigabit Ethernet" },
 	{ RT_VENDORID, RT_DEVICEID_8169SC, 0,
@@ -1358,15 +1360,17 @@ re_attach(device_t dev)
 		CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
 	}
 
-	/* Disable ASPM L0S/L1. */
+	/* Disable ASPM L0S/L1 and CLKREQ. */
 	if (sc->rl_expcap != 0) {
 		cap = pci_read_config(dev, sc->rl_expcap +
 		    PCIER_LINK_CAP, 2);
 		if ((cap & PCIEM_LINK_CAP_ASPM) != 0) {
 			ctl = pci_read_config(dev, sc->rl_expcap +
 			    PCIER_LINK_CTL, 2);
-			if ((ctl & PCIEM_LINK_CTL_ASPMC) != 0) {
-				ctl &= ~PCIEM_LINK_CTL_ASPMC;
+			if ((ctl & (PCIEM_LINK_CTL_ECPM |
+			    PCIEM_LINK_CTL_ASPMC))!= 0) {
+				ctl &= ~(PCIEM_LINK_CTL_ECPM |
+				    PCIEM_LINK_CTL_ASPMC);
 				pci_write_config(dev, sc->rl_expcap +
 				    PCIER_LINK_CTL, ctl, 2);
 				device_printf(dev, "ASPM disabled\n");
diff --git a/freebsd/sys/dev/rl/if_rlreg.h b/freebsd/sys/dev/rl/if_rlreg.h
index 2cef251..2fa44ef 100644
--- a/freebsd/sys/dev/rl/if_rlreg.h
+++ b/freebsd/sys/dev/rl/if_rlreg.h
@@ -1158,3 +1158,8 @@ struct rl_softc {
 /* US Robotics 997902 device ID */
 
 #define	USR_DEVICEID_997902	0x0116
+
+/* 
+ * NCube vendor ID
+ */
+#define	NCUBE_VENDORID		0x10FF
diff --git a/freebsd/sys/dev/tsec/if_tsec.h b/freebsd/sys/dev/tsec/if_tsec.h
index 108b0f2..60a565e 100644
--- a/freebsd/sys/dev/tsec/if_tsec.h
+++ b/freebsd/sys/dev/tsec/if_tsec.h
@@ -137,6 +137,7 @@ struct tsec_softc {
 	int		phyaddr;
 	bus_space_tag_t phy_bst;
 	bus_space_handle_t phy_bsh;
+	int		phy_regoff;
 };
 
 /* interface to get/put generic objects */
@@ -260,9 +261,11 @@ extern struct mtx tsec_phy_mtx;
 #define TSEC_PHY_LOCK(sc)	mtx_lock(&tsec_phy_mtx)
 #define TSEC_PHY_UNLOCK(sc)	mtx_unlock(&tsec_phy_mtx)
 #define TSEC_PHY_READ(sc, reg)		\
-		bus_space_read_4((sc)->phy_bst, (sc)->phy_bsh, (reg))
+		bus_space_read_4((sc)->phy_bst, (sc)->phy_bsh, \
+			(reg) + (sc)->phy_regoff)
 #define TSEC_PHY_WRITE(sc, reg, val)	\
-		bus_space_write_4((sc)->phy_bst, (sc)->phy_bsh, (reg), (val))
+		bus_space_write_4((sc)->phy_bst, (sc)->phy_bsh, \
+			(reg) + (sc)->phy_regoff, (val))
 
 /* Lock for transmitter */
 #define TSEC_TRANSMIT_LOCK(sc) do {					\
diff --git a/freebsd/sys/dev/usb/controller/dwc_otg.c b/freebsd/sys/dev/usb/controller/dwc_otg.c
index d070f14..3450f6d 100644
--- a/freebsd/sys/dev/usb/controller/dwc_otg.c
+++ b/freebsd/sys/dev/usb/controller/dwc_otg.c
@@ -100,10 +100,6 @@
    GINTSTS_WKUPINT | GINTSTS_USBSUSP | GINTMSK_OTGINTMSK |	\
    GINTSTS_SESSREQINT)
 
-#define	DWC_OTG_PHY_ULPI 0
-#define	DWC_OTG_PHY_HSIC 1
-#define	DWC_OTG_PHY_INTERNAL 2
-
 #ifndef DWC_OTG_PHY_DEFAULT
 #define	DWC_OTG_PHY_DEFAULT DWC_OTG_PHY_ULPI
 #endif
@@ -112,10 +108,10 @@ static int dwc_otg_phy_type = DWC_OTG_PHY_DEFAULT;
 
 static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW, 0, "USB DWC OTG");
 SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, phy_type, CTLFLAG_RDTUN,
-    &dwc_otg_phy_type, 0, "DWC OTG PHY TYPE - 0/1/2 - ULPI/HSIC/INTERNAL");
+    &dwc_otg_phy_type, 0, "DWC OTG PHY TYPE - 0/1/2/3 - ULPI/HSIC/INTERNAL/UTMI+");
 
 #ifdef USB_DEBUG
-static int dwc_otg_debug;
+static int dwc_otg_debug = 0;
 
 SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, debug, CTLFLAG_RWTUN,
     &dwc_otg_debug, 0, "DWC OTG debug level");
@@ -3891,8 +3887,13 @@ dwc_otg_init(struct dwc_otg_softc *sc)
 		break;
 	}
 
-	/* select HSIC, ULPI or internal PHY mode */
-	switch (dwc_otg_phy_type) {
+	if (sc->sc_phy_type == 0)
+		sc->sc_phy_type = dwc_otg_phy_type + 1;
+	if (sc->sc_phy_bits == 0)
+		sc->sc_phy_bits = 16;
+
+	/* select HSIC, ULPI, UTMI+ or internal PHY mode */
+	switch (sc->sc_phy_type) {
 	case DWC_OTG_PHY_HSIC:
 		DWC_OTG_WRITE_4(sc, DOTG_GUSBCFG,
 		    GUSBCFG_PHYIF |
@@ -3916,6 +3917,16 @@ dwc_otg_init(struct dwc_otg_softc *sc)
 		DWC_OTG_WRITE_4(sc, DOTG_GLPMCFG,
 		    temp & ~GLPMCFG_HSIC_CONN);
 		break;
+	case DWC_OTG_PHY_UTMI:
+		DWC_OTG_WRITE_4(sc, DOTG_GUSBCFG,
+		    (sc->sc_phy_bits == 16 ? GUSBCFG_PHYIF : 0) |
+		    GUSBCFG_TRD_TIM_SET(5) | temp);
+		DWC_OTG_WRITE_4(sc, DOTG_GOTGCTL, 0);
+
+		temp = DWC_OTG_READ_4(sc, DOTG_GLPMCFG);
+		DWC_OTG_WRITE_4(sc, DOTG_GLPMCFG,
+		    temp & ~GLPMCFG_HSIC_CONN);
+		break;
 	case DWC_OTG_PHY_INTERNAL:
 		DWC_OTG_WRITE_4(sc, DOTG_GUSBCFG,
 		    GUSBCFG_PHYSEL |
diff --git a/freebsd/sys/dev/usb/controller/dwc_otg.h b/freebsd/sys/dev/usb/controller/dwc_otg.h
index 038b072..7f5ede4 100644
--- a/freebsd/sys/dev/usb/controller/dwc_otg.h
+++ b/freebsd/sys/dev/usb/controller/dwc_otg.h
@@ -191,6 +191,13 @@ struct dwc_otg_softc {
 	uint16_t sc_active_rx_ep;
 	uint16_t sc_last_frame_num;
 
+	uint8_t sc_phy_type;
+	uint8_t sc_phy_bits;
+#define	DWC_OTG_PHY_ULPI 1
+#define	DWC_OTG_PHY_HSIC 2
+#define	DWC_OTG_PHY_INTERNAL 3
+#define	DWC_OTG_PHY_UTMI 4
+
 	uint8_t sc_timer_active;
 	uint8_t	sc_dev_ep_max;
 	uint8_t sc_dev_in_ep_max;
diff --git a/freebsd/sys/dev/usb/quirk/usb_quirk.c b/freebsd/sys/dev/usb/quirk/usb_quirk.c
index 1ff0afb..d73116e 100644
--- a/freebsd/sys/dev/usb/quirk/usb_quirk.c
+++ b/freebsd/sys/dev/usb/quirk/usb_quirk.c
@@ -661,7 +661,7 @@ usb_test_quirk_by_info(const struct usbd_lookup_info *info, uint16_t quirk)
 	if (quirk == UQ_NONE)
 		goto done;
 
-	mtx_lock(&usb_quirk_mtx);
+	USB_MTX_LOCK(&usb_quirk_mtx);
 
 	for (x = 0; x != USB_DEV_QUIRKS_MAX; x++) {
 		/* see if quirk information does not match */
@@ -685,13 +685,13 @@ usb_test_quirk_by_info(const struct usbd_lookup_info *info, uint16_t quirk)
 		/* lookup quirk */
 		for (y = 0; y != USB_SUB_QUIRKS_MAX; y++) {
 			if (usb_quirks[x].quirks[y] == quirk) {
-				mtx_unlock(&usb_quirk_mtx);
+				USB_MTX_UNLOCK(&usb_quirk_mtx);
 				DPRINTF("Found quirk '%s'.\n", usb_quirkstr(quirk));
 				return (1);
 			}
 		}
 	}
-	mtx_unlock(&usb_quirk_mtx);
+	USB_MTX_UNLOCK(&usb_quirk_mtx);
 done:
 	return (0);			/* no quirk match */
 }
@@ -702,7 +702,7 @@ usb_quirk_get_entry(uint16_t vid, uint16_t pid,
 {
 	uint16_t x;
 
-	mtx_assert(&usb_quirk_mtx, MA_OWNED);
+	USB_MTX_ASSERT(&usb_quirk_mtx, MA_OWNED);
 
 	if ((vid | pid | lo_rev | hi_rev) == 0) {
 		/* all zero - special case */
@@ -770,7 +770,7 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
 		if (y >= USB_DEV_QUIRKS_MAX) {
 			return (EINVAL);
 		}
-		mtx_lock(&usb_quirk_mtx);
+		USB_MTX_LOCK(&usb_quirk_mtx);
 		/* copy out data */
 		pgq->vid = usb_quirks[y].vid;
 		pgq->pid = usb_quirks[y].pid;
@@ -779,7 +779,7 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
 		strlcpy(pgq->quirkname,
 		    usb_quirkstr(usb_quirks[y].quirks[x]),
 		    sizeof(pgq->quirkname));
-		mtx_unlock(&usb_quirk_mtx);
+		USB_MTX_UNLOCK(&usb_quirk_mtx);
 		return (0);		/* success */
 
 	case USB_QUIRK_NAME_GET:
@@ -812,11 +812,11 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
 		if (y == UQ_NONE) {
 			return (EINVAL);
 		}
-		mtx_lock(&usb_quirk_mtx);
+		USB_MTX_LOCK(&usb_quirk_mtx);
 		pqe = usb_quirk_get_entry(pgq->vid, pgq->pid,
 		    pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 1);
 		if (pqe == NULL) {
-			mtx_unlock(&usb_quirk_mtx);
+			USB_MTX_UNLOCK(&usb_quirk_mtx);
 			return (EINVAL);
 		}
 		for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) {
@@ -825,7 +825,7 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
 				break;
 			}
 		}
-		mtx_unlock(&usb_quirk_mtx);
+		USB_MTX_UNLOCK(&usb_quirk_mtx);
 		if (x == USB_SUB_QUIRKS_MAX) {
 			return (ENOMEM);
 		}
@@ -850,11 +850,11 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
 		if (y == UQ_NONE) {
 			return (EINVAL);
 		}
-		mtx_lock(&usb_quirk_mtx);
+		USB_MTX_LOCK(&usb_quirk_mtx);
 		pqe = usb_quirk_get_entry(pgq->vid, pgq->pid,
 		    pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 0);
 		if (pqe == NULL) {
-			mtx_unlock(&usb_quirk_mtx);
+			USB_MTX_UNLOCK(&usb_quirk_mtx);
 			return (EINVAL);
 		}
 		for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) {
@@ -864,7 +864,7 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
 			}
 		}
 		if (x == USB_SUB_QUIRKS_MAX) {
-			mtx_unlock(&usb_quirk_mtx);
+			USB_MTX_UNLOCK(&usb_quirk_mtx);
 			return (ENOMEM);
 		}
 		for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) {
@@ -876,7 +876,7 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
 			/* all quirk entries are unused - release */
 			memset(pqe, 0, sizeof(*pqe));
 		}
-		mtx_unlock(&usb_quirk_mtx);
+		USB_MTX_UNLOCK(&usb_quirk_mtx);
 		return (0);		/* success */
 
 	default:
@@ -967,14 +967,14 @@ usb_quirk_add_entry_from_str(const char *name, const char *env)
 			printf("%s: Too many USB quirks, only %d allowed!\n",
 			    name, USB_SUB_QUIRKS_MAX);
 		}
-		mtx_lock(&usb_quirk_mtx);
+		USB_MTX_LOCK(&usb_quirk_mtx);
 		new = usb_quirk_get_entry(entry.vid, entry.pid,
 		    entry.lo_rev, entry.hi_rev, 1);
 		if (new == NULL)
 			printf("%s: USB quirks table is full!\n", name);
 		else
 			memcpy(new->quirks, entry.quirks, sizeof(entry.quirks));
-		mtx_unlock(&usb_quirk_mtx);
+		USB_MTX_UNLOCK(&usb_quirk_mtx);
 	} else {
 		printf("%s: No USB quirks found!\n", name);
 	}
diff --git a/freebsd/sys/dev/usb/storage/umass.c b/freebsd/sys/dev/usb/storage/umass.c
index 0fb810c..e8ee210 100644
--- a/freebsd/sys/dev/usb/storage/umass.c
+++ b/freebsd/sys/dev/usb/storage/umass.c
@@ -1149,7 +1149,7 @@ umass_cancel_ccb(struct umass_softc *sc)
 {
 	union ccb *ccb;
 
-	mtx_assert(&sc->sc_mtx, MA_OWNED);
+	USB_MTX_ASSERT(&sc->sc_mtx, MA_OWNED);
 
 	ccb = sc->sc_transfer.ccb;
 	sc->sc_transfer.ccb = NULL;
diff --git a/freebsd/sys/dev/usb/usb_busdma.c b/freebsd/sys/dev/usb/usb_busdma.c
index 8856619..16fc7f7 100644
--- a/freebsd/sys/dev/usb/usb_busdma.c
+++ b/freebsd/sys/dev/usb/usb_busdma.c
@@ -510,7 +510,7 @@ usb_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs,
 done:
 	owned = mtx_owned(uptag->mtx);
 	if (!owned)
-		mtx_lock(uptag->mtx);
+		USB_MTX_LOCK(uptag->mtx);
 
 	uptag->dma_error = (error ? 1 : 0);
 	if (isload) {
@@ -519,7 +519,7 @@ done:
 		cv_broadcast(uptag->cv);
 	}
 	if (!owned)
-		mtx_unlock(uptag->mtx);
+		USB_MTX_UNLOCK(uptag->mtx);
 }
 
 /*------------------------------------------------------------------------*
@@ -594,7 +594,7 @@ usb_pc_alloc_mem(struct usb_page_cache *pc, struct usb_page *pg,
 	pc->tag = utag->tag;
 	pc->ismultiseg = (align == 1);
 
-	mtx_lock(uptag->mtx);
+	USB_MTX_LOCK(uptag->mtx);
 
 	/* load memory into DMA */
 	err = bus_dmamap_load(
@@ -605,7 +605,7 @@ usb_pc_alloc_mem(struct usb_page_cache *pc, struct usb_page *pg,
 		cv_wait(uptag->cv, uptag->mtx);
 		err = 0;
 	}
-	mtx_unlock(uptag->mtx);
+	USB_MTX_UNLOCK(uptag->mtx);
 
 	if (err || uptag->dma_error) {
 		bus_dmamem_free(utag->tag, ptr, map);
@@ -661,7 +661,7 @@ usb_pc_load_mem(struct usb_page_cache *pc, usb_size_t size, uint8_t sync)
 	pc->page_offset_end = size;
 	pc->ismultiseg = 1;
 
-	mtx_assert(pc->tag_parent->mtx, MA_OWNED);
+	USB_MTX_ASSERT(pc->tag_parent->mtx, MA_OWNED);
 
 	if (size > 0) {
 		if (sync) {
@@ -919,7 +919,7 @@ usb_bdma_work_loop(struct usb_xfer_queue *pq)
 	xfer = pq->curr;
 	info = xfer->xroot;
 
-	mtx_assert(info->xfer_mtx, MA_OWNED);
+	USB_MTX_ASSERT(info->xfer_mtx, MA_OWNED);
 
 	if (xfer->error) {
 		/* some error happened */
@@ -1043,7 +1043,7 @@ usb_bdma_done_event(struct usb_dma_parent_tag *udpt)
 
 	info = USB_DMATAG_TO_XROOT(udpt);
 
-	mtx_assert(info->xfer_mtx, MA_OWNED);
+	USB_MTX_ASSERT(info->xfer_mtx, MA_OWNED);
 
 	/* copy error */
 	info->dma_error = udpt->dma_error;
diff --git a/freebsd/sys/dev/usb/usb_core.c b/freebsd/sys/dev/usb/usb_core.c
index b5e6640..a74bdca 100644
--- a/freebsd/sys/dev/usb/usb_core.c
+++ b/freebsd/sys/dev/usb/usb_core.c
@@ -53,6 +53,8 @@
 #include <sys/callout.h>
 #include <sys/malloc.h>
 #include <sys/priv.h>
+#include <sys/proc.h>
+#include <sys/kdb.h>
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
@@ -66,4 +68,16 @@ const struct usb_string_lang usb_string_lang_en = {
 MALLOC_DEFINE(M_USB, "USB", "USB");
 MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
 
+int
+usbd_in_polling_mode(void)
+{
+	return (USB_IN_POLLING_MODE_VALUE());
+}
+
+void
+usbd_dummy_timeout(void *arg)
+{
+	/* NOP */
+}
+
 MODULE_VERSION(usb, 1);
diff --git a/freebsd/sys/dev/usb/usb_core.h b/freebsd/sys/dev/usb/usb_core.h
index 739a003..9f52e65 100644
--- a/freebsd/sys/dev/usb/usb_core.h
+++ b/freebsd/sys/dev/usb/usb_core.h
@@ -39,17 +39,20 @@
 	USB_MODE_DEVICE ? (((xfer)->endpointno & UE_DIR_IN) ? 0 : 1) : \
 	(((xfer)->endpointno & UE_DIR_IN) ? 1 : 0))
 
-/* macros */
-
-#define	USB_BUS_LOCK(_b)		mtx_lock(&(_b)->bus_mtx)
-#define	USB_BUS_UNLOCK(_b)		mtx_unlock(&(_b)->bus_mtx)
-#define	USB_BUS_LOCK_ASSERT(_b, _t)	mtx_assert(&(_b)->bus_mtx, _t)
-#define	USB_BUS_SPIN_LOCK(_b)		mtx_lock_spin(&(_b)->bus_spin_lock)
-#define	USB_BUS_SPIN_UNLOCK(_b)		mtx_unlock_spin(&(_b)->bus_spin_lock)
-#define	USB_BUS_SPIN_LOCK_ASSERT(_b, _t)	mtx_assert(&(_b)->bus_spin_lock, _t)
-#define	USB_XFER_LOCK(_x)		mtx_lock((_x)->xroot->xfer_mtx)
-#define	USB_XFER_UNLOCK(_x)		mtx_unlock((_x)->xroot->xfer_mtx)
-#define	USB_XFER_LOCK_ASSERT(_x, _t)	mtx_assert((_x)->xroot->xfer_mtx, _t)
+/* locking wrappers for BUS lock */
+#define	USB_BUS_LOCK(_b)		USB_MTX_LOCK(&(_b)->bus_mtx)
+#define	USB_BUS_UNLOCK(_b)		USB_MTX_UNLOCK(&(_b)->bus_mtx)
+#define	USB_BUS_LOCK_ASSERT(_b, _t)	USB_MTX_ASSERT(&(_b)->bus_mtx, _t)
+
+/* locking wrappers for BUS spin lock */
+#define	USB_BUS_SPIN_LOCK(_b)		USB_MTX_LOCK_SPIN(&(_b)->bus_spin_lock)
+#define	USB_BUS_SPIN_UNLOCK(_b)		USB_MTX_UNLOCK_SPIN(&(_b)->bus_spin_lock)
+#define	USB_BUS_SPIN_LOCK_ASSERT(_b, _t) USB_MTX_ASSERT(&(_b)->bus_spin_lock, _t)
+
+/* locking wrappers for XFER lock */
+#define	USB_XFER_LOCK(_x)		USB_MTX_LOCK((_x)->xroot->xfer_mtx)
+#define	USB_XFER_UNLOCK(_x)		USB_MTX_UNLOCK((_x)->xroot->xfer_mtx)
+#define	USB_XFER_LOCK_ASSERT(_x, _t)	USB_MTX_ASSERT((_x)->xroot->xfer_mtx, _t)
 
 /* helper for converting pointers to integers */
 #define	USB_P2U(ptr) \
diff --git a/freebsd/sys/dev/usb/usb_dev.c b/freebsd/sys/dev/usb/usb_dev.c
index b31ba61..fe249c2 100644
--- a/freebsd/sys/dev/usb/usb_dev.c
+++ b/freebsd/sys/dev/usb/usb_dev.c
@@ -1161,7 +1161,7 @@ usb_filter_write(struct knote *kn, long hint)
 
 	f = kn->kn_hook;
 
-	mtx_assert(f->priv_mtx, MA_OWNED);
+	USB_MTX_ASSERT(f->priv_mtx, MA_OWNED);
 
 	cpd = f->curr_cpd;
 	if (cpd == NULL) {
@@ -1202,7 +1202,7 @@ usb_filter_read(struct knote *kn, long hint)
 
 	f = kn->kn_hook;
 
-	mtx_assert(f->priv_mtx, MA_OWNED);
+	USB_MTX_ASSERT(f->priv_mtx, MA_OWNED);
 
 	cpd = f->curr_cpd;
 	if (cpd == NULL) {
@@ -1732,7 +1732,7 @@ usb_fifo_wait(struct usb_fifo *f)
 {
 	int err;
 
-	mtx_assert(f->priv_mtx, MA_OWNED);
+	USB_MTX_ASSERT(f->priv_mtx, MA_OWNED);
 
 	if (f->flag_iserror) {
 		/* we are gone */
diff --git a/freebsd/sys/dev/usb/usb_device.c b/freebsd/sys/dev/usb/usb_device.c
index 26c694e..06e7050 100644
--- a/freebsd/sys/dev/usb/usb_device.c
+++ b/freebsd/sys/dev/usb/usb_device.c
@@ -1109,10 +1109,8 @@ usb_detach_device_sub(struct usb_device *udev, device_t *ppdev,
 					device_printf(dev, "Resume failed\n");
 				}
 			}
-			if (device_detach(dev)) {
-				goto error;
-			}
 		}
+		/* detach and delete child */
 		if (device_delete_child(udev->parent_dev, dev)) {
 			goto error;
 		}
@@ -1517,13 +1515,13 @@ usbd_clear_stall_proc(struct usb_proc_msg *_pm)
 
 	/* Change lock */
 	USB_BUS_UNLOCK(udev->bus);
-	mtx_lock(&udev->device_mtx);
+	USB_MTX_LOCK(&udev->device_mtx);
 
 	/* Start clear stall callback */
 	usbd_transfer_start(udev->ctrl_xfer[1]);
 
 	/* Change lock */
-	mtx_unlock(&udev->device_mtx);
+	USB_MTX_UNLOCK(&udev->device_mtx);
 	USB_BUS_LOCK(udev->bus);
 }
 
@@ -1591,6 +1589,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
 	/* initialise our SX-lock */
 	sx_init_flags(&udev->enum_sx, "USB config SX lock", SX_DUPOK);
 	sx_init_flags(&udev->sr_sx, "USB suspend and resume SX lock", SX_NOWITNESS);
+	sx_init_flags(&udev->ctrl_sx, "USB control transfer SX lock", SX_DUPOK);
 
 	cv_init(&udev->ctrlreq_cv, "WCTRL");
 	cv_init(&udev->ref_cv, "UGONE");
@@ -1776,7 +1775,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
 	 */
 
 	/* Protect scratch area */
-	do_unlock = usbd_enum_lock(udev);
+	do_unlock = usbd_ctrl_lock(udev);
 
 	scratch_ptr = udev->scratch.data;
 
@@ -1827,7 +1826,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
 	}
 
 	if (do_unlock)
-		usbd_enum_unlock(udev);
+		usbd_ctrl_unlock(udev);
 
 	/* assume 100mA bus powered for now. Changed when configured. */
 	udev->power = USB_MIN_POWER;
@@ -1945,8 +1944,8 @@ config_done:
 	udev->ugen_symlink = usb_alloc_symlink(udev->ugen_name);
 
 	/* Announce device */
-	printf("%s: <%s> at %s\n", udev->ugen_name,
-	    usb_get_manufacturer(udev),
+	printf("%s: <%s %s> at %s\n", udev->ugen_name,
+	    usb_get_manufacturer(udev), usb_get_product(udev),
 	    device_get_nameunit(udev->bus->bdev));
 #endif
 
@@ -2155,8 +2154,9 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
 
 #if USB_HAVE_UGEN
 	if (!rebooting) {
-		printf("%s: <%s> at %s (disconnected)\n", udev->ugen_name,
-		    usb_get_manufacturer(udev), device_get_nameunit(bus->bdev));
+		printf("%s: <%s %s> at %s (disconnected)\n", udev->ugen_name,
+		    usb_get_manufacturer(udev), usb_get_product(udev),
+		    device_get_nameunit(bus->bdev));
 	}
 
 	/* Destroy UGEN symlink, if any */
@@ -2201,6 +2201,7 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
 	
 	sx_destroy(&udev->enum_sx);
 	sx_destroy(&udev->sr_sx);
+	sx_destroy(&udev->ctrl_sx);
 
 	cv_destroy(&udev->ctrlreq_cv);
 	cv_destroy(&udev->ref_cv);
@@ -2364,7 +2365,7 @@ usbd_set_device_strings(struct usb_device *udev)
 	uint8_t do_unlock;
 
 	/* Protect scratch area */
-	do_unlock = usbd_enum_lock(udev);
+	do_unlock = usbd_ctrl_lock(udev);
 
 	temp_ptr = (char *)udev->scratch.data;
 	temp_size = sizeof(udev->scratch.data);
@@ -2424,7 +2425,7 @@ usbd_set_device_strings(struct usb_device *udev)
 	}
 
 	if (do_unlock)
-		usbd_enum_unlock(udev);
+		usbd_ctrl_unlock(udev);
 }
 
 /*
@@ -2831,6 +2832,40 @@ usbd_enum_is_locked(struct usb_device *udev)
 }
 
 /*
+ * The following function is used to serialize access to USB control
+ * transfers and the USB scratch area. If the lock is already grabbed
+ * this function returns zero. Else a value of one is returned.
+ */
+uint8_t
+usbd_ctrl_lock(struct usb_device *udev)
+{
+	if (sx_xlocked(&udev->ctrl_sx))
+		return (0);
+	sx_xlock(&udev->ctrl_sx);
+
+	/*
+	 * We need to allow suspend and resume at this point, else the
+	 * control transfer will timeout if the device is suspended!
+	 */
+	if (usbd_enum_is_locked(udev))
+		usbd_sr_unlock(udev);
+	return (1);
+}
+
+void
+usbd_ctrl_unlock(struct usb_device *udev)
+{
+	sx_xunlock(&udev->ctrl_sx);
+
+	/*
+	 * Restore the suspend and resume lock after we have unlocked
+	 * the USB control transfer lock to avoid LOR:
+	 */
+	if (usbd_enum_is_locked(udev))
+		usbd_sr_lock(udev);
+}
+
+/*
  * The following function is used to set the per-interface specific
  * plug and play information. The string referred to by the pnpinfo
  * argument can safely be freed after calling this function. The
diff --git a/freebsd/sys/dev/usb/usb_device.h b/freebsd/sys/dev/usb/usb_device.h
index 24a5a4a..22e1560 100644
--- a/freebsd/sys/dev/usb/usb_device.h
+++ b/freebsd/sys/dev/usb/usb_device.h
@@ -162,7 +162,7 @@ struct usb_temp_setup {
 
 /* 
  * The scratch area for USB devices. Access to this structure is
- * protected by the enumeration SX lock.
+ * protected by the control SX lock.
  */
 union usb_device_scratch {
 	struct usb_hw_ep_scratch hw_ep_scratch[1];
@@ -183,6 +183,7 @@ struct usb_device {
 	struct usb_udev_msg cs_msg[2];
 	struct sx enum_sx;
 	struct sx sr_sx;
+  	struct sx ctrl_sx;
 	struct mtx device_mtx;
 	struct cv ctrlreq_cv;
 	struct cv ref_cv;
@@ -320,6 +321,8 @@ uint8_t	usbd_enum_lock_sig(struct usb_device *);
 void	usbd_enum_unlock(struct usb_device *);
 void	usbd_sr_lock(struct usb_device *);
 void	usbd_sr_unlock(struct usb_device *);
+uint8_t	usbd_ctrl_lock(struct usb_device *);
+void	usbd_ctrl_unlock(struct usb_device *);
 uint8_t usbd_enum_is_locked(struct usb_device *);
 
 #if USB_HAVE_TT_SUPPORT
diff --git a/freebsd/sys/dev/usb/usb_freebsd.h b/freebsd/sys/dev/usb/usb_freebsd.h
index 0d2e810..bc5d242 100644
--- a/freebsd/sys/dev/usb/usb_freebsd.h
+++ b/freebsd/sys/dev/usb/usb_freebsd.h
@@ -92,6 +92,9 @@
 
 #define	USB_MAX_AUTO_QUIRK	8	/* maximum number of dynamic quirks */
 
+#define	USB_IN_POLLING_MODE_FUNC() usbd_in_polling_mode()
+#define	USB_IN_POLLING_MODE_VALUE() (SCHEDULER_STOPPED() || kdb_active)
+
 typedef uint32_t usb_timeout_t;		/* milliseconds */
 typedef uint32_t usb_frlength_t;	/* bytes */
 typedef uint32_t usb_frcount_t;		/* units */
diff --git a/freebsd/sys/dev/usb/usb_generic.c b/freebsd/sys/dev/usb/usb_generic.c
index 675a63d..c0873a6 100644
--- a/freebsd/sys/dev/usb/usb_generic.c
+++ b/freebsd/sys/dev/usb/usb_generic.c
@@ -238,7 +238,7 @@ ugen_open_pipe_write(struct usb_fifo *f)
 	struct usb_endpoint *ep = usb_fifo_softc(f);
 	struct usb_endpoint_descriptor *ed = ep->edesc;
 
-	mtx_assert(f->priv_mtx, MA_OWNED);
+	USB_MTX_ASSERT(f->priv_mtx, MA_OWNED);
 
 	if (f->xfer[0] || f->xfer[1]) {
 		/* transfers are already opened */
@@ -307,7 +307,7 @@ ugen_open_pipe_read(struct usb_fifo *f)
 	struct usb_endpoint *ep = usb_fifo_softc(f);
 	struct usb_endpoint_descriptor *ed = ep->edesc;
 
-	mtx_assert(f->priv_mtx, MA_OWNED);
+	USB_MTX_ASSERT(f->priv_mtx, MA_OWNED);
 
 	if (f->xfer[0] || f->xfer[1]) {
 		/* transfers are already opened */
@@ -716,16 +716,16 @@ ugen_get_cdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
 	return (error);
 }
 
-/*
- * This function is called having the enumeration SX locked which
- * protects the scratch area used.
- */
 static int
 ugen_get_sdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
 {
 	void *ptr;
 	uint16_t size;
 	int error;
+	uint8_t do_unlock;
+
+	/* Protect scratch area */
+	do_unlock = usbd_ctrl_lock(f->udev);
 
 	ptr = f->udev->scratch.data;
 	size = sizeof(f->udev->scratch.data);
@@ -746,6 +746,9 @@ ugen_get_sdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
 
 		error = copyout(ptr, ugd->ugd_data, size);
 	}
+	if (do_unlock)
+		usbd_ctrl_unlock(f->udev);
+
 	return (error);
 }
 
diff --git a/freebsd/sys/dev/usb/usb_hub.c b/freebsd/sys/dev/usb/usb_hub.c
index a744a82..d27728e 100644
--- a/freebsd/sys/dev/usb/usb_hub.c
+++ b/freebsd/sys/dev/usb/usb_hub.c
@@ -272,11 +272,11 @@ uhub_reset_tt_proc(struct usb_proc_msg *_pm)
 
 	/* Change lock */
 	USB_BUS_UNLOCK(udev->bus);
-	mtx_lock(&sc->sc_mtx);
+	USB_MTX_LOCK(&sc->sc_mtx);
 	/* Start transfer */
 	usbd_transfer_start(sc->sc_xfer[UHUB_RESET_TT_TRANSFER]);
 	/* Change lock */
-	mtx_unlock(&sc->sc_mtx);
+	USB_MTX_UNLOCK(&sc->sc_mtx);
 	USB_BUS_LOCK(udev->bus);
 }
 #endif
@@ -1521,9 +1521,9 @@ uhub_attach(device_t dev)
 
 	/* Start the interrupt endpoint, if any */
 
-	mtx_lock(&sc->sc_mtx);
+	USB_MTX_LOCK(&sc->sc_mtx);
 	usbd_transfer_start(sc->sc_xfer[UHUB_INTR_TRANSFER]);
-	mtx_unlock(&sc->sc_mtx);
+	USB_MTX_UNLOCK(&sc->sc_mtx);
 
 	/* Enable automatic power save on all USB HUBs */
 
diff --git a/freebsd/sys/dev/usb/usb_msctest.c b/freebsd/sys/dev/usb/usb_msctest.c
index cf29d09..58849f1 100644
--- a/freebsd/sys/dev/usb/usb_msctest.c
+++ b/freebsd/sys/dev/usb/usb_msctest.c
@@ -553,13 +553,13 @@ bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun,
 	memcpy(&sc->cbw->CBWCDB, cmd_ptr, cmd_len);
 	DPRINTFN(1, "SCSI cmd = %*D\n", (int)cmd_len, (char *)sc->cbw->CBWCDB, ":");
 
-	mtx_lock(&sc->mtx);
+	USB_MTX_LOCK(&sc->mtx);
 	usbd_transfer_start(sc->xfer[sc->state]);
 
 	while (usbd_transfer_pending(sc->xfer[sc->state])) {
 		cv_wait(&sc->cv, &sc->mtx);
 	}
-	mtx_unlock(&sc->mtx);
+	USB_MTX_UNLOCK(&sc->mtx);
 	return (sc->error);
 }
 
@@ -584,11 +584,11 @@ bbb_raw_write(struct bbb_transfer *sc, const void *data_ptr, size_t data_len,
 	DPRINTFN(1, "BULK DATA = %*D\n", (int)data_len,
 	    (const char *)data_ptr, ":");
 
-	mtx_lock(&sc->mtx);
+	USB_MTX_LOCK(&sc->mtx);
 	usbd_transfer_start(sc->xfer[0]);
 	while (usbd_transfer_pending(sc->xfer[0]))
 		cv_wait(&sc->cv, &sc->mtx);
-	mtx_unlock(&sc->mtx);
+	USB_MTX_UNLOCK(&sc->mtx);
 	return (sc->error);
 }
 
diff --git a/freebsd/sys/dev/usb/usb_process.c b/freebsd/sys/dev/usb/usb_process.c
index 219a736..569550e 100644
--- a/freebsd/sys/dev/usb/usb_process.c
+++ b/freebsd/sys/dev/usb/usb_process.c
@@ -121,7 +121,7 @@ usb_process(void *arg)
 	thread_unlock(td);
 #endif /* __rtems__ */
 
-	mtx_lock(up->up_mtx);
+	USB_MTX_LOCK(up->up_mtx);
 
 	up->up_curtd = td;
 
@@ -190,7 +190,7 @@ usb_process(void *arg)
 
 			continue;
 		}
-		/* end if messages - check if anyone is waiting for sync */
+		/* end of messages - check if anyone is waiting for sync */
 		if (up->up_dsleep) {
 			up->up_dsleep = 0;
 			cv_broadcast(&up->up_drain);
@@ -201,7 +201,7 @@ usb_process(void *arg)
 
 	up->up_ptr = NULL;
 	cv_signal(&up->up_cv);
-	mtx_unlock(up->up_mtx);
+	USB_MTX_UNLOCK(up->up_mtx);
 #if (__FreeBSD_version >= 800000)
 	/* Clear the proc pointer if this is the last thread. */
 	if (--usb_pcount == 0)
@@ -297,11 +297,12 @@ usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
 	usb_size_t d;
 	uint8_t t;
 
-	/* check if gone, return dummy value */
-	if (up->up_gone)
+	/* check if gone or in polling mode, return dummy value */
+	if (up->up_gone != 0 ||
+	    USB_IN_POLLING_MODE_FUNC() != 0)
 		return (_pm0);
 
-	mtx_assert(up->up_mtx, MA_OWNED);
+	USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
 
 	t = 0;
 
@@ -382,7 +383,7 @@ usb_proc_is_gone(struct usb_process *up)
 	 * structure is initialised.
 	 */
 	if (up->up_mtx != NULL)
-		mtx_assert(up->up_mtx, MA_OWNED);
+		USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
 	return (0);
 }
 
@@ -403,7 +404,7 @@ usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
 	if (up->up_gone)
 		return;
 
-	mtx_assert(up->up_mtx, MA_OWNED);
+	USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
 
 	if (up->up_curtd == curthread) {
 		/* Just remove the messages from the queue. */
@@ -443,9 +444,9 @@ usb_proc_drain(struct usb_process *up)
 		return;
 	/* handle special case with Giant */
 	if (up->up_mtx != &Giant)
-		mtx_assert(up->up_mtx, MA_NOTOWNED);
+		USB_MTX_ASSERT(up->up_mtx, MA_NOTOWNED);
 
-	mtx_lock(up->up_mtx);
+	USB_MTX_LOCK(up->up_mtx);
 
 	/* Set the gone flag */
 
@@ -482,7 +483,7 @@ usb_proc_drain(struct usb_process *up)
 		DPRINTF("WARNING: Someone is waiting "
 		    "for USB process drain!\n");
 	}
-	mtx_unlock(up->up_mtx);
+	USB_MTX_UNLOCK(up->up_mtx);
 }
 
 /*------------------------------------------------------------------------*
@@ -503,7 +504,7 @@ usb_proc_rewakeup(struct usb_process *up)
 	if (up->up_gone)
 		return;
 
-	mtx_assert(up->up_mtx, MA_OWNED);
+	USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
 
 	if (up->up_msleep == 0) {
 		/* re-wakeup */
diff --git a/freebsd/sys/dev/usb/usb_request.c b/freebsd/sys/dev/usb/usb_request.c
index f092094..2d7634a 100644
--- a/freebsd/sys/dev/usb/usb_request.c
+++ b/freebsd/sys/dev/usb/usb_request.c
@@ -457,21 +457,14 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
 		return (USB_ERR_INVAL);
 #endif
 	if ((mtx != NULL) && (mtx != &Giant)) {
-		mtx_unlock(mtx);
-		mtx_assert(mtx, MA_NOTOWNED);
+		USB_MTX_UNLOCK(mtx);
+		USB_MTX_ASSERT(mtx, MA_NOTOWNED);
 	}
 
 	/*
-	 * Grab the USB device enumeration SX-lock serialization is
-	 * achieved when multiple threads are involved:
+	 * Serialize access to this function:
 	 */
-	do_unlock = usbd_enum_lock(udev);
-
-	/*
-	 * We need to allow suspend and resume at this point, else the
-	 * control transfer will timeout if the device is suspended!
-	 */
-	usbd_sr_unlock(udev);
+	do_unlock = usbd_ctrl_lock(udev);
 
 	hr_func = usbd_get_hr_func(udev);
 
@@ -715,13 +708,11 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
 	USB_XFER_UNLOCK(xfer);
 
 done:
-	usbd_sr_lock(udev);
-
 	if (do_unlock)
-		usbd_enum_unlock(udev);
+		usbd_ctrl_unlock(udev);
 
 	if ((mtx != NULL) && (mtx != &Giant))
-		mtx_lock(mtx);
+		USB_MTX_LOCK(mtx);
 
 	switch (err) {
 	case USB_ERR_NORMAL_COMPLETION:
diff --git a/freebsd/sys/dev/usb/usb_transfer.c b/freebsd/sys/dev/usb/usb_transfer.c
index 9bb68fd..9cd4034 100644
--- a/freebsd/sys/dev/usb/usb_transfer.c
+++ b/freebsd/sys/dev/usb/usb_transfer.c
@@ -47,7 +47,6 @@
 #include <sys/callout.h>
 #include <sys/malloc.h>
 #include <sys/priv.h>
-#include <sys/proc.h>
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
@@ -341,12 +340,12 @@ usbd_transfer_setup_sub_malloc(struct usb_setup_params *parm,
 			pc->buffer = USB_ADD_BYTES(buf, y * size);
 			pc->page_start = pg;
 
-			mtx_lock(pc->tag_parent->mtx);
+			USB_MTX_LOCK(pc->tag_parent->mtx);
 			if (usb_pc_load_mem(pc, size, 1 /* synchronous */ )) {
-				mtx_unlock(pc->tag_parent->mtx);
+				USB_MTX_UNLOCK(pc->tag_parent->mtx);
 				return (1);	/* failure */
 			}
-			mtx_unlock(pc->tag_parent->mtx);
+			USB_MTX_UNLOCK(pc->tag_parent->mtx);
 		}
 	    }
 	}
@@ -983,7 +982,7 @@ usbd_transfer_setup(struct usb_device *udev,
 		return (error);
 
 	/* Protect scratch area */
-	do_unlock = usbd_enum_lock(udev);
+	do_unlock = usbd_ctrl_lock(udev);
 
 	refcount = 0;
 	info = NULL;
@@ -1304,7 +1303,7 @@ done:
 	error = parm->err;
 
 	if (do_unlock)
-		usbd_enum_unlock(udev);
+		usbd_ctrl_unlock(udev);
 
 	return (error);
 }
@@ -2292,14 +2291,14 @@ usb_callback_proc(struct usb_proc_msg *_pm)
 	 * We exploit the fact that the mutex is the same for all
 	 * callbacks that will be called from this thread:
 	 */
-	mtx_lock(info->xfer_mtx);
+	USB_MTX_LOCK(info->xfer_mtx);
 	USB_BUS_LOCK(info->bus);
 
 	/* Continue where we lost track */
 	usb_command_wrapper(&info->done_q,
 	    info->done_q.curr);
 
-	mtx_unlock(info->xfer_mtx);
+	USB_MTX_UNLOCK(info->xfer_mtx);
 }
 
 /*------------------------------------------------------------------------*
@@ -2352,7 +2351,7 @@ usbd_callback_wrapper(struct usb_xfer_queue *pq)
 
 	USB_BUS_LOCK_ASSERT(info->bus, MA_OWNED);
 	if ((pq->recurse_3 != 0 || mtx_owned(info->xfer_mtx) == 0) &&
-	    SCHEDULER_STOPPED() == 0) {
+	    USB_IN_POLLING_MODE_FUNC() == 0) {
 		/*
 	       	 * Cases that end up here:
 		 *
@@ -3333,7 +3332,9 @@ usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
 	struct usb_xfer_root *xroot;
 	struct usb_device *udev;
 	struct usb_proc_msg *pm;
+	struct usb_bus *bus;
 	uint16_t n;
+	uint16_t drop_bus_spin;
 	uint16_t drop_bus;
 	uint16_t drop_xfer;
 
@@ -3348,38 +3349,47 @@ usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
 		udev = xroot->udev;
 		if (udev == NULL)
 			continue;	/* no USB device */
-		if (udev->bus == NULL)
+		bus = udev->bus;
+		if (bus == NULL)
 			continue;	/* no BUS structure */
-		if (udev->bus->methods == NULL)
+		if (bus->methods == NULL)
 			continue;	/* no BUS methods */
-		if (udev->bus->methods->xfer_poll == NULL)
+		if (bus->methods->xfer_poll == NULL)
 			continue;	/* no poll method */
 
-		/* make sure that the BUS mutex is not locked */
+		drop_bus_spin = 0;
 		drop_bus = 0;
-		while (mtx_owned(&xroot->udev->bus->bus_mtx) && !SCHEDULER_STOPPED()) {
-			mtx_unlock(&xroot->udev->bus->bus_mtx);
-			drop_bus++;
-		}
-
-		/* make sure that the transfer mutex is not locked */
 		drop_xfer = 0;
-		while (mtx_owned(xroot->xfer_mtx) && !SCHEDULER_STOPPED()) {
-			mtx_unlock(xroot->xfer_mtx);
-			drop_xfer++;
+
+		if (USB_IN_POLLING_MODE_FUNC() == 0) {
+			/* make sure that the BUS spin mutex is not locked */
+			while (mtx_owned(&bus->bus_spin_lock)) {
+				mtx_unlock_spin(&bus->bus_spin_lock);
+				drop_bus_spin++;
+			}
+		
+			/* make sure that the BUS mutex is not locked */
+			while (mtx_owned(&bus->bus_mtx)) {
+				mtx_unlock(&bus->bus_mtx);
+				drop_bus++;
+			}
+
+			/* make sure that the transfer mutex is not locked */
+			while (mtx_owned(xroot->xfer_mtx)) {
+				mtx_unlock(xroot->xfer_mtx);
+				drop_xfer++;
+			}
 		}
 
-#if USB_HAVE_PER_BUS_PROCESS
 		/* Make sure cv_signal() and cv_broadcast() is not called */
-		USB_BUS_CONTROL_XFER_PROC(udev->bus)->up_msleep = 0;
-		USB_BUS_EXPLORE_PROC(udev->bus)->up_msleep = 0;
-		USB_BUS_GIANT_PROC(udev->bus)->up_msleep = 0;
-		USB_BUS_NON_GIANT_ISOC_PROC(udev->bus)->up_msleep = 0;
-		USB_BUS_NON_GIANT_BULK_PROC(udev->bus)->up_msleep = 0;
-#endif
+		USB_BUS_CONTROL_XFER_PROC(bus)->up_msleep = 0;
+		USB_BUS_EXPLORE_PROC(bus)->up_msleep = 0;
+		USB_BUS_GIANT_PROC(bus)->up_msleep = 0;
+		USB_BUS_NON_GIANT_ISOC_PROC(bus)->up_msleep = 0;
+		USB_BUS_NON_GIANT_BULK_PROC(bus)->up_msleep = 0;
 
 		/* poll USB hardware */
-		(udev->bus->methods->xfer_poll) (udev->bus);
+		(bus->methods->xfer_poll) (bus);
 
 		USB_BUS_LOCK(xroot->bus);
 
@@ -3407,7 +3417,11 @@ usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
 
 		/* restore BUS mutex */
 		while (drop_bus--)
-			mtx_lock(&xroot->udev->bus->bus_mtx);
+			mtx_lock(&bus->bus_mtx);
+
+		/* restore BUS spin mutex */
+		while (drop_bus_spin--)
+			mtx_lock_spin(&bus->bus_spin_lock);
 	}
 }
 
diff --git a/freebsd/sys/dev/usb/usb_util.c b/freebsd/sys/dev/usb/usb_util.c
index a2a5cee..377c234 100644
--- a/freebsd/sys/dev/usb/usb_util.c
+++ b/freebsd/sys/dev/usb/usb_util.c
@@ -100,7 +100,7 @@ device_set_usb_desc(device_t dev)
 	}
 
 	/* Protect scratch area */
-	do_unlock = usbd_enum_lock(udev);
+	do_unlock = usbd_ctrl_lock(udev);
 
 	temp_p = (char *)udev->scratch.data;
 
@@ -117,7 +117,7 @@ device_set_usb_desc(device_t dev)
 	}
 
 	if (do_unlock)
-		usbd_enum_unlock(udev);
+		usbd_ctrl_unlock(udev);
 
 	device_set_desc_copy(dev, temp_p);
 	device_printf(dev, "<%s> on %s\n", temp_p,
diff --git a/freebsd/sys/dev/usb/usbdi.h b/freebsd/sys/dev/usb/usbdi.h
index 202ad89..6ad3e43 100644
--- a/freebsd/sys/dev/usb/usbdi.h
+++ b/freebsd/sys/dev/usb/usbdi.h
@@ -435,6 +435,39 @@ struct usb_attach_arg {
 };
 
 /*
+ * General purpose locking wrappers to ease supporting
+ * USB polled mode:
+ */
+#ifdef INVARIANTS
+#define	USB_MTX_ASSERT(_m, _t) do {		\
+	if (!USB_IN_POLLING_MODE_FUNC())	\
+		mtx_assert(_m, _t);		\
+} while (0)
+#else
+#define	USB_MTX_ASSERT(_m, _t) do { } while (0)
+#endif
+
+#define	USB_MTX_LOCK(_m) do {			\
+	if (!USB_IN_POLLING_MODE_FUNC())	\
+		mtx_lock(_m);			\
+} while (0)
+
+#define	USB_MTX_UNLOCK(_m) do {			\
+	if (!USB_IN_POLLING_MODE_FUNC())	\
+		mtx_unlock(_m);			\
+} while (0)
+
+#define	USB_MTX_LOCK_SPIN(_m) do {		\
+	if (!USB_IN_POLLING_MODE_FUNC())	\
+		mtx_lock_spin(_m);		\
+} while (0)
+
+#define	USB_MTX_UNLOCK_SPIN(_m) do {		\
+	if (!USB_IN_POLLING_MODE_FUNC())	\
+		mtx_unlock_spin(_m);		\
+} while (0)
+
+/*
  * The following is a wrapper for the callout structure to ease
  * porting the code to other platforms.
  */
@@ -442,8 +475,26 @@ struct usb_callout {
 	struct callout co;
 };
 #define	usb_callout_init_mtx(c,m,f) callout_init_mtx(&(c)->co,m,f)
-#define	usb_callout_reset(c,t,f,d) callout_reset(&(c)->co,t,f,d)
-#define	usb_callout_stop(c) callout_stop(&(c)->co)
+#define	usb_callout_reset(c,...) do {			\
+	if (!USB_IN_POLLING_MODE_FUNC())		\
+		callout_reset(&(c)->co, __VA_ARGS__);	\
+} while (0)
+#define	usb_callout_reset_sbt(c,...) do {			\
+	if (!USB_IN_POLLING_MODE_FUNC())			\
+		callout_reset_sbt(&(c)->co, __VA_ARGS__);	\
+} while (0)
+#define	usb_callout_stop(c) do {			\
+	if (!USB_IN_POLLING_MODE_FUNC()) {		\
+		callout_stop(&(c)->co);			\
+	} else {					\
+		/*					\
+		 * Cannot stop callout when		\
+		 * polling. Set dummy callback		\
+		 * function instead:			\
+		 */					\
+		(c)->co.c_func = &usbd_dummy_timeout;	\
+	}						\
+} while (0)
 #define	usb_callout_drain(c) callout_drain(&(c)->co)
 #define	usb_callout_pending(c) callout_pending(&(c)->co)
 
@@ -623,6 +674,8 @@ void	usbd_frame_zero(struct usb_page_cache *cache, usb_frlength_t offset,
 void	usbd_start_re_enumerate(struct usb_device *udev);
 usb_error_t
 	usbd_start_set_config(struct usb_device *, uint8_t);
+int	usbd_in_polling_mode(void);
+void	usbd_dummy_timeout(void *);
 
 int	usb_fifo_attach(struct usb_device *udev, void *priv_sc,
 	    struct mtx *priv_mtx, struct usb_fifo_methods *pm,
diff --git a/freebsd/sys/i386/include/machine/md_var.h b/freebsd/sys/i386/include/machine/md_var.h
index c3caf07..c93d70c 100644
--- a/freebsd/sys/i386/include/machine/md_var.h
+++ b/freebsd/sys/i386/include/machine/md_var.h
@@ -65,6 +65,7 @@ void	i686_pagezero(void *addr);
 void	sse2_pagezero(void *addr);
 void	init_AMD_Elan_sc520(void);
 vm_paddr_t kvtop(void *addr);
+void	panicifcpuunsupported(void);
 void	ppro_reenable_apic(void);
 void	setidt(int idx, alias_for_inthand_t *func, int typ, int dpl, int selec);
 union savefpu *get_pcb_user_save_td(struct thread *td);
diff --git a/freebsd/sys/kern/init_main.c b/freebsd/sys/kern/init_main.c
index 627c01e..72bab87 100644
--- a/freebsd/sys/kern/init_main.c
+++ b/freebsd/sys/kern/init_main.c
@@ -215,9 +215,9 @@ void
 mi_startup(void)
 {
 
-	register struct sysinit **sipp;		/* system initialization*/
-	register struct sysinit **xipp;		/* interior loop of sort*/
-	register struct sysinit *save;		/* bubble*/
+	struct sysinit **sipp;	/* system initialization*/
+	struct sysinit **xipp;	/* interior loop of sort*/
+	struct sysinit *save;	/* bubble*/
 #ifdef __rtems__
 	struct sysinit **sysinit = NULL;
 	struct sysinit **sysinit_end = NULL;
@@ -339,16 +339,7 @@ restart:
 #endif /* __rtems__ */
 }
 
-
 #ifndef __rtems__
-/*
- ***************************************************************************
- ****
- **** The following SYSINIT's belong elsewhere, but have not yet
- **** been moved.
- ****
- ***************************************************************************
- */
 static void
 print_caddr_t(void *data)
 {
@@ -442,17 +433,10 @@ struct sysentvec null_sysvec = {
 };
 
 /*
- ***************************************************************************
- ****
- **** The two following SYSINIT's are proc0 specific glue code.  I am not
- **** convinced that they can not be safely combined, but their order of
- **** operation has been maintained as the same as the original init_main.c
- **** for right now.
- ****
- **** These probably belong in init_proc.c or kern_proc.c, since they
- **** deal with proc0 (the fork template process).
- ****
- ***************************************************************************
+ * The two following SYSINIT's are proc0 specific glue code.  I am not
+ * convinced that they can not be safely combined, but their order of
+ * operation has been maintained as the same as the original init_main.c
+ * for right now.
  */
 /* ARGSUSED*/
 static void
@@ -686,16 +670,6 @@ SYSINIT(random, SI_SUB_RANDOM, SI_ORDER_FIRST, random_init, NULL);
  ***************************************************************************
  */
 
-
-/*
- ***************************************************************************
- ****
- **** The following code probably belongs in another file, like
- **** kern/init_init.c.
- ****
- ***************************************************************************
- */
-
 /*
  * List of paths to try when searching for "init".
  */
@@ -843,7 +817,7 @@ start_init(void *dummy)
 }
 
 /*
- * Like kproc_create(), but runs in it's own address space.
+ * Like kproc_create(), but runs in its own address space.
  * We do this early to reserve pid 1.
  *
  * Note special case - do not make it runnable yet.  Other work
diff --git a/freebsd/sys/kern/kern_condvar.c b/freebsd/sys/kern/kern_condvar.c
index 239640e..6358c37 100644
--- a/freebsd/sys/kern/kern_condvar.c
+++ b/freebsd/sys/kern/kern_condvar.c
@@ -407,6 +407,8 @@ cv_signal(struct cv *cvp)
 {
 	int wakeup_swapper;
 
+	if (cvp->cv_waiters == 0)
+		return;
 	wakeup_swapper = 0;
 	sleepq_lock(cvp);
 	if (cvp->cv_waiters > 0) {
@@ -434,6 +436,8 @@ cv_broadcastpri(struct cv *cvp, int pri)
 {
 	int wakeup_swapper;
 
+	if (cvp->cv_waiters == 0)
+		return;
 	/*
 	 * XXX sleepq_broadcast pri argument changed from -1 meaning
 	 * no pri to 0 meaning no pri.
diff --git a/freebsd/sys/kern/kern_linker.c b/freebsd/sys/kern/kern_linker.c
index a115aa9..82a3302 100644
--- a/freebsd/sys/kern/kern_linker.c
+++ b/freebsd/sys/kern/kern_linker.c
@@ -1615,7 +1615,6 @@ restart:
 			if (error)
 				panic("cannot add dependency");
 		}
-		lf->userrefs++;	/* so we can (try to) kldunload it */
 		error = linker_file_lookup_set(lf, MDT_SETNAME, &start,
 		    &stop, NULL);
 		if (!error) {
@@ -1653,6 +1652,8 @@ restart:
 			goto fail;
 		}
 		linker_file_register_modules(lf);
+		if (!TAILQ_EMPTY(&lf->modules))
+			lf->flags |= LINKER_FILE_MODULES;
 		if (linker_file_lookup_set(lf, "sysinit_set", &si_start,
 		    &si_stop, NULL) == 0)
 			sysinit_add(si_start, si_stop);
@@ -1670,6 +1671,41 @@ fail:
 SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0);
 
 /*
+ * Handle preload files that failed to load any modules.
+ */
+static void
+linker_preload_finish(void *arg)
+{
+	linker_file_t lf, nlf;
+
+	sx_xlock(&kld_sx);
+	TAILQ_FOREACH_SAFE(lf, &linker_files, link, nlf) {
+		/*
+		 * If all of the modules in this file failed to load, unload
+		 * the file and return an error of ENOEXEC.  (Parity with
+		 * linker_load_file.)
+		 */
+		if ((lf->flags & LINKER_FILE_MODULES) != 0 &&
+		    TAILQ_EMPTY(&lf->modules)) {
+			linker_file_unload(lf, LINKER_UNLOAD_FORCE);
+			continue;
+		}
+
+		lf->flags &= ~LINKER_FILE_MODULES;
+		lf->userrefs++;	/* so we can (try to) kldunload it */
+	}
+	sx_xunlock(&kld_sx);
+}
+
+/*
+ * Attempt to run after all DECLARE_MODULE SYSINITs.  Unfortunately they can be
+ * scheduled at any subsystem and order, so run this as late as possible.  init
+ * becomes runnable in SI_SUB_KTHREAD_INIT, so go slightly before that.
+ */
+SYSINIT(preload_finish, SI_SUB_KTHREAD_INIT - 100, SI_ORDER_MIDDLE,
+    linker_preload_finish, 0);
+
+/*
  * Search for a not-loaded module by name.
  *
  * Modules may be found in the following locations:
diff --git a/freebsd/sys/kern/kern_mib.c b/freebsd/sys/kern/kern_mib.c
index aa1c577..63d8b44 100644
--- a/freebsd/sys/kern/kern_mib.c
+++ b/freebsd/sys/kern/kern_mib.c
@@ -18,7 +18,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -144,9 +144,12 @@ SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, CTLFLAG_RD|CTLFLAG_CAPRD,
 
 char kernelname[MAXPATHLEN] = "/kernel";	/* XXX bloat */
 
-SYSCTL_STRING(_kern, KERN_BOOTFILE, bootfile, CTLFLAG_RW,
+SYSCTL_STRING(_kern, KERN_BOOTFILE, bootfile, CTLFLAG_RW | CTLFLAG_MPSAFE,
     kernelname, sizeof kernelname, "Name of kernel file booted");
 
+SYSCTL_INT(_kern, KERN_MAXPHYS, maxphys, CTLFLAG_RD | CTLFLAG_CAPRD,
+    SYSCTL_NULL_INT_PTR, MAXPHYS, "Maximum block I/O access size");
+
 SYSCTL_INT(_hw, HW_NCPU, ncpu, CTLFLAG_RD|CTLFLAG_CAPRD,
     &mp_ncpus, 0, "Number of active CPUs");
 
@@ -263,8 +266,9 @@ sysctl_hw_machine_arch(SYSCTL_HANDLER_ARGS)
 	return (error);
 
 }
-SYSCTL_PROC(_hw, HW_MACHINE_ARCH, machine_arch, CTLTYPE_STRING | CTLFLAG_RD,
-    NULL, 0, sysctl_hw_machine_arch, "A", "System architecture");
+SYSCTL_PROC(_hw, HW_MACHINE_ARCH, machine_arch, CTLTYPE_STRING | CTLFLAG_RD |
+    CTLFLAG_MPSAFE, NULL, 0, sysctl_hw_machine_arch, "A",
+    "System architecture");
 #endif /* __rtems__ */
 
 SYSCTL_STRING(_kern, OID_AUTO, supported_archs, CTLFLAG_RD | CTLFLAG_MPSAFE,
@@ -339,15 +343,15 @@ sysctl_hostname(SYSCTL_HANDLER_ARGS)
 }
 
 SYSCTL_PROC(_kern, KERN_HOSTNAME, hostname,
-    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
+    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_CAPRD | CTLFLAG_MPSAFE,
     (void *)(offsetof(struct prison, pr_hostname)), MAXHOSTNAMELEN,
     sysctl_hostname, "A", "Hostname");
 SYSCTL_PROC(_kern, KERN_NISDOMAINNAME, domainname,
-    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
+    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_CAPRD | CTLFLAG_MPSAFE,
     (void *)(offsetof(struct prison, pr_domainname)), MAXHOSTNAMELEN,
     sysctl_hostname, "A", "Name of the current YP/NIS domain");
 SYSCTL_PROC(_kern, KERN_HOSTUUID, hostuuid,
-    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
+    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_CAPRD | CTLFLAG_MPSAFE,
     (void *)(offsetof(struct prison, pr_hostuuid)), HOSTUUIDLEN,
     sysctl_hostname, "A", "Host UUID");
 
@@ -407,8 +411,8 @@ SYSCTL_PROC(_kern, KERN_SECURELVL, securelevel,
 /* Actual kernel configuration options. */
 extern char kernconfstring[];
 
-SYSCTL_STRING(_kern, OID_AUTO, conftxt, CTLFLAG_RD, kernconfstring, 0,
-    "Kernel configuration file");
+SYSCTL_STRING(_kern, OID_AUTO, conftxt, CTLFLAG_RD | CTLFLAG_MPSAFE,
+    kernconfstring, 0, "Kernel configuration file");
 #endif
 
 static int
diff --git a/freebsd/sys/kern/kern_synch.c b/freebsd/sys/kern/kern_synch.c
index 6ecedfd..6a8e775 100644
--- a/freebsd/sys/kern/kern_synch.c
+++ b/freebsd/sys/kern/kern_synch.c
@@ -17,7 +17,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -191,13 +191,7 @@ _sleep(void *ident, struct lock_object *lock, int priority,
 	pri = priority;
 #endif /* __rtems__ */
 
-	/*
-	 * If we are already on a sleep queue, then remove us from that
-	 * sleep queue first.  We have to do this to handle recursive
-	 * sleeps.
-	 */
-	if (TD_ON_SLEEPQ(td))
-		sleepq_remove(td, td->td_wchan);
+	KASSERT(!TD_ON_SLEEPQ(td), ("recursive sleep"));
 
 	if ((uint8_t *)ident >= &pause_wchan[0] &&
 	    (uint8_t *)ident <= &pause_wchan[MAXCPU - 1])
diff --git a/freebsd/sys/kern/kern_sysctl.c b/freebsd/sys/kern/kern_sysctl.c
index 3bcf668..07ddded 100644
--- a/freebsd/sys/kern/kern_sysctl.c
+++ b/freebsd/sys/kern/kern_sysctl.c
@@ -18,7 +18,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
diff --git a/freebsd/sys/kern/kern_time.c b/freebsd/sys/kern/kern_time.c
index 2fb4dd2..9511193 100644
--- a/freebsd/sys/kern/kern_time.c
+++ b/freebsd/sys/kern/kern_time.c
@@ -12,7 +12,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
diff --git a/freebsd/sys/kern/kern_timeout.c b/freebsd/sys/kern/kern_timeout.c
index 37ec095..73b5533 100644
--- a/freebsd/sys/kern/kern_timeout.c
+++ b/freebsd/sys/kern/kern_timeout.c
@@ -17,7 +17,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -1059,6 +1059,8 @@ callout_when(sbintime_t sbt, sbintime_t precision, int flags,
 		spinlock_exit();
 #endif
 #endif
+		if (cold && to_sbt == 0)
+			to_sbt = sbinuptime();
 		if ((flags & C_HARDCLOCK) == 0)
 			to_sbt += tick_sbt;
 	} else
diff --git a/freebsd/sys/kern/subr_bus.c b/freebsd/sys/kern/subr_bus.c
index 3eb7d7e..1175456 100644
--- a/freebsd/sys/kern/subr_bus.c
+++ b/freebsd/sys/kern/subr_bus.c
@@ -30,6 +30,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <rtems/bsd/local/opt_bus.h>
+#include <rtems/bsd/local/opt_ddb.h>
 
 #include <rtems/bsd/sys/param.h>
 #include <sys/conf.h>
@@ -67,6 +68,8 @@ __FBSDID("$FreeBSD$");
 #include <vm/uma.h>
 #include <vm/vm.h>
 
+#include <ddb/ddb.h>
+
 SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL);
 SYSCTL_ROOT_NODE(OID_AUTO, dev, CTLFLAG_RW, NULL, NULL);
 
@@ -147,6 +150,9 @@ static MALLOC_DEFINE(M_BUS_SC, "bus-sc", "Bus data structures, softc");
 static void devctl2_init(void);
 #endif /* __rtems__ */
 
+#define DRIVERNAME(d)	((d)? d->name : "no driver")
+#define DEVCLANAME(d)	((d)? d->name : "no devclass")
+
 #ifdef BUS_DEBUG
 
 static int bus_debug = 1;
@@ -155,8 +161,6 @@ SYSCTL_INT(_debug, OID_AUTO, bus_debug, CTLFLAG_RWTUN, &bus_debug, 0,
 
 #define PDEBUG(a)	if (bus_debug) {printf("%s:%d: ", __func__, __LINE__), printf a; printf("\n");}
 #define DEVICENAME(d)	((d)? device_get_name(d): "no device")
-#define DRIVERNAME(d)	((d)? d->name : "no driver")
-#define DEVCLANAME(d)	((d)? d->name : "no devclass")
 
 /**
  * Produce the indenting, indent*2 spaces plus a '.' ahead of that to
@@ -180,8 +184,6 @@ void print_devclass_list(void);
 /* Make the compiler ignore the function calls */
 #define PDEBUG(a)			/* nop */
 #define DEVICENAME(d)			/* nop */
-#define DRIVERNAME(d)			/* nop */
-#define DEVCLANAME(d)			/* nop */
 
 #define print_device_short(d,i)		/* nop */
 #define print_device(d,i)		/* nop */
@@ -1981,15 +1983,17 @@ device_delete_child(device_t dev, device_t child)
 
 	PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev)));
 
-	/* remove children first */
+	/* detach parent before deleting children, if any */
+	if ((error = device_detach(child)) != 0)
+		return (error);
+	
+	/* remove children second */
 	while ((grandchild = TAILQ_FIRST(&child->children)) != NULL) {
 		error = device_delete_child(child, grandchild);
 		if (error)
 			return (error);
 	}
 
-	if ((error = device_detach(child)) != 0)
-		return (error);
 	if (child->devclass)
 		devclass_delete_device(child->devclass, child);
 	if (child->parent)
@@ -2180,6 +2184,12 @@ device_probe_child(device_t dev, device_t child)
 			}
 
 			/*
+			 * Reset DF_QUIET in case this driver doesn't
+			 * end up as the best driver.
+			 */
+			device_verbose(child);
+
+			/*
 			 * Probes that return BUS_PROBE_NOWILDCARD or lower
 			 * only match on devices whose driver was explicitly
 			 * specified.
@@ -3008,6 +3018,7 @@ device_detach(device_t dev)
 	if (!(dev->flags & DF_FIXEDCLASS))
 		devclass_delete_device(dev->devclass, dev);
 
+	device_verbose(dev);
 	dev->state = DS_NOTPRESENT;
 	(void)device_set_driver(dev, NULL);
 	device_sysctl_fini(dev);
@@ -5396,6 +5407,7 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
 	case DEV_SUSPEND:
 	case DEV_RESUME:
 	case DEV_SET_DRIVER:
+	case DEV_CLEAR_DRIVER:
 	case DEV_RESCAN:
 	case DEV_DELETE:
 		error = priv_check(td, PRIV_DRIVER);
@@ -5561,6 +5573,25 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
 		error = device_probe_and_attach(dev);
 		break;
 	}
+	case DEV_CLEAR_DRIVER:
+		if (!(dev->flags & DF_FIXEDCLASS)) {
+			error = 0;
+			break;
+		}
+		if (device_is_attached(dev)) {
+			if (req->dr_flags & DEVF_CLEAR_DRIVER_DETACH)
+				error = device_detach(dev);
+			else
+				error = EBUSY;
+			if (error)
+				break;
+		}
+
+		dev->flags &= ~DF_FIXEDCLASS;
+		dev->flags |= DF_WILDCARD;
+		devclass_delete_device(dev->devclass, dev);
+		error = device_probe_and_attach(dev);
+		break;
 	case DEV_RESCAN:
 		if (!device_is_attached(dev)) {
 			error = ENXIO;
@@ -5604,4 +5635,33 @@ devctl2_init(void)
 	make_dev_credf(MAKEDEV_ETERNAL, &devctl2_cdevsw, 0, NULL,
 	    UID_ROOT, GID_WHEEL, 0600, "devctl2");
 }
+
+#ifdef DDB
+DB_SHOW_COMMAND(device, db_show_device)
+{
+	device_t dev;
+
+	if (!have_addr)
+		return;
+
+	dev = (device_t)addr;
+
+	db_printf("name:    %s\n", device_get_nameunit(dev));
+	db_printf("  driver:  %s\n", DRIVERNAME(dev->driver));
+	db_printf("  class:   %s\n", DEVCLANAME(dev->devclass));
+	db_printf("  addr:    %p\n", dev);
+	db_printf("  parent:  %p\n", dev->parent);
+	db_printf("  softc:   %p\n", dev->softc);
+	db_printf("  ivars:   %p\n", dev->ivars);
+}
+
+DB_SHOW_ALL_COMMAND(devices, db_show_all_devices)
+{
+	device_t dev;
+
+	TAILQ_FOREACH(dev, &bus_data_devices, devlink) {
+		db_show_device((db_expr_t)dev, true, count, modif);
+	}
+}
+#endif
 #endif /* __rtems__ */
diff --git a/freebsd/sys/kern/subr_hash.c b/freebsd/sys/kern/subr_hash.c
index 1371a34..425fd34 100644
--- a/freebsd/sys/kern/subr_hash.c
+++ b/freebsd/sys/kern/subr_hash.c
@@ -17,7 +17,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
diff --git a/freebsd/sys/kern/subr_pcpu.c b/freebsd/sys/kern/subr_pcpu.c
index 4d22389..5c244b4 100644
--- a/freebsd/sys/kern/subr_pcpu.c
+++ b/freebsd/sys/kern/subr_pcpu.c
@@ -16,7 +16,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
diff --git a/freebsd/sys/kern/subr_prf.c b/freebsd/sys/kern/subr_prf.c
index 9273cd2..2aed7f6 100644
--- a/freebsd/sys/kern/subr_prf.c
+++ b/freebsd/sys/kern/subr_prf.c
@@ -17,7 +17,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -80,7 +80,11 @@ __FBSDID("$FreeBSD$");
  * Note that stdarg.h and the ANSI style va_start macro is used for both
  * ANSI and traditional C compilers.
  */
+#ifdef _KERNEL
 #include <machine/stdarg.h>
+#else
+#include <stdarg.h>
+#endif
 
 #ifdef _KERNEL
 
diff --git a/freebsd/sys/kern/subr_sleepqueue.c b/freebsd/sys/kern/subr_sleepqueue.c
index be8e772..a42c62f 100644
--- a/freebsd/sys/kern/subr_sleepqueue.c
+++ b/freebsd/sys/kern/subr_sleepqueue.c
@@ -434,7 +434,7 @@ sleepq_set_timeout_sbt(void *wchan, sbintime_t sbt, sbintime_t pr,
 	MPASS(TD_ON_SLEEPQ(td));
 	MPASS(td->td_sleepqueue == NULL);
 	MPASS(wchan != NULL);
-	if (cold)
+	if (cold && td == &thread0)
 		panic("timed sleep before timers are working");
 	KASSERT(td->td_sleeptimo == 0, ("td %d %p td_sleeptimo %jx",
 	    td->td_tid, td, (uintmax_t)td->td_sleeptimo));
@@ -1089,9 +1089,9 @@ sleepq_signal(void *wchan, int flags, int pri, int queue)
 	 * been sleeping the longest since threads are always added to
 	 * the tail of sleep queues.
 	 */
-	besttd = NULL;
+	besttd = TAILQ_FIRST(&sq->sq_blocked[queue]);
 	TAILQ_FOREACH(td, &sq->sq_blocked[queue], td_slpq) {
-		if (besttd == NULL || td->td_priority < besttd->td_priority)
+		if (td->td_priority < besttd->td_priority)
 			besttd = td;
 	}
 #else /* __rtems__ */
diff --git a/freebsd/sys/kern/subr_taskqueue.c b/freebsd/sys/kern/subr_taskqueue.c
index 8580e8f..5ef8683 100644
--- a/freebsd/sys/kern/subr_taskqueue.c
+++ b/freebsd/sys/kern/subr_taskqueue.c
@@ -89,6 +89,7 @@ struct taskqueue {
 #define	TQ_FLAGS_UNLOCKED_ENQUEUE	(1 << 2)
 
 #define	DT_CALLOUT_ARMED	(1 << 0)
+#define	DT_DRAIN_IN_PROGRESS	(1 << 1)
 
 #ifndef __rtems__
 #define	TQ_LOCK(tq)							\
@@ -334,7 +335,11 @@ taskqueue_enqueue_timeout(struct taskqueue *queue,
 #endif /* __rtems__ */
 	timeout_task->q = queue;
 	res = timeout_task->t.ta_pending;
-	if (ticks == 0) {
+	if (timeout_task->f & DT_DRAIN_IN_PROGRESS) {
+		/* Do nothing */
+		TQ_UNLOCK(queue);
+		res = -1;
+	} else if (ticks == 0) {
 		taskqueue_enqueue_locked(queue, &timeout_task->t);
 		/* The lock is released inside. */
 	} else {
@@ -598,8 +603,24 @@ taskqueue_drain_timeout(struct taskqueue *queue,
     struct timeout_task *timeout_task)
 {
 
+	/*
+	 * Set flag to prevent timer from re-starting during drain:
+	 */
+	TQ_LOCK(queue);
+	KASSERT((timeout_task->f & DT_DRAIN_IN_PROGRESS) == 0,
+	    ("Drain already in progress"));
+	timeout_task->f |= DT_DRAIN_IN_PROGRESS;
+	TQ_UNLOCK(queue);
+
 	callout_drain(&timeout_task->c);
 	taskqueue_drain(queue, &timeout_task->t);
+
+	/*
+	 * Clear flag to allow timer to re-start:
+	 */
+	TQ_LOCK(queue);
+	timeout_task->f &= ~DT_DRAIN_IN_PROGRESS;
+	TQ_UNLOCK(queue);
 }
 
 static void
@@ -666,6 +687,11 @@ _taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
 		} else
 			tq->tq_tcount++;
 	}
+	if (tq->tq_tcount == 0) {
+		free(tq->tq_threads, M_TASKQUEUE);
+		tq->tq_threads = NULL;
+		return (ENOMEM);
+	}
 #ifndef __rtems__
 	for (i = 0; i < count; i++) {
 		if (tq->tq_threads[i] == NULL)
diff --git a/freebsd/sys/kern/subr_uio.c b/freebsd/sys/kern/subr_uio.c
index a319685..f5dc76e 100644
--- a/freebsd/sys/kern/subr_uio.c
+++ b/freebsd/sys/kern/subr_uio.c
@@ -22,7 +22,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -556,7 +556,7 @@ fueword32(volatile const void *base, int32_t *val)
 int
 fueword64(volatile const void *base, int64_t *val)
 {
-	int32_t res;
+	int64_t res;
 
 	res = fuword64(base);
 	if (res == -1)
diff --git a/freebsd/sys/kern/sys_generic.c b/freebsd/sys/kern/sys_generic.c
index 26cd9d3..d6b3d15 100644
--- a/freebsd/sys/kern/sys_generic.c
+++ b/freebsd/sys/kern/sys_generic.c
@@ -17,7 +17,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
diff --git a/freebsd/sys/kern/sys_socket.c b/freebsd/sys/kern/sys_socket.c
index f312c8f..a253765 100644
--- a/freebsd/sys/kern/sys_socket.c
+++ b/freebsd/sys/kern/sys_socket.c
@@ -12,7 +12,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
diff --git a/freebsd/sys/kern/uipc_accf.c b/freebsd/sys/kern/uipc_accf.c
index 6ecea0e..7d6bde2 100644
--- a/freebsd/sys/kern/uipc_accf.c
+++ b/freebsd/sys/kern/uipc_accf.c
@@ -252,7 +252,7 @@ do_setopt_accept_filter(struct socket *so, struct sockopt *sopt)
 	newaf = malloc(sizeof(*newaf), M_ACCF, M_WAITOK |
 	    M_ZERO);
 	if (afp->accf_create != NULL && afap->af_name[0] != '\0') {
-		int len = strlen(afap->af_name) + 1;
+		size_t len = strlen(afap->af_name) + 1;
 		newaf->so_accept_filter_str = malloc(len, M_ACCF,
 		    M_WAITOK);
 		strcpy(newaf->so_accept_filter_str, afap->af_name);
diff --git a/freebsd/sys/kern/uipc_domain.c b/freebsd/sys/kern/uipc_domain.c
index 7c0e708..ab301eb 100644
--- a/freebsd/sys/kern/uipc_domain.c
+++ b/freebsd/sys/kern/uipc_domain.c
@@ -12,7 +12,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
diff --git a/freebsd/sys/kern/uipc_mbuf.c b/freebsd/sys/kern/uipc_mbuf.c
index db4975c..571dd3b 100644
--- a/freebsd/sys/kern/uipc_mbuf.c
+++ b/freebsd/sys/kern/uipc_mbuf.c
@@ -12,7 +12,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -986,7 +986,7 @@ m_devget(char *buf, int totlen, int off, struct ifnet *ifp,
 				len = MHLEN;
 
 				/* Place initial small packet/header at end of mbuf */
-				if (m && totlen + off + max_linkhdr <= MLEN) {
+				if (m && totlen + off + max_linkhdr <= MHLEN) {
 					m->m_data += max_linkhdr;
 					len -= max_linkhdr;
 				}
@@ -1338,7 +1338,7 @@ nospace:
 /*
  * Defragment an mbuf chain, returning at most maxfrags separate
  * mbufs+clusters.  If this is not possible NULL is returned and
- * the original mbuf chain is left in it's present (potentially
+ * the original mbuf chain is left in its present (potentially
  * modified) state.  We use two techniques: collapsing consecutive
  * mbufs and replacing consecutive mbufs by a cluster.
  *
diff --git a/freebsd/sys/kern/uipc_mbuf2.c b/freebsd/sys/kern/uipc_mbuf2.c
index fef1c51..fc5c8e8 100644
--- a/freebsd/sys/kern/uipc_mbuf2.c
+++ b/freebsd/sys/kern/uipc_mbuf2.c
@@ -43,7 +43,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
diff --git a/freebsd/sys/kern/uipc_sockbuf.c b/freebsd/sys/kern/uipc_sockbuf.c
index f62014b..a797714 100644
--- a/freebsd/sys/kern/uipc_sockbuf.c
+++ b/freebsd/sys/kern/uipc_sockbuf.c
@@ -12,7 +12,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
diff --git a/freebsd/sys/kern/uipc_socket.c b/freebsd/sys/kern/uipc_socket.c
index 3f2dba7..c086ee7 100644
--- a/freebsd/sys/kern/uipc_socket.c
+++ b/freebsd/sys/kern/uipc_socket.c
@@ -15,7 +15,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -1669,7 +1669,8 @@ dontblock:
 		do {
 			if (flags & MSG_PEEK) {
 				if (controlp != NULL) {
-					*controlp = m_copy(m, 0, m->m_len);
+					*controlp = m_copym(m, 0, m->m_len,
+					    M_NOWAIT);
 					controlp = &(*controlp)->m_next;
 				}
 				m = m->m_next;
diff --git a/freebsd/sys/kern/uipc_syscalls.c b/freebsd/sys/kern/uipc_syscalls.c
index 99ae639..2d81fc2 100644
--- a/freebsd/sys/kern/uipc_syscalls.c
+++ b/freebsd/sys/kern/uipc_syscalls.c
@@ -12,7 +12,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -94,20 +94,23 @@ static int sockargs(struct mbuf **, char *, socklen_t, int);
 /*
  * Convert a user file descriptor to a kernel file entry and check if required
  * capability rights are present.
+ * If required copy of current set of capability rights is returned.
  * A reference on the file entry is held upon returning.
  */
 int
 getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
-    struct file **fpp, u_int *fflagp)
+    struct file **fpp, u_int *fflagp, struct filecaps *havecapsp)
 {
 	struct file *fp;
 	int error;
 
-	error = fget_unlocked(td->td_proc->p_fd, fd, rightsp, &fp, NULL);
+	error = fget_cap(td, fd, rightsp, &fp, havecapsp);
 	if (error != 0)
 		return (error);
 	if (fp->f_type != DTYPE_SOCKET) {
 		fdrop(fp, td);
+		if (havecapsp != NULL)
+			filecaps_free(havecapsp);
 		return (ENOTSOCK);
 	}
 	if (fflagp != NULL)
@@ -148,7 +151,7 @@ rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp)
 	return (error);
 }
 
-#define	getsock_cap(td, fd, rights, fpp, fflagp) rtems_bsd_getsock(fd, fpp, fflagp)
+#define	getsock_cap(td, fd, rights, fpp, fflagp, havecapsp) rtems_bsd_getsock(fd, fpp, fflagp)
 #endif /* __rtems__ */
 
 /*
@@ -162,13 +165,7 @@ rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp)
 static
 #endif /* __rtems__ */
 int
-sys_socket(td, uap)
-	struct thread *td;
-	struct socket_args /* {
-		int	domain;
-		int	type;
-		int	protocol;
-	} */ *uap;
+sys_socket(struct thread *td, struct socket_args *uap)
 {
 	struct socket *so;
 	struct file *fp;
@@ -239,7 +236,6 @@ socket(int domain, int type, int protocol)
 }
 #endif /* __rtems__ */
 
-/* ARGSUSED */
 #ifdef __rtems__
 static int kern_bindat(struct thread *td, int dirfd, int fd,
     struct sockaddr *sa);
@@ -247,13 +243,7 @@ static int kern_bindat(struct thread *td, int dirfd, int fd,
 static
 #endif /* __rtems__ */
 int
-sys_bind(td, uap)
-	struct thread *td;
-	struct bind_args /* {
-		int	s;
-		caddr_t	name;
-		int	namelen;
-	} */ *uap;
+sys_bind(struct thread *td, struct bind_args *uap)
 {
 	struct sockaddr *sa;
 	int error;
@@ -298,7 +288,7 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
 	AUDIT_ARG_FD(fd);
 	AUDIT_ARG_SOCKADDR(td, dirfd, sa);
 	error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_BIND),
-	    &fp, NULL);
+	    &fp, NULL, NULL);
 	if (error != 0)
 		return (error);
 	so = fp->f_data;
@@ -321,18 +311,10 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
 	return (error);
 }
 
-/* ARGSUSED */
 #ifndef __rtems__
 static
 int
-sys_bindat(td, uap)
-	struct thread *td;
-	struct bindat_args /* {
-		int	fd;
-		int	s;
-		caddr_t	name;
-		int	namelen;
-	} */ *uap;
+sys_bindat(struct thread *td, struct bindat_args *uap)
 {
 	struct sockaddr *sa;
 	int error;
@@ -346,14 +328,8 @@ sys_bindat(td, uap)
 }
 #endif /* __rtems__ */
 
-/* ARGSUSED */
 int
-sys_listen(td, uap)
-	struct thread *td;
-	struct listen_args /* {
-		int	s;
-		int	backlog;
-	} */ *uap;
+sys_listen(struct thread *td, struct listen_args *uap)
 {
 	struct socket *so;
 	struct file *fp;
@@ -362,7 +338,7 @@ sys_listen(td, uap)
 
 	AUDIT_ARG_FD(uap->s);
 	error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_LISTEN),
-	    &fp, NULL);
+	    &fp, NULL, NULL);
 	if (error == 0) {
 		so = fp->f_data;
 #ifdef MAC
@@ -483,6 +459,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
 	struct file *headfp, *nfp = NULL;
 	struct sockaddr *sa = NULL;
 	struct socket *head, *so;
+	struct filecaps fcaps;
 	cap_rights_t rights;
 	u_int fflag;
 	pid_t pgid;
@@ -493,7 +470,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
 
 	AUDIT_ARG_FD(s);
 	error = getsock_cap(td, s, cap_rights_init(&rights, CAP_ACCEPT),
-	    &headfp, &fflag);
+	    &headfp, &fflag, &fcaps);
 	if (error != 0)
 		return (error);
 	head = headfp->f_data;
@@ -506,7 +483,8 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
 	if (error != 0)
 		goto done;
 #endif
-	error = falloc(td, &nfp, &fd, (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0);
+	error = falloc_caps(td, &nfp, &fd,
+	    (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0, &fcaps);
 	if (error != 0)
 		goto done;
 	ACCEPT_LOCK();
@@ -615,6 +593,8 @@ noconnection:
 	 * a reference on nfp to the caller on success if they request it.
 	 */
 done:
+	if (nfp == NULL)
+		filecaps_free(&fcaps);
 	if (fp != NULL) {
 		if (error == 0) {
 			*fp = nfp;
@@ -663,7 +643,6 @@ oaccept(td, uap)
 #endif /* COMPAT_OLDSOCK */
 #endif /* __rtems__ */
 
-/* ARGSUSED */
 #ifdef __rtems__
 static int kern_connectat(struct thread *td, int dirfd, int fd,
     struct sockaddr *sa);
@@ -671,13 +650,7 @@ static int kern_connectat(struct thread *td, int dirfd, int fd,
 static
 #endif /* __rtems__ */
 int
-sys_connect(td, uap)
-	struct thread *td;
-	struct connect_args /* {
-		int	s;
-		caddr_t	name;
-		int	namelen;
-	} */ *uap;
+sys_connect(struct thread *td, struct connect_args *uap)
 {
 	struct sockaddr *sa;
 	int error;
@@ -722,7 +695,7 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
 	AUDIT_ARG_FD(fd);
 	AUDIT_ARG_SOCKADDR(td, dirfd, sa);
 	error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_CONNECT),
-	    &fp, NULL);
+	    &fp, NULL, NULL);
 	if (error != 0)
 		return (error);
 	so = fp->f_data;
@@ -775,16 +748,8 @@ done1:
 }
 
 #ifndef __rtems__
-/* ARGSUSED */
 int
-sys_connectat(td, uap)
-	struct thread *td;
-	struct connectat_args /* {
-		int	fd;
-		int	s;
-		caddr_t	name;
-		int	namelen;
-	} */ *uap;
+sys_connectat(struct thread *td, struct connectat_args *uap)
 {
 	struct sockaddr *sa;
 	int error;
@@ -936,11 +901,7 @@ kern_sendit( struct thread *td, int s, struct msghdr *mp, int flags,
     struct mbuf *control, enum uio_seg segflg);
 #endif /* __rtems__ */
 static int
-sendit(td, s, mp, flags)
-	struct thread *td;
-	int s;
-	struct msghdr *mp;
-	int flags;
+sendit(struct thread *td, int s, struct msghdr *mp, int flags)
 {
 	struct mbuf *control;
 	struct sockaddr *to;
@@ -998,13 +959,8 @@ bad:
 }
 
 int
-kern_sendit(td, s, mp, flags, control, segflg)
-	struct thread *td;
-	int s;
-	struct msghdr *mp;
-	int flags;
-	struct mbuf *control;
-	enum uio_seg segflg;
+kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
+    struct mbuf *control, enum uio_seg segflg)
 {
 	struct file *fp;
 	struct uio auio;
@@ -1026,12 +982,12 @@ kern_sendit(td, s, mp, flags, control, segflg)
 		AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
 		cap_rights_set(&rights, CAP_CONNECT);
 	}
-	error = getsock_cap(td, s, &rights, &fp, NULL);
-	if (error != 0)
 #endif /* __rtems__ */
-	error = getsock_cap(td->td_proc->p_fd, s, rights, &fp, NULL);
-	if (error)
+	error = getsock_cap(td, s, &rights, &fp, NULL, NULL);
+	if (error != 0) {
+		m_freem(control);
 		return (error);
+	}
 	so = (struct socket *)fp->f_data;
 
 #ifdef KTRACE
@@ -1042,12 +998,16 @@ kern_sendit(td, s, mp, flags, control, segflg)
 	if (mp->msg_name != NULL) {
 		error = mac_socket_check_connect(td->td_ucred, so,
 		    mp->msg_name);
-		if (error != 0)
+		if (error != 0) {
+			m_freem(control);
 			goto bad;
+		}
 	}
 	error = mac_socket_check_send(td->td_ucred, so);
-	if (error != 0)
+	if (error != 0) {
+		m_freem(control);
 		goto bad;
+	}
 #endif
 
 	auio.uio_iov = mp->msg_iov;
@@ -1061,6 +1021,7 @@ kern_sendit(td, s, mp, flags, control, segflg)
 	for (i = 0; i < mp->msg_iovlen; i++, iov++) {
 		if ((auio.uio_resid += iov->iov_len) < 0) {
 			error = EINVAL;
+			m_freem(control);
 			goto bad;
 		}
 	}
@@ -1103,16 +1064,7 @@ bad:
 static
 #endif /* __rtems__ */
 int
-sys_sendto(td, uap)
-	struct thread *td;
-	struct sendto_args /* {
-		int	s;
-		caddr_t	buf;
-		size_t	len;
-		int	flags;
-		caddr_t	to;
-		int	tolen;
-	} */ *uap;
+sys_sendto(struct thread *td, struct sendto_args *uap)
 {
 	struct msghdr msg;
 	struct iovec aiov;
@@ -1167,7 +1119,7 @@ rtems_bsd_sendto(int socket, struct mbuf *m, int flags,
 	struct socket *so;
 	int error;
 
-	error = getsock_cap(td->td_proc->p_fd, socket, CAP_WRITE, &fp, NULL);
+	error = getsock_cap(td->td_proc->p_fd, socket, CAP_WRITE, &fp, NULL, NULL);
 	if (error)
 		return (error);
 	so = (struct socket *)fp->f_data;
@@ -1186,14 +1138,7 @@ rtems_bsd_sendto(int socket, struct mbuf *m, int flags,
 #ifndef __rtems__
 #ifdef COMPAT_OLDSOCK
 int
-osend(td, uap)
-	struct thread *td;
-	struct osend_args /* {
-		int	s;
-		caddr_t	buf;
-		int	len;
-		int	flags;
-	} */ *uap;
+osend(struct thread *td, struct osend_args *uap)
 {
 	struct msghdr msg;
 	struct iovec aiov;
@@ -1210,13 +1155,7 @@ osend(td, uap)
 }
 
 int
-osendmsg(td, uap)
-	struct thread *td;
-	struct osendmsg_args /* {
-		int	s;
-		caddr_t	msg;
-		int	flags;
-	} */ *uap;
+osendmsg(struct thread *td, struct osendmsg_args *uap)
 {
 	struct msghdr msg;
 	struct iovec *iov;
@@ -1241,13 +1180,7 @@ osendmsg(td, uap)
 static
 #endif /* __rtems__ */
 int
-sys_sendmsg(td, uap)
-	struct thread *td;
-	struct sendmsg_args /* {
-		int	s;
-		caddr_t	msg;
-		int	flags;
-	} */ *uap;
+sys_sendmsg(struct thread *td, struct sendmsg_args *uap)
 {
 	struct msghdr msg;
 	struct iovec *iov;
@@ -1297,12 +1230,8 @@ sendmsg(int socket, const struct msghdr *message, int flags)
 static
 #endif /* __rtems__ */
 int
-kern_recvit(td, s, mp, fromseg, controlp)
-	struct thread *td;
-	int s;
-	struct msghdr *mp;
-	enum uio_seg fromseg;
-	struct mbuf **controlp;
+kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg,
+    struct mbuf **controlp)
 {
 	struct uio auio;
 	struct iovec *iov;
@@ -1323,7 +1252,7 @@ kern_recvit(td, s, mp, fromseg, controlp)
 
 	AUDIT_ARG_FD(s);
 	error = getsock_cap(td, s, cap_rights_init(&rights, CAP_RECV),
-	    &fp, NULL);
+	    &fp, NULL, NULL);
 	if (error != 0)
 		return (error);
 	so = fp->f_data;
@@ -1459,11 +1388,7 @@ out:
 }
 
 static int
-recvit(td, s, mp, namelenp)
-	struct thread *td;
-	int s;
-	struct msghdr *mp;
-	void *namelenp;
+recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp)
 {
 	int error;
 
@@ -1484,16 +1409,7 @@ recvit(td, s, mp, namelenp)
 static
 #endif /* __rtems__ */
 int
-sys_recvfrom(td, uap)
-	struct thread *td;
-	struct recvfrom_args /* {
-		int	s;
-		caddr_t	buf;
-		size_t	len;
-		int	flags;
-		struct sockaddr * __restrict	from;
-		socklen_t * __restrict fromlenaddr;
-	} */ *uap;
+sys_recvfrom(struct thread *td, struct recvfrom_args *uap)
 {
 	struct msghdr msg;
 	struct iovec aiov;
@@ -1551,9 +1467,7 @@ recvfrom(int socket, void *__restrict buffer, size_t length, int flags,
 #ifndef __rtems__
 #ifdef COMPAT_OLDSOCK
 int
-orecvfrom(td, uap)
-	struct thread *td;
-	struct recvfrom_args *uap;
+orecvfrom(struct thread *td, struct recvfrom_args *uap)
 {
 
 	uap->flags |= MSG_COMPAT;
@@ -1563,14 +1477,7 @@ orecvfrom(td, uap)
 
 #ifdef COMPAT_OLDSOCK
 int
-orecv(td, uap)
-	struct thread *td;
-	struct orecv_args /* {
-		int	s;
-		caddr_t	buf;
-		int	len;
-		int	flags;
-	} */ *uap;
+orecv(struct thread *td, struct orecv_args *uap)
 {
 	struct msghdr msg;
 	struct iovec aiov;
@@ -1592,13 +1499,7 @@ orecv(td, uap)
  * rights where the control fields are now.
  */
 int
-orecvmsg(td, uap)
-	struct thread *td;
-	struct orecvmsg_args /* {
-		int	s;
-		struct	omsghdr *msg;
-		int	flags;
-	} */ *uap;
+orecvmsg(struct thread *td, struct orecvmsg_args *uap)
 {
 	struct msghdr msg;
 	struct iovec *iov;
@@ -1626,13 +1527,7 @@ orecvmsg(td, uap)
 static
 #endif /* __rtems__ */
 int
-sys_recvmsg(td, uap)
-	struct thread *td;
-	struct recvmsg_args /* {
-		int	s;
-		struct	msghdr *msg;
-		int	flags;
-	} */ *uap;
+sys_recvmsg(struct thread *td, struct recvmsg_args *uap)
 {
 	struct msghdr msg;
 	struct iovec *uiov, *iov;
@@ -1684,17 +1579,11 @@ recvmsg(int socket, struct msghdr *message, int flags)
 }
 #endif /* __rtems__ */
 
-/* ARGSUSED */
 #ifdef __rtems__
 static
 #endif /* __rtems__ */
 int
-sys_shutdown(td, uap)
-	struct thread *td;
-	struct shutdown_args /* {
-		int	s;
-		int	how;
-	} */ *uap;
+sys_shutdown(struct thread *td, struct shutdown_args *uap)
 {
 	struct socket *so;
 	struct file *fp;
@@ -1703,7 +1592,7 @@ sys_shutdown(td, uap)
 
 	AUDIT_ARG_FD(uap->s);
 	error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_SHUTDOWN),
-	    &fp, NULL);
+	    &fp, NULL, NULL);
 	if (error == 0) {
 		so = fp->f_data;
 		error = soshutdown(so, uap->how);
@@ -1736,7 +1625,6 @@ shutdown(int socket, int how)
 }
 #endif /* __rtems__ */
 
-/* ARGSUSED */
 #ifdef __rtems__
 static int kern_setsockopt( struct thread *td, int s, int level, int name,
     void *val, enum uio_seg valseg, socklen_t valsize);
@@ -1744,15 +1632,7 @@ static int kern_setsockopt( struct thread *td, int s, int level, int name,
 static
 #endif /* __rtems__ */
 int
-sys_setsockopt(td, uap)
-	struct thread *td;
-	struct setsockopt_args /* {
-		int	s;
-		int	level;
-		int	name;
-		caddr_t	val;
-		int	valsize;
-	} */ *uap;
+sys_setsockopt(struct thread *td, struct setsockopt_args *uap)
 {
 
 	return (kern_setsockopt(td, uap->s, uap->level, uap->name,
@@ -1784,14 +1664,8 @@ setsockopt(int socket, int level, int option_name, const void *option_value,
 #endif /* __rtems__ */
 
 int
-kern_setsockopt(td, s, level, name, val, valseg, valsize)
-	struct thread *td;
-	int s;
-	int level;
-	int name;
-	void *val;
-	enum uio_seg valseg;
-	socklen_t valsize;
+kern_setsockopt(struct thread *td, int s, int level, int name, void *val,
+    enum uio_seg valseg, socklen_t valsize)
 {
 	struct socket *so;
 	struct file *fp;
@@ -1822,7 +1696,7 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize)
 
 	AUDIT_ARG_FD(s);
 	error = getsock_cap(td, s, cap_rights_init(&rights, CAP_SETSOCKOPT),
-	    &fp, NULL);
+	    &fp, NULL, NULL);
 	if (error == 0) {
 		so = fp->f_data;
 		error = sosetopt(so, &sopt);
@@ -1831,7 +1705,6 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize)
 	return(error);
 }
 
-/* ARGSUSED */
 #ifdef __rtems__
 static int kern_getsockopt( struct thread *td, int s, int level, int name,
     void *val, enum uio_seg valseg, socklen_t *valsize);
@@ -1839,15 +1712,7 @@ static int kern_getsockopt( struct thread *td, int s, int level, int name,
 static
 #endif /* __rtems__ */
 int
-sys_getsockopt(td, uap)
-	struct thread *td;
-	struct getsockopt_args /* {
-		int	s;
-		int	level;
-		int	name;
-		void * __restrict	val;
-		socklen_t * __restrict avalsize;
-	} */ *uap;
+sys_getsockopt(struct thread *td, struct getsockopt_args *uap)
 {
 	socklen_t valsize;
 	int error;
@@ -1895,14 +1760,8 @@ getsockopt(int socket, int level, int option_name, void *__restrict
  * optval can be a userland or userspace. optlen is always a kernel pointer.
  */
 int
-kern_getsockopt(td, s, level, name, val, valseg, valsize)
-	struct thread *td;
-	int s;
-	int level;
-	int name;
-	void *val;
-	enum uio_seg valseg;
-	socklen_t *valsize;
+kern_getsockopt(struct thread *td, int s, int level, int name, void *val,
+    enum uio_seg valseg, socklen_t *valsize)
 {
 	struct socket *so;
 	struct file *fp;
@@ -1933,7 +1792,7 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize)
 
 	AUDIT_ARG_FD(s);
 	error = getsock_cap(td, s, cap_rights_init(&rights, CAP_GETSOCKOPT),
-	    &fp, NULL);
+	    &fp, NULL, NULL);
 	if (error == 0) {
 		so = fp->f_data;
 		error = sogetopt(so, &sopt);
@@ -1951,16 +1810,8 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
 /*
  * getsockname1() - Get socket name.
  */
-/* ARGSUSED */
 static int
-getsockname1(td, uap, compat)
-	struct thread *td;
-	struct getsockname_args /* {
-		int	fdes;
-		struct sockaddr * __restrict asa;
-		socklen_t * __restrict alen;
-	} */ *uap;
-	int compat;
+getsockname1(struct thread *td, struct getsockname_args *uap, int compat)
 {
 	struct sockaddr *sa;
 	socklen_t len;
@@ -2000,7 +1851,7 @@ getsockname(int socket, struct sockaddr *__restrict address,
 	int error;
 
 	if (td != NULL) {
-		error = getsockname1(td, &ua);
+		error = getsockname1(td, &ua, 0);
 	} else {
 		error = ENOMEM;
 	}
@@ -2021,7 +1872,7 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
 
 	AUDIT_ARG_FD(fd);
 	error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETSOCKNAME),
-	    &fp, NULL);
+	    &fp, NULL, NULL);
 	if (error != 0)
 		return (error);
 	so = fp->f_data;
@@ -2051,9 +1902,7 @@ bad:
 
 #ifndef __rtems__
 int
-sys_getsockname(td, uap)
-	struct thread *td;
-	struct getsockname_args *uap;
+sys_getsockname(struct thread *td, struct getsockname_args *uap)
 {
 
 	return (getsockname1(td, uap, 0));
@@ -2061,9 +1910,7 @@ sys_getsockname(td, uap)
 
 #ifdef COMPAT_OLDSOCK
 int
-ogetsockname(td, uap)
-	struct thread *td;
-	struct getsockname_args *uap;
+ogetsockname(struct thread *td, struct getsockname_args *uap)
 {
 
 	return (getsockname1(td, uap, 1));
@@ -2079,16 +1926,8 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
 /*
  * getpeername1() - Get name of peer for connected socket.
  */
-/* ARGSUSED */
 static int
-getpeername1(td, uap, compat)
-	struct thread *td;
-	struct getpeername_args /* {
-		int	fdes;
-		struct sockaddr * __restrict	asa;
-		socklen_t * __restrict	alen;
-	} */ *uap;
-	int compat;
+getpeername1(struct thread *td, struct getpeername_args *uap, int compat)
 {
 	struct sockaddr *sa;
 	socklen_t len;
@@ -2128,7 +1967,7 @@ getpeername(int socket, struct sockaddr *__restrict address,
 	int error;
 
 	if (td != NULL) {
-		error = getpeername1(td, &ua);
+		error = getpeername1(td, &ua, 0);
 	} else {
 		error = ENOMEM;
 	}
@@ -2149,7 +1988,7 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
 
 	AUDIT_ARG_FD(fd);
 	error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETPEERNAME),
-	    &fp, NULL);
+	    &fp, NULL, NULL);
 	if (error != 0)
 		return (error);
 	so = fp->f_data;
@@ -2184,9 +2023,7 @@ done:
 
 #ifndef __rtems__
 int
-sys_getpeername(td, uap)
-	struct thread *td;
-	struct getpeername_args *uap;
+sys_getpeername(struct thread *td, struct getpeername_args *uap)
 {
 
 	return (getpeername1(td, uap, 0));
@@ -2194,9 +2031,7 @@ sys_getpeername(td, uap)
 
 #ifdef COMPAT_OLDSOCK
 int
-ogetpeername(td, uap)
-	struct thread *td;
-	struct ogetpeername_args *uap;
+ogetpeername(struct thread *td, struct ogetpeername_args *uap)
 {
 
 	/* XXX uap should have type `getpeername_args *' to begin with. */
@@ -2242,10 +2077,7 @@ sockargs(struct mbuf **mp, char *buf, socklen_t buflen, int type)
 }
 
 int
-getsockaddr(namp, uaddr, len)
-	struct sockaddr **namp;
-	caddr_t uaddr;
-	size_t len;
+getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len)
 {
 	struct sockaddr *sa;
 	int error;
diff --git a/freebsd/sys/kern/uipc_usrreq.c b/freebsd/sys/kern/uipc_usrreq.c
index 7b2d1bc..159de13 100644
--- a/freebsd/sys/kern/uipc_usrreq.c
+++ b/freebsd/sys/kern/uipc_usrreq.c
@@ -14,7 +14,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -291,8 +291,8 @@ static int	unp_connectat(int, struct socket *, struct sockaddr *,
 static int	unp_connect2(struct socket *so, struct socket *so2, int);
 static void	unp_disconnect(struct unpcb *unp, struct unpcb *unp2);
 #ifndef __rtems__
-static void	unp_dispose(struct mbuf *);
-static void	unp_dispose_so(struct socket *so);
+static void	unp_dispose(struct socket *so);
+static void	unp_dispose_mbuf(struct mbuf *);
 #endif /* __rtems__ */
 static void	unp_shutdown(struct unpcb *);
 static void	unp_drop(struct unpcb *);
@@ -355,7 +355,7 @@ static struct domain localdomain = {
 	.dom_init =		unp_init,
 #ifndef __rtems__
 	.dom_externalize =	unp_externalize,
-	.dom_dispose =		unp_dispose_so,
+	.dom_dispose =		unp_dispose,
 #endif /* __rtems__ */
 	.dom_protosw =		localsw,
 	.dom_protoswNPROTOSW =	&localsw[nitems(localsw)]
@@ -1164,7 +1164,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
 
 	if (control != NULL && error != 0)
 #ifndef __rtems__
-		unp_dispose(control);
+		unp_dispose_mbuf(control);
 #else /* __rtems__ */
 		BSD_ASSERT(0);
 #endif /* __rtems__ */
@@ -2511,7 +2511,7 @@ unp_gc(__unused void *arg, int pending)
 }
 
 static void
-unp_dispose(struct mbuf *m)
+unp_dispose_mbuf(struct mbuf *m)
 {
 
 	if (m)
@@ -2522,7 +2522,7 @@ unp_dispose(struct mbuf *m)
  * Synchronize against unp_gc, which can trip over data as we are freeing it.
  */
 static void
-unp_dispose_so(struct socket *so)
+unp_dispose(struct socket *so)
 {
 	struct unpcb *unp;
 
@@ -2530,7 +2530,7 @@ unp_dispose_so(struct socket *so)
 	UNP_LIST_LOCK();
 	unp->unp_gcflag |= UNPGC_IGNORE_RIGHTS;
 	UNP_LIST_UNLOCK();
-	unp_dispose(so->so_rcv.sb_mb);
+	unp_dispose_mbuf(so->so_rcv.sb_mb);
 }
 
 static void
diff --git a/freebsd/sys/mips/include/machine/cpufunc.h b/freebsd/sys/mips/include/machine/cpufunc.h
index 427aba7..5ebaf4c 100644
--- a/freebsd/sys/mips/include/machine/cpufunc.h
+++ b/freebsd/sys/mips/include/machine/cpufunc.h
@@ -249,7 +249,8 @@ MIPS_RW32_COP0_SEL(config5, MIPS_COP_0_CONFIG, 5);
 #if defined(CPU_NLM) || defined(BERI_LARGE_TLB)
 MIPS_RW32_COP0_SEL(config6, MIPS_COP_0_CONFIG, 6);
 #endif
-#if defined(CPU_NLM) || defined(CPU_MIPS1004K)
+#if defined(CPU_NLM) || defined(CPU_MIPS1004K) || defined (CPU_MIPS74K) || \
+    defined(CPU_MIPS24K)
 MIPS_RW32_COP0_SEL(config7, MIPS_COP_0_CONFIG, 7);
 #endif
 MIPS_RW32_COP0(count, MIPS_COP_0_COUNT);
@@ -278,6 +279,13 @@ MIPS_RW32_COP0(entrylo1, MIPS_COP_0_TLB_LO1);
 MIPS_RW32_COP0(prid, MIPS_COP_0_PRID);
 /* XXX 64-bit?  */
 MIPS_RW32_COP0_SEL(ebase, MIPS_COP_0_PRID, 1);
+#ifdef CPU_XBURST
+MIPS_RW32_COP0_SEL(xburst_mbox0, MIPS_COP_0_XBURST_MBOX, 0);
+MIPS_RW32_COP0_SEL(xburst_mbox1, MIPS_COP_0_XBURST_MBOX, 1);
+MIPS_RW32_COP0_SEL(xburst_core_ctl, MIPS_COP_0_XBURST_C12, 2);
+MIPS_RW32_COP0_SEL(xburst_core_sts, MIPS_COP_0_XBURST_C12, 3);
+MIPS_RW32_COP0_SEL(xburst_reim, MIPS_COP_0_XBURST_C12, 4);
+#endif
 MIPS_RW32_COP0(watchlo, MIPS_COP_0_WATCH_LO);
 MIPS_RW32_COP0_SEL(watchlo1, MIPS_COP_0_WATCH_LO, 1);
 MIPS_RW32_COP0_SEL(watchlo2, MIPS_COP_0_WATCH_LO, 2);
diff --git a/freebsd/sys/mips/include/machine/cpuregs.h b/freebsd/sys/mips/include/machine/cpuregs.h
index 4ce7e1b..26bee19 100644
--- a/freebsd/sys/mips/include/machine/cpuregs.h
+++ b/freebsd/sys/mips/include/machine/cpuregs.h
@@ -522,12 +522,18 @@
 
 #define	MIPS_COP_0_COUNT	_(9)
 #define	MIPS_COP_0_COMPARE	_(11)
-
+#ifdef CPU_XBURST
+#define	MIPS_COP_0_XBURST_C12	_(12)
+#endif
 #define	MIPS_COP_0_CONFIG	_(16)
 #define	MIPS_COP_0_LLADDR	_(17)
 #define	MIPS_COP_0_WATCH_LO	_(18)
 #define	MIPS_COP_0_WATCH_HI	_(19)
 #define	MIPS_COP_0_TLB_XCONTEXT _(20)
+#ifdef CPU_XBURST
+#define	MIPS_COP_0_XBURST_MBOX	_(20)
+#endif
+
 #define	MIPS_COP_0_ECC		_(26)
 #define	MIPS_COP_0_CACHE_ERR	_(27)
 #define	MIPS_COP_0_TAG_LO	_(28)
diff --git a/freebsd/sys/net/altq/altq_subr.c b/freebsd/sys/net/altq/altq_subr.c
index 66ff441..a9a68b3 100644
--- a/freebsd/sys/net/altq/altq_subr.c
+++ b/freebsd/sys/net/altq/altq_subr.c
@@ -437,7 +437,7 @@ tbr_timeout(arg)
 	VNET_FOREACH(vnet_iter) {
 		CURVNET_SET(vnet_iter);
 		for (ifp = TAILQ_FIRST(&V_ifnet); ifp;
-		    ifp = TAILQ_NEXT(ifp, if_list)) {
+		    ifp = TAILQ_NEXT(ifp, if_link)) {
 			/* read from if_snd unlocked */
 			if (!TBR_IS_ENABLED(&ifp->if_snd))
 				continue;
diff --git a/freebsd/sys/net/bpf_filter.c b/freebsd/sys/net/bpf_filter.c
index 941fa29..ecfb3d1 100644
--- a/freebsd/sys/net/bpf_filter.c
+++ b/freebsd/sys/net/bpf_filter.c
@@ -436,6 +436,12 @@ bpf_filter(const struct bpf_insn *pc, u_char *p, u_int wirelen, u_int buflen)
 			A /= X;
 			continue;
 
+		case BPF_ALU|BPF_MOD|BPF_X:
+			if (X == 0)
+				return (0);
+			A %= X;
+			continue;
+
 		case BPF_ALU|BPF_AND|BPF_X:
 			A &= X;
 			continue;
@@ -444,6 +450,10 @@ bpf_filter(const struct bpf_insn *pc, u_char *p, u_int wirelen, u_int buflen)
 			A |= X;
 			continue;
 
+		case BPF_ALU|BPF_XOR|BPF_X:
+			A ^= X;
+			continue;
+
 		case BPF_ALU|BPF_LSH|BPF_X:
 			A <<= X;
 			continue;
@@ -468,6 +478,10 @@ bpf_filter(const struct bpf_insn *pc, u_char *p, u_int wirelen, u_int buflen)
 			A /= pc->k;
 			continue;
 
+		case BPF_ALU|BPF_MOD|BPF_K:
+			A %= pc->k;
+			continue;
+
 		case BPF_ALU|BPF_AND|BPF_K:
 			A &= pc->k;
 			continue;
@@ -476,6 +490,10 @@ bpf_filter(const struct bpf_insn *pc, u_char *p, u_int wirelen, u_int buflen)
 			A |= pc->k;
 			continue;
 
+		case BPF_ALU|BPF_XOR|BPF_K:
+			A ^= pc->k;
+			continue;
+
 		case BPF_ALU|BPF_LSH|BPF_K:
 			A <<= pc->k;
 			continue;
@@ -510,8 +528,8 @@ static const u_short	bpf_code_map[] = {
 	0x1013,	/* 0x60-0x6f: 1100100000001000 */
 	0x1010,	/* 0x70-0x7f: 0000100000001000 */
 	0x0093,	/* 0x80-0x8f: 1100100100000000 */
-	0x0000,	/* 0x90-0x9f: 0000000000000000 */
-	0x0000,	/* 0xa0-0xaf: 0000000000000000 */
+	0x1010,	/* 0x90-0x9f: 0000100000001000 */
+	0x1010,	/* 0xa0-0xaf: 0000100000001000 */
 	0x0002,	/* 0xb0-0xbf: 0100000000000000 */
 	0x0000,	/* 0xc0-0xcf: 0000000000000000 */
 	0x0000,	/* 0xd0-0xdf: 0000000000000000 */
@@ -579,7 +597,8 @@ bpf_validate(const struct bpf_insn *f, int len)
 		/*
 		 * Check for constant division by 0.
 		 */
-		if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
+		if ((p->code == (BPF_ALU|BPF_DIV|BPF_K) ||
+		    p->code == (BPF_ALU|BPF_MOD|BPF_K)) && p->k == 0)
 			return (0);
 	}
 	return (BPF_CLASS(f[len - 1].code) == BPF_RET);
diff --git a/freebsd/sys/net/ethernet.h b/freebsd/sys/net/ethernet.h
index bc5fa9c..5ec9d20 100644
--- a/freebsd/sys/net/ethernet.h
+++ b/freebsd/sys/net/ethernet.h
@@ -92,7 +92,7 @@ struct ether_vlan_header {
 #define	EVL_PRIOFTAG(tag)	(((tag) >> 13) & 7)
 #define	EVL_CFIOFTAG(tag)	(((tag) >> 12) & 1)
 #define	EVL_MAKETAG(vlid, pri, cfi)					\
-	((((((pri) & 7) << 1) | ((cfi) & 1)) << 12) | ((vlid) & EVL_VLID_MASK))
+	((((((pri) & 7) << 13) | ((cfi) & 1)) << 12) | ((vlid) & EVL_VLID_MASK))
 
 /*
  *  NOTE: 0x0000-0x05DC (0..1500) are generally IEEE 802.3 length fields.
diff --git a/freebsd/sys/net/if.c b/freebsd/sys/net/if.c
index 8bfa9e2..e1c525b 100644
--- a/freebsd/sys/net/if.c
+++ b/freebsd/sys/net/if.c
@@ -2208,7 +2208,7 @@ do_link_state_change(void *arg, int pending)
 	if (log_link_state_change)
 		log(LOG_NOTICE, "%s: link state changed to %s\n", ifp->if_xname,
 		    (link_state == LINK_STATE_UP) ? "UP" : "DOWN" );
-	EVENTHANDLER_INVOKE(ifnet_link_event, ifp, ifp->if_link_state);
+	EVENTHANDLER_INVOKE(ifnet_link_event, ifp, link_state);
 	CURVNET_RESTORE();
 }
 
diff --git a/freebsd/sys/net/if_arcsubr.c b/freebsd/sys/net/if_arcsubr.c
index 1954e26..042f3e8 100644
--- a/freebsd/sys/net/if_arcsubr.c
+++ b/freebsd/sys/net/if_arcsubr.c
@@ -227,7 +227,7 @@ arc_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
 
 	if ((ifp->if_flags & IFF_SIMPLEX) && (loop_copy != -1)) {
 		if ((m->m_flags & M_BCAST) || (loop_copy > 0)) {
-			struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
+			struct mbuf *n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
 
 			(void) if_simloop(ifp, n, dst->sa_family, ARC_HDRLEN);
 		} else if (ah->arc_dhost == ah->arc_shost) {
diff --git a/freebsd/sys/net/if_bridge.c b/freebsd/sys/net/if_bridge.c
index 77b376b..fc0dbff 100644
--- a/freebsd/sys/net/if_bridge.c
+++ b/freebsd/sys/net/if_bridge.c
@@ -335,7 +335,7 @@ static int	bridge_ip_checkbasic(struct mbuf **mp);
 #ifdef INET6
 static int	bridge_ip6_checkbasic(struct mbuf **mp);
 #endif /* INET6 */
-static int	bridge_fragment(struct ifnet *, struct mbuf *,
+static int	bridge_fragment(struct ifnet *, struct mbuf **mp,
 		    struct ether_header *, int, struct llc *);
 static void	bridge_linkstate(struct ifnet *ifp);
 static void	bridge_linkcheck(struct bridge_softc *sc);
@@ -410,7 +410,7 @@ SYSCTL_INT(_net_link_bridge, OID_AUTO, inherit_mac,
 static VNET_DEFINE(int, allow_llz_overlap) = 0;
 #define	V_allow_llz_overlap	VNET(allow_llz_overlap)
 SYSCTL_INT(_net_link_bridge, OID_AUTO, allow_llz_overlap,
-    CTLFLAG_VNET | CTLFLAG_RW | CTLFLAG_VNET, &VNET_NAME(allow_llz_overlap), 0,
+    CTLFLAG_RW | CTLFLAG_VNET, &VNET_NAME(allow_llz_overlap), 0,
     "Allow overlap of link-local scope "
     "zones of a bridge interface and the member interfaces");
 
@@ -1919,6 +1919,7 @@ bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m)
 			m->m_flags &= ~M_VLANTAG;
 		}
 
+		M_ASSERTPKTHDR(m); /* We shouldn't transmit mbuf without pkthdr */
 		if ((err = dst_ifp->if_transmit(dst_ifp, m))) {
 			m_freem(m0);
 			if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1);
@@ -3236,10 +3237,12 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
 			break;
 
 		/* check if we need to fragment the packet */
+		/* bridge_fragment generates a mbuf chain of packets */
+		/* that already include eth headers */
 		if (V_pfil_member && ifp != NULL && dir == PFIL_OUT) {
 			i = (*mp)->m_pkthdr.len;
 			if (i > ifp->if_mtu) {
-				error = bridge_fragment(ifp, *mp, &eh2, snap,
+				error = bridge_fragment(ifp, mp, &eh2, snap,
 					    &llc1);
 				return (error);
 			}
@@ -3478,56 +3481,77 @@ bad:
 /*
  * bridge_fragment:
  *
- *	Return a fragmented mbuf chain.
+ *	Fragment mbuf chain in multiple packets and prepend ethernet header.
  */
 static int
-bridge_fragment(struct ifnet *ifp, struct mbuf *m, struct ether_header *eh,
+bridge_fragment(struct ifnet *ifp, struct mbuf **mp, struct ether_header *eh,
     int snap, struct llc *llc)
 {
-	struct mbuf *m0;
+	struct mbuf *m = *mp, *nextpkt = NULL, *mprev = NULL, *mcur = NULL;
 	struct ip *ip;
 	int error = -1;
 
 	if (m->m_len < sizeof(struct ip) &&
 	    (m = m_pullup(m, sizeof(struct ip))) == NULL)
-		goto out;
+		goto dropit;
 	ip = mtod(m, struct ip *);
 
 	m->m_pkthdr.csum_flags |= CSUM_IP;
 	error = ip_fragment(ip, &m, ifp->if_mtu, ifp->if_hwassist);
 	if (error)
-		goto out;
+		goto dropit;
 
-	/* walk the chain and re-add the Ethernet header */
-	for (m0 = m; m0; m0 = m0->m_nextpkt) {
-		if (error == 0) {
-			if (snap) {
-				M_PREPEND(m0, sizeof(struct llc), M_NOWAIT);
-				if (m0 == NULL) {
-					error = ENOBUFS;
-					continue;
-				}
-				bcopy(llc, mtod(m0, caddr_t),
-				    sizeof(struct llc));
-			}
-			M_PREPEND(m0, ETHER_HDR_LEN, M_NOWAIT);
-			if (m0 == NULL) {
+	/*
+	 * Walk the chain and re-add the Ethernet header for
+	 * each mbuf packet.
+	 */
+	for (mcur = m; mcur; mcur = mcur->m_nextpkt) {
+		nextpkt = mcur->m_nextpkt;
+		mcur->m_nextpkt = NULL;
+		if (snap) {
+			M_PREPEND(mcur, sizeof(struct llc), M_NOWAIT);
+			if (mcur == NULL) {
 				error = ENOBUFS;
-				continue;
+				if (mprev != NULL)
+					mprev->m_nextpkt = nextpkt;
+				goto dropit;
 			}
-			bcopy(eh, mtod(m0, caddr_t), ETHER_HDR_LEN);
-		} else
-			m_freem(m);
-	}
+			bcopy(llc, mtod(mcur, caddr_t),sizeof(struct llc));
+		}
+
+		M_PREPEND(mcur, ETHER_HDR_LEN, M_NOWAIT);
+		if (mcur == NULL) {
+			error = ENOBUFS;
+			if (mprev != NULL)
+				mprev->m_nextpkt = nextpkt;
+			goto dropit;
+		}
+		bcopy(eh, mtod(mcur, caddr_t), ETHER_HDR_LEN);
 
-	if (error == 0)
-		KMOD_IPSTAT_INC(ips_fragmented);
+		/*
+		 * The previous two M_PREPEND could have inserted one or two
+		 * mbufs in front so we have to update the previous packet's
+		 * m_nextpkt.
+		 */
+		mcur->m_nextpkt = nextpkt;
+		if (mprev != NULL)
+			mprev->m_nextpkt = mcur;
+		else {
+			/* The first mbuf in the original chain needs to be
+			 * updated. */
+			*mp = mcur;
+		}
+		mprev = mcur;
+	}
 
+	KMOD_IPSTAT_INC(ips_fragmented);
 	return (error);
 
-out:
-	if (m != NULL)
-		m_freem(m);
+dropit:
+	for (mcur = *mp; mcur; mcur = m) { /* droping the full packet chain */
+		m = mcur->m_nextpkt;
+		m_freem(mcur);
+	}
 	return (error);
 }
 
diff --git a/freebsd/sys/net/if_fddisubr.c b/freebsd/sys/net/if_fddisubr.c
index 9df882e..98ac4cc 100644
--- a/freebsd/sys/net/if_fddisubr.c
+++ b/freebsd/sys/net/if_fddisubr.c
@@ -277,7 +277,7 @@ fddi_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
 	if ((ifp->if_flags & IFF_SIMPLEX) && (loop_copy != -1)) {
 		if ((m->m_flags & M_BCAST) || (loop_copy > 0)) {
 			struct mbuf *n;
-			n = m_copy(m, 0, (int)M_COPYALL);
+			n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
 			(void) if_simloop(ifp, n, dst->sa_family,
 					  FDDI_HDR_LEN);
 	     	} else if (bcmp(fh->fddi_dhost, fh->fddi_shost,
diff --git a/freebsd/sys/net/if_iso88025subr.c b/freebsd/sys/net/if_iso88025subr.c
index d26d0eb..38322b2 100644
--- a/freebsd/sys/net/if_iso88025subr.c
+++ b/freebsd/sys/net/if_iso88025subr.c
@@ -366,7 +366,7 @@ iso88025_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
         if ((ifp->if_flags & IFF_SIMPLEX) && (loop_copy != -1)) {
                 if ((m->m_flags & M_BCAST) || (loop_copy > 0)) { 
                         struct mbuf *n;
-			n = m_copy(m, 0, (int)M_COPYALL);
+			n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
                         (void) if_simloop(ifp, n, dst->sa_family,
 					  ISO88025_HDR_LEN);
                 } else if (bcmp(th->iso88025_dhost, th->iso88025_shost,
diff --git a/freebsd/sys/net/if_llatbl.c b/freebsd/sys/net/if_llatbl.c
index 20c0b9d..a474188 100644
--- a/freebsd/sys/net/if_llatbl.c
+++ b/freebsd/sys/net/if_llatbl.c
@@ -68,8 +68,13 @@ static VNET_DEFINE(SLIST_HEAD(, lltable), lltables) =
     SLIST_HEAD_INITIALIZER(lltables);
 #define	V_lltables	VNET(lltables)
 
-struct rwlock lltable_rwlock;
-RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock");
+static struct rwlock lltable_list_lock;
+RW_SYSINIT(lltable_list_lock, &lltable_list_lock, "lltable_list_lock");
+#define	LLTABLE_LIST_RLOCK()		rw_rlock(&lltable_list_lock)
+#define	LLTABLE_LIST_RUNLOCK()		rw_runlock(&lltable_list_lock)
+#define	LLTABLE_LIST_WLOCK()		rw_wlock(&lltable_list_lock)
+#define	LLTABLE_LIST_WUNLOCK()		rw_wunlock(&lltable_list_lock)
+#define	LLTABLE_LIST_LOCK_ASSERT()	rw_assert(&lltable_list_lock, RA_LOCKED)
 
 static void lltable_unlink(struct lltable *llt);
 static void llentries_unlink(struct lltable *llt, struct llentries *head);
@@ -87,7 +92,7 @@ lltable_dump_af(struct lltable *llt, struct sysctl_req *wr)
 {
 	int error;
 
-	LLTABLE_LOCK_ASSERT();
+	LLTABLE_LIST_LOCK_ASSERT();
 
 	if (llt->llt_ifp->if_flags & IFF_LOOPBACK)
 		return (0);
@@ -110,7 +115,7 @@ lltable_sysctl_dumparp(int af, struct sysctl_req *wr)
 	struct lltable *llt;
 	int error = 0;
 
-	LLTABLE_RLOCK();
+	LLTABLE_LIST_RLOCK();
 	SLIST_FOREACH(llt, &V_lltables, llt_link) {
 		if (llt->llt_af == af) {
 			error = lltable_dump_af(llt, wr);
@@ -119,7 +124,7 @@ lltable_sysctl_dumparp(int af, struct sysctl_req *wr)
 		}
 	}
 done:
-	LLTABLE_RUNLOCK();
+	LLTABLE_LIST_RUNLOCK();
 	return (error);
 }
 
@@ -533,7 +538,7 @@ lltable_drain(int af)
 	struct llentry	*lle;
 	register int i;
 
-	LLTABLE_RLOCK();
+	LLTABLE_LIST_RLOCK();
 	SLIST_FOREACH(llt, &V_lltables, llt_link) {
 		if (llt->llt_af != af)
 			continue;
@@ -549,7 +554,7 @@ lltable_drain(int af)
 			}
 		}
 	}
-	LLTABLE_RUNLOCK();
+	LLTABLE_LIST_RUNLOCK();
 }
 #endif
 
@@ -593,14 +598,14 @@ lltable_prefix_free(int af, struct sockaddr *addr, struct sockaddr *mask,
 {
 	struct lltable *llt;
 
-	LLTABLE_RLOCK();
+	LLTABLE_LIST_RLOCK();
 	SLIST_FOREACH(llt, &V_lltables, llt_link) {
 		if (llt->llt_af != af)
 			continue;
 
 		llt->llt_prefix_free(llt, addr, mask, flags);
 	}
-	LLTABLE_RUNLOCK();
+	LLTABLE_LIST_RUNLOCK();
 }
 
 struct lltable *
@@ -634,18 +639,18 @@ void
 lltable_link(struct lltable *llt)
 {
 
-	LLTABLE_WLOCK();
+	LLTABLE_LIST_WLOCK();
 	SLIST_INSERT_HEAD(&V_lltables, llt, llt_link);
-	LLTABLE_WUNLOCK();
+	LLTABLE_LIST_WUNLOCK();
 }
 
 static void
 lltable_unlink(struct lltable *llt)
 {
 
-	LLTABLE_WLOCK();
+	LLTABLE_LIST_WLOCK();
 	SLIST_REMOVE(&V_lltables, llt, lltable, llt_link);
-	LLTABLE_WUNLOCK();
+	LLTABLE_LIST_WUNLOCK();
 
 }
 
@@ -741,13 +746,13 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
 	}
 
 	/* XXX linked list may be too expensive */
-	LLTABLE_RLOCK();
+	LLTABLE_LIST_RLOCK();
 	SLIST_FOREACH(llt, &V_lltables, llt_link) {
 		if (llt->llt_af == dst->sa_family &&
 		    llt->llt_ifp == ifp)
 			break;
 	}
-	LLTABLE_RUNLOCK();
+	LLTABLE_LIST_RUNLOCK();
 	KASSERT(llt != NULL, ("Yep, ugly hacks are bad\n"));
 
 	error = 0;
diff --git a/freebsd/sys/net/if_llatbl.h b/freebsd/sys/net/if_llatbl.h
index 51de726..5e89fea 100644
--- a/freebsd/sys/net/if_llatbl.h
+++ b/freebsd/sys/net/if_llatbl.h
@@ -37,17 +37,9 @@ struct ifnet;
 struct sysctl_req;
 struct rt_msghdr;
 struct rt_addrinfo;
-
 struct llentry;
 LIST_HEAD(llentries, llentry);
 
-extern struct rwlock lltable_rwlock;
-#define	LLTABLE_RLOCK()		rw_rlock(&lltable_rwlock)
-#define	LLTABLE_RUNLOCK()	rw_runlock(&lltable_rwlock)
-#define	LLTABLE_WLOCK()		rw_wlock(&lltable_rwlock)
-#define	LLTABLE_WUNLOCK()	rw_wunlock(&lltable_rwlock)
-#define	LLTABLE_LOCK_ASSERT()	rw_assert(&lltable_rwlock, RA_LOCKED)
-
 #define	LLE_MAX_LINKHDR		24	/* Full IB header */
 /*
  * Code referencing llentry must at least hold
diff --git a/freebsd/sys/net/if_loop.c b/freebsd/sys/net/if_loop.c
index aa5109e..5ee82fc 100644
--- a/freebsd/sys/net/if_loop.c
+++ b/freebsd/sys/net/if_loop.c
@@ -38,6 +38,7 @@
 
 #include <rtems/bsd/local/opt_inet.h>
 #include <rtems/bsd/local/opt_inet6.h>
+#include <rtems/bsd/local/opt_rss.h>
 
 #include <rtems/bsd/sys/param.h>
 #include <sys/systm.h>
@@ -226,6 +227,10 @@ looutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
 	if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
 	if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len);
 
+#ifdef RSS
+	M_HASHTYPE_CLEAR(m);
+#endif
+
 	/* BPF writes need to be handled specially. */
 	if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT)
 		bcopy(dst->sa_data, &af, sizeof(af));
diff --git a/freebsd/sys/net/if_var.h b/freebsd/sys/net/if_var.h
index ec3719d..6ddb6c7 100644
--- a/freebsd/sys/net/if_var.h
+++ b/freebsd/sys/net/if_var.h
@@ -178,9 +178,6 @@ struct if_encap_req {
 
 /*
  * Structure defining a network interface.
- *
- * Size ILP32:  592 (approx)
- *	 LP64: 1048 (approx)
  */
 struct ifnet {
 	/* General book keeping of interface lists. */
@@ -316,8 +313,6 @@ struct ifnet {
 };
 
 /* for compatibility with other BSDs */
-#define	if_addrlist	if_addrhead
-#define	if_list		if_link
 #define	if_name(ifp)	((ifp)->if_xname)
 
 /*
@@ -451,9 +446,6 @@ struct ifaddr {
 	counter_u64_t	ifa_obytes;
 };
 
-/* For compatibility with other BSDs. SCTP uses it. */
-#define	ifa_list	ifa_link
-
 struct ifaddr *	ifa_alloc(size_t size, int flags);
 void	ifa_free(struct ifaddr *ifa);
 void	ifa_ref(struct ifaddr *ifa);
@@ -504,7 +496,7 @@ extern	struct sx ifnet_sxlock;
 /*
  * Look up an ifnet given its index; the _ref variant also acquires a
  * reference that must be freed using if_rele().  It is almost always a bug
- * to call ifnet_byindex() instead if ifnet_byindex_ref().
+ * to call ifnet_byindex() instead of ifnet_byindex_ref().
  */
 struct ifnet	*ifnet_byindex(u_short idx);
 struct ifnet	*ifnet_byindex_locked(u_short idx);
diff --git a/freebsd/sys/net/pfkeyv2.h b/freebsd/sys/net/pfkeyv2.h
index c9b2769..3534881 100644
--- a/freebsd/sys/net/pfkeyv2.h
+++ b/freebsd/sys/net/pfkeyv2.h
@@ -283,6 +283,14 @@ struct sadb_x_nat_t_frag {
 };
 _Static_assert(sizeof(struct sadb_x_nat_t_frag) == 8, "struct size mismatch");
 
+/* Additional large replay window support
+ */
+struct sadb_x_sa_replay {
+  u_int16_t sadb_x_sa_replay_len;
+  u_int16_t sadb_x_sa_replay_exttype;
+  u_int32_t sadb_x_sa_replay_replay;	/* in packets */
+};
+_Static_assert(sizeof(struct sadb_x_sa_replay) == 8, "struct size mismatch");
 
 #define SADB_EXT_RESERVED             0
 #define SADB_EXT_SA                   1
@@ -311,7 +319,8 @@ _Static_assert(sizeof(struct sadb_x_nat_t_frag) == 8, "struct size mismatch");
 #define SADB_X_EXT_NAT_T_OAI          23	/* Peer's NAT_OA for src of SA. */
 #define SADB_X_EXT_NAT_T_OAR          24	/* Peer's NAT_OA for dst of SA. */
 #define SADB_X_EXT_NAT_T_FRAG         25	/* Manual MTU override. */
-#define SADB_EXT_MAX                  25
+#define SADB_X_EXT_SA_REPLAY          26	/* Replay window override. */
+#define SADB_EXT_MAX                  26
 
 #define SADB_SATYPE_UNSPEC	0
 #define SADB_SATYPE_AH		2
diff --git a/freebsd/sys/net/raw_usrreq.c b/freebsd/sys/net/raw_usrreq.c
index e170ad7..6e9668f 100644
--- a/freebsd/sys/net/raw_usrreq.c
+++ b/freebsd/sys/net/raw_usrreq.c
@@ -97,7 +97,7 @@ raw_input_ext(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src,
 			continue;
 		if (last) {
 			struct mbuf *n;
-			n = m_copy(m, 0, (int)M_COPYALL);
+			n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
 			if (n) {
 				if (sbappendaddr(&last->so_rcv, src,
 				    n, (struct mbuf *)0) == 0)
diff --git a/freebsd/sys/net/route.c b/freebsd/sys/net/route.c
index 3eb05b9..a851efa 100644
--- a/freebsd/sys/net/route.c
+++ b/freebsd/sys/net/route.c
@@ -362,7 +362,7 @@ rt_table_init(int offset)
 	rh->head.rnh_masks = &rh->rmhead;
 
 	/* Init locks */
-	rw_init(&rh->rib_lock, "rib head lock");
+	RIB_LOCK_INIT(rh);
 
 	/* Finally, set base callbacks */
 	rh->rnh_addaddr = rn_addroute;
@@ -394,7 +394,7 @@ rt_table_destroy(struct rib_head *rh)
 	rn_walktree(&rh->rmhead.head, rt_freeentry, &rh->rmhead.head);
 
 	/* Assume table is already empty */
-	rw_destroy(&rh->rib_lock);
+	RIB_LOCK_DESTROY(rh);
 	free(rh, M_RTABLE);
 }
 
@@ -499,9 +499,8 @@ rtalloc1_fib(struct sockaddr *dst, int report, u_long ignflags,
 		RIB_RUNLOCK(rh);
 	
 	/*
-	 * Either we hit the root or couldn't find any match,
-	 * Which basically means
-	 * "caint get there frm here"
+	 * Either we hit the root or could not find any match,
+	 * which basically means: "cannot get there from here".
 	 */
 miss:
 	V_rtstat.rts_unreach++;
diff --git a/freebsd/sys/net/route_var.h b/freebsd/sys/net/route_var.h
index a8ef56a..914bcfe 100644
--- a/freebsd/sys/net/route_var.h
+++ b/freebsd/sys/net/route_var.h
@@ -48,6 +48,8 @@ struct rib_head {
 	struct radix_mask_head	rmhead;		/* masks radix head */
 };
 
+#define	RIB_LOCK_INIT(rh)	rw_init(&(rh)->rib_lock, "rib head lock")
+#define	RIB_LOCK_DESTROY(rh)	rw_destroy(&(rh)->rib_lock)
 #define	RIB_RLOCK(rh)		rw_rlock(&(rh)->rib_lock)
 #define	RIB_RUNLOCK(rh)		rw_runlock(&(rh)->rib_lock)
 #define	RIB_WLOCK(rh)		rw_wlock(&(rh)->rib_lock)
diff --git a/freebsd/sys/net/rtsock.c b/freebsd/sys/net/rtsock.c
index 1e69bcd..97b9212 100644
--- a/freebsd/sys/net/rtsock.c
+++ b/freebsd/sys/net/rtsock.c
@@ -1578,8 +1578,8 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
 }
 
 static int
-sysctl_iflist_ifml(struct ifnet *ifp, struct rt_addrinfo *info,
-    struct walkarg *w, int len)
+sysctl_iflist_ifml(struct ifnet *ifp, const struct if_data *src_ifd,
+    struct rt_addrinfo *info, struct walkarg *w, int len)
 {
 	struct if_msghdrl *ifm;
 	struct if_data *ifd;
@@ -1610,14 +1610,14 @@ sysctl_iflist_ifml(struct ifnet *ifp, struct rt_addrinfo *info,
 		ifd = &ifm->ifm_data;
 	}
 
-	if_data_copy(ifp, ifd);
+	memcpy(ifd, src_ifd, sizeof(*ifd));
 
 	return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
 }
 
 static int
-sysctl_iflist_ifm(struct ifnet *ifp, struct rt_addrinfo *info,
-    struct walkarg *w, int len)
+sysctl_iflist_ifm(struct ifnet *ifp, const struct if_data *src_ifd,
+    struct rt_addrinfo *info, struct walkarg *w, int len)
 {
 	struct if_msghdr *ifm;
 	struct if_data *ifd;
@@ -1642,7 +1642,7 @@ sysctl_iflist_ifm(struct ifnet *ifp, struct rt_addrinfo *info,
 		ifd = &ifm->ifm_data;
 	}
 
-	if_data_copy(ifp, ifd);
+	memcpy(ifd, src_ifd, sizeof(*ifd));
 
 	return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
 }
@@ -1717,15 +1717,18 @@ sysctl_iflist(int af, struct walkarg *w)
 {
 	struct ifnet *ifp;
 	struct ifaddr *ifa;
+	struct if_data ifd;
 	struct rt_addrinfo info;
 	int len, error = 0;
 	struct sockaddr_storage ss;
 
 	bzero((caddr_t)&info, sizeof(info));
+	bzero(&ifd, sizeof(ifd));
 	IFNET_RLOCK_NOSLEEP();
 	TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
 		if (w->w_arg && w->w_arg != ifp->if_index)
 			continue;
+		if_data_copy(ifp, &ifd);
 		IF_ADDR_RLOCK(ifp);
 		ifa = ifp->if_addr;
 		info.rti_info[RTAX_IFP] = ifa->ifa_addr;
@@ -1735,9 +1738,11 @@ sysctl_iflist(int af, struct walkarg *w)
 		info.rti_info[RTAX_IFP] = NULL;
 		if (w->w_req && w->w_tmem) {
 			if (w->w_op == NET_RT_IFLISTL)
-				error = sysctl_iflist_ifml(ifp, &info, w, len);
+				error = sysctl_iflist_ifml(ifp, &ifd, &info, w,
+				    len);
 			else
-				error = sysctl_iflist_ifm(ifp, &info, w, len);
+				error = sysctl_iflist_ifm(ifp, &ifd, &info, w,
+				    len);
 			if (error)
 				goto done;
 		}
@@ -1780,13 +1785,15 @@ done:
 static int
 sysctl_ifmalist(int af, struct walkarg *w)
 {
-	struct ifnet *ifp;
-	struct ifmultiaddr *ifma;
-	struct	rt_addrinfo info;
-	int	len, error = 0;
+	struct rt_addrinfo info;
 	struct ifaddr *ifa;
+	struct ifmultiaddr *ifma;
+	struct ifnet *ifp;
+	int error, len;
 
+	error = 0;
 	bzero((caddr_t)&info, sizeof(info));
+
 	IFNET_RLOCK_NOSLEEP();
 	TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
 		if (w->w_arg && w->w_arg != ifp->if_index)
@@ -1806,7 +1813,7 @@ sysctl_ifmalist(int af, struct walkarg *w)
 			    ifma->ifma_lladdr : NULL;
 			error = rtsock_msg_buffer(RTM_NEWMADDR, &info, w, &len);
 			if (error != 0)
-				goto done;
+				break;
 			if (w->w_req && w->w_tmem) {
 				struct ifma_msghdr *ifmam;
 
@@ -1815,15 +1822,14 @@ sysctl_ifmalist(int af, struct walkarg *w)
 				ifmam->ifmam_flags = 0;
 				ifmam->ifmam_addrs = info.rti_addrs;
 				error = SYSCTL_OUT(w->w_req, w->w_tmem, len);
-				if (error) {
-					IF_ADDR_RUNLOCK(ifp);
-					goto done;
-				}
+				if (error != 0)
+					break;
 			}
 		}
 		IF_ADDR_RUNLOCK(ifp);
+		if (error != 0)
+			break;
 	}
-done:
 	IFNET_RUNLOCK_NOSLEEP();
 	return (error);
 }
diff --git a/freebsd/sys/netinet/cc/cc.h b/freebsd/sys/netinet/cc/cc.h
index 1da6f62..5e61b04 100644
--- a/freebsd/sys/netinet/cc/cc.h
+++ b/freebsd/sys/netinet/cc/cc.h
@@ -86,6 +86,7 @@ struct cc_var {
 		struct tcpcb		*tcp;
 		struct sctp_nets	*sctp;
 	} ccvc;
+	uint16_t	nsegs; /* # segments coalesced into current chain. */
 };
 
 /* cc_var flags. */
diff --git a/freebsd/sys/netinet/cc/cc_newreno.c b/freebsd/sys/netinet/cc/cc_newreno.c
index 8077bb2..4c21036 100644
--- a/freebsd/sys/netinet/cc/cc_newreno.c
+++ b/freebsd/sys/netinet/cc/cc_newreno.c
@@ -139,7 +139,8 @@ newreno_ack_received(struct cc_var *ccv, uint16_t type)
 			 */
 			if (CCV(ccv, snd_nxt) == CCV(ccv, snd_max))
 				incr = min(ccv->bytes_this_ack,
-				    V_tcp_abc_l_var * CCV(ccv, t_maxseg));
+				    ccv->nsegs * V_tcp_abc_l_var *
+				    CCV(ccv, t_maxseg));
 			else
 				incr = min(ccv->bytes_this_ack, CCV(ccv, t_maxseg));
 		}
@@ -183,30 +184,42 @@ newreno_after_idle(struct cc_var *ccv)
 static void
 newreno_cong_signal(struct cc_var *ccv, uint32_t type)
 {
-	u_int win;
+	uint32_t cwin, ssthresh_on_loss;
+	u_int mss;
+
+	cwin = CCV(ccv, snd_cwnd);
+	mss = CCV(ccv, t_maxseg);
+	ssthresh_on_loss =
+	    max((CCV(ccv, snd_max) - CCV(ccv, snd_una)) / 2 / mss, 2)
+		* mss;
 
 	/* Catch algos which mistakenly leak private signal types. */
 	KASSERT((type & CC_SIGPRIVMASK) == 0,
 	    ("%s: congestion signal type 0x%08x is private\n", __func__, type));
 
-	win = max(CCV(ccv, snd_cwnd) / 2 / CCV(ccv, t_maxseg), 2) *
-	    CCV(ccv, t_maxseg);
+	cwin = max(cwin / 2 / mss, 2) * mss;
 
 	switch (type) {
 	case CC_NDUPACK:
 		if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) {
-			if (!IN_CONGRECOVERY(CCV(ccv, t_flags)))
-				CCV(ccv, snd_ssthresh) = win;
+			if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
+				CCV(ccv, snd_ssthresh) = ssthresh_on_loss;
+				CCV(ccv, snd_cwnd) = cwin;
+			}
 			ENTER_RECOVERY(CCV(ccv, t_flags));
 		}
 		break;
 	case CC_ECN:
 		if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
-			CCV(ccv, snd_ssthresh) = win;
-			CCV(ccv, snd_cwnd) = win;
+			CCV(ccv, snd_ssthresh) = ssthresh_on_loss;
+			CCV(ccv, snd_cwnd) = cwin;
 			ENTER_CONGRECOVERY(CCV(ccv, t_flags));
 		}
 		break;
+	case CC_RTO:
+		CCV(ccv, snd_ssthresh) = ssthresh_on_loss;
+		CCV(ccv, snd_cwnd) = mss;
+		break;
 	}
 }
 
diff --git a/freebsd/sys/netinet/if_ether.c b/freebsd/sys/netinet/if_ether.c
index 0a8b101..9fb25c2 100644
--- a/freebsd/sys/netinet/if_ether.c
+++ b/freebsd/sys/netinet/if_ether.c
@@ -139,6 +139,28 @@ SYSCTL_INT(_net_link_ether_inet, OID_AUTO, max_log_per_second,
 	"Maximum number of remotely triggered ARP messages that can be "
 	"logged per second");
 
+/*
+ * Due to the exponential backoff algorithm used for the interval between GARP
+ * retransmissions, the maximum number of retransmissions is limited for
+ * sanity. This limit corresponds to a maximum interval between retransmissions
+ * of 2^16 seconds ~= 18 hours.
+ *
+ * Making this limit more dynamic is more complicated than worthwhile,
+ * especially since sending out GARPs spaced days apart would be of little
+ * use. A maximum dynamic limit would look something like:
+ *
+ * const int max = fls(INT_MAX / hz) - 1;
+ */
+#define MAX_GARP_RETRANSMITS 16
+static int sysctl_garp_rexmit(SYSCTL_HANDLER_ARGS);
+static int garp_rexmit_count = 0; /* GARP retransmission setting. */
+
+SYSCTL_PROC(_net_link_ether_inet, OID_AUTO, garp_rexmit_count,
+    CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_MPSAFE,
+    &garp_rexmit_count, 0, sysctl_garp_rexmit, "I",
+    "Number of times to retransmit GARP packets;"
+    " 0 to disable, maximum of 16");
+
 #define	ARP_LOG(pri, ...)	do {					\
 	if (ppsratecheck(&arp_lastlog, &arp_curpps, arp_maxpps))	\
 		log((pri), "arp: " __VA_ARGS__);			\
@@ -1289,6 +1311,109 @@ arp_add_ifa_lle(struct ifnet *ifp, const struct sockaddr *dst)
 		lltable_free_entry(LLTABLE(ifp), lle_tmp);
 }
 
+/*
+ * Handle the garp_rexmit_count. Like sysctl_handle_int(), but limits the range
+ * of valid values.
+ */
+static int
+sysctl_garp_rexmit(SYSCTL_HANDLER_ARGS)
+{
+	int error;
+	int rexmit_count = *(int *)arg1;
+
+	error = sysctl_handle_int(oidp, &rexmit_count, 0, req);
+
+	/* Enforce limits on any new value that may have been set. */
+	if (!error && req->newptr) {
+		/* A new value was set. */
+		if (rexmit_count < 0) {
+			rexmit_count = 0;
+		} else if (rexmit_count > MAX_GARP_RETRANSMITS) {
+			rexmit_count = MAX_GARP_RETRANSMITS;
+		}
+		*(int *)arg1 = rexmit_count;
+	}
+
+	return (error);
+}
+
+/*
+ * Retransmit a Gratuitous ARP (GARP) and, if necessary, schedule a callout to
+ * retransmit it again. A pending callout owns a reference to the ifa.
+ */
+static void
+garp_rexmit(void *arg)
+{
+	struct in_ifaddr *ia = arg;
+
+	if (callout_pending(&ia->ia_garp_timer) ||
+	    !callout_active(&ia->ia_garp_timer)) {
+		IF_ADDR_WUNLOCK(ia->ia_ifa.ifa_ifp);
+		ifa_free(&ia->ia_ifa);
+		return;
+	}
+
+	/*
+	 * Drop lock while the ARP request is generated.
+	 */
+	IF_ADDR_WUNLOCK(ia->ia_ifa.ifa_ifp);
+
+	arprequest(ia->ia_ifa.ifa_ifp, &IA_SIN(ia)->sin_addr,
+	    &IA_SIN(ia)->sin_addr, IF_LLADDR(ia->ia_ifa.ifa_ifp));
+
+	/*
+	 * Increment the count of retransmissions. If the count has reached the
+	 * maximum value, stop sending the GARP packets. Otherwise, schedule
+	 * the callout to retransmit another GARP packet.
+	 */
+	++ia->ia_garp_count;
+	if (ia->ia_garp_count >= garp_rexmit_count) {
+		ifa_free(&ia->ia_ifa);
+	} else {
+		int rescheduled;
+		IF_ADDR_WLOCK(ia->ia_ifa.ifa_ifp);
+		rescheduled = callout_reset(&ia->ia_garp_timer,
+		    (1 << ia->ia_garp_count) * hz,
+		    garp_rexmit, ia);
+		IF_ADDR_WUNLOCK(ia->ia_ifa.ifa_ifp);
+		if (rescheduled) {
+			ifa_free(&ia->ia_ifa);
+		}
+	}
+}
+
+/*
+ * Start the GARP retransmit timer.
+ *
+ * A single GARP is always transmitted when an IPv4 address is added
+ * to an interface and that is usually sufficient. However, in some
+ * circumstances, such as when a shared address is passed between
+ * cluster nodes, this single GARP may occasionally be dropped or
+ * lost. This can lead to neighbors on the network link working with a
+ * stale ARP cache and sending packets destined for that address to
+ * the node that previously owned the address, which may not respond.
+ *
+ * To avoid this situation, GARP retransmits can be enabled by setting
+ * the net.link.ether.inet.garp_rexmit_count sysctl to a value greater
+ * than zero. The setting represents the maximum number of
+ * retransmissions. The interval between retransmissions is calculated
+ * using an exponential backoff algorithm, doubling each time, so the
+ * retransmission intervals are: {1, 2, 4, 8, 16, ...} (seconds).
+ */
+static void
+garp_timer_start(struct ifaddr *ifa)
+{
+	struct in_ifaddr *ia = (struct in_ifaddr *) ifa;
+
+	IF_ADDR_WLOCK(ia->ia_ifa.ifa_ifp);
+	ia->ia_garp_count = 0;
+	if (callout_reset(&ia->ia_garp_timer, (1 << ia->ia_garp_count) * hz,
+	    garp_rexmit, ia) == 0) {
+		ifa_ref(ifa);
+	}
+	IF_ADDR_WUNLOCK(ia->ia_ifa.ifa_ifp);
+}
+
 void
 arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa)
 {
@@ -1304,6 +1429,9 @@ arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa)
 	if (ntohl(dst_in->sin_addr.s_addr) == INADDR_ANY)
 		return;
 	arp_announce_ifaddr(ifp, dst_in->sin_addr, IF_LLADDR(ifp));
+	if (garp_rexmit_count > 0) {
+		garp_timer_start(ifa);
+	}
 
 	arp_add_ifa_lle(ifp, dst);
 }
diff --git a/freebsd/sys/netinet/igmp.c b/freebsd/sys/netinet/igmp.c
index cd57e42..12bb2f0 100644
--- a/freebsd/sys/netinet/igmp.c
+++ b/freebsd/sys/netinet/igmp.c
@@ -545,10 +545,10 @@ igmp_ra_alloc(void)
 	m = m_get(M_WAITOK, MT_DATA);
 	p = mtod(m, struct ipoption *);
 	p->ipopt_dst.s_addr = INADDR_ANY;
-	p->ipopt_list[0] = IPOPT_RA;	/* Router Alert Option */
-	p->ipopt_list[1] = 0x04;	/* 4 bytes long */
-	p->ipopt_list[2] = IPOPT_EOL;	/* End of IP option list */
-	p->ipopt_list[3] = 0x00;	/* pad byte */
+	p->ipopt_list[0] = (char)IPOPT_RA;	/* Router Alert Option */
+	p->ipopt_list[1] = 0x04;		/* 4 bytes long */
+	p->ipopt_list[2] = IPOPT_EOL;		/* End of IP option list */
+	p->ipopt_list[3] = 0x00;		/* pad byte */
 	m->m_len = sizeof(p->ipopt_dst) + p->ipopt_list[1];
 
 	return (m);
diff --git a/freebsd/sys/netinet/in.c b/freebsd/sys/netinet/in.c
index 06b2397..f08e550 100644
--- a/freebsd/sys/netinet/in.c
+++ b/freebsd/sys/netinet/in.c
@@ -401,6 +401,8 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
 	ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
 	ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
 	ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask;
+	callout_init_rw(&ia->ia_garp_timer, &ifp->if_addr_lock,
+	    CALLOUT_RETURNUNLOCKED);
 
 	ia->ia_ifp = ifp;
 	ia->ia_addr = *addr;
@@ -639,6 +641,12 @@ in_difaddr_ioctl(caddr_t data, struct ifnet *ifp, struct thread *td)
 		IN_MULTI_UNLOCK();
 	}
 
+	IF_ADDR_WLOCK(ifp);
+	if (callout_stop(&ia->ia_garp_timer) == 1) {
+		ifa_free(&ia->ia_ifa);
+	}
+	IF_ADDR_WUNLOCK(ifp);
+
 	EVENTHANDLER_INVOKE(ifaddr_event, ifp);
 	ifa_free(&ia->ia_ifa);		/* in_ifaddrhead */
 
diff --git a/freebsd/sys/netinet/in_pcb.c b/freebsd/sys/netinet/in_pcb.c
index f879093..809a7de 100644
--- a/freebsd/sys/netinet/in_pcb.c
+++ b/freebsd/sys/netinet/in_pcb.c
@@ -1311,10 +1311,7 @@ in_pcbfree(struct inpcb *inp)
 	if (inp->inp_moptions != NULL)
 		inp_freemoptions(inp->inp_moptions);
 #endif
-	if (inp->inp_route.ro_rt) {
-		RTFREE(inp->inp_route.ro_rt);
-		inp->inp_route.ro_rt = (struct rtentry *)NULL;
-	}
+	RO_RTFREE(&inp->inp_route);
 	if (inp->inp_route.ro_lle)
 		LLE_FREE(inp->inp_route.ro_lle);	/* zeros ro_lle */
 
@@ -2254,10 +2251,7 @@ void
 in_losing(struct inpcb *inp)
 {
 
-	if (inp->inp_route.ro_rt) {
-		RTFREE(inp->inp_route.ro_rt);
-		inp->inp_route.ro_rt = (struct rtentry *)NULL;
-	}
+	RO_RTFREE(&inp->inp_route);
 	if (inp->inp_route.ro_lle)
 		LLE_FREE(inp->inp_route.ro_lle);	/* zeros ro_lle */
 	return;
diff --git a/freebsd/sys/netinet/in_var.h b/freebsd/sys/netinet/in_var.h
index af83e9a..08055c4 100644
--- a/freebsd/sys/netinet/in_var.h
+++ b/freebsd/sys/netinet/in_var.h
@@ -82,6 +82,8 @@ struct in_ifaddr {
 	struct	sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */
 #define	ia_broadaddr	ia_dstaddr
 	struct	sockaddr_in ia_sockmask; /* reserve space for general netmask */
+	struct	callout ia_garp_timer;	/* timer for retransmitting GARPs */
+	int	ia_garp_count;		/* count of retransmitted GARPs */
 };
 
 /*
diff --git a/freebsd/sys/netinet/ip_fastfwd.c b/freebsd/sys/netinet/ip_fastfwd.c
index 19dfb1a..bc4d70b 100644
--- a/freebsd/sys/netinet/ip_fastfwd.c
+++ b/freebsd/sys/netinet/ip_fastfwd.c
@@ -99,6 +99,7 @@ __FBSDID("$FreeBSD$");
 #include <net/vnet.h>
 
 #include <netinet/in.h>
+#include <netinet/in_fib.h>
 #include <netinet/in_kdtrace.h>
 #include <netinet/in_systm.h>
 #include <netinet/in_var.h>
@@ -109,40 +110,33 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/in_cksum.h>
 
-static struct sockaddr_in *
-ip_findroute(struct route *ro, struct in_addr dest, struct mbuf *m)
+static int
+ip_findroute(struct nhop4_basic *pnh, struct in_addr dest, struct mbuf *m)
 {
-	struct sockaddr_in *dst;
-	struct rtentry *rt;
 
+	bzero(pnh, sizeof(*pnh));
+	if (fib4_lookup_nh_basic(M_GETFIB(m), dest, 0, 0, pnh) != 0) {
+		IPSTAT_INC(ips_noroute);
+		IPSTAT_INC(ips_cantforward);
+		icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
+		return (EHOSTUNREACH);
+	}
 	/*
-	 * Find route to destination.
+	 * Drop blackholed traffic and directed broadcasts.
 	 */
-	bzero(ro, sizeof(*ro));
-	dst = (struct sockaddr_in *)&ro->ro_dst;
-	dst->sin_family = AF_INET;
-	dst->sin_len = sizeof(*dst);
-	dst->sin_addr.s_addr = dest.s_addr;
-	in_rtalloc_ign(ro, 0, M_GETFIB(m));
+	if ((pnh->nh_flags & (NHF_BLACKHOLE | NHF_BROADCAST)) != 0) {
+		IPSTAT_INC(ips_cantforward);
+		m_freem(m);
+		return (EHOSTUNREACH);
+	}
 
-	/*
-	 * Route there and interface still up?
-	 */
-	rt = ro->ro_rt;
-	if (rt && (rt->rt_flags & RTF_UP) &&
-	    (rt->rt_ifp->if_flags & IFF_UP) &&
-	    (rt->rt_ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-		if (rt->rt_flags & RTF_GATEWAY)
-			dst = (struct sockaddr_in *)rt->rt_gateway;
-	} else {
-		IPSTAT_INC(ips_noroute);
+	if (pnh->nh_flags & NHF_REJECT) {
 		IPSTAT_INC(ips_cantforward);
-		if (rt)
-			RTFREE(rt);
 		icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
-		return NULL;
+		return (EHOSTUNREACH);
 	}
-	return dst;
+
+	return (0);
 }
 
 /*
@@ -157,13 +151,11 @@ ip_tryforward(struct mbuf *m)
 {
 	struct ip *ip;
 	struct mbuf *m0 = NULL;
-	struct route ro;
-	struct sockaddr_in *dst = NULL;
-	struct ifnet *ifp;
+	struct nhop4_basic nh;
+	struct sockaddr_in dst;
 	struct in_addr odest, dest;
 	uint16_t ip_len, ip_off;
 	int error = 0;
-	int mtu;
 	struct m_tag *fwd_tag = NULL;
 
 	/*
@@ -173,9 +165,6 @@ ip_tryforward(struct mbuf *m)
 	M_ASSERTVALID(m);
 	M_ASSERTPKTHDR(m);
 
-	bzero(&ro, sizeof(ro));
-
-
 #ifdef ALTQ
 	/*
 	 * Is packet dropped by traffic conditioner?
@@ -307,29 +296,17 @@ passin:
 	/*
 	 * Find route to destination.
 	 */
-	if ((dst = ip_findroute(&ro, dest, m)) == NULL)
-		return NULL;	/* icmp unreach already sent */
-	ifp = ro.ro_rt->rt_ifp;
-
-	/*
-	 * Immediately drop blackholed traffic, and directed broadcasts
-	 * for either the all-ones or all-zero subnet addresses on
-	 * locally attached networks.
-	 */
-	if ((ro.ro_rt->rt_flags & (RTF_BLACKHOLE|RTF_BROADCAST)) != 0)
-		goto drop;
+	if (ip_findroute(&nh, dest, m) != 0)
+		return (NULL);	/* icmp unreach already sent */
 
 	/*
 	 * Step 5: outgoing firewall packet processing
 	 */
-
-	/*
-	 * Run through list of hooks for output packets.
-	 */
 	if (!PFIL_HOOKED(&V_inet_pfil_hook))
 		goto passout;
 
-	if (pfil_run_hooks(&V_inet_pfil_hook, &m, ifp, PFIL_OUT, NULL) || m == NULL) {
+	if (pfil_run_hooks(&V_inet_pfil_hook, &m, nh.nh_ifp, PFIL_OUT, NULL) ||
+	    m == NULL) {
 		goto drop;
 	}
 
@@ -354,9 +331,7 @@ forwardlocal:
 			 * Return packet for processing by ip_input().
 			 */
 			m->m_flags |= M_FASTFWD_OURS;
-			if (ro.ro_rt)
-				RTFREE(ro.ro_rt);
-			return m;
+			return (m);
 		}
 		/*
 		 * Redo route lookup with new destination address
@@ -367,10 +342,8 @@ forwardlocal:
 			m_tag_delete(m, fwd_tag);
 			m->m_flags &= ~M_IP_NEXTHOP;
 		}
-		RTFREE(ro.ro_rt);
-		if ((dst = ip_findroute(&ro, dest, m)) == NULL)
-			return NULL;	/* icmp unreach already sent */
-		ifp = ro.ro_rt->rt_ifp;
+		if (ip_findroute(&nh, dest, m) != 0)
+			return (NULL);	/* icmp unreach already sent */
 	}
 
 passout:
@@ -380,32 +353,15 @@ passout:
 	ip_len = ntohs(ip->ip_len);
 	ip_off = ntohs(ip->ip_off);
 
-	/*
-	 * Check if route is dampned (when ARP is unable to resolve)
-	 */
-	if ((ro.ro_rt->rt_flags & RTF_REJECT) &&
-	    (ro.ro_rt->rt_expire == 0 || time_uptime < ro.ro_rt->rt_expire)) {
-		icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
-		goto consumed;
-	}
-
-	/*
-	 * Check if media link state of interface is not down
-	 */
-	if (ifp->if_link_state == LINK_STATE_DOWN) {
-		icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
-		goto consumed;
-	}
+	bzero(&dst, sizeof(dst));
+	dst.sin_family = AF_INET;
+	dst.sin_len = sizeof(dst);
+	dst.sin_addr = nh.nh_addr;
 
 	/*
 	 * Check if packet fits MTU or if hardware will fragment for us
 	 */
-	if (ro.ro_rt->rt_mtu)
-		mtu = min(ro.ro_rt->rt_mtu, ifp->if_mtu);
-	else
-		mtu = ifp->if_mtu;
-
-	if (ip_len <= mtu) {
+	if (ip_len <= nh.nh_mtu) {
 		/*
 		 * Avoid confusing lower layers.
 		 */
@@ -413,9 +369,9 @@ passout:
 		/*
 		 * Send off the packet via outgoing interface
 		 */
-		IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
-		error = (*ifp->if_output)(ifp, m,
-				(struct sockaddr *)dst, &ro);
+		IP_PROBE(send, NULL, NULL, ip, nh.nh_ifp, ip, NULL);
+		error = (*nh.nh_ifp->if_output)(nh.nh_ifp, m,
+		    (struct sockaddr *)&dst, NULL);
 	} else {
 		/*
 		 * Handle EMSGSIZE with icmp reply needfrag for TCP MTU discovery
@@ -423,14 +379,15 @@ passout:
 		if (ip_off & IP_DF) {
 			IPSTAT_INC(ips_cantfrag);
 			icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG,
-				0, mtu);
+				0, nh.nh_mtu);
 			goto consumed;
 		} else {
 			/*
 			 * We have to fragment the packet
 			 */
 			m->m_pkthdr.csum_flags |= CSUM_IP;
-			if (ip_fragment(ip, &m, mtu, ifp->if_hwassist))
+			if (ip_fragment(ip, &m, nh.nh_mtu,
+			    nh.nh_ifp->if_hwassist) != 0)
 				goto drop;
 			KASSERT(m != NULL, ("null mbuf and no error"));
 			/*
@@ -445,9 +402,11 @@ passout:
 				 */
 				m_clrprotoflags(m);
 
-				IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
-				error = (*ifp->if_output)(ifp, m,
-					(struct sockaddr *)dst, &ro);
+				IP_PROBE(send, NULL, NULL, ip, nh.nh_ifp,
+				    ip, NULL);
+				/* XXX: we can use cached route here */
+				error = (*nh.nh_ifp->if_output)(nh.nh_ifp, m,
+				    (struct sockaddr *)&dst, NULL);
 				if (error)
 					break;
 			} while ((m = m0) != NULL);
@@ -465,17 +424,13 @@ passout:
 	if (error != 0)
 		IPSTAT_INC(ips_odropped);
 	else {
-		counter_u64_add(ro.ro_rt->rt_pksent, 1);
 		IPSTAT_INC(ips_forward);
 		IPSTAT_INC(ips_fastforward);
 	}
 consumed:
-	RTFREE(ro.ro_rt);
 	return NULL;
 drop:
 	if (m)
 		m_freem(m);
-	if (ro.ro_rt)
-		RTFREE(ro.ro_rt);
 	return NULL;
 }
diff --git a/freebsd/sys/netinet/ip_icmp.c b/freebsd/sys/netinet/ip_icmp.c
index f34cc4b..a1331ca 100644
--- a/freebsd/sys/netinet/ip_icmp.c
+++ b/freebsd/sys/netinet/ip_icmp.c
@@ -459,6 +459,8 @@ icmp_input(struct mbuf **mp, int *offp, int proto)
 			 * Treat subcodes 2,3 as immediate RST
 			 */
 			case ICMP_UNREACH_PROTOCOL:
+				code = PRC_UNREACH_PROTOCOL;
+				break;
 			case ICMP_UNREACH_PORT:
 				code = PRC_UNREACH_PORT;
 				break;
diff --git a/freebsd/sys/netinet/ip_input.c b/freebsd/sys/netinet/ip_input.c
index 425dbc1..a227861 100644
--- a/freebsd/sys/netinet/ip_input.c
+++ b/freebsd/sys/netinet/ip_input.c
@@ -1002,7 +1002,7 @@ ip_forward(struct mbuf *m, int srcrt)
 	 * because unnecessary, or because rate limited), so we are
 	 * really we are wasting a lot of work here.
 	 *
-	 * We don't use m_copy() because it might return a reference
+	 * We don't use m_copym() because it might return a reference
 	 * to a shared cluster. Both this function and ip_output()
 	 * assume exclusive access to the IP header in `m', so any
 	 * data in a cluster may change before we reach icmp_error().
diff --git a/freebsd/sys/netinet/ip_mroute.c b/freebsd/sys/netinet/ip_mroute.c
index f8b1473..f5aa0a3 100644
--- a/freebsd/sys/netinet/ip_mroute.c
+++ b/freebsd/sys/netinet/ip_mroute.c
@@ -1346,7 +1346,7 @@ X_ip_mforward(struct ip *ip, struct ifnet *ifp, struct mbuf *m,
 		goto fail;
 
 	    /* Make a copy of the header to send to the user level process */
-	    mm = m_copy(mb0, 0, hlen);
+	    mm = m_copym(mb0, 0, hlen, M_NOWAIT);
 	    if (mm == NULL)
 		goto fail1;
 
@@ -1544,7 +1544,7 @@ ip_mdq(struct mbuf *m, struct ifnet *ifp, struct mfc *rt, vifi_t xmt_vif)
 		struct sockaddr_in k_igmpsrc = { sizeof k_igmpsrc, AF_INET };
 		struct igmpmsg *im;
 		int hlen = ip->ip_hl << 2;
-		struct mbuf *mm = m_copy(m, 0, hlen);
+		struct mbuf *mm = m_copym(m, 0, hlen, M_NOWAIT);
 
 		if (mm && (!M_WRITABLE(mm) || mm->m_len < hlen))
 		    mm = m_pullup(mm, hlen);
@@ -2736,9 +2736,9 @@ pim_input(struct mbuf **mp, int *offp, int proto)
 	 * actions (e.g., send back PIM_REGISTER_STOP).
 	 * XXX: here m->m_data points to the outer IP header.
 	 */
-	mcp = m_copy(m, 0, iphlen + PIM_REG_MINLEN);
+	mcp = m_copym(m, 0, iphlen + PIM_REG_MINLEN, M_NOWAIT);
 	if (mcp == NULL) {
-	    CTR1(KTR_IPMF, "%s: m_copy() failed", __func__);
+	    CTR1(KTR_IPMF, "%s: m_copym() failed", __func__);
 	    m_freem(m);
 	    return (IPPROTO_DONE);
 	}
diff --git a/freebsd/sys/netinet/ip_output.c b/freebsd/sys/netinet/ip_output.c
index 81e7b12..5436ea2 100644
--- a/freebsd/sys/netinet/ip_output.c
+++ b/freebsd/sys/netinet/ip_output.c
@@ -352,7 +352,8 @@ again:
 		have_ia_ref = 1;
 		ifp = ia->ia_ifp;
 		ip->ip_ttl = 1;
-		isbroadcast = in_ifaddr_broadcast(dst->sin_addr, ia);
+		isbroadcast = ifp->if_flags & IFF_BROADCAST ?
+		    in_ifaddr_broadcast(dst->sin_addr, ia) : 0;
 	} else if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) &&
 	    imo != NULL && imo->imo_multicast_ifp != NULL) {
 		/*
@@ -405,8 +406,10 @@ again:
 			gw = (struct sockaddr_in *)rte->rt_gateway;
 		if (rte->rt_flags & RTF_HOST)
 			isbroadcast = (rte->rt_flags & RTF_BROADCAST);
-		else
+		else if (ifp->if_flags & IFF_BROADCAST)
 			isbroadcast = in_ifaddr_broadcast(gw->sin_addr, ia);
+		else
+			isbroadcast = 0;
 	}
 
 	/*
@@ -706,11 +709,7 @@ sendit:
 		IPSTAT_INC(ips_fragmented);
 
 done:
-	/*
-	 * Release the route if using our private route, or if
-	 * (with flowtable) we don't have our own reference.
-	 */
-	if (ro == &iproute || ro->ro_flags & RT_NORTREF)
+	if (ro == &iproute)
 		RO_RTFREE(ro);
 	else if (rte == NULL)
 		/*
diff --git a/freebsd/sys/netinet/raw_ip.c b/freebsd/sys/netinet/raw_ip.c
index a467958..c379d68 100644
--- a/freebsd/sys/netinet/raw_ip.c
+++ b/freebsd/sys/netinet/raw_ip.c
@@ -324,7 +324,7 @@ rip_input(struct mbuf **mp, int *offp, int proto)
 		if (last != NULL) {
 			struct mbuf *n;
 
-			n = m_copy(m, 0, (int)M_COPYALL);
+			n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
 			if (n != NULL)
 		    	    (void) rip_append(last, ip, n, &ripsrc);
 			/* XXX count dropped packet */
@@ -402,7 +402,7 @@ rip_input(struct mbuf **mp, int *offp, int proto)
 		if (last != NULL) {
 			struct mbuf *n;
 
-			n = m_copy(m, 0, (int)M_COPYALL);
+			n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
 			if (n != NULL)
 				(void) rip_append(last, ip, n, &ripsrc);
 			/* XXX count dropped packet */
diff --git a/freebsd/sys/netinet/sctp_asconf.c b/freebsd/sys/netinet/sctp_asconf.c
index 4256ab5..5d86e52 100644
--- a/freebsd/sys/netinet/sctp_asconf.c
+++ b/freebsd/sys/netinet/sctp_asconf.c
@@ -153,24 +153,19 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
 	union sctp_sockstore store;
 	struct sctp_paramhdr *ph;
 	uint16_t param_type, aparam_length;
-
 #if defined(INET) || defined(INET6)
 	uint16_t param_length;
-
 #endif
 	struct sockaddr *sa;
 	int zero_address = 0;
 	int bad_address = 0;
-
 #ifdef INET
 	struct sockaddr_in *sin;
 	struct sctp_ipv4addr_param *v4addr;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 *sin6;
 	struct sctp_ipv6addr_param *v6addr;
-
 #endif
 
 	aparam_length = ntohs(aph->ph.param_length);
@@ -308,24 +303,19 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
 	union sctp_sockstore store;
 	struct sctp_paramhdr *ph;
 	uint16_t param_type, aparam_length;
-
 #if defined(INET) || defined(INET6)
 	uint16_t param_length;
-
 #endif
 	struct sockaddr *sa;
 	int zero_address = 0;
 	int result;
-
 #ifdef INET
 	struct sockaddr_in *sin;
 	struct sctp_ipv4addr_param *v4addr;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 *sin6;
 	struct sctp_ipv6addr_param *v6addr;
-
 #endif
 
 	aparam_length = ntohs(aph->ph.param_length);
@@ -443,23 +433,18 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
 	union sctp_sockstore store;
 	struct sctp_paramhdr *ph;
 	uint16_t param_type, aparam_length;
-
 #if defined(INET) || defined(INET6)
 	uint16_t param_length;
-
 #endif
 	struct sockaddr *sa;
 	int zero_address = 0;
-
 #ifdef INET
 	struct sockaddr_in *sin;
 	struct sctp_ipv4addr_param *v4addr;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 *sin6;
 	struct sctp_ipv6addr_param *v6addr;
-
 #endif
 
 	aparam_length = ntohs(aph->ph.param_length);
@@ -1787,7 +1772,7 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset,
 	 * if there are any "sent" params still on the queue, these are
 	 * implicitly "success", or "failed" (if we got an error back) ...
 	 * so process these appropriately
-	 * 
+	 *
 	 * we assume that the correlation_id's are monotonically increasing
 	 * beginning from 1 and that we don't have *that* many outstanding
 	 * at any given time
@@ -1863,7 +1848,6 @@ sctp_is_scopeid_in_nets(struct sctp_tcb *stcb, struct sockaddr *sa)
 	/* didn't find one */
 	return (0);
 }
-
 #endif
 
 /*
@@ -2437,10 +2421,8 @@ sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa)
 		}
 	}
 
-	/*
-	 * we want to find the sequences which consist of ADD -> DEL -> ADD
-	 * or DEL -> ADD
-	 */
+	/* we want to find the sequences which consist of ADD -> DEL -> ADD
+	 * or DEL -> ADD */
 	if (add_cnt > del_cnt ||
 	    (add_cnt == del_cnt && last_param_type == SCTP_ADD_IP_ADDRESS)) {
 		return (1);
@@ -2492,10 +2474,8 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
 					if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
 					    (!sctp_is_addr_pending(stcb, sctp_ifa)))
 						continue;
-					/*
-					 * found a valid local v4 address to
-					 * use
-					 */
+					/* found a valid local v4 address to
+					 * use */
 					if (addr_locked == SCTP_ADDR_NOT_LOCKED)
 						SCTP_IPI_ADDR_RUNLOCK();
 					return (&sctp_ifa->address.sa);
@@ -2512,10 +2492,8 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
 					}
 					sin6 = &sctp_ifa->address.sin6;
 					if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
-						/*
-						 * we skip unspecifed
-						 * addresses
-						 */
+						/* we skip unspecifed
+						 * addresses */
 						continue;
 					}
 					if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
@@ -2532,10 +2510,8 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
 					if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
 					    (!sctp_is_addr_pending(stcb, sctp_ifa)))
 						continue;
-					/*
-					 * found a valid local v6 address to
-					 * use
-					 */
+					/* found a valid local v6 address to
+					 * use */
 					if (addr_locked == SCTP_ADDR_NOT_LOCKED)
 						SCTP_IPI_ADDR_RUNLOCK();
 					return (&sctp_ifa->address.sa);
@@ -2783,14 +2759,11 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
 	uint16_t plen, ptype;
 	struct sctp_ifa *sctp_ifa;
 	union sctp_sockstore store;
-
 #ifdef INET6
 	struct sctp_ipv6addr_param addr6_store;
-
 #endif
 #ifdef INET
 	struct sctp_ipv4addr_param addr4_store;
-
 #endif
 
 	SCTPDBG(SCTP_DEBUG_ASCONF2, "processing init-ack addresses\n");
@@ -2917,19 +2890,16 @@ sctp_addr_in_initack(struct mbuf *m, uint32_t offset, uint32_t length, struct so
 {
 	struct sctp_paramhdr tmp_param, *ph;
 	uint16_t plen, ptype;
-
 #ifdef INET
 	struct sockaddr_in *sin;
 	struct sctp_ipv4addr_param *a4p;
 	struct sctp_ipv6addr_param addr4_store;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 *sin6;
 	struct sctp_ipv6addr_param *a6p;
 	struct sctp_ipv6addr_param addr6_store;
 	struct sockaddr_in6 sin6_tmp;
-
 #endif
 
 	switch (sa->sa_family) {
@@ -3081,14 +3051,11 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
 	struct sctp_ifn *sctp_ifn;
 	struct sctp_ifa *sctp_ifa;
 	uint32_t vrf_id;
-
 #ifdef INET
 	struct sockaddr_in *sin;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 *sin6;
-
 #endif
 
 	if (stcb) {
@@ -3303,14 +3270,11 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
 	struct sctp_asconf_addr *aa;
 	struct sctp_ifa *sctp_ifap;
 	struct sctp_asconf_tag_param *vtag;
-
 #ifdef INET
 	struct sockaddr_in *to;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 *to6;
-
 #endif
 	if (net == NULL) {
 		SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing net\n");
diff --git a/freebsd/sys/netinet/sctp_asconf.h b/freebsd/sys/netinet/sctp_asconf.h
index 183c99b..c8d670e 100644
--- a/freebsd/sys/netinet/sctp_asconf.h
+++ b/freebsd/sys/netinet/sctp_asconf.h
@@ -90,7 +90,6 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
 
 extern int
     sctp_is_addr_pending(struct sctp_tcb *, struct sctp_ifa *);
-
 #endif				/* _KERNEL */
 
 #endif				/* !_NETINET_SCTP_ASCONF_H_ */
diff --git a/freebsd/sys/netinet/sctp_bsd_addr.c b/freebsd/sys/netinet/sctp_bsd_addr.c
index bfd7f81..72c63d7 100644
--- a/freebsd/sys/netinet/sctp_bsd_addr.c
+++ b/freebsd/sys/netinet/sctp_bsd_addr.c
@@ -142,7 +142,6 @@ sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa)
 		ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE;
 	}
 }
-
 #endif				/* INET6 */
 
 
@@ -203,20 +202,18 @@ sctp_init_ifns_for_vrf(int vrfid)
 	struct ifaddr *ifa;
 	struct sctp_ifa *sctp_ifa;
 	uint32_t ifa_flags;
-
 #ifdef INET6
 	struct in6_ifaddr *ifa6;
-
 #endif
 
 	IFNET_RLOCK();
-	TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
+	TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_link) {
 		if (sctp_is_desired_interface_type(ifn) == 0) {
 			/* non desired type */
 			continue;
 		}
 		IF_ADDR_RLOCK(ifn);
-		TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+		TAILQ_FOREACH(ifa, &ifn->if_addrhead, ifa_link) {
 			if (ifa->ifa_addr == NULL) {
 				continue;
 			}
@@ -363,11 +360,11 @@ void
 	struct ifaddr *ifa;
 
 	IFNET_RLOCK();
-	TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
+	TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_link) {
 		if (!(*pred) (ifn)) {
 			continue;
 		}
-		TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+		TAILQ_FOREACH(ifa, &ifn->if_addrhead, ifa_link) {
 			sctp_addr_change(ifa, add ? RTM_ADD : RTM_DELETE);
 		}
 	}
diff --git a/freebsd/sys/netinet/sctp_bsd_addr.h b/freebsd/sys/netinet/sctp_bsd_addr.h
index 24660ca..5fb1efb 100644
--- a/freebsd/sys/netinet/sctp_bsd_addr.h
+++ b/freebsd/sys/netinet/sctp_bsd_addr.h
@@ -48,7 +48,6 @@ void sctp_startup_iterator(void);
 
 #ifdef INET6
 void sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa);
-
 #endif
 
 #ifdef  SCTP_PACKET_LOGGING
diff --git a/freebsd/sys/netinet/sctp_cc_functions.c b/freebsd/sys/netinet/sctp_cc_functions.c
index 68dc460..49670e9 100644
--- a/freebsd/sys/netinet/sctp_cc_functions.c
+++ b/freebsd/sys/netinet/sctp_cc_functions.c
@@ -162,17 +162,13 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
 						uint32_t srtt;
 
 						srtt = net->lastsa;
-						/*
-						 * lastsa>>3;  we don't need
-						 * to devide ...
-						 */
+						/* lastsa>>3;  we don't need
+						 * to devide ... */
 						if (srtt == 0) {
 							srtt = 1;
 						}
-						/*
-						 * Short Version => Equal to
-						 * Contel Version MBe
-						 */
+						/* Short Version => Equal to
+						 * Contel Version MBe */
 						net->ssthresh = (uint32_t) (((uint64_t) 4 *
 						    (uint64_t) net->mtu *
 						    (uint64_t) net->cwnd) /
@@ -211,7 +207,7 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
 					/* Mark end of the window */
 					asoc->fast_recovery_tsn = asoc->sending_seq - 1;
 				} else {
-					asoc->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1;
+					asoc->fast_recovery_tsn = lchk->rec.data.tsn - 1;
 				}
 
 				/*
@@ -224,7 +220,7 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
 					/* Mark end of the window */
 					net->fast_recovery_tsn = asoc->sending_seq - 1;
 				} else {
-					net->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1;
+					net->fast_recovery_tsn = lchk->rec.data.tsn - 1;
 				}
 
 				sctp_timer_stop(SCTP_TIMER_TYPE_SEND,
@@ -407,10 +403,8 @@ cc_bw_decrease(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw, uint6
 			    net->flight_size,
 			    probepoint);
 			if (net->cc_mod.rtcc.ret_from_eq) {
-				/*
-				 * Switch over to CA if we are less
-				 * aggressive
-				 */
+				/* Switch over to CA if we are less
+				 * aggressive */
 				net->ssthresh = net->cwnd - 1;
 				net->partial_bytes_acked = 0;
 			}
@@ -786,9 +780,9 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
 			/*
 			 * At this point our bw_bytes has been updated by
 			 * incoming sack information.
-			 * 
+			 *
 			 * But our bw may not yet be set.
-			 * 
+			 *
 			 */
 			if ((net->cc_mod.rtcc.new_tot_time / 1000) > 0) {
 				nbw = net->cc_mod.rtcc.bw_bytes / (net->cc_mod.rtcc.new_tot_time / 1000);
@@ -853,10 +847,8 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
 						}
 						break;
 					case SCTP_CMT_RPV2:
-						/*
-						 * lastsa>>3;  we don't need
-						 * to divide ...
-						 */
+						/* lastsa>>3;  we don't need
+						 * to divide ... */
 						srtt = net->lastsa;
 						if (srtt == 0) {
 							srtt = 1;
@@ -940,10 +932,8 @@ sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb,
 						}
 						break;
 					case SCTP_CMT_RPV2:
-						/*
-						 * lastsa>>3;  we don't need
-						 * to divide ...
-						 */
+						/* lastsa>>3;  we don't need
+						 * to divide ... */
 						srtt = net->lastsa;
 						if (srtt == 0) {
 							srtt = 1;
@@ -1110,10 +1100,8 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets *
 				sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT);
 			}
 		} else {
-			/*
-			 * Further tuning down required over the drastic
-			 * original cut
-			 */
+			/* Further tuning down required over the drastic
+			 * original cut */
 			net->ssthresh -= (net->mtu * num_pkt_lost);
 			net->cwnd -= (net->mtu * num_pkt_lost);
 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
@@ -1127,10 +1115,8 @@ sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets *
 			net->ssthresh = net->cwnd / 2;
 			if (net->ssthresh < net->mtu) {
 				net->ssthresh = net->mtu;
-				/*
-				 * here back off the timer as well, to slow
-				 * us down
-				 */
+				/* here back off the timer as well, to slow
+				 * us down */
 				net->RTO <<= 1;
 			}
 			net->cwnd = net->ssthresh;
@@ -1377,10 +1363,8 @@ sctp_cwnd_new_rtcc_transmission_begins(struct sctp_tcb *stcb,
 
 			cwnd_in_mtu = SCTP_BASE_SYSCTL(sctp_initial_cwnd);
 			if (cwnd_in_mtu == 0) {
-				/*
-				 * Using 0 means that the value of RFC 4960
-				 * is used.
-				 */
+				/* Using 0 means that the value of RFC 4960
+				 * is used. */
 				cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND));
 			} else {
 				/*
@@ -1392,10 +1376,8 @@ sctp_cwnd_new_rtcc_transmission_begins(struct sctp_tcb *stcb,
 				cwnd = (net->mtu - sizeof(struct sctphdr)) * cwnd_in_mtu;
 			}
 			if (net->cwnd > cwnd) {
-				/*
-				 * Only set if we are not a timeout (i.e.
-				 * down to 1 mtu)
-				 */
+				/* Only set if we are not a timeout (i.e.
+				 * down to 1 mtu) */
 				net->cwnd = cwnd;
 			}
 		}
@@ -1718,7 +1700,7 @@ sctp_hs_cwnd_update_after_fr(struct sctp_tcb *stcb,
 					/* Mark end of the window */
 					asoc->fast_recovery_tsn = asoc->sending_seq - 1;
 				} else {
-					asoc->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1;
+					asoc->fast_recovery_tsn = lchk->rec.data.tsn - 1;
 				}
 
 				/*
@@ -1731,7 +1713,7 @@ sctp_hs_cwnd_update_after_fr(struct sctp_tcb *stcb,
 					/* Mark end of the window */
 					net->fast_recovery_tsn = asoc->sending_seq - 1;
 				} else {
-					net->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1;
+					net->fast_recovery_tsn = lchk->rec.data.tsn - 1;
 				}
 
 				sctp_timer_stop(SCTP_TIMER_TYPE_SEND,
@@ -2025,10 +2007,8 @@ htcp_param_update(struct sctp_nets *net)
 	htcp_beta_update(&net->cc_mod.htcp_ca, minRTT, maxRTT);
 	htcp_alpha_update(&net->cc_mod.htcp_ca);
 
-	/*
-	 * add slowly fading memory for maxRTT to accommodate routing
-	 * changes etc
-	 */
+	/* add slowly fading memory for maxRTT to accommodate routing
+	 * changes etc */
 	if (minRTT > 0 && maxRTT > minRTT)
 		net->cc_mod.htcp_ca.maxRTT = minRTT + ((maxRTT - minRTT) * 95) / 100;
 }
@@ -2111,7 +2091,6 @@ htcp_min_cwnd(struct sctp_tcb *stcb, struct sctp_nets *net)
 {
 	return (net->ssthresh);
 }
-
 #endif
 
 static void
@@ -2251,7 +2230,7 @@ sctp_htcp_cwnd_update_after_fr(struct sctp_tcb *stcb,
 					/* Mark end of the window */
 					asoc->fast_recovery_tsn = asoc->sending_seq - 1;
 				} else {
-					asoc->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1;
+					asoc->fast_recovery_tsn = lchk->rec.data.tsn - 1;
 				}
 
 				/*
@@ -2264,7 +2243,7 @@ sctp_htcp_cwnd_update_after_fr(struct sctp_tcb *stcb,
 					/* Mark end of the window */
 					net->fast_recovery_tsn = asoc->sending_seq - 1;
 				} else {
-					net->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1;
+					net->fast_recovery_tsn = lchk->rec.data.tsn - 1;
 				}
 
 				sctp_timer_stop(SCTP_TIMER_TYPE_SEND,
diff --git a/freebsd/sys/netinet/sctp_constants.h b/freebsd/sys/netinet/sctp_constants.h
index ecde4fe..e779051 100644
--- a/freebsd/sys/netinet/sctp_constants.h
+++ b/freebsd/sys/netinet/sctp_constants.h
@@ -898,8 +898,9 @@ __FBSDID("$FreeBSD$");
 #define SCTP_SSN_GE(a, b) SCTP_UINT16_GE(a, b)
 #define SCTP_TSN_GT(a, b) SCTP_UINT32_GT(a, b)
 #define SCTP_TSN_GE(a, b) SCTP_UINT32_GE(a, b)
-#define SCTP_MSGID_GT(o, a, b) ((o == 1) ? SCTP_UINT16_GT((uint16_t)a, (uint16_t)b) : SCTP_UINT32_GT(a, b))
-#define SCTP_MSGID_GE(o, a, b) ((o == 1) ? SCTP_UINT16_GE((uint16_t)a, (uint16_t)b) : SCTP_UINT32_GE(a, b))
+#define SCTP_MID_GT(i, a, b) (((i) == 1) ? SCTP_UINT32_GT(a, b) : SCTP_UINT16_GT((uint16_t)a, (uint16_t)b))
+#define SCTP_MID_GE(i, a, b) (((i) == 1) ? SCTP_UINT32_GE(a, b) : SCTP_UINT16_GE((uint16_t)a, (uint16_t)b))
+#define SCTP_MID_EQ(i, a, b) (((i) == 1) ? a == b : (uint16_t)a == (uint16_t)b)
 
 /* Mapping array manipulation routines */
 #define SCTP_IS_TSN_PRESENT(arry, gap) ((arry[(gap >> 3)] >> (gap & 0x07)) & 0x01)
diff --git a/freebsd/sys/netinet/sctp_crc32.c b/freebsd/sys/netinet/sctp_crc32.c
index bb081e8..9130feb 100644
--- a/freebsd/sys/netinet/sctp_crc32.c
+++ b/freebsd/sys/netinet/sctp_crc32.c
@@ -115,7 +115,6 @@ sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
 	base = sctp_finalize_crc32c(base);
 	return (base);
 }
-
 #endif				/* !defined(SCTP_WITH_NO_CSUM) */
 
 
diff --git a/freebsd/sys/netinet/sctp_crc32.h b/freebsd/sys/netinet/sctp_crc32.h
index 3f98be4..7fe02f5 100644
--- a/freebsd/sys/netinet/sctp_crc32.h
+++ b/freebsd/sys/netinet/sctp_crc32.h
@@ -39,9 +39,7 @@ __FBSDID("$FreeBSD$");
 #if defined(_KERNEL)
 #if !defined(SCTP_WITH_NO_CSUM)
 uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
-
 #endif
 void sctp_delayed_cksum(struct mbuf *, uint32_t offset);
-
 #endif				/* _KERNEL */
 #endif				/* __crc32c_h__ */
diff --git a/freebsd/sys/netinet/sctp_header.h b/freebsd/sys/netinet/sctp_header.h
index 3f4948d..b650d93 100644
--- a/freebsd/sys/netinet/sctp_header.h
+++ b/freebsd/sys/netinet/sctp_header.h
@@ -141,9 +141,9 @@ struct sctp_supported_chunk_types_param {
  */
 struct sctp_data {
 	uint32_t tsn;
-	uint16_t stream_id;
-	uint16_t stream_sequence;
-	uint32_t protocol_id;
+	uint16_t sid;
+	uint16_t ssn;
+	uint32_t ppid;
 	/* user data follows */
 }         SCTP_PACKED;
 
@@ -154,11 +154,11 @@ struct sctp_data_chunk {
 
 struct sctp_idata {
 	uint32_t tsn;
-	uint16_t stream_id;
+	uint16_t sid;
 	uint16_t reserved;	/* Where does the SSN go? */
-	uint32_t msg_id;
+	uint32_t mid;
 	union {
-		uint32_t protocol_id;
+		uint32_t ppid;
 		uint32_t fsn;	/* Fragment Sequence Number */
 	}     ppid_fsn;
 	/* user data follows */
@@ -182,7 +182,6 @@ struct sctp_init {
 	uint32_t initial_tsn;	/* I-TSN */
 	/* optional param's follow */
 }         SCTP_PACKED;
-
 #define SCTP_IDENTIFICATION_SIZE 16
 #define SCTP_ADDRESS_SIZE 4
 #define SCTP_RESERVE_SPACE 6
@@ -391,14 +390,14 @@ struct sctp_forward_tsn_chunk {
 }                      SCTP_PACKED;
 
 struct sctp_strseq {
-	uint16_t stream;
-	uint16_t sequence;
+	uint16_t sid;
+	uint16_t ssn;
 }           SCTP_PACKED;
 
 struct sctp_strseq_mid {
-	uint16_t stream;
+	uint16_t sid;
 	uint16_t flags;
-	uint32_t msg_id;
+	uint32_t mid;
 };
 
 struct sctp_forward_tsn_msg {
diff --git a/freebsd/sys/netinet/sctp_indata.c b/freebsd/sys/netinet/sctp_indata.c
index 12c2c80..d9449a6 100644
--- a/freebsd/sys/netinet/sctp_indata.c
+++ b/freebsd/sys/netinet/sctp_indata.c
@@ -132,8 +132,8 @@ struct sctp_queued_to_read *
 sctp_build_readq_entry(struct sctp_tcb *stcb,
     struct sctp_nets *net,
     uint32_t tsn, uint32_t ppid,
-    uint32_t context, uint16_t stream_no,
-    uint32_t stream_seq, uint8_t flags,
+    uint32_t context, uint16_t sid,
+    uint32_t mid, uint8_t flags,
     struct mbuf *dm)
 {
 	struct sctp_queued_to_read *read_queue_e = NULL;
@@ -143,14 +143,14 @@ sctp_build_readq_entry(struct sctp_tcb *stcb,
 		goto failed_build;
 	}
 	memset(read_queue_e, 0, sizeof(struct sctp_queued_to_read));
-	read_queue_e->sinfo_stream = stream_no;
-	read_queue_e->sinfo_ssn = stream_seq;
+	read_queue_e->sinfo_stream = sid;
 	read_queue_e->sinfo_flags = (flags << 8);
 	read_queue_e->sinfo_ppid = ppid;
 	read_queue_e->sinfo_context = context;
 	read_queue_e->sinfo_tsn = tsn;
 	read_queue_e->sinfo_cumtsn = tsn;
 	read_queue_e->sinfo_assoc_id = sctp_get_associd(stcb);
+	read_queue_e->mid = mid;
 	read_queue_e->top_fsn = read_queue_e->fsn_included = 0xffffffff;
 	TAILQ_INIT(&read_queue_e->reasm);
 	read_queue_e->whoFrom = net;
@@ -343,10 +343,8 @@ sctp_place_control_in_stream(struct sctp_stream_in *strm,
 		q = &strm->uno_inqueue;
 		if (asoc->idata_supported == 0) {
 			if (!TAILQ_EMPTY(q)) {
-				/*
-				 * Only one stream can be here in old style
-				 * -- abort
-				 */
+				/* Only one stream can be here in old style
+				 * -- abort */
 				return (-1);
 			}
 			TAILQ_INSERT_TAIL(q, control, next_instrm);
@@ -370,7 +368,7 @@ sctp_place_control_in_stream(struct sctp_stream_in *strm,
 		return (0);
 	} else {
 		TAILQ_FOREACH(at, q, next_instrm) {
-			if (SCTP_TSN_GT(at->msg_id, control->msg_id)) {
+			if (SCTP_MID_GT(asoc->idata_supported, at->mid, control->mid)) {
 				/*
 				 * one in queue is bigger than the new one,
 				 * insert before this one
@@ -382,7 +380,7 @@ sctp_place_control_in_stream(struct sctp_stream_in *strm,
 					control->on_strm_q = SCTP_ON_ORDERED;
 				}
 				break;
-			} else if (at->msg_id == control->msg_id) {
+			} else if (SCTP_MID_EQ(asoc->idata_supported, at->mid, control->mid)) {
 				/*
 				 * Gak, He sent me a duplicate msg id
 				 * number?? return -1 to abort.
@@ -427,18 +425,18 @@ sctp_abort_in_reasm(struct sctp_tcb *stcb,
 		    "Reass %x,CF:%x,TSN=%8.8x,SID=%4.4x,FSN=%8.8x,MID:%8.8x",
 		    opspot,
 		    control->fsn_included,
-		    chk->rec.data.TSN_seq,
-		    chk->rec.data.stream_number,
-		    chk->rec.data.fsn_num, chk->rec.data.stream_seq);
+		    chk->rec.data.tsn,
+		    chk->rec.data.sid,
+		    chk->rec.data.fsn, chk->rec.data.mid);
 	} else {
 		snprintf(msg, sizeof(msg),
 		    "Reass %x,CI:%x,TSN=%8.8x,SID=%4.4x,FSN=%4.4x,SSN:%4.4x",
 		    opspot,
 		    control->fsn_included,
-		    chk->rec.data.TSN_seq,
-		    chk->rec.data.stream_number,
-		    chk->rec.data.fsn_num,
-		    (uint16_t) chk->rec.data.stream_seq);
+		    chk->rec.data.tsn,
+		    chk->rec.data.sid,
+		    chk->rec.data.fsn,
+		    (uint16_t) chk->rec.data.mid);
 	}
 	oper = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 	sctp_m_freem(chk->data);
@@ -489,13 +487,13 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb,
 	 * has wrapped but not in the stream. Is this worth worrying about
 	 * or should we just change our queue sort at the bottom to be by
 	 * TSN.
-	 * 
-	 * Could it also be legal for a peer to send ssn 1 with TSN 2 and ssn 2
-	 * with TSN 1? If the peer is doing some sort of funky TSN/SSN
+	 *
+	 * Could it also be legal for a peer to send ssn 1 with TSN 2 and
+	 * ssn 2 with TSN 1? If the peer is doing some sort of funky TSN/SSN
 	 * assignment this could happen... and I don't see how this would be
 	 * a violation. So for now I am undecided an will leave the sort by
 	 * SSN alone. Maybe a hybred approach is the answer
-	 * 
+	 *
 	 */
 	struct sctp_queued_to_read *at;
 	int queue_needed;
@@ -506,19 +504,27 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb,
 	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_STR_LOGGING_ENABLE) {
 		sctp_log_strm_del(control, NULL, SCTP_STR_LOG_FROM_INTO_STRD);
 	}
-	if (SCTP_MSGID_GT((!asoc->idata_supported), strm->last_sequence_delivered, control->sinfo_ssn)) {
+	if (SCTP_MID_GT((asoc->idata_supported), strm->last_mid_delivered, control->mid)) {
 		/* The incoming sseq is behind where we last delivered? */
 		SCTPDBG(SCTP_DEBUG_INDATA1, "Duplicate S-SEQ: %u delivered: %u from peer, Abort association\n",
-		    control->sinfo_ssn, strm->last_sequence_delivered);
+		    control->mid, strm->last_mid_delivered);
 protocol_error:
 		/*
 		 * throw it in the stream so it gets cleaned up in
 		 * association destruction
 		 */
 		TAILQ_INSERT_HEAD(&strm->inqueue, control, next_instrm);
-		snprintf(msg, sizeof(msg), "Delivered SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
-		    strm->last_sequence_delivered, control->sinfo_tsn,
-		    control->sinfo_stream, control->sinfo_ssn);
+		if (asoc->idata_supported) {
+			snprintf(msg, sizeof(msg), "Delivered MID=%8.8x, got TSN=%8.8x, SID=%4.4x, MID=%8.8x",
+			    strm->last_mid_delivered, control->sinfo_tsn,
+			    control->sinfo_stream, control->mid);
+		} else {
+			snprintf(msg, sizeof(msg), "Delivered SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+			    (uint16_t) strm->last_mid_delivered,
+			    control->sinfo_tsn,
+			    control->sinfo_stream,
+			    (uint16_t) control->mid);
+		}
 		op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 		stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_2;
 		sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
@@ -532,8 +538,8 @@ protocol_error:
 	queue_needed = 1;
 	asoc->size_on_all_streams += control->length;
 	sctp_ucount_incr(asoc->cnt_on_all_streams);
-	nxt_todel = strm->last_sequence_delivered + 1;
-	if (nxt_todel == control->sinfo_ssn) {
+	nxt_todel = strm->last_mid_delivered + 1;
+	if (SCTP_MID_EQ(asoc->idata_supported, nxt_todel, control->mid)) {
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 		struct socket *so;
 
@@ -556,7 +562,7 @@ protocol_error:
 		queue_needed = 0;
 		asoc->size_on_all_streams -= control->length;
 		sctp_ucount_decr(asoc->cnt_on_all_streams);
-		strm->last_sequence_delivered++;
+		strm->last_mid_delivered++;
 		sctp_mark_non_revokable(asoc, control->sinfo_tsn);
 		sctp_add_to_readq(stcb->sctp_ep, stcb,
 		    control,
@@ -564,8 +570,8 @@ protocol_error:
 		    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_LOCKED);
 		TAILQ_FOREACH_SAFE(control, &strm->inqueue, next_instrm, at) {
 			/* all delivered */
-			nxt_todel = strm->last_sequence_delivered + 1;
-			if ((nxt_todel == control->sinfo_ssn) &&
+			nxt_todel = strm->last_mid_delivered + 1;
+			if (SCTP_MID_EQ(asoc->idata_supported, nxt_todel, control->mid) &&
 			    (((control->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG)) {
 				asoc->size_on_all_streams -= control->length;
 				sctp_ucount_decr(asoc->cnt_on_all_streams);
@@ -578,7 +584,7 @@ protocol_error:
 #endif
 				}
 				control->on_strm_q = 0;
-				strm->last_sequence_delivered++;
+				strm->last_mid_delivered++;
 				/*
 				 * We ignore the return of deliver_data here
 				 * since we always can hold the chunk on the
@@ -596,7 +602,7 @@ protocol_error:
 				    SCTP_READ_LOCK_NOT_HELD,
 				    SCTP_SO_LOCKED);
 				continue;
-			} else if (nxt_todel == control->sinfo_ssn) {
+			} else if (SCTP_MID_EQ(asoc->idata_supported, nxt_todel, control->mid)) {
 				*need_reasm = 1;
 			}
 			break;
@@ -612,8 +618,8 @@ protocol_error:
 		 */
 		if (sctp_place_control_in_stream(strm, asoc, control)) {
 			snprintf(msg, sizeof(msg),
-			    "Queue to str msg_id: %u duplicate",
-			    control->msg_id);
+			    "Queue to str MID: %u duplicate",
+			    control->mid);
 			sctp_clean_up_control(stcb, control);
 			op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 			stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_3;
@@ -724,10 +730,10 @@ sctp_build_readq_entry_from_ctl(struct sctp_queued_to_read *nc, struct sctp_queu
 {
 	memset(nc, 0, sizeof(struct sctp_queued_to_read));
 	nc->sinfo_stream = control->sinfo_stream;
-	nc->sinfo_ssn = control->sinfo_ssn;
+	nc->mid = control->mid;
 	TAILQ_INIT(&nc->reasm);
 	nc->top_fsn = control->top_fsn;
-	nc->msg_id = control->msg_id;
+	nc->mid = control->mid;
 	nc->sinfo_flags = control->sinfo_flags;
 	nc->sinfo_ppid = control->sinfo_ppid;
 	nc->sinfo_context = control->sinfo_context;
@@ -766,11 +772,11 @@ sctp_handle_old_unordered_data(struct sctp_tcb *stcb,
 {
 	/*
 	 * Special handling for the old un-ordered data chunk. All the
-	 * chunks/TSN's go to msg_id 0. So we have to do the old style
-	 * watching to see if we have it all. If you return one, no other
-	 * control entries on the un-ordered queue will be looked at. In
-	 * theory there should be no others entries in reality, unless the
-	 * guy is sending both unordered NDATA and unordered DATA...
+	 * chunks/TSN's go to mid 0. So we have to do the old style watching
+	 * to see if we have it all. If you return one, no other control
+	 * entries on the un-ordered queue will be looked at. In theory
+	 * there should be no others entries in reality, unless the guy is
+	 * sending both unordered NDATA and unordered DATA...
 	 */
 	struct sctp_tmit_chunk *chk, *lchk, *tchk;
 	uint32_t fsn;
@@ -787,7 +793,7 @@ restart:
 	fsn = control->fsn_included + 1;
 	/* Now what can we add? */
 	TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, lchk) {
-		if (chk->rec.data.fsn_num == fsn) {
+		if (chk->rec.data.fsn == fsn) {
 			/* Ok lets add it */
 			sctp_alloc_a_readq(stcb, nc);
 			if (nc == NULL) {
@@ -811,12 +817,14 @@ restart:
 					tchk = TAILQ_FIRST(&control->reasm);
 					if (tchk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) {
 						TAILQ_REMOVE(&control->reasm, tchk, sctp_next);
+						asoc->size_on_reasm_queue -= tchk->send_size;
+						sctp_ucount_decr(asoc->cnt_on_reasm_queue);
 						nc->first_frag_seen = 1;
-						nc->fsn_included = tchk->rec.data.fsn_num;
+						nc->fsn_included = tchk->rec.data.fsn;
 						nc->data = tchk->data;
-						nc->sinfo_ppid = tchk->rec.data.payloadtype;
-						nc->sinfo_tsn = tchk->rec.data.TSN_seq;
-						sctp_mark_non_revokable(asoc, tchk->rec.data.TSN_seq);
+						nc->sinfo_ppid = tchk->rec.data.ppid;
+						nc->sinfo_tsn = tchk->rec.data.tsn;
+						sctp_mark_non_revokable(asoc, tchk->rec.data.tsn);
 						tchk->data = NULL;
 						sctp_free_a_chunk(stcb, tchk, SCTP_SO_NOT_LOCKED);
 						sctp_setup_tail_pointer(nc);
@@ -828,10 +836,8 @@ restart:
 						TAILQ_INSERT_TAIL(&nc->reasm, tchk, sctp_next);
 						tchk = TAILQ_FIRST(&control->reasm);
 					}
-					/*
-					 * Now lets add it to the queue
-					 * after removing control
-					 */
+					/* Now lets add it to the queue
+					 * after removing control */
 					TAILQ_INSERT_TAIL(&strm->uno_inqueue, nc, next_instrm);
 					nc->on_strm_q = SCTP_ON_UNORDERED;
 					if (control->on_strm_q) {
@@ -855,10 +861,8 @@ restart:
 				}
 				sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
 				if ((nc->first_frag_seen) && !TAILQ_EMPTY(&nc->reasm)) {
-					/*
-					 * Switch to the new guy and
-					 * continue
-					 */
+					/* Switch to the new guy and
+					 * continue */
 					control = nc;
 					goto restart;
 				} else {
@@ -906,7 +910,7 @@ sctp_inject_old_unordered_data(struct sctp_tcb *stcb,
 		/* Its the very first one. */
 		SCTPDBG(SCTP_DEBUG_XXX,
 		    "chunk is a first fsn: %u becomes fsn_included\n",
-		    chk->rec.data.fsn_num);
+		    chk->rec.data.fsn);
 		if (control->first_frag_seen) {
 			/*
 			 * In old un-ordered we can reassembly on one
@@ -917,24 +921,22 @@ sctp_inject_old_unordered_data(struct sctp_tcb *stcb,
 			struct mbuf *tdata;
 			uint32_t tmp;
 
-			if (SCTP_TSN_GT(chk->rec.data.fsn_num, control->fsn_included)) {
-				/*
-				 * Easy way the start of a new guy beyond
-				 * the lowest
-				 */
+			if (SCTP_TSN_GT(chk->rec.data.fsn, control->fsn_included)) {
+				/* Easy way the start of a new guy beyond
+				 * the lowest */
 				goto place_chunk;
 			}
-			if ((chk->rec.data.fsn_num == control->fsn_included) ||
+			if ((chk->rec.data.fsn == control->fsn_included) ||
 			    (control->pdapi_started)) {
 				/*
 				 * Ok this should not happen, if it does we
 				 * started the pd-api on the higher TSN
 				 * (since the equals part is a TSN failure
 				 * it must be that).
-				 * 
-				 * We are completly hosed in that case since I
-				 * have no way to recover. This really will
-				 * only happen if we can get more TSN's
+				 *
+				 * We are completly hosed in that case since
+				 * I have no way to recover. This really
+				 * will only happen if we can get more TSN's
 				 * higher before the pd-api-point.
 				 */
 				sctp_abort_in_reasm(stcb, control, chk,
@@ -958,25 +960,25 @@ sctp_inject_old_unordered_data(struct sctp_tcb *stcb,
 			sctp_setup_tail_pointer(control);
 			/* Fix the FSN included */
 			tmp = control->fsn_included;
-			control->fsn_included = chk->rec.data.fsn_num;
-			chk->rec.data.fsn_num = tmp;
+			control->fsn_included = chk->rec.data.fsn;
+			chk->rec.data.fsn = tmp;
 			/* Fix the TSN included */
 			tmp = control->sinfo_tsn;
-			control->sinfo_tsn = chk->rec.data.TSN_seq;
-			chk->rec.data.TSN_seq = tmp;
+			control->sinfo_tsn = chk->rec.data.tsn;
+			chk->rec.data.tsn = tmp;
 			/* Fix the PPID included */
 			tmp = control->sinfo_ppid;
-			control->sinfo_ppid = chk->rec.data.payloadtype;
-			chk->rec.data.payloadtype = tmp;
+			control->sinfo_ppid = chk->rec.data.ppid;
+			chk->rec.data.ppid = tmp;
 			/* Fix tail pointer */
 			goto place_chunk;
 		}
 		control->first_frag_seen = 1;
-		control->top_fsn = control->fsn_included = chk->rec.data.fsn_num;
-		control->sinfo_tsn = chk->rec.data.TSN_seq;
-		control->sinfo_ppid = chk->rec.data.payloadtype;
+		control->top_fsn = control->fsn_included = chk->rec.data.fsn;
+		control->sinfo_tsn = chk->rec.data.tsn;
+		control->sinfo_ppid = chk->rec.data.ppid;
 		control->data = chk->data;
-		sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
+		sctp_mark_non_revokable(asoc, chk->rec.data.tsn);
 		chk->data = NULL;
 		sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		sctp_setup_tail_pointer(control);
@@ -985,7 +987,7 @@ sctp_inject_old_unordered_data(struct sctp_tcb *stcb,
 place_chunk:
 	inserted = 0;
 	TAILQ_FOREACH(at, &control->reasm, sctp_next) {
-		if (SCTP_TSN_GT(at->rec.data.fsn_num, chk->rec.data.fsn_num)) {
+		if (SCTP_TSN_GT(at->rec.data.fsn, chk->rec.data.fsn)) {
 			/*
 			 * This one in queue is bigger than the new one,
 			 * insert the new one before at.
@@ -995,7 +997,7 @@ place_chunk:
 			inserted = 1;
 			TAILQ_INSERT_BEFORE(at, chk, sctp_next);
 			break;
-		} else if (at->rec.data.fsn_num == chk->rec.data.fsn_num) {
+		} else if (at->rec.data.fsn == chk->rec.data.fsn) {
 			/*
 			 * They sent a duplicate fsn number. This really
 			 * should not happen since the FSN is a TSN and it
@@ -1011,7 +1013,7 @@ place_chunk:
 		/* Its at the end */
 		asoc->size_on_reasm_queue += chk->send_size;
 		sctp_ucount_incr(asoc->cnt_on_reasm_queue);
-		control->top_fsn = chk->rec.data.fsn_num;
+		control->top_fsn = chk->rec.data.fsn;
 		TAILQ_INSERT_TAIL(&control->reasm, chk, sctp_next);
 	}
 }
@@ -1052,7 +1054,7 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc,
 	}
 	while (control) {
 		SCTPDBG(SCTP_DEBUG_XXX, "Looking at control: %p e(%d) ssn: %u top_fsn: %u inc_fsn: %u -uo\n",
-		    control, control->end_added, control->sinfo_ssn, control->top_fsn, control->fsn_included);
+		    control, control->end_added, control->mid, control->top_fsn, control->fsn_included);
 		nctl = TAILQ_NEXT(control, next_instrm);
 		if (control->end_added) {
 			/* We just put the last bit on */
@@ -1097,7 +1099,7 @@ done_un:
 	if (control == NULL) {
 		return (ret);
 	}
-	if (strm->last_sequence_delivered == control->sinfo_ssn) {
+	if (SCTP_MID_EQ(asoc->idata_supported, strm->last_mid_delivered, control->mid)) {
 		/*
 		 * Ok the guy at the top was being partially delivered
 		 * completed, so we remove it. Note the pd_api flag was
@@ -1107,9 +1109,9 @@ done_un:
 		nctl = TAILQ_NEXT(control, next_instrm);
 		SCTPDBG(SCTP_DEBUG_XXX,
 		    "Looking at control: %p e(%d) ssn: %u top_fsn: %u inc_fsn: %u (lastdel: %u)- o\n",
-		    control, control->end_added, control->sinfo_ssn,
+		    control, control->end_added, control->mid,
 		    control->top_fsn, control->fsn_included,
-		    strm->last_sequence_delivered);
+		    strm->last_mid_delivered);
 		if (control->end_added) {
 			if (control->on_strm_q) {
 #ifdef INVARIANTS
@@ -1136,21 +1138,19 @@ done_un:
 		}
 	}
 	if (strm->pd_api_started) {
-		/*
-		 * Can't add more must have gotten an un-ordered above being
-		 * partially delivered.
-		 */
+		/* Can't add more must have gotten an un-ordered above being
+		 * partially delivered. */
 		return (0);
 	}
 deliver_more:
-	next_to_del = strm->last_sequence_delivered + 1;
+	next_to_del = strm->last_mid_delivered + 1;
 	if (control) {
 		SCTPDBG(SCTP_DEBUG_XXX,
 		    "Looking at control: %p e(%d) ssn: %u top_fsn: %u inc_fsn: %u (nxtdel: %u)- o\n",
-		    control, control->end_added, control->sinfo_ssn, control->top_fsn, control->fsn_included,
+		    control, control->end_added, control->mid, control->top_fsn, control->fsn_included,
 		    next_to_del);
 		nctl = TAILQ_NEXT(control, next_instrm);
-		if ((control->sinfo_ssn == next_to_del) &&
+		if (SCTP_MID_EQ(asoc->idata_supported, control->mid, next_to_del) &&
 		    (control->first_frag_seen)) {
 			int done;
 
@@ -1171,21 +1171,15 @@ deliver_more:
 				ret++;
 			}
 			if (((control->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) {
-				/*
-				 * A singleton now slipping through - mark
-				 * it non-revokable too
-				 */
+				/* A singleton now slipping through - mark
+				 * it non-revokable too */
 				sctp_mark_non_revokable(asoc, control->sinfo_tsn);
 			} else if (control->end_added == 0) {
-				/*
-				 * Check if we can defer adding until its
-				 * all there
-				 */
+				/* Check if we can defer adding until its
+				 * all there */
 				if ((control->length < pd_point) || (strm->pd_api_started)) {
-					/*
-					 * Don't need it or cannot add more
-					 * (one being delivered that way)
-					 */
+					/* Don't need it or cannot add more
+					 * (one being delivered that way) */
 					goto out;
 				}
 			}
@@ -1196,7 +1190,7 @@ deliver_more:
 				    &stcb->sctp_socket->so_rcv, control->end_added,
 				    inp_read_lock_held, SCTP_SO_NOT_LOCKED);
 			}
-			strm->last_sequence_delivered = next_to_del;
+			strm->last_mid_delivered = next_to_del;
 			if (done) {
 				control = nctl;
 				goto deliver_more;
@@ -1237,10 +1231,10 @@ sctp_add_chk_to_control(struct sctp_queued_to_read *control,
 	} else {
 		sctp_add_to_tail_pointer(control, chk->data);
 	}
-	control->fsn_included = chk->rec.data.fsn_num;
+	control->fsn_included = chk->rec.data.fsn;
 	asoc->size_on_reasm_queue -= chk->send_size;
 	sctp_ucount_decr(asoc->cnt_on_reasm_queue);
-	sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
+	sctp_mark_non_revokable(asoc, chk->rec.data.tsn);
 	chk->data = NULL;
 	if (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) {
 		control->first_frag_seen = 1;
@@ -1341,7 +1335,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		/* Its the very first one. */
 		SCTPDBG(SCTP_DEBUG_XXX,
 		    "chunk is a first fsn: %u becomes fsn_included\n",
-		    chk->rec.data.fsn_num);
+		    chk->rec.data.fsn);
 		if (control->first_frag_seen) {
 			/*
 			 * Error on senders part, they either sent us two
@@ -1355,9 +1349,9 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 			return;
 		}
 		control->first_frag_seen = 1;
-		control->fsn_included = chk->rec.data.fsn_num;
+		control->fsn_included = chk->rec.data.fsn;
 		control->data = chk->data;
-		sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
+		sctp_mark_non_revokable(asoc, chk->rec.data.tsn);
 		chk->data = NULL;
 		sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		sctp_setup_tail_pointer(control);
@@ -1367,16 +1361,16 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 
 		if (control->last_frag_seen == 0) {
 			/* Still willing to raise highest FSN seen */
-			if (SCTP_TSN_GT(chk->rec.data.fsn_num, control->top_fsn)) {
+			if (SCTP_TSN_GT(chk->rec.data.fsn, control->top_fsn)) {
 				SCTPDBG(SCTP_DEBUG_XXX,
 				    "We have a new top_fsn: %u\n",
-				    chk->rec.data.fsn_num);
-				control->top_fsn = chk->rec.data.fsn_num;
+				    chk->rec.data.fsn);
+				control->top_fsn = chk->rec.data.fsn;
 			}
 			if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
 				SCTPDBG(SCTP_DEBUG_XXX,
 				    "The last fsn is now in place fsn: %u\n",
-				    chk->rec.data.fsn_num);
+				    chk->rec.data.fsn);
 				control->last_frag_seen = 1;
 			}
 			if (asoc->idata_supported || control->first_frag_seen) {
@@ -1386,11 +1380,9 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				 * DATA we have to receive the first before
 				 * we know the first FSN (which is the TSN).
 				 */
-				if (SCTP_TSN_GE(control->fsn_included, chk->rec.data.fsn_num)) {
-					/*
-					 * We have already delivered up to
-					 * this so its a dup
-					 */
+				if (SCTP_TSN_GE(control->fsn_included, chk->rec.data.fsn)) {
+					/* We have already delivered up to
+					 * this so its a dup */
 					sctp_abort_in_reasm(stcb, control, chk,
 					    abort_flag,
 					    SCTP_FROM_SCTP_INDATA + SCTP_LOC_9);
@@ -1402,7 +1394,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				/* Second last? huh? */
 				SCTPDBG(SCTP_DEBUG_XXX,
 				    "Duplicate last fsn: %u (top: %u) -- abort\n",
-				    chk->rec.data.fsn_num, control->top_fsn);
+				    chk->rec.data.fsn, control->top_fsn);
 				sctp_abort_in_reasm(stcb, control,
 				    chk, abort_flag,
 				    SCTP_FROM_SCTP_INDATA + SCTP_LOC_10);
@@ -1416,28 +1408,24 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				 * we know the first FSN (which is the TSN).
 				 */
 
-				if (SCTP_TSN_GE(control->fsn_included, chk->rec.data.fsn_num)) {
-					/*
-					 * We have already delivered up to
-					 * this so its a dup
-					 */
+				if (SCTP_TSN_GE(control->fsn_included, chk->rec.data.fsn)) {
+					/* We have already delivered up to
+					 * this so its a dup */
 					SCTPDBG(SCTP_DEBUG_XXX,
 					    "New fsn: %u is already seen in included_fsn: %u -- abort\n",
-					    chk->rec.data.fsn_num, control->fsn_included);
+					    chk->rec.data.fsn, control->fsn_included);
 					sctp_abort_in_reasm(stcb, control, chk,
 					    abort_flag,
 					    SCTP_FROM_SCTP_INDATA + SCTP_LOC_11);
 					return;
 				}
 			}
-			/*
-			 * validate not beyond top FSN if we have seen last
-			 * one
-			 */
-			if (SCTP_TSN_GT(chk->rec.data.fsn_num, control->top_fsn)) {
+			/* validate not beyond top FSN if we have seen last
+			 * one */
+			if (SCTP_TSN_GT(chk->rec.data.fsn, control->top_fsn)) {
 				SCTPDBG(SCTP_DEBUG_XXX,
 				    "New fsn: %u is beyond or at top_fsn: %u -- abort\n",
-				    chk->rec.data.fsn_num,
+				    chk->rec.data.fsn,
 				    control->top_fsn);
 				sctp_abort_in_reasm(stcb, control, chk,
 				    abort_flag,
@@ -1451,26 +1439,24 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		 */
 		SCTPDBG(SCTP_DEBUG_XXX,
 		    "chunk is a not first fsn: %u needs to be inserted\n",
-		    chk->rec.data.fsn_num);
+		    chk->rec.data.fsn);
 		TAILQ_FOREACH(at, &control->reasm, sctp_next) {
-			if (SCTP_TSN_GT(at->rec.data.fsn_num, chk->rec.data.fsn_num)) {
+			if (SCTP_TSN_GT(at->rec.data.fsn, chk->rec.data.fsn)) {
 				/*
 				 * This one in queue is bigger than the new
 				 * one, insert the new one before at.
 				 */
 				SCTPDBG(SCTP_DEBUG_XXX,
 				    "Insert it before fsn: %u\n",
-				    at->rec.data.fsn_num);
+				    at->rec.data.fsn);
 				asoc->size_on_reasm_queue += chk->send_size;
 				sctp_ucount_incr(asoc->cnt_on_reasm_queue);
 				TAILQ_INSERT_BEFORE(at, chk, sctp_next);
 				inserted = 1;
 				break;
-			} else if (at->rec.data.fsn_num == chk->rec.data.fsn_num) {
-				/*
-				 * Gak, He sent me a duplicate str seq
-				 * number
-				 */
+			} else if (at->rec.data.fsn == chk->rec.data.fsn) {
+				/* Gak, He sent me a duplicate str seq
+				 * number */
 				/*
 				 * foo bar, I guess I will just free this
 				 * new guy, should we abort too? FIX ME
@@ -1481,7 +1467,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				 */
 				SCTPDBG(SCTP_DEBUG_XXX,
 				    "Duplicate to fsn: %u -- abort\n",
-				    at->rec.data.fsn_num);
+				    at->rec.data.fsn);
 				sctp_abort_in_reasm(stcb, control,
 				    chk, abort_flag,
 				    SCTP_FROM_SCTP_INDATA + SCTP_LOC_13);
@@ -1491,7 +1477,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		if (inserted == 0) {
 			/* Goes on the end */
 			SCTPDBG(SCTP_DEBUG_XXX, "Inserting at tail of list fsn: %u\n",
-			    chk->rec.data.fsn_num);
+			    chk->rec.data.fsn);
 			asoc->size_on_reasm_queue += chk->send_size;
 			sctp_ucount_incr(asoc->cnt_on_reasm_queue);
 			TAILQ_INSERT_TAIL(&control->reasm, chk, sctp_next);
@@ -1509,12 +1495,12 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 	if (control->first_frag_seen) {
 		next_fsn = control->fsn_included + 1;
 		TAILQ_FOREACH_SAFE(at, &control->reasm, sctp_next, nat) {
-			if (at->rec.data.fsn_num == next_fsn) {
+			if (at->rec.data.fsn == next_fsn) {
 				/* We can add this one now to the control */
 				SCTPDBG(SCTP_DEBUG_XXX,
 				    "Adding more to control: %p at: %p fsn: %u next_fsn: %u included: %u\n",
 				    control, at,
-				    at->rec.data.fsn_num,
+				    at->rec.data.fsn,
 				    next_fsn, control->fsn_included);
 				TAILQ_REMOVE(&control->reasm, at, sctp_next);
 				sctp_add_chk_to_control(control, strm, stcb, asoc, at, SCTP_READ_LOCK_NOT_HELD);
@@ -1548,25 +1534,25 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
 }
 
 static struct sctp_queued_to_read *
-sctp_find_reasm_entry(struct sctp_stream_in *strm, uint32_t msg_id, int ordered, int old)
+sctp_find_reasm_entry(struct sctp_stream_in *strm, uint32_t mid, int ordered, int idata_supported)
 {
 	struct sctp_queued_to_read *control;
 
 	if (ordered) {
 		TAILQ_FOREACH(control, &strm->inqueue, next_instrm) {
-			if (control->msg_id == msg_id) {
+			if (SCTP_MID_EQ(idata_supported, control->mid, mid)) {
 				break;
 			}
 		}
 	} else {
-		if (old) {
-			control = TAILQ_FIRST(&strm->uno_inqueue);
-			return (control);
-		}
-		TAILQ_FOREACH(control, &strm->uno_inqueue, next_instrm) {
-			if (control->msg_id == msg_id) {
-				break;
+		if (idata_supported) {
+			TAILQ_FOREACH(control, &strm->uno_inqueue, next_instrm) {
+				if (SCTP_MID_EQ(idata_supported, control->mid, mid)) {
+					break;
+				}
 			}
+		} else {
+			control = TAILQ_FIRST(&strm->uno_inqueue);
 		}
 	}
 	return (control);
@@ -1583,22 +1569,21 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 	struct sctp_data_chunk *ch;
 	struct sctp_idata_chunk *nch, chunk_buf;
 	struct sctp_tmit_chunk *chk;
-	uint32_t tsn, fsn, gap, msg_id;
+	uint32_t tsn, fsn, gap, mid;
 	struct mbuf *dmbuf;
 	int the_len;
 	int need_reasm_check = 0;
-	uint16_t strmno;
+	uint16_t sid;
 	struct mbuf *op_err;
 	char msg[SCTP_DIAG_INFO_LEN];
 	struct sctp_queued_to_read *control = NULL;
-	uint32_t protocol_id;
+	uint32_t ppid;
 	uint8_t chunk_flags;
 	struct sctp_stream_reset_list *liste;
 	struct sctp_stream_in *strm;
 	int ordered;
 	size_t clen;
 	int created_control = 0;
-	uint8_t old_data;
 
 	chk = NULL;
 	if (chtype == SCTP_IDATA) {
@@ -1607,23 +1592,21 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		ch = (struct sctp_data_chunk *)nch;
 		clen = sizeof(struct sctp_idata_chunk);
 		tsn = ntohl(ch->dp.tsn);
-		msg_id = ntohl(nch->dp.msg_id);
-		protocol_id = nch->dp.ppid_fsn.protocol_id;
+		mid = ntohl(nch->dp.mid);
+		ppid = nch->dp.ppid_fsn.ppid;
 		if (ch->ch.chunk_flags & SCTP_DATA_FIRST_FRAG)
 			fsn = 0;
 		else
 			fsn = ntohl(nch->dp.ppid_fsn.fsn);
-		old_data = 0;
 	} else {
 		ch = (struct sctp_data_chunk *)sctp_m_getptr(*m, offset,
 		    sizeof(struct sctp_data_chunk), (uint8_t *) & chunk_buf);
 		tsn = ntohl(ch->dp.tsn);
-		protocol_id = ch->dp.protocol_id;
+		ppid = ch->dp.ppid;
 		clen = sizeof(struct sctp_data_chunk);
 		fsn = tsn;
-		msg_id = (uint32_t) (ntohs(ch->dp.stream_sequence));
+		mid = (uint32_t) (ntohs(ch->dp.ssn));
 		nch = NULL;
-		old_data = 1;
 	}
 	chunk_flags = ch->ch.chunk_flags;
 	if ((size_t)chk_length == clen) {
@@ -1709,9 +1692,9 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 	 */
 
 	/* Is the stream valid? */
-	strmno = ntohs(ch->dp.stream_id);
+	sid = ntohs(ch->dp.sid);
 
-	if (strmno >= asoc->streamincnt) {
+	if (sid >= asoc->streamincnt) {
 		struct sctp_error_invalid_stream *cause;
 
 		op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_error_invalid_stream),
@@ -1728,7 +1711,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 			SCTP_BUF_LEN(op_err) = sizeof(struct sctp_error_invalid_stream);
 			cause->cause.code = htons(SCTP_CAUSE_INVALID_STREAM);
 			cause->cause.length = htons(sizeof(struct sctp_error_invalid_stream));
-			cause->stream_id = ch->dp.stream_id;
+			cause->stream_id = ch->dp.sid;
 			cause->reserved = htons(0);
 			sctp_queue_op_err(stcb, op_err);
 		}
@@ -1744,7 +1727,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		}
 		return (0);
 	}
-	strm = &asoc->strmin[strmno];
+	strm = &asoc->strmin[sid];
 	/*
 	 * If its a fragmented message, lets see if we can find the control
 	 * on the reassembly queues.
@@ -1758,18 +1741,18 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		 * wrap around. Ignore is for now.
 		 */
 		snprintf(msg, sizeof(msg), "FSN zero for MID=%8.8x, but flags=%2.2x",
-		    msg_id, chunk_flags);
+		    mid, chunk_flags);
 		goto err_out;
 	}
-	control = sctp_find_reasm_entry(strm, msg_id, ordered, old_data);
+	control = sctp_find_reasm_entry(strm, mid, ordered, asoc->idata_supported);
 	SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags:0x%x look for control on queues %p\n",
 	    chunk_flags, control);
 	if ((chunk_flags & SCTP_DATA_NOT_FRAG) != SCTP_DATA_NOT_FRAG) {
 		/* See if we can find the re-assembly entity */
 		if (control != NULL) {
 			/* We found something, does it belong? */
-			if (ordered && (msg_id != control->sinfo_ssn)) {
-				snprintf(msg, sizeof(msg), "Reassembly problem (MID=%8.8x)", msg_id);
+			if (ordered && (mid != control->mid)) {
+				snprintf(msg, sizeof(msg), "Reassembly problem (MID=%8.8x)", mid);
 		err_out:
 				op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_15;
@@ -1778,19 +1761,15 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				return (0);
 			}
 			if (ordered && ((control->sinfo_flags >> 8) & SCTP_DATA_UNORDERED)) {
-				/*
-				 * We can't have a switched order with an
-				 * unordered chunk
-				 */
+				/* We can't have a switched order with an
+				 * unordered chunk */
 				snprintf(msg, sizeof(msg), "All fragments of a user message must be ordered or unordered (TSN=%8.8x)",
 				    tsn);
 				goto err_out;
 			}
 			if (!ordered && (((control->sinfo_flags >> 8) & SCTP_DATA_UNORDERED) == 0)) {
-				/*
-				 * We can't have a switched unordered with a
-				 * ordered chunk
-				 */
+				/* We can't have a switched unordered with a
+				 * ordered chunk */
 				snprintf(msg, sizeof(msg), "All fragments of a user message must be ordered or unordered (TSN=%8.8x)",
 				    tsn);
 				goto err_out;
@@ -1803,10 +1782,10 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		 * ordered) or in the same Stream for unordered.
 		 */
 		if (control != NULL) {
-			if (ordered || (old_data == 0)) {
-				SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags: 0x%x dup detected on msg_id: %u\n",
-				    chunk_flags, msg_id);
-				snprintf(msg, sizeof(msg), "Duplicate MID=%8.8x detected.", msg_id);
+			if (ordered || asoc->idata_supported) {
+				SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags: 0x%x dup detected on MID: %u\n",
+				    chunk_flags, mid);
+				snprintf(msg, sizeof(msg), "Duplicate MID=%8.8x detected.", mid);
 				goto err_out;
 			} else {
 				if ((tsn == control->fsn_included + 1) &&
@@ -1883,8 +1862,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		asoc->tsn_in_wrapped = 1;
 	}
 	asoc->in_tsnlog[asoc->tsn_in_at].tsn = tsn;
-	asoc->in_tsnlog[asoc->tsn_in_at].strm = strmno;
-	asoc->in_tsnlog[asoc->tsn_in_at].seq = msg_id;
+	asoc->in_tsnlog[asoc->tsn_in_at].strm = sid;
+	asoc->in_tsnlog[asoc->tsn_in_at].seq = mid;
 	asoc->in_tsnlog[asoc->tsn_in_at].sz = chk_length;
 	asoc->in_tsnlog[asoc->tsn_in_at].flgs = chunk_flags;
 	asoc->in_tsnlog[asoc->tsn_in_at].stcb = (void *)stcb;
@@ -1902,14 +1881,24 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 	if ((chunk_flags & SCTP_DATA_FIRST_FRAG) &&
 	    (TAILQ_EMPTY(&asoc->resetHead)) &&
 	    (chunk_flags & SCTP_DATA_UNORDERED) == 0 &&
-	    SCTP_MSGID_GE(old_data, asoc->strmin[strmno].last_sequence_delivered, msg_id)) {
+	    SCTP_MID_GE(asoc->idata_supported, asoc->strmin[sid].last_mid_delivered, mid)) {
 		/* The incoming sseq is behind where we last delivered? */
 		SCTPDBG(SCTP_DEBUG_INDATA1, "EVIL/Broken-Dup S-SEQ: %u delivered: %u from peer, Abort!\n",
-		    msg_id, asoc->strmin[strmno].last_sequence_delivered);
+		    mid, asoc->strmin[sid].last_mid_delivered);
 
-		snprintf(msg, sizeof(msg), "Delivered SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
-		    asoc->strmin[strmno].last_sequence_delivered,
-		    tsn, strmno, msg_id);
+		if (asoc->idata_supported) {
+			snprintf(msg, sizeof(msg), "Delivered MID=%8.8x, got TSN=%8.8x, SID=%4.4x, MID=%8.8x",
+			    asoc->strmin[sid].last_mid_delivered,
+			    tsn,
+			    sid,
+			    mid);
+		} else {
+			snprintf(msg, sizeof(msg), "Delivered SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+			    (uint16_t) asoc->strmin[sid].last_mid_delivered,
+			    tsn,
+			    sid,
+			    (uint16_t) mid);
+		}
 		op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 		stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_16;
 		sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
@@ -1982,10 +1971,10 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 	if (control == NULL) {
 		sctp_alloc_a_readq(stcb, control);
 		sctp_build_readq_entry_mac(control, stcb, asoc->context, net, tsn,
-		    protocol_id,
-		    strmno, msg_id,
+		    ppid,
+		    sid,
 		    chunk_flags,
-		    NULL, fsn, msg_id);
+		    NULL, fsn, mid);
 		if (control == NULL) {
 			SCTP_STAT_INCR(sctps_nomem);
 			return (0);
@@ -1998,13 +1987,13 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		}
 		created_control = 1;
 	}
-	SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags: 0x%x ordered: %d msgid: %u control: %p\n",
-	    chunk_flags, ordered, msg_id, control);
+	SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags: 0x%x ordered: %d MID: %u control: %p\n",
+	    chunk_flags, ordered, mid, control);
 	if ((chunk_flags & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG &&
 	    TAILQ_EMPTY(&asoc->resetHead) &&
 	    ((ordered == 0) ||
-	    ((uint16_t) (asoc->strmin[strmno].last_sequence_delivered + 1) == msg_id &&
-	    TAILQ_EMPTY(&asoc->strmin[strmno].inqueue)))) {
+	    (SCTP_MID_EQ(asoc->idata_supported, asoc->strmin[sid].last_mid_delivered + 1, mid) &&
+	    TAILQ_EMPTY(&asoc->strmin[sid].inqueue)))) {
 		/* Candidate for express delivery */
 		/*
 		 * Its not fragmented, No PD-API is up, Nothing in the
@@ -2017,8 +2006,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		if (SCTP_TSN_GT(tsn, asoc->highest_tsn_inside_nr_map)) {
 			asoc->highest_tsn_inside_nr_map = tsn;
 		}
-		SCTPDBG(SCTP_DEBUG_XXX, "Injecting control: %p to be read (msg_id: %u)\n",
-		    control, msg_id);
+		SCTPDBG(SCTP_DEBUG_XXX, "Injecting control: %p to be read (MID: %u)\n",
+		    control, mid);
 
 		sctp_add_to_readq(stcb->sctp_ep, stcb,
 		    control, &stcb->sctp_socket->so_rcv,
@@ -2026,11 +2015,11 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 
 		if ((chunk_flags & SCTP_DATA_UNORDERED) == 0) {
 			/* for ordered, bump what we delivered */
-			strm->last_sequence_delivered++;
+			strm->last_mid_delivered++;
 		}
 		SCTP_STAT_INCR(sctps_recvexpress);
 		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_STR_LOGGING_ENABLE) {
-			sctp_log_strm_del_alt(stcb, tsn, msg_id, strmno,
+			sctp_log_strm_del_alt(stcb, tsn, mid, sid,
 			    SCTP_STR_LOG_FROM_EXPRS_DEL);
 		}
 		control = NULL;
@@ -2048,21 +2037,21 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 			}
 			return (0);
 		}
-		chk->rec.data.TSN_seq = tsn;
+		chk->rec.data.tsn = tsn;
 		chk->no_fr_allowed = 0;
-		chk->rec.data.fsn_num = fsn;
-		chk->rec.data.stream_seq = msg_id;
-		chk->rec.data.stream_number = strmno;
-		chk->rec.data.payloadtype = protocol_id;
+		chk->rec.data.fsn = fsn;
+		chk->rec.data.mid = mid;
+		chk->rec.data.sid = sid;
+		chk->rec.data.ppid = ppid;
 		chk->rec.data.context = stcb->asoc.context;
 		chk->rec.data.doing_fast_retransmit = 0;
 		chk->rec.data.rcv_flags = chunk_flags;
 		chk->asoc = asoc;
 		chk->send_size = the_len;
 		chk->whoTo = net;
-		SCTPDBG(SCTP_DEBUG_XXX, "Building ck: %p for control: %p to be read (msg_id: %u)\n",
+		SCTPDBG(SCTP_DEBUG_XXX, "Building ck: %p for control: %p to be read (MID: %u)\n",
 		    chk,
-		    control, msg_id);
+		    control, mid);
 		atomic_add_int(&net->ref_count, 1);
 		chk->data = dmbuf;
 	}
@@ -2086,7 +2075,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		 * if it is not being reset.. that way we would not create a
 		 * HOLB when amongst streams being reset and those not being
 		 * reset.
-		 * 
+		 *
 		 */
 		if (((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) &&
 		    SCTP_TSN_GT(tsn, liste->tsn)) {
@@ -2125,8 +2114,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		}
 		if (chunk_flags & SCTP_DATA_UNORDERED) {
 			/* queue directly into socket buffer */
-			SCTPDBG(SCTP_DEBUG_XXX, "Unordered data to be read control: %p msg_id: %u\n",
-			    control, msg_id);
+			SCTPDBG(SCTP_DEBUG_XXX, "Unordered data to be read control: %p MID: %u\n",
+			    control, mid);
 			sctp_mark_non_revokable(asoc, control->sinfo_tsn);
 			sctp_add_to_readq(stcb->sctp_ep, stcb,
 			    control,
@@ -2134,8 +2123,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 			    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
 
 		} else {
-			SCTPDBG(SCTP_DEBUG_XXX, "Queue control: %p for reordering msg_id: %u\n", control,
-			    msg_id);
+			SCTPDBG(SCTP_DEBUG_XXX, "Queue control: %p for reordering MID: %u\n", control,
+			    mid);
 			sctp_queue_data_to_stream(stcb, strm, asoc, control, abort_flag, &need_reasm_check);
 			if (*abort_flag) {
 				if (last_chunk) {
@@ -2149,8 +2138,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
 	/* If we reach here its a reassembly */
 	need_reasm_check = 1;
 	SCTPDBG(SCTP_DEBUG_XXX,
-	    "Queue data to stream for reasm control: %p msg_id: %u\n",
-	    control, msg_id);
+	    "Queue data to stream for reasm control: %p MID: %u\n",
+	    control, mid);
 	sctp_queue_data_for_reasm(stcb, asoc, strm, control, chk, created_control, abort_flag, tsn);
 	if (*abort_flag) {
 		/*
@@ -2179,7 +2168,7 @@ finish_express_del:
 	SCTP_STAT_INCR(sctps_recvdata);
 	/* Set it present please */
 	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_STR_LOGGING_ENABLE) {
-		sctp_log_strm_del_alt(stcb, tsn, msg_id, strmno, SCTP_STR_LOG_FROM_MARK_TSN);
+		sctp_log_strm_del_alt(stcb, tsn, mid, sid, SCTP_STR_LOG_FROM_MARK_TSN);
 	}
 	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
 		sctp_log_map(asoc->mapping_array_base_tsn, asoc->cumulative_tsn,
@@ -2284,10 +2273,10 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
 	/*
 	 * Now we also need to check the mapping array in a couple of ways.
 	 * 1) Did we move the cum-ack point?
-	 * 
-	 * When you first glance at this you might think that all entries that
-	 * make up the position of the cum-ack would be in the nr-mapping
-	 * array only.. i.e. things up to the cum-ack are always
+	 *
+	 * When you first glance at this you might think that all entries
+	 * that make up the position of the cum-ack would be in the
+	 * nr-mapping array only.. i.e. things up to the cum-ack are always
 	 * deliverable. Thats true with one exception, when its a fragmented
 	 * message we may not deliver the data until some threshold (or all
 	 * of it) is in place. So we must OR the nr_mapping_array and
@@ -2346,10 +2335,8 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
 		/* The complete array was completed by a single FR */
 		/* highest becomes the cum-ack */
 		int clr;
-
 #ifdef INVARIANTS
 		unsigned int i;
-
 #endif
 
 		/* clear the array */
@@ -2497,8 +2484,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap)
 		    (stcb->asoc.numduptsns) ||	/* we have dup's */
 		    (is_a_gap) ||	/* is still a gap */
 		    (stcb->asoc.delayed_ack == 0) ||	/* Delayed sack disabled */
-		    (stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq)	/* hit limit of pkts */
-		    ) {
+		    (stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq) /* hit limit of pkts */ ) {
 
 			if ((stcb->asoc.sctp_cmt_on_off > 0) &&
 			    (SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) &&
@@ -2510,9 +2496,9 @@ sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap)
 				/*
 				 * CMT DAC algorithm: With CMT, delay acks
 				 * even in the face of
-				 * 
-				 * reordering. Therefore, if acks that do not
-				 * have to be sent because of the above
+				 *
+				 * reordering. Therefore, if acks that do
+				 * not have to be sent because of the above
 				 * reasons, will be delayed. That is, acks
 				 * that would have been sent due to gap
 				 * reports will be delayed with DAC. Start
@@ -2719,7 +2705,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
 					 * Now, what do we do with KNOWN
 					 * chunks that are NOT in the right
 					 * place?
-					 * 
+					 *
 					 * For now, I do nothing but ignore
 					 * them. We may later want to add
 					 * sysctl stuff to switch out and do
@@ -2761,8 +2747,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
 					/* discard the rest of this packet */
 					stop_proc = 1;
 				}	/* else skip this bad chunk and
-					 * continue... */
-				break;
+				  * continue... */ break;
 			}	/* switch of chunk type */
 		}
 		*offset += SCTP_SIZE32(chk_length);
@@ -2845,16 +2830,16 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
 			if ((tp1->sent < SCTP_DATAGRAM_RESEND) &&
 			    (tp1->whoTo->find_pseudo_cumack == 1) &&
 			    (tp1->snd_count == 1)) {
-				tp1->whoTo->pseudo_cumack = tp1->rec.data.TSN_seq;
+				tp1->whoTo->pseudo_cumack = tp1->rec.data.tsn;
 				tp1->whoTo->find_pseudo_cumack = 0;
 			}
 			if ((tp1->sent < SCTP_DATAGRAM_RESEND) &&
 			    (tp1->whoTo->find_rtx_pseudo_cumack == 1) &&
 			    (tp1->snd_count > 1)) {
-				tp1->whoTo->rtx_pseudo_cumack = tp1->rec.data.TSN_seq;
+				tp1->whoTo->rtx_pseudo_cumack = tp1->rec.data.tsn;
 				tp1->whoTo->find_rtx_pseudo_cumack = 0;
 			}
-			if (tp1->rec.data.TSN_seq == theTSN) {
+			if (tp1->rec.data.tsn == theTSN) {
 				if (tp1->sent != SCTP_DATAGRAM_UNSENT) {
 					/*-
 					 * must be held until
@@ -2868,9 +2853,9 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
 						 * via previous Gap Ack Blocks...
 						 * i.e. ACKED or RESEND.
 						 */
-						if (SCTP_TSN_GT(tp1->rec.data.TSN_seq,
+						if (SCTP_TSN_GT(tp1->rec.data.tsn,
 						    *biggest_newly_acked_tsn)) {
-							*biggest_newly_acked_tsn = tp1->rec.data.TSN_seq;
+							*biggest_newly_acked_tsn = tp1->rec.data.tsn;
 						}
 						/*-
 						 * CMT: SFR algo (and HTNA) - set
@@ -2882,10 +2867,10 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
 						if (tp1->rec.data.chunk_was_revoked == 0)
 							tp1->whoTo->saw_newack = 1;
 
-						if (SCTP_TSN_GT(tp1->rec.data.TSN_seq,
+						if (SCTP_TSN_GT(tp1->rec.data.tsn,
 						    tp1->whoTo->this_sack_highest_newack)) {
 							tp1->whoTo->this_sack_highest_newack =
-							    tp1->rec.data.TSN_seq;
+							    tp1->rec.data.tsn;
 						}
 						/*-
 						 * CMT DAC algo: also update
@@ -2895,12 +2880,12 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
 							if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
 								sctp_log_sack(*this_sack_lowest_newack,
 								    last_tsn,
-								    tp1->rec.data.TSN_seq,
+								    tp1->rec.data.tsn,
 								    0,
 								    0,
 								    SCTP_LOG_TSN_ACKED);
 							}
-							*this_sack_lowest_newack = tp1->rec.data.TSN_seq;
+							*this_sack_lowest_newack = tp1->rec.data.tsn;
 						}
 						/*-
 						 * CMT: CUCv2 algorithm. If (rtx-)pseudo-cumack for corresp
@@ -2910,16 +2895,16 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
 						 * Separate pseudo_cumack trackers for first transmissions and
 						 * retransmissions.
 						 */
-						if (tp1->rec.data.TSN_seq == tp1->whoTo->pseudo_cumack) {
+						if (tp1->rec.data.tsn == tp1->whoTo->pseudo_cumack) {
 							if (tp1->rec.data.chunk_was_revoked == 0) {
 								tp1->whoTo->new_pseudo_cumack = 1;
 							}
 							tp1->whoTo->find_pseudo_cumack = 1;
 						}
 						if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
-							sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.TSN_seq, SCTP_CWND_LOG_FROM_SACK);
+							sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.tsn, SCTP_CWND_LOG_FROM_SACK);
 						}
-						if (tp1->rec.data.TSN_seq == tp1->whoTo->rtx_pseudo_cumack) {
+						if (tp1->rec.data.tsn == tp1->whoTo->rtx_pseudo_cumack) {
 							if (tp1->rec.data.chunk_was_revoked == 0) {
 								tp1->whoTo->new_pseudo_cumack = 1;
 							}
@@ -2928,7 +2913,7 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
 						if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
 							sctp_log_sack(*biggest_newly_acked_tsn,
 							    last_tsn,
-							    tp1->rec.data.TSN_seq,
+							    tp1->rec.data.tsn,
 							    frag_strt,
 							    frag_end,
 							    SCTP_LOG_TSN_ACKED);
@@ -2938,7 +2923,7 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
 							    tp1->whoTo->flight_size,
 							    tp1->book_size,
 							    (uint32_t) (uintptr_t) tp1->whoTo,
-							    tp1->rec.data.TSN_seq);
+							    tp1->rec.data.tsn);
 						}
 						sctp_flight_size_decrease(tp1);
 						if (stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) {
@@ -2976,10 +2961,10 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
 						}
 					}
 					if (tp1->sent <= SCTP_DATAGRAM_RESEND) {
-						if (SCTP_TSN_GT(tp1->rec.data.TSN_seq,
+						if (SCTP_TSN_GT(tp1->rec.data.tsn,
 						    stcb->asoc.this_sack_highest_gap)) {
 							stcb->asoc.this_sack_highest_gap =
-							    tp1->rec.data.TSN_seq;
+							    tp1->rec.data.tsn;
 						}
 						if (tp1->sent == SCTP_DATAGRAM_RESEND) {
 							sctp_ucount_decr(stcb->asoc.sent_queue_retran_cnt);
@@ -3005,24 +2990,22 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
 					/* NR Sack code here */
 					if (nr_sacking &&
 					    (tp1->sent != SCTP_DATAGRAM_NR_ACKED)) {
-						if (stcb->asoc.strmout[tp1->rec.data.stream_number].chunks_on_queues > 0) {
-							stcb->asoc.strmout[tp1->rec.data.stream_number].chunks_on_queues--;
+						if (stcb->asoc.strmout[tp1->rec.data.sid].chunks_on_queues > 0) {
+							stcb->asoc.strmout[tp1->rec.data.sid].chunks_on_queues--;
 #ifdef INVARIANTS
 						} else {
-							panic("No chunks on the queues for sid %u.", tp1->rec.data.stream_number);
+							panic("No chunks on the queues for sid %u.", tp1->rec.data.sid);
 #endif
 						}
-						if ((stcb->asoc.strmout[tp1->rec.data.stream_number].chunks_on_queues == 0) &&
-						    (stcb->asoc.strmout[tp1->rec.data.stream_number].state == SCTP_STREAM_RESET_PENDING) &&
-						    TAILQ_EMPTY(&stcb->asoc.strmout[tp1->rec.data.stream_number].outqueue)) {
+						if ((stcb->asoc.strmout[tp1->rec.data.sid].chunks_on_queues == 0) &&
+						    (stcb->asoc.strmout[tp1->rec.data.sid].state == SCTP_STREAM_RESET_PENDING) &&
+						    TAILQ_EMPTY(&stcb->asoc.strmout[tp1->rec.data.sid].outqueue)) {
 							stcb->asoc.trigger_reset = 1;
 						}
 						tp1->sent = SCTP_DATAGRAM_NR_ACKED;
 						if (tp1->data) {
-							/*
-							 * sa_ignore
-							 * NO_NULL_CHK
-							 */
+							/* sa_ignore
+							 * NO_NULL_CHK */
 							sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);
 							sctp_m_freem(tp1->data);
 							tp1->data = NULL;
@@ -3031,8 +3014,7 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
 					}
 				}
 				break;
-			}	/* if (tp1->TSN_seq == theTSN) */
-			if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, theTSN)) {
+			} /* if (tp1->tsn == theTSN) */ if (SCTP_TSN_GT(tp1->rec.data.tsn, theTSN)) {
 				break;
 			}
 			tp1 = TAILQ_NEXT(tp1, sctp_next);
@@ -3124,14 +3106,14 @@ sctp_check_for_revoked(struct sctp_tcb *stcb,
 	struct sctp_tmit_chunk *tp1;
 
 	TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
-		if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, cumack)) {
+		if (SCTP_TSN_GT(tp1->rec.data.tsn, cumack)) {
 			/*
 			 * ok this guy is either ACK or MARKED. If it is
 			 * ACKED it has been previously acked but not this
 			 * time i.e. revoked.  If it is MARKED it was ACK'ed
 			 * again.
 			 */
-			if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, biggest_tsn_acked)) {
+			if (SCTP_TSN_GT(tp1->rec.data.tsn, biggest_tsn_acked)) {
 				break;
 			}
 			if (tp1->sent == SCTP_DATAGRAM_ACKED) {
@@ -3147,7 +3129,7 @@ sctp_check_for_revoked(struct sctp_tcb *stcb,
 					    tp1->whoTo->flight_size,
 					    tp1->book_size,
 					    (uint32_t) (uintptr_t) tp1->whoTo,
-					    tp1->rec.data.TSN_seq);
+					    tp1->rec.data.tsn);
 				}
 				sctp_flight_size_increase(tp1);
 				sctp_total_flight_increase(stcb, tp1);
@@ -3159,7 +3141,7 @@ sctp_check_for_revoked(struct sctp_tcb *stcb,
 				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
 					sctp_log_sack(asoc->last_acked_seq,
 					    cumack,
-					    tp1->rec.data.TSN_seq,
+					    tp1->rec.data.tsn,
 					    0,
 					    0,
 					    SCTP_LOG_TSN_REVOKED);
@@ -3195,7 +3177,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 	if (tp1 == NULL) {
 		sending_seq = asoc->sending_seq;
 	} else {
-		sending_seq = tp1->rec.data.TSN_seq;
+		sending_seq = tp1->rec.data.tsn;
 	}
 
 	/* CMT DAC algo: finding out if SACK is a mixed SACK */
@@ -3218,11 +3200,11 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
 			if (tp1->sent < SCTP_DATAGRAM_RESEND)
 				sctp_log_fr(biggest_tsn_newly_acked,
-				    tp1->rec.data.TSN_seq,
+				    tp1->rec.data.tsn,
 				    tp1->sent,
 				    SCTP_FR_LOG_CHECK_STRIKE);
 		}
-		if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, biggest_tsn_acked) ||
+		if (SCTP_TSN_GT(tp1->rec.data.tsn, biggest_tsn_acked) ||
 		    tp1->sent == SCTP_DATAGRAM_UNSENT) {
 			/* done */
 			break;
@@ -3240,7 +3222,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				}
 			}
 		}
-		if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, asoc->this_sack_highest_gap)) {
+		if (SCTP_TSN_GT(tp1->rec.data.tsn, asoc->this_sack_highest_gap)) {
 			/* we are beyond the tsn in the sack  */
 			break;
 		}
@@ -3264,7 +3246,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 			 * FR using this SACK.
 			 */
 			continue;
-		} else if (tp1->whoTo && SCTP_TSN_GT(tp1->rec.data.TSN_seq,
+		} else if (tp1->whoTo && SCTP_TSN_GT(tp1->rec.data.tsn,
 		    tp1->whoTo->this_sack_highest_newack)) {
 			/*
 			 * CMT: New acks were receieved for data sent to
@@ -3294,7 +3276,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 			 */
 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
 				sctp_log_fr(biggest_tsn_newly_acked,
-				    tp1->rec.data.TSN_seq,
+				    tp1->rec.data.tsn,
 				    tp1->sent,
 				    SCTP_FR_LOG_STRIKE_CHUNK);
 			}
@@ -3316,10 +3298,10 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				 * received after this missing TSN.
 				 */
 				if ((tp1->sent < SCTP_DATAGRAM_RESEND) && (num_dests_sacked == 1) &&
-				    SCTP_TSN_GT(this_sack_lowest_newack, tp1->rec.data.TSN_seq)) {
+				    SCTP_TSN_GT(this_sack_lowest_newack, tp1->rec.data.tsn)) {
 					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
 						sctp_log_fr(16 + num_dests_sacked,
-						    tp1->rec.data.TSN_seq,
+						    tp1->rec.data.tsn,
 						    tp1->sent,
 						    SCTP_FR_LOG_STRIKE_CHUNK);
 					}
@@ -3357,7 +3339,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 					 */
 					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
 						sctp_log_fr(biggest_tsn_newly_acked,
-						    tp1->rec.data.TSN_seq,
+						    tp1->rec.data.tsn,
 						    tp1->sent,
 						    SCTP_FR_LOG_STRIKE_CHUNK);
 					}
@@ -3389,10 +3371,10 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 						if ((tp1->sent < SCTP_DATAGRAM_RESEND) &&
 						    (num_dests_sacked == 1) &&
 						    SCTP_TSN_GT(this_sack_lowest_newack,
-						    tp1->rec.data.TSN_seq)) {
+						    tp1->rec.data.tsn)) {
 							if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
 								sctp_log_fr(32 + num_dests_sacked,
-								    tp1->rec.data.TSN_seq,
+								    tp1->rec.data.tsn,
 								    tp1->sent,
 								    SCTP_FR_LOG_STRIKE_CHUNK);
 							}
@@ -3407,7 +3389,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 			 * JRI: TODO: remove code for HTNA algo. CMT's SFR
 			 * algo covers HTNA.
 			 */
-		} else if (SCTP_TSN_GT(tp1->rec.data.TSN_seq,
+		} else if (SCTP_TSN_GT(tp1->rec.data.tsn,
 		    biggest_tsn_newly_acked)) {
 			/*
 			 * We don't strike these: This is the  HTNA
@@ -3419,7 +3401,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 			/* Strike the TSN */
 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
 				sctp_log_fr(biggest_tsn_newly_acked,
-				    tp1->rec.data.TSN_seq,
+				    tp1->rec.data.tsn,
 				    tp1->sent,
 				    SCTP_FR_LOG_STRIKE_CHUNK);
 			}
@@ -3441,10 +3423,10 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				 * received after this missing TSN.
 				 */
 				if ((tp1->sent < SCTP_DATAGRAM_RESEND) && (num_dests_sacked == 1) &&
-				    SCTP_TSN_GT(this_sack_lowest_newack, tp1->rec.data.TSN_seq)) {
+				    SCTP_TSN_GT(this_sack_lowest_newack, tp1->rec.data.tsn)) {
 					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
 						sctp_log_fr(48 + num_dests_sacked,
-						    tp1->rec.data.TSN_seq,
+						    tp1->rec.data.tsn,
 						    tp1->sent,
 						    SCTP_FR_LOG_STRIKE_CHUNK);
 					}
@@ -3461,7 +3443,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				    (tp1->whoTo ? (tp1->whoTo->flight_size) : 0),
 				    tp1->book_size,
 				    (uint32_t) (uintptr_t) tp1->whoTo,
-				    tp1->rec.data.TSN_seq);
+				    tp1->rec.data.tsn);
 			}
 			if (tp1->whoTo) {
 				tp1->whoTo->net_ack++;
@@ -3483,10 +3465,8 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 
 			if ((stcb->asoc.prsctp_supported) &&
 			    (PR_SCTP_RTX_ENABLED(tp1->flags))) {
-				/*
-				 * Has it been retransmitted tv_sec times? -
-				 * we store the retran count there.
-				 */
+				/* Has it been retransmitted tv_sec times? -
+				 * we store the retran count there. */
 				if (tp1->snd_count > tp1->rec.data.timetodrop.tv_sec) {
 					/* Yes, so drop it */
 					if (tp1->data != NULL) {
@@ -3498,12 +3478,10 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 					continue;
 				}
 			}
-			/*
-			 * SCTP_PRINTF("OK, we are now ready to FR this
-			 * guy\n");
-			 */
+			/* SCTP_PRINTF("OK, we are now ready to FR this
+			 * guy\n"); */
 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
-				sctp_log_fr(tp1->rec.data.TSN_seq, tp1->snd_count,
+				sctp_log_fr(tp1->rec.data.tsn, tp1->snd_count,
 				    0, SCTP_FR_MARKED);
 			}
 			if (strike_flag) {
@@ -3521,18 +3499,14 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 				alt = tp1->whoTo;
 				/* sa_ignore NO_NULL_CHK */
 				if (asoc->sctp_cmt_pf > 0) {
-					/*
-					 * JRS 5/18/07 - If CMT PF is on,
+					/* JRS 5/18/07 - If CMT PF is on,
 					 * use the PF version of
-					 * find_alt_net()
-					 */
+					 * find_alt_net() */
 					alt = sctp_find_alternate_net(stcb, alt, 2);
 				} else {
-					/*
-					 * JRS 5/18/07 - If only CMT is on,
+					/* JRS 5/18/07 - If only CMT is on,
 					 * use the CMT version of
-					 * find_alt_net()
-					 */
+					 * find_alt_net() */
 					/* sa_ignore NO_NULL_CHK */
 					alt = sctp_find_alternate_net(stcb, alt, 1);
 				}
@@ -3570,7 +3544,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 			/* mark the sending seq for possible subsequent FR's */
 			/*
 			 * SCTP_PRINTF("Marking TSN for FR new value %x\n",
-			 * (uint32_t)tpi->rec.data.TSN_seq);
+			 * (uint32_t)tpi->rec.data.tsn);
 			 */
 			if (TAILQ_EMPTY(&asoc->send_queue)) {
 				/*
@@ -3593,7 +3567,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
 
 				ttt = TAILQ_FIRST(&asoc->send_queue);
 				tp1->rec.data.fast_retran_tsn =
-				    ttt->rec.data.TSN_seq;
+				    ttt->rec.data.tsn;
 			}
 
 			if (tp1->do_rtt) {
@@ -3641,7 +3615,7 @@ sctp_try_advance_peer_ack_point(struct sctp_tcb *stcb,
 			    (tp1->sent == SCTP_DATAGRAM_NR_ACKED)) {
 				sctp_misc_ints(SCTP_FWD_TSN_CHECK,
 				    asoc->advanced_peer_ack_point,
-				    tp1->rec.data.TSN_seq, 0, 0);
+				    tp1->rec.data.tsn, 0, 0);
 			}
 		}
 		if (!PR_SCTP_ENABLED(tp1->flags)) {
@@ -3689,10 +3663,10 @@ sctp_try_advance_peer_ack_point(struct sctp_tcb *stcb,
 		if ((tp1->sent == SCTP_FORWARD_TSN_SKIP) ||
 		    (tp1->sent == SCTP_DATAGRAM_NR_ACKED)) {
 			/* advance PeerAckPoint goes forward */
-			if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, asoc->advanced_peer_ack_point)) {
-				asoc->advanced_peer_ack_point = tp1->rec.data.TSN_seq;
+			if (SCTP_TSN_GT(tp1->rec.data.tsn, asoc->advanced_peer_ack_point)) {
+				asoc->advanced_peer_ack_point = tp1->rec.data.tsn;
 				a_adv = tp1;
-			} else if (tp1->rec.data.TSN_seq == asoc->advanced_peer_ack_point) {
+			} else if (tp1->rec.data.tsn == asoc->advanced_peer_ack_point) {
 				/* No update but we do save the chk */
 				a_adv = tp1;
 			}
@@ -3713,10 +3687,8 @@ sctp_fs_audit(struct sctp_association *asoc)
 	struct sctp_tmit_chunk *chk;
 	int inflight = 0, resend = 0, inbetween = 0, acked = 0, above = 0;
 	int ret;
-
 #ifndef INVARIANTS
 	int entry_flight, entry_cnt;
-
 #endif
 
 	ret = 0;
@@ -3730,7 +3702,7 @@ sctp_fs_audit(struct sctp_association *asoc)
 	TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
 		if (chk->sent < SCTP_DATAGRAM_RESEND) {
 			SCTP_PRINTF("Chk TSN: %u size: %d inflight cnt: %d\n",
-			    chk->rec.data.TSN_seq,
+			    chk->rec.data.tsn,
 			    chk->send_size,
 			    chk->snd_count);
 			inflight++;
@@ -3773,7 +3745,7 @@ sctp_window_probe_recovery(struct sctp_tcb *stcb,
 		    tp1->whoTo ? tp1->whoTo->flight_size : 0,
 		    tp1->book_size,
 		    (uint32_t) (uintptr_t) tp1->whoTo,
-		    tp1->rec.data.TSN_seq);
+		    tp1->rec.data.tsn);
 		return;
 	}
 	/* First setup this by shrinking flight */
@@ -3792,7 +3764,7 @@ sctp_window_probe_recovery(struct sctp_tcb *stcb,
 		    tp1->whoTo->flight_size,
 		    tp1->book_size,
 		    (uint32_t) (uintptr_t) tp1->whoTo,
-		    tp1->rec.data.TSN_seq);
+		    tp1->rec.data.tsn);
 	}
 }
 
@@ -3863,7 +3835,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
 	if (!TAILQ_EMPTY(&asoc->sent_queue)) {
 		tp1 = TAILQ_LAST(&asoc->sent_queue,
 		    sctpchunk_listhead);
-		send_s = tp1->rec.data.TSN_seq + 1;
+		send_s = tp1->rec.data.tsn + 1;
 	} else {
 		send_s = asoc->sending_seq;
 	}
@@ -3892,7 +3864,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
 	if (SCTP_TSN_GT(cumack, asoc->last_acked_seq)) {
 		/* process the new consecutive TSN first */
 		TAILQ_FOREACH_SAFE(tp1, &asoc->sent_queue, sctp_next, tp2) {
-			if (SCTP_TSN_GE(cumack, tp1->rec.data.TSN_seq)) {
+			if (SCTP_TSN_GE(cumack, tp1->rec.data.tsn)) {
 				if (tp1->sent == SCTP_DATAGRAM_UNSENT) {
 					SCTP_PRINTF("Warning, an unsent is now acked?\n");
 				}
@@ -3908,7 +3880,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
 							    tp1->whoTo->flight_size,
 							    tp1->book_size,
 							    (uint32_t) (uintptr_t) tp1->whoTo,
-							    tp1->rec.data.TSN_seq);
+							    tp1->rec.data.tsn);
 						}
 						sctp_flight_size_decrease(tp1);
 						if (stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) {
@@ -3933,8 +3905,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
 								tp1->whoTo->RTO =
 								/*
 								 * sa_ignore
-								 * NO_NULL_CH
-								 * K
+								 * NO_NULL_CHK
 								 */
 								    sctp_calculate_rto(stcb,
 								    asoc, tp1->whoTo,
@@ -3967,7 +3938,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
 
 					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
 						/* sa_ignore NO_NULL_CHK */
-						sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.TSN_seq, SCTP_CWND_LOG_FROM_SACK);
+						sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.tsn, SCTP_CWND_LOG_FROM_SACK);
 					}
 				}
 				if (tp1->sent == SCTP_DATAGRAM_RESEND) {
@@ -3979,17 +3950,17 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
 					tp1->rec.data.chunk_was_revoked = 0;
 				}
 				if (tp1->sent != SCTP_DATAGRAM_NR_ACKED) {
-					if (asoc->strmout[tp1->rec.data.stream_number].chunks_on_queues > 0) {
-						asoc->strmout[tp1->rec.data.stream_number].chunks_on_queues--;
+					if (asoc->strmout[tp1->rec.data.sid].chunks_on_queues > 0) {
+						asoc->strmout[tp1->rec.data.sid].chunks_on_queues--;
 #ifdef INVARIANTS
 					} else {
-						panic("No chunks on the queues for sid %u.", tp1->rec.data.stream_number);
+						panic("No chunks on the queues for sid %u.", tp1->rec.data.sid);
 #endif
 					}
 				}
-				if ((asoc->strmout[tp1->rec.data.stream_number].chunks_on_queues == 0) &&
-				    (asoc->strmout[tp1->rec.data.stream_number].state == SCTP_STREAM_RESET_PENDING) &&
-				    TAILQ_EMPTY(&asoc->strmout[tp1->rec.data.stream_number].outqueue)) {
+				if ((asoc->strmout[tp1->rec.data.sid].chunks_on_queues == 0) &&
+				    (asoc->strmout[tp1->rec.data.sid].state == SCTP_STREAM_RESET_PENDING) &&
+				    TAILQ_EMPTY(&asoc->strmout[tp1->rec.data.sid].outqueue)) {
 					asoc->trigger_reset = 1;
 				}
 				TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next);
@@ -4002,7 +3973,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
 				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
 					sctp_log_sack(asoc->last_acked_seq,
 					    cumack,
-					    tp1->rec.data.TSN_seq,
+					    tp1->rec.data.tsn,
 					    0,
 					    0,
 					    SCTP_LOG_FREE_SENT);
@@ -4066,10 +4037,8 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
 				}
 				if (net == stcb->asoc.primary_destination) {
 					if (stcb->asoc.alternate) {
-						/*
-						 * release the alternate,
-						 * primary is good
-						 */
+						/* release the alternate,
+						 * primary is good */
 						sctp_free_remote_addr(stcb->asoc.alternate);
 						stcb->asoc.alternate = NULL;
 					}
@@ -4152,10 +4121,8 @@ again:
 			}
 		} else {
 			if (net->window_probe) {
-				/*
-				 * In window probes we must assure a timer
-				 * is still running there
-				 */
+				/* In window probes we must assure a timer
+				 * is still running there */
 				net->window_probe = 0;
 				if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
 					SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks,
@@ -4406,7 +4373,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
 	if (!TAILQ_EMPTY(&asoc->sent_queue)) {
 		tp1 = TAILQ_LAST(&asoc->sent_queue,
 		    sctpchunk_listhead);
-		send_s = tp1->rec.data.TSN_seq + 1;
+		send_s = tp1->rec.data.tsn + 1;
 	} else {
 		tp1 = NULL;
 		send_s = asoc->sending_seq;
@@ -4423,7 +4390,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
 		    cum_ack, send_s);
 		if (tp1) {
 			SCTP_PRINTF("Got send_s from tsn:%x + 1 of tp1: %p\n",
-			    tp1->rec.data.TSN_seq, (void *)tp1);
+			    tp1->rec.data.tsn, (void *)tp1);
 		}
 hopeless_peer:
 		*abort_now = 1;
@@ -4498,7 +4465,7 @@ hopeless_peer:
 	}
 	/* process the new consecutive TSN first */
 	TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
-		if (SCTP_TSN_GE(last_tsn, tp1->rec.data.TSN_seq)) {
+		if (SCTP_TSN_GE(last_tsn, tp1->rec.data.tsn)) {
 			if (tp1->sent != SCTP_DATAGRAM_UNSENT) {
 				accum_moved = 1;
 				if (tp1->sent < SCTP_DATAGRAM_ACKED) {
@@ -4527,7 +4494,7 @@ hopeless_peer:
 							    tp1->whoTo->flight_size,
 							    tp1->book_size,
 							    (uint32_t) (uintptr_t) tp1->whoTo,
-							    tp1->rec.data.TSN_seq);
+							    tp1->rec.data.tsn);
 						}
 						sctp_flight_size_decrease(tp1);
 						sctp_total_flight_decrease(stcb, tp1);
@@ -4539,7 +4506,7 @@ hopeless_peer:
 					tp1->whoTo->net_ack += tp1->send_size;
 
 					/* CMT SFR and DAC algos */
-					this_sack_lowest_newack = tp1->rec.data.TSN_seq;
+					this_sack_lowest_newack = tp1->rec.data.tsn;
 					tp1->whoTo->saw_newack = 1;
 
 					if (tp1->snd_count < 2) {
@@ -4587,13 +4554,13 @@ hopeless_peer:
 					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
 						sctp_log_sack(asoc->last_acked_seq,
 						    cum_ack,
-						    tp1->rec.data.TSN_seq,
+						    tp1->rec.data.tsn,
 						    0,
 						    0,
 						    SCTP_LOG_TSN_ACKED);
 					}
 					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
-						sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.TSN_seq, SCTP_CWND_LOG_FROM_SACK);
+						sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.tsn, SCTP_CWND_LOG_FROM_SACK);
 					}
 				}
 				if (tp1->sent == SCTP_DATAGRAM_RESEND) {
@@ -4682,21 +4649,21 @@ hopeless_peer:
 	asoc->last_acked_seq = cum_ack;
 
 	TAILQ_FOREACH_SAFE(tp1, &asoc->sent_queue, sctp_next, tp2) {
-		if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, cum_ack)) {
+		if (SCTP_TSN_GT(tp1->rec.data.tsn, cum_ack)) {
 			break;
 		}
 		if (tp1->sent != SCTP_DATAGRAM_NR_ACKED) {
-			if (asoc->strmout[tp1->rec.data.stream_number].chunks_on_queues > 0) {
-				asoc->strmout[tp1->rec.data.stream_number].chunks_on_queues--;
+			if (asoc->strmout[tp1->rec.data.sid].chunks_on_queues > 0) {
+				asoc->strmout[tp1->rec.data.sid].chunks_on_queues--;
 #ifdef INVARIANTS
 			} else {
-				panic("No chunks on the queues for sid %u.", tp1->rec.data.stream_number);
+				panic("No chunks on the queues for sid %u.", tp1->rec.data.sid);
 #endif
 			}
 		}
-		if ((asoc->strmout[tp1->rec.data.stream_number].chunks_on_queues == 0) &&
-		    (asoc->strmout[tp1->rec.data.stream_number].state == SCTP_STREAM_RESET_PENDING) &&
-		    TAILQ_EMPTY(&asoc->strmout[tp1->rec.data.stream_number].outqueue)) {
+		if ((asoc->strmout[tp1->rec.data.sid].chunks_on_queues == 0) &&
+		    (asoc->strmout[tp1->rec.data.sid].state == SCTP_STREAM_RESET_PENDING) &&
+		    TAILQ_EMPTY(&asoc->strmout[tp1->rec.data.sid].outqueue)) {
 			asoc->trigger_reset = 1;
 		}
 		TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next);
@@ -4717,7 +4684,7 @@ hopeless_peer:
 		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SACK_LOGGING_ENABLE) {
 			sctp_log_sack(asoc->last_acked_seq,
 			    cum_ack,
-			    tp1->rec.data.TSN_seq,
+			    tp1->rec.data.tsn,
 			    0,
 			    0,
 			    SCTP_LOG_FREE_SENT);
@@ -4775,7 +4742,7 @@ hopeless_peer:
 	}
 	/*
 	 * Check for revoked fragments:
-	 * 
+	 *
 	 * if Previous sack - Had no frags then we can't have any revoked if
 	 * Previous sack - Had frag's then - If we now have frags aka
 	 * num_seg > 0 call sctp_check_for_revoked() to tell if peer revoked
@@ -4798,7 +4765,7 @@ hopeless_peer:
 					    tp1->whoTo->flight_size,
 					    tp1->book_size,
 					    (uint32_t) (uintptr_t) tp1->whoTo,
-					    tp1->rec.data.TSN_seq);
+					    tp1->rec.data.tsn);
 				}
 				sctp_flight_size_increase(tp1);
 				sctp_total_flight_increase(stcb, tp1);
@@ -4840,10 +4807,8 @@ hopeless_peer:
 				}
 				if (net == stcb->asoc.primary_destination) {
 					if (stcb->asoc.alternate) {
-						/*
-						 * release the alternate,
-						 * primary is good
-						 */
+						/* release the alternate,
+						 * primary is good */
 						sctp_free_remote_addr(stcb->asoc.alternate);
 						stcb->asoc.alternate = NULL;
 					}
@@ -5054,10 +5019,8 @@ again:
 			}
 		} else {
 			if (net->window_probe) {
-				/*
-				 * In window probes we must assure a timer
-				 * is still running there
-				 */
+				/* In window probes we must assure a timer
+				 * is still running there */
 				if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
 					sctp_timer_start(SCTP_TIMER_TYPE_SEND,
 					    stcb->sctp_ep, stcb, net);
@@ -5167,22 +5130,17 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
 {
 	struct sctp_queued_to_read *ctl, *nctl;
 	struct sctp_association *asoc;
-	uint32_t tt;
-	int need_reasm_check = 0, old;
+	uint32_t mid;
+	int need_reasm_check = 0;
 
 	asoc = &stcb->asoc;
-	tt = strmin->last_sequence_delivered;
-	if (asoc->idata_supported) {
-		old = 0;
-	} else {
-		old = 1;
-	}
+	mid = strmin->last_mid_delivered;
 	/*
 	 * First deliver anything prior to and including the stream no that
 	 * came in.
 	 */
 	TAILQ_FOREACH_SAFE(ctl, &strmin->inqueue, next_instrm, nctl) {
-		if (SCTP_MSGID_GE(old, tt, ctl->sinfo_ssn)) {
+		if (SCTP_MID_GE(asoc->idata_supported, mid, ctl->mid)) {
 			/* this is deliverable now */
 			if (((ctl->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) {
 				if (ctl->on_strm_q) {
@@ -5213,11 +5171,9 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
 			} else {
 				/* Its a fragmented message */
 				if (ctl->first_frag_seen) {
-					/*
-					 * Make it so this is next to
-					 * deliver, we restore later
-					 */
-					strmin->last_sequence_delivered = ctl->sinfo_ssn - 1;
+					/* Make it so this is next to
+					 * deliver, we restore later */
+					strmin->last_mid_delivered = ctl->mid - 1;
 					need_reasm_check = 1;
 					break;
 				}
@@ -5231,9 +5187,9 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
 		int ret;
 
 		ret = sctp_deliver_reasm_check(stcb, &stcb->asoc, strmin, SCTP_READ_LOCK_HELD);
-		if (SCTP_MSGID_GT(old, tt, strmin->last_sequence_delivered)) {
+		if (SCTP_MID_GT(asoc->idata_supported, mid, strmin->last_mid_delivered)) {
 			/* Restore the next to deliver unless we are ahead */
-			strmin->last_sequence_delivered = tt;
+			strmin->last_mid_delivered = mid;
 		}
 		if (ret == 0) {
 			/* Left the front Partial one on */
@@ -5245,9 +5201,9 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
 	 * now we must deliver things in queue the normal way  if any are
 	 * now ready.
 	 */
-	tt = strmin->last_sequence_delivered + 1;
+	mid = strmin->last_mid_delivered + 1;
 	TAILQ_FOREACH_SAFE(ctl, &strmin->inqueue, next_instrm, nctl) {
-		if (tt == ctl->sinfo_ssn) {
+		if (SCTP_MID_EQ(asoc->idata_supported, mid, ctl->mid)) {
 			if (((ctl->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) {
 				/* this is deliverable now */
 				if (ctl->on_strm_q) {
@@ -5267,7 +5223,7 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
 				asoc->size_on_all_streams -= ctl->length;
 				sctp_ucount_decr(asoc->cnt_on_all_streams);
 				/* deliver it to at least the delivery-q */
-				strmin->last_sequence_delivered = ctl->sinfo_ssn;
+				strmin->last_mid_delivered = ctl->mid;
 				if (stcb->sctp_socket) {
 					sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
 					sctp_add_to_readq(stcb->sctp_ep, stcb,
@@ -5276,15 +5232,13 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
 					    SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
 
 				}
-				tt = strmin->last_sequence_delivered + 1;
+				mid = strmin->last_mid_delivered + 1;
 			} else {
 				/* Its a fragmented message */
 				if (ctl->first_frag_seen) {
-					/*
-					 * Make it so this is next to
-					 * deliver
-					 */
-					strmin->last_sequence_delivered = ctl->sinfo_ssn - 1;
+					/* Make it so this is next to
+					 * deliver */
+					strmin->last_mid_delivered = ctl->mid - 1;
 					need_reasm_check = 1;
 					break;
 				}
@@ -5303,7 +5257,7 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
 static void
 sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
     struct sctp_association *asoc,
-    uint16_t stream, uint32_t seq, int ordered, int old, uint32_t cumtsn)
+    uint16_t stream, uint32_t mid, int ordered, uint32_t cumtsn)
 {
 	struct sctp_queued_to_read *control;
 	struct sctp_stream_in *strm;
@@ -5319,15 +5273,18 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
 	 * queue.
 	 */
 	strm = &asoc->strmin[stream];
-	control = sctp_find_reasm_entry(strm, (uint32_t) seq, ordered, old);
+	control = sctp_find_reasm_entry(strm, mid, ordered, asoc->idata_supported);
 	if (control == NULL) {
 		/* Not found */
 		return;
 	}
+	if (!asoc->idata_supported && !ordered && SCTP_TSN_GT(control->fsn_included, cumtsn)) {
+		return;
+	}
 	TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) {
 		/* Purge hanging chunks */
-		if (old && (ordered == 0)) {
-			if (SCTP_TSN_GT(chk->rec.data.TSN_seq, cumtsn)) {
+		if (!asoc->idata_supported && (ordered == 0)) {
+			if (SCTP_TSN_GT(chk->rec.data.tsn, cumtsn)) {
 				break;
 			}
 		}
@@ -5389,11 +5346,11 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
 	/*
 	 * here we will perform all the data receiver side steps for
 	 * processing FwdTSN, as required in by pr-sctp draft:
-	 * 
+	 *
 	 * Assume we get FwdTSN(x):
-	 * 
-	 * 1) update local cumTSN to x 2) try to further advance cumTSN to x +
-	 * others we have 3) examine and update re-ordering queue on
+	 *
+	 * 1) update local cumTSN to x 2) try to further advance cumTSN to x
+	 * + others we have 3) examine and update re-ordering queue on
 	 * pr-in-streams 4) clean up re-assembly queue 5) Send a sack to
 	 * report where we are.
 	 */
@@ -5479,7 +5436,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
 		/* Flush all the un-ordered data based on cum-tsn */
 		SCTP_INP_READ_LOCK(stcb->sctp_ep);
 		for (sid = 0; sid < asoc->streamincnt; sid++) {
-			sctp_flush_reassm_for_str_seq(stcb, asoc, sid, 0, 0, 1, new_cum_tsn);
+			sctp_flush_reassm_for_str_seq(stcb, asoc, sid, 0, 0, new_cum_tsn);
 		}
 		SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
 	}
@@ -5491,10 +5448,9 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
 	if (m && fwd_sz) {
 		/* New method. */
 		unsigned int num_str;
-		uint32_t sequence;
-		uint16_t stream;
+		uint32_t mid, cur_mid;
+		uint16_t sid;
 		uint16_t ordered, flags;
-		int old;
 		struct sctp_strseq *stseq, strseqbuf;
 		struct sctp_strseq_mid *stseq_m, strseqbuf_m;
 
@@ -5503,10 +5459,8 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
 		SCTP_INP_READ_LOCK(stcb->sctp_ep);
 		if (asoc->idata_supported) {
 			num_str = fwd_sz / sizeof(struct sctp_strseq_mid);
-			old = 0;
 		} else {
 			num_str = fwd_sz / sizeof(struct sctp_strseq);
-			old = 1;
 		}
 		for (i = 0; i < num_str; i++) {
 			if (asoc->idata_supported) {
@@ -5517,8 +5471,8 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
 				if (stseq_m == NULL) {
 					break;
 				}
-				stream = ntohs(stseq_m->stream);
-				sequence = ntohl(stseq_m->msg_id);
+				sid = ntohs(stseq_m->sid);
+				mid = ntohl(stseq_m->mid);
 				flags = ntohs(stseq_m->flags);
 				if (flags & PR_SCTP_UNORDERED_FLAG) {
 					ordered = 0;
@@ -5533,8 +5487,8 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
 				if (stseq == NULL) {
 					break;
 				}
-				stream = ntohs(stseq->stream);
-				sequence = (uint32_t) ntohs(stseq->sequence);
+				sid = ntohs(stseq->sid);
+				mid = (uint32_t) ntohs(stseq->ssn);
 				ordered = 1;
 			}
 			/* Convert */
@@ -5546,12 +5500,12 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
 			 * queue where its not all delivered. If we find it
 			 * we transmute the read entry into a PDI_ABORTED.
 			 */
-			if (stream >= asoc->streamincnt) {
+			if (sid >= asoc->streamincnt) {
 				/* screwed up streams, stop!  */
 				break;
 			}
-			if ((asoc->str_of_pdapi == stream) &&
-			    (asoc->ssn_of_pdapi == sequence)) {
+			if ((asoc->str_of_pdapi == sid) &&
+			    (asoc->ssn_of_pdapi == mid)) {
 				/*
 				 * If this is the one we were partially
 				 * delivering now then we no longer are.
@@ -5560,24 +5514,14 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
 				 */
 				asoc->fragmented_delivery_inprogress = 0;
 			}
-			strm = &asoc->strmin[stream];
-			if (asoc->idata_supported == 0) {
-				uint16_t strm_at;
-
-				for (strm_at = strm->last_sequence_delivered; SCTP_MSGID_GE(1, sequence, strm_at); strm_at++) {
-					sctp_flush_reassm_for_str_seq(stcb, asoc, stream, strm_at, ordered, old, new_cum_tsn);
-				}
-			} else {
-				uint32_t strm_at;
-
-				for (strm_at = strm->last_sequence_delivered; SCTP_MSGID_GE(0, sequence, strm_at); strm_at++) {
-					sctp_flush_reassm_for_str_seq(stcb, asoc, stream, strm_at, ordered, old, new_cum_tsn);
-				}
+			strm = &asoc->strmin[sid];
+			for (cur_mid = strm->last_mid_delivered; SCTP_MID_GE(asoc->idata_supported, mid, cur_mid); cur_mid++) {
+				sctp_flush_reassm_for_str_seq(stcb, asoc, sid, cur_mid, ordered, new_cum_tsn);
 			}
 			TAILQ_FOREACH(ctl, &stcb->sctp_ep->read_queue, next) {
-				if ((ctl->sinfo_stream == stream) &&
-				    (ctl->sinfo_ssn == sequence)) {
-					str_seq = (stream << 16) | (0x0000ffff & sequence);
+				if ((ctl->sinfo_stream == sid) &&
+				    (SCTP_MID_EQ(asoc->idata_supported, ctl->mid, mid))) {
+					str_seq = (sid << 16) | (0x0000ffff & mid);
 					ctl->pdapi_aborted = 1;
 					sv = stcb->asoc.control_pdapi;
 					ctl->end_added = 1;
@@ -5600,15 +5544,15 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
 					    SCTP_SO_NOT_LOCKED);
 					stcb->asoc.control_pdapi = sv;
 					break;
-				} else if ((ctl->sinfo_stream == stream) &&
-				    SCTP_MSGID_GT(old, ctl->sinfo_ssn, sequence)) {
+				} else if ((ctl->sinfo_stream == sid) &&
+				    SCTP_MID_GT(asoc->idata_supported, ctl->mid, mid)) {
 					/* We are past our victim SSN */
 					break;
 				}
 			}
-			if (SCTP_MSGID_GT(old, sequence, strm->last_sequence_delivered)) {
+			if (SCTP_MID_GT(asoc->idata_supported, mid, strm->last_mid_delivered)) {
 				/* Update the sequence number */
-				strm->last_sequence_delivered = sequence;
+				strm->last_mid_delivered = mid;
 			}
 			/* now kick the stream the new way */
 			/* sa_ignore NO_NULL_CHK */
diff --git a/freebsd/sys/netinet/sctp_indata.h b/freebsd/sys/netinet/sctp_indata.h
index 162ca90..e277ae8 100644
--- a/freebsd/sys/netinet/sctp_indata.h
+++ b/freebsd/sys/netinet/sctp_indata.h
@@ -42,20 +42,19 @@ struct sctp_queued_to_read *
 sctp_build_readq_entry(struct sctp_tcb *stcb,
     struct sctp_nets *net,
     uint32_t tsn, uint32_t ppid,
-    uint32_t context, uint16_t stream_no,
-    uint32_t stream_seq, uint8_t flags,
+    uint32_t context, uint16_t sid,
+    uint32_t mid, uint8_t flags,
     struct mbuf *dm);
 
 
-#define sctp_build_readq_entry_mac(_ctl, in_it, context, net, tsn, ppid, stream_no, stream_seq, flags, dm, tfsn, msgid) do { \
+#define sctp_build_readq_entry_mac(_ctl, in_it, context, net, tsn, ppid, sid, flags, dm, tfsn, mid) do { \
 	if (_ctl) { \
 		atomic_add_int(&((net)->ref_count), 1); \
 		memset(_ctl, 0, sizeof(struct sctp_queued_to_read)); \
-		(_ctl)->sinfo_stream = stream_no; \
-		(_ctl)->sinfo_ssn = stream_seq; \
+		(_ctl)->sinfo_stream = sid; \
 		TAILQ_INIT(&_ctl->reasm); \
 		(_ctl)->top_fsn = tfsn; \
-		(_ctl)->msg_id = msgid; \
+		(_ctl)->mid = mid; \
 		(_ctl)->sinfo_flags = (flags << 8); \
 		(_ctl)->sinfo_ppid = ppid; \
 		(_ctl)->sinfo_context = context; \
diff --git a/freebsd/sys/netinet/sctp_input.c b/freebsd/sys/netinet/sctp_input.c
index 621784e..3c596c4 100644
--- a/freebsd/sys/netinet/sctp_input.c
+++ b/freebsd/sys/netinet/sctp_input.c
@@ -163,10 +163,8 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
 			*abort_no_unlock = 1;
 		goto outnow;
 	}
-	/*
-	 * We are only accepting if we have a socket with positive
-	 * so_qlimit.
-	 */
+	/* We are only accepting if we have a socket with positive
+	 * so_qlimit. */
 	if ((stcb == NULL) &&
 	    ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
 	    (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
@@ -322,14 +320,14 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
 		/* abandon the upper streams */
 		newcnt = ntohs(init->num_inbound_streams);
 		TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
-			if (chk->rec.data.stream_number >= newcnt) {
+			if (chk->rec.data.sid >= newcnt) {
 				TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
 				asoc->send_queue_cnt--;
-				if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
-					asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
+				if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
+					asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
 #ifdef INVARIANTS
 				} else {
-					panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number);
+					panic("No chunks on the queues for sid %u.", chk->rec.data.sid);
 #endif
 				}
 				if (chk->data != NULL) {
@@ -414,8 +412,8 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
 		return (-1);
 	}
 	for (i = 0; i < asoc->streamincnt; i++) {
-		asoc->strmin[i].stream_no = i;
-		asoc->strmin[i].last_sequence_delivered = 0xffffffff;
+		asoc->strmin[i].sid = i;
+		asoc->strmin[i].last_mid_delivered = 0xffffffff;
 		TAILQ_INIT(&asoc->strmin[i].inqueue);
 		TAILQ_INIT(&asoc->strmin[i].uno_inqueue);
 		asoc->strmin[i].pd_api_started = 0;
@@ -711,10 +709,8 @@ sctp_handle_nat_colliding_state(struct sctp_tcb *stcb)
 		LIST_REMOVE(stcb, sctp_asocs);
 		stcb->asoc.my_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
 		head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
-		/*
-		 * put it in the bucket in the vtag hash of assoc's for the
-		 * system
-		 */
+		/* put it in the bucket in the vtag hash of assoc's for the
+		 * system */
 		LIST_INSERT_HEAD(head, stcb, sctp_asocs);
 		sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
 		return (1);
@@ -732,10 +728,8 @@ sctp_handle_nat_colliding_state(struct sctp_tcb *stcb)
 		sctp_toss_old_cookies(stcb, &stcb->asoc);
 		stcb->asoc.my_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
 		head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
-		/*
-		 * put it in the bucket in the vtag hash of assoc's for the
-		 * system
-		 */
+		/* put it in the bucket in the vtag hash of assoc's for the
+		 * system */
 		LIST_INSERT_HEAD(head, stcb, sctp_asocs);
 		sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
 		return (1);
@@ -766,7 +760,6 @@ sctp_handle_abort(struct sctp_abort_chunk *abort,
 {
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so;
-
 #endif
 	uint16_t len;
 	uint16_t error;
@@ -868,10 +861,8 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
 	struct sctp_association *asoc;
 	int some_on_streamwheel;
 	int old_state;
-
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so;
-
 #endif
 
 	SCTPDBG(SCTP_DEBUG_INPUT2,
@@ -948,10 +939,8 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
 		    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT)) {
 			SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_RECEIVED);
 			SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
-			/*
-			 * notify upper layer that peer has initiated a
-			 * shutdown
-			 */
+			/* notify upper layer that peer has initiated a
+			 * shutdown */
 			sctp_ulp_notify(SCTP_NOTIFY_PEER_SHUTDOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
 
 			/* reset time */
@@ -1001,7 +990,6 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
     struct sctp_nets *net)
 {
 	struct sctp_association *asoc;
-
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so;
 
@@ -1171,10 +1159,8 @@ sctp_handle_error(struct sctp_chunkhdr *ch,
 	uint16_t error_len;
 	struct sctp_association *asoc;
 	int adjust;
-
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so;
-
 #endif
 
 	/* parse through all of the errors and process */
@@ -1494,10 +1480,8 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
 	int retval;
 	int spec_flag = 0;
 	uint32_t how_indx;
-
 #if defined(SCTP_DETAILED_STR_STATS)
 	int j;
-
 #endif
 
 	net = *netp;
@@ -1621,7 +1605,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
 			    ) {
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 				struct socket *so;
-
 #endif
 				/*
 				 * Here is where collision would go if we
@@ -1822,7 +1805,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
 			    (inp->sctp_socket->so_qlimit == 0)) {
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 				struct socket *so;
-
 #endif
 				stcb->sctp_ep->sctp_flags |=
 				    SCTP_PCB_FLAGS_CONNECTED;
@@ -1882,10 +1864,8 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
 	    cookie->tie_tag_peer_vtag == asoc->peer_vtag_nonce &&
 	    cookie->tie_tag_peer_vtag != 0) {
 		struct sctpasochead *head;
-
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 		struct socket *so;
-
 #endif
 
 		if (asoc->peer_supports_nat) {
@@ -1977,7 +1957,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
 			asoc->strmout[i].abandoned_sent[0] = 0;
 			asoc->strmout[i].abandoned_unsent[0] = 0;
 #endif
-			stcb->asoc.strmout[i].stream_no = i;
+			stcb->asoc.strmout[i].sid = i;
 			stcb->asoc.strmout[i].next_mid_ordered = 0;
 			stcb->asoc.strmout[i].next_mid_unordered = 0;
 			stcb->asoc.strmout[i].last_msg_incomplete = 0;
@@ -2069,7 +2049,6 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
 	int retval;
 	int error = 0;
 	uint8_t auth_chunk_buf[SCTP_PARAM_BUFFER_SIZE];
-
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so;
 
@@ -2444,14 +2423,11 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
 	struct sctp_nets *netl;
 	int had_a_existing_tcb = 0;
 	int send_int_conf = 0;
-
 #ifdef INET
 	struct sockaddr_in sin;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 sin6;
-
 #endif
 
 	SCTPDBG(SCTP_DEBUG_INPUT2,
@@ -2773,10 +2749,8 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
 
 			if (so == NULL) {
 				struct mbuf *op_err;
-
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 				struct socket *pcb_so;
-
 #endif
 				/* Too many sockets */
 				SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: no room for another socket!\n");
@@ -2889,10 +2863,8 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
 				sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
 				    (*stcb), 0, (void *)netl, SCTP_SO_NOT_LOCKED);
 			}
-			/*
-			 * Pull it from the incomplete queue and wake the
-			 * guy
-			 */
+			/* Pull it from the incomplete queue and wake the
+			 * guy */
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 			atomic_add_int(&(*stcb)->asoc.refcnt, 1);
 			SCTP_TCB_UNLOCK((*stcb));
@@ -3057,18 +3029,18 @@ sctp_handle_ecn_echo(struct sctp_ecne_chunk *cp,
 	if (lchk == NULL) {
 		window_data_tsn = stcb->asoc.sending_seq - 1;
 	} else {
-		window_data_tsn = lchk->rec.data.TSN_seq;
+		window_data_tsn = lchk->rec.data.tsn;
 	}
 
 	/* Find where it was sent to if possible. */
 	net = NULL;
 	TAILQ_FOREACH(lchk, &stcb->asoc.sent_queue, sctp_next) {
-		if (lchk->rec.data.TSN_seq == tsn) {
+		if (lchk->rec.data.tsn == tsn) {
 			net = lchk->whoTo;
 			net->ecn_prev_cwnd = lchk->rec.data.cwnd_at_send;
 			break;
 		}
-		if (SCTP_TSN_GT(lchk->rec.data.TSN_seq, tsn)) {
+		if (SCTP_TSN_GT(lchk->rec.data.tsn, tsn)) {
 			break;
 		}
 	}
@@ -3104,10 +3076,8 @@ sctp_handle_ecn_echo(struct sctp_ecne_chunk *cp,
 	}
 	if (SCTP_TSN_GT(tsn, net->cwr_window_tsn) &&
 	    ((override_bit & SCTP_CWR_REDUCE_OVERRIDE) == 0)) {
-		/*
-		 * JRS - Use the congestion control given in the pluggable
-		 * CC module
-		 */
+		/* JRS - Use the congestion control given in the pluggable
+		 * CC module */
 		stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo(stcb, net, 0, pkt_cnt);
 		/*
 		 * We reduce once every RTT. So we will only lower cwnd at
@@ -3195,10 +3165,8 @@ sctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp SCTP_UNUSE
     struct sctp_tcb *stcb, struct sctp_nets *net)
 {
 	struct sctp_association *asoc;
-
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so;
-
 #endif
 
 	SCTPDBG(SCTP_DEBUG_INPUT2,
@@ -3262,11 +3230,11 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
 
 			tsn = ntohl(desc->tsn_ifany);
 			TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) {
-				if (tp1->rec.data.TSN_seq == tsn) {
+				if (tp1->rec.data.tsn == tsn) {
 					/* found it */
 					break;
 				}
-				if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, tsn)) {
+				if (SCTP_TSN_GT(tp1->rec.data.tsn, tsn)) {
 					/* not found */
 					tp1 = NULL;
 					break;
@@ -3279,7 +3247,7 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
 				 */
 				SCTP_STAT_INCR(sctps_pdrpdnfnd);
 				TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) {
-					if (tp1->rec.data.TSN_seq == tsn) {
+					if (tp1->rec.data.tsn == tsn) {
 						/* found it */
 						break;
 					}
@@ -3345,7 +3313,7 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
 				if (TAILQ_EMPTY(&stcb->asoc.send_queue)) {
 					tp1->rec.data.fast_retran_tsn = stcb->asoc.sending_seq;
 				} else {
-					tp1->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.TSN_seq;
+					tp1->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.tsn;
 				}
 
 				/* restart the timer */
@@ -3361,7 +3329,7 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
 					    tp1->whoTo->flight_size,
 					    tp1->book_size,
 					    (uint32_t) (uintptr_t) stcb,
-					    tp1->rec.data.TSN_seq);
+					    tp1->rec.data.tsn);
 				}
 				if (tp1->sent < SCTP_DATAGRAM_RESEND) {
 					sctp_flight_size_decrease(tp1);
@@ -3432,10 +3400,8 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
 	case SCTP_HEARTBEAT_REQUEST:
 		/* resend a demand HB */
 		if ((stcb->asoc.overall_error_count + 3) < stcb->asoc.max_send_times) {
-			/*
-			 * Only retransmit if we KNOW we wont destroy the
-			 * tcb
-			 */
+			/* Only retransmit if we KNOW we wont destroy the
+			 * tcb */
 			sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
 		}
 		break;
@@ -3507,12 +3473,12 @@ sctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t *
 			if (temp >= stcb->asoc.streamincnt) {
 				continue;
 			}
-			stcb->asoc.strmin[temp].last_sequence_delivered = 0xffffffff;
+			stcb->asoc.strmin[temp].last_mid_delivered = 0xffffffff;
 		}
 	} else {
 		list = NULL;
 		for (i = 0; i < stcb->asoc.streamincnt; i++) {
-			stcb->asoc.strmin[i].last_sequence_delivered = 0xffffffff;
+			stcb->asoc.strmin[i].last_mid_delivered = 0xffffffff;
 		}
 	}
 	sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_RECV, stcb, number_entries, (void *)list, SCTP_SO_NOT_LOCKED);
@@ -3676,10 +3642,8 @@ sctp_handle_stream_reset_response(struct sctp_tcb *stcb,
 				} else if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
 					sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_DENIED_OUT, stcb, number_entries, req_out_param->list_of_streams, SCTP_SO_NOT_LOCKED);
 				} else if (action == SCTP_STREAM_RESET_RESULT_IN_PROGRESS) {
-					/*
-					 * Set it up so we don't stop
-					 * retransmitting
-					 */
+					/* Set it up so we don't stop
+					 * retransmitting */
 					asoc->stream_reset_outstanding++;
 					stcb->asoc.str_reset_seq_out--;
 					asoc->stream_reset_out_is_outstanding = 1;
@@ -4056,8 +4020,8 @@ sctp_handle_str_reset_add_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *ch
 			for (i = 0; i < stcb->asoc.streamincnt; i++) {
 				TAILQ_INIT(&stcb->asoc.strmin[i].inqueue);
 				TAILQ_INIT(&stcb->asoc.strmin[i].uno_inqueue);
-				stcb->asoc.strmin[i].stream_no = i;
-				stcb->asoc.strmin[i].last_sequence_delivered = oldstrm[i].last_sequence_delivered;
+				stcb->asoc.strmin[i].sid = i;
+				stcb->asoc.strmin[i].last_mid_delivered = oldstrm[i].last_mid_delivered;
 				stcb->asoc.strmin[i].delivery_started = oldstrm[i].delivery_started;
 				stcb->asoc.strmin[i].pd_api_started = oldstrm[i].pd_api_started;
 				/* now anything on those queues? */
@@ -4074,8 +4038,8 @@ sctp_handle_str_reset_add_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *ch
 			for (i = stcb->asoc.streamincnt; i < num_stream; i++) {
 				TAILQ_INIT(&stcb->asoc.strmin[i].inqueue);
 				TAILQ_INIT(&stcb->asoc.strmin[i].uno_inqueue);
-				stcb->asoc.strmin[i].stream_no = i;
-				stcb->asoc.strmin[i].last_sequence_delivered = 0xffffffff;
+				stcb->asoc.strmin[i].sid = i;
+				stcb->asoc.strmin[i].last_mid_delivered = 0xffffffff;
 				stcb->asoc.strmin[i].pd_api_started = 0;
 				stcb->asoc.strmin[i].delivery_started = 0;
 			}
@@ -4532,10 +4496,8 @@ __attribute__((noinline))
 	uint32_t auth_offset = 0, auth_len = 0;
 	int auth_skipped = 0;
 	int asconf_cnt = 0;
-
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so;
-
 #endif
 
 	SCTPDBG(SCTP_DEBUG_INPUT1, "sctp_process_control: iphlen=%u, offset=%u, length=%u stcb:%p\n",
@@ -4735,10 +4697,8 @@ __attribute__((noinline))
 				return (NULL);
 			}
 		}
-	}			/* end if !SCTP_COOKIE_ECHO */
-	/*
-	 * process all control chunks...
-	 */
+	}			/* end if !SCTP_COOKIE_ECHO *//* process all
+				 * control chunks... */
 	if (((ch->chunk_type == SCTP_SELECTIVE_ACK) ||
 	    (ch->chunk_type == SCTP_NR_SELECTIVE_ACK) ||
 	    (ch->chunk_type == SCTP_HEARTBEAT_REQUEST)) &&
@@ -5032,10 +4992,8 @@ process_control_chunks:
 				}
 			}
 			break;
-			/*
-			 * EY - nr_sack:  If the received chunk is an
-			 * nr_sack chunk
-			 */
+			/* EY - nr_sack:  If the received chunk is an
+			 * nr_sack chunk */
 		case SCTP_NR_SELECTIVE_ACK:
 			{
 				struct sctp_nr_sack_chunk *nr_sack;
@@ -5517,6 +5475,11 @@ process_control_chunks:
 					*offset = length;
 					return (NULL);
 				}
+				/*
+				 * For sending a SACK this looks like DATA
+				 * chunks.
+				 */
+				stcb->asoc.last_data_chunk_from = stcb->asoc.last_control_chunk_from;
 				sctp_handle_forward_tsn(stcb,
 				    (struct sctp_forward_tsn_chunk *)ch, &abort_flag, m, *offset);
 				if (abort_flag) {
@@ -5648,8 +5611,7 @@ process_control_chunks:
 				/* discard this packet */
 				*offset = length;
 				return (stcb);
-			}	/* else skip this bad chunk and continue... */
-			break;
+			} /* else skip this bad chunk and continue... */ break;
 		}		/* switch (ch->chunk_type) */
 
 
@@ -6106,10 +6068,8 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
 	struct sctphdr *sh;
 	struct sctp_chunkhdr *ch;
 	int length, offset;
-
 #if !defined(SCTP_WITH_NO_CSUM)
 	uint8_t compute_crc;
-
 #endif
 	uint32_t mflowid;
 	uint8_t mflowtype;
@@ -6210,7 +6170,6 @@ out:
 
 #if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
 extern int *sctp_cpuarry;
-
 #endif
 
 int
@@ -6258,5 +6217,4 @@ sctp_input(struct mbuf **mp, int *offp, int proto SCTP_UNUSED)
 	sctp_input_with_port(m, off, 0);
 	return (IPPROTO_DONE);
 }
-
 #endif
diff --git a/freebsd/sys/netinet/sctp_os_bsd.h b/freebsd/sys/netinet/sctp_os_bsd.h
index e87914e..438973c 100644
--- a/freebsd/sys/netinet/sctp_os_bsd.h
+++ b/freebsd/sys/netinet/sctp_os_bsd.h
@@ -247,7 +247,6 @@ MALLOC_DECLARE(SCTP_M_MCORE);
 
 /* SCTP_ZONE_INIT: initialize the zone */
 typedef struct uma_zone *sctp_zone_t;
-
 #define SCTP_ZONE_INIT(zone, name, size, number) { \
 	zone = uma_zcreate(name, size, NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,\
 		0); \
diff --git a/freebsd/sys/netinet/sctp_output.c b/freebsd/sys/netinet/sctp_output.c
index 9e12e77..94f9d86 100644
--- a/freebsd/sys/netinet/sctp_output.c
+++ b/freebsd/sys/netinet/sctp_output.c
@@ -1945,7 +1945,6 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t * len)
 	struct sctp_paramhdr *parmh;
 	struct mbuf *mret;
 	uint16_t plen;
-
 #endif
 
 	switch (ifa->address.sa.sa_family) {
@@ -2141,10 +2140,8 @@ skip_count:
 						cnt++;
 						total_count++;
 						if (cnt >= 2) {
-							/*
-							 * two from each
-							 * address
-							 */
+							/* two from each
+							 * address */
 							break;
 						}
 						if (total_count > SCTP_ADDRESS_LIMIT) {
@@ -2786,7 +2783,6 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
 {
 	struct sctp_ifa *ifa, *sifa;
 	int num_eligible_addr = 0;
-
 #ifdef INET6
 	struct sockaddr_in6 sin6, lsa6;
 
@@ -2831,10 +2827,8 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
 		if (fam == AF_INET6 &&
 		    IN6_IS_ADDR_LINKLOCAL(&sifa->address.sin6.sin6_addr) &&
 		    IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) {
-			/*
-			 * link-local <-> link-local must belong to the same
-			 * scope.
-			 */
+			/* link-local <-> link-local must belong to the same
+			 * scope. */
 			memcpy(&lsa6, &sifa->address.sin6, sizeof(struct sockaddr_in6));
 			(void)sa6_recoverscope(&lsa6);
 			if (sin6.sin6_scope_id != lsa6.sin6_scope_id) {
@@ -2968,10 +2962,8 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
 	struct sctp_ifa *sctp_ifa, *sifa;
 	uint32_t ifn_index;
 	struct sctp_vrf *vrf;
-
 #ifdef INET
 	int retried = 0;
-
 #endif
 
 	/*-
@@ -3317,14 +3309,11 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
 	struct sctp_ifa *answer;
 	uint8_t dest_is_priv, dest_is_loop;
 	sa_family_t fam;
-
 #ifdef INET
 	struct sockaddr_in *to = (struct sockaddr_in *)&ro->ro_dst;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&ro->ro_dst;
-
 #endif
 
 	/**
@@ -3572,14 +3561,11 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
 	struct cmsghdr cmh;
 	int tlen, at;
 	struct sctp_initmsg initmsg;
-
 #ifdef INET
 	struct sockaddr_in sin;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 sin6;
-
 #endif
 
 	tlen = SCTP_BUF_LEN(control);
@@ -3620,10 +3606,8 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
 				if (stcb->asoc.streamoutcnt < stcb->asoc.pre_open_streams) {
 					struct sctp_stream_out *tmp_str;
 					unsigned int i;
-
 #if defined(SCTP_DETAILED_STR_STATS)
 					int j;
-
 #endif
 
 					/* Default is NOT correct */
@@ -3656,7 +3640,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
 						stcb->asoc.strmout[i].abandoned_sent[0] = 0;
 						stcb->asoc.strmout[i].abandoned_unsent[0] = 0;
 #endif
-						stcb->asoc.strmout[i].stream_no = i;
+						stcb->asoc.strmout[i].sid = i;
 						stcb->asoc.strmout[i].last_msg_incomplete = 0;
 						stcb->asoc.strmout[i].state = SCTP_STREAM_OPENING;
 						stcb->asoc.ss_functions.sctp_ss_init_stream(stcb, &stcb->asoc.strmout[i], NULL);
@@ -3746,14 +3730,11 @@ sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p,
 	int tlen, at;
 	struct sctp_tcb *stcb;
 	struct sockaddr *addr;
-
 #ifdef INET
 	struct sockaddr_in sin;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 sin6;
-
 #endif
 
 	tlen = SCTP_BUF_LEN(control);
@@ -3972,7 +3953,6 @@ sctp_handle_no_route(struct sctp_tcb *stcb,
 		}
 	}
 }
-
 #endif
 
 static int
@@ -4018,22 +3998,17 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
 	struct sctphdr *sctphdr;
 	int packet_length;
 	int ret;
-
 #if defined(INET) || defined(INET6)
 	uint32_t vrf_id;
-
 #endif
 #if defined(INET) || defined(INET6)
 	struct mbuf *o_pak;
 	sctp_route_t *ro = NULL;
 	struct udphdr *udp = NULL;
-
 #endif
 	uint8_t tos_value;
-
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so = NULL;
-
 #endif
 
 	if ((net) && (net->dest_state & SCTP_ADDR_OUT_OF_SCOPE)) {
@@ -4291,10 +4266,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
 				/* free tempy routes */
 				RO_RTFREE(ro);
 			} else {
-				/*
-				 * PMTU check versus smallest asoc MTU goes
-				 * here
-				 */
+				/* PMTU check versus smallest asoc MTU goes
+				 * here */
 				if ((ro->ro_rt != NULL) &&
 				    (net->ro._s_addr)) {
 					uint32_t mtu;
@@ -4569,10 +4542,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
 			SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT3, (struct sockaddr *)sin6);
 			if (net) {
 				sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
-				/*
-				 * preserve the port and scope for link
-				 * local send
-				 */
+				/* preserve the port and scope for link
+				 * local send */
 				prev_scope = sin6->sin6_scope_id;
 				prev_port = sin6->sin6_port;
 			}
@@ -4638,10 +4609,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
 				/* Now if we had a temp route free it */
 				RO_RTFREE(ro);
 			} else {
-				/*
-				 * PMTU check versus smallest asoc MTU goes
-				 * here
-				 */
+				/* PMTU check versus smallest asoc MTU goes
+				 * here */
 				if (ro->ro_rt == NULL) {
 					/* Route was freed */
 					if (net->ro._s_addr &&
@@ -4971,11 +4940,11 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
 	 * being equal to the beginning of the params i.e. (iphlen +
 	 * sizeof(struct sctp_init_msg) parse through the parameters to the
 	 * end of the mbuf verifying that all parameters are known.
-	 * 
+	 *
 	 * For unknown parameters build and return a mbuf with
 	 * UNRECOGNIZED_PARAMETER errors. If the flags indicate to stop
 	 * processing this chunk stop, and set *abort_processing to 1.
-	 * 
+	 *
 	 * By having param_offset be pre-set to where parameters begin it is
 	 * hoped that this routine may be reused in the future by new
 	 * features.
@@ -5262,7 +5231,6 @@ invalid_size:
 	*abort_processing = 1;
 	if ((op_err == NULL) && phdr) {
 		int l_len;
-
 #ifdef INET6
 		l_len = SCTP_MIN_OVERHEAD;
 #else
@@ -5320,14 +5288,11 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
 	uint8_t fnd;
 	struct sctp_nets *net;
 	int check_src;
-
 #ifdef INET
 	struct sockaddr_in sin4, *sa4;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 sin6, *sa6;
-
 #endif
 
 #ifdef INET
@@ -5511,18 +5476,15 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 	struct sctp_paramhdr *ph;
 	union sctp_sockstore *over_addr;
 	struct sctp_scoping scp;
-
 #ifdef INET
 	struct sockaddr_in *dst4 = (struct sockaddr_in *)dst;
 	struct sockaddr_in *src4 = (struct sockaddr_in *)src;
 	struct sockaddr_in *sin;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)dst;
 	struct sockaddr_in6 *src6 = (struct sockaddr_in6 *)src;
 	struct sockaddr_in6 *sin6;
-
 #endif
 	struct sockaddr *to;
 	struct sctp_state_cookie stc;
@@ -5546,10 +5508,10 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 			/*
 			 * new addresses, out of here in non-cookie-wait
 			 * states
-			 * 
-			 * Send an ABORT, without the new address error cause.
-			 * This looks no different than if no listener was
-			 * present.
+			 *
+			 * Send an ABORT, without the new address error
+			 * cause. This looks no different than if no
+			 * listener was present.
 			 */
 			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
 			    "Address added");
@@ -5562,9 +5524,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 			/*
 			 * change of remote encapsulation port, out of here
 			 * in non-cookie-wait states
-			 * 
-			 * Send an ABORT, without an specific error cause. This
-			 * looks no different than if no listener was
+			 *
+			 * Send an ABORT, without an specific error cause.
+			 * This looks no different than if no listener was
 			 * present.
 			 */
 			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
@@ -5718,10 +5680,8 @@ do_a_abort:
 					 * show up in our scoped count.
 					 */
 					cnt_inits_to = 1;
-					/*
-					 * pull out the scope_id from
-					 * incoming pkt
-					 */
+					/* pull out the scope_id from
+					 * incoming pkt */
 				} else if (IN6_IS_ADDR_SITELOCAL(&src6->sin6_addr) ||
 				    IN6_IS_ADDR_SITELOCAL(&dst6->sin6_addr)) {
 					/*
@@ -5746,7 +5706,6 @@ do_a_abort:
 
 #ifdef INET6
 		struct sctp_nets *lnet;
-
 #endif
 
 		stc.loopback_scope = asoc->scope.loopback_scope;
@@ -6208,9 +6167,9 @@ sctp_prune_prsctp(struct sctp_tcb *stcb,
 						if (freed_spc >= dataout) {
 							return;
 						}
-					}	/* if chunk was present */
-				}	/* if of sufficient priority */
-			}	/* if chunk has enabled */
+					} /* if chunk was present */ 
+				} /* if of sufficient priority */ 
+			} /* if chunk has enabled */ 
 		}		/* tailqforeach */
 
 		TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
@@ -6231,11 +6190,11 @@ sctp_prune_prsctp(struct sctp_tcb *stcb,
 						if (freed_spc >= dataout) {
 							return;
 						}
-					}	/* end if chk->data */
-				}	/* end if right class */
-			}	/* end if chk pr-sctp */
+					} /* end if chk->data */ 
+				} /* end if right class */ 
+			} /* end if chk pr-sctp */ 
 		}		/* tailqforeachsafe (chk) */
-	}			/* if enabled in asoc */
+	} /* if enabled in asoc */ 
 }
 
 int
@@ -6391,7 +6350,7 @@ sctp_msg_append(struct sctp_tcb *stcb,
 		sp->net = NULL;
 	}
 	(void)SCTP_GETTIME_TIMEVAL(&sp->ts);
-	sp->stream = srcv->sinfo_stream;
+	sp->sid = srcv->sinfo_stream;
 	sp->msg_is_complete = 1;
 	sp->sender_all_done = 1;
 	sp->some_taken = 0;
@@ -6478,10 +6437,8 @@ error_out:
 					/* get the prepend space */
 					SCTP_BUF_RESV_UF(outchain, (SCTP_FIRST_MBUF_RESV + 4));
 				} else {
-					/*
-					 * We really should not get a NULL
-					 * in endofchain
-					 */
+					/* We really should not get a NULL
+					 * in endofchain */
 					/* find end */
 					m = outchain;
 					while (m) {
@@ -6493,10 +6450,8 @@ error_out:
 					}
 					/* sanity */
 					if (*endofchain == NULL) {
-						/*
-						 * huh, TSNH XXX maybe we
-						 * should panic
-						 */
+						/* huh, TSNH XXX maybe we
+						 * should panic */
 						sctp_m_freem(outchain);
 						goto new_mbuf;
 					}
@@ -6695,17 +6650,13 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
 				if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) {
 					goto abort_anyway;
 				}
-				/*
-				 * there is nothing queued to send, so I'm
-				 * done...
-				 */
+				/* there is nothing queued to send, so I'm
+				 * done... */
 				if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
 				    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
 				    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
-					/*
-					 * only send SHUTDOWN the first time
-					 * through
-					 */
+					/* only send SHUTDOWN the first time
+					 * through */
 					if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
 						SCTP_STAT_DECR_GAUGE32(sctps_currestab);
 					}
@@ -6982,14 +6933,14 @@ sctp_clean_up_datalist(struct sctp_tcb *stcb,
 		/* record time */
 		data_list[i]->sent_rcv_time = net->last_sent_time;
 		data_list[i]->rec.data.cwnd_at_send = net->cwnd;
-		data_list[i]->rec.data.fast_retran_tsn = data_list[i]->rec.data.TSN_seq;
+		data_list[i]->rec.data.fast_retran_tsn = data_list[i]->rec.data.tsn;
 		if (data_list[i]->whoTo == NULL) {
 			data_list[i]->whoTo = net;
 			atomic_add_int(&net->ref_count, 1);
 		}
 		/* on to the sent queue */
 		tp1 = TAILQ_LAST(&asoc->sent_queue, sctpchunk_listhead);
-		if ((tp1) && SCTP_TSN_GT(tp1->rec.data.TSN_seq, data_list[i]->rec.data.TSN_seq)) {
+		if ((tp1) && SCTP_TSN_GT(tp1->rec.data.tsn, data_list[i]->rec.data.tsn)) {
 			struct sctp_tmit_chunk *tpp;
 
 			/* need to move back */
@@ -7000,7 +6951,7 @@ sctp_clean_up_datalist(struct sctp_tcb *stcb,
 				goto all_done;
 			}
 			tp1 = tpp;
-			if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, data_list[i]->rec.data.TSN_seq)) {
+			if (SCTP_TSN_GT(tp1->rec.data.tsn, data_list[i]->rec.data.tsn)) {
 				goto back_up_more;
 			}
 			TAILQ_INSERT_AFTER(&asoc->sent_queue, tp1, data_list[i], sctp_next);
@@ -7029,7 +6980,7 @@ all_done:
 			    data_list[i]->whoTo->flight_size,
 			    data_list[i]->book_size,
 			    (uint32_t) (uintptr_t) data_list[i]->whoTo,
-			    data_list[i]->rec.data.TSN_seq);
+			    data_list[i]->rec.data.tsn);
 		}
 		sctp_flight_size_increase(data_list[i]);
 		sctp_total_flight_increase(stcb, data_list[i]);
@@ -7197,7 +7148,7 @@ one_more_time:
 		    (stcb->asoc.idata_supported == 0) &&
 		    (strq->last_msg_incomplete)) {
 			SCTP_PRINTF("Huh? Stream:%d lm_in_c=%d but queue is NULL\n",
-			    strq->stream_no,
+			    strq->sid,
 			    strq->last_msg_incomplete);
 			strq->last_msg_incomplete = 0;
 		}
@@ -7336,10 +7287,8 @@ re_look:
 					SCTP_TCB_SEND_LOCK(stcb);
 					send_lock_up = 1;
 					if (sp->msg_is_complete) {
-						/*
-						 * the sender finished the
-						 * msg
-						 */
+						/* the sender finished the
+						 * msg */
 						goto re_look;
 					}
 				}
@@ -7546,28 +7495,28 @@ dont_do_it:
 	if (stcb->asoc.idata_supported == 0) {
 		if (rcv_flags & SCTP_DATA_UNORDERED) {
 			/* Just use 0. The receiver ignores the values. */
-			chk->rec.data.stream_seq = 0;
+			chk->rec.data.mid = 0;
 		} else {
-			chk->rec.data.stream_seq = strq->next_mid_ordered;
+			chk->rec.data.mid = strq->next_mid_ordered;
 			if (rcv_flags & SCTP_DATA_LAST_FRAG) {
 				strq->next_mid_ordered++;
 			}
 		}
 	} else {
 		if (rcv_flags & SCTP_DATA_UNORDERED) {
-			chk->rec.data.stream_seq = strq->next_mid_unordered;
+			chk->rec.data.mid = strq->next_mid_unordered;
 			if (rcv_flags & SCTP_DATA_LAST_FRAG) {
 				strq->next_mid_unordered++;
 			}
 		} else {
-			chk->rec.data.stream_seq = strq->next_mid_ordered;
+			chk->rec.data.mid = strq->next_mid_ordered;
 			if (rcv_flags & SCTP_DATA_LAST_FRAG) {
 				strq->next_mid_ordered++;
 			}
 		}
 	}
-	chk->rec.data.stream_number = sp->stream;
-	chk->rec.data.payloadtype = sp->ppid;
+	chk->rec.data.sid = sp->sid;
+	chk->rec.data.ppid = sp->ppid;
 	chk->rec.data.context = sp->context;
 	chk->rec.data.doing_fast_retransmit = 0;
 
@@ -7585,12 +7534,12 @@ dont_do_it:
 		sctp_auth_key_acquire(stcb, chk->auth_keyid);
 		chk->holds_key_ref = 1;
 	}
-	chk->rec.data.TSN_seq = atomic_fetchadd_int(&asoc->sending_seq, 1);
+	chk->rec.data.tsn = atomic_fetchadd_int(&asoc->sending_seq, 1);
 	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_AT_SEND_2_OUTQ) {
 		sctp_misc_ints(SCTP_STRMOUT_LOG_SEND,
 		    (uint32_t) (uintptr_t) stcb, sp->length,
-		    (uint32_t) ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq),
-		    chk->rec.data.TSN_seq);
+		    (uint32_t) ((chk->rec.data.sid << 16) | (0x0000ffff & chk->rec.data.mid)),
+		    chk->rec.data.tsn);
 	}
 	if (stcb->asoc.idata_supported == 0) {
 		dchkh = mtod(chk->data, struct sctp_data_chunk *);
@@ -7608,9 +7557,9 @@ dont_do_it:
 		asoc->tsn_out_at = 0;
 		asoc->tsn_out_wrapped = 1;
 	}
-	asoc->out_tsnlog[asoc->tsn_out_at].tsn = chk->rec.data.TSN_seq;
-	asoc->out_tsnlog[asoc->tsn_out_at].strm = chk->rec.data.stream_number;
-	asoc->out_tsnlog[asoc->tsn_out_at].seq = chk->rec.data.stream_seq;
+	asoc->out_tsnlog[asoc->tsn_out_at].tsn = chk->rec.data.tsn;
+	asoc->out_tsnlog[asoc->tsn_out_at].strm = chk->rec.data.sid;
+	asoc->out_tsnlog[asoc->tsn_out_at].seq = chk->rec.data.mid;
 	asoc->out_tsnlog[asoc->tsn_out_at].sz = chk->send_size;
 	asoc->out_tsnlog[asoc->tsn_out_at].flgs = chk->rec.data.rcv_flags;
 	asoc->out_tsnlog[asoc->tsn_out_at].stcb = (void *)stcb;
@@ -7621,20 +7570,20 @@ dont_do_it:
 	if (stcb->asoc.idata_supported == 0) {
 		dchkh->ch.chunk_type = SCTP_DATA;
 		dchkh->ch.chunk_flags = chk->rec.data.rcv_flags;
-		dchkh->dp.tsn = htonl(chk->rec.data.TSN_seq);
-		dchkh->dp.stream_id = htons((strq->stream_no & 0x0000ffff));
-		dchkh->dp.stream_sequence = htons((uint16_t) chk->rec.data.stream_seq);
-		dchkh->dp.protocol_id = chk->rec.data.payloadtype;
+		dchkh->dp.tsn = htonl(chk->rec.data.tsn);
+		dchkh->dp.sid = htons(strq->sid);
+		dchkh->dp.ssn = htons((uint16_t) chk->rec.data.mid);
+		dchkh->dp.ppid = chk->rec.data.ppid;
 		dchkh->ch.chunk_length = htons(chk->send_size);
 	} else {
 		ndchkh->ch.chunk_type = SCTP_IDATA;
 		ndchkh->ch.chunk_flags = chk->rec.data.rcv_flags;
-		ndchkh->dp.tsn = htonl(chk->rec.data.TSN_seq);
-		ndchkh->dp.stream_id = htons(strq->stream_no);
+		ndchkh->dp.tsn = htonl(chk->rec.data.tsn);
+		ndchkh->dp.sid = htons(strq->sid);
 		ndchkh->dp.reserved = htons(0);
-		ndchkh->dp.msg_id = htonl(chk->rec.data.stream_seq);
+		ndchkh->dp.mid = htonl(chk->rec.data.mid);
 		if (sp->fsn == 0)
-			ndchkh->dp.ppid_fsn.protocol_id = chk->rec.data.payloadtype;
+			ndchkh->dp.ppid_fsn.ppid = chk->rec.data.ppid;
 		else
 			ndchkh->dp.ppid_fsn.fsn = htonl(sp->fsn);
 		sp->fsn++;
@@ -7957,9 +7906,9 @@ nothing_to_send:
 			 * (when CMT is off) then it calls
 			 * sctp_fill_outqueue for the net. This gets data on
 			 * the send queue for that network.
-			 * 
-			 * In sctp_fill_outqueue TSN's are assigned and data is
-			 * copied out of the stream buffers. Note mostly
+			 *
+			 * In sctp_fill_outqueue TSN's are assigned and data
+			 * is copied out of the stream buffers. Note mostly
 			 * copy by reference (we hope).
 			 */
 			net->window_probe = 0;
@@ -8228,10 +8177,8 @@ again_one_more_time:
 					    net->port, NULL,
 					    0, 0,
 					    so_locked))) {
-						/*
-						 * error, we could not
-						 * output
-						 */
+						/* error, we could not
+						 * output */
 						SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
 						if (from_where == 0) {
 							SCTP_STAT_INCR(sctps_lowlevelerrusr);
@@ -8304,16 +8251,12 @@ again_one_more_time:
 				 * to where the sack is going..
 				 */
 				if (chk->whoTo == net) {
-					/*
-					 * Don't transmit it to where its
-					 * going (current net)
-					 */
+					/* Don't transmit it to where its
+					 * going (current net) */
 					continue;
 				} else if (sack_goes_to == net) {
-					/*
-					 * But do transmit it to this
-					 * address
-					 */
+					/* But do transmit it to this
+					 * address */
 					goto skip_net_check;
 				}
 			}
@@ -8506,10 +8449,8 @@ again_one_more_time:
 					    net->port, NULL,
 					    0, 0,
 					    so_locked))) {
-						/*
-						 * error, we could not
-						 * output
-						 */
+						/* error, we could not
+						 * output */
 						SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
 						if (from_where == 0) {
 							SCTP_STAT_INCR(sctps_lowlevelerrusr);
@@ -8706,17 +8647,13 @@ again_one_more_time:
 							override_ok = 0;
 							SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
 						} else if (override_ok) {
-							/*
-							 * use this data's
-							 * keyid
-							 */
+							/* use this data's
+							 * keyid */
 							auth_keyid = chk->auth_keyid;
 							override_ok = 0;
 						} else if (auth_keyid != chk->auth_keyid) {
-							/*
-							 * different keyid,
-							 * so done bundling
-							 */
+							/* different keyid,
+							 * so done bundling */
 							break;
 						}
 					}
@@ -8795,8 +8732,7 @@ again_one_more_time:
 					break;
 				}
 			}	/* for (chunk gather loop for this net) */
-		}		/* if asoc.state OPEN */
-no_data_fill:
+} /* if asoc.state OPEN */ no_data_fill:
 		/* Is there something to send for this destination? */
 		if (outchain) {
 			/* We may need to start a control timer or two */
@@ -8883,7 +8819,7 @@ no_data_fill:
 			}
 			if (bundle_at) {
 				/* setup for a RTO measurement */
-				tsns_sent = data_list[0]->rec.data.TSN_seq;
+				tsns_sent = data_list[0]->rec.data.tsn;
 				/* fill time if not already filled */
 				if (*now_filled == 0) {
 					(void)SCTP_GETTIME_TIMEVAL(&asoc->time_last_sent);
@@ -9564,7 +9500,7 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
 		}
 		if (chk->data == NULL) {
 			SCTP_PRINTF("TSN:%x chk->snd_count:%d chk->sent:%d can't retran - no data\n",
-			    chk->rec.data.TSN_seq, chk->snd_count, chk->sent);
+			    chk->rec.data.tsn, chk->snd_count, chk->sent);
 			continue;
 		}
 		if ((SCTP_BASE_SYSCTL(sctp_max_retran_chunk)) &&
@@ -9573,7 +9509,7 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
 			char msg[SCTP_DIAG_INFO_LEN];
 
 			snprintf(msg, sizeof(msg), "TSN %8.8x retransmitted %d times, giving up",
-			    chk->rec.data.TSN_seq, chk->snd_count);
+			    chk->rec.data.tsn, chk->snd_count);
 			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
 			    msg);
 			atomic_add_int(&stcb->asoc.refcnt, 1);
@@ -9607,7 +9543,7 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
 			uint32_t tsn;
 
 			tsn = asoc->last_acked_seq + 1;
-			if (tsn == chk->rec.data.TSN_seq) {
+			if (tsn == chk->rec.data.tsn) {
 				/*
 				 * we make a special exception for this
 				 * case. The peer has no rwnd but is missing
@@ -9736,10 +9672,8 @@ one_chunk_around:
 							auth_keyid = fwd->auth_keyid;
 							override_ok = 0;
 						} else if (fwd->auth_keyid != auth_keyid) {
-							/*
-							 * different keyid,
-							 * so done bundling
-							 */
+							/* different keyid,
+							 * so done bundling */
 							break;
 						}
 					}
@@ -9819,7 +9753,7 @@ one_chunk_around:
 			sctp_audit_log(0xC4, bundle_at);
 #endif
 			if (bundle_at) {
-				tsns_sent = data_list[0]->rec.data.TSN_seq;
+				tsns_sent = data_list[0]->rec.data.tsn;
 			}
 			for (i = 0; i < bundle_at; i++) {
 				SCTP_STAT_INCR(sctps_sendretransdata);
@@ -9869,7 +9803,7 @@ one_chunk_around:
 					    data_list[i]->whoTo->flight_size,
 					    data_list[i]->book_size,
 					    (uint32_t) (uintptr_t) data_list[i]->whoTo,
-					    data_list[i]->rec.data.TSN_seq);
+					    data_list[i]->rec.data.tsn);
 				}
 				sctp_flight_size_increase(data_list[i]);
 				sctp_total_flight_increase(stcb, data_list[i]);
@@ -10115,11 +10049,9 @@ do_it_again:
 			if (asoc->max_burst > 0) {
 				if (SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst)) {
 					if ((net->flight_size + (asoc->max_burst * net->mtu)) < net->cwnd) {
-						/*
-						 * JRS - Use the congestion
+						/* JRS - Use the congestion
 						 * control given in the
-						 * congestion control module
-						 */
+						 * congestion control module */
 						asoc->cc_functions.sctp_cwnd_update_after_output(stcb, net, asoc->max_burst);
 						if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_MAXBURST_ENABLE) {
 							sctp_log_maxburst(stcb, net, 0, asoc->max_burst, SCTP_MAX_BURST_APPLIED);
@@ -10129,10 +10061,8 @@ do_it_again:
 					net->fast_retran_ip = 0;
 				} else {
 					if (net->flight_size == 0) {
-						/*
-						 * Should be decaying the
-						 * cwnd here
-						 */
+						/* Should be decaying the
+						 * cwnd here */
 						;
 					}
 				}
@@ -10268,13 +10198,7 @@ send_forward_tsn(struct sctp_tcb *stcb,
 	unsigned int cnt_of_space, i, ovh;
 	unsigned int space_needed;
 	unsigned int cnt_of_skipped = 0;
-	int old;
 
-	if (asoc->idata_supported) {
-		old = 0;
-	} else {
-		old = 1;
-	}
 	SCTP_TCB_LOCK_ASSERT(stcb);
 	TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
 		if (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN) {
@@ -10328,18 +10252,18 @@ sctp_fill_in_rest:
 			/* no more to look at */
 			break;
 		}
-		if (old && (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED)) {
+		if (!asoc->idata_supported && (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED)) {
 			/* We don't report these */
 			continue;
 		}
 		cnt_of_skipped++;
 	}
-	if (old) {
+	if (asoc->idata_supported) {
 		space_needed = (sizeof(struct sctp_forward_tsn_chunk) +
-		    (cnt_of_skipped * sizeof(struct sctp_strseq)));
+		    (cnt_of_skipped * sizeof(struct sctp_strseq_mid)));
 	} else {
 		space_needed = (sizeof(struct sctp_forward_tsn_chunk) +
-		    (cnt_of_skipped * sizeof(struct sctp_strseq_mid)));
+		    (cnt_of_skipped * sizeof(struct sctp_strseq)));
 	}
 	cnt_of_space = (unsigned int)M_TRAILINGSPACE(chk->data);
 
@@ -10368,12 +10292,11 @@ sctp_fill_in_rest:
 			    0xff, 0xff, cnt_of_space,
 			    space_needed);
 		}
-		if (old) {
-			cnt_of_skipped = cnt_of_space - sizeof(struct sctp_forward_tsn_chunk);
-			cnt_of_skipped /= sizeof(struct sctp_strseq);
-		} else {
-			cnt_of_skipped = cnt_of_space - sizeof(struct sctp_forward_tsn_chunk);
+		cnt_of_skipped = cnt_of_space - sizeof(struct sctp_forward_tsn_chunk);
+		if (asoc->idata_supported) {
 			cnt_of_skipped /= sizeof(struct sctp_strseq_mid);
+		} else {
+			cnt_of_skipped /= sizeof(struct sctp_strseq);
 		}
 		/*-
 		 * Go through and find the TSN that will be the one
@@ -10391,7 +10314,7 @@ sctp_fill_in_rest:
 		}
 		if (at && SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_TRY_ADVANCE) {
 			sctp_misc_ints(SCTP_FWD_TSN_CHECK,
-			    0xff, cnt_of_skipped, at->rec.data.TSN_seq,
+			    0xff, cnt_of_skipped, at->rec.data.tsn,
 			    asoc->advanced_peer_ack_point);
 		}
 		last = at;
@@ -10400,14 +10323,14 @@ sctp_fill_in_rest:
 		 * peer ack point
 		 */
 		if (last) {
-			advance_peer_ack_point = last->rec.data.TSN_seq;
+			advance_peer_ack_point = last->rec.data.tsn;
 		}
-		if (old) {
+		if (asoc->idata_supported) {
 			space_needed = sizeof(struct sctp_forward_tsn_chunk) +
-			    cnt_of_skipped * sizeof(struct sctp_strseq);
+			    cnt_of_skipped * sizeof(struct sctp_strseq_mid);
 		} else {
 			space_needed = sizeof(struct sctp_forward_tsn_chunk) +
-			    cnt_of_skipped * sizeof(struct sctp_strseq_mid);
+			    cnt_of_skipped * sizeof(struct sctp_strseq);
 		}
 	}
 	chk->send_size = space_needed;
@@ -10415,10 +10338,10 @@ sctp_fill_in_rest:
 	fwdtsn = mtod(chk->data, struct sctp_forward_tsn_chunk *);
 	fwdtsn->ch.chunk_length = htons(chk->send_size);
 	fwdtsn->ch.chunk_flags = 0;
-	if (old) {
-		fwdtsn->ch.chunk_type = SCTP_FORWARD_CUM_TSN;
-	} else {
+	if (asoc->idata_supported) {
 		fwdtsn->ch.chunk_type = SCTP_IFORWARD_CUM_TSN;
+	} else {
+		fwdtsn->ch.chunk_type = SCTP_FORWARD_CUM_TSN;
 	}
 	fwdtsn->new_cumulative_tsn = htonl(advance_peer_ack_point);
 	SCTP_BUF_LEN(chk->data) = chk->send_size;
@@ -10427,10 +10350,12 @@ sctp_fill_in_rest:
 	 * Move pointer to after the fwdtsn and transfer to the
 	 * strseq pointer.
 	 */
-	if (old) {
-		strseq = (struct sctp_strseq *)fwdtsn;
-	} else {
+	if (asoc->idata_supported) {
 		strseq_m = (struct sctp_strseq_mid *)fwdtsn;
+		strseq = NULL;
+	} else {
+		strseq = (struct sctp_strseq *)fwdtsn;
+		strseq_m = NULL;
 	}
 	/*-
 	 * Now populate the strseq list. This is done blindly
@@ -10449,26 +10374,26 @@ sctp_fill_in_rest:
 		if (i >= cnt_of_skipped) {
 			break;
 		}
-		if (old && (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED)) {
+		if (!asoc->idata_supported && (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED)) {
 			/* We don't report these */
 			continue;
 		}
-		if (at->rec.data.TSN_seq == advance_peer_ack_point) {
+		if (at->rec.data.tsn == advance_peer_ack_point) {
 			at->rec.data.fwd_tsn_cnt = 0;
 		}
-		if (old) {
-			strseq->stream = htons(at->rec.data.stream_number);
-			strseq->sequence = htons((uint16_t) at->rec.data.stream_seq);
-			strseq++;
-		} else {
-			strseq_m->stream = htons(at->rec.data.stream_number);
+		if (asoc->idata_supported) {
+			strseq_m->sid = htons(at->rec.data.sid);
 			if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) {
 				strseq_m->flags = htons(PR_SCTP_UNORDERED_FLAG);
 			} else {
 				strseq_m->flags = 0;
 			}
-			strseq_m->msg_id = htonl(at->rec.data.stream_seq);
+			strseq_m->mid = htonl(at->rec.data.mid);
 			strseq_m++;
+		} else {
+			strseq->sid = htons(at->rec.data.sid);
+			strseq->ssn = htons((uint16_t) at->rec.data.mid);
+			strseq++;
 		}
 		i++;
 	}
@@ -11019,23 +10944,18 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
 	struct mbuf *mout;
 	struct sctphdr *shout;
 	struct sctp_chunkhdr *ch;
-
 #if defined(INET) || defined(INET6)
 	struct udphdr *udp;
 	int ret;
-
 #endif
 	int len, cause_len, padding_len;
-
 #ifdef INET
 	struct sockaddr_in *src_sin, *dst_sin;
 	struct ip *ip;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 *src_sin6, *dst_sin6;
 	struct ip6_hdr *ip6;
-
 #endif
 
 	/* Compute the length of the cause and add final padding. */
@@ -11624,10 +11544,8 @@ sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn, u
 	asoc = &stcb->asoc;
 	TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
 		if ((chk->rec.chunk_id.id == SCTP_ECN_CWR) && (net == chk->whoTo)) {
-			/*
-			 * found a previous CWR queued to same destination
-			 * update it if needed
-			 */
+			/* found a previous CWR queued to same destination
+			 * update it if needed */
 			uint32_t ctsn;
 
 			cwr = mtod(chk->data, struct sctp_cwr_chunk *);
@@ -12171,10 +12089,8 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
 		struct sctp_stream_out *oldstream;
 		struct sctp_stream_queue_pending *sp, *nsp;
 		int i;
-
 #if defined(SCTP_DETAILED_STR_STATS)
 		int j;
-
 #endif
 
 		oldstream = stcb->asoc.strmout;
@@ -12203,13 +12119,11 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
 			stcb->asoc.strmout[i].next_mid_ordered = oldstream[i].next_mid_ordered;
 			stcb->asoc.strmout[i].next_mid_unordered = oldstream[i].next_mid_unordered;
 			stcb->asoc.strmout[i].last_msg_incomplete = oldstream[i].last_msg_incomplete;
-			stcb->asoc.strmout[i].stream_no = i;
+			stcb->asoc.strmout[i].sid = i;
 			stcb->asoc.strmout[i].state = oldstream[i].state;
 			/* FIX ME FIX ME */
-			/*
-			 * This should be a SS_COPY operation FIX ME STREAM
-			 * SCHEDULER EXPERT
-			 */
+			/* This should be a SS_COPY operation FIX ME STREAM
+			 * SCHEDULER EXPERT */
 			stcb->asoc.ss_functions.sctp_ss_init_stream(stcb, &stcb->asoc.strmout[i], &oldstream[i]);
 			/* now anything on those queues? */
 			TAILQ_FOREACH_SAFE(sp, &oldstream[i].outqueue, next, nsp) {
@@ -12234,7 +12148,7 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
 #endif
 			stcb->asoc.strmout[i].next_mid_ordered = 0;
 			stcb->asoc.strmout[i].next_mid_unordered = 0;
-			stcb->asoc.strmout[i].stream_no = i;
+			stcb->asoc.strmout[i].sid = i;
 			stcb->asoc.strmout[i].last_msg_incomplete = 0;
 			stcb->asoc.ss_functions.sctp_ss_init_stream(stcb, &stcb->asoc.strmout[i], NULL);
 			stcb->asoc.strmout[i].state = SCTP_STREAM_CLOSED;
@@ -12393,7 +12307,7 @@ sctp_copy_it_in(struct sctp_tcb *stcb,
 	sp->fsn = 0;
 	(void)SCTP_GETTIME_TIMEVAL(&sp->ts);
 
-	sp->stream = srcv->sinfo_stream;
+	sp->sid = srcv->sinfo_stream;
 	sp->length = (uint32_t) min(uio->uio_resid, max_send_len);
 	if ((sp->length == (uint32_t) uio->uio_resid) &&
 	    ((user_marks_eor == 0) ||
@@ -12453,10 +12367,8 @@ sctp_sosend(struct socket *so,
 	int error, use_sndinfo = 0;
 	struct sctp_sndrcvinfo sndrcvninfo;
 	struct sockaddr *addr_to_use;
-
 #if defined(INET) && defined(INET6)
 	struct sockaddr_in sin;
-
 #endif
 
 	if (control) {
@@ -12741,10 +12653,8 @@ sctp_lower_sosend(struct socket *so,
 			}
 			if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
 				stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
-				/*
-				 * Set the connected flag so we can queue
-				 * data
-				 */
+				/* Set the connected flag so we can queue
+				 * data */
 				soisconnecting(so);
 			}
 			hold_tcblock = 1;
@@ -12754,10 +12664,8 @@ sctp_lower_sosend(struct socket *so,
 			} else {
 				SCTP_PRINTF("Huh-3? create lock should have been on??\n");
 			}
-			/*
-			 * Turn on queue only flag to prevent data from
-			 * being sent
-			 */
+			/* Turn on queue only flag to prevent data from
+			 * being sent */
 			queue_only = 1;
 			asoc = &stcb->asoc;
 			SCTP_SET_STATE(asoc, SCTP_STATE_COOKIE_WAIT);
@@ -13252,10 +13160,8 @@ skip_preblock:
 			}
 			/* PR-SCTP? */
 			if ((asoc->prsctp_supported) && (asoc->sent_queue_cnt_removeable > 0)) {
-				/*
-				 * This is ugly but we must assure locking
-				 * order
-				 */
+				/* This is ugly but we must assure locking
+				 * order */
 				if (hold_tcblock == 0) {
 					SCTP_TCB_LOCK(stcb);
 					hold_tcblock = 1;
@@ -13532,10 +13438,8 @@ dataless_eof:
 					    msg);
 					sctp_abort_an_association(stcb->sctp_ep, stcb,
 					    op_err, SCTP_SO_LOCKED);
-					/*
-					 * now relock the stcb so everything
-					 * is sane
-					 */
+					/* now relock the stcb so everything
+					 * is sane */
 					hold_tcblock = 0;
 					stcb = NULL;
 					goto out;
@@ -13609,10 +13513,8 @@ skip_out_eof:
 	if ((queue_only == 0) && (nagle_applies == 0) && (stcb->asoc.peers_rwnd && un_sent)) {
 		/* we can attempt to send too. */
 		if (hold_tcblock == 0) {
-			/*
-			 * If there is activity recv'ing sacks no need to
-			 * send
-			 */
+			/* If there is activity recv'ing sacks no need to
+			 * send */
 			if (SCTP_TCB_TRYLOCK(stcb)) {
 				sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_USR_SEND, SCTP_SO_LOCKED);
 				hold_tcblock = 1;
@@ -13751,6 +13653,7 @@ sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t * ro)
 		return (0);
 
 	/* get prefix entry of address */
+	ND6_RLOCK();
 	LIST_FOREACH(pfx, &MODULE_GLOBAL(nd_prefix), ndpr_entry) {
 		if (pfx->ndpr_stateflags & NDPRF_DETACHED)
 			continue;
@@ -13760,6 +13663,7 @@ sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t * ro)
 	}
 	/* no prefix entry in the prefix list */
 	if (pfx == NULL) {
+		ND6_RUNLOCK();
 		SCTPDBG(SCTP_DEBUG_OUTPUT2, "No prefix entry for ");
 		SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)src6);
 		return (0);
@@ -13778,16 +13682,16 @@ sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t * ro)
 		SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)&gw6);
 		SCTPDBG(SCTP_DEBUG_OUTPUT2, "installed router is ");
 		SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, ro->ro_rt->rt_gateway);
-		if (sctp_cmpaddr((struct sockaddr *)&gw6,
-		    ro->ro_rt->rt_gateway)) {
+		if (sctp_cmpaddr((struct sockaddr *)&gw6, ro->ro_rt->rt_gateway)) {
+			ND6_RUNLOCK();
 			SCTPDBG(SCTP_DEBUG_OUTPUT2, "pfxrouter is installed\n");
 			return (1);
 		}
 	}
+	ND6_RUNLOCK();
 	SCTPDBG(SCTP_DEBUG_OUTPUT2, "pfxrouter is not installed\n");
 	return (0);
 }
-
 #endif
 
 int
diff --git a/freebsd/sys/netinet/sctp_pcb.c b/freebsd/sys/netinet/sctp_pcb.c
index 62ef1e3..ca86a13 100644
--- a/freebsd/sys/netinet/sctp_pcb.c
+++ b/freebsd/sys/netinet/sctp_pcb.c
@@ -79,7 +79,6 @@ SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
 	}
 	return (IN6_ARE_ADDR_EQUAL(&tmp_a.sin6_addr, &tmp_b.sin6_addr));
 }
-
 #endif
 
 void
@@ -839,14 +838,11 @@ static int
 sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
 {
 	int loopback_scope;
-
 #if defined(INET)
 	int ipv4_local_scope, ipv4_addr_legal;
-
 #endif
 #if defined(INET6)
 	int local_scope, site_scope, ipv6_addr_legal;
-
 #endif
 	struct sctp_vrf *vrf;
 	struct sctp_ifn *sctp_ifn;
@@ -1218,10 +1214,8 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
 						if (netp != NULL) {
 							*netp = net;
 						}
-						/*
-						 * Update the endpoint
-						 * pointer
-						 */
+						/* Update the endpoint
+						 * pointer */
 						*inp_p = inp;
 						SCTP_INP_RUNLOCK(inp);
 						return (stcb);
@@ -1242,10 +1236,8 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
 						if (netp != NULL) {
 							*netp = net;
 						}
-						/*
-						 * Update the endpoint
-						 * pointer
-						 */
+						/* Update the endpoint
+						 * pointer */
 						*inp_p = inp;
 						SCTP_INP_RUNLOCK(inp);
 						return (stcb);
@@ -1624,15 +1616,12 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
 {
 	struct sctp_inpcb *inp;
 	struct sctp_laddr *laddr;
-
 #ifdef INET
 	struct sockaddr_in *sin;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 *sin6;
 	struct sockaddr_in6 *intf_addr6;
-
 #endif
 	int fnd;
 
@@ -1675,10 +1664,8 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
 			case AF_INET:
 				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
 				    SCTP_IPV6_V6ONLY(inp)) {
-					/*
-					 * IPv4 on a IPv6 socket with ONLY
-					 * IPv6 set
-					 */
+					/* IPv4 on a IPv6 socket with ONLY
+					 * IPv6 set */
 					SCTP_INP_RUNLOCK(inp);
 					continue;
 				}
@@ -1691,10 +1678,8 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
 #endif
 #ifdef INET6
 			case AF_INET6:
-				/*
-				 * A V6 address and the endpoint is NOT
-				 * bound V6
-				 */
+				/* A V6 address and the endpoint is NOT
+				 * bound V6 */
 				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
 					SCTP_INP_RUNLOCK(inp);
 					continue;
@@ -1928,14 +1913,11 @@ sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock,
 	struct sctppcbhead *head;
 	int lport;
 	unsigned int i;
-
 #ifdef INET
 	struct sockaddr_in *sin;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 *sin6;
-
 #endif
 
 	switch (nam->sa_family) {
@@ -2059,21 +2041,16 @@ sctp_findassociation_special_addr(struct mbuf *m, int offset,
     struct sockaddr *dst)
 {
 	struct sctp_paramhdr *phdr, parm_buf;
-
 #if defined(INET) || defined(INET6)
 	struct sctp_tcb *stcb;
 	uint16_t ptype;
-
 #endif
 	uint16_t plen;
-
 #ifdef INET
 	struct sockaddr_in sin4;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 sin6;
-
 #endif
 
 #ifdef INET
@@ -2200,10 +2177,8 @@ sctp_findassoc_by_vtag(struct sockaddr *from, struct sockaddr *to, uint32_t vtag
 				continue;
 			}
 			if (remote_tag) {
-				/*
-				 * If we have both vtags that's all we match
-				 * on
-				 */
+				/* If we have both vtags that's all we match
+				 * on */
 				if (stcb->asoc.peer_vtag == remote_tag) {
 					/*
 					 * If both tags match we consider it
@@ -2321,14 +2296,11 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
 	struct sctp_paramhdr parm_buf, *phdr;
 	int ptype;
 	int zero_address = 0;
-
 #ifdef INET
 	struct sockaddr_in *sin;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 *sin6;
-
 #endif
 
 	memset(&remote_store, 0, sizeof(remote_store));
@@ -2899,10 +2871,8 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
 #ifdef INET6
 		case AF_INET6:
 			{
-				/*
-				 * Only for pure IPv6 Address. (No IPv4
-				 * Mapped!)
-				 */
+				/* Only for pure IPv6 Address. (No IPv4
+				 * Mapped!) */
 				struct sockaddr_in6 *sin6;
 
 				sin6 = (struct sockaddr_in6 *)addr;
@@ -2979,10 +2949,8 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
 				/* unlock info */
 				if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) &&
 				    (sctp_is_feature_on(inp_tmp, SCTP_PCB_FLAGS_PORTREUSE))) {
-					/*
-					 * Ok, must be one-2-one and
-					 * allowing port re-use
-					 */
+					/* Ok, must be one-2-one and
+					 * allowing port re-use */
 					port_reuse_active = 1;
 					goto continue_anyway;
 				}
@@ -3005,10 +2973,8 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
 				/* unlock info */
 				if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) &&
 				    (sctp_is_feature_on(inp_tmp, SCTP_PCB_FLAGS_PORTREUSE))) {
-					/*
-					 * Ok, must be one-2-one and
-					 * allowing port re-use
-					 */
+					/* Ok, must be one-2-one and
+					 * allowing port re-use */
 					port_reuse_active = 1;
 					goto continue_anyway;
 				}
@@ -3148,11 +3114,11 @@ continue_anyway:
 		 * bind specific, make sure flags is off and add a new
 		 * address structure to the sctp_addr_list inside the ep
 		 * structure.
-		 * 
-		 * We will need to allocate one and insert it at the head. The
-		 * socketopt call can just insert new addresses in there as
-		 * well. It will also have to do the embed scope kame hack
-		 * too (before adding).
+		 *
+		 * We will need to allocate one and insert it at the head.
+		 * The socketopt call can just insert new addresses in there
+		 * as well. It will also have to do the embed scope kame
+		 * hack too (before adding).
 		 */
 		struct sctp_ifa *ifa;
 		union sctp_sockstore store;
@@ -3270,11 +3236,11 @@ sctp_iterator_inp_being_freed(struct sctp_inpcb *inp)
 		 * from happening. But of course the iterator has a
 		 * reference on the stcb and inp. We can mark it and it will
 		 * stop.
-		 * 
-		 * If its a single iterator situation, we set the end iterator
-		 * flag. Otherwise we set the iterator to go to the next
-		 * inp.
-		 * 
+		 *
+		 * If its a single iterator situation, we set the end
+		 * iterator flag. Otherwise we set the iterator to go to the
+		 * next inp.
+		 *
 		 */
 		if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
 			sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
@@ -3307,10 +3273,8 @@ sctp_iterator_inp_being_freed(struct sctp_inpcb *inp)
 					SCTP_INP_INCR_REF(it->inp);
 				}
 			}
-			/*
-			 * When its put in the refcnt is incremented so decr
-			 * it
-			 */
+			/* When its put in the refcnt is incremented so decr
+			 * it */
 			SCTP_INP_DECR_REF(inp);
 		}
 	}
@@ -3995,10 +3959,8 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
 
 			rmtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, net->ro.ro_rt);
 			if (rmtu == 0) {
-				/*
-				 * Start things off to match mtu of
-				 * interface please.
-				 */
+				/* Start things off to match mtu of
+				 * interface please. */
 				SCTP_SET_MTU_OF_ROUTE(&net->ro._l_addr.sa,
 				    net->ro.ro_rt, net->mtu);
 			} else {
@@ -4820,7 +4782,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
 						uint32_t strseq;
 
 						stcb->asoc.control_pdapi = sq;
-						strseq = (sq->sinfo_stream << 16) | sq->sinfo_ssn;
+						strseq = (sq->sinfo_stream << 16) | (sq->mid & 0x0000ffff);
 						sctp_ulp_notify(SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION,
 						    stcb,
 						    SCTP_PARTIAL_DELIVERY_ABORTED,
@@ -4912,6 +4874,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
 					    SS_ISCONNECTED);
 				}
 				socantrcvmore_locked(so);
+				socantsendmore(so);
 				sctp_sowwakeup(inp, so);
 				sctp_sorwakeup(inp, so);
 				SCTP_SOWAKEUP(so);
@@ -5040,11 +5003,11 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
 	}
 	/* pending send queue SHOULD be empty */
 	TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
-		if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
-			asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
+		if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
+			asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
 #ifdef INVARIANTS
 		} else {
-			panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number);
+			panic("No chunks on the queues for sid %u.", chk->rec.data.sid);
 #endif
 		}
 		TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
@@ -5072,11 +5035,11 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
 	/* sent queue SHOULD be empty */
 	TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
 		if (chk->sent != SCTP_DATAGRAM_NR_ACKED) {
-			if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
-				asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
+			if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
+				asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
 #ifdef INVARIANTS
 			} else {
-				panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number);
+				panic("No chunks on the queues for sid %u.", chk->rec.data.sid);
 #endif
 			}
 		}
@@ -5488,10 +5451,8 @@ sctp_del_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa)
 			if (stcb->asoc.last_used_address == laddr)
 				/* delete this address */
 				stcb->asoc.last_used_address = NULL;
-			/*
-			 * Now spin through all the nets and purge any ref
-			 * to laddr
-			 */
+			/* Now spin through all the nets and purge any ref
+			 * to laddr */
 			TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
 				if (net->ro._s_addr == laddr->ifa) {
 					/* Yep, purge src address selected */
@@ -5759,7 +5720,6 @@ sctp_startup_mcore_threads(void)
 
 	}
 }
-
 #endif
 
 void
@@ -6101,14 +6061,11 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
 	uint8_t peer_supports_nrsack;
 	uint8_t peer_supports_pktdrop;
 	uint8_t peer_supports_idata;
-
 #ifdef INET
 	struct sockaddr_in sin;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 sin6;
-
 #endif
 
 	/* First get the destination address setup too. */
@@ -6271,10 +6228,8 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
 							struct mbuf *op_err;
 							char msg[SCTP_DIAG_INFO_LEN];
 
-							/*
-							 * in setup state we
-							 * abort this guy
-							 */
+							/* in setup state we
+							 * abort this guy */
 							snprintf(msg, sizeof(msg),
 							    "%s:%d at %s", __FILE__, __LINE__, __func__);
 							op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
@@ -6316,10 +6271,8 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
 					goto next_param;
 				}
 				if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) {
-					/*
-					 * Link local make no sense without
-					 * scope
-					 */
+					/* Link local make no sense without
+					 * scope */
 					goto next_param;
 				}
 				sa = (struct sockaddr *)&sin6;
@@ -6370,10 +6323,8 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
 							struct mbuf *op_err;
 							char msg[SCTP_DIAG_INFO_LEN];
 
-							/*
-							 * in setup state we
-							 * abort this guy
-							 */
+							/* in setup state we
+							 * abort this guy */
 							snprintf(msg, sizeof(msg),
 							    "%s:%d at %s", __FILE__, __LINE__, __func__);
 							op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
@@ -6413,10 +6364,8 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
 			struct sctp_asconf_addr_param lstore, *fee;
 			int lptype;
 			struct sockaddr *lsa = NULL;
-
 #ifdef INET
 			struct sctp_asconf_addrv4_param *fii;
-
 #endif
 
 			if (stcb->asoc.asconf_supported == 0) {
@@ -6896,7 +6845,7 @@ sctp_drain_mbufs(struct sctp_tcb *stcb)
 				/* Now its reasm? */
 				TAILQ_FOREACH_SAFE(chk, &ctl->reasm, sctp_next, nchk) {
 					cnt++;
-					SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.TSN_seq, asoc->mapping_array_base_tsn);
+					SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.tsn, asoc->mapping_array_base_tsn);
 					asoc->size_on_reasm_queue = sctp_sbspace_sub(asoc->size_on_reasm_queue, chk->send_size);
 					sctp_ucount_decr(asoc->cnt_on_reasm_queue);
 					SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
@@ -6938,7 +6887,7 @@ sctp_drain_mbufs(struct sctp_tcb *stcb)
 				/* Now its reasm? */
 				TAILQ_FOREACH_SAFE(chk, &ctl->reasm, sctp_next, nchk) {
 					cnt++;
-					SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.TSN_seq, asoc->mapping_array_base_tsn);
+					SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.tsn, asoc->mapping_array_base_tsn);
 					asoc->size_on_reasm_queue = sctp_sbspace_sub(asoc->size_on_reasm_queue, chk->send_size);
 					sctp_ucount_decr(asoc->cnt_on_reasm_queue);
 					SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
diff --git a/freebsd/sys/netinet/sctp_pcb.h b/freebsd/sys/netinet/sctp_pcb.h
index 9820409..a2a1e7d 100644
--- a/freebsd/sys/netinet/sctp_pcb.h
+++ b/freebsd/sys/netinet/sctp_pcb.h
@@ -353,7 +353,6 @@ struct sctp_pcbtsn_rlog {
 	uint16_t sz;
 	uint16_t flgs;
 };
-
 #define SCTP_READ_LOG_SIZE 135	/* we choose the number to make a pcb a page */
 
 
@@ -380,10 +379,8 @@ struct sctp_inpcb {
 
 	/* list of addrs in use by the EP, NULL if bound-all */
 	struct sctpladdr sctp_addr_list;
-	/*
-	 * used for source address selection rotation when we are subset
-	 * bound
-	 */
+	/* used for source address selection rotation when we are subset
+	 * bound */
 	struct sctp_laddr *next_addr_touse;
 
 	/* back pointer to our socket */
@@ -490,7 +487,6 @@ VNET_DECLARE(struct sctp_base_info, system_base_info);
 
 #ifdef INET6
 int SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b);
-
 #endif
 
 void sctp_fill_pcbinfo(struct sctp_pcbinfo *);
@@ -646,7 +642,6 @@ sctp_initiate_iterator(inp_func inpf,
     end_func ef,
     struct sctp_inpcb *,
     uint8_t co_off);
-
 #if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
 void
      sctp_queue_to_mcore(struct mbuf *m, int off, int cpu_to_use);
diff --git a/freebsd/sys/netinet/sctp_peeloff.h b/freebsd/sys/netinet/sctp_peeloff.h
index dd90567..00b8703 100644
--- a/freebsd/sys/netinet/sctp_peeloff.h
+++ b/freebsd/sys/netinet/sctp_peeloff.h
@@ -38,6 +38,5 @@ __FBSDID("$FreeBSD$");
 #if defined(_KERNEL)
 int sctp_can_peel_off(struct socket *, sctp_assoc_t);
 int sctp_do_peeloff(struct socket *, struct socket *, sctp_assoc_t);
-
 #endif				/* _KERNEL */
 #endif				/* _NETINET_SCTP_PEELOFF_H_ */
diff --git a/freebsd/sys/netinet/sctp_structs.h b/freebsd/sys/netinet/sctp_structs.h
index 280100b..22a3c73 100644
--- a/freebsd/sys/netinet/sctp_structs.h
+++ b/freebsd/sys/netinet/sctp_structs.h
@@ -183,7 +183,6 @@ struct iterator_control {
 	uint32_t iterator_running;
 	uint32_t iterator_flags;
 };
-
 #define SCTP_ITERATOR_STOP_CUR_IT	0x00000004
 #define SCTP_ITERATOR_STOP_CUR_INP	0x00000008
 
@@ -389,10 +388,10 @@ struct sctp_nets {
 
 
 struct sctp_data_chunkrec {
-	uint32_t TSN_seq;	/* the TSN of this transmit */
-	uint32_t stream_seq;	/* the stream sequence number of this transmit */
-	uint16_t stream_number;	/* the stream number of this guy */
-	uint32_t payloadtype;
+	uint32_t tsn;		/* the TSN of this transmit */
+	uint32_t mid;		/* the message identifier of this transmit */
+	uint16_t sid;		/* the stream number of this guy */
+	uint32_t ppid;
 	uint32_t context;	/* from send */
 	uint32_t cwnd_at_send;
 	/*
@@ -401,7 +400,7 @@ struct sctp_data_chunkrec {
 	 */
 	uint32_t fast_retran_tsn;	/* sending_seq at the time of FR */
 	struct timeval timetodrop;	/* time we drop it from queue */
-	uint32_t fsn_num;	/* Fragment Sequence Number */
+	uint32_t fsn;		/* Fragment Sequence Number */
 	uint8_t doing_fast_retransmit;
 	uint8_t rcv_flags;	/* flags pulled from data chunk on inbound for
 				 * outbound holds sending flags for PR-SCTP. */
@@ -455,7 +454,6 @@ struct sctp_tmit_chunk {
 
 struct sctp_queued_to_read {	/* sinfo structure Pluse more */
 	uint16_t sinfo_stream;	/* off the wire */
-	uint32_t sinfo_ssn;	/* off the wire */
 	uint16_t sinfo_flags;	/* SCTP_UNORDERED from wire use SCTP_EOF for
 				 * EOR */
 	uint32_t sinfo_ppid;	/* off the wire */
@@ -465,7 +463,7 @@ struct sctp_queued_to_read {	/* sinfo structure Pluse more */
 	uint32_t sinfo_cumtsn;	/* Use this in reassembly as last TSN */
 	sctp_assoc_t sinfo_assoc_id;	/* our assoc id */
 	/* Non sinfo stuff */
-	uint32_t msg_id;	/* Fragment Index */
+	uint32_t mid;		/* Fragment Index */
 	uint32_t length;	/* length of data */
 	uint32_t held_length;	/* length held in sb */
 	uint32_t top_fsn;	/* Highest FSN in queue */
@@ -527,7 +525,7 @@ struct sctp_stream_queue_pending {
 	uint32_t ppid;
 	uint32_t context;
 	uint16_t sinfo_flags;
-	uint16_t stream;
+	uint16_t sid;
 	uint16_t act_flags;
 	uint16_t auth_keyid;
 	uint8_t holds_key_ref;
@@ -546,8 +544,8 @@ TAILQ_HEAD(sctpwheelunrel_listhead, sctp_stream_in);
 struct sctp_stream_in {
 	struct sctp_readhead inqueue;
 	struct sctp_readhead uno_inqueue;
-	uint32_t last_sequence_delivered;	/* used for re-order */
-	uint16_t stream_no;
+	uint32_t last_mid_delivered;	/* used for re-order */
+	uint16_t sid;
 	uint8_t delivery_started;
 	uint8_t pd_api_started;
 };
@@ -630,7 +628,7 @@ struct sctp_stream_out {
 	 */
 	uint32_t next_mid_ordered;
 	uint32_t next_mid_unordered;
-	uint16_t stream_no;
+	uint16_t sid;
 	uint8_t last_msg_incomplete;
 	uint8_t state;
 };
@@ -883,10 +881,8 @@ struct sctp_association {
 
 	/* JRS - the congestion control functions are in this struct */
 	struct sctp_cc_functions cc_functions;
-	/*
-	 * JRS - value to store the currently loaded congestion control
-	 * module
-	 */
+	/* JRS - value to store the currently loaded congestion control
+	 * module */
 	uint32_t congestion_control_module;
 	/* RS - the stream scheduling functions are in this struct */
 	struct sctp_ss_functions ss_functions;
diff --git a/freebsd/sys/netinet/sctp_sysctl.c b/freebsd/sys/netinet/sctp_sysctl.c
index 8715c69..152a299 100644
--- a/freebsd/sys/netinet/sctp_sysctl.c
+++ b/freebsd/sys/netinet/sctp_sysctl.c
@@ -645,12 +645,10 @@ static int
 sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS)
 {
 	int error;
-
 #if defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
 	struct sctpstat *sarry;
 	struct sctpstat sb;
 	int cpu;
-
 #endif
 	struct sctpstat sb_temp;
 
@@ -830,7 +828,6 @@ sctp_sysctl_handle_trace_log_clear(SYSCTL_HANDLER_ARGS)
 	memset(&SCTP_BASE_SYSCTL(sctp_log), 0, sizeof(struct sctp_log));
 	return (error);
 }
-
 #endif
 
 #define SCTP_UINT_SYSCTL(mib_name, var_name, prefix)			\
diff --git a/freebsd/sys/netinet/sctp_timer.c b/freebsd/sys/netinet/sctp_timer.c
index c851317..2d427e4 100644
--- a/freebsd/sys/netinet/sctp_timer.c
+++ b/freebsd/sys/netinet/sctp_timer.c
@@ -195,10 +195,8 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
 	 */
 	if (mode == 2) {
 		TAILQ_FOREACH(mnet, &stcb->asoc.nets, sctp_next) {
-			/*
-			 * JRS 5/14/07 - If the destination is unreachable
-			 * or unconfirmed, skip it.
-			 */
+			/* JRS 5/14/07 - If the destination is unreachable
+			 * or unconfirmed, skip it. */
 			if (((mnet->dest_state & SCTP_ADDR_REACHABLE) != SCTP_ADDR_REACHABLE) ||
 			    (mnet->dest_state & SCTP_ADDR_UNCONFIRMED)) {
 				continue;
@@ -288,11 +286,8 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
 		} else {
 			return (max_cwnd_net);
 		}
-	}
-	/*
-	 * JRS 5/14/07 - If mode is set to 1, use the CMT policy for
-	 * choosing an alternate net.
-	 */ 
+	}			/* JRS 5/14/07 - If mode is set to 1, use the
+	  * CMT policy for choosing an alternate net. */ 
 	else if (mode == 1) {
 		TAILQ_FOREACH(mnet, &stcb->asoc.nets, sctp_next) {
 			if (((mnet->dest_state & SCTP_ADDR_REACHABLE) != SCTP_ADDR_REACHABLE) ||
@@ -436,17 +431,17 @@ sctp_recover_sent_list(struct sctp_tcb *stcb)
 
 	asoc = &stcb->asoc;
 	TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
-		if (SCTP_TSN_GE(asoc->last_acked_seq, chk->rec.data.TSN_seq)) {
+		if (SCTP_TSN_GE(asoc->last_acked_seq, chk->rec.data.tsn)) {
 			SCTP_PRINTF("Found chk:%p tsn:%x <= last_acked_seq:%x\n",
-			    (void *)chk, chk->rec.data.TSN_seq, asoc->last_acked_seq);
+			    (void *)chk, chk->rec.data.tsn, asoc->last_acked_seq);
 			if (chk->sent != SCTP_DATAGRAM_NR_ACKED) {
-				if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
-					asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
+				if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
+					asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
 				}
 			}
-			if ((asoc->strmout[chk->rec.data.stream_number].chunks_on_queues == 0) &&
-			    (asoc->strmout[chk->rec.data.stream_number].state == SCTP_STREAM_RESET_PENDING) &&
-			    TAILQ_EMPTY(&asoc->strmout[chk->rec.data.stream_number].outqueue)) {
+			if ((asoc->strmout[chk->rec.data.sid].chunks_on_queues == 0) &&
+			    (asoc->strmout[chk->rec.data.sid].state == SCTP_STREAM_RESET_PENDING) &&
+			    TAILQ_EMPTY(&asoc->strmout[chk->rec.data.sid].outqueue)) {
 				asoc->trigger_reset = 1;
 			}
 			TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
@@ -469,10 +464,9 @@ sctp_recover_sent_list(struct sctp_tcb *stcb)
 	}
 	SCTP_PRINTF("after recover order is as follows\n");
 	TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
-		SCTP_PRINTF("chk:%p TSN:%x\n", (void *)chk, chk->rec.data.TSN_seq);
+		SCTP_PRINTF("chk:%p TSN:%x\n", (void *)chk, chk->rec.data.tsn);
 	}
 }
-
 #endif
 
 static int
@@ -554,10 +548,10 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
 start_again:
 #endif
 	TAILQ_FOREACH_SAFE(chk, &stcb->asoc.sent_queue, sctp_next, nchk) {
-		if (SCTP_TSN_GE(stcb->asoc.last_acked_seq, chk->rec.data.TSN_seq)) {
+		if (SCTP_TSN_GE(stcb->asoc.last_acked_seq, chk->rec.data.tsn)) {
 			/* Strange case our list got out of order? */
 			SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x\n",
-			    (unsigned int)stcb->asoc.last_acked_seq, (unsigned int)chk->rec.data.TSN_seq);
+			    (unsigned int)stcb->asoc.last_acked_seq, (unsigned int)chk->rec.data.tsn);
 			recovery_cnt++;
 #ifdef INVARIANTS
 			panic("last acked >= chk on sent-Q");
@@ -582,7 +576,7 @@ start_again:
 
 			/* validate its been outstanding long enough */
 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
-				sctp_log_fr(chk->rec.data.TSN_seq,
+				sctp_log_fr(chk->rec.data.tsn,
 				    chk->sent_rcv_time.tv_sec,
 				    chk->sent_rcv_time.tv_usec,
 				    SCTP_FR_T3_MARK_TIME);
@@ -646,11 +640,11 @@ start_again:
 				num_mk++;
 				if (fir == 0) {
 					fir = 1;
-					tsnfirst = chk->rec.data.TSN_seq;
+					tsnfirst = chk->rec.data.tsn;
 				}
-				tsnlast = chk->rec.data.TSN_seq;
+				tsnlast = chk->rec.data.tsn;
 				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
-					sctp_log_fr(chk->rec.data.TSN_seq, chk->snd_count,
+					sctp_log_fr(chk->rec.data.tsn, chk->snd_count,
 					    0, SCTP_FR_T3_MARKED);
 				}
 				if (chk->rec.data.chunk_was_revoked) {
@@ -665,7 +659,7 @@ start_again:
 					    chk->whoTo->flight_size,
 					    chk->book_size,
 					    (uint32_t) (uintptr_t) chk->whoTo,
-					    chk->rec.data.TSN_seq);
+					    chk->rec.data.tsn);
 				}
 				sctp_flight_size_decrease(chk);
 				sctp_total_flight_decrease(stcb, chk);
@@ -695,7 +689,7 @@ start_again:
 				if (TAILQ_EMPTY(&stcb->asoc.send_queue)) {
 					chk->rec.data.fast_retran_tsn = stcb->asoc.sending_seq;
 				} else {
-					chk->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.TSN_seq;
+					chk->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.tsn;
 				}
 			}
 			/*
@@ -793,7 +787,7 @@ start_again:
 					    chk->whoTo->flight_size,
 					    chk->book_size,
 					    (uint32_t) (uintptr_t) chk->whoTo,
-					    chk->rec.data.TSN_seq);
+					    chk->rec.data.tsn);
 				}
 				sctp_flight_size_increase(chk);
 				sctp_total_flight_increase(stcb, chk);
diff --git a/freebsd/sys/netinet/sctp_uio.h b/freebsd/sys/netinet/sctp_uio.h
index e65b7b5..d605516 100644
--- a/freebsd/sys/netinet/sctp_uio.h
+++ b/freebsd/sys/netinet/sctp_uio.h
@@ -147,7 +147,6 @@ struct sctp_extrcvinfo {
 	uint16_t sinfo_keynumber_valid;
 	uint8_t __reserve_pad[SCTP_ALIGN_RESV_PAD_SHORT];
 };
-
 #define sinfo_pr_value sinfo_timetolive
 #define sreinfo_next_flags serinfo_next_flags
 #define sreinfo_next_stream serinfo_next_stream
@@ -573,7 +572,6 @@ struct sctp_paddrparams {
 	uint16_t spp_pathmaxrxt;
 	uint8_t spp_dscp;
 };
-
 #define spp_ipv4_tos spp_dscp
 
 #define SPP_HB_ENABLE		0x00000001
@@ -1284,7 +1282,6 @@ sctp_sorecvmsg(struct socket *so,
     int *msg_flags,
     struct sctp_sndrcvinfo *sinfo,
     int filling_sinfo);
-
 #endif
 
 /*
diff --git a/freebsd/sys/netinet/sctp_usrreq.c b/freebsd/sys/netinet/sctp_usrreq.c
index 1cbb707..e3e398d 100644
--- a/freebsd/sys/netinet/sctp_usrreq.c
+++ b/freebsd/sys/netinet/sctp_usrreq.c
@@ -137,7 +137,7 @@ sctp_pathmtu_adjustment(struct sctp_tcb *stcb, uint16_t nxtsz)
 					    chk->whoTo->flight_size,
 					    chk->book_size,
 					    (uint32_t) (uintptr_t) chk->whoTo,
-					    chk->rec.data.TSN_seq);
+					    chk->rec.data.tsn);
 				}
 				/* Clear any time so NO RTT is being done */
 				chk->do_rtt = 0;
@@ -158,7 +158,6 @@ sctp_notify(struct sctp_inpcb *inp,
 {
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so;
-
 #endif
 	int timer_stopped;
 
@@ -346,7 +345,6 @@ sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
 	}
 	return;
 }
-
 #endif
 
 static int
@@ -979,10 +977,8 @@ sctp_shutdown(struct socket *so)
 			}
 		}
 		sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, netp);
-		/*
-		 * XXX: Why do this in the case where we have still data
-		 * queued?
-		 */
+		/* XXX: Why do this in the case where we have still data
+		 * queued? */
 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
 		SCTP_TCB_UNLOCK(stcb);
 		SCTP_INP_RUNLOCK(inp);
@@ -1023,14 +1019,11 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
 	struct sctp_ifa *sctp_ifa;
 	size_t actual;
 	int loopback_scope;
-
 #if defined(INET)
 	int ipv4_local_scope, ipv4_addr_legal;
-
 #endif
 #if defined(INET6)
 	int local_scope, site_scope, ipv6_addr_legal;
-
 #endif
 	struct sctp_vrf *vrf;
 
@@ -1176,19 +1169,14 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
 							if (sin6->sin6_scope_id == 0) {
 								if (sa6_recoverscope(sin6) != 0)
 									/*
-									 * 
+									 *
 									 * bad
-									 * 
-									 * li
-									 * nk
-									 * 
-									 * loc
-									 * al
-									 * 
-									 * add
-									 * re
-									 * ss
-									 * */
+									 * link
+									 *
+									 * local
+									 *
+									 * address
+									 */
 									continue;
 							}
 						}
@@ -1523,19 +1511,19 @@ out_now:
 		stcb = LIST_FIRST(&inp->sctp_asoc_list); \
 		if (stcb) { \
 			SCTP_TCB_LOCK(stcb); \
-                } \
+		} \
 		SCTP_INP_RUNLOCK(inp); \
 	} else if (assoc_id > SCTP_ALL_ASSOC) { \
 		stcb = sctp_findassociation_ep_asocid(inp, assoc_id, 1); \
 		if (stcb == NULL) { \
-		        SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); \
+			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); \
 			error = ENOENT; \
 			break; \
 		} \
 	} else { \
 		stcb = NULL; \
-        } \
-  }
+	} \
+}
 
 
 #define SCTP_CHECK_AND_CAST(destp, srcp, type, size) {\
@@ -1546,7 +1534,7 @@ out_now:
 	} else { \
 		destp = (type *)srcp; \
 	} \
-      }
+}
 
 static int
 sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
@@ -1825,10 +1813,8 @@ flags_out:
 				}
 				SCTP_TCB_UNLOCK(stcb);
 			} else {
-				/*
-				 * Can't get stream value without
-				 * association
-				 */
+				/* Can't get stream value without
+				 * association */
 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
 				error = EINVAL;
 			}
@@ -2328,10 +2314,8 @@ flags_out:
 			struct sctp_paddrparams *paddrp;
 			struct sctp_nets *net;
 			struct sockaddr *addr;
-
 #if defined(INET) && defined(INET6)
 			struct sockaddr_in sin_store;
-
 #endif
 
 			SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, *optsize);
@@ -2531,10 +2515,8 @@ flags_out:
 			struct sctp_paddrinfo *paddri;
 			struct sctp_nets *net;
 			struct sockaddr *addr;
-
 #if defined(INET) && defined(INET6)
 			struct sockaddr_in sin_store;
-
 #endif
 
 			SCTP_CHECK_AND_CAST(paddri, optval, struct sctp_paddrinfo, *optsize);
@@ -3200,10 +3182,8 @@ flags_out:
 			struct sctp_paddrthlds *thlds;
 			struct sctp_nets *net;
 			struct sockaddr *addr;
-
 #if defined(INET) && defined(INET6)
 			struct sockaddr_in sin_store;
-
 #endif
 
 			SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, *optsize);
@@ -3314,10 +3294,8 @@ flags_out:
 			struct sctp_udpencaps *encaps;
 			struct sctp_nets *net;
 			struct sockaddr *addr;
-
 #if defined(INET) && defined(INET6)
 			struct sockaddr_in sin_store;
-
 #endif
 
 			SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, *optsize);
@@ -3911,12 +3889,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 						    (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS))) {
 							inp->idata_supported = 1;
 						} else {
-							/*
-							 * Must have Frag
+							/* Must have Frag
 							 * interleave and
 							 * stream interleave
-							 * on
-							 */
+							 * on */
 							SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
 							error = EINVAL;
 						}
@@ -4127,10 +4103,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 					}
 					SCTP_INP_RUNLOCK(inp);
 				} else {
-					/*
-					 * Can't set stream value without
-					 * association
-					 */
+					/* Can't set stream value without
+					 * association */
 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
 					error = EINVAL;
 				}
@@ -4360,10 +4334,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 					LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
 						SCTP_TCB_LOCK(stcb);
 						shared_keys = &stcb->asoc.shared_keys;
-						/*
-						 * clear the cached keys for
-						 * this key id
-						 */
+						/* clear the cached keys for
+						 * this key id */
 						sctp_clear_cachedkeys(stcb, sca->sca_keynumber);
 						/*
 						 * create the new shared key
@@ -4762,10 +4734,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 				int cnt;
 
 				addstream |= 2;
-				/*
-				 * We allocate inside
-				 * sctp_send_str_reset_req()
-				 */
+				/* We allocate inside
+				 * sctp_send_str_reset_req() */
 				add_i_strmcnt = stradd->sas_instrms;
 				cnt = add_i_strmcnt;
 				cnt += stcb->asoc.streamincnt;
@@ -4813,10 +4783,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 				SCTP_TCB_UNLOCK(stcb);
 				break;
 			}
-			/*
-			 * Is there any data pending in the send or sent
-			 * queues?
-			 */
+			/* Is there any data pending in the send or sent
+			 * queues? */
 			if (!TAILQ_EMPTY(&stcb->asoc.send_queue) ||
 			    !TAILQ_EMPTY(&stcb->asoc.sent_queue)) {
 		busy_out:
@@ -4962,10 +4930,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 				    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
 				    (av->assoc_id == SCTP_FUTURE_ASSOC)) {
 					SCTP_INP_WLOCK(inp);
-					/*
-					 * FIXME MT: I think this is not in
-					 * tune with the API ID
-					 */
+					/* FIXME MT: I think this is not in
+					 * tune with the API ID */
 					if (av->assoc_value) {
 						inp->sctp_frag_point = (av->assoc_value + ovh);
 					} else {
@@ -5108,10 +5074,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 				}
 				SCTP_TCB_UNLOCK(stcb);
 			}
-			/*
-			 * Send up the sender dry event only for 1-to-1
-			 * style sockets.
-			 */
+			/* Send up the sender dry event only for 1-to-1
+			 * style sockets. */
 			if (events->sctp_sender_dry_event) {
 				if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
 				    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
@@ -5197,10 +5161,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 			struct sctp_paddrparams *paddrp;
 			struct sctp_nets *net;
 			struct sockaddr *addr;
-
 #if defined(INET) && defined(INET6)
 			struct sockaddr_in sin_store;
-
 #endif
 
 			SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, optsize);
@@ -5701,10 +5663,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 			struct sctp_setprim *spa;
 			struct sctp_nets *net;
 			struct sockaddr *addr;
-
 #if defined(INET) && defined(INET6)
 			struct sockaddr_in sin_store;
-
 #endif
 
 			SCTP_CHECK_AND_CAST(spa, optval, struct sctp_setprim, optsize);
@@ -5793,10 +5753,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 		{
 			struct sctp_setpeerprim *sspp;
 			struct sockaddr *addr;
-
 #if defined(INET) && defined(INET6)
 			struct sockaddr_in sin_store;
-
 #endif
 
 			SCTP_CHECK_AND_CAST(sspp, optval, struct sctp_setpeerprim, optsize);
@@ -5828,10 +5786,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 					goto out_of_it;
 				}
 				if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
-					/*
-					 * Must validate the ifa found is in
-					 * our ep
-					 */
+					/* Must validate the ifa found is in
+					 * our ep */
 					struct sctp_laddr *laddr;
 					int found = 0;
 
@@ -6246,10 +6202,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 			struct sctp_paddrthlds *thlds;
 			struct sctp_nets *net;
 			struct sockaddr *addr;
-
 #if defined(INET) && defined(INET6)
 			struct sockaddr_in sin_store;
-
 #endif
 
 			SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, optsize);
@@ -6417,10 +6371,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 			struct sctp_udpencaps *encaps;
 			struct sctp_nets *net;
 			struct sockaddr *addr;
-
 #if defined(INET) && defined(INET6)
 			struct sockaddr_in sin_store;
-
 #endif
 
 			SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, optsize);
@@ -6591,10 +6543,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 				    (av->assoc_id == SCTP_FUTURE_ASSOC)) {
 					if ((av->assoc_value == 0) &&
 					    (inp->asconf_supported == 1)) {
-						/*
-						 * AUTH is required for
-						 * ASCONF
-						 */
+						/* AUTH is required for
+						 * ASCONF */
 						SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
 						error = EINVAL;
 					} else {
@@ -6630,10 +6580,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
 				    (av->assoc_id == SCTP_FUTURE_ASSOC)) {
 					if ((av->assoc_value != 0) &&
 					    (inp->auth_supported == 0)) {
-						/*
-						 * AUTH is required for
-						 * ASCONF
-						 */
+						/* AUTH is required for
+						 * ASCONF */
 						SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
 						error = EINVAL;
 					} else {
@@ -7012,7 +6960,6 @@ out_now:
 	SCTP_INP_DECR_REF(inp);
 	return (error);
 }
-
 #endif
 
 int
@@ -7066,10 +7013,8 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
 				    ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
 				    ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
 				    (tinp->sctp_socket->so_qlimit)) {
-					/*
-					 * we have a listener already and
-					 * its not this inp.
-					 */
+					/* we have a listener already and
+					 * its not this inp. */
 					SCTP_INP_DECR_REF(tinp);
 					return (EADDRINUSE);
 				} else if (tinp) {
@@ -7110,10 +7055,8 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
 			    ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
 			    ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
 			    (tinp->sctp_socket->so_qlimit)) {
-				/*
-				 * we have a listener already and its not
-				 * this inp.
-				 */
+				/* we have a listener already and its not
+				 * this inp. */
 				SCTP_INP_DECR_REF(tinp);
 				return (EADDRINUSE);
 			} else if (tinp) {
@@ -7186,10 +7129,8 @@ sctp_accept(struct socket *so, struct sockaddr **addr)
 	struct sctp_tcb *stcb;
 	struct sctp_inpcb *inp;
 	union sctp_sockstore store;
-
 #ifdef INET6
 	int error;
-
 #endif
 	inp = (struct sctp_inpcb *)so->so_pcb;
 
@@ -7472,5 +7413,4 @@ struct pr_usrreqs sctp_usrreqs = {
 	.pru_sosend = sctp_sosend,
 	.pru_soreceive = sctp_soreceive
 };
-
 #endif
diff --git a/freebsd/sys/netinet/sctp_var.h b/freebsd/sys/netinet/sctp_var.h
index a4d2b99..6365dfe 100644
--- a/freebsd/sys/netinet/sctp_var.h
+++ b/freebsd/sys/netinet/sctp_var.h
@@ -267,7 +267,7 @@ extern struct pr_usrreqs sctp_usrreqs;
 	if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
 		stcb->asoc.fs_index = 0;\
 	stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
-	stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \
+	stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.tsn; \
 	stcb->asoc.fslog[stcb->asoc.fs_index].book = tp1->book_size; \
 	stcb->asoc.fslog[stcb->asoc.fs_index].sent = tp1->sent; \
 	stcb->asoc.fslog[stcb->asoc.fs_index].incr = 0; \
@@ -288,7 +288,7 @@ extern struct pr_usrreqs sctp_usrreqs;
 	if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
 		stcb->asoc.fs_index = 0;\
 	stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
-	stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \
+	stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.tsn; \
 	stcb->asoc.fslog[stcb->asoc.fs_index].book = tp1->book_size; \
 	stcb->asoc.fslog[stcb->asoc.fs_index].sent = tp1->sent; \
 	stcb->asoc.fslog[stcb->asoc.fs_index].incr = 1; \
@@ -332,11 +332,9 @@ void sctp_close(struct socket *so);
 int sctp_disconnect(struct socket *so);
 void sctp_ctlinput(int, struct sockaddr *, void *);
 int sctp_ctloutput(struct socket *, struct sockopt *);
-
 #ifdef INET
 void sctp_input_with_port(struct mbuf *, int, uint16_t);
 int sctp_input(struct mbuf **, int *, int);
-
 #endif
 void sctp_pathmtu_adjustment(struct sctp_tcb *, uint16_t);
 void sctp_drain(void);
diff --git a/freebsd/sys/netinet/sctputil.c b/freebsd/sys/netinet/sctputil.c
index 36a9c2c..136b4bb 100644
--- a/freebsd/sys/netinet/sctputil.c
+++ b/freebsd/sys/netinet/sctputil.c
@@ -257,7 +257,6 @@ sctp_log_mbc(struct mbuf *m, int from)
 		sctp_log_mb(mat, from);
 	}
 }
-
 #endif
 
 void
@@ -271,11 +270,11 @@ sctp_log_strm_del(struct sctp_queued_to_read *control, struct sctp_queued_to_rea
 	}
 	sctp_clog.x.strlog.stcb = control->stcb;
 	sctp_clog.x.strlog.n_tsn = control->sinfo_tsn;
-	sctp_clog.x.strlog.n_sseq = control->sinfo_ssn;
+	sctp_clog.x.strlog.n_sseq = (uint16_t) control->mid;
 	sctp_clog.x.strlog.strm = control->sinfo_stream;
 	if (poschk != NULL) {
 		sctp_clog.x.strlog.e_tsn = poschk->sinfo_tsn;
-		sctp_clog.x.strlog.e_sseq = poschk->sinfo_ssn;
+		sctp_clog.x.strlog.e_sseq = (uint16_t) poschk->mid;
 	} else {
 		sctp_clog.x.strlog.e_tsn = 0;
 		sctp_clog.x.strlog.e_sseq = 0;
@@ -449,7 +448,6 @@ sctp_log_mbcnt(uint8_t from, uint32_t total_oq, uint32_t book, uint32_t total_mb
 	    sctp_clog.x.misc.log3,
 	    sctp_clog.x.misc.log4);
 }
-
 #endif
 
 void
@@ -959,10 +957,8 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 	 * caller in the sctp_aloc_assoc() function.
 	 */
 	int i;
-
 #if defined(SCTP_DETAILED_STR_STATS)
 	int j;
-
 #endif
 
 	asoc = &stcb->asoc;
@@ -1137,7 +1133,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 		asoc->strmout[i].abandoned_sent[0] = 0;
 		asoc->strmout[i].abandoned_unsent[0] = 0;
 #endif
-		asoc->strmout[i].stream_no = i;
+		asoc->strmout[i].sid = i;
 		asoc->strmout[i].last_msg_incomplete = 0;
 		asoc->strmout[i].state = SCTP_STREAM_OPENING;
 		asoc->ss_functions.sctp_ss_init_stream(stcb, &asoc->strmout[i], NULL);
@@ -1488,10 +1484,8 @@ sctp_handle_addr_wq(void)
 		    sctp_asconf_iterator_end, NULL, 0);
 		if (ret) {
 			SCTP_PRINTF("Failed to initiate iterator for handle_addr_wq\n");
-			/*
-			 * Freeing if we are stopping or put back on the
-			 * addr_wq.
-			 */
+			/* Freeing if we are stopping or put back on the
+			 * addr_wq. */
 			if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
 				sctp_asconf_iterator_end(asc, 0);
 			} else {
@@ -1514,10 +1508,8 @@ sctp_timeout_handler(void *t)
 	struct sctp_nets *net;
 	struct sctp_timer *tmr;
 	struct mbuf *op_err;
-
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so;
-
 #endif
 	int did_output;
 	int type;
@@ -2493,10 +2485,8 @@ sctp_calculate_rto(struct sctp_tcb *stcb,
 	/* compute rtt in ms */
 	rtt = (int32_t) (net->rtt / 1000);
 	if ((asoc->cc_functions.sctp_rtt_calculated) && (rtt_from_sack == SCTP_RTT_FROM_DATA)) {
-		/*
-		 * Tell the CC module that a new update has just occurred
-		 * from a sack
-		 */
+		/* Tell the CC module that a new update has just occurred
+		 * from a sack */
 		(*asoc->cc_functions.sctp_rtt_calculated) (stcb, net, &now);
 	}
 	/*
@@ -2688,10 +2678,8 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
 	unsigned int notif_len;
 	uint16_t abort_len;
 	unsigned int i;
-
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so;
-
 #endif
 
 	if (stcb == NULL) {
@@ -2989,9 +2977,9 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
 		ssfe->ssfe_length = (uint32_t) (notifhdr_len + payload_len);
 		ssfe->ssfe_error = error;
 		/* not exactly what the user sent in, but should be close :) */
-		ssfe->ssfe_info.snd_sid = chk->rec.data.stream_number;
+		ssfe->ssfe_info.snd_sid = chk->rec.data.sid;
 		ssfe->ssfe_info.snd_flags = chk->rec.data.rcv_flags;
-		ssfe->ssfe_info.snd_ppid = chk->rec.data.payloadtype;
+		ssfe->ssfe_info.snd_ppid = chk->rec.data.ppid;
 		ssfe->ssfe_info.snd_context = chk->rec.data.context;
 		ssfe->ssfe_info.snd_assoc_id = sctp_get_associd(stcb);
 		ssfe->ssfe_assoc_id = sctp_get_associd(stcb);
@@ -3007,10 +2995,10 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
 		ssf->ssf_length = (uint32_t) (notifhdr_len + payload_len);
 		ssf->ssf_error = error;
 		/* not exactly what the user sent in, but should be close :) */
-		ssf->ssf_info.sinfo_stream = chk->rec.data.stream_number;
-		ssf->ssf_info.sinfo_ssn = (uint16_t) chk->rec.data.stream_seq;
+		ssf->ssf_info.sinfo_stream = chk->rec.data.sid;
+		ssf->ssf_info.sinfo_ssn = (uint16_t) chk->rec.data.mid;
 		ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags;
-		ssf->ssf_info.sinfo_ppid = chk->rec.data.payloadtype;
+		ssf->ssf_info.sinfo_ppid = chk->rec.data.ppid;
 		ssf->ssf_info.sinfo_context = chk->rec.data.context;
 		ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
 		ssf->ssf_assoc_id = sctp_get_associd(stcb);
@@ -3093,7 +3081,7 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
 		ssfe->ssfe_length = (uint32_t) (notifhdr_len + sp->length);
 		ssfe->ssfe_error = error;
 		/* not exactly what the user sent in, but should be close :) */
-		ssfe->ssfe_info.snd_sid = sp->stream;
+		ssfe->ssfe_info.snd_sid = sp->sid;
 		if (sp->some_taken) {
 			ssfe->ssfe_info.snd_flags = SCTP_DATA_LAST_FRAG;
 		} else {
@@ -3111,7 +3099,7 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
 		ssf->ssf_length = (uint32_t) (notifhdr_len + sp->length);
 		ssf->ssf_error = error;
 		/* not exactly what the user sent in, but should be close :) */
-		ssf->ssf_info.sinfo_stream = sp->stream;
+		ssf->ssf_info.sinfo_stream = sp->sid;
 		ssf->ssf_info.sinfo_ssn = 0;
 		if (sp->some_taken) {
 			ssf->ssf_info.sinfo_flags = SCTP_DATA_LAST_FRAG;
@@ -3861,11 +3849,11 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock,
 		TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
 		asoc->sent_queue_cnt--;
 		if (chk->sent != SCTP_DATAGRAM_NR_ACKED) {
-			if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
-				asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
+			if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
+				asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
 #ifdef INVARIANTS
 			} else {
-				panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number);
+				panic("No chunks on the queues for sid %u.", chk->rec.data.sid);
 #endif
 			}
 		}
@@ -3885,11 +3873,11 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock,
 	TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
 		TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
 		asoc->send_queue_cnt--;
-		if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
-			asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
+		if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
+			asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
 #ifdef INVARIANTS
 		} else {
-			panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number);
+			panic("No chunks on the queues for sid %u.", chk->rec.data.sid);
 #endif
 		}
 		if (chk->data != NULL) {
@@ -3977,25 +3965,22 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
     uint32_t vrf_id, uint16_t port)
 {
 	uint32_t vtag;
-
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so;
-
 #endif
 
 	vtag = 0;
 	if (stcb != NULL) {
-		/* We have a TCB to abort, send notification too */
 		vtag = stcb->asoc.peer_vtag;
-		sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED);
-		/* get the assoc vrf id and table id */
 		vrf_id = stcb->asoc.vrf_id;
-		stcb->asoc.state |= SCTP_STATE_WAS_ABORTED;
 	}
 	sctp_send_abort(m, iphlen, src, dst, sh, vtag, op_err,
 	    mflowtype, mflowid, inp->fibnum,
 	    vrf_id, port);
 	if (stcb != NULL) {
+		/* We have a TCB to abort, send notification too */
+		sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED);
+		stcb->asoc.state |= SCTP_STATE_WAS_ABORTED;
 		/* Ok, now lets free it */
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 		so = SCTP_INP_SO(inp);
@@ -4017,7 +4002,6 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 #endif
 	}
 }
-
 #ifdef SCTP_ASOCLOG_OF_TSNS
 void
 sctp_print_out_track_log(struct sctp_tcb *stcb)
@@ -4079,7 +4063,6 @@ none_in:
 	}
 #endif
 }
-
 #endif
 
 void
@@ -4093,7 +4076,6 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 {
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so;
-
 #endif
 
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@@ -4111,10 +4093,6 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 	} else {
 		stcb->asoc.state |= SCTP_STATE_WAS_ABORTED;
 	}
-	/* notify the ulp */
-	if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
-		sctp_abort_notification(stcb, 0, 0, NULL, so_locked);
-	}
 	/* notify the peer */
 	sctp_send_abort_tcb(stcb, op_err, so_locked);
 	SCTP_STAT_INCR_COUNTER32(sctps_aborted);
@@ -4122,6 +4100,10 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 	    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
 		SCTP_STAT_DECR_GAUGE32(sctps_currestab);
 	}
+	/* notify the ulp */
+	if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
+		sctp_abort_notification(stcb, 0, 0, NULL, so_locked);
+	}
 	/* now free the asoc */
 #ifdef SCTP_ASOCLOG_OF_TSNS
 	sctp_print_out_track_log(stcb);
@@ -4305,7 +4287,6 @@ sctp_recover_scope(struct sockaddr_in6 *addr, struct sockaddr_in6 *store)
 	}
 	return (addr);
 }
-
 #endif
 
 /*
@@ -4359,7 +4340,6 @@ sctp_print_address(struct sockaddr *sa)
 {
 #ifdef INET6
 	char ip6buf[INET6_ADDRSTRLEN];
-
 #endif
 
 	switch (sa->sa_family) {
@@ -4712,25 +4692,26 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
 	struct sctp_stream_out *strq;
 	struct sctp_tmit_chunk *chk = NULL, *tp2;
 	struct sctp_stream_queue_pending *sp;
-	uint16_t stream = 0, seq = 0;
+	uint32_t mid;
+	uint16_t sid;
 	uint8_t foundeom = 0;
 	int ret_sz = 0;
 	int notdone;
 	int do_wakeup_routine = 0;
 
-	stream = tp1->rec.data.stream_number;
-	seq = tp1->rec.data.stream_seq;
+	sid = tp1->rec.data.sid;
+	mid = tp1->rec.data.mid;
 	if (sent || !(tp1->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG)) {
 		stcb->asoc.abandoned_sent[0]++;
 		stcb->asoc.abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++;
-		stcb->asoc.strmout[stream].abandoned_sent[0]++;
+		stcb->asoc.strmout[sid].abandoned_sent[0]++;
 #if defined(SCTP_DETAILED_STR_STATS)
 		stcb->asoc.strmout[stream].abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++;
 #endif
 	} else {
 		stcb->asoc.abandoned_unsent[0]++;
 		stcb->asoc.abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++;
-		stcb->asoc.strmout[stream].abandoned_unsent[0]++;
+		stcb->asoc.strmout[sid].abandoned_unsent[0]++;
 #if defined(SCTP_DETAILED_STR_STATS)
 		stcb->asoc.strmout[stream].abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++;
 #endif
@@ -4784,8 +4765,8 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
 		 * sent queue.
 		 */
 		TAILQ_FOREACH_SAFE(tp1, &stcb->asoc.send_queue, sctp_next, tp2) {
-			if ((tp1->rec.data.stream_number != stream) ||
-			    (tp1->rec.data.stream_seq != seq)) {
+			if ((tp1->rec.data.sid != sid) ||
+			    (!SCTP_MID_EQ(stcb->asoc.idata_supported, tp1->rec.data.mid, mid))) {
 				break;
 			}
 			/*
@@ -4813,10 +4794,8 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
 			do_wakeup_routine = 1;
 			tp1->sent = SCTP_FORWARD_TSN_SKIP;
 			TAILQ_REMOVE(&stcb->asoc.send_queue, tp1, sctp_next);
-			/*
-			 * on to the sent queue so we can wait for it to be
-			 * passed by.
-			 */
+			/* on to the sent queue so we can wait for it to be
+			 * passed by. */
 			TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, tp1,
 			    sctp_next);
 			stcb->asoc.send_queue_cnt--;
@@ -4829,7 +4808,7 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
 		 * stream out queue.. yuck.
 		 */
 		SCTP_TCB_SEND_LOCK(stcb);
-		strq = &stcb->asoc.strmout[stream];
+		strq = &stcb->asoc.strmout[sid];
 		sp = TAILQ_FIRST(&strq->outqueue);
 		if (sp != NULL) {
 			sp->discard_rest = 1;
@@ -4856,23 +4835,23 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
 				chk->asoc = &stcb->asoc;
 				if (stcb->asoc.idata_supported == 0) {
 					if (sp->sinfo_flags & SCTP_UNORDERED) {
-						chk->rec.data.stream_seq = 0;
+						chk->rec.data.mid = 0;
 					} else {
-						chk->rec.data.stream_seq = strq->next_mid_ordered;
+						chk->rec.data.mid = strq->next_mid_ordered;
 					}
 				} else {
 					if (sp->sinfo_flags & SCTP_UNORDERED) {
-						chk->rec.data.stream_seq = strq->next_mid_unordered;
+						chk->rec.data.mid = strq->next_mid_unordered;
 					} else {
-						chk->rec.data.stream_seq = strq->next_mid_ordered;
+						chk->rec.data.mid = strq->next_mid_ordered;
 					}
 				}
-				chk->rec.data.stream_number = sp->stream;
-				chk->rec.data.payloadtype = sp->ppid;
+				chk->rec.data.sid = sp->sid;
+				chk->rec.data.ppid = sp->ppid;
 				chk->rec.data.context = sp->context;
 				chk->flags = sp->act_flags;
 				chk->whoTo = NULL;
-				chk->rec.data.TSN_seq = atomic_fetchadd_int(&stcb->asoc.sending_seq, 1);
+				chk->rec.data.tsn = atomic_fetchadd_int(&stcb->asoc.sending_seq, 1);
 				strq->chunks_on_queues++;
 				TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next);
 				stcb->asoc.sent_queue_cnt++;
@@ -5190,7 +5169,7 @@ sctp_sorecvmsg(struct socket *so,
 	 * mp=NULL thus uio is the copy method to userland) MSG_WAITALL - ??
 	 * On the way out we may send out any combination of:
 	 * MSG_NOTIFICATION MSG_EOR
-	 * 
+	 *
 	 */
 	struct sctp_inpcb *inp = NULL;
 	int my_len = 0;
@@ -5309,10 +5288,8 @@ restart_nosblocks:
 				 * connect.
 				 */
 				if (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED) {
-					/*
-					 * You were aborted, passive side
-					 * always hits here
-					 */
+					/* You were aborted, passive side
+					 * always hits here */
 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
 					error = ECONNRESET;
 				}
@@ -5411,10 +5388,8 @@ restart_nosblocks:
 	}
 	if ((control->length == 0) &&
 	    (control->end_added == 1)) {
-		/*
-		 * Do we also need to check for (control->pdapi_aborted ==
-		 * 1)?
-		 */
+		/* Do we also need to check for (control->pdapi_aborted ==
+		 * 1)? */
 		if (hold_rlock == 0) {
 			hold_rlock = 1;
 			SCTP_INP_READ_LOCK(inp);
@@ -5555,7 +5530,7 @@ found_one:
 	/* First lets get off the sinfo and sockaddr info */
 	if ((sinfo != NULL) && (filling_sinfo != 0)) {
 		sinfo->sinfo_stream = control->sinfo_stream;
-		sinfo->sinfo_ssn = (uint16_t) control->sinfo_ssn;
+		sinfo->sinfo_ssn = (uint16_t) control->mid;
 		sinfo->sinfo_flags = control->sinfo_flags;
 		sinfo->sinfo_ppid = control->sinfo_ppid;
 		sinfo->sinfo_context = control->sinfo_context;
@@ -5631,7 +5606,7 @@ found_one:
 		entry = &inp->readlog[index];
 		entry->vtag = control->sinfo_assoc_id;
 		entry->strm = control->sinfo_stream;
-		entry->seq = control->sinfo_ssn;
+		entry->seq = (uint16_t) control->mid;
 		entry->sz = control->length;
 		entry->flgs = control->sinfo_flags;
 	}
@@ -5757,10 +5732,8 @@ get_more_data:
 					atomic_subtract_int(&control->length, cp_len);
 					control->data = sctp_m_free(m);
 					m = control->data;
-					/*
-					 * been through it all, must hold sb
-					 * lock ok to null tail
-					 */
+					/* been through it all, must hold sb
+					 * lock ok to null tail */
 					if (control->data == NULL) {
 #ifdef INVARIANTS
 						if ((control->end_added == 0) ||
@@ -5979,10 +5952,8 @@ wait_some_more:
 			 */
 			SCTP_INP_READ_LOCK(inp);
 			if ((control->length > 0) && (control->data == NULL)) {
-				/*
-				 * big trouble.. we have the lock and its
-				 * corrupt?
-				 */
+				/* big trouble.. we have the lock and its
+				 * corrupt? */
 #ifdef INVARIANTS
 				panic("Impossible data==NULL length !=0");
 #endif
@@ -6273,14 +6244,11 @@ sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr,
 	struct sctp_inpcb *inp;
 	struct sockaddr *sa;
 	size_t incr = 0;
-
 #ifdef INET
 	struct sockaddr_in *sin;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 *sin6;
-
 #endif
 
 	sa = addr;
@@ -6402,6 +6370,7 @@ sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr,
 #endif
 		default:
 			*totaddr = i;
+			incr = 0;
 			/* we are done */
 			break;
 		}
@@ -6435,10 +6404,8 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
     uint32_t vrf_id, int *error, void *p)
 {
 	struct sockaddr *addr_touse;
-
 #if defined(INET) && defined(INET6)
 	struct sockaddr_in sin;
-
 #endif
 
 	/* see if we're bound all already! */
@@ -6567,10 +6534,8 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
     uint32_t vrf_id, int *error)
 {
 	struct sockaddr *addr_touse;
-
 #if defined(INET) && defined(INET6)
 	struct sockaddr_in sin;
-
 #endif
 
 	/* see if we're bound all already! */
@@ -6584,7 +6549,6 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
 	if (sa->sa_family == AF_INET6) {
 #ifdef INET
 		struct sockaddr_in6 *sin6;
-
 #endif
 
 		if (sa->sa_len != sizeof(struct sockaddr_in6)) {
@@ -6655,14 +6619,11 @@ int
 sctp_local_addr_count(struct sctp_tcb *stcb)
 {
 	int loopback_scope;
-
 #if defined(INET)
 	int ipv4_local_scope, ipv4_addr_legal;
-
 #endif
 #if defined (INET6)
 	int local_scope, site_scope, ipv6_addr_legal;
-
 #endif
 	struct sctp_vrf *vrf;
 	struct sctp_ifn *sctp_ifn;
@@ -6707,10 +6668,8 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
 
 						sin = &sctp_ifa->address.sin;
 						if (sin->sin_addr.s_addr == 0) {
-							/*
-							 * skip unspecified
-							 * addrs
-							 */
+							/* skip unspecified
+							 * addrs */
 							continue;
 						}
 						if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
@@ -6747,19 +6706,14 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
 							if (sin6->sin6_scope_id == 0) {
 								if (sa6_recoverscope(sin6) != 0)
 									/*
-									 * 
+									 *
 									 * bad
-									 * 
-									 * li
-									 * nk
-									 * 
-									 * loc
-									 * al
-									 * 
-									 * add
-									 * re
-									 * ss
-									 * */
+									 * link
+									 *
+									 * local
+									 *
+									 * address
+									 */
 									continue;
 							}
 						}
@@ -6831,10 +6785,8 @@ sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp,
     const struct sockaddr *sa SCTP_UNUSED, void *ctx SCTP_UNUSED)
 {
 	struct ip *iph;
-
 #ifdef INET6
 	struct ip6_hdr *ip6;
-
 #endif
 	struct mbuf *sp, *last;
 	struct udphdr *uhdr;
@@ -7019,7 +6971,6 @@ sctp_recv_icmp_tunneled_packet(int cmd, struct sockaddr *sa, void *vip, void *ct
 	}
 	return;
 }
-
 #endif
 
 #ifdef INET6
@@ -7161,7 +7112,6 @@ sctp_recv_icmp6_tunneled_packet(int cmd, struct sockaddr *sa, void *d, void *ctx
 		}
 	}
 }
-
 #endif
 
 void
@@ -7190,14 +7140,11 @@ sctp_over_udp_start(void)
 {
 	uint16_t port;
 	int ret;
-
 #ifdef INET
 	struct sockaddr_in sin;
-
 #endif
 #ifdef INET6
 	struct sockaddr_in6 sin6;
-
 #endif
 	/*
 	 * This function assumes sysctl caller holds sctp_sysctl_info_lock()
diff --git a/freebsd/sys/netinet/sctputil.h b/freebsd/sys/netinet/sctputil.h
index 292068a..a3a4f3c 100644
--- a/freebsd/sys/netinet/sctputil.h
+++ b/freebsd/sys/netinet/sctputil.h
@@ -43,13 +43,11 @@ __FBSDID("$FreeBSD$");
 
 #ifdef SCTP_ASOCLOG_OF_TSNS
 void sctp_print_out_track_log(struct sctp_tcb *stcb);
-
 #endif
 
 #ifdef SCTP_MBUF_LOGGING
 struct mbuf *sctp_m_free(struct mbuf *m);
 void sctp_m_freem(struct mbuf *m);
-
 #else
 #define sctp_m_free m_free
 #define sctp_m_freem m_freem
@@ -58,7 +56,6 @@ void sctp_m_freem(struct mbuf *m);
 #if defined(SCTP_LOCAL_TRACE_BUF) || defined(__APPLE__)
 void
      sctp_log_trace(uint32_t fr, const char *str SCTP_UNUSED, uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e, uint32_t f);
-
 #endif
 
 #define sctp_get_associd(stcb) ((sctp_assoc_t)stcb->asoc.assoc_id)
@@ -222,7 +219,6 @@ sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr,
     int *error, unsigned int limit, int *bad_addr);
 
 int sctp_is_there_an_abort_here(struct mbuf *, int, uint32_t *);
-
 #ifdef INET6
 uint32_t sctp_is_same_scope(struct sockaddr_in6 *, struct sockaddr_in6 *);
 
@@ -357,7 +353,6 @@ void
 
 void
      sctp_log_mbc(struct mbuf *m, int from);
-
 #endif
 
 void
diff --git a/freebsd/sys/netinet/tcp_debug.c b/freebsd/sys/netinet/tcp_debug.c
index c5f7418..707e7c5 100644
--- a/freebsd/sys/netinet/tcp_debug.c
+++ b/freebsd/sys/netinet/tcp_debug.c
@@ -217,9 +217,9 @@ tcp_trace(short act, short ostate, struct tcpcb *tp, void *ipgen,
 		return;
 	printf(
 	"\trcv_(nxt,wnd,up) (%lx,%lx,%lx) snd_(una,nxt,max) (%lx,%lx,%lx)\n",
-	    (u_long)tp->rcv_nxt, tp->rcv_wnd, (u_long)tp->rcv_up,
+	    (u_long)tp->rcv_nxt, (u_long)tp->rcv_wnd, (u_long)tp->rcv_up,
 	    (u_long)tp->snd_una, (u_long)tp->snd_nxt, (u_long)tp->snd_max);
 	printf("\tsnd_(wl1,wl2,wnd) (%lx,%lx,%lx)\n",
-	    (u_long)tp->snd_wl1, (u_long)tp->snd_wl2, tp->snd_wnd);
+	    (u_long)tp->snd_wl1, (u_long)tp->snd_wl2, (u_long)tp->snd_wnd);
 #endif /* TCPDEBUG */
 }
diff --git a/freebsd/sys/netinet/tcp_fsm.h b/freebsd/sys/netinet/tcp_fsm.h
index 61fd0c1..5423e1f 100644
--- a/freebsd/sys/netinet/tcp_fsm.h
+++ b/freebsd/sys/netinet/tcp_fsm.h
@@ -73,7 +73,8 @@
 
 #define	TCPS_HAVERCVDSYN(s)	((s) >= TCPS_SYN_RECEIVED)
 #define	TCPS_HAVEESTABLISHED(s)	((s) >= TCPS_ESTABLISHED)
-#define	TCPS_HAVERCVDFIN(s)	((s) >= TCPS_TIME_WAIT)
+#define	TCPS_HAVERCVDFIN(s)	\
+    ((s) == TCPS_CLOSE_WAIT || ((s) >= TCPS_CLOSING && (s) != TCPS_FIN_WAIT_2))
 
 #ifdef	TCPOUTFLAGS
 /*
diff --git a/freebsd/sys/netinet/tcp_hostcache.c b/freebsd/sys/netinet/tcp_hostcache.c
index 4e78b8b..e0c4b49 100644
--- a/freebsd/sys/netinet/tcp_hostcache.c
+++ b/freebsd/sys/netinet/tcp_hostcache.c
@@ -126,6 +126,12 @@ static void tcp_hc_purge(void *);
 static SYSCTL_NODE(_net_inet_tcp, OID_AUTO, hostcache, CTLFLAG_RW, 0,
     "TCP Host cache");
 
+VNET_DEFINE(int, tcp_use_hostcache) = 1;
+#define V_tcp_use_hostcache  VNET(tcp_use_hostcache)
+SYSCTL_INT(_net_inet_tcp_hostcache, OID_AUTO, enable, CTLFLAG_VNET | CTLFLAG_RW,
+    &VNET_NAME(tcp_use_hostcache), 0,
+    "Enable the TCP hostcache");
+
 SYSCTL_UINT(_net_inet_tcp_hostcache, OID_AUTO, cachelimit, CTLFLAG_VNET | CTLFLAG_RDTUN,
     &VNET_NAME(tcp_hostcache.cache_limit), 0,
     "Overall entry limit for hostcache");
@@ -278,6 +284,9 @@ tcp_hc_lookup(struct in_conninfo *inc)
 	struct hc_head *hc_head;
 	struct hc_metrics *hc_entry;
 
+	if (!V_tcp_use_hostcache)
+		return NULL;
+
 	KASSERT(inc != NULL, ("tcp_hc_lookup with NULL in_conninfo pointer"));
 
 	/*
@@ -334,6 +343,9 @@ tcp_hc_insert(struct in_conninfo *inc)
 	struct hc_head *hc_head;
 	struct hc_metrics *hc_entry;
 
+	if (!V_tcp_use_hostcache)
+		return NULL;
+
 	KASSERT(inc != NULL, ("tcp_hc_insert with NULL in_conninfo pointer"));
 
 	/*
@@ -423,6 +435,9 @@ tcp_hc_get(struct in_conninfo *inc, struct hc_metrics_lite *hc_metrics_lite)
 {
 	struct hc_metrics *hc_entry;
 
+	if (!V_tcp_use_hostcache)
+		return;
+
 	/*
 	 * Find the right bucket.
 	 */
@@ -454,14 +469,17 @@ tcp_hc_get(struct in_conninfo *inc, struct hc_metrics_lite *hc_metrics_lite)
 
 /*
  * External function: look up an entry in the hostcache and return the
- * discovered path MTU.  Returns NULL if no entry is found or value is not
+ * discovered path MTU.  Returns 0 if no entry is found or value is not
  * set.
  */
-u_long
+uint32_t
 tcp_hc_getmtu(struct in_conninfo *inc)
 {
 	struct hc_metrics *hc_entry;
-	u_long mtu;
+	uint32_t mtu;
+
+	if (!V_tcp_use_hostcache)
+		return 0;
 
 	hc_entry = tcp_hc_lookup(inc);
 	if (hc_entry == NULL) {
@@ -480,10 +498,13 @@ tcp_hc_getmtu(struct in_conninfo *inc)
  * Creates a new entry if none was found.
  */
 void
-tcp_hc_updatemtu(struct in_conninfo *inc, u_long mtu)
+tcp_hc_updatemtu(struct in_conninfo *inc, uint32_t mtu)
 {
 	struct hc_metrics *hc_entry;
 
+	if (!V_tcp_use_hostcache)
+		return;
+
 	/*
 	 * Find the right bucket.
 	 */
@@ -523,6 +544,9 @@ tcp_hc_update(struct in_conninfo *inc, struct hc_metrics_lite *hcml)
 {
 	struct hc_metrics *hc_entry;
 
+	if (!V_tcp_use_hostcache)
+		return;
+
 	hc_entry = tcp_hc_lookup(inc);
 	if (hc_entry == NULL) {
 		hc_entry = tcp_hc_insert(inc);
@@ -536,16 +560,16 @@ tcp_hc_update(struct in_conninfo *inc, struct hc_metrics_lite *hcml)
 		if (hc_entry->rmx_rtt == 0)
 			hc_entry->rmx_rtt = hcml->rmx_rtt;
 		else
-			hc_entry->rmx_rtt =
-			    (hc_entry->rmx_rtt + hcml->rmx_rtt) / 2;
+			hc_entry->rmx_rtt = ((uint64_t)hc_entry->rmx_rtt +
+			    (uint64_t)hcml->rmx_rtt) / 2;
 		TCPSTAT_INC(tcps_cachedrtt);
 	}
 	if (hcml->rmx_rttvar != 0) {
 	        if (hc_entry->rmx_rttvar == 0)
 			hc_entry->rmx_rttvar = hcml->rmx_rttvar;
 		else
-			hc_entry->rmx_rttvar =
-			    (hc_entry->rmx_rttvar + hcml->rmx_rttvar) / 2;
+			hc_entry->rmx_rttvar = ((uint64_t)hc_entry->rmx_rttvar +
+			    (uint64_t)hcml->rmx_rttvar) / 2;
 		TCPSTAT_INC(tcps_cachedrttvar);
 	}
 	if (hcml->rmx_ssthresh != 0) {
@@ -560,8 +584,8 @@ tcp_hc_update(struct in_conninfo *inc, struct hc_metrics_lite *hcml)
 		if (hc_entry->rmx_cwnd == 0)
 			hc_entry->rmx_cwnd = hcml->rmx_cwnd;
 		else
-			hc_entry->rmx_cwnd =
-			    (hc_entry->rmx_cwnd + hcml->rmx_cwnd) / 2;
+			hc_entry->rmx_cwnd = ((uint64_t)hc_entry->rmx_cwnd +
+			    (uint64_t)hcml->rmx_cwnd) / 2;
 		/* TCPSTAT_INC(tcps_cachedcwnd); */
 	}
 	if (hcml->rmx_sendpipe != 0) {
@@ -569,7 +593,8 @@ tcp_hc_update(struct in_conninfo *inc, struct hc_metrics_lite *hcml)
 			hc_entry->rmx_sendpipe = hcml->rmx_sendpipe;
 		else
 			hc_entry->rmx_sendpipe =
-			    (hc_entry->rmx_sendpipe + hcml->rmx_sendpipe) /2;
+			    ((uint64_t)hc_entry->rmx_sendpipe +
+			    (uint64_t)hcml->rmx_sendpipe) /2;
 		/* TCPSTAT_INC(tcps_cachedsendpipe); */
 	}
 	if (hcml->rmx_recvpipe != 0) {
@@ -577,7 +602,8 @@ tcp_hc_update(struct in_conninfo *inc, struct hc_metrics_lite *hcml)
 			hc_entry->rmx_recvpipe = hcml->rmx_recvpipe;
 		else
 			hc_entry->rmx_recvpipe =
-			    (hc_entry->rmx_recvpipe + hcml->rmx_recvpipe) /2;
+			    ((uint64_t)hc_entry->rmx_recvpipe +
+			    (uint64_t)hcml->rmx_recvpipe) /2;
 		/* TCPSTAT_INC(tcps_cachedrecvpipe); */
 	}
 
@@ -614,7 +640,7 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
 		TAILQ_FOREACH(hc_entry, &V_tcp_hostcache.hashbase[i].hch_bucket,
 			      rmx_q) {
 			sbuf_printf(&sb,
-			    "%-15s %5lu %8lu %6lums %6lums %8lu %8lu %8lu %4lu "
+			    "%-15s %5u %8u %6lums %6lums %8u %8u %8u %4lu "
 			    "%4lu %4i\n",
 			    hc_entry->ip4.s_addr ? inet_ntoa(hc_entry->ip4) :
 #ifdef INET6
@@ -624,9 +650,9 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
 #endif
 			    hc_entry->rmx_mtu,
 			    hc_entry->rmx_ssthresh,
-			    msec(hc_entry->rmx_rtt *
+			    msec((u_long)hc_entry->rmx_rtt *
 				(RTM_RTTUNIT / (hz * TCP_RTT_SCALE))),
-			    msec(hc_entry->rmx_rttvar *
+			    msec((u_long)hc_entry->rmx_rttvar *
 				(RTM_RTTUNIT / (hz * TCP_RTTVAR_SCALE))),
 			    hc_entry->rmx_cwnd,
 			    hc_entry->rmx_sendpipe,
diff --git a/freebsd/sys/netinet/tcp_hostcache.h b/freebsd/sys/netinet/tcp_hostcache.h
index 44875ff..23a0c67 100644
--- a/freebsd/sys/netinet/tcp_hostcache.h
+++ b/freebsd/sys/netinet/tcp_hostcache.h
@@ -48,22 +48,22 @@ struct hc_head {
 struct hc_metrics {
 	/* housekeeping */
 	TAILQ_ENTRY(hc_metrics) rmx_q;
-	struct	hc_head *rmx_head; /* head of bucket tail queue */
-	struct	in_addr ip4;	/* IP address */
-	struct	in6_addr ip6;	/* IP6 address */
-	uint32_t ip6_zoneid;	/* IPv6 scope zone id */
+	struct		hc_head *rmx_head; /* head of bucket tail queue */
+	struct		in_addr ip4;	/* IP address */
+	struct		in6_addr ip6;	/* IP6 address */
+	uint32_t	ip6_zoneid;	/* IPv6 scope zone id */
 	/* endpoint specific values for tcp */
-	u_long	rmx_mtu;	/* MTU for this path */
-	u_long	rmx_ssthresh;	/* outbound gateway buffer limit */
-	u_long	rmx_rtt;	/* estimated round trip time */
-	u_long	rmx_rttvar;	/* estimated rtt variance */
-	u_long	rmx_cwnd;	/* congestion window */
-	u_long	rmx_sendpipe;	/* outbound delay-bandwidth product */
-	u_long	rmx_recvpipe;	/* inbound delay-bandwidth product */
+	uint32_t	rmx_mtu;	/* MTU for this path */
+	uint32_t	rmx_ssthresh;	/* outbound gateway buffer limit */
+	uint32_t	rmx_rtt;	/* estimated round trip time */
+	uint32_t	rmx_rttvar;	/* estimated rtt variance */
+	uint32_t	rmx_cwnd;	/* congestion window */
+	uint32_t	rmx_sendpipe;	/* outbound delay-bandwidth product */
+	uint32_t	rmx_recvpipe;	/* inbound delay-bandwidth product */
 	/* TCP hostcache internal data */
-	int	rmx_expire;	/* lifetime for object */
-	u_long	rmx_hits;	/* number of hits */
-	u_long	rmx_updates;	/* number of updates */
+	int		rmx_expire;	/* lifetime for object */
+	u_long		rmx_hits;	/* number of hits */
+	u_long		rmx_updates;	/* number of updates */
 };
 
 struct tcp_hostcache {
diff --git a/freebsd/sys/netinet/tcp_input.c b/freebsd/sys/netinet/tcp_input.c
index eaa3eb3..7e07fc0 100644
--- a/freebsd/sys/netinet/tcp_input.c
+++ b/freebsd/sys/netinet/tcp_input.c
@@ -59,7 +59,9 @@ __FBSDID("$FreeBSD$");
 
 #include <rtems/bsd/sys/param.h>
 #include <sys/kernel.h>
+#ifdef TCP_HHOOK
 #include <sys/hhook.h>
+#endif
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/proc.h>		/* for proc0 declaration */
@@ -280,6 +282,7 @@ kmod_tcpstat_inc(int statnum)
 	counter_u64_add(VNET(tcpstat)[statnum], 1);
 }
 
+#ifdef TCP_HHOOK
 /*
  * Wrapper for the TCP established input helper hook.
  */
@@ -297,15 +300,18 @@ hhook_run_tcp_est_in(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to)
 		    tp->osd);
 	}
 }
+#endif
 
 /*
  * CC wrapper hook functions
  */
 void
-cc_ack_received(struct tcpcb *tp, struct tcphdr *th, uint16_t type)
+cc_ack_received(struct tcpcb *tp, struct tcphdr *th, uint16_t nsegs,
+    uint16_t type)
 {
 	INP_WLOCK_ASSERT(tp->t_inpcb);
 
+	tp->ccv->nsegs = nsegs;
 	tp->ccv->bytes_this_ack = BYTES_THIS_ACK(tp, th);
 	if (tp->snd_cwnd <= tp->snd_wnd)
 		tp->ccv->flags |= CCF_CWND_LIMITED;
@@ -315,7 +321,7 @@ cc_ack_received(struct tcpcb *tp, struct tcphdr *th, uint16_t type)
 	if (type == CC_ACK) {
 		if (tp->snd_cwnd > tp->snd_ssthresh) {
 			tp->t_bytes_acked += min(tp->ccv->bytes_this_ack,
-			     V_tcp_abc_l_var * tcp_maxseg(tp));
+			     nsegs * V_tcp_abc_l_var * tcp_maxseg(tp));
 			if (tp->t_bytes_acked >= tp->snd_cwnd) {
 				tp->t_bytes_acked -= tp->snd_cwnd;
 				tp->ccv->flags |= CCF_ABC_SENTAWND;
@@ -434,9 +440,16 @@ cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type)
 		tp->t_dupacks = 0;
 		tp->t_bytes_acked = 0;
 		EXIT_RECOVERY(tp->t_flags);
-		tp->snd_ssthresh = max(2, min(tp->snd_wnd, tp->snd_cwnd) / 2 /
-		    maxseg) * maxseg;
-		tp->snd_cwnd = maxseg;
+		if (CC_ALGO(tp)->cong_signal == NULL) {
+			/*
+			 * RFC5681 Section 3.1 
+			 * ssthresh = max (FlightSize / 2, 2*SMSS) eq (4)
+			 */
+			tp->snd_ssthresh =
+			    max((tp->snd_max - tp->snd_una) / 2 / maxseg, 2)
+				* maxseg;
+			tp->snd_cwnd = maxseg;
+		}
 		break;
 	case CC_RTO_ERR:
 		TCPSTAT_INC(tcps_sndrexmitbad);
@@ -603,7 +616,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
 #ifdef TCP_SIGNATURE
 	uint8_t sig_checked = 0;
 #endif
-	uint8_t iptos = 0;
+	uint8_t iptos;
 	struct m_tag *fwd_tag = NULL;
 #ifdef INET6
 	struct ip6_hdr *ip6 = NULL;
@@ -675,6 +688,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
 			/* XXX stat */
 			goto drop;
 		}
+		iptos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
 	}
 #endif
 #if defined(INET) && defined(INET6)
@@ -701,6 +715,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
 		th = (struct tcphdr *)((caddr_t)ip + off0);
 		tlen = ntohs(ip->ip_len) - off0;
 
+		iptos = ip->ip_tos;
 		if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
 			if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
 				th->th_sum = m->m_pkthdr.csum_data;
@@ -721,29 +736,20 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
 			ipov->ih_len = htons(tlen);
 			th->th_sum = in_cksum(m, len);
 			/* Reset length for SDT probes. */
-			ip->ip_len = htons(tlen + off0);
+			ip->ip_len = htons(len);
+			/* Reset TOS bits */
+			ip->ip_tos = iptos;
+			/* Re-initialization for later version check */
+			ip->ip_v = IPVERSION;
 		}
 
 		if (th->th_sum) {
 			TCPSTAT_INC(tcps_rcvbadsum);
 			goto drop;
 		}
-		/* Re-initialization for later version check */
-		ip->ip_v = IPVERSION;
 	}
 #endif /* INET */
 
-#ifdef INET6
-	if (isipv6)
-		iptos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
-#endif
-#if defined(INET) && defined(INET6)
-	else
-#endif
-#ifdef INET
-		iptos = ip->ip_tos;
-#endif
-
 	/*
 	 * Check that TCP offset makes sense,
 	 * pull out TCP options and adjust length.		XXX
@@ -923,6 +929,16 @@ findpcb:
 		goto dropwithreset;
 	}
 	INP_WLOCK_ASSERT(inp);
+	/*
+	 * While waiting for inp lock during the lookup, another thread
+	 * can have dropped the inpcb, in which case we need to loop back
+	 * and try to find a new inpcb to deliver to.
+	 */
+	if (inp->inp_flags & INP_DROPPED) {
+		INP_WUNLOCK(inp);
+		inp = NULL;
+		goto findpcb;
+	}
 	if ((inp->inp_flowtype == M_HASHTYPE_NONE) &&
 	    (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) &&
 	    ((inp->inp_socket == NULL) ||
@@ -983,6 +999,10 @@ relocked:
 				if (in_pcbrele_wlocked(inp)) {
 					inp = NULL;
 					goto findpcb;
+				} else if (inp->inp_flags & INP_DROPPED) {
+					INP_WUNLOCK(inp);
+					inp = NULL;
+					goto findpcb;
 				}
 			} else
 				ti_locked = TI_RLOCKED;
@@ -1031,7 +1051,7 @@ relocked:
 #endif
 	if (!((tp->t_state == TCPS_ESTABLISHED && (thflags & TH_SYN) == 0) ||
 	      (tp->t_state == TCPS_LISTEN && (thflags & TH_SYN) &&
-	       !(tp->t_flags & TF_FASTOPEN)))) {
+	       !IS_FASTOPEN(tp->t_flags)))) {
 		if (ti_locked == TI_UNLOCKED) {
 			if (INP_INFO_TRY_RLOCK(&V_tcbinfo) == 0) {
 				in_pcbref(inp);
@@ -1042,6 +1062,10 @@ relocked:
 				if (in_pcbrele_wlocked(inp)) {
 					inp = NULL;
 					goto findpcb;
+				} else if (inp->inp_flags & INP_DROPPED) {
+					INP_WUNLOCK(inp);
+					inp = NULL;
+					goto findpcb;
 				}
 				goto relocked;
 			} else
@@ -1074,11 +1098,11 @@ relocked:
 	 * state) we look into the SYN cache if this is a new connection
 	 * attempt or the completion of a previous one.
 	 */
-	if (so->so_options & SO_ACCEPTCONN) {
+	KASSERT(tp->t_state == TCPS_LISTEN || !(so->so_options & SO_ACCEPTCONN),
+	    ("%s: so accepting but tp %p not listening", __func__, tp));
+	if (tp->t_state == TCPS_LISTEN && (so->so_options & SO_ACCEPTCONN)) {
 		struct in_conninfo inc;
 
-		KASSERT(tp->t_state == TCPS_LISTEN, ("%s: so accepting but "
-		    "tp not listening", __func__));
 		bzero(&inc, sizeof(inc));
 #ifdef INET6
 		if (isipv6) {
@@ -1124,7 +1148,7 @@ relocked:
 				goto dropwithreset;
 			}
 #ifdef TCP_RFC7413
-new_tfo_socket:
+tfo_socket_result:
 #endif
 			if (so == NULL) {
 				/*
@@ -1390,7 +1414,7 @@ new_tfo_socket:
 		tcp_dooptions(&to, optp, optlen, TO_SYN);
 #ifdef TCP_RFC7413
 		if (syncache_add(&inc, &to, th, inp, &so, m, NULL, NULL))
-			goto new_tfo_socket;
+			goto tfo_socket_result;
 #else
 		syncache_add(&inc, &to, th, inp, &so, m, NULL, NULL);
 #endif
@@ -1503,12 +1527,15 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 {
 	int thflags, acked, ourfinisacked, needoutput = 0, sack_changed;
 	int rstreason, todrop, win;
-	u_long tiwin;
+	uint32_t tiwin;
+	uint16_t nsegs;
 	char *s;
 	struct in_conninfo *inc;
 	struct mbuf *mfree;
 	struct tcpopt to;
+#ifdef TCP_RFC7413
 	int tfo_syn;
+#endif
 	
 #ifdef TCPDEBUG
 	/*
@@ -1523,6 +1550,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 	inc = &tp->t_inpcb->inp_inc;
 	tp->sackhint.last_sack_ack = 0;
 	sack_changed = 0;
+	nsegs = max(1, m->m_pkthdr.lro_nsegs);
 
 	/*
 	 * If this is either a state-changing packet or current state isn't
@@ -1564,8 +1592,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 	 * validation to ignore broken/spoofed segs.
 	 */
 	tp->t_rcvtime = ticks;
-	if (TCPS_HAVEESTABLISHED(tp->t_state))
-		tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp));
 
 	/*
 	 * Scale up the window into a 32-bit value.
@@ -1741,7 +1767,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 				 */
 				if ((to.to_flags & TOF_TS) != 0 &&
 				    to.to_tsecr) {
-					u_int t;
+					uint32_t t;
 
 					t = tcp_ts_getticks() - to.to_tsecr;
 					if (!tp->t_rttlow || tp->t_rttlow > t)
@@ -1758,10 +1784,12 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 				}
 				acked = BYTES_THIS_ACK(tp, th);
 
+#ifdef TCP_HHOOK
 				/* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */
 				hhook_run_tcp_est_in(tp, th, &to);
+#endif
 
-				TCPSTAT_INC(tcps_rcvackpack);
+				TCPSTAT_ADD(tcps_rcvackpack, nsegs);
 				TCPSTAT_ADD(tcps_rcvackbyte, acked);
 				sbdrop(&so->so_snd, acked);
 				if (SEQ_GT(tp->snd_una, tp->snd_recover) &&
@@ -1774,7 +1802,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 				 * typically means increasing the congestion
 				 * window.
 				 */
-				cc_ack_received(tp, th, CC_ACK);
+				cc_ack_received(tp, th, nsegs, CC_ACK);
 
 				tp->snd_una = th->th_ack;
 				/*
@@ -1840,7 +1868,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 			 * rcv_nxt.
 			 */
 			tp->rcv_up = tp->rcv_nxt;
-			TCPSTAT_INC(tcps_rcvpack);
+			TCPSTAT_ADD(tcps_rcvpack, nsegs);
 			TCPSTAT_ADD(tcps_rcvbyte, tlen);
 #ifdef TCPDEBUG
 			if (so->so_options & SO_DEBUG)
@@ -1963,7 +1991,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 				goto dropwithreset;
 		}
 #ifdef TCP_RFC7413
-		if (tp->t_flags & TF_FASTOPEN) {
+		if (IS_FASTOPEN(tp->t_flags)) {
 			/*
 			 * When a TFO connection is in SYN_RECEIVED, the
 			 * only valid packets are the initial SYN, a
@@ -2030,7 +2058,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 				(TF_RCVD_SCALE|TF_REQ_SCALE)) {
 				tp->rcv_scale = tp->request_r_scale;
 			}
-			tp->rcv_adv += imin(tp->rcv_wnd,
+			tp->rcv_adv += min(tp->rcv_wnd,
 			    TCP_MAXWIN << tp->rcv_scale);
 			tp->snd_una++;		/* SYN is acked */
 			/*
@@ -2176,9 +2204,10 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 				case TCPS_FIN_WAIT_1:
 				case TCPS_FIN_WAIT_2:
 				case TCPS_CLOSE_WAIT:
+				case TCPS_CLOSING:
+				case TCPS_LAST_ACK:
 					so->so_error = ECONNRESET;
 				close:
-					tcp_state_change(tp, TCPS_CLOSED);
 					/* FALLTHROUGH */
 				default:
 					tp = tcp_close(tp);
@@ -2397,7 +2426,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 		    (tp->t_flags & TF_NEEDSYN)) {
 #ifdef TCP_RFC7413
 			if (tp->t_state == TCPS_SYN_RECEIVED &&
-			    tp->t_flags & TF_FASTOPEN) {
+			    IS_FASTOPEN(tp->t_flags)) {
 				tp->snd_wnd = tiwin;
 				cc_conn_init(tp);
 			}
@@ -2460,7 +2489,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 			 * snd_cwnd reduction that occurs when a TFO SYN|ACK
 			 * is retransmitted.
 			 */
-			if (!(tp->t_flags & TF_FASTOPEN))
+			if (!IS_FASTOPEN(tp->t_flags))
 #endif
 				cc_conn_init(tp);
 			tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp));
@@ -2504,8 +2533,10 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 			 */
 			tp->sackhint.sacked_bytes = 0;
 
+#ifdef TCP_HHOOK
 		/* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */
 		hhook_run_tcp_est_in(tp, th, &to);
+#endif
 
 		if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
 			u_int maxseg;
@@ -2572,7 +2603,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 					tp->t_dupacks = 0;
 				else if (++tp->t_dupacks > tcprexmtthresh ||
 				     IN_FASTRECOVERY(tp->t_flags)) {
-					cc_ack_received(tp, th, CC_DUPACK);
+					cc_ack_received(tp, th, nsegs,
+					    CC_DUPACK);
 					if ((tp->t_flags & TF_SACK_PERMIT) &&
 					    IN_FASTRECOVERY(tp->t_flags)) {
 						int awnd;
@@ -2591,6 +2623,15 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 
 						if (awnd < tp->snd_ssthresh) {
 							tp->snd_cwnd += maxseg;
+							/*
+							 * RFC5681 Section 3.2 talks about cwnd
+							 * inflation on additional dupacks and
+							 * deflation on recovering from loss.
+							 *
+							 * We keep cwnd into check so that
+							 * we don't have to 'deflate' it when we
+							 * get out of recovery.
+							 */
 							if (tp->snd_cwnd > tp->snd_ssthresh)
 								tp->snd_cwnd = tp->snd_ssthresh;
 						}
@@ -2622,26 +2663,30 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 					}
 					/* Congestion signal before ack. */
 					cc_cong_signal(tp, th, CC_NDUPACK);
-					cc_ack_received(tp, th, CC_DUPACK);
+					cc_ack_received(tp, th, nsegs,
+					    CC_DUPACK);
 					tcp_timer_activate(tp, TT_REXMT, 0);
 					tp->t_rtttime = 0;
 					if (tp->t_flags & TF_SACK_PERMIT) {
 						TCPSTAT_INC(
 						    tcps_sack_recovery_episode);
 						tp->sack_newdata = tp->snd_nxt;
-						tp->snd_cwnd = maxseg;
+						if (CC_ALGO(tp)->cong_signal == NULL)
+							tp->snd_cwnd = maxseg;
 						(void) tp->t_fb->tfb_tcp_output(tp);
 						goto drop;
 					}
 					tp->snd_nxt = th->th_ack;
-					tp->snd_cwnd = maxseg;
+					if (CC_ALGO(tp)->cong_signal == NULL)
+						tp->snd_cwnd = maxseg;
 					(void) tp->t_fb->tfb_tcp_output(tp);
 					KASSERT(tp->snd_limited <= 2,
 					    ("%s: tp->snd_limited too big",
 					    __func__));
-					tp->snd_cwnd = tp->snd_ssthresh +
-					     maxseg *
-					     (tp->t_dupacks - tp->snd_limited);
+					if (CC_ALGO(tp)->cong_signal == NULL)
+						tp->snd_cwnd = tp->snd_ssthresh +
+						    maxseg *
+						    (tp->t_dupacks - tp->snd_limited);
 					if (SEQ_GT(onxt, tp->snd_nxt))
 						tp->snd_nxt = onxt;
 					goto drop;
@@ -2656,8 +2701,9 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
 					 * segment. Restore the original
 					 * snd_cwnd after packet transmission.
 					 */
-					cc_ack_received(tp, th, CC_DUPACK);
-					u_long oldcwnd = tp->snd_cwnd;
+					cc_ack_received(tp, th, nsegs,
+					    CC_DUPACK);
+					uint32_t oldcwnd = tp->snd_cwnd;
 					tcp_seq oldsndmax = tp->snd_max;
 					u_int sent;
 					int avail;
@@ -2758,7 +2804,7 @@ process_ACK:
 		KASSERT(acked >= 0, ("%s: acked unexepectedly negative "
 		    "(tp->snd_una=%u, th->th_ack=%u, tp=%p, m=%p)", __func__,
 		    tp->snd_una, th->th_ack, tp, m));
-		TCPSTAT_INC(tcps_rcvackpack);
+		TCPSTAT_ADD(tcps_rcvackpack, nsegs);
 		TCPSTAT_ADD(tcps_rcvackbyte, acked);
 
 		/*
@@ -2787,7 +2833,7 @@ process_ACK:
 		 * huge RTT and blow up the retransmit timer.
 		 */
 		if ((to.to_flags & TOF_TS) != 0 && to.to_tsecr) {
-			u_int t;
+			uint32_t t;
 
 			t = tcp_ts_getticks() - to.to_tsecr;
 			if (!tp->t_rttlow || tp->t_rttlow > t)
@@ -2823,7 +2869,7 @@ process_ACK:
 		 * control related information. This typically means increasing
 		 * the congestion window.
 		 */
-		cc_ack_received(tp, th, CC_ACK);
+		cc_ack_received(tp, th, nsegs, CC_ACK);
 
 		SOCKBUF_LOCK(&so->so_snd);
 		if (acked > sbavail(&so->so_snd)) {
@@ -2836,7 +2882,7 @@ process_ACK:
 			ourfinisacked = 1;
 		} else {
 			mfree = sbcut_locked(&so->so_snd, acked);
-			if (tp->snd_wnd >= (u_long) acked)
+			if (tp->snd_wnd >= (uint32_t) acked)
 				tp->snd_wnd -= acked;
 			else
 				tp->snd_wnd = 0;
@@ -2997,7 +3043,7 @@ step6:
 		 * but if two URG's are pending at once, some out-of-band
 		 * data may creep in... ick.
 		 */
-		if (th->th_urp <= (u_long)tlen &&
+		if (th->th_urp <= (uint32_t)tlen &&
 		    !(so->so_options & SO_OOBINLINE)) {
 			/* hdr drop is delayed */
 			tcp_pulloutofband(so, th, m, drop_hdrlen);
@@ -3022,8 +3068,12 @@ dodata:							/* XXX */
 	 * case PRU_RCVD).  If a FIN has already been received on this
 	 * connection then we just ignore the text.
 	 */
+#ifdef TCP_RFC7413
 	tfo_syn = ((tp->t_state == TCPS_SYN_RECEIVED) &&
-		   (tp->t_flags & TF_FASTOPEN));
+		   IS_FASTOPEN(tp->t_flags));
+#else
+#define	tfo_syn	(false)
+#endif
 	if ((tlen || (thflags & TH_FIN) || tfo_syn) &&
 	    TCPS_HAVERCVDFIN(tp->t_state) == 0) {
 		tcp_seq save_start = th->th_seq;
@@ -3247,6 +3297,9 @@ drop:
 	if (tp != NULL)
 		INP_WUNLOCK(tp->t_inpcb);
 	m_freem(m);
+#ifndef TCP_RFC7413
+#undef	tfo_syn
+#endif
 }
 
 /*
@@ -3306,6 +3359,8 @@ tcp_dropwithreset(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp,
 	} else {
 		if (th->th_flags & TH_SYN)
 			tlen++;
+		if (th->th_flags & TH_FIN)
+			tlen++;
 		tcp_respond(tp, mtod(m, void *), th, m, th->th_seq+tlen,
 		    (tcp_seq)0, TH_RST|TH_ACK);
 	}
@@ -3562,7 +3617,7 @@ tcp_mss_update(struct tcpcb *tp, int offer, int mtuoffer,
     struct hc_metrics_lite *metricptr, struct tcp_ifcap *cap)
 {
 	int mss = 0;
-	u_long maxmtu = 0;
+	uint32_t maxmtu = 0;
 	struct inpcb *inp = tp->t_inpcb;
 	struct hc_metrics_lite metrics;
 #ifdef INET6
@@ -3708,7 +3763,7 @@ void
 tcp_mss(struct tcpcb *tp, int offer)
 {
 	int mss;
-	u_long bufsize;
+	uint32_t bufsize;
 	struct inpcb *inp;
 	struct socket *so;
 	struct hc_metrics_lite metrics;
@@ -3745,7 +3800,15 @@ tcp_mss(struct tcpcb *tp, int offer)
 			(void)sbreserve_locked(&so->so_snd, bufsize, so, NULL);
 	}
 	SOCKBUF_UNLOCK(&so->so_snd);
-	tp->t_maxseg = mss;
+	/*
+	 * Sanity check: make sure that maxseg will be large
+	 * enough to allow some data on segments even if the
+	 * all the option space is used (40bytes).  Otherwise
+	 * funny things may happen in tcp_output.
+	 *
+	 * XXXGL: shouldn't we reserve space for IP/IPv6 options?
+	 */
+	tp->t_maxseg = max(mss, 64);
 
 	SOCKBUF_LOCK(&so->so_rcv);
 	if ((so->so_rcv.sb_hiwat == V_tcp_recvspace) && metrics.rmx_recvpipe)
@@ -3777,8 +3840,8 @@ int
 tcp_mssopt(struct in_conninfo *inc)
 {
 	int mss = 0;
-	u_long maxmtu = 0;
-	u_long thcmtu = 0;
+	uint32_t thcmtu = 0;
+	uint32_t maxmtu = 0;
 	size_t min_protoh;
 
 	KASSERT(inc != NULL, ("tcp_mssopt with NULL in_conninfo pointer"));
@@ -3823,7 +3886,7 @@ void
 tcp_newreno_partial_ack(struct tcpcb *tp, struct tcphdr *th)
 {
 	tcp_seq onxt = tp->snd_nxt;
-	u_long ocwnd = tp->snd_cwnd;
+	uint32_t ocwnd = tp->snd_cwnd;
 	u_int maxseg = tcp_maxseg(tp);
 
 	INP_WLOCK_ASSERT(tp->t_inpcb);
diff --git a/freebsd/sys/netinet/tcp_lro.c b/freebsd/sys/netinet/tcp_lro.c
index 3550ab8..f318e78 100644
--- a/freebsd/sys/netinet/tcp_lro.c
+++ b/freebsd/sys/netinet/tcp_lro.c
@@ -394,6 +394,7 @@ tcp_lro_flush(struct lro_ctrl *lc, struct lro_entry *le)
 #endif
 	}
 
+	le->m_head->m_pkthdr.lro_nsegs = le->append_cnt + 1;
 	(*lc->ifp->if_input)(lc->ifp, le->m_head);
 	lc->lro_queued += le->append_cnt + 1;
 	lc->lro_flushed++;
diff --git a/freebsd/sys/netinet/tcp_output.c b/freebsd/sys/netinet/tcp_output.c
index af11d80..a310512 100644
--- a/freebsd/sys/netinet/tcp_output.c
+++ b/freebsd/sys/netinet/tcp_output.c
@@ -42,7 +42,9 @@ __FBSDID("$FreeBSD$");
 #include <rtems/bsd/sys/param.h>
 #include <sys/systm.h>
 #include <sys/domain.h>
+#ifdef TCP_HHOOK
 #include <sys/hhook.h>
+#endif
 #include <sys/kernel.h>
 #include <rtems/bsd/sys/lock.h>
 #include <sys/mbuf.h>
@@ -142,17 +144,20 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_max, CTLFLAG_VNET | CTLFLAG_RW,
 	    tcp_timer_active((tp), TT_PERSIST),				\
 	    ("neither rexmt nor persist timer is set"))
 
+#ifdef TCP_HHOOK
 static void inline	hhook_run_tcp_est_out(struct tcpcb *tp,
 			    struct tcphdr *th, struct tcpopt *to,
-			    long len, int tso);
+			    uint32_t len, int tso);
+#endif
 static void inline	cc_after_idle(struct tcpcb *tp);
 
+#ifdef TCP_HHOOK
 /*
  * Wrapper for the TCP established output helper hook.
  */
 static void inline
 hhook_run_tcp_est_out(struct tcpcb *tp, struct tcphdr *th,
-    struct tcpopt *to, long len, int tso)
+    struct tcpopt *to, uint32_t len, int tso)
 {
 	struct tcp_hhook_data hhook_data;
 
@@ -167,6 +172,7 @@ hhook_run_tcp_est_out(struct tcpcb *tp, struct tcphdr *th,
 		    tp->osd);
 	}
 }
+#endif
 
 /*
  * CC wrapper hook functions
@@ -187,7 +193,8 @@ int
 tcp_output(struct tcpcb *tp)
 {
 	struct socket *so = tp->t_inpcb->inp_socket;
-	long len, recwin, sendwin;
+	int32_t len;
+	uint32_t recwin, sendwin;
 	int off, flags, error = 0;	/* Keep compiler happy */
 	struct mbuf *m;
 	struct ip *ip = NULL;
@@ -225,7 +232,7 @@ tcp_output(struct tcpcb *tp)
 	 * For TFO connections in SYN_RECEIVED, only allow the initial
 	 * SYN|ACK and those sent by the retransmit timer.
 	 */
-	if ((tp->t_flags & TF_FASTOPEN) &&
+	if (IS_FASTOPEN(tp->t_flags) &&
 	    (tp->t_state == TCPS_SYN_RECEIVED) &&
 	    SEQ_GT(tp->snd_max, tp->snd_una) &&    /* initial SYN|ACK sent */
 	    (tp->snd_nxt != tp->snd_una))          /* not a retransmit */
@@ -279,11 +286,10 @@ again:
 	p = NULL;
 	if ((tp->t_flags & TF_SACK_PERMIT) && IN_FASTRECOVERY(tp->t_flags) &&
 	    (p = tcp_sack_output(tp, &sack_bytes_rxmt))) {
-		long cwin;
+		uint32_t cwin;
 		
-		cwin = min(tp->snd_wnd, tp->snd_cwnd) - sack_bytes_rxmt;
-		if (cwin < 0)
-			cwin = 0;
+		cwin =
+		    imax(min(tp->snd_wnd, tp->snd_cwnd) - sack_bytes_rxmt, 0);
 		/* Do not retransmit SACK segments beyond snd_recover */
 		if (SEQ_GT(p->end, tp->snd_recover)) {
 			/*
@@ -302,10 +308,10 @@ again:
 				goto after_sack_rexmit;
 			} else
 				/* Can rexmit part of the current hole */
-				len = ((long)ulmin(cwin,
+				len = ((int32_t)ulmin(cwin,
 						   tp->snd_recover - p->rxmit));
 		} else
-			len = ((long)ulmin(cwin, p->end - p->rxmit));
+			len = ((int32_t)ulmin(cwin, p->end - p->rxmit));
 		off = p->rxmit - tp->snd_una;
 		KASSERT(off >= 0,("%s: sack block to the left of una : %d",
 		    __func__, off));
@@ -378,17 +384,17 @@ after_sack_rexmit:
 	 */
 	if (sack_rxmit == 0) {
 		if (sack_bytes_rxmt == 0)
-			len = ((long)ulmin(sbavail(&so->so_snd), sendwin) -
+			len = ((int32_t)ulmin(sbavail(&so->so_snd), sendwin) -
 			    off);
 		else {
-			long cwin;
+			int32_t cwin;
 
                         /*
 			 * We are inside of a SACK recovery episode and are
 			 * sending new data, having retransmitted all the
 			 * data possible in the scoreboard.
 			 */
-			len = ((long)ulmin(sbavail(&so->so_snd), tp->snd_wnd) -
+			len = ((int32_t)min(sbavail(&so->so_snd), tp->snd_wnd) -
 			    off);
 			/*
 			 * Don't remove this (len > 0) check !
@@ -404,7 +410,7 @@ after_sack_rexmit:
 					sack_bytes_rxmt;
 				if (cwin < 0)
 					cwin = 0;
-				len = lmin(len, cwin);
+				len = imin(len, cwin);
 			}
 		}
 	}
@@ -422,7 +428,7 @@ after_sack_rexmit:
 		 * When sending additional segments following a TFO SYN|ACK,
 		 * do not include the SYN bit.
 		 */
-		if ((tp->t_flags & TF_FASTOPEN) &&
+		if (IS_FASTOPEN(tp->t_flags) &&
 		    (tp->t_state == TCPS_SYN_RECEIVED))
 			flags &= ~TH_SYN;
 #endif
@@ -445,7 +451,7 @@ after_sack_rexmit:
 	 * don't include data, as the presence of data may have caused the
 	 * original SYN|ACK to have been dropped by a middlebox.
 	 */
-	if ((tp->t_flags & TF_FASTOPEN) &&
+	if (IS_FASTOPEN(tp->t_flags) &&
 	    (((tp->t_state == TCPS_SYN_RECEIVED) && (tp->t_rxtshift > 0)) ||
 	     (flags & TH_RST)))
 		len = 0;
@@ -568,7 +574,8 @@ after_sack_rexmit:
 			flags &= ~TH_FIN;
 	}
 
-	recwin = sbspace(&so->so_rcv);
+	recwin = lmin(lmax(sbspace(&so->so_rcv), 0),
+	    (long)TCP_MAXWIN << tp->rcv_scale);
 
 	/*
 	 * Sender silly window avoidance.   We transmit under the following
@@ -594,7 +601,7 @@ after_sack_rexmit:
 		 */
 		if (!(tp->t_flags & TF_MORETOCOME) &&	/* normal case */
 		    (idle || (tp->t_flags & TF_NODELAY)) &&
-		    len + off >= sbavail(&so->so_snd) &&
+		    (uint32_t)len + (uint32_t)off >= sbavail(&so->so_snd) &&
 		    (tp->t_flags & TF_NOPUSH) == 0) {
 			goto send;
 		}
@@ -645,10 +652,10 @@ after_sack_rexmit:
 		 * taking into account that we are limited by
 		 * TCP_MAXWIN << tp->rcv_scale.
 		 */
-		long adv;
+		int32_t adv;
 		int oldwin;
 
-		adv = min(recwin, (long)TCP_MAXWIN << tp->rcv_scale);
+		adv = recwin;
 		if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) {
 			oldwin = (tp->rcv_adv - tp->rcv_nxt);
 			adv -= oldwin;
@@ -656,15 +663,16 @@ after_sack_rexmit:
 			oldwin = 0;
 
 		/* 
-		 * If the new window size ends up being the same as the old
-		 * size when it is scaled, then don't force a window update.
+		 * If the new window size ends up being the same as or less
+		 * than the old size when it is scaled, then don't force
+		 * a window update.
 		 */
-		if (oldwin >> tp->rcv_scale == (adv + oldwin) >> tp->rcv_scale)
+		if (oldwin >> tp->rcv_scale >= (adv + oldwin) >> tp->rcv_scale)
 			goto dontupdate;
 
-		if (adv >= (long)(2 * tp->t_maxseg) &&
-		    (adv >= (long)(so->so_rcv.sb_hiwat / 4) ||
-		     recwin <= (long)(so->so_rcv.sb_hiwat / 8) ||
+		if (adv >= (int32_t)(2 * tp->t_maxseg) &&
+		    (adv >= (int32_t)(so->so_rcv.sb_hiwat / 4) ||
+		     recwin <= (so->so_rcv.sb_hiwat / 8) ||
 		     so->so_rcv.sb_hiwat <= 8 * tp->t_maxseg))
 			goto send;
 	}
@@ -780,7 +788,7 @@ send:
 			 * the TFO option may have caused the original
 			 * SYN|ACK to have been dropped by a middlebox.
 			 */
-			if ((tp->t_flags & TF_FASTOPEN) &&
+			if (IS_FASTOPEN(tp->t_flags) &&
 			    (tp->t_state == TCPS_SYN_RECEIVED) &&
 			    (tp->t_rxtshift == 0)) {
 				to.to_tfo_len = TCP_FASTOPEN_COOKIE_LEN;
@@ -951,7 +959,8 @@ send:
 			 * emptied:
 			 */
 			max_len = (tp->t_maxseg - optlen);
-			if ((off + len) < sbavail(&so->so_snd)) {
+			if (((uint32_t)off + (uint32_t)len) <
+			    sbavail(&so->so_snd)) {
 				moff = len % max_len;
 				if (moff != 0) {
 					len -= moff;
@@ -1047,11 +1056,11 @@ send:
 		mb = sbsndptr(&so->so_snd, off, len, &moff);
 
 		if (len <= MHLEN - hdrlen - max_linkhdr) {
-			m_copydata(mb, moff, (int)len,
+			m_copydata(mb, moff, len,
 			    mtod(m, caddr_t) + hdrlen);
 			m->m_len += len;
 		} else {
-			m->m_next = m_copy(mb, moff, (int)len);
+			m->m_next = m_copym(mb, moff, len, M_NOWAIT);
 			if (m->m_next == NULL) {
 				SOCKBUF_UNLOCK(&so->so_snd);
 				(void) m_free(m);
@@ -1067,7 +1076,8 @@ send:
 		 * give data to the user when a buffer fills or
 		 * a PUSH comes in.)
 		 */
-		if ((off + len == sbused(&so->so_snd)) && !(flags & TH_SYN))
+		if (((uint32_t)off + (uint32_t)len == sbused(&so->so_snd)) &&
+		    !(flags & TH_SYN))
 			flags |= TH_PUSH;
 		SOCKBUF_UNLOCK(&so->so_snd);
 	} else {
@@ -1200,14 +1210,12 @@ send:
 	 * Calculate receive window.  Don't shrink window,
 	 * but avoid silly window syndrome.
 	 */
-	if (recwin < (long)(so->so_rcv.sb_hiwat / 4) &&
-	    recwin < (long)tp->t_maxseg)
+	if (recwin < (so->so_rcv.sb_hiwat / 4) &&
+	    recwin < tp->t_maxseg)
 		recwin = 0;
 	if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt) &&
-	    recwin < (long)(tp->rcv_adv - tp->rcv_nxt))
-		recwin = (long)(tp->rcv_adv - tp->rcv_nxt);
-	if (recwin > (long)TCP_MAXWIN << tp->rcv_scale)
-		recwin = (long)TCP_MAXWIN << tp->rcv_scale;
+	    recwin < (tp->rcv_adv - tp->rcv_nxt))
+		recwin = (tp->rcv_adv - tp->rcv_nxt);
 
 	/*
 	 * According to RFC1323 the window field in a SYN (i.e., a <SYN>
@@ -1298,16 +1306,18 @@ send:
 
 #ifdef IPSEC
 	KASSERT(len + hdrlen + ipoptlen - ipsec_optlen == m_length(m, NULL),
-	    ("%s: mbuf chain shorter than expected: %ld + %u + %u - %u != %u",
+	    ("%s: mbuf chain shorter than expected: %d + %u + %u - %u != %u",
 	    __func__, len, hdrlen, ipoptlen, ipsec_optlen, m_length(m, NULL)));
 #else
 	KASSERT(len + hdrlen + ipoptlen == m_length(m, NULL),
-	    ("%s: mbuf chain shorter than expected: %ld + %u + %u != %u",
+	    ("%s: mbuf chain shorter than expected: %d + %u + %u != %u",
 	    __func__, len, hdrlen, ipoptlen, m_length(m, NULL)));
 #endif
 
+#ifdef TCP_HHOOK
 	/* Run HHOOK_TCP_ESTABLISHED_OUT helper hooks. */
 	hhook_run_tcp_est_out(tp, th, &to, len, tso);
+#endif
 
 #ifdef TCPDEBUG
 	/*
@@ -1521,7 +1531,7 @@ timer:
 			tp->t_flags |= TF_SENTFIN;
 		}
 		if (SEQ_GT(tp->snd_nxt + xlen, tp->snd_max))
-			tp->snd_max = tp->snd_nxt + len;
+			tp->snd_max = tp->snd_nxt + xlen;
 	}
 
 	if (error) {
@@ -1598,7 +1608,7 @@ timer:
 	 * then remember the size of the advertised window.
 	 * Any pending ACK has now been sent.
 	 */
-	if (recwin >= 0 && SEQ_GT(tp->rcv_nxt + recwin, tp->rcv_adv))
+	if (SEQ_GT(tp->rcv_nxt + recwin, tp->rcv_adv))
 		tp->rcv_adv = tp->rcv_nxt + recwin;
 	tp->last_ack_sent = tp->rcv_nxt;
 	tp->t_flags &= ~(TF_ACKNOW | TF_DELACK);
diff --git a/freebsd/sys/netinet/tcp_seq.h b/freebsd/sys/netinet/tcp_seq.h
index 51d971f..666cf60 100644
--- a/freebsd/sys/netinet/tcp_seq.h
+++ b/freebsd/sys/netinet/tcp_seq.h
@@ -75,20 +75,17 @@
  * tcp_ts_getticks() in ms, should be 1ms < x < 1000ms according to RFC 1323.
  * We always use 1ms granularity independent of hz.
  */
-static __inline u_int
+static __inline uint32_t
 tcp_ts_getticks(void)
 {
 	struct timeval tv;
-	u_long ms;
 
 	/*
 	 * getmicrouptime() should be good enough for any 1-1000ms granularity.
 	 * Do not use getmicrotime() here as it might break nfsroot/tcp.
 	 */
 	getmicrouptime(&tv);
-	ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
-
-	return (ms);
+	return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
 }
 #endif /* _KERNEL */
 
diff --git a/freebsd/sys/netinet/tcp_subr.c b/freebsd/sys/netinet/tcp_subr.c
index cff9bd7..4f196a1 100644
--- a/freebsd/sys/netinet/tcp_subr.c
+++ b/freebsd/sys/netinet/tcp_subr.c
@@ -48,9 +48,13 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/callout.h>
 #include <sys/eventhandler.h>
+#ifdef TCP_HHOOK
 #include <sys/hhook.h>
+#endif
 #include <sys/kernel.h>
+#ifdef TCP_HHOOK
 #include <sys/khelp.h>
+#endif
 #include <sys/sysctl.h>
 #include <sys/jail.h>
 #include <sys/malloc.h>
@@ -244,7 +248,9 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, signature_verify_input, CTLFLAG_RW,
 VNET_DEFINE(uma_zone_t, sack_hole_zone);
 #define	V_sack_hole_zone		VNET(sack_hole_zone)
 
+#ifdef TCP_HHOOK
 VNET_DEFINE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST+1]);
+#endif
 
 static struct inpcb *tcp_notify(struct inpcb *, int);
 static struct inpcb *tcp_mtudisc_notify(struct inpcb *, int);
@@ -455,7 +461,9 @@ struct tcpcb_mem {
 	struct	tcpcb		tcb;
 	struct	tcp_timer	tt;
 	struct	cc_var		ccv;
+#ifdef TCP_HHOOK
 	struct	osd		osd;
+#endif
 };
 
 static VNET_DEFINE(uma_zone_t, tcpcb_zone);
@@ -611,12 +619,14 @@ tcp_init(void)
 
 	tcbhash_tuneable = "net.inet.tcp.tcbhashsize";
 
+#ifdef TCP_HHOOK
 	if (hhook_head_register(HHOOK_TYPE_TCP, HHOOK_TCP_EST_IN,
 	    &V_tcp_hhh[HHOOK_TCP_EST_IN], HHOOK_NOWAIT|HHOOK_HEADISINVNET) != 0)
 		printf("%s: WARNING: unable to register helper hook\n", __func__);
 	if (hhook_head_register(HHOOK_TYPE_TCP, HHOOK_TCP_EST_OUT,
 	    &V_tcp_hhh[HHOOK_TCP_EST_OUT], HHOOK_NOWAIT|HHOOK_HEADISINVNET) != 0)
 		printf("%s: WARNING: unable to register helper hook\n", __func__);
+#endif
 	hashsize = TCBHASHSIZE;
 	TUNABLE_INT_FETCH(tcbhash_tuneable, &hashsize);
 	if (hashsize == 0) {
@@ -738,7 +748,10 @@ tcp_init(void)
 static void
 tcp_destroy(void *unused __unused)
 {
-	int error, n;
+	int n;
+#ifdef TCP_HHOOK
+	int error;
+#endif
 
 	/*
 	 * All our processes are gone, all our sockets should be cleaned
@@ -769,6 +782,7 @@ tcp_destroy(void *unused __unused)
 	tcp_fastopen_destroy();
 #endif
 
+#ifdef TCP_HHOOK
 	error = hhook_head_deregister(V_tcp_hhh[HHOOK_TCP_EST_IN]);
 	if (error != 0) {
 		printf("%s: WARNING: unable to deregister helper hook "
@@ -781,6 +795,7 @@ tcp_destroy(void *unused __unused)
 		    "type=%d, id=%d: error %d returned\n", __func__,
 		    HHOOK_TYPE_TCP, HHOOK_TCP_EST_OUT, error);
 	}
+#endif
 }
 VNET_SYSUNINIT(tcp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, tcp_destroy, NULL);
 #endif
@@ -919,8 +934,8 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
 	if (tp != NULL) {
 		if (!(flags & TH_RST)) {
 			win = sbspace(&inp->inp_socket->so_rcv);
-			if (win > (long)TCP_MAXWIN << tp->rcv_scale)
-				win = (long)TCP_MAXWIN << tp->rcv_scale;
+			if (win > TCP_MAXWIN << tp->rcv_scale)
+				win = TCP_MAXWIN << tp->rcv_scale;
 		}
 		if ((tp->t_flags & TF_NOOPT) == 0)
 			incl_opts = true;
@@ -1210,6 +1225,7 @@ tcp_newtcpcb(struct inpcb *inp)
 			return (NULL);
 		}
 
+#ifdef TCP_HHOOK
 	tp->osd = &tm->osd;
 	if (khelp_init_osd(HELPER_CLASS_TCP, tp->osd)) {
 		if (tp->t_fb->tfb_tcp_fb_fini)
@@ -1218,6 +1234,7 @@ tcp_newtcpcb(struct inpcb *inp)
 		uma_zfree(V_tcpcb_zone, tm);
 		return (NULL);
 	}
+#endif
 
 #ifdef VIMAGE
 	tp->t_vnet = inp->inp_vnet;
@@ -1418,7 +1435,7 @@ tcp_discardcb(struct tcpcb *tp)
 	 */
 	if (tp->t_rttupdated >= 4) {
 		struct hc_metrics_lite metrics;
-		u_long ssthresh;
+		uint32_t ssthresh;
 
 		bzero(&metrics, sizeof(metrics));
 		/*
@@ -1439,7 +1456,7 @@ tcp_discardcb(struct tcpcb *tp)
 			ssthresh = (ssthresh + tp->t_maxseg / 2) / tp->t_maxseg;
 			if (ssthresh < 2)
 				ssthresh = 2;
-			ssthresh *= (u_long)(tp->t_maxseg +
+			ssthresh *= (tp->t_maxseg +
 #ifdef INET6
 			    (isipv6 ? sizeof (struct ip6_hdr) +
 				sizeof (struct tcphdr) :
@@ -1483,12 +1500,15 @@ tcp_discardcb(struct tcpcb *tp)
 	if (CC_ALGO(tp)->cb_destroy != NULL)
 		CC_ALGO(tp)->cb_destroy(tp->ccv);
 
+#ifdef TCP_HHOOK
 	khelp_destroy_osd(tp->osd);
+#endif
 
 	CC_ALGO(tp) = NULL;
 	inp->inp_ppcb = NULL;
 	if (tp->t_timers->tt_draincnt == 0) {
 		/* We own the last reference on tcpcb, let's free it. */
+		TCPSTATES_DEC(tp->t_state);
 		if (tp->t_fb->tfb_tcp_fb_fini)
 			(*tp->t_fb->tfb_tcp_fb_fini)(tp, 1);
 		refcount_release(&tp->t_fb->tfb_refcnt);
@@ -1518,6 +1538,7 @@ tcp_timer_discard(void *ptp)
 	tp->t_timers->tt_draincnt--;
 	if (tp->t_timers->tt_draincnt == 0) {
 		/* We own the last reference on this tcpcb, let's free it. */
+		TCPSTATES_DEC(tp->t_state);
 		if (tp->t_fb->tfb_tcp_fb_fini)
 			(*tp->t_fb->tfb_tcp_fb_fini)(tp, 1);
 		refcount_release(&tp->t_fb->tfb_refcnt);
@@ -1564,7 +1585,8 @@ tcp_close(struct tcpcb *tp)
 #endif
 	in_pcbdrop(inp);
 	TCPSTAT_INC(tcps_closed);
-	TCPSTATES_DEC(tp->t_state);
+	if (tp->t_state != TCPS_CLOSED)
+		tcp_state_change(tp, TCPS_CLOSED);
 	KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL"));
 	so = inp->inp_socket;
 	soisdisconnected(so);
@@ -1955,7 +1977,8 @@ tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
 	if (cmd == PRC_MSGSIZE)
 		notify = tcp_mtudisc_notify;
 	else if (V_icmp_may_rst && (cmd == PRC_UNREACH_ADMIN_PROHIB ||
-		cmd == PRC_UNREACH_PORT || cmd == PRC_TIMXCEED_INTRANS) && ip)
+		cmd == PRC_UNREACH_PORT || cmd == PRC_UNREACH_PROTOCOL || 
+		cmd == PRC_TIMXCEED_INTRANS) && ip)
 		notify = tcp_drop_syn_sent;
 
 	/*
@@ -2087,8 +2110,8 @@ tcp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
 	if (cmd == PRC_MSGSIZE)
 		notify = tcp_mtudisc_notify;
 	else if (V_icmp_may_rst && (cmd == PRC_UNREACH_ADMIN_PROHIB ||
-		cmd == PRC_UNREACH_PORT || cmd == PRC_TIMXCEED_INTRANS) &&
-		ip6 != NULL)
+		cmd == PRC_UNREACH_PORT || cmd == PRC_UNREACH_PROTOCOL || 
+		cmd == PRC_TIMXCEED_INTRANS) && ip6 != NULL)
 		notify = tcp_drop_syn_sent;
 
 	/*
@@ -2388,12 +2411,12 @@ tcp_mtudisc(struct inpcb *inp, int mtuoffer)
  * is called by TCP routines that access the rmx structure and by
  * tcp_mss_update to get the peer/interface MTU.
  */
-u_long
+uint32_t
 tcp_maxmtu(struct in_conninfo *inc, struct tcp_ifcap *cap)
 {
 	struct nhop4_extended nh4;
 	struct ifnet *ifp;
-	u_long maxmtu = 0;
+	uint32_t maxmtu = 0;
 
 	KASSERT(inc != NULL, ("tcp_maxmtu with NULL in_conninfo pointer"));
 
@@ -2423,14 +2446,14 @@ tcp_maxmtu(struct in_conninfo *inc, struct tcp_ifcap *cap)
 #endif /* INET */
 
 #ifdef INET6
-u_long
+uint32_t
 tcp_maxmtu6(struct in_conninfo *inc, struct tcp_ifcap *cap)
 {
 	struct nhop6_extended nh6;
 	struct in6_addr dst6;
 	uint32_t scopeid;
 	struct ifnet *ifp;
-	u_long maxmtu = 0;
+	uint32_t maxmtu = 0;
 
 	KASSERT(inc != NULL, ("tcp_maxmtu6 with NULL in_conninfo pointer"));
 
@@ -2717,6 +2740,7 @@ tcp_signature_do_compute(struct mbuf *m, int len, int optlen,
 	 * Note: Upper-Layer Packet Length comes before Next Header.
 	 */
 	case (IPV6_VERSION >> 4):
+		ip6 = mtod(m, struct ip6_hdr *);
 		in6 = ip6->ip6_src;
 		in6_clearscope(&in6);
 		MD5Update(&ctx, (char *)&in6, sizeof(struct in6_addr));
diff --git a/freebsd/sys/netinet/tcp_syncache.c b/freebsd/sys/netinet/tcp_syncache.c
index d7da3a0..453d5ba 100644
--- a/freebsd/sys/netinet/tcp_syncache.c
+++ b/freebsd/sys/netinet/tcp_syncache.c
@@ -928,8 +928,6 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
 	tp->t_keepcnt = sototcpcb(lso)->t_keepcnt;
 	tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp));
 
-	soisconnected(so);
-
 	TCPSTAT_INC(tcps_accepts);
 	return (so);
 
@@ -1081,10 +1079,17 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
 	}
 
 	/*
-	 * If timestamps were negotiated the reflected timestamp
-	 * must be equal to what we actually sent in the SYN|ACK.
+	 * If timestamps were negotiated, the reflected timestamp
+	 * must be equal to what we actually sent in the SYN|ACK
+	 * except in the case of 0. Some boxes are known for sending
+	 * broken timestamp replies during the 3whs (and potentially
+	 * during the connection also).
+	 *
+	 * Accept the final ACK of 3whs with reflected timestamp of 0
+	 * instead of sending a RST and deleting the syncache entry.
 	 */
-	if ((to->to_flags & TOF_TS) && to->to_tsecr != sc->sc_ts) {
+	if ((to->to_flags & TOF_TS) && to->to_tsecr &&
+	    to->to_tsecr != sc->sc_ts) {
 		if ((s = tcp_log_addrs(inc, th, NULL, NULL)))
 			log(LOG_DEBUG, "%s; %s: TSECR %u != TS %u, "
 			    "segment rejected\n",
@@ -1159,11 +1164,10 @@ syncache_tfo_expand(struct syncache *sc, struct socket **lsop, struct mbuf *m,
  * the data, we avoid this DoS scenario.
  *
  * The exception to the above is when a SYN with a valid TCP Fast Open (TFO)
- * cookie is processed, V_tcp_fastopen_enabled set to true, and the
- * TCP_FASTOPEN socket option is set.  In this case, a new socket is created
- * and returned via lsop, the mbuf is not freed so that tcp_input() can
- * queue its data to the socket, and 1 is returned to indicate the
- * TFO-socket-creation path was taken.
+ * cookie is processed and a new socket is created.  In this case, any data
+ * accompanying the SYN will be queued to the socket by tcp_input() and will
+ * be ACKed either when the application sends response data or the delayed
+ * ACK timer expires, whichever comes first.
  */
 int
 syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
@@ -1189,6 +1193,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
 	struct ucred *cred;
 #ifdef TCP_RFC7413
 	uint64_t tfo_response_cookie;
+	unsigned int *tfo_pending = NULL;
 	int tfo_cookie_valid = 0;
 	int tfo_response_cookie_valid = 0;
 #endif
@@ -1217,7 +1222,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
 	ltflags = (tp->t_flags & (TF_NOOPT | TF_SIGNATURE));
 
 #ifdef TCP_RFC7413
-	if (V_tcp_fastopen_enabled && (tp->t_flags & TF_FASTOPEN) &&
+	if (V_tcp_fastopen_enabled && IS_FASTOPEN(tp->t_flags) &&
 	    (tp->t_tfo_pending != NULL) && (to->to_flags & TOF_FASTOPEN)) {
 		/*
 		 * Limit the number of pending TFO connections to
@@ -1234,8 +1239,13 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
 			    &tfo_response_cookie);
 			tfo_cookie_valid = (result > 0);
 			tfo_response_cookie_valid = (result >= 0);
-		} else
-			atomic_subtract_int(tp->t_tfo_pending, 1);
+		}
+
+		/*
+		 * Remember the TFO pending counter as it will have to be
+		 * decremented below if we don't make it to syncache_tfo_expand().
+		 */
+		tfo_pending = tp->t_tfo_pending;
 	}
 #endif
 
@@ -1476,9 +1486,9 @@ skip_alloc:
 #ifdef TCP_RFC7413
 	if (tfo_cookie_valid) {
 		syncache_tfo_expand(sc, lsop, m, tfo_response_cookie);
-		/* INP_WUNLOCK(inp) will be performed by the called */
+		/* INP_WUNLOCK(inp) will be performed by the caller */
 		rv = 1;
-		goto tfo_done;
+		goto tfo_expanded;
 	}
 #endif
 
@@ -1504,7 +1514,16 @@ done:
 		m_freem(m);
 	}
 #ifdef TCP_RFC7413
-tfo_done:
+	/*
+	 * If tfo_pending is not NULL here, then a TFO SYN that did not
+	 * result in a new socket was processed and the associated pending
+	 * counter has not yet been decremented.  All such TFO processing paths
+	 * transit this point.
+	 */
+	if (tfo_pending != NULL)
+		tcp_fastopen_decrement_counter(tfo_pending);
+
+tfo_expanded:
 #endif
 	if (cred != NULL)
 		crfree(cred);
diff --git a/freebsd/sys/netinet/tcp_timer.c b/freebsd/sys/netinet/tcp_timer.c
index edfc382..89b61ad 100644
--- a/freebsd/sys/netinet/tcp_timer.c
+++ b/freebsd/sys/netinet/tcp_timer.c
@@ -470,6 +470,26 @@ tcp_timer_keep(void *xtp)
 	}
 	KASSERT((tp->t_timers->tt_flags & TT_STOPPED) == 0,
 		("%s: tp %p tcpcb can't be stopped here", __func__, tp));
+
+	/*
+	 * Because we don't regularly reset the keepalive callout in
+	 * the ESTABLISHED state, it may be that we don't actually need
+	 * to send a keepalive yet. If that occurs, schedule another
+	 * call for the next time the keepalive timer might expire.
+	 */
+	if (TCPS_HAVEESTABLISHED(tp->t_state)) {
+		u_int idletime;
+
+		idletime = ticks - tp->t_rcvtime;
+		if (idletime < TP_KEEPIDLE(tp)) {
+			callout_reset(&tp->t_timers->tt_keep,
+			    TP_KEEPIDLE(tp) - idletime, tcp_timer_keep, tp);
+			INP_WUNLOCK(inp);
+			CURVNET_RESTORE();
+			return;
+		}
+	}
+
 	/*
 	 * Keep-alive timer went off; send something
 	 * or drop connection if idle for too long.
diff --git a/freebsd/sys/netinet/tcp_timewait.c b/freebsd/sys/netinet/tcp_timewait.c
index 330e842..7eb0546 100644
--- a/freebsd/sys/netinet/tcp_timewait.c
+++ b/freebsd/sys/netinet/tcp_timewait.c
@@ -233,6 +233,10 @@ tcp_twstart(struct tcpcb *tp)
 	INP_INFO_RLOCK_ASSERT(&V_tcbinfo);
 	INP_WLOCK_ASSERT(inp);
 
+	/* A dropped inp should never transition to TIME_WAIT state. */
+	KASSERT((inp->inp_flags & INP_DROPPED) == 0, ("tcp_twstart: "
+	    "(inp->inp_flags & INP_DROPPED) != 0"));
+
 	if (V_nolocaltimewait) {
 		int error = 0;
 #ifdef INET6
@@ -338,6 +342,7 @@ tcp_twstart(struct tcpcb *tp)
 		tcp_twrespond(tw, TH_ACK);
 	inp->inp_ppcb = tw;
 	inp->inp_flags |= INP_TIMEWAIT;
+	TCPSTATES_INC(TCPS_TIME_WAIT);
 	tcp_tw_2msl_reset(tw, 0);
 
 	/*
diff --git a/freebsd/sys/netinet/tcp_usrreq.c b/freebsd/sys/netinet/tcp_usrreq.c
index d5fa680..436f30f 100644
--- a/freebsd/sys/netinet/tcp_usrreq.c
+++ b/freebsd/sys/netinet/tcp_usrreq.c
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/protosw.h>
 #include <sys/proc.h>
 #include <sys/jail.h>
+#include <sys/syslog.h>
 
 #ifdef DDB
 #include <ddb/ddb.h>
@@ -212,10 +213,26 @@ tcp_detach(struct socket *so, struct inpcb *inp)
 		 *  In all three cases the tcptw should not be freed here.
 		 */
 		if (inp->inp_flags & INP_DROPPED) {
-			KASSERT(tp == NULL, ("tcp_detach: INP_TIMEWAIT && "
-			    "INP_DROPPED && tp != NULL"));
 			in_pcbdetach(inp);
-			in_pcbfree(inp);
+			if (__predict_true(tp == NULL)) {
+				in_pcbfree(inp);
+			} else {
+				/*
+				 * This case should not happen as in TIMEWAIT
+				 * state the inp should not be destroyed before
+				 * its tcptw.  If INVARIANTS is defined, panic.
+				 */
+#ifdef INVARIANTS
+				panic("%s: Panic before an inp double-free: "
+				    "INP_TIMEWAIT && INP_DROPPED && tp != NULL"
+				    , __func__);
+#else
+				log(LOG_ERR, "%s: Avoid an inp double-free: "
+				    "INP_TIMEWAIT && INP_DROPPED && tp != NULL"
+				    , __func__);
+#endif
+				INP_WUNLOCK(inp);
+			}
 		} else {
 			in_pcbdetach(inp);
 			INP_WUNLOCK(inp);
@@ -412,7 +429,7 @@ tcp_usr_listen(struct socket *so, int backlog, struct thread *td)
 	SOCK_UNLOCK(so);
 
 #ifdef TCP_RFC7413
-	if (tp->t_flags & TF_FASTOPEN)
+	if (IS_FASTOPEN(tp->t_flags))
 		tp->t_tfo_pending = tcp_fastopen_alloc_counter();
 #endif
 out:
@@ -462,7 +479,7 @@ tcp6_usr_listen(struct socket *so, int backlog, struct thread *td)
 	SOCK_UNLOCK(so);
 
 #ifdef TCP_RFC7413
-	if (tp->t_flags & TF_FASTOPEN)
+	if (IS_FASTOPEN(tp->t_flags))
 		tp->t_tfo_pending = tcp_fastopen_alloc_counter();
 #endif
 out:
@@ -828,7 +845,7 @@ tcp_usr_rcvd(struct socket *so, int flags)
 	 * application response data, or failing that, when the DELACK timer
 	 * expires.
 	 */
-	if ((tp->t_flags & TF_FASTOPEN) &&
+	if (IS_FASTOPEN(tp->t_flags) &&
 	    (tp->t_state == TCPS_SYN_RECEIVED))
 		goto out;
 #endif
@@ -1331,9 +1348,11 @@ tcp_fill_info(struct tcpcb *tp, struct tcp_info *ti)
 		ti->tcpi_snd_wscale = tp->snd_scale;
 		ti->tcpi_rcv_wscale = tp->rcv_scale;
 	}
+	if (tp->t_flags & TF_ECN_PERMIT)
+		ti->tcpi_options |= TCPI_OPT_ECN;
 
 	ti->tcpi_rto = tp->t_rxtcur * tick;
-	ti->tcpi_last_data_recv = (long)(ticks - (int)tp->t_rcvtime) * tick;
+	ti->tcpi_last_data_recv = ((uint32_t)ticks - tp->t_rcvtime) * tick;
 	ti->tcpi_rtt = ((u_int64_t)tp->t_srtt * tick) >> TCP_RTT_SHIFT;
 	ti->tcpi_rttvar = ((u_int64_t)tp->t_rttvar * tick) >> TCP_RTTVAR_SHIFT;
 
@@ -1819,16 +1838,16 @@ unlock_and_done:
 		case TCP_KEEPCNT:
 			switch (sopt->sopt_name) {
 			case TCP_KEEPIDLE:
-				ui = tp->t_keepidle / hz;
+				ui = TP_KEEPIDLE(tp) / hz;
 				break;
 			case TCP_KEEPINTVL:
-				ui = tp->t_keepintvl / hz;
+				ui = TP_KEEPINTVL(tp) / hz;
 				break;
 			case TCP_KEEPINIT:
-				ui = tp->t_keepinit / hz;
+				ui = TP_KEEPINIT(tp) / hz;
 				break;
 			case TCP_KEEPCNT:
-				ui = tp->t_keepcnt;
+				ui = TP_KEEPCNT(tp);
 				break;
 			}
 			INP_WUNLOCK(inp);
@@ -2242,15 +2261,15 @@ db_print_tcpcb(struct tcpcb *tp, const char *name, int indent)
 	    tp->iss, tp->irs, tp->rcv_nxt);
 
 	db_print_indent(indent);
-	db_printf("rcv_adv: 0x%08x   rcv_wnd: %lu   rcv_up: 0x%08x\n",
+	db_printf("rcv_adv: 0x%08x   rcv_wnd: %u   rcv_up: 0x%08x\n",
 	    tp->rcv_adv, tp->rcv_wnd, tp->rcv_up);
 
 	db_print_indent(indent);
-	db_printf("snd_wnd: %lu   snd_cwnd: %lu\n",
+	db_printf("snd_wnd: %u   snd_cwnd: %u\n",
 	   tp->snd_wnd, tp->snd_cwnd);
 
 	db_print_indent(indent);
-	db_printf("snd_ssthresh: %lu   snd_recover: "
+	db_printf("snd_ssthresh: %u   snd_recover: "
 	    "0x%08x\n", tp->snd_ssthresh, tp->snd_recover);
 
 	db_print_indent(indent);
@@ -2271,7 +2290,7 @@ db_print_tcpcb(struct tcpcb *tp, const char *name, int indent)
 	    tp->t_rttbest);
 
 	db_print_indent(indent);
-	db_printf("t_rttupdated: %lu   max_sndwnd: %lu   t_softerror: %d\n",
+	db_printf("t_rttupdated: %lu   max_sndwnd: %u   t_softerror: %d\n",
 	    tp->t_rttupdated, tp->max_sndwnd, tp->t_softerror);
 
 	db_print_indent(indent);
@@ -2289,10 +2308,10 @@ db_print_tcpcb(struct tcpcb *tp, const char *name, int indent)
 
 	db_print_indent(indent);
 	db_printf("ts_offset: %u   last_ack_sent: 0x%08x   snd_cwnd_prev: "
-	    "%lu\n", tp->ts_offset, tp->last_ack_sent, tp->snd_cwnd_prev);
+	    "%u\n", tp->ts_offset, tp->last_ack_sent, tp->snd_cwnd_prev);
 
 	db_print_indent(indent);
-	db_printf("snd_ssthresh_prev: %lu   snd_recover_prev: 0x%08x   "
+	db_printf("snd_ssthresh_prev: %u   snd_recover_prev: 0x%08x   "
 	    "t_badrxtwin: %u\n", tp->snd_ssthresh_prev,
 	    tp->snd_recover_prev, tp->t_badrxtwin);
 
diff --git a/freebsd/sys/netinet/tcp_var.h b/freebsd/sys/netinet/tcp_var.h
index 5dcd35b..f4ea246 100644
--- a/freebsd/sys/netinet/tcp_var.h
+++ b/freebsd/sys/netinet/tcp_var.h
@@ -192,13 +192,13 @@ struct tcpcb {
 
 	tcp_seq	rcv_nxt;		/* receive next */
 	tcp_seq	rcv_adv;		/* advertised window */
-	u_long	rcv_wnd;		/* receive window */
+	uint32_t  rcv_wnd;		/* receive window */
 	tcp_seq	rcv_up;			/* receive urgent pointer */
 
-	u_long	snd_wnd;		/* send window */
-	u_long	snd_cwnd;		/* congestion-controlled window */
+	uint32_t  snd_wnd;		/* send window */
+	uint32_t  snd_cwnd;		/* congestion-controlled window */
 	u_long	snd_spare1;		/* unused */
-	u_long	snd_ssthresh;		/* snd_cwnd size threshold for
+	uint32_t  snd_ssthresh;		/* snd_cwnd size threshold for
 					 * for slow start exponential to
 					 * linear switch
 					 */
@@ -223,7 +223,7 @@ struct tcpcb {
 	u_int	t_rttmin;		/* minimum rtt allowed */
 	u_int	t_rttbest;		/* best rtt we've seen */
 	u_long	t_rttupdated;		/* number of times rtt sampled */
-	u_long	max_sndwnd;		/* largest window peer has offered */
+	uint32_t  max_sndwnd;		/* largest window peer has offered */
 
 	int	t_softerror;		/* possible error not yet reported */
 /* out-of-band data */
@@ -239,8 +239,8 @@ struct tcpcb {
 
 	tcp_seq	last_ack_sent;
 /* experimental */
-	u_long	snd_cwnd_prev;		/* cwnd prior to retransmit */
-	u_long	snd_ssthresh_prev;	/* ssthresh prior to retransmit */
+	uint32_t  snd_cwnd_prev;	/* cwnd prior to retransmit */
+	uint32_t  snd_ssthresh_prev;	/* ssthresh prior to retransmit */
 	tcp_seq	snd_recover_prev;	/* snd_recover prior to retransmit */
 	int	t_sndzerowin;		/* zero-window updates sent */
 	u_int	t_badrxtwin;		/* window for retransmit recovery */
@@ -349,6 +349,12 @@ struct tcpcb {
 #define	ENTER_RECOVERY(t_flags) t_flags |= (TF_CONGRECOVERY | TF_FASTRECOVERY)
 #define	EXIT_RECOVERY(t_flags) t_flags &= ~(TF_CONGRECOVERY | TF_FASTRECOVERY)
 
+#if defined(_KERNEL) && !defined(TCP_RFC7413)
+#define	IS_FASTOPEN(t_flags)		(false)
+#else
+#define	IS_FASTOPEN(t_flags)		(t_flags & TF_FASTOPEN)
+#endif
+
 #define	BYTES_THIS_ACK(tp, th)	(th->th_ack - tp->snd_una)
 
 /*
@@ -415,13 +421,13 @@ struct tcpopt {
 #define	TO_SYN		0x01		/* parse SYN-only options */
 
 struct hc_metrics_lite {	/* must stay in sync with hc_metrics */
-	u_long	rmx_mtu;	/* MTU for this path */
-	u_long	rmx_ssthresh;	/* outbound gateway buffer limit */
-	u_long	rmx_rtt;	/* estimated round trip time */
-	u_long	rmx_rttvar;	/* estimated rtt variance */
-	u_long	rmx_cwnd;	/* congestion window */
-	u_long	rmx_sendpipe;   /* outbound delay-bandwidth product */
-	u_long	rmx_recvpipe;   /* inbound delay-bandwidth product */
+	uint32_t	rmx_mtu;	/* MTU for this path */
+	uint32_t	rmx_ssthresh;	/* outbound gateway buffer limit */
+	uint32_t	rmx_rtt;	/* estimated round trip time */
+	uint32_t	rmx_rttvar;	/* estimated rtt variance */
+	uint32_t	rmx_cwnd;	/* congestion window */
+	uint32_t	rmx_sendpipe;   /* outbound delay-bandwidth product */
+	uint32_t	rmx_recvpipe;   /* inbound delay-bandwidth product */
 };
 
 /*
@@ -657,7 +663,7 @@ struct tcp_hhook_data {
 	struct tcpcb	*tp;
 	struct tcphdr	*th;
 	struct tcpopt	*to;
-	long		len;
+	uint32_t	len;
 	int		tso;
 	tcp_seq		curack;
 };
@@ -749,8 +755,10 @@ VNET_DECLARE(int, tcp_ecn_maxretries);
 #define	V_tcp_do_ecn		VNET(tcp_do_ecn)
 #define	V_tcp_ecn_maxretries	VNET(tcp_ecn_maxretries)
 
+#ifdef TCP_HHOOK
 VNET_DECLARE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST + 1]);
 #define	V_tcp_hhh		VNET(tcp_hhh)
+#endif
 
 VNET_DECLARE(int, tcp_do_rfc6675_pipe);
 #define V_tcp_do_rfc6675_pipe	VNET(tcp_do_rfc6675_pipe)
@@ -784,12 +792,14 @@ void	tcp_pulloutofband(struct socket *,
 void	tcp_xmit_timer(struct tcpcb *, int);
 void	tcp_newreno_partial_ack(struct tcpcb *, struct tcphdr *);
 void	cc_ack_received(struct tcpcb *tp, struct tcphdr *th,
-			    uint16_t type);
+			    uint16_t nsegs, uint16_t type);
 void 	cc_conn_init(struct tcpcb *tp);
 void 	cc_post_recovery(struct tcpcb *tp, struct tcphdr *th);
 void	cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type);
+#ifdef TCP_HHOOK
 void	hhook_run_tcp_est_in(struct tcpcb *tp,
 			    struct tcphdr *th, struct tcpopt *to);
+#endif
 
 int	 tcp_input(struct mbuf **, int *, int);
 void	 tcp_do_segment(struct mbuf *, struct tcphdr *,
@@ -802,8 +812,8 @@ struct tcp_function_block *find_and_ref_tcp_functions(struct tcp_function_set *f
 struct tcp_function_block *find_and_ref_tcp_fb(struct tcp_function_block *blk);
 int tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp, struct tcpcb *tp);
 
-u_long	 tcp_maxmtu(struct in_conninfo *, struct tcp_ifcap *);
-u_long	 tcp_maxmtu6(struct in_conninfo *, struct tcp_ifcap *);
+uint32_t tcp_maxmtu(struct in_conninfo *, struct tcp_ifcap *);
+uint32_t tcp_maxmtu6(struct in_conninfo *, struct tcp_ifcap *);
 u_int	 tcp_maxseg(const struct tcpcb *);
 void	 tcp_mss_update(struct tcpcb *, int, int, struct hc_metrics_lite *,
 	    struct tcp_ifcap *);
@@ -852,8 +862,8 @@ void	 tcp_hc_init(void);
 void	 tcp_hc_destroy(void);
 #endif
 void	 tcp_hc_get(struct in_conninfo *, struct hc_metrics_lite *);
-u_long	 tcp_hc_getmtu(struct in_conninfo *);
-void	 tcp_hc_updatemtu(struct in_conninfo *, u_long);
+uint32_t tcp_hc_getmtu(struct in_conninfo *);
+void	 tcp_hc_updatemtu(struct in_conninfo *, uint32_t);
 void	 tcp_hc_update(struct in_conninfo *, struct hc_metrics_lite *);
 
 extern	struct pr_usrreqs tcp_usrreqs;
@@ -867,7 +877,6 @@ struct sackhole *tcp_sack_output(struct tcpcb *tp, int *sack_bytes_rexmt);
 void	 tcp_sack_partialack(struct tcpcb *, struct tcphdr *);
 void	 tcp_free_sackholes(struct tcpcb *tp);
 int	 tcp_newreno(struct tcpcb *, struct tcphdr *);
-u_long	 tcp_seq_subtract(u_long, u_long );
 int	 tcp_compute_pipe(struct tcpcb *);
 
 static inline void
diff --git a/freebsd/sys/netinet/udp_usrreq.c b/freebsd/sys/netinet/udp_usrreq.c
index 7eb1164..42461ce 100644
--- a/freebsd/sys/netinet/udp_usrreq.c
+++ b/freebsd/sys/netinet/udp_usrreq.c
@@ -603,7 +603,8 @@ udp_input(struct mbuf **mp, int *offp, int proto)
 			if (last != NULL) {
 				struct mbuf *n;
 
-				if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
+				if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) !=
+				    NULL) {
 					UDP_PROBE(receive, NULL, last, ip,
 					    last, uh);
 					if (udp_append(last, ip, n, iphlen,
@@ -1572,12 +1573,18 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
 
 release:
 	if (unlock_udbinfo == UH_WLOCKED) {
+		KASSERT(unlock_inp == UH_WLOCKED,
+		    ("%s: excl udbinfo lock, shared inp lock", __func__));
 		INP_HASH_WUNLOCK(pcbinfo);
 		INP_WUNLOCK(inp);
 	} else if (unlock_udbinfo == UH_RLOCKED) {
+		KASSERT(unlock_inp == UH_RLOCKED,
+		    ("%s: shared udbinfo lock, excl inp lock", __func__));
 		INP_HASH_RUNLOCK(pcbinfo);
 		INP_RUNLOCK(inp);
-	} else
+	} else if (unlock_inp == UH_WLOCKED)
+		INP_WUNLOCK(inp);
+	else
 		INP_RUNLOCK(inp);
 	m_freem(m);
 	return (error);
diff --git a/freebsd/sys/netinet6/icmp6.c b/freebsd/sys/netinet6/icmp6.c
index 6e3a487..14ce2b3 100644
--- a/freebsd/sys/netinet6/icmp6.c
+++ b/freebsd/sys/netinet6/icmp6.c
@@ -492,7 +492,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
 			break;
 		case ICMP6_DST_UNREACH_ADMIN:
 			icmp6_ifstat_inc(ifp, ifs6_in_adminprohib);
-			code = PRC_UNREACH_PROTOCOL; /* is this a good code? */
+			code = PRC_UNREACH_ADMIN_PROHIB;
 			break;
 		case ICMP6_DST_UNREACH_BEYONDSCOPE:
 			/* I mean "source address was incorrect." */
@@ -556,7 +556,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
 		icmp6_ifstat_inc(ifp, ifs6_in_echo);
 		if (code != 0)
 			goto badcode;
-		if ((n = m_copy(m, 0, M_COPYALL)) == NULL) {
+		if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) == NULL) {
 			/* Give up remote */
 			break;
 		}
@@ -653,7 +653,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
 			IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_nodeinfo),
 			    IPPROTO_DONE);
 #endif
-			n = m_copy(m, 0, M_COPYALL);
+			n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
 			if (n)
 				n = ni6_input(n, off);
 			/* XXX meaningless if n == NULL */
@@ -740,36 +740,19 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
 			goto badcode;
 		if (icmp6len < sizeof(struct nd_router_solicit))
 			goto badlen;
-		if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) == NULL) {
-			/* give up local */
-
-			/* Send incoming SeND packet to user space. */
-			if (send_sendso_input_hook != NULL) {
-				IP6_EXTHDR_CHECK(m, off,
-				    icmp6len, IPPROTO_DONE);
-				error = send_sendso_input_hook(m, ifp,
-				    SND_IN, ip6len);
-				/* -1 == no app on SEND socket */
-				if (error == 0)
-					return (IPPROTO_DONE);
-				nd6_rs_input(m, off, icmp6len);
-			} else
-				nd6_rs_input(m, off, icmp6len);
-			m = NULL;
-			goto freeit;
-		}
 		if (send_sendso_input_hook != NULL) {
-			IP6_EXTHDR_CHECK(n, off,
-			    icmp6len, IPPROTO_DONE);
-                        error = send_sendso_input_hook(n, ifp,
-			    SND_IN, ip6len);
-			if (error == 0)
+			IP6_EXTHDR_CHECK(m, off, icmp6len, IPPROTO_DONE);
+			error = send_sendso_input_hook(m, ifp, SND_IN, ip6len);
+			if (error == 0) {
+				m = NULL;
 				goto freeit;
-			/* -1 == no app on SEND socket */
-			nd6_rs_input(n, off, icmp6len);
-		} else
-			nd6_rs_input(n, off, icmp6len);
-		/* m stays. */
+			}
+		}
+		n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
+		nd6_rs_input(m, off, icmp6len);
+		m = n;
+		if (m == NULL)
+			goto freeit;
 		break;
 
 	case ND_ROUTER_ADVERT:
@@ -778,29 +761,18 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
 			goto badcode;
 		if (icmp6len < sizeof(struct nd_router_advert))
 			goto badlen;
-		if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) == NULL) {
-
-			/* Send incoming SeND-protected/ND packet to user space. */
-			if (send_sendso_input_hook != NULL) {
-				error = send_sendso_input_hook(m, ifp,
-				    SND_IN, ip6len);
-				if (error == 0)
-					return (IPPROTO_DONE);
-				nd6_ra_input(m, off, icmp6len);
-			} else
-				nd6_ra_input(m, off, icmp6len);
-			m = NULL;
-			goto freeit;
-		}
 		if (send_sendso_input_hook != NULL) {
-			error = send_sendso_input_hook(n, ifp,
-			    SND_IN, ip6len);
-			if (error == 0)
+			error = send_sendso_input_hook(m, ifp, SND_IN, ip6len);
+			if (error == 0) {
+				m = NULL;
 				goto freeit;
-			nd6_ra_input(n, off, icmp6len);
-		} else
-			nd6_ra_input(n, off, icmp6len);
-		/* m stays. */
+			}
+		}
+		n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
+		nd6_ra_input(m, off, icmp6len);
+		m = n;
+		if (m == NULL)
+			goto freeit;
 		break;
 
 	case ND_NEIGHBOR_SOLICIT:
@@ -809,27 +781,18 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
 			goto badcode;
 		if (icmp6len < sizeof(struct nd_neighbor_solicit))
 			goto badlen;
-		if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) == NULL) {
-			if (send_sendso_input_hook != NULL) {
-				error = send_sendso_input_hook(m, ifp,
-				    SND_IN, ip6len);
-				if (error == 0)
-					return (IPPROTO_DONE);
-				nd6_ns_input(m, off, icmp6len);
-			} else
-				nd6_ns_input(m, off, icmp6len);
-			m = NULL;
-			goto freeit;
-		}
 		if (send_sendso_input_hook != NULL) {
-			error = send_sendso_input_hook(n, ifp,
-			    SND_IN, ip6len);
-			if (error == 0)
+			error = send_sendso_input_hook(m, ifp, SND_IN, ip6len);
+			if (error == 0) {
+				m = NULL;
 				goto freeit;
-			nd6_ns_input(n, off, icmp6len);
-		} else
-			nd6_ns_input(n, off, icmp6len);
-		/* m stays. */
+			}
+		}
+		n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
+		nd6_ns_input(m, off, icmp6len);
+		m = n;
+		if (m == NULL)
+			goto freeit;
 		break;
 
 	case ND_NEIGHBOR_ADVERT:
@@ -838,29 +801,18 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
 			goto badcode;
 		if (icmp6len < sizeof(struct nd_neighbor_advert))
 			goto badlen;
-		if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) == NULL) {
-
-			/* Send incoming SeND-protected/ND packet to user space. */
-			if (send_sendso_input_hook != NULL) {
-				error = send_sendso_input_hook(m, ifp,
-				    SND_IN, ip6len);
-				if (error == 0)
-					return (IPPROTO_DONE);
-				nd6_na_input(m, off, icmp6len);
-			} else
-				nd6_na_input(m, off, icmp6len);
-			m = NULL;
-			goto freeit;
-		}
 		if (send_sendso_input_hook != NULL) {
-			error = send_sendso_input_hook(n, ifp,
-			    SND_IN, ip6len);
-			if (error == 0)
+			error = send_sendso_input_hook(m, ifp, SND_IN, ip6len);
+			if (error == 0) {
+				m = NULL;
 				goto freeit;
-			nd6_na_input(n, off, icmp6len);
-		} else
-			nd6_na_input(n, off, icmp6len);
-		/* m stays. */
+			}
+		}
+		n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
+		nd6_na_input(m, off, icmp6len);
+		m = n;
+		if (m == NULL)
+			goto freeit;
 		break;
 
 	case ND_REDIRECT:
@@ -869,27 +821,18 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
 			goto badcode;
 		if (icmp6len < sizeof(struct nd_redirect))
 			goto badlen;
-		if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) == NULL) {
-			if (send_sendso_input_hook != NULL) {
-				error = send_sendso_input_hook(m, ifp,
-				    SND_IN, ip6len);
-		 		if (error == 0)
-					return (IPPROTO_DONE);
-			    icmp6_redirect_input(m, off);
-			} else
-				icmp6_redirect_input(m, off);
-			m = NULL;
-			goto freeit;
-		}
 		if (send_sendso_input_hook != NULL) {
-			error = send_sendso_input_hook(n, ifp,
-			    SND_IN, ip6len);
-			if (error == 0)
+			error = send_sendso_input_hook(m, ifp, SND_IN, ip6len);
+			if (error == 0) {
+				m = NULL;
 				goto freeit;
-			icmp6_redirect_input(n, off);
-		} else
-			icmp6_redirect_input(n, off);
-		/* m stays. */
+			}
+		}
+		n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
+		icmp6_redirect_input(m, off);
+		m = n;
+		if (m == NULL)
+			goto freeit;
 		break;
 
 	case ICMP6_ROUTER_RENUMBERING:
@@ -2053,7 +1996,7 @@ icmp6_rip6_input(struct mbuf **mp, int off)
 				}
 			}
 			if (n != NULL ||
-			    (n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
+			    (n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) != NULL) {
 				if (last->inp_flags & INP_CONTROLOPTS)
 					ip6_savecontrol(last, n, &opts);
 				/* strip intermediate headers */
@@ -2217,7 +2160,7 @@ icmp6_reflect(struct mbuf *m, size_t off)
 		 * that we do not own.  Select a source address based on the
 		 * source address of the erroneous packet.
 		 */
-		in6_splitscope(&ip6->ip6_dst, &dst6, &scopeid);
+		in6_splitscope(&ip6->ip6_src, &dst6, &scopeid);
 		error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6,
 		    scopeid, NULL, &src6, &hlim);
 
diff --git a/freebsd/sys/netinet6/in6.c b/freebsd/sys/netinet6/in6.c
index f5d8252..8a4c366 100644
--- a/freebsd/sys/netinet6/in6.c
+++ b/freebsd/sys/netinet6/in6.c
@@ -634,7 +634,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data,
 		/* relate the address to the prefix */
 		if (ia->ia6_ndpr == NULL) {
 			ia->ia6_ndpr = pr;
-			pr->ndpr_refcnt++;
+			pr->ndpr_addrcnt++;
 
 			/*
 			 * If this is the first autoconf address from the
@@ -642,7 +642,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data,
 			 * (when required).
 			 */
 			if ((ia->ia6_flags & IN6_IFF_AUTOCONF) &&
-			    V_ip6_use_tempaddr && pr->ndpr_refcnt == 1) {
+			    V_ip6_use_tempaddr && pr->ndpr_addrcnt == 1) {
 				int e;
 				if ((e = in6_tmpifadd(ia, 1, 0)) != 0) {
 					log(LOG_NOTICE, "in6_control: failed "
@@ -651,6 +651,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data,
 				}
 			}
 		}
+		nd6_prefix_rele(pr);
 
 		/*
 		 * this might affect the status of autoconfigured addresses,
@@ -694,12 +695,16 @@ aifaddr_out:
 		 * and the prefix management.  We do this, however, to provide
 		 * as much backward compatibility as possible in terms of
 		 * the ioctl operation.
-		 * Note that in6_purgeaddr() will decrement ndpr_refcnt.
+		 * Note that in6_purgeaddr() will decrement ndpr_addrcnt.
 		 */
 		pr = ia->ia6_ndpr;
 		in6_purgeaddr(&ia->ia_ifa);
-		if (pr && pr->ndpr_refcnt == 0)
-			prelist_remove(pr);
+		if (pr != NULL && pr->ndpr_addrcnt == 0) {
+			ND6_WLOCK();
+			nd6_prefix_unlink(pr, NULL);
+			ND6_WUNLOCK();
+			nd6_prefix_del(pr);
+		}
 		EVENTHANDLER_INVOKE(ifaddr_event, ifp);
 		break;
 	}
@@ -1309,9 +1314,9 @@ in6_unlink_ifa(struct in6_ifaddr *ia, struct ifnet *ifp)
 		    "in6_unlink_ifa: autoconf'ed address "
 		    "%s has no prefix\n", ip6_sprintf(ip6buf, IA6_IN6(ia))));
 	} else {
-		ia->ia6_ndpr->ndpr_refcnt--;
+		ia->ia6_ndpr->ndpr_addrcnt--;
 		/* Do not delete lles within prefix if refcont != 0 */
-		if (ia->ia6_ndpr->ndpr_refcnt == 0)
+		if (ia->ia6_ndpr->ndpr_addrcnt == 0)
 			remove_lle = 1;
 		ia->ia6_ndpr = NULL;
 	}
diff --git a/freebsd/sys/netinet6/in6_ifattach.c b/freebsd/sys/netinet6/in6_ifattach.c
index 791e9e2..879336a 100644
--- a/freebsd/sys/netinet6/in6_ifattach.c
+++ b/freebsd/sys/netinet6/in6_ifattach.c
@@ -459,6 +459,7 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet *altifp)
 	struct in6_ifaddr *ia;
 	struct in6_aliasreq ifra;
 	struct nd_prefixctl pr0;
+	struct nd_prefix *pr;
 	int error;
 
 	/*
@@ -541,10 +542,11 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet *altifp)
 	 * address, and then reconfigure another one, the prefix is still
 	 * valid with referring to the old link-local address.
 	 */
-	if (nd6_prefix_lookup(&pr0) == NULL) {
+	if ((pr = nd6_prefix_lookup(&pr0)) == NULL) {
 		if ((error = nd6_prelist_add(&pr0, NULL, NULL)) != 0)
 			return (error);
-	}
+	} else
+		nd6_prefix_rele(pr);
 
 	return 0;
 }
@@ -788,15 +790,6 @@ _in6_ifdetach(struct ifnet *ifp, int purgeulp)
 		return;
 
 	/*
-	 * Remove neighbor management table.
-	 * Enabling the nd6_purge will panic on vmove for interfaces on VNET
-	 * teardown as the IPv6 layer is cleaned up already and the locks
-	 * are destroyed.
-	 */
-	if (purgeulp)
-		nd6_purge(ifp);
-
-	/*
 	 * nuke any of IPv6 addresses we have
 	 * XXX: all addresses should be already removed
 	 */
@@ -814,12 +807,10 @@ _in6_ifdetach(struct ifnet *ifp, int purgeulp)
 	in6_purgemaddrs(ifp);
 
 	/*
-	 * remove neighbor management table.  we call it twice just to make
-	 * sure we nuke everything.  maybe we need just one call.
-	 * XXX: since the first call did not release addresses, some prefixes
-	 * might remain.  We should call nd6_purge() again to release the
-	 * prefixes after removing all addresses above.
-	 * (Or can we just delay calling nd6_purge until at this point?)
+	 * Remove neighbor management table.
+	 * Enabling the nd6_purge will panic on vmove for interfaces on VNET
+	 * teardown as the IPv6 layer is cleaned up already and the locks
+	 * are destroyed.
 	 */
 	if (purgeulp)
 		nd6_purge(ifp);
diff --git a/freebsd/sys/netinet6/ip6_forward.c b/freebsd/sys/netinet6/ip6_forward.c
index 5058353..b57d31f 100644
--- a/freebsd/sys/netinet6/ip6_forward.c
+++ b/freebsd/sys/netinet6/ip6_forward.c
@@ -168,7 +168,8 @@ ip6_forward(struct mbuf *m, int srcrt)
 	 * It is important to save it before IPsec processing as IPsec
 	 * processing may modify the mbuf.
 	 */
-	mcopy = m_copy(m, 0, imin(m->m_pkthdr.len, ICMPV6_PLD_MAXLEN));
+	mcopy = m_copym(m, 0, imin(m->m_pkthdr.len, ICMPV6_PLD_MAXLEN),
+	    M_NOWAIT);
 
 #ifdef IPSEC
 	/* get a security policy for this packet */
diff --git a/freebsd/sys/netinet6/ip6_input.c b/freebsd/sys/netinet6/ip6_input.c
index c7ffe75..6af5acd 100644
--- a/freebsd/sys/netinet6/ip6_input.c
+++ b/freebsd/sys/netinet6/ip6_input.c
@@ -1774,6 +1774,6 @@ u_char	inet6ctlerrmap[PRC_NCMDS] = {
 	0,		EMSGSIZE,	EHOSTDOWN,	EHOSTUNREACH,
 	EHOSTUNREACH,	EHOSTUNREACH,	ECONNREFUSED,	ECONNREFUSED,
 	EMSGSIZE,	EHOSTUNREACH,	0,		0,
-	0,		0,		0,		0,
-	ENOPROTOOPT
+	0,		0,		EHOSTUNREACH,	0,
+	ENOPROTOOPT,	ECONNREFUSED
 };
diff --git a/freebsd/sys/netinet6/ip6_mroute.c b/freebsd/sys/netinet6/ip6_mroute.c
index f74b71c..e40ce06 100644
--- a/freebsd/sys/netinet6/ip6_mroute.c
+++ b/freebsd/sys/netinet6/ip6_mroute.c
@@ -1147,7 +1147,7 @@ X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m)
 		MFC6_UNLOCK();
 		return (ENOBUFS);
 	}
-	mb0 = m_copy(m, 0, M_COPYALL);
+	mb0 = m_copym(m, 0, M_COPYALL, M_NOWAIT);
 	/*
 	 * Pullup packet header if needed before storing it,
 	 * as other references may modify it in the meantime.
@@ -1187,7 +1187,7 @@ X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m)
 		 * Make a copy of the header to send to the user
 		 * level process
 		 */
-		mm = m_copy(mb0, 0, sizeof(struct ip6_hdr));
+		mm = m_copym(mb0, 0, sizeof(struct ip6_hdr), M_NOWAIT);
 		if (mm == NULL) {
 			free(rte, M_MRTABLE6);
 			m_freem(mb0);
@@ -1419,7 +1419,8 @@ ip6_mdq(struct mbuf *m, struct ifnet *ifp, struct mf6c *rt)
 				struct omrt6msg *oim;
 #endif
 
-				mm = m_copy(m, 0, sizeof(struct ip6_hdr));
+				mm = m_copym(m, 0, sizeof(struct ip6_hdr),
+				    M_NOWAIT);
 				if (mm &&
 				    (!M_WRITABLE(mm) ||
 				     mm->m_len < sizeof(struct ip6_hdr)))
@@ -1549,7 +1550,7 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m)
 	 * the IPv6 header is actually copied, not just referenced,
 	 * so that ip6_output() only scribbles on the copy.
 	 */
-	mb_copy = m_copy(m, 0, M_COPYALL);
+	mb_copy = m_copym(m, 0, M_COPYALL, M_NOWAIT);
 	if (mb_copy &&
 	    (!M_WRITABLE(mb_copy) || mb_copy->m_len < sizeof(struct ip6_hdr)))
 		mb_copy = m_pullup(mb_copy, sizeof(struct ip6_hdr));
@@ -1653,7 +1654,7 @@ register_send(struct ip6_hdr *ip6, struct mif6 *mif, struct mbuf *m)
 	mm->m_data += max_linkhdr;
 	mm->m_len = sizeof(struct ip6_hdr);
 
-	if ((mm->m_next = m_copy(m, 0, M_COPYALL)) == NULL) {
+	if ((mm->m_next = m_copym(m, 0, M_COPYALL, M_NOWAIT)) == NULL) {
 		m_freem(mm);
 		return (ENOBUFS);
 	}
@@ -1872,7 +1873,7 @@ pim6_input(struct mbuf **mp, int *offp, int proto)
 		/*
 		 * make a copy of the whole header to pass to the daemon later.
 		 */
-		mcp = m_copy(m, 0, off + PIM6_REG_MINLEN);
+		mcp = m_copym(m, 0, off + PIM6_REG_MINLEN, M_NOWAIT);
 		if (mcp == NULL) {
 			MRT6_DLOG(DEBUG_ANY | DEBUG_ERR, "pim register: "
 			    "could not copy register head");
diff --git a/freebsd/sys/netinet6/ip6_output.c b/freebsd/sys/netinet6/ip6_output.c
index d3dc973..63d1dac 100644
--- a/freebsd/sys/netinet6/ip6_output.c
+++ b/freebsd/sys/netinet6/ip6_output.c
@@ -89,6 +89,7 @@ __FBSDID("$FreeBSD$");
 
 #include <net/if.h>
 #include <net/if_var.h>
+#include <net/if_llatbl.h>
 #include <net/netisr.h>
 #include <net/route.h>
 #include <net/pfil.h>
@@ -260,7 +261,7 @@ ip6_fragment(struct ifnet *ifp, struct mbuf *m0, int hlen, u_char nextproto,
 			ip6f->ip6f_offlg |= IP6F_MORE_FRAG;
 		mhip6->ip6_plen = htons((u_short)(mtu + hlen +
 		    sizeof(*ip6f) - sizeof(struct ip6_hdr)));
-		if ((m_frgpart = m_copy(m0, off, mtu)) == NULL) {
+		if ((m_frgpart = m_copym(m0, off, mtu, M_NOWAIT)) == NULL) {
 			IP6STAT_INC(ip6s_odropped);
 			return (ENOBUFS);
 		}
@@ -554,6 +555,9 @@ again:
 		rt = ro->ro_rt;
 		ifp = ro->ro_rt->rt_ifp;
 	} else {
+		if (ro->ro_lle)
+			LLE_FREE(ro->ro_lle);	/* zeros ro_lle */
+		ro->ro_lle = NULL;
 		if (fwd_tag == NULL) {
 			bzero(&dst_sa, sizeof(dst_sa));
 			dst_sa.sin6_family = AF_INET6;
@@ -823,6 +827,9 @@ again:
 		} else {
 			RO_RTFREE(ro);
 			needfiblookup = 1; /* Redo the routing table lookup. */
+			if (ro->ro_lle)
+				LLE_FREE(ro->ro_lle);	/* zeros ro_lle */
+			ro->ro_lle = NULL;
 		}
 	}
 	/* See if fib was changed by packet filter. */
@@ -831,6 +838,9 @@ again:
 		fibnum = M_GETFIB(m);
 		RO_RTFREE(ro);
 		needfiblookup = 1;
+		if (ro->ro_lle)
+			LLE_FREE(ro->ro_lle);	/* zeros ro_lle */
+		ro->ro_lle = NULL;
 	}
 	if (needfiblookup)
 		goto again;
@@ -1056,12 +1066,7 @@ sendorfree:
 		IP6STAT_INC(ip6s_fragmented);
 
 done:
-	/*
-	 * Release the route if using our private route, or if
-	 * (with flowtable) we don't have our own reference.
-	 */
-	if (ro == &ip6route ||
-	    (ro != NULL && ro->ro_flags & RT_NORTREF))
+	if (ro == &ip6route)
 		RO_RTFREE(ro);
 	return (error);
 
@@ -1390,6 +1395,15 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
 	int retval;
 #endif
 
+/*
+ * Don't use more than a quarter of mbuf clusters.  N.B.:
+ * nmbclusters is an int, but nmbclusters * MCLBYTES may overflow
+ * on LP64 architectures, so cast to u_long to avoid undefined
+ * behavior.  ILP32 architectures cannot have nmbclusters
+ * large enough to overflow for other reasons.
+ */
+#define IPV6_PKTOPTIONS_MBUF_LIMIT	((u_long)nmbclusters * MCLBYTES / 4)
+
 	level = sopt->sopt_level;
 	op = sopt->sopt_dir;
 	optname = sopt->sopt_name;
@@ -1445,6 +1459,12 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
 			{
 				struct mbuf *m;
 
+				if (optlen > IPV6_PKTOPTIONS_MBUF_LIMIT) {
+					printf("ip6_ctloutput: mbuf limit hit\n");
+					error = ENOBUFS;
+					break;
+				}
+
 				error = soopt_getm(sopt, &m); /* XXX */
 				if (error != 0)
 					break;
@@ -2995,7 +3015,7 @@ ip6_mloopback(struct ifnet *ifp, struct mbuf *m)
 	struct mbuf *copym;
 	struct ip6_hdr *ip6;
 
-	copym = m_copy(m, 0, M_COPYALL);
+	copym = m_copym(m, 0, M_COPYALL, M_NOWAIT);
 	if (copym == NULL)
 		return;
 
diff --git a/freebsd/sys/netinet6/nd6.c b/freebsd/sys/netinet6/nd6.c
index d1c7036..3e019a6 100644
--- a/freebsd/sys/netinet6/nd6.c
+++ b/freebsd/sys/netinet6/nd6.c
@@ -40,8 +40,10 @@ __FBSDID("$FreeBSD$");
 #include <rtems/bsd/sys/param.h>
 #include <sys/systm.h>
 #include <sys/callout.h>
+#include <rtems/bsd/sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
+#include <sys/mutex.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
 #include <sys/time.h>
@@ -49,7 +51,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/protosw.h>
 #include <rtems/bsd/sys/errno.h>
 #include <sys/syslog.h>
-#include <rtems/bsd/sys/lock.h>
 #include <sys/rwlock.h>
 #include <sys/queue.h>
 #include <sys/sdt.h>
@@ -120,6 +121,8 @@ static eventhandler_tag lle_event_eh, iflladdr_event_eh;
 VNET_DEFINE(struct nd_drhead, nd_defrouter);
 VNET_DEFINE(struct nd_prhead, nd_prefix);
 VNET_DEFINE(struct rwlock, nd6_lock);
+VNET_DEFINE(uint64_t, nd6_list_genid);
+VNET_DEFINE(struct mtx, nd6_onlink_mtx);
 
 VNET_DEFINE(int, nd6_recalc_reachtm_interval) = ND6_RECALC_REACHTM_INTERVAL;
 #define	V_nd6_recalc_reachtm_interval	VNET(nd6_recalc_reachtm_interval)
@@ -211,11 +214,10 @@ void
 nd6_init(void)
 {
 
-	rw_init(&V_nd6_lock, "nd6");
+	mtx_init(&V_nd6_onlink_mtx, "nd6 onlink", NULL, MTX_DEF);
+	rw_init(&V_nd6_lock, "nd6 list");
 
 	LIST_INIT(&V_nd_prefix);
-
-	/* initialization of the default router list */
 	TAILQ_INIT(&V_nd_defrouter);
 
 	/* Start timers. */
@@ -247,6 +249,7 @@ nd6_destroy()
 		EVENTHANDLER_DEREGISTER(iflladdr_event, iflladdr_event_eh);
 	}
 	rw_destroy(&V_nd6_lock);
+	mtx_destroy(&V_nd6_onlink_mtx);
 }
 #endif
 
@@ -905,13 +908,15 @@ nd6_timer(void *arg)
 {
 	CURVNET_SET((struct vnet *) arg);
 	struct nd_drhead drq;
+	struct nd_prhead prl;
 	struct nd_defrouter *dr, *ndr;
 	struct nd_prefix *pr, *npr;
 	struct in6_ifaddr *ia6, *nia6;
+	bool onlink_locked;
 
 	TAILQ_INIT(&drq);
+	LIST_INIT(&prl);
 
-	/* expire default router list */
 	ND6_WLOCK();
 	TAILQ_FOREACH_SAFE(dr, &V_nd_defrouter, dr_entry, ndr)
 		if (dr->expire && dr->expire < time_uptime)
@@ -1018,23 +1023,51 @@ nd6_timer(void *arg)
 		}
 	}
 
-	/* expire prefix list */
+	ND6_WLOCK();
+	onlink_locked = false;
+restart:
 	LIST_FOREACH_SAFE(pr, &V_nd_prefix, ndpr_entry, npr) {
 		/*
-		 * check prefix lifetime.
-		 * since pltime is just for autoconf, pltime processing for
-		 * prefix is not necessary.
+		 * Expire prefixes. Since the pltime is only used for
+		 * autoconfigured addresses, pltime processing for prefixes is
+		 * not necessary.
+		 *
+		 * Only unlink after all derived addresses have expired. This
+		 * may not occur until two hours after the prefix has expired
+		 * per RFC 4862. If the prefix expires before its derived
+		 * addresses, mark it off-link. This will be done automatically
+		 * after unlinking if no address references remain.
 		 */
-		if (pr->ndpr_vltime != ND6_INFINITE_LIFETIME &&
-		    time_uptime - pr->ndpr_lastupdate > pr->ndpr_vltime) {
+		if (pr->ndpr_vltime == ND6_INFINITE_LIFETIME ||
+		    time_uptime - pr->ndpr_lastupdate <= pr->ndpr_vltime)
+			continue;
 
-			/*
-			 * address expiration and prefix expiration are
-			 * separate.  NEVER perform in6_purgeaddr here.
-			 */
-			prelist_remove(pr);
+		if (pr->ndpr_addrcnt == 0) {
+			nd6_prefix_unlink(pr, &prl);
+			continue;
+		}
+		if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0) {
+			if (!onlink_locked) {
+				onlink_locked = ND6_ONLINK_TRYLOCK();
+				if (!onlink_locked) {
+					ND6_WUNLOCK();
+					ND6_ONLINK_LOCK();
+					onlink_locked = true;
+					ND6_WLOCK();
+					goto restart;
+				}
+			}
+			(void)nd6_prefix_offlink(pr);
 		}
 	}
+	ND6_WUNLOCK();
+	if (onlink_locked)
+		ND6_ONLINK_UNLOCK();
+
+	while ((pr = LIST_FIRST(&prl)) != NULL) {
+		LIST_REMOVE(pr, ndpr_entry);
+		nd6_prefix_del(pr);
+	}
 
 	callout_reset(&V_nd6_timer_ch, V_nd6_prune * hz,
 	    nd6_timer, curvnet);
@@ -1120,10 +1153,12 @@ void
 nd6_purge(struct ifnet *ifp)
 {
 	struct nd_drhead drq;
+	struct nd_prhead prl;
 	struct nd_defrouter *dr, *ndr;
 	struct nd_prefix *pr, *npr;
 
 	TAILQ_INIT(&drq);
+	LIST_INIT(&prl);
 
 	/*
 	 * Nuke default router list entries toward ifp.
@@ -1138,33 +1173,31 @@ nd6_purge(struct ifnet *ifp)
 		if (dr->ifp == ifp)
 			defrouter_unlink(dr, &drq);
 	}
-
 	TAILQ_FOREACH_SAFE(dr, &V_nd_defrouter, dr_entry, ndr) {
 		if (!dr->installed)
 			continue;
 		if (dr->ifp == ifp)
 			defrouter_unlink(dr, &drq);
 	}
+
+	/*
+	 * Remove prefixes on ifp. We should have already removed addresses on
+	 * this interface, so no addresses should be referencing these prefixes.
+	 */
+	LIST_FOREACH_SAFE(pr, &V_nd_prefix, ndpr_entry, npr) {
+		if (pr->ndpr_ifp == ifp)
+			nd6_prefix_unlink(pr, &prl);
+	}
 	ND6_WUNLOCK();
 
+	/* Delete the unlinked router and prefix objects. */
 	while ((dr = TAILQ_FIRST(&drq)) != NULL) {
 		TAILQ_REMOVE(&drq, dr, dr_entry);
 		defrouter_del(dr);
 	}
-
-	/* Nuke prefix list entries toward ifp */
-	LIST_FOREACH_SAFE(pr, &V_nd_prefix, ndpr_entry, npr) {
-		if (pr->ndpr_ifp == ifp) {
-			/*
-			 * Because if_detach() does *not* release prefixes
-			 * while purging addresses the reference count will
-			 * still be above zero. We therefore reset it to
-			 * make sure that the prefix really gets purged.
-			 */
-			pr->ndpr_refcnt = 0;
-
-			prelist_remove(pr);
-		}
+	while ((pr = LIST_FIRST(&prl)) != NULL) {
+		LIST_REMOVE(pr, ndpr_entry);
+		nd6_prefix_del(pr);
 	}
 
 	/* cancel default outgoing interface setting */
@@ -1229,8 +1262,9 @@ nd6_is_new_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp)
 	struct ifaddr *dstaddr;
 	struct rt_addrinfo info;
 	struct sockaddr_in6 rt_key;
-	struct sockaddr *dst6;
-	int fibnum;
+	const struct sockaddr *dst6;
+	uint64_t genid;
+	int error, fibnum;
 
 	/*
 	 * A link-local address is always a neighbor.
@@ -1268,19 +1302,29 @@ nd6_is_new_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp)
 	 * If the address matches one of our on-link prefixes, it should be a
 	 * neighbor.
 	 */
+	ND6_RLOCK();
+restart:
 	LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
 		if (pr->ndpr_ifp != ifp)
 			continue;
 
-		if (!(pr->ndpr_stateflags & NDPRF_ONLINK)) {
-
+		if ((pr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
 			/* Always use the default FIB here. */
-			dst6 = (struct sockaddr *)&pr->ndpr_prefix;
+			dst6 = (const struct sockaddr *)&pr->ndpr_prefix;
+
+			genid = V_nd6_list_genid;
+			ND6_RUNLOCK();
 
 			/* Restore length field before retrying lookup */
 			rt_key.sin6_len = sizeof(rt_key);
-			if (rib_lookup_info(fibnum, dst6, 0, 0, &info) != 0)
+			error = rib_lookup_info(fibnum, dst6, 0, 0, &info);
+
+			ND6_RLOCK();
+			if (genid != V_nd6_list_genid)
+				goto restart;
+			if (error != 0)
 				continue;
+
 			/*
 			 * This is the case where multiple interfaces
 			 * have the same prefix, but only one is installed 
@@ -1292,14 +1336,17 @@ nd6_is_new_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp)
 			 * differ.
 			 */
 			if (!IN6_ARE_ADDR_EQUAL(&pr->ndpr_prefix.sin6_addr,
-			       &rt_key.sin6_addr))
+			    &rt_key.sin6_addr))
 				continue;
 		}
 
 		if (IN6_ARE_MASKED_ADDR_EQUAL(&pr->ndpr_prefix.sin6_addr,
-		    &addr->sin6_addr, &pr->ndpr_mask))
+		    &addr->sin6_addr, &pr->ndpr_mask)) {
+			ND6_RUNLOCK();
 			return (1);
+		}
 	}
+	ND6_RUNLOCK();
 
 	/*
 	 * If the address is assigned on the node of the other side of
@@ -1730,15 +1777,22 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
 	case SIOCSPFXFLUSH_IN6:
 	{
 		/* flush all the prefix advertised by routers */
+		struct in6_ifaddr *ia, *ia_next;
 		struct nd_prefix *pr, *next;
+		struct nd_prhead prl;
 
-		LIST_FOREACH_SAFE(pr, &V_nd_prefix, ndpr_entry, next) {
-			struct in6_ifaddr *ia, *ia_next;
+		LIST_INIT(&prl);
 
+		ND6_WLOCK();
+		LIST_FOREACH_SAFE(pr, &V_nd_prefix, ndpr_entry, next) {
 			if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr))
 				continue; /* XXX */
+			nd6_prefix_unlink(pr, &prl);
+		}
+		ND6_WUNLOCK();
 
-			/* do we really have to remove addresses as well? */
+		while ((pr = LIST_FIRST(&prl)) != NULL) {
+			LIST_REMOVE(pr, ndpr_entry);
 			/* XXXRW: in6_ifaddrhead locking. */
 			TAILQ_FOREACH_SAFE(ia, &V_in6_ifaddrhead, ia_link,
 			    ia_next) {
@@ -1748,7 +1802,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
 				if (ia->ia6_ndpr == pr)
 					in6_purgeaddr(&ia->ia_ifa);
 			}
-			prelist_remove(pr);
+			nd6_prefix_del(pr);
 		}
 		break;
 	}
@@ -2676,7 +2730,7 @@ nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS)
 			else
 				p.expire = maxexpire;
 		}
-		p.refcnt = pr->ndpr_refcnt;
+		p.refcnt = pr->ndpr_addrcnt;
 		p.flags = pr->ndpr_stateflags;
 		p.advrtrs = 0;
 		LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry)
@@ -2692,9 +2746,10 @@ nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS)
 				    ip6_sprintf(ip6buf, &pfr->router->rtaddr));
 			error = SYSCTL_OUT(req, &s6, sizeof(s6));
 			if (error != 0)
-				break;
+				goto out;
 		}
 	}
+out:
 	ND6_RUNLOCK();
 	return (error);
 }
diff --git a/freebsd/sys/netinet6/nd6.h b/freebsd/sys/netinet6/nd6.h
index 33ac438..9b9fa3d 100644
--- a/freebsd/sys/netinet6/nd6.h
+++ b/freebsd/sys/netinet6/nd6.h
@@ -256,7 +256,7 @@ struct nd_prefixctl {
 	struct prf_ra ndpr_flags;
 };
 
-
+LIST_HEAD(nd_prhead, nd_prefix);
 struct nd_prefix {
 	struct ifnet *ndpr_ifp;
 	LIST_ENTRY(nd_prefix) ndpr_entry;
@@ -275,7 +275,8 @@ struct nd_prefix {
 	/* list of routers that advertise the prefix: */
 	LIST_HEAD(pr_rtrhead, nd_pfxrouter) ndpr_advrtrs;
 	u_char	ndpr_plen;
-	int	ndpr_refcnt;	/* reference couter from addresses */
+	int	ndpr_addrcnt;	/* count of derived addresses */
+	volatile u_int ndpr_refcnt;
 };
 
 #define ndpr_raf		ndpr_flags
@@ -314,8 +315,6 @@ struct nd_pfxrouter {
 	struct nd_defrouter *router;
 };
 
-LIST_HEAD(nd_prhead, nd_prefix);
-
 #ifdef MALLOC_DECLARE
 MALLOC_DECLARE(M_IP6NDP);
 #endif
@@ -346,17 +345,30 @@ VNET_DECLARE(int, nd6_onlink_ns_rfc4861);
 
 /* Lock for the prefix and default router lists. */
 VNET_DECLARE(struct rwlock, nd6_lock);
+VNET_DECLARE(uint64_t, nd6_list_genid);
 #define	V_nd6_lock			VNET(nd6_lock)
+#define	V_nd6_list_genid		VNET(nd6_list_genid)
 
 #define	ND6_RLOCK()			rw_rlock(&V_nd6_lock)
 #define	ND6_RUNLOCK()			rw_runlock(&V_nd6_lock)
 #define	ND6_WLOCK()			rw_wlock(&V_nd6_lock)
 #define	ND6_WUNLOCK()			rw_wunlock(&V_nd6_lock)
+#define	ND6_TRY_UPGRADE()		rw_try_upgrade(&V_nd6_lock)
 #define	ND6_WLOCK_ASSERT()		rw_assert(&V_nd6_lock, RA_WLOCKED)
 #define	ND6_RLOCK_ASSERT()		rw_assert(&V_nd6_lock, RA_RLOCKED)
 #define	ND6_LOCK_ASSERT()		rw_assert(&V_nd6_lock, RA_LOCKED)
 #define	ND6_UNLOCK_ASSERT()		rw_assert(&V_nd6_lock, RA_UNLOCKED)
 
+/* Mutex for prefix onlink/offlink transitions. */
+VNET_DECLARE(struct mtx, nd6_onlink_mtx);
+#define	V_nd6_onlink_mtx		VNET(nd6_onlink_mtx)
+
+#define	ND6_ONLINK_LOCK()		mtx_lock(&V_nd6_onlink_mtx)
+#define	ND6_ONLINK_TRYLOCK()		mtx_trylock(&V_nd6_onlink_mtx)
+#define	ND6_ONLINK_UNLOCK()		mtx_unlock(&V_nd6_onlink_mtx)
+#define	ND6_ONLINK_LOCK_ASSERT()	mtx_assert(&V_nd6_onlink_mtx, MA_OWNED)
+#define	ND6_ONLINK_UNLOCK_ASSERT()	mtx_assert(&V_nd6_onlink_mtx, MA_NOTOWNED)
+
 #define nd6log(x)	do { if (V_nd6_debug) log x; } while (/*CONSTCOND*/ 0)
 
 /* nd6_rtr.c */
@@ -463,9 +475,14 @@ void defrouter_rele(struct nd_defrouter *);
 bool defrouter_remove(struct in6_addr *, struct ifnet *);
 void defrouter_unlink(struct nd_defrouter *, struct nd_drhead *);
 void defrouter_del(struct nd_defrouter *);
-void prelist_remove(struct nd_prefix *);
 int nd6_prelist_add(struct nd_prefixctl *, struct nd_defrouter *,
-	struct nd_prefix **);
+    struct nd_prefix **);
+void nd6_prefix_unlink(struct nd_prefix *, struct nd_prhead *);
+void nd6_prefix_del(struct nd_prefix *);
+void nd6_prefix_ref(struct nd_prefix *);
+void nd6_prefix_rele(struct nd_prefix *);
+int nd6_prefix_onlink(struct nd_prefix *);
+int nd6_prefix_offlink(struct nd_prefix *);
 void pfxlist_onlink_check(void);
 struct nd_defrouter *defrouter_lookup(struct in6_addr *, struct ifnet *);
 struct nd_defrouter *defrouter_lookup_locked(struct in6_addr *, struct ifnet *);
diff --git a/freebsd/sys/netinet6/nd6_nbr.c b/freebsd/sys/netinet6/nd6_nbr.c
index df50fa9..e30dca8 100644
--- a/freebsd/sys/netinet6/nd6_nbr.c
+++ b/freebsd/sys/netinet6/nd6_nbr.c
@@ -1219,40 +1219,26 @@ nd6_dad_start(struct ifaddr *ifa, int delay)
 	struct dadq *dp;
 	char ip6buf[INET6_ADDRSTRLEN];
 
+	KASSERT((ia->ia6_flags & IN6_IFF_TENTATIVE) != 0,
+	    ("starting DAD on non-tentative address %p", ifa));
+
 	/*
 	 * If we don't need DAD, don't do it.
 	 * There are several cases:
-	 * - DAD is disabled (ip6_dad_count == 0)
+	 * - DAD is disabled globally or on the interface
 	 * - the interface address is anycast
 	 */
-	if (!(ia->ia6_flags & IN6_IFF_TENTATIVE)) {
-		log(LOG_DEBUG,
-			"nd6_dad_start: called with non-tentative address "
-			"%s(%s)\n",
-			ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr),
-			ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
-		return;
-	}
-	if (ia->ia6_flags & IN6_IFF_ANYCAST) {
+	if ((ia->ia6_flags & IN6_IFF_ANYCAST) != 0 ||
+	    V_ip6_dad_count == 0 ||
+	    (ND_IFINFO(ifa->ifa_ifp)->flags & ND6_IFF_NO_DAD) != 0) {
 		ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
 		return;
 	}
-	if (!V_ip6_dad_count) {
-		ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
+	if ((ifa->ifa_ifp->if_flags & IFF_UP) == 0 ||
+	    (ifa->ifa_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
+	    (ND_IFINFO(ifa->ifa_ifp)->flags & ND6_IFF_IFDISABLED) != 0)
 		return;
-	}
-	if (ifa->ifa_ifp == NULL)
-		panic("nd6_dad_start: ifa->ifa_ifp == NULL");
-	if (ND_IFINFO(ifa->ifa_ifp)->flags & ND6_IFF_NO_DAD) {
-		ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
-		return;
-	}
-	if (!(ifa->ifa_ifp->if_flags & IFF_UP) ||
-	    !(ifa->ifa_ifp->if_drv_flags & IFF_DRV_RUNNING) ||
-	    (ND_IFINFO(ifa->ifa_ifp)->flags & ND6_IFF_IFDISABLED)) {
-		ia->ia6_flags |= IN6_IFF_TENTATIVE;
-		return;
-	}
+
 	if ((dp = nd6_dad_find(ifa, NULL)) != NULL) {
 		/*
 		 * DAD is already in progress.  Let the existing entry
@@ -1331,11 +1317,8 @@ nd6_dad_timer(struct dadq *dp)
 	struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
 	char ip6buf[INET6_ADDRSTRLEN];
 
-	/* Sanity check */
-	if (ia == NULL) {
-		log(LOG_ERR, "nd6_dad_timer: called with null parameter\n");
-		goto err;
-	}
+	KASSERT(ia != NULL, ("DAD entry %p with no address", dp));
+
 	if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) {
 		/* Do not need DAD for ifdisabled interface. */
 		log(LOG_ERR, "nd6_dad_timer: cancel DAD on %s because of "
diff --git a/freebsd/sys/netinet6/nd6_rtr.c b/freebsd/sys/netinet6/nd6_rtr.c
index c8d7c0e..33d8fa2 100644
--- a/freebsd/sys/netinet6/nd6_rtr.c
+++ b/freebsd/sys/netinet6/nd6_rtr.c
@@ -78,20 +78,16 @@ static int prelist_update(struct nd_prefixctl *, struct nd_defrouter *,
     struct mbuf *, int);
 static struct in6_ifaddr *in6_ifadd(struct nd_prefixctl *, int);
 static struct nd_pfxrouter *pfxrtr_lookup(struct nd_prefix *,
-	struct nd_defrouter *);
+    struct nd_defrouter *);
 static void pfxrtr_add(struct nd_prefix *, struct nd_defrouter *);
 static void pfxrtr_del(struct nd_pfxrouter *);
-static struct nd_pfxrouter *find_pfxlist_reachable_router
-(struct nd_prefix *);
+static struct nd_pfxrouter *find_pfxlist_reachable_router(struct nd_prefix *);
 static void defrouter_delreq(struct nd_defrouter *);
 static void nd6_rtmsg(int, struct rtentry *);
 
 static int in6_init_prefix_ltimes(struct nd_prefix *);
 static void in6_init_address_ltimes(struct nd_prefix *,
-	struct in6_addrlifetime *);
-
-static int nd6_prefix_onlink(struct nd_prefix *);
-static int nd6_prefix_offlink(struct nd_prefix *);
+    struct in6_addrlifetime *);
 
 static int rt6_deleteroute(const struct rtentry *, void *);
 
@@ -664,6 +660,7 @@ defrouter_unlink(struct nd_defrouter *dr, struct nd_drhead *drq)
 
 	ND6_WLOCK_ASSERT();
 	TAILQ_REMOVE(&V_nd_defrouter, dr, dr_entry);
+	V_nd6_list_genid++;
 	if (drq != NULL)
 		TAILQ_INSERT_TAIL(drq, dr, dr_entry);
 }
@@ -673,6 +670,7 @@ defrouter_del(struct nd_defrouter *dr)
 {
 	struct nd_defrouter *deldr = NULL;
 	struct nd_prefix *pr;
+	struct nd_pfxrouter *pfxrtr;
 
 	ND6_UNLOCK_ASSERT();
 
@@ -691,11 +689,13 @@ defrouter_del(struct nd_defrouter *dr)
 	/*
 	 * Also delete all the pointers to the router in each prefix lists.
 	 */
+	ND6_WLOCK();
 	LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
-		struct nd_pfxrouter *pfxrtr;
 		if ((pfxrtr = pfxrtr_lookup(pr, dr)) != NULL)
 			pfxrtr_del(pfxrtr);
 	}
+	ND6_WUNLOCK();
+
 	pfxlist_onlink_check();
 
 	/*
@@ -855,14 +855,18 @@ static struct nd_defrouter *
 defrtrlist_update(struct nd_defrouter *new)
 {
 	struct nd_defrouter *dr, *n;
+	uint64_t genid;
 	int oldpref;
+	bool writelocked;
 
 	if (new->rtlifetime == 0) {
 		defrouter_remove(&new->rtaddr, new->ifp);
 		return (NULL);
 	}
 
-	ND6_WLOCK();
+	ND6_RLOCK();
+	writelocked = false;
+restart:
 	dr = defrouter_lookup_locked(&new->rtaddr, new->ifp);
 	if (dr != NULL) {
 		oldpref = rtpref(dr);
@@ -878,10 +882,32 @@ defrtrlist_update(struct nd_defrouter *new)
 		 * router is still installed in the kernel.
 		 */
 		if (dr->installed && rtpref(new) == oldpref) {
-			ND6_WUNLOCK();
+			if (writelocked)
+				ND6_WUNLOCK();
+			else
+				ND6_RUNLOCK();
 			return (dr);
 		}
+	}
+
+	/*
+	 * The router needs to be reinserted into the default router
+	 * list, so upgrade to a write lock. If that fails and the list
+	 * has potentially changed while the lock was dropped, we'll
+	 * redo the lookup with the write lock held.
+	 */
+	if (!writelocked) {
+		writelocked = true;
+		if (!ND6_TRY_UPGRADE()) {
+			genid = V_nd6_list_genid;
+			ND6_RUNLOCK();
+			ND6_WLOCK();
+			if (genid != V_nd6_list_genid)
+				goto restart;
+		}
+	}
 
+	if (dr != NULL) {
 		/*
 		 * The preferred router may have changed, so relocate this
 		 * router.
@@ -915,6 +941,7 @@ defrtrlist_update(struct nd_defrouter *new)
 		TAILQ_INSERT_BEFORE(dr, n, dr_entry);
 	else
 		TAILQ_INSERT_TAIL(&V_nd_defrouter, n, dr_entry);
+	V_nd6_list_genid++;
 	ND6_WUNLOCK();
 
 	defrouter_select();
@@ -927,11 +954,12 @@ pfxrtr_lookup(struct nd_prefix *pr, struct nd_defrouter *dr)
 {
 	struct nd_pfxrouter *search;
 
+	ND6_LOCK_ASSERT();
+
 	LIST_FOREACH(search, &pr->ndpr_advrtrs, pfr_entry) {
 		if (search->router == dr)
 			break;
 	}
-
 	return (search);
 }
 
@@ -939,55 +967,110 @@ static void
 pfxrtr_add(struct nd_prefix *pr, struct nd_defrouter *dr)
 {
 	struct nd_pfxrouter *new;
+	bool update;
+
+	ND6_UNLOCK_ASSERT();
+
+	ND6_RLOCK();
+	if (pfxrtr_lookup(pr, dr) != NULL) {
+		ND6_RUNLOCK();
+		return;
+	}
+	ND6_RUNLOCK();
 
 	new = malloc(sizeof(*new), M_IP6NDP, M_NOWAIT | M_ZERO);
 	if (new == NULL)
 		return;
-	new->router = dr;
 	defrouter_ref(dr);
+	new->router = dr;
 
-	LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry);
+	ND6_WLOCK();
+	if (pfxrtr_lookup(pr, dr) == NULL) {
+		LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry);
+		update = true;
+	} else {
+		/* We lost a race to add the reference. */
+		defrouter_rele(dr);
+		free(new, M_IP6NDP);
+		update = false;
+	}
+	ND6_WUNLOCK();
 
-	pfxlist_onlink_check();
+	if (update)
+		pfxlist_onlink_check();
 }
 
 static void
 pfxrtr_del(struct nd_pfxrouter *pfr)
 {
 
+	ND6_WLOCK_ASSERT();
+
 	LIST_REMOVE(pfr, pfr_entry);
 	defrouter_rele(pfr->router);
 	free(pfr, M_IP6NDP);
 }
 
-struct nd_prefix *
-nd6_prefix_lookup(struct nd_prefixctl *key)
+static struct nd_prefix *
+nd6_prefix_lookup_locked(struct nd_prefixctl *key)
 {
 	struct nd_prefix *search;
 
+	ND6_LOCK_ASSERT();
+
 	LIST_FOREACH(search, &V_nd_prefix, ndpr_entry) {
 		if (key->ndpr_ifp == search->ndpr_ifp &&
 		    key->ndpr_plen == search->ndpr_plen &&
 		    in6_are_prefix_equal(&key->ndpr_prefix.sin6_addr,
 		    &search->ndpr_prefix.sin6_addr, key->ndpr_plen)) {
+			nd6_prefix_ref(search);
 			break;
 		}
 	}
+	return (search);
+}
+
+struct nd_prefix *
+nd6_prefix_lookup(struct nd_prefixctl *key)
+{
+	struct nd_prefix *search;
 
+	ND6_RLOCK();
+	search = nd6_prefix_lookup_locked(key);
+	ND6_RUNLOCK();
 	return (search);
 }
 
+void
+nd6_prefix_ref(struct nd_prefix *pr)
+{
+
+	refcount_acquire(&pr->ndpr_refcnt);
+}
+
+void
+nd6_prefix_rele(struct nd_prefix *pr)
+{
+
+	if (refcount_release(&pr->ndpr_refcnt)) {
+		KASSERT(LIST_EMPTY(&pr->ndpr_advrtrs),
+		    ("prefix %p has advertising routers", pr));
+		free(pr, M_IP6NDP);
+	}
+}
+
 int
 nd6_prelist_add(struct nd_prefixctl *pr, struct nd_defrouter *dr,
     struct nd_prefix **newp)
 {
-	struct nd_prefix *new = NULL;
-	int error = 0;
+	struct nd_prefix *new;
 	char ip6buf[INET6_ADDRSTRLEN];
+	int error;
 
 	new = malloc(sizeof(*new), M_IP6NDP, M_NOWAIT | M_ZERO);
 	if (new == NULL)
 		return (ENOMEM);
+	refcount_init(&new->ndpr_refcnt, newp != NULL ? 2 : 1);
 	new->ndpr_ifp = pr->ndpr_ifp;
 	new->ndpr_prefix = pr->ndpr_prefix;
 	new->ndpr_plen = pr->ndpr_plen;
@@ -1006,20 +1089,22 @@ nd6_prelist_add(struct nd_prefixctl *pr, struct nd_defrouter *dr,
 	/* make prefix in the canonical form */
 	IN6_MASK_ADDR(&new->ndpr_prefix.sin6_addr, &new->ndpr_mask);
 
-	/* link ndpr_entry to nd_prefix list */
+	ND6_WLOCK();
 	LIST_INSERT_HEAD(&V_nd_prefix, new, ndpr_entry);
+	V_nd6_list_genid++;
+	ND6_WUNLOCK();
 
 	/* ND_OPT_PI_FLAG_ONLINK processing */
 	if (new->ndpr_raf_onlink) {
-		int e;
-
-		if ((e = nd6_prefix_onlink(new)) != 0) {
+		ND6_ONLINK_LOCK();
+		if ((error = nd6_prefix_onlink(new)) != 0) {
 			nd6log((LOG_ERR, "nd6_prelist_add: failed to make "
 			    "the prefix %s/%d on-link on %s (errno=%d)\n",
 			    ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
-			    pr->ndpr_plen, if_name(pr->ndpr_ifp), e));
+			    pr->ndpr_plen, if_name(pr->ndpr_ifp), error));
 			/* proceed anyway. XXX: is it correct? */
 		}
+		ND6_ONLINK_UNLOCK();
 	}
 
 	if (dr != NULL)
@@ -1029,51 +1114,69 @@ nd6_prelist_add(struct nd_prefixctl *pr, struct nd_defrouter *dr,
 	return (0);
 }
 
+/*
+ * Remove a prefix from the prefix list and optionally stash it in a
+ * caller-provided list.
+ *
+ * The ND6 lock must be held.
+ */
 void
-prelist_remove(struct nd_prefix *pr)
+nd6_prefix_unlink(struct nd_prefix *pr, struct nd_prhead *list)
+{
+
+	KASSERT(pr->ndpr_addrcnt == 0,
+	    ("prefix %p has referencing addresses", pr));
+	ND6_WLOCK_ASSERT();
+
+	LIST_REMOVE(pr, ndpr_entry);
+	V_nd6_list_genid++;
+	if (list != NULL)
+		LIST_INSERT_HEAD(list, pr, ndpr_entry);
+}
+
+/*
+ * Free an unlinked prefix, first marking it off-link if necessary.
+ */
+void
+nd6_prefix_del(struct nd_prefix *pr)
 {
 	struct nd_pfxrouter *pfr, *next;
 	int e;
 	char ip6buf[INET6_ADDRSTRLEN];
 
-	/* make sure to invalidate the prefix until it is really freed. */
-	pr->ndpr_vltime = 0;
-	pr->ndpr_pltime = 0;
+	KASSERT(pr->ndpr_addrcnt == 0,
+	    ("prefix %p has referencing addresses", pr));
+	ND6_UNLOCK_ASSERT();
 
 	/*
 	 * Though these flags are now meaningless, we'd rather keep the value
 	 * of pr->ndpr_raf_onlink and pr->ndpr_raf_auto not to confuse users
 	 * when executing "ndp -p".
 	 */
-
-	if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0 &&
-	    (e = nd6_prefix_offlink(pr)) != 0) {
-		nd6log((LOG_ERR, "prelist_remove: failed to make %s/%d offlink "
-		    "on %s, errno=%d\n",
-		    ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
-		    pr->ndpr_plen, if_name(pr->ndpr_ifp), e));
-		/* what should we do? */
+	if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0) {
+		ND6_ONLINK_LOCK();
+		if ((e = nd6_prefix_offlink(pr)) != 0) {
+			nd6log((LOG_ERR,
+			    "nd6_prefix_del: failed to make %s/%d offlink "
+			    "on %s, errno=%d\n",
+			    ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
+			    pr->ndpr_plen, if_name(pr->ndpr_ifp), e));
+			/* what should we do? */
+		}
+		ND6_ONLINK_UNLOCK();
 	}
 
-	if (pr->ndpr_refcnt > 0)
-		return;		/* notice here? */
-
-	/* unlink ndpr_entry from nd_prefix list */
-	LIST_REMOVE(pr, ndpr_entry);
-
-	/* free list of routers that advertised the prefix */
-	LIST_FOREACH_SAFE(pfr, &pr->ndpr_advrtrs, pfr_entry, next) {
+	/* Release references to routers that have advertised this prefix. */
+	ND6_WLOCK();
+	LIST_FOREACH_SAFE(pfr, &pr->ndpr_advrtrs, pfr_entry, next)
 		pfxrtr_del(pfr);
-	}
-	free(pr, M_IP6NDP);
+	ND6_WUNLOCK();
+
+	nd6_prefix_rele(pr);
 
 	pfxlist_onlink_check();
 }
 
-/*
- * dr - may be NULL
- */
-
 static int
 prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
     struct mbuf *m, int mcast)
@@ -1123,21 +1226,22 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
 
 		if (new->ndpr_raf_onlink &&
 		    (pr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
-			int e;
-
-			if ((e = nd6_prefix_onlink(pr)) != 0) {
+			ND6_ONLINK_LOCK();
+			if ((error = nd6_prefix_onlink(pr)) != 0) {
 				nd6log((LOG_ERR,
 				    "prelist_update: failed to make "
 				    "the prefix %s/%d on-link on %s "
 				    "(errno=%d)\n",
 				    ip6_sprintf(ip6buf,
-					    &pr->ndpr_prefix.sin6_addr),
-				    pr->ndpr_plen, if_name(pr->ndpr_ifp), e));
+				        &pr->ndpr_prefix.sin6_addr),
+				    pr->ndpr_plen, if_name(pr->ndpr_ifp),
+				    error));
 				/* proceed anyway. XXX: is it correct? */
 			}
+			ND6_ONLINK_UNLOCK();
 		}
 
-		if (dr && pfxrtr_lookup(pr, dr) == NULL)
+		if (dr != NULL)
 			pfxrtr_add(pr, dr);
 	} else {
 		if (new->ndpr_vltime == 0)
@@ -1358,7 +1462,7 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
 			/*
 			 * note that we should use pr (not new) for reference.
 			 */
-			pr->ndpr_refcnt++;
+			pr->ndpr_addrcnt++;
 			ia6->ia6_ndpr = pr;
 
 			/*
@@ -1396,8 +1500,10 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
 		}
 	}
 
- end:
-	return error;
+end:
+	if (pr != NULL)
+		nd6_prefix_rele(pr);
+	return (error);
 }
 
 /*
@@ -1412,6 +1518,8 @@ find_pfxlist_reachable_router(struct nd_prefix *pr)
 	struct llentry *ln;
 	int canreach;
 
+	ND6_LOCK_ASSERT();
+
 	LIST_FOREACH(pfxrtr, &pr->ndpr_advrtrs, pfr_entry) {
 		IF_AFDATA_RLOCK(pfxrtr->router->ifp);
 		ln = nd6_lookup(&pfxrtr->router->rtaddr, 0, pfxrtr->router->ifp);
@@ -1434,7 +1542,7 @@ find_pfxlist_reachable_router(struct nd_prefix *pr)
  * we have moved from the network but the lifetime of the prefix has not
  * expired yet.  So we should not use the prefix if there is another prefix
  * that has an available router.
- * But, if there is no prefix that has an available router, we still regards
+ * But, if there is no prefix that has an available router, we still regard
  * all the prefixes as on-link.  This is because we can't tell if all the
  * routers are simply dead or if we really moved from the network and there
  * is no router around us.
@@ -1447,6 +1555,11 @@ pfxlist_onlink_check(void)
 	struct nd_defrouter *dr;
 	struct nd_pfxrouter *pfxrtr = NULL;
 	struct rm_priotracker in6_ifa_tracker;
+	uint64_t genid;
+	uint32_t flags;
+
+	ND6_ONLINK_LOCK();
+	ND6_RLOCK();
 
 	/*
 	 * Check if there is a prefix that has a reachable advertising
@@ -1462,7 +1575,6 @@ pfxlist_onlink_check(void)
 	 * that does not advertise any prefixes.
 	 */
 	if (pr == NULL) {
-		ND6_RLOCK();
 		TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) {
 			struct nd_prefix *pr0;
 
@@ -1473,7 +1585,6 @@ pfxlist_onlink_check(void)
 			if (pfxrtr != NULL)
 				break;
 		}
-		ND6_RUNLOCK();
 	}
 	if (pr != NULL || (!TAILQ_EMPTY(&V_nd_defrouter) && pfxrtr == NULL)) {
 		/*
@@ -1487,40 +1598,26 @@ pfxlist_onlink_check(void)
 		 */
 		LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
 			/* XXX: a link-local prefix should never be detached */
-			if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr))
-				continue;
-
-			/*
-			 * we aren't interested in prefixes without the L bit
-			 * set.
-			 */
-			if (pr->ndpr_raf_onlink == 0)
-				continue;
-
-			if (pr->ndpr_raf_auto == 0)
+			if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr) ||
+			    pr->ndpr_raf_onlink == 0 ||
+			    pr->ndpr_raf_auto == 0)
 				continue;
 
 			if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 &&
 			    find_pfxlist_reachable_router(pr) == NULL)
 				pr->ndpr_stateflags |= NDPRF_DETACHED;
-			if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 &&
+			else if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 &&
 			    find_pfxlist_reachable_router(pr) != NULL)
 				pr->ndpr_stateflags &= ~NDPRF_DETACHED;
 		}
 	} else {
 		/* there is no prefix that has a reachable router */
 		LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
-			if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr))
-				continue;
-
-			if (pr->ndpr_raf_onlink == 0)
-				continue;
-
-			if (pr->ndpr_raf_auto == 0)
+			if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr) ||
+			    pr->ndpr_raf_onlink == 0 ||
+			    pr->ndpr_raf_auto == 0)
 				continue;
-
-			if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0)
-				pr->ndpr_stateflags &= ~NDPRF_DETACHED;
+			pr->ndpr_stateflags &= ~NDPRF_DETACHED;
 		}
 	}
 
@@ -1532,34 +1629,30 @@ pfxlist_onlink_check(void)
 	 * interfaces.  Such cases will be handled in nd6_prefix_onlink,
 	 * so we don't have to care about them.
 	 */
+restart:
 	LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
-		int e;
 		char ip6buf[INET6_ADDRSTRLEN];
+		int e;
 
-		if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr))
-			continue;
-
-		if (pr->ndpr_raf_onlink == 0)
-			continue;
-
-		if (pr->ndpr_raf_auto == 0)
+		if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr) ||
+		    pr->ndpr_raf_onlink == 0 ||
+		    pr->ndpr_raf_auto == 0)
 			continue;
 
-		if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 &&
-		    (pr->ndpr_stateflags & NDPRF_ONLINK) != 0) {
-			if ((e = nd6_prefix_offlink(pr)) != 0) {
+		flags = pr->ndpr_stateflags & (NDPRF_DETACHED | NDPRF_ONLINK);
+		if (flags == 0 || flags == (NDPRF_DETACHED | NDPRF_ONLINK)) {
+			genid = V_nd6_list_genid;
+			ND6_RUNLOCK();
+			if ((flags & NDPRF_ONLINK) != 0 &&
+			    (e = nd6_prefix_offlink(pr)) != 0) {
 				nd6log((LOG_ERR,
 				    "pfxlist_onlink_check: failed to "
 				    "make %s/%d offlink, errno=%d\n",
 				    ip6_sprintf(ip6buf,
 					    &pr->ndpr_prefix.sin6_addr),
 					    pr->ndpr_plen, e));
-			}
-		}
-		if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 &&
-		    (pr->ndpr_stateflags & NDPRF_ONLINK) == 0 &&
-		    pr->ndpr_raf_onlink) {
-			if ((e = nd6_prefix_onlink(pr)) != 0) {
+			} else if ((flags & NDPRF_ONLINK) == 0 &&
+			    (e = nd6_prefix_onlink(pr)) != 0) {
 				nd6log((LOG_ERR,
 				    "pfxlist_onlink_check: failed to "
 				    "make %s/%d onlink, errno=%d\n",
@@ -1567,6 +1660,9 @@ pfxlist_onlink_check(void)
 					    &pr->ndpr_prefix.sin6_addr),
 					    pr->ndpr_plen, e));
 			}
+			ND6_RLOCK();
+			if (genid != V_nd6_list_genid)
+				goto restart;
 		}
 	}
 
@@ -1627,6 +1723,8 @@ pfxlist_onlink_check(void)
 		}
 	}
 	IN6_IFADDR_RUNLOCK(&in6_ifa_tracker);
+	ND6_RUNLOCK();
+	ND6_ONLINK_UNLOCK();
 }
 
 static int
@@ -1707,23 +1805,20 @@ nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa)
 	return (a_failure);
 }
 
-static int
+int
 nd6_prefix_onlink(struct nd_prefix *pr)
 {
 	struct ifaddr *ifa;
 	struct ifnet *ifp = pr->ndpr_ifp;
 	struct nd_prefix *opr;
-	int error = 0;
 	char ip6buf[INET6_ADDRSTRLEN];
+	int error;
 
-	/* sanity check */
-	if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0) {
-		nd6log((LOG_ERR,
-		    "nd6_prefix_onlink: %s/%d is already on-link\n",
-		    ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
-		    pr->ndpr_plen));
+	ND6_ONLINK_LOCK_ASSERT();
+	ND6_UNLOCK_ASSERT();
+
+	if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0)
 		return (EEXIST);
-	}
 
 	/*
 	 * Add the interface route associated with the prefix.  Before
@@ -1732,6 +1827,7 @@ nd6_prefix_onlink(struct nd_prefix *pr)
 	 * Although such a configuration is expected to be rare, we explicitly
 	 * allow it.
 	 */
+	ND6_RLOCK();
 	LIST_FOREACH(opr, &V_nd_prefix, ndpr_entry) {
 		if (opr == pr)
 			continue;
@@ -1741,9 +1837,12 @@ nd6_prefix_onlink(struct nd_prefix *pr)
 
 		if (opr->ndpr_plen == pr->ndpr_plen &&
 		    in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr,
-		    &opr->ndpr_prefix.sin6_addr, pr->ndpr_plen))
+		    &opr->ndpr_prefix.sin6_addr, pr->ndpr_plen)) {
+			ND6_RUNLOCK();
 			return (0);
+		}
 	}
+	ND6_RUNLOCK();
 
 	/*
 	 * We prefer link-local addresses as the associated interface address.
@@ -1755,11 +1854,11 @@ nd6_prefix_onlink(struct nd_prefix *pr)
 		/* XXX: freebsd does not have ifa_ifwithaf */
 		IF_ADDR_RLOCK(ifp);
 		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
-			if (ifa->ifa_addr->sa_family == AF_INET6)
+			if (ifa->ifa_addr->sa_family == AF_INET6) {
+				ifa_ref(ifa);
 				break;
+			}
 		}
-		if (ifa != NULL)
-			ifa_ref(ifa);
 		IF_ADDR_RUNLOCK(ifp);
 		/* should we care about ia6_flags? */
 	}
@@ -1786,7 +1885,7 @@ nd6_prefix_onlink(struct nd_prefix *pr)
 	return (error);
 }
 
-static int
+int
 nd6_prefix_offlink(struct nd_prefix *pr)
 {
 	int error = 0;
@@ -1795,16 +1894,14 @@ nd6_prefix_offlink(struct nd_prefix *pr)
 	struct sockaddr_in6 sa6, mask6;
 	struct rtentry *rt;
 	char ip6buf[INET6_ADDRSTRLEN];
+	uint64_t genid;
 	int fibnum, a_failure;
 
-	/* sanity check */
-	if ((pr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
-		nd6log((LOG_ERR,
-		    "nd6_prefix_offlink: %s/%d is already off-link\n",
-		    ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
-		    pr->ndpr_plen));
+	ND6_ONLINK_LOCK_ASSERT();
+	ND6_UNLOCK_ASSERT();
+
+	if ((pr->ndpr_stateflags & NDPRF_ONLINK) == 0)
 		return (EEXIST);
-	}
 
 	bzero(&sa6, sizeof(sa6));
 	sa6.sin6_family = AF_INET6;
@@ -1845,18 +1942,15 @@ nd6_prefix_offlink(struct nd_prefix *pr)
 		 * If there's one, try to make the prefix on-link on the
 		 * interface.
 		 */
+		ND6_RLOCK();
+restart:
 		LIST_FOREACH(opr, &V_nd_prefix, ndpr_entry) {
-			if (opr == pr)
-				continue;
-
-			if ((opr->ndpr_stateflags & NDPRF_ONLINK) != 0)
-				continue;
-
 			/*
 			 * KAME specific: detached prefixes should not be
 			 * on-link.
 			 */
-			if ((opr->ndpr_stateflags & NDPRF_DETACHED) != 0)
+			if (opr == pr || (opr->ndpr_stateflags &
+			    (NDPRF_ONLINK | NDPRF_DETACHED)) != 0)
 				continue;
 
 			if (opr->ndpr_plen == pr->ndpr_plen &&
@@ -1864,6 +1958,8 @@ nd6_prefix_offlink(struct nd_prefix *pr)
 			    &opr->ndpr_prefix.sin6_addr, pr->ndpr_plen)) {
 				int e;
 
+				genid = V_nd6_list_genid;
+				ND6_RUNLOCK();
 				if ((e = nd6_prefix_onlink(opr)) != 0) {
 					nd6log((LOG_ERR,
 					    "nd6_prefix_offlink: failed to "
@@ -1875,8 +1971,12 @@ nd6_prefix_offlink(struct nd_prefix *pr)
 					    if_name(opr->ndpr_ifp), e));
 				} else
 					a_failure = 0;
+				ND6_RLOCK();
+				if (genid != V_nd6_list_genid)
+					goto restart;
 			}
 		}
+		ND6_RUNLOCK();
 	} else {
 		/* XXX: can we still set the NDPRF_ONLINK flag? */
 		nd6log((LOG_ERR,
@@ -2116,7 +2216,7 @@ in6_tmpifadd(const struct in6_ifaddr *ia0, int forcegen, int delay)
 		return (EINVAL); /* XXX */
 	}
 	newia->ia6_ndpr = ia0->ia6_ndpr;
-	newia->ia6_ndpr->ndpr_refcnt++;
+	newia->ia6_ndpr->ndpr_addrcnt++;
 	ifa_free(&newia->ia_ifa);
 
 	/*
diff --git a/freebsd/sys/netinet6/raw_ip6.c b/freebsd/sys/netinet6/raw_ip6.c
index dfd7c45..5b0577d 100644
--- a/freebsd/sys/netinet6/raw_ip6.c
+++ b/freebsd/sys/netinet6/raw_ip6.c
@@ -258,7 +258,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
 			}
 		}
 		if (last != NULL) {
-			struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
+			struct mbuf *n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
 
 #ifdef IPSEC
 			/*
diff --git a/freebsd/sys/netinet6/sctp6_usrreq.c b/freebsd/sys/netinet6/sctp6_usrreq.c
index 962a622..735de62 100644
--- a/freebsd/sys/netinet6/sctp6_usrreq.c
+++ b/freebsd/sys/netinet6/sctp6_usrreq.c
@@ -76,10 +76,8 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port)
 	struct sctphdr *sh;
 	struct sctp_chunkhdr *ch;
 	int length, offset;
-
 #if !defined(SCTP_WITH_NO_CSUM)
 	uint8_t compute_crc;
-
 #endif
 	uint32_t mflowid;
 	uint8_t mflowtype;
@@ -196,7 +194,6 @@ sctp6_notify(struct sctp_inpcb *inp,
 {
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
 	struct socket *so;
-
 #endif
 	int timer_stopped;
 
@@ -700,7 +697,6 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
 
 #ifdef INET
 	struct sockaddr_in6 *sin6;
-
 #endif				/* INET */
 	/* No SPL needed since sctp_output does this */
 
@@ -802,12 +798,10 @@ sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
 	int error = 0;
 	struct sctp_inpcb *inp;
 	struct sctp_tcb *stcb;
-
 #ifdef INET
 	struct in6pcb *inp6;
 	struct sockaddr_in6 *sin6;
 	union sctp_sockstore store;
-
 #endif
 
 #ifdef INET
diff --git a/freebsd/sys/netinet6/sctp6_var.h b/freebsd/sys/netinet6/sctp6_var.h
index 782567c..232fee1 100644
--- a/freebsd/sys/netinet6/sctp6_var.h
+++ b/freebsd/sys/netinet6/sctp6_var.h
@@ -50,6 +50,5 @@ void sctp6_ctlinput(int, struct sockaddr *, void *);
 void 
 sctp6_notify(struct sctp_inpcb *, struct sctp_tcb *, struct sctp_nets *,
     uint8_t, uint8_t, uint16_t);
-
 #endif
 #endif
diff --git a/freebsd/sys/netinet6/udp6_usrreq.c b/freebsd/sys/netinet6/udp6_usrreq.c
index 790bed2..2f950e6 100644
--- a/freebsd/sys/netinet6/udp6_usrreq.c
+++ b/freebsd/sys/netinet6/udp6_usrreq.c
@@ -368,7 +368,8 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
 			if (last != NULL) {
 				struct mbuf *n;
 
-				if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
+				if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) !=
+				    NULL) {
 					INP_RLOCK(last);
 					UDP_PROBE(receive, NULL, last, ip6,
 					    last, uh);
@@ -900,7 +901,7 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6,
 
 		UDP_PROBE(send, NULL, inp, ip6, inp, udp6);
 		UDPSTAT_INC(udps_opackets);
-		error = ip6_output(m, optp, NULL, flags,
+		error = ip6_output(m, optp, &inp->inp_route6, flags,
 		    inp->in6p_moptions, NULL, inp);
 		break;
 	case AF_INET:
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw2.c b/freebsd/sys/netpfil/ipfw/ip_fw2.c
index a3a1181..945ad17 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw2.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw2.c
@@ -2728,6 +2728,7 @@ ipfw_init(void)
 	  default_fw_tables = IPFW_TABLES_MAX;
 
 	ipfw_init_sopt_handler();
+	ipfw_init_obj_rewriter();
 	ipfw_iface_init();
 	return (error);
 }
@@ -2742,6 +2743,7 @@ ipfw_destroy(void)
 
 	ipfw_iface_destroy();
 	ipfw_destroy_sopt_handler();
+	ipfw_destroy_obj_rewriter();
 	printf("IP firewall unloaded\n");
 }
 #endif /* __rtems__ */
@@ -2777,7 +2779,6 @@ vnet_ipfw_init(const void *unused)
 	/* Init shared services hash table */
 	ipfw_init_srv(chain);
 
-	ipfw_init_obj_rewriter();
 	ipfw_init_counters();
 	/* insert the default rule and create the initial map */
 	chain->n_rules = 1;
@@ -2883,7 +2884,6 @@ vnet_ipfw_uninit(const void *unused)
 	IPFW_LOCK_DESTROY(chain);
 	ipfw_dyn_uninit(1);	/* free the remaining parts */
 	ipfw_destroy_counters();
-	ipfw_destroy_obj_rewriter();
 	ipfw_bpf_uninit(last);
 	return (0);
 }
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_dynamic.c b/freebsd/sys/netpfil/ipfw/ip_fw_dynamic.c
index 4696faa..5694b1d 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_dynamic.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_dynamic.c
@@ -258,9 +258,8 @@ hash_packet6(struct ipfw_flow_id *id)
 	i = (id->dst_ip6.__u6_addr.__u6_addr32[2]) ^
 	    (id->dst_ip6.__u6_addr.__u6_addr32[3]) ^
 	    (id->src_ip6.__u6_addr.__u6_addr32[2]) ^
-	    (id->src_ip6.__u6_addr.__u6_addr32[3]) ^
-	    (id->dst_port) ^ (id->src_port);
-	return i;
+	    (id->src_ip6.__u6_addr.__u6_addr32[3]);
+	return ntohl(i);
 }
 #endif
 
@@ -279,9 +278,9 @@ hash_packet(struct ipfw_flow_id *id, int buckets)
 		i = hash_packet6(id);
 	else
 #endif /* INET6 */
-	i = (id->dst_ip) ^ (id->src_ip) ^ (id->dst_port) ^ (id->src_port);
-	i &= (buckets - 1);
-	return i;
+	i = (id->dst_ip) ^ (id->src_ip);
+	i ^= (id->dst_port) ^ (id->src_port);
+	return (i & (buckets - 1));
 }
 
 #if 0
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_pfil.c b/freebsd/sys/netpfil/ipfw/ip_fw_pfil.c
index 59c13aa..167d202 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_pfil.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_pfil.c
@@ -305,11 +305,9 @@ again:
 
 /*
  * ipfw processing for ethernet packets (in and out).
- * Inteface is NULL from ether_demux, and ifp from
- * ether_output_frame.
  */
 int
-ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *dst, int dir,
+ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
     struct inpcb *inp)
 {
 	struct ether_header *eh;
@@ -319,20 +317,15 @@ ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *dst, int dir,
 	struct ip_fw_args args;
 	struct m_tag *mtag;
 
-	/* fetch start point from rule, if any */
+	/* fetch start point from rule, if any.  remove the tag if present. */
 	mtag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL);
 	if (mtag == NULL) {
 		args.rule.slot = 0;
 	} else {
-		/* dummynet packet, already partially processed */
-		struct ipfw_rule_ref *r;
-
-		/* XXX can we free it after use ? */
-		mtag->m_tag_id = PACKET_TAG_NONE;
-		r = (struct ipfw_rule_ref *)(mtag + 1);
-		if (r->info & IPFW_ONEPASS)
+		args.rule = *((struct ipfw_rule_ref *)(mtag+1));
+		m_tag_delete(*m0, mtag);
+		if (args.rule.info & IPFW_ONEPASS)
 			return (0);
-		args.rule = *r;
 	}
 
 	/* I need some amt of data to be contiguous */
@@ -350,7 +343,7 @@ ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *dst, int dir,
 	m_adj(m, ETHER_HDR_LEN);	/* strip ethernet header */
 
 	args.m = m;		/* the packet we are looking at		*/
-	args.oif = dir == PFIL_OUT ? dst: NULL;	/* destination, if any	*/
+	args.oif = dir == PFIL_OUT ? ifp: NULL;	/* destination, if any	*/
 	args.next_hop = NULL;	/* we do not support forward yet	*/
 	args.next_hop6 = NULL;	/* we do not support forward yet	*/
 	args.eh = &save_eh;	/* MAC header for bridged/MAC packets	*/
@@ -385,14 +378,13 @@ ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *dst, int dir,
 
 	case IP_FW_DUMMYNET:
 		ret = EACCES;
-		int dir;
 
 		if (ip_dn_io_ptr == NULL)
 			break; /* i.e. drop */
 
 		*m0 = NULL;
-		dir = PROTO_LAYER2 | (dst ? DIR_OUT : DIR_IN);
-		ip_dn_io_ptr(&m, dir, &args);
+		dir = (dir == PFIL_IN) ? DIR_IN : DIR_OUT;
+		ip_dn_io_ptr(&m, dir | PROTO_LAYER2, &args);
 		return 0;
 
 	default:
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_table.c b/freebsd/sys/netpfil/ipfw/ip_fw_table.c
index 9d2baad..17c5f01 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_table.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_table.c
@@ -1089,6 +1089,7 @@ find_table_entry(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
 	struct table_config *tc;
 	struct table_algo *ta;
 	struct table_info *kti;
+	struct table_value *pval;
 	struct namedobj_instance *ni;
 	int error;
 	size_t sz;
@@ -1134,7 +1135,10 @@ find_table_entry(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
 		return (ENOTSUP);
 
 	error = ta->find_tentry(tc->astate, kti, tent);
-
+	if (error == 0) {
+		pval = get_table_value(ch, tc, tent->v.kidx);
+		ipfw_export_table_value_v1(pval, &tent->v.value);
+	}
 	IPFW_UH_RUNLOCK(ch);
 
 	return (error);
@@ -2878,13 +2882,12 @@ table_manage_sets(struct ip_fw_chain *ch, uint16_t set, uint8_t new_set,
 	switch (cmd) {
 	case SWAP_ALL:
 	case TEST_ALL:
+	case MOVE_ALL:
 		/*
-		 * Return success for TEST_ALL, since nothing prevents
-		 * move rules from one set to another. All tables are
-		 * accessible from all sets when per-set tables sysctl
-		 * is disabled.
+		 * Always return success, the real action and decision
+		 * should make table_manage_sets_all().
 		 */
-	case MOVE_ALL:
+		return (0);
 	case TEST_ONE:
 	case MOVE_ONE:
 		/*
@@ -2909,6 +2912,39 @@ table_manage_sets(struct ip_fw_chain *ch, uint16_t set, uint8_t new_set,
 	    set, new_set, cmd));
 }
 
+/*
+ * We register several opcode rewriters for lookup tables.
+ * All tables opcodes have the same ETLV type, but different subtype.
+ * To avoid invoking sets handler several times for XXX_ALL commands,
+ * we use separate manage_sets handler. O_RECV has the lowest value,
+ * so it should be called first.
+ */
+static int
+table_manage_sets_all(struct ip_fw_chain *ch, uint16_t set, uint8_t new_set,
+    enum ipfw_sets_cmd cmd)
+{
+
+	switch (cmd) {
+	case SWAP_ALL:
+	case TEST_ALL:
+		/*
+		 * Return success for TEST_ALL, since nothing prevents
+		 * move rules from one set to another. All tables are
+		 * accessible from all sets when per-set tables sysctl
+		 * is disabled.
+		 */
+	case MOVE_ALL:
+		if (V_fw_tables_sets == 0)
+			return (0);
+		break;
+	default:
+		return (table_manage_sets(ch, set, new_set, cmd));
+	}
+	/* Use generic sets handler when per-set sysctl is enabled. */
+	return (ipfw_obj_manage_sets(CHAIN_TO_NI(ch), IPFW_TLV_TBL_NAME,
+	    set, new_set, cmd));
+}
+
 static struct opcode_obj_rewrite opcodes[] = {
 	{
 		.opcode = O_IP_SRC_LOOKUP,
@@ -2958,7 +2994,7 @@ static struct opcode_obj_rewrite opcodes[] = {
 		.find_byname = table_findbyname,
 		.find_bykidx = table_findbykidx,
 		.create_object = create_table_compat,
-		.manage_sets = table_manage_sets,
+		.manage_sets = table_manage_sets_all,
 	},
 	{
 		.opcode = O_VIA,
diff --git a/freebsd/sys/netpfil/ipfw/nat64/nat64_translate.c b/freebsd/sys/netpfil/ipfw/nat64/nat64_translate.c
index d250767..2f88147 100644
--- a/freebsd/sys/netpfil/ipfw/nat64/nat64_translate.c
+++ b/freebsd/sys/netpfil/ipfw/nat64/nat64_translate.c
@@ -1258,9 +1258,9 @@ nat64_handle_icmp6(struct mbuf *m, int hlen, uint32_t aaddr, uint16_t aport,
 		 */
 		mtu -= sizeof(struct ip6_hdr) - sizeof(struct ip);
 		break;
-	case ICMP6_TIME_EXCEED_TRANSIT:
+	case ICMP6_TIME_EXCEEDED:
 		type = ICMP_TIMXCEED;
-		code = ICMP_TIMXCEED_INTRANS;
+		code = icmp6->icmp6_code;
 		break;
 	case ICMP6_PARAM_PROB:
 		switch (icmp6->icmp6_code) {
diff --git a/freebsd/sys/netpfil/pf/if_pflog.c b/freebsd/sys/netpfil/pf/if_pflog.c
index 3a364ab..09473f1 100644
--- a/freebsd/sys/netpfil/pf/if_pflog.c
+++ b/freebsd/sys/netpfil/pf/if_pflog.c
@@ -223,7 +223,7 @@ pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
 
 	if (am == NULL) {
 		hdr.rulenr = htonl(rm->nr);
-		hdr.subrulenr =  1;
+		hdr.subrulenr = -1;
 	} else {
 		hdr.rulenr = htonl(am->nr);
 		hdr.subrulenr = htonl(rm->nr);
diff --git a/freebsd/sys/netpfil/pf/if_pfsync.c b/freebsd/sys/netpfil/pf/if_pfsync.c
index d6a0dfc..d82a6b7 100644
--- a/freebsd/sys/netpfil/pf/if_pfsync.c
+++ b/freebsd/sys/netpfil/pf/if_pfsync.c
@@ -1511,7 +1511,7 @@ pfsync_sendout(int schedswi)
 	struct ip *ip;
 	struct pfsync_header *ph;
 	struct pfsync_subheader *subh;
-	struct pf_state *st;
+	struct pf_state *st, *st_next;
 	struct pfsync_upd_req_item *ur;
 	int offset;
 	int q, count = 0;
@@ -1561,7 +1561,7 @@ pfsync_sendout(int schedswi)
 		offset += sizeof(*subh);
 
 		count = 0;
-		TAILQ_FOREACH(st, &sc->sc_qs[q], sync_list) {
+		TAILQ_FOREACH_SAFE(st, &sc->sc_qs[q], sync_list, st_next) {
 			KASSERT(st->sync_state == q,
 				("%s: st->sync_state == q",
 					__func__));
@@ -1933,6 +1933,8 @@ pfsync_delete_state(struct pf_state *st)
 	if (sc->sc_len == PFSYNC_MINPKT)
 		callout_reset(&sc->sc_tmo, 1 * hz, pfsync_timeout, V_pfsyncif);
 
+	pf_ref_state(st);
+
 	switch (st->sync_state) {
 	case PFSYNC_S_INS:
 		/* We never got to tell the world so just forget about it. */
@@ -1952,6 +1954,9 @@ pfsync_delete_state(struct pf_state *st)
 	default:
 		panic("%s: unexpected sync state %d", __func__, st->sync_state);
 	}
+
+	pf_release_state(st);
+
 	PFSYNC_UNLOCK(sc);
 }
 
diff --git a/freebsd/sys/netpfil/pf/pf.c b/freebsd/sys/netpfil/pf/pf.c
index 7ac181b..5b6be3c 100644
--- a/freebsd/sys/netpfil/pf/pf.c
+++ b/freebsd/sys/netpfil/pf/pf.c
@@ -3644,7 +3644,7 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
 		s->timeout = PFTM_OTHER_FIRST_PACKET;
 	}
 
-	if (r->rt && r->rt != PF_FASTROUTE) {
+	if (r->rt) {
 		if (pf_map_addr(pd->af, r, pd->src, &s->rt_addr, NULL, &sn)) {
 			REASON_SET(&reason, PFRES_MAPFAILED);
 			pf_src_tree_remove_state(s);
@@ -5451,41 +5451,24 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
 	dst.sin_len = sizeof(dst);
 	dst.sin_addr = ip->ip_dst;
 
-	if (r->rt == PF_FASTROUTE) {
-		struct nhop4_basic nh4;
-
-		if (s)
-			PF_STATE_UNLOCK(s);
-
-		if (fib4_lookup_nh_basic(M_GETFIB(m0), ip->ip_dst, 0,
-		    m0->m_pkthdr.flowid, &nh4) != 0) {
-			KMOD_IPSTAT_INC(ips_noroute);
-			error = EHOSTUNREACH;
-			goto bad;
-		}
-
-		ifp = nh4.nh_ifp;
-		dst.sin_addr = nh4.nh_addr;
+	if (TAILQ_EMPTY(&r->rpool.list)) {
+		DPFPRINTF(PF_DEBUG_URGENT,
+		    ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__));
+		goto bad_locked;
+	}
+	if (s == NULL) {
+		pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
+		    &naddr, NULL, &sn);
+		if (!PF_AZERO(&naddr, AF_INET))
+			dst.sin_addr.s_addr = naddr.v4.s_addr;
+		ifp = r->rpool.cur->kif ?
+		    r->rpool.cur->kif->pfik_ifp : NULL;
 	} else {
-		if (TAILQ_EMPTY(&r->rpool.list)) {
-			DPFPRINTF(PF_DEBUG_URGENT,
-			    ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__));
-			goto bad_locked;
-		}
-		if (s == NULL) {
-			pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
-			    &naddr, NULL, &sn);
-			if (!PF_AZERO(&naddr, AF_INET))
-				dst.sin_addr.s_addr = naddr.v4.s_addr;
-			ifp = r->rpool.cur->kif ?
-			    r->rpool.cur->kif->pfik_ifp : NULL;
-		} else {
-			if (!PF_AZERO(&s->rt_addr, AF_INET))
-				dst.sin_addr.s_addr =
-				    s->rt_addr.v4.s_addr;
-			ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
-			PF_STATE_UNLOCK(s);
-		}
+		if (!PF_AZERO(&s->rt_addr, AF_INET))
+			dst.sin_addr.s_addr =
+			    s->rt_addr.v4.s_addr;
+		ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
+		PF_STATE_UNLOCK(s);
 	}
 	if (ifp == NULL)
 		goto bad;
@@ -5627,16 +5610,6 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
 	dst.sin6_len = sizeof(dst);
 	dst.sin6_addr = ip6->ip6_dst;
 
-	/* Cheat. XXX why only in the v6 case??? */
-	if (r->rt == PF_FASTROUTE) {
-		if (s)
-			PF_STATE_UNLOCK(s);
-		m0->m_flags |= M_SKIP_FIREWALL;
-		ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
-		*m = NULL;
-		return;
-	}
-
 	if (TAILQ_EMPTY(&r->rpool.list)) {
 		DPFPRINTF(PF_DEBUG_URGENT,
 		    ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__));
@@ -5932,7 +5905,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
 	pd.sidx = (dir == PF_IN) ? 0 : 1;
 	pd.didx = (dir == PF_IN) ? 1 : 0;
 	pd.af = AF_INET;
-	pd.tos = h->ip_tos;
+	pd.tos = h->ip_tos & ~IPTOS_ECN_MASK;
 	pd.tot_len = ntohs(h->ip_len);
 
 	/* handle fragments that didn't get reassembled by normalization */
diff --git a/freebsd/sys/netpfil/pf/pf_if.c b/freebsd/sys/netpfil/pf/pf_if.c
index d1c54b2..29f8e94 100644
--- a/freebsd/sys/netpfil/pf/pf_if.c
+++ b/freebsd/sys/netpfil/pf/pf_if.c
@@ -525,7 +525,7 @@ pfi_instance_add(struct ifnet *ifp, int net, int flags)
 	int		 net2, af;
 
 	IF_ADDR_RLOCK(ifp);
-	TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_list) {
+	TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
 		if (ia->ifa_addr == NULL)
 			continue;
 		af = ia->ifa_addr->sa_family;
diff --git a/freebsd/sys/netpfil/pf/pf_ioctl.c b/freebsd/sys/netpfil/pf/pf_ioctl.c
index 9c1523c..076ed5f 100644
--- a/freebsd/sys/netpfil/pf/pf_ioctl.c
+++ b/freebsd/sys/netpfil/pf/pf_ioctl.c
@@ -1274,7 +1274,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
 		pf_mv_pool(&V_pf_pabuf, &rule->rpool.list);
 		if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
 		    (rule->action == PF_BINAT)) && rule->anchor == NULL) ||
-		    (rule->rt > PF_FASTROUTE)) &&
+		    (rule->rt > PF_NOPFROUTE)) &&
 		    (TAILQ_FIRST(&rule->rpool.list) == NULL))
 			error = EINVAL;
 
@@ -1539,7 +1539,7 @@ DIOCADDRULE_error:
 			if (((((newrule->action == PF_NAT) ||
 			    (newrule->action == PF_RDR) ||
 			    (newrule->action == PF_BINAT) ||
-			    (newrule->rt > PF_FASTROUTE)) &&
+			    (newrule->rt > PF_NOPFROUTE)) &&
 			    !newrule->anchor)) &&
 			    (TAILQ_FIRST(&newrule->rpool.list) == NULL))
 				error = EINVAL;
diff --git a/freebsd/sys/netpfil/pf/pf_norm.c b/freebsd/sys/netpfil/pf/pf_norm.c
index 86d2c8e..42b44c7 100644
--- a/freebsd/sys/netpfil/pf/pf_norm.c
+++ b/freebsd/sys/netpfil/pf/pf_norm.c
@@ -1813,7 +1813,7 @@ pf_scrub_ip(struct mbuf **m0, u_int32_t flags, u_int8_t min_ttl, u_int8_t tos)
 		u_int16_t	ov, nv;
 
 		ov = *(u_int16_t *)h;
-		h->ip_tos = tos;
+		h->ip_tos = tos | (h->ip_tos & IPTOS_ECN_MASK);
 		nv = *(u_int16_t *)h;
 
 		h->ip_sum = pf_cksum_fixup(h->ip_sum, ov, nv, 0);
diff --git a/freebsd/sys/opencrypto/crypto.c b/freebsd/sys/opencrypto/crypto.c
index 4a01364..2d9787b 100644
--- a/freebsd/sys/opencrypto/crypto.c
+++ b/freebsd/sys/opencrypto/crypto.c
@@ -83,7 +83,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/bus.h>
 #include <rtems/bsd/local/cryptodev_if.h>
 
-#if defined(__i386__) || defined(__amd64__)
+#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
 #include <machine/pcb.h>
 #endif
 
@@ -1254,7 +1254,7 @@ crypto_proc(void)
 	int result, hint;
 
 #ifndef __rtems__
-#if defined(__i386__) || defined(__amd64__)
+#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
 	fpu_kern_thread(FPU_KERN_NORMAL);
 #endif
 #endif /* __rtems__ */
diff --git a/freebsd/sys/powerpc/include/machine/cpufunc.h b/freebsd/sys/powerpc/include/machine/cpufunc.h
index c949d53..378274b 100644
--- a/freebsd/sys/powerpc/include/machine/cpufunc.h
+++ b/freebsd/sys/powerpc/include/machine/cpufunc.h
@@ -82,7 +82,7 @@ static __inline void
 mtsrin(vm_offset_t va, register_t value)
 {
 
-	__asm __volatile ("mtsrin %0,%1" :: "r"(value), "r"(va));
+	__asm __volatile ("mtsrin %0,%1; isync" :: "r"(value), "r"(va));
 }
 
 static __inline register_t
diff --git a/freebsd/sys/powerpc/include/machine/spr.h b/freebsd/sys/powerpc/include/machine/spr.h
index 86dac97..35bd900 100644
--- a/freebsd/sys/powerpc/include/machine/spr.h
+++ b/freebsd/sys/powerpc/include/machine/spr.h
@@ -192,6 +192,7 @@
 #define	  FSL_E5500		  0x8024
 #define	  FSL_E6500		  0x8040
 
+#define	SPR_SPEFSCR		0x200	/* ..8 Signal Processing Engine FSCR. */
 #define	SPR_IBAT0U		0x210	/* .68 Instruction BAT Reg 0 Upper */
 #define	SPR_IBAT0U		0x210	/* .6. Instruction BAT Reg 0 Upper */
 #define	SPR_IBAT0L		0x211	/* .6. Instruction BAT Reg 0 Lower */
@@ -697,8 +698,12 @@
 #define	  SVR_MPC8572E		  0x80e8
 #define	  SVR_P1011		  0x80e5
 #define	  SVR_P1011E		  0x80ed
+#define	  SVR_P1013		  0x80e7
+#define	  SVR_P1013E		  0x80ef
 #define	  SVR_P1020		  0x80e4
 #define	  SVR_P1020E		  0x80ec
+#define	  SVR_P1022		  0x80e6
+#define	  SVR_P1022E		  0x80ee
 #define	  SVR_P2010		  0x80e3
 #define	  SVR_P2010E		  0x80eb
 #define	  SVR_P2020		  0x80e2
diff --git a/freebsd/sys/sys/buf.h b/freebsd/sys/sys/buf.h
index f32c6ca..8688056 100644
--- a/freebsd/sys/sys/buf.h
+++ b/freebsd/sys/sys/buf.h
@@ -68,6 +68,7 @@ extern struct bio_ops {
 } bioops;
 
 struct vm_object;
+struct vm_page;
 
 typedef unsigned char b_xflags_t;
 
@@ -139,6 +140,15 @@ struct buf {
 	void	*b_fsprivate1;
 	void	*b_fsprivate2;
 	void	*b_fsprivate3;
+
+#if defined(FULL_BUF_TRACKING)
+#define BUF_TRACKING_SIZE	32
+#define BUF_TRACKING_ENTRY(x)	((x) & (BUF_TRACKING_SIZE - 1))
+	const char	*b_io_tracking[BUF_TRACKING_SIZE];
+	uint32_t	b_io_tcnt;
+#elif defined(BUF_TRACKING)
+	const char	*b_io_tracking;
+#endif
 };
 
 #define b_object	b_bufobj->bo_object
@@ -428,6 +438,17 @@ buf_countdeps(struct buf *bp, int i)
 		return (0);
 }
 
+static __inline void
+buf_track(struct buf *bp, const char *location)
+{
+
+#if defined(FULL_BUF_TRACKING)
+	bp->b_io_tracking[BUF_TRACKING_ENTRY(bp->b_io_tcnt++)] = location;
+#elif defined(BUF_TRACKING)
+	bp->b_io_tracking = location;
+#endif
+}
+
 #endif /* _KERNEL */
 
 /*
@@ -517,9 +538,11 @@ int	cluster_read(struct vnode *, u_quad_t, daddr_t, long,
 	    struct ucred *, long, int, int, struct buf **);
 int	cluster_wbuild(struct vnode *, long, daddr_t, int, int);
 void	cluster_write(struct vnode *, struct buf *, u_quad_t, int, int);
+void	vfs_bio_brelse(struct buf *bp, int ioflags);
 void	vfs_bio_bzero_buf(struct buf *bp, int base, int size);
-void	vfs_bio_set_valid(struct buf *, int base, int size);
 void	vfs_bio_clrbuf(struct buf *);
+void	vfs_bio_set_flags(struct buf *bp, int ioflags);
+void	vfs_bio_set_valid(struct buf *, int base, int size);
 void	vfs_busy_pages(struct buf *, int clear_modify);
 void	vfs_unbusy_pages(struct buf *);
 int	vmapbuf(struct buf *, int);
@@ -537,6 +560,12 @@ struct	buf *trypbuf(int *);
 void	bwait(struct buf *, u_char, const char *);
 void	bdone(struct buf *);
 
+typedef daddr_t (vbg_get_lblkno_t)(struct vnode *, vm_ooffset_t);
+typedef int (vbg_get_blksize_t)(struct vnode *, daddr_t);
+int	vfs_bio_getpages(struct vnode *vp, struct vm_page **ma, int count,
+	    int *rbehind, int *rahead, vbg_get_lblkno_t get_lblkno,
+	    vbg_get_blksize_t get_blksize);
+
 #endif /* _KERNEL */
 
 #endif /* !_SYS_BUF_H_ */
diff --git a/freebsd/sys/sys/bufobj.h b/freebsd/sys/sys/bufobj.h
index 0fa6c8c..657702c 100644
--- a/freebsd/sys/sys/bufobj.h
+++ b/freebsd/sys/sys/bufobj.h
@@ -94,11 +94,6 @@ struct bufobj {
 	struct vm_object *bo_object;	/* v Place to store VM object */
 	LIST_ENTRY(bufobj) bo_synclist;	/* S dirty vnode list */
 	void		*bo_private;	/* private pointer */
-	struct vnode	*__bo_vnode;	/*
-					 * XXX: This vnode pointer is here
-					 * XXX: only to keep the syncer working
-					 * XXX: for now.
-					 */
 	struct bufv	bo_clean;	/* i Clean buffers */
 	struct bufv	bo_dirty;	/* i Dirty buffers */
 	long		bo_numoutput;	/* i Writes in progress */
diff --git a/freebsd/sys/sys/bus.h b/freebsd/sys/sys/bus.h
index 6e356e9..e62c9ba 100644
--- a/freebsd/sys/sys/bus.h
+++ b/freebsd/sys/sys/bus.h
@@ -117,6 +117,7 @@ struct devreq {
 #define	DEV_SUSPEND	_IOW('D', 5, struct devreq)
 #define	DEV_RESUME	_IOW('D', 6, struct devreq)
 #define	DEV_SET_DRIVER	_IOW('D', 7, struct devreq)
+#define	DEV_CLEAR_DRIVER _IOW('D', 8, struct devreq)
 #define	DEV_RESCAN	_IOW('D', 9, struct devreq)
 #define	DEV_DELETE	_IOW('D', 10, struct devreq)
 
@@ -126,6 +127,9 @@ struct devreq {
 /* Flags for DEV_SET_DRIVER. */
 #define	DEVF_SET_DRIVER_DETACH	0x0000001	/* Detach existing driver. */
 
+/* Flags for DEV_CLEAR_DRIVER. */
+#define	DEVF_CLEAR_DRIVER_DETACH 0x0000001	/* Detach existing driver. */
+
 /* Flags for DEV_DELETE. */
 #define	DEVF_FORCE_DELETE	0x0000001
 
diff --git a/freebsd/sys/sys/capsicum.h b/freebsd/sys/sys/capsicum.h
index af4da03..a5e6492 100644
--- a/freebsd/sys/sys/capsicum.h
+++ b/freebsd/sys/sys/capsicum.h
@@ -374,6 +374,8 @@ int	cap_ioctl_check(struct filedesc *fdp, int fd, u_long cmd);
 int	cap_fcntl_check_fde(struct filedescent *fde, int cmd);
 int	cap_fcntl_check(struct filedesc *fdp, int fd, int cmd);
 
+extern int trap_enotcap;
+
 #else /* !_KERNEL */
 
 __BEGIN_DECLS
diff --git a/freebsd/sys/sys/eventhandler.h b/freebsd/sys/sys/eventhandler.h
index 9315f8c..845b28c 100644
--- a/freebsd/sys/sys/eventhandler.h
+++ b/freebsd/sys/sys/eventhandler.h
@@ -270,4 +270,11 @@ typedef void (*unregister_framebuffer_fn)(void *, struct fb_info *);
 EVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn);
 EVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn);
 
+/* Veto ada attachment */
+struct cam_path;
+struct ata_params;
+typedef void (*ada_probe_veto_fn)(void *, struct cam_path *,
+    struct ata_params *, int *);
+EVENTHANDLER_DECLARE(ada_probe_veto, ada_probe_veto_fn);
+
 #endif /* _SYS_EVENTHANDLER_H_ */
diff --git a/freebsd/sys/sys/filedesc.h b/freebsd/sys/sys/filedesc.h
index 30c2dee..1e99bfa 100644
--- a/freebsd/sys/sys/filedesc.h
+++ b/freebsd/sys/sys/filedesc.h
@@ -175,7 +175,11 @@ void	filecaps_init(struct filecaps *fcaps);
 int	filecaps_copy(const struct filecaps *src, struct filecaps *dst,
 	    bool locked);
 void	filecaps_move(struct filecaps *src, struct filecaps *dst);
+#ifndef __rtems__
 void	filecaps_free(struct filecaps *fcaps);
+#else /* __rtems__ */
+#define	filecaps_free(fcaps) do { } while (0)
+#endif /* __rtems__ */
 
 int	closef(struct file *fp, struct thread *td);
 int	dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode,
@@ -245,6 +249,11 @@ int	getvnode(struct thread *td, int fd, cap_rights_t *rightsp,
 	    struct file **fpp);
 void	mountcheckdirs(struct vnode *olddp, struct vnode *newdp);
 
+int	fget_cap_locked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
+	    struct file **fpp, struct filecaps *havecapsp);
+int	fget_cap(struct thread *td, int fd, cap_rights_t *needrightsp,
+	    struct file **fpp, struct filecaps *havecapsp);
+
 /* Return a referenced file from an unlocked descriptor. */
 #ifndef __rtems__
 int	fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
@@ -282,12 +291,31 @@ fget_locked(struct filedesc *fdp, int fd)
 	return (fdp->fd_ofiles[fd].fde_file);
 }
 
+static __inline struct filedescent *
+fdeget_locked(struct filedesc *fdp, int fd)
+{
+	struct filedescent *fde;
+
+	FILEDESC_LOCK_ASSERT(fdp);
+
+	if (fd < 0 || fd > fdp->fd_lastfile)
+		return (NULL);
+
+	fde = &fdp->fd_ofiles[fd];
+	if (fde->fde_file == NULL)
+		return (NULL);
+
+	return (fde);
+}
+
+#ifdef CAPABILITIES
 static __inline bool
 fd_modified(struct filedesc *fdp, int fd, seq_t seq)
 {
 
 	return (!seq_consistent(fd_seq(fdp->fd_files, fd), seq));
 }
+#endif
 #endif /* __rtems__ */
 
 /* cdir/rdir/jdir manipulation functions. */
diff --git a/freebsd/sys/sys/linker.h b/freebsd/sys/sys/linker.h
index 90db1b8..eecb4cd 100644
--- a/freebsd/sys/sys/linker.h
+++ b/freebsd/sys/sys/linker.h
@@ -73,6 +73,7 @@ struct linker_file {
     int			userrefs;	/* kldload(2) count */
     int			flags;
 #define LINKER_FILE_LINKED	0x1	/* file has been fully linked */
+#define LINKER_FILE_MODULES	0x2	/* file has >0 modules at preload */
     TAILQ_ENTRY(linker_file) link;	/* list of all loaded files */
     char*		filename;	/* file which was loaded */
     char*		pathname;	/* file name with full path */
diff --git a/freebsd/sys/sys/mbuf.h b/freebsd/sys/sys/mbuf.h
index 95194e0..9ce52a1 100644
--- a/freebsd/sys/sys/mbuf.h
+++ b/freebsd/sys/sys/mbuf.h
@@ -174,6 +174,7 @@ struct pkthdr {
 #define	PH_vt		PH_per
 #define	vt_nrecs	sixteen[0]
 #define	tso_segsz	PH_per.sixteen[1]
+#define	lro_nsegs	tso_segsz
 #define	csum_phsum	PH_per.sixteen[2]
 #define	csum_data	PH_per.thirtytwo[1]
 
@@ -334,7 +335,7 @@ struct mbuf {
 #define	M_HASHTYPE_RSS_TCP_IPV6		M_HASHTYPE_HASH(4) /* TCPv6 4-tuple */
 #define	M_HASHTYPE_RSS_IPV6_EX		M_HASHTYPE_HASH(5) /* IPv6 2-tuple +
 							    * ext hdrs */
-#define	M_HASHTYPE_RSS_TCP_IPV6_EX	M_HASHTYPE_HASH(6) /* TCPv6 4-tiple +
+#define	M_HASHTYPE_RSS_TCP_IPV6_EX	M_HASHTYPE_HASH(6) /* TCPv6 4-tuple +
 							    * ext hdrs */
 /* Non-standard RSS hash types */
 #define	M_HASHTYPE_RSS_UDP_IPV4		M_HASHTYPE_HASH(7) /* IPv4 UDP 4-tuple*/
@@ -392,7 +393,7 @@ struct mbuf {
 #define	EXT_JUMBO9	4	/* jumbo cluster 9216 bytes */
 #define	EXT_JUMBO16	5	/* jumbo cluster 16184 bytes */
 #define	EXT_PACKET	6	/* mbuf+cluster from packet zone */
-#define	EXT_MBUF	7	/* external mbuf reference (M_IOVEC) */
+#define	EXT_MBUF	7	/* external mbuf reference */
 #ifndef __rtems__
 #define	EXT_SFBUF_NOCACHE 8	/* sendfile(2)'s sf_buf not to be cached */
 #endif /* __rtems__ */
@@ -983,9 +984,6 @@ m_align(struct mbuf *m, int len)
 /* Length to m_copy to copy all. */
 #define	M_COPYALL	1000000000
 
-/* Compatibility with 4.3. */
-#define	m_copy(m, o, l)	m_copym((m), (o), (l), M_NOWAIT)
-
 extern int		max_datalen;	/* MHLEN - max_hdr */
 extern int		max_hdr;	/* Largest link + protocol header */
 extern int		max_linkhdr;	/* Largest link-level header */
diff --git a/freebsd/sys/sys/module.h b/freebsd/sys/sys/module.h
index 07464fc..71aa995 100644
--- a/freebsd/sys/sys/module.h
+++ b/freebsd/sys/sys/module.h
@@ -233,7 +233,7 @@ extern int mod_debug;
 
 #define	MOD_DPF(cat, args) do {						\
 	if (mod_debug & MOD_DEBUG_##cat)				\
-		printf(args);						\
+		printf args;						\
 } while (0)
 
 #else	/* !MOD_DEBUG */
diff --git a/freebsd/sys/sys/mount.h b/freebsd/sys/sys/mount.h
index 49e688f..1bf583a 100644
--- a/freebsd/sys/sys/mount.h
+++ b/freebsd/sys/sys/mount.h
@@ -147,6 +147,7 @@ struct vfsopt {
  * put on a doubly linked list.
  *
  * Lock reference:
+ * 	l - mnt_listmtx
  *	m - mountlist_mtx
  *	i - interlock
  *	v - vnode freelist mutex
@@ -166,8 +167,6 @@ struct mount {
 	int		mnt_ref;		/* (i) Reference count */
 	struct vnodelst	mnt_nvnodelist;		/* (i) list of vnodes */
 	int		mnt_nvnodelistsize;	/* (i) # of vnodes */
-	struct vnodelst	mnt_activevnodelist;	/* (v) list of active vnodes */
-	int		mnt_activevnodelistsize;/* (v) # of active vnodes */
 	int		mnt_writeopcount;	/* (i) write syscalls pending */
 	int		mnt_kern_flag;		/* (i) kernel only flags */
 	uint64_t	mnt_flag;		/* (i) flags shared with user */
@@ -188,6 +187,11 @@ struct mount {
 	struct thread	*mnt_susp_owner;	/* (i) thread owning suspension */
 #define	mnt_endzero	mnt_gjprovider
 	char		*mnt_gjprovider;	/* gjournal provider name */
+	struct mtx	mnt_listmtx;
+	struct vnodelst	mnt_activevnodelist;	/* (l) list of active vnodes */
+	int		mnt_activevnodelistsize;/* (l) # of active vnodes */
+	struct vnodelst	mnt_tmpfreevnodelist;	/* (l) list of free vnodes */
+	int		mnt_tmpfreevnodelistsize;/* (l) # of free vnodes */
 	struct lock	mnt_explock;		/* vfs_export walkers lock */
 	TAILQ_ENTRY(mount) mnt_upper_link;	/* (m) we in the all uppers */
 	TAILQ_HEAD(, mount) mnt_uppers;		/* (m) upper mounts over us*/
@@ -366,7 +370,8 @@ void          __mnt_vnode_markerfree_active(struct vnode **mvp, struct mount *);
 #define	MNTK_SUSPEND	0x08000000	/* request write suspension */
 #define	MNTK_SUSPEND2	0x04000000	/* block secondary writes */
 #define	MNTK_SUSPENDED	0x10000000	/* write operations are suspended */
-#define	MNTK_UNUSED1	0x20000000
+#define	MNTK_NULL_NOCACHE	0x20000000 /* auto disable cache for nullfs
+					      mounts over this fs */
 #define MNTK_LOOKUP_SHARED	0x40000000 /* FS supports shared lock lookups */
 #define	MNTK_NOKNOTE	0x80000000	/* Don't send KNOTEs from VOP hooks */
 
diff --git a/freebsd/sys/sys/proc.h b/freebsd/sys/sys/proc.h
index 4a695ef..03aae8f 100644
--- a/freebsd/sys/sys/proc.h
+++ b/freebsd/sys/sys/proc.h
@@ -761,6 +761,7 @@ struct proc {
 #define	P2_NOTRACE_EXEC 0x00000004	/* Keep P2_NOPTRACE on exec(2). */
 #define	P2_AST_SU	0x00000008	/* Handles SU ast for kthreads. */
 #define	P2_PTRACE_FSTP	0x00000010 /* SIGSTOP from PT_ATTACH not yet handled. */
+#define	P2_TRAPCAP	0x00000020	/* SIGTRAP on ENOTCAPABLE */
 
 /* Flags protected by proctree_lock, kept in p_treeflags. */
 #define	P_TREE_ORPHANED		0x00000001	/* Reparented, on orphan list */
diff --git a/freebsd/sys/sys/sf_buf.h b/freebsd/sys/sys/sf_buf.h
index b5970d9..6aebe43 100644
--- a/freebsd/sys/sys/sf_buf.h
+++ b/freebsd/sys/sys/sf_buf.h
@@ -41,6 +41,7 @@ struct sfstat {				/* sendfile statistics */
 	uint64_t	sf_busy;	/* times aborted on a busy page */
 	uint64_t	sf_allocfail;	/* times sfbuf allocation failed */
 	uint64_t	sf_allocwait;	/* times sfbuf allocation had to wait */
+	uint64_t	sf_pages_bogus;	/* times bogus page was used */
 };
 
 #ifdef _KERNEL
diff --git a/freebsd/sys/sys/socket.h b/freebsd/sys/sys/socket.h
index f23b5f6..ea3d9b6 100644
--- a/freebsd/sys/sys/socket.h
+++ b/freebsd/sys/sys/socket.h
@@ -590,6 +590,7 @@ struct sf_hdtr {
 #define	SF_NODISKIO     0x00000001
 #define	SF_MNOWAIT	0x00000002	/* obsolete */
 #define	SF_SYNC		0x00000004
+#define	SF_USER_READAHEAD	0x00000008
 #define	SF_NOCACHE	0x00000010
 #define	SF_FLAGS(rh, flags)	(((rh) << 16) | (flags))
 
diff --git a/freebsd/sys/sys/socketvar.h b/freebsd/sys/sys/socketvar.h
index 72eaa99..1e599a6 100644
--- a/freebsd/sys/sys/socketvar.h
+++ b/freebsd/sys/sys/socketvar.h
@@ -321,6 +321,7 @@ extern u_long	sb_max;
 extern so_gen_t so_gencnt;
 
 struct file;
+struct filecaps;
 struct filedesc;
 struct mbuf;
 struct sockaddr;
@@ -340,7 +341,7 @@ struct uio;
  */
 int	getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len);
 int	getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
-	    struct file **fpp, u_int *fflagp);
+	    struct file **fpp, u_int *fflagp, struct filecaps *havecaps);
 void	soabort(struct socket *so);
 int	soaccept(struct socket *so, struct sockaddr **nam);
 void	soaio_enqueue(struct task *task);
diff --git a/freebsd/sys/sys/sysctl.h b/freebsd/sys/sys/sysctl.h
index 687fb23..291b7e4 100644
--- a/freebsd/sys/sys/sysctl.h
+++ b/freebsd/sys/sys/sysctl.h
@@ -876,6 +876,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
 #define	KERN_IOV_MAX		35	/* int: value of UIO_MAXIOV */
 #define	KERN_HOSTUUID		36	/* string: host UUID identifier */
 #define	KERN_ARND		37	/* int: from arc4rand() */
+#define	KERN_MAXPHYS		38	/* int: MAXPHYS value */
 /*
  * KERN_PROC subtypes
  */
diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h
index 1ee7bb4..b3c944b 100644
--- a/freebsd/sys/sys/sysproto.h
+++ b/freebsd/sys/sys/sysproto.h
@@ -3,7 +3,7 @@
  *
  * DO NOT EDIT-- this file is automatically generated.
  * $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 304395 2016-08-18 10:50:40Z gnn 
+ * created from FreeBSD: head/sys/kern/syscalls.master 309677 2016-12-07 16:11:55Z rwatson
  */
 
 #ifndef _SYS_SYSPROTO_H_
diff --git a/freebsd/sys/sys/user.h b/freebsd/sys/sys/user.h
index d0da045..9dad4d0 100644
--- a/freebsd/sys/sys/user.h
+++ b/freebsd/sys/sys/user.h
@@ -180,12 +180,13 @@ struct kinfo_proc {
 	char	ki_comm[COMMLEN+1];	/* command name */
 	char	ki_emul[KI_EMULNAMELEN+1];  /* emulation name */
 	char	ki_loginclass[LOGINCLASSLEN+1]; /* login class */
+	char	ki_moretdname[MAXCOMLEN-TDNAMLEN+1];	/* more thread name */
 	/*
 	 * When adding new variables, take space for char-strings from the
 	 * front of ki_sparestrings, and ints from the end of ki_spareints.
 	 * That way the spare room from both arrays will remain contiguous.
 	 */
-	char	ki_sparestrings[50];	/* spare string space */
+	char	ki_sparestrings[46];	/* spare string space */
 	int	ki_spareints[KI_NSPARE_INT];	/* spare room for growth */
 	int	ki_oncpu;		/* Which cpu we are on */
 	int	ki_lastcpu;		/* Last cpu we were on */
diff --git a/freebsd/sys/sys/vmmeter.h b/freebsd/sys/sys/vmmeter.h
index 39f03d0..31312b0 100644
--- a/freebsd/sys/sys/vmmeter.h
+++ b/freebsd/sys/sys/vmmeter.h
@@ -75,11 +75,11 @@ struct vmmeter {
 	u_int v_vnodepgsin;	/* (p) vnode_pager pages paged in */
 	u_int v_vnodepgsout;	/* (p) vnode pager pages paged out */
 	u_int v_intrans;	/* (p) intransit blocking page faults */
-	u_int v_reactivated;	/* (f) pages reactivated from free list */
+	u_int v_reactivated;	/* (p) pages reactivated by the pagedaemon */
 	u_int v_pdwakeups;	/* (p) times daemon has awaken from sleep */
 	u_int v_pdpages;	/* (p) pages analyzed by daemon */
+	u_int v_pdshortfalls;	/* (p) page reclamation shortfalls */
 
-	u_int v_tcached;	/* (p) total pages cached */
 	u_int v_dfree;		/* (p) pages freed by daemon */
 	u_int v_pfree;		/* (p) pages freed by exiting processes */
 	u_int v_tfree;		/* (p) total pages freed */
@@ -96,7 +96,7 @@ struct vmmeter {
 	u_int v_active_count;	/* (q) pages active */
 	u_int v_inactive_target; /* (c) pages desired inactive */
 	u_int v_inactive_count;	/* (q) pages inactive */
-	u_int v_cache_count;	/* (f) pages on cache queue */
+	u_int v_laundry_count;	/* (q) pages eligible for laundering */
 	u_int v_pageout_free_min;   /* (c) min pages reserved for kernel */
 	u_int v_interrupt_free_min; /* (c) reserved pages for int code */
 	u_int v_free_severe;	/* (c) severe page depletion point */
@@ -111,7 +111,6 @@ struct vmmeter {
 	u_int v_vforkpages;	/* (p) VM pages affected by vfork() */
 	u_int v_rforkpages;	/* (p) VM pages affected by rfork() */
 	u_int v_kthreadpages;	/* (p) VM pages affected by fork() by kernel */
-	u_int v_spare[2];
 };
 #ifdef _KERNEL
 
@@ -129,8 +128,7 @@ static inline int
 vm_page_count_severe(void)
 {
 
-	return (vm_cnt.v_free_severe > vm_cnt.v_free_count +
-	    vm_cnt.v_cache_count);
+	return (vm_cnt.v_free_severe > vm_cnt.v_free_count);
 }
 
 /*
@@ -146,7 +144,7 @@ static inline int
 vm_page_count_min(void)
 {
 
-	return (vm_cnt.v_free_min > vm_cnt.v_free_count + vm_cnt.v_cache_count);
+	return (vm_cnt.v_free_min > vm_cnt.v_free_count);
 }
 
 /*
@@ -157,8 +155,7 @@ static inline int
 vm_page_count_target(void)
 {
 
-	return (vm_cnt.v_free_target > vm_cnt.v_free_count +
-	    vm_cnt.v_cache_count);
+	return (vm_cnt.v_free_target > vm_cnt.v_free_count);
 }
 
 /*
@@ -169,8 +166,7 @@ static inline int
 vm_paging_target(void)
 {
 
-	return (vm_cnt.v_free_target - (vm_cnt.v_free_count +
-	    vm_cnt.v_cache_count));
+	return (vm_cnt.v_free_target - vm_cnt.v_free_count);
 }
 
 /*
@@ -180,10 +176,28 @@ static inline int
 vm_paging_needed(void)
 {
 
-	return (vm_cnt.v_free_count + vm_cnt.v_cache_count <
-	    vm_pageout_wakeup_thresh);
+	return (vm_cnt.v_free_count < vm_pageout_wakeup_thresh);
 }
 
+/*
+ * Return the number of pages we need to launder.
+ * A positive number indicates that we have a shortfall of clean pages.
+ */
+static inline int
+vm_laundry_target(void)
+{
+
+	return (vm_paging_target());
+}
+
+/*
+ * Obtain the value of a per-CPU counter.
+ */
+#define	VM_METER_PCPU_CNT(member)					\
+	vm_meter_cnt(__offsetof(struct vmmeter, member))
+
+u_int	vm_meter_cnt(size_t);
+
 #endif
 
 /* systemwide totals computed every five seconds */
diff --git a/freebsd/sys/sys/vnode.h b/freebsd/sys/sys/vnode.h
index a047bc6..5400fe1 100644
--- a/freebsd/sys/sys/vnode.h
+++ b/freebsd/sys/sys/vnode.h
@@ -76,8 +76,8 @@ struct vpollinfo {
  *
  * Lock reference:
  *	c - namecache mutex
- *	f - freelist mutex
  *	i - interlock
+ *	l - mp mnt_listmtx or freelist mutex
  *	I - updated with atomics, 0->1 and 1->0 transitions with interlock held
  *	m - mount point interlock
  *	p - pollinfo lock
@@ -145,7 +145,7 @@ struct vnode {
 	/*
 	 * The machinery of being a vnode
 	 */
-	TAILQ_ENTRY(vnode) v_actfreelist;	/* f vnode active/free lists */
+	TAILQ_ENTRY(vnode) v_actfreelist;	/* l vnode active/free lists */
 	struct bufobj	v_bufobj;		/* * Buffer cache object */
 
 	/*
@@ -168,6 +168,7 @@ struct vnode {
 	u_int	v_usecount;			/* I ref count of users */
 	u_int	v_iflag;			/* i vnode flags (see below) */
 	u_int	v_vflag;			/* v vnode flags */
+	u_int	v_mflag;			/* l mnt-specific vnode flags */
 	int	v_writecount;			/* v ref count of writers */
 	u_int	v_hash;
 	enum	vtype v_type;			/* u vnode type */
@@ -180,6 +181,8 @@ struct vnode {
 #define	v_rdev		v_un.vu_cdev
 #define	v_fifoinfo	v_un.vu_fifoinfo
 
+#define	bo2vnode(bo)	__containerof((bo), struct vnode, v_bufobj)
+
 /* XXX: These are temporary to avoid a source sweep at this time */
 #define v_object	v_bufobj.bo_object
 
@@ -255,6 +258,8 @@ struct xvnode {
 #define	VV_MD		0x0800	/* vnode backs the md device */
 #define	VV_FORCEINSMQ	0x1000	/* force the insmntque to succeed */
 
+#define	VMP_TMPMNTFREELIST	0x0001	/* Vnode is on mnt's tmp free list */
+
 /*
  * Vnode attributes.  A field value of VNOVAL represents a field whose value
  * is unavailable (getattr) or which is not to be changed (setattr).
@@ -303,6 +308,7 @@ struct vattr {
 #define	IO_INVAL	0x0040		/* invalidate after I/O */
 #define	IO_SYNC		0x0080		/* do I/O synchronously */
 #define	IO_DIRECT	0x0100		/* attempt to bypass buffer cache */
+#define	IO_NOREUSE	0x0200		/* VMIO data won't be reused */
 #define	IO_EXT		0x0400		/* operate on external attributes */
 #define	IO_NORMAL	0x0800		/* operate on regular data */
 #define	IO_NOMACCHECK	0x1000		/* MAC checks unnecessary */
@@ -604,7 +610,7 @@ int	cache_lookup(struct vnode *dvp, struct vnode **vpp,
 	    struct componentname *cnp, struct timespec *tsp, int *ticksp);
 void	cache_purge(struct vnode *vp);
 void	cache_purge_negative(struct vnode *vp);
-void	cache_purgevfs(struct mount *mp);
+void	cache_purgevfs(struct mount *mp, bool force);
 int	change_dir(struct vnode *vp, struct thread *td);
 void	cvtstat(struct stat *st, struct ostat *ost);
 void	cvtnstat(struct stat *sb, struct nstat *nsb);
@@ -655,6 +661,7 @@ int	vtruncbuf(struct vnode *vp, struct ucred *cred, off_t length,
 void	vunref(struct vnode *);
 void	vn_printf(struct vnode *vp, const char *fmt, ...) __printflike(2,3);
 int	vrecycle(struct vnode *vp);
+int	vrecyclel(struct vnode *vp);
 int	vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off,
 	    struct ucred *cred);
 int	vn_close(struct vnode *vp,
diff --git a/freebsd/sys/vm/uma_core.c b/freebsd/sys/vm/uma_core.c
index 3957a22..00ac3e5 100644
--- a/freebsd/sys/vm/uma_core.c
+++ b/freebsd/sys/vm/uma_core.c
@@ -880,8 +880,7 @@ static void
 keg_drain(uma_keg_t keg)
 {
 	struct slabhead freeslabs = { 0 };
-	uma_slab_t slab;
-	uma_slab_t n;
+	uma_slab_t slab, tmp;
 
 	/*
 	 * We don't want to take pages from statically allocated kegs at this
@@ -897,16 +896,11 @@ keg_drain(uma_keg_t keg)
 	if (keg->uk_free == 0)
 		goto finished;
 
-	slab = LIST_FIRST(&keg->uk_free_slab);
-	while (slab) {
-		n = LIST_NEXT(slab, us_link);
-
+	LIST_FOREACH_SAFE(slab, &keg->uk_free_slab, us_link, tmp) {
 #ifndef __rtems__
-		/* We have no where to free these to */
-		if (slab->us_flags & UMA_SLAB_BOOT) {
-			slab = n;
+		/* We have nowhere to free these to. */
+		if (slab->us_flags & UMA_SLAB_BOOT)
 			continue;
-		}
 #endif /* __rtems__ */
 
 		LIST_REMOVE(slab, us_link);
@@ -917,8 +911,6 @@ keg_drain(uma_keg_t keg)
 			UMA_HASH_REMOVE(&keg->uk_hash, slab, slab->us_data);
 
 		SLIST_INSERT_HEAD(&freeslabs, slab, us_hlink);
-
-		slab = n;
 	}
 finished:
 	KEG_UNLOCK(keg);
diff --git a/freebsd/usr.bin/netstat/mbuf.c b/freebsd/usr.bin/netstat/mbuf.c
index 81f5729..446592a 100644
--- a/freebsd/usr.bin/netstat/mbuf.c
+++ b/freebsd/usr.bin/netstat/mbuf.c
@@ -361,6 +361,9 @@ mbpr(void *kvmd, u_long mbaddr)
         xo_emit("{:sendfile-pages-valid/%ju} "
 	    "{N:pages were valid at time of a sendfile request}\n",
             (uintmax_t)sfstat.sf_pages_valid);
+        xo_emit("{:sendfile-pages-bogus/%ju} "
+	    "{N:pages were valid and substituted to bogus page}\n",
+            (uintmax_t)sfstat.sf_pages_bogus);
         xo_emit("{:sendfile-requested-readahead/%ju} "
 	    "{N:pages were requested for read ahead by applications}\n",
             (uintmax_t)sfstat.sf_rhpages_requested);
diff --git a/freebsd/usr.bin/netstat/route.c b/freebsd/usr.bin/netstat/route.c
index bed58b0..da79982 100644
--- a/freebsd/usr.bin/netstat/route.c
+++ b/freebsd/usr.bin/netstat/route.c
@@ -125,7 +125,9 @@ static int ifmap_size;
 static struct timespec uptime;
 
 static const char *netname4(in_addr_t, in_addr_t);
+#ifdef INET6
 static const char *netname6(struct sockaddr_in6 *, struct sockaddr_in6 *);
+#endif
 static void p_rtable_sysctl(int, int);
 static void p_rtentry_sysctl(const char *name, struct rt_msghdr *);
 static int p_sockaddr(const char *name, struct sockaddr *, struct sockaddr *,
diff --git a/freebsd/usr.bin/vmstat/vmstat.c b/freebsd/usr.bin/vmstat/vmstat.c
index ed14656..8f9daa9 100644
--- a/freebsd/usr.bin/vmstat/vmstat.c
+++ b/freebsd/usr.bin/vmstat/vmstat.c
@@ -623,7 +623,7 @@ fill_vmmeter(struct vmmeter *vmmp)
 		GET_VM_STATS(vm, v_reactivated);
 		GET_VM_STATS(vm, v_pdwakeups);
 		GET_VM_STATS(vm, v_pdpages);
-		GET_VM_STATS(vm, v_tcached);
+		GET_VM_STATS(vm, v_pdshortfalls);
 		GET_VM_STATS(vm, v_dfree);
 		GET_VM_STATS(vm, v_pfree);
 		GET_VM_STATS(vm, v_tfree);
@@ -637,7 +637,7 @@ fill_vmmeter(struct vmmeter *vmmp)
 		GET_VM_STATS(vm, v_active_count);
 		GET_VM_STATS(vm, v_inactive_target);
 		GET_VM_STATS(vm, v_inactive_count);
-		GET_VM_STATS(vm, v_cache_count);
+		GET_VM_STATS(vm, v_laundry_count);
 		GET_VM_STATS(vm, v_pageout_free_min);
 		GET_VM_STATS(vm, v_interrupt_free_min);
 		/*GET_VM_STATS(vm, v_free_severe);*/
@@ -1115,7 +1115,9 @@ dosum(void)
 		sum.v_pdwakeups);
 	xo_emit("{:page-daemon-pages/%9u} {N:pages examined by the page daemon}\n",
 		sum.v_pdpages);
-	xo_emit("{:reactivated/%9u} {N:pages reactivated}\n",
+	xo_emit("{:page-reclamation-shortfalls/%9u} {N:clean page reclamation shortfalls}\n",
+		sum.v_pdshortfalls);
+	xo_emit("{:reactivated/%9u} {N:pages reactivated by the page daemon}\n",
 		sum.v_reactivated);
 	xo_emit("{:copy-on-write-faults/%9u} {N:copy-on-write faults}\n",
 		sum.v_cow_faults);
@@ -1139,8 +1141,6 @@ dosum(void)
 		sum.v_vforkpages);
 	xo_emit("{:pages-rfork/%9u} {N:pages affected by rfork}()\n",
 		sum.v_rforkpages);
-	xo_emit("{:pages-total-cached/%9u} {N:pages cached}\n",
-		sum.v_tcached);
 	xo_emit("{:pages-freed/%9u} {N:pages freed}\n",
 		sum.v_tfree);
 	xo_emit("{:pages-freed-by-daemon/%9u} {N:pages freed by daemon}\n",
@@ -1151,8 +1151,8 @@ dosum(void)
 		sum.v_active_count);
 	xo_emit("{:inactive-pages/%9u} {N:pages inactive}\n",
 		sum.v_inactive_count);
-	xo_emit("{:vm-cache/%9u} {N:pages in VM cache}\n",
-		sum.v_cache_count);
+	xo_emit("{:laundry-pages/%9u} {N:pages in the laundry queue}\n",
+		sum.v_laundry_count);
 	xo_emit("{:wired-pages/%9u} {N:pages wired down}\n",
 		sum.v_wire_count);
 	xo_emit("{:free-pages/%9u} {N:pages free}\n",
diff --git a/libbsd.txt b/libbsd.txt
index 2d0a012..12a2880 100644
--- a/libbsd.txt
+++ b/libbsd.txt
@@ -776,7 +776,7 @@ detail and debug level information from the command.
 
 == FreeBSD version of imported files and directories
 
-. *, trunk, 2016-08-23, 9fe7c416e6abb28b1398fd3e5687099846800cfd
+. *, trunk, 2016-12-10, 80c55f08a05ab3b26a73b226ccb56adc3122a55c.
 
 == How to import code from FreeBSD
 
diff --git a/rtemsbsd/include/machine/rtems-bsd-kernel-space.h b/rtemsbsd/include/machine/rtems-bsd-kernel-space.h
index 49dc3aa..10ce9d2 100644
--- a/rtemsbsd/include/machine/rtems-bsd-kernel-space.h
+++ b/rtemsbsd/include/machine/rtems-bsd-kernel-space.h
@@ -80,4 +80,6 @@ void rtems_bsd_assert_func(const char *file, int line, const char *func, const c
 
 #define BSD_DEFAULT_PRISON (&prison0)
 
+#define kdb_active 0
+
 #endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_KERNEL_SPACE_H_ */
diff --git a/rtemsbsd/include/rtems/bsd/sys/param.h b/rtemsbsd/include/rtems/bsd/sys/param.h
index a21e94a..fb9b80c 100644
--- a/rtemsbsd/include/rtems/bsd/sys/param.h
+++ b/rtemsbsd/include/rtems/bsd/sys/param.h
@@ -62,7 +62,7 @@
  *		in the range 5 to 9.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1200003	/* Master, propagated to newvers */
+#define __FreeBSD_version 1200018	/* Master, propagated to newvers */
 
 #ifdef _KERNEL
 #define	P_OSREL_SIGWAIT			700000




More information about the vc mailing list