Merge pull request #1095 from mrjana/ipam

Remove all netlink/osl deps from ipam/ipamutils
This commit is contained in:
Alessandro Boch 2016-04-15 11:46:47 -07:00
commit c891a47cb3
21 changed files with 272 additions and 254 deletions

View file

@ -29,8 +29,8 @@ import (
"github.com/docker/libnetwork/config"
"github.com/docker/libnetwork/datastore"
"github.com/docker/libnetwork/driverapi"
"github.com/docker/libnetwork/ipamutils"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/types"
"github.com/gorilla/mux"
@ -429,7 +429,7 @@ func encodeData(data interface{}) (*bytes.Buffer, error) {
}
func ipamOption(bridgeName string) libnetwork.NetworkOption {
if nw, _, err := ipamutils.ElectInterfaceAddresses(bridgeName); err == nil {
if nw, _, err := netutils.ElectInterfaceAddresses(bridgeName); err == nil {
ipamV4Conf := &libnetwork.IpamConf{PreferredPool: nw.String()}
hip, _ := types.GetHostPartIP(nw.IP, nw.Mask)
if hip.IsGlobalUnicast() {

View file

@ -10,6 +10,7 @@ import (
"github.com/docker/libnetwork/ipamutils"
"github.com/docker/libnetwork/iptables"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/testutils"
"github.com/docker/libnetwork/types"
@ -21,7 +22,7 @@ func init() {
func getIPv4Data(t *testing.T) []driverapi.IPAMData {
ipd := driverapi.IPAMData{AddressSpace: "full"}
nw, _, err := ipamutils.ElectInterfaceAddresses("")
nw, _, err := netutils.ElectInterfaceAddresses("")
if err != nil {
t.Fatal(err)
}

View file

@ -401,13 +401,6 @@ func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error)
}
if !aSpace.contains(as, nw) {
if as == localAddressSpace {
// Check if nw overlap with system routes, name servers
if _, err := ipamutils.FindAvailableNetwork([]*net.IPNet{nw}); err == nil {
return nw, nil
}
continue
}
return nw, nil
}
}

View file

@ -453,27 +453,11 @@ func TestPredefinedPool(t *testing.T) {
t.Fatalf("Expected failure for non default addr space")
}
exp, err := ipamutils.FindAvailableNetwork(a.predefined[localAddressSpace])
pid, nw, _, err := a.RequestPool(localAddressSpace, "", "", nil, false)
if err != nil {
t.Fatal(err)
}
nw, err := a.getPredefinedPool(localAddressSpace, false)
if err != nil {
t.Fatal(err)
}
if !types.CompareIPNet(nw, exp) {
t.Fatalf("Unexpected default network returned: %s. Expected: %s", nw, exp)
}
pid, nw, _, err := a.RequestPool(localAddressSpace, exp.String(), "", nil, false)
if err != nil {
t.Fatal(err)
}
if !types.CompareIPNet(nw, exp) {
t.Fatalf("Unexpected default network returned: %s. Expected: %s", nw, exp)
}
nw2, err := a.getPredefinedPool(localAddressSpace, false)
if err != nil {
t.Fatal(err)
@ -485,14 +469,6 @@ func TestPredefinedPool(t *testing.T) {
if err := a.ReleasePool(pid); err != nil {
t.Fatal(err)
}
nw, err = a.getPredefinedPool(localAddressSpace, false)
if err != nil {
t.Fatal(err)
}
if !types.CompareIPNet(nw, exp) {
t.Fatalf("Unexpected default network returned: %s. Expected %s", nw, exp)
}
}
func TestRemoveSubnet(t *testing.T) {

View file

@ -1,76 +0,0 @@
// Package ipamutils provides utililty functions for ipam management
package ipamutils
import (
"fmt"
"net"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/osl"
"github.com/docker/libnetwork/resolvconf"
"github.com/vishvananda/netlink"
)
// ElectInterfaceAddresses looks for an interface on the OS with the specified name
// and returns its IPv4 and IPv6 addresses in CIDR form. If the interface does not exist,
// it chooses from a predifined list the first IPv4 address which does not conflict
// with other interfaces on the system.
func ElectInterfaceAddresses(name string) (*net.IPNet, []*net.IPNet, error) {
var (
v4Net *net.IPNet
v6Nets []*net.IPNet
err error
)
InitNetworks()
defer osl.InitOSContext()()
link, _ := netlink.LinkByName(name)
if link != nil {
v4addr, err := netlink.AddrList(link, netlink.FAMILY_V4)
if err != nil {
return nil, nil, err
}
v6addr, err := netlink.AddrList(link, netlink.FAMILY_V6)
if err != nil {
return nil, nil, err
}
if len(v4addr) > 0 {
v4Net = v4addr[0].IPNet
}
for _, nlAddr := range v6addr {
v6Nets = append(v6Nets, nlAddr.IPNet)
}
}
if link == nil || v4Net == nil {
// Choose from predifined broad networks
v4Net, err = FindAvailableNetwork(PredefinedBroadNetworks)
if err != nil {
return nil, nil, err
}
}
return v4Net, v6Nets, nil
}
// FindAvailableNetwork returns a network from the passed list which does not
// overlap with existing interfaces in the system
func FindAvailableNetwork(list []*net.IPNet) (*net.IPNet, error) {
// We don't check for an error here, because we don't really care if we
// can't read /etc/resolv.conf. So instead we skip the append if resolvConf
// is nil. It either doesn't exist, or we can't read it for some reason.
var nameservers []string
if rc, err := resolvconf.Get(); err == nil {
nameservers = resolvconf.GetNameserversAsCIDR(rc.Content)
}
for _, nw := range list {
if err := netutils.CheckNameserverOverlaps(nameservers, nw); err == nil {
if err := netutils.CheckRouteOverlaps(nw); err == nil {
return nw, nil
}
}
}
return nil, fmt.Errorf("no available network")
}

View file

@ -1,12 +1,9 @@
package ipamutils
import (
"net"
"testing"
"github.com/docker/libnetwork/testutils"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink"
_ "github.com/docker/libnetwork/testutils"
)
func init() {
@ -27,91 +24,3 @@ func TestGranularPredefined(t *testing.T) {
}
}
func TestNetworkRequest(t *testing.T) {
defer testutils.SetupTestOSContext(t)()
_, exp, err := net.ParseCIDR("172.17.0.0/16")
if err != nil {
t.Fatal(err)
}
nw, err := FindAvailableNetwork(PredefinedBroadNetworks)
if err != nil {
t.Fatal(err)
}
if !types.CompareIPNet(exp, nw) {
t.Fatalf("exected %s. got %s", exp, nw)
}
_, exp, err = net.ParseCIDR("10.0.0.0/24")
if err != nil {
t.Fatal(err)
}
nw, err = FindAvailableNetwork(PredefinedGranularNetworks)
if err != nil {
t.Fatal(err)
}
if !types.CompareIPNet(exp, nw) {
t.Fatalf("exected %s. got %s", exp, nw)
}
// Add iface and ssert returned address on request
createInterface(t, "test", "172.17.42.1/16")
_, exp, err = net.ParseCIDR("172.18.0.0/16")
if err != nil {
t.Fatal(err)
}
nw, err = FindAvailableNetwork(PredefinedBroadNetworks)
if err != nil {
t.Fatal(err)
}
if !types.CompareIPNet(exp, nw) {
t.Fatalf("exected %s. got %s", exp, nw)
}
}
func TestElectInterfaceAddress(t *testing.T) {
defer testutils.SetupTestOSContext(t)()
nws := "172.101.202.254/16"
createInterface(t, "test", nws)
ipv4Nw, ipv6Nw, err := ElectInterfaceAddresses("test")
if err != nil {
t.Fatal(err)
}
if ipv4Nw == nil {
t.Fatalf("unexpected empty ipv4 network addresses")
}
if len(ipv6Nw) == 0 {
t.Fatalf("unexpected empty ipv4 network addresses")
}
if nws != ipv4Nw.String() {
t.Fatalf("expected %s. got %s", nws, ipv4Nw)
}
}
func createInterface(t *testing.T, name, nw string) {
// Add interface
link := &netlink.Bridge{
LinkAttrs: netlink.LinkAttrs{
Name: "test",
},
}
bip, err := types.ParseCIDR(nw)
if err != nil {
t.Fatal(err)
}
if err = netlink.LinkAdd(link); err != nil {
t.Fatalf("Failed to create interface via netlink: %v", err)
}
if err := netlink.AddrAdd(link, &netlink.Addr{IPNet: bip}); err != nil {
t.Fatal(err)
}
if err = netlink.LinkSetUp(link); err != nil {
t.Fatal(err)
}
}

View file

@ -14,13 +14,6 @@ import (
"github.com/docker/libnetwork/types"
)
// constants for the IP address type
const (
IP = iota // IPv4 and IPv6
IPv4
IPv6
)
var (
// ErrNetworkOverlapsWithNameservers preformatted error
ErrNetworkOverlapsWithNameservers = errors.New("requested network overlaps with nameserver")

View file

@ -1,5 +1,4 @@
// Package ipamutils provides utililty functions for ipam management
package ipamutils
package netutils
import (
"net"

View file

@ -4,9 +4,13 @@
package netutils
import (
"fmt"
"net"
"strings"
"github.com/docker/libnetwork/ipamutils"
"github.com/docker/libnetwork/osl"
"github.com/docker/libnetwork/resolvconf"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink"
)
@ -48,3 +52,66 @@ func GenerateIfaceName(prefix string, len int) (string, error) {
}
return "", types.InternalErrorf("could not generate interface name")
}
// ElectInterfaceAddresses looks for an interface on the OS with the
// specified name and returns its IPv4 and IPv6 addresses in CIDR
// form. If the interface does not exist, it chooses from a predifined
// list the first IPv4 address which does not conflict with other
// interfaces on the system.
func ElectInterfaceAddresses(name string) (*net.IPNet, []*net.IPNet, error) {
var (
v4Net *net.IPNet
v6Nets []*net.IPNet
err error
)
defer osl.InitOSContext()()
link, _ := netlink.LinkByName(name)
if link != nil {
v4addr, err := netlink.AddrList(link, netlink.FAMILY_V4)
if err != nil {
return nil, nil, err
}
v6addr, err := netlink.AddrList(link, netlink.FAMILY_V6)
if err != nil {
return nil, nil, err
}
if len(v4addr) > 0 {
v4Net = v4addr[0].IPNet
}
for _, nlAddr := range v6addr {
v6Nets = append(v6Nets, nlAddr.IPNet)
}
}
if link == nil || v4Net == nil {
// Choose from predifined broad networks
v4Net, err = FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
if err != nil {
return nil, nil, err
}
}
return v4Net, v6Nets, nil
}
// FindAvailableNetwork returns a network from the passed list which does not
// overlap with existing interfaces in the system
func FindAvailableNetwork(list []*net.IPNet) (*net.IPNet, error) {
// We don't check for an error here, because we don't really care if we
// can't read /etc/resolv.conf. So instead we skip the append if resolvConf
// is nil. It either doesn't exist, or we can't read it for some reason.
var nameservers []string
if rc, err := resolvconf.Get(); err == nil {
nameservers = resolvconf.GetNameserversAsCIDR(rc.Content)
}
for _, nw := range list {
if err := CheckNameserverOverlaps(nameservers, nw); err == nil {
if err := CheckRouteOverlaps(nw); err == nil {
return nw, nil
}
}
}
return nil, fmt.Errorf("no available network")
}

View file

@ -5,7 +5,9 @@ import (
"net"
"testing"
_ "github.com/docker/libnetwork/testutils"
"github.com/docker/libnetwork/ipamutils"
"github.com/docker/libnetwork/testutils"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink"
)
@ -210,3 +212,95 @@ func TestUtilGenerateRandomMAC(t *testing.T) {
t.Fatalf("mac1 %s should not equal mac2 %s", mac1, mac2)
}
}
func TestNetworkRequest(t *testing.T) {
defer testutils.SetupTestOSContext(t)()
ipamutils.InitNetworks()
_, exp, err := net.ParseCIDR("172.17.0.0/16")
if err != nil {
t.Fatal(err)
}
nw, err := FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
if err != nil {
t.Fatal(err)
}
if !types.CompareIPNet(exp, nw) {
t.Fatalf("exected %s. got %s", exp, nw)
}
_, exp, err = net.ParseCIDR("10.0.0.0/24")
if err != nil {
t.Fatal(err)
}
nw, err = FindAvailableNetwork(ipamutils.PredefinedGranularNetworks)
if err != nil {
t.Fatal(err)
}
if !types.CompareIPNet(exp, nw) {
t.Fatalf("exected %s. got %s", exp, nw)
}
// Add iface and ssert returned address on request
createInterface(t, "test", "172.17.42.1/16")
_, exp, err = net.ParseCIDR("172.18.0.0/16")
if err != nil {
t.Fatal(err)
}
nw, err = FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
if err != nil {
t.Fatal(err)
}
if !types.CompareIPNet(exp, nw) {
t.Fatalf("exected %s. got %s", exp, nw)
}
}
func TestElectInterfaceAddress(t *testing.T) {
defer testutils.SetupTestOSContext(t)()
ipamutils.InitNetworks()
nws := "172.101.202.254/16"
createInterface(t, "test", nws)
ipv4Nw, ipv6Nw, err := ElectInterfaceAddresses("test")
if err != nil {
t.Fatal(err)
}
if ipv4Nw == nil {
t.Fatalf("unexpected empty ipv4 network addresses")
}
if len(ipv6Nw) == 0 {
t.Fatalf("unexpected empty ipv4 network addresses")
}
if nws != ipv4Nw.String() {
t.Fatalf("expected %s. got %s", nws, ipv4Nw)
}
}
func createInterface(t *testing.T, name, nw string) {
// Add interface
link := &netlink.Bridge{
LinkAttrs: netlink.LinkAttrs{
Name: "test",
},
}
bip, err := types.ParseCIDR(nw)
if err != nil {
t.Fatal(err)
}
if err = netlink.LinkAdd(link); err != nil {
t.Fatalf("Failed to create interface via netlink: %v", err)
}
if err := netlink.AddrAdd(link, &netlink.Addr{IPNet: bip}); err != nil {
t.Fatal(err)
}
if err = netlink.LinkSetUp(link); err != nil {
t.Fatal(err)
}
}

View file

@ -1,5 +1,4 @@
// Package ipamutils provides utililty functions for ipam management
package ipamutils
package netutils
import (
"net"

View file

@ -1097,6 +1097,48 @@ func (n *network) ipamAllocate() error {
return n.ipamAllocateVersion(6, ipam)
}
func (n *network) requestPoolHelper(ipam ipamapi.Ipam, addressSpace, preferredPool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
for {
poolID, pool, meta, err := ipam.RequestPool(addressSpace, preferredPool, subPool, options, v6)
if err != nil {
return "", nil, nil, err
}
// If the network belongs to global scope or the pool
// returned is invalid, no need to perform overlap
// check.
if n.Scope() == datastore.GlobalScope || !types.IsIPNetValid(pool) {
return poolID, pool, meta, nil
}
// Check for overlap and if none found, we have found the right pool.
if _, err := netutils.FindAvailableNetwork([]*net.IPNet{pool}); err == nil {
return poolID, pool, meta, nil
}
// Pool obtained in this iteration is
// overlapping. Hold onto the pool and don't release
// it yet, because we don't want ipam to give us back
// the same pool over again. But make sure we still do
// a deferred release when we have either obtained a
// non-overlapping pool or ran out of pre-defined
// pools.
defer func() {
if err := ipam.ReleasePool(poolID); err != nil {
log.Warnf("Failed to release overlapping pool %s while returning from pool request helper for network %s", pool, n.Name())
}
}()
// If this is a preferred pool request and the network
// is local scope and there is a overlap, we fail the
// network creation right here. The pool will be
// released in the defer.
if preferredPool != "" {
return "", nil, nil, fmt.Errorf("requested subnet %s overlaps in the host", preferredPool)
}
}
}
func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error {
var (
cfgList *[]*IpamConf
@ -1133,7 +1175,7 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error {
d := &IpamInfo{}
(*infoList)[i] = d
d.PoolID, d.Pool, d.Meta, err = ipam.RequestPool(n.addrSpace, cfg.PreferredPool, cfg.SubPool, n.ipamOptions, ipVer == 6)
d.PoolID, d.Pool, d.Meta, err = n.requestPoolHelper(ipam, n.addrSpace, cfg.PreferredPool, cfg.SubPool, n.ipamOptions, ipVer == 6)
if err != nil {
return err
}

View file

@ -1,6 +1,9 @@
package osl
import (
"crypto/rand"
"encoding/hex"
"io"
"net"
"os"
"path/filepath"
@ -9,7 +12,6 @@ import (
"testing"
"time"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/testutils"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink"
@ -25,8 +27,16 @@ const (
sboxIfaceName = "containername"
)
func generateRandomName(prefix string, size int) (string, error) {
id := make([]byte, 32)
if _, err := io.ReadFull(rand.Reader, id); err != nil {
return "", err
}
return prefix + hex.EncodeToString(id)[:size], nil
}
func newKey(t *testing.T) (string, error) {
name, err := netutils.GenerateRandomName("netns", 12)
name, err := generateRandomName("netns", 12)
if err != nil {
return "", err
}

View file

@ -10,8 +10,8 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/resolvconf/dns"
"github.com/docker/libnetwork/types"
)
var (
@ -122,7 +122,7 @@ func FilterResolvDNS(resolvConf []byte, ipv6Enabled bool) (*File, error) {
}
// if the resulting resolvConf has no more nameservers defined, add appropriate
// default DNS servers for IPv4 and (optionally) IPv6
if len(GetNameservers(cleanedResolvConf, netutils.IP)) == 0 {
if len(GetNameservers(cleanedResolvConf, types.IP)) == 0 {
logrus.Infof("No non-localhost DNS nameservers are left in resolv.conf. Using default external servers : %v", defaultIPv4Dns)
dns := defaultIPv4Dns
if ipv6Enabled {
@ -158,11 +158,11 @@ func GetNameservers(resolvConf []byte, kind int) []string {
nameservers := []string{}
for _, line := range getLines(resolvConf, []byte("#")) {
var ns [][]byte
if kind == netutils.IP {
if kind == types.IP {
ns = nsRegexp.FindSubmatch(line)
} else if kind == netutils.IPv4 {
} else if kind == types.IPv4 {
ns = nsIPv4Regexpmatch.FindSubmatch(line)
} else if kind == netutils.IPv6 {
} else if kind == types.IPv6 {
ns = nsIPv6Regexpmatch.FindSubmatch(line)
}
if len(ns) > 0 {
@ -177,7 +177,7 @@ func GetNameservers(resolvConf []byte, kind int) []string {
// This function's output is intended for net.ParseCIDR
func GetNameserversAsCIDR(resolvConf []byte) []string {
nameservers := []string{}
for _, nameserver := range GetNameservers(resolvConf, netutils.IP) {
for _, nameserver := range GetNameservers(resolvConf, types.IP) {
nameservers = append(nameservers, nameserver+"/32")
}
return nameservers

View file

@ -7,8 +7,8 @@ import (
"testing"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/libnetwork/netutils"
_ "github.com/docker/libnetwork/testutils"
"github.com/docker/libnetwork/types"
)
func TestGet(t *testing.T) {
@ -49,7 +49,7 @@ nameserver 1.2.3.4
`search example.com
nameserver 1.2.3.4 # not 4.3.2.1`: {"1.2.3.4"},
} {
test := GetNameservers([]byte(resolv), netutils.IP)
test := GetNameservers([]byte(resolv), types.IP)
if !strSlicesEqual(test, result) {
t.Fatalf("Wrong nameserver string {%s} should be %v. Input: %s", test, result, resolv)
}
@ -84,11 +84,11 @@ func TestGetSearchDomains(t *testing.T) {
for resolv, result := range map[string][]string{
`search example.com`: {"example.com"},
`search example.com # ignored`: {"example.com"},
` search example.com `: {"example.com"},
` search example.com # ignored`: {"example.com"},
` search example.com `: {"example.com"},
` search example.com # ignored`: {"example.com"},
`search foo.example.com example.com`: {"foo.example.com", "example.com"},
` search foo.example.com example.com `: {"foo.example.com", "example.com"},
` search foo.example.com example.com # ignored`: {"foo.example.com", "example.com"},
` search foo.example.com example.com `: {"foo.example.com", "example.com"},
` search foo.example.com example.com # ignored`: {"foo.example.com", "example.com"},
``: {},
`# ignored`: {},
`nameserver 1.2.3.4
@ -111,12 +111,12 @@ func TestGetOptions(t *testing.T) {
for resolv, result := range map[string][]string{
`options opt1`: {"opt1"},
`options opt1 # ignored`: {"opt1"},
` options opt1 `: {"opt1"},
` options opt1 # ignored`: {"opt1"},
` options opt1 `: {"opt1"},
` options opt1 # ignored`: {"opt1"},
`options opt1 opt2 opt3`: {"opt1", "opt2", "opt3"},
`options opt1 opt2 opt3 # ignored`: {"opt1", "opt2", "opt3"},
` options opt1 opt2 opt3 `: {"opt1", "opt2", "opt3"},
` options opt1 opt2 opt3 # ignored`: {"opt1", "opt2", "opt3"},
` options opt1 opt2 opt3 `: {"opt1", "opt2", "opt3"},
` options opt1 opt2 opt3 # ignored`: {"opt1", "opt2", "opt3"},
``: {},
`# ignored`: {},
`nameserver 1.2.3.4`: {},

View file

@ -10,7 +10,7 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/docker/libnetwork/iptables"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/types"
"github.com/miekg/dns"
)
@ -240,7 +240,7 @@ func (r *resolver) handleIPQuery(name string, query *dns.Msg, ipType int) (*dns.
if len(addr) > 1 {
addr = shuffleAddr(addr)
}
if ipType == netutils.IPv4 {
if ipType == types.IPv4 {
for _, ip := range addr {
rr := new(dns.A)
rr.Hdr = dns.RR_Header{Name: name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: respTTL}
@ -312,9 +312,9 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
}
name := query.Question[0].Name
if query.Question[0].Qtype == dns.TypeA {
resp, err = r.handleIPQuery(name, query, netutils.IPv4)
resp, err = r.handleIPQuery(name, query, types.IPv4)
} else if query.Question[0].Qtype == dns.TypeAAAA {
resp, err = r.handleIPQuery(name, query, netutils.IPv6)
resp, err = r.handleIPQuery(name, query, types.IPv6)
} else if query.Question[0].Qtype == dns.TypePTR {
resp, err = r.handlePTRQuery(name, query)
}

View file

@ -12,7 +12,6 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/docker/libnetwork/etchosts"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/osl"
"github.com/docker/libnetwork/types"
)
@ -522,7 +521,7 @@ func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoin
n.Lock()
ip, ok = sr.svcMap[name]
if ipType == netutils.IPv6 {
if ipType == types.IPv6 {
// If the name resolved to v4 address then its a valid name in
// the docker network domain. If the network is not v6 enabled
// set ipv6Miss to filter the DNS query from going to external

View file

@ -11,7 +11,6 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/docker/libnetwork/etchosts"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/resolvconf"
"github.com/docker/libnetwork/types"
)
@ -166,7 +165,7 @@ func (sb *sandbox) setupDNS() error {
if len(sb.config.dnsList) > 0 || len(sb.config.dnsSearchList) > 0 || len(sb.config.dnsOptionsList) > 0 {
var (
err error
dnsList = resolvconf.GetNameservers(currRC.Content, netutils.IP)
dnsList = resolvconf.GetNameservers(currRC.Content, types.IP)
dnsSearchList = resolvconf.GetSearchDomains(currRC.Content)
dnsOptionsList = resolvconf.GetOptions(currRC.Content)
)
@ -275,7 +274,7 @@ func (sb *sandbox) rebuildDNS() error {
// localhost entries have already been filtered out from the list
// retain only the v4 servers in sb for forwarding the DNS queries
sb.extDNS = resolvconf.GetNameservers(currRC.Content, netutils.IPv4)
sb.extDNS = resolvconf.GetNameservers(currRC.Content, types.IPv4)
var (
dnsList = []string{sb.resolver.NameServer()}
@ -284,7 +283,7 @@ func (sb *sandbox) rebuildDNS() error {
)
// external v6 DNS servers has to be listed in resolv.conf
dnsList = append(dnsList, resolvconf.GetNameservers(currRC.Content, netutils.IPv6)...)
dnsList = append(dnsList, resolvconf.GetNameservers(currRC.Content, types.IPv6)...)
// Resolver returns the options in the format resolv.conf expects
dnsOptionsList = append(dnsOptionsList, sb.resolver.ResolverOptions()...)

View file

@ -291,12 +291,12 @@ function test_single_network_connectivity() {
dnet_cmd $(inst_id2port 1) container create container_1
# connects to internal network, confirm it can't conmunicate with outside world
net_connect 1 container_1 internal
run runc $(dnet_container_name 1 bridge) $(get_sbox_id 1 container_1) "ping -c 1 www.google.com"
run runc $(dnet_container_name 1 bridge) $(get_sbox_id 1 container_1) "ping -c 1 8.8.8.8"
[[ "$output" == *"1 packets transmitted, 0 packets received, 100% packet loss"* ]]
net_disconnect 1 container_1 internal
# connects to bridge network, confirm it can conmunicate with outside world
net_connect 1 container_1 bridge
runc $(dnet_container_name 1 bridge) $(get_sbox_id 1 container_1) "ping -c 1 www.google.com"
runc $(dnet_container_name 1 bridge) $(get_sbox_id 1 container_1) "ping -c 1 8.8.8.8"
net_disconnect 1 container_1 bridge
dnet_cmd $(inst_id2port 1) container rm container_1
# test conmunications within internal network

View file

@ -25,6 +25,11 @@ load helpers
test_overlay consul skip_add
}
@test "Test overlay network internal network with consul" {
skip_for_circleci
test_overlay consul internal
}
@test "Test overlay network with dnet ungraceful shutdown" {
skip_for_circleci
dnet_cmd $(inst_id2port 1) network create -d overlay multihost
@ -32,8 +37,8 @@ load helpers
end=3
for i in `seq ${start} ${end}`;
do
dnet_cmd $(inst_id2port $i) container create container_${i}
net_connect ${i} container_${i} multihost
dnet_cmd $(inst_id2port $i) container create container_${i}
net_connect ${i} container_${i} multihost
done
hrun runc $(dnet_container_name 1 consul) $(get_sbox_id 1 container_1) "ifconfig eth0"
@ -51,11 +56,6 @@ load helpers
container_1_new_ip=$(echo ${output} | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}')
if [ "$container_1_ip" != "$container_1_new_ip" ]; then
exit 1
exit 1
fi
}
@test "Test overlay network internal network with consul" {
skip_for_circleci
test_overlay consul internal
}

View file

@ -9,6 +9,13 @@ import (
"strings"
)
// constants for the IP address type
const (
IP = iota // IPv4 and IPv6
IPv4
IPv6
)
// UUID represents a globally unique ID of various resources like network and endpoint
type UUID string
@ -323,6 +330,12 @@ func GetMinimalIPNet(nw *net.IPNet) *net.IPNet {
return nw
}
// IsIPNetValid returns true if the ipnet is a valid network/mask
// combination. Otherwise returns false.
func IsIPNetValid(nw *net.IPNet) bool {
return nw.String() != "0.0.0.0/0"
}
var v4inV6MaskPrefix = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
// compareIPMask checks if the passed ip and mask are semantically compatible.