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/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);
}