Merge pull request #1510 from Luap99/netavark-ipam

libnetwork/netavark: fix ipam allocation for custom lease range
This commit is contained in:
OpenShift Merge Robot 2023-06-16 11:23:18 -04:00 committed by GitHub
commit 7308f7b11d
2 changed files with 59 additions and 9 deletions

View File

@ -173,20 +173,23 @@ func getFreeIPFromBucket(bucket *bbolt.Bucket, subnet *types.Subnet) (net.IP, er
if rangeStart == nil {
// let start with the first ip in subnet
rangeStart = util.NextIP(subnet.Subnet.IP)
} else if util.Cmp(rangeStart, subnet.Subnet.IP) == 0 {
// when we start on the subnet ip we need to inc by one as the subnet ip cannot be assigned
rangeStart = util.NextIP(rangeStart)
}
lastIP, err := util.LastIPInSubnet(&subnet.Subnet.IPNet)
// this error should never happen but lets check anyways to prevent panics
if err != nil {
return nil, fmt.Errorf("failed to get lastIP: %w", err)
}
if rangeEnd == nil {
lastIP, err := util.LastIPInSubnet(&subnet.Subnet.IPNet)
// this error should never happen but lets check anyways to prevent panics
if err != nil {
return nil, fmt.Errorf("failed to get lastIP: %w", err)
}
// ipv4 uses the last ip in a subnet for broadcast so we cannot use it
if util.IsIPv4(lastIP) {
lastIP = util.PrevIP(lastIP)
}
rangeEnd = lastIP
}
// ipv4 uses the last ip in a subnet for broadcast so we cannot use it
if util.IsIPv4(rangeEnd) && util.Cmp(rangeEnd, lastIP) == 0 {
rangeEnd = util.PrevIP(rangeEnd)
}
lastIPByte := bucket.Get(lastIPKey)
curIP := net.IP(lastIPByte)

View File

@ -450,4 +450,51 @@ var _ = Describe("IPAM", func() {
err = networkInterface.deallocIPs(opts)
Expect(err).ToNot(HaveOccurred())
})
for _, leaseRange := range []types.LeaseRange{{
StartIP: net.ParseIP("10.0.0.0"),
EndIP: net.ParseIP("10.0.0.63"),
}, {
EndIP: net.ParseIP("10.0.0.63"),
}, {
StartIP: net.ParseIP("10.0.0.0"),
}} {
lease := leaseRange
It(fmt.Sprintf("ipam alloc with lease range as big as subnet: %v", lease), func() {
s, _ := types.ParseCIDR("10.0.0.0/26")
network, err := networkInterface.NetworkCreate(
types.Network{
Subnets: []types.Subnet{
{
Subnet: s,
LeaseRange: &lease,
},
},
},
nil,
)
Expect(err).ToNot(HaveOccurred())
netName := network.Name
for i := 2; i < 64; i++ {
opts := &types.NetworkOptions{
ContainerID: fmt.Sprintf("id-%d", i),
Networks: map[string]types.PerNetworkOptions{
netName: {},
},
}
err = networkInterface.allocIPs(opts)
if i < 63 {
Expect(err).ToNot(HaveOccurred())
Expect(opts.Networks).To(HaveKey(netName))
Expect(opts.Networks[netName].StaticIPs).To(HaveLen(1))
Expect(opts.Networks[netName].StaticIPs[0]).To(Equal(net.ParseIP(fmt.Sprintf("10.0.0.%d", i)).To4()))
} else {
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(Equal("IPAM error: failed to find free IP in range: 10.0.0.1 - 10.0.0.62"))
}
}
})
}
})