Browse code

Remove 2^32 bits restriction on bitsequence

- Allow bitsequence of length 2^64-1
- Updated ID Manager and IPAM

Signed-off-by: Alessandro Boch <aboch@docker.com>

Alessandro Boch authored on 2015/10/09 12:04:13
Showing 9 changed files
... ...
@@ -17,10 +17,10 @@ import (
17 17
 // If needed we can think of making these configurable
18 18
 const (
19 19
 	blockLen      = uint32(32)
20
-	blockBytes    = blockLen / 8
20
+	blockBytes    = uint64(blockLen / 8)
21 21
 	blockMAX      = uint32(1<<blockLen - 1)
22 22
 	blockFirstBit = uint32(1) << (blockLen - 1)
23
-	invalidPos    = blockMAX
23
+	invalidPos    = uint64(0xFFFFFFFFFFFFFFFF)
24 24
 )
25 25
 
26 26
 var (
... ...
@@ -29,8 +29,8 @@ var (
29 29
 
30 30
 // Handle contains the sequece representing the bitmask and its identifier
31 31
 type Handle struct {
32
-	bits       uint32
33
-	unselected uint32
32
+	bits       uint64
33
+	unselected uint64
34 34
 	head       *sequence
35 35
 	app        string
36 36
 	id         string
... ...
@@ -41,7 +41,7 @@ type Handle struct {
41 41
 }
42 42
 
43 43
 // NewHandle returns a thread-safe instance of the bitmask handler
44
-func NewHandle(app string, ds datastore.DataStore, id string, numElements uint32) (*Handle, error) {
44
+func NewHandle(app string, ds datastore.DataStore, id string, numElements uint64) (*Handle, error) {
45 45
 	h := &Handle{
46 46
 		app:        app,
47 47
 		id:         id,
... ...
@@ -76,7 +76,7 @@ func NewHandle(app string, ds datastore.DataStore, id string, numElements uint32
76 76
 // sequence represents a recurring sequence of 32 bits long bitmasks
77 77
 type sequence struct {
78 78
 	block uint32    // block is a symbol representing 4 byte long allocation bitmask
79
-	count uint32    // number of consecutive blocks (symbols)
79
+	count uint64    // number of consecutive blocks (symbols)
80 80
 	next  *sequence // next sequence
81 81
 }
82 82
 
... ...
@@ -92,7 +92,7 @@ func (s *sequence) toString() string {
92 92
 }
93 93
 
94 94
 // GetAvailableBit returns the position of the first unset bit in the bitmask represented by this sequence
95
-func (s *sequence) getAvailableBit(from uint32) (uint32, uint32, error) {
95
+func (s *sequence) getAvailableBit(from uint64) (uint64, uint64, error) {
96 96
 	if s.block == blockMAX || s.count == 0 {
97 97
 		return invalidPos, invalidPos, errNoBitAvailable
98 98
 	}
... ...
@@ -145,9 +145,9 @@ func (s *sequence) toByteArray() ([]byte, error) {
145 145
 
146 146
 	p := s
147 147
 	for p != nil {
148
-		b := make([]byte, 8)
148
+		b := make([]byte, 12)
149 149
 		binary.BigEndian.PutUint32(b[0:], p.block)
150
-		binary.BigEndian.PutUint32(b[4:], p.count)
150
+		binary.BigEndian.PutUint64(b[4:], p.count)
151 151
 		bb = append(bb, b...)
152 152
 		p = p.next
153 153
 	}
... ...
@@ -158,7 +158,7 @@ func (s *sequence) toByteArray() ([]byte, error) {
158 158
 // fromByteArray construct the sequence from the byte array
159 159
 func (s *sequence) fromByteArray(data []byte) error {
160 160
 	l := len(data)
161
-	if l%8 != 0 {
161
+	if l%12 != 0 {
162 162
 		return fmt.Errorf("cannot deserialize byte sequence of lenght %d (%v)", l, data)
163 163
 	}
164 164
 
... ...
@@ -166,8 +166,8 @@ func (s *sequence) fromByteArray(data []byte) error {
166 166
 	i := 0
167 167
 	for {
168 168
 		p.block = binary.BigEndian.Uint32(data[i : i+4])
169
-		p.count = binary.BigEndian.Uint32(data[i+4 : i+8])
170
-		i += 8
169
+		p.count = binary.BigEndian.Uint64(data[i+4 : i+12])
170
+		i += 12
171 171
 		if i == l {
172 172
 			break
173 173
 		}
... ...
@@ -192,7 +192,7 @@ func (h *Handle) getCopy() *Handle {
192 192
 }
193 193
 
194 194
 // SetAnyInRange atomically sets the first unset bit in the specified range in the sequence and returns the corresponding ordinal
195
-func (h *Handle) SetAnyInRange(start, end uint32) (uint32, error) {
195
+func (h *Handle) SetAnyInRange(start, end uint64) (uint64, error) {
196 196
 	if end-start <= 0 || end >= h.bits {
197 197
 		return invalidPos, fmt.Errorf("invalid bit range [%d, %d]", start, end)
198 198
 	}
... ...
@@ -203,7 +203,7 @@ func (h *Handle) SetAnyInRange(start, end uint32) (uint32, error) {
203 203
 }
204 204
 
205 205
 // SetAny atomically sets the first unset bit in the sequence and returns the corresponding ordinal
206
-func (h *Handle) SetAny() (uint32, error) {
206
+func (h *Handle) SetAny() (uint64, error) {
207 207
 	if h.Unselected() == 0 {
208 208
 		return invalidPos, errNoBitAvailable
209 209
 	}
... ...
@@ -211,7 +211,7 @@ func (h *Handle) SetAny() (uint32, error) {
211 211
 }
212 212
 
213 213
 // Set atomically sets the corresponding bit in the sequence
214
-func (h *Handle) Set(ordinal uint32) error {
214
+func (h *Handle) Set(ordinal uint64) error {
215 215
 	if err := h.validateOrdinal(ordinal); err != nil {
216 216
 		return err
217 217
 	}
... ...
@@ -220,7 +220,7 @@ func (h *Handle) Set(ordinal uint32) error {
220 220
 }
221 221
 
222 222
 // Unset atomically unsets the corresponding bit in the sequence
223
-func (h *Handle) Unset(ordinal uint32) error {
223
+func (h *Handle) Unset(ordinal uint64) error {
224 224
 	if err := h.validateOrdinal(ordinal); err != nil {
225 225
 		return err
226 226
 	}
... ...
@@ -230,7 +230,7 @@ func (h *Handle) Unset(ordinal uint32) error {
230 230
 
231 231
 // IsSet atomically checks if the ordinal bit is set. In case ordinal
232 232
 // is outside of the bit sequence limits, false is returned.
233
-func (h *Handle) IsSet(ordinal uint32) bool {
233
+func (h *Handle) IsSet(ordinal uint64) bool {
234 234
 	if err := h.validateOrdinal(ordinal); err != nil {
235 235
 		return false
236 236
 	}
... ...
@@ -241,11 +241,11 @@ func (h *Handle) IsSet(ordinal uint32) bool {
241 241
 }
242 242
 
243 243
 // set/reset the bit
244
-func (h *Handle) set(ordinal, start, end uint32, any bool, release bool) (uint32, error) {
244
+func (h *Handle) set(ordinal, start, end uint64, any bool, release bool) (uint64, error) {
245 245
 	var (
246
-		bitPos  uint32
247
-		bytePos uint32
248
-		ret     uint32
246
+		bitPos  uint64
247
+		bytePos uint64
248
+		ret     uint64
249 249
 		err     error
250 250
 	)
251 251
 
... ...
@@ -309,7 +309,7 @@ func (h *Handle) set(ordinal, start, end uint32, any bool, release bool) (uint32
309 309
 }
310 310
 
311 311
 // checks is needed because to cover the case where the number of bits is not a multiple of blockLen
312
-func (h *Handle) validateOrdinal(ordinal uint32) error {
312
+func (h *Handle) validateOrdinal(ordinal uint64) error {
313 313
 	if ordinal >= h.bits {
314 314
 		return fmt.Errorf("bit does not belong to the sequence")
315 315
 	}
... ...
@@ -341,9 +341,9 @@ func (h *Handle) ToByteArray() ([]byte, error) {
341 341
 
342 342
 	h.Lock()
343 343
 	defer h.Unlock()
344
-	ba := make([]byte, 8)
345
-	binary.BigEndian.PutUint32(ba[0:], h.bits)
346
-	binary.BigEndian.PutUint32(ba[4:], h.unselected)
344
+	ba := make([]byte, 16)
345
+	binary.BigEndian.PutUint64(ba[0:], h.bits)
346
+	binary.BigEndian.PutUint64(ba[8:], h.unselected)
347 347
 	bm, err := h.head.toByteArray()
348 348
 	if err != nil {
349 349
 		return nil, fmt.Errorf("failed to serialize head: %s", err.Error())
... ...
@@ -360,27 +360,27 @@ func (h *Handle) FromByteArray(ba []byte) error {
360 360
 	}
361 361
 
362 362
 	nh := &sequence{}
363
-	err := nh.fromByteArray(ba[8:])
363
+	err := nh.fromByteArray(ba[16:])
364 364
 	if err != nil {
365 365
 		return fmt.Errorf("failed to deserialize head: %s", err.Error())
366 366
 	}
367 367
 
368 368
 	h.Lock()
369 369
 	h.head = nh
370
-	h.bits = binary.BigEndian.Uint32(ba[0:4])
371
-	h.unselected = binary.BigEndian.Uint32(ba[4:8])
370
+	h.bits = binary.BigEndian.Uint64(ba[0:8])
371
+	h.unselected = binary.BigEndian.Uint64(ba[8:16])
372 372
 	h.Unlock()
373 373
 
374 374
 	return nil
375 375
 }
376 376
 
377 377
 // Bits returns the length of the bit sequence
378
-func (h *Handle) Bits() uint32 {
378
+func (h *Handle) Bits() uint64 {
379 379
 	return h.bits
380 380
 }
381 381
 
382 382
 // Unselected returns the number of bits which are not selected
383
-func (h *Handle) Unselected() uint32 {
383
+func (h *Handle) Unselected() uint64 {
384 384
 	h.Lock()
385 385
 	defer h.Unlock()
386 386
 	return h.unselected
... ...
@@ -426,7 +426,7 @@ func (h *Handle) UnmarshalJSON(data []byte) error {
426 426
 }
427 427
 
428 428
 // getFirstAvailable looks for the first unset bit in passed mask starting from start
429
-func getFirstAvailable(head *sequence, start uint32) (uint32, uint32, error) {
429
+func getFirstAvailable(head *sequence, start uint64) (uint64, uint64, error) {
430 430
 	// Find sequence which contains the start bit
431 431
 	byteStart, bitStart := ordinalToPos(start)
432 432
 	current, _, _, inBlockBytePos := findSequence(head, byteStart)
... ...
@@ -450,7 +450,7 @@ func getFirstAvailable(head *sequence, start uint32) (uint32, uint32, error) {
450 450
 
451 451
 // checkIfAvailable checks if the bit correspondent to the specified ordinal is unset
452 452
 // If the ordinal is beyond the sequence limits, a negative response is returned
453
-func checkIfAvailable(head *sequence, ordinal uint32) (uint32, uint32, error) {
453
+func checkIfAvailable(head *sequence, ordinal uint64) (uint64, uint64, error) {
454 454
 	bytePos, bitPos := ordinalToPos(ordinal)
455 455
 
456 456
 	// Find the sequence containing this byte
... ...
@@ -470,7 +470,7 @@ func checkIfAvailable(head *sequence, ordinal uint32) (uint32, uint32, error) {
470 470
 // sequence containing the byte (current), the pointer to the previous sequence,
471 471
 // the number of blocks preceding the block containing the byte inside the current sequence.
472 472
 // If bytePos is outside of the list, function will return (nil, nil, 0, invalidPos)
473
-func findSequence(head *sequence, bytePos uint32) (*sequence, *sequence, uint32, uint32) {
473
+func findSequence(head *sequence, bytePos uint64) (*sequence, *sequence, uint64, uint64) {
474 474
 	// Find the sequence containing this byte
475 475
 	previous := head
476 476
 	current := head
... ...
@@ -511,7 +511,7 @@ func findSequence(head *sequence, bytePos uint32) (*sequence, *sequence, uint32,
511 511
 // A) block is first in current:         [prev seq] [new] [modified current seq] [next seq]
512 512
 // B) block is last in current:          [prev seq] [modified current seq] [new] [next seq]
513 513
 // C) block is in the middle of current: [prev seq] [curr pre] [new] [curr post] [next seq]
514
-func pushReservation(bytePos, bitPos uint32, head *sequence, release bool) *sequence {
514
+func pushReservation(bytePos, bitPos uint64, head *sequence, release bool) *sequence {
515 515
 	// Store list's head
516 516
 	newHead := head
517 517
 
... ...
@@ -599,18 +599,18 @@ func mergeSequences(seq *sequence) {
599 599
 	}
600 600
 }
601 601
 
602
-func getNumBlocks(numBits uint32) uint32 {
603
-	numBlocks := numBits / blockLen
604
-	if numBits%blockLen != 0 {
602
+func getNumBlocks(numBits uint64) uint64 {
603
+	numBlocks := numBits / uint64(blockLen)
604
+	if numBits%uint64(blockLen) != 0 {
605 605
 		numBlocks++
606 606
 	}
607 607
 	return numBlocks
608 608
 }
609 609
 
610
-func ordinalToPos(ordinal uint32) (uint32, uint32) {
610
+func ordinalToPos(ordinal uint64) (uint64, uint64) {
611 611
 	return ordinal / 8, ordinal % 8
612 612
 }
613 613
 
614
-func posToOrdinal(bytePos, bitPos uint32) uint32 {
614
+func posToOrdinal(bytePos, bitPos uint64) uint64 {
615 615
 	return bytePos*8 + bitPos
616 616
 }
... ...
@@ -9,9 +9,9 @@ import (
9 9
 func TestSequenceGetAvailableBit(t *testing.T) {
10 10
 	input := []struct {
11 11
 		head    *sequence
12
-		from    uint32
13
-		bytePos uint32
14
-		bitPos  uint32
12
+		from    uint64
13
+		bytePos uint64
14
+		bitPos  uint64
15 15
 	}{
16 16
 		{&sequence{block: 0x0, count: 0}, 0, invalidPos, invalidPos},
17 17
 		{&sequence{block: 0x0, count: 1}, 0, 0, 0},
... ...
@@ -120,8 +120,8 @@ func TestSequenceCopy(t *testing.T) {
120 120
 func TestGetFirstAvailable(t *testing.T) {
121 121
 	input := []struct {
122 122
 		mask    *sequence
123
-		bytePos uint32
124
-		bitPos  uint32
123
+		bytePos uint64
124
+		bitPos  uint64
125 125
 	}{
126 126
 		{&sequence{block: 0xffffffff, count: 2048}, invalidPos, invalidPos},
127 127
 		{&sequence{block: 0x0, count: 8}, 0, 0},
... ...
@@ -167,9 +167,9 @@ func TestGetFirstAvailable(t *testing.T) {
167 167
 func TestFindSequence(t *testing.T) {
168 168
 	input := []struct {
169 169
 		head           *sequence
170
-		bytePos        uint32
171
-		precBlocks     uint32
172
-		inBlockBytePos uint32
170
+		bytePos        uint64
171
+		precBlocks     uint64
172
+		inBlockBytePos uint64
173 173
 	}{
174 174
 		{&sequence{block: 0xffffffff, count: 0}, 0, 0, invalidPos},
175 175
 		{&sequence{block: 0xffffffff, count: 0}, 31, 0, invalidPos},
... ...
@@ -202,9 +202,9 @@ func TestFindSequence(t *testing.T) {
202 202
 func TestCheckIfAvailable(t *testing.T) {
203 203
 	input := []struct {
204 204
 		head    *sequence
205
-		ordinal uint32
206
-		bytePos uint32
207
-		bitPos  uint32
205
+		ordinal uint64
206
+		bytePos uint64
207
+		bitPos  uint64
208 208
 	}{
209 209
 		{&sequence{block: 0xffffffff, count: 0}, 0, invalidPos, invalidPos},
210 210
 		{&sequence{block: 0xffffffff, count: 0}, 31, invalidPos, invalidPos},
... ...
@@ -274,8 +274,8 @@ func TestMergeSequences(t *testing.T) {
274 274
 func TestPushReservation(t *testing.T) {
275 275
 	input := []struct {
276 276
 		mask    *sequence
277
-		bytePos uint32
278
-		bitPos  uint32
277
+		bytePos uint64
278
+		bitPos  uint64
279 279
 		newMask *sequence
280 280
 	}{
281 281
 		// Create first sequence and fill in 8 addresses starting from address 0
... ...
@@ -445,8 +445,8 @@ func TestSet(t *testing.T) {
445 445
 	}
446 446
 	hnd.head = getTestSequence()
447 447
 
448
-	firstAv := uint32(32*100 + 31)
449
-	last := uint32(1024*32 - 1)
448
+	firstAv := uint64(32*100 + 31)
449
+	last := uint64(1024*32 - 1)
450 450
 
451 451
 	if hnd.IsSet(100000) {
452 452
 		t.Fatal("IsSet() returned wrong result")
... ...
@@ -497,7 +497,7 @@ func TestSet(t *testing.T) {
497 497
 }
498 498
 
499 499
 func TestSetUnset(t *testing.T) {
500
-	numBits := uint32(64 * 1024)
500
+	numBits := uint64(64 * 1024)
501 501
 	hnd, err := NewHandle("", nil, "", numBits)
502 502
 	if err != nil {
503 503
 		t.Fatal(err)
... ...
@@ -508,7 +508,7 @@ func TestSetUnset(t *testing.T) {
508 508
 			t.Fatal(err)
509 509
 		}
510 510
 	}
511
-	i := uint32(0)
511
+	i := uint64(0)
512 512
 	for hnd.Unselected() < numBits {
513 513
 		if err := hnd.Unset(i); err != nil {
514 514
 			t.Fatal(err)
... ...
@@ -518,14 +518,14 @@ func TestSetUnset(t *testing.T) {
518 518
 }
519 519
 
520 520
 func TestSetInRange(t *testing.T) {
521
-	numBits := uint32(1024 * blockLen)
521
+	numBits := uint64(1024 * blockLen)
522 522
 	hnd, err := NewHandle("", nil, "", numBits)
523 523
 	if err != nil {
524 524
 		t.Fatal(err)
525 525
 	}
526 526
 	hnd.head = getTestSequence()
527 527
 
528
-	firstAv := uint32(100*blockLen + blockLen - 1)
528
+	firstAv := uint64(100*blockLen + blockLen - 1)
529 529
 
530 530
 	if o, err := hnd.SetAnyInRange(4, 3); err == nil {
531 531
 		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
... ...
@@ -539,7 +539,7 @@ func TestSetInRange(t *testing.T) {
539 539
 		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
540 540
 	}
541 541
 
542
-	o, err := hnd.SetAnyInRange(100*blockLen, 101*blockLen)
542
+	o, err := hnd.SetAnyInRange(100*uint64(blockLen), 101*uint64(blockLen))
543 543
 	if err != nil {
544 544
 		t.Fatalf("Unexpected failure: (%d, %v)", o, err)
545 545
 	}
... ...
@@ -547,7 +547,7 @@ func TestSetInRange(t *testing.T) {
547 547
 		t.Fatalf("Unexpected ordinal: %d", o)
548 548
 	}
549 549
 
550
-	if o, err := hnd.SetAnyInRange(0, blockLen); err == nil {
550
+	if o, err := hnd.SetAnyInRange(0, uint64(blockLen)); err == nil {
551 551
 		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
552 552
 	}
553 553
 
... ...
@@ -555,27 +555,27 @@ func TestSetInRange(t *testing.T) {
555 555
 		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
556 556
 	}
557 557
 
558
-	if o, err := hnd.SetAnyInRange(111*blockLen, 161*blockLen); err == nil {
558
+	if o, err := hnd.SetAnyInRange(111*uint64(blockLen), 161*uint64(blockLen)); err == nil {
559 559
 		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
560 560
 	}
561 561
 
562
-	o, err = hnd.SetAnyInRange(161*blockLen, 162*blockLen)
562
+	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen))
563 563
 	if err != nil {
564 564
 		t.Fatal(err)
565 565
 	}
566
-	if o != 161*blockLen+30 {
566
+	if o != 161*uint64(blockLen)+30 {
567 567
 		t.Fatalf("Unexpected ordinal: %d", o)
568 568
 	}
569 569
 
570
-	o, err = hnd.SetAnyInRange(161*blockLen, 162*blockLen)
570
+	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen))
571 571
 	if err != nil {
572 572
 		t.Fatal(err)
573 573
 	}
574
-	if o != 161*blockLen+31 {
574
+	if o != 161*uint64(blockLen)+31 {
575 575
 		t.Fatalf("Unexpected ordinal: %d", o)
576 576
 	}
577 577
 
578
-	o, err = hnd.SetAnyInRange(161*blockLen, 162*blockLen)
578
+	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen))
579 579
 	if err == nil {
580 580
 		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
581 581
 	}
... ...
@@ -475,7 +475,7 @@ func (n *network) releaseVxlanID() error {
475 475
 	}
476 476
 
477 477
 	for _, s := range n.subnets {
478
-		n.driver.vxlanIdm.Release(n.vxlanID(s))
478
+		n.driver.vxlanIdm.Release(uint64(n.vxlanID(s)))
479 479
 		n.setVxlanID(s, 0)
480 480
 	}
481 481
 	return nil
... ...
@@ -502,9 +502,9 @@ func (n *network) obtainVxlanID(s *subnet) error {
502 502
 				return fmt.Errorf("failed to allocate vxlan id: %v", err)
503 503
 			}
504 504
 
505
-			n.setVxlanID(s, vxlanID)
505
+			n.setVxlanID(s, uint32(vxlanID))
506 506
 			if err := n.writeToStore(); err != nil {
507
-				n.driver.vxlanIdm.Release(n.vxlanID(s))
507
+				n.driver.vxlanIdm.Release(uint64(n.vxlanID(s)))
508 508
 				n.setVxlanID(s, 0)
509 509
 				if err == datastore.ErrKeyModified {
510 510
 					continue
... ...
@@ -10,13 +10,13 @@ import (
10 10
 
11 11
 // Idm manages the reservation/release of numerical ids from a contiguos set
12 12
 type Idm struct {
13
-	start  uint32
14
-	end    uint32
13
+	start  uint64
14
+	end    uint64
15 15
 	handle *bitseq.Handle
16 16
 }
17 17
 
18 18
 // New returns an instance of id manager for a set of [start-end] numerical ids
19
-func New(ds datastore.DataStore, id string, start, end uint32) (*Idm, error) {
19
+func New(ds datastore.DataStore, id string, start, end uint64) (*Idm, error) {
20 20
 	if id == "" {
21 21
 		return nil, fmt.Errorf("Invalid id")
22 22
 	}
... ...
@@ -33,7 +33,7 @@ func New(ds datastore.DataStore, id string, start, end uint32) (*Idm, error) {
33 33
 }
34 34
 
35 35
 // GetID returns the first available id in the set
36
-func (i *Idm) GetID() (uint32, error) {
36
+func (i *Idm) GetID() (uint64, error) {
37 37
 	if i.handle == nil {
38 38
 		return 0, fmt.Errorf("ID set is not initialized")
39 39
 	}
... ...
@@ -42,7 +42,7 @@ func (i *Idm) GetID() (uint32, error) {
42 42
 }
43 43
 
44 44
 // GetSpecificID tries to reserve the specified id
45
-func (i *Idm) GetSpecificID(id uint32) error {
45
+func (i *Idm) GetSpecificID(id uint64) error {
46 46
 	if i.handle == nil {
47 47
 		return fmt.Errorf("ID set is not initialized")
48 48
 	}
... ...
@@ -55,6 +55,6 @@ func (i *Idm) GetSpecificID(id uint32) error {
55 55
 }
56 56
 
57 57
 // Release releases the specified id
58
-func (i *Idm) Release(id uint32) {
58
+func (i *Idm) Release(id uint64) {
59 59
 	i.handle.Unset(id - i.start)
60 60
 }
... ...
@@ -17,9 +17,8 @@ const (
17 17
 	localAddressSpace  = "LocalDefault"
18 18
 	globalAddressSpace = "GlobalDefault"
19 19
 	// The biggest configurable host subnets
20
-	minNetSize      = 8
21
-	minNetSizeV6    = 64
22
-	minNetSizeV6Eff = 96
20
+	minNetSize   = 8
21
+	minNetSizeV6 = 64
23 22
 	// datastore keyes for ipam objects
24 23
 	dsConfigKey = "ipam/" + ipamapi.DefaultIPAM + "/config"
25 24
 	dsDataKey   = "ipam/" + ipamapi.DefaultIPAM + "/data"
... ...
@@ -129,7 +128,7 @@ func (a *Allocator) GetDefaultAddressSpaces() (string, string, error) {
129 129
 // RequestPool returns an address pool along with its unique id.
130 130
 func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
131 131
 	log.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6)
132
-	k, nw, aw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6)
132
+	k, nw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6)
133 133
 	if err != nil {
134 134
 		return "", nil, nil, ipamapi.ErrInvalidPool
135 135
 	}
... ...
@@ -157,7 +156,7 @@ retry:
157 157
 		goto retry
158 158
 	}
159 159
 
160
-	return k.String(), aw, nil, insert()
160
+	return k.String(), nw, nil, insert()
161 161
 }
162 162
 
163 163
 // ReleasePool releases the address pool identified by the passed id
... ...
@@ -205,41 +204,38 @@ func (a *Allocator) getAddrSpace(as string) (*addrSpace, error) {
205 205
 	return aSpace, nil
206 206
 }
207 207
 
208
-func (a *Allocator) parsePoolRequest(addressSpace, pool, subPool string, v6 bool) (*SubnetKey, *net.IPNet, *net.IPNet, *AddressRange, error) {
208
+func (a *Allocator) parsePoolRequest(addressSpace, pool, subPool string, v6 bool) (*SubnetKey, *net.IPNet, *AddressRange, error) {
209 209
 	var (
210
-		nw, aw *net.IPNet
211
-		ipr    *AddressRange
212
-		err    error
210
+		nw  *net.IPNet
211
+		ipr *AddressRange
212
+		err error
213 213
 	)
214 214
 
215 215
 	if addressSpace == "" {
216
-		return nil, nil, nil, nil, ipamapi.ErrInvalidAddressSpace
216
+		return nil, nil, nil, ipamapi.ErrInvalidAddressSpace
217 217
 	}
218 218
 
219 219
 	if pool == "" && subPool != "" {
220
-		return nil, nil, nil, nil, ipamapi.ErrInvalidSubPool
220
+		return nil, nil, nil, ipamapi.ErrInvalidSubPool
221 221
 	}
222 222
 
223 223
 	if pool != "" {
224 224
 		if _, nw, err = net.ParseCIDR(pool); err != nil {
225
-			return nil, nil, nil, nil, ipamapi.ErrInvalidPool
225
+			return nil, nil, nil, ipamapi.ErrInvalidPool
226 226
 		}
227 227
 		if subPool != "" {
228 228
 			if ipr, err = getAddressRange(subPool); err != nil {
229
-				return nil, nil, nil, nil, err
229
+				return nil, nil, nil, err
230 230
 			}
231 231
 		}
232 232
 	} else {
233 233
 		if nw, err = a.getPredefinedPool(addressSpace, v6); err != nil {
234
-			return nil, nil, nil, nil, err
234
+			return nil, nil, nil, err
235 235
 		}
236 236
 
237 237
 	}
238
-	if aw, err = adjustAndCheckSubnetSize(nw); err != nil {
239
-		return nil, nil, nil, nil, err
240
-	}
241 238
 
242
-	return &SubnetKey{AddressSpace: addressSpace, Subnet: nw.String(), ChildSubnet: subPool}, nw, aw, ipr, nil
239
+	return &SubnetKey{AddressSpace: addressSpace, Subnet: nw.String(), ChildSubnet: subPool}, nw, ipr, nil
243 240
 }
244 241
 
245 242
 func (a *Allocator) insertBitMask(key SubnetKey, pool *net.IPNet) error {
... ...
@@ -252,23 +248,27 @@ func (a *Allocator) insertBitMask(key SubnetKey, pool *net.IPNet) error {
252 252
 
253 253
 	ipVer := getAddressVersion(pool.IP)
254 254
 	ones, bits := pool.Mask.Size()
255
-	numAddresses := uint32(1 << uint(bits-ones))
255
+	numAddresses := uint64(1 << uint(bits-ones))
256 256
 
257 257
 	if ipVer == v4 {
258 258
 		// Do not let broadcast address be reserved
259 259
 		numAddresses--
260 260
 	}
261 261
 
262
+	// Allow /64 subnet
263
+	if ipVer == v6 && numAddresses == 0 {
264
+		numAddresses--
265
+	}
266
+
262 267
 	// Generate the new address masks. AddressMask content may come from datastore
263 268
 	h, err := bitseq.NewHandle(dsDataKey, store, key.String(), numAddresses)
264 269
 	if err != nil {
265 270
 		return err
266 271
 	}
267 272
 
268
-	if ipVer == v4 {
269
-		// Do not let network identifier address be reserved
270
-		h.Set(0)
271
-	}
273
+	// Do not let network identifier address be reserved
274
+	// Do the same for IPv6 so that bridge ip starts with XXXX...::1
275
+	h.Set(0)
272 276
 
273 277
 	a.Lock()
274 278
 	a.addresses[key] = h
... ...
@@ -438,6 +438,7 @@ func (a *Allocator) ReleaseAddress(poolID string, address net.IP) error {
438 438
 	if p.Range != nil {
439 439
 		mask = p.Range.Sub.Mask
440 440
 	}
441
+
441 442
 	h, err := types.GetHostPartIP(address, mask)
442 443
 	if err != nil {
443 444
 		return fmt.Errorf("failed to release address %s: %v", address.String(), err)
... ...
@@ -448,12 +449,13 @@ func (a *Allocator) ReleaseAddress(poolID string, address net.IP) error {
448 448
 		return fmt.Errorf("could not find bitmask in datastore for %s on address %v release from pool %s: %v",
449 449
 			k.String(), address, poolID, err)
450 450
 	}
451
-	return bm.Unset(ipToUint32(h))
451
+
452
+	return bm.Unset(ipToUint64(h))
452 453
 }
453 454
 
454 455
 func (a *Allocator) getAddress(nw *net.IPNet, bitmask *bitseq.Handle, prefAddress net.IP, ipr *AddressRange) (net.IP, error) {
455 456
 	var (
456
-		ordinal uint32
457
+		ordinal uint64
457 458
 		err     error
458 459
 		base    *net.IPNet
459 460
 	)
... ...
@@ -470,7 +472,7 @@ func (a *Allocator) getAddress(nw *net.IPNet, bitmask *bitseq.Handle, prefAddres
470 470
 		if e != nil {
471 471
 			return nil, fmt.Errorf("failed to allocate preferred address %s: %v", prefAddress.String(), e)
472 472
 		}
473
-		ordinal = ipToUint32(types.GetMinimalIP(hostPart))
473
+		ordinal = ipToUint64(types.GetMinimalIP(hostPart))
474 474
 		err = bitmask.Set(ordinal)
475 475
 	} else {
476 476
 		base.IP = ipr.Sub.IP
... ...
@@ -66,10 +66,10 @@ func getAllocator() (*Allocator, error) {
66 66
 }
67 67
 
68 68
 func TestInt2IP2IntConversion(t *testing.T) {
69
-	for i := uint32(0); i < 256*256*256; i++ {
69
+	for i := uint64(0); i < 256*256*256; i++ {
70 70
 		var array [4]byte // new array at each cycle
71 71
 		addIntToIP(array[:], i)
72
-		j := ipToUint32(array[:])
72
+		j := ipToUint64(array[:])
73 73
 		if j != i {
74 74
 			t.Fatalf("Failed to convert ordinal %d to IP % x and back to ordinal. Got %d", i, array, j)
75 75
 		}
... ...
@@ -502,31 +502,6 @@ func TestPredefinedPool(t *testing.T) {
502 502
 	}
503 503
 }
504 504
 
505
-func TestAdjustAndCheckSubnet(t *testing.T) {
506
-	_, sub6, _ := net.ParseCIDR("1003:1:2:300::/63")
507
-	_, err := adjustAndCheckSubnetSize(sub6)
508
-	if err == nil {
509
-		t.Fatalf("Failed detect too big v6 subnet")
510
-	}
511
-
512
-	_, sub, _ := net.ParseCIDR("192.0.0.0/7")
513
-	_, err = adjustAndCheckSubnetSize(sub)
514
-	if err == nil {
515
-		t.Fatalf("Failed detect too big v4 subnet")
516
-	}
517
-
518
-	subnet := "1004:1:2:6::/64"
519
-	_, sub6, _ = net.ParseCIDR(subnet)
520
-	subnetToSplit, err := adjustAndCheckSubnetSize(sub6)
521
-	if err != nil {
522
-		t.Fatalf("Unexpected error returned by adjustAndCheckSubnetSize()")
523
-	}
524
-	ones, _ := subnetToSplit.Mask.Size()
525
-	if ones < minNetSizeV6Eff {
526
-		t.Fatalf("Wrong effective network size for %s. Expected: %d. Got: %d", subnet, minNetSizeV6Eff, ones)
527
-	}
528
-}
529
-
530 505
 func TestRemoveSubnet(t *testing.T) {
531 506
 	a, err := getAllocator()
532 507
 	if err != nil {
... ...
@@ -757,7 +732,7 @@ func TestRequestSyntaxCheck(t *testing.T) {
757 757
 
758 758
 	err = a.ReleaseAddress(pid, ip)
759 759
 	if err != nil {
760
-		t.Fatalf("Unexpected failure: %v", err)
760
+		t.Fatalf("Unexpected failure: %v: %s, %s", err, pid, ip)
761 761
 	}
762 762
 }
763 763
 
... ...
@@ -873,7 +848,7 @@ func assertGetAddress(t *testing.T, subnet string) {
873 873
 	zeroes := bits - ones
874 874
 	numAddresses := 1 << uint(zeroes)
875 875
 
876
-	bm, err := bitseq.NewHandle("ipam_test", nil, "default/"+subnet, uint32(numAddresses))
876
+	bm, err := bitseq.NewHandle("ipam_test", nil, "default/"+subnet, uint64(numAddresses))
877 877
 	if err != nil {
878 878
 		t.Fatal(err)
879 879
 	}
... ...
@@ -43,7 +43,7 @@ type addrSpace struct {
43 43
 // identify a range in a a pool of addresses
44 44
 type AddressRange struct {
45 45
 	Sub        *net.IPNet
46
-	Start, End uint32
46
+	Start, End uint64
47 47
 }
48 48
 
49 49
 // String returns the string form of the AddressRange object
... ...
@@ -71,8 +71,8 @@ func (r *AddressRange) UnmarshalJSON(data []byte) error {
71 71
 	if r.Sub, err = types.ParseCIDR(m["Sub"].(string)); err != nil {
72 72
 		return err
73 73
 	}
74
-	r.Start = uint32(m["Start"].(float64))
75
-	r.End = uint32(m["End"].(float64))
74
+	r.Start = uint64(m["Start"].(float64))
75
+	r.End = uint64(m["End"].(float64))
76 76
 	return nil
77 77
 }
78 78
 
... ...
@@ -33,32 +33,12 @@ func getAddressRange(pool string) (*AddressRange, error) {
33 33
 		return nil, fmt.Errorf("failed to compute range's highest ip address: %v", e)
34 34
 	}
35 35
 	nw.IP = ip
36
-	return &AddressRange{nw, ipToUint32(types.GetMinimalIP(lIP)), ipToUint32(types.GetMinimalIP(hIP))}, nil
37
-}
38
-
39
-// Check subnets size. In case configured subnet is v6 and host size is
40
-// greater than 32 bits, adjust subnet to /96.
41
-func adjustAndCheckSubnetSize(subnet *net.IPNet) (*net.IPNet, error) {
42
-	ones, bits := subnet.Mask.Size()
43
-	if v6 == getAddressVersion(subnet.IP) {
44
-		if ones < minNetSizeV6 {
45
-			return nil, ipamapi.ErrInvalidPool
46
-		}
47
-		if ones < minNetSizeV6Eff {
48
-			newMask := net.CIDRMask(minNetSizeV6Eff, bits)
49
-			return &net.IPNet{IP: subnet.IP, Mask: newMask}, nil
50
-		}
51
-	} else {
52
-		if ones < minNetSize {
53
-			return nil, ipamapi.ErrInvalidPool
54
-		}
55
-	}
56
-	return subnet, nil
36
+	return &AddressRange{nw, ipToUint64(types.GetMinimalIP(lIP)), ipToUint64(types.GetMinimalIP(hIP))}, nil
57 37
 }
58 38
 
59 39
 // It generates the ip address in the passed subnet specified by
60 40
 // the passed host address ordinal
61
-func generateAddress(ordinal uint32, network *net.IPNet) net.IP {
41
+func generateAddress(ordinal uint64, network *net.IPNet) net.IP {
62 42
 	var address [16]byte
63 43
 
64 44
 	// Get network portion of IP
... ...
@@ -83,7 +63,7 @@ func getAddressVersion(ip net.IP) ipVersion {
83 83
 
84 84
 // Adds the ordinal IP to the current array
85 85
 // 192.168.0.0 + 53 => 192.168.53
86
-func addIntToIP(array []byte, ordinal uint32) {
86
+func addIntToIP(array []byte, ordinal uint64) {
87 87
 	for i := len(array) - 1; i >= 0; i-- {
88 88
 		array[i] |= (byte)(ordinal & 0xff)
89 89
 		ordinal >>= 8
... ...
@@ -91,11 +71,11 @@ func addIntToIP(array []byte, ordinal uint32) {
91 91
 }
92 92
 
93 93
 // Convert an ordinal to the respective IP address
94
-func ipToUint32(ip []byte) uint32 {
95
-	value := uint32(0)
96
-	for i := 0; i < len(ip); i++ {
97
-		j := len(ip) - 1 - i
98
-		value += uint32(ip[i]) << uint(j*8)
94
+func ipToUint64(ip []byte) (value uint64) {
95
+	cip := types.GetMinimalIP(ip)
96
+	for i := 0; i < len(cip); i++ {
97
+		j := len(cip) - 1 - i
98
+		value += uint64(cip[i]) << uint(j*8)
99 99
 	}
100 100
 	return value
101 101
 }
... ...
@@ -276,7 +276,7 @@ func TestBridge(t *testing.T) {
276 276
 		},
277 277
 	}
278 278
 	ipamV4ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "192.168.100.0/24", Gateway: "192.168.100.1"}}
279
-	ipamV6ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "fe90::/98", Gateway: "fe90::22"}}
279
+	ipamV6ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "fe90::/64", Gateway: "fe90::22"}}
280 280
 
281 281
 	network, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, ipamV4ConfList, ipamV6ConfList)
282 282
 	if err != nil {
... ...
@@ -1641,7 +1641,7 @@ func TestEnableIPv6(t *testing.T) {
1641 1641
 			"BridgeName": "testnetwork",
1642 1642
 		},
1643 1643
 	}
1644
-	ipamV6ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "fe80::/98"}}
1644
+	ipamV6ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "fe80::/64"}}
1645 1645
 
1646 1646
 	n, err := createTestNetwork("bridge", "testnetwork", netOption, nil, ipamV6ConfList)
1647 1647
 	if err != nil {