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 * Make copies of the original message. 561 * mpctl will hold SCTP counters, 562 * mp_conn_ctl will hold list of connections. 563 */ 564 mp_ret = copymsg(mpctl); 565 mp_conn_ctl = copymsg(mpctl); 566 mp_pidnode_ctl = copymsg(mpctl); 567 mp_local_ctl = copymsg(mpctl); 568 mp_rem_ctl = copymsg(mpctl); 569 mp_attr_ctl = copymsg(mpctl); 570 571 mpdata = mpctl->b_cont; 572 573 if (mp_conn_ctl == NULL || mp_pidnode_ctl == NULL || 574 mp_local_ctl == NULL || mp_rem_ctl == NULL || mp_attr_ctl == NULL || 575 mpdata == NULL) { 576 freemsg(mp_attr_ctl); 577 freemsg(mp_rem_ctl); 578 freemsg(mp_local_ctl); 579 freemsg(mp_pidnode_ctl); 580 freemsg(mp_conn_ctl); 581 freemsg(mp_ret); 582 freemsg(mpctl); 583 return (NULL); 584 } 585 mp_conn_data = mp_conn_ctl->b_cont; 586 mp_pidnode_data = mp_pidnode_ctl->b_cont; 587 mp_local_data = mp_local_ctl->b_cont; 588 mp_rem_data = mp_rem_ctl->b_cont; 589 mp_attr_data = mp_attr_ctl->b_cont; 590 591 bzero(&sctp_mib, sizeof (sctp_mib)); 592 593 /* hostname address parameters are not supported in Solaris */ 594 sce.sctpAssocRemHostName.o_length = 0; 595 sce.sctpAssocRemHostName.o_bytes[0] = 0; 596 597 /* build table of connections -- need count in fixed part */ 598 599 idx = 0; 600 mutex_enter(&sctps->sctps_g_lock); 601 sctp = list_head(&sctps->sctps_g_list); 602 while (sctp != NULL) { 603 mutex_enter(&sctp->sctp_reflock); 604 if (sctp->sctp_condemned) { 605 mutex_exit(&sctp->sctp_reflock); 606 sctp = list_next(&sctps->sctps_g_list, sctp); 607 continue; 608 } 609 sctp->sctp_refcnt++; 610 mutex_exit(&sctp->sctp_reflock); 611 mutex_exit(&sctps->sctps_g_lock); 612 if (sctp_prev != NULL) 613 SCTP_REFRELE(sctp_prev); 614 if (sctp->sctp_connp->conn_zoneid != zoneid) 615 goto next_sctp; 616 if (sctp->sctp_state == SCTPS_ESTABLISHED || 617 sctp->sctp_state == SCTPS_SHUTDOWN_PENDING || 618 sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) { 619 /* 620 * Just bump the local sctp_mib. The number of 621 * existing associations is not kept in kernel. 622 */ 623 BUMP_MIB(&sctp_mib, sctpCurrEstab); 624 } 625 SCTPS_UPDATE_MIB(sctps, sctpOutSCTPPkts, sctp->sctp_opkts); 626 sctp->sctp_opkts = 0; 627 SCTPS_UPDATE_MIB(sctps, sctpOutCtrlChunks, sctp->sctp_obchunks); 628 UPDATE_LOCAL(sctp->sctp_cum_obchunks, 629 sctp->sctp_obchunks); 630 sctp->sctp_obchunks = 0; 631 SCTPS_UPDATE_MIB(sctps, sctpOutOrderChunks, 632 sctp->sctp_odchunks); 633 UPDATE_LOCAL(sctp->sctp_cum_odchunks, 634 sctp->sctp_odchunks); 635 sctp->sctp_odchunks = 0; 636 SCTPS_UPDATE_MIB(sctps, sctpOutUnorderChunks, 637 sctp->sctp_oudchunks); 638 UPDATE_LOCAL(sctp->sctp_cum_oudchunks, 639 sctp->sctp_oudchunks); 640 sctp->sctp_oudchunks = 0; 641 SCTPS_UPDATE_MIB(sctps, sctpRetransChunks, 642 sctp->sctp_rxtchunks); 643 UPDATE_LOCAL(sctp->sctp_cum_rxtchunks, 644 sctp->sctp_rxtchunks); 645 sctp->sctp_rxtchunks = 0; 646 SCTPS_UPDATE_MIB(sctps, sctpInSCTPPkts, sctp->sctp_ipkts); 647 sctp->sctp_ipkts = 0; 648 SCTPS_UPDATE_MIB(sctps, sctpInCtrlChunks, sctp->sctp_ibchunks); 649 UPDATE_LOCAL(sctp->sctp_cum_ibchunks, 650 sctp->sctp_ibchunks); 651 sctp->sctp_ibchunks = 0; 652 SCTPS_UPDATE_MIB(sctps, sctpInOrderChunks, sctp->sctp_idchunks); 653 UPDATE_LOCAL(sctp->sctp_cum_idchunks, 654 sctp->sctp_idchunks); 655 sctp->sctp_idchunks = 0; 656 SCTPS_UPDATE_MIB(sctps, sctpInUnorderChunks, 657 sctp->sctp_iudchunks); 658 UPDATE_LOCAL(sctp->sctp_cum_iudchunks, 659 sctp->sctp_iudchunks); 660 sctp->sctp_iudchunks = 0; 661 SCTPS_UPDATE_MIB(sctps, sctpFragUsrMsgs, sctp->sctp_fragdmsgs); 662 sctp->sctp_fragdmsgs = 0; 663 SCTPS_UPDATE_MIB(sctps, sctpReasmUsrMsgs, sctp->sctp_reassmsgs); 664 sctp->sctp_reassmsgs = 0; 665 666 sce.sctpAssocId = ntohl(sctp->sctp_lvtag); 667 sce.sctpAssocLocalPort = ntohs(sctp->sctp_connp->conn_lport); 668 sce.sctpAssocRemPort = ntohs(sctp->sctp_connp->conn_fport); 669 670 RUN_SCTP(sctp); 671 if (sctp->sctp_primary != NULL) { 672 fp = sctp->sctp_primary; 673 674 if (IN6_IS_ADDR_V4MAPPED(&fp->sf_faddr)) { 675 sce.sctpAssocRemPrimAddrType = 676 MIB2_SCTP_ADDR_V4; 677 } else { 678 sce.sctpAssocRemPrimAddrType = 679 MIB2_SCTP_ADDR_V6; 680 } 681 sce.sctpAssocRemPrimAddr = fp->sf_faddr; 682 sce.sctpAssocLocPrimAddr = fp->sf_saddr; 683 sce.sctpAssocHeartBeatInterval = TICK_TO_MSEC( 684 fp->sf_hb_interval); 685 } else { 686 sce.sctpAssocRemPrimAddrType = MIB2_SCTP_ADDR_V4; 687 bzero(&sce.sctpAssocRemPrimAddr, 688 sizeof (sce.sctpAssocRemPrimAddr)); 689 bzero(&sce.sctpAssocLocPrimAddr, 690 sizeof (sce.sctpAssocLocPrimAddr)); 691 sce.sctpAssocHeartBeatInterval = 692 sctps->sctps_heartbeat_interval; 693 } 694 695 /* 696 * Table for local addresses 697 */ 698 scanned = 0; 699 for (i = 0; i < SCTP_IPIF_HASH; i++) { 700 sctp_saddr_ipif_t *obj; 701 702 if (sctp->sctp_saddrs[i].ipif_count == 0) 703 continue; 704 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list); 705 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) { 706 sctp_ipif_t *sctp_ipif; 707 in6_addr_t addr; 708 709 sctp_ipif = obj->saddr_ipifp; 710 addr = sctp_ipif->sctp_ipif_saddr; 711 scanned++; 712 scle.sctpAssocId = ntohl(sctp->sctp_lvtag); 713 if (IN6_IS_ADDR_V4MAPPED(&addr)) { 714 scle.sctpAssocLocalAddrType = 715 MIB2_SCTP_ADDR_V4; 716 } else { 717 scle.sctpAssocLocalAddrType = 718 MIB2_SCTP_ADDR_V6; 719 } 720 scle.sctpAssocLocalAddr = addr; 721 (void) snmp_append_data2(mp_local_data, 722 &mp_local_tail, (char *)&scle, 723 sizeof (scle)); 724 if (scanned >= sctp->sctp_nsaddrs) 725 goto done; 726 obj = list_next(&sctp-> 727 sctp_saddrs[i].sctp_ipif_list, obj); 728 } 729 } 730 done: 731 /* 732 * Table for remote addresses 733 */ 734 for (fp = sctp->sctp_faddrs; fp; fp = fp->sf_next) { 735 scre.sctpAssocId = ntohl(sctp->sctp_lvtag); 736 if (IN6_IS_ADDR_V4MAPPED(&fp->sf_faddr)) { 737 scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V4; 738 } else { 739 scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V6; 740 } 741 scre.sctpAssocRemAddr = fp->sf_faddr; 742 if (fp->sf_state == SCTP_FADDRS_ALIVE) { 743 scre.sctpAssocRemAddrActive = 744 scre.sctpAssocRemAddrHBActive = 745 MIB2_SCTP_ACTIVE; 746 } else { 747 scre.sctpAssocRemAddrActive = 748 scre.sctpAssocRemAddrHBActive = 749 MIB2_SCTP_INACTIVE; 750 } 751 scre.sctpAssocRemAddrRTO = TICK_TO_MSEC(fp->sf_rto); 752 scre.sctpAssocRemAddrMaxPathRtx = fp->sf_max_retr; 753 scre.sctpAssocRemAddrRtx = fp->sf_T3expire; 754 (void) snmp_append_data2(mp_rem_data, &mp_rem_tail, 755 (char *)&scre, sizeof (scre)); 756 } 757 connp = sctp->sctp_connp; 758 needattr = B_FALSE; 759 bzero(&mlp, sizeof (mlp)); 760 if (connp->conn_mlp_type != mlptSingle) { 761 if (connp->conn_mlp_type == mlptShared || 762 connp->conn_mlp_type == mlptBoth) 763 mlp.tme_flags |= MIB2_TMEF_SHARED; 764 if (connp->conn_mlp_type == mlptPrivate || 765 connp->conn_mlp_type == mlptBoth) 766 mlp.tme_flags |= MIB2_TMEF_PRIVATE; 767 needattr = B_TRUE; 768 } 769 if (connp->conn_anon_mlp) { 770 mlp.tme_flags |= MIB2_TMEF_ANONMLP; 771 needattr = B_TRUE; 772 } 773 switch (connp->conn_mac_mode) { 774 case CONN_MAC_DEFAULT: 775 break; 776 case CONN_MAC_AWARE: 777 mlp.tme_flags |= MIB2_TMEF_MACEXEMPT; 778 needattr = B_TRUE; 779 break; 780 case CONN_MAC_IMPLICIT: 781 mlp.tme_flags |= MIB2_TMEF_MACIMPLICIT; 782 needattr = B_TRUE; 783 break; 784 } 785 if (sctp->sctp_connp->conn_ixa->ixa_tsl != NULL) { 786 ts_label_t *tsl; 787 788 tsl = sctp->sctp_connp->conn_ixa->ixa_tsl; 789 mlp.tme_flags |= MIB2_TMEF_IS_LABELED; 790 mlp.tme_doi = label2doi(tsl); 791 mlp.tme_label = *label2bslabel(tsl); 792 needattr = B_TRUE; 793 } 794 WAKE_SCTP(sctp); 795 sce.sctpAssocState = sctp_snmp_state(sctp); 796 sce.sctpAssocInStreams = sctp->sctp_num_istr; 797 sce.sctpAssocOutStreams = sctp->sctp_num_ostr; 798 sce.sctpAssocMaxRetr = sctp->sctp_pa_max_rxt; 799 /* A 0 here indicates that no primary process is known */ 800 sce.sctpAssocPrimProcess = 0; 801 sce.sctpAssocT1expired = sctp->sctp_T1expire; 802 sce.sctpAssocT2expired = sctp->sctp_T2expire; 803 sce.sctpAssocRtxChunks = sctp->sctp_T3expire; 804 sce.sctpAssocStartTime = sctp->sctp_assoc_start_time; 805 sce.sctpConnEntryInfo.ce_sendq = sctp->sctp_unacked + 806 sctp->sctp_unsent; 807 sce.sctpConnEntryInfo.ce_recvq = sctp->sctp_rxqueued; 808 sce.sctpConnEntryInfo.ce_swnd = sctp->sctp_frwnd; 809 sce.sctpConnEntryInfo.ce_rwnd = sctp->sctp_rwnd; 810 sce.sctpConnEntryInfo.ce_mss = sctp->sctp_mss; 811 (void) snmp_append_data2(mp_conn_data, &mp_conn_tail, 812 (char *)&sce, sizeof (sce)); 813 814 (void) snmp_append_data2(mp_pidnode_data, &mp_pidnode_tail, 815 (char *)&sce, sizeof (sce)); 816 817 (void) snmp_append_mblk2(mp_pidnode_data, &mp_pidnode_tail, 818 conn_get_pid_mblk(connp)); 819 820 mlp.tme_connidx = idx++; 821 if (needattr) 822 (void) snmp_append_data2(mp_attr_ctl->b_cont, 823 &mp_attr_tail, (char *)&mlp, sizeof (mlp)); 824 next_sctp: 825 sctp_prev = sctp; 826 mutex_enter(&sctps->sctps_g_lock); 827 sctp = list_next(&sctps->sctps_g_list, sctp); 828 } 829 mutex_exit(&sctps->sctps_g_lock); 830 if (sctp_prev != NULL) 831 SCTP_REFRELE(sctp_prev); 832 833 sctp_sum_mib(sctps, &sctp_mib); 834 835 optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)]; 836 optp->level = MIB2_SCTP; 837 optp->name = 0; 838 (void) snmp_append_data(mpdata, (char *)&sctp_mib, sizeof (sctp_mib)); 839 optp->len = msgdsize(mpdata); 840 qreply(q, mpctl); 841 842 /* table of connections... */ 843 optp = (struct opthdr *)&mp_conn_ctl->b_rptr[ 844 sizeof (struct T_optmgmt_ack)]; 845 optp->level = MIB2_SCTP; 846 optp->name = MIB2_SCTP_CONN; 847 optp->len = msgdsize(mp_conn_data); 848 qreply(q, mp_conn_ctl); 849 850 /* table of EXPER_XPORT_PROC_INFO */ 851 optp = (struct opthdr *)&mp_pidnode_ctl->b_rptr[ 852 sizeof (struct T_optmgmt_ack)]; 853 optp->level = MIB2_SCTP; 854 optp->name = EXPER_XPORT_PROC_INFO; 855 optp->len = msgdsize(mp_pidnode_data); 856 qreply(q, mp_pidnode_ctl); 857 858 /* assoc local address table */ 859 optp = (struct opthdr *)&mp_local_ctl->b_rptr[ 860 sizeof (struct T_optmgmt_ack)]; 861 optp->level = MIB2_SCTP; 862 optp->name = MIB2_SCTP_CONN_LOCAL; 863 optp->len = msgdsize(mp_local_data); 864 qreply(q, mp_local_ctl); 865 866 /* assoc remote address table */ 867 optp = (struct opthdr *)&mp_rem_ctl->b_rptr[ 868 sizeof (struct T_optmgmt_ack)]; 869 optp->level = MIB2_SCTP; 870 optp->name = MIB2_SCTP_CONN_REMOTE; 871 optp->len = msgdsize(mp_rem_data); 872 qreply(q, mp_rem_ctl); 873 874 /* table of MLP attributes */ 875 optp = (struct opthdr *)&mp_attr_ctl->b_rptr[ 876 sizeof (struct T_optmgmt_ack)]; 877 optp->level = MIB2_SCTP; 878 optp->name = EXPER_XPORT_MLP; 879 optp->len = msgdsize(mp_attr_data); 880 if (optp->len == 0) 881 freemsg(mp_attr_ctl); 882 else 883 qreply(q, mp_attr_ctl); 884 885 return (mp_ret); 886 } 887 888 /* Translate SCTP state to MIB2 SCTP state. */ 889 static int 890 sctp_snmp_state(sctp_t *sctp) 891 { 892 if (sctp == NULL) 893 return (0); 894 895 switch (sctp->sctp_state) { 896 case SCTPS_IDLE: 897 case SCTPS_BOUND: 898 return (MIB2_SCTP_closed); 899 case SCTPS_LISTEN: 900 return (MIB2_SCTP_listen); 901 case SCTPS_COOKIE_WAIT: 902 return (MIB2_SCTP_cookieWait); 903 case SCTPS_COOKIE_ECHOED: 904 return (MIB2_SCTP_cookieEchoed); 905 case SCTPS_ESTABLISHED: 906 return (MIB2_SCTP_established); 907 case SCTPS_SHUTDOWN_PENDING: 908 return (MIB2_SCTP_shutdownPending); 909 case SCTPS_SHUTDOWN_SENT: 910 return (MIB2_SCTP_shutdownSent); 911 case SCTPS_SHUTDOWN_RECEIVED: 912 return (MIB2_SCTP_shutdownReceived); 913 case SCTPS_SHUTDOWN_ACK_SENT: 914 return (MIB2_SCTP_shutdownAckSent); 915 default: 916 return (0); 917 } 918 } 919 920 /* 921 * To sum up all MIB2 stats for a sctp_stack_t from all per CPU stats. The 922 * caller should initialize the target mib2_sctp_t properly as this function 923 * just adds up all the per CPU stats. 924 */ 925 static void 926 sctp_sum_mib(sctp_stack_t *sctps, mib2_sctp_t *sctp_mib) 927 { 928 int i; 929 int cnt; 930 931 /* Static componets of mib2_sctp_t. */ 932 SET_MIB(sctp_mib->sctpRtoAlgorithm, MIB2_SCTP_RTOALGO_VANJ); 933 SET_MIB(sctp_mib->sctpRtoMin, sctps->sctps_rto_ming); 934 SET_MIB(sctp_mib->sctpRtoMax, sctps->sctps_rto_maxg); 935 SET_MIB(sctp_mib->sctpRtoInitial, sctps->sctps_rto_initialg); 936 SET_MIB(sctp_mib->sctpMaxAssocs, -1); 937 SET_MIB(sctp_mib->sctpValCookieLife, sctps->sctps_cookie_life); 938 SET_MIB(sctp_mib->sctpMaxInitRetr, sctps->sctps_max_init_retr); 939 940 /* fixed length structure for IPv4 and IPv6 counters */ 941 SET_MIB(sctp_mib->sctpEntrySize, sizeof (mib2_sctpConnEntry_t)); 942 SET_MIB(sctp_mib->sctpLocalEntrySize, 943 sizeof (mib2_sctpConnLocalEntry_t)); 944 SET_MIB(sctp_mib->sctpRemoteEntrySize, 945 sizeof (mib2_sctpConnRemoteEntry_t)); 946 947 /* 948 * sctps_sc_cnt may change in the middle of the loop. It is better 949 * to get its value first. 950 */ 951 cnt = sctps->sctps_sc_cnt; 952 for (i = 0; i < cnt; i++) 953 sctp_add_mib(&sctps->sctps_sc[i]->sctp_sc_mib, sctp_mib); 954 } 955 956 static void 957 sctp_add_mib(mib2_sctp_t *from, mib2_sctp_t *to) 958 { 959 to->sctpActiveEstab += from->sctpActiveEstab; 960 to->sctpPassiveEstab += from->sctpPassiveEstab; 961 to->sctpAborted += from->sctpAborted; 962 to->sctpShutdowns += from->sctpShutdowns; 963 to->sctpOutOfBlue += from->sctpOutOfBlue; 964 to->sctpChecksumError += from->sctpChecksumError; 965 to->sctpOutCtrlChunks += from->sctpOutCtrlChunks; 966 to->sctpOutOrderChunks += from->sctpOutOrderChunks; 967 to->sctpOutUnorderChunks += from->sctpOutUnorderChunks; 968 to->sctpRetransChunks += from->sctpRetransChunks; 969 to->sctpOutAck += from->sctpOutAck; 970 to->sctpOutAckDelayed += from->sctpOutAckDelayed; 971 to->sctpOutWinUpdate += from->sctpOutWinUpdate; 972 to->sctpOutFastRetrans += from->sctpOutFastRetrans; 973 to->sctpOutWinProbe += from->sctpOutWinProbe; 974 to->sctpInCtrlChunks += from->sctpInCtrlChunks; 975 to->sctpInOrderChunks += from->sctpInOrderChunks; 976 to->sctpInUnorderChunks += from->sctpInUnorderChunks; 977 to->sctpInAck += from->sctpInAck; 978 to->sctpInDupAck += from->sctpInDupAck; 979 to->sctpInAckUnsent += from->sctpInAckUnsent; 980 to->sctpFragUsrMsgs += from->sctpFragUsrMsgs; 981 to->sctpReasmUsrMsgs += from->sctpReasmUsrMsgs; 982 to->sctpOutSCTPPkts += from->sctpOutSCTPPkts; 983 to->sctpInSCTPPkts += from->sctpInSCTPPkts; 984 to->sctpInInvalidCookie += from->sctpInInvalidCookie; 985 to->sctpTimRetrans += from->sctpTimRetrans; 986 to->sctpTimRetransDrop += from->sctpTimRetransDrop; 987 to->sctpTimHeartBeatProbe += from->sctpTimHeartBeatProbe; 988 to->sctpTimHeartBeatDrop += from->sctpTimHeartBeatDrop; 989 to->sctpListenDrop += from->sctpListenDrop; 990 to->sctpInClosed += from->sctpInClosed; 991 }