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,11 +557,11 @@
  * number for this piece.
  */
 static mblk_t *
 tcp_reass(tcp_t *tcp, mblk_t *mp, uint32_t start)
 {
-        uint32_t        end;
+        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,30 +576,30 @@
                 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) {
-                        tcp->tcp_reass_tail = mp;
+                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;
-                        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);
+                        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,11 +2412,11 @@
                 tcp->tcp_last_recv_time = LBOLT_FASTPATH;
         }
 
         flags = (unsigned int)tcpha->tha_flags & 0xFF;
 
-        BUMP_LOCAL(tcp->tcp_ibsegs);
+        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,11 +2657,11 @@
                                                 (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, tcpHCOutSegs);
                                         TCPS_BUMP_MIB(tcps, tcpOutAck);
 
                                         if (!IPCL_IS_NONSTR(connp)) {
                                                 /* Send up T_CONN_CON */
                                                 if (ira->ira_cred != NULL) {

@@ -3046,10 +3046,11 @@
         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,10 +3296,13 @@
                         }
                 }
         } 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,11 +4148,11 @@
                                 }
                                 return;
                         }
                         mp = tcp_ack_mp(tcp);
                         if (mp != NULL) {
-                                BUMP_LOCAL(tcp->tcp_obsegs);
+                                TCPS_BUMP_MIB(tcps, tcpHCOutSegs);
                                 TCPS_BUMP_MIB(tcps, tcpOutAck);
                                 tcp_send_data(tcp, mp);
                         }
                         return;
                 }

@@ -4835,10 +4839,12 @@
                                     (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,11 +4916,11 @@
                  */
                 mp1 = tcp_ack_mp(tcp);
 
                 if (mp1 != NULL) {
                         tcp_send_data(tcp, mp1);
-                        BUMP_LOCAL(tcp->tcp_obsegs);
+                        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,10 +5232,12 @@
         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):