Skip to contentSkip to conversation

mptcp: fix recent failed backports (20250919)

PATCH Applied Matthieu Baerts (NGI0) 2 participants 5 messages Sep 19, 2025 – Sep 21, 2025

Subsystems (4)
lore
Share & tools
lore

Matthieu Baerts (NGI0)

author maintainer
#0 lore raw

cover mptcp: fix recent failed backports (20250919)

The following patches could not be applied without conflicts in this tree:

- 2293c57484ae ("mptcp: pm: nl: announce deny-join-id0 flag")
- 24733e193a0d ("selftests: mptcp: userspace pm: validate deny-join-id0 flag")

Conflicts have been resolved, and documented in each patch.

Matthieu Baerts (NGI0) (2):
mptcp: pm: nl: announce deny-join-id0 flag
selftests: mptcp: userspace pm: validate deny-join-id0 flag

 include/uapi/linux/mptcp.h                        |  6 ++++--
 net/mptcp/pm_netlink.c                            |  7 +++++++
 tools/testing/selftests/net/mptcp/pm_nl_ctl.c     |  7 +++++++
 tools/testing/selftests/net/mptcp/userspace_pm.sh | 14 ++++++++++++--
 4 files changed, 30 insertions(+), 4 deletions(-)
Signature · 1 line
2.51.0
author maintainer
#1 lore raw

PATCH 1/2 mptcp: pm: nl: announce deny-join-id0 flag

commit 2293c57484ae64c9a3c847c8807db8c26a3a4d41 upstream.

During the connection establishment, a peer can tell the other one that it cannot establish new subflows to the initial IP address and port by setting the 'C' flag [1]. Doing so makes sense when the sender is behind a strict NAT, operating behind a legacy Layer 4 load balancer, or using anycast IP address for example.

When this 'C' flag is set, the path-managers must then not try to establish new subflows to the other peer's initial IP address and port. The in-kernel PM has access to this info, but the userspace PM didn't.

The RFC8684 [1] is strict about that:

(...) therefore the receiver MUST NOT try to open any additional subflows toward this address and port.

So it is important to tell the userspace about that as it is responsible for the respect of this flag.

When a new connection is created and established, the Netlink events now contain the existing but not currently used 'flags' attribute. When MPTCP_PM_EV_FLAG_DENY_JOIN_ID0 is set, it means no other subflows to the initial IP address and port -- info that are also part of the event -- can be established.

[ Conflicts in mptcp_pm.yaml, and mptcp_pm.h, because these files have
been added later by commit bc8aeb2045e2 ("Documentation: netlink: add a YAML spec for mptcp"), and commit 9d1ed17f93ce ("uapi: mptcp: use header file generated from YAML spec"), which are not in this version. Applying the same modifications, but only in mptcp.h. Conflict in pm_netlink.c, because of a difference in the context, introduced by commit b9f4554356f6 ("mptcp: annotate lockless access for token"), which is not in this version. ]

---
 include/uapi/linux/mptcp.h | 6 ++++--
 net/mptcp/pm_netlink.c     | 7 +++++++
 2 files changed, 11 insertions(+), 2 deletions(-)
