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 }