Print this page
dccp: build fixes, mdb (vfs sonode missing)
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mdb/common/modules/genunix/net.c
+++ new/usr/src/cmd/mdb/common/modules/genunix/net.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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #include <mdb/mdb_modapi.h>
27 27 #include <mdb/mdb_ks.h>
28 28 #include <mdb/mdb_ctf.h>
29 29 #include <sys/types.h>
30 30 #include <sys/tihdr.h>
31 31 #include <inet/led.h>
32 32 #include <inet/common.h>
33 33 #include <netinet/in.h>
34 34 #include <netinet/ip6.h>
35 35 #include <netinet/icmp6.h>
36 36 #include <inet/ip.h>
37 37 #include <inet/ip6.h>
38 38 #include <inet/ipclassifier.h>
39 39 #include <inet/tcp.h>
↓ open down ↓ |
39 lines elided |
↑ open up ↑ |
40 40 #include <sys/stream.h>
41 41 #include <sys/vfs.h>
42 42 #include <sys/stropts.h>
43 43 #include <sys/tpicommon.h>
44 44 #include <sys/socket.h>
45 45 #include <sys/socketvar.h>
46 46 #include <sys/cred_impl.h>
47 47 #include <inet/udp_impl.h>
48 48 #include <inet/rawip_impl.h>
49 49 #include <inet/mi.h>
50 +#include <inet/dccp/dccp_impl.h>
50 51 #include <fs/sockfs/socktpi_impl.h>
51 52 #include <net/bridge_impl.h>
52 53 #include <io/trill_impl.h>
53 54 #include <sys/mac_impl.h>
54 55
55 56 #define ADDR_V6_WIDTH 23
56 57 #define ADDR_V4_WIDTH 15
57 58
58 59 #define NETSTAT_ALL 0x01
59 60 #define NETSTAT_VERBOSE 0x02
60 61 #define NETSTAT_ROUTE 0x04
61 62 #define NETSTAT_V4 0x08
62 63 #define NETSTAT_V6 0x10
63 64 #define NETSTAT_UNIX 0x20
64 65
65 66 #define NETSTAT_FIRST 0x80000000u
66 67
67 68 typedef struct netstat_cb_data_s {
68 69 uint_t opts;
69 70 conn_t conn;
70 71 int af;
71 72 } netstat_cb_data_t;
72 73
73 74 int
74 75 icmp_stacks_walk_init(mdb_walk_state_t *wsp)
75 76 {
76 77 if (mdb_layered_walk("netstack", wsp) == -1) {
77 78 mdb_warn("can't walk 'netstack'");
78 79 return (WALK_ERR);
79 80 }
80 81 return (WALK_NEXT);
81 82 }
82 83
83 84 int
84 85 icmp_stacks_walk_step(mdb_walk_state_t *wsp)
85 86 {
86 87 uintptr_t kaddr;
87 88 netstack_t nss;
88 89
89 90 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) {
90 91 mdb_warn("can't read netstack at %p", wsp->walk_addr);
91 92 return (WALK_ERR);
92 93 }
93 94 kaddr = (uintptr_t)nss.netstack_modules[NS_ICMP];
94 95 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata));
95 96 }
96 97
97 98 int
98 99 tcp_stacks_walk_init(mdb_walk_state_t *wsp)
99 100 {
100 101 if (mdb_layered_walk("netstack", wsp) == -1) {
101 102 mdb_warn("can't walk 'netstack'");
102 103 return (WALK_ERR);
103 104 }
104 105 return (WALK_NEXT);
105 106 }
106 107
107 108 int
108 109 tcp_stacks_walk_step(mdb_walk_state_t *wsp)
109 110 {
110 111 uintptr_t kaddr;
111 112 netstack_t nss;
112 113
113 114 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) {
114 115 mdb_warn("can't read netstack at %p", wsp->walk_addr);
115 116 return (WALK_ERR);
116 117 }
117 118 kaddr = (uintptr_t)nss.netstack_modules[NS_TCP];
118 119 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata));
119 120 }
120 121
121 122 int
122 123 udp_stacks_walk_init(mdb_walk_state_t *wsp)
123 124 {
124 125 if (mdb_layered_walk("netstack", wsp) == -1) {
125 126 mdb_warn("can't walk 'netstack'");
126 127 return (WALK_ERR);
127 128 }
128 129 return (WALK_NEXT);
129 130 }
130 131
131 132 int
132 133 udp_stacks_walk_step(mdb_walk_state_t *wsp)
133 134 {
134 135 uintptr_t kaddr;
↓ open down ↓ |
75 lines elided |
↑ open up ↑ |
135 136 netstack_t nss;
136 137
137 138 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) {
138 139 mdb_warn("can't read netstack at %p", wsp->walk_addr);
139 140 return (WALK_ERR);
140 141 }
141 142 kaddr = (uintptr_t)nss.netstack_modules[NS_UDP];
142 143 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata));
143 144 }
144 145
146 +int
147 +dccp_stacks_walk_init(mdb_walk_state_t *wsp)
148 +{
149 + if (mdb_layered_walk("netstack", wsp) == -1) {
150 + mdb_warn("can't walk 'netstack'");
151 + return (WALK_ERR);
152 + }
153 + return (WALK_NEXT);
154 +}
155 +
156 +int
157 +dccp_stacks_walk_step(mdb_walk_state_t *wsp)
158 +{
159 + uintptr_t kaddr;
160 + netstack_t nss;
161 +
162 + if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) {
163 + mdb_warn("can't read netstack at %p", wsp->walk_addr);
164 + return (WALK_ERR);
165 + }
166 + kaddr = (uintptr_t)nss.netstack_modules[NS_DCCP];
167 + return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata));
168 +}
169 +
145 170 /*
146 171 * Print an IPv4 address and port number in a compact and easy to read format
147 172 * The arguments are in network byte order
148 173 */
149 174 static void
150 175 net_ipv4addrport_pr(const in6_addr_t *nipv6addr, in_port_t nport)
151 176 {
152 177 uint32_t naddr = V4_PART_OF_V6((*nipv6addr));
153 178
154 179 mdb_nhconvert(&nport, &nport, sizeof (nport));
155 180 mdb_printf("%*I.%-5hu", ADDR_V4_WIDTH, naddr, nport);
156 181 }
157 182
158 183 /*
159 184 * Print an IPv6 address and port number in a compact and easy to read format
160 185 * The arguments are in network byte order
161 186 */
162 187 static void
163 188 net_ipv6addrport_pr(const in6_addr_t *naddr, in_port_t nport)
164 189 {
165 190 mdb_nhconvert(&nport, &nport, sizeof (nport));
166 191 mdb_printf("%*N.%-5hu", ADDR_V6_WIDTH, naddr, nport);
167 192 }
168 193
169 194 static int
170 195 net_tcp_active(const tcp_t *tcp)
171 196 {
172 197 return (tcp->tcp_state >= TCPS_ESTABLISHED);
173 198 }
174 199
175 200 static int
176 201 net_tcp_ipv4(const tcp_t *tcp)
177 202 {
178 203 return ((tcp->tcp_connp->conn_ipversion == IPV4_VERSION) ||
179 204 (IN6_IS_ADDR_UNSPECIFIED(&tcp->tcp_connp->conn_laddr_v6) &&
180 205 (tcp->tcp_state <= TCPS_LISTEN)));
181 206 }
182 207
183 208 static int
184 209 net_tcp_ipv6(const tcp_t *tcp)
185 210 {
186 211 return (tcp->tcp_connp->conn_ipversion == IPV6_VERSION);
187 212 }
188 213
189 214 static int
190 215 net_udp_active(const udp_t *udp)
191 216 {
192 217 return ((udp->udp_state == TS_IDLE) ||
193 218 (udp->udp_state == TS_DATA_XFER));
194 219 }
195 220
196 221 static int
197 222 net_udp_ipv4(const udp_t *udp)
198 223 {
199 224 return ((udp->udp_connp->conn_ipversion == IPV4_VERSION) ||
↓ open down ↓ |
45 lines elided |
↑ open up ↑ |
200 225 (IN6_IS_ADDR_UNSPECIFIED(&udp->udp_connp->conn_laddr_v6) &&
201 226 (udp->udp_state <= TS_IDLE)));
202 227 }
203 228
204 229 static int
205 230 net_udp_ipv6(const udp_t *udp)
206 231 {
207 232 return (udp->udp_connp->conn_ipversion == IPV6_VERSION);
208 233 }
209 234
235 +static int
236 +net_dccp_active(const dccp_t *dccp)
237 +{
238 + return ((dccp->dccp_state == TS_IDLE) ||
239 + (dccp->dccp_state == TS_DATA_XFER));
240 +}
241 +
242 +static int
243 +net_dccp_ipv4(const dccp_t *dccp)
244 +{
245 + return ((dccp->dccp_connp->conn_ipversion == IPV4_VERSION) ||
246 + (IN6_IS_ADDR_UNSPECIFIED(&dccp->dccp_connp->conn_laddr_v6) &&
247 + (dccp->dccp_state <= DCCPS_LISTEN)));
248 +}
249 +
250 +static int
251 +net_dccp_ipv6(const dccp_t *dccp)
252 +{
253 + return (dccp->dccp_connp->conn_ipversion == IPV6_VERSION);
254 +}
255 +
210 256 int
211 257 sonode_walk_init(mdb_walk_state_t *wsp)
212 258 {
213 259 if (wsp->walk_addr == NULL) {
214 260 GElf_Sym sym;
215 261 struct socklist *slp;
216 262
217 263 if (mdb_lookup_by_obj("sockfs", "socklist", &sym) == -1) {
218 264 mdb_warn("failed to lookup sockfs`socklist");
219 265 return (WALK_ERR);
220 266 }
221 267
222 268 slp = (struct socklist *)(uintptr_t)sym.st_value;
223 269
224 270 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
225 271 (uintptr_t)&slp->sl_list) == -1) {
226 272 mdb_warn("failed to read address of initial sonode "
227 273 "at %p", &slp->sl_list);
228 274 return (WALK_ERR);
229 275 }
230 276 }
231 277
232 278 wsp->walk_data = mdb_alloc(sizeof (struct sotpi_sonode), UM_SLEEP);
233 279 return (WALK_NEXT);
234 280 }
235 281
236 282 int
237 283 sonode_walk_step(mdb_walk_state_t *wsp)
238 284 {
239 285 int status;
240 286 struct sotpi_sonode *stp;
241 287
242 288 if (wsp->walk_addr == NULL)
243 289 return (WALK_DONE);
244 290
245 291 if (mdb_vread(wsp->walk_data, sizeof (struct sotpi_sonode),
246 292 wsp->walk_addr) == -1) {
247 293 mdb_warn("failed to read sonode at %p", wsp->walk_addr);
248 294 return (WALK_ERR);
249 295 }
250 296
251 297 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
252 298 wsp->walk_cbdata);
253 299
254 300 stp = wsp->walk_data;
255 301
256 302 wsp->walk_addr = (uintptr_t)stp->st_info.sti_next_so;
257 303 return (status);
258 304 }
259 305
260 306 void
261 307 sonode_walk_fini(mdb_walk_state_t *wsp)
262 308 {
263 309 mdb_free(wsp->walk_data, sizeof (struct sotpi_sonode));
264 310 }
265 311
266 312 struct mi_walk_data {
267 313 uintptr_t mi_wd_miofirst;
268 314 MI_O mi_wd_miodata;
269 315 };
270 316
271 317 int
272 318 mi_walk_init(mdb_walk_state_t *wsp)
273 319 {
274 320 struct mi_walk_data *wdp;
275 321
276 322 if (wsp->walk_addr == NULL) {
277 323 mdb_warn("mi doesn't support global walks\n");
278 324 return (WALK_ERR);
279 325 }
280 326
281 327 wdp = mdb_alloc(sizeof (struct mi_walk_data), UM_SLEEP);
282 328
283 329 /* So that we do not immediately return WALK_DONE below */
284 330 wdp->mi_wd_miofirst = NULL;
285 331
286 332 wsp->walk_data = wdp;
287 333 return (WALK_NEXT);
288 334 }
289 335
290 336 int
291 337 mi_walk_step(mdb_walk_state_t *wsp)
292 338 {
293 339 struct mi_walk_data *wdp = wsp->walk_data;
294 340 MI_OP miop = &wdp->mi_wd_miodata;
295 341 int status;
296 342
297 343 /* Always false in the first iteration */
298 344 if ((wsp->walk_addr == (uintptr_t)NULL) ||
299 345 (wsp->walk_addr == wdp->mi_wd_miofirst)) {
300 346 return (WALK_DONE);
301 347 }
302 348
303 349 if (mdb_vread(miop, sizeof (MI_O), wsp->walk_addr) == -1) {
304 350 mdb_warn("failed to read MI object at %p", wsp->walk_addr);
305 351 return (WALK_ERR);
306 352 }
307 353
308 354 /* Only true in the first iteration */
309 355 if (wdp->mi_wd_miofirst == NULL) {
310 356 wdp->mi_wd_miofirst = wsp->walk_addr;
311 357 status = WALK_NEXT;
312 358 } else {
313 359 status = wsp->walk_callback(wsp->walk_addr + sizeof (MI_O),
314 360 &miop[1], wsp->walk_cbdata);
315 361 }
316 362
317 363 wsp->walk_addr = (uintptr_t)miop->mi_o_next;
318 364 return (status);
319 365 }
320 366
321 367 void
322 368 mi_walk_fini(mdb_walk_state_t *wsp)
323 369 {
324 370 mdb_free(wsp->walk_data, sizeof (struct mi_walk_data));
325 371 }
326 372
327 373 typedef struct mi_payload_walk_arg_s {
328 374 const char *mi_pwa_walker; /* Underlying walker */
329 375 const off_t mi_pwa_head_off; /* Offset for mi_o_head_t * in stack */
330 376 const size_t mi_pwa_size; /* size of mi payload */
331 377 const uint_t mi_pwa_flags; /* device and/or module */
332 378 } mi_payload_walk_arg_t;
333 379
334 380 #define MI_PAYLOAD_DEVICE 0x1
335 381 #define MI_PAYLOAD_MODULE 0x2
336 382
337 383 int
338 384 mi_payload_walk_init(mdb_walk_state_t *wsp)
339 385 {
340 386 const mi_payload_walk_arg_t *arg = wsp->walk_arg;
341 387
342 388 if (mdb_layered_walk(arg->mi_pwa_walker, wsp) == -1) {
343 389 mdb_warn("can't walk '%s'", arg->mi_pwa_walker);
344 390 return (WALK_ERR);
345 391 }
346 392 return (WALK_NEXT);
347 393 }
348 394
349 395 int
350 396 mi_payload_walk_step(mdb_walk_state_t *wsp)
351 397 {
352 398 const mi_payload_walk_arg_t *arg = wsp->walk_arg;
353 399 uintptr_t kaddr;
354 400
355 401 kaddr = wsp->walk_addr + arg->mi_pwa_head_off;
356 402
357 403 if (mdb_vread(&kaddr, sizeof (kaddr), kaddr) == -1) {
358 404 mdb_warn("can't read address of mi head at %p for %s",
359 405 kaddr, arg->mi_pwa_walker);
360 406 return (WALK_ERR);
361 407 }
362 408
363 409 if (kaddr == 0) {
364 410 /* Empty list */
365 411 return (WALK_DONE);
366 412 }
367 413
368 414 if (mdb_pwalk("genunix`mi", wsp->walk_callback,
369 415 wsp->walk_cbdata, kaddr) == -1) {
370 416 mdb_warn("failed to walk genunix`mi");
371 417 return (WALK_ERR);
372 418 }
373 419 return (WALK_NEXT);
374 420 }
375 421
376 422 const mi_payload_walk_arg_t mi_icmp_arg = {
377 423 "icmp_stacks", OFFSETOF(icmp_stack_t, is_head), sizeof (icmp_t),
378 424 MI_PAYLOAD_DEVICE | MI_PAYLOAD_MODULE
379 425 };
380 426
381 427 int
382 428 sonode(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
383 429 {
384 430 const char *optf = NULL;
385 431 const char *optt = NULL;
386 432 const char *optp = NULL;
387 433 int family, type, proto;
388 434 int filter = 0;
389 435 struct sonode so;
390 436
391 437 if (!(flags & DCMD_ADDRSPEC)) {
392 438 if (mdb_walk_dcmd("genunix`sonode", "genunix`sonode", argc,
393 439 argv) == -1) {
394 440 mdb_warn("failed to walk sonode");
395 441 return (DCMD_ERR);
396 442 }
397 443
398 444 return (DCMD_OK);
399 445 }
400 446
401 447 if (mdb_getopts(argc, argv,
402 448 'f', MDB_OPT_STR, &optf,
403 449 't', MDB_OPT_STR, &optt,
404 450 'p', MDB_OPT_STR, &optp,
405 451 NULL) != argc)
406 452 return (DCMD_USAGE);
407 453
408 454 if (optf != NULL) {
409 455 if (strcmp("inet", optf) == 0)
410 456 family = AF_INET;
411 457 else if (strcmp("inet6", optf) == 0)
412 458 family = AF_INET6;
413 459 else if (strcmp("unix", optf) == 0)
414 460 family = AF_UNIX;
415 461 else
416 462 family = mdb_strtoull(optf);
417 463 filter = 1;
418 464 }
419 465
420 466 if (optt != NULL) {
421 467 if (strcmp("stream", optt) == 0)
422 468 type = SOCK_STREAM;
423 469 else if (strcmp("dgram", optt) == 0)
424 470 type = SOCK_DGRAM;
425 471 else if (strcmp("raw", optt) == 0)
426 472 type = SOCK_RAW;
427 473 else
428 474 type = mdb_strtoull(optt);
429 475 filter = 1;
430 476 }
431 477
432 478 if (optp != NULL) {
433 479 proto = mdb_strtoull(optp);
434 480 filter = 1;
435 481 }
436 482
437 483 if (DCMD_HDRSPEC(flags) && !filter) {
438 484 mdb_printf("%<u>%-?s Family Type Proto State Mode Flag "
439 485 "AccessVP%</u>\n", "Sonode:");
440 486 }
441 487
442 488 if (mdb_vread(&so, sizeof (so), addr) == -1) {
443 489 mdb_warn("failed to read sonode at %p", addr);
444 490 return (DCMD_ERR);
445 491 }
446 492
447 493 if ((optf != NULL) && (so.so_family != family))
448 494 return (DCMD_OK);
449 495
450 496 if ((optt != NULL) && (so.so_type != type))
451 497 return (DCMD_OK);
452 498
453 499 if ((optp != NULL) && (so.so_protocol != proto))
454 500 return (DCMD_OK);
455 501
456 502 if (filter) {
457 503 mdb_printf("%0?p\n", addr);
458 504 return (DCMD_OK);
459 505 }
460 506
461 507 mdb_printf("%0?p ", addr);
462 508
463 509 switch (so.so_family) {
464 510 case AF_UNIX:
465 511 mdb_printf("unix ");
466 512 break;
467 513 case AF_INET:
468 514 mdb_printf("inet ");
469 515 break;
470 516 case AF_INET6:
471 517 mdb_printf("inet6 ");
472 518 break;
473 519 default:
474 520 mdb_printf("%6hi", so.so_family);
475 521 }
476 522
477 523 switch (so.so_type) {
478 524 case SOCK_STREAM:
479 525 mdb_printf(" strm");
480 526 break;
481 527 case SOCK_DGRAM:
482 528 mdb_printf(" dgrm");
483 529 break;
484 530 case SOCK_RAW:
485 531 mdb_printf(" raw ");
486 532 break;
487 533 default:
488 534 mdb_printf(" %4hi", so.so_type);
489 535 }
490 536
491 537 mdb_printf(" %5hi %05x %04x %04hx\n",
492 538 so.so_protocol, so.so_state, so.so_mode,
493 539 so.so_flag);
494 540
495 541 return (DCMD_OK);
496 542 }
497 543
498 544 #define MI_PAYLOAD 0x1
499 545 #define MI_DEVICE 0x2
500 546 #define MI_MODULE 0x4
501 547
502 548 int
503 549 mi(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
504 550 {
505 551 uint_t opts = 0;
506 552 MI_O mio;
507 553
508 554 if (!(flags & DCMD_ADDRSPEC))
509 555 return (DCMD_USAGE);
510 556
511 557 if (mdb_getopts(argc, argv,
512 558 'p', MDB_OPT_SETBITS, MI_PAYLOAD, &opts,
513 559 'd', MDB_OPT_SETBITS, MI_DEVICE, &opts,
514 560 'm', MDB_OPT_SETBITS, MI_MODULE, &opts,
515 561 NULL) != argc)
516 562 return (DCMD_USAGE);
517 563
518 564 if ((opts & (MI_DEVICE | MI_MODULE)) == (MI_DEVICE | MI_MODULE)) {
519 565 mdb_warn("at most one filter, d for devices or m "
520 566 "for modules, may be specified\n");
521 567 return (DCMD_USAGE);
522 568 }
523 569
524 570 if ((opts == 0) && (DCMD_HDRSPEC(flags))) {
525 571 mdb_printf("%<u>%-?s %-?s %-?s IsDev Dev%</u>\n",
526 572 "MI_O", "Next", "Prev");
527 573 }
528 574
529 575 if (mdb_vread(&mio, sizeof (mio), addr) == -1) {
530 576 mdb_warn("failed to read mi object MI_O at %p", addr);
531 577 return (DCMD_ERR);
532 578 }
533 579
534 580 if (opts != 0) {
535 581 if (mio.mi_o_isdev == B_FALSE) {
536 582 /* mio is a module */
537 583 if (!(opts & MI_MODULE) && (opts & MI_DEVICE))
538 584 return (DCMD_OK);
539 585 } else {
540 586 /* mio is a device */
541 587 if (!(opts & MI_DEVICE) && (opts & MI_MODULE))
542 588 return (DCMD_OK);
543 589 }
544 590
545 591 if (opts & MI_PAYLOAD)
546 592 mdb_printf("%p\n", addr + sizeof (MI_O));
547 593 else
548 594 mdb_printf("%p\n", addr);
549 595 return (DCMD_OK);
550 596 }
551 597
552 598 mdb_printf("%0?p %0?p %0?p ", addr, mio.mi_o_next, mio.mi_o_prev);
553 599
554 600 if (mio.mi_o_isdev == B_FALSE)
555 601 mdb_printf("FALSE");
556 602 else
557 603 mdb_printf("TRUE ");
558 604
559 605 mdb_printf(" %0?p\n", mio.mi_o_dev);
560 606
561 607 return (DCMD_OK);
562 608 }
563 609
564 610 static int
565 611 ns_to_stackid(uintptr_t kaddr)
566 612 {
567 613 netstack_t nss;
568 614
569 615 if (mdb_vread(&nss, sizeof (nss), kaddr) == -1) {
570 616 mdb_warn("failed to read netstack_t %p", kaddr);
571 617 return (0);
572 618 }
573 619 return (nss.netstack_stackid);
574 620 }
575 621
576 622
577 623
578 624 static void
579 625 netstat_tcp_verbose_pr(const tcp_t *tcp)
580 626 {
581 627 mdb_printf(" %5i %08x %08x %5i %08x %08x %5li %5i\n",
582 628 tcp->tcp_swnd, tcp->tcp_snxt, tcp->tcp_suna, tcp->tcp_rwnd,
583 629 tcp->tcp_rack, tcp->tcp_rnxt, tcp->tcp_rto, tcp->tcp_mss);
584 630 }
585 631
586 632 /*ARGSUSED*/
587 633 static int
588 634 netstat_tcp_cb(uintptr_t kaddr, const void *walk_data, void *cb_data)
589 635 {
590 636 netstat_cb_data_t *ncb = cb_data;
591 637 uint_t opts = ncb->opts;
592 638 int af = ncb->af;
593 639 uintptr_t tcp_kaddr;
594 640 conn_t *connp = &ncb->conn;
595 641 tcp_t tcps, *tcp;
596 642
597 643 if (mdb_vread(connp, sizeof (conn_t), kaddr) == -1) {
598 644 mdb_warn("failed to read conn_t at %p", kaddr);
599 645 return (WALK_ERR);
600 646 }
601 647
602 648 tcp_kaddr = (uintptr_t)connp->conn_tcp;
603 649 if (mdb_vread(&tcps, sizeof (tcp_t), tcp_kaddr) == -1) {
604 650 mdb_warn("failed to read tcp_t at %p", tcp_kaddr);
605 651 return (WALK_ERR);
606 652 }
607 653
608 654 tcp = &tcps;
609 655 connp->conn_tcp = tcp;
610 656 tcp->tcp_connp = connp;
611 657
612 658 if (!((opts & NETSTAT_ALL) || net_tcp_active(tcp)) ||
613 659 (af == AF_INET && !net_tcp_ipv4(tcp)) ||
614 660 (af == AF_INET6 && !net_tcp_ipv6(tcp))) {
615 661 return (WALK_NEXT);
616 662 }
617 663
618 664 mdb_printf("%0?p %2i ", tcp_kaddr, tcp->tcp_state);
619 665 if (af == AF_INET) {
620 666 net_ipv4addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
621 667 mdb_printf(" ");
622 668 net_ipv4addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
623 669 } else if (af == AF_INET6) {
624 670 net_ipv6addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
625 671 mdb_printf(" ");
626 672 net_ipv6addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
627 673 }
628 674 mdb_printf(" %5i", ns_to_stackid((uintptr_t)connp->conn_netstack));
629 675 mdb_printf(" %4i\n", connp->conn_zoneid);
630 676 if (opts & NETSTAT_VERBOSE)
631 677 netstat_tcp_verbose_pr(tcp);
632 678
633 679 return (WALK_NEXT);
634 680 }
635 681
636 682 /*ARGSUSED*/
637 683 static int
638 684 netstat_udp_cb(uintptr_t kaddr, const void *walk_data, void *cb_data)
639 685 {
640 686 netstat_cb_data_t *ncb = cb_data;
641 687 uint_t opts = ncb->opts;
642 688 int af = ncb->af;
643 689 udp_t udp;
644 690 conn_t *connp = &ncb->conn;
645 691 char *state;
646 692
647 693 if (mdb_vread(connp, sizeof (conn_t), kaddr) == -1) {
648 694 mdb_warn("failed to read conn_t at %p", kaddr);
649 695 return (WALK_ERR);
650 696 }
651 697
652 698 if (mdb_vread(&udp, sizeof (udp_t),
653 699 (uintptr_t)connp->conn_udp) == -1) {
654 700 mdb_warn("failed to read conn_udp at %p",
655 701 (uintptr_t)connp->conn_udp);
656 702 return (WALK_ERR);
657 703 }
658 704
659 705 connp->conn_udp = &udp;
660 706 udp.udp_connp = connp;
661 707
662 708 if (!((opts & NETSTAT_ALL) || net_udp_active(&udp)) ||
663 709 (af == AF_INET && !net_udp_ipv4(&udp)) ||
664 710 (af == AF_INET6 && !net_udp_ipv6(&udp))) {
665 711 return (WALK_NEXT);
666 712 }
667 713
668 714 if (udp.udp_state == TS_UNBND)
669 715 state = "UNBOUND";
670 716 else if (udp.udp_state == TS_IDLE)
671 717 state = "IDLE";
672 718 else if (udp.udp_state == TS_DATA_XFER)
673 719 state = "CONNECTED";
674 720 else
675 721 state = "UNKNOWN";
676 722
677 723 mdb_printf("%0?p %10s ", (uintptr_t)connp->conn_udp, state);
678 724 if (af == AF_INET) {
679 725 net_ipv4addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
680 726 mdb_printf(" ");
681 727 net_ipv4addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
682 728 } else if (af == AF_INET6) {
683 729 net_ipv6addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
684 730 mdb_printf(" ");
685 731 net_ipv6addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
686 732 }
687 733 mdb_printf(" %5i", ns_to_stackid((uintptr_t)connp->conn_netstack));
688 734 mdb_printf(" %4i\n", connp->conn_zoneid);
689 735
690 736 return (WALK_NEXT);
691 737 }
692 738
693 739 /*ARGSUSED*/
694 740 static int
695 741 netstat_icmp_cb(uintptr_t kaddr, const void *walk_data, void *cb_data)
696 742 {
697 743 netstat_cb_data_t *ncb = cb_data;
698 744 int af = ncb->af;
699 745 icmp_t icmp;
700 746 conn_t *connp = &ncb->conn;
701 747 char *state;
702 748
703 749 if (mdb_vread(connp, sizeof (conn_t), kaddr) == -1) {
704 750 mdb_warn("failed to read conn_t at %p", kaddr);
705 751 return (WALK_ERR);
706 752 }
707 753
708 754 if (mdb_vread(&icmp, sizeof (icmp_t),
709 755 (uintptr_t)connp->conn_icmp) == -1) {
710 756 mdb_warn("failed to read conn_icmp at %p",
711 757 (uintptr_t)connp->conn_icmp);
712 758 return (WALK_ERR);
713 759 }
714 760
715 761 connp->conn_icmp = &icmp;
716 762 icmp.icmp_connp = connp;
717 763
718 764 if ((af == AF_INET && connp->conn_ipversion != IPV4_VERSION) ||
719 765 (af == AF_INET6 && connp->conn_ipversion != IPV6_VERSION)) {
720 766 return (WALK_NEXT);
721 767 }
722 768
723 769 if (icmp.icmp_state == TS_UNBND)
724 770 state = "UNBOUND";
725 771 else if (icmp.icmp_state == TS_IDLE)
726 772 state = "IDLE";
727 773 else if (icmp.icmp_state == TS_DATA_XFER)
728 774 state = "CONNECTED";
729 775 else
730 776 state = "UNKNOWN";
731 777
732 778 mdb_printf("%0?p %10s ", (uintptr_t)connp->conn_icmp, state);
733 779 if (af == AF_INET) {
734 780 net_ipv4addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
735 781 mdb_printf(" ");
736 782 net_ipv4addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
737 783 } else if (af == AF_INET6) {
↓ open down ↓ |
518 lines elided |
↑ open up ↑ |
738 784 net_ipv6addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
739 785 mdb_printf(" ");
740 786 net_ipv6addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
741 787 }
742 788 mdb_printf(" %5i", ns_to_stackid((uintptr_t)connp->conn_netstack));
743 789 mdb_printf(" %4i\n", connp->conn_zoneid);
744 790
745 791 return (WALK_NEXT);
746 792 }
747 793
794 +static void
795 +netstat_dccp_verbose_pr(const dccp_t *dccp)
796 +{
797 +/* XXX:DCCP
798 + mdb_printf(" %5i %08x %08x %5i %08x %08x %5li %5i\n",
799 + tcp->tcp_swnd, tcp->tcp_snxt, tcp->tcp_suna, tcp->tcp_rwnd,
800 + tcp->tcp_rack, tcp->tcp_rnxt, tcp->tcp_rto, tcp->tcp_mss);
801 +*/
802 +}
803 +
804 +/*ARGSUSED*/
805 +static int
806 +netstat_dccp_cb(uintptr_t kaddr, const void *walk_data, void *cb_data)
807 +{
808 + netstat_cb_data_t *ncb = cb_data;
809 + uint_t opts = ncb->opts;
810 + int af = ncb->af;
811 + uintptr_t dccp_kaddr;
812 + conn_t *connp = &ncb->conn;
813 + dccp_t dccps, *dccp;
814 +
815 + if (mdb_vread(connp, sizeof (conn_t), kaddr) == -1) {
816 + mdb_warn("failed to read conn_t at %p", kaddr);
817 + return (WALK_ERR);
818 + }
819 +
820 + dccp_kaddr = (uintptr_t)connp->conn_dccp;
821 + if (mdb_vread(&dccps, sizeof (dccp_t), dccp_kaddr) == -1) {
822 + mdb_warn("failed to read tcp_t at %p", dccp_kaddr);
823 + return (WALK_ERR);
824 + }
825 +
826 + dccp = &dccps;
827 + connp->conn_dccp = dccp;
828 + dccp->dccp_connp = connp;
829 +
830 + if (!((opts & NETSTAT_ALL) || net_dccp_active(dccp)) ||
831 + (af == AF_INET && !net_dccp_ipv4(dccp)) ||
832 + (af == AF_INET6 && !net_dccp_ipv6(dccp))) {
833 + return (WALK_NEXT);
834 + }
835 +
836 + mdb_printf("%0?p %2i ", dccp_kaddr, dccp->dccp_state);
837 + if (af == AF_INET) {
838 + net_ipv4addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
839 + mdb_printf(" ");
840 + net_ipv4addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
841 + } else if (af == AF_INET6) {
842 + net_ipv6addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
843 + mdb_printf(" ");
844 + net_ipv6addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
845 + }
846 + mdb_printf(" %5i", ns_to_stackid((uintptr_t)connp->conn_netstack));
847 + mdb_printf(" %4i\n", connp->conn_zoneid);
848 + if (opts & NETSTAT_VERBOSE)
849 + netstat_dccp_verbose_pr(dccp);
850 +
851 + return (WALK_NEXT);
852 +}
853 +
748 854 /*
749 855 * print the address of a unix domain socket
750 856 *
751 857 * so is the address of a AF_UNIX struct sonode in mdb's address space
752 858 * soa is the address of the struct soaddr to print
753 859 *
754 860 * returns 0 on success, -1 otherwise
755 861 */
756 862 static int
757 863 netstat_unix_name_pr(const struct sotpi_sonode *st, const struct soaddr *soa)
758 864 {
759 865 const struct sonode *so = &st->st_sonode;
760 866 const char none[] = " (none)";
761 867
762 868 if ((so->so_state & SS_ISBOUND) && (soa->soa_len != 0)) {
763 869 if (st->st_info.sti_faddr_noxlate) {
764 870 mdb_printf("%-14s ", " (socketpair)");
765 871 } else {
766 872 if (soa->soa_len > sizeof (sa_family_t)) {
767 873 char addr[MAXPATHLEN + 1];
768 874
769 875 if (mdb_readstr(addr, sizeof (addr),
770 876 (uintptr_t)&soa->soa_sa->sa_data) == -1) {
771 877 mdb_warn("failed to read unix address "
772 878 "at %p", &soa->soa_sa->sa_data);
773 879 return (-1);
774 880 }
775 881
776 882 mdb_printf("%-14s ", addr);
777 883 } else {
778 884 mdb_printf("%-14s ", none);
779 885 }
780 886 }
781 887 } else {
782 888 mdb_printf("%-14s ", none);
783 889 }
784 890
785 891 return (0);
786 892 }
787 893
788 894 /* based on sockfs_snapshot */
789 895 /*ARGSUSED*/
790 896 static int
791 897 netstat_unix_cb(uintptr_t kaddr, const void *walk_data, void *cb_data)
792 898 {
793 899 const struct sotpi_sonode *st = walk_data;
794 900 const struct sonode *so = &st->st_sonode;
795 901 const struct sotpi_info *sti = &st->st_info;
796 902
797 903 if (so->so_count == 0)
798 904 return (WALK_NEXT);
799 905
800 906 if (so->so_family != AF_UNIX) {
801 907 mdb_warn("sonode of family %hi at %p\n", so->so_family, kaddr);
802 908 return (WALK_ERR);
803 909 }
804 910
805 911 mdb_printf("%-?p ", kaddr);
806 912
807 913 switch (sti->sti_serv_type) {
808 914 case T_CLTS:
809 915 mdb_printf("%-10s ", "dgram");
810 916 break;
811 917 case T_COTS:
812 918 mdb_printf("%-10s ", "stream");
813 919 break;
814 920 case T_COTS_ORD:
815 921 mdb_printf("%-10s ", "stream-ord");
816 922 break;
817 923 default:
818 924 mdb_printf("%-10i ", sti->sti_serv_type);
819 925 }
820 926
821 927 if ((so->so_state & SS_ISBOUND) &&
822 928 (sti->sti_ux_laddr.soua_magic == SOU_MAGIC_EXPLICIT)) {
823 929 mdb_printf("%0?p ", sti->sti_ux_laddr.soua_vp);
824 930 } else {
825 931 mdb_printf("%0?p ", NULL);
826 932 }
827 933
828 934 if ((so->so_state & SS_ISCONNECTED) &&
829 935 (sti->sti_ux_faddr.soua_magic == SOU_MAGIC_EXPLICIT)) {
830 936 mdb_printf("%0?p ", sti->sti_ux_faddr.soua_vp);
831 937 } else {
832 938 mdb_printf("%0?p ", NULL);
833 939 }
834 940
835 941 if (netstat_unix_name_pr(st, &sti->sti_laddr) == -1)
836 942 return (WALK_ERR);
837 943
838 944 if (netstat_unix_name_pr(st, &sti->sti_faddr) == -1)
839 945 return (WALK_ERR);
840 946
841 947 mdb_printf("%4i\n", so->so_zoneid);
842 948
843 949 return (WALK_NEXT);
844 950 }
845 951
846 952 static void
847 953 netstat_tcp_verbose_header_pr(void)
848 954 {
849 955 mdb_printf(" %<u>%-5s %-8s %-8s %-5s %-8s %-8s %5s %5s%</u>\n",
850 956 "Swind", "Snext", "Suna", "Rwind", "Rack", "Rnext", "Rto", "Mss");
851 957 }
852 958
853 959 static void
854 960 get_ifname(const ire_t *ire, char *intf)
855 961 {
856 962 ill_t ill;
857 963
858 964 *intf = '\0';
859 965 if (ire->ire_ill != NULL) {
860 966 if (mdb_vread(&ill, sizeof (ill),
861 967 (uintptr_t)ire->ire_ill) == -1)
862 968 return;
863 969 (void) mdb_readstr(intf, MIN(LIFNAMSIZ, ill.ill_name_length),
864 970 (uintptr_t)ill.ill_name);
865 971 }
866 972 }
867 973
868 974 const in6_addr_t ipv6_all_ones =
869 975 { 0xffffffffU, 0xffffffffU, 0xffffffffU, 0xffffffffU };
870 976
871 977 static void
872 978 get_ireflags(const ire_t *ire, char *flags)
873 979 {
874 980 (void) strcpy(flags, "U");
875 981 /* RTF_INDIRECT wins over RTF_GATEWAY - don't display both */
876 982 if (ire->ire_flags & RTF_INDIRECT)
877 983 (void) strcat(flags, "I");
878 984 else if (ire->ire_type & IRE_OFFLINK)
879 985 (void) strcat(flags, "G");
880 986
881 987 /* IRE_IF_CLONE wins over RTF_HOST - don't display both */
882 988 if (ire->ire_type & IRE_IF_CLONE)
883 989 (void) strcat(flags, "C");
884 990 else if (ire->ire_ipversion == IPV4_VERSION) {
885 991 if (ire->ire_mask == IP_HOST_MASK)
886 992 (void) strcat(flags, "H");
887 993 } else {
888 994 if (IN6_ARE_ADDR_EQUAL(&ire->ire_mask_v6, &ipv6_all_ones))
889 995 (void) strcat(flags, "H");
890 996 }
891 997
892 998 if (ire->ire_flags & RTF_DYNAMIC)
893 999 (void) strcat(flags, "D");
894 1000 if (ire->ire_type == IRE_BROADCAST)
895 1001 (void) strcat(flags, "b");
896 1002 if (ire->ire_type == IRE_MULTICAST)
897 1003 (void) strcat(flags, "m");
898 1004 if (ire->ire_type == IRE_LOCAL)
899 1005 (void) strcat(flags, "L");
900 1006 if (ire->ire_type == IRE_NOROUTE)
901 1007 (void) strcat(flags, "N");
902 1008 if (ire->ire_flags & RTF_MULTIRT)
903 1009 (void) strcat(flags, "M");
904 1010 if (ire->ire_flags & RTF_SETSRC)
905 1011 (void) strcat(flags, "S");
906 1012 if (ire->ire_flags & RTF_REJECT)
907 1013 (void) strcat(flags, "R");
908 1014 if (ire->ire_flags & RTF_BLACKHOLE)
909 1015 (void) strcat(flags, "B");
910 1016 }
911 1017
912 1018 static int
913 1019 netstat_irev4_cb(uintptr_t kaddr, const void *walk_data, void *cb_data)
914 1020 {
915 1021 const ire_t *ire = walk_data;
916 1022 uint_t *opts = cb_data;
917 1023 ipaddr_t gate;
918 1024 char flags[10], intf[LIFNAMSIZ + 1];
919 1025
920 1026 if (ire->ire_ipversion != IPV4_VERSION)
921 1027 return (WALK_NEXT);
922 1028
923 1029 /* Skip certain IREs by default */
924 1030 if (!(*opts & NETSTAT_ALL) &&
925 1031 (ire->ire_type &
926 1032 (IRE_BROADCAST|IRE_LOCAL|IRE_MULTICAST|IRE_NOROUTE|IRE_IF_CLONE)))
927 1033 return (WALK_NEXT);
928 1034
929 1035 if (*opts & NETSTAT_FIRST) {
930 1036 *opts &= ~NETSTAT_FIRST;
931 1037 mdb_printf("%<u>%s Table: IPv4%</u>\n",
932 1038 (*opts & NETSTAT_VERBOSE) ? "IRE" : "Routing");
933 1039 if (*opts & NETSTAT_VERBOSE) {
934 1040 mdb_printf("%<u>%-?s %-*s %-*s %-*s Device Mxfrg Rtt "
935 1041 " Ref Flg Out In/Fwd%</u>\n",
936 1042 "Address", ADDR_V4_WIDTH, "Destination",
937 1043 ADDR_V4_WIDTH, "Mask", ADDR_V4_WIDTH, "Gateway");
938 1044 } else {
939 1045 mdb_printf("%<u>%-?s %-*s %-*s Flags Ref Use "
940 1046 "Interface%</u>\n",
941 1047 "Address", ADDR_V4_WIDTH, "Destination",
942 1048 ADDR_V4_WIDTH, "Gateway");
943 1049 }
944 1050 }
945 1051
946 1052 gate = ire->ire_gateway_addr;
947 1053
948 1054 get_ireflags(ire, flags);
949 1055
950 1056 get_ifname(ire, intf);
951 1057
952 1058 if (*opts & NETSTAT_VERBOSE) {
953 1059 mdb_printf("%?p %-*I %-*I %-*I %-6s %5u%c %4u %3u %-3s %5u "
954 1060 "%u\n", kaddr, ADDR_V4_WIDTH, ire->ire_addr, ADDR_V4_WIDTH,
955 1061 ire->ire_mask, ADDR_V4_WIDTH, gate, intf,
956 1062 0, ' ',
957 1063 ire->ire_metrics.iulp_rtt, ire->ire_refcnt, flags,
958 1064 ire->ire_ob_pkt_count, ire->ire_ib_pkt_count);
959 1065 } else {
960 1066 mdb_printf("%?p %-*I %-*I %-5s %4u %5u %s\n", kaddr,
961 1067 ADDR_V4_WIDTH, ire->ire_addr, ADDR_V4_WIDTH, gate, flags,
962 1068 ire->ire_refcnt,
963 1069 ire->ire_ob_pkt_count + ire->ire_ib_pkt_count, intf);
964 1070 }
965 1071
966 1072 return (WALK_NEXT);
967 1073 }
968 1074
969 1075 int
970 1076 ip_mask_to_plen_v6(const in6_addr_t *v6mask)
971 1077 {
972 1078 int plen;
973 1079 int i;
974 1080 uint32_t val;
975 1081
976 1082 for (i = 3; i >= 0; i--)
977 1083 if (v6mask->s6_addr32[i] != 0)
978 1084 break;
979 1085 if (i < 0)
980 1086 return (0);
981 1087 plen = 32 + 32 * i;
982 1088 val = v6mask->s6_addr32[i];
983 1089 while (!(val & 1)) {
984 1090 val >>= 1;
985 1091 plen--;
986 1092 }
987 1093
988 1094 return (plen);
989 1095 }
990 1096
991 1097 static int
992 1098 netstat_irev6_cb(uintptr_t kaddr, const void *walk_data, void *cb_data)
993 1099 {
994 1100 const ire_t *ire = walk_data;
995 1101 uint_t *opts = cb_data;
996 1102 const in6_addr_t *gatep;
997 1103 char deststr[ADDR_V6_WIDTH + 5];
998 1104 char flags[10], intf[LIFNAMSIZ + 1];
999 1105 int masklen;
1000 1106
1001 1107 if (ire->ire_ipversion != IPV6_VERSION)
1002 1108 return (WALK_NEXT);
1003 1109
1004 1110 /* Skip certain IREs by default */
1005 1111 if (!(*opts & NETSTAT_ALL) &&
1006 1112 (ire->ire_type &
1007 1113 (IRE_BROADCAST|IRE_LOCAL|IRE_MULTICAST|IRE_NOROUTE|IRE_IF_CLONE)))
1008 1114 return (WALK_NEXT);
1009 1115
1010 1116 if (*opts & NETSTAT_FIRST) {
1011 1117 *opts &= ~NETSTAT_FIRST;
1012 1118 mdb_printf("\n%<u>%s Table: IPv6%</u>\n",
1013 1119 (*opts & NETSTAT_VERBOSE) ? "IRE" : "Routing");
1014 1120 if (*opts & NETSTAT_VERBOSE) {
1015 1121 mdb_printf("%<u>%-?s %-*s %-*s If PMTU Rtt Ref "
1016 1122 "Flags Out In/Fwd%</u>\n",
1017 1123 "Address", ADDR_V6_WIDTH+4, "Destination/Mask",
1018 1124 ADDR_V6_WIDTH, "Gateway");
1019 1125 } else {
1020 1126 mdb_printf("%<u>%-?s %-*s %-*s Flags Ref Use If"
1021 1127 "%</u>\n",
1022 1128 "Address", ADDR_V6_WIDTH+4, "Destination/Mask",
1023 1129 ADDR_V6_WIDTH, "Gateway");
1024 1130 }
1025 1131 }
1026 1132
1027 1133 gatep = &ire->ire_gateway_addr_v6;
1028 1134
1029 1135 masklen = ip_mask_to_plen_v6(&ire->ire_mask_v6);
1030 1136 (void) mdb_snprintf(deststr, sizeof (deststr), "%N/%d",
1031 1137 &ire->ire_addr_v6, masklen);
1032 1138
1033 1139 get_ireflags(ire, flags);
1034 1140
1035 1141 get_ifname(ire, intf);
1036 1142
1037 1143 if (*opts & NETSTAT_VERBOSE) {
1038 1144 mdb_printf("%?p %-*s %-*N %-5s %5u%c %5u %3u %-5s %6u %u\n",
1039 1145 kaddr, ADDR_V6_WIDTH+4, deststr, ADDR_V6_WIDTH, gatep,
1040 1146 intf, 0, ' ',
1041 1147 ire->ire_metrics.iulp_rtt, ire->ire_refcnt,
1042 1148 flags, ire->ire_ob_pkt_count, ire->ire_ib_pkt_count);
1043 1149 } else {
1044 1150 mdb_printf("%?p %-*s %-*N %-5s %3u %6u %s\n", kaddr,
1045 1151 ADDR_V6_WIDTH+4, deststr, ADDR_V6_WIDTH, gatep, flags,
1046 1152 ire->ire_refcnt,
1047 1153 ire->ire_ob_pkt_count + ire->ire_ib_pkt_count, intf);
1048 1154 }
1049 1155
1050 1156 return (WALK_NEXT);
1051 1157 }
1052 1158
1053 1159 static void
1054 1160 netstat_header_v4(int proto)
1055 1161 {
1056 1162 if (proto == IPPROTO_TCP)
1057 1163 mdb_printf("%<u>%-?s ", "TCPv4");
1058 1164 else if (proto == IPPROTO_UDP)
1059 1165 mdb_printf("%<u>%-?s ", "UDPv4");
1060 1166 else if (proto == IPPROTO_ICMP)
1061 1167 mdb_printf("%<u>%-?s ", "ICMPv4");
1062 1168 mdb_printf("State %6s%*s %6s%*s %-5s %-4s%</u>\n",
1063 1169 "", ADDR_V4_WIDTH, "Local Address",
1064 1170 "", ADDR_V4_WIDTH, "Remote Address", "Stack", "Zone");
1065 1171 }
1066 1172
1067 1173 static void
1068 1174 netstat_header_v6(int proto)
1069 1175 {
1070 1176 if (proto == IPPROTO_TCP)
1071 1177 mdb_printf("%<u>%-?s ", "TCPv6");
1072 1178 else if (proto == IPPROTO_UDP)
1073 1179 mdb_printf("%<u>%-?s ", "UDPv6");
1074 1180 else if (proto == IPPROTO_ICMP)
1075 1181 mdb_printf("%<u>%-?s ", "ICMPv6");
1076 1182 mdb_printf("State %6s%*s %6s%*s %-5s %-4s%</u>\n",
1077 1183 "", ADDR_V6_WIDTH, "Local Address",
1078 1184 "", ADDR_V6_WIDTH, "Remote Address", "Stack", "Zone");
1079 1185 }
1080 1186
1081 1187 static int
1082 1188 netstat_print_conn(const char *cache, int proto, mdb_walk_cb_t cbfunc,
1083 1189 void *cbdata)
1084 1190 {
1085 1191 netstat_cb_data_t *ncb = cbdata;
1086 1192
1087 1193 if ((ncb->opts & NETSTAT_VERBOSE) && proto == IPPROTO_TCP)
1088 1194 netstat_tcp_verbose_header_pr();
1089 1195 if (mdb_walk(cache, cbfunc, cbdata) == -1) {
1090 1196 mdb_warn("failed to walk %s", cache);
1091 1197 return (DCMD_ERR);
1092 1198 }
1093 1199 return (DCMD_OK);
1094 1200 }
1095 1201
1096 1202 static int
1097 1203 netstat_print_common(const char *cache, int proto, mdb_walk_cb_t cbfunc,
1098 1204 void *cbdata)
1099 1205 {
1100 1206 netstat_cb_data_t *ncb = cbdata;
1101 1207 int af = ncb->af;
1102 1208 int status = DCMD_OK;
1103 1209
1104 1210 if (af != AF_INET6) {
1105 1211 ncb->af = AF_INET;
1106 1212 netstat_header_v4(proto);
1107 1213 status = netstat_print_conn(cache, proto, cbfunc, cbdata);
1108 1214 }
1109 1215 if (status == DCMD_OK && af != AF_INET) {
1110 1216 ncb->af = AF_INET6;
1111 1217 netstat_header_v6(proto);
1112 1218 status = netstat_print_conn(cache, proto, cbfunc, cbdata);
1113 1219 }
1114 1220 ncb->af = af;
1115 1221 return (status);
1116 1222 }
1117 1223
1118 1224 /*ARGSUSED*/
1119 1225 int
1120 1226 netstat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1121 1227 {
1122 1228 uint_t opts = 0;
1123 1229 const char *optf = NULL;
1124 1230 const char *optP = NULL;
1125 1231 netstat_cb_data_t *cbdata;
1126 1232 int status;
1127 1233 int af = 0;
1128 1234
1129 1235 if (mdb_getopts(argc, argv,
1130 1236 'a', MDB_OPT_SETBITS, NETSTAT_ALL, &opts,
1131 1237 'f', MDB_OPT_STR, &optf,
1132 1238 'P', MDB_OPT_STR, &optP,
1133 1239 'r', MDB_OPT_SETBITS, NETSTAT_ROUTE, &opts,
1134 1240 'v', MDB_OPT_SETBITS, NETSTAT_VERBOSE, &opts,
1135 1241 NULL) != argc)
1136 1242 return (DCMD_USAGE);
1137 1243
1138 1244 if (optP != NULL) {
1139 1245 if ((strcmp("tcp", optP) != 0) && (strcmp("udp", optP) != 0) &&
1140 1246 (strcmp("icmp", optP) != 0))
1141 1247 return (DCMD_USAGE);
1142 1248 if (opts & NETSTAT_ROUTE)
1143 1249 return (DCMD_USAGE);
1144 1250 }
1145 1251
1146 1252 if (optf == NULL)
1147 1253 opts |= NETSTAT_V4 | NETSTAT_V6 | NETSTAT_UNIX;
1148 1254 else if (strcmp("inet", optf) == 0)
1149 1255 opts |= NETSTAT_V4;
1150 1256 else if (strcmp("inet6", optf) == 0)
1151 1257 opts |= NETSTAT_V6;
1152 1258 else if (strcmp("unix", optf) == 0)
1153 1259 opts |= NETSTAT_UNIX;
1154 1260 else
1155 1261 return (DCMD_USAGE);
1156 1262
1157 1263 if (opts & NETSTAT_ROUTE) {
1158 1264 if (!(opts & (NETSTAT_V4|NETSTAT_V6)))
1159 1265 return (DCMD_USAGE);
1160 1266 if (opts & NETSTAT_V4) {
1161 1267 opts |= NETSTAT_FIRST;
1162 1268 if (mdb_walk("ip`ire", netstat_irev4_cb, &opts) == -1) {
1163 1269 mdb_warn("failed to walk ip`ire");
1164 1270 return (DCMD_ERR);
1165 1271 }
1166 1272 }
1167 1273 if (opts & NETSTAT_V6) {
1168 1274 opts |= NETSTAT_FIRST;
1169 1275 if (mdb_walk("ip`ire", netstat_irev6_cb, &opts) == -1) {
1170 1276 mdb_warn("failed to walk ip`ire");
1171 1277 return (DCMD_ERR);
1172 1278 }
1173 1279 }
1174 1280 return (DCMD_OK);
1175 1281 }
1176 1282
1177 1283 if ((opts & NETSTAT_UNIX) && (optP == NULL)) {
1178 1284 /* Print Unix Domain Sockets */
1179 1285 mdb_printf("%<u>%-?s %-10s %-?s %-?s %-14s %-14s %s%</u>\n",
1180 1286 "AF_UNIX", "Type", "Vnode", "Conn", "Local Addr",
1181 1287 "Remote Addr", "Zone");
1182 1288
1183 1289 if (mdb_walk("genunix`sonode", netstat_unix_cb, NULL) == -1) {
1184 1290 mdb_warn("failed to walk genunix`sonode");
1185 1291 return (DCMD_ERR);
1186 1292 }
1187 1293 if (!(opts & (NETSTAT_V4 | NETSTAT_V6)))
1188 1294 return (DCMD_OK);
1189 1295 }
1190 1296
1191 1297 cbdata = mdb_alloc(sizeof (netstat_cb_data_t), UM_SLEEP);
1192 1298 cbdata->opts = opts;
1193 1299 if ((optf != NULL) && (opts & NETSTAT_V4))
1194 1300 af = AF_INET;
1195 1301 else if ((optf != NULL) && (opts & NETSTAT_V6))
1196 1302 af = AF_INET6;
1197 1303
1198 1304 cbdata->af = af;
1199 1305 if ((optP == NULL) || (strcmp("tcp", optP) == 0)) {
1200 1306 status = netstat_print_common("tcp_conn_cache", IPPROTO_TCP,
1201 1307 netstat_tcp_cb, cbdata);
1202 1308 if (status != DCMD_OK)
1203 1309 goto out;
1204 1310 }
1205 1311
1206 1312 if ((optP == NULL) || (strcmp("udp", optP) == 0)) {
1207 1313 status = netstat_print_common("udp_conn_cache", IPPROTO_UDP,
1208 1314 netstat_udp_cb, cbdata);
↓ open down ↓ |
451 lines elided |
↑ open up ↑ |
1209 1315 if (status != DCMD_OK)
1210 1316 goto out;
1211 1317 }
1212 1318
1213 1319 if ((optP == NULL) || (strcmp("icmp", optP) == 0)) {
1214 1320 status = netstat_print_common("rawip_conn_cache", IPPROTO_ICMP,
1215 1321 netstat_icmp_cb, cbdata);
1216 1322 if (status != DCMD_OK)
1217 1323 goto out;
1218 1324 }
1325 +
1326 + if ((optP == NULL) || (strcmp("dccp", optP) == 0)) {
1327 + status = netstat_print_common("dccp_conn_cache", IPPROTO_DCCP,
1328 + netstat_dccp_cb, cbdata);
1329 + if (status != DCMD_OK)
1330 + goto out;
1331 + }
1219 1332 out:
1220 1333 mdb_free(cbdata, sizeof (netstat_cb_data_t));
1221 1334 return (status);
1222 1335 }
1223 1336
1224 1337 /*
1225 1338 * "::dladm show-bridge" support
1226 1339 */
1227 1340 typedef struct {
1228 1341 uint_t opt_l;
1229 1342 uint_t opt_f;
1230 1343 uint_t opt_t;
1231 1344 const char *name;
1232 1345 clock_t lbolt;
1233 1346 boolean_t found;
1234 1347 uint_t nlinks;
1235 1348 uint_t nfwd;
1236 1349
1237 1350 /*
1238 1351 * These structures are kept inside the 'args' for allocation reasons.
1239 1352 * They're all large data structures (over 1K), and may cause the stack
1240 1353 * to explode. mdb and kmdb will fail in these cases, and thus we
1241 1354 * allocate them from the heap.
1242 1355 */
1243 1356 trill_inst_t ti;
1244 1357 bridge_link_t bl;
1245 1358 mac_impl_t mi;
1246 1359 } show_bridge_args_t;
1247 1360
1248 1361 static void
1249 1362 show_vlans(const uint8_t *vlans)
1250 1363 {
1251 1364 int i, bit;
1252 1365 uint8_t val;
1253 1366 int rstart = -1, rnext = -1;
1254 1367
1255 1368 for (i = 0; i < BRIDGE_VLAN_ARR_SIZE; i++) {
1256 1369 val = vlans[i];
1257 1370 if (i == 0)
1258 1371 val &= ~1;
1259 1372 while ((bit = mdb_ffs(val)) != 0) {
1260 1373 bit--;
1261 1374 val &= ~(1 << bit);
1262 1375 bit += i * sizeof (*vlans) * NBBY;
1263 1376 if (bit != rnext) {
1264 1377 if (rnext != -1 && rstart + 1 != rnext)
1265 1378 mdb_printf("-%d", rnext - 1);
1266 1379 if (rstart != -1)
1267 1380 mdb_printf(",");
1268 1381 mdb_printf("%d", bit);
1269 1382 rstart = bit;
1270 1383 }
1271 1384 rnext = bit + 1;
1272 1385 }
1273 1386 }
1274 1387 if (rnext != -1 && rstart + 1 != rnext)
1275 1388 mdb_printf("-%d", rnext - 1);
1276 1389 mdb_printf("\n");
1277 1390 }
1278 1391
1279 1392 /*
1280 1393 * This callback is invoked by a walk of the links attached to a bridge. If
1281 1394 * we're showing link details, then they're printed here. If not, then we just
1282 1395 * count up the links for the bridge summary.
1283 1396 */
1284 1397 static int
1285 1398 do_bridge_links(uintptr_t addr, const void *data, void *ptr)
1286 1399 {
1287 1400 show_bridge_args_t *args = ptr;
1288 1401 const bridge_link_t *blp = data;
1289 1402 char macaddr[ETHERADDRL * 3];
1290 1403 const char *name;
1291 1404
1292 1405 args->nlinks++;
1293 1406
1294 1407 if (!args->opt_l)
1295 1408 return (WALK_NEXT);
1296 1409
1297 1410 if (mdb_vread(&args->mi, sizeof (args->mi),
1298 1411 (uintptr_t)blp->bl_mh) == -1) {
1299 1412 mdb_warn("cannot read mac data at %p", blp->bl_mh);
1300 1413 name = "?";
1301 1414 } else {
1302 1415 name = args->mi.mi_name;
1303 1416 }
1304 1417
1305 1418 mdb_mac_addr(blp->bl_local_mac, ETHERADDRL, macaddr,
1306 1419 sizeof (macaddr));
1307 1420
1308 1421 mdb_printf("%-?p %-16s %-17s %03X %-4d ", addr, name, macaddr,
1309 1422 blp->bl_flags, blp->bl_pvid);
1310 1423
1311 1424 if (blp->bl_trilldata == NULL) {
1312 1425 switch (blp->bl_state) {
1313 1426 case BLS_BLOCKLISTEN:
1314 1427 name = "BLOCK";
1315 1428 break;
1316 1429 case BLS_LEARNING:
1317 1430 name = "LEARN";
1318 1431 break;
1319 1432 case BLS_FORWARDING:
1320 1433 name = "FWD";
1321 1434 break;
1322 1435 default:
1323 1436 name = "?";
1324 1437 }
1325 1438 mdb_printf("%-5s ", name);
1326 1439 show_vlans(blp->bl_vlans);
1327 1440 } else {
1328 1441 show_vlans(blp->bl_afs);
1329 1442 }
1330 1443
1331 1444 return (WALK_NEXT);
1332 1445 }
1333 1446
1334 1447 /*
1335 1448 * It seems a shame to duplicate this code, but merging it with the link
1336 1449 * printing code above is more trouble than it would be worth.
1337 1450 */
1338 1451 static void
1339 1452 print_link_name(show_bridge_args_t *args, uintptr_t addr, char sep)
1340 1453 {
1341 1454 const char *name;
1342 1455
1343 1456 if (mdb_vread(&args->bl, sizeof (args->bl), addr) == -1) {
1344 1457 mdb_warn("cannot read bridge link at %p", addr);
1345 1458 return;
1346 1459 }
1347 1460
1348 1461 if (mdb_vread(&args->mi, sizeof (args->mi),
1349 1462 (uintptr_t)args->bl.bl_mh) == -1) {
1350 1463 name = "?";
1351 1464 } else {
1352 1465 name = args->mi.mi_name;
1353 1466 }
1354 1467
1355 1468 mdb_printf("%s%c", name, sep);
1356 1469 }
1357 1470
1358 1471 static int
1359 1472 do_bridge_fwd(uintptr_t addr, const void *data, void *ptr)
1360 1473 {
1361 1474 show_bridge_args_t *args = ptr;
1362 1475 const bridge_fwd_t *bfp = data;
1363 1476 char macaddr[ETHERADDRL * 3];
1364 1477 int i;
1365 1478 #define MAX_FWD_LINKS 16
1366 1479 bridge_link_t *links[MAX_FWD_LINKS];
1367 1480 uint_t nlinks;
1368 1481
1369 1482 args->nfwd++;
1370 1483
1371 1484 if (!args->opt_f)
1372 1485 return (WALK_NEXT);
1373 1486
1374 1487 if ((nlinks = bfp->bf_nlinks) > MAX_FWD_LINKS)
1375 1488 nlinks = MAX_FWD_LINKS;
1376 1489
1377 1490 if (mdb_vread(links, sizeof (links[0]) * nlinks,
1378 1491 (uintptr_t)bfp->bf_links) == -1) {
1379 1492 mdb_warn("cannot read bridge forwarding links at %p",
1380 1493 bfp->bf_links);
1381 1494 return (WALK_ERR);
1382 1495 }
1383 1496
1384 1497 mdb_mac_addr(bfp->bf_dest, ETHERADDRL, macaddr, sizeof (macaddr));
1385 1498
1386 1499 mdb_printf("%-?p %-17s ", addr, macaddr);
1387 1500 if (bfp->bf_flags & BFF_LOCALADDR)
1388 1501 mdb_printf("%-7s", "[self]");
1389 1502 else
1390 1503 mdb_printf("t-%-5d", args->lbolt - bfp->bf_lastheard);
1391 1504 mdb_printf(" %-7u ", bfp->bf_refs);
1392 1505
1393 1506 if (bfp->bf_trill_nick != 0) {
1394 1507 mdb_printf("%d\n", bfp->bf_trill_nick);
1395 1508 } else {
1396 1509 for (i = 0; i < bfp->bf_nlinks; i++) {
1397 1510 print_link_name(args, (uintptr_t)links[i],
1398 1511 i == bfp->bf_nlinks - 1 ? '\n' : ' ');
1399 1512 }
1400 1513 }
1401 1514
1402 1515 return (WALK_NEXT);
1403 1516 }
1404 1517
1405 1518 static int
1406 1519 do_show_bridge(uintptr_t addr, const void *data, void *ptr)
1407 1520 {
1408 1521 show_bridge_args_t *args = ptr;
1409 1522 bridge_inst_t bi;
1410 1523 const bridge_inst_t *bip;
1411 1524 trill_node_t tn;
1412 1525 trill_sock_t tsp;
1413 1526 trill_nickinfo_t tni;
1414 1527 char bname[MAXLINKNAMELEN];
1415 1528 char macaddr[ETHERADDRL * 3];
1416 1529 char *cp;
1417 1530 uint_t nnicks;
1418 1531 int i;
1419 1532
1420 1533 if (data != NULL) {
1421 1534 bip = data;
1422 1535 } else {
1423 1536 if (mdb_vread(&bi, sizeof (bi), addr) == -1) {
1424 1537 mdb_warn("cannot read bridge instance at %p", addr);
1425 1538 return (WALK_ERR);
1426 1539 }
1427 1540 bip = &bi;
1428 1541 }
1429 1542
1430 1543 (void) strncpy(bname, bip->bi_name, sizeof (bname) - 1);
1431 1544 bname[MAXLINKNAMELEN - 1] = '\0';
1432 1545 cp = bname + strlen(bname);
1433 1546 if (cp > bname && cp[-1] == '0')
1434 1547 cp[-1] = '\0';
1435 1548
1436 1549 if (args->name != NULL && strcmp(args->name, bname) != 0)
1437 1550 return (WALK_NEXT);
1438 1551
1439 1552 args->found = B_TRUE;
1440 1553 args->nlinks = args->nfwd = 0;
1441 1554
1442 1555 if (args->opt_l) {
1443 1556 mdb_printf("%-?s %-16s %-17s %3s %-4s ", "ADDR", "LINK",
1444 1557 "MAC-ADDR", "FLG", "PVID");
1445 1558 if (bip->bi_trilldata == NULL)
1446 1559 mdb_printf("%-5s %s\n", "STATE", "VLANS");
1447 1560 else
1448 1561 mdb_printf("%s\n", "FWD-VLANS");
1449 1562 }
1450 1563
1451 1564 if (!args->opt_f && !args->opt_t &&
1452 1565 mdb_pwalk("list", do_bridge_links, args,
1453 1566 addr + offsetof(bridge_inst_t, bi_links)) != DCMD_OK)
1454 1567 return (WALK_ERR);
1455 1568
1456 1569 if (args->opt_f)
1457 1570 mdb_printf("%-?s %-17s %-7s %-7s %s\n", "ADDR", "DEST", "TIME",
1458 1571 "REFS", "OUTPUT");
1459 1572
1460 1573 if (!args->opt_l && !args->opt_t &&
1461 1574 mdb_pwalk("avl", do_bridge_fwd, args,
1462 1575 addr + offsetof(bridge_inst_t, bi_fwd)) != DCMD_OK)
1463 1576 return (WALK_ERR);
1464 1577
1465 1578 nnicks = 0;
1466 1579 if (bip->bi_trilldata != NULL && !args->opt_l && !args->opt_f) {
1467 1580 if (mdb_vread(&args->ti, sizeof (args->ti),
1468 1581 (uintptr_t)bip->bi_trilldata) == -1) {
1469 1582 mdb_warn("cannot read trill instance at %p",
1470 1583 bip->bi_trilldata);
1471 1584 return (WALK_ERR);
1472 1585 }
1473 1586 if (args->opt_t)
1474 1587 mdb_printf("%-?s %-5s %-17s %s\n", "ADDR",
1475 1588 "NICK", "NEXT-HOP", "LINK");
1476 1589 for (i = 0; i < RBRIDGE_NICKNAME_MAX; i++) {
1477 1590 if (args->ti.ti_nodes[i] == NULL)
1478 1591 continue;
1479 1592 if (args->opt_t) {
1480 1593 if (mdb_vread(&tn, sizeof (tn),
1481 1594 (uintptr_t)args->ti.ti_nodes[i]) == -1) {
1482 1595 mdb_warn("cannot read trill node %d at "
1483 1596 "%p", i, args->ti.ti_nodes[i]);
1484 1597 return (WALK_ERR);
1485 1598 }
1486 1599 if (mdb_vread(&tni, sizeof (tni),
1487 1600 (uintptr_t)tn.tn_ni) == -1) {
1488 1601 mdb_warn("cannot read trill node info "
1489 1602 "%d at %p", i, tn.tn_ni);
1490 1603 return (WALK_ERR);
1491 1604 }
1492 1605 mdb_mac_addr(tni.tni_adjsnpa, ETHERADDRL,
1493 1606 macaddr, sizeof (macaddr));
1494 1607 if (tni.tni_nick == args->ti.ti_nick) {
1495 1608 (void) strcpy(macaddr, "[self]");
1496 1609 }
1497 1610 mdb_printf("%-?p %-5u %-17s ",
1498 1611 args->ti.ti_nodes[i], tni.tni_nick,
1499 1612 macaddr);
1500 1613 if (tn.tn_tsp != NULL) {
1501 1614 if (mdb_vread(&tsp, sizeof (tsp),
1502 1615 (uintptr_t)tn.tn_tsp) == -1) {
1503 1616 mdb_warn("cannot read trill "
1504 1617 "socket info at %p",
1505 1618 tn.tn_tsp);
1506 1619 return (WALK_ERR);
1507 1620 }
1508 1621 if (tsp.ts_link != NULL) {
1509 1622 print_link_name(args,
1510 1623 (uintptr_t)tsp.ts_link,
1511 1624 '\n');
1512 1625 continue;
1513 1626 }
1514 1627 }
1515 1628 mdb_printf("--\n");
1516 1629 } else {
1517 1630 nnicks++;
1518 1631 }
1519 1632 }
1520 1633 } else {
1521 1634 if (args->opt_t)
1522 1635 mdb_printf("bridge is not running TRILL\n");
1523 1636 }
1524 1637
1525 1638 if (!args->opt_l && !args->opt_f && !args->opt_t) {
1526 1639 mdb_printf("%-?p %-7s %-16s %-7u %-7u", addr,
1527 1640 bip->bi_trilldata == NULL ? "stp" : "trill", bname,
1528 1641 args->nlinks, args->nfwd);
1529 1642 if (bip->bi_trilldata != NULL)
1530 1643 mdb_printf(" %-7u %u\n", nnicks, args->ti.ti_nick);
1531 1644 else
1532 1645 mdb_printf(" %-7s %s\n", "--", "--");
1533 1646 }
1534 1647 return (WALK_NEXT);
1535 1648 }
1536 1649
1537 1650 static int
1538 1651 dladm_show_bridge(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1539 1652 {
1540 1653 show_bridge_args_t *args;
1541 1654 GElf_Sym sym;
1542 1655 int i;
1543 1656
1544 1657 args = mdb_zalloc(sizeof (*args), UM_SLEEP);
1545 1658
1546 1659 i = mdb_getopts(argc, argv,
1547 1660 'l', MDB_OPT_SETBITS, 1, &args->opt_l,
1548 1661 'f', MDB_OPT_SETBITS, 1, &args->opt_f,
1549 1662 't', MDB_OPT_SETBITS, 1, &args->opt_t,
1550 1663 NULL);
1551 1664
1552 1665 argc -= i;
1553 1666 argv += i;
1554 1667
1555 1668 if (argc > 1 || (argc == 1 && argv[0].a_type != MDB_TYPE_STRING)) {
1556 1669 mdb_free(args, sizeof (*args));
1557 1670 return (DCMD_USAGE);
1558 1671 }
1559 1672 if (argc == 1)
1560 1673 args->name = argv[0].a_un.a_str;
1561 1674
1562 1675 if ((args->lbolt = mdb_get_lbolt()) == -1) {
1563 1676 mdb_warn("failed to read lbolt");
1564 1677 goto err;
1565 1678 }
1566 1679
1567 1680 if (flags & DCMD_ADDRSPEC) {
1568 1681 if (args->name != NULL) {
1569 1682 mdb_printf("bridge name and address are mutually "
1570 1683 "exclusive\n");
1571 1684 goto err;
1572 1685 }
1573 1686 if (!args->opt_l && !args->opt_f && !args->opt_t)
1574 1687 mdb_printf("%-?s %-7s %-16s %-7s %-7s\n", "ADDR",
1575 1688 "PROTECT", "NAME", "NLINKS", "NFWD");
1576 1689 if (do_show_bridge(addr, NULL, args) != WALK_NEXT)
1577 1690 goto err;
1578 1691 mdb_free(args, sizeof (*args));
1579 1692 return (DCMD_OK);
1580 1693 } else {
1581 1694 if ((args->opt_l || args->opt_f || args->opt_t) &&
1582 1695 args->name == NULL) {
1583 1696 mdb_printf("need bridge name or address with -[lft]\n");
1584 1697 goto err;
1585 1698 }
1586 1699 if (mdb_lookup_by_obj("bridge", "inst_list", &sym) == -1) {
1587 1700 mdb_warn("failed to find 'bridge`inst_list'");
1588 1701 goto err;
1589 1702 }
1590 1703 if (!args->opt_l && !args->opt_f && !args->opt_t)
1591 1704 mdb_printf("%-?s %-7s %-16s %-7s %-7s %-7s %s\n",
1592 1705 "ADDR", "PROTECT", "NAME", "NLINKS", "NFWD",
1593 1706 "NNICKS", "NICK");
1594 1707 if (mdb_pwalk("list", do_show_bridge, args,
1595 1708 (uintptr_t)sym.st_value) != DCMD_OK)
1596 1709 goto err;
1597 1710 if (!args->found && args->name != NULL) {
1598 1711 mdb_printf("bridge instance %s not found\n",
1599 1712 args->name);
1600 1713 goto err;
1601 1714 }
1602 1715 mdb_free(args, sizeof (*args));
1603 1716 return (DCMD_OK);
1604 1717 }
1605 1718
1606 1719 err:
1607 1720 mdb_free(args, sizeof (*args));
1608 1721 return (DCMD_ERR);
1609 1722 }
1610 1723
1611 1724 /*
1612 1725 * Support for the "::dladm" dcmd
1613 1726 */
1614 1727 int
1615 1728 dladm(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1616 1729 {
1617 1730 if (argc < 1 || argv[0].a_type != MDB_TYPE_STRING)
1618 1731 return (DCMD_USAGE);
1619 1732
1620 1733 /*
1621 1734 * This could be a bit more elaborate, once we support more of the
1622 1735 * dladm show-* subcommands.
1623 1736 */
1624 1737 argc--;
1625 1738 argv++;
1626 1739 if (strcmp(argv[-1].a_un.a_str, "show-bridge") == 0)
1627 1740 return (dladm_show_bridge(addr, flags, argc, argv));
1628 1741
1629 1742 return (DCMD_USAGE);
1630 1743 }
1631 1744
1632 1745 void
1633 1746 dladm_help(void)
1634 1747 {
1635 1748 mdb_printf("Subcommands:\n"
1636 1749 " show-bridge [-flt] [<name>]\n"
1637 1750 "\t Show bridge information; -l for links and -f for "
1638 1751 "forwarding\n"
1639 1752 "\t entries, and -t for TRILL nicknames. Address is required "
1640 1753 "if name\n"
1641 1754 "\t is not specified.\n");
1642 1755 }
↓ open down ↓ |
414 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX