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):