mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
f7ad95cab9
This feature allows user to specify list of subnets for global default address pool. User can configure subnet list using 'swarm init' command. Daemon passes the information to swarmkit. We validate the information in swarmkit, then store it in cluster object. when IPAM init is called, we pass subnet list to IPAM driver. Signed-off-by: selansen <elango.siva@docker.com>
135 lines
4.5 KiB
Go
135 lines
4.5 KiB
Go
// Package ipamutils provides utility functions for ipam management
|
|
package ipamutils
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"sync"
|
|
)
|
|
|
|
var (
|
|
// PredefinedLocalScopeDefaultNetworks contains a list of 31 IPv4 private networks with host size 16 and 12
|
|
// (172.17-31.x.x/16, 192.168.x.x/20) which do not overlap with the networks in `PredefinedGlobalScopeDefaultNetworks`
|
|
PredefinedLocalScopeDefaultNetworks []*net.IPNet
|
|
// PredefinedGlobalScopeDefaultNetworks contains a list of 64K IPv4 private networks with host size 8
|
|
// (10.x.x.x/24) which do not overlap with the networks in `PredefinedLocalScopeDefaultNetworks`
|
|
PredefinedGlobalScopeDefaultNetworks []*net.IPNet
|
|
mutex sync.Mutex
|
|
localScopeDefaultNetworks = []*NetworkToSplit{{"172.17.0.0/16", 16}, {"172.18.0.0/16", 16}, {"172.19.0.0/16", 16},
|
|
{"172.20.0.0/14", 16}, {"172.24.0.0/14", 16}, {"172.28.0.0/14", 16},
|
|
{"192.168.0.0/16", 20}}
|
|
globalScopeDefaultNetworks = []*NetworkToSplit{{"10.0.0.0/8", 24}}
|
|
)
|
|
|
|
// NetworkToSplit represent a network that has to be split in chunks with mask length Size.
|
|
// Each subnet in the set is derived from the Base pool. Base is to be passed
|
|
// in CIDR format.
|
|
// Example: a Base "10.10.0.0/16 with Size 24 will define the set of 256
|
|
// 10.10.[0-255].0/24 address pools
|
|
type NetworkToSplit struct {
|
|
Base string `json:"base"`
|
|
Size int `json:"size"`
|
|
}
|
|
|
|
func init() {
|
|
var err error
|
|
if PredefinedGlobalScopeDefaultNetworks, err = splitNetworks(globalScopeDefaultNetworks); err != nil {
|
|
//we are going to panic in case of error as we should never get into this state
|
|
panic("InitAddressPools failed to initialize the global scope default address pool")
|
|
}
|
|
|
|
if PredefinedLocalScopeDefaultNetworks, err = splitNetworks(localScopeDefaultNetworks); err != nil {
|
|
//we are going to panic in case of error as we should never get into this state
|
|
panic("InitAddressPools failed to initialize the local scope default address pool")
|
|
}
|
|
}
|
|
|
|
// configDefaultNetworks configures local as well global default pool based on input
|
|
func configDefaultNetworks(defaultAddressPool []*NetworkToSplit, result *[]*net.IPNet) error {
|
|
mutex.Lock()
|
|
defer mutex.Unlock()
|
|
defaultNetworks, err := splitNetworks(defaultAddressPool)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*result = defaultNetworks
|
|
return nil
|
|
}
|
|
|
|
// GetGlobalScopeDefaultNetworks returns PredefinedGlobalScopeDefaultNetworks
|
|
func GetGlobalScopeDefaultNetworks() []*net.IPNet {
|
|
mutex.Lock()
|
|
defer mutex.Unlock()
|
|
return PredefinedGlobalScopeDefaultNetworks
|
|
}
|
|
|
|
// GetLocalScopeDefaultNetworks returns PredefinedLocalScopeDefaultNetworks
|
|
func GetLocalScopeDefaultNetworks() []*net.IPNet {
|
|
mutex.Lock()
|
|
defer mutex.Unlock()
|
|
return PredefinedLocalScopeDefaultNetworks
|
|
}
|
|
|
|
// ConfigGlobalScopeDefaultNetworks configures global default pool.
|
|
// Ideally this will be called from SwarmKit as part of swarm init
|
|
func ConfigGlobalScopeDefaultNetworks(defaultAddressPool []*NetworkToSplit) error {
|
|
if defaultAddressPool == nil {
|
|
defaultAddressPool = globalScopeDefaultNetworks
|
|
}
|
|
return configDefaultNetworks(defaultAddressPool, &PredefinedGlobalScopeDefaultNetworks)
|
|
}
|
|
|
|
// ConfigLocalScopeDefaultNetworks configures local default pool.
|
|
// Ideally this will be called during libnetwork init
|
|
func ConfigLocalScopeDefaultNetworks(defaultAddressPool []*NetworkToSplit) error {
|
|
if defaultAddressPool == nil {
|
|
return nil
|
|
}
|
|
return configDefaultNetworks(defaultAddressPool, &PredefinedLocalScopeDefaultNetworks)
|
|
}
|
|
|
|
// splitNetworks takes a slice of networks, split them accordingly and returns them
|
|
func splitNetworks(list []*NetworkToSplit) ([]*net.IPNet, error) {
|
|
localPools := make([]*net.IPNet, 0, len(list))
|
|
|
|
for _, p := range list {
|
|
_, b, err := net.ParseCIDR(p.Base)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid base pool %q: %v", p.Base, err)
|
|
}
|
|
ones, _ := b.Mask.Size()
|
|
if p.Size <= 0 || p.Size < ones {
|
|
return nil, fmt.Errorf("invalid pools size: %d", p.Size)
|
|
}
|
|
localPools = append(localPools, splitNetwork(p.Size, b)...)
|
|
}
|
|
return localPools, nil
|
|
}
|
|
|
|
func splitNetwork(size int, base *net.IPNet) []*net.IPNet {
|
|
one, bits := base.Mask.Size()
|
|
mask := net.CIDRMask(size, bits)
|
|
n := 1 << uint(size-one)
|
|
s := uint(bits - size)
|
|
list := make([]*net.IPNet, 0, n)
|
|
|
|
for i := 0; i < n; i++ {
|
|
ip := copyIP(base.IP)
|
|
addIntToIP(ip, uint(i<<s))
|
|
list = append(list, &net.IPNet{IP: ip, Mask: mask})
|
|
}
|
|
return list
|
|
}
|
|
|
|
func copyIP(from net.IP) net.IP {
|
|
ip := make([]byte, len(from))
|
|
copy(ip, from)
|
|
return ip
|
|
}
|
|
|
|
func addIntToIP(array net.IP, ordinal uint) {
|
|
for i := len(array) - 1; i >= 0; i-- {
|
|
array[i] |= (byte)(ordinal & 0xff)
|
|
ordinal >>= 8
|
|
}
|
|
}
|