allocator.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. package ipam
  2. import (
  3. "fmt"
  4. "net"
  5. "sort"
  6. "sync"
  7. "github.com/docker/docker/libnetwork/bitseq"
  8. "github.com/docker/docker/libnetwork/ipamapi"
  9. "github.com/docker/docker/libnetwork/types"
  10. "github.com/sirupsen/logrus"
  11. )
  12. const (
  13. localAddressSpace = "LocalDefault"
  14. globalAddressSpace = "GlobalDefault"
  15. )
  16. // Allocator provides per address space ipv4/ipv6 book keeping
  17. type Allocator struct {
  18. // Predefined pools for default address spaces
  19. // Separate from the addrSpace because they should not be serialized
  20. predefined map[string][]*net.IPNet
  21. predefinedStartIndices map[string]int
  22. // The address spaces
  23. addrSpaces map[string]*addrSpace
  24. // Allocated addresses in each address space's subnet
  25. addresses map[SubnetKey]*bitseq.Handle
  26. sync.Mutex
  27. }
  28. // NewAllocator returns an instance of libnetwork ipam
  29. func NewAllocator(lcAs, glAs []*net.IPNet) (*Allocator, error) {
  30. a := &Allocator{
  31. predefined: map[string][]*net.IPNet{
  32. localAddressSpace: lcAs,
  33. globalAddressSpace: glAs,
  34. },
  35. predefinedStartIndices: map[string]int{},
  36. addresses: map[SubnetKey]*bitseq.Handle{},
  37. }
  38. a.addrSpaces = map[string]*addrSpace{
  39. localAddressSpace: a.newAddressSpace(),
  40. globalAddressSpace: a.newAddressSpace(),
  41. }
  42. return a, nil
  43. }
  44. func (a *Allocator) newAddressSpace() *addrSpace {
  45. return &addrSpace{
  46. subnets: map[SubnetKey]*PoolData{},
  47. alloc: a,
  48. }
  49. }
  50. // GetDefaultAddressSpaces returns the local and global default address spaces
  51. func (a *Allocator) GetDefaultAddressSpaces() (string, string, error) {
  52. return localAddressSpace, globalAddressSpace, nil
  53. }
  54. // RequestPool returns an address pool along with its unique id.
  55. // addressSpace must be a valid address space name and must not be the empty string.
  56. // If pool is the empty string then the default predefined pool for addressSpace will be used, otherwise pool must be a valid IP address and length in CIDR notation.
  57. // If subPool is not empty, it must be a valid IP address and length in CIDR notation which is a sub-range of pool.
  58. // subPool must be empty if pool is empty.
  59. func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
  60. logrus.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6)
  61. k, nw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6)
  62. if err != nil {
  63. return "", nil, nil, types.InternalErrorf("failed to parse pool request for address space %q pool %q subpool %q: %v", addressSpace, pool, subPool, err)
  64. }
  65. pdf := k == nil
  66. retry:
  67. if pdf {
  68. if nw, err = a.getPredefinedPool(addressSpace, v6); err != nil {
  69. return "", nil, nil, err
  70. }
  71. k = &SubnetKey{AddressSpace: addressSpace, Subnet: nw.String()}
  72. }
  73. aSpace, err := a.getAddrSpace(addressSpace)
  74. if err != nil {
  75. return "", nil, nil, err
  76. }
  77. insert, err := aSpace.updatePoolDBOnAdd(*k, nw, ipr, pdf)
  78. if err != nil {
  79. if _, ok := err.(types.MaskableError); ok {
  80. logrus.Debugf("Retrying predefined pool search: %v", err)
  81. goto retry
  82. }
  83. return "", nil, nil, err
  84. }
  85. return k.String(), nw, nil, insert()
  86. }
  87. // ReleasePool releases the address pool identified by the passed id
  88. func (a *Allocator) ReleasePool(poolID string) error {
  89. logrus.Debugf("ReleasePool(%s)", poolID)
  90. k := SubnetKey{}
  91. if err := k.FromString(poolID); err != nil {
  92. return types.BadRequestErrorf("invalid pool id: %s", poolID)
  93. }
  94. aSpace, err := a.getAddrSpace(k.AddressSpace)
  95. if err != nil {
  96. return err
  97. }
  98. return aSpace.updatePoolDBOnRemoval(k)
  99. }
  100. // Given the address space, returns the local or global PoolConfig based on whether the
  101. // address space is local or global. AddressSpace locality is registered with IPAM out of band.
  102. func (a *Allocator) getAddrSpace(as string) (*addrSpace, error) {
  103. a.Lock()
  104. defer a.Unlock()
  105. aSpace, ok := a.addrSpaces[as]
  106. if !ok {
  107. return nil, types.BadRequestErrorf("cannot find address space %s", as)
  108. }
  109. return aSpace, nil
  110. }
  111. // parsePoolRequest parses and validates a request to create a new pool under addressSpace and returns
  112. // a SubnetKey, network and range describing the request.
  113. func (a *Allocator) parsePoolRequest(addressSpace, pool, subPool string, v6 bool) (*SubnetKey, *net.IPNet, *AddressRange, error) {
  114. var (
  115. nw *net.IPNet
  116. ipr *AddressRange
  117. err error
  118. )
  119. if addressSpace == "" {
  120. return nil, nil, nil, ipamapi.ErrInvalidAddressSpace
  121. }
  122. if pool == "" && subPool != "" {
  123. return nil, nil, nil, ipamapi.ErrInvalidSubPool
  124. }
  125. if pool == "" {
  126. return nil, nil, nil, nil
  127. }
  128. if _, nw, err = net.ParseCIDR(pool); err != nil {
  129. return nil, nil, nil, ipamapi.ErrInvalidPool
  130. }
  131. if subPool != "" {
  132. if ipr, err = getAddressRange(subPool, nw); err != nil {
  133. return nil, nil, nil, err
  134. }
  135. }
  136. return &SubnetKey{AddressSpace: addressSpace, Subnet: nw.String(), ChildSubnet: subPool}, nw, ipr, nil
  137. }
  138. func (a *Allocator) insertBitMask(key SubnetKey, pool *net.IPNet) error {
  139. //logrus.Debugf("Inserting bitmask (%s, %s)", key.String(), pool.String())
  140. ipVer := getAddressVersion(pool.IP)
  141. ones, bits := pool.Mask.Size()
  142. numAddresses := uint64(1 << uint(bits-ones))
  143. // Allow /64 subnet
  144. if ipVer == v6 && numAddresses == 0 {
  145. numAddresses--
  146. }
  147. // Generate the new address masks.
  148. h, err := bitseq.NewHandle("", nil, "", numAddresses)
  149. if err != nil {
  150. return err
  151. }
  152. // Pre-reserve the network address on IPv4 networks large
  153. // enough to have one (i.e., anything bigger than a /31.
  154. if !(ipVer == v4 && numAddresses <= 2) {
  155. h.Set(0)
  156. }
  157. // Pre-reserve the broadcast address on IPv4 networks large
  158. // enough to have one (i.e., anything bigger than a /31).
  159. if ipVer == v4 && numAddresses > 2 {
  160. h.Set(numAddresses - 1)
  161. }
  162. a.Lock()
  163. a.addresses[key] = h
  164. a.Unlock()
  165. return nil
  166. }
  167. func (a *Allocator) retrieveBitmask(k SubnetKey, n *net.IPNet) (*bitseq.Handle, error) {
  168. a.Lock()
  169. bm, ok := a.addresses[k]
  170. a.Unlock()
  171. if !ok {
  172. logrus.Debugf("Retrieving bitmask (%s, %s)", k.String(), n.String())
  173. if err := a.insertBitMask(k, n); err != nil {
  174. return nil, types.InternalErrorf("could not find bitmask for %s", k.String())
  175. }
  176. a.Lock()
  177. bm = a.addresses[k]
  178. a.Unlock()
  179. }
  180. return bm, nil
  181. }
  182. func (a *Allocator) getPredefineds(as string) []*net.IPNet {
  183. a.Lock()
  184. defer a.Unlock()
  185. p := a.predefined[as]
  186. i := a.predefinedStartIndices[as]
  187. // defensive in case the list changed since last update
  188. if i >= len(p) {
  189. i = 0
  190. }
  191. return append(p[i:], p[:i]...)
  192. }
  193. func (a *Allocator) updateStartIndex(as string, amt int) {
  194. a.Lock()
  195. i := a.predefinedStartIndices[as] + amt
  196. if i < 0 || i >= len(a.predefined[as]) {
  197. i = 0
  198. }
  199. a.predefinedStartIndices[as] = i
  200. a.Unlock()
  201. }
  202. func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error) {
  203. var v ipVersion
  204. v = v4
  205. if ipV6 {
  206. v = v6
  207. }
  208. if as != localAddressSpace && as != globalAddressSpace {
  209. return nil, types.NotImplementedErrorf("no default pool available for non-default address spaces")
  210. }
  211. aSpace, err := a.getAddrSpace(as)
  212. if err != nil {
  213. return nil, err
  214. }
  215. predefined := a.getPredefineds(as)
  216. aSpace.Lock()
  217. for i, nw := range predefined {
  218. if v != getAddressVersion(nw.IP) {
  219. continue
  220. }
  221. // Checks whether pool has already been allocated
  222. if _, ok := aSpace.subnets[SubnetKey{AddressSpace: as, Subnet: nw.String()}]; ok {
  223. continue
  224. }
  225. // Shouldn't be necessary, but check prevents IP collisions should
  226. // predefined pools overlap for any reason.
  227. if !aSpace.contains(as, nw) {
  228. aSpace.Unlock()
  229. a.updateStartIndex(as, i+1)
  230. return nw, nil
  231. }
  232. }
  233. aSpace.Unlock()
  234. return nil, types.NotFoundErrorf("could not find an available, non-overlapping IPv%d address pool among the defaults to assign to the network", v)
  235. }
  236. // RequestAddress returns an address from the specified pool ID
  237. func (a *Allocator) RequestAddress(poolID string, prefAddress net.IP, opts map[string]string) (*net.IPNet, map[string]string, error) {
  238. logrus.Debugf("RequestAddress(%s, %v, %v)", poolID, prefAddress, opts)
  239. k := SubnetKey{}
  240. if err := k.FromString(poolID); err != nil {
  241. return nil, nil, types.BadRequestErrorf("invalid pool id: %s", poolID)
  242. }
  243. aSpace, err := a.getAddrSpace(k.AddressSpace)
  244. if err != nil {
  245. return nil, nil, err
  246. }
  247. aSpace.Lock()
  248. p, ok := aSpace.subnets[k]
  249. if !ok {
  250. aSpace.Unlock()
  251. return nil, nil, types.NotFoundErrorf("cannot find address pool for poolID:%s", poolID)
  252. }
  253. if prefAddress != nil && !p.Pool.Contains(prefAddress) {
  254. aSpace.Unlock()
  255. return nil, nil, ipamapi.ErrIPOutOfRange
  256. }
  257. c := p
  258. for c.Range != nil {
  259. k = c.ParentKey
  260. c = aSpace.subnets[k]
  261. }
  262. aSpace.Unlock()
  263. bm, err := a.retrieveBitmask(k, c.Pool)
  264. if err != nil {
  265. return nil, nil, types.InternalErrorf("could not find bitmask for %s on address %v request from pool %s: %v",
  266. k.String(), prefAddress, poolID, err)
  267. }
  268. // In order to request for a serial ip address allocation, callers can pass in the option to request
  269. // IP allocation serially or first available IP in the subnet
  270. var serial bool
  271. if opts != nil {
  272. if val, ok := opts[ipamapi.AllocSerialPrefix]; ok {
  273. serial = (val == "true")
  274. }
  275. }
  276. ip, err := a.getAddress(p.Pool, bm, prefAddress, p.Range, serial)
  277. if err != nil {
  278. return nil, nil, err
  279. }
  280. return &net.IPNet{IP: ip, Mask: p.Pool.Mask}, nil, nil
  281. }
  282. // ReleaseAddress releases the address from the specified pool ID
  283. func (a *Allocator) ReleaseAddress(poolID string, address net.IP) error {
  284. logrus.Debugf("ReleaseAddress(%s, %v)", poolID, address)
  285. k := SubnetKey{}
  286. if err := k.FromString(poolID); err != nil {
  287. return types.BadRequestErrorf("invalid pool id: %s", poolID)
  288. }
  289. aSpace, err := a.getAddrSpace(k.AddressSpace)
  290. if err != nil {
  291. return err
  292. }
  293. aSpace.Lock()
  294. p, ok := aSpace.subnets[k]
  295. if !ok {
  296. aSpace.Unlock()
  297. return types.NotFoundErrorf("cannot find address pool for poolID:%s", poolID)
  298. }
  299. if address == nil {
  300. aSpace.Unlock()
  301. return types.BadRequestErrorf("invalid address: nil")
  302. }
  303. if !p.Pool.Contains(address) {
  304. aSpace.Unlock()
  305. return ipamapi.ErrIPOutOfRange
  306. }
  307. c := p
  308. for c.Range != nil {
  309. k = c.ParentKey
  310. c = aSpace.subnets[k]
  311. }
  312. aSpace.Unlock()
  313. mask := p.Pool.Mask
  314. h, err := types.GetHostPartIP(address, mask)
  315. if err != nil {
  316. return types.InternalErrorf("failed to release address %s: %v", address.String(), err)
  317. }
  318. bm, err := a.retrieveBitmask(k, c.Pool)
  319. if err != nil {
  320. return types.InternalErrorf("could not find bitmask for %s on address %v release from pool %s: %v",
  321. k.String(), address, poolID, err)
  322. }
  323. defer logrus.Debugf("Released address PoolID:%s, Address:%v Sequence:%s", poolID, address, bm.String())
  324. return bm.Unset(ipToUint64(h))
  325. }
  326. func (a *Allocator) getAddress(nw *net.IPNet, bitmask *bitseq.Handle, prefAddress net.IP, ipr *AddressRange, serial bool) (net.IP, error) {
  327. var (
  328. ordinal uint64
  329. err error
  330. base *net.IPNet
  331. )
  332. logrus.Debugf("Request address PoolID:%v %s Serial:%v PrefAddress:%v ", nw, bitmask.String(), serial, prefAddress)
  333. base = types.GetIPNetCopy(nw)
  334. if bitmask.Unselected() == 0 {
  335. return nil, ipamapi.ErrNoAvailableIPs
  336. }
  337. if ipr == nil && prefAddress == nil {
  338. ordinal, err = bitmask.SetAny(serial)
  339. } else if prefAddress != nil {
  340. hostPart, e := types.GetHostPartIP(prefAddress, base.Mask)
  341. if e != nil {
  342. return nil, types.InternalErrorf("failed to allocate requested address %s: %v", prefAddress.String(), e)
  343. }
  344. ordinal = ipToUint64(types.GetMinimalIP(hostPart))
  345. err = bitmask.Set(ordinal)
  346. } else {
  347. ordinal, err = bitmask.SetAnyInRange(ipr.Start, ipr.End, serial)
  348. }
  349. switch err {
  350. case nil:
  351. // Convert IP ordinal for this subnet into IP address
  352. return generateAddress(ordinal, base), nil
  353. case bitseq.ErrBitAllocated:
  354. return nil, ipamapi.ErrIPAlreadyAllocated
  355. case bitseq.ErrNoBitAvailable:
  356. return nil, ipamapi.ErrNoAvailableIPs
  357. default:
  358. return nil, err
  359. }
  360. }
  361. // DumpDatabase dumps the internal info
  362. func (a *Allocator) DumpDatabase() string {
  363. a.Lock()
  364. aspaces := make(map[string]*addrSpace, len(a.addrSpaces))
  365. orderedAS := make([]string, 0, len(a.addrSpaces))
  366. for as, aSpace := range a.addrSpaces {
  367. orderedAS = append(orderedAS, as)
  368. aspaces[as] = aSpace
  369. }
  370. a.Unlock()
  371. sort.Strings(orderedAS)
  372. var s string
  373. for _, as := range orderedAS {
  374. aSpace := aspaces[as]
  375. s = fmt.Sprintf("\n\n%s Config", as)
  376. aSpace.Lock()
  377. for k, config := range aSpace.subnets {
  378. s += fmt.Sprintf("\n%v: %v", k, config)
  379. if config.Range == nil {
  380. a.retrieveBitmask(k, config.Pool)
  381. }
  382. }
  383. aSpace.Unlock()
  384. }
  385. s = fmt.Sprintf("%s\n\nBitmasks", s)
  386. for k, bm := range a.addresses {
  387. s += fmt.Sprintf("\n%s: %s", k, bm)
  388. }
  389. return s
  390. }
  391. // IsBuiltIn returns true for builtin drivers
  392. func (a *Allocator) IsBuiltIn() bool {
  393. return true
  394. }