Home | History | Annotate | Download | only in sctp
      1      0    stevel /*
      2      0    stevel  * CDDL HEADER START
      3      0    stevel  *
      4      0    stevel  * The contents of this file are subject to the terms of the
      5   1676       jpk  * Common Development and Distribution License (the "License").
      6   1676       jpk  * You may not use this file except in compliance with the License.
      7      0    stevel  *
      8      0    stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9      0    stevel  * or http://www.opensolaris.org/os/licensing.
     10      0    stevel  * See the License for the specific language governing permissions
     11      0    stevel  * and limitations under the License.
     12      0    stevel  *
     13      0    stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14      0    stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15      0    stevel  * If applicable, add the following below this CDDL HEADER, with the
     16      0    stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17      0    stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18      0    stevel  *
     19      0    stevel  * CDDL HEADER END
     20      0    stevel  */
     21   1735    kcpoon 
     22      0    stevel /*
     23   8778      Erik  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24      0    stevel  * Use is subject to license terms.
     25      0    stevel  */
     26      0    stevel 
     27      0    stevel #include <sys/types.h>
     28      0    stevel #include <sys/systm.h>
     29      0    stevel #include <sys/stream.h>
     30      0    stevel #include <sys/cmn_err.h>
     31      0    stevel #define	_SUN_TPI_VERSION 2
     32      0    stevel #include <sys/tihdr.h>
     33      0    stevel #include <sys/socket.h>
     34      0    stevel #include <sys/stropts.h>
     35      0    stevel #include <sys/strsun.h>
     36      0    stevel #include <sys/strsubr.h>
     37      0    stevel #include <sys/socketvar.h>
     38      0    stevel #include <inet/common.h>
     39      0    stevel #include <inet/mi.h>
     40      0    stevel #include <inet/ip.h>
     41  11042      Erik #include <inet/ip_ire.h>
     42      0    stevel #include <inet/ip6.h>
     43      0    stevel #include <inet/sctp_ip.h>
     44      0    stevel #include <inet/ipclassifier.h>
     45      0    stevel 
     46      0    stevel /*
     47      0    stevel  * PR-SCTP comments.
     48      0    stevel  *
     49      0    stevel  * A message can expire before it gets to the transmit list (i.e. it is still
     50      0    stevel  * in the unsent list - unchunked), after it gets to the transmit list, but
     51      0    stevel  * before transmission has actually started, or after transmission has begun.
     52      0    stevel  * Accordingly, we check for the status of a message in sctp_chunkify() when
     53      0    stevel  * the message is being transferred from the unsent list to the transmit list;
     54      0    stevel  * in sctp_get_msg_to_send(), when we get the next chunk from the transmit
     55      0    stevel  * list and in sctp_rexmit() when we get the next chunk to be (re)transmitted.
     56      0    stevel  * When we nuke a message in sctp_chunkify(), all we need to do is take it
     57      0    stevel  * out of the unsent list and update sctp_unsent; when a message is deemed
     58      0    stevel  * timed-out in sctp_get_msg_to_send() we can just take it out of the transmit
     59      0    stevel  * list, update sctp_unsent IFF transmission for the message has not yet begun
     60      0    stevel  * (i.e. !SCTP_CHUNK_ISSENT(meta->b_cont)). However, if transmission for the
     61      0    stevel  * message has started, then we cannot just take it out of the list, we need
     62      0    stevel  * to send Forward TSN chunk to the peer so that the peer can clear its
     63      0    stevel  * fragment list for this message. However, we cannot just send the Forward
     64      0    stevel  * TSN in sctp_get_msg_to_send() because there might be unacked chunks for
     65      0    stevel  * messages preceeding this abandoned message. So, we send a Forward TSN
     66      0    stevel  * IFF all messages prior to this abandoned message has been SACKd, if not
     67      0    stevel  * we defer sending the Forward TSN to sctp_cumack(), which will check for
     68      0    stevel  * this condition and send the Forward TSN via sctp_check_abandoned_msg(). In
     69      0    stevel  * sctp_rexmit() when we check for retransmissions, we need to determine if
     70      0    stevel  * the advanced peer ack point can be moved ahead, and if so, send a Forward
     71      0    stevel  * TSN to the peer instead of retransmitting the chunk. Note that when
     72      0    stevel  * we send a Forward TSN for a message, there may be yet unsent chunks for
     73      0    stevel  * this message; we need to mark all such chunks as abandoned, so that
     74      0    stevel  * sctp_cumack() can take the message out of the transmit list, additionally
     75      0    stevel  * sctp_unsent need to be adjusted. Whenever sctp_unsent is updated (i.e.
     76      0    stevel  * decremented when a message/chunk is deemed abandoned), sockfs needs to
     77      0    stevel  * be notified so that it can adjust its idea of the queued message.
     78      0    stevel  */
     79      0    stevel 
     80      0    stevel #include "sctp_impl.h"
     81      0    stevel 
     82      0    stevel static struct kmem_cache	*sctp_kmem_ftsn_set_cache;
     83  10037      Nick static mblk_t			*sctp_chunkify(sctp_t *, int, int, int);
     84      0    stevel 
     85      0    stevel #ifdef	DEBUG
     86      0    stevel static boolean_t	sctp_verify_chain(mblk_t *, mblk_t *);
     87      0    stevel #endif
     88      0    stevel 
     89      0    stevel /*
     90      0    stevel  * Called to allocate a header mblk when sending data to SCTP.
     91      0    stevel  * Data will follow in b_cont of this mblk.
     92      0    stevel  */
     93      0    stevel mblk_t *
     94      0    stevel sctp_alloc_hdr(const char *name, int nlen, const char *control, int clen,
     95      0    stevel     int flags)
     96      0    stevel {
     97      0    stevel 	mblk_t *mp;
     98      0    stevel 	struct T_unitdata_req *tudr;
     99      0    stevel 	size_t size;
    100      0    stevel 	int error;
    101      0    stevel 
    102      0    stevel 	size = sizeof (*tudr) + _TPI_ALIGN_TOPT(nlen) + clen;
    103      0    stevel 	size = MAX(size, sizeof (sctp_msg_hdr_t));
    104      0    stevel 	if (flags & SCTP_CAN_BLOCK) {
    105      0    stevel 		mp = allocb_wait(size, BPRI_MED, 0, &error);
    106      0    stevel 	} else {
    107      0    stevel 		mp = allocb(size, BPRI_MED);
    108      0    stevel 	}
    109      0    stevel 	if (mp) {
    110      0    stevel 		tudr = (struct T_unitdata_req *)mp->b_rptr;
    111      0    stevel 		tudr->PRIM_type = T_UNITDATA_REQ;
    112      0    stevel 		tudr->DEST_length = nlen;
    113      0    stevel 		tudr->DEST_offset = sizeof (*tudr);
    114      0    stevel 		tudr->OPT_length = clen;
    115      0    stevel 		tudr->OPT_offset = (t_scalar_t)(sizeof (*tudr) +
    116      0    stevel 		    _TPI_ALIGN_TOPT(nlen));
    117      0    stevel 		if (nlen > 0)
    118      0    stevel 			bcopy(name, tudr + 1, nlen);
    119      0    stevel 		if (clen > 0)
    120      0    stevel 			bcopy(control, (char *)tudr + tudr->OPT_offset, clen);
    121      0    stevel 		mp->b_wptr += (tudr ->OPT_offset + clen);
    122      0    stevel 		mp->b_datap->db_type = M_PROTO;
    123      0    stevel 	}
    124      0    stevel 	return (mp);
    125      0    stevel }
    126      0    stevel 
    127      0    stevel /*ARGSUSED2*/
    128      0    stevel int
    129      0    stevel sctp_sendmsg(sctp_t *sctp, mblk_t *mp, int flags)
    130      0    stevel {
    131      0    stevel 	sctp_faddr_t	*fp = NULL;
    132      0    stevel 	struct T_unitdata_req	*tudr;
    133      0    stevel 	int		error = 0;
    134      0    stevel 	mblk_t		*mproto = mp;
    135      0    stevel 	in6_addr_t	*addr;
    136      0    stevel 	in6_addr_t	tmpaddr;
    137      0    stevel 	uint16_t	sid = sctp->sctp_def_stream;
    138      0    stevel 	uint32_t	ppid = sctp->sctp_def_ppid;
    139      0    stevel 	uint32_t	context = sctp->sctp_def_context;
    140      0    stevel 	uint16_t	msg_flags = sctp->sctp_def_flags;
    141      0    stevel 	sctp_msg_hdr_t	*sctp_msg_hdr;
    142      0    stevel 	uint32_t	msg_len = 0;
    143      0    stevel 	uint32_t	timetolive = sctp->sctp_def_timetolive;
    144  11042      Erik 	conn_t		*connp = sctp->sctp_connp;
    145      0    stevel 
    146      0    stevel 	ASSERT(DB_TYPE(mproto) == M_PROTO);
    147      0    stevel 
    148      0    stevel 	mp = mp->b_cont;
    149      0    stevel 	ASSERT(mp == NULL || DB_TYPE(mp) == M_DATA);
    150      0    stevel 
    151      0    stevel 	tudr = (struct T_unitdata_req *)mproto->b_rptr;
    152      0    stevel 	ASSERT(tudr->PRIM_type == T_UNITDATA_REQ);
    153      0    stevel 
    154      0    stevel 	/* Get destination address, if specified */
    155      0    stevel 	if (tudr->DEST_length > 0) {
    156      0    stevel 		sin_t *sin;
    157      0    stevel 		sin6_t *sin6;
    158      0    stevel 
    159      0    stevel 		sin = (struct sockaddr_in *)
    160      0    stevel 		    (mproto->b_rptr + tudr->DEST_offset);
    161      0    stevel 		switch (sin->sin_family) {
    162      0    stevel 		case AF_INET:
    163      0    stevel 			if (tudr->DEST_length < sizeof (*sin)) {
    164      0    stevel 				return (EINVAL);
    165      0    stevel 			}
    166      0    stevel 			IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &tmpaddr);
    167      0    stevel 			addr = &tmpaddr;
    168      0    stevel 			break;
    169      0    stevel 		case AF_INET6:
    170      0    stevel 			if (tudr->DEST_length < sizeof (*sin6)) {
    171      0    stevel 				return (EINVAL);
    172      0    stevel 			}
    173      0    stevel 			sin6 = (struct sockaddr_in6 *)
    174      0    stevel 			    (mproto->b_rptr + tudr->DEST_offset);
    175      0    stevel 			addr = &sin6->sin6_addr;
    176      0    stevel 			break;
    177      0    stevel 		default:
    178      0    stevel 			return (EAFNOSUPPORT);
    179      0    stevel 		}
    180      0    stevel 		fp = sctp_lookup_faddr(sctp, addr);
    181      0    stevel 		if (fp == NULL) {
    182      0    stevel 			return (EINVAL);
    183      0    stevel 		}
    184      0    stevel 	}
    185      0    stevel 	/* Ancillary Data? */
    186      0    stevel 	if (tudr->OPT_length > 0) {
    187      0    stevel 		struct cmsghdr		*cmsg;
    188      0    stevel 		char			*cend;
    189      0    stevel 		struct sctp_sndrcvinfo	*sndrcv;
    190      0    stevel 
    191      0    stevel 		cmsg = (struct cmsghdr *)(mproto->b_rptr + tudr->OPT_offset);
    192      0    stevel 		cend = ((char *)cmsg + tudr->OPT_length);
    193      0    stevel 		ASSERT(cend <= (char *)mproto->b_wptr);
    194      0    stevel 
    195      0    stevel 		for (;;) {
    196      0    stevel 			if ((char *)(cmsg + 1) > cend ||
    197      0    stevel 			    ((char *)cmsg + cmsg->cmsg_len) > cend) {
    198      0    stevel 				break;
    199      0    stevel 			}
    200      0    stevel 			if ((cmsg->cmsg_level == IPPROTO_SCTP) &&
    201      0    stevel 			    (cmsg->cmsg_type == SCTP_SNDRCV)) {
    202      0    stevel 				if (cmsg->cmsg_len <
    203      0    stevel 				    (sizeof (*sndrcv) + sizeof (*cmsg))) {
    204      0    stevel 					return (EINVAL);
    205      0    stevel 				}
    206      0    stevel 				sndrcv = (struct sctp_sndrcvinfo *)(cmsg + 1);
    207      0    stevel 				sid = sndrcv->sinfo_stream;
    208      0    stevel 				msg_flags = sndrcv->sinfo_flags;
    209      0    stevel 				ppid = sndrcv->sinfo_ppid;
    210      0    stevel 				context = sndrcv->sinfo_context;
    211      0    stevel 				timetolive = sndrcv->sinfo_timetolive;
    212      0    stevel 				break;
    213      0    stevel 			}
    214      0    stevel 			if (cmsg->cmsg_len > 0)
    215      0    stevel 				cmsg = CMSG_NEXT(cmsg);
    216      0    stevel 			else
    217      0    stevel 				break;
    218      0    stevel 		}
    219      0    stevel 	}
    220      0    stevel 	if (msg_flags & MSG_ABORT) {
    221      0    stevel 		if (mp && mp->b_cont) {
    222      0    stevel 			mblk_t *pump = msgpullup(mp, -1);
    223      0    stevel 			if (!pump) {
    224      0    stevel 				return (ENOMEM);
    225      0    stevel 			}
    226      0    stevel 			freemsg(mp);
    227      0    stevel 			mp = pump;
    228      0    stevel 			mproto->b_cont = mp;
    229      0    stevel 		}
    230      0    stevel 		RUN_SCTP(sctp);
    231   7480  Kacheong 		sctp_user_abort(sctp, mp);
    232      0    stevel 		freemsg(mproto);
    233  11042      Erik 		goto done2;
    234      0    stevel 	}
    235      0    stevel 	if (mp == NULL)
    236      0    stevel 		goto done;
    237      0    stevel 
    238      0    stevel 	RUN_SCTP(sctp);
    239      0    stevel 
    240      0    stevel 	/* Reject any new data requests if we are shutting down */
    241   4505    kcpoon 	if (sctp->sctp_state > SCTPS_ESTABLISHED ||
    242   4505    kcpoon 	    (sctp->sctp_connp->conn_state_flags & CONN_CLOSING)) {
    243      0    stevel 		error = EPIPE;
    244      0    stevel 		goto unlock_done;
    245      0    stevel 	}
    246      0    stevel 
    247      0    stevel 	/* Re-use the mproto to store relevant info. */
    248      0    stevel 	ASSERT(MBLKSIZE(mproto) >= sizeof (*sctp_msg_hdr));
    249      0    stevel 
    250      0    stevel 	mproto->b_rptr = mproto->b_datap->db_base;
    251      0    stevel 	mproto->b_wptr = mproto->b_rptr + sizeof (*sctp_msg_hdr);
    252      0    stevel 
    253      0    stevel 	sctp_msg_hdr = (sctp_msg_hdr_t *)mproto->b_rptr;
    254      0    stevel 	bzero(sctp_msg_hdr, sizeof (*sctp_msg_hdr));
    255      0    stevel 	sctp_msg_hdr->smh_context = context;
    256      0    stevel 	sctp_msg_hdr->smh_sid = sid;
    257      0    stevel 	sctp_msg_hdr->smh_ppid = ppid;
    258      0    stevel 	sctp_msg_hdr->smh_flags = msg_flags;
    259      0    stevel 	sctp_msg_hdr->smh_ttl = MSEC_TO_TICK(timetolive);
    260  11066    rafael 	sctp_msg_hdr->smh_tob = ddi_get_lbolt64();
    261      0    stevel 	for (; mp != NULL; mp = mp->b_cont)
    262      0    stevel 		msg_len += MBLKL(mp);
    263      0    stevel 	sctp_msg_hdr->smh_msglen = msg_len;
    264      0    stevel 
    265      0    stevel 	/* User requested specific destination */
    266      0    stevel 	SCTP_SET_CHUNK_DEST(mproto, fp);
    267      0    stevel 
    268      0    stevel 	if (sctp->sctp_state >= SCTPS_COOKIE_ECHOED &&
    269      0    stevel 	    sid >= sctp->sctp_num_ostr) {
    270      0    stevel 		/* Send sendfail event */
    271      0    stevel 		sctp_sendfail_event(sctp, dupmsg(mproto), SCTP_ERR_BAD_SID,
    272      0    stevel 		    B_FALSE);
    273      0    stevel 		error = EINVAL;
    274      0    stevel 		goto unlock_done;
    275      0    stevel 	}
    276      0    stevel 
    277      0    stevel 	/* no data */
    278      0    stevel 	if (msg_len == 0) {
    279      0    stevel 		sctp_sendfail_event(sctp, dupmsg(mproto),
    280      0    stevel 		    SCTP_ERR_NO_USR_DATA, B_FALSE);
    281      0    stevel 		error = EINVAL;
    282      0    stevel 		goto unlock_done;
    283      0    stevel 	}
    284      0    stevel 
    285      0    stevel 	/* Add it to the unsent list */
    286      0    stevel 	if (sctp->sctp_xmit_unsent == NULL) {
    287      0    stevel 		sctp->sctp_xmit_unsent = sctp->sctp_xmit_unsent_tail = mproto;
    288      0    stevel 	} else {
    289      0    stevel 		sctp->sctp_xmit_unsent_tail->b_next = mproto;
    290      0    stevel 		sctp->sctp_xmit_unsent_tail = mproto;
    291      0    stevel 	}
    292      0    stevel 	sctp->sctp_unsent += msg_len;
    293      0    stevel 	BUMP_LOCAL(sctp->sctp_msgcount);
    294   8348      Eric 	/*
    295   8348      Eric 	 * Notify sockfs if the tx queue is full.
    296   8348      Eric 	 */
    297  11042      Erik 	if (SCTP_TXQ_LEN(sctp) >= connp->conn_sndbuf) {
    298   8348      Eric 		sctp->sctp_txq_full = 1;
    299   8348      Eric 		sctp->sctp_ulp_xmitted(sctp->sctp_ulpd, B_TRUE);
    300   8348      Eric 	}
    301      0    stevel 	if (sctp->sctp_state == SCTPS_ESTABLISHED)
    302   3795    kcpoon 		sctp_output(sctp, UINT_MAX);
    303  11042      Erik done2:
    304      0    stevel 	WAKE_SCTP(sctp);
    305      0    stevel 	return (0);
    306      0    stevel unlock_done:
    307      0    stevel 	WAKE_SCTP(sctp);
    308      0    stevel done:
    309      0    stevel 	return (error);
    310      0    stevel }
    311      0    stevel 
    312  10037      Nick /*
    313  10037      Nick  * While there are messages on sctp_xmit_unsent, detach each one. For each:
    314  10037      Nick  * allocate space for the chunk header, fill in the data chunk, and fill in
    315  10037      Nick  * the chunk header. Then append it to sctp_xmit_tail.
    316  10037      Nick  * Return after appending as many bytes as required (bytes_to_send).
    317  10037      Nick  * We also return if we've appended one or more chunks, and find a subsequent
    318  10037      Nick  * unsent message is too big to fit in the segment.
    319  10037      Nick  */
    320  10037      Nick mblk_t *
    321  10037      Nick sctp_chunkify(sctp_t *sctp, int mss, int firstseg_len, int bytes_to_send)
    322      0    stevel {
    323      0    stevel 	mblk_t			*mp;
    324      0    stevel 	mblk_t			*chunk_mp;
    325      0    stevel 	mblk_t			*chunk_head;
    326      0    stevel 	mblk_t			*chunk_hdr;
    327      0    stevel 	mblk_t			*chunk_tail = NULL;
    328      0    stevel 	int			count;
    329      0    stevel 	int			chunksize;
    330      0    stevel 	sctp_data_hdr_t		*sdc;
    331      0    stevel 	mblk_t			*mdblk = sctp->sctp_xmit_unsent;
    332      0    stevel 	sctp_faddr_t		*fp;
    333      0    stevel 	sctp_faddr_t		*fp1;
    334      0    stevel 	size_t			xtralen;
    335      0    stevel 	sctp_msg_hdr_t		*msg_hdr;
    336  10037      Nick 	sctp_stack_t		*sctps = sctp->sctp_sctps;
    337  10037      Nick 	sctp_msg_hdr_t		*next_msg_hdr;
    338  10037      Nick 	size_t			nextlen;
    339  10037      Nick 	int			remaining_len = mss - firstseg_len;
    340  10037      Nick 
    341  10037      Nick 	ASSERT(remaining_len >= 0);
    342      0    stevel 
    343      0    stevel 	fp = SCTP_CHUNK_DEST(mdblk);
    344      0    stevel 	if (fp == NULL)
    345      0    stevel 		fp = sctp->sctp_current;
    346      0    stevel 	if (fp->isv4)
    347   3448  dh155122 		xtralen = sctp->sctp_hdr_len + sctps->sctps_wroff_xtra +
    348   3448  dh155122 		    sizeof (*sdc);
    349      0    stevel 	else
    350   3448  dh155122 		xtralen = sctp->sctp_hdr6_len + sctps->sctps_wroff_xtra +
    351   3448  dh155122 		    sizeof (*sdc);
    352  10037      Nick 	count = chunksize = remaining_len - sizeof (*sdc);
    353      0    stevel nextmsg:
    354  10037      Nick 	next_msg_hdr = (sctp_msg_hdr_t *)sctp->sctp_xmit_unsent->b_rptr;
    355  10037      Nick 	nextlen = next_msg_hdr->smh_msglen;
    356  10037      Nick 	/*
    357  10037      Nick 	 * Will the entire next message fit in the current packet ?
    358  10037      Nick 	 * if not, leave it on the unsent list.
    359  10037      Nick 	 */
    360  10037      Nick 	if ((firstseg_len != 0) && (nextlen > remaining_len))
    361  10037      Nick 		return (NULL);
    362  10037      Nick 
    363      0    stevel 	chunk_mp = mdblk->b_cont;
    364      0    stevel 
    365      0    stevel 	/*
    366  10037      Nick 	 * If this partially chunked, we ignore the next one for now and
    367  10037      Nick 	 * use the one already present. For the unchunked bits, we use the
    368  10037      Nick 	 * length of the last chunk.
    369      0    stevel 	 */
    370      0    stevel 	if (SCTP_IS_MSG_CHUNKED(mdblk)) {
    371      0    stevel 		int	chunk_len;
    372      0    stevel 
    373      0    stevel 		ASSERT(chunk_mp->b_next != NULL);
    374      0    stevel 		mdblk->b_cont = chunk_mp->b_next;
    375      0    stevel 		chunk_mp->b_next = NULL;
    376      0    stevel 		SCTP_MSG_CLEAR_CHUNKED(mdblk);
    377      0    stevel 		mp = mdblk->b_cont;
    378      0    stevel 		while (mp->b_next != NULL)
    379      0    stevel 			mp = mp->b_next;
    380      0    stevel 		chunk_len = ntohs(((sctp_data_hdr_t *)mp->b_rptr)->sdh_len);
    381      0    stevel 		if (fp->sfa_pmss - chunk_len > sizeof (*sdc))
    382      0    stevel 			count = chunksize = fp->sfa_pmss - chunk_len;
    383      0    stevel 		else
    384      0    stevel 			count = chunksize = fp->sfa_pmss;
    385      0    stevel 		count = chunksize = count - sizeof (*sdc);
    386      0    stevel 	} else {
    387      0    stevel 		msg_hdr = (sctp_msg_hdr_t *)mdblk->b_rptr;
    388      0    stevel 		if (SCTP_MSG_TO_BE_ABANDONED(mdblk, msg_hdr, sctp)) {
    389      0    stevel 			sctp->sctp_xmit_unsent = mdblk->b_next;
    390      0    stevel 			if (sctp->sctp_xmit_unsent == NULL)
    391      0    stevel 				sctp->sctp_xmit_unsent_tail = NULL;
    392      0    stevel 			ASSERT(sctp->sctp_unsent >= msg_hdr->smh_msglen);
    393      0    stevel 			sctp->sctp_unsent -= msg_hdr->smh_msglen;
    394      0    stevel 			mdblk->b_next = NULL;
    395      0    stevel 			BUMP_LOCAL(sctp->sctp_prsctpdrop);
    396      0    stevel 			/*
    397      0    stevel 			 * Update ULP the amount of queued data, which is
    398      0    stevel 			 * sent-unack'ed + unsent.
    399      0    stevel 			 */
    400   8348      Eric 			if (!SCTP_IS_DETACHED(sctp))
    401   8348      Eric 				SCTP_TXQ_UPDATE(sctp);
    402      0    stevel 			sctp_sendfail_event(sctp, mdblk, 0, B_FALSE);
    403      0    stevel 			goto try_next;
    404      0    stevel 		}
    405      0    stevel 		mdblk->b_cont = NULL;
    406      0    stevel 	}
    407      0    stevel 	msg_hdr = (sctp_msg_hdr_t *)mdblk->b_rptr;
    408      0    stevel nextchunk:
    409      0    stevel 	chunk_head = chunk_mp;
    410      0    stevel 	chunk_tail = NULL;
    411      0    stevel 
    412      0    stevel 	/* Skip as many mblk's as we need */
    413      0    stevel 	while (chunk_mp != NULL && ((count - MBLKL(chunk_mp)) >= 0)) {
    414      0    stevel 		count -= MBLKL(chunk_mp);
    415      0    stevel 		chunk_tail = chunk_mp;
    416      0    stevel 		chunk_mp = chunk_mp->b_cont;
    417      0    stevel 	}
    418      0    stevel 	/* Split the chain, if needed */
    419      0    stevel 	if (chunk_mp != NULL) {
    420      0    stevel 		if (count > 0) {
    421      0    stevel 			mblk_t	*split_mp = dupb(chunk_mp);
    422      0    stevel 
    423      0    stevel 			if (split_mp == NULL) {
    424      0    stevel 				if (mdblk->b_cont == NULL) {
    425      0    stevel 					mdblk->b_cont = chunk_head;
    426      0    stevel 				} else  {
    427      0    stevel 					SCTP_MSG_SET_CHUNKED(mdblk);
    428      0    stevel 					ASSERT(chunk_head->b_next == NULL);
    429      0    stevel 					chunk_head->b_next = mdblk->b_cont;
    430      0    stevel 					mdblk->b_cont = chunk_head;
    431      0    stevel 				}
    432  10037      Nick 				return (sctp->sctp_xmit_tail);
    433      0    stevel 			}
    434      0    stevel 			if (chunk_tail != NULL) {
    435      0    stevel 				chunk_tail->b_cont = split_mp;
    436      0    stevel 				chunk_tail = chunk_tail->b_cont;
    437      0    stevel 			} else {
    438      0    stevel 				chunk_head = chunk_tail = split_mp;
    439      0    stevel 			}
    440      0    stevel 			chunk_tail->b_wptr = chunk_tail->b_rptr + count;
    441      0    stevel 			chunk_mp->b_rptr = chunk_tail->b_wptr;
    442      0    stevel 			count = 0;
    443      0    stevel 		} else if (chunk_tail == NULL) {
    444      0    stevel 			goto next;
    445      0    stevel 		} else {
    446      0    stevel 			chunk_tail->b_cont = NULL;
    447      0    stevel 		}
    448      0    stevel 	}
    449      0    stevel 	/* Alloc chunk hdr, if needed */
    450      0    stevel 	if (DB_REF(chunk_head) > 1 ||
    451      0    stevel 	    ((intptr_t)chunk_head->b_rptr) & (SCTP_ALIGN - 1) ||
    452      0    stevel 	    MBLKHEAD(chunk_head) < sizeof (*sdc)) {
    453      0    stevel 		if ((chunk_hdr = allocb(xtralen, BPRI_MED)) == NULL) {
    454      0    stevel 			if (mdblk->b_cont == NULL) {
    455      0    stevel 				if (chunk_mp != NULL)
    456      0    stevel 					linkb(chunk_head, chunk_mp);
    457      0    stevel 				mdblk->b_cont = chunk_head;
    458      0    stevel 			} else {
    459      0    stevel 				SCTP_MSG_SET_CHUNKED(mdblk);
    460      0    stevel 				if (chunk_mp != NULL)
    461      0    stevel 					linkb(chunk_head, chunk_mp);
    462      0    stevel 				ASSERT(chunk_head->b_next == NULL);
    463      0    stevel 				chunk_head->b_next = mdblk->b_cont;
    464      0    stevel 				mdblk->b_cont = chunk_head;
    465      0    stevel 			}
    466  10037      Nick 			return (sctp->sctp_xmit_tail);
    467      0    stevel 		}
    468      0    stevel 		chunk_hdr->b_rptr += xtralen - sizeof (*sdc);
    469      0    stevel 		chunk_hdr->b_wptr = chunk_hdr->b_rptr + sizeof (*sdc);
    470      0    stevel 		chunk_hdr->b_cont = chunk_head;
    471      0    stevel 	} else {
    472      0    stevel 		chunk_hdr = chunk_head;
    473      0    stevel 		chunk_hdr->b_rptr -= sizeof (*sdc);
    474      0    stevel 	}
    475      0    stevel 	ASSERT(chunk_hdr->b_datap->db_ref == 1);
    476      0    stevel 	sdc = (sctp_data_hdr_t *)chunk_hdr->b_rptr;
    477      0    stevel 	sdc->sdh_id = CHUNK_DATA;
    478      0    stevel 	sdc->sdh_flags = 0;
    479      0    stevel 	sdc->sdh_len = htons(sizeof (*sdc) + chunksize - count);
    480      0    stevel 	ASSERT(sdc->sdh_len);
    481      0    stevel 	sdc->sdh_sid = htons(msg_hdr->smh_sid);
    482      0    stevel 	/*
    483      0    stevel 	 * We defer assigning the SSN just before sending the chunk, else
    484      0    stevel 	 * if we drop the chunk in sctp_get_msg_to_send(), we would need
    485      0    stevel 	 * to send a Forward TSN to let the peer know. Some more comments
    486      0    stevel 	 * about this in sctp_impl.h for SCTP_CHUNK_SENT.
    487      0    stevel 	 */
    488      0    stevel 	sdc->sdh_payload_id = msg_hdr->smh_ppid;
    489      0    stevel 
    490      0    stevel 	if (mdblk->b_cont == NULL) {
    491      0    stevel 		mdblk->b_cont = chunk_hdr;
    492      0    stevel 		SCTP_DATA_SET_BBIT(sdc);
    493      0    stevel 	} else {
    494      0    stevel 		mp = mdblk->b_cont;
    495      0    stevel 		while (mp->b_next != NULL)
    496      0    stevel 			mp = mp->b_next;
    497      0    stevel 		mp->b_next = chunk_hdr;
    498      0    stevel 	}
    499      0    stevel 
    500      0    stevel 	bytes_to_send -= (chunksize - count);
    501      0    stevel 	if (chunk_mp != NULL) {
    502      0    stevel next:
    503      0    stevel 		count = chunksize = fp->sfa_pmss - sizeof (*sdc);
    504      0    stevel 		goto nextchunk;
    505      0    stevel 	}
    506      0    stevel 	SCTP_DATA_SET_EBIT(sdc);
    507      0    stevel 	sctp->sctp_xmit_unsent = mdblk->b_next;
    508      0    stevel 	if (mdblk->b_next == NULL) {
    509      0    stevel 		sctp->sctp_xmit_unsent_tail = NULL;
    510      0    stevel 	}
    511      0    stevel 	mdblk->b_next = NULL;
    512      0    stevel 
    513      0    stevel 	if (sctp->sctp_xmit_tail == NULL) {
    514      0    stevel 		sctp->sctp_xmit_head = sctp->sctp_xmit_tail = mdblk;
    515      0    stevel 	} else {
    516      0    stevel 		mp = sctp->sctp_xmit_tail;
    517      0    stevel 		while (mp->b_next != NULL)
    518      0    stevel 			mp = mp->b_next;
    519      0    stevel 		mp->b_next = mdblk;
    520      0    stevel 		mdblk->b_prev = mp;
    521      0    stevel 	}
    522      0    stevel try_next:
    523      0    stevel 	if (bytes_to_send > 0 && sctp->sctp_xmit_unsent != NULL) {
    524      0    stevel 		mdblk = sctp->sctp_xmit_unsent;
    525      0    stevel 		fp1 = SCTP_CHUNK_DEST(mdblk);
    526      0    stevel 		if (fp1 == NULL)
    527      0    stevel 			fp1 = sctp->sctp_current;
    528      0    stevel 		if (fp == fp1) {
    529      0    stevel 			size_t len = MBLKL(mdblk->b_cont);
    530      0    stevel 			if ((count > 0) &&
    531      0    stevel 			    ((len > fp->sfa_pmss - sizeof (*sdc)) ||
    532   4505    kcpoon 			    (len <= count))) {
    533      0    stevel 				count -= sizeof (*sdc);
    534      0    stevel 				count = chunksize = count - (count & 0x3);
    535      0    stevel 			} else {
    536      0    stevel 				count = chunksize = fp->sfa_pmss -
    537      0    stevel 				    sizeof (*sdc);
    538      0    stevel 			}
    539      0    stevel 		} else {
    540      0    stevel 			if (fp1->isv4)
    541      0    stevel 				xtralen = sctp->sctp_hdr_len;
    542      0    stevel 			else
    543      0    stevel 				xtralen = sctp->sctp_hdr6_len;
    544   3448  dh155122 			xtralen += sctps->sctps_wroff_xtra + sizeof (*sdc);
    545      0    stevel 			count = chunksize = fp1->sfa_pmss - sizeof (*sdc);
    546      0    stevel 			fp = fp1;
    547      0    stevel 		}
    548      0    stevel 		goto nextmsg;
    549      0    stevel 	}
    550  10037      Nick 	return (sctp->sctp_xmit_tail);
    551      0    stevel }
    552      0    stevel 
    553      0    stevel void
    554      0    stevel sctp_free_msg(mblk_t *ump)
    555      0    stevel {
    556      0    stevel 	mblk_t *mp, *nmp;
    557      0    stevel 
    558      0    stevel 	for (mp = ump->b_cont; mp; mp = nmp) {
    559      0    stevel 		nmp = mp->b_next;
    560      0    stevel 		mp->b_next = mp->b_prev = NULL;
    561      0    stevel 		freemsg(mp);
    562      0    stevel 	}
    563      0    stevel 	ASSERT(!ump->b_prev);
    564      0    stevel 	ump->b_next = NULL;
    565      0    stevel 	freeb(ump);
    566      0    stevel }
    567      0    stevel 
    568      0    stevel mblk_t *
    569    252  vi117747 sctp_add_proto_hdr(sctp_t *sctp, sctp_faddr_t *fp, mblk_t *mp, int sacklen,
    570    252  vi117747     int *error)
    571      0    stevel {
    572      0    stevel 	int hdrlen;
    573  11042      Erik 	uchar_t *hdr;
    574      0    stevel 	int isv4 = fp->isv4;
    575   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
    576    252  vi117747 
    577    252  vi117747 	if (error != NULL)
    578    252  vi117747 		*error = 0;
    579      0    stevel 
    580      0    stevel 	if (isv4) {
    581      0    stevel 		hdrlen = sctp->sctp_hdr_len;
    582      0    stevel 		hdr = sctp->sctp_iphc;
    583      0    stevel 	} else {
    584      0    stevel 		hdrlen = sctp->sctp_hdr6_len;
    585      0    stevel 		hdr = sctp->sctp_iphc6;
    586      0    stevel 	}
    587    252  vi117747 	/*
    588  11042      Erik 	 * A reject|blackhole could mean that the address is 'down'. Similarly,
    589    252  vi117747 	 * it is possible that the address went down, we tried to send an
    590    252  vi117747 	 * heartbeat and ended up setting fp->saddr as unspec because we
    591   1735    kcpoon 	 * didn't have any usable source address.  In either case
    592  11042      Erik 	 * sctp_get_dest() will try find an IRE, if available, and set
    593   1735    kcpoon 	 * the source address, if needed.  If we still don't have any
    594    252  vi117747 	 * usable source address, fp->state will be SCTP_FADDRS_UNREACH and
    595    252  vi117747 	 * we return EHOSTUNREACH.
    596    252  vi117747 	 */
    597  11042      Erik 	ASSERT(fp->ixa->ixa_ire != NULL);
    598  11042      Erik 	if ((fp->ixa->ixa_ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) ||
    599  11042      Erik 	    SCTP_IS_ADDR_UNSPEC(fp->isv4, fp->saddr)) {
    600  11042      Erik 		sctp_get_dest(sctp, fp);
    601    252  vi117747 		if (fp->state == SCTP_FADDRS_UNREACH) {
    602    252  vi117747 			if (error != NULL)
    603    252  vi117747 				*error = EHOSTUNREACH;
    604    252  vi117747 			return (NULL);
    605      0    stevel 		}
    606      0    stevel 	}
    607      0    stevel 	/* Copy in IP header. */
    608      0    stevel 	if ((mp->b_rptr - mp->b_datap->db_base) <
    609  11042      Erik 	    (sctps->sctps_wroff_xtra + hdrlen + sacklen) || DB_REF(mp) > 2) {
    610      0    stevel 		mblk_t *nmp;
    611   1735    kcpoon 
    612      0    stevel 		/*
    613      0    stevel 		 * This can happen if IP headers are adjusted after
    614      0    stevel 		 * data was moved into chunks, or during retransmission,
    615      0    stevel 		 * or things like snoop is running.
    616      0    stevel 		 */
    617  11042      Erik 		nmp = allocb(sctps->sctps_wroff_xtra + hdrlen + sacklen,
    618  11042      Erik 		    BPRI_MED);
    619      0    stevel 		if (nmp == NULL) {
    620    252  vi117747 			if (error !=  NULL)
    621    252  vi117747 				*error = ENOMEM;
    622      0    stevel 			return (NULL);
    623      0    stevel 		}
    624   3448  dh155122 		nmp->b_rptr += sctps->sctps_wroff_xtra;
    625      0    stevel 		nmp->b_wptr = nmp->b_rptr + hdrlen + sacklen;
    626      0    stevel 		nmp->b_cont = mp;
    627      0    stevel 		mp = nmp;
    628      0    stevel 	} else {
    629      0    stevel 		mp->b_rptr -= (hdrlen + sacklen);
    630      0    stevel 	}
    631      0    stevel 	bcopy(hdr, mp->b_rptr, hdrlen);
    632      0    stevel 	if (sacklen) {
    633      0    stevel 		sctp_fill_sack(sctp, mp->b_rptr + hdrlen, sacklen);
    634      0    stevel 	}
    635      0    stevel 	if (fp != sctp->sctp_current) {
    636      0    stevel 		/* change addresses in header */
    637      0    stevel 		if (isv4) {
    638      0    stevel 			ipha_t *iph = (ipha_t *)mp->b_rptr;
    639      0    stevel 
    640      0    stevel 			IN6_V4MAPPED_TO_IPADDR(&fp->faddr, iph->ipha_dst);
    641      0    stevel 			if (!IN6_IS_ADDR_V4MAPPED_ANY(&fp->saddr)) {
    642      0    stevel 				IN6_V4MAPPED_TO_IPADDR(&fp->saddr,
    643      0    stevel 				    iph->ipha_src);
    644      0    stevel 			} else if (sctp->sctp_bound_to_all) {
    645      0    stevel 				iph->ipha_src = INADDR_ANY;
    646      0    stevel 			}
    647      0    stevel 		} else {
    648  11042      Erik 			ip6_t *ip6h = (ip6_t *)mp->b_rptr;
    649  11042      Erik 
    650  11042      Erik 			ip6h->ip6_dst = fp->faddr;
    651      0    stevel 			if (!IN6_IS_ADDR_UNSPECIFIED(&fp->saddr)) {
    652  11042      Erik 				ip6h->ip6_src = fp->saddr;
    653      0    stevel 			} else if (sctp->sctp_bound_to_all) {
    654  11042      Erik 				ip6h->ip6_src = ipv6_all_zeros;
    655      0    stevel 			}
    656      0    stevel 		}
    657      0    stevel 	}
    658      0    stevel 	return (mp);
    659      0    stevel }
    660      0    stevel 
    661      0    stevel /*
    662      0    stevel  * SCTP requires every chunk to be padded so that the total length
    663      0    stevel  * is a multiple of SCTP_ALIGN.  This function returns a mblk with
    664      0    stevel  * the specified pad length.
    665      0    stevel  */
    666      0    stevel static mblk_t *
    667   4691    kcpoon sctp_get_padding(sctp_t *sctp, int pad)
    668      0    stevel {
    669      0    stevel 	mblk_t *fill;
    670      0    stevel 
    671      0    stevel 	ASSERT(pad < SCTP_ALIGN);
    672   4691    kcpoon 	ASSERT(sctp->sctp_pad_mp != NULL);
    673   4691    kcpoon 	if ((fill = dupb(sctp->sctp_pad_mp)) != NULL) {
    674      0    stevel 		fill->b_wptr += pad;
    675      0    stevel 		return (fill);
    676      0    stevel 	}
    677      0    stevel 
    678      0    stevel 	/*
    679      0    stevel 	 * The memory saving path of reusing the sctp_pad_mp
    680      0    stevel 	 * fails may be because it has been dupb() too
    681      0    stevel 	 * many times (DBLK_REFMAX).  Use the memory consuming
    682      0    stevel 	 * path of allocating the pad mblk.
    683      0    stevel 	 */
    684      0    stevel 	if ((fill = allocb(SCTP_ALIGN, BPRI_MED)) != NULL) {
    685      0    stevel 		/* Zero it out.  SCTP_ALIGN is sizeof (int32_t) */
    686      0    stevel 		*(int32_t *)fill->b_rptr = 0;
    687      0    stevel 		fill->b_wptr += pad;
    688      0    stevel 	}
    689      0    stevel 	return (fill);
    690      0    stevel }
    691      0    stevel 
    692      0    stevel static mblk_t *
    693      0    stevel sctp_find_fast_rexmit_mblks(sctp_t *sctp, int *total, sctp_faddr_t **fp)
    694      0    stevel {
    695      0    stevel 	mblk_t		*meta;
    696      0    stevel 	mblk_t		*start_mp = NULL;
    697      0    stevel 	mblk_t		*end_mp = NULL;
    698      0    stevel 	mblk_t		*mp, *nmp;
    699      0    stevel 	mblk_t		*fill;
    700      0    stevel 	sctp_data_hdr_t	*sdh;
    701      0    stevel 	int		msglen;
    702      0    stevel 	int		extra;
    703      0    stevel 	sctp_msg_hdr_t	*msg_hdr;
    704   1735    kcpoon 	sctp_faddr_t	*old_fp = NULL;
    705   1735    kcpoon 	sctp_faddr_t	*chunk_fp;
    706   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
    707      0    stevel 
    708      0    stevel 	for (meta = sctp->sctp_xmit_head; meta != NULL; meta = meta->b_next) {
    709      0    stevel 		msg_hdr = (sctp_msg_hdr_t *)meta->b_rptr;
    710      0    stevel 		if (SCTP_IS_MSG_ABANDONED(meta) ||
    711      0    stevel 		    SCTP_MSG_TO_BE_ABANDONED(meta, msg_hdr, sctp)) {
    712      0    stevel 			continue;
    713      0    stevel 		}
    714      0    stevel 		for (mp = meta->b_cont; mp != NULL; mp = mp->b_next) {
    715      0    stevel 			if (SCTP_CHUNK_WANT_REXMIT(mp)) {
    716      0    stevel 				/*
    717      0    stevel 				 * Use the same peer address to do fast
    718   1735    kcpoon 				 * retransmission.  If the original peer
    719   1735    kcpoon 				 * address is dead, switch to the current
    720   1735    kcpoon 				 * one.  Record the old one so that we
    721   1735    kcpoon 				 * will pick the chunks sent to the old
    722   1735    kcpoon 				 * one for fast retransmission.
    723      0    stevel 				 */
    724   1735    kcpoon 				chunk_fp = SCTP_CHUNK_DEST(mp);
    725      0    stevel 				if (*fp == NULL) {
    726   1735    kcpoon 					*fp = chunk_fp;
    727   1735    kcpoon 					if ((*fp)->state != SCTP_FADDRS_ALIVE) {
    728   1735    kcpoon 						old_fp = *fp;
    729      0    stevel 						*fp = sctp->sctp_current;
    730   1735    kcpoon 					}
    731   1735    kcpoon 				} else if (old_fp == NULL && *fp != chunk_fp) {
    732   1735    kcpoon 					continue;
    733   1735    kcpoon 				} else if (old_fp != NULL &&
    734   1735    kcpoon 				    old_fp != chunk_fp) {
    735      0    stevel 					continue;
    736      0    stevel 				}
    737      0    stevel 
    738      0    stevel 				sdh = (sctp_data_hdr_t *)mp->b_rptr;
    739      0    stevel 				msglen = ntohs(sdh->sdh_len);
    740      0    stevel 				if ((extra = msglen & (SCTP_ALIGN - 1)) != 0) {
    741      0    stevel 					extra = SCTP_ALIGN - extra;
    742      0    stevel 				}
    743      0    stevel 
    744      0    stevel 				/*
    745      0    stevel 				 * We still return at least the first message
    746      0    stevel 				 * even if that message cannot fit in as
    747      0    stevel 				 * PMTU may have changed.
    748      0    stevel 				 */
    749      0    stevel 				if (*total + msglen + extra >
    750      0    stevel 				    (*fp)->sfa_pmss && start_mp != NULL) {
    751      0    stevel 					return (start_mp);
    752      0    stevel 				}
    753      0    stevel 				if ((nmp = dupmsg(mp)) == NULL)
    754      0    stevel 					return (start_mp);
    755      0    stevel 				if (extra > 0) {
    756   4691    kcpoon 					fill = sctp_get_padding(sctp, extra);
    757      0    stevel 					if (fill != NULL) {
    758      0    stevel 						linkb(nmp, fill);
    759      0    stevel 					} else {
    760      0    stevel 						return (start_mp);
    761      0    stevel 					}
    762      0    stevel 				}
    763   3448  dh155122 				BUMP_MIB(&sctps->sctps_mib, sctpOutFastRetrans);
    764   1735    kcpoon 				BUMP_LOCAL(sctp->sctp_rxtchunks);
    765      0    stevel 				SCTP_CHUNK_CLEAR_REXMIT(mp);
    766      0    stevel 				if (start_mp == NULL) {
    767      0    stevel 					start_mp = nmp;
    768      0    stevel 				} else {
    769      0    stevel 					linkb(end_mp, nmp);
    770      0    stevel 				}
    771      0    stevel 				end_mp = nmp;
    772      0    stevel 				*total += msglen + extra;
    773      0    stevel 				dprint(2, ("sctp_find_fast_rexmit_mblks: "
    774      0    stevel 				    "tsn %x\n", sdh->sdh_tsn));
    775      0    stevel 			}
    776      0    stevel 		}
    777      0    stevel 	}
    778      0    stevel 	/* Clear the flag as there is no more message to be fast rexmitted. */
    779      0    stevel 	sctp->sctp_chk_fast_rexmit = B_FALSE;
    780      0    stevel 	return (start_mp);
    781      0    stevel }
    782      0    stevel 
    783      0    stevel /* A debug function just to make sure that a mblk chain is not broken */
    784      0    stevel #ifdef	DEBUG
    785      0    stevel static boolean_t
    786      0    stevel sctp_verify_chain(mblk_t *head, mblk_t *tail)
    787      0    stevel {
    788      0    stevel 	mblk_t	*mp = head;
    789      0    stevel 
    790      0    stevel 	if (head == NULL || tail == NULL)
    791      0    stevel 		return (B_TRUE);
    792      0    stevel 	while (mp != NULL) {
    793      0    stevel 		if (mp == tail)
    794      0    stevel 			return (B_TRUE);
    795      0    stevel 		mp = mp->b_next;
    796      0    stevel 	}
    797      0    stevel 	return (B_FALSE);
    798      0    stevel }
    799      0    stevel #endif
    800      0    stevel 
    801      0    stevel /*
    802      0    stevel  * Gets the next unsent chunk to transmit. Messages that are abandoned are
    803      0    stevel  * skipped. A message can be abandoned if it has a non-zero timetolive and
    804      0    stevel  * transmission has not yet started or if it is a partially reliable
    805      0    stevel  * message and its time is up (assuming we are PR-SCTP aware).
    806  10037      Nick  * We only return a chunk if it will fit entirely in the current packet.
    807      0    stevel  * 'cansend' is used to determine if need to try and chunkify messages from
    808      0    stevel  * the unsent list, if any, and also as an input to sctp_chunkify() if so.
    809   8154    George  *
    810  10037      Nick  * firstseg_len indicates the space already used, cansend represents remaining
    811  10037      Nick  * space in the window, ((sfa_pmss - firstseg_len) can therefore reasonably
    812   8154    George  * be used to compute the cansend arg).
    813      0    stevel  */
    814      0    stevel mblk_t *
    815      0    stevel sctp_get_msg_to_send(sctp_t *sctp, mblk_t **mp, mblk_t *meta, int  *error,
    816  10037      Nick     int32_t firstseg_len, uint32_t cansend, sctp_faddr_t *fp)
    817      0    stevel {
    818      0    stevel 	mblk_t		*mp1;
    819      0    stevel 	sctp_msg_hdr_t	*msg_hdr;
    820      0    stevel 	mblk_t		*tmp_meta;
    821      0    stevel 	sctp_faddr_t	*fp1;
    822      0    stevel 
    823      0    stevel 	ASSERT(error != NULL && mp != NULL);
    824      0    stevel 	*error = 0;
    825      0    stevel 
    826      0    stevel 	ASSERT(sctp->sctp_current != NULL);
    827      0    stevel 
    828      0    stevel chunkified:
    829      0    stevel 	while (meta != NULL) {
    830      0    stevel 		tmp_meta = meta->b_next;
    831      0    stevel 		msg_hdr = (sctp_msg_hdr_t *)meta->b_rptr;
    832      0    stevel 		mp1 = meta->b_cont;
    833      0    stevel 		if (SCTP_IS_MSG_ABANDONED(meta))
    834      0    stevel 			goto next_msg;
    835      0    stevel 		if (!SCTP_MSG_TO_BE_ABANDONED(meta, msg_hdr, sctp)) {
    836      0    stevel 			while (mp1 != NULL) {
    837      0    stevel 				if (SCTP_CHUNK_CANSEND(mp1)) {
    838      0    stevel 					*mp = mp1;
    839      0    stevel #ifdef	DEBUG
    840      0    stevel 					ASSERT(sctp_verify_chain(
    841      0    stevel 					    sctp->sctp_xmit_head, meta));
    842      0    stevel #endif
    843      0    stevel 					return (meta);
    844      0    stevel 				}
    845      0    stevel 				mp1 = mp1->b_next;
    846      0    stevel 			}
    847      0    stevel 			goto next_msg;
    848      0    stevel 		}
    849      0    stevel 		/*
    850      0    stevel 		 * If we come here and the first chunk is sent, then we
    851      0    stevel 		 * we are PR-SCTP aware, in which case if the cumulative
    852      0    stevel 		 * TSN has moved upto or beyond the first chunk (which
    853      0    stevel 		 * means all the previous messages have been cumulative
    854      0    stevel 		 * SACK'd), then we send a Forward TSN with the last
    855      0    stevel 		 * chunk that was sent in this message. If we can't send
    856      0    stevel 		 * a Forward TSN because previous non-abandoned messages
    857      0    stevel 		 * have not been acked then we will defer the Forward TSN
    858      0    stevel 		 * to sctp_rexmit() or sctp_cumack().
    859      0    stevel 		 */
    860      0    stevel 		if (SCTP_CHUNK_ISSENT(mp1)) {
    861      0    stevel 			*error = sctp_check_abandoned_msg(sctp, meta);
    862      0    stevel 			if (*error != 0) {
    863      0    stevel #ifdef	DEBUG
    864      0    stevel 				ASSERT(sctp_verify_chain(sctp->sctp_xmit_head,
    865      0    stevel 				    sctp->sctp_xmit_tail));
    866      0    stevel #endif
    867      0    stevel 				return (NULL);
    868      0    stevel 			}
    869      0    stevel 			goto next_msg;
    870      0    stevel 		}
    871      0    stevel 		BUMP_LOCAL(sctp->sctp_prsctpdrop);
    872      0    stevel 		ASSERT(sctp->sctp_unsent >= msg_hdr->smh_msglen);
    873      0    stevel 		if (meta->b_prev == NULL) {
    874      0    stevel 			ASSERT(sctp->sctp_xmit_head == meta);
    875      0    stevel 			sctp->sctp_xmit_head = tmp_meta;
    876      0    stevel 			if (sctp->sctp_xmit_tail == meta)
    877      0    stevel 				sctp->sctp_xmit_tail = tmp_meta;
    878      0    stevel 			meta->b_next = NULL;
    879      0    stevel 			if (tmp_meta != NULL)
    880      0    stevel 				tmp_meta->b_prev = NULL;
    881      0    stevel 		} else if (meta->b_next == NULL) {
    882      0    stevel 			if (sctp->sctp_xmit_tail == meta)
    883      0    stevel 				sctp->sctp_xmit_tail = meta->b_prev;
    884      0    stevel 			meta->b_prev->b_next = NULL;
    885      0    stevel 			meta->b_prev = NULL;
    886      0    stevel 		} else {
    887      0    stevel 			meta->b_prev->b_next = tmp_meta;
    888      0    stevel 			tmp_meta->b_prev = meta->b_prev;
    889      0    stevel 			if (sctp->sctp_xmit_tail == meta)
    890      0    stevel 				sctp->sctp_xmit_tail = tmp_meta;
    891      0    stevel 			meta->b_prev = NULL;
    892      0    stevel 			meta->b_next = NULL;
    893      0    stevel 		}
    894      0    stevel 		sctp->sctp_unsent -= msg_hdr->smh_msglen;
    895      0    stevel 		/*
    896      0    stevel 		 * Update ULP the amount of queued data, which is
    897      0    stevel 		 * sent-unack'ed + unsent.
    898      0    stevel 		 */
    899   8348      Eric 		if (!SCTP_IS_DETACHED(sctp))
    900   8348      Eric 			SCTP_TXQ_UPDATE(sctp);
    901      0    stevel 		sctp_sendfail_event(sctp, meta, 0, B_TRUE);
    902      0    stevel next_msg:
    903      0    stevel 		meta = tmp_meta;
    904      0    stevel 	}
    905      0    stevel 	/* chunkify, if needed */
    906      0    stevel 	if (cansend > 0 && sctp->sctp_xmit_unsent != NULL) {
    907      0    stevel 		ASSERT(sctp->sctp_unsent > 0);
    908      0    stevel 		if (fp == NULL) {
    909      0    stevel 			fp = SCTP_CHUNK_DEST(sctp->sctp_xmit_unsent);
    910      0    stevel 			if (fp == NULL || fp->state != SCTP_FADDRS_ALIVE)
    911      0    stevel 				fp = sctp->sctp_current;
    912      0    stevel 		} else {
    913      0    stevel 			/*
    914      0    stevel 			 * If user specified destination, try to honor that.
    915      0    stevel 			 */
    916      0    stevel 			fp1 = SCTP_CHUNK_DEST(sctp->sctp_xmit_unsent);
    917      0    stevel 			if (fp1 != NULL && fp1->state == SCTP_FADDRS_ALIVE &&
    918      0    stevel 			    fp1 != fp) {
    919      0    stevel 				goto chunk_done;
    920      0    stevel 			}
    921      0    stevel 		}
    922  10037      Nick 		meta = sctp_chunkify(sctp, fp->sfa_pmss, firstseg_len, cansend);
    923  10037      Nick 		if (meta == NULL)
    924      0    stevel 			goto chunk_done;
    925      0    stevel 		/*
    926      0    stevel 		 * sctp_chunkify() won't advance sctp_xmit_tail if it adds
    927      0    stevel 		 * new chunk(s) to the tail, so we need to skip the
    928      0    stevel 		 * sctp_xmit_tail, which would have already been processed.
    929      0    stevel 		 * This could happen when there is unacked chunks, but
    930      0    stevel 		 * nothing new to send.
    931      0    stevel 		 * When sctp_chunkify() is called when the transmit queue
    932      0    stevel 		 * is empty then we need to start from sctp_xmit_tail.
    933      0    stevel 		 */
    934      0    stevel 		if (SCTP_CHUNK_ISSENT(sctp->sctp_xmit_tail->b_cont)) {
    935      0    stevel #ifdef	DEBUG
    936      0    stevel 			mp1 = sctp->sctp_xmit_tail->b_cont;
    937      0    stevel 			while (mp1 != NULL) {
    938      0    stevel 				ASSERT(!SCTP_CHUNK_CANSEND(mp1));
    939      0    stevel 				mp1 = mp1->b_next;
    940      0    stevel 			}
    941      0    stevel #endif
    942      0    stevel 			if ((meta = sctp->sctp_xmit_tail->b_next) == NULL)
    943      0    stevel 				goto chunk_done;
    944      0    stevel 		}
    945      0    stevel 		goto chunkified;
    946      0    stevel 	}
    947      0    stevel chunk_done:
    948      0    stevel #ifdef	DEBUG
    949      0    stevel 	ASSERT(sctp_verify_chain(sctp->sctp_xmit_head, sctp->sctp_xmit_tail));
    950      0    stevel #endif
    951      0    stevel 	return (NULL);
    952      0    stevel }
    953      0    stevel 
    954      0    stevel void
    955      0    stevel sctp_fast_rexmit(sctp_t *sctp)
    956      0    stevel {
    957      0    stevel 	mblk_t		*mp, *head;
    958      0    stevel 	int		pktlen = 0;
    959      0    stevel 	sctp_faddr_t	*fp = NULL;
    960   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
    961      0    stevel 
    962      0    stevel 	ASSERT(sctp->sctp_xmit_head != NULL);
    963      0    stevel 	mp = sctp_find_fast_rexmit_mblks(sctp, &pktlen, &fp);
    964   1735    kcpoon 	if (mp == NULL) {
    965   3448  dh155122 		SCTP_KSTAT(sctps, sctp_fr_not_found);
    966      0    stevel 		return;
    967   1735    kcpoon 	}
    968    252  vi117747 	if ((head = sctp_add_proto_hdr(sctp, fp, mp, 0, NULL)) == NULL) {
    969      0    stevel 		freemsg(mp);
    970   3448  dh155122 		SCTP_KSTAT(sctps, sctp_fr_add_hdr);
    971      0    stevel 		return;
    972      0    stevel 	}
    973      0    stevel 	if ((pktlen > fp->sfa_pmss) && fp->isv4) {
    974      0    stevel 		ipha_t *iph = (ipha_t *)head->b_rptr;
    975      0    stevel 
    976      0    stevel 		iph->ipha_fragment_offset_and_flags = 0;
    977      0    stevel 	}
    978      0    stevel 
    979  11042      Erik 	sctp_set_iplen(sctp, head, fp->ixa);
    980  11042      Erik 	(void) conn_ip_output(head, fp->ixa);
    981  11042      Erik 	BUMP_LOCAL(sctp->sctp_opkts);
    982  11066    rafael 	sctp->sctp_active = fp->lastactive = ddi_get_lbolt64();
    983      0    stevel }
    984      0    stevel 
    985      0    stevel void
    986   3795    kcpoon sctp_output(sctp_t *sctp, uint_t num_pkt)
    987      0    stevel {
    988      0    stevel 	mblk_t			*mp = NULL;
    989      0    stevel 	mblk_t			*nmp;
    990      0    stevel 	mblk_t			*head;
    991      0    stevel 	mblk_t			*meta = sctp->sctp_xmit_tail;
    992      0    stevel 	mblk_t			*fill = NULL;
    993      0    stevel 	uint16_t 		chunklen;
    994      0    stevel 	uint32_t 		cansend;
    995      0    stevel 	int32_t			seglen;
    996      0    stevel 	int32_t			xtralen;
    997      0    stevel 	int32_t			sacklen;
    998      0    stevel 	int32_t			pad = 0;
    999      0    stevel 	int32_t			pathmax;
   1000      0    stevel 	int			extra;
   1001  11066    rafael 	int64_t			now = ddi_get_lbolt64();
   1002      0    stevel 	sctp_faddr_t		*fp;
   1003      0    stevel 	sctp_faddr_t		*lfp;
   1004      0    stevel 	sctp_data_hdr_t		*sdc;
   1005      0    stevel 	int			error;
   1006    252  vi117747 	boolean_t		notsent = B_TRUE;
   1007   3795    kcpoon 	sctp_stack_t		*sctps = sctp->sctp_sctps;
   1008      0    stevel 
   1009      0    stevel 	if (sctp->sctp_ftsn == sctp->sctp_lastacked + 1) {
   1010      0    stevel 		sacklen = 0;
   1011      0    stevel 	} else {
   1012      0    stevel 		/* send a SACK chunk */
   1013      0    stevel 		sacklen = sizeof (sctp_chunk_hdr_t) +
   1014      0    stevel 		    sizeof (sctp_sack_chunk_t) +
   1015      0    stevel 		    (sizeof (sctp_sack_frag_t) * sctp->sctp_sack_gaps);
   1016      0    stevel 		lfp = sctp->sctp_lastdata;
   1017      0    stevel 		ASSERT(lfp != NULL);
   1018      0    stevel 		if (lfp->state != SCTP_FADDRS_ALIVE)
   1019      0    stevel 			lfp = sctp->sctp_current;
   1020      0    stevel 	}
   1021      0    stevel 
   1022      0    stevel 	cansend = sctp->sctp_frwnd;
   1023      0    stevel 	if (sctp->sctp_unsent < cansend)
   1024      0    stevel 		cansend = sctp->sctp_unsent;
   1025   8222    George 
   1026   8222    George 	/*
   1027   8222    George 	 * Start persist timer if unable to send or when
   1028   8222    George 	 * trying to send into a zero window. This timer
   1029   8222    George 	 * ensures the blocked send attempt is retried.
   1030   8222    George 	 */
   1031      0    stevel 	if ((cansend < sctp->sctp_current->sfa_pmss / 2) &&
   1032   8222    George 	    (sctp->sctp_unacked != 0) &&
   1033      0    stevel 	    (sctp->sctp_unacked < sctp->sctp_current->sfa_pmss) &&
   1034   8222    George 	    !sctp->sctp_ndelay ||
   1035   8222    George 	    (cansend == 0 && sctp->sctp_unacked == 0 &&
   1036   8222    George 	    sctp->sctp_unsent != 0)) {
   1037      0    stevel 		head = NULL;
   1038      0    stevel 		fp = sctp->sctp_current;
   1039      0    stevel 		goto unsent_data;
   1040      0    stevel 	}
   1041      0    stevel 	if (meta != NULL)
   1042      0    stevel 		mp = meta->b_cont;
   1043   3795    kcpoon 	while (cansend > 0 && num_pkt-- != 0) {
   1044      0    stevel 		pad = 0;
   1045      0    stevel 
   1046      0    stevel 		/*
   1047      0    stevel 		 * Find first segment eligible for transmit.
   1048      0    stevel 		 */
   1049      0    stevel 		while (mp != NULL) {
   1050      0    stevel 			if (SCTP_CHUNK_CANSEND(mp))
   1051      0    stevel 				break;
   1052      0    stevel 			mp = mp->b_next;
   1053      0    stevel 		}
   1054      0    stevel 		if (mp == NULL) {
   1055      0    stevel 			meta = sctp_get_msg_to_send(sctp, &mp,
   1056      0    stevel 			    meta == NULL ? NULL : meta->b_next, &error, sacklen,
   1057      0    stevel 			    cansend, NULL);
   1058      0    stevel 			if (error != 0 || meta == NULL) {
   1059      0    stevel 				head = NULL;
   1060      0    stevel 				fp = sctp->sctp_current;
   1061      0    stevel 				goto unsent_data;
   1062      0    stevel 			}
   1063      0    stevel 			sctp->sctp_xmit_tail =  meta;
   1064      0    stevel 		}
   1065      0    stevel 
   1066      0    stevel 		sdc = (sctp_data_hdr_t *)mp->b_rptr;
   1067      0    stevel 		seglen = ntohs(sdc->sdh_len);
   1068      0    stevel 		xtralen = sizeof (*sdc);
   1069      0    stevel 		chunklen = seglen - xtralen;
   1070      0    stevel 
   1071      0    stevel 		/*
   1072      0    stevel 		 * Check rwnd.
   1073      0    stevel 		 */
   1074      0    stevel 		if (chunklen > cansend) {
   1075      0    stevel 			head = NULL;
   1076      0    stevel 			fp = SCTP_CHUNK_DEST(meta);
   1077      0    stevel 			if (fp == NULL || fp->state != SCTP_FADDRS_ALIVE)
   1078      0    stevel 				fp = sctp->sctp_current;
   1079      0    stevel 			goto unsent_data;
   1080      0    stevel 		}
   1081      0    stevel 		if ((extra = seglen & (SCTP_ALIGN - 1)) != 0)
   1082      0    stevel 			extra = SCTP_ALIGN - extra;
   1083      0    stevel 
   1084      0    stevel 		/*
   1085      0    stevel 		 * Pick destination address, and check cwnd.
   1086      0    stevel 		 */
   1087      0    stevel 		if (sacklen > 0 && (seglen + extra <= lfp->cwnd - lfp->suna) &&
   1088      0    stevel 		    (seglen + sacklen + extra <= lfp->sfa_pmss)) {
   1089      0    stevel 			/*
   1090      0    stevel 			 * Only include SACK chunk if it can be bundled
   1091      0    stevel 			 * with a data chunk, and sent to sctp_lastdata.
   1092      0    stevel 			 */
   1093      0    stevel 			pathmax = lfp->cwnd - lfp->suna;
   1094      0    stevel 
   1095      0    stevel 			fp = lfp;
   1096      0    stevel 			if ((nmp = dupmsg(mp)) == NULL) {
   1097      0    stevel 				head = NULL;
   1098      0    stevel 				goto unsent_data;
   1099      0    stevel 			}
   1100      0    stevel 			SCTP_CHUNK_CLEAR_FLAGS(nmp);
   1101    252  vi117747 			head = sctp_add_proto_hdr(sctp, fp, nmp, sacklen,
   1102    252  vi117747 			    &error);
   1103      0    stevel 			if (head == NULL) {
   1104    252  vi117747 				/*
   1105    252  vi117747 				 * If none of the source addresses are
   1106    252  vi117747 				 * available (i.e error == EHOSTUNREACH),
   1107    252  vi117747 				 * pretend we have sent the data. We will
   1108    252  vi117747 				 * eventually time out trying to retramsmit
   1109    252  vi117747 				 * the data if the interface never comes up.
   1110    252  vi117747 				 * If we have already sent some stuff (i.e.,
   1111    252  vi117747 				 * notsent is B_FALSE) then we are fine, else
   1112    252  vi117747 				 * just mark this packet as sent.
   1113    252  vi117747 				 */
   1114    252  vi117747 				if (notsent && error == EHOSTUNREACH) {
   1115    252  vi117747 					SCTP_CHUNK_SENT(sctp, mp, sdc,
   1116    252  vi117747 					    fp, chunklen, meta);
   1117    252  vi117747 				}
   1118      0    stevel 				freemsg(nmp);
   1119   3448  dh155122 				SCTP_KSTAT(sctps, sctp_output_failed);
   1120      0    stevel 				goto unsent_data;
   1121      0    stevel 			}
   1122      0    stevel 			seglen += sacklen;
   1123      0    stevel 			xtralen += sacklen;
   1124      0    stevel 			sacklen = 0;
   1125      0    stevel 		} else {
   1126      0    stevel 			fp = SCTP_CHUNK_DEST(meta);
   1127      0    stevel 			if (fp == NULL || fp->state != SCTP_FADDRS_ALIVE)
   1128      0    stevel 				fp = sctp->sctp_current;
   1129      0    stevel 			/*
   1130      0    stevel 			 * If we haven't sent data to this destination for
   1131      0    stevel 			 * a while, do slow start again.
   1132      0    stevel 			 */
   1133      0    stevel 			if (now - fp->lastactive > fp->rto) {
   1134   3795    kcpoon 				SET_CWND(fp, fp->sfa_pmss,
   1135   3795    kcpoon 				    sctps->sctps_slow_start_after_idle);
   1136      0    stevel 			}
   1137      0    stevel 
   1138      0    stevel 			pathmax = fp->cwnd - fp->suna;
   1139      0    stevel 			if (seglen + extra > pathmax) {
   1140      0    stevel 				head = NULL;
   1141      0    stevel 				goto unsent_data;
   1142      0    stevel 			}
   1143      0    stevel 			if ((nmp = dupmsg(mp)) == NULL) {
   1144      0    stevel 				head = NULL;
   1145      0    stevel 				goto unsent_data;
   1146      0    stevel 			}
   1147      0    stevel 			SCTP_CHUNK_CLEAR_FLAGS(nmp);
   1148    252  vi117747 			head = sctp_add_proto_hdr(sctp, fp, nmp, 0, &error);
   1149      0    stevel 			if (head == NULL) {
   1150    252  vi117747 				/*
   1151    252  vi117747 				 * If none of the source addresses are
   1152    252  vi117747 				 * available (i.e error == EHOSTUNREACH),
   1153    252  vi117747 				 * pretend we have sent the data. We will
   1154    252  vi117747 				 * eventually time out trying to retramsmit
   1155    252  vi117747 				 * the data if the interface never comes up.
   1156    252  vi117747 				 * If we have already sent some stuff (i.e.,
   1157    252  vi117747 				 * notsent is B_FALSE) then we are fine, else
   1158    252  vi117747 				 * just mark this packet as sent.
   1159    252  vi117747 				 */
   1160    252  vi117747 				if (notsent && error == EHOSTUNREACH) {
   1161    252  vi117747 					SCTP_CHUNK_SENT(sctp, mp, sdc,
   1162    252  vi117747 					    fp, chunklen, meta);
   1163    252  vi117747 				}
   1164      0    stevel 				freemsg(nmp);
   1165   3448  dh155122 				SCTP_KSTAT(sctps, sctp_output_failed);
   1166      0    stevel 				goto unsent_data;
   1167      0    stevel 			}
   1168      0    stevel 		}
   1169   1735    kcpoon 		fp->lastactive = now;
   1170      0    stevel 		if (pathmax > fp->sfa_pmss)
   1171      0    stevel 			pathmax = fp->sfa_pmss;
   1172      0    stevel 		SCTP_CHUNK_SENT(sctp, mp, sdc, fp, chunklen, meta);
   1173      0    stevel 		mp = mp->b_next;
   1174      0    stevel 
   1175      0    stevel 		/* Use this chunk to measure RTT? */
   1176      0    stevel 		if (sctp->sctp_out_time == 0) {
   1177      0    stevel 			sctp->sctp_out_time = now;
   1178      0    stevel 			sctp->sctp_rtt_tsn = sctp->sctp_ltsn - 1;
   1179   1735    kcpoon 			ASSERT(sctp->sctp_rtt_tsn == ntohl(sdc->sdh_tsn));
   1180      0    stevel 		}
   1181      0    stevel 		if (extra > 0) {
   1182   4691    kcpoon 			fill = sctp_get_padding(sctp, extra);
   1183      0    stevel 			if (fill != NULL) {
   1184      0    stevel 				linkb(head, fill);
   1185      0    stevel 				pad = extra;
   1186      0    stevel 				seglen += extra;
   1187      0    stevel 			} else {
   1188      0    stevel 				goto unsent_data;
   1189      0    stevel 			}
   1190      0    stevel 		}
   1191  10037      Nick 		/*
   1192  10037      Nick 		 * Bundle chunks. We linkb() the chunks together to send
   1193  10037      Nick 		 * downstream in a single packet.
   1194  10037      Nick 		 * Partial chunks MUST NOT be bundled with full chunks, so we
   1195  10037      Nick 		 * rely on sctp_get_msg_to_send() to only return messages that
   1196  10037      Nick 		 * will fit entirely in the current packet.
   1197  10037      Nick 		 */
   1198      0    stevel 		while (seglen < pathmax) {
   1199      0    stevel 			int32_t		new_len;
   1200      0    stevel 			int32_t		new_xtralen;
   1201      0    stevel 
   1202      0    stevel 			while (mp != NULL) {
   1203      0    stevel 				if (SCTP_CHUNK_CANSEND(mp))
   1204      0    stevel 					break;
   1205      0    stevel 				mp = mp->b_next;
   1206      0    stevel 			}
   1207      0    stevel 			if (mp == NULL) {
   1208      0    stevel 				meta = sctp_get_msg_to_send(sctp, &mp,
   1209      0    stevel 				    meta->b_next, &error, seglen,
   1210      0    stevel 				    (seglen - xtralen) >= cansend ? 0 :
   1211      0    stevel 				    cansend - seglen, fp);
   1212  10037      Nick 				if (error != 0)
   1213  10037      Nick 					break;
   1214  10037      Nick 				/* If no more eligible chunks, cease bundling */
   1215  10037      Nick 				if (meta == NULL)
   1216      0    stevel 					break;
   1217      0    stevel 				sctp->sctp_xmit_tail =  meta;
   1218      0    stevel 			}
   1219      0    stevel 			ASSERT(mp != NULL);
   1220      0    stevel 			if (!SCTP_CHUNK_ISSENT(mp) && SCTP_CHUNK_DEST(meta) &&
   1221      0    stevel 			    fp != SCTP_CHUNK_DEST(meta)) {
   1222      0    stevel 				break;
   1223      0    stevel 			}
   1224      0    stevel 			sdc = (sctp_data_hdr_t *)mp->b_rptr;
   1225      0    stevel 			chunklen = ntohs(sdc->sdh_len);
   1226      0    stevel 			if ((extra = chunklen  & (SCTP_ALIGN - 1)) != 0)
   1227      0    stevel 				extra = SCTP_ALIGN - extra;
   1228      0    stevel 
   1229      0    stevel 			new_len = seglen + chunklen;
   1230      0    stevel 			new_xtralen = xtralen + sizeof (*sdc);
   1231      0    stevel 			chunklen -= sizeof (*sdc);
   1232      0    stevel 
   1233      0    stevel 			if (new_len - new_xtralen > cansend ||
   1234      0    stevel 			    new_len + extra > pathmax) {
   1235      0    stevel 				break;
   1236      0    stevel 			}
   1237      0    stevel 			if ((nmp = dupmsg(mp)) == NULL)
   1238      0    stevel 				break;
   1239      0    stevel 			if (extra > 0) {
   1240   4691    kcpoon 				fill = sctp_get_padding(sctp, extra);
   1241      0    stevel 				if (fill != NULL) {
   1242      0    stevel 					pad += extra;
   1243      0    stevel 					new_len += extra;
   1244      0    stevel 					linkb(nmp, fill);
   1245      0    stevel 				} else {
   1246      0    stevel 					freemsg(nmp);
   1247      0    stevel 					break;
   1248      0    stevel 				}
   1249      0    stevel 			}
   1250      0    stevel 			seglen = new_len;
   1251      0    stevel 			xtralen = new_xtralen;
   1252      0    stevel 			SCTP_CHUNK_CLEAR_FLAGS(nmp);
   1253      0    stevel 			SCTP_CHUNK_SENT(sctp, mp, sdc, fp, chunklen, meta);
   1254      0    stevel 			linkb(head, nmp);
   1255      0    stevel 			mp = mp->b_next;
   1256      0    stevel 		}
   1257      0    stevel 		if ((seglen > fp->sfa_pmss) && fp->isv4) {
   1258      0    stevel 			ipha_t *iph = (ipha_t *)head->b_rptr;
   1259      0    stevel 
   1260      0    stevel 			/*
   1261      0    stevel 			 * Path MTU is different from what we thought it would
   1262      0    stevel 			 * be when we created chunks, or IP headers have grown.
   1263      0    stevel 			 * Need to clear the DF bit.
   1264      0    stevel 			 */
   1265      0    stevel 			iph->ipha_fragment_offset_and_flags = 0;
   1266      0    stevel 		}
   1267      0    stevel 		/* xmit segment */
   1268      0    stevel 		ASSERT(cansend >= seglen - pad - xtralen);
   1269      0    stevel 		cansend -= (seglen - pad - xtralen);
   1270      0    stevel 		dprint(2, ("sctp_output: Sending packet %d bytes, tsn %x "
   1271   1676       jpk 		    "ssn %d to %p (rwnd %d, cansend %d, lastack_rxd %x)\n",
   1272   1676       jpk 		    seglen - xtralen, ntohl(sdc->sdh_tsn),
   1273   1676       jpk 		    ntohs(sdc->sdh_ssn), (void *)fp, sctp->sctp_frwnd,
   1274   1676       jpk 		    cansend, sctp->sctp_lastack_rxd));
   1275  11042      Erik 		sctp_set_iplen(sctp, head, fp->ixa);
   1276  11042      Erik 		(void) conn_ip_output(head, fp->ixa);
   1277  11042      Erik 		BUMP_LOCAL(sctp->sctp_opkts);
   1278      0    stevel 		/* arm rto timer (if not set) */
   1279      0    stevel 		if (!fp->timer_running)
   1280      0    stevel 			SCTP_FADDR_TIMER_RESTART(sctp, fp, fp->rto);
   1281    252  vi117747 		notsent = B_FALSE;
   1282      0    stevel 	}
   1283      0    stevel 	sctp->sctp_active = now;
   1284      0    stevel 	return;
   1285      0    stevel unsent_data:
   1286      0    stevel 	/* arm persist timer (if rto timer not set) */
   1287      0    stevel 	if (!fp->timer_running)
   1288      0    stevel 		SCTP_FADDR_TIMER_RESTART(sctp, fp, fp->rto);
   1289      0    stevel 	if (head != NULL)
   1290      0    stevel 		freemsg(head);
   1291      0    stevel }
   1292      0    stevel 
   1293      0    stevel /*
   1294      0    stevel  * The following two functions initialize and destroy the cache
   1295      0    stevel  * associated with the sets used for PR-SCTP.
   1296      0    stevel  */
   1297      0    stevel void
   1298      0    stevel sctp_ftsn_sets_init(void)
   1299      0    stevel {
   1300      0    stevel 	sctp_kmem_ftsn_set_cache = kmem_cache_create("sctp_ftsn_set_cache",
   1301      0    stevel 	    sizeof (sctp_ftsn_set_t), 0, NULL, NULL, NULL, NULL,
   1302      0    stevel 	    NULL, 0);
   1303      0    stevel }
   1304      0    stevel 
   1305      0    stevel void
   1306      0    stevel sctp_ftsn_sets_fini(void)
   1307      0    stevel {
   1308      0    stevel 	kmem_cache_destroy(sctp_kmem_ftsn_set_cache);
   1309      0    stevel }
   1310      0    stevel 
   1311      0    stevel 
   1312      0    stevel /* Free PR-SCTP sets */
   1313      0    stevel void
   1314      0    stevel sctp_free_ftsn_set(sctp_ftsn_set_t *s)
   1315      0    stevel {
   1316      0    stevel 	sctp_ftsn_set_t *p;
   1317      0    stevel 
   1318      0    stevel 	while (s != NULL) {
   1319      0    stevel 		p = s->next;
   1320      0    stevel 		s->next = NULL;
   1321      0    stevel 		kmem_cache_free(sctp_kmem_ftsn_set_cache, s);
   1322      0    stevel 		s = p;
   1323      0    stevel 	}
   1324      0    stevel }
   1325      0    stevel 
   1326      0    stevel /*
   1327      0    stevel  * Given a message meta block, meta, this routine creates or modifies
   1328      0    stevel  * the set that will be used to generate a Forward TSN chunk. If the
   1329      0    stevel  * entry for stream id, sid, for this message already exists, the
   1330      0    stevel  * sequence number, ssn, is updated if it is greater than the existing
   1331      0    stevel  * one. If an entry for this sid does not exist, one is created if
   1332      0    stevel  * the size does not exceed fp->sfa_pmss. We return false in case
   1333      0    stevel  * or an error.
   1334      0    stevel  */
   1335      0    stevel boolean_t
   1336      0    stevel sctp_add_ftsn_set(sctp_ftsn_set_t **s, sctp_faddr_t *fp, mblk_t *meta,
   1337      0    stevel     uint_t *nsets, uint32_t *slen)
   1338      0    stevel {
   1339      0    stevel 	sctp_ftsn_set_t		*p;
   1340      0    stevel 	sctp_msg_hdr_t		*msg_hdr = (sctp_msg_hdr_t *)meta->b_rptr;
   1341      0    stevel 	uint16_t		sid = htons(msg_hdr->smh_sid);
   1342      0    stevel 	/* msg_hdr->smh_ssn is already in NBO */
   1343      0    stevel 	uint16_t		ssn = msg_hdr->smh_ssn;
   1344      0    stevel 
   1345      0    stevel 	ASSERT(s != NULL && nsets != NULL);
   1346      0    stevel 	ASSERT((*nsets == 0 && *s == NULL) || (*nsets > 0 && *s != NULL));
   1347      0    stevel 
   1348      0    stevel 	if (*s == NULL) {
   1349      0    stevel 		ASSERT((*slen + sizeof (uint32_t)) <= fp->sfa_pmss);
   1350      0    stevel 		*s = kmem_cache_alloc(sctp_kmem_ftsn_set_cache, KM_NOSLEEP);
   1351      0    stevel 		if (*s == NULL)
   1352      0    stevel 			return (B_FALSE);
   1353      0    stevel 		(*s)->ftsn_entries.ftsn_sid = sid;
   1354      0    stevel 		(*s)->ftsn_entries.ftsn_ssn = ssn;
   1355      0    stevel 		(*s)->next = NULL;
   1356      0    stevel 		*nsets = 1;
   1357      0    stevel 		*slen += sizeof (uint32_t);
   1358      0    stevel 		return (B_TRUE);
   1359      0    stevel 	}
   1360      0    stevel 	for (p = *s; p->next != NULL; p = p->next) {
   1361      0    stevel 		if (p->ftsn_entries.ftsn_sid == sid) {
   1362      0    stevel 			if (SSN_GT(ssn, p->ftsn_entries.ftsn_ssn))
   1363      0    stevel 				p->ftsn_entries.ftsn_ssn = ssn;
   1364      0    stevel 			return (B_TRUE);
   1365      0    stevel 		}
   1366      0    stevel 	}
   1367      0    stevel 	/* the last one */
   1368      0    stevel 	if (p->ftsn_entries.ftsn_sid == sid) {
   1369      0    stevel 		if (SSN_GT(ssn, p->ftsn_entries.ftsn_ssn))
   1370      0    stevel 			p->ftsn_entries.ftsn_ssn = ssn;
   1371      0    stevel 	} else {
   1372      0    stevel 		if ((*slen + sizeof (uint32_t)) > fp->sfa_pmss)
   1373      0    stevel 			return (B_FALSE);
   1374      0    stevel 		p->next = kmem_cache_alloc(sctp_kmem_ftsn_set_cache,
   1375      0    stevel 		    KM_NOSLEEP);
   1376      0    stevel 		if (p->next == NULL)
   1377      0    stevel 			return (B_FALSE);
   1378      0    stevel 		p = p->next;
   1379      0    stevel 		p->ftsn_entries.ftsn_sid = sid;
   1380      0    stevel 		p->ftsn_entries.ftsn_ssn = ssn;
   1381      0    stevel 		p->next = NULL;
   1382      0    stevel 		(*nsets)++;
   1383      0    stevel 		*slen += sizeof (uint32_t);
   1384      0    stevel 	}
   1385      0    stevel 	return (B_TRUE);
   1386      0    stevel }
   1387      0    stevel 
   1388      0    stevel /*
   1389      0    stevel  * Given a set of stream id - sequence number pairs, this routing creates
   1390      0    stevel  * a Forward TSN chunk. The cumulative TSN (advanced peer ack point)
   1391      0    stevel  * for the chunk is obtained from sctp->sctp_adv_pap. The caller
   1392      0    stevel  * will add the IP/SCTP header.
   1393      0    stevel  */
   1394      0    stevel mblk_t *
   1395      0    stevel sctp_make_ftsn_chunk(sctp_t *sctp, sctp_faddr_t *fp, sctp_ftsn_set_t *sets,
   1396      0    stevel     uint_t nsets, uint32_t seglen)
   1397      0    stevel {
   1398      0    stevel 	mblk_t			*ftsn_mp;
   1399      0    stevel 	sctp_chunk_hdr_t	*ch_hdr;
   1400      0    stevel 	uint32_t		*advtsn;
   1401      0    stevel 	uint16_t		schlen;
   1402      0    stevel 	size_t			xtralen;
   1403      0    stevel 	ftsn_entry_t		*ftsn_entry;
   1404   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
   1405      0    stevel 
   1406      0    stevel 	seglen += sizeof (sctp_chunk_hdr_t);
   1407      0    stevel 	if (fp->isv4)
   1408   3448  dh155122 		xtralen = sctp->sctp_hdr_len + sctps->sctps_wroff_xtra;
   1409      0    stevel 	else
   1410   3448  dh155122 		xtralen = sctp->sctp_hdr6_len + sctps->sctps_wroff_xtra;
   1411  11042      Erik 	ftsn_mp = allocb(xtralen + seglen, BPRI_MED);
   1412      0    stevel 	if (ftsn_mp == NULL)
   1413      0    stevel 		return (NULL);
   1414      0    stevel 	ftsn_mp->b_rptr += xtralen;
   1415      0    stevel 	ftsn_mp->b_wptr = ftsn_mp->b_rptr + seglen;
   1416      0    stevel 
   1417      0    stevel 	ch_hdr = (sctp_chunk_hdr_t *)ftsn_mp->b_rptr;
   1418      0    stevel 	ch_hdr->sch_id = CHUNK_FORWARD_TSN;
   1419      0    stevel 	ch_hdr->sch_flags = 0;
   1420      0    stevel 	/*
   1421      0    stevel 	 * The cast here should not be an issue since seglen is
   1422      0    stevel 	 * the length of the Forward TSN chunk.
   1423      0    stevel 	 */
   1424      0    stevel 	schlen = (uint16_t)seglen;
   1425      0    stevel 	U16_TO_ABE16(schlen, &(ch_hdr->sch_len));
   1426      0    stevel 
   1427      0    stevel 	advtsn = (uint32_t *)(ch_hdr + 1);
   1428      0    stevel 	U32_TO_ABE32(sctp->sctp_adv_pap, advtsn);
   1429      0    stevel 	ftsn_entry = (ftsn_entry_t *)(advtsn + 1);
   1430      0    stevel 	while (nsets > 0) {
   1431      0    stevel 		ASSERT((uchar_t *)&ftsn_entry[1] <= ftsn_mp->b_wptr);
   1432      0    stevel 		ftsn_entry->ftsn_sid = sets->ftsn_entries.ftsn_sid;
   1433      0    stevel 		ftsn_entry->ftsn_ssn = sets->ftsn_entries.ftsn_ssn;
   1434      0    stevel 		ftsn_entry++;
   1435      0    stevel 		sets = sets->next;
   1436      0    stevel 		nsets--;
   1437      0    stevel 	}
   1438      0    stevel 	return (ftsn_mp);
   1439      0    stevel }
   1440      0    stevel 
   1441      0    stevel /*
   1442      0    stevel  * Given a starting message, the routine steps through all the
   1443      0    stevel  * messages whose TSN is less than sctp->sctp_adv_pap and creates
   1444      0    stevel  * ftsn sets. The ftsn sets is then used to create an Forward TSN
   1445      0    stevel  * chunk. All the messages, that have chunks that are included in the
   1446      0    stevel  * ftsn sets, are flagged abandonded. If a message is partially sent
   1447      0    stevel  * and is deemed abandoned, all remaining unsent chunks are marked
   1448      0    stevel  * abandoned and are deducted from sctp_unsent.
   1449      0    stevel  */
   1450      0    stevel void
   1451      0    stevel sctp_make_ftsns(sctp_t *sctp, mblk_t *meta, mblk_t *mp, mblk_t **nmp,
   1452      0    stevel     sctp_faddr_t *fp, uint32_t *seglen)
   1453      0    stevel {
   1454      0    stevel 	mblk_t		*mp1 = mp;
   1455      0    stevel 	mblk_t		*mp_head = mp;
   1456      0    stevel 	mblk_t		*meta_head = meta;
   1457      0    stevel 	mblk_t		*head;
   1458      0    stevel 	sctp_ftsn_set_t	*sets = NULL;
   1459      0    stevel 	uint_t		nsets = 0;
   1460      0    stevel 	uint16_t	clen;
   1461      0    stevel 	sctp_data_hdr_t	*sdc;
   1462      0    stevel 	uint32_t	sacklen;
   1463      0    stevel 	uint32_t	adv_pap = sctp->sctp_adv_pap;
   1464      0    stevel 	uint32_t	unsent = 0;
   1465      0    stevel 	boolean_t	ubit;
   1466   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
   1467      0    stevel 
   1468      0    stevel 	*seglen = sizeof (uint32_t);
   1469      0    stevel 
   1470      0    stevel 	sdc  = (sctp_data_hdr_t *)mp1->b_rptr;
   1471      0    stevel 	while (meta != NULL &&
   1472      0    stevel 	    SEQ_GEQ(sctp->sctp_adv_pap, ntohl(sdc->sdh_tsn))) {
   1473      0    stevel 		/*
   1474      0    stevel 		 * Skip adding FTSN sets for un-ordered messages as they do
   1475      0    stevel 		 * not have SSNs.
   1476      0    stevel 		 */
   1477      0    stevel 		ubit = SCTP_DATA_GET_UBIT(sdc);
   1478      0    stevel 		if (!ubit &&
   1479      0    stevel 		    !sctp_add_ftsn_set(&sets, fp, meta, &nsets, seglen)) {
   1480      0    stevel 			meta = NULL;
   1481      0    stevel 			sctp->sctp_adv_pap = adv_pap;
   1482      0    stevel 			goto ftsn_done;
   1483      0    stevel 		}
   1484      0    stevel 		while (mp1 != NULL && SCTP_CHUNK_ISSENT(mp1)) {
   1485      0    stevel 			sdc = (sctp_data_hdr_t *)mp1->b_rptr;
   1486      0    stevel 			adv_pap = ntohl(sdc->sdh_tsn);
   1487      0    stevel 			mp1 = mp1->b_next;
   1488      0    stevel 		}
   1489      0    stevel 		meta = meta->b_next;
   1490      0    stevel 		if (meta != NULL) {
   1491      0    stevel 			mp1 = meta->b_cont;
   1492      0    stevel 			if (!SCTP_CHUNK_ISSENT(mp1))
   1493      0    stevel 				break;
   1494      0    stevel 			sdc  = (sctp_data_hdr_t *)mp1->b_rptr;
   1495      0    stevel 		}
   1496      0    stevel 	}
   1497      0    stevel ftsn_done:
   1498      0    stevel 	/*
   1499      0    stevel 	 * Can't compare with sets == NULL, since we don't add any
   1500      0    stevel 	 * sets for un-ordered messages.
   1501      0    stevel 	 */
   1502      0    stevel 	if (meta == meta_head)
   1503      0    stevel 		return;
   1504      0    stevel 	*nmp = sctp_make_ftsn_chunk(sctp, fp, sets, nsets, *seglen);
   1505      0    stevel 	sctp_free_ftsn_set(sets);
   1506      0    stevel 	if (*nmp == NULL)
   1507      0    stevel 		return;
   1508      0    stevel 	if (sctp->sctp_ftsn == sctp->sctp_lastacked + 1) {
   1509      0    stevel 		sacklen = 0;
   1510      0    stevel 	} else {
   1511      0    stevel 		sacklen = sizeof (sctp_chunk_hdr_t) +
   1512      0    stevel 		    sizeof (sctp_sack_chunk_t) +
   1513      0    stevel 		    (sizeof (sctp_sack_frag_t) * sctp->sctp_sack_gaps);
   1514      0    stevel 		if (*seglen + sacklen > sctp->sctp_lastdata->sfa_pmss) {
   1515      0    stevel 			/* piggybacked SACK doesn't fit */
   1516      0    stevel 			sacklen = 0;
   1517      0    stevel 		} else {
   1518      0    stevel 			fp = sctp->sctp_lastdata;
   1519      0    stevel 		}
   1520      0    stevel 	}
   1521    252  vi117747 	head = sctp_add_proto_hdr(sctp, fp, *nmp, sacklen, NULL);
   1522      0    stevel 	if (head == NULL) {
   1523      0    stevel 		freemsg(*nmp);
   1524      0    stevel 		*nmp = NULL;
   1525   3448  dh155122 		SCTP_KSTAT(sctps, sctp_send_ftsn_failed);
   1526      0    stevel 		return;
   1527      0    stevel 	}
   1528      0    stevel 	*seglen += sacklen;
   1529      0    stevel 	*nmp = head;
   1530      0    stevel 
   1531      0    stevel 	/*
   1532      0    stevel 	 * XXXNeed to optimise this, the reason it is done here is so
   1533      0    stevel 	 * that we don't have to undo in case of failure.
   1534      0    stevel 	 */
   1535      0    stevel 	mp1 = mp_head;
   1536      0    stevel 	sdc  = (sctp_data_hdr_t *)mp1->b_rptr;
   1537      0    stevel 	while (meta_head != NULL &&
   1538      0    stevel 	    SEQ_GEQ(sctp->sctp_adv_pap, ntohl(sdc->sdh_tsn))) {
   1539      0    stevel 		if (!SCTP_IS_MSG_ABANDONED(meta_head))
   1540      0    stevel 			SCTP_MSG_SET_ABANDONED(meta_head);
   1541      0    stevel 		while (mp1 != NULL && SCTP_CHUNK_ISSENT(mp1)) {
   1542      0    stevel 			sdc = (sctp_data_hdr_t *)mp1->b_rptr;
   1543      0    stevel 			if (!SCTP_CHUNK_ISACKED(mp1)) {
   1544      0    stevel 				clen = ntohs(sdc->sdh_len) - sizeof (*sdc);
   1545      0    stevel 				SCTP_CHUNK_SENT(sctp, mp1, sdc, fp, clen,
   1546      0    stevel 				    meta_head);
   1547      0    stevel 			}
   1548      0    stevel 			mp1 = mp1->b_next;
   1549      0    stevel 		}
   1550      0    stevel 		while (mp1 != NULL) {
   1551      0    stevel 			sdc = (sctp_data_hdr_t *)mp1->b_rptr;
   1552      0    stevel 			if (!SCTP_CHUNK_ABANDONED(mp1)) {
   1553      0    stevel 				ASSERT(!SCTP_CHUNK_ISSENT(mp1));
   1554      0    stevel 				unsent += ntohs(sdc->sdh_len) - sizeof (*sdc);
   1555      0    stevel 				SCTP_ABANDON_CHUNK(mp1);
   1556      0    stevel 			}
   1557      0    stevel 			mp1 = mp1->b_next;
   1558      0    stevel 		}
   1559      0    stevel 		meta_head = meta_head->b_next;
   1560      0    stevel 		if (meta_head != NULL) {
   1561      0    stevel 			mp1 = meta_head->b_cont;
   1562      0    stevel 			if (!SCTP_CHUNK_ISSENT(mp1))
   1563      0    stevel 				break;
   1564      0    stevel 			sdc  = (sctp_data_hdr_t *)mp1->b_rptr;
   1565      0    stevel 		}
   1566      0    stevel 	}
   1567      0    stevel 	if (unsent > 0) {
   1568      0    stevel 		ASSERT(sctp->sctp_unsent >= unsent);
   1569      0    stevel 		sctp->sctp_unsent -= unsent;
   1570      0    stevel 		/*
   1571      0    stevel 		 * Update ULP the amount of queued data, which is
   1572      0    stevel 		 * sent-unack'ed + unsent.
   1573      0    stevel 		 */
   1574   8348      Eric 		if (!SCTP_IS_DETACHED(sctp))
   1575   8348      Eric 			SCTP_TXQ_UPDATE(sctp);
   1576      0    stevel 	}
   1577      0    stevel }
   1578      0    stevel 
   1579      0    stevel /*
   1580      0    stevel  * This function steps through messages starting at meta and checks if
   1581      0    stevel  * the message is abandoned. It stops when it hits an unsent chunk or
   1582      0    stevel  * a message that has all its chunk acked. This is the only place
   1583      0    stevel  * where the sctp_adv_pap is moved forward to indicated abandoned
   1584      0    stevel  * messages.
   1585      0    stevel  */
   1586      0    stevel void
   1587      0    stevel sctp_check_adv_ack_pt(sctp_t *sctp, mblk_t *meta, mblk_t *mp)
   1588      0    stevel {
   1589      0    stevel 	uint32_t	tsn = sctp->sctp_adv_pap;
   1590      0    stevel 	sctp_data_hdr_t	*sdc;
   1591      0    stevel 	sctp_msg_hdr_t	*msg_hdr;
   1592      0    stevel 
   1593      0    stevel 	ASSERT(mp != NULL);
   1594      0    stevel 	sdc = (sctp_data_hdr_t *)mp->b_rptr;
   1595      0    stevel 	ASSERT(SEQ_GT(ntohl(sdc->sdh_tsn), sctp->sctp_lastack_rxd));
   1596      0    stevel 	msg_hdr = (sctp_msg_hdr_t *)meta->b_rptr;
   1597      0    stevel 	if (!SCTP_IS_MSG_ABANDONED(meta) &&
   1598      0    stevel 	    !SCTP_MSG_TO_BE_ABANDONED(meta, msg_hdr, sctp)) {
   1599      0    stevel 		return;
   1600      0    stevel 	}
   1601      0    stevel 	while (meta != NULL) {
   1602      0    stevel 		while (mp != NULL && SCTP_CHUNK_ISSENT(mp)) {
   1603      0    stevel 			sdc = (sctp_data_hdr_t *)mp->b_rptr;
   1604      0    stevel 			tsn = ntohl(sdc->sdh_tsn);
   1605      0    stevel 			mp = mp->b_next;
   1606      0    stevel 		}
   1607      0    stevel 		if (mp != NULL)
   1608      0    stevel 			break;
   1609      0    stevel 		/*
   1610      0    stevel 		 * We continue checking for successive messages only if there
   1611      0    stevel 		 * is a chunk marked for retransmission. Else, we might
   1612      0    stevel 		 * end up sending FTSN prematurely for chunks that have been
   1613      0    stevel 		 * sent, but not yet acked.
   1614      0    stevel 		 */
   1615      0    stevel 		if ((meta = meta->b_next) != NULL) {
   1616      0    stevel 			msg_hdr = (sctp_msg_hdr_t *)meta->b_rptr;
   1617      0    stevel 			if (!SCTP_IS_MSG_ABANDONED(meta) &&
   1618      0    stevel 			    !SCTP_MSG_TO_BE_ABANDONED(meta, msg_hdr, sctp)) {
   1619      0    stevel 				break;
   1620      0    stevel 			}
   1621      0    stevel 			for (mp = meta->b_cont; mp != NULL; mp = mp->b_next) {
   1622      0    stevel 				if (!SCTP_CHUNK_ISSENT(mp)) {
   1623      0    stevel 					sctp->sctp_adv_pap = tsn;
   1624      0    stevel 					return;
   1625      0    stevel 				}
   1626      0    stevel 				if (SCTP_CHUNK_WANT_REXMIT(mp))
   1627      0    stevel 					break;
   1628      0    stevel 			}
   1629      0    stevel 			if (mp == NULL)
   1630      0    stevel 				break;
   1631      0    stevel 		}
   1632      0    stevel 	}
   1633      0    stevel 	sctp->sctp_adv_pap = tsn;
   1634      0    stevel }
   1635      0    stevel 
   1636   1735    kcpoon 
   1637   1735    kcpoon /*
   1638   1735    kcpoon  * Determine if we should bundle a data chunk with the chunk being
   1639   1735    kcpoon  * retransmitted.  We bundle if
   1640   1735    kcpoon  *
   1641   1735    kcpoon  * - the chunk is sent to the same destination and unack'ed.
   1642   1735    kcpoon  *
   1643   1735    kcpoon  * OR
   1644   1735    kcpoon  *
   1645   1735    kcpoon  * - the chunk is unsent, i.e. new data.
   1646   1735    kcpoon  */
   1647   1735    kcpoon #define	SCTP_CHUNK_RX_CANBUNDLE(mp, fp)					\
   1648   1735    kcpoon 	(!SCTP_CHUNK_ABANDONED((mp)) && 				\
   1649   1735    kcpoon 	((SCTP_CHUNK_ISSENT((mp)) && (SCTP_CHUNK_DEST(mp) == (fp) &&	\
   1650   1735    kcpoon 	!SCTP_CHUNK_ISACKED(mp))) ||					\
   1651   1735    kcpoon 	(((mp)->b_flag & (SCTP_CHUNK_FLAG_REXMIT|SCTP_CHUNK_FLAG_SENT)) != \
   1652   1735    kcpoon 	SCTP_CHUNK_FLAG_SENT)))
   1653   1735    kcpoon 
   1654      0    stevel /*
   1655      0    stevel  * Retransmit first segment which hasn't been acked with cumtsn or send
   1656      0    stevel  * a Forward TSN chunk, if appropriate.
   1657      0    stevel  */
   1658      0    stevel void
   1659      0    stevel sctp_rexmit(sctp_t *sctp, sctp_faddr_t *oldfp)
   1660      0    stevel {
   1661      0    stevel 	mblk_t		*mp;
   1662      0    stevel 	mblk_t		*nmp = NULL;
   1663      0    stevel 	mblk_t		*head;
   1664      0    stevel 	mblk_t		*meta = sctp->sctp_xmit_head;
   1665      0    stevel 	mblk_t		*fill;
   1666      0    stevel 	uint32_t	seglen = 0;
   1667      0    stevel 	uint32_t	sacklen;
   1668      0    stevel 	uint16_t	chunklen;
   1669      0    stevel 	int		extra;
   1670      0    stevel 	sctp_data_hdr_t	*sdc;
   1671      0    stevel 	sctp_faddr_t	*fp;
   1672      0    stevel 	uint32_t	adv_pap = sctp->sctp_adv_pap;
   1673      0    stevel 	boolean_t	do_ftsn = B_FALSE;
   1674      0    stevel 	boolean_t	ftsn_check = B_TRUE;
   1675   1735    kcpoon 	uint32_t	first_ua_tsn;
   1676   1735    kcpoon 	sctp_msg_hdr_t	*mhdr;
   1677   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
   1678   8154    George 	int		error;
   1679      0    stevel 
   1680      0    stevel 	while (meta != NULL) {
   1681      0    stevel 		for (mp = meta->b_cont; mp != NULL; mp = mp->b_next) {
   1682      0    stevel 			uint32_t	tsn;
   1683      0    stevel 
   1684      0    stevel 			if (!SCTP_CHUNK_ISSENT(mp))
   1685      0    stevel 				goto window_probe;
   1686      0    stevel 			/*
   1687      0    stevel 			 * We break in the following cases -
   1688      0    stevel 			 *
   1689      0    stevel 			 *	if the advanced peer ack point includes the next
   1690      0    stevel 			 *	chunk to be retransmited - possibly the Forward
   1691      0    stevel 			 * 	TSN was lost.
   1692      0    stevel 			 *
   1693      0    stevel 			 *	if we are PRSCTP aware and the next chunk to be
   1694      0    stevel 			 *	retransmitted is now abandoned
   1695      0    stevel 			 *
   1696      0    stevel 			 *	if the next chunk to be retransmitted is for
   1697      0    stevel 			 *	the dest on which the timer went off. (this
   1698      0    stevel 			 *	message is not abandoned).
   1699      0    stevel 			 *
   1700      0    stevel 			 * We check for Forward TSN only for the first
   1701      0    stevel 			 * eligible chunk to be retransmitted. The reason
   1702      0    stevel 			 * being if the first eligible chunk is skipped (say
   1703      0    stevel 			 * it was sent to a destination other than oldfp)
   1704      0    stevel 			 * then we cannot advance the cum TSN via Forward
   1705      0    stevel 			 * TSN chunk.
   1706      0    stevel 			 *
   1707      0    stevel 			 * Also, ftsn_check is B_TRUE only for the first
   1708      0    stevel 			 * eligible chunk, it  will be B_FALSE for all
   1709      0    stevel 			 * subsequent candidate messages for retransmission.
   1710      0    stevel 			 */
   1711      0    stevel 			sdc = (sctp_data_hdr_t *)mp->b_rptr;
   1712      0    stevel 			tsn = ntohl(sdc->sdh_tsn);
   1713      0    stevel 			if (SEQ_GT(tsn, sctp->sctp_lastack_rxd)) {
   1714      0    stevel 				if (sctp->sctp_prsctp_aware && ftsn_check) {
   1715      0    stevel 					if (SEQ_GEQ(sctp->sctp_adv_pap, tsn)) {
   1716      0    stevel 						ASSERT(sctp->sctp_prsctp_aware);
   1717      0    stevel 						do_ftsn = B_TRUE;
   1718      0    stevel 						goto out;
   1719      0    stevel 					} else {
   1720      0    stevel 						sctp_check_adv_ack_pt(sctp,
   1721      0    stevel 						    meta, mp);
   1722      0    stevel 						if (SEQ_GT(sctp->sctp_adv_pap,
   1723      0    stevel 						    adv_pap)) {
   1724      0    stevel 							do_ftsn = B_TRUE;
   1725      0    stevel 							goto out;
   1726      0    stevel 						}
   1727      0    stevel 					}
   1728      0    stevel 					ftsn_check = B_FALSE;
   1729      0    stevel 				}
   1730      0    stevel 				if (SCTP_CHUNK_DEST(mp) == oldfp)
   1731      0    stevel 					goto out;
   1732      0    stevel 			}
   1733      0    stevel 		}
   1734      0    stevel 		meta = meta->b_next;
   1735      0    stevel 		if (meta != NULL && sctp->sctp_prsctp_aware) {
   1736   1735    kcpoon 			mhdr = (sctp_msg_hdr_t *)meta->b_rptr;
   1737      0    stevel 
   1738      0    stevel 			while (meta != NULL && (SCTP_IS_MSG_ABANDONED(meta) ||
   1739      0    stevel 			    SCTP_MSG_TO_BE_ABANDONED(meta, mhdr, sctp))) {
   1740      0    stevel 				meta = meta->b_next;
   1741      0    stevel 			}
   1742      0    stevel 		}
   1743      0    stevel 	}
   1744      0    stevel window_probe:
   1745      0    stevel 	/*
   1746      0    stevel 	 * Retransmit fired for a destination which didn't have
   1747      0    stevel 	 * any unacked data pending.
   1748      0    stevel 	 */
   1749   1932  vi117747 	if (sctp->sctp_unacked == 0 && sctp->sctp_unsent != 0) {
   1750      0    stevel 		/*
   1751      0    stevel 		 * Send a window probe. Inflate frwnd to allow
   1752      0    stevel 		 * sending one segment.
   1753      0    stevel 		 */
   1754   1932  vi117747 		if (sctp->sctp_frwnd < (oldfp->sfa_pmss - sizeof (*sdc)))
   1755      0    stevel 			sctp->sctp_frwnd = oldfp->sfa_pmss - sizeof (*sdc);
   1756   3795    kcpoon 
   1757   1932  vi117747 		/* next TSN to send */
   1758   1932  vi117747 		sctp->sctp_rxt_nxttsn = sctp->sctp_ltsn;
   1759   3795    kcpoon 
   1760   3795    kcpoon 		/*
   1761   3795    kcpoon 		 * The above sctp_frwnd adjustment is coarse.  The "changed"
   1762   3795    kcpoon 		 * sctp_frwnd may allow us to send more than 1 packet.  So
   1763   3795    kcpoon 		 * tell sctp_output() to send only 1 packet.
   1764   3795    kcpoon 		 */
   1765   3795    kcpoon 		sctp_output(sctp, 1);
   1766   3795    kcpoon 
   1767   1932  vi117747 		/* Last sent TSN */
   1768   1932  vi117747 		sctp->sctp_rxt_maxtsn = sctp->sctp_ltsn - 1;
   1769   1932  vi117747 		ASSERT(sctp->sctp_rxt_maxtsn >= sctp->sctp_rxt_nxttsn);
   1770   1932  vi117747 		sctp->sctp_zero_win_probe = B_TRUE;
   1771   3448  dh155122 		BUMP_MIB(&sctps->sctps_mib, sctpOutWinProbe);
   1772      0    stevel 	}
   1773      0    stevel 	return;
   1774      0    stevel out:
   1775   1932  vi117747 	/*
   1776   3795    kcpoon 	 * After a time out, assume that everything has left the network.  So
   1777   3795    kcpoon 	 * we can clear rxt_unacked for the original peer address.
   1778   3795    kcpoon 	 */
   1779   3795    kcpoon 	oldfp->rxt_unacked = 0;
   1780   3795    kcpoon 
   1781   3795    kcpoon 	/*
   1782   3795    kcpoon 	 * If we were probing for zero window, don't adjust retransmission
   1783   1932  vi117747 	 * variables, but the timer is still backed off.
   1784   1932  vi117747 	 */
   1785   1932  vi117747 	if (sctp->sctp_zero_win_probe) {
   1786   1932  vi117747 		mblk_t	*pkt;
   1787   1932  vi117747 		uint_t	pkt_len;
   1788   1932  vi117747 
   1789   1932  vi117747 		/*
   1790   1932  vi117747 		 * Get the Zero Win Probe for retrasmission, sctp_rxt_nxttsn
   1791   1932  vi117747 		 * and sctp_rxt_maxtsn will specify the ZWP packet.
   1792   1932  vi117747 		 */
   1793   1932  vi117747 		fp = oldfp;
   1794   1932  vi117747 		if (oldfp->state != SCTP_FADDRS_ALIVE)
   1795   1932  vi117747 			fp = sctp_rotate_faddr(sctp, oldfp);
   1796   1932  vi117747 		pkt = sctp_rexmit_packet(sctp, &meta, &mp, fp, &pkt_len);
   1797   1932  vi117747 		if (pkt != NULL) {
   1798   1932  vi117747 			ASSERT(pkt_len <= fp->sfa_pmss);
   1799  11042      Erik 			sctp_set_iplen(sctp, pkt, fp->ixa);
   1800  11042      Erik 			(void) conn_ip_output(pkt, fp->ixa);
   1801  11042      Erik 			BUMP_LOCAL(sctp->sctp_opkts);
   1802   1932  vi117747 		} else {
   1803   3448  dh155122 			SCTP_KSTAT(sctps, sctp_ss_rexmit_failed);
   1804   1932  vi117747 		}
   1805   3795    kcpoon 
   1806   3795    kcpoon 		/*
   1807   3795    kcpoon 		 * The strikes will be clear by sctp_faddr_alive() when the
   1808   3795    kcpoon 		 * other side sends us an ack.
   1809   3795    kcpoon 		 */
   1810   1932  vi117747 		oldfp->strikes++;
   1811   1932  vi117747 		sctp->sctp_strikes++;
   1812   3795    kcpoon 
   1813  10212    George 		SCTP_CALC_RXT(sctp, oldfp);
   1814   1932  vi117747 		if (oldfp != fp && oldfp->suna != 0)
   1815   1932  vi117747 			SCTP_FADDR_TIMER_RESTART(sctp, oldfp, fp->rto);
   1816   1932  vi117747 		SCTP_FADDR_TIMER_RESTART(sctp, fp, fp->rto);
   1817   3448  dh155122 		BUMP_MIB(&sctps->sctps_mib, sctpOutWinProbe);
   1818   1932  vi117747 		return;
   1819   1932  vi117747 	}
   1820   1932  vi117747 
   1821      0    stevel 	/*
   1822      0    stevel 	 * Enter slowstart for this destination
   1823      0    stevel 	 */
   1824      0    stevel 	oldfp->ssthresh = oldfp->cwnd / 2;
   1825      0    stevel 	if (oldfp->ssthresh < 2 * oldfp->sfa_pmss)
   1826      0    stevel 		oldfp->ssthresh = 2 * oldfp->sfa_pmss;
   1827      0    stevel 	oldfp->cwnd = oldfp->sfa_pmss;
   1828      0    stevel 	oldfp->pba = 0;
   1829      0    stevel 	fp = sctp_rotate_faddr(sctp, oldfp);
   1830      0    stevel 	ASSERT(fp != NULL);
   1831      0    stevel 	sdc = (sctp_data_hdr_t *)mp->b_rptr;
   1832      0    stevel 
   1833   1735    kcpoon 	first_ua_tsn = ntohl(sdc->sdh_tsn);
   1834      0    stevel 	if (do_ftsn) {
   1835      0    stevel 		sctp_make_ftsns(sctp, meta, mp, &nmp, fp, &seglen);
   1836      0    stevel 		if (nmp == NULL) {
   1837      0    stevel 			sctp->sctp_adv_pap = adv_pap;
   1838      0    stevel 			goto restart_timer;
   1839      0    stevel 		}
   1840      0    stevel 		head = nmp;
   1841   1735    kcpoon 		/*
   1842   1735    kcpoon 		 * Move to the next unabandoned chunk. XXXCheck if meta will
   1843   1735    kcpoon 		 * always be marked abandoned.
   1844   1735    kcpoon 		 */
   1845   1735    kcpoon 		while (meta != NULL && SCTP_IS_MSG_ABANDONED(meta))
   1846   1735    kcpoon 			meta = meta->b_next;
   1847      0    stevel 		if (meta != NULL)
   1848   1735    kcpoon 			mp = mp->b_cont;
   1849   1735    kcpoon 		else
   1850   1735    kcpoon 			mp = NULL;
   1851      0    stevel 		goto try_bundle;
   1852      0    stevel 	}
   1853      0    stevel 	seglen = ntohs(sdc->sdh_len);
   1854      0    stevel 	chunklen = seglen - sizeof (*sdc);
   1855      0    stevel 	if ((extra = seglen & (SCTP_ALIGN - 1)) != 0)
   1856      0    stevel 		extra = SCTP_ALIGN - extra;
   1857   1735    kcpoon 
   1858   1735    kcpoon 	/* Find out if we need to piggyback SACK. */
   1859   1735    kcpoon 	if (sctp->sctp_ftsn == sctp->sctp_lastacked + 1) {
   1860   1735    kcpoon 		sacklen = 0;
   1861   1735    kcpoon 	} else {
   1862   1735    kcpoon 		sacklen = sizeof (sctp_chunk_hdr_t) +
   1863   1735    kcpoon 		    sizeof (sctp_sack_chunk_t) +
   1864   1735    kcpoon 		    (sizeof (sctp_sack_frag_t) * sctp->sctp_sack_gaps);
   1865   1735    kcpoon 		if (seglen + sacklen > sctp->sctp_lastdata->sfa_pmss) {
   1866   1735    kcpoon 			/* piggybacked SACK doesn't fit */
   1867   1735    kcpoon 			sacklen = 0;
   1868   1735    kcpoon 		} else {
   1869   1735    kcpoon 			/*
   1870   1735    kcpoon 			 * OK, we have room to send SACK back.  But we
   1871   1735    kcpoon 			 * should send it back to the last fp where we
   1872   1735    kcpoon 			 * receive data from, unless sctp_lastdata equals
   1873   1735    kcpoon 			 * oldfp, then we should probably not send it
   1874   1735    kcpoon 			 * back to that fp.  Also we should check that
   1875   1735    kcpoon 			 * the fp is alive.
   1876   1735    kcpoon 			 */
   1877   1735    kcpoon 			if (sctp->sctp_lastdata != oldfp &&
   1878   1735    kcpoon 			    sctp->sctp_lastdata->state == SCTP_FADDRS_ALIVE) {
   1879   1735    kcpoon 				fp = sctp->sctp_lastdata;
   1880   1735    kcpoon 			}
   1881   1735    kcpoon 		}
   1882   1735    kcpoon 	}
   1883      0    stevel 
   1884      0    stevel 	/*
   1885      0    stevel 	 * Cancel RTT measurement if the retransmitted TSN is before the
   1886      0    stevel 	 * TSN used for timimg.
   1887      0    stevel 	 */
   1888      0    stevel 	if (sctp->sctp_out_time != 0 &&
   1889      0    stevel 	    SEQ_GEQ(sctp->sctp_rtt_tsn, sdc->sdh_tsn)) {
   1890      0    stevel 		sctp->sctp_out_time = 0;
   1891      0    stevel 	}
   1892      0    stevel 	/* Clear the counter as the RTT calculation may be off. */
   1893      0    stevel 	fp->rtt_updates = 0;
   1894   1735    kcpoon 	oldfp->rtt_updates = 0;
   1895      0    stevel 
   1896   1735    kcpoon 	/*
   1897   1735    kcpoon 	 * After a timeout, we should change the current faddr so that
   1898   1735    kcpoon 	 * new chunks will be sent to the alternate address.
   1899   1735    kcpoon 	 */
   1900   1735    kcpoon 	sctp_set_faddr_current(sctp, fp);
   1901      0    stevel 
   1902      0    stevel 	nmp = dupmsg(mp);
   1903      0    stevel 	if (nmp == NULL)
   1904      0    stevel 		goto restart_timer;
   1905      0    stevel 	if (extra > 0) {
   1906   4691    kcpoon 		fill = sctp_get_padding(sctp, extra);
   1907      0    stevel 		if (fill != NULL) {
   1908      0    stevel 			linkb(nmp, fill);
   1909      0    stevel 			seglen += extra;
   1910      0    stevel 		} else {
   1911      0    stevel 			freemsg(nmp);
   1912      0    stevel 			goto restart_timer;
   1913      0    stevel 		}
   1914      0    stevel 	}
   1915      0    stevel 	SCTP_CHUNK_CLEAR_FLAGS(nmp);
   1916    252  vi117747 	head = sctp_add_proto_hdr(sctp, fp, nmp, sacklen, NULL);
   1917      0    stevel 	if (head == NULL) {
   1918      0    stevel 		freemsg(nmp);
   1919   3448  dh155122 		SCTP_KSTAT(sctps, sctp_rexmit_failed);
   1920      0    stevel 		goto restart_timer;
   1921      0    stevel 	}
   1922      0    stevel 	seglen += sacklen;
   1923      0    stevel 
   1924      0    stevel 	SCTP_CHUNK_SENT(sctp, mp, sdc, fp, chunklen, meta);
   1925      0    stevel 
   1926      0    stevel 	mp = mp->b_next;
   1927   1735    kcpoon 
   1928      0    stevel try_bundle:
   1929   3795    kcpoon 	/* We can at least and at most send 1 packet at timeout. */
   1930      0    stevel 	while (seglen < fp->sfa_pmss) {
   1931      0    stevel 		int32_t new_len;
   1932      0    stevel 
   1933   1735    kcpoon 		/* Go through the list to find more chunks to be bundled. */
   1934      0    stevel 		while (mp != NULL) {
   1935   1735    kcpoon 			/* Check if the chunk can be bundled. */
   1936   1735    kcpoon 			if (SCTP_CHUNK_RX_CANBUNDLE(mp, oldfp))
   1937      0    stevel 				break;
   1938      0    stevel 			mp = mp->b_next;
   1939      0    stevel 		}
   1940   1735    kcpoon 		/* Go to the next message. */
   1941      0    stevel 		if (mp == NULL) {
   1942   1735    kcpoon 			for (meta = meta->b_next; meta != NULL;
   1943   1735    kcpoon 			    meta = meta->b_next) {
   1944   1735    kcpoon 				mhdr = (sctp_msg_hdr_t *)meta->b_rptr;
   1945   1735    kcpoon 
   1946   1735    kcpoon 				if (SCTP_IS_MSG_ABANDONED(meta) ||
   1947   1735    kcpoon 				    SCTP_MSG_TO_BE_ABANDONED(meta, mhdr,
   1948   1735    kcpoon 				    sctp)) {
   1949   1735    kcpoon 					continue;
   1950   1735    kcpoon 				}
   1951   1735    kcpoon 
   1952   1735    kcpoon 				mp = meta->b_cont;
   1953   1735    kcpoon 				goto try_bundle;
   1954   1735    kcpoon 			}
   1955   8154    George 			/*
   1956   8154    George 			 * Check if there is a new message which potentially
   1957   8154    George 			 * could be bundled with this retransmission.
   1958   8154    George 			 */
   1959   8154    George 			meta = sctp_get_msg_to_send(sctp, &mp, NULL, &error,
   1960   8154    George 			    seglen, fp->sfa_pmss - seglen, NULL);
   1961   8154    George 			if (error != 0 || meta == NULL) {
   1962   8154    George 				/* No more chunk to be bundled. */
   1963   8154    George 				break;
   1964   8154    George 			} else {
   1965   8154    George 				goto try_bundle;
   1966   8154    George 			}
   1967      0    stevel 		}
   1968   1735    kcpoon 
   1969      0    stevel 		sdc = (sctp_data_hdr_t *)mp->b_rptr;
   1970   1735    kcpoon 		new_len = ntohs(sdc->sdh_len);
   1971   1735    kcpoon 		chunklen = new_len - sizeof (*sdc);
   1972      0    stevel 
   1973   1735    kcpoon 		if ((extra = new_len & (SCTP_ALIGN - 1)) != 0)
   1974   1735    kcpoon 			extra = SCTP_ALIGN - extra;
   1975   1735    kcpoon 		if ((new_len = seglen + new_len + extra) > fp->sfa_pmss)
   1976   1735    kcpoon 			break;
   1977   1735    kcpoon 		if ((nmp = dupmsg(mp)) == NULL)
   1978   1735    kcpoon 			break;
   1979      0    stevel 
   1980   1735    kcpoon 		if (extra > 0) {
   1981   4691    kcpoon 			fill = sctp_get_padding(sctp, extra);
   1982      0    stevel 			if (fill != NULL) {
   1983   1735    kcpoon 				linkb(nmp, fill);
   1984      0    stevel 			} else {
   1985   1735    kcpoon 				freemsg(nmp);
   1986      0    stevel 				break;
   1987      0    stevel 			}
   1988      0    stevel 		}
   1989   1735    kcpoon 		linkb(head, nmp);
   1990      0    stevel 
   1991      0    stevel 		SCTP_CHUNK_CLEAR_FLAGS(nmp);
   1992      0    stevel 		SCTP_CHUNK_SENT(sctp, mp, sdc, fp, chunklen, meta);
   1993   1735    kcpoon 
   1994   1735    kcpoon 		seglen = new_len;
   1995      0    stevel 		mp = mp->b_next;
   1996      0    stevel 	}
   1997   1735    kcpoon done_bundle:
   1998      0    stevel 	if ((seglen > fp->sfa_pmss) && fp->isv4) {
   1999      0    stevel 		ipha_t *iph = (ipha_t *)head->b_rptr;
   2000      0    stevel 
   2001      0    stevel 		/*
   2002      0    stevel 		 * Path MTU is different from path we thought it would
   2003      0    stevel 		 * be when we created chunks, or IP headers have grown.
   2004      0    stevel 		 * Need to clear the DF bit.
   2005      0    stevel 		 */
   2006      0    stevel 		iph->ipha_fragment_offset_and_flags = 0;
   2007      0    stevel 	}
   2008   3795    kcpoon 	fp->rxt_unacked += seglen;
   2009   3795    kcpoon 
   2010      0    stevel 	dprint(2, ("sctp_rexmit: Sending packet %d bytes, tsn %x "
   2011      0    stevel 	    "ssn %d to %p (rwnd %d, lastack_rxd %x)\n",
   2012   1676       jpk 	    seglen, ntohl(sdc->sdh_tsn), ntohs(sdc->sdh_ssn),
   2013   1676       jpk 	    (void *)fp, sctp->sctp_frwnd, sctp->sctp_lastack_rxd));
   2014      0    stevel 
   2015   1735    kcpoon 	sctp->sctp_rexmitting = B_TRUE;
   2016   1735    kcpoon 	sctp->sctp_rxt_nxttsn = first_ua_tsn;
   2017   1735    kcpoon 	sctp->sctp_rxt_maxtsn = sctp->sctp_ltsn - 1;
   2018  11042      Erik 	sctp_set_iplen(sctp, head, fp->ixa);
   2019  11042      Erik 	(void) conn_ip_output(head, fp->ixa);
   2020  11042      Erik 	BUMP_LOCAL(sctp->sctp_opkts);
   2021      0    stevel 
   2022      0    stevel 	/*
   2023   1735    kcpoon 	 * Restart the oldfp timer with exponential backoff and
   2024   1735    kcpoon 	 * the new fp timer for the retransmitted chunks.
   2025      0    stevel 	 */
   2026      0    stevel restart_timer:
   2027      0    stevel 	oldfp->strikes++;
   2028      0    stevel 	sctp->sctp_strikes++;
   2029  10212    George 	SCTP_CALC_RXT(sctp, oldfp);
   2030   4818    kcpoon 	/*
   2031   4818    kcpoon 	 * If there is still some data in the oldfp, restart the
   2032   4818    kcpoon 	 * retransmission timer.  If there is no data, the heartbeat will
   2033   4818    kcpoon 	 * continue to run so it will do its job in checking the reachability
   2034   4818    kcpoon 	 * of the oldfp.
   2035   4818    kcpoon 	 */
   2036   4818    kcpoon 	if (oldfp != fp && oldfp->suna != 0)
   2037      0    stevel 		SCTP_FADDR_TIMER_RESTART(sctp, oldfp, oldfp->rto);
   2038   1735    kcpoon 
   2039   1735    kcpoon 	/*
   2040   1735    kcpoon 	 * Should we restart the timer of the new fp?  If there is
   2041   1735    kcpoon 	 * outstanding data to the new fp, the timer should be
   2042   1735    kcpoon 	 * running already.  So restarting it means that the timer
   2043   1735    kcpoon 	 * will fire later for those outstanding data.  But if
   2044   1735    kcpoon 	 * we don't restart it, the timer will fire too early for the
   2045   1735    kcpoon 	 * just retransmitted chunks to the new fp.  The reason is that we
   2046   1735    kcpoon 	 * don't keep a timestamp on when a chunk is retransmitted.
   2047   1735    kcpoon 	 * So when the timer fires, it will just search for the
   2048   1735    kcpoon 	 * chunk with the earliest TSN sent to new fp.  This probably
   2049   1735    kcpoon 	 * is the chunk we just retransmitted.  So for now, let's
   2050   1735    kcpoon 	 * be conservative and restart the timer of the new fp.
   2051   1735    kcpoon 	 */
   2052   1735    kcpoon 	SCTP_FADDR_TIMER_RESTART(sctp, fp, fp->rto);
   2053   4818    kcpoon 
   2054  11066    rafael 	sctp->sctp_active = ddi_get_lbolt64();
   2055      0    stevel }
   2056      0    stevel 
   2057      0    stevel /*
   2058   1735    kcpoon  * This function is called by sctp_ss_rexmit() to create a packet
   2059   1735    kcpoon  * to be retransmitted to the given fp.  The given meta and mp
   2060   1735    kcpoon  * parameters are respectively the sctp_msg_hdr_t and the mblk of the
   2061   3795    kcpoon  * first chunk to be retransmitted.  This is also called when we want
   2062   1932  vi117747  * to retransmit a zero window probe from sctp_rexmit() or when we
   2063   1932  vi117747  * want to retransmit the zero window probe after the window has
   2064   1932  vi117747  * opened from sctp_got_sack().
   2065   1735    kcpoon  */
   2066   1932  vi117747 mblk_t *
   2067   1735    kcpoon sctp_rexmit_packet(sctp_t *sctp, mblk_t **meta, mblk_t **mp, sctp_faddr_t *fp,
   2068   1735    kcpoon     uint_t *packet_len)
   2069   1735    kcpoon {
   2070   1735    kcpoon 	uint32_t	seglen = 0;
   2071   1735    kcpoon 	uint16_t	chunklen;
   2072   1735    kcpoon 	int		extra;
   2073   1735    kcpoon 	mblk_t		*nmp;
   2074   1735    kcpoon 	mblk_t		*head;
   2075   1735    kcpoon 	mblk_t		*fill;
   2076   1735    kcpoon 	sctp_data_hdr_t	*sdc;
   2077   1735    kcpoon 	sctp_msg_hdr_t	*mhdr;
   2078   1735    kcpoon 
   2079   1735    kcpoon 	sdc = (sctp_data_hdr_t *)(*mp)->b_rptr;
   2080   1735    kcpoon 	seglen = ntohs(sdc->sdh_len);
   2081   1735    kcpoon 	chunklen = seglen - sizeof (*sdc);
   2082   1735    kcpoon 	if ((extra = seglen & (SCTP_ALIGN - 1)) != 0)
   2083   1735    kcpoon 		extra = SCTP_ALIGN - extra;
   2084   1735    kcpoon 
   2085   1735    kcpoon 	nmp = dupmsg(*mp);
   2086   1735    kcpoon 	if (nmp == NULL)
   2087   1735    kcpoon 		return (NULL);
   2088   1735    kcpoon 	if (extra > 0) {
   2089   4691    kcpoon 		fill = sctp_get_padding(sctp, extra);
   2090   1735    kcpoon 		if (fill != NULL) {
   2091   1735    kcpoon 			linkb(nmp, fill);
   2092   1735    kcpoon 			seglen += extra;
   2093   1735    kcpoon 		} else {
   2094   1735    kcpoon 			freemsg(nmp);
   2095   1735    kcpoon 			return (NULL);
   2096   1735    kcpoon 		}
   2097   1735    kcpoon 	}
   2098   1735    kcpoon 	SCTP_CHUNK_CLEAR_FLAGS(nmp);
   2099   1735    kcpoon 	head = sctp_add_proto_hdr(sctp, fp, nmp, 0, NULL);
   2100   1735    kcpoon 	if (head == NULL) {
   2101   1735    kcpoon 		freemsg(nmp);
   2102   1735    kcpoon 		return (NULL);
   2103   1735    kcpoon 	}
   2104   1735    kcpoon 	SCTP_CHUNK_SENT(sctp, *mp, sdc, fp, chunklen, *meta);
   2105   1932  vi117747 	/*
   2106   1932  vi117747 	 * Don't update the TSN if we are doing a Zero Win Probe.
   2107   1932  vi117747 	 */
   2108   1932  vi117747 	if (!sctp->sctp_zero_win_probe)
   2109   1932  vi117747 		sctp->sctp_rxt_nxttsn = ntohl(sdc->sdh_tsn);
   2110   1735    kcpoon 	*mp = (*mp)->b_next;
   2111   1735    kcpoon 
   2112   1735    kcpoon try_bundle:
   2113   1735    kcpoon 	while (seglen < fp->sfa_pmss) {
   2114   1735    kcpoon 		int32_t new_len;
   2115   1735    kcpoon 
   2116   1735    kcpoon 		/*
   2117   1735    kcpoon 		 * Go through the list to find more chunks to be bundled.
   2118   1735    kcpoon 		 * We should only retransmit sent by unack'ed chunks.  Since
   2119   1735    kcpoon 		 * they were sent before, the peer's receive window should
   2120   1735    kcpoon 		 * be able to receive them.
   2121   1735    kcpoon 		 */
   2122   1735    kcpoon 		while (*mp != NULL) {
   2123   1735    kcpoon 			/* Check if the chunk can be bundled. */
   2124   1735    kcpoon 			if (SCTP_CHUNK_ISSENT(*mp) && !SCTP_CHUNK_ISACKED(*mp))
   2125   1735    kcpoon 				break;
   2126   1735    kcpoon 			*mp = (*mp)->b_next;
   2127   1735    kcpoon 		}
   2128   1735    kcpoon 		/* Go to the next message. */
   2129   1735    kcpoon 		if (*mp == NULL) {
   2130   1735    kcpoon 			for (*meta = (*meta)->b_next; *meta != NULL;
   2131   1735    kcpoon 			    *meta = (*meta)->b_next) {
   2132   1735    kcpoon 				mhdr = (sctp_msg_hdr_t *)(*meta)->b_rptr;
   2133   1735    kcpoon 
   2134   1735    kcpoon 				if (SCTP_IS_MSG_ABANDONED(*meta) ||
   2135   1735    kcpoon 				    SCTP_MSG_TO_BE_ABANDONED(*meta, mhdr,
   2136   1735    kcpoon 				    sctp)) {
   2137   1735    kcpoon 					continue;
   2138   1735    kcpoon 				}
   2139   1735    kcpoon 
   2140   1735    kcpoon 				*mp = (*meta)->b_cont;
   2141   1735    kcpoon 				goto try_bundle;
   2142   1735    kcpoon 			}
   2143   1735    kcpoon 			/* No more chunk to be bundled. */
   2144   1735    kcpoon 			break;
   2145   1735    kcpoon 		}
   2146   1735    kcpoon 
   2147   1735    kcpoon 		sdc = (sctp_data_hdr_t *)(*mp)->b_rptr;
   2148   1735    kcpoon 		/* Don't bundle chunks beyond sctp_rxt_maxtsn. */
   2149   1735    kcpoon 		if (SEQ_GT(ntohl(sdc->sdh_tsn), sctp->sctp_rxt_maxtsn))
   2150   1735    kcpoon 			break;
   2151   1735    kcpoon 		new_len = ntohs(sdc->sdh_len);
   2152   1735    kcpoon 		chunklen = new_len - sizeof (*sdc);
   2153   1735    kcpoon 
   2154   1735    kcpoon 		if ((extra = new_len & (SCTP_ALIGN - 1)) != 0)
   2155   1735    kcpoon 			extra = SCTP_ALIGN - extra;
   2156   1735    kcpoon 		if ((new_len = seglen + new_len + extra) > fp->sfa_pmss)
   2157   1735    kcpoon 			break;
   2158   1735    kcpoon 		if ((nmp = dupmsg(*mp)) == NULL)
   2159   1735    kcpoon 			break;
   2160   1735    kcpoon 
   2161   1735    kcpoon 		if (extra > 0) {
   2162   4691    kcpoon 			fill = sctp_get_padding(sctp, extra);
   2163   1735    kcpoon 			if (fill != NULL) {
   2164   1735    kcpoon 				linkb(nmp, fill);
   2165   1735    kcpoon 			} else {
   2166   1735    kcpoon 				freemsg(nmp);
   2167   1735    kcpoon 				break;
   2168   1735    kcpoon 			}
   2169   1735    kcpoon 		}
   2170   1735    kcpoon 		linkb(head, nmp);
   2171   1735    kcpoon 
   2172   1735    kcpoon 		SCTP_CHUNK_CLEAR_FLAGS(nmp);
   2173   1735    kcpoon 		SCTP_CHUNK_SENT(sctp, *mp, sdc, fp, chunklen, *meta);
   2174   1932  vi117747 		/*
   2175   1932  vi117747 		 * Don't update the TSN if we are doing a Zero Win Probe.
   2176   1932  vi117747 		 */
   2177   1932  vi117747 		if (!sctp->sctp_zero_win_probe)
   2178   1932  vi117747 			sctp->sctp_rxt_nxttsn = ntohl(sdc->sdh_tsn);
   2179   1735    kcpoon 
   2180   1735    kcpoon 		seglen = new_len;
   2181   1735    kcpoon 		*mp = (*mp)->b_next;
   2182   1735    kcpoon 	}
   2183   1735    kcpoon 	*packet_len = seglen;
   2184   3795    kcpoon 	fp->rxt_unacked += seglen;
   2185   1735    kcpoon 	return (head);
   2186   1735    kcpoon }
   2187   1735    kcpoon 
   2188   1735    kcpoon /*
   2189   1735    kcpoon  * sctp_ss_rexmit() is called when we get a SACK after a timeout which
   2190   1735    kcpoon  * advances the cum_tsn but the cum_tsn is still less than what we have sent
   2191   1735    kcpoon  * (sctp_rxt_maxtsn) at the time of the timeout.  This SACK is a "partial"
   2192   1735    kcpoon  * SACK.  We retransmit unacked chunks without having to wait for another
   2193   1735    kcpoon  * timeout.  The rationale is that the SACK should not be "partial" if all the
   2194   1735    kcpoon  * lost chunks have been retransmitted.  Since the SACK is "partial,"
   2195   1735    kcpoon  * the chunks between the cum_tsn and the sctp_rxt_maxtsn should still
   2196   1735    kcpoon  * be missing.  It is better for us to retransmit them now instead
   2197   1735    kcpoon  * of waiting for a timeout.
   2198   1735    kcpoon  */
   2199   1735    kcpoon void
   2200   1735    kcpoon sctp_ss_rexmit(sctp_t *sctp)
   2201   1735    kcpoon {
   2202   1735    kcpoon 	mblk_t		*meta;
   2203   1735    kcpoon 	mblk_t		*mp;
   2204   1735    kcpoon 	mblk_t		*pkt;
   2205   1735    kcpoon 	sctp_faddr_t	*fp;
   2206   1735    kcpoon 	uint_t		pkt_len;
   2207   1735    kcpoon 	uint32_t	tot_wnd;
   2208   1735    kcpoon 	sctp_data_hdr_t	*sdc;
   2209   1735    kcpoon 	int		burst;
   2210   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
   2211   1735    kcpoon 
   2212   1932  vi117747 	ASSERT(!sctp->sctp_zero_win_probe);
   2213   1932  vi117747 
   2214   1735    kcpoon 	/*
   2215   1735    kcpoon 	 * If the last cum ack is smaller than what we have just
   2216   1735    kcpoon 	 * retransmitted, simply return.
   2217   1735    kcpoon 	 */
   2218   1735    kcpoon 	if (SEQ_GEQ(sctp->sctp_lastack_rxd, sctp->sctp_rxt_nxttsn))
   2219   1735    kcpoon 		sctp->sctp_rxt_nxttsn = sctp->sctp_lastack_rxd + 1;
   2220   1735    kcpoon 	else
   2221   1735    kcpoon 		return;
   2222   1735    kcpoon 	ASSERT(SEQ_LEQ(sctp->sctp_rxt_nxttsn, sctp->sctp_rxt_maxtsn));
   2223   1735    kcpoon 
   2224   1735    kcpoon 	/*
   2225   1735    kcpoon 	 * After a timer fires, sctp_current should be set to the new
   2226   1735    kcpoon 	 * fp where the retransmitted chunks are sent.
   2227   1735    kcpoon 	 */
   2228   1735    kcpoon 	fp = sctp->sctp_current;
   2229   1735    kcpoon 
   2230   1735    kcpoon 	/*
   2231   3795    kcpoon 	 * Since we are retransmitting, we only need to use cwnd to determine
   2232   3795    kcpoon 	 * how much we can send as we were allowed (by peer's receive window)
   2233   3795    kcpoon 	 * to send those retransmitted chunks previously when they are first
   2234   3795    kcpoon 	 * sent.  If we record how much we have retransmitted but
   2235   3795    kcpoon 	 * unacknowledged using rxt_unacked, then the amount we can now send
   2236   3795    kcpoon 	 * is equal to cwnd minus rxt_unacked.
   2237   3795    kcpoon 	 *
   2238   3795    kcpoon 	 * The field rxt_unacked is incremented when we retransmit a packet
   2239   3795    kcpoon 	 * and decremented when we got a SACK acknowledging something.  And
   2240   3795    kcpoon 	 * it is reset when the retransmission timer fires as we assume that
   2241   3795    kcpoon 	 * all packets have left the network after a timeout.  If this
   2242   3795    kcpoon 	 * assumption is not true, it means that after a timeout, we can
   2243   3795    kcpoon 	 * get a SACK acknowledging more than rxt_unacked (its value only
   2244   3795    kcpoon 	 * contains what is retransmitted when the timer fires).  So
   2245   3795    kcpoon 	 * rxt_unacked will become very big (it is an unsiged int so going
   2246   3795    kcpoon 	 * negative means that the value is huge).  This is the reason we
   2247   3795    kcpoon 	 * always send at least 1 MSS bytes.
   2248   3795    kcpoon 	 *
   2249   3795    kcpoon 	 * The reason why we do not have an accurate count is that we
   2250   3795    kcpoon 	 * only know how many packets are outstanding (using the TSN numbers).
   2251   3795    kcpoon 	 * But we do not know how many bytes those packets contain.  To
   2252   3795    kcpoon 	 * have an accurate count, we need to walk through the send list.
   2253   3795    kcpoon 	 * As it is not really important to have an accurate count during
   2254   3795    kcpoon 	 * retransmission, we skip this walk to save some time.  This should
   2255   3795    kcpoon 	 * not make the retransmission too aggressive to cause congestion.
   2256   1735    kcpoon 	 */
   2257   3795    kcpoon 	if (fp->cwnd <= fp->rxt_unacked)
   2258   3795    kcpoon 		tot_wnd = fp->sfa_pmss;
   2259   1735    kcpoon 	else
   2260   3795    kcpoon 		tot_wnd = fp->cwnd - fp->rxt_unacked;
   2261   1735    kcpoon 
   2262   1735    kcpoon 	/* Find the first unack'ed chunk */
   2263   1735    kcpoon 	for (meta = sctp->sctp_xmit_head; meta != NULL; meta = meta->b_next) {
   2264   1735    kcpoon 		sctp_msg_hdr_t	*mhdr = (sctp_msg_hdr_t *)meta->b_rptr;
   2265   1735    kcpoon 
   2266   1735    kcpoon 		if (SCTP_IS_MSG_ABANDONED(meta) ||
   2267   1735    kcpoon 		    SCTP_MSG_TO_BE_ABANDONED(meta, mhdr, sctp)) {
   2268   1735    kcpoon 			continue;
   2269   1735    kcpoon 		}
   2270   1735    kcpoon 
   2271   1735    kcpoon 		for (mp = meta->b_cont; mp != NULL; mp = mp->b_next) {
   2272   1735    kcpoon 			/* Again, this may not be possible */
   2273   1735    kcpoon 			if (!SCTP_CHUNK_ISSENT(mp))
   2274   1735    kcpoon 				return;
   2275   1735    kcpoon 			sdc = (sctp_data_hdr_t *)mp->b_rptr;
   2276   1735    kcpoon 			if (ntohl(sdc->sdh_tsn) == sctp->sctp_rxt_nxttsn)
   2277   1735    kcpoon 				goto found_msg;
   2278   1735    kcpoon 		}
   2279   1735    kcpoon 	}
   2280   1735    kcpoon 
   2281   1735    kcpoon 	/* Everything is abandoned... */
   2282   1735    kcpoon 	return;
   2283   1735    kcpoon 
   2284   1735    kcpoon found_msg:
   2285   1735    kcpoon 	if (!fp->timer_running)
   2286   1735    kcpoon 		SCTP_FADDR_TIMER_RESTART(sctp, fp, fp->rto);
   2287   1735    kcpoon 	pkt = sctp_rexmit_packet(sctp, &meta, &mp, fp, &pkt_len);
   2288   1735    kcpoon 	if (pkt == NULL) {
   2289   3448  dh155122 		SCTP_KSTAT(sctps, sctp_ss_rexmit_failed);
   2290   1735    kcpoon 		return;
   2291   1735    kcpoon 	}
   2292   1735    kcpoon 	if ((pkt_len > fp->sfa_pmss) && fp->isv4) {
   2293   1735    kcpoon 		ipha_t	*iph = (ipha_t *)pkt->b_rptr;
   2294   1735    kcpoon 
   2295   1735    kcpoon 		/*
   2296   1735    kcpoon 		 * Path MTU is different from path we thought it would
   2297   1735    kcpoon 		 * be when we created chunks, or IP headers have grown.
   2298   1735    kcpoon 		 *  Need to clear the DF bit.
   2299   1735    kcpoon 		 */
   2300   1735    kcpoon 		iph->ipha_fragment_offset_and_flags = 0;
   2301   1735    kcpoon 	}
   2302  11042      Erik 	sctp_set_iplen(sctp, pkt, fp->ixa);
   2303  11042      Erik 	(void) conn_ip_output(pkt, fp->ixa);
   2304  11042      Erik 	BUMP_LOCAL(sctp->sctp_opkts);
   2305   1735    kcpoon 
   2306   1735    kcpoon 	/* Check and see if there is more chunk to be retransmitted. */
   2307   1735    kcpoon 	if (tot_wnd <= pkt_len || tot_wnd - pkt_len < fp->sfa_pmss ||
   2308   1735    kcpoon 	    meta == NULL)
   2309   1735    kcpoon 		return;
   2310   1735    kcpoon 	if (mp == NULL)
   2311   1735    kcpoon 		meta = meta->b_next;
   2312   1735    kcpoon 	if (meta == NULL)
   2313   1735    kcpoon 		return;
   2314   1735    kcpoon 
   2315   1735    kcpoon 	/* Retransmit another packet if the window allows. */
   2316   3448  dh155122 	for (tot_wnd -= pkt_len, burst = sctps->sctps_maxburst - 1;
   2317   1735    kcpoon 	    meta != NULL && burst > 0; meta = meta->b_next, burst--) {
   2318   1735    kcpoon 		if (mp == NULL)
   2319   1735    kcpoon 			mp = meta->b_cont;
   2320   1735    kcpoon 		for (; mp != NULL; mp = mp->b_next) {
   2321   1735    kcpoon 			/* Again, this may not be possible */
   2322   1735    kcpoon 			if (!SCTP_CHUNK_ISSENT(mp))
   2323   1735    kcpoon 				return;
   2324   1735    kcpoon 			if (!SCTP_CHUNK_ISACKED(mp))
   2325   1735    kcpoon 				goto found_msg;
   2326   1735    kcpoon 		}
   2327   1735    kcpoon 	}
   2328   1735    kcpoon }
   2329