Browse code

Phase-2 bridge driver changes to support IPAM

- Set bridge ipv4 address when bridge is present
- IPv6 changes for bridge
- Convert unit tests to the new model

Signed-off-by: Alessandro Boch <aboch@docker.com>

Alessandro Boch authored on 2015/10/06 06:53:25
Showing 17 changed files
... ...
@@ -5,6 +5,7 @@ package bitseq
5 5
 
6 6
 import (
7 7
 	"encoding/binary"
8
+	"encoding/json"
8 9
 	"fmt"
9 10
 	"sync"
10 11
 
... ...
@@ -392,6 +393,38 @@ func (h *Handle) String() string {
392 392
 		h.app, h.id, h.dbIndex, h.bits, h.unselected, h.head.toString())
393 393
 }
394 394
 
395
+// MarshalJSON encodes Handle into json message
396
+func (h *Handle) MarshalJSON() ([]byte, error) {
397
+	m := map[string]interface{}{
398
+		"id": h.id,
399
+	}
400
+
401
+	b, err := h.ToByteArray()
402
+	if err != nil {
403
+		return nil, err
404
+	}
405
+	m["sequence"] = b
406
+	return json.Marshal(m)
407
+}
408
+
409
+// UnmarshalJSON decodes json message into Handle
410
+func (h *Handle) UnmarshalJSON(data []byte) error {
411
+	var (
412
+		m   map[string]interface{}
413
+		b   []byte
414
+		err error
415
+	)
416
+	if err = json.Unmarshal(data, &m); err != nil {
417
+		return err
418
+	}
419
+	h.id = m["id"].(string)
420
+	bi, _ := json.Marshal(m["sequence"])
421
+	if err := json.Unmarshal(bi, &b); err != nil {
422
+		return err
423
+	}
424
+	return h.FromByteArray(b)
425
+}
426
+
395 427
 // getFirstAvailable looks for the first unset bit in passed mask starting from start
396 428
 func getFirstAvailable(head *sequence, start uint32) (uint32, uint32, error) {
397 429
 	// Find sequence which contains the start bit
... ...
@@ -4,7 +4,6 @@ import (
4 4
 	"encoding/json"
5 5
 	"fmt"
6 6
 
7
-	log "github.com/Sirupsen/logrus"
8 7
 	"github.com/docker/libnetwork/datastore"
9 8
 	"github.com/docker/libnetwork/types"
10 9
 )
... ...
@@ -25,27 +24,16 @@ func (h *Handle) KeyPrefix() []string {
25 25
 
26 26
 // Value marshals the data to be stored in the KV store
27 27
 func (h *Handle) Value() []byte {
28
-	b, err := h.ToByteArray()
28
+	b, err := json.Marshal(h)
29 29
 	if err != nil {
30
-		log.Warnf("Failed to serialize Handle: %v", err)
31
-		b = []byte{}
32
-	}
33
-	jv, err := json.Marshal(b)
34
-	if err != nil {
35
-		log.Warnf("Failed to json encode bitseq handler byte array: %v", err)
36
-		return []byte{}
30
+		return nil
37 31
 	}
38
-	return jv
32
+	return b
39 33
 }
40 34
 
41 35
 // SetValue unmarshals the data from the KV store
42 36
 func (h *Handle) SetValue(value []byte) error {
43
-	var b []byte
44
-	if err := json.Unmarshal(value, &b); err != nil {
45
-		return err
46
-	}
47
-
48
-	return h.FromByteArray(b)
37
+	return json.Unmarshal(value, h)
49 38
 }
50 39
 
51 40
 // Index returns the latest DB Index as seen by this object
... ...
@@ -77,7 +65,6 @@ func (h *Handle) New() datastore.KVObject {
77 77
 
78 78
 	return &Handle{
79 79
 		app:   h.app,
80
-		id:    h.id,
81 80
 		store: h.store,
82 81
 	}
83 82
 }
... ...
@@ -29,8 +29,10 @@ import (
29 29
 	"github.com/docker/libnetwork/config"
30 30
 	"github.com/docker/libnetwork/datastore"
31 31
 	"github.com/docker/libnetwork/driverapi"
32
+	"github.com/docker/libnetwork/ipamutils"
32 33
 	"github.com/docker/libnetwork/netlabel"
33 34
 	"github.com/docker/libnetwork/options"
35
+	"github.com/docker/libnetwork/types"
34 36
 	"github.com/gorilla/mux"
35 37
 )
36 38
 
... ...
@@ -187,7 +189,12 @@ func createDefaultNetwork(c libnetwork.NetworkController) {
187 187
 			}
188 188
 			createOptions = append(createOptions,
189 189
 				libnetwork.NetworkOptionGeneric(genericOption),
190
-				libnetwork.NetworkOptionPersist(false))
190
+				ipamOption(nw))
191
+		}
192
+
193
+		if _, err := c.NetworkByName(nw); err == nil {
194
+			logrus.Debugf("Default network %s already present", nw)
195
+			return
191 196
 		}
192 197
 		_, err := c.NewNetwork(d, nw, createOptions...)
193 198
 		if err != nil {
... ...
@@ -405,3 +412,15 @@ func encodeData(data interface{}) (*bytes.Buffer, error) {
405 405
 	}
406 406
 	return params, nil
407 407
 }
408
+
409
+func ipamOption(bridgeName string) libnetwork.NetworkOption {
410
+	if nw, _, err := ipamutils.ElectInterfaceAddresses(bridgeName); err == nil {
411
+		ipamV4Conf := &libnetwork.IpamConf{PreferredPool: nw.String()}
412
+		hip, _ := types.GetHostPartIP(nw.IP, nw.Mask)
413
+		if hip.IsGlobalUnicast() {
414
+			ipamV4Conf.Gateway = nw.IP.String()
415
+		}
416
+		return libnetwork.NetworkOptionIpam("default", "", []*libnetwork.IpamConf{ipamV4Conf}, nil)
417
+	}
418
+	return nil
419
+}
... ...
@@ -56,15 +56,17 @@ type configuration struct {
56 56
 // networkConfiguration for network specific configuration
57 57
 type networkConfiguration struct {
58 58
 	BridgeName         string
59
-	AddressIPv4        *net.IPNet
60 59
 	EnableIPv6         bool
61 60
 	EnableIPMasquerade bool
62 61
 	EnableICC          bool
63 62
 	Mtu                int
64
-	DefaultGatewayIPv4 net.IP
65
-	DefaultGatewayIPv6 net.IP
66 63
 	DefaultBindingIP   net.IP
67 64
 	DefaultBridge      bool
65
+	// Internal fields set after ipam data parsing
66
+	AddressIPv4        *net.IPNet
67
+	AddressIPv6        *net.IPNet
68
+	DefaultGatewayIPv4 net.IP
69
+	DefaultGatewayIPv6 net.IP
68 70
 }
69 71
 
70 72
 // endpointConfiguration represents the user specified configuration for the sandbox endpoint
... ...
@@ -161,27 +163,39 @@ func (c *networkConfiguration) Validate() error {
161 161
 		}
162 162
 	}
163 163
 
164
+	// If default v6 gw is specified, AddressIPv6 must be specified and gw must belong to AddressIPv6 subnet
165
+	if c.EnableIPv6 && c.DefaultGatewayIPv6 != nil {
166
+		if c.AddressIPv6 == nil || !c.AddressIPv6.Contains(c.DefaultGatewayIPv6) {
167
+			return &ErrInvalidGateway{}
168
+		}
169
+	}
164 170
 	return nil
165 171
 }
166 172
 
167 173
 // Conflicts check if two NetworkConfiguration objects overlap
