network.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. package libnetwork
  2. import (
  3. "encoding/json"
  4. "net"
  5. "sync"
  6. log "github.com/Sirupsen/logrus"
  7. "github.com/docker/docker/pkg/stringid"
  8. "github.com/docker/libnetwork/config"
  9. "github.com/docker/libnetwork/datastore"
  10. "github.com/docker/libnetwork/driverapi"
  11. "github.com/docker/libnetwork/etchosts"
  12. "github.com/docker/libnetwork/netlabel"
  13. "github.com/docker/libnetwork/options"
  14. "github.com/docker/libnetwork/types"
  15. )
  16. // A Network represents a logical connectivity zone that containers may
  17. // join using the Link method. A Network is managed by a specific driver.
  18. type Network interface {
  19. // A user chosen name for this network.
  20. Name() string
  21. // A system generated id for this network.
  22. ID() string
  23. // The type of network, which corresponds to its managing driver.
  24. Type() string
  25. // Create a new endpoint to this network symbolically identified by the
  26. // specified unique name. The options parameter carry driver specific options.
  27. // Labels support will be added in the near future.
  28. CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error)
  29. // Delete the network.
  30. Delete() error
  31. // Endpoints returns the list of Endpoint(s) in this network.
  32. Endpoints() []Endpoint
  33. // WalkEndpoints uses the provided function to walk the Endpoints
  34. WalkEndpoints(walker EndpointWalker)
  35. // EndpointByName returns the Endpoint which has the passed name. If not found, the error ErrNoSuchEndpoint is returned.
  36. EndpointByName(name string) (Endpoint, error)
  37. // EndpointByID returns the Endpoint which has the passed id. If not found, the error ErrNoSuchEndpoint is returned.
  38. EndpointByID(id string) (Endpoint, error)
  39. }
  40. // EndpointWalker is a client provided function which will be used to walk the Endpoints.
  41. // When the function returns true, the walk will stop.
  42. type EndpointWalker func(ep Endpoint) bool
  43. type svcMap map[string]net.IP
  44. // IpamConf contains all the ipam related configurations for a network
  45. type IpamConf struct {
  46. PreferredPool string
  47. SubPool string
  48. Options map[string]string // IPAM input options
  49. IsV6 bool
  50. Gateway string
  51. AuxAddresses map[string]string
  52. }
  53. // Validate checks whether the configuration is valid
  54. func (c *IpamConf) Validate() error {
  55. if c.Gateway != "" && nil == net.ParseIP(c.Gateway) {
  56. return types.BadRequestErrorf("invalid gateway address %s in IpamConf dtructure", c.Gateway)
  57. }
  58. return nil
  59. }
  60. // IpamInfo contains all the ipam related operational info for a network
  61. type IpamInfo struct {
  62. PoolID string
  63. Meta map[string]string
  64. driverapi.IPAMData
  65. }
  66. // MarshalJSON encodes IpamInfo into json message
  67. func (i *IpamInfo) MarshalJSON() ([]byte, error) {
  68. m := map[string]interface{}{
  69. "PoolID": i.PoolID,
  70. }
  71. v, err := json.Marshal(&i.IPAMData)
  72. if err != nil {
  73. return nil, err
  74. }
  75. m["IPAMData"] = string(v)
  76. if i.Meta != nil {
  77. m["Meta"] = i.Meta
  78. }
  79. return json.Marshal(m)
  80. }
  81. // UnmarshalJSON decodes json message into PoolData
  82. func (i *IpamInfo) UnmarshalJSON(data []byte) error {
  83. var (
  84. m map[string]interface{}
  85. err error
  86. )
  87. if err = json.Unmarshal(data, &m); err != nil {
  88. return err
  89. }
  90. i.PoolID = m["PoolID"].(string)
  91. if v, ok := m["Meta"]; ok {
  92. b, _ := json.Marshal(v)
  93. if err = json.Unmarshal(b, &i.Meta); err != nil {
  94. return err
  95. }
  96. }
  97. if v, ok := m["IPAMData"]; ok {
  98. if err = json.Unmarshal([]byte(v.(string)), &i.IPAMData); err != nil {
  99. return err
  100. }
  101. }
  102. return nil
  103. }
  104. type network struct {
  105. ctrlr *controller
  106. name string
  107. networkType string
  108. id string
  109. ipamType string
  110. driver driverapi.Driver
  111. addrSpace string
  112. ipamV4Config []*IpamConf
  113. ipamV6Config []*IpamConf
  114. ipamV4Info []*IpamInfo
  115. ipamV6Info []*IpamInfo
  116. enableIPv6 bool
  117. endpointCnt uint64
  118. endpoints endpointTable
  119. generic options.Generic
  120. dbIndex uint64
  121. svcRecords svcMap
  122. dbExists bool
  123. persist bool
  124. stopWatchCh chan struct{}
  125. dataScope datastore.DataScope
  126. sync.Mutex
  127. }
  128. func (n *network) Name() string {
  129. n.Lock()
  130. defer n.Unlock()
  131. return n.name
  132. }
  133. func (n *network) ID() string {
  134. n.Lock()
  135. defer n.Unlock()
  136. return n.id
  137. }
  138. func (n *network) Type() string {
  139. n.Lock()
  140. defer n.Unlock()
  141. if n.driver == nil {
  142. return ""
  143. }
  144. return n.driver.Type()
  145. }
  146. func (n *network) Key() []string {
  147. n.Lock()
  148. defer n.Unlock()
  149. return []string{datastore.NetworkKeyPrefix, n.id}
  150. }
  151. func (n *network) KeyPrefix() []string {
  152. return []string{datastore.NetworkKeyPrefix}
  153. }
  154. func (n *network) Value() []byte {
  155. n.Lock()
  156. defer n.Unlock()
  157. b, err := json.Marshal(n)
  158. if err != nil {
  159. return nil
  160. }
  161. return b
  162. }
  163. func (n *network) SetValue(value []byte) error {
  164. return json.Unmarshal(value, n)
  165. }
  166. func (n *network) Index() uint64 {
  167. n.Lock()
  168. defer n.Unlock()
  169. return n.dbIndex
  170. }
  171. func (n *network) SetIndex(index uint64) {
  172. n.Lock()
  173. n.dbIndex = index
  174. n.dbExists = true
  175. n.Unlock()
  176. }
  177. func (n *network) Exists() bool {
  178. n.Lock()
  179. defer n.Unlock()
  180. return n.dbExists
  181. }
  182. func (n *network) Skip() bool {
  183. n.Lock()
  184. defer n.Unlock()
  185. return !n.persist
  186. }
  187. func (n *network) DataScope() datastore.DataScope {
  188. n.Lock()
  189. defer n.Unlock()
  190. return n.dataScope
  191. }
  192. func (n *network) EndpointCnt() uint64 {
  193. n.Lock()
  194. defer n.Unlock()
  195. return n.endpointCnt
  196. }
  197. func (n *network) IncEndpointCnt() {
  198. n.Lock()
  199. n.endpointCnt++
  200. n.Unlock()
  201. }
  202. func (n *network) DecEndpointCnt() {
  203. n.Lock()
  204. n.endpointCnt--
  205. n.Unlock()
  206. }
  207. // TODO : Can be made much more generic with the help of reflection (but has some golang limitations)
  208. func (n *network) MarshalJSON() ([]byte, error) {
  209. netMap := make(map[string]interface{})
  210. netMap["name"] = n.name
  211. netMap["id"] = n.id
  212. netMap["networkType"] = n.networkType
  213. netMap["ipamType"] = n.ipamType
  214. netMap["addrSpace"] = n.addrSpace
  215. netMap["endpointCnt"] = n.endpointCnt
  216. netMap["enableIPv6"] = n.enableIPv6
  217. if n.generic != nil {
  218. netMap["generic"] = n.generic
  219. }
  220. netMap["persist"] = n.persist
  221. if len(n.ipamV4Config) > 0 {
  222. ics, err := json.Marshal(n.ipamV4Config)
  223. if err != nil {
  224. return nil, err
  225. }
  226. netMap["ipamV4Config"] = string(ics)
  227. }
  228. if len(n.ipamV4Info) > 0 {
  229. iis, err := json.Marshal(n.ipamV4Info)
  230. if err != nil {
  231. return nil, err
  232. }
  233. netMap["ipamV4Info"] = string(iis)
  234. }
  235. if len(n.ipamV6Config) > 0 {
  236. ics, err := json.Marshal(n.ipamV6Config)
  237. if err != nil {
  238. return nil, err
  239. }
  240. netMap["ipamV6Config"] = string(ics)
  241. }
  242. if len(n.ipamV6Info) > 0 {
  243. iis, err := json.Marshal(n.ipamV6Info)
  244. if err != nil {
  245. return nil, err
  246. }
  247. netMap["ipamV6Info"] = string(iis)
  248. }
  249. return json.Marshal(netMap)
  250. }
  251. // TODO : Can be made much more generic with the help of reflection (but has some golang limitations)
  252. func (n *network) UnmarshalJSON(b []byte) (err error) {
  253. var netMap map[string]interface{}
  254. if err := json.Unmarshal(b, &netMap); err != nil {
  255. return err
  256. }
  257. n.name = netMap["name"].(string)
  258. n.id = netMap["id"].(string)
  259. n.ipamType = netMap["ipamType"].(string)
  260. n.addrSpace = netMap["addrSpace"].(string)
  261. n.networkType = netMap["networkType"].(string)
  262. n.endpointCnt = uint64(netMap["endpointCnt"].(float64))
  263. n.enableIPv6 = netMap["enableIPv6"].(bool)
  264. if v, ok := netMap["generic"]; ok {
  265. n.generic = v.(map[string]interface{})
  266. }
  267. if v, ok := netMap["persist"]; ok {
  268. n.persist = v.(bool)
  269. }
  270. if v, ok := netMap["ipamV4Config"]; ok {
  271. if err := json.Unmarshal([]byte(v.(string)), &n.ipamV4Config); err != nil {
  272. return err
  273. }
  274. }
  275. if v, ok := netMap["ipamV4Info"]; ok {
  276. if err := json.Unmarshal([]byte(v.(string)), &n.ipamV4Info); err != nil {
  277. return err
  278. }
  279. }
  280. if v, ok := netMap["ipamV6Config"]; ok {
  281. if err := json.Unmarshal([]byte(v.(string)), &n.ipamV6Config); err != nil {
  282. return err
  283. }
  284. }
  285. if v, ok := netMap["ipamV6Info"]; ok {
  286. if err := json.Unmarshal([]byte(v.(string)), &n.ipamV6Info); err != nil {
  287. return err
  288. }
  289. }
  290. return nil
  291. }
  292. // NetworkOption is a option setter function type used to pass varios options to
  293. // NewNetwork method. The various setter functions of type NetworkOption are
  294. // provided by libnetwork, they look like NetworkOptionXXXX(...)
  295. type NetworkOption func(n *network)
  296. // NetworkOptionGeneric function returns an option setter for a Generic option defined
  297. // in a Dictionary of Key-Value pair
  298. func NetworkOptionGeneric(generic map[string]interface{}) NetworkOption {
  299. return func(n *network) {
  300. n.generic = generic
  301. if _, ok := generic[netlabel.EnableIPv6]; ok {
  302. n.enableIPv6 = generic[netlabel.EnableIPv6].(bool)
  303. }
  304. }
  305. }
  306. // NetworkOptionPersist returns an option setter to set persistence policy for a network
  307. func NetworkOptionPersist(persist bool) NetworkOption {
  308. return func(n *network) {
  309. n.persist = persist
  310. }
  311. }
  312. // NetworkOptionIpam function returns an option setter for the ipam configuration for this network
  313. func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ipV6 []*IpamConf) NetworkOption {
  314. return func(n *network) {
  315. n.ipamType = ipamDriver
  316. n.addrSpace = addrSpace
  317. n.ipamV4Config = ipV4
  318. n.ipamV6Config = ipV6
  319. }
  320. }
  321. func (n *network) processOptions(options ...NetworkOption) {
  322. for _, opt := range options {
  323. if opt != nil {
  324. opt(n)
  325. }
  326. }
  327. }
  328. func (n *network) Delete() error {
  329. var err error
  330. ctrlr := n.getController()
  331. ctrlr.Lock()
  332. _, ok := ctrlr.networks[n.id]
  333. ctrlr.Unlock()
  334. if !ok {
  335. return &UnknownNetworkError{name: n.name, id: n.id}
  336. }
  337. numEps := n.EndpointCnt()
  338. if numEps != 0 {
  339. return &ActiveEndpointsError{name: n.name, id: n.id}
  340. }
  341. // deleteNetworkFromStore performs an atomic delete operation and the network.endpointCnt field will help
  342. // prevent any possible race between endpoint join and network delete
  343. if err = ctrlr.deleteFromStore(n); err != nil {
  344. if err == datastore.ErrKeyModified {
  345. return types.InternalErrorf("operation in progress. delete failed for network %s. Please try again.")
  346. }
  347. return err
  348. }
  349. defer func() {
  350. if err != nil {
  351. n.dbExists = false
  352. if e := ctrlr.updateToStore(n); e != nil {
  353. log.Warnf("failed to recreate network in store %s : %v", n.name, e)
  354. }
  355. }
  356. }()
  357. if err = n.deleteNetwork(); err != nil {
  358. return err
  359. }
  360. n.ipamRelease()
  361. return nil
  362. }
  363. func (n *network) deleteNetwork() error {
  364. n.Lock()
  365. id := n.id
  366. d := n.driver
  367. n.ctrlr.Lock()
  368. delete(n.ctrlr.networks, id)
  369. n.ctrlr.Unlock()
  370. n.Unlock()
  371. if err := d.DeleteNetwork(n.id); err != nil {
  372. // Forbidden Errors should be honored
  373. if _, ok := err.(types.ForbiddenError); ok {
  374. n.ctrlr.Lock()
  375. n.ctrlr.networks[n.id] = n
  376. n.ctrlr.Unlock()
  377. return err
  378. }
  379. log.Warnf("driver error deleting network %s : %v", n.name, err)
  380. }
  381. n.stopWatch()
  382. return nil
  383. }
  384. func (n *network) addEndpoint(ep *endpoint) error {
  385. var err error
  386. n.Lock()
  387. n.endpoints[ep.id] = ep
  388. d := n.driver
  389. n.Unlock()
  390. defer func() {
  391. if err != nil {
  392. n.Lock()
  393. delete(n.endpoints, ep.id)
  394. n.Unlock()
  395. }
  396. }()
  397. err = d.CreateEndpoint(n.id, ep.id, ep.Interface(), ep.generic)
  398. if err != nil {
  399. return types.InternalErrorf("failed to create endpoint %s on network %s: %v", ep.Name(), n.Name(), err)
  400. }
  401. n.updateSvcRecord(ep, true)
  402. return nil
  403. }
  404. func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) {
  405. var err error
  406. if !config.IsValidName(name) {
  407. return nil, ErrInvalidName(name)
  408. }
  409. if _, err = n.EndpointByName(name); err == nil {
  410. return nil, types.ForbiddenErrorf("service endpoint with name %s already exists", name)
  411. }
  412. ep := &endpoint{name: name, generic: make(map[string]interface{}), iface: &endpointInterface{}}
  413. ep.id = stringid.GenerateRandomID()
  414. ep.network = n
  415. ep.processOptions(options...)
  416. if err = ep.assignAddress(); err != nil {
  417. return nil, err
  418. }
  419. defer func() {
  420. if err != nil {
  421. ep.releaseAddress()
  422. }
  423. }()
  424. ctrlr := n.getController()
  425. n.IncEndpointCnt()
  426. if err = ctrlr.updateToStore(n); err != nil {
  427. return nil, err
  428. }
  429. defer func() {
  430. if err != nil {
  431. n.DecEndpointCnt()
  432. if err = ctrlr.updateToStore(n); err != nil {
  433. log.Warnf("endpoint count cleanup failed when updating network for %s : %v", name, err)
  434. }
  435. }
  436. }()
  437. if err = n.addEndpoint(ep); err != nil {
  438. return nil, err
  439. }
  440. defer func() {
  441. if err != nil {
  442. if e := ep.Delete(); ep != nil {
  443. log.Warnf("cleaning up endpoint failed %s : %v", name, e)
  444. }
  445. }
  446. }()
  447. if !ep.isLocalScoped() {
  448. if err = ctrlr.updateToStore(ep); err != nil {
  449. return nil, err
  450. }
  451. }
  452. return ep, nil
  453. }
  454. func (n *network) Endpoints() []Endpoint {
  455. n.Lock()
  456. defer n.Unlock()
  457. list := make([]Endpoint, 0, len(n.endpoints))
  458. for _, e := range n.endpoints {
  459. list = append(list, e)
  460. }
  461. return list
  462. }
  463. func (n *network) WalkEndpoints(walker EndpointWalker) {
  464. for _, e := range n.Endpoints() {
  465. if walker(e) {
  466. return
  467. }
  468. }
  469. }
  470. func (n *network) EndpointByName(name string) (Endpoint, error) {
  471. if name == "" {
  472. return nil, ErrInvalidName(name)
  473. }
  474. var e Endpoint
  475. s := func(current Endpoint) bool {
  476. if current.Name() == name {
  477. e = current
  478. return true
  479. }
  480. return false
  481. }
  482. n.WalkEndpoints(s)
  483. if e == nil {
  484. return nil, ErrNoSuchEndpoint(name)
  485. }
  486. return e, nil
  487. }
  488. func (n *network) EndpointByID(id string) (Endpoint, error) {
  489. if id == "" {
  490. return nil, ErrInvalidID(id)
  491. }
  492. n.Lock()
  493. defer n.Unlock()
  494. if e, ok := n.endpoints[id]; ok {
  495. return e, nil
  496. }
  497. return nil, ErrNoSuchEndpoint(id)
  498. }
  499. func (n *network) isGlobalScoped() bool {
  500. return n.DataScope() == datastore.GlobalScope
  501. }
  502. func (n *network) updateSvcRecord(ep *endpoint, isAdd bool) {
  503. n.Lock()
  504. var recs []etchosts.Record
  505. if iface := ep.Iface(); iface.Address() != nil {
  506. if isAdd {
  507. n.svcRecords[ep.Name()] = iface.Address().IP
  508. n.svcRecords[ep.Name()+"."+n.name] = iface.Address().IP
  509. } else {
  510. delete(n.svcRecords, ep.Name())
  511. delete(n.svcRecords, ep.Name()+"."+n.name)
  512. }
  513. recs = append(recs, etchosts.Record{
  514. Hosts: ep.Name(),
  515. IP: iface.Address().IP.String(),
  516. })
  517. recs = append(recs, etchosts.Record{
  518. Hosts: ep.Name() + "." + n.name,
  519. IP: iface.Address().IP.String(),
  520. })
  521. }
  522. n.Unlock()
  523. // If there are no records to add or delete then simply return here
  524. if len(recs) == 0 {
  525. return
  526. }
  527. var sbList []*sandbox
  528. n.WalkEndpoints(func(e Endpoint) bool {
  529. if sb, hasSandbox := e.(*endpoint).getSandbox(); hasSandbox {
  530. sbList = append(sbList, sb)
  531. }
  532. return false
  533. })
  534. for _, sb := range sbList {
  535. if isAdd {
  536. sb.addHostsEntries(recs)
  537. } else {
  538. sb.deleteHostsEntries(recs)
  539. }
  540. }
  541. }
  542. func (n *network) getSvcRecords() []etchosts.Record {
  543. n.Lock()
  544. defer n.Unlock()
  545. var recs []etchosts.Record
  546. for h, ip := range n.svcRecords {
  547. recs = append(recs, etchosts.Record{
  548. Hosts: h,
  549. IP: ip.String(),
  550. })
  551. }
  552. return recs
  553. }
  554. func (n *network) getController() *controller {
  555. n.Lock()
  556. defer n.Unlock()
  557. return n.ctrlr
  558. }
  559. func (n *network) ipamAllocate() ([]func(), error) {
  560. var (
  561. cnl []func()
  562. err error
  563. )
  564. // For now also exclude bridge from using new ipam
  565. if n.Type() == "host" || n.Type() == "null" || n.Type() == "bridge" {
  566. return cnl, nil
  567. }
  568. ipam, err := n.getController().getIpamDriver(n.ipamType)
  569. if err != nil {
  570. return nil, err
  571. }
  572. if n.addrSpace == "" {
  573. if n.addrSpace, err = n.deriveAddressSpace(); err != nil {
  574. return nil, err
  575. }
  576. }
  577. if n.ipamV4Config == nil {
  578. n.ipamV4Config = []*IpamConf{&IpamConf{}}
  579. }
  580. n.ipamV4Info = make([]*IpamInfo, len(n.ipamV4Config))
  581. for i, cfg := range n.ipamV4Config {
  582. if err = cfg.Validate(); err != nil {
  583. return nil, err
  584. }
  585. d := &IpamInfo{}
  586. n.ipamV4Info[i] = d
  587. d.PoolID, d.Pool, d.Meta, err = ipam.RequestPool(n.addrSpace, cfg.PreferredPool, cfg.SubPool, cfg.Options, cfg.IsV6)
  588. if err != nil {
  589. return nil, err
  590. }
  591. defer func() {
  592. if err != nil {
  593. if err := ipam.ReleasePool(d.PoolID); err != nil {
  594. log.Warnf("Failed to release address pool %s after failure to create network %s (%s)", d.PoolID, n.Name(), n.ID())
  595. }
  596. }
  597. }()
  598. if gws, ok := d.Meta[netlabel.Gateway]; ok {
  599. if d.Gateway, err = types.ParseCIDR(gws); err != nil {
  600. return nil, types.BadRequestErrorf("failed to parse gateway address (%v) returned by ipam driver: %v", gws, err)
  601. }
  602. }
  603. // If user requested a specific gateway, libnetwork will allocate it
  604. // irrespective of whether ipam driver returned a gateway already.
  605. // If none of the above is true, libnetwork will allocate one.
  606. if cfg.Gateway != "" || d.Gateway == nil {
  607. if d.Gateway, _, err = ipam.RequestAddress(d.PoolID, net.ParseIP(cfg.Gateway), nil); err != nil {
  608. return nil, types.InternalErrorf("failed to allocate gateway (%v): %v", cfg.Gateway, err)
  609. }
  610. }
  611. cnl = append(cnl, func() {
  612. if err := ipam.ReleaseAddress(d.PoolID, d.Gateway.IP); err != nil {
  613. log.Warnf("Failed to release gw address %s after failure to create network %s (%s)", d.Gateway, n.Name(), n.ID())
  614. }
  615. })
  616. if cfg.AuxAddresses != nil {
  617. var ip net.IP
  618. d.IPAMData.AuxAddresses = make(map[string]*net.IPNet, len(cfg.AuxAddresses))
  619. for k, v := range cfg.AuxAddresses {
  620. if ip = net.ParseIP(v); ip == nil {
  621. return nil, types.BadRequestErrorf("non parsable secondary ip address %s (%s) passed for network %s", k, v, n.Name())
  622. }
  623. if d.IPAMData.AuxAddresses[k], _, err = ipam.RequestAddress(d.PoolID, net.ParseIP(cfg.Gateway), nil); err != nil {
  624. return nil, types.InternalErrorf("failed to allocate secondary ip address %s(%s): %v", k, v, err)
  625. }
  626. }
  627. }
  628. }
  629. return cnl, nil
  630. }
  631. func (n *network) ipamRelease() {
  632. // For now also exclude bridge from using new ipam
  633. if n.Type() == "host" || n.Type() == "null" || n.Type() == "bridge" {
  634. return
  635. }
  636. ipam, err := n.getController().getIpamDriver(n.ipamType)
  637. if err != nil {
  638. log.Warnf("Failed to retrieve ipam driver to release address pool(s) on delete of network %s (%s): %v", n.Name(), n.ID(), err)
  639. return
  640. }
  641. for _, d := range n.ipamV4Info {
  642. if d.Gateway != nil {
  643. if err := ipam.ReleaseAddress(d.PoolID, d.Gateway.IP); err != nil {
  644. log.Warnf("Failed to release gateway ip address %s on delete of network %s (%s): %v", d.Gateway.IP, n.Name(), n.ID(), err)
  645. }
  646. }
  647. if d.IPAMData.AuxAddresses != nil {
  648. for k, nw := range d.IPAMData.AuxAddresses {
  649. if err := ipam.ReleaseAddress(d.PoolID, nw.IP); err != nil {
  650. log.Warnf("Failed to release secondary ip address %s (%v) on delete of network %s (%s): %v", k, nw.IP, n.Name(), n.ID(), err)
  651. }
  652. }
  653. }
  654. if err := ipam.ReleasePool(d.PoolID); err != nil {
  655. log.Warnf("Failed to release address pool %s on delete of network %s (%s): %v", d.PoolID, n.Name(), n.ID(), err)
  656. }
  657. }
  658. }
  659. func (n *network) getIPInfo() []*IpamInfo {
  660. n.Lock()
  661. defer n.Unlock()
  662. l := make([]*IpamInfo, 0, len(n.ipamV4Info))
  663. for _, d := range n.ipamV4Info {
  664. l = append(l, d)
  665. }
  666. return l
  667. }
  668. func (n *network) getIPv4Data() []driverapi.IPAMData {
  669. l := make([]driverapi.IPAMData, 0, len(n.ipamV4Info))
  670. n.Lock()
  671. for _, d := range n.ipamV4Info {
  672. l = append(l, d.IPAMData)
  673. }
  674. n.Unlock()
  675. return l
  676. }
  677. func (n *network) getIPv6Data() []driverapi.IPAMData {
  678. l := make([]driverapi.IPAMData, 0, len(n.ipamV6Info))
  679. n.Lock()
  680. for _, d := range n.ipamV6Info {
  681. l = append(l, d.IPAMData)
  682. }
  683. n.Unlock()
  684. return l
  685. }
  686. func (n *network) deriveAddressSpace() (string, error) {
  687. c := n.getController()
  688. c.Lock()
  689. ipd, ok := c.ipamDrivers[n.ipamType]
  690. c.Unlock()
  691. if !ok {
  692. return "", types.NotFoundErrorf("could not find ipam driver %s to get default address space", n.ipamType)
  693. }
  694. if n.isGlobalScoped() {
  695. return ipd.defaultGlobalAddressSpace, nil
  696. }
  697. return ipd.defaultLocalAddressSpace, nil
  698. }