22package ipamutils
33
44import (
5+ "fmt"
56 "net"
67 "sync"
8+
9+ "github.com/sirupsen/logrus"
710)
811
912var (
@@ -13,18 +16,33 @@ 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
16-
17- initNetworksOnce sync.Once
19+ initNetworksOnce sync.Once
1820)
1921
20- // InitNetworks initializes the pre-defined networks used by the built-in IP allocator
21- func InitNetworks () {
22+ // PredefinedPools represent a set of address pools with prefix length Size.
23+ // Each pool in the set is derived from the Base pool. Base is to be passed
24+ // in CIDR format.Currently we support only local scope networks
25+ // Example: a Base "10.10.0.0/16 with Size 24 will define the set of 256
26+ // 10.10.[0-255].0/24 address pools
27+ type PredefinedPools struct {
28+ Base string `json:"base"`
29+ Size int `json:"size"`
30+ }
31+
32+ // InitNetworks initializes the local predefined address pools
33+ // with the default values.
34+ func InitNetworks (defaultAddressPool []* PredefinedPools ) {
2235 initNetworksOnce .Do (func () {
36+ if defaultAddressPool != nil {
37+ if err := InitAddressPools (defaultAddressPool ); err != nil {
38+ logrus .WithError (err ).Error ("InitAddressPools failed to initialize the default address pool" )
39+ }
40+ return
41+ }
2342 PredefinedBroadNetworks = initBroadPredefinedNetworks ()
2443 PredefinedGranularNetworks = initGranularPredefinedNetworks ()
2544 })
2645}
27-
2846func initBroadPredefinedNetworks () []* net.IPNet {
2947 pl := make ([]* net.IPNet , 0 , 31 )
3048 mask := []byte {255 , 255 , 0 , 0 }
@@ -48,3 +66,55 @@ func initGranularPredefinedNetworks() []*net.IPNet {
4866 }
4967 return pl
5068}
69+
70+ // InitAddressPools allows to initialize the local scope predefined
71+ // address pools to the desired values. It fails is invalid input is passed
72+ // or if the predefined pools were already initialized.
73+ func InitAddressPools (list []* PredefinedPools ) error {
74+ localPools := make ([]* net.IPNet , 0 , len (list ))
75+
76+ for _ , p := range list {
77+ if p == nil {
78+ continue
79+ }
80+ _ , b , err := net .ParseCIDR (p .Base )
81+ if err != nil {
82+ return fmt .Errorf ("invalid base pool %q: %v" , p .Base , err )
83+ }
84+ ones , _ := b .Mask .Size ()
85+ if p .Size <= 0 || p .Size < ones {
86+ return fmt .Errorf ("invalid pools size: %d" , p .Size )
87+ }
88+ localPools = append (localPools , initPools (p .Size , b )... )
89+ }
90+ PredefinedBroadNetworks = localPools
91+ return nil
92+ }
93+
94+ func initPools (size int , base * net.IPNet ) []* net.IPNet {
95+ one , bits := base .Mask .Size ()
96+ mask := net .CIDRMask (size , bits )
97+ n := 1 << uint (size - one )
98+ s := uint (bits - size )
99+ list := make ([]* net.IPNet , 0 , n )
100+
101+ for i := 0 ; i < n ; i ++ {
102+ ip := copyIP (base .IP )
103+ addIntToIP (ip , uint (i << s ))
104+ list = append (list , & net.IPNet {IP : ip , Mask : mask })
105+ }
106+ return list
107+ }
108+
109+ func copyIP (from net.IP ) net.IP {
110+ ip := make ([]byte , len (from ))
111+ copy (ip , from )
112+ return ip
113+ }
114+
115+ func addIntToIP (array net.IP , ordinal uint ) {
116+ for i := len (array ) - 1 ; i >= 0 ; i -- {
117+ array [i ] |= (byte )(ordinal & 0xff )
118+ ordinal >>= 8
119+ }
120+ }
0 commit comments