コード例 #1
0
ファイル: allocator.go プロジェクト: Gandi/docker
// return an available ip if one is currently available.  If not,
// return the next available ip for the nextwork
func (allocated *allocatedMap) getNextIP(network *net.IPNet) (*net.IP, error) {
	var (
		ownIP    = ipToInt(&network.IP)
		first, _ = networkdriver.NetworkRange(network)
		base     = ipToInt(&first)
		size     = int(networkdriver.NetworkSize(network.Mask))
		max      = int32(size - 2) // size -1 for the broadcast network, -1 for the gateway network
		pos      = allocated.last
	)

	var (
		firstNetIP = network.IP.To4().Mask(network.Mask)
		firstAsInt = ipToInt(&firstNetIP) + 1
	)

	for i := int32(0); i < max; i++ {
		pos = pos%max + 1
		next := int32(base + pos)

		if next == ownIP || next == firstAsInt {
			continue
		}
		if _, ok := allocated.p[pos]; ok {
			continue
		}
		allocated.p[pos] = struct{}{}
		allocated.last = pos
		return intToIP(next), nil
	}
	return nil, ErrNoAvailableIPs
}
コード例 #2
0
ファイル: allocator.go プロジェクト: baoruxing/docker
func newAllocatedMap(network *net.IPNet) *allocatedMap {
	firstIP, lastIP := networkdriver.NetworkRange(network)
	begin := ipToInt(firstIP) + 2
	end := ipToInt(lastIP) - 1
	return &allocatedMap{
		p:     make(map[uint32]struct{}),
		begin: begin,
		end:   end,
		last:  begin - 1, // so first allocated will be begin
	}
}
コード例 #3
0
ファイル: allocator.go プロジェクト: nicholaskh/docker
func newAllocatedMap(network *net.IPNet) *allocatedMap {
	firstIP, lastIP := networkdriver.NetworkRange(network)
	begin := big.NewInt(0).Add(ipToBigInt(firstIP), big.NewInt(1))
	end := big.NewInt(0).Sub(ipToBigInt(lastIP), big.NewInt(1))

	return &allocatedMap{
		p:     make(map[string]struct{}),
		begin: begin,
		end:   end,
		last:  big.NewInt(0).Sub(begin, big.NewInt(1)), // so first allocated will be begin
	}
}
コード例 #4
0
ファイル: allocator.go プロジェクト: harshavardhana/docker
func newAllocatedMap(network *net.IPNet) *allocatedMap {
	firstIP, lastIP := networkdriver.NetworkRange(network)
	begin := big.NewInt(0).Add(ipToBigInt(firstIP), big.NewInt(1))
	end := big.NewInt(0).Sub(ipToBigInt(lastIP), big.NewInt(1))

	// if IPv4 network, then allocation range starts at begin + 1 because begin is bridge IP
	if len(firstIP) == 4 {
		begin = begin.Add(begin, big.NewInt(1))
	}

	return &allocatedMap{
		p:     make(map[string]struct{}),
		begin: begin,
		end:   end,
		last:  big.NewInt(0).Sub(begin, big.NewInt(1)), // so first allocated will be begin
	}
}
コード例 #5
0
ファイル: allocator.go プロジェクト: baoruxing/docker
// RegisterSubnet registers network in global allocator with bounds
// defined by subnet. If you want to use network range you must call
// this method before first RequestIP, otherwise full network range will be used
func RegisterSubnet(network *net.IPNet, subnet *net.IPNet) error {
	lock.Lock()
	defer lock.Unlock()
	key := network.String()
	if _, ok := allocatedIPs[key]; ok {
		return ErrNetworkAlreadyRegistered
	}
	n := newAllocatedMap(network)
	beginIP, endIP := networkdriver.NetworkRange(subnet)
	begin, end := ipToInt(beginIP)+1, ipToInt(endIP)-1
	if !(begin >= n.begin && end <= n.end && begin < end) {
		return ErrBadSubnet
	}
	n.begin = begin
	n.end = end
	n.last = begin - 1
	allocatedIPs[key] = n
	return nil
}
コード例 #6
0
ファイル: allocator.go プロジェクト: harshavardhana/docker
// RegisterSubnet registers network in global allocator with bounds
// defined by subnet. If you want to use network range you must call
// this method before first RequestIP, otherwise full network range will be used
func RegisterSubnet(network *net.IPNet, subnet *net.IPNet) error {
	lock.Lock()
	defer lock.Unlock()
	key := network.String()
	if _, ok := allocatedIPs[key]; ok {
		return ErrNetworkAlreadyRegistered
	}
	n := newAllocatedMap(network)
	beginIP, endIP := networkdriver.NetworkRange(subnet)
	begin := big.NewInt(0).Add(ipToBigInt(beginIP), big.NewInt(1))
	end := big.NewInt(0).Sub(ipToBigInt(endIP), big.NewInt(1))

	// Check that subnet is within network
	if !(begin.Cmp(n.begin) >= 0 && end.Cmp(n.end) <= 0 && begin.Cmp(end) == -1) {
		return ErrBadSubnet
	}
	n.begin.Set(begin)
	n.end.Set(end)
	n.last.Sub(begin, big.NewInt(1))
	allocatedIPs[key] = n
	return nil
}
コード例 #7
0
ファイル: allocator.go プロジェクト: Gandi/docker
// convert the ip into the position in the subnet.  Only
// position are saved in the set
func getPosition(network *net.IPNet, ip *net.IP) int32 {
	first, _ := networkdriver.NetworkRange(network)
	return ipToInt(ip) - ipToInt(&first)
}