Przeglądaj źródła

Merge pull request #11689 from calavera/ipallocator_refactor

Use a structure to keep the allocated ips pool.
Alexander Morozov 10 lat temu
rodzic
commit
f7900cdd67

+ 8 - 7
daemon/networkdriver/bridge/driver.go

@@ -80,6 +80,7 @@ var (
 
 	defaultBindingIP  = net.ParseIP("0.0.0.0")
 	currentInterfaces = ifaces{c: make(map[string]*networkInterface)}
+	ipAllocator       = ipallocator.New()
 )
 
 func InitDriver(job *engine.Job) engine.Status {
@@ -244,7 +245,7 @@ func InitDriver(job *engine.Job) engine.Status {
 			return job.Error(err)
 		}
 		log.Debugf("Subnet: %v", subnet)
-		if err := ipallocator.RegisterSubnet(bridgeIPv4Network, subnet); err != nil {
+		if err := ipAllocator.RegisterSubnet(bridgeIPv4Network, subnet); err != nil {
 			return job.Error(err)
 		}
 	}
@@ -255,14 +256,14 @@ func InitDriver(job *engine.Job) engine.Status {
 			return job.Error(err)
 		}
 		log.Debugf("Subnet: %v", subnet)
-		if err := ipallocator.RegisterSubnet(subnet, subnet); err != nil {
+		if err := ipAllocator.RegisterSubnet(subnet, subnet); err != nil {
 			return job.Error(err)
 		}
 		globalIPv6Network = subnet
 	}
 
 	// Block BridgeIP in IP allocator
-	ipallocator.RequestIP(bridgeIPv4Network, bridgeIPv4Network.IP)
+	ipAllocator.RequestIP(bridgeIPv4Network, bridgeIPv4Network.IP)
 
 	// https://github.com/docker/docker/issues/2768
 	job.Eng.Hack_SetGlobalVar("httpapi.bridgeIP", bridgeIPv4Network.IP)
@@ -509,7 +510,7 @@ func Allocate(job *engine.Job) engine.Status {
 		globalIPv6    net.IP
 	)
 
-	ip, err = ipallocator.RequestIP(bridgeIPv4Network, requestedIP)
+	ip, err = ipAllocator.RequestIP(bridgeIPv4Network, requestedIP)
 	if err != nil {
 		return job.Error(err)
 	}
@@ -530,7 +531,7 @@ func Allocate(job *engine.Job) engine.Status {
 			}
 		}
 
-		globalIPv6, err = ipallocator.RequestIP(globalIPv6Network, requestedIPv6)
+		globalIPv6, err = ipAllocator.RequestIP(globalIPv6Network, requestedIPv6)
 		if err != nil {
 			log.Errorf("Allocator: RequestIP v6: %v", err)
 			return job.Error(err)
@@ -591,11 +592,11 @@ func Release(job *engine.Job) engine.Status {
 		}
 	}
 
