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: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
131a627751
commit
ccae357c1c
@ -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 socket *ssock;
|
||||
int err = -EINVAL;
|
||||
struct sock *ssk;
|
||||
|
||||
ssock = __mptcp_nmpc_socket(msk);
|
||||
if (IS_ERR(ssock))
|
||||
return PTR_ERR(ssock);
|
||||
|
||||
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
|
||||
/* 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))
|
||||
if (rcu_access_pointer(tcp_sk(ssk)->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);
|
||||
if (subflow->request_mptcp && mptcp_token_new_connect(ssk)) {
|
||||
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_TOKENFALLBACKINIT);
|
||||
mptcp_subflow_early_fallback(msk, subflow);
|
||||
}
|
||||
if (likely(!__mptcp_check_fallback(msk)))
|
||||
@ -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
|
||||
* acquired the subflow socket lock, too.
|
||||
*/
|
||||
if (msk->fastopening)
|
||||
err = __inet_stream_connect(ssock, uaddr, addr_len, O_NONBLOCK, 1);
|
||||
else
|
||||
err = inet_stream_connect(ssock, uaddr, addr_len, O_NONBLOCK);
|
||||
inet_sk(sk)->defer_connect = inet_sk(ssock->sk)->defer_connect;
|
||||
if (!msk->fastopening)
|
||||
lock_sock(ssk);
|
||||
|
||||
/* the following mirrors closely a very small chunk of code from
|
||||
* __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
|
||||
* subflow_finish_connect()
|
||||
*/
|
||||
if (unlikely(err && err != -EINPROGRESS)) {
|
||||
if (unlikely(err)) {
|
||||
/* avoid leaving a dangling token in an unconnected socket */
|
||||
mptcp_token_destroy(msk);
|
||||
inet_sk_state_store(sk, inet_sk_state_load(ssock->sk));
|
||||
inet_sk_state_store(sk, TCP_CLOSE);
|
||||
return err;
|
||||
}
|
||||
|
||||
mptcp_copy_inaddrs(sk, ssock->sk);
|
||||
|
||||
/* silence EINPROGRESS and let the caller inet_stream_connect
|
||||
* handle the connection in progress
|
||||
*/
|
||||
mptcp_copy_inaddrs(sk, ssk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user