|
@@ -17,13 +17,88 @@ import (
|
|
|
"github.com/gravitl/netmaker/models"
|
|
|
"github.com/gravitl/netmaker/servercfg"
|
|
|
"github.com/gravitl/netmaker/validation"
|
|
|
+ "golang.org/x/exp/slog"
|
|
|
)
|
|
|
|
|
|
var (
|
|
|
networkCacheMutex = &sync.RWMutex{}
|
|
|
networkCacheMap = make(map[string]models.Network)
|
|
|
+ allocatedIpMap = make(map[string]map[string]net.IP)
|
|
|
)
|
|
|
|
|
|
+const (
|
|
|
+ ipAddrCap = 5000
|
|
|
+)
|
|
|
+
|
|
|
+// SetAllocatedIpMap - set allocated ip map for networks
|
|
|
+func SetAllocatedIpMap() error {
|
|
|
+ logger.Log(0, "start setting up allocated ip map")
|
|
|
+ if allocatedIpMap == nil {
|
|
|
+ allocatedIpMap = map[string]map[string]net.IP{}
|
|
|
+ }
|
|
|
+
|
|
|
+ currentNetworks, err := GetNetworks()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range currentNetworks {
|
|
|
+ pMap := map[string]net.IP{}
|
|
|
+ netName := v.NetID
|
|
|
+
|
|
|
+ nodes, err := GetNetworkNodes(netName)
|
|
|
+ if err != nil {
|
|
|
+ slog.Error("could not load node for network", netName, "error", err.Error())
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, n := range nodes {
|
|
|
+
|
|
|
+ if n.Address.IP != nil {
|
|
|
+ pMap[n.Address.IP.String()] = n.Address.IP
|
|
|
+ }
|
|
|
+ if n.Address6.IP != nil {
|
|
|
+ pMap[n.Address6.IP.String()] = n.Address6.IP
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ allocatedIpMap[netName] = pMap
|
|
|
+ }
|
|
|
+ logger.Log(0, "setting up allocated ip map done")
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+// ClearAllocatedIpMap - set allocatedIpMap to nil
|
|
|
+func ClearAllocatedIpMap() {
|
|
|
+ allocatedIpMap = nil
|
|
|
+}
|
|
|
+
|
|
|
+func AddIpToAllocatedIpMap(networkName string, ip net.IP) {
|
|
|
+ networkCacheMutex.Lock()
|
|
|
+ allocatedIpMap[networkName][ip.String()] = ip
|
|
|
+ networkCacheMutex.Unlock()
|
|
|
+}
|
|
|
+
|
|
|
+func RemoveIpFromAllocatedIpMap(networkName string, ip string) {
|
|
|
+ networkCacheMutex.Lock()
|
|
|
+ delete(allocatedIpMap[networkName], ip)
|
|
|
+ networkCacheMutex.Unlock()
|
|
|
+}
|
|
|
+
|
|
|
+// AddNetworkToAllocatedIpMap - add network to allocated ip map when network is added
|
|
|
+func AddNetworkToAllocatedIpMap(networkName string) {
|
|
|
+ networkCacheMutex.Lock()
|
|
|
+ allocatedIpMap[networkName] = map[string]net.IP{}
|
|
|
+ networkCacheMutex.Unlock()
|
|
|
+}
|
|
|
+
|
|
|
+// RemoveNetworkFromAllocatedIpMap - remove network from allocated ip map when network is deleted
|
|
|
+func RemoveNetworkFromAllocatedIpMap(networkName string) {
|
|
|
+ networkCacheMutex.Lock()
|
|
|
+ delete(allocatedIpMap, networkName)
|
|
|
+ networkCacheMutex.Unlock()
|
|
|
+}
|
|
|
+
|
|
|
func getNetworksFromCache() (networks []models.Network) {
|
|
|
networkCacheMutex.RLock()
|
|
|
for _, network := range networkCacheMap {
|
|
@@ -239,9 +314,17 @@ func UniqueAddress(networkName string, reverse bool) (net.IP, error) {
|
|
|
newAddrs = net4.LastAddress()
|
|
|
}
|
|
|
|
|
|
+ ipAllocated := allocatedIpMap[networkName]
|
|
|
+ i := 0
|
|
|
for {
|
|
|
- if IsIPUnique(networkName, newAddrs.String(), database.NODES_TABLE_NAME, false) &&
|
|
|
- IsIPUnique(networkName, newAddrs.String(), database.EXT_CLIENT_TABLE_NAME, false) {
|
|
|
+ if i >= ipAddrCap {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ // if IsIPUnique(networkName, newAddrs.String(), database.NODES_TABLE_NAME, false) &&
|
|
|
+ // IsIPUnique(networkName, newAddrs.String(), database.EXT_CLIENT_TABLE_NAME, false) {
|
|
|
+ // return newAddrs, nil
|
|
|
+ // }
|
|
|
+ if _, ok := ipAllocated[newAddrs.String()]; !ok {
|
|
|
return newAddrs, nil
|
|
|
}
|
|
|
if reverse {
|
|
@@ -252,6 +335,7 @@ func UniqueAddress(networkName string, reverse bool) (net.IP, error) {
|
|
|
if err != nil {
|
|
|
break
|
|
|
}
|
|
|
+ i++
|
|
|
}
|
|
|
|
|
|
return add, errors.New("ERROR: No unique addresses available. Check network subnet")
|
|
@@ -328,9 +412,17 @@ func UniqueAddress6(networkName string, reverse bool) (net.IP, error) {
|
|
|
return add, err
|
|
|
}
|
|
|
|
|
|
+ ipAllocated := allocatedIpMap[networkName]
|
|
|
+ i := 0
|
|
|
for {
|
|
|
- if IsIPUnique(networkName, newAddrs.String(), database.NODES_TABLE_NAME, true) &&
|
|
|
- IsIPUnique(networkName, newAddrs.String(), database.EXT_CLIENT_TABLE_NAME, true) {
|
|
|
+ if i >= ipAddrCap {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ // if IsIPUnique(networkName, newAddrs.String(), database.NODES_TABLE_NAME, true) &&
|
|
|
+ // IsIPUnique(networkName, newAddrs.String(), database.EXT_CLIENT_TABLE_NAME, true) {
|
|
|
+ // return newAddrs, nil
|
|
|
+ // }
|
|
|
+ if _, ok := ipAllocated[newAddrs.String()]; !ok {
|
|
|
return newAddrs, nil
|
|
|
}
|
|
|
if reverse {
|
|
@@ -341,6 +433,7 @@ func UniqueAddress6(networkName string, reverse bool) (net.IP, error) {
|
|
|
if err != nil {
|
|
|
break
|
|
|
}
|
|
|
+ i++
|
|
|
}
|
|
|
|
|
|
return add, errors.New("ERROR: No unique IPv6 addresses available. Check network subnet")
|