func (a *Allocator) getAddress(nw *net.IPNet, bitmask *bitseq.Handle, prefAddress net.IP, ipr *AddressRange) (net.IP, error) { var ( ordinal uint64 err error base *net.IPNet ) base = types.GetIPNetCopy(nw) if bitmask.Unselected() <= 0 { return nil, ipamapi.ErrNoAvailableIPs } if ipr == nil && prefAddress == nil { ordinal, err = bitmask.SetAny() } else if prefAddress != nil { hostPart, e := types.GetHostPartIP(prefAddress, base.Mask) if e != nil { return nil, fmt.Errorf("failed to allocate preferred address %s: %v", prefAddress.String(), e) } ordinal = ipToUint64(types.GetMinimalIP(hostPart)) err = bitmask.Set(ordinal) } else { base.IP = ipr.Sub.IP ordinal, err = bitmask.SetAnyInRange(ipr.Start, ipr.End) } if err != nil { return nil, ipamapi.ErrNoAvailableIPs } // Convert IP ordinal for this subnet into IP address return generateAddress(ordinal, base), nil }
// Release allows releasing the address from the specified address space func (a *Allocator) Release(addrSpace AddressSpace, address net.IP) { var ( space *bitseq.Handle sub *net.IPNet ) if address == nil { log.Debugf("Requested to remove nil address from address space %s", addrSpace) return } ver := getAddressVersion(address) if ver == v4 { address = address.To4() } // Find the subnet containing the address for _, subKey := range a.getSubnetList(addrSpace, ver) { sub = subKey.canonicalChildSubnet() if sub.Contains(address) { a.Lock() space = a.addresses[subKey] a.Unlock() break } } if space == nil { log.Debugf("Could not find subnet on address space %s containing %s on release", addrSpace, address.String()) return } // Retrieve correspondent ordinal in the subnet hostPart, err := types.GetHostPartIP(address, sub.Mask) if err != nil { log.Warnf("Failed to release address %s on address space %s because of internal error: %v", address.String(), addrSpace, err) return } ordinal := ipToUint32(hostPart) // Release it if err := space.Unset(ordinal); err != nil { log.Warnf("Failed to release address %s on address space %s because of internal error: %v", address.String(), addrSpace, err) } }
func (a *Allocator) getAddress(subnet *net.IPNet, bitmask *bitseq.Handle, prefAddress net.IP, ver ipVersion) (net.IP, error) { var ( ordinal uint32 err error ) if bitmask.Unselected() <= 0 { return nil, ErrNoAvailableIPs } if prefAddress == nil { ordinal, err = bitmask.SetAny() } else { hostPart, e := types.GetHostPartIP(prefAddress, subnet.Mask) if e != nil { return nil, fmt.Errorf("failed to allocate preferred address %s: %v", prefAddress.String(), e) } ordinal = ipToUint32(types.GetMinimalIP(hostPart)) err = bitmask.Set(ordinal) } if err != nil { return nil, ErrNoAvailableIPs } // Convert IP ordinal for this subnet into IP address return generateAddress(ordinal, subnet), nil }
func (a *Allocator) getAddress(subnet *net.IPNet, bitmask *bitseq.Handle, prefAddress net.IP, ver ipVersion) (net.IP, error) { var ( bytePos, bitPos int ordinal int err error ) // Look for free IP, skip .0 and .255, they will be automatically reserved for { if bitmask.Unselected() <= 0 { return nil, ErrNoAvailableIPs } if prefAddress == nil { bytePos, bitPos, err = bitmask.GetFirstAvailable() } else { ordinal = ipToInt(getHostPortionIP(prefAddress, subnet)) bytePos, bitPos, err = bitmask.CheckIfAvailable(ordinal) } if err != nil { return nil, ErrNoAvailableIPs } // Lock it if err = bitmask.PushReservation(bytePos, bitPos, false); err != nil { if _, ok := err.(types.RetryError); !ok { return nil, fmt.Errorf("internal failure while reserving the address: %s", err.Error()) } continue } // Build IP ordinal ordinal = bitPos + bytePos*8 // For v4, let reservation of .0 and .255 happen automatically if ver == v4 && !isValidIP(ordinal) { continue } break } // Convert IP ordinal for this subnet into IP address return generateAddress(ordinal, subnet), nil }
func (a *Allocator) getAddress(nw *net.IPNet, bitmask *bitseq.Handle, prefAddress net.IP, ipr *AddressRange) (net.IP, error) { var ( ordinal uint64 err error base *net.IPNet ) base = types.GetIPNetCopy(nw) if bitmask.Unselected() <= 0 { return nil, ipamapi.ErrNoAvailableIPs } if ipr == nil && prefAddress == nil { ordinal, err = bitmask.SetAny() } else if prefAddress != nil { hostPart, e := types.GetHostPartIP(prefAddress, base.Mask) if e != nil { return nil, types.InternalErrorf("failed to allocate requested address %s: %v", prefAddress.String(), e) } ordinal = ipToUint64(types.GetMinimalIP(hostPart)) err = bitmask.Set(ordinal) } else { ordinal, err = bitmask.SetAnyInRange(ipr.Start, ipr.End) } switch err { case nil: // Convert IP ordinal for this subnet into IP address return generateAddress(ordinal, base), nil case bitseq.ErrBitAllocated: return nil, ipamapi.ErrIPAlreadyAllocated case bitseq.ErrNoBitAvailable: return nil, ipamapi.ErrNoAvailableIPs default: return nil, err } }