Print this page
dccp: build fixes, mdb (vfs sonode missing)


  30 #include <sys/tihdr.h>
  31 #include <inet/led.h>
  32 #include <inet/common.h>
  33 #include <netinet/in.h>
  34 #include <netinet/ip6.h>
  35 #include <netinet/icmp6.h>
  36 #include <inet/ip.h>
  37 #include <inet/ip6.h>
  38 #include <inet/ipclassifier.h>
  39 #include <inet/tcp.h>
  40 #include <sys/stream.h>
  41 #include <sys/vfs.h>
  42 #include <sys/stropts.h>
  43 #include <sys/tpicommon.h>
  44 #include <sys/socket.h>
  45 #include <sys/socketvar.h>
  46 #include <sys/cred_impl.h>
  47 #include <inet/udp_impl.h>
  48 #include <inet/rawip_impl.h>
  49 #include <inet/mi.h>

  50 #include <fs/sockfs/socktpi_impl.h>
  51 #include <net/bridge_impl.h>
  52 #include <io/trill_impl.h>
  53 #include <sys/mac_impl.h>
  54 
  55 #define ADDR_V6_WIDTH   23
  56 #define ADDR_V4_WIDTH   15
  57 
  58 #define NETSTAT_ALL     0x01
  59 #define NETSTAT_VERBOSE 0x02
  60 #define NETSTAT_ROUTE   0x04
  61 #define NETSTAT_V4      0x08
  62 #define NETSTAT_V6      0x10
  63 #define NETSTAT_UNIX    0x20
  64 
  65 #define NETSTAT_FIRST   0x80000000u
  66 
  67 typedef struct netstat_cb_data_s {
  68         uint_t  opts;
  69         conn_t  conn;


 125                 mdb_warn("can't walk 'netstack'");
 126                 return (WALK_ERR);
 127         }
 128         return (WALK_NEXT);
 129 }
 130 
 131 int
 132 udp_stacks_walk_step(mdb_walk_state_t *wsp)
 133 {
 134         uintptr_t kaddr;
 135         netstack_t nss;
 136 
 137         if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) {
 138                 mdb_warn("can't read netstack at %p", wsp->walk_addr);
 139                 return (WALK_ERR);
 140         }
 141         kaddr = (uintptr_t)nss.netstack_modules[NS_UDP];
 142         return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata));
 143 }
 144 
























 145 /*
 146  * Print an IPv4 address and port number in a compact and easy to read format
 147  * The arguments are in network byte order
 148  */
 149 static void
 150 net_ipv4addrport_pr(const in6_addr_t *nipv6addr, in_port_t nport)
 151 {
 152         uint32_t naddr = V4_PART_OF_V6((*nipv6addr));
 153 
 154         mdb_nhconvert(&nport, &nport, sizeof (nport));
 155         mdb_printf("%*I.%-5hu", ADDR_V4_WIDTH, naddr, nport);
 156 }
 157 
 158 /*
 159  * Print an IPv6 address and port number in a compact and easy to read format
 160  * The arguments are in network byte order
 161  */
 162 static void
 163 net_ipv6addrport_pr(const in6_addr_t *naddr, in_port_t nport)
 164 {


 190 net_udp_active(const udp_t *udp)
 191 {
 192         return ((udp->udp_state == TS_IDLE) ||
 193             (udp->udp_state == TS_DATA_XFER));
 194 }
 195 
 196 static int
 197 net_udp_ipv4(const udp_t *udp)
 198 {
 199         return ((udp->udp_connp->conn_ipversion == IPV4_VERSION) ||
 200             (IN6_IS_ADDR_UNSPECIFIED(&udp->udp_connp->conn_laddr_v6) &&
 201             (udp->udp_state <= TS_IDLE)));
 202 }
 203 
 204 static int
 205 net_udp_ipv6(const udp_t *udp)
 206 {
 207         return (udp->udp_connp->conn_ipversion == IPV6_VERSION);
 208 }
 209 





















 210 int
 211 sonode_walk_init(mdb_walk_state_t *wsp)
 212 {
 213         if (wsp->walk_addr == NULL) {
 214                 GElf_Sym sym;
 215                 struct socklist *slp;
 216 
 217                 if (mdb_lookup_by_obj("sockfs", "socklist", &sym) == -1) {
 218                         mdb_warn("failed to lookup sockfs`socklist");
 219                         return (WALK_ERR);
 220                 }
 221 
 222                 slp = (struct socklist *)(uintptr_t)sym.st_value;
 223 
 224                 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
 225                     (uintptr_t)&slp->sl_list) == -1) {
 226                         mdb_warn("failed to read address of initial sonode "
 227                             "at %p", &slp->sl_list);
 228                         return (WALK_ERR);
 229                 }


 728                 state = "CONNECTED";
 729         else
 730                 state = "UNKNOWN";
 731 
 732         mdb_printf("%0?p %10s ", (uintptr_t)connp->conn_icmp, state);
 733         if (af == AF_INET) {
 734                 net_ipv4addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
 735                 mdb_printf(" ");
 736                 net_ipv4addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
 737         } else if (af == AF_INET6) {
 738                 net_ipv6addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
 739                 mdb_printf(" ");
 740                 net_ipv6addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
 741         }
 742         mdb_printf(" %5i", ns_to_stackid((uintptr_t)connp->conn_netstack));
 743         mdb_printf(" %4i\n", connp->conn_zoneid);
 744 
 745         return (WALK_NEXT);
 746 }
 747 




























































 748 /*
 749  * print the address of a unix domain socket
 750  *
 751  * so is the address of a AF_UNIX struct sonode in mdb's address space
 752  * soa is the address of the struct soaddr to print
 753  *
 754  * returns 0 on success, -1 otherwise
 755  */
 756 static int
 757 netstat_unix_name_pr(const struct sotpi_sonode *st, const struct soaddr *soa)
 758 {
 759         const struct sonode *so = &st->st_sonode;
 760         const char none[] = " (none)";
 761 
 762         if ((so->so_state & SS_ISBOUND) && (soa->soa_len != 0)) {
 763                 if (st->st_info.sti_faddr_noxlate) {
 764                         mdb_printf("%-14s ", " (socketpair)");
 765                 } else {
 766                         if (soa->soa_len > sizeof (sa_family_t)) {
 767                                 char addr[MAXPATHLEN + 1];


1199         if ((optP == NULL) || (strcmp("tcp", optP) == 0)) {
1200                 status = netstat_print_common("tcp_conn_cache", IPPROTO_TCP,
1201                     netstat_tcp_cb, cbdata);
1202                 if (status != DCMD_OK)
1203                         goto out;
1204         }
1205 
1206         if ((optP == NULL) || (strcmp("udp", optP) == 0)) {
1207                 status = netstat_print_common("udp_conn_cache", IPPROTO_UDP,
1208                     netstat_udp_cb, cbdata);
1209                 if (status != DCMD_OK)
1210                         goto out;
1211         }
1212 
1213         if ((optP == NULL) || (strcmp("icmp", optP) == 0)) {
1214                 status = netstat_print_common("rawip_conn_cache", IPPROTO_ICMP,
1215                     netstat_icmp_cb, cbdata);
1216                 if (status != DCMD_OK)
1217                         goto out;
1218         }







1219 out:
1220         mdb_free(cbdata, sizeof (netstat_cb_data_t));
1221         return (status);
1222 }
1223 
1224 /*
1225  * "::dladm show-bridge" support
1226  */
1227 typedef struct {
1228         uint_t opt_l;
1229         uint_t opt_f;
1230         uint_t opt_t;
1231         const char *name;
1232         clock_t lbolt;
1233         boolean_t found;
1234         uint_t nlinks;
1235         uint_t nfwd;
1236 
1237         /*
1238          * These structures are kept inside the 'args' for allocation reasons.




  30 #include <sys/tihdr.h>
  31 #include <inet/led.h>
  32 #include <inet/common.h>
  33 #include <netinet/in.h>
  34 #include <netinet/ip6.h>
  35 #include <netinet/icmp6.h>
  36 #include <inet/ip.h>
  37 #include <inet/ip6.h>
  38 #include <inet/ipclassifier.h>
  39 #include <inet/tcp.h>
  40 #include <sys/stream.h>
  41 #include <sys/vfs.h>
  42 #include <sys/stropts.h>
  43 #include <sys/tpicommon.h>
  44 #include <sys/socket.h>
  45 #include <sys/socketvar.h>
  46 #include <sys/cred_impl.h>
  47 #include <inet/udp_impl.h>
  48 #include <inet/rawip_impl.h>
  49 #include <inet/mi.h>
  50 #include <inet/dccp/dccp_impl.h>
  51 #include <fs/sockfs/socktpi_impl.h>
  52 #include <net/bridge_impl.h>
  53 #include <io/trill_impl.h>
  54 #include <sys/mac_impl.h>
  55 
  56 #define ADDR_V6_WIDTH   23
  57 #define ADDR_V4_WIDTH   15
  58 
  59 #define NETSTAT_ALL     0x01
  60 #define NETSTAT_VERBOSE 0x02
  61 #define NETSTAT_ROUTE   0x04
  62 #define NETSTAT_V4      0x08
  63 #define NETSTAT_V6      0x10
  64 #define NETSTAT_UNIX    0x20
  65 
  66 #define NETSTAT_FIRST   0x80000000u
  67 
  68 typedef struct netstat_cb_data_s {
  69         uint_t  opts;
  70         conn_t  conn;


 126                 mdb_warn("can't walk 'netstack'");
 127                 return (WALK_ERR);
 128         }
 129         return (WALK_NEXT);
 130 }
 131 
 132 int
 133 udp_stacks_walk_step(mdb_walk_state_t *wsp)
 134 {
 135         uintptr_t kaddr;
 136         netstack_t nss;
 137 
 138         if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) {
 139                 mdb_warn("can't read netstack at %p", wsp->walk_addr);
 140                 return (WALK_ERR);
 141         }
 142         kaddr = (uintptr_t)nss.netstack_modules[NS_UDP];
 143         return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata));
 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 
 170 /*
 171  * Print an IPv4 address and port number in a compact and easy to read format
 172  * The arguments are in network byte order
 173  */
 174 static void
 175 net_ipv4addrport_pr(const in6_addr_t *nipv6addr, in_port_t nport)
 176 {
 177         uint32_t naddr = V4_PART_OF_V6((*nipv6addr));
 178 
 179         mdb_nhconvert(&nport, &nport, sizeof (nport));
 180         mdb_printf("%*I.%-5hu", ADDR_V4_WIDTH, naddr, nport);
 181 }
 182 
 183 /*
 184  * Print an IPv6 address and port number in a compact and easy to read format
 185  * The arguments are in network byte order
 186  */
 187 static void
 188 net_ipv6addrport_pr(const in6_addr_t *naddr, in_port_t nport)
 189 {


 215 net_udp_active(const udp_t *udp)
 216 {
 217         return ((udp->udp_state == TS_IDLE) ||
 218             (udp->udp_state == TS_DATA_XFER));
 219 }
 220 
 221 static int
 222 net_udp_ipv4(const udp_t *udp)
 223 {
 224         return ((udp->udp_connp->conn_ipversion == IPV4_VERSION) ||
 225             (IN6_IS_ADDR_UNSPECIFIED(&udp->udp_connp->conn_laddr_v6) &&
 226             (udp->udp_state <= TS_IDLE)));
 227 }
 228 
 229 static int
 230 net_udp_ipv6(const udp_t *udp)
 231 {
 232         return (udp->udp_connp->conn_ipversion == IPV6_VERSION);
 233 }
 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 
 256 int
 257 sonode_walk_init(mdb_walk_state_t *wsp)
 258 {
 259         if (wsp->walk_addr == NULL) {
 260                 GElf_Sym sym;
 261                 struct socklist *slp;
 262 
 263                 if (mdb_lookup_by_obj("sockfs", "socklist", &sym) == -1) {
 264                         mdb_warn("failed to lookup sockfs`socklist");
 265                         return (WALK_ERR);
 266                 }
 267 
 268                 slp = (struct socklist *)(uintptr_t)sym.st_value;
 269 
 270                 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
 271                     (uintptr_t)&slp->sl_list) == -1) {
 272                         mdb_warn("failed to read address of initial sonode "
 273                             "at %p", &slp->sl_list);
 274                         return (WALK_ERR);
 275                 }


 774                 state = "CONNECTED";
 775         else
 776                 state = "UNKNOWN";
 777 
 778         mdb_printf("%0?p %10s ", (uintptr_t)connp->conn_icmp, state);
 779         if (af == AF_INET) {
 780                 net_ipv4addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
 781                 mdb_printf(" ");
 782                 net_ipv4addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
 783         } else if (af == AF_INET6) {
 784                 net_ipv6addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
 785                 mdb_printf(" ");
 786                 net_ipv6addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
 787         }
 788         mdb_printf(" %5i", ns_to_stackid((uintptr_t)connp->conn_netstack));
 789         mdb_printf(" %4i\n", connp->conn_zoneid);
 790 
 791         return (WALK_NEXT);
 792 }
 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 
 854 /*
 855  * print the address of a unix domain socket
 856  *
 857  * so is the address of a AF_UNIX struct sonode in mdb's address space
 858  * soa is the address of the struct soaddr to print
 859  *
 860  * returns 0 on success, -1 otherwise
 861  */
 862 static int
 863 netstat_unix_name_pr(const struct sotpi_sonode *st, const struct soaddr *soa)
 864 {
 865         const struct sonode *so = &st->st_sonode;
 866         const char none[] = " (none)";
 867 
 868         if ((so->so_state & SS_ISBOUND) && (soa->soa_len != 0)) {
 869                 if (st->st_info.sti_faddr_noxlate) {
 870                         mdb_printf("%-14s ", " (socketpair)");
 871                 } else {
 872                         if (soa->soa_len > sizeof (sa_family_t)) {
 873                                 char addr[MAXPATHLEN + 1];


1305         if ((optP == NULL) || (strcmp("tcp", optP) == 0)) {
1306                 status = netstat_print_common("tcp_conn_cache", IPPROTO_TCP,
1307                     netstat_tcp_cb, cbdata);
1308                 if (status != DCMD_OK)
1309                         goto out;
1310         }
1311 
1312         if ((optP == NULL) || (strcmp("udp", optP) == 0)) {
1313                 status = netstat_print_common("udp_conn_cache", IPPROTO_UDP,
1314                     netstat_udp_cb, cbdata);
1315                 if (status != DCMD_OK)
1316                         goto out;
1317         }
1318 
1319         if ((optP == NULL) || (strcmp("icmp", optP) == 0)) {
1320                 status = netstat_print_common("rawip_conn_cache", IPPROTO_ICMP,
1321                     netstat_icmp_cb, cbdata);
1322                 if (status != DCMD_OK)
1323                         goto out;
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         }
1332 out:
1333         mdb_free(cbdata, sizeof (netstat_cb_data_t));
1334         return (status);
1335 }
1336 
1337 /*
1338  * "::dladm show-bridge" support
1339  */
1340 typedef struct {
1341         uint_t opt_l;
1342         uint_t opt_f;
1343         uint_t opt_t;
1344         const char *name;
1345         clock_t lbolt;
1346         boolean_t found;
1347         uint_t nlinks;
1348         uint_t nfwd;
1349 
1350         /*
1351          * These structures are kept inside the 'args' for allocation reasons.