1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00
moby--moby/daemon/networkdriver/bridge/driver_test.go
Arnaud Porterie f42348e18f Add --userland-proxy daemon flag
The `--userland-proxy` daemon flag makes it possible to rely on hairpin
NAT and additional iptables routes instead of userland proxy for port
publishing and inter-container communication.

Usage of the userland proxy remains the default as hairpin NAT is
unsupported by older kernels.

Signed-off-by: Arnaud Porterie <arnaud.porterie@docker.com>
2015-05-04 16:07:45 -07:00

193 lines
5.5 KiB
Go

package bridge
import (
"fmt"
"net"
"strconv"
"testing"
"github.com/docker/docker/daemon/network"
"github.com/docker/docker/daemon/networkdriver/portmapper"
"github.com/docker/docker/nat"
"github.com/docker/docker/pkg/iptables"
)
func init() {
// reset the new proxy command for mocking out the userland proxy in tests
portmapper.NewProxy = portmapper.NewMockProxyCommand
}
func findFreePort(t *testing.T) string {
l, err := net.Listen("tcp", ":0")
if err != nil {
t.Fatal("Failed to find a free port")
}
defer l.Close()
result, err := net.ResolveTCPAddr("tcp", l.Addr().String())
if err != nil {
t.Fatal("Failed to resolve address to identify free port")
}
return strconv.Itoa(result.Port)
}
func TestAllocatePortDetection(t *testing.T) {
freePort := findFreePort(t)
if err := InitDriver(new(Config)); err != nil {
t.Fatal("Failed to initialize network driver")
}
// Allocate interface
if _, err := Allocate("container_id", "", "", ""); err != nil {
t.Fatal("Failed to allocate network interface")
}
port := nat.Port(freePort + "/tcp")
binding := nat.PortBinding{HostIp: "127.0.0.1", HostPort: freePort}
// Allocate same port twice, expect failure on second call
if _, err := AllocatePort("container_id", port, binding); err != nil {
t.Fatal("Failed to find a free port to allocate")
}
if _, err := AllocatePort("container_id", port, binding); err == nil {
t.Fatal("Duplicate port allocation granted by AllocatePort")
}
}
func TestHostnameFormatChecking(t *testing.T) {
freePort := findFreePort(t)
if err := InitDriver(new(Config)); err != nil {
t.Fatal("Failed to initialize network driver")
}
// Allocate interface
if _, err := Allocate("container_id", "", "", ""); err != nil {
t.Fatal("Failed to allocate network interface")
}
port := nat.Port(freePort + "/tcp")
binding := nat.PortBinding{HostIp: "localhost", HostPort: freePort}
if _, err := AllocatePort("container_id", port, binding); err == nil {
t.Fatal("Failed to check invalid HostIP")
}
}
func newInterfaceAllocation(t *testing.T, globalIPv6 *net.IPNet, requestedMac, requestedIP, requestedIPv6 string, expectFail bool) *network.Settings {
// set IPv6 global if given
if globalIPv6 != nil {
globalIPv6Network = globalIPv6
}
networkSettings, err := Allocate("container_id", requestedMac, requestedIP, requestedIPv6)
if err == nil && expectFail {
t.Fatal("Doesn't fail to allocate network interface")
} else if err != nil && !expectFail {
t.Fatal("Failed to allocate network interface")
}
if globalIPv6 != nil {
// check for bug #11427
if globalIPv6Network.IP.String() != globalIPv6.IP.String() {
t.Fatal("globalIPv6Network was modified during allocation")
}
// clean up IPv6 global
globalIPv6Network = nil
}
return networkSettings
}
func TestIPv6InterfaceAllocationAutoNetmaskGt80(t *testing.T) {
_, subnet, _ := net.ParseCIDR("2001:db8:1234:1234:1234::/81")
networkSettings := newInterfaceAllocation(t, subnet, "", "", "", false)
// ensure low manually assigend global ip
ip := net.ParseIP(networkSettings.GlobalIPv6Address)
_, subnet, _ = net.ParseCIDR(fmt.Sprintf("%s/%d", subnet.IP.String(), 120))
if !subnet.Contains(ip) {
t.Fatalf("Error ip %s not in subnet %s", ip.String(), subnet.String())
}
}
func TestIPv6InterfaceAllocationAutoNetmaskLe80(t *testing.T) {
_, subnet, _ := net.ParseCIDR("2001:db8:1234:1234:1234::/80")
networkSettings := newInterfaceAllocation(t, subnet, "ab:cd:ab:cd:ab:cd", "", "", false)
// ensure global ip with mac
ip := net.ParseIP(networkSettings.GlobalIPv6Address)
expectedIP := net.ParseIP("2001:db8:1234:1234:1234:abcd:abcd:abcd")
if ip.String() != expectedIP.String() {
t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP.String())
}
// ensure link local format
ip = net.ParseIP(networkSettings.LinkLocalIPv6Address)
expectedIP = net.ParseIP("fe80::a9cd:abff:fecd:abcd")
if ip.String() != expectedIP.String() {
t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP.String())
}
}
func TestIPv6InterfaceAllocationRequest(t *testing.T) {
_, subnet, _ := net.ParseCIDR("2001:db8:1234:1234:1234::/80")
expectedIP := "2001:db8:1234:1234:1234::1328"
networkSettings := newInterfaceAllocation(t, subnet, "", "", expectedIP, false)
// ensure global ip with mac
ip := net.ParseIP(networkSettings.GlobalIPv6Address)
if ip.String() != expectedIP {
t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP)
}
// retry -> fails for duplicated address
_ = newInterfaceAllocation(t, subnet, "", "", expectedIP, true)
}
func TestMacAddrGeneration(t *testing.T) {
ip := net.ParseIP("192.168.0.1")
mac := generateMacAddr(ip).String()
// Should be consistent.
if generateMacAddr(ip).String() != mac {
t.Fatal("Inconsistent MAC address")
}
// Should be unique.
ip2 := net.ParseIP("192.168.0.2")
if generateMacAddr(ip2).String() == mac {
t.Fatal("Non-unique MAC address")
}
}
func TestLinkContainers(t *testing.T) {
// Init driver
if err := InitDriver(new(Config)); err != nil {
t.Fatal("Failed to initialize network driver")
}
// Allocate interface
if _, err := Allocate("container_id", "", "", ""); err != nil {
t.Fatal("Failed to allocate network interface")
}
bridgeIface = "lo"
if _, err := iptables.NewChain("DOCKER", bridgeIface, iptables.Filter, false); err != nil {
t.Fatal(err)
}
if err := LinkContainers("-I", "172.17.0.1", "172.17.0.2", []nat.Port{nat.Port("1234")}, false); err != nil {
t.Fatal("LinkContainers failed")
}
// flush rules
if _, err := iptables.Raw([]string{"-F", "DOCKER"}...); err != nil {
t.Fatal(err)
}
}