* [PATCH mptcp-net v2 0/2] mptcp: pm: avoid sending RM_ADDR over the same subflow
@ 2026-02-20 11:25 Matthieu Baerts (NGI0)
2026-02-20 11:25 ` [PATCH mptcp-net v2 1/2] mptcp: pm: avoid sending RM_ADDR over " Matthieu Baerts (NGI0)
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Matthieu Baerts (NGI0) @ 2026-02-20 11:25 UTC (permalink / raw)
To: MPTCP Upstream; +Cc: Matthieu Baerts (NGI0)
This should close the issue 612 reported by Frank Lorenz:
- Patch 1: avoid sending RM_ADDR over the same subflow as the one going
to be removed.
- Patch 2: validate that in the MPTCP Join selftest.
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
Changes in v2:
- Patch 1: small refactoring to reduce the indentation level
- Link to v1: https://patch.msgid.link/20260219-mptcp-issue-612-v1-0-839e20d96fe7@kernel.org
---
Matthieu Baerts (NGI0) (2):
mptcp: pm: avoid sending RM_ADDR over same subflow
selftests: mptcp: join: check RM_ADDR not sent over same subflow
net/mptcp/pm.c | 55 +++++++++++++++++++------
tools/testing/selftests/net/mptcp/mptcp_join.sh | 36 ++++++++++++++++
2 files changed, 79 insertions(+), 12 deletions(-)
---
base-commit: d81a02a671623999f5ec963b73181d845c665747
change-id: 20260219-mptcp-issue-612-d94095f11d0e
Best regards,
--
Matthieu Baerts (NGI0) <matttbe@kernel.org>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH mptcp-net v2 1/2] mptcp: pm: avoid sending RM_ADDR over same subflow
2026-02-20 11:25 [PATCH mptcp-net v2 0/2] mptcp: pm: avoid sending RM_ADDR over the same subflow Matthieu Baerts (NGI0)
@ 2026-02-20 11:25 ` Matthieu Baerts (NGI0)
2026-02-25 4:12 ` Mat Martineau
2026-02-20 11:25 ` [PATCH mptcp-net v2 2/2] selftests: mptcp: join: check RM_ADDR not sent " Matthieu Baerts (NGI0)
2026-02-20 12:42 ` [PATCH mptcp-net v2 0/2] mptcp: pm: avoid sending RM_ADDR over the " MPTCP CI
2 siblings, 1 reply; 8+ messages in thread
From: Matthieu Baerts (NGI0) @ 2026-02-20 11:25 UTC (permalink / raw)
To: MPTCP Upstream; +Cc: Matthieu Baerts (NGI0)
RM_ADDR are sent over an active subflow, the first one in the subflows
list. There is then a high chance the initial subflow is picked. With
the in-kernel PM, when an endpoint is removed, a RM_ADDR is sent, then
linked subflows are closed. This is done for each active MPTCP
connection.
MPTCP endpoints are likely removed because the attached network is no
longer available or usable. In this case, it is better to avoid sending
this RM_ADDR over the subflow that is going to be removed, but prefer
sending it over another active and non stale subflow, if any.
This modification avoids situations where the other end is not notified
when a subflow is no longer usable: typically when the endpoint linked
to the initial subflow is removed, especially on the server side.
Fixes: 8dd5efb1f91b ("mptcp: send ack for rm_addr")
Reported-by: Frank Lorenz
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/612
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
Note: in my initial version, I only used one alternative for both
"stale" and "same id" subflows. I guess it is better to send over the
same subflow than a stale one, hence the priority, but there are then a
few more lines of code (but still readable, I think). To be discussed.
v2:
- reduce one indentation level and s/rlist/rm_list/g
---
net/mptcp/pm.c | 55 +++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 43 insertions(+), 12 deletions(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 8206b0fd2377..daef91e597ae 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -212,9 +212,24 @@ void mptcp_pm_send_ack(struct mptcp_sock *msk,
spin_lock_bh(&msk->pm.lock);
}
-void mptcp_pm_addr_send_ack(struct mptcp_sock *msk)
+static bool subflow_in_rm_list(const struct mptcp_subflow_context *subflow,
+ const struct mptcp_rm_list *rm_list)
{
- struct mptcp_subflow_context *subflow, *alt = NULL;
+ u8 i, id = subflow_get_local_id(subflow);
+
+ for (i = 0; i < rm_list->nr; i++) {
+ if (rm_list->ids[i] == id)
+ return true;
+ }
+
+ return false;
+}
+
+static void
+mptcp_pm_addr_send_ack_avoid_list(struct mptcp_sock *msk,
+ const struct mptcp_rm_list *rm_list)
+{
+ struct mptcp_subflow_context *subflow, *stale = NULL, *same_id = NULL;
msk_owned_by_me(msk);
lockdep_assert_held(&msk->pm.lock);
@@ -224,19 +239,35 @@ void mptcp_pm_addr_send_ack(struct mptcp_sock *msk)
return;
mptcp_for_each_subflow(msk, subflow) {
- if (__mptcp_subflow_active(subflow)) {
- if (!subflow->stale) {
- mptcp_pm_send_ack(msk, subflow, false, false);
- return;
- }
+ if (!__mptcp_subflow_active(subflow))
+ continue;
- if (!alt)
- alt = subflow;
+ if (unlikely(subflow->stale)) {
+ if (!stale)
+ stale = subflow;
+ } else if (unlikely(rm_list &&
+ subflow_in_rm_list(subflow, rm_list))) {
+ if (!same_id)
+ same_id = subflow;
+ } else {
+ goto send_ack;
}
}
- if (alt)
- mptcp_pm_send_ack(msk, alt, false, false);
+ if (same_id)
+ subflow = same_id;
+ else if (stale)
+ subflow = stale;
+ else
+ return;
+
+send_ack:
+ mptcp_pm_send_ack(msk, subflow, false, false);
+}
+
+void mptcp_pm_addr_send_ack(struct mptcp_sock *msk)
+{
+ mptcp_pm_addr_send_ack_avoid_list(msk, NULL);
}
int mptcp_pm_mp_prio_send_ack(struct mptcp_sock *msk,
@@ -470,7 +501,7 @@ int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_
msk->pm.rm_list_tx = *rm_list;
rm_addr |= BIT(MPTCP_RM_ADDR_SIGNAL);
WRITE_ONCE(msk->pm.addr_signal, rm_addr);
- mptcp_pm_addr_send_ack(msk);
+ mptcp_pm_addr_send_ack_avoid_list(msk, rm_list);
return 0;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH mptcp-net v2 2/2] selftests: mptcp: join: check RM_ADDR not sent over same subflow
2026-02-20 11:25 [PATCH mptcp-net v2 0/2] mptcp: pm: avoid sending RM_ADDR over the same subflow Matthieu Baerts (NGI0)
2026-02-20 11:25 ` [PATCH mptcp-net v2 1/2] mptcp: pm: avoid sending RM_ADDR over " Matthieu Baerts (NGI0)
@ 2026-02-20 11:25 ` Matthieu Baerts (NGI0)
2026-02-20 12:42 ` [PATCH mptcp-net v2 0/2] mptcp: pm: avoid sending RM_ADDR over the " MPTCP CI
2 siblings, 0 replies; 8+ messages in thread
From: Matthieu Baerts (NGI0) @ 2026-02-20 11:25 UTC (permalink / raw)
To: MPTCP Upstream; +Cc: Matthieu Baerts (NGI0)
This validates the previous commit: RM_ADDR were sent over the first
found active subflow which could be the same as the one being removed.
It is more likely to loose this notification.
For this check, RM_ADDR are explicitly dropped when trying to send them
over the initial subflow, when removing the endpoint attached to it. If
it is dropped, the test will complain because some RM_ADDR have not been
received.
Note that only the RM_ADDR are dropped, to allow the linked subflow to
be quickly and cleanly closed. To only drop those RM_ADDR, a cBPF byte
code is used. If the IPTables commands fail, that's OK, the tests will
continue to pass, but not validate this part. This can be ignored:
another subtest fully depends on such command, and will be marked as
skipped.
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.
Fixes: 8dd5efb1f91b ("mptcp: send ack for rm_addr")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
v2: revert to original commit message, not sure how I ended up with that
---
tools/testing/selftests/net/mptcp/mptcp_join.sh | 36 +++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index dc1f200aaa81..058ad5a13d24 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -104,6 +104,24 @@ CBPF_MPTCP_SUBOPTION_ADD_ADDR="14,
6 0 0 65535,
6 0 0 0"
+# IPv4: TCP hdr of 48B, a first suboption of 12B (DACK8), the RM_ADDR suboption
+# generated using "nfbpf_compile '(ip[32] & 0xf0) == 0xc0 && ip[53] == 0x0c &&
+# (ip[66] & 0xf0) == 0x40'"
+CBPF_MPTCP_SUBOPTION_RM_ADDR="13,
+ 48 0 0 0,
+ 84 0 0 240,
+ 21 0 9 64,
+ 48 0 0 32,
+ 84 0 0 240,
+ 21 0 6 192,
+ 48 0 0 53,
+ 21 0 4 12,
+ 48 0 0 66,
+ 84 0 0 240,
+ 21 0 1 64,
+ 6 0 0 65535,
+ 6 0 0 0"
+
init_partial()
{
capout=$(mktemp)
@@ -4217,6 +4235,14 @@ endpoint_tests()
chk_subflow_nr "after no reject" 3
chk_mptcp_info subflows 2 subflows 2
+ # To make sure RM_ADDR are sent over a different subflow, but
+ # allow the rest to quickly and cleanly close the subflow
+ local ipt=1
+ ip netns exec "${ns2}" ${iptables} -I OUTPUT -s "10.0.1.2" \
+ -p tcp -m tcp --tcp-option 30 \
+ -m bpf --bytecode \
+ "$CBPF_MPTCP_SUBOPTION_RM_ADDR" \
+ -j DROP || ipt=0
local i
for i in $(seq 3); do
pm_nl_del_endpoint $ns2 1 10.0.1.2
@@ -4229,6 +4255,7 @@ endpoint_tests()
chk_subflow_nr "after re-add id 0 ($i)" 3
chk_mptcp_info subflows 3 subflows 3
done
+ [ ${ipt} = 1 ] && ip netns exec "${ns2}" ${iptables} -D OUTPUT 1
mptcp_lib_kill_group_wait $tests_pid
@@ -4288,11 +4315,20 @@ endpoint_tests()
chk_mptcp_info subflows 2 subflows 2
chk_mptcp_info add_addr_signal 2 add_addr_accepted 2
+ # To make sure RM_ADDR are sent over a different subflow, but
+ # allow the rest to quickly and cleanly close the subflow
+ local ipt=1
+ ip netns exec "${ns1}" ${iptables} -I OUTPUT -s "10.0.1.1" \
+ -p tcp -m tcp --tcp-option 30 \
+ -m bpf --bytecode \
+ "$CBPF_MPTCP_SUBOPTION_RM_ADDR" \
+ -j DROP || ipt=0
pm_nl_del_endpoint $ns1 42 10.0.1.1
sleep 0.5
chk_subflow_nr "after delete ID 0" 2
chk_mptcp_info subflows 2 subflows 2
chk_mptcp_info add_addr_signal 2 add_addr_accepted 2
+ [ ${ipt} = 1 ] && ip netns exec "${ns1}" ${iptables} -D OUTPUT 1
pm_nl_add_endpoint $ns1 10.0.1.1 id 99 flags signal
wait_mpj 4
--
2.51.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH mptcp-net v2 0/2] mptcp: pm: avoid sending RM_ADDR over the same subflow
2026-02-20 11:25 [PATCH mptcp-net v2 0/2] mptcp: pm: avoid sending RM_ADDR over the same subflow Matthieu Baerts (NGI0)
2026-02-20 11:25 ` [PATCH mptcp-net v2 1/2] mptcp: pm: avoid sending RM_ADDR over " Matthieu Baerts (NGI0)
2026-02-20 11:25 ` [PATCH mptcp-net v2 2/2] selftests: mptcp: join: check RM_ADDR not sent " Matthieu Baerts (NGI0)
@ 2026-02-20 12:42 ` MPTCP CI
2 siblings, 0 replies; 8+ messages in thread
From: MPTCP CI @ 2026-02-20 12:42 UTC (permalink / raw)
To: Matthieu Baerts; +Cc: mptcp
Hi Matthieu,
Thank you for your modifications, that's great!
Our CI did some validations and here is its report:
- KVM Validation: normal (except selftest_mptcp_join): Success! ✅
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Success! ✅
- KVM Validation: debug (only selftest_mptcp_join): Notice: Call Traces at boot time, rebooted and continued 🔴
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Notice: Call Traces at boot time, rebooted and continued 🔴
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/22222681925
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/6208f5fa9a3d
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1055875
If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:
$ cd [kernel source code]
$ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
--pull always mptcp/mptcp-upstream-virtme-docker:latest \
auto-normal
For more details:
https://github.com/multipath-tcp/mptcp-upstream-virtme-docker
Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)
Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH mptcp-net v2 1/2] mptcp: pm: avoid sending RM_ADDR over same subflow
2026-02-20 11:25 ` [PATCH mptcp-net v2 1/2] mptcp: pm: avoid sending RM_ADDR over " Matthieu Baerts (NGI0)
@ 2026-02-25 4:12 ` Mat Martineau
2026-02-25 12:18 ` Matthieu Baerts
0 siblings, 1 reply; 8+ messages in thread
From: Mat Martineau @ 2026-02-25 4:12 UTC (permalink / raw)
To: Matthieu Baerts (NGI0); +Cc: MPTCP Upstream
On Fri, 20 Feb 2026, Matthieu Baerts (NGI0) wrote:
> RM_ADDR are sent over an active subflow, the first one in the subflows
> list. There is then a high chance the initial subflow is picked. With
> the in-kernel PM, when an endpoint is removed, a RM_ADDR is sent, then
> linked subflows are closed. This is done for each active MPTCP
> connection.
>
> MPTCP endpoints are likely removed because the attached network is no
> longer available or usable. In this case, it is better to avoid sending
> this RM_ADDR over the subflow that is going to be removed, but prefer
> sending it over another active and non stale subflow, if any.
>
> This modification avoids situations where the other end is not notified
> when a subflow is no longer usable: typically when the endpoint linked
> to the initial subflow is removed, especially on the server side.
>
> Fixes: 8dd5efb1f91b ("mptcp: send ack for rm_addr")
> Reported-by: Frank Lorenz
> Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/612
> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> ---
> Note: in my initial version, I only used one alternative for both
> "stale" and "same id" subflows. I guess it is better to send over the
> same subflow than a stale one, hence the priority, but there are then a
> few more lines of code (but still readable, I think). To be discussed.
>
> v2:
> - reduce one indentation level and s/rlist/rm_list/g
> ---
> net/mptcp/pm.c | 55 +++++++++++++++++++++++++++++++++++++++++++------------
> 1 file changed, 43 insertions(+), 12 deletions(-)
>
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index 8206b0fd2377..daef91e597ae 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -212,9 +212,24 @@ void mptcp_pm_send_ack(struct mptcp_sock *msk,
> spin_lock_bh(&msk->pm.lock);
> }
>
> -void mptcp_pm_addr_send_ack(struct mptcp_sock *msk)
> +static bool subflow_in_rm_list(const struct mptcp_subflow_context *subflow,
> + const struct mptcp_rm_list *rm_list)
> {
> - struct mptcp_subflow_context *subflow, *alt = NULL;
> + u8 i, id = subflow_get_local_id(subflow);
> +
> + for (i = 0; i < rm_list->nr; i++) {
> + if (rm_list->ids[i] == id)
> + return true;
> + }
> +
> + return false;
> +}
> +
> +static void
> +mptcp_pm_addr_send_ack_avoid_list(struct mptcp_sock *msk,
> + const struct mptcp_rm_list *rm_list)
> +{
> + struct mptcp_subflow_context *subflow, *stale = NULL, *same_id = NULL;
>
> msk_owned_by_me(msk);
> lockdep_assert_held(&msk->pm.lock);
> @@ -224,19 +239,35 @@ void mptcp_pm_addr_send_ack(struct mptcp_sock *msk)
> return;
>
> mptcp_for_each_subflow(msk, subflow) {
> - if (__mptcp_subflow_active(subflow)) {
> - if (!subflow->stale) {
> - mptcp_pm_send_ack(msk, subflow, false, false);
> - return;
> - }
> + if (!__mptcp_subflow_active(subflow))
> + continue;
>
> - if (!alt)
> - alt = subflow;
> + if (unlikely(subflow->stale)) {
> + if (!stale)
> + stale = subflow;
> + } else if (unlikely(rm_list &&
> + subflow_in_rm_list(subflow, rm_list))) {
> + if (!same_id)
> + same_id = subflow;
> + } else {
> + goto send_ack;
Hi Matthieu -
This is definitely an improvement over the older code, thanks! It does
still send RM_ADDR exactly once. It could also RM_ADDR using *all* active
non-stale subflows (any that are delivered after the first would be
ignored). In terms of interoperability there is the risk of confusing the
peer's path manager if it doesn't handle RM_ADDR for a non-existant
subflow.
Maybe that's more of a mptcp-next feature (if it makes sense to do at
all).
The v2 patch here is closer to the existing behavior so I'm ok with
approving it:
Reviewed-by: Mat Martineau <martineau@kernel.org>
> }
> }
>
> - if (alt)
> - mptcp_pm_send_ack(msk, alt, false, false);
> + if (same_id)
> + subflow = same_id;
> + else if (stale)
> + subflow = stale;
> + else
> + return;
> +
> +send_ack:
> + mptcp_pm_send_ack(msk, subflow, false, false);
> +}
> +
> +void mptcp_pm_addr_send_ack(struct mptcp_sock *msk)
> +{
> + mptcp_pm_addr_send_ack_avoid_list(msk, NULL);
> }
>
> int mptcp_pm_mp_prio_send_ack(struct mptcp_sock *msk,
> @@ -470,7 +501,7 @@ int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_
> msk->pm.rm_list_tx = *rm_list;
> rm_addr |= BIT(MPTCP_RM_ADDR_SIGNAL);
> WRITE_ONCE(msk->pm.addr_signal, rm_addr);
> - mptcp_pm_addr_send_ack(msk);
> + mptcp_pm_addr_send_ack_avoid_list(msk, rm_list);
> return 0;
> }
>
>
> --
> 2.51.0
>
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH mptcp-net v2 1/2] mptcp: pm: avoid sending RM_ADDR over same subflow
2026-02-25 4:12 ` Mat Martineau
@ 2026-02-25 12:18 ` Matthieu Baerts
2026-02-25 16:57 ` Mat Martineau
0 siblings, 1 reply; 8+ messages in thread
From: Matthieu Baerts @ 2026-02-25 12:18 UTC (permalink / raw)
To: Mat Martineau; +Cc: MPTCP Upstream
Hi Mat,
Thank you for the review!
On 25/02/2026 05:12, Mat Martineau wrote:
> On Fri, 20 Feb 2026, Matthieu Baerts (NGI0) wrote:
>
>> RM_ADDR are sent over an active subflow, the first one in the subflows
>> list. There is then a high chance the initial subflow is picked. With
>> the in-kernel PM, when an endpoint is removed, a RM_ADDR is sent, then
>> linked subflows are closed. This is done for each active MPTCP
>> connection.
>>
>> MPTCP endpoints are likely removed because the attached network is no
>> longer available or usable. In this case, it is better to avoid sending
>> this RM_ADDR over the subflow that is going to be removed, but prefer
>> sending it over another active and non stale subflow, if any.
>>
>> This modification avoids situations where the other end is not notified
>> when a subflow is no longer usable: typically when the endpoint linked
>> to the initial subflow is removed, especially on the server side.
(...)
> This is definitely an improvement over the older code, thanks! It does
> still send RM_ADDR exactly once. It could also RM_ADDR using *all*
> active non-stale subflows (any that are delivered after the first would
> be ignored). In terms of interoperability there is the risk of confusing
> the peer's path manager if it doesn't handle RM_ADDR for a non-existant
> subflow.
>
> Maybe that's more of a mptcp-next feature (if it makes sense to do at all).
I think implementing this would definitively be mptcp-next material. If
we want this, we will also need to change the way the option is added:
for the moment, the rm_list is copied in the msk, and a bit is set
before triggering the ACK, and when sending the ACK, the bit is reset.
So we would need to also record the subflow IDs that should send the
RM_ADDR, and only remove the main bit when all of subflows have sent it.
Now regarding the behaviour, I think it more likely to have concurrent
issues: maybe a subflow could be re-created or an ADD_ADDR could be
received before all RM_ADDR are transmitted, e.g. in case of bufferbloat
on one path?
> The v2 patch here is closer to the existing behavior so I'm ok with
> approving it:
>
> Reviewed-by: Mat Martineau <martineau@kernel.org>
Thanks! Is this tag also covering patch 2/2?
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH mptcp-net v2 1/2] mptcp: pm: avoid sending RM_ADDR over same subflow
2026-02-25 12:18 ` Matthieu Baerts
@ 2026-02-25 16:57 ` Mat Martineau
2026-02-26 7:39 ` Matthieu Baerts
0 siblings, 1 reply; 8+ messages in thread
From: Mat Martineau @ 2026-02-25 16:57 UTC (permalink / raw)
To: Matthieu Baerts; +Cc: MPTCP Upstream
On Wed, 25 Feb 2026, Matthieu Baerts wrote:
> Hi Mat,
>
> Thank you for the review!
>
> On 25/02/2026 05:12, Mat Martineau wrote:
>> On Fri, 20 Feb 2026, Matthieu Baerts (NGI0) wrote:
>>
>>> RM_ADDR are sent over an active subflow, the first one in the subflows
>>> list. There is then a high chance the initial subflow is picked. With
>>> the in-kernel PM, when an endpoint is removed, a RM_ADDR is sent, then
>>> linked subflows are closed. This is done for each active MPTCP
>>> connection.
>>>
>>> MPTCP endpoints are likely removed because the attached network is no
>>> longer available or usable. In this case, it is better to avoid sending
>>> this RM_ADDR over the subflow that is going to be removed, but prefer
>>> sending it over another active and non stale subflow, if any.
>>>
>>> This modification avoids situations where the other end is not notified
>>> when a subflow is no longer usable: typically when the endpoint linked
>>> to the initial subflow is removed, especially on the server side.
>
> (...)
>
>> This is definitely an improvement over the older code, thanks! It does
>> still send RM_ADDR exactly once. It could also RM_ADDR using *all*
>> active non-stale subflows (any that are delivered after the first would
>> be ignored). In terms of interoperability there is the risk of confusing
>> the peer's path manager if it doesn't handle RM_ADDR for a non-existant
>> subflow.
>>
>> Maybe that's more of a mptcp-next feature (if it makes sense to do at all).
>
> I think implementing this would definitively be mptcp-next material. If
> we want this, we will also need to change the way the option is added:
> for the moment, the rm_list is copied in the msk, and a bit is set
> before triggering the ACK, and when sending the ACK, the bit is reset.
> So we would need to also record the subflow IDs that should send the
> RM_ADDR, and only remove the main bit when all of subflows have sent it.
>
> Now regarding the behaviour, I think it more likely to have concurrent
> issues: maybe a subflow could be re-created or an ADD_ADDR could be
> received before all RM_ADDR are transmitted, e.g. in case of bufferbloat
> on one path?
>
>> The v2 patch here is closer to the existing behavior so I'm ok with
>> approving it:
>>
>> Reviewed-by: Mat Martineau <martineau@kernel.org>
>
> Thanks! Is this tag also covering patch 2/2?
>
Yes, I had intended to reply to the cover letter to RvB the series.
Thanks for clarifying.
- Mat
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH mptcp-net v2 1/2] mptcp: pm: avoid sending RM_ADDR over same subflow
2026-02-25 16:57 ` Mat Martineau
@ 2026-02-26 7:39 ` Matthieu Baerts
0 siblings, 0 replies; 8+ messages in thread
From: Matthieu Baerts @ 2026-02-26 7:39 UTC (permalink / raw)
To: Mat Martineau; +Cc: MPTCP Upstream
Hi Mat,
On 25/02/2026 17:57, Mat Martineau wrote:
> On Wed, 25 Feb 2026, Matthieu Baerts wrote:
>
>> Hi Mat,
>>
>> Thank you for the review!
>>
>> On 25/02/2026 05:12, Mat Martineau wrote:
>>> On Fri, 20 Feb 2026, Matthieu Baerts (NGI0) wrote:
>>>
>>>> RM_ADDR are sent over an active subflow, the first one in the subflows
>>>> list. There is then a high chance the initial subflow is picked. With
>>>> the in-kernel PM, when an endpoint is removed, a RM_ADDR is sent, then
>>>> linked subflows are closed. This is done for each active MPTCP
>>>> connection.
>>>>
>>>> MPTCP endpoints are likely removed because the attached network is no
>>>> longer available or usable. In this case, it is better to avoid sending
>>>> this RM_ADDR over the subflow that is going to be removed, but prefer
>>>> sending it over another active and non stale subflow, if any.
>>>>
>>>> This modification avoids situations where the other end is not notified
>>>> when a subflow is no longer usable: typically when the endpoint linked
>>>> to the initial subflow is removed, especially on the server side.
>>
>> (...)
>>
>>> This is definitely an improvement over the older code, thanks! It does
>>> still send RM_ADDR exactly once. It could also RM_ADDR using *all*
>>> active non-stale subflows (any that are delivered after the first would
>>> be ignored). In terms of interoperability there is the risk of confusing
>>> the peer's path manager if it doesn't handle RM_ADDR for a non-existant
>>> subflow.
>>>
>>> Maybe that's more of a mptcp-next feature (if it makes sense to do at
>>> all).
>>
>> I think implementing this would definitively be mptcp-next material. If
>> we want this, we will also need to change the way the option is added:
>> for the moment, the rm_list is copied in the msk, and a bit is set
>> before triggering the ACK, and when sending the ACK, the bit is reset.
>> So we would need to also record the subflow IDs that should send the
>> RM_ADDR, and only remove the main bit when all of subflows have sent it.
>>
>> Now regarding the behaviour, I think it more likely to have concurrent
>> issues: maybe a subflow could be re-created or an ADD_ADDR could be
>> received before all RM_ADDR are transmitted, e.g. in case of bufferbloat
>> on one path?
>>
>>> The v2 patch here is closer to the existing behavior so I'm ok with
>>> approving it:
>>>
>>> Reviewed-by: Mat Martineau <martineau@kernel.org>
>>
>> Thanks! Is this tag also covering patch 2/2?
>>
>
> Yes, I had intended to reply to the cover letter to RvB the series.
> Thanks for clarifying.
Great, just applied:
New patches for t/upstream-net and t/upstream:
- 2f79a7def595: mptcp: pm: avoid sending RM_ADDR over same subflow
- c4a9449065db: selftests: mptcp: join: check RM_ADDR not sent over same
subflow
- Results: 4a4900c134dd..652750a9d6a6 (export-net)
- Results: 5e61492ae392..d3854ef490c9 (export)
Tests are now in progress:
- export-net:
https://github.com/multipath-tcp/mptcp_net-next/commit/f7b905d300ce1fb82367bb2e069fa067c4ae0d49/checks
- export:
https://github.com/multipath-tcp/mptcp_net-next/commit/07e1c275611e95ade08509cf5eeb2c39f181d116/checks
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-02-26 7:39 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-20 11:25 [PATCH mptcp-net v2 0/2] mptcp: pm: avoid sending RM_ADDR over the same subflow Matthieu Baerts (NGI0)
2026-02-20 11:25 ` [PATCH mptcp-net v2 1/2] mptcp: pm: avoid sending RM_ADDR over " Matthieu Baerts (NGI0)
2026-02-25 4:12 ` Mat Martineau
2026-02-25 12:18 ` Matthieu Baerts
2026-02-25 16:57 ` Mat Martineau
2026-02-26 7:39 ` Matthieu Baerts
2026-02-20 11:25 ` [PATCH mptcp-net v2 2/2] selftests: mptcp: join: check RM_ADDR not sent " Matthieu Baerts (NGI0)
2026-02-20 12:42 ` [PATCH mptcp-net v2 0/2] mptcp: pm: avoid sending RM_ADDR over the " MPTCP CI
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox