1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 #include <sys/types.h>
  27 #include <sys/stream.h>
  28 #include <sys/cmn_err.h>
  29 #define _SUN_TPI_VERSION 2
  30 #include <sys/tihdr.h>
  31 #include <sys/ddi.h>
  32 #include <sys/sunddi.h>
  33 #include <sys/tsol/tndb.h>
  34 
  35 #include <netinet/in.h>
  36 
  37 #include <inet/common.h>
  38 #include <inet/ip.h>
  39 #include <inet/mib2.h>
  40 #include <inet/snmpcom.h>
  41 #include <inet/kstatcom.h>
  42 #include <inet/ipclassifier.h>
  43 #include "sctp_impl.h"
  44 #include "sctp_addr.h"
  45 
  46 static void sctp_clr_kstats2(sctp_kstat_t *);
  47 static void sctp_add_kstats2(sctp_kstat_counter_t *, sctp_kstat_t *);
  48 static int sctp_snmp_state(sctp_t *);
  49 static void sctp_sum_mib(sctp_stack_t *, mib2_sctp_t *);
  50 static void sctp_add_mib(mib2_sctp_t *, mib2_sctp_t *);
  51 
  52 static int
  53 sctp_kstat_update(kstat_t *kp, int rw)
  54 {
  55         sctp_named_kstat_t      *sctpkp;
  56         sctp_t                  *sctp, *sctp_prev;
  57         zoneid_t        myzoneid;
  58         netstackid_t    stackid = (netstackid_t)(uintptr_t)kp->ks_private;
  59         netstack_t      *ns;
  60         sctp_stack_t    *sctps;
  61         mib2_sctp_t     sctp_mib;
  62 
  63         if (kp == NULL|| kp->ks_data == NULL)
  64                 return (EIO);
  65 
  66         if (rw == KSTAT_WRITE)
  67                 return (EACCES);
  68 
  69         ns = netstack_find_by_stackid(stackid);
  70         if (ns == NULL)
  71                 return (-1);
  72         sctps = ns->netstack_sctp;
  73         if (sctps == NULL) {
  74                 netstack_rele(ns);
  75                 return (-1);
  76         }
  77 
  78         /*
  79          * For all exclusive netstacks, the zone ID is always GLOBAL_ZONEID.
  80          */
  81         if (stackid != GLOBAL_NETSTACKID)
  82                 myzoneid = GLOBAL_ZONEID;
  83         else
  84                 myzoneid = curproc->p_zone->zone_id;
  85 
  86         bzero(&sctp_mib, sizeof (sctp_mib));
  87 
  88         /*
  89          * Get the number of current associations and gather their
  90          * individual set of statistics.
  91          */
  92         sctp_prev = NULL;
  93         mutex_enter(&sctps->sctps_g_lock);
  94         sctp = list_head(&sctps->sctps_g_list);
  95         while (sctp != NULL) {
  96                 mutex_enter(&sctp->sctp_reflock);
  97                 if (sctp->sctp_condemned) {
  98                         mutex_exit(&sctp->sctp_reflock);
  99                         sctp = list_next(&sctps->sctps_g_list, sctp);
 100                         continue;
 101                 }
 102                 sctp->sctp_refcnt++;
 103                 mutex_exit(&sctp->sctp_reflock);
 104                 mutex_exit(&sctps->sctps_g_lock);
 105                 if (sctp_prev != NULL)
 106                         SCTP_REFRELE(sctp_prev);
 107                 if (sctp->sctp_connp->conn_zoneid != myzoneid)
 108                         goto next_sctp;
 109                 if (sctp->sctp_state == SCTPS_ESTABLISHED ||
 110                     sctp->sctp_state == SCTPS_SHUTDOWN_PENDING ||
 111                     sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) {
 112                         /*
 113                          * Just bump the local sctp_mib.  The number of
 114                          * existing associations is not kept in kernel.
 115                          */
 116                         BUMP_MIB(&sctp_mib, sctpCurrEstab);
 117                 }
 118 
 119                 if (sctp->sctp_opkts) {
 120                         SCTPS_UPDATE_MIB(sctps, sctpOutSCTPPkts,
 121                             sctp->sctp_opkts);
 122                         sctp->sctp_opkts = 0;
 123                 }
 124 
 125                 if (sctp->sctp_obchunks) {
 126                         SCTPS_UPDATE_MIB(sctps, sctpOutCtrlChunks,
 127                             sctp->sctp_obchunks);
 128                         UPDATE_LOCAL(sctp->sctp_cum_obchunks,
 129                             sctp->sctp_obchunks);
 130                         sctp->sctp_obchunks = 0;
 131                 }
 132 
 133                 if (sctp->sctp_odchunks) {
 134                         SCTPS_UPDATE_MIB(sctps, sctpOutOrderChunks,
 135                             sctp->sctp_odchunks);
 136                         UPDATE_LOCAL(sctp->sctp_cum_odchunks,
 137                             sctp->sctp_odchunks);
 138                         sctp->sctp_odchunks = 0;
 139                 }
 140 
 141                 if (sctp->sctp_oudchunks) {
 142                         SCTPS_UPDATE_MIB(sctps, sctpOutUnorderChunks,
 143                             sctp->sctp_oudchunks);
 144                         UPDATE_LOCAL(sctp->sctp_cum_oudchunks,
 145                             sctp->sctp_oudchunks);
 146                         sctp->sctp_oudchunks = 0;
 147                 }
 148 
 149                 if (sctp->sctp_rxtchunks) {
 150                         SCTPS_UPDATE_MIB(sctps, sctpRetransChunks,
 151                             sctp->sctp_rxtchunks);
 152                         UPDATE_LOCAL(sctp->sctp_cum_rxtchunks,
 153                             sctp->sctp_rxtchunks);
 154                         sctp->sctp_rxtchunks = 0;
 155                 }
 156 
 157                 if (sctp->sctp_ipkts) {
 158                         SCTPS_UPDATE_MIB(sctps, sctpInSCTPPkts,
 159                             sctp->sctp_ipkts);
 160                         sctp->sctp_ipkts = 0;
 161                 }
 162 
 163                 if (sctp->sctp_ibchunks) {
 164                         SCTPS_UPDATE_MIB(sctps, sctpInCtrlChunks,
 165                             sctp->sctp_ibchunks);
 166                         UPDATE_LOCAL(sctp->sctp_cum_ibchunks,
 167                             sctp->sctp_ibchunks);
 168                         sctp->sctp_ibchunks = 0;
 169                 }
 170 
 171                 if (sctp->sctp_idchunks) {
 172                         SCTPS_UPDATE_MIB(sctps, sctpInOrderChunks,
 173                             sctp->sctp_idchunks);
 174                         UPDATE_LOCAL(sctp->sctp_cum_idchunks,
 175                             sctp->sctp_idchunks);
 176                         sctp->sctp_idchunks = 0;
 177                 }
 178 
 179                 if (sctp->sctp_iudchunks) {
 180                         SCTPS_UPDATE_MIB(sctps, sctpInUnorderChunks,
 181                             sctp->sctp_iudchunks);
 182                         UPDATE_LOCAL(sctp->sctp_cum_iudchunks,
 183                             sctp->sctp_iudchunks);
 184                         sctp->sctp_iudchunks = 0;
 185                 }
 186 
 187                 if (sctp->sctp_fragdmsgs) {
 188                         SCTPS_UPDATE_MIB(sctps, sctpFragUsrMsgs,
 189                             sctp->sctp_fragdmsgs);
 190                         sctp->sctp_fragdmsgs = 0;
 191                 }
 192 
 193                 if (sctp->sctp_reassmsgs) {
 194                         SCTPS_UPDATE_MIB(sctps, sctpReasmUsrMsgs,
 195                             sctp->sctp_reassmsgs);
 196                         sctp->sctp_reassmsgs = 0;
 197                 }
 198 
 199 next_sctp:
 200                 sctp_prev = sctp;
 201                 mutex_enter(&sctps->sctps_g_lock);
 202                 sctp = list_next(&sctps->sctps_g_list, sctp);
 203         }
 204         mutex_exit(&sctps->sctps_g_lock);
 205         if (sctp_prev != NULL)
 206                 SCTP_REFRELE(sctp_prev);
 207 
 208         sctp_sum_mib(sctps, &sctp_mib);
 209 
 210         /* Copy data from the SCTP MIB */
 211         sctpkp = (sctp_named_kstat_t *)kp->ks_data;
 212 
 213         /* These are from global ndd params. */
 214         sctpkp->sctpRtoMin.value.ui32 = sctps->sctps_rto_ming;
 215         sctpkp->sctpRtoMax.value.ui32 = sctps->sctps_rto_maxg;
 216         sctpkp->sctpRtoInitial.value.ui32 = sctps->sctps_rto_initialg;
 217         sctpkp->sctpValCookieLife.value.ui32 = sctps->sctps_cookie_life;
 218         sctpkp->sctpMaxInitRetr.value.ui32 = sctps->sctps_max_init_retr;
 219 
 220         /* Copy data from the local sctp_mib to the provided kstat. */
 221         sctpkp->sctpCurrEstab.value.i32 = sctp_mib.sctpCurrEstab;
 222         sctpkp->sctpActiveEstab.value.i32 = sctp_mib.sctpActiveEstab;
 223         sctpkp->sctpPassiveEstab.value.i32 = sctp_mib.sctpPassiveEstab;
 224         sctpkp->sctpAborted.value.i32 = sctp_mib.sctpAborted;
 225         sctpkp->sctpShutdowns.value.i32 = sctp_mib.sctpShutdowns;
 226         sctpkp->sctpOutOfBlue.value.i32 = sctp_mib.sctpOutOfBlue;
 227         sctpkp->sctpChecksumError.value.i32 = sctp_mib.sctpChecksumError;
 228         sctpkp->sctpOutCtrlChunks.value.i64 = sctp_mib.sctpOutCtrlChunks;
 229         sctpkp->sctpOutOrderChunks.value.i64 = sctp_mib.sctpOutOrderChunks;
 230         sctpkp->sctpOutUnorderChunks.value.i64 = sctp_mib.sctpOutUnorderChunks;
 231         sctpkp->sctpRetransChunks.value.i64 = sctp_mib.sctpRetransChunks;
 232         sctpkp->sctpOutAck.value.i32 = sctp_mib.sctpOutAck;
 233         sctpkp->sctpOutAckDelayed.value.i32 = sctp_mib.sctpOutAckDelayed;
 234         sctpkp->sctpOutWinUpdate.value.i32 = sctp_mib.sctpOutWinUpdate;
 235         sctpkp->sctpOutFastRetrans.value.i32 = sctp_mib.sctpOutFastRetrans;
 236         sctpkp->sctpOutWinProbe.value.i32 = sctp_mib.sctpOutWinProbe;
 237         sctpkp->sctpInCtrlChunks.value.i64 = sctp_mib.sctpInCtrlChunks;
 238         sctpkp->sctpInOrderChunks.value.i64 = sctp_mib.sctpInOrderChunks;
 239         sctpkp->sctpInUnorderChunks.value.i64 = sctp_mib.sctpInUnorderChunks;
 240         sctpkp->sctpInAck.value.i32 = sctp_mib.sctpInAck;
 241         sctpkp->sctpInDupAck.value.i32 = sctp_mib.sctpInDupAck;
 242         sctpkp->sctpInAckUnsent.value.i32 = sctp_mib.sctpInAckUnsent;
 243         sctpkp->sctpFragUsrMsgs.value.i64 = sctp_mib.sctpFragUsrMsgs;
 244         sctpkp->sctpReasmUsrMsgs.value.i64 = sctp_mib.sctpReasmUsrMsgs;
 245         sctpkp->sctpOutSCTPPkts.value.i64 = sctp_mib.sctpOutSCTPPkts;
 246         sctpkp->sctpInSCTPPkts.value.i64 = sctp_mib.sctpInSCTPPkts;
 247         sctpkp->sctpInInvalidCookie.value.i32 = sctp_mib.sctpInInvalidCookie;
 248         sctpkp->sctpTimRetrans.value.i32 = sctp_mib.sctpTimRetrans;
 249         sctpkp->sctpTimRetransDrop.value.i32 = sctp_mib.sctpTimRetransDrop;
 250         sctpkp->sctpTimHeartBeatProbe.value.i32 =
 251             sctp_mib.sctpTimHeartBeatProbe;
 252         sctpkp->sctpTimHeartBeatDrop.value.i32 = sctp_mib.sctpTimHeartBeatDrop;
 253         sctpkp->sctpListenDrop.value.i32 = sctp_mib.sctpListenDrop;
 254         sctpkp->sctpInClosed.value.i32 = sctp_mib.sctpInClosed;
 255 
 256         netstack_rele(ns);
 257         return (0);
 258 }
 259 
 260 void *
 261 sctp_kstat_init(netstackid_t stackid)
 262 {
 263         kstat_t *ksp;
 264 
 265         sctp_named_kstat_t template = {
 266                 { "sctpRtoAlgorithm",           KSTAT_DATA_INT32, 0 },
 267                 { "sctpRtoMin",                 KSTAT_DATA_UINT32, 0 },
 268                 { "sctpRtoMax",                 KSTAT_DATA_UINT32, 0 },
 269                 { "sctpRtoInitial",             KSTAT_DATA_UINT32, 0 },
 270                 { "sctpMaxAssocs",              KSTAT_DATA_INT32, 0 },
 271                 { "sctpValCookieLife",          KSTAT_DATA_UINT32, 0 },
 272                 { "sctpMaxInitRetr",            KSTAT_DATA_UINT32, 0 },
 273                 { "sctpCurrEstab",              KSTAT_DATA_INT32, 0 },
 274                 { "sctpActiveEstab",            KSTAT_DATA_INT32, 0 },
 275                 { "sctpPassiveEstab",           KSTAT_DATA_INT32, 0 },
 276                 { "sctpAborted",                KSTAT_DATA_INT32, 0 },
 277                 { "sctpShutdowns",              KSTAT_DATA_INT32, 0 },
 278                 { "sctpOutOfBlue",              KSTAT_DATA_INT32, 0 },
 279                 { "sctpChecksumError",          KSTAT_DATA_INT32, 0 },
 280                 { "sctpOutCtrlChunks",          KSTAT_DATA_INT64, 0 },
 281                 { "sctpOutOrderChunks",         KSTAT_DATA_INT64, 0 },
 282                 { "sctpOutUnorderChunks",       KSTAT_DATA_INT64, 0 },
 283                 { "sctpRetransChunks",          KSTAT_DATA_INT64, 0 },
 284                 { "sctpOutAck",                 KSTAT_DATA_INT32, 0 },
 285                 { "sctpOutAckDelayed",          KSTAT_DATA_INT32, 0 },
 286                 { "sctpOutWinUpdate",           KSTAT_DATA_INT32, 0 },
 287                 { "sctpOutFastRetrans",         KSTAT_DATA_INT32, 0 },
 288                 { "sctpOutWinProbe",            KSTAT_DATA_INT32, 0 },
 289                 { "sctpInCtrlChunks",           KSTAT_DATA_INT64, 0 },
 290                 { "sctpInOrderChunks",          KSTAT_DATA_INT64, 0 },
 291                 { "sctpInUnorderChunks",        KSTAT_DATA_INT64, 0 },
 292                 { "sctpInAck",                  KSTAT_DATA_INT32, 0 },
 293                 { "sctpInDupAck",               KSTAT_DATA_INT32, 0 },
 294                 { "sctpInAckUnsent",            KSTAT_DATA_INT32, 0 },
 295                 { "sctpFragUsrMsgs",            KSTAT_DATA_INT64, 0 },
 296                 { "sctpReasmUsrMsgs",           KSTAT_DATA_INT64, 0 },
 297                 { "sctpOutSCTPPkts",            KSTAT_DATA_INT64, 0 },
 298                 { "sctpInSCTPPkts",             KSTAT_DATA_INT64, 0 },
 299                 { "sctpInInvalidCookie",        KSTAT_DATA_INT32, 0 },
 300                 { "sctpTimRetrans",             KSTAT_DATA_INT32, 0 },
 301                 { "sctpTimRetransDrop",         KSTAT_DATA_INT32, 0 },
 302                 { "sctpTimHearBeatProbe",       KSTAT_DATA_INT32, 0 },
 303                 { "sctpTimHearBeatDrop",        KSTAT_DATA_INT32, 0 },
 304                 { "sctpListenDrop",             KSTAT_DATA_INT32, 0 },
 305                 { "sctpInClosed",               KSTAT_DATA_INT32, 0 }
 306         };
 307 
 308         ksp = kstat_create_netstack(SCTP_MOD_NAME, 0, "sctp", "mib2",
 309             KSTAT_TYPE_NAMED, NUM_OF_FIELDS(sctp_named_kstat_t), 0, stackid);
 310 
 311         if (ksp == NULL)
 312                 return (NULL);
 313 
 314         /* These won't change. */
 315         template.sctpRtoAlgorithm.value.i32 = MIB2_SCTP_RTOALGO_VANJ;
 316         template.sctpMaxAssocs.value.i32 = -1;
 317 
 318         bcopy(&template, ksp->ks_data, sizeof (template));
 319         ksp->ks_update = sctp_kstat_update;
 320         ksp->ks_private = (void *)(uintptr_t)stackid;
 321 
 322         kstat_install(ksp);
 323         return (ksp);
 324 }
 325 
 326 /*
 327  * To set all sctp_stat_t counters to 0.
 328  */
 329 static void
 330 sctp_clr_kstats2(sctp_kstat_t *stats)
 331 {
 332         stats->sctp_add_faddr.value.ui64 = 0;
 333         stats->sctp_add_timer.value.ui64 = 0;
 334         stats->sctp_conn_create.value.ui64 = 0;
 335         stats->sctp_find_next_tq.value.ui64 = 0;
 336         stats->sctp_fr_add_hdr.value.ui64 = 0;
 337         stats->sctp_fr_not_found.value.ui64 = 0;
 338         stats->sctp_output_failed.value.ui64 = 0;
 339         stats->sctp_rexmit_failed.value.ui64 = 0;
 340         stats->sctp_send_init_failed.value.ui64 = 0;
 341         stats->sctp_send_cookie_failed.value.ui64 = 0;
 342         stats->sctp_send_cookie_ack_failed.value.ui64 = 0;
 343         stats->sctp_send_err_failed.value.ui64 = 0;
 344         stats->sctp_send_sack_failed.value.ui64 = 0;
 345         stats->sctp_send_shutdown_failed.value.ui64 = 0;
 346         stats->sctp_send_shutdown_ack_failed.value.ui64 = 0;
 347         stats->sctp_send_shutdown_comp_failed.value.ui64 = 0;
 348         stats->sctp_send_user_abort_failed.value.ui64 = 0;
 349         stats->sctp_send_asconf_failed.value.ui64 = 0;
 350         stats->sctp_send_asconf_ack_failed.value.ui64 = 0;
 351         stats->sctp_send_ftsn_failed.value.ui64 = 0;
 352         stats->sctp_send_hb_failed.value.ui64 = 0;
 353         stats->sctp_return_hb_failed.value.ui64 = 0;
 354         stats->sctp_ss_rexmit_failed.value.ui64 = 0;
 355         stats->sctp_cl_connect.value.ui64 = 0;
 356         stats->sctp_cl_assoc_change.value.ui64 = 0;
 357         stats->sctp_cl_check_addrs.value.ui64 = 0;
 358         stats->sctp_reclaim_cnt.value.ui64 = 0;
 359         stats->sctp_listen_cnt_drop.value.ui64 = 0;
 360 }
 361 
 362 /*
 363  * To add counters from the per CPU sctp_kstat_counter_t to the stack
 364  * sctp_kstat_t.
 365  */
 366 static void
 367 sctp_add_kstats2(sctp_kstat_counter_t *from, sctp_kstat_t *to)
 368 {
 369         to->sctp_add_faddr.value.ui64 += from->sctp_add_faddr;
 370         to->sctp_add_timer.value.ui64 += from->sctp_add_timer;
 371         to->sctp_conn_create.value.ui64 += from->sctp_conn_create;
 372         to->sctp_find_next_tq.value.ui64 += from->sctp_find_next_tq;
 373         to->sctp_fr_add_hdr.value.ui64 += from->sctp_fr_add_hdr;
 374         to->sctp_fr_not_found.value.ui64 += from->sctp_fr_not_found;
 375         to->sctp_output_failed.value.ui64 += from->sctp_output_failed;
 376         to->sctp_rexmit_failed.value.ui64 += from->sctp_rexmit_failed;
 377         to->sctp_send_init_failed.value.ui64 += from->sctp_send_init_failed;
 378         to->sctp_send_cookie_failed.value.ui64 += from->sctp_send_cookie_failed;
 379         to->sctp_send_cookie_ack_failed.value.ui64 +=
 380             from->sctp_send_cookie_ack_failed;
 381         to->sctp_send_err_failed.value.ui64 += from->sctp_send_err_failed;
 382         to->sctp_send_sack_failed.value.ui64 += from->sctp_send_sack_failed;
 383         to->sctp_send_shutdown_failed.value.ui64 +=
 384             from->sctp_send_shutdown_failed;
 385         to->sctp_send_shutdown_ack_failed.value.ui64 +=
 386             from->sctp_send_shutdown_ack_failed;
 387         to->sctp_send_shutdown_comp_failed.value.ui64 +=
 388             from->sctp_send_shutdown_comp_failed;
 389         to->sctp_send_user_abort_failed.value.ui64 +=
 390             from->sctp_send_user_abort_failed;
 391         to->sctp_send_asconf_failed.value.ui64 += from->sctp_send_asconf_failed;
 392         to->sctp_send_asconf_ack_failed.value.ui64 +=
 393             from->sctp_send_asconf_ack_failed;
 394         to->sctp_send_ftsn_failed.value.ui64 += from->sctp_send_ftsn_failed;
 395         to->sctp_send_hb_failed.value.ui64 += from->sctp_send_hb_failed;
 396         to->sctp_return_hb_failed.value.ui64 += from->sctp_return_hb_failed;
 397         to->sctp_ss_rexmit_failed.value.ui64 += from->sctp_ss_rexmit_failed;
 398         to->sctp_cl_connect.value.ui64 += from->sctp_cl_connect;
 399         to->sctp_cl_assoc_change.value.ui64 += from->sctp_cl_assoc_change;
 400         to->sctp_cl_check_addrs.value.ui64 += from->sctp_cl_check_addrs;
 401 }
 402 
 403 /*
 404  * Sum up all per CPU tcp_stat_t kstat counters.
 405  */
 406 static int
 407 sctp_kstat2_update(kstat_t *kp, int rw)
 408 {
 409         netstackid_t    stackid = (netstackid_t)(uintptr_t)kp->ks_private;
 410         netstack_t      *ns;
 411         sctp_stack_t    *sctps;
 412         sctp_kstat_t    *stats;
 413         int             i;
 414         int             cnt;
 415 
 416         if (rw == KSTAT_WRITE)
 417                 return (EACCES);
 418 
 419         ns = netstack_find_by_stackid(stackid);
 420         if (ns == NULL)
 421                 return (-1);
 422         sctps = ns->netstack_sctp;
 423         if (sctps == NULL) {
 424                 netstack_rele(ns);
 425                 return (-1);
 426         }
 427 
 428         stats = (sctp_kstat_t *)kp->ks_data;
 429         sctp_clr_kstats2(stats);
 430 
 431         /*
 432          * sctps_sc_cnt may change in the middle of the loop.  It is better
 433          * to get its value first.
 434          */
 435         cnt = sctps->sctps_sc_cnt;
 436         for (i = 0; i < cnt; i++)
 437                 sctp_add_kstats2(&sctps->sctps_sc[i]->sctp_sc_stats, stats);
 438 
 439         netstack_rele(ns);
 440         return (0);
 441 }
 442 
 443 /*
 444  * The following kstats are for debugging purposes.  They keep
 445  * track of problems which should not happen normally.  But in
 446  * those cases which they do happen, these kstats would be handy
 447  * for engineers to diagnose the problems.  They are not intended
 448  * to be consumed by customers.
 449  */
 450 void *
 451 sctp_kstat2_init(netstackid_t stackid)
 452 {
 453         kstat_t *ksp;
 454 
 455         sctp_kstat_t template = {
 456                 { "sctp_add_faddr",                     KSTAT_DATA_UINT64 },
 457                 { "sctp_add_timer",                     KSTAT_DATA_UINT64 },
 458                 { "sctp_conn_create",                   KSTAT_DATA_UINT64 },
 459                 { "sctp_find_next_tq",                  KSTAT_DATA_UINT64 },
 460                 { "sctp_fr_add_hdr",                    KSTAT_DATA_UINT64 },
 461                 { "sctp_fr_not_found",                  KSTAT_DATA_UINT64 },
 462                 { "sctp_output_failed",                 KSTAT_DATA_UINT64 },
 463                 { "sctp_rexmit_failed",                 KSTAT_DATA_UINT64 },
 464                 { "sctp_send_init_failed",              KSTAT_DATA_UINT64 },
 465                 { "sctp_send_cookie_failed",            KSTAT_DATA_UINT64 },
 466                 { "sctp_send_cookie_ack_failed",        KSTAT_DATA_UINT64 },
 467                 { "sctp_send_err_failed",               KSTAT_DATA_UINT64 },
 468                 { "sctp_send_sack_failed",              KSTAT_DATA_UINT64 },
 469                 { "sctp_send_shutdown_failed",          KSTAT_DATA_UINT64 },
 470                 { "sctp_send_shutdown_ack_failed",      KSTAT_DATA_UINT64 },
 471                 { "sctp_send_shutdown_comp_failed",     KSTAT_DATA_UINT64 },
 472                 { "sctp_send_user_abort_failed",        KSTAT_DATA_UINT64 },
 473                 { "sctp_send_asconf_failed",            KSTAT_DATA_UINT64 },
 474                 { "sctp_send_asconf_ack_failed",        KSTAT_DATA_UINT64 },
 475                 { "sctp_send_ftsn_failed",              KSTAT_DATA_UINT64 },
 476                 { "sctp_send_hb_failed",                KSTAT_DATA_UINT64 },
 477                 { "sctp_return_hb_failed",              KSTAT_DATA_UINT64 },
 478                 { "sctp_ss_rexmit_failed",              KSTAT_DATA_UINT64 },
 479                 { "sctp_cl_connect",                    KSTAT_DATA_UINT64 },
 480                 { "sctp_cl_assoc_change",               KSTAT_DATA_UINT64 },
 481                 { "sctp_cl_check_addrs",                KSTAT_DATA_UINT64 },
 482                 { "sctp_reclaim_drop",                  KSTAT_DATA_UINT64 },
 483                 { "sctp_listen_cnt_drop",               KSTAT_DATA_UINT64 },
 484         };
 485 
 486         ksp = kstat_create_netstack(SCTP_MOD_NAME, 0, "sctpstat", "net",
 487             KSTAT_TYPE_NAMED, NUM_OF_FIELDS(template), 0, stackid);
 488 
 489         if (ksp == NULL)
 490                 return (NULL);
 491 
 492         bcopy(&template, ksp->ks_data, sizeof (template));
 493         ksp->ks_private = (void *)(uintptr_t)stackid;
 494         ksp->ks_update = sctp_kstat2_update;
 495 
 496         kstat_install(ksp);
 497         return (ksp);
 498 }
 499 
 500 void
 501 sctp_kstat_fini(netstackid_t stackid, kstat_t *ksp)
 502 {
 503         if (ksp != NULL) {
 504                 ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
 505                 kstat_delete_netstack(ksp, stackid);
 506         }
 507 }
 508 
 509 void
 510 sctp_kstat2_fini(netstackid_t stackid, kstat_t *ksp)
 511 {
 512         if (ksp != NULL) {
 513                 ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
 514                 kstat_delete_netstack(ksp, stackid);
 515         }
 516 }
 517 
 518 /*
 519  * Return SNMP global stats in buffer in mpdata.
 520  * Return associatiation table in mp_conn_data,
 521  * local address table in mp_local_data, and
 522  * remote address table in mp_rem_data.
 523  */
 524 mblk_t *
 525 sctp_snmp_get_mib2(queue_t *q, mblk_t *mpctl, sctp_stack_t *sctps)
 526 {
 527         mblk_t                  *mpdata, *mp_ret;
 528         mblk_t                  *mp_conn_ctl = NULL;
 529         mblk_t                  *mp_conn_data;
 530         mblk_t                  *mp_conn_tail = NULL;
 531         mblk_t                  *mp_pidnode_ctl = NULL;
 532         mblk_t                  *mp_pidnode_data;
 533         mblk_t                  *mp_pidnode_tail = NULL;
 534         mblk_t                  *mp_local_ctl = NULL;
 535         mblk_t                  *mp_local_data;
 536         mblk_t                  *mp_local_tail = NULL;
 537         mblk_t                  *mp_rem_ctl = NULL;
 538         mblk_t                  *mp_rem_data;
 539         mblk_t                  *mp_rem_tail = NULL;
 540         mblk_t                  *mp_attr_ctl = NULL;
 541         mblk_t                  *mp_attr_data;
 542         mblk_t                  *mp_attr_tail = NULL;
 543         struct opthdr           *optp;
 544         sctp_t                  *sctp, *sctp_prev = NULL;
 545         sctp_faddr_t            *fp;
 546         mib2_sctpConnEntry_t    sce;
 547         mib2_sctpConnLocalEntry_t       scle;
 548         mib2_sctpConnRemoteEntry_t      scre;
 549         mib2_transportMLPEntry_t        mlp;
 550         int                     i;
 551         int                     l;
 552         int                     scanned = 0;
 553         zoneid_t                zoneid = Q_TO_CONN(q)->conn_zoneid;
 554         conn_t                  *connp;
 555         boolean_t               needattr;
 556         int                     idx;
 557         mib2_sctp_t             sctp_mib;
 558 
 559 
 560         conn_pid_node_list_hdr_t        *cph;
 561 
 562         /*
 563          * Make copies of the original message.
 564          * mpctl will hold SCTP counters,
 565          * mp_conn_ctl will hold list of connections.
 566          */
 567         mp_ret = copymsg(mpctl);
 568         mp_conn_ctl = copymsg(mpctl);
 569         mp_pidnode_ctl = copymsg(mpctl);
 570         mp_local_ctl = copymsg(mpctl);
 571         mp_rem_ctl = copymsg(mpctl);
 572         mp_attr_ctl = copymsg(mpctl);
 573 
 574         mpdata = mpctl->b_cont;
 575 
 576         if (mp_conn_ctl == NULL || mp_pidnode_ctl == NULL ||
 577             mp_local_ctl == NULL || mp_rem_ctl == NULL || mp_attr_ctl == NULL ||
 578             mpdata == NULL) {
 579                 freemsg(mp_attr_ctl);
 580                 freemsg(mp_rem_ctl);
 581                 freemsg(mp_local_ctl);
 582                 freemsg(mp_pidnode_ctl);
 583                 freemsg(mp_conn_ctl);
 584                 freemsg(mp_ret);
 585                 freemsg(mpctl);
 586                 return (NULL);
 587         }
 588         mp_conn_data = mp_conn_ctl->b_cont;
 589         mp_pidnode_data = mp_pidnode_ctl->b_cont;
 590         mp_local_data = mp_local_ctl->b_cont;
 591         mp_rem_data = mp_rem_ctl->b_cont;
 592         mp_attr_data = mp_attr_ctl->b_cont;
 593 
 594         bzero(&sctp_mib, sizeof (sctp_mib));
 595 
 596         /* hostname address parameters are not supported in Solaris */
 597         sce.sctpAssocRemHostName.o_length = 0;
 598         sce.sctpAssocRemHostName.o_bytes[0] = 0;
 599 
 600         /* build table of connections -- need count in fixed part */
 601 
 602         idx = 0;
 603         mutex_enter(&sctps->sctps_g_lock);
 604         sctp = list_head(&sctps->sctps_g_list);
 605         while (sctp != NULL) {
 606                 mutex_enter(&sctp->sctp_reflock);
 607                 if (sctp->sctp_condemned) {
 608                         mutex_exit(&sctp->sctp_reflock);
 609                         sctp = list_next(&sctps->sctps_g_list, sctp);
 610                         continue;
 611                 }
 612                 sctp->sctp_refcnt++;
 613                 mutex_exit(&sctp->sctp_reflock);
 614                 mutex_exit(&sctps->sctps_g_lock);
 615                 if (sctp_prev != NULL)
 616                         SCTP_REFRELE(sctp_prev);
 617                 if (sctp->sctp_connp->conn_zoneid != zoneid)
 618                         goto next_sctp;
 619                 if (sctp->sctp_state == SCTPS_ESTABLISHED ||
 620                     sctp->sctp_state == SCTPS_SHUTDOWN_PENDING ||
 621                     sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) {
 622                         /*
 623                          * Just bump the local sctp_mib.  The number of
 624                          * existing associations is not kept in kernel.
 625                          */
 626                         BUMP_MIB(&sctp_mib, sctpCurrEstab);
 627                 }
 628                 SCTPS_UPDATE_MIB(sctps, sctpOutSCTPPkts, sctp->sctp_opkts);
 629                 sctp->sctp_opkts = 0;
 630                 SCTPS_UPDATE_MIB(sctps, sctpOutCtrlChunks, sctp->sctp_obchunks);
 631                 UPDATE_LOCAL(sctp->sctp_cum_obchunks,
 632                     sctp->sctp_obchunks);
 633                 sctp->sctp_obchunks = 0;
 634                 SCTPS_UPDATE_MIB(sctps, sctpOutOrderChunks,
 635                     sctp->sctp_odchunks);
 636                 UPDATE_LOCAL(sctp->sctp_cum_odchunks,
 637                     sctp->sctp_odchunks);
 638                 sctp->sctp_odchunks = 0;
 639                 SCTPS_UPDATE_MIB(sctps, sctpOutUnorderChunks,
 640                     sctp->sctp_oudchunks);
 641                 UPDATE_LOCAL(sctp->sctp_cum_oudchunks,
 642                     sctp->sctp_oudchunks);
 643                 sctp->sctp_oudchunks = 0;
 644                 SCTPS_UPDATE_MIB(sctps, sctpRetransChunks,
 645                     sctp->sctp_rxtchunks);
 646                 UPDATE_LOCAL(sctp->sctp_cum_rxtchunks,
 647                     sctp->sctp_rxtchunks);
 648                 sctp->sctp_rxtchunks = 0;
 649                 SCTPS_UPDATE_MIB(sctps, sctpInSCTPPkts, sctp->sctp_ipkts);
 650                 sctp->sctp_ipkts = 0;
 651                 SCTPS_UPDATE_MIB(sctps, sctpInCtrlChunks, sctp->sctp_ibchunks);
 652                 UPDATE_LOCAL(sctp->sctp_cum_ibchunks,
 653                     sctp->sctp_ibchunks);
 654                 sctp->sctp_ibchunks = 0;
 655                 SCTPS_UPDATE_MIB(sctps, sctpInOrderChunks, sctp->sctp_idchunks);
 656                 UPDATE_LOCAL(sctp->sctp_cum_idchunks,
 657                     sctp->sctp_idchunks);
 658                 sctp->sctp_idchunks = 0;
 659                 SCTPS_UPDATE_MIB(sctps, sctpInUnorderChunks,
 660                     sctp->sctp_iudchunks);
 661                 UPDATE_LOCAL(sctp->sctp_cum_iudchunks,
 662                     sctp->sctp_iudchunks);
 663                 sctp->sctp_iudchunks = 0;
 664                 SCTPS_UPDATE_MIB(sctps, sctpFragUsrMsgs, sctp->sctp_fragdmsgs);
 665                 sctp->sctp_fragdmsgs = 0;
 666                 SCTPS_UPDATE_MIB(sctps, sctpReasmUsrMsgs, sctp->sctp_reassmsgs);
 667                 sctp->sctp_reassmsgs = 0;
 668 
 669                 sce.sctpAssocId = ntohl(sctp->sctp_lvtag);
 670                 sce.sctpAssocLocalPort = ntohs(sctp->sctp_connp->conn_lport);
 671                 sce.sctpAssocRemPort = ntohs(sctp->sctp_connp->conn_fport);
 672 
 673                 RUN_SCTP(sctp);
 674                 if (sctp->sctp_primary != NULL) {
 675                         fp = sctp->sctp_primary;
 676 
 677                         if (IN6_IS_ADDR_V4MAPPED(&fp->sf_faddr)) {
 678                                 sce.sctpAssocRemPrimAddrType =
 679                                     MIB2_SCTP_ADDR_V4;
 680                         } else {
 681                                 sce.sctpAssocRemPrimAddrType =
 682                                     MIB2_SCTP_ADDR_V6;
 683                         }
 684                         sce.sctpAssocRemPrimAddr = fp->sf_faddr;
 685                         sce.sctpAssocLocPrimAddr = fp->sf_saddr;
 686                         sce.sctpAssocHeartBeatInterval = TICK_TO_MSEC(
 687                             fp->sf_hb_interval);
 688                 } else {
 689                         sce.sctpAssocRemPrimAddrType = MIB2_SCTP_ADDR_V4;
 690                         bzero(&sce.sctpAssocRemPrimAddr,
 691                             sizeof (sce.sctpAssocRemPrimAddr));
 692                         bzero(&sce.sctpAssocLocPrimAddr,
 693                             sizeof (sce.sctpAssocLocPrimAddr));
 694                         sce.sctpAssocHeartBeatInterval =
 695                             sctps->sctps_heartbeat_interval;
 696                 }
 697 
 698                 /*
 699                  * Table for local addresses
 700                  */
 701                 scanned = 0;
 702                 for (i = 0; i < SCTP_IPIF_HASH; i++) {
 703                         sctp_saddr_ipif_t       *obj;
 704 
 705                         if (sctp->sctp_saddrs[i].ipif_count == 0)
 706                                 continue;
 707                         obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list);
 708                         for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
 709                                 sctp_ipif_t     *sctp_ipif;
 710                                 in6_addr_t      addr;
 711 
 712                                 sctp_ipif = obj->saddr_ipifp;
 713                                 addr = sctp_ipif->sctp_ipif_saddr;
 714                                 scanned++;
 715                                 scle.sctpAssocId = ntohl(sctp->sctp_lvtag);
 716                                 if (IN6_IS_ADDR_V4MAPPED(&addr)) {
 717                                         scle.sctpAssocLocalAddrType =
 718                                             MIB2_SCTP_ADDR_V4;
 719                                 } else {
 720                                         scle.sctpAssocLocalAddrType =
 721                                             MIB2_SCTP_ADDR_V6;
 722                                 }
 723                                 scle.sctpAssocLocalAddr = addr;
 724                                 (void) snmp_append_data2(mp_local_data,
 725                                     &mp_local_tail, (char *)&scle,
 726                                     sizeof (scle));
 727                                 if (scanned >= sctp->sctp_nsaddrs)
 728                                         goto done;
 729                                 obj = list_next(&sctp->
 730                                     sctp_saddrs[i].sctp_ipif_list, obj);
 731                         }
 732                 }
 733 done:
 734                 /*
 735                  * Table for remote addresses
 736                  */
 737                 for (fp = sctp->sctp_faddrs; fp; fp = fp->sf_next) {
 738                         scre.sctpAssocId = ntohl(sctp->sctp_lvtag);
 739                         if (IN6_IS_ADDR_V4MAPPED(&fp->sf_faddr)) {
 740                                 scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V4;
 741                         } else {
 742                                 scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V6;
 743                         }
 744                         scre.sctpAssocRemAddr = fp->sf_faddr;
 745                         if (fp->sf_state == SCTP_FADDRS_ALIVE) {
 746                                 scre.sctpAssocRemAddrActive =
 747                                     scre.sctpAssocRemAddrHBActive =
 748                                     MIB2_SCTP_ACTIVE;
 749                         } else {
 750                                 scre.sctpAssocRemAddrActive =
 751                                     scre.sctpAssocRemAddrHBActive =
 752                                     MIB2_SCTP_INACTIVE;
 753                         }
 754                         scre.sctpAssocRemAddrRTO = TICK_TO_MSEC(fp->sf_rto);
 755                         scre.sctpAssocRemAddrMaxPathRtx = fp->sf_max_retr;
 756                         scre.sctpAssocRemAddrRtx = fp->sf_T3expire;
 757                         (void) snmp_append_data2(mp_rem_data, &mp_rem_tail,
 758                             (char *)&scre, sizeof (scre));
 759                 }
 760                 connp = sctp->sctp_connp;
 761                 needattr = B_FALSE;
 762                 bzero(&mlp, sizeof (mlp));
 763                 if (connp->conn_mlp_type != mlptSingle) {
 764                         if (connp->conn_mlp_type == mlptShared ||
 765                             connp->conn_mlp_type == mlptBoth)
 766                                 mlp.tme_flags |= MIB2_TMEF_SHARED;
 767                         if (connp->conn_mlp_type == mlptPrivate ||
 768                             connp->conn_mlp_type == mlptBoth)
 769                                 mlp.tme_flags |= MIB2_TMEF_PRIVATE;
 770                         needattr = B_TRUE;
 771                 }
 772                 if (connp->conn_anon_mlp) {
 773                         mlp.tme_flags |= MIB2_TMEF_ANONMLP;
 774                         needattr = B_TRUE;
 775                 }
 776                 switch (connp->conn_mac_mode) {
 777                 case CONN_MAC_DEFAULT:
 778                         break;
 779                 case CONN_MAC_AWARE:
 780                         mlp.tme_flags |= MIB2_TMEF_MACEXEMPT;
 781                         needattr = B_TRUE;
 782                         break;
 783                 case CONN_MAC_IMPLICIT:
 784                         mlp.tme_flags |= MIB2_TMEF_MACIMPLICIT;
 785                         needattr = B_TRUE;
 786                         break;
 787                 }
 788                 if (sctp->sctp_connp->conn_ixa->ixa_tsl != NULL) {
 789                         ts_label_t *tsl;
 790 
 791                         tsl = sctp->sctp_connp->conn_ixa->ixa_tsl;
 792                         mlp.tme_flags |= MIB2_TMEF_IS_LABELED;
 793                         mlp.tme_doi = label2doi(tsl);
 794                         mlp.tme_label = *label2bslabel(tsl);
 795                         needattr = B_TRUE;
 796                 }
 797                 WAKE_SCTP(sctp);
 798                 sce.sctpAssocState = sctp_snmp_state(sctp);
 799                 sce.sctpAssocInStreams = sctp->sctp_num_istr;
 800                 sce.sctpAssocOutStreams = sctp->sctp_num_ostr;
 801                 sce.sctpAssocMaxRetr = sctp->sctp_pa_max_rxt;
 802                 /* A 0 here indicates that no primary process is known */
 803                 sce.sctpAssocPrimProcess = 0;
 804                 sce.sctpAssocT1expired = sctp->sctp_T1expire;
 805                 sce.sctpAssocT2expired = sctp->sctp_T2expire;
 806                 sce.sctpAssocRtxChunks = sctp->sctp_T3expire;
 807                 sce.sctpAssocStartTime = sctp->sctp_assoc_start_time;
 808                 sce.sctpConnEntryInfo.ce_sendq = sctp->sctp_unacked +
 809                     sctp->sctp_unsent;
 810                 sce.sctpConnEntryInfo.ce_recvq = sctp->sctp_rxqueued;
 811                 sce.sctpConnEntryInfo.ce_swnd = sctp->sctp_frwnd;
 812                 sce.sctpConnEntryInfo.ce_rwnd = sctp->sctp_rwnd;
 813                 sce.sctpConnEntryInfo.ce_mss = sctp->sctp_mss;
 814                 (void) snmp_append_data2(mp_conn_data, &mp_conn_tail,
 815                     (char *)&sce, sizeof (sce));
 816                 /* my data */
 817                 (void) snmp_append_data2(mp_pidnode_data, &mp_pidnode_tail,
 818                     (char *)&sce, sizeof (sce));
 819 
 820                 cph = conn_get_pid_list(connp);
 821 
 822                 (void) snmp_append_data2(mp_pidnode_data, &mp_pidnode_tail,
 823                     (char *)cph, cph->cph_tot_size);
 824 
 825                 kmem_free(cph, cph->cph_tot_size);
 826                 /* end of my data */
 827                 mlp.tme_connidx = idx++;
 828                 if (needattr)
 829                         (void) snmp_append_data2(mp_attr_ctl->b_cont,
 830                             &mp_attr_tail, (char *)&mlp, sizeof (mlp));
 831 next_sctp:
 832                 sctp_prev = sctp;
 833                 mutex_enter(&sctps->sctps_g_lock);
 834                 sctp = list_next(&sctps->sctps_g_list, sctp);
 835         }
 836         mutex_exit(&sctps->sctps_g_lock);
 837         if (sctp_prev != NULL)
 838                 SCTP_REFRELE(sctp_prev);
 839 
 840         sctp_sum_mib(sctps, &sctp_mib);
 841 
 842         optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
 843         optp->level = MIB2_SCTP;
 844         optp->name = 0;
 845         (void) snmp_append_data(mpdata, (char *)&sctp_mib, sizeof (sctp_mib));
 846         optp->len = msgdsize(mpdata);
 847         qreply(q, mpctl);
 848 
 849         /* table of connections... */
 850         optp = (struct opthdr *)&mp_conn_ctl->b_rptr[
 851             sizeof (struct T_optmgmt_ack)];
 852         optp->level = MIB2_SCTP;
 853         optp->name = MIB2_SCTP_CONN;
 854         optp->len = msgdsize(mp_conn_data);
 855         qreply(q, mp_conn_ctl);
 856 
 857         /* table of EXPER_XPORT_PROC_INFO */
 858         optp = (struct opthdr *)&mp_pidnode_ctl->b_rptr[
 859             sizeof (struct T_optmgmt_ack)];
 860         optp->level = MIB2_SCTP;
 861         optp->name = EXPER_XPORT_PROC_INFO;
 862         optp->len = msgdsize(mp_pidnode_data);
 863         qreply(q, mp_pidnode_ctl);
 864 
 865         /* assoc local address table */
 866         optp = (struct opthdr *)&mp_local_ctl->b_rptr[
 867             sizeof (struct T_optmgmt_ack)];
 868         optp->level = MIB2_SCTP;
 869         optp->name = MIB2_SCTP_CONN_LOCAL;
 870         optp->len = msgdsize(mp_local_data);
 871         qreply(q, mp_local_ctl);
 872 
 873         /* assoc remote address table */
 874         optp = (struct opthdr *)&mp_rem_ctl->b_rptr[
 875             sizeof (struct T_optmgmt_ack)];
 876         optp->level = MIB2_SCTP;
 877         optp->name = MIB2_SCTP_CONN_REMOTE;
 878         optp->len = msgdsize(mp_rem_data);
 879         qreply(q, mp_rem_ctl);
 880 
 881         /* table of MLP attributes */
 882         optp = (struct opthdr *)&mp_attr_ctl->b_rptr[
 883             sizeof (struct T_optmgmt_ack)];
 884         optp->level = MIB2_SCTP;
 885         optp->name = EXPER_XPORT_MLP;
 886         optp->len = msgdsize(mp_attr_data);
 887         if (optp->len == 0)
 888                 freemsg(mp_attr_ctl);
 889         else
 890                 qreply(q, mp_attr_ctl);
 891 
 892         return (mp_ret);
 893 }
 894 
 895 /* Translate SCTP state to MIB2 SCTP state. */
 896 static int
 897 sctp_snmp_state(sctp_t *sctp)
 898 {
 899         if (sctp == NULL)
 900                 return (0);
 901 
 902         switch (sctp->sctp_state) {
 903         case SCTPS_IDLE:
 904         case SCTPS_BOUND:
 905                 return (MIB2_SCTP_closed);
 906         case SCTPS_LISTEN:
 907                 return (MIB2_SCTP_listen);
 908         case SCTPS_COOKIE_WAIT:
 909                 return (MIB2_SCTP_cookieWait);
 910         case SCTPS_COOKIE_ECHOED:
 911                 return (MIB2_SCTP_cookieEchoed);
 912         case SCTPS_ESTABLISHED:
 913                 return (MIB2_SCTP_established);
 914         case SCTPS_SHUTDOWN_PENDING:
 915                 return (MIB2_SCTP_shutdownPending);
 916         case SCTPS_SHUTDOWN_SENT:
 917                 return (MIB2_SCTP_shutdownSent);
 918         case SCTPS_SHUTDOWN_RECEIVED:
 919                 return (MIB2_SCTP_shutdownReceived);
 920         case SCTPS_SHUTDOWN_ACK_SENT:
 921                 return (MIB2_SCTP_shutdownAckSent);
 922         default:
 923                 return (0);
 924         }
 925 }
 926 
 927 /*
 928  * To sum up all MIB2 stats for a sctp_stack_t from all per CPU stats.  The
 929  * caller should initialize the target mib2_sctp_t properly as this function
 930  * just adds up all the per CPU stats.
 931  */
 932 static void
 933 sctp_sum_mib(sctp_stack_t *sctps, mib2_sctp_t *sctp_mib)
 934 {
 935         int i;
 936         int cnt;
 937 
 938         /* Static componets of mib2_sctp_t. */
 939         SET_MIB(sctp_mib->sctpRtoAlgorithm, MIB2_SCTP_RTOALGO_VANJ);
 940         SET_MIB(sctp_mib->sctpRtoMin, sctps->sctps_rto_ming);
 941         SET_MIB(sctp_mib->sctpRtoMax, sctps->sctps_rto_maxg);
 942         SET_MIB(sctp_mib->sctpRtoInitial, sctps->sctps_rto_initialg);
 943         SET_MIB(sctp_mib->sctpMaxAssocs, -1);
 944         SET_MIB(sctp_mib->sctpValCookieLife, sctps->sctps_cookie_life);
 945         SET_MIB(sctp_mib->sctpMaxInitRetr, sctps->sctps_max_init_retr);
 946 
 947         /* fixed length structure for IPv4 and IPv6 counters */
 948         SET_MIB(sctp_mib->sctpEntrySize, sizeof (mib2_sctpConnEntry_t));
 949         SET_MIB(sctp_mib->sctpLocalEntrySize,
 950             sizeof (mib2_sctpConnLocalEntry_t));
 951         SET_MIB(sctp_mib->sctpRemoteEntrySize,
 952             sizeof (mib2_sctpConnRemoteEntry_t));
 953 
 954         /*
 955          * sctps_sc_cnt may change in the middle of the loop.  It is better
 956          * to get its value first.
 957          */
 958         cnt = sctps->sctps_sc_cnt;
 959         for (i = 0; i < cnt; i++)
 960                 sctp_add_mib(&sctps->sctps_sc[i]->sctp_sc_mib, sctp_mib);
 961 }
 962 
 963 static void
 964 sctp_add_mib(mib2_sctp_t *from, mib2_sctp_t *to)
 965 {
 966         to->sctpActiveEstab += from->sctpActiveEstab;
 967         to->sctpPassiveEstab += from->sctpPassiveEstab;
 968         to->sctpAborted += from->sctpAborted;
 969         to->sctpShutdowns += from->sctpShutdowns;
 970         to->sctpOutOfBlue += from->sctpOutOfBlue;
 971         to->sctpChecksumError += from->sctpChecksumError;
 972         to->sctpOutCtrlChunks += from->sctpOutCtrlChunks;
 973         to->sctpOutOrderChunks += from->sctpOutOrderChunks;
 974         to->sctpOutUnorderChunks += from->sctpOutUnorderChunks;
 975         to->sctpRetransChunks += from->sctpRetransChunks;
 976         to->sctpOutAck += from->sctpOutAck;
 977         to->sctpOutAckDelayed += from->sctpOutAckDelayed;
 978         to->sctpOutWinUpdate += from->sctpOutWinUpdate;
 979         to->sctpOutFastRetrans += from->sctpOutFastRetrans;
 980         to->sctpOutWinProbe += from->sctpOutWinProbe;
 981         to->sctpInCtrlChunks += from->sctpInCtrlChunks;
 982         to->sctpInOrderChunks += from->sctpInOrderChunks;
 983         to->sctpInUnorderChunks += from->sctpInUnorderChunks;
 984         to->sctpInAck += from->sctpInAck;
 985         to->sctpInDupAck += from->sctpInDupAck;
 986         to->sctpInAckUnsent += from->sctpInAckUnsent;
 987         to->sctpFragUsrMsgs += from->sctpFragUsrMsgs;
 988         to->sctpReasmUsrMsgs += from->sctpReasmUsrMsgs;
 989         to->sctpOutSCTPPkts += from->sctpOutSCTPPkts;
 990         to->sctpInSCTPPkts += from->sctpInSCTPPkts;
 991         to->sctpInInvalidCookie += from->sctpInInvalidCookie;
 992         to->sctpTimRetrans += from->sctpTimRetrans;
 993         to->sctpTimRetransDrop += from->sctpTimRetransDrop;
 994         to->sctpTimHeartBeatProbe += from->sctpTimHeartBeatProbe;
 995         to->sctpTimHeartBeatDrop += from->sctpTimHeartBeatDrop;
 996         to->sctpListenDrop += from->sctpListenDrop;
 997         to->sctpInClosed += from->sctpInClosed;
 998 }