diff --git a/pkg/registry/core/service/ipallocator/allocator.go b/pkg/registry/core/service/ipallocator/allocator.go index dd206eb1d0..e8c28bf374 100644 --- a/pkg/registry/core/service/ipallocator/allocator.go +++ b/pkg/registry/core/service/ipallocator/allocator.go @@ -263,8 +263,8 @@ func calculateIPOffset(base *big.Int, ip net.IP) int { // RangeSize returns the size of a range in valid addresses. func RangeSize(subnet *net.IPNet) int64 { ones, bits := subnet.Mask.Size() - if (bits - ones) >= 31 { - panic("masks greater than 31 bits are not supported") + if bits == 32 && (bits-ones) >= 31 || bits == 128 && (bits-ones) >= 63 { + return 0 } max := int64(1) << uint(bits-ones) return max diff --git a/pkg/registry/core/service/ipallocator/allocator_test.go b/pkg/registry/core/service/ipallocator/allocator_test.go index ff854ce31b..481a4d41b6 100644 --- a/pkg/registry/core/service/ipallocator/allocator_test.go +++ b/pkg/registry/core/service/ipallocator/allocator_test.go @@ -166,18 +166,41 @@ func TestAllocateSmall(t *testing.T) { } func TestRangeSize(t *testing.T) { - testCases := map[string]int64{ - "192.168.1.0/24": 256, - "192.168.1.0/32": 1, - "192.168.1.0/31": 2, + testCases := []struct { + name string + cidr string + addrs int64 + }{ + { + name: "supported IPv4 cidr", + cidr: "192.168.1.0/24", + addrs: 256, + }, + { + name: "unsupported IPv4 cidr", + cidr: "192.168.1.0/1", + addrs: 0, + }, + { + name: "supported IPv6 cidr", + cidr: "2001:db8::/98", + addrs: 1073741824, + }, + { + name: "unsupported IPv6 mask", + cidr: "2001:db8::/65", + addrs: 0, + }, } - for k, v := range testCases { - _, cidr, err := net.ParseCIDR(k) + + for _, tc := range testCases { + _, cidr, err := net.ParseCIDR(tc.cidr) if err != nil { - t.Fatal(err) + t.Errorf("failed to parse cidr for test %s, unexpected error: '%s'", tc.name, err) } - if size := RangeSize(cidr); size != v { - t.Errorf("%s should have a range size of %d, got %d", k, v, size) + if size := RangeSize(cidr); size != tc.addrs { + t.Errorf("test %s failed. %s should have a range size of %d, got %d", + tc.name, tc.cidr, tc.addrs, size) } } }