[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <ZWivkx3frDwoCX0k@debian>
Date: Thu, 30 Nov 2023 16:51:47 +0100
From: Guillaume Nault <gnault@...hat.com>
To: David Miller <davem@...emloft.net>, Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>, Eric Dumazet <edumazet@...gle.com>
Cc: netdev@...r.kernel.org, David Ahern <dsahern@...nel.org>,
Kuniyuki Iwashima <kuniyu@...zon.com>,
Michal Kubecek <mkubecek@...e.cz>
Subject: Re: [PATCH net-next v3] tcp: Dump bound-only sockets in inet_diag.
On Thu, Nov 30, 2023 at 04:40:51PM +0100, Guillaume Nault wrote:
> Walk the hashinfo->bhash2 table so that inet_diag can dump TCP sockets
> that are bound but haven't yet called connect() or listen().
>
> The code is inspired by the ->lhash2 loop. However there's no manual
> test of the source port, since this kind of filtering is already
> handled by inet_diag_bc_sk(). Also, a maximum of 16 sockets are dumped
> at a time, to avoid running with bh disabled for too long.
>
> There's no TCP state for bound but otherwise inactive sockets. Such
> sockets normally map to TCP_CLOSE. However, "ss -l", which is supposed
> to only dump listening sockets, actually requests the kernel to dump
> sockets in either the TCP_LISTEN or TCP_CLOSE states. To avoid dumping
> bound-only sockets with "ss -l", we therefore need to define a new
> pseudo-state (TCP_BOUND_INACTIVE) that user space will be able to set
> explicitly.
>
> With an IPv4, an IPv6 and an IPv6-only socket, bound respectively to
> 40000, 64000, 60000, an updated version of iproute2 could work as
> follow:
>
> $ ss -t state bound-inactive
> Recv-Q Send-Q Local Address:Port Peer Address:Port Process
> 0 0 0.0.0.0:40000 0.0.0.0:*
> 0 0 [::]:60000 [::]:*
> 0 0 *:64000 *:*
Here's a patch for iproute2-next for easy testing.
I'll submit it formally once the kernel side will be in place.
-------- >8 --------
diff --git a/man/man8/ss.8 b/man/man8/ss.8
index 073e9f03..4ece41fa 100644
--- a/man/man8/ss.8
+++ b/man/man8/ss.8
@@ -40,6 +40,10 @@ established connections) sockets.
.B \-l, \-\-listening
Display only listening sockets (these are omitted by default).
.TP
+.B \-B, \-\-bound-inactive
+Display only TCP bound but inactive (not listening, connecting, etc.) sockets
+(these are omitted by default).
+.TP
.B \-o, \-\-options
Show timer information. For TCP protocol, the output format is:
.RS
@@ -456,6 +460,9 @@ states except for
- opposite to
.B bucket
+.B bound-inactive
+- bound but otherwise inactive sockets (not listening, connecting, etc.)
+
.SH EXPRESSION
.B EXPRESSION
diff --git a/misc/ss.c b/misc/ss.c
index 9438382b..45f01286 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -210,6 +210,8 @@ enum {
SS_LAST_ACK,
SS_LISTEN,
SS_CLOSING,
+ SS_NEW_SYN_RECV,
+ SS_BOUND_INACTIVE,
SS_MAX
};
@@ -1381,6 +1383,8 @@ static void sock_state_print(struct sockstat *s)
[SS_LAST_ACK] = "LAST-ACK",
[SS_LISTEN] = "LISTEN",
[SS_CLOSING] = "CLOSING",
+ [SS_NEW_SYN_RECV] = "NEW-SYN-RECV",
+ [SS_BOUND_INACTIVE] = "BOUND-INACTIVE",
};
switch (s->local.family) {
@@ -5333,6 +5337,7 @@ static void _usage(FILE *dest)
" -r, --resolve resolve host names\n"
" -a, --all display all sockets\n"
" -l, --listening display listening sockets\n"
+" -B, --bound-inactive display TCP bound but inactive sockets\n"
" -o, --options show timer information\n"
" -e, --extended show detailed socket information\n"
" -m, --memory show socket memory usage\n"
@@ -5415,6 +5420,8 @@ static int scan_state(const char *state)
[SS_LAST_ACK] = "last-ack",
[SS_LISTEN] = "listening",
[SS_CLOSING] = "closing",
+ [SS_NEW_SYN_RECV] = "new-syn-recv",
+ [SS_BOUND_INACTIVE] = "bound-inactive",
};
int i;
@@ -5481,6 +5488,7 @@ static const struct option long_opts[] = {
{ "vsock", 0, 0, OPT_VSOCK },
{ "all", 0, 0, 'a' },
{ "listening", 0, 0, 'l' },
+ { "bound-inactive", 0, 0, 'B' },
{ "ipv4", 0, 0, '4' },
{ "ipv6", 0, 0, '6' },
{ "packet", 0, 0, '0' },
@@ -5519,7 +5527,7 @@ int main(int argc, char *argv[])
int state_filter = 0;
while ((ch = getopt_long(argc, argv,
- "dhaletuwxnro460spTbEf:mMiA:D:F:vVzZN:KHSO",
+ "dhalBetuwxnro460spTbEf:mMiA:D:F:vVzZN:KHSO",
long_opts, NULL)) != EOF) {
switch (ch) {
case 'n':
@@ -5584,6 +5592,9 @@ int main(int argc, char *argv[])
case 'l':
state_filter = (1 << SS_LISTEN) | (1 << SS_CLOSE);
break;
+ case 'B':
+ state_filter = 1 << SS_BOUND_INACTIVE;
+ break;
case '4':
filter_af_set(¤t_filter, AF_INET);
break;
Powered by blists - more mailing lists