1package libnetwork 2 3import ( 4 "encoding/json" 5 "fmt" 6 "net" 7 "strings" 8 "sync" 9 "time" 10 11 "github.com/docker/docker/pkg/stringid" 12 "github.com/docker/libnetwork/common" 13 "github.com/docker/libnetwork/config" 14 "github.com/docker/libnetwork/datastore" 15 "github.com/docker/libnetwork/driverapi" 16 "github.com/docker/libnetwork/etchosts" 17 "github.com/docker/libnetwork/ipamapi" 18 "github.com/docker/libnetwork/netlabel" 19 "github.com/docker/libnetwork/netutils" 20 "github.com/docker/libnetwork/networkdb" 21 "github.com/docker/libnetwork/options" 22 "github.com/docker/libnetwork/types" 23 "github.com/sirupsen/logrus" 24) 25 26// A Network represents a logical connectivity zone that containers may 27// join using the Link method. A Network is managed by a specific driver. 28type Network interface { 29 // A user chosen name for this network. 30 Name() string 31 32 // A system generated id for this network. 33 ID() string 34 35 // The type of network, which corresponds to its managing driver. 36 Type() string 37 38 // Create a new endpoint to this network symbolically identified by the 39 // specified unique name. The options parameter carries driver specific options. 40 CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) 41 42 // Delete the network. 43 Delete() error 44 45 // Endpoints returns the list of Endpoint(s) in this network. 46 Endpoints() []Endpoint 47 48 // WalkEndpoints uses the provided function to walk the Endpoints 49 WalkEndpoints(walker EndpointWalker) 50 51 // EndpointByName returns the Endpoint which has the passed name. If not found, the error ErrNoSuchEndpoint is returned. 52 EndpointByName(name string) (Endpoint, error) 53 54 // EndpointByID returns the Endpoint which has the passed id. If not found, the error ErrNoSuchEndpoint is returned. 55 EndpointByID(id string) (Endpoint, error) 56 57 // Return certain operational data belonging to this network 58 Info() NetworkInfo 59} 60 61// NetworkInfo returns some configuration and operational information about the network 62type NetworkInfo interface { 63 IpamConfig() (string, map[string]string, []*IpamConf, []*IpamConf) 64 IpamInfo() ([]*IpamInfo, []*IpamInfo) 65 DriverOptions() map[string]string 66 Scope() string 67 IPv6Enabled() bool 68 Internal() bool 69 Attachable() bool 70 Ingress() bool 71 ConfigFrom() string 72 ConfigOnly() bool 73 Labels() map[string]string 74 Dynamic() bool 75 Created() time.Time 76 // Peers returns a slice of PeerInfo structures which has the information about the peer 77 // nodes participating in the same overlay network. This is currently the per-network 78 // gossip cluster. For non-dynamic overlay networks and bridge networks it returns an 79 // empty slice 80 Peers() []networkdb.PeerInfo 81 //Services returns a map of services keyed by the service name with the details 82 //of all the tasks that belong to the service. Applicable only in swarm mode. 83 Services() map[string]ServiceInfo 84} 85 86// EndpointWalker is a client provided function which will be used to walk the Endpoints. 87// When the function returns true, the walk will stop. 88type EndpointWalker func(ep Endpoint) bool 89 90// ipInfo is the reverse mapping from IP to service name to serve the PTR query. 91// extResolver is set if an externl server resolves a service name to this IP. 92// Its an indication to defer PTR queries also to that external server. 93type ipInfo struct { 94 name string 95 serviceID string 96 extResolver bool 97} 98 99// svcMapEntry is the body of the element into the svcMap 100// The ip is a string because the SetMatrix does not accept non hashable values 101type svcMapEntry struct { 102 ip string 103 serviceID string 104} 105 106type svcInfo struct { 107 svcMap common.SetMatrix 108 svcIPv6Map common.SetMatrix 109 ipMap common.SetMatrix 110 service map[string][]servicePorts 111} 112 113// backing container or host's info 114type serviceTarget struct { 115 name string 116 ip net.IP 117 port uint16 118} 119 120type servicePorts struct { 121 portName string 122 proto string 123 target []serviceTarget 124} 125 126type networkDBTable struct { 127 name string 128 objType driverapi.ObjectType 129} 130 131// IpamConf contains all the ipam related configurations for a network 132type IpamConf struct { 133 // The master address pool for containers and network interfaces 134 PreferredPool string 135 // A subset of the master pool. If specified, 136 // this becomes the container pool 137 SubPool string 138 // Preferred Network Gateway address (optional) 139 Gateway string 140 // Auxiliary addresses for network driver. Must be within the master pool. 141 // libnetwork will reserve them if they fall into the container pool 142 AuxAddresses map[string]string 143} 144 145// Validate checks whether the configuration is valid 146func (c *IpamConf) Validate() error { 147 if c.Gateway != "" && nil == net.ParseIP(c.Gateway) { 148 return types.BadRequestErrorf("invalid gateway address %s in Ipam configuration", c.Gateway) 149 } 150 return nil 151} 152 153// IpamInfo contains all the ipam related operational info for a network 154type IpamInfo struct { 155 PoolID string 156 Meta map[string]string 157 driverapi.IPAMData 158} 159 160// MarshalJSON encodes IpamInfo into json message 161func (i *IpamInfo) MarshalJSON() ([]byte, error) { 162 m := map[string]interface{}{ 163 "PoolID": i.PoolID, 164 } 165 v, err := json.Marshal(&i.IPAMData) 166 if err != nil { 167 return nil, err 168 } 169 m["IPAMData"] = string(v) 170 171 if i.Meta != nil { 172 m["Meta"] = i.Meta 173 } 174 return json.Marshal(m) 175} 176 177// UnmarshalJSON decodes json message into PoolData 178func (i *IpamInfo) UnmarshalJSON(data []byte) error { 179 var ( 180 m map[string]interface{} 181 err error 182 ) 183 if err = json.Unmarshal(data, &m); err != nil { 184 return err 185 } 186 i.PoolID = m["PoolID"].(string) 187 if v, ok := m["Meta"]; ok { 188 b, _ := json.Marshal(v) 189 if err = json.Unmarshal(b, &i.Meta); err != nil { 190 return err 191 } 192 } 193 if v, ok := m["IPAMData"]; ok { 194 if err = json.Unmarshal([]byte(v.(string)), &i.IPAMData); err != nil { 195 return err 196 } 197 } 198 return nil 199} 200 201type network struct { 202 ctrlr *controller 203 name string 204 networkType string 205 id string 206 created time.Time 207 scope string // network data scope 208 labels map[string]string 209 ipamType string 210 ipamOptions map[string]string 211 addrSpace string 212 ipamV4Config []*IpamConf 213 ipamV6Config []*IpamConf 214 ipamV4Info []*IpamInfo 215 ipamV6Info []*IpamInfo 216 enableIPv6 bool 217 postIPv6 bool 218 epCnt *endpointCnt 219 generic options.Generic 220 dbIndex uint64 221 dbExists bool 222 persist bool 223 stopWatchCh chan struct{} 224 drvOnce *sync.Once 225 resolverOnce sync.Once 226 resolver []Resolver 227 internal bool 228 attachable bool 229 inDelete bool 230 ingress bool 231 driverTables []networkDBTable 232 dynamic bool 233 configOnly bool 234 configFrom string 235 loadBalancerIP net.IP 236 sync.Mutex 237} 238 239func (n *network) Name() string { 240 n.Lock() 241 defer n.Unlock() 242 243 return n.name 244} 245 246func (n *network) ID() string { 247 n.Lock() 248 defer n.Unlock() 249 250 return n.id 251} 252 253func (n *network) Created() time.Time { 254 n.Lock() 255 defer n.Unlock() 256 257 return n.created 258} 259 260func (n *network) Type() string { 261 n.Lock() 262 defer n.Unlock() 263 264 return n.networkType 265} 266 267func (n *network) Key() []string { 268 n.Lock() 269 defer n.Unlock() 270 return []string{datastore.NetworkKeyPrefix, n.id} 271} 272 273func (n *network) KeyPrefix() []string { 274 return []string{datastore.NetworkKeyPrefix} 275} 276 277func (n *network) Value() []byte { 278 n.Lock() 279 defer n.Unlock() 280 b, err := json.Marshal(n) 281 if err != nil { 282 return nil 283 } 284 return b 285} 286 287func (n *network) SetValue(value []byte) error { 288 return json.Unmarshal(value, n) 289} 290 291func (n *network) Index() uint64 { 292 n.Lock() 293 defer n.Unlock() 294 return n.dbIndex 295} 296 297func (n *network) SetIndex(index uint64) { 298 n.Lock() 299 n.dbIndex = index 300 n.dbExists = true 301 n.Unlock() 302} 303 304func (n *network) Exists() bool { 305 n.Lock() 306 defer n.Unlock() 307 return n.dbExists 308} 309 310func (n *network) Skip() bool { 311 n.Lock() 312 defer n.Unlock() 313 return !n.persist 314} 315 316func (n *network) New() datastore.KVObject { 317 n.Lock() 318 defer n.Unlock() 319 320 return &network{ 321 ctrlr: n.ctrlr, 322 drvOnce: &sync.Once{}, 323 scope: n.scope, 324 } 325} 326 327// CopyTo deep copies to the destination IpamConfig 328func (c *IpamConf) CopyTo(dstC *IpamConf) error { 329 dstC.PreferredPool = c.PreferredPool 330 dstC.SubPool = c.SubPool 331 dstC.Gateway = c.Gateway 332 if c.AuxAddresses != nil { 333 dstC.AuxAddresses = make(map[string]string, len(c.AuxAddresses)) 334 for k, v := range c.AuxAddresses { 335 dstC.AuxAddresses[k] = v 336 } 337 } 338 return nil 339} 340 341// CopyTo deep copies to the destination IpamInfo 342func (i *IpamInfo) CopyTo(dstI *IpamInfo) error { 343 dstI.PoolID = i.PoolID 344 if i.Meta != nil { 345 dstI.Meta = make(map[string]string) 346 for k, v := range i.Meta { 347 dstI.Meta[k] = v 348 } 349 } 350 351 dstI.AddressSpace = i.AddressSpace 352 dstI.Pool = types.GetIPNetCopy(i.Pool) 353 dstI.Gateway = types.GetIPNetCopy(i.Gateway) 354 355 if i.AuxAddresses != nil { 356 dstI.AuxAddresses = make(map[string]*net.IPNet) 357 for k, v := range i.AuxAddresses { 358 dstI.AuxAddresses[k] = types.GetIPNetCopy(v) 359 } 360 } 361 362 return nil 363} 364 365func (n *network) validateConfiguration() error { 366 if n.configOnly { 367 // Only supports network specific configurations. 368 // Network operator configurations are not supported. 369 if n.ingress || n.internal || n.attachable || n.scope != "" { 370 return types.ForbiddenErrorf("configuration network can only contain network " + 371 "specific fields. Network operator fields like " + 372 "[ ingress | internal | attachable | scope ] are not supported.") 373 } 374 } 375 if n.configFrom != "" { 376 if n.configOnly { 377 return types.ForbiddenErrorf("a configuration network cannot depend on another configuration network") 378 } 379 if n.ipamType != "" && 380 n.ipamType != defaultIpamForNetworkType(n.networkType) || 381 n.enableIPv6 || 382 len(n.labels) > 0 || len(n.ipamOptions) > 0 || 383 len(n.ipamV4Config) > 0 || len(n.ipamV6Config) > 0 { 384 return types.ForbiddenErrorf("user specified configurations are not supported if the network depends on a configuration network") 385 } 386 if len(n.generic) > 0 { 387 if data, ok := n.generic[netlabel.GenericData]; ok { 388 var ( 389 driverOptions map[string]string 390 opts interface{} 391 ) 392 switch data.(type) { 393 case map[string]interface{}: 394 opts = data.(map[string]interface{}) 395 case map[string]string: 396 opts = data.(map[string]string) 397 } 398 ba, err := json.Marshal(opts) 399 if err != nil { 400 return fmt.Errorf("failed to validate network configuration: %v", err) 401 } 402 if err := json.Unmarshal(ba, &driverOptions); err != nil { 403 return fmt.Errorf("failed to validate network configuration: %v", err) 404 } 405 if len(driverOptions) > 0 { 406 return types.ForbiddenErrorf("network driver options are not supported if the network depends on a configuration network") 407 } 408 } 409 } 410 } 411 return nil 412} 413 414// Applies network specific configurations 415func (n *network) applyConfigurationTo(to *network) error { 416 to.enableIPv6 = n.enableIPv6 417 if len(n.labels) > 0 { 418 to.labels = make(map[string]string, len(n.labels)) 419 for k, v := range n.labels { 420 if _, ok := to.labels[k]; !ok { 421 to.labels[k] = v 422 } 423 } 424 } 425 if len(n.ipamType) != 0 { 426 to.ipamType = n.ipamType 427 } 428 if len(n.ipamOptions) > 0 { 429 to.ipamOptions = make(map[string]string, len(n.ipamOptions)) 430 for k, v := range n.ipamOptions { 431 if _, ok := to.ipamOptions[k]; !ok { 432 to.ipamOptions[k] = v 433 } 434 } 435 } 436 if len(n.ipamV4Config) > 0 { 437 to.ipamV4Config = make([]*IpamConf, 0, len(n.ipamV4Config)) 438 to.ipamV4Config = append(to.ipamV4Config, n.ipamV4Config...) 439 } 440 if len(n.ipamV6Config) > 0 { 441 to.ipamV6Config = make([]*IpamConf, 0, len(n.ipamV6Config)) 442 to.ipamV6Config = append(to.ipamV6Config, n.ipamV6Config...) 443 } 444 if len(n.generic) > 0 { 445 to.generic = options.Generic{} 446 for k, v := range n.generic { 447 to.generic[k] = v 448 } 449 } 450 return nil 451} 452 453func (n *network) CopyTo(o datastore.KVObject) error { 454 n.Lock() 455 defer n.Unlock() 456 457 dstN := o.(*network) 458 dstN.name = n.name 459 dstN.id = n.id 460 dstN.created = n.created 461 dstN.networkType = n.networkType 462 dstN.scope = n.scope 463 dstN.dynamic = n.dynamic 464 dstN.ipamType = n.ipamType 465 dstN.enableIPv6 = n.enableIPv6 466 dstN.persist = n.persist 467 dstN.postIPv6 = n.postIPv6 468 dstN.dbIndex = n.dbIndex 469 dstN.dbExists = n.dbExists 470 dstN.drvOnce = n.drvOnce 471 dstN.internal = n.internal 472 dstN.attachable = n.attachable 473 dstN.inDelete = n.inDelete 474 dstN.ingress = n.ingress 475 dstN.configOnly = n.configOnly 476 dstN.configFrom = n.configFrom 477 dstN.loadBalancerIP = n.loadBalancerIP 478 479 // copy labels 480 if dstN.labels == nil { 481 dstN.labels = make(map[string]string, len(n.labels)) 482 } 483 for k, v := range n.labels { 484 dstN.labels[k] = v 485 } 486 487 if n.ipamOptions != nil { 488 dstN.ipamOptions = make(map[string]string, len(n.ipamOptions)) 489 for k, v := range n.ipamOptions { 490 dstN.ipamOptions[k] = v 491 } 492 } 493 494 for _, v4conf := range n.ipamV4Config { 495 dstV4Conf := &IpamConf{} 496 v4conf.CopyTo(dstV4Conf) 497 dstN.ipamV4Config = append(dstN.ipamV4Config, dstV4Conf) 498 } 499 500 for _, v4info := range n.ipamV4Info { 501 dstV4Info := &IpamInfo{} 502 v4info.CopyTo(dstV4Info) 503 dstN.ipamV4Info = append(dstN.ipamV4Info, dstV4Info) 504 } 505 506 for _, v6conf := range n.ipamV6Config { 507 dstV6Conf := &IpamConf{} 508 v6conf.CopyTo(dstV6Conf) 509 dstN.ipamV6Config = append(dstN.ipamV6Config, dstV6Conf) 510 } 511 512 for _, v6info := range n.ipamV6Info { 513 dstV6Info := &IpamInfo{} 514 v6info.CopyTo(dstV6Info) 515 dstN.ipamV6Info = append(dstN.ipamV6Info, dstV6Info) 516 } 517 518 dstN.generic = options.Generic{} 519 for k, v := range n.generic { 520 dstN.generic[k] = v 521 } 522 523 return nil 524} 525 526func (n *network) DataScope() string { 527 s := n.Scope() 528 // All swarm scope networks have local datascope 529 if s == datastore.SwarmScope { 530 s = datastore.LocalScope 531 } 532 return s 533} 534 535func (n *network) getEpCnt() *endpointCnt { 536 n.Lock() 537 defer n.Unlock() 538 539 return n.epCnt 540} 541 542// TODO : Can be made much more generic with the help of reflection (but has some golang limitations) 543func (n *network) MarshalJSON() ([]byte, error) { 544 netMap := make(map[string]interface{}) 545 netMap["name"] = n.name 546 netMap["id"] = n.id 547 netMap["created"] = n.created 548 netMap["networkType"] = n.networkType 549 netMap["scope"] = n.scope 550 netMap["labels"] = n.labels 551 netMap["ipamType"] = n.ipamType 552 netMap["ipamOptions"] = n.ipamOptions 553 netMap["addrSpace"] = n.addrSpace 554 netMap["enableIPv6"] = n.enableIPv6 555 if n.generic != nil { 556 netMap["generic"] = n.generic 557 } 558 netMap["persist"] = n.persist 559 netMap["postIPv6"] = n.postIPv6 560 if len(n.ipamV4Config) > 0 { 561 ics, err := json.Marshal(n.ipamV4Config) 562 if err != nil { 563 return nil, err 564 } 565 netMap["ipamV4Config"] = string(ics) 566 } 567 if len(n.ipamV4Info) > 0 { 568 iis, err := json.Marshal(n.ipamV4Info) 569 if err != nil { 570 return nil, err 571 } 572 netMap["ipamV4Info"] = string(iis) 573 } 574 if len(n.ipamV6Config) > 0 { 575 ics, err := json.Marshal(n.ipamV6Config) 576 if err != nil { 577 return nil, err 578 } 579 netMap["ipamV6Config"] = string(ics) 580 } 581 if len(n.ipamV6Info) > 0 { 582 iis, err := json.Marshal(n.ipamV6Info) 583 if err != nil { 584 return nil, err 585 } 586 netMap["ipamV6Info"] = string(iis) 587 } 588 netMap["internal"] = n.internal 589 netMap["attachable"] = n.attachable 590 netMap["inDelete"] = n.inDelete 591 netMap["ingress"] = n.ingress 592 netMap["configOnly"] = n.configOnly 593 netMap["configFrom"] = n.configFrom 594 netMap["loadBalancerIP"] = n.loadBalancerIP 595 return json.Marshal(netMap) 596} 597 598// TODO : Can be made much more generic with the help of reflection (but has some golang limitations) 599func (n *network) UnmarshalJSON(b []byte) (err error) { 600 var netMap map[string]interface{} 601 if err := json.Unmarshal(b, &netMap); err != nil { 602 return err 603 } 604 n.name = netMap["name"].(string) 605 n.id = netMap["id"].(string) 606 // "created" is not available in older versions 607 if v, ok := netMap["created"]; ok { 608 // n.created is time.Time but marshalled as string 609 if err = n.created.UnmarshalText([]byte(v.(string))); err != nil { 610 logrus.Warnf("failed to unmarshal creation time %v: %v", v, err) 611 n.created = time.Time{} 612 } 613 } 614 n.networkType = netMap["networkType"].(string) 615 n.enableIPv6 = netMap["enableIPv6"].(bool) 616 617 // if we weren't unmarshaling to netMap we could simply set n.labels 618 // unfortunately, we can't because map[string]interface{} != map[string]string 619 if labels, ok := netMap["labels"].(map[string]interface{}); ok { 620 n.labels = make(map[string]string, len(labels)) 621 for label, value := range labels { 622 n.labels[label] = value.(string) 623 } 624 } 625 626 if v, ok := netMap["ipamOptions"]; ok { 627 if iOpts, ok := v.(map[string]interface{}); ok { 628 n.ipamOptions = make(map[string]string, len(iOpts)) 629 for k, v := range iOpts { 630 n.ipamOptions[k] = v.(string) 631 } 632 } 633 } 634 635 if v, ok := netMap["generic"]; ok { 636 n.generic = v.(map[string]interface{}) 637 // Restore opts in their map[string]string form 638 if v, ok := n.generic[netlabel.GenericData]; ok { 639 var lmap map[string]string 640 ba, err := json.Marshal(v) 641 if err != nil { 642 return err 643 } 644 if err := json.Unmarshal(ba, &lmap); err != nil { 645 return err 646 } 647 n.generic[netlabel.GenericData] = lmap 648 } 649 } 650 if v, ok := netMap["persist"]; ok { 651 n.persist = v.(bool) 652 } 653 if v, ok := netMap["postIPv6"]; ok { 654 n.postIPv6 = v.(bool) 655 } 656 if v, ok := netMap["ipamType"]; ok { 657 n.ipamType = v.(string) 658 } else { 659 n.ipamType = ipamapi.DefaultIPAM 660 } 661 if v, ok := netMap["addrSpace"]; ok { 662 n.addrSpace = v.(string) 663 } 664 if v, ok := netMap["ipamV4Config"]; ok { 665 if err := json.Unmarshal([]byte(v.(string)), &n.ipamV4Config); err != nil { 666 return err 667 } 668 } 669 if v, ok := netMap["ipamV4Info"]; ok { 670 if err := json.Unmarshal([]byte(v.(string)), &n.ipamV4Info); err != nil { 671 return err 672 } 673 } 674 if v, ok := netMap["ipamV6Config"]; ok { 675 if err := json.Unmarshal([]byte(v.(string)), &n.ipamV6Config); err != nil { 676 return err 677 } 678 } 679 if v, ok := netMap["ipamV6Info"]; ok { 680 if err := json.Unmarshal([]byte(v.(string)), &n.ipamV6Info); err != nil { 681 return err 682 } 683 } 684 if v, ok := netMap["internal"]; ok { 685 n.internal = v.(bool) 686 } 687 if v, ok := netMap["attachable"]; ok { 688 n.attachable = v.(bool) 689 } 690 if s, ok := netMap["scope"]; ok { 691 n.scope = s.(string) 692 } 693 if v, ok := netMap["inDelete"]; ok { 694 n.inDelete = v.(bool) 695 } 696 if v, ok := netMap["ingress"]; ok { 697 n.ingress = v.(bool) 698 } 699 if v, ok := netMap["configOnly"]; ok { 700 n.configOnly = v.(bool) 701 } 702 if v, ok := netMap["configFrom"]; ok { 703 n.configFrom = v.(string) 704 } 705 if v, ok := netMap["loadBalancerIP"]; ok { 706 n.loadBalancerIP = net.ParseIP(v.(string)) 707 } 708 // Reconcile old networks with the recently added `--ipv6` flag 709 if !n.enableIPv6 { 710 n.enableIPv6 = len(n.ipamV6Info) > 0 711 } 712 return nil 713} 714 715// NetworkOption is an option setter function type used to pass various options to 716// NewNetwork method. The various setter functions of type NetworkOption are 717// provided by libnetwork, they look like NetworkOptionXXXX(...) 718type NetworkOption func(n *network) 719 720// NetworkOptionGeneric function returns an option setter for a Generic option defined 721// in a Dictionary of Key-Value pair 722func NetworkOptionGeneric(generic map[string]interface{}) NetworkOption { 723 return func(n *network) { 724 if n.generic == nil { 725 n.generic = make(map[string]interface{}) 726 } 727 if val, ok := generic[netlabel.EnableIPv6]; ok { 728 n.enableIPv6 = val.(bool) 729 } 730 if val, ok := generic[netlabel.Internal]; ok { 731 n.internal = val.(bool) 732 } 733 for k, v := range generic { 734 n.generic[k] = v 735 } 736 } 737} 738 739// NetworkOptionIngress returns an option setter to indicate if a network is 740// an ingress network. 741func NetworkOptionIngress(ingress bool) NetworkOption { 742 return func(n *network) { 743 n.ingress = ingress 744 } 745} 746 747// NetworkOptionPersist returns an option setter to set persistence policy for a network 748func NetworkOptionPersist(persist bool) NetworkOption { 749 return func(n *network) { 750 n.persist = persist 751 } 752} 753 754// NetworkOptionEnableIPv6 returns an option setter to explicitly configure IPv6 755func NetworkOptionEnableIPv6(enableIPv6 bool) NetworkOption { 756 return func(n *network) { 757 if n.generic == nil { 758 n.generic = make(map[string]interface{}) 759 } 760 n.enableIPv6 = enableIPv6 761 n.generic[netlabel.EnableIPv6] = enableIPv6 762 } 763} 764 765// NetworkOptionInternalNetwork returns an option setter to config the network 766// to be internal which disables default gateway service 767func NetworkOptionInternalNetwork() NetworkOption { 768 return func(n *network) { 769 if n.generic == nil { 770 n.generic = make(map[string]interface{}) 771 } 772 n.internal = true 773 n.generic[netlabel.Internal] = true 774 } 775} 776 777// NetworkOptionAttachable returns an option setter to set attachable for a network 778func NetworkOptionAttachable(attachable bool) NetworkOption { 779 return func(n *network) { 780 n.attachable = attachable 781 } 782} 783 784// NetworkOptionScope returns an option setter to overwrite the network's scope. 785// By default the network's scope is set to the network driver's datascope. 786func NetworkOptionScope(scope string) NetworkOption { 787 return func(n *network) { 788 n.scope = scope 789 } 790} 791 792// NetworkOptionIpam function returns an option setter for the ipam configuration for this network 793func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ipV6 []*IpamConf, opts map[string]string) NetworkOption { 794 return func(n *network) { 795 if ipamDriver != "" { 796 n.ipamType = ipamDriver 797 if ipamDriver == ipamapi.DefaultIPAM { 798 n.ipamType = defaultIpamForNetworkType(n.Type()) 799 } 800 } 801 n.ipamOptions = opts 802 n.addrSpace = addrSpace 803 n.ipamV4Config = ipV4 804 n.ipamV6Config = ipV6 805 } 806} 807 808// NetworkOptionLBEndpoint function returns an option setter for the configuration of the load balancer endpoint for this network 809func NetworkOptionLBEndpoint(ip net.IP) NetworkOption { 810 return func(n *network) { 811 n.loadBalancerIP = ip 812 } 813} 814 815// NetworkOptionDriverOpts function returns an option setter for any driver parameter described by a map 816func NetworkOptionDriverOpts(opts map[string]string) NetworkOption { 817 return func(n *network) { 818 if n.generic == nil { 819 n.generic = make(map[string]interface{}) 820 } 821 if opts == nil { 822 opts = make(map[string]string) 823 } 824 // Store the options 825 n.generic[netlabel.GenericData] = opts 826 } 827} 828 829// NetworkOptionLabels function returns an option setter for labels specific to a network 830func NetworkOptionLabels(labels map[string]string) NetworkOption { 831 return func(n *network) { 832 n.labels = labels 833 } 834} 835 836// NetworkOptionDynamic function returns an option setter for dynamic option for a network 837func NetworkOptionDynamic() NetworkOption { 838 return func(n *network) { 839 n.dynamic = true 840 } 841} 842 843// NetworkOptionDeferIPv6Alloc instructs the network to defer the IPV6 address allocation until after the endpoint has been created 844// It is being provided to support the specific docker daemon flags where user can deterministically assign an IPv6 address 845// to a container as combination of fixed-cidr-v6 + mac-address 846// TODO: Remove this option setter once we support endpoint ipam options 847func NetworkOptionDeferIPv6Alloc(enable bool) NetworkOption { 848 return func(n *network) { 849 n.postIPv6 = enable 850 } 851} 852 853// NetworkOptionConfigOnly tells controller this network is 854// a configuration only network. It serves as a configuration 855// for other networks. 856func NetworkOptionConfigOnly() NetworkOption { 857 return func(n *network) { 858 n.configOnly = true 859 } 860} 861 862// NetworkOptionConfigFrom tells controller to pick the 863// network configuration from a configuration only network 864func NetworkOptionConfigFrom(name string) NetworkOption { 865 return func(n *network) { 866 n.configFrom = name 867 } 868} 869 870func (n *network) processOptions(options ...NetworkOption) { 871 for _, opt := range options { 872 if opt != nil { 873 opt(n) 874 } 875 } 876} 877 878func (n *network) resolveDriver(name string, load bool) (driverapi.Driver, *driverapi.Capability, error) { 879 c := n.getController() 880 881 // Check if a driver for the specified network type is available 882 d, cap := c.drvRegistry.Driver(name) 883 if d == nil { 884 if load { 885 err := c.loadDriver(name) 886 if err != nil { 887 return nil, nil, err 888 } 889 890 d, cap = c.drvRegistry.Driver(name) 891 if d == nil { 892 return nil, nil, fmt.Errorf("could not resolve driver %s in registry", name) 893 } 894 } else { 895 // don't fail if driver loading is not required 896 return nil, nil, nil 897 } 898 } 899 900 return d, cap, nil 901} 902 903func (n *network) driverScope() string { 904 _, cap, err := n.resolveDriver(n.networkType, true) 905 if err != nil { 906 // If driver could not be resolved simply return an empty string 907 return "" 908 } 909 910 return cap.DataScope 911} 912 913func (n *network) driverIsMultihost() bool { 914 _, cap, err := n.resolveDriver(n.networkType, true) 915 if err != nil { 916 return false 917 } 918 return cap.ConnectivityScope == datastore.GlobalScope 919} 920 921func (n *network) driver(load bool) (driverapi.Driver, error) { 922 d, cap, err := n.resolveDriver(n.networkType, load) 923 if err != nil { 924 return nil, err 925 } 926 927 n.Lock() 928 // If load is not required, driver, cap and err may all be nil 929 if n.scope == "" && cap != nil { 930 n.scope = cap.DataScope 931 } 932 if n.dynamic { 933 // If the network is dynamic, then it is swarm 934 // scoped regardless of the backing driver. 935 n.scope = datastore.SwarmScope 936 } 937 n.Unlock() 938 return d, nil 939} 940 941func (n *network) Delete() error { 942 return n.delete(false) 943} 944 945func (n *network) delete(force bool) error { 946 n.Lock() 947 c := n.ctrlr 948 name := n.name 949 id := n.id 950 n.Unlock() 951 952 c.networkLocker.Lock(id) 953 defer c.networkLocker.Unlock(id) 954 955 n, err := c.getNetworkFromStore(id) 956 if err != nil { 957 return &UnknownNetworkError{name: name, id: id} 958 } 959 960 if len(n.loadBalancerIP) != 0 { 961 endpoints := n.Endpoints() 962 if force || (len(endpoints) == 1 && !n.ingress) { 963 n.deleteLoadBalancerSandbox() 964 } 965 //Reload the network from the store to update the epcnt. 966 n, err = c.getNetworkFromStore(id) 967 if err != nil { 968 return &UnknownNetworkError{name: name, id: id} 969 } 970 } 971 972 if !force && n.getEpCnt().EndpointCnt() != 0 { 973 if n.configOnly { 974 return types.ForbiddenErrorf("configuration network %q is in use", n.Name()) 975 } 976 return &ActiveEndpointsError{name: n.name, id: n.id} 977 } 978 979 // Mark the network for deletion 980 n.inDelete = true 981 if err = c.updateToStore(n); err != nil { 982 return fmt.Errorf("error marking network %s (%s) for deletion: %v", n.Name(), n.ID(), err) 983 } 984 985 if n.ConfigFrom() != "" { 986 if t, err := c.getConfigNetwork(n.ConfigFrom()); err == nil { 987 if err := t.getEpCnt().DecEndpointCnt(); err != nil { 988 logrus.Warnf("Failed to update reference count for configuration network %q on removal of network %q: %v", 989 t.Name(), n.Name(), err) 990 } 991 } else { 992 logrus.Warnf("Could not find configuration network %q during removal of network %q", n.configOnly, n.Name()) 993 } 994 } 995 996 if n.configOnly { 997 goto removeFromStore 998 } 999 1000 if err = n.deleteNetwork(); err != nil { 1001 if !force { 1002 return err 1003 } 1004 logrus.Debugf("driver failed to delete stale network %s (%s): %v", n.Name(), n.ID(), err) 1005 } 1006 1007 n.ipamRelease() 1008 if err = c.updateToStore(n); err != nil { 1009 logrus.Warnf("Failed to update store after ipam release for network %s (%s): %v", n.Name(), n.ID(), err) 1010 } 1011 1012 // We are about to delete the network. Leave the gossip 1013 // cluster for the network to stop all incoming network 1014 // specific gossip updates before cleaning up all the service 1015 // bindings for the network. But cleanup service binding 1016 // before deleting the network from the store since service 1017 // bindings cleanup requires the network in the store. 1018 n.cancelDriverWatches() 1019 if err = n.leaveCluster(); err != nil { 1020 logrus.Errorf("Failed leaving network %s from the agent cluster: %v", n.Name(), err) 1021 } 1022 1023 // Cleanup the service discovery for this network 1024 c.cleanupServiceDiscovery(n.ID()) 1025 1026 // Cleanup the load balancer 1027 c.cleanupServiceBindings(n.ID()) 1028 1029removeFromStore: 1030 // deleteFromStore performs an atomic delete operation and the 1031 // network.epCnt will help prevent any possible 1032 // race between endpoint join and network delete 1033 if err = c.deleteFromStore(n.getEpCnt()); err != nil { 1034 if !force { 1035 return fmt.Errorf("error deleting network endpoint count from store: %v", err) 1036 } 1037 logrus.Debugf("Error deleting endpoint count from store for stale network %s (%s) for deletion: %v", n.Name(), n.ID(), err) 1038 } 1039 1040 if err = c.deleteFromStore(n); err != nil { 1041 return fmt.Errorf("error deleting network from store: %v", err) 1042 } 1043 1044 return nil 1045} 1046 1047func (n *network) deleteNetwork() error { 1048 d, err := n.driver(true) 1049 if err != nil { 1050 return fmt.Errorf("failed deleting network: %v", err) 1051 } 1052 1053 if err := d.DeleteNetwork(n.ID()); err != nil { 1054 // Forbidden Errors should be honored 1055 if _, ok := err.(types.ForbiddenError); ok { 1056 return err 1057 } 1058 1059 if _, ok := err.(types.MaskableError); !ok { 1060 logrus.Warnf("driver error deleting network %s : %v", n.name, err) 1061 } 1062 } 1063 1064 for _, resolver := range n.resolver { 1065 resolver.Stop() 1066 } 1067 return nil 1068} 1069 1070func (n *network) addEndpoint(ep *endpoint) error { 1071 d, err := n.driver(true) 1072 if err != nil { 1073 return fmt.Errorf("failed to add endpoint: %v", err) 1074 } 1075 1076 err = d.CreateEndpoint(n.id, ep.id, ep.Interface(), ep.generic) 1077 if err != nil { 1078 return types.InternalErrorf("failed to create endpoint %s on network %s: %v", 1079 ep.Name(), n.Name(), err) 1080 } 1081 1082 return nil 1083} 1084 1085func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) { 1086 var err error 1087 if !config.IsValidName(name) { 1088 return nil, ErrInvalidName(name) 1089 } 1090 1091 if n.ConfigOnly() { 1092 return nil, types.ForbiddenErrorf("cannot create endpoint on configuration-only network") 1093 } 1094 1095 if _, err = n.EndpointByName(name); err == nil { 1096 return nil, types.ForbiddenErrorf("endpoint with name %s already exists in network %s", name, n.Name()) 1097 } 1098 1099 n.ctrlr.networkLocker.Lock(n.id) 1100 defer n.ctrlr.networkLocker.Unlock(n.id) 1101 1102 return n.createEndpoint(name, options...) 1103 1104} 1105 1106func (n *network) createEndpoint(name string, options ...EndpointOption) (Endpoint, error) { 1107 var err error 1108 1109 ep := &endpoint{name: name, generic: make(map[string]interface{}), iface: &endpointInterface{}} 1110 ep.id = stringid.GenerateRandomID() 1111 1112 // Initialize ep.network with a possibly stale copy of n. We need this to get network from 1113 // store. But once we get it from store we will have the most uptodate copy possibly. 1114 ep.network = n 1115 ep.locator = n.getController().clusterHostID() 1116 ep.network, err = ep.getNetworkFromStore() 1117 if err != nil { 1118 return nil, fmt.Errorf("failed to get network during CreateEndpoint: %v", err) 1119 } 1120 n = ep.network 1121 1122 ep.processOptions(options...) 1123 1124 for _, llIPNet := range ep.Iface().LinkLocalAddresses() { 1125 if !llIPNet.IP.IsLinkLocalUnicast() { 1126 return nil, types.BadRequestErrorf("invalid link local IP address: %v", llIPNet.IP) 1127 } 1128 } 1129 1130 if opt, ok := ep.generic[netlabel.MacAddress]; ok { 1131 if mac, ok := opt.(net.HardwareAddr); ok { 1132 ep.iface.mac = mac 1133 } 1134 } 1135 1136 ipam, cap, err := n.getController().getIPAMDriver(n.ipamType) 1137 if err != nil { 1138 return nil, err 1139 } 1140 1141 if cap.RequiresMACAddress { 1142 if ep.iface.mac == nil { 1143 ep.iface.mac = netutils.GenerateRandomMAC() 1144 } 1145 if ep.ipamOptions == nil { 1146 ep.ipamOptions = make(map[string]string) 1147 } 1148 ep.ipamOptions[netlabel.MacAddress] = ep.iface.mac.String() 1149 } 1150 1151 if err = ep.assignAddress(ipam, true, n.enableIPv6 && !n.postIPv6); err != nil { 1152 return nil, err 1153 } 1154 defer func() { 1155 if err != nil { 1156 ep.releaseAddress() 1157 } 1158 }() 1159 // Moving updateToSTore before calling addEndpoint so that we shall clean up VETH interfaces in case 1160 // DockerD get killed between addEndpoint and updateSTore call 1161 if err = n.getController().updateToStore(ep); err != nil { 1162 return nil, err 1163 } 1164 defer func() { 1165 if err != nil { 1166 if e := n.getController().deleteFromStore(ep); e != nil { 1167 logrus.Warnf("error rolling back endpoint %s from store: %v", name, e) 1168 } 1169 } 1170 }() 1171 1172 if err = n.addEndpoint(ep); err != nil { 1173 return nil, err 1174 } 1175 defer func() { 1176 if err != nil { 1177 if e := ep.deleteEndpoint(false); e != nil { 1178 logrus.Warnf("cleaning up endpoint failed %s : %v", name, e) 1179 } 1180 } 1181 }() 1182 1183 if err = ep.assignAddress(ipam, false, n.enableIPv6 && n.postIPv6); err != nil { 1184 return nil, err 1185 } 1186 1187 // Watch for service records 1188 n.getController().watchSvcRecord(ep) 1189 defer func() { 1190 if err != nil { 1191 n.getController().unWatchSvcRecord(ep) 1192 } 1193 }() 1194 1195 // Increment endpoint count to indicate completion of endpoint addition 1196 if err = n.getEpCnt().IncEndpointCnt(); err != nil { 1197 return nil, err 1198 } 1199 1200 return ep, nil 1201} 1202 1203func (n *network) Endpoints() []Endpoint { 1204 var list []Endpoint 1205 1206 endpoints, err := n.getEndpointsFromStore() 1207 if err != nil { 1208 logrus.Error(err) 1209 } 1210 1211 for _, ep := range endpoints { 1212 list = append(list, ep) 1213 } 1214 1215 return list 1216} 1217 1218func (n *network) WalkEndpoints(walker EndpointWalker) { 1219 for _, e := range n.Endpoints() { 1220 if walker(e) { 1221 return 1222 } 1223 } 1224} 1225 1226func (n *network) EndpointByName(name string) (Endpoint, error) { 1227 if name == "" { 1228 return nil, ErrInvalidName(name) 1229 } 1230 var e Endpoint 1231 1232 s := func(current Endpoint) bool { 1233 if current.Name() == name { 1234 e = current 1235 return true 1236 } 1237 return false 1238 } 1239 1240 n.WalkEndpoints(s) 1241 1242 if e == nil { 1243 return nil, ErrNoSuchEndpoint(name) 1244 } 1245 1246 return e, nil 1247} 1248 1249func (n *network) EndpointByID(id string) (Endpoint, error) { 1250 if id == "" { 1251 return nil, ErrInvalidID(id) 1252 } 1253 1254 ep, err := n.getEndpointFromStore(id) 1255 if err != nil { 1256 return nil, ErrNoSuchEndpoint(id) 1257 } 1258 1259 return ep, nil 1260} 1261 1262func (n *network) updateSvcRecord(ep *endpoint, localEps []*endpoint, isAdd bool) { 1263 var ipv6 net.IP 1264 epName := ep.Name() 1265 if iface := ep.Iface(); iface.Address() != nil { 1266 myAliases := ep.MyAliases() 1267 if iface.AddressIPv6() != nil { 1268 ipv6 = iface.AddressIPv6().IP 1269 } 1270 1271 serviceID := ep.svcID 1272 if serviceID == "" { 1273 serviceID = ep.ID() 1274 } 1275 if isAdd { 1276 // If anonymous endpoint has an alias use the first alias 1277 // for ip->name mapping. Not having the reverse mapping 1278 // breaks some apps 1279 if ep.isAnonymous() { 1280 if len(myAliases) > 0 { 1281 n.addSvcRecords(ep.ID(), myAliases[0], serviceID, iface.Address().IP, ipv6, true, "updateSvcRecord") 1282 } 1283 } else { 1284 n.addSvcRecords(ep.ID(), epName, serviceID, iface.Address().IP, ipv6, true, "updateSvcRecord") 1285 } 1286 for _, alias := range myAliases { 1287 n.addSvcRecords(ep.ID(), alias, serviceID, iface.Address().IP, ipv6, false, "updateSvcRecord") 1288 } 1289 } else { 1290 if ep.isAnonymous() { 1291 if len(myAliases) > 0 { 1292 n.deleteSvcRecords(ep.ID(), myAliases[0], serviceID, iface.Address().IP, ipv6, true, "updateSvcRecord") 1293 } 1294 } else { 1295 n.deleteSvcRecords(ep.ID(), epName, serviceID, iface.Address().IP, ipv6, true, "updateSvcRecord") 1296 } 1297 for _, alias := range myAliases { 1298 n.deleteSvcRecords(ep.ID(), alias, serviceID, iface.Address().IP, ipv6, false, "updateSvcRecord") 1299 } 1300 } 1301 } 1302} 1303 1304func addIPToName(ipMap common.SetMatrix, name, serviceID string, ip net.IP) { 1305 reverseIP := netutils.ReverseIP(ip.String()) 1306 ipMap.Insert(reverseIP, ipInfo{ 1307 name: name, 1308 serviceID: serviceID, 1309 }) 1310} 1311 1312func delIPToName(ipMap common.SetMatrix, name, serviceID string, ip net.IP) { 1313 reverseIP := netutils.ReverseIP(ip.String()) 1314 ipMap.Remove(reverseIP, ipInfo{ 1315 name: name, 1316 serviceID: serviceID, 1317 }) 1318} 1319 1320func addNameToIP(svcMap common.SetMatrix, name, serviceID string, epIP net.IP) { 1321 svcMap.Insert(name, svcMapEntry{ 1322 ip: epIP.String(), 1323 serviceID: serviceID, 1324 }) 1325} 1326 1327func delNameToIP(svcMap common.SetMatrix, name, serviceID string, epIP net.IP) { 1328 svcMap.Remove(name, svcMapEntry{ 1329 ip: epIP.String(), 1330 serviceID: serviceID, 1331 }) 1332} 1333 1334func (n *network) addSvcRecords(eID, name, serviceID string, epIP, epIPv6 net.IP, ipMapUpdate bool, method string) { 1335 // Do not add service names for ingress network as this is a 1336 // routing only network 1337 if n.ingress { 1338 return 1339 } 1340 1341 logrus.Debugf("%s (%s).addSvcRecords(%s, %s, %s, %t) %s sid:%s", eID, n.ID()[0:7], name, epIP, epIPv6, ipMapUpdate, method, serviceID) 1342 1343 c := n.getController() 1344 c.Lock() 1345 defer c.Unlock() 1346 1347 sr, ok := c.svcRecords[n.ID()] 1348 if !ok { 1349 sr = svcInfo{ 1350 svcMap: common.NewSetMatrix(), 1351 svcIPv6Map: common.NewSetMatrix(), 1352 ipMap: common.NewSetMatrix(), 1353 } 1354 c.svcRecords[n.ID()] = sr 1355 } 1356 1357 if ipMapUpdate { 1358 addIPToName(sr.ipMap, name, serviceID, epIP) 1359 if epIPv6 != nil { 1360 addIPToName(sr.ipMap, name, serviceID, epIPv6) 1361 } 1362 } 1363 1364 addNameToIP(sr.svcMap, name, serviceID, epIP) 1365 if epIPv6 != nil { 1366 addNameToIP(sr.svcIPv6Map, name, serviceID, epIPv6) 1367 } 1368} 1369 1370func (n *network) deleteSvcRecords(eID, name, serviceID string, epIP net.IP, epIPv6 net.IP, ipMapUpdate bool, method string) { 1371 // Do not delete service names from ingress network as this is a 1372 // routing only network 1373 if n.ingress { 1374 return 1375 } 1376 1377 logrus.Debugf("%s (%s).deleteSvcRecords(%s, %s, %s, %t) %s sid:%s ", eID, n.ID()[0:7], name, epIP, epIPv6, ipMapUpdate, method, serviceID) 1378 1379 c := n.getController() 1380 c.Lock() 1381 defer c.Unlock() 1382 1383 sr, ok := c.svcRecords[n.ID()] 1384 if !ok { 1385 return 1386 } 1387 1388 if ipMapUpdate { 1389 delIPToName(sr.ipMap, name, serviceID, epIP) 1390 1391 if epIPv6 != nil { 1392 delIPToName(sr.ipMap, name, serviceID, epIPv6) 1393 } 1394 } 1395 1396 delNameToIP(sr.svcMap, name, serviceID, epIP) 1397 1398 if epIPv6 != nil { 1399 delNameToIP(sr.svcIPv6Map, name, serviceID, epIPv6) 1400 } 1401} 1402 1403func (n *network) getSvcRecords(ep *endpoint) []etchosts.Record { 1404 n.Lock() 1405 defer n.Unlock() 1406 1407 if ep == nil { 1408 return nil 1409 } 1410 1411 var recs []etchosts.Record 1412 1413 epName := ep.Name() 1414 1415 n.ctrlr.Lock() 1416 defer n.ctrlr.Unlock() 1417 sr, ok := n.ctrlr.svcRecords[n.id] 1418 if !ok || sr.svcMap == nil { 1419 return nil 1420 } 1421 1422 svcMapKeys := sr.svcMap.Keys() 1423 // Loop on service names on this network 1424 for _, k := range svcMapKeys { 1425 if strings.Split(k, ".")[0] == epName { 1426 continue 1427 } 1428 // Get all the IPs associated to this service 1429 mapEntryList, ok := sr.svcMap.Get(k) 1430 if !ok { 1431 // The key got deleted 1432 continue 1433 } 1434 if len(mapEntryList) == 0 { 1435 logrus.Warnf("Found empty list of IP addresses for service %s on network %s (%s)", k, n.name, n.id) 1436 continue 1437 } 1438 1439 recs = append(recs, etchosts.Record{ 1440 Hosts: k, 1441 IP: mapEntryList[0].(svcMapEntry).ip, 1442 }) 1443 } 1444 1445 return recs 1446} 1447 1448func (n *network) getController() *controller { 1449 n.Lock() 1450 defer n.Unlock() 1451 return n.ctrlr 1452} 1453 1454func (n *network) ipamAllocate() error { 1455 if n.hasSpecialDriver() { 1456 return nil 1457 } 1458 1459 ipam, _, err := n.getController().getIPAMDriver(n.ipamType) 1460 if err != nil { 1461 return err 1462 } 1463 1464 if n.addrSpace == "" { 1465 if n.addrSpace, err = n.deriveAddressSpace(); err != nil { 1466 return err 1467 } 1468 } 1469 1470 err = n.ipamAllocateVersion(4, ipam) 1471 if err != nil { 1472 return err 1473 } 1474 1475 defer func() { 1476 if err != nil { 1477 n.ipamReleaseVersion(4, ipam) 1478 } 1479 }() 1480 1481 if !n.enableIPv6 { 1482 return nil 1483 } 1484 1485 err = n.ipamAllocateVersion(6, ipam) 1486 return err 1487} 1488 1489func (n *network) requestPoolHelper(ipam ipamapi.Ipam, addressSpace, preferredPool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) { 1490 for { 1491 poolID, pool, meta, err := ipam.RequestPool(addressSpace, preferredPool, subPool, options, v6) 1492 if err != nil { 1493 return "", nil, nil, err 1494 } 1495 1496 // If the network belongs to global scope or the pool was 1497 // explicitly chosen or it is invalid, do not perform the overlap check. 1498 if n.Scope() == datastore.GlobalScope || preferredPool != "" || !types.IsIPNetValid(pool) { 1499 return poolID, pool, meta, nil 1500 } 1501 1502 // Check for overlap and if none found, we have found the right pool. 1503 if _, err := netutils.FindAvailableNetwork([]*net.IPNet{pool}); err == nil { 1504 return poolID, pool, meta, nil 1505 } 1506 1507 // Pool obtained in this iteration is 1508 // overlapping. Hold onto the pool and don't release 1509 // it yet, because we don't want ipam to give us back 1510 // the same pool over again. But make sure we still do 1511 // a deferred release when we have either obtained a 1512 // non-overlapping pool or ran out of pre-defined 1513 // pools. 1514 defer func() { 1515 if err := ipam.ReleasePool(poolID); err != nil { 1516 logrus.Warnf("Failed to release overlapping pool %s while returning from pool request helper for network %s", pool, n.Name()) 1517 } 1518 }() 1519 1520 // If this is a preferred pool request and the network 1521 // is local scope and there is an overlap, we fail the 1522 // network creation right here. The pool will be 1523 // released in the defer. 1524 if preferredPool != "" { 1525 return "", nil, nil, fmt.Errorf("requested subnet %s overlaps in the host", preferredPool) 1526 } 1527 } 1528} 1529 1530func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error { 1531 var ( 1532 cfgList *[]*IpamConf 1533 infoList *[]*IpamInfo 1534 err error 1535 ) 1536 1537 switch ipVer { 1538 case 4: 1539 cfgList = &n.ipamV4Config 1540 infoList = &n.ipamV4Info 1541 case 6: 1542 cfgList = &n.ipamV6Config 1543 infoList = &n.ipamV6Info 1544 default: 1545 return types.InternalErrorf("incorrect ip version passed to ipam allocate: %d", ipVer) 1546 } 1547 1548 if len(*cfgList) == 0 { 1549 *cfgList = []*IpamConf{{}} 1550 } 1551 1552 *infoList = make([]*IpamInfo, len(*cfgList)) 1553 1554 logrus.Debugf("Allocating IPv%d pools for network %s (%s)", ipVer, n.Name(), n.ID()) 1555 1556 for i, cfg := range *cfgList { 1557 if err = cfg.Validate(); err != nil { 1558 return err 1559 } 1560 d := &IpamInfo{} 1561 (*infoList)[i] = d 1562 1563 d.AddressSpace = n.addrSpace 1564 d.PoolID, d.Pool, d.Meta, err = n.requestPoolHelper(ipam, n.addrSpace, cfg.PreferredPool, cfg.SubPool, n.ipamOptions, ipVer == 6) 1565 if err != nil { 1566 return err 1567 } 1568 1569 defer func() { 1570 if err != nil { 1571 if err := ipam.ReleasePool(d.PoolID); err != nil { 1572 logrus.Warnf("Failed to release address pool %s after failure to create network %s (%s)", d.PoolID, n.Name(), n.ID()) 1573 } 1574 } 1575 }() 1576 1577 if gws, ok := d.Meta[netlabel.Gateway]; ok { 1578 if d.Gateway, err = types.ParseCIDR(gws); err != nil { 1579 return types.BadRequestErrorf("failed to parse gateway address (%v) returned by ipam driver: %v", gws, err) 1580 } 1581 } 1582 1583 // If user requested a specific gateway, libnetwork will allocate it 1584 // irrespective of whether ipam driver returned a gateway already. 1585 // If none of the above is true, libnetwork will allocate one. 1586 if cfg.Gateway != "" || d.Gateway == nil { 1587 var gatewayOpts = map[string]string{ 1588 ipamapi.RequestAddressType: netlabel.Gateway, 1589 } 1590 if d.Gateway, _, err = ipam.RequestAddress(d.PoolID, net.ParseIP(cfg.Gateway), gatewayOpts); err != nil { 1591 return types.InternalErrorf("failed to allocate gateway (%v): %v", cfg.Gateway, err) 1592 } 1593 } 1594 1595 // Auxiliary addresses must be part of the master address pool 1596 // If they fall into the container addressable pool, libnetwork will reserve them 1597 if cfg.AuxAddresses != nil { 1598 var ip net.IP 1599 d.IPAMData.AuxAddresses = make(map[string]*net.IPNet, len(cfg.AuxAddresses)) 1600 for k, v := range cfg.AuxAddresses { 1601 if ip = net.ParseIP(v); ip == nil { 1602 return types.BadRequestErrorf("non parsable secondary ip address (%s:%s) passed for network %s", k, v, n.Name()) 1603 } 1604 if !d.Pool.Contains(ip) { 1605 return types.ForbiddenErrorf("auxilairy address: (%s:%s) must belong to the master pool: %s", k, v, d.Pool) 1606 } 1607 // Attempt reservation in the container addressable pool, silent the error if address does not belong to that pool 1608 if d.IPAMData.AuxAddresses[k], _, err = ipam.RequestAddress(d.PoolID, ip, nil); err != nil && err != ipamapi.ErrIPOutOfRange { 1609 return types.InternalErrorf("failed to allocate secondary ip address (%s:%s): %v", k, v, err) 1610 } 1611 } 1612 } 1613 } 1614 1615 return nil 1616} 1617 1618func (n *network) ipamRelease() { 1619 if n.hasSpecialDriver() { 1620 return 1621 } 1622 ipam, _, err := n.getController().getIPAMDriver(n.ipamType) 1623 if err != nil { 1624 logrus.Warnf("Failed to retrieve ipam driver to release address pool(s) on delete of network %s (%s): %v", n.Name(), n.ID(), err) 1625 return 1626 } 1627 n.ipamReleaseVersion(4, ipam) 1628 n.ipamReleaseVersion(6, ipam) 1629} 1630 1631func (n *network) ipamReleaseVersion(ipVer int, ipam ipamapi.Ipam) { 1632 var infoList *[]*IpamInfo 1633 1634 switch ipVer { 1635 case 4: 1636 infoList = &n.ipamV4Info 1637 case 6: 1638 infoList = &n.ipamV6Info 1639 default: 1640 logrus.Warnf("incorrect ip version passed to ipam release: %d", ipVer) 1641 return 1642 } 1643 1644 if len(*infoList) == 0 { 1645 return 1646 } 1647 1648 logrus.Debugf("releasing IPv%d pools from network %s (%s)", ipVer, n.Name(), n.ID()) 1649 1650 for _, d := range *infoList { 1651 if d.Gateway != nil { 1652 if err := ipam.ReleaseAddress(d.PoolID, d.Gateway.IP); err != nil { 1653 logrus.Warnf("Failed to release gateway ip address %s on delete of network %s (%s): %v", d.Gateway.IP, n.Name(), n.ID(), err) 1654 } 1655 } 1656 if d.IPAMData.AuxAddresses != nil { 1657 for k, nw := range d.IPAMData.AuxAddresses { 1658 if d.Pool.Contains(nw.IP) { 1659 if err := ipam.ReleaseAddress(d.PoolID, nw.IP); err != nil && err != ipamapi.ErrIPOutOfRange { 1660 logrus.Warnf("Failed to release secondary ip address %s (%v) on delete of network %s (%s): %v", k, nw.IP, n.Name(), n.ID(), err) 1661 } 1662 } 1663 } 1664 } 1665 if err := ipam.ReleasePool(d.PoolID); err != nil { 1666 logrus.Warnf("Failed to release address pool %s on delete of network %s (%s): %v", d.PoolID, n.Name(), n.ID(), err) 1667 } 1668 } 1669 1670 *infoList = nil 1671} 1672 1673func (n *network) getIPInfo(ipVer int) []*IpamInfo { 1674 var info []*IpamInfo 1675 switch ipVer { 1676 case 4: 1677 info = n.ipamV4Info 1678 case 6: 1679 info = n.ipamV6Info 1680 default: 1681 return nil 1682 } 1683 l := make([]*IpamInfo, 0, len(info)) 1684 n.Lock() 1685 l = append(l, info...) 1686 n.Unlock() 1687 return l 1688} 1689 1690func (n *network) getIPData(ipVer int) []driverapi.IPAMData { 1691 var info []*IpamInfo 1692 switch ipVer { 1693 case 4: 1694 info = n.ipamV4Info 1695 case 6: 1696 info = n.ipamV6Info 1697 default: 1698 return nil 1699 } 1700 l := make([]driverapi.IPAMData, 0, len(info)) 1701 n.Lock() 1702 for _, d := range info { 1703 l = append(l, d.IPAMData) 1704 } 1705 n.Unlock() 1706 return l 1707} 1708 1709func (n *network) deriveAddressSpace() (string, error) { 1710 local, global, err := n.getController().drvRegistry.IPAMDefaultAddressSpaces(n.ipamType) 1711 if err != nil { 1712 return "", types.NotFoundErrorf("failed to get default address space: %v", err) 1713 } 1714 if n.DataScope() == datastore.GlobalScope { 1715 return global, nil 1716 } 1717 return local, nil 1718} 1719 1720func (n *network) Info() NetworkInfo { 1721 return n 1722} 1723 1724func (n *network) Peers() []networkdb.PeerInfo { 1725 if !n.Dynamic() { 1726 return []networkdb.PeerInfo{} 1727 } 1728 1729 agent := n.getController().getAgent() 1730 if agent == nil { 1731 return []networkdb.PeerInfo{} 1732 } 1733 1734 return agent.networkDB.Peers(n.ID()) 1735} 1736 1737func (n *network) DriverOptions() map[string]string { 1738 n.Lock() 1739 defer n.Unlock() 1740 if n.generic != nil { 1741 if m, ok := n.generic[netlabel.GenericData]; ok { 1742 return m.(map[string]string) 1743 } 1744 } 1745 return map[string]string{} 1746} 1747 1748func (n *network) Scope() string { 1749 n.Lock() 1750 defer n.Unlock() 1751 return n.scope 1752} 1753 1754func (n *network) IpamConfig() (string, map[string]string, []*IpamConf, []*IpamConf) { 1755 n.Lock() 1756 defer n.Unlock() 1757 1758 v4L := make([]*IpamConf, len(n.ipamV4Config)) 1759 v6L := make([]*IpamConf, len(n.ipamV6Config)) 1760 1761 for i, c := range n.ipamV4Config { 1762 cc := &IpamConf{} 1763 c.CopyTo(cc) 1764 v4L[i] = cc 1765 } 1766 1767 for i, c := range n.ipamV6Config { 1768 cc := &IpamConf{} 1769 c.CopyTo(cc) 1770 v6L[i] = cc 1771 } 1772 1773 return n.ipamType, n.ipamOptions, v4L, v6L 1774} 1775 1776func (n *network) IpamInfo() ([]*IpamInfo, []*IpamInfo) { 1777 n.Lock() 1778 defer n.Unlock() 1779 1780 v4Info := make([]*IpamInfo, len(n.ipamV4Info)) 1781 v6Info := make([]*IpamInfo, len(n.ipamV6Info)) 1782 1783 for i, info := range n.ipamV4Info { 1784 ic := &IpamInfo{} 1785 info.CopyTo(ic) 1786 v4Info[i] = ic 1787 } 1788 1789 for i, info := range n.ipamV6Info { 1790 ic := &IpamInfo{} 1791 info.CopyTo(ic) 1792 v6Info[i] = ic 1793 } 1794 1795 return v4Info, v6Info 1796} 1797 1798func (n *network) Internal() bool { 1799 n.Lock() 1800 defer n.Unlock() 1801 1802 return n.internal 1803} 1804 1805func (n *network) Attachable() bool { 1806 n.Lock() 1807 defer n.Unlock() 1808 1809 return n.attachable 1810} 1811 1812func (n *network) Ingress() bool { 1813 n.Lock() 1814 defer n.Unlock() 1815 1816 return n.ingress 1817} 1818 1819func (n *network) Dynamic() bool { 1820 n.Lock() 1821 defer n.Unlock() 1822 1823 return n.dynamic 1824} 1825 1826func (n *network) IPv6Enabled() bool { 1827 n.Lock() 1828 defer n.Unlock() 1829 1830 return n.enableIPv6 1831} 1832 1833func (n *network) ConfigFrom() string { 1834 n.Lock() 1835 defer n.Unlock() 1836 1837 return n.configFrom 1838} 1839 1840func (n *network) ConfigOnly() bool { 1841 n.Lock() 1842 defer n.Unlock() 1843 1844 return n.configOnly 1845} 1846 1847func (n *network) Labels() map[string]string { 1848 n.Lock() 1849 defer n.Unlock() 1850 1851 var lbls = make(map[string]string, len(n.labels)) 1852 for k, v := range n.labels { 1853 lbls[k] = v 1854 } 1855 1856 return lbls 1857} 1858 1859func (n *network) TableEventRegister(tableName string, objType driverapi.ObjectType) error { 1860 if !driverapi.IsValidType(objType) { 1861 return fmt.Errorf("invalid object type %v in registering table, %s", objType, tableName) 1862 } 1863 1864 t := networkDBTable{ 1865 name: tableName, 1866 objType: objType, 1867 } 1868 n.Lock() 1869 defer n.Unlock() 1870 n.driverTables = append(n.driverTables, t) 1871 return nil 1872} 1873 1874// Special drivers are ones which do not need to perform any network plumbing 1875func (n *network) hasSpecialDriver() bool { 1876 return n.Type() == "host" || n.Type() == "null" 1877} 1878 1879func (n *network) ResolveName(req string, ipType int) ([]net.IP, bool) { 1880 var ipv6Miss bool 1881 1882 c := n.getController() 1883 c.Lock() 1884 defer c.Unlock() 1885 sr, ok := c.svcRecords[n.ID()] 1886 1887 if !ok { 1888 return nil, false 1889 } 1890 1891 req = strings.TrimSuffix(req, ".") 1892 ipSet, ok := sr.svcMap.Get(req) 1893 1894 if ipType == types.IPv6 { 1895 // If the name resolved to v4 address then its a valid name in 1896 // the docker network domain. If the network is not v6 enabled 1897 // set ipv6Miss to filter the DNS query from going to external 1898 // resolvers. 1899 if ok && !n.enableIPv6 { 1900 ipv6Miss = true 1901 } 1902 ipSet, ok = sr.svcIPv6Map.Get(req) 1903 } 1904 1905 if ok && len(ipSet) > 0 { 1906 // this map is to avoid IP duplicates, this can happen during a transition period where 2 services are using the same IP 1907 noDup := make(map[string]bool) 1908 var ipLocal []net.IP 1909 for _, ip := range ipSet { 1910 if _, dup := noDup[ip.(svcMapEntry).ip]; !dup { 1911 noDup[ip.(svcMapEntry).ip] = true 1912 ipLocal = append(ipLocal, net.ParseIP(ip.(svcMapEntry).ip)) 1913 } 1914 } 1915 return ipLocal, ok 1916 } 1917 1918 return nil, ipv6Miss 1919} 1920 1921func (n *network) HandleQueryResp(name string, ip net.IP) { 1922 c := n.getController() 1923 c.Lock() 1924 defer c.Unlock() 1925 sr, ok := c.svcRecords[n.ID()] 1926 1927 if !ok { 1928 return 1929 } 1930 1931 ipStr := netutils.ReverseIP(ip.String()) 1932 // If an object with extResolver == true is already in the set this call will fail 1933 // but anyway it means that has already been inserted before 1934 if ok, _ := sr.ipMap.Contains(ipStr, ipInfo{name: name}); ok { 1935 sr.ipMap.Remove(ipStr, ipInfo{name: name}) 1936 sr.ipMap.Insert(ipStr, ipInfo{name: name, extResolver: true}) 1937 } 1938} 1939 1940func (n *network) ResolveIP(ip string) string { 1941 c := n.getController() 1942 c.Lock() 1943 defer c.Unlock() 1944 sr, ok := c.svcRecords[n.ID()] 1945 1946 if !ok { 1947 return "" 1948 } 1949 1950 nwName := n.Name() 1951 1952 elemSet, ok := sr.ipMap.Get(ip) 1953 if !ok || len(elemSet) == 0 { 1954 return "" 1955 } 1956 // NOTE it is possible to have more than one element in the Set, this will happen 1957 // because of interleave of different events from different sources (local container create vs 1958 // network db notifications) 1959 // In such cases the resolution will be based on the first element of the set, and can vary 1960 // during the system stabilitation 1961 elem, ok := elemSet[0].(ipInfo) 1962 if !ok { 1963 setStr, b := sr.ipMap.String(ip) 1964 logrus.Errorf("expected set of ipInfo type for key %s set:%t %s", ip, b, setStr) 1965 return "" 1966 } 1967 1968 if elem.extResolver { 1969 return "" 1970 } 1971 1972 return elem.name + "." + nwName 1973} 1974 1975func (n *network) ResolveService(name string) ([]*net.SRV, []net.IP) { 1976 c := n.getController() 1977 1978 srv := []*net.SRV{} 1979 ip := []net.IP{} 1980 1981 logrus.Debugf("Service name To resolve: %v", name) 1982 1983 // There are DNS implementaions that allow SRV queries for names not in 1984 // the format defined by RFC 2782. Hence specific validations checks are 1985 // not done 1986 parts := strings.Split(name, ".") 1987 if len(parts) < 3 { 1988 return nil, nil 1989 } 1990 1991 portName := parts[0] 1992 proto := parts[1] 1993 svcName := strings.Join(parts[2:], ".") 1994 1995 c.Lock() 1996 defer c.Unlock() 1997 sr, ok := c.svcRecords[n.ID()] 1998 1999 if !ok { 2000 return nil, nil 2001 } 2002 2003 svcs, ok := sr.service[svcName] 2004 if !ok { 2005 return nil, nil 2006 } 2007 2008 for _, svc := range svcs { 2009 if svc.portName != portName { 2010 continue 2011 } 2012 if svc.proto != proto { 2013 continue 2014 } 2015 for _, t := range svc.target { 2016 srv = append(srv, 2017 &net.SRV{ 2018 Target: t.name, 2019 Port: t.port, 2020 }) 2021 2022 ip = append(ip, t.ip) 2023 } 2024 } 2025 2026 return srv, ip 2027} 2028 2029func (n *network) ExecFunc(f func()) error { 2030 return types.NotImplementedErrorf("ExecFunc not supported by network") 2031} 2032 2033func (n *network) NdotsSet() bool { 2034 return false 2035} 2036 2037// config-only network is looked up by name 2038func (c *controller) getConfigNetwork(name string) (*network, error) { 2039 var n Network 2040 2041 s := func(current Network) bool { 2042 if current.Info().ConfigOnly() && current.Name() == name { 2043 n = current 2044 return true 2045 } 2046 return false 2047 } 2048 2049 c.WalkNetworks(s) 2050 2051 if n == nil { 2052 return nil, types.NotFoundErrorf("configuration network %q not found", name) 2053 } 2054 2055 return n.(*network), nil 2056} 2057 2058func (n *network) createLoadBalancerSandbox() error { 2059 sandboxName := n.name + "-sbox" 2060 sbOptions := []SandboxOption{} 2061 if n.ingress { 2062 sbOptions = append(sbOptions, OptionIngress()) 2063 } 2064 sb, err := n.ctrlr.NewSandbox(sandboxName, sbOptions...) 2065 if err != nil { 2066 return err 2067 } 2068 defer func() { 2069 if err != nil { 2070 if e := n.ctrlr.SandboxDestroy(sandboxName); e != nil { 2071 logrus.Warnf("could not delete sandbox %s on failure on failure (%v): %v", sandboxName, err, e) 2072 } 2073 } 2074 }() 2075 2076 endpointName := n.name + "-endpoint" 2077 epOptions := []EndpointOption{ 2078 CreateOptionIpam(n.loadBalancerIP, nil, nil, nil), 2079 CreateOptionLoadBalancer(), 2080 } 2081 ep, err := n.createEndpoint(endpointName, epOptions...) 2082 if err != nil { 2083 return err 2084 } 2085 defer func() { 2086 if err != nil { 2087 if e := ep.Delete(true); e != nil { 2088 logrus.Warnf("could not delete endpoint %s on failure on failure (%v): %v", endpointName, err, e) 2089 } 2090 } 2091 }() 2092 2093 if err := ep.Join(sb, nil); err != nil { 2094 return err 2095 } 2096 return sb.EnableService() 2097} 2098 2099func (n *network) deleteLoadBalancerSandbox() { 2100 n.Lock() 2101 c := n.ctrlr 2102 name := n.name 2103 n.Unlock() 2104 2105 endpointName := name + "-endpoint" 2106 sandboxName := name + "-sbox" 2107 2108 endpoint, err := n.EndpointByName(endpointName) 2109 if err != nil { 2110 logrus.Warnf("Failed to find load balancer endpoint %s on network %s: %v", endpointName, name, err) 2111 } else { 2112 2113 info := endpoint.Info() 2114 if info != nil { 2115 sb := info.Sandbox() 2116 if sb != nil { 2117 if err := sb.DisableService(); err != nil { 2118 logrus.Warnf("Failed to disable service on sandbox %s: %v", sandboxName, err) 2119 //Ignore error and attempt to delete the load balancer endpoint 2120 } 2121 } 2122 } 2123 2124 if err := endpoint.Delete(true); err != nil { 2125 logrus.Warnf("Failed to delete endpoint %s (%s) in %s: %v", endpoint.Name(), endpoint.ID(), sandboxName, err) 2126 //Ignore error and attempt to delete the sandbox. 2127 } 2128 } 2129 2130 if err := c.SandboxDestroy(sandboxName); err != nil { 2131 logrus.Warnf("Failed to delete %s sandbox: %v", sandboxName, err) 2132 } 2133} 2134