소스 검색

Merge pull request #15185 from aboch/vnd_lbn_1.8

Vendoring libnetwork 31139cdb513aea5ad1ed08b60d4350a68b4c96db
David Calavera 10 년 전
부모
커밋
9e9f3aa36b

+ 1 - 1
hack/vendor.sh

@@ -22,7 +22,7 @@ clone git golang.org/x/net 3cffabab72adf04f8e3b01c5baf775361837b5fe https://gith
 clone hg code.google.com/p/gosqlite 74691fb6f837
 
 #get libnetwork packages
-clone git github.com/docker/libnetwork f1c5671f1ee2133055144e566cd8b3a0ae4f0433
+clone git github.com/docker/libnetwork 31139cdb513aea5ad1ed08b60d4350a68b4c96db
 clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
 clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
 clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4

+ 12 - 0
integration-cli/docker_cli_daemon_test.go

@@ -780,6 +780,18 @@ func (s *DockerDaemonSuite) TestDaemonDefaultGatewayIPv4Explicit(c *check.C) {
 	deleteInterface(c, defaultNetworkBridge)
 }
 
+func (s *DockerDaemonSuite) TestDaemonDefaultGatewayIPv4ExplicitOutsideContainerSubnet(c *check.C) {
+	defaultNetworkBridge := "docker0"
+	deleteInterface(c, defaultNetworkBridge)
+
+	// Program a custom default gateway outside of the container subnet, daemon should accept it and start
+	err := s.d.StartWithBusybox("--bip", "172.16.0.10/16", "--fixed-cidr", "172.16.1.0/24", "--default-gateway", "172.16.0.254")
+	c.Assert(err, check.IsNil)
+
+	deleteInterface(c, defaultNetworkBridge)
+	s.d.Restart()
+}
+
 func (s *DockerDaemonSuite) TestDaemonIP(c *check.C) {
 	d := s.d
 

+ 26 - 22
vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go

@@ -596,21 +596,18 @@ func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) err
 	// networks. This step is needed now because driver might have now set the bridge
 	// name on this config struct. And because we need to check for possible address
 	// conflicts, so we need to check against operationa lnetworks.
-	if err := config.conflictsWithNetworks(id, networkList); err != nil {
+	if err = config.conflictsWithNetworks(id, networkList); err != nil {
 		return err
 	}
 
 	setupNetworkIsolationRules := func(config *networkConfiguration, i *bridgeInterface) error {
-		defer func() {
-			if err != nil {
-				if err := network.isolateNetwork(networkList, false); err != nil {
-					logrus.Warnf("Failed on removing the inter-network iptables rules on cleanup: %v", err)
-				}
+		if err := network.isolateNetwork(networkList, true); err != nil {
+			if err := network.isolateNetwork(networkList, false); err != nil {
+				logrus.Warnf("Failed on removing the inter-network iptables rules on cleanup: %v", err)
 			}
-		}()
-
-		err := network.isolateNetwork(networkList, true)
-		return err
+			return err
+		}
+		return nil
 	}
 
 	// Prepare the bridge setup configuration
@@ -766,17 +763,26 @@ func (d *driver) DeleteNetwork(nid types.UUID) error {
 }
 
 func addToBridge(ifaceName, bridgeName string) error {
-	iface, err := net.InterfaceByName(ifaceName)
+	link, err := netlink.LinkByName(ifaceName)
 	if err != nil {
 		return fmt.Errorf("could not find interface %s: %v", ifaceName, err)
 	}
+	if err = netlink.LinkSetMaster(link,
+		&netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}}); err != nil {
+		logrus.Debugf("Failed to add %s to bridge via netlink.Trying ioctl: %v", ifaceName, err)
+		iface, err := net.InterfaceByName(ifaceName)
+		if err != nil {
+			return fmt.Errorf("could not find network interface %s: %v", ifaceName, err)
+		}
 
-	master, err := net.InterfaceByName(bridgeName)
-	if err != nil {
-		return fmt.Errorf("could not find bridge %s: %v", bridgeName, err)
-	}
+		master, err := net.InterfaceByName(bridgeName)
+		if err != nil {
+			return fmt.Errorf("could not find bridge %s: %v", bridgeName, err)
+		}
 
-	return ioctlAddToBridge(iface, master)
+		return ioctlAddToBridge(iface, master)
+	}
+	return nil
 }
 
 func setHairpinMode(link netlink.Link, enable bool) error {
@@ -947,15 +953,14 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn
 	}
 
 	// v4 address for the sandbox side pipe interface
