func (subnet *Subnet) GetStaticAddress(podName, nicName string, ip IP, mac string, force bool, checkConflict bool) (IP, string, error) {
subnet.mutex.Lock()
defer func() {
subnet.pushPodNic(podName, nicName)
subnet.mutex.Unlock()
}()
var v4, v6 bool
if net.ParseIP(string(ip)).To4() != nil {
v4 = subnet.V4CIDR != nil
} else {
v6 = subnet.V6CIDR != nil
}
if v4 && !subnet.V4CIDR.Contains(net.ParseIP(string(ip))) {
return ip, mac, ErrOutOfRange
}
if v6 && !subnet.V6CIDR.Contains(net.ParseIP(string(ip))) {
return ip, mac, ErrOutOfRange
}
if mac == "" {
if m, ok := subnet.NicToMac[nicName]; ok {
mac = m
} else {
mac = subnet.GetRandomMac(podName, nicName)
}
} else {
if err := subnet.GetStaticMac(podName, nicName, mac, checkConflict); err != nil {
return ip, mac, err
}
}
if v4 {
if existPod, ok := subnet.V4IPToPod[ip]; ok {
pods := strings.Split(existPod, ",")
if !util.ContainsString(pods, podName) {
if !checkConflict {
subnet.V4NicToIP[nicName] = ip
subnet.V4IPToPod[ip] = fmt.Sprintf("%s,%s", subnet.V4IPToPod[ip], podName)
return ip, mac, nil
}
return ip, mac, ErrConflict
}
if !force {
return ip, mac, nil
}
}
if subnet.V4ReservedIPList.Contains(ip) {
subnet.V4NicToIP[nicName] = ip
subnet.V4IPToPod[ip] = podName
return ip, mac, nil
}
if split, newFreeList := splitIPRangeList(subnet.V4FreeIPList, ip); split {
subnet.V4FreeIPList = newFreeList
subnet.V4NicToIP[nicName] = ip
subnet.V4IPToPod[ip] = podName
return ip, mac, nil
} else {
if split, newReleasedList := splitIPRangeList(subnet.V4ReleasedIPList, ip); split {
subnet.V4ReleasedIPList = newReleasedList
subnet.V4NicToIP[nicName] = ip
subnet.V4IPToPod[ip] = podName
return ip, mac, nil
}
}
} else if v6 {
if existPod, ok := subnet.V6IPToPod[ip]; ok {
pods := strings.Split(existPod, ",")
if !util.ContainsString(pods, podName) {
if !checkConflict {
subnet.V6NicToIP[nicName] = ip
subnet.V6IPToPod[ip] = fmt.Sprintf("%s,%s", subnet.V6IPToPod[ip], podName)
return ip, mac, nil
}
return ip, mac, ErrConflict
}
if !force {
return ip, mac, nil
}
}
if subnet.V6ReservedIPList.Contains(ip) {
subnet.V6NicToIP[nicName] = ip
subnet.V6IPToPod[ip] = podName
return ip, mac, nil
}
if split, newFreeList := splitIPRangeList(subnet.V6FreeIPList, ip); split {
subnet.V6FreeIPList = newFreeList
subnet.V6NicToIP[nicName] = ip
subnet.V6IPToPod[ip] = podName
return ip, mac, nil
} else {
if split, newReleasedList := splitIPRangeList(subnet.V6ReleasedIPList, ip); split {
subnet.V6ReleasedIPList = newReleasedList
subnet.V6NicToIP[nicName] = ip
subnet.V6IPToPod[ip] = podName
return ip, mac, nil
}
}
}
return ip, mac, ErrNoAvailable
}