Skip to content

Commit

Permalink
mptcp: fix active subflow finalization
Browse files Browse the repository at this point in the history
commit 55b47ca upstream.

Active subflow are inserted into the connection list at creation time.
When the MPJ handshake completes successfully, a new subflow creation
netlink event is generated correctly, but the current code wrongly
avoid initializing a couple of subflow data.

The above will cause misbehavior on a few exceptional events: unneeded
mptcp-level retransmission on msk-level sequence wrap-around and infinite
mapping fallback even when a MPJ socket is present.

Address the issue factoring out the needed initialization in a new helper
and invoking the latter from __mptcp_finish_join() time for passive
subflow and from mptcp_finish_join() for active ones.

Fixes: 0530020 ("mptcp: track and update contiguous data status")
Cc: stable@vger.kernel.org
Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Paolo Abeni authored and gregkh committed Jun 9, 2023
1 parent 977a63a commit 9ce0319
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions net/mptcp/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,13 @@ void mptcp_data_ready(struct sock *sk, struct sock *ssk)
mptcp_data_unlock(sk);
}

static void mptcp_subflow_joined(struct mptcp_sock *msk, struct sock *ssk)
{
mptcp_subflow_ctx(ssk)->map_seq = READ_ONCE(msk->ack_seq);
WRITE_ONCE(msk->allow_infinite_fallback, false);
mptcp_event(MPTCP_EVENT_SUB_ESTABLISHED, msk, ssk, GFP_ATOMIC);
}

static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
{
struct sock *sk = (struct sock *)msk;
Expand All @@ -835,6 +842,7 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
mptcp_sock_graft(ssk, sk->sk_socket);

mptcp_sockopt_sync_locked(msk, ssk);
mptcp_subflow_joined(msk, ssk);
return true;
}

Expand Down Expand Up @@ -3485,14 +3493,16 @@ bool mptcp_finish_join(struct sock *ssk)
return false;
}

if (!list_empty(&subflow->node))
goto out;
/* active subflow, already present inside the conn_list */
if (!list_empty(&subflow->node)) {
mptcp_subflow_joined(msk, ssk);
return true;
}

if (!mptcp_pm_allow_new_subflow(msk))
goto err_prohibited;

/* active connections are already on conn_list.
* If we can't acquire msk socket lock here, let the release callback
/* If we can't acquire msk socket lock here, let the release callback
* handle it
*/
mptcp_data_lock(parent);
Expand All @@ -3515,11 +3525,6 @@ bool mptcp_finish_join(struct sock *ssk)
return false;
}

subflow->map_seq = READ_ONCE(msk->ack_seq);
WRITE_ONCE(msk->allow_infinite_fallback, false);

out:
mptcp_event(MPTCP_EVENT_SUB_ESTABLISHED, msk, ssk, GFP_ATOMIC);
return true;
}

Expand Down

0 comments on commit 9ce0319

Please sign in to comment.