- Allow bitsequence of length 2^64-1
- Updated ID Manager and IPAM
Signed-off-by: Alessandro Boch <aboch@docker.com>
| ... | ... |
@@ -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 {
|