From b84ceb3d0ac53690f19cfc05f6b0e91e1998aa41 Mon Sep 17 00:00:00 2001 From: Alexander Morozov Date: Thu, 16 Jul 2015 13:58:34 -0700 Subject: [PATCH] Update github.com/docker/libnetwork to 2a5cb84758b5115d99d8f82c84845417c6c345a3 This update includes removal of libcontainer dependency. Signed-off-by: Alexander Morozov --- hack/vendor.sh | 2 +- .../src/github.com/docker/libnetwork/Makefile | 7 +- .../libnetwork/drivers/bridge/bridge.go | 12 +- .../bridge/netlink_deprecated_linux.go | 139 +++++++++++++++ .../netlink_deprecated_linux_armppc64.go | 7 + .../bridge/netlink_deprecated_linux_notarm.go | 7 + .../bridge/netlink_deprecated_unsupported.go | 18 ++ .../bridge/setup_bridgenetfiltering.go | 162 ++++++++++++++++++ .../libnetwork/drivers/bridge/setup_device.go | 3 +- .../libnetwork/portallocator/portallocator.go | 3 + .../docker/libnetwork/sandbox/route_linux.go | 4 +- 11 files changed, 353 insertions(+), 11 deletions(-) create mode 100644 vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux.go create mode 100644 vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_armppc64.go create mode 100644 vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_notarm.go create mode 100644 vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_unsupported.go create mode 100644 vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_bridgenetfiltering.go diff --git a/hack/vendor.sh b/hack/vendor.sh index f6ed5fb1eb..798a3f2792 100755 --- a/hack/vendor.sh +++ b/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 diff --git a/vendor/src/github.com/docker/libnetwork/Makefile b/vendor/src/github.com/docker/libnetwork/Makefile index f5b1169c00..deb510cf8c 100644 --- a/vendor/src/github.com/docker/libnetwork/Makefile +++ b/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: diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go index a0960986a0..7a86239a8f 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go +++ b/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 } diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux.go new file mode 100644 index 0000000000..007ccb285a --- /dev/null +++ b/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 +} diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_armppc64.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_armppc64.go new file mode 100644 index 0000000000..d3eadfa21c --- /dev/null +++ b/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) +} diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_notarm.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_notarm.go new file mode 100644 index 0000000000..97f51e1edc --- /dev/null +++ b/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) +} diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_unsupported.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_unsupported.go new file mode 100644 index 0000000000..7e2d57b660 --- /dev/null +++ b/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") +} diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_bridgenetfiltering.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_bridgenetfiltering.go new file mode 100644 index 0000000000..e7a5f4b077 --- /dev/null +++ b/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) +} diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_device.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_device.go index 66d55897f9..96eeee552a 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_device.go +++ b/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. diff --git a/vendor/src/github.com/docker/libnetwork/portallocator/portallocator.go b/vendor/src/github.com/docker/libnetwork/portallocator/portallocator.go index 293cc92e09..37d9c769b4 100644 --- a/vendor/src/github.com/docker/libnetwork/portallocator/portallocator.go +++ b/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 { diff --git a/vendor/src/github.com/docker/libnetwork/sandbox/route_linux.go b/vendor/src/github.com/docker/libnetwork/sandbox/route_linux.go index 3055f69b51..7010957345 100644 --- a/vendor/src/github.com/docker/libnetwork/sandbox/route_linux.go +++ b/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, }) })