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 }