git: 144259f67303 - main - tcp: purge the input queue from tcp_discardcb()

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Tue, 25 Apr 2023 19:21:51 UTC
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=144259f673038635709022506d3adc819da137b6

commit 144259f673038635709022506d3adc819da137b6
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2023-04-25 19:18:19 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2023-04-25 19:18:19 +0000

    tcp: purge the input queue from tcp_discardcb()
    
    The purge was intentionally removed in a540cdca3183.  My assumption
    was that the stacks that use the input queue always call the
    tcp_handle_orphaned_packets() in their tfb_tcp_fb_fini method.
    However, rack will skip doing that if t_fb_ptr is NULL and there are
    scenarios when it is NULL, e.g. close(2) on a socket (but some
    special close(2)).  Instead of working out all possible scenarios
    let's put this safebelt back.
    
    Reviewed by:            rrs
    Differential Revision:  https://reviews.freebsd.org/D39696
---
 sys/netinet/tcp_subr.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index d7ca44e8a581..c57eedef151f 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -2379,6 +2379,7 @@ tcp_discardcb(struct tcpcb *tp)
 {
 	struct inpcb *inp = tptoinpcb(tp);
 	struct socket *so = tptosocket(tp);
+	struct mbuf *m;
 #ifdef INET6
 	bool isipv6 = (inp->inp_vflag & INP_IPV6) != 0;
 #endif
@@ -2422,7 +2423,13 @@ tcp_discardcb(struct tcpcb *tp)
 #endif
 
 	CC_ALGO(tp) = NULL;
+	if ((m = STAILQ_FIRST(&tp->t_inqueue)) != NULL) {
+		struct mbuf *prev;
 
+		STAILQ_INIT(&tp->t_inqueue);
+		STAILQ_FOREACH_FROM_SAFE(m, &tp->t_inqueue, m_stailqpkt, prev)
+			m_freem(m);
+	}
 	TCPSTATES_DEC(tp->t_state);
 
 	if (tp->t_fb->tfb_tcp_fb_fini)
@@ -2430,7 +2437,6 @@ tcp_discardcb(struct tcpcb *tp)
 #ifdef TCP_BLACKBOX
 	tcp_log_tcpcbfini(tp);
 #endif
-	MPASS(STAILQ_EMPTY(&tp->t_inqueue));
 
 	/*
 	 * If we got enough samples through the srtt filter,