Browse code

Docker side changes for the newly introduced IPAM driver

* Made use of IPAM driver primitives for legacy IP configurations
* Replaced custom Generics with backend labels

Signed-off-by: Madhu Venugopal <madhu@docker.com>

Madhu Venugopal authored on 2015/10/11 01:43:03
Showing 6 changed files
... ...
@@ -204,12 +204,12 @@ func buildEndpointResource(e libnetwork.Endpoint) types.EndpointResource {
204 204
 		if mac := iface.MacAddress(); mac != nil {
205 205
 			er.MacAddress = mac.String()
206 206
 		}
207
-		if ip := iface.Address(); len(ip.IP) > 0 {
208
-			er.IPv4Address = (&ip).String()
207
+		if ip := iface.Address(); ip != nil && len(ip.IP) > 0 {
208
+			er.IPv4Address = ip.String()
209 209
 		}
210 210
 
211
-		if ipv6 := iface.AddressIPv6(); len(ipv6.IP) > 0 {
212
-			er.IPv6Address = (&ipv6).String()
211
+		if ipv6 := iface.AddressIPv6(); ipv6 != nil && len(ipv6.IP) > 0 {
212
+			er.IPv6Address = ipv6.String()
213 213
 		}
214 214
 	}
215 215
 	return er
... ...
@@ -30,6 +30,7 @@ import (
30 30
 	"github.com/docker/docker/volume"
31 31
 	"github.com/docker/docker/volume/store"
32 32
 	"github.com/docker/libnetwork"
33
+	"github.com/docker/libnetwork/drivers/bridge"
33 34
 	"github.com/docker/libnetwork/netlabel"
34 35
 	"github.com/docker/libnetwork/options"
35 36
 	"github.com/docker/libnetwork/types"
... ...
@@ -651,11 +652,13 @@ func (container *Container) buildEndpointInfo(ep libnetwork.Endpoint, networkSet
651 651
 		return networkSettings, nil
652 652
 	}
653 653
 
654
-	ones, _ := iface.Address().Mask.Size()
655
-	networkSettings.IPAddress = iface.Address().IP.String()
656
-	networkSettings.IPPrefixLen = ones
654
+	if iface.Address() != nil {
655
+		ones, _ := iface.Address().Mask.Size()
656
+		networkSettings.IPAddress = iface.Address().IP.String()
657
+		networkSettings.IPPrefixLen = ones
658
+	}
657 659
 
658
-	if iface.AddressIPv6().IP.To16() != nil {
660
+	if iface.AddressIPv6() != nil && iface.AddressIPv6().IP.To16() != nil {
659 661
 		onesv6, _ := iface.AddressIPv6().Mask.Size()
660 662
 		networkSettings.GlobalIPv6Address = iface.AddressIPv6().IP.String()
661 663
 		networkSettings.GlobalIPv6PrefixLen = onesv6
... ...
@@ -861,9 +864,8 @@ func createNetwork(controller libnetwork.NetworkController, dnet string, driver
861 861
 
862 862
 	// Bridge driver is special due to legacy reasons
863 863
 	if runconfig.NetworkMode(driver).IsBridge() {
864
-		genericOption[netlabel.GenericData] = map[string]interface{}{
865
-			"BridgeName":            dnet,
866
-			"AllowNonDefaultBridge": "true",
864
+		genericOption[netlabel.GenericData] = map[string]string{
865
+			bridge.BridgeName: dnet,
867 866
 		}
868 867
 		networkOption := libnetwork.NetworkOptionGeneric(genericOption)
869 868
 		createOptions = append(createOptions, networkOption)
... ...
@@ -1163,7 +1165,7 @@ func (container *Container) disconnectFromNetwork(n libnetwork.Network, updateSe
1163 1163
 	n.WalkEndpoints(s)
1164 1164
 
1165 1165
 	if ep == nil {
1166
-		return fmt.Errorf("could not locate network endpoint for container %s", container.ID)
1166
+		return fmt.Errorf("container %s is not connected to the network", container.ID)
1167 1167
 	}
1168 1168
 
1169 1169
 	if err := ep.Leave(sbox); err != nil {
... ...
@@ -7,6 +7,7 @@ import (
7 7
 	"net"
8 8
 	"os"
9 9
 	"path/filepath"
10
+	"strconv"
10 11
 	"strings"
11 12
 	"syscall"
12 13
 
... ...
@@ -23,8 +24,11 @@ import (
23 23
 	"github.com/docker/docker/utils"
24 24
 	"github.com/docker/libnetwork"
25 25
 	nwconfig "github.com/docker/libnetwork/config"
26
+	"github.com/docker/libnetwork/drivers/bridge"
27
+	"github.com/docker/libnetwork/ipamutils"
26 28
 	"github.com/docker/libnetwork/netlabel"
27 29
 	"github.com/docker/libnetwork/options"
30
+	"github.com/docker/libnetwork/types"
28 31
 	"github.com/opencontainers/runc/libcontainer/label"
29 32
 	"github.com/vishvananda/netlink"
30 33
 )
... ...
@@ -312,6 +316,9 @@ func (daemon *Daemon) networkOptions(dconfig *Config) ([]nwconfig.Option, error)
312 312
 	if dconfig == nil {
313 313
 		return options, nil
314 314
 	}
315
+
316
+	options = append(options, nwconfig.OptionDataDir(dconfig.Root))
317
+
315 318
 	if strings.TrimSpace(dconfig.DefaultNetwork) != "" {
316 319
 		dn := strings.Split(dconfig.DefaultNetwork, ":")
317 320
 		if len(dn) < 2 {
... ...
@@ -392,22 +399,48 @@ func driverOptions(config *Config) []nwconfig.Option {
392 392
 }
393 393
 
394 394
 func initBridgeDriver(controller libnetwork.NetworkController, config *Config) error {
395
-	netOption := options.Generic{
396
-		"BridgeName":         config.Bridge.Iface,
397
-		"DefaultBridge":      true,
398
-		"Mtu":                config.Mtu,
399
-		"EnableIPMasquerade": config.Bridge.EnableIPMasq,
400
-		"EnableICC":          config.Bridge.InterContainerCommunication,
395
+	if n, err := controller.NetworkByName("bridge"); err == nil {
396
+		if err = n.Delete(); err != nil {
397
+			return fmt.Errorf("could not delete the default bridge network: %v", err)
398
+		}
399
+	}
400
+
401
+	bridgeName := bridge.DefaultBridgeName
402
+	if config.Bridge.Iface != "" {
403
+		bridgeName = config.Bridge.Iface
404
+	}
405
+	netOption := map[string]string{
406
+		bridge.BridgeName:         bridgeName,
407
+		bridge.DefaultBridge:      strconv.FormatBool(true),
408
+		netlabel.DriverMTU:        strconv.Itoa(config.Mtu),
409
+		bridge.EnableIPMasquerade: strconv.FormatBool(config.Bridge.EnableIPMasq),
410
+		bridge.EnableICC:          strconv.FormatBool(config.Bridge.InterContainerCommunication),
411
+	}
412
+
413
+	// --ip processing
414
+	if config.Bridge.DefaultIP != nil {
415
+		netOption[bridge.DefaultBindingIP] = config.Bridge.DefaultIP.String()
416
+	}
417
+
418
+	ipamV4Conf := libnetwork.IpamConf{}
419
+
420
+	ipamV4Conf.AuxAddresses = make(map[string]string)
421
+
422
+	if nw, _, err := ipamutils.ElectInterfaceAddresses(bridgeName); err == nil {
423
+		ipamV4Conf.PreferredPool = nw.String()
424
+		hip, _ := types.GetHostPartIP(nw.IP, nw.Mask)
425
+		if hip.IsGlobalUnicast() {
426
+			ipamV4Conf.Gateway = nw.IP.String()
427
+		}
401 428
 	}
402 429
 
403 430
 	if config.Bridge.IP != "" {
404
-		ip, bipNet, err := net.ParseCIDR(config.Bridge.IP)
431
+		ipamV4Conf.PreferredPool = config.Bridge.IP
432
+		ip, _, err := net.ParseCIDR(config.Bridge.IP)
405 433
 		if err != nil {
406 434
 			return err
407 435
 		}
408
-
409
-		bipNet.IP = ip
410
-		netOption["AddressIPv4"] = bipNet
436
+		ipamV4Conf.Gateway = ip.String()
411 437
 	}
412 438
 
413 439
 	if config.Bridge.FixedCIDR != "" {
... ...
@@ -416,38 +449,44 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
416 416
 			return err
417 417
 		}
418 418
 
419
-		netOption["FixedCIDR"] = fCIDR
419
+		ipamV4Conf.SubPool = fCIDR.String()
420 420
 	}
421 421
 
422
+	if config.Bridge.DefaultGatewayIPv4 != nil {
423
+		ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.Bridge.DefaultGatewayIPv4.String()
424
+	}
425
+
426
+	var ipamV6Conf *libnetwork.IpamConf
422 427
 	if config.Bridge.FixedCIDRv6 != "" {
423 428
 		_, fCIDRv6, err := net.ParseCIDR(config.Bridge.FixedCIDRv6)
424 429
 		if err != nil {
425 430
 			return err
426 431
 		}
427
-
428
-		netOption["FixedCIDRv6"] = fCIDRv6
429
-	}
430
-
431
-	if config.Bridge.DefaultGatewayIPv4 != nil {
432
-		netOption["DefaultGatewayIPv4"] = config.Bridge.DefaultGatewayIPv4
432
+		if ipamV6Conf == nil {
433
+			ipamV6Conf = &libnetwork.IpamConf{}
434
+		}
435
+		ipamV6Conf.PreferredPool = fCIDRv6.String()
433 436
 	}
434 437
 
435 438
 	if config.Bridge.DefaultGatewayIPv6 != nil {
436
-		netOption["DefaultGatewayIPv6"] = config.Bridge.DefaultGatewayIPv6
439
+		if ipamV6Conf == nil {
440
+			ipamV6Conf = &libnetwork.IpamConf{}
441
+		}
442
+		ipamV6Conf.AuxAddresses["DefaultGatewayIPv6"] = config.Bridge.DefaultGatewayIPv6.String()
437 443
 	}
438 444
 
439
-	// --ip processing
440
-	if config.Bridge.DefaultIP != nil {
441
-		netOption["DefaultBindingIP"] = config.Bridge.DefaultIP
445
+	v4Conf := []*libnetwork.IpamConf{&ipamV4Conf}
446
+	v6Conf := []*libnetwork.IpamConf{}
447
+	if ipamV6Conf != nil {
448
+		v6Conf = append(v6Conf, ipamV6Conf)
442 449
 	}
443
-
444 450
 	// Initialize default network on "bridge" with the same name
445 451
 	_, err := controller.NewNetwork("bridge", "bridge",
446 452
 		libnetwork.NetworkOptionGeneric(options.Generic{
447 453
 			netlabel.GenericData: netOption,
448 454
 			netlabel.EnableIPv6:  config.Bridge.EnableIPv6,
449 455
 		}),
450
-		libnetwork.NetworkOptionPersist(false))
456
+		libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf))
451 457
 	if err != nil {
452 458
 		return fmt.Errorf("Error creating default \"bridge\" network: %v", err)
453 459
 	}
... ...
@@ -6,6 +6,7 @@ import (
6 6
 
7 7
 	"github.com/docker/libnetwork"
8 8
 	"github.com/docker/libnetwork/netlabel"
9
+	"github.com/docker/libnetwork/options"
9 10
 )
10 11
 
11 12
 const (
... ...
@@ -78,29 +79,14 @@ func (daemon *Daemon) GetNetworksByID(partialID string) []libnetwork.Network {
78 78
 }
79 79
 
80 80
 // CreateNetwork creates a network with the given name, driver and other optional parameters
81
-func (daemon *Daemon) CreateNetwork(name, driver string, options map[string]interface{}) (libnetwork.Network, error) {
81
+func (daemon *Daemon) CreateNetwork(name, driver string, labels map[string]interface{}) (libnetwork.Network, error) {
82 82
 	c := daemon.netController
83 83
 	if driver == "" {
84 84
 		driver = c.Config().Daemon.DefaultDriver
85 85
 	}
86
+	option := libnetwork.NetworkOptionGeneric(options.Generic{
87
+		netlabel.GenericData: map[string]string{},
88
+	})
86 89
 
87
-	if options == nil {
88
-		options = make(map[string]interface{})
89
-	}
90
-	_, ok := options[netlabel.GenericData]
91
-	if !ok {
92
-		options[netlabel.GenericData] = make(map[string]interface{})
93
-	}
94
-
95
-	return c.NewNetwork(driver, name, parseOptions(options)...)
96
-}
97
-
98
-func parseOptions(options map[string]interface{}) []libnetwork.NetworkOption {
99
-	var setFctList []libnetwork.NetworkOption
100
-
101
-	if options != nil {
102
-		setFctList = append(setFctList, libnetwork.NetworkOptionGeneric(options))
103
-	}
104
-
105
-	return setFctList
90
+	return c.NewNetwork(driver, name, option)
106 91
 }
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"github.com/docker/docker/api/types/versions/v1p20"
9 9
 	"github.com/docker/docker/daemon/execdriver"
10 10
 	"github.com/docker/docker/pkg/version"
11
-	"github.com/docker/libnetwork/osl"
11
+	lntypes "github.com/docker/libnetwork/types"
12 12
 	"github.com/opencontainers/runc/libcontainer"
13 13
 )
14 14
 
... ...
@@ -166,7 +166,7 @@ func (daemon *Daemon) getNetworkStats(c *Container) ([]*libcontainer.NetworkInte
166 166
 	return list, nil
167 167
 }
168 168
 
169
-func convertLnNetworkStats(name string, stats *osl.InterfaceStatistics) *libcontainer.NetworkInterface {
169
+func convertLnNetworkStats(name string, stats *lntypes.InterfaceStatistics) *libcontainer.NetworkInterface {
170 170
 	n := &libcontainer.NetworkInterface{Name: name}
171 171
 	n.RxBytes = stats.RxBytes
172 172
 	n.RxPackets = stats.RxPackets
... ...
@@ -787,7 +787,7 @@ func (s *DockerDaemonSuite) TestDaemonBridgeFixedCidr(c *check.C) {
787 787
 		cName := "Container" + strconv.Itoa(i)
788 788
 		out, err := d.Cmd("run", "-d", "--name", cName, "busybox", "top")
789 789
 		if err != nil {
790
-			c.Assert(strings.Contains(out, "no available ip addresses"), check.Equals, true,
790
+			c.Assert(strings.Contains(out, "no available IPv4 addresses"), check.Equals, true,
791 791
 				check.Commentf("Could not run a Container : %s %s", err.Error(), out))
792 792
 		}
793 793
 	}