+++ /dev/null
-From 6834097fc38c5416701c793da94558cea49c0a1f Mon Sep 17 00:00:00 2001
-From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
-Date: Sat, 27 Jul 2024 12:01:28 +0200
-Subject: mptcp: pm: fix backup support in signal endpoints
-
-From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
-
-commit 6834097fc38c5416701c793da94558cea49c0a1f upstream.
-
-There was a support for signal endpoints, but only when the endpoint's
-flag was changed during a connection. If an endpoint with the signal and
-backup was already present, the MP_JOIN reply was not containing the
-backup flag as expected.
-
-That's confusing to have this inconsistent behaviour. On the other hand,
-the infrastructure to set the backup flag in the SYN + ACK + MP_JOIN was
-already there, it was just never set before. Now when requesting the
-local ID from the path-manager, the backup status is also requested.
-
-Note that when the userspace PM is used, the backup flag can be set if
-the local address was already used before with a backup flag, e.g. if
-the address was announced with the 'backup' flag, or a subflow was
-created with the 'backup' flag.
-
-Fixes: 4596a2c1b7f5 ("mptcp: allow creating non-backup subflows")
-Cc: stable@vger.kernel.org
-Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/507
-Reviewed-by: Mat Martineau <martineau@kernel.org>
-Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- net/mptcp/pm.c | 12 ++++++++++++
- net/mptcp/pm_netlink.c | 18 ++++++++++++++++++
- net/mptcp/pm_userspace.c | 18 ++++++++++++++++++
- net/mptcp/protocol.h | 3 +++
- net/mptcp/subflow.c | 3 +++
- 5 files changed, 54 insertions(+)
-
-diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
-index 55406720c607..23bb89c94e90 100644
---- a/net/mptcp/pm.c
-+++ b/net/mptcp/pm.c
-@@ -426,6 +426,18 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
- return mptcp_pm_nl_get_local_id(msk, &skc_local);
- }
-
-+bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc)
-+{
-+ struct mptcp_addr_info skc_local;
-+
-+ mptcp_local_address((struct sock_common *)skc, &skc_local);
-+
-+ if (mptcp_pm_is_userspace(msk))
-+ return mptcp_userspace_pm_is_backup(msk, &skc_local);
-+
-+ return mptcp_pm_nl_is_backup(msk, &skc_local);
-+}
-+
- int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
- u8 *flags, int *ifindex)
- {
-diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
-index 7635fac91539..37954a0b087d 100644
---- a/net/mptcp/pm_netlink.c
-+++ b/net/mptcp/pm_netlink.c
-@@ -1101,6 +1101,24 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc
- return ret;
- }
-
-+bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc)
-+{
-+ struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
-+ struct mptcp_pm_addr_entry *entry;
-+ bool backup = false;
-+
-+ rcu_read_lock();
-+ list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
-+ if (mptcp_addresses_equal(&entry->addr, skc, entry->addr.port)) {
-+ backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
-+ break;
-+ }
-+ }
-+ rcu_read_unlock();
-+
-+ return backup;
-+}
-+
- #define MPTCP_PM_CMD_GRP_OFFSET 0
- #define MPTCP_PM_EV_GRP_OFFSET 1
-
-diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
-index f0a4590506c6..8eaa9fbe3e34 100644
---- a/net/mptcp/pm_userspace.c
-+++ b/net/mptcp/pm_userspace.c
-@@ -165,6 +165,24 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
- return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry, true);
- }
-
-+bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
-+ struct mptcp_addr_info *skc)
-+{
-+ struct mptcp_pm_addr_entry *entry;
-+ bool backup = false;
-+
-+ spin_lock_bh(&msk->pm.lock);
-+ list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
-+ if (mptcp_addresses_equal(&entry->addr, skc, false)) {
-+ backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
-+ break;
-+ }
-+ }
-+ spin_unlock_bh(&msk->pm.lock);
-+
-+ return backup;
-+}
-+
- int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
- {
- struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
-diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
-index b8b25124e7de..60c6b073d65f 100644
---- a/net/mptcp/protocol.h
-+++ b/net/mptcp/protocol.h
-@@ -1109,6 +1109,9 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
- int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
- int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
- int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
-+bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc);
-+bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
-+bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
- int mptcp_pm_dump_addr(struct sk_buff *msg, struct netlink_callback *cb);
- int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
- struct netlink_callback *cb);
-diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
-index be406197b1c4..0e4b5bfbeaa1 100644
---- a/net/mptcp/subflow.c
-+++ b/net/mptcp/subflow.c
-@@ -100,6 +100,7 @@ static struct mptcp_sock *subflow_token_join_request(struct request_sock *req)
- return NULL;
- }
- subflow_req->local_id = local_id;
-+ subflow_req->request_bkup = mptcp_pm_is_backup(msk, (struct sock_common *)req);
-
- return msk;
- }
-@@ -620,6 +621,8 @@ static int subflow_chk_local_id(struct sock *sk)
- return err;
-
- subflow_set_local_id(subflow, err);
-+ subflow->request_bkup = mptcp_pm_is_backup(msk, (struct sock_common *)sk);
-+
- return 0;
- }
-
---
-2.46.0
-