From nobody Thu Apr 25 11:49:22 2024 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 D46071FB0 for ; Tue, 17 Jan 2023 07:37:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1673941039; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=STOWPGwSE773zhlawTEXcElOJSTVsESesy8J/2SHfTI=; b=REjnvtU3itUOiP85ch3lfyq6WRUzBjjtglDLZntbJWL16rYjDnLoCgXzfUbpsfuOda1Lqg 9qGua+2svQPl1nMljsxoJQVcy/MpicRjYeZJjKNHui6Wwp6Wjv9KP5CjJc/Zi4PtxspQnm GWDgrB6Y0bCpxpn8izuHamhN5Pk5XAU= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-526-zNqd7FJTOAOwB-FbJmfYpw-1; Tue, 17 Jan 2023 02:37:18 -0500 X-MC-Unique: zNqd7FJTOAOwB-FbJmfYpw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 98B9980D0E3 for ; Tue, 17 Jan 2023 07:37:18 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.39.192.87]) by smtp.corp.redhat.com (Postfix) with ESMTP id 27D7740C2004 for ; Tue, 17 Jan 2023 07:37:18 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH mptcp-next v2 08/13] mptcp: move first subflow allocation at mpc access time Date: Tue, 17 Jan 2023 08:36:28 +0100 Message-Id: In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" In the long run this will simplify the mptcp code and will allow for more consistent behavior. Move the first subflow allocation out of the sock->init ops into the __mptcp_nmpc_socket() helper. Since the first subflow creation can now happen after the first setsockopt() we additionally need to invoke mptcp_sockopt_sync() on it. Signed-off-by: Paolo Abeni --- v1 -> v2: - really remove subflow creation from init() (!!!) --- net/mptcp/pm_netlink.c | 4 +-- net/mptcp/protocol.c | 61 +++++++++++++++++++++++++----------------- net/mptcp/protocol.h | 2 +- net/mptcp/sockopt.c | 20 +++++++------- 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index 155916174841..d1d859517d91 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -1016,8 +1016,8 @@ static int mptcp_pm_nl_create_listen_socket(struct so= ck *sk, lock_sock(newsk); ssock =3D __mptcp_nmpc_socket(mptcp_sk(newsk)); release_sock(newsk); - if (!ssock) - return -EINVAL; + if (IS_ERR(ssock)) + return PTR_ERR(ssock); =20 mptcp_info2sockaddr(&entry->addr, &addr, entry->addr.family); #if IS_ENABLED(CONFIG_MPTCP_IPV6) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 9c4c729bf271..4f7a71561efd 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -49,18 +49,6 @@ static void __mptcp_check_send_data_fin(struct sock *sk); DEFINE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions); static struct net_device mptcp_napi_dev; =20 -/* If msk has an initial subflow socket, and the MP_CAPABLE handshake has = not - * completed yet or has failed, return the subflow socket. - * Otherwise return NULL. - */ -struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk) -{ - if (!msk->subflow || READ_ONCE(msk->can_ack)) - return NULL; - - return msk->subflow; -} - /* Returns end sequence number of the receiver's advertised window */ static u64 mptcp_wnd_end(const struct mptcp_sock *msk) { @@ -116,6 +104,31 @@ static int __mptcp_socket_create(struct mptcp_sock *ms= k) return 0; } =20 +/* Returns the first subflow socket if available and the MPC + * handshake is not started yet. + */ +struct socket *__mptcp_nmpc_socket(struct mptcp_sock *msk) +{ + struct sock *sk =3D (struct sock *)msk; + int ret; + + if (!((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) + return ERR_PTR(-EINVAL); + + if (!msk->subflow) { + if (msk->first) + return ERR_PTR(-EINVAL); + + ret =3D __mptcp_socket_create(msk); + if (ret) + return ERR_PTR(ret); + + mptcp_sockopt_sync(msk, msk->first); + } + + return msk->subflow; +} + static void mptcp_drop(struct sock *sk, struct sk_buff *skb) { sk_drops_add(sk, skb); @@ -1699,6 +1712,7 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, st= ruct msghdr *msg, { unsigned int saved_flags =3D msg->msg_flags; struct mptcp_sock *msk =3D mptcp_sk(sk); + struct socket *ssock; struct sock *ssk; int ret; =20 @@ -1708,8 +1722,11 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, s= truct msghdr *msg, * Since the defer_connect flag is cleared after the first succsful * fastopen attempt, no need to check for additional subflow status. */ - if (msg->msg_flags & MSG_FASTOPEN && !__mptcp_nmpc_socket(msk)) - return -EINVAL; + if (msg->msg_flags & MSG_FASTOPEN) { + ssock =3D __mptcp_nmpc_socket(msk); + if (IS_ERR(ssock)) + return PTR_ERR(ssock); + } if (!msk->first) return -EINVAL; =20 @@ -2768,10 +2785,6 @@ static int mptcp_init_sock(struct sock *sk) if (unlikely(!net->mib.mptcp_statistics) && !mptcp_mib_alloc(net)) return -ENOMEM; =20 - ret =3D __mptcp_socket_create(mptcp_sk(sk)); - if (ret) - return ret; - ret =3D mptcp_init_sched(mptcp_sk(sk), mptcp_sched_find(mptcp_get_scheduler(net))); if (ret) @@ -3592,8 +3605,8 @@ static int mptcp_connect(struct sock *sk, struct sock= addr *uaddr, int addr_len) int err =3D -EINVAL; =20 ssock =3D __mptcp_nmpc_socket(msk); - if (!ssock) - return -EINVAL; + if (IS_ERR(ssock)) + return PTR_ERR(ssock); =20 mptcp_token_destroy(msk); inet_sk_state_store(sk, TCP_SYN_SENT); @@ -3681,8 +3694,8 @@ static int mptcp_bind(struct socket *sock, struct soc= kaddr *uaddr, int addr_len) =20 lock_sock(sock->sk); ssock =3D __mptcp_nmpc_socket(msk); - if (!ssock) { - err =3D -EINVAL; + if (IS_ERR(ssock)) { + err =3D PTR_ERR(ssock); goto unlock; } =20 @@ -3718,8 +3731,8 @@ static int mptcp_listen(struct socket *sock, int back= log) =20 lock_sock(sk); ssock =3D __mptcp_nmpc_socket(msk); - if (!ssock) { - err =3D -EINVAL; + if (IS_ERR(ssock)) { + err =3D PTR_ERR(ssock); goto unlock; } =20 diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 5f1a30959b5c..3a055438c65e 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -632,7 +632,7 @@ void __mptcp_subflow_send_ack(struct sock *ssk); void mptcp_subflow_reset(struct sock *ssk); void mptcp_subflow_queue_clean(struct sock *sk, struct sock *ssk); void mptcp_sock_graft(struct sock *sk, struct socket *parent); -struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk); +struct socket *__mptcp_nmpc_socket(struct mptcp_sock *msk); bool __mptcp_close(struct sock *sk, long timeout); void mptcp_cancel_work(struct sock *sk); void mptcp_set_owner_r(struct sk_buff *skb, struct sock *sk); diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index 8a9656248b0f..9bddae9c5c58 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -301,9 +301,9 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_soc= k *msk, int optname, case SO_BINDTOIFINDEX: lock_sock(sk); ssock =3D __mptcp_nmpc_socket(msk); - if (!ssock) { + if (IS_ERR(ssock)) { release_sock(sk); - return -EINVAL; + return PTR_ERR(ssock); } =20 ret =3D sock_setsockopt(ssock, SOL_SOCKET, optname, optval, optlen); @@ -396,9 +396,9 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, = int optname, case IPV6_FREEBIND: lock_sock(sk); ssock =3D __mptcp_nmpc_socket(msk); - if (!ssock) { + if (IS_ERR(ssock)) { release_sock(sk); - return -EINVAL; + return PTR_ERR(ssock); } =20 ret =3D tcp_setsockopt(ssock->sk, SOL_IPV6, optname, optval, optlen); @@ -693,9 +693,9 @@ static int mptcp_setsockopt_sol_ip_set_transparent(stru= ct mptcp_sock *msk, int o lock_sock(sk); =20 ssock =3D __mptcp_nmpc_socket(msk); - if (!ssock) { + if (IS_ERR(ssock)) { release_sock(sk); - return -EINVAL; + return PTR_ERR(ssock); } =20 issk =3D inet_sk(ssock->sk); @@ -762,13 +762,15 @@ static int mptcp_setsockopt_first_sf_only(struct mptc= p_sock *msk, int level, int { struct sock *sk =3D (struct sock *)msk; struct socket *sock; - int ret =3D -EINVAL; + int ret; =20 /* Limit to first subflow, before the connection establishment */ lock_sock(sk); sock =3D __mptcp_nmpc_socket(msk); - if (!sock) + if (IS_ERR(sock)) { + ret =3D PTR_ERR(sock); goto unlock; + } =20 ret =3D tcp_setsockopt(sock->sk, level, optname, optval, optlen); =20 @@ -872,7 +874,7 @@ static int mptcp_getsockopt_first_sf_only(struct mptcp_= sock *msk, int level, int } =20 ssock =3D __mptcp_nmpc_socket(msk); - if (!ssock) + if (IS_ERR(ssock)) goto out; =20 ret =3D tcp_getsockopt(ssock->sk, level, optname, optval, optlen); --=20 2.39.0