Print this page
dccp: clock_t
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/inet/dccp/dccp_stats.c
+++ new/usr/src/uts/common/inet/dccp/dccp_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 2010 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 /*
28 28 * Copyright 2012 David Hoeppner. All rights reserved.
29 29 */
30 30
31 31 /*
32 32 * Functions related to MIB-II and kstat.
33 33 */
34 34
35 35 #include <sys/types.h>
36 36 #include <sys/tihdr.h>
37 37 #include <sys/policy.h>
38 38 #include <sys/tsol/tnet.h>
39 39
40 40 #include <inet/common.h>
41 41 #include <inet/dccp_impl.h>
42 42 #include <inet/ip.h>
43 43 #include <inet/kstatcom.h>
44 44 #include <inet/snmpcom.h>
45 45
46 46 #include <sys/cmn_err.h>
47 47
48 48 static int dccp_snmp_state(dccp_t *);
49 49 static int dccp_kstat_update(kstat_t *, int);
50 50 static int dccp_kstat2_update(kstat_t *, int);
51 51 static void dccp_add_mib(mib2_dccp_t *, mib2_dccp_t *);
52 52 static void dccp_sum_mib(dccp_stack_t *, mib2_dccp_t *);
53 53 static void dccp_clr_stats(dccp_stat_t *);
54 54 static void dccp_add_stats(dccp_stat_counter_t *, dccp_stat_t *);
55 55
56 56 /*
57 57 * Translate DCCP state to MIB2 state.
58 58 */
59 59 static int
60 60 dccp_snmp_state(dccp_t *dccp)
61 61 {
62 62 if (dccp == NULL) {
63 63 return (0);
64 64 }
65 65
66 66 switch(dccp->dccp_state) {
67 67 case DCCPS_CLOSED:
68 68 return (MIB2_DCCP_closed);
69 69 default:
70 70 return (0);
71 71 }
72 72 }
73 73
74 74 /*
75 75 * Get the MIB-II stats.
76 76 */
77 77 mblk_t *
78 78 dccp_snmp_get(queue_t *q, mblk_t *mpctl, boolean_t legacy_req)
79 79 {
80 80 conn_t *connp = Q_TO_CONN(q);
81 81 connf_t *connfp;
82 82 ip_stack_t *ipst;
83 83 dccp_stack_t *dccps;
84 84 struct opthdr *optp;
85 85 mblk_t *mp2ctl;
86 86 mblk_t *mpdata;
87 87 mblk_t *mp_conn_ctl = NULL;
88 88 mblk_t *mp_conn_tail;
89 89 mblk_t *mp_attr_ctl = NULL;
90 90 mblk_t *mp_attr_tail;
91 91 mblk_t *mp6_conn_ctl = NULL;
92 92 mblk_t *mp6_conn_tail;
93 93 mblk_t *mp6_attr_ctl = NULL;
94 94 mblk_t *mp6_attr_tail;
95 95 size_t dccp_mib_size;
96 96 size_t dce_size;
97 97 size_t dce6_size;
98 98 boolean_t ispriv;
99 99 zoneid_t zoneid;
100 100 int v4_conn_idx;
101 101 int v6_conn_idx;
102 102 int i;
103 103 mib2_dccp_t dccp_mib;
104 104 mib2_dccpConnEntry_t dce;
105 105 mib2_dccp6ConnEntry_t dce6;
106 106 mib2_transportMLPEntry_t mlp;
107 107
108 108 /*
109 109 * Make a copy of the original message.
110 110 */
111 111 mp2ctl = copymsg(mpctl);
112 112
113 113 cmn_err(CE_NOTE, "dccp_stats.c: dccp_snmp_get");
114 114
115 115 if (mpctl == NULL ||
116 116 (mpdata = mpctl->b_cont) == NULL ||
117 117 (mp_conn_ctl = copymsg(mpctl)) == NULL ||
118 118 (mp_attr_ctl = copymsg(mpctl)) == NULL ||
119 119 (mp6_conn_ctl = copymsg(mpctl)) == NULL ||
120 120 (mp6_attr_ctl = copymsg(mpctl)) == NULL) {
121 121 freemsg(mp_conn_ctl);
122 122 freemsg(mp_attr_ctl);
123 123 freemsg(mp6_conn_ctl);
124 124 freemsg(mp6_attr_ctl);
125 125 freemsg(mpctl);
126 126 freemsg(mp2ctl);
127 127 return (NULL);
128 128 }
129 129
130 130 ipst = connp->conn_netstack->netstack_ip;
131 131 dccps = connp->conn_netstack->netstack_dccp;
132 132
133 133 if (legacy_req) {
134 134 dccp_mib_size = LEGACY_MIB_SIZE(&dccp_mib, mib2_dccp_t);
135 135 dce_size = LEGACY_MIB_SIZE(&dce, mib2_dccpConnEntry_t);
136 136 dce6_size = LEGACY_MIB_SIZE(&dce6, mib2_dccp6ConnEntry_t);
137 137 } else {
138 138 dccp_mib_size = sizeof (mib2_dccp_t);
139 139 dce_size = sizeof (mib2_dccpConnEntry_t);
140 140 dce6_size = sizeof (mib2_dccp6ConnEntry_t);
141 141 }
142 142
143 143 bzero(&dccp_mib, sizeof (dccp_mib));
144 144
145 145 ispriv = secpolicy_ip_config((Q_TO_CONN(q))->conn_cred, B_TRUE) == 0;
146 146 zoneid = Q_TO_CONN(q)->conn_zoneid;
147 147
148 148 v4_conn_idx = v6_conn_idx = 0;
149 149 mp_conn_tail = mp_attr_tail = mp6_conn_tail = mp6_attr_tail = NULL;
150 150
151 151 for (i = 0; i < CONN_G_HASH_SIZE; i++) {
152 152 ipst = dccps->dccps_netstack->netstack_ip;
153 153
154 154 connfp = &ipst->ips_ipcl_globalhash_fanout[i];
155 155 connp = NULL;
156 156
157 157 while ((connp = ipcl_get_next_conn(connfp, connp,
158 158 IPCL_DCCPCONN)) != NULL) {
159 159 dccp_t *dccp;
160 160 boolean_t needattr;
161 161
162 162 if (connp->conn_zoneid != zoneid) {
163 163 continue; /* Not in this zone */
164 164 }
165 165
166 166 dccp = connp->conn_dccp;
167 167 DCCPS_UPDATE_MIB(dccps, dccpHCInSegs, dccp->dccp_ibsegs);
168 168 dccp->dccp_ibsegs = 0;
169 169 DCCPS_UPDATE_MIB(dccps, dccpHCOutSegs, dccp->dccp_obsegs);
170 170 dccp->dccp_obsegs = 0;
171 171
172 172 dce.dccpConnState = dccp_snmp_state(dccp);
173 173
174 174 needattr = B_FALSE;
175 175 bzero(&mlp, sizeof (mlp));
176 176 if (connp->conn_mlp_type != mlptSingle) {
177 177 if (connp->conn_mlp_type == mlptShared ||
178 178 connp->conn_mlp_type == mlptBoth) {
179 179 mlp.tme_flags |= MIB2_TMEF_SHARED;
180 180 }
181 181
182 182 if (connp->conn_mlp_type == mlptPrivate ||
183 183 connp->conn_mlp_type == mlptBoth) {
184 184 mlp.tme_flags |= MIB2_TMEF_PRIVATE;
185 185 }
186 186
187 187 needattr = B_TRUE;
188 188 }
189 189
190 190 if (connp->conn_anon_mlp) {
191 191 mlp.tme_flags |= MIB2_TMEF_ANONMLP;
192 192 needattr = B_TRUE;
193 193 }
194 194
195 195 switch (connp->conn_mac_mode) {
196 196 case CONN_MAC_DEFAULT:
197 197 break;
198 198 case CONN_MAC_AWARE:
199 199 mlp.tme_flags |= MIB2_TMEF_MACEXEMPT;
200 200 needattr = B_TRUE;
201 201 break;
202 202 case CONN_MAC_IMPLICIT:
203 203 mlp.tme_flags |= MIB2_TMEF_MACIMPLICIT;
204 204 needattr = B_TRUE;
205 205 break;
206 206 }
207 207
208 208 if (connp->conn_ixa->ixa_tsl != NULL) {
209 209 ts_label_t *tsl;
210 210
211 211 tsl = connp->conn_ixa->ixa_tsl;
212 212 mlp.tme_flags |= MIB2_TMEF_IS_LABELED;
213 213 mlp.tme_doi = label2doi(tsl);
214 214 mlp.tme_label = *label2bslabel(tsl);
215 215 needattr = B_TRUE;
216 216 }
217 217
218 218 /* Create a message to report on IPv6 entries */
219 219 if (connp->conn_ipversion == IPV6_VERSION) {
220 220 dce6.dccp6ConnLocalAddress =
221 221 connp->conn_laddr_v6;
222 222 dce6.dccp6ConnRemAddress =
223 223 connp->conn_faddr_v6;
224 224 dce6.dccp6ConnLocalPort =
225 225 ntohs(connp->conn_lport);
226 226 dce6.dccp6ConnRemPort =
227 227 ntohs(connp->conn_fport);
228 228
229 229 if (connp->conn_ixa->ixa_flags &
230 230 IXAF_SCOPEID_SET) {
231 231 dce6.dccp6ConnIfIndex =
232 232 connp->conn_ixa->ixa_scopeid;
233 233 } else {
234 234 dce6.dccp6ConnIfIndex =
235 235 connp->conn_bound_if;
236 236 }
237 237
238 238 /* XXX */
239 239
240 240 dce6.dccp6ConnEntryInfo.ce_state =
241 241 dccp->dccp_state;
242 242
243 243 dce6.dccp6ConnCreationProcess =
244 244 (connp->conn_cpid < 0) ?
245 245 MIB2_UNKNOWN_PROCESS : connp->conn_cpid;
246 246 dce6.dccp6ConnCreationTime =
247 247 connp->conn_open_time;
248 248
249 249 (void) snmp_append_data2(mp6_conn_ctl->b_cont,
250 250 &mp6_conn_tail, (char *)&dce6, dce6_size);
251 251
252 252 mlp.tme_connidx = v6_conn_idx++;
253 253 if (needattr) {
254 254 (void) snmp_append_data2(
255 255 mp6_attr_ctl->b_cont,
256 256 &mp6_attr_tail, (char *)&mlp,
257 257 sizeof (mlp));
258 258 }
259 259 }
260 260
261 261 if (connp->conn_ipversion == IPV4_VERSION ||
262 262 (dccp->dccp_state <= DCCPS_LISTEN &&
263 263 !connp->conn_ipv6_v6only &&
264 264 IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6))) {
265 265
266 266 if (connp->conn_ipversion == IPV6_VERSION) {
267 267 dce.dccpConnRemAddress = INADDR_ANY;
268 268 dce.dccpConnLocalAddress = INADDR_ANY;
269 269 } else {
270 270 dce.dccpConnRemAddress =
271 271 connp->conn_faddr_v4;
272 272 dce.dccpConnLocalAddress =
273 273 connp->conn_laddr_v4;
274 274 }
275 275
276 276 dce.dccpConnLocalPort =
277 277 ntohs(connp->conn_lport);
278 278 dce.dccpConnRemPort =
279 279 ntohs(connp->conn_fport);
280 280
281 281 /* XXX */
282 282
283 283 dce.dccpConnEntryInfo.ce_state =
284 284 dccp->dccp_state;
285 285
286 286 dce.dccpConnCreationProcess =
287 287 (connp->conn_cpid < 0) ?
288 288 MIB2_UNKNOWN_PROCESS : connp->conn_cpid;
289 289 dce.dccpConnCreationTime =
290 290 connp->conn_open_time;
291 291
292 292 (void) snmp_append_data2(mp_conn_ctl->b_cont,
293 293 &mp_conn_tail, (char *)&dce, dce_size);
294 294
295 295 mlp.tme_connidx = v4_conn_idx++;
296 296 if (needattr) {
297 297 (void) snmp_append_data2(
298 298 mp_attr_ctl->b_cont,
299 299 &mp_attr_tail, (char *)&mlp,
300 300 sizeof (mlp));
301 301 }
302 302 }
303 303 }
304 304 }
305 305
306 306 /* Sum up per CPU stats */
307 307 dccp_sum_mib(dccps, &dccp_mib);
308 308
309 309 /* Fixed length structure for IPv4 and IPv6 counters */
310 310 SET_MIB(dccp_mib.dccpConnTableSize, dce_size);
311 311 SET_MIB(dccp_mib.dccp6ConnTableSize, dce6_size);
312 312
313 313 /* Synchronize 32- and 64-bit counters */
314 314 SYNC32_MIB(&dccp_mib, dccpInSegs, dccpHCInSegs);
315 315 SYNC32_MIB(&dccp_mib, dccpOutSegs, dccpHCOutSegs);
316 316
317 317 optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
318 318 optp->level = MIB2_DCCP;
319 319 optp->name = 0;
320 320 (void) snmp_append_data(mpdata, (char *)&dccp_mib, dccp_mib_size);
321 321 optp->len = msgdsize(mpdata);
322 322 qreply(q, mpctl);
323 323
324 324 optp = (struct opthdr *)&mp_conn_ctl->b_rptr[
325 325 sizeof (struct T_optmgmt_ack)];
326 326 optp->level = MIB2_DCCP;
327 327 optp->name = MIB2_DCCP_CONN;
328 328 optp->len = msgdsize(mp_conn_ctl->b_cont);
329 329 qreply(q, mp_conn_ctl);
330 330
331 331 optp = (struct opthdr *)&mp_attr_ctl->b_rptr[
332 332 sizeof (struct T_optmgmt_ack)];
333 333 optp->level = MIB2_DCCP;
334 334 optp->name = EXPER_XPORT_MLP;
335 335 optp->len = msgdsize(mp_attr_ctl->b_cont);
336 336 if (optp->len == 0) {
337 337 freemsg(mp_attr_ctl);
338 338 } else {
339 339 qreply(q, mp_attr_ctl);
340 340 }
341 341
342 342 optp = (struct opthdr *)&mp6_conn_ctl->b_rptr[
343 343 sizeof (struct T_optmgmt_ack)];
344 344 optp->level = MIB2_DCCP6;
345 345 optp->name = MIB2_DCCP6_CONN;
346 346 optp->len = msgdsize(mp6_conn_ctl->b_cont);
347 347 qreply(q, mp6_conn_ctl);
348 348
349 349 optp = (struct opthdr *)&mp6_attr_ctl->b_rptr[
350 350 sizeof (struct T_optmgmt_ack)];
351 351 optp->level = MIB2_DCCP6;
352 352 optp->name = EXPER_XPORT_MLP;
353 353 optp->len = msgdsize(mp6_attr_ctl->b_cont);
354 354 if (optp->len == 0) {
355 355 freemsg(mp6_attr_ctl);
356 356 } else {
357 357 qreply(q, mp6_attr_ctl);
358 358 }
359 359
360 360 return (mp2ctl);
361 361 }
362 362
363 363 /*
364 364 * DCCP kernel statistics.
365 365 */
366 366 void *
367 367 dccp_kstat_init(netstackid_t stackid)
368 368 {
369 369 kstat_t *ksp;
370 370
371 371 dccp_named_kstat_t template = {
372 372 { "activeOpens", KSTAT_DATA_UINT32, 0 },
373 373 { "passiveOpens", KSTAT_DATA_UINT32, 0 },
374 374 { "inSegs", KSTAT_DATA_UINT64, 0 },
375 375 { "outSegs", KSTAT_DATA_UINT64, 0 },
376 376 };
377 377
378 378 ksp = kstat_create_netstack(DCCP_MOD_NAME, 0, DCCP_MOD_NAME, "mib2",
379 379 KSTAT_TYPE_NAMED, NUM_OF_FIELDS(dccp_named_kstat_t), 0, stackid);
380 380 if (ksp == NULL) {
381 381 return (NULL);
382 382 }
383 383
384 384 bcopy(&template, ksp->ks_data, sizeof (template));
385 385 ksp->ks_update = dccp_kstat_update;
386 386 ksp->ks_private = (void *)(uintptr_t)stackid;
387 387
388 388 kstat_install(ksp);
389 389
390 390 return (ksp);
391 391 }
392 392
393 393 /*
394 394 * Destroy DCCP kernel statistics.
395 395 */
396 396 void
397 397 dccp_kstat_fini(netstackid_t stackid, kstat_t *ksp)
398 398 {
399 399
400 400 if (ksp != NULL) {
401 401 ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
402 402 kstat_delete_netstack(ksp, stackid);
403 403 }
404 404 }
405 405
406 406 /*
407 407 * Update DCCP kernel statistics.
408 408 */
409 409 static int
410 410 dccp_kstat_update(kstat_t *kp, int rw)
411 411 {
412 412 conn_t *connp;
413 413 connf_t *connfp;
414 414 dccp_named_kstat_t *dccpkp;
415 415 dccp_t *dccp;
416 416 dccp_stack_t *dccps;
417 417 ip_stack_t *ipst;
418 418 netstack_t *ns;
419 419 netstackid_t stackid;
420 420 mib2_dccp_t dccp_mib;
421 421
422 422 if (rw == KSTAT_WRITE) {
423 423 return (EACCES);
424 424 }
425 425
426 426 stackid = (netstackid_t)(uintptr_t)kp->ks_private;
427 427 ns = netstack_find_by_stackid(stackid);
428 428 if (ns == NULL) {
429 429 return (-1);
430 430 }
431 431
432 432 dccps = ns->netstack_dccp;
433 433 if (dccps == NULL) {
434 434 netstack_rele(ns);
435 435 return (-1);
436 436 }
437 437
438 438 dccpkp = (dccp_named_kstat_t *)kp->ks_data;
439 439 ipst = ns->netstack_ip;
440 440
441 441 bzero(&dccp_mib, sizeof (dccp_mib));
442 442 dccp_sum_mib(dccps, &dccp_mib);
443 443
444 444 /* Fixed length structure for IPv4 and IPv6 counters */
445 445 SET_MIB(dccp_mib.dccpConnTableSize, sizeof (mib2_dccpConnEntry_t));
446 446 SET_MIB(dccp_mib.dccp6ConnTableSize, sizeof (mib2_dccp6ConnEntry_t));
447 447
448 448 dccpkp->activeOpens.value.ui32 = dccp_mib.dccpActiveOpens;
449 449 dccpkp->passiveOpens.value.ui32 = dccp_mib.dccpPassiveOpens;
450 450 dccpkp->inSegs.value.ui64 = dccp_mib.dccpHCInSegs;
451 451 dccpkp->outSegs.value.ui64 = dccp_mib.dccpHCOutSegs;
452 452
453 453 return (0);
454 454 }
455 455
456 456 /*
457 457 *
458 458 */
459 459 void *
460 460 dccp_kstat2_init(netstackid_t stackid)
461 461 {
462 462 kstat_t *ksp;
463 463
464 464 dccp_stat_t template = {
465 465 { "dccp_sock_fallback", KSTAT_DATA_UINT64, 0 },
466 466 };
467 467
468 468 ksp = kstat_create_netstack(DCCP_MOD_NAME, 0, "dccpstat", "net",
469 469 KSTAT_TYPE_NAMED, sizeof (template) / sizeof (kstat_named_t), 0,
470 470 stackid);
471 471 if (ksp == NULL) {
472 472 return (NULL);
473 473 }
↓ open down ↓ |
473 lines elided |
↑ open up ↑ |
474 474
475 475 bcopy(&template, ksp->ks_data, sizeof (template));
476 476 ksp->ks_private = (void *)(uintptr_t)stackid;
477 477 ksp->ks_update = dccp_kstat2_update;
478 478
479 479 kstat_install(ksp);
480 480
481 481 return (ksp);
482 482 }
483 483
484 +/*
485 + * Destroy DCCP kernel statistics.
486 + */
484 487 void
485 488 dccp_kstat2_fini(netstackid_t stackid, kstat_t *ksp)
486 489 {
487 490 if (ksp != NULL) {
488 491 ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
489 492 kstat_delete_netstack(ksp, stackid);
490 493 }
491 494 }
492 495
493 496 /*
494 497 * Update routine for .
495 498 */
496 499 static int
497 500 dccp_kstat2_update(kstat_t *kp, int rw)
498 501 {
499 502 dccp_stack_t *dccps;
500 503 dccp_stat_t *stats;
501 504 netstack_t *ns;
502 505 netstackid_t stackid;
503 506 int i;
504 507 int cnt;
505 508
506 509 if (rw == KSTAT_WRITE) {
507 510 return (EACCES);
508 511 }
509 512
510 513 stackid = (netstackid_t)(uintptr_t)kp->ks_private;
511 514 ns = netstack_find_by_stackid(stackid);
512 515 if (ns == NULL) {
513 516 return (-1);
514 517 }
515 518
516 519 dccps = ns->netstack_dccp;
517 520 if (dccps == NULL) {
518 521 netstack_rele(ns);
519 522 return (-1);
520 523 }
521 524
522 525 stats = (dccp_stat_t *)kp->ks_data;
523 526 dccp_clr_stats(stats);
524 527
525 528 /* Sum up all stats */
526 529 cnt = dccps->dccps_sc_cnt;
527 530 for (i = 0; i < cnt; i++) {
528 531 dccp_add_stats(&dccps->dccps_sc[i]->dccp_sc_stats, stats);
529 532 }
530 533
531 534 netstack_rele(ns);
532 535
533 536 return (0);
534 537 }
535 538
536 539 /*
537 540 * Add stats from one to another.
538 541 */
539 542 static void
540 543 dccp_add_mib(mib2_dccp_t *from, mib2_dccp_t *to)
541 544 {
542 545 to->dccpActiveOpens += from->dccpActiveOpens;
543 546 to->dccpPassiveOpens += from->dccpPassiveOpens;
544 547 to->dccpInSegs += from->dccpInSegs;
545 548 to->dccpOutSegs += from->dccpOutSegs;
546 549 }
547 550
548 551 /*
549 552 * Sum up all MIB-II stats for a dccp_stack_t from all per CPU stats.
550 553 */
551 554 static void
552 555 dccp_sum_mib(dccp_stack_t *dccps, mib2_dccp_t *dccp_mib)
553 556 {
554 557 int i;
555 558 int cnt;
556 559
557 560 cnt = dccps->dccps_sc_cnt;
558 561 for (i = 0; i < cnt; i++) {
559 562 dccp_add_mib(&dccps->dccps_sc[i]->dccp_sc_mib, dccp_mib);
560 563 }
561 564 }
562 565
563 566 /*
564 567 * Set all dccp_stat_t counters to zero.
565 568 */
566 569 static void
567 570 dccp_clr_stats(dccp_stat_t *stats)
568 571 {
569 572 stats->dccp_sock_fallback.value.ui64 = 0;
570 573 }
571 574
572 575 /*
573 576 * Add counters from the per CPU stats.
574 577 */
575 578 static void
576 579 dccp_add_stats(dccp_stat_counter_t *from, dccp_stat_t *to)
577 580 {
578 581 to->dccp_sock_fallback.value.ui64 +=
579 582 from->dccp_sock_fallback;
580 583 }
↓ open down ↓ |
87 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX