Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/inet/tcp/tcp_stats.c
+++ new/usr/src/uts/common/inet/tcp/tcp_stats.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright (c) 2011, Joyent Inc. All rights reserved.
25 25 */
26 26
27 27 #include <sys/types.h>
28 28 #include <sys/tihdr.h>
29 29 #include <sys/policy.h>
30 30 #include <sys/tsol/tnet.h>
31 31 #include <sys/kstat.h>
32 32
33 33 #include <inet/common.h>
34 34 #include <inet/ip.h>
35 35 #include <inet/tcp.h>
36 36 #include <inet/tcp_impl.h>
37 37 #include <inet/tcp_stats.h>
38 38 #include <inet/kstatcom.h>
39 39 #include <inet/snmpcom.h>
40 40
41 41 static int tcp_kstat_update(kstat_t *, int);
42 42 static int tcp_kstat2_update(kstat_t *, int);
43 43 static void tcp_sum_mib(tcp_stack_t *, mib2_tcp_t *);
44 44
45 45 static void tcp_add_mib(mib2_tcp_t *, mib2_tcp_t *);
46 46 static void tcp_add_stats(tcp_stat_counter_t *, tcp_stat_t *);
47 47 static void tcp_clr_stats(tcp_stat_t *);
48 48
49 49 tcp_g_stat_t tcp_g_statistics;
50 50 kstat_t *tcp_g_kstat;
51 51
52 52 /* Translate TCP state to MIB2 TCP state. */
53 53 static int
54 54 tcp_snmp_state(tcp_t *tcp)
55 55 {
56 56 if (tcp == NULL)
57 57 return (0);
58 58
59 59 switch (tcp->tcp_state) {
60 60 case TCPS_CLOSED:
61 61 case TCPS_IDLE: /* RFC1213 doesn't have analogue for IDLE & BOUND */
62 62 case TCPS_BOUND:
63 63 return (MIB2_TCP_closed);
64 64 case TCPS_LISTEN:
65 65 return (MIB2_TCP_listen);
66 66 case TCPS_SYN_SENT:
67 67 return (MIB2_TCP_synSent);
68 68 case TCPS_SYN_RCVD:
69 69 return (MIB2_TCP_synReceived);
70 70 case TCPS_ESTABLISHED:
71 71 return (MIB2_TCP_established);
72 72 case TCPS_CLOSE_WAIT:
73 73 return (MIB2_TCP_closeWait);
74 74 case TCPS_FIN_WAIT_1:
75 75 return (MIB2_TCP_finWait1);
76 76 case TCPS_CLOSING:
77 77 return (MIB2_TCP_closing);
78 78 case TCPS_LAST_ACK:
79 79 return (MIB2_TCP_lastAck);
80 80 case TCPS_FIN_WAIT_2:
81 81 return (MIB2_TCP_finWait2);
82 82 case TCPS_TIME_WAIT:
83 83 return (MIB2_TCP_timeWait);
84 84 default:
85 85 return (0);
86 86 }
87 87 }
88 88
89 89 /*
90 90 * Return SNMP stuff in buffer in mpdata.
91 91 */
92 92 mblk_t *
93 93 tcp_snmp_get(queue_t *q, mblk_t *mpctl, boolean_t legacy_req)
94 94 {
95 95 mblk_t *mpdata;
96 96 mblk_t *mp_conn_ctl = NULL;
97 97 mblk_t *mp_conn_tail;
98 98 mblk_t *mp_attr_ctl = NULL;
99 99 mblk_t *mp_attr_tail;
100 100 mblk_t *mp6_conn_ctl = NULL;
101 101 mblk_t *mp6_conn_tail;
102 102 mblk_t *mp6_attr_ctl = NULL;
103 103 mblk_t *mp6_attr_tail;
104 104 struct opthdr *optp;
105 105 mib2_tcpConnEntry_t tce;
106 106 mib2_tcp6ConnEntry_t tce6;
107 107 mib2_transportMLPEntry_t mlp;
108 108 connf_t *connfp;
109 109 int i;
110 110 boolean_t ispriv;
111 111 zoneid_t zoneid;
112 112 int v4_conn_idx;
113 113 int v6_conn_idx;
114 114 conn_t *connp = Q_TO_CONN(q);
115 115 tcp_stack_t *tcps;
116 116 ip_stack_t *ipst;
117 117 mblk_t *mp2ctl;
118 118 mib2_tcp_t tcp_mib;
119 119 size_t tcp_mib_size, tce_size, tce6_size;
120 120
121 121 /*
122 122 * make a copy of the original message
123 123 */
124 124 mp2ctl = copymsg(mpctl);
125 125
126 126 if (mpctl == NULL ||
127 127 (mpdata = mpctl->b_cont) == NULL ||
128 128 (mp_conn_ctl = copymsg(mpctl)) == NULL ||
129 129 (mp_attr_ctl = copymsg(mpctl)) == NULL ||
130 130 (mp6_conn_ctl = copymsg(mpctl)) == NULL ||
131 131 (mp6_attr_ctl = copymsg(mpctl)) == NULL) {
132 132 freemsg(mp_conn_ctl);
133 133 freemsg(mp_attr_ctl);
134 134 freemsg(mp6_conn_ctl);
135 135 freemsg(mp6_attr_ctl);
136 136 freemsg(mpctl);
137 137 freemsg(mp2ctl);
138 138 return (NULL);
139 139 }
140 140
141 141 ipst = connp->conn_netstack->netstack_ip;
142 142 tcps = connp->conn_netstack->netstack_tcp;
143 143
144 144 if (legacy_req) {
145 145 tcp_mib_size = LEGACY_MIB_SIZE(&tcp_mib, mib2_tcp_t);
146 146 tce_size = LEGACY_MIB_SIZE(&tce, mib2_tcpConnEntry_t);
147 147 tce6_size = LEGACY_MIB_SIZE(&tce6, mib2_tcp6ConnEntry_t);
148 148 } else {
149 149 tcp_mib_size = sizeof (mib2_tcp_t);
150 150 tce_size = sizeof (mib2_tcpConnEntry_t);
151 151 tce6_size = sizeof (mib2_tcp6ConnEntry_t);
152 152 }
153 153
154 154 bzero(&tcp_mib, sizeof (tcp_mib));
155 155
156 156 /* build table of connections -- need count in fixed part */
157 157 SET_MIB(tcp_mib.tcpRtoAlgorithm, 4); /* vanj */
158 158 SET_MIB(tcp_mib.tcpRtoMin, tcps->tcps_rexmit_interval_min);
159 159 SET_MIB(tcp_mib.tcpRtoMax, tcps->tcps_rexmit_interval_max);
160 160 SET_MIB(tcp_mib.tcpMaxConn, -1);
161 161 SET_MIB(tcp_mib.tcpCurrEstab, 0);
162 162
163 163 ispriv =
164 164 secpolicy_ip_config((Q_TO_CONN(q))->conn_cred, B_TRUE) == 0;
165 165 zoneid = Q_TO_CONN(q)->conn_zoneid;
166 166
167 167 v4_conn_idx = v6_conn_idx = 0;
168 168 mp_conn_tail = mp_attr_tail = mp6_conn_tail = mp6_attr_tail = NULL;
169 169
170 170 for (i = 0; i < CONN_G_HASH_SIZE; i++) {
171 171 ipst = tcps->tcps_netstack->netstack_ip;
172 172
173 173 connfp = &ipst->ips_ipcl_globalhash_fanout[i];
174 174
175 175 connp = NULL;
176 176
177 177 while ((connp =
178 178 ipcl_get_next_conn(connfp, connp, IPCL_TCPCONN)) != NULL) {
179 179 tcp_t *tcp;
180 180 boolean_t needattr;
181 181
182 182 if (connp->conn_zoneid != zoneid)
183 183 continue; /* not in this zone */
184 184
185 185 tcp = connp->conn_tcp;
186 186 TCPS_UPDATE_MIB(tcps, tcpHCInSegs, tcp->tcp_ibsegs);
187 187 tcp->tcp_ibsegs = 0;
188 188 TCPS_UPDATE_MIB(tcps, tcpHCOutSegs, tcp->tcp_obsegs);
189 189 tcp->tcp_obsegs = 0;
190 190
191 191 tce6.tcp6ConnState = tce.tcpConnState =
192 192 tcp_snmp_state(tcp);
193 193 if (tce.tcpConnState == MIB2_TCP_established ||
194 194 tce.tcpConnState == MIB2_TCP_closeWait)
195 195 BUMP_MIB(&tcp_mib, tcpCurrEstab);
196 196
197 197 needattr = B_FALSE;
198 198 bzero(&mlp, sizeof (mlp));
199 199 if (connp->conn_mlp_type != mlptSingle) {
200 200 if (connp->conn_mlp_type == mlptShared ||
201 201 connp->conn_mlp_type == mlptBoth)
202 202 mlp.tme_flags |= MIB2_TMEF_SHARED;
203 203 if (connp->conn_mlp_type == mlptPrivate ||
204 204 connp->conn_mlp_type == mlptBoth)
205 205 mlp.tme_flags |= MIB2_TMEF_PRIVATE;
206 206 needattr = B_TRUE;
207 207 }
208 208 if (connp->conn_anon_mlp) {
209 209 mlp.tme_flags |= MIB2_TMEF_ANONMLP;
210 210 needattr = B_TRUE;
211 211 }
212 212 switch (connp->conn_mac_mode) {
213 213 case CONN_MAC_DEFAULT:
214 214 break;
215 215 case CONN_MAC_AWARE:
216 216 mlp.tme_flags |= MIB2_TMEF_MACEXEMPT;
217 217 needattr = B_TRUE;
218 218 break;
219 219 case CONN_MAC_IMPLICIT:
220 220 mlp.tme_flags |= MIB2_TMEF_MACIMPLICIT;
221 221 needattr = B_TRUE;
222 222 break;
223 223 }
224 224 if (connp->conn_ixa->ixa_tsl != NULL) {
225 225 ts_label_t *tsl;
226 226
227 227 tsl = connp->conn_ixa->ixa_tsl;
228 228 mlp.tme_flags |= MIB2_TMEF_IS_LABELED;
229 229 mlp.tme_doi = label2doi(tsl);
230 230 mlp.tme_label = *label2bslabel(tsl);
231 231 needattr = B_TRUE;
232 232 }
233 233
234 234 /* Create a message to report on IPv6 entries */
235 235 if (connp->conn_ipversion == IPV6_VERSION) {
236 236 tce6.tcp6ConnLocalAddress = connp->conn_laddr_v6;
237 237 tce6.tcp6ConnRemAddress = connp->conn_faddr_v6;
238 238 tce6.tcp6ConnLocalPort = ntohs(connp->conn_lport);
239 239 tce6.tcp6ConnRemPort = ntohs(connp->conn_fport);
240 240 if (connp->conn_ixa->ixa_flags & IXAF_SCOPEID_SET) {
241 241 tce6.tcp6ConnIfIndex =
242 242 connp->conn_ixa->ixa_scopeid;
243 243 } else {
244 244 tce6.tcp6ConnIfIndex = connp->conn_bound_if;
245 245 }
246 246 /* Don't want just anybody seeing these... */
247 247 if (ispriv) {
248 248 tce6.tcp6ConnEntryInfo.ce_snxt =
249 249 tcp->tcp_snxt;
250 250 tce6.tcp6ConnEntryInfo.ce_suna =
251 251 tcp->tcp_suna;
252 252 tce6.tcp6ConnEntryInfo.ce_rnxt =
253 253 tcp->tcp_rnxt;
254 254 tce6.tcp6ConnEntryInfo.ce_rack =
255 255 tcp->tcp_rack;
256 256 } else {
257 257 /*
258 258 * Netstat, unfortunately, uses this to
259 259 * get send/receive queue sizes. How to fix?
260 260 * Why not compute the difference only?
261 261 */
262 262 tce6.tcp6ConnEntryInfo.ce_snxt =
263 263 tcp->tcp_snxt - tcp->tcp_suna;
264 264 tce6.tcp6ConnEntryInfo.ce_suna = 0;
265 265 tce6.tcp6ConnEntryInfo.ce_rnxt =
266 266 tcp->tcp_rnxt - tcp->tcp_rack;
267 267 tce6.tcp6ConnEntryInfo.ce_rack = 0;
268 268 }
269 269
270 270 tce6.tcp6ConnEntryInfo.ce_swnd = tcp->tcp_swnd;
271 271 tce6.tcp6ConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
272 272 tce6.tcp6ConnEntryInfo.ce_rto = tcp->tcp_rto;
273 273 tce6.tcp6ConnEntryInfo.ce_mss = tcp->tcp_mss;
274 274 tce6.tcp6ConnEntryInfo.ce_state = tcp->tcp_state;
275 275
276 276 tce6.tcp6ConnCreationProcess =
277 277 (connp->conn_cpid < 0) ? MIB2_UNKNOWN_PROCESS :
278 278 connp->conn_cpid;
279 279 tce6.tcp6ConnCreationTime = connp->conn_open_time;
280 280
281 281 (void) snmp_append_data2(mp6_conn_ctl->b_cont,
282 282 &mp6_conn_tail, (char *)&tce6, tce6_size);
283 283
284 284 mlp.tme_connidx = v6_conn_idx++;
285 285 if (needattr)
286 286 (void) snmp_append_data2(mp6_attr_ctl->b_cont,
287 287 &mp6_attr_tail, (char *)&mlp, sizeof (mlp));
288 288 }
289 289 /*
290 290 * Create an IPv4 table entry for IPv4 entries and also
291 291 * for IPv6 entries which are bound to in6addr_any
292 292 * but don't have IPV6_V6ONLY set.
293 293 * (i.e. anything an IPv4 peer could connect to)
294 294 */
295 295 if (connp->conn_ipversion == IPV4_VERSION ||
296 296 (tcp->tcp_state <= TCPS_LISTEN &&
297 297 !connp->conn_ipv6_v6only &&
298 298 IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6))) {
299 299 if (connp->conn_ipversion == IPV6_VERSION) {
300 300 tce.tcpConnRemAddress = INADDR_ANY;
301 301 tce.tcpConnLocalAddress = INADDR_ANY;
302 302 } else {
303 303 tce.tcpConnRemAddress =
304 304 connp->conn_faddr_v4;
305 305 tce.tcpConnLocalAddress =
306 306 connp->conn_laddr_v4;
307 307 }
308 308 tce.tcpConnLocalPort = ntohs(connp->conn_lport);
309 309 tce.tcpConnRemPort = ntohs(connp->conn_fport);
310 310 /* Don't want just anybody seeing these... */
311 311 if (ispriv) {
312 312 tce.tcpConnEntryInfo.ce_snxt =
313 313 tcp->tcp_snxt;
314 314 tce.tcpConnEntryInfo.ce_suna =
315 315 tcp->tcp_suna;
316 316 tce.tcpConnEntryInfo.ce_rnxt =
317 317 tcp->tcp_rnxt;
318 318 tce.tcpConnEntryInfo.ce_rack =
319 319 tcp->tcp_rack;
320 320 } else {
321 321 /*
322 322 * Netstat, unfortunately, uses this to
323 323 * get send/receive queue sizes. How
324 324 * to fix?
325 325 * Why not compute the difference only?
326 326 */
327 327 tce.tcpConnEntryInfo.ce_snxt =
328 328 tcp->tcp_snxt - tcp->tcp_suna;
329 329 tce.tcpConnEntryInfo.ce_suna = 0;
330 330 tce.tcpConnEntryInfo.ce_rnxt =
331 331 tcp->tcp_rnxt - tcp->tcp_rack;
332 332 tce.tcpConnEntryInfo.ce_rack = 0;
333 333 }
334 334
335 335 tce.tcpConnEntryInfo.ce_swnd = tcp->tcp_swnd;
336 336 tce.tcpConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
337 337 tce.tcpConnEntryInfo.ce_rto = tcp->tcp_rto;
338 338 tce.tcpConnEntryInfo.ce_mss = tcp->tcp_mss;
339 339 tce.tcpConnEntryInfo.ce_state =
340 340 tcp->tcp_state;
341 341
342 342 tce.tcpConnCreationProcess =
343 343 (connp->conn_cpid < 0) ?
344 344 MIB2_UNKNOWN_PROCESS :
345 345 connp->conn_cpid;
346 346 tce.tcpConnCreationTime = connp->conn_open_time;
347 347
348 348 (void) snmp_append_data2(mp_conn_ctl->b_cont,
349 349 &mp_conn_tail, (char *)&tce, tce_size);
350 350
351 351 mlp.tme_connidx = v4_conn_idx++;
352 352 if (needattr)
353 353 (void) snmp_append_data2(
354 354 mp_attr_ctl->b_cont,
355 355 &mp_attr_tail, (char *)&mlp,
356 356 sizeof (mlp));
357 357 }
358 358 }
359 359 }
360 360
361 361 tcp_sum_mib(tcps, &tcp_mib);
362 362
363 363 /* Fixed length structure for IPv4 and IPv6 counters */
364 364 SET_MIB(tcp_mib.tcpConnTableSize, tce_size);
365 365 SET_MIB(tcp_mib.tcp6ConnTableSize, tce6_size);
366 366
367 367 /*
368 368 * Synchronize 32- and 64-bit counters. Note that tcpInSegs and
369 369 * tcpOutSegs are not updated anywhere in TCP. The new 64 bits
370 370 * counters are used. Hence the old counters' values in tcp_sc_mib
371 371 * are always 0.
372 372 */
373 373 SYNC32_MIB(&tcp_mib, tcpInSegs, tcpHCInSegs);
374 374 SYNC32_MIB(&tcp_mib, tcpOutSegs, tcpHCOutSegs);
375 375
376 376 optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
377 377 optp->level = MIB2_TCP;
378 378 optp->name = 0;
379 379 (void) snmp_append_data(mpdata, (char *)&tcp_mib, tcp_mib_size);
380 380 optp->len = msgdsize(mpdata);
381 381 qreply(q, mpctl);
382 382
383 383 /* table of connections... */
384 384 optp = (struct opthdr *)&mp_conn_ctl->b_rptr[
385 385 sizeof (struct T_optmgmt_ack)];
386 386 optp->level = MIB2_TCP;
387 387 optp->name = MIB2_TCP_CONN;
388 388 optp->len = msgdsize(mp_conn_ctl->b_cont);
389 389 qreply(q, mp_conn_ctl);
390 390
391 391 /* table of MLP attributes... */
392 392 optp = (struct opthdr *)&mp_attr_ctl->b_rptr[
393 393 sizeof (struct T_optmgmt_ack)];
394 394 optp->level = MIB2_TCP;
395 395 optp->name = EXPER_XPORT_MLP;
396 396 optp->len = msgdsize(mp_attr_ctl->b_cont);
397 397 if (optp->len == 0)
398 398 freemsg(mp_attr_ctl);
399 399 else
400 400 qreply(q, mp_attr_ctl);
401 401
402 402 /* table of IPv6 connections... */
403 403 optp = (struct opthdr *)&mp6_conn_ctl->b_rptr[
404 404 sizeof (struct T_optmgmt_ack)];
405 405 optp->level = MIB2_TCP6;
406 406 optp->name = MIB2_TCP6_CONN;
407 407 optp->len = msgdsize(mp6_conn_ctl->b_cont);
408 408 qreply(q, mp6_conn_ctl);
409 409
410 410 /* table of IPv6 MLP attributes... */
411 411 optp = (struct opthdr *)&mp6_attr_ctl->b_rptr[
412 412 sizeof (struct T_optmgmt_ack)];
413 413 optp->level = MIB2_TCP6;
414 414 optp->name = EXPER_XPORT_MLP;
415 415 optp->len = msgdsize(mp6_attr_ctl->b_cont);
416 416 if (optp->len == 0)
417 417 freemsg(mp6_attr_ctl);
418 418 else
419 419 qreply(q, mp6_attr_ctl);
420 420 return (mp2ctl);
421 421 }
422 422
423 423 /* Return 0 if invalid set request, 1 otherwise, including non-tcp requests */
424 424 /* ARGSUSED */
425 425 int
426 426 tcp_snmp_set(queue_t *q, int level, int name, uchar_t *ptr, int len)
427 427 {
428 428 mib2_tcpConnEntry_t *tce = (mib2_tcpConnEntry_t *)ptr;
429 429
430 430 switch (level) {
431 431 case MIB2_TCP:
432 432 switch (name) {
433 433 case 13:
434 434 if (tce->tcpConnState != MIB2_TCP_deleteTCB)
435 435 return (0);
436 436 /* TODO: delete entry defined by tce */
437 437 return (1);
438 438 default:
439 439 return (0);
440 440 }
441 441 default:
442 442 return (1);
443 443 }
444 444 }
↓ open down ↓ |
444 lines elided |
↑ open up ↑ |
445 445
446 446 /*
447 447 * TCP Kstats implementation
448 448 */
449 449 void *
450 450 tcp_kstat_init(netstackid_t stackid)
451 451 {
452 452 kstat_t *ksp;
453 453
454 454 tcp_named_kstat_t template = {
455 - { "rtoAlgorithm", KSTAT_DATA_INT32, 0 },
456 - { "rtoMin", KSTAT_DATA_INT32, 0 },
457 - { "rtoMax", KSTAT_DATA_INT32, 0 },
458 - { "maxConn", KSTAT_DATA_INT32, 0 },
459 - { "activeOpens", KSTAT_DATA_UINT32, 0 },
460 - { "passiveOpens", KSTAT_DATA_UINT32, 0 },
461 - { "attemptFails", KSTAT_DATA_UINT32, 0 },
462 - { "estabResets", KSTAT_DATA_UINT32, 0 },
463 - { "currEstab", KSTAT_DATA_UINT32, 0 },
464 - { "inSegs", KSTAT_DATA_UINT64, 0 },
465 - { "outSegs", KSTAT_DATA_UINT64, 0 },
466 - { "retransSegs", KSTAT_DATA_UINT32, 0 },
467 - { "connTableSize", KSTAT_DATA_INT32, 0 },
468 - { "outRsts", KSTAT_DATA_UINT32, 0 },
469 - { "outDataSegs", KSTAT_DATA_UINT32, 0 },
470 - { "outDataBytes", KSTAT_DATA_UINT32, 0 },
471 - { "retransBytes", KSTAT_DATA_UINT32, 0 },
472 - { "outAck", KSTAT_DATA_UINT32, 0 },
473 - { "outAckDelayed", KSTAT_DATA_UINT32, 0 },
474 - { "outUrg", KSTAT_DATA_UINT32, 0 },
475 - { "outWinUpdate", KSTAT_DATA_UINT32, 0 },
476 - { "outWinProbe", KSTAT_DATA_UINT32, 0 },
477 - { "outControl", KSTAT_DATA_UINT32, 0 },
478 - { "outFastRetrans", KSTAT_DATA_UINT32, 0 },
479 - { "inAckSegs", KSTAT_DATA_UINT32, 0 },
480 - { "inAckBytes", KSTAT_DATA_UINT32, 0 },
481 - { "inDupAck", KSTAT_DATA_UINT32, 0 },
482 - { "inAckUnsent", KSTAT_DATA_UINT32, 0 },
483 - { "inDataInorderSegs", KSTAT_DATA_UINT32, 0 },
484 - { "inDataInorderBytes", KSTAT_DATA_UINT32, 0 },
485 - { "inDataUnorderSegs", KSTAT_DATA_UINT32, 0 },
486 - { "inDataUnorderBytes", KSTAT_DATA_UINT32, 0 },
487 - { "inDataDupSegs", KSTAT_DATA_UINT32, 0 },
488 - { "inDataDupBytes", KSTAT_DATA_UINT32, 0 },
489 - { "inDataPartDupSegs", KSTAT_DATA_UINT32, 0 },
490 - { "inDataPartDupBytes", KSTAT_DATA_UINT32, 0 },
491 - { "inDataPastWinSegs", KSTAT_DATA_UINT32, 0 },
492 - { "inDataPastWinBytes", KSTAT_DATA_UINT32, 0 },
493 - { "inWinProbe", KSTAT_DATA_UINT32, 0 },
494 - { "inWinUpdate", KSTAT_DATA_UINT32, 0 },
495 - { "inClosed", KSTAT_DATA_UINT32, 0 },
496 - { "rttUpdate", KSTAT_DATA_UINT32, 0 },
497 - { "rttNoUpdate", KSTAT_DATA_UINT32, 0 },
498 - { "timRetrans", KSTAT_DATA_UINT32, 0 },
499 - { "timRetransDrop", KSTAT_DATA_UINT32, 0 },
500 - { "timKeepalive", KSTAT_DATA_UINT32, 0 },
501 - { "timKeepaliveProbe", KSTAT_DATA_UINT32, 0 },
502 - { "timKeepaliveDrop", KSTAT_DATA_UINT32, 0 },
503 - { "listenDrop", KSTAT_DATA_UINT32, 0 },
504 - { "listenDropQ0", KSTAT_DATA_UINT32, 0 },
505 - { "halfOpenDrop", KSTAT_DATA_UINT32, 0 },
506 - { "outSackRetransSegs", KSTAT_DATA_UINT32, 0 },
507 - { "connTableSize6", KSTAT_DATA_INT32, 0 }
455 + { "rtoAlgorithm", KSTAT_DATA_INT32, {{0}} },
456 + { "rtoMin", KSTAT_DATA_INT32, {{0}} },
457 + { "rtoMax", KSTAT_DATA_INT32, {{0}} },
458 + { "maxConn", KSTAT_DATA_INT32, {{0}} },
459 + { "activeOpens", KSTAT_DATA_UINT32, {{0}} },
460 + { "passiveOpens", KSTAT_DATA_UINT32, {{0}} },
461 + { "attemptFails", KSTAT_DATA_UINT32, {{0}} },
462 + { "estabResets", KSTAT_DATA_UINT32, {{0}} },
463 + { "currEstab", KSTAT_DATA_UINT32, {{0}} },
464 + { "inSegs", KSTAT_DATA_UINT64, {{0}} },
465 + { "outSegs", KSTAT_DATA_UINT64, {{0}} },
466 + { "retransSegs", KSTAT_DATA_UINT32, {{0}} },
467 + { "connTableSize", KSTAT_DATA_INT32, {{0}} },
468 + { "outRsts", KSTAT_DATA_UINT32, {{0}} },
469 + { "outDataSegs", KSTAT_DATA_UINT32, {{0}} },
470 + { "outDataBytes", KSTAT_DATA_UINT32, {{0}} },
471 + { "retransBytes", KSTAT_DATA_UINT32, {{0}} },
472 + { "outAck", KSTAT_DATA_UINT32, {{0}} },
473 + { "outAckDelayed", KSTAT_DATA_UINT32, {{0}} },
474 + { "outUrg", KSTAT_DATA_UINT32, {{0}} },
475 + { "outWinUpdate", KSTAT_DATA_UINT32, {{0}} },
476 + { "outWinProbe", KSTAT_DATA_UINT32, {{0}} },
477 + { "outControl", KSTAT_DATA_UINT32, {{0}} },
478 + { "outFastRetrans", KSTAT_DATA_UINT32, {{0}} },
479 + { "inAckSegs", KSTAT_DATA_UINT32, {{0}} },
480 + { "inAckBytes", KSTAT_DATA_UINT32, {{0}} },
481 + { "inDupAck", KSTAT_DATA_UINT32, {{0}} },
482 + { "inAckUnsent", KSTAT_DATA_UINT32, {{0}} },
483 + { "inDataInorderSegs", KSTAT_DATA_UINT32, {{0}} },
484 + { "inDataInorderBytes", KSTAT_DATA_UINT32, {{0}} },
485 + { "inDataUnorderSegs", KSTAT_DATA_UINT32, {{0}} },
486 + { "inDataUnorderBytes", KSTAT_DATA_UINT32, {{0}} },
487 + { "inDataDupSegs", KSTAT_DATA_UINT32, {{0}} },
488 + { "inDataDupBytes", KSTAT_DATA_UINT32, {{0}} },
489 + { "inDataPartDupSegs", KSTAT_DATA_UINT32, {{0}} },
490 + { "inDataPartDupBytes", KSTAT_DATA_UINT32, {{0}} },
491 + { "inDataPastWinSegs", KSTAT_DATA_UINT32, {{0}} },
492 + { "inDataPastWinBytes", KSTAT_DATA_UINT32, {{0}} },
493 + { "inWinProbe", KSTAT_DATA_UINT32, {{0}} },
494 + { "inWinUpdate", KSTAT_DATA_UINT32, {{0}} },
495 + { "inClosed", KSTAT_DATA_UINT32, {{0}} },
496 + { "rttUpdate", KSTAT_DATA_UINT32, {{0}} },
497 + { "rttNoUpdate", KSTAT_DATA_UINT32, {{0}} },
498 + { "timRetrans", KSTAT_DATA_UINT32, {{0}} },
499 + { "timRetransDrop", KSTAT_DATA_UINT32, {{0}} },
500 + { "timKeepalive", KSTAT_DATA_UINT32, {{0}} },
501 + { "timKeepaliveProbe", KSTAT_DATA_UINT32, {{0}} },
502 + { "timKeepaliveDrop", KSTAT_DATA_UINT32, {{0}} },
503 + { "listenDrop", KSTAT_DATA_UINT32, {{0}} },
504 + { "listenDropQ0", KSTAT_DATA_UINT32, {{0}} },
505 + { "halfOpenDrop", KSTAT_DATA_UINT32, {{0}} },
506 + { "outSackRetransSegs", KSTAT_DATA_UINT32, {{0}} },
507 + { "connTableSize6", KSTAT_DATA_INT32, {{0}} }
508 508 };
509 509
510 510 ksp = kstat_create_netstack(TCP_MOD_NAME, stackid, TCP_MOD_NAME, "mib2",
511 511 KSTAT_TYPE_NAMED, NUM_OF_FIELDS(tcp_named_kstat_t), 0, stackid);
512 512
513 513 if (ksp == NULL)
514 514 return (NULL);
515 515
516 516 template.rtoAlgorithm.value.ui32 = 4;
517 517 template.maxConn.value.i32 = -1;
518 518
519 519 bcopy(&template, ksp->ks_data, sizeof (template));
520 520 ksp->ks_update = tcp_kstat_update;
521 521 ksp->ks_private = (void *)(uintptr_t)stackid;
522 522
523 523 /*
524 524 * If this is an exclusive netstack for a local zone, the global zone
525 525 * should still be able to read the kstat.
526 526 */
527 527 if (stackid != GLOBAL_NETSTACKID)
528 528 kstat_zone_add(ksp, GLOBAL_ZONEID);
529 529
530 530 kstat_install(ksp);
531 531 return (ksp);
532 532 }
533 533
534 534 void
535 535 tcp_kstat_fini(netstackid_t stackid, kstat_t *ksp)
536 536 {
537 537 if (ksp != NULL) {
538 538 ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
539 539 kstat_delete_netstack(ksp, stackid);
540 540 }
541 541 }
542 542
543 543 static int
544 544 tcp_kstat_update(kstat_t *kp, int rw)
545 545 {
546 546 tcp_named_kstat_t *tcpkp;
547 547 tcp_t *tcp;
548 548 connf_t *connfp;
549 549 conn_t *connp;
550 550 int i;
551 551 netstackid_t stackid = (netstackid_t)(uintptr_t)kp->ks_private;
552 552 netstack_t *ns;
553 553 tcp_stack_t *tcps;
554 554 ip_stack_t *ipst;
555 555 mib2_tcp_t tcp_mib;
556 556
557 557 if (rw == KSTAT_WRITE)
558 558 return (EACCES);
559 559
560 560 ns = netstack_find_by_stackid(stackid);
561 561 if (ns == NULL)
562 562 return (-1);
563 563 tcps = ns->netstack_tcp;
564 564 if (tcps == NULL) {
565 565 netstack_rele(ns);
566 566 return (-1);
567 567 }
568 568
569 569 tcpkp = (tcp_named_kstat_t *)kp->ks_data;
570 570
571 571 tcpkp->currEstab.value.ui32 = 0;
572 572 tcpkp->rtoMin.value.ui32 = tcps->tcps_rexmit_interval_min;
573 573 tcpkp->rtoMax.value.ui32 = tcps->tcps_rexmit_interval_max;
574 574
575 575 ipst = ns->netstack_ip;
576 576
577 577 for (i = 0; i < CONN_G_HASH_SIZE; i++) {
578 578 connfp = &ipst->ips_ipcl_globalhash_fanout[i];
579 579 connp = NULL;
580 580 while ((connp =
581 581 ipcl_get_next_conn(connfp, connp, IPCL_TCPCONN)) != NULL) {
582 582 tcp = connp->conn_tcp;
583 583 switch (tcp_snmp_state(tcp)) {
584 584 case MIB2_TCP_established:
585 585 case MIB2_TCP_closeWait:
586 586 tcpkp->currEstab.value.ui32++;
587 587 break;
588 588 }
589 589 }
590 590 }
591 591 bzero(&tcp_mib, sizeof (tcp_mib));
592 592 tcp_sum_mib(tcps, &tcp_mib);
593 593
594 594 /* Fixed length structure for IPv4 and IPv6 counters */
595 595 SET_MIB(tcp_mib.tcpConnTableSize, sizeof (mib2_tcpConnEntry_t));
596 596 SET_MIB(tcp_mib.tcp6ConnTableSize, sizeof (mib2_tcp6ConnEntry_t));
597 597
598 598 tcpkp->activeOpens.value.ui32 = tcp_mib.tcpActiveOpens;
599 599 tcpkp->passiveOpens.value.ui32 = tcp_mib.tcpPassiveOpens;
600 600 tcpkp->attemptFails.value.ui32 = tcp_mib.tcpAttemptFails;
601 601 tcpkp->estabResets.value.ui32 = tcp_mib.tcpEstabResets;
602 602 tcpkp->inSegs.value.ui64 = tcp_mib.tcpHCInSegs;
603 603 tcpkp->outSegs.value.ui64 = tcp_mib.tcpHCOutSegs;
604 604 tcpkp->retransSegs.value.ui32 = tcp_mib.tcpRetransSegs;
605 605 tcpkp->connTableSize.value.i32 = tcp_mib.tcpConnTableSize;
606 606 tcpkp->outRsts.value.ui32 = tcp_mib.tcpOutRsts;
607 607 tcpkp->outDataSegs.value.ui32 = tcp_mib.tcpOutDataSegs;
608 608 tcpkp->outDataBytes.value.ui32 = tcp_mib.tcpOutDataBytes;
609 609 tcpkp->retransBytes.value.ui32 = tcp_mib.tcpRetransBytes;
610 610 tcpkp->outAck.value.ui32 = tcp_mib.tcpOutAck;
611 611 tcpkp->outAckDelayed.value.ui32 = tcp_mib.tcpOutAckDelayed;
612 612 tcpkp->outUrg.value.ui32 = tcp_mib.tcpOutUrg;
613 613 tcpkp->outWinUpdate.value.ui32 = tcp_mib.tcpOutWinUpdate;
614 614 tcpkp->outWinProbe.value.ui32 = tcp_mib.tcpOutWinProbe;
615 615 tcpkp->outControl.value.ui32 = tcp_mib.tcpOutControl;
616 616 tcpkp->outFastRetrans.value.ui32 = tcp_mib.tcpOutFastRetrans;
617 617 tcpkp->inAckSegs.value.ui32 = tcp_mib.tcpInAckSegs;
618 618 tcpkp->inAckBytes.value.ui32 = tcp_mib.tcpInAckBytes;
619 619 tcpkp->inDupAck.value.ui32 = tcp_mib.tcpInDupAck;
620 620 tcpkp->inAckUnsent.value.ui32 = tcp_mib.tcpInAckUnsent;
621 621 tcpkp->inDataInorderSegs.value.ui32 = tcp_mib.tcpInDataInorderSegs;
622 622 tcpkp->inDataInorderBytes.value.ui32 = tcp_mib.tcpInDataInorderBytes;
623 623 tcpkp->inDataUnorderSegs.value.ui32 = tcp_mib.tcpInDataUnorderSegs;
624 624 tcpkp->inDataUnorderBytes.value.ui32 = tcp_mib.tcpInDataUnorderBytes;
625 625 tcpkp->inDataDupSegs.value.ui32 = tcp_mib.tcpInDataDupSegs;
626 626 tcpkp->inDataDupBytes.value.ui32 = tcp_mib.tcpInDataDupBytes;
627 627 tcpkp->inDataPartDupSegs.value.ui32 = tcp_mib.tcpInDataPartDupSegs;
628 628 tcpkp->inDataPartDupBytes.value.ui32 = tcp_mib.tcpInDataPartDupBytes;
629 629 tcpkp->inDataPastWinSegs.value.ui32 = tcp_mib.tcpInDataPastWinSegs;
630 630 tcpkp->inDataPastWinBytes.value.ui32 = tcp_mib.tcpInDataPastWinBytes;
631 631 tcpkp->inWinProbe.value.ui32 = tcp_mib.tcpInWinProbe;
632 632 tcpkp->inWinUpdate.value.ui32 = tcp_mib.tcpInWinUpdate;
633 633 tcpkp->inClosed.value.ui32 = tcp_mib.tcpInClosed;
634 634 tcpkp->rttNoUpdate.value.ui32 = tcp_mib.tcpRttNoUpdate;
635 635 tcpkp->rttUpdate.value.ui32 = tcp_mib.tcpRttUpdate;
636 636 tcpkp->timRetrans.value.ui32 = tcp_mib.tcpTimRetrans;
637 637 tcpkp->timRetransDrop.value.ui32 = tcp_mib.tcpTimRetransDrop;
638 638 tcpkp->timKeepalive.value.ui32 = tcp_mib.tcpTimKeepalive;
639 639 tcpkp->timKeepaliveProbe.value.ui32 = tcp_mib.tcpTimKeepaliveProbe;
640 640 tcpkp->timKeepaliveDrop.value.ui32 = tcp_mib.tcpTimKeepaliveDrop;
641 641 tcpkp->listenDrop.value.ui32 = tcp_mib.tcpListenDrop;
642 642 tcpkp->listenDropQ0.value.ui32 = tcp_mib.tcpListenDropQ0;
643 643 tcpkp->halfOpenDrop.value.ui32 = tcp_mib.tcpHalfOpenDrop;
644 644 tcpkp->outSackRetransSegs.value.ui32 = tcp_mib.tcpOutSackRetransSegs;
645 645 tcpkp->connTableSize6.value.i32 = tcp_mib.tcp6ConnTableSize;
646 646
647 647 netstack_rele(ns);
648 648 return (0);
649 649 }
650 650
651 651 /*
652 652 * kstats related to squeues i.e. not per IP instance
653 653 */
654 654 void *
655 655 tcp_g_kstat_init(tcp_g_stat_t *tcp_g_statp)
656 656 {
657 657 kstat_t *ksp;
658 658
659 659 tcp_g_stat_t template = {
660 660 { "tcp_timermp_alloced", KSTAT_DATA_UINT64 },
661 661 { "tcp_timermp_allocfail", KSTAT_DATA_UINT64 },
662 662 { "tcp_timermp_allocdblfail", KSTAT_DATA_UINT64 },
663 663 { "tcp_freelist_cleanup", KSTAT_DATA_UINT64 },
664 664 };
665 665
666 666 ksp = kstat_create(TCP_MOD_NAME, 0, "tcpstat_g", "net",
667 667 KSTAT_TYPE_NAMED, sizeof (template) / sizeof (kstat_named_t),
668 668 KSTAT_FLAG_VIRTUAL);
669 669
670 670 if (ksp == NULL)
671 671 return (NULL);
672 672
673 673 bcopy(&template, tcp_g_statp, sizeof (template));
674 674 ksp->ks_data = (void *)tcp_g_statp;
675 675
676 676 kstat_install(ksp);
677 677 return (ksp);
678 678 }
679 679
680 680 void
681 681 tcp_g_kstat_fini(kstat_t *ksp)
682 682 {
683 683 if (ksp != NULL) {
↓ open down ↓ |
166 lines elided |
↑ open up ↑ |
684 684 kstat_delete(ksp);
685 685 }
686 686 }
687 687
688 688 void *
689 689 tcp_kstat2_init(netstackid_t stackid)
690 690 {
691 691 kstat_t *ksp;
692 692
693 693 tcp_stat_t template = {
694 - { "tcp_time_wait_syn_success", KSTAT_DATA_UINT64, 0 },
695 - { "tcp_clean_death_nondetached", KSTAT_DATA_UINT64, 0 },
696 - { "tcp_eager_blowoff_q", KSTAT_DATA_UINT64, 0 },
697 - { "tcp_eager_blowoff_q0", KSTAT_DATA_UINT64, 0 },
698 - { "tcp_no_listener", KSTAT_DATA_UINT64, 0 },
699 - { "tcp_listendrop", KSTAT_DATA_UINT64, 0 },
700 - { "tcp_listendropq0", KSTAT_DATA_UINT64, 0 },
701 - { "tcp_wsrv_called", KSTAT_DATA_UINT64, 0 },
702 - { "tcp_flwctl_on", KSTAT_DATA_UINT64, 0 },
703 - { "tcp_timer_fire_early", KSTAT_DATA_UINT64, 0 },
704 - { "tcp_timer_fire_miss", KSTAT_DATA_UINT64, 0 },
705 - { "tcp_zcopy_on", KSTAT_DATA_UINT64, 0 },
706 - { "tcp_zcopy_off", KSTAT_DATA_UINT64, 0 },
707 - { "tcp_zcopy_backoff", KSTAT_DATA_UINT64, 0 },
708 - { "tcp_fusion_flowctl", KSTAT_DATA_UINT64, 0 },
709 - { "tcp_fusion_backenabled", KSTAT_DATA_UINT64, 0 },
710 - { "tcp_fusion_urg", KSTAT_DATA_UINT64, 0 },
711 - { "tcp_fusion_putnext", KSTAT_DATA_UINT64, 0 },
712 - { "tcp_fusion_unfusable", KSTAT_DATA_UINT64, 0 },
713 - { "tcp_fusion_aborted", KSTAT_DATA_UINT64, 0 },
714 - { "tcp_fusion_unqualified", KSTAT_DATA_UINT64, 0 },
715 - { "tcp_fusion_rrw_busy", KSTAT_DATA_UINT64, 0 },
716 - { "tcp_fusion_rrw_msgcnt", KSTAT_DATA_UINT64, 0 },
717 - { "tcp_fusion_rrw_plugged", KSTAT_DATA_UINT64, 0 },
718 - { "tcp_in_ack_unsent_drop", KSTAT_DATA_UINT64, 0 },
719 - { "tcp_sock_fallback", KSTAT_DATA_UINT64, 0 },
720 - { "tcp_lso_enabled", KSTAT_DATA_UINT64, 0 },
721 - { "tcp_lso_disabled", KSTAT_DATA_UINT64, 0 },
722 - { "tcp_lso_times", KSTAT_DATA_UINT64, 0 },
723 - { "tcp_lso_pkt_out", KSTAT_DATA_UINT64, 0 },
724 - { "tcp_listen_cnt_drop", KSTAT_DATA_UINT64, 0 },
725 - { "tcp_listen_mem_drop", KSTAT_DATA_UINT64, 0 },
726 - { "tcp_zwin_mem_drop", KSTAT_DATA_UINT64, 0 },
727 - { "tcp_zwin_ack_syn", KSTAT_DATA_UINT64, 0 },
728 - { "tcp_rst_unsent", KSTAT_DATA_UINT64, 0 },
729 - { "tcp_reclaim_cnt", KSTAT_DATA_UINT64, 0 },
730 - { "tcp_reass_timeout", KSTAT_DATA_UINT64, 0 },
694 + { "tcp_time_wait_syn_success", KSTAT_DATA_UINT64, {{0}} },
695 + { "tcp_clean_death_nondetached", KSTAT_DATA_UINT64, {{0}} },
696 + { "tcp_eager_blowoff_q", KSTAT_DATA_UINT64, {{0}} },
697 + { "tcp_eager_blowoff_q0", KSTAT_DATA_UINT64, {{0}} },
698 + { "tcp_no_listener", KSTAT_DATA_UINT64, {{0}} },
699 + { "tcp_listendrop", KSTAT_DATA_UINT64, {{0}} },
700 + { "tcp_listendropq0", KSTAT_DATA_UINT64, {{0}} },
701 + { "tcp_wsrv_called", KSTAT_DATA_UINT64, {{0}} },
702 + { "tcp_flwctl_on", KSTAT_DATA_UINT64, {{0}} },
703 + { "tcp_timer_fire_early", KSTAT_DATA_UINT64, {{0}} },
704 + { "tcp_timer_fire_miss", KSTAT_DATA_UINT64, {{0}} },
705 + { "tcp_zcopy_on", KSTAT_DATA_UINT64, {{0}} },
706 + { "tcp_zcopy_off", KSTAT_DATA_UINT64, {{0}} },
707 + { "tcp_zcopy_backoff", KSTAT_DATA_UINT64, {{0}} },
708 + { "tcp_fusion_flowctl", KSTAT_DATA_UINT64, {{0}} },
709 + { "tcp_fusion_backenabled", KSTAT_DATA_UINT64, {{0}} },
710 + { "tcp_fusion_urg", KSTAT_DATA_UINT64, {{0}} },
711 + { "tcp_fusion_putnext", KSTAT_DATA_UINT64, {{0}} },
712 + { "tcp_fusion_unfusable", KSTAT_DATA_UINT64, {{0}} },
713 + { "tcp_fusion_aborted", KSTAT_DATA_UINT64, {{0}} },
714 + { "tcp_fusion_unqualified", KSTAT_DATA_UINT64, {{0}} },
715 + { "tcp_fusion_rrw_busy", KSTAT_DATA_UINT64, {{0}} },
716 + { "tcp_fusion_rrw_msgcnt", KSTAT_DATA_UINT64, {{0}} },
717 + { "tcp_fusion_rrw_plugged", KSTAT_DATA_UINT64, {{0}} },
718 + { "tcp_in_ack_unsent_drop", KSTAT_DATA_UINT64, {{0}} },
719 + { "tcp_sock_fallback", KSTAT_DATA_UINT64, {{0}} },
720 + { "tcp_lso_enabled", KSTAT_DATA_UINT64, {{0}} },
721 + { "tcp_lso_disabled", KSTAT_DATA_UINT64, {{0}} },
722 + { "tcp_lso_times", KSTAT_DATA_UINT64, {{0}} },
723 + { "tcp_lso_pkt_out", KSTAT_DATA_UINT64, {{0}} },
724 + { "tcp_listen_cnt_drop", KSTAT_DATA_UINT64, {{0}} },
725 + { "tcp_listen_mem_drop", KSTAT_DATA_UINT64, {{0}} },
726 + { "tcp_zwin_mem_drop", KSTAT_DATA_UINT64, {{0}} },
727 + { "tcp_zwin_ack_syn", KSTAT_DATA_UINT64, {{0}} },
728 + { "tcp_rst_unsent", KSTAT_DATA_UINT64, {{0}} },
729 + { "tcp_reclaim_cnt", KSTAT_DATA_UINT64, {{0}} },
730 + { "tcp_reass_timeout", KSTAT_DATA_UINT64, {{0}} },
731 731 #ifdef TCP_DEBUG_COUNTER
732 - { "tcp_time_wait", KSTAT_DATA_UINT64, 0 },
733 - { "tcp_rput_time_wait", KSTAT_DATA_UINT64, 0 },
734 - { "tcp_detach_time_wait", KSTAT_DATA_UINT64, 0 },
735 - { "tcp_timeout_calls", KSTAT_DATA_UINT64, 0 },
736 - { "tcp_timeout_cached_alloc", KSTAT_DATA_UINT64, 0 },
737 - { "tcp_timeout_cancel_reqs", KSTAT_DATA_UINT64, 0 },
738 - { "tcp_timeout_canceled", KSTAT_DATA_UINT64, 0 },
739 - { "tcp_timermp_freed", KSTAT_DATA_UINT64, 0 },
740 - { "tcp_push_timer_cnt", KSTAT_DATA_UINT64, 0 },
741 - { "tcp_ack_timer_cnt", KSTAT_DATA_UINT64, 0 },
732 + { "tcp_time_wait", KSTAT_DATA_UINT64, {{0}} },
733 + { "tcp_rput_time_wait", KSTAT_DATA_UINT64, {{0}} },
734 + { "tcp_detach_time_wait", KSTAT_DATA_UINT64, {{0}} },
735 + { "tcp_timeout_calls", KSTAT_DATA_UINT64, {{0}} },
736 + { "tcp_timeout_cached_alloc", KSTAT_DATA_UINT64, {{0}} },
737 + { "tcp_timeout_cancel_reqs", KSTAT_DATA_UINT64, {{0}} },
738 + { "tcp_timeout_canceled", KSTAT_DATA_UINT64, {{0}} },
739 + { "tcp_timermp_freed", KSTAT_DATA_UINT64, {{0}} },
740 + { "tcp_push_timer_cnt", KSTAT_DATA_UINT64, {{0}} },
741 + { "tcp_ack_timer_cnt", KSTAT_DATA_UINT64, {{0}} },
742 742 #endif
743 743 };
744 744
745 745 ksp = kstat_create_netstack(TCP_MOD_NAME, stackid, "tcpstat", "net",
746 746 KSTAT_TYPE_NAMED, sizeof (template) / sizeof (kstat_named_t), 0,
747 747 stackid);
748 748
749 749 if (ksp == NULL)
750 750 return (NULL);
751 751
752 752 bcopy(&template, ksp->ks_data, sizeof (template));
753 753 ksp->ks_private = (void *)(uintptr_t)stackid;
754 754 ksp->ks_update = tcp_kstat2_update;
755 755
756 756 /*
757 757 * If this is an exclusive netstack for a local zone, the global zone
758 758 * should still be able to read the kstat.
759 759 */
760 760 if (stackid != GLOBAL_NETSTACKID)
761 761 kstat_zone_add(ksp, GLOBAL_ZONEID);
762 762
763 763 kstat_install(ksp);
764 764 return (ksp);
765 765 }
766 766
767 767 void
768 768 tcp_kstat2_fini(netstackid_t stackid, kstat_t *ksp)
769 769 {
770 770 if (ksp != NULL) {
771 771 ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
772 772 kstat_delete_netstack(ksp, stackid);
773 773 }
774 774 }
775 775
776 776 /*
777 777 * Sum up all per CPU tcp_stat_t kstat counters.
778 778 */
779 779 static int
780 780 tcp_kstat2_update(kstat_t *kp, int rw)
781 781 {
782 782 netstackid_t stackid = (netstackid_t)(uintptr_t)kp->ks_private;
783 783 netstack_t *ns;
784 784 tcp_stack_t *tcps;
785 785 tcp_stat_t *stats;
786 786 int i;
787 787 int cnt;
788 788
789 789 if (rw == KSTAT_WRITE)
790 790 return (EACCES);
791 791
792 792 ns = netstack_find_by_stackid(stackid);
793 793 if (ns == NULL)
794 794 return (-1);
795 795 tcps = ns->netstack_tcp;
796 796 if (tcps == NULL) {
797 797 netstack_rele(ns);
798 798 return (-1);
799 799 }
800 800
801 801 stats = (tcp_stat_t *)kp->ks_data;
802 802 tcp_clr_stats(stats);
803 803
804 804 /*
805 805 * tcps_sc_cnt may change in the middle of the loop. It is better
806 806 * to get its value first.
807 807 */
808 808 cnt = tcps->tcps_sc_cnt;
809 809 for (i = 0; i < cnt; i++)
810 810 tcp_add_stats(&tcps->tcps_sc[i]->tcp_sc_stats, stats);
811 811
812 812 netstack_rele(ns);
813 813 return (0);
814 814 }
815 815
816 816 /*
817 817 * To add stats from one mib2_tcp_t to another. Static fields are not added.
818 818 * The caller should set them up propertly.
819 819 */
820 820 static void
821 821 tcp_add_mib(mib2_tcp_t *from, mib2_tcp_t *to)
822 822 {
823 823 to->tcpActiveOpens += from->tcpActiveOpens;
824 824 to->tcpPassiveOpens += from->tcpPassiveOpens;
825 825 to->tcpAttemptFails += from->tcpAttemptFails;
826 826 to->tcpEstabResets += from->tcpEstabResets;
827 827 to->tcpInSegs += from->tcpInSegs;
828 828 to->tcpOutSegs += from->tcpOutSegs;
829 829 to->tcpRetransSegs += from->tcpRetransSegs;
830 830 to->tcpOutRsts += from->tcpOutRsts;
831 831
832 832 to->tcpOutDataSegs += from->tcpOutDataSegs;
833 833 to->tcpOutDataBytes += from->tcpOutDataBytes;
834 834 to->tcpRetransBytes += from->tcpRetransBytes;
835 835 to->tcpOutAck += from->tcpOutAck;
836 836 to->tcpOutAckDelayed += from->tcpOutAckDelayed;
837 837 to->tcpOutUrg += from->tcpOutUrg;
838 838 to->tcpOutWinUpdate += from->tcpOutWinUpdate;
839 839 to->tcpOutWinProbe += from->tcpOutWinProbe;
840 840 to->tcpOutControl += from->tcpOutControl;
841 841 to->tcpOutFastRetrans += from->tcpOutFastRetrans;
842 842
843 843 to->tcpInAckBytes += from->tcpInAckBytes;
844 844 to->tcpInDupAck += from->tcpInDupAck;
845 845 to->tcpInAckUnsent += from->tcpInAckUnsent;
846 846 to->tcpInDataInorderSegs += from->tcpInDataInorderSegs;
847 847 to->tcpInDataInorderBytes += from->tcpInDataInorderBytes;
848 848 to->tcpInDataUnorderSegs += from->tcpInDataUnorderSegs;
849 849 to->tcpInDataUnorderBytes += from->tcpInDataUnorderBytes;
850 850 to->tcpInDataDupSegs += from->tcpInDataDupSegs;
851 851 to->tcpInDataDupBytes += from->tcpInDataDupBytes;
852 852 to->tcpInDataPartDupSegs += from->tcpInDataPartDupSegs;
853 853 to->tcpInDataPartDupBytes += from->tcpInDataPartDupBytes;
854 854 to->tcpInDataPastWinSegs += from->tcpInDataPastWinSegs;
855 855 to->tcpInDataPastWinBytes += from->tcpInDataPastWinBytes;
856 856 to->tcpInWinProbe += from->tcpInWinProbe;
857 857 to->tcpInWinUpdate += from->tcpInWinUpdate;
858 858 to->tcpInClosed += from->tcpInClosed;
859 859
860 860 to->tcpRttNoUpdate += from->tcpRttNoUpdate;
861 861 to->tcpRttUpdate += from->tcpRttUpdate;
862 862 to->tcpTimRetrans += from->tcpTimRetrans;
863 863 to->tcpTimRetransDrop += from->tcpTimRetransDrop;
864 864 to->tcpTimKeepalive += from->tcpTimKeepalive;
865 865 to->tcpTimKeepaliveProbe += from->tcpTimKeepaliveProbe;
866 866 to->tcpTimKeepaliveDrop += from->tcpTimKeepaliveDrop;
867 867 to->tcpListenDrop += from->tcpListenDrop;
868 868 to->tcpListenDropQ0 += from->tcpListenDropQ0;
869 869 to->tcpHalfOpenDrop += from->tcpHalfOpenDrop;
870 870 to->tcpOutSackRetransSegs += from->tcpOutSackRetransSegs;
871 871 to->tcpHCInSegs += from->tcpHCInSegs;
872 872 to->tcpHCOutSegs += from->tcpHCOutSegs;
873 873 }
874 874
875 875 /*
876 876 * To sum up all MIB2 stats for a tcp_stack_t from all per CPU stats. The
877 877 * caller should initialize the target mib2_tcp_t properly as this function
878 878 * just adds up all the per CPU stats.
879 879 */
880 880 static void
881 881 tcp_sum_mib(tcp_stack_t *tcps, mib2_tcp_t *tcp_mib)
882 882 {
883 883 int i;
884 884 int cnt;
885 885
886 886 /*
887 887 * tcps_sc_cnt may change in the middle of the loop. It is better
888 888 * to get its value first.
889 889 */
890 890 cnt = tcps->tcps_sc_cnt;
891 891 for (i = 0; i < cnt; i++)
892 892 tcp_add_mib(&tcps->tcps_sc[i]->tcp_sc_mib, tcp_mib);
893 893 }
894 894
895 895 /*
896 896 * To set all tcp_stat_t counters to 0.
897 897 */
898 898 static void
899 899 tcp_clr_stats(tcp_stat_t *stats)
900 900 {
901 901 stats->tcp_time_wait_syn_success.value.ui64 = 0;
902 902 stats->tcp_clean_death_nondetached.value.ui64 = 0;
903 903 stats->tcp_eager_blowoff_q.value.ui64 = 0;
904 904 stats->tcp_eager_blowoff_q0.value.ui64 = 0;
905 905 stats->tcp_no_listener.value.ui64 = 0;
906 906 stats->tcp_listendrop.value.ui64 = 0;
907 907 stats->tcp_listendropq0.value.ui64 = 0;
908 908 stats->tcp_wsrv_called.value.ui64 = 0;
909 909 stats->tcp_flwctl_on.value.ui64 = 0;
910 910 stats->tcp_timer_fire_early.value.ui64 = 0;
911 911 stats->tcp_timer_fire_miss.value.ui64 = 0;
912 912 stats->tcp_zcopy_on.value.ui64 = 0;
913 913 stats->tcp_zcopy_off.value.ui64 = 0;
914 914 stats->tcp_zcopy_backoff.value.ui64 = 0;
915 915 stats->tcp_fusion_flowctl.value.ui64 = 0;
916 916 stats->tcp_fusion_backenabled.value.ui64 = 0;
917 917 stats->tcp_fusion_urg.value.ui64 = 0;
918 918 stats->tcp_fusion_putnext.value.ui64 = 0;
919 919 stats->tcp_fusion_unfusable.value.ui64 = 0;
920 920 stats->tcp_fusion_aborted.value.ui64 = 0;
921 921 stats->tcp_fusion_unqualified.value.ui64 = 0;
922 922 stats->tcp_fusion_rrw_busy.value.ui64 = 0;
923 923 stats->tcp_fusion_rrw_msgcnt.value.ui64 = 0;
924 924 stats->tcp_fusion_rrw_plugged.value.ui64 = 0;
925 925 stats->tcp_in_ack_unsent_drop.value.ui64 = 0;
926 926 stats->tcp_sock_fallback.value.ui64 = 0;
927 927 stats->tcp_lso_enabled.value.ui64 = 0;
928 928 stats->tcp_lso_disabled.value.ui64 = 0;
929 929 stats->tcp_lso_times.value.ui64 = 0;
930 930 stats->tcp_lso_pkt_out.value.ui64 = 0;
931 931 stats->tcp_listen_cnt_drop.value.ui64 = 0;
932 932 stats->tcp_listen_mem_drop.value.ui64 = 0;
933 933 stats->tcp_zwin_mem_drop.value.ui64 = 0;
934 934 stats->tcp_zwin_ack_syn.value.ui64 = 0;
935 935 stats->tcp_rst_unsent.value.ui64 = 0;
936 936 stats->tcp_reclaim_cnt.value.ui64 = 0;
937 937 stats->tcp_reass_timeout.value.ui64 = 0;
938 938
939 939 #ifdef TCP_DEBUG_COUNTER
940 940 stats->tcp_time_wait.value.ui64 = 0;
941 941 stats->tcp_rput_time_wait.value.ui64 = 0;
942 942 stats->tcp_detach_time_wait.value.ui64 = 0;
943 943 stats->tcp_timeout_calls.value.ui64 = 0;
944 944 stats->tcp_timeout_cached_alloc.value.ui64 = 0;
945 945 stats->tcp_timeout_cancel_reqs.value.ui64 = 0;
946 946 stats->tcp_timeout_canceled.value.ui64 = 0;
947 947 stats->tcp_timermp_freed.value.ui64 = 0;
948 948 stats->tcp_push_timer_cnt.value.ui64 = 0;
949 949 stats->tcp_ack_timer_cnt.value.ui64 = 0;
950 950 #endif
951 951 }
952 952
953 953 /*
954 954 * To add counters from the per CPU tcp_stat_counter_t to the stack
955 955 * tcp_stat_t.
956 956 */
957 957 static void
958 958 tcp_add_stats(tcp_stat_counter_t *from, tcp_stat_t *to)
959 959 {
960 960 to->tcp_time_wait_syn_success.value.ui64 +=
961 961 from->tcp_time_wait_syn_success;
962 962 to->tcp_clean_death_nondetached.value.ui64 +=
963 963 from->tcp_clean_death_nondetached;
964 964 to->tcp_eager_blowoff_q.value.ui64 +=
965 965 from->tcp_eager_blowoff_q;
966 966 to->tcp_eager_blowoff_q0.value.ui64 +=
967 967 from->tcp_eager_blowoff_q0;
968 968 to->tcp_no_listener.value.ui64 +=
969 969 from->tcp_no_listener;
970 970 to->tcp_listendrop.value.ui64 +=
971 971 from->tcp_listendrop;
972 972 to->tcp_listendropq0.value.ui64 +=
973 973 from->tcp_listendropq0;
974 974 to->tcp_wsrv_called.value.ui64 +=
975 975 from->tcp_wsrv_called;
976 976 to->tcp_flwctl_on.value.ui64 +=
977 977 from->tcp_flwctl_on;
978 978 to->tcp_timer_fire_early.value.ui64 +=
979 979 from->tcp_timer_fire_early;
980 980 to->tcp_timer_fire_miss.value.ui64 +=
981 981 from->tcp_timer_fire_miss;
982 982 to->tcp_zcopy_on.value.ui64 +=
983 983 from->tcp_zcopy_on;
984 984 to->tcp_zcopy_off.value.ui64 +=
985 985 from->tcp_zcopy_off;
986 986 to->tcp_zcopy_backoff.value.ui64 +=
987 987 from->tcp_zcopy_backoff;
988 988 to->tcp_fusion_flowctl.value.ui64 +=
989 989 from->tcp_fusion_flowctl;
990 990 to->tcp_fusion_backenabled.value.ui64 +=
991 991 from->tcp_fusion_backenabled;
992 992 to->tcp_fusion_urg.value.ui64 +=
993 993 from->tcp_fusion_urg;
994 994 to->tcp_fusion_putnext.value.ui64 +=
995 995 from->tcp_fusion_putnext;
996 996 to->tcp_fusion_unfusable.value.ui64 +=
997 997 from->tcp_fusion_unfusable;
998 998 to->tcp_fusion_aborted.value.ui64 +=
999 999 from->tcp_fusion_aborted;
1000 1000 to->tcp_fusion_unqualified.value.ui64 +=
1001 1001 from->tcp_fusion_unqualified;
1002 1002 to->tcp_fusion_rrw_busy.value.ui64 +=
1003 1003 from->tcp_fusion_rrw_busy;
1004 1004 to->tcp_fusion_rrw_msgcnt.value.ui64 +=
1005 1005 from->tcp_fusion_rrw_msgcnt;
1006 1006 to->tcp_fusion_rrw_plugged.value.ui64 +=
1007 1007 from->tcp_fusion_rrw_plugged;
1008 1008 to->tcp_in_ack_unsent_drop.value.ui64 +=
1009 1009 from->tcp_in_ack_unsent_drop;
1010 1010 to->tcp_sock_fallback.value.ui64 +=
1011 1011 from->tcp_sock_fallback;
1012 1012 to->tcp_lso_enabled.value.ui64 +=
1013 1013 from->tcp_lso_enabled;
1014 1014 to->tcp_lso_disabled.value.ui64 +=
1015 1015 from->tcp_lso_disabled;
1016 1016 to->tcp_lso_times.value.ui64 +=
1017 1017 from->tcp_lso_times;
1018 1018 to->tcp_lso_pkt_out.value.ui64 +=
1019 1019 from->tcp_lso_pkt_out;
1020 1020 to->tcp_listen_cnt_drop.value.ui64 +=
1021 1021 from->tcp_listen_cnt_drop;
1022 1022 to->tcp_listen_mem_drop.value.ui64 +=
1023 1023 from->tcp_listen_mem_drop;
1024 1024 to->tcp_zwin_mem_drop.value.ui64 +=
1025 1025 from->tcp_zwin_mem_drop;
1026 1026 to->tcp_zwin_ack_syn.value.ui64 +=
1027 1027 from->tcp_zwin_ack_syn;
1028 1028 to->tcp_rst_unsent.value.ui64 +=
1029 1029 from->tcp_rst_unsent;
1030 1030 to->tcp_reclaim_cnt.value.ui64 +=
1031 1031 from->tcp_reclaim_cnt;
1032 1032 to->tcp_reass_timeout.value.ui64 +=
1033 1033 from->tcp_reass_timeout;
1034 1034
1035 1035 #ifdef TCP_DEBUG_COUNTER
1036 1036 to->tcp_time_wait.value.ui64 +=
1037 1037 from->tcp_time_wait;
1038 1038 to->tcp_rput_time_wait.value.ui64 +=
1039 1039 from->tcp_rput_time_wait;
1040 1040 to->tcp_detach_time_wait.value.ui64 +=
1041 1041 from->tcp_detach_time_wait;
1042 1042 to->tcp_timeout_calls.value.ui64 +=
1043 1043 from->tcp_timeout_calls;
1044 1044 to->tcp_timeout_cached_alloc.value.ui64 +=
1045 1045 from->tcp_timeout_cached_alloc;
1046 1046 to->tcp_timeout_cancel_reqs.value.ui64 +=
1047 1047 from->tcp_timeout_cancel_reqs;
1048 1048 to->tcp_timeout_canceled.value.ui64 +=
1049 1049 from->tcp_timeout_canceled;
1050 1050 to->tcp_timermp_freed.value.ui64 +=
1051 1051 from->tcp_timermp_freed;
1052 1052 to->tcp_push_timer_cnt.value.ui64 +=
1053 1053 from->tcp_push_timer_cnt;
1054 1054 to->tcp_ack_timer_cnt.value.ui64 +=
1055 1055 from->tcp_ack_timer_cnt;
1056 1056 #endif
1057 1057 }
↓ open down ↓ |
306 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX