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

@@ -45,10 +45,11 @@
 #include <sys/socketvar.h>
 #include <sys/cred_impl.h>
 #include <inet/udp_impl.h>
 #include <inet/rawip_impl.h>
 #include <inet/mi.h>
+#include <inet/dccp_impl.h>
 #include <fs/sockfs/socktpi_impl.h>
 #include <net/bridge_impl.h>
 #include <io/trill_impl.h>
 #include <sys/mac_impl.h>
 

@@ -140,10 +141,34 @@
         }
         kaddr = (uintptr_t)nss.netstack_modules[NS_UDP];
         return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata));
 }
 
+int
+dccp_stacks_walk_init(mdb_walk_state_t *wsp)
+{
+        if (mdb_layered_walk("netstack", wsp) == -1) {
+                mdb_warn("can't walk 'netstack'");
+                return (WALK_ERR);
+        }
+        return (WALK_NEXT);
+}
+
+int
+dccp_stacks_walk_step(mdb_walk_state_t *wsp)
+{
+        uintptr_t kaddr;
+        netstack_t nss;
+
+        if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) {
+                mdb_warn("can't read netstack at %p", wsp->walk_addr);
+                return (WALK_ERR);
+        }
+        kaddr = (uintptr_t)nss.netstack_modules[NS_DCCP];
+        return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata));
+}
+
 /*
  * Print an IPv4 address and port number in a compact and easy to read format
  * The arguments are in network byte order
  */
 static void

@@ -205,10 +230,31 @@
 net_udp_ipv6(const udp_t *udp)
 {
         return (udp->udp_connp->conn_ipversion == IPV6_VERSION);
 }
 
+static int
+net_dccp_active(const dccp_t *dccp)
+{
+        return ((dccp->dccp_state == TS_IDLE) ||
+            (dccp->dccp_state == TS_DATA_XFER));
+}
+
+static int
+net_dccp_ipv4(const dccp_t *dccp)
+{
+        return ((dccp->dccp_connp->conn_ipversion == IPV4_VERSION) ||
+            (IN6_IS_ADDR_UNSPECIFIED(&dccp->dccp_connp->conn_laddr_v6) &&
+            (dccp->dccp_state <= DCCPS_LISTEN)));
+}
+
+static int
+net_dccp_ipv6(const dccp_t *dccp)
+{
+        return (dccp->dccp_connp->conn_ipversion == IPV6_VERSION);
+}
+
 int
 sonode_walk_init(mdb_walk_state_t *wsp)
 {
         if (wsp->walk_addr == NULL) {
                 GElf_Sym sym;

@@ -743,10 +789,70 @@
         mdb_printf(" %4i\n", connp->conn_zoneid);
 
         return (WALK_NEXT);
 }
 
+static void
+netstat_dccp_verbose_pr(const dccp_t *dccp)
+{
+/* XXX:DCCP
+        mdb_printf("       %5i %08x %08x %5i %08x %08x %5li %5i\n",
+            tcp->tcp_swnd, tcp->tcp_snxt, tcp->tcp_suna, tcp->tcp_rwnd,
+            tcp->tcp_rack, tcp->tcp_rnxt, tcp->tcp_rto, tcp->tcp_mss);
+*/
+}
+
+/*ARGSUSED*/
+static int
+netstat_dccp_cb(uintptr_t kaddr, const void *walk_data, void *cb_data)
+{
+        netstat_cb_data_t *ncb = cb_data;
+        uint_t opts = ncb->opts;
+        int af = ncb->af;
+        uintptr_t dccp_kaddr;
+        conn_t *connp = &ncb->conn;
+        dccp_t dccps, *dccp;
+
+        if (mdb_vread(connp, sizeof (conn_t), kaddr) == -1) {
+                mdb_warn("failed to read conn_t at %p", kaddr);
+                return (WALK_ERR);
+        }
+
+        dccp_kaddr = (uintptr_t)connp->conn_dccp;
+        if (mdb_vread(&dccps, sizeof (dccp_t), dccp_kaddr) == -1) {
+                mdb_warn("failed to read tcp_t at %p", dccp_kaddr);
+                return (WALK_ERR);
+        }
+
+        dccp = &dccps;
+        connp->conn_dccp = dccp;
+        dccp->dccp_connp = connp;
+
+        if (!((opts & NETSTAT_ALL) || net_dccp_active(dccp)) ||
+            (af == AF_INET && !net_dccp_ipv4(dccp)) ||
+            (af == AF_INET6 && !net_dccp_ipv6(dccp))) {
+                return (WALK_NEXT);
+        }
+
+        mdb_printf("%0?p %2i ", dccp_kaddr, dccp->dccp_state);
+        if (af == AF_INET) {
+                net_ipv4addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
+                mdb_printf(" ");
+                net_ipv4addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
+        } else if (af == AF_INET6) {
+                net_ipv6addrport_pr(&connp->conn_laddr_v6, connp->conn_lport);
+                mdb_printf(" ");
+                net_ipv6addrport_pr(&connp->conn_faddr_v6, connp->conn_fport);
+        }
+        mdb_printf(" %5i", ns_to_stackid((uintptr_t)connp->conn_netstack));
+        mdb_printf(" %4i\n", connp->conn_zoneid);
+        if (opts & NETSTAT_VERBOSE)
+                netstat_dccp_verbose_pr(dccp);
+
+        return (WALK_NEXT);
+}
+
 /*
  * print the address of a unix domain socket
  *
  * so is the address of a AF_UNIX struct sonode in mdb's address space
  * soa is the address of the struct soaddr to print

@@ -1214,10 +1320,17 @@
                 status = netstat_print_common("rawip_conn_cache", IPPROTO_ICMP,
                     netstat_icmp_cb, cbdata);
                 if (status != DCMD_OK)
                         goto out;
         }
+
+        if ((optP == NULL) || (strcmp("dccp", optP) == 0)) {
+                status = netstat_print_common("dccp_conn_cache", IPPROTO_DCCP,
+                    netstat_dccp_cb, cbdata);
+                if (status != DCMD_OK)
+                        goto out;
+        }
 out:
         mdb_free(cbdata, sizeof (netstat_cb_data_t));
         return (status);
 }