git: 7a842346c3cd - main - tcp: Rack can crash with the new non-TSO fix..

From: Randall Stewart <rrs_at_FreeBSD.org>
Date: Wed, 19 Apr 2023 17:16:53 UTC
The branch main has been updated by rrs:

URL: https://cgit.FreeBSD.org/src/commit/?id=7a842346c3cd04dc07235c6af5ce0bec0db90be2

commit 7a842346c3cd04dc07235c6af5ce0bec0db90be2
Author:     Randall Stewart <rrs@FreeBSD.org>
AuthorDate: 2023-04-19 17:17:04 +0000
Commit:     Randall Stewart <rrs@FreeBSD.org>
CommitDate: 2023-04-19 17:17:04 +0000

    tcp: Rack can crash with the new non-TSO fix..
    
    Turns out the location of the check to see if we can do output is in the wrong place. We need
    to jump off to the compressed acks before handling that case since th is NULL in the
    compressed ack case which is handled differently anyway.
    
    Reviewed by: tuexen
    Sponsored by: Netflix Inc
    Differential Revision:https://reviews.freebsd.org/D39690
---
 sys/netinet/tcp_stacks/rack.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
index 40706d5ebfca..a6d5362fafb4 100644
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -16497,6 +16497,15 @@ rack_do_segment_nounlock(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
 	 * anything becase a pacing timer is running.
 	 */
 	us_cts = tcp_tv_to_usectick(tv);
+	if (m->m_flags & M_ACKCMP) {
+		/*
+		 * All compressed ack's are ack's by definition so
+		 * remove any ack required flag and then do the processing.
+		 */
+		rack->rc_ack_required = 0;
+		return (rack_do_compressed_ack_processing(tp, so, m, nxt_pkt, tv));
+	}
+	thflags = tcp_get_flags(th);
 	if ((rack->rc_always_pace == 1) &&
 	    (rack->rc_ack_can_sendout_data == 0) &&
 	    (rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) &&
@@ -16539,15 +16548,6 @@ rack_do_segment_nounlock(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
 			no_output = 0;
 		}
 	}
-	if (m->m_flags & M_ACKCMP) {
-		/*
-		 * All compressed ack's are ack's by definition so
-		 * remove any ack required flag and then do the processing.
-		 */
-		rack->rc_ack_required = 0;
-		return (rack_do_compressed_ack_processing(tp, so, m, nxt_pkt, tv));
-	}
-	thflags = tcp_get_flags(th);
 	/*
 	 * If there is a RST or FIN lets dump out the bw
 	 * with a FIN the connection may go on but we