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