Author: rrs
Date: Thu Apr  7 09:10:34 2016
New Revision: 297662
URL: https://svnweb.freebsd.org/changeset/base/297662

Log:
  This is work done by Michael Tuexen and myself at the IETF. This
  adds the new I-Data (Interleaved Data) message. This allows a user
  to be able to have complete freedom from Head Of Line blocking that
  was previously there due to the in-ability to send multiple large
  messages without the TSN's being in sequence. The code as been
  tested with Michaels various packet drill scripts as well as
  inter-networking between the IETF's location in Argentina and Germany.

Modified:
  head/sys/netinet/sctp.h
  head/sys/netinet/sctp_constants.h
  head/sys/netinet/sctp_dtrace_define.h
  head/sys/netinet/sctp_header.h
  head/sys/netinet/sctp_indata.c
  head/sys/netinet/sctp_indata.h
  head/sys/netinet/sctp_input.c
  head/sys/netinet/sctp_os_bsd.h
  head/sys/netinet/sctp_output.c
  head/sys/netinet/sctp_pcb.c
  head/sys/netinet/sctp_pcb.h
  head/sys/netinet/sctp_structs.h
  head/sys/netinet/sctp_sysctl.h
  head/sys/netinet/sctp_uio.h
  head/sys/netinet/sctp_usrreq.c
  head/sys/netinet/sctp_var.h
  head/sys/netinet/sctputil.c
  head/sys/netinet/sctputil.h

Modified: head/sys/netinet/sctp.h
==============================================================================
--- head/sys/netinet/sctp.h     Thu Apr  7 08:32:37 2016        (r297661)
+++ head/sys/netinet/sctp.h     Thu Apr  7 09:10:34 2016        (r297662)
@@ -196,6 +196,9 @@ struct sctp_paramhdr {
 #define SCTP_SS_VALUE                  0x00001204
 #define SCTP_CC_OPTION                 0x00001205      /* Options for CC
                                                         * modules */
+/* For I-DATA */
+#define SCTP_INTERLEAVING_SUPPORTED    0x00001206
+
 /* read only */
 #define SCTP_GET_SNDBUF_USE            0x00001101
 #define SCTP_GET_STAT_LOG              0x00001103
@@ -452,6 +455,7 @@ struct sctp_error_auth_invalid_hmac {
 /* EY nr_sack chunk id*/
 #define SCTP_NR_SELECTIVE_ACK  0x10
 /************0x40 series ***********/
+#define SCTP_IDATA             0x40
 /************0x80 series ***********/
 /* RFC5061 */
 #define        SCTP_ASCONF_ACK         0x80
@@ -467,7 +471,7 @@ struct sctp_error_auth_invalid_hmac {
 #define SCTP_FORWARD_CUM_TSN   0xc0
 /* RFC5061 */
 #define SCTP_ASCONF            0xc1
-
+#define SCTP_IFORWARD_CUM_TSN  0xc2
 
 /* ABORT and SHUTDOWN COMPLETE FLAG */
 #define SCTP_HAD_NO_TCB                0x01

Modified: head/sys/netinet/sctp_constants.h
==============================================================================
--- head/sys/netinet/sctp_constants.h   Thu Apr  7 08:32:37 2016        
(r297661)
+++ head/sys/netinet/sctp_constants.h   Thu Apr  7 09:10:34 2016        
(r297662)
@@ -386,8 +386,8 @@ __FBSDID("$FreeBSD$");
 /* align to 32-bit sizes */
 #define SCTP_SIZE32(x) ((((x) + 3) >> 2) << 2)
 
-#define IS_SCTP_CONTROL(a) ((a)->chunk_type != SCTP_DATA)
-#define IS_SCTP_DATA(a) ((a)->chunk_type == SCTP_DATA)
+#define IS_SCTP_CONTROL(a) (((a)->chunk_type != SCTP_DATA) && ((a)->chunk_type 
!= SCTP_IDATA))
+#define IS_SCTP_DATA(a) (((a)->chunk_type == SCTP_DATA) || ((a)->chunk_type == 
SCTP_IDATA))
 
 
 /* SCTP parameter types */
@@ -886,12 +886,19 @@ __FBSDID("$FreeBSD$");
 
 /* modular comparison */
 /* See RFC 1982 for details. */
-#define SCTP_SSN_GT(a, b) (((a < b) && ((uint16_t)(b - a) > (1U<<15))) || \
-                           ((a > b) && ((uint16_t)(a - b) < (1U<<15))))
-#define SCTP_SSN_GE(a, b) (SCTP_SSN_GT(a, b) || (a == b))
-#define SCTP_TSN_GT(a, b) (((a < b) && ((uint32_t)(b - a) > (1U<<31))) || \
-                           ((a > b) && ((uint32_t)(a - b) < (1U<<31))))
-#define SCTP_TSN_GE(a, b) (SCTP_TSN_GT(a, b) || (a == b))
+#define SCTP_UINT16_GT(a, b) (((a < b) && ((uint16_t)(b - a) > (1U<<15))) || \
+                              ((a > b) && ((uint16_t)(a - b) < (1U<<15))))
+#define SCTP_UINT16_GE(a, b) (SCTP_UINT16_GT(a, b) || (a == b))
+#define SCTP_UINT32_GT(a, b) (((a < b) && ((uint32_t)(b - a) > (1U<<31))) || \
+                              ((a > b) && ((uint32_t)(a - b) < (1U<<31))))
+#define SCTP_UINT32_GE(a, b) (SCTP_UINT32_GT(a, b) || (a == b))
+
+#define SCTP_SSN_GT(a, b) SCTP_UINT16_GT(a, b)
+#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))
 
 /* Mapping array manipulation routines */
 #define SCTP_IS_TSN_PRESENT(arry, gap) ((arry[(gap >> 3)] >> (gap & 0x07)) & 
