Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assign sequential ips #3

Open
wants to merge 4 commits into
base: Predefined-subnet
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 34 additions & 17 deletions management/server/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"sync"
"time"
"os"
"strconv"

"github.com/c-robinson/iplib"
"github.com/rs/xid"
Expand Down Expand Up @@ -113,30 +114,46 @@ func (n *Network) Copy() *Network {
}
}

// AllocatePeerIP pics an available IP from an net.IPNet.
// This method considers already taken IPs and reuses IPs if there are gaps in takenIps
// E.g. if ipNet=100.30.0.0/16 and takenIps=[100.30.0.1, 100.30.0.4] then the result would be 100.30.0.2 or 100.30.0.3

// AllocatePeerIP picks an available IP from a net.IPNet.
// If sequential IPs assigning is enabled, it assigns the smallest available IP address.
// Otherwise, it assigns a random available IP address.
func AllocatePeerIP(ipNet net.IPNet, takenIps []net.IP) (net.IP, error) {
takenIPMap := make(map[string]struct{})
takenIPMap[ipNet.IP.String()] = struct{}{}
for _, ip := range takenIps {
takenIPMap[ip.String()] = struct{}{}
}
takenIPMap := make(map[string]struct{})
takenIPMap[ipNet.IP.String()] = struct{}{}
for _, ip := range takenIps {
takenIPMap[ip.String()] = struct{}{}
}

ips, _ := generateIPs(&ipNet, takenIPMap)
// Check if sequential IP assignment is enabled
assignSequentialIPsStr := os.Getenv("NETBIRD_ASSIGN_SEQUENTIAL_IPS")
assignSequentialIPs, err := strconv.Atoi(assignSequentialIPsStr)
if err != nil {
return nil, err
}

if len(ips) == 0 {
return nil, status.Errorf(status.PreconditionFailed, "failed allocating new IP for the ipNet %s - network is out of IPs", ipNet.String())
}
ips, _ := generateIPs(&ipNet, takenIPMap)

if len(ips) == 0 {
return nil, status.Errorf(status.PreconditionFailed, "failed allocating new IP for the ipNet %s - network is out of IPs", ipNet.String())
}

// pick the smallest available IP if sequential assignment is enabled
if assignSequentialIPs == 1 {
return ips[0], nil
} else {

// pick a random IP
s := rand.NewSource(time.Now().Unix())
r := rand.New(s)
intn := r.Intn(len(ips))
// pick a random IP
s := rand.NewSource(time.Now().Unix())
r := rand.New(s)
intn := r.Intn(len(ips))

return ips[intn], nil
return ips[intn], nil
}
}



// generateIPs generates a list of all possible IPs of the given network excluding IPs specified in the exclusion list
func generateIPs(ipNet *net.IPNet, exclusions map[string]struct{}) ([]net.IP, int) {

Expand Down
Loading