--- share/man/man4/tcp.4.orig
+++ share/man/man4/tcp.4
@@ -445,6 +445,20 @@
 Reseeding should not be necessary, and will break
 .Dv TIME_WAIT
 recycling for a few minutes.
+.It Va reass.cursegments
+The current total number of segments present in all reassembly queues.
+.It Va reass.maxsegments
+The maximum limit on the total number of segments across all reassembly
+queues.
+The limit can be adjusted as a tunable.
+.It Va reass.maxqueuelen
+The maximum number of segments allowed in each reassembly queue.
+By default, the system chooses a limit based on each TCP connection's
+receive buffer size and maximum segment size (MSS).
+The actual limit applied to a session's reassembly queue will be the lower of
+the system-calculated automatic limit and the user-specified
+.Va reass.maxqueuelen
+limit.
 .It Va rexmit_min , rexmit_slop
 Adjust the retransmit timer calculation for
 .Tn TCP .
--- sys/netinet/tcp_reass.c.orig
+++ sys/netinet/tcp_reass.c
@@ -89,6 +89,11 @@
     &tcp_reass_zone,
     "Global number of TCP Segments currently in Reassembly Queue");
 
+static u_int tcp_reass_maxqueuelen = 100;
+SYSCTL_UINT(_net_inet_tcp_reass, OID_AUTO, maxqueuelen, CTLFLAG_RWTUN,
+    &tcp_reass_maxqueuelen, 0,
+    "Maximum number of TCP Segments per Reassembly Queue");
+
 /* Initialize TCP reassembly queue */
 static void
 tcp_reass_zone_change(void *tag)
@@ -168,6 +173,10 @@
 	 * socket receive buffer determines our advertised window and grows
 	 * automatically when socket buffer autotuning is enabled. Use it as the
 	 * basis for our queue limit.
+	 *
+	 * However, allow the user to specify a ceiling for the number of
+	 * segments in each queue.
+	 *
 	 * Always let the missing segment through which caused this queue.
 	 * NB: Access to the socket buffer is left intentionally unlocked as we
 	 * can tolerate stale information here.
@@ -178,7 +187,8 @@
 	 * is understood.
 	 */
 	if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) &&
-	    tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) {
+	    tp->t_segqlen >= min((so->so_rcv.sb_hiwat / tp->t_maxseg) + 1,
+	    tcp_reass_maxqueuelen)) {
 		TCPSTAT_INC(tcps_rcvreassfull);
 		*tlenp = 0;
 		if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) {
