From 2c59c807af377122098ae2bece5291a631c738a4 Mon Sep 17 00:00:00 2001 From: Francesco Cheinasso Date: Wed, 4 Dec 2024 12:06:02 +0100 Subject: [PATCH] fix: function NetworkIsAvailable refactoring --- pkg/ipam/core/ipam.go | 21 +++++++++------------ pkg/ipam/core/node.go | 31 ++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/pkg/ipam/core/ipam.go b/pkg/ipam/core/ipam.go index a474d79648..6456f0d5b1 100644 --- a/pkg/ipam/core/ipam.go +++ b/pkg/ipam/core/ipam.go @@ -63,8 +63,10 @@ func (ipam *Ipam) NetworkAcquire(size int) *netip.Prefix { // It returns the allocated network or nil if the network is not available. func (ipam *Ipam) NetworkAcquireWithPrefix(prefix netip.Prefix) *netip.Prefix { for i := range ipam.roots { - if result := allocateNetworkWithPrefix(prefix, &ipam.roots[i]); result != nil { - return result + if isPrefixChildOf(ipam.roots[i].prefix, prefix) { + if result := allocateNetworkWithPrefix(prefix, &ipam.roots[i]); result != nil { + return result + } } } return nil @@ -95,17 +97,12 @@ func (ipam *Ipam) ListNetworks() []netip.Prefix { // NetworkIsAvailable checks if the network with the given prefix is allocated. // It returns false if the network is allocated or there is no suitable pool, true otherwise. func (ipam *Ipam) NetworkIsAvailable(prefix netip.Prefix) bool { - node, err := ipam.search(prefix) - if err != nil { - return false - } - if node == nil { - return true - } - if node.left != nil || node.right != nil { - return false + for i := range ipam.roots { + if isPrefixChildOf(ipam.roots[i].prefix, prefix) { + return networkIsAvailable(prefix, &ipam.roots[i]) + } } - return !node.acquired + return false } // IPAcquire allocates an IP address from the given prefix. diff --git a/pkg/ipam/core/node.go b/pkg/ipam/core/node.go index 79d2301a29..fc9dd48d9b 100644 --- a/pkg/ipam/core/node.go +++ b/pkg/ipam/core/node.go @@ -121,6 +121,31 @@ func networkRelease(prefix netip.Prefix, node *node) *netip.Prefix { return result } +func networkIsAvailable(prefix netip.Prefix, node *node) bool { + if node == nil { + return true + } + + if node.prefix.Addr().Compare(prefix.Addr()) == 0 && node.prefix.Bits() == prefix.Bits() { + if node.left != nil && (node.left.left != nil || node.left.right != nil) { + return false + } + if node.right != nil && (node.right.left != nil || node.right.right != nil) { + return false + } + return !node.acquired + } + + if node.left != nil && node.left.prefix.Overlaps(prefix) && !node.left.acquired { + return networkIsAvailable(prefix, node.left) + } + if node.right != nil && node.right.prefix.Overlaps(prefix) && !node.right.acquired { + return networkIsAvailable(prefix, node.right) + } + + return false +} + func listNetworks(node *node) []netip.Prefix { if node == nil { return nil @@ -308,13 +333,13 @@ func (n *node) toGraphviz() error { n.toGraphvizRecursive(&sb) sb.WriteString("}\n") - if _, err := os.Stat("/graphviz"); os.IsNotExist(err) { - if err := os.Mkdir("/graphviz", 0o700); err != nil { + if _, err := os.Stat("./graphviz"); os.IsNotExist(err) { + if err := os.Mkdir("./graphviz", 0o700); err != nil { return err } } - filePath := filepath.Clean("/graphviz/" + strings.NewReplacer("/", "_", ".", "_").Replace(n.prefix.String()) + ".dot") + filePath := filepath.Clean("./graphviz/" + strings.NewReplacer("/", "_", ".", "_").Replace(n.prefix.String()) + ".dot") file, err := os.Create(filePath) if err != nil { return err