Commit ccae357c authored by Paolo Abeni's avatar Paolo Abeni Committed by David S. Miller

mptcp: avoid additional __inet_stream_connect() call

The mptcp protocol maintains an additional socket just to easily
invoke a few stream operations on the first subflow. One of them is
__inet_stream_connect().

We are going to remove the first subflow socket soon, so avoid
the additional indirection via at connect time, calling directly
into the sock-level connect() ops.

The sk-level connect never return -EINPROGRESS, cleanup the error
path accordingly. Additionally, the ssk status on error is always
TCP_CLOSE. Avoid unneeded access to the subflow sk state.

No functional change intended.
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Reviewed-by: default avatarMat Martineau <martineau@kernel.org>
Signed-off-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 131a6277
...@@ -3589,22 +3589,24 @@ static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -3589,22 +3589,24 @@ static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
struct mptcp_sock *msk = mptcp_sk(sk); struct mptcp_sock *msk = mptcp_sk(sk);
struct socket *ssock; struct socket *ssock;
int err = -EINVAL; int err = -EINVAL;
struct sock *ssk;
ssock = __mptcp_nmpc_socket(msk); ssock = __mptcp_nmpc_socket(msk);
if (IS_ERR(ssock)) if (IS_ERR(ssock))
return PTR_ERR(ssock); return PTR_ERR(ssock);
inet_sk_state_store(sk, TCP_SYN_SENT); inet_sk_state_store(sk, TCP_SYN_SENT);
subflow = mptcp_subflow_ctx(ssock->sk); ssk = msk->first;
subflow = mptcp_subflow_ctx(ssk);
#ifdef CONFIG_TCP_MD5SIG #ifdef CONFIG_TCP_MD5SIG
/* no MPTCP if MD5SIG is enabled on this socket or we may run out of /* no MPTCP if MD5SIG is enabled on this socket or we may run out of
* TCP option space. * TCP option space.
*/ */
if (rcu_access_pointer(tcp_sk(ssock->sk)->md5sig_info)) if (rcu_access_pointer(tcp_sk(ssk)->md5sig_info))
mptcp_subflow_early_fallback(msk, subflow); mptcp_subflow_early_fallback(msk, subflow);
#endif #endif
if (subflow->request_mptcp && mptcp_token_new_connect(ssock->sk)) { if (subflow->request_mptcp && mptcp_token_new_connect(ssk)) {
MPTCP_INC_STATS(sock_net(ssock->sk), MPTCP_MIB_TOKENFALLBACKINIT); MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_TOKENFALLBACKINIT);
mptcp_subflow_early_fallback(msk, subflow); mptcp_subflow_early_fallback(msk, subflow);
} }
if (likely(!__mptcp_check_fallback(msk))) if (likely(!__mptcp_check_fallback(msk)))
...@@ -3613,27 +3615,42 @@ static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -3613,27 +3615,42 @@ static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
/* if reaching here via the fastopen/sendmsg path, the caller already /* if reaching here via the fastopen/sendmsg path, the caller already
* acquired the subflow socket lock, too. * acquired the subflow socket lock, too.
*/ */
if (msk->fastopening) if (!msk->fastopening)
err = __inet_stream_connect(ssock, uaddr, addr_len, O_NONBLOCK, 1); lock_sock(ssk);
else
err = inet_stream_connect(ssock, uaddr, addr_len, O_NONBLOCK); /* the following mirrors closely a very small chunk of code from
inet_sk(sk)->defer_connect = inet_sk(ssock->sk)->defer_connect; * __inet_stream_connect()
*/
if (ssk->sk_state != TCP_CLOSE)
goto out;
if (BPF_CGROUP_PRE_CONNECT_ENABLED(ssk)) {
err = ssk->sk_prot->pre_connect(ssk, uaddr, addr_len);
if (err)
goto out;
}
err = ssk->sk_prot->connect(ssk, uaddr, addr_len);
if (err < 0)
goto out;
inet_sk(sk)->defer_connect = inet_sk(ssk)->defer_connect;
out:
if (!msk->fastopening)
release_sock(ssk);
/* on successful connect, the msk state will be moved to established by /* on successful connect, the msk state will be moved to established by
* subflow_finish_connect() * subflow_finish_connect()
*/ */
if (unlikely(err && err != -EINPROGRESS)) { if (unlikely(err)) {
/* avoid leaving a dangling token in an unconnected socket */ /* avoid leaving a dangling token in an unconnected socket */
mptcp_token_destroy(msk); mptcp_token_destroy(msk);
inet_sk_state_store(sk, inet_sk_state_load(ssock->sk)); inet_sk_state_store(sk, TCP_CLOSE);
return err; return err;
} }
mptcp_copy_inaddrs(sk, ssock->sk); mptcp_copy_inaddrs(sk, ssk);
/* silence EINPROGRESS and let the caller inet_stream_connect
* handle the connection in progress
*/
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment