Browse Source

Merge pull request #14690 from LK4D4/update_libnetwork

Update libnetwork
David Calavera 10 years ago
parent
commit
5d3043649a

+ 1 - 1
hack/vendor.sh

@@ -20,7 +20,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 0517ceae7dea82ded435b99af810efa27b56de73
+clone git github.com/docker/libnetwork 2a5cb84758b5115d99d8f82c84845417c6c345a3
 clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
 clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
 clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4

+ 4 - 3
vendor/src/github.com/docker/libnetwork/Makefile

@@ -61,11 +61,12 @@ check-local: 	check-format check-code run-tests
 
 install-deps:
 	apt-get update && apt-get -y install iptables
+	git clone https://github.com/golang/tools /go/src/golang.org/x/tools
+	go install golang.org/x/tools/cmd/vet
+	go install golang.org/x/tools/cmd/goimports
+	go install golang.org/x/tools/cmd/cover
 	go get github.com/tools/godep
 	go get github.com/golang/lint/golint
-	go get golang.org/x/tools/cmd/vet
-	go get golang.org/x/tools/cmd/goimports
-	go get golang.org/x/tools/cmd/cover
 	go get github.com/mattn/goveralls
 
 coveralls:

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

@@ -9,7 +9,6 @@ import (
 	"sync"
 
 	"github.com/Sirupsen/logrus"
-	bri "github.com/docker/libcontainer/netlink"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/ipallocator"
 	"github.com/docker/libnetwork/iptables"
@@ -669,6 +668,9 @@ func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) err
 
 		// Add inter-network communication rules.
 		{config.EnableIPTables, setupNetworkIsolationRules},
