aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavide Caratti <dcaratti@redhat.com>2020-04-23 15:37:09 +0200
committerDavid Ahern <dsahern@gmail.com>2020-04-29 16:44:55 +0000
commit712fdd98c0839540a50baca0fb858c7a72d18031 (patch)
treea227e3134854f099c0fa86374dae2d35294e85ac
parent7e0767cd862bb5dd2d41c41c5e6f55d633f953ea (diff)
downloadiproute2-712fdd98c0839540a50baca0fb858c7a72d18031.tar.gz
ss: allow dumping MPTCP subflow information
[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 Additionally extends ss manpage to describe the new entry layout. Signed-off-by: Davide Caratti <dcaratti@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David Ahern <dsahern@gmail.com>
-rw-r--r--man/man8/ss.85
-rw-r--r--misc/ss.c62
2 files changed, 67 insertions, 0 deletions
diff --git a/man/man8/ss.8 b/man/man8/ss.8
index 023d771b1..c80853f98 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 3ef151fbf..ee840149b 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);
+ }
}
}