Skip to content

Commit 6834097

Browse files
matttbePaolo Abeni
authored andcommitted
mptcp: pm: fix backup support in signal endpoints
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: 4596a2c ("mptcp: allow creating non-backup subflows") Cc: stable@vger.kernel.org Closes: multipath-tcp/mptcp_net-next#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>
1 parent 935ff5b commit 6834097

5 files changed

Lines changed: 54 additions & 0 deletions

File tree

net/mptcp/pm.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,18 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
426426
return mptcp_pm_nl_get_local_id(msk, &skc_local);
427427
}
428428

429+
bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc)
430+
{
431+
struct mptcp_addr_info skc_local;
432+
433+
mptcp_local_address((struct sock_common *)skc, &skc_local);
434+
435+
if (mptcp_pm_is_userspace(msk))
436+
return mptcp_userspace_pm_is_backup(msk, &skc_local);
437+
438+
return mptcp_pm_nl_is_backup(msk, &skc_local);
439+
}
440+
429441
int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
430442
u8 *flags, int *ifindex)
431443
{

net/mptcp/pm_netlink.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,24 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc
11011101
return ret;
11021102
}
11031103

1104+
bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc)
1105+
{
1106+
struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
1107+
struct mptcp_pm_addr_entry *entry;
1108+
bool backup = false;
1109+
1110+
rcu_read_lock();
1111+
list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
1112+
if (mptcp_addresses_equal(&entry->addr, skc, entry->addr.port)) {
1113+
backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
1114+
break;
1115+
}
1116+
}
1117+
rcu_read_unlock();
1118+
1119+
return backup;
1120+
}
1121+
11041122
#define MPTCP_PM_CMD_GRP_OFFSET 0
11051123
#define MPTCP_PM_EV_GRP_OFFSET 1
11061124

net/mptcp/pm_userspace.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,24 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
165165
return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry, true);
166166
}
167167

168+
bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk,
169+
struct mptcp_addr_info *skc)
170+
{
171+
struct mptcp_pm_addr_entry *entry;
172+
bool backup = false;
173+
174+
spin_lock_bh(&msk->pm.lock);
175+
list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
176+
if (mptcp_addresses_equal(&entry->addr, skc, false)) {
177+
backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
178+
break;
179+
}
180+
}
181+
spin_unlock_bh(&msk->pm.lock);
182+
183+
return backup;
184+
}
185+
168186
int mptcp_pm_nl_announce_doit(struct sk_buff *skb, struct genl_info *info)
169187
{
170188
struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];

net/mptcp/protocol.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,9 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
11091109
int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
11101110
int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
11111111
int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
1112+
bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc);
1113+
bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
1114+
bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
11121115
int mptcp_pm_dump_addr(struct sk_buff *msg, struct netlink_callback *cb);
11131116
int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
11141117
struct netlink_callback *cb);

net/mptcp/subflow.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ static struct mptcp_sock *subflow_token_join_request(struct request_sock *req)
100100
return NULL;
101101
}
102102
subflow_req->local_id = local_id;
103+
subflow_req->request_bkup = mptcp_pm_is_backup(msk, (struct sock_common *)req);
103104

104105
return msk;
105106
}
@@ -620,6 +621,8 @@ static int subflow_chk_local_id(struct sock *sk)
620621
return err;
621622

622623
subflow_set_local_id(subflow, err);
624+
subflow->request_bkup = mptcp_pm_is_backup(msk, (struct sock_common *)sk);
625+
623626
return 0;
624627
}
625628

0 commit comments

Comments
 (0)