-	sub := types.GetIPNetCanonical(n.bridge.bridgeIPv4)
-	ip4, err := ipAllocator.RequestIP(sub, nil)
+	ip4, err := ipAllocator.RequestIP(n.bridge.bridgeIPv4, nil)
 	if err != nil {
 		return err
 	}
 	ipv4Addr := &net.IPNet{IP: ip4, Mask: n.bridge.bridgeIPv4.Mask}
 
 	// Down the interface before configuring mac address.
-	if err := netlink.LinkSetDown(sbox); err != nil {
+	if err = netlink.LinkSetDown(sbox); err != nil {
 		return fmt.Errorf("could not set link down for container interface %s: %v", containerIfName, err)
 	}
 
@@ -968,7 +973,7 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn
 	endpoint.macAddress = mac
 
 	// Up the host interface after finishing all netlink configuration
-	if err := netlink.LinkSetUp(host); err != nil {
+	if err = netlink.LinkSetUp(host); err != nil {
 		return fmt.Errorf("could not set link up for host interface %s: %v", hostIfName, err)
 	}
 
@@ -1074,8 +1079,7 @@ func (d *driver) DeleteEndpoint(nid, eid types.UUID) error {
 	n.releasePorts(ep)
 
 	// Release the v4 address allocated to this endpoint's sandbox interface
-	sub := types.GetIPNetCanonical(n.bridge.bridgeIPv4)
-	err = ipAllocator.ReleaseIP(sub, ep.addr.IP)
+	err = ipAllocator.ReleaseIP(n.bridge.bridgeIPv4, ep.addr.IP)
 	if err != nil {
 		return err
 	}

+ 21 - 3
vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_device.go

@@ -1,7 +1,11 @@
 package bridge
 
 import (
+	"fmt"
+
+	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/parsers/kernel"
+	"github.com/docker/libnetwork/netutils"
 	"github.com/vishvananda/netlink"
 )
 
@@ -25,11 +29,25 @@ func setupDevice(config *networkConfiguration, i *bridgeInterface) error {
 	// Only set the bridge's MAC address if the kernel version is > 3.3, as it
 	// was not supported before that.
 	kv, err := kernel.GetKernelVersion()
-	if err == nil && (kv.Kernel >= 3 && kv.Major >= 3) {
-		setMac = true
+	if err != nil {
+		logrus.Errorf("Failed to check kernel versions: %v. Will not assign a MAC address to the bridge interface", err)
+	} else {
+		setMac = kv.Kernel > 3 || (kv.Kernel == 3 && kv.Major >= 3)
 	}
 
-	return ioctlCreateBridge(config.BridgeName, setMac)
+	if err = netlink.LinkAdd(i.Link); err != nil {
+		logrus.Debugf("Failed to create bridge %s via netlink. Trying ioctl", config.BridgeName)
+		return ioctlCreateBridge(config.BridgeName, setMac)
+	}
+
+	if setMac {
+		hwAddr := netutils.GenerateRandomMAC()
+		if err = netlink.LinkSetHardwareAddr(i.Link, hwAddr); err != nil {
+			return fmt.Errorf("failed to set bridge mac-address %s : %s", hwAddr, err.Error())
+		}
+		logrus.Debugf("Setting bridge mac address to %s", hwAddr)
+	}
+	return err
 }
 
 // SetupDeviceUp ups the given bridge interface.

+ 13 - 7
vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_ipv4.go

@@ -8,7 +8,6 @@ import (
 
 	log "github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/netutils"
-	"github.com/docker/libnetwork/types"
 	"github.com/vishvananda/netlink"
 )
 
@@ -76,8 +75,12 @@ func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
 }
 
 func allocateBridgeIP(config *networkConfiguration, i *bridgeInterface) error {
-	sub := types.GetIPNetCanonical(i.bridgeIPv4)
-	ipAllocator.RequestIP(sub, i.bridgeIPv4.IP)
+	// Because of the way ipallocator manages the container address space,
+	// reserve bridge address only if it belongs to the container network
+	// (if defined), no need otherwise
+	if config.FixedCIDR == nil || config.FixedCIDR.Contains(i.bridgeIPv4.IP) {
+		ipAllocator.RequestIP(i.bridgeIPv4, i.bridgeIPv4.IP)
+	}
 	return nil
 }
 
@@ -112,10 +115,13 @@ func setupGatewayIPv4(config *networkConfiguration, i *bridgeInterface) error {
 		return &ErrInvalidGateway{}
 	}
 
-	// Pass the real network subnet to ip allocator (no host bits set)
-	sub := types.GetIPNetCanonical(i.bridgeIPv4)
-	if _, err := ipAllocator.RequestIP(sub, config.DefaultGatewayIPv4); err != nil {
-		return err
+	// Because of the way ipallocator manages the container address space,
+	// reserve default gw address only if it belongs to the container network
+	// (if defined), no need otherwise
+	if config.FixedCIDR == nil || config.FixedCIDR.Contains(config.DefaultGatewayIPv4) {
+		if _, err := ipAllocator.RequestIP(i.bridgeIPv4, config.DefaultGatewayIPv4); err != nil {
+			return err
+		}
 	}
 
 	// Store requested default gateway

+ 7 - 4
vendor/src/github.com/docker/libnetwork/ipallocator/allocator.go

@@ -66,7 +66,8 @@ func (a *IPAllocator) RegisterSubnet(network *net.IPNet, subnet *net.IPNet) erro
 	a.mutex.Lock()
 	defer a.mutex.Unlock()
 
-	key := network.String()
+	nw := &net.IPNet{IP: network.IP.Mask(network.Mask), Mask: network.Mask}
+	key := nw.String()
 	if _, ok := a.allocatedIPs[key]; ok {
 		return ErrNetworkAlreadyRegistered
 	}
@@ -90,10 +91,11 @@ func (a *IPAllocator) RequestIP(network *net.IPNet, ip net.IP) (net.IP, error) {
 	a.mutex.Lock()
 	defer a.mutex.Unlock()
 
-	key := network.String()
+	nw := &net.IPNet{IP: network.IP.Mask(network.Mask), Mask: network.Mask}
+	key := nw.String()
 	allocated, ok := a.allocatedIPs[key]
 	if !ok {
-		allocated = newAllocatedMap(network)
+		allocated = newAllocatedMap(nw)
 		a.allocatedIPs[key] = allocated
 	}
 
@@ -109,7 +111,8 @@ func (a *IPAllocator) ReleaseIP(network *net.IPNet, ip net.IP) error {
 	a.mutex.Lock()
 	defer a.mutex.Unlock()
 
-	if allocated, exists := a.allocatedIPs[network.String()]; exists {
+	nw := &net.IPNet{IP: network.IP.Mask(network.Mask), Mask: network.Mask}
+	if allocated, exists := a.allocatedIPs[nw.String()]; exists {
 		delete(allocated.p, ip.String())
 	}
 	return nil

+ 12 - 10
vendor/src/github.com/docker/libnetwork/netutils/utils.go

@@ -74,20 +74,22 @@ func NetworkOverlaps(netX *net.IPNet, netY *net.IPNet) bool {
 
 // NetworkRange calculates the first and last IP addresses in an IPNet
 func NetworkRange(network *net.IPNet) (net.IP, net.IP) {
-	var netIP net.IP
-	if network.IP.To4() != nil {
-		netIP = network.IP.To4()
-	} else if network.IP.To16() != nil {
-		netIP = network.IP.To16()
-	} else {
+	if network == nil {
 		return nil, nil
 	}
 
-	lastIP := make([]byte, len(netIP), len(netIP))
-	for i := 0; i < len(netIP); i++ {
-		lastIP[i] = netIP[i] | ^network.Mask[i]
+	firstIP := network.IP.Mask(network.Mask)
+	lastIP := types.GetIPCopy(firstIP)
+	for i := 0; i < len(firstIP); i++ {
+		lastIP[i] = firstIP[i] | ^network.Mask[i]
 	}
-	return netIP.Mask(network.Mask), net.IP(lastIP)
+
+	if network.IP.To4() != nil {
+		firstIP = firstIP.To4()
+		lastIP = lastIP.To4()
+	}
+
+	return firstIP, lastIP
 }
 
 // GetIfaceAddr returns the first IPv4 address and slice of IPv6 addresses for the specified network interface

+ 11 - 3
vendor/src/github.com/docker/libnetwork/sandboxdata.go

@@ -139,10 +139,15 @@ func (s *sandboxData) rmEndpoint(ep *endpoint) {
 		}
 	}
 
-	// We don't check if s.endpoints is empty here because
-	// it should never be empty during a rmEndpoint call and
-	// if it is we will rightfully panic here
 	s.Lock()
+	if len(s.endpoints) == 0 {
+		// s.endpoints should never be empty and this is unexpected error condition
+		// We log an error message to note this down for debugging purposes.
+		logrus.Errorf("No endpoints in sandbox while trying to remove endpoint %s", ep.Name())
+		s.Unlock()
+		return
+	}
+
 	highEpBefore := s.endpoints[0]
 	var (
 		i int
@@ -245,7 +250,10 @@ func (c *controller) LeaveAll(id string) error {
 	}
 
 	sData.sandbox().Destroy()
+
+	c.Lock()
 	delete(c.sandboxes, sandbox.GenerateKey(id))
+	c.Unlock()
 
 	return nil
 }