FreeBSD SIFTR: Read TCP Control-Block Telemetry Without Packet Capture
Use FreeBSD SIFTR to sample TCP control-block state, bound log volume, correlate with BPF captures, and account for kernel-memory risks.
When a TCP connection stalls, packet capture shows what crossed an observation point; it does not directly show every decision represented in the host TCP control block. FreeBSD’s SIFTR module (Statistical Information For TCP Research) logs per-flow TCP state when packets traverse its hooks. That makes it useful for diagnosing windows, retransmission timing, RTT estimates, and queue state alongside a packet capture. It is not a payload capture and does not replace tcpdump(1).
The distinction matters operationally. SIFTR records connection metadata such as local and foreign addresses and ports, TCP state, congestion and advertised windows, smoothed RTT, retransmission timeout, socket buffer occupancy, bytes in flight, and reassembly-queue depth. Those fields can be sensitive even though application payload is not present. In the FreeBSD 15.1 kernel source, SIFTR requests mode 0644 when ALQ creates its output file, so do not rely on a process umask to make a newly created log private. The ALQ open path does not truncate an existing file, so its requested creation mode does not establish the current mode of a pre-existing log. On a vendor-fixed build, protect access through the containing directory’s ownership, traversal permissions, and ACL policy, then inspect the actual log file’s owner, mode, ACL, and contents before relying on it. Treat the result as production telemetry with an access policy, bounded collection window, and explicit cleanup plan.
Check the target release and module first
The commands below follow the FreeBSD 15.1-RELEASE siftr(4) manual. Verify the manual shipped for the exact host before applying them. In its documented default build, SIFTR handles IPv4 TCP; IPv6 support requires the module to be built with SIFTR_IPV6. Do not interpret a quiet IPv6 flow as evidence that SIFTR observed it.
The module is disabled by default after loading. The manual says its pfil hooks are inserted only when net.inet.siftr.enabled is set to 1, so loading an idle module is different from enabling measurements. If firewall or other modules use the same pfil framework, the manual advises loading those modules first so their packet changes occur before SIFTR observes traffic.
Inspect state before considering collection
The read-only checks below help record the exact kernel release, current SIFTR settings, and available space. Run the SIFTR queries only if the module is loaded; an unknown OID is not a value of zero.
freebsd-version -kru
sysctl net.inet.siftr.enabled
sysctl net.inet.siftr.ppl
sysctl net.inet.siftr.port_filter
sysctl net.inet.siftr.logfile
df -h /var/log
The reviewed FreeBSD 15.1 release source and current upstream main source both contain a material enable-path defect: siftr_manage_ops(SIFTR_ENABLE) calls alq_open() but ignores its return, with a source comment noting that it should abort on failure. The handler can continue into worker and hook setup even if opening the log fails; therefore, a successful sysctl net.inet.siftr.enabled=1 is not sufficient evidence that collection is safely initialized. The logfile-setting handler separately probes a changed path, but enabling opens the path again, so a preflight file test cannot verify that second open. Because the failure can leave the kernel module in an inconsistent state, this article deliberately does not provide a command or automation to enable capture on those builds. Verify the exact source and vendor fix for the installed kernel before considering collection, and do not infer a particular failure outcome beyond what the source shows.
For a source-verified build where this path has been fixed, ppl controls how many eligible packets per connection trigger a log message; the documented default is 1. port_filter can restrict eligibility to connections whose source or destination port matches a chosen port, but the manual does not provide a per-address flow filter. Prefer a narrow port and coarser packet interval, use a bounded collection window, and verify both the resulting log contents and the access controls of its containing directory. In the reviewed 15.1 source, the module requests file mode 0644; if extended ACLs are enabled or inherited, inspect them as well rather than relying on the mode bits alone.
The manual allows changing ppl and the log path while enabled, but changing a path is not log rotation by itself. Preserve the original evidence and do not delete the active file expecting the module to reopen it; the manual warns that messages can be lost if the configured path is deleted.
Even ppl=20 is not an exact one-in-twenty sampling guarantee. Packets skipped before the processing thread are not counted by the PPL logic, so a skipped packet can shift the next trigger. Inspect the disable summary for skipped-packet counters and record the enable/disable timestamps. SIFTR’s rows are CSV data, but parse them against the field order documented for that FreeBSD release rather than guessing a header or importing them as an unrelated generic CSV schema.
Correlate state with what was on the wire
Use a separate, time-bounded BPF capture for the relevant interface and flow. Align system clocks, capture interval, interface direction, and the local/foreign tuple. SIFTR observes packets at IP-layer pfil hooks; its documentation notes that inbound packets are seen before TCP processing, whereas outbound packets are seen after TCP processing. Thus, the two directions do not represent the same point in the TCP state transition.
Some lifecycle events cannot produce a complete SIFTR control-block sample: the initial handshake can precede a fully initialized control block, and the final ACK occurs in TIME_WAIT. If the question is “was this SYN on the wire?” use a capture. If the question is “what TCP state and window values did the host report around these later packets?” SIFTR may add useful evidence. Neither source alone necessarily gives the complete story.
The SIFTR manual also warns that its inter-thread queue is unbounded. Under sustained high packet rates, if the worker cannot keep up, queued records can consume kernel memory. PPL reduces output volume but does not turn the tool into an unlimited, fixed-overhead telemetry service. Monitor memory and system behavior during a controlled test, stop promptly when the evidence is sufficient, and never claim that the module has zero performance cost while it is actively collecting.
Stop cleanly and preserve the evidence
On a build whose enable path has been reviewed and fixed, stop collection using that release’s documented control, verify it is disabled before changing other settings or unloading the module, and retain the exact host release, module version, sysctl values, and collection times with the log. If the log shows skipped-packet counters, a port filter that captured both directions, or IPv4-only support, record those constraints with any conclusion. Scrub or restrict endpoint addresses and ports before sharing the file outside the operations team. If SIFTR is already active on an affected build, coordinate recovery with the system owner or vendor rather than blindly applying a generic restore script.
SIFTR is most effective as one measurement in a diagnosis: TCP control-block samples explain host-side state, while BPF capture records packets at its own observation point. Use both when needed, state exactly what each saw, and avoid turning a short-lived kernel research instrument into an unbounded production logging pipeline.
Related:
- FreeBSD BPF Packet Capture: Filters, Buffers, and Loss-Aware Analysis
- FreeBSD TCP Congestion Control: Selecting Algorithms and Measuring Real Paths
Sources:
- FreeBSD 15.1-RELEASE
siftr(4)manual - configuration, row fields, hook placement, and documented limitations. - FreeBSD 15.1 SIFTR kernel source - requested log-file mode and the metadata fields emitted by the module.
- Current FreeBSD SIFTR kernel source - confirms the enable-path
alq_open()behavior is still present in upstream main. - FreeBSD 15.1-RELEASE
tcpdump(1)manual - packet-capture command reference. - FreeBSD 15.1-RELEASE
pfil(9)manual - packet-filter hook framework referenced by SIFTR.