Skip to content

sec(FP-8): land goip_write tag and no-write-encoders check on main (#298, #299) - #305

Merged
randomizedcoder merged 14 commits into
mainfrom
sec/fp8-land
Nov 14, 2026
Merged

randomizedcoder merged 14 commits into
mainfrom
sec/fp8-land

Conversation

@randomizedcoder

Copy link
Copy Markdown
Owner

Lands FP-8b (#298) and FP-8c (#299) on main. Both were merged into their stacked base branches after #297 had already gone to main, so their content never reached main.

  • sec/fp8b-goip-write-tag at 3f43e56 (FP-8b + FP-8c as reviewed), with current main merged in (clean, no conflicts).
  • FP-8b: goip write verbs behind goip_write via the writeOps seam; pkg/xtcpnl write builders tagged; Nix wiring.
  • FP-8c: checks.no-write-encoders and docs.
  • Since Add reviewed TCP route treatments, controller, and VM soak tests #282: pkg/xtcpnl's route/rule builders build with goip_write || treatment for internal/goip/actuate; link/addr/nsid/genl/xfrm stay goip_write-only.
  • internal/goip/actuate, pkg/treatment/{local,agent}, xtcp2-treatment-agent and xtcp2-treatmentctl build with treatment (already set on full builds by mkGoBinary).
  • no-write-encoders exempts exactly those three files/symbols under treatment; go-link-monitor stays strict; adds xtcp2-min (files and no_exec).
  • go vet clean untagged, treatment, goip_write, and both.

🤖 Generated with Claude Code

randomizedcoder and others added 14 commits November 12, 2026 00:32
Every runX write arm now calls through writeOps, a table of the arms
whose untagged default is a stub per arm returning ErrWriteNotCompiled
(an ErrWriteVerb). write_ops_goip_write.go fills in the real arms under
the goip_write tag. The chain arms claim exactly their segment's verbs,
so flush, restore and route's MPLS check keep their order; neigh and
nexthop gain segments for that. ioam's and sr's inline write tails
become ioamWrite and srWrite.

From here an untagged build refuses every write verb. The write files
still compile into it; the next commit tags them, their tests, and the
builds that need them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The write-only files in internal/goip, pkg/xtcpnl and
pkg/nlparity/nlparity_write.go carry //go:build goip_write, as do
internal/goipparity and cmd/goip-parity whole. Untagged, writeOps keeps
its stubs and every write verb is ErrWriteNotCompiled, exit 1.

Tests follow the code: a test of a tagged file is tagged, a mixed file's
write tests move to <stem>_write_test.go, and the helpers only tagged
tests use move with them. A mixed table's write rows skip in the untagged
build when the run is ErrWriteNotCompiled; the goip_write leg runs them.

- nlparity.IsWrite and ParseWriteRequests* move to the untagged
  nlparity_classify.go, and xtcpnl.IsAdmittedXfrmWrite to
  xtcpnl_xfrm_request.go: they classify, they build nothing.
- notag_test.go: every write verb is ErrWriteNotCompiled with no request
  sent, and writeOps is the stubs; TestWriteOpsTagged is the other half.
- The segment parity test gains neigh and nexthop.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- versions.goipWriteTags; binaries.nix adds it per name (extraTagsByName)
  to goip and goip-parity only. goip_write joins optInOnlyTags, and
  flavor-tags fails a full xtcp2 that carries it.
- The three golangci tiers and govulncheck's all-tags pass take the tag.
- test-focused-goip runs with it, over internal/goipparity, pkg/nlparity
  and pkg/xtcpnl too: their write halves build only so. The untagged
  halves run in the default `go test ./...`.
- write_ops.go: initialized, for misspell.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
checks.no-write-encoders proves goip_write stays out of xtcp2 and
go-link-monitor, each proof with a positive control:

- files: go list -deps with each binary's own tags names no write file
  of internal/goip, pkg/xtcpnl or pkg/nlparity; with goip_write it does.
- symbols: go tool nm on xtcp2-debug and go-link-monitor finds no write
  builder, Encode*InfoData or goip write arm; goip has BuildWriteRequest.
- no_exec: no package in either daemon's deps imports os/exec, bar
  minio-go's credentials provider (s3parquet), which is listed.

A manual negative run (BuildWriteRequest untagged and referenced from
goip.Show) fails both the files and the symbols proofs for both daemons.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- docs/build-flavors.md: a "goip write verbs" section (who carries the
  tag, what /ip does without it, the check, how to test the write path)
  and a row in the build-tag table.
- docs/netlink/README.md: the parity harness notes the write path is
  goip/goip-parity only.
- cmd/goip: the package comment said goip was read-only; it now says
  writes are dry runs behind goip_write.
- CHANGELOG Breaking: /ip and the daemons carry no netlink write verbs.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
…te-tag

Main's NX10 bpf encap writes (bpf_load.go, lwt_encap_bpf_args.go and their
tests) take the goip_write tag like the other encap parsers. wsO5Spaces
moves to the untagged ws_differential_test.go: the readback tests (O9)
read it. Main's fou and O5 test updates go to the tagged files they moved
to.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#282's treatment actuator (internal/goip/actuate) encodes routes and rules
with xtcpnl's typed builders, which FP-8b put behind goip_write.

- BuildWriteRequest, the route builders and the rule builders build with
  `goip_write || treatment`; link, addr, nsid, genl and xfrm writes stay
  goip_write-only.
- actuate, pkg/treatment/{local,agent}, xtcp2-treatment-agent and
  xtcp2-treatmentctl build with `treatment` (mkGoBinary already sets it for
  the full-destination builds those binaries come from).
- Boundary rules for those packages walk with the tag; the untagged daemon
  must not reach actuate.
- golangci tiers lint with `treatment`; tcp-controller quality tests and
  focused-xtcp-treatment pass it (treatmentctl added).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
A `treatment` build embeds internal/goip/actuate, which encodes routes and
rules. It may compile xtcpnl_{route,rule}_write.go and xtcpnl_write_request.go
and link BuildWriteRequest/BuildRouteWriteRequest/BuildRuleWriteRequest;
everything else of the write set still fails. The exemption list must all be
present under the tag, or it is stale.

- Adds xtcp2-min (no treatment tag, stripped) to the files and no_exec proofs.
- go-link-monitor (untagged) stays fully strict.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
test(nix): no-write-encoders check, goip_write docs (FP-8c)
@randomizedcoder
randomizedcoder merged commit e1fd8a5 into main Nov 14, 2026
1 check failed
@randomizedcoder
randomizedcoder deleted the sec/fp8-land branch November 14, 2026 07:34
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.

1 participant