diff --git a/pkg/mesh/ip.go b/pkg/mesh/ip.go index e5eb5b2..760321e 100644 --- a/pkg/mesh/ip.go +++ b/pkg/mesh/ip.go @@ -337,12 +337,13 @@ func defaultInterface() (*net.Interface, error) { type allocator struct { bits int + ones int cidr *net.IPNet current net.IP } func newAllocator(cidr net.IPNet) *allocator { - _, bits := cidr.Mask.Size() + ones, bits := cidr.Mask.Size() current := make(net.IP, len(cidr.IP)) copy(current, cidr.IP) if ip4 := current.To4(); ip4 != nil { @@ -351,6 +352,7 @@ func newAllocator(cidr net.IPNet) *allocator { return &allocator{ bits: bits, + ones: ones, cidr: &cidr, current: current, } @@ -373,5 +375,5 @@ func (a *allocator) next() *net.IPNet { ip := make(net.IP, len(a.current)) copy(ip, a.current) - return &net.IPNet{IP: ip, Mask: net.CIDRMask(a.bits, a.bits)} + return &net.IPNet{IP: ip, Mask: net.CIDRMask(a.ones, a.bits)} } diff --git a/pkg/mesh/ip_test.go b/pkg/mesh/ip_test.go index 605ba82..8e9c201 100644 --- a/pkg/mesh/ip_test.go +++ b/pkg/mesh/ip_test.go @@ -19,6 +19,60 @@ import ( "testing" ) +func TestNewAllocator(t *testing.T) { + _, c1, err := net.ParseCIDR("10.1.0.0/16") + if err != nil { + t.Fatalf("failed to parse CIDR: %v", err) + } + a1 := newAllocator(*c1) + _, c2, err := net.ParseCIDR("10.1.0.0/32") + if err != nil { + t.Fatalf("failed to parse CIDR: %v", err) + } + a2 := newAllocator(*c2) + _, c3, err := net.ParseCIDR("10.1.0.0/31") + if err != nil { + t.Fatalf("failed to parse CIDR: %v", err) + } + a3 := newAllocator(*c3) + for _, tc := range []struct { + name string + a *allocator + next string + }{ + { + name: "10.1.0.0/16 first", + a: a1, + next: "10.1.0.1/16", + }, + { + name: "10.1.0.0/16 second", + a: a1, + next: "10.1.0.2/16", + }, + { + name: "10.1.0.0/32", + a: a2, + next: "", + }, + { + name: "10.1.0.0/31 first", + a: a3, + next: "10.1.0.1/31", + }, + { + name: "10.1.0.0/31 second", + a: a3, + next: "", + }, + } { + next := tc.a.next() + if next.String() != tc.next { + t.Errorf("test case %q: expected %s, got %s", tc.name, tc.next, next.String()) + } + } +} + func TestSortIPs(t *testing.T) { ip1 := oneAddressCIDR(net.ParseIP("10.0.0.1")) ip2 := oneAddressCIDR(net.ParseIP("10.0.0.2")) diff --git a/pkg/mesh/mesh_test.go b/pkg/mesh/mesh_test.go index bdd561a..24c9e13 100644 --- a/pkg/mesh/mesh_test.go +++ b/pkg/mesh/mesh_test.go @@ -20,60 +20,6 @@ import ( "time" ) -func TestNewAllocator(t *testing.T) { - _, c1, err := net.ParseCIDR("10.1.0.0/16") - if err != nil { - t.Fatalf("failed to parse CIDR: %v", err) - } - a1 := newAllocator(*c1) - _, c2, err := net.ParseCIDR("10.1.0.0/32") - if err != nil { - t.Fatalf("failed to parse CIDR: %v", err) - } - a2 := newAllocator(*c2) - _, c3, err := net.ParseCIDR("10.1.0.0/31") - if err != nil { - t.Fatalf("failed to parse CIDR: %v", err) - } - a3 := newAllocator(*c3) - for _, tc := range []struct { - name string - a *allocator - next string - }{ - { - name: "10.1.0.0/16 first", - a: a1, - next: "10.1.0.1/32", - }, - { - name: "10.1.0.0/16 second", - a: a1, - next: "10.1.0.2/32", - }, - { - name: "10.1.0.0/32", - a: a2, - next: "", - }, - { - name: "10.1.0.0/31 first", - a: a3, - next: "10.1.0.1/32", - }, - { - name: "10.1.0.0/31 second", - a: a3, - next: "", - }, - } { - next := tc.a.next() - if next.String() != tc.next { - t.Errorf("test case %q: expected %s, got %s", tc.name, tc.next, next.String()) - } - } -} - func TestReady(t *testing.T) { internalIP := oneAddressCIDR(net.ParseIP("1.1.1.1")) externalIP := oneAddressCIDR(net.ParseIP("2.2.2.2")) diff --git a/pkg/mesh/topology.go b/pkg/mesh/topology.go index d3ca4c2..b8697d4 100644 --- a/pkg/mesh/topology.go +++ b/pkg/mesh/topology.go @@ -154,7 +154,7 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra return nil, errors.New("failed to allocate an IP address; ran out of IP addresses") } segment.wireGuardIP = ipNet.IP - segment.allowedIPs = append(segment.allowedIPs, ipNet) + segment.allowedIPs = append(segment.allowedIPs, oneAddressCIDR(ipNet.IP)) if t.leader && segment.location == t.location { t.wireGuardCIDR = &net.IPNet{IP: ipNet.IP, Mask: t.subnet.Mask} }