diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 55406720c60711..98b0b31e3b8d59 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -405,7 +405,8 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, return ret; } -int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc) +int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc, + bool *backup) { struct mptcp_addr_info skc_local; struct mptcp_addr_info msk_local; @@ -413,6 +414,8 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc) if (WARN_ON_ONCE(!msk)) return -1; + *backup = false; + /* The 0 ID mapping is defined by the first subflow, copied into the msk * addr */ @@ -422,8 +425,8 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc) return 0; if (mptcp_pm_is_userspace(msk)) - return mptcp_userspace_pm_get_local_id(msk, &skc_local); - return mptcp_pm_nl_get_local_id(msk, &skc_local); + return mptcp_userspace_pm_get_local_id(msk, &skc_local, backup); + return mptcp_pm_nl_get_local_id(msk, &skc_local, backup); } int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id, diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index 7635fac9153989..44bfab3516937d 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -1064,7 +1064,8 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk, return err; } -int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc) +int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc, + bool *backup) { struct mptcp_pm_addr_entry *entry; struct pm_nl_pernet *pernet; @@ -1076,6 +1077,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) { if (mptcp_addresses_equal(&entry->addr, skc, entry->addr.port)) { ret = entry->addr.id; + *backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP); break; } } diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index f0a4590506c69a..adc015af168ea7 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -137,7 +137,7 @@ int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, } int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, - struct mptcp_addr_info *skc) + struct mptcp_addr_info *skc, bool *backup) { struct mptcp_pm_addr_entry *entry = NULL, *e, new_entry; __be16 msk_sport = ((struct inet_sock *) @@ -151,8 +151,10 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, } } spin_unlock_bh(&msk->pm.lock); - if (entry) + if (entry) { + *backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP); return entry->addr.id; + } memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry)); new_entry.addr = *skc; diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 6b6b76152db52a..cee0a8098b4160 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -1111,9 +1111,12 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb, bool *drop_other_suboptions); bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, struct mptcp_rm_list *rm_list); -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); +int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc, + bool *backup); +int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc, + bool *backup); +int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc, + bool *backup); 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 a3778aee4e77f8..955fb9aa2ce528 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -87,6 +87,7 @@ static struct mptcp_sock *subflow_token_join_request(struct request_sock *req) struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req); struct mptcp_sock *msk; int local_id; + bool backup; msk = mptcp_token_get_sock(sock_net(req_to_sk(req)), subflow_req->token); if (!msk) { @@ -94,12 +95,13 @@ static struct mptcp_sock *subflow_token_join_request(struct request_sock *req) return NULL; } - local_id = mptcp_pm_get_local_id(msk, (struct sock_common *)req); + local_id = mptcp_pm_get_local_id(msk, (struct sock_common *)req, &backup); if (local_id < 0) { sock_put((struct sock *)msk); return NULL; } subflow_req->local_id = local_id; + subflow_req->request_bkup = backup; return msk; } @@ -604,12 +606,13 @@ static int subflow_chk_local_id(struct sock *sk) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); struct mptcp_sock *msk = mptcp_sk(subflow->conn); + bool backup; int err; if (likely(subflow->local_id >= 0)) return 0; - err = mptcp_pm_get_local_id(msk, (struct sock_common *)sk); + err = mptcp_pm_get_local_id(msk, (struct sock_common *)sk, &backup); if (err < 0) return err; diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index 55d84a1bde15de..167914df05fa8e 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -2617,6 +2617,19 @@ backup_tests() # single address, backup if reset "single address, backup" && + continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then + pm_nl_set_limits $ns1 0 1 + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup + pm_nl_set_limits $ns2 1 1 + sflags=nobackup speed=slow \ + run_tests $ns1 $ns2 10.0.1.1 + chk_join_nr 1 1 1 + chk_add_nr 1 1 + chk_prio_nr 1 0 + fi + + # single address, switch to backup + if reset "single address, switch to backup" && continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then pm_nl_set_limits $ns1 0 1 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal @@ -2632,13 +2645,13 @@ backup_tests() if reset "single address with port, backup" && continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then pm_nl_set_limits $ns1 0 1 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100 + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup port 10100 pm_nl_set_limits $ns2 1 1 - sflags=backup speed=slow \ + sflags=nobackup speed=slow \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 1 1 1 chk_add_nr 1 1 - chk_prio_nr 1 1 + chk_prio_nr 1 0 fi if reset "mpc backup" &&