Skip to content

ateomnet: move the actor nftables table to the inet family - #1116

Draft
Yuan Gao (ygao-g) wants to merge 1 commit into
agent-substrate:mainfrom
ygao-g:ateomnet-nft-inet
Draft

ateomnet: move the actor nftables table to the inet family#1116
Yuan Gao (ygao-g) wants to merge 1 commit into
agent-substrate:mainfrom
ygao-g:ateomnet-nft-inet

Conversation

@ygao-g

@ygao-g Yuan Gao (ygao-g) commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Part of #246.

The actor's NAT and filter rules live in an ip table, which can only ever carry IPv4. This moves them to an inet table so one table can hold both address families once the actor veth is dual-stack. Every IPv4 match now opens with an NFPROTO_IPV4 comparison, because a bare payload match in an inet table would read an IPv4 offset out of an IPv6 header. Teardown sweeps ip as well as inet: a table name is unique per family, and the pod netns outlives an in-place container restart.

IPv4 behaviour is unchanged, but this is not a no-op on a dual-stack pod. inet nat chains register the nat hooks for both families, so IPv6 traffic in the worker pod netns is now conntracked — measured in a netns replica, where the ip table produced no IPv6 conntrack entries and the inet table does. The forward chain's accept now covers IPv6 too; it is per-table, so it cannot override a drop from the CNI's own chains. NAT in the inet family needs Linux 5.2 or later, and the tests skip rather than fail below that.

First of two: #1057 builds on this to give the actor an IPv6 address. This one has no dependency of its own.

Testing

TestActorNftablesRuleExprs pins the rule expressions and needs no root, so it runs in make test. Root-gated: TestSetupActorNetworkInstallsEgressRedirect checks that an inet nat chain actually takes the redirect, TestRemoveActorNftablesRulesSweepsIPv4Family covers the ipinet upgrade, and TestSetupActorNetworkIsRepeatable asserts the table is gone after each teardown.

Three negative controls discriminate (Linux 6.17, under root): deleting the NFPROTO guard fails TestActorNftablesRuleExprs and TestSetupActorNetworkInstallsEgressRedirect and nothing else, dropping ip from the sweep fails only TestRemoveActorNftablesRulesSweepsIPv4Family, and skipping the redirect install fails only TestSetupActorNetworkInstallsEgressRedirect.

🤖 Generated with Claude Code

Benjamin Elder (BenTheElder) added a commit to BenTheElder/substrate that referenced this pull request Aug 21, 2026
Both ateoms now build actor networking through internal/actornet, so
ateomnet's version has had no caller outside its own package since the
micro-VM ateom moved. This deletes it: SetupActorNetwork, NetworkConfig,
CleanupActorNetwork, ConfigureActorVeth, the nftables install and remove,
their expression helpers, and PodIPv4 and DumpNetInfo, which only those
used. What stays is what actornet actually consumes -- the veth constants
and addresses, MustParse*, EnableIPv4Forwarding, TCPProtocol, and the
namespace helpers.

Leaving it would not have been merely untidy. It creates a table named
ateom_actor in the ip family, and actornet creates one under the same name
for the actors that are really running; a table name is unique per family,
so the two are invisible to each other's cleanup and either could delete
or shadow the other's. That is latent while nothing calls the dead path,
and stops being latent the moment anyone does.

The table name moves to actornet with it, unexported, since actornet is
now its only creator. The value is unchanged so an ateom rolling onto this
code still recognises and clears the table its predecessor left behind.

Two smaller leftovers of the same replacement: prepareOCIBundles no longer
takes the ateom pod UID, because the namespace it writes into the bundle is
keyed by actor now; and ateomnet's tests go with the code they covered,
after porting the three that pin behaviour actornet still has -- repeatable
setup, the fixed host-veth MAC, and the interior-link sweep. The last two
are micro-VM requirements, so losing their coverage would have been a real
gap rather than a bookkeeping one.

NOTE: this collides with agent-substrate#1116, which moves the same table to the inet
family, and with agent-substrate#1057 behind it. Both are dual-stack work on code this
deletes. Whichever lands first, the other side is a delete-vs-modify
conflict -- loud, and resolved by keeping the delete -- but the dual-stack
change will need to be made in actornet instead. Worth settling before any
of this becomes a real PR.
The actor's NAT and filter rules lived in an ip table, which can only
ever carry IPv4. They are now in an inet table, so one table can hold
both address families when the actor veth becomes dual-stack. Every
IPv4 match opens with an NFPROTO comparison, because a bare payload
match in an inet table would read an IPv4 offset out of an IPv6 header.
IPv4 behaviour is unchanged, but the move is not a no-op on a dual-stack
pod: inet nat chains register the nat hooks for both families, so IPv6
traffic in the worker pod netns is now conntracked, and the forward
accept now covers IPv6. NAT in the inet family needs Linux 5.2 or later.

Teardown sweeps ip as well as inet. A table name is unique per family,
so the ip table an earlier ateom left behind is invisible to an
inet-only cleanup: the dump comes back empty, the "already clean" path
reports success, and the stale table keeps redirecting alongside the
new one.

Part of agent-substrate#246
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