+
+		//Configure bridge networking filtering if ICC is off and IP tables are enabled
+		{!config.EnableICC && config.EnableIPTables, setupBridgeNetFiltering},
 	} {
 		if step.Condition {
 			bridgeSetup.queueStep(step.Fn)
@@ -767,7 +769,7 @@ func addToBridge(ifaceName, bridgeName string) error {
 		return fmt.Errorf("could not find bridge %s: %v", bridgeName, err)
 	}
 
-	return bri.AddToBridge(iface, master)
+	return ioctlAddToBridge(iface, master)
 }
 
 func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointInfo, epOptions map[string]interface{}) error {
@@ -1044,7 +1046,11 @@ func (d *driver) DeleteEndpoint(nid, eid types.UUID) error {
 
 	// Release the v6 address allocated to this endpoint's sandbox interface
 	if config.EnableIPv6 {
-		err := ipAllocator.ReleaseIP(n.bridge.bridgeIPv6, ep.addrv6.IP)
+		network := n.bridge.bridgeIPv6
+		if config.FixedCIDRv6 != nil {
+			network = config.FixedCIDRv6
+		}
+		err := ipAllocator.ReleaseIP(network, ep.addrv6.IP)
 		if err != nil {
 			return err
 		}

+ 139 - 0
vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux.go

@@ -0,0 +1,139 @@
+package bridge
+
+import (
+	"fmt"
+	"math/rand"
+	"net"
+	"syscall"
+	"time"
+	"unsafe"
+)
+
+const (
+	ifNameSize   = 16
+	ioctlBrAdd   = 0x89a0
+	ioctlBrAddIf = 0x89a2
+)
+
+type ifreqIndex struct {
+	IfrnName  [ifNameSize]byte
+	IfruIndex int32
+}
+
+type ifreqHwaddr struct {
+	IfrnName   [ifNameSize]byte
+	IfruHwaddr syscall.RawSockaddr
+}
+
+var rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
+
+// THIS CODE DOES NOT COMMUNICATE WITH KERNEL VIA RTNETLINK INTERFACE
+// IT IS HERE FOR BACKWARDS COMPATIBILITY WITH OLDER LINUX KERNELS
+// WHICH SHIP WITH OLDER NOT ENTIRELY FUNCTIONAL VERSION OF NETLINK
+func getIfSocket() (fd int, err error) {
+	for _, socket := range []int{
+		syscall.AF_INET,
+		syscall.AF_PACKET,
+		syscall.AF_INET6,
+	} {
+		if fd, err = syscall.Socket(socket, syscall.SOCK_DGRAM, 0); err == nil {
+			break
+		}
+	}
+	if err == nil {
+		return fd, nil
+	}
+	return -1, err
+}
+
+func ifIoctBridge(iface, master *net.Interface, op uintptr) error {
+	if len(master.Name) >= ifNameSize {
+		return fmt.Errorf("Interface name %s too long", master.Name)
+	}
+
+	s, err := getIfSocket()
+	if err != nil {
+		return err
+	}
+	defer syscall.Close(s)
+
+	ifr := ifreqIndex{}
+	copy(ifr.IfrnName[:len(ifr.IfrnName)-1], master.Name)
+	ifr.IfruIndex = int32(iface.Index)
+
+	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), op, uintptr(unsafe.Pointer(&ifr))); err != 0 {
+		return err
+	}
+
+	return nil
+}
+
+// Add a slave to a bridge device.  This is more backward-compatible than
+// netlink.NetworkSetMaster and works on RHEL 6.
+func ioctlAddToBridge(iface, master *net.Interface) error {
+	return ifIoctBridge(iface, master, ioctlBrAddIf)
+}
+
+func randMacAddr() string {
+	hw := make(net.HardwareAddr, 6)
+	for i := 0; i < 6; i++ {
+		hw[i] = byte(rnd.Intn(255))
+	}
+	hw[0] &^= 0x1 // clear multicast bit
+	hw[0] |= 0x2  // set local assignment bit (IEEE802)
+	return hw.String()
+}
+
+func ioctlSetMacAddress(name, addr string) error {
+	if len(name) >= ifNameSize {
+		return fmt.Errorf("Interface name %s too long", name)
+	}
+
+	hw, err := net.ParseMAC(addr)
+	if err != nil {
+		return err
+	}
+
+	s, err := getIfSocket()
+	if err != nil {
+		return err
+	}
+	defer syscall.Close(s)
+
+	ifr := ifreqHwaddr{}
+	ifr.IfruHwaddr.Family = syscall.ARPHRD_ETHER
+	copy(ifr.IfrnName[:len(ifr.IfrnName)-1], name)
+
+	for i := 0; i < 6; i++ {
+		ifr.IfruHwaddr.Data[i] = ifrDataByte(hw[i])
+	}
+
+	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&ifr))); err != 0 {
+		return err
+	}
+	return nil
+}
+
+func ioctlCreateBridge(name string, setMacAddr bool) error {
+	if len(name) >= ifNameSize {
+		return fmt.Errorf("Interface name %s too long", name)
+	}
+
+	s, err := getIfSocket()
+	if err != nil {
+		return err
+	}
+	defer syscall.Close(s)
+
+	nameBytePtr, err := syscall.BytePtrFromString(name)
+	if err != nil {
+		return err
+	}
+	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), ioctlBrAdd, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 {
+		return err
+	}
+	if setMacAddr {
+		return ioctlSetMacAddress(name, randMacAddr())
+	}
+	return nil
+}

+ 7 - 0
vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_armppc64.go

@@ -0,0 +1,7 @@
+// +build arm ppc64
+
+package bridge
+
+func ifrDataByte(b byte) uint8 {
+	return uint8(b)
+}

+ 7 - 0
vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_notarm.go

@@ -0,0 +1,7 @@
+// +build !arm,!ppc64
+
+package bridge
+
+func ifrDataByte(b byte) int8 {
+	return int8(b)
+}

+ 18 - 0
vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_unsupported.go

@@ -0,0 +1,18 @@
+// +build !linux
+
+package bridge
+
+import (
+	"errors"
+	"net"
+)
+
+// Add a slave to a bridge device.  This is more backward-compatible than
+// netlink.NetworkSetMaster and works on RHEL 6.
+func ioctlAddToBridge(iface, master *net.Interface) error {
+	return errors.New("not implemented")
+}
+
+func ioctlCreateBridge(name string, setMacAddr bool) error {
+	return errors.New("not implemented")
+}

+ 162 - 0
vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_bridgenetfiltering.go

@@ -0,0 +1,162 @@
+package bridge
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"syscall"
+
+	"github.com/Sirupsen/logrus"
+)
+
+// Enumeration type saying which versions of IP protocol to process.
+type ipVersion int
+
+const (
+	ipvnone ipVersion = iota
+	ipv4
+	ipv6
+	ipvboth
+)
+
+//Gets the IP version in use ( [ipv4], [ipv6] or [ipv4 and ipv6] )
+func getIPVersion(config *networkConfiguration) ipVersion {
+	ipVersion := ipv4
+	if config.FixedCIDRv6 != nil || config.EnableIPv6 {
+		ipVersion |= ipv6
+	}
+	return ipVersion
+}
+
+func setupBridgeNetFiltering(config *networkConfiguration, i *bridgeInterface) error {
+	err := checkBridgeNetFiltering(config, i)
+	if err != nil {
+		if ptherr, ok := err.(*os.PathError); ok {
+			if errno, ok := ptherr.Err.(syscall.Errno); ok && errno == syscall.ENOENT {
+				if isRunningInContainer() {
+					logrus.Warnf("running inside docker container, ignoring missing kernel params: %v", err)
+					err = nil
+				} else {
+					err = fmt.Errorf("please ensure that br_netfilter kernel module is loaded")
+				}
+			}
+		}
+		if err != nil {
+			return fmt.Errorf("cannot restrict inter-container communication: %v", err)
+		}
+	}
+	return nil
+}
+
+//Enable bridge net filtering if ip forwarding is enabled. See github issue #11404
+func checkBridgeNetFiltering(config *networkConfiguration, i *bridgeInterface) error {
+	ipVer := getIPVersion(config)
+	iface := config.BridgeName
+	doEnable := func(ipVer ipVersion) error {
+		var ipVerName string
+		if ipVer == ipv4 {
+			ipVerName = "IPv4"
+		} else {
+			ipVerName = "IPv6"
+		}
+		enabled, err := isPacketForwardingEnabled(ipVer, iface)
+		if err != nil {
+			logrus.Warnf("failed to check %s forwarding: %v", ipVerName, err)
+		} else if enabled {
+			enabled, err := getKernelBoolParam(getBridgeNFKernelParam(ipVer))
+			if err != nil || enabled {
+				return err
+			}
+			return setKernelBoolParam(getBridgeNFKernelParam(ipVer), true)
+		}
+		return nil
+	}
+
+	switch ipVer {
+	case ipv4, ipv6:
+		return doEnable(ipVer)
+	case ipvboth:
+		v4err := doEnable(ipv4)
+		v6err := doEnable(ipv6)
+		if v4err == nil {
+			return v6err
+		}
+		return v4err
+	default:
+		return nil
+	}
+}
+
+// Get kernel param path saying whether IPv${ipVer} traffic is being forwarded
+// on particular interface. Interface may be specified for IPv6 only. If
+// `iface` is empty, `default` will be assumed, which represents default value
+// for new interfaces.
+func getForwardingKernelParam(ipVer ipVersion, iface string) string {
+	switch ipVer {
+	case ipv4:
+		return "/proc/sys/net/ipv4/ip_forward"
+	case ipv6:
+		if iface == "" {
+			iface = "default"
+		}
+		return fmt.Sprintf("/proc/sys/net/ipv6/conf/%s/forwarding", iface)
+	default:
+		return ""
+	}
+}
+
+// Get kernel param path saying whether bridged IPv${ipVer} traffic shall be
+// passed to ip${ipVer}tables' chains.
+func getBridgeNFKernelParam(ipVer ipVersion) string {
+	switch ipVer {
+	case ipv4:
+		return "/proc/sys/net/bridge/bridge-nf-call-iptables"
+	case ipv6:
+		return "/proc/sys/net/bridge/bridge-nf-call-ip6tables"
+	default:
+		return ""
+	}
+}
+
+//Gets the value of the kernel parameters located at the given path
+func getKernelBoolParam(path string) (bool, error) {
+	enabled := false
+	line, err := ioutil.ReadFile(path)
+	if err != nil {
+		return false, err
+	}
+	if len(line) > 0 {
+		enabled = line[0] == '1'
+	}
+	return enabled, err
+}
+
+//Sets the value of the kernel parameter located at the given path
+func setKernelBoolParam(path string, on bool) error {
+	value := byte('0')
+	if on {
+		value = byte('1')
+	}
+	return ioutil.WriteFile(path, []byte{value, '\n'}, 0644)
+}
+
+//Checks to see if packet forwarding is enabled
+func isPacketForwardingEnabled(ipVer ipVersion, iface string) (bool, error) {
+	switch ipVer {
+	case ipv4, ipv6:
+		return getKernelBoolParam(getForwardingKernelParam(ipVer, iface))
+	case ipvboth:
+		enabled, err := getKernelBoolParam(getForwardingKernelParam(ipv4, ""))
+		if err != nil || !enabled {
+			return enabled, err
+		}
+		return getKernelBoolParam(getForwardingKernelParam(ipv6, iface))
+	default:
+		return true, nil
+	}
+}
+
+func isRunningInContainer() bool {
+	_, err := os.Stat("/.dockerinit")
+	return !os.IsNotExist(err)
+}

