@@ -19,14 +19,10 @@ package ipallocator
19
19
import (
20
20
"errors"
21
21
"fmt"
22
-
23
- "math/big"
24
- "net"
25
-
26
22
api "k8s.io/kubernetes/pkg/apis/core"
27
23
"k8s.io/kubernetes/pkg/registry/core/service/allocator"
28
- "k8s.io/utils/integer "
29
- utilnet "k8s.io/utils/ net"
24
+ "math/big "
25
+ " net"
30
26
)
31
27
32
28
// Interface manages the allocation of IP addresses out of a range. Interface
@@ -84,8 +80,8 @@ type Range struct {
84
80
85
81
// NewAllocatorCIDRRange creates a Range over a net.IPNet, calling allocatorFactory to construct the backing store.
86
82
func NewAllocatorCIDRRange (cidr * net.IPNet , allocatorFactory allocator.AllocatorFactory ) (* Range , error ) {
87
- max := integer . Int64Min ( utilnet . RangeSize (cidr ), 1 << 16 )
88
- base := utilnet . BigForIP (cidr .IP )
83
+ max := RangeSize (cidr )
84
+ base := bigForIP (cidr .IP )
89
85
rangeSpec := cidr .String ()
90
86
91
87
r := Range {
@@ -173,7 +169,7 @@ func (r *Range) AllocateNext() (net.IP, error) {
173
169
if ! ok {
174
170
return nil , ErrFull
175
171
}
176
- return utilnet . AddIPOffset (r .base , offset ), nil
172
+ return addIPOffset (r .base , offset ), nil
177
173
}
178
174
179
175
// Release releases the IP back to the pool. Releasing an
@@ -191,7 +187,7 @@ func (r *Range) Release(ip net.IP) error {
191
187
// ForEach calls the provided function for each allocated IP.
192
188
func (r * Range ) ForEach (fn func (net.IP )) {
193
189
r .alloc .ForEach (func (offset int ) {
194
- ip , _ := utilnet . GetIndexedIP (r .net , offset + 1 ) // +1 because Range doesn't store IP 0
190
+ ip , _ := GetIndexedIP (r .net , offset + 1 ) // +1 because Range doesn't store IP 0
195
191
fn (ip )
196
192
})
197
193
}
@@ -249,8 +245,49 @@ func (r *Range) contains(ip net.IP) (bool, int) {
249
245
return true , offset
250
246
}
251
247
248
+ // bigForIP creates a big.Int based on the provided net.IP
249
+ func bigForIP (ip net.IP ) * big.Int {
250
+ b := ip .To4 ()
251
+ if b == nil {
252
+ b = ip .To16 ()
253
+ }
254
+ return big .NewInt (0 ).SetBytes (b )
255
+ }
256
+
257
+ // addIPOffset adds the provided integer offset to a base big.Int representing a
258
+ // net.IP
259
+ func addIPOffset (base * big.Int , offset int ) net.IP {
260
+ return net .IP (big .NewInt (0 ).Add (base , big .NewInt (int64 (offset ))).Bytes ())
261
+ }
262
+
252
263
// calculateIPOffset calculates the integer offset of ip from base such that
253
264
// base + offset = ip. It requires ip >= base.
254
265
func calculateIPOffset (base * big.Int , ip net.IP ) int {
255
- return int (big .NewInt (0 ).Sub (utilnet .BigForIP (ip ), base ).Int64 ())
266
+ return int (big .NewInt (0 ).Sub (bigForIP (ip ), base ).Int64 ())
267
+ }
268
+
269
+ // RangeSize returns the size of a range in valid addresses.
270
+ func RangeSize (subnet * net.IPNet ) int64 {
271
+ ones , bits := subnet .Mask .Size ()
272
+ if bits == 32 && (bits - ones ) >= 31 || bits == 128 && (bits - ones ) >= 127 {
273
+ return 0
274
+ }
275
+ // For IPv6, the max size will be limited to 65536
276
+ // This is due to the allocator keeping track of all the
277
+ // allocated IP's in a bitmap. This will keep the size of
278
+ // the bitmap to 64k.
279
+ if bits == 128 && (bits - ones ) >= 16 {
280
+ return int64 (1 ) << uint (16 )
281
+ } else {
282
+ return int64 (1 ) << uint (bits - ones )
283
+ }
284
+ }
285
+
286
+ // GetIndexedIP returns a net.IP that is subnet.IP + index in the contiguous IP space.
287
+ func GetIndexedIP (subnet * net.IPNet , index int ) (net.IP , error ) {
288
+ ip := addIPOffset (bigForIP (subnet .IP ), index )
289
+ if ! subnet .Contains (ip ) {
290
+ return nil , fmt .Errorf ("can't generate IP with index %d from subnet. subnet too small. subnet: %q" , index , subnet )
291
+ }
292
+ return ip , nil
256
293
}
0 commit comments