From nobody Sat Jul 18 09:24:23 2026 X-Original-To: dev-commits-src-all@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 4h2Lvc69Nlz6l8XS for ; Sat, 18 Jul 2026 09:24:28 +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 "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4h2Lvc48JQz3PRw for ; Sat, 18 Jul 2026 09:24:28 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1784366668; 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=MyJMXglxbQcGH7CC8zPob0OmoE7RrBCAYCnF064+cws=; b=qnG0i1IdlVPqrhUxVG9ix2ot25mTU/mQHkeTLGi7dfRdGXKkNQXAUo9to6f/aYTx6S0Zv2 nMlUeR3kXlYgEIwPzvpZfmCd3m9D/XRtd+tCFTJRuNy9tSNMx18gsccKzL+xTPDf8cD4DN gjWvVKBM/rD+27RxowCWRfNc9al67f/y1KsIilpjOXebsOUUP2OtEQyjaqmOeH6RUxyBiR OTUkITIxknoBoMVVIbAgTIY2BOAZSLVvuwwlVFgNpX7u+UsspiwU8F6bNjeW6KLxfhfW3R OfYVdgxds/YsJbHfmakSPd16/9OYo42o8kpPwhNVRuPNIn2P6fDyVtGAPzkrvQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1784366668; a=rsa-sha256; cv=none; b=DLaz/BZRt3EtWeaagLgxG7in9woBuIGiZZEEkivcj8PnsW8jCcW4pWsOMC627jzBwqWt6A HXWRg478qZpcqJgH6UBF4RX5lMUKyVlj6B4Uv/pzjemew35hVYYz4bxlZO0sPoeaFZbZYZ OePK73GSFMsIlIlkRNsHQTqdNfINVXSg6d/qRkjfwqivFv4T8OhzEBo+a3CPgC6bf88Ntl kMWjyeV568TvRGTe1RPex3ygI7uqwINbcRxHDmgydGOjFvTpQqpZe+//UHgxqRc8Apl65+ IaVwroBA6Xzn+eyh/UDAwZhhrt8gRLlh1ApReCa3Ml0Kp3l+HspQx0UigZjHuQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1784366668; 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=MyJMXglxbQcGH7CC8zPob0OmoE7RrBCAYCnF064+cws=; b=Zuig2V+4cpbAI6AyT6pER0pjSCe2t26WxoY4e468a/46XNDMx7AHu7iy/Js8HWMZHvW2AR 4V+z0Gtfoes0bPwV2H4s84SH3AO7SDpDPK4qfsEQ60AAreuUJjGRPkAN8HyVBJ2eJ8G0Xh 85+e2lDr5N91bKtqwy6sDrasST9o/PFVL51LPYXe5WHwMHUVlFIKPKjdh9F1FuhQ5Hrt64 BtRS6Qh2RdR48Z2qbsSsoZW4ksVLaoH+jcVW4/88iqDB+z4wjwoH/ZXjLDBpyqH2xOVAqR JB2A/tgyiIkC3CZ8WBOwee7+opEYw9g+C4T51eD9EIhUvkswsJUMyEqSBLM6Bw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4h2Lvc3837zBQj for ; Sat, 18 Jul 2026 09:24:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1e260 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 18 Jul 2026 09:24:23 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Richard Scheffenegger Subject: git: 506e3e30a43c - main - tcp: Align PRR implementation with RFC 9937 List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list 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: 506e3e30a43cc04a21aa65a423bbd1cc4e0543f8 Auto-Submitted: auto-generated Date: Sat, 18 Jul 2026 09:24:23 +0000 Message-Id: <6a5b4647.1e260.62c07abb@gitrepo.freebsd.org> The branch main has been updated by rscheff: URL: https://cgit.FreeBSD.org/src/commit/?id=506e3e30a43cc04a21aa65a423bbd1cc4e0543f8 commit 506e3e30a43cc04a21aa65a423bbd1cc4e0543f8 Author: Richard Scheffenegger AuthorDate: 2026-07-18 08:51:51 +0000 Commit: Richard Scheffenegger CommitDate: 2026-07-18 09:24:05 +0000 tcp: Align PRR implementation with RFC 9937 - Early return when no new data is delivered - Switching from PRR-CRB to PRR-SSRB only when both SND.UNA advances and no further loss is indicated. - Accounting for sequence ranges SACKed before entering recovery in RecoverFS calculation. - Force a fast retransmit upon entering recovery when prr_out is 0 AND SndCnt is 0. - Set cwnd to ssthresh post recovery. Obtained from: mohnishhemanthkumar_gmail.com Reviewed by: rscheff, tuexen Differential Revision: https://reviews.freebsd.org/D56535 MFC after: 3 months --- sys/netinet/tcp_input.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 35a9d7633fa7..2a778687faf2 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -496,6 +496,7 @@ cc_post_recovery(struct tcpcb *tp, struct tcphdr *th) tp->sackhint.delivered_data = 0; tp->sackhint.prr_delivered = 0; tp->sackhint.prr_out = 0; + tp->snd_cwnd = tp->snd_ssthresh; } /* @@ -1496,6 +1497,7 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, struct tcpopt to; int tfo_syn; u_int maxseg = 0; + uint32_t prev_sacked_bytes = 0; bool no_data; no_data = (tlen == 0); @@ -2515,6 +2517,7 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, goto dropafterack; } if (tcp_is_sack_recovery(tp, &to)) { + prev_sacked_bytes = tp->sackhint.sacked_bytes; sack_changed = tcp_sack_doack(tp, &to, th->th_ack); if ((sack_changed != SACK_NOCHANGE) && (tp->t_flags & TF_LRD)) { @@ -2666,12 +2669,15 @@ enter_recovery: tp->sackhint.prr_delivered = imin(tp->snd_max - th->th_ack, (tp->snd_limited + 1) * maxseg); + tp->sackhint.recover_fs = imax(1, + (tp->snd_nxt - tp->snd_una) - prev_sacked_bytes + + tp->sackhint.delivered_data); } else { tp->sackhint.prr_delivered = maxseg; + tp->sackhint.recover_fs = max(1, + tp->snd_nxt - tp->snd_una); } - tp->sackhint.recover_fs = max(1, - tp->snd_nxt - tp->snd_una); } tp->snd_limited = 0; if (tcp_is_sack_recovery(tp, &to)) { @@ -3994,8 +4000,9 @@ void tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to, sackstatus_t sack_changed, u_int *maxsegp) { - int snd_cnt = 0, limit = 0, del_data = 0, pipe = 0; + int snd_cnt = 0, del_data = 0, pipe = 0; u_int maxseg; + bool safe_ack; INP_WLOCK_ASSERT(tptoinpcb(tp)); @@ -4021,6 +4028,10 @@ tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to, pipe = imax(0, tp->snd_max - tp->snd_una - imin(INT_MAX / 65536, tp->t_dupacks) * maxseg); } + + if (del_data == 0) + return; + tp->sackhint.prr_delivered += del_data; /* * Proportional Rate Reduction @@ -4033,25 +4044,16 @@ tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to, tp->snd_ssthresh, tp->sackhint.recover_fs) - tp->sackhint.prr_out + maxseg - 1; } else { - /* - * PRR 6937bis heuristic: - * - A partial ack without SACK block beneath snd_recover - * indicates further loss. - * - An SACK scoreboard update adding a new hole indicates - * further loss, so be conservative and send at most one - * segment. - * - Prevent ACK splitting attacks, by being conservative - * when no new data is acked. - */ - if ((sack_changed == SACK_NEWLOSS) || (del_data == 0)) { - limit = tp->sackhint.prr_delivered - - tp->sackhint.prr_out; - } else { - limit = imax(tp->sackhint.prr_delivered - - tp->sackhint.prr_out, del_data) + - maxseg; + safe_ack = SEQ_GT(th->th_ack, tp->snd_una) && (sack_changed != SACK_NEWLOSS); + snd_cnt = imax(tp->sackhint.prr_delivered - tp->sackhint.prr_out, del_data); + if (safe_ack) { + snd_cnt += maxseg; } - snd_cnt = imin((tp->snd_ssthresh - pipe), limit); + snd_cnt = imin(tp->snd_ssthresh - pipe, snd_cnt); + } + + if (tp->sackhint.prr_out == 0 && snd_cnt == 0) { + snd_cnt = maxseg; } snd_cnt = imax(snd_cnt, 0) / maxseg; /*