소스 검색

Disable DAD for sandbox IPv6 addresses

Signed-off-by: Alessandro Boch <aboch@docker.com>
Alessandro Boch 9 년 전
부모
커밋
31016faad5
4개의 변경된 파일52개의 추가작업 그리고 2개의 파일을 삭제
  1. 1 1
      libnetwork/Makefile
  2. 2 1
      libnetwork/osl/interface_linux.go
  3. 43 0
      libnetwork/osl/sandbox_linux_test.go
  4. 6 0
      libnetwork/testutils/context.go

+ 1 - 1
libnetwork/Makefile

@@ -4,7 +4,7 @@ build_image=libnetworkbuild
 dockerargs = --privileged -v $(shell pwd):/go/src/github.com/docker/libnetwork -w /go/src/github.com/docker/libnetwork
 dockerargs = --privileged -v $(shell pwd):/go/src/github.com/docker/libnetwork -w /go/src/github.com/docker/libnetwork
 container_env = -e "INSIDECONTAINER=-incontainer=true"
 container_env = -e "INSIDECONTAINER=-incontainer=true"
 docker = docker run --rm -it ${dockerargs} $$EXTRA_ARGS ${container_env} ${build_image}
 docker = docker run --rm -it ${dockerargs} $$EXTRA_ARGS ${container_env} ${build_image}
-ciargs = -e "COVERALLS_TOKEN=$$COVERALLS_TOKEN" -e "INSIDECONTAINER=-incontainer=true"
+ciargs = -e CIRCLECI -e "COVERALLS_TOKEN=$$COVERALLS_TOKEN" -e "INSIDECONTAINER=-incontainer=true"
 cidocker = docker run ${dockerargs} ${ciargs} ${container_env} ${build_image}
 cidocker = docker run ${dockerargs} ${ciargs} ${container_env} ${build_image}
 CROSS_PLATFORMS = linux/amd64 linux/386 linux/arm windows/amd64 windows/386
 CROSS_PLATFORMS = linux/amd64 linux/386 linux/arm windows/amd64 windows/386
 
 

+ 2 - 1
libnetwork/osl/interface_linux.go

@@ -6,6 +6,7 @@ import (
 	"os/exec"
 	"os/exec"
 	"regexp"
 	"regexp"
 	"sync"
 	"sync"
+	"syscall"
 
 
 	"github.com/docker/libnetwork/types"
 	"github.com/docker/libnetwork/types"
 	"github.com/vishvananda/netlink"
 	"github.com/vishvananda/netlink"
@@ -337,7 +338,7 @@ func setInterfaceIPv6(iface netlink.Link, i *nwIface) error {
 	if i.AddressIPv6() == nil {
 	if i.AddressIPv6() == nil {
 		return nil
 		return nil
 	}
 	}
-	ipAddr := &netlink.Addr{IPNet: i.AddressIPv6(), Label: ""}
+	ipAddr := &netlink.Addr{IPNet: i.AddressIPv6(), Label: "", Flags: syscall.IFA_F_NODAD}
 	return netlink.AddrAdd(iface, ipAddr)
 	return netlink.AddrAdd(iface, ipAddr)
 }
 }
 
 

+ 43 - 0
libnetwork/osl/sandbox_linux_test.go

@@ -5,12 +5,15 @@ import (
 	"os"
 	"os"
 	"path/filepath"
 	"path/filepath"
 	"runtime"
 	"runtime"
+	"syscall"
 	"testing"
 	"testing"
 	"time"
 	"time"
 
 
 	"github.com/docker/libnetwork/netutils"
 	"github.com/docker/libnetwork/netutils"
+	"github.com/docker/libnetwork/testutils"
 	"github.com/docker/libnetwork/types"
 	"github.com/docker/libnetwork/types"
 	"github.com/vishvananda/netlink"
 	"github.com/vishvananda/netlink"
+	"github.com/vishvananda/netlink/nl"
 	"github.com/vishvananda/netns"
 	"github.com/vishvananda/netns"
 )
 )
 
 
@@ -179,3 +182,43 @@ func TestScanStatistics(t *testing.T) {
 		t.Fatalf("Error scanning the statistics")
 		t.Fatalf("Error scanning the statistics")
 	}
 	}
 }
 }
+
+func TestDisableIPv6DAD(t *testing.T) {
+	if testutils.RunningOnCircleCI() {
+		t.Skipf("Skipping as not supported on CIRCLE CI kernel")
+	}
+
+	defer testutils.SetupTestOSContext(t)()
+
+	ipv6, _ := types.ParseCIDR("2001:db8::44/64")
+	iface := &nwIface{addressIPv6: ipv6}
+
+	veth := &netlink.Veth{
+		LinkAttrs: netlink.LinkAttrs{Name: "sideA"},
+		PeerName:  "sideB",
+	}
+
+	err := netlink.LinkAdd(veth)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	link, err := netlink.LinkByName("sideA")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = setInterfaceIPv6(link, iface)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	addrList, err := netlink.AddrList(link, nl.FAMILY_V6)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if addrList[0].Flags&syscall.IFA_F_NODAD == 0 {
+		t.Fatalf("Unexpected interface flags: 0x%x. Expected to contain 0x%x", addrList[0].Flags, syscall.IFA_F_NODAD)
+	}
+}

+ 6 - 0
libnetwork/testutils/context.go

@@ -1,6 +1,7 @@
 package testutils
 package testutils
 
 
 import (
 import (
+	"os"
 	"runtime"
 	"runtime"
 	"syscall"
 	"syscall"
 	"testing"
 	"testing"
@@ -37,3 +38,8 @@ func SetupTestOSContext(t *testing.T) func() {
 		runtime.UnlockOSThread()
 		runtime.UnlockOSThread()
 	}
 	}
 }
 }
+
+// RunningOnCircleCI returns true if being executed on libnetwork Circle CI setup
+func RunningOnCircleCI() bool {
+	return os.Getenv("CIRCLECI") != ""
+}