]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Mar 2024 08:11:45 +0000 (09:11 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Mar 2024 08:11:45 +0000 (09:11 +0100)
added patches:
mptcp-continue-marking-the-first-subflow-as-unconnected.patch
mptcp-fix-data-races-on-local_id.patch
mptcp-fix-data-races-on-remote_id.patch

queue-6.1/mptcp-continue-marking-the-first-subflow-as-unconnected.patch [new file with mode: 0644]
queue-6.1/mptcp-fix-data-races-on-local_id.patch [new file with mode: 0644]
queue-6.1/mptcp-fix-data-races-on-remote_id.patch [new file with mode: 0644]
queue-6.1/mptcp-fix-duplicate-subflow-creation.patch
queue-6.1/mptcp-let-the-in-kernel-pm-use-mixed-ipv4-and-ipv6-a.patch [deleted file]
queue-6.1/series

diff --git a/queue-6.1/mptcp-continue-marking-the-first-subflow-as-unconnected.patch b/queue-6.1/mptcp-continue-marking-the-first-subflow-as-unconnected.patch
new file mode 100644 (file)
index 0000000..f360361
--- /dev/null
@@ -0,0 +1,42 @@
+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;
diff --git a/queue-6.1/mptcp-fix-data-races-on-local_id.patch b/queue-6.1/mptcp-fix-data-races-on-local_id.patch
new file mode 100644 (file)
index 0000000..52f8d4b
--- /dev/null
@@ -0,0 +1,180 @@
+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;
diff --git a/queue-6.1/mptcp-fix-data-races-on-remote_id.patch b/queue-6.1/mptcp-fix-data-races-on-remote_id.patch
new file mode 100644 (file)
index 0000000..df2e29b
--- /dev/null
@@ -0,0 +1,86 @@
+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;
index 3c907c3e9404f3d7b125eddd2a7ff812a7ee28c2..93ee13ddb38f2caca646ca937c635eebbf1cb400 100644 (file)
@@ -1,11 +1,11 @@
-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
@@ -31,16 +31,14 @@ 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: 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
        }
  }
  
@@ -60,7 +58,14 @@ index beacea4d5da51..4f8f8c27a59e9 100644
  /* 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 {
@@ -77,16 +82,10 @@ index beacea4d5da51..4f8f8c27a59e9 100644
                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) {
@@ -97,6 +96,12 @@ index beacea4d5da51..4f8f8c27a59e9 100644
                                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);
diff --git a/queue-6.1/mptcp-let-the-in-kernel-pm-use-mixed-ipv4-and-ipv6-a.patch b/queue-6.1/mptcp-let-the-in-kernel-pm-use-mixed-ipv4-and-ipv6-a.patch
deleted file mode 100644 (file)
index f9b6cf1..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-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
-
index 8a07620ffbb03b6376d1af9153df5f7ebfff4207..7fa940e88f3ae06a06f41d62b9bbab515f1fa8ea 100644 (file)
@@ -3,8 +3,6 @@ drm-meson-fix-unbind-path-if-hdmi-fails-to-bind.patch
 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
@@ -97,3 +95,7 @@ pmdomain-qcom-rpmhpd-fix-enabled_corner-aggregation.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