1f4b3ec61Sdh155122 /* 2f4b3ec61Sdh155122 * CDDL HEADER START 3f4b3ec61Sdh155122 * 4f4b3ec61Sdh155122 * The contents of this file are subject to the terms of the 5f4b3ec61Sdh155122 * Common Development and Distribution License (the "License"). 6f4b3ec61Sdh155122 * You may not use this file except in compliance with the License. 7f4b3ec61Sdh155122 * 8f4b3ec61Sdh155122 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9f4b3ec61Sdh155122 * or http://www.opensolaris.org/os/licensing. 10f4b3ec61Sdh155122 * See the License for the specific language governing permissions 11f4b3ec61Sdh155122 * and limitations under the License. 12f4b3ec61Sdh155122 * 13f4b3ec61Sdh155122 * When distributing Covered Code, include this CDDL HEADER in each 14f4b3ec61Sdh155122 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15f4b3ec61Sdh155122 * If applicable, add the following below this CDDL HEADER, with the 16f4b3ec61Sdh155122 * fields enclosed by brackets "[]" replaced with your own identifying 17f4b3ec61Sdh155122 * information: Portions Copyright [yyyy] [name of copyright owner] 18f4b3ec61Sdh155122 * 19f4b3ec61Sdh155122 * CDDL HEADER END 20f4b3ec61Sdh155122 */ 21f4b3ec61Sdh155122 /* 22f4b3ec61Sdh155122 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23f4b3ec61Sdh155122 * Use is subject to license terms. 24*589efa95SRobert Mustacchi * Copyright (c) 2012, Joyent, Inc. All rights reserved. 25f4b3ec61Sdh155122 */ 26f4b3ec61Sdh155122 27f4b3ec61Sdh155122 #include <mdb/mdb_modapi.h> 28f4b3ec61Sdh155122 #include <mdb/mdb_ks.h> 29f4b3ec61Sdh155122 #include <mdb/mdb_ctf.h> 30f4b3ec61Sdh155122 #include <sys/types.h> 31f4b3ec61Sdh155122 #include <sys/netstack.h> 32f4b3ec61Sdh155122 33f4b3ec61Sdh155122 int 34f4b3ec61Sdh155122 netstack_walk_init(mdb_walk_state_t *wsp) 35f4b3ec61Sdh155122 { 36f4b3ec61Sdh155122 GElf_Sym sym; 37f4b3ec61Sdh155122 uintptr_t addr; 38f4b3ec61Sdh155122 39f4b3ec61Sdh155122 if (mdb_lookup_by_name("netstack_head", &sym) == -1) { 40f4b3ec61Sdh155122 mdb_warn("couldn't find netstack_head"); 41f4b3ec61Sdh155122 return (WALK_ERR); 42f4b3ec61Sdh155122 } 43f4b3ec61Sdh155122 addr = (uintptr_t)sym.st_value; 44f4b3ec61Sdh155122 45f4b3ec61Sdh155122 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), addr) == -1) { 46f4b3ec61Sdh155122 mdb_warn("failed to read address of initial netstack " 47f4b3ec61Sdh155122 "at %p", addr); 48f4b3ec61Sdh155122 return (WALK_ERR); 49f4b3ec61Sdh155122 } 50f4b3ec61Sdh155122 return (WALK_NEXT); 51f4b3ec61Sdh155122 } 52f4b3ec61Sdh155122 53f4b3ec61Sdh155122 int 54f4b3ec61Sdh155122 netstack_walk_step(mdb_walk_state_t *wsp) 55f4b3ec61Sdh155122 { 56f4b3ec61Sdh155122 int status; 57f4b3ec61Sdh155122 netstack_t nss; 58f4b3ec61Sdh155122 59f4b3ec61Sdh155122 if (wsp->walk_addr == NULL) 60f4b3ec61Sdh155122 return (WALK_DONE); 61f4b3ec61Sdh155122 62f4b3ec61Sdh155122 if (mdb_vread(&nss, sizeof (netstack_t), wsp->walk_addr) == -1) { 63f4b3ec61Sdh155122 mdb_warn("failed to read netstack at %p", wsp->walk_addr); 64f4b3ec61Sdh155122 return (WALK_ERR); 65f4b3ec61Sdh155122 } 66f4b3ec61Sdh155122 67f4b3ec61Sdh155122 status = wsp->walk_callback(wsp->walk_addr, &nss, 68f4b3ec61Sdh155122 wsp->walk_cbdata); 69f4b3ec61Sdh155122 70f4b3ec61Sdh155122 if (status != WALK_NEXT) 71f4b3ec61Sdh155122 return (status); 72f4b3ec61Sdh155122 73f4b3ec61Sdh155122 wsp->walk_addr = (uintptr_t)nss.netstack_next; 74f4b3ec61Sdh155122 return (status); 75f4b3ec61Sdh155122 } 76f4b3ec61Sdh155122 77f4b3ec61Sdh155122 /*ARGSUSED*/ 78f4b3ec61Sdh155122 int 79f4b3ec61Sdh155122 netstack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 80f4b3ec61Sdh155122 { 81f4b3ec61Sdh155122 netstack_t nss; 82f4b3ec61Sdh155122 uint_t quiet = FALSE; 83f4b3ec61Sdh155122 uint_t verbose = FALSE; 84f4b3ec61Sdh155122 85f4b3ec61Sdh155122 if (!(flags & DCMD_ADDRSPEC)) { 86f4b3ec61Sdh155122 if (mdb_walk_dcmd("genunix`netstack", "genunix`netstack", 87f4b3ec61Sdh155122 argc, argv) == -1) { 88f4b3ec61Sdh155122 mdb_warn("failed to walk netstack"); 89f4b3ec61Sdh155122 return (DCMD_ERR); 90f4b3ec61Sdh155122 } 91f4b3ec61Sdh155122 return (DCMD_OK); 92f4b3ec61Sdh155122 } 93f4b3ec61Sdh155122 if (mdb_getopts(argc, argv, 94f4b3ec61Sdh155122 'v', MDB_OPT_SETBITS, TRUE, &verbose, 95f4b3ec61Sdh155122 'q', MDB_OPT_SETBITS, TRUE, &quiet, 96f4b3ec61Sdh155122 NULL) != argc) 97f4b3ec61Sdh155122 return (DCMD_USAGE); 98f4b3ec61Sdh155122 99f4b3ec61Sdh155122 if (DCMD_HDRSPEC(flags) && !quiet) { 100f4b3ec61Sdh155122 mdb_printf("%?s %-7s %6s\n", 101f4b3ec61Sdh155122 "ADDR", "STACKID", "FLAGS"); 102f4b3ec61Sdh155122 } 103f4b3ec61Sdh155122 104f4b3ec61Sdh155122 if (mdb_vread(&nss, sizeof (nss), addr) == -1) { 105f4b3ec61Sdh155122 mdb_warn("couldn't read netstack at %p", addr); 106f4b3ec61Sdh155122 return (DCMD_ERR); 107f4b3ec61Sdh155122 } 108f4b3ec61Sdh155122 109f4b3ec61Sdh155122 /* 110f4b3ec61Sdh155122 * Options are specified for filtering, so If any option is specified on 111f4b3ec61Sdh155122 * the command line, just print address and exit. 112f4b3ec61Sdh155122 */ 113f4b3ec61Sdh155122 if (quiet) { 114f4b3ec61Sdh155122 mdb_printf("%0?p\n", addr); 115f4b3ec61Sdh155122 return (DCMD_OK); 116f4b3ec61Sdh155122 } 117f4b3ec61Sdh155122 118f4b3ec61Sdh155122 mdb_printf("%0?p %6d %06x\n", 119f4b3ec61Sdh155122 addr, nss.netstack_stackid, nss.netstack_flags); 120f4b3ec61Sdh155122 121f4b3ec61Sdh155122 return (DCMD_OK); 122f4b3ec61Sdh155122 } 123*589efa95SRobert Mustacchi 124*589efa95SRobert Mustacchi static int 125*589efa95SRobert Mustacchi netstackid_lookup_cb(uintptr_t addr, const netstack_t *ns, void *arg) 126*589efa95SRobert Mustacchi { 127*589efa95SRobert Mustacchi netstackid_t nid = *(uintptr_t *)arg; 128*589efa95SRobert Mustacchi if (ns->netstack_stackid == nid) 129*589efa95SRobert Mustacchi mdb_printf("%p\n", addr); 130*589efa95SRobert Mustacchi 131*589efa95SRobert Mustacchi return (WALK_NEXT); 132*589efa95SRobert Mustacchi } 133*589efa95SRobert Mustacchi 134*589efa95SRobert Mustacchi /*ARGSUSED*/ 135*589efa95SRobert Mustacchi int 136*589efa95SRobert Mustacchi netstackid2netstack(uintptr_t addr, uint_t flags, int argc, 137*589efa95SRobert Mustacchi const mdb_arg_t *argv) 138*589efa95SRobert Mustacchi { 139*589efa95SRobert Mustacchi if (!(flags & DCMD_ADDRSPEC) || argc != 0) 140*589efa95SRobert Mustacchi return (DCMD_USAGE); 141*589efa95SRobert Mustacchi 142*589efa95SRobert Mustacchi if (mdb_walk("netstack", (mdb_walk_cb_t)netstackid_lookup_cb, &addr) == 143*589efa95SRobert Mustacchi -1) { 144*589efa95SRobert Mustacchi mdb_warn("failed to walk zone"); 145*589efa95SRobert Mustacchi return (DCMD_ERR); 146*589efa95SRobert Mustacchi } 147*589efa95SRobert Mustacchi 148*589efa95SRobert Mustacchi return (DCMD_OK); 149*589efa95SRobert Mustacchi } 150