0x01)

Modified: head/sys/netinet/sctp_dtrace_define.h
==============================================================================
--- head/sys/netinet/sctp_dtrace_define.h       Thu Apr  7 08:32:37 2016        
(r297661)
+++ head/sys/netinet/sctp_dtrace_define.h       Thu Apr  7 09:10:34 2016        
(r297662)
@@ -45,131 +45,131 @@ SDT_PROVIDER_DEFINE(sctp);
 /********************************************************/
 /* Initial */
 SDT_PROBE_DEFINE5(sctp, cwnd, net, init,
-    "uint32_t",                /* The Vtag for this end */
-    "uint32_t",                /*
-                        * The port number of the local side << 16 | port number
-                        * of remote in network byte order.
-                        */
-    "uintptr_t",       /* The pointer to the struct sctp_nets * changing */
-    "int",             /* The old value of the cwnd */
-    "int");            /* The new value of the cwnd */
+    "uint32_t",                        /* The Vtag for this end */
+    "uint32_t",                        /* The port number of the local side << 
16 |
+                                * port number of remote in network byte
+                                * order. */
+    "uintptr_t",               /* The pointer to the struct sctp_nets *
+                                * changing */
+    "int",                     /* The old value of the cwnd */
+    "int");                    /* The new value of the cwnd */
 
 /* ACK-INCREASE */
 SDT_PROBE_DEFINE5(sctp, cwnd, net, ack,
-    "uint32_t",                /* The Vtag for this end */
-    "uint32_t",                /*
-                        * The port number of the local side << 16 | port number
-                        * of remote in network byte order.
-                        */
-    "uintptr_t",       /* The pointer to the struct sctp_nets * changing */
-    "int",             /* The old value of the cwnd */
-    "int");            /* The new value of the cwnd */
+    "uint32_t",                        /* The Vtag for this end */
+    "uint32_t",                        /* The port number of the local side << 
16 |
+                                * port number of remote in network byte
+                                * order. */
+    "uintptr_t",               /* The pointer to the struct sctp_nets *
+                                * changing */
+    "int",                     /* The old value of the cwnd */
+    "int");                    /* The new value of the cwnd */
 
 /* ACK-INCREASE */
 SDT_PROBE_DEFINE5(sctp, cwnd, net, rttvar,
-    "uint64_t",                /* The Vtag << 32 | localport << 16 | 
remoteport */
-    "uint64_t",                /* obw | nbw */
-    "uint64_t",                /* bwrtt | newrtt */
-    "uint64_t",                /* flight */
-    "uint64_t");       /* (cwnd << 32) | point << 16 | retval(0/1) */
+    "uint64_t",                        /* The Vtag << 32 | localport << 16 |
+                                * remoteport */
+    "uint64_t",                        /* obw | nbw */
+    "uint64_t",                        /* bwrtt | newrtt */
+    "uint64_t",                        /* flight */
+    "uint64_t");               /* (cwnd << 32) | point << 16 | retval(0/1) */
 
 SDT_PROBE_DEFINE5(sctp, cwnd, net, rttstep,
-    "uint64_t",                /* The Vtag << 32 | localport << 16 | 
remoteport */
-    "uint64_t",                /* obw | nbw */
-    "uint64_t",                /* bwrtt | newrtt */
-    "uint64_t",                /* flight */
-    "uint64_t");       /* (cwnd << 32) | point << 16 | retval(0/1) */
+    "uint64_t",                        /* The Vtag << 32 | localport << 16 |
+                                * remoteport */
+    "uint64_t",                        /* obw | nbw */
+    "uint64_t",                        /* bwrtt | newrtt */
+    "uint64_t",                        /* flight */
+    "uint64_t");               /* (cwnd << 32) | point << 16 | retval(0/1) */
 
 /* FastRetransmit-DECREASE */
 SDT_PROBE_DEFINE5(sctp, cwnd, net, fr,
-    "uint32_t",                /* The Vtag for this end */
-    "uint32_t",                /*
-                        * The port number of the local side << 16 | port number
-                        * of remote in network byte order.
-                        */
-    "uintptr_t",       /* The pointer to the struct sctp_nets * changing */
-    "int",             /* The old value of the cwnd */
-    "int");            /* The new value of the cwnd */
+    "uint32_t",                        /* The Vtag for this end */
+    "uint32_t",                        /* The port number of the local side << 
16 |
+                                * port number of remote in network byte
+                                * order. */
+    "uintptr_t",               /* The pointer to the struct sctp_nets *
+                                * changing */
+    "int",                     /* The old value of the cwnd */
+    "int");                    /* The new value of the cwnd */
 
 /* TimeOut-DECREASE */
 SDT_PROBE_DEFINE5(sctp, cwnd, net, to,
-    "uint32_t",                /* The Vtag for this end */
-    "uint32_t",                /*
-                        * The port number of the local side << 16 | port number
-                        * of remote in network byte order.
-                        */
-    "uintptr_t",       /* The pointer to the struct sctp_nets * changing */
-    "int",             /* The old value of the cwnd */
-    "int");            /* The new value of the cwnd */
+    "uint32_t",                        /* The Vtag for this end */
+    "uint32_t",                        /* The port number of the local side << 
16 |
+                                * port number of remote in network byte
+                                * order. */
+    "uintptr_t",               /* The pointer to the struct sctp_nets *
+                                * changing */
+    "int",                     /* The old value of the cwnd */
+    "int");                    /* The new value of the cwnd */
 
 /* BurstLimit-DECREASE */
 SDT_PROBE_DEFINE5(sctp, cwnd, net, bl,
-    "uint32_t",                /* The Vtag for this end */
-    "uint32_t",                /*
-                        * The port number of the local side << 16 | port number
-                        * of remote in network byte order.
-                        */
-    "uintptr_t",       /* The pointer to the struct sctp_nets * changing */
-    "int",             /* The old value of the cwnd */
-    "int");            /* The new value of the cwnd */
+    "uint32_t",                        /* The Vtag for this end */
+    "uint32_t",                        /* The port number of the local side << 
16 |
+                                * port number of remote in network byte
+                                * order. */
+    "uintptr_t",               /* The pointer to the struct sctp_nets *
+                                * changing */
+    "int",                     /* The old value of the cwnd */
+    "int");                    /* The new value of the cwnd */
 
 /* ECN-DECREASE */
 SDT_PROBE_DEFINE5(sctp, cwnd, net, ecn,
-    "uint32_t",                /* The Vtag for this end */
-    "uint32_t",                /*
-                        * The port number of the local side << 16 | port number
-                        * of remote in network byte order.
-                        */
-    "uintptr_t",       /* The pointer to the struct sctp_nets * changing */
-    "int",             /* The old value of the cwnd */
-    "int");            /* The new value of the cwnd */
+    "uint32_t",                        /* The Vtag for this end */
+    "uint32_t",                        /* The port number of the local side << 
16 |
+                                * port number of remote in network byte
+                                * order. */
+    "uintptr_t",               /* The pointer to the struct sctp_nets *
+                                * changing */
+    "int",                     /* The old value of the cwnd */
+    "int");                    /* The new value of the cwnd */
 
 /* PacketDrop-DECREASE */
 SDT_PROBE_DEFINE5(sctp, cwnd, net, pd,
-    "uint32_t",                /* The Vtag for this end */
-    "uint32_t",                /*
-                        * The port number of the local side << 16 | port number
-                        * of remote in network byte order.
-                        */
-    "uintptr_t",       /* The pointer to the struct sctp_nets * changing */
-    "int",             /* The old value of the cwnd */
-    "int");            /* The new value of the cwnd */
+    "uint32_t",                        /* The Vtag for this end */
+    "uint32_t",                        /* The port number of the local side << 
16 |
+                                * port number of remote in network byte
+                                * order. */
+    "uintptr_t",               /* The pointer to the struct sctp_nets *
+                                * changing */
+    "int",                     /* The old value of the cwnd */
+    "int");                    /* The new value of the cwnd */
 
 /********************************************************/
 /* Rwnd probe - tracks changes in the receiver window for an assoc */
 /********************************************************/
 SDT_PROBE_DEFINE4(sctp, rwnd, assoc, val,
-    "uint32_t",                /* The Vtag for this end */
-    "uint32_t",                /*
-                        * The port number of the local side << 16 | port number
-                        * of remote in network byte order.
-                        */
-    "int",             /* The up/down amount */
-    "int");            /* The new value of the cwnd */
+    "uint32_t",                        /* The Vtag for this end */
+    "uint32_t",                        /* The port number of the local side << 
16 |
+                                * port number of remote in network byte
+                                * order. */
+    "int",                     /* The up/down amount */
+    "int");                    /* The new value of the cwnd */
 
 /********************************************************/
 /* flight probe - tracks changes in the flight size on a net or assoc */
 /********************************************************/
 SDT_PROBE_DEFINE5(sctp, flightsize, net, val,
-    "uint32_t",                /* The Vtag for this end */
-    "uint32_t",                /*
-                        * The port number of the local side << 16 | port number
-                        * of remote in network byte order.
-                        */
-    "uintptr_t",        /* The pointer to the struct sctp_nets * changing */
-    "int",             /* The up/down amount */
-    "int");            /* The new value of the cwnd */
+    "uint32_t",                        /* The Vtag for this end */
+    "uint32_t",                        /* The port number of the local side << 
16 |
+                                * port number of remote in network byte
+                                * order. */
+    "uintptr_t",               /* The pointer to the struct sctp_nets *
+                                * changing */
+    "int",                     /* The up/down amount */
+    "int");                    /* The new value of the cwnd */
 
 /********************************************************/
 /* The total flight version */
 /********************************************************/
 SDT_PROBE_DEFINE4(sctp, flightsize, assoc, val,
-    "uint32_t",                /* The Vtag for this end */
-    "uint32_t",                /*
-                        * The port number of the local side << 16 | port number
-                        * of remote in network byte order.
-                        */
-    "int",             /* The up/down amount */
-    "int");            /* The new value of the cwnd */
+    "uint32_t",                        /* The Vtag for this end */
+    "uint32_t",                        /* The port number of the local side << 
16 |
+                                * port number of remote in network byte
+                                * order. */
+    "int",                     /* The up/down amount */
+    "int");                    /* The new value of the cwnd */
 
 #endif

