mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-20 07:09:58 +00:00
mptcp: fix active subflow finalization
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: 0530020a7c8f ("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>
This commit is contained in:
parent
6b9831bfd9
commit
55b47ca7d8
@ -825,6 +825,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;
|
||||
@ -839,6 +846,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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
@ -3515,11 +3525,6 @@ err_prohibited:
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user