Browse code

Vendoring latest swarmkit and libnetwork

Signed-off-by: Sandeep Bansal <msabansal@microsoft.com>

Sandeep Bansal authored on 2016/11/10 11:01:07
Showing 79 changed files
... ...
@@ -23,7 +23,7 @@ github.com/RackSec/srslog 365bf33cd9acc21ae1c355209865f17228ca534e
23 23
 github.com/imdario/mergo 0.2.1
24 24
 
25 25
 #get libnetwork packages
26
-github.com/docker/libnetwork a98901aebe7ce920b6fbf02ebe5c3afc9ca975b8
26
+github.com/docker/libnetwork 3ab699ea36573d98f481d233c30c742ade737565
27 27
 github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894
28 28
 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
29 29
 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
... ...
@@ -100,7 +100,7 @@ github.com/docker/containerd 8517738ba4b82aff5662c97ca4627e7e4d03b531
100 100
 github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4
101 101
 
102 102
 # cluster
103
-github.com/docker/swarmkit bddd3f0fb45491987d3dec5fb48311d289d21393
103
+github.com/docker/swarmkit ce07d9f69c9b4a1b1eb508e777c44eeacca87065
104 104
 github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9
105 105
 github.com/gogo/protobuf v0.3
106 106
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"fmt"
10 10
 	"sync"
11 11
 
12
-	log "github.com/Sirupsen/logrus"
12
+	"github.com/Sirupsen/logrus"
13 13
 	"github.com/docker/libnetwork/datastore"
14 14
 	"github.com/docker/libnetwork/types"
15 15
 )
... ...
@@ -286,7 +286,7 @@ func (h *Handle) CheckConsistency() error {
286 286
 			continue
287 287
 		}
288 288
 
289
-		log.Infof("Fixed inconsistent bit sequence in datastore:\n%s\n%s", h, nh)
289
+		logrus.Infof("Fixed inconsistent bit sequence in datastore:\n%s\n%s", h, nh)
290 290
 
291 291
 		h.Lock()
292 292
 		h.head = nh.head
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"strings"
7 7
 
8 8
 	"github.com/BurntSushi/toml"
9
-	log "github.com/Sirupsen/logrus"
9
+	"github.com/Sirupsen/logrus"
10 10
 	"github.com/docker/docker/pkg/discovery"
11 11
 	"github.com/docker/docker/pkg/plugingetter"
12 12
 	"github.com/docker/go-connections/tlsconfig"
... ...
@@ -100,7 +100,7 @@ type Option func(c *Config)
100 100
 // OptionDefaultNetwork function returns an option setter for a default network
101 101
 func OptionDefaultNetwork(dn string) Option {
102 102
 	return func(c *Config) {
103
-		log.Debugf("Option DefaultNetwork: %s", dn)
103
+		logrus.Debugf("Option DefaultNetwork: %s", dn)
104 104
 		c.Daemon.DefaultNetwork = strings.TrimSpace(dn)
105 105
 	}
106 106
 }
... ...
@@ -108,7 +108,7 @@ func OptionDefaultNetwork(dn string) Option {
108 108
 // OptionDefaultDriver function returns an option setter for default driver
109 109
 func OptionDefaultDriver(dd string) Option {
110 110
 	return func(c *Config) {
111
-		log.Debugf("Option DefaultDriver: %s", dd)
111
+		logrus.Debugf("Option DefaultDriver: %s", dd)
112 112
 		c.Daemon.DefaultDriver = strings.TrimSpace(dd)
113 113
 	}
114 114
 }
... ...
@@ -134,7 +134,7 @@ func OptionLabels(labels []string) Option {
134 134
 // OptionKVProvider function returns an option setter for kvstore provider
135 135
 func OptionKVProvider(provider string) Option {
136 136
 	return func(c *Config) {
137
-		log.Debugf("Option OptionKVProvider: %s", provider)
137
+		logrus.Debugf("Option OptionKVProvider: %s", provider)
138 138
 		if _, ok := c.Scopes[datastore.GlobalScope]; !ok {
139 139
 			c.Scopes[datastore.GlobalScope] = &datastore.ScopeCfg{}
140 140
 		}
... ...
@@ -145,7 +145,7 @@ func OptionKVProvider(provider string) Option {
145 145
 // OptionKVProviderURL function returns an option setter for kvstore url
146 146
 func OptionKVProviderURL(url string) Option {
147 147
 	return func(c *Config) {
148
-		log.Debugf("Option OptionKVProviderURL: %s", url)
148
+		logrus.Debugf("Option OptionKVProviderURL: %s", url)
149 149
 		if _, ok := c.Scopes[datastore.GlobalScope]; !ok {
150 150
 			c.Scopes[datastore.GlobalScope] = &datastore.ScopeCfg{}
151 151
 		}
... ...
@@ -157,14 +157,14 @@ func OptionKVProviderURL(url string) Option {
157 157
 func OptionKVOpts(opts map[string]string) Option {
158 158
 	return func(c *Config) {
159 159
 		if opts["kv.cacertfile"] != "" && opts["kv.certfile"] != "" && opts["kv.keyfile"] != "" {
160
-			log.Info("Option Initializing KV with TLS")
160
+			logrus.Info("Option Initializing KV with TLS")
161 161
 			tlsConfig, err := tlsconfig.Client(tlsconfig.Options{
162 162
 				CAFile:   opts["kv.cacertfile"],
163 163
 				CertFile: opts["kv.certfile"],
164 164
 				KeyFile:  opts["kv.keyfile"],
165 165
 			})
166 166
 			if err != nil {
167
-				log.Errorf("Unable to set up TLS: %s", err)
167
+				logrus.Errorf("Unable to set up TLS: %s", err)
168 168
 				return
169 169
 			}
170 170
 			if _, ok := c.Scopes[datastore.GlobalScope]; !ok {
... ...
@@ -182,7 +182,7 @@ func OptionKVOpts(opts map[string]string) Option {
182 182
 				KeyFile:    opts["kv.keyfile"],
183 183
 			}
184 184
 		} else {
185
-			log.Info("Option Initializing KV without TLS")
185
+			logrus.Info("Option Initializing KV without TLS")
186 186
 		}
187 187
 	}
188 188
 }
... ...
@@ -242,7 +242,7 @@ func ValidateName(name string) error {
242 242
 // OptionLocalKVProvider function returns an option setter for kvstore provider
243 243
 func OptionLocalKVProvider(provider string) Option {
244 244
 	return func(c *Config) {
245
-		log.Debugf("Option OptionLocalKVProvider: %s", provider)
245
+		logrus.Debugf("Option OptionLocalKVProvider: %s", provider)
246 246
 		if _, ok := c.Scopes[datastore.LocalScope]; !ok {
247 247
 			c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{}
248 248
 		}
... ...
@@ -253,7 +253,7 @@ func OptionLocalKVProvider(provider string) Option {
253 253
 // OptionLocalKVProviderURL function returns an option setter for kvstore url
254 254
 func OptionLocalKVProviderURL(url string) Option {
255 255
 	return func(c *Config) {
256
-		log.Debugf("Option OptionLocalKVProviderURL: %s", url)
256
+		logrus.Debugf("Option OptionLocalKVProviderURL: %s", url)
257 257
 		if _, ok := c.Scopes[datastore.LocalScope]; !ok {
258 258
 			c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{}
259 259
 		}
... ...
@@ -264,7 +264,7 @@ func OptionLocalKVProviderURL(url string) Option {
264 264
 // OptionLocalKVProviderConfig function returns an option setter for kvstore config
265 265
 func OptionLocalKVProviderConfig(config *store.Config) Option {
266 266
 	return func(c *Config) {
267
-		log.Debugf("Option OptionLocalKVProviderConfig: %v", config)
267
+		logrus.Debugf("Option OptionLocalKVProviderConfig: %v", config)
268 268
 		if _, ok := c.Scopes[datastore.LocalScope]; !ok {
269 269
 			c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{}
270 270
 		}
... ...
@@ -51,7 +51,7 @@ import (
51 51
 	"sync"
52 52
 	"time"
53 53
 
54
-	log "github.com/Sirupsen/logrus"
54
+	"github.com/Sirupsen/logrus"
55 55
 	"github.com/docker/docker/pkg/discovery"
56 56
 	"github.com/docker/docker/pkg/locker"
57 57
 	"github.com/docker/docker/pkg/plugingetter"
... ...
@@ -212,7 +212,7 @@ func New(cfgOptions ...config.Option) (NetworkController, error) {
212 212
 		if err := c.initDiscovery(c.cfg.Cluster.Watcher); err != nil {
213 213
 			// Failing to initialize discovery is a bad situation to be in.
214 214
 			// But it cannot fail creating the Controller
215
-			log.Errorf("Failed to Initialize Discovery : %v", err)
215
+			logrus.Errorf("Failed to Initialize Discovery : %v", err)
216 216
 		}
217 217
 	}
218 218
 
... ...
@@ -283,7 +283,7 @@ func (c *controller) SetKeys(keys []*types.EncryptionKey) error {
283 283
 		if clusterConfigAvailable {
284 284
 			return c.agentSetup()
285 285
 		}
286
-		log.Debugf("received encryption keys before cluster config")
286
+		logrus.Debug("received encryption keys before cluster config")
287 287
 		return nil
288 288
 	}
289 289
 	if agent == nil {
... ...
@@ -441,7 +441,7 @@ func (c *controller) ReloadConfiguration(cfgOptions ...config.Option) error {
441 441
 	c.drvRegistry.WalkIPAMs(func(name string, driver ipamapi.Ipam, cap *ipamapi.Capability) bool {
442 442
 		err := driver.DiscoverNew(discoverapi.DatastoreConfig, *dsConfig)
443 443
 		if err != nil {
444
-			log.Errorf("Failed to set datastore in driver %s: %v", name, err)
444
+			logrus.Errorf("Failed to set datastore in driver %s: %v", name, err)
445 445
 		}
446 446
 		return false
447 447
 	})
... ...
@@ -449,14 +449,14 @@ func (c *controller) ReloadConfiguration(cfgOptions ...config.Option) error {
449 449
 	c.drvRegistry.WalkDrivers(func(name string, driver driverapi.Driver, capability driverapi.Capability) bool {
450 450
 		err := driver.DiscoverNew(discoverapi.DatastoreConfig, *dsConfig)
451 451
 		if err != nil {
452
-			log.Errorf("Failed to set datastore in driver %s: %v", name, err)
452
+			logrus.Errorf("Failed to set datastore in driver %s: %v", name, err)
453 453
 		}
454 454
 		return false
455 455
 	})
456 456
 
457 457
 	if c.discovery == nil && c.cfg.Cluster.Watcher != nil {
458 458
 		if err := c.initDiscovery(c.cfg.Cluster.Watcher); err != nil {
459
-			log.Errorf("Failed to Initialize Discovery after configuration update: %v", err)
459
+			logrus.Errorf("Failed to Initialize Discovery after configuration update: %v", err)
460 460
 		}
461 461
 	}
462 462
 
... ...
@@ -561,7 +561,7 @@ func (c *controller) pushNodeDiscovery(d driverapi.Driver, cap driverapi.Capabil
561 561
 			err = d.DiscoverDelete(discoverapi.NodeDiscovery, nodeData)
562 562
 		}
563 563
 		if err != nil {
564
-			log.Debugf("discovery notification error : %v", err)
564
+			logrus.Debugf("discovery notification error : %v", err)
565 565
 		}
566 566
 	}
567 567
 }
... ...
@@ -634,12 +634,13 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
634 634
 		id = stringid.GenerateRandomID()
635 635
 	}
636 636
 
637
+	defaultIpam := defaultIpamForNetworkType(networkType)
637 638
 	// Construct the network object
638 639
 	network := &network{
639 640
 		name:        name,
640 641
 		networkType: networkType,
641 642
 		generic:     map[string]interface{}{netlabel.GenericData: make(map[string]string)},
642
-		ipamType:    ipamapi.DefaultIPAM,
643
+		ipamType:    defaultIpam,
643 644
 		id:          id,
644 645
 		created:     time.Now(),
645 646
 		ctrlr:       c,
... ...
@@ -686,7 +687,7 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
686 686
 	defer func() {
687 687
 		if err != nil {
688 688
 			if e := network.deleteNetwork(); e != nil {
689
-				log.Warnf("couldn't roll back driver network on network %s creation failure: %v", network.name, err)
689
+				logrus.Warnf("couldn't roll back driver network on network %s creation failure: %v", network.name, err)
690 690
 			}
691 691
 		}
692 692
 	}()
... ...
@@ -701,7 +702,7 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
701 701
 	defer func() {
702 702
 		if err != nil {
703 703
 			if e := c.deleteFromStore(epCnt); e != nil {
704
-				log.Warnf("couldnt rollback from store, epCnt %v on failure (%v): %v", epCnt, err, e)
704
+				logrus.Warnf("could not rollback from store, epCnt %v on failure (%v): %v", epCnt, err, e)
705 705
 			}
706 706
 		}
707 707
 	}()
... ...
@@ -722,7 +723,7 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
722 722
 var joinCluster NetworkWalker = func(nw Network) bool {
723 723
 	n := nw.(*network)
724 724
 	if err := n.joinCluster(); err != nil {
725
-		log.Errorf("Failed to join network %s (%s) into agent cluster: %v", n.Name(), n.ID(), err)
725
+		logrus.Errorf("Failed to join network %s (%s) into agent cluster: %v", n.Name(), n.ID(), err)
726 726
 	}
727 727
 	n.addDriverWatches()
728 728
 	return false
... ...
@@ -731,7 +732,7 @@ var joinCluster NetworkWalker = func(nw Network) bool {
731 731
 func (c *controller) reservePools() {
732 732
 	networks, err := c.getNetworksForScope(datastore.LocalScope)
733 733
 	if err != nil {
734
-		log.Warnf("Could not retrieve networks from local store during ipam allocation for existing networks: %v", err)
734
+		logrus.Warnf("Could not retrieve networks from local store during ipam allocation for existing networks: %v", err)
735 735
 		return
736 736
 	}
737 737
 
... ...
@@ -763,22 +764,22 @@ func (c *controller) reservePools() {
763 763
 		}
764 764
 		// Reserve pools
765 765
 		if err := n.ipamAllocate(); err != nil {
766
-			log.Warnf("Failed to allocate ipam pool(s) for network %q (%s): %v", n.Name(), n.ID(), err)
766
+			logrus.Warnf("Failed to allocate ipam pool(s) for network %q (%s): %v", n.Name(), n.ID(), err)
767 767
 		}
768 768
 		// Reserve existing endpoints' addresses
769 769
 		ipam, _, err := n.getController().getIPAMDriver(n.ipamType)
770 770
 		if err != nil {
771
-			log.Warnf("Failed to retrieve ipam driver for network %q (%s) during address reservation", n.Name(), n.ID())
771
+			logrus.Warnf("Failed to retrieve ipam driver for network %q (%s) during address reservation", n.Name(), n.ID())
772 772
 			continue
773 773
 		}
774 774
 		epl, err := n.getEndpointsFromStore()
775 775
 		if err != nil {
776
-			log.Warnf("Failed to retrieve list of current endpoints on network %q (%s)", n.Name(), n.ID())
776
+			logrus.Warnf("Failed to retrieve list of current endpoints on network %q (%s)", n.Name(), n.ID())
777 777
 			continue
778 778
 		}
779 779
 		for _, ep := range epl {
780 780
 			if err := ep.assignAddress(ipam, true, ep.Iface().AddressIPv6() != nil); err != nil {
781
-				log.Warnf("Failed to reserve current adress for endpoint %q (%s) on network %q (%s)",
781
+				logrus.Warnf("Failed to reserve current adress for endpoint %q (%s) on network %q (%s)",
782 782
 					ep.Name(), ep.ID(), n.Name(), n.ID())
783 783
 			}
784 784
 		}
... ...
@@ -788,7 +789,7 @@ func (c *controller) reservePools() {
788 788
 func doReplayPoolReserve(n *network) bool {
789 789
 	_, caps, err := n.getController().getIPAMDriver(n.ipamType)
790 790
 	if err != nil {
791
-		log.Warnf("Failed to retrieve ipam driver for network %q (%s): %v", n.Name(), n.ID(), err)
791
+		logrus.Warnf("Failed to retrieve ipam driver for network %q (%s): %v", n.Name(), n.ID(), err)
792 792
 		return false
793 793
 	}
794 794
 	return caps.RequiresRequestReplay
... ...
@@ -815,7 +816,7 @@ func (c *controller) Networks() []Network {
815 815
 
816 816
 	networks, err := c.getNetworksFromStore()
817 817
 	if err != nil {
818
-		log.Error(err)
818
+		logrus.Error(err)
819 819
 	}
820 820
 
821 821
 	for _, n := range networks {
... ...
@@ -1132,18 +1133,18 @@ func (c *controller) clearIngress(clusterLeave bool) {
1132 1132
 
1133 1133
 	if ingressSandbox != nil {
1134 1134
 		if err := ingressSandbox.Delete(); err != nil {
1135
-			log.Warnf("Could not delete ingress sandbox while leaving: %v", err)
1135
+			logrus.Warnf("Could not delete ingress sandbox while leaving: %v", err)
1136 1136
 		}
1137 1137
 	}
1138 1138
 
1139 1139
 	n, err := c.NetworkByName("ingress")
1140 1140
 	if err != nil && clusterLeave {
1141
-		log.Warnf("Could not find ingress network while leaving: %v", err)
1141
+		logrus.Warnf("Could not find ingress network while leaving: %v", err)
1142 1142
 	}
1143 1143
 
1144 1144
 	if n != nil {
1145 1145
 		if err := n.Delete(); err != nil {
1146
-			log.Warnf("Could not delete ingress network while leaving: %v", err)
1146
+			logrus.Warnf("Could not delete ingress network while leaving: %v", err)
1147 1147
 		}
1148 1148
 	}
1149 1149
 }
... ...
@@ -6,6 +6,7 @@ import (
6 6
 	"reflect"
7 7
 	"strings"
8 8
 	"sync"
9
+	"time"
9 10
 
10 11
 	"github.com/docker/libkv"
11 12
 	"github.com/docker/libkv/store"
... ...
@@ -134,7 +135,8 @@ func makeDefaultScopes() map[string]*ScopeCfg {
134 134
 			Provider: string(store.BOLTDB),
135 135
 			Address:  defaultPrefix + "/local-kv.db",
136 136
 			Config: &store.Config{
137
-				Bucket: "libnetwork",
137
+				Bucket:            "libnetwork",
138
+				ConnectionTimeout: time.Minute,
138 139
 			},
139 140
 		},
140 141
 	}
... ...
@@ -2,13 +2,14 @@ package libnetwork
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"strings"
5 6
 
7
+	"github.com/docker/libnetwork/netlabel"
6 8
 	"github.com/docker/libnetwork/types"
7 9
 )
8 10
 
9 11
 const (
10
-	libnGWNetwork = "docker_gwbridge"
11
-	gwEPlen       = 12
12
+	gwEPlen = 12
12 13
 )
13 14
 
14 15
 var procGwNetwork = make(chan (bool), 1)
... ...
@@ -52,6 +53,21 @@ func (sb *sandbox) setupDefaultGW() error {
52 52
 		eplen = len(sb.containerID)
53 53
 	}
54 54
 
55
+	sbLabels := sb.Labels()
56
+
57
+	if sbLabels[netlabel.PortMap] != nil {
58
+		createOptions = append(createOptions, CreateOptionPortMapping(sbLabels[netlabel.PortMap].([]types.PortBinding)))
59
+	}
60
+
61
+	if sbLabels[netlabel.ExposedPorts] != nil {
62
+		createOptions = append(createOptions, CreateOptionExposedPorts(sbLabels[netlabel.ExposedPorts].([]types.TransportPort)))
63
+	}
64
+
65
+	epOption := getPlatformOption()
66
+	if epOption != nil {
67
+		createOptions = append(createOptions, epOption)
68
+	}
69
+
55 70
 	newEp, err := n.CreateEndpoint("gateway_"+sb.containerID[0:eplen], createOptions...)
56 71
 	if err != nil {
57 72
 		return fmt.Errorf("container %s: endpoint create on GW Network failed: %v", sb.containerID, err)
... ...
@@ -119,7 +135,7 @@ func (sb *sandbox) needDefaultGW() bool {
119 119
 
120 120
 func (sb *sandbox) getEndpointInGWNetwork() *endpoint {
121 121
 	for _, ep := range sb.getConnectedEndpoints() {
122
-		if ep.getNetwork().name == libnGWNetwork {
122
+		if ep.getNetwork().name == libnGWNetwork && strings.HasPrefix(ep.Name(), "gateway_") {
123 123
 			return ep
124 124
 		}
125 125
 	}
... ...
@@ -127,7 +143,7 @@ func (sb *sandbox) getEndpointInGWNetwork() *endpoint {
127 127
 }
128 128
 
129 129
 func (ep *endpoint) endpointInGWNetwork() bool {
130
-	if ep.getNetwork().name == libnGWNetwork {
130
+	if ep.getNetwork().name == libnGWNetwork && strings.HasPrefix(ep.Name(), "gateway_") {
131 131
 		return true
132 132
 	}
133 133
 	return false
... ...
@@ -2,6 +2,12 @@ package libnetwork
2 2
 
3 3
 import "github.com/docker/libnetwork/types"
4 4
 
5
+const libnGWNetwork = "docker_gwbridge"
6
+
7
+func getPlatformOption() EndpointOption {
8
+	return nil
9
+}
10
+
5 11
 func (c *controller) createGWNetwork() (Network, error) {
6 12
 	return nil, types.NotImplementedErrorf("default gateway functionality is not implemented in freebsd")
7 13
 }
... ...
@@ -7,6 +7,12 @@ import (
7 7
 	"github.com/docker/libnetwork/drivers/bridge"
8 8
 )
9 9
 
10
+const libnGWNetwork = "docker_gwbridge"
11
+
12
+func getPlatformOption() EndpointOption {
13
+	return nil
14
+}
15
+
10 16
 func (c *controller) createGWNetwork() (Network, error) {
11 17
 	netOption := map[string]string{
12 18
 		bridge.BridgeName:         libnGWNetwork,
... ...
@@ -1,7 +1,32 @@
1 1
 package libnetwork
2 2
 
3
-import "github.com/docker/libnetwork/types"
3
+import (
4
+	"fmt"
5
+	"strconv"
6
+
7
+	"github.com/docker/libnetwork/drivers/solaris/bridge"
8
+)
9
+
10
+const libnGWNetwork = "docker_gwbridge"
11
+
12
+func getPlatformOption() EndpointOption {
13
+	return nil
14
+}
4 15
 
5 16
 func (c *controller) createGWNetwork() (Network, error) {
6
-	return nil, types.NotImplementedErrorf("default gateway functionality is not implemented in solaris")
17
+	netOption := map[string]string{
18
+		bridge.BridgeName:         libnGWNetwork,
19
+		bridge.EnableICC:          strconv.FormatBool(false),
20
+		bridge.EnableIPMasquerade: strconv.FormatBool(true),
21
+	}
22
+
23
+	n, err := c.NewNetwork("bridge", libnGWNetwork, "",
24
+		NetworkOptionDriverOpts(netOption),
25
+		NetworkOptionEnableIPv6(false),
26
+	)
27
+
28
+	if err != nil {
29
+		return nil, fmt.Errorf("error creating external connectivity network: %v", err)
30
+	}
31
+	return n, err
7 32
 }
... ...
@@ -1,6 +1,21 @@
1 1
 package libnetwork
2 2
 
3
-import "github.com/docker/libnetwork/types"
3
+import (
4
+	windriver "github.com/docker/libnetwork/drivers/windows"
5
+	"github.com/docker/libnetwork/options"
6
+	"github.com/docker/libnetwork/types"
7
+)
8
+
9
+const libnGWNetwork = "nat"
10
+
11
+func getPlatformOption() EndpointOption {
12
+
13
+	epOption := options.Generic{
14
+		windriver.DisableICC: true,
15
+		windriver.DisableDNS: true,
16
+	}
17
+	return EndpointOptionGeneric(epOption)
18
+}
4 19
 
5 20
 func (c *controller) createGWNetwork() (Network, error) {
6 21
 	return nil, types.NotImplementedErrorf("default gateway functionality is not implemented in windows")
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"fmt"
5 5
 	"net"
6 6
 
7
-	log "github.com/Sirupsen/logrus"
7
+	"github.com/Sirupsen/logrus"
8 8
 	"github.com/docker/libnetwork/iptables"
9 9
 	"github.com/docker/libnetwork/types"
10 10
 )
... ...
@@ -44,7 +44,7 @@ func (l *link) Disable() {
44 44
 	// -D == iptables delete flag
45 45
 	err := linkContainers("-D", l.parentIP, l.childIP, l.ports, l.bridge, true)
46 46
 	if err != nil {
47
-		log.Errorf("Error removing IPTables rules for a link %s due to %s", l.String(), err.Error())
47
+		logrus.Errorf("Error removing IPTables rules for a link %s due to %s", l.String(), err.Error())
48 48
 	}
49 49
 	// Return proper error once we move to use a proper iptables package
50 50
 	// that returns typed errors
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"net"
7 7
 	"path/filepath"
8 8
 
9
-	log "github.com/Sirupsen/logrus"
9
+	"github.com/Sirupsen/logrus"
10 10
 	"github.com/docker/libnetwork/types"
11 11
 	"github.com/vishvananda/netlink"
12 12
 )
... ...
@@ -39,7 +39,7 @@ func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
39 39
 				return fmt.Errorf("failed to remove current ip address from bridge: %v", err)
40 40
 			}
41 41
 		}
42
-		log.Debugf("Assigning address to bridge interface %s: %s", config.BridgeName, config.AddressIPv4)
42
+		logrus.Debugf("Assigning address to bridge interface %s: %s", config.BridgeName, config.AddressIPv4)
43 43
 		if err := i.nlh.AddrAdd(i.Link, &netlink.Addr{IPNet: config.AddressIPv4}); err != nil {
44 44
 			return &IPv4AddrAddError{IP: config.AddressIPv4, Err: err}
45 45
 		}
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"fmt"
5 5
 	"strings"
6 6
 
7
-	log "github.com/Sirupsen/logrus"
7
+	"github.com/Sirupsen/logrus"
8 8
 	"github.com/docker/libnetwork/ns"
9 9
 	"github.com/docker/libnetwork/types"
10 10
 	"github.com/vishvananda/netlink"
... ...
@@ -39,7 +39,7 @@ func setupVerifyAndReconcile(config *networkConfiguration, i *bridgeInterface) e
39 39
 	for _, addrv6 := range addrsv6 {
40 40
 		if addrv6.IP.IsGlobalUnicast() && !types.CompareIPNet(addrv6.IPNet, i.bridgeIPv6) {
41 41
 			if err := i.nlh.AddrDel(i.Link, &addrv6); err != nil {
42
-				log.Warnf("Failed to remove residual IPv6 address %s from bridge: %v", addrv6.IPNet, err)
42
+				logrus.Warnf("Failed to remove residual IPv6 address %s from bridge: %v", addrv6.IPNet, err)
43 43
 			}
44 44
 		}
45 45
 	}
... ...
@@ -12,7 +12,7 @@ import (
12 12
 
13 13
 	"strconv"
14 14
 
15
-	log "github.com/Sirupsen/logrus"
15
+	"github.com/Sirupsen/logrus"
16 16
 	"github.com/docker/libnetwork/iptables"
17 17
 	"github.com/docker/libnetwork/ns"
18 18
 	"github.com/docker/libnetwork/types"
... ...
@@ -77,7 +77,7 @@ func (e *encrMap) String() string {
77 77
 }
78 78
 
79 79
 func (d *driver) checkEncryption(nid string, rIP net.IP, vxlanID uint32, isLocal, add bool) error {
80
-	log.Debugf("checkEncryption(%s, %v, %d, %t)", nid[0:7], rIP, vxlanID, isLocal)
80
+	logrus.Debugf("checkEncryption(%s, %v, %d, %t)", nid[0:7], rIP, vxlanID, isLocal)
81 81
 
82 82
 	n := d.network(nid)
83 83
 	if n == nil || !n.secure {
... ...
@@ -100,7 +100,7 @@ func (d *driver) checkEncryption(nid string, rIP net.IP, vxlanID uint32, isLocal
100 100
 			}
101 101
 			return false
102 102
 		}); err != nil {
103
-			log.Warnf("Failed to retrieve list of participating nodes in overlay network %s: %v", nid[0:5], err)
103
+			logrus.Warnf("Failed to retrieve list of participating nodes in overlay network %s: %v", nid[0:5], err)
104 104
 		}
105 105
 	default:
106 106
 		if len(d.network(nid).endpoints) > 0 {
... ...
@@ -108,18 +108,18 @@ func (d *driver) checkEncryption(nid string, rIP net.IP, vxlanID uint32, isLocal
108 108
 		}
109 109
 	}
110 110
 
111
-	log.Debugf("List of nodes: %s", nodes)
111
+	logrus.Debugf("List of nodes: %s", nodes)
112 112
 
113 113
 	if add {
114 114
 		for _, rIP := range nodes {
115 115
 			if err := setupEncryption(lIP, aIP, rIP, vxlanID, d.secMap, d.keys); err != nil {
116
-				log.Warnf("Failed to program network encryption between %s and %s: %v", lIP, rIP, err)
116
+				logrus.Warnf("Failed to program network encryption between %s and %s: %v", lIP, rIP, err)
117 117
 			}
118 118
 		}
119 119
 	} else {
120 120
 		if len(nodes) == 0 {
121 121
 			if err := removeEncryption(lIP, rIP, d.secMap); err != nil {
122
-				log.Warnf("Failed to remove network encryption between %s and %s: %v", lIP, rIP, err)
122
+				logrus.Warnf("Failed to remove network encryption between %s and %s: %v", lIP, rIP, err)
123 123
 			}
124 124
 		}
125 125
 	}
... ...
@@ -128,14 +128,14 @@ func (d *driver) checkEncryption(nid string, rIP net.IP, vxlanID uint32, isLocal
128 128
 }
129 129
 
130 130
 func setupEncryption(localIP, advIP, remoteIP net.IP, vni uint32, em *encrMap, keys []*key) error {
131
-	log.Debugf("Programming encryption for vxlan %d between %s and %s", vni, localIP, remoteIP)
131
+	logrus.Debugf("Programming encryption for vxlan %d between %s and %s", vni, localIP, remoteIP)
132 132
 	rIPs := remoteIP.String()
133 133
 
134 134
 	indices := make([]*spi, 0, len(keys))
135 135
 
136 136
 	err := programMangle(vni, true)
137 137
 	if err != nil {
138
-		log.Warn(err)
138
+		logrus.Warn(err)
139 139
 	}
140 140
 
141 141
 	for i, k := range keys {
... ...
@@ -146,7 +146,7 @@ func setupEncryption(localIP, advIP, remoteIP net.IP, vni uint32, em *encrMap, k
146 146
 		}
147 147
 		fSA, rSA, err := programSA(localIP, remoteIP, spis, k, dir, true)
148 148
 		if err != nil {
149
-			log.Warn(err)
149
+			logrus.Warn(err)
150 150
 		}
151 151
 		indices = append(indices, spis)
152 152
 		if i != 0 {
... ...
@@ -154,7 +154,7 @@ func setupEncryption(localIP, advIP, remoteIP net.IP, vni uint32, em *encrMap, k
154 154
 		}
155 155
 		err = programSP(fSA, rSA, true)
156 156
 		if err != nil {
157
-			log.Warn(err)
157
+			logrus.Warn(err)
158 158
 		}
159 159
 	}
160 160
 
... ...
@@ -179,14 +179,14 @@ func removeEncryption(localIP, remoteIP net.IP, em *encrMap) error {
179 179
 		}
180 180
 		fSA, rSA, err := programSA(localIP, remoteIP, idxs, nil, dir, false)
181 181
 		if err != nil {
182
-			log.Warn(err)
182
+			logrus.Warn(err)
183 183
 		}
184 184
 		if i != 0 {
185 185
 			continue
186 186
 		}
187 187
 		err = programSP(fSA, rSA, false)
188 188
 		if err != nil {
189
-			log.Warn(err)
189
+			logrus.Warn(err)
190 190
 		}
191 191
 	}
192 192
 	return nil
... ...
@@ -213,7 +213,7 @@ func programMangle(vni uint32, add bool) (err error) {
213 213
 	}
214 214
 
215 215
 	if err = iptables.RawCombinedOutput(append([]string{"-t", string(iptables.Mangle), a, chain}, rule...)...); err != nil {
216
-		log.Warnf("could not %s mangle rule: %v", action, err)
216
+		logrus.Warnf("could not %s mangle rule: %v", action, err)
217 217
 	}
218 218
 
219 219
 	return
... ...
@@ -248,9 +248,9 @@ func programSA(localIP, remoteIP net.IP, spi *spi, k *key, dir int, add bool) (f
248 248
 		}
249 249
 
250 250
 		if add != exists {
251
-			log.Debugf("%s: rSA{%s}", action, rSA)
251
+			logrus.Debugf("%s: rSA{%s}", action, rSA)
252 252
 			if err := xfrmProgram(rSA); err != nil {
253
-				log.Warnf("Failed %s rSA{%s}: %v", action, rSA, err)
253
+				logrus.Warnf("Failed %s rSA{%s}: %v", action, rSA, err)
254 254
 			}
255 255
 		}
256 256
 	}
... ...
@@ -273,9 +273,9 @@ func programSA(localIP, remoteIP net.IP, spi *spi, k *key, dir int, add bool) (f
273 273
 		}
274 274
 
275 275
 		if add != exists {
276
-			log.Debugf("%s fSA{%s}", action, fSA)
276
+			logrus.Debugf("%s fSA{%s}", action, fSA)
277 277
 			if err := xfrmProgram(fSA); err != nil {
278
-				log.Warnf("Failed %s fSA{%s}: %v.", action, fSA, err)
278
+				logrus.Warnf("Failed %s fSA{%s}: %v.", action, fSA, err)
279 279
 			}
280 280
 		}
281 281
 	}
... ...
@@ -319,9 +319,9 @@ func programSP(fSA *netlink.XfrmState, rSA *netlink.XfrmState, add bool) error {
319 319
 	}
320 320
 
321 321
 	if add != exists {
322
-		log.Debugf("%s fSP{%s}", action, fPol)
322
+		logrus.Debugf("%s fSP{%s}", action, fPol)
323 323
 		if err := xfrmProgram(fPol); err != nil {
324
-			log.Warnf("%s fSP{%s}: %v", action, fPol, err)
324
+			logrus.Warnf("%s fSP{%s}: %v", action, fPol, err)
325 325
 		}
326 326
 	}
327 327
 
... ...
@@ -337,7 +337,7 @@ func saExists(sa *netlink.XfrmState) (bool, error) {
337 337
 		return false, nil
338 338
 	default:
339 339
 		err = fmt.Errorf("Error while checking for SA existence: %v", err)
340
-		log.Warn(err)
340
+		logrus.Warn(err)
341 341
 		return false, err
342 342
 	}
343 343
 }
... ...
@@ -351,7 +351,7 @@ func spExists(sp *netlink.XfrmPolicy) (bool, error) {
351 351
 		return false, nil
352 352
 	default:
353 353
 		err = fmt.Errorf("Error while checking for SP existence: %v", err)
354
-		log.Warn(err)
354
+		logrus.Warn(err)
355 355
 		return false, err
356 356
 	}
357 357
 }
... ...
@@ -397,16 +397,16 @@ func (d *driver) setKeys(keys []*key) error {
397 397
 	d.keys = keys
398 398
 	d.secMap = &encrMap{nodes: map[string][]*spi{}}
399 399
 	d.Unlock()
400
-	log.Debugf("Initial encryption keys: %v", d.keys)
400
+	logrus.Debugf("Initial encryption keys: %v", d.keys)
401 401
 	return nil
402 402
 }
403 403
 
404 404
 // updateKeys allows to add a new key and/or change the primary key and/or prune an existing key
405 405
 // The primary key is the key used in transmission and will go in first position in the list.
406 406
 func (d *driver) updateKeys(newKey, primary, pruneKey *key) error {
407
-	log.Debugf("Updating Keys. New: %v, Primary: %v, Pruned: %v", newKey, primary, pruneKey)
407
+	logrus.Debugf("Updating Keys. New: %v, Primary: %v, Pruned: %v", newKey, primary, pruneKey)
408 408
 
409
-	log.Debugf("Current: %v", d.keys)
409
+	logrus.Debugf("Current: %v", d.keys)
410 410
 
411 411
 	var (
412 412
 		newIdx = -1
... ...
@@ -459,7 +459,7 @@ func (d *driver) updateKeys(newKey, primary, pruneKey *key) error {
459 459
 	}
460 460
 	d.Unlock()
461 461
 
462
-	log.Debugf("Updated: %v", d.keys)
462
+	logrus.Debugf("Updated: %v", d.keys)
463 463
 
464 464
 	return nil
465 465
 }
... ...
@@ -472,10 +472,10 @@ func (d *driver) updateKeys(newKey, primary, pruneKey *key) error {
472 472
 
473 473
 // Spis and keys are sorted in such away the one in position 0 is the primary
474 474
 func updateNodeKey(lIP, rIP net.IP, idxs []*spi, curKeys []*key, newIdx, priIdx, delIdx int) []*spi {
475
-	log.Debugf("Updating keys for node: %s (%d,%d,%d)", rIP, newIdx, priIdx, delIdx)
475
+	logrus.Debugf("Updating keys for node: %s (%d,%d,%d)", rIP, newIdx, priIdx, delIdx)
476 476
 
477 477
 	spis := idxs
478
-	log.Debugf("Current: %v", spis)
478
+	logrus.Debugf("Current: %v", spis)
479 479
 
480 480
 	// add new
481 481
 	if newIdx != -1 {
... ...
@@ -520,9 +520,9 @@ func updateNodeKey(lIP, rIP net.IP, idxs []*spi, curKeys []*key, newIdx, priIdx,
520 520
 				},
521 521
 			},
522 522
 		}
523
-		log.Debugf("Updating fSP{%s}", fSP1)
523
+		logrus.Debugf("Updating fSP{%s}", fSP1)
524 524
 		if err := ns.NlHandle().XfrmPolicyUpdate(fSP1); err != nil {
525
-			log.Warnf("Failed to update fSP{%s}: %v", fSP1, err)
525
+			logrus.Warnf("Failed to update fSP{%s}: %v", fSP1, err)
526 526
 		}
527 527
 
528 528
 		// -fSA1
... ...
@@ -543,7 +543,7 @@ func updateNodeKey(lIP, rIP net.IP, idxs []*spi, curKeys []*key, newIdx, priIdx,
543 543
 		spis = append(spis[:delIdx], spis[delIdx+1:]...)
544 544
 	}
545 545
 
546
-	log.Debugf("Updated: %v", spis)
546
+	logrus.Debugf("Updated: %v", spis)
547 547
 
548 548
 	return spis
549 549
 }
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"net"
6 6
 	"syscall"
7 7
 
8
-	log "github.com/Sirupsen/logrus"
8
+	"github.com/Sirupsen/logrus"
9 9
 	"github.com/docker/libnetwork/driverapi"
10 10
 	"github.com/docker/libnetwork/ns"
11 11
 	"github.com/docker/libnetwork/types"
... ...
@@ -109,7 +109,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
109 109
 			continue
110 110
 		}
111 111
 		if err := jinfo.AddStaticRoute(sub.subnetIP, types.NEXTHOP, s.gwIP.IP); err != nil {
112
-			log.Errorf("Adding subnet %s static route in network %q failed\n", s.subnetIP, n.id)
112
+			logrus.Errorf("Adding subnet %s static route in network %q failed\n", s.subnetIP, n.id)
113 113
 		}
114 114
 	}
115 115
 
... ...
@@ -124,7 +124,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
124 124
 		net.ParseIP(d.advertiseAddress), true)
125 125
 
126 126
 	if err := d.checkEncryption(nid, nil, n.vxlanID(s), true, true); err != nil {
127
-		log.Warn(err)
127
+		logrus.Warn(err)
128 128
 	}
129 129
 
130 130
 	buf, err := proto.Marshal(&PeerRecord{
... ...
@@ -137,7 +137,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
137 137
 	}
138 138
 
139 139
 	if err := jinfo.AddTableEntry(ovPeerTable, eid, buf); err != nil {
140
-		log.Errorf("overlay: Failed adding table entry to joininfo: %v", err)
140
+		logrus.Errorf("overlay: Failed adding table entry to joininfo: %v", err)
141 141
 	}
142 142
 
143 143
 	d.pushLocalEndpointEvent("join", nid, eid)
... ...
@@ -147,7 +147,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
147 147
 
148 148
 func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
149 149
 	if tableName != ovPeerTable {
150
-		log.Errorf("Unexpected table notification for table %s received", tableName)
150
+		logrus.Errorf("Unexpected table notification for table %s received", tableName)
151 151
 		return
152 152
 	}
153 153
 
... ...
@@ -155,7 +155,7 @@ func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key stri
155 155
 
156 156
 	var peer PeerRecord
157 157
 	if err := proto.Unmarshal(value, &peer); err != nil {
158
-		log.Errorf("Failed to unmarshal peer record: %v", err)
158
+		logrus.Errorf("Failed to unmarshal peer record: %v", err)
159 159
 		return
160 160
 	}
161 161
 
... ...
@@ -167,19 +167,19 @@ func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key stri
167 167
 
168 168
 	addr, err := types.ParseCIDR(peer.EndpointIP)
169 169
 	if err != nil {
170
-		log.Errorf("Invalid peer IP %s received in event notify", peer.EndpointIP)
170
+		logrus.Errorf("Invalid peer IP %s received in event notify", peer.EndpointIP)
171 171
 		return
172 172
 	}
173 173
 
174 174
 	mac, err := net.ParseMAC(peer.EndpointMAC)
175 175
 	if err != nil {
176
-		log.Errorf("Invalid mac %s received in event notify", peer.EndpointMAC)
176
+		logrus.Errorf("Invalid mac %s received in event notify", peer.EndpointMAC)
177 177
 		return
178 178
 	}
179 179
 
180 180
 	vtep := net.ParseIP(peer.TunnelEndpointIP)
181 181
 	if vtep == nil {
182
-		log.Errorf("Invalid VTEP %s received in event notify", peer.TunnelEndpointIP)
182
+		logrus.Errorf("Invalid VTEP %s received in event notify", peer.TunnelEndpointIP)
183 183
 		return
184 184
 	}
185 185
 
... ...
@@ -219,7 +219,7 @@ func (d *driver) Leave(nid, eid string) error {
219 219
 	n.leaveSandbox()
220 220
 
221 221
 	if err := d.checkEncryption(nid, nil, 0, true, false); err != nil {
222
-		log.Warn(err)
222
+		logrus.Warn(err)
223 223
 	}
224 224
 
225 225
 	return nil
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"fmt"
6 6
 	"net"
7 7
 
8
-	log "github.com/Sirupsen/logrus"
8
+	"github.com/Sirupsen/logrus"
9 9
 	"github.com/docker/libnetwork/datastore"
10 10
 	"github.com/docker/libnetwork/driverapi"
11 11
 	"github.com/docker/libnetwork/netutils"
... ...
@@ -116,7 +116,7 @@ func (d *driver) DeleteEndpoint(nid, eid string) error {
116 116
 	n.deleteEndpoint(eid)
117 117
 
118 118
 	if err := d.deleteEndpointFromStore(ep); err != nil {
119
-		log.Warnf("Failed to delete overlay endpoint %s from local store: %v", ep.id[0:7], err)
119
+		logrus.Warnf("Failed to delete overlay endpoint %s from local store: %v", ep.id[0:7], err)
120 120
 	}
121 121
 
122 122
 	if ep.ifName == "" {
... ...
@@ -125,11 +125,11 @@ func (d *driver) DeleteEndpoint(nid, eid string) error {
125 125
 
126 126
 	link, err := nlh.LinkByName(ep.ifName)
127 127
 	if err != nil {
128
-		log.Debugf("Failed to retrieve interface (%s)'s link on endpoint (%s) delete: %v", ep.ifName, ep.id, err)
128
+		logrus.Debugf("Failed to retrieve interface (%s)'s link on endpoint (%s) delete: %v", ep.ifName, ep.id, err)
129 129
 		return nil
130 130
 	}
131 131
 	if err := nlh.LinkDel(link); err != nil {
132
-		log.Debugf("Failed to delete interface (%s)'s link on endpoint (%s) delete: %v", ep.ifName, ep.id, err)
132
+		logrus.Debugf("Failed to delete interface (%s)'s link on endpoint (%s) delete: %v", ep.ifName, ep.id, err)
133 133
 	}
134 134
 
135 135
 	return nil
... ...
@@ -111,7 +111,7 @@ func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
111 111
 // Endpoints are stored in the local store. Restore them and reconstruct the overlay sandbox
112 112
 func (d *driver) restoreEndpoints() error {
113 113
 	if d.localStore == nil {
114
-		logrus.Warnf("Cannot restore overlay endpoints because local datastore is missing")
114
+		logrus.Warn("Cannot restore overlay endpoints because local datastore is missing")
115 115
 		return nil
116 116
 	}
117 117
 	kvol, err := d.localStore.List(datastore.Key(overlayEndpointPrefix), &endpoint{})
... ...
@@ -18,7 +18,7 @@ import (
18 18
 
19 19
 const (
20 20
 	networkType  = "overlay"
21
-	vxlanIDStart = 256
21
+	vxlanIDStart = 4096
22 22
 	vxlanIDEnd   = (1 << 24) - 1
23 23
 )
24 24
 
... ...
@@ -57,7 +57,7 @@ func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
57 57
 		config:   config,
58 58
 	}
59 59
 
60
-	d.vxlanIdm, err = idm.New(nil, "vxlan-id", vxlanIDStart, vxlanIDEnd)
60
+	d.vxlanIdm, err = idm.New(nil, "vxlan-id", 1, vxlanIDEnd)
61 61
 	if err != nil {
62 62
 		return fmt.Errorf("failed to initialize vxlan id manager: %v", err)
63 63
 	}
... ...
@@ -164,7 +164,7 @@ func (n *network) obtainVxlanID(s *subnet) error {
164 164
 	n.Unlock()
165 165
 
166 166
 	if vni == 0 {
167
-		vni, err = n.driver.vxlanIdm.GetID()
167
+		vni, err = n.driver.vxlanIdm.GetIDInRange(vxlanIDStart, vxlanIDEnd)
168 168
 		if err != nil {
169 169
 			return err
170 170
 		}
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"sync"
7 7
 	"syscall"
8 8
 
9
-	log "github.com/Sirupsen/logrus"
9
+	"github.com/Sirupsen/logrus"
10 10
 )
11 11
 
12 12
 const ovPeerTable = "overlay_peer_table"
... ...
@@ -90,7 +90,7 @@ func (d *driver) peerDbNetworkWalk(nid string, f func(*peerKey, *peerEntry) bool
90 90
 	for pKeyStr, pEntry := range pMap.mp {
91 91
 		var pKey peerKey
92 92
 		if _, err := fmt.Sscan(pKeyStr, &pKey); err != nil {
93
-			log.Warnf("Peer key scan on network %s failed: %v", nid, err)
93
+			logrus.Warnf("Peer key scan on network %s failed: %v", nid, err)
94 94
 		}
95 95
 
96 96
 		if f(&pKey, &pEntry) {
... ...
@@ -289,7 +289,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
289 289
 	}
290 290
 
291 291
 	if err := d.checkEncryption(nid, vtep, n.vxlanID(s), false, true); err != nil {
292
-		log.Warn(err)
292
+		logrus.Warn(err)
293 293
 	}
294 294
 
295 295
 	// Add neighbor entry for the peer IP
... ...
@@ -349,7 +349,7 @@ func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMas
349 349
 	}
350 350
 
351 351
 	if err := d.checkEncryption(nid, vtep, 0, false, false); err != nil {
352
-		log.Warn(err)
352
+		logrus.Warn(err)
353 353
 	}
354 354
 
355 355
 	return nil
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"fmt"
5 5
 	"net"
6 6
 
7
-	log "github.com/Sirupsen/logrus"
7
+	"github.com/Sirupsen/logrus"
8 8
 	"github.com/docker/docker/pkg/plugins"
9 9
 	"github.com/docker/libnetwork/datastore"
10 10
 	"github.com/docker/libnetwork/discoverapi"
... ...
@@ -39,11 +39,11 @@ func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
39 39
 		d := newDriver(name, client)
40 40
 		c, err := d.(*driver).getCapabilities()
41 41
 		if err != nil {
42
-			log.Errorf("error getting capability for %s due to %v", name, err)
42
+			logrus.Errorf("error getting capability for %s due to %v", name, err)
43 43
 			return
44 44
 		}
45 45
 		if err = dc.RegisterDriver(name, d, *c); err != nil {
46
-			log.Errorf("error registering driver for %s due to %v", name, err)
46
+			logrus.Errorf("error registering driver for %s due to %v", name, err)
47 47
 		}
48 48
 	})
49 49
 	return nil
... ...
@@ -390,7 +390,7 @@ func bridgeSetup(config *networkConfiguration) error {
390 390
 			"/usr/bin/grep " + config.DefaultBindingIP.String()
391 391
 		out, err := exec.Command("/usr/bin/bash", "-c", ipadmCmd).Output()
392 392
 		if err != nil {
393
-			logrus.Warnf("cannot find binding interface")
393
+			logrus.Warn("cannot find binding interface")
394 394
 			return err
395 395
 		}
396 396
 		bindingIntf = strings.SplitN(string(out), "/", 2)[0]
... ...
@@ -456,21 +456,21 @@ func bridgeCleanup(config *networkConfiguration, logErr bool) {
456 456
 
457 457
 	err = exec.Command("/usr/sbin/pfctl", "-a", pfAnchor, "-F", "all").Run()
458 458
 	if err != nil && logErr {
459
-		logrus.Warnf("cannot flush firewall rules")
459
+		logrus.Warn("cannot flush firewall rules")
460 460
 	}
461 461
 	err = exec.Command("/usr/sbin/ifconfig", gwName, "unplumb").Run()
462 462
 	if err != nil && logErr {
463
-		logrus.Warnf("cannot remove gateway interface")
463
+		logrus.Warn("cannot remove gateway interface")
464 464
 	}
465 465
 	err = exec.Command("/usr/sbin/dladm", "delete-vnic",
466 466
 		"-t", gwName).Run()
467 467
 	if err != nil && logErr {
468
-		logrus.Warnf("cannot delete vnic")
468
+		logrus.Warn("cannot delete vnic")
469 469
 	}
470 470
 	err = exec.Command("/usr/sbin/dladm", "delete-etherstub",
471 471
 		"-t", config.BridgeNameInternal).Run()
472 472
 	if err != nil && logErr {
473
-		logrus.Warnf("cannot delete etherstub")
473
+		logrus.Warn("cannot delete etherstub")
474 474
 	}
475 475
 	err = exec.Command("/usr/sbin/pfctl", "-a", tableAnchor, "-t", tableName, "-T", "delete", gwIP).Run()
476 476
 	if err != nil && logErr {
... ...
@@ -36,7 +36,7 @@ func addPFRules(epid, bindIntf string, bs []types.PortBinding) {
36 36
 	f, err := os.OpenFile(fname,
37 37
 		os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
38 38
 	if err != nil {
39
-		logrus.Warnf("cannot open temp pf file")
39
+		logrus.Warn("cannot open temp pf file")
40 40
 		return
41 41
 	}
42 42
 	for _, b := range bs {
43 43
new file mode 100644
... ...
@@ -0,0 +1,274 @@
0
+package overlay
1
+
2
+import (
3
+	"bytes"
4
+	"encoding/binary"
5
+	"encoding/hex"
6
+	"fmt"
7
+	"hash/fnv"
8
+	"net"
9
+	"sync"
10
+
11
+	"github.com/Sirupsen/logrus"
12
+	"github.com/docker/libnetwork/types"
13
+)
14
+
15
+const (
16
+	mark         = uint32(0xD0C4E3)
17
+	timeout      = 30
18
+	pktExpansion = 26 // SPI(4) + SeqN(4) + IV(8) + PadLength(1) + NextHeader(1) + ICV(8)
19
+)
20
+
21
+const (
22
+	forward = iota + 1
23
+	reverse
24
+	bidir
25
+)
26
+
27
+type key struct {
28
+	value []byte
29
+	tag   uint32
30
+}
31
+
32
+func (k *key) String() string {
33
+	if k != nil {
34
+		return fmt.Sprintf("(key: %s, tag: 0x%x)", hex.EncodeToString(k.value)[0:5], k.tag)
35
+	}
36
+	return ""
37
+}
38
+
39
+type spi struct {
40
+	forward int
41
+	reverse int
42
+}
43
+
44
+func (s *spi) String() string {
45
+	return fmt.Sprintf("SPI(FWD: 0x%x, REV: 0x%x)", uint32(s.forward), uint32(s.reverse))
46
+}
47
+
48
+type encrMap struct {
49
+	nodes map[string][]*spi
50
+	sync.Mutex
51
+}
52
+
53
+func (e *encrMap) String() string {
54
+	e.Lock()
55
+	defer e.Unlock()
56
+	b := new(bytes.Buffer)
57
+	for k, v := range e.nodes {
58
+		b.WriteString("\n")
59
+		b.WriteString(k)
60
+		b.WriteString(":")
61
+		b.WriteString("[")
62
+		for _, s := range v {
63
+			b.WriteString(s.String())
64
+			b.WriteString(",")
65
+		}
66
+		b.WriteString("]")
67
+
68
+	}
69
+	return b.String()
70
+}
71
+
72
+func (d *driver) checkEncryption(nid string, rIP net.IP, vxlanID uint32, isLocal, add bool) error {
73
+	logrus.Debugf("checkEncryption(%s, %v, %d, %t)", nid[0:7], rIP, vxlanID, isLocal)
74
+
75
+	n := d.network(nid)
76
+	if n == nil || !n.secure {
77
+		return nil
78
+	}
79
+
80
+	if len(d.keys) == 0 {
81
+		return types.ForbiddenErrorf("encryption key is not present")
82
+	}
83
+
84
+	lIP := net.ParseIP(d.bindAddress)
85
+	aIP := net.ParseIP(d.advertiseAddress)
86
+	nodes := map[string]net.IP{}
87
+
88
+	switch {
89
+	case isLocal:
90
+		if err := d.peerDbNetworkWalk(nid, func(pKey *peerKey, pEntry *peerEntry) bool {
91
+			if !aIP.Equal(pEntry.vtep) {
92
+				nodes[pEntry.vtep.String()] = pEntry.vtep
93
+			}
94
+			return false
95
+		}); err != nil {
96
+			logrus.Warnf("Failed to retrieve list of participating nodes in overlay network %s: %v", nid[0:5], err)
97
+		}
98
+	default:
99
+		if len(d.network(nid).endpoints) > 0 {
100
+			nodes[rIP.String()] = rIP
101
+		}
102
+	}
103
+
104
+	logrus.Debugf("List of nodes: %s", nodes)
105
+
106
+	if add {
107
+		for _, rIP := range nodes {
108
+			if err := setupEncryption(lIP, aIP, rIP, vxlanID, d.secMap, d.keys); err != nil {
109
+				logrus.Warnf("Failed to program network encryption between %s and %s: %v", lIP, rIP, err)
110
+			}
111
+		}
112
+	} else {
113
+		if len(nodes) == 0 {
114
+			if err := removeEncryption(lIP, rIP, d.secMap); err != nil {
115
+				logrus.Warnf("Failed to remove network encryption between %s and %s: %v", lIP, rIP, err)
116
+			}
117
+		}
118
+	}
119
+
120
+	return nil
121
+}
122
+
123
+func setupEncryption(localIP, advIP, remoteIP net.IP, vni uint32, em *encrMap, keys []*key) error {
124
+	logrus.Debugf("Programming encryption for vxlan %d between %s and %s", vni, localIP, remoteIP)
125
+	rIPs := remoteIP.String()
126
+
127
+	indices := make([]*spi, 0, len(keys))
128
+
129
+	err := programMangle(vni, true)
130
+	if err != nil {
131
+		logrus.Warn(err)
132
+	}
133
+
134
+	em.Lock()
135
+	em.nodes[rIPs] = indices
136
+	em.Unlock()
137
+
138
+	return nil
139
+}
140
+
141
+func removeEncryption(localIP, remoteIP net.IP, em *encrMap) error {
142
+	return nil
143
+}
144
+
145
+func programMangle(vni uint32, add bool) (err error) {
146
+	return
147
+}
148
+
149
+func buildSPI(src, dst net.IP, st uint32) int {
150
+	b := make([]byte, 4)
151
+	binary.BigEndian.PutUint32(b, st)
152
+	h := fnv.New32a()
153
+	h.Write(src)
154
+	h.Write(b)
155
+	h.Write(dst)
156
+	return int(binary.BigEndian.Uint32(h.Sum(nil)))
157
+}
158
+
159
+func (d *driver) secMapWalk(f func(string, []*spi) ([]*spi, bool)) error {
160
+	d.secMap.Lock()
161
+	for node, indices := range d.secMap.nodes {
162
+		idxs, stop := f(node, indices)
163
+		if idxs != nil {
164
+			d.secMap.nodes[node] = idxs
165
+		}
166
+		if stop {
167
+			break
168
+		}
169
+	}
170
+	d.secMap.Unlock()
171
+	return nil
172
+}
173
+
174
+func (d *driver) setKeys(keys []*key) error {
175
+	if d.keys != nil {
176
+		return types.ForbiddenErrorf("initial keys are already present")
177
+	}
178
+	d.keys = keys
179
+	logrus.Debugf("Initial encryption keys: %v", d.keys)
180
+	return nil
181
+}
182
+
183
+// updateKeys allows to add a new key and/or change the primary key and/or prune an existing key
184
+// The primary key is the key used in transmission and will go in first position in the list.
185
+func (d *driver) updateKeys(newKey, primary, pruneKey *key) error {
186
+	logrus.Debugf("Updating Keys. New: %v, Primary: %v, Pruned: %v", newKey, primary, pruneKey)
187
+
188
+	logrus.Debugf("Current: %v", d.keys)
189
+
190
+	var (
191
+		newIdx = -1
192
+		priIdx = -1
193
+		delIdx = -1
194
+		lIP    = net.ParseIP(d.bindAddress)
195
+	)
196
+
197
+	d.Lock()
198
+	// add new
199
+	if newKey != nil {
200
+		d.keys = append(d.keys, newKey)
201
+		newIdx += len(d.keys)
202
+	}
203
+	for i, k := range d.keys {
204
+		if primary != nil && k.tag == primary.tag {
205
+			priIdx = i
206
+		}
207
+		if pruneKey != nil && k.tag == pruneKey.tag {
208
+			delIdx = i
209
+		}
210
+	}
211
+	d.Unlock()
212
+
213
+	if (newKey != nil && newIdx == -1) ||
214
+		(primary != nil && priIdx == -1) ||
215
+		(pruneKey != nil && delIdx == -1) {
216
+		err := types.BadRequestErrorf("cannot find proper key indices while processing key update:"+
217
+			"(newIdx,priIdx,delIdx):(%d, %d, %d)", newIdx, priIdx, delIdx)
218
+		logrus.Warn(err)
219
+		return err
220
+	}
221
+
222
+	d.secMapWalk(func(rIPs string, spis []*spi) ([]*spi, bool) {
223
+		rIP := net.ParseIP(rIPs)
224
+		return updateNodeKey(lIP, rIP, spis, d.keys, newIdx, priIdx, delIdx), false
225
+	})
226
+
227
+	d.Lock()
228
+	// swap primary
229
+	if priIdx != -1 {
230
+		swp := d.keys[0]
231
+		d.keys[0] = d.keys[priIdx]
232
+		d.keys[priIdx] = swp
233
+	}
234
+	// prune
235
+	if delIdx != -1 {
236
+		if delIdx == 0 {
237
+			delIdx = priIdx
238
+		}
239
+		d.keys = append(d.keys[:delIdx], d.keys[delIdx+1:]...)
240
+	}
241
+	d.Unlock()
242
+
243
+	logrus.Debugf("Updated: %v", d.keys)
244
+
245
+	return nil
246
+}
247
+
248
+/********************************************************
249
+ * Steady state: rSA0, rSA1, rSA2, fSA1, fSP1
250
+ * Rotation --> -rSA0, +rSA3, +fSA2, +fSP2/-fSP1, -fSA1
251
+ * Steady state: rSA1, rSA2, rSA3, fSA2, fSP2
252
+ *********************************************************/
253
+
254
+// Spis and keys are sorted in such away the one in position 0 is the primary
255
+func updateNodeKey(lIP, rIP net.IP, idxs []*spi, curKeys []*key, newIdx, priIdx, delIdx int) []*spi {
256
+	logrus.Debugf("Updating keys for node: %s (%d,%d,%d)", rIP, newIdx, priIdx, delIdx)
257
+	return nil
258
+}
259
+
260
+func (n *network) maxMTU() int {
261
+	mtu := 1500
262
+	if n.mtu != 0 {
263
+		mtu = n.mtu
264
+	}
265
+	mtu -= vxlanEncap
266
+	if n.secure {
267
+		// In case of encryption account for the
268
+		// esp packet espansion and padding
269
+		mtu -= pktExpansion
270
+		mtu -= (mtu % 4)
271
+	}
272
+	return mtu
273
+}
0 274
new file mode 100644
... ...
@@ -0,0 +1,184 @@
0
+package overlay
1
+
2
+import (
3
+	"fmt"
4
+	"net"
5
+
6
+	"github.com/Sirupsen/logrus"
7
+	"github.com/docker/libnetwork/driverapi"
8
+	"github.com/docker/libnetwork/types"
9
+	"github.com/gogo/protobuf/proto"
10
+)
11
+
12
+// Join method is invoked when a Sandbox is attached to an endpoint.
13
+func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
14
+	if err := validateID(nid, eid); err != nil {
15
+		return err
16
+	}
17
+
18
+	n := d.network(nid)
19
+	if n == nil {
20
+		return fmt.Errorf("could not find network with id %s", nid)
21
+	}
22
+
23
+	ep := n.endpoint(eid)
24
+	if ep == nil {
25
+		return fmt.Errorf("could not find endpoint with id %s", eid)
26
+	}
27
+
28
+	if n.secure && len(d.keys) == 0 {
29
+		return fmt.Errorf("cannot join secure network: encryption keys not present")
30
+	}
31
+
32
+	s := n.getSubnetforIP(ep.addr)
33
+	if s == nil {
34
+		return fmt.Errorf("could not find subnet for endpoint %s", eid)
35
+	}
36
+
37
+	if err := n.obtainVxlanID(s); err != nil {
38
+		return fmt.Errorf("couldn't get vxlan id for %q: %v", s.subnetIP.String(), err)
39
+	}
40
+
41
+	if err := n.joinSandbox(false); err != nil {
42
+		return fmt.Errorf("network sandbox join failed: %v", err)
43
+	}
44
+
45
+	if err := n.joinSubnetSandbox(s, false); err != nil {
46
+		return fmt.Errorf("subnet sandbox join failed for %q: %v", s.subnetIP.String(), err)
47
+	}
48
+
49
+	// joinSubnetSandbox gets called when an endpoint comes up on a new subnet in the
50
+	// overlay network. Hence the Endpoint count should be updated outside joinSubnetSandbox
51
+	n.incEndpointCount()
52
+
53
+	// Add creating a veth Pair for Solaris
54
+
55
+	containerIfName := "solaris-if"
56
+	ep.ifName = containerIfName
57
+
58
+	if err := d.writeEndpointToStore(ep); err != nil {
59
+		return fmt.Errorf("failed to update overlay endpoint %s to local data store: %v", ep.id[0:7], err)
60
+	}
61
+
62
+	// Add solaris plumbing to add veth (with ep mac addr) to sandbox
63
+
64
+	for _, sub := range n.subnets {
65
+		if sub == s {
66
+			continue
67
+		}
68
+		if err := jinfo.AddStaticRoute(sub.subnetIP, types.NEXTHOP, s.gwIP.IP); err != nil {
69
+			logrus.Errorf("Adding subnet %s static route in network %q failed\n", s.subnetIP, n.id)
70
+		}
71
+	}
72
+
73
+	if iNames := jinfo.InterfaceName(); iNames != nil {
74
+		err := iNames.SetNames(containerIfName, "eth")
75
+		if err != nil {
76
+			return err
77
+		}
78
+	}
79
+
80
+	d.peerDbAdd(nid, eid, ep.addr.IP, ep.addr.Mask, ep.mac,
81
+		net.ParseIP(d.advertiseAddress), true)
82
+
83
+	if err := d.checkEncryption(nid, nil, n.vxlanID(s), true, true); err != nil {
84
+		logrus.Warn(err)
85
+	}
86
+
87
+	buf, err := proto.Marshal(&PeerRecord{
88
+		EndpointIP:       ep.addr.String(),
89
+		EndpointMAC:      ep.mac.String(),
90
+		TunnelEndpointIP: d.advertiseAddress,
91
+	})
92
+	if err != nil {
93
+		return err
94
+	}
95
+
96
+	if err := jinfo.AddTableEntry(ovPeerTable, eid, buf); err != nil {
97
+		logrus.Errorf("overlay: Failed adding table entry to joininfo: %v", err)
98
+	}
99
+
100
+	d.pushLocalEndpointEvent("join", nid, eid)
101
+
102
+	return nil
103
+}
104
+
105
+func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
106
+	if tableName != ovPeerTable {
107
+		logrus.Errorf("Unexpected table notification for table %s received", tableName)
108
+		return
109
+	}
110
+
111
+	eid := key
112
+
113
+	var peer PeerRecord
114
+	if err := proto.Unmarshal(value, &peer); err != nil {
115
+		logrus.Errorf("Failed to unmarshal peer record: %v", err)
116
+		return
117
+	}
118
+
119
+	// Ignore local peers. We already know about them and they
120
+	// should not be added to vxlan fdb.
121
+	if peer.TunnelEndpointIP == d.advertiseAddress {
122
+		return
123
+	}
124
+
125
+	addr, err := types.ParseCIDR(peer.EndpointIP)
126
+	if err != nil {
127
+		logrus.Errorf("Invalid peer IP %s received in event notify", peer.EndpointIP)
128
+		return
129
+	}
130
+
131
+	mac, err := net.ParseMAC(peer.EndpointMAC)
132
+	if err != nil {
133
+		logrus.Errorf("Invalid mac %s received in event notify", peer.EndpointMAC)
134
+		return
135
+	}
136
+
137
+	vtep := net.ParseIP(peer.TunnelEndpointIP)
138
+	if vtep == nil {
139
+		logrus.Errorf("Invalid VTEP %s received in event notify", peer.TunnelEndpointIP)
140
+		return
141
+	}
142
+
143
+	if etype == driverapi.Delete {
144
+		d.peerDelete(nid, eid, addr.IP, addr.Mask, mac, vtep, true)
145
+		return
146
+	}
147
+
148
+	d.peerAdd(nid, eid, addr.IP, addr.Mask, mac, vtep, true)
149
+}
150
+
151
+// Leave method is invoked when a Sandbox detaches from an endpoint.
152
+func (d *driver) Leave(nid, eid string) error {
153
+	if err := validateID(nid, eid); err != nil {
154
+		return err
155
+	}
156
+
157
+	n := d.network(nid)
158
+	if n == nil {
159
+		return fmt.Errorf("could not find network with id %s", nid)
160
+	}
161
+
162
+	ep := n.endpoint(eid)
163
+
164
+	if ep == nil {
165
+		return types.InternalMaskableErrorf("could not find endpoint with id %s", eid)
166
+	}
167
+
168
+	if d.notifyCh != nil {
169
+		d.notifyCh <- ovNotify{
170
+			action: "leave",
171
+			nw:     n,
172
+			ep:     ep,
173
+		}
174
+	}
175
+
176
+	n.leaveSandbox()
177
+
178
+	if err := d.checkEncryption(nid, nil, 0, true, false); err != nil {
179
+		logrus.Warn(err)
180
+	}
181
+
182
+	return nil
183
+}
0 184
new file mode 100644
... ...
@@ -0,0 +1,249 @@
0
+package overlay
1
+
2
+import (
3
+	"encoding/json"
4
+	"fmt"
5
+	"net"
6
+
7
+	"github.com/Sirupsen/logrus"
8
+	"github.com/docker/libnetwork/datastore"
9
+	"github.com/docker/libnetwork/driverapi"
10
+	"github.com/docker/libnetwork/netutils"
11
+	"github.com/docker/libnetwork/types"
12
+)
13
+
14
+type endpointTable map[string]*endpoint
15
+
16
+const overlayEndpointPrefix = "overlay/endpoint"
17
+
18
+type endpoint struct {
19
+	id       string
20
+	nid      string
21
+	ifName   string
22
+	mac      net.HardwareAddr
23
+	addr     *net.IPNet
24
+	dbExists bool
25
+	dbIndex  uint64
26
+}
27
+
28
+func (n *network) endpoint(eid string) *endpoint {
29
+	n.Lock()
30
+	defer n.Unlock()
31
+
32
+	return n.endpoints[eid]
33
+}
34
+
35
+func (n *network) addEndpoint(ep *endpoint) {
36
+	n.Lock()
37
+	n.endpoints[ep.id] = ep
38
+	n.Unlock()
39
+}
40
+
41
+func (n *network) deleteEndpoint(eid string) {
42
+	n.Lock()
43
+	delete(n.endpoints, eid)
44
+	n.Unlock()
45
+}
46
+
47
+func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
48
+	epOptions map[string]interface{}) error {
49
+	var err error
50
+
51
+	if err = validateID(nid, eid); err != nil {
52
+		return err
53
+	}
54
+
55
+	// Since we perform lazy configuration make sure we try
56
+	// configuring the driver when we enter CreateEndpoint since
57
+	// CreateNetwork may not be called in every node.
58
+	if err := d.configure(); err != nil {
59
+		return err
60
+	}
61
+
62
+	n := d.network(nid)
63
+	if n == nil {
64
+		return fmt.Errorf("network id %q not found", nid)
65
+	}
66
+
67
+	ep := &endpoint{
68
+		id:   eid,
69
+		nid:  n.id,
70
+		addr: ifInfo.Address(),
71
+		mac:  ifInfo.MacAddress(),
72
+	}
73
+	if ep.addr == nil {
74
+		return fmt.Errorf("create endpoint was not passed interface IP address")
75
+	}
76
+
77
+	if s := n.getSubnetforIP(ep.addr); s == nil {
78
+		return fmt.Errorf("no matching subnet for IP %q in network %q\n", ep.addr, nid)
79
+	}
80
+
81
+	if ep.mac == nil {
82
+		ep.mac = netutils.GenerateMACFromIP(ep.addr.IP)
83
+		if err := ifInfo.SetMacAddress(ep.mac); err != nil {
84
+			return err
85
+		}
86
+	}
87
+
88
+	n.addEndpoint(ep)
89
+
90
+	if err := d.writeEndpointToStore(ep); err != nil {
91
+		return fmt.Errorf("failed to update overlay endpoint %s to local store: %v", ep.id[0:7], err)
92
+	}
93
+
94
+	return nil
95
+}
96
+
97
+func (d *driver) DeleteEndpoint(nid, eid string) error {
98
+	if err := validateID(nid, eid); err != nil {
99
+		return err
100
+	}
101
+
102
+	n := d.network(nid)
103
+	if n == nil {
104
+		return fmt.Errorf("network id %q not found", nid)
105
+	}
106
+
107
+	ep := n.endpoint(eid)
108
+	if ep == nil {
109
+		return fmt.Errorf("endpoint id %q not found", eid)
110
+	}
111
+
112
+	n.deleteEndpoint(eid)
113
+
114
+	if err := d.deleteEndpointFromStore(ep); err != nil {
115
+		logrus.Warnf("Failed to delete overlay endpoint %s from local store: %v", ep.id[0:7], err)
116
+	}
117
+
118
+	if ep.ifName == "" {
119
+		return nil
120
+	}
121
+
122
+	// OVERLAY_SOLARIS: Add Solaris unplumbing for removing the interface endpoint
123
+
124
+	return nil
125
+}
126
+
127
+func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) {
128
+	return make(map[string]interface{}, 0), nil
129
+}
130
+
131
+func (d *driver) deleteEndpointFromStore(e *endpoint) error {
132
+	if d.localStore == nil {
133
+		return fmt.Errorf("overlay local store not initialized, ep not deleted")
134
+	}
135
+
136
+	if err := d.localStore.DeleteObjectAtomic(e); err != nil {
137
+		return err
138
+	}
139
+
140
+	return nil
141
+}
142
+
143
+func (d *driver) writeEndpointToStore(e *endpoint) error {
144
+	if d.localStore == nil {
145
+		return fmt.Errorf("overlay local store not initialized, ep not added")
146
+	}
147
+
148
+	if err := d.localStore.PutObjectAtomic(e); err != nil {
149
+		return err
150
+	}
151
+	return nil
152
+}
153
+
154
+func (ep *endpoint) DataScope() string {
155
+	return datastore.LocalScope
156
+}
157
+
158
+func (ep *endpoint) New() datastore.KVObject {
159
+	return &endpoint{}
160
+}
161
+
162
+func (ep *endpoint) CopyTo(o datastore.KVObject) error {
163
+	dstep := o.(*endpoint)
164
+	*dstep = *ep
165
+	return nil
166
+}
167
+
168
+func (ep *endpoint) Key() []string {
169
+	return []string{overlayEndpointPrefix, ep.id}
170
+}
171
+
172
+func (ep *endpoint) KeyPrefix() []string {
173
+	return []string{overlayEndpointPrefix}
174
+}
175
+
176
+func (ep *endpoint) Index() uint64 {
177
+	return ep.dbIndex
178
+}
179
+
180
+func (ep *endpoint) SetIndex(index uint64) {
181
+	ep.dbIndex = index
182
+	ep.dbExists = true
183
+}
184
+
185
+func (ep *endpoint) Exists() bool {
186
+	return ep.dbExists
187
+}
188
+
189
+func (ep *endpoint) Skip() bool {
190
+	return false
191
+}
192
+
193
+func (ep *endpoint) Value() []byte {
194
+	b, err := json.Marshal(ep)
195
+	if err != nil {
196
+		return nil
197
+	}
198
+	return b
199
+}
200
+
201
+func (ep *endpoint) SetValue(value []byte) error {
202
+	return json.Unmarshal(value, ep)
203
+}
204
+
205
+func (ep *endpoint) MarshalJSON() ([]byte, error) {
206
+	epMap := make(map[string]interface{})
207
+
208
+	epMap["id"] = ep.id
209
+	epMap["nid"] = ep.nid
210
+	if ep.ifName != "" {
211
+		epMap["ifName"] = ep.ifName
212
+	}
213
+	if ep.addr != nil {
214
+		epMap["addr"] = ep.addr.String()
215
+	}
216
+	if len(ep.mac) != 0 {
217
+		epMap["mac"] = ep.mac.String()
218
+	}
219
+
220
+	return json.Marshal(epMap)
221
+}
222
+
223
+func (ep *endpoint) UnmarshalJSON(value []byte) error {
224
+	var (
225
+		err   error
226
+		epMap map[string]interface{}
227
+	)
228
+
229
+	json.Unmarshal(value, &epMap)
230
+
231
+	ep.id = epMap["id"].(string)
232
+	ep.nid = epMap["nid"].(string)
233
+	if v, ok := epMap["mac"]; ok {
234
+		if ep.mac, err = net.ParseMAC(v.(string)); err != nil {
235
+			return types.InternalErrorf("failed to decode endpoint interface mac address after json unmarshal: %s", v.(string))
236
+		}
237
+	}
238
+	if v, ok := epMap["addr"]; ok {
239
+		if ep.addr, err = types.ParseCIDR(v.(string)); err != nil {
240
+			return types.InternalErrorf("failed to decode endpoint interface ipv4 address after json unmarshal: %v", err)
241
+		}
242
+	}
243
+	if v, ok := epMap["ifName"]; ok {
244
+		ep.ifName = v.(string)
245
+	}
246
+
247
+	return nil
248
+}
0 249
new file mode 100644
... ...
@@ -0,0 +1,791 @@
0
+package overlay
1
+
2
+import (
3
+	"encoding/json"
4
+	"fmt"
5
+	"net"
6
+	"os"
7
+	"path/filepath"
8
+	"strconv"
9
+	"strings"
10
+	"sync"
11
+
12
+	"github.com/Sirupsen/logrus"
13
+	"github.com/docker/libnetwork/datastore"
14
+	"github.com/docker/libnetwork/driverapi"
15
+	"github.com/docker/libnetwork/netlabel"
16
+	"github.com/docker/libnetwork/netutils"
17
+	"github.com/docker/libnetwork/osl"
18
+	"github.com/docker/libnetwork/resolvconf"
19
+	"github.com/docker/libnetwork/types"
20
+)
21
+
22
+var (
23
+	hostMode    bool
24
+	networkOnce sync.Once
25
+	networkMu   sync.Mutex
26
+	vniTbl      = make(map[uint32]string)
27
+)
28
+
29
+type networkTable map[string]*network
30
+
31
+type subnet struct {
32
+	once      *sync.Once
33
+	vxlanName string
34
+	brName    string
35
+	vni       uint32
36
+	initErr   error
37
+	subnetIP  *net.IPNet
38
+	gwIP      *net.IPNet
39
+}
40
+
41
+type subnetJSON struct {
42
+	SubnetIP string
43
+	GwIP     string
44
+	Vni      uint32
45
+}
46
+
47
+type network struct {
48
+	id        string
49
+	dbIndex   uint64
50
+	dbExists  bool
51
+	sbox      osl.Sandbox
52
+	endpoints endpointTable
53
+	driver    *driver
54
+	joinCnt   int
55
+	once      *sync.Once
56
+	initEpoch int
57
+	initErr   error
58
+	subnets   []*subnet
59
+	secure    bool
60
+	mtu       int
61
+	sync.Mutex
62
+}
63
+
64
+func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) {
65
+	return nil, types.NotImplementedErrorf("not implemented")
66
+}
67
+
68
+func (d *driver) NetworkFree(id string) error {
69
+	return types.NotImplementedErrorf("not implemented")
70
+}
71
+
72
+func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
73
+	if id == "" {
74
+		return fmt.Errorf("invalid network id")
75
+	}
76
+	if len(ipV4Data) == 0 || ipV4Data[0].Pool.String() == "0.0.0.0/0" {
77
+		return types.BadRequestErrorf("ipv4 pool is empty")
78
+	}
79
+
80
+	// Since we perform lazy configuration make sure we try
81
+	// configuring the driver when we enter CreateNetwork
82
+	if err := d.configure(); err != nil {
83
+		return err
84
+	}
85
+
86
+	n := &network{
87
+		id:        id,
88
+		driver:    d,
89
+		endpoints: endpointTable{},
90
+		once:      &sync.Once{},
91
+		subnets:   []*subnet{},
92
+	}
93
+
94
+	vnis := make([]uint32, 0, len(ipV4Data))
95
+	if gval, ok := option[netlabel.GenericData]; ok {
96
+		optMap := gval.(map[string]string)
97
+		if val, ok := optMap[netlabel.OverlayVxlanIDList]; ok {
98
+			logrus.Debugf("overlay: Received vxlan IDs: %s", val)
99
+			vniStrings := strings.Split(val, ",")
100
+			for _, vniStr := range vniStrings {
101
+				vni, err := strconv.Atoi(vniStr)
102
+				if err != nil {
103
+					return fmt.Errorf("invalid vxlan id value %q passed", vniStr)
104
+				}
105
+
106
+				vnis = append(vnis, uint32(vni))
107
+			}
108
+		}
109
+		if _, ok := optMap[secureOption]; ok {
110
+			n.secure = true
111
+		}
112
+		if val, ok := optMap[netlabel.DriverMTU]; ok {
113
+			var err error
114
+			if n.mtu, err = strconv.Atoi(val); err != nil {
115
+				return fmt.Errorf("failed to parse %v: %v", val, err)
116
+			}
117
+			if n.mtu < 0 {
118
+				return fmt.Errorf("invalid MTU value: %v", n.mtu)
119
+			}
120
+		}
121
+	}
122
+
123
+	// If we are getting vnis from libnetwork, either we get for
124
+	// all subnets or none.
125
+	if len(vnis) != 0 && len(vnis) < len(ipV4Data) {
126
+		return fmt.Errorf("insufficient vnis(%d) passed to overlay", len(vnis))
127
+	}
128
+
129
+	for i, ipd := range ipV4Data {
130
+		s := &subnet{
131
+			subnetIP: ipd.Pool,
132
+			gwIP:     ipd.Gateway,
133
+			once:     &sync.Once{},
134
+		}
135
+
136
+		if len(vnis) != 0 {
137
+			s.vni = vnis[i]
138
+		}
139
+
140
+		n.subnets = append(n.subnets, s)
141
+	}
142
+
143
+	if err := n.writeToStore(); err != nil {
144
+		return fmt.Errorf("failed to update data store for network %v: %v", n.id, err)
145
+	}
146
+
147
+	// Make sure no rule is on the way from any stale secure network
148
+	if !n.secure {
149
+		for _, vni := range vnis {
150
+			programMangle(vni, false)
151
+		}
152
+	}
153
+
154
+	if nInfo != nil {
155
+		if err := nInfo.TableEventRegister(ovPeerTable); err != nil {
156
+			return err
157
+		}
158
+	}
159
+
160
+	d.addNetwork(n)
161
+	return nil
162
+}
163
+
164
+func (d *driver) DeleteNetwork(nid string) error {
165
+	if nid == "" {
166
+		return fmt.Errorf("invalid network id")
167
+	}
168
+
169
+	// Make sure driver resources are initialized before proceeding
170
+	if err := d.configure(); err != nil {
171
+		return err
172
+	}
173
+
174
+	n := d.network(nid)
175
+	if n == nil {
176
+		return fmt.Errorf("could not find network with id %s", nid)
177
+	}
178
+
179
+	d.deleteNetwork(nid)
180
+
181
+	vnis, err := n.releaseVxlanID()
182
+	if err != nil {
183
+		return err
184
+	}
185
+
186
+	if n.secure {
187
+		for _, vni := range vnis {
188
+			programMangle(vni, false)
189
+		}
190
+	}
191
+
192
+	return nil
193
+}
194
+
195
+func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error {
196
+	return nil
197
+}
198
+
199
+func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
200
+	return nil
201
+}
202
+
203
+func (n *network) incEndpointCount() {
204
+	n.Lock()
205
+	defer n.Unlock()
206
+	n.joinCnt++
207
+}
208
+
209
+func (n *network) joinSandbox(restore bool) error {
210
+	// If there is a race between two go routines here only one will win
211
+	// the other will wait.
212
+	n.once.Do(func() {
213
+		// save the error status of initSandbox in n.initErr so that
214
+		// all the racing go routines are able to know the status.
215
+		n.initErr = n.initSandbox(restore)
216
+	})
217
+
218
+	return n.initErr
219
+}
220
+
221
+func (n *network) joinSubnetSandbox(s *subnet, restore bool) error {
222
+	s.once.Do(func() {
223
+		s.initErr = n.initSubnetSandbox(s, restore)
224
+	})
225
+	return s.initErr
226
+}
227
+
228
+func (n *network) leaveSandbox() {
229
+	n.Lock()
230
+	defer n.Unlock()
231
+	n.joinCnt--
232
+	if n.joinCnt != 0 {
233
+		return
234
+	}
235
+
236
+	// We are about to destroy sandbox since the container is leaving the network
237
+	// Reinitialize the once variable so that we will be able to trigger one time
238
+	// sandbox initialization(again) when another container joins subsequently.
239
+	n.once = &sync.Once{}
240
+	for _, s := range n.subnets {
241
+		s.once = &sync.Once{}
242
+	}
243
+
244
+	n.destroySandbox()
245
+}
246
+
247
+// to be called while holding network lock
248
+func (n *network) destroySandbox() {
249
+	if n.sbox != nil {
250
+		for _, iface := range n.sbox.Info().Interfaces() {
251
+			if err := iface.Remove(); err != nil {
252
+				logrus.Debugf("Remove interface %s failed: %v", iface.SrcName(), err)
253
+			}
254
+		}
255
+
256
+		for _, s := range n.subnets {
257
+			if s.vxlanName != "" {
258
+				err := deleteInterface(s.vxlanName)
259
+				if err != nil {
260
+					logrus.Warnf("could not cleanup sandbox properly: %v", err)
261
+				}
262
+			}
263
+		}
264
+
265
+		n.sbox.Destroy()
266
+		n.sbox = nil
267
+	}
268
+}
269
+
270
+func networkOnceInit() {
271
+	if os.Getenv("_OVERLAY_HOST_MODE") != "" {
272
+		hostMode = true
273
+		return
274
+	}
275
+
276
+	err := createVxlan("testvxlan1", 1, 0)
277
+	if err != nil {
278
+		logrus.Errorf("Failed to create testvxlan1 interface: %v", err)
279
+		return
280
+	}
281
+
282
+	defer deleteInterface("testvxlan1")
283
+}
284
+
285
+func (n *network) generateVxlanName(s *subnet) string {
286
+	id := n.id
287
+	if len(n.id) > 12 {
288
+		id = n.id[:12]
289
+	}
290
+
291
+	return "vx_" + id + "_0"
292
+}
293
+
294
+func (n *network) generateBridgeName(s *subnet) string {
295
+	id := n.id
296
+	if len(n.id) > 5 {
297
+		id = n.id[:5]
298
+	}
299
+
300
+	return n.getBridgeNamePrefix(s) + "_" + id + "_0"
301
+}
302
+
303
+func (n *network) getBridgeNamePrefix(s *subnet) string {
304
+	return "ov_" + fmt.Sprintf("%06x", n.vxlanID(s))
305
+}
306
+
307
+func isOverlap(nw *net.IPNet) bool {
308
+	var nameservers []string
309
+
310
+	if rc, err := resolvconf.Get(); err == nil {
311
+		nameservers = resolvconf.GetNameserversAsCIDR(rc.Content)
312
+	}
313
+
314
+	if err := netutils.CheckNameserverOverlaps(nameservers, nw); err != nil {
315
+		return true
316
+	}
317
+
318
+	if err := netutils.CheckRouteOverlaps(nw); err != nil {
319
+		return true
320
+	}
321
+
322
+	return false
323
+}
324
+
325
+func (n *network) restoreSubnetSandbox(s *subnet, brName, vxlanName string) error {
326
+	sbox := n.sandbox()
327
+
328
+	// restore overlay osl sandbox
329
+	Ifaces := make(map[string][]osl.IfaceOption)
330
+	brIfaceOption := make([]osl.IfaceOption, 2)
331
+	brIfaceOption = append(brIfaceOption, sbox.InterfaceOptions().Address(s.gwIP))
332
+	brIfaceOption = append(brIfaceOption, sbox.InterfaceOptions().Bridge(true))
333
+	Ifaces[fmt.Sprintf("%s+%s", brName, "br")] = brIfaceOption
334
+
335
+	err := sbox.Restore(Ifaces, nil, nil, nil)
336
+	if err != nil {
337
+		return err
338
+	}
339
+
340
+	Ifaces = make(map[string][]osl.IfaceOption)
341
+	vxlanIfaceOption := make([]osl.IfaceOption, 1)
342
+	vxlanIfaceOption = append(vxlanIfaceOption, sbox.InterfaceOptions().Master(brName))
343
+	Ifaces[fmt.Sprintf("%s+%s", vxlanName, "vxlan")] = vxlanIfaceOption
344
+	err = sbox.Restore(Ifaces, nil, nil, nil)
345
+	if err != nil {
346
+		return err
347
+	}
348
+	return nil
349
+}
350
+
351
+func (n *network) addInterface(srcName, dstPrefix, name string, isBridge bool) error {
352
+	return nil
353
+}
354
+
355
+func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error {
356
+
357
+	if hostMode {
358
+		// Try to delete stale bridge interface if it exists
359
+		if err := deleteInterface(brName); err != nil {
360
+			deleteInterfaceBySubnet(n.getBridgeNamePrefix(s), s)
361
+		}
362
+
363
+		if isOverlap(s.subnetIP) {
364
+			return fmt.Errorf("overlay subnet %s has conflicts in the host while running in host mode", s.subnetIP.String())
365
+		}
366
+	}
367
+
368
+	if !hostMode {
369
+		// Try to find this subnet's vni is being used in some
370
+		// other namespace by looking at vniTbl that we just
371
+		// populated in the once init. If a hit is found then
372
+		// it must a stale namespace from previous
373
+		// life. Destroy it completely and reclaim resourced.
374
+		networkMu.Lock()
375
+		path, ok := vniTbl[n.vxlanID(s)]
376
+		networkMu.Unlock()
377
+
378
+		if ok {
379
+			os.Remove(path)
380
+
381
+			networkMu.Lock()
382
+			delete(vniTbl, n.vxlanID(s))
383
+			networkMu.Unlock()
384
+		}
385
+	}
386
+
387
+	err := createVxlan(vxlanName, n.vxlanID(s), n.maxMTU())
388
+	if err != nil {
389
+		return err
390
+	}
391
+
392
+	return nil
393
+}
394
+
395
+func (n *network) initSubnetSandbox(s *subnet, restore bool) error {
396
+	brName := n.generateBridgeName(s)
397
+	vxlanName := n.generateVxlanName(s)
398
+
399
+	if restore {
400
+		n.restoreSubnetSandbox(s, brName, vxlanName)
401
+	} else {
402
+		n.setupSubnetSandbox(s, brName, vxlanName)
403
+	}
404
+
405
+	n.Lock()
406
+	s.vxlanName = vxlanName
407
+	s.brName = brName
408
+	n.Unlock()
409
+
410
+	return nil
411
+}
412
+
413
+func (n *network) cleanupStaleSandboxes() {
414
+	filepath.Walk(filepath.Dir(osl.GenerateKey("walk")),
415
+		func(path string, info os.FileInfo, err error) error {
416
+			_, fname := filepath.Split(path)
417
+
418
+			pList := strings.Split(fname, "-")
419
+			if len(pList) <= 1 {
420
+				return nil
421
+			}
422
+
423
+			pattern := pList[1]
424
+			if strings.Contains(n.id, pattern) {
425
+				// Now that we have destroyed this
426
+				// sandbox, remove all references to
427
+				// it in vniTbl so that we don't
428
+				// inadvertently destroy the sandbox
429
+				// created in this life.
430
+				networkMu.Lock()
431
+				for vni, tblPath := range vniTbl {
432
+					if tblPath == path {
433
+						delete(vniTbl, vni)
434
+					}
435
+				}
436
+				networkMu.Unlock()
437
+			}
438
+
439
+			return nil
440
+		})
441
+}
442
+
443
+func (n *network) initSandbox(restore bool) error {
444
+	n.Lock()
445
+	n.initEpoch++
446
+	n.Unlock()
447
+
448
+	networkOnce.Do(networkOnceInit)
449
+
450
+	if !restore {
451
+		// If there are any stale sandboxes related to this network
452
+		// from previous daemon life clean it up here
453
+		n.cleanupStaleSandboxes()
454
+	}
455
+
456
+	// In the restore case network sandbox already exist; but we don't know
457
+	// what epoch number it was created with. It has to be retrieved by
458
+	// searching the net namespaces.
459
+	key := ""
460
+	if restore {
461
+		key = osl.GenerateKey("-" + n.id)
462
+	} else {
463
+		key = osl.GenerateKey(fmt.Sprintf("%d-", n.initEpoch) + n.id)
464
+	}
465
+
466
+	sbox, err := osl.NewSandbox(key, !hostMode, restore)
467
+	if err != nil {
468
+		return fmt.Errorf("could not get network sandbox (oper %t): %v", restore, err)
469
+	}
470
+
471
+	n.setSandbox(sbox)
472
+
473
+	if !restore {
474
+		n.driver.peerDbUpdateSandbox(n.id)
475
+	}
476
+
477
+	return nil
478
+}
479
+
480
+func (d *driver) addNetwork(n *network) {
481
+	d.Lock()
482
+	d.networks[n.id] = n
483
+	d.Unlock()
484
+}
485
+
486
+func (d *driver) deleteNetwork(nid string) {
487
+	d.Lock()
488
+	delete(d.networks, nid)
489
+	d.Unlock()
490
+}
491
+
492
+func (d *driver) network(nid string) *network {
493
+	d.Lock()
494
+	networks := d.networks
495
+	d.Unlock()
496
+
497
+	n, ok := networks[nid]
498
+	if !ok {
499
+		n = d.getNetworkFromStore(nid)
500
+		if n != nil {
501
+			n.driver = d
502
+			n.endpoints = endpointTable{}
503
+			n.once = &sync.Once{}
504
+			networks[nid] = n
505
+		}
506
+	}
507
+
508
+	return n
509
+}
510
+
511
+func (d *driver) getNetworkFromStore(nid string) *network {
512
+	if d.store == nil {
513
+		return nil
514
+	}
515
+
516
+	n := &network{id: nid}
517
+	if err := d.store.GetObject(datastore.Key(n.Key()...), n); err != nil {
518
+		return nil
519
+	}
520
+
521
+	return n
522
+}
523
+
524
+func (n *network) sandbox() osl.Sandbox {
525
+	n.Lock()
526
+	defer n.Unlock()
527
+
528
+	return n.sbox
529
+}
530
+
531
+func (n *network) setSandbox(sbox osl.Sandbox) {
532
+	n.Lock()
533
+	n.sbox = sbox
534
+	n.Unlock()
535
+}
536
+
537
+func (n *network) vxlanID(s *subnet) uint32 {
538
+	n.Lock()
539
+	defer n.Unlock()
540
+
541
+	return s.vni
542
+}
543
+
544
+func (n *network) setVxlanID(s *subnet, vni uint32) {
545
+	n.Lock()
546
+	s.vni = vni
547
+	n.Unlock()
548
+}
549
+
550
+func (n *network) Key() []string {
551
+	return []string{"overlay", "network", n.id}
552
+}
553
+
554
+func (n *network) KeyPrefix() []string {
555
+	return []string{"overlay", "network"}
556
+}
557
+
558
+func (n *network) Value() []byte {
559
+	m := map[string]interface{}{}
560
+
561
+	netJSON := []*subnetJSON{}
562
+
563
+	for _, s := range n.subnets {
564
+		sj := &subnetJSON{
565
+			SubnetIP: s.subnetIP.String(),
566
+			GwIP:     s.gwIP.String(),
567
+			Vni:      s.vni,
568
+		}
569
+		netJSON = append(netJSON, sj)
570
+	}
571
+
572
+	b, err := json.Marshal(netJSON)
573
+	if err != nil {
574
+		return []byte{}
575
+	}
576
+
577
+	m["secure"] = n.secure
578
+	m["subnets"] = netJSON
579
+	m["mtu"] = n.mtu
580
+	b, err = json.Marshal(m)
581
+	if err != nil {
582
+		return []byte{}
583
+	}
584
+
585
+	return b
586
+}
587
+
588
+func (n *network) Index() uint64 {
589
+	return n.dbIndex
590
+}
591
+
592
+func (n *network) SetIndex(index uint64) {
593
+	n.dbIndex = index
594
+	n.dbExists = true
595
+}
596
+
597
+func (n *network) Exists() bool {
598
+	return n.dbExists
599
+}
600
+
601
+func (n *network) Skip() bool {
602
+	return false
603
+}
604
+
605
+func (n *network) SetValue(value []byte) error {
606
+	var (
607
+		m       map[string]interface{}
608
+		newNet  bool
609
+		isMap   = true
610
+		netJSON = []*subnetJSON{}
611
+	)
612
+
613
+	if err := json.Unmarshal(value, &m); err != nil {
614
+		err := json.Unmarshal(value, &netJSON)
615
+		if err != nil {
616
+			return err
617
+		}
618
+		isMap = false
619
+	}
620
+
621
+	if len(n.subnets) == 0 {
622
+		newNet = true
623
+	}
624
+
625
+	if isMap {
626
+		if val, ok := m["secure"]; ok {
627
+			n.secure = val.(bool)
628
+		}
629
+		if val, ok := m["mtu"]; ok {
630
+			n.mtu = int(val.(float64))
631
+		}
632
+		bytes, err := json.Marshal(m["subnets"])
633
+		if err != nil {
634
+			return err
635
+		}
636
+		if err := json.Unmarshal(bytes, &netJSON); err != nil {
637
+			return err
638
+		}
639
+	}
640
+
641
+	for _, sj := range netJSON {
642
+		subnetIPstr := sj.SubnetIP
643
+		gwIPstr := sj.GwIP
644
+		vni := sj.Vni
645
+
646
+		subnetIP, _ := types.ParseCIDR(subnetIPstr)
647
+		gwIP, _ := types.ParseCIDR(gwIPstr)
648
+
649
+		if newNet {
650
+			s := &subnet{
651
+				subnetIP: subnetIP,
652
+				gwIP:     gwIP,
653
+				vni:      vni,
654
+				once:     &sync.Once{},
655
+			}
656
+			n.subnets = append(n.subnets, s)
657
+		} else {
658
+			sNet := n.getMatchingSubnet(subnetIP)
659
+			if sNet != nil {
660
+				sNet.vni = vni
661
+			}
662
+		}
663
+	}
664
+	return nil
665
+}
666
+
667
+func (n *network) DataScope() string {
668
+	return datastore.GlobalScope
669
+}
670
+
671
+func (n *network) writeToStore() error {
672
+	if n.driver.store == nil {
673
+		return nil
674
+	}
675
+
676
+	return n.driver.store.PutObjectAtomic(n)
677
+}
678
+
679
+func (n *network) releaseVxlanID() ([]uint32, error) {
680
+	if len(n.subnets) == 0 {
681
+		return nil, nil
682
+	}
683
+
684
+	if n.driver.store != nil {
685
+		if err := n.driver.store.DeleteObjectAtomic(n); err != nil {
686
+			if err == datastore.ErrKeyModified || err == datastore.ErrKeyNotFound {
687
+				// In both the above cases we can safely assume that the key has been removed by some other
688
+				// instance and so simply get out of here
689
+				return nil, nil
690
+			}
691
+
692
+			return nil, fmt.Errorf("failed to delete network to vxlan id map: %v", err)
693
+		}
694
+	}
695
+	var vnis []uint32
696
+	for _, s := range n.subnets {
697
+		if n.driver.vxlanIdm != nil {
698
+			vni := n.vxlanID(s)
699
+			vnis = append(vnis, vni)
700
+			n.driver.vxlanIdm.Release(uint64(vni))
701
+		}
702
+
703
+		n.setVxlanID(s, 0)
704
+	}
705
+
706
+	return vnis, nil
707
+}
708
+
709
+func (n *network) obtainVxlanID(s *subnet) error {
710
+	//return if the subnet already has a vxlan id assigned
711
+	if s.vni != 0 {
712
+		return nil
713
+	}
714
+
715
+	if n.driver.store == nil {
716
+		return fmt.Errorf("no valid vxlan id and no datastore configured, cannot obtain vxlan id")
717
+	}
718
+
719
+	for {
720
+		if err := n.driver.store.GetObject(datastore.Key(n.Key()...), n); err != nil {
721
+			return fmt.Errorf("getting network %q from datastore failed %v", n.id, err)
722
+		}
723
+
724
+		if s.vni == 0 {
725
+			vxlanID, err := n.driver.vxlanIdm.GetID()
726
+			if err != nil {
727
+				return fmt.Errorf("failed to allocate vxlan id: %v", err)
728
+			}
729
+
730
+			n.setVxlanID(s, uint32(vxlanID))
731
+			if err := n.writeToStore(); err != nil {
732
+				n.driver.vxlanIdm.Release(uint64(n.vxlanID(s)))
733
+				n.setVxlanID(s, 0)
734
+				if err == datastore.ErrKeyModified {
735
+					continue
736
+				}
737
+				return fmt.Errorf("network %q failed to update data store: %v", n.id, err)
738
+			}
739
+			return nil
740
+		}
741
+		return nil
742
+	}
743
+}
744
+
745
+// contains return true if the passed ip belongs to one the network's
746
+// subnets
747
+func (n *network) contains(ip net.IP) bool {
748
+	for _, s := range n.subnets {
749
+		if s.subnetIP.Contains(ip) {
750
+			return true
751
+		}
752
+	}
753
+
754
+	return false
755
+}
756
+
757
+// getSubnetforIP returns the subnet to which the given IP belongs
758
+func (n *network) getSubnetforIP(ip *net.IPNet) *subnet {
759
+	for _, s := range n.subnets {
760
+		// first check if the mask lengths are the same
761
+		i, _ := s.subnetIP.Mask.Size()
762
+		j, _ := ip.Mask.Size()
763
+		if i != j {
764
+			continue
765
+		}
766
+		if s.subnetIP.Contains(ip.IP) {
767
+			return s
768
+		}
769
+	}
770
+	return nil
771
+}
772
+
773
+// getMatchingSubnet return the network's subnet that matches the input
774
+func (n *network) getMatchingSubnet(ip *net.IPNet) *subnet {
775
+	if ip == nil {
776
+		return nil
777
+	}
778
+	for _, s := range n.subnets {
779
+		// first check if the mask lengths are the same
780
+		i, _ := s.subnetIP.Mask.Size()
781
+		j, _ := ip.Mask.Size()
782
+		if i != j {
783
+			continue
784
+		}
785
+		if s.subnetIP.IP.Equal(ip.IP) {
786
+			return s
787
+		}
788
+	}
789
+	return nil
790
+}
0 791
new file mode 100644
... ...
@@ -0,0 +1,233 @@
0
+package overlay
1
+
2
+import (
3
+	"fmt"
4
+	"net"
5
+	"strings"
6
+	"time"
7
+
8
+	"github.com/Sirupsen/logrus"
9
+	"github.com/hashicorp/serf/serf"
10
+)
11
+
12
+type ovNotify struct {
13
+	action string
14
+	ep     *endpoint
15
+	nw     *network
16
+}
17
+
18
+type logWriter struct{}
19
+
20
+func (l *logWriter) Write(p []byte) (int, error) {
21
+	str := string(p)
22
+
23
+	switch {
24
+	case strings.Contains(str, "[WARN]"):
25
+		logrus.Warn(str)
26
+	case strings.Contains(str, "[DEBUG]"):
27
+		logrus.Debug(str)
28
+	case strings.Contains(str, "[INFO]"):
29
+		logrus.Info(str)
30
+	case strings.Contains(str, "[ERR]"):
31
+		logrus.Error(str)
32
+	}
33
+
34
+	return len(p), nil
35
+}
36
+
37
+func (d *driver) serfInit() error {
38
+	var err error
39
+
40
+	config := serf.DefaultConfig()
41
+	config.Init()
42
+	config.MemberlistConfig.BindAddr = d.advertiseAddress
43
+
44
+	d.eventCh = make(chan serf.Event, 4)
45
+	config.EventCh = d.eventCh
46
+	config.UserCoalescePeriod = 1 * time.Second
47
+	config.UserQuiescentPeriod = 50 * time.Millisecond
48
+
49
+	config.LogOutput = &logWriter{}
50
+	config.MemberlistConfig.LogOutput = config.LogOutput
51
+
52
+	s, err := serf.Create(config)
53
+	if err != nil {
54
+		return fmt.Errorf("failed to create cluster node: %v", err)
55
+	}
56
+	defer func() {
57
+		if err != nil {
58
+			s.Shutdown()
59
+		}
60
+	}()
61
+
62
+	d.serfInstance = s
63
+
64
+	d.notifyCh = make(chan ovNotify)
65
+	d.exitCh = make(chan chan struct{})
66
+
67
+	go d.startSerfLoop(d.eventCh, d.notifyCh, d.exitCh)
68
+	return nil
69
+}
70
+
71
+func (d *driver) serfJoin(neighIP string) error {
72
+	if neighIP == "" {
73
+		return fmt.Errorf("no neighbor to join")
74
+	}
75
+	if _, err := d.serfInstance.Join([]string{neighIP}, false); err != nil {
76
+		return fmt.Errorf("Failed to join the cluster at neigh IP %s: %v",
77
+			neighIP, err)
78
+	}
79
+	return nil
80
+}
81
+
82
+func (d *driver) notifyEvent(event ovNotify) {
83
+	ep := event.ep
84
+
85
+	ePayload := fmt.Sprintf("%s %s %s %s", event.action, ep.addr.IP.String(),
86
+		net.IP(ep.addr.Mask).String(), ep.mac.String())
87
+	eName := fmt.Sprintf("jl %s %s %s", d.serfInstance.LocalMember().Addr.String(),
88
+		event.nw.id, ep.id)
89
+
90
+	if err := d.serfInstance.UserEvent(eName, []byte(ePayload), true); err != nil {
91
+		logrus.Errorf("Sending user event failed: %v\n", err)
92
+	}
93
+}
94
+
95
+func (d *driver) processEvent(u serf.UserEvent) {
96
+	logrus.Debugf("Received user event name:%s, payload:%s\n", u.Name,
97
+		string(u.Payload))
98
+
99
+	var dummy, action, vtepStr, nid, eid, ipStr, maskStr, macStr string
100
+	if _, err := fmt.Sscan(u.Name, &dummy, &vtepStr, &nid, &eid); err != nil {
101
+		fmt.Printf("Failed to scan name string: %v\n", err)
102
+	}
103
+
104
+	if _, err := fmt.Sscan(string(u.Payload), &action,
105
+		&ipStr, &maskStr, &macStr); err != nil {
106
+		fmt.Printf("Failed to scan value string: %v\n", err)
107
+	}
108
+
109
+	logrus.Debugf("Parsed data = %s/%s/%s/%s/%s/%s\n", nid, eid, vtepStr, ipStr, maskStr, macStr)
110
+
111
+	mac, err := net.ParseMAC(macStr)
112
+	if err != nil {
113
+		logrus.Errorf("Failed to parse mac: %v\n", err)
114
+	}
115
+
116
+	if d.serfInstance.LocalMember().Addr.String() == vtepStr {
117
+		return
118
+	}
119
+
120
+	switch action {
121
+	case "join":
122
+		if err := d.peerAdd(nid, eid, net.ParseIP(ipStr), net.IPMask(net.ParseIP(maskStr).To4()), mac,
123
+			net.ParseIP(vtepStr), true); err != nil {
124
+			logrus.Errorf("Peer add failed in the driver: %v\n", err)
125
+		}
126
+	case "leave":
127
+		if err := d.peerDelete(nid, eid, net.ParseIP(ipStr), net.IPMask(net.ParseIP(maskStr).To4()), mac,
128
+			net.ParseIP(vtepStr), true); err != nil {
129
+			logrus.Errorf("Peer delete failed in the driver: %v\n", err)
130
+		}
131
+	}
132
+}
133
+
134
+func (d *driver) processQuery(q *serf.Query) {
135
+	logrus.Debugf("Received query name:%s, payload:%s\n", q.Name,
136
+		string(q.Payload))
137
+
138
+	var nid, ipStr string
139
+	if _, err := fmt.Sscan(string(q.Payload), &nid, &ipStr); err != nil {
140
+		fmt.Printf("Failed to scan query payload string: %v\n", err)
141
+	}
142
+
143
+	peerMac, peerIPMask, vtep, err := d.peerDbSearch(nid, net.ParseIP(ipStr))
144
+	if err != nil {
145
+		return
146
+	}
147
+
148
+	q.Respond([]byte(fmt.Sprintf("%s %s %s", peerMac.String(), net.IP(peerIPMask).String(), vtep.String())))
149
+}
150
+
151
+func (d *driver) resolvePeer(nid string, peerIP net.IP) (net.HardwareAddr, net.IPMask, net.IP, error) {
152
+	if d.serfInstance == nil {
153
+		return nil, nil, nil, fmt.Errorf("could not resolve peer: serf instance not initialized")
154
+	}
155
+
156
+	qPayload := fmt.Sprintf("%s %s", string(nid), peerIP.String())
157
+	resp, err := d.serfInstance.Query("peerlookup", []byte(qPayload), nil)
158
+	if err != nil {
159
+		return nil, nil, nil, fmt.Errorf("resolving peer by querying the cluster failed: %v", err)
160
+	}
161
+
162
+	respCh := resp.ResponseCh()
163
+	select {
164
+	case r := <-respCh:
165
+		var macStr, maskStr, vtepStr string
166
+		if _, err := fmt.Sscan(string(r.Payload), &macStr, &maskStr, &vtepStr); err != nil {
167
+			return nil, nil, nil, fmt.Errorf("bad response %q for the resolve query: %v", string(r.Payload), err)
168
+		}
169
+
170
+		mac, err := net.ParseMAC(macStr)
171
+		if err != nil {
172
+			return nil, nil, nil, fmt.Errorf("failed to parse mac: %v", err)
173
+		}
174
+
175
+		return mac, net.IPMask(net.ParseIP(maskStr).To4()), net.ParseIP(vtepStr), nil
176
+
177
+	case <-time.After(time.Second):
178
+		return nil, nil, nil, fmt.Errorf("timed out resolving peer by querying the cluster")
179
+	}
180
+}
181
+
182
+func (d *driver) startSerfLoop(eventCh chan serf.Event, notifyCh chan ovNotify,
183
+	exitCh chan chan struct{}) {
184
+
185
+	for {
186
+		select {
187
+		case notify, ok := <-notifyCh:
188
+			if !ok {
189
+				break
190
+			}
191
+
192
+			d.notifyEvent(notify)
193
+		case ch, ok := <-exitCh:
194
+			if !ok {
195
+				break
196
+			}
197
+
198
+			if err := d.serfInstance.Leave(); err != nil {
199
+				logrus.Errorf("failed leaving the cluster: %v\n", err)
200
+			}
201
+
202
+			d.serfInstance.Shutdown()
203
+			close(ch)
204
+			return
205
+		case e, ok := <-eventCh:
206
+			if !ok {
207
+				break
208
+			}
209
+
210
+			if e.EventType() == serf.EventQuery {
211
+				d.processQuery(e.(*serf.Query))
212
+				break
213
+			}
214
+
215
+			u, ok := e.(serf.UserEvent)
216
+			if !ok {
217
+				break
218
+			}
219
+			d.processEvent(u)
220
+		}
221
+	}
222
+}
223
+
224
+func (d *driver) isSerfAlive() bool {
225
+	d.Lock()
226
+	serfInstance := d.serfInstance
227
+	d.Unlock()
228
+	if serfInstance == nil || serfInstance.State() != serf.SerfAlive {
229
+		return false
230
+	}
231
+	return true
232
+}
0 233
new file mode 100644
... ...
@@ -0,0 +1,61 @@
0
+package overlay
1
+
2
+import (
3
+	"fmt"
4
+	"os/exec"
5
+	"strings"
6
+
7
+	"github.com/docker/libnetwork/osl"
8
+)
9
+
10
+func validateID(nid, eid string) error {
11
+	if nid == "" {
12
+		return fmt.Errorf("invalid network id")
13
+	}
14
+
15
+	if eid == "" {
16
+		return fmt.Errorf("invalid endpoint id")
17
+	}
18
+
19
+	return nil
20
+}
21
+
22
+func createVxlan(name string, vni uint32, mtu int) error {
23
+	defer osl.InitOSContext()()
24
+
25
+	// Get default interface to plumb the vxlan on
26
+	routeCmd := "/usr/sbin/ipadm show-addr -p -o addrobj " +
27
+		"`/usr/sbin/route get default | /usr/bin/grep interface | " +
28
+		"/usr/bin/awk '{print $2}'`"
29
+	out, err := exec.Command("/usr/bin/bash", "-c", routeCmd).Output()
30
+	if err != nil {
31
+		return fmt.Errorf("cannot get default route: %v", err)
32
+	}
33
+
34
+	defaultInterface := strings.SplitN(string(out), "/", 2)
35
+	propList := fmt.Sprintf("interface=%s,vni=%d", defaultInterface[0], vni)
36
+
37
+	out, err = exec.Command("/usr/sbin/dladm", "create-vxlan", "-t", "-p", propList,
38
+		name).Output()
39
+	if err != nil {
40
+		return fmt.Errorf("error creating vxlan interface: %v %s", err, out)
41
+	}
42
+
43
+	return nil
44
+}
45
+
46
+func deleteInterfaceBySubnet(brPrefix string, s *subnet) error {
47
+	return nil
48
+
49
+}
50
+
51
+func deleteInterface(name string) error {
52
+	defer osl.InitOSContext()()
53
+
54
+	out, err := exec.Command("/usr/sbin/dladm", "delete-vxlan", name).Output()
55
+	if err != nil {
56
+		return fmt.Errorf("error creating vxlan interface: %v %s", err, out)
57
+	}
58
+
59
+	return nil
60
+}
0 61
new file mode 100644
... ...
@@ -0,0 +1,362 @@
0
+package overlay
1
+
2
+//go:generate protoc -I.:../../Godeps/_workspace/src/github.com/gogo/protobuf  --gogo_out=import_path=github.com/docker/libnetwork/drivers/overlay,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. overlay.proto
3
+
4
+import (
5
+	"fmt"
6
+	"net"
7
+	"sync"
8
+
9
+	"github.com/Sirupsen/logrus"
10
+	"github.com/docker/libnetwork/datastore"
11
+	"github.com/docker/libnetwork/discoverapi"
12
+	"github.com/docker/libnetwork/driverapi"
13
+	"github.com/docker/libnetwork/idm"
14
+	"github.com/docker/libnetwork/netlabel"
15
+	"github.com/docker/libnetwork/osl"
16
+	"github.com/docker/libnetwork/types"
17
+	"github.com/hashicorp/serf/serf"
18
+)
19
+
20
+// XXX OVERLAY_SOLARIS
21
+// Might need changes for names/constant values in solaris
22
+const (
23
+	networkType  = "overlay"
24
+	vethPrefix   = "veth"
25
+	vethLen      = 7
26
+	vxlanIDStart = 256
27
+	vxlanIDEnd   = (1 << 24) - 1
28
+	vxlanPort    = 4789
29
+	vxlanEncap   = 50
30
+	secureOption = "encrypted"
31
+)
32
+
33
+var initVxlanIdm = make(chan (bool), 1)
34
+
35
+type driver struct {
36
+	eventCh          chan serf.Event
37
+	notifyCh         chan ovNotify
38
+	exitCh           chan chan struct{}
39
+	bindAddress      string
40
+	advertiseAddress string
41
+	neighIP          string
42
+	config           map[string]interface{}
43
+	peerDb           peerNetworkMap
44
+	secMap           *encrMap
45
+	serfInstance     *serf.Serf
46
+	networks         networkTable
47
+	store            datastore.DataStore
48
+	localStore       datastore.DataStore
49
+	vxlanIdm         *idm.Idm
50
+	once             sync.Once
51
+	joinOnce         sync.Once
52
+	keys             []*key
53
+	sync.Mutex
54
+}
55
+
56
+// Init registers a new instance of overlay driver
57
+func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
58
+	c := driverapi.Capability{
59
+		DataScope: datastore.GlobalScope,
60
+	}
61
+	d := &driver{
62
+		networks: networkTable{},
63
+		peerDb: peerNetworkMap{
64
+			mp: map[string]*peerMap{},
65
+		},
66
+		secMap: &encrMap{nodes: map[string][]*spi{}},
67
+		config: config,
68
+	}
69
+
70
+	if data, ok := config[netlabel.GlobalKVClient]; ok {
71
+		var err error
72
+		dsc, ok := data.(discoverapi.DatastoreConfigData)
73
+		if !ok {
74
+			return types.InternalErrorf("incorrect data in datastore configuration: %v", data)
75
+		}
76
+		d.store, err = datastore.NewDataStoreFromConfig(dsc)
77
+		if err != nil {
78
+			return types.InternalErrorf("failed to initialize data store: %v", err)
79
+		}
80
+	}
81
+
82
+	if data, ok := config[netlabel.LocalKVClient]; ok {
83
+		var err error
84
+		dsc, ok := data.(discoverapi.DatastoreConfigData)
85
+		if !ok {
86
+			return types.InternalErrorf("incorrect data in datastore configuration: %v", data)
87
+		}
88
+		d.localStore, err = datastore.NewDataStoreFromConfig(dsc)
89
+		if err != nil {
90
+			return types.InternalErrorf("failed to initialize local data store: %v", err)
91
+		}
92
+	}
93
+
94
+	d.restoreEndpoints()
95
+
96
+	return dc.RegisterDriver(networkType, d, c)
97
+}
98
+
99
+// Endpoints are stored in the local store. Restore them and reconstruct the overlay sandbox
100
+func (d *driver) restoreEndpoints() error {
101
+	if d.localStore == nil {
102
+		logrus.Warnf("Cannot restore overlay endpoints because local datastore is missing")
103
+		return nil
104
+	}
105
+	kvol, err := d.localStore.List(datastore.Key(overlayEndpointPrefix), &endpoint{})
106
+	if err != nil && err != datastore.ErrKeyNotFound {
107
+		return fmt.Errorf("failed to read overlay endpoint from store: %v", err)
108
+	}
109
+
110
+	if err == datastore.ErrKeyNotFound {
111
+		return nil
112
+	}
113
+	for _, kvo := range kvol {
114
+		ep := kvo.(*endpoint)
115
+		n := d.network(ep.nid)
116
+		if n == nil {
117
+			logrus.Debugf("Network (%s) not found for restored endpoint (%s)", ep.nid[0:7], ep.id[0:7])
118
+			logrus.Debugf("Deleting stale overlay endpoint (%s) from store", ep.id[0:7])
119
+			if err := d.deleteEndpointFromStore(ep); err != nil {
120
+				logrus.Debugf("Failed to delete stale overlay endpoint (%s) from store", ep.id[0:7])
121
+			}
122
+			continue
123
+		}
124
+		n.addEndpoint(ep)
125
+
126
+		s := n.getSubnetforIP(ep.addr)
127
+		if s == nil {
128
+			return fmt.Errorf("could not find subnet for endpoint %s", ep.id)
129
+		}
130
+
131
+		if err := n.joinSandbox(true); err != nil {
132
+			return fmt.Errorf("restore network sandbox failed: %v", err)
133
+		}
134
+
135
+		if err := n.joinSubnetSandbox(s, true); err != nil {
136
+			return fmt.Errorf("restore subnet sandbox failed for %q: %v", s.subnetIP.String(), err)
137
+		}
138
+
139
+		Ifaces := make(map[string][]osl.IfaceOption)
140
+		vethIfaceOption := make([]osl.IfaceOption, 1)
141
+		vethIfaceOption = append(vethIfaceOption, n.sbox.InterfaceOptions().Master(s.brName))
142
+		Ifaces[fmt.Sprintf("%s+%s", "veth", "veth")] = vethIfaceOption
143
+
144
+		err := n.sbox.Restore(Ifaces, nil, nil, nil)
145
+		if err != nil {
146
+			return fmt.Errorf("failed to restore overlay sandbox: %v", err)
147
+		}
148
+
149
+		n.incEndpointCount()
150
+		d.peerDbAdd(ep.nid, ep.id, ep.addr.IP, ep.addr.Mask, ep.mac, net.ParseIP(d.advertiseAddress), true)
151
+	}
152
+	return nil
153
+}
154
+
155
+// Fini cleans up the driver resources
156
+func Fini(drv driverapi.Driver) {
157
+	d := drv.(*driver)
158
+
159
+	if d.exitCh != nil {
160
+		waitCh := make(chan struct{})
161
+
162
+		d.exitCh <- waitCh
163
+
164
+		<-waitCh
165
+	}
166
+}
167
+
168
+func (d *driver) configure() error {
169
+	if d.store == nil {
170
+		return nil
171
+	}
172
+
173
+	if d.vxlanIdm == nil {
174
+		return d.initializeVxlanIdm()
175
+	}
176
+
177
+	return nil
178
+}
179
+
180
+func (d *driver) initializeVxlanIdm() error {
181
+	var err error
182
+
183
+	initVxlanIdm <- true
184
+	defer func() { <-initVxlanIdm }()
185
+
186
+	if d.vxlanIdm != nil {
187
+		return nil
188
+	}
189
+
190
+	d.vxlanIdm, err = idm.New(d.store, "vxlan-id", vxlanIDStart, vxlanIDEnd)
191
+	if err != nil {
192
+		return fmt.Errorf("failed to initialize vxlan id manager: %v", err)
193
+	}
194
+
195
+	return nil
196
+}
197
+
198
+func (d *driver) Type() string {
199
+	return networkType
200
+}
201
+
202
+func validateSelf(node string) error {
203
+	advIP := net.ParseIP(node)
204
+	if advIP == nil {
205
+		return fmt.Errorf("invalid self address (%s)", node)
206
+	}
207
+
208
+	addrs, err := net.InterfaceAddrs()
209
+	if err != nil {
210
+		return fmt.Errorf("Unable to get interface addresses %v", err)
211
+	}
212
+	for _, addr := range addrs {
213
+		ip, _, err := net.ParseCIDR(addr.String())
214
+		if err == nil && ip.Equal(advIP) {
215
+			return nil
216
+		}
217
+	}
218
+	return fmt.Errorf("Multi-Host overlay networking requires cluster-advertise(%s) to be configured with a local ip-address that is reachable within the cluster", advIP.String())
219
+}
220
+
221
+func (d *driver) nodeJoin(advertiseAddress, bindAddress string, self bool) {
222
+	if self && !d.isSerfAlive() {
223
+		d.Lock()
224
+		d.advertiseAddress = advertiseAddress
225
+		d.bindAddress = bindAddress
226
+		d.Unlock()
227
+
228
+		// If there is no cluster store there is no need to start serf.
229
+		if d.store != nil {
230
+			if err := validateSelf(advertiseAddress); err != nil {
231
+				logrus.Warnf("%s", err.Error())
232
+			}
233
+			err := d.serfInit()
234
+			if err != nil {
235
+				logrus.Errorf("initializing serf instance failed: %v", err)
236
+				d.Lock()
237
+				d.advertiseAddress = ""
238
+				d.bindAddress = ""
239
+				d.Unlock()
240
+				return
241
+			}
242
+		}
243
+	}
244
+
245
+	d.Lock()
246
+	if !self {
247
+		d.neighIP = advertiseAddress
248
+	}
249
+	neighIP := d.neighIP
250
+	d.Unlock()
251
+
252
+	if d.serfInstance != nil && neighIP != "" {
253
+		var err error
254
+		d.joinOnce.Do(func() {
255
+			err = d.serfJoin(neighIP)
256
+			if err == nil {
257
+				d.pushLocalDb()
258
+			}
259
+		})
260
+		if err != nil {
261
+			logrus.Errorf("joining serf neighbor %s failed: %v", advertiseAddress, err)
262
+			d.Lock()
263
+			d.joinOnce = sync.Once{}
264
+			d.Unlock()
265
+			return
266
+		}
267
+	}
268
+}
269
+
270
+func (d *driver) pushLocalEndpointEvent(action, nid, eid string) {
271
+	n := d.network(nid)
272
+	if n == nil {
273
+		logrus.Debugf("Error pushing local endpoint event for network %s", nid)
274
+		return
275
+	}
276
+	ep := n.endpoint(eid)
277
+	if ep == nil {
278
+		logrus.Debugf("Error pushing local endpoint event for ep %s / %s", nid, eid)
279
+		return
280
+	}
281
+
282
+	if !d.isSerfAlive() {
283
+		return
284
+	}
285
+	d.notifyCh <- ovNotify{
286
+		action: "join",
287
+		nw:     n,
288
+		ep:     ep,
289
+	}
290
+}
291
+
292
+// DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster
293
+func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
294
+	var err error
295
+	switch dType {
296
+	case discoverapi.NodeDiscovery:
297
+		nodeData, ok := data.(discoverapi.NodeDiscoveryData)
298
+		if !ok || nodeData.Address == "" {
299
+			return fmt.Errorf("invalid discovery data")
300
+		}
301
+		d.nodeJoin(nodeData.Address, nodeData.BindAddress, nodeData.Self)
302
+	case discoverapi.DatastoreConfig:
303
+		if d.store != nil {
304
+			return types.ForbiddenErrorf("cannot accept datastore configuration: Overlay driver has a datastore configured already")
305
+		}
306
+		dsc, ok := data.(discoverapi.DatastoreConfigData)
307
+		if !ok {
308
+			return types.InternalErrorf("incorrect data in datastore configuration: %v", data)
309
+		}
310
+		d.store, err = datastore.NewDataStoreFromConfig(dsc)
311
+		if err != nil {
312
+			return types.InternalErrorf("failed to initialize data store: %v", err)
313
+		}
314
+	case discoverapi.EncryptionKeysConfig:
315
+		encrData, ok := data.(discoverapi.DriverEncryptionConfig)
316
+		if !ok {
317
+			return fmt.Errorf("invalid encryption key notification data")
318
+		}
319
+		keys := make([]*key, 0, len(encrData.Keys))
320
+		for i := 0; i < len(encrData.Keys); i++ {
321
+			k := &key{
322
+				value: encrData.Keys[i],
323
+				tag:   uint32(encrData.Tags[i]),
324
+			}
325
+			keys = append(keys, k)
326
+		}
327
+		d.setKeys(keys)
328
+	case discoverapi.EncryptionKeysUpdate:
329
+		var newKey, delKey, priKey *key
330
+		encrData, ok := data.(discoverapi.DriverEncryptionUpdate)
331
+		if !ok {
332
+			return fmt.Errorf("invalid encryption key notification data")
333
+		}
334
+		if encrData.Key != nil {
335
+			newKey = &key{
336
+				value: encrData.Key,
337
+				tag:   uint32(encrData.Tag),
338
+			}
339
+		}
340
+		if encrData.Primary != nil {
341
+			priKey = &key{
342
+				value: encrData.Primary,
343
+				tag:   uint32(encrData.PrimaryTag),
344
+			}
345
+		}
346
+		if encrData.Prune != nil {
347
+			delKey = &key{
348
+				value: encrData.Prune,
349
+				tag:   uint32(encrData.PruneTag),
350
+			}
351
+		}
352
+		d.updateKeys(newKey, priKey, delKey)
353
+	default:
354
+	}
355
+	return nil
356
+}
357
+
358
+// DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster
359
+func (d *driver) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error {
360
+	return nil
361
+}
0 362
new file mode 100644
... ...
@@ -0,0 +1,468 @@
0
+// Code generated by protoc-gen-gogo.
1
+// source: overlay.proto
2
+// DO NOT EDIT!
3
+
4
+/*
5
+	Package overlay is a generated protocol buffer package.
6
+
7
+	It is generated from these files:
8
+		overlay.proto
9
+
10
+	It has these top-level messages:
11
+		PeerRecord
12
+*/
13
+package overlay
14
+
15
+import proto "github.com/gogo/protobuf/proto"
16
+import fmt "fmt"
17
+import math "math"
18
+import _ "github.com/gogo/protobuf/gogoproto"
19
+
20
+import strings "strings"
21
+import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
22
+import sort "sort"
23
+import strconv "strconv"
24
+import reflect "reflect"
25
+
26
+import io "io"
27
+
28
+// Reference imports to suppress errors if they are not otherwise used.
29
+var _ = proto.Marshal
30
+var _ = fmt.Errorf
31
+var _ = math.Inf
32
+
33
+// This is a compile-time assertion to ensure that this generated file
34
+// is compatible with the proto package it is being compiled against.
35
+const _ = proto.GoGoProtoPackageIsVersion1
36
+
37
+// PeerRecord defines the information corresponding to a peer
38
+// container in the overlay network.
39
+type PeerRecord struct {
40
+	// Endpoint IP is the IP of the container attachment on the
41
+	// given overlay network.
42
+	EndpointIP string `protobuf:"bytes,1,opt,name=endpoint_ip,json=endpointIp,proto3" json:"endpoint_ip,omitempty"`
43
+	// Endpoint MAC is the mac address of the container attachment
44
+	// on the given overlay network.
45
+	EndpointMAC string `protobuf:"bytes,2,opt,name=endpoint_mac,json=endpointMac,proto3" json:"endpoint_mac,omitempty"`
46
+	// Tunnel Endpoint IP defines the host IP for the host in
47
+	// which this container is running and can be reached by
48
+	// building a tunnel to that host IP.
49
+	TunnelEndpointIP string `protobuf:"bytes,3,opt,name=tunnel_endpoint_ip,json=tunnelEndpointIp,proto3" json:"tunnel_endpoint_ip,omitempty"`
50
+}
51
+
52
+func (m *PeerRecord) Reset()                    { *m = PeerRecord{} }
53
+func (*PeerRecord) ProtoMessage()               {}
54
+func (*PeerRecord) Descriptor() ([]byte, []int) { return fileDescriptorOverlay, []int{0} }
55
+
56
+func init() {
57
+	proto.RegisterType((*PeerRecord)(nil), "overlay.PeerRecord")
58
+}
59
+func (this *PeerRecord) GoString() string {
60
+	if this == nil {
61
+		return "nil"
62
+	}
63
+	s := make([]string, 0, 7)
64
+	s = append(s, "&overlay.PeerRecord{")
65
+	s = append(s, "EndpointIP: "+fmt.Sprintf("%#v", this.EndpointIP)+",\n")
66
+	s = append(s, "EndpointMAC: "+fmt.Sprintf("%#v", this.EndpointMAC)+",\n")
67
+	s = append(s, "TunnelEndpointIP: "+fmt.Sprintf("%#v", this.TunnelEndpointIP)+",\n")
68
+	s = append(s, "}")
69
+	return strings.Join(s, "")
70
+}
71
+func valueToGoStringOverlay(v interface{}, typ string) string {
72
+	rv := reflect.ValueOf(v)
73
+	if rv.IsNil() {
74
+		return "nil"
75
+	}
76
+	pv := reflect.Indirect(rv).Interface()
77
+	return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
78
+}
79
+func extensionToGoStringOverlay(e map[int32]github_com_gogo_protobuf_proto.Extension) string {
80
+	if e == nil {
81
+		return "nil"
82
+	}
83
+	s := "map[int32]proto.Extension{"
84
+	keys := make([]int, 0, len(e))
85
+	for k := range e {
86
+		keys = append(keys, int(k))
87
+	}
88
+	sort.Ints(keys)
89
+	ss := []string{}
90
+	for _, k := range keys {
91
+		ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString())
92
+	}
93
+	s += strings.Join(ss, ",") + "}"
94
+	return s
95
+}
96
+func (m *PeerRecord) Marshal() (data []byte, err error) {
97
+	size := m.Size()
98
+	data = make([]byte, size)
99
+	n, err := m.MarshalTo(data)
100
+	if err != nil {
101
+		return nil, err
102
+	}
103
+	return data[:n], nil
104
+}
105
+
106
+func (m *PeerRecord) MarshalTo(data []byte) (int, error) {
107
+	var i int
108
+	_ = i
109
+	var l int
110
+	_ = l
111
+	if len(m.EndpointIP) > 0 {
112
+		data[i] = 0xa
113
+		i++
114
+		i = encodeVarintOverlay(data, i, uint64(len(m.EndpointIP)))
115
+		i += copy(data[i:], m.EndpointIP)
116
+	}
117
+	if len(m.EndpointMAC) > 0 {
118
+		data[i] = 0x12
119
+		i++
120
+		i = encodeVarintOverlay(data, i, uint64(len(m.EndpointMAC)))
121
+		i += copy(data[i:], m.EndpointMAC)
122
+	}
123
+	if len(m.TunnelEndpointIP) > 0 {
124
+		data[i] = 0x1a
125
+		i++
126
+		i = encodeVarintOverlay(data, i, uint64(len(m.TunnelEndpointIP)))
127
+		i += copy(data[i:], m.TunnelEndpointIP)
128
+	}
129
+	return i, nil
130
+}
131
+
132
+func encodeFixed64Overlay(data []byte, offset int, v uint64) int {
133
+	data[offset] = uint8(v)
134
+	data[offset+1] = uint8(v >> 8)
135
+	data[offset+2] = uint8(v >> 16)
136
+	data[offset+3] = uint8(v >> 24)
137
+	data[offset+4] = uint8(v >> 32)
138
+	data[offset+5] = uint8(v >> 40)
139
+	data[offset+6] = uint8(v >> 48)
140
+	data[offset+7] = uint8(v >> 56)
141
+	return offset + 8
142
+}
143
+func encodeFixed32Overlay(data []byte, offset int, v uint32) int {
144
+	data[offset] = uint8(v)
145
+	data[offset+1] = uint8(v >> 8)
146
+	data[offset+2] = uint8(v >> 16)
147
+	data[offset+3] = uint8(v >> 24)
148
+	return offset + 4
149
+}
150
+func encodeVarintOverlay(data []byte, offset int, v uint64) int {
151
+	for v >= 1<<7 {
152
+		data[offset] = uint8(v&0x7f | 0x80)
153
+		v >>= 7
154
+		offset++
155
+	}
156
+	data[offset] = uint8(v)
157
+	return offset + 1
158
+}
159
+func (m *PeerRecord) Size() (n int) {
160
+	var l int
161
+	_ = l
162
+	l = len(m.EndpointIP)
163
+	if l > 0 {
164
+		n += 1 + l + sovOverlay(uint64(l))
165
+	}
166
+	l = len(m.EndpointMAC)
167
+	if l > 0 {
168
+		n += 1 + l + sovOverlay(uint64(l))
169
+	}
170
+	l = len(m.TunnelEndpointIP)
171
+	if l > 0 {
172
+		n += 1 + l + sovOverlay(uint64(l))
173
+	}
174
+	return n
175
+}
176
+
177
+func sovOverlay(x uint64) (n int) {
178
+	for {
179
+		n++
180
+		x >>= 7
181
+		if x == 0 {
182
+			break
183
+		}
184
+	}
185
+	return n
186
+}
187
+func sozOverlay(x uint64) (n int) {
188
+	return sovOverlay(uint64((x << 1) ^ uint64((int64(x) >> 63))))
189
+}
190
+func (this *PeerRecord) String() string {
191
+	if this == nil {
192
+		return "nil"
193
+	}
194
+	s := strings.Join([]string{`&PeerRecord{`,
195
+		`EndpointIP:` + fmt.Sprintf("%v", this.EndpointIP) + `,`,
196
+		`EndpointMAC:` + fmt.Sprintf("%v", this.EndpointMAC) + `,`,
197
+		`TunnelEndpointIP:` + fmt.Sprintf("%v", this.TunnelEndpointIP) + `,`,
198
+		`}`,
199
+	}, "")
200
+	return s
201
+}
202
+func valueToStringOverlay(v interface{}) string {
203
+	rv := reflect.ValueOf(v)
204
+	if rv.IsNil() {
205
+		return "nil"
206
+	}
207
+	pv := reflect.Indirect(rv).Interface()
208
+	return fmt.Sprintf("*%v", pv)
209
+}
210
+func (m *PeerRecord) Unmarshal(data []byte) error {
211
+	l := len(data)
212
+	iNdEx := 0
213
+	for iNdEx < l {
214
+		preIndex := iNdEx
215
+		var wire uint64
216
+		for shift := uint(0); ; shift += 7 {
217
+			if shift >= 64 {
218
+				return ErrIntOverflowOverlay
219
+			}
220
+			if iNdEx >= l {
221
+				return io.ErrUnexpectedEOF
222
+			}
223
+			b := data[iNdEx]
224
+			iNdEx++
225
+			wire |= (uint64(b) & 0x7F) << shift
226
+			if b < 0x80 {
227
+				break
228
+			}
229
+		}
230
+		fieldNum := int32(wire >> 3)
231
+		wireType := int(wire & 0x7)
232
+		if wireType == 4 {
233
+			return fmt.Errorf("proto: PeerRecord: wiretype end group for non-group")
234
+		}
235
+		if fieldNum <= 0 {
236
+			return fmt.Errorf("proto: PeerRecord: illegal tag %d (wire type %d)", fieldNum, wire)
237
+		}
238
+		switch fieldNum {
239
+		case 1:
240
+			if wireType != 2 {
241
+				return fmt.Errorf("proto: wrong wireType = %d for field EndpointIP", wireType)
242
+			}
243
+			var stringLen uint64
244
+			for shift := uint(0); ; shift += 7 {
245
+				if shift >= 64 {
246
+					return ErrIntOverflowOverlay
247
+				}
248
+				if iNdEx >= l {
249
+					return io.ErrUnexpectedEOF
250
+				}
251
+				b := data[iNdEx]
252
+				iNdEx++
253
+				stringLen |= (uint64(b) & 0x7F) << shift
254
+				if b < 0x80 {
255
+					break
256
+				}
257
+			}
258
+			intStringLen := int(stringLen)
259
+			if intStringLen < 0 {
260
+				return ErrInvalidLengthOverlay
261
+			}
262
+			postIndex := iNdEx + intStringLen
263
+			if postIndex > l {
264
+				return io.ErrUnexpectedEOF
265
+			}
266
+			m.EndpointIP = string(data[iNdEx:postIndex])
267
+			iNdEx = postIndex
268
+		case 2:
269
+			if wireType != 2 {
270
+				return fmt.Errorf("proto: wrong wireType = %d for field EndpointMAC", wireType)
271
+			}
272
+			var stringLen uint64
273
+			for shift := uint(0); ; shift += 7 {
274
+				if shift >= 64 {
275
+					return ErrIntOverflowOverlay
276
+				}
277
+				if iNdEx >= l {
278
+					return io.ErrUnexpectedEOF
279
+				}
280
+				b := data[iNdEx]
281
+				iNdEx++
282
+				stringLen |= (uint64(b) & 0x7F) << shift
283
+				if b < 0x80 {
284
+					break
285
+				}
286
+			}
287
+			intStringLen := int(stringLen)
288
+			if intStringLen < 0 {
289
+				return ErrInvalidLengthOverlay
290
+			}
291
+			postIndex := iNdEx + intStringLen
292
+			if postIndex > l {
293
+				return io.ErrUnexpectedEOF
294
+			}
295
+			m.EndpointMAC = string(data[iNdEx:postIndex])
296
+			iNdEx = postIndex
297
+		case 3:
298
+			if wireType != 2 {
299
+				return fmt.Errorf("proto: wrong wireType = %d for field TunnelEndpointIP", wireType)
300
+			}
301
+			var stringLen uint64
302
+			for shift := uint(0); ; shift += 7 {
303
+				if shift >= 64 {
304
+					return ErrIntOverflowOverlay
305
+				}
306
+				if iNdEx >= l {
307
+					return io.ErrUnexpectedEOF
308
+				}
309
+				b := data[iNdEx]
310
+				iNdEx++
311
+				stringLen |= (uint64(b) & 0x7F) << shift
312
+				if b < 0x80 {
313
+					break
314
+				}
315
+			}
316
+			intStringLen := int(stringLen)
317
+			if intStringLen < 0 {
318
+				return ErrInvalidLengthOverlay
319
+			}
320
+			postIndex := iNdEx + intStringLen
321
+			if postIndex > l {
322
+				return io.ErrUnexpectedEOF
323
+			}
324
+			m.TunnelEndpointIP = string(data[iNdEx:postIndex])
325
+			iNdEx = postIndex
326
+		default:
327
+			iNdEx = preIndex
328
+			skippy, err := skipOverlay(data[iNdEx:])
329
+			if err != nil {
330
+				return err
331
+			}
332
+			if skippy < 0 {
333
+				return ErrInvalidLengthOverlay
334
+			}
335
+			if (iNdEx + skippy) > l {
336
+				return io.ErrUnexpectedEOF
337
+			}
338
+			iNdEx += skippy
339
+		}
340
+	}
341
+
342
+	if iNdEx > l {
343
+		return io.ErrUnexpectedEOF
344
+	}
345
+	return nil
346
+}
347
+func skipOverlay(data []byte) (n int, err error) {
348
+	l := len(data)
349
+	iNdEx := 0
350
+	for iNdEx < l {
351
+		var wire uint64
352
+		for shift := uint(0); ; shift += 7 {
353
+			if shift >= 64 {
354
+				return 0, ErrIntOverflowOverlay
355
+			}
356
+			if iNdEx >= l {
357
+				return 0, io.ErrUnexpectedEOF
358
+			}
359
+			b := data[iNdEx]
360
+			iNdEx++
361
+			wire |= (uint64(b) & 0x7F) << shift
362
+			if b < 0x80 {
363
+				break
364
+			}
365
+		}
366
+		wireType := int(wire & 0x7)
367
+		switch wireType {
368
+		case 0:
369
+			for shift := uint(0); ; shift += 7 {
370
+				if shift >= 64 {
371
+					return 0, ErrIntOverflowOverlay
372
+				}
373
+				if iNdEx >= l {
374
+					return 0, io.ErrUnexpectedEOF
375
+				}
376
+				iNdEx++
377
+				if data[iNdEx-1] < 0x80 {
378
+					break
379
+				}
380
+			}
381
+			return iNdEx, nil
382
+		case 1:
383
+			iNdEx += 8
384
+			return iNdEx, nil
385
+		case 2:
386
+			var length int
387
+			for shift := uint(0); ; shift += 7 {
388
+				if shift >= 64 {
389
+					return 0, ErrIntOverflowOverlay
390
+				}
391
+				if iNdEx >= l {
392
+					return 0, io.ErrUnexpectedEOF
393
+				}
394
+				b := data[iNdEx]
395
+				iNdEx++
396
+				length |= (int(b) & 0x7F) << shift
397
+				if b < 0x80 {
398
+					break
399
+				}
400
+			}
401
+			iNdEx += length
402
+			if length < 0 {
403
+				return 0, ErrInvalidLengthOverlay
404
+			}
405
+			return iNdEx, nil
406
+		case 3:
407
+			for {
408
+				var innerWire uint64
409
+				var start int = iNdEx
410
+				for shift := uint(0); ; shift += 7 {
411
+					if shift >= 64 {
412
+						return 0, ErrIntOverflowOverlay
413
+					}
414
+					if iNdEx >= l {
415
+						return 0, io.ErrUnexpectedEOF
416
+					}
417
+					b := data[iNdEx]
418
+					iNdEx++
419
+					innerWire |= (uint64(b) & 0x7F) << shift
420
+					if b < 0x80 {
421
+						break
422
+					}
423
+				}
424
+				innerWireType := int(innerWire & 0x7)
425
+				if innerWireType == 4 {
426
+					break
427
+				}
428
+				next, err := skipOverlay(data[start:])
429
+				if err != nil {
430
+					return 0, err
431
+				}
432
+				iNdEx = start + next
433
+			}
434
+			return iNdEx, nil
435
+		case 4:
436
+			return iNdEx, nil
437
+		case 5:
438
+			iNdEx += 4
439
+			return iNdEx, nil
440
+		default:
441
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
442
+		}
443
+	}
444
+	panic("unreachable")
445
+}
446
+
447
+var (
448
+	ErrInvalidLengthOverlay = fmt.Errorf("proto: negative length found during unmarshaling")
449
+	ErrIntOverflowOverlay   = fmt.Errorf("proto: integer overflow")
450
+)
451
+
452
+var fileDescriptorOverlay = []byte{
453
+	// 195 bytes of a gzipped FileDescriptorProto
454
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0xcd, 0x2f, 0x4b, 0x2d,
455
+	0xca, 0x49, 0xac, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x87, 0x72, 0xa5, 0x44, 0xd2,
456
+	0xf3, 0xd3, 0xf3, 0xc1, 0x62, 0xfa, 0x20, 0x16, 0x44, 0x5a, 0x69, 0x2b, 0x23, 0x17, 0x57, 0x40,
457
+	0x6a, 0x6a, 0x51, 0x50, 0x6a, 0x72, 0x7e, 0x51, 0x8a, 0x90, 0x3e, 0x17, 0x77, 0x6a, 0x5e, 0x4a,
458
+	0x41, 0x7e, 0x66, 0x5e, 0x49, 0x7c, 0x66, 0x81, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xa7, 0x13, 0xdf,
459
+	0xa3, 0x7b, 0xf2, 0x5c, 0xae, 0x50, 0x61, 0xcf, 0x80, 0x20, 0x2e, 0x98, 0x12, 0xcf, 0x02, 0x21,
460
+	0x23, 0x2e, 0x1e, 0xb8, 0x86, 0xdc, 0xc4, 0x64, 0x09, 0x26, 0xb0, 0x0e, 0x7e, 0xa0, 0x0e, 0x6e,
461
+	0x98, 0x0e, 0x5f, 0x47, 0xe7, 0x20, 0xb8, 0xa9, 0xbe, 0x89, 0xc9, 0x42, 0x4e, 0x5c, 0x42, 0x25,
462
+	0xa5, 0x79, 0x79, 0xa9, 0x39, 0xf1, 0xc8, 0x76, 0x31, 0x83, 0x75, 0x8a, 0x00, 0x75, 0x0a, 0x84,
463
+	0x80, 0x65, 0x91, 0x6c, 0x14, 0x28, 0x41, 0x15, 0x29, 0x70, 0x92, 0xb8, 0xf1, 0x50, 0x8e, 0xe1,
464
+	0xc3, 0x43, 0x39, 0xc6, 0x86, 0x47, 0x72, 0x8c, 0x27, 0x80, 0xf8, 0x02, 0x10, 0x3f, 0x00, 0xe2,
465
+	0x24, 0x36, 0xb0, 0xc7, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbf, 0xd7, 0x7d, 0x7d, 0x08,
466
+	0x01, 0x00, 0x00,
467
+}
0 468
new file mode 100644
... ...
@@ -0,0 +1,27 @@
0
+syntax = "proto3";
1
+
2
+import "gogoproto/gogo.proto";
3
+
4
+package overlay;
5
+
6
+option (gogoproto.marshaler_all) = true;
7
+option (gogoproto.unmarshaler_all) = true;
8
+option (gogoproto.stringer_all) = true;
9
+option (gogoproto.gostring_all) = true;
10
+option (gogoproto.sizer_all) = true;
11
+option (gogoproto.goproto_stringer_all) = false;
12
+
13
+// PeerRecord defines the information corresponding to a peer
14
+// container in the overlay network.
15
+message PeerRecord {
16
+	// Endpoint IP is the IP of the container attachment on the
17
+	// given overlay network.
18
+	string endpoint_ip = 1 [(gogoproto.customname) = "EndpointIP"];
19
+	// Endpoint MAC is the mac address of the container attachment
20
+	// on the given overlay network.
21
+	string endpoint_mac = 2 [(gogoproto.customname) = "EndpointMAC"];
22
+	// Tunnel Endpoint IP defines the host IP for the host in
23
+	// which this container is running and can be reached by
24
+	// building a tunnel to that host IP.
25
+	string tunnel_endpoint_ip = 3 [(gogoproto.customname) = "TunnelEndpointIP"];
26
+}
0 27
\ No newline at end of file
1 28
new file mode 100644
... ...
@@ -0,0 +1,336 @@
0
+package overlay
1
+
2
+import (
3
+	"fmt"
4
+	"net"
5
+	"sync"
6
+
7
+	"github.com/Sirupsen/logrus"
8
+)
9
+
10
+const ovPeerTable = "overlay_peer_table"
11
+
12
+type peerKey struct {
13
+	peerIP  net.IP
14
+	peerMac net.HardwareAddr
15
+}
16
+
17
+type peerEntry struct {
18
+	eid        string
19
+	vtep       net.IP
20
+	peerIPMask net.IPMask
21
+	inSandbox  bool
22
+	isLocal    bool
23
+}
24
+
25
+type peerMap struct {
26
+	mp map[string]peerEntry
27
+	sync.Mutex
28
+}
29
+
30
+type peerNetworkMap struct {
31
+	mp map[string]*peerMap
32
+	sync.Mutex
33
+}
34
+
35
+func (pKey peerKey) String() string {
36
+	return fmt.Sprintf("%s %s", pKey.peerIP, pKey.peerMac)
37
+}
38
+
39
+func (pKey *peerKey) Scan(state fmt.ScanState, verb rune) error {
40
+	ipB, err := state.Token(true, nil)
41
+	if err != nil {
42
+		return err
43
+	}
44
+
45
+	pKey.peerIP = net.ParseIP(string(ipB))
46
+
47
+	macB, err := state.Token(true, nil)
48
+	if err != nil {
49
+		return err
50
+	}
51
+
52
+	pKey.peerMac, err = net.ParseMAC(string(macB))
53
+	if err != nil {
54
+		return err
55
+	}
56
+
57
+	return nil
58
+}
59
+
60
+var peerDbWg sync.WaitGroup
61
+
62
+func (d *driver) peerDbWalk(f func(string, *peerKey, *peerEntry) bool) error {
63
+	d.peerDb.Lock()
64
+	nids := []string{}
65
+	for nid := range d.peerDb.mp {
66
+		nids = append(nids, nid)
67
+	}
68
+	d.peerDb.Unlock()
69
+
70
+	for _, nid := range nids {
71
+		d.peerDbNetworkWalk(nid, func(pKey *peerKey, pEntry *peerEntry) bool {
72
+			return f(nid, pKey, pEntry)
73
+		})
74
+	}
75
+	return nil
76
+}
77
+
78
+func (d *driver) peerDbNetworkWalk(nid string, f func(*peerKey, *peerEntry) bool) error {
79
+	d.peerDb.Lock()
80
+	pMap, ok := d.peerDb.mp[nid]
81
+	if !ok {
82
+		d.peerDb.Unlock()
83
+		return nil
84
+	}
85
+	d.peerDb.Unlock()
86
+
87
+	pMap.Lock()
88
+	for pKeyStr, pEntry := range pMap.mp {
89
+		var pKey peerKey
90
+		if _, err := fmt.Sscan(pKeyStr, &pKey); err != nil {
91
+			logrus.Warnf("Peer key scan on network %s failed: %v", nid, err)
92
+		}
93
+
94
+		if f(&pKey, &pEntry) {
95
+			pMap.Unlock()
96
+			return nil
97
+		}
98
+	}
99
+	pMap.Unlock()
100
+
101
+	return nil
102
+}
103
+
104
+func (d *driver) peerDbSearch(nid string, peerIP net.IP) (net.HardwareAddr, net.IPMask, net.IP, error) {
105
+	var (
106
+		peerMac    net.HardwareAddr
107
+		vtep       net.IP
108
+		peerIPMask net.IPMask
109
+		found      bool
110
+	)
111
+
112
+	err := d.peerDbNetworkWalk(nid, func(pKey *peerKey, pEntry *peerEntry) bool {
113
+		if pKey.peerIP.Equal(peerIP) {
114
+			peerMac = pKey.peerMac
115
+			peerIPMask = pEntry.peerIPMask
116
+			vtep = pEntry.vtep
117
+			found = true
118
+			return found
119
+		}
120
+
121
+		return found
122
+	})
123
+
124
+	if err != nil {
125
+		return nil, nil, nil, fmt.Errorf("peerdb search for peer ip %q failed: %v", peerIP, err)
126
+	}
127
+
128
+	if !found {
129
+		return nil, nil, nil, fmt.Errorf("peer ip %q not found in peerdb", peerIP)
130
+	}
131
+
132
+	return peerMac, peerIPMask, vtep, nil
133
+}
134
+
135
+func (d *driver) peerDbAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
136
+	peerMac net.HardwareAddr, vtep net.IP, isLocal bool) {
137
+
138
+	peerDbWg.Wait()
139
+
140
+	d.peerDb.Lock()
141
+	pMap, ok := d.peerDb.mp[nid]
142
+	if !ok {
143
+		d.peerDb.mp[nid] = &peerMap{
144
+			mp: make(map[string]peerEntry),
145
+		}
146
+
147
+		pMap = d.peerDb.mp[nid]
148
+	}
149
+	d.peerDb.Unlock()
150
+
151
+	pKey := peerKey{
152
+		peerIP:  peerIP,
153
+		peerMac: peerMac,
154
+	}
155
+
156
+	pEntry := peerEntry{
157
+		eid:        eid,
158
+		vtep:       vtep,
159
+		peerIPMask: peerIPMask,
160
+		isLocal:    isLocal,
161
+	}
162
+
163
+	pMap.Lock()
164
+	pMap.mp[pKey.String()] = pEntry
165
+	pMap.Unlock()
166
+}
167
+
168
+func (d *driver) peerDbDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
169
+	peerMac net.HardwareAddr, vtep net.IP) {
170
+	peerDbWg.Wait()
171
+
172
+	d.peerDb.Lock()
173
+	pMap, ok := d.peerDb.mp[nid]
174
+	if !ok {
175
+		d.peerDb.Unlock()
176
+		return
177
+	}
178
+	d.peerDb.Unlock()
179
+
180
+	pKey := peerKey{
181
+		peerIP:  peerIP,
182
+		peerMac: peerMac,
183
+	}
184
+
185
+	pMap.Lock()
186
+	delete(pMap.mp, pKey.String())
187
+	pMap.Unlock()
188
+}
189
+
190
+func (d *driver) peerDbUpdateSandbox(nid string) {
191
+	d.peerDb.Lock()
192
+	pMap, ok := d.peerDb.mp[nid]
193
+	if !ok {
194
+		d.peerDb.Unlock()
195
+		return
196
+	}
197
+	d.peerDb.Unlock()
198
+
199
+	peerDbWg.Add(1)
200
+
201
+	var peerOps []func()
202
+	pMap.Lock()
203
+	for pKeyStr, pEntry := range pMap.mp {
204
+		var pKey peerKey
205
+		if _, err := fmt.Sscan(pKeyStr, &pKey); err != nil {
206
+			fmt.Printf("peer key scan failed: %v", err)
207
+		}
208
+
209
+		if pEntry.isLocal {
210
+			continue
211
+		}
212
+
213
+		// Go captures variables by reference. The pEntry could be
214
+		// pointing to the same memory location for every iteration. Make
215
+		// a copy of pEntry before capturing it in the following closure.
216
+		entry := pEntry
217
+		op := func() {
218
+			if err := d.peerAdd(nid, entry.eid, pKey.peerIP, entry.peerIPMask,
219
+				pKey.peerMac, entry.vtep,
220
+				false); err != nil {
221
+				fmt.Printf("peerdbupdate in sandbox failed for ip %s and mac %s: %v",
222
+					pKey.peerIP, pKey.peerMac, err)
223
+			}
224
+		}
225
+
226
+		peerOps = append(peerOps, op)
227
+	}
228
+	pMap.Unlock()
229
+
230
+	for _, op := range peerOps {
231
+		op()
232
+	}
233
+
234
+	peerDbWg.Done()
235
+}
236
+
237
+func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
238
+	peerMac net.HardwareAddr, vtep net.IP, updateDb bool) error {
239
+
240
+	if err := validateID(nid, eid); err != nil {
241
+		return err
242
+	}
243
+
244
+	if updateDb {
245
+		d.peerDbAdd(nid, eid, peerIP, peerIPMask, peerMac, vtep, false)
246
+	}
247
+
248
+	n := d.network(nid)
249
+	if n == nil {
250
+		return nil
251
+	}
252
+
253
+	sbox := n.sandbox()
254
+	if sbox == nil {
255
+		return nil
256
+	}
257
+
258
+	IP := &net.IPNet{
259
+		IP:   peerIP,
260
+		Mask: peerIPMask,
261
+	}
262
+
263
+	s := n.getSubnetforIP(IP)
264
+	if s == nil {
265
+		return fmt.Errorf("couldn't find the subnet %q in network %q\n", IP.String(), n.id)
266
+	}
267
+
268
+	if err := n.obtainVxlanID(s); err != nil {
269
+		return fmt.Errorf("couldn't get vxlan id for %q: %v", s.subnetIP.String(), err)
270
+	}
271
+
272
+	if err := n.joinSubnetSandbox(s, false); err != nil {
273
+		return fmt.Errorf("subnet sandbox join failed for %q: %v", s.subnetIP.String(), err)
274
+	}
275
+
276
+	if err := d.checkEncryption(nid, vtep, n.vxlanID(s), false, true); err != nil {
277
+		logrus.Warn(err)
278
+	}
279
+
280
+	// Add neighbor entry for the peer IP
281
+	if err := sbox.AddNeighbor(peerIP, peerMac, sbox.NeighborOptions().LinkName(s.vxlanName)); err != nil {
282
+		return fmt.Errorf("could not add neigbor entry into the sandbox: %v", err)
283
+	}
284
+
285
+	// XXX Add fdb entry to the bridge for the peer mac
286
+
287
+	return nil
288
+}
289
+
290
+func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
291
+	peerMac net.HardwareAddr, vtep net.IP, updateDb bool) error {
292
+
293
+	if err := validateID(nid, eid); err != nil {
294
+		return err
295
+	}
296
+
297
+	if updateDb {
298
+		d.peerDbDelete(nid, eid, peerIP, peerIPMask, peerMac, vtep)
299
+	}
300
+
301
+	n := d.network(nid)
302
+	if n == nil {
303
+		return nil
304
+	}
305
+
306
+	sbox := n.sandbox()
307
+	if sbox == nil {
308
+		return nil
309
+	}
310
+
311
+	// Delete fdb entry to the bridge for the peer mac
312
+	if err := sbox.DeleteNeighbor(vtep, peerMac, true); err != nil {
313
+		return fmt.Errorf("could not delete fdb entry into the sandbox: %v", err)
314
+	}
315
+
316
+	// Delete neighbor entry for the peer IP
317
+	if err := sbox.DeleteNeighbor(peerIP, peerMac, true); err != nil {
318
+		return fmt.Errorf("could not delete neigbor entry into the sandbox: %v", err)
319
+	}
320
+
321
+	if err := d.checkEncryption(nid, vtep, 0, false, false); err != nil {
322
+		logrus.Warn(err)
323
+	}
324
+
325
+	return nil
326
+}
327
+
328
+func (d *driver) pushLocalDb() {
329
+	d.peerDbWalk(func(nid string, pKey *peerKey, pEntry *peerEntry) bool {
330
+		if pEntry.isLocal {
331
+			d.pushLocalEndpointEvent("join", nid, pEntry.eid)
332
+		}
333
+		return false
334
+	})
335
+}
... ...
@@ -30,4 +30,10 @@ const (
30 30
 
31 31
 	// SourceMac of the network
32 32
 	SourceMac = "com.docker.network.windowsshim.sourcemac"
33
+
34
+	// DisableICC label
35
+	DisableICC = "com.docker.network.windowsshim.disableicc"
36
+
37
+	// DisableDNS label
38
+	DisableDNS = "com.docker.network.windowsshim.disable_dns"
33 39
 )
34 40
new file mode 100644
... ...
@@ -0,0 +1,112 @@
0
+package overlay
1
+
2
+import (
3
+	"fmt"
4
+	"net"
5
+
6
+	"github.com/Sirupsen/logrus"
7
+	"github.com/docker/libnetwork/driverapi"
8
+	"github.com/docker/libnetwork/types"
9
+	"github.com/gogo/protobuf/proto"
10
+)
11
+
12
+// Join method is invoked when a Sandbox is attached to an endpoint.
13
+func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
14
+	if err := validateID(nid, eid); err != nil {
15
+		return err
16
+	}
17
+
18
+	n := d.network(nid)
19
+	if n == nil {
20
+		return fmt.Errorf("could not find network with id %s", nid)
21
+	}
22
+
23
+	ep := n.endpoint(eid)
24
+	if ep == nil {
25
+		return fmt.Errorf("could not find endpoint with id %s", eid)
26
+	}
27
+
28
+	if err := d.writeEndpointToStore(ep); err != nil {
29
+		return fmt.Errorf("failed to update overlay endpoint %s to local data store: %v", ep.id[0:7], err)
30
+	}
31
+
32
+	buf, err := proto.Marshal(&PeerRecord{
33
+		EndpointIP:       ep.addr.String(),
34
+		EndpointMAC:      ep.mac.String(),
35
+		TunnelEndpointIP: n.providerAddress,
36
+	})
37
+
38
+	if err != nil {
39
+		return err
40
+	}
41
+
42
+	if err := jinfo.AddTableEntry(ovPeerTable, eid, buf); err != nil {
43
+		logrus.Errorf("overlay: Failed adding table entry to joininfo: %v", err)
44
+	}
45
+
46
+	d.pushLocalEndpointEvent("join", nid, eid)
47
+
48
+	return nil
49
+}
50
+
51
+func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
52
+	if tableName != ovPeerTable {
53
+		logrus.Errorf("Unexpected table notification for table %s received", tableName)
54
+		return
55
+	}
56
+
57
+	eid := key
58
+
59
+	var peer PeerRecord
60
+	if err := proto.Unmarshal(value, &peer); err != nil {
61
+		logrus.Errorf("Failed to unmarshal peer record: %v", err)
62
+		return
63
+	}
64
+
65
+	n := d.network(nid)
66
+	if n == nil {
67
+		return
68
+	}
69
+
70
+	// Ignore local peers. We already know about them and they
71
+	// should not be added to vxlan fdb.
72
+	if peer.TunnelEndpointIP == n.providerAddress {
73
+		return
74
+	}
75
+
76
+	addr, err := types.ParseCIDR(peer.EndpointIP)
77
+	if err != nil {
78
+		logrus.Errorf("Invalid peer IP %s received in event notify", peer.EndpointIP)
79
+		return
80
+	}
81
+
82
+	mac, err := net.ParseMAC(peer.EndpointMAC)
83
+	if err != nil {
84
+		logrus.Errorf("Invalid mac %s received in event notify", peer.EndpointMAC)
85
+		return
86
+	}
87
+
88
+	vtep := net.ParseIP(peer.TunnelEndpointIP)
89
+	if vtep == nil {
90
+		logrus.Errorf("Invalid VTEP %s received in event notify", peer.TunnelEndpointIP)
91
+		return
92
+	}
93
+
94
+	if etype == driverapi.Delete {
95
+		d.peerDelete(nid, eid, addr.IP, addr.Mask, mac, vtep, true)
96
+		return
97
+	}
98
+
99
+	d.peerAdd(nid, eid, addr.IP, addr.Mask, mac, vtep, true)
100
+}
101
+
102
+// Leave method is invoked when a Sandbox detaches from an endpoint.
103
+func (d *driver) Leave(nid, eid string) error {
104
+	if err := validateID(nid, eid); err != nil {
105
+		return err
106
+	}
107
+
108
+	d.pushLocalEndpointEvent("leave", nid, eid)
109
+
110
+	return nil
111
+}
0 112
new file mode 100644
... ...
@@ -0,0 +1,346 @@
0
+package overlay
1
+
2
+import (
3
+	"encoding/json"
4
+	"fmt"
5
+	"net"
6
+
7
+	"github.com/Microsoft/hcsshim"
8
+	"github.com/Sirupsen/logrus"
9
+	"github.com/docker/libnetwork/datastore"
10
+	"github.com/docker/libnetwork/driverapi"
11
+	"github.com/docker/libnetwork/types"
12
+)
13
+
14
+type endpointTable map[string]*endpoint
15
+
16
+const overlayEndpointPrefix = "overlay/endpoint"
17
+
18
+type endpoint struct {
19
+	id        string
20
+	nid       string
21
+	profileId string
22
+	remote    bool
23
+	mac       net.HardwareAddr
24
+	addr      *net.IPNet
25
+	dbExists  bool
26
+	dbIndex   uint64
27
+}
28
+
29
+func validateID(nid, eid string) error {
30
+	if nid == "" {
31
+		return fmt.Errorf("invalid network id")
32
+	}
33
+
34
+	if eid == "" {
35
+		return fmt.Errorf("invalid endpoint id")
36
+	}
37
+
38
+	return nil
39
+}
40
+
41
+func (n *network) endpoint(eid string) *endpoint {
42
+	n.Lock()
43
+	defer n.Unlock()
44
+
45
+	return n.endpoints[eid]
46
+}
47
+
48
+func (n *network) addEndpoint(ep *endpoint) {
49
+	n.Lock()
50
+	n.endpoints[ep.id] = ep
51
+	n.Unlock()
52
+}
53
+
54
+func (n *network) deleteEndpoint(eid string) {
55
+	n.Lock()
56
+	delete(n.endpoints, eid)
57
+	n.Unlock()
58
+}
59
+
60
+func (n *network) removeEndpointWithAddress(addr *net.IPNet) {
61
+	var networkEndpoint *endpoint
62
+	n.Lock()
63
+	for _, ep := range n.endpoints {
64
+		if ep.addr.IP.Equal(addr.IP) {
65
+			networkEndpoint = ep
66
+			break
67
+		}
68
+	}
69
+	if networkEndpoint != nil {
70
+		delete(n.endpoints, networkEndpoint.id)
71
+	}
72
+	n.Unlock()
73
+
74
+	if networkEndpoint != nil {
75
+		logrus.Debugf("Removing stale endpoint from HNS")
76
+		_, err := hcsshim.HNSEndpointRequest("DELETE", networkEndpoint.profileId, "")
77
+
78
+		if err != nil {
79
+			logrus.Debugf("Failed to delete stale overlay endpoint (%s) from hns", networkEndpoint.id[0:7])
80
+		}
81
+
82
+		if err := n.driver.deleteEndpointFromStore(networkEndpoint); err != nil {
83
+			logrus.Debugf("Failed to delete stale overlay endpoint (%s) from store", networkEndpoint.id[0:7])
84
+		}
85
+	}
86
+}
87
+
88
+func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
89
+	epOptions map[string]interface{}) error {
90
+	var err error
91
+	if err = validateID(nid, eid); err != nil {
92
+		return err
93
+	}
94
+
95
+	// Since we perform lazy configuration make sure we try
96
+	// configuring the driver when we enter CreateEndpoint since
97
+	// CreateNetwork may not be called in every node.
98
+	if err := d.configure(); err != nil {
99
+		return err
100
+	}
101
+
102
+	n := d.network(nid)
103
+	if n == nil {
104
+		return fmt.Errorf("network id %q not found", nid)
105
+	}
106
+
107
+	ep := &endpoint{
108
+		id:   eid,
109
+		nid:  n.id,
110
+		addr: ifInfo.Address(),
111
+		mac:  ifInfo.MacAddress(),
112
+	}
113
+
114
+	if ep.addr == nil {
115
+		return fmt.Errorf("create endpoint was not passed interface IP address")
116
+	}
117
+
118
+	if s := n.getSubnetforIP(ep.addr); s == nil {
119
+		return fmt.Errorf("no matching subnet for IP %q in network %q\n", ep.addr, nid)
120
+	}
121
+
122
+	// Todo: Add port bindings and qos policies here
123
+
124
+	hnsEndpoint := &hcsshim.HNSEndpoint{
125
+		VirtualNetwork:    n.hnsId,
126
+		IPAddress:         ep.addr.IP,
127
+		EnableInternalDNS: true,
128
+	}
129
+
130
+	if ep.mac != nil {
131
+		hnsEndpoint.MacAddress = ep.mac.String()
132
+	}
133
+
134
+	paPolicy, err := json.Marshal(hcsshim.PaPolicy{
135
+		Type: "PA",
136
+		PA:   n.providerAddress,
137
+	})
138
+
139
+	if err != nil {
140
+		return err
141
+	}
142
+
143
+	hnsEndpoint.Policies = append(hnsEndpoint.Policies, paPolicy)
144
+
145
+	configurationb, err := json.Marshal(hnsEndpoint)
146
+	if err != nil {
147
+		return err
148
+	}
149
+
150
+	hnsresponse, err := hcsshim.HNSEndpointRequest("POST", "", string(configurationb))
151
+	if err != nil {
152
+		return err
153
+	}
154
+
155
+	ep.profileId = hnsresponse.Id
156
+
157
+	if ep.mac == nil {
158
+		ep.mac, err = net.ParseMAC(hnsresponse.MacAddress)
159
+		if err != nil {
160
+			return err
161
+		}
162
+
163
+		if err := ifInfo.SetMacAddress(ep.mac); err != nil {
164
+			return err
165
+		}
166
+	}
167
+
168
+	n.addEndpoint(ep)
169
+	if err := d.writeEndpointToStore(ep); err != nil {
170
+		return fmt.Errorf("failed to update overlay endpoint %s to local store: %v", ep.id[0:7], err)
171
+	}
172
+
173
+	return nil
174
+}
175
+
176
+func (d *driver) DeleteEndpoint(nid, eid string) error {
177
+	if err := validateID(nid, eid); err != nil {
178
+		return err
179
+	}
180
+
181
+	n := d.network(nid)
182
+	if n == nil {
183
+		return fmt.Errorf("network id %q not found", nid)
184
+	}
185
+
186
+	ep := n.endpoint(eid)
187
+	if ep == nil {
188
+		return fmt.Errorf("endpoint id %q not found", eid)
189
+	}
190
+
191
+	n.deleteEndpoint(eid)
192
+
193
+	if err := d.deleteEndpointFromStore(ep); err != nil {
194
+		logrus.Warnf("Failed to delete overlay endpoint %s from local store: %v", ep.id[0:7], err)
195
+	}
196
+
197
+	_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileId, "")
198
+	if err != nil {
199
+		return err
200
+	}
201
+
202
+	return nil
203
+}
204
+
205
+func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) {
206
+	if err := validateID(nid, eid); err != nil {
207
+		return nil, err
208
+	}
209
+
210
+	n := d.network(nid)
211
+	if n == nil {
212
+		return nil, fmt.Errorf("network id %q not found", nid)
213
+	}
214
+
215
+	ep := n.endpoint(eid)
216
+	if ep == nil {
217
+		return nil, fmt.Errorf("endpoint id %q not found", eid)
218
+	}
219
+
220
+	data := make(map[string]interface{}, 1)
221
+	data["hnsid"] = ep.profileId
222
+	data["AllowUnqualifiedDNSQuery"] = true
223
+	return data, nil
224
+}
225
+
226
+func (d *driver) deleteEndpointFromStore(e *endpoint) error {
227
+	if d.localStore == nil {
228
+		return fmt.Errorf("overlay local store not initialized, ep not deleted")
229
+	}
230
+
231
+	if err := d.localStore.DeleteObjectAtomic(e); err != nil {
232
+		return err
233
+	}
234
+
235
+	return nil
236
+}
237
+
238
+func (d *driver) writeEndpointToStore(e *endpoint) error {
239
+	if d.localStore == nil {
240
+		return fmt.Errorf("overlay local store not initialized, ep not added")
241
+	}
242
+
243
+	if err := d.localStore.PutObjectAtomic(e); err != nil {
244
+		return err
245
+	}
246
+	return nil
247
+}
248
+
249
+func (ep *endpoint) DataScope() string {
250
+	return datastore.LocalScope
251
+}
252
+
253
+func (ep *endpoint) New() datastore.KVObject {
254
+	return &endpoint{}
255
+}
256
+
257
+func (ep *endpoint) CopyTo(o datastore.KVObject) error {
258
+	dstep := o.(*endpoint)
259
+	*dstep = *ep
260
+	return nil
261
+}
262
+
263
+func (ep *endpoint) Key() []string {
264
+	return []string{overlayEndpointPrefix, ep.id}
265
+}
266
+
267
+func (ep *endpoint) KeyPrefix() []string {
268
+	return []string{overlayEndpointPrefix}
269
+}
270
+
271
+func (ep *endpoint) Index() uint64 {
272
+	return ep.dbIndex
273
+}
274
+
275
+func (ep *endpoint) SetIndex(index uint64) {
276
+	ep.dbIndex = index
277
+	ep.dbExists = true
278
+}
279
+
280
+func (ep *endpoint) Exists() bool {
281
+	return ep.dbExists
282
+}
283
+
284
+func (ep *endpoint) Skip() bool {
285
+	return false
286
+}
287
+
288
+func (ep *endpoint) Value() []byte {
289
+	b, err := json.Marshal(ep)
290
+	if err != nil {
291
+		return nil
292
+	}
293
+	return b
294
+}
295
+
296
+func (ep *endpoint) SetValue(value []byte) error {
297
+	return json.Unmarshal(value, ep)
298
+}
299
+
300
+func (ep *endpoint) MarshalJSON() ([]byte, error) {
301
+	epMap := make(map[string]interface{})
302
+
303
+	epMap["id"] = ep.id
304
+	epMap["nid"] = ep.nid
305
+	epMap["remote"] = ep.remote
306
+	if ep.profileId != "" {
307
+		epMap["profileId"] = ep.profileId
308
+	}
309
+
310
+	if ep.addr != nil {
311
+		epMap["addr"] = ep.addr.String()
312
+	}
313
+	if len(ep.mac) != 0 {
314
+		epMap["mac"] = ep.mac.String()
315
+	}
316
+
317
+	return json.Marshal(epMap)
318
+}
319
+
320
+func (ep *endpoint) UnmarshalJSON(value []byte) error {
321
+	var (
322
+		err   error
323
+		epMap map[string]interface{}
324
+	)
325
+
326
+	json.Unmarshal(value, &epMap)
327
+
328
+	ep.id = epMap["id"].(string)
329
+	ep.nid = epMap["nid"].(string)
330
+	ep.remote = epMap["remote"].(bool)
331
+	if v, ok := epMap["profileId"]; ok {
332
+		ep.profileId = v.(string)
333
+	}
334
+	if v, ok := epMap["mac"]; ok {
335
+		if ep.mac, err = net.ParseMAC(v.(string)); err != nil {
336
+			return types.InternalErrorf("failed to decode endpoint interface mac address after json unmarshal: %s", v.(string))
337
+		}
338
+	}
339
+	if v, ok := epMap["addr"]; ok {
340
+		if ep.addr, err = types.ParseCIDR(v.(string)); err != nil {
341
+			return types.InternalErrorf("failed to decode endpoint interface ipv4 address after json unmarshal: %v", err)
342
+		}
343
+	}
344
+	return nil
345
+}
0 346
new file mode 100644
... ...
@@ -0,0 +1,209 @@
0
+package overlay
1
+
2
+import (
3
+	"encoding/json"
4
+	"fmt"
5
+	"sync"
6
+
7
+	"github.com/Microsoft/hcsshim"
8
+	"github.com/Sirupsen/logrus"
9
+	"github.com/docker/libnetwork/datastore"
10
+)
11
+
12
+const overlayNetworkPrefix = "overlay/network"
13
+
14
+type localNetwork struct {
15
+	id              string
16
+	hnsID           string
17
+	providerAddress string
18
+	dbIndex         uint64
19
+	dbExists        bool
20
+	sync.Mutex
21
+}
22
+
23
+func (d *driver) findHnsNetwork(n *network) error {
24
+	ln, err := d.getLocalNetworkFromStore(n.id)
25
+
26
+	if err != nil {
27
+		return err
28
+	}
29
+
30
+	if ln == nil {
31
+		subnets := []hcsshim.Subnet{}
32
+
33
+		for _, s := range n.subnets {
34
+			subnet := hcsshim.Subnet{
35
+				AddressPrefix: s.subnetIP.String(),
36
+			}
37
+
38
+			if s.gwIP != nil {
39
+				subnet.GatewayAddress = s.gwIP.IP.String()
40
+			}
41
+
42
+			vsidPolicy, err := json.Marshal(hcsshim.VsidPolicy{
43
+				Type: "VSID",
44
+				VSID: uint(s.vni),
45
+			})
46
+
47
+			if err != nil {
48
+				return err
49
+			}
50
+
51
+			subnet.Policies = append(subnet.Policies, vsidPolicy)
52
+			subnets = append(subnets, subnet)
53
+		}
54
+
55
+		network := &hcsshim.HNSNetwork{
56
+			Name:               n.name,
57
+			Type:               d.Type(),
58
+			Subnets:            subnets,
59
+			NetworkAdapterName: n.interfaceName,
60
+		}
61
+
62
+		configurationb, err := json.Marshal(network)
63
+		if err != nil {
64
+			return err
65
+		}
66
+
67
+		configuration := string(configurationb)
68
+		logrus.Infof("HNSNetwork Request =%v", configuration)
69
+
70
+		hnsresponse, err := hcsshim.HNSNetworkRequest("POST", "", configuration)
71
+		if err != nil {
72
+			return err
73
+		}
74
+
75
+		n.hnsId = hnsresponse.Id
76
+		n.providerAddress = hnsresponse.ManagementIP
77
+
78
+		// Save local host specific info
79
+		if err := d.writeLocalNetworkToStore(n); err != nil {
80
+			return fmt.Errorf("failed to update data store for network %v: %v", n.id, err)
81
+		}
82
+	} else {
83
+		n.hnsId = ln.hnsID
84
+		n.providerAddress = ln.providerAddress
85
+	}
86
+
87
+	return nil
88
+}
89
+
90
+func (d *driver) getLocalNetworkFromStore(nid string) (*localNetwork, error) {
91
+
92
+	if d.localStore == nil {
93
+		return nil, fmt.Errorf("overlay local store not initialized, network not found")
94
+	}
95
+
96
+	n := &localNetwork{id: nid}
97
+	if err := d.localStore.GetObject(datastore.Key(n.Key()...), n); err != nil {
98
+		return nil, nil
99
+	}
100
+
101
+	return n, nil
102
+}
103
+
104
+func (d *driver) deleteLocalNetworkFromStore(n *network) error {
105
+	if d.localStore == nil {
106
+		return fmt.Errorf("overlay local store not initialized, network not deleted")
107
+	}
108
+
109
+	ln, err := d.getLocalNetworkFromStore(n.id)
110
+
111
+	if err != nil {
112
+		return err
113
+	}
114
+
115
+	if err = d.localStore.DeleteObjectAtomic(ln); err != nil {
116
+		return err
117
+	}
118
+
119
+	return nil
120
+}
121
+
122
+func (d *driver) writeLocalNetworkToStore(n *network) error {
123
+	if d.localStore == nil {
124
+		return fmt.Errorf("overlay local store not initialized, network not added")
125
+	}
126
+
127
+	ln := &localNetwork{
128
+		id:              n.id,
129
+		hnsID:           n.hnsId,
130
+		providerAddress: n.providerAddress,
131
+	}
132
+
133
+	if err := d.localStore.PutObjectAtomic(ln); err != nil {
134
+		return err
135
+	}
136
+	return nil
137
+}
138
+
139
+func (n *localNetwork) DataScope() string {
140
+	return datastore.LocalScope
141
+}
142
+
143
+func (n *localNetwork) New() datastore.KVObject {
144
+	return &localNetwork{}
145
+}
146
+
147
+func (n *localNetwork) CopyTo(o datastore.KVObject) error {
148
+	dstep := o.(*localNetwork)
149
+	*dstep = *n
150
+	return nil
151
+}
152
+
153
+func (n *localNetwork) Key() []string {
154
+	return []string{overlayNetworkPrefix, n.id}
155
+}
156
+
157
+func (n *localNetwork) KeyPrefix() []string {
158
+	return []string{overlayNetworkPrefix}
159
+}
160
+
161
+func (n *localNetwork) Index() uint64 {
162
+	return n.dbIndex
163
+}
164
+
165
+func (n *localNetwork) SetIndex(index uint64) {
166
+	n.dbIndex = index
167
+	n.dbExists = true
168
+}
169
+
170
+func (n *localNetwork) Exists() bool {
171
+	return n.dbExists
172
+}
173
+
174
+func (n *localNetwork) Skip() bool {
175
+	return false
176
+}
177
+
178
+func (n *localNetwork) Value() []byte {
179
+	b, err := json.Marshal(n)
180
+	if err != nil {
181
+		return nil
182
+	}
183
+	return b
184
+}
185
+
186
+func (n *localNetwork) SetValue(value []byte) error {
187
+	return json.Unmarshal(value, n)
188
+}
189
+
190
+func (n *localNetwork) MarshalJSON() ([]byte, error) {
191
+	networkMap := make(map[string]interface{})
192
+
193
+	networkMap["id"] = n.id
194
+	networkMap["hnsID"] = n.hnsID
195
+	networkMap["providerAddress"] = n.providerAddress
196
+	return json.Marshal(networkMap)
197
+}
198
+
199
+func (n *localNetwork) UnmarshalJSON(value []byte) error {
200
+	var networkMap map[string]interface{}
201
+
202
+	json.Unmarshal(value, &networkMap)
203
+
204
+	n.id = networkMap["id"].(string)
205
+	n.hnsID = networkMap["hnsID"].(string)
206
+	n.providerAddress = networkMap["providerAddress"].(string)
207
+	return nil
208
+}
0 209
new file mode 100644
... ...
@@ -0,0 +1,512 @@
0
+package overlay
1
+
2
+import (
3
+	"encoding/json"
4
+	"fmt"
5
+	"net"
6
+	"strconv"
7
+	"strings"
8
+	"sync"
9
+
10
+	"github.com/Microsoft/hcsshim"
11
+	"github.com/Sirupsen/logrus"
12
+	"github.com/docker/libnetwork/datastore"
13
+	"github.com/docker/libnetwork/driverapi"
14
+	"github.com/docker/libnetwork/netlabel"
15
+	"github.com/docker/libnetwork/types"
16
+)
17
+
18
+var (
19
+	hostMode  bool
20
+	networkMu sync.Mutex
21
+)
22
+
23
+type networkTable map[string]*network
24
+
25
+type subnet struct {
26
+	vni      uint32
27
+	initErr  error
28
+	subnetIP *net.IPNet
29
+	gwIP     *net.IPNet
30
+}
31
+
32
+type subnetJSON struct {
33
+	SubnetIP string
34
+	GwIP     string
35
+	Vni      uint32
36
+}
37
+
38
+type network struct {
39
+	id              string
40
+	name            string
41
+	hnsId           string
42
+	dbIndex         uint64
43
+	dbExists        bool
44
+	providerAddress string
45
+	interfaceName   string
46
+	endpoints       endpointTable
47
+	driver          *driver
48
+	initEpoch       int
49
+	initErr         error
50
+	subnets         []*subnet
51
+	secure          bool
52
+	sync.Mutex
53
+}
54
+
55
+func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) {
56
+	return nil, types.NotImplementedErrorf("not implemented")
57
+}
58
+
59
+func (d *driver) NetworkFree(id string) error {
60
+	return types.NotImplementedErrorf("not implemented")
61
+}
62
+
63
+func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
64
+	var (
65
+		networkName   string
66
+		interfaceName string
67
+	)
68
+
69
+	if id == "" {
70
+		return fmt.Errorf("invalid network id")
71
+	}
72
+
73
+	if len(ipV4Data) == 0 || ipV4Data[0].Pool.String() == "0.0.0.0/0" {
74
+		return types.BadRequestErrorf("ipv4 pool is empty")
75
+	}
76
+
77
+	vnis := make([]uint32, 0, len(ipV4Data))
78
+
79
+	// Since we perform lazy configuration make sure we try
80
+	// configuring the driver when we enter CreateNetwork
81
+	if err := d.configure(); err != nil {
82
+		return err
83
+	}
84
+
85
+	n := &network{
86
+		id:        id,
87
+		driver:    d,
88
+		endpoints: endpointTable{},
89
+		subnets:   []*subnet{},
90
+	}
91
+
92
+	genData, ok := option[netlabel.GenericData].(map[string]string)
93
+
94
+	if !ok {
95
+		return fmt.Errorf("Unknown generic data option")
96
+	}
97
+
98
+	for label, value := range genData {
99
+		switch label {
100
+		case "com.docker.network.windowsshim.networkname":
101
+			networkName = value
102
+		case "com.docker.network.windowsshim.interface":
103
+			interfaceName = value
104
+		case "com.docker.network.windowsshim.hnsid":
105
+			n.hnsId = value
106
+		case netlabel.OverlayVxlanIDList:
107
+			vniStrings := strings.Split(value, ",")
108
+			for _, vniStr := range vniStrings {
109
+				vni, err := strconv.Atoi(vniStr)
110
+				if err != nil {
111
+					return fmt.Errorf("invalid vxlan id value %q passed", vniStr)
112
+				}
113
+
114
+				vnis = append(vnis, uint32(vni))
115
+			}
116
+		}
117
+	}
118
+
119
+	// If we are getting vnis from libnetwork, either we get for
120
+	// all subnets or none.
121
+	if len(vnis) != 0 && len(vnis) < len(ipV4Data) {
122
+		return fmt.Errorf("insufficient vnis(%d) passed to overlay", len(vnis))
123
+	}
124
+
125
+	for i, ipd := range ipV4Data {
126
+		s := &subnet{
127
+			subnetIP: ipd.Pool,
128
+			gwIP:     ipd.Gateway,
129
+		}
130
+
131
+		if len(vnis) != 0 {
132
+			s.vni = vnis[i]
133
+		}
134
+
135
+		n.subnets = append(n.subnets, s)
136
+	}
137
+
138
+	n.name = networkName
139
+	if n.name == "" {
140
+		n.name = id
141
+	}
142
+
143
+	n.interfaceName = interfaceName
144
+
145
+	if err := n.writeToStore(); err != nil {
146
+		return fmt.Errorf("failed to update data store for network %v: %v", n.id, err)
147
+	}
148
+
149
+	if nInfo != nil {
150
+		if err := nInfo.TableEventRegister(ovPeerTable); err != nil {
151
+			return err
152
+		}
153
+	}
154
+
155
+	d.addNetwork(n)
156
+
157
+	err := d.findHnsNetwork(n)
158
+	genData["com.docker.network.windowsshim.hnsid"] = n.hnsId
159
+
160
+	return err
161
+}
162
+
163
+func (d *driver) DeleteNetwork(nid string) error {
164
+	if nid == "" {
165
+		return fmt.Errorf("invalid network id")
166
+	}
167
+
168
+	// Make sure driver resources are initialized before proceeding
169
+	if err := d.configure(); err != nil {
170
+		return err
171
+	}
172
+
173
+	n := d.network(nid)
174
+	if n == nil {
175
+		return fmt.Errorf("could not find network with id %s", nid)
176
+	}
177
+
178
+	_, err := hcsshim.HNSNetworkRequest("DELETE", n.hnsId, "")
179
+	if err != nil {
180
+		return err
181
+	}
182
+
183
+	d.deleteNetwork(nid)
184
+	d.deleteLocalNetworkFromStore(n)
185
+
186
+	return nil
187
+}
188
+
189
+func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error {
190
+	return nil
191
+}
192
+
193
+func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
194
+	return nil
195
+}
196
+
197
+func (d *driver) addNetwork(n *network) {
198
+	d.Lock()
199
+	d.networks[n.id] = n
200
+	d.Unlock()
201
+}
202
+
203
+func (d *driver) deleteNetwork(nid string) {
204
+	d.Lock()
205
+	delete(d.networks, nid)
206
+	d.Unlock()
207
+}
208
+
209
+func (d *driver) network(nid string) *network {
210
+	d.Lock()
211
+	networks := d.networks
212
+	d.Unlock()
213
+
214
+	n, ok := networks[nid]
215
+	if !ok {
216
+		n = d.getNetworkFromStore(nid)
217
+		if n != nil {
218
+			n.driver = d
219
+			n.endpoints = endpointTable{}
220
+			networks[nid] = n
221
+		}
222
+	}
223
+
224
+	return n
225
+}
226
+
227
+func (d *driver) getNetworkFromStore(nid string) *network {
228
+	if d.store == nil {
229
+		return nil
230
+	}
231
+
232
+	n := &network{id: nid}
233
+	if err := d.store.GetObject(datastore.Key(n.Key()...), n); err != nil {
234
+		return nil
235
+	}
236
+
237
+	// As the network is being discovered from the global store, HNS may not be aware of it yet
238
+	err := d.findHnsNetwork(n)
239
+	if err != nil {
240
+		logrus.Errorf("Failed to find hns network: %v", err)
241
+		return nil
242
+	}
243
+
244
+	return n
245
+}
246
+
247
+func (n *network) vxlanID(s *subnet) uint32 {
248
+	n.Lock()
249
+	defer n.Unlock()
250
+
251
+	return s.vni
252
+}
253
+
254
+func (n *network) setVxlanID(s *subnet, vni uint32) {
255
+	n.Lock()
256
+	s.vni = vni
257
+	n.Unlock()
258
+}
259
+
260
+func (n *network) Key() []string {
261
+	return []string{"overlay", "network", n.id}
262
+}
263
+
264
+func (n *network) KeyPrefix() []string {
265
+	return []string{"overlay", "network"}
266
+}
267
+
268
+func (n *network) Value() []byte {
269
+	m := map[string]interface{}{}
270
+
271
+	netJSON := []*subnetJSON{}
272
+
273
+	for _, s := range n.subnets {
274
+		sj := &subnetJSON{
275
+			SubnetIP: s.subnetIP.String(),
276
+			GwIP:     s.gwIP.String(),
277
+			Vni:      s.vni,
278
+		}
279
+		netJSON = append(netJSON, sj)
280
+	}
281
+
282
+	b, err := json.Marshal(netJSON)
283
+	if err != nil {
284
+		return []byte{}
285
+	}
286
+
287
+	m["secure"] = n.secure
288
+	m["subnets"] = netJSON
289
+	m["interfaceName"] = n.interfaceName
290
+	m["providerAddress"] = n.providerAddress
291
+	m["hnsId"] = n.hnsId
292
+	m["name"] = n.name
293
+	b, err = json.Marshal(m)
294
+	if err != nil {
295
+		return []byte{}
296
+	}
297
+
298
+	return b
299
+}
300
+
301
+func (n *network) Index() uint64 {
302
+	return n.dbIndex
303
+}
304
+
305
+func (n *network) SetIndex(index uint64) {
306
+	n.dbIndex = index
307
+	n.dbExists = true
308
+}
309
+
310
+func (n *network) Exists() bool {
311
+	return n.dbExists
312
+}
313
+
314
+func (n *network) Skip() bool {
315
+	return false
316
+}
317
+
318
+func (n *network) SetValue(value []byte) error {
319
+	var (
320
+		m       map[string]interface{}
321
+		newNet  bool
322
+		isMap   = true
323
+		netJSON = []*subnetJSON{}
324
+	)
325
+
326
+	if err := json.Unmarshal(value, &m); err != nil {
327
+		err := json.Unmarshal(value, &netJSON)
328
+		if err != nil {
329
+			return err
330
+		}
331
+		isMap = false
332
+	}
333
+
334
+	if len(n.subnets) == 0 {
335
+		newNet = true
336
+	}
337
+
338
+	if isMap {
339
+		if val, ok := m["secure"]; ok {
340
+			n.secure = val.(bool)
341
+		}
342
+		if val, ok := m["providerAddress"]; ok {
343
+			n.providerAddress = val.(string)
344
+		}
345
+		if val, ok := m["interfaceName"]; ok {
346
+			n.interfaceName = val.(string)
347
+		}
348
+		if val, ok := m["hnsId"]; ok {
349
+			n.hnsId = val.(string)
350
+		}
351
+		if val, ok := m["name"]; ok {
352
+			n.name = val.(string)
353
+		}
354
+		bytes, err := json.Marshal(m["subnets"])
355
+		if err != nil {
356
+			return err
357
+		}
358
+		if err := json.Unmarshal(bytes, &netJSON); err != nil {
359
+			return err
360
+		}
361
+	}
362
+
363
+	for _, sj := range netJSON {
364
+		subnetIPstr := sj.SubnetIP
365
+		gwIPstr := sj.GwIP
366
+		vni := sj.Vni
367
+
368
+		subnetIP, _ := types.ParseCIDR(subnetIPstr)
369
+		gwIP, _ := types.ParseCIDR(gwIPstr)
370
+
371
+		if newNet {
372
+			s := &subnet{
373
+				subnetIP: subnetIP,
374
+				gwIP:     gwIP,
375
+				vni:      vni,
376
+			}
377
+			n.subnets = append(n.subnets, s)
378
+		} else {
379
+			sNet := n.getMatchingSubnet(subnetIP)
380
+			if sNet != nil {
381
+				sNet.vni = vni
382
+			}
383
+		}
384
+	}
385
+	return nil
386
+}
387
+
388
+func (n *network) DataScope() string {
389
+	return datastore.GlobalScope
390
+}
391
+
392
+func (n *network) writeToStore() error {
393
+	if n.driver.store == nil {
394
+		return nil
395
+	}
396
+
397
+	return n.driver.store.PutObjectAtomic(n)
398
+}
399
+
400
+func (n *network) releaseVxlanID() ([]uint32, error) {
401
+	if len(n.subnets) == 0 {
402
+		return nil, nil
403
+	}
404
+
405
+	if n.driver.store != nil {
406
+		if err := n.driver.store.DeleteObjectAtomic(n); err != nil {
407
+			if err == datastore.ErrKeyModified || err == datastore.ErrKeyNotFound {
408
+				// In both the above cases we can safely assume that the key has been removed by some other
409
+				// instance and so simply get out of here
410
+				return nil, nil
411
+			}
412
+
413
+			return nil, fmt.Errorf("failed to delete network to vxlan id map: %v", err)
414
+		}
415
+	}
416
+	var vnis []uint32
417
+	for _, s := range n.subnets {
418
+		if n.driver.vxlanIdm != nil {
419
+			vni := n.vxlanID(s)
420
+			vnis = append(vnis, vni)
421
+			n.driver.vxlanIdm.Release(uint64(vni))
422
+		}
423
+
424
+		n.setVxlanID(s, 0)
425
+	}
426
+
427
+	return vnis, nil
428
+}
429
+
430
+func (n *network) obtainVxlanID(s *subnet) error {
431
+	//return if the subnet already has a vxlan id assigned
432
+	if s.vni != 0 {
433
+		return nil
434
+	}
435
+
436
+	if n.driver.store == nil {
437
+		return fmt.Errorf("no valid vxlan id and no datastore configured, cannot obtain vxlan id")
438
+	}
439
+
440
+	for {
441
+		if err := n.driver.store.GetObject(datastore.Key(n.Key()...), n); err != nil {
442
+			return fmt.Errorf("getting network %q from datastore failed %v", n.id, err)
443
+		}
444
+
445
+		if s.vni == 0 {
446
+			vxlanID, err := n.driver.vxlanIdm.GetID()
447
+			if err != nil {
448
+				return fmt.Errorf("failed to allocate vxlan id: %v", err)
449
+			}
450
+
451
+			n.setVxlanID(s, uint32(vxlanID))
452
+			if err := n.writeToStore(); err != nil {
453
+				n.driver.vxlanIdm.Release(uint64(n.vxlanID(s)))
454
+				n.setVxlanID(s, 0)
455
+				if err == datastore.ErrKeyModified {
456
+					continue
457
+				}
458
+				return fmt.Errorf("network %q failed to update data store: %v", n.id, err)
459
+			}
460
+			return nil
461
+		}
462
+		return nil
463
+	}
464
+}
465
+
466
+// contains return true if the passed ip belongs to one the network's
467
+// subnets
468
+func (n *network) contains(ip net.IP) bool {
469
+	for _, s := range n.subnets {
470
+		if s.subnetIP.Contains(ip) {
471
+			return true
472
+		}
473
+	}
474
+
475
+	return false
476
+}
477
+
478
+// getSubnetforIP returns the subnet to which the given IP belongs
479
+func (n *network) getSubnetforIP(ip *net.IPNet) *subnet {
480
+	for _, s := range n.subnets {
481
+		// first check if the mask lengths are the same
482
+		i, _ := s.subnetIP.Mask.Size()
483
+		j, _ := ip.Mask.Size()
484
+		if i != j {
485
+			continue
486
+		}
487
+		if s.subnetIP.Contains(ip.IP) {
488
+			return s
489
+		}
490
+	}
491
+	return nil
492
+}
493
+
494
+// getMatchingSubnet return the network's subnet that matches the input
495
+func (n *network) getMatchingSubnet(ip *net.IPNet) *subnet {
496
+	if ip == nil {
497
+		return nil
498
+	}
499
+	for _, s := range n.subnets {
500
+		// first check if the mask lengths are the same
501
+		i, _ := s.subnetIP.Mask.Size()
502
+		j, _ := ip.Mask.Size()
503
+		if i != j {
504
+			continue
505
+		}
506
+		if s.subnetIP.IP.Equal(ip.IP) {
507
+			return s
508
+		}
509
+	}
510
+	return nil
511
+}
0 512
new file mode 100644
... ...
@@ -0,0 +1,179 @@
0
+package overlay
1
+
2
+import (
3
+	"fmt"
4
+	"net"
5
+	"strings"
6
+	"time"
7
+
8
+	"github.com/Sirupsen/logrus"
9
+	"github.com/hashicorp/serf/serf"
10
+)
11
+
12
+type ovNotify struct {
13
+	action string
14
+	ep     *endpoint
15
+	nw     *network
16
+}
17
+
18
+type logWriter struct{}
19
+
20
+func (l *logWriter) Write(p []byte) (int, error) {
21
+	str := string(p)
22
+
23
+	switch {
24
+	case strings.Contains(str, "[WARN]"):
25
+		logrus.Warn(str)
26
+	case strings.Contains(str, "[DEBUG]"):
27
+		logrus.Debug(str)
28
+	case strings.Contains(str, "[INFO]"):
29
+		logrus.Info(str)
30
+	case strings.Contains(str, "[ERR]"):
31
+		logrus.Error(str)
32
+	}
33
+
34
+	return len(p), nil
35
+}
36
+
37
+func (d *driver) serfInit() error {
38
+	var err error
39
+
40
+	config := serf.DefaultConfig()
41
+	config.Init()
42
+	config.MemberlistConfig.BindAddr = d.bindAddress
43
+
44
+	d.eventCh = make(chan serf.Event, 4)
45
+	config.EventCh = d.eventCh
46
+	config.UserCoalescePeriod = 1 * time.Second
47
+	config.UserQuiescentPeriod = 50 * time.Millisecond
48
+
49
+	config.LogOutput = &logWriter{}
50
+	config.MemberlistConfig.LogOutput = config.LogOutput
51
+
52
+	s, err := serf.Create(config)
53
+	if err != nil {
54
+		return fmt.Errorf("failed to create cluster node: %v", err)
55
+	}
56
+	defer func() {
57
+		if err != nil {
58
+			s.Shutdown()
59
+		}
60
+	}()
61
+
62
+	d.serfInstance = s
63
+
64
+	d.notifyCh = make(chan ovNotify)
65
+	d.exitCh = make(chan chan struct{})
66
+
67
+	go d.startSerfLoop(d.eventCh, d.notifyCh, d.exitCh)
68
+	return nil
69
+}
70
+
71
+func (d *driver) serfJoin(neighIP string) error {
72
+	if neighIP == "" {
73
+		return fmt.Errorf("no neighbor to join")
74
+	}
75
+	if _, err := d.serfInstance.Join([]string{neighIP}, false); err != nil {
76
+		return fmt.Errorf("Failed to join the cluster at neigh IP %s: %v",
77
+			neighIP, err)
78
+	}
79
+	return nil
80
+}
81
+
82
+func (d *driver) notifyEvent(event ovNotify) {
83
+	ep := event.ep
84
+
85
+	ePayload := fmt.Sprintf("%s %s %s %s", event.action, ep.addr.IP.String(),
86
+		net.IP(ep.addr.Mask).String(), ep.mac.String())
87
+	eName := fmt.Sprintf("jl %s %s %s", d.serfInstance.LocalMember().Addr.String(),
88
+		event.nw.id, ep.id)
89
+
90
+	if err := d.serfInstance.UserEvent(eName, []byte(ePayload), true); err != nil {
91
+		logrus.Errorf("Sending user event failed: %v\n", err)
92
+	}
93
+}
94
+
95
+func (d *driver) processEvent(u serf.UserEvent) {
96
+	logrus.Debugf("Received user event name:%s, payload:%s\n", u.Name,
97
+		string(u.Payload))
98
+
99
+	var dummy, action, vtepStr, nid, eid, ipStr, maskStr, macStr string
100
+	if _, err := fmt.Sscan(u.Name, &dummy, &vtepStr, &nid, &eid); err != nil {
101
+		fmt.Printf("Failed to scan name string: %v\n", err)
102
+	}
103
+
104
+	if _, err := fmt.Sscan(string(u.Payload), &action,
105
+		&ipStr, &maskStr, &macStr); err != nil {
106
+		fmt.Printf("Failed to scan value string: %v\n", err)
107
+	}
108
+
109
+	logrus.Debugf("Parsed data = %s/%s/%s/%s/%s/%s\n", nid, eid, vtepStr, ipStr, maskStr, macStr)
110
+
111
+	mac, err := net.ParseMAC(macStr)
112
+	if err != nil {
113
+		logrus.Errorf("Failed to parse mac: %v\n", err)
114
+	}
115
+
116
+	if d.serfInstance.LocalMember().Addr.String() == vtepStr {
117
+		return
118
+	}
119
+
120
+	switch action {
121
+	case "join":
122
+		if err := d.peerAdd(nid, eid, net.ParseIP(ipStr), net.IPMask(net.ParseIP(maskStr).To4()), mac,
123
+			net.ParseIP(vtepStr), true); err != nil {
124
+			logrus.Errorf("Peer add failed in the driver: %v\n", err)
125
+		}
126
+	case "leave":
127
+		if err := d.peerDelete(nid, eid, net.ParseIP(ipStr), net.IPMask(net.ParseIP(maskStr).To4()), mac,
128
+			net.ParseIP(vtepStr), true); err != nil {
129
+			logrus.Errorf("Peer delete failed in the driver: %v\n", err)
130
+		}
131
+	}
132
+}
133
+
134
+func (d *driver) startSerfLoop(eventCh chan serf.Event, notifyCh chan ovNotify,
135
+	exitCh chan chan struct{}) {
136
+
137
+	for {
138
+		select {
139
+		case notify, ok := <-notifyCh:
140
+			if !ok {
141
+				break
142
+			}
143
+
144
+			d.notifyEvent(notify)
145
+		case ch, ok := <-exitCh:
146
+			if !ok {
147
+				break
148
+			}
149
+
150
+			if err := d.serfInstance.Leave(); err != nil {
151
+				logrus.Errorf("failed leaving the cluster: %v\n", err)
152
+			}
153
+
154
+			d.serfInstance.Shutdown()
155
+			close(ch)
156
+			return
157
+		case e, ok := <-eventCh:
158
+			if !ok {
159
+				break
160
+			}
161
+			u, ok := e.(serf.UserEvent)
162
+			if !ok {
163
+				break
164
+			}
165
+			d.processEvent(u)
166
+		}
167
+	}
168
+}
169
+
170
+func (d *driver) isSerfAlive() bool {
171
+	d.Lock()
172
+	serfInstance := d.serfInstance
173
+	d.Unlock()
174
+	if serfInstance == nil || serfInstance.State() != serf.SerfAlive {
175
+		return false
176
+	}
177
+	return true
178
+}
0 179
new file mode 100644
... ...
@@ -0,0 +1,468 @@
0
+// Code generated by protoc-gen-gogo.
1
+// source: overlay.proto
2
+// DO NOT EDIT!
3
+
4
+/*
5
+	Package overlay is a generated protocol buffer package.
6
+
7
+	It is generated from these files:
8
+		overlay.proto
9
+
10
+	It has these top-level messages:
11
+		PeerRecord
12
+*/
13
+package overlay
14
+
15
+import proto "github.com/gogo/protobuf/proto"
16
+import fmt "fmt"
17
+import math "math"
18
+import _ "github.com/gogo/protobuf/gogoproto"
19
+
20
+import strings "strings"
21
+import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
22
+import sort "sort"
23
+import strconv "strconv"
24
+import reflect "reflect"
25
+
26
+import io "io"
27
+
28
+// Reference imports to suppress errors if they are not otherwise used.
29
+var _ = proto.Marshal
30
+var _ = fmt.Errorf
31
+var _ = math.Inf
32
+
33
+// This is a compile-time assertion to ensure that this generated file
34
+// is compatible with the proto package it is being compiled against.
35
+const _ = proto.GoGoProtoPackageIsVersion1
36
+
37
+// PeerRecord defines the information corresponding to a peer
38
+// container in the overlay network.
39
+type PeerRecord struct {
40
+	// Endpoint IP is the IP of the container attachment on the
41
+	// given overlay network.
42
+	EndpointIP string `protobuf:"bytes,1,opt,name=endpoint_ip,json=endpointIp,proto3" json:"endpoint_ip,omitempty"`
43
+	// Endpoint MAC is the mac address of the container attachment
44
+	// on the given overlay network.
45
+	EndpointMAC string `protobuf:"bytes,2,opt,name=endpoint_mac,json=endpointMac,proto3" json:"endpoint_mac,omitempty"`
46
+	// Tunnel Endpoint IP defines the host IP for the host in
47
+	// which this container is running and can be reached by
48
+	// building a tunnel to that host IP.
49
+	TunnelEndpointIP string `protobuf:"bytes,3,opt,name=tunnel_endpoint_ip,json=tunnelEndpointIp,proto3" json:"tunnel_endpoint_ip,omitempty"`
50
+}
51
+
52
+func (m *PeerRecord) Reset()                    { *m = PeerRecord{} }
53
+func (*PeerRecord) ProtoMessage()               {}
54
+func (*PeerRecord) Descriptor() ([]byte, []int) { return fileDescriptorOverlay, []int{0} }
55
+
56
+func init() {
57
+	proto.RegisterType((*PeerRecord)(nil), "overlay.PeerRecord")
58
+}
59
+func (this *PeerRecord) GoString() string {
60
+	if this == nil {
61
+		return "nil"
62
+	}
63
+	s := make([]string, 0, 7)
64
+	s = append(s, "&overlay.PeerRecord{")
65
+	s = append(s, "EndpointIP: "+fmt.Sprintf("%#v", this.EndpointIP)+",\n")
66
+	s = append(s, "EndpointMAC: "+fmt.Sprintf("%#v", this.EndpointMAC)+",\n")
67
+	s = append(s, "TunnelEndpointIP: "+fmt.Sprintf("%#v", this.TunnelEndpointIP)+",\n")
68
+	s = append(s, "}")
69
+	return strings.Join(s, "")
70
+}
71
+func valueToGoStringOverlay(v interface{}, typ string) string {
72
+	rv := reflect.ValueOf(v)
73
+	if rv.IsNil() {
74
+		return "nil"
75
+	}
76
+	pv := reflect.Indirect(rv).Interface()
77
+	return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
78
+}
79
+func extensionToGoStringOverlay(e map[int32]github_com_gogo_protobuf_proto.Extension) string {
80
+	if e == nil {
81
+		return "nil"
82
+	}
83
+	s := "map[int32]proto.Extension{"
84
+	keys := make([]int, 0, len(e))
85
+	for k := range e {
86
+		keys = append(keys, int(k))
87
+	}
88
+	sort.Ints(keys)
89
+	ss := []string{}
90
+	for _, k := range keys {
91
+		ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString())
92
+	}
93
+	s += strings.Join(ss, ",") + "}"
94
+	return s
95
+}
96
+func (m *PeerRecord) Marshal() (data []byte, err error) {
97
+	size := m.Size()
98
+	data = make([]byte, size)
99
+	n, err := m.MarshalTo(data)
100
+	if err != nil {
101
+		return nil, err
102
+	}
103
+	return data[:n], nil
104
+}
105
+
106
+func (m *PeerRecord) MarshalTo(data []byte) (int, error) {
107
+	var i int
108
+	_ = i
109
+	var l int
110
+	_ = l
111
+	if len(m.EndpointIP) > 0 {
112
+		data[i] = 0xa
113
+		i++
114
+		i = encodeVarintOverlay(data, i, uint64(len(m.EndpointIP)))
115
+		i += copy(data[i:], m.EndpointIP)
116
+	}
117
+	if len(m.EndpointMAC) > 0 {
118
+		data[i] = 0x12
119
+		i++
120
+		i = encodeVarintOverlay(data, i, uint64(len(m.EndpointMAC)))
121
+		i += copy(data[i:], m.EndpointMAC)
122
+	}
123
+	if len(m.TunnelEndpointIP) > 0 {
124
+		data[i] = 0x1a
125
+		i++
126
+		i = encodeVarintOverlay(data, i, uint64(len(m.TunnelEndpointIP)))
127
+		i += copy(data[i:], m.TunnelEndpointIP)
128
+	}
129
+	return i, nil
130
+}
131
+
132
+func encodeFixed64Overlay(data []byte, offset int, v uint64) int {
133
+	data[offset] = uint8(v)
134
+	data[offset+1] = uint8(v >> 8)
135
+	data[offset+2] = uint8(v >> 16)
136
+	data[offset+3] = uint8(v >> 24)
137
+	data[offset+4] = uint8(v >> 32)
138
+	data[offset+5] = uint8(v >> 40)
139
+	data[offset+6] = uint8(v >> 48)
140
+	data[offset+7] = uint8(v >> 56)
141
+	return offset + 8
142
+}
143
+func encodeFixed32Overlay(data []byte, offset int, v uint32) int {
144
+	data[offset] = uint8(v)
145
+	data[offset+1] = uint8(v >> 8)
146
+	data[offset+2] = uint8(v >> 16)
147
+	data[offset+3] = uint8(v >> 24)
148
+	return offset + 4
149
+}
150
+func encodeVarintOverlay(data []byte, offset int, v uint64) int {
151
+	for v >= 1<<7 {
152
+		data[offset] = uint8(v&0x7f | 0x80)
153
+		v >>= 7
154
+		offset++
155
+	}
156
+	data[offset] = uint8(v)
157
+	return offset + 1
158
+}
159
+func (m *PeerRecord) Size() (n int) {
160
+	var l int
161
+	_ = l
162
+	l = len(m.EndpointIP)
163
+	if l > 0 {
164
+		n += 1 + l + sovOverlay(uint64(l))
165
+	}
166
+	l = len(m.EndpointMAC)
167
+	if l > 0 {
168
+		n += 1 + l + sovOverlay(uint64(l))
169
+	}
170
+	l = len(m.TunnelEndpointIP)
171
+	if l > 0 {
172
+		n += 1 + l + sovOverlay(uint64(l))
173
+	}
174
+	return n
175
+}
176
+
177
+func sovOverlay(x uint64) (n int) {
178
+	for {
179
+		n++
180
+		x >>= 7
181
+		if x == 0 {
182
+			break
183
+		}
184
+	}
185
+	return n
186
+}
187
+func sozOverlay(x uint64) (n int) {
188
+	return sovOverlay(uint64((x << 1) ^ uint64((int64(x) >> 63))))
189
+}
190
+func (this *PeerRecord) String() string {
191
+	if this == nil {
192
+		return "nil"
193
+	}
194
+	s := strings.Join([]string{`&PeerRecord{`,
195
+		`EndpointIP:` + fmt.Sprintf("%v", this.EndpointIP) + `,`,
196
+		`EndpointMAC:` + fmt.Sprintf("%v", this.EndpointMAC) + `,`,
197
+		`TunnelEndpointIP:` + fmt.Sprintf("%v", this.TunnelEndpointIP) + `,`,
198
+		`}`,
199
+	}, "")
200
+	return s
201
+}
202
+func valueToStringOverlay(v interface{}) string {
203
+	rv := reflect.ValueOf(v)
204
+	if rv.IsNil() {
205
+		return "nil"
206
+	}
207
+	pv := reflect.Indirect(rv).Interface()
208
+	return fmt.Sprintf("*%v", pv)
209
+}
210
+func (m *PeerRecord) Unmarshal(data []byte) error {
211
+	l := len(data)
212
+	iNdEx := 0
213
+	for iNdEx < l {
214
+		preIndex := iNdEx
215
+		var wire uint64
216
+		for shift := uint(0); ; shift += 7 {
217
+			if shift >= 64 {
218
+				return ErrIntOverflowOverlay
219
+			}
220
+			if iNdEx >= l {
221
+				return io.ErrUnexpectedEOF
222
+			}
223
+			b := data[iNdEx]
224
+			iNdEx++
225
+			wire |= (uint64(b) & 0x7F) << shift
226
+			if b < 0x80 {
227
+				break
228
+			}
229
+		}
230
+		fieldNum := int32(wire >> 3)
231
+		wireType := int(wire & 0x7)
232
+		if wireType == 4 {
233
+			return fmt.Errorf("proto: PeerRecord: wiretype end group for non-group")
234
+		}
235
+		if fieldNum <= 0 {
236
+			return fmt.Errorf("proto: PeerRecord: illegal tag %d (wire type %d)", fieldNum, wire)
237
+		}
238
+		switch fieldNum {
239
+		case 1:
240
+			if wireType != 2 {
241
+				return fmt.Errorf("proto: wrong wireType = %d for field EndpointIP", wireType)
242
+			}
243
+			var stringLen uint64
244
+			for shift := uint(0); ; shift += 7 {
245
+				if shift >= 64 {
246
+					return ErrIntOverflowOverlay
247
+				}
248
+				if iNdEx >= l {
249
+					return io.ErrUnexpectedEOF
250
+				}
251
+				b := data[iNdEx]
252
+				iNdEx++
253
+				stringLen |= (uint64(b) & 0x7F) << shift
254
+				if b < 0x80 {
255
+					break
256
+				}
257
+			}
258
+			intStringLen := int(stringLen)
259
+			if intStringLen < 0 {
260
+				return ErrInvalidLengthOverlay
261
+			}
262
+			postIndex := iNdEx + intStringLen
263
+			if postIndex > l {
264
+				return io.ErrUnexpectedEOF
265
+			}
266
+			m.EndpointIP = string(data[iNdEx:postIndex])
267
+			iNdEx = postIndex
268
+		case 2:
269
+			if wireType != 2 {
270
+				return fmt.Errorf("proto: wrong wireType = %d for field EndpointMAC", wireType)
271
+			}
272
+			var stringLen uint64
273
+			for shift := uint(0); ; shift += 7 {
274
+				if shift >= 64 {
275
+					return ErrIntOverflowOverlay
276
+				}
277
+				if iNdEx >= l {
278
+					return io.ErrUnexpectedEOF
279
+				}
280
+				b := data[iNdEx]
281
+				iNdEx++
282
+				stringLen |= (uint64(b) & 0x7F) << shift
283
+				if b < 0x80 {
284
+					break
285
+				}
286
+			}
287
+			intStringLen := int(stringLen)
288
+			if intStringLen < 0 {
289
+				return ErrInvalidLengthOverlay
290
+			}
291
+			postIndex := iNdEx + intStringLen
292
+			if postIndex > l {
293
+				return io.ErrUnexpectedEOF
294
+			}
295
+			m.EndpointMAC = string(data[iNdEx:postIndex])
296
+			iNdEx = postIndex
297
+		case 3:
298
+			if wireType != 2 {
299
+				return fmt.Errorf("proto: wrong wireType = %d for field TunnelEndpointIP", wireType)
300
+			}
301
+			var stringLen uint64
302
+			for shift := uint(0); ; shift += 7 {
303
+				if shift >= 64 {
304
+					return ErrIntOverflowOverlay
305
+				}
306
+				if iNdEx >= l {
307
+					return io.ErrUnexpectedEOF
308
+				}
309
+				b := data[iNdEx]
310
+				iNdEx++
311
+				stringLen |= (uint64(b) & 0x7F) << shift
312
+				if b < 0x80 {
313
+					break
314
+				}
315
+			}
316
+			intStringLen := int(stringLen)
317
+			if intStringLen < 0 {
318
+				return ErrInvalidLengthOverlay
319
+			}
320
+			postIndex := iNdEx + intStringLen
321
+			if postIndex > l {
322
+				return io.ErrUnexpectedEOF
323
+			}
324
+			m.TunnelEndpointIP = string(data[iNdEx:postIndex])
325
+			iNdEx = postIndex
326
+		default:
327
+			iNdEx = preIndex
328
+			skippy, err := skipOverlay(data[iNdEx:])
329
+			if err != nil {
330
+				return err
331
+			}
332
+			if skippy < 0 {
333
+				return ErrInvalidLengthOverlay
334
+			}
335
+			if (iNdEx + skippy) > l {
336
+				return io.ErrUnexpectedEOF
337
+			}
338
+			iNdEx += skippy
339
+		}
340
+	}
341
+
342
+	if iNdEx > l {
343
+		return io.ErrUnexpectedEOF
344
+	}
345
+	return nil
346
+}
347
+func skipOverlay(data []byte) (n int, err error) {
348
+	l := len(data)
349
+	iNdEx := 0
350
+	for iNdEx < l {
351
+		var wire uint64
352
+		for shift := uint(0); ; shift += 7 {
353
+			if shift >= 64 {
354
+				return 0, ErrIntOverflowOverlay
355
+			}
356
+			if iNdEx >= l {
357
+				return 0, io.ErrUnexpectedEOF
358
+			}
359
+			b := data[iNdEx]
360
+			iNdEx++
361
+			wire |= (uint64(b) & 0x7F) << shift
362
+			if b < 0x80 {
363
+				break
364
+			}
365
+		}
366
+		wireType := int(wire & 0x7)
367
+		switch wireType {
368
+		case 0:
369
+			for shift := uint(0); ; shift += 7 {
370
+				if shift >= 64 {
371
+					return 0, ErrIntOverflowOverlay
372
+				}
373
+				if iNdEx >= l {
374
+					return 0, io.ErrUnexpectedEOF
375
+				}
376
+				iNdEx++
377
+				if data[iNdEx-1] < 0x80 {
378
+					break
379
+				}
380
+			}
381
+			return iNdEx, nil
382
+		case 1:
383
+			iNdEx += 8
384
+			return iNdEx, nil
385
+		case 2:
386
+			var length int
387
+			for shift := uint(0); ; shift += 7 {
388
+				if shift >= 64 {
389
+					return 0, ErrIntOverflowOverlay
390
+				}
391
+				if iNdEx >= l {
392
+					return 0, io.ErrUnexpectedEOF
393
+				}
394
+				b := data[iNdEx]
395
+				iNdEx++
396
+				length |= (int(b) & 0x7F) << shift
397
+				if b < 0x80 {
398
+					break
399
+				}
400
+			}
401
+			iNdEx += length
402
+			if length < 0 {
403
+				return 0, ErrInvalidLengthOverlay
404
+			}
405
+			return iNdEx, nil
406
+		case 3:
407
+			for {
408
+				var innerWire uint64
409
+				var start int = iNdEx
410
+				for shift := uint(0); ; shift += 7 {
411
+					if shift >= 64 {
412
+						return 0, ErrIntOverflowOverlay
413
+					}
414
+					if iNdEx >= l {
415
+						return 0, io.ErrUnexpectedEOF
416
+					}
417
+					b := data[iNdEx]
418
+					iNdEx++
419
+					innerWire |= (uint64(b) & 0x7F) << shift
420
+					if b < 0x80 {
421
+						break
422
+					}
423
+				}
424
+				innerWireType := int(innerWire & 0x7)
425
+				if innerWireType == 4 {
426
+					break
427
+				}
428
+				next, err := skipOverlay(data[start:])
429
+				if err != nil {
430
+					return 0, err
431
+				}
432
+				iNdEx = start + next
433
+			}
434
+			return iNdEx, nil
435
+		case 4:
436
+			return iNdEx, nil
437
+		case 5:
438
+			iNdEx += 4
439
+			return iNdEx, nil
440
+		default:
441
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
442
+		}
443
+	}
444
+	panic("unreachable")
445
+}
446
+
447
+var (
448
+	ErrInvalidLengthOverlay = fmt.Errorf("proto: negative length found during unmarshaling")
449
+	ErrIntOverflowOverlay   = fmt.Errorf("proto: integer overflow")
450
+)
451
+
452
+var fileDescriptorOverlay = []byte{
453
+	// 195 bytes of a gzipped FileDescriptorProto
454
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0xcd, 0x2f, 0x4b, 0x2d,
455
+	0xca, 0x49, 0xac, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x87, 0x72, 0xa5, 0x44, 0xd2,
456
+	0xf3, 0xd3, 0xf3, 0xc1, 0x62, 0xfa, 0x20, 0x16, 0x44, 0x5a, 0x69, 0x2b, 0x23, 0x17, 0x57, 0x40,
457
+	0x6a, 0x6a, 0x51, 0x50, 0x6a, 0x72, 0x7e, 0x51, 0x8a, 0x90, 0x3e, 0x17, 0x77, 0x6a, 0x5e, 0x4a,
458
+	0x41, 0x7e, 0x66, 0x5e, 0x49, 0x7c, 0x66, 0x81, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xa7, 0x13, 0xdf,
459
+	0xa3, 0x7b, 0xf2, 0x5c, 0xae, 0x50, 0x61, 0xcf, 0x80, 0x20, 0x2e, 0x98, 0x12, 0xcf, 0x02, 0x21,
460
+	0x23, 0x2e, 0x1e, 0xb8, 0x86, 0xdc, 0xc4, 0x64, 0x09, 0x26, 0xb0, 0x0e, 0x7e, 0xa0, 0x0e, 0x6e,
461
+	0x98, 0x0e, 0x5f, 0x47, 0xe7, 0x20, 0xb8, 0xa9, 0xbe, 0x89, 0xc9, 0x42, 0x4e, 0x5c, 0x42, 0x25,
462
+	0xa5, 0x79, 0x79, 0xa9, 0x39, 0xf1, 0xc8, 0x76, 0x31, 0x83, 0x75, 0x8a, 0x00, 0x75, 0x0a, 0x84,
463
+	0x80, 0x65, 0x91, 0x6c, 0x14, 0x28, 0x41, 0x15, 0x29, 0x70, 0x92, 0xb8, 0xf1, 0x50, 0x8e, 0xe1,
464
+	0xc3, 0x43, 0x39, 0xc6, 0x86, 0x47, 0x72, 0x8c, 0x27, 0x80, 0xf8, 0x02, 0x10, 0x3f, 0x00, 0xe2,
465
+	0x24, 0x36, 0xb0, 0xc7, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbf, 0xd7, 0x7d, 0x7d, 0x08,
466
+	0x01, 0x00, 0x00,
467
+}
0 468
new file mode 100644
... ...
@@ -0,0 +1,27 @@
0
+syntax = "proto3";
1
+
2
+import "gogoproto/gogo.proto";
3
+
4
+package overlay;
5
+
6
+option (gogoproto.marshaler_all) = true;
7
+option (gogoproto.unmarshaler_all) = true;
8
+option (gogoproto.stringer_all) = true;
9
+option (gogoproto.gostring_all) = true;
10
+option (gogoproto.sizer_all) = true;
11
+option (gogoproto.goproto_stringer_all) = false;
12
+
13
+// PeerRecord defines the information corresponding to a peer
14
+// container in the overlay network.
15
+message PeerRecord {
16
+	// Endpoint IP is the IP of the container attachment on the
17
+	// given overlay network.
18
+	string endpoint_ip = 1 [(gogoproto.customname) = "EndpointIP"];
19
+	// Endpoint MAC is the mac address of the container attachment
20
+	// on the given overlay network.
21
+	string endpoint_mac = 2 [(gogoproto.customname) = "EndpointMAC"];
22
+	// Tunnel Endpoint IP defines the host IP for the host in
23
+	// which this container is running and can be reached by
24
+	// building a tunnel to that host IP.
25
+	string tunnel_endpoint_ip = 3 [(gogoproto.customname) = "TunnelEndpointIP"];
26
+}
0 27
\ No newline at end of file
1 28
new file mode 100644
... ...
@@ -0,0 +1,297 @@
0
+package overlay
1
+
2
+//go:generate protoc -I.:../../Godeps/_workspace/src/github.com/gogo/protobuf  --gogo_out=import_path=github.com/docker/libnetwork/drivers/overlay,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. overlay.proto
3
+
4
+import (
5
+	"fmt"
6
+	"net"
7
+	"sync"
8
+
9
+	"github.com/Microsoft/hcsshim"
10
+	"github.com/Sirupsen/logrus"
11
+	"github.com/docker/libnetwork/datastore"
12
+	"github.com/docker/libnetwork/discoverapi"
13
+	"github.com/docker/libnetwork/driverapi"
14
+	"github.com/docker/libnetwork/idm"
15
+	"github.com/docker/libnetwork/netlabel"
16
+	"github.com/docker/libnetwork/types"
17
+	"github.com/hashicorp/serf/serf"
18
+)
19
+
20
+const (
21
+	networkType  = "overlay"
22
+	vethPrefix   = "veth"
23
+	vethLen      = 7
24
+	vxlanIDStart = 4096
25
+	vxlanIDEnd   = (1 << 24) - 1
26
+	vxlanPort    = 4789
27
+	vxlanEncap   = 50
28
+	secureOption = "encrypted"
29
+)
30
+
31
+var initVxlanIdm = make(chan (bool), 1)
32
+
33
+type driver struct {
34
+	eventCh          chan serf.Event
35
+	notifyCh         chan ovNotify
36
+	exitCh           chan chan struct{}
37
+	bindAddress      string
38
+	advertiseAddress string
39
+	neighIP          string
40
+	config           map[string]interface{}
41
+	serfInstance     *serf.Serf
42
+	networks         networkTable
43
+	store            datastore.DataStore
44
+	localStore       datastore.DataStore
45
+	vxlanIdm         *idm.Idm
46
+	once             sync.Once
47
+	joinOnce         sync.Once
48
+	sync.Mutex
49
+}
50
+
51
+// Init registers a new instance of overlay driver
52
+func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
53
+	c := driverapi.Capability{
54
+		DataScope: datastore.GlobalScope,
55
+	}
56
+
57
+	d := &driver{
58
+		networks: networkTable{},
59
+		config:   config,
60
+	}
61
+
62
+	if data, ok := config[netlabel.GlobalKVClient]; ok {
63
+		var err error
64
+		dsc, ok := data.(discoverapi.DatastoreConfigData)
65
+		if !ok {
66
+			return types.InternalErrorf("incorrect data in datastore configuration: %v", data)
67
+		}
68
+		d.store, err = datastore.NewDataStoreFromConfig(dsc)
69
+		if err != nil {
70
+			return types.InternalErrorf("failed to initialize data store: %v", err)
71
+		}
72
+	}
73
+
74
+	if data, ok := config[netlabel.LocalKVClient]; ok {
75
+		var err error
76
+		dsc, ok := data.(discoverapi.DatastoreConfigData)
77
+		if !ok {
78
+			return types.InternalErrorf("incorrect data in datastore configuration: %v", data)
79
+		}
80
+		d.localStore, err = datastore.NewDataStoreFromConfig(dsc)
81
+		if err != nil {
82
+			return types.InternalErrorf("failed to initialize local data store: %v", err)
83
+		}
84
+	}
85
+
86
+	d.restoreEndpoints()
87
+
88
+	return dc.RegisterDriver(networkType, d, c)
89
+}
90
+
91
+// Endpoints are stored in the local store. Restore them and reconstruct the overlay sandbox
92
+func (d *driver) restoreEndpoints() error {
93
+	if d.localStore == nil {
94
+		logrus.Warnf("Cannot restore overlay endpoints because local datastore is missing")
95
+		return nil
96
+	}
97
+	kvol, err := d.localStore.List(datastore.Key(overlayEndpointPrefix), &endpoint{})
98
+	if err != nil && err != datastore.ErrKeyNotFound {
99
+		return fmt.Errorf("failed to read overlay endpoint from store: %v", err)
100
+	}
101
+
102
+	if err == datastore.ErrKeyNotFound {
103
+		return nil
104
+	}
105
+
106
+	for _, kvo := range kvol {
107
+		ep := kvo.(*endpoint)
108
+
109
+		n := d.network(ep.nid)
110
+		if n == nil || ep.remote {
111
+			if !ep.remote {
112
+				logrus.Debugf("Network (%s) not found for restored endpoint (%s)", ep.nid[0:7], ep.id[0:7])
113
+				logrus.Debugf("Deleting stale overlay endpoint (%s) from store", ep.id[0:7])
114
+			}
115
+
116
+			hcsshim.HNSEndpointRequest("DELETE", ep.profileId, "")
117
+
118
+			if err := d.deleteEndpointFromStore(ep); err != nil {
119
+				logrus.Debugf("Failed to delete stale overlay endpoint (%s) from store", ep.id[0:7])
120
+			}
121
+
122
+			continue
123
+		}
124
+
125
+		n.addEndpoint(ep)
126
+	}
127
+
128
+	return nil
129
+}
130
+
131
+// Fini cleans up the driver resources
132
+func Fini(drv driverapi.Driver) {
133
+	d := drv.(*driver)
134
+
135
+	if d.exitCh != nil {
136
+		waitCh := make(chan struct{})
137
+
138
+		d.exitCh <- waitCh
139
+
140
+		<-waitCh
141
+	}
142
+}
143
+
144
+func (d *driver) configure() error {
145
+	if d.store == nil {
146
+		return nil
147
+	}
148
+
149
+	if d.vxlanIdm == nil {
150
+		return d.initializeVxlanIdm()
151
+	}
152
+
153
+	return nil
154
+}
155
+
156
+func (d *driver) initializeVxlanIdm() error {
157
+	var err error
158
+
159
+	initVxlanIdm <- true
160
+	defer func() { <-initVxlanIdm }()
161
+
162
+	if d.vxlanIdm != nil {
163
+		return nil
164
+	}
165
+
166
+	d.vxlanIdm, err = idm.New(d.store, "vxlan-id", vxlanIDStart, vxlanIDEnd)
167
+	if err != nil {
168
+		return fmt.Errorf("failed to initialize vxlan id manager: %v", err)
169
+	}
170
+
171
+	return nil
172
+}
173
+
174
+func (d *driver) Type() string {
175
+	return networkType
176
+}
177
+
178
+func validateSelf(node string) error {
179
+	advIP := net.ParseIP(node)
180
+	if advIP == nil {
181
+		return fmt.Errorf("invalid self address (%s)", node)
182
+	}
183
+
184
+	addrs, err := net.InterfaceAddrs()
185
+	if err != nil {
186
+		return fmt.Errorf("Unable to get interface addresses %v", err)
187
+	}
188
+	for _, addr := range addrs {
189
+		ip, _, err := net.ParseCIDR(addr.String())
190
+		if err == nil && ip.Equal(advIP) {
191
+			return nil
192
+		}
193
+	}
194
+	return fmt.Errorf("Multi-Host overlay networking requires cluster-advertise(%s) to be configured with a local ip-address that is reachable within the cluster", advIP.String())
195
+}
196
+
197
+func (d *driver) nodeJoin(advertiseAddress, bindAddress string, self bool) {
198
+	if self && !d.isSerfAlive() {
199
+		if err := validateSelf(advertiseAddress); err != nil {
200
+			logrus.Errorf("%s", err.Error())
201
+		}
202
+
203
+		d.Lock()
204
+		d.advertiseAddress = advertiseAddress
205
+		d.bindAddress = bindAddress
206
+		d.Unlock()
207
+
208
+		// If there is no cluster store there is no need to start serf.
209
+		if d.store != nil {
210
+			err := d.serfInit()
211
+			if err != nil {
212
+				logrus.Errorf("initializing serf instance failed: %v", err)
213
+				return
214
+			}
215
+		}
216
+	}
217
+
218
+	d.Lock()
219
+	if !self {
220
+		d.neighIP = advertiseAddress
221
+	}
222
+	neighIP := d.neighIP
223
+	d.Unlock()
224
+
225
+	if d.serfInstance != nil && neighIP != "" {
226
+		var err error
227
+		d.joinOnce.Do(func() {
228
+			err = d.serfJoin(neighIP)
229
+			if err == nil {
230
+				d.pushLocalDb()
231
+			}
232
+		})
233
+		if err != nil {
234
+			logrus.Errorf("joining serf neighbor %s failed: %v", advertiseAddress, err)
235
+			d.Lock()
236
+			d.joinOnce = sync.Once{}
237
+			d.Unlock()
238
+			return
239
+		}
240
+	}
241
+}
242
+
243
+func (d *driver) pushLocalEndpointEvent(action, nid, eid string) {
244
+	n := d.network(nid)
245
+	if n == nil {
246
+		logrus.Debugf("Error pushing local endpoint event for network %s", nid)
247
+		return
248
+	}
249
+	ep := n.endpoint(eid)
250
+	if ep == nil {
251
+		logrus.Debugf("Error pushing local endpoint event for ep %s / %s", nid, eid)
252
+		return
253
+	}
254
+
255
+	if !d.isSerfAlive() {
256
+		return
257
+	}
258
+	d.notifyCh <- ovNotify{
259
+		action: action,
260
+		nw:     n,
261
+		ep:     ep,
262
+	}
263
+}
264
+
265
+// DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster
266
+func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
267
+
268
+	var err error
269
+	switch dType {
270
+	case discoverapi.NodeDiscovery:
271
+		nodeData, ok := data.(discoverapi.NodeDiscoveryData)
272
+		if !ok || nodeData.Address == "" {
273
+			return fmt.Errorf("invalid discovery data")
274
+		}
275
+		d.nodeJoin(nodeData.Address, nodeData.BindAddress, nodeData.Self)
276
+	case discoverapi.DatastoreConfig:
277
+		if d.store != nil {
278
+			return types.ForbiddenErrorf("cannot accept datastore configuration: Overlay driver has a datastore configured already")
279
+		}
280
+		dsc, ok := data.(discoverapi.DatastoreConfigData)
281
+		if !ok {
282
+			return types.InternalErrorf("incorrect data in datastore configuration: %v", data)
283
+		}
284
+		d.store, err = datastore.NewDataStoreFromConfig(dsc)
285
+		if err != nil {
286
+			return types.InternalErrorf("failed to initialize data store: %v", err)
287
+		}
288
+	default:
289
+	}
290
+	return nil
291
+}
292
+
293
+// DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster
294
+func (d *driver) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error {
295
+	return nil
296
+}
0 297
new file mode 100644
... ...
@@ -0,0 +1,154 @@
0
+package overlay
1
+
2
+import (
3
+	"fmt"
4
+	"net"
5
+
6
+	"encoding/json"
7
+
8
+	"github.com/Sirupsen/logrus"
9
+
10
+	"github.com/Microsoft/hcsshim"
11
+	"github.com/docker/libnetwork/types"
12
+)
13
+
14
+const ovPeerTable = "overlay_peer_table"
15
+
16
+func (d *driver) pushLocalDb() {
17
+	if !d.isSerfAlive() {
18
+		return
19
+	}
20
+
21
+	d.Lock()
22
+	networks := d.networks
23
+	d.Unlock()
24
+
25
+	for _, n := range networks {
26
+		n.Lock()
27
+		endpoints := n.endpoints
28
+		n.Unlock()
29
+
30
+		for _, ep := range endpoints {
31
+			if !ep.remote {
32
+				d.notifyCh <- ovNotify{
33
+					action: "join",
34
+					nw:     n,
35
+					ep:     ep,
36
+				}
37
+
38
+			}
39
+		}
40
+	}
41
+}
42
+
43
+func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
44
+	peerMac net.HardwareAddr, vtep net.IP, updateDb bool) error {
45
+
46
+	logrus.Debugf("WINOVERLAY: Enter peerAdd for ca ip %s with ca mac %s", peerIP.String(), peerMac.String())
47
+
48
+	if err := validateID(nid, eid); err != nil {
49
+		return err
50
+	}
51
+
52
+	n := d.network(nid)
53
+	if n == nil {
54
+		return nil
55
+	}
56
+
57
+	if updateDb {
58
+		logrus.Info("WINOVERLAY: peerAdd: notifying HNS of the REMOTE endpoint")
59
+
60
+		hnsEndpoint := &hcsshim.HNSEndpoint{
61
+			VirtualNetwork:   n.hnsId,
62
+			MacAddress:       peerMac.String(),
63
+			IPAddress:        peerIP,
64
+			IsRemoteEndpoint: true,
65
+		}
66
+
67
+		paPolicy, err := json.Marshal(hcsshim.PaPolicy{
68
+			Type: "PA",
69
+			PA:   vtep.String(),
70
+		})
71
+
72
+		if err != nil {
73
+			return err
74
+		}
75
+
76
+		hnsEndpoint.Policies = append(hnsEndpoint.Policies, paPolicy)
77
+
78
+		configurationb, err := json.Marshal(hnsEndpoint)
79
+		if err != nil {
80
+			return err
81
+		}
82
+
83
+		// Temp: We have to create a endpoint object to keep track of the HNS ID for
84
+		// this endpoint so that we can retrieve it later when the endpoint is deleted.
85
+		// This seems unnecessary when we already have dockers EID. See if we can pass
86
+		// the global EID to HNS to use as it's ID, rather than having each HNS assign
87
+		// it's own local ID for the endpoint
88
+
89
+		addr, err := types.ParseCIDR(peerIP.String() + "/32")
90
+		if err != nil {
91
+			return err
92
+		}
93
+
94
+		n.removeEndpointWithAddress(addr)
95
+
96
+		hnsresponse, err := hcsshim.HNSEndpointRequest("POST", "", string(configurationb))
97
+		if err != nil {
98
+			return err
99
+		}
100
+
101
+		ep := &endpoint{
102
+			id:        eid,
103
+			nid:       nid,
104
+			addr:      addr,
105
+			mac:       peerMac,
106
+			profileId: hnsresponse.Id,
107
+			remote:    true,
108
+		}
109
+
110
+		n.addEndpoint(ep)
111
+
112
+		if err := d.writeEndpointToStore(ep); err != nil {
113
+			return fmt.Errorf("failed to update overlay endpoint %s to local store: %v", ep.id[0:7], err)
114
+		}
115
+	}
116
+
117
+	return nil
118
+}
119
+
120
+func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
121
+	peerMac net.HardwareAddr, vtep net.IP, updateDb bool) error {
122
+
123
+	logrus.Infof("WINOVERLAY: Enter peerDelete for endpoint %s and peer ip %s", eid, peerIP.String())
124
+
125
+	if err := validateID(nid, eid); err != nil {
126
+		return err
127
+	}
128
+
129
+	n := d.network(nid)
130
+	if n == nil {
131
+		return nil
132
+	}
133
+
134
+	ep := n.endpoint(eid)
135
+	if ep == nil {
136
+		return fmt.Errorf("could not find endpoint with id %s", eid)
137
+	}
138
+
139
+	if updateDb {
140
+		_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileId, "")
141
+		if err != nil {
142
+			return err
143
+		}
144
+
145
+		n.deleteEndpoint(eid)
146
+
147
+		if err := d.deleteEndpointFromStore(ep); err != nil {
148
+			logrus.Debugf("Failed to delete stale overlay endpoint (%s) from store", ep.id[0:7])
149
+		}
150
+	}
151
+
152
+	return nil
153
+}
... ...
@@ -20,7 +20,7 @@ import (
20 20
 	"sync"
21 21
 
22 22
 	"github.com/Microsoft/hcsshim"
23
-	log "github.com/Sirupsen/logrus"
23
+	"github.com/Sirupsen/logrus"
24 24
 	"github.com/docker/libnetwork/datastore"
25 25
 	"github.com/docker/libnetwork/discoverapi"
26 26
 	"github.com/docker/libnetwork/driverapi"
... ...
@@ -44,21 +44,28 @@ type networkConfiguration struct {
44 44
 }
45 45
 
46 46
 // endpointConfiguration represents the user specified configuration for the sandbox endpoint
47
-type endpointConfiguration struct {
48
-	MacAddress   net.HardwareAddr
47
+type endpointOption struct {
48
+	MacAddress  net.HardwareAddr
49
+	QosPolicies []types.QosPolicy
50
+	DNSServers  []string
51
+	DisableDNS  bool
52
+	DisableICC  bool
53
+}
54
+
55
+type endpointConnectivity struct {
49 56
 	PortBindings []types.PortBinding
50 57
 	ExposedPorts []types.TransportPort
51
-	QosPolicies  []types.QosPolicy
52
-	DNSServers   []string
53 58
 }
54 59
 
55 60
 type hnsEndpoint struct {
56
-	id          string
57
-	profileID   string
58
-	macAddress  net.HardwareAddr
59
-	config      *endpointConfiguration // User specified parameters
60
-	portMapping []types.PortBinding    // Operation port bindings
61
-	addr        *net.IPNet
61
+	id             string
62
+	profileID      string
63
+	macAddress     net.HardwareAddr
64
+	epOption       *endpointOption       // User specified parameters
65
+	epConnectivity *endpointConnectivity // User specified parameters
66
+	portMapping    []types.PortBinding   // Operation port bindings
67
+	addr           *net.IPNet
68
+	gateway        net.IP
62 69
 }
63 70
 
64 71
 type hnsNetwork struct {
... ...
@@ -75,7 +82,8 @@ type driver struct {
75 75
 	sync.Mutex
76 76
 }
77 77
 
78
-func isValidNetworkType(networkType string) bool {
78
+// IsBuiltinWindowsDriver vaidates if network-type is a builtin local-scoped driver
79
+func IsBuiltinLocalDriver(networkType string) bool {
79 80
 	if "l2bridge" == networkType || "l2tunnel" == networkType || "nat" == networkType || "ics" == networkType || "transparent" == networkType {
80 81
 		return true
81 82
 	}
... ...
@@ -91,7 +99,7 @@ func newDriver(networkType string) *driver {
91 91
 // GetInit returns an initializer for the given network type
92 92
 func GetInit(networkType string) func(dc driverapi.DriverCallback, config map[string]interface{}) error {
93 93
 	return func(dc driverapi.DriverCallback, config map[string]interface{}) error {
94
-		if !isValidNetworkType(networkType) {
94
+		if !IsBuiltinLocalDriver(networkType) {
95 95
 			return types.BadRequestErrorf("Network type not supported: %s", networkType)
96 96
 		}
97 97
 
... ...
@@ -270,7 +278,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
270 270
 		}
271 271
 
272 272
 		configuration := string(configurationb)
273
-		log.Debugf("HNSNetwork Request =%v Address Space=%v", configuration, subnets)
273
+		logrus.Debugf("HNSNetwork Request =%v Address Space=%v", configuration, subnets)
274 274
 
275 275
 		hnsresponse, err := hcsshim.HNSNetworkRequest("POST", "", configuration)
276 276
 		if err != nil {
... ...
@@ -390,12 +398,12 @@ func parsePortBindingPolicies(policies []json.RawMessage) ([]types.PortBinding,
390 390
 	return bindings, nil
391 391
 }
392 392
 
393
-func parseEndpointOptions(epOptions map[string]interface{}) (*endpointConfiguration, error) {
393
+func parseEndpointOptions(epOptions map[string]interface{}) (*endpointOption, error) {
394 394
 	if epOptions == nil {
395 395
 		return nil, nil
396 396
 	}
397 397
 
398
-	ec := &endpointConfiguration{}
398
+	ec := &endpointOption{}
399 399
 
400 400
 	if opt, ok := epOptions[netlabel.MacAddress]; ok {
401 401
 		if mac, ok := opt.(net.HardwareAddr); ok {
... ...
@@ -405,33 +413,33 @@ func parseEndpointOptions(epOptions map[string]interface{}) (*endpointConfigurat
405 405
 		}
406 406
 	}
407 407
 
408
-	if opt, ok := epOptions[netlabel.PortMap]; ok {
409
-		if bs, ok := opt.([]types.PortBinding); ok {
410
-			ec.PortBindings = bs
408
+	if opt, ok := epOptions[QosPolicies]; ok {
409
+		if policies, ok := opt.([]types.QosPolicy); ok {
410
+			ec.QosPolicies = policies
411 411
 		} else {
412 412
 			return nil, fmt.Errorf("Invalid endpoint configuration")
413 413
 		}
414 414
 	}
415 415
 
416
-	if opt, ok := epOptions[netlabel.ExposedPorts]; ok {
417
-		if ports, ok := opt.([]types.TransportPort); ok {
418
-			ec.ExposedPorts = ports
416
+	if opt, ok := epOptions[netlabel.DNSServers]; ok {
417
+		if dns, ok := opt.([]string); ok {
418
+			ec.DNSServers = dns
419 419
 		} else {
420 420
 			return nil, fmt.Errorf("Invalid endpoint configuration")
421 421
 		}
422 422
 	}
423 423
 
424
-	if opt, ok := epOptions[QosPolicies]; ok {
425
-		if policies, ok := opt.([]types.QosPolicy); ok {
426
-			ec.QosPolicies = policies
424
+	if opt, ok := epOptions[DisableICC]; ok {
425
+		if disableICC, ok := opt.(bool); ok {
426
+			ec.DisableICC = disableICC
427 427
 		} else {
428 428
 			return nil, fmt.Errorf("Invalid endpoint configuration")
429 429
 		}
430 430
 	}
431 431
 
432
-	if opt, ok := epOptions[netlabel.DNSServers]; ok {
433
-		if dns, ok := opt.([]string); ok {
434
-			ec.DNSServers = dns
432
+	if opt, ok := epOptions[DisableDNS]; ok {
433
+		if disableDNS, ok := opt.(bool); ok {
434
+			ec.DisableDNS = disableDNS
435 435
 		} else {
436 436
 			return nil, fmt.Errorf("Invalid endpoint configuration")
437 437
 		}
... ...
@@ -440,6 +448,31 @@ func parseEndpointOptions(epOptions map[string]interface{}) (*endpointConfigurat
440 440
 	return ec, nil
441 441
 }
442 442
 
443
+func parseEndpointConnectivity(epOptions map[string]interface{}) (*endpointConnectivity, error) {
444
+	if epOptions == nil {
445
+		return nil, nil
446
+	}
447
+
448
+	ec := &endpointConnectivity{}
449
+
450
+	if opt, ok := epOptions[netlabel.PortMap]; ok {
451
+		if bs, ok := opt.([]types.PortBinding); ok {
452
+			ec.PortBindings = bs
453
+		} else {
454
+			return nil, fmt.Errorf("Invalid endpoint configuration")
455
+		}
456
+	}
457
+
458
+	if opt, ok := epOptions[netlabel.ExposedPorts]; ok {
459
+		if ports, ok := opt.([]types.TransportPort); ok {
460
+			ec.ExposedPorts = ports
461
+		} else {
462
+			return nil, fmt.Errorf("Invalid endpoint configuration")
463
+		}
464
+	}
465
+	return ec, nil
466
+}
467
+
443 468
 func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
444 469
 	n, err := d.getNetwork(nid)
445 470
 	if err != nil {
... ...
@@ -456,7 +489,8 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
456 456
 		VirtualNetwork: n.config.HnsID,
457 457
 	}
458 458
 
459
-	ec, err := parseEndpointOptions(epOptions)
459
+	epOption, err := parseEndpointOptions(epOptions)
460
+	epConnectivity, err := parseEndpointConnectivity(epOptions)
460 461
 
461 462
 	macAddress := ifInfo.MacAddress()
462 463
 	// Use the macaddress if it was provided
... ...
@@ -464,12 +498,12 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
464 464
 		endpointStruct.MacAddress = strings.Replace(macAddress.String(), ":", "-", -1)
465 465
 	}
466 466
 
467
-	endpointStruct.Policies, err = convertPortBindings(ec.PortBindings)
467
+	endpointStruct.Policies, err = convertPortBindings(epConnectivity.PortBindings)
468 468
 	if err != nil {
469 469
 		return err
470 470
 	}
471 471
 
472
-	qosPolicies, err := convertQosPolicies(ec.QosPolicies)
472
+	qosPolicies, err := convertQosPolicies(epOption.QosPolicies)
473 473
 	if err != nil {
474 474
 		return err
475 475
 	}
... ...
@@ -479,12 +513,14 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
479 479
 		endpointStruct.IPAddress = ifInfo.Address().IP
480 480
 	}
481 481
 
482
-	endpointStruct.DNSServerList = strings.Join(ec.DNSServers, ",")
482
+	endpointStruct.DNSServerList = strings.Join(epOption.DNSServers, ",")
483 483
 
484
-	if n.driver.name == "nat" {
484
+	if n.driver.name == "nat" && !epOption.DisableDNS {
485 485
 		endpointStruct.EnableInternalDNS = true
486 486
 	}
487 487
 
488
+	endpointStruct.DisableICC = epOption.DisableICC
489
+
488 490
 	configurationb, err := json.Marshal(endpointStruct)
489 491
 	if err != nil {
490 492
 		return err
... ...
@@ -507,8 +543,13 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
507 507
 		macAddress: mac,
508 508
 	}
509 509
 
510
+	if hnsresponse.GatewayAddress != "" {
511
+		endpoint.gateway = net.ParseIP(hnsresponse.GatewayAddress)
512
+	}
513
+
510 514
 	endpoint.profileID = hnsresponse.Id
511
-	endpoint.config = ec
515
+	endpoint.epConnectivity = epConnectivity
516
+	endpoint.epOption = epOption
512 517
 	endpoint.portMapping, err = parsePortBindingPolicies(hnsresponse.Policies)
513 518
 
514 519
 	if err != nil {
... ...
@@ -571,10 +612,10 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro
571 571
 	}
572 572
 
573 573
 	data["hnsid"] = ep.profileID
574
-	if ep.config.ExposedPorts != nil {
574
+	if ep.epConnectivity.ExposedPorts != nil {
575 575
 		// Return a copy of the config data
576
-		epc := make([]types.TransportPort, 0, len(ep.config.ExposedPorts))
577
-		for _, tp := range ep.config.ExposedPorts {
576
+		epc := make([]types.TransportPort, 0, len(ep.epConnectivity.ExposedPorts))
577
+		for _, tp := range ep.epConnectivity.ExposedPorts {
578 578
 			epc = append(epc, tp.GetCopy())
579 579
 		}
580 580
 		data[netlabel.ExposedPorts] = epc
... ...
@@ -603,7 +644,12 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
603 603
 	}
604 604
 
605 605
 	// Ensure that the endpoint exists
606
-	_, err = network.getEndpoint(eid)
606
+	endpoint, err := network.getEndpoint(eid)
607
+	if err != nil {
608
+		return err
609
+	}
610
+
611
+	err = jinfo.SetGateway(endpoint.gateway)
607 612
 	if err != nil {
608 613
 		return err
609 614
 	}
... ...
@@ -3,10 +3,12 @@ package libnetwork
3 3
 import (
4 4
 	"github.com/docker/libnetwork/drivers/null"
5 5
 	"github.com/docker/libnetwork/drivers/solaris/bridge"
6
+	"github.com/docker/libnetwork/drivers/solaris/overlay"
6 7
 )
7 8
 
8 9
 func getInitializers() []initializer {
9 10
 	return []initializer{
11
+		{overlay.Init, "overlay"},
10 12
 		{bridge.Init, "bridge"},
11 13
 		{null.Init, "null"},
12 14
 	}
... ...
@@ -2,12 +2,16 @@ package libnetwork
2 2
 
3 3
 import (
4 4
 	"github.com/docker/libnetwork/drivers/null"
5
+	"github.com/docker/libnetwork/drivers/remote"
5 6
 	"github.com/docker/libnetwork/drivers/windows"
7
+	"github.com/docker/libnetwork/drivers/windows/overlay"
6 8
 )
7 9
 
8 10
 func getInitializers() []initializer {
9 11
 	return []initializer{
10 12
 		{null.Init, "null"},
13
+		{overlay.Init, "overlay"},
14
+		{remote.Init, "remote"},
11 15
 		{windows.GetInit("transparent"), "transparent"},
12 16
 		{windows.GetInit("l2bridge"), "l2bridge"},
13 17
 		{windows.GetInit("l2tunnel"), "l2tunnel"},
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"strings"
9 9
 	"sync"
10 10
 
11
-	log "github.com/Sirupsen/logrus"
11
+	"github.com/Sirupsen/logrus"
12 12
 	"github.com/docker/libnetwork/datastore"
13 13
 	"github.com/docker/libnetwork/ipamapi"
14 14
 	"github.com/docker/libnetwork/netlabel"
... ...
@@ -142,12 +142,12 @@ func (ep *endpoint) UnmarshalJSON(b []byte) (err error) {
142 142
 
143 143
 				bytes, err := json.Marshal(tmp)
144 144
 				if err != nil {
145
-					log.Error(err)
145
+					logrus.Error(err)
146 146
 					break
147 147
 				}
148 148
 				err = json.Unmarshal(bytes, &pb)
149 149
 				if err != nil {
150
-					log.Error(err)
150
+					logrus.Error(err)
151 151
 					break
152 152
 				}
153 153
 				pblist = append(pblist, pb)
... ...
@@ -164,12 +164,12 @@ func (ep *endpoint) UnmarshalJSON(b []byte) (err error) {
164 164
 
165 165
 				bytes, err := json.Marshal(tmp)
166 166
 				if err != nil {
167
-					log.Error(err)
167
+					logrus.Error(err)
168 168
 					break
169 169
 				}
170 170
 				err = json.Unmarshal(bytes, &tp)
171 171
 				if err != nil {
172
-					log.Error(err)
172
+					logrus.Error(err)
173 173
 					break
174 174
 				}
175 175
 				tplist = append(tplist, tp)
... ...
@@ -472,7 +472,7 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error {
472 472
 	defer func() {
473 473
 		if err != nil {
474 474
 			if err := d.Leave(nid, epid); err != nil {
475
-				log.Warnf("driver leave failed while rolling back join: %v", err)
475
+				logrus.Warnf("driver leave failed while rolling back join: %v", err)
476 476
 			}
477 477
 		}
478 478
 	}()
... ...
@@ -495,10 +495,6 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error {
495 495
 		return err
496 496
 	}
497 497
 
498
-	if err = n.getController().updateToStore(ep); err != nil {
499
-		return err
500
-	}
501
-
502 498
 	// Current endpoint providing external connectivity for the sandbox
503 499
 	extEp := sb.getGatewayEndpoint()
504 500
 
... ...
@@ -515,6 +511,10 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error {
515 515
 		return err
516 516
 	}
517 517
 
518
+	if err = n.getController().updateToStore(ep); err != nil {
519
+		return err
520
+	}
521
+
518 522
 	if sb.needDefaultGW() && sb.getEndpointInGWNetwork() == nil {
519 523
 		return sb.setupDefaultGW()
520 524
 	}
... ...
@@ -523,7 +523,7 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error {
523 523
 
524 524
 	if moveExtConn {
525 525
 		if extEp != nil {
526
-			log.Debugf("Revoking external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID())
526
+			logrus.Debugf("Revoking external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID())
527 527
 			extN, err := extEp.getNetworkFromStore()
528 528
 			if err != nil {
529 529
 				return fmt.Errorf("failed to get network from store during join: %v", err)
... ...
@@ -540,14 +540,14 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error {
540 540
 			defer func() {
541 541
 				if err != nil {
542 542
 					if e := extD.ProgramExternalConnectivity(extEp.network.ID(), extEp.ID(), sb.Labels()); e != nil {
543
-						log.Warnf("Failed to roll-back external connectivity on endpoint %s (%s): %v",
543
+						logrus.Warnf("Failed to roll-back external connectivity on endpoint %s (%s): %v",
544 544
 							extEp.Name(), extEp.ID(), e)
545 545
 					}
546 546
 				}
547 547
 			}()
548 548
 		}
549 549
 		if !n.internal {
550
-			log.Debugf("Programming external connectivity on endpoint %s (%s)", ep.Name(), ep.ID())
550
+			logrus.Debugf("Programming external connectivity on endpoint %s (%s)", ep.Name(), ep.ID())
551 551
 			if err = d.ProgramExternalConnectivity(n.ID(), ep.ID(), sb.Labels()); err != nil {
552 552
 				return types.InternalErrorf(
553 553
 					"driver failed programming external connectivity on endpoint %s (%s): %v",
... ...
@@ -559,7 +559,7 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error {
559 559
 
560 560
 	if !sb.needDefaultGW() {
561 561
 		if err := sb.clearDefaultGW(); err != nil {
562
-			log.Warnf("Failure while disconnecting sandbox %s (%s) from gateway network: %v",
562
+			logrus.Warnf("Failure while disconnecting sandbox %s (%s) from gateway network: %v",
563 563
 				sb.ID(), sb.ContainerID(), err)
564 564
 		}
565 565
 	}
... ...
@@ -682,22 +682,22 @@ func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption)
682 682
 
683 683
 	if d != nil {
684 684
 		if moveExtConn {
685
-			log.Debugf("Revoking external connectivity on endpoint %s (%s)", ep.Name(), ep.ID())
685
+			logrus.Debugf("Revoking external connectivity on endpoint %s (%s)", ep.Name(), ep.ID())
686 686
 			if err := d.RevokeExternalConnectivity(n.id, ep.id); err != nil {
687
-				log.Warnf("driver failed revoking external connectivity on endpoint %s (%s): %v",
687
+				logrus.Warnf("driver failed revoking external connectivity on endpoint %s (%s): %v",
688 688
 					ep.Name(), ep.ID(), err)
689 689
 			}
690 690
 		}
691 691
 
692 692
 		if err := d.Leave(n.id, ep.id); err != nil {
693 693
 			if _, ok := err.(types.MaskableError); !ok {
694
-				log.Warnf("driver error disconnecting container %s : %v", ep.name, err)
694
+				logrus.Warnf("driver error disconnecting container %s : %v", ep.name, err)
695 695
 			}
696 696
 		}
697 697
 	}
698 698
 
699 699
 	if err := sb.clearNetworkResources(ep); err != nil {
700
-		log.Warnf("Could not cleanup network resources on container %s disconnect: %v", ep.name, err)
700
+		logrus.Warnf("Could not cleanup network resources on container %s disconnect: %v", ep.name, err)
701 701
 	}
702 702
 
703 703
 	// Update the store about the sandbox detach only after we
... ...
@@ -710,7 +710,7 @@ func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption)
710 710
 	}
711 711
 
712 712
 	if e := ep.deleteFromCluster(); e != nil {
713
-		log.Errorf("Could not delete state for endpoint %s from cluster: %v", ep.Name(), e)
713
+		logrus.Errorf("Could not delete state for endpoint %s from cluster: %v", ep.Name(), e)
714 714
 	}
715 715
 
716 716
 	sb.deleteHostsEntries(n.getSvcRecords(ep))
... ...
@@ -721,7 +721,7 @@ func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption)
721 721
 	// New endpoint providing external connectivity for the sandbox
722 722
 	extEp = sb.getGatewayEndpoint()
723 723
 	if moveExtConn && extEp != nil {
724
-		log.Debugf("Programming external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID())
724
+		logrus.Debugf("Programming external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID())
725 725
 		extN, err := extEp.getNetworkFromStore()
726 726
 		if err != nil {
727 727
 			return fmt.Errorf("failed to get network from store during leave: %v", err)
... ...
@@ -731,14 +731,14 @@ func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption)
731 731
 			return fmt.Errorf("failed to leave endpoint: %v", err)
732 732
 		}
733 733
 		if err := extD.ProgramExternalConnectivity(extEp.network.ID(), extEp.ID(), sb.Labels()); err != nil {
734
-			log.Warnf("driver failed programming external connectivity on endpoint %s: (%s) %v",
734
+			logrus.Warnf("driver failed programming external connectivity on endpoint %s: (%s) %v",
735 735
 				extEp.Name(), extEp.ID(), err)
736 736
 		}
737 737
 	}
738 738
 
739 739
 	if !sb.needDefaultGW() {
740 740
 		if err := sb.clearDefaultGW(); err != nil {
741
-			log.Warnf("Failure while disconnecting sandbox %s (%s) from gateway network: %v",
741
+			logrus.Warnf("Failure while disconnecting sandbox %s (%s) from gateway network: %v",
742 742
 				sb.ID(), sb.ContainerID(), err)
743 743
 		}
744 744
 	}
... ...
@@ -771,7 +771,7 @@ func (ep *endpoint) Delete(force bool) error {
771 771
 
772 772
 	if sb != nil {
773 773
 		if e := ep.sbLeave(sb.(*sandbox), force); e != nil {
774
-			log.Warnf("failed to leave sandbox for endpoint %s : %v", name, e)
774
+			logrus.Warnf("failed to leave sandbox for endpoint %s : %v", name, e)
775 775
 		}
776 776
 	}
777 777
 
... ...
@@ -783,7 +783,7 @@ func (ep *endpoint) Delete(force bool) error {
783 783
 		if err != nil && !force {
784 784
 			ep.dbExists = false
785 785
 			if e := n.getController().updateToStore(ep); e != nil {
786
-				log.Warnf("failed to recreate endpoint in store %s : %v", name, e)
786
+				logrus.Warnf("failed to recreate endpoint in store %s : %v", name, e)
787 787
 			}
788 788
 		}
789 789
 	}()
... ...
@@ -798,7 +798,7 @@ func (ep *endpoint) Delete(force bool) error {
798 798
 	ep.releaseAddress()
799 799
 
800 800
 	if err := n.getEpCnt().DecEndpointCnt(); err != nil {
801
-		log.Warnf("failed to decrement endpoint count for ep %s: %v", ep.ID(), err)
801
+		logrus.Warnf("failed to decrement endpoint count for ep %s: %v", ep.ID(), err)
802 802
 	}
803 803
 
804 804
 	return nil
... ...
@@ -826,7 +826,7 @@ func (ep *endpoint) deleteEndpoint(force bool) error {
826 826
 		}
827 827
 
828 828
 		if _, ok := err.(types.MaskableError); !ok {
829
-			log.Warnf("driver error deleting endpoint %s : %v", name, err)
829
+			logrus.Warnf("driver error deleting endpoint %s : %v", name, err)
830 830
 		}
831 831
 	}
832 832
 
... ...
@@ -976,7 +976,7 @@ func JoinOptionPriority(ep Endpoint, prio int) EndpointOption {
976 976
 		sb, ok := c.sandboxes[ep.sandboxID]
977 977
 		c.Unlock()
978 978
 		if !ok {
979
-			log.Errorf("Could not set endpoint priority value during Join to endpoint %s: No sandbox id present in endpoint", ep.id)
979
+			logrus.Errorf("Could not set endpoint priority value during Join to endpoint %s: No sandbox id present in endpoint", ep.id)
980 980
 			return
981 981
 		}
982 982
 		sb.epPriority[ep.id] = prio
... ...
@@ -995,7 +995,7 @@ func (ep *endpoint) assignAddress(ipam ipamapi.Ipam, assignIPv4, assignIPv6 bool
995 995
 		return nil
996 996
 	}
997 997
 
998
-	log.Debugf("Assigning addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
998
+	logrus.Debugf("Assigning addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
999 999
 
1000 1000
 	if assignIPv4 {
1001 1001
 		if err = ep.assignAddressVersion(4, ipam); err != nil {
... ...
@@ -1075,23 +1075,23 @@ func (ep *endpoint) releaseAddress() {
1075 1075
 		return
1076 1076
 	}
1077 1077
 
1078
-	log.Debugf("Releasing addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
1078
+	logrus.Debugf("Releasing addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
1079 1079
 
1080 1080
 	ipam, _, err := n.getController().getIPAMDriver(n.ipamType)
1081 1081
 	if err != nil {
1082
-		log.Warnf("Failed to retrieve ipam driver to release interface address on delete of endpoint %s (%s): %v", ep.Name(), ep.ID(), err)
1082
+		logrus.Warnf("Failed to retrieve ipam driver to release interface address on delete of endpoint %s (%s): %v", ep.Name(), ep.ID(), err)
1083 1083
 		return
1084 1084
 	}
1085 1085
 
1086 1086
 	if ep.iface.addr != nil {
1087 1087
 		if err := ipam.ReleaseAddress(ep.iface.v4PoolID, ep.iface.addr.IP); err != nil {
1088
-			log.Warnf("Failed to release ip address %s on delete of endpoint %s (%s): %v", ep.iface.addr.IP, ep.Name(), ep.ID(), err)
1088
+			logrus.Warnf("Failed to release ip address %s on delete of endpoint %s (%s): %v", ep.iface.addr.IP, ep.Name(), ep.ID(), err)
1089 1089
 		}
1090 1090
 	}
1091 1091
 
1092 1092
 	if ep.iface.addrv6 != nil && ep.iface.addrv6.IP.IsGlobalUnicast() {
1093 1093
 		if err := ipam.ReleaseAddress(ep.iface.v6PoolID, ep.iface.addrv6.IP); err != nil {
1094
-			log.Warnf("Failed to release ip address %s on delete of endpoint %s (%s): %v", ep.iface.addrv6.IP, ep.Name(), ep.ID(), err)
1094
+			logrus.Warnf("Failed to release ip address %s on delete of endpoint %s (%s): %v", ep.iface.addrv6.IP, ep.Name(), ep.ID(), err)
1095 1095
 		}
1096 1096
 	}
1097 1097
 }
... ...
@@ -1106,14 +1106,14 @@ func (c *controller) cleanupLocalEndpoints() {
1106 1106
 	}
1107 1107
 	nl, err := c.getNetworksForScope(datastore.LocalScope)
1108 1108
 	if err != nil {
1109
-		log.Warnf("Could not get list of networks during endpoint cleanup: %v", err)
1109
+		logrus.Warnf("Could not get list of networks during endpoint cleanup: %v", err)
1110 1110
 		return
1111 1111
 	}
1112 1112
 
1113 1113
 	for _, n := range nl {
1114 1114
 		epl, err := n.getEndpointsFromStore()
1115 1115
 		if err != nil {
1116
-			log.Warnf("Could not get list of endpoints in network %s during endpoint cleanup: %v", n.name, err)
1116
+			logrus.Warnf("Could not get list of endpoints in network %s during endpoint cleanup: %v", n.name, err)
1117 1117
 			continue
1118 1118
 		}
1119 1119
 
... ...
@@ -1121,21 +1121,21 @@ func (c *controller) cleanupLocalEndpoints() {
1121 1121
 			if _, ok := eps[ep.id]; ok {
1122 1122
 				continue
1123 1123
 			}
1124
-			log.Infof("Removing stale endpoint %s (%s)", ep.name, ep.id)
1124
+			logrus.Infof("Removing stale endpoint %s (%s)", ep.name, ep.id)
1125 1125
 			if err := ep.Delete(true); err != nil {
1126
-				log.Warnf("Could not delete local endpoint %s during endpoint cleanup: %v", ep.name, err)
1126
+				logrus.Warnf("Could not delete local endpoint %s during endpoint cleanup: %v", ep.name, err)
1127 1127
 			}
1128 1128
 		}
1129 1129
 
1130 1130
 		epl, err = n.getEndpointsFromStore()
1131 1131
 		if err != nil {
1132
-			log.Warnf("Could not get list of endpoints in network %s for count update: %v", n.name, err)
1132
+			logrus.Warnf("Could not get list of endpoints in network %s for count update: %v", n.name, err)
1133 1133
 			continue
1134 1134
 		}
1135 1135
 
1136 1136
 		epCnt := n.getEpCnt().EndpointCnt()
1137 1137
 		if epCnt != uint64(len(epl)) {
1138
-			log.Infof("Fixing inconsistent endpoint_cnt for network %s. Expected=%d, Actual=%d", n.name, len(epl), epCnt)
1138
+			logrus.Infof("Fixing inconsistent endpoint_cnt for network %s. Expected=%d, Actual=%d", n.name, len(epl), epCnt)
1139 1139
 			n.getEpCnt().setCnt(uint64(len(epl)))
1140 1140
 		}
1141 1141
 	}
... ...
@@ -205,31 +205,6 @@ func (ep *endpoint) Info() EndpointInfo {
205 205
 	return nil
206 206
 }
207 207
 
208
-func (ep *endpoint) DriverInfo() (map[string]interface{}, error) {
209
-	ep, err := ep.retrieveFromStore()
210
-	if err != nil {
211
-		return nil, err
212
-	}
213
-
214
-	if sb, ok := ep.getSandbox(); ok {
215
-		if gwep := sb.getEndpointInGWNetwork(); gwep != nil && gwep.ID() != ep.ID() {
216
-			return gwep.DriverInfo()
217
-		}
218
-	}
219
-
220
-	n, err := ep.getNetworkFromStore()
221
-	if err != nil {
222
-		return nil, fmt.Errorf("could not find network in store for driver info: %v", err)
223
-	}
224
-
225
-	driver, err := n.driver(true)
226
-	if err != nil {
227
-		return nil, fmt.Errorf("failed to get driver info: %v", err)
228
-	}
229
-
230
-	return driver.EndpointOperInfo(n.ID(), ep.ID())
231
-}
232
-
233 208
 func (ep *endpoint) Iface() InterfaceInfo {
234 209
 	ep.Lock()
235 210
 	defer ep.Unlock()
236 211
new file mode 100644
... ...
@@ -0,0 +1,30 @@
0
+// +build !windows
1
+
2
+package libnetwork
3
+
4
+import "fmt"
5
+
6
+func (ep *endpoint) DriverInfo() (map[string]interface{}, error) {
7
+	ep, err := ep.retrieveFromStore()
8
+	if err != nil {
9
+		return nil, err
10
+	}
11
+
12
+	if sb, ok := ep.getSandbox(); ok {
13
+		if gwep := sb.getEndpointInGWNetwork(); gwep != nil && gwep.ID() != ep.ID() {
14
+			return gwep.DriverInfo()
15
+		}
16
+	}
17
+
18
+	n, err := ep.getNetworkFromStore()
19
+	if err != nil {
20
+		return nil, fmt.Errorf("could not find network in store for driver info: %v", err)
21
+	}
22
+
23
+	driver, err := n.driver(true)
24
+	if err != nil {
25
+		return nil, fmt.Errorf("failed to get driver info: %v", err)
26
+	}
27
+
28
+	return driver.EndpointOperInfo(n.ID(), ep.ID())
29
+}
0 30
new file mode 100644
... ...
@@ -0,0 +1,45 @@
0
+// +build windows
1
+
2
+package libnetwork
3
+
4
+import "fmt"
5
+
6
+func (ep *endpoint) DriverInfo() (map[string]interface{}, error) {
7
+	ep, err := ep.retrieveFromStore()
8
+	if err != nil {
9
+		return nil, err
10
+	}
11
+
12
+	var gwDriverInfo map[string]interface{}
13
+	if sb, ok := ep.getSandbox(); ok {
14
+		if gwep := sb.getEndpointInGWNetwork(); gwep != nil && gwep.ID() != ep.ID() {
15
+
16
+			gwDriverInfo, err = gwep.DriverInfo()
17
+			if err != nil {
18
+				return nil, err
19
+			}
20
+		}
21
+	}
22
+
23
+	n, err := ep.getNetworkFromStore()
24
+	if err != nil {
25
+		return nil, fmt.Errorf("could not find network in store for driver info: %v", err)
26
+	}
27
+
28
+	driver, err := n.driver(true)
29
+	if err != nil {
30
+		return nil, fmt.Errorf("failed to get driver info: %v", err)
31
+	}
32
+
33
+	epInfo, err := driver.EndpointOperInfo(n.ID(), ep.ID())
34
+	if err != nil {
35
+		return nil, err
36
+	}
37
+
38
+	if epInfo != nil {
39
+		epInfo["GW_INFO"] = gwDriverInfo
40
+		return epInfo, nil
41
+	}
42
+
43
+	return gwDriverInfo, nil
44
+}
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"net"
5 5
 	"sync"
6 6
 
7
-	log "github.com/Sirupsen/logrus"
7
+	"github.com/Sirupsen/logrus"
8 8
 
9 9
 	mapset "github.com/deckarep/golang-set"
10 10
 	"github.com/docker/docker/pkg/discovery"
... ...
@@ -54,7 +54,7 @@ func (h *hostDiscovery) monitorDiscovery(ch <-chan discovery.Entries, errCh <-ch
54 54
 			h.processCallback(entries, activeCallback, joinCallback, leaveCallback)
55 55
 		case err := <-errCh:
56 56
 			if err != nil {
57
-				log.Errorf("discovery error: %v", err)
57
+				logrus.Errorf("discovery error: %v", err)
58 58
 			}
59 59
 		case <-h.stopChan:
60 60
 			return
... ...
@@ -54,6 +54,19 @@ func (i *Idm) GetSpecificID(id uint64) error {
54 54
 	return i.handle.Set(id - i.start)
55 55
 }
56 56
 
57
+// GetIDInRange returns the first available id in the set within a range
58
+func (i *Idm) GetIDInRange(start, end uint64) (uint64, error) {
59
+	if i.handle == nil {
60
+		return 0, fmt.Errorf("ID set is not initialized")
61
+	}
62
+
63
+	if start < i.start || end > i.end {
64
+		return 0, fmt.Errorf("Requested range does not belong to the set")
65
+	}
66
+
67
+	return i.handle.SetAnyInRange(start, end-start)
68
+}
69
+
57 70
 // Release releases the specified id
58 71
 func (i *Idm) Release(id uint64) {
59 72
 	i.handle.Unset(id - i.start)
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"sort"
7 7
 	"sync"
8 8
 
9
-	log "github.com/Sirupsen/logrus"
9
+	"github.com/Sirupsen/logrus"
10 10
 	"github.com/docker/libnetwork/bitseq"
11 11
 	"github.com/docker/libnetwork/datastore"
12 12
 	"github.com/docker/libnetwork/discoverapi"
... ...
@@ -135,7 +135,7 @@ func (a *Allocator) checkConsistency(as string) {
135 135
 		bm := a.addresses[sk]
136 136
 		a.Unlock()
137 137
 		if err := bm.CheckConsistency(); err != nil {
138
-			log.Warnf("Error while running consistency check for %s: %v", sk, err)
138
+			logrus.Warnf("Error while running consistency check for %s: %v", sk, err)
139 139
 		}
140 140
 	}
141 141
 }
... ...
@@ -198,7 +198,7 @@ func (a *Allocator) GetDefaultAddressSpaces() (string, string, error) {
198 198
 
199 199
 // RequestPool returns an address pool along with its unique id.
200 200
 func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
201
-	log.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6)
201
+	logrus.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6)
202 202
 
203 203
 	k, nw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6)
204 204
 	if err != nil {
... ...
@@ -227,7 +227,7 @@ retry:
227 227
 	insert, err := aSpace.updatePoolDBOnAdd(*k, nw, ipr, pdf)
228 228
 	if err != nil {
229 229
 		if _, ok := err.(types.MaskableError); ok {
230
-			log.Debugf("Retrying predefined pool search: %v", err)
230
+			logrus.Debugf("Retrying predefined pool search: %v", err)
231 231
 			goto retry
232 232
 		}
233 233
 		return "", nil, nil, err
... ...
@@ -246,7 +246,7 @@ retry:
246 246
 
247 247
 // ReleasePool releases the address pool identified by the passed id
248 248
 func (a *Allocator) ReleasePool(poolID string) error {
249
-	log.Debugf("ReleasePool(%s)", poolID)
249
+	logrus.Debugf("ReleasePool(%s)", poolID)
250 250
 	k := SubnetKey{}
251 251
 	if err := k.FromString(poolID); err != nil {
252 252
 		return types.BadRequestErrorf("invalid pool id: %s", poolID)
... ...
@@ -322,7 +322,7 @@ func (a *Allocator) parsePoolRequest(addressSpace, pool, subPool string, v6 bool
322 322
 }
323 323
 
324 324
 func (a *Allocator) insertBitMask(key SubnetKey, pool *net.IPNet) error {
325
-	//log.Debugf("Inserting bitmask (%s, %s)", key.String(), pool.String())
325
+	//logrus.Debugf("Inserting bitmask (%s, %s)", key.String(), pool.String())
326 326
 
327 327
 	store := a.getStore(key.AddressSpace)
328 328
 	ipVer := getAddressVersion(pool.IP)
... ...
@@ -360,7 +360,7 @@ func (a *Allocator) retrieveBitmask(k SubnetKey, n *net.IPNet) (*bitseq.Handle,
360 360
 	bm, ok := a.addresses[k]
361 361
 	a.Unlock()
362 362
 	if !ok {
363
-		log.Debugf("Retrieving bitmask (%s, %s)", k.String(), n.String())
363
+		logrus.Debugf("Retrieving bitmask (%s, %s)", k.String(), n.String())
364 364
 		if err := a.insertBitMask(k, n); err != nil {
365 365
 			return nil, types.InternalErrorf("could not find bitmask in datastore for %s", k.String())
366 366
 		}
... ...
@@ -418,7 +418,7 @@ func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error)
418 418
 
419 419
 // RequestAddress returns an address from the specified pool ID
420 420
 func (a *Allocator) RequestAddress(poolID string, prefAddress net.IP, opts map[string]string) (*net.IPNet, map[string]string, error) {
421
-	log.Debugf("RequestAddress(%s, %v, %v)", poolID, prefAddress, opts)
421
+	logrus.Debugf("RequestAddress(%s, %v, %v)", poolID, prefAddress, opts)
422 422
 	k := SubnetKey{}
423 423
 	if err := k.FromString(poolID); err != nil {
424 424
 		return nil, nil, types.BadRequestErrorf("invalid pool id: %s", poolID)
... ...
@@ -467,7 +467,7 @@ func (a *Allocator) RequestAddress(poolID string, prefAddress net.IP, opts map[s
467 467
 
468 468
 // ReleaseAddress releases the address from the specified pool ID
469 469
 func (a *Allocator) ReleaseAddress(poolID string, address net.IP) error {
470
-	log.Debugf("ReleaseAddress(%s, %v)", poolID, address)
470
+	logrus.Debugf("ReleaseAddress(%s, %v)", poolID, address)
471 471
 	k := SubnetKey{}
472 472
 	if err := k.FromString(poolID); err != nil {
473 473
 		return types.BadRequestErrorf("invalid pool id: %s", poolID)
... ...
@@ -3,7 +3,7 @@ package ipam
3 3
 import (
4 4
 	"encoding/json"
5 5
 
6
-	log "github.com/Sirupsen/logrus"
6
+	"github.com/Sirupsen/logrus"
7 7
 	"github.com/docker/libnetwork/datastore"
8 8
 	"github.com/docker/libnetwork/types"
9 9
 )
... ...
@@ -26,7 +26,7 @@ func (aSpace *addrSpace) KeyPrefix() []string {
26 26
 func (aSpace *addrSpace) Value() []byte {
27 27
 	b, err := json.Marshal(aSpace)
28 28
 	if err != nil {
29
-		log.Warnf("Failed to marshal ipam configured pools: %v", err)
29
+		logrus.Warnf("Failed to marshal ipam configured pools: %v", err)
30 30
 		return nil
31 31
 	}
32 32
 	return b
... ...
@@ -3,14 +3,55 @@
3 3
 package builtin
4 4
 
5 5
 import (
6
+	"fmt"
7
+
8
+	"github.com/docker/libnetwork/datastore"
9
+	"github.com/docker/libnetwork/ipam"
6 10
 	"github.com/docker/libnetwork/ipamapi"
11
+	"github.com/docker/libnetwork/ipamutils"
7 12
 
8 13
 	windowsipam "github.com/docker/libnetwork/ipams/windowsipam"
9 14
 )
10 15
 
16
+// InitDockerDefault registers the built-in ipam service with libnetwork
17
+func InitDockerDefault(ic ipamapi.Callback, l, g interface{}) error {
18
+	var (
19
+		ok                bool
20
+		localDs, globalDs datastore.DataStore
21
+	)
22
+
23
+	if l != nil {
24
+		if localDs, ok = l.(datastore.DataStore); !ok {
25
+			return fmt.Errorf("incorrect local datastore passed to built-in ipam init")
26
+		}
27
+	}
28
+
29
+	if g != nil {
30
+		if globalDs, ok = g.(datastore.DataStore); !ok {
31
+			return fmt.Errorf("incorrect global datastore passed to built-in ipam init")
32
+		}
33
+	}
34
+
35
+	ipamutils.InitNetworks()
36
+
37
+	a, err := ipam.NewAllocator(localDs, globalDs)
38
+	if err != nil {
39
+		return err
40
+	}
41
+
42
+	cps := &ipamapi.Capability{RequiresRequestReplay: true}
43
+
44
+	return ic.RegisterIpamDriverWithCapabilities(ipamapi.DefaultIPAM, a, cps)
45
+}
46
+
11 47
 // Init registers the built-in ipam service with libnetwork
12 48
 func Init(ic ipamapi.Callback, l, g interface{}) error {
13
-	initFunc := windowsipam.GetInit(ipamapi.DefaultIPAM)
49
+	initFunc := windowsipam.GetInit(windowsipam.DefaultIPAM)
50
+
51
+	err := InitDockerDefault(ic, l, g)
52
+	if err != nil {
53
+		return err
54
+	}
14 55
 
15 56
 	return initFunc(ic, l, g)
16 57
 }
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"fmt"
5 5
 	"net"
6 6
 
7
-	log "github.com/Sirupsen/logrus"
7
+	"github.com/Sirupsen/logrus"
8 8
 	"github.com/docker/docker/pkg/plugins"
9 9
 	"github.com/docker/libnetwork/discoverapi"
10 10
 	"github.com/docker/libnetwork/ipamapi"
... ...
@@ -40,13 +40,13 @@ func Init(cb ipamapi.Callback, l, g interface{}) error {
40 40
 		a := newAllocator(name, client)
41 41
 		if cps, err := a.(*allocator).getCapabilities(); err == nil {
42 42
 			if err := cb.RegisterIpamDriverWithCapabilities(name, a, cps); err != nil {
43
-				log.Errorf("error registering remote ipam driver %s due to %v", name, err)
43
+				logrus.Errorf("error registering remote ipam driver %s due to %v", name, err)
44 44
 			}
45 45
 		} else {
46
-			log.Infof("remote ipam driver %s does not support capabilities", name)
47
-			log.Debug(err)
46
+			logrus.Infof("remote ipam driver %s does not support capabilities", name)
47
+			logrus.Debug(err)
48 48
 			if err := cb.RegisterIpamDriver(name, a); err != nil {
49
-				log.Errorf("error registering remote ipam driver %s due to %v", name, err)
49
+				logrus.Errorf("error registering remote ipam driver %s due to %v", name, err)
50 50
 			}
51 51
 		}
52 52
 	})
... ...
@@ -3,7 +3,7 @@ package windowsipam
3 3
 import (
4 4
 	"net"
5 5
 
6
-	log "github.com/Sirupsen/logrus"
6
+	"github.com/Sirupsen/logrus"
7 7
 	"github.com/docker/libnetwork/discoverapi"
8 8
 	"github.com/docker/libnetwork/ipamapi"
9 9
 	"github.com/docker/libnetwork/netlabel"
... ...
@@ -15,6 +15,9 @@ const (
15 15
 	globalAddressSpace = "GlobalDefault"
16 16
 )
17 17
 
18
+// DefaultIPAM defines the default ipam-driver for local-scoped windows networks
19
+const DefaultIPAM = "windows"
20
+
18 21
 var (
19 22
 	defaultPool, _ = types.ParseCIDR("0.0.0.0/0")
20 23
 )
... ...
@@ -36,7 +39,7 @@ func (a *allocator) GetDefaultAddressSpaces() (string, string, error) {
36 36
 // RequestPool returns an address pool along with its unique id. This is a null ipam driver. It allocates the
37 37
 // subnet user asked and does not validate anything. Doesn't support subpool allocation
38 38
 func (a *allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
39
-	log.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6)
39
+	logrus.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6)
40 40
 	if subPool != "" || v6 {
41 41
 		return "", nil, nil, types.InternalErrorf("This request is not supported by null ipam driver")
42 42
 	}
... ...
@@ -58,14 +61,14 @@ func (a *allocator) RequestPool(addressSpace, pool, subPool string, options map[
58 58
 
59 59
 // ReleasePool releases the address pool - always succeeds
60 60
 func (a *allocator) ReleasePool(poolID string) error {
61
-	log.Debugf("ReleasePool(%s)", poolID)
61
+	logrus.Debugf("ReleasePool(%s)", poolID)
62 62
 	return nil
63 63
 }
64 64
 
65 65
 // RequestAddress returns an address from the specified pool ID.
66 66
 // Always allocate the 0.0.0.0/32 ip if no preferred address was specified
67 67
 func (a *allocator) RequestAddress(poolID string, prefAddress net.IP, opts map[string]string) (*net.IPNet, map[string]string, error) {
68
-	log.Debugf("RequestAddress(%s, %v, %v)", poolID, prefAddress, opts)
68
+	logrus.Debugf("RequestAddress(%s, %v, %v)", poolID, prefAddress, opts)
69 69
 	_, ipNet, err := net.ParseCIDR(poolID)
70 70
 
71 71
 	if err != nil {
... ...
@@ -85,7 +88,7 @@ func (a *allocator) RequestAddress(poolID string, prefAddress net.IP, opts map[s
85 85
 
86 86
 // ReleaseAddress releases the address - always succeeds
87 87
 func (a *allocator) ReleaseAddress(poolID string, address net.IP) error {
88
-	log.Debugf("ReleaseAddress(%s, %v)", poolID, address)
88
+	logrus.Debugf("ReleaseAddress(%s, %v)", poolID, address)
89 89
 	return nil
90 90
 }
91 91
 
... ...
@@ -64,7 +64,7 @@ func setup() {
64 64
 
65 65
 		ipvsFamily, err = getIPVSFamily()
66 66
 		if err != nil {
67
-			logrus.Errorf("Could not get ipvs family information from the kernel. It is possible that ipvs is not enabled in your kernel. Native loadbalancing will not work until this is fixed.")
67
+			logrus.Error("Could not get ipvs family information from the kernel. It is possible that ipvs is not enabled in your kernel. Native loadbalancing will not work until this is fixed.")
68 68
 		}
69 69
 	})
70 70
 }
... ...
@@ -18,6 +18,8 @@ func ElectInterfaceAddresses(name string) ([]*net.IPNet, []*net.IPNet, error) {
18 18
 
19 19
 // FindAvailableNetwork returns a network from the passed list which does not
20 20
 // overlap with existing interfaces in the system
21
+
22
+// TODO : Use appropriate windows APIs to identify non-overlapping subnets
21 23
 func FindAvailableNetwork(list []*net.IPNet) (*net.IPNet, error) {
22
-	return nil, types.NotImplementedErrorf("not supported on windows")
24
+	return nil, nil
23 25
 }
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"sync"
9 9
 	"time"
10 10
 
11
-	log "github.com/Sirupsen/logrus"
11
+	"github.com/Sirupsen/logrus"
12 12
 	"github.com/docker/docker/pkg/stringid"
13 13
 	"github.com/docker/libnetwork/config"
14 14
 	"github.com/docker/libnetwork/datastore"
... ...
@@ -473,7 +473,7 @@ func (n *network) UnmarshalJSON(b []byte) (err error) {
473 473
 	if v, ok := netMap["created"]; ok {
474 474
 		// n.created is time.Time but marshalled as string
475 475
 		if err = n.created.UnmarshalText([]byte(v.(string))); err != nil {
476
-			log.Warnf("failed to unmarshal creation time %v: %v", v, err)
476
+			logrus.Warnf("failed to unmarshal creation time %v: %v", v, err)
477 477
 			n.created = time.Time{}
478 478
 		}
479 479
 	}
... ...
@@ -633,6 +633,9 @@ func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ip
633 633
 	return func(n *network) {
634 634
 		if ipamDriver != "" {
635 635
 			n.ipamType = ipamDriver
636
+			if ipamDriver == ipamapi.DefaultIPAM {
637
+				n.ipamType = defaultIpamForNetworkType(n.Type())
638
+			}
636 639
 		}
637 640
 		n.ipamOptions = opts
638 641
 		n.addrSpace = addrSpace
... ...
@@ -776,12 +779,12 @@ func (n *network) delete(force bool) error {
776 776
 		if !force {
777 777
 			return err
778 778
 		}
779
-		log.Debugf("driver failed to delete stale network %s (%s): %v", n.Name(), n.ID(), err)
779
+		logrus.Debugf("driver failed to delete stale network %s (%s): %v", n.Name(), n.ID(), err)
780 780
 	}
781 781
 
782 782
 	n.ipamRelease()
783 783
 	if err = c.updateToStore(n); err != nil {
784
-		log.Warnf("Failed to update store after ipam release for network %s (%s): %v", n.Name(), n.ID(), err)
784
+		logrus.Warnf("Failed to update store after ipam release for network %s (%s): %v", n.Name(), n.ID(), err)
785 785
 	}
786 786
 
787 787
 	// We are about to delete the network. Leave the gossip
... ...
@@ -792,7 +795,7 @@ func (n *network) delete(force bool) error {
792 792
 	// bindings cleanup requires the network in the store.
793 793
 	n.cancelDriverWatches()
794 794
 	if err = n.leaveCluster(); err != nil {
795
-		log.Errorf("Failed leaving network %s from the agent cluster: %v", n.Name(), err)
795
+		logrus.Errorf("Failed leaving network %s from the agent cluster: %v", n.Name(), err)
796 796
 	}
797 797
 
798 798
 	c.cleanupServiceBindings(n.ID())
... ...
@@ -804,7 +807,7 @@ func (n *network) delete(force bool) error {
804 804
 		if !force {
805 805
 			return fmt.Errorf("error deleting network endpoint count from store: %v", err)
806 806
 		}
807
-		log.Debugf("Error deleting endpoint count from store for stale network %s (%s) for deletion: %v", n.Name(), n.ID(), err)
807
+		logrus.Debugf("Error deleting endpoint count from store for stale network %s (%s) for deletion: %v", n.Name(), n.ID(), err)
808 808
 	}
809 809
 
810 810
 	if err = c.deleteFromStore(n); err != nil {
... ...
@@ -827,7 +830,7 @@ func (n *network) deleteNetwork() error {
827 827
 		}
828 828
 
829 829
 		if _, ok := err.(types.MaskableError); !ok {
830
-			log.Warnf("driver error deleting network %s : %v", n.name, err)
830
+			logrus.Warnf("driver error deleting network %s : %v", n.name, err)
831 831
 		}
832 832
 	}
833 833
 
... ...
@@ -920,7 +923,7 @@ func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoi
920 920
 	defer func() {
921 921
 		if err != nil {
922 922
 			if e := ep.deleteEndpoint(false); e != nil {
923
-				log.Warnf("cleaning up endpoint failed %s : %v", name, e)
923
+				logrus.Warnf("cleaning up endpoint failed %s : %v", name, e)
924 924
 			}
925 925
 		}
926 926
 	}()
... ...
@@ -935,7 +938,7 @@ func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoi
935 935
 	defer func() {
936 936
 		if err != nil {
937 937
 			if e := n.getController().deleteFromStore(ep); e != nil {
938
-				log.Warnf("error rolling back endpoint %s from store: %v", name, e)
938
+				logrus.Warnf("error rolling back endpoint %s from store: %v", name, e)
939 939
 			}
940 940
 		}
941 941
 	}()
... ...
@@ -961,7 +964,7 @@ func (n *network) Endpoints() []Endpoint {
961 961
 
962 962
 	endpoints, err := n.getEndpointsFromStore()
963 963
 	if err != nil {
964
-		log.Error(err)
964
+		logrus.Error(err)
965 965
 	}
966 966
 
967 967
 	for _, ep := range endpoints {
... ...
@@ -1169,7 +1172,7 @@ func (n *network) getSvcRecords(ep *endpoint) []etchosts.Record {
1169 1169
 			continue
1170 1170
 		}
1171 1171
 		if len(ip) == 0 {
1172
-			log.Warnf("Found empty list of IP addresses for service %s on network %s (%s)", h, n.name, n.id)
1172
+			logrus.Warnf("Found empty list of IP addresses for service %s on network %s (%s)", h, n.name, n.id)
1173 1173
 			continue
1174 1174
 		}
1175 1175
 		recs = append(recs, etchosts.Record{
... ...
@@ -1253,7 +1256,7 @@ func (n *network) requestPoolHelper(ipam ipamapi.Ipam, addressSpace, preferredPo
1253 1253
 		// pools.
1254 1254
 		defer func() {
1255 1255
 			if err := ipam.ReleasePool(poolID); err != nil {
1256
-				log.Warnf("Failed to release overlapping pool %s while returning from pool request helper for network %s", pool, n.Name())
1256
+				logrus.Warnf("Failed to release overlapping pool %s while returning from pool request helper for network %s", pool, n.Name())
1257 1257
 			}
1258 1258
 		}()
1259 1259
 
... ...
@@ -1294,7 +1297,7 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error {
1294 1294
 
1295 1295
 	*infoList = make([]*IpamInfo, len(*cfgList))
1296 1296
 
1297
-	log.Debugf("Allocating IPv%d pools for network %s (%s)", ipVer, n.Name(), n.ID())
1297
+	logrus.Debugf("Allocating IPv%d pools for network %s (%s)", ipVer, n.Name(), n.ID())
1298 1298
 
1299 1299
 	for i, cfg := range *cfgList {
1300 1300
 		if err = cfg.Validate(); err != nil {
... ...
@@ -1312,7 +1315,7 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error {
1312 1312
 		defer func() {
1313 1313
 			if err != nil {
1314 1314
 				if err := ipam.ReleasePool(d.PoolID); err != nil {
1315
-					log.Warnf("Failed to release address pool %s after failure to create network %s (%s)", d.PoolID, n.Name(), n.ID())
1315
+					logrus.Warnf("Failed to release address pool %s after failure to create network %s (%s)", d.PoolID, n.Name(), n.ID())
1316 1316
 				}
1317 1317
 			}
1318 1318
 		}()
... ...
@@ -1364,7 +1367,7 @@ func (n *network) ipamRelease() {
1364 1364
 	}
1365 1365
 	ipam, _, err := n.getController().getIPAMDriver(n.ipamType)
1366 1366
 	if err != nil {
1367
-		log.Warnf("Failed to retrieve ipam driver to release address pool(s) on delete of network %s (%s): %v", n.Name(), n.ID(), err)
1367
+		logrus.Warnf("Failed to retrieve ipam driver to release address pool(s) on delete of network %s (%s): %v", n.Name(), n.ID(), err)
1368 1368
 		return
1369 1369
 	}
1370 1370
 	n.ipamReleaseVersion(4, ipam)
... ...
@@ -1380,7 +1383,7 @@ func (n *network) ipamReleaseVersion(ipVer int, ipam ipamapi.Ipam) {
1380 1380
 	case 6:
1381 1381
 		infoList = &n.ipamV6Info
1382 1382
 	default:
1383
-		log.Warnf("incorrect ip version passed to ipam release: %d", ipVer)
1383
+		logrus.Warnf("incorrect ip version passed to ipam release: %d", ipVer)
1384 1384
 		return
1385 1385
 	}
1386 1386
 
... ...
@@ -1388,25 +1391,25 @@ func (n *network) ipamReleaseVersion(ipVer int, ipam ipamapi.Ipam) {
1388 1388
 		return
1389 1389
 	}
1390 1390
 
1391
-	log.Debugf("releasing IPv%d pools from network %s (%s)", ipVer, n.Name(), n.ID())
1391
+	logrus.Debugf("releasing IPv%d pools from network %s (%s)", ipVer, n.Name(), n.ID())
1392 1392
 
1393 1393
 	for _, d := range *infoList {
1394 1394
 		if d.Gateway != nil {
1395 1395
 			if err := ipam.ReleaseAddress(d.PoolID, d.Gateway.IP); err != nil {
1396
-				log.Warnf("Failed to release gateway ip address %s on delete of network %s (%s): %v", d.Gateway.IP, n.Name(), n.ID(), err)
1396
+				logrus.Warnf("Failed to release gateway ip address %s on delete of network %s (%s): %v", d.Gateway.IP, n.Name(), n.ID(), err)
1397 1397
 			}
1398 1398
 		}
1399 1399
 		if d.IPAMData.AuxAddresses != nil {
1400 1400
 			for k, nw := range d.IPAMData.AuxAddresses {
1401 1401
 				if d.Pool.Contains(nw.IP) {
1402 1402
 					if err := ipam.ReleaseAddress(d.PoolID, nw.IP); err != nil && err != ipamapi.ErrIPOutOfRange {
1403
-						log.Warnf("Failed to release secondary ip address %s (%v) on delete of network %s (%s): %v", k, nw.IP, n.Name(), n.ID(), err)
1403
+						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)
1404 1404
 					}
1405 1405
 				}
1406 1406
 			}
1407 1407
 		}
1408 1408
 		if err := ipam.ReleasePool(d.PoolID); err != nil {
1409
-			log.Warnf("Failed to release address pool %s on delete of network %s (%s): %v", d.PoolID, n.Name(), n.ID(), err)
1409
+			logrus.Warnf("Failed to release address pool %s on delete of network %s (%s): %v", d.PoolID, n.Name(), n.ID(), err)
1410 1410
 		}
1411 1411
 	}
1412 1412
 
... ...
@@ -1658,7 +1661,7 @@ func (n *network) ResolveService(name string) ([]*net.SRV, []net.IP) {
1658 1658
 	srv := []*net.SRV{}
1659 1659
 	ip := []net.IP{}
1660 1660
 
1661
-	log.Debugf("Service name To resolve: %v", name)
1661
+	logrus.Debugf("Service name To resolve: %v", name)
1662 1662
 
1663 1663
 	// There are DNS implementaions that allow SRV queries for names not in
1664 1664
 	// the format defined by RFC 2782. Hence specific validations checks are
... ...
@@ -2,7 +2,13 @@
2 2
 
3 3
 package libnetwork
4 4
 
5
+import "github.com/docker/libnetwork/ipamapi"
6
+
5 7
 // Stub implementations for DNS related functions
6 8
 
7 9
 func (n *network) startResolver() {
8 10
 }
11
+
12
+func defaultIpamForNetworkType(networkType string) string {
13
+	return ipamapi.DefaultIPAM
14
+}
... ...
@@ -4,17 +4,20 @@ package libnetwork
4 4
 
5 5
 import (
6 6
 	"runtime"
7
+	"time"
7 8
 
8 9
 	"github.com/Microsoft/hcsshim"
9
-	log "github.com/Sirupsen/logrus"
10
+	"github.com/Sirupsen/logrus"
10 11
 	"github.com/docker/libnetwork/drivers/windows"
12
+	"github.com/docker/libnetwork/ipamapi"
13
+	"github.com/docker/libnetwork/ipams/windowsipam"
11 14
 )
12 15
 
13 16
 func executeInCompartment(compartmentID uint32, x func()) {
14 17
 	runtime.LockOSThread()
15 18
 
16 19
 	if err := hcsshim.SetCurrentThreadCompartmentId(compartmentID); err != nil {
17
-		log.Error(err)
20
+		logrus.Error(err)
18 21
 	}
19 22
 	defer func() {
20 23
 		hcsshim.SetCurrentThreadCompartmentId(0)
... ...
@@ -26,7 +29,7 @@ func executeInCompartment(compartmentID uint32, x func()) {
26 26
 
27 27
 func (n *network) startResolver() {
28 28
 	n.resolverOnce.Do(func() {
29
-		log.Debugf("Launching DNS server for network", n.Name())
29
+		logrus.Debugf("Launching DNS server for network", n.Name())
30 30
 		options := n.Info().DriverOptions()
31 31
 		hnsid := options[windows.HNSID]
32 32
 
... ...
@@ -36,21 +39,34 @@ func (n *network) startResolver() {
36 36
 
37 37
 		hnsresponse, err := hcsshim.HNSNetworkRequest("GET", hnsid, "")
38 38
 		if err != nil {
39
-			log.Errorf("Resolver Setup/Start failed for container %s, %q", n.Name(), err)
39
+			logrus.Errorf("Resolver Setup/Start failed for container %s, %q", n.Name(), err)
40 40
 			return
41 41
 		}
42 42
 
43 43
 		for _, subnet := range hnsresponse.Subnets {
44 44
 			if subnet.GatewayAddress != "" {
45
-				resolver := NewResolver(subnet.GatewayAddress, false, "", n)
46
-				log.Debugf("Binding a resolver on network %s gateway %s", n.Name(), subnet.GatewayAddress)
47
-				executeInCompartment(hnsresponse.DNSServerCompartment, resolver.SetupFunc(53))
48
-				if err = resolver.Start(); err != nil {
49
-					log.Errorf("Resolver Setup/Start failed for container %s, %q", n.Name(), err)
50
-				} else {
51
-					n.resolver = append(n.resolver, resolver)
45
+				for i := 0; i < 3; i++ {
46
+					resolver := NewResolver(subnet.GatewayAddress, false, "", n)
47
+					logrus.Debugf("Binding a resolver on network %s gateway %s", n.Name(), subnet.GatewayAddress)
48
+					executeInCompartment(hnsresponse.DNSServerCompartment, resolver.SetupFunc(53))
49
+
50
+					if err = resolver.Start(); err != nil {
51
+						logrus.Errorf("Resolver Setup/Start failed for container %s, %q", n.Name(), err)
52
+						time.Sleep(1 * time.Second)
53
+					} else {
54
+						logrus.Debugf("Resolver bound successfuly for network %s", n.Name())
55
+						n.resolver = append(n.resolver, resolver)
56
+						break
57
+					}
52 58
 				}
53 59
 			}
54 60
 		}
55 61
 	})
56 62
 }
63
+
64
+func defaultIpamForNetworkType(networkType string) string {
65
+	if windows.IsBuiltinLocalDriver(networkType) {
66
+		return windowsipam.DefaultIPAM
67
+	}
68
+	return ipamapi.DefaultIPAM
69
+}
... ...
@@ -139,7 +139,6 @@ func (nDB *NetworkDB) clusterInit() error {
139 139
 
140 140
 	nDB.stopCh = make(chan struct{})
141 141
 	nDB.memberlist = mlist
142
-	nDB.mConfig = config
143 142
 
144 143
 	for _, trigger := range []struct {
145 144
 		interval time.Duration
... ...
@@ -242,7 +241,7 @@ func (nDB *NetworkDB) reapDeadNode() {
242 242
 	defer nDB.Unlock()
243 243
 	for id, n := range nDB.failedNodes {
244 244
 		if n.reapTime > 0 {
245
-			n.reapTime -= reapPeriod
245
+			n.reapTime -= nodeReapPeriod
246 246
 			continue
247 247
 		}
248 248
 		logrus.Debugf("Removing failed node %v from gossip cluster", n.Name)
... ...
@@ -29,10 +29,6 @@ type NetworkDB struct {
29 29
 	// NetworkDB configuration.
30 30
 	config *Config
31 31
 
32
-	// local copy of memberlist config that we use to driver
33
-	// network scoped gossip and bulk sync.
34
-	mConfig *memberlist.Config
35
-
36 32
 	// All the tree index (byTable, byNetwork) that we maintain
37 33
 	// the db.
38 34
 	indexes map[int]*radix.Tree
... ...
@@ -57,7 +53,6 @@ type NetworkDB struct {
57 57
 
58 58
 	// A map of nodes which are participating in a given
59 59
 	// network. The key is a network ID.
60
-
61 60
 	networkNodes map[string][]string
62 61
 
63 62
 	// A table of ack channels for every node from which we are
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"sync"
9 9
 	"syscall"
10 10
 
11
-	log "github.com/Sirupsen/logrus"
11
+	"github.com/Sirupsen/logrus"
12 12
 	"github.com/vishvananda/netlink"
13 13
 	"github.com/vishvananda/netns"
14 14
 )
... ...
@@ -24,11 +24,11 @@ func Init() {
24 24
 	var err error
25 25
 	initNs, err = netns.Get()
26 26
 	if err != nil {
27
-		log.Errorf("could not get initial namespace: %v", err)
27
+		logrus.Errorf("could not get initial namespace: %v", err)
28 28
 	}
29 29
 	initNl, err = netlink.NewHandle(getSupportedNlFamilies()...)
30 30
 	if err != nil {
31
-		log.Errorf("could not create netlink handle on initial namespace: %v", err)
31
+		logrus.Errorf("could not create netlink handle on initial namespace: %v", err)
32 32
 	}
33 33
 }
34 34
 
... ...
@@ -70,7 +70,7 @@ func getSupportedNlFamilies() []int {
70 70
 	fams := []int{syscall.NETLINK_ROUTE}
71 71
 	if err := loadXfrmModules(); err != nil {
72 72
 		if checkXfrmSocket() != nil {
73
-			log.Warnf("Could not load necessary modules for IPSEC rules: %v", err)
73
+			logrus.Warnf("Could not load necessary modules for IPSEC rules: %v", err)
74 74
 			return fams
75 75
 		}
76 76
 	}
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"syscall"
9 9
 	"time"
10 10
 
11
-	log "github.com/Sirupsen/logrus"
11
+	"github.com/Sirupsen/logrus"
12 12
 	"github.com/docker/libnetwork/ns"
13 13
 	"github.com/docker/libnetwork/types"
14 14
 	"github.com/vishvananda/netlink"
... ...
@@ -167,7 +167,7 @@ func (i *nwIface) Remove() error {
167 167
 
168 168
 	err = nlh.LinkSetName(iface, i.SrcName())
169 169
 	if err != nil {
170
-		log.Debugf("LinkSetName failed for interface %s: %v", i.SrcName(), err)
170
+		logrus.Debugf("LinkSetName failed for interface %s: %v", i.SrcName(), err)
171 171
 		return err
172 172
 	}
173 173
 
... ...
@@ -179,7 +179,7 @@ func (i *nwIface) Remove() error {
179 179
 	} else if !isDefault {
180 180
 		// Move the network interface to caller namespace.
181 181
 		if err := nlh.LinkSetNsFd(iface, ns.ParseHandlerInt()); err != nil {
182
-			log.Debugf("LinkSetNsPid failed for interface %s: %v", i.SrcName(), err)
182
+			logrus.Debugf("LinkSetNsPid failed for interface %s: %v", i.SrcName(), err)
183 183
 			return err
184 184
 		}
185 185
 	}
... ...
@@ -315,7 +315,7 @@ func (n *networkNamespace) AddInterface(srcName, dstPrefix string, options ...If
315 315
 	// Up the interface.
316 316
 	cnt := 0
317 317
 	for err = nlh.LinkSetUp(iface); err != nil && cnt < 3; cnt++ {
318
-		log.Debugf("retrying link setup because of: %v", err)
318
+		logrus.Debugf("retrying link setup because of: %v", err)
319 319
 		time.Sleep(10 * time.Millisecond)
320 320
 		err = nlh.LinkSetUp(iface)
321 321
 	}
... ...
@@ -377,7 +377,9 @@ func setInterfaceIP(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
377 377
 	if i.Address() == nil {
378 378
 		return nil
379 379
 	}
380
-
380
+	if err := checkRouteConflict(nlh, i.Address(), netlink.FAMILY_V4); err != nil {
381
+		return err
382
+	}
381 383
 	ipAddr := &netlink.Addr{IPNet: i.Address(), Label: ""}
382 384
 	return nlh.AddrAdd(iface, ipAddr)
383 385
 }
... ...
@@ -386,6 +388,9 @@ func setInterfaceIPv6(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error
386 386
 	if i.AddressIPv6() == nil {
387 387
 		return nil
388 388
 	}
389
+	if err := checkRouteConflict(nlh, i.AddressIPv6(), netlink.FAMILY_V6); err != nil {
390
+		return err
391
+	}
389 392
 	ipAddr := &netlink.Addr{IPNet: i.AddressIPv6(), Label: "", Flags: syscall.IFA_F_NODAD}
390 393
 	return nlh.AddrAdd(iface, ipAddr)
391 394
 }
... ...
@@ -442,3 +447,19 @@ func scanInterfaceStats(data, ifName string, i *types.InterfaceStatistics) error
442 442
 
443 443
 	return err
444 444
 }
445
+
446
+func checkRouteConflict(nlh *netlink.Handle, address *net.IPNet, family int) error {
447
+	routes, err := nlh.RouteList(nil, family)
448
+	if err != nil {
449
+		return err
450
+	}
451
+	for _, route := range routes {
452
+		if route.Dst != nil {
453
+			if route.Dst.Contains(address.IP) || address.Contains(route.Dst.IP) {
454
+				return fmt.Errorf("cannot program address %v in sandbox interface because it conflicts with existing route %s",
455
+					address, route)
456
+			}
457
+		}
458
+	}
459
+	return nil
460
+}
... ...
@@ -14,7 +14,7 @@ import (
14 14
 	"syscall"
15 15
 	"time"
16 16
 
17
-	log "github.com/Sirupsen/logrus"
17
+	"github.com/Sirupsen/logrus"
18 18
 	"github.com/docker/docker/pkg/reexec"
19 19
 	"github.com/docker/libnetwork/ns"
20 20
 	"github.com/docker/libnetwork/types"
... ...
@@ -263,10 +263,10 @@ func GetSandboxForExternalKey(basePath string, key string) (Sandbox, error) {
263 263
 
264 264
 func reexecCreateNamespace() {
265 265
 	if len(os.Args) < 2 {
266
-		log.Fatal("no namespace path provided")
266
+		logrus.Fatal("no namespace path provided")
267 267
 	}
268 268
 	if err := mountNetworkNamespace("/proc/self/ns/net", os.Args[1]); err != nil {
269
-		log.Fatal(err)
269
+		logrus.Fatal(err)
270 270
 	}
271 271
 }
272 272
 
... ...
@@ -338,7 +338,7 @@ func (n *networkNamespace) InvokeFunc(f func()) error {
338 338
 func InitOSContext() func() {
339 339
 	runtime.LockOSThread()
340 340
 	if err := ns.SetNamespace(); err != nil {
341
-		log.Error(err)
341
+		logrus.Error(err)
342 342
 	}
343 343
 	return runtime.UnlockOSThread
344 344
 }
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"sync"
9 9
 	"time"
10 10
 
11
-	log "github.com/Sirupsen/logrus"
11
+	"github.com/Sirupsen/logrus"
12 12
 	"github.com/docker/libnetwork/types"
13 13
 	"github.com/miekg/dns"
14 14
 )
... ...
@@ -219,7 +219,7 @@ func (r *resolver) handleIPQuery(name string, query *dns.Msg, ipType int) (*dns.
219 219
 
220 220
 	if addr == nil && ipv6Miss {
221 221
 		// Send a reply without any Answer sections
222
-		log.Debugf("Lookup name %s present without IPv6 address", name)
222
+		logrus.Debugf("Lookup name %s present without IPv6 address", name)
223 223
 		resp := createRespMsg(query)
224 224
 		return resp, nil
225 225
 	}
... ...
@@ -227,7 +227,7 @@ func (r *resolver) handleIPQuery(name string, query *dns.Msg, ipType int) (*dns.
227 227
 		return nil, nil
228 228
 	}
229 229
 
230
-	log.Debugf("Lookup for %s: IP %v", name, addr)
230
+	logrus.Debugf("Lookup for %s: IP %v", name, addr)
231 231
 
232 232
 	resp := createRespMsg(query)
233 233
 	if len(addr) > 1 {
... ...
@@ -268,7 +268,7 @@ func (r *resolver) handlePTRQuery(ptr string, query *dns.Msg) (*dns.Msg, error)
268 268
 		return nil, nil
269 269
 	}
270 270
 
271
-	log.Debugf("Lookup for IP %s: name %s", parts[0], host)
271
+	logrus.Debugf("Lookup for IP %s: name %s", parts[0], host)
272 272
 	fqdn := dns.Fqdn(host)
273 273
 
274 274
 	resp := new(dns.Msg)
... ...
@@ -352,7 +352,7 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
352 352
 	}
353 353
 
354 354
 	if err != nil {
355
-		log.Error(err)
355
+		logrus.Error(err)
356 356
 		return
357 357
 	}
358 358
 
... ...
@@ -411,10 +411,10 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
411 411
 
412 412
 			execErr := r.backend.ExecFunc(extConnect)
413 413
 			if execErr != nil || err != nil {
414
-				log.Debugf("Connect failed, %s", err)
414
+				logrus.Debugf("Connect failed, %s", err)
415 415
 				continue
416 416
 			}
417
-			log.Debugf("Query %s[%d] from %s, forwarding to %s:%s", name, query.Question[0].Qtype,
417
+			logrus.Debugf("Query %s[%d] from %s, forwarding to %s:%s", name, query.Question[0].Qtype,
418 418
 				extConn.LocalAddr().String(), proto, extDNS.ipStr)
419 419
 
420 420
 			// Timeout has to be set for every IO operation.
... ...
@@ -430,7 +430,7 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
430 430
 				old := r.tStamp
431 431
 				r.tStamp = time.Now()
432 432
 				if r.tStamp.Sub(old) > logInterval {
433
-					log.Errorf("More than %v concurrent queries from %s", maxConcurrent, extConn.LocalAddr().String())
433
+					logrus.Errorf("More than %v concurrent queries from %s", maxConcurrent, extConn.LocalAddr().String())
434 434
 				}
435 435
 				continue
436 436
 			}
... ...
@@ -438,7 +438,7 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
438 438
 			err = co.WriteMsg(query)
439 439
 			if err != nil {
440 440
 				r.forwardQueryEnd()
441
-				log.Debugf("Send to DNS server failed, %s", err)
441
+				logrus.Debugf("Send to DNS server failed, %s", err)
442 442
 				continue
443 443
 			}
444 444
 
... ...
@@ -447,7 +447,7 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
447 447
 			// client can retry over TCP
448 448
 			if err != nil && err != dns.ErrTruncated {
449 449
 				r.forwardQueryEnd()
450
-				log.Debugf("Read from DNS server failed, %s", err)
450
+				logrus.Debugf("Read from DNS server failed, %s", err)
451 451
 				continue
452 452
 			}
453 453
 
... ...
@@ -462,7 +462,7 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
462 462
 	}
463 463
 
464 464
 	if err = w.WriteMsg(resp); err != nil {
465
-		log.Errorf("error writing resolver resp, %s", err)
465
+		logrus.Errorf("error writing resolver resp, %s", err)
466 466
 	}
467 467
 }
468 468
 
... ...
@@ -483,7 +483,7 @@ func (r *resolver) forwardQueryEnd() {
483 483
 	defer r.queryLock.Unlock()
484 484
 
485 485
 	if r.count == 0 {
486
-		log.Errorf("Invalid concurrent query count")
486
+		logrus.Error("Invalid concurrent query count")
487 487
 	} else {
488 488
 		r.count--
489 489
 	}
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"os/exec"
10 10
 	"runtime"
11 11
 
12
-	log "github.com/Sirupsen/logrus"
12
+	"github.com/Sirupsen/logrus"
13 13
 	"github.com/docker/docker/pkg/reexec"
14 14
 	"github.com/docker/libnetwork/iptables"
15 15
 	"github.com/vishvananda/netns"
... ...
@@ -31,7 +31,7 @@ func reexecSetupResolver() {
31 31
 	defer runtime.UnlockOSThread()
32 32
 
33 33
 	if len(os.Args) < 4 {
34
-		log.Error("invalid number of arguments..")
34
+		logrus.Error("invalid number of arguments..")
35 35
 		os.Exit(1)
36 36
 	}
37 37
 
... ...
@@ -46,14 +46,14 @@ func reexecSetupResolver() {
46 46
 
47 47
 	f, err := os.OpenFile(os.Args[1], os.O_RDONLY, 0)
48 48
 	if err != nil {
49
-		log.Errorf("failed get network namespace %q: %v", os.Args[1], err)
49
+		logrus.Errorf("failed get network namespace %q: %v", os.Args[1], err)
50 50
 		os.Exit(2)
51 51
 	}
52 52
 	defer f.Close()
53 53
 
54 54
 	nsFD := f.Fd()
55 55
 	if err = netns.Set(netns.NsHandle(nsFD)); err != nil {
56
-		log.Errorf("setting into container net ns %v failed, %v", os.Args[1], err)
56
+		logrus.Errorf("setting into container net ns %v failed, %v", os.Args[1], err)
57 57
 		os.Exit(3)
58 58
 	}
59 59
 
... ...
@@ -76,7 +76,7 @@ func reexecSetupResolver() {
76 76
 
77 77
 	for _, rule := range rules {
78 78
 		if iptables.RawCombinedOutputNative(rule...) != nil {
79
-			log.Errorf("setting up rule failed, %v", rule)
79
+			logrus.Errorf("setting up rule failed, %v", rule)
80 80
 		}
81 81
 	}
82 82
 }
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"sync"
10 10
 	"time"
11 11
 
12
-	log "github.com/Sirupsen/logrus"
12
+	"github.com/Sirupsen/logrus"
13 13
 	"github.com/docker/libnetwork/etchosts"
14 14
 	"github.com/docker/libnetwork/netlabel"
15 15
 	"github.com/docker/libnetwork/osl"
... ...
@@ -213,18 +213,18 @@ func (sb *sandbox) delete(force bool) error {
213 213
 			if c.isDistributedControl() {
214 214
 				retain = true
215 215
 			}
216
-			log.Warnf("Failed getting network for ep %s during sandbox %s delete: %v", ep.ID(), sb.ID(), err)
216
+			logrus.Warnf("Failed getting network for ep %s during sandbox %s delete: %v", ep.ID(), sb.ID(), err)
217 217
 			continue
218 218
 		}
219 219
 
220 220
 		if !force {
221 221
 			if err := ep.Leave(sb); err != nil {
222
-				log.Warnf("Failed detaching sandbox %s from endpoint %s: %v\n", sb.ID(), ep.ID(), err)
222
+				logrus.Warnf("Failed detaching sandbox %s from endpoint %s: %v\n", sb.ID(), ep.ID(), err)
223 223
 			}
224 224
 		}
225 225
 
226 226
 		if err := ep.Delete(force); err != nil {
227
-			log.Warnf("Failed deleting endpoint %s: %v\n", ep.ID(), err)
227
+			logrus.Warnf("Failed deleting endpoint %s: %v\n", ep.ID(), err)
228 228
 		}
229 229
 	}
230 230
 
... ...
@@ -247,7 +247,7 @@ func (sb *sandbox) delete(force bool) error {
247 247
 	}
248 248
 
249 249
 	if err := sb.storeDelete(); err != nil {
250
-		log.Warnf("Failed to delete sandbox %s from store: %v", sb.ID(), err)
250
+		logrus.Warnf("Failed to delete sandbox %s from store: %v", sb.ID(), err)
251 251
 	}
252 252
 
253 253
 	c.Lock()
... ...
@@ -291,7 +291,7 @@ func (sb *sandbox) Refresh(options ...SandboxOption) error {
291 291
 	// Detach from all endpoints
292 292
 	for _, ep := range epList {
293 293
 		if err := ep.Leave(sb); err != nil {
294
-			log.Warnf("Failed detaching sandbox %s from endpoint %s: %v\n", sb.ID(), ep.ID(), err)
294
+			logrus.Warnf("Failed detaching sandbox %s from endpoint %s: %v\n", sb.ID(), ep.ID(), err)
295 295
 		}
296 296
 	}
297 297
 
... ...
@@ -307,7 +307,7 @@ func (sb *sandbox) Refresh(options ...SandboxOption) error {
307 307
 	// Re-connect to all endpoints
308 308
 	for _, ep := range epList {
309 309
 		if err := ep.Join(sb); err != nil {
310
-			log.Warnf("Failed attach sandbox %s to endpoint %s: %v\n", sb.ID(), ep.ID(), err)
310
+			logrus.Warnf("Failed attach sandbox %s to endpoint %s: %v\n", sb.ID(), ep.ID(), err)
311 311
 		}
312 312
 	}
313 313
 
... ...
@@ -413,7 +413,7 @@ func (sb *sandbox) updateGateway(ep *endpoint) error {
413 413
 
414 414
 func (sb *sandbox) ResolveIP(ip string) string {
415 415
 	var svc string
416
-	log.Debugf("IP To resolve %v", ip)
416
+	logrus.Debugf("IP To resolve %v", ip)
417 417
 
418 418
 	for _, ep := range sb.getConnectedEndpoints() {
419 419
 		n := ep.getNetwork()
... ...
@@ -434,7 +434,7 @@ func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
434 434
 	srv := []*net.SRV{}
435 435
 	ip := []net.IP{}
436 436
 
437
-	log.Debugf("Service name To resolve: %v", name)
437
+	logrus.Debugf("Service name To resolve: %v", name)
438 438
 
439 439
 	// There are DNS implementaions that allow SRV queries for names not in
440 440
 	// the format defined by RFC 2782. Hence specific validations checks are
... ...
@@ -497,7 +497,7 @@ func (sb *sandbox) ResolveName(name string, ipType int) ([]net.IP, bool) {
497 497
 	// {a.b in network c.d},
498 498
 	// {a in network b.c.d},
499 499
 
500
-	log.Debugf("Name To resolve: %v", name)
500
+	logrus.Debugf("Name To resolve: %v", name)
501 501
 	name = strings.TrimSuffix(name, ".")
502 502
 	reqName := []string{name}
503 503
 	networkName := []string{""}
... ...
@@ -605,7 +605,7 @@ func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoin
605 605
 func (sb *sandbox) SetKey(basePath string) error {
606 606
 	start := time.Now()
607 607
 	defer func() {
608
-		log.Debugf("sandbox set key processing took %s for container %s", time.Now().Sub(start), sb.ContainerID())
608
+		logrus.Debugf("sandbox set key processing took %s for container %s", time.Now().Sub(start), sb.ContainerID())
609 609
 	}()
610 610
 
611 611
 	if basePath == "" {
... ...
@@ -646,10 +646,10 @@ func (sb *sandbox) SetKey(basePath string) error {
646 646
 
647 647
 		if err := sb.osSbox.InvokeFunc(sb.resolver.SetupFunc(0)); err == nil {
648 648
 			if err := sb.resolver.Start(); err != nil {
649
-				log.Errorf("Resolver Start failed for container %s, %q", sb.ContainerID(), err)
649
+				logrus.Errorf("Resolver Start failed for container %s, %q", sb.ContainerID(), err)
650 650
 			}
651 651
 		} else {
652
-			log.Errorf("Resolver Setup Function failed for container %s, %q", sb.ContainerID(), err)
652
+			logrus.Errorf("Resolver Setup Function failed for container %s, %q", sb.ContainerID(), err)
653 653
 		}
654 654
 	}
655 655
 
... ...
@@ -690,7 +690,7 @@ func releaseOSSboxResources(osSbox osl.Sandbox, ep *endpoint) {
690 690
 		// Only remove the interfaces owned by this endpoint from the sandbox.
691 691
 		if ep.hasInterface(i.SrcName()) {
692 692
 			if err := i.Remove(); err != nil {
693
-				log.Debugf("Remove interface %s failed: %v", i.SrcName(), err)
693
+				logrus.Debugf("Remove interface %s failed: %v", i.SrcName(), err)
694 694
 			}
695 695
 		}
696 696
 	}
... ...
@@ -706,7 +706,7 @@ func releaseOSSboxResources(osSbox osl.Sandbox, ep *endpoint) {
706 706
 	// Remove non-interface routes.
707 707
 	for _, r := range joinInfo.StaticRoutes {
708 708
 		if err := osSbox.RemoveStaticRoute(r); err != nil {
709
-			log.Debugf("Remove route failed: %v", err)
709
+			logrus.Debugf("Remove route failed: %v", err)
710 710
 		}
711 711
 	}
712 712
 }
... ...
@@ -741,7 +741,7 @@ func (sb *sandbox) restoreOslSandbox() error {
741 741
 		ep.Unlock()
742 742
 
743 743
 		if i == nil {
744
-			log.Errorf("error restoring endpoint %s for container %s", ep.Name(), sb.ContainerID())
744
+			logrus.Errorf("error restoring endpoint %s for container %s", ep.Name(), sb.ContainerID())
745 745
 			continue
746 746
 		}
747 747
 
... ...
@@ -876,7 +876,7 @@ func (sb *sandbox) clearNetworkResources(origEp *endpoint) error {
876 876
 	if len(sb.endpoints) == 0 {
877 877
 		// sb.endpoints should never be empty and this is unexpected error condition
878 878
 		// We log an error message to note this down for debugging purposes.
879
-		log.Errorf("No endpoints in sandbox while trying to remove endpoint %s", ep.Name())
879
+		logrus.Errorf("No endpoints in sandbox while trying to remove endpoint %s", ep.Name())
880 880
 		sb.Unlock()
881 881
 		return nil
882 882
 	}
... ...
@@ -11,7 +11,7 @@ import (
11 11
 	"strconv"
12 12
 	"strings"
13 13
 
14
-	log "github.com/Sirupsen/logrus"
14
+	"github.com/Sirupsen/logrus"
15 15
 	"github.com/docker/libnetwork/etchosts"
16 16
 	"github.com/docker/libnetwork/resolvconf"
17 17
 	"github.com/docker/libnetwork/types"
... ...
@@ -40,19 +40,19 @@ func (sb *sandbox) startResolver(restore bool) {
40 40
 		if !restore {
41 41
 			err = sb.rebuildDNS()
42 42
 			if err != nil {
43
-				log.Errorf("Updating resolv.conf failed for container %s, %q", sb.ContainerID(), err)
43
+				logrus.Errorf("Updating resolv.conf failed for container %s, %q", sb.ContainerID(), err)
44 44
 				return
45 45
 			}
46 46
 		}
47 47
 		sb.resolver.SetExtServers(sb.extDNS)
48 48
 
49 49
 		if err = sb.osSbox.InvokeFunc(sb.resolver.SetupFunc(0)); err != nil {
50
-			log.Errorf("Resolver Setup function failed for container %s, %q", sb.ContainerID(), err)
50
+			logrus.Errorf("Resolver Setup function failed for container %s, %q", sb.ContainerID(), err)
51 51
 			return
52 52
 		}
53 53
 
54 54
 		if err = sb.resolver.Start(); err != nil {
55
-			log.Errorf("Resolver Start failed for container %s, %q", sb.ContainerID(), err)
55
+			logrus.Errorf("Resolver Start failed for container %s, %q", sb.ContainerID(), err)
56 56
 		}
57 57
 	})
58 58
 }
... ...
@@ -125,13 +125,13 @@ func (sb *sandbox) updateHostsFile(ifaceIP string) error {
125 125
 
126 126
 func (sb *sandbox) addHostsEntries(recs []etchosts.Record) {
127 127
 	if err := etchosts.Add(sb.config.hostsPath, recs); err != nil {
128
-		log.Warnf("Failed adding service host entries to the running container: %v", err)
128
+		logrus.Warnf("Failed adding service host entries to the running container: %v", err)
129 129
 	}
130 130
 }
131 131
 
132 132
 func (sb *sandbox) deleteHostsEntries(recs []etchosts.Record) {
133 133
 	if err := etchosts.Delete(sb.config.hostsPath, recs); err != nil {
134
-		log.Warnf("Failed deleting service host entries to the running container: %v", err)
134
+		logrus.Warnf("Failed deleting service host entries to the running container: %v", err)
135 135
 	}
136 136
 }
137 137
 
... ...
@@ -261,7 +261,7 @@ func (sb *sandbox) updateDNS(ipv6Enabled bool) error {
261 261
 	if currHash != "" && currHash != currRC.Hash {
262 262
 		// Seems the user has changed the container resolv.conf since the last time
263 263
 		// we checked so return without doing anything.
264
-		//log.Infof("Skipping update of resolv.conf file with ipv6Enabled: %t because file was touched by user", ipv6Enabled)
264
+		//logrus.Infof("Skipping update of resolv.conf file with ipv6Enabled: %t because file was touched by user", ipv6Enabled)
265 265
 		return nil
266 266
 	}
267 267
 
... ...
@@ -178,7 +178,7 @@ func (sb *sandbox) storeDelete() error {
178 178
 func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
179 179
 	store := c.getStore(datastore.LocalScope)
180 180
 	if store == nil {
181
-		logrus.Errorf("Could not find local scope store while trying to cleanup sandboxes")
181
+		logrus.Error("Could not find local scope store while trying to cleanup sandboxes")
182 182
 		return
183 183
 	}
184 184
 
185 185
new file mode 100644
... ...
@@ -0,0 +1,225 @@
0
+// +build linux windows
1
+
2
+package libnetwork
3
+
4
+import (
5
+	"net"
6
+
7
+	"github.com/Sirupsen/logrus"
8
+)
9
+
10
+func newService(name string, id string, ingressPorts []*PortConfig, aliases []string) *service {
11
+	return &service{
12
+		name:          name,
13
+		id:            id,
14
+		ingressPorts:  ingressPorts,
15
+		loadBalancers: make(map[string]*loadBalancer),
16
+		aliases:       aliases,
17
+	}
18
+}
19
+
20
+func (c *controller) cleanupServiceBindings(cleanupNID string) {
21
+	var cleanupFuncs []func()
22
+
23
+	c.Lock()
24
+	services := make([]*service, 0, len(c.serviceBindings))
25
+	for _, s := range c.serviceBindings {
26
+		services = append(services, s)
27
+	}
28
+	c.Unlock()
29
+
30
+	for _, s := range services {
31
+		s.Lock()
32
+		for nid, lb := range s.loadBalancers {
33
+			if cleanupNID != "" && nid != cleanupNID {
34
+				continue
35
+			}
36
+
37
+			for eid, ip := range lb.backEnds {
38
+				service := s
39
+				loadBalancer := lb
40
+				networkID := nid
41
+				epID := eid
42
+				epIP := ip
43
+
44
+				cleanupFuncs = append(cleanupFuncs, func() {
45
+					if err := c.rmServiceBinding(service.name, service.id, networkID, epID, loadBalancer.vip,
46
+						service.ingressPorts, service.aliases, epIP); err != nil {
47
+						logrus.Errorf("Failed to remove service bindings for service %s network %s endpoint %s while cleanup: %v",
48
+							service.id, networkID, epID, err)
49
+					}
50
+				})
51
+			}
52
+		}
53
+		s.Unlock()
54
+	}
55
+
56
+	for _, f := range cleanupFuncs {
57
+		f()
58
+	}
59
+
60
+}
61
+
62
+func (c *controller) addServiceBinding(name, sid, nid, eid string, vip net.IP, ingressPorts []*PortConfig, aliases []string, ip net.IP) error {
63
+	var (
64
+		s          *service
65
+		addService bool
66
+	)
67
+
68
+	n, err := c.NetworkByID(nid)
69
+	if err != nil {
70
+		return err
71
+	}
72
+
73
+	skey := serviceKey{
74
+		id:    sid,
75
+		ports: portConfigs(ingressPorts).String(),
76
+	}
77
+
78
+	c.Lock()
79
+	s, ok := c.serviceBindings[skey]
80
+	if !ok {
81
+		// Create a new service if we are seeing this service
82
+		// for the first time.
83
+		s = newService(name, sid, ingressPorts, aliases)
84
+		c.serviceBindings[skey] = s
85
+	}
86
+	c.Unlock()
87
+
88
+	// Add endpoint IP to special "tasks.svc_name" so that the
89
+	// applications have access to DNS RR.
90
+	n.(*network).addSvcRecords("tasks."+name, ip, nil, false)
91
+	for _, alias := range aliases {
92
+		n.(*network).addSvcRecords("tasks."+alias, ip, nil, false)
93
+	}
94
+
95
+	// Add service name to vip in DNS, if vip is valid. Otherwise resort to DNS RR
96
+	svcIP := vip
97
+	if len(svcIP) == 0 {
98
+		svcIP = ip
99
+	}
100
+	n.(*network).addSvcRecords(name, svcIP, nil, false)
101
+	for _, alias := range aliases {
102
+		n.(*network).addSvcRecords(alias, svcIP, nil, false)
103
+	}
104
+
105
+	s.Lock()
106
+	defer s.Unlock()
107
+
108
+	lb, ok := s.loadBalancers[nid]
109
+	if !ok {
110
+		// Create a new load balancer if we are seeing this
111
+		// network attachment on the service for the first
112
+		// time.
113
+		lb = &loadBalancer{
114
+			vip:      vip,
115
+			fwMark:   fwMarkCtr,
116
+			backEnds: make(map[string]net.IP),
117
+			service:  s,
118
+		}
119
+
120
+		fwMarkCtrMu.Lock()
121
+		fwMarkCtr++
122
+		fwMarkCtrMu.Unlock()
123
+
124
+		s.loadBalancers[nid] = lb
125
+
126
+		// Since we just created this load balancer make sure
127
+		// we add a new service service in IPVS rules.
128
+		addService = true
129
+
130
+	}
131
+
132
+	lb.backEnds[eid] = ip
133
+
134
+	// Add loadbalancer service and backend in all sandboxes in
135
+	// the network only if vip is valid.
136
+	if len(vip) != 0 {
137
+		n.(*network).addLBBackend(ip, vip, lb.fwMark, ingressPorts, addService)
138
+	}
139
+
140
+	return nil
141
+}
142
+
143
+func (c *controller) rmServiceBinding(name, sid, nid, eid string, vip net.IP, ingressPorts []*PortConfig, aliases []string, ip net.IP) error {
144
+	var rmService bool
145
+
146
+	n, err := c.NetworkByID(nid)
147
+	if err != nil {
148
+		return err
149
+	}
150
+
151
+	skey := serviceKey{
152
+		id:    sid,
153
+		ports: portConfigs(ingressPorts).String(),
154
+	}
155
+
156
+	c.Lock()
157
+	s, ok := c.serviceBindings[skey]
158
+	if !ok {
159
+		c.Unlock()
160
+		return nil
161
+	}
162
+	c.Unlock()
163
+
164
+	s.Lock()
165
+	lb, ok := s.loadBalancers[nid]
166
+	if !ok {
167
+		s.Unlock()
168
+		return nil
169
+	}
170
+
171
+	_, ok = lb.backEnds[eid]
172
+	if !ok {
173
+		s.Unlock()
174
+		return nil
175
+	}
176
+
177
+	delete(lb.backEnds, eid)
178
+	if len(lb.backEnds) == 0 {
179
+		// All the backends for this service have been
180
+		// removed. Time to remove the load balancer and also
181
+		// remove the service entry in IPVS.
182
+		rmService = true
183
+
184
+		delete(s.loadBalancers, nid)
185
+	}
186
+
187
+	if len(s.loadBalancers) == 0 {
188
+		// All loadbalancers for the service removed. Time to
189
+		// remove the service itself.
190
+		delete(c.serviceBindings, skey)
191
+	}
192
+
193
+	// Remove loadbalancer service(if needed) and backend in all
194
+	// sandboxes in the network only if the vip is valid.
195
+	if len(vip) != 0 {
196
+		n.(*network).rmLBBackend(ip, vip, lb.fwMark, ingressPorts, rmService)
197
+	}
198
+	s.Unlock()
199
+
200
+	// Delete the special "tasks.svc_name" backend record.
201
+	n.(*network).deleteSvcRecords("tasks."+name, ip, nil, false)
202
+	for _, alias := range aliases {
203
+		n.(*network).deleteSvcRecords("tasks."+alias, ip, nil, false)
204
+	}
205
+
206
+	// If we are doing DNS RR add the endpoint IP to DNS record
207
+	// right away.
208
+	if len(vip) == 0 {
209
+		n.(*network).deleteSvcRecords(name, ip, nil, false)
210
+		for _, alias := range aliases {
211
+			n.(*network).deleteSvcRecords(alias, ip, nil, false)
212
+		}
213
+	}
214
+
215
+	// Remove the DNS record for VIP only if we are removing the service
216
+	if rmService && len(vip) != 0 {
217
+		n.(*network).deleteSvcRecords(name, vip, nil, false)
218
+		for _, alias := range aliases {
219
+			n.(*network).deleteSvcRecords(alias, vip, nil, false)
220
+		}
221
+	}
222
+
223
+	return nil
224
+}
... ...
@@ -29,222 +29,6 @@ func init() {
29 29
 	reexec.Register("redirecter", redirecter)
30 30
 }
31 31
 
32
-func newService(name string, id string, ingressPorts []*PortConfig, aliases []string) *service {
33
-	return &service{
34
-		name:          name,
35
-		id:            id,
36
-		ingressPorts:  ingressPorts,
37
-		loadBalancers: make(map[string]*loadBalancer),
38
-		aliases:       aliases,
39
-	}
40
-}
41
-
42
-func (c *controller) cleanupServiceBindings(cleanupNID string) {
43
-	var cleanupFuncs []func()
44
-
45
-	c.Lock()
46
-	services := make([]*service, 0, len(c.serviceBindings))
47
-	for _, s := range c.serviceBindings {
48
-		services = append(services, s)
49
-	}
50
-	c.Unlock()
51
-
52
-	for _, s := range services {
53
-		s.Lock()
54
-		for nid, lb := range s.loadBalancers {
55
-			if cleanupNID != "" && nid != cleanupNID {
56
-				continue
57
-			}
58
-
59
-			for eid, ip := range lb.backEnds {
60
-				service := s
61
-				loadBalancer := lb
62
-				networkID := nid
63
-				epID := eid
64
-				epIP := ip
65
-
66
-				cleanupFuncs = append(cleanupFuncs, func() {
67
-					if err := c.rmServiceBinding(service.name, service.id, networkID, epID, loadBalancer.vip,
68
-						service.ingressPorts, service.aliases, epIP); err != nil {
69
-						logrus.Errorf("Failed to remove service bindings for service %s network %s endpoint %s while cleanup: %v",
70
-							service.id, networkID, epID, err)
71
-					}
72
-				})
73
-			}
74
-		}
75
-		s.Unlock()
76
-	}
77
-
78
-	for _, f := range cleanupFuncs {
79
-		f()
80
-	}
81
-
82
-}
83
-
84
-func (c *controller) addServiceBinding(name, sid, nid, eid string, vip net.IP, ingressPorts []*PortConfig, aliases []string, ip net.IP) error {
85
-	var (
86
-		s          *service
87
-		addService bool
88
-	)
89
-
90
-	n, err := c.NetworkByID(nid)
91
-	if err != nil {
92
-		return err
93
-	}
94
-
95
-	skey := serviceKey{
96
-		id:    sid,
97
-		ports: portConfigs(ingressPorts).String(),
98
-	}
99
-
100
-	c.Lock()
101
-	s, ok := c.serviceBindings[skey]
102
-	if !ok {
103
-		// Create a new service if we are seeing this service
104
-		// for the first time.
105
-		s = newService(name, sid, ingressPorts, aliases)
106
-		c.serviceBindings[skey] = s
107
-	}
108
-	c.Unlock()
109
-
110
-	// Add endpoint IP to special "tasks.svc_name" so that the
111
-	// applications have access to DNS RR.
112
-	n.(*network).addSvcRecords("tasks."+name, ip, nil, false)
113
-	for _, alias := range aliases {
114
-		n.(*network).addSvcRecords("tasks."+alias, ip, nil, false)
115
-	}
116
-
117
-	// Add service name to vip in DNS, if vip is valid. Otherwise resort to DNS RR
118
-	svcIP := vip
119
-	if len(svcIP) == 0 {
120
-		svcIP = ip
121
-	}
122
-	n.(*network).addSvcRecords(name, svcIP, nil, false)
123
-	for _, alias := range aliases {
124
-		n.(*network).addSvcRecords(alias, svcIP, nil, false)
125
-	}
126
-
127
-	s.Lock()
128
-	defer s.Unlock()
129
-
130
-	lb, ok := s.loadBalancers[nid]
131
-	if !ok {
132
-		// Create a new load balancer if we are seeing this
133
-		// network attachment on the service for the first
134
-		// time.
135
-		lb = &loadBalancer{
136
-			vip:      vip,
137
-			fwMark:   fwMarkCtr,
138
-			backEnds: make(map[string]net.IP),
139
-			service:  s,
140
-		}
141
-
142
-		fwMarkCtrMu.Lock()
143
-		fwMarkCtr++
144
-		fwMarkCtrMu.Unlock()
145
-
146
-		s.loadBalancers[nid] = lb
147
-
148
-		// Since we just created this load balancer make sure
149
-		// we add a new service service in IPVS rules.
150
-		addService = true
151
-
152
-	}
153
-
154
-	lb.backEnds[eid] = ip
155
-
156
-	// Add loadbalancer service and backend in all sandboxes in
157
-	// the network only if vip is valid.
158
-	if len(vip) != 0 {
159
-		n.(*network).addLBBackend(ip, vip, lb.fwMark, ingressPorts, addService)
160
-	}
161
-
162
-	return nil
163
-}
164
-
165
-func (c *controller) rmServiceBinding(name, sid, nid, eid string, vip net.IP, ingressPorts []*PortConfig, aliases []string, ip net.IP) error {
166
-	var rmService bool
167
-
168
-	n, err := c.NetworkByID(nid)
169
-	if err != nil {
170
-		return err
171
-	}
172
-
173
-	skey := serviceKey{
174
-		id:    sid,
175
-		ports: portConfigs(ingressPorts).String(),
176
-	}
177
-
178
-	c.Lock()
179
-	s, ok := c.serviceBindings[skey]
180
-	if !ok {
181
-		c.Unlock()
182
-		return nil
183
-	}
184
-	c.Unlock()
185
-
186
-	s.Lock()
187
-	lb, ok := s.loadBalancers[nid]
188
-	if !ok {
189
-		s.Unlock()
190
-		return nil
191
-	}
192
-
193
-	_, ok = lb.backEnds[eid]
194
-	if !ok {
195
-		s.Unlock()
196
-		return nil
197
-	}
198
-
199
-	delete(lb.backEnds, eid)
200
-	if len(lb.backEnds) == 0 {
201
-		// All the backends for this service have been
202
-		// removed. Time to remove the load balancer and also
203
-		// remove the service entry in IPVS.
204
-		rmService = true
205
-
206
-		delete(s.loadBalancers, nid)
207
-	}
208
-
209
-	if len(s.loadBalancers) == 0 {
210
-		// All loadbalancers for the service removed. Time to
211
-		// remove the service itself.
212
-		delete(c.serviceBindings, skey)
213
-	}
214
-
215
-	// Remove loadbalancer service(if needed) and backend in all
216
-	// sandboxes in the network only if the vip is valid.
217
-	if len(vip) != 0 {
218
-		n.(*network).rmLBBackend(ip, vip, lb.fwMark, ingressPorts, rmService)
219
-	}
220
-	s.Unlock()
221
-
222
-	// Delete the special "tasks.svc_name" backend record.
223
-	n.(*network).deleteSvcRecords("tasks."+name, ip, nil, false)
224
-	for _, alias := range aliases {
225
-		n.(*network).deleteSvcRecords("tasks."+alias, ip, nil, false)
226
-	}
227
-
228
-	// If we are doing DNS RR add the endpoint IP to DNS record
229
-	// right away.
230
-	if len(vip) == 0 {
231
-		n.(*network).deleteSvcRecords(name, ip, nil, false)
232
-		for _, alias := range aliases {
233
-			n.(*network).deleteSvcRecords(alias, ip, nil, false)
234
-		}
235
-	}
236
-
237
-	// Remove the DNS record for VIP only if we are removing the service
238
-	if rmService && len(vip) != 0 {
239
-		n.(*network).deleteSvcRecords(name, vip, nil, false)
240
-		for _, alias := range aliases {
241
-			n.(*network).deleteSvcRecords(alias, vip, nil, false)
242
-		}
243
-	}
244
-
245
-	return nil
246
-}
247
-
248 32
 // Get all loadbalancers on this network that is currently discovered
249 33
 // on this node.
250 34
 func (n *network) connectedLoadbalancers() []*loadBalancer {
... ...
@@ -1,4 +1,4 @@
1
-// +build !linux
1
+// +build !linux,!windows
2 2
 
3 3
 package libnetwork
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,15 @@
0
+package libnetwork
1
+
2
+import "net"
3
+
4
+func (n *network) addLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*PortConfig, addService bool) {
5
+}
6
+
7
+func (n *network) rmLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*PortConfig, rmService bool) {
8
+}
9
+
10
+func (sb *sandbox) populateLoadbalancers(ep *endpoint) {
11
+}
12
+
13
+func arrangeIngressFilterRule() {
14
+}
... ...
@@ -3,7 +3,7 @@ package libnetwork
3 3
 import (
4 4
 	"fmt"
5 5
 
6
-	log "github.com/Sirupsen/logrus"
6
+	"github.com/Sirupsen/logrus"
7 7
 	"github.com/docker/libkv/store/boltdb"
8 8
 	"github.com/docker/libkv/store/consul"
9 9
 	"github.com/docker/libkv/store/etcd"
... ...
@@ -85,7 +85,7 @@ func (c *controller) getNetworkFromStore(nid string) (*network, error) {
85 85
 		// Continue searching in the next store if the key is not found in this store
86 86
 		if err != nil {
87 87
 			if err != datastore.ErrKeyNotFound {
88
-				log.Debugf("could not find network %s: %v", nid, err)
88
+				logrus.Debugf("could not find network %s: %v", nid, err)
89 89
 			}
90 90
 			continue
91 91
 		}
... ...
@@ -126,7 +126,7 @@ func (c *controller) getNetworksForScope(scope string) ([]*network, error) {
126 126
 		ec := &endpointCnt{n: n}
127 127
 		err = store.GetObject(datastore.Key(ec.Key()...), ec)
128 128
 		if err != nil && !n.inDelete {
129
-			log.Warnf("Could not find endpoint count key %s for network %s while listing: %v", datastore.Key(ec.Key()...), n.Name(), err)
129
+			logrus.Warnf("Could not find endpoint count key %s for network %s while listing: %v", datastore.Key(ec.Key()...), n.Name(), err)
130 130
 			continue
131 131
 		}
132 132
 
... ...
@@ -147,7 +147,7 @@ func (c *controller) getNetworksFromStore() ([]*network, error) {
147 147
 		// Continue searching in the next store if no keys found in this store
148 148
 		if err != nil {
149 149
 			if err != datastore.ErrKeyNotFound {
150
-				log.Debugf("failed to get networks for scope %s: %v", store.Scope(), err)
150
+				logrus.Debugf("failed to get networks for scope %s: %v", store.Scope(), err)
151 151
 			}
152 152
 			continue
153 153
 		}
... ...
@@ -161,7 +161,7 @@ func (c *controller) getNetworksFromStore() ([]*network, error) {
161 161
 			ec := &endpointCnt{n: n}
162 162
 			err = store.GetObject(datastore.Key(ec.Key()...), ec)
163 163
 			if err != nil && !n.inDelete {
164
-				log.Warnf("could not find endpoint count key %s for network %s while listing: %v", datastore.Key(ec.Key()...), n.Name(), err)
164
+				logrus.Warnf("could not find endpoint count key %s for network %s while listing: %v", datastore.Key(ec.Key()...), n.Name(), err)
165 165
 				continue
166 166
 			}
167 167
 
... ...
@@ -185,7 +185,7 @@ func (n *network) getEndpointFromStore(eid string) (*endpoint, error) {
185 185
 		if err != nil {
186 186
 			if err != datastore.ErrKeyNotFound {
187 187
 				errors = append(errors, fmt.Sprintf("{%s:%v}, ", store.Scope(), err))
188
-				log.Debugf("could not find endpoint %s in %s: %v", eid, store.Scope(), err)
188
+				logrus.Debugf("could not find endpoint %s in %s: %v", eid, store.Scope(), err)
189 189
 			}
190 190
 			continue
191 191
 		}
... ...
@@ -203,7 +203,7 @@ func (n *network) getEndpointsFromStore() ([]*endpoint, error) {
203 203
 		// Continue searching in the next store if no keys found in this store
204 204
 		if err != nil {
205 205
 			if err != datastore.ErrKeyNotFound {
206
-				log.Debugf("failed to get endpoints for network %s scope %s: %v",
206
+				logrus.Debugf("failed to get endpoints for network %s scope %s: %v",
207 207
 					n.Name(), store.Scope(), err)
208 208
 			}
209 209
 			continue
... ...
@@ -396,7 +396,7 @@ func (c *controller) processEndpointCreate(nmap map[string]*netWatch, ep *endpoi
396 396
 
397 397
 	ch, err := store.Watch(ep.getNetwork().getEpCnt(), nw.stopCh)
398 398
 	if err != nil {
399
-		log.Warnf("Error creating watch for network: %v", err)
399
+		logrus.Warnf("Error creating watch for network: %v", err)
400 400
 		return
401 401
 	}
402 402
 
... ...
@@ -459,15 +459,15 @@ func (c *controller) startWatch() {
459 459
 func (c *controller) networkCleanup() {
460 460
 	networks, err := c.getNetworksFromStore()
461 461
 	if err != nil {
462
-		log.Warnf("Could not retrieve networks from store(s) during network cleanup: %v", err)
462
+		logrus.Warnf("Could not retrieve networks from store(s) during network cleanup: %v", err)
463 463
 		return
464 464
 	}
465 465
 
466 466
 	for _, n := range networks {
467 467
 		if n.inDelete {
468
-			log.Infof("Removing stale network %s (%s)", n.Name(), n.ID())
468
+			logrus.Infof("Removing stale network %s (%s)", n.Name(), n.ID())
469 469
 			if err := n.delete(true); err != nil {
470
-				log.Debugf("Error while removing stale network: %v", err)
470
+				logrus.Debugf("Error while removing stale network: %v", err)
471 471
 			}
472 472
 		}
473 473
 	}
... ...
@@ -476,7 +476,7 @@ func (c *controller) networkCleanup() {
476 476
 var populateSpecial NetworkWalker = func(nw Network) bool {
477 477
 	if n := nw.(*network); n.hasSpecialDriver() {
478 478
 		if err := n.getController().addNetwork(n); err != nil {
479
-			log.Warnf("Failed to populate network %q with driver %q", nw.Name(), nw.Type())
479
+			logrus.Warnf("Failed to populate network %q with driver %q", nw.Name(), nw.Type())
480 480
 		}
481 481
 	}
482 482
 	return false
483 483
deleted file mode 100644
... ...
@@ -1,13 +0,0 @@
1
-package networkallocator
2
-
3
-import (
4
-	"github.com/docker/libnetwork/drivers/overlay/ovmanager"
5
-	"github.com/docker/libnetwork/drivers/remote"
6
-)
7
-
8
-func getInitializers() []initializer {
9
-	return []initializer{
10
-		{remote.Init, "remote"},
11
-		{ovmanager.Init, "overlay"},
12
-	}
13
-}
14 1
new file mode 100644
... ...
@@ -0,0 +1,15 @@
0
+// +build linux windows
1
+
2
+package networkallocator
3
+
4
+import (
5
+	"github.com/docker/libnetwork/drivers/overlay/ovmanager"
6
+	"github.com/docker/libnetwork/drivers/remote"
7
+)
8
+
9
+func getInitializers() []initializer {
10
+	return []initializer{
11
+		{remote.Init, "remote"},
12
+		{ovmanager.Init, "overlay"},
13
+	}
14
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !linux,!darwin
1
+// +build !linux,!darwin,!windows
2 2
 
3 3
 package networkallocator
4 4