xref: /onnv-gate/usr/src/uts/common/inet/sctp/sctp_snmp.c (revision 12869:fb36eaeb6ee0)
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 /*
23*12869SKacheong.Poon@Sun.COM  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <sys/types.h>
270Sstevel@tonic-gate #include <sys/stream.h>
280Sstevel@tonic-gate #include <sys/cmn_err.h>
290Sstevel@tonic-gate #define	_SUN_TPI_VERSION 2
300Sstevel@tonic-gate #include <sys/tihdr.h>
310Sstevel@tonic-gate #include <sys/ddi.h>
320Sstevel@tonic-gate #include <sys/sunddi.h>
331676Sjpk #include <sys/tsol/tndb.h>
340Sstevel@tonic-gate 
350Sstevel@tonic-gate #include <netinet/in.h>
360Sstevel@tonic-gate 
370Sstevel@tonic-gate #include <inet/common.h>
380Sstevel@tonic-gate #include <inet/ip.h>
390Sstevel@tonic-gate #include <inet/mib2.h>
400Sstevel@tonic-gate #include <inet/snmpcom.h>
410Sstevel@tonic-gate #include <inet/kstatcom.h>
420Sstevel@tonic-gate #include <inet/ipclassifier.h>
430Sstevel@tonic-gate #include "sctp_impl.h"
440Sstevel@tonic-gate #include "sctp_addr.h"
450Sstevel@tonic-gate 
46*12869SKacheong.Poon@Sun.COM static void sctp_clr_kstats2(sctp_kstat_t *);
47*12869SKacheong.Poon@Sun.COM static void sctp_add_kstats2(sctp_kstat_counter_t *, sctp_kstat_t *);
48*12869SKacheong.Poon@Sun.COM static int sctp_snmp_state(sctp_t *);
49*12869SKacheong.Poon@Sun.COM static void sctp_sum_mib(sctp_stack_t *, mib2_sctp_t *);
50*12869SKacheong.Poon@Sun.COM static void sctp_add_mib(mib2_sctp_t *, mib2_sctp_t *);
511735Skcpoon 
520Sstevel@tonic-gate static int
530Sstevel@tonic-gate sctp_kstat_update(kstat_t *kp, int rw)
540Sstevel@tonic-gate {
550Sstevel@tonic-gate 	sctp_named_kstat_t	*sctpkp;
560Sstevel@tonic-gate 	sctp_t			*sctp, *sctp_prev;
573448Sdh155122 	zoneid_t	myzoneid;
583448Sdh155122 	netstackid_t	stackid = (netstackid_t)(uintptr_t)kp->ks_private;
593448Sdh155122 	netstack_t	*ns;
603448Sdh155122 	sctp_stack_t	*sctps;
61*12869SKacheong.Poon@Sun.COM 	mib2_sctp_t	sctp_mib;
620Sstevel@tonic-gate 
630Sstevel@tonic-gate 	if (kp == NULL|| kp->ks_data == NULL)
640Sstevel@tonic-gate 		return (EIO);
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 	if (rw == KSTAT_WRITE)
670Sstevel@tonic-gate 		return (EACCES);
680Sstevel@tonic-gate 
693448Sdh155122 	ns = netstack_find_by_stackid(stackid);
703448Sdh155122 	if (ns == NULL)
713448Sdh155122 		return (-1);
723448Sdh155122 	sctps = ns->netstack_sctp;
733448Sdh155122 	if (sctps == NULL) {
743448Sdh155122 		netstack_rele(ns);
753448Sdh155122 		return (-1);
763448Sdh155122 	}
77*12869SKacheong.Poon@Sun.COM 
78*12869SKacheong.Poon@Sun.COM 	/*
79*12869SKacheong.Poon@Sun.COM 	 * For all exclusive netstacks, the zone ID is always GLOBAL_ZONEID.
80*12869SKacheong.Poon@Sun.COM 	 */
81*12869SKacheong.Poon@Sun.COM 	if (stackid != GLOBAL_NETSTACKID)
82*12869SKacheong.Poon@Sun.COM 		myzoneid = GLOBAL_ZONEID;
83*12869SKacheong.Poon@Sun.COM 	else
84*12869SKacheong.Poon@Sun.COM 		myzoneid = curproc->p_zone->zone_id;
85*12869SKacheong.Poon@Sun.COM 
86*12869SKacheong.Poon@Sun.COM 	bzero(&sctp_mib, sizeof (sctp_mib));
870Sstevel@tonic-gate 
880Sstevel@tonic-gate 	/*
890Sstevel@tonic-gate 	 * Get the number of current associations and gather their
900Sstevel@tonic-gate 	 * individual set of statistics.
910Sstevel@tonic-gate 	 */
920Sstevel@tonic-gate 	sctp_prev = NULL;
933448Sdh155122 	mutex_enter(&sctps->sctps_g_lock);
9411042SErik.Nordmark@Sun.COM 	sctp = list_head(&sctps->sctps_g_list);
950Sstevel@tonic-gate 	while (sctp != NULL) {
960Sstevel@tonic-gate 		mutex_enter(&sctp->sctp_reflock);
970Sstevel@tonic-gate 		if (sctp->sctp_condemned) {
980Sstevel@tonic-gate 			mutex_exit(&sctp->sctp_reflock);
993448Sdh155122 			sctp = list_next(&sctps->sctps_g_list, sctp);
1000Sstevel@tonic-gate 			continue;
1010Sstevel@tonic-gate 		}
1020Sstevel@tonic-gate 		sctp->sctp_refcnt++;
1030Sstevel@tonic-gate 		mutex_exit(&sctp->sctp_reflock);
1043448Sdh155122 		mutex_exit(&sctps->sctps_g_lock);
1050Sstevel@tonic-gate 		if (sctp_prev != NULL)
1060Sstevel@tonic-gate 			SCTP_REFRELE(sctp_prev);
1073448Sdh155122 		if (sctp->sctp_connp->conn_zoneid != myzoneid)
1080Sstevel@tonic-gate 			goto next_sctp;
1090Sstevel@tonic-gate 		if (sctp->sctp_state == SCTPS_ESTABLISHED ||
1100Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_PENDING ||
1110Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) {
112*12869SKacheong.Poon@Sun.COM 			/*
113*12869SKacheong.Poon@Sun.COM 			 * Just bump the local sctp_mib.  The number of
114*12869SKacheong.Poon@Sun.COM 			 * existing associations is not kept in kernel.
115*12869SKacheong.Poon@Sun.COM 			 */
116*12869SKacheong.Poon@Sun.COM 			BUMP_MIB(&sctp_mib, sctpCurrEstab);
1170Sstevel@tonic-gate 		}
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 		if (sctp->sctp_opkts) {
120*12869SKacheong.Poon@Sun.COM 			SCTPS_UPDATE_MIB(sctps, sctpOutSCTPPkts,
1210Sstevel@tonic-gate 			    sctp->sctp_opkts);
1220Sstevel@tonic-gate 			sctp->sctp_opkts = 0;
1230Sstevel@tonic-gate 		}
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 		if (sctp->sctp_obchunks) {
126*12869SKacheong.Poon@Sun.COM 			SCTPS_UPDATE_MIB(sctps, sctpOutCtrlChunks,
1270Sstevel@tonic-gate 			    sctp->sctp_obchunks);
12810751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_obchunks,
12910751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_obchunks);
1300Sstevel@tonic-gate 			sctp->sctp_obchunks = 0;
1310Sstevel@tonic-gate 		}
1320Sstevel@tonic-gate 
1330Sstevel@tonic-gate 		if (sctp->sctp_odchunks) {
134*12869SKacheong.Poon@Sun.COM 			SCTPS_UPDATE_MIB(sctps, sctpOutOrderChunks,
1350Sstevel@tonic-gate 			    sctp->sctp_odchunks);
13610751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_odchunks,
13710751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_odchunks);
1380Sstevel@tonic-gate 			sctp->sctp_odchunks = 0;
1390Sstevel@tonic-gate 		}
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate 		if (sctp->sctp_oudchunks) {
142*12869SKacheong.Poon@Sun.COM 			SCTPS_UPDATE_MIB(sctps, sctpOutUnorderChunks,
1430Sstevel@tonic-gate 			    sctp->sctp_oudchunks);
14410751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_oudchunks,
14510751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_oudchunks);
1460Sstevel@tonic-gate 			sctp->sctp_oudchunks = 0;
1470Sstevel@tonic-gate 		}
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate 		if (sctp->sctp_rxtchunks) {
150*12869SKacheong.Poon@Sun.COM 			SCTPS_UPDATE_MIB(sctps, sctpRetransChunks,
1510Sstevel@tonic-gate 			    sctp->sctp_rxtchunks);
15210751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_rxtchunks,
15310751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_rxtchunks);
1540Sstevel@tonic-gate 			sctp->sctp_rxtchunks = 0;
1550Sstevel@tonic-gate 		}
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 		if (sctp->sctp_ipkts) {
158*12869SKacheong.Poon@Sun.COM 			SCTPS_UPDATE_MIB(sctps, sctpInSCTPPkts,
1593448Sdh155122 			    sctp->sctp_ipkts);
1600Sstevel@tonic-gate 			sctp->sctp_ipkts = 0;
1610Sstevel@tonic-gate 		}
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 		if (sctp->sctp_ibchunks) {
164*12869SKacheong.Poon@Sun.COM 			SCTPS_UPDATE_MIB(sctps, sctpInCtrlChunks,
1650Sstevel@tonic-gate 			    sctp->sctp_ibchunks);
16610751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_ibchunks,
16710751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_ibchunks);
1680Sstevel@tonic-gate 			sctp->sctp_ibchunks = 0;
1690Sstevel@tonic-gate 		}
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate 		if (sctp->sctp_idchunks) {
172*12869SKacheong.Poon@Sun.COM 			SCTPS_UPDATE_MIB(sctps, sctpInOrderChunks,
1730Sstevel@tonic-gate 			    sctp->sctp_idchunks);
17410751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_idchunks,
17510751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_idchunks);
1760Sstevel@tonic-gate 			sctp->sctp_idchunks = 0;
1770Sstevel@tonic-gate 		}
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate 		if (sctp->sctp_iudchunks) {
180*12869SKacheong.Poon@Sun.COM 			SCTPS_UPDATE_MIB(sctps, sctpInUnorderChunks,
1810Sstevel@tonic-gate 			    sctp->sctp_iudchunks);
18210751SGeorge.Shepherd@Sun.COM 			UPDATE_LOCAL(sctp->sctp_cum_iudchunks,
18310751SGeorge.Shepherd@Sun.COM 			    sctp->sctp_iudchunks);
1840Sstevel@tonic-gate 			sctp->sctp_iudchunks = 0;
1850Sstevel@tonic-gate 		}
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate 		if (sctp->sctp_fragdmsgs) {
188*12869SKacheong.Poon@Sun.COM 			SCTPS_UPDATE_MIB(sctps, sctpFragUsrMsgs,
1890Sstevel@tonic-gate 			    sctp->sctp_fragdmsgs);
1900Sstevel@tonic-gate 			sctp->sctp_fragdmsgs = 0;
1910Sstevel@tonic-gate 		}
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate 		if (sctp->sctp_reassmsgs) {
194*12869SKacheong.Poon@Sun.COM 			SCTPS_UPDATE_MIB(sctps, sctpReasmUsrMsgs,
1950Sstevel@tonic-gate 			    sctp->sctp_reassmsgs);
1960Sstevel@tonic-gate 			sctp->sctp_reassmsgs = 0;
1970Sstevel@tonic-gate 		}
1980Sstevel@tonic-gate 
1990Sstevel@tonic-gate next_sctp:
2000Sstevel@tonic-gate 		sctp_prev = sctp;
2013448Sdh155122 		mutex_enter(&sctps->sctps_g_lock);
2023448Sdh155122 		sctp = list_next(&sctps->sctps_g_list, sctp);
2030Sstevel@tonic-gate 	}
2043448Sdh155122 	mutex_exit(&sctps->sctps_g_lock);
2050Sstevel@tonic-gate 	if (sctp_prev != NULL)
2060Sstevel@tonic-gate 		SCTP_REFRELE(sctp_prev);
2070Sstevel@tonic-gate 
208*12869SKacheong.Poon@Sun.COM 	sctp_sum_mib(sctps, &sctp_mib);
209*12869SKacheong.Poon@Sun.COM 
2100Sstevel@tonic-gate 	/* Copy data from the SCTP MIB */
2110Sstevel@tonic-gate 	sctpkp = (sctp_named_kstat_t *)kp->ks_data;
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 	/* These are from global ndd params. */
2143448Sdh155122 	sctpkp->sctpRtoMin.value.ui32 = sctps->sctps_rto_ming;
2153448Sdh155122 	sctpkp->sctpRtoMax.value.ui32 = sctps->sctps_rto_maxg;
2163448Sdh155122 	sctpkp->sctpRtoInitial.value.ui32 = sctps->sctps_rto_initialg;
2173448Sdh155122 	sctpkp->sctpValCookieLife.value.ui32 = sctps->sctps_cookie_life;
2183448Sdh155122 	sctpkp->sctpMaxInitRetr.value.ui32 = sctps->sctps_max_init_retr;
2190Sstevel@tonic-gate 
220*12869SKacheong.Poon@Sun.COM 	/* Copy data from the local sctp_mib to the provided kstat. */
221*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpCurrEstab.value.i32 = sctp_mib.sctpCurrEstab;
222*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpActiveEstab.value.i32 = sctp_mib.sctpActiveEstab;
223*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpPassiveEstab.value.i32 = sctp_mib.sctpPassiveEstab;
224*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpAborted.value.i32 = sctp_mib.sctpAborted;
225*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpShutdowns.value.i32 = sctp_mib.sctpShutdowns;
226*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpOutOfBlue.value.i32 = sctp_mib.sctpOutOfBlue;
227*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpChecksumError.value.i32 = sctp_mib.sctpChecksumError;
228*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpOutCtrlChunks.value.i64 = sctp_mib.sctpOutCtrlChunks;
229*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpOutOrderChunks.value.i64 = sctp_mib.sctpOutOrderChunks;
230*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpOutUnorderChunks.value.i64 = sctp_mib.sctpOutUnorderChunks;
231*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpRetransChunks.value.i64 = sctp_mib.sctpRetransChunks;
232*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpOutAck.value.i32 = sctp_mib.sctpOutAck;
233*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpOutAckDelayed.value.i32 = sctp_mib.sctpOutAckDelayed;
234*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpOutWinUpdate.value.i32 = sctp_mib.sctpOutWinUpdate;
235*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpOutFastRetrans.value.i32 = sctp_mib.sctpOutFastRetrans;
236*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpOutWinProbe.value.i32 = sctp_mib.sctpOutWinProbe;
237*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpInCtrlChunks.value.i64 = sctp_mib.sctpInCtrlChunks;
238*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpInOrderChunks.value.i64 = sctp_mib.sctpInOrderChunks;
239*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpInUnorderChunks.value.i64 = sctp_mib.sctpInUnorderChunks;
240*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpInAck.value.i32 = sctp_mib.sctpInAck;
241*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpInDupAck.value.i32 = sctp_mib.sctpInDupAck;
242*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpInAckUnsent.value.i32 = sctp_mib.sctpInAckUnsent;
243*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpFragUsrMsgs.value.i64 = sctp_mib.sctpFragUsrMsgs;
244*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpReasmUsrMsgs.value.i64 = sctp_mib.sctpReasmUsrMsgs;
245*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpOutSCTPPkts.value.i64 = sctp_mib.sctpOutSCTPPkts;
246*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpInSCTPPkts.value.i64 = sctp_mib.sctpInSCTPPkts;
247*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpInInvalidCookie.value.i32 = sctp_mib.sctpInInvalidCookie;
248*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpTimRetrans.value.i32 = sctp_mib.sctpTimRetrans;
249*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpTimRetransDrop.value.i32 = sctp_mib.sctpTimRetransDrop;
2500Sstevel@tonic-gate 	sctpkp->sctpTimHeartBeatProbe.value.i32 =
251*12869SKacheong.Poon@Sun.COM 	    sctp_mib.sctpTimHeartBeatProbe;
252*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpTimHeartBeatDrop.value.i32 = sctp_mib.sctpTimHeartBeatDrop;
253*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpListenDrop.value.i32 = sctp_mib.sctpListenDrop;
254*12869SKacheong.Poon@Sun.COM 	sctpkp->sctpInClosed.value.i32 = sctp_mib.sctpInClosed;
2550Sstevel@tonic-gate 
2563448Sdh155122 	netstack_rele(ns);
2570Sstevel@tonic-gate 	return (0);
2580Sstevel@tonic-gate }
2590Sstevel@tonic-gate 
2603448Sdh155122 void *
2613448Sdh155122 sctp_kstat_init(netstackid_t stackid)
2620Sstevel@tonic-gate {
2633448Sdh155122 	kstat_t	*ksp;
2643448Sdh155122 
2650Sstevel@tonic-gate 	sctp_named_kstat_t template = {
2660Sstevel@tonic-gate 		{ "sctpRtoAlgorithm",		KSTAT_DATA_INT32, 0 },
2670Sstevel@tonic-gate 		{ "sctpRtoMin",			KSTAT_DATA_UINT32, 0 },
2680Sstevel@tonic-gate 		{ "sctpRtoMax",			KSTAT_DATA_UINT32, 0 },
2690Sstevel@tonic-gate 		{ "sctpRtoInitial",		KSTAT_DATA_UINT32, 0 },
2700Sstevel@tonic-gate 		{ "sctpMaxAssocs",		KSTAT_DATA_INT32, 0 },
2710Sstevel@tonic-gate 		{ "sctpValCookieLife",		KSTAT_DATA_UINT32, 0 },
2720Sstevel@tonic-gate 		{ "sctpMaxInitRetr",		KSTAT_DATA_UINT32, 0 },
2730Sstevel@tonic-gate 		{ "sctpCurrEstab",		KSTAT_DATA_INT32, 0 },
2740Sstevel@tonic-gate 		{ "sctpActiveEstab",		KSTAT_DATA_INT32, 0 },
2750Sstevel@tonic-gate 		{ "sctpPassiveEstab",		KSTAT_DATA_INT32, 0 },
2760Sstevel@tonic-gate 		{ "sctpAborted",		KSTAT_DATA_INT32, 0 },
2770Sstevel@tonic-gate 		{ "sctpShutdowns",		KSTAT_DATA_INT32, 0 },
2780Sstevel@tonic-gate 		{ "sctpOutOfBlue",		KSTAT_DATA_INT32, 0 },
2790Sstevel@tonic-gate 		{ "sctpChecksumError",		KSTAT_DATA_INT32, 0 },
2800Sstevel@tonic-gate 		{ "sctpOutCtrlChunks",		KSTAT_DATA_INT64, 0 },
2810Sstevel@tonic-gate 		{ "sctpOutOrderChunks",		KSTAT_DATA_INT64, 0 },
2820Sstevel@tonic-gate 		{ "sctpOutUnorderChunks",	KSTAT_DATA_INT64, 0 },
2830Sstevel@tonic-gate 		{ "sctpRetransChunks",		KSTAT_DATA_INT64, 0 },
2840Sstevel@tonic-gate 		{ "sctpOutAck",			KSTAT_DATA_INT32, 0 },
2850Sstevel@tonic-gate 		{ "sctpOutAckDelayed",		KSTAT_DATA_INT32, 0 },
2860Sstevel@tonic-gate 		{ "sctpOutWinUpdate",		KSTAT_DATA_INT32, 0 },
2870Sstevel@tonic-gate 		{ "sctpOutFastRetrans",		KSTAT_DATA_INT32, 0 },
2880Sstevel@tonic-gate 		{ "sctpOutWinProbe",		KSTAT_DATA_INT32, 0 },
2890Sstevel@tonic-gate 		{ "sctpInCtrlChunks",		KSTAT_DATA_INT64, 0 },
2900Sstevel@tonic-gate 		{ "sctpInOrderChunks",		KSTAT_DATA_INT64, 0 },
2910Sstevel@tonic-gate 		{ "sctpInUnorderChunks",	KSTAT_DATA_INT64, 0 },
2920Sstevel@tonic-gate 		{ "sctpInAck",			KSTAT_DATA_INT32, 0 },
2930Sstevel@tonic-gate 		{ "sctpInDupAck",		KSTAT_DATA_INT32, 0 },
2940Sstevel@tonic-gate 		{ "sctpInAckUnsent",		KSTAT_DATA_INT32, 0 },
2950Sstevel@tonic-gate 		{ "sctpFragUsrMsgs",		KSTAT_DATA_INT64, 0 },
2960Sstevel@tonic-gate 		{ "sctpReasmUsrMsgs",		KSTAT_DATA_INT64, 0 },
2970Sstevel@tonic-gate 		{ "sctpOutSCTPPkts",		KSTAT_DATA_INT64, 0 },
2980Sstevel@tonic-gate 		{ "sctpInSCTPPkts",		KSTAT_DATA_INT64, 0 },
2990Sstevel@tonic-gate 		{ "sctpInInvalidCookie",	KSTAT_DATA_INT32, 0 },
3000Sstevel@tonic-gate 		{ "sctpTimRetrans",		KSTAT_DATA_INT32, 0 },
3010Sstevel@tonic-gate 		{ "sctpTimRetransDrop",		KSTAT_DATA_INT32, 0 },
3020Sstevel@tonic-gate 		{ "sctpTimHearBeatProbe",	KSTAT_DATA_INT32, 0 },
3030Sstevel@tonic-gate 		{ "sctpTimHearBeatDrop",	KSTAT_DATA_INT32, 0 },
3040Sstevel@tonic-gate 		{ "sctpListenDrop",		KSTAT_DATA_INT32, 0 },
3050Sstevel@tonic-gate 		{ "sctpInClosed",		KSTAT_DATA_INT32, 0 }
3060Sstevel@tonic-gate 	};
3070Sstevel@tonic-gate 
3083448Sdh155122 	ksp = kstat_create_netstack(SCTP_MOD_NAME, 0, "sctp", "mib2",
3093448Sdh155122 	    KSTAT_TYPE_NAMED, NUM_OF_FIELDS(sctp_named_kstat_t), 0, stackid);
3100Sstevel@tonic-gate 
311*12869SKacheong.Poon@Sun.COM 	if (ksp == NULL)
3123448Sdh155122 		return (NULL);
3130Sstevel@tonic-gate 
3140Sstevel@tonic-gate 	/* These won't change. */
3150Sstevel@tonic-gate 	template.sctpRtoAlgorithm.value.i32 = MIB2_SCTP_RTOALGO_VANJ;
3160Sstevel@tonic-gate 	template.sctpMaxAssocs.value.i32 = -1;
3170Sstevel@tonic-gate 
3183448Sdh155122 	bcopy(&template, ksp->ks_data, sizeof (template));
3193448Sdh155122 	ksp->ks_update = sctp_kstat_update;
3203448Sdh155122 	ksp->ks_private = (void *)(uintptr_t)stackid;
3213448Sdh155122 
3223448Sdh155122 	kstat_install(ksp);
3233448Sdh155122 	return (ksp);
3243448Sdh155122 }
3250Sstevel@tonic-gate 
3263448Sdh155122 /*
327*12869SKacheong.Poon@Sun.COM  * To set all sctp_stat_t counters to 0.
328*12869SKacheong.Poon@Sun.COM  */
329*12869SKacheong.Poon@Sun.COM static void
330*12869SKacheong.Poon@Sun.COM sctp_clr_kstats2(sctp_kstat_t *stats)
331*12869SKacheong.Poon@Sun.COM {
332*12869SKacheong.Poon@Sun.COM 	stats->sctp_add_faddr.value.ui64 = 0;
333*12869SKacheong.Poon@Sun.COM 	stats->sctp_add_timer.value.ui64 = 0;
334*12869SKacheong.Poon@Sun.COM 	stats->sctp_conn_create.value.ui64 = 0;
335*12869SKacheong.Poon@Sun.COM 	stats->sctp_find_next_tq.value.ui64 = 0;
336*12869SKacheong.Poon@Sun.COM 	stats->sctp_fr_add_hdr.value.ui64 = 0;
337*12869SKacheong.Poon@Sun.COM 	stats->sctp_fr_not_found.value.ui64 = 0;
338*12869SKacheong.Poon@Sun.COM 	stats->sctp_output_failed.value.ui64 = 0;
339*12869SKacheong.Poon@Sun.COM 	stats->sctp_rexmit_failed.value.ui64 = 0;
340*12869SKacheong.Poon@Sun.COM 	stats->sctp_send_init_failed.value.ui64 = 0;
341*12869SKacheong.Poon@Sun.COM 	stats->sctp_send_cookie_failed.value.ui64 = 0;
342*12869SKacheong.Poon@Sun.COM 	stats->sctp_send_cookie_ack_failed.value.ui64 = 0;
343*12869SKacheong.Poon@Sun.COM 	stats->sctp_send_err_failed.value.ui64 = 0;
344*12869SKacheong.Poon@Sun.COM 	stats->sctp_send_sack_failed.value.ui64 = 0;
345*12869SKacheong.Poon@Sun.COM 	stats->sctp_send_shutdown_failed.value.ui64 = 0;
346*12869SKacheong.Poon@Sun.COM 	stats->sctp_send_shutdown_ack_failed.value.ui64 = 0;
347*12869SKacheong.Poon@Sun.COM 	stats->sctp_send_shutdown_comp_failed.value.ui64 = 0;
348*12869SKacheong.Poon@Sun.COM 	stats->sctp_send_user_abort_failed.value.ui64 = 0;
349*12869SKacheong.Poon@Sun.COM 	stats->sctp_send_asconf_failed.value.ui64 = 0;
350*12869SKacheong.Poon@Sun.COM 	stats->sctp_send_asconf_ack_failed.value.ui64 = 0;
351*12869SKacheong.Poon@Sun.COM 	stats->sctp_send_ftsn_failed.value.ui64 = 0;
352*12869SKacheong.Poon@Sun.COM 	stats->sctp_send_hb_failed.value.ui64 = 0;
353*12869SKacheong.Poon@Sun.COM 	stats->sctp_return_hb_failed.value.ui64 = 0;
354*12869SKacheong.Poon@Sun.COM 	stats->sctp_ss_rexmit_failed.value.ui64 = 0;
355*12869SKacheong.Poon@Sun.COM 	stats->sctp_cl_connect.value.ui64 = 0;
356*12869SKacheong.Poon@Sun.COM 	stats->sctp_cl_assoc_change.value.ui64 = 0;
357*12869SKacheong.Poon@Sun.COM 	stats->sctp_cl_check_addrs.value.ui64 = 0;
358*12869SKacheong.Poon@Sun.COM 	stats->sctp_reclaim_cnt.value.ui64 = 0;
359*12869SKacheong.Poon@Sun.COM 	stats->sctp_listen_cnt_drop.value.ui64 = 0;
360*12869SKacheong.Poon@Sun.COM }
361*12869SKacheong.Poon@Sun.COM 
362*12869SKacheong.Poon@Sun.COM /*
363*12869SKacheong.Poon@Sun.COM  * To add counters from the per CPU sctp_kstat_counter_t to the stack
364*12869SKacheong.Poon@Sun.COM  * sctp_kstat_t.
365*12869SKacheong.Poon@Sun.COM  */
366*12869SKacheong.Poon@Sun.COM static void
367*12869SKacheong.Poon@Sun.COM sctp_add_kstats2(sctp_kstat_counter_t *from, sctp_kstat_t *to)
368*12869SKacheong.Poon@Sun.COM {
369*12869SKacheong.Poon@Sun.COM 	to->sctp_add_faddr.value.ui64 += from->sctp_add_faddr;
370*12869SKacheong.Poon@Sun.COM 	to->sctp_add_timer.value.ui64 += from->sctp_add_timer;
371*12869SKacheong.Poon@Sun.COM 	to->sctp_conn_create.value.ui64 += from->sctp_conn_create;
372*12869SKacheong.Poon@Sun.COM 	to->sctp_find_next_tq.value.ui64 += from->sctp_find_next_tq;
373*12869SKacheong.Poon@Sun.COM 	to->sctp_fr_add_hdr.value.ui64 += from->sctp_fr_add_hdr;
374*12869SKacheong.Poon@Sun.COM 	to->sctp_fr_not_found.value.ui64 += from->sctp_fr_not_found;
375*12869SKacheong.Poon@Sun.COM 	to->sctp_output_failed.value.ui64 += from->sctp_output_failed;
376*12869SKacheong.Poon@Sun.COM 	to->sctp_rexmit_failed.value.ui64 += from->sctp_rexmit_failed;
377*12869SKacheong.Poon@Sun.COM 	to->sctp_send_init_failed.value.ui64 += from->sctp_send_init_failed;
378*12869SKacheong.Poon@Sun.COM 	to->sctp_send_cookie_failed.value.ui64 += from->sctp_send_cookie_failed;
379*12869SKacheong.Poon@Sun.COM 	to->sctp_send_cookie_ack_failed.value.ui64 +=
380*12869SKacheong.Poon@Sun.COM 	    from->sctp_send_cookie_ack_failed;
381*12869SKacheong.Poon@Sun.COM 	to->sctp_send_err_failed.value.ui64 += from->sctp_send_err_failed;
382*12869SKacheong.Poon@Sun.COM 	to->sctp_send_sack_failed.value.ui64 += from->sctp_send_sack_failed;
383*12869SKacheong.Poon@Sun.COM 	to->sctp_send_shutdown_failed.value.ui64 +=
384*12869SKacheong.Poon@Sun.COM 	    from->sctp_send_shutdown_failed;
385*12869SKacheong.Poon@Sun.COM 	to->sctp_send_shutdown_ack_failed.value.ui64 +=
386*12869SKacheong.Poon@Sun.COM 	    from->sctp_send_shutdown_ack_failed;
387*12869SKacheong.Poon@Sun.COM 	to->sctp_send_shutdown_comp_failed.value.ui64 +=
388*12869SKacheong.Poon@Sun.COM 	    from->sctp_send_shutdown_comp_failed;
389*12869SKacheong.Poon@Sun.COM 	to->sctp_send_user_abort_failed.value.ui64 +=
390*12869SKacheong.Poon@Sun.COM 	    from->sctp_send_user_abort_failed;
391*12869SKacheong.Poon@Sun.COM 	to->sctp_send_asconf_failed.value.ui64 += from->sctp_send_asconf_failed;
392*12869SKacheong.Poon@Sun.COM 	to->sctp_send_asconf_ack_failed.value.ui64 +=
393*12869SKacheong.Poon@Sun.COM 	    from->sctp_send_asconf_ack_failed;
394*12869SKacheong.Poon@Sun.COM 	to->sctp_send_ftsn_failed.value.ui64 += from->sctp_send_ftsn_failed;
395*12869SKacheong.Poon@Sun.COM 	to->sctp_send_hb_failed.value.ui64 += from->sctp_send_hb_failed;
396*12869SKacheong.Poon@Sun.COM 	to->sctp_return_hb_failed.value.ui64 += from->sctp_return_hb_failed;
397*12869SKacheong.Poon@Sun.COM 	to->sctp_ss_rexmit_failed.value.ui64 += from->sctp_ss_rexmit_failed;
398*12869SKacheong.Poon@Sun.COM 	to->sctp_cl_connect.value.ui64 += from->sctp_cl_connect;
399*12869SKacheong.Poon@Sun.COM 	to->sctp_cl_assoc_change.value.ui64 += from->sctp_cl_assoc_change;
400*12869SKacheong.Poon@Sun.COM 	to->sctp_cl_check_addrs.value.ui64 += from->sctp_cl_check_addrs;
401*12869SKacheong.Poon@Sun.COM }
402*12869SKacheong.Poon@Sun.COM 
403*12869SKacheong.Poon@Sun.COM /*
404*12869SKacheong.Poon@Sun.COM  * Sum up all per CPU tcp_stat_t kstat counters.
405*12869SKacheong.Poon@Sun.COM  */
406*12869SKacheong.Poon@Sun.COM static int
407*12869SKacheong.Poon@Sun.COM sctp_kstat2_update(kstat_t *kp, int rw)
408*12869SKacheong.Poon@Sun.COM {
409*12869SKacheong.Poon@Sun.COM 	netstackid_t	stackid = (netstackid_t)(uintptr_t)kp->ks_private;
410*12869SKacheong.Poon@Sun.COM 	netstack_t	*ns;
411*12869SKacheong.Poon@Sun.COM 	sctp_stack_t	*sctps;
412*12869SKacheong.Poon@Sun.COM 	sctp_kstat_t	*stats;
413*12869SKacheong.Poon@Sun.COM 	int		i;
414*12869SKacheong.Poon@Sun.COM 	int		cnt;
415*12869SKacheong.Poon@Sun.COM 
416*12869SKacheong.Poon@Sun.COM 	if (rw == KSTAT_WRITE)
417*12869SKacheong.Poon@Sun.COM 		return (EACCES);
418*12869SKacheong.Poon@Sun.COM 
419*12869SKacheong.Poon@Sun.COM 	ns = netstack_find_by_stackid(stackid);
420*12869SKacheong.Poon@Sun.COM 	if (ns == NULL)
421*12869SKacheong.Poon@Sun.COM 		return (-1);
422*12869SKacheong.Poon@Sun.COM 	sctps = ns->netstack_sctp;
423*12869SKacheong.Poon@Sun.COM 	if (sctps == NULL) {
424*12869SKacheong.Poon@Sun.COM 		netstack_rele(ns);
425*12869SKacheong.Poon@Sun.COM 		return (-1);
426*12869SKacheong.Poon@Sun.COM 	}
427*12869SKacheong.Poon@Sun.COM 
428*12869SKacheong.Poon@Sun.COM 	stats = (sctp_kstat_t *)kp->ks_data;
429*12869SKacheong.Poon@Sun.COM 	sctp_clr_kstats2(stats);
430*12869SKacheong.Poon@Sun.COM 
431*12869SKacheong.Poon@Sun.COM 	/*
432*12869SKacheong.Poon@Sun.COM 	 * sctps_sc_cnt may change in the middle of the loop.  It is better
433*12869SKacheong.Poon@Sun.COM 	 * to get its value first.
434*12869SKacheong.Poon@Sun.COM 	 */
435*12869SKacheong.Poon@Sun.COM 	cnt = sctps->sctps_sc_cnt;
436*12869SKacheong.Poon@Sun.COM 	for (i = 0; i < cnt; i++)
437*12869SKacheong.Poon@Sun.COM 		sctp_add_kstats2(&sctps->sctps_sc[i]->sctp_sc_stats, stats);
438*12869SKacheong.Poon@Sun.COM 
439*12869SKacheong.Poon@Sun.COM 	netstack_rele(ns);
440*12869SKacheong.Poon@Sun.COM 	return (0);
441*12869SKacheong.Poon@Sun.COM }
442*12869SKacheong.Poon@Sun.COM 
443*12869SKacheong.Poon@Sun.COM /*
4443448Sdh155122  * The following kstats are for debugging purposes.  They keep
4453448Sdh155122  * track of problems which should not happen normally.  But in
4463448Sdh155122  * those cases which they do happen, these kstats would be handy
4473448Sdh155122  * for engineers to diagnose the problems.  They are not intended
4483448Sdh155122  * to be consumed by customers.
4493448Sdh155122  */
4503448Sdh155122 void *
451*12869SKacheong.Poon@Sun.COM sctp_kstat2_init(netstackid_t stackid)
4523448Sdh155122 {
4533448Sdh155122 	kstat_t *ksp;
4541735Skcpoon 
4553448Sdh155122 	sctp_kstat_t template = {
4563448Sdh155122 		{ "sctp_add_faddr",			KSTAT_DATA_UINT64 },
4573448Sdh155122 		{ "sctp_add_timer",			KSTAT_DATA_UINT64 },
4583448Sdh155122 		{ "sctp_conn_create",			KSTAT_DATA_UINT64 },
4593448Sdh155122 		{ "sctp_find_next_tq",			KSTAT_DATA_UINT64 },
4603448Sdh155122 		{ "sctp_fr_add_hdr",			KSTAT_DATA_UINT64 },
4613448Sdh155122 		{ "sctp_fr_not_found",			KSTAT_DATA_UINT64 },
4623448Sdh155122 		{ "sctp_output_failed",			KSTAT_DATA_UINT64 },
4633448Sdh155122 		{ "sctp_rexmit_failed",			KSTAT_DATA_UINT64 },
4643448Sdh155122 		{ "sctp_send_init_failed",		KSTAT_DATA_UINT64 },
4653448Sdh155122 		{ "sctp_send_cookie_failed",		KSTAT_DATA_UINT64 },
4663448Sdh155122 		{ "sctp_send_cookie_ack_failed",	KSTAT_DATA_UINT64 },
4673448Sdh155122 		{ "sctp_send_err_failed",		KSTAT_DATA_UINT64 },
4683448Sdh155122 		{ "sctp_send_sack_failed",		KSTAT_DATA_UINT64 },
4693448Sdh155122 		{ "sctp_send_shutdown_failed",		KSTAT_DATA_UINT64 },
4703448Sdh155122 		{ "sctp_send_shutdown_ack_failed",	KSTAT_DATA_UINT64 },
4713448Sdh155122 		{ "sctp_send_shutdown_comp_failed",	KSTAT_DATA_UINT64 },
4723448Sdh155122 		{ "sctp_send_user_abort_failed",	KSTAT_DATA_UINT64 },
4733448Sdh155122 		{ "sctp_send_asconf_failed",		KSTAT_DATA_UINT64 },
4743448Sdh155122 		{ "sctp_send_asconf_ack_failed",	KSTAT_DATA_UINT64 },
4753448Sdh155122 		{ "sctp_send_ftsn_failed",		KSTAT_DATA_UINT64 },
4763448Sdh155122 		{ "sctp_send_hb_failed",		KSTAT_DATA_UINT64 },
4773448Sdh155122 		{ "sctp_return_hb_failed",		KSTAT_DATA_UINT64 },
4783448Sdh155122 		{ "sctp_ss_rexmit_failed",		KSTAT_DATA_UINT64 },
4793448Sdh155122 		{ "sctp_cl_connect",			KSTAT_DATA_UINT64 },
4803448Sdh155122 		{ "sctp_cl_assoc_change",		KSTAT_DATA_UINT64 },
4813448Sdh155122 		{ "sctp_cl_check_addrs",		KSTAT_DATA_UINT64 },
482*12869SKacheong.Poon@Sun.COM 		{ "sctp_reclaim_drop",			KSTAT_DATA_UINT64 },
483*12869SKacheong.Poon@Sun.COM 		{ "sctp_listen_cnt_drop",		KSTAT_DATA_UINT64 },
4843448Sdh155122 	};
4853448Sdh155122 
4863448Sdh155122 	ksp = kstat_create_netstack(SCTP_MOD_NAME, 0, "sctpstat", "net",
487*12869SKacheong.Poon@Sun.COM 	    KSTAT_TYPE_NAMED, NUM_OF_FIELDS(template), 0, stackid);
4883448Sdh155122 
4893448Sdh155122 	if (ksp == NULL)
4903448Sdh155122 		return (NULL);
4913448Sdh155122 
492*12869SKacheong.Poon@Sun.COM 	bcopy(&template, ksp->ks_data, sizeof (template));
4933448Sdh155122 	ksp->ks_private = (void *)(uintptr_t)stackid;
494*12869SKacheong.Poon@Sun.COM 	ksp->ks_update = sctp_kstat2_update;
4953448Sdh155122 
4963448Sdh155122 	kstat_install(ksp);
4973448Sdh155122 	return (ksp);
4983448Sdh155122 }
4993448Sdh155122 
5003448Sdh155122 void
5013448Sdh155122 sctp_kstat_fini(netstackid_t stackid, kstat_t *ksp)
5023448Sdh155122 {
5033448Sdh155122 	if (ksp != NULL) {
5043448Sdh155122 		ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
5053448Sdh155122 		kstat_delete_netstack(ksp, stackid);
5061735Skcpoon 	}
5070Sstevel@tonic-gate }
5080Sstevel@tonic-gate 
5090Sstevel@tonic-gate void
5103448Sdh155122 sctp_kstat2_fini(netstackid_t stackid, kstat_t *ksp)
5110Sstevel@tonic-gate {
5123448Sdh155122 	if (ksp != NULL) {
5133448Sdh155122 		ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
5143448Sdh155122 		kstat_delete_netstack(ksp, stackid);
5151735Skcpoon 	}
5160Sstevel@tonic-gate }
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate /*
5190Sstevel@tonic-gate  * Return SNMP global stats in buffer in mpdata.
5200Sstevel@tonic-gate  * Return associatiation table in mp_conn_data,
5210Sstevel@tonic-gate  * local address table in mp_local_data, and
5220Sstevel@tonic-gate  * remote address table in mp_rem_data.
5230Sstevel@tonic-gate  */
5240Sstevel@tonic-gate mblk_t *
5253448Sdh155122 sctp_snmp_get_mib2(queue_t *q, mblk_t *mpctl, sctp_stack_t *sctps)
5260Sstevel@tonic-gate {
5270Sstevel@tonic-gate 	mblk_t			*mpdata, *mp_ret;
5280Sstevel@tonic-gate 	mblk_t			*mp_conn_ctl = NULL;
5290Sstevel@tonic-gate 	mblk_t			*mp_conn_data;
5300Sstevel@tonic-gate 	mblk_t			*mp_conn_tail = NULL;
5310Sstevel@tonic-gate 	mblk_t			*mp_local_ctl = NULL;
5320Sstevel@tonic-gate 	mblk_t			*mp_local_data;
5330Sstevel@tonic-gate 	mblk_t			*mp_local_tail = NULL;
5340Sstevel@tonic-gate 	mblk_t			*mp_rem_ctl = NULL;
5350Sstevel@tonic-gate 	mblk_t			*mp_rem_data;
5360Sstevel@tonic-gate 	mblk_t			*mp_rem_tail = NULL;
5371676Sjpk 	mblk_t			*mp_attr_ctl = NULL;
5381676Sjpk 	mblk_t			*mp_attr_data;
5391676Sjpk 	mblk_t			*mp_attr_tail = NULL;
5400Sstevel@tonic-gate 	struct opthdr		*optp;
5410Sstevel@tonic-gate 	sctp_t			*sctp, *sctp_prev = NULL;
5420Sstevel@tonic-gate 	sctp_faddr_t		*fp;
5430Sstevel@tonic-gate 	mib2_sctpConnEntry_t	sce;
5440Sstevel@tonic-gate 	mib2_sctpConnLocalEntry_t	scle;
5450Sstevel@tonic-gate 	mib2_sctpConnRemoteEntry_t	scre;
5461676Sjpk 	mib2_transportMLPEntry_t	mlp;
5470Sstevel@tonic-gate 	int			i;
5480Sstevel@tonic-gate 	int			l;
5490Sstevel@tonic-gate 	int			scanned = 0;
5500Sstevel@tonic-gate 	zoneid_t		zoneid = Q_TO_CONN(q)->conn_zoneid;
5511676Sjpk 	conn_t			*connp;
5521676Sjpk 	boolean_t		needattr;
5531676Sjpk 	int			idx;
554*12869SKacheong.Poon@Sun.COM 	mib2_sctp_t		sctp_mib;
5550Sstevel@tonic-gate 
5560Sstevel@tonic-gate 	/*
5570Sstevel@tonic-gate 	 * Make copies of the original message.
5580Sstevel@tonic-gate 	 * mpctl will hold SCTP counters,
5590Sstevel@tonic-gate 	 * mp_conn_ctl will hold list of connections.
5600Sstevel@tonic-gate 	 */
5610Sstevel@tonic-gate 	mp_ret = copymsg(mpctl);
5620Sstevel@tonic-gate 	mp_conn_ctl = copymsg(mpctl);
5630Sstevel@tonic-gate 	mp_local_ctl = copymsg(mpctl);
5640Sstevel@tonic-gate 	mp_rem_ctl = copymsg(mpctl);
5651676Sjpk 	mp_attr_ctl = copymsg(mpctl);
5660Sstevel@tonic-gate 
5670Sstevel@tonic-gate 	mpdata = mpctl->b_cont;
5680Sstevel@tonic-gate 
5691676Sjpk 	if (mp_conn_ctl == NULL || mp_local_ctl == NULL ||
5701676Sjpk 	    mp_rem_ctl == NULL || mp_attr_ctl == NULL || mpdata == NULL) {
5711676Sjpk 		freemsg(mp_attr_ctl);
5720Sstevel@tonic-gate 		freemsg(mp_rem_ctl);
5730Sstevel@tonic-gate 		freemsg(mp_local_ctl);
5740Sstevel@tonic-gate 		freemsg(mp_conn_ctl);
5750Sstevel@tonic-gate 		freemsg(mp_ret);
5760Sstevel@tonic-gate 		freemsg(mpctl);
5770Sstevel@tonic-gate 		return (NULL);
5780Sstevel@tonic-gate 	}
5790Sstevel@tonic-gate 	mp_conn_data = mp_conn_ctl->b_cont;
5800Sstevel@tonic-gate 	mp_local_data = mp_local_ctl->b_cont;
5810Sstevel@tonic-gate 	mp_rem_data = mp_rem_ctl->b_cont;
5821676Sjpk 	mp_attr_data = mp_attr_ctl->b_cont;
5830Sstevel@tonic-gate 
584*12869SKacheong.Poon@Sun.COM 	bzero(&sctp_mib, sizeof (sctp_mib));
585*12869SKacheong.Poon@Sun.COM 
5860Sstevel@tonic-gate 	/* hostname address parameters are not supported in Solaris */
5870Sstevel@tonic-gate 	sce.sctpAssocRemHostName.o_length = 0;
5880Sstevel@tonic-gate 	sce.sctpAssocRemHostName.o_bytes[0] = 0;
5890Sstevel@tonic-gate 
5900Sstevel@tonic-gate 	/* build table of connections -- need count in fixed part */
5910Sstevel@tonic-gate 
5921676Sjpk 	idx = 0;
5933448Sdh155122 	mutex_enter(&sctps->sctps_g_lock);
59411042SErik.Nordmark@Sun.COM 	sctp = list_head(&sctps->sctps_g_list);
5950Sstevel@tonic-gate 	while (sctp != NULL) {
5960Sstevel@tonic-gate 		mutex_enter(&sctp->sctp_reflock);
5970Sstevel@tonic-gate 		if (sctp->sctp_condemned) {
5980Sstevel@tonic-gate 			mutex_exit(&sctp->sctp_reflock);
5993448Sdh155122 			sctp = list_next(&sctps->sctps_g_list, sctp);
6000Sstevel@tonic-gate 			continue;
6010Sstevel@tonic-gate 		}
6020Sstevel@tonic-gate 		sctp->sctp_refcnt++;
6030Sstevel@tonic-gate 		mutex_exit(&sctp->sctp_reflock);
6043448Sdh155122 		mutex_exit(&sctps->sctps_g_lock);
6050Sstevel@tonic-gate 		if (sctp_prev != NULL)
6060Sstevel@tonic-gate 			SCTP_REFRELE(sctp_prev);
6070Sstevel@tonic-gate 		if (sctp->sctp_connp->conn_zoneid != zoneid)
6080Sstevel@tonic-gate 			goto next_sctp;
6090Sstevel@tonic-gate 		if (sctp->sctp_state == SCTPS_ESTABLISHED ||
6100Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_PENDING ||
6110Sstevel@tonic-gate 		    sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) {
612*12869SKacheong.Poon@Sun.COM 			/*
613*12869SKacheong.Poon@Sun.COM 			 * Just bump the local sctp_mib.  The number of
614*12869SKacheong.Poon@Sun.COM 			 * existing associations is not kept in kernel.
615*12869SKacheong.Poon@Sun.COM 			 */
616*12869SKacheong.Poon@Sun.COM 			BUMP_MIB(&sctp_mib, sctpCurrEstab);
6170Sstevel@tonic-gate 		}
618*12869SKacheong.Poon@Sun.COM 		SCTPS_UPDATE_MIB(sctps, sctpOutSCTPPkts, sctp->sctp_opkts);
6190Sstevel@tonic-gate 		sctp->sctp_opkts = 0;
620*12869SKacheong.Poon@Sun.COM 		SCTPS_UPDATE_MIB(sctps, sctpOutCtrlChunks, sctp->sctp_obchunks);
62110751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_obchunks,
62210751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_obchunks);
6230Sstevel@tonic-gate 		sctp->sctp_obchunks = 0;
624*12869SKacheong.Poon@Sun.COM 		SCTPS_UPDATE_MIB(sctps, sctpOutOrderChunks,
625*12869SKacheong.Poon@Sun.COM 		    sctp->sctp_odchunks);
62610751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_odchunks,
62710751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_odchunks);
6280Sstevel@tonic-gate 		sctp->sctp_odchunks = 0;
629*12869SKacheong.Poon@Sun.COM 		SCTPS_UPDATE_MIB(sctps, sctpOutUnorderChunks,
6300Sstevel@tonic-gate 		    sctp->sctp_oudchunks);
63110751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_oudchunks,
63210751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_oudchunks);
6330Sstevel@tonic-gate 		sctp->sctp_oudchunks = 0;
634*12869SKacheong.Poon@Sun.COM 		SCTPS_UPDATE_MIB(sctps, sctpRetransChunks,
635*12869SKacheong.Poon@Sun.COM 		    sctp->sctp_rxtchunks);
63610751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_rxtchunks,
63710751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_rxtchunks);
6380Sstevel@tonic-gate 		sctp->sctp_rxtchunks = 0;
639*12869SKacheong.Poon@Sun.COM 		SCTPS_UPDATE_MIB(sctps, sctpInSCTPPkts, sctp->sctp_ipkts);
6400Sstevel@tonic-gate 		sctp->sctp_ipkts = 0;
641*12869SKacheong.Poon@Sun.COM 		SCTPS_UPDATE_MIB(sctps, sctpInCtrlChunks, sctp->sctp_ibchunks);
64210751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_ibchunks,
64310751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_ibchunks);
6440Sstevel@tonic-gate 		sctp->sctp_ibchunks = 0;
645*12869SKacheong.Poon@Sun.COM 		SCTPS_UPDATE_MIB(sctps, sctpInOrderChunks, sctp->sctp_idchunks);
64610751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_idchunks,
64710751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_idchunks);
6480Sstevel@tonic-gate 		sctp->sctp_idchunks = 0;
649*12869SKacheong.Poon@Sun.COM 		SCTPS_UPDATE_MIB(sctps, sctpInUnorderChunks,
6500Sstevel@tonic-gate 		    sctp->sctp_iudchunks);
65110751SGeorge.Shepherd@Sun.COM 		UPDATE_LOCAL(sctp->sctp_cum_iudchunks,
65210751SGeorge.Shepherd@Sun.COM 		    sctp->sctp_iudchunks);
6530Sstevel@tonic-gate 		sctp->sctp_iudchunks = 0;
654*12869SKacheong.Poon@Sun.COM 		SCTPS_UPDATE_MIB(sctps, sctpFragUsrMsgs, sctp->sctp_fragdmsgs);
6550Sstevel@tonic-gate 		sctp->sctp_fragdmsgs = 0;
656*12869SKacheong.Poon@Sun.COM 		SCTPS_UPDATE_MIB(sctps, sctpReasmUsrMsgs, sctp->sctp_reassmsgs);
6570Sstevel@tonic-gate 		sctp->sctp_reassmsgs = 0;
6580Sstevel@tonic-gate 
6590Sstevel@tonic-gate 		sce.sctpAssocId = ntohl(sctp->sctp_lvtag);
66011042SErik.Nordmark@Sun.COM 		sce.sctpAssocLocalPort = ntohs(sctp->sctp_connp->conn_lport);
66111042SErik.Nordmark@Sun.COM 		sce.sctpAssocRemPort = ntohs(sctp->sctp_connp->conn_fport);
6620Sstevel@tonic-gate 
6630Sstevel@tonic-gate 		RUN_SCTP(sctp);
6640Sstevel@tonic-gate 		if (sctp->sctp_primary != NULL) {
6650Sstevel@tonic-gate 			fp = sctp->sctp_primary;
6660Sstevel@tonic-gate 
6670Sstevel@tonic-gate 			if (IN6_IS_ADDR_V4MAPPED(&fp->faddr)) {
6680Sstevel@tonic-gate 				sce.sctpAssocRemPrimAddrType =
6690Sstevel@tonic-gate 				    MIB2_SCTP_ADDR_V4;
6700Sstevel@tonic-gate 			} else {
6710Sstevel@tonic-gate 				sce.sctpAssocRemPrimAddrType =
6720Sstevel@tonic-gate 				    MIB2_SCTP_ADDR_V6;
6730Sstevel@tonic-gate 			}
6740Sstevel@tonic-gate 			sce.sctpAssocRemPrimAddr = fp->faddr;
6750Sstevel@tonic-gate 			sce.sctpAssocLocPrimAddr = fp->saddr;
6760Sstevel@tonic-gate 			sce.sctpAssocHeartBeatInterval = TICK_TO_MSEC(
6770Sstevel@tonic-gate 			    fp->hb_interval);
6780Sstevel@tonic-gate 		} else {
6790Sstevel@tonic-gate 			sce.sctpAssocRemPrimAddrType = MIB2_SCTP_ADDR_V4;
6800Sstevel@tonic-gate 			bzero(&sce.sctpAssocRemPrimAddr,
6810Sstevel@tonic-gate 			    sizeof (sce.sctpAssocRemPrimAddr));
6820Sstevel@tonic-gate 			bzero(&sce.sctpAssocLocPrimAddr,
6830Sstevel@tonic-gate 			    sizeof (sce.sctpAssocLocPrimAddr));
6840Sstevel@tonic-gate 			sce.sctpAssocHeartBeatInterval =
6853448Sdh155122 			    sctps->sctps_heartbeat_interval;
6860Sstevel@tonic-gate 		}
6870Sstevel@tonic-gate 
6880Sstevel@tonic-gate 		/*
6890Sstevel@tonic-gate 		 * Table for local addresses
6900Sstevel@tonic-gate 		 */
6910Sstevel@tonic-gate 		scanned = 0;
6920Sstevel@tonic-gate 		for (i = 0; i < SCTP_IPIF_HASH; i++) {
6930Sstevel@tonic-gate 			sctp_saddr_ipif_t	*obj;
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate 			if (sctp->sctp_saddrs[i].ipif_count == 0)
6960Sstevel@tonic-gate 				continue;
6970Sstevel@tonic-gate 			obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
6980Sstevel@tonic-gate 			for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
6990Sstevel@tonic-gate 				sctp_ipif_t	*sctp_ipif;
7000Sstevel@tonic-gate 				in6_addr_t	addr;
7010Sstevel@tonic-gate 
7020Sstevel@tonic-gate 				sctp_ipif = obj->saddr_ipifp;
7030Sstevel@tonic-gate 				addr = sctp_ipif->sctp_ipif_saddr;
7040Sstevel@tonic-gate 				scanned++;
7050Sstevel@tonic-gate 				scle.sctpAssocId = ntohl(sctp->sctp_lvtag);
7060Sstevel@tonic-gate 				if (IN6_IS_ADDR_V4MAPPED(&addr)) {
7070Sstevel@tonic-gate 					scle.sctpAssocLocalAddrType =
7080Sstevel@tonic-gate 					    MIB2_SCTP_ADDR_V4;
7090Sstevel@tonic-gate 				} else {
7100Sstevel@tonic-gate 					scle.sctpAssocLocalAddrType =
7110Sstevel@tonic-gate 					    MIB2_SCTP_ADDR_V6;
7120Sstevel@tonic-gate 				}
7130Sstevel@tonic-gate 				scle.sctpAssocLocalAddr = addr;
7140Sstevel@tonic-gate 				(void) snmp_append_data2(mp_local_data,
7150Sstevel@tonic-gate 				    &mp_local_tail, (char *)&scle,
7160Sstevel@tonic-gate 				    sizeof (scle));
7170Sstevel@tonic-gate 				if (scanned >= sctp->sctp_nsaddrs)
7180Sstevel@tonic-gate 					goto done;
7190Sstevel@tonic-gate 				obj = list_next(&sctp->
7200Sstevel@tonic-gate 				    sctp_saddrs[i].sctp_ipif_list, obj);
7210Sstevel@tonic-gate 			}
7220Sstevel@tonic-gate 		}
7230Sstevel@tonic-gate done:
7240Sstevel@tonic-gate 		/*
7250Sstevel@tonic-gate 		 * Table for remote addresses
7260Sstevel@tonic-gate 		 */
7270Sstevel@tonic-gate 		for (fp = sctp->sctp_faddrs; fp; fp = fp->next) {
7280Sstevel@tonic-gate 			scre.sctpAssocId = ntohl(sctp->sctp_lvtag);
7290Sstevel@tonic-gate 			if (IN6_IS_ADDR_V4MAPPED(&fp->faddr)) {
7300Sstevel@tonic-gate 				scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V4;
7310Sstevel@tonic-gate 			} else {
7320Sstevel@tonic-gate 				scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V6;
7330Sstevel@tonic-gate 			}
7340Sstevel@tonic-gate 			scre.sctpAssocRemAddr = fp->faddr;
7350Sstevel@tonic-gate 			if (fp->state == SCTP_FADDRS_ALIVE) {
7360Sstevel@tonic-gate 				scre.sctpAssocRemAddrActive =
7370Sstevel@tonic-gate 				    scre.sctpAssocRemAddrHBActive =
7380Sstevel@tonic-gate 				    MIB2_SCTP_ACTIVE;
7390Sstevel@tonic-gate 			} else {
7400Sstevel@tonic-gate 				scre.sctpAssocRemAddrActive =
7410Sstevel@tonic-gate 				    scre.sctpAssocRemAddrHBActive =
7420Sstevel@tonic-gate 				    MIB2_SCTP_INACTIVE;
7430Sstevel@tonic-gate 			}
7440Sstevel@tonic-gate 			scre.sctpAssocRemAddrRTO = TICK_TO_MSEC(fp->rto);
7450Sstevel@tonic-gate 			scre.sctpAssocRemAddrMaxPathRtx = fp->max_retr;
7460Sstevel@tonic-gate 			scre.sctpAssocRemAddrRtx = fp->T3expire;
7470Sstevel@tonic-gate 			(void) snmp_append_data2(mp_rem_data, &mp_rem_tail,
7480Sstevel@tonic-gate 			    (char *)&scre, sizeof (scre));
7490Sstevel@tonic-gate 		}
7501676Sjpk 		connp = sctp->sctp_connp;
7511676Sjpk 		needattr = B_FALSE;
7521676Sjpk 		bzero(&mlp, sizeof (mlp));
7531676Sjpk 		if (connp->conn_mlp_type != mlptSingle) {
7541676Sjpk 			if (connp->conn_mlp_type == mlptShared ||
7551676Sjpk 			    connp->conn_mlp_type == mlptBoth)
7561676Sjpk 				mlp.tme_flags |= MIB2_TMEF_SHARED;
7571676Sjpk 			if (connp->conn_mlp_type == mlptPrivate ||
7581676Sjpk 			    connp->conn_mlp_type == mlptBoth)
7591676Sjpk 				mlp.tme_flags |= MIB2_TMEF_PRIVATE;
7601676Sjpk 			needattr = B_TRUE;
7611676Sjpk 		}
7629710SKen.Powell@Sun.COM 		if (connp->conn_anon_mlp) {
7639710SKen.Powell@Sun.COM 			mlp.tme_flags |= MIB2_TMEF_ANONMLP;
7649710SKen.Powell@Sun.COM 			needattr = B_TRUE;
7659710SKen.Powell@Sun.COM 		}
76610934Ssommerfeld@sun.com 		switch (connp->conn_mac_mode) {
76710934Ssommerfeld@sun.com 		case CONN_MAC_DEFAULT:
76810934Ssommerfeld@sun.com 			break;
76910934Ssommerfeld@sun.com 		case CONN_MAC_AWARE:
7709710SKen.Powell@Sun.COM 			mlp.tme_flags |= MIB2_TMEF_MACEXEMPT;
7719710SKen.Powell@Sun.COM 			needattr = B_TRUE;
77210934Ssommerfeld@sun.com 			break;
77310934Ssommerfeld@sun.com 		case CONN_MAC_IMPLICIT:
77410934Ssommerfeld@sun.com 			mlp.tme_flags |= MIB2_TMEF_MACIMPLICIT;
77510934Ssommerfeld@sun.com 			needattr = B_TRUE;
77610934Ssommerfeld@sun.com 			break;
7779710SKen.Powell@Sun.COM 		}
77811042SErik.Nordmark@Sun.COM 		if (sctp->sctp_connp->conn_ixa->ixa_tsl != NULL) {
7791676Sjpk 			ts_label_t *tsl;
7801676Sjpk 
78111042SErik.Nordmark@Sun.COM 			tsl = sctp->sctp_connp->conn_ixa->ixa_tsl;
7829710SKen.Powell@Sun.COM 			mlp.tme_flags |= MIB2_TMEF_IS_LABELED;
7831676Sjpk 			mlp.tme_doi = label2doi(tsl);
7841676Sjpk 			mlp.tme_label = *label2bslabel(tsl);
7851676Sjpk 			needattr = B_TRUE;
7861676Sjpk 		}
7870Sstevel@tonic-gate 		WAKE_SCTP(sctp);
7880Sstevel@tonic-gate 		sce.sctpAssocState = sctp_snmp_state(sctp);
7890Sstevel@tonic-gate 		sce.sctpAssocInStreams = sctp->sctp_num_istr;
7900Sstevel@tonic-gate 		sce.sctpAssocOutStreams = sctp->sctp_num_ostr;
7910Sstevel@tonic-gate 		sce.sctpAssocMaxRetr = sctp->sctp_pa_max_rxt;
7920Sstevel@tonic-gate 		/* A 0 here indicates that no primary process is known */
7930Sstevel@tonic-gate 		sce.sctpAssocPrimProcess = 0;
7940Sstevel@tonic-gate 		sce.sctpAssocT1expired = sctp->sctp_T1expire;
7950Sstevel@tonic-gate 		sce.sctpAssocT2expired = sctp->sctp_T2expire;
7960Sstevel@tonic-gate 		sce.sctpAssocRtxChunks = sctp->sctp_T3expire;
7970Sstevel@tonic-gate 		sce.sctpAssocStartTime = sctp->sctp_assoc_start_time;
7980Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_sendq = sctp->sctp_unacked +
7990Sstevel@tonic-gate 		    sctp->sctp_unsent;
8000Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_recvq = sctp->sctp_rxqueued;
8010Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_swnd = sctp->sctp_frwnd;
8020Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_rwnd = sctp->sctp_rwnd;
8030Sstevel@tonic-gate 		sce.sctpConnEntryInfo.ce_mss = sctp->sctp_mss;
8040Sstevel@tonic-gate 		(void) snmp_append_data2(mp_conn_data, &mp_conn_tail,
8050Sstevel@tonic-gate 		    (char *)&sce, sizeof (sce));
8061676Sjpk 		mlp.tme_connidx = idx++;
8071676Sjpk 		if (needattr)
8081676Sjpk 			(void) snmp_append_data2(mp_attr_ctl->b_cont,
8091676Sjpk 			    &mp_attr_tail, (char *)&mlp, sizeof (mlp));
8100Sstevel@tonic-gate next_sctp:
8110Sstevel@tonic-gate 		sctp_prev = sctp;
8123448Sdh155122 		mutex_enter(&sctps->sctps_g_lock);
8133448Sdh155122 		sctp = list_next(&sctps->sctps_g_list, sctp);
8140Sstevel@tonic-gate 	}
8153448Sdh155122 	mutex_exit(&sctps->sctps_g_lock);
8160Sstevel@tonic-gate 	if (sctp_prev != NULL)
8170Sstevel@tonic-gate 		SCTP_REFRELE(sctp_prev);
8180Sstevel@tonic-gate 
819*12869SKacheong.Poon@Sun.COM 	sctp_sum_mib(sctps, &sctp_mib);
820*12869SKacheong.Poon@Sun.COM 
8210Sstevel@tonic-gate 	optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
8220Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
8230Sstevel@tonic-gate 	optp->name = 0;
824*12869SKacheong.Poon@Sun.COM 	(void) snmp_append_data(mpdata, (char *)&sctp_mib, sizeof (sctp_mib));
8250Sstevel@tonic-gate 	optp->len = msgdsize(mpdata);
8260Sstevel@tonic-gate 	qreply(q, mpctl);
8270Sstevel@tonic-gate 
8280Sstevel@tonic-gate 	/* table of connections... */
8290Sstevel@tonic-gate 	optp = (struct opthdr *)&mp_conn_ctl->b_rptr[
8300Sstevel@tonic-gate 	    sizeof (struct T_optmgmt_ack)];
8310Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
8320Sstevel@tonic-gate 	optp->name = MIB2_SCTP_CONN;
8330Sstevel@tonic-gate 	optp->len = msgdsize(mp_conn_data);
8340Sstevel@tonic-gate 	qreply(q, mp_conn_ctl);
8350Sstevel@tonic-gate 
8360Sstevel@tonic-gate 	/* assoc local address table */
8370Sstevel@tonic-gate 	optp = (struct opthdr *)&mp_local_ctl->b_rptr[
8380Sstevel@tonic-gate 	    sizeof (struct T_optmgmt_ack)];
8390Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
8400Sstevel@tonic-gate 	optp->name = MIB2_SCTP_CONN_LOCAL;
8410Sstevel@tonic-gate 	optp->len = msgdsize(mp_local_data);
8420Sstevel@tonic-gate 	qreply(q, mp_local_ctl);
8430Sstevel@tonic-gate 
8440Sstevel@tonic-gate 	/* assoc remote address table */
8450Sstevel@tonic-gate 	optp = (struct opthdr *)&mp_rem_ctl->b_rptr[
8460Sstevel@tonic-gate 	    sizeof (struct T_optmgmt_ack)];
8470Sstevel@tonic-gate 	optp->level = MIB2_SCTP;
8480Sstevel@tonic-gate 	optp->name = MIB2_SCTP_CONN_REMOTE;
8490Sstevel@tonic-gate 	optp->len = msgdsize(mp_rem_data);
8500Sstevel@tonic-gate 	qreply(q, mp_rem_ctl);
8510Sstevel@tonic-gate 
8521676Sjpk 	/* table of MLP attributes */
8531676Sjpk 	optp = (struct opthdr *)&mp_attr_ctl->b_rptr[
8541676Sjpk 	    sizeof (struct T_optmgmt_ack)];
8551676Sjpk 	optp->level = MIB2_SCTP;
8561676Sjpk 	optp->name = EXPER_XPORT_MLP;
8571676Sjpk 	optp->len = msgdsize(mp_attr_data);
8581676Sjpk 	if (optp->len == 0)
8591676Sjpk 		freemsg(mp_attr_ctl);
8601676Sjpk 	else
8611676Sjpk 		qreply(q, mp_attr_ctl);
8621676Sjpk 
8630Sstevel@tonic-gate 	return (mp_ret);
8640Sstevel@tonic-gate }
8650Sstevel@tonic-gate 
8660Sstevel@tonic-gate /* Translate SCTP state to MIB2 SCTP state. */
8670Sstevel@tonic-gate static int
8680Sstevel@tonic-gate sctp_snmp_state(sctp_t *sctp)
8690Sstevel@tonic-gate {
8700Sstevel@tonic-gate 	if (sctp == NULL)
8710Sstevel@tonic-gate 		return (0);
8720Sstevel@tonic-gate 
8730Sstevel@tonic-gate 	switch (sctp->sctp_state) {
8740Sstevel@tonic-gate 	case SCTPS_IDLE:
8750Sstevel@tonic-gate 	case SCTPS_BOUND:
8760Sstevel@tonic-gate 		return (MIB2_SCTP_closed);
8770Sstevel@tonic-gate 	case SCTPS_LISTEN:
8780Sstevel@tonic-gate 		return (MIB2_SCTP_listen);
8790Sstevel@tonic-gate 	case SCTPS_COOKIE_WAIT:
8800Sstevel@tonic-gate 		return (MIB2_SCTP_cookieWait);
8810Sstevel@tonic-gate 	case SCTPS_COOKIE_ECHOED:
8820Sstevel@tonic-gate 		return (MIB2_SCTP_cookieEchoed);
8830Sstevel@tonic-gate 	case SCTPS_ESTABLISHED:
8840Sstevel@tonic-gate 		return (MIB2_SCTP_established);
8850Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_PENDING:
8860Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownPending);
8870Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_SENT:
8880Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownSent);
8890Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_RECEIVED:
8900Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownReceived);
8910Sstevel@tonic-gate 	case SCTPS_SHUTDOWN_ACK_SENT:
8920Sstevel@tonic-gate 		return (MIB2_SCTP_shutdownAckSent);
8930Sstevel@tonic-gate 	default:
8940Sstevel@tonic-gate 		return (0);
8950Sstevel@tonic-gate 	}
8960Sstevel@tonic-gate }
897*12869SKacheong.Poon@Sun.COM 
898*12869SKacheong.Poon@Sun.COM /*
899*12869SKacheong.Poon@Sun.COM  * To sum up all MIB2 stats for a sctp_stack_t from all per CPU stats.  The
900*12869SKacheong.Poon@Sun.COM  * caller should initialize the target mib2_sctp_t properly as this function
901*12869SKacheong.Poon@Sun.COM  * just adds up all the per CPU stats.
902*12869SKacheong.Poon@Sun.COM  */
903*12869SKacheong.Poon@Sun.COM static void
904*12869SKacheong.Poon@Sun.COM sctp_sum_mib(sctp_stack_t *sctps, mib2_sctp_t *sctp_mib)
905*12869SKacheong.Poon@Sun.COM {
906*12869SKacheong.Poon@Sun.COM 	int i;
907*12869SKacheong.Poon@Sun.COM 	int cnt;
908*12869SKacheong.Poon@Sun.COM 
909*12869SKacheong.Poon@Sun.COM 	/* Static componets of mib2_sctp_t. */
910*12869SKacheong.Poon@Sun.COM 	SET_MIB(sctp_mib->sctpRtoAlgorithm, MIB2_SCTP_RTOALGO_VANJ);
911*12869SKacheong.Poon@Sun.COM 	SET_MIB(sctp_mib->sctpRtoMin, sctps->sctps_rto_ming);
912*12869SKacheong.Poon@Sun.COM 	SET_MIB(sctp_mib->sctpRtoMax, sctps->sctps_rto_maxg);
913*12869SKacheong.Poon@Sun.COM 	SET_MIB(sctp_mib->sctpRtoInitial, sctps->sctps_rto_initialg);
914*12869SKacheong.Poon@Sun.COM 	SET_MIB(sctp_mib->sctpMaxAssocs, -1);
915*12869SKacheong.Poon@Sun.COM 	SET_MIB(sctp_mib->sctpValCookieLife, sctps->sctps_cookie_life);
916*12869SKacheong.Poon@Sun.COM 	SET_MIB(sctp_mib->sctpMaxInitRetr, sctps->sctps_max_init_retr);
917*12869SKacheong.Poon@Sun.COM 
918*12869SKacheong.Poon@Sun.COM 	/* fixed length structure for IPv4 and IPv6 counters */
919*12869SKacheong.Poon@Sun.COM 	SET_MIB(sctp_mib->sctpEntrySize, sizeof (mib2_sctpConnEntry_t));
920*12869SKacheong.Poon@Sun.COM 	SET_MIB(sctp_mib->sctpLocalEntrySize,
921*12869SKacheong.Poon@Sun.COM 	    sizeof (mib2_sctpConnLocalEntry_t));
922*12869SKacheong.Poon@Sun.COM 	SET_MIB(sctp_mib->sctpRemoteEntrySize,
923*12869SKacheong.Poon@Sun.COM 	    sizeof (mib2_sctpConnRemoteEntry_t));
924*12869SKacheong.Poon@Sun.COM 
925*12869SKacheong.Poon@Sun.COM 	/*
926*12869SKacheong.Poon@Sun.COM 	 * sctps_sc_cnt may change in the middle of the loop.  It is better
927*12869SKacheong.Poon@Sun.COM 	 * to get its value first.
928*12869SKacheong.Poon@Sun.COM 	 */
929*12869SKacheong.Poon@Sun.COM 	cnt = sctps->sctps_sc_cnt;
930*12869SKacheong.Poon@Sun.COM 	for (i = 0; i < cnt; i++)
931*12869SKacheong.Poon@Sun.COM 		sctp_add_mib(&sctps->sctps_sc[i]->sctp_sc_mib, sctp_mib);
932*12869SKacheong.Poon@Sun.COM }
933*12869SKacheong.Poon@Sun.COM 
934*12869SKacheong.Poon@Sun.COM static void
935*12869SKacheong.Poon@Sun.COM sctp_add_mib(mib2_sctp_t *from, mib2_sctp_t *to)
936*12869SKacheong.Poon@Sun.COM {
937*12869SKacheong.Poon@Sun.COM 	to->sctpActiveEstab += from->sctpActiveEstab;
938*12869SKacheong.Poon@Sun.COM 	to->sctpPassiveEstab += from->sctpPassiveEstab;
939*12869SKacheong.Poon@Sun.COM 	to->sctpAborted += from->sctpAborted;
940*12869SKacheong.Poon@Sun.COM 	to->sctpShutdowns += from->sctpShutdowns;
941*12869SKacheong.Poon@Sun.COM 	to->sctpOutOfBlue += from->sctpOutOfBlue;
942*12869SKacheong.Poon@Sun.COM 	to->sctpChecksumError += from->sctpChecksumError;
943*12869SKacheong.Poon@Sun.COM 	to->sctpOutCtrlChunks += from->sctpOutCtrlChunks;
944*12869SKacheong.Poon@Sun.COM 	to->sctpOutOrderChunks += from->sctpOutOrderChunks;
945*12869SKacheong.Poon@Sun.COM 	to->sctpOutUnorderChunks += from->sctpOutUnorderChunks;
946*12869SKacheong.Poon@Sun.COM 	to->sctpRetransChunks += from->sctpRetransChunks;
947*12869SKacheong.Poon@Sun.COM 	to->sctpOutAck += from->sctpOutAck;
948*12869SKacheong.Poon@Sun.COM 	to->sctpOutAckDelayed += from->sctpOutAckDelayed;
949*12869SKacheong.Poon@Sun.COM 	to->sctpOutWinUpdate += from->sctpOutWinUpdate;
950*12869SKacheong.Poon@Sun.COM 	to->sctpOutFastRetrans += from->sctpOutFastRetrans;
951*12869SKacheong.Poon@Sun.COM 	to->sctpOutWinProbe += from->sctpOutWinProbe;
952*12869SKacheong.Poon@Sun.COM 	to->sctpInCtrlChunks += from->sctpInCtrlChunks;
953*12869SKacheong.Poon@Sun.COM 	to->sctpInOrderChunks += from->sctpInOrderChunks;
954*12869SKacheong.Poon@Sun.COM 	to->sctpInUnorderChunks += from->sctpInUnorderChunks;
955*12869SKacheong.Poon@Sun.COM 	to->sctpInAck += from->sctpInAck;
956*12869SKacheong.Poon@Sun.COM 	to->sctpInDupAck += from->sctpInDupAck;
957*12869SKacheong.Poon@Sun.COM 	to->sctpInAckUnsent += from->sctpInAckUnsent;
958*12869SKacheong.Poon@Sun.COM 	to->sctpFragUsrMsgs += from->sctpFragUsrMsgs;
959*12869SKacheong.Poon@Sun.COM 	to->sctpReasmUsrMsgs += from->sctpReasmUsrMsgs;
960*12869SKacheong.Poon@Sun.COM 	to->sctpOutSCTPPkts += from->sctpOutSCTPPkts;
961*12869SKacheong.Poon@Sun.COM 	to->sctpInSCTPPkts += from->sctpInSCTPPkts;
962*12869SKacheong.Poon@Sun.COM 	to->sctpInInvalidCookie += from->sctpInInvalidCookie;
963*12869SKacheong.Poon@Sun.COM 	to->sctpTimRetrans += from->sctpTimRetrans;
964*12869SKacheong.Poon@Sun.COM 	to->sctpTimRetransDrop += from->sctpTimRetransDrop;
965*12869SKacheong.Poon@Sun.COM 	to->sctpTimHeartBeatProbe += from->sctpTimHeartBeatProbe;
966*12869SKacheong.Poon@Sun.COM 	to->sctpTimHeartBeatDrop += from->sctpTimHeartBeatDrop;
967*12869SKacheong.Poon@Sun.COM 	to->sctpListenDrop += from->sctpListenDrop;
968*12869SKacheong.Poon@Sun.COM 	to->sctpInClosed += from->sctpInClosed;
969*12869SKacheong.Poon@Sun.COM }
970