Browse code

Account dcoker0 IPv6 address on daemon start

- In case --fixed-cidr-v6 is specified and docker0 bridge already
has a global scope IPv6 address belonging to that v6 network
(likely from a previous daemon instance), to maintain consistency
with what done for the docker0 IPv4 address, daemon has to pass it
down to libnetwork in the IPAMConfig as network gateway to make
sure that the address is not given to some container.

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

Alessandro Boch authored on 2016/01/12 16:47:44
Showing 1 changed files
... ...
@@ -528,12 +528,16 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
528 528
 		netOption[bridge.DefaultBindingIP] = config.Bridge.DefaultIP.String()
529 529
 	}
530 530
 
531
-	ipamV4Conf := libnetwork.IpamConf{}
531
+	var (
532
+		ipamV4Conf *libnetwork.IpamConf
533
+		ipamV6Conf *libnetwork.IpamConf
534
+	)
532 535
 
533
-	ipamV4Conf.AuxAddresses = make(map[string]string)
536
+	ipamV4Conf = &libnetwork.IpamConf{AuxAddresses: make(map[string]string)}
534 537
 
535
-	if nw, _, err := ipamutils.ElectInterfaceAddresses(bridgeName); err == nil {
536
-		ipamV4Conf.PreferredPool = nw.String()
538
+	nw, nw6List, err := ipamutils.ElectInterfaceAddresses(bridgeName)
539
+	if err == nil {
540
+		ipamV4Conf.PreferredPool = types.GetIPNetCanonical(nw).String()
537 541
 		hip, _ := types.GetHostPartIP(nw.IP, nw.Mask)
538 542
 		if hip.IsGlobalUnicast() {
539 543
 			ipamV4Conf.Gateway = nw.IP.String()
... ...
@@ -564,10 +568,7 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
564 564
 		ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.Bridge.DefaultGatewayIPv4.String()
565 565
 	}
566 566
 
567
-	var (
568
-		ipamV6Conf     *libnetwork.IpamConf
569
-		deferIPv6Alloc bool
570
-	)
567
+	var deferIPv6Alloc bool
571 568
 	if config.Bridge.FixedCIDRv6 != "" {
572 569
 		_, fCIDRv6, err := net.ParseCIDR(config.Bridge.FixedCIDRv6)
573 570
 		if err != nil {
... ...
@@ -587,6 +588,16 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
587 587
 			ipamV6Conf = &libnetwork.IpamConf{AuxAddresses: make(map[string]string)}
588 588
 		}
589 589
 		ipamV6Conf.PreferredPool = fCIDRv6.String()
590
+
591
+		// In case the --fixed-cidr-v6 is specified and the current docker0 bridge IPv6
592
+		// address belongs to the same network, we need to inform libnetwork about it, so
593
+		// that it can be reserved with IPAM and it will not be given away to somebody else
594
+		for _, nw6 := range nw6List {
595
+			if fCIDRv6.Contains(nw6.IP) {
596
+				ipamV6Conf.Gateway = nw6.IP.String()
597
+				break
598
+			}
599
+		}
590 600
 	}
591 601
 
592 602
 	if config.Bridge.DefaultGatewayIPv6 != nil {
... ...
@@ -596,13 +607,13 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
596 596
 		ipamV6Conf.AuxAddresses["DefaultGatewayIPv6"] = config.Bridge.DefaultGatewayIPv6.String()
597 597
 	}
598 598
 
599
-	v4Conf := []*libnetwork.IpamConf{&ipamV4Conf}
599
+	v4Conf := []*libnetwork.IpamConf{ipamV4Conf}
600 600
 	v6Conf := []*libnetwork.IpamConf{}
601 601
 	if ipamV6Conf != nil {
602 602
 		v6Conf = append(v6Conf, ipamV6Conf)
603 603
 	}
604 604
 	// Initialize default network on "bridge" with the same name
605
-	_, err := controller.NewNetwork("bridge", "bridge",
605
+	_, err = controller.NewNetwork("bridge", "bridge",
606 606
 		libnetwork.NetworkOptionGeneric(options.Generic{
607 607
 			netlabel.GenericData: netOption,
608 608
 			netlabel.EnableIPv6:  config.Bridge.EnableIPv6,