xref: /onnv-gate/usr/src/uts/common/inet/sctp/sctp_snmp.c (revision 11042:2d6e217af1b4)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51676Sjpk  * Common Development and Distribution License (the "License").
61676Sjpk  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
211735Skcpoon 
220Sstevel@tonic-gate /*
239710SKen.Powell@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #include <sys/types.h>
280Sstevel@tonic-gate #include <sys/stream.h>
290Sstevel@tonic-gate #include <sys/cmn_err.h>
300Sstevel@tonic-gate #define	_SUN_TPI_VERSION 2
310Sstevel@tonic-gate #include <sys/tihdr.h>
320Sstevel@tonic-gate #include <sys/ddi.h>
330Sstevel@tonic-gate #include <sys/sunddi.h>
341676Sjpk #include <sys/tsol/tndb.h>
350Sstevel@tonic-gate 
360Sstevel@tonic-gate #include <netinet/in.h>
370Sstevel@tonic-gate 
380Sstevel@tonic-gate #include <inet/common.h>
390Sstevel@tonic-gate #include <inet/ip.h>
400Sstevel@tonic-gate #include <inet/mib2.h>
410Sstevel@tonic-gate #include <inet/snmpcom.h>
420Sstevel@tonic-gate #include <inet/kstatcom.h>
430Sstevel@tonic-gate #include <inet/ipclassifier.h>
440Sstevel@tonic-gate #include "sctp_impl.h"
450Sstevel@tonic-gate #include "sctp_addr.h"
460Sstevel@tonic-gate 
470Sstevel@tonic-gate static int sctp_snmp_state(sctp_t *sctp);
480Sstevel@tonic-gate 
491735Skcpoon 
500Sstevel@tonic-gate static int
510Sstevel@tonic-gate sctp_kstat_update(kstat_t *kp, int rw)
520Sstevel@tonic-gate {
530Sstevel@tonic-gate 	sctp_named_kstat_t	*sctpkp;
540Sstevel@tonic-gate 	sctp_t			*sctp, *sctp_prev;
553448Sdh155122 	zoneid_t	myzoneid;
563448Sdh155122 	netstackid_t	stackid = (netstackid_t)(uintptr_t)kp->ks_private;
573448Sdh155122 	netstack_t	*ns;
583448Sdh155122 	sctp_stack_t	*sctps;
590Sstevel@tonic-gate 
600Sstevel@tonic-gate 	if (kp == NULL|| kp->ks_data == NULL)
610Sstevel@tonic-gate 		return (EIO);
620Sstevel@tonic-gate 
630Sstevel@tonic-gate 	if (rw == KSTAT_WRITE)
640Sstevel@tonic-gate 		return (EACCES);
650Sstevel@tonic-gate 
663448Sdh155122 	ns = netstack_find_by_stackid(stackid);
673448Sdh155122 	if (ns == NULL)
683448Sdh155122 		return (-1);
693448Sdh155122 	sctps = ns->netstack_sctp;
703448Sdh155122 	if (sctps == NULL) {
713448Sdh155122 		netstack_rele(ns);
723448Sdh155122 		return (-1);
733448Sdh155122 	}
743448Sdh155122 	myzoneid = netstackid_to_zoneid(stackid);
750Sstevel@tonic-gate 
760Sstevel@tonic-gate 	/*
770Sstevel@tonic-gate 	 * Get the number of current associations and gather their
780Sstevel@tonic-gate 	 * individual set of statistics.
790Sstevel@tonic-gate 	 */
803448Sdh155122 	SET_MIB(sctps->sctps_mib.sctpCurrEstab, 0);
810Sstevel@tonic-gate 	sctp_prev = NULL;
823448Sdh155122 	mutex_enter(&sctps->sctps_g_lock);
83*11042SErik.Nordmark@Sun.COM 	sctp = list_head(&sctps->sctps_g_list);
840Sstevel@tonic-gate 	while (sctp != NULL) {
850Sstevel@tonic-gate 		mutex_enter(&sctp->sctp_reflock);
860Sstevel@tonic-gate 		if (sctp->sctp_condemned) {
870Sstevel@tonic-gate 			mutex_exit(&sctp->sctp_reflock);
883448Sdh155122 			sctp = list_next(&sctps->sctps_g_list, sctp);
890Sstevel@tonic-gate 			continue;
900Sstevel@tonic-gate 		}
910Sstevel@tonic-gate 		sctp->sctp_refcnt++;
920Sstevel@tonic-gate 		mutex_exit(&sctp->sctp_reflock);
933448Sdh155122 		mutex_exit(&sctps->sctps_g_lock);
940Sstevel@tonic-gate 		if (sctp_prev != NULL)
950Sstevel@tonic-gate 			SCTP_REFRELE(sctp_prev);
963448Sdh155122 		if (sctp->sctp_connp->conn_zoneid != myzoneid)
970Sstevel@tonic-gate 			goto next_sctp;
980Sstevel@tonic-gate 		if (sctp->sctp_state == SCTPS_ESTABLISHED ||
990Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_PENDING ||
1000Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) {
1013448Sdh155122 			BUMP_MIB(&sctps->sctps_mib, sctpCurrEstab);
1020Sstevel@tonic-gate 		}
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate 		if (sctp->sctp_opkts) {
1053448Sdh155122 			UPDATE_MIB(&sctps->sctps_mib, sctpOutSCTPPkts,
1060Sstevel@tonic-gate 			    sctp->sctp_opkts);
1070Sstevel@tonic-gate 			sctp->sctp_opkts = 0;
1080Sstevel@tonic-gate 		}
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate 		if (sctp->sctp_obchunks) {
1113448Sdh155122 			UPDATE_MIB(&sctps->sctps_mib, sctpOutCtrlChunks,
1120Sstevel@tonic-gate 			    sctp->sctp_obchunks);
11310751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_obchunks,
11410751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_obchunks);
1150Sstevel@tonic-gate 			sctp->sctp_obchunks = 0;
1160Sstevel@tonic-gate 		}
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate 		if (sctp->sctp_odchunks) {
1193448Sdh155122 			UPDATE_MIB(&sctps->sctps_mib, sctpOutOrderChunks,
1200Sstevel@tonic-gate 			    sctp->sctp_odchunks);
12110751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_odchunks,
12210751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_odchunks);
1230Sstevel@tonic-gate 			sctp->sctp_odchunks = 0;
1240Sstevel@tonic-gate 		}
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate 		if (sctp->sctp_oudchunks) {
1273448Sdh155122 			UPDATE_MIB(&sctps->sctps_mib, sctpOutUnorderChunks,
1280Sstevel@tonic-gate 			    sctp->sctp_oudchunks);
12910751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_oudchunks,
13010751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_oudchunks);
1310Sstevel@tonic-gate 			sctp->sctp_oudchunks = 0;
1320Sstevel@tonic-gate 		}
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate 		if (sctp->sctp_rxtchunks) {
1353448Sdh155122 			UPDATE_MIB(&sctps->sctps_mib, sctpRetransChunks,
1360Sstevel@tonic-gate 			    sctp->sctp_rxtchunks);
13710751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_rxtchunks,
13810751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_rxtchunks);
1390Sstevel@tonic-gate 			sctp->sctp_rxtchunks = 0;
1400Sstevel@tonic-gate 		}
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate 		if (sctp->sctp_ipkts) {
1433448Sdh155122 			UPDATE_MIB(&sctps->sctps_mib, sctpInSCTPPkts,
1443448Sdh155122 			    sctp->sctp_ipkts);
1450Sstevel@tonic-gate 			sctp->sctp_ipkts = 0;
1460Sstevel@tonic-gate 		}
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 		if (sctp->sctp_ibchunks) {
1493448Sdh155122 			UPDATE_MIB(&sctps->sctps_mib, sctpInCtrlChunks,
1500Sstevel@tonic-gate 			    sctp->sctp_ibchunks);
15110751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_ibchunks,
15210751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_ibchunks);
1530Sstevel@tonic-gate 			sctp->sctp_ibchunks = 0;
1540Sstevel@tonic-gate 		}
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 		if (sctp->sctp_idchunks) {
1573448Sdh155122 			UPDATE_MIB(&sctps->sctps_mib, sctpInOrderChunks,
1580Sstevel@tonic-gate 			    sctp->sctp_idchunks);
15910751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_idchunks,
16010751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_idchunks);
1610Sstevel@tonic-gate 			sctp->sctp_idchunks = 0;
1620Sstevel@tonic-gate 		}
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate 		if (sctp->sctp_iudchunks) {
1653448Sdh155122 			UPDATE_MIB(&sctps->sctps_mib, sctpInUnorderChunks,
1660Sstevel@tonic-gate 			    sctp->sctp_iudchunks);
16710751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_iudchunks,
16810751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_iudchunks);
1690Sstevel@tonic-gate 			sctp->sctp_iudchunks = 0;
1700Sstevel@tonic-gate 		}
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate 		if (sctp->sctp_fragdmsgs) {
1733448Sdh155122 			UPDATE_MIB(&sctps->sctps_mib, sctpFragUsrMsgs,
1740Sstevel@tonic-gate 			    sctp->sctp_fragdmsgs);
1750Sstevel@tonic-gate 			sctp->sctp_fragdmsgs = 0;
1760Sstevel@tonic-gate 		}
1770Sstevel@tonic-gate 
1780Sstevel@tonic-gate 		if (sctp->sctp_reassmsgs) {
1793448Sdh155122 			UPDATE_MIB(&sctps->sctps_mib, sctpReasmUsrMsgs,
1800Sstevel@tonic-gate 			    sctp->sctp_reassmsgs);
1810Sstevel@tonic-gate 			sctp->sctp_reassmsgs = 0;
1820Sstevel@tonic-gate 		}
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate next_sctp:
1850Sstevel@tonic-gate 		sctp_prev = sctp;
1863448Sdh155122 		mutex_enter(&sctps->sctps_g_lock);
1873448Sdh155122 		sctp = list_next(&sctps->sctps_g_list, sctp);
1880Sstevel@tonic-gate 	}
1893448Sdh155122 	mutex_exit(&sctps->sctps_g_lock);
1900Sstevel@tonic-gate 	if (sctp_prev != NULL)
1910Sstevel@tonic-gate 		SCTP_REFRELE(sctp_prev);
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate 	/* Copy data from the SCTP MIB */
1940Sstevel@tonic-gate 	sctpkp = (sctp_named_kstat_t *)kp->ks_data;
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate 	/* These are from global ndd params. */
1973448Sdh155122 	sctpkp->sctpRtoMin.value.ui32 = sctps->sctps_rto_ming;
1983448Sdh155122 	sctpkp->sctpRtoMax.value.ui32 = sctps->sctps_rto_maxg;
1993448Sdh155122 	sctpkp->sctpRtoInitial.value.ui32 = sctps->sctps_rto_initialg;
2003448Sdh155122 	sctpkp->sctpValCookieLife.value.ui32 = sctps->sctps_cookie_life;
2013448Sdh155122 	sctpkp->sctpMaxInitRetr.value.ui32 = sctps->sctps_max_init_retr;
2020Sstevel@tonic-gate 
2033448Sdh155122 	sctpkp->sctpCurrEstab.value.i32 = sctps->sctps_mib.sctpCurrEstab;
2043448Sdh155122 	sctpkp->sctpActiveEstab.value.i32 = sctps->sctps_mib.sctpActiveEstab;
2053448Sdh155122 	sctpkp->sctpPassiveEstab.value.i32 = sctps->sctps_mib.sctpPassiveEstab;
2063448Sdh155122 	sctpkp->sctpAborted.value.i32 = sctps->sctps_mib.sctpAborted;
2073448Sdh155122 	sctpkp->sctpShutdowns.value.i32 = sctps->sctps_mib.sctpShutdowns;
2083448Sdh155122 	sctpkp->sctpOutOfBlue.value.i32 = sctps->sctps_mib.sctpOutOfBlue;
2093448Sdh155122 	sctpkp->sctpChecksumError.value.i32 =
2103448Sdh155122 	    sctps->sctps_mib.sctpChecksumError;
2113448Sdh155122 	sctpkp->sctpOutCtrlChunks.value.i64 =
2123448Sdh155122 	    sctps->sctps_mib.sctpOutCtrlChunks;
2133448Sdh155122 	sctpkp->sctpOutOrderChunks.value.i64 =
2143448Sdh155122 	    sctps->sctps_mib.sctpOutOrderChunks;
2153448Sdh155122 	sctpkp->sctpOutUnorderChunks.value.i64 =
2163448Sdh155122 	    sctps->sctps_mib.sctpOutUnorderChunks;
2173448Sdh155122 	sctpkp->sctpRetransChunks.value.i64 =
2183448Sdh155122 	    sctps->sctps_mib.sctpRetransChunks;
2193448Sdh155122 	sctpkp->sctpOutAck.value.i32 = sctps->sctps_mib.sctpOutAck;
2203448Sdh155122 	sctpkp->sctpOutAckDelayed.value.i32 =
2213448Sdh155122 	    sctps->sctps_mib.sctpOutAckDelayed;
2223448Sdh155122 	sctpkp->sctpOutWinUpdate.value.i32 = sctps->sctps_mib.sctpOutWinUpdate;
2233448Sdh155122 	sctpkp->sctpOutFastRetrans.value.i32 =
2243448Sdh155122 	    sctps->sctps_mib.sctpOutFastRetrans;
2253448Sdh155122 	sctpkp->sctpOutWinProbe.value.i32 = sctps->sctps_mib.sctpOutWinProbe;
2263448Sdh155122 	sctpkp->sctpInCtrlChunks.value.i64 = sctps->sctps_mib.sctpInCtrlChunks;
2273448Sdh155122 	sctpkp->sctpInOrderChunks.value.i64 =
2283448Sdh155122 	    sctps->sctps_mib.sctpInOrderChunks;
2293448Sdh155122 	sctpkp->sctpInUnorderChunks.value.i64 =
2303448Sdh155122 	    sctps->sctps_mib.sctpInUnorderChunks;
2313448Sdh155122 	sctpkp->sctpInAck.value.i32 = sctps->sctps_mib.sctpInAck;
2323448Sdh155122 	sctpkp->sctpInDupAck.value.i32 = sctps->sctps_mib.sctpInDupAck;
2333448Sdh155122 	sctpkp->sctpInAckUnsent.value.i32 = sctps->sctps_mib.sctpInAckUnsent;
2343448Sdh155122 	sctpkp->sctpFragUsrMsgs.value.i64 = sctps->sctps_mib.sctpFragUsrMsgs;
2353448Sdh155122 	sctpkp->sctpReasmUsrMsgs.value.i64 = sctps->sctps_mib.sctpReasmUsrMsgs;
2363448Sdh155122 	sctpkp->sctpOutSCTPPkts.value.i64 = sctps->sctps_mib.sctpOutSCTPPkts;
2373448Sdh155122 	sctpkp->sctpInSCTPPkts.value.i64 = sctps->sctps_mib.sctpInSCTPPkts;
2383448Sdh155122 	sctpkp->sctpInInvalidCookie.value.i32 =
2393448Sdh155122 	    sctps->sctps_mib.sctpInInvalidCookie;
2403448Sdh155122 	sctpkp->sctpTimRetrans.value.i32 = sctps->sctps_mib.sctpTimRetrans;
2413448Sdh155122 	sctpkp->sctpTimRetransDrop.value.i32 =
2423448Sdh155122 	    sctps->sctps_mib.sctpTimRetransDrop;
2430Sstevel@tonic-gate 	sctpkp->sctpTimHeartBeatProbe.value.i32 =
2443448Sdh155122 	    sctps->sctps_mib.sctpTimHeartBeatProbe;
2453448Sdh155122 	sctpkp->sctpTimHeartBeatDrop.value.i32 =
2463448Sdh155122 	    sctps->sctps_mib.sctpTimHeartBeatDrop;
2473448Sdh155122 	sctpkp->sctpListenDrop.value.i32 = sctps->sctps_mib.sctpListenDrop;
2483448Sdh155122 	sctpkp->sctpInClosed.value.i32 = sctps->sctps_mib.sctpInClosed;
2490Sstevel@tonic-gate 
2503448Sdh155122 	netstack_rele(ns);
2510Sstevel@tonic-gate 	return (0);
2520Sstevel@tonic-gate }
2530Sstevel@tonic-gate 
2543448Sdh155122 void *
2553448Sdh155122 sctp_kstat_init(netstackid_t stackid)
2560Sstevel@tonic-gate {
2573448Sdh155122 	kstat_t	*ksp;
2583448Sdh155122 
2590Sstevel@tonic-gate 	sctp_named_kstat_t template = {
2600Sstevel@tonic-gate 		{ "sctpRtoAlgorithm",		KSTAT_DATA_INT32, 0 },
2610Sstevel@tonic-gate 		{ "sctpRtoMin",			KSTAT_DATA_UINT32, 0 },
2620Sstevel@tonic-gate 		{ "sctpRtoMax",			KSTAT_DATA_UINT32, 0 },
2630Sstevel@tonic-gate 		{ "sctpRtoInitial",		KSTAT_DATA_UINT32, 0 },
2640Sstevel@tonic-gate 		{ "sctpMaxAssocs",		KSTAT_DATA_INT32, 0 },
2650Sstevel@tonic-gate 		{ "sctpValCookieLife",		KSTAT_DATA_UINT32, 0 },
2660Sstevel@tonic-gate 		{ "sctpMaxInitRetr",		KSTAT_DATA_UINT32, 0 },
2670Sstevel@tonic-gate 		{ "sctpCurrEstab",		KSTAT_DATA_INT32, 0 },
2680Sstevel@tonic-gate 		{ "sctpActiveEstab",		KSTAT_DATA_INT32, 0 },
2690Sstevel@tonic-gate 		{ "sctpPassiveEstab",		KSTAT_DATA_INT32, 0 },
2700Sstevel@tonic-gate 		{ "sctpAborted",		KSTAT_DATA_INT32, 0 },
2710Sstevel@tonic-gate 		{ "sctpShutdowns",		KSTAT_DATA_INT32, 0 },
2720Sstevel@tonic-gate 		{ "sctpOutOfBlue",		KSTAT_DATA_INT32, 0 },
2730Sstevel@tonic-gate 		{ "sctpChecksumError",		KSTAT_DATA_INT32, 0 },
2740Sstevel@tonic-gate 		{ "sctpOutCtrlChunks",		KSTAT_DATA_INT64, 0 },
2750Sstevel@tonic-gate 		{ "sctpOutOrderChunks",		KSTAT_DATA_INT64, 0 },
2760Sstevel@tonic-gate 		{ "sctpOutUnorderChunks",	KSTAT_DATA_INT64, 0 },
2770Sstevel@tonic-gate 		{ "sctpRetransChunks",		KSTAT_DATA_INT64, 0 },
2780Sstevel@tonic-gate 		{ "sctpOutAck",			KSTAT_DATA_INT32, 0 },
2790Sstevel@tonic-gate 		{ "sctpOutAckDelayed",		KSTAT_DATA_INT32, 0 },
2800Sstevel@tonic-gate 		{ "sctpOutWinUpdate",		KSTAT_DATA_INT32, 0 },
2810Sstevel@tonic-gate 		{ "sctpOutFastRetrans",		KSTAT_DATA_INT32, 0 },
2820Sstevel@tonic-gate 		{ "sctpOutWinProbe",		KSTAT_DATA_INT32, 0 },
2830Sstevel@tonic-gate 		{ "sctpInCtrlChunks",		KSTAT_DATA_INT64, 0 },
2840Sstevel@tonic-gate 		{ "sctpInOrderChunks",		KSTAT_DATA_INT64, 0 },
2850Sstevel@tonic-gate 		{ "sctpInUnorderChunks",	KSTAT_DATA_INT64, 0 },
2860Sstevel@tonic-gate 		{ "sctpInAck",			KSTAT_DATA_INT32, 0 },
2870Sstevel@tonic-gate 		{ "sctpInDupAck",		KSTAT_DATA_INT32, 0 },
2880Sstevel@tonic-gate 		{ "sctpInAckUnsent",		KSTAT_DATA_INT32, 0 },
2890Sstevel@tonic-gate 		{ "sctpFragUsrMsgs",		KSTAT_DATA_INT64, 0 },
2900Sstevel@tonic-gate 		{ "sctpReasmUsrMsgs",		KSTAT_DATA_INT64, 0 },
2910Sstevel@tonic-gate 		{ "sctpOutSCTPPkts",		KSTAT_DATA_INT64, 0 },
2920Sstevel@tonic-gate 		{ "sctpInSCTPPkts",		KSTAT_DATA_INT64, 0 },
2930Sstevel@tonic-gate 		{ "sctpInInvalidCookie",	KSTAT_DATA_INT32, 0 },
2940Sstevel@tonic-gate 		{ "sctpTimRetrans",		KSTAT_DATA_INT32, 0 },
2950Sstevel@tonic-gate 		{ "sctpTimRetransDrop",		KSTAT_DATA_INT32, 0 },
2960Sstevel@tonic-gate 		{ "sctpTimHearBeatProbe",	KSTAT_DATA_INT32, 0 },
2970Sstevel@tonic-gate 		{ "sctpTimHearBeatDrop",	KSTAT_DATA_INT32, 0 },
2980Sstevel@tonic-gate 		{ "sctpListenDrop",		KSTAT_DATA_INT32, 0 },
2990Sstevel@tonic-gate 		{ "sctpInClosed",		KSTAT_DATA_INT32, 0 }
3000Sstevel@tonic-gate 	};
3010Sstevel@tonic-gate 
3023448Sdh155122 	ksp = kstat_create_netstack(SCTP_MOD_NAME, 0, "sctp", "mib2",
3033448Sdh155122 	    KSTAT_TYPE_NAMED, NUM_OF_FIELDS(sctp_named_kstat_t), 0, stackid);
3040Sstevel@tonic-gate 
3053448Sdh155122 	if (ksp == NULL || ksp->ks_data == NULL)
3063448Sdh155122 		return (NULL);
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate 	/* These won't change. */
3090Sstevel@tonic-gate 	template.sctpRtoAlgorithm.value.i32 = MIB2_SCTP_RTOALGO_VANJ;
3100Sstevel@tonic-gate 	template.sctpMaxAssocs.value.i32 = -1;
3110Sstevel@tonic-gate 
3123448Sdh155122 	bcopy(&template, ksp->ks_data, sizeof (template));
3133448Sdh155122 	ksp->ks_update = sctp_kstat_update;
3143448Sdh155122 	ksp->ks_private = (void *)(uintptr_t)stackid;
3153448Sdh155122 
3163448Sdh155122 	kstat_install(ksp);
3173448Sdh155122 	return (ksp);
3183448Sdh155122 }
3190Sstevel@tonic-gate 
3203448Sdh155122 /*
3213448Sdh155122  * The following kstats are for debugging purposes.  They keep
3223448Sdh155122  * track of problems which should not happen normally.  But in
3233448Sdh155122  * those cases which they do happen, these kstats would be handy
3243448Sdh155122  * for engineers to diagnose the problems.  They are not intended
3253448Sdh155122  * to be consumed by customers.
3263448Sdh155122  */
3273448Sdh155122 void *
3283448Sdh155122 sctp_kstat2_init(netstackid_t stackid, sctp_kstat_t *sctps_statisticsp)
3293448Sdh155122 {
3303448Sdh155122 	kstat_t *ksp;
3311735Skcpoon 
3323448Sdh155122 	sctp_kstat_t template = {
3333448Sdh155122 		{ "sctp_add_faddr",			KSTAT_DATA_UINT64 },
3343448Sdh155122 		{ "sctp_add_timer",			KSTAT_DATA_UINT64 },
3353448Sdh155122 		{ "sctp_conn_create",			KSTAT_DATA_UINT64 },
3363448Sdh155122 		{ "sctp_find_next_tq",			KSTAT_DATA_UINT64 },
3373448Sdh155122 		{ "sctp_fr_add_hdr",			KSTAT_DATA_UINT64 },
3383448Sdh155122 		{ "sctp_fr_not_found",			KSTAT_DATA_UINT64 },
3393448Sdh155122 		{ "sctp_output_failed",			KSTAT_DATA_UINT64 },
3403448Sdh155122 		{ "sctp_rexmit_failed",			KSTAT_DATA_UINT64 },
3413448Sdh155122 		{ "sctp_send_init_failed",		KSTAT_DATA_UINT64 },
3423448Sdh155122 		{ "sctp_send_cookie_failed",		KSTAT_DATA_UINT64 },
3433448Sdh155122 		{ "sctp_send_cookie_ack_failed",	KSTAT_DATA_UINT64 },
3443448Sdh155122 		{ "sctp_send_err_failed",		KSTAT_DATA_UINT64 },
3453448Sdh155122 		{ "sctp_send_sack_failed",		KSTAT_DATA_UINT64 },
3463448Sdh155122 		{ "sctp_send_shutdown_failed",		KSTAT_DATA_UINT64 },
3473448Sdh155122 		{ "sctp_send_shutdown_ack_failed",	KSTAT_DATA_UINT64 },
3483448Sdh155122 		{ "sctp_send_shutdown_comp_failed",	KSTAT_DATA_UINT64 },
3493448Sdh155122 		{ "sctp_send_user_abort_failed",	KSTAT_DATA_UINT64 },
3503448Sdh155122 		{ "sctp_send_asconf_failed",		KSTAT_DATA_UINT64 },
3513448Sdh155122 		{ "sctp_send_asconf_ack_failed",	KSTAT_DATA_UINT64 },
3523448Sdh155122 		{ "sctp_send_ftsn_failed",		KSTAT_DATA_UINT64 },
3533448Sdh155122 		{ "sctp_send_hb_failed",		KSTAT_DATA_UINT64 },
3543448Sdh155122 		{ "sctp_return_hb_failed",		KSTAT_DATA_UINT64 },
3553448Sdh155122 		{ "sctp_ss_rexmit_failed",		KSTAT_DATA_UINT64 },
3563448Sdh155122 		{ "sctp_cl_connect",			KSTAT_DATA_UINT64 },
3573448Sdh155122 		{ "sctp_cl_assoc_change",		KSTAT_DATA_UINT64 },
3583448Sdh155122 		{ "sctp_cl_check_addrs",		KSTAT_DATA_UINT64 },
3593448Sdh155122 	};
3603448Sdh155122 
3613448Sdh155122 	ksp = kstat_create_netstack(SCTP_MOD_NAME, 0, "sctpstat", "net",
3623448Sdh155122 	    KSTAT_TYPE_NAMED, NUM_OF_FIELDS(template), KSTAT_FLAG_VIRTUAL,
3633448Sdh155122 	    stackid);
3643448Sdh155122 
3653448Sdh155122 	if (ksp == NULL)
3663448Sdh155122 		return (NULL);
3673448Sdh155122 
3683448Sdh155122 	bcopy(&template, sctps_statisticsp, sizeof (template));
3693448Sdh155122 	ksp->ks_data = (void *)sctps_statisticsp;
3703448Sdh155122 	ksp->ks_private = (void *)(uintptr_t)stackid;
3713448Sdh155122 
3723448Sdh155122 	kstat_install(ksp);
3733448Sdh155122 	return (ksp);
3743448Sdh155122 }
3753448Sdh155122 
3763448Sdh155122 void
3773448Sdh155122 sctp_kstat_fini(netstackid_t stackid, kstat_t *ksp)
3783448Sdh155122 {
3793448Sdh155122 	if (ksp != NULL) {
3803448Sdh155122 		ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
3813448Sdh155122 		kstat_delete_netstack(ksp, stackid);
3821735Skcpoon 	}
3830Sstevel@tonic-gate }
3840Sstevel@tonic-gate 
3850Sstevel@tonic-gate void
3863448Sdh155122 sctp_kstat2_fini(netstackid_t stackid, kstat_t *ksp)
3870Sstevel@tonic-gate {
3883448Sdh155122 	if (ksp != NULL) {
3893448Sdh155122 		ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
3903448Sdh155122 		kstat_delete_netstack(ksp, stackid);
3911735Skcpoon 	}
3920Sstevel@tonic-gate }
3930Sstevel@tonic-gate 
3940Sstevel@tonic-gate /*
3950Sstevel@tonic-gate  * Return SNMP global stats in buffer in mpdata.
3960Sstevel@tonic-gate  * Return associatiation table in mp_conn_data,
3970Sstevel@tonic-gate  * local address table in mp_local_data, and
3980Sstevel@tonic-gate  * remote address table in mp_rem_data.
3990Sstevel@tonic-gate  */
4000Sstevel@tonic-gate mblk_t *
4013448Sdh155122 sctp_snmp_get_mib2(queue_t *q, mblk_t *mpctl, sctp_stack_t *sctps)
4020Sstevel@tonic-gate {
4030Sstevel@tonic-gate 	mblk_t			*mpdata, *mp_ret;
4040Sstevel@tonic-gate 	mblk_t			*mp_conn_ctl = NULL;
4050Sstevel@tonic-gate 	mblk_t			*mp_conn_data;
4060Sstevel@tonic-gate 	mblk_t			*mp_conn_tail = NULL;
4070Sstevel@tonic-gate 	mblk_t			*mp_local_ctl = NULL;
4080Sstevel@tonic-gate 	mblk_t			*mp_local_data;
4090Sstevel@tonic-gate 	mblk_t			*mp_local_tail = NULL;
4100Sstevel@tonic-gate 	mblk_t			*mp_rem_ctl = NULL;
4110Sstevel@tonic-gate 	mblk_t			*mp_rem_data;
4120Sstevel@tonic-gate 	mblk_t			*mp_rem_tail = NULL;
4131676Sjpk 	mblk_t			*mp_attr_ctl = NULL;
4141676Sjpk 	mblk_t			*mp_attr_data;
4151676Sjpk 	mblk_t			*mp_attr_tail = NULL;
4160Sstevel@tonic-gate 	struct opthdr		*optp;
4170Sstevel@tonic-gate 	sctp_t			*sctp, *sctp_prev = NULL;
4180Sstevel@tonic-gate 	sctp_faddr_t		*fp;
4190Sstevel@tonic-gate 	mib2_sctpConnEntry_t	sce;
4200Sstevel@tonic-gate 	mib2_sctpConnLocalEntry_t	scle;
4210Sstevel@tonic-gate 	mib2_sctpConnRemoteEntry_t	scre;
4221676Sjpk 	mib2_transportMLPEntry_t	mlp;
4230Sstevel@tonic-gate 	int			i;
4240Sstevel@tonic-gate 	int			l;
4250Sstevel@tonic-gate 	int			scanned = 0;
4260Sstevel@tonic-gate 	zoneid_t		zoneid = Q_TO_CONN(q)->conn_zoneid;
4271676Sjpk 	conn_t			*connp;
4281676Sjpk 	boolean_t		needattr;
4291676Sjpk 	int			idx;
4300Sstevel@tonic-gate 
4310Sstevel@tonic-gate 	/*
4320Sstevel@tonic-gate 	 * Make copies of the original message.
4330Sstevel@tonic-gate 	 * mpctl will hold SCTP counters,
4340Sstevel@tonic-gate 	 * mp_conn_ctl will hold list of connections.
4350Sstevel@tonic-gate 	 */
4360Sstevel@tonic-gate 	mp_ret = copymsg(mpctl);
4370Sstevel@tonic-gate 	mp_conn_ctl = copymsg(mpctl);
4380Sstevel@tonic-gate 	mp_local_ctl = copymsg(mpctl);
4390Sstevel@tonic-gate 	mp_rem_ctl = copymsg(mpctl);
4401676Sjpk 	mp_attr_ctl = copymsg(mpctl);
4410Sstevel@tonic-gate 
4420Sstevel@tonic-gate 	mpdata = mpctl->b_cont;
4430Sstevel@tonic-gate 
4441676Sjpk 	if (mp_conn_ctl == NULL || mp_local_ctl == NULL ||
4451676Sjpk 	    mp_rem_ctl == NULL || mp_attr_ctl == NULL || mpdata == NULL) {
4461676Sjpk 		freemsg(mp_attr_ctl);
4470Sstevel@tonic-gate 		freemsg(mp_rem_ctl);
4480Sstevel@tonic-gate 		freemsg(mp_local_ctl);
4490Sstevel@tonic-gate 		freemsg(mp_conn_ctl);
4500Sstevel@tonic-gate 		freemsg(mp_ret);
4510Sstevel@tonic-gate 		freemsg(mpctl);
4520Sstevel@tonic-gate 		return (NULL);
4530Sstevel@tonic-gate 	}
4540Sstevel@tonic-gate 	mp_conn_data = mp_conn_ctl->b_cont;
4550Sstevel@tonic-gate 	mp_local_data = mp_local_ctl->b_cont;
4560Sstevel@tonic-gate 	mp_rem_data = mp_rem_ctl->b_cont;
4571676Sjpk 	mp_attr_data = mp_attr_ctl->b_cont;
4580Sstevel@tonic-gate 
4590Sstevel@tonic-gate 	/* hostname address parameters are not supported in Solaris */
4600Sstevel@tonic-gate 	sce.sctpAssocRemHostName.o_length = 0;
4610Sstevel@tonic-gate 	sce.sctpAssocRemHostName.o_bytes[0] = 0;
4620Sstevel@tonic-gate 
4630Sstevel@tonic-gate 	/* build table of connections -- need count in fixed part */
4643448Sdh155122 	SET_MIB(sctps->sctps_mib.sctpRtoAlgorithm, MIB2_SCTP_RTOALGO_VANJ);
4653448Sdh155122 	SET_MIB(sctps->sctps_mib.sctpRtoMin, sctps->sctps_rto_ming);
4663448Sdh155122 	SET_MIB(sctps->sctps_mib.sctpRtoMax, sctps->sctps_rto_maxg);
4673448Sdh155122 	SET_MIB(sctps->sctps_mib.sctpRtoInitial, sctps->sctps_rto_initialg);
4683448Sdh155122 	SET_MIB(sctps->sctps_mib.sctpMaxAssocs, -1);
4693448Sdh155122 	SET_MIB(sctps->sctps_mib.sctpValCookieLife, sctps->sctps_cookie_life);
4703448Sdh155122 	SET_MIB(sctps->sctps_mib.sctpMaxInitRetr, sctps->sctps_max_init_retr);
4713448Sdh155122 	SET_MIB(sctps->sctps_mib.sctpCurrEstab, 0);
4720Sstevel@tonic-gate 
4731676Sjpk 	idx = 0;
4743448Sdh155122 	mutex_enter(&sctps->sctps_g_lock);
475*11042SErik.Nordmark@Sun.COM 	sctp = list_head(&sctps->sctps_g_list);
4760Sstevel@tonic-gate 	while (sctp != NULL) {
4770Sstevel@tonic-gate 		mutex_enter(&sctp->sctp_reflock);
4780Sstevel@tonic-gate 		if (sctp->sctp_condemned) {
4790Sstevel@tonic-gate 			mutex_exit(&sctp->sctp_reflock);
4803448Sdh155122 			sctp = list_next(&sctps->sctps_g_list, sctp);
4810Sstevel@tonic-gate 			continue;
4820Sstevel@tonic-gate 		}
4830Sstevel@tonic-gate 		sctp->sctp_refcnt++;
4840Sstevel@tonic-gate 		mutex_exit(&sctp->sctp_reflock);
4853448Sdh155122 		mutex_exit(&sctps->sctps_g_lock);
4860Sstevel@tonic-gate 		if (sctp_prev != NULL)
4870Sstevel@tonic-gate 			SCTP_REFRELE(sctp_prev);
4880Sstevel@tonic-gate 		if (sctp->sctp_connp->conn_zoneid != zoneid)
4890Sstevel@tonic-gate 			goto next_sctp;
4900Sstevel@tonic-gate 		if (sctp->sctp_state == SCTPS_ESTABLISHED ||
4910Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_PENDING ||
4920Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) {
4933448Sdh155122 			BUMP_MIB(&sctps->sctps_mib, sctpCurrEstab);
4940Sstevel@tonic-gate 		}
4953448Sdh155122 		UPDATE_MIB(&sctps->sctps_mib,
4963448Sdh155122 		    sctpOutSCTPPkts, sctp->sctp_opkts);
4970Sstevel@tonic-gate 		sctp->sctp_opkts = 0;
4983448Sdh155122 		UPDATE_MIB(&sctps->sctps_mib,
4993448Sdh155122 		    sctpOutCtrlChunks, sctp->sctp_obchunks);
50010751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_obchunks,
50110751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_obchunks);
5020Sstevel@tonic-gate 		sctp->sctp_obchunks = 0;
5033448Sdh155122 		UPDATE_MIB(&sctps->sctps_mib,
5043448Sdh155122 		    sctpOutOrderChunks, sctp->sctp_odchunks);
50510751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_odchunks,
50610751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_odchunks);
5070Sstevel@tonic-gate 		sctp->sctp_odchunks = 0;
5083448Sdh155122 		UPDATE_MIB(&sctps->sctps_mib, sctpOutUnorderChunks,
5090Sstevel@tonic-gate 		    sctp->sctp_oudchunks);
51010751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_oudchunks,
51110751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_oudchunks);
5120Sstevel@tonic-gate 		sctp->sctp_oudchunks = 0;
5133448Sdh155122 		UPDATE_MIB(&sctps->sctps_mib,
5143448Sdh155122 		    sctpRetransChunks, sctp->sctp_rxtchunks);
51510751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_rxtchunks,
51610751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_rxtchunks);
5170Sstevel@tonic-gate 		sctp->sctp_rxtchunks = 0;
5183448Sdh155122 		UPDATE_MIB(&sctps->sctps_mib,
5193448Sdh155122 		    sctpInSCTPPkts, sctp->sctp_ipkts);
5200Sstevel@tonic-gate 		sctp->sctp_ipkts = 0;
5213448Sdh155122 		UPDATE_MIB(&sctps->sctps_mib,
5223448Sdh155122 		    sctpInCtrlChunks, sctp->sctp_ibchunks);
52310751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_ibchunks,
52410751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_ibchunks);
5250Sstevel@tonic-gate 		sctp->sctp_ibchunks = 0;
5263448Sdh155122 		UPDATE_MIB(&sctps->sctps_mib,
5273448Sdh155122 		    sctpInOrderChunks, sctp->sctp_idchunks);
52810751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_idchunks,
52910751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_idchunks);
5300Sstevel@tonic-gate 		sctp->sctp_idchunks = 0;
5313448Sdh155122 		UPDATE_MIB(&sctps->sctps_mib, sctpInUnorderChunks,
5320Sstevel@tonic-gate 		    sctp->sctp_iudchunks);
53310751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_iudchunks,
53410751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_iudchunks);
5350Sstevel@tonic-gate 		sctp->sctp_iudchunks = 0;
5363448Sdh155122 		UPDATE_MIB(&sctps->sctps_mib,
5373448Sdh155122 		    sctpFragUsrMsgs, sctp->sctp_fragdmsgs);
5380Sstevel@tonic-gate 		sctp->sctp_fragdmsgs = 0;
5393448Sdh155122 		UPDATE_MIB(&sctps->sctps_mib,
5403448Sdh155122 		    sctpReasmUsrMsgs, sctp->sctp_reassmsgs);
5410Sstevel@tonic-gate 		sctp->sctp_reassmsgs = 0;
5420Sstevel@tonic-gate 
5430Sstevel@tonic-gate 		sce.sctpAssocId = ntohl(sctp->sctp_lvtag);
544*11042SErik.Nordmark@Sun.COM 		sce.sctpAssocLocalPort = ntohs(sctp->sctp_connp->conn_lport);
545*11042SErik.Nordmark@Sun.COM 		sce.sctpAssocRemPort = ntohs(sctp->sctp_connp->conn_fport);
5460Sstevel@tonic-gate 
5470Sstevel@tonic-gate 		RUN_SCTP(sctp);
5480Sstevel@tonic-gate 		if (sctp->sctp_primary != NULL) {
5490Sstevel@tonic-gate 			fp = sctp->sctp_primary;
5500Sstevel@tonic-gate 
5510Sstevel@tonic-gate 			if (IN6_IS_ADDR_V4MAPPED(&fp->faddr)) {
5520Sstevel@tonic-gate 				sce.sctpAssocRemPrimAddrType =
5530Sstevel@tonic-gate 				    MIB2_SCTP_ADDR_V4;
5540Sstevel@tonic-gate 			} else {
5550Sstevel@tonic-gate 				sce.sctpAssocRemPrimAddrType =
5560Sstevel@tonic-gate 				    MIB2_SCTP_ADDR_V6;
5570Sstevel@tonic-gate 			}
5580Sstevel@tonic-gate 			sce.sctpAssocRemPrimAddr = fp->faddr;
5590Sstevel@tonic-gate 			sce.sctpAssocLocPrimAddr = fp->saddr;
5600Sstevel@tonic-gate 			sce.sctpAssocHeartBeatInterval = TICK_TO_MSEC(
5610Sstevel@tonic-gate 			    fp->hb_interval);
5620Sstevel@tonic-gate 		} else {
5630Sstevel@tonic-gate 			sce.sctpAssocRemPrimAddrType = MIB2_SCTP_ADDR_V4;
5640Sstevel@tonic-gate 			bzero(&sce.sctpAssocRemPrimAddr,
5650Sstevel@tonic-gate 			    sizeof (sce.sctpAssocRemPrimAddr));
5660Sstevel@tonic-gate 			bzero(&sce.sctpAssocLocPrimAddr,
5670Sstevel@tonic-gate 			    sizeof (sce.sctpAssocLocPrimAddr));
5680Sstevel@tonic-gate 			sce.sctpAssocHeartBeatInterval =
5693448Sdh155122 			    sctps->sctps_heartbeat_interval;
5700Sstevel@tonic-gate 		}
5710Sstevel@tonic-gate 
5720Sstevel@tonic-gate 		/*
5730Sstevel@tonic-gate 		 * Table for local addresses
5740Sstevel@tonic-gate 		 */
5750Sstevel@tonic-gate 		scanned = 0;
5760Sstevel@tonic-gate 		for (i = 0; i < SCTP_IPIF_HASH; i++) {
5770Sstevel@tonic-gate 			sctp_saddr_ipif_t	*obj;
5780Sstevel@tonic-gate 
5790Sstevel@tonic-gate 			if (sctp->sctp_saddrs[i].ipif_count == 0)
5800Sstevel@tonic-gate 				continue;
5810Sstevel@tonic-gate 			obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
5820Sstevel@tonic-gate 			for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
5830Sstevel@tonic-gate 				sctp_ipif_t	*sctp_ipif;
5840Sstevel@tonic-gate 				in6_addr_t	addr;
5850Sstevel@tonic-gate 
5860Sstevel@tonic-gate 				sctp_ipif = obj->saddr_ipifp;
5870Sstevel@tonic-gate 				addr = sctp_ipif->sctp_ipif_saddr;
5880Sstevel@tonic-gate 				scanned++;
5890Sstevel@tonic-gate 				scle.sctpAssocId = ntohl(sctp->sctp_lvtag);
5900Sstevel@tonic-gate 				if (IN6_IS_ADDR_V4MAPPED(&addr)) {
5910Sstevel@tonic-gate 					scle.sctpAssocLocalAddrType =
5920Sstevel@tonic-gate 					    MIB2_SCTP_ADDR_V4;
5930Sstevel@tonic-gate 				} else {
5940Sstevel@tonic-gate 					scle.sctpAssocLocalAddrType =
5950Sstevel@tonic-gate 					    MIB2_SCTP_ADDR_V6;
5960Sstevel@tonic-gate 				}
5970Sstevel@tonic-gate 				scle.sctpAssocLocalAddr = addr;
5980Sstevel@tonic-gate 				(void) snmp_append_data2(mp_local_data,
5990Sstevel@tonic-gate 				    &mp_local_tail, (char *)&scle,
6000Sstevel@tonic-gate 				    sizeof (scle));
6010Sstevel@tonic-gate 				if (scanned >= sctp->sctp_nsaddrs)
6020Sstevel@tonic-gate 					goto done;
6030Sstevel@tonic-gate 				obj = list_next(&sctp->
6040Sstevel@tonic-gate 				    sctp_saddrs[i].sctp_ipif_list, obj);
6050Sstevel@tonic-gate 			}
6060Sstevel@tonic-gate 		}
6070Sstevel@tonic-gate done:
6080Sstevel@tonic-gate 		/*
6090Sstevel@tonic-gate 		 * Table for remote addresses
6100Sstevel@tonic-gate 		 */
6110Sstevel@tonic-gate 		for (fp = sctp->sctp_faddrs; fp; fp = fp->next) {
6120Sstevel@tonic-gate 			scre.sctpAssocId = ntohl(sctp->sctp_lvtag);
6130Sstevel@tonic-gate 			if (IN6_IS_ADDR_V4MAPPED(&fp->faddr)) {
6140Sstevel@tonic-gate 				scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V4;
6150Sstevel@tonic-gate 			} else {
6160Sstevel@tonic-gate 				scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V6;
6170Sstevel@tonic-gate 			}
6180Sstevel@tonic-gate 			scre.sctpAssocRemAddr = fp->faddr;
6190Sstevel@tonic-gate 			if (fp->state == SCTP_FADDRS_ALIVE) {
6200Sstevel@tonic-gate 				scre.sctpAssocRemAddrActive =
6210Sstevel@tonic-gate 				    scre.sctpAssocRemAddrHBActive =
6220Sstevel@tonic-gate 				    MIB2_SCTP_ACTIVE;
6230Sstevel@tonic-gate 			} else {
6240Sstevel@tonic-gate 				scre.sctpAssocRemAddrActive =
6250Sstevel@tonic-gate 				    scre.sctpAssocRemAddrHBActive =
6260Sstevel@tonic-gate 				    MIB2_SCTP_INACTIVE;
6270Sstevel@tonic-gate 			}
6280Sstevel@tonic-gate 			scre.sctpAssocRemAddrRTO = TICK_TO_MSEC(fp->rto);
6290Sstevel@tonic-gate 			scre.sctpAssocRemAddrMaxPathRtx = fp->max_retr;
6300Sstevel@tonic-gate 			scre.sctpAssocRemAddrRtx = fp->T3expire;
6310Sstevel@tonic-gate 			(void) snmp_append_data2(mp_rem_data, &mp_rem_tail,
6320Sstevel@tonic-gate 			    (char *)&scre, sizeof (scre));
6330Sstevel@tonic-gate 		}
6341676Sjpk 		connp = sctp->sctp_connp;
6351676Sjpk 		needattr = B_FALSE;
6361676Sjpk 		bzero(&mlp, sizeof (mlp));
6371676Sjpk 		if (connp->conn_mlp_type != mlptSingle) {
6381676Sjpk 			if (connp->conn_mlp_type == mlptShared ||
6391676Sjpk 			    connp->conn_mlp_type == mlptBoth)
6401676Sjpk 				mlp.tme_flags |= MIB2_TMEF_SHARED;
6411676Sjpk 			if (connp->conn_mlp_type == mlptPrivate ||
6421676Sjpk 			    connp->conn_mlp_type == mlptBoth)
6431676Sjpk 				mlp.tme_flags |= MIB2_TMEF_PRIVATE;
6441676Sjpk 			needattr = B_TRUE;
6451676Sjpk 		}
6469710SKen.Powell@Sun.COM 		if (connp->conn_anon_mlp) {
6479710SKen.Powell@Sun.COM 			mlp.tme_flags |= MIB2_TMEF_ANONMLP;
6489710SKen.Powell@Sun.COM 			needattr = B_TRUE;
6499710SKen.Powell@Sun.COM 		}
65010934Ssommerfeld@sun.com 		switch (connp->conn_mac_mode) {
65110934Ssommerfeld@sun.com 		case CONN_MAC_DEFAULT:
65210934Ssommerfeld@sun.com 			break;
65310934Ssommerfeld@sun.com 		case CONN_MAC_AWARE:
6549710SKen.Powell@Sun.COM 			mlp.tme_flags |= MIB2_TMEF_MACEXEMPT;
6559710SKen.Powell@Sun.COM 			needattr = B_TRUE;
65610934Ssommerfeld@sun.com 			break;
65710934Ssommerfeld@sun.com 		case CONN_MAC_IMPLICIT:
65810934Ssommerfeld@sun.com 			mlp.tme_flags |= MIB2_TMEF_MACIMPLICIT;
65910934Ssommerfeld@sun.com 			needattr = B_TRUE;
66010934Ssommerfeld@sun.com 			break;
6619710SKen.Powell@Sun.COM 		}
662*11042SErik.Nordmark@Sun.COM 		if (sctp->sctp_connp->conn_ixa->ixa_tsl != NULL) {
6631676Sjpk 			ts_label_t *tsl;
6641676Sjpk 
665*11042SErik.Nordmark@Sun.COM 			tsl = sctp->sctp_connp->conn_ixa->ixa_tsl;
6669710SKen.Powell@Sun.COM 			mlp.tme_flags |= MIB2_TMEF_IS_LABELED;
6671676Sjpk 			mlp.tme_doi = label2doi(tsl);
6681676Sjpk 			mlp.tme_label = *label2bslabel(tsl);
6691676Sjpk 			needattr = B_TRUE;
6701676Sjpk 		}
6710Sstevel@tonic-gate 		WAKE_SCTP(sctp);
6720Sstevel@tonic-gate 		sce.sctpAssocState = sctp_snmp_state(sctp);
6730Sstevel@tonic-gate 		sce.sctpAssocInStreams = sctp->sctp_num_istr;
6740Sstevel@tonic-gate 		sce.sctpAssocOutStreams = sctp->sctp_num_ostr;
6750Sstevel@tonic-gate 		sce.sctpAssocMaxRetr = sctp->sctp_pa_max_rxt;
6760Sstevel@tonic-gate 		/* A 0 here indicates that no primary process is known */
6770Sstevel@tonic-gate 		sce.sctpAssocPrimProcess = 0;
6780Sstevel@tonic-gate 		sce.sctpAssocT1expired = sctp->sctp_T1expire;
6790Sstevel@tonic-gate 		sce.sctpAssocT2expired = sctp->sctp_T2expire;
6800Sstevel@tonic-gate 		sce.sctpAssocRtxChunks = sctp->sctp_T3expire;
6810Sstevel@tonic-gate 		sce.sctpAssocStartTime = sctp->sctp_assoc_start_time;
6820Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_sendq = sctp->sctp_unacked +
6830Sstevel@tonic-gate 		    sctp->sctp_unsent;
6840Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_recvq = sctp->sctp_rxqueued;
6850Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_swnd = sctp->sctp_frwnd;
6860Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_rwnd = sctp->sctp_rwnd;
6870Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_mss = sctp->sctp_mss;
6880Sstevel@tonic-gate 		(void) snmp_append_data2(mp_conn_data, &mp_conn_tail,
6890Sstevel@tonic-gate 		    (char *)&sce, sizeof (sce));
6901676Sjpk 		mlp.tme_connidx = idx++;
6911676Sjpk 		if (needattr)
6921676Sjpk 			(void) snmp_append_data2(mp_attr_ctl->b_cont,
6931676Sjpk 			    &mp_attr_tail, (char *)&mlp, sizeof (mlp));
6940Sstevel@tonic-gate next_sctp:
6950Sstevel@tonic-gate 		sctp_prev = sctp;
6963448Sdh155122 		mutex_enter(&sctps->sctps_g_lock);
6973448Sdh155122 		sctp = list_next(&sctps->sctps_g_list, sctp);
6980Sstevel@tonic-gate 	}
6993448Sdh155122 	mutex_exit(&sctps->sctps_g_lock);
7000Sstevel@tonic-gate 	if (sctp_prev != NULL)
7010Sstevel@tonic-gate 		SCTP_REFRELE(sctp_prev);
7020Sstevel@tonic-gate 
7030Sstevel@tonic-gate 	/* fixed length structure for IPv4 and IPv6 counters */
7043448Sdh155122 	SET_MIB(sctps->sctps_mib.sctpEntrySize, sizeof (sce));
7053448Sdh155122 	SET_MIB(sctps->sctps_mib.sctpLocalEntrySize, sizeof (scle));
7063448Sdh155122 	SET_MIB(sctps->sctps_mib.sctpRemoteEntrySize, sizeof (scre));
7070Sstevel@tonic-gate 	optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
7080Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
7090Sstevel@tonic-gate 	optp->name = 0;
7103448Sdh155122 	(void) snmp_append_data(mpdata, (char *)&sctps->sctps_mib,
7113448Sdh155122 	    sizeof (sctps->sctps_mib));
7120Sstevel@tonic-gate 	optp->len = msgdsize(mpdata);
7130Sstevel@tonic-gate 	qreply(q, mpctl);
7140Sstevel@tonic-gate 
7150Sstevel@tonic-gate 	/* table of connections... */
7160Sstevel@tonic-gate 	optp = (struct opthdr *)&mp_conn_ctl->b_rptr[
7170Sstevel@tonic-gate 	    sizeof (struct T_optmgmt_ack)];
7180Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
7190Sstevel@tonic-gate 	optp->name = MIB2_SCTP_CONN;
7200Sstevel@tonic-gate 	optp->len = msgdsize(mp_conn_data);
7210Sstevel@tonic-gate 	qreply(q, mp_conn_ctl);
7220Sstevel@tonic-gate 
7230Sstevel@tonic-gate 	/* assoc local address table */
7240Sstevel@tonic-gate 	optp = (struct opthdr *)&mp_local_ctl->b_rptr[
7250Sstevel@tonic-gate 	    sizeof (struct T_optmgmt_ack)];
7260Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
7270Sstevel@tonic-gate 	optp->name = MIB2_SCTP_CONN_LOCAL;
7280Sstevel@tonic-gate 	optp->len = msgdsize(mp_local_data);
7290Sstevel@tonic-gate 	qreply(q, mp_local_ctl);
7300Sstevel@tonic-gate 
7310Sstevel@tonic-gate 	/* assoc remote address table */
7320Sstevel@tonic-gate 	optp = (struct opthdr *)&mp_rem_ctl->b_rptr[
7330Sstevel@tonic-gate 	    sizeof (struct T_optmgmt_ack)];
7340Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
7350Sstevel@tonic-gate 	optp->name = MIB2_SCTP_CONN_REMOTE;
7360Sstevel@tonic-gate 	optp->len = msgdsize(mp_rem_data);
7370Sstevel@tonic-gate 	qreply(q, mp_rem_ctl);
7380Sstevel@tonic-gate 
7391676Sjpk 	/* table of MLP attributes */
7401676Sjpk 	optp = (struct opthdr *)&mp_attr_ctl->b_rptr[
7411676Sjpk 	    sizeof (struct T_optmgmt_ack)];
7421676Sjpk 	optp->level = MIB2_SCTP;
7431676Sjpk 	optp->name = EXPER_XPORT_MLP;
7441676Sjpk 	optp->len = msgdsize(mp_attr_data);
7451676Sjpk 	if (optp->len == 0)
7461676Sjpk 		freemsg(mp_attr_ctl);
7471676Sjpk 	else
7481676Sjpk 		qreply(q, mp_attr_ctl);
7491676Sjpk 
7500Sstevel@tonic-gate 	return (mp_ret);
7510Sstevel@tonic-gate }
7520Sstevel@tonic-gate 
7530Sstevel@tonic-gate /* Translate SCTP state to MIB2 SCTP state. */
7540Sstevel@tonic-gate static int
7550Sstevel@tonic-gate sctp_snmp_state(sctp_t *sctp)
7560Sstevel@tonic-gate {
7570Sstevel@tonic-gate 	if (sctp == NULL)
7580Sstevel@tonic-gate 		return (0);
7590Sstevel@tonic-gate 
7600Sstevel@tonic-gate 	switch (sctp->sctp_state) {
7610Sstevel@tonic-gate 	case SCTPS_IDLE:
7620Sstevel@tonic-gate 	case SCTPS_BOUND:
7630Sstevel@tonic-gate 		return (MIB2_SCTP_closed);
7640Sstevel@tonic-gate 	case SCTPS_LISTEN:
7650Sstevel@tonic-gate 		return (MIB2_SCTP_listen);
7660Sstevel@tonic-gate 	case SCTPS_COOKIE_WAIT:
7670Sstevel@tonic-gate 		return (MIB2_SCTP_cookieWait);
7680Sstevel@tonic-gate 	case SCTPS_COOKIE_ECHOED:
7690Sstevel@tonic-gate 		return (MIB2_SCTP_cookieEchoed);
7700Sstevel@tonic-gate 	case SCTPS_ESTABLISHED:
7710Sstevel@tonic-gate 		return (MIB2_SCTP_established);
7720Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_PENDING:
7730Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownPending);
7740Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_SENT:
7750Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownSent);
7760Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_RECEIVED:
7770Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownReceived);
7780Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_ACK_SENT:
7790Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownAckSent);
7800Sstevel@tonic-gate 	default:
7810Sstevel@tonic-gate 		return (0);
7820Sstevel@tonic-gate 	}
7830Sstevel@tonic-gate }
784