Print this page
11547 Want connstat(1M) command to display per-connection TCP statistics
Portions contributed by: Cody Peter Mello <cody.mello@joyent.com>
Portions contributed by: Ahmed G <ahmedg@delphix.com>
Reviewed by: Jason King <jason.king@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Dan McDonald <danmcd@joyent.com>

*** 20,29 **** --- 20,30 ---- */ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, Joyent Inc. All rights reserved. + * Copyright (c) 2015, 2016 by Delphix. All rights reserved. */ #include <sys/types.h> #include <sys/tihdr.h> #include <sys/policy.h>
*** 84,93 **** --- 85,138 ---- default: return (0); } } + static void + tcp_set_conninfo(tcp_t *tcp, struct tcpConnEntryInfo_s *tcei, boolean_t ispriv) + { + /* Don't want just anybody seeing these... */ + if (ispriv) { + tcei->ce_snxt = tcp->tcp_snxt; + tcei->ce_suna = tcp->tcp_suna; + tcei->ce_rnxt = tcp->tcp_rnxt; + tcei->ce_rack = tcp->tcp_rack; + } else { + /* + * Netstat, unfortunately, uses this to get send/receive queue + * sizes. How to fix? Why not compute the difference only? + */ + tcei->ce_snxt = tcp->tcp_snxt - tcp->tcp_suna; + tcei->ce_suna = 0; + tcei->ce_rnxt = tcp->tcp_rnxt - tcp->tcp_rack; + tcei->ce_rack = 0; + } + + tcei->ce_in_data_inorder_bytes = tcp->tcp_cs.tcp_in_data_inorder_bytes; + tcei->ce_in_data_inorder_segs = tcp->tcp_cs.tcp_in_data_inorder_segs; + tcei->ce_in_data_unorder_bytes = tcp->tcp_cs.tcp_in_data_unorder_bytes; + tcei->ce_in_data_unorder_segs = tcp->tcp_cs.tcp_in_data_unorder_segs; + tcei->ce_in_zwnd_probes = tcp->tcp_cs.tcp_in_zwnd_probes; + + tcei->ce_out_data_bytes = tcp->tcp_cs.tcp_out_data_bytes; + tcei->ce_out_data_segs = tcp->tcp_cs.tcp_out_data_segs; + tcei->ce_out_retrans_bytes = tcp->tcp_cs.tcp_out_retrans_bytes; + tcei->ce_out_retrans_segs = tcp->tcp_cs.tcp_out_retrans_segs; + tcei->ce_out_zwnd_probes = tcp->tcp_cs.tcp_out_zwnd_probes; + + tcei->ce_unsent = tcp->tcp_unsent; + tcei->ce_swnd = tcp->tcp_swnd; + tcei->ce_cwnd = tcp->tcp_cwnd; + tcei->ce_rwnd = tcp->tcp_rwnd; + tcei->ce_rto = tcp->tcp_rto; + tcei->ce_mss = tcp->tcp_mss; + tcei->ce_state = tcp->tcp_state; + tcei->ce_rtt_sa = NSEC2USEC(tcp->tcp_rtt_sa >> 3); + tcei->ce_rtt_sum = NSEC2USEC(tcp->tcp_rtt_sum); + tcei->ce_rtt_cnt = tcp->tcp_rtt_cnt; + } + /* * Return SNMP stuff in buffer in mpdata. */ mblk_t * tcp_snmp_get(queue_t *q, mblk_t *mpctl, boolean_t legacy_req)
*** 181,195 **** if (connp->conn_zoneid != zoneid) continue; /* not in this zone */ tcp = connp->conn_tcp; - TCPS_UPDATE_MIB(tcps, tcpHCInSegs, tcp->tcp_ibsegs); - tcp->tcp_ibsegs = 0; - TCPS_UPDATE_MIB(tcps, tcpHCOutSegs, tcp->tcp_obsegs); - tcp->tcp_obsegs = 0; - tce6.tcp6ConnState = tce.tcpConnState = tcp_snmp_state(tcp); if (tce.tcpConnState == MIB2_TCP_established || tce.tcpConnState == MIB2_TCP_closeWait) BUMP_MIB(&tcp_mib, tcpCurrEstab); --- 226,235 ----
*** 241,279 **** tce6.tcp6ConnIfIndex = connp->conn_ixa->ixa_scopeid; } else { tce6.tcp6ConnIfIndex = connp->conn_bound_if; } - /* Don't want just anybody seeing these... */ - if (ispriv) { - tce6.tcp6ConnEntryInfo.ce_snxt = - tcp->tcp_snxt; - tce6.tcp6ConnEntryInfo.ce_suna = - tcp->tcp_suna; - tce6.tcp6ConnEntryInfo.ce_rnxt = - tcp->tcp_rnxt; - tce6.tcp6ConnEntryInfo.ce_rack = - tcp->tcp_rack; - } else { - /* - * Netstat, unfortunately, uses this to - * get send/receive queue sizes. How to fix? - * Why not compute the difference only? - */ - tce6.tcp6ConnEntryInfo.ce_snxt = - tcp->tcp_snxt - tcp->tcp_suna; - tce6.tcp6ConnEntryInfo.ce_suna = 0; - tce6.tcp6ConnEntryInfo.ce_rnxt = - tcp->tcp_rnxt - tcp->tcp_rack; - tce6.tcp6ConnEntryInfo.ce_rack = 0; - } ! tce6.tcp6ConnEntryInfo.ce_swnd = tcp->tcp_swnd; ! tce6.tcp6ConnEntryInfo.ce_rwnd = tcp->tcp_rwnd; ! tce6.tcp6ConnEntryInfo.ce_rto = tcp->tcp_rto; ! tce6.tcp6ConnEntryInfo.ce_mss = tcp->tcp_mss; ! tce6.tcp6ConnEntryInfo.ce_state = tcp->tcp_state; tce6.tcp6ConnCreationProcess = (connp->conn_cpid < 0) ? MIB2_UNKNOWN_PROCESS : connp->conn_cpid; tce6.tcp6ConnCreationTime = connp->conn_open_time; --- 281,293 ---- tce6.tcp6ConnIfIndex = connp->conn_ixa->ixa_scopeid; } else { tce6.tcp6ConnIfIndex = connp->conn_bound_if; } ! tcp_set_conninfo(tcp, &tce6.tcp6ConnEntryInfo, ! ispriv); tce6.tcp6ConnCreationProcess = (connp->conn_cpid < 0) ? MIB2_UNKNOWN_PROCESS : connp->conn_cpid; tce6.tcp6ConnCreationTime = connp->conn_open_time;
*** 305,345 **** tce.tcpConnLocalAddress = connp->conn_laddr_v4; } tce.tcpConnLocalPort = ntohs(connp->conn_lport); tce.tcpConnRemPort = ntohs(connp->conn_fport); - /* Don't want just anybody seeing these... */ - if (ispriv) { - tce.tcpConnEntryInfo.ce_snxt = - tcp->tcp_snxt; - tce.tcpConnEntryInfo.ce_suna = - tcp->tcp_suna; - tce.tcpConnEntryInfo.ce_rnxt = - tcp->tcp_rnxt; - tce.tcpConnEntryInfo.ce_rack = - tcp->tcp_rack; - } else { - /* - * Netstat, unfortunately, uses this to - * get send/receive queue sizes. How - * to fix? - * Why not compute the difference only? - */ - tce.tcpConnEntryInfo.ce_snxt = - tcp->tcp_snxt - tcp->tcp_suna; - tce.tcpConnEntryInfo.ce_suna = 0; - tce.tcpConnEntryInfo.ce_rnxt = - tcp->tcp_rnxt - tcp->tcp_rack; - tce.tcpConnEntryInfo.ce_rack = 0; - } ! tce.tcpConnEntryInfo.ce_swnd = tcp->tcp_swnd; ! tce.tcpConnEntryInfo.ce_rwnd = tcp->tcp_rwnd; ! tce.tcpConnEntryInfo.ce_rto = tcp->tcp_rto; ! tce.tcpConnEntryInfo.ce_mss = tcp->tcp_mss; ! tce.tcpConnEntryInfo.ce_state = ! tcp->tcp_state; tce.tcpConnCreationProcess = (connp->conn_cpid < 0) ? MIB2_UNKNOWN_PROCESS : connp->conn_cpid; --- 319,331 ---- tce.tcpConnLocalAddress = connp->conn_laddr_v4; } tce.tcpConnLocalPort = ntohs(connp->conn_lport); tce.tcpConnRemPort = ntohs(connp->conn_fport); ! tcp_set_conninfo(tcp, &tce.tcpConnEntryInfo, ! ispriv); tce.tcpConnCreationProcess = (connp->conn_cpid < 0) ? MIB2_UNKNOWN_PROCESS : connp->conn_cpid;