Skip to content

Make the network and broadcast address reservation optional and editable - #199

Open
GeertJohan wants to merge 2 commits into
metal-stack:masterfrom
GeertJohan:optional-network-broadcast-reservation
Open

Make the network and broadcast address reservation optional and editable#199
GeertJohan wants to merge 2 commits into
metal-stack:masterfrom
GeertJohan:optional-network-broadcast-reservation

Conversation

@GeertJohan

Copy link
Copy Markdown
Contributor

Every prefix reserves its network and (IPv4) broadcast address at creation (the FIXME in newPrefix). For prefixes used as routed pools, where no L2 semantics apply, this wastes addresses: a /30 yields 2 usable instead of 4.

  • NewPrefix accepts options; WithoutNetworkAndBroadcastReservation() creates a prefix whose network and broadcast address are allocatable.
  • SetNetworkAndBroadcastReservation(ctx, cidr, reserved) edits the flag on an existing prefix: unreserving is always possible, re-reserving fails while either address is allocated.
  • The flag persists through all storages (prefixJSON) and gob; decoding data from before this field defaults to the previous behavior (reserved).
  • hasIPs() and the child prefix release check now account for the flag, so an unreserved prefix with a single allocation cannot be deleted. The child release check previously allowed len(ips) up to 2 regardless of address family; it now uses hasIPs().

Used AI-Tools ✨

  • Claude Fable 5

Noteworthy

  • The gob encoding gains one trailing field. Old encodings decode fine with this version (the missing field defaults to the previous behavior, reserved). Older versions also still decode new encodings, ignoring the trailing field. The one unsafe pattern is a mixed-version round trip: an older go-ipam re-encoding a prefix drops the flag, so a prefix created without the reservation would afterwards read as reserved while its network and broadcast address remain allocatable. Gob-persisting deployments should not run mixed versions against the same data.

@GeertJohan
GeertJohan requested a review from a team as a code owner July 30, 2026 12:24
@metal-robot metal-robot Bot added area: control-plane Affects the metal-stack control-plane area. area: network Affects the network area. labels Jul 30, 2026
@GeertJohan
GeertJohan force-pushed the optional-network-broadcast-reservation branch from 928e1f9 to 5740b61 Compare July 30, 2026 12:29
@codecov-commenter

codecov-commenter commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 36.33441% with 198 lines in your changes missing coverage. Please review.
✅ Project coverage is 33.73%. Comparing base (7636b1b) to head (3a86aa6).

Files with missing lines Patch % Lines
api/v1/ipam.pb.go 0.00% 140 Missing ⚠️
prefix.go 75.96% 14 Missing and 11 partials ⚠️
api/v1/apiv1connect/ipam.connect.go 0.00% 21 Missing ⚠️
cmd/client/client.go 0.00% 6 Missing ⚠️
pkg/service/ipam-service.go 78.57% 4 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #199      +/-   ##
==========================================
+ Coverage   33.46%   33.73%   +0.27%     
==========================================
  Files          17       17              
  Lines        3156     3338     +182     
==========================================
+ Hits         1056     1126      +70     
- Misses       1878     1978     +100     
- Partials      222      234      +12     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@majst01

majst01 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

GRPC Service needs this option to be exposed as well

@GeertJohan
GeertJohan marked this pull request as draft July 30, 2026 14:27
@GeertJohan
GeertJohan force-pushed the optional-network-broadcast-reservation branch from cdfa0aa to 4dac07b Compare July 30, 2026 14:28
@majst01
majst01 marked this pull request as ready for review July 30, 2026 14:43
@GeertJohan
GeertJohan force-pushed the optional-network-broadcast-reservation branch 2 times, most recently from cb395ad to d33321e Compare July 30, 2026 14:46
Every prefix reserves its network and (IPv4) broadcast address at
creation (the FIXME in newPrefix). For prefixes used as routed pools,
where no L2 semantics apply, this wastes addresses: a /30 yields 2
usable instead of 4.

- NewPrefix accepts options; WithNetworkAndBroadcastAllocatable()
  creates a prefix whose network and broadcast address are allocatable
  like any other address.
- Ipamer.SetPrefixNetworkAndBroadcastAllocatable edits the flag on an
  existing prefix: making the addresses allocatable is always possible,
  reserving them again fails while either address is allocated.
- The flag persists through all storages (prefixJSON) and gob; data from
  before this field decodes to the previous behavior (reserved).
- hasIPs() and the child prefix release check account for the flag, so a
  prefix with allocatable boundary addresses cannot be deleted while it
  holds a single allocation. The child release check previously allowed
  up to 2 ips regardless of address family; it now uses hasIPs().
- grpc: network_and_broadcast_allocatable on Prefix and
  CreatePrefixRequest, a new SetPrefixNetworkAndBroadcastAllocatable
  rpc, and the cli flag --network-and-broadcast-allocatable. The proto3
  zero values match the previous behavior, so existing clients and
  servers are unaffected.
@GeertJohan
GeertJohan force-pushed the optional-network-broadcast-reservation branch from d33321e to 996e681 Compare July 30, 2026 14:54
@GeertJohan

Copy link
Copy Markdown
Contributor Author

Changed the naming, I think it's more friendly to read / self-documenting now.

@GeertJohan

Copy link
Copy Markdown
Contributor Author

And implemented gRPC :)

@majst01

majst01 commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

/ok-to-build

@metal-robot metal-robot Bot mentioned this pull request Jul 31, 2026
@majst01

majst01 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Usage reporting needs also adoption

Reserved network and broadcast addresses no longer count as acquired
ips; they reduce the available count instead. A reserved /29 reports
6 available and 0 acquired at creation; with the addresses allocatable
it reports 8 available. The free count (available minus acquired) is
unchanged in both modes.
@GeertJohan

Copy link
Copy Markdown
Contributor Author

@majst01 Added this. Note that the diff changes the meaning of Usage.AvailableIPs and Usage.AcquiredIPs. This could be considered a breaking change by users who depended on AcquiredIPs giving 2 on a fresh/"unused" IPv4 prefix. (Hyrum's law...)
Even though it's not a breaking API change, we could consider a major version bump of go-ipam to notify users of the change. Alternatively, we could revert the behavior of AcquiredIPs, but that feels backwards/wrong.

@majst01

majst01 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

/ok-to-build

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: control-plane Affects the metal-stack control-plane area. area: network Affects the network area.

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants