1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Check if present before programming IPv6 in bridge

Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
Alessandro Boch 2016-01-06 18:13:08 -08:00
parent dfea2836a5
commit e22b54dee1
3 changed files with 37 additions and 23 deletions

View file

@ -1,6 +1,7 @@
package bridge package bridge
import ( import (
"fmt"
"net" "net"
"github.com/vishvananda/netlink" "github.com/vishvananda/netlink"
@ -61,3 +62,18 @@ func (i *bridgeInterface) addresses() (netlink.Addr, []netlink.Addr, error) {
} }
return v4addr[0], v6addr, nil return v4addr[0], v6addr, nil
} }
func (i *bridgeInterface) programIPv6Address() error {
_, nlAddressList, err := i.addresses()
if err != nil {
return &IPv6AddrAddError{IP: i.bridgeIPv6, Err: fmt.Errorf("failed to retrieve address list: %v", err)}
}
nlAddr := netlink.Addr{IPNet: i.bridgeIPv6}
if findIPv6Address(nlAddr, nlAddressList) {
return nil
}
if err := netlink.AddrAdd(i.Link, &nlAddr); err != nil {
return &IPv6AddrAddError{IP: i.bridgeIPv6, Err: err}
}
return nil
}

View file

@ -7,6 +7,7 @@ import (
"os" "os"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink" "github.com/vishvananda/netlink"
) )
@ -22,9 +23,8 @@ const (
func init() { func init() {
// We allow ourselves to panic in this special case because we indicate a // We allow ourselves to panic in this special case because we indicate a
// failure to parse a compile-time define constant. // failure to parse a compile-time define constant.
if ip, netw, err := net.ParseCIDR(bridgeIPv6Str); err == nil { var err error
bridgeIPv6 = &net.IPNet{IP: ip, Mask: netw.Mask} if bridgeIPv6, err = types.ParseCIDR(bridgeIPv6Str); err != nil {
} else {
panic(fmt.Sprintf("Cannot parse default bridge IPv6 address %q: %v", bridgeIPv6Str, err)) panic(fmt.Sprintf("Cannot parse default bridge IPv6 address %q: %v", bridgeIPv6Str, err))
} }
} }
@ -42,31 +42,24 @@ func setupBridgeIPv6(config *networkConfiguration, i *bridgeInterface) error {
} }
} }
_, addrsv6, err := i.addresses()
if err != nil {
return err
}
// Add the default link local ipv6 address if it doesn't exist
if !findIPv6Address(netlink.Addr{IPNet: bridgeIPv6}, addrsv6) {
if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: bridgeIPv6}); err != nil {
return &IPv6AddrAddError{IP: bridgeIPv6, Err: err}
}
}
// Store bridge network and default gateway // Store bridge network and default gateway
i.bridgeIPv6 = bridgeIPv6 i.bridgeIPv6 = bridgeIPv6
i.gatewayIPv6 = i.bridgeIPv6.IP i.gatewayIPv6 = i.bridgeIPv6.IP
if err := i.programIPv6Address(); err != nil {
return err
}
if config.AddressIPv6 == nil { if config.AddressIPv6 == nil {
return nil return nil
} }
// Store and program user specified bridge network and network gateway // Store the user specified bridge network and network gateway and program it
i.bridgeIPv6 = config.AddressIPv6 i.bridgeIPv6 = config.AddressIPv6
i.gatewayIPv6 = config.AddressIPv6.IP i.gatewayIPv6 = config.AddressIPv6.IP
if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: i.bridgeIPv6}); err != nil {
return &IPv6AddrAddError{IP: i.bridgeIPv6, Err: err} if err := i.programIPv6Address(); err != nil {
return err
} }
// Setting route to global IPv6 subnet // Setting route to global IPv6 subnet

View file

@ -1,6 +1,8 @@
package bridge package bridge
import ( import (
log "github.com/Sirupsen/logrus"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink" "github.com/vishvananda/netlink"
) )
@ -27,11 +29,14 @@ func setupVerifyAndReconcile(config *networkConfiguration, i *bridgeInterface) e
return (*IPv6AddrNoMatchError)(bridgeIPv6) return (*IPv6AddrNoMatchError)(bridgeIPv6)
} }
// By this time we have either configured a new bridge with an IP address // Release any residual IPv6 address that might be there because of older daemon instances
// or made sure an existing bridge's IP matches the configuration for _, addrv6 := range addrsv6 {
// Now is the time to cache these states in the bridgeInterface. if addrv6.IP.IsGlobalUnicast() && !types.CompareIPNet(addrv6.IPNet, i.bridgeIPv6) {
i.bridgeIPv4 = addrv4.IPNet if err := netlink.AddrDel(i.Link, &addrv6); err != nil {
i.bridgeIPv6 = bridgeIPv6 log.Warnf("Failed to remove residual IPv6 address %s from bridge: %v", addrv6.IPNet, err)
}
}
}
return nil return nil
} }