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;