in plugins/ipam/ipstore/ipstore.go [244:278]
func NextIP(ip net.IP, subnet net.IPNet) (net.IP, error) {
if ones, _ := subnet.Mask.Size(); ones > MaxMask {
return nil, errors.Errorf("nextIP ipstore: no available ip in the subnet: %v", subnet)
}
// currently only ipv4 is supported
ipv4 := ip.To4()
if ipv4 == nil {
return nil, errors.Errorf("nextIP ipstore: invalid ipv4 address: %v", ipv4)
}
if !subnet.Contains(ipv4) {
return nil, errors.Errorf("nextIP ipstore: ip %v is not within subnet %s", ipv4.String(), subnet.String())
}
minIP := subnet.IP.Mask(subnet.Mask)
maxIP := net.IP(make([]byte, 4))
for i := range ipv4 {
maxIP[i] = minIP[i] | ^subnet.Mask[i]
}
nextIP := ipv4
// Reserve the broadcast address(all 1) and the network address(all 0)
for nextIP.Equal(ipv4) || nextIP.Equal(minIP) || nextIP.Equal(maxIP) {
if nextIP.Equal(maxIP) {
nextIP = minIP
}
// convert the IP into Int for easily calculation
nextIPInBytes := big.NewInt(0).SetBytes(nextIP)
nextIPInBytes.Add(nextIPInBytes, big.NewInt(1))
nextIP = net.IP(nextIPInBytes.Bytes())
}
return nextIP, nil
}