tcp: snmp stats for Fast Open, SYN rtx, and data pkts
authorYuchung Cheng <ycheng@google.com>
Mon, 3 Mar 2014 20:31:36 +0000 (12:31 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 3 Mar 2014 20:58:03 +0000 (15:58 -0500)
Add the following snmp stats:

TCPFastOpenActiveFail: Fast Open attempts (SYN/data) failed beacuse
the remote does not accept it or the attempts timed out.

TCPSynRetrans: number of SYN and SYN/ACK retransmits to break down
retransmissions into SYN, fast-retransmits, timeout retransmits, etc.

TCPOrigDataSent: number of outgoing packets with original data (excluding
retransmission but including data-in-SYN). This counter is different from
TcpOutSegs because TcpOutSegs also tracks pure ACKs. TCPOrigDataSent is
more useful to track the TCP retransmission rate.

Change TCPFastOpenActive to track only successful Fast Opens to be symmetric to
TCPFastOpenPassive.

Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Nandita Dukkipati <nanditad@google.com>
Signed-off-by: Lawrence Brakmo <brakmo@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/uapi/linux/snmp.h
net/ipv4/proc.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/tcp_timer.c
net/ipv6/tcp_ipv6.c

index 8d64a7e5d3713f0179144dea5f3bb11dfbea7ced..df40137f33dd48c0b23dad1f5cd13c357c91c031 100644 (file)
@@ -252,6 +252,7 @@ enum
        LINUX_MIB_TCPCHALLENGEACK,              /* TCPChallengeACK */
        LINUX_MIB_TCPSYNCHALLENGE,              /* TCPSYNChallenge */
        LINUX_MIB_TCPFASTOPENACTIVE,            /* TCPFastOpenActive */
+       LINUX_MIB_TCPFASTOPENACTIVEFAIL,        /* TCPFastOpenActiveFail */
        LINUX_MIB_TCPFASTOPENPASSIVE,           /* TCPFastOpenPassive*/
        LINUX_MIB_TCPFASTOPENPASSIVEFAIL,       /* TCPFastOpenPassiveFail */
        LINUX_MIB_TCPFASTOPENLISTENOVERFLOW,    /* TCPFastOpenListenOverflow */
@@ -262,6 +263,8 @@ enum
        LINUX_MIB_TCPFROMZEROWINDOWADV,         /* TCPFromZeroWindowAdv */
        LINUX_MIB_TCPTOZEROWINDOWADV,           /* TCPToZeroWindowAdv */
        LINUX_MIB_TCPWANTZEROWINDOWADV,         /* TCPWantZeroWindowAdv */
+       LINUX_MIB_TCPSYNRETRANS,                /* TCPSynRetrans */
+       LINUX_MIB_TCPORIGDATASENT,              /* TCPOrigDataSent */
        __LINUX_MIB_MAX
 };
 
index 99d2e9b6fac9a87e199f70022ed38867d934072d..ad737fad6d8b82dec74fab1260015e539647271d 100644 (file)
@@ -273,6 +273,7 @@ static const struct snmp_mib snmp4_net_list[] = {
        SNMP_MIB_ITEM("TCPChallengeACK", LINUX_MIB_TCPCHALLENGEACK),
        SNMP_MIB_ITEM("TCPSYNChallenge", LINUX_MIB_TCPSYNCHALLENGE),
        SNMP_MIB_ITEM("TCPFastOpenActive", LINUX_MIB_TCPFASTOPENACTIVE),
+       SNMP_MIB_ITEM("TCPFastOpenActiveFail", LINUX_MIB_TCPFASTOPENACTIVEFAIL),
        SNMP_MIB_ITEM("TCPFastOpenPassive", LINUX_MIB_TCPFASTOPENPASSIVE),
        SNMP_MIB_ITEM("TCPFastOpenPassiveFail", LINUX_MIB_TCPFASTOPENPASSIVEFAIL),
        SNMP_MIB_ITEM("TCPFastOpenListenOverflow", LINUX_MIB_TCPFASTOPENLISTENOVERFLOW),
@@ -283,6 +284,8 @@ static const struct snmp_mib snmp4_net_list[] = {
        SNMP_MIB_ITEM("TCPFromZeroWindowAdv", LINUX_MIB_TCPFROMZEROWINDOWADV),
        SNMP_MIB_ITEM("TCPToZeroWindowAdv", LINUX_MIB_TCPTOZEROWINDOWADV),
        SNMP_MIB_ITEM("TCPWantZeroWindowAdv", LINUX_MIB_TCPWANTZEROWINDOWADV),
+       SNMP_MIB_ITEM("TCPSynRetrans", LINUX_MIB_TCPSYNRETRANS),
+       SNMP_MIB_ITEM("TCPOrigDataSent", LINUX_MIB_TCPORIGDATASENT),
        SNMP_MIB_SENTINEL
 };
 
index 23a41d978fadac791416cc16d1d697b0fbbd981f..6e4809389cbf766643e2cb62f78e7dcb7c52809b 100644 (file)
@@ -5393,9 +5393,12 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
                                break;
                }
                tcp_rearm_rto(sk);
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFASTOPENACTIVEFAIL);
                return true;
        }
        tp->syn_data_acked = tp->syn_data;
+       if (tp->syn_data_acked)
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFASTOPENACTIVE);
        return false;
 }
 
index 17c0fb172fba77938ac029cab6930826f193be6c..c4f1d9a76c443a8f0beca90317f088769502960f 100644 (file)
@@ -854,8 +854,10 @@ static int tcp_v4_rtx_synack(struct sock *sk, struct request_sock *req)
 {
        int res = tcp_v4_send_synack(sk, NULL, req, 0);
 
-       if (!res)
+       if (!res) {
                TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNRETRANS);
+       }
        return res;
 }
 
index bf38b1fb63ab69eb86a177d44d17ba0b908be51e..aaa68f5b105586156431ce0c9ce0ac3ec2759c9b 100644 (file)
@@ -86,6 +86,9 @@ static void tcp_event_new_data_sent(struct sock *sk, const struct sk_buff *skb)
            icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
                tcp_rearm_rto(sk);
        }
+
+       NET_ADD_STATS_BH(sock_net(sk), LINUX_MIB_TCPORIGDATASENT,
+                        tcp_skb_pcount(skb));
 }
 
 /* SND.NXT, if window was not shrunk.
@@ -2433,7 +2436,8 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
        if (err == 0) {
                /* Update global TCP statistics. */
                TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS);
-
+               if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)
+                       NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNRETRANS);
                tp->total_retrans++;
 
 #if FASTRETRANS_DEBUG > 0
@@ -2958,7 +2962,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
 
        if (tcp_transmit_skb(sk, syn_data, 0, sk->sk_allocation) == 0) {
                tp->syn_data = (fo->copied > 0);
-               NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENACTIVE);
+               NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPORIGDATASENT);
                goto done;
        }
        syn_data = NULL;
index 64f0354c84c7a8956230f2794b4dcb56331d98fc..286227abed10656a5efeb7026a9741ad1b6c6207 100644 (file)
@@ -165,6 +165,9 @@ static int tcp_write_timeout(struct sock *sk)
                        dst_negative_advice(sk);
                        if (tp->syn_fastopen || tp->syn_data)
                                tcp_fastopen_cache_set(sk, 0, NULL, true);
+                       if (tp->syn_data)
+                               NET_INC_STATS_BH(sock_net(sk),
+                                                LINUX_MIB_TCPFASTOPENACTIVEFAIL);
                }
                retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
                syn_set = true;
index 889079b2ea852f237dea495cc66a63c968037b6d..3277680186b4894a62f3791f3fcca9aa7ed99a23 100644 (file)
@@ -501,8 +501,10 @@ static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req)
        int res;
 
        res = tcp_v6_send_synack(sk, NULL, &fl6, req, 0);
-       if (!res)
+       if (!res) {
                TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNRETRANS);
+       }
        return res;
 }