17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
545916cd2Sjpk  * Common Development and Distribution License (the "License").
645916cd2Sjpk  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
2177c67f2fSkcpoon 
227c478bd9Sstevel@tonic-gate /*
23fd7b5aedSGeorge Shepherd  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
26c1bf5ca0SJohn Levon /*
27c1bf5ca0SJohn Levon  * Copyright (c) 2018, Joyent, Inc.
28c1bf5ca0SJohn Levon  */
29c1bf5ca0SJohn Levon 
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/stream.h>
327c478bd9Sstevel@tonic-gate #define	_SUN_TPI_VERSION 2
337c478bd9Sstevel@tonic-gate #include <sys/tihdr.h>
347c478bd9Sstevel@tonic-gate #include <sys/socket.h>
357c478bd9Sstevel@tonic-gate #include <sys/xti_inet.h>
367c478bd9Sstevel@tonic-gate #include <sys/systm.h>
377c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
387c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
397c478bd9Sstevel@tonic-gate #include <sys/kmem.h>
407c478bd9Sstevel@tonic-gate #include <sys/strsubr.h>
417c478bd9Sstevel@tonic-gate #include <sys/strsun.h>
427c478bd9Sstevel@tonic-gate #include <sys/policy.h>
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate #include <inet/common.h>
457c478bd9Sstevel@tonic-gate #include <netinet/ip6.h>
467c478bd9Sstevel@tonic-gate #include <inet/ip.h>
477c478bd9Sstevel@tonic-gate #include <inet/ip_ire.h>
4843d18f1cSpriyanka #include <inet/ip_if.h>
49bd670b35SErik Nordmark #include <inet/proto_set.h>
507c478bd9Sstevel@tonic-gate #include <inet/ipclassifier.h>
517c478bd9Sstevel@tonic-gate #include <inet/ipsec_impl.h>
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate #include <netinet/in.h>
547c478bd9Sstevel@tonic-gate #include <netinet/ip.h>
557c478bd9Sstevel@tonic-gate #include <netinet/tcp.h>
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate #include <inet/common.h>
587c478bd9Sstevel@tonic-gate #include <inet/ip.h>
597c478bd9Sstevel@tonic-gate #include <inet/ip6.h>
607c478bd9Sstevel@tonic-gate #include <inet/sctp_itf.h>
617c478bd9Sstevel@tonic-gate #include "sctp_impl.h"
627c478bd9Sstevel@tonic-gate #include "sctp_asconf.h"
637c478bd9Sstevel@tonic-gate #include "sctp_addr.h"
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate static int	sctp_getpeeraddrs(sctp_t *, void *, int *);
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate static int
sctp_get_status(sctp_t * sctp,void * ptr)687c478bd9Sstevel@tonic-gate sctp_get_status(sctp_t *sctp, void *ptr)
697c478bd9Sstevel@tonic-gate {
707c478bd9Sstevel@tonic-gate 	struct sctp_status *sstat = ptr;
717c478bd9Sstevel@tonic-gate 	sctp_faddr_t *fp;
727c478bd9Sstevel@tonic-gate 	struct sockaddr_in *sin;
737c478bd9Sstevel@tonic-gate 	struct sockaddr_in6 *sin6;
747c478bd9Sstevel@tonic-gate 	struct sctp_paddrinfo *sp;
757c478bd9Sstevel@tonic-gate 	mblk_t *meta, *mp;
767c478bd9Sstevel@tonic-gate 	int i;
77bd670b35SErik Nordmark 	conn_t	*connp = sctp->sctp_connp;
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 	sstat->sstat_state = sctp->sctp_state;
807c478bd9Sstevel@tonic-gate 	sstat->sstat_rwnd = sctp->sctp_frwnd;
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 	sp = &sstat->sstat_primary;
837c478bd9Sstevel@tonic-gate 	if (!sctp->sctp_primary) {
847c478bd9Sstevel@tonic-gate 		bzero(sp, sizeof (*sp));
857c478bd9Sstevel@tonic-gate 		goto noprim;
867c478bd9Sstevel@tonic-gate 	}
877c478bd9Sstevel@tonic-gate 	fp = sctp->sctp_primary;
887c478bd9Sstevel@tonic-gate 
896be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	if (fp->sf_isv4) {
907c478bd9Sstevel@tonic-gate 		sin = (struct sockaddr_in *)&sp->spinfo_address;
917c478bd9Sstevel@tonic-gate 		sin->sin_family = AF_INET;
92bd670b35SErik Nordmark 		sin->sin_port = connp->conn_fport;
936be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 		IN6_V4MAPPED_TO_INADDR(&fp->sf_faddr, &sin->sin_addr);
947c478bd9Sstevel@tonic-gate 		sp->spinfo_mtu = sctp->sctp_hdr_len;
957c478bd9Sstevel@tonic-gate 	} else {
967c478bd9Sstevel@tonic-gate 		sin6 = (struct sockaddr_in6 *)&sp->spinfo_address;
977c478bd9Sstevel@tonic-gate 		sin6->sin6_family = AF_INET6;
98bd670b35SErik Nordmark 		sin6->sin6_port = connp->conn_fport;
996be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 		sin6->sin6_addr = fp->sf_faddr;
1007c478bd9Sstevel@tonic-gate 		sp->spinfo_mtu = sctp->sctp_hdr6_len;
1017c478bd9Sstevel@tonic-gate 	}
1026be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	sp->spinfo_state = fp->sf_state == SCTP_FADDRS_ALIVE ? SCTP_ACTIVE :
1037c478bd9Sstevel@tonic-gate 	    SCTP_INACTIVE;
1046be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	sp->spinfo_cwnd = fp->sf_cwnd;
1056be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	sp->spinfo_srtt = fp->sf_srtt;
1066be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	sp->spinfo_rto = fp->sf_rto;
1076be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	sp->spinfo_mtu += fp->sf_pmss;
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate noprim:
1107c478bd9Sstevel@tonic-gate 	sstat->sstat_unackdata = 0;
1117c478bd9Sstevel@tonic-gate 	sstat->sstat_penddata = 0;
1127c478bd9Sstevel@tonic-gate 	sstat->sstat_instrms = sctp->sctp_num_istr;
1137c478bd9Sstevel@tonic-gate 	sstat->sstat_outstrms = sctp->sctp_num_ostr;
1147c478bd9Sstevel@tonic-gate 	sstat->sstat_fragmentation_point = sctp->sctp_mss -
1157c478bd9Sstevel@tonic-gate 	    sizeof (sctp_data_hdr_t);
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 	/* count unack'd */
1187c478bd9Sstevel@tonic-gate 	for (meta = sctp->sctp_xmit_head; meta; meta = meta->b_next) {
1197c478bd9Sstevel@tonic-gate 		for (mp = meta->b_cont; mp; mp = mp->b_next) {
1207c478bd9Sstevel@tonic-gate 			if (!SCTP_CHUNK_ISSENT(mp)) {
1217c478bd9Sstevel@tonic-gate 				break;
1227c478bd9Sstevel@tonic-gate 			}
1237c478bd9Sstevel@tonic-gate 			if (!SCTP_CHUNK_ISACKED(mp)) {
1247c478bd9Sstevel@tonic-gate 				sstat->sstat_unackdata++;
1257c478bd9Sstevel@tonic-gate 			}
1267c478bd9Sstevel@tonic-gate 		}
1277c478bd9Sstevel@tonic-gate 	}
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 	/*
1307c478bd9Sstevel@tonic-gate 	 * Count penddata chunks. We can only count chunks in SCTP (not
1317c478bd9Sstevel@tonic-gate 	 * data already delivered to socket layer).
1327c478bd9Sstevel@tonic-gate 	 */
1337c478bd9Sstevel@tonic-gate 	if (sctp->sctp_instr != NULL) {
1347c478bd9Sstevel@tonic-gate 		for (i = 0; i < sctp->sctp_num_istr; i++) {
1357c478bd9Sstevel@tonic-gate 			for (meta = sctp->sctp_instr[i].istr_reass;
1367c478bd9Sstevel@tonic-gate 			    meta != NULL; meta = meta->b_next) {
1377c478bd9Sstevel@tonic-gate 				for (mp = meta->b_cont; mp; mp = mp->b_cont) {
1387c478bd9Sstevel@tonic-gate 					if (DB_TYPE(mp) != M_CTL) {
1397c478bd9Sstevel@tonic-gate 						sstat->sstat_penddata++;
1407c478bd9Sstevel@tonic-gate 					}
1417c478bd9Sstevel@tonic-gate 				}
1427c478bd9Sstevel@tonic-gate 			}
1437c478bd9Sstevel@tonic-gate 		}
1447c478bd9Sstevel@tonic-gate 	}
1457c478bd9Sstevel@tonic-gate 	/* Un-Ordered Frag list */
1467c478bd9Sstevel@tonic-gate 	for (meta = sctp->sctp_uo_frags; meta != NULL; meta = meta->b_next)
1477c478bd9Sstevel@tonic-gate 		sstat->sstat_penddata++;
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 	return (sizeof (*sstat));
1507c478bd9Sstevel@tonic-gate }
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate /*
1537c478bd9Sstevel@tonic-gate  * SCTP_GET_PEER_ADDR_INFO
1547c478bd9Sstevel@tonic-gate  */
1557c478bd9Sstevel@tonic-gate static int
sctp_get_paddrinfo(sctp_t * sctp,void * ptr,socklen_t * optlen)1567c478bd9Sstevel@tonic-gate sctp_get_paddrinfo(sctp_t *sctp, void *ptr, socklen_t *optlen)
1577c478bd9Sstevel@tonic-gate {
1587c478bd9Sstevel@tonic-gate 	struct sctp_paddrinfo	*infop = ptr;
1597c478bd9Sstevel@tonic-gate 	struct sockaddr_in	*sin4;
1607c478bd9Sstevel@tonic-gate 	struct sockaddr_in6	*sin6;
1617c478bd9Sstevel@tonic-gate 	in6_addr_t		faddr;
1627c478bd9Sstevel@tonic-gate 	sctp_faddr_t		*fp;
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 	switch (infop->spinfo_address.ss_family) {
1657c478bd9Sstevel@tonic-gate 	case AF_INET:
1667c478bd9Sstevel@tonic-gate 		sin4 = (struct sockaddr_in *)&infop->spinfo_address;
1677c478bd9Sstevel@tonic-gate 		IN6_INADDR_TO_V4MAPPED(&sin4->sin_addr, &faddr);
1687c478bd9Sstevel@tonic-gate 		break;
1697c478bd9Sstevel@tonic-gate 	case AF_INET6:
1707c478bd9Sstevel@tonic-gate 		sin6 = (struct sockaddr_in6 *)&infop->spinfo_address;
1717c478bd9Sstevel@tonic-gate 		faddr = sin6->sin6_addr;
1727c478bd9Sstevel@tonic-gate 		break;
1737c478bd9Sstevel@tonic-gate 	default:
1747c478bd9Sstevel@tonic-gate 		return (EAFNOSUPPORT);
1757c478bd9Sstevel@tonic-gate 	}
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	if ((fp = sctp_lookup_faddr(sctp, &faddr)) == NULL)
1787c478bd9Sstevel@tonic-gate 		return (EINVAL);
1797c478bd9Sstevel@tonic-gate 
1806be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	infop->spinfo_state = (fp->sf_state == SCTP_FADDRS_ALIVE) ?
1816be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	    SCTP_ACTIVE : SCTP_INACTIVE;
1826be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	infop->spinfo_cwnd = fp->sf_cwnd;
1836be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	infop->spinfo_srtt = TICK_TO_MSEC(fp->sf_srtt);
1846be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	infop->spinfo_rto = TICK_TO_MSEC(fp->sf_rto);
1856be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	infop->spinfo_mtu = fp->sf_pmss;
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 	*optlen = sizeof (struct sctp_paddrinfo);
1887c478bd9Sstevel@tonic-gate 	return (0);
1897c478bd9Sstevel@tonic-gate }
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate /*
1927c478bd9Sstevel@tonic-gate  * SCTP_RTOINFO
1937c478bd9Sstevel@tonic-gate  */
1947c478bd9Sstevel@tonic-gate static int
sctp_get_rtoinfo(sctp_t * sctp,void * ptr)1957c478bd9Sstevel@tonic-gate sctp_get_rtoinfo(sctp_t *sctp, void *ptr)
1967c478bd9Sstevel@tonic-gate {
1977c478bd9Sstevel@tonic-gate 	struct sctp_rtoinfo *srto = ptr;
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 	srto->srto_initial = TICK_TO_MSEC(sctp->sctp_rto_initial);
2007c478bd9Sstevel@tonic-gate 	srto->srto_max = TICK_TO_MSEC(sctp->sctp_rto_max);
2017c478bd9Sstevel@tonic-gate 	srto->srto_min = TICK_TO_MSEC(sctp->sctp_rto_min);
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	return (sizeof (*srto));
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate static int
sctp_set_rtoinfo(sctp_t * sctp,const void * invalp)207bd670b35SErik Nordmark sctp_set_rtoinfo(sctp_t *sctp, const void *invalp)
2087c478bd9Sstevel@tonic-gate {
2097c478bd9Sstevel@tonic-gate 	const struct sctp_rtoinfo *srto;
2107c478bd9Sstevel@tonic-gate 	boolean_t ispriv;
211f4b3ec61Sdh 	sctp_stack_t	*sctps = sctp->sctp_sctps;
212bd670b35SErik Nordmark 	conn_t		*connp = sctp->sctp_connp;
21305cdb43cSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	uint32_t	new_min, new_max;
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	srto = invalp;
2167c478bd9Sstevel@tonic-gate 
217bd670b35SErik Nordmark 	ispriv = secpolicy_ip_config(connp->conn_cred, B_TRUE) == 0;
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	/*
2207c478bd9Sstevel@tonic-gate 	 * Bounds checking.  Priviledged user can set the RTO initial
2217c478bd9Sstevel@tonic-gate 	 * outside the ndd boundary.
2227c478bd9Sstevel@tonic-gate 	 */
2237c478bd9Sstevel@tonic-gate 	if (srto->srto_initial != 0 &&
224f4b3ec61Sdh 	    (!ispriv && (srto->srto_initial < sctps->sctps_rto_initialg_low ||
225b34b8d1aSkcpoon 	    srto->srto_initial > sctps->sctps_rto_initialg_high))) {
2267c478bd9Sstevel@tonic-gate 		return (EINVAL);
2277c478bd9Sstevel@tonic-gate 	}
2287c478bd9Sstevel@tonic-gate 	if (srto->srto_max != 0 &&
229f4b3ec61Sdh 	    (!ispriv && (srto->srto_max < sctps->sctps_rto_maxg_low ||
230b34b8d1aSkcpoon 	    srto->srto_max > sctps->sctps_rto_maxg_high))) {
2317c478bd9Sstevel@tonic-gate 		return (EINVAL);
2327c478bd9Sstevel@tonic-gate 	}
2337c478bd9Sstevel@tonic-gate 	if (srto->srto_min != 0 &&
234f4b3ec61Sdh 	    (!ispriv && (srto->srto_min < sctps->sctps_rto_ming_low ||
235b34b8d1aSkcpoon 	    srto->srto_min > sctps->sctps_rto_ming_high))) {
2367c478bd9Sstevel@tonic-gate 		return (EINVAL);
2377c478bd9Sstevel@tonic-gate 	}
2387c478bd9Sstevel@tonic-gate 
23905cdb43cSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	new_min = (srto->srto_min != 0) ? srto->srto_min : sctp->sctp_rto_min;
24005cdb43cSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	new_max = (srto->srto_max != 0) ? srto->srto_max : sctp->sctp_rto_max;
24105cdb43cSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	if (new_max < new_min) {
24205cdb43cSchandrasekar marimuthu - Sun Microsystems - Bangalore India 		return (EINVAL);
24305cdb43cSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	}
24405cdb43cSchandrasekar marimuthu - Sun Microsystems - Bangalore India 
2457c478bd9Sstevel@tonic-gate 	if (srto->srto_initial != 0) {
2467c478bd9Sstevel@tonic-gate 		sctp->sctp_rto_initial = MSEC_TO_TICK(srto->srto_initial);
2477c478bd9Sstevel@tonic-gate 	}
24805cdb43cSchandrasekar marimuthu - Sun Microsystems - Bangalore India 
24905cdb43cSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	/* Ensure that sctp_rto_max will never be zero. */
2507c478bd9Sstevel@tonic-gate 	if (srto->srto_max != 0) {
25105cdb43cSchandrasekar marimuthu - Sun Microsystems - Bangalore India 		sctp->sctp_rto_max = MAX(MSEC_TO_TICK(srto->srto_max), 1);
2527c478bd9Sstevel@tonic-gate 	}
2537c478bd9Sstevel@tonic-gate 	if (srto->srto_min != 0) {
2547c478bd9Sstevel@tonic-gate 		sctp->sctp_rto_min = MSEC_TO_TICK(srto->srto_min);
2557c478bd9Sstevel@tonic-gate 	}
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 	return (0);
2587c478bd9Sstevel@tonic-gate }
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate /*
2617c478bd9Sstevel@tonic-gate  * SCTP_ASSOCINFO
2627c478bd9Sstevel@tonic-gate  */
2637c478bd9Sstevel@tonic-gate static int
sctp_get_assocparams(sctp_t * sctp,void * ptr)2647c478bd9Sstevel@tonic-gate sctp_get_assocparams(sctp_t *sctp, void *ptr)
2657c478bd9Sstevel@tonic-gate {
2667c478bd9Sstevel@tonic-gate 	struct sctp_assocparams *sap = ptr;
2677c478bd9Sstevel@tonic-gate 	sctp_faddr_t *fp;
2687c478bd9Sstevel@tonic-gate 	uint16_t i;
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate 	sap->sasoc_asocmaxrxt = sctp->sctp_pa_max_rxt;
2717c478bd9Sstevel@tonic-gate 
2727c478bd9Sstevel@tonic-gate 	/*
2737c478bd9Sstevel@tonic-gate 	 * Count the number of peer addresses
2747c478bd9Sstevel@tonic-gate 	 */
2756be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	for (i = 0, fp = sctp->sctp_faddrs; fp != NULL; fp = fp->sf_next) {
2767c478bd9Sstevel@tonic-gate 		i++;
2777c478bd9Sstevel@tonic-gate 	}
2787c478bd9Sstevel@tonic-gate 	sap->sasoc_number_peer_destinations = i;
2797c478bd9Sstevel@tonic-gate 	sap->sasoc_peer_rwnd = sctp->sctp_frwnd;
2807c478bd9Sstevel@tonic-gate 	sap->sasoc_local_rwnd = sctp->sctp_rwnd;
2817c478bd9Sstevel@tonic-gate 	sap->sasoc_cookie_life = TICK_TO_MSEC(sctp->sctp_cookie_lifetime);
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate 	return (sizeof (*sap));
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate static int
sctp_set_assocparams(sctp_t * sctp,const void * invalp)287bd670b35SErik Nordmark sctp_set_assocparams(sctp_t *sctp, const void *invalp)
2887c478bd9Sstevel@tonic-gate {
2897c478bd9Sstevel@tonic-gate 	const struct sctp_assocparams *sap = invalp;
2907c478bd9Sstevel@tonic-gate 	uint32_t sum = 0;
2917c478bd9Sstevel@tonic-gate 	sctp_faddr_t *fp;
292f4b3ec61Sdh 	sctp_stack_t	*sctps = sctp->sctp_sctps;
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	if (sap->sasoc_asocmaxrxt) {
2957c478bd9Sstevel@tonic-gate 		if (sctp->sctp_faddrs) {
2967c478bd9Sstevel@tonic-gate 			/*
2977c478bd9Sstevel@tonic-gate 			 * Bounds check: as per rfc2960, assoc max retr cannot
2987c478bd9Sstevel@tonic-gate 			 * exceed the sum of all individual path max retr's.
2997c478bd9Sstevel@tonic-gate 			 */
3006be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			for (fp = sctp->sctp_faddrs; fp; fp = fp->sf_next) {
3016be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 				sum += fp->sf_max_retr;
3027c478bd9Sstevel@tonic-gate 			}
3037c478bd9Sstevel@tonic-gate 			if (sap->sasoc_asocmaxrxt > sum) {
3047c478bd9Sstevel@tonic-gate 				return (EINVAL);
3057c478bd9Sstevel@tonic-gate 			}
3067c478bd9Sstevel@tonic-gate 		}
307f4b3ec61Sdh 		if (sap->sasoc_asocmaxrxt < sctps->sctps_pa_max_retr_low ||
308f4b3ec61Sdh 		    sap->sasoc_asocmaxrxt > sctps->sctps_pa_max_retr_high) {
3097c478bd9Sstevel@tonic-gate 			/*
3107c478bd9Sstevel@tonic-gate 			 * Out of bounds.
3117c478bd9Sstevel@tonic-gate 			 */
3127c478bd9Sstevel@tonic-gate 			return (EINVAL);
3137c478bd9Sstevel@tonic-gate 		}
3147c478bd9Sstevel@tonic-gate 	}
3157c478bd9Sstevel@tonic-gate 	if (sap->sasoc_cookie_life != 0 &&
316f4b3ec61Sdh 	    (sap->sasoc_cookie_life < sctps->sctps_cookie_life_low ||
317b34b8d1aSkcpoon 	    sap->sasoc_cookie_life > sctps->sctps_cookie_life_high)) {
318b34b8d1aSkcpoon 		return (EINVAL);
3197c478bd9Sstevel@tonic-gate 	}
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 	if (sap->sasoc_asocmaxrxt > 0) {
3227c478bd9Sstevel@tonic-gate 		sctp->sctp_pa_max_rxt = sap->sasoc_asocmaxrxt;
3237c478bd9Sstevel@tonic-gate 	}
3247c478bd9Sstevel@tonic-gate 	if (sap->sasoc_cookie_life > 0) {
3257c478bd9Sstevel@tonic-gate 		sctp->sctp_cookie_lifetime = MSEC_TO_TICK(
3267c478bd9Sstevel@tonic-gate 		    sap->sasoc_cookie_life);
3277c478bd9Sstevel@tonic-gate 	}
3287c478bd9Sstevel@tonic-gate 	return (0);
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate /*
3327c478bd9Sstevel@tonic-gate  * SCTP_INITMSG
3337c478bd9Sstevel@tonic-gate  */
3347c478bd9Sstevel@tonic-gate static int
sctp_get_initmsg(sctp_t * sctp,void * ptr)3357c478bd9Sstevel@tonic-gate sctp_get_initmsg(sctp_t *sctp, void *ptr)
3367c478bd9Sstevel@tonic-gate {
3377c478bd9Sstevel@tonic-gate 	struct sctp_initmsg *si = ptr;
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate 	si->sinit_num_ostreams = sctp->sctp_num_ostr;
3407c478bd9Sstevel@tonic-gate 	si->sinit_max_instreams = sctp->sctp_num_istr;
3417c478bd9Sstevel@tonic-gate 	si->sinit_max_attempts = sctp->sctp_max_init_rxt;
342fd7b5aedSGeorge Shepherd 	si->sinit_max_init_timeo = TICK_TO_MSEC(sctp->sctp_rto_max_init);
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 	return (sizeof (*si));
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate static int
sctp_set_initmsg(sctp_t * sctp,const void * invalp,uint_t inlen)3487c478bd9Sstevel@tonic-gate sctp_set_initmsg(sctp_t *sctp, const void *invalp, uint_t inlen)
3497c478bd9Sstevel@tonic-gate {
3507c478bd9Sstevel@tonic-gate 	const struct sctp_initmsg *si = invalp;
351f4b3ec61Sdh 	sctp_stack_t	*sctps = sctp->sctp_sctps;
352bd670b35SErik Nordmark 	conn_t		*connp = sctp->sctp_connp;
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate 	if (sctp->sctp_state > SCTPS_LISTEN) {
3557c478bd9Sstevel@tonic-gate 		return (EINVAL);
3567c478bd9Sstevel@tonic-gate 	}
3577c478bd9Sstevel@tonic-gate 	if (inlen < sizeof (*si)) {
3587c478bd9Sstevel@tonic-gate 		return (EINVAL);
3597c478bd9Sstevel@tonic-gate 	}
3607c478bd9Sstevel@tonic-gate 	if (si->sinit_num_ostreams != 0 &&
361f4b3ec61Sdh 	    (si->sinit_num_ostreams < sctps->sctps_initial_out_streams_low ||
362f4b3ec61Sdh 	    si->sinit_num_ostreams >
363f4b3ec61Sdh 	    sctps->sctps_initial_out_streams_high)) {
3647c478bd9Sstevel@tonic-gate 		/*
3657c478bd9Sstevel@tonic-gate 		 * Out of bounds.
3667c478bd9Sstevel@tonic-gate 		 */
3677c478bd9Sstevel@tonic-gate 		return (EINVAL);
3687c478bd9Sstevel@tonic-gate 	}
3697c478bd9Sstevel@tonic-gate 	if (si->sinit_max_instreams != 0 &&
370f4b3ec61Sdh 	    (si->sinit_max_instreams < sctps->sctps_max_in_streams_low ||
371b34b8d1aSkcpoon 	    si->sinit_max_instreams > sctps->sctps_max_in_streams_high)) {
3727c478bd9Sstevel@tonic-gate 		return (EINVAL);
3737c478bd9Sstevel@tonic-gate 	}
3747c478bd9Sstevel@tonic-gate 	if (si->sinit_max_attempts != 0 &&
375f4b3ec61Sdh 	    (si->sinit_max_attempts < sctps->sctps_max_init_retr_low ||
376b34b8d1aSkcpoon 	    si->sinit_max_attempts > sctps->sctps_max_init_retr_high)) {
3777c478bd9Sstevel@tonic-gate 		return (EINVAL);
3787c478bd9Sstevel@tonic-gate 	}
3797c478bd9Sstevel@tonic-gate 	if (si->sinit_max_init_timeo != 0 &&
380bd670b35SErik Nordmark 	    (secpolicy_ip_config(connp->conn_cred, B_TRUE) != 0 &&
381b34b8d1aSkcpoon 	    (si->sinit_max_init_timeo < sctps->sctps_rto_maxg_low ||
382b34b8d1aSkcpoon 	    si->sinit_max_init_timeo > sctps->sctps_rto_maxg_high))) {
3837c478bd9Sstevel@tonic-gate 		return (EINVAL);
3847c478bd9Sstevel@tonic-gate 	}
3857c478bd9Sstevel@tonic-gate 	if (si->sinit_num_ostreams != 0)
3867c478bd9Sstevel@tonic-gate 		sctp->sctp_num_ostr = si->sinit_num_ostreams;
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate 	if (si->sinit_max_instreams != 0)
3897c478bd9Sstevel@tonic-gate 		sctp->sctp_num_istr = si->sinit_max_instreams;
3907c478bd9Sstevel@tonic-gate 
3917c478bd9Sstevel@tonic-gate 	if (si->sinit_max_attempts != 0)
3927c478bd9Sstevel@tonic-gate 		sctp->sctp_max_init_rxt = si->sinit_max_attempts;
3937c478bd9Sstevel@tonic-gate 
3947c478bd9Sstevel@tonic-gate 	if (si->sinit_max_init_timeo != 0) {
395fd7b5aedSGeorge Shepherd 		sctp->sctp_rto_max_init =
3967c478bd9Sstevel@tonic-gate 		    MSEC_TO_TICK(si->sinit_max_init_timeo);
3977c478bd9Sstevel@tonic-gate 	}
3987c478bd9Sstevel@tonic-gate 	return (0);
3997c478bd9Sstevel@tonic-gate }
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate /*
4027c478bd9Sstevel@tonic-gate  * SCTP_PEER_ADDR_PARAMS
4037c478bd9Sstevel@tonic-gate  */
4047c478bd9Sstevel@tonic-gate static int
sctp_find_peer_fp(sctp_t * sctp,const struct sockaddr_storage * ss,sctp_faddr_t ** fpp)4057c478bd9Sstevel@tonic-gate sctp_find_peer_fp(sctp_t *sctp, const struct sockaddr_storage *ss,
4067c478bd9Sstevel@tonic-gate     sctp_faddr_t **fpp)
4077c478bd9Sstevel@tonic-gate {
4087c478bd9Sstevel@tonic-gate 	struct sockaddr_in *sin;
4097c478bd9Sstevel@tonic-gate 	struct sockaddr_in6 *sin6;
4107c478bd9Sstevel@tonic-gate 	in6_addr_t addr;
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	if (ss->ss_family == AF_INET) {
4137c478bd9Sstevel@tonic-gate 		sin = (struct sockaddr_in *)ss;
4147c478bd9Sstevel@tonic-gate 		IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &addr);
4157c478bd9Sstevel@tonic-gate 	} else if (ss->ss_family == AF_INET6) {
4167c478bd9Sstevel@tonic-gate 		sin6 = (struct sockaddr_in6 *)ss;
4177c478bd9Sstevel@tonic-gate 		addr = sin6->sin6_addr;
4187c478bd9Sstevel@tonic-gate 	} else if (ss->ss_family) {
4197c478bd9Sstevel@tonic-gate 		return (EAFNOSUPPORT);
4207c478bd9Sstevel@tonic-gate 	}
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate 	if (!ss->ss_family ||
4237c478bd9Sstevel@tonic-gate 	    SCTP_IS_ADDR_UNSPEC(IN6_IS_ADDR_V4MAPPED(&addr), addr)) {
4247c478bd9Sstevel@tonic-gate 		*fpp = NULL;
4257c478bd9Sstevel@tonic-gate 	} else {
4267c478bd9Sstevel@tonic-gate 		*fpp = sctp_lookup_faddr(sctp, &addr);
4277c478bd9Sstevel@tonic-gate 		if (*fpp == NULL) {
4287c478bd9Sstevel@tonic-gate 			return (EINVAL);
4297c478bd9Sstevel@tonic-gate 		}
4307c478bd9Sstevel@tonic-gate 	}
4317c478bd9Sstevel@tonic-gate 	return (0);
4327c478bd9Sstevel@tonic-gate }
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate static int
sctp_get_peer_addr_params(sctp_t * sctp,void * ptr)4357c478bd9Sstevel@tonic-gate sctp_get_peer_addr_params(sctp_t *sctp, void *ptr)
4367c478bd9Sstevel@tonic-gate {
4377c478bd9Sstevel@tonic-gate 	struct sctp_paddrparams *spp = ptr;
4387c478bd9Sstevel@tonic-gate 	sctp_faddr_t *fp;
4397c478bd9Sstevel@tonic-gate 	int retval;
4407c478bd9Sstevel@tonic-gate 
4417c478bd9Sstevel@tonic-gate 	retval = sctp_find_peer_fp(sctp, &spp->spp_address, &fp);
4427c478bd9Sstevel@tonic-gate 	if (retval) {
4437c478bd9Sstevel@tonic-gate 		return (retval);
4447c478bd9Sstevel@tonic-gate 	}
4457c478bd9Sstevel@tonic-gate 	if (fp) {
4466be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 		spp->spp_hbinterval = TICK_TO_MSEC(fp->sf_hb_interval);
4476be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 		spp->spp_pathmaxrxt = fp->sf_max_retr;
4487c478bd9Sstevel@tonic-gate 	} else {
4497c478bd9Sstevel@tonic-gate 		spp->spp_hbinterval = TICK_TO_MSEC(sctp->sctp_hb_interval);
4507c478bd9Sstevel@tonic-gate 		spp->spp_pathmaxrxt = sctp->sctp_pp_max_rxt;
4517c478bd9Sstevel@tonic-gate 	}
4527c478bd9Sstevel@tonic-gate 	return (sizeof (*spp));
4537c478bd9Sstevel@tonic-gate }
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate static int
sctp_set_peer_addr_params(sctp_t * sctp,const void * invalp)456bd670b35SErik Nordmark sctp_set_peer_addr_params(sctp_t *sctp, const void *invalp)
4577c478bd9Sstevel@tonic-gate {
4587c478bd9Sstevel@tonic-gate 	const struct sctp_paddrparams *spp = invalp;
4597c478bd9Sstevel@tonic-gate 	sctp_faddr_t *fp, *fp2;
4607c478bd9Sstevel@tonic-gate 	int retval;
4617c478bd9Sstevel@tonic-gate 	uint32_t sum = 0;
4627c478bd9Sstevel@tonic-gate 	int64_t now;
463f4b3ec61Sdh 	sctp_stack_t	*sctps = sctp->sctp_sctps;
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 	retval = sctp_find_peer_fp(sctp, &spp->spp_address, &fp);
4667c478bd9Sstevel@tonic-gate 	if (retval != 0) {
4677c478bd9Sstevel@tonic-gate 		return (retval);
4687c478bd9Sstevel@tonic-gate 	}
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 	if (spp->spp_hbinterval && spp->spp_hbinterval != UINT32_MAX &&
471f4b3ec61Sdh 	    (spp->spp_hbinterval < sctps->sctps_heartbeat_interval_low ||
472b34b8d1aSkcpoon 	    spp->spp_hbinterval > sctps->sctps_heartbeat_interval_high)) {
4737c478bd9Sstevel@tonic-gate 		return (EINVAL);
4747c478bd9Sstevel@tonic-gate 	}
4757c478bd9Sstevel@tonic-gate 	if (spp->spp_pathmaxrxt &&
476f4b3ec61Sdh 	    (spp->spp_pathmaxrxt < sctps->sctps_pp_max_retr_low ||
477b34b8d1aSkcpoon 	    spp->spp_pathmaxrxt > sctps->sctps_pp_max_retr_high)) {
4787c478bd9Sstevel@tonic-gate 		return (EINVAL);
4797c478bd9Sstevel@tonic-gate 	}
4807c478bd9Sstevel@tonic-gate 	if (spp->spp_pathmaxrxt && sctp->sctp_faddrs) {
4816be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 		for (fp2 = sctp->sctp_faddrs; fp2; fp2 = fp2->sf_next) {
4827c478bd9Sstevel@tonic-gate 			if (!fp || fp2 == fp) {
4837c478bd9Sstevel@tonic-gate 				sum += spp->spp_pathmaxrxt;
4847c478bd9Sstevel@tonic-gate 			} else {
4856be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 				sum += fp2->sf_max_retr;
4867c478bd9Sstevel@tonic-gate 			}
4877c478bd9Sstevel@tonic-gate 		}
4887c478bd9Sstevel@tonic-gate 		if (sctp->sctp_pa_max_rxt > sum) {
4897c478bd9Sstevel@tonic-gate 			return (EINVAL);
4907c478bd9Sstevel@tonic-gate 		}
4917c478bd9Sstevel@tonic-gate 	}
4927c478bd9Sstevel@tonic-gate 
493d3d50737SRafael Vanoni 	now = ddi_get_lbolt64();
4947c478bd9Sstevel@tonic-gate 	if (fp != NULL) {
4957c478bd9Sstevel@tonic-gate 		if (spp->spp_hbinterval == UINT32_MAX) {
4967c478bd9Sstevel@tonic-gate 			/*
4977c478bd9Sstevel@tonic-gate 			 * Send heartbeat immediatelly, don't modify the
4987c478bd9Sstevel@tonic-gate 			 * current setting.
4997c478bd9Sstevel@tonic-gate 			 */
5007c478bd9Sstevel@tonic-gate 			sctp_send_heartbeat(sctp, fp);
5017c478bd9Sstevel@tonic-gate 		} else {
5026be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			fp->sf_hb_interval = MSEC_TO_TICK(spp->spp_hbinterval);
5036be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			fp->sf_hb_expiry = now + SET_HB_INTVL(fp);
5047c478bd9Sstevel@tonic-gate 			/*
5057c478bd9Sstevel@tonic-gate 			 * Restart the heartbeat timer using the new intrvl.
5067c478bd9Sstevel@tonic-gate 			 * We need to call sctp_heartbeat_timer() to set
5077c478bd9Sstevel@tonic-gate 			 * the earliest heartbeat expiry time.
5087c478bd9Sstevel@tonic-gate 			 */
5097c478bd9Sstevel@tonic-gate 			sctp_heartbeat_timer(sctp);
5107c478bd9Sstevel@tonic-gate 		}
5117c478bd9Sstevel@tonic-gate 		if (spp->spp_pathmaxrxt) {
5126be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			fp->sf_max_retr = spp->spp_pathmaxrxt;
5137c478bd9Sstevel@tonic-gate 		}
5147c478bd9Sstevel@tonic-gate 	} else {
5156be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 		for (fp2 = sctp->sctp_faddrs; fp2 != NULL; fp2 = fp2->sf_next) {
5167c478bd9Sstevel@tonic-gate 			if (spp->spp_hbinterval == UINT32_MAX) {
5177c478bd9Sstevel@tonic-gate 				/*
5187c478bd9Sstevel@tonic-gate 				 * Send heartbeat immediatelly, don't modify
5197c478bd9Sstevel@tonic-gate 				 * the current setting.
5207c478bd9Sstevel@tonic-gate 				 */
5217c478bd9Sstevel@tonic-gate 				sctp_send_heartbeat(sctp, fp2);
5227c478bd9Sstevel@tonic-gate 			} else {
5236be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 				fp2->sf_hb_interval = MSEC_TO_TICK(
5247c478bd9Sstevel@tonic-gate 				    spp->spp_hbinterval);
5256be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 				fp2->sf_hb_expiry = now + SET_HB_INTVL(fp2);
5267c478bd9Sstevel@tonic-gate 			}
5277c478bd9Sstevel@tonic-gate 			if (spp->spp_pathmaxrxt) {
5286be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 				fp2->sf_max_retr = spp->spp_pathmaxrxt;
5297c478bd9Sstevel@tonic-gate 			}
5307c478bd9Sstevel@tonic-gate 		}
5317c478bd9Sstevel@tonic-gate 		if (spp->spp_hbinterval != UINT32_MAX) {
5327c478bd9Sstevel@tonic-gate 			sctp->sctp_hb_interval = MSEC_TO_TICK(
5337c478bd9Sstevel@tonic-gate 			    spp->spp_hbinterval);
5347c478bd9Sstevel@tonic-gate 			/* Restart the heartbeat timer using the new intrvl. */
5357c478bd9Sstevel@tonic-gate 			sctp_timer(sctp, sctp->sctp_heartbeat_mp,
5367c478bd9Sstevel@tonic-gate 			    sctp->sctp_hb_interval);
5377c478bd9Sstevel@tonic-gate 		}
5387c478bd9Sstevel@tonic-gate 		if (spp->spp_pathmaxrxt) {
5397c478bd9Sstevel@tonic-gate 			sctp->sctp_pp_max_rxt = spp->spp_pathmaxrxt;
5407c478bd9Sstevel@tonic-gate 		}
5417c478bd9Sstevel@tonic-gate 	}
5427c478bd9Sstevel@tonic-gate 	return (0);
5437c478bd9Sstevel@tonic-gate }
5447c478bd9Sstevel@tonic-gate 
5457c478bd9Sstevel@tonic-gate /*
5467c478bd9Sstevel@tonic-gate  * SCTP_DEFAULT_SEND_PARAM
5477c478bd9Sstevel@tonic-gate  */
5487c478bd9Sstevel@tonic-gate static int
sctp_get_def_send_params(sctp_t * sctp,void * ptr)5497c478bd9Sstevel@tonic-gate sctp_get_def_send_params(sctp_t *sctp, void *ptr)
5507c478bd9Sstevel@tonic-gate {
5517c478bd9Sstevel@tonic-gate 	struct sctp_sndrcvinfo *sinfo = ptr;
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 	sinfo->sinfo_stream = sctp->sctp_def_stream;
5547c478bd9Sstevel@tonic-gate 	sinfo->sinfo_ssn = 0;
5557c478bd9Sstevel@tonic-gate 	sinfo->sinfo_flags = sctp->sctp_def_flags;
5567c478bd9Sstevel@tonic-gate 	sinfo->sinfo_ppid = sctp->sctp_def_ppid;
5577c478bd9Sstevel@tonic-gate 	sinfo->sinfo_context = sctp->sctp_def_context;
5587c478bd9Sstevel@tonic-gate 	sinfo->sinfo_timetolive = sctp->sctp_def_timetolive;
5597c478bd9Sstevel@tonic-gate 	sinfo->sinfo_tsn = 0;
5607c478bd9Sstevel@tonic-gate 	sinfo->sinfo_cumtsn = 0;
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate 	return (sizeof (*sinfo));
5637c478bd9Sstevel@tonic-gate }
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate static int
sctp_set_def_send_params(sctp_t * sctp,const void * invalp)566bd670b35SErik Nordmark sctp_set_def_send_params(sctp_t *sctp, const void *invalp)
5677c478bd9Sstevel@tonic-gate {
5687c478bd9Sstevel@tonic-gate 	const struct sctp_sndrcvinfo *sinfo = invalp;
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 	if (sinfo->sinfo_stream >= sctp->sctp_num_ostr) {
5717c478bd9Sstevel@tonic-gate 		return (EINVAL);
5727c478bd9Sstevel@tonic-gate 	}
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 	sctp->sctp_def_stream = sinfo->sinfo_stream;
5757c478bd9Sstevel@tonic-gate 	sctp->sctp_def_flags = sinfo->sinfo_flags;
5767c478bd9Sstevel@tonic-gate 	sctp->sctp_def_ppid = sinfo->sinfo_ppid;
5777c478bd9Sstevel@tonic-gate 	sctp->sctp_def_context = sinfo->sinfo_context;
5787c478bd9Sstevel@tonic-gate 	sctp->sctp_def_timetolive = sinfo->sinfo_timetolive;
5797c478bd9Sstevel@tonic-gate 
5807c478bd9Sstevel@tonic-gate 	return (0);
5817c478bd9Sstevel@tonic-gate }
5827c478bd9Sstevel@tonic-gate 
5837c478bd9Sstevel@tonic-gate static int
sctp_set_prim(sctp_t * sctp,const void * invalp)584bd670b35SErik Nordmark sctp_set_prim(sctp_t *sctp, const void *invalp)
5857c478bd9Sstevel@tonic-gate {
5867c478bd9Sstevel@tonic-gate 	const struct	sctp_setpeerprim *pp = invalp;
5877c478bd9Sstevel@tonic-gate 	int		retval;
5887c478bd9Sstevel@tonic-gate 	sctp_faddr_t	*fp;
5897c478bd9Sstevel@tonic-gate 
5907c478bd9Sstevel@tonic-gate 	retval = sctp_find_peer_fp(sctp, &pp->sspp_addr, &fp);
5917c478bd9Sstevel@tonic-gate 	if (retval)
5927c478bd9Sstevel@tonic-gate 		return (retval);
5937c478bd9Sstevel@tonic-gate 
5947c478bd9Sstevel@tonic-gate 	if (fp == NULL)
5957c478bd9Sstevel@tonic-gate 		return (EINVAL);
5967c478bd9Sstevel@tonic-gate 	if (fp == sctp->sctp_primary)
5977c478bd9Sstevel@tonic-gate 		return (0);
5987c478bd9Sstevel@tonic-gate 	sctp->sctp_primary = fp;
5997c478bd9Sstevel@tonic-gate 
6007c478bd9Sstevel@tonic-gate 	/* Only switch current if fp is alive */
6016be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	if (fp->sf_state != SCTP_FADDRS_ALIVE || fp == sctp->sctp_current) {
6027c478bd9Sstevel@tonic-gate 		return (0);
6037c478bd9Sstevel@tonic-gate 	}
60477c67f2fSkcpoon 	sctp_set_faddr_current(sctp, fp);
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 	return (0);
6077c478bd9Sstevel@tonic-gate }
6087c478bd9Sstevel@tonic-gate 
609bd670b35SErik Nordmark /*
610bd670b35SErik Nordmark  * Table of all known options handled on a SCTP protocol stack.
611bd670b35SErik Nordmark  *
612bd670b35SErik Nordmark  * Note: This table contains options processed by both SCTP and IP levels
613bd670b35SErik Nordmark  *       and is the superset of options that can be performed on a SCTP and IP
614bd670b35SErik Nordmark  *       stack.
615bd670b35SErik Nordmark  */
616bd670b35SErik Nordmark opdes_t	sctp_opt_arr[] = {
617