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