-	if err := ipallocator.ReleaseIP(bridgeIPv4Network, containerInterface.IP); err != nil {
+	if err := ipAllocator.ReleaseIP(bridgeIPv4Network, containerInterface.IP); err != nil {
 		log.Infof("Unable to release IPv4 %s", err)
 	}
 	if globalIPv6Network != nil {
-		if err := ipallocator.ReleaseIP(globalIPv6Network, containerInterface.IPv6); err != nil {
+		if err := ipAllocator.ReleaseIP(globalIPv6Network, containerInterface.IPv6); err != nil {
 			log.Infof("Unable to release IPv6 %s", err)
 		}
 	}

+ 25 - 18
daemon/networkdriver/ipallocator/allocator.go

@@ -41,19 +41,24 @@ var (
 	ErrBadSubnet                = errors.New("network does not contain specified subnet")
 )
 
-var (
-	lock         = sync.Mutex{}
-	allocatedIPs = networkSet{}
-)
+type IPAllocator struct {
+	allocatedIPs networkSet
+	mutex        sync.Mutex
+}
+
+func New() *IPAllocator {
+	return &IPAllocator{networkSet{}, sync.Mutex{}}
+}
 
 // RegisterSubnet registers network in global allocator with bounds
 // defined by subnet. If you want to use network range you must call
 // this method before first RequestIP, otherwise full network range will be used
-func RegisterSubnet(network *net.IPNet, subnet *net.IPNet) error {
-	lock.Lock()
-	defer lock.Unlock()
+func (a *IPAllocator) RegisterSubnet(network *net.IPNet, subnet *net.IPNet) error {
+	a.mutex.Lock()
+	defer a.mutex.Unlock()
+
 	key := network.String()
-	if _, ok := allocatedIPs[key]; ok {
+	if _, ok := a.allocatedIPs[key]; ok {
 		return ErrNetworkAlreadyRegistered
 	}
 	n := newAllocatedMap(network)
@@ -68,7 +73,7 @@ func RegisterSubnet(network *net.IPNet, subnet *net.IPNet) error {
 	n.begin.Set(begin)
 	n.end.Set(end)
 	n.last.Sub(begin, big.NewInt(1))
-	allocatedIPs[key] = n
+	a.allocatedIPs[key] = n
 	return nil
 }
 
@@ -76,14 +81,15 @@ func RegisterSubnet(network *net.IPNet, subnet *net.IPNet) error {
 // will return the next available ip if the ip provided is nil.  If the
 // ip provided is not nil it will validate that the provided ip is available
 // for use or return an error
-func RequestIP(network *net.IPNet, ip net.IP) (net.IP, error) {
-	lock.Lock()
-	defer lock.Unlock()
+func (a *IPAllocator) RequestIP(network *net.IPNet, ip net.IP) (net.IP, error) {
+	a.mutex.Lock()
+	defer a.mutex.Unlock()
+
 	key := network.String()
-	allocated, ok := allocatedIPs[key]
+	allocated, ok := a.allocatedIPs[key]
 	if !ok {
 		allocated = newAllocatedMap(network)
-		allocatedIPs[key] = allocated
+		a.allocatedIPs[key] = allocated
 	}
 
 	if ip == nil {
@@ -94,10 +100,11 @@ func RequestIP(network *net.IPNet, ip net.IP) (net.IP, error) {
 
 // ReleaseIP adds the provided ip back into the pool of
 // available ips to be returned for use.
-func ReleaseIP(network *net.IPNet, ip net.IP) error {
-	lock.Lock()
-	defer lock.Unlock()
-	if allocated, exists := allocatedIPs[network.String()]; exists {
+func (a *IPAllocator) ReleaseIP(network *net.IPNet, ip net.IP) error {
+	a.mutex.Lock()
+	defer a.mutex.Unlock()
+
+	if allocated, exists := a.allocatedIPs[network.String()]; exists {
 		delete(allocated.p, ip.String())
 	}
 	return nil

+ 95 - 86
daemon/networkdriver/ipallocator/allocator_test.go

@@ -7,10 +7,6 @@ import (
 	"testing"
 )
 
-func reset() {
-	allocatedIPs = networkSet{}
-}
-
 func TestConversion(t *testing.T) {
 	ip := net.ParseIP("127.0.0.1")
 	i := ipToBigInt(ip)
@@ -52,7 +48,8 @@ func TestConversionIPv6(t *testing.T) {
 }
 
 func TestRequestNewIps(t *testing.T) {
-	defer reset()
+	a := New()
+
 	network := &net.IPNet{
 		IP:   []byte{192, 168, 0, 1},
 		Mask: []byte{255, 255, 255, 0},
@@ -62,7 +59,7 @@ func TestRequestNewIps(t *testing.T) {
 	var err error
 
 	for i := 1; i < 10; i++ {
-		ip, err = RequestIP(network, nil)
+		ip, err = a.RequestIP(network, nil)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -72,10 +69,10 @@ func TestRequestNewIps(t *testing.T) {
 		}
 	}
 	value := bigIntToIP(big.NewInt(0).Add(ipToBigInt(ip), big.NewInt(1))).String()
-	if err := ReleaseIP(network, ip); err != nil {
+	if err := a.ReleaseIP(network, ip); err != nil {
 		t.Fatal(err)
 	}
-	ip, err = RequestIP(network, nil)
+	ip, err = a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -85,7 +82,8 @@ func TestRequestNewIps(t *testing.T) {
 }
 
 func TestRequestNewIpV6(t *testing.T) {
-	defer reset()
+	a := New()
+
 	network := &net.IPNet{
 		IP:   []byte{0x2a, 0x00, 0x14, 0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
 		Mask: []byte{255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0}, // /64 netmask
@@ -94,7 +92,7 @@ func TestRequestNewIpV6(t *testing.T) {
 	var ip net.IP
 	var err error
 	for i := 1; i < 10; i++ {
-		ip, err = RequestIP(network, nil)
+		ip, err = a.RequestIP(network, nil)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -104,10 +102,10 @@ func TestRequestNewIpV6(t *testing.T) {
 		}
 	}
 	value := bigIntToIP(big.NewInt(0).Add(ipToBigInt(ip), big.NewInt(1))).String()
-	if err := ReleaseIP(network, ip); err != nil {
+	if err := a.ReleaseIP(network, ip); err != nil {
 		t.Fatal(err)
 	}
-	ip, err = RequestIP(network, nil)
+	ip, err = a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -117,68 +115,70 @@ func TestRequestNewIpV6(t *testing.T) {
 }
 
 func TestReleaseIp(t *testing.T) {
-	defer reset()
+	a := New()
+
 	network := &net.IPNet{
 		IP:   []byte{192, 168, 0, 1},
 		Mask: []byte{255, 255, 255, 0},
 	}
 
-	ip, err := RequestIP(network, nil)
+	ip, err := a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if err := ReleaseIP(network, ip); err != nil {
+	if err := a.ReleaseIP(network, ip); err != nil {
 		t.Fatal(err)
 	}
 }
 
 func TestReleaseIpV6(t *testing.T) {
-	defer reset()
+	a := New()
+
 	network := &net.IPNet{
 		IP:   []byte{0x2a, 0x00, 0x14, 0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
 		Mask: []byte{255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0}, // /64 netmask
 	}
 
-	ip, err := RequestIP(network, nil)
+	ip, err := a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if err := ReleaseIP(network, ip); err != nil {
+	if err := a.ReleaseIP(network, ip); err != nil {
 		t.Fatal(err)
 	}
 }
 
 func TestGetReleasedIp(t *testing.T) {
-	defer reset()
+	a := New()
 	network := &net.IPNet{
 		IP:   []byte{192, 168, 0, 1},
 		Mask: []byte{255, 255, 255, 0},
 	}
 
-	ip, err := RequestIP(network, nil)
+	ip, err := a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
 
 	value := ip.String()
-	if err := ReleaseIP(network, ip); err != nil {
+	if err := a.ReleaseIP(network, ip); err != nil {
 		t.Fatal(err)
 	}
 
 	for i := 0; i < 253; i++ {
-		_, err = RequestIP(network, nil)
+		_, err = a.RequestIP(network, nil)
 		if err != nil {
 			t.Fatal(err)
 		}
-		err = ReleaseIP(network, ip)
+		err = a.ReleaseIP(network, ip)
 		if err != nil {
 			t.Fatal(err)
 		}
 	}
 
-	ip, err = RequestIP(network, nil)
+	ip, err = a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -189,34 +189,35 @@ func TestGetReleasedIp(t *testing.T) {
 }
 
 func TestGetReleasedIpV6(t *testing.T) {
-	defer reset()
+	a := New()
+
 	network := &net.IPNet{
 		IP:   []byte{0x2a, 0x00, 0x14, 0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
 		Mask: []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0},
 	}
 
-	ip, err := RequestIP(network, nil)
+	ip, err := a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
 
 	value := ip.String()
-	if err := ReleaseIP(network, ip); err != nil {
+	if err := a.ReleaseIP(network, ip); err != nil {
 		t.Fatal(err)
 	}
 
 	for i := 0; i < 253; i++ {
-		_, err = RequestIP(network, nil)
+		_, err = a.RequestIP(network, nil)
 		if err != nil {
 			t.Fatal(err)
 		}
-		err = ReleaseIP(network, ip)
+		err = a.ReleaseIP(network, ip)
 		if err != nil {
 			t.Fatal(err)
 		}
 	}
 
-	ip, err = RequestIP(network, nil)
+	ip, err = a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -227,7 +228,8 @@ func TestGetReleasedIpV6(t *testing.T) {
 }
 
 func TestRequestSpecificIp(t *testing.T) {
-	defer reset()
+	a := New()
+
 	network := &net.IPNet{
 		IP:   []byte{192, 168, 0, 1},
 		Mask: []byte{255, 255, 255, 224},
@@ -236,23 +238,24 @@ func TestRequestSpecificIp(t *testing.T) {
 	ip := net.ParseIP("192.168.0.5")
 
 	// Request a "good" IP.
-	if _, err := RequestIP(network, ip); err != nil {
+	if _, err := a.RequestIP(network, ip); err != nil {
 		t.Fatal(err)
 	}
 
 	// Request the same IP again.
-	if _, err := RequestIP(network, ip); err != ErrIPAlreadyAllocated {
+	if _, err := a.RequestIP(network, ip); err != ErrIPAlreadyAllocated {
 		t.Fatalf("Got the same IP twice: %#v", err)
 	}
 
 	// Request an out of range IP.
-	if _, err := RequestIP(network, net.ParseIP("192.168.0.42")); err != ErrIPOutOfRange {
+	if _, err := a.RequestIP(network, net.ParseIP("192.168.0.42")); err != ErrIPOutOfRange {
 		t.Fatalf("Got an out of range IP: %#v", err)
 	}
 }
 
 func TestRequestSpecificIpV6(t *testing.T) {
-	defer reset()
+	a := New()
+
 	network := &net.IPNet{
 		IP:   []byte{0x2a, 0x00, 0x14, 0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
 		Mask: []byte{255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0}, // /64 netmask
@@ -261,22 +264,24 @@ func TestRequestSpecificIpV6(t *testing.T) {
 	ip := net.ParseIP("2a00:1450::5")
 
 	// Request a "good" IP.
-	if _, err := RequestIP(network, ip); err != nil {
+	if _, err := a.RequestIP(network, ip); err != nil {
 		t.Fatal(err)
 	}
 
 	// Request the same IP again.
-	if _, err := RequestIP(network, ip); err != ErrIPAlreadyAllocated {
+	if _, err := a.RequestIP(network, ip); err != ErrIPAlreadyAllocated {
 		t.Fatalf("Got the same IP twice: %#v", err)
 	}
 
 	// Request an out of range IP.
-	if _, err := RequestIP(network, net.ParseIP("2a00:1500::1")); err != ErrIPOutOfRange {
+	if _, err := a.RequestIP(network, net.ParseIP("2a00:1500::1")); err != ErrIPOutOfRange {
 		t.Fatalf("Got an out of range IP: %#v", err)
 	}
 }
 
 func TestIPAllocator(t *testing.T) {
+	a := New()
+
 	expectedIPs := []net.IP{
 		0: net.IPv4(127, 0, 0, 1),
 		1: net.IPv4(127, 0, 0, 2),
@@ -296,7 +301,7 @@ func TestIPAllocator(t *testing.T) {
 	// Check that we get 6 IPs, from 127.0.0.1–127.0.0.6, in that
 	// order.
 	for i := 0; i < 6; i++ {
-		ip, err := RequestIP(network, nil)
+		ip, err := a.RequestIP(network, nil)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -332,25 +337,25 @@ func TestIPAllocator(t *testing.T) {
 	//  ↑
 
 	// Check that there are no more IPs
-	ip, err := RequestIP(network, nil)
+	ip, err := a.RequestIP(network, nil)
 	if err == nil {
 		t.Fatalf("There shouldn't be any IP addresses at this point, got %s\n", ip)
 	}
 
 	// Release some IPs in non-sequential order
-	if err := ReleaseIP(network, expectedIPs[3]); err != nil {
+	if err := a.ReleaseIP(network, expectedIPs[3]); err != nil {
 		t.Fatal(err)
 	}
 	// 1(u) - 2(u) - 3(u) - 4(f) - 5(u) - 6(u)
 	//                       ↑
 
-	if err := ReleaseIP(network, expectedIPs[2]); err != nil {
+	if err := a.ReleaseIP(network, expectedIPs[2]); err != nil {
 		t.Fatal(err)
 	}
 	// 1(u) - 2(u) - 3(f) - 4(f) - 5(u) - 6(u)
 	//                ↑
 
-	if err := ReleaseIP(network, expectedIPs[4]); err != nil {
+	if err := a.ReleaseIP(network, expectedIPs[4]); err != nil {
 		t.Fatal(err)
 	}
 	// 1(u) - 2(u) - 3(f) - 4(f) - 5(f) - 6(u)
@@ -360,7 +365,7 @@ func TestIPAllocator(t *testing.T) {
 	// with the first released IP
 	newIPs := make([]net.IP, 3)
 	for i := 0; i < 3; i++ {
-		ip, err := RequestIP(network, nil)
+		ip, err := a.RequestIP(network, nil)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -371,14 +376,15 @@ func TestIPAllocator(t *testing.T) {
 	assertIPEquals(t, expectedIPs[3], newIPs[1])
 	assertIPEquals(t, expectedIPs[4], newIPs[2])
 
-	_, err = RequestIP(network, nil)
+	_, err = a.RequestIP(network, nil)
 	if err == nil {
 		t.Fatal("There shouldn't be any IP addresses at this point")
 	}
 }
 
 func TestAllocateFirstIP(t *testing.T) {
-	defer reset()
+	a := New()
+
 	network := &net.IPNet{
 		IP:   []byte{192, 168, 0, 0},
 		Mask: []byte{255, 255, 255, 0},
@@ -387,7 +393,7 @@ func TestAllocateFirstIP(t *testing.T) {
 	firstIP := network.IP.To4().Mask(network.Mask)
 	first := big.NewInt(0).Add(ipToBigInt(firstIP), big.NewInt(1))
 
-	ip, err := RequestIP(network, nil)
+	ip, err := a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -399,7 +405,8 @@ func TestAllocateFirstIP(t *testing.T) {
 }
 
 func TestAllocateAllIps(t *testing.T) {
-	defer reset()
+	a := New()
+
 	network := &net.IPNet{
 		IP:   []byte{192, 168, 0, 1},
 		Mask: []byte{255, 255, 255, 0},
@@ -412,7 +419,7 @@ func TestAllocateAllIps(t *testing.T) {
 	)
 
 	for err == nil {
-		current, err = RequestIP(network, nil)
+		current, err = a.RequestIP(network, nil)
 		if isFirst {
 			first = current
 			isFirst = false
@@ -423,15 +430,15 @@ func TestAllocateAllIps(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if _, err := RequestIP(network, nil); err != ErrNoAvailableIPs {
+	if _, err := a.RequestIP(network, nil); err != ErrNoAvailableIPs {
 		t.Fatal(err)
 	}
 
-	if err := ReleaseIP(network, first); err != nil {
+	if err := a.ReleaseIP(network, first); err != nil {
 		t.Fatal(err)
 	}
 
-	again, err := RequestIP(network, nil)
+	again, err := a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -439,17 +446,17 @@ func TestAllocateAllIps(t *testing.T) {
 	assertIPEquals(t, first, again)
 
 	// ensure that alloc.last == alloc.begin won't result in dead loop
-	if _, err := RequestIP(network, nil); err != ErrNoAvailableIPs {
+	if _, err := a.RequestIP(network, nil); err != ErrNoAvailableIPs {
 		t.Fatal(err)
 	}
 
 	// Test by making alloc.last the only free ip and ensure we get it back
 	// #1. first of the range, (alloc.last == ipToInt(first) already)
-	if err := ReleaseIP(network, first); err != nil {
+	if err := a.ReleaseIP(network, first); err != nil {
 		t.Fatal(err)
 	}
 
-	ret, err := RequestIP(network, nil)
+	ret, err := a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -458,9 +465,9 @@ func TestAllocateAllIps(t *testing.T) {
 
 	// #2. last of the range, note that current is the last one
 	last := net.IPv4(192, 168, 0, 254)
-	setLastTo(t, network, last)
+	setLastTo(t, a, network, last)
 
-	ret, err = RequestIP(network, nil)
+	ret, err = a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -469,9 +476,9 @@ func TestAllocateAllIps(t *testing.T) {
 
 	// #3. middle of the range
 	mid := net.IPv4(192, 168, 0, 7)
-	setLastTo(t, network, mid)
+	setLastTo(t, a, network, mid)
 
-	ret, err = RequestIP(network, nil)
+	ret, err = a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -481,25 +488,25 @@ func TestAllocateAllIps(t *testing.T) {
 
 // make sure the pool is full when calling setLastTo.
 // we don't cheat here
-func setLastTo(t *testing.T, network *net.IPNet, ip net.IP) {
-	if err := ReleaseIP(network, ip); err != nil {
+func setLastTo(t *testing.T, a *IPAllocator, network *net.IPNet, ip net.IP) {
+	if err := a.ReleaseIP(network, ip); err != nil {
 		t.Fatal(err)
 	}
 
-	ret, err := RequestIP(network, nil)
+	ret, err := a.RequestIP(network, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
 
 	assertIPEquals(t, ip, ret)
 
-	if err := ReleaseIP(network, ip); err != nil {
+	if err := a.ReleaseIP(network, ip); err != nil {
 		t.Fatal(err)
 	}
 }
 
 func TestAllocateDifferentSubnets(t *testing.T) {
-	defer reset()
+	a := New()
 	network1 := &net.IPNet{
 		IP:   []byte{192, 168, 0, 1},
 		Mask: []byte{255, 255, 255, 0},
@@ -528,39 +535,39 @@ func TestAllocateDifferentSubnets(t *testing.T) {
 		8: net.ParseIP("2a00:1632::2"),
 	}
 
-	ip11, err := RequestIP(network1, nil)
+	ip11, err := a.RequestIP(network1, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
-	ip12, err := RequestIP(network1, nil)
+	ip12, err := a.RequestIP(network1, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
-	ip21, err := RequestIP(network2, nil)
+	ip21, err := a.RequestIP(network2, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
-	ip22, err := RequestIP(network2, nil)
+	ip22, err := a.RequestIP(network2, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
-	ip31, err := RequestIP(network3, nil)
+	ip31, err := a.RequestIP(network3, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
-	ip32, err := RequestIP(network3, nil)
+	ip32, err := a.RequestIP(network3, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
-	ip33, err := RequestIP(network3, nil)
+	ip33, err := a.RequestIP(network3, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
-	ip41, err := RequestIP(network4, nil)
+	ip41, err := a.RequestIP(network4, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
-	ip42, err := RequestIP(network4, nil)
+	ip42, err := a.RequestIP(network4, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -576,7 +583,7 @@ func TestAllocateDifferentSubnets(t *testing.T) {
 }
 
 func TestRegisterBadTwice(t *testing.T) {
-	defer reset()
+	a := New()
 	network := &net.IPNet{
 		IP:   []byte{192, 168, 1, 1},
 		Mask: []byte{255, 255, 255, 0},
@@ -586,20 +593,20 @@ func TestRegisterBadTwice(t *testing.T) {
 		Mask: []byte{255, 255, 255, 248},
 	}
 
-	if err := RegisterSubnet(network, subnet); err != nil {
+	if err := a.RegisterSubnet(network, subnet); err != nil {
 		t.Fatal(err)
 	}
 	subnet = &net.IPNet{
 		IP:   []byte{192, 168, 1, 16},
 		Mask: []byte{255, 255, 255, 248},
 	}
-	if err := RegisterSubnet(network, subnet); err != ErrNetworkAlreadyRegistered {
+	if err := a.RegisterSubnet(network, subnet); err != ErrNetworkAlreadyRegistered {
 		t.Fatalf("Expecteded ErrNetworkAlreadyRegistered error, got %v", err)
 	}
 }
 
 func TestRegisterBadRange(t *testing.T) {
-	defer reset()
+	a := New()
 	network := &net.IPNet{
 		IP:   []byte{192, 168, 1, 1},
 		Mask: []byte{255, 255, 255, 0},
@@ -608,13 +615,13 @@ func TestRegisterBadRange(t *testing.T) {
 		IP:   []byte{192, 168, 1, 1},
 		Mask: []byte{255, 255, 0, 0},
 	}
-	if err := RegisterSubnet(network, subnet); err != ErrBadSubnet {
+	if err := a.RegisterSubnet(network, subnet); err != ErrBadSubnet {
 		t.Fatalf("Expected ErrBadSubnet error, got %v", err)
 	}
 }
 
 func TestAllocateFromRange(t *testing.T) {
-	defer reset()
+	a := New()
 	network := &net.IPNet{
 		IP:   []byte{192, 168, 0, 1},
 		Mask: []byte{255, 255, 255, 0},
@@ -625,7 +632,7 @@ func TestAllocateFromRange(t *testing.T) {
 		Mask: []byte{255, 255, 255, 248},
 	}
 
-	if err := RegisterSubnet(network, subnet); err != nil {
+	if err := a.RegisterSubnet(network, subnet); err != nil {
 		t.Fatal(err)
 	}
 	expectedIPs := []net.IP{
@@ -637,19 +644,19 @@ func TestAllocateFromRange(t *testing.T) {
 		5: net.IPv4(192, 168, 0, 14),
 	}
 	for _, ip := range expectedIPs {
-		rip, err := RequestIP(network, nil)
+		rip, err := a.RequestIP(network, nil)
 		if err != nil {
 			t.Fatal(err)
 		}
 		assertIPEquals(t, ip, rip)
 	}
 
-	if _, err := RequestIP(network, nil); err != ErrNoAvailableIPs {
+	if _, err := a.RequestIP(network, nil); err != ErrNoAvailableIPs {
 		t.Fatalf("Expected ErrNoAvailableIPs error, got %v", err)
 	}
 	for _, ip := range expectedIPs {
-		ReleaseIP(network, ip)
-		rip, err := RequestIP(network, nil)
+		a.ReleaseIP(network, ip)
+		rip, err := a.RequestIP(network, nil)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -669,13 +676,15 @@ func BenchmarkRequestIP(b *testing.B) {
 		Mask: []byte{255, 255, 255, 0},
 	}
 	b.ResetTimer()
+
 	for i := 0; i < b.N; i++ {
+		a := New()
+
 		for j := 0; j < 253; j++ {
-			_, err := RequestIP(network, nil)
+			_, err := a.RequestIP(network, nil)
 			if err != nil {
 				b.Fatal(err)
 			}
 		}
-		reset()
 	}
 }