git: 1e2a0cef6bf1 - stable/13 - tcptw: count how many times a tcptw was actually useful

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Thu, 13 Jan 2022 21:20:58 UTC
The branch stable/13 has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=1e2a0cef6bf10db00f230f33ee14293f5b00e894

commit 1e2a0cef6bf10db00f230f33ee14293f5b00e894
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2022-01-13 21:19:40 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2022-01-13 21:19:40 +0000

    tcptw: count how many times a tcptw was actually useful
    
    This will allow a sysadmin to lower net.inet.tcp.msl and
    see how long tcptw are actually useful.
    
    (cherry picked from commit 71d2d5adfe18e80e5f8afeb4f86ef69be1aaad81)
---
 sys/netinet/tcp_timewait.c |  3 +++
 sys/netinet/tcp_var.h      |  7 ++++++-
 usr.bin/netstat/inet.c     | 14 ++++++++++++--
 3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index b62386ddca05..0ed3856b68a4 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -443,6 +443,7 @@ tcp_twcheck(struct inpcb *inp, struct tcpopt *to, struct tcphdr *th,
 	 */
 	if ((thflags & TH_SYN) && SEQ_GT(th->th_seq, tw->rcv_nxt)) {
 		tcp_twclose(tw, 0);
+		TCPSTAT_INC(tcps_tw_recycles);
 		return (1);
 	}
 
@@ -462,6 +463,7 @@ tcp_twcheck(struct inpcb *inp, struct tcpopt *to, struct tcphdr *th,
 			    th->th_seq+tlen, (tcp_seq)0, TH_RST|TH_ACK);
 		}
 		INP_WUNLOCK(inp);
+		TCPSTAT_INC(tcps_tw_resets);
 		return (0);
 	}
 
@@ -498,6 +500,7 @@ tcp_twcheck(struct inpcb *inp, struct tcpopt *to, struct tcphdr *th,
 	    th->th_seq != tw->rcv_nxt || th->th_ack != tw->snd_nxt) {
 		TCP_PROBE5(receive, NULL, NULL, m, NULL, th);
 		tcp_twrespond(tw, TH_ACK);
+		TCPSTAT_INC(tcps_tw_responds);
 		goto dropnoprobe;
 	}
 drop:
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 323472f96cfb..86783c0eae38 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -700,7 +700,12 @@ struct	tcpstat {
 	uint64_t tcps_tunneled_pkts;	/* Packets encap's in UDP received */
 	uint64_t tcps_tunneled_errs;	/* Packets that had errors that were UDP encaped */
 
-	uint64_t _pad[10];		/* 6 UTO, 6 TBD */
+	/* TCPS_TIME_WAIT usage stats */
+	uint64_t tcps_tw_recycles;	/* Times time-wait was recycled. */
+	uint64_t tcps_tw_resets;	/* Times time-wait sent a reset. */
+	uint64_t tcps_tw_responds;	/* Times time-wait sent a valid ack. */
+
+	uint64_t _pad[7];
 };
 
 #define	tcps_rcvmemdrop	tcps_rcvreassfull	/* compat */
diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c
index b46f5c92e808..ec8128e19baf 100644
--- a/usr.bin/netstat/inet.c
+++ b/usr.bin/netstat/inet.c
@@ -849,13 +849,23 @@ tcp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 	    "{N:/Path MTU discovery black hole detection min MSS activation%s}\n");
 	p(tcps_pmtud_blackhole_failed, "\t{:pmtud-failed/%ju} "
 	    "{N:/Path MTU discovery black hole detection failure%s}\n");
+
+	xo_close_container("pmtud");
+	xo_open_container("tw");
+
+	p(tcps_tw_responds, "\t{:tw_responds/%ju} "
+	    "{N:/time%s connection in TIME-WAIT responded with ACK}\n");
+	p(tcps_tw_recycles, "\t{:tw_recycles/%ju} "
+	    "{N:/time%s connection in TIME-WAIT was actively recycled}\n");
+	p(tcps_tw_resets, "\t{:tw_resets/%ju} "
+	    "{N:/time%s connection in TIME-WAIT responded with RST}\n");
+
+	xo_close_container("tw");
  #undef p
  #undef p1a
  #undef p2
  #undef p2a
  #undef p3
-	xo_close_container("pmtud");
-
 
 	xo_open_container("TCP connection count by state");
 	xo_emit("{T:/TCP connection count by state}:\n");