Browse code

Vendor libnetwork

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>

Flavio Crisciani authored on 2018/07/18 04:12:18
Showing 48 changed files
... ...
@@ -3,7 +3,7 @@
3 3
 # LIBNETWORK_COMMIT is used to build the docker-userland-proxy binary. When
4 4
 # updating the binary version, consider updating github.com/docker/libnetwork
5 5
 # in vendor.conf accordingly
6
-LIBNETWORK_COMMIT=3ac297bc7fd0afec9051bbb47024c9bc1d75bf5b
6
+LIBNETWORK_COMMIT=f30a35b091cc2a431ef9856c75c343f75bb5f2e2
7 7
 
8 8
 install_proxy() {
9 9
 	case "$1" in
... ...
@@ -37,7 +37,7 @@ github.com/mitchellh/hashstructure 2bca23e0e452137f789efbc8610126fd8b94f73b
37 37
 #get libnetwork packages
38 38
 
39 39
 # When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy accordingly
40
-github.com/docker/libnetwork d00ceed44cc447c77f25cdf5d59e83163bdcb4c9
40
+github.com/docker/libnetwork f30a35b091cc2a431ef9856c75c343f75bb5f2e2
41 41
 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
42 42
 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
43 43
 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
... ...
@@ -15,6 +15,17 @@ There are many networking solutions available to suit a broad range of use-cases
15 15
 
16 16
 
17 17
 ```go
18
+import (
19
+	"fmt"
20
+	"log"
21
+
22
+	"github.com/docker/docker/pkg/reexec"
23
+	"github.com/docker/libnetwork"
24
+	"github.com/docker/libnetwork/config"
25
+	"github.com/docker/libnetwork/netlabel"
26
+	"github.com/docker/libnetwork/options"
27
+)
28
+
18 29
 func main() {
19 30
 	if reexec.Init() {
20 31
 		return
... ...
@@ -194,7 +194,7 @@ func (c *controller) handleKeyChange(keys []*types.EncryptionKey) error {
194 194
 func (c *controller) agentSetup(clusterProvider cluster.Provider) error {
195 195
 	agent := c.getAgent()
196 196
 
197
-	// If the agent is already present there is no need to try to initilize it again
197
+	// If the agent is already present there is no need to try to initialize it again
198 198
 	if agent != nil {
199 199
 		return nil
200 200
 	}
... ...
@@ -372,7 +372,7 @@ func (h *Handle) set(ordinal, start, end uint64, any bool, release bool, serial
372 372
 			h.Lock()
373 373
 		}
374 374
 
375
-		// Previous atomic push was succesfull. Save private copy to local copy
375
+		// Previous atomic push was successful. Save private copy to local copy
376 376
 		h.unselected = nh.unselected
377 377
 		h.head = nh.head
378 378
 		h.dbExists = nh.dbExists
379 379
deleted file mode 100644
... ...
@@ -1,29 +0,0 @@
1
-package common
2
-
3
-import (
4
-	"runtime"
5
-	"strings"
6
-)
7
-
8
-func callerInfo(i int) string {
9
-	ptr, _, _, ok := runtime.Caller(i)
10
-	fName := "unknown"
11
-	if ok {
12
-		f := runtime.FuncForPC(ptr)
13
-		if f != nil {
14
-			// f.Name() is like: github.com/docker/libnetwork/common.MethodName
15
-			tmp := strings.Split(f.Name(), ".")
16
-			if len(tmp) > 0 {
17
-				fName = tmp[len(tmp)-1]
18
-			}
19
-		}
20
-	}
21
-
22
-	return fName
23
-}
24
-
25
-// CallerName returns the name of the function at the specified level
26
-// level == 0 means current method name
27
-func CallerName(level int) string {
28
-	return callerInfo(2 + level)
29
-}
30 1
deleted file mode 100644
... ...
@@ -1,135 +0,0 @@
1
-package common
2
-
3
-import (
4
-	"sync"
5
-
6
-	mapset "github.com/deckarep/golang-set"
7
-)
8
-
9
-// SetMatrix is a map of Sets
10
-type SetMatrix interface {
11
-	// Get returns the members of the set for a specific key as a slice.
12
-	Get(key string) ([]interface{}, bool)
13
-	// Contains is used to verify if an element is in a set for a specific key
14
-	// returns true if the element is in the set
15
-	// returns true if there is a set for the key
16
-	Contains(key string, value interface{}) (bool, bool)
17
-	// Insert inserts the value in the set of a key
18
-	// returns true if the value is inserted (was not already in the set), false otherwise
19
-	// returns also the length of the set for the key
20
-	Insert(key string, value interface{}) (bool, int)
21
-	// Remove removes the value in the set for a specific key
22
-	// returns true if the value is deleted, false otherwise
23
-	// returns also the length of the set for the key
24
-	Remove(key string, value interface{}) (bool, int)
25
-	// Cardinality returns the number of elements in the set for a key
26
-	// returns false if the set is not present
27
-	Cardinality(key string) (int, bool)
28
-	// String returns the string version of the set, empty otherwise
29
-	// returns false if the set is not present
30
-	String(key string) (string, bool)
31
-	// Returns all the keys in the map
32
-	Keys() []string
33
-}
34
-
35
-type setMatrix struct {
36
-	matrix map[string]mapset.Set
37
-
38
-	sync.Mutex
39
-}
40
-
41
-// NewSetMatrix creates a new set matrix object
42
-func NewSetMatrix() SetMatrix {
43
-	s := &setMatrix{}
44
-	s.init()
45
-	return s
46
-}
47
-
48
-func (s *setMatrix) init() {
49
-	s.matrix = make(map[string]mapset.Set)
50
-}
51
-
52
-func (s *setMatrix) Get(key string) ([]interface{}, bool) {
53
-	s.Lock()
54
-	defer s.Unlock()
55
-	set, ok := s.matrix[key]
56
-	if !ok {
57
-		return nil, ok
58
-	}
59
-	return set.ToSlice(), ok
60
-}
61
-
62
-func (s *setMatrix) Contains(key string, value interface{}) (bool, bool) {
63
-	s.Lock()
64
-	defer s.Unlock()
65
-	set, ok := s.matrix[key]
66
-	if !ok {
67
-		return false, ok
68
-	}
69
-	return set.Contains(value), ok
70
-}
71
-
72
-func (s *setMatrix) Insert(key string, value interface{}) (bool, int) {
73
-	s.Lock()
74
-	defer s.Unlock()
75
-	set, ok := s.matrix[key]
76
-	if !ok {
77
-		s.matrix[key] = mapset.NewSet()
78
-		s.matrix[key].Add(value)
79
-		return true, 1
80
-	}
81
-
82
-	return set.Add(value), set.Cardinality()
83
-}
84
-
85
-func (s *setMatrix) Remove(key string, value interface{}) (bool, int) {
86
-	s.Lock()
87
-	defer s.Unlock()
88
-	set, ok := s.matrix[key]
89
-	if !ok {
90
-		return false, 0
91
-	}
92
-
93
-	var removed bool
94
-	if set.Contains(value) {
95
-		set.Remove(value)
96
-		removed = true
97
-		// If the set is empty remove it from the matrix
98
-		if set.Cardinality() == 0 {
99
-			delete(s.matrix, key)
100
-		}
101
-	}
102
-
103
-	return removed, set.Cardinality()
104
-}
105
-
106
-func (s *setMatrix) Cardinality(key string) (int, bool) {
107
-	s.Lock()
108
-	defer s.Unlock()
109
-	set, ok := s.matrix[key]
110
-	if !ok {
111
-		return 0, ok
112
-	}
113
-
114
-	return set.Cardinality(), ok
115
-}
116
-
117
-func (s *setMatrix) String(key string) (string, bool) {
118
-	s.Lock()
119
-	defer s.Unlock()
120
-	set, ok := s.matrix[key]
121
-	if !ok {
122
-		return "", ok
123
-	}
124
-	return set.String(), ok
125
-}
126
-
127
-func (s *setMatrix) Keys() []string {
128
-	s.Lock()
129
-	defer s.Unlock()
130
-	keys := make([]string, 0, len(s.matrix))
131
-	for k := range s.matrix {
132
-		keys = append(keys, k)
133
-	}
134
-	return keys
135
-}
... ...
@@ -121,7 +121,7 @@ type NetworkController interface {
121 121
 	// Stop network controller
122 122
 	Stop()
123 123
 
124
-	// ReloadCondfiguration updates the controller configuration
124
+	// ReloadConfiguration updates the controller configuration
125 125
 	ReloadConfiguration(cfgOptions ...config.Option) error
126 126
 
127 127
 	// SetClusterProvider sets cluster provider
... ...
@@ -1107,6 +1107,8 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
1107 1107
 		sb.config.hostsPath = filepath.Join(c.cfg.Daemon.DataDir, "/network/files/hosts")
1108 1108
 		sb.config.resolvConfPath = filepath.Join(c.cfg.Daemon.DataDir, "/network/files/resolv.conf")
1109 1109
 		sb.id = "ingress_sbox"
1110
+	} else if sb.loadBalancerNID != "" {
1111
+		sb.id = "lb_" + sb.loadBalancerNID
1110 1112
 	}
1111 1113
 	c.Unlock()
1112 1114
 
... ...
@@ -185,7 +185,7 @@ func Key(key ...string) string {
185 185
 func ParseKey(key string) ([]string, error) {
186 186
 	chain := strings.Split(strings.Trim(key, "/"), "/")
187 187
 
188
-	// The key must atleast be equal to the rootChain in order to be considered as valid
188
+	// The key must at least be equal to the rootChain in order to be considered as valid
189 189
 	if len(chain) <= len(rootChain) || !reflect.DeepEqual(chain[0:len(rootChain)], rootChain) {
190 190
 		return nil, types.BadRequestErrorf("invalid Key : %s", key)
191 191
 	}
... ...
@@ -589,7 +589,7 @@ func (ds *datastore) DeleteObject(kvObject KVObject) error {
589 589
 		defer ds.Unlock()
590 590
 	}
591 591
 
592
-	// cleaup the cache first
592
+	// cleanup the cache first
593 593
 	if ds.cache != nil {
594 594
 		// If persistent store is skipped, sequencing needs to
595 595
 		// happen in cache.
... ...
@@ -645,7 +645,7 @@ func (ds *datastore) DeleteTree(kvObject KVObject) error {
645 645
 		defer ds.Unlock()
646 646
 	}
647 647
 
648
-	// cleaup the cache first
648
+	// cleanup the cache first
649 649
 	if ds.cache != nil {
650 650
 		// If persistent store is skipped, sequencing needs to
651 651
 		// happen in cache.
... ...
@@ -8,8 +8,8 @@ import (
8 8
 )
9 9
 
10 10
 var (
11
-	// ErrNotImplmented exported
12
-	ErrNotImplmented = errors.New("Functionality not implemented")
11
+	// ErrNotImplemented exported
12
+	ErrNotImplemented = errors.New("Functionality not implemented")
13 13
 )
14 14
 
15 15
 // MockData exported
... ...
@@ -65,7 +65,7 @@ func (s *MockStore) Exists(key string) (bool, error) {
65 65
 
66 66
 // List gets a range of values at "directory"
67 67
 func (s *MockStore) List(prefix string) ([]*store.KVPair, error) {
68
-	return nil, ErrNotImplmented
68
+	return nil, ErrNotImplemented
69 69
 }
70 70
 
71 71
 // DeleteTree deletes a range of values at "directory"
... ...
@@ -76,17 +76,17 @@ func (s *MockStore) DeleteTree(prefix string) error {
76 76
 
77 77
 // Watch a single key for modifications
78 78
 func (s *MockStore) Watch(key string, stopCh <-chan struct{}) (<-chan *store.KVPair, error) {
79
-	return nil, ErrNotImplmented
79
+	return nil, ErrNotImplemented
80 80
 }
81 81
 
82 82
 // WatchTree triggers a watch on a range of values at "directory"
83 83
 func (s *MockStore) WatchTree(prefix string, stopCh <-chan struct{}) (<-chan []*store.KVPair, error) {
84
-	return nil, ErrNotImplmented
84
+	return nil, ErrNotImplemented
85 85
 }
86 86
 
87 87
 // NewLock exposed
88 88
 func (s *MockStore) NewLock(key string, options *store.LockOptions) (store.Locker, error) {
89
-	return nil, ErrNotImplmented
89
+	return nil, ErrNotImplemented
90 90
 }
91 91
 
92 92
 // AtomicPut put a value at "key" if the key has not been
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"sync/atomic"
10 10
 
11 11
 	stackdump "github.com/docker/docker/pkg/signal"
12
-	"github.com/docker/libnetwork/common"
12
+	"github.com/docker/libnetwork/internal/caller"
13 13
 	"github.com/sirupsen/logrus"
14 14
 )
15 15
 
... ...
@@ -127,7 +127,7 @@ func notImplemented(ctx interface{}, w http.ResponseWriter, r *http.Request) {
127 127
 	rsp := WrongCommand("not implemented", fmt.Sprintf("URL path: %s no method implemented check /help\n", r.URL.Path))
128 128
 
129 129
 	// audit logs
130
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
130
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
131 131
 	log.Info("command not implemented done")
132 132
 
133 133
 	HTTPReply(w, rsp, json)
... ...
@@ -138,7 +138,7 @@ func help(ctx interface{}, w http.ResponseWriter, r *http.Request) {
138 138
 	_, json := ParseHTTPFormOptions(r)
139 139
 
140 140
 	// audit logs
141
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
141
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
142 142
 	log.Info("help done")
143 143
 
144 144
 	n, ok := ctx.(*Server)
... ...
@@ -156,7 +156,7 @@ func ready(ctx interface{}, w http.ResponseWriter, r *http.Request) {
156 156
 	_, json := ParseHTTPFormOptions(r)
157 157
 
158 158
 	// audit logs
159
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
159
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
160 160
 	log.Info("ready done")
161 161
 	HTTPReply(w, CommandSucceed(&StringCmd{Info: "OK"}), json)
162 162
 }
... ...
@@ -166,7 +166,7 @@ func stackTrace(ctx interface{}, w http.ResponseWriter, r *http.Request) {
166 166
 	_, json := ParseHTTPFormOptions(r)
167 167
 
168 168
 	// audit logs
169
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
169
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
170 170
 	log.Info("stack trace")
171 171
 
172 172
 	path, err := stackdump.DumpStacks("/tmp/")
... ...
@@ -75,10 +75,10 @@ type Driver interface {
75 75
 	// DecodeTableEntry passes the driver a key, value pair from table it registered
76 76
 	// with libnetwork. Driver should return {object ID, map[string]string} tuple.
77 77
 	// If DecodeTableEntry is called for a table associated with NetworkObject or
78
-	// EndpointObject the return object ID should be the network id or endppoint id
78
+	// EndpointObject the return object ID should be the network id or endpoint id
79 79
 	// associated with that entry. map should have information about the object that
80 80
 	// can be presented to the user.
81
-	// For exampe: overlay driver returns the VTEP IP of the host that has the endpoint
81
+	// For example: overlay driver returns the VTEP IP of the host that has the endpoint
82 82
 	// which is shown in 'network inspect --verbose'
83 83
 	DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string)
84 84
 
... ...
@@ -97,7 +97,7 @@ type NetworkInfo interface {
97 97
 	TableEventRegister(tableName string, objType ObjectType) error
98 98
 }
99 99
 
100
-// InterfaceInfo provides a go interface for drivers to retrive
100
+// InterfaceInfo provides a go interface for drivers to retrieve
101 101
 // network information to interface resources.
102 102
 type InterfaceInfo interface {
103 103
 	// SetMacAddress allows the driver to set the mac address to the endpoint interface
... ...
@@ -104,7 +104,7 @@ type containerConfiguration struct {
104 104
 	ChildEndpoints  []string
105 105
 }
106 106
 
107
-// cnnectivityConfiguration represents the user specified configuration regarding the external connectivity
107
+// connectivityConfiguration represents the user specified configuration regarding the external connectivity
108 108
 type connectivityConfiguration struct {
109 109
 	PortBindings []types.PortBinding
110 110
 	ExposedPorts []types.TransportPort
... ...
@@ -84,7 +84,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
84 84
 			}
85 85
 			v4gw, _, err := net.ParseCIDR(s.GwIP)
86 86
 			if err != nil {
87
-				return fmt.Errorf("gatway %s is not a valid ipv4 address: %v", s.GwIP, err)
87
+				return fmt.Errorf("gateway %s is not a valid ipv4 address: %v", s.GwIP, err)
88 88
 			}
89 89
 			err = jinfo.SetGateway(v4gw)
90 90
 			if err != nil {
... ...
@@ -101,7 +101,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
101 101
 			}
102 102
 			v6gw, _, err := net.ParseCIDR(s.GwIP)
103 103
 			if err != nil {
104
-				return fmt.Errorf("gatway %s is not a valid ipv6 address: %v", s.GwIP, err)
104
+				return fmt.Errorf("gateway %s is not a valid ipv6 address: %v", s.GwIP, err)
105 105
 			}
106 106
 			err = jinfo.SetGatewayIPv6(v6gw)
107 107
 			if err != nil {
... ...
@@ -68,7 +68,7 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
68 68
 	err = d.storeUpdate(config)
69 69
 	if err != nil {
70 70
 		d.deleteNetwork(config.ID)
71
-		logrus.Debugf("encoutered an error rolling back a network create for %s : %v", config.ID, err)
71
+		logrus.Debugf("encountered an error rolling back a network create for %s : %v", config.ID, err)
72 72
 		return err
73 73
 	}
74 74
 
... ...
@@ -92,7 +92,7 @@ func (d *driver) createNetwork(config *configuration) error {
92 92
 				return err
93 93
 			}
94 94
 			config.CreatedSlaveLink = true
95
-			// notify the user in logs they have limited comunicatins
95
+			// notify the user in logs they have limited communications
96 96
 			if config.Parent == getDummyName(stringid.TruncateID(config.ID)) {
97 97
 				logrus.Debugf("Empty -o parent= and --internal flags limit communications to other containers inside of network: %s",
98 98
 					config.Parent)
... ...
@@ -30,7 +30,7 @@ func createIPVlan(containerIfName, parent, ipvlanMode string) (string, error) {
30 30
 	// Get the link for the master index (Example: the docker host eth iface)
31 31
 	parentLink, err := ns.NlHandle().LinkByName(parent)
32 32
 	if err != nil {
33
-		return "", fmt.Errorf("error occoured looking up the %s parent iface %s error: %s", ipvlanType, parent, err)
33
+		return "", fmt.Errorf("error occurred looking up the %s parent iface %s error: %s", ipvlanType, parent, err)
34 34
 	}
35 35
 	// Create an ipvlan link
36 36
 	ipvlan := &netlink.IPVlan{
... ...
@@ -169,7 +169,7 @@ func createDummyLink(dummyName, truncNetID string) error {
169 169
 	}
170 170
 	parentDummyLink, err := ns.NlHandle().LinkByName(dummyName)
171 171
 	if err != nil {
172
-		return fmt.Errorf("error occoured looking up the %s parent iface %s error: %s", ipvlanType, dummyName, err)
172
+		return fmt.Errorf("error occurred looking up the %s parent iface %s error: %s", ipvlanType, dummyName, err)
173 173
 	}
174 174
 	// bring the new netlink iface up
175 175
 	if err := ns.NlHandle().LinkSetUp(parentDummyLink); err != nil {
... ...
@@ -31,7 +31,7 @@ func (d *driver) deleteNetwork(nid string) {
31 31
 	d.Unlock()
32 32
 }
33 33
 
34
-// getNetworks Safely returns a slice of existng networks
34
+// getNetworks Safely returns a slice of existing networks
35 35
 func (d *driver) getNetworks() []*network {
36 36
 	d.Lock()
37 37
 	defer d.Unlock()
... ...
@@ -46,7 +46,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
46 46
 		}
47 47
 		v4gw, _, err := net.ParseCIDR(s.GwIP)
48 48
 		if err != nil {
49
-			return fmt.Errorf("gatway %s is not a valid ipv4 address: %v", s.GwIP, err)
49
+			return fmt.Errorf("gateway %s is not a valid ipv4 address: %v", s.GwIP, err)
50 50
 		}
51 51
 		err = jinfo.SetGateway(v4gw)
52 52
 		if err != nil {
... ...
@@ -63,7 +63,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
63 63
 		}
64 64
 		v6gw, _, err := net.ParseCIDR(s.GwIP)
65 65
 		if err != nil {
66
-			return fmt.Errorf("gatway %s is not a valid ipv6 address: %v", s.GwIP, err)
66
+			return fmt.Errorf("gateway %s is not a valid ipv6 address: %v", s.GwIP, err)
67 67
 		}
68 68
 		err = jinfo.SetGatewayIPv6(v6gw)
69 69
 		if err != nil {
... ...
@@ -72,7 +72,7 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
72 72
 	err = d.storeUpdate(config)
73 73
 	if err != nil {
74 74
 		d.deleteNetwork(config.ID)
75
-		logrus.Debugf("encoutered an error rolling back a network create for %s : %v", config.ID, err)
75
+		logrus.Debugf("encountered an error rolling back a network create for %s : %v", config.ID, err)
76 76
 		return err
77 77
 	}
78 78
 
... ...
@@ -96,7 +96,7 @@ func (d *driver) createNetwork(config *configuration) error {
96 96
 				return err
97 97
 			}
98 98
 			config.CreatedSlaveLink = true
99
-			// notify the user in logs they have limited comunicatins
99
+			// notify the user in logs they have limited communications
100 100
 			if config.Parent == getDummyName(stringid.TruncateID(config.ID)) {
101 101
 				logrus.Debugf("Empty -o parent= and --internal flags limit communications to other containers inside of network: %s",
102 102
 					config.Parent)
... ...
@@ -30,7 +30,7 @@ func createMacVlan(containerIfName, parent, macvlanMode string) (string, error)
30 30
 	// Get the link for the master index (Example: the docker host eth iface)
31 31
 	parentLink, err := ns.NlHandle().LinkByName(parent)
32 32
 	if err != nil {
33
-		return "", fmt.Errorf("error occoured looking up the %s parent iface %s error: %s", macvlanType, parent, err)
33
+		return "", fmt.Errorf("error occurred looking up the %s parent iface %s error: %s", macvlanType, parent, err)
34 34
 	}
35 35
 	// Create a macvlan link
36 36
 	macvlan := &netlink.Macvlan{
... ...
@@ -173,7 +173,7 @@ func createDummyLink(dummyName, truncNetID string) error {
173 173
 	}
174 174
 	parentDummyLink, err := ns.NlHandle().LinkByName(dummyName)
175 175
 	if err != nil {
176
-		return fmt.Errorf("error occoured looking up the %s parent iface %s error: %s", macvlanType, dummyName, err)
176
+		return fmt.Errorf("error occurred looking up the %s parent iface %s error: %s", macvlanType, dummyName, err)
177 177
 	}
178 178
 	// bring the new netlink iface up
179 179
 	if err := ns.NlHandle().LinkSetUp(parentDummyLink); err != nil {
... ...
@@ -601,7 +601,7 @@ func (n *network) maxMTU() int {
601 601
 	mtu -= vxlanEncap
602 602
 	if n.secure {
603 603
 		// In case of encryption account for the
604
-		// esp packet espansion and padding
604
+		// esp packet expansion and padding
605 605
 		mtu -= pktExpansion
606 606
 		mtu -= (mtu % 4)
607 607
 	}
... ...
@@ -47,18 +47,10 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
47 47
 		return fmt.Errorf("couldn't get vxlan id for %q: %v", s.subnetIP.String(), err)
48 48
 	}
49 49
 
50
-	if err := n.joinSandbox(false); err != nil {
50
+	if err := n.joinSandbox(s, false, true); err != nil {
51 51
 		return fmt.Errorf("network sandbox join failed: %v", err)
52 52
 	}
53 53
 
54
-	if err := n.joinSubnetSandbox(s, false); err != nil {
55
-		return fmt.Errorf("subnet sandbox join failed for %q: %v", s.subnetIP.String(), err)
56
-	}
57
-
58
-	// joinSubnetSandbox gets called when an endpoint comes up on a new subnet in the
59
-	// overlay network. Hence the Endpoint count should be updated outside joinSubnetSandbox
60
-	n.incEndpointCount()
61
-
62 54
 	sbox := n.sandbox()
63 55
 
64 56
 	overlayIfName, containerIfName, err := createVethPair()
... ...
@@ -39,7 +39,7 @@ var (
39 39
 type networkTable map[string]*network
40 40
 
41 41
 type subnet struct {
42
-	once      *sync.Once
42
+	sboxInit  bool
43 43
 	vxlanName string
44 44
 	brName    string
45 45
 	vni       uint32
... ...
@@ -63,7 +63,7 @@ type network struct {
63 63
 	endpoints endpointTable
64 64
 	driver    *driver
65 65
 	joinCnt   int
66
-	once      *sync.Once
66
+	sboxInit  bool
67 67
 	initEpoch int
68 68
 	initErr   error
69 69
 	subnets   []*subnet
... ...
@@ -150,7 +150,6 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
150 150
 		id:        id,
151 151
 		driver:    d,
152 152
 		endpoints: endpointTable{},
153
-		once:      &sync.Once{},
154 153
 		subnets:   []*subnet{},
155 154
 	}
156 155
 
... ...
@@ -193,7 +192,6 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
193 193
 		s := &subnet{
194 194
 			subnetIP: ipd.Pool,
195 195
 			gwIP:     ipd.Gateway,
196
-			once:     &sync.Once{},
197 196
 		}
198 197
 
199 198
 		if len(vnis) != 0 {
... ...
@@ -277,7 +275,7 @@ func (d *driver) DeleteNetwork(nid string) error {
277 277
 			logrus.Warnf("Failed to delete overlay endpoint %.7s from local store: %v", ep.id, err)
278 278
 		}
279 279
 	}
280
-	// flush the peerDB entries
280
+
281 281
 	doPeerFlush = true
282 282
 	delete(d.networks, nid)
283 283
 
... ...
@@ -304,29 +302,54 @@ func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
304 304
 	return nil
305 305
 }
306 306
 
307
-func (n *network) incEndpointCount() {
308
-	n.Lock()
309
-	defer n.Unlock()
310
-	n.joinCnt++
311
-}
312
-
313
-func (n *network) joinSandbox(restore bool) error {
307
+func (n *network) joinSandbox(s *subnet, restore bool, incJoinCount bool) error {
314 308
 	// If there is a race between two go routines here only one will win
315 309
 	// the other will wait.
316
-	n.once.Do(func() {
317
-		// save the error status of initSandbox in n.initErr so that
318
-		// all the racing go routines are able to know the status.
310
+	networkOnce.Do(networkOnceInit)
311
+
312
+	n.Lock()
313
+	// If non-restore initialization occurred and was successful then
314
+	// tell the peerDB to initialize the sandbox with all the peers
315
+	// previously received from networkdb.  But only do this after
316
+	// unlocking the network.  Otherwise we could deadlock with
317
+	// on the peerDB channel while peerDB is waiting for the network lock.
318
+	var doInitPeerDB bool
319
+	defer func() {
320
+		n.Unlock()
321
+		if doInitPeerDB {
322
+			n.driver.initSandboxPeerDB(n.id)
323
+		}
324
+	}()
325
+
326
+	if !n.sboxInit {
319 327
 		n.initErr = n.initSandbox(restore)
320
-	})
328
+		doInitPeerDB = n.initErr == nil && !restore
329
+		// If there was an error, we cannot recover it
330
+		n.sboxInit = true
331
+	}
321 332
 
322
-	return n.initErr
323
-}
333
+	if n.initErr != nil {
334
+		return fmt.Errorf("network sandbox join failed: %v", n.initErr)
335
+	}
324 336
 
325
-func (n *network) joinSubnetSandbox(s *subnet, restore bool) error {
326
-	s.once.Do(func() {
327
-		s.initErr = n.initSubnetSandbox(s, restore)
328
-	})
329
-	return s.initErr
337
+	subnetErr := s.initErr
338
+	if !s.sboxInit {
339
+		subnetErr = n.initSubnetSandbox(s, restore)
340
+		// We can recover from these errors, but not on restore
341
+		if restore || subnetErr == nil {
342
+			s.initErr = subnetErr
343
+			s.sboxInit = true
344
+		}
345
+	}
346
+	if subnetErr != nil {
347
+		return fmt.Errorf("subnet sandbox join failed for %q: %v", s.subnetIP.String(), subnetErr)
348
+	}
349
+
350
+	if incJoinCount {
351
+		n.joinCnt++
352
+	}
353
+
354
+	return nil
330 355
 }
331 356
 
332 357
 func (n *network) leaveSandbox() {
... ...
@@ -337,15 +360,14 @@ func (n *network) leaveSandbox() {
337 337
 		return
338 338
 	}
339 339
 
340
-	// We are about to destroy sandbox since the container is leaving the network
341
-	// Reinitialize the once variable so that we will be able to trigger one time
342
-	// sandbox initialization(again) when another container joins subsequently.
343
-	n.once = &sync.Once{}
340
+	n.destroySandbox()
341
+
342
+	n.sboxInit = false
343
+	n.initErr = nil
344 344
 	for _, s := range n.subnets {
345
-		s.once = &sync.Once{}
345
+		s.sboxInit = false
346
+		s.initErr = nil
346 347
 	}
347
-
348
-	n.destroySandbox()
349 348
 }
350 349
 
351 350
 // to be called while holding network lock
... ...
@@ -478,7 +500,7 @@ func (n *network) generateVxlanName(s *subnet) string {
478 478
 		id = n.id[:5]
479 479
 	}
480 480
 
481
-	return "vx-" + fmt.Sprintf("%06x", n.vxlanID(s)) + "-" + id
481
+	return fmt.Sprintf("vx-%06x-%v", s.vni, id)
482 482
 }
483 483
 
484 484
 func (n *network) generateBridgeName(s *subnet) string {
... ...
@@ -491,7 +513,7 @@ func (n *network) generateBridgeName(s *subnet) string {
491 491
 }
492 492
 
493 493
 func (n *network) getBridgeNamePrefix(s *subnet) string {
494
-	return "ov-" + fmt.Sprintf("%06x", n.vxlanID(s))
494
+	return fmt.Sprintf("ov-%06x", s.vni)
495 495
 }
496 496
 
497 497
 func checkOverlap(nw *net.IPNet) error {
... ...
@@ -513,7 +535,7 @@ func checkOverlap(nw *net.IPNet) error {
513 513
 }
514 514
 
515 515
 func (n *network) restoreSubnetSandbox(s *subnet, brName, vxlanName string) error {
516
-	sbox := n.sandbox()
516
+	sbox := n.sbox
517 517
 
518 518
 	// restore overlay osl sandbox
519 519
 	Ifaces := make(map[string][]osl.IfaceOption)
... ...
@@ -542,7 +564,7 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error
542 542
 			deleteInterfaceBySubnet(n.getBridgeNamePrefix(s), s)
543 543
 		}
544 544
 		// Try to delete the vxlan interface by vni if already present
545
-		deleteVxlanByVNI("", n.vxlanID(s))
545
+		deleteVxlanByVNI("", s.vni)
546 546
 
547 547
 		if err := checkOverlap(s.subnetIP); err != nil {
548 548
 			return err
... ...
@@ -556,24 +578,24 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error
556 556
 		// it must a stale namespace from previous
557 557
 		// life. Destroy it completely and reclaim resourced.
558 558
 		networkMu.Lock()
559
-		path, ok := vniTbl[n.vxlanID(s)]
559
+		path, ok := vniTbl[s.vni]
560 560
 		networkMu.Unlock()
561 561
 
562 562
 		if ok {
563
-			deleteVxlanByVNI(path, n.vxlanID(s))
563
+			deleteVxlanByVNI(path, s.vni)
564 564
 			if err := syscall.Unmount(path, syscall.MNT_FORCE); err != nil {
565 565
 				logrus.Errorf("unmount of %s failed: %v", path, err)
566 566
 			}
567 567
 			os.Remove(path)
568 568
 
569 569
 			networkMu.Lock()
570
-			delete(vniTbl, n.vxlanID(s))
570
+			delete(vniTbl, s.vni)
571 571
 			networkMu.Unlock()
572 572
 		}
573 573
 	}
574 574
 
575 575
 	// create a bridge and vxlan device for this subnet and move it to the sandbox
576
-	sbox := n.sandbox()
576
+	sbox := n.sbox
577 577
 
578 578
 	if err := sbox.AddInterface(brName, "br",
579 579
 		sbox.InterfaceOptions().Address(s.gwIP),
... ...
@@ -581,13 +603,30 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error
581 581
 		return fmt.Errorf("bridge creation in sandbox failed for subnet %q: %v", s.subnetIP.String(), err)
582 582
 	}
583 583
 
584
-	err := createVxlan(vxlanName, n.vxlanID(s), n.maxMTU())
584
+	err := createVxlan(vxlanName, s.vni, n.maxMTU())
585 585
 	if err != nil {
586 586
 		return err
587 587
 	}
588 588
 
589 589
 	if err := sbox.AddInterface(vxlanName, "vxlan",
590 590
 		sbox.InterfaceOptions().Master(brName)); err != nil {
591
+		// If adding vxlan device to the overlay namespace fails, remove the bridge interface we
592
+		// already added to the namespace. This allows the caller to try the setup again.
593
+		for _, iface := range sbox.Info().Interfaces() {
594
+			if iface.SrcName() == brName {
595
+				if ierr := iface.Remove(); ierr != nil {
596
+					logrus.Errorf("removing bridge failed from ov ns %v failed, %v", n.sbox.Key(), ierr)
597
+				}
598
+			}
599
+		}
600
+
601
+		// Also, delete the vxlan interface. Since a global vni id is associated
602
+		// with the vxlan interface, an orphaned vxlan interface will result in
603
+		// failure of vxlan device creation if the vni is assigned to some other
604
+		// network.
605
+		if deleteErr := deleteInterface(vxlanName); deleteErr != nil {
606
+			logrus.Warnf("could not delete vxlan interface, %s, error %v, after config error, %v", vxlanName, deleteErr, err)
607
+		}
591 608
 		return fmt.Errorf("vxlan interface creation failed for subnet %q: %v", s.subnetIP.String(), err)
592 609
 	}
593 610
 
... ...
@@ -619,6 +658,7 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error
619 619
 	return nil
620 620
 }
621 621
 
622
+// Must be called with the network lock
622 623
 func (n *network) initSubnetSandbox(s *subnet, restore bool) error {
623 624
 	brName := n.generateBridgeName(s)
624 625
 	vxlanName := n.generateVxlanName(s)
... ...
@@ -633,10 +673,8 @@ func (n *network) initSubnetSandbox(s *subnet, restore bool) error {
633 633
 		}
634 634
 	}
635 635
 
636
-	n.Lock()
637 636
 	s.vxlanName = vxlanName
638 637
 	s.brName = brName
639
-	n.Unlock()
640 638
 
641 639
 	return nil
642 640
 }
... ...
@@ -677,11 +715,7 @@ func (n *network) cleanupStaleSandboxes() {
677 677
 }
678 678
 
679 679
 func (n *network) initSandbox(restore bool) error {
680
-	n.Lock()
681 680
 	n.initEpoch++
682
-	n.Unlock()
683
-
684
-	networkOnce.Do(networkOnceInit)
685 681
 
686 682
 	if !restore {
687 683
 		if hostMode {
... ...
@@ -711,12 +745,7 @@ func (n *network) initSandbox(restore bool) error {
711 711
 	}
712 712
 
713 713
 	// this is needed to let the peerAdd configure the sandbox
714
-	n.setSandbox(sbox)
715
-
716
-	if !restore {
717
-		// Initialize the sandbox with all the peers previously received from networkdb
718
-		n.driver.initSandboxPeerDB(n.id)
719
-	}
714
+	n.sbox = sbox
720 715
 
721 716
 	// If we are in swarm mode, we don't need anymore the watchMiss routine.
722 717
 	// This will save 1 thread and 1 netlink socket per network
... ...
@@ -734,7 +763,7 @@ func (n *network) initSandbox(restore bool) error {
734 734
 		tv := syscall.NsecToTimeval(soTimeout.Nanoseconds())
735 735
 		err = nlSock.SetReceiveTimeout(&tv)
736 736
 	})
737
-	n.setNetlinkSocket(nlSock)
737
+	n.nlSocket = nlSock
738 738
 
739 739
 	if err == nil {
740 740
 		go n.watchMiss(nlSock, key)
... ...
@@ -836,7 +865,6 @@ func (d *driver) restoreNetworkFromStore(nid string) *network {
836 836
 	if n != nil {
837 837
 		n.driver = d
838 838
 		n.endpoints = endpointTable{}
839
-		n.once = &sync.Once{}
840 839
 		d.networks[nid] = n
841 840
 	}
842 841
 	return n
... ...
@@ -844,11 +872,11 @@ func (d *driver) restoreNetworkFromStore(nid string) *network {
844 844
 
845 845
 func (d *driver) network(nid string) *network {
846 846
 	d.Lock()
847
-	defer d.Unlock()
848 847
 	n, ok := d.networks[nid]
849 848
 	if !ok {
850 849
 		n = d.restoreNetworkFromStore(nid)
851 850
 	}
851
+	d.Unlock()
852 852
 
853 853
 	return n
854 854
 }
... ...
@@ -869,26 +897,12 @@ func (d *driver) getNetworkFromStore(nid string) *network {
869 869
 func (n *network) sandbox() osl.Sandbox {
870 870
 	n.Lock()
871 871
 	defer n.Unlock()
872
-
873 872
 	return n.sbox
874 873
 }
875 874
 
876
-func (n *network) setSandbox(sbox osl.Sandbox) {
877
-	n.Lock()
878
-	n.sbox = sbox
879
-	n.Unlock()
880
-}
881
-
882
-func (n *network) setNetlinkSocket(nlSk *nl.NetlinkSocket) {
883
-	n.Lock()
884
-	n.nlSocket = nlSk
885
-	n.Unlock()
886
-}
887
-
888 875
 func (n *network) vxlanID(s *subnet) uint32 {
889 876
 	n.Lock()
890 877
 	defer n.Unlock()
891
-
892 878
 	return s.vni
893 879
 }
894 880
 
... ...
@@ -997,7 +1011,6 @@ func (n *network) SetValue(value []byte) error {
997 997
 				subnetIP: subnetIP,
998 998
 				gwIP:     gwIP,
999 999
 				vni:      vni,
1000
-				once:     &sync.Once{},
1001 1000
 			}
1002 1001
 			n.subnets = append(n.subnets, s)
1003 1002
 		} else {
... ...
@@ -1023,7 +1036,10 @@ func (n *network) writeToStore() error {
1023 1023
 }
1024 1024
 
1025 1025
 func (n *network) releaseVxlanID() ([]uint32, error) {
1026
-	if len(n.subnets) == 0 {
1026
+	n.Lock()
1027
+	nSubnets := len(n.subnets)
1028
+	n.Unlock()
1029
+	if nSubnets == 0 {
1027 1030
 		return nil, nil
1028 1031
 	}
1029 1032
 
... ...
@@ -1039,14 +1055,17 @@ func (n *network) releaseVxlanID() ([]uint32, error) {
1039 1039
 		}
1040 1040
 	}
1041 1041
 	var vnis []uint32
1042
+	n.Lock()
1042 1043
 	for _, s := range n.subnets {
1043 1044
 		if n.driver.vxlanIdm != nil {
1044
-			vni := n.vxlanID(s)
1045
-			vnis = append(vnis, vni)
1046
-			n.driver.vxlanIdm.Release(uint64(vni))
1045
+			vnis = append(vnis, s.vni)
1047 1046
 		}
1047
+		s.vni = 0
1048
+	}
1049
+	n.Unlock()
1048 1050
 
1049
-		n.setVxlanID(s, 0)
1051
+	for _, vni := range vnis {
1052
+		n.driver.vxlanIdm.Release(uint64(vni))
1050 1053
 	}
1051 1054
 
1052 1055
 	return vnis, nil
... ...
@@ -1054,7 +1073,7 @@ func (n *network) releaseVxlanID() ([]uint32, error) {
1054 1054
 
1055 1055
 func (n *network) obtainVxlanID(s *subnet) error {
1056 1056
 	//return if the subnet already has a vxlan id assigned
1057
-	if s.vni != 0 {
1057
+	if n.vxlanID(s) != 0 {
1058 1058
 		return nil
1059 1059
 	}
1060 1060
 
... ...
@@ -1067,7 +1086,7 @@ func (n *network) obtainVxlanID(s *subnet) error {
1067 1067
 			return fmt.Errorf("getting network %q from datastore failed %v", n.id, err)
1068 1068
 		}
1069 1069
 
1070
-		if s.vni == 0 {
1070
+		if n.vxlanID(s) == 0 {
1071 1071
 			vxlanID, err := n.driver.vxlanIdm.GetID(true)
1072 1072
 			if err != nil {
1073 1073
 				return fmt.Errorf("failed to allocate vxlan id: %v", err)
... ...
@@ -105,17 +105,6 @@ func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
105 105
 		logrus.Warnf("Failure during overlay endpoints restore: %v", err)
106 106
 	}
107 107
 
108
-	// If an error happened when the network join the sandbox during the endpoints restore
109
-	// we should reset it now along with the once variable, so that subsequent endpoint joins
110
-	// outside of the restore path can potentially fix the network join and succeed.
111
-	for nid, n := range d.networks {
112
-		if n.initErr != nil {
113
-			logrus.Infof("resetting init error and once variable for network %s after unsuccessful endpoint restore: %v", nid, n.initErr)
114
-			n.initErr = nil
115
-			n.once = &sync.Once{}
116
-		}
117
-	}
118
-
119 108
 	return dc.RegisterDriver(networkType, d, c)
120 109
 }
121 110
 
... ...
@@ -151,14 +140,10 @@ func (d *driver) restoreEndpoints() error {
151 151
 			return fmt.Errorf("could not find subnet for endpoint %s", ep.id)
152 152
 		}
153 153
 
154
-		if err := n.joinSandbox(true); err != nil {
154
+		if err := n.joinSandbox(s, true, true); err != nil {
155 155
 			return fmt.Errorf("restore network sandbox failed: %v", err)
156 156
 		}
157 157
 
158
-		if err := n.joinSubnetSandbox(s, true); err != nil {
159
-			return fmt.Errorf("restore subnet sandbox failed for %q: %v", s.subnetIP.String(), err)
160
-		}
161
-
162 158
 		Ifaces := make(map[string][]osl.IfaceOption)
163 159
 		vethIfaceOption := make([]osl.IfaceOption, 1)
164 160
 		vethIfaceOption = append(vethIfaceOption, n.sbox.InterfaceOptions().Master(s.brName))
... ...
@@ -166,10 +151,10 @@ func (d *driver) restoreEndpoints() error {
166 166
 
167 167
 		err := n.sbox.Restore(Ifaces, nil, nil, nil)
168 168
 		if err != nil {
169
+			n.leaveSandbox()
169 170
 			return fmt.Errorf("failed to restore overlay sandbox: %v", err)
170 171
 		}
171 172
 
172
-		n.incEndpointCount()
173 173
 		d.peerAdd(ep.nid, ep.id, ep.addr.IP, ep.addr.Mask, ep.mac, net.ParseIP(d.advertiseAddress), false, false, true)
174 174
 	}
175 175
 	return nil
... ...
@@ -7,7 +7,8 @@ import (
7 7
 	"sync"
8 8
 	"syscall"
9 9
 
10
-	"github.com/docker/libnetwork/common"
10
+	"github.com/docker/libnetwork/internal/caller"
11
+	"github.com/docker/libnetwork/internal/setmatrix"
11 12
 	"github.com/docker/libnetwork/osl"
12 13
 	"github.com/sirupsen/logrus"
13 14
 )
... ...
@@ -59,7 +60,7 @@ func (p *peerEntryDB) UnMarshalDB() peerEntry {
59 59
 
60 60
 type peerMap struct {
61 61
 	// set of peerEntry, note they have to be objects and not pointers to maintain the proper equality checks
62
-	mp common.SetMatrix
62
+	mp setmatrix.SetMatrix
63 63
 	sync.Mutex
64 64
 }
65 65
 
... ...
@@ -170,7 +171,7 @@ func (d *driver) peerDbAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask
170 170
 	pMap, ok := d.peerDb.mp[nid]
171 171
 	if !ok {
172 172
 		d.peerDb.mp[nid] = &peerMap{
173
-			mp: common.NewSetMatrix(),
173
+			mp: setmatrix.NewSetMatrix(),
174 174
 		}
175 175
 
176 176
 		pMap = d.peerDb.mp[nid]
... ...
@@ -297,7 +298,7 @@ func (d *driver) peerOpRoutine(ctx context.Context, ch chan *peerOperation) {
297 297
 }
298 298
 
299 299
 func (d *driver) peerInit(nid string) {
300
-	callerName := common.CallerName(1)
300
+	callerName := caller.Name(1)
301 301
 	d.peerOpCh <- &peerOperation{
302 302
 		opType:     peerOperationINIT,
303 303
 		networkID:  nid,
... ...
@@ -331,7 +332,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
331 331
 		l2Miss:     l2Miss,
332 332
 		l3Miss:     l3Miss,
333 333
 		localPeer:  localPeer,
334
-		callerName: common.CallerName(1),
334
+		callerName: caller.Name(1),
335 335
 	}
336 336
 }
337 337
 
... ...
@@ -384,7 +385,7 @@ func (d *driver) peerAddOp(nid, eid string, peerIP net.IP, peerIPMask net.IPMask
384 384
 		return fmt.Errorf("couldn't get vxlan id for %q: %v", s.subnetIP.String(), err)
385 385
 	}
386 386
 
387
-	if err := n.joinSubnetSandbox(s, false); err != nil {
387
+	if err := n.joinSandbox(s, false, false); err != nil {
388 388
 		return fmt.Errorf("subnet sandbox join failed for %q: %v", s.subnetIP.String(), err)
389 389
 	}
390 390
 
... ...
@@ -422,7 +423,7 @@ func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMas
422 422
 		peerIPMask: peerIPMask,
423 423
 		peerMac:    peerMac,
424 424
 		vtepIP:     vtep,
425
-		callerName: common.CallerName(1),
425
+		callerName: caller.Name(1),
426 426
 		localPeer:  localPeer,
427 427
 	}
428 428
 }
... ...
@@ -491,7 +492,7 @@ func (d *driver) peerFlush(nid string) {
491 491
 	d.peerOpCh <- &peerOperation{
492 492
 		opType:     peerOperationFLUSH,
493 493
 		networkID:  nid,
494
-		callerName: common.CallerName(1),
494
+		callerName: caller.Name(1),
495 495
 	}
496 496
 }
497 497
 
... ...
@@ -150,7 +150,7 @@ type JoinRequest struct {
150 150
 	Options    map[string]interface{}
151 151
 }
152 152
 
153
-// InterfaceName is the struct represetation of a pair of devices with source
153
+// InterfaceName is the struct representation of a pair of devices with source
154 154
 // and destination, for the purposes of putting an endpoint into a container.
155 155
 type InterfaceName struct {
156 156
 	SrcName   string
... ...
@@ -54,7 +54,7 @@ type IPAMNotifyFunc func(name string, driver ipamapi.Ipam, cap *ipamapi.Capabili
54 54
 // DriverNotifyFunc defines the notify function signature when a new network driver gets registered.
55 55
 type DriverNotifyFunc func(name string, driver driverapi.Driver, capability driverapi.Capability) error
56 56
 
57
-// New retruns a new driver registry handle.
57
+// New returns a new driver registry handle.
58 58
 func New(lDs, gDs interface{}, dfn DriverNotifyFunc, ifn IPAMNotifyFunc, pg plugingetter.PluginGetter) (*DrvRegistry, error) {
59 59
 	r := &DrvRegistry{
60 60
 		drivers:      make(driverTable),
61 61
new file mode 100644
... ...
@@ -0,0 +1,29 @@
0
+package caller
1
+
2
+import (
3
+	"runtime"
4
+	"strings"
5
+)
6
+
7
+func callerInfo(i int) string {
8
+	ptr, _, _, ok := runtime.Caller(i)
9
+	fName := "unknown"
10
+	if ok {
11
+		f := runtime.FuncForPC(ptr)
12
+		if f != nil {
13
+			// f.Name() is like: github.com/docker/libnetwork/caller.MethodName
14
+			tmp := strings.Split(f.Name(), ".")
15
+			if len(tmp) > 0 {
16
+				fName = tmp[len(tmp)-1]
17
+			}
18
+		}
19
+	}
20
+
21
+	return fName
22
+}
23
+
24
+// Name returns the name of the function at the specified level
25
+// level == 0 means current method name
26
+func Name(level int) string {
27
+	return callerInfo(2 + level)
28
+}
0 29
new file mode 100644
... ...
@@ -0,0 +1,135 @@
0
+package setmatrix
1
+
2
+import (
3
+	"sync"
4
+
5
+	mapset "github.com/deckarep/golang-set"
6
+)
7
+
8
+// SetMatrix is a map of Sets
9
+type SetMatrix interface {
10
+	// Get returns the members of the set for a specific key as a slice.
11
+	Get(key string) ([]interface{}, bool)
12
+	// Contains is used to verify if an element is in a set for a specific key
13
+	// returns true if the element is in the set
14
+	// returns true if there is a set for the key
15
+	Contains(key string, value interface{}) (bool, bool)
16
+	// Insert inserts the value in the set of a key
17
+	// returns true if the value is inserted (was not already in the set), false otherwise
18
+	// returns also the length of the set for the key
19
+	Insert(key string, value interface{}) (bool, int)
20
+	// Remove removes the value in the set for a specific key
21
+	// returns true if the value is deleted, false otherwise
22
+	// returns also the length of the set for the key
23
+	Remove(key string, value interface{}) (bool, int)
24
+	// Cardinality returns the number of elements in the set for a key
25
+	// returns false if the set is not present
26
+	Cardinality(key string) (int, bool)
27
+	// String returns the string version of the set, empty otherwise
28
+	// returns false if the set is not present
29
+	String(key string) (string, bool)
30
+	// Returns all the keys in the map
31
+	Keys() []string
32
+}
33
+
34
+type setMatrix struct {
35
+	matrix map[string]mapset.Set
36
+
37
+	sync.Mutex
38
+}
39
+
40
+// NewSetMatrix creates a new set matrix object
41
+func NewSetMatrix() SetMatrix {
42
+	s := &setMatrix{}
43
+	s.init()
44
+	return s
45
+}
46
+
47
+func (s *setMatrix) init() {
48
+	s.matrix = make(map[string]mapset.Set)
49
+}
50
+
51
+func (s *setMatrix) Get(key string) ([]interface{}, bool) {
52
+	s.Lock()
53
+	defer s.Unlock()
54
+	set, ok := s.matrix[key]
55
+	if !ok {
56
+		return nil, ok
57
+	}
58
+	return set.ToSlice(), ok
59
+}
60
+
61
+func (s *setMatrix) Contains(key string, value interface{}) (bool, bool) {
62
+	s.Lock()
63
+	defer s.Unlock()
64
+	set, ok := s.matrix[key]
65
+	if !ok {
66
+		return false, ok
67
+	}
68
+	return set.Contains(value), ok
69
+}
70
+
71
+func (s *setMatrix) Insert(key string, value interface{}) (bool, int) {
72
+	s.Lock()
73
+	defer s.Unlock()
74
+	set, ok := s.matrix[key]
75
+	if !ok {
76
+		s.matrix[key] = mapset.NewSet()
77
+		s.matrix[key].Add(value)
78
+		return true, 1
79
+	}
80
+
81
+	return set.Add(value), set.Cardinality()
82
+}
83
+
84
+func (s *setMatrix) Remove(key string, value interface{}) (bool, int) {
85
+	s.Lock()
86
+	defer s.Unlock()
87
+	set, ok := s.matrix[key]
88
+	if !ok {
89
+		return false, 0
90
+	}
91
+
92
+	var removed bool
93
+	if set.Contains(value) {
94
+		set.Remove(value)
95
+		removed = true
96
+		// If the set is empty remove it from the matrix
97
+		if set.Cardinality() == 0 {
98
+			delete(s.matrix, key)
99
+		}
100
+	}
101
+
102
+	return removed, set.Cardinality()
103
+}
104
+
105
+func (s *setMatrix) Cardinality(key string) (int, bool) {
106
+	s.Lock()
107
+	defer s.Unlock()
108
+	set, ok := s.matrix[key]
109
+	if !ok {
110
+		return 0, ok
111
+	}
112
+
113
+	return set.Cardinality(), ok
114
+}
115
+
116
+func (s *setMatrix) String(key string) (string, bool) {
117
+	s.Lock()
118
+	defer s.Unlock()
119
+	set, ok := s.matrix[key]
120
+	if !ok {
121
+		return "", ok
122
+	}
123
+	return set.String(), ok
124
+}
125
+
126
+func (s *setMatrix) Keys() []string {
127
+	s.Lock()
128
+	defer s.Unlock()
129
+	keys := make([]string, 0, len(s.matrix))
130
+	for k := range s.matrix {
131
+		keys = append(keys, k)
132
+	}
133
+	return keys
134
+}
... ...
@@ -66,7 +66,7 @@ func newConnection() (*Conn, error) {
66 66
 	return c, nil
67 67
 }
68 68
 
69
-// Innitialize D-Bus connection.
69
+// Initialize D-Bus connection.
70 70
 func (c *Conn) initConnection() error {
71 71
 	var err error
72 72
 
... ...
@@ -477,7 +477,7 @@ func raw(args ...string) ([]byte, error) {
477 477
 	return filterOutput(startTime, output, args...), err
478 478
 }
479 479
 
480
-// RawCombinedOutput inernally calls the Raw function and returns a non nil
480
+// RawCombinedOutput internally calls the Raw function and returns a non nil
481 481
 // error if Raw returned a non nil error or a non empty output
482 482
 func RawCombinedOutput(args ...string) error {
483 483
 	if output, err := Raw(args...); err != nil || len(output) != 0 {
... ...
@@ -100,7 +100,7 @@ func fillService(s *Service) nl.NetlinkRequestData {
100 100
 	return cmdAttr
101 101
 }
102 102
 
103
-func fillDestinaton(d *Destination) nl.NetlinkRequestData {
103
+func fillDestination(d *Destination) nl.NetlinkRequestData {
104 104
 	cmdAttr := nl.NewRtAttr(ipvsCmdAttrDest, nil)
105 105
 
106 106
 	nl.NewRtAttrChild(cmdAttr, ipvsDestAttrAddress, rawIPData(d.Address))
... ...
@@ -134,7 +134,7 @@ func (i *Handle) doCmdwithResponse(s *Service, d *Destination, cmd uint8) ([][]b
134 134
 		}
135 135
 
136 136
 	} else {
137
-		req.AddData(fillDestinaton(d))
137
+		req.AddData(fillDestination(d))
138 138
 	}
139 139
 
140 140
 	res, err := execute(i.sock, req, 0)
... ...
@@ -9,11 +9,11 @@ import (
9 9
 	"time"
10 10
 
11 11
 	"github.com/docker/docker/pkg/stringid"
12
-	"github.com/docker/libnetwork/common"
13 12
 	"github.com/docker/libnetwork/config"
14 13
 	"github.com/docker/libnetwork/datastore"
15 14
 	"github.com/docker/libnetwork/driverapi"
16 15
 	"github.com/docker/libnetwork/etchosts"
16
+	"github.com/docker/libnetwork/internal/setmatrix"
17 17
 	"github.com/docker/libnetwork/ipamapi"
18 18
 	"github.com/docker/libnetwork/netlabel"
19 19
 	"github.com/docker/libnetwork/netutils"
... ...
@@ -88,7 +88,7 @@ type NetworkInfo interface {
88 88
 type EndpointWalker func(ep Endpoint) bool
89 89
 
90 90
 // ipInfo is the reverse mapping from IP to service name to serve the PTR query.
91
-// extResolver is set if an externl server resolves a service name to this IP.
91
+// extResolver is set if an external server resolves a service name to this IP.
92 92
 // Its an indication to defer PTR queries also to that external server.
93 93
 type ipInfo struct {
94 94
 	name        string
... ...
@@ -104,9 +104,9 @@ type svcMapEntry struct {
104 104
 }
105 105
 
106 106
 type svcInfo struct {
107
-	svcMap     common.SetMatrix
108
-	svcIPv6Map common.SetMatrix
109
-	ipMap      common.SetMatrix
107
+	svcMap     setmatrix.SetMatrix
108
+	svcIPv6Map setmatrix.SetMatrix
109
+	ipMap      setmatrix.SetMatrix
110 110
 	service    map[string][]servicePorts
111 111
 }
112 112
 
... ...
@@ -1353,7 +1353,7 @@ func (n *network) updateSvcRecord(ep *endpoint, localEps []*endpoint, isAdd bool
1353 1353
 	}
1354 1354
 }
1355 1355
 
1356
-func addIPToName(ipMap common.SetMatrix, name, serviceID string, ip net.IP) {
1356
+func addIPToName(ipMap setmatrix.SetMatrix, name, serviceID string, ip net.IP) {
1357 1357
 	reverseIP := netutils.ReverseIP(ip.String())
1358 1358
 	ipMap.Insert(reverseIP, ipInfo{
1359 1359
 		name:      name,
... ...
@@ -1361,7 +1361,7 @@ func addIPToName(ipMap common.SetMatrix, name, serviceID string, ip net.IP) {
1361 1361
 	})
1362 1362
 }
1363 1363
 
1364
-func delIPToName(ipMap common.SetMatrix, name, serviceID string, ip net.IP) {
1364
+func delIPToName(ipMap setmatrix.SetMatrix, name, serviceID string, ip net.IP) {
1365 1365
 	reverseIP := netutils.ReverseIP(ip.String())
1366 1366
 	ipMap.Remove(reverseIP, ipInfo{
1367 1367
 		name:      name,
... ...
@@ -1369,14 +1369,14 @@ func delIPToName(ipMap common.SetMatrix, name, serviceID string, ip net.IP) {
1369 1369
 	})
1370 1370
 }
1371 1371
 
1372
-func addNameToIP(svcMap common.SetMatrix, name, serviceID string, epIP net.IP) {
1372
+func addNameToIP(svcMap setmatrix.SetMatrix, name, serviceID string, epIP net.IP) {
1373 1373
 	svcMap.Insert(name, svcMapEntry{
1374 1374
 		ip:        epIP.String(),
1375 1375
 		serviceID: serviceID,
1376 1376
 	})
1377 1377
 }
1378 1378
 
1379
-func delNameToIP(svcMap common.SetMatrix, name, serviceID string, epIP net.IP) {
1379
+func delNameToIP(svcMap setmatrix.SetMatrix, name, serviceID string, epIP net.IP) {
1380 1380
 	svcMap.Remove(name, svcMapEntry{
1381 1381
 		ip:        epIP.String(),
1382 1382
 		serviceID: serviceID,
... ...
@@ -1399,9 +1399,9 @@ func (n *network) addSvcRecords(eID, name, serviceID string, epIP, epIPv6 net.IP
1399 1399
 	sr, ok := c.svcRecords[n.ID()]
1400 1400
 	if !ok {
1401 1401
 		sr = svcInfo{
1402
-			svcMap:     common.NewSetMatrix(),
1403
-			svcIPv6Map: common.NewSetMatrix(),
1404
-			ipMap:      common.NewSetMatrix(),
1402
+			svcMap:     setmatrix.NewSetMatrix(),
1403
+			svcIPv6Map: setmatrix.NewSetMatrix(),
1404
+			ipMap:      setmatrix.NewSetMatrix(),
1405 1405
 		}
1406 1406
 		c.svcRecords[n.ID()] = sr
1407 1407
 	}
... ...
@@ -1654,7 +1654,7 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error {
1654 1654
 					return types.BadRequestErrorf("non parsable secondary ip address (%s:%s) passed for network %s", k, v, n.Name())
1655 1655
 				}
1656 1656
 				if !d.Pool.Contains(ip) {
1657
-					return types.ForbiddenErrorf("auxilairy address: (%s:%s) must belong to the master pool: %s", k, v, d.Pool)
1657
+					return types.ForbiddenErrorf("auxiliary address: (%s:%s) must belong to the master pool: %s", k, v, d.Pool)
1658 1658
 				}
1659 1659
 				// Attempt reservation in the container addressable pool, silent the error if address does not belong to that pool
1660 1660
 				if d.IPAMData.AuxAddresses[k], _, err = ipam.RequestAddress(d.PoolID, ip, nil); err != nil && err != ipamapi.ErrIPOutOfRange {
... ...
@@ -2036,7 +2036,7 @@ func (n *network) ResolveService(name string) ([]*net.SRV, []net.IP) {
2036 2036
 
2037 2037
 	logrus.Debugf("Service name To resolve: %v", name)
2038 2038
 
2039
-	// There are DNS implementaions that allow SRV queries for names not in
2039
+	// There are DNS implementations that allow SRV queries for names not in
2040 2040
 	// the format defined by RFC 2782. Hence specific validations checks are
2041 2041
 	// not done
2042 2042
 	parts := strings.Split(name, ".")
... ...
@@ -2126,7 +2126,7 @@ func (n *network) lbEndpointName() string {
2126 2126
 func (n *network) createLoadBalancerSandbox() (retErr error) {
2127 2127
 	sandboxName := n.lbSandboxName()
2128 2128
 	// Mark the sandbox to be a load balancer
2129
-	sbOptions := []SandboxOption{OptionLoadBalancer()}
2129
+	sbOptions := []SandboxOption{OptionLoadBalancer(n.id)}
2130 2130
 	if n.ingress {
2131 2131
 		sbOptions = append(sbOptions, OptionIngress())
2132 2132
 	}
... ...
@@ -243,7 +243,7 @@ func (nDB *NetworkDB) clusterLeave() error {
243 243
 }
244 244
 
245 245
 func (nDB *NetworkDB) triggerFunc(stagger time.Duration, C <-chan time.Time, f func()) {
246
-	// Use a random stagger to avoid syncronizing
246
+	// Use a random stagger to avoid synchronizing
247 247
 	randStagger := time.Duration(uint64(rnd.Int63()) % uint64(stagger))
248 248
 	select {
249 249
 	case <-time.After(randStagger):
... ...
@@ -58,7 +58,7 @@ type NetworkDB struct {
58 58
 	// List of all peer nodes which have left
59 59
 	leftNodes map[string]*node
60 60
 
61
-	// A multi-dimensional map of network/node attachmemts. The
61
+	// A multi-dimensional map of network/node attachments. The
62 62
 	// first key is a node name and the second key is a network ID
63 63
 	// for the network that node is participating in.
64 64
 	networks map[string]map[string]*network
... ...
@@ -153,7 +153,7 @@ type network struct {
153 153
 	entriesNumber int
154 154
 }
155 155
 
156
-// Config represents the configuration of the networdb instance and
156
+// Config represents the configuration of the networkdb instance and
157 157
 // can be passed by the caller.
158 158
 type Config struct {
159 159
 	// NodeID is the node unique identifier of the node when is part of the cluster
... ...
@@ -48,7 +48,7 @@ type MessageType int32
48 48
 
49 49
 const (
50 50
 	MessageTypeInvalid MessageType = 0
51
-	// NetworEvent message type is used to communicate network
51
+	// NetworkEvent message type is used to communicate network
52 52
 	// attachments on the node.
53 53
 	MessageTypeNetworkEvent MessageType = 1
54 54
 	// TableEvent message type is used to communicate any table
... ...
@@ -66,7 +66,7 @@ const (
66 66
 	// which is a pack of many message of above types, packed into
67 67
 	// a single compound message.
68 68
 	MessageTypeCompound MessageType = 5
69
-	// NodeEvent message type is used to communicare node
69
+	// NodeEvent message type is used to communicate node
70 70
 	// join/leave events in the cluster
71 71
 	MessageTypeNodeEvent MessageType = 6
72 72
 )
... ...
@@ -19,7 +19,7 @@ enum MessageType {
19 19
 
20 20
 	INVALID = 0 [(gogoproto.enumvalue_customname) = "MessageTypeInvalid"];
21 21
 
22
-	// NetworEvent message type is used to communicate network
22
+	// NetworkEvent message type is used to communicate network
23 23
 	// attachments on the node.
24 24
 	NETWORK_EVENT = 1 [(gogoproto.enumvalue_customname) = "MessageTypeNetworkEvent"];
25 25
 
... ...
@@ -42,7 +42,7 @@ enum MessageType {
42 42
 	// a single compound message.
43 43
 	COMPOUND = 5 [(gogoproto.enumvalue_customname) = "MessageTypeCompound"];
44 44
 
45
-	// NodeEvent message type is used to communicare node
45
+	// NodeEvent message type is used to communicate node
46 46
 	// join/leave events in the cluster
47 47
 	NODE_EVENT = 6 [(gogoproto.enumvalue_customname) = "MessageTypeNodeEvent"];
48 48
 }
... ...
@@ -6,8 +6,8 @@ import (
6 6
 	"net/http"
7 7
 	"strings"
8 8
 
9
-	"github.com/docker/libnetwork/common"
10 9
 	"github.com/docker/libnetwork/diagnostic"
10
+	"github.com/docker/libnetwork/internal/caller"
11 11
 	"github.com/sirupsen/logrus"
12 12
 )
13 13
 
... ...
@@ -37,7 +37,7 @@ func dbJoin(ctx interface{}, w http.ResponseWriter, r *http.Request) {
37 37
 	_, json := diagnostic.ParseHTTPFormOptions(r)
38 38
 
39 39
 	// audit logs
40
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
40
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
41 41
 	log.Info("join cluster")
42 42
 
43 43
 	if len(r.Form["members"]) < 1 {
... ...
@@ -70,7 +70,7 @@ func dbPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) {
70 70
 	_, json := diagnostic.ParseHTTPFormOptions(r)
71 71
 
72 72
 	// audit logs
73
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
73
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
74 74
 	log.Info("network peers")
75 75
 
76 76
 	if len(r.Form["nid"]) < 1 {
... ...
@@ -104,7 +104,7 @@ func dbClusterPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) {
104 104
 	_, json := diagnostic.ParseHTTPFormOptions(r)
105 105
 
106 106
 	// audit logs
107
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
107
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
108 108
 	log.Info("cluster peers")
109 109
 
110 110
 	nDB, ok := ctx.(*NetworkDB)
... ...
@@ -127,7 +127,7 @@ func dbCreateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
127 127
 	unsafe, json := diagnostic.ParseHTTPFormOptions(r)
128 128
 
129 129
 	// audit logs
130
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
130
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
131 131
 	log.Info("create entry")
132 132
 
133 133
 	if len(r.Form["tname"]) < 1 ||
... ...
@@ -176,7 +176,7 @@ func dbUpdateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
176 176
 	unsafe, json := diagnostic.ParseHTTPFormOptions(r)
177 177
 
178 178
 	// audit logs
179
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
179
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
180 180
 	log.Info("update entry")
181 181
 
182 182
 	if len(r.Form["tname"]) < 1 ||
... ...
@@ -224,7 +224,7 @@ func dbDeleteEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
224 224
 	_, json := diagnostic.ParseHTTPFormOptions(r)
225 225
 
226 226
 	// audit logs
227
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
227
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
228 228
 	log.Info("delete entry")
229 229
 
230 230
 	if len(r.Form["tname"]) < 1 ||
... ...
@@ -261,7 +261,7 @@ func dbGetEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
261 261
 	unsafe, json := diagnostic.ParseHTTPFormOptions(r)
262 262
 
263 263
 	// audit logs
264
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
264
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
265 265
 	log.Info("get entry")
266 266
 
267 267
 	if len(r.Form["tname"]) < 1 ||
... ...
@@ -307,7 +307,7 @@ func dbJoinNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
307 307
 	_, json := diagnostic.ParseHTTPFormOptions(r)
308 308
 
309 309
 	// audit logs
310
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
310
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
311 311
 	log.Info("join network")
312 312
 
313 313
 	if len(r.Form["nid"]) < 1 {
... ...
@@ -339,7 +339,7 @@ func dbLeaveNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
339 339
 	_, json := diagnostic.ParseHTTPFormOptions(r)
340 340
 
341 341
 	// audit logs
342
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
342
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
343 343
 	log.Info("leave network")
344 344
 
345 345
 	if len(r.Form["nid"]) < 1 {
... ...
@@ -371,7 +371,7 @@ func dbGetTable(ctx interface{}, w http.ResponseWriter, r *http.Request) {
371 371
 	unsafe, json := diagnostic.ParseHTTPFormOptions(r)
372 372
 
373 373
 	// audit logs
374
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
374
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
375 375
 	log.Info("get table")
376 376
 
377 377
 	if len(r.Form["tname"]) < 1 ||
... ...
@@ -419,7 +419,7 @@ func dbNetworkStats(ctx interface{}, w http.ResponseWriter, r *http.Request) {
419 419
 	_, json := diagnostic.ParseHTTPFormOptions(r)
420 420
 
421 421
 	// audit logs
422
-	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
422
+	log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
423 423
 	log.Info("network stats")
424 424
 
425 425
 	if len(r.Form["nid"]) < 1 {
... ...
@@ -289,6 +289,16 @@ func (n *networkNamespace) AddInterface(srcName, dstPrefix string, options ...If
289 289
 
290 290
 	// Configure the interface now this is moved in the proper namespace.
291 291
 	if err := configureInterface(nlh, iface, i); err != nil {
292
+		// If configuring the device fails move it back to the host namespace
293
+		// and change the name back to the source name. This allows the caller
294
+		// to properly cleanup the interface. Its important especially for
295
+		// interfaces with global attributes, ex: vni id for vxlan interfaces.
296
+		if nerr := nlh.LinkSetName(iface, i.SrcName()); nerr != nil {
297
+			logrus.Errorf("renaming interface (%s->%s) failed, %v after config error %v", i.DstName(), i.SrcName(), nerr, err)
298
+		}
299
+		if nerr := nlh.LinkSetNsFd(iface, ns.ParseHandlerInt()); nerr != nil {
300
+			logrus.Errorf("moving inteface %s to host ns failed, %v, after config error %v", i.SrcName(), nerr, err)
301
+		}
292 302
 		return err
293 303
 	}
294 304
 
... ...
@@ -2,7 +2,7 @@ package kernel
2 2
 
3 3
 type conditionalCheck func(val1, val2 string) bool
4 4
 
5
-// OSValue represents a tuple, value defired, check function when to apply the value
5
+// OSValue represents a tuple, value defined, check function when to apply the value
6 6
 type OSValue struct {
7 7
 	Value   string
8 8
 	CheckFn conditionalCheck
... ...
@@ -394,10 +394,13 @@ func (n *networkNamespace) InvokeFunc(f func()) error {
394 394
 // InitOSContext initializes OS context while configuring network resources
395 395
 func InitOSContext() func() {
396 396
 	runtime.LockOSThread()
397
+	if err := ns.SetNamespace(); err != nil {
398
+		logrus.Error(err)
399
+	}
397 400
 	return runtime.UnlockOSThread
398 401
 }
399 402
 
400
-func nsInvoke(path string, prefunc, postfunc func(int) error) error {
403
+func nsInvoke(path string, prefunc func(nsFD int) error, postfunc func(callerFD int) error) error {
401 404
 	defer InitOSContext()()
402 405
 
403 406
 	newNs, err := netns.GetFromPath(path)
... ...
@@ -412,14 +415,10 @@ func nsInvoke(path string, prefunc, postfunc func(int) error) error {
412 412
 		return fmt.Errorf("failed in prefunc: %v", err)
413 413
 	}
414 414
 
415
-	// save the current namespace (host namespace)
416
-	curNs, _ := netns.Get()
417 415
 	if err = netns.Set(newNs); err != nil {
418 416
 		return err
419 417
 	}
420
-	defer curNs.Close()
421
-	// will restore the previous namespace before unlocking the thread
422
-	defer netns.Set(curNs)
418
+	defer ns.SetNamespace()
423 419
 
424 420
 	// Invoked after the namespace switch.
425 421
 	return postfunc(ns.ParseHandlerInt())
... ...
@@ -652,10 +651,7 @@ func (n *networkNamespace) ApplyOSTweaks(types []SandboxType) {
652 652
 	for _, t := range types {
653 653
 		switch t {
654 654
 		case SandboxTypeLoadBalancer:
655
-			nsInvoke(n.nsPath(),
656
-				func(nsFD int) error { return nil },
657
-				func(callerFD int) error { kernel.ApplyOSTweaks(loadBalancerConfig); return nil },
658
-			)
655
+			kernel.ApplyOSTweaks(loadBalancerConfig)
659 656
 		}
660 657
 	}
661 658
 }
... ...
@@ -14,6 +14,11 @@ import (
14 14
 	"github.com/sirupsen/logrus"
15 15
 )
16 16
 
17
+const (
18
+	// DefaultResolvConf points to the default file used for dns configuration on a linux machine
19
+	DefaultResolvConf = "/etc/resolv.conf"
20
+)
21
+
17 22
 var (
18 23
 	// Note: the default IPv4 & IPv6 resolvers are set to Google's Public DNS
19 24
 	defaultIPv4Dns = []string{"nameserver 8.8.8.8", "nameserver 8.8.4.4"}
... ...
@@ -50,15 +55,7 @@ type File struct {
50 50
 
51 51
 // Get returns the contents of /etc/resolv.conf and its hash
52 52
 func Get() (*File, error) {
53
-	resolv, err := ioutil.ReadFile("/etc/resolv.conf")
54
-	if err != nil {
55
-		return nil, err
56
-	}
57
-	hash, err := ioutils.HashData(bytes.NewReader(resolv))
58
-	if err != nil {
59
-		return nil, err
60
-	}
61
-	return &File{Content: resolv, Hash: hash}, nil
53
+	return GetSpecific(DefaultResolvConf)
62 54
 }
63 55
 
64 56
 // GetSpecific returns the contents of the user specified resolv.conf file and its hash
... ...
@@ -35,7 +35,7 @@ type Resolver interface {
35 35
 }
36 36
 
37 37
 // DNSBackend represents a backend DNS resolver used for DNS name
38
-// resolution. All the queries to the resolver are forwared to the
38
+// resolution. All the queries to the resolver are forwarded to the
39 39
 // backend resolver.
40 40
 type DNSBackend interface {
41 41
 	// ResolveName resolves a service name to an IPv4 or IPv6 address by searching
... ...
@@ -84,6 +84,7 @@ type sandbox struct {
84 84
 	ingress            bool
85 85
 	ndotsSet           bool
86 86
 	oslTypes           []osl.SandboxType // slice of properties of this sandbox
87
+	loadBalancerNID    string            // NID that this SB is a load balancer for
87 88
 	sync.Mutex
88 89
 	// This mutex is used to serialize service related operation for an endpoint
89 90
 	// The lock is here because the endpoint is saved into the store so is not unique
... ...
@@ -467,7 +468,7 @@ func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
467 467
 
468 468
 	logrus.Debugf("Service name To resolve: %v", name)
469 469
 
470
-	// There are DNS implementaions that allow SRV queries for names not in
470
+	// There are DNS implementations that allow SRV queries for names not in
471 471
 	// the format defined by RFC 2782. Hence specific validations checks are
472 472
 	// not done
473 473
 	parts := strings.Split(name, ".")
... ...
@@ -1098,8 +1099,8 @@ func OptionDNSOptions(options string) SandboxOption {
1098 1098
 	}
1099 1099
 }
1100 1100
 
1101
-// OptionUseDefaultSandbox function returns an option setter for using default sandbox to
1102
-// be passed to container Create method.
1101
+// OptionUseDefaultSandbox function returns an option setter for using default sandbox
1102
+// (host namespace) to be passed to container Create method.
1103 1103
 func OptionUseDefaultSandbox() SandboxOption {
1104 1104
 	return func(sb *sandbox) {
1105 1105
 		sb.config.useDefaultSandBox = true
... ...
@@ -1169,8 +1170,9 @@ func OptionIngress() SandboxOption {
1169 1169
 
1170 1170
 // OptionLoadBalancer function returns an option setter for marking a
1171 1171
 // sandbox as a load balancer sandbox.
1172
-func OptionLoadBalancer() SandboxOption {
1172
+func OptionLoadBalancer(nid string) SandboxOption {
1173 1173
 	return func(sb *sandbox) {
1174
+		sb.loadBalancerNID = nid
1174 1175
 		sb.oslTypes = append(sb.oslTypes, osl.SandboxTypeLoadBalancer)
1175 1176
 	}
1176 1177
 }
... ...
@@ -81,7 +81,9 @@ func (sb *sandbox) buildHostsFile() error {
81 81
 	}
82 82
 
83 83
 	// This is for the host mode networking
84
-	if sb.config.originHostsPath != "" {
84
+	if sb.config.useDefaultSandBox && len(sb.config.extraHosts) == 0 {
85
+		// We are working under the assumption that the origin file option had been properly expressed by the upper layer
86
+		// if not here we are going to error out
85 87
 		if err := copyFile(sb.config.originHostsPath, sb.config.hostsPath); err != nil && !os.IsNotExist(err) {
86 88
 			return types.InternalErrorf("could not copy source hosts file %s to %s: %v", sb.config.originHostsPath, sb.config.hostsPath, err)
87 89
 		}
... ...
@@ -190,8 +192,13 @@ func (sb *sandbox) setupDNS() error {
190 190
 		return err
191 191
 	}
192 192
 
193
-	// This is for the host mode networking
194
-	if sb.config.originResolvConfPath != "" {
193
+	// When the user specify a conainter in the host namespace and do no have any dns option specified
194
+	// we just copy the host resolv.conf from the host itself
195
+	if sb.config.useDefaultSandBox &&
196
+		len(sb.config.dnsList) == 0 && len(sb.config.dnsSearchList) == 0 && len(sb.config.dnsOptionsList) == 0 {
197
+
198
+		// We are working under the assumption that the origin file option had been properly expressed by the upper layer
199
+		// if not here we are going to error out
195 200
 		if err := copyFile(sb.config.originResolvConfPath, sb.config.resolvConfPath); err != nil {
196 201
 			if !os.IsNotExist(err) {
197 202
 				return fmt.Errorf("could not copy source resolv.conf file %s to %s: %v", sb.config.originResolvConfPath, sb.config.resolvConfPath, err)
... ...
@@ -204,7 +211,12 @@ func (sb *sandbox) setupDNS() error {
204 204
 		return nil
205 205
 	}
206 206
 
207
-	currRC, err := resolvconf.Get()
207
+	originResolvConfPath := sb.config.originResolvConfPath
208
+	if originResolvConfPath == "" {
209
+		// if not specified fallback to default /etc/resolv.conf
210
+		originResolvConfPath = resolvconf.DefaultResolvConf
211
+	}
212
+	currRC, err := resolvconf.GetSpecific(originResolvConfPath)
208 213
 	if err != nil {
209 214
 		if !os.IsNotExist(err) {
210 215
 			return err
... ...
@@ -241,7 +253,7 @@ func (sb *sandbox) setupDNS() error {
241 241
 		sb.setExternalResolvers(newRC.Content, types.IPv4, false)
242 242
 	} else {
243 243
 		// If the host resolv.conf file has 127.0.0.x container should
244
-		// use the host restolver for queries. This is supported by the
244
+		// use the host resolver for queries. This is supported by the
245 245
 		// docker embedded DNS server. Hence save the external resolvers
246 246
 		// before filtering it out.
247 247
 		sb.setExternalResolvers(currRC.Content, types.IPv4, true)
... ...
@@ -271,7 +283,7 @@ func (sb *sandbox) updateDNS(ipv6Enabled bool) error {
271 271
 	)
272 272
 
273 273
 	// This is for the host mode networking
274
-	if sb.config.originResolvConfPath != "" {
274
+	if sb.config.useDefaultSandBox {
275 275
 		return nil
276 276
 	}
277 277
 
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"net"
6 6
 	"sync"
7 7
 
8
-	"github.com/docker/libnetwork/common"
8
+	"github.com/docker/libnetwork/internal/setmatrix"
9 9
 )
10 10
 
11 11
 var (
... ...
@@ -54,7 +54,7 @@ type service struct {
54 54
 	// associated with it. At stable state the endpoint ID expected is 1
55 55
 	// but during transition and service change it is possible to have
56 56
 	// temporary more than 1
57
-	ipToEndpoint common.SetMatrix
57
+	ipToEndpoint setmatrix.SetMatrix
58 58
 
59 59
 	deleted bool
60 60
 
... ...
@@ -5,7 +5,7 @@ package libnetwork
5 5
 import (
6 6
 	"net"
7 7
 
8
-	"github.com/docker/libnetwork/common"
8
+	"github.com/docker/libnetwork/internal/setmatrix"
9 9
 	"github.com/sirupsen/logrus"
10 10
 )
11 11
 
... ...
@@ -139,7 +139,7 @@ func newService(name string, id string, ingressPorts []*PortConfig, serviceAlias
139 139
 		ingressPorts:  ingressPorts,
140 140
 		loadBalancers: make(map[string]*loadBalancer),
141 141
 		aliases:       serviceAliases,
142
-		ipToEndpoint:  common.NewSetMatrix(),
142
+		ipToEndpoint:  setmatrix.NewSetMatrix(),
143 143
 	}
144 144
 }
145 145
 
... ...
@@ -27,7 +27,7 @@ import (
27 27
 
28 28
 func init() {
29 29
 	reexec.Register("fwmarker", fwMarker)
30
-	reexec.Register("redirecter", redirecter)
30
+	reexec.Register("redirector", redirector)
31 31
 }
32 32
 
33 33
 // Populate all loadbalancers on the network that the passed endpoint
... ...
@@ -431,7 +431,7 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro
431 431
 // DOCKER-USER so the user is able to filter packet first.
432 432
 // The second rule should be jump to INGRESS-CHAIN.
433 433
 // This chain has the rules to allow access to the published ports for swarm tasks
434
-// from local bridge networks and docker_gwbridge (ie:taks on other swarm netwroks)
434
+// from local bridge networks and docker_gwbridge (ie:taks on other swarm networks)
435 435
 func arrangeIngressFilterRule() {
436 436
 	if iptables.ExistChain(ingressChain, iptables.Filter) {
437 437
 		if iptables.Exists(iptables.Filter, "FORWARD", "-j", ingressChain) {
... ...
@@ -668,7 +668,7 @@ func addRedirectRules(path string, eIP *net.IPNet, ingressPorts []*PortConfig) e
668 668
 
669 669
 	cmd := &exec.Cmd{
670 670
 		Path:   reexec.Self(),
671
-		Args:   append([]string{"redirecter"}, path, eIP.String(), ingressPortsFile),
671
+		Args:   append([]string{"redirector"}, path, eIP.String(), ingressPortsFile),
672 672
 		Stdout: os.Stdout,
673 673
 		Stderr: os.Stderr,
674 674
 	}
... ...
@@ -680,8 +680,8 @@ func addRedirectRules(path string, eIP *net.IPNet, ingressPorts []*PortConfig) e
680 680
 	return nil
681 681
 }
682 682
 
683
-// Redirecter reexec function.
684
-func redirecter() {
683
+// Redirector reexec function.
684
+func redirector() {
685 685
 	runtime.LockOSThread()
686 686
 	defer runtime.UnlockOSThread()
687 687