From 14b21d5d880da70370bea9b9be14d375138def76 Mon Sep 17 00:00:00 2001 From: Alessandro Boch Date: Sun, 8 Nov 2015 11:18:10 -0800 Subject: [PATCH] Fix bug in getAddressRange() in default ipam driver - Callers expect to work with offsets based on master pool Signed-off-by: Alessandro Boch --- libnetwork/ipam/allocator.go | 6 +--- libnetwork/ipam/allocator_test.go | 53 +++++++++++++++++++++++++++++++ libnetwork/ipam/utils.go | 6 ++-- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/libnetwork/ipam/allocator.go b/libnetwork/ipam/allocator.go index bec7c75343..f90c7c1805 100644 --- a/libnetwork/ipam/allocator.go +++ b/libnetwork/ipam/allocator.go @@ -220,7 +220,7 @@ func (a *Allocator) parsePoolRequest(addressSpace, pool, subPool string, v6 bool return nil, nil, nil, ipamapi.ErrInvalidPool } if subPool != "" { - if ipr, err = getAddressRange(subPool); err != nil { + if ipr, err = getAddressRange(subPool, nw); err != nil { return nil, nil, nil, err } } @@ -431,9 +431,6 @@ func (a *Allocator) ReleaseAddress(poolID string, address net.IP) error { aSpace.Unlock() mask := p.Pool.Mask - if p.Range != nil { - mask = p.Range.Sub.Mask - } h, err := types.GetHostPartIP(address, mask) if err != nil { @@ -471,7 +468,6 @@ func (a *Allocator) getAddress(nw *net.IPNet, bitmask *bitseq.Handle, prefAddres ordinal = ipToUint64(types.GetMinimalIP(hostPart)) err = bitmask.Set(ordinal) } else { - base.IP = ipr.Sub.IP ordinal, err = bitmask.SetAnyInRange(ipr.Start, ipr.End) } if err != nil { diff --git a/libnetwork/ipam/allocator_test.go b/libnetwork/ipam/allocator_test.go index 0b0242df27..30c0475cb7 100644 --- a/libnetwork/ipam/allocator_test.go +++ b/libnetwork/ipam/allocator_test.go @@ -666,6 +666,59 @@ func TestRequestReleaseAddressFromSubPool(t *testing.T) { if !types.CompareIPNet(rp, ip) { t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip) } + + // Request any addresses from subpool after explicit address request + unoExp, _ := types.ParseCIDR("10.2.2.0/16") + dueExp, _ := types.ParseCIDR("10.2.2.2/16") + treExp, _ := types.ParseCIDR("10.2.2.1/16") + if poolID, _, _, err = a.RequestPool("rosso", "10.2.0.0/16", "10.2.2.0/24", nil, false); err != nil { + t.Fatal(err) + } + tre, _, err := a.RequestAddress(poolID, treExp.IP, nil) + if err != nil { + t.Fatal(err) + } + if !types.CompareIPNet(tre, treExp) { + t.Fatalf("Unexpected address: %v", tre) + } + + uno, _, err := a.RequestAddress(poolID, nil, nil) + if err != nil { + t.Fatal(err) + } + if !types.CompareIPNet(uno, unoExp) { + t.Fatalf("Unexpected address: %v", uno) + } + + due, _, err := a.RequestAddress(poolID, nil, nil) + if err != nil { + t.Fatal(err) + } + if !types.CompareIPNet(due, dueExp) { + t.Fatalf("Unexpected address: %v", due) + } + + if err = a.ReleaseAddress(poolID, uno.IP); err != nil { + t.Fatal(err) + } + uno, _, err = a.RequestAddress(poolID, nil, nil) + if err != nil { + t.Fatal(err) + } + if !types.CompareIPNet(uno, unoExp) { + t.Fatalf("Unexpected address: %v", uno) + } + + if err = a.ReleaseAddress(poolID, tre.IP); err != nil { + t.Fatal(err) + } + tre, _, err = a.RequestAddress(poolID, nil, nil) + if err != nil { + t.Fatal(err) + } + if !types.CompareIPNet(tre, treExp) { + t.Fatalf("Unexpected address: %v", tre) + } } func TestGetAddress(t *testing.T) { diff --git a/libnetwork/ipam/utils.go b/libnetwork/ipam/utils.go index 2d9c6b17bf..d524b47830 100644 --- a/libnetwork/ipam/utils.go +++ b/libnetwork/ipam/utils.go @@ -15,12 +15,12 @@ const ( v6 = 6 ) -func getAddressRange(pool string) (*AddressRange, error) { +func getAddressRange(pool string, masterNw *net.IPNet) (*AddressRange, error) { ip, nw, err := net.ParseCIDR(pool) if err != nil { return nil, ipamapi.ErrInvalidSubPool } - lIP, e := types.GetHostPartIP(nw.IP, nw.Mask) + lIP, e := types.GetHostPartIP(nw.IP, masterNw.Mask) if e != nil { return nil, fmt.Errorf("failed to compute range's lowest ip address: %v", e) } @@ -28,7 +28,7 @@ func getAddressRange(pool string) (*AddressRange, error) { if e != nil { return nil, fmt.Errorf("failed to compute range's broadcast ip address: %v", e) } - hIP, e := types.GetHostPartIP(bIP, nw.Mask) + hIP, e := types.GetHostPartIP(bIP, masterNw.Mask) if e != nil { return nil, fmt.Errorf("failed to compute range's highest ip address: %v", e) }