git: 31537ea583c0 - main - tcpdrop: allow TCP connections to be filtered by cc-algo

From: Michael Tuexen <tuexen_at_FreeBSD.org>
Date: Sat, 04 Dec 2021 15:09:49 UTC
The branch main has been updated by tuexen:

URL: https://cgit.FreeBSD.org/src/commit/?id=31537ea583c0965fe22498d52831ced4b4f4fc5e

commit 31537ea583c0965fe22498d52831ced4b4f4fc5e
Author:     Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2021-12-04 14:00:05 +0000
Commit:     Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2021-12-04 14:02:15 +0000

    tcpdrop: allow TCP connections to be filtered by cc-algo
    
    In addition to filtering by stack and state, allow filtering
    by the congestion control module used.  Choose the command line
    options to be consistent with the ones of sockstat.
    
    MFC after:      1 week
    Sponsored by:   Netflix, Inc.
---
 usr.sbin/tcpdrop/tcpdrop.8 | 45 ++++++++++++++++++++++++++++++++++-----------
 usr.sbin/tcpdrop/tcpdrop.c | 28 +++++++++++++++++++++-------
 2 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/usr.sbin/tcpdrop/tcpdrop.8 b/usr.sbin/tcpdrop/tcpdrop.8
index c58388b3eab8..2549a2ec0ad7 100644
--- a/usr.sbin/tcpdrop/tcpdrop.8
+++ b/usr.sbin/tcpdrop/tcpdrop.8
@@ -34,13 +34,18 @@
 .Fl a
 .Nm tcpdrop
 .Op Fl l
-.Fl S Ar stack
+.Fl C Ar cc-algo
+.Op Fl S Ar stack
+.Op Fl s Ar state
 .Nm tcpdrop
 .Op Fl l
-.Fl s Ar state
+.Op Fl C Ar cc-algo
+.Fl S Ar stack
+.Op Fl s Ar state
 .Nm tcpdrop
 .Op Fl l
-.Fl S Ar stack
+.Op Fl C Ar cc-algo
+.Op Fl S Ar stack
 .Fl s Ar state
 .Sh DESCRIPTION
 The
@@ -54,6 +59,13 @@ is specified then
 will attempt to drop all TCP connections.
 .Pp
 If
+.Fl C Ar cc-algo
+is specified then
+.Nm
+will attempt to drop all connections using the TCP congestion control algorithm
+.Ar cc-algo .
+.Pp
+If
 .Fl S Ar stack
 is specified then
 .Nm
@@ -78,16 +90,20 @@ is one of
 .Dv FIN_WAIT_2 , or
 .Dv TIME_WAIT .
 .Pp
-If
-.Fl S Ar stack
+If multiple of
+.Fl C Ar cc-algo ,
+.Fl S Ar stack ,
 and
 .Fl s Ar state
 are specified,
 .Nm
-will attempt to drop all TCP connections being in the state
-.Ar state
+will attempt to drop all TCP connections using the congestion control algorithm
+.Ar cc-algo ,
+being in the state
+.Ar state ,
 and using the TCP stack
-.Ar stack .
+.Ar stack ,
+if specified.
 Since TCP connections in the
 .Dv TIME_WAIT
 state are not tied to any TCP stack, using the option
@@ -102,6 +118,7 @@ The
 .Fl l
 flag may be given in addition to the
 .Fl a ,
+.Fl C ,
 .Fl S ,
 or
 .Fl s
@@ -110,6 +127,7 @@ connections one at a time.
 .Pp
 If none of the
 .Fl a ,
+.Fl C ,
 .Fl S ,
 or
 .Fl s
@@ -154,6 +172,11 @@ port 22, the port used by
 # tcpdrop -l -a | grep -vw 22 | sh
 .Ed
 .Pp
+To drop all TCP connections using the new-reno congestion control algorithm use:
+.Bd -literal -offset indent
+# tcpdrop -C new-reno
+.Ed
+.Pp
 The following command will drop all connections using the TCP stack
 rack:
 .Bd -literal -offset indent
@@ -165,10 +188,10 @@ To drop all TCP connections in the LAST_ACK state use:
 # tcpdrop -s LAST_ACK
 .Ed
 .Pp
