diff mbox series

[v3,3/4] ss: allow dumping MPTCP subflow information

Message ID 075c9ea7d3368d21972405166574cb7e4efe34ce.1587139599.git.pabeni@redhat.com
State Superseded, archived
Delegated to: Matthieu Baerts
Headers show
Series [v3,1/4] uapi: update linux/mptcp.h | expand

Commit Message

Paolo Abeni April 17, 2020, 4:08 p.m. UTC
From: Davide Caratti <dcaratti@redhat.com>

 [root@f31 packetdrill]# ss -tni

 ESTAB    0        0           192.168.82.247:8080           192.0.2.1:35273
          cubic wscale:7,8 [...] tcp-ulp-mptcp flags:Mec token:0000(id:0)/5f856c60(id:0) seq:b810457db34209a5 sfseq:1 ssnoff:0 maplen:190

Signed-off-by: Davide Caratti <dcaratti@redhat.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
 man/man8/ss.8 |  5 +++++
 misc/ss.c     | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

Comments

Matthieu Baerts April 20, 2020, 4:47 p.m. UTC | #1
Hi Davide,

Thank you for the new version!

On 17/04/2020 18:08, Paolo Abeni wrote:
> From: Davide Caratti <dcaratti@redhat.com>
> 
>   [root@f31 packetdrill]# ss -tni
> 
>   ESTAB    0        0           192.168.82.247:8080           192.0.2.1:35273
>            cubic wscale:7,8 [...] tcp-ulp-mptcp flags:Mec token:0000(id:0)/5f856c60(id:0) seq:b810457db34209a5 sfseq:1 ssnoff:0 maplen:190
> 
> Signed-off-by: Davide Caratti <dcaratti@redhat.com>
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> ---
>   man/man8/ss.8 |  5 +++++
>   misc/ss.c     | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 67 insertions(+)
> 
> diff --git a/man/man8/ss.8 b/man/man8/ss.8
> index 023d771b..c80853f9 100644
> --- a/man/man8/ss.8
> +++ b/man/man8/ss.8
> @@ -261,6 +261,11 @@ the pacing rate and max pacing rate
>   .TP
>   .B rcv_space:<rcv_space>
>   a helper variable for TCP internal auto tuning socket receive buffer
> +.P
> +.TP
> +.B tcp-ulp-mptcp flags:[MmBbJjecv] token:<rem_token(rem_id)/loc_token(loc_id)> seq:<sn> sfseq:<ssn> ssnoff:<off> maplen:<maplen>
> +MPTCP subflow information
> +.P

Do you think we can also add what each of "MmBbJjecv" means? :-)

Cheers,
Matt
Davide Caratti April 20, 2020, 5:10 p.m. UTC | #2
On Mon, 2020-04-20 at 18:47 +0200, Matthieu Baerts wrote:
> Do you think we can also add what each of "MmBbJjecv" means? :-)

... sure, even if it's painful as we are already in a .TP item :) I'm more
worried about what to write as understandable description for 'sfseq'
'ssn_offset', and 'map_valid'.

Can we do this in a separate patch, if it doesn't block the acceptance of
'iproute2' series?
Matthieu Baerts April 22, 2020, 2 p.m. UTC | #3
Hi Davide,

On 20/04/2020 19:10, Davide Caratti wrote:
> On Mon, 2020-04-20 at 18:47 +0200, Matthieu Baerts wrote:
>> Do you think we can also add what each of "MmBbJjecv" means? :-)
> 
> ... sure, even if it's painful as we are already in a .TP item :) I'm more
> worried about what to write as understandable description for 'sfseq'
> 'ssn_offset', and 'map_valid'.

Indeed, when looking at SS man page, I don't know where to explain that.
Or maybe:

   .B tcp-ulp-mptcp flags:[M<remote MP_CAPABLE>m<local 
MP_CAPABLE>J<remote MP_JOIN>j<local MP_JOIN>B<remote backup>b<local 
backup>e<fully established>c<connected>v<map valid>] 
token:<rem_token(rem_id)/loc_token(loc_id)> seq:<sn> sfseq:<ssn> 
ssnoff:<off> maplen:<maplen>

a bit like what is described for "skmem"?
But that's maybe too long?
Or a link to a doc stored somewhere?

> Can we do this in a separate patch, if it doesn't block the acceptance of
> 'iproute2' series?

Sure, I don't want to block this.

Cheers,
Matt
diff mbox series

Patch

diff --git a/man/man8/ss.8 b/man/man8/ss.8
index 023d771b..c80853f9 100644
--- a/man/man8/ss.8
+++ b/man/man8/ss.8
@@ -261,6 +261,11 @@  the pacing rate and max pacing rate
 .TP
 .B rcv_space:<rcv_space>
 a helper variable for TCP internal auto tuning socket receive buffer
