summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
m---------freebsd-org0
-rw-r--r--freebsd/bin/hostname/hostname.c22
-rw-r--r--freebsd/contrib/tcpdump/tcpdump.c47
-rw-r--r--freebsd/lib/libc/db/btree/bt_close.c3
-rw-r--r--freebsd/lib/libc/include/libc_private.h1
-rw-r--r--freebsd/lib/libc/net/getaddrinfo.c21
-rw-r--r--freebsd/lib/libc/net/linkaddr.c52
-rw-r--r--freebsd/lib/libc/net/name6.c21
-rw-r--r--freebsd/lib/libc/stdio/fgetln.c7
-rw-r--r--freebsd/lib/libipsec/pfkey.c1
-rw-r--r--freebsd/lib/libipsec/pfkey_dump.c5
-rw-r--r--freebsd/lib/libmemstat/memstat_uma.c3
-rw-r--r--freebsd/sbin/dhclient/clparse.c2
-rw-r--r--freebsd/sbin/dhclient/dhclient.c15
-rw-r--r--freebsd/sbin/dhclient/dhcpd.h2
-rw-r--r--freebsd/sbin/dhclient/dispatch.c48
-rw-r--r--freebsd/sbin/dhclient/privsep.c8
-rw-r--r--freebsd/sbin/dhclient/privsep.h3
-rw-r--r--freebsd/sbin/dhclient/tables.c1
-rw-r--r--freebsd/sbin/ifconfig/af_inet.c2
-rw-r--r--freebsd/sbin/ifconfig/af_inet6.c2
-rw-r--r--freebsd/sbin/ifconfig/af_link.c25
-rw-r--r--freebsd/sbin/pfctl/parse.y78
-rw-r--r--freebsd/sbin/pfctl/pfctl.c2
-rw-r--r--freebsd/sbin/pfctl/pfctl_optimize.c4
-rw-r--r--freebsd/sbin/pfctl/pfctl_parser.c8
-rw-r--r--freebsd/sbin/sysctl/sysctl.c3
-rw-r--r--freebsd/sys/arm/include/machine/cpufunc.h46
-rw-r--r--freebsd/sys/arm/xilinx/zy7_slcr.c5
-rw-r--r--freebsd/sys/cam/cam.h2
-rw-r--r--freebsd/sys/cam/cam_ccb.h6
-rw-r--r--freebsd/sys/cam/cam_periph.h1
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.c123
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.h48
-rw-r--r--freebsd/sys/crypto/sha1.h2
-rw-r--r--freebsd/sys/crypto/sha2/sha256.h11
-rw-r--r--freebsd/sys/crypto/sha2/sha384.h11
-rw-r--r--freebsd/sys/crypto/sha2/sha512.h11
-rw-r--r--freebsd/sys/crypto/sha2/sha512t.h22
-rw-r--r--freebsd/sys/crypto/siphash/siphash.h9
-rw-r--r--freebsd/sys/crypto/skein/skein_freebsd.h15
-rw-r--r--freebsd/sys/crypto/skein/skein_port.h10
-rw-r--r--freebsd/sys/dev/bfe/if_bfe.c2
-rw-r--r--freebsd/sys/dev/e1000/if_em.c44
-rw-r--r--freebsd/sys/dev/e1000/if_igb.c19
-rw-r--r--freebsd/sys/dev/e1000/if_lem.c175
-rw-r--r--freebsd/sys/dev/mii/rgephy.c12
-rw-r--r--freebsd/sys/dev/mii/rgephyreg.h3
-rw-r--r--freebsd/sys/dev/nvme/nvme.h38
-rw-r--r--freebsd/sys/dev/pci/pci.c180
-rw-r--r--freebsd/sys/dev/pci/pcireg.h21
-rw-r--r--freebsd/sys/dev/pci/pcivar.h13
-rw-r--r--freebsd/sys/dev/re/if_re.c10
-rw-r--r--freebsd/sys/dev/rl/if_rlreg.h5
-rw-r--r--freebsd/sys/dev/tsec/if_tsec.h7
-rw-r--r--freebsd/sys/dev/usb/controller/dwc_otg.c27
-rw-r--r--freebsd/sys/dev/usb/controller/dwc_otg.h7
-rw-r--r--freebsd/sys/dev/usb/quirk/usb_quirk.c30
-rw-r--r--freebsd/sys/dev/usb/storage/umass.c2
-rw-r--r--freebsd/sys/dev/usb/usb_busdma.c14
-rw-r--r--freebsd/sys/dev/usb/usb_core.c14
-rw-r--r--freebsd/sys/dev/usb/usb_core.h25
-rw-r--r--freebsd/sys/dev/usb/usb_dev.c6
-rw-r--r--freebsd/sys/dev/usb/usb_device.c61
-rw-r--r--freebsd/sys/dev/usb/usb_device.h5
-rw-r--r--freebsd/sys/dev/usb/usb_freebsd.h3
-rw-r--r--freebsd/sys/dev/usb/usb_generic.c15
-rw-r--r--freebsd/sys/dev/usb/usb_hub.c8
-rw-r--r--freebsd/sys/dev/usb/usb_msctest.c8
-rw-r--r--freebsd/sys/dev/usb/usb_process.c25
-rw-r--r--freebsd/sys/dev/usb/usb_request.c21
-rw-r--r--freebsd/sys/dev/usb/usb_transfer.c76
-rw-r--r--freebsd/sys/dev/usb/usb_util.c4
-rw-r--r--freebsd/sys/dev/usb/usbdi.h57
-rw-r--r--freebsd/sys/i386/include/machine/md_var.h1
-rw-r--r--freebsd/sys/kern/init_main.c42
-rw-r--r--freebsd/sys/kern/kern_condvar.c4
-rw-r--r--freebsd/sys/kern/kern_linker.c38
-rw-r--r--freebsd/sys/kern/kern_mib.c22
-rw-r--r--freebsd/sys/kern/kern_synch.c10
-rw-r--r--freebsd/sys/kern/kern_sysctl.c2
-rw-r--r--freebsd/sys/kern/kern_time.c2
-rw-r--r--freebsd/sys/kern/kern_timeout.c4
-rw-r--r--freebsd/sys/kern/subr_bus.c74
-rw-r--r--freebsd/sys/kern/subr_hash.c2
-rw-r--r--freebsd/sys/kern/subr_pcpu.c2
-rw-r--r--freebsd/sys/kern/subr_prf.c6
-rw-r--r--freebsd/sys/kern/subr_sleepqueue.c6
-rw-r--r--freebsd/sys/kern/subr_taskqueue.c28
-rw-r--r--freebsd/sys/kern/subr_uio.c4
-rw-r--r--freebsd/sys/kern/sys_generic.c2
-rw-r--r--freebsd/sys/kern/sys_socket.c2
-rw-r--r--freebsd/sys/kern/uipc_accf.c2
-rw-r--r--freebsd/sys/kern/uipc_domain.c2
-rw-r--r--freebsd/sys/kern/uipc_mbuf.c6
-rw-r--r--freebsd/sys/kern/uipc_mbuf2.c2
-rw-r--r--freebsd/sys/kern/uipc_sockbuf.c2
-rw-r--r--freebsd/sys/kern/uipc_socket.c5
-rw-r--r--freebsd/sys/kern/uipc_syscalls.c310
-rw-r--r--freebsd/sys/kern/uipc_usrreq.c16
-rw-r--r--freebsd/sys/mips/include/machine/cpufunc.h10
-rw-r--r--freebsd/sys/mips/include/machine/cpuregs.h8
-rw-r--r--freebsd/sys/net/altq/altq_subr.c2
-rw-r--r--freebsd/sys/net/bpf_filter.c25
-rw-r--r--freebsd/sys/net/ethernet.h2
-rw-r--r--freebsd/sys/net/if.c2
-rw-r--r--freebsd/sys/net/if_arcsubr.c2
-rw-r--r--freebsd/sys/net/if_bridge.c88
-rw-r--r--freebsd/sys/net/if_fddisubr.c2
-rw-r--r--freebsd/sys/net/if_iso88025subr.c2
-rw-r--r--freebsd/sys/net/if_llatbl.c35
-rw-r--r--freebsd/sys/net/if_llatbl.h8
-rw-r--r--freebsd/sys/net/if_loop.c5
-rw-r--r--freebsd/sys/net/if_var.h10
-rw-r--r--freebsd/sys/net/pfkeyv2.h11
-rw-r--r--freebsd/sys/net/raw_usrreq.c2
-rw-r--r--freebsd/sys/net/route.c9
-rw-r--r--freebsd/sys/net/route_var.h2
-rw-r--r--freebsd/sys/net/rtsock.c42
-rw-r--r--freebsd/sys/netinet/cc/cc.h1
-rw-r--r--freebsd/sys/netinet/cc/cc_newreno.c29
-rw-r--r--freebsd/sys/netinet/if_ether.c128
-rw-r--r--freebsd/sys/netinet/igmp.c8
-rw-r--r--freebsd/sys/netinet/in.c8
-rw-r--r--freebsd/sys/netinet/in_pcb.c10
-rw-r--r--freebsd/sys/netinet/in_var.h2
-rw-r--r--freebsd/sys/netinet/ip_fastfwd.c135
-rw-r--r--freebsd/sys/netinet/ip_icmp.c2
-rw-r--r--freebsd/sys/netinet/ip_input.c2
-rw-r--r--freebsd/sys/netinet/ip_mroute.c8
-rw-r--r--freebsd/sys/netinet/ip_output.c13
-rw-r--r--freebsd/sys/netinet/raw_ip.c4
-rw-r--r--freebsd/sys/netinet/sctp_asconf.c54
-rw-r--r--freebsd/sys/netinet/sctp_asconf.h1
-rw-r--r--freebsd/sys/netinet/sctp_bsd_addr.c11
-rw-r--r--freebsd/sys/netinet/sctp_bsd_addr.h1
-rw-r--r--freebsd/sys/netinet/sctp_cc_functions.c77
-rw-r--r--freebsd/sys/netinet/sctp_constants.h5
-rw-r--r--freebsd/sys/netinet/sctp_crc32.c1
-rw-r--r--freebsd/sys/netinet/sctp_crc32.h2
-rw-r--r--freebsd/sys/netinet/sctp_header.h21
-rw-r--r--freebsd/sys/netinet/sctp_indata.c776
-rw-r--r--freebsd/sys/netinet/sctp_indata.h11
-rw-r--r--freebsd/sys/netinet/sctp_input.c136
-rw-r--r--freebsd/sys/netinet/sctp_os_bsd.h1
-rw-r--r--freebsd/sys/netinet/sctp_output.c386
-rw-r--r--freebsd/sys/netinet/sctp_pcb.c147
-rw-r--r--freebsd/sys/netinet/sctp_pcb.h9
-rw-r--r--freebsd/sys/netinet/sctp_peeloff.h1
-rw-r--r--freebsd/sys/netinet/sctp_structs.h28
-rw-r--r--freebsd/sys/netinet/sctp_sysctl.c3
-rw-r--r--freebsd/sys/netinet/sctp_timer.c48
-rw-r--r--freebsd/sys/netinet/sctp_uio.h3
-rw-r--r--freebsd/sys/netinet/sctp_usrreq.c142
-rw-r--r--freebsd/sys/netinet/sctp_var.h6
-rw-r--r--freebsd/sys/netinet/sctputil.c185
-rw-r--r--freebsd/sys/netinet/sctputil.h5
-rw-r--r--freebsd/sys/netinet/tcp_debug.c4
-rw-r--r--freebsd/sys/netinet/tcp_fsm.h3
-rw-r--r--freebsd/sys/netinet/tcp_hostcache.c56
-rw-r--r--freebsd/sys/netinet/tcp_hostcache.h28
-rw-r--r--freebsd/sys/netinet/tcp_input.c181
-rw-r--r--freebsd/sys/netinet/tcp_lro.c1
-rw-r--r--freebsd/sys/netinet/tcp_output.c92
-rw-r--r--freebsd/sys/netinet/tcp_seq.h7
-rw-r--r--freebsd/sys/netinet/tcp_subr.c50
-rw-r--r--freebsd/sys/netinet/tcp_syncache.c51
-rw-r--r--freebsd/sys/netinet/tcp_timer.c20
-rw-r--r--freebsd/sys/netinet/tcp_timewait.c5
-rw-r--r--freebsd/sys/netinet/tcp_usrreq.c53
-rw-r--r--freebsd/sys/netinet/tcp_var.h51
-rw-r--r--freebsd/sys/netinet/udp_usrreq.c11
-rw-r--r--freebsd/sys/netinet6/icmp6.c169
-rw-r--r--freebsd/sys/netinet6/in6.c19
-rw-r--r--freebsd/sys/netinet6/in6_ifattach.c25
-rw-r--r--freebsd/sys/netinet6/ip6_forward.c3
-rw-r--r--freebsd/sys/netinet6/ip6_input.c4
-rw-r--r--freebsd/sys/netinet6/ip6_mroute.c13
-rw-r--r--freebsd/sys/netinet6/ip6_output.c36
-rw-r--r--freebsd/sys/netinet6/nd6.c145
-rw-r--r--freebsd/sys/netinet6/nd6.h29
-rw-r--r--freebsd/sys/netinet6/nd6_nbr.c43
-rw-r--r--freebsd/sys/netinet6/nd6_rtr.c358
-rw-r--r--freebsd/sys/netinet6/raw_ip6.c2
-rw-r--r--freebsd/sys/netinet6/sctp6_usrreq.c6
-rw-r--r--freebsd/sys/netinet6/sctp6_var.h1
-rw-r--r--freebsd/sys/netinet6/udp6_usrreq.c5
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw2.c4
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw_dynamic.c11
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw_pfil.c24
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw_table.c50
-rw-r--r--freebsd/sys/netpfil/ipfw/nat64/nat64_translate.c4
-rw-r--r--freebsd/sys/netpfil/pf/if_pflog.c2
-rw-r--r--freebsd/sys/netpfil/pf/if_pfsync.c9
-rw-r--r--freebsd/sys/netpfil/pf/pf.c65
-rw-r--r--freebsd/sys/netpfil/pf/pf_if.c2
-rw-r--r--freebsd/sys/netpfil/pf/pf_ioctl.c4
-rw-r--r--freebsd/sys/netpfil/pf/pf_norm.c2
-rw-r--r--freebsd/sys/opencrypto/crypto.c4
-rw-r--r--freebsd/sys/powerpc/include/machine/cpufunc.h2
-rw-r--r--freebsd/sys/powerpc/include/machine/spr.h5
-rw-r--r--freebsd/sys/sys/buf.h31
-rw-r--r--freebsd/sys/sys/bufobj.h5
-rw-r--r--freebsd/sys/sys/bus.h4
-rw-r--r--freebsd/sys/sys/capsicum.h2
-rw-r--r--freebsd/sys/sys/eventhandler.h7
-rw-r--r--freebsd/sys/sys/filedesc.h28
-rw-r--r--freebsd/sys/sys/linker.h1
-rw-r--r--freebsd/sys/sys/mbuf.h8
-rw-r--r--freebsd/sys/sys/module.h2
-rw-r--r--freebsd/sys/sys/mount.h11
-rw-r--r--freebsd/sys/sys/proc.h1
-rw-r--r--freebsd/sys/sys/sf_buf.h1
-rw-r--r--freebsd/sys/sys/socket.h1
-rw-r--r--freebsd/sys/sys/socketvar.h3
-rw-r--r--freebsd/sys/sys/sysctl.h1
-rw-r--r--freebsd/sys/sys/sysproto.h2
-rw-r--r--freebsd/sys/sys/user.h3
-rw-r--r--freebsd/sys/sys/vmmeter.h40
-rw-r--r--freebsd/sys/sys/vnode.h13
-rw-r--r--freebsd/sys/vm/uma_core.c16
-rw-r--r--freebsd/usr.bin/netstat/mbuf.c3
-rw-r--r--freebsd/usr.bin/netstat/route.c2
-rw-r--r--freebsd/usr.bin/vmstat/vmstat.c14
-rw-r--r--libbsd.txt2
-rw-r--r--rtemsbsd/include/machine/rtems-bsd-kernel-space.h2
-rw-r--r--rtemsbsd/include/rtems/bsd/sys/param.h2
227 files changed, 3788 insertions, 2994 deletions
diff --git a/freebsd-org b/freebsd-org
-Subproject 9fe7c416e6abb28b1398fd3e5687099846800cf
+Subproject 80c55f08a05ab3b26a73b226ccb56adc3122a55
diff --git a/freebsd/bin/hostname/hostname.c b/freebsd/bin/hostname/hostname.c
index 8e9fc975..61b5dbad 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 16914512..6a74ef70 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 2034f6af..a8146e5a 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 9fe6ab01..053b221a 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 0fe1b5d8..18aed435 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 1a2c3fd3..dbd363d8 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 a106ad98..8b8ac79c 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 7d9f6a53..8d1235c5 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 abb0cee1..eeb07f82 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 7a5c2f21..7c6ff8d8 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 9c5e4024..299386c8 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 a65236fc..10df53b3 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 c7b75c59..46ffaffc 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 852513a8..f2bc7738 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 4a68c62d..d37c9925 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 aa1042fd..b1cf5106 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 d464da43..e1a7338f 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 d73022d1..6339898c 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 d464df52..040da216 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 f743ee8f..d3d58ade 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 1c37496e..5fa2545d 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 33edd3e5..9664aaf5 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 ab597068..f9efa090 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 b8f44e8b..89cebe91 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 0ff7deec..cb49dc2a 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 fdbecd5f..03069a38 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 911fc14c..8a9a2a84 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 7ce502f9..dc6475c0 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 5eb0a776..23feb508 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 e00b5bd3..d9b91f8d 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 e28d5b11..d5a74a51 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 0cb7118a..9e8924c5 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 1fd45405..9c1376cf 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 d61709e2..c1bc1a3a 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 17aae7de..bd31a621 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 63dd948b..01345592 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 b008aeae..8b3e17cc 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 3f0c921f..1ae490f5 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 8bbda4f3..235818b5 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 935fa090..676b79bc 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 7025a516..ab320b29 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 c87dea13..a76bc7ee 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 fa34dd62..d8c1e5a6 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 d683b85f..2e9c7259 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 c46c3728..b3da1bdd 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 067bbadf..963197a1 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 7c24a1f7..35917daa 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 755e3766..9c1dab17 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 789825dc..211562f0 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 d463b7a5..291bb2ea 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 fc3fa5fb..4652715a 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 554af66a..7e0e87f8 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 2cef251b..2fa44efa 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 108b0f21..60a565ea 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 d070f145..3450f6de 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 038b072a..7f5ede48 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 1ff0afba..d73116e2 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 0fb810c1..e8ee210a 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 88566199..16fc7f7b 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 b5e66407..a74bdcaa 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 739a0039..9f52e65a 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 b31ba617..fe249c20 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 26c694e8..06e70503 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 24a5a4a6..22e15606 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 0d2e8105..bc5d2422 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 675a63d3..c0873a6a 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 a744a82e..d27728e9 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 cf29d09d..58849f13 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 219a736a..569550e6 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 f092094b..2d7634a2 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 9bb68fd3..9cd40349 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 a2a5cee7..377c2341 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 202ad89f..6ad3e43e 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 c3caf07a..c93d70c8 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 627c01e0..72bab872 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 239640e2..6358c376 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 a115aa96..82a33023 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 aa1c5774..63d8b44f 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 6ecedfd2..6a8e7754 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 3bcf6688..07ddded9 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 2fb4dd2e..95111932 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 37ec0956..73b55338 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 3eb7d7e9..1175456c 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 1371a345..425fd34d 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 4d223899..5c244b42 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 9273cd2a..2aed7f68 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 be8e7721..a42c62f8 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 8580e8fc..5ef8683c 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 a319685a..f5dc76e7 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 26cd9d36..d6b3d15b 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 f312c8f4..a2537652 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 6ecea0eb..7d6bde25 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 7c0e7085..ab301eb5 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 db4975ca..571dd3bd 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 fef1c514..fc5c8e8a 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 f62014bc..a7977141 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 3f2dba72..c086ee7c 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 99ae6392..2d81fc20 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 7b2d1bc4..159de132 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 427aba74..5ebaf4cc 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 4ce7e1b4..26bee195 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 66ff441d..a9a68b37 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 941fa290..ecfb3d14 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 bc5fa9cb..5ec9d20e 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 8bfa9e21..e1c525bd 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 1954e262..042f3e84 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 77b376b9..fc0dbffd 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 9df882ec..98ac4cc3 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 d26d0ebd..38322b23 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 20c0b9d2..a4741884 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 51de726a..5e89fea0 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 aa5109eb..5ee82fc0 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 ec3719d4..6ddb6c7b 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 c9b27695..35348819 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 e170ad74..6e9668f3 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 3eb05b94..a851efa8 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 a8ef56a5..914bcfe2 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 1e69bcdf..97b92127 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 1da6f620..5e61b04b 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 8077bb22..4c21036a 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 0a8b101e..9fb25c21 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 cd57e426..12bb2f07 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 06b23973..f08e550b 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 f8790938..809a7de0 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 af83e9a1..08055c4f 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 19dfb1ab..bc4d70b4 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 f34cc4bd..a1331cac 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 425dbc1f..a2278616 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 f8b14735..f5aa0a38 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 81e7b123..5436ea2d 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 a4679586..c379d681 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 4256ab51..5d86e520 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 183c99b4..c8d670e5 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 bfd7f816..72c63d76 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 24660ca5..5fb1efb4 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 68dc460a..49670e9b 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 ecde4fee..e779051d 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 bb081e8f..9130feb2 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 3f98be41..7fe02f5c 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 3f4948dd..b650d930 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 12c2c80f..d9449a66 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 162ca905..e277ae88 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 621784ea..3c596c48 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 e87914e5..438973cb 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 9e12e775..94f9d866 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 62ef1e3d..ca86a139 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 98204096..a2a1e7d7 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 dd905676..00b87031 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 280100bb..22a3c736 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 8715c69b..152a2996 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 c851317b..2d427e48 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 e65b7b5e..d6055163 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 1cbb7076..e3e398d4 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 a4d2b998..6365dfec 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 36a9c2ce..136b4bb6 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 292068af..a3a4f3c6 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 c5f74182..707e7c5d 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 61fd0c1f..5423e1f1 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 4e78b8b2..e0c4b493 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 44875ff6..23a0c673 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 eaa3eb3d..7e07fc0a 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 3550ab84..f318e78b 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 af11d805..a310512e 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 51d971f2..666cf603 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 cff9bd7b..4f196a15 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 d7da3a01..453d5ba4 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 edfc3829..89b61ad8 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 330e842e..7eb05462 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 d5fa680f..436f30f8 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 5dcd35b8..f4ea246b 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 7eb11648..42461ce9 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 6e3a4873..14ce2b3b 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 f5d82524..8a4c3663 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 791e9e27..879336a4 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 50583537..b57d31fa 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 c7ffe759..6af5acd7 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 f74b71c3..e40ce06c 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 d3dc973e..63d1dac1 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 d1c7036d..3e019a62 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 33ac4386..9b9fa3d1 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 df50fa93..e30dca8e 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 c8d7c0ef..33d8fa2a 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 dfd7c45b..5b0577d3 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 962a622e..735de62a 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 782567c5..232fee15 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 790bed2b..2f950e62 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 a3a11819..945ad170 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 4696faac..5694b1d1 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 59c13aa5..167d2028 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 9d2baad2..17c5f017 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 d2507674..2f881476 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 3a364abc..09473f17 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 d6a0dfc0..d82a6b74 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 7ac181b5..5b6be3cb 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 d1c54b22..29f8e941 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 9c1523ca..076ed5f8 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 86d2c8eb..42b44c70 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 4a013648..2d9787bd 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 c949d53d..378274b6 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 86dac97b..35bd9009 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 f32c6ca1..8688056f 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 0fa6c8ce..657702c1 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 6e356e9c..e62c9bab 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 af4da032..a5e64925 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 9315f8c8..845b28c1 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 30c2deef..1e99bfae 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 90db1b8c..eecb4cdd 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 95194e0b..9ce52a17 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 07464fc6..71aa9954 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 49e688f3..1bf583a6 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 4a695ef9..03aae8f8 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 b5970d95..6aebe430 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 f23b5f69..ea3d9b6b 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 72eaa998..1e599a66 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 687fb23b..291b7e44 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 1ee7bb4e..b3c944bf 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 d0da0455..9dad4d0a 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 39f03d0d..31312b0a 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 a047bc67..5400fe1c 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 3957a223..00ac3e5a 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 81f57292..446592ae 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 bed58b06..da799825 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 ed146562..8f9daa9a 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 2d0a012c..12a28809 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 49dc3aad..10ce9d2d 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 a21e94aa..fb9b80cc 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