Skip to content

Commit

Permalink
do not count ips in excludeIPs as available and using IPs (#3582)
Browse files Browse the repository at this point in the history
Signed-off-by: 马洪贞 <hzma@alauda.io>
  • Loading branch information
hongzhen-ma committed Jan 3, 2024
1 parent f4311ab commit 4b85905
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 7 deletions.
4 changes: 2 additions & 2 deletions pkg/controller/subnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -2029,7 +2029,7 @@ func calcDualSubnetStatusIP(subnet *kubeovnv1.Subnet, c *Controller) error {
v6availableIPs = 0
}

v4UsingIPStr, v6UsingIPStr, v4AvailableIPStr, v6AvailableIPStr := c.ipam.GetSubnetIPRangeString(subnet.Name)
v4UsingIPStr, v6UsingIPStr, v4AvailableIPStr, v6AvailableIPStr := c.ipam.GetSubnetIPRangeString(subnet.Name, subnet.Spec.ExcludeIps)

if subnet.Status.V4AvailableIPs == v4availableIPs &&
subnet.Status.V6AvailableIPs == v6availableIPs &&
Expand Down Expand Up @@ -2118,7 +2118,7 @@ func calcSubnetStatusIP(subnet *kubeovnv1.Subnet, c *Controller) error {
availableIPs = 0
}

v4UsingIPStr, v6UsingIPStr, v4AvailableIPStr, v6AvailableIPStr := c.ipam.GetSubnetIPRangeString(subnet.Name)
v4UsingIPStr, v6UsingIPStr, v4AvailableIPStr, v6AvailableIPStr := c.ipam.GetSubnetIPRangeString(subnet.Name, subnet.Spec.ExcludeIps)
cachedFloatFields := [4]float64{
subnet.Status.V4AvailableIPs,
subnet.Status.V4UsingIPs,
Expand Down
17 changes: 12 additions & 5 deletions pkg/ipam/ipam.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,16 +380,23 @@ func (ipam *IPAM) GetSubnetV4Mask(subnetName string) (string, error) {
return "", ErrNoAvailable
}

func (ipam *IPAM) GetSubnetIPRangeString(subnetName string) (string, string, string, string) {
func (ipam *IPAM) GetSubnetIPRangeString(subnetName string, excludeIps []string) (string, string, string, string) {
ipam.mutex.RLock()
defer ipam.mutex.RUnlock()

// subnet.Spec.ExcludeIps contains both v4 and v6 addresses
v4ExcludeIps, v6ExcludeIps := util.SplitIpsByProtocol(excludeIps)

var v4UsingIPStr, v6UsingIPStr, v4AvailableIPStr, v6AvailableIPStr string
if subnet, ok := ipam.Subnets[subnetName]; ok {
v4UsingIPStr = subnet.V4Using.String()
v6UsingIPStr = subnet.V6Using.String()
v4AvailableIPStr = subnet.V4Available.String()
v6AvailableIPStr = subnet.V6Available.String()
v4Reserved, _ := NewIPRangeListFrom(v4ExcludeIps...)
v6Reserved, _ := NewIPRangeListFrom(v6ExcludeIps...)

// do not count ips in excludeIPs as available and using IPs
v4AvailableIPStr = subnet.V4Available.Separate(v4Reserved).String()
v6AvailableIPStr = subnet.V6Available.Separate(v6Reserved).String()
v4UsingIPStr = subnet.V4Using.Separate(v4Reserved).String()
v6UsingIPStr = subnet.V6Using.Separate(v6Reserved).String()
}

return v4UsingIPStr, v6UsingIPStr, v4AvailableIPStr, v6AvailableIPStr
Expand Down
3 changes: 3 additions & 0 deletions pkg/ipam/subnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,8 @@ func (s *Subnet) GetStaticAddress(podName, nicName string, ip IP, mac *string, f
if pool.V4Reserved.Contains(ip) {
s.V4NicToIP[nicName] = ip
s.V4IPToPod[ip.String()] = podName
// ip allocated from excludeIPs should be recorded in usingIPs since when the ip is removed from excludeIPs, there's no way to update usingIPs
isAllocated = true
return ip, macStr, nil
}

Expand Down Expand Up @@ -431,6 +433,7 @@ func (s *Subnet) GetStaticAddress(podName, nicName string, ip IP, mac *string, f
if pool.V6Reserved.Contains(ip) {
s.V6NicToIP[nicName] = ip
s.V6IPToPod[ip.String()] = podName
isAllocated = true
return ip, macStr, nil
}

Expand Down
20 changes: 20 additions & 0 deletions test/unittest/ipam/ipam.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,26 @@ var _ = Describe("[IPAM]", func() {
_, _, _, err = im.GetRandomAddress("pod1.ns", "pod1.ns", nil, subnetName, "", nil, true)
Expect(err).Should(MatchError(ipam.ErrNoAvailable))
})

It("do not count excludedIps as subnet's v4availableIPs and v4usingIPs", func() {
im := ipam.NewIPAM()
err := im.AddOrUpdateSubnet(subnetName, "10.16.10.0/28", "10.16.10.1", []string{"10.16.10.1", "10.16.10.10"})
Expect(err).ShouldNot(HaveOccurred())

ip, _, _, err := im.GetStaticAddress("pod1.ns", "pod1.ns", "10.16.10.10", nil, subnetName, true)
Expect(err).ShouldNot(HaveOccurred())
Expect(ip).To(Equal("10.16.10.10"))

v4UsingIPStr, _, v4AvailableIPStr, _ := im.GetSubnetIPRangeString(subnetName, []string{"10.16.10.10"})
Expect(v4UsingIPStr).To(Equal(""))
Expect(v4AvailableIPStr).To(Equal("10.16.10.2-10.16.10.9,10.16.10.11-10.16.10.14"))

err = im.AddOrUpdateSubnet(subnetName, "10.16.10.0/28", "10.16.10.1", []string{"10.16.10.1"})
Expect(err).ShouldNot(HaveOccurred())
v4UsingIPStr, _, v4AvailableIPStr, _ = im.GetSubnetIPRangeString(subnetName, nil)
Expect(v4UsingIPStr).To(Equal("10.16.10.10"))
Expect(v4AvailableIPStr).To(Equal("10.16.10.2-10.16.10.9,10.16.10.11-10.16.10.14"))
})
})

Context("[IPv6]", func() {
Expand Down

0 comments on commit 4b85905

Please sign in to comment.