From nobody Wed Aug 31 12:54:54 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4MHkfR0FLfz4bLDv; Wed, 31 Aug 2022 12:54:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4MHkfQ6svJz3fyd; Wed, 31 Aug 2022 12:54:54 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1661950495; 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; bh=jQP3InoASU0S87FrtrO4A3Lnfg0JXb3yzw/NX7L9ZmY=; b=cqxuxljA3O1FUNA+kHROwT9HuKkBaOkGB1wev3E61MKaVXyLkGJ6ppj6zHr7Y44bAl4Cxp 2I/WauiF4NClMrX7ARhnu4YpM7AH6UsnWhydUQGV3xGF4cM7VM4U0HpDjofoTL7ePtvZhc sUjnnPuL93XAA5Kpe02cOtHnlcknyj8j2F7kWgxg8EnwaCWjJ6uy6X/Nf/aZ2oTn1ty6ry OR5RoftSqhjpakojZ7gq30/srWgbN/q42x8RJUIEDBoR0y6MPcyWfSK9zd9afyCQtJIcBb Lop5TACH14WZ0aOQU5Nk7wlb/LMt6UCcRJvjBe5fOrr77uaA9hPSgjhoX847TA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4MHkfQ5wBSz17Sn; Wed, 31 Aug 2022 12:54:54 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 27VCssGA088655; Wed, 31 Aug 2022 12:54:54 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 27VCssNL088654; Wed, 31 Aug 2022 12:54:54 GMT (envelope-from git) Date: Wed, 31 Aug 2022 12:54:54 GMT Message-Id: <202208311254.27VCssNL088654@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Richard Scheffenegger Subject: git: c21b7b55bea2 - main - tcp: finish SACK loss recovery on sudden lack of SACK blocks List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rscheff X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: c21b7b55bea2cc2bf3b420c70a9018e703ed6f00 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1661950495; 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; bh=jQP3InoASU0S87FrtrO4A3Lnfg0JXb3yzw/NX7L9ZmY=; b=PaWm3pqAmjy50EbWFqp5+E3l4oIBVHyGpY8xgUSMB5dMyb1hHyt4R9fhACDgYlvJQlOHyC RW4aisLCukwvHt7tcqc7owlazp1QPnJgyomR+WYwI92jbCNAqTpbnHdPRB4uduE/tl+58Q Rautb21qCeV9+u7RT/IbXlaoRk9gnSOwwuyO0Qc/OdQ8brjFcyVs2JNPdE3VCUezZIoG61 lTwG5XHrtpFSJygpO0AfkNKh8P5jML0J0U26If0ai+HTDhYa6W8HqGOQE+bLWUSxyAqVJ7 Y6PhNYqH+YjDOElPaLhTv6rCwuNOYyfhR7Dm2dhDBa2fGE7uMtFMxASewPeegg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1661950495; a=rsa-sha256; cv=none; b=pui+fECFcCGr33IWusL8qDqIKWAmLKimmVUTexC0oJJGnBIFoh3/90SO4iGHFrHyh2HvTP mNtgEvytayl0KymfDHNv/d7nXa7jGSWyrl6odTgYyp6S5CG8f4YxfWO7+s9g7iXB32yQqp vvTw0+PsRcpHoOFhQ75iOgj/J0SoHu8LG+i9Qgxap9F/N+Sv5tQcDfuy+HG0N5f8e+CXl7 O1rA/xbZVK2WqxvU9KEqzthsAk6pRlWcBTjiiMWCYL0gj6JcbxPcccpHaxgY/YhqkcffJw SIrQcIj/zkqyZ0dQg7b386+JzhEBrcNdINMnVdNnL5RsPTBNb7l5/Ydb0xMZQA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by rscheff: URL: https://cgit.FreeBSD.org/src/commit/?id=c21b7b55bea2cc2bf3b420c70a9018e703ed6f00 commit c21b7b55bea2cc2bf3b420c70a9018e703ed6f00 Author: Richard Scheffenegger AuthorDate: 2022-08-31 12:49:25 +0000 Commit: Richard Scheffenegger CommitDate: 2022-08-31 12:49:47 +0000 tcp: finish SACK loss recovery on sudden lack of SACK blocks While a receiver should continue sending SACK blocks for the duration of a SACK loss recovery, if for some reason the TCP options no longer contain these SACK blocks, but we already started maintaining the Scoreboard, keep on handling incoming ACKs (without SACK) as belonging to the SACK recovery. Reported by: thj Reviewed by: tuexen, #transport MFC after: 2 weeks Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D36046 --- sys/netinet/tcp_input.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index bf963840cd23..e8f2676f2aa8 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -268,6 +268,20 @@ kmod_tcpstat_add(int statnum, int val) counter_u64_add(VNET(tcpstat)[statnum], val); } +/* + * Make sure that we only start a SACK loss recovery when + * receiving a duplicate ACK with a SACK block, and also + * complete SACK loss recovery in case the other end + * reneges. + */ +static bool inline +tcp_is_sack_recovery(struct tcpcb *tp, struct tcpopt *to) +{ + return ((tp->t_flags & TF_SACK_PERMIT) && + ((to->to_flags & TOF_SACK) || + (!TAILQ_EMPTY(&tp->snd_holes)))); +} + #ifdef TCP_HHOOK /* * Wrapper for the TCP established input helper hook. @@ -2491,9 +2505,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, TCPSTAT_INC(tcps_rcvacktoomuch); goto dropafterack; } - if ((tp->t_flags & TF_SACK_PERMIT) && - ((to.to_flags & TOF_SACK) || - !TAILQ_EMPTY(&tp->snd_holes))) { + if (tcp_is_sack_recovery(tp, &to)) { if (((sack_changed = tcp_sack_doack(tp, &to, th->th_ack)) != 0) && (tp->t_flags & TF_LRD)) { tcp_sack_lost_retransmission(tp, th); @@ -2566,8 +2578,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * duplicating packets or a possible DoS attack. */ if (th->th_ack != tp->snd_una || - ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK) && + (tcp_is_sack_recovery(tp, &to) && !sack_changed)) break; else if (!tcp_timer_active(tp, TT_REXMT)) @@ -2579,8 +2590,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, if (V_tcp_do_prr && IN_FASTRECOVERY(tp->t_flags)) { tcp_do_prr_ack(tp, th, &to); - } else if ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK) && + } else if (tcp_is_sack_recovery(tp, &to) && IN_FASTRECOVERY(tp->t_flags)) { int awnd; @@ -2653,8 +2663,7 @@ enter_recovery: * snd_ssthresh is already updated by * cc_cong_signal. */ - if ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK)) { + if (tcp_is_sack_recovery(tp, &to)) { tp->sackhint.prr_delivered = tp->sackhint.sacked_bytes; } else { @@ -2666,8 +2675,7 @@ enter_recovery: tp->sackhint.recover_fs = max(1, tp->snd_nxt - tp->snd_una); } - if ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK)) { + if (tcp_is_sack_recovery(tp, &to)) { TCPSTAT_INC( tcps_sack_recovery_episode); tp->snd_recover = tp->snd_nxt; @@ -2759,8 +2767,7 @@ enter_recovery: * from the left side. Such partial ACKs should not be * counted as dupacks here. */ - if ((tp->t_flags & TF_SACK_PERMIT) && - (to.to_flags & TOF_SACK) && + if (tcp_is_sack_recovery(tp, &to) && sack_changed) { tp->t_dupacks++; /* limit overhead by setting maxseg last */ @@ -3942,8 +3949,7 @@ tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to) * (del_data) and an estimate of how many bytes are in the * network. */ - if (((tp->t_flags & TF_SACK_PERMIT) && - (to->to_flags & TOF_SACK)) || + if (tcp_is_sack_recovery(tp, to) || (IN_CONGRECOVERY(tp->t_flags) && !IN_FASTRECOVERY(tp->t_flags))) { del_data = tp->sackhint.delivered_data; @@ -3987,8 +3993,7 @@ tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to) * accordingly. */ if (IN_FASTRECOVERY(tp->t_flags)) { - if ((tp->t_flags & TF_SACK_PERMIT) && - (to->to_flags & TOF_SACK)) { + if (tcp_is_sack_recovery(tp, to)) { tp->snd_cwnd = tp->snd_nxt - tp->snd_recover + tp->sackhint.sack_bytes_rexmit + (snd_cnt * maxseg);