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>
*** 557,567 ****
* number for this piece.
*/
static mblk_t *
tcp_reass(tcp_t *tcp, mblk_t *mp, uint32_t start)
{
! uint32_t end;
mblk_t *mp1;
mblk_t *mp2;
mblk_t *next_mp;
uint32_t u1;
tcp_stack_t *tcps = tcp->tcp_tcps;
--- 557,567 ----
* number for this piece.
*/
static mblk_t *
tcp_reass(tcp_t *tcp, mblk_t *mp, uint32_t start)
{
! uint32_t end, bytes;
mblk_t *mp1;
mblk_t *mp2;
mblk_t *next_mp;
uint32_t u1;
tcp_stack_t *tcps = tcp->tcp_tcps;
*** 576,605 ****
if (start == end) {
/* Empty. Blast it. */
freeb(mp);
continue;
}
mp->b_cont = NULL;
TCP_REASS_SET_SEQ(mp, start);
TCP_REASS_SET_END(mp, end);
mp1 = tcp->tcp_reass_tail;
! if (!mp1) {
! tcp->tcp_reass_tail = mp;
tcp->tcp_reass_head = mp;
- TCPS_BUMP_MIB(tcps, tcpInDataUnorderSegs);
- TCPS_UPDATE_MIB(tcps, tcpInDataUnorderBytes,
- end - start);
- continue;
}
- /* New stuff completely beyond tail? */
- if (SEQ_GEQ(start, TCP_REASS_END(mp1))) {
- /* Link it on end. */
- mp1->b_cont = mp;
tcp->tcp_reass_tail = mp;
TCPS_BUMP_MIB(tcps, tcpInDataUnorderSegs);
! TCPS_UPDATE_MIB(tcps, tcpInDataUnorderBytes,
! end - start);
continue;
}
mp1 = tcp->tcp_reass_head;
u1 = TCP_REASS_SEQ(mp1);
/* New stuff at the front? */
--- 576,605 ----
if (start == end) {
/* Empty. Blast it. */
freeb(mp);
continue;
}
+ bytes = end - start;
mp->b_cont = NULL;
TCP_REASS_SET_SEQ(mp, start);
TCP_REASS_SET_END(mp, end);
mp1 = tcp->tcp_reass_tail;
! if (mp1 == NULL || SEQ_GEQ(start, TCP_REASS_END(mp1))) {
! if (mp1 != NULL) {
! /*
! * New stuff is beyond the tail; link it on the
! * end.
! */
! mp1->b_cont = mp;
! } else {
tcp->tcp_reass_head = mp;
}
tcp->tcp_reass_tail = mp;
TCPS_BUMP_MIB(tcps, tcpInDataUnorderSegs);
! TCPS_UPDATE_MIB(tcps, tcpInDataUnorderBytes, bytes);
! tcp->tcp_cs.tcp_in_data_unorder_segs++;
! tcp->tcp_cs.tcp_in_data_unorder_bytes += bytes;
continue;
}
mp1 = tcp->tcp_reass_head;
u1 = TCP_REASS_SEQ(mp1);
/* New stuff at the front? */
*** 2412,2422 ****
tcp->tcp_last_recv_time = LBOLT_FASTPATH;
}
flags = (unsigned int)tcpha->tha_flags & 0xFF;
! BUMP_LOCAL(tcp->tcp_ibsegs);
DTRACE_PROBE2(tcp__trace__recv, mblk_t *, mp, tcp_t *, tcp);
if ((flags & TH_URG) && sqp != NULL) {
/*
* TCP can't handle urgent pointers that arrive before
--- 2412,2422 ----
tcp->tcp_last_recv_time = LBOLT_FASTPATH;
}
flags = (unsigned int)tcpha->tha_flags & 0xFF;
! TCPS_BUMP_MIB(tcps, tcpHCInSegs);
DTRACE_PROBE2(tcp__trace__recv, mblk_t *, mp, tcp_t *, tcp);
if ((flags & TH_URG) && sqp != NULL) {
/*
* TCP can't handle urgent pointers that arrive before
*** 2657,2667 ****
(void) TCP_TIMER_CANCEL(tcp,
tcp->tcp_ack_tid);
tcp->tcp_ack_tid = 0;
}
tcp_send_data(tcp, ack_mp);
! BUMP_LOCAL(tcp->tcp_obsegs);
TCPS_BUMP_MIB(tcps, tcpOutAck);
if (!IPCL_IS_NONSTR(connp)) {
/* Send up T_CONN_CON */
if (ira->ira_cred != NULL) {
--- 2657,2667 ----
(void) TCP_TIMER_CANCEL(tcp,
tcp->tcp_ack_tid);
tcp->tcp_ack_tid = 0;
}
tcp_send_data(tcp, ack_mp);
! TCPS_BUMP_MIB(tcps, tcpHCOutSegs);
TCPS_BUMP_MIB(tcps, tcpOutAck);
if (!IPCL_IS_NONSTR(connp)) {
/* Send up T_CONN_CON */
if (ira->ira_cred != NULL) {
*** 3046,3055 ****
--- 3046,3056 ----
if (rgap < 0) {
mblk_t *mp2;
if (tcp->tcp_rwnd == 0) {
TCPS_BUMP_MIB(tcps, tcpInWinProbe);
+ tcp->tcp_cs.tcp_in_zwnd_probes++;
} else {
TCPS_BUMP_MIB(tcps, tcpInDataPastWinSegs);
TCPS_UPDATE_MIB(tcps, tcpInDataPastWinBytes, -rgap);
}
*** 3295,3304 ****
--- 3296,3308 ----
}
}
} else if (seg_len > 0) {
TCPS_BUMP_MIB(tcps, tcpInDataInorderSegs);
TCPS_UPDATE_MIB(tcps, tcpInDataInorderBytes, seg_len);
+ tcp->tcp_cs.tcp_in_data_inorder_segs++;
+ tcp->tcp_cs.tcp_in_data_inorder_bytes += seg_len;
+
/*
* If an out of order FIN was received before, and the seq
* num and len of the new segment match that of the FIN,
* put the FIN flag back in.
*/
*** 4144,4154 ****
}
return;
}
mp = tcp_ack_mp(tcp);
if (mp != NULL) {
! BUMP_LOCAL(tcp->tcp_obsegs);
TCPS_BUMP_MIB(tcps, tcpOutAck);
tcp_send_data(tcp, mp);
}
return;
}
--- 4148,4158 ----
}
return;
}
mp = tcp_ack_mp(tcp);
if (mp != NULL) {
! TCPS_BUMP_MIB(tcps, tcpHCOutSegs);
TCPS_BUMP_MIB(tcps, tcpOutAck);
tcp_send_data(tcp, mp);
}
return;
}
*** 4835,4844 ****
--- 4839,4850 ----
(mblk_t *)(intptr_t)gethrtime();
tcp->tcp_csuna = tcp->tcp_snxt;
TCPS_BUMP_MIB(tcps, tcpRetransSegs);
TCPS_UPDATE_MIB(tcps, tcpRetransBytes,
snd_size);
+ tcp->tcp_cs.tcp_out_retrans_segs++;
+ tcp->tcp_cs.tcp_out_retrans_bytes += snd_size;
tcp_send_data(tcp, mp1);
}
}
if (flags & TH_NEED_SACK_REXMIT) {
tcp_sack_rexmit(tcp, &flags);
*** 4910,4920 ****
*/
mp1 = tcp_ack_mp(tcp);
if (mp1 != NULL) {
tcp_send_data(tcp, mp1);
! BUMP_LOCAL(tcp->tcp_obsegs);
TCPS_BUMP_MIB(tcps, tcpOutAck);
}
if (tcp->tcp_ack_tid != 0) {
(void) TCP_TIMER_CANCEL(tcp, tcp->tcp_ack_tid);
tcp->tcp_ack_tid = 0;
--- 4916,4926 ----
*/
mp1 = tcp_ack_mp(tcp);
if (mp1 != NULL) {
tcp_send_data(tcp, mp1);
! TCPS_BUMP_MIB(tcps, tcpHCOutSegs);
TCPS_BUMP_MIB(tcps, tcpOutAck);
}
if (tcp->tcp_ack_tid != 0) {
(void) TCP_TIMER_CANCEL(tcp, tcp->tcp_ack_tid);
tcp->tcp_ack_tid = 0;
*** 5226,5235 ****
--- 5232,5243 ----
hrtime_t sv = tcp->tcp_rtt_sd;
tcp_stack_t *tcps = tcp->tcp_tcps;
TCPS_BUMP_MIB(tcps, tcpRttUpdate);
tcp->tcp_rtt_update++;
+ tcp->tcp_rtt_sum += m;
+ tcp->tcp_rtt_cnt++;
/* tcp_rtt_sa is not 0 means this is a new sample. */
if (sa != 0) {
/*
* Update average estimator (see section 2.3 of RFC6298):