Commit c93674ba authored by Matthieu Baerts (NGI0)'s avatar Matthieu Baerts (NGI0) Committed by Wentao Guan
Browse files

mptcp: reset when MPTCP opts are dropped after join

stable inclusion
from stable-v6.6.81
commit 3d7e7ef8fa1aa8094ca9972cc2eff6b3c68e203a
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBYZED

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=3d7e7ef8fa1aa8094ca9972cc2eff6b3c68e203a



--------------------------------

commit 8668860b0ad32a13fcd6c94a0995b7aa7638c9ef upstream.

Before this patch, if the checksum was not used, the subflow was only
reset if map_data_len was != 0. If there were no MPTCP options or an
invalid mapping, map_data_len was not set to the data len, and then the
subflow was not reset as it should have been, leaving the MPTCP
connection in a wrong fallback mode.

This map_data_len condition has been introduced to handle the reception
of the infinite mapping. Instead, a new dedicated mapping error could
have been returned and treated as a special case. However, the commit
31bf11de ("mptcp: introduce MAPPING_BAD_CSUM") has been introduced
by Paolo Abeni soon after, and backported later on to stable. It better
handle the csum case, and it means the exception for valid_csum_seen in
subflow_can_fallback(), plus this one for the infinite mapping in
subflow_check_data_avail(), are no longer needed.

In other words, the code can be simplified there: a fallback should only
be done if msk->allow_infinite_fallback is set. This boolean is set to
false once MPTCP-specific operations acting on the whole MPTCP
connection vs the initial path have been done, e.g. a second path has
been created, or an MPTCP re-injection -- yes, possible even with a
single subflow. The subflow_can_fallback() helper can then be dropped,
and replaced by this single condition.

This also makes the code clearer: a fallback should only be done if it
is possible to do so.

While at it, no need to set map_data_len to 0 in get_mapping_status()
for the infinite mapping case: it will be set to skb->len just after, at
the end of subflow_check_data_avail(), and not read in between.

Fixes: f8d4bcac ("mptcp: infinite mapping receiving")
Cc: stable@vger.kernel.org
Reported-by: default avatarChester A. Unal <chester.a.unal@xpedite-tech.com>
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/544


Acked-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarMatthieu Baerts (NGI0) <matttbe@kernel.org>
Tested-by: default avatarChester A. Unal <chester.a.unal@xpedite-tech.com>
Link: https://patch.msgid.link/20250224-net-mptcp-misc-fixes-v1-2-f550f636b435@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 3d7e7ef8fa1aa8094ca9972cc2eff6b3c68e203a)
Signed-off-by: default avatarWentao Guan <guanwentao@uniontech.com>
parent b096e983
Loading
Loading
Loading
Loading
+1 −14
Original line number Diff line number Diff line
@@ -1106,7 +1106,6 @@ static enum mapping_status get_mapping_status(struct sock *ssk,
	if (data_len == 0) {
		pr_debug("infinite mapping received\n");
		MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPRX);
		subflow->map_data_len = 0;
		return MAPPING_INVALID;
	}

@@ -1248,18 +1247,6 @@ static void subflow_sched_work_if_closed(struct mptcp_sock *msk, struct sock *ss
		mptcp_schedule_work(sk);
}

static bool subflow_can_fallback(struct mptcp_subflow_context *subflow)
{
	struct mptcp_sock *msk = mptcp_sk(subflow->conn);

	if (subflow->mp_join)
		return false;
	else if (READ_ONCE(msk->csum_enabled))
		return !subflow->valid_csum_seen;
	else
		return READ_ONCE(msk->allow_infinite_fallback);
}

static void mptcp_subflow_fail(struct mptcp_sock *msk, struct sock *ssk)
{
	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
@@ -1355,7 +1342,7 @@ static bool subflow_check_data_avail(struct sock *ssk)
			return true;
		}

		if (!subflow_can_fallback(subflow) && subflow->map_data_len) {
		if (!READ_ONCE(msk->allow_infinite_fallback)) {
			/* fatal protocol error, close the socket.
			 * subflow_error_report() will introduce the appropriate barriers
			 */