Modified: head/sys/netinet/sctp_header.h
==============================================================================
--- head/sys/netinet/sctp_header.h      Thu Apr  7 08:32:37 2016        
(r297661)
+++ head/sys/netinet/sctp_header.h      Thu Apr  7 09:10:34 2016        
(r297662)
@@ -152,6 +152,23 @@ struct sctp_data_chunk {
        struct sctp_data dp;
 }               SCTP_PACKED;
 
+struct sctp_idata {
+       uint32_t tsn;
+       uint16_t stream_id;
+       uint16_t reserved;      /* Where does the SSN go? */
+       uint32_t msg_id;
+       union {
+               uint32_t protocol_id;
+               uint32_t fsn;   /* Fragment Sequence Number */
+       };
+       /* user data follows */
+}          SCTP_PACKED;
+
+struct sctp_idata_chunk {
+       struct sctp_chunkhdr ch;
+       struct sctp_idata dp;
+}                SCTP_PACKED;
+
 /*
  * Structures for the control chunks
  */
@@ -378,6 +395,12 @@ struct sctp_strseq {
        uint16_t sequence;
 }           SCTP_PACKED;
 
+struct sctp_strseq_mid {
+       uint16_t stream;
+       uint16_t reserved;
+       uint32_t msg_id;
+};
+
 struct sctp_forward_tsn_msg {
        struct sctphdr sh;
        struct sctp_forward_tsn_chunk msg;

Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c      Thu Apr  7 08:32:37 2016        
(r297661)
+++ head/sys/netinet/sctp_indata.c      Thu Apr  7 09:10:34 2016        
(r297662)
@@ -34,18 +34,22 @@
 __FBSDID("$FreeBSD$");
 
 #include <netinet/sctp_os.h>
+#include <sys/proc.h>
 #include <netinet/sctp_var.h>
 #include <netinet/sctp_sysctl.h>
-#include <netinet/sctp_pcb.h>
 #include <netinet/sctp_header.h>
+#include <netinet/sctp_pcb.h>
 #include <netinet/sctputil.h>
 #include <netinet/sctp_output.h>
-#include <netinet/sctp_input.h>
-#include <netinet/sctp_indata.h>
 #include <netinet/sctp_uio.h>
+#include <netinet/sctp_auth.h>
 #include <netinet/sctp_timer.h>
-
-
+#include <netinet/sctp_asconf.h>
+#include <netinet/sctp_indata.h>
+#include <netinet/sctp_bsd_addr.h>
+#include <netinet/sctp_input.h>
+#include <netinet/sctp_crc32.h>
+#include <netinet/sctp_lock_bsd.h>
 /*
  * NOTES: On the outbound side of things I need to check the sack timer to
  * see if I should generate a sack into the chunk queue (if I have data to
@@ -55,6 +59,13 @@ __FBSDID("$FreeBSD$");
  * This will cause sctp_service_queues() to get called on the top entry in
  * the list.
  */
+static void
+sctp_add_chk_to_control(struct sctp_queued_to_read *control,
+    struct sctp_stream_in *strm,
+    struct sctp_tcb *stcb,
+    struct sctp_association *asoc,
+    struct sctp_tmit_chunk *chk);
+
 
 void
 sctp_set_rwnd(struct sctp_tcb *stcb, struct sctp_association *asoc)
@@ -74,9 +85,9 @@ sctp_calc_rwnd(struct sctp_tcb *stcb, st
         * sctp_soreceive then we will fix this so that ONLY this
         * associations data is taken into account.
         */
-       if (stcb->sctp_socket == NULL)
+       if (stcb->sctp_socket == NULL) {
                return (calc);
-
+       }
        if (stcb->asoc.sb_cc == 0 &&
            asoc->size_on_reasm_queue == 0 &&
            asoc->size_on_all_streams == 0) {
@@ -86,7 +97,6 @@ sctp_calc_rwnd(struct sctp_tcb *stcb, st
        }
        /* get actual space */
        calc = (uint32_t) sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv);
-
        /*
         * take out what has NOT been put on socket queue and we yet hold
         * for putting up.
@@ -95,7 +105,6 @@ sctp_calc_rwnd(struct sctp_tcb *stcb, st
            asoc->cnt_on_reasm_queue * MSIZE));
        calc = sctp_sbspace_sub(calc, (uint32_t) (asoc->size_on_all_streams +
            asoc->cnt_on_all_streams * MSIZE));
-
        if (calc == 0) {
                /* out of space */
                return (calc);
@@ -122,7 +131,7 @@ sctp_build_readq_entry(struct sctp_tcb *
     struct sctp_nets *net,
     uint32_t tsn, uint32_t ppid,
     uint32_t context, uint16_t stream_no,
-    uint16_t stream_seq, uint8_t flags,
+    uint32_t stream_seq, uint8_t flags,
     struct mbuf *dm)
 {
        struct sctp_queued_to_read *read_queue_e = NULL;
@@ -131,73 +140,26 @@ sctp_build_readq_entry(struct sctp_tcb *
        if (read_queue_e == NULL) {
                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_flags = (flags << 8);
        read_queue_e->sinfo_ppid = ppid;
        read_queue_e->sinfo_context = context;
-       read_queue_e->sinfo_timetolive = 0;
        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->top_fsn = read_queue_e->fsn_included = 0xffffffff;
+       TAILQ_INIT(&read_queue_e->reasm);
        read_queue_e->whoFrom = net;
-       read_queue_e->length = 0;
        atomic_add_int(&net->ref_count, 1);
        read_queue_e->data = dm;
-       read_queue_e->spec_flags = 0;
-       read_queue_e->tail_mbuf = NULL;
-       read_queue_e->aux_data = NULL;
-       read_queue_e->stcb = stcb;
-       read_queue_e->port_from = stcb->rport;
-       read_queue_e->do_not_ref_stcb = 0;
-       read_queue_e->end_added = 0;
-       read_queue_e->some_taken = 0;
-       read_queue_e->pdapi_aborted = 0;
-failed_build:
-       return (read_queue_e);
-}
-
-
-/*
- * Build out our readq entry based on the incoming packet.
- */
-static struct sctp_queued_to_read *
-sctp_build_readq_entry_chk(struct sctp_tcb *stcb,
-    struct sctp_tmit_chunk *chk)
-{
-       struct sctp_queued_to_read *read_queue_e = NULL;
-
-       sctp_alloc_a_readq(stcb, read_queue_e);
-       if (read_queue_e == NULL) {
-               goto failed_build;
-       }
-       read_queue_e->sinfo_stream = chk->rec.data.stream_number;
-       read_queue_e->sinfo_ssn = chk->rec.data.stream_seq;
-       read_queue_e->sinfo_flags = (chk->rec.data.rcv_flags << 8);
-       read_queue_e->sinfo_ppid = chk->rec.data.payloadtype;
-       read_queue_e->sinfo_context = stcb->asoc.context;
-       read_queue_e->sinfo_timetolive = 0;
-       read_queue_e->sinfo_tsn = chk->rec.data.TSN_seq;
-       read_queue_e->sinfo_cumtsn = chk->rec.data.TSN_seq;
-       read_queue_e->sinfo_assoc_id = sctp_get_associd(stcb);
-       read_queue_e->whoFrom = chk->whoTo;
-       read_queue_e->aux_data = NULL;
-       read_queue_e->length = 0;
-       atomic_add_int(&chk->whoTo->ref_count, 1);
-       read_queue_e->data = chk->data;
-       read_queue_e->tail_mbuf = NULL;
        read_queue_e->stcb = stcb;
        read_queue_e->port_from = stcb->rport;
-       read_queue_e->spec_flags = 0;
-       read_queue_e->do_not_ref_stcb = 0;
-       read_queue_e->end_added = 0;
-       read_queue_e->some_taken = 0;
-       read_queue_e->pdapi_aborted = 0;
 failed_build:
        return (read_queue_e);
 }
 
-
 struct mbuf *
 sctp_build_ctl_nchunk(struct sctp_inpcb *inp, struct sctp_sndrcvinfo *sinfo)
 {
@@ -317,6 +279,7 @@ sctp_mark_non_revokable(struct sctp_asso
 {
        uint32_t gap, i, cumackp1;
        int fnd = 0;
+       int in_r = 0, in_nr = 0;
 
        if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
                return;
@@ -330,15 +293,20 @@ sctp_mark_non_revokable(struct sctp_asso
                return;
        }
        SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn);
-       if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
+       in_r = SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap);
+       in_nr = SCTP_IS_TSN_PRESENT(asoc->nr_mapping_array, gap);
+       if ((in_r == 0) && (in_nr == 0)) {
+#ifdef INVARIANTS
+               panic("Things are really messed up now");
+#else
                SCTP_PRINTF("gap:%x tsn:%x\n", gap, tsn);
                sctp_print_mapping_array(asoc);
-#ifdef INVARIANTS
-               panic("Things are really messed up now!!");
 #endif
        }
-       SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
-       SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
+       if (in_nr == 0)
+               SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap);
+       if (in_r)
+               SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
        if (SCTP_TSN_GT(tsn, asoc->highest_tsn_inside_nr_map)) {
                asoc->highest_tsn_inside_nr_map = tsn;
        }
@@ -358,191 +326,157 @@ sctp_mark_non_revokable(struct sctp_asso
        }
 }
 
-
-/*
- * We are delivering currently from the reassembly queue. We must continue to
- * deliver until we either: 1) run out of space. 2) run out of sequential
- * TSN's 3) hit the SCTP_DATA_LAST_FRAG flag.
- */
-static void
-sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
+static int
+sctp_place_control_in_stream(struct sctp_stream_in *strm,
+    struct sctp_association *asoc,
+    struct sctp_queued_to_read *control)
 {
-       struct sctp_tmit_chunk *chk, *nchk;
-       uint16_t nxt_todel;
-       uint16_t stream_no;
-       int end = 0;
-       int cntDel;
-       struct sctp_queued_to_read *control, *ctl, *nctl;
-
-       if (stcb == NULL)
-               return;
+       struct sctp_queued_to_read *at;
+       struct sctp_readhead *q;
+       uint8_t bits, unordered;
 
-       cntDel = stream_no = 0;
-       if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
-           (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) ||
-           (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
-               /* socket above is long gone or going.. */
-abandon:
-               asoc->fragmented_delivery_inprogress = 0;
-               TAILQ_FOREACH_SAFE(chk, &asoc->reasmqueue, sctp_next, nchk) {
-                       TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next);
-                       asoc->size_on_reasm_queue -= chk->send_size;
-                       sctp_ucount_decr(asoc->cnt_on_reasm_queue);
-                       /*
-                        * Lose the data pointer, since its in the socket
-                        * buffer
-                        */
-                       if (chk->data) {
-                               sctp_m_freem(chk->data);
-                               chk->data = NULL;
+       bits = (control->sinfo_flags >> 8);
+       unordered = bits & SCTP_DATA_UNORDERED;
+       if (unordered) {
+               q = &strm->uno_inqueue;
+               if (asoc->idata_supported == 0) {
+                       if (!TAILQ_EMPTY(q)) {
+                               /*
+                                * Only one stream can be here in old style
+                                * -- abort
+                                */
+                               return (-1);
                        }
-                       /* Now free the address and data */
-                       sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
-                       /* sa_ignore FREED_MEMORY */
+                       TAILQ_INSERT_TAIL(q, control, next_instrm);
+                       control->on_strm_q = SCTP_ON_UNORDERED;
+                       return (0);
                }
-               return;
+       } else {
+               q = &strm->inqueue;
        }
-       SCTP_TCB_LOCK_ASSERT(stcb);
-       TAILQ_FOREACH_SAFE(chk, &asoc->reasmqueue, sctp_next, nchk) {
-               if (chk->rec.data.TSN_seq != (asoc->tsn_last_delivered + 1)) {
-                       /* Can't deliver more :< */
-                       return;
-               }
-               stream_no = chk->rec.data.stream_number;
-               nxt_todel = asoc->strmin[stream_no].last_sequence_delivered + 1;
-               if (nxt_todel != chk->rec.data.stream_seq &&
-                   (chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) == 0) {
-                       /*
-                        * Not the next sequence to deliver in its stream OR
-                        * unordered
-                        */
-                       return;
-               }
-               if (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) {
-
-                       control = sctp_build_readq_entry_chk(stcb, chk);
-                       if (control == NULL) {
-                               /* out of memory? */
-                               return;
-                       }
-                       /* save it off for our future deliveries */
-                       stcb->asoc.control_pdapi = control;
-                       if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG)
-                               end = 1;
-                       else
-                               end = 0;
-                       sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
-                       sctp_add_to_readq(stcb->sctp_ep,
-                           stcb, control, &stcb->sctp_socket->so_rcv, end,
-                           SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
-                       cntDel++;
+       if ((bits & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) {
+               control->end_added = control->last_frag_seen = 
control->first_frag_seen = 1;
+       }
+       if (TAILQ_EMPTY(q)) {
+               /* Empty queue */
+               TAILQ_INSERT_HEAD(q, control, next_instrm);
+               if (unordered) {
+                       control->on_strm_q = SCTP_ON_UNORDERED;
                } else {
-                       if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG)
-                               end = 1;
-                       else
-                               end = 0;
-                       sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq);
-                       if (sctp_append_to_readq(stcb->sctp_ep, stcb,
-                           stcb->asoc.control_pdapi,
-                           chk->data, end, chk->rec.data.TSN_seq,
-                           &stcb->sctp_socket->so_rcv)) {
+                       control->on_strm_q = SCTP_ON_ORDERED;
+               }
+               return (0);
+       } else {
+               TAILQ_FOREACH(at, q, next_instrm) {
+                       if (SCTP_TSN_GT(at->msg_id, control->msg_id)) {
                                /*
-                                * something is very wrong, either
-                                * control_pdapi is NULL, or the tail_mbuf
-                                * is corrupt, or there is a EOM already on
-                                * the mbuf chain.
+                                * one in queue is bigger than the new one,
+                                * insert before this one
                                 */
-                               if (stcb->asoc.state & 
SCTP_STATE_ABOUT_TO_BE_FREED) {
-                                       goto abandon;
+                               TAILQ_INSERT_BEFORE(at, control, next_instrm);
+                               if (unordered) {
+                                       control->on_strm_q = SCTP_ON_UNORDERED;
                                } else {
-#ifdef INVARIANTS
-                                       if ((stcb->asoc.control_pdapi == NULL) 
|| (stcb->asoc.control_pdapi->tail_mbuf == NULL)) {
-                                               panic("This should not happen 
control_pdapi NULL?");
+                                       control->on_strm_q = SCTP_ON_ORDERED;
+                               }
+                               break;
+                       } else if (at->msg_id == control->msg_id) {
+                               /*
+                                * Gak, He sent me a duplicate msg id
+                                * number?? return -1 to abort.
+                                */
+                               return (-1);
+                       } else {
+                               if (TAILQ_NEXT(at, next_instrm) == NULL) {
+                                       /*
+                                        * We are at the end, insert it
+                                        * after this one
+                                        */
+                                       if 
(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_STR_LOGGING_ENABLE) {
+                                               sctp_log_strm_del(control, at,
+                                                   
SCTP_STR_LOG_FROM_INSERT_TL);
                                        }
-                                       /* if we did not panic, it was a EOM */
-                                       panic("Bad chunking ??");
-#else
-                                       if ((stcb->asoc.control_pdapi == NULL) 
|| (stcb->asoc.control_pdapi->tail_mbuf == NULL)) {
-                                               SCTP_PRINTF("This should not 
happen control_pdapi NULL?\n");
+                                       TAILQ_INSERT_AFTER(q,
+                                           at, control, next_instrm);
+                                       if (unordered) {
+                                               control->on_strm_q = 
SCTP_ON_UNORDERED;
+                                       } else {
+                                               control->on_strm_q = 
SCTP_ON_ORDERED;
                                        }
-                                       SCTP_PRINTF("Bad chunking ??\n");
-                                       SCTP_PRINTF("Dumping re-assembly queue 
this will probably hose the association\n");
-
-#endif
-                                       goto abandon;
+                                       break;
                                }
                        }
-                       cntDel++;
-               }
-               /* pull it we did it */
-               TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next);
-               if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
-                       asoc->fragmented_delivery_inprogress = 0;
-                       if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) == 
0) {
-                               
asoc->strmin[stream_no].last_sequence_delivered++;
-                       }
-                       if ((chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) == 
0) {
-                               SCTP_STAT_INCR_COUNTER64(sctps_reasmusrmsgs);
-                       }
-               } else if (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) {
-                       /*
-                        * turn the flag back on since we just  delivered
-                        * yet another one.
-                        */
-                       asoc->fragmented_delivery_inprogress = 1;
                }
-               asoc->tsn_of_pdapi_last_delivered = chk->rec.data.TSN_seq;
-               asoc->last_flags_delivered = chk->rec.data.rcv_flags;
-               asoc->last_strm_seq_delivered = chk->rec.data.stream_seq;
-               asoc->last_strm_no_delivered = chk->rec.data.stream_number;
+       }
+       return (0);
+}
 
-               asoc->tsn_last_delivered = chk->rec.data.TSN_seq;
-               asoc->size_on_reasm_queue -= chk->send_size;
-               sctp_ucount_decr(asoc->cnt_on_reasm_queue);
-               /* free up the chk */
-               chk->data = NULL;
-               sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
+static void
+sctp_abort_in_reasm(struct sctp_tcb *stcb,
+    struct sctp_stream_in *strm,
+    struct sctp_queued_to_read *control,
+    struct sctp_tmit_chunk *chk,
+    int *abort_flag, int opspot)
+{
+       char msg[SCTP_DIAG_INFO_LEN];
+       struct mbuf *oper;
 
-               if (asoc->fragmented_delivery_inprogress == 0) {
-                       /*
-                        * Now lets see if we can deliver the next one on
-                        * the stream
-                        */
-                       struct sctp_stream_in *strm;
+       if (stcb->asoc.idata_supported) {
+               snprintf(msg, sizeof(msg),
+                   "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);
+       } 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);
+       }
+       oper = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
+       sctp_m_freem(chk->data);
+       chk->data = NULL;
+       sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
+       stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_1;
+       sctp_abort_an_association(stcb->sctp_ep, stcb, oper, 
SCTP_SO_NOT_LOCKED);
+       *abort_flag = 1;
+}
 
-                       strm = &asoc->strmin[stream_no];
-                       nxt_todel = strm->last_sequence_delivered + 1;
-                       TAILQ_FOREACH_SAFE(ctl, &strm->inqueue, next, nctl) {
-                               /* Deliver more if we can. */
-                               if (nxt_todel == ctl->sinfo_ssn) {
-                                       TAILQ_REMOVE(&strm->inqueue, ctl, next);
-                                       asoc->size_on_all_streams -= 
ctl->length;
-                                       
sctp_ucount_decr(asoc->cnt_on_all_streams);
-                                       strm->last_sequence_delivered++;
-                                       sctp_mark_non_revokable(asoc, 
ctl->sinfo_tsn);
-                                       sctp_add_to_readq(stcb->sctp_ep, stcb,
-                                           ctl,
-                                           &stcb->sctp_socket->so_rcv, 1,
-                                           SCTP_READ_LOCK_NOT_HELD, 
SCTP_SO_NOT_LOCKED);
-                               } else {
-                                       break;
-                               }
-                               nxt_todel = strm->last_sequence_delivered + 1;
-                       }
-                       break;
-               }
+static void
+clean_up_control(struct sctp_tcb *stcb, struct sctp_queued_to_read *control)
+{
+       /*
+        * The control could not be placed and must be cleaned.
+        */
+       struct sctp_tmit_chunk *chk, *nchk;
+
+       TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) {
+               TAILQ_REMOVE(&control->reasm, chk, sctp_next);
+               if (chk->data)
+                       sctp_m_freem(chk->data);
+               chk->data = NULL;
+               sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
        }
+       sctp_free_a_readq(stcb, control);
 }
 
 /*
  * Queue the chunk either right into the socket buffer if it is the next one
  * to go OR put it in the correct place in the delivery queue.  If we do
- * append to the so_buf, keep doing so until we are out of order. One big
- * question still remains, what to do when the socket buffer is FULL??
+ * append to the so_buf, keep doing so until we are out of order as
+ * long as the control's entered are non-fragmented.
  */
 static void
-sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
-    struct sctp_queued_to_read *control, int *abort_flag)
+sctp_queue_data_to_stream(struct sctp_tcb *stcb,
+    struct sctp_stream_in *strm,
+    struct sctp_association *asoc,
+    struct sctp_queued_to_read *control, int *abort_flag, int *need_reasm)
 {
        /*
         * FIX-ME maybe? What happens when the ssn wraps? If we are getting
@@ -562,27 +496,16 @@ sctp_queue_data_to_stream(struct sctp_tc
         * SSN alone. Maybe a hybred approach is the answer
         * 
         */
-       struct sctp_stream_in *strm;
        struct sctp_queued_to_read *at;
        int queue_needed;
-       uint16_t nxt_todel;
+       uint32_t nxt_todel;
        struct mbuf *op_err;
        char msg[SCTP_DIAG_INFO_LEN];
 
-       queue_needed = 1;
-       asoc->size_on_all_streams += control->length;
-       sctp_ucount_incr(asoc->cnt_on_all_streams);
-       strm = &asoc->strmin[control->sinfo_stream];
-       nxt_todel = strm->last_sequence_delivered + 1;
        if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_STR_LOGGING_ENABLE) {
                sctp_log_strm_del(control, NULL, SCTP_STR_LOG_FROM_INTO_STRD);
        }
-       SCTPDBG(SCTP_DEBUG_INDATA1,
-           "queue to stream called for sid:%u ssn:%u tsn:%u lastdel:%u 
nxt:%u\n",
-           (uint32_t) control->sinfo_stream, (uint32_t) control->sinfo_ssn,
-           (uint32_t) control->sinfo_tsn,
-           (uint32_t) strm->last_sequence_delivered, (uint32_t) nxt_todel);
-       if (SCTP_SSN_GE(strm->last_sequence_delivered, control->sinfo_ssn)) {
+       if (SCTP_MSGID_GT((!asoc->idata_supported), 
strm->last_sequence_delivered, control->sinfo_ssn)) {
                /* The incoming sseq is behind where we last delivered? */
                SCTPDBG(SCTP_DEBUG_INDATA1, "Duplicate S-SEQ:%d delivered:%d 
from peer, Abort association\n",
                    control->sinfo_ssn, strm->last_sequence_delivered);
@@ -591,32 +514,39 @@ protocol_error:
                 * throw it in the stream so it gets cleaned up in
                 * association destruction
                 */
-               TAILQ_INSERT_HEAD(&strm->inqueue, control, next);
+               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);
                op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, 
msg);
-               stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + 
SCTP_LOC_1;
+               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);
                *abort_flag = 1;
                return;
 
        }
+       if ((SCTP_TSN_GE(asoc->cumulative_tsn, control->sinfo_tsn)) && 
(asoc->idata_supported == 0)) {
+               goto 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) {
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
-       struct socket *so;
+               struct socket *so;
 
-       so = SCTP_INP_SO(stcb->sctp_ep);
-       atomic_add_int(&stcb->asoc.refcnt, 1);
-       SCTP_TCB_UNLOCK(stcb);
-       SCTP_SOCKET_LOCK(so, 1);
-       SCTP_TCB_LOCK(stcb);
-       atomic_subtract_int(&stcb->asoc.refcnt, 1);
-       if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
-               SCTP_SOCKET_UNLOCK(so, 1);
-               return;
-       }
+               so = SCTP_INP_SO(stcb->sctp_ep);
+               atomic_add_int(&stcb->asoc.refcnt, 1);
+               SCTP_TCB_UNLOCK(stcb);
+               SCTP_SOCKET_LOCK(so, 1);
+               SCTP_TCB_LOCK(stcb);
+               atomic_subtract_int(&stcb->asoc.refcnt, 1);
+               if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
+                       SCTP_SOCKET_UNLOCK(so, 1);
+                       return;
+               }
 #endif
-       if (nxt_todel == control->sinfo_ssn) {
                /* can be delivered right away? */
                if (SCTP_BASE_SYSCTL(sctp_logging_level) & 
SCTP_STR_LOGGING_ENABLE) {
                        sctp_log_strm_del(control, NULL, 
SCTP_STR_LOG_FROM_IMMED_DEL);
@@ -626,19 +556,25 @@ protocol_error:
                asoc->size_on_all_streams -= control->length;
                sctp_ucount_decr(asoc->cnt_on_all_streams);
                strm->last_sequence_delivered++;
-
                sctp_mark_non_revokable(asoc, control->sinfo_tsn);
                sctp_add_to_readq(stcb->sctp_ep, stcb,
                    control,
                    &stcb->sctp_socket->so_rcv, 1,
-                   SCTP_READ_LOCK_NOT_HELD, SCTP_SO_LOCKED);
-               TAILQ_FOREACH_SAFE(control, &strm->inqueue, next, at) {
+                   SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_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) {
-                               TAILQ_REMOVE(&strm->inqueue, control, next);
+                       if ((nxt_todel == control->sinfo_ssn) &&
+                           (((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);
+                               if (control->on_strm_q == SCTP_ON_ORDERED) {
+                                       TAILQ_REMOVE(&strm->inqueue, control, 
next_instrm);
+                               } else {
+                                       panic("Huh control:%p is on_strm_q:%d",
+                                           control, control->on_strm_q);
+                               }
+                               control->on_strm_q = 0;
                                strm->last_sequence_delivered++;
                                /*
                                 * We ignore the return of deliver_data here
@@ -655,655 +591,1000 @@ protocol_error:
                                    control,
                                    &stcb->sctp_socket->so_rcv, 1,
                                    SCTP_READ_LOCK_NOT_HELD,
-                                   SCTP_SO_LOCKED);
+                                   SCTP_SO_NOT_LOCKED);
                                continue;
+                       } else if (nxt_todel == control->sinfo_ssn) {
+                               *need_reasm = 1;
                        }
                        break;
                }
+#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
+               SCTP_SOCKET_UNLOCK(so, 1);
+#endif
        }
        if (queue_needed) {
                /*
                 * Ok, we did not deliver this guy, find the correct place
                 * to put it on the queue.
                 */
-               if (SCTP_TSN_GE(asoc->cumulative_tsn, control->sinfo_tsn)) {
-#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
-                       SCTP_SOCKET_UNLOCK(so, 1);
-#endif
-                       goto protocol_error;
-               }
-               if (TAILQ_EMPTY(&strm->inqueue)) {
-                       /* Empty queue */
-                       if (SCTP_BASE_SYSCTL(sctp_logging_level) & 
SCTP_STR_LOGGING_ENABLE) {
-                               sctp_log_strm_del(control, NULL, 
SCTP_STR_LOG_FROM_INSERT_HD);
-                       }
-                       TAILQ_INSERT_HEAD(&strm->inqueue, control, next);
-               } else {
-                       TAILQ_FOREACH(at, &strm->inqueue, next) {
-                               if (SCTP_SSN_GT(at->sinfo_ssn, 
control->sinfo_ssn)) {
-                                       /*
-                                        * one in queue is bigger than the
-                                        * new one, insert before this one
-                                        */
-                                       if 
(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_STR_LOGGING_ENABLE) {
-                                               sctp_log_strm_del(control, at,
-                                                   
SCTP_STR_LOG_FROM_INSERT_MD);
-                                       }
-                                       TAILQ_INSERT_BEFORE(at, control, next);
-                                       break;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to