include/uapi/linux/mptcp.h +4 -2
index dfe19bf13f4c..dacc7af2ea1e 100644
@@ -81,6 +81,8 @@ enum {
 
 #define MPTCP_PM_ADDR_ATTR_MAX (__MPTCP_PM_ADDR_ATTR_MAX - 1)
 
+#define MPTCP_PM_EV_FLAG_DENY_JOIN_ID0		_BITUL(0)
+
 #define MPTCP_PM_ADDR_FLAG_SIGNAL			(1 << 0)
 #define MPTCP_PM_ADDR_FLAG_SUBFLOW			(1 << 1)
 #define MPTCP_PM_ADDR_FLAG_BACKUP			(1 << 2)
@@ -127,13 +129,13 @@ struct mptcp_info {
 
 /*
  * MPTCP_EVENT_CREATED: token, family, saddr4 | saddr6, daddr4 | daddr6,
- *                      sport, dport
+ *                      sport, dport, server-side, [flags]
  * A new MPTCP connection has been created. It is the good time to allocate
  * memory and send ADD_ADDR if needed. Depending on the traffic-patterns
  * it can take a long time until the MPTCP_EVENT_ESTABLISHED is sent.
  *
  * MPTCP_EVENT_ESTABLISHED: token, family, saddr4 | saddr6, daddr4 | daddr6,
- *			    sport, dport
+ *			    sport, dport, server-side, [flags]
  * A MPTCP connection is established (can start new subflows).
  *
  * MPTCP_EVENT_CLOSED: token
net/mptcp/pm_netlink.c +7 -0
index cf9244a3644f..7e72862a6b54 100644
@@ -2242,6 +2242,7 @@ static int mptcp_event_created(struct sk_buff *skb,
 			       const struct sock *ssk)
 {
 	int err = nla_put_u32(skb, MPTCP_ATTR_TOKEN, msk->token);
+	u16 flags = 0;
 
 	if (err)
 		return err;
@@ -2249,6 +2250,12 @@ static int mptcp_event_created(struct sk_buff *skb,
 	if (nla_put_u8(skb, MPTCP_ATTR_SERVER_SIDE, READ_ONCE(msk->pm.server_side)))
 		return -EMSGSIZE;
 
+	if (READ_ONCE(msk->pm.remote_deny_join_id0))
+		flags |= MPTCP_PM_EV_FLAG_DENY_JOIN_ID0;
+
+	if (flags && nla_put_u16(skb, MPTCP_ATTR_FLAGS, flags))
+		return -EMSGSIZE;
+
 	return mptcp_event_add_subflow(skb, ssk);
 }
 
Signature · 1 line
2.51.0
maintainer Applied
#2 lore raw

Patch "mptcp: pm: nl: announce deny-join-id0 flag" has been added to the 6.1-stable tree

This is a note to let you know that I've just added the patch titled

mptcp: pm: nl: announce deny-join-id0 flag

to the 6.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
mptcp-pm-nl-announce-deny-join-id0-flag.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

From [email protected] Sat Sep 20 00:51:43 2025
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Sat, 20 Sep 2025 00:51:20 +0200
Subject: mptcp: pm: nl: announce deny-join-id0 flag
To: [email protected], [email protected], [email protected]
Cc: "Matthieu Baerts (NGI0)" <[email protected]>, [email protected], Marek Majkowski <[email protected]>, Mat Martineau <[email protected]>, Jakub Kicinski <[email protected]>
Message-ID: <[email protected]>

From: "Matthieu Baerts (NGI0)" <[email protected]>

commit 2293c57484ae64c9a3c847c8807db8c26a3a4d41 upstream.

During the connection establishment, a peer can tell the other one that it cannot establish new subflows to the initial IP address and port by setting the 'C' flag [1]. Doing so makes sense when the sender is behind a strict NAT, operating behind a legacy Layer 4 load balancer, or using anycast IP address for example.

When this 'C' flag is set, the path-managers must then not try to establish new subflows to the other peer's initial IP address and port. The in-kernel PM has access to this info, but the userspace PM didn't.

The RFC8684 [1] is strict about that:

(...) therefore the receiver MUST NOT try to open any additional subflows toward this address and port.

So it is important to tell the userspace about that as it is responsible for the respect of this flag.

When a new connection is created and established, the Netlink events now contain the existing but not currently used 'flags' attribute. When MPTCP_PM_EV_FLAG_DENY_JOIN_ID0 is set, it means no other subflows to the initial IP address and port -- info that are also part of the event -- can be established.

[ Conflicts in mptcp_pm.yaml, and mptcp_pm.h, because these files have
been added later by commit bc8aeb2045e2 ("Documentation: netlink: add a YAML spec for mptcp"), and commit 9d1ed17f93ce ("uapi: mptcp: use header file generated from YAML spec"), which are not in this version. Applying the same modifications, but only in mptcp.h. Conflict in pm_netlink.c, because of a difference in the context, introduced by commit b9f4554356f6 ("mptcp: annotate lockless access for token"), which is not in this version. ]

---
 include/uapi/linux/mptcp.h |    6 ++++--
 net/mptcp/pm_netlink.c     |    7 +++++++
 2 files changed, 11 insertions(+), 2 deletions(-)
include/uapi/linux/mptcp.h +4 -2
@@ -81,6 +81,8 @@ enum {
 
 #define MPTCP_PM_ADDR_ATTR_MAX (__MPTCP_PM_ADDR_ATTR_MAX - 1)
 
+#define MPTCP_PM_EV_FLAG_DENY_JOIN_ID0		_BITUL(0)
+
 #define MPTCP_PM_ADDR_FLAG_SIGNAL			(1 << 0)
 #define MPTCP_PM_ADDR_FLAG_SUBFLOW			(1 << 1)
 #define MPTCP_PM_ADDR_FLAG_BACKUP			(1 << 2)
@@ -127,13 +129,13 @@ struct mptcp_info {
 
 /*
  * MPTCP_EVENT_CREATED: token, family, saddr4 | saddr6, daddr4 | daddr6,
- *                      sport, dport
+ *                      sport, dport, server-side, [flags]
  * A new MPTCP connection has been created. It is the good time to allocate
  * memory and send ADD_ADDR if needed. Depending on the traffic-patterns
  * it can take a long time until the MPTCP_EVENT_ESTABLISHED is sent.
  *
  * MPTCP_EVENT_ESTABLISHED: token, family, saddr4 | saddr6, daddr4 | daddr6,
- *			    sport, dport
+ *			    sport, dport, server-side, [flags]
  * A MPTCP connection is established (can start new subflows).
  *
  * MPTCP_EVENT_CLOSED: token
net/mptcp/pm_netlink.c +7 -0
@@ -2242,6 +2242,7 @@ static int mptcp_event_created(struct sk
 			       const struct sock *ssk)
 {
 	int err = nla_put_u32(skb, MPTCP_ATTR_TOKEN, msk->token);
+	u16 flags = 0;
 
 	if (err)
 		return err;
@@ -2249,6 +2250,12 @@ static int mptcp_event_created(struct sk
 	if (nla_put_u8(skb, MPTCP_ATTR_SERVER_SIDE, READ_ONCE(msk->pm.server_side)))
 		return -EMSGSIZE;
 
+	if (READ_ONCE(msk->pm.remote_deny_join_id0))
+		flags |= MPTCP_PM_EV_FLAG_DENY_JOIN_ID0;
+
+	if (flags && nla_put_u16(skb, MPTCP_ATTR_FLAGS, flags))
+		return -EMSGSIZE;
+
 	return mptcp_event_add_subflow(skb, ssk);
 }
 

Patches currently in stable-queue which might be from [email protected] are

queue-6.1/mptcp-pm-nl-announce-deny-join-id0-flag.patch queue-6.1/selftests-mptcp-avoid-spurious-errors-on-tcp-disconnect.patch queue-6.1/mptcp-set-remote_deny_join_id0-on-syn-recv.patch queue-6.1/selftests-mptcp-userspace-pm-validate-deny-join-id0-flag.patch

author maintainer
#3 lore raw

PATCH 2/2 selftests: mptcp: userspace pm: validate deny-join-id0 flag

In reply to Matthieu Baerts (NGI0)

commit 24733e193a0d68f20d220e86da0362460c9aa812 upstream.

The previous commit adds the MPTCP_PM_EV_FLAG_DENY_JOIN_ID0 flag. Make sure it is correctly announced by the other peer when it has been received.

pm_nl_ctl will now display 'deny_join_id0:1' when monitoring the events, and when this flag was set by the other peer.

The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests, but it validates the previous fix for an issue introduced by this commit ID.

[ Conflict in userspace_pm.sh, because of a difference in the context,
introduced by commit c66fb480a330 ("selftests: userspace pm: avoid relaunching pm events"), which is not in this version. The same lines can still be added at the same place.
Conflicts in userspace_pm.sh, because of different refactoring, like with commit ae1fa39da991 ("selftests: mptcp: add evts_get_info helper"), and commit e198ad759273 ("selftests: mptcp: userspace_pm:
uniform results printing"). The modifications have been adapted to the old version, without the new helpers. ]

---
 tools/testing/selftests/net/mptcp/pm_nl_ctl.c     |  7 +++++++
 tools/testing/selftests/net/mptcp/userspace_pm.sh | 14 ++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)
tools/testing/selftests/net/mptcp/pm_nl_ctl.c +7 -0
index 1887bd61bd9a..17e5b7ec53b6 100644
@@ -188,6 +188,13 @@ static int capture_events(int fd, int event_group)
 					fprintf(stderr, ",error:%u", *(__u8 *)RTA_DATA(attrs));
 				else if (attrs->rta_type == MPTCP_ATTR_SERVER_SIDE)
 					fprintf(stderr, ",server_side:%u", *(__u8 *)RTA_DATA(attrs));
+				else if (attrs->rta_type == MPTCP_ATTR_FLAGS) {
+					__u16 flags = *(__u16 *)RTA_DATA(attrs);
+
+					/* only print when present, easier */
+					if (flags & MPTCP_PM_EV_FLAG_DENY_JOIN_ID0)
+						fprintf(stderr, ",deny_join_id0:1");
+				}
 
 				attrs = RTA_NEXT(attrs, msg_len);
 			}
