A machine says which networks it routes, and its filter forwards them

The derived filter denies forwarding by default and then allows the container
runtime's two default pools, named in this code with a comment saying a machine
configured otherwise needs to say so -- and no way to say it. So the filter was
right on a machine using the defaults and silently wrong on any other.

Measured today: flipping a workstation to the derived filter cut egress for five
of its container networks and for every network its test beds create, because
those come from ranges the defaults do not cover. Nothing reported a fault; the
guests just could not reach anything, while the machine reported it had applied
what it was told.

A node-level fact beside the public domain, because the machine routes them and
the module that loads the filter may be replaced. Added to the defaults, never
replacing them. Their guests also keep address and name service, without which a
network does not work at all, and the converge preview now says what a machine
routes instead of leaving it to a sentence about what it cannot preview.
This commit is contained in:
2026-09-28 21:29:10 +02:00
parent ce9e20fbbc
commit 54812306be
12 changed files with 358 additions and 22 deletions
+6 -1
View File
@@ -124,6 +124,11 @@ type Rendering struct {
// nothing on this node keeps them, or the mesh has no operator key.
Kept *KeptExport
// Routed is the networks this machine routes for what it hosts, beyond the container runtime's
// own default pools, which the filter allows without being told (novox/hq ADR 0137). A node-level
// fact: the machine routes them, and the module that loads the filter may be replaced.
Routed []string
// Foundation is the ports the mesh itself needs reachable on every machine, which no module
// declares because the foundation is not a module (novox/hq 04-ISSUES/051 and 052). The broker
// is the one that matters: a machine dials it to enrol, and a firewall derived only from
@@ -345,7 +350,7 @@ func (r Resolution) compose(with Rendering, owner map[string]string) ([]map[stri
if err != nil {
return nil, err
}
filtering := AsNftables(rules, with.Mesh, r.PublicDomain != "", with.Foundation)
filtering := AsNftables(rules, with.Mesh, r.PublicDomain != "", with.Foundation, with.Routed)
var out []map[string]any
for _, m := range r.Modules {