Bläddra i källkod

Merge pull request #10406 from estesp/fixup-ipv6-bridge-creation

Fix bridge initialization for IPv6 if IPv4-only docker0 exists
Arnaud Porterie 10 år sedan
förälder
incheckning
45ef269498
2 ändrade filer med 41 tillägg och 14 borttagningar
  1. 40 13
      daemon/networkdriver/bridge/driver.go
  2. 1 1
      daemon/networkdriver/utils.go

+ 40 - 13
daemon/networkdriver/bridge/driver.go

@@ -150,6 +150,21 @@ func InitDriver(job *engine.Job) engine.Status {
 			}
 			}
 		}
 		}
 
 
+		// a bridge might exist but not have any IPv6 addr associated with it yet
+		// (for example, an existing Docker installation that has only been used
+		// with IPv4 and docker0 already is set up) In that case, we can perform
+		// the bridge init for IPv6 here, else we will error out below if --ipv6=true
+		if len(addrsv6) == 0 && enableIPv6 {
+			if err := setupIPv6Bridge(bridgeIPv6); err != nil {
+				return job.Error(err)
+			}
+			// recheck addresses now that IPv6 is setup on the bridge
+			addrv4, addrsv6, err = networkdriver.GetIfaceAddr(bridgeIface)
+			if err != nil {
+				return job.Error(err)
+			}
+		}
+
 		// TODO: Check if route to fixedCIDRv6 is set
 		// TODO: Check if route to fixedCIDRv6 is set
 	}
 	}
 
 
@@ -401,21 +416,9 @@ func configureBridge(bridgeIP string, bridgeIPv6 string, enableIPv6 bool) error
 	}
 	}
 
 
 	if enableIPv6 {
 	if enableIPv6 {
-		// Enable IPv6 on the bridge
-		procFile := "/proc/sys/net/ipv6/conf/" + iface.Name + "/disable_ipv6"
-		if err := ioutil.WriteFile(procFile, []byte{'0', '\n'}, 0644); err != nil {
-			return fmt.Errorf("unable to enable IPv6 addresses on bridge: %s\n", err)
-		}
-
-		ipAddr6, ipNet6, err := net.ParseCIDR(bridgeIPv6)
-		if err != nil {
-			log.Errorf("BridgeIPv6 parsing failed")
+		if err := setupIPv6Bridge(bridgeIPv6); err != nil {
 			return err
 			return err
 		}
 		}
-
-		if err := netlink.NetworkLinkAddIp(iface, ipAddr6, ipNet6); err != nil {
-			return fmt.Errorf("Unable to add private IPv6 network: %s", err)
-		}
 	}
 	}
 
 
 	if err := netlink.NetworkLinkUp(iface); err != nil {
 	if err := netlink.NetworkLinkUp(iface); err != nil {
@@ -424,6 +427,30 @@ func configureBridge(bridgeIP string, bridgeIPv6 string, enableIPv6 bool) error
 	return nil
 	return nil
 }
 }
 
 
+func setupIPv6Bridge(bridgeIPv6 string) error {
+
+	iface, err := net.InterfaceByName(bridgeIface)
+	if err != nil {
+		return err
+	}
+	// Enable IPv6 on the bridge
+	procFile := "/proc/sys/net/ipv6/conf/" + iface.Name + "/disable_ipv6"
+	if err := ioutil.WriteFile(procFile, []byte{'0', '\n'}, 0644); err != nil {
+		return fmt.Errorf("Unable to enable IPv6 addresses on bridge: %v", err)
+	}
+
+	ipAddr6, ipNet6, err := net.ParseCIDR(bridgeIPv6)
+	if err != nil {
+		return fmt.Errorf("Unable to parse bridge IPv6 address: %q, error: %v", bridgeIPv6, err)
+	}
+
+	if err := netlink.NetworkLinkAddIp(iface, ipAddr6, ipNet6); err != nil {
+		return fmt.Errorf("Unable to add private IPv6 network: %v", err)
+	}
+
+	return nil
+}
+
 func createBridgeIface(name string) error {
 func createBridgeIface(name string) error {
 	kv, err := kernel.GetKernelVersion()
 	kv, err := kernel.GetKernelVersion()
 	// only set the bridge's mac address if the kernel version is > 3.3
 	// only set the bridge's mac address if the kernel version is > 3.3

+ 1 - 1
daemon/networkdriver/utils.go

@@ -74,7 +74,7 @@ func NetworkRange(network *net.IPNet) (net.IP, net.IP) {
 	return netIP.Mask(network.Mask), net.IP(lastIP)
 	return netIP.Mask(network.Mask), net.IP(lastIP)
 }
 }
 
 
-// Return the IPv4 address of a network interface
+// Return the first IPv4 address and slice of IPv6 addresses for the specified network interface
 func GetIfaceAddr(name string) (net.Addr, []net.Addr, error) {
 func GetIfaceAddr(name string) (net.Addr, []net.Addr, error) {
 	iface, err := net.InterfaceByName(name)
 	iface, err := net.InterfaceByName(name)
 	if err != nil {
 	if err != nil {