Extend netstat to display TCP stack and detailed congestion state

Adding the "-c" option used to show detailed per-connection
congestion control state for TCP sessions.

This is one summary patch, which adds the relevant variables into
xtcpcb. As previous "spare" space is used, these changes are ABI
compatible.

Reviewed by:	tuexen
MFC after:	2 weeks
Sponsored by:	NetApp, Inc.
Differential Revision:	https://reviews.freebsd.org/D26518
This commit is contained in:
Richard Scheffenegger 2020-10-09 10:07:41 +00:00
parent f15e9afb1f
commit 0e5e35e322
4 changed files with 67 additions and 10 deletions

View File

@ -85,6 +85,8 @@ __FBSDID("$FreeBSD$");
#include "netstat.h"
#include "nl_defs.h"
#define max(a, b) (((a) > (b)) ? (a) : (b))
#ifdef INET
static void inetprint(const char *, struct in_addr *, int, const char *, int,
const int);
@ -204,6 +206,7 @@ protopr(u_long off, const char *name, int af1, int proto)
struct xinpcb *inp;
struct xinpgen *xig, *oxig;
struct xsocket *so;
int fnamelen, cnamelen;
istcp = 0;
switch (proto) {
@ -236,6 +239,28 @@ protopr(u_long off, const char *name, int af1, int proto)
if (!pcblist_sysctl(proto, name, &buf))
return;
if (cflag || Cflag) {
fnamelen = strlen("Stack");
cnamelen = strlen("CC");
oxig = xig = (struct xinpgen *)buf;
for (xig = (struct xinpgen*)((char *)xig + xig->xig_len);
xig->xig_len > sizeof(struct xinpgen);
xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
if (istcp) {
tp = (struct xtcpcb *)xig;
inp = &tp->xt_inp;
} else {
continue;
}
if (so->xso_protocol != proto)
continue;
if (inp->inp_gencnt > oxig->xig_gen)
continue;
fnamelen = max(fnamelen, (int)strlen(tp->xt_stack));
cnamelen = max(cnamelen, (int)strlen(tp->xt_cc));
}
}
oxig = xig = (struct xinpgen *)buf;
for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
xig->xig_len > sizeof(struct xinpgen);
@ -341,9 +366,19 @@ protopr(u_long off, const char *name, int af1, int proto)
xo_emit(" {T:/%8.8s} {T:/%5.5s}",
"flowid", "ftype");
}
if (cflag) {
xo_emit(" {T:/%-*.*s}",
fnamelen, fnamelen, "Stack");
}
if (Cflag)
xo_emit(" {T:/%-*.*s}", TCP_CA_NAME_MAX,
TCP_CA_NAME_MAX, "CC");
xo_emit(" {T:/%-*.*s} {T:/%10.10s}"
" {T:/%10.10s} {T:/%5.5s}"
" {T:/%3.3s}", cnamelen,
cnamelen, "CC",
"cwin",
"ssthresh",
"MSS",
"ECN");
if (Pflag)
xo_emit(" {T:/%s}", "Log ID");
xo_emit("\n");
@ -518,9 +553,24 @@ protopr(u_long off, const char *name, int af1, int proto)
inp->inp_flowtype);
}
if (istcp) {
if (cflag)
xo_emit(" {:stack/%-*.*s}",
fnamelen, fnamelen, tp->xt_stack);
if (Cflag)
xo_emit(" {:cc/%-*.*s}", TCP_CA_NAME_MAX,
TCP_CA_NAME_MAX, tp->xt_cc);
xo_emit(" {:cc/%-*.*s}"
" {:snd-cwnd/%10lu}"
" {:snd-ssthresh/%10lu}"
" {:t-maxseg/%5u} {:ecn/%3s}",
cnamelen, cnamelen, tp->xt_cc,
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 (Pflag)
xo_emit(" {:log-id/%s}",
tp->xt_logid[0] == '\0' ?

View File

@ -205,7 +205,8 @@ int Aflag; /* show addresses of protocol control block */
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 stack */
int Cflag; /* show congestion control algo and vars */
int dflag; /* show i/f dropped packets */
int gflag; /* show group (multicast) routing or stats */
int hflag; /* show counters in human readable format */
@ -251,7 +252,7 @@ main(int argc, char *argv[])
if (argc < 0)
exit(EXIT_FAILURE);
while ((ch = getopt(argc, argv, "46AaBbCdF:f:ghI:iLlM:mN:nOoPp:Qq:RrSTsuWw:xz"))
while ((ch = getopt(argc, argv, "46AaBbCcdF:f:ghI:iLlM:mN:nOoPp:Qq:RrSTsuWw:xz"))
!= -1)
switch(ch) {
case '4':
@ -280,6 +281,9 @@ main(int argc, char *argv[])
case 'b':
bflag = 1;
break;
case 'c':
cflag = 1;
break;
case 'C':
Cflag = 1;
break;
@ -886,7 +890,7 @@ static void
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]",

View File

@ -28,7 +28,7 @@
.\" @(#)netstat.1 8.8 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
.Dd September 13, 2020
.Dd September 25, 2020
.Dt NETSTAT 1
.Os
.Sh NAME
@ -172,8 +172,10 @@ associated with a socket; used for debugging.
.It Fl a
Show the state of all sockets;
normally sockets used by server processes are not shown.
.It Fl c
Show the used TCP stack for each session.
.It Fl C
Show the congestion control of TCP sockets.
Show the congestion control algorithm and diagnostic information of TCP sockets.
.It Fl L
Show the size of the various listen queues.
The first count shows the number of unaccepted connections,

View File

@ -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 */