+.P
+.TP
+.B tcp-ulp-mptcp flags:[MmBbJjecv] token:<rem_token(rem_id)/loc_token(loc_id)> seq:<sn> sfseq:<ssn> ssnoff:<off> maplen:<maplen>
+MPTCP subflow information
+.P
 .RE
 .TP
 .B \-\-tos
diff --git a/misc/ss.c b/misc/ss.c
index 3ef151fb..ee840149 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -53,6 +53,7 @@ 
 #include <linux/tipc_netlink.h>
 #include <linux/tipc_sockets_diag.h>
 #include <linux/tls.h>
+#include <linux/mptcp.h>
 
 /* AF_VSOCK/PF_VSOCK is only provided since glibc 2.18 */
 #ifndef PF_VSOCK
@@ -2836,6 +2837,59 @@  static void tcp_tls_conf(const char *name, struct rtattr *attr)
 	}
 }
 
+static void mptcp_subflow_info(struct rtattr *tb[])
+{
+	u_int32_t flags = 0;
+
+	if (tb[MPTCP_SUBFLOW_ATTR_FLAGS]) {
+		char caps[32 + 1] = { 0 }, *cap = &caps[0];
+
+		flags = rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_FLAGS]);
+
+		if (flags & MPTCP_SUBFLOW_FLAG_MCAP_REM)
+			*cap++ = 'M';
+		if (flags & MPTCP_SUBFLOW_FLAG_MCAP_LOC)
+			*cap++ = 'm';
+		if (flags & MPTCP_SUBFLOW_FLAG_JOIN_REM)
+			*cap++ = 'J';
+		if (flags & MPTCP_SUBFLOW_FLAG_JOIN_LOC)
+			*cap++ = 'j';
+		if (flags & MPTCP_SUBFLOW_FLAG_BKUP_REM)
+			*cap++ = 'B';
+		if (flags & MPTCP_SUBFLOW_FLAG_BKUP_LOC)
+			*cap++ = 'b';
+		if (flags & MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED)
+			*cap++ = 'e';
+		if (flags & MPTCP_SUBFLOW_FLAG_CONNECTED)
+			*cap++ = 'c';
+		if (flags & MPTCP_SUBFLOW_FLAG_MAPVALID)
+			*cap++ = 'v';
+		if (flags)
+			out(" flags:%s", caps);
+	}
+	if (tb[MPTCP_SUBFLOW_ATTR_TOKEN_REM] &&
+	    tb[MPTCP_SUBFLOW_ATTR_TOKEN_LOC] &&
+	    tb[MPTCP_SUBFLOW_ATTR_ID_REM] &&
+	    tb[MPTCP_SUBFLOW_ATTR_ID_LOC])
+		out(" token:%04x(id:%hhu)/%04x(id:%hhu)",
+		    rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_TOKEN_REM]),
+		    rta_getattr_u8(tb[MPTCP_SUBFLOW_ATTR_ID_REM]),
+		    rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_TOKEN_LOC]),
+		    rta_getattr_u8(tb[MPTCP_SUBFLOW_ATTR_ID_LOC]));
+	if (tb[MPTCP_SUBFLOW_ATTR_MAP_SEQ])
+		out(" seq:%llx",
+		    rta_getattr_u64(tb[MPTCP_SUBFLOW_ATTR_MAP_SEQ]));
+	if (tb[MPTCP_SUBFLOW_ATTR_MAP_SFSEQ])
+		out(" sfseq:%x",
+		    rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_MAP_SFSEQ]));
+	if (tb[MPTCP_SUBFLOW_ATTR_SSN_OFFSET])
+		out(" ssnoff:%x",
+		    rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_SSN_OFFSET]));
+	if (tb[MPTCP_SUBFLOW_ATTR_MAP_DATALEN])
+		out(" maplen:%x",
+		    rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_MAP_DATALEN]));
+}
+
 #define TCPI_HAS_OPT(info, opt) !!(info->tcpi_options & (opt))
 
 static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
@@ -3012,6 +3066,14 @@  static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
 			tcp_tls_conf("rxconf", tlsinfo[TLS_INFO_RXCONF]);
 			tcp_tls_conf("txconf", tlsinfo[TLS_INFO_TXCONF]);
 		}
+		if (ulpinfo[INET_ULP_INFO_MPTCP]) {
+			struct rtattr *sfinfo[MPTCP_SUBFLOW_ATTR_MAX + 1] =
+				{ 0 };
+
+			parse_rtattr_nested(sfinfo, MPTCP_SUBFLOW_ATTR_MAX,
+					    ulpinfo[INET_ULP_INFO_MPTCP]);
+			mptcp_subflow_info(sfinfo);
+		}
 	}
 }