From nobody Mon Feb 9 07:05:54 2026 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D08136AB7 for ; Fri, 21 Oct 2022 22:59:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1666393144; x=1697929144; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=BVoQO49mbb5TcS4QVTWYXVSx7xX/0TjdWjL77zoQ0eU=; b=h7Kk6SjyOQ6Ej7HqguKaav4IHL1GI4BCkbeYaqHE1pzVfgBYCQCl0BfT hmvV9hsucNr0I3HFBk8Q1aZMMGdI9H2/l+251lUZJJUNSh6Ni2NJds7PZ eo+1Nl1+gSQZp03DY4ciclZDmAI+hgtV7VfQ/CKKrZyP0aVHIXbenIA7d COlhwrVgqDpsq+G01wEpxFDBiYMyhYx0jXm8Xjz6paU9HM1A3EB0Eu8E6 b+BVeeJzXoYDv3Zo7E1mYshg5rCLsWqii05lI8wUVGCoHzgaGFHrBUs5u D7+2acRNqjNt4DepKNQirbx67L10s/4+9UJYj17Tf1cPm6hab3IXeo3WZ A==; X-IronPort-AV: E=McAfee;i="6500,9779,10507"; a="333699092" X-IronPort-AV: E=Sophos;i="5.95,203,1661842800"; d="scan'208";a="333699092" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2022 15:59:02 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10507"; a="663928732" X-IronPort-AV: E=Sophos;i="5.95,203,1661842800"; d="scan'208";a="663928732" Received: from tremple-mobl1.amr.corp.intel.com (HELO mjmartin-desk2.intel.com) ([10.209.66.81]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2022 15:59:01 -0700 From: Mat Martineau To: netdev@vger.kernel.org Cc: Paolo Abeni , davem@davemloft.net, kuba@kernel.org, edumazet@google.com, dmytro@shytyi.net, benjamin.hesmans@tessares.net, matthieu.baerts@tessares.net, mptcp@lists.linux.dev, Mat Martineau Subject: [PATCH net 2/3] mptcp: factor out mptcp_connect() Date: Fri, 21 Oct 2022 15:58:55 -0700 Message-Id: <20221021225856.88119-3-mathew.j.martineau@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221021225856.88119-1-mathew.j.martineau@linux.intel.com> References: <20221021225856.88119-1-mathew.j.martineau@linux.intel.com> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Paolo Abeni The current MPTCP connect implementation duplicates a bit of inet code and does not use nor provide a struct proto->connect callback, which in turn will not fit the upcoming fastopen implementation. Refactor such implementation to use the common helper, moving the MPTCP-specific bits into mptcp_connect(). Additionally, avoid an indirect call to the subflow connect callback. Note that the fastopen call-path invokes mptcp_connect() while already holding the subflow socket lock. Explicitly keep track of such path via a new MPTCP-level flag and handle the locking accordingly. Additionally, track the connect flags in a new msk field to allow propagating them to the subflow inet_stream_connect call. Fixes: d98a82a6afc7 ("mptcp: handle defer connect in mptcp_sendmsg") Reviewed-by: Mat Martineau Signed-off-by: Paolo Abeni Signed-off-by: Mat Martineau --- net/mptcp/protocol.c | 136 ++++++++++++++++++++++--------------------- net/mptcp/protocol.h | 4 +- 2 files changed, 73 insertions(+), 67 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index e33f9caf409d..f2930699c6d3 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1698,7 +1698,10 @@ static int mptcp_sendmsg(struct sock *sk, struct msg= hdr *msg, size_t len) =20 lock_sock(ssk); =20 + msk->connect_flags =3D (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0; + msk->is_sendmsg =3D 1; ret =3D tcp_sendmsg_fastopen(ssk, msg, &copied_syn, len, NULL); + msk->is_sendmsg =3D 0; copied +=3D copied_syn; if (ret =3D=3D -EINPROGRESS && copied_syn > 0) { /* reflect the new state on the MPTCP socket */ @@ -3507,10 +3510,73 @@ static int mptcp_ioctl(struct sock *sk, int cmd, un= signed long arg) return put_user(answ, (int __user *)arg); } =20 +static void mptcp_subflow_early_fallback(struct mptcp_sock *msk, + struct mptcp_subflow_context *subflow) +{ + subflow->request_mptcp =3D 0; + __mptcp_do_fallback(msk); +} + +static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr= _len) +{ + struct mptcp_subflow_context *subflow; + struct mptcp_sock *msk =3D mptcp_sk(sk); + struct socket *ssock; + int err =3D -EINVAL; + + ssock =3D __mptcp_nmpc_socket(msk); + if (!ssock) + return -EINVAL; + + mptcp_token_destroy(msk); + inet_sk_state_store(sk, TCP_SYN_SENT); + subflow =3D mptcp_subflow_ctx(ssock->sk); +#ifdef CONFIG_TCP_MD5SIG + /* no MPTCP if MD5SIG is enabled on this socket or we may run out of + * TCP option space. + */ + if (rcu_access_pointer(tcp_sk(ssock->sk)->md5sig_info)) + mptcp_subflow_early_fallback(msk, subflow); +#endif + if (subflow->request_mptcp && mptcp_token_new_connect(ssock->sk)) { + MPTCP_INC_STATS(sock_net(ssock->sk), MPTCP_MIB_TOKENFALLBACKINIT); + mptcp_subflow_early_fallback(msk, subflow); + } + if (likely(!__mptcp_check_fallback(msk))) + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVE); + + /* if reaching here via the fastopen/sendmsg path, the caller already + * acquired the subflow socket lock, too. + */ + if (msk->is_sendmsg) + err =3D __inet_stream_connect(ssock, uaddr, addr_len, msk->connect_flags= , 1); + else + err =3D inet_stream_connect(ssock, uaddr, addr_len, msk->connect_flags); + inet_sk(sk)->defer_connect =3D inet_sk(ssock->sk)->defer_connect; + + /* on successful connect, the msk state will be moved to established by + * subflow_finish_connect() + */ + if (unlikely(err && err !=3D -EINPROGRESS)) { + inet_sk_state_store(sk, inet_sk_state_load(ssock->sk)); + return err; + } + + mptcp_copy_inaddrs(sk, ssock->sk); + + /* unblocking connect, mptcp-level inet_stream_connect will error out + * without changing the socket state, update it here. + */ + if (err =3D=3D -EINPROGRESS) + sk->sk_socket->state =3D ssock->state; + return err; +} + static struct proto mptcp_prot =3D { .name =3D "MPTCP", .owner =3D THIS_MODULE, .init =3D mptcp_init_sock, + .connect =3D mptcp_connect, .disconnect =3D mptcp_disconnect, .close =3D mptcp_close, .accept =3D mptcp_accept, @@ -3562,78 +3628,16 @@ static int mptcp_bind(struct socket *sock, struct s= ockaddr *uaddr, int addr_len) return err; } =20 -static void mptcp_subflow_early_fallback(struct mptcp_sock *msk, - struct mptcp_subflow_context *subflow) -{ - subflow->request_mptcp =3D 0; - __mptcp_do_fallback(msk); -} - static int mptcp_stream_connect(struct socket *sock, struct sockaddr *uadd= r, int addr_len, int flags) { - struct mptcp_sock *msk =3D mptcp_sk(sock->sk); - struct mptcp_subflow_context *subflow; - struct socket *ssock; - int err =3D -EINVAL; + int ret; =20 lock_sock(sock->sk); - if (uaddr) { - if (addr_len < sizeof(uaddr->sa_family)) - goto unlock; - - if (uaddr->sa_family =3D=3D AF_UNSPEC) { - err =3D mptcp_disconnect(sock->sk, flags); - sock->state =3D err ? SS_DISCONNECTING : SS_UNCONNECTED; - goto unlock; - } - } - - if (sock->state !=3D SS_UNCONNECTED && msk->subflow) { - /* pending connection or invalid state, let existing subflow - * cope with that - */ - ssock =3D msk->subflow; - goto do_connect; - } - - ssock =3D __mptcp_nmpc_socket(msk); - if (!ssock) - goto unlock; - - mptcp_token_destroy(msk); - inet_sk_state_store(sock->sk, TCP_SYN_SENT); - subflow =3D mptcp_subflow_ctx(ssock->sk); -#ifdef CONFIG_TCP_MD5SIG - /* no MPTCP if MD5SIG is enabled on this socket or we may run out of - * TCP option space. - */ - if (rcu_access_pointer(tcp_sk(ssock->sk)->md5sig_info)) - mptcp_subflow_early_fallback(msk, subflow); -#endif - if (subflow->request_mptcp && mptcp_token_new_connect(ssock->sk)) { - MPTCP_INC_STATS(sock_net(ssock->sk), MPTCP_MIB_TOKENFALLBACKINIT); - mptcp_subflow_early_fallback(msk, subflow); - } - if (likely(!__mptcp_check_fallback(msk))) - MPTCP_INC_STATS(sock_net(sock->sk), MPTCP_MIB_MPCAPABLEACTIVE); - -do_connect: - err =3D ssock->ops->connect(ssock, uaddr, addr_len, flags); - inet_sk(sock->sk)->defer_connect =3D inet_sk(ssock->sk)->defer_connect; - sock->state =3D ssock->state; - - /* on successful connect, the msk state will be moved to established by - * subflow_finish_connect() - */ - if (!err || err =3D=3D -EINPROGRESS) - mptcp_copy_inaddrs(sock->sk, ssock->sk); - else - inet_sk_state_store(sock->sk, inet_sk_state_load(ssock->sk)); - -unlock: + mptcp_sk(sock->sk)->connect_flags =3D flags; + ret =3D __inet_stream_connect(sock, uaddr, addr_len, flags, 0); release_sock(sock->sk); - return err; + return ret; } =20 static int mptcp_listen(struct socket *sock, int backlog) diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index be19592441df..6a09ab99a12d 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -285,7 +285,9 @@ struct mptcp_sock { u8 mpc_endpoint_id; u8 recvmsg_inq:1, cork:1, - nodelay:1; + nodelay:1, + is_sendmsg:1; + int connect_flags; struct work_struct work; struct sk_buff *ooo_last_skb; struct rb_root out_of_order_queue; --=20 2.38.1