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