Просмотр исходного кода

plugins/allocators: Rename fixedsize to bitmap

Allocators themselves are implementation details for now; bitmap
reflects better the properties of this allocator

Signed-off-by: Anatole Denis <anatole@unverle.fr>
Anatole Denis 5 лет назад
Родитель
Сommit
fb0d278233

+ 3 - 0
go.sum

@@ -241,6 +241,7 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
 golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw=
 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@@ -254,6 +255,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
 golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.0 h1:sfUMP1Gu8qASkorDVjnMuvgJzwFbTZSeXFiGBYAVdl4=
 golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -307,6 +309,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
 golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=

+ 0 - 0
plugins/prefix/allocators/allocator.go → plugins/allocators/allocator.go


+ 6 - 9
plugins/prefix/allocators/fixedsize/fixedsize.go → plugins/allocators/bitmap/bitmap.go

@@ -8,7 +8,7 @@
 // range is much larger than the expected number of clients. Also is what KEA
 // does so at least it's not worse than that
 
-package fixedsize
+package bitmap
 
 import (
 	"errors"
@@ -19,10 +19,10 @@ import (
 	"github.com/willf/bitset"
 
 	"github.com/coredhcp/coredhcp/logger"
-	"github.com/coredhcp/coredhcp/plugins/prefix/allocators"
+	"github.com/coredhcp/coredhcp/plugins/allocators"
 )
 
-var log = logger.GetLogger("plugins/prefix/allocator")
+var log = logger.GetLogger("plugins/allocators/bitmap")
 
 // Allocator is a prefix allocator allocating in chunks of a fixed size
 // regardless of the size requested by the client.
@@ -33,9 +33,6 @@ type Allocator struct {
 	bitmap     *bitset.BitSet
 }
 
-type block struct {
-}
-
 // prefix must verify: containing.Mask.Size < prefix.Mask.Size < page
 func (a *Allocator) toIndex(base net.IP) (uint, error) {
 	value, err := allocators.Offset(base, a.containing.IP, a.page)
@@ -101,9 +98,9 @@ func (a *Allocator) Free(prefix net.IPNet) error {
 	return nil
 }
 
-// NewFixedSizeAllocator creates a new allocator, allocating /`size` prefixes
+// NewBitmapAllocator creates a new allocator, allocating /`size` prefixes
 // carved out of the given `pool` prefix
-func NewFixedSizeAllocator(pool net.IPNet, size int) (*Allocator, error) {
+func NewBitmapAllocator(pool net.IPNet, size int) (*Allocator, error) {
 
 	poolSize, _ := pool.Mask.Size()
 	allocOrder := size - poolSize
@@ -117,7 +114,7 @@ func NewFixedSizeAllocator(pool net.IPNet, size int) (*Allocator, error) {
 	}
 
 	if !(1<<uint(allocOrder) <= bitset.Cap()) {
-		return nil, errors.New("Can't fit this pool using the fixedsize allocator")
+		return nil, errors.New("Can't fit this pool using the bitmap allocator")
 	}
 
 	alloc := Allocator{

+ 7 - 4
plugins/prefix/allocators/fixedsize/fixedsize_test.go → plugins/allocators/bitmap/bitmap_test.go

@@ -2,7 +2,7 @@
 // This source code is licensed under the MIT license found in the
 // LICENSE file in the root directory of this source tree.
 
-package fixedsize
+package bitmap
 
 import (
 	"net"
@@ -14,7 +14,7 @@ func getAllocator() *Allocator {
 	if err != nil {
 		panic(err)
 	}
-	alloc, err := NewFixedSizeAllocator(*prefix, 64)
+	alloc, err := NewBitmapAllocator(*prefix, 64)
 	if err != nil {
 		panic(err)
 	}
@@ -42,7 +42,7 @@ func TestAlloc(t *testing.T) {
 
 func TestExhaust(t *testing.T) {
 	_, prefix, _ := net.ParseCIDR("2001:db8::/62")
-	alloc, _ := NewFixedSizeAllocator(*prefix, 64)
+	alloc, _ := NewBitmapAllocator(*prefix, 64)
 
 	allocd := []net.IPNet{}
 	for i := 0; i < 4; i++ {
@@ -58,7 +58,10 @@ func TestExhaust(t *testing.T) {
 		t.Fatalf("Successfully allocated more prefixes than there are in the pool")
 	}
 
-	alloc.Free(allocd[1])
+	err = alloc.Free(allocd[1])
+	if err != nil {
+		t.Fatalf("Could not free: %v", err)
+	}
 	net, err := alloc.Allocate(allocd[1])
 	if err != nil {
 		t.Fatalf("Could not reallocate after free: %v", err)

+ 6 - 0
plugins/prefix/allocators/ipcalc.go → plugins/allocators/ipcalc.go

@@ -92,8 +92,14 @@ func AddPrefixes(ip net.IP, n, unit uint64) (net.IP, error) {
 	} else if n == 0 {
 		return ip, nil
 	}
+	if len(ip) != 16 {
+		// We don't actually care if they're true v6 or v4-mapped,
+		// but they need to be 128-bit to handle as 64-bit ints
+		return net.IP{}, errors.New("AddPrefixes needs 128-bit IPs")
+	}
 
 	// Compute as pairs of uint64 for easier operations
+	// This could all be 1 function call if go had 128-bit integers
 	iph, ipl := binary.BigEndian.Uint64(ip[:8]), binary.BigEndian.Uint64(ip[8:])
 
 	// Compute `n` /`unit` subnets as uint64 pair

+ 27 - 0
plugins/prefix/allocators/ipcalc_test.go → plugins/allocators/ipcalc_test.go

@@ -7,6 +7,9 @@ package allocators
 import (
 	"fmt"
 	"net"
+	"testing"
+
+	"math/rand"
 )
 
 func ExampleOffset() {
@@ -39,10 +42,34 @@ func ExampleAddPrefixes() {
 	fmt.Println(AddPrefixes(net.ParseIP("2001:db8::"), 0xff, 32))
 	fmt.Println(AddPrefixes(net.ParseIP("2001:db8::"), 0x1, 16))
 	fmt.Println(AddPrefixes(net.ParseIP("2001:db8::"), 0xff, 65))
+	// Error cases
+	fmt.Println(AddPrefixes(net.ParseIP("2001:db8::"), 0xff, 8))
+	fmt.Println(AddPrefixes(net.IP{10, 0, 0, 1}, 64, 32))
 	// Output:
 	// 2001:db8:0:ff:: <nil>
 	// 2001:db8::1 <nil>
 	// 2001:eb7:: <nil>
 	// 2002:db8:: <nil>
 	// 2001:db8:0:7f:8000:: <nil>
+	// <nil> Operation overflows
+	// <nil> AddPrefixes needs 128-bit IPs
+}
+
+// Offset is used as a hash function, so it needs to be reasonably fast
+func BenchmarkOffset(b *testing.B) {
+	addresses := make([]byte, b.N*net.IPv6len*2)
+	_, err := rand.Read(addresses)
+	if err != nil {
+		b.Fatalf("Could not generate random addresses: %v", err)
+	}
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		// The arrays will be in cache, so this should amortize to measure mostly just the offset
+		// computation itself
+		_, _ = Offset(
+			addresses[i*2*net.IPv6len:(i*2+1)*net.IPv6len],
+			addresses[(i*2+1)*net.IPv6len:(i+1)*2*net.IPv6len],
+			(i*4)%128,
+		)
+	}
 }

+ 3 - 3
plugins/prefix/plugin.go

@@ -26,8 +26,8 @@ import (
 	"github.com/coredhcp/coredhcp/handler"
 	"github.com/coredhcp/coredhcp/logger"
 	"github.com/coredhcp/coredhcp/plugins"
-	"github.com/coredhcp/coredhcp/plugins/prefix/allocators"
-	"github.com/coredhcp/coredhcp/plugins/prefix/allocators/fixedsize"
+	"github.com/coredhcp/coredhcp/plugins/allocators"
+	"github.com/coredhcp/coredhcp/plugins/allocators/bitmap"
 )
 
 var log = logger.GetLogger("plugins/prefix")
@@ -55,7 +55,7 @@ func setupPrefix(args ...string) (handler.Handler6, error) {
 	}
 
 	// TODO: select allocators based on heuristics or user configuration
-	alloc, err := fixedsize.NewFixedSizeAllocator(*prefix, allocSize)
+	alloc, err := bitmap.NewBitmapAllocator(*prefix, allocSize)
 	if err != nil {
 		return nil, fmt.Errorf("Could not initialize prefix allocator: %v", err)
 	}