Index: sys/netinet/tcp_subr.c =================================================================== --- sys/netinet/tcp_subr.c +++ sys/netinet/tcp_subr.c @@ -3438,6 +3438,13 @@ xt->t_sndzerowin = tp->t_sndzerowin; xt->t_sndrexmitpack = tp->t_sndrexmitpack; xt->t_rcvoopack = tp->t_rcvoopack; + xt->t_rcv_wnd = tp->rcv_wnd; + xt->t_snd_wnd = tp->snd_wnd; + xt->t_snd_cwnd = tp->snd_cwnd; + xt->t_snd_ssthresh = tp->snd_ssthresh; + xt->t_maxseg = tp->t_maxseg; + xt->xt_ecn = (tp->t_flags2 & TF2_ECN_PERMIT) ? 1 : 0 + + (tp->t_flags2 & TF2_ACE_PERMIT) ? 2 : 0; now = getsbinuptime(); #define COPYTIMER(ttt) do { \ Index: sys/netinet/tcp_var.h =================================================================== --- sys/netinet/tcp_var.h +++ sys/netinet/tcp_var.h @@ -768,7 +768,13 @@ int32_t tt_2msl; /* (s) */ int32_t tt_delack; /* (s) */ int32_t t_logstate; /* (3) */ - int32_t spare32[32]; + uint32_t t_snd_cwnd; /* (s) */ + uint32_t t_snd_ssthresh; /* (s) */ + uint32_t t_maxseg; /* (s) */ + uint32_t t_rcv_wnd; /* (s) */ + uint32_t t_snd_wnd; /* (s) */ + uint32_t xt_ecn; /* (s) */ + int32_t spare32[26]; } __aligned(8); #ifdef _KERNEL Index: usr.bin/netstat/inet.c =================================================================== --- usr.bin/netstat/inet.c +++ usr.bin/netstat/inet.c @@ -341,9 +341,18 @@ xo_emit(" {T:/%8.8s} {T:/%5.5s}", "flowid", "ftype"); } + if (cflag) { + xo_emit(" {T:/%10.10s} {T:/%10.10s}" + " {T:/%5.5s} {T:/%3.3s}", + "Cong-win", + "ssthresh", + "MSS", + "ECN"); + } if (Cflag) - xo_emit(" {T:/%-*.*s}", TCP_CA_NAME_MAX, - TCP_CA_NAME_MAX, "CC"); + xo_emit(" {T:/%-*.*s} {T:/%-*.*s}", TCP_CA_NAME_MAX, + TCP_CA_NAME_MAX, TCP_FUNCTION_NAME_LEN_MAX, + TCP_FUNCTION_NAME_LEN_MAX, "CC", "Stack"); if (Pflag) xo_emit(" {T:/%s}", "Log ID"); xo_emit("\n"); @@ -518,9 +527,24 @@ inp->inp_flowtype); } if (istcp) { + if (cflag) + xo_emit(" {:snd-cwnd/%10lu}" + " {:snd-ssthresh/%10lu}" + " {:t-maxseg/%5u} {:ecn/%3s}", + tp->t_snd_cwnd, tp->t_snd_ssthresh, + tp->t_maxseg, + (tp->t_state >= TCPS_ESTABLISHED ? + (tp->xt_ecn > 0 ? + (tp->xt_ecn == 1 ? + "ecn" : "ace") + : "off") + : "n/a")); if (Cflag) - xo_emit(" {:cc/%-*.*s}", TCP_CA_NAME_MAX, - TCP_CA_NAME_MAX, tp->xt_cc); + xo_emit(" {:cc/%-*.*s} {:stack/%-*.*s}", + TCP_CA_NAME_MAX, TCP_CA_NAME_MAX, + TCP_FUNCTION_NAME_LEN_MAX, + TCP_FUNCTION_NAME_LEN_MAX, + tp->xt_cc, tp->xt_stack); if (Pflag) xo_emit(" {:log-id/%s}", tp->xt_logid[0] == '\0' ? Index: usr.bin/netstat/main.c =================================================================== --- usr.bin/netstat/main.c +++ usr.bin/netstat/main.c @@ -205,7 +205,8 @@ int aflag; /* show all sockets (including servers) */ static int Bflag; /* show information about bpf consumers */ int bflag; /* show i/f total bytes in/out */ -int Cflag; /* show congestion control */ +int cflag; /* show TCP congestion control info */ +int Cflag; /* show congestion control algo and TCP stack */ int dflag; /* show i/f dropped packets */ int gflag; /* show group (multicast) routing or stats */ int hflag; /* show counters in human readable format */ @@ -250,7 +251,7 @@ if (argc < 0) exit(EXIT_FAILURE); - while ((ch = getopt(argc, argv, "46AaBbCdF:f:ghI:iLlM:mN:noPp:Qq:RrSTsuWw:xz")) + while ((ch = getopt(argc, argv, "46AaBbCcdF:f:ghI:iLlM:mN:noPp:Qq:RrSTsuWw:xz")) != -1) switch(ch) { case '4': @@ -279,6 +280,9 @@ case 'b': bflag = 1; break; + case 'c': + cflag = 1; + break; case 'C': Cflag = 1; break; @@ -874,7 +878,7 @@ usage(void) { (void)xo_error("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", -"usage: netstat [-46AaLnRSTWx] [-f protocol_family | -p protocol]\n" +"usage: netstat [-46AaCcLnRSTWx] [-f protocol_family | -p protocol]\n" " [-M core] [-N system]", " netstat -i | -I interface [-46abdhnW] [-f address_family]\n" " [-M core] [-N system]", Index: usr.bin/netstat/netstat.h =================================================================== --- usr.bin/netstat/netstat.h +++ usr.bin/netstat/netstat.h @@ -41,7 +41,8 @@ extern int Aflag; /* show addresses of protocol control block */ extern int aflag; /* show all sockets (including servers) */ extern int bflag; /* show i/f total bytes in/out */ -extern int Cflag; /* show congestion control */ +extern int cflag; /* show congestion control stats */ +extern int Cflag; /* show congestion control algo and stack */ extern int dflag; /* show i/f dropped packets */ extern int gflag; /* show group (multicast) routing or stats */ extern int hflag; /* show counters in human readable format */ Index: usr.bin/netstat/netstat.1 =================================================================== --- usr.bin/netstat/netstat.1 +++ usr.bin/netstat/netstat.1 @@ -28,7 +28,7 @@ .\" @(#)netstat.1 8.8 (Berkeley) 4/18/94 .\" $FreeBSD$ .\" -.Dd September 13, 2020 +.Dd September 21, 2020 .Dt NETSTAT 1 .Os .Sh NAME @@ -172,8 +172,10 @@ .It Fl a Show the state of all sockets; normally sockets used by server processes are not shown. +.It Fl c +Show diagnostic information of the TCP congestion control state. .It Fl C -Show the congestion control of TCP sockets. +Show the congestion control algorithm and TCP Stack used by a TCP socket. .It Fl L Show the size of the various listen queues. The first count shows the number of unaccepted connections,