+ 1 - 2
vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_device.go

@@ -2,7 +2,6 @@ package bridge
 
 import (
 	"github.com/docker/docker/pkg/parsers/kernel"
-	bri "github.com/docker/libcontainer/netlink"
 	"github.com/vishvananda/netlink"
 )
 
@@ -30,7 +29,7 @@ func setupDevice(config *networkConfiguration, i *bridgeInterface) error {
 		setMac = true
 	}
 
-	return bri.CreateBridge(config.BridgeName, setMac)
+	return ioctlCreateBridge(config.BridgeName, setMac)
 }
 
 // SetupDeviceUp ups the given bridge interface.

+ 3 - 0
vendor/src/github.com/docker/libnetwork/portallocator/portallocator.go

@@ -108,6 +108,9 @@ func getDynamicPortRange() (start int, end int, err error) {
 	if err != nil {
 		return 0, 0, fmt.Errorf("port allocator - %s due to error: %v", portRangeFallback, err)
 	}
+
+	defer file.Close()
+
 	n, err := fmt.Fscanf(bufio.NewReader(file), "%d\t%d", &start, &end)
 	if n != 2 || err != nil {
 		if err == nil {

+ 2 - 2
vendor/src/github.com/docker/libnetwork/sandbox/route_linux.go

@@ -111,7 +111,7 @@ func programRoute(path string, dest *net.IPNet, nh net.IP) error {
 		return netlink.RouteAdd(&netlink.Route{
 			Scope:     netlink.SCOPE_UNIVERSE,
 			LinkIndex: gwRoutes[0].LinkIndex,
-			Gw:        gwRoutes[0].Gw,
+			Gw:        nh,
 			Dst:       dest,
 		})
 	})
@@ -128,7 +128,7 @@ func removeRoute(path string, dest *net.IPNet, nh net.IP) error {
 		return netlink.RouteDel(&netlink.Route{
 			Scope:     netlink.SCOPE_UNIVERSE,
 			LinkIndex: gwRoutes[0].LinkIndex,
-			Gw:        gwRoutes[0].Gw,
+			Gw:        nh,
 			Dst:       dest,
 		})
 	})