tcp/sack: Add more statistics
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 27 Mar 2012 01:54:55 +0000 (09:54 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 28 Mar 2012 03:25:55 +0000 (11:25 +0800)
sys/netinet/tcp_input.c
sys/netinet/tcp_output.c
sys/netinet/tcp_sack.c
sys/netinet/tcp_var.h

index 248bd72..1d03220 100644 (file)
@@ -2692,6 +2692,7 @@ tcp_dooptions(struct tcpopt *to, u_char *cp, int cnt, boolean_t is_syn)
                                         * Invalid SACK block; discard all
                                         * SACK blocks
                                         */
+                                       tcpstat.tcps_rcvbadsackopt++;
                                        to->to_nsackblocks = 0;
                                        to->to_sackblocks = NULL;
                                        to->to_flags &= ~TOF_SACK;
index 58f4d19..ef137ef 100644 (file)
@@ -711,6 +711,10 @@ send:
                else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
                        if (tp->snd_nxt == tp->snd_una)
                                tp->snd_max_rexmt = tp->snd_max;
+                       if (nsacked) {
+                               tcpstat.tcps_sndsackrtopack++;
+                               tcpstat.tcps_sndsackrtobyte += len;
+                       }
                        tcpstat.tcps_sndrexmitpack++;
                        tcpstat.tcps_sndrexmitbyte += len;
                } else {
index 85633bd..e65154c 100644 (file)
@@ -249,12 +249,17 @@ tcp_sack_add_blocks(struct tcpcb *tp, struct tcpopt *to)
                struct raw_sackblock *newsackblock = &blocks[i];
 
                /* don't accept bad SACK blocks */
-               if (SEQ_GT(newsackblock->rblk_end, tp->snd_max))
+               if (SEQ_GT(newsackblock->rblk_end, tp->snd_max)) {
+                       tcpstat.tcps_rcvbadsackopt++;
                        break;          /* skip all other blocks */
+               }
+               tcpstat.tcps_sacksbupdate++;
 
                sb = alloc_sackblock();
-               if (sb == NULL)         /* do some sort of cleanup? XXX */
+               if (sb == NULL) {       /* do some sort of cleanup? XXX */
+                       tcpstat.tcps_sacksbfailed++;
                        break;          /* just skip rest of blocks */
+               }
                sb->sblk_start = newsackblock->rblk_start;
                sb->sblk_end = newsackblock->rblk_end;
                if (TAILQ_EMPTY(&scb->sackblocks)) {
@@ -297,6 +302,7 @@ insert_block(struct scoreboard *scb, struct sackblock *newblock)
                 * Or, go other way and free all blocks if we hit this limit.
                 */
                free_sackblock(newblock);
+               tcpstat.tcps_sacksboverflow++;
                return;
        }
        KASSERT(scb->nblocks < MAXSAVEDBLOCKS,
@@ -315,6 +321,7 @@ insert_block(struct scoreboard *scb, struct sackblock *newblock)
                        if (SEQ_GT(newblock->sblk_end, sb->sblk_end))
                                sb->sblk_end = newblock->sblk_end;
                        free_sackblock(newblock);
+                       tcpstat.tcps_sacksbreused++;
                } else {
                        workingblock = newblock;
                        TAILQ_INSERT_AFTER(&scb->sackblocks, sb, newblock,
@@ -692,6 +699,11 @@ tcp_sack_fill_report(struct tcpcb *tp, u_char *opt, u_int *plen)
            TCPOLEN_SACK_ALIGNED + TCPOLEN_SACK_BLOCK,
            ("no room for SACK header and one block: optlen %d", optlen));
 
+       if (tp->t_flags & TF_DUPSEG)
+               tcpstat.tcps_snddsackopt++;
+       else
+               tcpstat.tcps_sndsackopt++;
+
        olp = lp++;
        optlen += TCPOLEN_SACK_ALIGNED;
 
index b9ea866..de718d6 100644 (file)
@@ -324,6 +324,8 @@ struct tcp_stats {
        u_long  tcps_sndbyte;           /* data bytes sent */
        u_long  tcps_sndrexmitpack;     /* data packets retransmitted */
        u_long  tcps_sndrexmitbyte;     /* data bytes retransmitted */
+       u_long  tcps_sndsackrtopack;    /* packets sent by SACK after RTO */
+       u_long  tcps_sndsackrtobyte;    /* bytes sent by SACK after RTO */
        u_long  tcps_sndfastrexmit;     /* Fast Retransmissions */
        u_long  tcps_sndearlyrexmit;    /* early Fast Retransmissions */
        u_long  tcps_sndlimited;        /* Limited Transmit packets */
@@ -343,6 +345,8 @@ struct tcp_stats {
        u_long  tcps_sndsackbyte;       /* bytes sent by SACK recovery */
        u_long  tcps_snduna3;           /* re-retransmit snd_una on 3 new seg */
        u_long  tcps_snduna1;           /* re-retransmit snd_una on 1 new seg */
+       u_long  tcps_sndsackopt;        /* SACK options sent */
+       u_long  tcps_snddsackopt;       /* D-SACK options sent */
 
        u_long  tcps_rcvtotal;          /* total packets received */
        u_long  tcps_rcvpack;           /* packets received in sequence */
@@ -380,6 +384,12 @@ struct tcp_stats {
        u_long  tcps_badsyn;            /* bogus SYN, e.g. premature ACK */
        u_long  tcps_mturesent;         /* resends due to MTU discovery */
        u_long  tcps_listendrop;        /* listen queue overflows */
+       u_long  tcps_rcvbadsackopt;     /* rcvd illegal SACK options */
+
+       u_long  tcps_sacksbupdate;      /* times SACK scoreboard updated */
+       u_long  tcps_sacksboverflow;    /* times SACK scoreboard overflowed */
+       u_long  tcps_sacksbreused;      /* times SACK sb-block reused */
+       u_long  tcps_sacksbfailed;      /* times SACK sb update failed */
 
        u_long  tcps_sc_added;          /* entry added to syncache */
        u_long  tcps_sc_retransmitted;  /* syncache entry was retransmitted */