diff --git a/libnetwork/drivers/bridge/bridge.go b/libnetwork/drivers/bridge/bridge.go index 651a6536f5..c3cf1e1817 100644 --- a/libnetwork/drivers/bridge/bridge.go +++ b/libnetwork/drivers/bridge/bridge.go @@ -162,8 +162,8 @@ func (d *driver) Config(option map[string]interface{}) error { return ErrConfigExists } - genericData := option[netlabel.GenericData] - if genericData != nil { + genericData, ok := option[netlabel.GenericData] + if ok && genericData != nil { switch opt := genericData.(type) { case options.Generic: opaqueConfig, err := options.GenerateFromModel(opt, &Configuration{}) @@ -178,6 +178,8 @@ func (d *driver) Config(option map[string]interface{}) error { } d.config = config + } else { + config = &Configuration{} } if config.EnableIPForwarding { @@ -198,8 +200,8 @@ func (d *driver) getNetwork(id types.UUID) (*bridgeNetwork, error) { func parseNetworkOptions(option options.Generic) (*NetworkConfiguration, error) { var config *NetworkConfiguration - genericData := option[netlabel.GenericData] - if genericData != nil { + genericData, ok := option[netlabel.GenericData] + if ok && genericData != nil { switch opt := genericData.(type) { case options.Generic: opaqueConfig, err := options.GenerateFromModel(opt, &NetworkConfiguration{}) @@ -220,6 +222,10 @@ func parseNetworkOptions(option options.Generic) (*NetworkConfiguration, error) config = &NetworkConfiguration{} } + if _, ok := option[netlabel.EnableIPv6]; ok { + config.EnableIPv6 = option[netlabel.EnableIPv6].(bool) + } + return config, nil } diff --git a/libnetwork/endpoint.go b/libnetwork/endpoint.go index 7643b1ecf1..734fbe98a9 100644 --- a/libnetwork/endpoint.go +++ b/libnetwork/endpoint.go @@ -409,7 +409,7 @@ func (ep *endpoint) setupDNS() error { } // replace any localhost/127.* but always discard IPv6 entries for now. - resolvConf, _ = resolvconf.FilterResolvDns(resolvConf, false) + resolvConf, _ = resolvconf.FilterResolvDns(resolvConf, ep.network.enableIPv6) return ioutil.WriteFile(ep.container.config.resolvConfPath, resolvConf, 0644) } diff --git a/libnetwork/libnetwork_test.go b/libnetwork/libnetwork_test.go index 3191df1c27..e84fb890e7 100644 --- a/libnetwork/libnetwork_test.go +++ b/libnetwork/libnetwork_test.go @@ -1,6 +1,8 @@ package libnetwork_test import ( + "bytes" + "io/ioutil" "net" "os" "testing" @@ -30,16 +32,13 @@ func createTestNetwork(networkType, networkName string, option options.Generic, genericOption := make(map[string]interface{}) genericOption[netlabel.GenericData] = option - genericNetOption := make(map[string]interface{}) - genericNetOption[netlabel.GenericData] = netOption - err := controller.ConfigureNetworkDriver(networkType, genericOption) if err != nil { return nil, err } network, err := controller.NewNetwork(networkType, networkName, - libnetwork.NetworkOptionGeneric(genericNetOption)) + libnetwork.NetworkOptionGeneric(netOption)) if err != nil { return nil, err } @@ -775,3 +774,106 @@ func TestEndpointUpdateParent(t *testing.T) { t.Fatal(err) } } + +func TestEnableIPv6(t *testing.T) { + defer netutils.SetupTestNetNS(t)() + + tmpResolvConf := []byte("search pommesfrites.fr\nnameserver 12.34.56.78\nnameserver 2001:4860:4860::8888") + //take a copy of resolv.conf for restoring after test completes + resolvConfSystem, err := ioutil.ReadFile("/etc/resolv.conf") + if err != nil { + t.Fatal(err) + } + //cleanup + defer func() { + if err := ioutil.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil { + t.Fatal(err) + } + }() + + netOption := options.Generic{ + netlabel.EnableIPv6: true, + } + + n, err := createTestNetwork("bridge", "testnetwork", options.Generic{}, netOption) + if err != nil { + t.Fatal(err) + } + + ep1, err := n.CreateEndpoint("ep1", nil) + if err != nil { + t.Fatal(err) + } + + if err := ioutil.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil { + t.Fatal(err) + } + + resolvConfPath := "/tmp/libnetwork_test/resolv.conf" + + _, err = ep1.Join(containerID, + libnetwork.JoinOptionResolvConfPath(resolvConfPath)) + + content, err := ioutil.ReadFile(resolvConfPath) + if err != nil { + t.Fatal(err) + } + + if !bytes.Equal(content, tmpResolvConf) { + t.Fatalf("Expected %s, Got %s", string(tmpResolvConf), string(content)) + } + + if err != nil { + t.Fatal(err) + } +} + +func TestNoEnableIPv6(t *testing.T) { + defer netutils.SetupTestNetNS(t)() + + tmpResolvConf := []byte("search pommesfrites.fr\nnameserver 12.34.56.78\nnameserver 2001:4860:4860::8888") + expectedResolvConf := []byte("search pommesfrites.fr\nnameserver 12.34.56.78\n") + //take a copy of resolv.conf for restoring after test completes + resolvConfSystem, err := ioutil.ReadFile("/etc/resolv.conf") + if err != nil { + t.Fatal(err) + } + //cleanup + defer func() { + if err := ioutil.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil { + t.Fatal(err) + } + }() + + n, err := createTestNetwork("bridge", "testnetwork", options.Generic{}, options.Generic{}) + if err != nil { + t.Fatal(err) + } + + ep1, err := n.CreateEndpoint("ep1", nil) + if err != nil { + t.Fatal(err) + } + + if err := ioutil.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil { + t.Fatal(err) + } + + resolvConfPath := "/tmp/libnetwork_test/resolv.conf" + + _, err = ep1.Join(containerID, + libnetwork.JoinOptionResolvConfPath(resolvConfPath)) + + content, err := ioutil.ReadFile(resolvConfPath) + if err != nil { + t.Fatal(err) + } + + if !bytes.Equal(content, expectedResolvConf) { + t.Fatalf("Expected %s, Got %s", string(expectedResolvConf), string(content)) + } + + if err != nil { + t.Fatal(err) + } +} diff --git a/libnetwork/network.go b/libnetwork/network.go index 4f65677cf5..f1830e90d5 100644 --- a/libnetwork/network.go +++ b/libnetwork/network.go @@ -5,6 +5,7 @@ import ( "github.com/docker/docker/pkg/stringid" "github.com/docker/libnetwork/driverapi" + "github.com/docker/libnetwork/pkg/netlabel" "github.com/docker/libnetwork/pkg/options" "github.com/docker/libnetwork/types" ) @@ -52,6 +53,7 @@ type network struct { networkType string id types.UUID driver driverapi.Driver + enableIPv6 bool endpoints endpointTable generic options.Generic sync.Mutex @@ -83,6 +85,9 @@ type NetworkOption func(n *network) func NetworkOptionGeneric(generic map[string]interface{}) NetworkOption { return func(n *network) { n.generic = generic + if _, ok := generic[netlabel.EnableIPv6]; ok { + n.enableIPv6 = generic[netlabel.EnableIPv6].(bool) + } } }