--- /dev/null
+From matttbe@kernel.org Mon Mar 4 09:10:32 2024
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Wed, 28 Feb 2024 18:21:21 +0100
+Subject: mptcp: continue marking the first subflow as UNCONNECTED
+To: stable@vger.kernel.org, gregkh@linuxfoundation.org, sashal@kernel.org
+Cc: MPTCP Upstream <mptcp@lists.linux.dev>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Message-ID: <20240228172121.243458-2-matttbe@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+After the 'Fixes' commit mentioned below, which is a partial backport,
+the MPTCP worker was no longer marking the first subflow as "UNCONNECTED"
+when the socket was transitioning to TCP_CLOSE state.
+
+As a result, in v6.1, it was no longer possible to reconnect to the just
+disconnected socket. Continue to do that like before, only for the first
+subflow.
+
+A few refactoring have been done around the 'msk->subflow' in later
+versions, and it looks like this is not needed to do that there, but
+still needed in v6.1. Without that, the 'disconnect' tests from the
+mptcp_connect.sh selftest fail: they repeat the transfer 3 times by
+reconnecting to the server each time.
+
+Fixes: 7857e35ef10e ("mptcp: get rid of msk->subflow")
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2440,6 +2440,8 @@ static void __mptcp_close_ssk(struct soc
+ need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk);
+ if (!dispose_it) {
+ __mptcp_subflow_disconnect(ssk, subflow, flags);
++ if (msk->subflow && ssk == msk->subflow->sk)
++ msk->subflow->state = SS_UNCONNECTED;
+ release_sock(ssk);
+
+ goto out;
--- /dev/null
+From a7cfe776637004a4c938fde78be4bd608c32c3ef Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Thu, 15 Feb 2024 19:25:31 +0100
+Subject: mptcp: fix data races on local_id
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit a7cfe776637004a4c938fde78be4bd608c32c3ef upstream.
+
+The local address id is accessed lockless by the NL PM, add
+all the required ONCE annotation. There is a caveat: the local
+id can be initialized late in the subflow life-cycle, and its
+validity is controlled by the local_id_valid flag.
+
+Remove such flag and encode the validity in the local_id field
+itself with negative value before initialization. That allows
+accessing the field consistently with a single read operation.
+
+Fixes: 0ee4261a3681 ("mptcp: implement mptcp_pm_remove_subflow")
+Cc: stable@vger.kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+
+---
+ net/mptcp/diag.c | 2 +-
+ net/mptcp/pm_netlink.c | 6 +++---
+ net/mptcp/pm_userspace.c | 2 +-
+ net/mptcp/protocol.c | 2 +-
+ net/mptcp/protocol.h | 13 +++++++++++--
+ net/mptcp/subflow.c | 9 +++++----
+ 6 files changed, 22 insertions(+), 12 deletions(-)
+
+--- a/net/mptcp/diag.c
++++ b/net/mptcp/diag.c
+@@ -65,7 +65,7 @@ static int subflow_get_info(struct sock
+ sf->map_data_len) ||
+ nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_FLAGS, flags) ||
+ nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_REM, sf->remote_id) ||
+- nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_LOC, sf->local_id)) {
++ nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_LOC, subflow_get_local_id(sf))) {
+ err = -EMSGSIZE;
+ goto nla_failure;
+ }
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -799,7 +799,7 @@ static void mptcp_pm_nl_rm_addr_or_subfl
+ mptcp_for_each_subflow_safe(msk, subflow, tmp) {
+ struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+ int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
+- u8 id = subflow->local_id;
++ u8 id = subflow_get_local_id(subflow);
+
+ if (rm_type == MPTCP_MIB_RMADDR && subflow->remote_id != rm_id)
+ continue;
+@@ -808,7 +808,7 @@ static void mptcp_pm_nl_rm_addr_or_subfl
+
+ pr_debug(" -> %s rm_list_ids[%d]=%u local_id=%u remote_id=%u mpc_id=%u",
+ rm_type == MPTCP_MIB_RMADDR ? "address" : "subflow",
+- i, rm_id, subflow->local_id, subflow->remote_id,
++ i, rm_id, id, subflow->remote_id,
+ msk->mpc_endpoint_id);
+ spin_unlock_bh(&msk->pm.lock);
+ mptcp_subflow_shutdown(sk, ssk, how);
+@@ -2028,7 +2028,7 @@ static int mptcp_event_add_subflow(struc
+ if (WARN_ON_ONCE(!sf))
+ return -EINVAL;
+
+- if (nla_put_u8(skb, MPTCP_ATTR_LOC_ID, sf->local_id))
++ if (nla_put_u8(skb, MPTCP_ATTR_LOC_ID, subflow_get_local_id(sf)))
+ return -EMSGSIZE;
+
+ if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, sf->remote_id))
+--- a/net/mptcp/pm_userspace.c
++++ b/net/mptcp/pm_userspace.c
+@@ -233,7 +233,7 @@ static int mptcp_userspace_pm_remove_id_
+
+ lock_sock(sk);
+ mptcp_for_each_subflow(msk, subflow) {
+- if (subflow->local_id == 0) {
++ if (READ_ONCE(subflow->local_id) == 0) {
+ has_id_0 = true;
+ break;
+ }
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -119,7 +119,7 @@ static int __mptcp_socket_create(struct
+ subflow->request_mptcp = 1;
+
+ /* This is the first subflow, always with id 0 */
+- subflow->local_id_valid = 1;
++ WRITE_ONCE(subflow->local_id, 0);
+ mptcp_sock_graft(msk->first, sk->sk_socket);
+
+ return 0;
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -475,7 +475,6 @@ struct mptcp_subflow_context {
+ can_ack : 1, /* only after processing the remote a key */
+ disposable : 1, /* ctx can be free at ulp release time */
+ stale : 1, /* unable to snd/rcv data, do not use for xmit */
+- local_id_valid : 1, /* local_id is correctly initialized */
+ valid_csum_seen : 1; /* at least one csum validated */
+ enum mptcp_data_avail data_avail;
+ u32 remote_nonce;
+@@ -483,7 +482,7 @@ struct mptcp_subflow_context {
+ u32 local_nonce;
+ u32 remote_token;
+ u8 hmac[MPTCPOPT_HMAC_LEN];
+- u8 local_id;
++ s16 local_id; /* if negative not initialized yet */
+ u8 remote_id;
+ u8 reset_seen:1;
+ u8 reset_transient:1;
+@@ -529,6 +528,7 @@ mptcp_subflow_ctx_reset(struct mptcp_sub
+ {
+ memset(&subflow->reset, 0, sizeof(subflow->reset));
+ subflow->request_mptcp = 1;
++ WRITE_ONCE(subflow->local_id, -1);
+ }
+
+ static inline u64
+@@ -909,6 +909,15 @@ bool mptcp_pm_rm_addr_signal(struct mptc
+ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
+ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
+
++static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflow)
++{
++ int local_id = READ_ONCE(subflow->local_id);
++
++ if (local_id < 0)
++ return 0;
++ return local_id;
++}
++
+ void __init mptcp_pm_nl_init(void);
+ void mptcp_pm_nl_work(struct mptcp_sock *msk);
+ void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -489,8 +489,8 @@ do_reset:
+
+ static void subflow_set_local_id(struct mptcp_subflow_context *subflow, int local_id)
+ {
+- subflow->local_id = local_id;
+- subflow->local_id_valid = 1;
++ WARN_ON_ONCE(local_id < 0 || local_id > 255);
++ WRITE_ONCE(subflow->local_id, local_id);
+ }
+
+ static int subflow_chk_local_id(struct sock *sk)
+@@ -499,7 +499,7 @@ static int subflow_chk_local_id(struct s
+ struct mptcp_sock *msk = mptcp_sk(subflow->conn);
+ int err;
+
+- if (likely(subflow->local_id_valid))
++ if (likely(subflow->local_id >= 0))
+ return 0;
+
+ err = mptcp_pm_get_local_id(msk, (struct sock_common *)sk);
+@@ -1630,6 +1630,7 @@ static struct mptcp_subflow_context *sub
+ pr_debug("subflow=%p", ctx);
+
+ ctx->tcp_sock = sk;
++ WRITE_ONCE(ctx->local_id, -1);
+
+ return ctx;
+ }
+@@ -1867,7 +1868,7 @@ static void subflow_ulp_clone(const stru
+ new_ctx->idsn = subflow_req->idsn;
+
+ /* this is the first subflow, id is always 0 */
+- new_ctx->local_id_valid = 1;
++ subflow_set_local_id(new_ctx, 0);
+ } else if (subflow_req->mp_join) {
+ new_ctx->ssn_offset = subflow_req->ssn_offset;
+ new_ctx->mp_join = 1;
--- /dev/null
+From 967d3c27127e71a10ff5c083583a038606431b61 Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Thu, 15 Feb 2024 19:25:32 +0100
+Subject: mptcp: fix data races on remote_id
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit 967d3c27127e71a10ff5c083583a038606431b61 upstream.
+
+Similar to the previous patch, address the data race on
+remote_id, adding the suitable ONCE annotations.
+
+Fixes: bedee0b56113 ("mptcp: address lookup improvements")
+Cc: stable@vger.kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c | 8 ++++----
+ net/mptcp/subflow.c | 6 +++---
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -449,7 +449,7 @@ static unsigned int fill_remote_addresse
+ mptcp_for_each_subflow(msk, subflow) {
+ ssk = mptcp_subflow_tcp_sock(subflow);
+ remote_address((struct sock_common *)ssk, &addrs[i]);
+- addrs[i].id = subflow->remote_id;
++ addrs[i].id = READ_ONCE(subflow->remote_id);
+ if (deny_id0 && !addrs[i].id)
+ continue;
+
+@@ -798,18 +798,18 @@ static void mptcp_pm_nl_rm_addr_or_subfl
+
+ mptcp_for_each_subflow_safe(msk, subflow, tmp) {
+ struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
++ u8 remote_id = READ_ONCE(subflow->remote_id);
+ int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
+ u8 id = subflow_get_local_id(subflow);
+
+- if (rm_type == MPTCP_MIB_RMADDR && subflow->remote_id != rm_id)
++ if (rm_type == MPTCP_MIB_RMADDR && remote_id != rm_id)
+ continue;
+ if (rm_type == MPTCP_MIB_RMSUBFLOW && !mptcp_local_id_match(msk, id, rm_id))
+ continue;
+
+ pr_debug(" -> %s rm_list_ids[%d]=%u local_id=%u remote_id=%u mpc_id=%u",
+ rm_type == MPTCP_MIB_RMADDR ? "address" : "subflow",
+- i, rm_id, id, subflow->remote_id,
+- msk->mpc_endpoint_id);
++ i, rm_id, id, remote_id, msk->mpc_endpoint_id);
+ spin_unlock_bh(&msk->pm.lock);
+ mptcp_subflow_shutdown(sk, ssk, how);
+
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -446,7 +446,7 @@ static void subflow_finish_connect(struc
+ subflow->backup = mp_opt.backup;
+ subflow->thmac = mp_opt.thmac;
+ subflow->remote_nonce = mp_opt.nonce;
+- subflow->remote_id = mp_opt.join_id;
++ WRITE_ONCE(subflow->remote_id, mp_opt.join_id);
+ pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u backup=%d",
+ subflow, subflow->thmac, subflow->remote_nonce,
+ subflow->backup);
+@@ -1477,7 +1477,7 @@ int __mptcp_subflow_connect(struct sock
+ pr_debug("msk=%p remote_token=%u local_id=%d remote_id=%d", msk,
+ remote_token, local_id, remote_id);
+ subflow->remote_token = remote_token;
+- subflow->remote_id = remote_id;
++ WRITE_ONCE(subflow->remote_id, remote_id);
+ subflow->request_join = 1;
+ subflow->request_bkup = !!(flags & MPTCP_PM_ADDR_FLAG_BACKUP);
+ mptcp_info2sockaddr(remote, &addr, ssk->sk_family);
+@@ -1874,7 +1874,7 @@ static void subflow_ulp_clone(const stru
+ new_ctx->mp_join = 1;
+ new_ctx->fully_established = 1;
+ new_ctx->backup = subflow_req->backup;
+- new_ctx->remote_id = subflow_req->remote_id;
++ WRITE_ONCE(new_ctx->remote_id, subflow_req->remote_id);
+ new_ctx->token = subflow_req->token;
+ new_ctx->thmac = subflow_req->thmac;
+
-From db1cb1b3347989a7492fd5e33c9597da8cc5194c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
+From 045e9d812868a2d80b7a57b224ce8009444b7bbc Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
Date: Thu, 15 Feb 2024 19:25:33 +0100
Subject: mptcp: fix duplicate subflow creation
From: Paolo Abeni <pabeni@redhat.com>
-[ Upstream commit 045e9d812868a2d80b7a57b224ce8009444b7bbc ]
+commit 045e9d812868a2d80b7a57b224ce8009444b7bbc upstream.
Fullmesh endpoints could end-up unexpectedly generating duplicate
subflows - same local and remote addresses - when multiple incoming
Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
- net/mptcp/pm_netlink.c | 33 ++++++++++++++++++---------------
- 1 file changed, 18 insertions(+), 15 deletions(-)
+ net/mptcp/pm_netlink.c | 36 +++++++++++++++++++-----------------
+ 1 file changed, 19 insertions(+), 17 deletions(-)
-diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
-index beacea4d5da51..4f8f8c27a59e9 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
-@@ -396,19 +396,6 @@ void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
+@@ -407,23 +407,12 @@ void mptcp_pm_free_anno_list(struct mptc
}
}
/* Fill all the remote addresses into the array addrs[],
* and return the array size.
*/
-@@ -440,6 +427,16 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk,
+-static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullmesh,
++static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk,
++ struct mptcp_addr_info *local,
++ bool fullmesh,
+ struct mptcp_addr_info *addrs)
+ {
+ bool deny_id0 = READ_ONCE(msk->pm.remote_deny_join_id0);
+@@ -446,6 +435,16 @@ static unsigned int fill_remote_addresse
msk->pm.subflows++;
addrs[i++] = remote;
} else {
mptcp_for_each_subflow(msk, subflow) {
ssk = mptcp_subflow_tcp_sock(subflow);
remote_address((struct sock_common *)ssk, &addrs[i]);
-@@ -447,11 +444,17 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk,
+@@ -453,8 +452,11 @@ static unsigned int fill_remote_addresse
if (deny_id0 && !addrs[i].id)
continue;
-+ if (test_bit(addrs[i].id, unavail_id))
-+ continue;
-+
- if (!mptcp_pm_addr_families_match(sk, local, &addrs[i]))
- continue;
-
- if (!lookup_address_in_vec(addrs, i, &addrs[i]) &&
- msk->pm.subflows < subflows_max) {
+ if (msk->pm.subflows < subflows_max) {
msk->pm.subflows++;
i++;
}
---
-2.43.0
-
+@@ -603,7 +605,7 @@ static void mptcp_pm_create_subflow_or_s
+ fullmesh = !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH);
+
+ msk->pm.local_addr_used++;
+- nr = fill_remote_addresses_vec(msk, fullmesh, addrs);
++ nr = fill_remote_addresses_vec(msk, &local->addr, fullmesh, addrs);
+ if (nr)
+ __clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
+ spin_unlock_bh(&msk->pm.lock);
+++ /dev/null
-From e671d10ddf30b6bb0474802666f944919d001148 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 25 Jan 2023 11:47:21 +0100
-Subject: mptcp: let the in-kernel PM use mixed IPv4 and IPv6 addresses
-
-From: Paolo Abeni <pabeni@redhat.com>
-
-[ Upstream commit b9d69db87fb77fc80997993d40f091b323b3651e ]
-
-Currently the in-kernel PM arbitrary enforces that created subflow's
-family must match the main MPTCP socket while the RFC allows mixing
-IPv4 and IPv6 subflows.
-
-This patch changes the in-kernel PM logic to create subflows matching
-the currently selected source (or destination) address. IPv4 sockets
-can pick only IPv4 addresses (and v4 mapped in v6), while IPv6 sockets
-not restricted to V6ONLY can pick either IPv4 and IPv6 addresses as
-long as the source and destination matches.
-
-A helper, previously introduced is used to ease family matching checks,
-taking care of IPv4 vs IPv4-mapped-IPv6 vs IPv6 only addresses.
-
-Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/269
-Co-developed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
-Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
-Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Stable-dep-of: 045e9d812868 ("mptcp: fix duplicate subflow creation")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/mptcp/pm_netlink.c | 58 ++++++++++++++++++++++--------------------
- 1 file changed, 31 insertions(+), 27 deletions(-)
-
-diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
-index 70a1025f093cf..beacea4d5da51 100644
---- a/net/mptcp/pm_netlink.c
-+++ b/net/mptcp/pm_netlink.c
-@@ -152,7 +152,6 @@ static struct mptcp_pm_addr_entry *
- select_local_address(const struct pm_nl_pernet *pernet,
- const struct mptcp_sock *msk)
- {
-- const struct sock *sk = (const struct sock *)msk;
- struct mptcp_pm_addr_entry *entry, *ret = NULL;
-
- msk_owned_by_me(msk);
-@@ -165,16 +164,6 @@ select_local_address(const struct pm_nl_pernet *pernet,
- if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
- continue;
-
-- if (entry->addr.family != sk->sk_family) {
--#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-- if ((entry->addr.family == AF_INET &&
-- !ipv6_addr_v4mapped(&sk->sk_v6_daddr)) ||
-- (sk->sk_family == AF_INET &&
-- !ipv6_addr_v4mapped(&entry->addr.addr6)))
--#endif
-- continue;
-- }
--
- ret = entry;
- break;
- }
-@@ -423,7 +412,9 @@ static bool lookup_address_in_vec(const struct mptcp_addr_info *addrs, unsigned
- /* Fill all the remote addresses into the array addrs[],
- * and return the array size.
- */
--static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullmesh,
-+static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk,
-+ struct mptcp_addr_info *local,
-+ bool fullmesh,
- struct mptcp_addr_info *addrs)
- {
- bool deny_id0 = READ_ONCE(msk->pm.remote_deny_join_id0);
-@@ -443,6 +434,9 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullm
- if (deny_id0)
- return 0;
-
-+ if (!mptcp_pm_addr_families_match(sk, local, &remote))
-+ return 0;
-+
- msk->pm.subflows++;
- addrs[i++] = remote;
- } else {
-@@ -453,6 +447,9 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullm
- if (deny_id0 && !addrs[i].id)
- continue;
-
-+ if (!mptcp_pm_addr_families_match(sk, local, &addrs[i]))
-+ continue;
-+
- if (!lookup_address_in_vec(addrs, i, &addrs[i]) &&
- msk->pm.subflows < subflows_max) {
- msk->pm.subflows++;
-@@ -603,9 +600,11 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
- fullmesh = !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH);
-
- msk->pm.local_addr_used++;
-- nr = fill_remote_addresses_vec(msk, fullmesh, addrs);
-- if (nr)
-- __clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
-+ __clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
-+ nr = fill_remote_addresses_vec(msk, &local->addr, fullmesh, addrs);
-+ if (nr == 0)
-+ continue;
-+
- spin_unlock_bh(&msk->pm.lock);
- for (i = 0; i < nr; i++)
- __mptcp_subflow_connect(sk, &local->addr, &addrs[i]);
-@@ -628,11 +627,11 @@ static void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk)
- * and return the array size.
- */
- static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
-+ struct mptcp_addr_info *remote,
- struct mptcp_addr_info *addrs)
- {
- struct sock *sk = (struct sock *)msk;
- struct mptcp_pm_addr_entry *entry;
-- struct mptcp_addr_info local;
- struct pm_nl_pernet *pernet;
- unsigned int subflows_max;
- int i = 0;
-@@ -645,15 +644,8 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
- if (!(entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH))
- continue;
-
-- if (entry->addr.family != sk->sk_family) {
--#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-- if ((entry->addr.family == AF_INET &&
-- !ipv6_addr_v4mapped(&sk->sk_v6_daddr)) ||
-- (sk->sk_family == AF_INET &&
-- !ipv6_addr_v4mapped(&entry->addr.addr6)))
--#endif
-- continue;
-- }
-+ if (!mptcp_pm_addr_families_match(sk, &entry->addr, remote))
-+ continue;
-
- if (msk->pm.subflows < subflows_max) {
- msk->pm.subflows++;
-@@ -666,8 +658,18 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
- * 'IPADDRANY' local address
- */
- if (!i) {
-+ struct mptcp_addr_info local;
-+
- memset(&local, 0, sizeof(local));
-- local.family = msk->pm.remote.family;
-+ local.family =
-+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-+ remote->family == AF_INET6 &&
-+ ipv6_addr_v4mapped(&remote->addr6) ? AF_INET :
-+#endif
-+ remote->family;
-+
-+ if (!mptcp_pm_addr_families_match(sk, &local, remote))
-+ return 0;
-
- msk->pm.subflows++;
- addrs[i++] = local;
-@@ -706,7 +708,9 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
- /* connect to the specified remote address, using whatever
- * local address the routing configuration will pick.
- */
-- nr = fill_local_addresses_vec(msk, addrs);
-+ nr = fill_local_addresses_vec(msk, &remote, addrs);
-+ if (nr == 0)
-+ return;
-
- msk->pm.add_addr_accepted++;
- if (msk->pm.add_addr_accepted >= add_addr_accept_max ||
---
-2.43.0
-
drm-meson-don-t-remove-bridges-which-are-created-by-.patch
scsi-core-add-struct-for-args-to-execution-functions.patch
scsi-sd-usb_storage-uas-access-media-prior-to-queryi.patch
-mptcp-let-the-in-kernel-pm-use-mixed-ipv4-and-ipv6-a.patch
-mptcp-fix-duplicate-subflow-creation.patch
af_unix-fix-task-hung-while-purging-oob_skb-in-gc.patch
of-overlay-reorder-struct-fragment-fields-kerneldoc.patch
net-restore-alpha-order-to-ethernet-devices-in-confi.patch
fs-aio-make-io_cancel-generate-completions-again.patch
x86-e820-don-t-reserve-setup_rng_seed-in-e820.patch
x86-cpu-intel-detect-tme-keyid-bits-before-setting-mtrr-mask-registers.patch
+mptcp-fix-data-races-on-local_id.patch
+mptcp-fix-data-races-on-remote_id.patch
+mptcp-fix-duplicate-subflow-creation.patch
+mptcp-continue-marking-the-first-subflow-as-unconnected.patch