Skip to content

net/tcpstats-kmod: new port for TCP socket statistics kernel module#497

Open
randomizedcoder wants to merge 2 commits intofreebsd:mainfrom
randomizedcoder:net/tcpstats-kmod
Open

net/tcpstats-kmod: new port for TCP socket statistics kernel module#497
randomizedcoder wants to merge 2 commits intofreebsd:mainfrom
randomizedcoder:net/tcpstats-kmod

Conversation

@randomizedcoder
Copy link
Copy Markdown

Summary

Port Details

  • USES=kmod uidfix with USE_GITHUB=yes
  • WRKSRC_SUBDIR=kmod/tcp_stats_kld (module lives within larger repo)
  • OPTIONS_DEFINE: DTRACE (DTrace SDT probes) and STATS (per-socket statistics counters)
  • License: MIT

What tcp_stats_kld does

Creates a read-only character device (/dev/tcpstats) that streams fixed-size 320-byte records containing per-connection TCP metrics: addresses, ports, TCP state, congestion control parameters (cwnd, ssthresh), RTT measurements, retransmit counts, ECN statistics, and process attribution. Features in-kernel filtering by port, TCP state, IP version, and CIDR address ranges.

Testing

Tested on:

  • FreeBSD 15.0-RELEASE — make, make stage, make check-plist, make package
  • FreeBSD 14.4-RELEASE — make, make stage, make check-plist, make package
  • FreeBSD 14.3-RELEASE — full cycle including kldload, sysctl dev.tcpstats, kldunload
  • All OPTIONS variants (DTRACE, STATS, DTRACE+STATS) build and pass check-plist ✓
  • 131 integration tests pass on all 3 FreeBSD versions ✓

Test plan

  • portlint -AC passes
  • make stage && make check-plist && make package on supported FreeBSD versions
  • kldload tcp_stats_kld.ko creates /dev/tcpstats
  • sysctl dev.tcpstats shows tunables
  • kldunload tcp_stats_kld removes device cleanly

🤖 Generated with Claude Code

@randomizedcoder
Copy link
Copy Markdown
Author

Hmmmm. No CI here. Interesting

@spmzt
Copy link
Copy Markdown
Member

spmzt commented Mar 17, 2026

Hmmmm. No CI here. Interesting

Github PRs are still experimental, as defined in porters handbook, we use bugzilla for our ports.
See: https://bugs.freebsd.org/

Thank you for your PR!
let me find a port committer to review your PR first.

@randomizedcoder
Copy link
Copy Markdown
Author

randomizedcoder commented Mar 17, 2026 via email

Copy link
Copy Markdown
Contributor

@clausecker clausecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Port looks ok, haven't done a build test yet. Please check the indicated items.

It might be a good idea to refactor the upstream repository such that its name matches the port name and that no subdirectory is required. Not required though.


MAINTAINER= dave.seddon.ca@gmail.com
COMMENT= Kernel module for system-wide TCP socket statistics
WWW= https://github.com/randomizedcoder/bsd-xtcp
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be omitted, as WWW is automatically derived from the GH_* macros.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will very much likely break various services and tools, please don't this.

@clausecker
Please review Porters Handbook
https://docs.freebsd.org/en/books/porters-handbook/book/#porting-makefile

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the specific objection?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WWW

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WWW being set through USE_GITHUB is an intentional feature of the ports framework. Will not break and services or tools, as make -VWWW works just fine. If you were not supposed to use this mechanism, why would it be present?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have quite a few things that parses the Makefile, just don't.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tools that parse port Makefiles instead of running make -V... are defective and should be rewritten. I am not going to accommodate defective tools.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stop with this sillyness, you have multiple entries in Porters Handbook clearly telling you to define it including examples for Rust. If you have issues with it push changes from there instead.
https://docs.freebsd.org/en/books/porters-handbook/book/#using-cargo

@@ -0,0 +1,31 @@
PORTNAME= tcpstats
DISTVERSION= 1.0.0
DISTVERSIONPREFIX= v
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please order the macros (variables) as given in Porter's Handbook. Try portlint and portclippy to check for correct formatting.

Copy link
Copy Markdown
Contributor

@diizzyy diizzyy Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should also be mentioned that neither tool is perfect. A better solution overall since submitter is upstream is to generate a static release archive. See https://docs.freebsd.org/en/books/porters-handbook/book/#makefile-master_sites-github

Edit: It's in Rust so the current solution is the better one and the one recommended by Porters Handbook. Sorry for the noise


PLIST_FILES= ${KMODDIR}/tcp_stats_kld.ko

