Message ID | 207f9245d3073d128132389b9d1c529b85133d77.1586953702.git.pabeni@redhat.com |
---|---|
State | Superseded, archived |
Delegated to: | Matthieu Baerts |
Headers | show |
Series | iproute: mptcp support | expand |
Hi Davide, On 15/04/2020 14:28, 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 Thank you for this patch! For the output, should it not be "flags:Mec" without space? If no, I guess it should not contain space for the parsing (flags: Mec) Is there a place where these flags can be explained? > Signed-off-by: Davide Caratti <dcaratti@redhat.com> > --- > misc/ss.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 62 insertions(+) > > diff --git a/misc/ss.c b/misc/ss.c > index 3ef151fb..3fac4be8 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:%d)/%04x(id:%d)", For the id, I guess it is fine with %d (because it's a u8) and not %u? (Just to avoid possible warnings with the compiler ;-) ) Cheers, Matt
On Wed, 2020-04-15 at 18:36 +0200, Matthieu Baerts wrote: > Hi Davide, > > On 15/04/2020 14:28, 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 > > Thank you for this patch! > > For the output, should it not be "flags:Mec" without space? If no, I > guess it should not contain space for the parsing (flags: Mec) yes, there is an extra space after the ':', I will fix it. > Is there a place where these flags can be explained? the place might be ss.8, let me see if I can write something decent. > > Signed-off-by: Davide Caratti <dcaratti@redhat.com> > > --- > > misc/ss.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 62 insertions(+) > > > > diff --git a/misc/ss.c b/misc/ss.c > > index 3ef151fb..3fac4be8 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:%d)/%04x(id:%d)", > > For the id, I guess it is fine with %d (because it's a u8) and not %u? > (Just to avoid possible warnings with the compiler ;-) ) right, or even better %hhu so we don't do the implicit cast.
diff --git a/misc/ss.c b/misc/ss.c index 3ef151fb..3fac4be8 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:%d)/%04x(id:%d)", + 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); + } } }