From nobody Mon Feb 9 01:16:58 2026 Delivered-To: wpasupplicant.patchew@gmail.com Received: by 2002:ac4:a898:0:b0:4b1:af33:c52d with SMTP id z24csp282618pid; Thu, 21 Apr 2022 07:20:48 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwKteqAWHiJiAQdBm71TUwDgkW2lgQaJyXrosu1Z7VyXnRlH+M9QpXbTpjb3KBvLOJvUbrB X-Received: by 2002:a05:6808:1788:b0:322:eae3:5d3c with SMTP id bg8-20020a056808178800b00322eae35d3cmr3588755oib.222.1650550848154; Thu, 21 Apr 2022 07:20:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1650550848; cv=none; d=google.com; s=arc-20160816; b=agj2Eih48c33zntLdnF3Kg4WMyv+ZnjFTL66GJVVda7fDHEuufM1MiIgZFl/1fLT/Z PE23bFjaeatG01YPi1jjegLq1MKYrjVYZfTu7dchnbDq8PtUwnHpos+AjiwUWOORmzQ3 hYI+H2qj8hfUyAyvPhTPv1AmzQYtHtX7eRZIUAew8p7wllAY88Mucmgjpy/505+g8yWq V7nCtNei/6d1kUCjHpMVDNgG2HX+DmpJbtbTg4NGS51wrJVW+uHdfHw96xYcY0IBwYx1 izu4K74eogMAu/ytH0a9fuidSt1DHl7ZBRw40sJs3dMZ0kUlELKDvEn01zhOnfAi5meh U3Gw== 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:to:from:dkim-signature; bh=HysrGFLfwusrd53mt5VTm/xDXivI7TUWaCPA66/u1M4=; b=S5p3xKjXtfyOR/0Mv4tHHw9fo5L9h6umcjIaRzgLVmLyEDhFlPR36XH9vn9MZAQRk8 ykdCBnPIrLwvzg/DzVaXRmHLAyKqQTWyBolNJXxeNWIPuty3yaUNiROeMSRZ6bZBVJTo BMQidOKtKCWsaly02SjvgzkbMFQNEXeJFcxll/MzX0leqyPeq5mg+hb9VwLTwGZCFXgO FRcbQQih+PiyIclQMKSimHvTiwDp/woasBFXXX3BSUcrZmpllCamMBwwhRh9c6yoAvUg C27RQ3OI9+xFkbIdtBdTkxQT1BYA7xLrfpqLSBev6p6KCIqPZidPNiHBiyHpdflpwsu5 8PHA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=S0rFywG8; spf=pass (google.com: domain of mptcp+bounces-4839-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 139.178.88.99 as permitted sender) smtp.mailfrom="mptcp+bounces-4839-wpasupplicant.patchew=gmail.com@lists.linux.dev"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id h16-20020a056830165000b006054fabb41fsi2698287otr.99.2022.04.21.07.20.48 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 21 Apr 2022 07:20:48 -0700 (PDT) Received-SPF: pass (google.com: domain of mptcp+bounces-4839-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=S0rFywG8; spf=pass (google.com: domain of mptcp+bounces-4839-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 139.178.88.99 as permitted sender) smtp.mailfrom="mptcp+bounces-4839-wpasupplicant.patchew=gmail.com@lists.linux.dev"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.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 sv.mirrors.kernel.org (Postfix) with ESMTPS id AA6CD280A94 for ; Thu, 21 Apr 2022 14:20:47 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 345157A; Thu, 21 Apr 2022 14:20:44 +0000 (UTC) X-Original-To: mptcp@lists.linux.dev 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 B95C31FBE for ; Thu, 21 Apr 2022 14:20:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1650550841; 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=HysrGFLfwusrd53mt5VTm/xDXivI7TUWaCPA66/u1M4=; b=S0rFywG8+/WyU4vw8uVpplFK540nPlePW5J+RYJDQZs1su01KDbE6+4hO95s8/sZTNMaHE cZfNOt8wXn5BiEaygE9nXairemEkiwORYxQ1ndilK2Dr1HDcTdPvt//rOJoiCfK7xPYAsj SGue8WF8nnSJo6j9qOFfInAbv8ZPz3U= 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-166-F8vCFtOjOAWqihLSbPMMMg-1; Thu, 21 Apr 2022 10:20:40 -0400 X-MC-Unique: F8vCFtOjOAWqihLSbPMMMg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 25BDE18A6581 for ; Thu, 21 Apr 2022 14:20:40 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.32.181.152]) by smtp.corp.redhat.com (Postfix) with ESMTP id CB89414A4F86 for ; Thu, 21 Apr 2022 14:20:39 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH v2 4/5] mptcp: never shrink offered window Date: Thu, 21 Apr 2022 16:20:18 +0200 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 2.85 on 10.11.54.7 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=pabeni@redhat.com 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" As per RFC, the offered MPTCP-level window should never shrink. While we currently track the right edge, we don't enforce the above constraint on the wire. Additionally, concurrent xmit on different subflows can end-up in erroneous right edge update. Address the above explicitly updating the announced window and protecting the update with an additional atomic operation (sic) Signed-off-by: Paolo Abeni --- v1 -> v2: - convert rcv_wnd_sent to atomic64: cmpxchg64 is not supported by every arch, while atomic64_t has no such issue RFC -> v1: - rebased on previous patch --- net/mptcp/options.c | 52 ++++++++++++++++++++++++++++++++++++++------ net/mptcp/protocol.c | 8 +++---- net/mptcp/protocol.h | 2 +- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/net/mptcp/options.c b/net/mptcp/options.c index 2570911735ab..df58130da4dc 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -1224,20 +1224,58 @@ bool mptcp_incoming_options(struct sock *sk, struct= sk_buff *skb) return true; } =20 -static void mptcp_set_rwin(const struct tcp_sock *tp) +static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th) { const struct sock *ssk =3D (const struct sock *)tp; - const struct mptcp_subflow_context *subflow; + struct mptcp_subflow_context *subflow; + u64 ack_seq, rcv_wnd_old, rcv_wnd_new; struct mptcp_sock *msk; - u64 ack_seq; + u32 new_win; + u64 win; =20 subflow =3D mptcp_subflow_ctx(ssk); msk =3D mptcp_sk(subflow->conn); =20 - ack_seq =3D READ_ONCE(msk->ack_seq) + tp->rcv_wnd; + ack_seq =3D READ_ONCE(msk->ack_seq); + rcv_wnd_new =3D ack_seq + tp->rcv_wnd; + + rcv_wnd_old =3D atomic64_read(&msk->rcv_wnd_sent); + if (after64(rcv_wnd_new, rcv_wnd_old)) { + u64 rcv_wnd; + + for (;;) { + rcv_wnd =3D atomic64_cmpxchg(&msk->rcv_wnd_sent, rcv_wnd_old, rcv_wnd_n= ew); + + if (rcv_wnd =3D=3D rcv_wnd_old) + break; + if (before64(rcv_wnd_new, rcv_wnd)) + goto raise_win; + rcv_wnd_old =3D rcv_wnd; + }; + return; + } + + if (rcv_wnd_new !=3D rcv_wnd_old) { +raise_win: + win =3D rcv_wnd_old - ack_seq; + tp->rcv_wnd =3D min_t(u64, win, U32_MAX); + new_win =3D tp->rcv_wnd; =20 - if (after64(ack_seq, READ_ONCE(msk->rcv_wnd_sent))) - WRITE_ONCE(msk->rcv_wnd_sent, ack_seq); + /* Make sure we do not exceed the maximum possible + * scaled window. + */ + if (unlikely(th->syn)) + new_win =3D min(new_win, 65535U) << tp->rx_opt.rcv_wscale; + if (!tp->rx_opt.rcv_wscale && + sock_net(ssk)->ipv4.sysctl_tcp_workaround_signed_windows) + new_win =3D min(new_win, MAX_TCP_WINDOW); + else + new_win =3D min(new_win, (65535U << tp->rx_opt.rcv_wscale)); + + /* RFC1323 scaling applied */ + new_win >>=3D tp->rx_opt.rcv_wscale; + th->window =3D htons(new_win); + } } =20 u16 __mptcp_make_csum(u64 data_seq, u32 subflow_seq, u16 data_len, __wsum = sum) @@ -1554,7 +1592,7 @@ void mptcp_write_options(struct tcphdr *th, __be32 *p= tr, struct tcp_sock *tp, } =20 if (tp) - mptcp_set_rwin(tp); + mptcp_set_rwin(tp, th); } =20 __be32 mptcp_get_reset_option(const struct sk_buff *skb) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 098f8f7d6366..653757ea0aca 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -216,7 +216,7 @@ static void mptcp_data_queue_ofo(struct mptcp_sock *msk= , struct sk_buff *skb) =20 seq =3D MPTCP_SKB_CB(skb)->map_seq; end_seq =3D MPTCP_SKB_CB(skb)->end_seq; - max_seq =3D READ_ONCE(msk->rcv_wnd_sent); + max_seq =3D atomic64_read(&msk->rcv_wnd_sent); =20 pr_debug("msk=3D%p seq=3D%llx limit=3D%llx empty=3D%d", msk, seq, max_seq, RB_EMPTY_ROOT(&msk->out_of_order_queue)); @@ -225,7 +225,7 @@ static void mptcp_data_queue_ofo(struct mptcp_sock *msk= , struct sk_buff *skb) mptcp_drop(sk, skb); pr_debug("oow by %lld, rcv_wnd_sent %llu\n", (unsigned long long)end_seq - (unsigned long)max_seq, - (unsigned long long)msk->rcv_wnd_sent); + (unsigned long long)atomic64_read(&msk->rcv_wnd_sent)); MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_NODSSWINDOW); return; } @@ -3008,7 +3008,7 @@ struct sock *mptcp_sk_clone(const struct sock *sk, mptcp_crypto_key_sha(msk->remote_key, NULL, &ack_seq); ack_seq++; WRITE_ONCE(msk->ack_seq, ack_seq); - WRITE_ONCE(msk->rcv_wnd_sent, ack_seq); + atomic64_set(&msk->rcv_wnd_sent, ack_seq); } =20 #if !IS_ENABLED(CONFIG_KASAN) @@ -3303,9 +3303,9 @@ void mptcp_finish_connect(struct sock *ssk) WRITE_ONCE(msk->write_seq, subflow->idsn + 1); WRITE_ONCE(msk->snd_nxt, msk->write_seq); WRITE_ONCE(msk->ack_seq, ack_seq); - WRITE_ONCE(msk->rcv_wnd_sent, ack_seq); WRITE_ONCE(msk->can_ack, 1); WRITE_ONCE(msk->snd_una, msk->write_seq); + atomic64_set(&msk->rcv_wnd_sent, ack_seq); =20 mptcp_pm_new_connection(msk, ssk, 0); =20 diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index f542aeaa5b09..4672901d0dfe 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -257,7 +257,7 @@ struct mptcp_sock { u64 write_seq; u64 snd_nxt; u64 ack_seq; - u64 rcv_wnd_sent; + atomic64_t rcv_wnd_sent; u64 rcv_data_fin_seq; int rmem_fwd_alloc; struct sock *last_snd; --=20 2.35.1