fix(cni): reserve the IPv6 pool subnet containing the gateway address - #267
Merged
Conversation
PoolAllocator handed out the /96 tile containing the region's own gateway (::1) to the first endpoint allocated from a pool, letting that endpoint self-assign the gateway's address to one of its own secondary/pod addresses and collide with the address every other endpoint's default route points at. IPv4PoolAllocator already reserved its network/gateway/broadcast addresses; PoolAllocator now reserves the gateway's containing subnet the same way. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
mattdjenkinson
approved these changes
Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PoolAllocator(used for IPv6 endpoint IPAM) could hand out the/96tile containing the region's own gateway address (::1) to the first endpoint allocated from a pool.datum-cloud/enhancements→architecture/design/network/addressing/tenant.md) reserves the remainder of an endpoint's/96for that endpoint to self-assign to secondary IPs/containers/pods, that endpoint could self-assign the gateway's own address — colliding with the address every other endpoint in the region routes its default route through.IPv4PoolAllocatoralready reserves its network/gateway/second-to-last/broadcast addresses (seereservedAddresses());PoolAllocatornow reserves the gateway's containing/96subnet the same way, so it's never handed out byAllocate.Test plan
go build ./...go test ./internal/cni/...go vet ./internal/cni/...golangci-lint run ./internal/cni/...TestPoolAllocatorReservesGatewaySubnet, which allocates 1,000 subnets from the pool and asserts the gateway's reserved/96is never returned byAllocateand is never reported allocated byIsAllocated.🤖 Generated with Claude Code