168
-func (c *networkConfiguration) Conflicts(o *networkConfiguration) bool {
174
+func (c *networkConfiguration) Conflicts(o *networkConfiguration) error {
169 175
 	if o == nil {
170
-		return false
176
+		return fmt.Errorf("same configuration")
171 177
 	}
172 178
 
173 179
 	// Also empty, becasue only one network with empty name is allowed
174 180
 	if c.BridgeName == o.BridgeName {
175
-		return true
181
+		return fmt.Errorf("networks have same name")
176 182
 	}
177 183
 
178 184
 	// They must be in different subnets
179 185
 	if (c.AddressIPv4 != nil && o.AddressIPv4 != nil) &&
180 186
 		(c.AddressIPv4.Contains(o.AddressIPv4.IP) || o.AddressIPv4.Contains(c.AddressIPv4.IP)) {
181
-		return true
187
+		return fmt.Errorf("networks have overlapping IPv4")
188
+	}
189
+
190
+	// They must be in different v6 subnets
191
+	if (c.AddressIPv6 != nil && o.AddressIPv6 != nil) &&
192
+		(c.AddressIPv6.Contains(o.AddressIPv6.IP) || o.AddressIPv6.Contains(c.AddressIPv6.IP)) {
193
+		return fmt.Errorf("networks have overlapping IPv6")
182 194
 	}
183 195
 
184
-	return false
196
+	return nil
185 197
 }
186 198
 
187 199
 // fromMap retrieve the configuration data from the map form.
... ...
@@ -456,18 +470,18 @@ func (c *networkConfiguration) processIPAM(id string, ipamV4Data, ipamV6Data []d
456 456
 		c.AddressIPv4 = types.GetIPNetCopy(ipamV4Data[0].Gateway)
457 457
 	}
458 458
 
459
-	if c.EnableIPv6 && len(ipamV6Data) == 0 {
460
-		return types.BadRequestErrorf("bridge network %s requires ipv6 configuration", id)
461
-	}
462
-
463
-	gw, ok := ipamV4Data[0].AuxAddresses[DefaultGatewayV4AuxKey]
464
-	if ok {
459
+	if gw, ok := ipamV4Data[0].AuxAddresses[DefaultGatewayV4AuxKey]; ok {
465 460
 		c.DefaultGatewayIPv4 = gw.IP
466 461
 	}
467 462
 
468
-	gw, ok = ipamV4Data[0].AuxAddresses[DefaultGatewayV6AuxKey]
469
-	if ok {
470
-		c.DefaultGatewayIPv6 = gw.IP
463
+	if len(ipamV6Data) > 0 {
464
+		if ipamV6Data[0].Gateway != nil {
465
+			c.AddressIPv6 = types.GetIPNetCopy(ipamV6Data[0].Gateway)
466
+		}
467
+
468
+		if gw, ok := ipamV6Data[0].AuxAddresses[DefaultGatewayV6AuxKey]; ok {
469
+			c.DefaultGatewayIPv6 = gw.IP
470
+		}
471 471
 	}
472 472
 
473 473
 	return nil
... ...
@@ -502,6 +516,9 @@ func parseNetworkOptions(id string, option options.Generic) (*networkConfigurati
502 502
 
503 503
 // Returns the non link-local IPv6 subnet for the containers attached to this bridge if found, nil otherwise
504 504
 func getV6Network(config *networkConfiguration, i *bridgeInterface) *net.IPNet {
505
+	if config.AddressIPv6 != nil {
506
+		return config.AddressIPv6
507
+	}
505 508
 	if i.bridgeIPv6 != nil && i.bridgeIPv6.IP != nil && !i.bridgeIPv6.IP.IsLinkLocalUnicast() {
506 509
 		return i.bridgeIPv6
507 510
 	}
... ...
@@ -551,8 +568,9 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, ipV4Dat
551 551
 		nw.Lock()
552 552
 		nwConfig := nw.config
553 553
 		nw.Unlock()
554
-		if nwConfig.Conflicts(config) {
555
-			return types.ForbiddenErrorf("conflicts with network %s (%s)", nw.id, nw.config.BridgeName)
554
+		if err := nwConfig.Conflicts(config); err != nil {
555
+			return types.ForbiddenErrorf("cannot create network %s (%s): conflicts with network %s (%s): %s",
556
+				nwConfig.BridgeName, id, nw.id, nw.config.BridgeName, err.Error())
556 557
 		}
557 558
 	}
558 559
 
... ...
@@ -613,10 +631,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, ipV4Dat
613 613
 	// Even if a bridge exists try to setup IPv4.
614 614
 	bridgeSetup.queueStep(setupBridgeIPv4)
615 615
 
616
-	enableIPv6Forwarding := false
617
-	if d.config.EnableIPForwarding {
618
-		enableIPv6Forwarding = true
619
-	}
616
+	enableIPv6Forwarding := d.config.EnableIPForwarding && config.AddressIPv6 != nil
620 617
 
621 618
 	// Conditionally queue setup steps depending on configuration values.
622 619
 	for _, step := range []struct {
... ...
@@ -797,11 +812,6 @@ func setHairpinMode(link netlink.Link, enable bool) error {
797 797
 }
798 798
 
799 799
 func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
800
-	var (
801
-		ipv6Addr *net.IPNet
802
-		err      error
803
-	)
804
-
805 800
 	defer osl.InitOSContext()()
806 801
 
807 802
 	if ifInfo == nil {
... ...
@@ -931,7 +941,11 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
931 931
 		}
932 932
 	}
933 933
 
934
-	ipv4Addr := ifInfo.Address()
934
+	// Create the sandbox side pipe interface
935
+	endpoint.srcName = containerIfName
936
+	endpoint.macAddress = ifInfo.MacAddress()
937
+	endpoint.addr = ifInfo.Address()
938
+	endpoint.addrv6 = ifInfo.AddressIPv6()
935 939
 
936 940
 	// Down the interface before configuring mac address.
937 941
 	if err = netlink.LinkSetDown(sbox); err != nil {
... ...
@@ -939,28 +953,38 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
939 939
 	}
940 940
 
941 941
 	// Set the sbox's MAC. If specified, use the one configured by user, otherwise generate one based on IP.
942
-	mac := ifInfo.MacAddress()
943
-	if mac == nil {
944
-		mac = electMacAddress(epConfig, ipv4Addr.IP)
942
+	if endpoint.macAddress == nil {
943
+		endpoint.macAddress = electMacAddress(epConfig, endpoint.addr.IP)
944
+		if err := ifInfo.SetMacAddress(endpoint.macAddress); err != nil {
945
+			return err
946
+		}
945 947
 	}
946
-	err = netlink.LinkSetHardwareAddr(sbox, mac)
948
+	err = netlink.LinkSetHardwareAddr(sbox, endpoint.macAddress)
947 949
 	if err != nil {
948 950
 		return fmt.Errorf("could not set mac address for container interface %s: %v", containerIfName, err)
949 951
 	}
950
-	endpoint.macAddress = mac
951 952
 
952 953
 	// Up the host interface after finishing all netlink configuration
953 954
 	if err = netlink.LinkSetUp(host); err != nil {
954 955
 		return fmt.Errorf("could not set link up for host interface %s: %v", hostIfName, err)
955 956
 	}
956 957
 
957
-	ipv6Addr = ifInfo.AddressIPv6()
958
-	// Create the sandbox side pipe interface
959
-	endpoint.srcName = containerIfName
960
-	endpoint.addr = ipv4Addr
958
+	if endpoint.addrv6 == nil && config.EnableIPv6 {
959
+		var ip6 net.IP
960
+		network := n.bridge.bridgeIPv6
961
+		ones, _ := network.Mask.Size()
962
+		if ones <= 80 {
963
+			ip6 = make(net.IP, len(network.IP))
964
+			copy(ip6, network.IP)
965
+			for i, h := range endpoint.macAddress {
966
+				ip6[i+10] = h
967
+			}
968
+		}
961 969
 
962
-	if config.EnableIPv6 {
963
-		endpoint.addrv6 = ipv6Addr
970
+		endpoint.addrv6 = &net.IPNet{IP: ip6, Mask: network.Mask}
971
+		if err := ifInfo.SetIPAddress(endpoint.addrv6); err != nil {
972
+			return err
973
+		}
964 974
 	}
965 975
 
966 976
 	// Program any required port mapping and store them in the endpoint
... ...
@@ -969,13 +993,6 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
969 969
 		return err
970 970
 	}
971 971
 
972
-	if ifInfo.MacAddress() == nil {
973
-		err = ifInfo.SetMacAddress(endpoint.macAddress)
974
-		if err != nil {
975
-			return err
976
-		}
977
-	}
978
-
979 972
 	return nil
980 973
 }
981 974
 
... ...
@@ -8,14 +8,27 @@ import (
8 8
 	"testing"
9 9
 
10 10
 	"github.com/docker/libnetwork/driverapi"
11
+	"github.com/docker/libnetwork/ipamutils"
11 12
 	"github.com/docker/libnetwork/iptables"
12 13
 	"github.com/docker/libnetwork/netlabel"
13
-	"github.com/docker/libnetwork/netutils"
14 14
 	"github.com/docker/libnetwork/testutils"
15 15
 	"github.com/docker/libnetwork/types"
16 16
 	"github.com/vishvananda/netlink"
17 17
 )
18 18
 
19
+func getIPv4Data(t *testing.T) []driverapi.IPAMData {
20
+	ipd := driverapi.IPAMData{AddressSpace: "full"}
21
+	nw, _, err := ipamutils.ElectInterfaceAddresses("")
22
+	if err != nil {
23
+		t.Fatal(err)
24
+	}
25
+	ipd.Pool = nw
26
+	// Set network gateway to X.X.X.1
27
+	ipd.Gateway = types.GetIPNetCopy(nw)
28
+	ipd.Gateway.IP[len(ipd.Gateway.IP)-1] = 1
29
+	return []driverapi.IPAMData{ipd}
30
+}
31
+
19 32
 func TestCreateFullOptions(t *testing.T) {
20 33
 	defer testutils.SetupTestOSContext(t)()
21 34
 	d := newDriver()
... ...
@@ -27,17 +40,14 @@ func TestCreateFullOptions(t *testing.T) {
27 27
 
28 28
 	// Test this scenario: Default gw address does not belong to
29 29
 	// container network and it's greater than bridge address
30
-	cip, cnw, _ := net.ParseCIDR("172.16.122.0/24")
31
-	cnw.IP = cip
32
-	ip, nw, _ := net.ParseCIDR("172.16.0.10/16")
33
-	nw.IP = ip
34
-	gw := net.ParseIP("172.16.0.1")
30
+	cnw, _ := types.ParseCIDR("172.16.122.0/24")
31
+	bnw, _ := types.ParseCIDR("172.16.0.0/24")
32
+	br, _ := types.ParseCIDR("172.16.0.1/16")
33
+	defgw, _ := types.ParseCIDR("172.16.0.100/16")
35 34
 
36 35
 	netConfig := &networkConfiguration{
37
-		BridgeName:         DefaultBridgeName,
38
-		AddressIPv4:        nw,
39
-		DefaultGatewayIPv4: gw,
40
-		EnableIPv6:         true,
36
+		BridgeName: DefaultBridgeName,
37
+		EnableIPv6: true,
41 38
 	}
42 39
 	genericOption := make(map[string]interface{})
43 40
 	genericOption[netlabel.GenericData] = config
... ...
@@ -49,14 +59,21 @@ func TestCreateFullOptions(t *testing.T) {
49 49
 	netOption := make(map[string]interface{})
50 50
 	netOption[netlabel.GenericData] = netConfig
51 51
 
52
-	err := d.CreateNetwork("dummy", netOption, nil, nil)
52
+	ipdList := []driverapi.IPAMData{
53
+		driverapi.IPAMData{
54
+			Pool:         bnw,
55
+			Gateway:      br,
56
+			AuxAddresses: map[string]*net.IPNet{DefaultGatewayV4AuxKey: defgw},
57
+		},
58
+	}
59
+	err := d.CreateNetwork("dummy", netOption, ipdList, nil)
53 60
 	if err != nil {
54 61
 		t.Fatalf("Failed to create bridge: %v", err)
55 62
 	}
56 63
 
57 64
 	// Verify the IP address allocated for the endpoint belongs to the container network
58 65
 	epOptions := make(map[string]interface{})
59
-	te := &testEndpoint{iface: &testInterface{}}
66
+	te := newTestEndpoint(cnw, 10)
60 67
 	err = d.CreateEndpoint("dummy", "ep1", te.Interface(), epOptions)
61 68
 	if err != nil {
62 69
 		t.Fatalf("Failed to create an endpoint : %s", err.Error())
... ...
@@ -75,7 +92,7 @@ func TestCreateNoConfig(t *testing.T) {
75 75
 	genericOption := make(map[string]interface{})
76 76
 	genericOption[netlabel.GenericData] = netconfig
77 77
 
78
-	if err := d.CreateNetwork("dummy", genericOption, nil, nil); err != nil {
78
+	if err := d.CreateNetwork("dummy", genericOption, getIPv4Data(t), nil); err != nil {
79 79
 		t.Fatalf("Failed to create bridge: %v", err)
80 80
 	}
81 81
 }
... ...
@@ -92,11 +109,11 @@ func TestCreate(t *testing.T) {
92 92
 	genericOption := make(map[string]interface{})
93 93
 	genericOption[netlabel.GenericData] = netconfig
94 94
 
95
-	if err := d.CreateNetwork("dummy", genericOption, nil, nil); err != nil {
95
+	if err := d.CreateNetwork("dummy", genericOption, getIPv4Data(t), nil); err != nil {
96 96
 		t.Fatalf("Failed to create bridge: %v", err)
97 97
 	}
98 98
 
99
-	err := d.CreateNetwork("dummy", genericOption, nil, nil)
99
+	err := d.CreateNetwork("dummy", genericOption, getIPv4Data(t), nil)
100 100
 	if err == nil {
101 101
 		t.Fatalf("Expected bridge driver to refuse creation of second network with default name")
102 102
 	}
... ...
@@ -125,7 +142,7 @@ func TestCreateFail(t *testing.T) {
125 125
 	genericOption := make(map[string]interface{})
126 126
 	genericOption[netlabel.GenericData] = netconfig
127 127
 
128
-	if err := d.CreateNetwork("dummy", genericOption, nil, nil); err == nil {
128
+	if err := d.CreateNetwork("dummy", genericOption, getIPv4Data(t), nil); err == nil {
129 129
 		t.Fatal("Bridge creation was expected to fail")
130 130
 	}
131 131
 }
... ...
@@ -147,19 +164,19 @@ func TestCreateMultipleNetworks(t *testing.T) {
147 147
 	config1 := &networkConfiguration{BridgeName: "net_test_1"}
148 148
 	genericOption = make(map[string]interface{})
149 149
 	genericOption[netlabel.GenericData] = config1
150
-	if err := d.CreateNetwork("1", genericOption, nil, nil); err != nil {
150
+	if err := d.CreateNetwork("1", genericOption, getIPv4Data(t), nil); err != nil {
151 151
 		t.Fatalf("Failed to create bridge: %v", err)
152 152
 	}
153 153
 
154 154
 	config2 := &networkConfiguration{BridgeName: "net_test_2"}
155 155
 	genericOption[netlabel.GenericData] = config2
156
-	if err := d.CreateNetwork("2", genericOption, nil, nil); err != nil {
156
+	if err := d.CreateNetwork("2", genericOption, getIPv4Data(t), nil); err != nil {
157 157
 		t.Fatalf("Failed to create bridge: %v", err)
158 158
 	}
159 159
 
160 160
 	config3 := &networkConfiguration{BridgeName: "net_test_3"}
161 161
 	genericOption[netlabel.GenericData] = config3
162
-	if err := d.CreateNetwork("3", genericOption, nil, nil); err != nil {
162
+	if err := d.CreateNetwork("3", genericOption, getIPv4Data(t), nil); err != nil {
163 163
 		t.Fatalf("Failed to create bridge: %v", err)
164 164
 	}
165 165
 
... ...
@@ -168,7 +185,7 @@ func TestCreateMultipleNetworks(t *testing.T) {
168 168
 
169 169
 	config4 := &networkConfiguration{BridgeName: "net_test_4"}
170 170
 	genericOption[netlabel.GenericData] = config4
171
-	if err := d.CreateNetwork("4", genericOption, nil, nil); err != nil {
171
+	if err := d.CreateNetwork("4", genericOption, getIPv4Data(t), nil); err != nil {
172 172
 		t.Fatalf("Failed to create bridge: %v", err)
173 173
 	}
174 174
 
... ...
@@ -221,6 +238,12 @@ type testEndpoint struct {
221 221
 	routes         []types.StaticRoute
222 222
 }
223 223
 
224
+func newTestEndpoint(nw *net.IPNet, ordinal byte) *testEndpoint {
225
+	addr := types.GetIPNetCopy(nw)
226
+	addr.IP[len(addr.IP)-1] = ordinal
227
+	return &testEndpoint{iface: &testInterface{addr: addr}}
228
+}
229
+
224 230
 func (te *testEndpoint) Interface() driverapi.InterfaceInfo {
225 231
 	if te.iface != nil {
226 232
 		return te.iface
... ...
@@ -329,7 +352,8 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
329 329
 	genericOption = make(map[string]interface{})
330 330
 	genericOption[netlabel.GenericData] = netconfig
331 331
 
332
-	err := d.CreateNetwork("net1", genericOption, nil, nil)
332
+	ipdList := getIPv4Data(t)
333
+	err := d.CreateNetwork("net1", genericOption, ipdList, nil)
333 334
 	if err != nil {
334 335
 		t.Fatalf("Failed to create bridge: %v", err)
335 336
 	}
... ...
@@ -338,7 +362,7 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
338 338
 	epOptions := make(map[string]interface{})
339 339
 	epOptions[netlabel.PortMap] = portMappings
340 340
 
341
-	te := &testEndpoint{iface: &testInterface{}}
341
+	te := newTestEndpoint(ipdList[0].Pool, 11)
342 342
 	err = d.CreateEndpoint("net1", "ep1", te.Interface(), epOptions)
343 343
 	if err != nil {
344 344
 		t.Fatalf("Failed to create an endpoint : %s", err.Error())
... ...
@@ -389,7 +413,8 @@ func TestCreateLinkWithOptions(t *testing.T) {
389 389
 	netOptions := make(map[string]interface{})
390 390
 	netOptions[netlabel.GenericData] = netconfig
391 391
 
392
-	err := d.CreateNetwork("net1", netOptions, nil, nil)
392
+	ipdList := getIPv4Data(t)
393
+	err := d.CreateNetwork("net1", netOptions, ipdList, nil)
393 394
 	if err != nil {
394 395
 		t.Fatalf("Failed to create bridge: %v", err)
395 396
 	}
... ...
@@ -398,7 +423,7 @@ func TestCreateLinkWithOptions(t *testing.T) {
398 398
 	epOptions := make(map[string]interface{})
399 399
 	epOptions[netlabel.MacAddress] = mac
400 400
 
401
-	te := &testEndpoint{iface: &testInterface{}}
401
+	te := newTestEndpoint(ipdList[0].Pool, 11)
402 402
 	err = d.CreateEndpoint("net1", "ep", te.Interface(), epOptions)
403 403
 	if err != nil {
404 404
 		t.Fatalf("Failed to create an endpoint: %s", err.Error())
... ...
@@ -458,7 +483,8 @@ func TestLinkContainers(t *testing.T) {
458 458
 	genericOption = make(map[string]interface{})
459 459
 	genericOption[netlabel.GenericData] = netconfig
460 460
 
461
-	err := d.CreateNetwork("net1", genericOption, nil, nil)
461
+	ipdList := getIPv4Data(t)
462
+	err := d.CreateNetwork("net1", genericOption, ipdList, nil)
462 463
 	if err != nil {
463 464
 		t.Fatalf("Failed to create bridge: %v", err)
464 465
 	}
... ...
@@ -467,7 +493,7 @@ func TestLinkContainers(t *testing.T) {
467 467
 	epOptions := make(map[string]interface{})
468 468
 	epOptions[netlabel.ExposedPorts] = exposedPorts
469 469
 
470
-	te1 := &testEndpoint{iface: &testInterface{}}
470
+	te1 := newTestEndpoint(ipdList[0].Pool, 11)
471 471
 	err = d.CreateEndpoint("net1", "ep1", te1.Interface(), epOptions)
472 472
 	if err != nil {
473 473
 		t.Fatalf("Failed to create an endpoint : %s", err.Error())
... ...
@@ -478,7 +504,7 @@ func TestLinkContainers(t *testing.T) {
478 478
 		t.Fatalf("No Ipv4 address assigned to the endpoint:  ep1")
479 479
 	}
480 480
 
481
-	te2 := &testEndpoint{iface: &testInterface{}}
481
+	te2 := newTestEndpoint(ipdList[0].Pool, 22)
482 482
 	err = d.CreateEndpoint("net1", "ep2", te2.Interface(), nil)
483 483
 	if err != nil {
484 484
 		t.Fatalf("Failed to create an endpoint : %s", err.Error())
... ...
@@ -581,6 +607,14 @@ func TestValidateConfig(t *testing.T) {
581 581
 
582 582
 	// Bridge network
583 583
 	_, network, _ := net.ParseCIDR("172.28.0.0/16")
584
+	c = networkConfiguration{
585
+		AddressIPv4: network,
586
+	}
587
+
588
+	err = c.Validate()
589
+	if err != nil {
590
+		t.Fatal(err)
591
+	}
584 592
 
585 593
 	// Test v4 gw
586 594
 	c.DefaultGatewayIPv4 = net.ParseIP("172.27.30.234")
... ...
@@ -596,9 +630,10 @@ func TestValidateConfig(t *testing.T) {
596 596
 	}
597 597
 
598 598
 	// Test v6 gw
599
-	_, containerSubnet, _ = net.ParseCIDR("2001:1234:ae:b004::/64")
599
+	_, v6nw, _ := net.ParseCIDR("2001:1234:ae:b004::/64")
600 600
 	c = networkConfiguration{
601 601
 		EnableIPv6:         true,
602
+		AddressIPv6:        v6nw,
602 603
 		DefaultGatewayIPv6: net.ParseIP("2001:1234:ac:b004::bad:a55"),
603 604
 	}
604 605
 	err = c.Validate()
... ...
@@ -611,6 +646,18 @@ func TestValidateConfig(t *testing.T) {
611 611
 	if err != nil {
612 612
 		t.Fatalf("Unexpected validation error on v6 default gateway")
613 613
 	}
614
+
615
+	c.AddressIPv6 = nil
616
+	err = c.Validate()
617
+	if err == nil {
618
+		t.Fatalf("Failed to detect invalid v6 default gateway")
619
+	}
620
+
621
+	c.AddressIPv6 = nil
622
+	err = c.Validate()
623
+	if err == nil {
624
+		t.Fatalf("Failed to detect invalid v6 default gateway")
625
+	}
614 626
 }
615 627
 
616 628
 func TestSetDefaultGw(t *testing.T) {
... ...
@@ -623,24 +670,15 @@ func TestSetDefaultGw(t *testing.T) {
623 623
 
624 624
 	_, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80")
625 625
 
626
-	var nw *net.IPNet
627
-	for _, n := range bridgeNetworks {
628
-		if err := netutils.CheckRouteOverlaps(n); err == nil {
629
-			nw = n
630
-			break
631
-		}
632
-	}
633
-	if nw == nil {
634
-		t.Skipf("Skip as no more automatic networks available")
635
-	}
636
-
637
-	gw4 := types.GetIPCopy(nw.IP).To4()
626
+	ipdList := getIPv4Data(t)
627
+	gw4 := types.GetIPCopy(ipdList[0].Pool.IP).To4()
638 628
 	gw4[3] = 254
639 629
 	gw6 := net.ParseIP("2001:db8:ea9:9abc:b0c4::254")
640 630
 
641 631
 	config := &networkConfiguration{
642 632
 		BridgeName:         DefaultBridgeName,
643 633
 		EnableIPv6:         true,
634
+		AddressIPv6:        subnetv6,
644 635
 		DefaultGatewayIPv4: gw4,
645 636
 		DefaultGatewayIPv6: gw6,
646 637
 	}
... ...
@@ -648,12 +686,12 @@ func TestSetDefaultGw(t *testing.T) {
648 648
 	genericOption := make(map[string]interface{})
649 649
 	genericOption[netlabel.GenericData] = config
650 650
 
651
-	err := d.CreateNetwork("dummy", genericOption, nil, nil)
651
+	err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
652 652
 	if err != nil {
653 653
 		t.Fatalf("Failed to create bridge: %v", err)
654 654
 	}
655 655
 
656
-	te := &testEndpoint{iface: &testInterface{}}
656
+	te := newTestEndpoint(ipdList[0].Pool, 10)
657 657
 	err = d.CreateEndpoint("dummy", "ep", te.Interface(), nil)
658 658
 	if err != nil {
659 659
 		t.Fatalf("Failed to create endpoint: %v", err)
... ...
@@ -26,12 +26,13 @@ func TestLinkCreate(t *testing.T) {
26 26
 	genericOption := make(map[string]interface{})
27 27
 	genericOption[netlabel.GenericData] = config
28 28
 
29
-	err := d.CreateNetwork("dummy", genericOption, nil, nil)
29
+	ipdList := getIPv4Data(t)
30
+	err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
30 31
 	if err != nil {
31 32
 		t.Fatalf("Failed to create bridge: %v", err)
32 33
 	}
33 34
 
34
-	te := &testEndpoint{iface: &testInterface{}}
35
+	te := newTestEndpoint(ipdList[0].Pool, 10)
35 36
 	err = d.CreateEndpoint("dummy", "", te.Interface(), nil)
36 37
 	if err != nil {
37 38
 		if _, ok := err.(InvalidEndpointIDError); !ok {
... ...
@@ -63,7 +64,7 @@ func TestLinkCreate(t *testing.T) {
63 63
 	// TODO: if we could get peer name from (sboxLnk.(*netlink.Veth)).PeerName
64 64
 	// then we could check the MTU on hostLnk as well.
65 65
 
66
-	te1 := &testEndpoint{iface: &testInterface{}}
66
+	te1 := newTestEndpoint(ipdList[0].Pool, 11)
67 67
 	err = d.CreateEndpoint("dummy", "ep", te1.Interface(), nil)
68 68
 	if err == nil {
69 69
 		t.Fatalf("Failed to detect duplicate endpoint id on same network")
... ...
@@ -117,18 +118,19 @@ func TestLinkCreateTwo(t *testing.T) {
117 117
 	genericOption := make(map[string]interface{})
118 118
 	genericOption[netlabel.GenericData] = config
119 119
 
120
-	err := d.CreateNetwork("dummy", genericOption, nil, nil)
120
+	ipdList := getIPv4Data(t)
121
+	err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
121 122
 	if err != nil {
122 123
 		t.Fatalf("Failed to create bridge: %v", err)
123 124
 	}
124 125
 
125
-	te1 := &testEndpoint{iface: &testInterface{}}
126
+	te1 := newTestEndpoint(ipdList[0].Pool, 11)
126 127
 	err = d.CreateEndpoint("dummy", "ep", te1.Interface(), nil)
127 128
 	if err != nil {
128 129
 		t.Fatalf("Failed to create a link: %s", err.Error())
129 130
 	}
130 131
 
131
-	te2 := &testEndpoint{iface: &testInterface{}}
132
+	te2 := newTestEndpoint(ipdList[0].Pool, 12)
132 133
 	err = d.CreateEndpoint("dummy", "ep", te2.Interface(), nil)
133 134
 	if err != nil {
134 135
 		if _, ok := err.(driverapi.ErrEndpointExists); !ok {
... ...
@@ -152,12 +154,12 @@ func TestLinkCreateNoEnableIPv6(t *testing.T) {
152 152
 	genericOption := make(map[string]interface{})
153 153
 	genericOption[netlabel.GenericData] = config
154 154
 
155
-	err := d.CreateNetwork("dummy", genericOption, nil, nil)
155
+	ipdList := getIPv4Data(t)
156
+	err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
156 157
 	if err != nil {
157 158
 		t.Fatalf("Failed to create bridge: %v", err)
158 159
 	}
159
-
160
-	te := &testEndpoint{iface: &testInterface{}}
160
+	te := newTestEndpoint(ipdList[0].Pool, 30)
161 161
 	err = d.CreateEndpoint("dummy", "ep", te.Interface(), nil)
162 162
 	if err != nil {
163 163
 		t.Fatalf("Failed to create a link: %s", err.Error())
... ...
@@ -187,12 +189,13 @@ func TestLinkDelete(t *testing.T) {
187 187
 	genericOption := make(map[string]interface{})
188 188
 	genericOption[netlabel.GenericData] = config
189 189
 
190
-	err := d.CreateNetwork("dummy", genericOption, nil, nil)
190
+	ipdList := getIPv4Data(t)
191
+	err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
191 192
 	if err != nil {
192 193
 		t.Fatalf("Failed to create bridge: %v", err)
193 194
 	}
194 195
 
195
-	te := &testEndpoint{iface: &testInterface{}}
196
+	te := newTestEndpoint(ipdList[0].Pool, 30)
196 197
 	err = d.CreateEndpoint("dummy", "ep1", te.Interface(), nil)
197 198
 	if err != nil {
198 199
 		t.Fatalf("Failed to create a link: %s", err.Error())
... ...
@@ -44,12 +44,13 @@ func TestPortMappingConfig(t *testing.T) {
44 44
 	netOptions := make(map[string]interface{})
45 45
 	netOptions[netlabel.GenericData] = netConfig
46 46
 
47
-	err := d.CreateNetwork("dummy", netOptions, nil, nil)
47
+	ipdList := getIPv4Data(t)
48
+	err := d.CreateNetwork("dummy", netOptions, ipdList, nil)
48 49
 	if err != nil {
49 50
 		t.Fatalf("Failed to create bridge: %v", err)
50 51
 	}
51 52
 
52
-	te := &testEndpoint{iface: &testInterface{}}
53
+	te := newTestEndpoint(ipdList[0].Pool, 11)
53 54
 	err = d.CreateEndpoint("dummy", "ep1", te.Interface(), epOptions)
54 55
 	if err != nil {
55 56
 		t.Fatalf("Failed to create the endpoint: %s", err.Error())
... ...
@@ -22,7 +22,7 @@ const (
22 22
 //Gets the IP version in use ( [ipv4], [ipv6] or [ipv4 and ipv6] )
23 23
 func getIPVersion(config *networkConfiguration) ipVersion {
24 24
 	ipVersion := ipv4
25
-	if config.EnableIPv6 {
25
+	if config.AddressIPv6 != nil || config.EnableIPv6 {
26 26
 		ipVersion |= ipv6
27 27
 	}
28 28
 	return ipVersion
... ...
@@ -3,103 +3,38 @@ package bridge
3 3
 import (
4 4
 	"fmt"
5 5
 	"io/ioutil"
6
-	"net"
7 6
 	"path/filepath"
8 7
 
9 8
 	log "github.com/Sirupsen/logrus"
10
-	"github.com/docker/libnetwork/netutils"
9
+	"github.com/docker/libnetwork/types"
11 10
 	"github.com/vishvananda/netlink"
12 11
 )
13 12
 
14
-var bridgeNetworks []*net.IPNet
15
-
16
-func init() {
17
-	// Here we don't follow the convention of using the 1st IP of the range for the gateway.
18
-	// This is to use the same gateway IPs as the /24 ranges, which predate the /16 ranges.
19
-	// In theory this shouldn't matter - in practice there's bound to be a few scripts relying
20
-	// on the internal addressing or other stupid things like that.
21
-	// They shouldn't, but hey, let's not break them unless we really have to.
22
-	// Don't use 172.16.0.0/16, it conflicts with EC2 DNS 172.16.0.23
23
-
24
-	// 172.[17-31].42.1/16
25
-	mask := []byte{255, 255, 0, 0}
26
-	for i := 17; i < 32; i++ {
27
-		bridgeNetworks = append(bridgeNetworks, &net.IPNet{IP: []byte{172, byte(i), 42, 1}, Mask: mask})
28
-	}
29
-	// 10.[0-255].42.1/16
30
-	for i := 0; i < 256; i++ {
31
-		bridgeNetworks = append(bridgeNetworks, &net.IPNet{IP: []byte{10, byte(i), 42, 1}, Mask: mask})
32
-	}
33
-	// 192.168.[42-44].1/24
34
-	mask24 := []byte{255, 255, 255, 0}
35
-	for i := 42; i < 45; i++ {
36
-		bridgeNetworks = append(bridgeNetworks, &net.IPNet{IP: []byte{192, 168, byte(i), 1}, Mask: mask24})
37
-	}
38
-}
39
-
40 13
 func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
41 14
 	addrv4, _, err := i.addresses()
42 15
 	if err != nil {
43
-		return err
44
-	}
45
-
46
-	// Check if we have an IP address already on the bridge.
47
-	if addrv4.IPNet != nil {
48
-		// Make sure to store bridge network and default gateway before getting out.
49
-		i.bridgeIPv4 = addrv4.IPNet
50
-		i.gatewayIPv4 = addrv4.IPNet.IP
51
-		return nil
52
-	}
53
-
54
-	// Do not try to configure IPv4 on a non-default bridge unless you are
55
-	// specifically asked to do so.
56
-	if config.BridgeName != DefaultBridgeName && config.DefaultBridge {
57
-		return NonDefaultBridgeNeedsIPError(config.BridgeName)
58
-	}
59
-
60
-	bridgeIPv4, err := electBridgeIPv4(config)
61
-	if err != nil {
62
-		return err
16
+		return fmt.Errorf("failed to retrieve bridge interface addresses: %v", err)
63 17
 	}
64 18
 
65
-	log.Debugf("Creating bridge interface %s with network %s", config.BridgeName, bridgeIPv4)
66
-	if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: bridgeIPv4}); err != nil {
67
-		return &IPv4AddrAddError{IP: bridgeIPv4, Err: err}
19
+	if !types.CompareIPNet(addrv4.IPNet, config.AddressIPv4) {
20
+		if addrv4.IPNet != nil {
21
+			if err := netlink.AddrDel(i.Link, &addrv4); err != nil {
22
+				return fmt.Errorf("failed to remove current ip address from bridge: %v", err)
23
+			}
24
+		}
25
+		log.Debugf("Assigning address to bridge interface %s: %s", config.BridgeName, config.AddressIPv4)
26
+		if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: config.AddressIPv4}); err != nil {
27
+			return &IPv4AddrAddError{IP: config.AddressIPv4, Err: err}
28
+		}
68 29
 	}
69 30
 
70 31
 	// Store bridge network and default gateway
71
-	i.bridgeIPv4 = bridgeIPv4
72
-	i.gatewayIPv4 = i.bridgeIPv4.IP
32
+	i.bridgeIPv4 = config.AddressIPv4
33
+	i.gatewayIPv4 = config.AddressIPv4.IP
73 34
 
74 35
 	return nil
75 36
 }
76 37
 
77
-func electBridgeIPv4(config *networkConfiguration) (*net.IPNet, error) {
78
-	// Use the requested IPv4 CIDR when available.
79
-	if config.AddressIPv4 != nil {
80
-		return config.AddressIPv4, nil
81
-	}
82
-
83
-	// We don't check for an error here, because we don't really care if we
84
-	// can't read /etc/resolv.conf. So instead we skip the append if resolvConf
85
-	// is nil. It either doesn't exist, or we can't read it for some reason.
86
-	nameservers := []string{}
87
-	if resolvConf, _ := readResolvConf(); resolvConf != nil {
88
-		nameservers = append(nameservers, getNameserversAsCIDR(resolvConf)...)
89
-	}
90
-
91
-	// Try to automatically elect appropriate bridge IPv4 settings.
92
-	for _, n := range bridgeNetworks {
93
-		if err := netutils.CheckNameserverOverlaps(nameservers, n); err == nil {
94
-			if err := netutils.CheckRouteOverlaps(n); err == nil {
95
-				return n, nil
96
-			}
97
-		}
98
-	}
99
-
100
-	return nil, IPv4AddrRangeError(config.BridgeName)
101
-}
102
-
103 38
 func setupGatewayIPv4(config *networkConfiguration, i *bridgeInterface) error {
104 39
 	if !i.bridgeIPv4.Contains(config.DefaultGatewayIPv4) {
105 40
 		return &ErrInvalidGateway{}
... ...
@@ -4,7 +4,6 @@ import (
4 4
 	"net"
5 5
 	"testing"
6 6
 
7
-	"github.com/docker/libnetwork/netutils"
8 7
 	"github.com/docker/libnetwork/testutils"
9 8
 	"github.com/vishvananda/netlink"
10 9
 )
... ...
@@ -52,43 +51,6 @@ func TestSetupBridgeIPv4Fixed(t *testing.T) {
52 52
 	}
53 53
 }
54 54
 
55
-func TestSetupBridgeIPv4Auto(t *testing.T) {
56
-	defer testutils.SetupTestOSContext(t)()
57
-
58
-	var toBeChosen *net.IPNet
59
-	for _, n := range bridgeNetworks {
60
-		if err := netutils.CheckRouteOverlaps(n); err == nil {
61
-			toBeChosen = n
62
-			break
63
-		}
64
-	}
65
-	if toBeChosen == nil {
66
-		t.Skipf("Skip as no more automatic networks available")
67
-	}
68
-
69
-	config, br := setupTestInterface(t)
70
-	if err := setupBridgeIPv4(config, br); err != nil {
71
-		t.Fatalf("Failed to setup bridge IPv4: %v", err)
72
-	}
73
-
74
-	addrsv4, err := netlink.AddrList(br.Link, netlink.FAMILY_V4)
75
-	if err != nil {
76
-		t.Fatalf("Failed to list device IPv4 addresses: %v", err)
77
-	}
78
-
79
-	var found bool
80
-	for _, addr := range addrsv4 {
81
-		if toBeChosen.String() == addr.IPNet.String() {
82
-			found = true
83
-			break
84
-		}
85
-	}
86
-
87
-	if !found {
88
-		t.Fatalf("Bridge device does not have the automatic IPv4 address %s", toBeChosen.String())
89
-	}
90
-}
91
-
92 55
 func TestSetupGatewayIPv4(t *testing.T) {
93 56
 	defer testutils.SetupTestOSContext(t)()
94 57
 
... ...
@@ -110,14 +72,3 @@ func TestSetupGatewayIPv4(t *testing.T) {
110 110
 		t.Fatalf("Set Default Gateway failed. Expected %v, Found %v", gw, br.gatewayIPv4)
111 111
 	}
112 112
 }
113
-
114
-func TestCheckPreallocatedBridgeNetworks(t *testing.T) {
115
-	// Just make sure the bridge networks are created the way we want (172.17.x.x/16)
116
-	for i := 0; i < len(bridgeNetworks); i++ {
117
-		fb := bridgeNetworks[i].IP[0]
118
-		ones, _ := bridgeNetworks[i].Mask.Size()
119
-		if ((fb == 172 || fb == 10) && ones != 16) || (fb == 192 && ones != 24) {
120
-			t.Fatalf("Wrong mask for preallocated bridge network: %s", bridgeNetworks[i].String())
121
-		}
122
-	}
123
-}
... ...
@@ -4,6 +4,7 @@ import (
4 4
 	"fmt"
5 5
 	"io/ioutil"
6 6
 	"net"
7
+	"os"
7 8
 
8 9
 	"github.com/Sirupsen/logrus"
9 10
 	"github.com/vishvananda/netlink"
... ...
@@ -57,12 +58,35 @@ func setupBridgeIPv6(config *networkConfiguration, i *bridgeInterface) error {
57 57
 	i.bridgeIPv6 = bridgeIPv6
58 58
 	i.gatewayIPv6 = i.bridgeIPv6.IP
59 59
 
60
+	if config.AddressIPv6 == nil {
61
+		return nil
62
+	}
63
+
64
+	// Setting route to global IPv6 subnet
65
+	logrus.Debugf("Adding route to IPv6 network %s via device %s", config.AddressIPv6.String(), config.BridgeName)
66
+	err = netlink.RouteAdd(&netlink.Route{
67
+		Scope:     netlink.SCOPE_UNIVERSE,
68
+		LinkIndex: i.Link.Attrs().Index,
69
+		Dst:       config.AddressIPv6,
70
+	})
71
+	if err != nil && !os.IsExist(err) {
72
+		logrus.Errorf("Could not add route to IPv6 network %s via device %s", config.AddressIPv6.String(), config.BridgeName)
73
+	}
74
+
60 75
 	return nil
61 76
 }
62 77
 
63 78
 func setupGatewayIPv6(config *networkConfiguration, i *bridgeInterface) error {
79
+	if config.AddressIPv6 == nil {
80
+		return &ErrInvalidContainerSubnet{}
81
+	}
82
+	if !config.AddressIPv6.Contains(config.DefaultGatewayIPv6) {
83
+		return &ErrInvalidGateway{}
84
+	}
85
+
64 86
 	// Store requested default gateway
65 87
 	i.gatewayIPv6 = config.DefaultGatewayIPv6
88
+
66 89
 	return nil
67 90
 }
68 91
 
... ...
@@ -55,6 +55,7 @@ func TestSetupGatewayIPv6(t *testing.T) {
55 55
 
56 56
 	config := &networkConfiguration{
57 57
 		BridgeName:         DefaultBridgeName,
58
+		AddressIPv6:        nw,
58 59
 		DefaultGatewayIPv6: gw}
59 60
 
60 61
 	br := &bridgeInterface{}
... ...
@@ -622,10 +622,14 @@ func (ep *endpoint) assignAddress() error {
622 622
 		ipam ipamapi.Ipam
623 623
 		err  error
624 624
 	)
625
+
625 626
 	n := ep.getNetwork()
626 627
 	if n.Type() == "host" || n.Type() == "null" {
627 628
 		return nil
628 629
 	}
630
+
631
+	log.Debugf("Assigning addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
632
+
629 633
 	ipam, err = n.getController().getIpamDriver(n.ipamType)
630 634
 	if err != nil {
631 635
 		return err
... ...
@@ -683,6 +687,9 @@ func (ep *endpoint) releaseAddress() {
683 683
 	if n.Type() == "host" || n.Type() == "null" {
684 684
 		return
685 685
 	}
686
+
687
+	log.Debugf("Releasing addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
688
+
686 689
 	ipam, err := n.getController().getIpamDriver(n.ipamType)
687 690
 	if err != nil {
688 691
 		log.Warnf("Failed to retrieve ipam driver to release interface address on delete of endpoint %s (%s): %v", ep.Name(), ep.ID(), err)
... ...
@@ -102,8 +102,9 @@ func (a *Allocator) updateBitMasks(aSpace *addrSpace) error {
102 102
 	aSpace.Lock()
103 103
 	for k, v := range aSpace.subnets {
104 104
 		if v.Range == nil {
105
-			inserterList = append(inserterList,
106
-				func() error { return a.insertBitMask(k, v.Pool) })
105
+			kk := k
106
+			vv := v
107
+			inserterList = append(inserterList, func() error { return a.insertBitMask(kk, vv.Pool) })
107 108
 		}
108 109
 	}
109 110
 	aSpace.Unlock()
... ...
@@ -127,6 +128,7 @@ func (a *Allocator) GetDefaultAddressSpaces() (string, string, error) {
127 127
 
128 128
 // RequestPool returns an address pool along with its unique id.
129 129
 func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
130
+	log.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6)
130 131
 	k, nw, aw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6)
131 132
 	if err != nil {
132 133
 		return "", nil, nil, ipamapi.ErrInvalidPool
... ...
@@ -160,6 +162,7 @@ retry:
160 160
 
161 161
 // ReleasePool releases the address pool identified by the passed id
162 162
 func (a *Allocator) ReleasePool(poolID string) error {
163
+	log.Debugf("ReleasePool(%s)", poolID)
163 164
 	k := SubnetKey{}
164 165
 	if err := k.FromString(poolID); err != nil {
165 166
 		return types.BadRequestErrorf("invalid pool id: %s", poolID)
... ...
@@ -343,6 +346,7 @@ func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error)
343 343
 
344 344
 // RequestAddress returns an address from the specified pool ID
345 345
 func (a *Allocator) RequestAddress(poolID string, prefAddress net.IP, opts map[string]string) (*net.IPNet, map[string]string, error) {
346
+	log.Debugf("RequestAddress(%s, %v, %v)", poolID, prefAddress, opts)
346 347
 	k := SubnetKey{}
347 348
 	if err := k.FromString(poolID); err != nil {
348 349
 		return nil, nil, types.BadRequestErrorf("invalid pool id: %s", poolID)
... ...
@@ -391,6 +395,7 @@ func (a *Allocator) RequestAddress(poolID string, prefAddress net.IP, opts map[s
391 391
 
392 392
 // ReleaseAddress releases the address from the specified pool ID
393 393
 func (a *Allocator) ReleaseAddress(poolID string, address net.IP) error {
394
+	log.Debugf("ReleaseAddress(%s, %v)", poolID, address)
394 395
 	k := SubnetKey{}
395 396
 	if err := k.FromString(poolID); err != nil {
396 397
 		return types.BadRequestErrorf("invalid pool id: %s", poolID)
... ...
@@ -13,7 +13,7 @@ import (
13 13
 	"github.com/docker/libnetwork/bitseq"
14 14
 	"github.com/docker/libnetwork/datastore"
15 15
 	"github.com/docker/libnetwork/ipamapi"
16
-	"github.com/docker/libnetwork/netutils"
16
+	"github.com/docker/libnetwork/ipamutils"
17 17
 	_ "github.com/docker/libnetwork/testutils"
18 18
 	"github.com/docker/libnetwork/types"
19 19
 )
... ...
@@ -461,22 +461,33 @@ func TestPredefinedPool(t *testing.T) {
461 461
 		t.Fatalf("Expected failure for non default addr space")
462 462
 	}
463 463
 
464
-	i, available, err := getFirstAvailablePool(a, localAddressSpace, 2)
464
+	exp, err := ipamutils.FindAvailableNetwork(a.predefined[localAddressSpace])
465 465
 	if err != nil {
466
-		t.Skip(err)
466
+		t.Fatal(err)
467 467
 	}
468 468
 
469
-	pid, _, _, err := a.RequestPool(localAddressSpace, available.String(), "", nil, false)
469
+	nw, err := a.getPredefinedPool(localAddressSpace, false)
470 470
 	if err != nil {
471 471
 		t.Fatal(err)
472 472
 	}
473
+	if !types.CompareIPNet(nw, exp) {
474
+		t.Fatalf("Unexpected default network returned: %s. Expected: %s", nw, exp)
475
+	}
473 476
 
474
-	nw, err := a.getPredefinedPool(localAddressSpace, false)
477
+	pid, nw, _, err := a.RequestPool(localAddressSpace, exp.String(), "", nil, false)
475 478
 	if err != nil {
476 479
 		t.Fatal(err)
477 480
 	}
478
-	if nw != a.predefined[localAddressSpace][i+1] {
479
-		t.Fatalf("Unexpected default network returned: %s", nw)
481
+	if !types.CompareIPNet(nw, exp) {
482
+		t.Fatalf("Unexpected default network returned: %s. Expected: %s", nw, exp)
483
+	}
484
+
485
+	nw2, err := a.getPredefinedPool(localAddressSpace, false)
486
+	if err != nil {
487
+		t.Fatal(err)
488
+	}
489
+	if types.CompareIPNet(nw, nw2) {
490
+		t.Fatalf("Unexpected default network returned: %s = %s", nw2, nw)
480 491
 	}
481 492
 
482 493
 	if err := a.ReleasePool(pid); err != nil {
... ...
@@ -487,23 +498,9 @@ func TestPredefinedPool(t *testing.T) {
487 487
 	if err != nil {
488 488
 		t.Fatal(err)
489 489
 	}
490
-	if nw != a.predefined[localAddressSpace][i] {
491
-		t.Fatalf("Unexpected default network returned: %s", nw)
492
-	}
493
-}
494
-
495
-func getFirstAvailablePool(a *Allocator, as string, atLeast int) (int, *net.IPNet, error) {
496
-	i := 0
497
-	for i < len(a.predefined[as])-1 {
498
-		if err := netutils.CheckRouteOverlaps(a.predefined[as][i]); err == nil {
499
-			break
500
-		}
501
-		i++
502
-	}
503
-	if i > len(a.predefined[as])-1-atLeast {
504
-		return 0, nil, fmt.Errorf("Not enough non-overlapping networks to run the test")
490
+	if !types.CompareIPNet(nw, exp) {
491
+		t.Fatalf("Unexpected default network returned: %s. Expected %s", nw, exp)
505 492
 	}
506
-	return i, a.predefined[as][i], nil
507 493
 }
508 494
 
509 495
 func TestAdjustAndCheckSubnet(t *testing.T) {
... ...
@@ -23,6 +23,7 @@ import (
23 23
 	"github.com/docker/libnetwork/config"
24 24
 	"github.com/docker/libnetwork/datastore"
25 25
 	"github.com/docker/libnetwork/driverapi"
26
+	"github.com/docker/libnetwork/ipamapi"
26 27
 	"github.com/docker/libnetwork/netlabel"
27 28
 	"github.com/docker/libnetwork/options"
28 29
 	"github.com/docker/libnetwork/osl"
... ...
@@ -82,14 +83,10 @@ func createController() error {
82 82
 	return nil
83 83
 }
84 84
 
85
-func createTestNetwork(networkType, networkName string, netOption options.Generic) (libnetwork.Network, error) {
86
-	network, err := controller.NewNetwork(networkType, networkName,
87
-		libnetwork.NetworkOptionGeneric(netOption))
88
-	if err != nil {
89
-		return nil, err
90
-	}
91
-
92
-	return network, nil
85
+func createTestNetwork(networkType, networkName string, netOption options.Generic, ipamV4Configs, ipamV6Configs []*libnetwork.IpamConf) (libnetwork.Network, error) {
86
+	return controller.NewNetwork(networkType, networkName,
87
+		libnetwork.NetworkOptionGeneric(netOption),
88
+		libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", ipamV4Configs, ipamV6Configs))
93 89
 }
94 90
 
95 91
 func getEmptyGenericOption() map[string]interface{} {
... ...
@@ -117,7 +114,7 @@ func TestNull(t *testing.T) {
117 117
 		t.Fatal(err)
118 118
 	}
119 119
 
120
-	network, err := createTestNetwork("null", "testnull", options.Generic{})
120
+	network, err := createTestNetwork("null", "testnull", options.Generic{}, nil, nil)
121 121
 	if err != nil {
122 122
 		t.Fatal(err)
123 123
 	}
... ...
@@ -184,7 +181,7 @@ func TestHost(t *testing.T) {
184 184
 		}
185 185
 	}()
186 186
 
187
-	network, err := createTestNetwork("host", "testhost", options.Generic{})
187
+	network, err := createTestNetwork("host", "testhost", options.Generic{}, nil, nil)
188 188
 	if err != nil {
189 189
 		t.Fatal(err)
190 190
 	}
... ...
@@ -270,24 +267,18 @@ func TestBridge(t *testing.T) {
270 270
 		defer testutils.SetupTestOSContext(t)()
271 271
 	}
272 272
 
273
-	subnet, err := types.ParseCIDR("192.168.100.1/24")
274
-	if err != nil {
275
-		t.Fatal(err)
276
-	}
277
-
278
-	log.Debug("Adding a bridge")
279
-
280 273
 	netOption := options.Generic{
281 274
 		netlabel.GenericData: options.Generic{
282 275
 			"BridgeName":         "testnetwork",
283
-			"AddressIPv4":        subnet,
284 276
 			"EnableIPv6":         true,
285 277
 			"EnableICC":          true,
286 278
 			"EnableIPMasquerade": true,
287 279
 		},
288 280
 	}
281
+	ipamV4ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "192.168.100.0/24", Gateway: "192.168.100.1"}}
282
+	ipamV6ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "fe90::/98", Gateway: "fe90::22"}}
289 283
 
290
-	network, err := createTestNetwork(bridgeNetType, "testnetwork", netOption)
284
+	network, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, ipamV4ConfList, ipamV6ConfList)
291 285
 	if err != nil {
292 286
 		t.Fatal(err)
293 287
 	}
... ...
@@ -327,7 +318,7 @@ func TestUnknownDriver(t *testing.T) {
327 327
 		defer testutils.SetupTestOSContext(t)()
328 328
 	}
329 329
 
330
-	_, err := createTestNetwork("unknowndriver", "testnetwork", options.Generic{})
330
+	_, err := createTestNetwork("unknowndriver", "testnetwork", options.Generic{}, nil, nil)
331 331
 	if err == nil {
332 332
 		t.Fatal("Expected to fail. But instead succeeded")
333 333
 	}
... ...
@@ -360,7 +351,7 @@ func TestNetworkName(t *testing.T) {
360 360
 		},
361 361
 	}
362 362
 
363
-	_, err := createTestNetwork(bridgeNetType, "", netOption)
363
+	_, err := createTestNetwork(bridgeNetType, "", netOption, nil, nil)
364 364
 	if err == nil {
365 365
 		t.Fatal("Expected to fail. But instead succeeded")
366 366
 	}
... ...
@@ -370,7 +361,7 @@ func TestNetworkName(t *testing.T) {
370 370
 	}
371 371
 
372 372
 	networkName := "testnetwork"
373
-	n, err := createTestNetwork(bridgeNetType, networkName, netOption)
373
+	n, err := createTestNetwork(bridgeNetType, networkName, netOption, nil, nil)
374 374
 	if err != nil {
375 375
 		t.Fatal(err)
376 376
 	}
... ...
@@ -396,7 +387,7 @@ func TestNetworkType(t *testing.T) {
396 396
 		},
397 397
 	}
398 398
 
399
-	n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption)
399
+	n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, nil, nil)
400 400
 	if err != nil {
401 401
 		t.Fatal(err)
402 402
 	}
... ...
@@ -422,7 +413,7 @@ func TestNetworkID(t *testing.T) {
422 422
 		},
423 423
 	}
424 424
 
425
-	n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption)
425
+	n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, nil, nil)
426 426
 	if err != nil {
427 427
 		t.Fatal(err)
428 428
 	}
... ...
@@ -449,7 +440,7 @@ func TestDeleteNetworkWithActiveEndpoints(t *testing.T) {
449 449
 		netlabel.GenericData: netOption,
450 450
 	}
451 451
 
452
-	network, err := createTestNetwork(bridgeNetType, "testnetwork", option)
452
+	network, err := createTestNetwork(bridgeNetType, "testnetwork", option, nil, nil)
453 453
 	if err != nil {
454 454
 		t.Fatal(err)
455 455
 	}
... ...
@@ -490,7 +481,7 @@ func TestUnknownNetwork(t *testing.T) {
490 490
 		netlabel.GenericData: netOption,
491 491
 	}
492 492
 
493
-	network, err := createTestNetwork(bridgeNetType, "testnetwork", option)
493
+	network, err := createTestNetwork(bridgeNetType, "testnetwork", option, nil, nil)
494 494
 	if err != nil {
495 495
 		t.Fatal(err)
496 496
 	}
... ...
@@ -515,20 +506,15 @@ func TestUnknownEndpoint(t *testing.T) {
515 515
 		defer testutils.SetupTestOSContext(t)()
516 516
 	}
517 517
 
518
-	subnet, err := types.ParseCIDR("192.168.100.1/24")
519
-	if err != nil {
520
-		t.Fatal(err)
521
-	}
522
-
523 518
 	netOption := options.Generic{
524
-		"BridgeName":  "testnetwork",
525
-		"AddressIPv4": subnet,
519
+		"BridgeName": "testnetwork",
526 520
 	}
527 521
 	option := options.Generic{
528 522
 		netlabel.GenericData: netOption,
529 523
 	}
524
+	ipamV4ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "192.168.100.0/24"}}
530 525
 
531
-	network, err := createTestNetwork(bridgeNetType, "testnetwork", option)
526
+	network, err := createTestNetwork(bridgeNetType, "testnetwork", option, ipamV4ConfList, nil)
532 527
 	if err != nil {
533 528
 		t.Fatal(err)
534 529
 	}
... ...
@@ -569,7 +555,7 @@ func TestNetworkEndpointsWalkers(t *testing.T) {
569 569
 		},
570 570
 	}
571 571
 
572
-	net1, err := createTestNetwork(bridgeNetType, "network1", netOption)
572
+	net1, err := createTestNetwork(bridgeNetType, "network1", netOption, nil, nil)
573 573
 	if err != nil {
574 574
 		t.Fatal(err)
575 575
 	}
... ...
@@ -641,7 +627,7 @@ func TestNetworkEndpointsWalkers(t *testing.T) {
641 641
 		},
642 642
 	}
643 643
 
644
-	net2, err := createTestNetwork(bridgeNetType, "network2", netOption)
644
+	net2, err := createTestNetwork(bridgeNetType, "network2", netOption, nil, nil)
645 645
 	if err != nil {
646 646
 		t.Fatal(err)
647 647
 	}
... ...
@@ -697,7 +683,7 @@ func TestDuplicateEndpoint(t *testing.T) {
697 697
 			"BridgeName": "testnetwork",
698 698
 		},
699 699
 	}
700
-	n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption)
700
+	n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, nil, nil)
701 701
 	if err != nil {
702 702
 		t.Fatal(err)
703 703
 	}
... ...
@@ -747,7 +733,7 @@ func TestControllerQuery(t *testing.T) {
747 747
 			"BridgeName": "network1",
748 748
 		},
749 749
 	}
750
-	net1, err := createTestNetwork(bridgeNetType, "network1", netOption)
750
+	net1, err := createTestNetwork(bridgeNetType, "network1", netOption, nil, nil)
751 751
 	if err != nil {
752 752
 		t.Fatal(err)
753 753
 	}
... ...
@@ -763,7 +749,7 @@ func TestControllerQuery(t *testing.T) {
763 763
 			"BridgeName": "network2",
764 764
 		},
765 765
 	}
766
-	net2, err := createTestNetwork(bridgeNetType, "network2", netOption)
766
+	net2, err := createTestNetwork(bridgeNetType, "network2", netOption, nil, nil)
767 767
 	if err != nil {
768 768
 		t.Fatal(err)
769 769
 	}
... ...
@@ -849,7 +835,7 @@ func TestNetworkQuery(t *testing.T) {
849 849
 			"BridgeName": "network1",
850 850
 		},
851 851
 	}
852
-	net1, err := createTestNetwork(bridgeNetType, "network1", netOption)
852
+	net1, err := createTestNetwork(bridgeNetType, "network1", netOption, nil, nil)
853 853
 	if err != nil {
854 854
 		t.Fatal(err)
855 855
 	}
... ...
@@ -969,7 +955,7 @@ func TestEndpointJoin(t *testing.T) {
969 969
 		netlabel.GenericData: options.Generic{
970 970
 			"BridgeName": "testnetwork1",
971 971
 		},
972
-	})
972
+	}, nil, nil)
973 973
 	if err != nil {
974 974
 		t.Fatal(err)
975 975
 	}
... ...
@@ -1078,7 +1064,7 @@ func TestEndpointJoin(t *testing.T) {
1078 1078
 			netlabel.GenericData: options.Generic{
1079 1079
 				"BridgeName": "testnetwork2",
1080 1080
 			},
1081
-		})
1081
+		}, nil, nil)
1082 1082
 	if err != nil {
1083 1083
 		t.Fatal(err)
1084 1084
 	}
... ...
@@ -1169,7 +1155,7 @@ func externalKeyTest(t *testing.T, reexec bool) {
1169 1169
 		netlabel.GenericData: options.Generic{
1170 1170
 			"BridgeName": "testnetwork",
1171 1171
 		},
1172
-	})
1172
+	}, nil, nil)
1173 1173
 	if err != nil {
1174 1174
 		t.Fatal(err)
1175 1175
 	}
... ...
@@ -1318,7 +1304,7 @@ func TestEndpointDeleteWithActiveContainer(t *testing.T) {
1318 1318
 		netlabel.GenericData: options.Generic{
1319 1319
 			"BridgeName": "testnetwork",
1320 1320
 		},
1321
-	})
1321
+	}, nil, nil)
1322 1322
 	if err != nil {
1323 1323
 		t.Fatal(err)
1324 1324
 	}
... ...
@@ -1381,7 +1367,7 @@ func TestEndpointMultipleJoins(t *testing.T) {
1381 1381
 		netlabel.GenericData: options.Generic{
1382 1382
 			"BridgeName": "testmultiple",
1383 1383
 		},
1384
-	})
1384
+	}, nil, nil)
1385 1385
 	if err != nil {
1386 1386
 		t.Fatal(err)
1387 1387
 	}
... ...
@@ -1452,7 +1438,7 @@ func TestLeaveAll(t *testing.T) {
1452 1452
 		netlabel.GenericData: options.Generic{
1453 1453
 			"BridgeName": "testnetwork",
1454 1454
 		},
1455
-	})
1455
+	}, nil, nil)
1456 1456
 	if err != nil {
1457 1457
 		t.Fatal(err)
1458 1458
 	}
... ...
@@ -1505,7 +1491,7 @@ func TestontainerInvalidLeave(t *testing.T) {
1505 1505
 		netlabel.GenericData: options.Generic{
1506 1506
 			"BridgeName": "testnetwork",
1507 1507
 		},
1508
-	})
1508
+	}, nil, nil)
1509 1509
 	if err != nil {
1510 1510
 		t.Fatal(err)
1511 1511
 	}
... ...
@@ -1571,7 +1557,7 @@ func TestEndpointUpdateParent(t *testing.T) {
1571 1571
 		netlabel.GenericData: options.Generic{
1572 1572
 			"BridgeName": "testnetwork",
1573 1573
 		},
1574
-	})
1574
+	}, nil, nil)
1575 1575
 	if err != nil {
1576 1576
 		t.Fatal(err)
1577 1577
 	}
... ...
@@ -1655,8 +1641,9 @@ func TestEnableIPv6(t *testing.T) {
1655 1655
 			"BridgeName": "testnetwork",
1656 1656
 		},
1657 1657
 	}
1658
+	ipamV6ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "fe80::/98"}}
1658 1659
 
1659
-	n, err := createTestNetwork("bridge", "testnetwork", netOption)
1660
+	n, err := createTestNetwork("bridge", "testnetwork", netOption, nil, ipamV6ConfList)
1660 1661
 	if err != nil {
1661 1662
 		t.Fatal(err)
1662 1663
 	}
... ...
@@ -1814,7 +1801,7 @@ func TestResolvConf(t *testing.T) {
1814 1814
 			"BridgeName": "testnetwork",
1815 1815
 		},
1816 1816
 	}
1817
-	n, err := createTestNetwork("bridge", "testnetwork", netOption)
1817
+	n, err := createTestNetwork("bridge", "testnetwork", netOption, nil, nil)
1818 1818
 	if err != nil {
1819 1819
 		t.Fatal(err)
1820 1820
 	}
... ...
@@ -2084,7 +2071,7 @@ func createGlobalInstance(t *testing.T) {
2084 2084
 		t.Fatal(err)
2085 2085
 	}
2086 2086
 
2087
-	net2, err := createTestNetwork("bridge", "network2", netOption)
2087
+	net2, err := createTestNetwork("bridge", "network2", netOption, nil, nil)
2088 2088
 	if err != nil {
2089 2089
 		t.Fatal(err)
2090 2090
 	}
... ...
@@ -852,7 +852,7 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error {
852 852
 
853 853
 	*infoList = make([]*IpamInfo, len(*cfgList))
854 854
 
855
-	log.Debugf("allocating IPv%d pools for network %s (%s)", ipVer, n.Name(), n.ID())
855
+	log.Debugf("Allocating IPv%d pools for network %s (%s)", ipVer, n.Name(), n.ID())
856 856
 
857 857
 	for i, cfg := range *cfgList {
858 858
 		if err = cfg.Validate(); err != nil {