mptcp: create first subflow at msk creation time

This cleans the code a bit and makes the behavior more consistent.

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Davide Caratti <dcaratti@redhat.com>
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Paolo Abeni 2020-06-29 22:26:23 +02:00 committed by David S. Miller
parent d2f77c5334
commit fa68018dc4

View file

@ -86,32 +86,16 @@ static struct socket *__mptcp_tcp_fallback(struct mptcp_sock *msk)
return msk->subflow; return msk->subflow;
} }
static bool __mptcp_can_create_subflow(const struct mptcp_sock *msk) static int __mptcp_socket_create(struct mptcp_sock *msk)
{
return !msk->first;
}
static struct socket *__mptcp_socket_create(struct mptcp_sock *msk, int state)
{ {
struct mptcp_subflow_context *subflow; struct mptcp_subflow_context *subflow;
struct sock *sk = (struct sock *)msk; struct sock *sk = (struct sock *)msk;
struct socket *ssock; struct socket *ssock;
int err; int err;
ssock = __mptcp_tcp_fallback(msk);
if (unlikely(ssock))
return ssock;
ssock = __mptcp_nmpc_socket(msk);
if (ssock)
goto set_state;
if (!__mptcp_can_create_subflow(msk))
return ERR_PTR(-EINVAL);
err = mptcp_subflow_create_socket(sk, &ssock); err = mptcp_subflow_create_socket(sk, &ssock);
if (err) if (err)
return ERR_PTR(err); return err;
msk->first = ssock->sk; msk->first = ssock->sk;
msk->subflow = ssock; msk->subflow = ssock;
@ -124,10 +108,7 @@ static struct socket *__mptcp_socket_create(struct mptcp_sock *msk, int state)
*/ */
RCU_INIT_POINTER(msk->first->sk_wq, &sk->sk_socket->wq); RCU_INIT_POINTER(msk->first->sk_wq, &sk->sk_socket->wq);
set_state: return 0;
if (state != MPTCP_SAME_STATE)
inet_sk_state_store(sk, state);
return ssock;
} }
static void __mptcp_move_skb(struct mptcp_sock *msk, struct sock *ssk, static void __mptcp_move_skb(struct mptcp_sock *msk, struct sock *ssk,
@ -1255,6 +1236,10 @@ static int mptcp_init_sock(struct sock *sk)
if (ret) if (ret)
return ret; return ret;
ret = __mptcp_socket_create(mptcp_sk(sk));
if (ret)
return ret;
sk_sockets_allocated_inc(sk); sk_sockets_allocated_inc(sk);
sk->sk_sndbuf = sock_net(sk)->ipv4.sysctl_tcp_wmem[2]; sk->sk_sndbuf = sock_net(sk)->ipv4.sysctl_tcp_wmem[2];
@ -1744,9 +1729,9 @@ static int mptcp_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
int err; int err;
lock_sock(sock->sk); lock_sock(sock->sk);
ssock = __mptcp_socket_create(msk, MPTCP_SAME_STATE); ssock = __mptcp_nmpc_socket(msk);
if (IS_ERR(ssock)) { if (!ssock) {
err = PTR_ERR(ssock); err = -EINVAL;
goto unlock; goto unlock;
} }
@ -1776,13 +1761,14 @@ static int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr,
goto do_connect; goto do_connect;
} }
mptcp_token_destroy(msk); ssock = __mptcp_nmpc_socket(msk);
ssock = __mptcp_socket_create(msk, TCP_SYN_SENT); if (!ssock) {
if (IS_ERR(ssock)) { err = -EINVAL;
err = PTR_ERR(ssock);
goto unlock; goto unlock;
} }
mptcp_token_destroy(msk);
inet_sk_state_store(sock->sk, TCP_SYN_SENT);
subflow = mptcp_subflow_ctx(ssock->sk); subflow = mptcp_subflow_ctx(ssock->sk);
#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
@ -1820,13 +1806,14 @@ static int mptcp_listen(struct socket *sock, int backlog)
pr_debug("msk=%p", msk); pr_debug("msk=%p", msk);
lock_sock(sock->sk); lock_sock(sock->sk);
mptcp_token_destroy(msk); ssock = __mptcp_nmpc_socket(msk);
ssock = __mptcp_socket_create(msk, TCP_LISTEN); if (!ssock) {
if (IS_ERR(ssock)) { err = -EINVAL;
err = PTR_ERR(ssock);
goto unlock; goto unlock;
} }
mptcp_token_destroy(msk);
inet_sk_state_store(sock->sk, TCP_LISTEN);
sock_set_flag(sock->sk, SOCK_RCU_FREE); sock_set_flag(sock->sk, SOCK_RCU_FREE);
err = ssock->ops->listen(ssock, backlog); err = ssock->ops->listen(ssock, backlog);