tools/testing/selftests/net/mptcp/userspace_pm.sh +12 -2
index cb6c28d40129..a82ac12e816d 100755
@@ -139,6 +139,9 @@ make_connection()
 		is_v6="v4"
 	fi
 
+	# set this on the client side only: will not affect the rest
+	ip netns exec "$ns2" sysctl -q net.mptcp.allow_join_initial_addr_port=0
+
 	# Capture netlink events over the two network namespaces running
 	# the MPTCP client and server
 	local client_evts
@@ -173,21 +176,28 @@ make_connection()
 	local client_token
 	local client_port
 	local client_serverside
+	local client_nojoin
 	local server_token
 	local server_serverside
+	local server_nojoin
 
 	client_token=$(sed --unbuffered -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts")
 	client_port=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts")
 	client_serverside=$(sed --unbuffered -n 's/.*\(server_side:\)\([[:digit:]]*\).*$/\2/p;q'\
 				      "$client_evts")
+	client_nojoin=$(sed --unbuffered -n 's/.*\(deny_join_id0:\)\([[:digit:]]*\).*$/\2/p;q'\
+				      "$client_evts")
 	kill_wait $server_evts_pid
 	server_token=$(sed --unbuffered -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts")
 	server_serverside=$(sed --unbuffered -n 's/.*\(server_side:\)\([[:digit:]]*\).*$/\2/p;q'\
 				      "$server_evts")
+	server_nojoin=$(sed --unbuffered -n 's/.*\(deny_join_id0:\)\([[:digit:]]*\).*$/\2/p;q'\
+				      "$server_evts")
 	rm -f "$client_evts" "$server_evts" "$file"
 
-	if [ "$client_token" != "" ] && [ "$server_token" != "" ] && [ "$client_serverside" = 0 ] &&
-		   [ "$server_serverside" = 1 ]
+	if [ "${client_token}" != "" ] && [ "${server_token}" != "" ] &&
+	   [ "${client_serverside}" = 0 ] && [ "${server_serverside}" = 1 ] &&
+	   [ "${client_nojoin:-0}" = 0 ] && [ "${server_nojoin:-0}" = 1 ]
 	then
 		stdbuf -o0 -e0 printf "Established IP%s MPTCP Connection ns2 => ns1    \t\t[OK]\n" $is_v6
 	else
Signature · 1 line
2.51.0
maintainer Applied
#4 lore raw

Patch "selftests: mptcp: userspace pm: validate deny-join-id0 flag" has been added to the 6.1-stable tree

This is a note to let you know that I've just added the patch titled

selftests: mptcp: userspace pm: validate deny-join-id0 flag

to the 6.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
selftests-mptcp-userspace-pm-validate-deny-join-id0-flag.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

From [email protected] Sat Sep 20 00:52:39 2025
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Sat, 20 Sep 2025 00:51:21 +0200
Subject: selftests: mptcp: userspace pm: validate deny-join-id0 flag
To: [email protected], [email protected], [email protected]
Cc: "Matthieu Baerts (NGI0)" <[email protected]>, [email protected], Mat Martineau <[email protected]>, Jakub Kicinski <[email protected]>
Message-ID: <[email protected]>

From: "Matthieu Baerts (NGI0)" <[email protected]>

commit 24733e193a0d68f20d220e86da0362460c9aa812 upstream.

The previous commit adds the MPTCP_PM_EV_FLAG_DENY_JOIN_ID0 flag. Make sure it is correctly announced by the other peer when it has been received.

pm_nl_ctl will now display 'deny_join_id0:1' when monitoring the events, and when this flag was set by the other peer.

The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests, but it validates the previous fix for an issue introduced by this commit ID.

[ Conflict in userspace_pm.sh, because of a difference in the context,
introduced by commit c66fb480a330 ("selftests: userspace pm: avoid relaunching pm events"), which is not in this version. The same lines can still be added at the same place.
Conflicts in userspace_pm.sh, because of different refactoring, like with commit ae1fa39da991 ("selftests: mptcp: add evts_get_info helper"), and commit e198ad759273 ("selftests: mptcp: userspace_pm:
uniform results printing"). The modifications have been adapted to the old version, without the new helpers. ]

---
 tools/testing/selftests/net/mptcp/pm_nl_ctl.c     |    7 +++++++
 tools/testing/selftests/net/mptcp/userspace_pm.sh |   14 ++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)
tools/testing/selftests/net/mptcp/pm_nl_ctl.c +7 -0
@@ -188,6 +188,13 @@ static int capture_events(int fd, int ev
 					fprintf(stderr, ",error:%u", *(__u8 *)RTA_DATA(attrs));
 				else if (attrs->rta_type == MPTCP_ATTR_SERVER_SIDE)
 					fprintf(stderr, ",server_side:%u", *(__u8 *)RTA_DATA(attrs));
+				else if (attrs->rta_type == MPTCP_ATTR_FLAGS) {
+					__u16 flags = *(__u16 *)RTA_DATA(attrs);
+
+					/* only print when present, easier */
+					if (flags & MPTCP_PM_EV_FLAG_DENY_JOIN_ID0)
+						fprintf(stderr, ",deny_join_id0:1");
+				}
 
 				attrs = RTA_NEXT(attrs, msg_len);
 			}
tools/testing/selftests/net/mptcp/userspace_pm.sh +12 -2
@@ -139,6 +139,9 @@ make_connection()
 		is_v6="v4"
 	fi
 
+	# set this on the client side only: will not affect the rest
+	ip netns exec "$ns2" sysctl -q net.mptcp.allow_join_initial_addr_port=0
+
 	# Capture netlink events over the two network namespaces running
 	# the MPTCP client and server
 	local client_evts
@@ -173,21 +176,28 @@ make_connection()
 	local client_token
 	local client_port
 	local client_serverside
+	local client_nojoin
 	local server_token
 	local server_serverside
+	local server_nojoin
 
 	client_token=$(sed --unbuffered -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts")
 	client_port=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts")
 	client_serverside=$(sed --unbuffered -n 's/.*\(server_side:\)\([[:digit:]]*\).*$/\2/p;q'\
 				      "$client_evts")
+	client_nojoin=$(sed --unbuffered -n 's/.*\(deny_join_id0:\)\([[:digit:]]*\).*$/\2/p;q'\
+				      "$client_evts")
 	kill_wait $server_evts_pid
 	server_token=$(sed --unbuffered -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts")
 	server_serverside=$(sed --unbuffered -n 's/.*\(server_side:\)\([[:digit:]]*\).*$/\2/p;q'\
 				      "$server_evts")
+	server_nojoin=$(sed --unbuffered -n 's/.*\(deny_join_id0:\)\([[:digit:]]*\).*$/\2/p;q'\
+				      "$server_evts")
 	rm -f "$client_evts" "$server_evts" "$file"
 
-	if [ "$client_token" != "" ] && [ "$server_token" != "" ] && [ "$client_serverside" = 0 ] &&
-		   [ "$server_serverside" = 1 ]
+	if [ "${client_token}" != "" ] && [ "${server_token}" != "" ] &&
+	   [ "${client_serverside}" = 0 ] && [ "${server_serverside}" = 1 ] &&
+	   [ "${client_nojoin:-0}" = 0 ] && [ "${server_nojoin:-0}" = 1 ]
 	then
 		stdbuf -o0 -e0 printf "Established IP%s MPTCP Connection ns2 => ns1    \t\t[OK]\n" $is_v6
 	else

Patches currently in stable-queue which might be from [email protected] are

queue-6.1/mptcp-pm-nl-announce-deny-join-id0-flag.patch queue-6.1/selftests-mptcp-avoid-spurious-errors-on-tcp-disconnect.patch queue-6.1/mptcp-set-remote_deny_join_id0-on-syn-recv.patch queue-6.1/selftests-mptcp-userspace-pm-validate-deny-join-id0-flag.patch