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:
parent
dfea2836a5
commit
e22b54dee1
3 changed files with 37 additions and 23 deletions
|
@ -1,6 +1,7 @@
|
|||
package bridge
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/vishvananda/netlink"
|
||||
|
@ -61,3 +62,18 @@ func (i *bridgeInterface) addresses() (netlink.Addr, []netlink.Addr, error) {
|
|||
}
|
||||
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
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/libnetwork/types"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
|
@ -22,9 +23,8 @@ const (
|
|||
func init() {
|
||||
// We allow ourselves to panic in this special case because we indicate a
|
||||
// failure to parse a compile-time define constant.
|
||||
if ip, netw, err := net.ParseCIDR(bridgeIPv6Str); err == nil {
|
||||
bridgeIPv6 = &net.IPNet{IP: ip, Mask: netw.Mask}
|
||||
} else {
|
||||
var err error
|
||||
if bridgeIPv6, err = types.ParseCIDR(bridgeIPv6Str); err != nil {
|
||||
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
|
||||
i.bridgeIPv6 = bridgeIPv6
|
||||
i.gatewayIPv6 = i.bridgeIPv6.IP
|
||||
|
||||
if err := i.programIPv6Address(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if config.AddressIPv6 == 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.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
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package bridge
|
||||
|
||||
import (
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/docker/libnetwork/types"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
|
@ -27,11 +29,14 @@ func setupVerifyAndReconcile(config *networkConfiguration, i *bridgeInterface) e
|
|||
return (*IPv6AddrNoMatchError)(bridgeIPv6)
|
||||
}
|
||||
|
||||
// By this time we have either configured a new bridge with an IP address
|
||||
// or made sure an existing bridge's IP matches the configuration
|
||||
// Now is the time to cache these states in the bridgeInterface.
|
||||
i.bridgeIPv4 = addrv4.IPNet
|
||||
i.bridgeIPv6 = bridgeIPv6
|
||||
// Release any residual IPv6 address that might be there because of older daemon instances
|
||||
for _, addrv6 := range addrsv6 {
|
||||
if addrv6.IP.IsGlobalUnicast() && !types.CompareIPNet(addrv6.IPNet, i.bridgeIPv6) {
|
||||
if err := netlink.AddrDel(i.Link, &addrv6); err != nil {
|
||||
log.Warnf("Failed to remove residual IPv6 address %s from bridge: %v", addrv6.IPNet, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue