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 /*
23*f4b3ec61Sdh  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <sys/types.h>
307c478bd9Sstevel@tonic-gate #include <sys/stream.h>
317c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
327c478bd9Sstevel@tonic-gate #define	_SUN_TPI_VERSION 2
337c478bd9Sstevel@tonic-gate #include <sys/tihdr.h>
347c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
357c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
3645916cd2Sjpk #include <sys/tsol/tndb.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include <netinet/in.h>
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate #include <inet/common.h>
417c478bd9Sstevel@tonic-gate #include <inet/ip.h>
427c478bd9Sstevel@tonic-gate #include <inet/mib2.h>
437c478bd9Sstevel@tonic-gate #include <inet/snmpcom.h>
447c478bd9Sstevel@tonic-gate #include <inet/kstatcom.h>
457c478bd9Sstevel@tonic-gate #include <inet/ipclassifier.h>
467c478bd9Sstevel@tonic-gate #include "sctp_impl.h"
477c478bd9Sstevel@tonic-gate #include "sctp_addr.h"
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate static int sctp_snmp_state(sctp_t *sctp);
507c478bd9Sstevel@tonic-gate 
5177c67f2fSkcpoon 
527c478bd9Sstevel@tonic-gate static int
537c478bd9Sstevel@tonic-gate sctp_kstat_update(kstat_t *kp, int rw)
547c478bd9Sstevel@tonic-gate {
557c478bd9Sstevel@tonic-gate 	sctp_named_kstat_t	*sctpkp;
567c478bd9Sstevel@tonic-gate 	sctp_t			*sctp, *sctp_prev;
57*f4b3ec61Sdh 	zoneid_t	myzoneid;
58*f4b3ec61Sdh 	netstackid_t	stackid = (netstackid_t)(uintptr_t)kp->ks_private;
59*f4b3ec61Sdh 	netstack_t	*ns;
60*f4b3ec61Sdh 	sctp_stack_t	*sctps;
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	if (kp == NULL|| kp->ks_data == NULL)
637c478bd9Sstevel@tonic-gate 		return (EIO);
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate 	if (rw == KSTAT_WRITE)
667c478bd9Sstevel@tonic-gate 		return (EACCES);
677c478bd9Sstevel@tonic-gate 
68*f4b3ec61Sdh 	ns = netstack_find_by_stackid(stackid);
69*f4b3ec61Sdh 	if (ns == NULL)
70*f4b3ec61Sdh 		return (-1);
71*f4b3ec61Sdh 	sctps = ns->netstack_sctp;
72*f4b3ec61Sdh 	if (sctps == NULL) {
73*f4b3ec61Sdh 		netstack_rele(ns);
74*f4b3ec61Sdh 		return (-1);
75*f4b3ec61Sdh 	}
76*f4b3ec61Sdh 	myzoneid = netstackid_to_zoneid(stackid);
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate 	/*
797c478bd9Sstevel@tonic-gate 	 * Get the number of current associations and gather their
807c478bd9Sstevel@tonic-gate 	 * individual set of statistics.
817c478bd9Sstevel@tonic-gate 	 */
82*f4b3ec61Sdh 	SET_MIB(sctps->sctps_mib.sctpCurrEstab, 0);
83*f4b3ec61Sdh 	sctp = sctps->sctps_gsctp;
847c478bd9Sstevel@tonic-gate 	sctp_prev = NULL;
85*f4b3ec61Sdh 	mutex_enter(&sctps->sctps_g_lock);
867c478bd9Sstevel@tonic-gate 	while (sctp != NULL) {
877c478bd9Sstevel@tonic-gate 		mutex_enter(&sctp->sctp_reflock);
887c478bd9Sstevel@tonic-gate 		if (sctp->sctp_condemned) {
897c478bd9Sstevel@tonic-gate 			mutex_exit(&sctp->sctp_reflock);
90*f4b3ec61Sdh 			sctp = list_next(&sctps->sctps_g_list, sctp);
917c478bd9Sstevel@tonic-gate 			continue;
927c478bd9Sstevel@tonic-gate 		}
937c478bd9Sstevel@tonic-gate 		sctp->sctp_refcnt++;
947c478bd9Sstevel@tonic-gate 		mutex_exit(&sctp->sctp_reflock);
95*f4b3ec61Sdh 		mutex_exit(&sctps->sctps_g_lock);
967c478bd9Sstevel@tonic-gate 		if (sctp_prev != NULL)
977c478bd9Sstevel@tonic-gate 			SCTP_REFRELE(sctp_prev);
98*f4b3ec61Sdh 		if (sctp->sctp_connp->conn_zoneid != myzoneid)
997c478bd9Sstevel@tonic-gate 			goto next_sctp;
1007c478bd9Sstevel@tonic-gate 		if (sctp->sctp_state == SCTPS_ESTABLISHED ||
1017c478bd9Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_PENDING ||
1027c478bd9Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) {
103*f4b3ec61Sdh 			BUMP_MIB(&sctps->sctps_mib, sctpCurrEstab);
1047c478bd9Sstevel@tonic-gate 		}
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate 		if (sctp->sctp_opkts) {
107*f4b3ec61Sdh 			UPDATE_MIB(&sctps->sctps_mib, sctpOutSCTPPkts,
1087c478bd9Sstevel@tonic-gate 			    sctp->sctp_opkts);
1097c478bd9Sstevel@tonic-gate 			sctp->sctp_opkts = 0;
1107c478bd9Sstevel@tonic-gate 		}
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 		if (sctp->sctp_obchunks) {
113*f4b3ec61Sdh 			UPDATE_MIB(&sctps->sctps_mib, sctpOutCtrlChunks,
1147c478bd9Sstevel@tonic-gate 			    sctp->sctp_obchunks);
1157c478bd9Sstevel@tonic-gate 			sctp->sctp_obchunks = 0;
1167c478bd9Sstevel@tonic-gate 		}
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 		if (sctp->sctp_odchunks) {
119*f4b3ec61Sdh 			UPDATE_MIB(&sctps->sctps_mib, sctpOutOrderChunks,
1207c478bd9Sstevel@tonic-gate 			    sctp->sctp_odchunks);
1217c478bd9Sstevel@tonic-gate 			sctp->sctp_odchunks = 0;
1227c478bd9Sstevel@tonic-gate 		}
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 		if (sctp->sctp_oudchunks) {
125*f4b3ec61Sdh 			UPDATE_MIB(&sctps->sctps_mib, sctpOutUnorderChunks,
1267c478bd9Sstevel@tonic-gate 			    sctp->sctp_oudchunks);
1277c478bd9Sstevel@tonic-gate 			sctp->sctp_oudchunks = 0;
1287c478bd9Sstevel@tonic-gate 		}
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 		if (sctp->sctp_rxtchunks) {
131*f4b3ec61Sdh 			UPDATE_MIB(&sctps->sctps_mib, sctpRetransChunks,
1327c478bd9Sstevel@tonic-gate 			    sctp->sctp_rxtchunks);
1337c478bd9Sstevel@tonic-gate 			sctp->sctp_rxtchunks = 0;
1347c478bd9Sstevel@tonic-gate 		}
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 		if (sctp->sctp_ipkts) {
137*f4b3ec61Sdh 			UPDATE_MIB(&sctps->sctps_mib, sctpInSCTPPkts,
138*f4b3ec61Sdh 			    sctp->sctp_ipkts);
1397c478bd9Sstevel@tonic-gate 			sctp->sctp_ipkts = 0;
1407c478bd9Sstevel@tonic-gate 		}
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 		if (sctp->sctp_ibchunks) {
143*f4b3ec61Sdh 			UPDATE_MIB(&sctps->sctps_mib, sctpInCtrlChunks,
1447c478bd9Sstevel@tonic-gate 			    sctp->sctp_ibchunks);
1457c478bd9Sstevel@tonic-gate 			sctp->sctp_ibchunks = 0;
1467c478bd9Sstevel@tonic-gate 		}
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 		if (sctp->sctp_idchunks) {
149*f4b3ec61Sdh 			UPDATE_MIB(&sctps->sctps_mib, sctpInOrderChunks,
1507c478bd9Sstevel@tonic-gate 			    sctp->sctp_idchunks);
1517c478bd9Sstevel@tonic-gate 			sctp->sctp_idchunks = 0;
1527c478bd9Sstevel@tonic-gate 		}
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 		if (sctp->sctp_iudchunks) {
155*f4b3ec61Sdh 			UPDATE_MIB(&sctps->sctps_mib, sctpInUnorderChunks,
1567c478bd9Sstevel@tonic-gate 			    sctp->sctp_iudchunks);
1577c478bd9Sstevel@tonic-gate 			sctp->sctp_iudchunks = 0;
1587c478bd9Sstevel@tonic-gate 		}
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 		if (sctp->sctp_fragdmsgs) {
161*f4b3ec61Sdh 			UPDATE_MIB(&sctps->sctps_mib, sctpFragUsrMsgs,
1627c478bd9Sstevel@tonic-gate 			    sctp->sctp_fragdmsgs);
1637c478bd9Sstevel@tonic-gate 			sctp->sctp_fragdmsgs = 0;
1647c478bd9Sstevel@tonic-gate 		}
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 		if (sctp->sctp_reassmsgs) {
167*f4b3ec61Sdh 			UPDATE_MIB(&sctps->sctps_mib, sctpReasmUsrMsgs,
1687c478bd9Sstevel@tonic-gate 			    sctp->sctp_reassmsgs);
1697c478bd9Sstevel@tonic-gate 			sctp->sctp_reassmsgs = 0;
1707c478bd9Sstevel@tonic-gate 		}
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate next_sctp:
1737c478bd9Sstevel@tonic-gate 		sctp_prev = sctp;
174*f4b3ec61Sdh 		mutex_enter(&sctps->sctps_g_lock);
175*f4b3ec61Sdh 		sctp = list_next(&sctps->sctps_g_list, sctp);
1767c478bd9Sstevel@tonic-gate 	}
177*f4b3ec61Sdh 	mutex_exit(&sctps->sctps_g_lock);
1787c478bd9Sstevel@tonic-gate 	if (sctp_prev != NULL)
1797c478bd9Sstevel@tonic-gate 		SCTP_REFRELE(sctp_prev);
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 	/* Copy data from the SCTP MIB */
1827c478bd9Sstevel@tonic-gate 	sctpkp = (sctp_named_kstat_t *)kp->ks_data;
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate 	/* These are from global ndd params. */
185*f4b3ec61Sdh 	sctpkp->sctpRtoMin.value.ui32 = sctps->sctps_rto_ming;
186*f4b3ec61Sdh 	sctpkp->sctpRtoMax.value.ui32 = sctps->sctps_rto_maxg;
187*f4b3ec61Sdh 	sctpkp->sctpRtoInitial.value.ui32 = sctps->sctps_rto_initialg;
188*f4b3ec61Sdh 	sctpkp->sctpValCookieLife.value.ui32 = sctps->sctps_cookie_life;
189*f4b3ec61Sdh 	sctpkp->sctpMaxInitRetr.value.ui32 = sctps->sctps_max_init_retr;
190*f4b3ec61Sdh 
191*f4b3ec61Sdh 	sctpkp->sctpCurrEstab.value.i32 = sctps->sctps_mib.sctpCurrEstab;
192*f4b3ec61Sdh 	sctpkp->sctpActiveEstab.value.i32 = sctps->sctps_mib.sctpActiveEstab;
193*f4b3ec61Sdh 	sctpkp->sctpPassiveEstab.value.i32 = sctps->sctps_mib.sctpPassiveEstab;
194*f4b3ec61Sdh 	sctpkp->sctpAborted.value.i32 = sctps->sctps_mib.sctpAborted;
195*f4b3ec61Sdh 	sctpkp->sctpShutdowns.value.i32 = sctps->sctps_mib.sctpShutdowns;
196*f4b3ec61Sdh 	sctpkp->sctpOutOfBlue.value.i32 = sctps->sctps_mib.sctpOutOfBlue;
197*f4b3ec61Sdh 	sctpkp->sctpChecksumError.value.i32 =
198*f4b3ec61Sdh 	    sctps->sctps_mib.sctpChecksumError;
199*f4b3ec61Sdh 	sctpkp->sctpOutCtrlChunks.value.i64 =
200*f4b3ec61Sdh 	    sctps->sctps_mib.sctpOutCtrlChunks;
201*f4b3ec61Sdh 	sctpkp->sctpOutOrderChunks.value.i64 =
202*f4b3ec61Sdh 	    sctps->sctps_mib.sctpOutOrderChunks;
203*f4b3ec61Sdh 	sctpkp->sctpOutUnorderChunks.value.i64 =
204*f4b3ec61Sdh 	    sctps->sctps_mib.sctpOutUnorderChunks;
205*f4b3ec61Sdh 	sctpkp->sctpRetransChunks.value.i64 =
206*f4b3ec61Sdh 	    sctps->sctps_mib.sctpRetransChunks;
207*f4b3ec61Sdh 	sctpkp->sctpOutAck.value.i32 = sctps->sctps_mib.sctpOutAck;
208*f4b3ec61Sdh 	sctpkp->sctpOutAckDelayed.value.i32 =
209*f4b3ec61Sdh 	    sctps->sctps_mib.sctpOutAckDelayed;
210*f4b3ec61Sdh 	sctpkp->sctpOutWinUpdate.value.i32 = sctps->sctps_mib.sctpOutWinUpdate;
211*f4b3ec61Sdh 	sctpkp->sctpOutFastRetrans.value.i32 =
212*f4b3ec61Sdh 	    sctps->sctps_mib.sctpOutFastRetrans;
213*f4b3ec61Sdh 	sctpkp->sctpOutWinProbe.value.i32 = sctps->sctps_mib.sctpOutWinProbe;
214*f4b3ec61Sdh 	sctpkp->sctpInCtrlChunks.value.i64 = sctps->sctps_mib.sctpInCtrlChunks;
215*f4b3ec61Sdh 	sctpkp->sctpInOrderChunks.value.i64 =
216*f4b3ec61Sdh 	    sctps->sctps_mib.sctpInOrderChunks;
217*f4b3ec61Sdh 	sctpkp->sctpInUnorderChunks.value.i64 =
218*f4b3ec61Sdh 	    sctps->sctps_mib.sctpInUnorderChunks;
219*f4b3ec61Sdh 	sctpkp->sctpInAck.value.i32 = sctps->sctps_mib.sctpInAck;
220*f4b3ec61Sdh 	sctpkp->sctpInDupAck.value.i32 = sctps->sctps_mib.sctpInDupAck;
221*f4b3ec61Sdh 	sctpkp->sctpInAckUnsent.value.i32 = sctps->sctps_mib.sctpInAckUnsent;
222*f4b3ec61Sdh 	sctpkp->sctpFragUsrMsgs.value.i64 = sctps->sctps_mib.sctpFragUsrMsgs;
223*f4b3ec61Sdh 	sctpkp->sctpReasmUsrMsgs.value.i64 = sctps->sctps_mib.sctpReasmUsrMsgs;
224*f4b3ec61Sdh 	sctpkp->sctpOutSCTPPkts.value.i64 = sctps->sctps_mib.sctpOutSCTPPkts;
225*f4b3ec61Sdh 	sctpkp->sctpInSCTPPkts.value.i64 = sctps->sctps_mib.sctpInSCTPPkts;
226*f4b3ec61Sdh 	sctpkp->sctpInInvalidCookie.value.i32 =
227*f4b3ec61Sdh 	    sctps->sctps_mib.sctpInInvalidCookie;
228*f4b3ec61Sdh 	sctpkp->sctpTimRetrans.value.i32 = sctps->sctps_mib.sctpTimRetrans;
229*f4b3ec61Sdh 	sctpkp->sctpTimRetransDrop.value.i32 =
230*f4b3ec61Sdh 	    sctps->sctps_mib.sctpTimRetransDrop;
2317c478bd9Sstevel@tonic-gate 	sctpkp->sctpTimHeartBeatProbe.value.i32 =
232*f4b3ec61Sdh 	    sctps->sctps_mib.sctpTimHeartBeatProbe;
233*f4b3ec61Sdh 	sctpkp->sctpTimHeartBeatDrop.value.i32 =
234*f4b3ec61Sdh 	    sctps->sctps_mib.sctpTimHeartBeatDrop;
235*f4b3ec61Sdh 	sctpkp->sctpListenDrop.value.i32 = sctps->sctps_mib.sctpListenDrop;
236*f4b3ec61Sdh 	sctpkp->sctpInClosed.value.i32 = sctps->sctps_mib.sctpInClosed;
2377c478bd9Sstevel@tonic-gate 
238*f4b3ec61Sdh 	netstack_rele(ns);
2397c478bd9Sstevel@tonic-gate 	return (0);
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate 
242*f4b3ec61Sdh void *
243*f4b3ec61Sdh sctp_kstat_init(netstackid_t stackid)
2447c478bd9Sstevel@tonic-gate {
245*f4b3ec61Sdh 	kstat_t	*ksp;
246*f4b3ec61Sdh 
2477c478bd9Sstevel@tonic-gate 	sctp_named_kstat_t template = {
2487c478bd9Sstevel@tonic-gate 		{ "sctpRtoAlgorithm",		KSTAT_DATA_INT32, 0 },
2497c478bd9Sstevel@tonic-gate 		{ "sctpRtoMin",			KSTAT_DATA_UINT32, 0 },
2507c478bd9Sstevel@tonic-gate 		{ "sctpRtoMax",			KSTAT_DATA_UINT32, 0 },
2517c478bd9Sstevel@tonic-gate 		{ "sctpRtoInitial",		KSTAT_DATA_UINT32, 0 },
2527c478bd9Sstevel@tonic-gate 		{ "sctpMaxAssocs",		KSTAT_DATA_INT32, 0 },
2537c478bd9Sstevel@tonic-gate 		{ "sctpValCookieLife",		KSTAT_DATA_UINT32, 0 },
2547c478bd9Sstevel@tonic-gate 		{ "sctpMaxInitRetr",		KSTAT_DATA_UINT32, 0 },
2557c478bd9Sstevel@tonic-gate 		{ "sctpCurrEstab",		KSTAT_DATA_INT32, 0 },
2567c478bd9Sstevel@tonic-gate 		{ "sctpActiveEstab",		KSTAT_DATA_INT32, 0 },
2577c478bd9Sstevel@tonic-gate 		{ "sctpPassiveEstab",		KSTAT_DATA_INT32, 0 },
2587c478bd9Sstevel@tonic-gate 		{ "sctpAborted",		KSTAT_DATA_INT32, 0 },
2597c478bd9Sstevel@tonic-gate 		{ "sctpShutdowns",		KSTAT_DATA_INT32, 0 },
2607c478bd9Sstevel@tonic-gate 		{ "sctpOutOfBlue",		KSTAT_DATA_INT32, 0 },
2617c478bd9Sstevel@tonic-gate 		{ "sctpChecksumError",		KSTAT_DATA_INT32, 0 },
2627c478bd9Sstevel@tonic-gate 		{ "sctpOutCtrlChunks",		KSTAT_DATA_INT64, 0 },
2637c478bd9Sstevel@tonic-gate 		{ "sctpOutOrderChunks",		KSTAT_DATA_INT64, 0 },
2647c478bd9Sstevel@tonic-gate 		{ "sctpOutUnorderChunks",	KSTAT_DATA_INT64, 0 },
2657c478bd9Sstevel@tonic-gate 		{ "sctpRetransChunks",		KSTAT_DATA_INT64, 0 },
2667c478bd9Sstevel@tonic-gate 		{ "sctpOutAck",			KSTAT_DATA_INT32, 0 },
2677c478bd9Sstevel@tonic-gate 		{ "sctpOutAckDelayed",		KSTAT_DATA_INT32, 0 },
2687c478bd9Sstevel@tonic-gate 		{ "sctpOutWinUpdate",		KSTAT_DATA_INT32, 0 },
2697c478bd9Sstevel@tonic-gate 		{ "sctpOutFastRetrans",		KSTAT_DATA_INT32, 0 },
2707c478bd9Sstevel@tonic-gate 		{ "sctpOutWinProbe",		KSTAT_DATA_INT32, 0 },
2717c478bd9Sstevel@tonic-gate 		{ "sctpInCtrlChunks",		KSTAT_DATA_INT64, 0 },
2727c478bd9Sstevel@tonic-gate 		{ "sctpInOrderChunks",		KSTAT_DATA_INT64, 0 },
2737c478bd9Sstevel@tonic-gate 		{ "sctpInUnorderChunks",	KSTAT_DATA_INT64, 0 },
2747c478bd9Sstevel@tonic-gate 		{ "sctpInAck",			KSTAT_DATA_INT32, 0 },
2757c478bd9Sstevel@tonic-gate 		{ "sctpInDupAck",		KSTAT_DATA_INT32, 0 },
2767c478bd9Sstevel@tonic-gate 		{ "sctpInAckUnsent",		KSTAT_DATA_INT32, 0 },
2777c478bd9Sstevel@tonic-gate 		{ "sctpFragUsrMsgs",		KSTAT_DATA_INT64, 0 },
2787c478bd9Sstevel@tonic-gate 		{ "sctpReasmUsrMsgs",		KSTAT_DATA_INT64, 0 },
2797c478bd9Sstevel@tonic-gate 		{ "sctpOutSCTPPkts",		KSTAT_DATA_INT64, 0 },
2807c478bd9Sstevel@tonic-gate 		{ "sctpInSCTPPkts",		KSTAT_DATA_INT64, 0 },
2817c478bd9Sstevel@tonic-gate 		{ "sctpInInvalidCookie",	KSTAT_DATA_INT32, 0 },
2827c478bd9Sstevel@tonic-gate 		{ "sctpTimRetrans",		KSTAT_DATA_INT32, 0 },
2837c478bd9Sstevel@tonic-gate 		{ "sctpTimRetransDrop",		KSTAT_DATA_INT32, 0 },
2847c478bd9Sstevel@tonic-gate 		{ "sctpTimHearBeatProbe",	KSTAT_DATA_INT32, 0 },
2857c478bd9Sstevel@tonic-gate 		{ "sctpTimHearBeatDrop",	KSTAT_DATA_INT32, 0 },
2867c478bd9Sstevel@tonic-gate 		{ "sctpListenDrop",		KSTAT_DATA_INT32, 0 },
2877c478bd9Sstevel@tonic-gate 		{ "sctpInClosed",		KSTAT_DATA_INT32, 0 }
2887c478bd9Sstevel@tonic-gate 	};
2897c478bd9Sstevel@tonic-gate 
290*f4b3ec61Sdh 	ksp = kstat_create_netstack(SCTP_MOD_NAME, 0, "sctp", "mib2",
291*f4b3ec61Sdh 	    KSTAT_TYPE_NAMED, NUM_OF_FIELDS(sctp_named_kstat_t), 0, stackid);
2927c478bd9Sstevel@tonic-gate 
293*f4b3ec61Sdh 	if (ksp == NULL || ksp->ks_data == NULL)
294*f4b3ec61Sdh 		return (NULL);
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	/* These won't change. */
2977c478bd9Sstevel@tonic-gate 	template.sctpRtoAlgorithm.value.i32 = MIB2_SCTP_RTOALGO_VANJ;
2987c478bd9Sstevel@tonic-gate 	template.sctpMaxAssocs.value.i32 = -1;
2997c478bd9Sstevel@tonic-gate 
300*f4b3ec61Sdh 	bcopy(&template, ksp->ks_data, sizeof (template));
301*f4b3ec61Sdh 	ksp->ks_update = sctp_kstat_update;
302*f4b3ec61Sdh 	ksp->ks_private = (void *)(uintptr_t)stackid;
303*f4b3ec61Sdh 
304*f4b3ec61Sdh 	kstat_install(ksp);
305*f4b3ec61Sdh 	return (ksp);
306*f4b3ec61Sdh }
307*f4b3ec61Sdh 
308*f4b3ec61Sdh /*
309*f4b3ec61Sdh  * The following kstats are for debugging purposes.  They keep
310*f4b3ec61Sdh  * track of problems which should not happen normally.  But in
311*f4b3ec61Sdh  * those cases which they do happen, these kstats would be handy
312*f4b3ec61Sdh  * for engineers to diagnose the problems.  They are not intended
313*f4b3ec61Sdh  * to be consumed by customers.
314*f4b3ec61Sdh  */
315*f4b3ec61Sdh void *
316*f4b3ec61Sdh sctp_kstat2_init(netstackid_t stackid, sctp_kstat_t *sctps_statisticsp)
317*f4b3ec61Sdh {
318*f4b3ec61Sdh 	kstat_t *ksp;
319*f4b3ec61Sdh 
320*f4b3ec61Sdh 	sctp_kstat_t template = {
321*f4b3ec61Sdh 		{ "sctp_add_faddr",			KSTAT_DATA_UINT64 },
322*f4b3ec61Sdh 		{ "sctp_add_timer",			KSTAT_DATA_UINT64 },
323*f4b3ec61Sdh 		{ "sctp_conn_create",			KSTAT_DATA_UINT64 },
324*f4b3ec61Sdh 		{ "sctp_find_next_tq",			KSTAT_DATA_UINT64 },
325*f4b3ec61Sdh 		{ "sctp_fr_add_hdr",			KSTAT_DATA_UINT64 },
326*f4b3ec61Sdh 		{ "sctp_fr_not_found",			KSTAT_DATA_UINT64 },
327*f4b3ec61Sdh 		{ "sctp_output_failed",			KSTAT_DATA_UINT64 },
328*f4b3ec61Sdh 		{ "sctp_rexmit_failed",			KSTAT_DATA_UINT64 },
329*f4b3ec61Sdh 		{ "sctp_send_init_failed",		KSTAT_DATA_UINT64 },
330*f4b3ec61Sdh 		{ "sctp_send_cookie_failed",		KSTAT_DATA_UINT64 },
331*f4b3ec61Sdh 		{ "sctp_send_cookie_ack_failed",	KSTAT_DATA_UINT64 },
332*f4b3ec61Sdh 		{ "sctp_send_err_failed",		KSTAT_DATA_UINT64 },
333*f4b3ec61Sdh 		{ "sctp_send_sack_failed",		KSTAT_DATA_UINT64 },
334*f4b3ec61Sdh 		{ "sctp_send_shutdown_failed",		KSTAT_DATA_UINT64 },
335*f4b3ec61Sdh 		{ "sctp_send_shutdown_ack_failed",	KSTAT_DATA_UINT64 },
336*f4b3ec61Sdh 		{ "sctp_send_shutdown_comp_failed",	KSTAT_DATA_UINT64 },
337*f4b3ec61Sdh 		{ "sctp_send_user_abort_failed",	KSTAT_DATA_UINT64 },
338*f4b3ec61Sdh 		{ "sctp_send_asconf_failed",		KSTAT_DATA_UINT64 },
339*f4b3ec61Sdh 		{ "sctp_send_asconf_ack_failed",	KSTAT_DATA_UINT64 },
340*f4b3ec61Sdh 		{ "sctp_send_ftsn_failed",		KSTAT_DATA_UINT64 },
341*f4b3ec61Sdh 		{ "sctp_send_hb_failed",		KSTAT_DATA_UINT64 },
342*f4b3ec61Sdh 		{ "sctp_return_hb_failed",		KSTAT_DATA_UINT64 },
343*f4b3ec61Sdh 		{ "sctp_ss_rexmit_failed",		KSTAT_DATA_UINT64 },
344*f4b3ec61Sdh 		{ "sctp_cl_connect",			KSTAT_DATA_UINT64 },
345*f4b3ec61Sdh 		{ "sctp_cl_assoc_change",		KSTAT_DATA_UINT64 },
346*f4b3ec61Sdh 		{ "sctp_cl_check_addrs",		KSTAT_DATA_UINT64 },
347*f4b3ec61Sdh 	};
348*f4b3ec61Sdh 
349*f4b3ec61Sdh 	ksp = kstat_create_netstack(SCTP_MOD_NAME, 0, "sctpstat", "net",
350*f4b3ec61Sdh 	    KSTAT_TYPE_NAMED, NUM_OF_FIELDS(template), KSTAT_FLAG_VIRTUAL,
351*f4b3ec61Sdh 	    stackid);
3527c478bd9Sstevel@tonic-gate 
353*f4b3ec61Sdh 	if (ksp == NULL)
354*f4b3ec61Sdh 		return (NULL);
3557c478bd9Sstevel@tonic-gate 
356*f4b3ec61Sdh 	bcopy(&template, sctps_statisticsp, sizeof (template));
357*f4b3ec61Sdh 	ksp->ks_data = (void *)sctps_statisticsp;
358*f4b3ec61Sdh 	ksp->ks_private = (void *)(uintptr_t)stackid;
35977c67f2fSkcpoon 
360*f4b3ec61Sdh 	kstat_install(ksp);
361*f4b3ec61Sdh 	return (ksp);
3627c478bd9Sstevel@tonic-gate }
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate void
365*f4b3ec61Sdh sctp_kstat_fini(netstackid_t stackid, kstat_t *ksp)
3667c478bd9Sstevel@tonic-gate {
367*f4b3ec61Sdh 	if (ksp != NULL) {
368*f4b3ec61Sdh 		ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
369*f4b3ec61Sdh 		kstat_delete_netstack(ksp, stackid);
3707c478bd9Sstevel@tonic-gate 	}
371*f4b3ec61Sdh }
372*f4b3ec61Sdh 
373*f4b3ec61Sdh void
374*f4b3ec61Sdh sctp_kstat2_fini(netstackid_t stackid, kstat_t *ksp)
375*f4b3ec61Sdh {
376*f4b3ec61Sdh 	if (ksp != NULL) {
377*f4b3ec61Sdh 		ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
378*f4b3ec61Sdh 		kstat_delete_netstack(ksp, stackid);
37977c67f2fSkcpoon 	}
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate /*
3837c478bd9Sstevel@tonic-gate  * Return SNMP global stats in buffer in mpdata.
3847c478bd9Sstevel@tonic-gate  * Return associatiation table in mp_conn_data,
3857c478bd9Sstevel@tonic-gate  * local address table in mp_local_data, and
3867c478bd9Sstevel@tonic-gate  * remote address table in mp_rem_data.
3877c478bd9Sstevel@tonic-gate  */
3887c478bd9Sstevel@tonic-gate mblk_t *
389*f4b3ec61Sdh sctp_snmp_get_mib2(queue_t *q, mblk_t *mpctl, sctp_stack_t *sctps)
3907c478bd9Sstevel@tonic-gate {
3917c478bd9Sstevel@tonic-gate 	mblk_t			*mpdata, *mp_ret;
3927c478bd9Sstevel@tonic-gate 	mblk_t			*mp_conn_ctl = NULL;
3937c478bd9Sstevel@tonic-gate 	mblk_t			*mp_conn_data;
3947c478bd9Sstevel@tonic-gate 	mblk_t			*mp_conn_tail = NULL;
3957c478bd9Sstevel@tonic-gate 	mblk_t			*mp_local_ctl = NULL;
3967c478bd9Sstevel@tonic-gate 	mblk_t			*mp_local_data;
3977c478bd9Sstevel@tonic-gate 	mblk_t			*mp_local_tail = NULL;
3987c478bd9Sstevel@tonic-gate 	mblk_t			*mp_rem_ctl = NULL;
3997c478bd9Sstevel@tonic-gate 	mblk_t			*mp_rem_data;
4007c478bd9Sstevel@tonic-gate 	mblk_t			*mp_rem_tail = NULL;
40145916cd2Sjpk 	mblk_t			*mp_attr_ctl = NULL;
40245916cd2Sjpk 	mblk_t			*mp_attr_data;
40345916cd2Sjpk 	mblk_t			*mp_attr_tail = NULL;
4047c478bd9Sstevel@tonic-gate 	struct opthdr		*optp;
4057c478bd9Sstevel@tonic-gate 	sctp_t			*sctp, *sctp_prev = NULL;
4067c478bd9Sstevel@tonic-gate 	sctp_faddr_t		*fp;
4077c478bd9Sstevel@tonic-gate 	mib2_sctpConnEntry_t	sce;
4087c478bd9Sstevel@tonic-gate 	mib2_sctpConnLocalEntry_t	scle;
4097c478bd9Sstevel@tonic-gate 	mib2_sctpConnRemoteEntry_t	scre;
41045916cd2Sjpk 	mib2_transportMLPEntry_t	mlp;
4117c478bd9Sstevel@tonic-gate 	int			i;
4127c478bd9Sstevel@tonic-gate 	int			l;
4137c478bd9Sstevel@tonic-gate 	int			scanned = 0;
4147c478bd9Sstevel@tonic-gate 	zoneid_t		zoneid = Q_TO_CONN(q)->conn_zoneid;
41545916cd2Sjpk 	conn_t			*connp;
41645916cd2Sjpk 	boolean_t		needattr;
41745916cd2Sjpk 	int			idx;
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate 	/*
4207c478bd9Sstevel@tonic-gate 	 * Make copies of the original message.
4217c478bd9Sstevel@tonic-gate 	 * mpctl will hold SCTP counters,
4227c478bd9Sstevel@tonic-gate 	 * mp_conn_ctl will hold list of connections.
4237c478bd9Sstevel@tonic-gate 	 */
4247c478bd9Sstevel@tonic-gate 	mp_ret = copymsg(mpctl);
4257c478bd9Sstevel@tonic-gate 	mp_conn_ctl = copymsg(mpctl);
4267c478bd9Sstevel@tonic-gate 	mp_local_ctl = copymsg(mpctl);
4277c478bd9Sstevel@tonic-gate 	mp_rem_ctl = copymsg(mpctl);
42845916cd2Sjpk 	mp_attr_ctl = copymsg(mpctl);
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate 	mpdata = mpctl->b_cont;
4317c478bd9Sstevel@tonic-gate 
43245916cd2Sjpk 	if (mp_conn_ctl == NULL || mp_local_ctl == NULL ||
43345916cd2Sjpk 	    mp_rem_ctl == NULL || mp_attr_ctl == NULL || mpdata == NULL) {
43445916cd2Sjpk 		freemsg(mp_attr_ctl);
4357c478bd9Sstevel@tonic-gate 		freemsg(mp_rem_ctl);
4367c478bd9Sstevel@tonic-gate 		freemsg(mp_local_ctl);
4377c478bd9Sstevel@tonic-gate 		freemsg(mp_conn_ctl);
4387c478bd9Sstevel@tonic-gate 		freemsg(mp_ret);
4397c478bd9Sstevel@tonic-gate 		freemsg(mpctl);
4407c478bd9Sstevel@tonic-gate 		return (NULL);
4417c478bd9Sstevel@tonic-gate 	}
4427c478bd9Sstevel@tonic-gate 	mp_conn_data = mp_conn_ctl->b_cont;
4437c478bd9Sstevel@tonic-gate 	mp_local_data = mp_local_ctl->b_cont;
4447c478bd9Sstevel@tonic-gate 	mp_rem_data = mp_rem_ctl->b_cont;
44545916cd2Sjpk 	mp_attr_data = mp_attr_ctl->b_cont;
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate 	/* hostname address parameters are not supported in Solaris */
4487c478bd9Sstevel@tonic-gate 	sce.sctpAssocRemHostName.o_length = 0;
4497c478bd9Sstevel@tonic-gate 	sce.sctpAssocRemHostName.o_bytes[0] = 0;
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 	/* build table of connections -- need count in fixed part */
452*f4b3ec61Sdh 	SET_MIB(sctps->sctps_mib.sctpRtoAlgorithm, MIB2_SCTP_RTOALGO_VANJ);
453*f4b3ec61Sdh 	SET_MIB(sctps->sctps_mib.sctpRtoMin, sctps->sctps_rto_ming);
454*f4b3ec61Sdh 	SET_MIB(sctps->sctps_mib.sctpRtoMax, sctps->sctps_rto_maxg);
455*f4b3ec61Sdh 	SET_MIB(sctps->sctps_mib.sctpRtoInitial, sctps->sctps_rto_initialg);
456*f4b3ec61Sdh 	SET_MIB(sctps->sctps_mib.sctpMaxAssocs, -1);
457*f4b3ec61Sdh 	SET_MIB(sctps->sctps_mib.sctpValCookieLife, sctps->sctps_cookie_life);
458*f4b3ec61Sdh 	SET_MIB(sctps->sctps_mib.sctpMaxInitRetr, sctps->sctps_max_init_retr);
459*f4b3ec61Sdh 	SET_MIB(sctps->sctps_mib.sctpCurrEstab, 0);
4607c478bd9Sstevel@tonic-gate 
46145916cd2Sjpk 	idx = 0;
462*f4b3ec61Sdh 	sctp = sctps->sctps_gsctp;
463*f4b3ec61Sdh 	mutex_enter(&sctps->sctps_g_lock);
4647c478bd9Sstevel@tonic-gate 	while (sctp != NULL) {
4657c478bd9Sstevel@tonic-gate 		mutex_enter(&sctp->sctp_reflock);
4667c478bd9Sstevel@tonic-gate 		if (sctp->sctp_condemned) {
4677c478bd9Sstevel@tonic-gate 			mutex_exit(&sctp->sctp_reflock);
468*f4b3ec61Sdh 			sctp = list_next(&sctps->sctps_g_list, sctp);
4697c478bd9Sstevel@tonic-gate 			continue;
4707c478bd9Sstevel@tonic-gate 		}
4717c478bd9Sstevel@tonic-gate 		sctp->sctp_refcnt++;
4727c478bd9Sstevel@tonic-gate 		mutex_exit(&sctp->sctp_reflock);
473*f4b3ec61Sdh 		mutex_exit(&sctps->sctps_g_lock);
4747c478bd9Sstevel@tonic-gate 		if (sctp_prev != NULL)
4757c478bd9Sstevel@tonic-gate 			SCTP_REFRELE(sctp_prev);
4767c478bd9Sstevel@tonic-gate 		if (sctp->sctp_connp->conn_zoneid != zoneid)
4777c478bd9Sstevel@tonic-gate 			goto next_sctp;
4787c478bd9Sstevel@tonic-gate 		if (sctp->sctp_state == SCTPS_ESTABLISHED ||
4797c478bd9Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_PENDING ||
4807c478bd9Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) {
481*f4b3ec61Sdh 			BUMP_MIB(&sctps->sctps_mib, sctpCurrEstab);
4827c478bd9Sstevel@tonic-gate 		}
483*f4b3ec61Sdh 		UPDATE_MIB(&sctps->sctps_mib,
484*f4b3ec61Sdh 		    sctpOutSCTPPkts, sctp->sctp_opkts);
4857c478bd9Sstevel@tonic-gate 		sctp->sctp_opkts = 0;
486*f4b3ec61Sdh 		UPDATE_MIB(&sctps->sctps_mib,
487*f4b3ec61Sdh 		    sctpOutCtrlChunks, sctp->sctp_obchunks);
4887c478bd9Sstevel@tonic-gate 		sctp->sctp_obchunks = 0;
489*f4b3ec61Sdh 		UPDATE_MIB(&sctps->sctps_mib,
490*f4b3ec61Sdh 		    sctpOutOrderChunks, sctp->sctp_odchunks);
4917c478bd9Sstevel@tonic-gate 		sctp->sctp_odchunks = 0;
492*f4b3ec61Sdh 		UPDATE_MIB(&sctps->sctps_mib, sctpOutUnorderChunks,
4937c478bd9Sstevel@tonic-gate 		    sctp->sctp_oudchunks);
4947c478bd9Sstevel@tonic-gate 		sctp->sctp_oudchunks = 0;
495*f4b3ec61Sdh 		UPDATE_MIB(&sctps->sctps_mib,
496*f4b3ec61Sdh 		    sctpRetransChunks, sctp->sctp_rxtchunks);
4977c478bd9Sstevel@tonic-gate 		sctp->sctp_rxtchunks = 0;
498*f4b3ec61Sdh 		UPDATE_MIB(&sctps->sctps_mib,
499*f4b3ec61Sdh 		    sctpInSCTPPkts, sctp->sctp_ipkts);
5007c478bd9Sstevel@tonic-gate 		sctp->sctp_ipkts = 0;
501*f4b3ec61Sdh 		UPDATE_MIB(&sctps->sctps_mib,
502*f4b3ec61Sdh 		    sctpInCtrlChunks, sctp->sctp_ibchunks);
5037c478bd9Sstevel@tonic-gate 		sctp->sctp_ibchunks = 0;
504*f4b3ec61Sdh 		UPDATE_MIB(&sctps->sctps_mib,
505*f4b3ec61Sdh 		    sctpInOrderChunks, sctp->sctp_idchunks);
5067c478bd9Sstevel@tonic-gate 		sctp->sctp_idchunks = 0;
507*f4b3ec61Sdh 		UPDATE_MIB(&sctps->sctps_mib, sctpInUnorderChunks,
5087c478bd9Sstevel@tonic-gate 		    sctp->sctp_iudchunks);
5097c478bd9Sstevel@tonic-gate 		sctp->sctp_iudchunks = 0;
510*f4b3ec61Sdh 		UPDATE_MIB(&sctps->sctps_mib,
511*f4b3ec61Sdh 		    sctpFragUsrMsgs, sctp->sctp_fragdmsgs);
5127c478bd9Sstevel@tonic-gate 		sctp->sctp_fragdmsgs = 0;
513*f4b3ec61Sdh 		UPDATE_MIB(&sctps->sctps_mib,
514*f4b3ec61Sdh 		    sctpReasmUsrMsgs, sctp->sctp_reassmsgs);
5157c478bd9Sstevel@tonic-gate 		sctp->sctp_reassmsgs = 0;
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate 		sce.sctpAssocId = ntohl(sctp->sctp_lvtag);
5187c478bd9Sstevel@tonic-gate 		sce.sctpAssocLocalPort = ntohs(sctp->sctp_lport);
5197c478bd9Sstevel@tonic-gate 		sce.sctpAssocRemPort = ntohs(sctp->sctp_fport);
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate 		RUN_SCTP(sctp);
5227c478bd9Sstevel@tonic-gate 		if (sctp->sctp_primary != NULL) {
5237c478bd9Sstevel@tonic-gate 			fp = sctp->sctp_primary;
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate 			if (IN6_IS_ADDR_V4MAPPED(&fp->faddr)) {
5267c478bd9Sstevel@tonic-gate 				sce.sctpAssocRemPrimAddrType =
5277c478bd9Sstevel@tonic-gate 				    MIB2_SCTP_ADDR_V4;
5287c478bd9Sstevel@tonic-gate 			} else {
5297c478bd9Sstevel@tonic-gate 				sce.sctpAssocRemPrimAddrType =
5307c478bd9Sstevel@tonic-gate 				    MIB2_SCTP_ADDR_V6;
5317c478bd9Sstevel@tonic-gate 			}
5327c478bd9Sstevel@tonic-gate 			sce.sctpAssocRemPrimAddr = fp->faddr;
5337c478bd9Sstevel@tonic-gate 			sce.sctpAssocLocPrimAddr = fp->saddr;
5347c478bd9Sstevel@tonic-gate 			sce.sctpAssocHeartBeatInterval = TICK_TO_MSEC(
5357c478bd9Sstevel@tonic-gate 			    fp->hb_interval);
5367c478bd9Sstevel@tonic-gate 		} else {
5377c478bd9Sstevel@tonic-gate 			sce.sctpAssocRemPrimAddrType = MIB2_SCTP_ADDR_V4;
5387c478bd9Sstevel@tonic-gate 			bzero(&sce.sctpAssocRemPrimAddr,
5397c478bd9Sstevel@tonic-gate 			    sizeof (sce.sctpAssocRemPrimAddr));
5407c478bd9Sstevel@tonic-gate 			bzero(&sce.sctpAssocLocPrimAddr,
5417c478bd9Sstevel@tonic-gate 			    sizeof (sce.sctpAssocLocPrimAddr));
5427c478bd9Sstevel@tonic-gate 			sce.sctpAssocHeartBeatInterval =
543*f4b3ec61Sdh 			    sctps->sctps_heartbeat_interval;
5447c478bd9Sstevel@tonic-gate 		}
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate 		/*
5477c478bd9Sstevel@tonic-gate 		 * Table for local addresses
5487c478bd9Sstevel@tonic-gate 		 */
5497c478bd9Sstevel@tonic-gate 		scanned = 0;
5507c478bd9Sstevel@tonic-gate 		for (i = 0; i < SCTP_IPIF_HASH; i++) {
5517c478bd9Sstevel@tonic-gate 			sctp_saddr_ipif_t	*obj;
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 			if (sctp->sctp_saddrs[i].ipif_count == 0)
5547c478bd9Sstevel@tonic-gate 				continue;
5557c478bd9Sstevel@tonic-gate 			obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
5567c478bd9Sstevel@tonic-gate 			for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
5577c478bd9Sstevel@tonic-gate 				sctp_ipif_t	*sctp_ipif;
5587c478bd9Sstevel@tonic-gate 				in6_addr_t	addr;
5597c478bd9Sstevel@tonic-gate 
5607c478bd9Sstevel@tonic-gate 				sctp_ipif = obj->saddr_ipifp;
5617c478bd9Sstevel@tonic-gate 				addr = sctp_ipif->sctp_ipif_saddr;
5627c478bd9Sstevel@tonic-gate 				scanned++;
5637c478bd9Sstevel@tonic-gate 				scle.sctpAssocId = ntohl(sctp->sctp_lvtag);
5647c478bd9Sstevel@tonic-gate 				if (IN6_IS_ADDR_V4MAPPED(&addr)) {
5657c478bd9Sstevel@tonic-gate 					scle.sctpAssocLocalAddrType =
5667c478bd9Sstevel@tonic-gate 					    MIB2_SCTP_ADDR_V4;
5677c478bd9Sstevel@tonic-gate 				} else {
5687c478bd9Sstevel@tonic-gate 					scle.sctpAssocLocalAddrType =
5697c478bd9Sstevel@tonic-gate 					    MIB2_SCTP_ADDR_V6;
5707c478bd9Sstevel@tonic-gate 				}
5717c478bd9Sstevel@tonic-gate 				scle.sctpAssocLocalAddr = addr;
5727c478bd9Sstevel@tonic-gate 				(void) snmp_append_data2(mp_local_data,
5737c478bd9Sstevel@tonic-gate 				    &mp_local_tail, (char *)&scle,
5747c478bd9Sstevel@tonic-gate 				    sizeof (scle));
5757c478bd9Sstevel@tonic-gate 				if (scanned >= sctp->sctp_nsaddrs)
5767c478bd9Sstevel@tonic-gate 					goto done;
5777c478bd9Sstevel@tonic-gate 				obj = list_next(&sctp->
5787c478bd9Sstevel@tonic-gate 				    sctp_saddrs[i].sctp_ipif_list, obj);
5797c478bd9Sstevel@tonic-gate 			}
5807c478bd9Sstevel@tonic-gate 		}
5817c478bd9Sstevel@tonic-gate done:
5827c478bd9Sstevel@tonic-gate 		/*
5837c478bd9Sstevel@tonic-gate 		 * Table for remote addresses
5847c478bd9Sstevel@tonic-gate 		 */
5857c478bd9Sstevel@tonic-gate 		for (fp = sctp->sctp_faddrs; fp; fp = fp->next) {
5867c478bd9Sstevel@tonic-gate 			scre.sctpAssocId = ntohl(sctp->sctp_lvtag);
5877c478bd9Sstevel@tonic-gate 			if (IN6_IS_ADDR_V4MAPPED(&fp->faddr)) {
5887c478bd9Sstevel@tonic-gate 				scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V4;
5897c478bd9Sstevel@tonic-gate 			} else {
5907c478bd9Sstevel@tonic-gate 				scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V6;
5917c478bd9Sstevel@tonic-gate 			}
5927c478bd9Sstevel@tonic-gate 			scre.sctpAssocRemAddr = fp->faddr;
5937c478bd9Sstevel@tonic-gate 			if (fp->state == SCTP_FADDRS_ALIVE) {
5947c478bd9Sstevel@tonic-gate 				scre.sctpAssocRemAddrActive =
5957c478bd9Sstevel@tonic-gate 				    scre.sctpAssocRemAddrHBActive =
5967c478bd9Sstevel@tonic-gate 				    MIB2_SCTP_ACTIVE;
5977c478bd9Sstevel@tonic-gate 			} else {
5987c478bd9Sstevel@tonic-gate 				scre.sctpAssocRemAddrActive =
5997c478bd9Sstevel@tonic-gate 				    scre.sctpAssocRemAddrHBActive =
6007c478bd9Sstevel@tonic-gate 				    MIB2_SCTP_INACTIVE;
6017c478bd9Sstevel@tonic-gate 			}
6027c478bd9Sstevel@tonic-gate 			scre.sctpAssocRemAddrRTO = TICK_TO_MSEC(fp->rto);
6037c478bd9Sstevel@tonic-gate 			scre.sctpAssocRemAddrMaxPathRtx = fp->max_retr;
6047c478bd9Sstevel@tonic-gate 			scre.sctpAssocRemAddrRtx = fp->T3expire;
6057c478bd9Sstevel@tonic-gate 			(void) snmp_append_data2(mp_rem_data, &mp_rem_tail,
6067c478bd9Sstevel@tonic-gate 			    (char *)&scre, sizeof (scre));
6077c478bd9Sstevel@tonic-gate 		}
60845916cd2Sjpk 		connp = sctp->sctp_connp;
60945916cd2Sjpk 		needattr = B_FALSE;
61045916cd2Sjpk 		bzero(&mlp, sizeof (mlp));
61145916cd2Sjpk 		if (connp->conn_mlp_type != mlptSingle) {
61245916cd2Sjpk 			if (connp->conn_mlp_type == mlptShared ||
61345916cd2Sjpk 			    connp->conn_mlp_type == mlptBoth)
61445916cd2Sjpk 				mlp.tme_flags |= MIB2_TMEF_SHARED;
61545916cd2Sjpk 			if (connp->conn_mlp_type == mlptPrivate ||
61645916cd2Sjpk 			    connp->conn_mlp_type == mlptBoth)
61745916cd2Sjpk 				mlp.tme_flags |= MIB2_TMEF_PRIVATE;
61845916cd2Sjpk 			needattr = B_TRUE;
61945916cd2Sjpk 		}
62045916cd2Sjpk 		if (connp->conn_peercred != NULL) {
62145916cd2Sjpk 			ts_label_t *tsl;
62245916cd2Sjpk 
62345916cd2Sjpk 			tsl = crgetlabel(connp->conn_peercred);
62445916cd2Sjpk 			mlp.tme_doi = label2doi(tsl);
62545916cd2Sjpk 			mlp.tme_label = *label2bslabel(tsl);
62645916cd2Sjpk 			needattr = B_TRUE;
62745916cd2Sjpk 		}
6287c478bd9Sstevel@tonic-gate 		WAKE_SCTP(sctp);
6297c478bd9Sstevel@tonic-gate 		sce.sctpAssocState = sctp_snmp_state(sctp);
6307c478bd9Sstevel@tonic-gate 		sce.sctpAssocInStreams = sctp->sctp_num_istr;
6317c478bd9Sstevel@tonic-gate 		sce.sctpAssocOutStreams = sctp->sctp_num_ostr;
6327c478bd9Sstevel@tonic-gate 		sce.sctpAssocMaxRetr = sctp->sctp_pa_max_rxt;
6337c478bd9Sstevel@tonic-gate 		/* A 0 here indicates that no primary process is known */
6347c478bd9Sstevel@tonic-gate 		sce.sctpAssocPrimProcess = 0;
6357c478bd9Sstevel@tonic-gate 		sce.sctpAssocT1expired = sctp->sctp_T1expire;
6367c478bd9Sstevel@tonic-gate 		sce.sctpAssocT2expired = sctp->sctp_T2expire;
6377c478bd9Sstevel@tonic-gate 		sce.sctpAssocRtxChunks = sctp->sctp_T3expire;
6387c478bd9Sstevel@tonic-gate 		sce.sctpAssocStartTime = sctp->sctp_assoc_start_time;
6397c478bd9Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_sendq = sctp->sctp_unacked +
6407c478bd9Sstevel@tonic-gate 		    sctp->sctp_unsent;
6417c478bd9Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_recvq = sctp->sctp_rxqueued;
6427c478bd9Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_swnd = sctp->sctp_frwnd;
6437c478bd9Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_rwnd = sctp->sctp_rwnd;
6447c478bd9Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_mss = sctp->sctp_mss;
6457c478bd9Sstevel@tonic-gate 		(void) snmp_append_data2(mp_conn_data, &mp_conn_tail,
6467c478bd9Sstevel@tonic-gate 		    (char *)&sce, sizeof (sce));
64745916cd2Sjpk 		mlp.tme_connidx = idx++;
64845916cd2Sjpk 		if (needattr)
64945916cd2Sjpk 			(void) snmp_append_data2(mp_attr_ctl->b_cont,
65045916cd2Sjpk 			    &mp_attr_tail, (char *)&mlp, sizeof (mlp));
6517c478bd9Sstevel@tonic-gate next_sctp:
6527c478bd9Sstevel@tonic-gate 		sctp_prev = sctp;
653*f4b3ec61Sdh 		mutex_enter(&sctps->sctps_g_lock);
654*f4b3ec61Sdh 		sctp = list_next(&sctps->sctps_g_list, sctp);
6557c478bd9Sstevel@tonic-gate 	}
656*f4b3ec61Sdh 	mutex_exit(&sctps->sctps_g_lock);
6577c478bd9Sstevel@tonic-gate 	if (sctp_prev != NULL)
6587c478bd9Sstevel@tonic-gate 		SCTP_REFRELE(sctp_prev);
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate 	/* fixed length structure for IPv4 and IPv6 counters */
661*f4b3ec61Sdh 	SET_MIB(sctps->sctps_mib.sctpEntrySize, sizeof (sce));
662*f4b3ec61Sdh 	SET_MIB(sctps->sctps_mib.sctpLocalEntrySize, sizeof (scle));
663*f4b3ec61Sdh 	SET_MIB(sctps->sctps_mib.sctpRemoteEntrySize, sizeof (scre));
6647c478bd9Sstevel@tonic-gate 	optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
6657c478bd9Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
6667c478bd9Sstevel@tonic-gate 	optp->name = 0;
667*f4b3ec61Sdh 	(void) snmp_append_data(mpdata, (char *)&sctps->sctps_mib,
668*f4b3ec61Sdh 	    sizeof (sctps->sctps_mib));
6697c478bd9Sstevel@tonic-gate 	optp->len = msgdsize(mpdata);
6707c478bd9Sstevel@tonic-gate 	qreply(q, mpctl);
6717c478bd9Sstevel@tonic-gate 
6727c478bd9Sstevel@tonic-gate 	/* table of connections... */
6737c478bd9Sstevel@tonic-gate 	optp = (struct opthdr *)&mp_conn_ctl->b_rptr[
6747c478bd9Sstevel@tonic-gate 	    sizeof (struct T_optmgmt_ack)];
6757c478bd9Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
6767c478bd9Sstevel@tonic-gate 	optp->name = MIB2_SCTP_CONN;
6777c478bd9Sstevel@tonic-gate 	optp->len = msgdsize(mp_conn_data);
6787c478bd9Sstevel@tonic-gate 	qreply(q, mp_conn_ctl);
6797c478bd9Sstevel@tonic-gate 
6807c478bd9Sstevel@tonic-gate 	/* assoc local address table */
6817c478bd9Sstevel@tonic-gate 	optp = (struct opthdr *)&mp_local_ctl->b_rptr[
6827c478bd9Sstevel@tonic-gate 	    sizeof (struct T_optmgmt_ack)];
6837c478bd9Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
6847c478bd9Sstevel@tonic-gate 	optp->name = MIB2_SCTP_CONN_LOCAL;
6857c478bd9Sstevel@tonic-gate 	optp->len = msgdsize(mp_local_data);
6867c478bd9Sstevel@tonic-gate 	qreply(q, mp_local_ctl);
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate 	/* assoc remote address table */
6897c478bd9Sstevel@tonic-gate 	optp = (struct opthdr *)&mp_rem_ctl->b_rptr[
6907c478bd9Sstevel@tonic-gate 	    sizeof (struct T_optmgmt_ack)];
6917c478bd9Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
6927c478bd9Sstevel@tonic-gate 	optp->name = MIB2_SCTP_CONN_REMOTE;
6937c478bd9Sstevel@tonic-gate 	optp->len = msgdsize(mp_rem_data);
6947c478bd9Sstevel@tonic-gate 	qreply(q, mp_rem_ctl);
6957c478bd9Sstevel@tonic-gate 
69645916cd2Sjpk 	/* table of MLP attributes */
69745916cd2Sjpk 	optp = (struct opthdr *)&mp_attr_ctl->b_rptr[
69845916cd2Sjpk 	    sizeof (struct T_optmgmt_ack)];
69945916cd2Sjpk 	optp->level = MIB2_SCTP;
70045916cd2Sjpk 	optp->name = EXPER_XPORT_MLP;
70145916cd2Sjpk 	optp->len = msgdsize(mp_attr_data);
70245916cd2Sjpk 	if (optp->len == 0)
70345916cd2Sjpk 		freemsg(mp_attr_ctl);
70445916cd2Sjpk 	else
70545916cd2Sjpk 		qreply(q, mp_attr_ctl);
70645916cd2Sjpk 
7077c478bd9Sstevel@tonic-gate 	return (mp_ret);
7087c478bd9Sstevel@tonic-gate }
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate /* Translate SCTP state to MIB2 SCTP state. */
7117c478bd9Sstevel@tonic-gate static int
7127c478bd9Sstevel@tonic-gate sctp_snmp_state(sctp_t *sctp)
7137c478bd9Sstevel@tonic-gate {
7147c478bd9Sstevel@tonic-gate 	if (sctp == NULL)
7157c478bd9Sstevel@tonic-gate 		return (0);
7167c478bd9Sstevel@tonic-gate 
7177c478bd9Sstevel@tonic-gate 	switch (sctp->sctp_state) {
7187c478bd9Sstevel@tonic-gate 	case SCTPS_IDLE:
7197c478bd9Sstevel@tonic-gate 	case SCTPS_BOUND:
7207c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_closed);
7217c478bd9Sstevel@tonic-gate 	case SCTPS_LISTEN:
7227c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_listen);
7237c478bd9Sstevel@tonic-gate 	case SCTPS_COOKIE_WAIT:
7247c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_cookieWait);
7257c478bd9Sstevel@tonic-gate 	case SCTPS_COOKIE_ECHOED:
7267c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_cookieEchoed);
7277c478bd9Sstevel@tonic-gate 	case SCTPS_ESTABLISHED:
7287c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_established);
7297c478bd9Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_PENDING:
7307c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownPending);
7317c478bd9Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_SENT:
7327c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownSent);
7337c478bd9Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_RECEIVED:
7347c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownReceived);
7357c478bd9Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_ACK_SENT:
7367c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownAckSent);
7377c478bd9Sstevel@tonic-gate 	default:
7387c478bd9Sstevel@tonic-gate 		return (0);
7397c478bd9Sstevel@tonic-gate 	}
7407c478bd9Sstevel@tonic-gate }
741