OPTIONS_DEFINE= DTRACE STATS
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason these two options are not on by default?

Do you have a man page or similar documenting this module? Would be quite helpful.

@randomizedcoder
Copy link
Copy Markdown
Author

Thanks for the feedback.

I've been considering what to do.

@clausecker - I think you are correct. I'll refactor the https://github.com/randomizedcoder/bsd-xtcp, so that this original repo and this proposed freebsd-ports are aligned. Otherwise it will be a maintenance pain in the $@!@#%.

@clausecker - Regarding DTRACE and STATS, these were features I added for very detailed analysis of the kernel module will I was performing the long running stress tests. I don't think most people need these. But this is good feedback, so I can update the docs to make this clear.

I'll update this in the next couple of days. Thanks again.

@clausecker
Copy link
Copy Markdown
Contributor

Thanks, looking forwards to your update! Please also strongly consider adding a man page or other form of documentation.

@randomizedcoder
Copy link
Copy Markdown
Author

@clausecker
Oh sorry I forgot to mention. The original pull request to freebsd has the man page, but sorry I forgot about it when recreating the PR for ports. I'll bring it over and refresh it.
https://github.com/freebsd/freebsd-src/pull/2079/changes#diff-0b512d479c9a5ab20d3b6119a825116f6c2646eef98d1a805ebc368cc1e58f13

@randomizedcoder
Copy link
Copy Markdown
Author

Thanks for the review feedback @clausecker and @diizzyy — really appreciate the guidance.

I've pushed an update addressing the items raised:

  • Macro ordering: moved DISTVERSIONPREFIX before DISTVERSION
  • Man page: added man/man4/tcpstats.4.gz to PLIST_FILES
  • Upstream repo refactored: renamed everything in bsd-xtcp to match the port naming:
    • Kernel module: tcp_stats_kldtcpstats (source files: tcp_statsdev.c/.h)
    • Kmod directory: kmod/tcp_stats_kld/kmod/tcpstats/
    • Userspace reader crate: bsd-xtcptcpstats-reader
    • Prometheus exporter: tcp-stats-kld-exportertcpstats-exporter
  • WWW= kept per Porter's Handbook
  • DTRACE/STATS options: left off by default — these enable verbose per-socket counters and DTrace SDT probes used during stress testing, not needed for typical use

The upstream repo restructuring means changes now flow directly between bsd-xtcp and this port without name mismatches — should make ongoing maintenance much simpler.

Verified by building and loading tcpstats.ko, then running tcpstats-reader --count 1 --pretty on FreeBSD 14.3, 14.4, and 15.0 VMs — all passing.

@clausecker
Copy link
Copy Markdown
Contributor

@randomizedcoder Please check, your PR is still on the state it was three weeks ago.

@randomizedcoder
Copy link
Copy Markdown
Author

Doh! Sorry @clausecker, looks like I forgot to git push. My bad. Please let me know how it looks now - thanks in advance.

@clausecker clausecker self-assigned this Apr 20, 2026
Copy link
Copy Markdown
Contributor

@clausecker clausecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, will commit with my next batch.

@clausecker
Copy link
Copy Markdown
Contributor

Are you ok with me adjusting your authorship data to

randomizedcoder <dave.seddon.ca@gmail.com>

and adding

Signed-off-by: randomizedcoder <dave.seddon.ca@gmail.com>

to the commit trailer? Through some sort of misconfiguration you currently have your email address in the author name in addition to it being in the email address field.

We do have a slight preference to real names, but using a pseudonym is fine, too.

@clausecker
Copy link
Copy Markdown
Contributor

Also, the port fails to build as you submitted it:

===>  Missing license file for MIT in /usr/home/ports/main.ports/net/tcpstats-kmod/work/bsd-xtcp-1.0.0/kmod/tcpstats/../../LICENSE
*** Error code 1

This is because your port looks for a subdirectory kmod/tcpstats, but actually the kernel module is in kmod/tcp_stats_kld. Have you actually build-tested this port prior to submission?

@clausecker
Copy link
Copy Markdown
Contributor

It seems like you may have forgotten to push your reorganisation to the bsd-xtcp repo and then forgotten to tag a new release and then forgotten to reference that release in the port.

Please rework.

randomizedcoder and others added 2 commits April 26, 2026 20:03
tcpstats is a FreeBSD kernel module that exports per-connection TCP socket
statistics via a /dev/tcpstats character device. Provides 320-byte fixed-size
records containing addresses, ports, TCP state, congestion control parameters,
RTT measurements, retransmit counts, and ECN statistics.

