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