git: 6e76489098c6 - main - tcp: remove support for TCPPCAP

From: Michael Tuexen <tuexen_at_FreeBSD.org>
Date: Mon, 31 Mar 2025 17:07:49 UTC
The branch main has been updated by tuexen:

URL: https://cgit.FreeBSD.org/src/commit/?id=6e76489098c6dc415ac3f2ae084154c3c22558ec

commit 6e76489098c6dc415ac3f2ae084154c3c22558ec
Author:     Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2025-03-31 14:55:39 +0000
Commit:     Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2025-03-31 14:55:39 +0000

    tcp: remove support for TCPPCAP
    
    This feature could be used to store the last sent and received TCP
    packets for a TCP endpoint. There was no utility to get these packets
    from a live system or core.
    This functionality is now provided by TCP Black Box Logging, which also
    stores additional events. There are tools to get these traces from a
    live system or a core.
    Therefore remove TCPPCAP to avoid maintaining it, when it is not
    used anymore.
    
    Reviewed by:            rrs, rscheff, Peter Lei, glebiu
    Sponsored by:           Netflix, Inc.
    Differential Revision:  https://reviews.freebsd.org/D49589
---
 ObsoleteFiles.inc                      |   3 +
 sys/conf/NOTES                         |   4 -
 sys/conf/files                         |   2 -
 sys/conf/options                       |   1 -
 sys/netinet/tcp.h                      |   4 +-
 sys/netinet/tcp_input.c                |   7 -
 sys/netinet/tcp_output.c               |  12 -
 sys/netinet/tcp_pcap.c                 | 452 ---------------------------------
 sys/netinet/tcp_pcap.h                 |  39 ---
 sys/netinet/tcp_subr.c                 |  24 --
 sys/netinet/tcp_usrreq.c               |  33 ---
 sys/netinet/tcp_var.h                  |   4 -
 tools/build/test-includes/badfiles.inc |   1 -
 usr.sbin/tcpsso/tcpsso.c               |   2 -
 14 files changed, 5 insertions(+), 583 deletions(-)

diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 850133db608a..14f54d75bc1d 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -51,6 +51,9 @@
 #   xargs -n1 | sort | uniq -d;
 # done
 
+# 20250331: removal of TCPPCAP
+OLD_FILES+=usr/include/netinet/tcp_pcap.h
+
 # 20250310: caroot bundle updated
 OLD_FILES+=usr/share/certs/trusted/Entrust_Root_Certification_Authority_-_G4.pem
 OLD_FILES+=usr/share/certs/trusted/SecureSign_RootCA11.pem
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index fc32acd681b3..081cb985c7fe 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1025,9 +1025,6 @@ device		dummymbuf
 #
 # PF_DEFAULT_TO_DROP causes the default pf(4) rule to deny everything.
 #
-# TCPPCAP enables code which keeps the last n packets sent and received
-# on a TCP socket.
-#
 # TCP_BLACKBOX enables enhanced TCP event logging.
 #
 # TCP_HHOOK enables the hhook(9) framework hooks for the TCP stack.
@@ -1050,7 +1047,6 @@ options 	IPFILTER_LOOKUP		#ipfilter pools
 options 	IPFILTER_DEFAULT_BLOCK	#block all packets by default
 options 	IPSTEALTH		#support for stealth forwarding
 options 	PF_DEFAULT_TO_DROP	#drop everything by default
-options 	TCPPCAP
 options 	TCP_BLACKBOX
 options 	TCP_HHOOK
 options		SOCKET_HHOOK
diff --git a/sys/conf/files b/sys/conf/files
index 3be4c1d8e3dd..2f4b7126a9cd 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -4389,8 +4389,6 @@ netinet/tcp_output.c		optional inet | inet6
 netinet/tcp_offload.c		optional tcp_offload inet | tcp_offload inet6
 netinet/tcp_hpts.c		optional tcphpts inet | tcphpts inet6
 netinet/tcp_ratelimit.c		optional ratelimit inet | ratelimit inet6
-netinet/tcp_pcap.c		optional inet tcppcap | inet6 tcppcap \
-	compile-with "${NORMAL_C} ${NO_WNONNULL}"
 netinet/tcp_reass.c		optional inet | inet6
 netinet/tcp_sack.c		optional inet | inet6
 netinet/tcp_stacks/bbr.c	optional inet tcphpts tcp_bbr | inet6 tcphpts tcp_bbr \
diff --git a/sys/conf/options b/sys/conf/options
index c467dc9995c2..92f3c310c77b 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -479,7 +479,6 @@ ROUTETABLES		opt_route.h
 FIB_ALGO		opt_route.h
 RSS			opt_rss.h
 SLIP_IFF_OPTS		opt_slip.h
-TCPPCAP		opt_global.h
 SIFTR
 TCP_BLACKBOX		opt_global.h
 TCP_HHOOK		opt_global.h
diff --git a/sys/netinet/tcp.h b/sys/netinet/tcp.h
index 69a8116a2201..94d41ff67836 100644
--- a/sys/netinet/tcp.h
+++ b/sys/netinet/tcp.h
@@ -224,8 +224,8 @@ __tcp_set_flags(struct tcphdr *th, uint16_t flags)
 #define	TCP_KEEPINTVL		512	/* L,N interval between keepalives */
 #define	TCP_KEEPCNT		1024	/* L,N number of keepalives before close */
 #define	TCP_FASTOPEN		1025	/* enable TFO / was created via TFO */
-#define	TCP_PCAP_OUT		2048	/* number of output packets to keep */
-#define	TCP_PCAP_IN		4096	/* number of input packets to keep */
+/* unused			2048	   was TCP_PCAP_OUT */
+/* unused			4096	   was TCP_PCAP_IN */
 #define	TCP_FUNCTION_BLK	8192	/* Set the tcp function pointers to the specified stack */
 #define	TCP_FUNCTION_ALIAS	8193	/* Get the current tcp function pointer name alias */
 /* Options for Rack and BBR */
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 2fc1e0deea16..29a6b431f311 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -112,9 +112,6 @@
 #include <netinet/tcpip.h>
 #include <netinet/cc/cc.h>
 #include <netinet/tcp_fastopen.h>
-#ifdef TCPPCAP
-#include <netinet/tcp_pcap.h>
-#endif
 #include <netinet/tcp_syncache.h>
 #ifdef TCP_OFFLOAD
 #include <netinet/tcp_offload.h>
@@ -1546,10 +1543,6 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
 	KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: TCPS_TIME_WAIT",
 	    __func__));
 
-#ifdef TCPPCAP
-	/* Save segment, if requested. */
-	tcp_pcap_add(th, m, &(tp->t_inpkts));
-#endif
 	TCP_LOG_EVENT(tp, th, &so->so_rcv, &so->so_snd, TCP_LOG_IN, 0,
 	    tlen, NULL, true);
 
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index 135e7d8493e2..bc5b42ee6f2c 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -85,9 +85,6 @@
 #include <netinet/tcpip.h>
 #include <netinet/cc/cc.h>
 #include <netinet/tcp_fastopen.h>
-#ifdef TCPPCAP
-#include <netinet/tcp_pcap.h>
-#endif
 #ifdef TCP_OFFLOAD
 #include <netinet/tcp_offload.h>
 #endif
@@ -1466,10 +1463,6 @@ send:
 
 		TCP_PROBE5(send, NULL, tp, ip6, tp, th);
 
-#ifdef TCPPCAP
-		/* Save packet, if requested. */
-		tcp_pcap_add(th, m, &(tp->t_outpkts));
-#endif
 
 		/* TODO: IPv6 IP6TOS_ECT bit on */
 		error = ip6_output(m, inp->in6p_outputopts, &inp->inp_route6,
@@ -1512,11 +1505,6 @@ send:
 
 	TCP_PROBE5(send, NULL, tp, ip, tp, th);
 
-#ifdef TCPPCAP
-	/* Save packet, if requested. */
-	tcp_pcap_add(th, m, &(tp->t_outpkts));
-#endif
-
 	error = ip_output(m, inp->inp_options, &inp->inp_route,
 	    ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0), 0, inp);
 
diff --git a/sys/netinet/tcp_pcap.c b/sys/netinet/tcp_pcap.c
deleted file mode 100644
index f26287bd7f03..000000000000
--- a/sys/netinet/tcp_pcap.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/*-
- * Copyright (c) 2015
- *	Jonathan Looney. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/queue.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/sysctl.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/eventhandler.h>
-#include <machine/atomic.h>
-#include <netinet/in.h>
-#include <netinet/in_pcb.h>
-#include <netinet/tcp_var.h>
-#include <netinet/tcp_pcap.h>
-
-#define M_LEADINGSPACE_NOWRITE(m)					\
-	((m)->m_data - M_START(m))
-
-int tcp_pcap_aggressive_free = 1;
-static int tcp_pcap_clusters_referenced_cur = 0;
-static int tcp_pcap_clusters_referenced_max = 0;
-
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcp_pcap_aggressive_free,
-	CTLFLAG_RW, &tcp_pcap_aggressive_free, 0,
-	"Free saved packets when the memory system comes under pressure");
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcp_pcap_clusters_referenced_cur,
-	CTLFLAG_RD, &tcp_pcap_clusters_referenced_cur, 0,
-	"Number of clusters currently referenced on TCP PCAP queues");
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcp_pcap_clusters_referenced_max,
-	CTLFLAG_RW, &tcp_pcap_clusters_referenced_max, 0,
-	"Maximum number of clusters allowed to be referenced on TCP PCAP "
-	"queues");
-
-static int tcp_pcap_alloc_reuse_ext = 0;
-static int tcp_pcap_alloc_reuse_mbuf = 0;
-static int tcp_pcap_alloc_new_mbuf = 0;
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcp_pcap_alloc_reuse_ext,
-	CTLFLAG_RD, &tcp_pcap_alloc_reuse_ext, 0,
-	"Number of mbufs with external storage reused for the TCP PCAP "
-	"functionality");
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcp_pcap_alloc_reuse_mbuf,
-	CTLFLAG_RD, &tcp_pcap_alloc_reuse_mbuf, 0,
-	"Number of mbufs with internal storage reused for the TCP PCAP "
-	"functionality");
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcp_pcap_alloc_new_mbuf,
-	CTLFLAG_RD, &tcp_pcap_alloc_new_mbuf, 0,
-	"Number of new mbufs allocated for the TCP PCAP functionality");
-
-VNET_DEFINE(int, tcp_pcap_packets) = 0;
-#define V_tcp_pcap_packets	VNET(tcp_pcap_packets)
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcp_pcap_packets,
-	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_pcap_packets), 0,
-	"Default number of packets saved per direction per TCPCB");
-
-/* Initialize the values. */
-static void
-tcp_pcap_max_set(void)
-{
-
-	tcp_pcap_clusters_referenced_max = nmbclusters / 4;
-}
-
-void
-tcp_pcap_init(void)
-{
-
-	tcp_pcap_max_set();
-	EVENTHANDLER_REGISTER(nmbclusters_change, tcp_pcap_max_set,
-		NULL, EVENTHANDLER_PRI_ANY);
-}
-
-/*
- * If we are below the maximum allowed cluster references,
- * increment the reference count and return TRUE. Otherwise,
- * leave the reference count alone and return FALSE.
- */
-static __inline bool
-tcp_pcap_take_cluster_reference(void)
-{
-	if (atomic_fetchadd_int(&tcp_pcap_clusters_referenced_cur, 1) >=
-		tcp_pcap_clusters_referenced_max) {
-		atomic_add_int(&tcp_pcap_clusters_referenced_cur, -1);
-		return FALSE;
-	}
-	return TRUE;
-}
-
-/*
- * For all the external entries in m, apply the given adjustment.
- * This can be used to adjust the counter when an mbuf chain is
- * copied or freed.
- */
-static __inline void
-tcp_pcap_adj_cluster_reference(struct mbuf *m, int adj)
-{
-	while (m) {
-		if (m->m_flags & M_EXT)
-			atomic_add_int(&tcp_pcap_clusters_referenced_cur, adj);
-
-		m = m->m_next;
-	}
-}
-
-/*
- * Free all mbufs in a chain, decrementing the reference count as
- * necessary.
- *
- * Functions in this file should use this instead of m_freem() when
- * they are freeing mbuf chains that may contain clusters that were
- * already included in tcp_pcap_clusters_referenced_cur.
- */
-static void
-tcp_pcap_m_freem(struct mbuf *mb)
-{
-	while (mb != NULL) {
-		if (mb->m_flags & M_EXT)
-			atomic_subtract_int(&tcp_pcap_clusters_referenced_cur,
-			    1);
-		mb = m_free(mb);
-	}
-}
-
-/*
- * Copy data from m to n, where n cannot fit all the data we might
- * want from m.
- *
- * Prioritize data like this:
- * 1. TCP header
- * 2. IP header
- * 3. Data
- */
-static void
-tcp_pcap_copy_bestfit(struct tcphdr *th, struct mbuf *m, struct mbuf *n)
-{
-	struct mbuf *m_cur = m;
-	int bytes_to_copy=0, trailing_data, skip=0, tcp_off;
-
-	/* Below, we assume these will be non-NULL. */
-	KASSERT(th, ("%s: called with th == NULL", __func__));
-	KASSERT(m, ("%s: called with m == NULL", __func__));
-	KASSERT(n, ("%s: called with n == NULL", __func__));
-
-	/* We assume this initialization occurred elsewhere. */
-	KASSERT(n->m_len == 0, ("%s: called with n->m_len=%d (expected 0)",
-		__func__, n->m_len));
-	KASSERT(n->m_data == M_START(n),
-		("%s: called with n->m_data != M_START(n)", __func__));
-
-	/*
-	 * Calculate the size of the TCP header. We use this often
-	 * enough that it is worth just calculating at the start.
-	 */
-	tcp_off = th->th_off << 2;
-
-	/* Trim off leading empty mbufs. */
-	while (m && m->m_len == 0)
-		m = m->m_next;
-
-	if (m) {
-		m_cur = m;
-	}
-	else {
-		/*
-		 * No data? Highly unusual. We would expect to at
-		 * least see a TCP header in the mbuf.
-		 * As we have a pointer to the TCP header, I guess
-		 * we should just copy that. (???)
-		 */
-fallback:
-		bytes_to_copy = tcp_off;
-		if (bytes_to_copy > M_SIZE(n))
-			bytes_to_copy = M_SIZE(n);
-		bcopy(th, n->m_data, bytes_to_copy);
-		n->m_len = bytes_to_copy;
-		return;
-	}
-
-	/*
-	 * Find TCP header. Record the total number of bytes up to,
-	 * and including, the TCP header.
-	 */
-	while (m_cur) {
-		if ((caddr_t) th >= (caddr_t) m_cur->m_data &&
-			(caddr_t) th < (caddr_t) (m_cur->m_data + m_cur->m_len))
-			break;
-		bytes_to_copy += m_cur->m_len;
-		m_cur = m_cur->m_next;
-	}
-	if (m_cur)
-		bytes_to_copy += (caddr_t) th - (caddr_t) m_cur->m_data;
-	else
-		goto fallback;
-	bytes_to_copy += tcp_off;
-
-	/*
-	 * If we already want to copy more bytes than we can hold
-	 * in the destination mbuf, skip leading bytes and copy
-	 * what we can.
-	 *
-	 * Otherwise, consider trailing data.
-	 */
-	if (bytes_to_copy > M_SIZE(n)) {
-		skip  = bytes_to_copy - M_SIZE(n);
-		bytes_to_copy = M_SIZE(n);
-	}
-	else {
-		/*
-		 * Determine how much trailing data is in the chain.
-		 * We start with the length of this mbuf (the one
-		 * containing th) and subtract the size of the TCP
-		 * header (tcp_off) and the size of the data prior
-		 * to th (th - m_cur->m_data).
-		 *
-		 * This *should not* be negative, as the TCP code
-		 * should put the whole TCP header in a single
-		 * mbuf. But, it isn't a problem if it is. We will
-		 * simple work off our negative balance as we look
-		 * at subsequent mbufs.
-		 */
-		trailing_data = m_cur->m_len - tcp_off;
-		trailing_data -= (caddr_t) th - (caddr_t) m_cur->m_data;
-		m_cur = m_cur->m_next;
-		while (m_cur) {
-			trailing_data += m_cur->m_len;
-			m_cur = m_cur->m_next;
-		}
-		if ((bytes_to_copy + trailing_data) > M_SIZE(n))
-			bytes_to_copy = M_SIZE(n);
-		else
-			bytes_to_copy += trailing_data;
-	}
-
-	m_copydata(m, skip, bytes_to_copy, n->m_data);
-	n->m_len = bytes_to_copy;
-}
-
-void
-tcp_pcap_add(struct tcphdr *th, struct mbuf *m, struct mbufq *queue)
-{
-	struct mbuf *n = NULL, *mhead;
-
-	KASSERT(th, ("%s: called with th == NULL", __func__));
-	KASSERT(m, ("%s: called with m == NULL", __func__));
-	KASSERT(queue, ("%s: called with queue == NULL", __func__));
-
-	/* We only care about data packets. */
-	while (m && m->m_type != MT_DATA)
-		m = m->m_next;
-
-	/* We only need to do something if we still have an mbuf. */
-	if (!m)
-		return;
-
-	/* If we are not saving mbufs, return now. */
-	if (queue->mq_maxlen == 0)
-		return;
-
-	/*
-	 * Check to see if we will need to recycle mbufs.
-	 *
-	 * If we need to get rid of mbufs to stay below
-	 * our packet count, try to reuse the mbuf. Once
-	 * we already have a new mbuf (n), then we can
-	 * simply free subsequent mbufs.
-	 *
-	 * Note that most of the logic in here is to deal
-	 * with the reuse. If we are fine with constant
-	 * mbuf allocs/deallocs, we could ditch this logic.
-	 * But, it only seems to make sense to reuse
-	 * mbufs we already have.
-	 */
-	while (mbufq_full(queue)) {
-		mhead = mbufq_dequeue(queue);
-
-		if (n) {
-			tcp_pcap_m_freem(mhead);
-		}
-		else {
-			/*
-			 * If this held an external cluster, try to
-			 * detach the cluster. But, if we held the
-			 * last reference, go through the normal
-			 * free-ing process.
-			 */
-			if (mhead->m_flags & M_EXTPG) {
-				/* Don't mess around with these. */
-				tcp_pcap_m_freem(mhead);
-				continue;
-			} else if (mhead->m_flags & M_EXT) {
-				switch (mhead->m_ext.ext_type) {
-				case EXT_SFBUF:
-					/* Don't mess around with these. */
-					tcp_pcap_m_freem(mhead);
-					continue;
-				default:
-					if (atomic_fetchadd_int(
-						mhead->m_ext.ext_cnt, -1) == 1)
-					{
-						/*
-						 * We held the last reference
-						 * on this cluster. Restore
-						 * the reference count and put
-						 * it back in the pool.
-				 		 */
-						*(mhead->m_ext.ext_cnt) = 1;
-						tcp_pcap_m_freem(mhead);
-						continue;
-					}
-					/*
-					 * We were able to cleanly free the
-					 * reference.
-				 	 */
-					atomic_subtract_int(
-					    &tcp_pcap_clusters_referenced_cur,
-					    1);
-					tcp_pcap_alloc_reuse_ext++;
-					break;
-				}
-			} else {
-				tcp_pcap_alloc_reuse_mbuf++;
-			}
-
-			n = mhead;
-			tcp_pcap_m_freem(n->m_next);
-			m_init(n, M_NOWAIT, MT_DATA, 0);
-		}
-	}
-
-	/* Check to see if we need to get a new mbuf. */
-	if (!n) {
-		if (!(n = m_get(M_NOWAIT, MT_DATA)))
-			return;
-		tcp_pcap_alloc_new_mbuf++;
-	}
-
-	/*
-	 * What are we dealing with? If a cluster, attach it. Otherwise,
-	 * try to copy the data from the beginning of the mbuf to the
-	 * end of data. (There may be data between the start of the data
-	 * area and the current data pointer. We want to get this, because
-	 * it may contain header information that is useful.)
-	 * In cases where that isn't possible, settle for what we can
-	 * get.
-	 */
-	if ((m->m_flags & (M_EXT | M_EXTPG)) &&
-	    tcp_pcap_take_cluster_reference()) {
-		n->m_data = m->m_data;
-		n->m_len = m->m_len;
-		mb_dupcl(n, m);
-	}
-	else if (((m->m_data + m->m_len) - M_START(m)) <= M_SIZE(n)) {
-		/*
-		 * At this point, n is guaranteed to be a normal mbuf
-		 * with no cluster and no packet header. Because the
-		 * logic in this code block requires this, the assert
-		 * is here to catch any instances where someone
-		 * changes the logic to invalidate that assumption.
-		 */
-		KASSERT((n->m_flags & (M_EXT | M_PKTHDR)) == 0,
-			("%s: Unexpected flags (%#x) for mbuf",
-			__func__, n->m_flags));
-		n->m_data = n->m_dat + M_LEADINGSPACE_NOWRITE(m);
-		n->m_len = m->m_len;
-		if (m->m_flags & M_EXTPG)
-			m_copydata(m, 0, m->m_len, n->m_data);
-		else
-			bcopy(M_START(m), n->m_dat,
-			    m->m_len + M_LEADINGSPACE_NOWRITE(m));
-	}
-	else {
-		/*
-		 * This is the case where we need to "settle for what
-		 * we can get". The most probable way to this code
-		 * path is that we've already taken references to the
-		 * maximum number of mbuf clusters we can, and the data
-		 * is too long to fit in an mbuf's internal storage.
-		 * Try for a "best fit".
-		 */
-		tcp_pcap_copy_bestfit(th, m, n);
-
-		/* Don't try to get additional data. */
-		goto add_to_queue;
-	}
-
-	if (m->m_next) {
-		n->m_next = m_copym(m->m_next, 0, M_COPYALL, M_NOWAIT);
-		tcp_pcap_adj_cluster_reference(n->m_next, 1);
-	}
-
-add_to_queue:
-	/* Add the new mbuf to the list. */
-	if (mbufq_enqueue(queue, n)) {
-		/* This shouldn't happen. If INVARIANTS is defined, panic. */
-		KASSERT(0, ("%s: mbufq was unexpectedly full!", __func__));
-		tcp_pcap_m_freem(n);
-	}
-}
-
-void
-tcp_pcap_drain(struct mbufq *queue)
-{
-	struct mbuf *m;
-	while ((m = mbufq_dequeue(queue)))
-		tcp_pcap_m_freem(m);
-}
-
-void
-tcp_pcap_tcpcb_init(struct tcpcb *tp)
-{
-	mbufq_init(&(tp->t_inpkts), V_tcp_pcap_packets);
-	mbufq_init(&(tp->t_outpkts), V_tcp_pcap_packets);
-}
-
-void
-tcp_pcap_set_sock_max(struct mbufq *queue, int newval)
-{
-	queue->mq_maxlen = newval;
-	while (queue->mq_len > queue->mq_maxlen)
-		tcp_pcap_m_freem(mbufq_dequeue(queue));
-}
-
-int
-tcp_pcap_get_sock_max(struct mbufq *queue)
-{
-	return queue->mq_maxlen;
-}
diff --git a/sys/netinet/tcp_pcap.h b/sys/netinet/tcp_pcap.h
deleted file mode 100644
index 8250c06d4ce0..000000000000
--- a/sys/netinet/tcp_pcap.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * Copyright (c) 2015
- *	Jonathan Looney. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _NETINET_TCP_PCAP_H_
-#define _NETINET_TCP_PCAP_H_
-
-void tcp_pcap_init(void);
-void tcp_pcap_add(struct tcphdr *th, struct mbuf *m, struct mbufq *queue);
-void tcp_pcap_drain(struct mbufq *queue);
-void tcp_pcap_tcpcb_init(struct tcpcb *tp);
-void tcp_pcap_set_sock_max(struct mbufq *queue, int newval);
-int tcp_pcap_get_sock_max(struct mbufq *queue);
-
-extern int tcp_pcap_aggressive_free;
-
-#endif /* _NETINET_TCP_PCAP_H_ */
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index f6317815521d..34964ed8283c 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -109,9 +109,6 @@
 #include <netinet/tcpip.h>
 #include <netinet/tcp_fastopen.h>
 #include <netinet/tcp_accounting.h>
-#ifdef TCPPCAP
-#include <netinet/tcp_pcap.h>
-#endif
 #ifdef TCP_OFFLOAD
 #include <netinet/tcp_offload.h>
 #endif
@@ -1415,13 +1412,6 @@ tcp_drain(void *ctx __unused, int flags __unused)
 				tcp_clean_sackreport(tcpb);
 #ifdef TCP_BLACKBOX
 				tcp_log_drain(tcpb);
-#endif
-#ifdef TCPPCAP
-				if (tcp_pcap_aggressive_free) {
-					/* Free the TCP PCAP queues. */
-					tcp_pcap_drain(&(tcpb->t_inpkts));
-					tcp_pcap_drain(&(tcpb->t_outpkts));
-				}
 #endif
 			}
 		}
@@ -1535,9 +1525,6 @@ tcp_init(void *arg __unused)
 	tcp_bad_csums = counter_u64_alloc(M_WAITOK);
 	tcp_pacing_failures = counter_u64_alloc(M_WAITOK);
 	tcp_dgp_failures = counter_u64_alloc(M_WAITOK);
-#ifdef TCPPCAP
-	tcp_pcap_init();
-#endif
 
 	hashsize = tcp_tcbhashsize;
 	if (hashsize == 0) {
@@ -2337,12 +2324,6 @@ tcp_newtcpcb(struct inpcb *inp, struct tcpcb *listening_tcb)
 	 * which may match an IPv4-mapped IPv6 address.
 	 */
 	inp->inp_ip_ttl = V_ip_defttl;
-#ifdef TCPPCAP
-	/*
-	 * Init the TCP PCAP queues.
-	 */
-	tcp_pcap_tcpcb_init(tp);
-#endif
 #ifdef TCP_BLACKBOX
 	/* Initialize the per-TCPCB log data. */
 	tcp_log_tcpcbinit(tp);
@@ -2419,11 +2400,6 @@ tcp_discardcb(struct tcpcb *tp)
 	if (tp->t_flags & TF_TOE)
 		tcp_offload_detach(tp);
 #endif
-#ifdef TCPPCAP
-	/* Free the TCP PCAP queues. */
-	tcp_pcap_drain(&(tp->t_inpkts));
-	tcp_pcap_drain(&(tp->t_outpkts));
-#endif
 
 	/* Allow the CC algorithm to clean up after itself. */
 	if (CC_ALGO(tp)->cb_destroy != NULL)
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 13e66f758d45..fbc204097b25 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -95,9 +95,6 @@
 #include <netinet/cc/cc.h>
 #include <netinet/tcp_fastopen.h>
 #include <netinet/tcp_hpts.h>
-#ifdef TCPPCAP
-#include <netinet/tcp_pcap.h>
-#endif
 #ifdef TCP_OFFLOAD
 #include <netinet/tcp_offload.h>
 #endif
@@ -2342,26 +2339,6 @@ unlock_and_done:
 				    TP_MAXIDLE(tp));
 			goto unlock_and_done;
 
-#ifdef TCPPCAP
-		case TCP_PCAP_OUT:
-		case TCP_PCAP_IN:
-			INP_WUNLOCK(inp);
-			error = sooptcopyin(sopt, &optval, sizeof optval,
-			    sizeof optval);
-			if (error)
-				return (error);
-
-			INP_WLOCK_RECHECK(inp);
-			if (optval >= 0)
-				tcp_pcap_set_sock_max(
-					(sopt->sopt_name == TCP_PCAP_OUT) ?
-					&(tp->t_outpkts) : &(tp->t_inpkts),
-					optval);
-			else
-				error = EINVAL;
-			goto unlock_and_done;
-#endif
-
 		case TCP_FASTOPEN: {
 			struct tcp_fastopen tfo_optval;
 
@@ -2592,16 +2569,6 @@ unhold:
 			INP_WUNLOCK(inp);
 			error = sooptcopyout(sopt, &ui, sizeof(ui));
 			break;
-#ifdef TCPPCAP
-		case TCP_PCAP_OUT:
-		case TCP_PCAP_IN:
-			optval = tcp_pcap_get_sock_max(
-					(sopt->sopt_name == TCP_PCAP_OUT) ?
-					&(tp->t_outpkts) : &(tp->t_inpkts));
-			INP_WUNLOCK(inp);
-			error = sooptcopyout(sopt, &optval, sizeof optval);
-			break;
-#endif
 		case TCP_FASTOPEN:
 			optval = tp->t_flags & TF_FASTOPEN;
 			INP_WUNLOCK(inp);
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 31663ed48f81..5be024ededc7 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -499,10 +499,6 @@ struct tcpcb {
 	uint64_t tcp_cnt_counters[TCP_NUM_CNT_COUNTERS];
 	uint64_t tcp_proc_time[TCP_NUM_CNT_COUNTERS];
 #endif
-#ifdef TCPPCAP
-	struct mbufq t_inpkts;		/* List of saved input packets. */
-	struct mbufq t_outpkts;		/* List of saved output packets. */
-#endif
 };
 #endif	/* _KERNEL || _WANT_TCPCB */
 
diff --git a/tools/build/test-includes/badfiles.inc b/tools/build/test-includes/badfiles.inc
index 5f088d3862aa..1e5182e40911 100644
--- a/tools/build/test-includes/badfiles.inc
+++ b/tools/build/test-includes/badfiles.inc
@@ -280,7 +280,6 @@ BADHDRS= \
 	netinet/tcp_log_buf.h \
 	netinet/tcp_lro.h \
 	netinet/tcp_offload.h \
-	netinet/tcp_pcap.h \
 	netinet/tcp_ratelimit.h \
 	netinet/tcp_var.h \
 	netinet/tcpip.h \
diff --git a/usr.sbin/tcpsso/tcpsso.c b/usr.sbin/tcpsso/tcpsso.c
index 95773fe5a4d7..14ea71f9ebbd 100644
--- a/usr.sbin/tcpsso/tcpsso.c
+++ b/usr.sbin/tcpsso/tcpsso.c
@@ -193,8 +193,6 @@ static struct so_name so_names[] = {
 	tcp_entry(TCP_KEEPINTVL),		/* unsigned int */
 	tcp_entry(TCP_KEEPINIT),		/* unsigned int */
 	tcp_entry(TCP_KEEPCNT),			/* unsigned int */
-	tcp_entry(TCP_PCAP_OUT),		/* int */
-	tcp_entry(TCP_PCAP_IN),			/* int */
 	tcp_entry(TCP_LOG),			/* int */
 	tcp_entry(TCP_LOGID),			/* char * */
 	tcp_entry(TCP_LOGDUMP),			/* char * */