Skip to content

Remove dependency on apparentlymart/go-cidr#661

Open
redbeam wants to merge 1 commit into
containers:mainfrom
redbeam:dependency-remove
Open

Remove dependency on apparentlymart/go-cidr#661
redbeam wants to merge 1 commit into
containers:mainfrom
redbeam:dependency-remove

Conversation

@redbeam

@redbeam redbeam commented May 11, 2026

Copy link
Copy Markdown
Contributor

Fixes #651

Replace the go-cidr library with Go's standard netip package. The dependency was only used in pkg/tap/ip_pool.go for counting IPs and getting the nth host address in a subnet.

Changes:

  • Convert IPPool to use netip.Prefix and netip.Addr instead of net.IPNet and net.IP
  • Replace cidr.Host() iteration with netip.Addr.Next() traversal
  • Remove cidr.AddressCount() by iterating directly through the prefix
  • Update callers in pkg/virtualnetwork and pkg/services/dhcp

Assisted-by: Claude Sonnet 4.5 noreply@anthropic.com

@openshift-ci

openshift-ci Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: redbeam
Once this PR has been reviewed and has the lgtm label, please assign baude for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@cfergeau cfergeau left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to see this deps removes with about the same amount of code:

 pkg/services/dhcp/dhcp.go            |  2 +-
 pkg/tap/ip_pool.go                   | 37 +++++++++++++++----------------------
 pkg/tap/ip_pool_test.go              |  4 ++--
 pkg/virtualnetwork/virtualnetwork.go | 15 ++++++++++++---
 4 files changed, 30 insertions(+), 28 deletions(-)

All of this with native go APIs, no need to use getNextUsableIPFromSubnet, good!

Comment thread pkg/tap/ip_pool.go
}
return nil, errors.New("cannot find available IP")

return netip.Addr{}, errors.New("cannot find available IP")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be sure, if we’ve allocated all IPs from the pool, p.base.Contains(candidate) will be false, and we will return netip.Addr{}, errors.New("cannot find available IP")?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly.

Comment thread pkg/tap/ip_pool_test.go Outdated

func TestIPPool(t *testing.T) {
_, network, _ := net.ParseCIDR("10.0.0.0/8")
network := netip.MustParsePrefix("10.0.0.0/8")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be a good opportunity to ask claude/your favorite agent to add more extensive test coverage for this API?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I asked Claude to do it and this is what was added:

  1. TestIPPoolExhaustion - Verifies that when all IPs in a small subnet (/30) are allocated, the pool correctly returns an error for the next assignment
  2. TestIPPoolReserve - Tests the Reserve() functionality:
    - Reserving specific IPs
    - Verifying reserved IPs appear in leases
    - Confirming GetOrAssign() skips reserved IPs
    - Testing that requesting the same MAC as a reservation returns the reserved IP
  3. TestIPPoolMask - Validates the Mask() method returns correct CIDR bits for various subnet sizes
  4. TestIPPoolReleaseNonExistent - Ensures releasing a non-existent MAC doesn't panic or corrupt the pool state
  5. TestIPPoolSmallSubnet - Tests edge case with a /29 subnet (8 total IPs), verifying all usable IPs are assigned correctly and exhaustion is handled
  6. TestIPPoolReleaseAndReassign - Validates that released IPs are properly reused on subsequent assignments (tests the gap-filling behavior)

Comment thread pkg/virtualnetwork/virtualnetwork.go Outdated
if err != nil {
return nil, fmt.Errorf("cannot parse static lease IP %s: %w", ip, err)
}
ipPool.Reserve(addr, mac)

@cfergeau cfergeau May 13, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of wondering if the calls to ParsePrefix and ParseIP should be done in pkg/tap/ip_pool.go, with an added error to the return values? This would make this code simpler.
Just starting a conversation, it’s fine with me if you prefer to keep the code this way.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

Comment thread pkg/tap/ip_pool.go Outdated
base *net.IPNet
count uint64
base netip.Prefix
leases map[string]string

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imo, if you change this to leases map[netip.Addr]string this makes the code slightly simpler

Compared to the net.IP type, Addr type takes less memory, is immutable, and is comparable (supports == and being a map key).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, changed that.

@redbeam redbeam force-pushed the dependency-remove branch from cd10577 to cb2ad84 Compare May 21, 2026 12:01
Fixes containers#651

Replace the go-cidr library with Go's standard netip package and
refactor IPPool for better ergonomics and type safety.

Changes:
- Convert IPPool to use netip.Prefix and netip.Addr instead of
  net.IPNet and net.IP
- Change leases map from map[string]string to map[netip.Addr]string,
  eliminating string conversions in hot paths
- Move parsing into API: NewIPPool and Reserve now accept strings
  and handle parsing internally, simplifying caller code
- Replace cidr.Host() iteration with netip.Addr.Next() traversal
- Remove cidr.AddressCount() by iterating directly through prefix
- Update callers in pkg/virtualnetwork and pkg/services/dhcp

Add extensive test coverage:
- Pool exhaustion with small subnets (/30, /29)
- IP reservation and gap-filling behavior
- Release and reassignment logic
- Invalid input validation (malformed subnets and IPs)
- Edge cases like non-existent MAC release

Assisted-by: Claude Sonnet 4.5 <noreply@anthropic.com>

Signed-off-by: Matus Skvarla <mskvarla@redhat.com>
@redbeam redbeam force-pushed the dependency-remove branch from cb2ad84 to 32dbf3f Compare May 21, 2026 12:36
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.

Remove usage of apparentlymart/go-cidr?

2 participants