Merge pull request #42626 from mfeit-internet2/small-ipv4-networks

Support small ipv4 networks
This commit is contained in:
Sebastiaan van Stijn 2022-06-07 22:15:19 +02:00 committed by GitHub
commit 9959eceb9a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 5 deletions

View file

@ -348,12 +348,15 @@ func (a *Allocator) insertBitMask(key SubnetKey, pool *net.IPNet) error {
return err
}
// Do not let network identifier address be reserved
// Do the same for IPv6 so that bridge ip starts with XXXX...::1
h.Set(0)
// Pre-reserve the network address on IPv4 networks large
// enough to have one (i.e., anything bigger than a /31.
if !(ipVer == v4 && numAddresses <= 2) {
h.Set(0)
}
// Do not let broadcast address be reserved
if ipVer == v4 {
// Pre-reserve the broadcast address on IPv4 networks large
// enough to have one (i.e., anything bigger than a /31).
if ipVer == v4 && numAddresses > 2 {
h.Set(numAddresses - 1)
}

View file

@ -1055,6 +1055,72 @@ func TestOverlappingRequests(t *testing.T) {
}
}
func TestUnusualSubnets(t *testing.T) {
subnet := "192.168.0.2/31"
outsideTheRangeAddresses := []struct {
address string
}{
{"192.168.0.1"},
{"192.168.0.4"},
{"192.168.0.100"},
}
expectedAddresses := []struct {
address string
}{
{"192.168.0.2"},
{"192.168.0.3"},
}
for _, store := range []bool{false, true} {
allocator, err := getAllocator(store)
if err != nil {
t.Fatal(err)
}
//
// IPv4 /31 blocks. See RFC 3021.
//
pool, _, _, err := allocator.RequestPool(localAddressSpace, subnet, "", nil, false)
if err != nil {
t.Fatal(err)
}
// Outside-the-range
for _, outside := range outsideTheRangeAddresses {
_, _, errx := allocator.RequestAddress(pool, net.ParseIP(outside.address), nil)
if errx != ipamapi.ErrIPOutOfRange {
t.Fatalf("Address %s failed to throw expected error: %s", outside.address, errx.Error())
}
}
// Should get just these two IPs followed by exhaustion on the next request
for _, expected := range expectedAddresses {
got, _, errx := allocator.RequestAddress(pool, nil, nil)
if errx != nil {
t.Fatalf("Failed to obtain the address: %s", errx.Error())
}
expectedIP := net.ParseIP(expected.address)
gotIP := got.IP
if !gotIP.Equal(expectedIP) {
t.Fatalf("Failed to obtain sequentialaddress. Expected: %s, Got: %s", expectedIP, gotIP)
}
}
_, _, err = allocator.RequestAddress(pool, nil, nil)
if err != ipamapi.ErrNoAvailableIPs {
t.Fatal("Did not get expected error when pool is exhausted.")
}
}
}
func TestRelease(t *testing.T) {
var (
subnet = "192.168.0.0/23"