From nobody Sun Feb 8 19:37:52 2026 Delivered-To: wpasupplicant.patchew@gmail.com Received: by 2002:a05:6638:38c:0:0:0:0 with SMTP id y12csp1899763jap; Thu, 6 Jan 2022 16:21:04 -0800 (PST) X-Google-Smtp-Source: ABdhPJwxvzCSFMSx6mmu2UH/rAqtcz9KKh54Kf6u02qf86p2GLemavp/GI0lXkHSxLuFqOo8ICiD X-Received: by 2002:aa7:8503:0:b0:4ba:7304:e9af with SMTP id v3-20020aa78503000000b004ba7304e9afmr62170148pfn.45.1641514864695; Thu, 06 Jan 2022 16:21:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1641514864; cv=none; d=google.com; s=arc-20160816; b=PXE2jK0vIyddl/urA3Dg7dhE2j7XE34N1LWAqmEqgeToyboY38A2JO3eR8md02Nk+I JJwgmiDtDaVlXl9qocGBQmL5802VrOxMtKKGtkBsjAeyUGuoOTjgv7Dd1IBEQp0YTb7I Btlc3E5eHGN9QagKN3w44CvVdya6HgUj+po+GgI4QT4wGj6cfc9rLbOlJR6Q6R9pr4/i u+jQVIV+AkdRB+DXdhfRjdWg4yR0sHr3M4wewQGYLyb0OE2zQzddRleB2JP3FuH8oDDw UuZgnE34nDe3eZJTOPrK3PXDzgNL60R8lFcLX1qYw4xlqm1pJpcfFMzYozDuI3TUhptz e6lQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=I2yQqDJgqv2Mf3aervuxeJKOa1yg3EOl3iY6ybRjYFc=; b=s7F8yQcjEZ9ba3sICaaIuarH21VNjdfuO9PP95xjuazyefI6e1YbaP9oJ5LKa7NhQr mhrl/A/EYGWLZPLNLi0TzXwAykxXuy57K26tmkXVNyS8/whLCfG6Z5F/AVmgwLshK2oB 5AL5P5My2+hQoggrQp4FoU4QidmMuX0Kn6oIgVW3PdIHLXPSa56ZIJ5zqFebs7WRtKt0 6K/+OtyvKSHxYe5ae8i3JVFcwLtZAmT9SwzsEH1u/N9nmHioassryqRpBz0MqSodC0NN kXcU3uzhy6LieECUTG7YwLTDkJS4FMVn9hulrskyQH1+DsDd0PMOOf++9/dWwNond5Af 91FA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=gGDf9qu+; spf=pass (google.com: domain of mptcp+bounces-2956-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 147.75.69.165 as permitted sender) smtp.mailfrom="mptcp+bounces-2956-wpasupplicant.patchew=gmail.com@lists.linux.dev"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from sjc.edge.kernel.org (sjc.edge.kernel.org. [147.75.69.165]) by mx.google.com with ESMTPS id e64si3255480pgc.578.2022.01.06.16.21.04 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 06 Jan 2022 16:21:04 -0800 (PST) Received-SPF: pass (google.com: domain of mptcp+bounces-2956-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 147.75.69.165 as permitted sender) client-ip=147.75.69.165; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=gGDf9qu+; spf=pass (google.com: domain of mptcp+bounces-2956-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 147.75.69.165 as permitted sender) smtp.mailfrom="mptcp+bounces-2956-wpasupplicant.patchew=gmail.com@lists.linux.dev"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sjc.edge.kernel.org (Postfix) with ESMTPS id DC9953E0F05 for ; Fri, 7 Jan 2022 00:21:03 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id F05682CAE; Fri, 7 Jan 2022 00:20:55 +0000 (UTC) X-Original-To: mptcp@lists.linux.dev Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (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 78E6A2C9D for ; Fri, 7 Jan 2022 00:20:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1641514853; x=1673050853; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1xG00dTFemk6+91lOhqDScRK+4QN48IfmgSY6haTzCs=; b=gGDf9qu+FQTdeOMapkWbBpYAfJ8WA2BUpqYRN58yZPQ2Cj5o96Jt8rOG BtXPUnSaEPFOVaz6UOrbYfNwY7Tv/lSVWHI/o8NMA8Ga4iWJ/MUAXT3AD /AP5FFxDPg2WKJs/hIPseBE/uEBVOU9qhKdUcCWwqDFYUfyGIMSWHn1v4 53NTLcUfxmV6lnXtxWUlq0wlGP3n7FOZKKyPA1CKw3U1p0PWWVDY5MjkV Sn5IaeDtGC2vVKzLw16khQ/LFam146xoro/BOX5qLNJf4beU29mMJYjFf mKzws1ktzibwIfzxb3YCZaFwTV5ukpp8LVKuBj47uhAFPbS6TNfSjhjvO w==; X-IronPort-AV: E=McAfee;i="6200,9189,10217"; a="329111053" X-IronPort-AV: E=Sophos;i="5.88,268,1635231600"; d="scan'208";a="329111053" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Jan 2022 16:20:36 -0800 X-IronPort-AV: E=Sophos;i="5.88,268,1635231600"; d="scan'208";a="618508515" Received: from mjmartin-desk2.amr.corp.intel.com (HELO mjmartin-desk2.intel.com) ([10.209.94.200]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Jan 2022 16:20:36 -0800 From: Mat Martineau To: netdev@vger.kernel.org Cc: Paolo Abeni , davem@davemloft.net, kuba@kernel.org, matthieu.baerts@tessares.net, mptcp@lists.linux.dev, Mat Martineau Subject: [PATCH net-next 10/13] mptcp: do not block subflows creation on errors Date: Thu, 6 Jan 2022 16:20:23 -0800 Message-Id: <20220107002026.375427-11-mathew.j.martineau@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220107002026.375427-1-mathew.j.martineau@linux.intel.com> References: <20220107002026.375427-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 If the MPTCP configuration allows for multiple subflows creation, and the first additional subflows never reach the fully established status - e.g. due to packets drop or reset - the in kernel path manager do not move to the next subflow. This patch introduces a new PM helper to cope with MPJ subflow creation failure and delay and hook it where appropriate. Such helper triggers additional subflow creation, as needed and updates the PM subflow counter, if the current one is closing. Additionally start all the needed additional subflows as soon as the MPTCP socket is fully established, so we don't have to cope with slow MPJ handshake blocking the next subflow creation. Signed-off-by: Paolo Abeni Signed-off-by: Mat Martineau --- net/mptcp/pm.c | 23 ++++++++++++-- net/mptcp/pm_netlink.c | 69 +++++++++++++++++++++++++----------------- net/mptcp/protocol.c | 6 ++++ net/mptcp/protocol.h | 4 ++- 4 files changed, 71 insertions(+), 31 deletions(-) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index e9ba9551832c..696b2c4613a7 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -172,9 +172,28 @@ void mptcp_pm_subflow_established(struct mptcp_sock *m= sk) spin_unlock_bh(&pm->lock); } =20 -void mptcp_pm_subflow_closed(struct mptcp_sock *msk, u8 id) +void mptcp_pm_subflow_check_next(struct mptcp_sock *msk, const struct sock= *ssk, + const struct mptcp_subflow_context *subflow) { - pr_debug("msk=3D%p", msk); + struct mptcp_pm_data *pm =3D &msk->pm; + bool update_subflows; + + update_subflows =3D (ssk->sk_state =3D=3D TCP_CLOSE) && + (subflow->request_join || subflow->mp_join); + if (!READ_ONCE(pm->work_pending) && !update_subflows) + return; + + spin_lock_bh(&pm->lock); + if (update_subflows) + pm->subflows--; + + /* Even if this subflow is not really established, tell the PM to try + * to pick the next ones, if possible. + */ + if (mptcp_pm_nl_check_work_pending(msk)) + mptcp_pm_schedule_work(msk, MPTCP_PM_SUBFLOW_ESTABLISHED); + + spin_unlock_bh(&pm->lock); } =20 void mptcp_pm_add_addr_received(struct mptcp_sock *msk, diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index ad3dc9c6c531..5efb63ab1fa3 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -251,14 +251,17 @@ unsigned int mptcp_pm_get_local_addr_max(struct mptcp= _sock *msk) } EXPORT_SYMBOL_GPL(mptcp_pm_get_local_addr_max); =20 -static void check_work_pending(struct mptcp_sock *msk) +bool mptcp_pm_nl_check_work_pending(struct mptcp_sock *msk) { struct pm_nl_pernet *pernet =3D net_generic(sock_net((struct sock *)msk),= pm_nl_pernet_id); =20 if (msk->pm.subflows =3D=3D mptcp_pm_get_subflows_max(msk) || (find_next_and_bit(pernet->id_bitmap, msk->pm.id_avail_bitmap, - MPTCP_PM_MAX_ADDR_ID + 1, 0) =3D=3D MPTCP_PM_MAX_ADDR_ID + 1)) + MPTCP_PM_MAX_ADDR_ID + 1, 0) =3D=3D MPTCP_PM_MAX_ADDR_ID + 1)) { WRITE_ONCE(msk->pm.work_pending, false); + return false; + } + return true; } =20 struct mptcp_pm_add_entry * @@ -427,6 +430,7 @@ static bool lookup_address_in_vec(struct mptcp_addr_inf= o *addrs, unsigned int nr static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool= fullmesh, struct mptcp_addr_info *addrs) { + bool deny_id0 =3D READ_ONCE(msk->pm.remote_deny_join_id0); struct sock *sk =3D (struct sock *)msk, *ssk; struct mptcp_subflow_context *subflow; struct mptcp_addr_info remote =3D { 0 }; @@ -434,22 +438,28 @@ static unsigned int fill_remote_addresses_vec(struct = mptcp_sock *msk, bool fullm int i =3D 0; =20 subflows_max =3D mptcp_pm_get_subflows_max(msk); + remote_address((struct sock_common *)sk, &remote); =20 /* Non-fullmesh endpoint, fill in the single entry * corresponding to the primary MPC subflow remote address */ if (!fullmesh) { - remote_address((struct sock_common *)sk, &remote); + if (deny_id0) + return 0; + msk->pm.subflows++; addrs[i++] =3D remote; } else { mptcp_for_each_subflow(msk, subflow) { ssk =3D mptcp_subflow_tcp_sock(subflow); - remote_address((struct sock_common *)ssk, &remote); - if (!lookup_address_in_vec(addrs, i, &remote) && + remote_address((struct sock_common *)ssk, &addrs[i]); + if (deny_id0 && addresses_equal(&addrs[i], &remote, false)) + continue; + + if (!lookup_address_in_vec(addrs, i, &addrs[i]) && msk->pm.subflows < subflows_max) { msk->pm.subflows++; - addrs[i++] =3D remote; + i++; } } } @@ -503,12 +513,12 @@ static void mptcp_pm_create_subflow_or_signal_addr(st= ruct mptcp_sock *msk) =20 /* do lazy endpoint usage accounting for the MPC subflows */ if (unlikely(!(msk->pm.status & BIT(MPTCP_PM_MPC_ENDPOINT_ACCOUNTED))) &&= msk->first) { - struct mptcp_addr_info local; + struct mptcp_addr_info mpc_addr; int mpc_id; =20 - local_address((struct sock_common *)msk->first, &local); - mpc_id =3D lookup_id_by_addr(pernet, &local); - if (mpc_id < 0) + local_address((struct sock_common *)msk->first, &mpc_addr); + mpc_id =3D lookup_id_by_addr(pernet, &mpc_addr); + if (mpc_id >=3D 0) __clear_bit(mpc_id, msk->pm.id_avail_bitmap); =20 msk->pm.status |=3D BIT(MPTCP_PM_MPC_ENDPOINT_ACCOUNTED); @@ -534,26 +544,28 @@ static void mptcp_pm_create_subflow_or_signal_addr(st= ruct mptcp_sock *msk) } =20 /* check if should create a new subflow */ - if (msk->pm.local_addr_used < local_addr_max && - msk->pm.subflows < subflows_max && - !READ_ONCE(msk->pm.remote_deny_join_id0)) { + while (msk->pm.local_addr_used < local_addr_max && + msk->pm.subflows < subflows_max) { + struct mptcp_addr_info addrs[MPTCP_PM_ADDR_MAX]; + bool fullmesh; + int i, nr; + local =3D select_local_address(pernet, msk); - if (local) { - bool fullmesh =3D !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH); - struct mptcp_addr_info addrs[MPTCP_PM_ADDR_MAX]; - int i, nr; + if (!local) + break; =20 - msk->pm.local_addr_used++; - nr =3D fill_remote_addresses_vec(msk, fullmesh, addrs); - if (nr) - __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); - spin_unlock_bh(&msk->pm.lock); - for (i =3D 0; i < nr; i++) - __mptcp_subflow_connect(sk, &local->addr, &addrs[i]); - spin_lock_bh(&msk->pm.lock); - } + fullmesh =3D !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH); + + msk->pm.local_addr_used++; + nr =3D fill_remote_addresses_vec(msk, fullmesh, addrs); + if (nr) + __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); + spin_unlock_bh(&msk->pm.lock); + for (i =3D 0; i < nr; i++) + __mptcp_subflow_connect(sk, &local->addr, &addrs[i]); + spin_lock_bh(&msk->pm.lock); } - check_work_pending(msk); + mptcp_pm_nl_check_work_pending(msk); } =20 static void mptcp_pm_nl_fully_established(struct mptcp_sock *msk) @@ -760,11 +772,12 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mpt= cp_sock *msk, i, rm_list->ids[i], subflow->local_id, subflow->remote_id); spin_unlock_bh(&msk->pm.lock); mptcp_subflow_shutdown(sk, ssk, how); + + /* the following takes care of updating the subflows counter */ mptcp_close_ssk(sk, ssk, subflow); spin_lock_bh(&msk->pm.lock); =20 removed =3D true; - msk->pm.subflows--; __MPTCP_INC_STATS(sock_net(sk), rm_type); } __set_bit(rm_list->ids[1], msk->pm.id_avail_bitmap); diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 5c956a8dc714..3e8cfaed00b5 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2332,6 +2332,12 @@ void mptcp_close_ssk(struct sock *sk, struct sock *s= sk, { if (sk->sk_state =3D=3D TCP_ESTABLISHED) mptcp_event(MPTCP_EVENT_SUB_CLOSED, mptcp_sk(sk), ssk, GFP_KERNEL); + + /* subflow aborted before reaching the fully_established status + * attempt the creation of the next subflow + */ + mptcp_pm_subflow_check_next(mptcp_sk(sk), ssk, subflow); + __mptcp_close_ssk(sk, ssk, subflow, MPTCP_CF_PUSH); } =20 diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 2a6f0960ba27..a8eb32e29215 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -743,7 +743,9 @@ void mptcp_pm_fully_established(struct mptcp_sock *msk,= const struct sock *ssk, bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk); void mptcp_pm_connection_closed(struct mptcp_sock *msk); void mptcp_pm_subflow_established(struct mptcp_sock *msk); -void mptcp_pm_subflow_closed(struct mptcp_sock *msk, u8 id); +bool mptcp_pm_nl_check_work_pending(struct mptcp_sock *msk); +void mptcp_pm_subflow_check_next(struct mptcp_sock *msk, const struct sock= *ssk, + const struct mptcp_subflow_context *subflow); void mptcp_pm_add_addr_received(struct mptcp_sock *msk, const struct mptcp_addr_info *addr); void mptcp_pm_add_addr_echoed(struct mptcp_sock *msk, --=20 2.34.1