Skip to content

Commit 1516ddb

Browse files
Paolo Abenigregkh
authored andcommitted
mptcp: refactor passive socket initialization
[ Upstream commit 3a236ae ] After commit 30e51b9 ("mptcp: fix unreleased socket in accept queue") unaccepted msk sockets go throu complete shutdown, we don't need anymore to delay inserting the first subflow into the subflow lists. The reference counting deserve some extra care, as __mptcp_close() is unaware of the request socket linkage to the first subflow. Please note that this is more a refactoring than a fix but because this modification is needed to include other corrections, see the following commits. Then a Fixes tag has been added here to help the stable team. Fixes: 30e51b9 ("mptcp: fix unreleased socket in accept queue") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net> Tested-by: Christoph Paasch <cpaasch@apple.com> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 75eb690 commit 1516ddb

2 files changed

Lines changed: 21 additions & 23 deletions

File tree

net/mptcp/protocol.c

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,6 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
834834
if (sk->sk_socket && !ssk->sk_socket)
835835
mptcp_sock_graft(ssk, sk->sk_socket);
836836

837-
mptcp_propagate_sndbuf((struct sock *)msk, ssk);
838837
mptcp_sockopt_sync_locked(msk, ssk);
839838
return true;
840839
}
@@ -3729,22 +3728,6 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
37293728

37303729
lock_sock(newsk);
37313730

3732-
/* PM/worker can now acquire the first subflow socket
3733-
* lock without racing with listener queue cleanup,
3734-
* we can notify it, if needed.
3735-
*
3736-
* Even if remote has reset the initial subflow by now
3737-
* the refcnt is still at least one.
3738-
*/
3739-
subflow = mptcp_subflow_ctx(msk->first);
3740-
list_add(&subflow->node, &msk->conn_list);
3741-
sock_hold(msk->first);
3742-
if (mptcp_is_fully_established(newsk))
3743-
mptcp_pm_fully_established(msk, msk->first, GFP_KERNEL);
3744-
3745-
mptcp_rcv_space_init(msk, msk->first);
3746-
mptcp_propagate_sndbuf(newsk, msk->first);
3747-
37483731
/* set ssk->sk_socket of accept()ed flows to mptcp socket.
37493732
* This is needed so NOSPACE flag can be set from tcp stack.
37503733
*/

net/mptcp/subflow.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,12 @@ void mptcp_subflow_reset(struct sock *ssk)
355355
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
356356
struct sock *sk = subflow->conn;
357357

358+
/* mptcp_mp_fail_no_response() can reach here on an already closed
359+
* socket
360+
*/
361+
if (ssk->sk_state == TCP_CLOSE)
362+
return;
363+
358364
/* must hold: tcp_done() could drop last reference on parent */
359365
sock_hold(sk);
360366

@@ -685,6 +691,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
685691
struct mptcp_options_received mp_opt;
686692
bool fallback, fallback_is_fatal;
687693
struct sock *new_msk = NULL;
694+
struct mptcp_sock *owner;
688695
struct sock *child;
689696

690697
pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn);
@@ -759,6 +766,8 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
759766
ctx->setsockopt_seq = listener->setsockopt_seq;
760767

761768
if (ctx->mp_capable) {
769+
owner = mptcp_sk(new_msk);
770+
762771
/* this can't race with mptcp_close(), as the msk is
763772
* not yet exposted to user-space
764773
*/
@@ -767,30 +776,36 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
767776
/* record the newly created socket as the first msk
768777
* subflow, but don't link it yet into conn_list
769778
*/
770-
WRITE_ONCE(mptcp_sk(new_msk)->first, child);
779+
WRITE_ONCE(owner->first, child);
771780

772781
/* new mpc subflow takes ownership of the newly
773782
* created mptcp socket
774783
*/
775784
mptcp_sk(new_msk)->setsockopt_seq = ctx->setsockopt_seq;
776-
mptcp_pm_new_connection(mptcp_sk(new_msk), child, 1);
777-
mptcp_token_accept(subflow_req, mptcp_sk(new_msk));
785+
mptcp_pm_new_connection(owner, child, 1);
786+
mptcp_token_accept(subflow_req, owner);
778787
ctx->conn = new_msk;
779788
new_msk = NULL;
780789

781790
/* set msk addresses early to ensure mptcp_pm_get_local_id()
782791
* uses the correct data
783792
*/
784793
mptcp_copy_inaddrs(ctx->conn, child);
794+
mptcp_propagate_sndbuf(ctx->conn, child);
795+
796+
mptcp_rcv_space_init(owner, child);
797+
list_add(&ctx->node, &owner->conn_list);
798+
sock_hold(child);
785799

786800
/* with OoO packets we can reach here without ingress
787801
* mpc option
788802
*/
789-
if (mp_opt.suboptions & OPTIONS_MPTCP_MPC)
803+
if (mp_opt.suboptions & OPTIONS_MPTCP_MPC) {
790804
mptcp_subflow_fully_established(ctx, &mp_opt);
805+
mptcp_pm_fully_established(owner, child, GFP_ATOMIC);
806+
ctx->pm_notified = 1;
807+
}
791808
} else if (ctx->mp_join) {
792-
struct mptcp_sock *owner;
793-
794809
owner = subflow_req->msk;
795810
if (!owner) {
796811
subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);

0 commit comments

Comments
 (0)