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