Skip to content

feat(cni): add dual-stack IPv6/IPv4 IPAM allocators#257

Open
privateip wants to merge 2 commits into
mainfrom
feat/cni-dual-stack-ipam
Open

feat(cni): add dual-stack IPv6/IPv4 IPAM allocators#257
privateip wants to merge 2 commits into
mainfrom
feat/cni-dual-stack-ipam

Conversation

@privateip

Copy link
Copy Markdown
Contributor

Summary

Phase 2 of the datum-cloud/enhancements#740 tenant addressing model — the allocator-level groundwork for dual-stack (IPv6 + IPv4) endpoint IP assignment:

  • PoolAllocator's DefaultSubnetLen moves from 80 to 96, matching the new endpoint-subnet size drawn from a /64 region pool instead of a /48 VPC pool. Local-IPAM fallback constants (cni.go) and docs/cni/configuration.md updated to match.
  • New IPv4PoolAllocator (internal/cni/ipam/ipv4.go) allocates individual /32s from an IPv4 pool, reserving the network, gateway, and last two addresses via pool-relative offsets (correct for any prefix length, not hardcoded to /24).
  • New DualStackAllocator (internal/cni/ipam/dualstack.go) wraps both allocators behind one Allocate() call; the IPv4 side is optional, so IPv6-only VPCs are unaffected.
  • Fixes a pre-existing bug in incSubnet: it zeroed the same byte it had just incremented, so a PoolAllocator could never produce more than two distinct subnets from one instance before spinning forever on the third Allocate() call. No observable effect under normal CNI usage (each invocation is a fresh process/allocator), but it blocks DualStackAllocator's exhaustion test, which allocates repeatedly from one long-lived instance.

NAD schema changes, CNI config wiring (PluginConf, allocateIPAM), and BGP advertisement updates that consume these allocators are separate, later phases — not included here.

Test plan

  • go build ./...
  • go vet ./...
  • go test ./internal/cni/ipam/... -race -v (new + existing tests)
  • go test ./... (full repo)
  • task lint (0 issues)

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

PR datum-cloud/enhancements#740 moves galactic-cni to a hierarchical,
dual-stack tenant addressing model (VPC /48 -> region /64 -> endpoint
/96 for IPv6; a shared IPv4 /9 -> macro-region /12 -> site /20 ->
endpoint /32). This lands the allocator-level groundwork:

- PoolAllocator's DefaultSubnetLen moves from 80 to 96, matching the
  new endpoint-subnet size drawn from a /64 region pool instead of a
  /48 VPC pool; the local-IPAM fallback constants in cni.go and
  docs/cni/configuration.md are updated to match.
- New IPv4PoolAllocator allocates individual /32s from an IPv4 pool,
  reserving the network, gateway, and last two addresses using
  pool-relative offsets (works for any prefix length, not just /24).
- New DualStackAllocator wraps both allocators behind a single
  Allocate() call; the IPv4 side is optional so IPv6-only VPCs are
  unaffected.

Also fixes a pre-existing bug in incSubnet: it zeroed the same byte it
had just incremented, so any PoolAllocator could never produce more
than two distinct subnets from one instance before spinning forever on
the third Allocate() call. This had no observable effect under normal
CNI usage (each invocation is a fresh process/allocator) but blocks
DualStackAllocator's exhaustion test, which allocates repeatedly from
one long-lived instance.

NAD schema changes, CNI config wiring, and BGP advertisement updates
that consume these allocators are separate, later phases.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@privateip
privateip requested a review from a team as a code owner July 26, 2026 15:08
Each CNI ADD/DEL is a separate OS process, so IPv4PoolAllocator's
in-memory sync.Map never guarded against concurrent invocations. PR
#740's shared site-wide IPv4 /20 makes that reachable: two pods in
different VPCs on the same node can race to allocate from the
identical pool. Persist allocations as marker files under a pool-scoped
state directory and guard reads/writes with a cross-process flock, so
concurrent allocator instances never hand out the same address.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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