4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
26 #include <sys/types.h>
27 #include <sys/stropts.h>
28 #include <sys/stream.h>
29 #include <sys/socket.h>
30 #include <sys/avl_impl.h>
31 #include <net/if_types.h>
33 #include <net/route.h>
34 #include <netinet/in.h>
35 #include <netinet/ip6.h>
36 #include <netinet/udp.h>
37 #include <netinet/sctp.h>
38 #include <inet/mib2.h>
39 #include <inet/common.h>
41 #include <inet/ip_ire.h>
43 #include <inet/ipclassifier.h>
45 #include <sys/squeue_impl.h>
46 #include <sys/modhash_impl.h>
47 #include <inet/ip_ndp.h>
48 #include <inet/ip_if.h>
50 #include <ilb/ilb_impl.h>
51 #include <ilb/ilb_stack.h>
52 #include <ilb/ilb_nat.h>
53 #include <ilb/ilb_conn.h>
57 #include <mdb/mdb_modapi.h>
58 #include <mdb/mdb_ks.h>
61 #define L2MAXADDRSTRLEN 255
62 #define MAX_SAP_LEN 255
66 const char *bit_name
; /* name of bit */
67 const char *bit_descr
; /* description of bit's purpose */
70 static const bitname_t squeue_states
[] = {
71 { "SQS_PROC", "being processed" },
72 { "SQS_WORKER", "... by a worker thread" },
73 { "SQS_ENTER", "... by an squeue_enter() thread" },
74 { "SQS_FAST", "... in fast-path mode" },
75 { "SQS_USER", "A non interrupt user" },
76 { "SQS_BOUND", "worker thread bound to CPU" },
77 { "SQS_PROFILE", "profiling enabled" },
78 { "SQS_REENTER", "re-entered thred" },
82 typedef struct illif_walk_data
{
83 ill_g_head_t ill_g_heads
[MAX_G_HEADS
];
88 typedef struct ncec_walk_data_s
{
89 struct ndp_g_s ncec_ip_ndp
;
90 int ncec_hash_tbl_index
;
94 typedef struct ncec_cbdata_s
{
99 typedef struct nce_cbdata_s
{
101 char nce_ill_name
[LIFNAMSIZ
];
104 typedef struct ire_cbdata_s
{
109 typedef struct zi_cbdata_s
{
110 const char *zone_name
;
112 boolean_t shared_ip_zone
;
115 typedef struct th_walk_data
{
116 uint_t thw_non_zero_only
;
118 uintptr_t thw_matchkey
;
123 typedef struct ipcl_hash_walk_data_s
{
128 } ipcl_hash_walk_data_t
;
130 typedef struct ill_walk_data_s
{
134 typedef struct ill_cbdata_s
{
137 ip_stack_t
*ill_ipst
;
141 typedef struct ipif_walk_data_s
{
145 typedef struct ipif_cbdata_s
{
151 typedef struct hash_walk_arg_s
{
156 static hash_walk_arg_t udp_hash_arg
= {
157 OFFSETOF(ip_stack_t
, ips_ipcl_udp_fanout
),
158 OFFSETOF(ip_stack_t
, ips_ipcl_udp_fanout_size
)
161 static hash_walk_arg_t conn_hash_arg
= {
162 OFFSETOF(ip_stack_t
, ips_ipcl_conn_fanout
),
163 OFFSETOF(ip_stack_t
, ips_ipcl_conn_fanout_size
)
166 static hash_walk_arg_t bind_hash_arg
= {
167 OFFSETOF(ip_stack_t
, ips_ipcl_bind_fanout
),
168 OFFSETOF(ip_stack_t
, ips_ipcl_bind_fanout_size
)
171 static hash_walk_arg_t proto_hash_arg
= {
172 OFFSETOF(ip_stack_t
, ips_ipcl_proto_fanout_v4
),
176 static hash_walk_arg_t proto_v6_hash_arg
= {
177 OFFSETOF(ip_stack_t
, ips_ipcl_proto_fanout_v6
),
181 typedef struct ip_list_walk_data_s
{
183 } ip_list_walk_data_t
;
185 typedef struct ip_list_walk_arg_s
{
189 } ip_list_walk_arg_t
;
191 static ip_list_walk_arg_t ipif_walk_arg
= {
192 OFFSETOF(ill_t
, ill_ipif
),
194 OFFSETOF(ipif_t
, ipif_next
)
197 static ip_list_walk_arg_t srcid_walk_arg
= {
198 OFFSETOF(ip_stack_t
, ips_srcid_head
),
199 sizeof (srcid_map_t
),
200 OFFSETOF(srcid_map_t
, sm_next
)
203 static int iphdr(uintptr_t, uint_t
, int, const mdb_arg_t
*);
204 static int ip6hdr(uintptr_t, uint_t
, int, const mdb_arg_t
*);
206 static int ill(uintptr_t, uint_t
, int, const mdb_arg_t
*);
207 static void ill_help(void);
208 static int ill_walk_init(mdb_walk_state_t
*);
209 static int ill_walk_step(mdb_walk_state_t
*);
210 static int ill_format(uintptr_t, const void *, void *);
211 static void ill_header(boolean_t
);
213 static int ipif(uintptr_t, uint_t
, int, const mdb_arg_t
*);
214 static void ipif_help(void);
215 static int ipif_walk_init(mdb_walk_state_t
*);
216 static int ipif_walk_step(mdb_walk_state_t
*);
217 static int ipif_format(uintptr_t, const void *, void *);
218 static void ipif_header(boolean_t
);
220 static int ip_list_walk_init(mdb_walk_state_t
*);
221 static int ip_list_walk_step(mdb_walk_state_t
*);
222 static void ip_list_walk_fini(mdb_walk_state_t
*);
223 static int srcid_walk_step(mdb_walk_state_t
*);
225 static int ire_format(uintptr_t addr
, const void *, void *);
226 static int ncec_format(uintptr_t addr
, const ncec_t
*ncec
, int ipversion
);
227 static int ncec(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
);
228 static int ncec_walk_step(mdb_walk_state_t
*wsp
);
229 static int ncec_stack_walk_init(mdb_walk_state_t
*wsp
);
230 static int ncec_stack_walk_step(mdb_walk_state_t
*wsp
);
231 static void ncec_stack_walk_fini(mdb_walk_state_t
*wsp
);
232 static int ncec_cb(uintptr_t addr
, const ncec_walk_data_t
*iw
,
234 static char *nce_l2_addr(const nce_t
*, const ill_t
*);
236 static int ipcl_hash_walk_init(mdb_walk_state_t
*);
237 static int ipcl_hash_walk_step(mdb_walk_state_t
*);
238 static void ipcl_hash_walk_fini(mdb_walk_state_t
*);
240 static int conn_status_walk_step(mdb_walk_state_t
*);
241 static int conn_status(uintptr_t, uint_t
, int, const mdb_arg_t
*);
242 static void conn_status_help(void);
244 static int srcid_status(uintptr_t, uint_t
, int, const mdb_arg_t
*);
246 static int ilb_stacks_walk_step(mdb_walk_state_t
*);
247 static int ilb_rules_walk_init(mdb_walk_state_t
*);
248 static int ilb_rules_walk_step(mdb_walk_state_t
*);
249 static int ilb_servers_walk_init(mdb_walk_state_t
*);
250 static int ilb_servers_walk_step(mdb_walk_state_t
*);
251 static int ilb_nat_src_walk_init(mdb_walk_state_t
*);
252 static int ilb_nat_src_walk_step(mdb_walk_state_t
*);
253 static int ilb_conn_walk_init(mdb_walk_state_t
*);
254 static int ilb_conn_walk_step(mdb_walk_state_t
*);
255 static int ilb_sticky_walk_init(mdb_walk_state_t
*);
256 static int ilb_sticky_walk_step(mdb_walk_state_t
*);
257 static void ilb_common_walk_fini(mdb_walk_state_t
*);
260 * Given the kernel address of an ip_stack_t, return the stackid
263 ips_to_stackid(uintptr_t kaddr
)
268 if (mdb_vread(&ipss
, sizeof (ipss
), kaddr
) == -1) {
269 mdb_warn("failed to read ip_stack_t %p", kaddr
);
272 kaddr
= (uintptr_t)ipss
.ips_netstack
;
273 if (mdb_vread(&nss
, sizeof (nss
), kaddr
) == -1) {
274 mdb_warn("failed to read netstack_t %p", kaddr
);
277 return (nss
.netstack_stackid
);
282 zone_to_ips_cb(uintptr_t addr
, const void *zi_arg
, void *zi_cb_arg
)
284 zi_cbdata_t
*zi_cb
= zi_cb_arg
;
286 char zone_name
[ZONENAME_MAX
];
289 if (mdb_vread(&zone
, sizeof (zone_t
), addr
) == -1) {
290 mdb_warn("can't read zone at %p", addr
);
294 (void) mdb_readstr(zone_name
, ZONENAME_MAX
, (uintptr_t)zone
.zone_name
);
296 if (strcmp(zi_cb
->zone_name
, zone_name
) != 0)
299 zi_cb
->shared_ip_zone
= (!(zone
.zone_flags
& ZF_NET_EXCL
) &&
300 (strcmp(zone_name
, "global") != 0));
302 if (mdb_vread(&ns
, sizeof (netstack_t
), (uintptr_t)zone
.zone_netstack
)
304 mdb_warn("can't read netstack at %p", zone
.zone_netstack
);
308 zi_cb
->ipst
= ns
.netstack_ip
;
313 zone_to_ips(const char *zone_name
)
317 if (zone_name
== NULL
)
320 zi_cb
.zone_name
= zone_name
;
322 zi_cb
.shared_ip_zone
= B_FALSE
;
324 if (mdb_walk("zone", (mdb_walk_cb_t
)zone_to_ips_cb
, &zi_cb
) == -1) {
325 mdb_warn("failed to walk zone");
329 if (zi_cb
.shared_ip_zone
) {
330 mdb_warn("%s is a Shared-IP zone, try '-s global' instead\n",
335 if (zi_cb
.ipst
== NULL
) {
336 mdb_warn("failed to find zone %s\n", zone_name
);
344 * Generic network stack walker initialization function. It is used by all
345 * other netwrok stack walkers.
348 ns_walk_init(mdb_walk_state_t
*wsp
)
350 if (mdb_layered_walk("netstack", wsp
) == -1) {
351 mdb_warn("can't walk 'netstack'");
358 * Generic network stack walker stepping function. It is used by all other
359 * network stack walkers. The which parameter differentiates the different
363 ns_walk_step(mdb_walk_state_t
*wsp
, int which
)
368 if (mdb_vread(&nss
, sizeof (nss
), wsp
->walk_addr
) == -1) {
369 mdb_warn("can't read netstack at %p", wsp
->walk_addr
);
372 kaddr
= (uintptr_t)nss
.netstack_modules
[which
];
374 return (wsp
->walk_callback(kaddr
, wsp
->walk_layer
, wsp
->walk_cbdata
));
378 * IP network stack walker stepping function.
381 ip_stacks_walk_step(mdb_walk_state_t
*wsp
)
383 return (ns_walk_step(wsp
, NS_IP
));
387 * TCP network stack walker stepping function.
390 tcp_stacks_walk_step(mdb_walk_state_t
*wsp
)
392 return (ns_walk_step(wsp
, NS_TCP
));
396 * SCTP network stack walker stepping function.
399 sctp_stacks_walk_step(mdb_walk_state_t
*wsp
)
401 return (ns_walk_step(wsp
, NS_SCTP
));
405 * UDP network stack walker stepping function.
408 udp_stacks_walk_step(mdb_walk_state_t
*wsp
)
410 return (ns_walk_step(wsp
, NS_UDP
));
414 * Initialization function for the per CPU TCP stats counter walker of a given
418 tcps_sc_walk_init(mdb_walk_state_t
*wsp
)
422 if (wsp
->walk_addr
== (uintptr_t)NULL
)
425 if (mdb_vread(&tcps
, sizeof (tcps
), wsp
->walk_addr
) == -1) {
426 mdb_warn("failed to read tcp_stack_t at %p", wsp
->walk_addr
);
429 if (tcps
.tcps_sc_cnt
== 0)
433 * Store the tcp_stack_t pointer in walk_data. The stepping function
434 * used it to calculate if the end of the counter has reached.
436 wsp
->walk_data
= (void *)wsp
->walk_addr
;
437 wsp
->walk_addr
= (uintptr_t)tcps
.tcps_sc
;
442 * Stepping function for the per CPU TCP stats counterwalker.
445 tcps_sc_walk_step(mdb_walk_state_t
*wsp
)
449 tcp_stats_cpu_t
*stats
;
452 if (mdb_vread(&tcps
, sizeof (tcps
), (uintptr_t)wsp
->walk_data
) == -1) {
453 mdb_warn("failed to read tcp_stack_t at %p", wsp
->walk_addr
);
456 if (mdb_vread(&stats
, sizeof (stats
), wsp
->walk_addr
) == -1) {
457 mdb_warn("failed ot read tcp_stats_cpu_t at %p",
461 status
= wsp
->walk_callback((uintptr_t)stats
, &stats
, wsp
->walk_cbdata
);
462 if (status
!= WALK_NEXT
)
465 next
= (char *)wsp
->walk_addr
+ sizeof (tcp_stats_cpu_t
*);
466 end
= (char *)tcps
.tcps_sc
+ tcps
.tcps_sc_cnt
*
467 sizeof (tcp_stats_cpu_t
*);
470 wsp
->walk_addr
= (uintptr_t)next
;
475 th_hash_walk_init(mdb_walk_state_t
*wsp
)
480 if (wsp
->walk_addr
== (uintptr_t)NULL
) {
481 if (mdb_lookup_by_obj("ip", "ip_thread_list", &sym
) == 0) {
482 wsp
->walk_addr
= sym
.st_value
;
484 mdb_warn("unable to locate ip_thread_list\n");
489 if (mdb_vread(&next
, sizeof (next
),
490 wsp
->walk_addr
+ offsetof(list_t
, list_head
) +
491 offsetof(list_node_t
, list_next
)) == -1 ||
493 mdb_warn("non-DEBUG image; cannot walk th_hash list\n");
497 if (mdb_layered_walk("list", wsp
) == -1) {
498 mdb_warn("can't walk 'list'");
506 th_hash_walk_step(mdb_walk_state_t
*wsp
)
508 return (wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_layer
,
513 * Called with walk_addr being the address of ips_ill_g_heads
516 illif_stack_walk_init(mdb_walk_state_t
*wsp
)
518 illif_walk_data_t
*iw
;
520 if (wsp
->walk_addr
== (uintptr_t)NULL
) {
521 mdb_warn("illif_stack supports only local walks\n");
525 iw
= mdb_alloc(sizeof (illif_walk_data_t
), UM_SLEEP
);
527 if (mdb_vread(iw
->ill_g_heads
, MAX_G_HEADS
* sizeof (ill_g_head_t
),
528 wsp
->walk_addr
) == -1) {
529 mdb_warn("failed to read 'ips_ill_g_heads' at %p",
531 mdb_free(iw
, sizeof (illif_walk_data_t
));
536 wsp
->walk_addr
= (uintptr_t)iw
->ill_g_heads
[0].ill_g_list_head
;
543 illif_stack_walk_step(mdb_walk_state_t
*wsp
)
545 uintptr_t addr
= wsp
->walk_addr
;
546 illif_walk_data_t
*iw
= wsp
->walk_data
;
547 int list
= iw
->ill_list
;
549 if (mdb_vread(&iw
->ill_if
, sizeof (ill_if_t
), addr
) == -1) {
550 mdb_warn("failed to read ill_if_t at %p", addr
);
554 wsp
->walk_addr
= (uintptr_t)iw
->ill_if
.illif_next
;
556 if (wsp
->walk_addr
==
557 (uintptr_t)iw
->ill_g_heads
[list
].ill_g_list_head
) {
559 if (++list
>= MAX_G_HEADS
)
564 (uintptr_t)iw
->ill_g_heads
[list
].ill_g_list_head
;
568 return (wsp
->walk_callback(addr
, iw
, wsp
->walk_cbdata
));
572 illif_stack_walk_fini(mdb_walk_state_t
*wsp
)
574 mdb_free(wsp
->walk_data
, sizeof (illif_walk_data_t
));
577 typedef struct illif_cbdata
{
580 int ill_printlist
; /* list to be printed (MAX_G_HEADS for all) */
581 boolean_t ill_printed
;
585 illif_cb(uintptr_t addr
, const illif_walk_data_t
*iw
, illif_cbdata_t
*id
)
589 if (id
->ill_printlist
< MAX_G_HEADS
&&
590 id
->ill_printlist
!= iw
->ill_list
)
593 if (id
->ill_flags
& DCMD_ADDRSPEC
&& id
->ill_addr
!= addr
)
596 if (id
->ill_flags
& DCMD_PIPE_OUT
) {
597 mdb_printf("%p\n", addr
);
601 switch (iw
->ill_list
) {
602 case IP_V4_G_HEAD
: version
= "v4"; break;
603 case IP_V6_G_HEAD
: version
= "v6"; break;
604 default: version
= "??"; break;
607 mdb_printf("%?p %2s %?p %10d %?p %s\n",
608 addr
, version
, addr
+ offsetof(ill_if_t
, illif_avl_by_ppa
),
609 iw
->ill_if
.illif_avl_by_ppa
.avl_numnodes
,
610 iw
->ill_if
.illif_ppa_arena
, iw
->ill_if
.illif_name
);
612 id
->ill_printed
= TRUE
;
618 ip_stacks_common_walk_init(mdb_walk_state_t
*wsp
)
620 if (mdb_layered_walk("ip_stacks", wsp
) == -1) {
621 mdb_warn("can't walk 'ip_stacks'");
629 illif_walk_step(mdb_walk_state_t
*wsp
)
633 kaddr
= wsp
->walk_addr
+ OFFSETOF(ip_stack_t
, ips_ill_g_heads
);
635 if (mdb_vread(&kaddr
, sizeof (kaddr
), kaddr
) == -1) {
636 mdb_warn("can't read ips_ip_cache_table at %p", kaddr
);
640 if (mdb_pwalk("illif_stack", wsp
->walk_callback
,
641 wsp
->walk_cbdata
, kaddr
) == -1) {
642 mdb_warn("couldn't walk 'illif_stack' for ips_ill_g_heads %p",
650 illif(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
654 const char *opt_P
= NULL
;
655 int printlist
= MAX_G_HEADS
;
657 if (mdb_getopts(argc
, argv
,
658 'P', MDB_OPT_STR
, &opt_P
, NULL
) != argc
)
662 if (strcmp("v4", opt_P
) == 0) {
663 printlist
= IP_V4_G_HEAD
;
664 } else if (strcmp("v6", opt_P
) == 0) {
665 printlist
= IP_V6_G_HEAD
;
667 mdb_warn("invalid protocol '%s'\n", opt_P
);
672 if (DCMD_HDRSPEC(flags
) && (flags
& DCMD_PIPE_OUT
) == 0) {
673 mdb_printf("%<u>%?s %2s %?s %10s %?s %-10s%</u>\n",
674 "ADDR", "IP", "AVLADDR", "NUMNODES", "ARENA", "NAME");
677 id
.ill_flags
= flags
;
679 id
.ill_printlist
= printlist
;
680 id
.ill_printed
= FALSE
;
682 if (mdb_walk("illif", (mdb_walk_cb_t
)illif_cb
, &id
) == -1) {
683 mdb_warn("can't walk ill_if_t structures");
687 if (!(flags
& DCMD_ADDRSPEC
) || opt_P
!= NULL
|| id
.ill_printed
)
691 * If an address is specified and the walk doesn't find it,
694 if (mdb_vread(&ill_if
, sizeof (ill_if_t
), addr
) == -1) {
695 mdb_warn("failed to read ill_if_t at %p", addr
);
699 mdb_printf("%?p %2s %?p %10d %?p %s\n",
700 addr
, "??", addr
+ offsetof(ill_if_t
, illif_avl_by_ppa
),
701 ill_if
.illif_avl_by_ppa
.avl_numnodes
,
702 ill_if
.illif_ppa_arena
, ill_if
.illif_name
);
710 mdb_printf("Options:\n");
711 mdb_printf("\t-P v4 | v6"
712 "\tfilter interface structures for the specified protocol\n");
716 nce_walk_init(mdb_walk_state_t
*wsp
)
718 if (mdb_layered_walk("nce_cache", wsp
) == -1) {
719 mdb_warn("can't walk 'nce_cache'");
727 nce_walk_step(mdb_walk_state_t
*wsp
)
731 if (mdb_vread(&nce
, sizeof (nce
), wsp
->walk_addr
) == -1) {
732 mdb_warn("can't read nce at %p", wsp
->walk_addr
);
736 return (wsp
->walk_callback(wsp
->walk_addr
, &nce
, wsp
->walk_cbdata
));
740 nce_format(uintptr_t addr
, const nce_t
*ncep
, void *nce_cb_arg
)
742 nce_cbdata_t
*nce_cb
= nce_cb_arg
;
744 char ill_name
[LIFNAMSIZ
];
747 if (mdb_vread(&ncec
, sizeof (ncec
),
748 (uintptr_t)ncep
->nce_common
) == -1) {
749 mdb_warn("can't read ncec at %p", ncep
->nce_common
);
752 if (nce_cb
->nce_ipversion
!= 0 &&
753 ncec
.ncec_ipversion
!= nce_cb
->nce_ipversion
)
756 if (mdb_vread(&ill
, sizeof (ill
), (uintptr_t)ncep
->nce_ill
) == -1) {
757 mdb_snprintf(ill_name
, sizeof (ill_name
), "--");
759 (void) mdb_readstr(ill_name
,
760 MIN(LIFNAMSIZ
, ill
.ill_name_length
),
761 (uintptr_t)ill
.ill_name
);
764 if (nce_cb
->nce_ill_name
[0] != '\0' &&
765 strncmp(nce_cb
->nce_ill_name
, ill_name
, LIFNAMSIZ
) != 0)
768 if (ncec
.ncec_ipversion
== IPV6_VERSION
) {
770 mdb_printf("%?p %5s %-18s %?p %6d %N\n",
772 nce_l2_addr(ncep
, &ill
),
778 struct in_addr nceaddr
;
780 IN6_V4MAPPED_TO_INADDR(&ncep
->nce_addr
, &nceaddr
);
781 mdb_printf("%?p %5s %-18s %?p %6d %I\n",
783 nce_l2_addr(ncep
, &ill
),
793 dce_walk_init(mdb_walk_state_t
*wsp
)
795 wsp
->walk_data
= (void *)wsp
->walk_addr
;
797 if (mdb_layered_walk("dce_cache", wsp
) == -1) {
798 mdb_warn("can't walk 'dce_cache'");
806 dce_walk_step(mdb_walk_state_t
*wsp
)
810 if (mdb_vread(&dce
, sizeof (dce
), wsp
->walk_addr
) == -1) {
811 mdb_warn("can't read dce at %p", wsp
->walk_addr
);
815 /* If ip_stack_t is specified, skip DCEs that don't belong to it. */
816 if ((wsp
->walk_data
!= NULL
) && (wsp
->walk_data
!= dce
.dce_ipst
))
819 return (wsp
->walk_callback(wsp
->walk_addr
, &dce
, wsp
->walk_cbdata
));
823 ire_walk_init(mdb_walk_state_t
*wsp
)
825 wsp
->walk_data
= (void *)wsp
->walk_addr
;
827 if (mdb_layered_walk("ire_cache", wsp
) == -1) {
828 mdb_warn("can't walk 'ire_cache'");
836 ire_walk_step(mdb_walk_state_t
*wsp
)
840 if (mdb_vread(&ire
, sizeof (ire
), wsp
->walk_addr
) == -1) {
841 mdb_warn("can't read ire at %p", wsp
->walk_addr
);
845 /* If ip_stack_t is specified, skip IREs that don't belong to it. */
846 if ((wsp
->walk_data
!= NULL
) && (wsp
->walk_data
!= ire
.ire_ipst
))
849 return (wsp
->walk_callback(wsp
->walk_addr
, &ire
, wsp
->walk_cbdata
));
854 ire_next_walk_init(mdb_walk_state_t
*wsp
)
860 ire_next_walk_step(mdb_walk_state_t
*wsp
)
866 if (wsp
->walk_addr
== (uintptr_t)NULL
)
869 if (mdb_vread(&ire
, sizeof (ire
), wsp
->walk_addr
) == -1) {
870 mdb_warn("can't read ire at %p", wsp
->walk_addr
);
873 status
= wsp
->walk_callback(wsp
->walk_addr
, &ire
,
876 if (status
!= WALK_NEXT
)
879 wsp
->walk_addr
= (uintptr_t)ire
.ire_next
;
884 ire_format(uintptr_t addr
, const void *ire_arg
, void *ire_cb_arg
)
886 const ire_t
*irep
= ire_arg
;
887 ire_cbdata_t
*ire_cb
= ire_cb_arg
;
888 boolean_t verbose
= ire_cb
->verbose
;
890 char ill_name
[LIFNAMSIZ
];
891 boolean_t condemned
= irep
->ire_generation
== IRE_GENERATION_CONDEMNED
;
893 static const mdb_bitmask_t tmasks
[] = {
894 { "BROADCAST", IRE_BROADCAST
, IRE_BROADCAST
},
895 { "DEFAULT", IRE_DEFAULT
, IRE_DEFAULT
},
896 { "LOCAL", IRE_LOCAL
, IRE_LOCAL
},
897 { "LOOPBACK", IRE_LOOPBACK
, IRE_LOOPBACK
},
898 { "PREFIX", IRE_PREFIX
, IRE_PREFIX
},
899 { "MULTICAST", IRE_MULTICAST
, IRE_MULTICAST
},
900 { "NOROUTE", IRE_NOROUTE
, IRE_NOROUTE
},
901 { "IF_NORESOLVER", IRE_IF_NORESOLVER
, IRE_IF_NORESOLVER
},
902 { "IF_RESOLVER", IRE_IF_RESOLVER
, IRE_IF_RESOLVER
},
903 { "IF_CLONE", IRE_IF_CLONE
, IRE_IF_CLONE
},
904 { "HOST", IRE_HOST
, IRE_HOST
},
908 static const mdb_bitmask_t fmasks
[] = {
909 { "UP", RTF_UP
, RTF_UP
},
910 { "GATEWAY", RTF_GATEWAY
, RTF_GATEWAY
},
911 { "HOST", RTF_HOST
, RTF_HOST
},
912 { "REJECT", RTF_REJECT
, RTF_REJECT
},
913 { "DYNAMIC", RTF_DYNAMIC
, RTF_DYNAMIC
},
914 { "MODIFIED", RTF_MODIFIED
, RTF_MODIFIED
},
915 { "DONE", RTF_DONE
, RTF_DONE
},
916 { "MASK", RTF_MASK
, RTF_MASK
},
917 { "CLONING", RTF_CLONING
, RTF_CLONING
},
918 { "XRESOLVE", RTF_XRESOLVE
, RTF_XRESOLVE
},
919 { "LLINFO", RTF_LLINFO
, RTF_LLINFO
},
920 { "STATIC", RTF_STATIC
, RTF_STATIC
},
921 { "BLACKHOLE", RTF_BLACKHOLE
, RTF_BLACKHOLE
},
922 { "PRIVATE", RTF_PRIVATE
, RTF_PRIVATE
},
923 { "PROTO2", RTF_PROTO2
, RTF_PROTO2
},
924 { "PROTO1", RTF_PROTO1
, RTF_PROTO1
},
925 { "SETSRC", RTF_SETSRC
, RTF_SETSRC
},
926 { "INDIRECT", RTF_INDIRECT
, RTF_INDIRECT
},
930 if (ire_cb
->ire_ipversion
!= 0 &&
931 irep
->ire_ipversion
!= ire_cb
->ire_ipversion
)
934 if (mdb_vread(&ill
, sizeof (ill
), (uintptr_t)irep
->ire_ill
) == -1) {
935 mdb_snprintf(ill_name
, sizeof (ill_name
), "--");
937 (void) mdb_readstr(ill_name
,
938 MIN(LIFNAMSIZ
, ill
.ill_name_length
),
939 (uintptr_t)ill
.ill_name
);
942 if (irep
->ire_ipversion
== IPV6_VERSION
&& verbose
) {
944 mdb_printf("%<b>%?p%</b>%3s %40N <%hb%s>\n"
946 "%?s %40d %4d <%hb> %s\n",
947 addr
, condemned
? "(C)" : "", &irep
->ire_setsrc_addr_v6
,
948 irep
->ire_type
, tmasks
,
949 (irep
->ire_testhidden
? ", HIDDEN" : ""),
950 "", &irep
->ire_addr_v6
,
951 "", ips_to_stackid((uintptr_t)irep
->ire_ipst
),
953 irep
->ire_flags
, fmasks
, ill_name
);
955 } else if (irep
->ire_ipversion
== IPV6_VERSION
) {
957 mdb_printf("%?p%3s %30N %30N %5d %4d %s\n",
958 addr
, condemned
? "(C)" : "", &irep
->ire_setsrc_addr_v6
,
960 ips_to_stackid((uintptr_t)irep
->ire_ipst
),
961 irep
->ire_zoneid
, ill_name
);
963 } else if (verbose
) {
965 mdb_printf("%<b>%?p%</b>%3s %40I <%hb%s>\n"
967 "%?s %40d %4d <%hb> %s\n",
968 addr
, condemned
? "(C)" : "", irep
->ire_setsrc_addr
,
969 irep
->ire_type
, tmasks
,
970 (irep
->ire_testhidden
? ", HIDDEN" : ""),
972 "", ips_to_stackid((uintptr_t)irep
->ire_ipst
),
973 irep
->ire_zoneid
, irep
->ire_flags
, fmasks
, ill_name
);
977 mdb_printf("%?p%3s %30I %30I %5d %4d %s\n", addr
,
978 condemned
? "(C)" : "", irep
->ire_setsrc_addr
,
979 irep
->ire_addr
, ips_to_stackid((uintptr_t)irep
->ire_ipst
),
980 irep
->ire_zoneid
, ill_name
);
987 * There are faster ways to do this. Given the interactive nature of this
988 * use I don't think its worth much effort.
990 static unsigned short
991 ipcksum(void *p
, int len
)
997 sum
+= *(uint16_t *)p
;
998 p
= (char *)p
+ sizeof (uint16_t);
999 if (sum
& 0x80000000)
1000 sum
= (sum
& 0xFFFF) + (sum
>> 16);
1005 sum
+= (uint16_t)*(unsigned char *)p
;
1008 sum
= (sum
& 0xFFFF) + (sum
>> 16);
1013 static const mdb_bitmask_t tcp_flags
[] = {
1014 { "SYN", TH_SYN
, TH_SYN
},
1015 { "ACK", TH_ACK
, TH_ACK
},
1016 { "FIN", TH_FIN
, TH_FIN
},
1017 { "RST", TH_RST
, TH_RST
},
1018 { "PSH", TH_PUSH
, TH_PUSH
},
1019 { "ECE", TH_ECE
, TH_ECE
},
1020 { "CWR", TH_CWR
, TH_CWR
},
1024 /* TCP option length */
1025 #define TCPOPT_HEADER_LEN 2
1026 #define TCPOPT_MAXSEG_LEN 4
1027 #define TCPOPT_WS_LEN 3
1028 #define TCPOPT_TSTAMP_LEN 10
1029 #define TCPOPT_SACK_OK_LEN 2
1032 tcphdr_print_options(uint8_t *opts
, uint32_t opts_len
)
1037 mdb_printf("%<b>Options:%</b>");
1038 endp
= opts
+ opts_len
;
1039 while (opts
< endp
) {
1052 case TCPOPT_MAXSEG
: {
1055 if (len
< TCPOPT_MAXSEG_LEN
||
1056 opts
[1] != TCPOPT_MAXSEG_LEN
) {
1057 mdb_printf(" <Truncated MSS>\n");
1060 mdb_nhconvert(&mss
, opts
+ TCPOPT_HEADER_LEN
,
1062 mdb_printf(" MSS=%u", mss
);
1063 opts
+= TCPOPT_MAXSEG_LEN
;
1068 if (len
< TCPOPT_WS_LEN
|| opts
[1] != TCPOPT_WS_LEN
) {
1069 mdb_printf(" <Truncated WS>\n");
1072 mdb_printf(" WS=%u", opts
[2]);
1073 opts
+= TCPOPT_WS_LEN
;
1076 case TCPOPT_TSTAMP
: {
1077 if (len
< TCPOPT_TSTAMP_LEN
||
1078 opts
[1] != TCPOPT_TSTAMP_LEN
) {
1079 mdb_printf(" <Truncated TS>\n");
1083 opts
+= TCPOPT_HEADER_LEN
;
1084 mdb_nhconvert(&val
, opts
, sizeof (val
));
1085 mdb_printf(" TS_VAL=%u,", val
);
1087 opts
+= sizeof (val
);
1088 mdb_nhconvert(&val
, opts
, sizeof (val
));
1089 mdb_printf("TS_ECHO=%u", val
);
1091 opts
+= sizeof (val
);
1095 case TCPOPT_SACK_PERMITTED
:
1096 if (len
< TCPOPT_SACK_OK_LEN
||
1097 opts
[1] != TCPOPT_SACK_OK_LEN
) {
1098 mdb_printf(" <Truncated SACK_OK>\n");
1101 mdb_printf(" SACK_OK");
1102 opts
+= TCPOPT_SACK_OK_LEN
;
1108 if (len
<= TCPOPT_HEADER_LEN
|| len
< opts
[1] ||
1109 opts
[1] <= TCPOPT_HEADER_LEN
) {
1110 mdb_printf(" <Truncated SACK>\n");
1113 sack_len
= opts
[1] - TCPOPT_HEADER_LEN
;
1114 opts
+= TCPOPT_HEADER_LEN
;
1116 mdb_printf(" SACK=");
1117 while (sack_len
> 0) {
1118 if (opts
+ 2 * sizeof (val
) > endp
) {
1119 mdb_printf("<Truncated SACK>\n");
1124 mdb_nhconvert(&val
, opts
, sizeof (val
));
1125 mdb_printf("<%u,", val
);
1126 opts
+= sizeof (val
);
1127 mdb_nhconvert(&val
, opts
, sizeof (val
));
1128 mdb_printf("%u>", val
);
1129 opts
+= sizeof (val
);
1131 sack_len
-= 2 * sizeof (val
);
1137 mdb_printf(" Opts=<val=%u,len=%u>", *opts
,
1147 tcphdr_print(struct tcphdr
*tcph
)
1149 in_port_t sport
, dport
;
1153 mdb_printf("%<b>TCP header%</b>\n");
1155 mdb_nhconvert(&sport
, &tcph
->th_sport
, sizeof (sport
));
1156 mdb_nhconvert(&dport
, &tcph
->th_dport
, sizeof (dport
));
1157 mdb_nhconvert(&seq
, &tcph
->th_seq
, sizeof (seq
));
1158 mdb_nhconvert(&ack
, &tcph
->th_ack
, sizeof (ack
));
1159 mdb_nhconvert(&win
, &tcph
->th_win
, sizeof (win
));
1160 mdb_nhconvert(&urp
, &tcph
->th_urp
, sizeof (urp
));
1162 mdb_printf("%<u>%6s %6s %10s %10s %4s %5s %5s %5s %-15s%</u>\n",
1163 "SPORT", "DPORT", "SEQ", "ACK", "HLEN", "WIN", "CSUM", "URP",
1165 mdb_printf("%6hu %6hu %10u %10u %4d %5hu %5hu %5hu <%b>\n",
1166 sport
, dport
, seq
, ack
, tcph
->th_off
<< 2, win
,
1167 tcph
->th_sum
, urp
, tcph
->th_flags
, tcp_flags
);
1168 mdb_printf("0x%04x 0x%04x 0x%08x 0x%08x\n\n",
1169 sport
, dport
, seq
, ack
);
1174 tcphdr(uintptr_t addr
, uint_t flags
, int ac
, const mdb_arg_t
*av
)
1179 if (!(flags
& DCMD_ADDRSPEC
))
1180 return (DCMD_USAGE
);
1182 if (mdb_vread(&tcph
, sizeof (tcph
), addr
) == -1) {
1183 mdb_warn("failed to read TCP header at %p", addr
);
1186 tcphdr_print(&tcph
);
1188 /* If there are options, print them out also. */
1189 opt_len
= (tcph
.th_off
<< 2) - TCP_MIN_HEADER_LENGTH
;
1191 uint8_t *opts
, *opt_buf
;
1193 opt_buf
= mdb_alloc(opt_len
, UM_SLEEP
);
1194 opts
= (uint8_t *)addr
+ sizeof (tcph
);
1195 if (mdb_vread(opt_buf
, opt_len
, (uintptr_t)opts
) == -1) {
1196 mdb_warn("failed to read TCP options at %p", opts
);
1199 tcphdr_print_options(opt_buf
, opt_len
);
1200 mdb_free(opt_buf
, opt_len
);
1207 udphdr_print(struct udphdr
*udph
)
1209 in_port_t sport
, dport
;
1212 mdb_printf("%<b>UDP header%</b>\n");
1214 mdb_nhconvert(&sport
, &udph
->uh_sport
, sizeof (sport
));
1215 mdb_nhconvert(&dport
, &udph
->uh_dport
, sizeof (dport
));
1216 mdb_nhconvert(&hlen
, &udph
->uh_ulen
, sizeof (hlen
));
1218 mdb_printf("%<u>%14s %14s %5s %6s%</u>\n",
1219 "SPORT", "DPORT", "LEN", "CSUM");
1220 mdb_printf("%5hu (0x%04x) %5hu (0x%04x) %5hu 0x%04hx\n\n", sport
, sport
,
1221 dport
, dport
, hlen
, udph
->uh_sum
);
1226 udphdr(uintptr_t addr
, uint_t flags
, int ac
, const mdb_arg_t
*av
)
1230 if (!(flags
& DCMD_ADDRSPEC
))
1231 return (DCMD_USAGE
);
1233 if (mdb_vread(&udph
, sizeof (udph
), addr
) == -1) {
1234 mdb_warn("failed to read UDP header at %p", addr
);
1237 udphdr_print(&udph
);
1242 sctphdr_print(sctp_hdr_t
*sctph
)
1244 in_port_t sport
, dport
;
1246 mdb_printf("%<b>SCTP header%</b>\n");
1247 mdb_nhconvert(&sport
, &sctph
->sh_sport
, sizeof (sport
));
1248 mdb_nhconvert(&dport
, &sctph
->sh_dport
, sizeof (dport
));
1250 mdb_printf("%<u>%14s %14s %10s %10s%</u>\n",
1251 "SPORT", "DPORT", "VTAG", "CHKSUM");
1252 mdb_printf("%5hu (0x%04x) %5hu (0x%04x) %10u 0x%08x\n\n", sport
, sport
,
1253 dport
, dport
, sctph
->sh_verf
, sctph
->sh_chksum
);
1258 sctphdr(uintptr_t addr
, uint_t flags
, int ac
, const mdb_arg_t
*av
)
1262 if (!(flags
& DCMD_ADDRSPEC
))
1263 return (DCMD_USAGE
);
1265 if (mdb_vread(&sctph
, sizeof (sctph
), addr
) == -1) {
1266 mdb_warn("failed to read SCTP header at %p", addr
);
1270 sctphdr_print(&sctph
);
1275 transport_hdr(int proto
, uintptr_t addr
)
1282 if (mdb_vread(&tcph
, sizeof (tcph
), addr
) == -1) {
1283 mdb_warn("failed to read TCP header at %p", addr
);
1286 tcphdr_print(&tcph
);
1292 if (mdb_vread(&udph
, sizeof (udph
), addr
) == -1) {
1293 mdb_warn("failed to read UDP header at %p", addr
);
1296 udphdr_print(&udph
);
1299 case IPPROTO_SCTP
: {
1302 if (mdb_vread(&sctph
, sizeof (sctph
), addr
) == -1) {
1303 mdb_warn("failed to read SCTP header at %p", addr
);
1306 sctphdr_print(&sctph
);
1316 static const mdb_bitmask_t ip_flags
[] = {
1317 { "DF", IPH_DF
, IPH_DF
},
1318 { "MF", IPH_MF
, IPH_MF
},
1324 iphdr(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1326 uint_t verbose
= FALSE
, force
= FALSE
;
1328 uint16_t ver
, totlen
, hdrlen
, ipid
, off
, csum
;
1329 uintptr_t nxt_proto
;
1332 if (mdb_getopts(argc
, argv
,
1333 'v', MDB_OPT_SETBITS
, TRUE
, &verbose
,
1334 'f', MDB_OPT_SETBITS
, TRUE
, &force
, NULL
) != argc
)
1335 return (DCMD_USAGE
);
1337 if (mdb_vread(iph
, sizeof (*iph
), addr
) == -1) {
1338 mdb_warn("failed to read IPv4 header at %p", addr
);
1342 ver
= (iph
->ipha_version_and_hdr_length
& 0xf0) >> 4;
1343 if (ver
!= IPV4_VERSION
) {
1344 if (ver
== IPV6_VERSION
) {
1345 return (ip6hdr(addr
, flags
, argc
, argv
));
1346 } else if (!force
) {
1347 mdb_warn("unknown IP version: %d\n", ver
);
1352 mdb_printf("%<b>IPv4 header%</b>\n");
1353 mdb_printf("%-34s %-34s\n"
1354 "%<u>%-4s %-4s %-5s %-5s %-6s %-5s %-5s %-6s %-8s %-6s%</u>\n",
1356 "HLEN", "TOS", "LEN", "ID", "OFFSET", "TTL", "PROTO", "CHKSUM",
1357 "EXP-CSUM", "FLGS");
1359 hdrlen
= (iph
->ipha_version_and_hdr_length
& 0x0f) << 2;
1360 mdb_nhconvert(&totlen
, &iph
->ipha_length
, sizeof (totlen
));
1361 mdb_nhconvert(&ipid
, &iph
->ipha_ident
, sizeof (ipid
));
1362 mdb_nhconvert(&off
, &iph
->ipha_fragment_offset_and_flags
, sizeof (off
));
1363 if (hdrlen
== IP_SIMPLE_HDR_LENGTH
) {
1364 if ((csum
= ipcksum(iph
, sizeof (*iph
))) != 0)
1365 csum
= ~(~csum
+ ~iph
->ipha_hdr_checksum
);
1367 csum
= iph
->ipha_hdr_checksum
;
1368 mdb_snprintf(exp_csum
, 8, "%u", csum
);
1370 mdb_snprintf(exp_csum
, 8, "<n/a>");
1373 mdb_printf("%-34I %-34I%\n"
1374 "%-4d %-4d %-5hu %-5hu %-6hu %-5hu %-5hu %-6u %-8s <%5hb>\n",
1375 iph
->ipha_src
, iph
->ipha_dst
,
1376 hdrlen
, iph
->ipha_type_of_service
, totlen
, ipid
,
1377 (off
<< 3) & 0xffff, iph
->ipha_ttl
, iph
->ipha_protocol
,
1378 iph
->ipha_hdr_checksum
, exp_csum
, off
, ip_flags
);
1381 nxt_proto
= addr
+ hdrlen
;
1382 return (transport_hdr(iph
->ipha_protocol
, nxt_proto
));
1390 ip6hdr(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1392 uint_t verbose
= FALSE
, force
= FALSE
;
1394 int ver
, class, flow
;
1396 uintptr_t nxt_proto
;
1398 if (mdb_getopts(argc
, argv
,
1399 'v', MDB_OPT_SETBITS
, TRUE
, &verbose
,
1400 'f', MDB_OPT_SETBITS
, TRUE
, &force
, NULL
) != argc
)
1401 return (DCMD_USAGE
);
1403 if (mdb_vread(iph
, sizeof (*iph
), addr
) == -1) {
1404 mdb_warn("failed to read IPv6 header at %p", addr
);
1408 ver
= (iph
->ip6_vfc
& 0xf0) >> 4;
1409 if (ver
!= IPV6_VERSION
) {
1410 if (ver
== IPV4_VERSION
) {
1411 return (iphdr(addr
, flags
, argc
, argv
));
1412 } else if (!force
) {
1413 mdb_warn("unknown IP version: %d\n", ver
);
1418 mdb_printf("%<b>IPv6 header%</b>\n");
1419 mdb_printf("%<u>%-26s %-26s %4s %7s %5s %3s %3s%</u>\n",
1420 "SRC", "DST", "TCLS", "FLOW-ID", "PLEN", "NXT", "HOP");
1422 class = (iph
->ip6_vcf
& IPV6_FLOWINFO_TCLASS
) >> 20;
1423 mdb_nhconvert(&class, &class, sizeof (class));
1424 flow
= iph
->ip6_vcf
& IPV6_FLOWINFO_FLOWLABEL
;
1425 mdb_nhconvert(&flow
, &flow
, sizeof (flow
));
1426 mdb_nhconvert(&plen
, &iph
->ip6_plen
, sizeof (plen
));
1428 mdb_printf("%-26N %-26N %4d %7d %5hu %3d %3d\n",
1429 &iph
->ip6_src
, &iph
->ip6_dst
,
1430 class, flow
, plen
, iph
->ip6_nxt
, iph
->ip6_hlim
);
1433 nxt_proto
= addr
+ sizeof (ip6_t
);
1434 return (transport_hdr(iph
->ip6_nxt
, nxt_proto
));
1441 nce(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1444 nce_cbdata_t nce_cb
;
1446 const char *opt_P
= NULL
, *opt_ill
= NULL
;
1448 if (mdb_getopts(argc
, argv
,
1449 'i', MDB_OPT_STR
, &opt_ill
,
1450 'P', MDB_OPT_STR
, &opt_P
, NULL
) != argc
)
1451 return (DCMD_USAGE
);
1453 if (opt_P
!= NULL
) {
1454 if (strcmp("v4", opt_P
) == 0) {
1455 ipversion
= IPV4_VERSION
;
1456 } else if (strcmp("v6", opt_P
) == 0) {
1457 ipversion
= IPV6_VERSION
;
1459 mdb_warn("invalid protocol '%s'\n", opt_P
);
1460 return (DCMD_USAGE
);
1464 if ((flags
& DCMD_LOOPFIRST
) || !(flags
& DCMD_LOOP
)) {
1465 mdb_printf("%<u>%?s %5s %18s %?s %s %s %</u>\n",
1466 "ADDR", "INTF", "LLADDR", "FP_MP", "REFCNT",
1470 bzero(&nce_cb
, sizeof (nce_cb
));
1471 if (opt_ill
!= NULL
) {
1472 strcpy(nce_cb
.nce_ill_name
, opt_ill
);
1474 nce_cb
.nce_ipversion
= ipversion
;
1476 if (flags
& DCMD_ADDRSPEC
) {
1477 (void) mdb_vread(&nce
, sizeof (nce_t
), addr
);
1478 (void) nce_format(addr
, &nce
, &nce_cb
);
1479 } else if (mdb_walk("nce", (mdb_walk_cb_t
)nce_format
, &nce_cb
) == -1) {
1480 mdb_warn("failed to walk ire table");
1489 dce_format(uintptr_t addr
, const dce_t
*dcep
, void *dce_cb_arg
)
1491 static const mdb_bitmask_t dmasks
[] = {
1492 { "D", DCEF_DEFAULT
, DCEF_DEFAULT
},
1493 { "P", DCEF_PMTU
, DCEF_PMTU
},
1494 { "U", DCEF_UINFO
, DCEF_UINFO
},
1495 { "S", DCEF_TOO_SMALL_PMTU
, DCEF_TOO_SMALL_PMTU
},
1498 char flagsbuf
[2 * A_CNT(dmasks
)];
1499 int ipversion
= *(int *)dce_cb_arg
;
1500 boolean_t condemned
= dcep
->dce_generation
== DCE_GENERATION_CONDEMNED
;
1502 if (ipversion
!= 0 && ipversion
!= dcep
->dce_ipversion
)
1505 mdb_snprintf(flagsbuf
, sizeof (flagsbuf
), "%b", dcep
->dce_flags
,
1508 switch (dcep
->dce_ipversion
) {
1510 mdb_printf("%<u>%?p%3s %8s %8d %30I %</u>\n", addr
, condemned
?
1511 "(C)" : "", flagsbuf
, dcep
->dce_pmtu
, &dcep
->dce_v4addr
);
1514 mdb_printf("%<u>%?p%3s %8s %8d %30N %</u>\n", addr
, condemned
?
1515 "(C)" : "", flagsbuf
, dcep
->dce_pmtu
, &dcep
->dce_v6addr
);
1518 mdb_printf("%<u>%?p%3s %8s %8d %30s %</u>\n", addr
, condemned
?
1519 "(C)" : "", flagsbuf
, dcep
->dce_pmtu
, "");
1526 dce(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1529 const char *opt_P
= NULL
;
1530 const char *zone_name
= NULL
;
1531 ip_stack_t
*ipst
= NULL
;
1534 if (mdb_getopts(argc
, argv
,
1535 's', MDB_OPT_STR
, &zone_name
,
1536 'P', MDB_OPT_STR
, &opt_P
, NULL
) != argc
)
1537 return (DCMD_USAGE
);
1539 /* Follow the specified zone name to find a ip_stack_t*. */
1540 if (zone_name
!= NULL
) {
1541 ipst
= zone_to_ips(zone_name
);
1543 return (DCMD_USAGE
);
1546 if (opt_P
!= NULL
) {
1547 if (strcmp("v4", opt_P
) == 0) {
1548 ipversion
= IPV4_VERSION
;
1549 } else if (strcmp("v6", opt_P
) == 0) {
1550 ipversion
= IPV6_VERSION
;
1552 mdb_warn("invalid protocol '%s'\n", opt_P
);
1553 return (DCMD_USAGE
);
1557 if ((flags
& DCMD_LOOPFIRST
) || !(flags
& DCMD_LOOP
)) {
1558 mdb_printf("%<u>%?s%3s %8s %8s %30s %</u>\n",
1559 "ADDR", "", "FLAGS", "PMTU", "DST_ADDR");
1562 if (flags
& DCMD_ADDRSPEC
) {
1563 (void) mdb_vread(&dce
, sizeof (dce_t
), addr
);
1564 (void) dce_format(addr
, &dce
, &ipversion
);
1565 } else if (mdb_pwalk("dce", (mdb_walk_cb_t
)dce_format
, &ipversion
,
1566 (uintptr_t)ipst
) == -1) {
1567 mdb_warn("failed to walk dce cache");
1575 ire(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1577 uint_t verbose
= FALSE
;
1579 ire_cbdata_t ire_cb
;
1581 const char *opt_P
= NULL
;
1582 const char *zone_name
= NULL
;
1583 ip_stack_t
*ipst
= NULL
;
1585 if (mdb_getopts(argc
, argv
,
1586 'v', MDB_OPT_SETBITS
, TRUE
, &verbose
,
1587 's', MDB_OPT_STR
, &zone_name
,
1588 'P', MDB_OPT_STR
, &opt_P
, NULL
) != argc
)
1589 return (DCMD_USAGE
);
1591 /* Follow the specified zone name to find a ip_stack_t*. */
1592 if (zone_name
!= NULL
) {
1593 ipst
= zone_to_ips(zone_name
);
1595 return (DCMD_USAGE
);
1598 if (opt_P
!= NULL
) {
1599 if (strcmp("v4", opt_P
) == 0) {
1600 ipversion
= IPV4_VERSION
;
1601 } else if (strcmp("v6", opt_P
) == 0) {
1602 ipversion
= IPV6_VERSION
;
1604 mdb_warn("invalid protocol '%s'\n", opt_P
);
1605 return (DCMD_USAGE
);
1609 if ((flags
& DCMD_LOOPFIRST
) || !(flags
& DCMD_LOOP
)) {
1612 mdb_printf("%?s %40s %-20s%\n"
1614 "%<u>%?s %40s %4s %-20s %s%</u>\n",
1615 "ADDR", "SRC", "TYPE",
1617 "", "STACK", "ZONE", "FLAGS", "INTF");
1619 mdb_printf("%<u>%?s %30s %30s %5s %4s %s%</u>\n",
1620 "ADDR", "SRC", "DST", "STACK", "ZONE", "INTF");
1624 ire_cb
.verbose
= (verbose
== TRUE
);
1625 ire_cb
.ire_ipversion
= ipversion
;
1627 if (flags
& DCMD_ADDRSPEC
) {
1628 (void) mdb_vread(&ire
, sizeof (ire_t
), addr
);
1629 (void) ire_format(addr
, &ire
, &ire_cb
);
1630 } else if (mdb_pwalk("ire", (mdb_walk_cb_t
)ire_format
, &ire_cb
,
1631 (uintptr_t)ipst
) == -1) {
1632 mdb_warn("failed to walk ire table");
1640 mi_osize(const queue_t
*q
)
1643 * The code in kernel/net/mi.c allocates an extra word to store the
1644 * size of the allocation. An mi_o_s is thus a size_t plus an mi_o_s.
1651 if (mdb_vread(&m
, sizeof (m
), (uintptr_t)q
->q_ptr
-
1652 sizeof (m
)) == sizeof (m
))
1653 return (m
.mi_nbytes
- sizeof (m
));
1659 ip_ill_qinfo(const queue_t
*q
, char *buf
, size_t nbytes
)
1664 if (mdb_vread(&ill
, sizeof (ill
),
1665 (uintptr_t)q
->q_ptr
) == sizeof (ill
) &&
1666 mdb_readstr(name
, sizeof (name
), (uintptr_t)ill
.ill_name
) > 0)
1667 (void) mdb_snprintf(buf
, nbytes
, "if: %s", name
);
1671 ip_qinfo(const queue_t
*q
, char *buf
, size_t nbytes
)
1673 size_t size
= mi_osize(q
);
1675 if (size
== sizeof (ill_t
))
1676 ip_ill_qinfo(q
, buf
, nbytes
);
1680 ip_rnext(const queue_t
*q
)
1682 size_t size
= mi_osize(q
);
1685 if (size
== sizeof (ill_t
) && mdb_vread(&ill
, sizeof (ill
),
1686 (uintptr_t)q
->q_ptr
) == sizeof (ill
))
1687 return ((uintptr_t)ill
.ill_rq
);
1689 return ((uintptr_t)NULL
);
1693 ip_wnext(const queue_t
*q
)
1695 size_t size
= mi_osize(q
);
1698 if (size
== sizeof (ill_t
) && mdb_vread(&ill
, sizeof (ill
),
1699 (uintptr_t)q
->q_ptr
) == sizeof (ill
))
1700 return ((uintptr_t)ill
.ill_wq
);
1702 return ((uintptr_t)NULL
);
1706 * Print the core fields in an squeue_t. With the "-v" argument,
1707 * provide more verbose output.
1710 squeue(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1713 unsigned int verbose
= FALSE
;
1714 const int SQUEUE_STATEDELT
= (int)(sizeof (uintptr_t) + 9);
1718 if (!(flags
& DCMD_ADDRSPEC
)) {
1719 if (mdb_walk_dcmd("genunix`squeue_cache", "ip`squeue",
1720 argc
, argv
) == -1) {
1721 mdb_warn("failed to walk squeue cache");
1727 if (mdb_getopts(argc
, argv
, 'v', MDB_OPT_SETBITS
, TRUE
, &verbose
, NULL
)
1729 return (DCMD_USAGE
);
1731 if (!DCMD_HDRSPEC(flags
) && verbose
)
1734 if (DCMD_HDRSPEC(flags
) || verbose
) {
1735 mdb_printf("%?s %-5s %-3s %?s %?s %?s\n",
1736 "ADDR", "STATE", "CPU",
1737 "FIRST", "LAST", "WORKER");
1740 if (mdb_vread(&squeue
, sizeof (squeue_t
), addr
) == -1) {
1741 mdb_warn("cannot read squeue_t at %p", addr
);
1745 mdb_printf("%0?p %05x %3d %0?p %0?p %0?p\n",
1746 addr
, squeue
.sq_state
, squeue
.sq_bind
,
1747 squeue
.sq_first
, squeue
.sq_last
, squeue
.sq_worker
);
1753 for (i
= 0; squeue_states
[i
].bit_name
!= NULL
; i
++) {
1754 if (((squeue
.sq_state
) & (1 << i
)) == 0)
1758 mdb_printf("%*s|\n", SQUEUE_STATEDELT
, "");
1759 mdb_printf("%*s+--> ", SQUEUE_STATEDELT
, "");
1762 mdb_printf("%*s ", SQUEUE_STATEDELT
, "");
1764 mdb_printf("%-12s %s\n", squeue_states
[i
].bit_name
,
1765 squeue_states
[i
].bit_descr
);
1772 ip_squeue_help(void)
1774 mdb_printf("Print the core information for a given NCA squeue_t.\n\n");
1775 mdb_printf("Options:\n");
1776 mdb_printf("\t-v\tbe verbose (more descriptive)\n");
1780 * This is called by ::th_trace (via a callback) when walking the th_hash
1781 * list. It calls modent to find the entries.
1785 modent_summary(uintptr_t addr
, const void *data
, void *private)
1787 th_walk_data_t
*thw
= private;
1788 const struct mod_hash_entry
*mhe
= data
;
1791 if (mdb_vread(&th
, sizeof (th
), (uintptr_t)mhe
->mhe_val
) == -1) {
1792 mdb_warn("failed to read th_trace_t %p", mhe
->mhe_val
);
1796 if (th
.th_refcnt
== 0 && thw
->thw_non_zero_only
)
1799 if (!thw
->thw_match
) {
1800 mdb_printf("%?p %?p %?p %8d %?p\n", thw
->thw_ipst
, mhe
->mhe_key
,
1801 mhe
->mhe_val
, th
.th_refcnt
, th
.th_id
);
1802 } else if (thw
->thw_matchkey
== (uintptr_t)mhe
->mhe_key
) {
1806 mdb_printf("Object %p in IP stack %p:\n", mhe
->mhe_key
,
1808 i
= th
.th_trace_lastref
;
1809 mdb_printf("\tThread %p refcnt %d:\n", th
.th_id
,
1811 for (j
= TR_BUF_MAX
; j
> 0; j
--) {
1812 tr
= th
.th_trbuf
+ i
;
1813 if (tr
->tr_depth
== 0 || tr
->tr_depth
> TR_STACK_DEPTH
)
1815 mdb_printf("\t T%+ld:\n", tr
->tr_time
-
1817 for (k
= 0; k
< tr
->tr_depth
; k
++)
1818 mdb_printf("\t\t%a\n", tr
->tr_stack
[k
]);
1827 * This is called by ::th_trace (via a callback) when walking the th_hash
1828 * list. It calls modent to find the entries.
1832 th_hash_summary(uintptr_t addr
, const void *data
, void *private)
1834 const th_hash_t
*thh
= data
;
1835 th_walk_data_t
*thw
= private;
1837 thw
->thw_ipst
= (uintptr_t)thh
->thh_ipst
;
1838 return (mdb_pwalk("modent", modent_summary
, private,
1839 (uintptr_t)thh
->thh_hash
));
1843 * Print or summarize the th_trace_t structures.
1846 th_trace(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1850 (void) memset(&thw
, 0, sizeof (thw
));
1852 if (mdb_getopts(argc
, argv
,
1853 'n', MDB_OPT_SETBITS
, TRUE
, &thw
.thw_non_zero_only
,
1855 return (DCMD_USAGE
);
1857 if (!(flags
& DCMD_ADDRSPEC
)) {
1859 * No address specified. Walk all of the th_hash_t in the
1860 * system, and summarize the th_trace_t entries in each.
1862 mdb_printf("%?s %?s %?s %8s %?s\n",
1863 "IPSTACK", "OBJECT", "TRACE", "REFCNT", "THREAD");
1864 thw
.thw_match
= B_FALSE
;
1866 thw
.thw_match
= B_TRUE
;
1867 thw
.thw_matchkey
= addr
;
1869 if ((thw
.thw_lbolt
= (clock_t)mdb_get_lbolt()) == -1) {
1870 mdb_warn("failed to read lbolt");
1874 if (mdb_pwalk("th_hash", th_hash_summary
, &thw
,
1875 (uintptr_t)NULL
) == -1) {
1876 mdb_warn("can't walk th_hash entries");
1885 mdb_printf("If given an address of an ill_t, ipif_t, ire_t, or ncec_t, "
1887 "corresponding th_trace_t structure in detail. Otherwise, if no "
1889 "given, then summarize all th_trace_t structures.\n\n");
1890 mdb_printf("Options:\n"
1891 "\t-n\tdisplay only entries with non-zero th_refcnt\n");
1894 static const mdb_dcmd_t dcmds
[] = {
1895 { "conn_status", ":",
1896 "display connection structures from ipcl hash tables",
1897 conn_status
, conn_status_help
},
1898 { "srcid_status", ":",
1899 "display connection structures from ipcl hash tables",
1901 { "ill", "?[-v] [-P v4 | v6] [-s exclusive-ip-zone-name]",
1902 "display ill_t structures", ill
, ill_help
},
1903 { "illif", "?[-P v4 | v6]",
1904 "display or filter IP Lower Level InterFace structures", illif
,
1906 { "iphdr", ":[-vf]", "display an IPv4 header", iphdr
},
1907 { "ip6hdr", ":[-vf]", "display an IPv6 header", ip6hdr
},
1908 { "ipif", "?[-v] [-P v4 | v6]", "display ipif structures",
1910 { "ire", "?[-v] [-P v4|v6] [-s exclusive-ip-zone-name]",
1911 "display Internet Route Entry structures", ire
},
1912 { "nce", "?[-P v4|v6] [-i <interface>]",
1913 "display interface-specific Neighbor Cache structures", nce
},
1914 { "ncec", "?[-P v4 | v6]", "display Neighbor Cache Entry structures",
1916 { "dce", "?[-P v4|v6] [-s exclusive-ip-zone-name]",
1917 "display Destination Cache Entry structures", dce
},
1918 { "squeue", ":[-v]", "print core squeue_t info", squeue
,
1920 { "tcphdr", ":", "display a TCP header", tcphdr
},
1921 { "udphdr", ":", "display an UDP header", udphdr
},
1922 { "sctphdr", ":", "display an SCTP header", sctphdr
},
1923 { "th_trace", "?[-n]", "display th_trace_t structures", th_trace
,
1928 static const mdb_walker_t walkers
[] = {
1929 { "conn_status", "walk list of conn_t structures",
1930 ip_stacks_common_walk_init
, conn_status_walk_step
, NULL
},
1931 { "illif", "walk list of ill interface types for all stacks",
1932 ip_stacks_common_walk_init
, illif_walk_step
, NULL
},
1933 { "illif_stack", "walk list of ill interface types",
1934 illif_stack_walk_init
, illif_stack_walk_step
,
1935 illif_stack_walk_fini
},
1936 { "ill", "walk active ill_t structures for all stacks",
1937 ill_walk_init
, ill_walk_step
, NULL
},
1938 { "ipif", "walk list of ipif structures for all stacks",
1939 ipif_walk_init
, ipif_walk_step
, NULL
},
1940 { "ipif_list", "walk the linked list of ipif structures "
1942 ip_list_walk_init
, ip_list_walk_step
,
1943 ip_list_walk_fini
, &ipif_walk_arg
},
1944 { "srcid", "walk list of srcid_map structures for all stacks",
1945 ip_stacks_common_walk_init
, srcid_walk_step
, NULL
},
1946 { "srcid_list", "walk list of srcid_map structures for a stack",
1947 ip_list_walk_init
, ip_list_walk_step
, ip_list_walk_fini
,
1949 { "ire", "walk active ire_t structures",
1950 ire_walk_init
, ire_walk_step
, NULL
},
1951 { "ire_next", "walk ire_t structures in the ctable",
1952 ire_next_walk_init
, ire_next_walk_step
, NULL
},
1953 { "nce", "walk active nce_t structures",
1954 nce_walk_init
, nce_walk_step
, NULL
},
1955 { "dce", "walk active dce_t structures",
1956 dce_walk_init
, dce_walk_step
, NULL
},
1957 { "ip_stacks", "walk all the ip_stack_t",
1958 ns_walk_init
, ip_stacks_walk_step
, NULL
},
1959 { "tcp_stacks", "walk all the tcp_stack_t",
1960 ns_walk_init
, tcp_stacks_walk_step
, NULL
},
1961 { "sctp_stacks", "walk all the sctp_stack_t",
1962 ns_walk_init
, sctp_stacks_walk_step
, NULL
},
1963 { "udp_stacks", "walk all the udp_stack_t",
1964 ns_walk_init
, udp_stacks_walk_step
, NULL
},
1965 { "th_hash", "walk all the th_hash_t entries",
1966 th_hash_walk_init
, th_hash_walk_step
, NULL
},
1967 { "ncec", "walk list of ncec structures for all stacks",
1968 ip_stacks_common_walk_init
, ncec_walk_step
, NULL
},
1969 { "ncec_stack", "walk list of ncec structures",
1970 ncec_stack_walk_init
, ncec_stack_walk_step
,
1971 ncec_stack_walk_fini
},
1972 { "udp_hash", "walk list of conn_t structures in ips_ipcl_udp_fanout",
1973 ipcl_hash_walk_init
, ipcl_hash_walk_step
,
1974 ipcl_hash_walk_fini
, &udp_hash_arg
},
1975 { "conn_hash", "walk list of conn_t structures in ips_ipcl_conn_fanout",
1976 ipcl_hash_walk_init
, ipcl_hash_walk_step
,
1977 ipcl_hash_walk_fini
, &conn_hash_arg
},
1978 { "bind_hash", "walk list of conn_t structures in ips_ipcl_bind_fanout",
1979 ipcl_hash_walk_init
, ipcl_hash_walk_step
,
1980 ipcl_hash_walk_fini
, &bind_hash_arg
},
1981 { "proto_hash", "walk list of conn_t structures in "
1982 "ips_ipcl_proto_fanout",
1983 ipcl_hash_walk_init
, ipcl_hash_walk_step
,
1984 ipcl_hash_walk_fini
, &proto_hash_arg
},
1985 { "proto_v6_hash", "walk list of conn_t structures in "
1986 "ips_ipcl_proto_fanout_v6",
1987 ipcl_hash_walk_init
, ipcl_hash_walk_step
,
1988 ipcl_hash_walk_fini
, &proto_v6_hash_arg
},
1989 { "ilb_stacks", "walk all ilb_stack_t",
1990 ns_walk_init
, ilb_stacks_walk_step
, NULL
},
1991 { "ilb_rules", "walk ilb rules in a given ilb_stack_t",
1992 ilb_rules_walk_init
, ilb_rules_walk_step
, NULL
},
1993 { "ilb_servers", "walk server in a given ilb_rule_t",
1994 ilb_servers_walk_init
, ilb_servers_walk_step
, NULL
},
1995 { "ilb_nat_src", "walk NAT source table of a given ilb_stack_t",
1996 ilb_nat_src_walk_init
, ilb_nat_src_walk_step
,
1997 ilb_common_walk_fini
},
1998 { "ilb_conns", "walk NAT table of a given ilb_stack_t",
1999 ilb_conn_walk_init
, ilb_conn_walk_step
, ilb_common_walk_fini
},
2000 { "ilb_stickys", "walk sticky table of a given ilb_stack_t",
2001 ilb_sticky_walk_init
, ilb_sticky_walk_step
,
2002 ilb_common_walk_fini
},
2003 { "tcps_sc", "walk all the per CPU stats counters of a tcp_stack_t",
2004 tcps_sc_walk_init
, tcps_sc_walk_step
, NULL
},
2008 static const mdb_qops_t ip_qops
= { ip_qinfo
, ip_rnext
, ip_wnext
};
2009 static const mdb_modinfo_t modinfo
= { MDB_API_VERSION
, dcmds
, walkers
};
2011 const mdb_modinfo_t
*
2016 if (mdb_lookup_by_obj("ip", "ipwinit", &sym
) == 0)
2017 mdb_qops_install(&ip_qops
, (uintptr_t)sym
.st_value
);
2027 if (mdb_lookup_by_obj("ip", "ipwinit", &sym
) == 0)
2028 mdb_qops_remove(&ip_qops
, (uintptr_t)sym
.st_value
);
2032 ncec_state(int ncec_state
)
2034 switch (ncec_state
) {
2036 return ("unchanged");
2038 return ("incomplete");
2040 return ("reachable");
2047 case ND_UNREACHABLE
:
2057 ncec_l2_addr(const ncec_t
*ncec
, const ill_t
*ill
)
2060 static char addr_buf
[L2MAXADDRSTRLEN
];
2062 if (ncec
->ncec_lladdr
== NULL
) {
2066 if (ill
->ill_net_type
== IRE_IF_RESOLVER
) {
2068 if (ill
->ill_phys_addr_length
== 0)
2070 h
= mdb_zalloc(ill
->ill_phys_addr_length
, UM_SLEEP
);
2071 if (mdb_vread(h
, ill
->ill_phys_addr_length
,
2072 (uintptr_t)ncec
->ncec_lladdr
) == -1) {
2073 mdb_warn("failed to read hwaddr at %p",
2077 mdb_mac_addr(h
, ill
->ill_phys_addr_length
,
2078 addr_buf
, sizeof (addr_buf
));
2082 mdb_free(h
, ill
->ill_phys_addr_length
);
2087 nce_l2_addr(const nce_t
*nce
, const ill_t
*ill
)
2090 static char addr_buf
[L2MAXADDRSTRLEN
];
2094 if (nce
->nce_dlur_mp
== NULL
)
2097 if (ill
->ill_net_type
== IRE_IF_RESOLVER
) {
2098 if (mdb_vread(&mp
, sizeof (mblk_t
),
2099 (uintptr_t)nce
->nce_dlur_mp
) == -1) {
2100 mdb_warn("failed to read nce_dlur_mp at %p",
2104 if (ill
->ill_phys_addr_length
== 0)
2106 mblen
= mp
.b_wptr
- mp
.b_rptr
;
2107 if (mblen
> (sizeof (dl_unitdata_req_t
) + MAX_SAP_LEN
) ||
2108 ill
->ill_phys_addr_length
> MAX_SAP_LEN
||
2109 (NCE_LL_ADDR_OFFSET(ill
) +
2110 ill
->ill_phys_addr_length
) > mblen
) {
2113 h
= mdb_zalloc(mblen
, UM_SLEEP
);
2114 if (mdb_vread(h
, mblen
, (uintptr_t)(mp
.b_rptr
)) == -1) {
2115 mdb_warn("failed to read hwaddr at %p",
2116 mp
.b_rptr
+ NCE_LL_ADDR_OFFSET(ill
));
2119 mdb_mac_addr(h
+ NCE_LL_ADDR_OFFSET(ill
),
2120 ill
->ill_phys_addr_length
, addr_buf
, sizeof (addr_buf
));
2129 ncec_header(uint_t flags
)
2131 if ((flags
& DCMD_LOOPFIRST
) || !(flags
& DCMD_LOOP
)) {
2133 mdb_printf("%<u>%?s %-20s %-10s %-8s %-5s %s%</u>\n",
2134 "ADDR", "HW_ADDR", "STATE", "FLAGS", "ILL", "IP ADDR");
2139 ncec(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
2144 const char *opt_P
= NULL
;
2146 if (mdb_getopts(argc
, argv
,
2147 'P', MDB_OPT_STR
, &opt_P
, NULL
) != argc
)
2148 return (DCMD_USAGE
);
2150 if (opt_P
!= NULL
) {
2151 if (strcmp("v4", opt_P
) == 0) {
2152 ipversion
= IPV4_VERSION
;
2153 } else if (strcmp("v6", opt_P
) == 0) {
2154 ipversion
= IPV6_VERSION
;
2156 mdb_warn("invalid protocol '%s'\n", opt_P
);
2157 return (DCMD_USAGE
);
2161 if (flags
& DCMD_ADDRSPEC
) {
2163 if (mdb_vread(&ncec
, sizeof (ncec_t
), addr
) == -1) {
2164 mdb_warn("failed to read ncec at %p\n", addr
);
2167 if (ipversion
!= 0 && ncec
.ncec_ipversion
!= ipversion
) {
2168 mdb_printf("IP Version mismatch\n");
2172 return (ncec_format(addr
, &ncec
, ipversion
));
2175 id
.ncec_addr
= addr
;
2176 id
.ncec_ipversion
= ipversion
;
2178 if (mdb_walk("ncec", (mdb_walk_cb_t
)ncec_cb
, &id
) == -1) {
2179 mdb_warn("failed to walk ncec table\n");
2187 ncec_format(uintptr_t addr
, const ncec_t
*ncec
, int ipversion
)
2189 static const mdb_bitmask_t ncec_flags
[] = {
2190 { "P", NCE_F_NONUD
, NCE_F_NONUD
},
2191 { "R", NCE_F_ISROUTER
, NCE_F_ISROUTER
},
2192 { "N", NCE_F_NONUD
, NCE_F_NONUD
},
2193 { "A", NCE_F_ANYCAST
, NCE_F_ANYCAST
},
2194 { "C", NCE_F_CONDEMNED
, NCE_F_CONDEMNED
},
2195 { "U", NCE_F_UNSOL_ADV
, NCE_F_UNSOL_ADV
},
2196 { "B", NCE_F_BCAST
, NCE_F_BCAST
},
2199 #define NCE_MAX_FLAGS (sizeof (ncec_flags) / sizeof (mdb_bitmask_t))
2200 struct in_addr nceaddr
;
2202 char ill_name
[LIFNAMSIZ
];
2203 char flagsbuf
[NCE_MAX_FLAGS
];
2205 if (mdb_vread(&ill
, sizeof (ill
), (uintptr_t)ncec
->ncec_ill
) == -1) {
2206 mdb_warn("failed to read ncec_ill at %p",
2211 (void) mdb_readstr(ill_name
, MIN(LIFNAMSIZ
, ill
.ill_name_length
),
2212 (uintptr_t)ill
.ill_name
);
2214 mdb_snprintf(flagsbuf
, sizeof (flagsbuf
), "%hb",
2215 ncec
->ncec_flags
, ncec_flags
);
2217 if (ipversion
!= 0 && ncec
->ncec_ipversion
!= ipversion
)
2220 if (ncec
->ncec_ipversion
== IPV4_VERSION
) {
2221 IN6_V4MAPPED_TO_INADDR(&ncec
->ncec_addr
, &nceaddr
);
2222 mdb_printf("%?p %-20s %-10s "
2225 addr
, ncec_l2_addr(ncec
, &ill
),
2226 ncec_state(ncec
->ncec_state
),
2228 ill_name
, nceaddr
.s_addr
);
2230 mdb_printf("%?p %-20s %-10s %-8s %-5s %N\n",
2231 addr
, ncec_l2_addr(ncec
, &ill
),
2232 ncec_state(ncec
->ncec_state
),
2234 ill_name
, &ncec
->ncec_addr
);
2241 ncec_get_next_hash_tbl(uintptr_t start
, int *index
, struct ndp_g_s ndp
)
2243 uintptr_t addr
= start
;
2246 while (addr
== (uintptr_t)NULL
) {
2248 if (++i
>= NCE_TABLE_SIZE
)
2250 addr
= (uintptr_t)ndp
.nce_hash_tbl
[i
];
2257 ncec_walk_step(mdb_walk_state_t
*wsp
)
2259 uintptr_t kaddr4
, kaddr6
;
2261 kaddr4
= wsp
->walk_addr
+ OFFSETOF(ip_stack_t
, ips_ndp4
);
2262 kaddr6
= wsp
->walk_addr
+ OFFSETOF(ip_stack_t
, ips_ndp6
);
2264 if (mdb_vread(&kaddr4
, sizeof (kaddr4
), kaddr4
) == -1) {
2265 mdb_warn("can't read ips_ip_cache_table at %p", kaddr4
);
2268 if (mdb_vread(&kaddr6
, sizeof (kaddr6
), kaddr6
) == -1) {
2269 mdb_warn("can't read ips_ip_cache_table at %p", kaddr6
);
2272 if (mdb_pwalk("ncec_stack", wsp
->walk_callback
, wsp
->walk_cbdata
,
2274 mdb_warn("couldn't walk 'ncec_stack' for ips_ndp4 %p",
2278 if (mdb_pwalk("ncec_stack", wsp
->walk_callback
,
2279 wsp
->walk_cbdata
, kaddr6
) == -1) {
2280 mdb_warn("couldn't walk 'ncec_stack' for ips_ndp6 %p",
2288 ipcl_hash_get_next_connf_tbl(ipcl_hash_walk_data_t
*iw
)
2290 struct connf_s connf
;
2291 uintptr_t addr
= (uintptr_t)NULL
, next
;
2292 int index
= iw
->connf_tbl_index
;
2295 next
= iw
->hash_tbl
+ index
* sizeof (struct connf_s
);
2296 if (++index
>= iw
->hash_tbl_size
) {
2297 addr
= (uintptr_t)NULL
;
2300 if (mdb_vread(&connf
, sizeof (struct connf_s
), next
) == -1) {
2301 mdb_warn("failed to read conn_t at %p", next
);
2302 return ((uintptr_t)NULL
);
2304 addr
= (uintptr_t)connf
.connf_head
;
2305 } while (addr
== (uintptr_t)NULL
);
2306 iw
->connf_tbl_index
= index
;
2311 ipcl_hash_walk_init(mdb_walk_state_t
*wsp
)
2313 const hash_walk_arg_t
*arg
= wsp
->walk_arg
;
2314 ipcl_hash_walk_data_t
*iw
;
2318 iw
= mdb_alloc(sizeof (ipcl_hash_walk_data_t
), UM_SLEEP
);
2319 iw
->conn
= mdb_alloc(sizeof (conn_t
), UM_SLEEP
);
2320 tbladdr
= wsp
->walk_addr
+ arg
->tbl_off
;
2321 sizeaddr
= wsp
->walk_addr
+ arg
->size_off
;
2323 if (mdb_vread(&iw
->hash_tbl
, sizeof (uintptr_t), tbladdr
) == -1) {
2324 mdb_warn("can't read fanout table addr at %p", tbladdr
);
2325 mdb_free(iw
->conn
, sizeof (conn_t
));
2326 mdb_free(iw
, sizeof (ipcl_hash_walk_data_t
));
2329 if (arg
->tbl_off
== OFFSETOF(ip_stack_t
, ips_ipcl_proto_fanout_v4
) ||
2330 arg
->tbl_off
== OFFSETOF(ip_stack_t
, ips_ipcl_proto_fanout_v6
)) {
2331 iw
->hash_tbl_size
= IPPROTO_MAX
;
2333 if (mdb_vread(&iw
->hash_tbl_size
, sizeof (int),
2335 mdb_warn("can't read fanout table size addr at %p",
2337 mdb_free(iw
->conn
, sizeof (conn_t
));
2338 mdb_free(iw
, sizeof (ipcl_hash_walk_data_t
));
2342 iw
->connf_tbl_index
= 0;
2343 wsp
->walk_addr
= ipcl_hash_get_next_connf_tbl(iw
);
2344 wsp
->walk_data
= iw
;
2346 if (wsp
->walk_addr
!= (uintptr_t)NULL
)
2353 ipcl_hash_walk_step(mdb_walk_state_t
*wsp
)
2355 uintptr_t addr
= wsp
->walk_addr
;
2356 ipcl_hash_walk_data_t
*iw
= wsp
->walk_data
;
2357 conn_t
*conn
= iw
->conn
;
2358 int ret
= WALK_DONE
;
2360 while (addr
!= (uintptr_t)NULL
) {
2361 if (mdb_vread(conn
, sizeof (conn_t
), addr
) == -1) {
2362 mdb_warn("failed to read conn_t at %p", addr
);
2365 ret
= wsp
->walk_callback(addr
, iw
, wsp
->walk_cbdata
);
2366 if (ret
!= WALK_NEXT
)
2368 addr
= (uintptr_t)conn
->conn_next
;
2370 if (ret
== WALK_NEXT
) {
2371 wsp
->walk_addr
= ipcl_hash_get_next_connf_tbl(iw
);
2373 if (wsp
->walk_addr
!= (uintptr_t)NULL
)
2383 ipcl_hash_walk_fini(mdb_walk_state_t
*wsp
)
2385 ipcl_hash_walk_data_t
*iw
= wsp
->walk_data
;
2387 mdb_free(iw
->conn
, sizeof (conn_t
));
2388 mdb_free(iw
, sizeof (ipcl_hash_walk_data_t
));
2392 * Called with walk_addr being the address of ips_ndp{4,6}
2395 ncec_stack_walk_init(mdb_walk_state_t
*wsp
)
2397 ncec_walk_data_t
*nw
;
2399 if (wsp
->walk_addr
== (uintptr_t)NULL
) {
2400 mdb_warn("ncec_stack requires ndp_g_s address\n");
2404 nw
= mdb_alloc(sizeof (ncec_walk_data_t
), UM_SLEEP
);
2406 if (mdb_vread(&nw
->ncec_ip_ndp
, sizeof (struct ndp_g_s
),
2407 wsp
->walk_addr
) == -1) {
2408 mdb_warn("failed to read 'ip_ndp' at %p",
2410 mdb_free(nw
, sizeof (ncec_walk_data_t
));
2415 * ncec_get_next_hash_tbl() starts at ++i , so initialize index to -1
2417 nw
->ncec_hash_tbl_index
= -1;
2418 wsp
->walk_addr
= ncec_get_next_hash_tbl((uintptr_t)NULL
,
2419 &nw
->ncec_hash_tbl_index
, nw
->ncec_ip_ndp
);
2420 wsp
->walk_data
= nw
;
2426 ncec_stack_walk_step(mdb_walk_state_t
*wsp
)
2428 uintptr_t addr
= wsp
->walk_addr
;
2429 ncec_walk_data_t
*nw
= wsp
->walk_data
;
2431 if (addr
== (uintptr_t)NULL
)
2434 if (mdb_vread(&nw
->ncec
, sizeof (ncec_t
), addr
) == -1) {
2435 mdb_warn("failed to read ncec_t at %p", addr
);
2439 wsp
->walk_addr
= (uintptr_t)nw
->ncec
.ncec_next
;
2441 wsp
->walk_addr
= ncec_get_next_hash_tbl(wsp
->walk_addr
,
2442 &nw
->ncec_hash_tbl_index
, nw
->ncec_ip_ndp
);
2444 return (wsp
->walk_callback(addr
, nw
, wsp
->walk_cbdata
));
2448 ncec_stack_walk_fini(mdb_walk_state_t
*wsp
)
2450 mdb_free(wsp
->walk_data
, sizeof (ncec_walk_data_t
));
2455 ncec_cb(uintptr_t addr
, const ncec_walk_data_t
*iw
, ncec_cbdata_t
*id
)
2459 if (mdb_vread(&ncec
, sizeof (ncec_t
), addr
) == -1) {
2460 mdb_warn("failed to read ncec at %p", addr
);
2463 (void) ncec_format(addr
, &ncec
, id
->ncec_ipversion
);
2468 ill_walk_init(mdb_walk_state_t
*wsp
)
2470 if (mdb_layered_walk("illif", wsp
) == -1) {
2471 mdb_warn("can't walk 'illif'");
2478 ill_walk_step(mdb_walk_state_t
*wsp
)
2482 if (mdb_vread(&ill_if
, sizeof (ill_if_t
), wsp
->walk_addr
) == -1) {
2483 mdb_warn("can't read ill_if_t at %p", wsp
->walk_addr
);
2486 wsp
->walk_addr
= (uintptr_t)(wsp
->walk_addr
+
2487 offsetof(ill_if_t
, illif_avl_by_ppa
));
2488 if (mdb_pwalk("avl", wsp
->walk_callback
, wsp
->walk_cbdata
,
2489 wsp
->walk_addr
) == -1) {
2490 mdb_warn("can't walk 'avl'");
2499 ill_cb(uintptr_t addr
, const ill_walk_data_t
*iw
, ill_cbdata_t
*id
)
2503 if (mdb_vread(&ill
, sizeof (ill_t
), (uintptr_t)addr
) == -1) {
2504 mdb_warn("failed to read ill at %p", addr
);
2508 /* If ip_stack_t is specified, skip ILLs that don't belong to it. */
2509 if (id
->ill_ipst
!= NULL
&& ill
.ill_ipst
!= id
->ill_ipst
)
2512 return (ill_format((uintptr_t)addr
, &ill
, id
));
2516 ill_header(boolean_t verbose
)
2519 mdb_printf("%-?s %-8s %3s %-10s %-?s %-?s %-10s%</u>\n",
2520 "ADDR", "NAME", "VER", "TYPE", "WQ", "IPST", "FLAGS");
2521 mdb_printf("%-?s %4s%4s %-?s\n",
2522 "PHYINT", "CNT", "", "GROUP");
2523 mdb_printf("%<u>%80s%</u>\n", "");
2525 mdb_printf("%<u>%-?s %-8s %-3s %-10s %4s %-?s %-10s%</u>\n",
2526 "ADDR", "NAME", "VER", "TYPE", "CNT", "WQ", "FLAGS");
2531 ill_format(uintptr_t addr
, const void *illptr
, void *ill_cb_arg
)
2533 ill_t
*ill
= (ill_t
*)illptr
;
2534 ill_cbdata_t
*illcb
= ill_cb_arg
;
2535 boolean_t verbose
= illcb
->verbose
;
2537 static const mdb_bitmask_t fmasks
[] = {
2538 { "R", PHYI_RUNNING
, PHYI_RUNNING
},
2539 { "P", PHYI_PROMISC
, PHYI_PROMISC
},
2540 { "V", PHYI_VIRTUAL
, PHYI_VIRTUAL
},
2541 { "I", PHYI_IPMP
, PHYI_IPMP
},
2542 { "f", PHYI_FAILED
, PHYI_FAILED
},
2543 { "S", PHYI_STANDBY
, PHYI_STANDBY
},
2544 { "i", PHYI_INACTIVE
, PHYI_INACTIVE
},
2545 { "O", PHYI_OFFLINE
, PHYI_OFFLINE
},
2546 { "T", ILLF_NOTRAILERS
, ILLF_NOTRAILERS
},
2547 { "A", ILLF_NOARP
, ILLF_NOARP
},
2548 { "M", ILLF_MULTICAST
, ILLF_MULTICAST
},
2549 { "F", ILLF_ROUTER
, ILLF_ROUTER
},
2550 { "D", ILLF_NONUD
, ILLF_NONUD
},
2551 { "X", ILLF_NORTEXCH
, ILLF_NORTEXCH
},
2554 static const mdb_bitmask_t v_fmasks
[] = {
2555 { "RUNNING", PHYI_RUNNING
, PHYI_RUNNING
},
2556 { "PROMISC", PHYI_PROMISC
, PHYI_PROMISC
},
2557 { "VIRTUAL", PHYI_VIRTUAL
, PHYI_VIRTUAL
},
2558 { "IPMP", PHYI_IPMP
, PHYI_IPMP
},
2559 { "FAILED", PHYI_FAILED
, PHYI_FAILED
},
2560 { "STANDBY", PHYI_STANDBY
, PHYI_STANDBY
},
2561 { "INACTIVE", PHYI_INACTIVE
, PHYI_INACTIVE
},
2562 { "OFFLINE", PHYI_OFFLINE
, PHYI_OFFLINE
},
2563 { "NOTRAILER", ILLF_NOTRAILERS
, ILLF_NOTRAILERS
},
2564 { "NOARP", ILLF_NOARP
, ILLF_NOARP
},
2565 { "MULTICAST", ILLF_MULTICAST
, ILLF_MULTICAST
},
2566 { "ROUTER", ILLF_ROUTER
, ILLF_ROUTER
},
2567 { "NONUD", ILLF_NONUD
, ILLF_NONUD
},
2568 { "NORTEXCH", ILLF_NORTEXCH
, ILLF_NORTEXCH
},
2571 char ill_name
[LIFNAMSIZ
];
2575 int ipver
= illcb
->ill_ipversion
;
2578 if ((ipver
== IPV4_VERSION
&& ill
->ill_isv6
) ||
2579 (ipver
== IPV6_VERSION
&& !ill
->ill_isv6
)) {
2583 if (mdb_vread(&phyi
, sizeof (phyint_t
),
2584 (uintptr_t)ill
->ill_phyint
) == -1) {
2585 mdb_warn("failed to read ill_phyint at %p",
2586 (uintptr_t)ill
->ill_phyint
);
2589 (void) mdb_readstr(ill_name
, MIN(LIFNAMSIZ
, ill
->ill_name_length
),
2590 (uintptr_t)ill
->ill_name
);
2592 switch (ill
->ill_type
) {
2594 typebuf
= "LOOPBACK";
2606 cnt
= ill
->ill_refcnt
+ ill
->ill_ire_cnt
+ ill
->ill_nce_cnt
+
2607 ill
->ill_ilm_cnt
+ ill
->ill_ncec_cnt
;
2608 mdb_printf("%-?p %-8s %-3s ",
2609 addr
, ill_name
, ill
->ill_isv6
? "v6" : "v4");
2610 if (typebuf
!= NULL
)
2611 mdb_printf("%-10s ", typebuf
);
2613 mdb_printf("%-10x ", ill
->ill_type
);
2615 mdb_printf("%-?p %-?p %-llb\n",
2616 ill
->ill_wq
, ill
->ill_ipst
,
2617 ill
->ill_flags
| phyi
.phyint_flags
, v_fmasks
);
2618 mdb_printf("%-?p %4d%4s %-?p\n",
2619 ill
->ill_phyint
, cnt
, "", ill
->ill_grp
);
2620 mdb_snprintf(sbuf
, sizeof (sbuf
), "%*s %3s",
2621 sizeof (uintptr_t) * 2, "", "");
2622 mdb_printf("%s|\n%s+--> %3d %-18s "
2623 "references from active threads\n",
2624 sbuf
, sbuf
, ill
->ill_refcnt
, "ill_refcnt");
2625 mdb_printf("%*s %7d %-18s ires referencing this ill\n",
2626 strlen(sbuf
), "", ill
->ill_ire_cnt
, "ill_ire_cnt");
2627 mdb_printf("%*s %7d %-18s nces referencing this ill\n",
2628 strlen(sbuf
), "", ill
->ill_nce_cnt
, "ill_nce_cnt");
2629 mdb_printf("%*s %7d %-18s ncecs referencing this ill\n",
2630 strlen(sbuf
), "", ill
->ill_ncec_cnt
, "ill_ncec_cnt");
2631 mdb_printf("%*s %7d %-18s ilms referencing this ill\n",
2632 strlen(sbuf
), "", ill
->ill_ilm_cnt
, "ill_ilm_cnt");
2634 mdb_printf("%4d %-?p %-llb\n",
2636 ill
->ill_flags
| phyi
.phyint_flags
, fmasks
);
2642 ill(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
2647 const char *zone_name
= NULL
;
2648 const char *opt_P
= NULL
;
2649 uint_t verbose
= FALSE
;
2650 ip_stack_t
*ipst
= NULL
;
2652 if (mdb_getopts(argc
, argv
,
2653 'v', MDB_OPT_SETBITS
, TRUE
, &verbose
,
2654 's', MDB_OPT_STR
, &zone_name
,
2655 'P', MDB_OPT_STR
, &opt_P
, NULL
) != argc
)
2656 return (DCMD_USAGE
);
2658 /* Follow the specified zone name to find a ip_stack_t*. */
2659 if (zone_name
!= NULL
) {
2660 ipst
= zone_to_ips(zone_name
);
2662 return (DCMD_USAGE
);
2665 if (opt_P
!= NULL
) {
2666 if (strcmp("v4", opt_P
) == 0) {
2667 ipversion
= IPV4_VERSION
;
2668 } else if (strcmp("v6", opt_P
) == 0) {
2669 ipversion
= IPV6_VERSION
;
2671 mdb_warn("invalid protocol '%s'\n", opt_P
);
2672 return (DCMD_USAGE
);
2676 id
.verbose
= verbose
;
2678 id
.ill_ipversion
= ipversion
;
2681 ill_header(verbose
);
2682 if (flags
& DCMD_ADDRSPEC
) {
2683 if (mdb_vread(&ill_data
, sizeof (ill_t
), addr
) == -1) {
2684 mdb_warn("failed to read ill at %p\n", addr
);
2687 (void) ill_format(addr
, &ill_data
, &id
);
2689 if (mdb_walk("ill", (mdb_walk_cb_t
)ill_cb
, &id
) == -1) {
2690 mdb_warn("failed to walk ills\n");
2700 mdb_printf("Prints the following fields: ill ptr, name, "
2701 "IP version, count, ill type and ill flags.\n"
2702 "The count field is a sum of individual refcnts and is expanded "
2703 "with the -v option.\n\n");
2704 mdb_printf("Options:\n");
2705 mdb_printf("\t-P v4 | v6"
2706 "\tfilter ill structures for the specified protocol\n");
2710 ip_list_walk_init(mdb_walk_state_t
*wsp
)
2712 const ip_list_walk_arg_t
*arg
= wsp
->walk_arg
;
2713 ip_list_walk_data_t
*iw
;
2714 uintptr_t addr
= (uintptr_t)(wsp
->walk_addr
+ arg
->off
);
2716 if (wsp
->walk_addr
== (uintptr_t)NULL
) {
2717 mdb_warn("only local walks supported\n");
2720 if (mdb_vread(&wsp
->walk_addr
, sizeof (uintptr_t),
2722 mdb_warn("failed to read list head at %p", addr
);
2725 iw
= mdb_alloc(sizeof (ip_list_walk_data_t
), UM_SLEEP
);
2726 iw
->nextoff
= arg
->nextp_off
;
2727 wsp
->walk_data
= iw
;
2733 ip_list_walk_step(mdb_walk_state_t
*wsp
)
2735 ip_list_walk_data_t
*iw
= wsp
->walk_data
;
2736 uintptr_t addr
= wsp
->walk_addr
;
2738 if (addr
== (uintptr_t)NULL
)
2740 wsp
->walk_addr
= addr
+ iw
->nextoff
;
2741 if (mdb_vread(&wsp
->walk_addr
, sizeof (uintptr_t),
2742 wsp
->walk_addr
) == -1) {
2743 mdb_warn("failed to read list node at %p", addr
);
2746 return (wsp
->walk_callback(addr
, iw
, wsp
->walk_cbdata
));
2750 ip_list_walk_fini(mdb_walk_state_t
*wsp
)
2752 mdb_free(wsp
->walk_data
, sizeof (ip_list_walk_data_t
));
2756 ipif_walk_init(mdb_walk_state_t
*wsp
)
2758 if (mdb_layered_walk("ill", wsp
) == -1) {
2759 mdb_warn("can't walk 'ills'");
2766 ipif_walk_step(mdb_walk_state_t
*wsp
)
2768 if (mdb_pwalk("ipif_list", wsp
->walk_callback
, wsp
->walk_cbdata
,
2769 wsp
->walk_addr
) == -1) {
2770 mdb_warn("can't walk 'ipif_list'");
2779 ipif_cb(uintptr_t addr
, const ipif_walk_data_t
*iw
, ipif_cbdata_t
*id
)
2783 if (mdb_vread(&ipif
, sizeof (ipif_t
), (uintptr_t)addr
) == -1) {
2784 mdb_warn("failed to read ipif at %p", addr
);
2787 if (mdb_vread(&id
->ill
, sizeof (ill_t
),
2788 (uintptr_t)ipif
.ipif_ill
) == -1) {
2789 mdb_warn("failed to read ill at %p", ipif
.ipif_ill
);
2792 (void) ipif_format((uintptr_t)addr
, &ipif
, id
);
2797 ipif_header(boolean_t verbose
)
2800 mdb_printf("%-?s %-10s %-3s %-?s %-8s %-30s\n",
2801 "ADDR", "NAME", "CNT", "ILL", "STFLAGS", "FLAGS");
2802 mdb_printf("%s\n%s\n",
2803 "LCLADDR", "BROADCAST");
2804 mdb_printf("%<u>%80s%</u>\n", "");
2806 mdb_printf("%-?s %-10s %6s %-?s %-8s %-30s\n",
2807 "ADDR", "NAME", "CNT", "ILL", "STFLAGS", "FLAGS");
2808 mdb_printf("%s\n%<u>%80s%</u>\n", "LCLADDR", "");
2813 #define ip_ntohl_32(x) ((x) & 0xffffffff)
2815 #define ip_ntohl_32(x) (((uint32_t)(x) << 24) | \
2816 (((uint32_t)(x) << 8) & 0xff0000) | \
2817 (((uint32_t)(x) >> 8) & 0xff00) | \
2818 ((uint32_t)(x) >> 24))
2822 mask_to_prefixlen(int af
, const in6_addr_t
*addr
)
2828 if (af
== AF_INET6
) {
2829 for (i
= 0; i
< 4; i
++) {
2830 if (addr
->s6_addr32
[i
] == 0xffffffff) {
2833 mask
= addr
->s6_addr32
[i
];
2838 mask
= V4_PART_OF_V6((*addr
));
2841 len
+= (33 - mdb_ffs(ip_ntohl_32(mask
)));
2846 ipif_format(uintptr_t addr
, const void *ipifptr
, void *ipif_cb_arg
)
2848 const ipif_t
*ipif
= ipifptr
;
2849 ipif_cbdata_t
*ipifcb
= ipif_cb_arg
;
2850 boolean_t verbose
= ipifcb
->verbose
;
2851 char ill_name
[LIFNAMSIZ
];
2852 char buf
[LIFNAMSIZ
];
2854 static const mdb_bitmask_t sfmasks
[] = {
2855 { "CO", IPIF_CONDEMNED
, IPIF_CONDEMNED
},
2856 { "CH", IPIF_CHANGING
, IPIF_CHANGING
},
2857 { "SL", IPIF_SET_LINKLOCAL
, IPIF_SET_LINKLOCAL
},
2860 static const mdb_bitmask_t fmasks
[] = {
2861 { "UP", IPIF_UP
, IPIF_UP
},
2862 { "UNN", IPIF_UNNUMBERED
, IPIF_UNNUMBERED
},
2863 { "DHCP", IPIF_DHCPRUNNING
, IPIF_DHCPRUNNING
},
2864 { "PRIV", IPIF_PRIVATE
, IPIF_PRIVATE
},
2865 { "NOXMT", IPIF_NOXMIT
, IPIF_NOXMIT
},
2866 { "NOLCL", IPIF_NOLOCAL
, IPIF_NOLOCAL
},
2867 { "DEPR", IPIF_DEPRECATED
, IPIF_DEPRECATED
},
2868 { "PREF", IPIF_PREFERRED
, IPIF_PREFERRED
},
2869 { "TEMP", IPIF_TEMPORARY
, IPIF_TEMPORARY
},
2870 { "ACONF", IPIF_ADDRCONF
, IPIF_ADDRCONF
},
2871 { "ANY", IPIF_ANYCAST
, IPIF_ANYCAST
},
2872 { "NFAIL", IPIF_NOFAILOVER
, IPIF_NOFAILOVER
},
2875 char flagsbuf
[2 * A_CNT(fmasks
)];
2876 char bitfields
[A_CNT(fmasks
)];
2877 char sflagsbuf
[A_CNT(sfmasks
)];
2878 char sbuf
[DEFCOLS
], addrstr
[INET6_ADDRSTRLEN
];
2879 int ipver
= ipifcb
->ipif_ipversion
;
2883 if ((ipver
== IPV4_VERSION
&& ipifcb
->ill
.ill_isv6
) ||
2884 (ipver
== IPV6_VERSION
&& !ipifcb
->ill
.ill_isv6
)) {
2888 if ((mdb_readstr(ill_name
, MIN(LIFNAMSIZ
,
2889 ipifcb
->ill
.ill_name_length
),
2890 (uintptr_t)ipifcb
->ill
.ill_name
)) == -1) {
2891 mdb_warn("failed to read ill_name of ill %p\n", ipifcb
->ill
);
2894 if (ipif
->ipif_id
!= 0) {
2895 mdb_snprintf(buf
, LIFNAMSIZ
, "%s:%d",
2896 ill_name
, ipif
->ipif_id
);
2898 mdb_snprintf(buf
, LIFNAMSIZ
, "%s", ill_name
);
2900 mdb_snprintf(bitfields
, sizeof (bitfields
), "%s",
2901 ipif
->ipif_addr_ready
? ",ADR" : "",
2902 ipif
->ipif_was_up
? ",WU" : "",
2903 ipif
->ipif_was_dup
? ",WD" : "");
2904 mdb_snprintf(flagsbuf
, sizeof (flagsbuf
), "%llb%s",
2905 ipif
->ipif_flags
, fmasks
, bitfields
);
2906 mdb_snprintf(sflagsbuf
, sizeof (sflagsbuf
), "%b",
2907 ipif
->ipif_state_flags
, sfmasks
);
2909 cnt
= ipif
->ipif_refcnt
;
2911 if (ipifcb
->ill
.ill_isv6
) {
2912 mdb_snprintf(addrstr
, sizeof (addrstr
), "%N",
2913 &ipif
->ipif_v6lcl_addr
);
2916 mdb_snprintf(addrstr
, sizeof (addrstr
), "%I",
2917 V4_PART_OF_V6((ipif
->ipif_v6lcl_addr
)));
2922 mdb_printf("%-?p %-10s %3d %-?p %-8s %-30s\n",
2923 addr
, buf
, cnt
, ipif
->ipif_ill
,
2924 sflagsbuf
, flagsbuf
);
2925 mdb_snprintf(sbuf
, sizeof (sbuf
), "%*s %12s",
2926 sizeof (uintptr_t) * 2, "", "");
2927 mdb_printf("%s |\n%s +---> %4d %-15s "
2928 "Active consistent reader cnt\n",
2929 sbuf
, sbuf
, ipif
->ipif_refcnt
, "ipif_refcnt");
2930 mdb_printf("%-s/%d\n",
2931 addrstr
, mask_to_prefixlen(af
, &ipif
->ipif_v6net_mask
));
2932 if (ipifcb
->ill
.ill_isv6
) {
2933 mdb_printf("%-N\n", &ipif
->ipif_v6brd_addr
);
2936 V4_PART_OF_V6((ipif
->ipif_v6brd_addr
)));
2939 mdb_printf("%-?p %-10s %6d %-?p %-8s %-30s\n",
2940 addr
, buf
, cnt
, ipif
->ipif_ill
,
2941 sflagsbuf
, flagsbuf
);
2942 mdb_printf("%-s/%d\n",
2943 addrstr
, mask_to_prefixlen(af
, &ipif
->ipif_v6net_mask
));
2950 ipif(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
2955 const char *opt_P
= NULL
;
2956 uint_t verbose
= FALSE
;
2958 if (mdb_getopts(argc
, argv
,
2959 'v', MDB_OPT_SETBITS
, TRUE
, &verbose
,
2960 'P', MDB_OPT_STR
, &opt_P
, NULL
) != argc
)
2961 return (DCMD_USAGE
);
2963 if (opt_P
!= NULL
) {
2964 if (strcmp("v4", opt_P
) == 0) {
2965 ipversion
= IPV4_VERSION
;
2966 } else if (strcmp("v6", opt_P
) == 0) {
2967 ipversion
= IPV6_VERSION
;
2969 mdb_warn("invalid protocol '%s'\n", opt_P
);
2970 return (DCMD_USAGE
);
2974 id
.verbose
= verbose
;
2975 id
.ipif_ipversion
= ipversion
;
2977 if (flags
& DCMD_ADDRSPEC
) {
2978 if (mdb_vread(&ipif
, sizeof (ipif_t
), addr
) == -1) {
2979 mdb_warn("failed to read ipif at %p\n", addr
);
2982 ipif_header(verbose
);
2983 if (mdb_vread(&id
.ill
, sizeof (ill_t
),
2984 (uintptr_t)ipif
.ipif_ill
) == -1) {
2985 mdb_warn("failed to read ill at %p", ipif
.ipif_ill
);
2988 return (ipif_format(addr
, &ipif
, &id
));
2990 ipif_header(verbose
);
2991 if (mdb_walk("ipif", (mdb_walk_cb_t
)ipif_cb
, &id
) == -1) {
2992 mdb_warn("failed to walk ipifs\n");
3002 mdb_printf("Prints the following fields: ipif ptr, name, "
3003 "count, ill ptr, state flags and ipif flags.\n"
3004 "The count field is a sum of individual refcnts and is expanded "
3005 "with the -v option.\n"
3006 "The flags field shows the following:"
3007 "\n\tUNN -> UNNUMBERED, DHCP -> DHCPRUNNING, PRIV -> PRIVATE, "
3008 "\n\tNOXMT -> NOXMIT, NOLCL -> NOLOCAL, DEPR -> DEPRECATED, "
3009 "\n\tPREF -> PREFERRED, TEMP -> TEMPORARY, ACONF -> ADDRCONF, "
3010 "\n\tANY -> ANYCAST, NFAIL -> NOFAILOVER, "
3011 "\n\tADR -> ipif_addr_ready, MU -> ipif_multicast_up, "
3012 "\n\tWU -> ipif_was_up, WD -> ipif_was_dup, "
3013 "JA -> ipif_joined_allhosts.\n\n");
3014 mdb_printf("Options:\n");
3015 mdb_printf("\t-P v4 | v6"
3016 "\tfilter ipif structures on ills for the specified protocol\n");
3020 conn_status_walk_fanout(uintptr_t addr
, mdb_walk_state_t
*wsp
,
3021 const char *walkname
)
3023 if (mdb_pwalk(walkname
, wsp
->walk_callback
, wsp
->walk_cbdata
,
3025 mdb_warn("couldn't walk '%s' at %p", walkname
, addr
);
3032 conn_status_walk_step(mdb_walk_state_t
*wsp
)
3034 uintptr_t addr
= wsp
->walk_addr
;
3036 (void) conn_status_walk_fanout(addr
, wsp
, "udp_hash");
3037 (void) conn_status_walk_fanout(addr
, wsp
, "conn_hash");
3038 (void) conn_status_walk_fanout(addr
, wsp
, "bind_hash");
3039 (void) conn_status_walk_fanout(addr
, wsp
, "proto_hash");
3040 (void) conn_status_walk_fanout(addr
, wsp
, "proto_v6_hash");
3046 conn_status_cb(uintptr_t addr
, const void *walk_data
, void *private)
3049 char src_addrstr
[INET6_ADDRSTRLEN
];
3050 char rem_addrstr
[INET6_ADDRSTRLEN
];
3051 const ipcl_hash_walk_data_t
*iw
= walk_data
;
3052 conn_t c
, *conn
= &c
;
3053 in_port_t lport
, fport
;
3057 else if (mdb_vread(conn
, sizeof (conn_t
), addr
) == -1) {
3058 mdb_warn("failed to read conn_t at %p", addr
);
3061 if (mdb_vread(&nss
, sizeof (nss
),
3062 (uintptr_t)conn
->conn_netstack
) == -1) {
3063 mdb_warn("failed to read netstack_t %p",
3064 conn
->conn_netstack
);
3067 mdb_printf("%-?p %-?p %?d %?d\n", addr
, conn
->conn_wq
,
3068 nss
.netstack_stackid
, conn
->conn_zoneid
);
3070 if (conn
->conn_family
== AF_INET6
) {
3071 mdb_snprintf(src_addrstr
, sizeof (rem_addrstr
), "%N",
3072 &conn
->conn_laddr_v6
);
3073 mdb_snprintf(rem_addrstr
, sizeof (rem_addrstr
), "%N",
3074 &conn
->conn_faddr_v6
);
3076 mdb_snprintf(src_addrstr
, sizeof (src_addrstr
), "%I",
3077 V4_PART_OF_V6((conn
->conn_laddr_v6
)));
3078 mdb_snprintf(rem_addrstr
, sizeof (rem_addrstr
), "%I",
3079 V4_PART_OF_V6((conn
->conn_faddr_v6
)));
3081 mdb_nhconvert(&lport
, &conn
->conn_lport
, sizeof (lport
));
3082 mdb_nhconvert(&fport
, &conn
->conn_fport
, sizeof (fport
));
3083 mdb_printf("%s:%-5d\n%s:%-5d\n",
3084 src_addrstr
, lport
, rem_addrstr
, fport
);
3091 mdb_printf("%-?s %-?s %?s %?s\n%s\n%s\n",
3092 "ADDR", "WQ", "STACK", "ZONE", "SRC:PORT", "DEST:PORT");
3093 mdb_printf("%<u>%80s%</u>\n", "");
3098 conn_status(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
3101 if (flags
& DCMD_ADDRSPEC
) {
3102 (void) conn_status_cb(addr
, NULL
, NULL
);
3104 if (mdb_walk("conn_status", (mdb_walk_cb_t
)conn_status_cb
,
3106 mdb_warn("failed to walk conn_fanout");
3114 conn_status_help(void)
3116 mdb_printf("Prints conn_t structures from the following hash tables: "
3117 "\n\tips_ipcl_udp_fanout\n\tips_ipcl_bind_fanout"
3118 "\n\tips_ipcl_conn_fanout\n\tips_ipcl_proto_fanout_v4"
3119 "\n\tips_ipcl_proto_fanout_v6\n");
3123 srcid_walk_step(mdb_walk_state_t
*wsp
)
3125 if (mdb_pwalk("srcid_list", wsp
->walk_callback
, wsp
->walk_cbdata
,
3126 wsp
->walk_addr
) == -1) {
3127 mdb_warn("can't walk 'srcid_list'");
3135 srcid_status_cb(uintptr_t addr
, const void *walk_data
,
3140 if (mdb_vread(&smp
, sizeof (srcid_map_t
), addr
) == -1) {
3141 mdb_warn("failed to read srcid_map at %p", addr
);
3144 mdb_printf("%-?p %3d %4d %6d %N\n",
3145 addr
, smp
.sm_srcid
, smp
.sm_zoneid
, smp
.sm_refcnt
,
3153 mdb_printf("%-?s %3s %4s %6s %s\n",
3154 "ADDR", "ID", "ZONE", "REFCNT", "IPADDR");
3155 mdb_printf("%<u>%80s%</u>\n", "");
3160 srcid_status(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
3163 if (flags
& DCMD_ADDRSPEC
) {
3164 (void) srcid_status_cb(addr
, NULL
, NULL
);
3166 if (mdb_walk("srcid", (mdb_walk_cb_t
)srcid_status_cb
,
3168 mdb_warn("failed to walk srcid_map");
3176 ilb_stacks_walk_step(mdb_walk_state_t
*wsp
)
3178 return (ns_walk_step(wsp
, NS_ILB
));
3182 ilb_rules_walk_init(mdb_walk_state_t
*wsp
)
3186 if (wsp
->walk_addr
== (uintptr_t)NULL
)
3189 if (mdb_vread(&ilbs
, sizeof (ilbs
), wsp
->walk_addr
) == -1) {
3190 mdb_warn("failed to read ilb_stack_t at %p", wsp
->walk_addr
);
3193 if ((wsp
->walk_addr
= (uintptr_t)ilbs
.ilbs_rule_head
) !=
3201 ilb_rules_walk_step(mdb_walk_state_t
*wsp
)
3206 if (mdb_vread(&rule
, sizeof (rule
), wsp
->walk_addr
) == -1) {
3207 mdb_warn("failed to read ilb_rule_t at %p", wsp
->walk_addr
);
3210 status
= wsp
->walk_callback(wsp
->walk_addr
, &rule
, wsp
->walk_cbdata
);
3211 if (status
!= WALK_NEXT
)
3213 if ((wsp
->walk_addr
= (uintptr_t)rule
.ir_next
) == (uintptr_t)NULL
)
3220 ilb_servers_walk_init(mdb_walk_state_t
*wsp
)
3224 if (wsp
->walk_addr
== (uintptr_t)NULL
)
3227 if (mdb_vread(&rule
, sizeof (rule
), wsp
->walk_addr
) == -1) {
3228 mdb_warn("failed to read ilb_rule_t at %p", wsp
->walk_addr
);
3231 if ((wsp
->walk_addr
= (uintptr_t)rule
.ir_servers
) != (uintptr_t)NULL
)
3238 ilb_servers_walk_step(mdb_walk_state_t
*wsp
)
3240 ilb_server_t server
;
3243 if (mdb_vread(&server
, sizeof (server
), wsp
->walk_addr
) == -1) {
3244 mdb_warn("failed to read ilb_server_t at %p", wsp
->walk_addr
);
3247 status
= wsp
->walk_callback(wsp
->walk_addr
, &server
, wsp
->walk_cbdata
);
3248 if (status
!= WALK_NEXT
)
3250 if ((wsp
->walk_addr
= (uintptr_t)server
.iser_next
) == (uintptr_t)NULL
)
3257 * Helper structure for ilb_nat_src walker. It stores the current index of the
3265 /* Copy from list.c */
3266 #define list_object(a, node) ((void *)(((char *)node) - (a)->list_offset))
3269 ilb_nat_src_walk_init(mdb_walk_state_t
*wsp
)
3272 ilb_walk_t
*ns_walk
;
3273 ilb_nat_src_entry_t
*entry
= NULL
;
3275 if (wsp
->walk_addr
== (uintptr_t)NULL
)
3278 ns_walk
= mdb_alloc(sizeof (ilb_walk_t
), UM_SLEEP
);
3279 if (mdb_vread(&ns_walk
->ilbs
, sizeof (ns_walk
->ilbs
),
3280 wsp
->walk_addr
) == -1) {
3281 mdb_warn("failed to read ilb_stack_t at %p", wsp
->walk_addr
);
3282 mdb_free(ns_walk
, sizeof (ilb_walk_t
));
3286 if (ns_walk
->ilbs
.ilbs_nat_src
== NULL
) {
3287 mdb_free(ns_walk
, sizeof (ilb_walk_t
));
3291 wsp
->walk_data
= ns_walk
;
3292 for (i
= 0; i
< ns_walk
->ilbs
.ilbs_nat_src_hash_size
; i
++) {
3296 /* Read in the nsh_head in the i-th element of the array. */
3297 khead
= (char *)ns_walk
->ilbs
.ilbs_nat_src
+ i
*
3298 sizeof (ilb_nat_src_hash_t
);
3299 if (mdb_vread(&head
, sizeof (list_t
), (uintptr_t)khead
) == -1) {
3300 mdb_warn("failed to read ilbs_nat_src at %p\n", khead
);
3305 * Note that list_next points to a kernel address and we need
3306 * to compare list_next with the kernel address of the list
3307 * head. So we need to calculate the address manually.
3309 if ((char *)head
.list_head
.list_next
!= khead
+
3310 offsetof(list_t
, list_head
)) {
3311 entry
= list_object(&head
, head
.list_head
.list_next
);
3319 wsp
->walk_addr
= (uintptr_t)entry
;
3325 ilb_nat_src_walk_step(mdb_walk_state_t
*wsp
)
3328 ilb_nat_src_entry_t entry
, *next_entry
;
3329 ilb_walk_t
*ns_walk
;
3335 if (mdb_vread(&entry
, sizeof (ilb_nat_src_entry_t
),
3336 wsp
->walk_addr
) == -1) {
3337 mdb_warn("failed to read ilb_nat_src_entry_t at %p",
3341 status
= wsp
->walk_callback(wsp
->walk_addr
, &entry
, wsp
->walk_cbdata
);
3342 if (status
!= WALK_NEXT
)
3345 ns_walk
= (ilb_walk_t
*)wsp
->walk_data
;
3346 ilbs
= &ns_walk
->ilbs
;
3349 /* Read in the nsh_head in the i-th element of the array. */
3350 khead
= (char *)ilbs
->ilbs_nat_src
+ i
* sizeof (ilb_nat_src_hash_t
);
3351 if (mdb_vread(&head
, sizeof (list_t
), (uintptr_t)khead
) == -1) {
3352 mdb_warn("failed to read ilbs_nat_src at %p\n", khead
);
3357 * Check if there is still entry in the current list.
3359 * Note that list_next points to a kernel address and we need to
3360 * compare list_next with the kernel address of the list head.
3361 * So we need to calculate the address manually.
3363 if ((char *)entry
.nse_link
.list_next
!= khead
+ offsetof(list_t
,
3365 wsp
->walk_addr
= (uintptr_t)list_object(&head
,
3366 entry
.nse_link
.list_next
);
3370 /* Start with the next bucket in the array. */
3372 for (i
++; i
< ilbs
->ilbs_nat_src_hash_size
; i
++) {
3373 khead
= (char *)ilbs
->ilbs_nat_src
+ i
*
3374 sizeof (ilb_nat_src_hash_t
);
3375 if (mdb_vread(&head
, sizeof (list_t
), (uintptr_t)khead
) == -1) {
3376 mdb_warn("failed to read ilbs_nat_src at %p\n", khead
);
3380 if ((char *)head
.list_head
.list_next
!= khead
+
3381 offsetof(list_t
, list_head
)) {
3382 next_entry
= list_object(&head
,
3383 head
.list_head
.list_next
);
3388 if (next_entry
== NULL
)
3391 wsp
->walk_addr
= (uintptr_t)next_entry
;
3397 ilb_common_walk_fini(mdb_walk_state_t
*wsp
)
3401 walk
= (ilb_walk_t
*)wsp
->walk_data
;
3404 mdb_free(walk
, sizeof (ilb_walk_t
*));
3408 ilb_conn_walk_init(mdb_walk_state_t
*wsp
)
3411 ilb_walk_t
*conn_walk
;
3412 ilb_conn_hash_t head
;
3414 if (wsp
->walk_addr
== (uintptr_t)NULL
)
3417 conn_walk
= mdb_alloc(sizeof (ilb_walk_t
), UM_SLEEP
);
3418 if (mdb_vread(&conn_walk
->ilbs
, sizeof (conn_walk
->ilbs
),
3419 wsp
->walk_addr
) == -1) {
3420 mdb_warn("failed to read ilb_stack_t at %p", wsp
->walk_addr
);
3421 mdb_free(conn_walk
, sizeof (ilb_walk_t
));
3425 if (conn_walk
->ilbs
.ilbs_c2s_conn_hash
== NULL
) {
3426 mdb_free(conn_walk
, sizeof (ilb_walk_t
));
3430 wsp
->walk_data
= conn_walk
;
3431 for (i
= 0; i
< conn_walk
->ilbs
.ilbs_conn_hash_size
; i
++) {
3434 /* Read in the nsh_head in the i-th element of the array. */
3435 khead
= (char *)conn_walk
->ilbs
.ilbs_c2s_conn_hash
+ i
*
3436 sizeof (ilb_conn_hash_t
);
3437 if (mdb_vread(&head
, sizeof (ilb_conn_hash_t
),
3438 (uintptr_t)khead
) == -1) {
3439 mdb_warn("failed to read ilbs_c2s_conn_hash at %p\n",
3444 if (head
.ilb_connp
!= NULL
)
3448 if (head
.ilb_connp
== NULL
)
3451 wsp
->walk_addr
= (uintptr_t)head
.ilb_connp
;
3457 ilb_conn_walk_step(mdb_walk_state_t
*wsp
)
3461 ilb_walk_t
*conn_walk
;
3463 ilb_conn_hash_t head
;
3467 if (mdb_vread(&conn
, sizeof (ilb_conn_t
), wsp
->walk_addr
) == -1) {
3468 mdb_warn("failed to read ilb_conn_t at %p", wsp
->walk_addr
);
3472 status
= wsp
->walk_callback(wsp
->walk_addr
, &conn
, wsp
->walk_cbdata
);
3473 if (status
!= WALK_NEXT
)
3476 conn_walk
= (ilb_walk_t
*)wsp
->walk_data
;
3477 ilbs
= &conn_walk
->ilbs
;
3480 /* Check if there is still entry in the current list. */
3481 if (conn
.conn_c2s_next
!= NULL
) {
3482 wsp
->walk_addr
= (uintptr_t)conn
.conn_c2s_next
;
3486 /* Start with the next bucket in the array. */
3487 for (i
++; i
< ilbs
->ilbs_conn_hash_size
; i
++) {
3488 khead
= (char *)ilbs
->ilbs_c2s_conn_hash
+ i
*
3489 sizeof (ilb_conn_hash_t
);
3490 if (mdb_vread(&head
, sizeof (ilb_conn_hash_t
),
3491 (uintptr_t)khead
) == -1) {
3492 mdb_warn("failed to read ilbs_c2s_conn_hash at %p\n",
3497 if (head
.ilb_connp
!= NULL
)
3501 if (head
.ilb_connp
== NULL
)
3504 wsp
->walk_addr
= (uintptr_t)head
.ilb_connp
;
3510 ilb_sticky_walk_init(mdb_walk_state_t
*wsp
)
3513 ilb_walk_t
*sticky_walk
;
3514 ilb_sticky_t
*st
= NULL
;
3516 if (wsp
->walk_addr
== (uintptr_t)NULL
)
3519 sticky_walk
= mdb_alloc(sizeof (ilb_walk_t
), UM_SLEEP
);
3520 if (mdb_vread(&sticky_walk
->ilbs
, sizeof (sticky_walk
->ilbs
),
3521 wsp
->walk_addr
) == -1) {
3522 mdb_warn("failed to read ilb_stack_t at %p", wsp
->walk_addr
);
3523 mdb_free(sticky_walk
, sizeof (ilb_walk_t
));
3527 if (sticky_walk
->ilbs
.ilbs_sticky_hash
== NULL
) {
3528 mdb_free(sticky_walk
, sizeof (ilb_walk_t
));
3532 wsp
->walk_data
= sticky_walk
;
3533 for (i
= 0; i
< sticky_walk
->ilbs
.ilbs_sticky_hash_size
; i
++) {
3537 /* Read in the nsh_head in the i-th element of the array. */
3538 khead
= (char *)sticky_walk
->ilbs
.ilbs_sticky_hash
+ i
*
3539 sizeof (ilb_sticky_hash_t
);
3540 if (mdb_vread(&head
, sizeof (list_t
), (uintptr_t)khead
) == -1) {
3541 mdb_warn("failed to read ilbs_sticky_hash at %p\n",
3547 * Note that list_next points to a kernel address and we need
3548 * to compare list_next with the kernel address of the list
3549 * head. So we need to calculate the address manually.
3551 if ((char *)head
.list_head
.list_next
!= khead
+
3552 offsetof(list_t
, list_head
)) {
3553 st
= list_object(&head
, head
.list_head
.list_next
);
3561 wsp
->walk_addr
= (uintptr_t)st
;
3562 sticky_walk
->idx
= i
;
3567 ilb_sticky_walk_step(mdb_walk_state_t
*wsp
)
3570 ilb_sticky_t st
, *st_next
;
3571 ilb_walk_t
*sticky_walk
;
3577 if (mdb_vread(&st
, sizeof (ilb_sticky_t
), wsp
->walk_addr
) == -1) {
3578 mdb_warn("failed to read ilb_sticky_t at %p", wsp
->walk_addr
);
3582 status
= wsp
->walk_callback(wsp
->walk_addr
, &st
, wsp
->walk_cbdata
);
3583 if (status
!= WALK_NEXT
)
3586 sticky_walk
= (ilb_walk_t
*)wsp
->walk_data
;
3587 ilbs
= &sticky_walk
->ilbs
;
3588 i
= sticky_walk
->idx
;
3590 /* Read in the nsh_head in the i-th element of the array. */
3591 khead
= (char *)ilbs
->ilbs_sticky_hash
+ i
* sizeof (ilb_sticky_hash_t
);
3592 if (mdb_vread(&head
, sizeof (list_t
), (uintptr_t)khead
) == -1) {
3593 mdb_warn("failed to read ilbs_sticky_hash at %p\n", khead
);
3598 * Check if there is still entry in the current list.
3600 * Note that list_next points to a kernel address and we need to
3601 * compare list_next with the kernel address of the list head.
3602 * So we need to calculate the address manually.
3604 if ((char *)st
.list
.list_next
!= khead
+ offsetof(list_t
,
3606 wsp
->walk_addr
= (uintptr_t)list_object(&head
,
3611 /* Start with the next bucket in the array. */
3613 for (i
++; i
< ilbs
->ilbs_nat_src_hash_size
; i
++) {
3614 khead
= (char *)ilbs
->ilbs_sticky_hash
+ i
*
3615 sizeof (ilb_sticky_hash_t
);
3616 if (mdb_vread(&head
, sizeof (list_t
), (uintptr_t)khead
) == -1) {
3617 mdb_warn("failed to read ilbs_sticky_hash at %p\n",
3622 if ((char *)head
.list_head
.list_next
!= khead
+
3623 offsetof(list_t
, list_head
)) {
3624 st_next
= list_object(&head
,
3625 head
.list_head
.list_next
);
3630 if (st_next
== NULL
)
3633 wsp
->walk_addr
= (uintptr_t)st_next
;
3634 sticky_walk
->idx
= i
;