Skip to content

Commit

Permalink
mptcp: more accurate MPC endpoint tracking
Browse files Browse the repository at this point in the history
Currently the id accounting for the ID 0 subflow is not correct:
at creation time we mark (correctly) as unavailable the endpoint
id corresponding the MPC subflow source address, while at subflow
removal time set as available the id 0.

With this change we track explicitly the endpoint id corresponding
to the MPC subflow so that we can mark it as available at removal time.
Additionally this allow deleting the initial subflow via the NL PM
specifying the corresponding endpoint id.

Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Paolo Abeni authored and Jakub Kicinski committed Jul 13, 2022
1 parent c157bbe commit 3ad14f5
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
21 changes: 14 additions & 7 deletions net/mptcp/pm_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
entry = __lookup_addr(pernet, &mpc_addr, false);
if (entry) {
__clear_bit(entry->addr.id, msk->pm.id_avail_bitmap);
msk->mpc_endpoint_id = entry->addr.id;
backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
}
rcu_read_unlock();
Expand Down Expand Up @@ -764,6 +765,11 @@ int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
return -EINVAL;
}

static bool mptcp_local_id_match(const struct mptcp_sock *msk, u8 local_id, u8 id)
{
return local_id == id || (!local_id && msk->mpc_endpoint_id == id);
}

static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
const struct mptcp_rm_list *rm_list,
enum linux_mptcp_mib_field rm_type)
Expand All @@ -787,22 +793,23 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
return;

for (i = 0; i < rm_list->nr; i++) {
u8 rm_id = rm_list->ids[i];
bool removed = false;

list_for_each_entry_safe(subflow, tmp, &msk->conn_list, node) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
u8 id = subflow->local_id;

if (rm_type == MPTCP_MIB_RMADDR)
id = subflow->remote_id;

if (rm_list->ids[i] != id)
if (rm_type == MPTCP_MIB_RMADDR && subflow->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",
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_list->ids[i], subflow->local_id, subflow->remote_id);
i, rm_id, subflow->local_id, subflow->remote_id,
msk->mpc_endpoint_id);
spin_unlock_bh(&msk->pm.lock);
mptcp_subflow_shutdown(sk, ssk, how);

Expand All @@ -814,7 +821,7 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
__MPTCP_INC_STATS(sock_net(sk), rm_type);
}
if (rm_type == MPTCP_MIB_RMSUBFLOW)
__set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap);
__set_bit(rm_id ? rm_id : msk->mpc_endpoint_id, msk->pm.id_avail_bitmap);
if (!removed)
continue;

Expand Down
1 change: 1 addition & 0 deletions net/mptcp/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ struct mptcp_sock {
bool use_64bit_ack; /* Set when we received a 64-bit DSN */
bool csum_enabled;
bool allow_infinite_fallback;
u8 mpc_endpoint_id;
u8 recvmsg_inq:1,
cork:1,
nodelay:1;
Expand Down

0 comments on commit 3ad14f5

Please sign in to comment.