github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/fleetmanager/hypervisors/subnets.go (about)

     1  package hypervisors
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  
     7  	"github.com/Cloud-Foundations/Dominator/fleetmanager/topology"
     8  	"github.com/Cloud-Foundations/Dominator/lib/net/util"
     9  )
    10  
    11  // This must be called with the lock held.
    12  func (m *Manager) checkIpReserved(tSubnet *topology.Subnet, ip net.IP) bool {
    13  	if ip.Equal(tSubnet.IpGateway) {
    14  		return true
    15  	}
    16  	ipAddr := ip.String()
    17  	if tSubnet.CheckIfIpIsReserved(ipAddr) {
    18  		return true
    19  	}
    20  	if _, ok := m.allocatingIPs[ipAddr]; ok {
    21  		return true
    22  	}
    23  	if _, ok := m.migratingIPs[ipAddr]; ok {
    24  		return true
    25  	}
    26  	return false
    27  }
    28  
    29  // This must be called with the lock held. This will update the allocatingIPs
    30  // map.
    31  func (m *Manager) findFreeIPs(tSubnet *topology.Subnet,
    32  	numNeeded uint) ([]net.IP, error) {
    33  	var freeIPs []net.IP
    34  	gatewayIp := tSubnet.IpGateway.String()
    35  	subnet, ok := m.subnets[gatewayIp]
    36  	if !ok {
    37  		return nil, fmt.Errorf("subnet for gateway: %s not found", gatewayIp)
    38  	}
    39  	initialIp := util.CopyIP(subnet.nextIp)
    40  	for numNeeded > 0 {
    41  		if !m.checkIpReserved(subnet.subnet, subnet.nextIp) {
    42  			registered, err := m.storer.CheckIpIsRegistered(subnet.nextIp)
    43  			if err != nil {
    44  				return nil, err
    45  			}
    46  			if !registered {
    47  				freeIPs = append(freeIPs, util.CopyIP(subnet.nextIp))
    48  				numNeeded--
    49  			}
    50  		}
    51  		util.IncrementIP(subnet.nextIp)
    52  		if subnet.nextIp.Equal(subnet.stopIp) {
    53  			copy(subnet.nextIp, subnet.startIp)
    54  		}
    55  		if initialIp.Equal(subnet.nextIp) {
    56  			break
    57  		}
    58  	}
    59  	for _, ip := range freeIPs {
    60  		m.allocatingIPs[ip.String()] = struct{}{}
    61  	}
    62  	return freeIPs, nil
    63  }
    64  
    65  func (m *Manager) makeSubnet(tSubnet *topology.Subnet) *subnetType {
    66  	networkIp := tSubnet.IpGateway.Mask(net.IPMask(tSubnet.IpMask))
    67  	var startIp, stopIp net.IP
    68  	if len(tSubnet.FirstAutoIP) > 0 {
    69  		startIp = tSubnet.FirstAutoIP
    70  	} else {
    71  		startIp = util.CopyIP(networkIp)
    72  		util.IncrementIP(startIp)
    73  	}
    74  	if len(tSubnet.LastAutoIP) > 0 {
    75  		stopIp = util.CopyIP(tSubnet.LastAutoIP)
    76  		util.IncrementIP(stopIp)
    77  	} else {
    78  		stopIp = make(net.IP, len(networkIp))
    79  		invertedMask := util.CopyIP(tSubnet.IpMask)
    80  		util.InvertIP(invertedMask)
    81  		for index, value := range invertedMask {
    82  			stopIp[index] = networkIp[index] | value
    83  		}
    84  	}
    85  	return &subnetType{
    86  		subnet:  tSubnet,
    87  		startIp: startIp,
    88  		stopIp:  stopIp,
    89  		nextIp:  util.CopyIP(startIp),
    90  	}
    91  }
    92  
    93  func (m *Manager) unmarkAllocatingIPs(ips []net.IP) {
    94  	if len(ips) < 1 {
    95  		return
    96  	}
    97  	m.mutex.Lock()
    98  	defer m.mutex.Unlock()
    99  	for _, ip := range ips {
   100  		delete(m.allocatingIPs, ip.String())
   101  	}
   102  }