Options:
  DTRACE - Enable DTrace SDT probes (7 probes) with 5 example scripts
  STATS  - Enable per-socket statistics counters

Tested on FreeBSD 15.0-RELEASE, 14.4-RELEASE, and 14.3-RELEASE via
automated port-test infrastructure (stage, stage-qa, check-plist,
install, kldload, package, deinstall, option variants).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Command-line tool for reading TCP socket statistics from the tcpstats
kernel module on FreeBSD. Reads fixed-size 320-byte records from
/dev/tcpstats and outputs JSON Lines, pretty-printed JSON, or protobuf.

Requires the tcpstats-kmod port to be installed and loaded.

BUILD_DEPENDS: protobuf (protoc for prost code generation)
USES: cargo (112 crate dependencies)

Tested on FreeBSD 15.0-RELEASE, 14.4-RELEASE, and 14.3-RELEASE via
automated port-test infrastructure (stage, stage-qa, check-plist,
install, --help, package, deinstall).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@randomizedcoder
Copy link
Copy Markdown
Author

randomizedcoder commented Apr 27, 2026

@clausecker Thanks for the patience, and apologies for the back and forth. I've done a full rework and proper build-testing this time.

What changed:

  • Squashed the branch into 2 clean commits
  • Upstream tagged as v1.0.2 — directory structure, naming, and tarball all aligned
  • Man page installed to share/man/man4/tcpstats.4.gz
  • DTRACE option now installs 5 example DTrace scripts to share/examples/tcpstats/ (all_probes.d, read_latency.d, read_summary.d, filter_skip_reasons.d, fill_time.d)
  • Added a companion port: net/tcpstats-reader — Rust CLI that reads from /dev/tcpstats and outputs JSON/protobuf (USES=cargo, 112 crate dependencies)

Build testing (for real this time):

Both ports tested through the full cycle on 3 VMs via automated port-test infrastructure:

Phase FreeBSD 15.0 FreeBSD 14.4 FreeBSD 14.3
stage PASS PASS PASS
stage-qa PASS PASS PASS
check-plist PASS PASS PASS
install PASS PASS PASS
kldload + /dev/tcpstats PASS PASS PASS
package PASS PASS PASS
deinstall PASS PASS PASS
DTRACE variant PASS PASS PASS
STATS variant PASS PASS PASS
tcpstats-reader stage/install/package PASS PASS PASS

Full details, bugs found, and port Makefiles documented in docs/status/port-testing.md.

Regarding authorship: Yes, absolutely fine to adjust to randomizedcoder <dave.seddon.ca@gmail.com> with your Signed-off-by. Thanks for catching the misconfiguration.

Regarding DTRACE/STATS options: These remain off by default — they're for detailed analysis during stress testing, not typical use. But with the DTRACE option now installing example scripts, users who do enable it get ready-to-use DTrace one-liners for latency measurement, probe tracing, and filter debugging.

Screenshot of testing with x3 versions of FreeBSD
image

Copy link
Copy Markdown
Member

@spmzt spmzt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@randomizedcoder
You probably tested with the header installed.

/usr/ports/net/tcpstats-kmod % make
...
tcp_statsdev_filter.c:66:10: fatal error: 'netinet/tcp_statsdev_filter.h' file not found
66 | #include <netinet/tcp_statsdev_filter.h>
|          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
*** [tcp_statsdev_filter.o] Error code 1

make: stopped making "all" in /usr/ports/net/tcpstats-kmod/work/bsd-xtcp-1.0.2/kmod/tcpstats
--- tcp_statsdev.o ---
tcp_statsdev.c:74:10: fatal error: 'netinet/tcp_statsdev.h' file not found
74 | #include <netinet/tcp_statsdev.h>
|          ^~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
*** [tcp_statsdev.o] Error code 1

make: stopped making "all" in /usr/ports/net/tcpstats-kmod/work/bsd-xtcp-1.0.2/kmod/tcpstats
make: 2 errors

make: stopped making "all" in /usr/ports/net/tcpstats-kmod/work/bsd-xtcp-1.0.2/kmod/tcpstats
===> Compilation failed unexpectedly.
Try to set MAKE_JOBS_UNSAFE=yes and rebuild before reporting the failure to
the maintainer.
*** Error code 1

Stop.
make[1]: stopped making "/usr/ports/net/tcpstats-kmod/work/.stage_done.tcpstats._usr_local" in /usr/ports/net/tcpstats-kmod
*** Error code 1

Stop.
make: stopped making "all" in /usr/ports/net/tcpstats-kmod

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants