22package ipamutils
33
44import (
5+ "fmt"
56 "net"
67 "sync"
8+
9+ "github.com/sirupsen/logrus"
710)
811
912var (
@@ -13,38 +16,81 @@ var (
1316 // PredefinedGranularNetworks contains a list of 64K IPv4 private networks with host size 8
1417 // (10.x.x.x/24) which do not overlap with the networks in `PredefinedBroadNetworks`
1518 PredefinedGranularNetworks []* net.IPNet
19+ initNetworksOnce sync.Once
1620
17- initNetworksOnce sync.Once
21+ defaultBroadNetwork = []* NetworkToSplit {{"172.17.0.0/16" , 16 }, {"172.18.0.0/16" , 16 }, {"172.19.0.0/16" , 16 },
22+ {"172.20.0.0/14" , 16 }, {"172.24.0.0/14" , 16 }, {"172.28.0.0/14" , 16 },
23+ {"192.168.0.0/16" , 20 }}
24+ defaultGranularNetwork = []* NetworkToSplit {{"10.0.0.0/8" , 24 }}
1825)
1926
20- // InitNetworks initializes the pre-defined networks used by the built-in IP allocator
21- func InitNetworks () {
27+ // NetworkToSplit represent a network that has to be split in chunks with mask length Size.
28+ // Each subnet in the set is derived from the Base pool. Base is to be passed
29+ // in CIDR format.
30+ // Example: a Base "10.10.0.0/16 with Size 24 will define the set of 256
31+ // 10.10.[0-255].0/24 address pools
32+ type NetworkToSplit struct {
33+ Base string `json:"base"`
34+ Size int `json:"size"`
35+ }
36+
37+ // InitNetworks initializes the broad network pool and the granular network pool
38+ func InitNetworks (defaultAddressPool []* NetworkToSplit ) {
2239 initNetworksOnce .Do (func () {
23- PredefinedBroadNetworks = initBroadPredefinedNetworks ()
24- PredefinedGranularNetworks = initGranularPredefinedNetworks ()
40+ // error ingnored should never fail
41+ PredefinedGranularNetworks , _ = splitNetworks (defaultGranularNetwork )
42+ if defaultAddressPool == nil {
43+ defaultAddressPool = defaultBroadNetwork
44+ }
45+ var err error
46+ if PredefinedBroadNetworks , err = splitNetworks (defaultAddressPool ); err != nil {
47+ logrus .WithError (err ).Error ("InitAddressPools failed to initialize the default address pool" )
48+ }
2549 })
2650}
2751
28- func initBroadPredefinedNetworks () []* net.IPNet {
29- pl := make ([]* net.IPNet , 0 , 31 )
30- mask := []byte {255 , 255 , 0 , 0 }
31- for i := 17 ; i < 32 ; i ++ {
32- pl = append (pl , & net.IPNet {IP : []byte {172 , byte (i ), 0 , 0 }, Mask : mask })
52+ // splitNetworks takes a slice of networks, split them accordingly and returns them
53+ func splitNetworks (list []* NetworkToSplit ) ([]* net.IPNet , error ) {
54+ localPools := make ([]* net.IPNet , 0 , len (list ))
55+
56+ for _ , p := range list {
57+ _ , b , err := net .ParseCIDR (p .Base )
58+ if err != nil {
59+ return nil , fmt .Errorf ("invalid base pool %q: %v" , p .Base , err )
60+ }
61+ ones , _ := b .Mask .Size ()
62+ if p .Size <= 0 || p .Size < ones {
63+ return nil , fmt .Errorf ("invalid pools size: %d" , p .Size )
64+ }
65+ localPools = append (localPools , splitNetwork (p .Size , b )... )
3366 }
34- mask20 := []byte {255 , 255 , 240 , 0 }
35- for i := 0 ; i < 16 ; i ++ {
36- pl = append (pl , & net.IPNet {IP : []byte {192 , 168 , byte (i << 4 ), 0 }, Mask : mask20 })
67+ return localPools , nil
68+ }
69+
70+ func splitNetwork (size int , base * net.IPNet ) []* net.IPNet {
71+ one , bits := base .Mask .Size ()
72+ mask := net .CIDRMask (size , bits )
73+ n := 1 << uint (size - one )
74+ s := uint (bits - size )
75+ list := make ([]* net.IPNet , 0 , n )
76+
77+ for i := 0 ; i < n ; i ++ {
78+ ip := copyIP (base .IP )
79+ addIntToIP (ip , uint (i << s ))
80+ list = append (list , & net.IPNet {IP : ip , Mask : mask })
3781 }
38- return pl
82+ return list
3983}
4084
41- func initGranularPredefinedNetworks () []* net.IPNet {
42- pl := make ([]* net.IPNet , 0 , 256 * 256 )
43- mask := []byte {255 , 255 , 255 , 0 }
44- for i := 0 ; i < 256 ; i ++ {
45- for j := 0 ; j < 256 ; j ++ {
46- pl = append (pl , & net.IPNet {IP : []byte {10 , byte (i ), byte (j ), 0 }, Mask : mask })
47- }
85+ func copyIP (from net.IP ) net.IP {
86+ ip := make ([]byte , len (from ))
87+ copy (ip , from )
88+ return ip
89+ }
90+
91+ func addIntToIP (array net.IP , ordinal uint ) {
92+ for i := len (array ) - 1 ; i >= 0 ; i -- {
93+ array [i ] |= (byte )(ordinal & 0xff )
94+ ordinal >>= 8
4895 }
49- return pl
5096}
0 commit comments