Add Matthieu as main maintainer, but also the MPTCP Linux mailing list to reach more people interested by MPTCP when submitting patches on this subject. Signed-off-by: Matthieu Baerts (NGI0) --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 51833ec1..2d13c752 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -42,6 +42,13 @@ devlink M: Jiri Pirko F: devlink/* +Multipath TCP - mptcp +M: Matthieu Baerts +L: mptcp@lists.linux.dev +F: ip/ipmptcp.c +F: man/man8/ip-mptcp.8 +K: mptcp + netkit M: Daniel Borkmann M: Nikolay Aleksandrov -- 2.51.0 - 'signaled' -> 'signalled' - 'a implicit' -> 'an implicit' Signed-off-by: Matthieu Baerts (NGI0) --- man/man8/ip-mptcp.8 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/man/man8/ip-mptcp.8 b/man/man8/ip-mptcp.8 index e4a55f6c..500dc671 100644 --- a/man/man8/ip-mptcp.8 +++ b/man/man8/ip-mptcp.8 @@ -156,7 +156,7 @@ ID. .TP .BR signal -The endpoint will be announced/signaled to each peer via an MPTCP ADD_ADDR +The endpoint will be announced/signalled to each peer via an MPTCP ADD_ADDR sub-option. Typically, a server would be responsible for this. Upon reception of an ADD_ADDR sub-option, the other peer, typically the client side, can try to create additional subflows, see @@ -207,7 +207,7 @@ is then optional. .BR implicit In some scenarios, an MPTCP .BR subflow -can use a local address mapped by a implicit endpoint created by the +can use a local address mapped by an implicit endpoint created by the in-kernel path manager. Once set, the implicit flag cannot be removed, but other flags can be added to the endpoint. Implicit endpoints cannot be created from user-space. -- 2.51.0 This new endpoint type has been recently added to the kernel in v6.18 [1]. It will be used to create new subflows from the associated address to additional addresses announced by the other peer. This will be done if allowed by the MPTCP limits, and if the associated address is not already being used by another subflow from the same MPTCP connection. Note that the fullmesh flag takes precedence over the laminar one. Without any of these two flags, the path-manager will create new subflows to additional addresses announced by the other peer by selecting the source address from the routing tables, which is harder to configure if the announced address is not known in advance. The support of the new flag is easy: simply by adding it in the mptcp_addr_flag_names array. The usage menu and the manual now references the new endpoint type. The new corresponding counter has also been added in ss. Link: https://git.kernel.org/torvalds/c/539f6b9de39e [1] Signed-off-by: Matthieu Baerts (NGI0) --- ip/ipmptcp.c | 3 ++- man/man8/ip-mptcp.8 | 16 ++++++++++++++++ misc/ss.c | 2 ++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ip/ipmptcp.c b/ip/ipmptcp.c index 2415cac8..2908b69e 100644 --- a/ip/ipmptcp.c +++ b/ip/ipmptcp.c @@ -32,7 +32,7 @@ static void usage(void) " ip mptcp limits show\n" " ip mptcp monitor\n" "FLAG-LIST := [ FLAG-LIST ] FLAG\n" - "FLAG := [ signal | subflow | backup | fullmesh ]\n" + "FLAG := [ signal | subflow | laminar | backup | fullmesh ]\n" "CHANGE-OPT := [ backup | nobackup | fullmesh | nofullmesh ]\n"); exit(-1); @@ -59,6 +59,7 @@ static const struct { { "backup", MPTCP_PM_ADDR_FLAG_BACKUP }, { "fullmesh", MPTCP_PM_ADDR_FLAG_FULLMESH }, { "implicit", MPTCP_PM_ADDR_FLAG_IMPLICIT }, + { "laminar", MPTCP_PM_ADDR_FLAG_LAMINAR }, { "nobackup", MPTCP_PM_ADDR_FLAG_NONE }, { "nofullmesh", MPTCP_PM_ADDR_FLAG_NONE } }; diff --git a/man/man8/ip-mptcp.8 b/man/man8/ip-mptcp.8 index 500dc671..c03935dd 100644 --- a/man/man8/ip-mptcp.8 +++ b/man/man8/ip-mptcp.8 @@ -66,6 +66,8 @@ ip-mptcp \- MPTCP path manager configuration .RB "|" .B subflow .RB "|" +.B laminar +.RB "|" .B backup .RB "|" .B fullmesh @@ -169,6 +171,20 @@ path manager will try to create an additional subflow using this endpoint as the source address after the MPTCP connection is established. A client would typically do this. +.TP +.BR laminar +The endpoint will be used to create new subflows from the associated address to +additional addresses announced by the other peer. This will be done if allowed +by the MPTCP limits, and if the associated address is not already being used by +another subflow from the same MPTCP connection. Note that the +.BR fullmesh +flag takes precedence over the +.BR laminar +one. Without any of these two flags, the path-manager will create new subflows +to additional addresses announced by the other peer by selecting the source +address from the routing tables, which is harder to configure if the announced +address is not known in advance. + .TP .BR backup If this is a diff --git a/misc/ss.c b/misc/ss.c index 989e168a..b3566f6b 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -3308,6 +3308,8 @@ static void mptcp_stats_print(struct mptcp_info *s) out(" bytes_acked:%llu", s->mptcpi_bytes_acked); if (s->mptcpi_subflows_total) out(" subflows_total:%u", s->mptcpi_subflows_total); + if (s->mptcpi_endp_laminar_max) + out(" endp_laminar_max:%u", s->mptcpi_endp_laminar_max); if (s->mptcpi_last_data_sent) out(" last_data_sent:%u", s->mptcpi_last_data_sent); if (s->mptcpi_last_data_recv) -- 2.51.0 This info has been added a while ago in the kernel [1], but it was not displayed in 'ip monitor'. Now, 'server_side' is displayed if the attribute is defined and set to true. It looks better to do that instead of showing server_side=0. Note that since v6.18 [2], this attribute is only defined if it is set to true. Link: https://git.kernel.org/torvalds/c/41b3c69bf941 [1] Link: https://git.kernel.org/torvalds/c/c9809f03c158 [2] Signed-off-by: Matthieu Baerts (NGI0) --- ip/ipmptcp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ip/ipmptcp.c b/ip/ipmptcp.c index 2908b69e..aaacc0a5 100644 --- a/ip/ipmptcp.c +++ b/ip/ipmptcp.c @@ -536,6 +536,8 @@ static int mptcp_monitor_msg(struct rtnl_ctrl_data *ctrl, printf(" reset_reason=%u", rta_getattr_u32(tb[MPTCP_ATTR_RESET_REASON])); if (tb[MPTCP_ATTR_RESET_FLAGS]) printf(" reset_flags=0x%x", rta_getattr_u32(tb[MPTCP_ATTR_RESET_FLAGS])); + if (tb[MPTCP_ATTR_SERVER_SIDE] && rta_getattr_u8(tb[MPTCP_ATTR_SERVER_SIDE])) + printf(" server_side"); puts(""); out: -- 2.51.0 Until recently, the 'flags' attribute was not used. This has recently been changed with the introduction of the 'deny_join_id0' flag [1]. This flag is set when a connection is created and the other peer set the 'C' flag in the MP_CAPABLE packets [2]. This flag can be set to tell the other side that the peer will not accept extra subflows requests sent to its initial IP address and port: typically set by a server behind a legacy Layer 4 load balancer. Now, when this flag is set, "deny_join_id0" will be printed instead of "flags=1". Unknown remaining flags will be printed in hexadecimal at the end, e.g. "flags=0x2". Link: https://git.kernel.org/torvalds/c/2293c57484ae [1] Link: https://datatracker.ietf.org/doc/html/rfc8684#section-3.1-20.6 [2] Signed-off-by: Matthieu Baerts (NGI0) --- ip/ipmptcp.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ip/ipmptcp.c b/ip/ipmptcp.c index aaacc0a5..01f6906f 100644 --- a/ip/ipmptcp.c +++ b/ip/ipmptcp.c @@ -477,6 +477,7 @@ static int mptcp_monitor_msg(struct rtnl_ctrl_data *ctrl, const struct genlmsghdr *ghdr = NLMSG_DATA(n); struct rtattr *tb[MPTCP_ATTR_MAX + 1]; int len = n->nlmsg_len; + __u16 flags = 0; len -= NLMSG_LENGTH(GENL_HDRLEN); if (len < 0) @@ -526,8 +527,6 @@ static int mptcp_monitor_msg(struct rtnl_ctrl_data *ctrl, printf(" backup=%u", rta_getattr_u8(tb[MPTCP_ATTR_BACKUP])); if (tb[MPTCP_ATTR_ERROR]) printf(" error=%u", rta_getattr_u8(tb[MPTCP_ATTR_ERROR])); - if (tb[MPTCP_ATTR_FLAGS]) - printf(" flags=%x", rta_getattr_u16(tb[MPTCP_ATTR_FLAGS])); if (tb[MPTCP_ATTR_TIMEOUT]) printf(" timeout=%u", rta_getattr_u32(tb[MPTCP_ATTR_TIMEOUT])); if (tb[MPTCP_ATTR_IF_IDX]) @@ -539,6 +538,15 @@ static int mptcp_monitor_msg(struct rtnl_ctrl_data *ctrl, if (tb[MPTCP_ATTR_SERVER_SIDE] && rta_getattr_u8(tb[MPTCP_ATTR_SERVER_SIDE])) printf(" server_side"); + if (tb[MPTCP_ATTR_FLAGS]) + flags = rta_getattr_u16(tb[MPTCP_ATTR_FLAGS]); + if (flags & MPTCP_PM_EV_FLAG_DENY_JOIN_ID0) { + flags &= ~MPTCP_PM_EV_FLAG_DENY_JOIN_ID0; + printf(" deny_join_id0"); + } + if (flags) /* remaining bits */ + printf(" flags=0x%x", flags); + puts(""); out: fflush(stdout); -- 2.51.0 In the v6.18 kernel, the 'server side' attribute has been deprecated [1] in favour of the 'server side' flag [2]. Support both: first checking the new flag, then the old attribute to continue supporting older kernels. Link: https://git.kernel.org/torvalds/c/c8bc168f5f3d [1] Link: https://git.kernel.org/torvalds/c/3d7ae91107b8 [2] Signed-off-by: Matthieu Baerts (NGI0) --- ip/ipmptcp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ip/ipmptcp.c b/ip/ipmptcp.c index 01f6906f..acd008f3 100644 --- a/ip/ipmptcp.c +++ b/ip/ipmptcp.c @@ -535,11 +535,14 @@ static int mptcp_monitor_msg(struct rtnl_ctrl_data *ctrl, printf(" reset_reason=%u", rta_getattr_u32(tb[MPTCP_ATTR_RESET_REASON])); if (tb[MPTCP_ATTR_RESET_FLAGS]) printf(" reset_flags=0x%x", rta_getattr_u32(tb[MPTCP_ATTR_RESET_FLAGS])); - if (tb[MPTCP_ATTR_SERVER_SIDE] && rta_getattr_u8(tb[MPTCP_ATTR_SERVER_SIDE])) - printf(" server_side"); if (tb[MPTCP_ATTR_FLAGS]) flags = rta_getattr_u16(tb[MPTCP_ATTR_FLAGS]); + if ((flags & MPTCP_PM_EV_FLAG_SERVER_SIDE) || + (tb[MPTCP_ATTR_SERVER_SIDE] && rta_getattr_u8(tb[MPTCP_ATTR_SERVER_SIDE]))) { + flags &= ~MPTCP_PM_EV_FLAG_SERVER_SIDE; + printf(" server_side"); + } if (flags & MPTCP_PM_EV_FLAG_DENY_JOIN_ID0) { flags &= ~MPTCP_PM_EV_FLAG_DENY_JOIN_ID0; printf(" deny_join_id0"); -- 2.51.0