-To drop all TCP connections using the TCP stack rack and being in the
-LAST_ACK state use:
+To drop all TCP connections using the congestion control algorithm new-reno and
+the TCP stack rack and being in the LAST_ACK state use:
 .Bd -literal -offset indent
-# tcpdrop -S rack -s LAST_ACK
+# tcpdrop -C new-reno -S rack -s LAST_ACK
 .Ed
 .Sh SEE ALSO
 .Xr netstat 1 ,
diff --git a/usr.sbin/tcpdrop/tcpdrop.c b/usr.sbin/tcpdrop/tcpdrop.c
index f05c027362b8..aa28f494e24d 100644
--- a/usr.sbin/tcpdrop/tcpdrop.c
+++ b/usr.sbin/tcpdrop/tcpdrop.c
@@ -54,7 +54,7 @@ static char *findport(const char *);
 static struct xinpgen *getxpcblist(const char *);
 static void sockinfo(const struct sockaddr *, struct host_service *);
 static bool tcpdrop(const struct sockaddr *, const struct sockaddr *);
-static bool tcpdropall(const char *, int);
+static bool tcpdropall(const char *, const char *, int);
 static bool tcpdropbyname(const char *, const char *, const char *,
     const char *);
 static bool tcpdropconn(const struct in_conninfo *);
@@ -67,20 +67,26 @@ int
 main(int argc, char *argv[])
 {
 	char stack[TCP_FUNCTION_NAME_LEN_MAX];
+	char ca_name[TCP_CA_NAME_MAX];
 	char *lport, *fport;
 	bool dropall, dropspecific;
 	int ch, state;
 
 	dropall = false;
 	dropspecific = false;
+	ca_name[0] = '\0';
 	stack[0] = '\0';
 	state = -1;
 
-	while ((ch = getopt(argc, argv, "alS:s:")) != -1) {
+	while ((ch = getopt(argc, argv, "aC:lS:s:")) != -1) {
 		switch (ch) {
 		case 'a':
 			dropall = true;
 			break;
+		case 'C':
+			dropspecific = true;
+			strlcpy(ca_name, optarg, sizeof(ca_name));
+			break;
 		case 'l':
 			tcpdrop_list_commands = true;
 			break;
@@ -111,7 +117,7 @@ main(int argc, char *argv[])
 	if (dropall || dropspecific) {
 		if (argc != 0)
 			usage();
-		if (!tcpdropall(stack, state))
+		if (!tcpdropall(ca_name, stack, state))
 			exit(1);
 		exit(0);
 	}
@@ -223,7 +229,7 @@ tcpdrop(const struct sockaddr *lsa, const struct sockaddr *fsa)
 }
 
 static bool
-tcpdropall(const char *stack, int state)
+tcpdropall(const char *ca_name, const char *stack, int state)
 {
 	struct xinpgen *head, *xinp;
 	struct xtcpcb *xtp;
@@ -259,6 +265,14 @@ tcpdropall(const char *stack, int state)
 		if ((state != -1) && (xtp->t_state != state))
 			continue;
 
+		/*
+		 * If requested, skip sockets not having the requested
+		 * congestion control algorithm.
+		 */
+		if (ca_name[0] != '\0' &&
+		    strncmp(xtp->xt_cc, ca_name, TCP_CA_NAME_MAX))
+			continue;
+
 		/* If requested, skip sockets not having the requested stack. */
 		if (stack[0] != '\0' &&
 		    strncmp(xtp->xt_stack, stack, TCP_FUNCTION_NAME_LEN_MAX))
@@ -379,8 +393,8 @@ usage(void)
 "       tcpdrop local-address:local-port foreign-address:foreign-port\n"
 "       tcpdrop local-address.local-port foreign-address.foreign-port\n"
 "       tcpdrop [-l] -a\n"
-"       tcpdrop [-l] -S stack\n"
-"       tcpdrop [-l] -s state\n"
-"       tcpdrop [-l] -S stack -s state\n");
+"       tcpdrop [-l] -C cc-algo [-S stack] [-s state]\n"
+"       tcpdrop [-l] [-C cc-algo] -S stack [-s state]\n"
+"       tcpdrop [-l] [-C cc-algo] [-S stack] -s state\n");
 	exit(1);
 }