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 /*
235dd46ab5SKacheong Poon  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
26*10ef8623SJohn Levon /*
27*10ef8623SJohn Levon  * Copyright (c) 2018, Joyent, Inc.
28*10ef8623SJohn Levon  */
29*10ef8623SJohn Levon 
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/stream.h>
327c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
337c478bd9Sstevel@tonic-gate #define	_SUN_TPI_VERSION 2
347c478bd9Sstevel@tonic-gate #include <sys/tihdr.h>
357c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
367c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
3745916cd2Sjpk #include <sys/tsol/tndb.h>
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #include <netinet/in.h>
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #include <inet/common.h>
427c478bd9Sstevel@tonic-gate #include <inet/ip.h>
437c478bd9Sstevel@tonic-gate #include <inet/mib2.h>
447c478bd9Sstevel@tonic-gate #include <inet/snmpcom.h>
457c478bd9Sstevel@tonic-gate #include <inet/kstatcom.h>
467c478bd9Sstevel@tonic-gate #include <inet/ipclassifier.h>
477c478bd9Sstevel@tonic-gate #include "sctp_impl.h"
487c478bd9Sstevel@tonic-gate #include "sctp_addr.h"
497c478bd9Sstevel@tonic-gate 
505dd46ab5SKacheong Poon static void sctp_clr_kstats2(sctp_kstat_t *);
515dd46ab5SKacheong Poon static void sctp_add_kstats2(sctp_kstat_counter_t *, sctp_kstat_t *);
525dd46ab5SKacheong Poon static int sctp_snmp_state(sctp_t *);
535dd46ab5SKacheong Poon static void sctp_sum_mib(sctp_stack_t *, mib2_sctp_t *);
545dd46ab5SKacheong Poon static void sctp_add_mib(mib2_sctp_t *, mib2_sctp_t *);
5577c67f2fSkcpoon 
567c478bd9Sstevel@tonic-gate static int
577c478bd9Sstevel@tonic-gate sctp_kstat_update(kstat_t *kp, int rw)
587c478bd9Sstevel@tonic-gate {
597c478bd9Sstevel@tonic-gate 	sctp_named_kstat_t	*sctpkp;
607c478bd9Sstevel@tonic-gate 	sctp_t			*sctp, *sctp_prev;
61f4b3ec61Sdh 	zoneid_t	myzoneid;
62f4b3ec61Sdh 	netstackid_t	stackid = (netstackid_t)(uintptr_t)kp->ks_private;
63f4b3ec61Sdh 	netstack_t	*ns;
64f4b3ec61Sdh 	sctp_stack_t	*sctps;
655dd46ab5SKacheong Poon 	mib2_sctp_t	sctp_mib;
667c478bd9Sstevel@tonic-gate 
67*10ef8623SJohn Levon 	if (kp->ks_data == NULL)
687c478bd9Sstevel@tonic-gate 		return (EIO);
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate 	if (rw == KSTAT_WRITE)
717c478bd9Sstevel@tonic-gate 		return (EACCES);
727c478bd9Sstevel@tonic-gate 
73f4b3ec61Sdh 	ns = netstack_find_by_stackid(stackid);
74f4b3ec61Sdh 	if (ns == NULL)
75f4b3ec61Sdh 		return (-1);
76f4b3ec61Sdh 	sctps = ns->netstack_sctp;
77f4b3ec61Sdh 	if (sctps == NULL) {
78f4b3ec61Sdh 		netstack_rele(ns);
79f4b3ec61Sdh 		return (-1);
80f4b3ec61Sdh 	}
815dd46ab5SKacheong Poon 
825dd46ab5SKacheong Poon 	/*
835dd46ab5SKacheong Poon 	 * For all exclusive netstacks, the zone ID is always GLOBAL_ZONEID.
845dd46ab5SKacheong Poon 	 */
855dd46ab5SKacheong Poon 	if (stackid != GLOBAL_NETSTACKID)
865dd46ab5SKacheong Poon 		myzoneid = GLOBAL_ZONEID;
875dd46ab5SKacheong Poon 	else
885dd46ab5SKacheong Poon 		myzoneid = curproc->p_zone->zone_id;
895dd46ab5SKacheong Poon 
905dd46ab5SKacheong Poon 	bzero(&sctp_mib, sizeof (sctp_mib));
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	/*
937c478bd9Sstevel@tonic-gate 	 * Get the number of current associations and gather their
947c478bd9Sstevel@tonic-gate 	 * individual set of statistics.
957c478bd9Sstevel@tonic-gate 	 */
967c478bd9Sstevel@tonic-gate 	sctp_prev = NULL;
97f4b3ec61Sdh 	mutex_enter(&sctps->sctps_g_lock);
98bd670b35SErik Nordmark 	sctp = list_head(&sctps->sctps_g_list);
997c478bd9Sstevel@tonic-gate 	while (sctp != NULL) {
1007c478bd9Sstevel@tonic-gate 		mutex_enter(&sctp->sctp_reflock);
1017c478bd9Sstevel@tonic-gate 		if (sctp->sctp_condemned) {
1027c478bd9Sstevel@tonic-gate 			mutex_exit(&sctp->sctp_reflock);
103f4b3ec61Sdh 			sctp = list_next(&sctps->sctps_g_list, sctp);
1047c478bd9Sstevel@tonic-gate 			continue;
1057c478bd9Sstevel@tonic-gate 		}
1067c478bd9Sstevel@tonic-gate 		sctp->sctp_refcnt++;
1077c478bd9Sstevel@tonic-gate 		mutex_exit(&sctp->sctp_reflock);
108f4b3ec61Sdh 		mutex_exit(&sctps->sctps_g_lock);
1097c478bd9Sstevel@tonic-gate 		if (sctp_prev != NULL)
1107c478bd9Sstevel@tonic-gate 			SCTP_REFRELE(sctp_prev);
111f4b3ec61Sdh 		if (sctp->sctp_connp->conn_zoneid != myzoneid)
1127c478bd9Sstevel@tonic-gate 			goto next_sctp;
1137c478bd9Sstevel@tonic-gate 		if (sctp->sctp_state == SCTPS_ESTABLISHED ||
1147c478bd9Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_PENDING ||
1157c478bd9Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) {
1165dd46ab5SKacheong Poon 			/*
1175dd46ab5SKacheong Poon 			 * Just bump the local sctp_mib.  The number of
1185dd46ab5SKacheong Poon 			 * existing associations is not kept in kernel.
1195dd46ab5SKacheong Poon 			 */
1205dd46ab5SKacheong Poon 			BUMP_MIB(&sctp_mib, sctpCurrEstab);
1217c478bd9Sstevel@tonic-gate 		}
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 		if (sctp->sctp_opkts) {
1245dd46ab5SKacheong Poon 			SCTPS_UPDATE_MIB(sctps, sctpOutSCTPPkts,
1257c478bd9Sstevel@tonic-gate 			    sctp->sctp_opkts);
1267c478bd9Sstevel@tonic-gate 			sctp->sctp_opkts = 0;
1277c478bd9Sstevel@tonic-gate 		}
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 		if (sctp->sctp_obchunks) {
1305dd46ab5SKacheong Poon 			SCTPS_UPDATE_MIB(sctps, sctpOutCtrlChunks,
1317c478bd9Sstevel@tonic-gate 			    sctp->sctp_obchunks);
13235e12f9cSGeorge Shepherd 			UPDATE_LOCAL(sctp->sctp_cum_obchunks,
13335e12f9cSGeorge Shepherd 			    sctp->sctp_obchunks);
1347c478bd9Sstevel@tonic-gate 			sctp->sctp_obchunks = 0;
1357c478bd9Sstevel@tonic-gate 		}
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 		if (sctp->sctp_odchunks) {
1385dd46ab5SKacheong Poon 			SCTPS_UPDATE_MIB(sctps, sctpOutOrderChunks,
1397c478bd9Sstevel@tonic-gate 			    sctp->sctp_odchunks);
14035e12f9cSGeorge Shepherd 			UPDATE_LOCAL(sctp->sctp_cum_odchunks,
14135e12f9cSGeorge Shepherd 			    sctp->sctp_odchunks);
1427c478bd9Sstevel@tonic-gate 			sctp->sctp_odchunks = 0;
1437c478bd9Sstevel@tonic-gate 		}
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 		if (sctp->sctp_oudchunks) {
1465dd46ab5SKacheong Poon 			SCTPS_UPDATE_MIB(sctps, sctpOutUnorderChunks,
1477c478bd9Sstevel@tonic-gate 			    sctp->sctp_oudchunks);
14835e12f9cSGeorge Shepherd 			UPDATE_LOCAL(sctp->sctp_cum_oudchunks,
14935e12f9cSGeorge Shepherd 			    sctp->sctp_oudchunks);
1507c478bd9Sstevel@tonic-gate 			sctp->sctp_oudchunks = 0;
1517c478bd9Sstevel@tonic-gate 		}
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 		if (sctp->sctp_rxtchunks) {
1545dd46ab5SKacheong Poon 			SCTPS_UPDATE_MIB(sctps, sctpRetransChunks,
1557c478bd9Sstevel@tonic-gate 			    sctp->sctp_rxtchunks);
15635e12f9cSGeorge Shepherd 			UPDATE_LOCAL(sctp->sctp_cum_rxtchunks,
15735e12f9cSGeorge Shepherd 			    sctp->sctp_rxtchunks);
1587c478bd9Sstevel@tonic-gate 			sctp->sctp_rxtchunks = 0;
1597c478bd9Sstevel@tonic-gate 		}
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate 		if (sctp->sctp_ipkts) {
1625dd46ab5SKacheong Poon 			SCTPS_UPDATE_MIB(sctps, sctpInSCTPPkts,
163f4b3ec61Sdh 			    sctp->sctp_ipkts);
1647c478bd9Sstevel@tonic-gate 			sctp->sctp_ipkts = 0;
1657c478bd9Sstevel@tonic-gate 		}
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 		if (sctp->sctp_ibchunks) {
1685dd46ab5SKacheong Poon 			SCTPS_UPDATE_MIB(sctps, sctpInCtrlChunks,
1697c478bd9Sstevel@tonic-gate 			    sctp->sctp_ibchunks);
17035e12f9cSGeorge Shepherd 			UPDATE_LOCAL(sctp->sctp_cum_ibchunks,
17135e12f9cSGeorge Shepherd 			    sctp->sctp_ibchunks);
1727c478bd9Sstevel@tonic-gate 			sctp->sctp_ibchunks = 0;
1737c478bd9Sstevel@tonic-gate 		}
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate 		if (sctp->sctp_idchunks) {
1765dd46ab5SKacheong Poon 			SCTPS_UPDATE_MIB(sctps, sctpInOrderChunks,
1777c478bd9Sstevel@tonic-gate 			    sctp->sctp_idchunks);
17835e12f9cSGeorge Shepherd 			UPDATE_LOCAL(sctp->sctp_cum_idchunks,
17935e12f9cSGeorge Shepherd 			    sctp->sctp_idchunks);
1807c478bd9Sstevel@tonic-gate 			sctp->sctp_idchunks = 0;
1817c478bd9Sstevel@tonic-gate 		}
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 		if (sctp->sctp_iudchunks) {
1845dd46ab5SKacheong Poon 			SCTPS_UPDATE_MIB(sctps, sctpInUnorderChunks,
1857c478bd9Sstevel@tonic-gate 			    sctp->sctp_iudchunks);
18635e12f9cSGeorge Shepherd 			UPDATE_LOCAL(sctp->sctp_cum_iudchunks,
18735e12f9cSGeorge Shepherd 			    sctp->sctp_iudchunks);
1887c478bd9Sstevel@tonic-gate 			sctp->sctp_iudchunks = 0;
1897c478bd9Sstevel@tonic-gate 		}
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate 		if (sctp->sctp_fragdmsgs) {
1925dd46ab5SKacheong Poon 			SCTPS_UPDATE_MIB(sctps, sctpFragUsrMsgs,
1937c478bd9Sstevel@tonic-gate 			    sctp->sctp_fragdmsgs);
1947c478bd9Sstevel@tonic-gate 			sctp->sctp_fragdmsgs = 0;
1957c478bd9Sstevel@tonic-gate 		}
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 		if (sctp->sctp_reassmsgs) {
1985dd46ab5SKacheong Poon 			SCTPS_UPDATE_MIB(sctps, sctpReasmUsrMsgs,
1997c478bd9Sstevel@tonic-gate 			    sctp->sctp_reassmsgs);
2007c478bd9Sstevel@tonic-gate 			sctp->sctp_reassmsgs = 0;
2017c478bd9Sstevel@tonic-gate 		}
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate next_sctp:
2047c478bd9Sstevel@tonic-gate 		sctp_prev = sctp;
205f4b3ec61Sdh 		mutex_enter(&sctps->sctps_g_lock);
206f4b3ec61Sdh 		sctp = list_next(&sctps->sctps_g_list, sctp);
2077c478bd9Sstevel@tonic-gate 	}
208f4b3ec61Sdh 	mutex_exit(&sctps->sctps_g_lock);
2097c478bd9Sstevel@tonic-gate 	if (sctp_prev != NULL)
2107c478bd9Sstevel@tonic-gate 		SCTP_REFRELE(sctp_prev);
2117c478bd9Sstevel@tonic-gate 
2125dd46ab5SKacheong Poon 	sctp_sum_mib(sctps, &sctp_mib);
2135dd46ab5SKacheong Poon 
2147c478bd9Sstevel@tonic-gate 	/* Copy data from the SCTP MIB */
2157c478bd9Sstevel@tonic-gate 	sctpkp = (sctp_named_kstat_t *)kp->ks_data;
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 	/* These are from global ndd params. */
218f4b3ec61Sdh 	sctpkp->sctpRtoMin.value.ui32 = sctps->sctps_rto_ming;
219f4b3ec61Sdh 	sctpkp->sctpRtoMax.value.ui32 = sctps->sctps_rto_maxg;
220f4b3ec61Sdh 	sctpkp->sctpRtoInitial.value.ui32 = sctps->sctps_rto_initialg;
221f4b3ec61Sdh 	sctpkp->sctpValCookieLife.value.ui32 = sctps->sctps_cookie_life;
222f4b3ec61Sdh 	sctpkp->sctpMaxInitRetr.value.ui32 = sctps->sctps_max_init_retr;
223f4b3ec61Sdh 
2245dd46ab5SKacheong Poon 	/* Copy data from the local sctp_mib to the provided kstat. */
2255dd46ab5SKacheong Poon 	sctpkp->sctpCurrEstab.value.i32 = sctp_mib.sctpCurrEstab;
2265dd46ab5SKacheong Poon 	sctpkp->sctpActiveEstab.value.i32 = sctp_mib.sctpActiveEstab;
2275dd46ab5SKacheong Poon 	sctpkp->sctpPassiveEstab.value.i32 = sctp_mib.sctpPassiveEstab;
2285dd46ab5SKacheong Poon 	sctpkp->sctpAborted.value.i32 = sctp_mib.sctpAborted;
2295dd46ab5SKacheong Poon 	sctpkp->sctpShutdowns.value.i32 = sctp_mib.sctpShutdowns;
2305dd46ab5SKacheong Poon 	sctpkp->sctpOutOfBlue.value.i32 = sctp_mib.sctpOutOfBlue;
2315dd46ab5SKacheong Poon 	sctpkp->sctpChecksumError.value.i32 = sctp_mib.sctpChecksumError;
2325dd46ab5SKacheong Poon 	sctpkp->sctpOutCtrlChunks.value.i64 = sctp_mib.sctpOutCtrlChunks;
2335dd46ab5SKacheong Poon 	sctpkp->sctpOutOrderChunks.value.i64 = sctp_mib.sctpOutOrderChunks;
2345dd46ab5SKacheong Poon 	sctpkp->sctpOutUnorderChunks.value.i64 = sctp_mib.sctpOutUnorderChunks;
2355dd46ab5SKacheong Poon 	sctpkp->sctpRetransChunks.value.i64 = sctp_mib.sctpRetransChunks;
2365dd46ab5SKacheong Poon 	sctpkp->sctpOutAck.value.i32 = sctp_mib.sctpOutAck;
2375dd46ab5SKacheong Poon 	sctpkp->sctpOutAckDelayed.value.i32 = sctp_mib.sctpOutAckDelayed;
2385dd46ab5SKacheong Poon 	sctpkp->sctpOutWinUpdate.value.i32 = sctp_mib.sctpOutWinUpdate;
2395dd46ab5SKacheong Poon 	sctpkp->sctpOutFastRetrans.value.i32 = sctp_mib.sctpOutFastRetrans;
2405dd46ab5SKacheong Poon 	sctpkp->sctpOutWinProbe.value.i32 = sctp_mib.sctpOutWinProbe;
2415dd46ab5SKacheong Poon 	sctpkp->sctpInCtrlChunks.value.i64 = sctp_mib.sctpInCtrlChunks;
2425dd46ab5SKacheong Poon 	sctpkp->sctpInOrderChunks.value.i64 = sctp_mib.sctpInOrderChunks;
2435dd46ab5SKacheong Poon 	sctpkp->sctpInUnorderChunks.value.i64 = sctp_mib.sctpInUnorderChunks;
2445dd46ab5SKacheong Poon 	sctpkp->sctpInAck.value.i32 = sctp_mib.sctpInAck;
2455dd46ab5SKacheong Poon 	sctpkp->sctpInDupAck.value.i32 = sctp_mib.sctpInDupAck;
2465dd46ab5SKacheong Poon 	sctpkp->sctpInAckUnsent.value.i32 = sctp_mib.sctpInAckUnsent;
2475dd46ab5SKacheong Poon 	sctpkp->sctpFragUsrMsgs.value.i64 = sctp_mib.sctpFragUsrMsgs;
2485dd46ab5SKacheong Poon 	sctpkp->sctpReasmUsrMsgs.value.i64 = sctp_mib.sctpReasmUsrMsgs;
2495dd46ab5SKacheong Poon 	sctpkp->sctpOutSCTPPkts.value.i64 = sctp_mib.sctpOutSCTPPkts;
2505dd46ab5SKacheong Poon 	sctpkp->sctpInSCTPPkts.value.i64 = sctp_mib.sctpInSCTPPkts;
2515dd46ab5SKacheong Poon 	sctpkp->sctpInInvalidCookie.value.i32 = sctp_mib.sctpInInvalidCookie;
2525dd46ab5SKacheong Poon 	sctpkp->sctpTimRetrans.value.i32 = sctp_mib.sctpTimRetrans;
2535dd46ab5SKacheong Poon 	sctpkp->sctpTimRetransDrop.value.i32 = sctp_mib.sctpTimRetransDrop;
2547c478bd9Sstevel@tonic-gate 	sctpkp->sctpTimHeartBeatProbe.value.i32 =
2555dd46ab5SKacheong Poon 	    sctp_mib.sctpTimHeartBeatProbe;
2565dd46ab5SKacheong Poon 	sctpkp->sctpTimHeartBeatDrop.value.i32 = sctp_mib.sctpTimHeartBeatDrop;
2575dd46ab5SKacheong Poon 	sctpkp->sctpListenDrop.value.i32 = sctp_mib.sctpListenDrop;
2585dd46ab5SKacheong Poon 	sctpkp->sctpInClosed.value.i32 = sctp_mib.sctpInClosed;
2597c478bd9Sstevel@tonic-gate 
260f4b3ec61Sdh 	netstack_rele(ns);
2617c478bd9Sstevel@tonic-gate 	return (0);
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate 
264f4b3ec61Sdh void *
265f4b3ec61Sdh sctp_kstat_init(netstackid_t stackid)
2667c478bd9Sstevel@tonic-gate {
267f4b3ec61Sdh 	kstat_t	*ksp;
268f4b3ec61Sdh 
2697c478bd9Sstevel@tonic-gate 	sctp_named_kstat_t template = {
2707c478bd9Sstevel@tonic-gate 		{ "sctpRtoAlgorithm",		KSTAT_DATA_INT32, 0 },
2717c478bd9Sstevel@tonic-gate 		{ "sctpRtoMin",			KSTAT_DATA_UINT32, 0 },
2727c478bd9Sstevel@tonic-gate 		{ "sctpRtoMax",			KSTAT_DATA_UINT32, 0 },
2737c478bd9Sstevel@tonic-gate 		{ "sctpRtoInitial",		KSTAT_DATA_UINT32, 0 },
2747c478bd9Sstevel@tonic-gate 		{ "sctpMaxAssocs",		KSTAT_DATA_INT32, 0 },
2757c478bd9Sstevel@tonic-gate 		{ "sctpValCookieLife",		KSTAT_DATA_UINT32, 0 },
2767c478bd9Sstevel@tonic-gate 		{ "sctpMaxInitRetr",		KSTAT_DATA_UINT32, 0 },
2777c478bd9Sstevel@tonic-gate 		{ "sctpCurrEstab",		KSTAT_DATA_INT32, 0 },
2787c478bd9Sstevel@tonic-gate 		{ "sctpActiveEstab",		KSTAT_DATA_INT32, 0 },
2797c478bd9Sstevel@tonic-gate 		{ "sctpPassiveEstab",		KSTAT_DATA_INT32, 0 },
2807c478bd9Sstevel@tonic-gate 		{ "sctpAborted",		KSTAT_DATA_INT32, 0 },
2817c478bd9Sstevel@tonic-gate 		{ "sctpShutdowns",		KSTAT_DATA_INT32, 0 },
2827c478bd9Sstevel@tonic-gate 		{ "sctpOutOfBlue",		KSTAT_DATA_INT32, 0 },
2837c478bd9Sstevel@tonic-gate 		{ "sctpChecksumError",		KSTAT_DATA_INT32, 0 },
2847c478bd9Sstevel@tonic-gate 		{ "sctpOutCtrlChunks",		KSTAT_DATA_INT64, 0 },
2857c478bd9Sstevel@tonic-gate 		{ "sctpOutOrderChunks",		KSTAT_DATA_INT64, 0 },
2867c478bd9Sstevel@tonic-gate 		{ "sctpOutUnorderChunks",	KSTAT_DATA_INT64, 0 },
2877c478bd9Sstevel@tonic-gate 		{ "sctpRetransChunks",		KSTAT_DATA_INT64, 0 },
2887c478bd9Sstevel@tonic-gate 		{ "sctpOutAck",			KSTAT_DATA_INT32, 0 },
2897c478bd9Sstevel@tonic-gate 		{ "sctpOutAckDelayed",		KSTAT_DATA_INT32, 0 },
2907c478bd9Sstevel@tonic-gate 		{ "sctpOutWinUpdate",		KSTAT_DATA_INT32, 0 },
2917c478bd9Sstevel@tonic-gate 		{ "sctpOutFastRetrans",		KSTAT_DATA_INT32, 0 },
2927c478bd9Sstevel@tonic-gate 		{ "sctpOutWinProbe",		KSTAT_DATA_INT32, 0 },
2937c478bd9Sstevel@tonic-gate 		{ "sctpInCtrlChunks",		KSTAT_DATA_INT64, 0 },
2947c478bd9Sstevel@tonic-gate 		{ "sctpInOrderChunks",		KSTAT_DATA_INT64, 0 },
2957c478bd9Sstevel@tonic-gate 		{ "sctpInUnorderChunks",	KSTAT_DATA_INT64, 0 },
2967c478bd9Sstevel@tonic-gate 		{ "sctpInAck",			KSTAT_DATA_INT32, 0 },
2977c478bd9Sstevel@tonic-gate 		{ "sctpInDupAck",		KSTAT_DATA_INT32, 0 },
2987c478bd9Sstevel@tonic-gate 		{ "sctpInAckUnsent",		KSTAT_DATA_INT32, 0 },
2997c478bd9Sstevel@tonic-gate 		{ "sctpFragUsrMsgs",		KSTAT_DATA_INT64, 0 },
3007c478bd9Sstevel@tonic-gate 		{ "sctpReasmUsrMsgs",		KSTAT_DATA_INT64, 0 },
3017c478bd9Sstevel@tonic-gate 		{ "sctpOutSCTPPkts",		KSTAT_DATA_INT64, 0 },
3027c478bd9Sstevel@tonic-gate 		{ "sctpInSCTPPkts",		KSTAT_DATA_INT64, 0 },
3037c478bd9Sstevel@tonic-gate 		{ "sctpInInvalidCookie",	KSTAT_DATA_INT32, 0 },
3047c478bd9Sstevel@tonic-gate 		{ "sctpTimRetrans",		KSTAT_DATA_INT32, 0 },
3057c478bd9Sstevel@tonic-gate 		{ "sctpTimRetransDrop",		KSTAT_DATA_INT32, 0 },
3067c478bd9Sstevel@tonic-gate 		{ "sctpTimHearBeatProbe",	KSTAT_DATA_INT32, 0 },
3077c478bd9Sstevel@tonic-gate 		{ "sctpTimHearBeatDrop",	KSTAT_DATA_INT32, 0 },
3087c478bd9Sstevel@tonic-gate 		{ "sctpListenDrop",		KSTAT_DATA_INT32, 0 },
3097c478bd9Sstevel@tonic-gate 		{ "sctpInClosed",		KSTAT_DATA_INT32, 0 }
3107c478bd9Sstevel@tonic-gate 	};
3117c478bd9Sstevel@tonic-gate 
312f4b3ec61Sdh 	ksp = kstat_create_netstack(SCTP_MOD_NAME, 0, "sctp", "mib2",
313f4b3ec61Sdh 	    KSTAT_TYPE_NAMED, NUM_OF_FIELDS(sctp_named_kstat_t), 0, stackid);
3147c478bd9Sstevel@tonic-gate 
3155dd46ab5SKacheong Poon 	if (ksp == NULL)
316f4b3ec61Sdh 		return (NULL);
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 	/* These won't change. */
3197c478bd9Sstevel@tonic-gate 	template.sctpRtoAlgorithm.value.i32 = MIB2_SCTP_RTOALGO_VANJ;
3207c478bd9Sstevel@tonic-gate 	template.sctpMaxAssocs.value.i32 = -1;
3217c478bd9Sstevel@tonic-gate 
322f4b3ec61Sdh 	bcopy(&template, ksp->ks_data, sizeof (template));
323f4b3ec61Sdh 	ksp->ks_update = sctp_kstat_update;
324f4b3ec61Sdh 	ksp->ks_private = (void *)(uintptr_t)stackid;
325f4b3ec61Sdh 
326f4b3ec61Sdh 	kstat_install(ksp);
327f4b3ec61Sdh 	return (ksp);
328f4b3ec61Sdh }
329f4b3ec61Sdh 
3305dd46ab5SKacheong Poon /*
3315dd46ab5SKacheong Poon  * To set all sctp_stat_t counters to 0.
3325dd46ab5SKacheong Poon  */
3335dd46ab5SKacheong Poon static void
3345dd46ab5SKacheong Poon sctp_clr_kstats2(sctp_kstat_t *stats)
3355dd46ab5SKacheong Poon {
3365dd46ab5SKacheong Poon 	stats->sctp_add_faddr.value.ui64 = 0;
3375dd46ab5SKacheong Poon 	stats->sctp_add_timer.value.ui64 = 0;
3385dd46ab5SKacheong Poon 	stats->sctp_conn_create.value.ui64 = 0;
3395dd46ab5SKacheong Poon 	stats->sctp_find_next_tq.value.ui64 = 0;
3405dd46ab5SKacheong Poon 	stats->sctp_fr_add_hdr.value.ui64 = 0;
3415dd46ab5SKacheong Poon 	stats->sctp_fr_not_found.value.ui64 = 0;
3425dd46ab5SKacheong Poon 	stats->sctp_output_failed.value.ui64 = 0;
3435dd46ab5SKacheong Poon 	stats->sctp_rexmit_failed.value.ui64 = 0;
3445dd46ab5SKacheong Poon 	stats->sctp_send_init_failed.value.ui64 = 0;
3455dd46ab5SKacheong Poon 	stats->sctp_send_cookie_failed.value.ui64 = 0;
3465dd46ab5SKacheong Poon 	stats->sctp_send_cookie_ack_failed.value.ui64 = 0;
3475dd46ab5SKacheong Poon 	stats->sctp_send_err_failed.value.ui64 = 0;
3485dd46ab5SKacheong Poon 	stats->sctp_send_sack_failed.value.ui64 = 0;
3495dd46ab5SKacheong Poon 	stats->sctp_send_shutdown_failed.value.ui64 = 0;
3505dd46ab5SKacheong Poon 	stats->sctp_send_shutdown_ack_failed.value.ui64 = 0;
3515dd46ab5SKacheong Poon 	stats->sctp_send_shutdown_comp_failed.value.ui64 = 0;
3525dd46ab5SKacheong Poon 	stats->sctp_send_user_abort_failed.value.ui64 = 0;
3535dd46ab5SKacheong Poon 	stats->sctp_send_asconf_failed.value.ui64 = 0;
3545dd46ab5SKacheong Poon 	stats->sctp_send_asconf_ack_failed.value.ui64 = 0;
3555dd46ab5SKacheong Poon 	stats->sctp_send_ftsn_failed.value.ui64 = 0;
3565dd46ab5SKacheong Poon 	stats->sctp_send_hb_failed.value.ui64 = 0;
3575dd46ab5SKacheong Poon 	stats->sctp_return_hb_failed.value.ui64 = 0;
3585dd46ab5SKacheong Poon 	stats->sctp_ss_rexmit_failed.value.ui64 = 0;
3595dd46ab5SKacheong Poon 	stats->sctp_cl_connect.value.ui64 = 0;
3605dd46ab5SKacheong Poon 	stats->sctp_cl_assoc_change.value.ui64 = 0;
3615dd46ab5SKacheong Poon 	stats->sctp_cl_check_addrs.value.ui64 = 0;
3625dd46ab5SKacheong Poon 	stats->sctp_reclaim_cnt.value.ui64 = 0;
3635dd46ab5SKacheong Poon 	stats->sctp_listen_cnt_drop.value.ui64 = 0;
3645dd46ab5SKacheong Poon }
3655dd46ab5SKacheong Poon 
3665dd46ab5SKacheong Poon /*
3675dd46ab5SKacheong Poon  * To add counters from the per CPU sctp_kstat_counter_t to the stack
3685dd46ab5SKacheong Poon  * sctp_kstat_t.
3695dd46ab5SKacheong Poon  */
3705dd46ab5SKacheong Poon static void
3715dd46ab5SKacheong Poon sctp_add_kstats2(sctp_kstat_counter_t *from, sctp_kstat_t *to)
3725dd46ab5SKacheong Poon {
3735dd46ab5SKacheong Poon 	to->sctp_add_faddr.value.ui64 += from->sctp_add_faddr;
3745dd46ab5SKacheong Poon 	to->sctp_add_timer.value.ui64 += from->sctp_add_timer;
3755dd46ab5SKacheong Poon 	to->sctp_conn_create.value.ui64 += from->sctp_conn_create;
3765dd46ab5SKacheong Poon 	to->sctp_find_next_tq.value.ui64 += from->sctp_find_next_tq;
3775dd46ab5SKacheong Poon 	to->sctp_fr_add_hdr.value.ui64 += from->sctp_fr_add_hdr;
3785dd46ab5SKacheong Poon 	to->sctp_fr_not_found.value.ui64 += from->sctp_fr_not_found;
3795dd46ab5SKacheong Poon 	to->sctp_output_failed.value.ui64 += from->sctp_output_failed;
3805dd46ab5SKacheong Poon 	to->sctp_rexmit_failed.value.ui64 += from->sctp_rexmit_failed;
3815dd46ab5SKacheong Poon 	to->sctp_send_init_failed.value.ui64 += from->sctp_send_init_failed;
3825dd46ab5SKacheong Poon 	to->sctp_send_cookie_failed.value.ui64 += from->sctp_send_cookie_failed;
3835dd46ab5SKacheong Poon 	to->sctp_send_cookie_ack_failed.value.ui64 +=
3845dd46ab5SKacheong Poon 	    from->sctp_send_cookie_ack_failed;
3855dd46ab5SKacheong Poon 	to->sctp_send_err_failed.value.ui64 += from->sctp_send_err_failed;
3865dd46ab5SKacheong Poon 	to->sctp_send_sack_failed.value.ui64 += from->sctp_send_sack_failed;
3875dd46ab5SKacheong Poon 	to->sctp_send_shutdown_failed.value.ui64 +=
3885dd46ab5SKacheong Poon 	    from->sctp_send_shutdown_failed;
3895dd46ab5SKacheong Poon 	to->sctp_send_shutdown_ack_failed.value.ui64 +=
3905dd46ab5SKacheong Poon 	    from->sctp_send_shutdown_ack_failed;
3915dd46ab5SKacheong Poon 	to->sctp_send_shutdown_comp_failed.value.ui64 +=
3925dd46ab5SKacheong Poon 	    from->sctp_send_shutdown_comp_failed;
3935dd46ab5SKacheong Poon 	to->sctp_send_user_abort_failed.value.ui64 +=
3945dd46ab5SKacheong Poon 	    from->sctp_send_user_abort_failed;
3955dd46ab5SKacheong Poon 	to->sctp_send_asconf_failed.value.ui64 += from->sctp_send_asconf_failed;
3965dd46ab5SKacheong Poon 	to->sctp_send_asconf_ack_failed.value.ui64 +=
3975dd46ab5SKacheong Poon 	    from->sctp_send_asconf_ack_failed;
3985dd46ab5SKacheong Poon 	to->sctp_send_ftsn_failed.value.ui64 += from->sctp_send_ftsn_failed;
3995dd46ab5SKacheong Poon 	to->sctp_send_hb_failed.value.ui64 += from->sctp_send_hb_failed;
4005dd46ab5SKacheong Poon 	to->sctp_return_hb_failed.value.ui64 += from->sctp_return_hb_failed;
4015dd46ab5SKacheong Poon 	to->sctp_ss_rexmit_failed.value.ui64 += from->sctp_ss_rexmit_failed;
4025dd46ab5SKacheong Poon 	to->sctp_cl_connect.value.ui64 += from->sctp_cl_connect;
4035dd46ab5SKacheong Poon 	to->sctp_cl_assoc_change.value.ui64 += from->sctp_cl_assoc_change;
4045dd46ab5SKacheong Poon 	to->sctp_cl_check_addrs.value.ui64 += from->sctp_cl_check_addrs;
4055dd46ab5SKacheong Poon }
4065dd46ab5SKacheong Poon 
4075dd46ab5SKacheong Poon /*
4085dd46ab5SKacheong Poon  * Sum up all per CPU tcp_stat_t kstat counters.
4095dd46ab5SKacheong Poon  */
4105dd46ab5SKacheong Poon static int
4115dd46ab5SKacheong Poon sctp_kstat2_update(kstat_t *kp, int rw)
4125dd46ab5SKacheong Poon {
4135dd46ab5SKacheong Poon 	netstackid_t	stackid = (netstackid_t)(uintptr_t)kp->ks_private;
4145dd46ab5SKacheong Poon 	netstack_t	*ns;
4155dd46ab5SKacheong Poon 	sctp_stack_t	*sctps;
4165dd46ab5SKacheong Poon 	sctp_kstat_t	*stats;
4175dd46ab5SKacheong Poon 	int		i;
4185dd46ab5SKacheong Poon 	int		cnt;
4195dd46ab5SKacheong Poon 
4205dd46ab5SKacheong Poon 	if (rw == KSTAT_WRITE)
4215dd46ab5SKacheong Poon 		return (EACCES);
4225dd46ab5SKacheong Poon 
4235dd46ab5SKacheong Poon 	ns = netstack_find_by_stackid(stackid);
4245dd46ab5SKacheong Poon 	if (ns == NULL)
4255dd46ab5SKacheong Poon 		return (-1);
4265dd46ab5SKacheong Poon 	sctps = ns->netstack_sctp;
4275dd46ab5SKacheong Poon 	if (sctps == NULL) {
4285dd46ab5SKacheong Poon 		netstack_rele(ns);
4295dd46ab5SKacheong Poon 		return (-1);
4305dd46ab5SKacheong Poon 	}
4315dd46ab5SKacheong Poon 
4325dd46ab5SKacheong Poon 	stats = (sctp_kstat_t *)kp->ks_data;
4335dd46ab5SKacheong Poon 	sctp_clr_kstats2(stats);
4345dd46ab5SKacheong Poon 
4355dd46ab5SKacheong Poon 	/*
4365dd46ab5SKacheong Poon 	 * sctps_sc_cnt may change in the middle of the loop.  It is better
4375dd46ab5SKacheong Poon 	 * to get its value first.
4385dd46ab5SKacheong Poon 	 */
4395dd46ab5SKacheong Poon 	cnt = sctps->sctps_sc_cnt;
4405dd46ab5SKacheong Poon 	for (i = 0; i < cnt; i++)
4415dd46ab5SKacheong Poon 		sctp_add_kstats2(&sctps->sctps_sc[i]->sctp_sc_stats, stats);
4425dd46ab5SKacheong Poon 
4435dd46ab5SKacheong Poon 	netstack_rele(ns);
4445dd46ab5SKacheong Poon 	return (0);
4455dd46ab5SKacheong Poon }
4465dd46ab5SKacheong Poon 
447f4b3ec61Sdh /*
448f4b3ec61Sdh  * The following kstats are for debugging purposes.  They keep
449f4b3ec61Sdh  * track of problems which should not happen normally.  But in
450f4b3ec61Sdh  * those cases which they do happen, these kstats would be handy
451f4b3ec61Sdh  * for engineers to diagnose the problems.  They are not intended
452f4b3ec61Sdh  * to be consumed by customers.
453f4b3ec61Sdh  */
454f4b3ec61Sdh void *
4555dd46ab5SKacheong Poon sctp_kstat2_init(netstackid_t stackid)
456f4b3ec61Sdh {
457f4b3ec61Sdh 	kstat_t *ksp;
458f4b3ec61Sdh 
459f4b3ec61Sdh 	sctp_kstat_t template = {
460f4b3ec61Sdh 		{ "sctp_add_faddr",			KSTAT_DATA_UINT64 },
461f4b3ec61Sdh 		{ "sctp_add_timer",			KSTAT_DATA_UINT64 },
462f4b3ec61Sdh 		{ "sctp_conn_create",			KSTAT_DATA_UINT64 },
463f4b3ec61Sdh 		{ "sctp_find_next_tq",			KSTAT_DATA_UINT64 },
464f4b3ec61Sdh 		{ "sctp_fr_add_hdr",			KSTAT_DATA_UINT64 },
465f4b3ec61Sdh 		{ "sctp_fr_not_found",			KSTAT_DATA_UINT64 },
466f4b3ec61Sdh 		{ "sctp_output_failed",			KSTAT_DATA_UINT64 },
467f4b3ec61Sdh 		{ "sctp_rexmit_failed",			KSTAT_DATA_UINT64 },
468f4b3ec61Sdh 		{ "sctp_send_init_failed",		KSTAT_DATA_UINT64 },
469f4b3ec61Sdh 		{ "sctp_send_cookie_failed",		KSTAT_DATA_UINT64 },
470f4b3ec61Sdh 		{ "sctp_send_cookie_ack_failed",	KSTAT_DATA_UINT64 },
471f4b3ec61Sdh 		{ "sctp_send_err_failed",		KSTAT_DATA_UINT64 },
472f4b3ec61Sdh 		{ "sctp_send_sack_failed",		KSTAT_DATA_UINT64 },
473f4b3ec61Sdh 		{ "sctp_send_shutdown_failed",		KSTAT_DATA_UINT64 },
474f4b3ec61Sdh 		{ "sctp_send_shutdown_ack_failed",	KSTAT_DATA_UINT64 },
475f4b3ec61Sdh 		{ "sctp_send_shutdown_comp_failed",	KSTAT_DATA_UINT64 },
476f4b3ec61Sdh 		{ "sctp_send_user_abort_failed",	KSTAT_DATA_UINT64 },
477f4b3ec61Sdh 		{ "sctp_send_asconf_failed",		KSTAT_DATA_UINT64 },
478f4b3ec61Sdh 		{ "sctp_send_asconf_ack_failed",	KSTAT_DATA_UINT64 },
479f4b3ec61Sdh 		{ "sctp_send_ftsn_failed",		KSTAT_DATA_UINT64 },
480f4b3ec61Sdh 		{ "sctp_send_hb_failed",		KSTAT_DATA_UINT64 },
481f4b3ec61Sdh 		{ "sctp_return_hb_failed",		KSTAT_DATA_UINT64 },
482f4b3ec61Sdh 		{ "sctp_ss_rexmit_failed",		KSTAT_DATA_UINT64 },
483f4b3ec61Sdh 		{ "sctp_cl_connect",			KSTAT_DATA_UINT64 },
484f4b3ec61Sdh 		{ "sctp_cl_assoc_change",		KSTAT_DATA_UINT64 },
485f4b3ec61Sdh 		{ "sctp_cl_check_addrs",		KSTAT_DATA_UINT64 },
4865dd46ab5SKacheong Poon 		{ "sctp_reclaim_drop",			KSTAT_DATA_UINT64 },
4875dd46ab5SKacheong Poon 		{ "sctp_listen_cnt_drop",		KSTAT_DATA_UINT64 },
488f4b3ec61Sdh 	};
489f4b3ec61Sdh 
490f4b3ec61Sdh 	ksp = kstat_create_netstack(SCTP_MOD_NAME, 0, "sctpstat", "net",
4915dd46ab5SKacheong Poon 	    KSTAT_TYPE_NAMED, NUM_OF_FIELDS(template), 0, stackid);
4927c478bd9Sstevel@tonic-gate 
493f4b3ec61Sdh 	if (ksp == NULL)
494f4b3ec61Sdh 		return (NULL);
4957c478bd9Sstevel@tonic-gate 
4965dd46ab5SKacheong Poon 	bcopy(&template, ksp->ks_data, sizeof (template));
497f4b3ec61Sdh 	ksp->ks_private = (void *)(uintptr_t)stackid;
4985dd46ab5SKacheong Poon 	ksp->ks_update = sctp_kstat2_update;
49977c67f2fSkcpoon 
500f4b3ec61Sdh 	kstat_install(ksp);
501f4b3ec61Sdh 	return (ksp);
5027c478bd9Sstevel@tonic-gate }
5037c478bd9Sstevel@tonic-gate 
5047c478bd9Sstevel@tonic-gate void
505f4b3ec61Sdh sctp_kstat_fini(netstackid_t stackid, kstat_t *ksp)
5067c478bd9Sstevel@tonic-gate {
507f4b3ec61Sdh 	if (ksp != NULL) {
508f4b3ec61Sdh 		ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
509f4b3ec61Sdh 		kstat_delete_netstack(ksp, stackid);
5107c478bd9Sstevel@tonic-gate 	}
511f4b3ec61Sdh }
512f4b3ec61Sdh 
513f4b3ec61Sdh void
514f4b3ec61Sdh sctp_kstat2_fini(netstackid_t stackid, kstat_t *ksp)
515f4b3ec61Sdh {
516f4b3ec61Sdh 	if (ksp != NULL) {
517f4b3ec61Sdh 		ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
518f4b3ec61Sdh 		kstat_delete_netstack(ksp, stackid);
51977c67f2fSkcpoon 	}
5207c478bd9Sstevel@tonic-gate }
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate /*
5237c478bd9Sstevel@tonic-gate  * Return SNMP global stats in buffer in mpdata.
5247c478bd9Sstevel@tonic-gate  * Return associatiation table in mp_conn_data,
5257c478bd9Sstevel@tonic-gate  * local address table in mp_local_data, and
5267c478bd9Sstevel@tonic-gate  * remote address table in mp_rem_data.
5277c478bd9Sstevel@tonic-gate  */
5287c478bd9Sstevel@tonic-gate mblk_t *
529f4b3ec61Sdh sctp_snmp_get_mib2(queue_t *q, mblk_t *mpctl, sctp_stack_t *sctps)
5307c478bd9Sstevel@tonic-gate {
5317c478bd9Sstevel@tonic-gate 	mblk_t			*mpdata, *mp_ret;
5327c478bd9Sstevel@tonic-gate 	mblk_t			*mp_conn_ctl = NULL;
5337c478bd9Sstevel@tonic-gate 	mblk_t			*mp_conn_data;
5347c478bd9Sstevel@tonic-gate 	mblk_t			*mp_conn_tail = NULL;
5357c478bd9Sstevel@tonic-gate 	mblk_t			*mp_local_ctl = NULL;
5367c478bd9Sstevel@tonic-gate 	mblk_t			*mp_local_data;
5377c478bd9Sstevel@tonic-gate 	mblk_t			*mp_local_tail = NULL;
5387c478bd9Sstevel@tonic-gate 	mblk_t			*mp_rem_ctl = NULL;
5397c478bd9Sstevel@tonic-gate 	mblk_t			*mp_rem_data;
5407c478bd9Sstevel@tonic-gate 	mblk_t			*mp_rem_tail = NULL;
54145916cd2Sjpk 	mblk_t			*mp_attr_ctl = NULL;
54245916cd2Sjpk 	mblk_t			*mp_attr_data;
54345916cd2Sjpk 	mblk_t			*mp_attr_tail = NULL;
5447c478bd9Sstevel@tonic-gate 	struct opthdr		*optp;
5457c478bd9Sstevel@tonic-gate 	sctp_t			*sctp, *sctp_prev = NULL;
5467c478bd9Sstevel@tonic-gate 	sctp_faddr_t		*fp;
5477c478bd9Sstevel@tonic-gate 	mib2_sctpConnEntry_t	sce;
5487c478bd9Sstevel@tonic-gate 	mib2_sctpConnLocalEntry_t	scle;
5497c478bd9Sstevel@tonic-gate 	mib2_sctpConnRemoteEntry_t	scre;
55045916cd2Sjpk 	mib2_transportMLPEntry_t	mlp;
5517c478bd9Sstevel@tonic-gate 	int			i;
5527c478bd9Sstevel@tonic-gate 	int			l;
5537c478bd9Sstevel@tonic-gate 	int			scanned = 0;
5547c478bd9Sstevel@tonic-gate 	zoneid_t		zoneid = Q_TO_CONN(q)->conn_zoneid;
55545916cd2Sjpk 	conn_t			*connp;
55645916cd2Sjpk 	boolean_t		needattr;
55745916cd2Sjpk 	int			idx;
5585dd46ab5SKacheong Poon 	mib2_sctp_t		sctp_mib;
5597c478bd9Sstevel@tonic-gate 
5607c478bd9Sstevel@tonic-gate 	/*
5617c478bd9Sstevel@tonic-gate 	 * Make copies of the original message.
5627c478bd9Sstevel@tonic-gate 	 * mpctl will hold SCTP counters,
5637c478bd9Sstevel@tonic-gate 	 * mp_conn_ctl will hold list of connections.
5647c478bd9Sstevel@tonic-gate 	 */
5657c478bd9Sstevel@tonic-gate 	mp_ret = copymsg(mpctl);
5667c478bd9Sstevel@tonic-gate 	mp_conn_ctl = copymsg(mpctl);
5677c478bd9Sstevel@tonic-gate 	mp_local_ctl = copymsg(mpctl);
5687c478bd9Sstevel@tonic-gate 	mp_rem_ctl = copymsg(mpctl);
56945916cd2Sjpk 	mp_attr_ctl = copymsg(mpctl);
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate 	mpdata = mpctl->b_cont;
5727c478bd9Sstevel@tonic-gate 
57345916cd2Sjpk 	if (mp_conn_ctl == NULL || mp_local_ctl == NULL ||
57445916cd2Sjpk 	    mp_rem_ctl == NULL || mp_attr_ctl == NULL || mpdata == NULL) {
57545916cd2Sjpk 		freemsg(mp_attr_ctl);
5767c478bd9Sstevel@tonic-gate 		freemsg(mp_rem_ctl);
5777c478bd9Sstevel@tonic-gate 		freemsg(mp_local_ctl);
5787c478bd9Sstevel@tonic-gate 		freemsg(mp_conn_ctl);
5797c478bd9Sstevel@tonic-gate 		freemsg(mp_ret);
5807c478bd9Sstevel@tonic-gate 		freemsg(mpctl);
5817c478bd9Sstevel@tonic-gate 		return (NULL);
5827c478bd9Sstevel@tonic-gate 	}
5837c478bd9Sstevel@tonic-gate 	mp_conn_data = mp_conn_ctl->b_cont;
5847c478bd9Sstevel@tonic-gate 	mp_local_data = mp_local_ctl->b_cont;
5857c478bd9Sstevel@tonic-gate 	mp_rem_data = mp_rem_ctl->b_cont;
58645916cd2Sjpk 	mp_attr_data = mp_attr_ctl->b_cont;
5877c478bd9Sstevel@tonic-gate 
5885dd46ab5SKacheong Poon 	bzero(&sctp_mib, sizeof (sctp_mib));
5895dd46ab5SKacheong Poon 
5907c478bd9Sstevel@tonic-gate 	/* hostname address parameters are not supported in Solaris */
5917c478bd9Sstevel@tonic-gate 	sce.sctpAssocRemHostName.o_length = 0;
5927c478bd9Sstevel@tonic-gate 	sce.sctpAssocRemHostName.o_bytes[0] = 0;
5937c478bd9Sstevel@tonic-gate 
5947c478bd9Sstevel@tonic-gate 	/* build table of connections -- need count in fixed part */
5957c478bd9Sstevel@tonic-gate 
59645916cd2Sjpk 	idx = 0;
597f4b3ec61Sdh 	mutex_enter(&sctps->sctps_g_lock);
598bd670b35SErik Nordmark 	sctp = list_head(&sctps->sctps_g_list);
5997c478bd9Sstevel@tonic-gate 	while (sctp != NULL) {
6007c478bd9Sstevel@tonic-gate 		mutex_enter(&sctp->sctp_reflock);
6017c478bd9Sstevel@tonic-gate 		if (sctp->sctp_condemned) {
6027c478bd9Sstevel@tonic-gate 			mutex_exit(&sctp->sctp_reflock);
603f4b3ec61Sdh 			sctp = list_next(&sctps->sctps_g_list, sctp);
6047c478bd9Sstevel@tonic-gate 			continue;
6057c478bd9Sstevel@tonic-gate 		}
6067c478bd9Sstevel@tonic-gate 		sctp->sctp_refcnt++;
6077c478bd9Sstevel@tonic-gate 		mutex_exit(&sctp->sctp_reflock);
608f4b3ec61Sdh 		mutex_exit(&sctps->sctps_g_lock);
6097c478bd9Sstevel@tonic-gate 		if (sctp_prev != NULL)
6107c478bd9Sstevel@tonic-gate 			SCTP_REFRELE(sctp_prev);
6117c478bd9Sstevel@tonic-gate 		if (sctp->sctp_connp->conn_zoneid != zoneid)
6127c478bd9Sstevel@tonic-gate 			goto next_sctp;
6137c478bd9Sstevel@tonic-gate 		if (sctp->sctp_state == SCTPS_ESTABLISHED ||
6147c478bd9Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_PENDING ||
6157c478bd9Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) {
6165dd46ab5SKacheong Poon 			/*
6175dd46ab5SKacheong Poon 			 * Just bump the local sctp_mib.  The number of
6185dd46ab5SKacheong Poon 			 * existing associations is not kept in kernel.
6195dd46ab5SKacheong Poon 			 */
6205dd46ab5SKacheong Poon 			BUMP_MIB(&sctp_mib, sctpCurrEstab);
6217c478bd9Sstevel@tonic-gate 		}
6225dd46ab5SKacheong Poon 		SCTPS_UPDATE_MIB(sctps, sctpOutSCTPPkts, sctp->sctp_opkts);
6237c478bd9Sstevel@tonic-gate 		sctp->sctp_opkts = 0;
6245dd46ab5SKacheong Poon 		SCTPS_UPDATE_MIB(sctps, sctpOutCtrlChunks, sctp->sctp_obchunks);
62535e12f9cSGeorge Shepherd 		UPDATE_LOCAL(sctp->sctp_cum_obchunks,
62635e12f9cSGeorge Shepherd 		    sctp->sctp_obchunks);
6277c478bd9Sstevel@tonic-gate 		sctp->sctp_obchunks = 0;
6285dd46ab5SKacheong Poon 		SCTPS_UPDATE_MIB(sctps, sctpOutOrderChunks,
6295dd46ab5SKacheong Poon 		    sctp->sctp_odchunks);
63035e12f9cSGeorge Shepherd 		UPDATE_LOCAL(sctp->sctp_cum_odchunks,
63135e12f9cSGeorge Shepherd 		    sctp->sctp_odchunks);
6327c478bd9Sstevel@tonic-gate 		sctp->sctp_odchunks = 0;
6335dd46ab5SKacheong Poon 		SCTPS_UPDATE_MIB(sctps, sctpOutUnorderChunks,
6347c478bd9Sstevel@tonic-gate 		    sctp->sctp_oudchunks);
63535e12f9cSGeorge Shepherd 		UPDATE_LOCAL(sctp->sctp_cum_oudchunks,
63635e12f9cSGeorge Shepherd 		    sctp->sctp_oudchunks);
6377c478bd9Sstevel@tonic-gate 		sctp->sctp_oudchunks = 0;
6385dd46ab5SKacheong Poon 		SCTPS_UPDATE_MIB(sctps, sctpRetransChunks,
6395dd46ab5SKacheong Poon 		    sctp->sctp_rxtchunks);
64035e12f9cSGeorge Shepherd 		UPDATE_LOCAL(sctp->sctp_cum_rxtchunks,
64135e12f9cSGeorge Shepherd 		    sctp->sctp_rxtchunks);
6427c478bd9Sstevel@tonic-gate 		sctp->sctp_rxtchunks = 0;
6435dd46ab5SKacheong Poon 		SCTPS_UPDATE_MIB(sctps, sctpInSCTPPkts, sctp->sctp_ipkts);
6447c478bd9Sstevel@tonic-gate 		sctp->sctp_ipkts = 0;
6455dd46ab5SKacheong Poon 		SCTPS_UPDATE_MIB(sctps, sctpInCtrlChunks, sctp->sctp_ibchunks);
64635e12f9cSGeorge Shepherd 		UPDATE_LOCAL(sctp->sctp_cum_ibchunks,
64735e12f9cSGeorge Shepherd 		    sctp->sctp_ibchunks);
6487c478bd9Sstevel@tonic-gate 		sctp->sctp_ibchunks = 0;
6495dd46ab5SKacheong Poon 		SCTPS_UPDATE_MIB(sctps, sctpInOrderChunks, sctp->sctp_idchunks);
65035e12f9cSGeorge Shepherd 		UPDATE_LOCAL(sctp->sctp_cum_idchunks,
65135e12f9cSGeorge Shepherd 		    sctp->sctp_idchunks);
6527c478bd9Sstevel@tonic-gate 		sctp->sctp_idchunks = 0;
6535dd46ab5SKacheong Poon 		SCTPS_UPDATE_MIB(sctps, sctpInUnorderChunks,
6547c478bd9Sstevel@tonic-gate 		    sctp->sctp_iudchunks);
65535e12f9cSGeorge Shepherd 		UPDATE_LOCAL(sctp->sctp_cum_iudchunks,
65635e12f9cSGeorge Shepherd 		    sctp->sctp_iudchunks);
6577c478bd9Sstevel@tonic-gate 		sctp->sctp_iudchunks = 0;
6585dd46ab5SKacheong Poon 		SCTPS_UPDATE_MIB(sctps, sctpFragUsrMsgs, sctp->sctp_fragdmsgs);
6597c478bd9Sstevel@tonic-gate 		sctp->sctp_fragdmsgs = 0;
6605dd46ab5SKacheong Poon 		SCTPS_UPDATE_MIB(sctps, sctpReasmUsrMsgs, sctp->sctp_reassmsgs);
6617c478bd9Sstevel@tonic-gate 		sctp->sctp_reassmsgs = 0;
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate 		sce.sctpAssocId = ntohl(sctp->sctp_lvtag);
664bd670b35SErik Nordmark 		sce.sctpAssocLocalPort = ntohs(sctp->sctp_connp->conn_lport);
665bd670b35SErik Nordmark 		sce.sctpAssocRemPort = ntohs(sctp->sctp_connp->conn_fport);
6667c478bd9Sstevel@tonic-gate 
6677c478bd9Sstevel@tonic-gate 		RUN_SCTP(sctp);
6687c478bd9Sstevel@tonic-gate 		if (sctp->sctp_primary != NULL) {
6697c478bd9Sstevel@tonic-gate 			fp = sctp->sctp_primary;
6707c478bd9Sstevel@tonic-gate 
6716be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			if (IN6_IS_ADDR_V4MAPPED(&fp->sf_faddr)) {
6727c478bd9Sstevel@tonic-gate 				sce.sctpAssocRemPrimAddrType =
6737c478bd9Sstevel@tonic-gate 				    MIB2_SCTP_ADDR_V4;
6747c478bd9Sstevel@tonic-gate 			} else {
6757c478bd9Sstevel@tonic-gate 				sce.sctpAssocRemPrimAddrType =
6767c478bd9Sstevel@tonic-gate 				    MIB2_SCTP_ADDR_V6;
6777c478bd9Sstevel@tonic-gate 			}
6786be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			sce.sctpAssocRemPrimAddr = fp->sf_faddr;
6796be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			sce.sctpAssocLocPrimAddr = fp->sf_saddr;
6807c478bd9Sstevel@tonic-gate 			sce.sctpAssocHeartBeatInterval = TICK_TO_MSEC(
6816be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			    fp->sf_hb_interval);
6827c478bd9Sstevel@tonic-gate 		} else {
6837c478bd9Sstevel@tonic-gate 			sce.sctpAssocRemPrimAddrType = MIB2_SCTP_ADDR_V4;
6847c478bd9Sstevel@tonic-gate 			bzero(&sce.sctpAssocRemPrimAddr,
6857c478bd9Sstevel@tonic-gate 			    sizeof (sce.sctpAssocRemPrimAddr));
6867c478bd9Sstevel@tonic-gate 			bzero(&sce.sctpAssocLocPrimAddr,
6877c478bd9Sstevel@tonic-gate 			    sizeof (sce.sctpAssocLocPrimAddr));
6887c478bd9Sstevel@tonic-gate 			sce.sctpAssocHeartBeatInterval =
689f4b3ec61Sdh 			    sctps->sctps_heartbeat_interval;
6907c478bd9Sstevel@tonic-gate 		}
6917c478bd9Sstevel@tonic-gate 
6927c478bd9Sstevel@tonic-gate 		/*
6937c478bd9Sstevel@tonic-gate 		 * Table for local addresses
6947c478bd9Sstevel@tonic-gate 		 */
6957c478bd9Sstevel@tonic-gate 		scanned = 0;
6967c478bd9Sstevel@tonic-gate 		for (i = 0; i < SCTP_IPIF_HASH; i++) {
6977c478bd9Sstevel@tonic-gate 			sctp_saddr_ipif_t	*obj;
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate 			if (sctp->sctp_saddrs[i].ipif_count == 0)
7007c478bd9Sstevel@tonic-gate 				continue;
7017c478bd9Sstevel@tonic-gate 			obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
7027c478bd9Sstevel@tonic-gate 			for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
7037c478bd9Sstevel@tonic-gate 				sctp_ipif_t	*sctp_ipif;
7047c478bd9Sstevel@tonic-gate 				in6_addr_t	addr;
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate 				sctp_ipif = obj->saddr_ipifp;
7077c478bd9Sstevel@tonic-gate 				addr = sctp_ipif->sctp_ipif_saddr;
7087c478bd9Sstevel@tonic-gate 				scanned++;
7097c478bd9Sstevel@tonic-gate 				scle.sctpAssocId = ntohl(sctp->sctp_lvtag);
7107c478bd9Sstevel@tonic-gate 				if (IN6_IS_ADDR_V4MAPPED(&addr)) {
7117c478bd9Sstevel@tonic-gate 					scle.sctpAssocLocalAddrType =
7127c478bd9Sstevel@tonic-gate 					    MIB2_SCTP_ADDR_V4;
7137c478bd9Sstevel@tonic-gate 				} else {
7147c478bd9Sstevel@tonic-gate 					scle.sctpAssocLocalAddrType =
7157c478bd9Sstevel@tonic-gate 					    MIB2_SCTP_ADDR_V6;
7167c478bd9Sstevel@tonic-gate 				}
7177c478bd9Sstevel@tonic-gate 				scle.sctpAssocLocalAddr = addr;
7187c478bd9Sstevel@tonic-gate 				(void) snmp_append_data2(mp_local_data,
7197c478bd9Sstevel@tonic-gate 				    &mp_local_tail, (char *)&scle,
7207c478bd9Sstevel@tonic-gate 				    sizeof (scle));
7217c478bd9Sstevel@tonic-gate 				if (scanned >= sctp->sctp_nsaddrs)
7227c478bd9Sstevel@tonic-gate 					goto done;
7237c478bd9Sstevel@tonic-gate 				obj = list_next(&sctp->
7247c478bd9Sstevel@tonic-gate 				    sctp_saddrs[i].sctp_ipif_list, obj);
7257c478bd9Sstevel@tonic-gate 			}
7267c478bd9Sstevel@tonic-gate 		}
7277c478bd9Sstevel@tonic-gate done:
7287c478bd9Sstevel@tonic-gate 		/*
7297c478bd9Sstevel@tonic-gate 		 * Table for remote addresses
7307c478bd9Sstevel@tonic-gate 		 */
7316be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 		for (fp = sctp->sctp_faddrs; fp; fp = fp->sf_next) {
7327c478bd9Sstevel@tonic-gate 			scre.sctpAssocId = ntohl(sctp->sctp_lvtag);
7336be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			if (IN6_IS_ADDR_V4MAPPED(&fp->sf_faddr)) {
7347c478bd9Sstevel@tonic-gate 				scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V4;
7357c478bd9Sstevel@tonic-gate 			} else {
7367c478bd9Sstevel@tonic-gate 				scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V6;
7377c478bd9Sstevel@tonic-gate 			}
7386be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			scre.sctpAssocRemAddr = fp->sf_faddr;
7396be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			if (fp->sf_state == SCTP_FADDRS_ALIVE) {
7407c478bd9Sstevel@tonic-gate 				scre.sctpAssocRemAddrActive =
7417c478bd9Sstevel@tonic-gate 				    scre.sctpAssocRemAddrHBActive =
7427c478bd9Sstevel@tonic-gate 				    MIB2_SCTP_ACTIVE;
7437c478bd9Sstevel@tonic-gate 			} else {
7447c478bd9Sstevel@tonic-gate 				scre.sctpAssocRemAddrActive =
7457c478bd9Sstevel@tonic-gate 				    scre.sctpAssocRemAddrHBActive =
7467c478bd9Sstevel@tonic-gate 				    MIB2_SCTP_INACTIVE;
7477c478bd9Sstevel@tonic-gate 			}
7486be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			scre.sctpAssocRemAddrRTO = TICK_TO_MSEC(fp->sf_rto);
7496be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			scre.sctpAssocRemAddrMaxPathRtx = fp->sf_max_retr;
7506be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 			scre.sctpAssocRemAddrRtx = fp->sf_T3expire;
7517c478bd9Sstevel@tonic-gate 			(void) snmp_append_data2(mp_rem_data, &mp_rem_tail,
7527c478bd9Sstevel@tonic-gate 			    (char *)&scre, sizeof (scre));
7537c478bd9Sstevel@tonic-gate 		}
75445916cd2Sjpk 		connp = sctp->sctp_connp;
75545916cd2Sjpk 		needattr = B_FALSE;
75645916cd2Sjpk 		bzero(&mlp, sizeof (mlp));
75745916cd2Sjpk 		if (connp->conn_mlp_type != mlptSingle) {
75845916cd2Sjpk 			if (connp->conn_mlp_type == mlptShared ||
75945916cd2Sjpk 			    connp->conn_mlp_type == mlptBoth)
76045916cd2Sjpk 				mlp.tme_flags |= MIB2_TMEF_SHARED;
76145916cd2Sjpk 			if (connp->conn_mlp_type == mlptPrivate ||
76245916cd2Sjpk 			    connp->conn_mlp_type == mlptBoth)
76345916cd2Sjpk 				mlp.tme_flags |= MIB2_TMEF_PRIVATE;
76445916cd2Sjpk 			needattr = B_TRUE;
76545916cd2Sjpk 		}
7665f9878b0Sken Powell - Sun Microsystem 		if (connp->conn_anon_mlp) {
7675f9878b0Sken Powell - Sun Microsystem 			mlp.tme_flags |= MIB2_TMEF_ANONMLP;
7685f9878b0Sken Powell - Sun Microsystem 			needattr = B_TRUE;
7695f9878b0Sken Powell - Sun Microsystem 		}
7705d3b8cb7SBill Sommerfeld 		switch (connp->conn_mac_mode) {
7715d3b8cb7SBill Sommerfeld 		case CONN_MAC_DEFAULT:
7725d3b8cb7SBill Sommerfeld 			break;
7735d3b8cb7SBill Sommerfeld 		case CONN_MAC_AWARE:
7745f9878b0Sken Powell - Sun Microsystem 			mlp.tme_flags |= MIB2_TMEF_MACEXEMPT;
7755f9878b0Sken Powell - Sun Microsystem 			needattr = B_TRUE;
7765d3b8cb7SBill Sommerfeld 			break;
7775d3b8cb7SBill Sommerfeld 		case CONN_MAC_IMPLICIT:
7785d3b8cb7SBill Sommerfeld 			mlp.tme_flags |= MIB2_TMEF_MACIMPLICIT;
7795d3b8cb7SBill Sommerfeld 			needattr = B_TRUE;
7805d3b8cb7SBill Sommerfeld 			break;
7815f9878b0Sken Powell - Sun Microsystem 		}
782bd670b35SErik Nordmark 		if (sctp->sctp_connp->conn_ixa->ixa_tsl != NULL) {
78345916cd2Sjpk 			ts_label_t *tsl;
78445916cd2Sjpk 
785bd670b35SErik Nordmark 			tsl = sctp->sctp_connp->conn_ixa->ixa_tsl;
7865f9878b0Sken Powell - Sun Microsystem 			mlp.tme_flags |= MIB2_TMEF_IS_LABELED;
78745916cd2Sjpk 			mlp.tme_doi = label2doi(tsl);
78845916cd2Sjpk 			mlp.tme_label = *label2bslabel(tsl);
78945916cd2Sjpk 			needattr = B_TRUE;
79045916cd2Sjpk 		}
7917c478bd9Sstevel@tonic-gate 		WAKE_SCTP(sctp);
7927c478bd9Sstevel@tonic-gate 		sce.sctpAssocState = sctp_snmp_state(sctp);
7937c478bd9Sstevel@tonic-gate 		sce.sctpAssocInStreams = sctp->sctp_num_istr;
7947c478bd9Sstevel@tonic-gate 		sce.sctpAssocOutStreams = sctp->sctp_num_ostr;
7957c478bd9Sstevel@tonic-gate 		sce.sctpAssocMaxRetr = sctp->sctp_pa_max_rxt;
7967c478bd9Sstevel@tonic-gate 		/* A 0 here indicates that no primary process is known */
7977c478bd9Sstevel@tonic-gate 		sce.sctpAssocPrimProcess = 0;
7987c478bd9Sstevel@tonic-gate 		sce.sctpAssocT1expired = sctp->sctp_T1expire;
7997c478bd9Sstevel@tonic-gate 		sce.sctpAssocT2expired = sctp->sctp_T2expire;
8007c478bd9Sstevel@tonic-gate 		sce.sctpAssocRtxChunks = sctp->sctp_T3expire;
8017c478bd9Sstevel@tonic-gate 		sce.sctpAssocStartTime = sctp->sctp_assoc_start_time;
8027c478bd9Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_sendq = sctp->sctp_unacked +
8037c478bd9Sstevel@tonic-gate 		    sctp->sctp_unsent;
8047c478bd9Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_recvq = sctp->sctp_rxqueued;
8057c478bd9Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_swnd = sctp->sctp_frwnd;
8067c478bd9Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_rwnd = sctp->sctp_rwnd;
8077c478bd9Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_mss = sctp->sctp_mss;
8087c478bd9Sstevel@tonic-gate 		(void) snmp_append_data2(mp_conn_data, &mp_conn_tail,
8097c478bd9Sstevel@tonic-gate 		    (char *)&sce, sizeof (sce));
81045916cd2Sjpk 		mlp.tme_connidx = idx++;
81145916cd2Sjpk 		if (needattr)
81245916cd2Sjpk 			(void) snmp_append_data2(mp_attr_ctl->b_cont,
81345916cd2Sjpk 			    &mp_attr_tail, (char *)&mlp, sizeof (mlp));
8147c478bd9Sstevel@tonic-gate next_sctp:
8157c478bd9Sstevel@tonic-gate 		sctp_prev = sctp;
816f4b3ec61Sdh 		mutex_enter(&sctps->sctps_g_lock);
817f4b3ec61Sdh 		sctp = list_next(&sctps->sctps_g_list, sctp);
8187c478bd9Sstevel@tonic-gate 	}
819f4b3ec61Sdh 	mutex_exit(&sctps->sctps_g_lock);
8207c478bd9Sstevel@tonic-gate 	if (sctp_prev != NULL)
8217c478bd9Sstevel@tonic-gate 		SCTP_REFRELE(sctp_prev);
8227c478bd9Sstevel@tonic-gate 
8235dd46ab5SKacheong Poon 	sctp_sum_mib(sctps, &sctp_mib);
8245dd46ab5SKacheong Poon 
8257c478bd9Sstevel@tonic-gate 	optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
8267c478bd9Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
8277c478bd9Sstevel@tonic-gate 	optp->name = 0;
8285dd46ab5SKacheong Poon 	(void) snmp_append_data(mpdata, (char *)&sctp_mib, sizeof (sctp_mib));
8297c478bd9Sstevel@tonic-gate 	optp->len = msgdsize(mpdata);
8307c478bd9Sstevel@tonic-gate 	qreply(q, mpctl);
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate 	/* table of connections... */
8337c478bd9Sstevel@tonic-gate 	optp = (struct opthdr *)&mp_conn_ctl->b_rptr[
8347c478bd9Sstevel@tonic-gate 	    sizeof (struct T_optmgmt_ack)];
8357c478bd9Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
8367c478bd9Sstevel@tonic-gate 	optp->name = MIB2_SCTP_CONN;
8377c478bd9Sstevel@tonic-gate 	optp->len = msgdsize(mp_conn_data);
8387c478bd9Sstevel@tonic-gate 	qreply(q, mp_conn_ctl);
8397c478bd9Sstevel@tonic-gate 
8407c478bd9Sstevel@tonic-gate 	/* assoc local address table */
8417c478bd9Sstevel@tonic-gate 	optp = (struct opthdr *)&mp_local_ctl->b_rptr[
8427c478bd9Sstevel@tonic-gate 	    sizeof (struct T_optmgmt_ack)];
8437c478bd9Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
8447c478bd9Sstevel@tonic-gate 	optp->name = MIB2_SCTP_CONN_LOCAL;
8457c478bd9Sstevel@tonic-gate 	optp->len = msgdsize(mp_local_data);
8467c478bd9Sstevel@tonic-gate 	qreply(q, mp_local_ctl);
8477c478bd9Sstevel@tonic-gate 
8487c478bd9Sstevel@tonic-gate 	/* assoc remote address table */
8497c478bd9Sstevel@tonic-gate 	optp = (struct opthdr *)&mp_rem_ctl->b_rptr[
8507c478bd9Sstevel@tonic-gate 	    sizeof (struct T_optmgmt_ack)];
8517c478bd9Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
8527c478bd9Sstevel@tonic-gate 	optp->name = MIB2_SCTP_CONN_REMOTE;
8537c478bd9Sstevel@tonic-gate 	optp->len = msgdsize(mp_rem_data);
8547c478bd9Sstevel@tonic-gate 	qreply(q, mp_rem_ctl);
8557c478bd9Sstevel@tonic-gate 
85645916cd2Sjpk 	/* table of MLP attributes */
85745916cd2Sjpk 	optp = (struct opthdr *)&mp_attr_ctl->b_rptr[
85845916cd2Sjpk 	    sizeof (struct T_optmgmt_ack)];
85945916cd2Sjpk 	optp->level = MIB2_SCTP;
86045916cd2Sjpk 	optp->name = EXPER_XPORT_MLP;
86145916cd2Sjpk 	optp->len = msgdsize(mp_attr_data);
86245916cd2Sjpk 	if (optp->len == 0)
86345916cd2Sjpk 		freemsg(mp_attr_ctl);
86445916cd2Sjpk 	else
86545916cd2Sjpk 		qreply(q, mp_attr_ctl);
86645916cd2Sjpk 
8677c478bd9Sstevel@tonic-gate 	return (mp_ret);
8687c478bd9Sstevel@tonic-gate }
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate /* Translate SCTP state to MIB2 SCTP state. */
8717c478bd9Sstevel@tonic-gate static int
8727c478bd9Sstevel@tonic-gate sctp_snmp_state(sctp_t *sctp)
8737c478bd9Sstevel@tonic-gate {
8747c478bd9Sstevel@tonic-gate 	if (sctp == NULL)
8757c478bd9Sstevel@tonic-gate 		return (0);
8767c478bd9Sstevel@tonic-gate 
8777c478bd9Sstevel@tonic-gate 	switch (sctp->sctp_state) {
8787c478bd9Sstevel@tonic-gate 	case SCTPS_IDLE:
8797c478bd9Sstevel@tonic-gate 	case SCTPS_BOUND:
8807c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_closed);
8817c478bd9Sstevel@tonic-gate 	case SCTPS_LISTEN:
8827c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_listen);
8837c478bd9Sstevel@tonic-gate 	case SCTPS_COOKIE_WAIT:
8847c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_cookieWait);
8857c478bd9Sstevel@tonic-gate 	case SCTPS_COOKIE_ECHOED:
8867c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_cookieEchoed);
8877c478bd9Sstevel@tonic-gate 	case SCTPS_ESTABLISHED:
8887c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_established);
8897c478bd9Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_PENDING:
8907c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownPending);
8917c478bd9Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_SENT:
8927c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownSent);
8937c478bd9Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_RECEIVED:
8947c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownReceived);
8957c478bd9Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_ACK_SENT:
8967c478bd9Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownAckSent);
8977c478bd9Sstevel@tonic-gate 	default:
8987c478bd9Sstevel@tonic-gate 		return (0);
8997c478bd9Sstevel@tonic-gate 	}
9007c478bd9Sstevel@tonic-gate }
9015dd46ab5SKacheong Poon 
9025dd46ab5SKacheong Poon /*
9035dd46ab5SKacheong Poon  * To sum up all MIB2 stats for a sctp_stack_t from all per CPU stats.  The
9045dd46ab5SKacheong Poon  * caller should initialize the target mib2_sctp_t properly as this function
9055dd46ab5SKacheong Poon  * just adds up all the per CPU stats.
9065dd46ab5SKacheong Poon  */
9075dd46ab5SKacheong Poon static void
9085dd46ab5SKacheong Poon sctp_sum_mib(sctp_stack_t *sctps, mib2_sctp_t *sctp_mib)
9095dd46ab5SKacheong Poon {
9105dd46ab5SKacheong Poon 	int i;
9115dd46ab5SKacheong Poon 	int cnt;
9125dd46ab5SKacheong Poon 
9135dd46ab5SKacheong Poon 	/* Static componets of mib2_sctp_t. */
9145dd46ab5SKacheong Poon 	SET_MIB(sctp_mib->sctpRtoAlgorithm, MIB2_SCTP_RTOALGO_VANJ);
9155dd46ab5SKacheong Poon 	SET_MIB(sctp_mib->sctpRtoMin, sctps->sctps_rto_ming);
9165dd46ab5SKacheong Poon 	SET_MIB(sctp_mib->sctpRtoMax, sctps->sctps_rto_maxg);
9175dd46ab5SKacheong Poon 	SET_MIB(sctp_mib->sctpRtoInitial, sctps->sctps_rto_initialg);
9185dd46ab5SKacheong Poon 	SET_MIB(sctp_mib->sctpMaxAssocs, -1);
9195dd46ab5SKacheong Poon 	SET_MIB(sctp_mib->sctpValCookieLife, sctps->sctps_cookie_life);
9205dd46ab5SKacheong Poon 	SET_MIB(sctp_mib->sctpMaxInitRetr, sctps->sctps_max_init_retr);
9215dd46ab5SKacheong Poon 
9225dd46ab5SKacheong Poon 	/* fixed length structure for IPv4 and IPv6 counters */
9235dd46ab5SKacheong Poon 	SET_MIB(sctp_mib->sctpEntrySize, sizeof (mib2_sctpConnEntry_t));
9245dd46ab5SKacheong Poon 	SET_MIB(sctp_mib->sctpLocalEntrySize,
9255dd46ab5SKacheong Poon 	    sizeof (mib2_sctpConnLocalEntry_t));
9265dd46ab5SKacheong Poon 	SET_MIB(sctp_mib->sctpRemoteEntrySize,
9275dd46ab5SKacheong Poon 	    sizeof (mib2_sctpConnRemoteEntry_t));
9285dd46ab5SKacheong Poon 
9295dd46ab5SKacheong Poon 	/*
9305dd46ab5SKacheong Poon 	 * sctps_sc_cnt may change in the middle of the loop.  It is better
9315dd46ab5SKacheong Poon 	 * to get its value first.
9325dd46ab5SKacheong Poon 	 */
9335dd46ab5SKacheong Poon 	cnt = sctps->sctps_sc_cnt;
9345dd46ab5SKacheong Poon 	for (i = 0; i < cnt; i++)
9355dd46ab5SKacheong Poon 		sctp_add_mib(&sctps->sctps_sc[i]->sctp_sc_mib, sctp_mib);
9365dd46ab5SKacheong Poon }
9375dd46ab5SKacheong Poon 
9385dd46ab5SKacheong Poon static void
9395dd46ab5SKacheong Poon sctp_add_mib(mib2_sctp_t *from, mib2_sctp_t *to)
9405dd46ab5SKacheong Poon {
9415dd46ab5SKacheong Poon 	to->sctpActiveEstab += from->sctpActiveEstab;
9425dd46ab5SKacheong Poon 	to->sctpPassiveEstab += from->sctpPassiveEstab;
9435dd46ab5SKacheong Poon 	to->sctpAborted += from->sctpAborted;
9445dd46ab5SKacheong Poon 	to->sctpShutdowns += from->sctpShutdowns;
9455dd46ab5SKacheong Poon 	to->sctpOutOfBlue += from->sctpOutOfBlue;
9465dd46ab5SKacheong Poon 	to->sctpChecksumError += from->sctpChecksumError;
9475dd46ab5SKacheong Poon 	to->sctpOutCtrlChunks += from->sctpOutCtrlChunks;
9485dd46ab5SKacheong Poon 	to->sctpOutOrderChunks += from->sctpOutOrderChunks;
9495dd46ab5SKacheong Poon 	to->sctpOutUnorderChunks += from->sctpOutUnorderChunks;
9505dd46ab5SKacheong Poon 	to->sctpRetransChunks += from->sctpRetransChunks;
9515dd46ab5SKacheong Poon 	to->sctpOutAck += from->sctpOutAck;
9525dd46ab5SKacheong Poon 	to->sctpOutAckDelayed += from->sctpOutAckDelayed;
9535dd46ab5SKacheong Poon 	to->sctpOutWinUpdate += from->sctpOutWinUpdate;
9545dd46ab5SKacheong Poon 	to->sctpOutFastRetrans += from->sctpOutFastRetrans;
9555dd46ab5SKacheong Poon 	to->sctpOutWinProbe += from->sctpOutWinProbe;
9565dd46ab5SKacheong Poon 	to->sctpInCtrlChunks += from->sctpInCtrlChunks;
9575dd46ab5SKacheong Poon 	to->sctpInOrderChunks += from->sctpInOrderChunks;
9585dd46ab5SKacheong Poon 	to->sctpInUnorderChunks += from->sctpInUnorderChunks;
9595dd46ab5SKacheong Poon 	to->sctpInAck += from->sctpInAck;
9605dd46ab5SKacheong Poon 	to->sctpInDupAck += from->sctpInDupAck;
9615dd46ab5SKacheong Poon 	to->sctpInAckUnsent += from->sctpInAckUnsent;
9625dd46ab5SKacheong Poon 	to->sctpFragUsrMsgs += from->sctpFragUsrMsgs;
9635dd46ab5SKacheong Poon 	to->sctpReasmUsrMsgs += from->sctpReasmUsrMsgs;
9645dd46ab5SKacheong Poon 	to->sctpOutSCTPPkts += from->sctpOutSCTPPkts;
9655dd46ab5SKacheong Poon 	to->sctpInSCTPPkts += from->sctpInSCTPPkts;
9665dd46ab5SKacheong Poon 	to->sctpInInvalidCookie += from->sctpInInvalidCookie;
9675dd46ab5SKacheong Poon 	to->sctpTimRetrans += from->sctpTimRetrans;
9685dd46ab5SKacheong Poon 	to->sctpTimRetransDrop += from->sctpTimRetransDrop;
9695dd46ab5SKacheong Poon 	to->sctpTimHeartBeatProbe += from->sctpTimHeartBeatProbe;
9705dd46ab5SKacheong Poon 	to->sctpTimHeartBeatDrop += from->sctpTimHeartBeatDrop;
9715dd46ab5SKacheong Poon 	to->sctpListenDrop += from->sctpListenDrop;
9725dd46ab5SKacheong Poon 	to->sctpInClosed += from->sctpInClosed;
9735dd46ab5SKacheong Poon }
974