From 7257c77e1998829705aae4cc0d85084b23df0251 Mon Sep 17 00:00:00 2001 From: Cory Snider Date: Wed, 1 Nov 2023 11:44:24 -0400 Subject: [PATCH] libnetwork/ipam: refactor prefix-overlap checks I am finally convinced that, given two netip.Prefix values a and b, the expression a.Contains(b.Addr()) || b.Contains(a.Addr()) is functionally equivalent to a.Overlaps(b) The (netip.Prefix).Contains method works by masking the address with the prefix's mask and testing whether the remaining most-significant bits are equal to the same bits in the prefix. The (netip.Prefix).Overlaps method works by masking the longer prefix to the length of the shorter prefix and testing whether the remaining most-significant bits are equal. This is equivalent to shorterPrefix.Contains(longerPrefix.Addr()), therefore applying Contains symmetrically to two prefixes will always yield the same result as applying Overlaps to the two prefixes in either order. Signed-off-by: Cory Snider --- libnetwork/ipam/allocator.go | 2 +- libnetwork/ipam/structures.go | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libnetwork/ipam/allocator.go b/libnetwork/ipam/allocator.go index e38ca7fd71..55b51643d1 100644 --- a/libnetwork/ipam/allocator.go +++ b/libnetwork/ipam/allocator.go @@ -214,7 +214,7 @@ func (aSpace *addrSpace) allocatePredefinedPool(ipV6 bool) (netip.Prefix, error) } // Shouldn't be necessary, but check prevents IP collisions should // predefined pools overlap for any reason. - if !aSpace.contains(nw) { + if !aSpace.overlaps(nw) { aSpace.updatePredefinedStartIndex(i + 1) err := aSpace.allocateSubnetL(nw, netip.Prefix{}) if err != nil { diff --git a/libnetwork/ipam/structures.go b/libnetwork/ipam/structures.go index 451d5a9253..c96495d096 100644 --- a/libnetwork/ipam/structures.go +++ b/libnetwork/ipam/structures.go @@ -107,7 +107,7 @@ func (aSpace *addrSpace) allocateSubnet(nw, sub netip.Prefix) error { func (aSpace *addrSpace) allocateSubnetL(nw, sub netip.Prefix) error { // If master pool, check for overlap if sub == (netip.Prefix{}) { - if aSpace.contains(nw) { + if aSpace.overlaps(nw) { return ipamapi.ErrPoolOverlap } // This is a new master pool, add it along with corresponding bitmask @@ -157,10 +157,11 @@ func (aSpace *addrSpace) releaseSubnet(nw, sub netip.Prefix) error { return nil } -// contains checks whether nw is a superset or subset of any of the existing subnets in this address space. -func (aSpace *addrSpace) contains(nw netip.Prefix) bool { +// overlaps reports whether nw contains any IP addresses in common with any of +// the existing subnets in this address space. +func (aSpace *addrSpace) overlaps(nw netip.Prefix) bool { for pool := range aSpace.subnets { - if nw.Contains(pool.Addr()) || pool.Contains(nw.Addr()) { + if pool.Overlaps(nw) { return true } }