mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Fix bridge initialization for IPv6 if IPv4-only docker0 exists
This fixes the daemon's failure to start when setting --ipv6=true for the first time without deleting `docker0` bridge from a prior use with only IPv4 addressing. The addition of the IPv6 bridge address is factored out into a separate initialization routine which is called even if the bridge exists but no IPv6 addresses are found. Docker-DCO-1.1-Signed-off-by: Phil Estes <estesp@linux.vnet.ibm.com> (github: estesp)
This commit is contained in:
parent
3ac5596fe0
commit
0c8d17b5c1
2 changed files with 41 additions and 14 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -401,21 +416,9 @@ func configureBridge(bridgeIP string, bridgeIPv6 string, enableIPv6 bool) error
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -424,6 +427,30 @@ func configureBridge(bridgeIP string, bridgeIPv6 string, enableIPv6 bool) error
|
|||
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 {
|
||||
kv, err := kernel.GetKernelVersion()
|
||||
// only set the bridge's mac address if the kernel version is > 3.3
|
||||
|
|
|
@ -74,7 +74,7 @@ func NetworkRange(network *net.IPNet) (net.IP, net.IP) {
|
|||
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) {
|
||||
iface, err := net.InterfaceByName(name)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue