diff --git a/daemon/container_unix.go b/daemon/container_unix.go index db4d5b890e..8708c488a0 100644 --- a/daemon/container_unix.go +++ b/daemon/container_unix.go @@ -720,6 +720,10 @@ func (daemon *Daemon) updateNetworkSettings(container *Container, n libnetwork.N container.NetworkSettings = &network.Settings{Networks: make(map[string]*network.EndpointSettings)} } + if !container.hostConfig.NetworkMode.IsHost() && runconfig.NetworkMode(n.Type()).IsHost() { + return runconfig.ErrConflictHostNetwork + } + for s := range container.NetworkSettings.Networks { sn, err := daemon.FindNetwork(s) if err != nil { @@ -1174,6 +1178,10 @@ func (container *Container) DisconnectFromNetwork(n libnetwork.Network) error { return derr.ErrorCodeNotRunning.WithArgs(container.ID) } + if container.hostConfig.NetworkMode.IsHost() && runconfig.NetworkMode(n.Type()).IsHost() { + return runconfig.ErrConflictHostNetwork + } + if err := container.disconnectFromNetwork(n); err != nil { return err } diff --git a/integration-cli/docker_cli_network_unix_test.go b/integration-cli/docker_cli_network_unix_test.go index 4934ad8b07..4481380f28 100644 --- a/integration-cli/docker_cli_network_unix_test.go +++ b/integration-cli/docker_cli_network_unix_test.go @@ -15,6 +15,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/versions/v1p20" "github.com/docker/docker/pkg/integration/checker" + "github.com/docker/docker/runconfig" "github.com/docker/libnetwork/driverapi" remoteapi "github.com/docker/libnetwork/drivers/remote/api" "github.com/docker/libnetwork/ipamapi" @@ -764,3 +765,20 @@ func (s *DockerNetworkSuite) TestDockerNetworkHostModeUngracefulDaemonRestart(c c.Assert(strings.TrimSpace(runningOut), checker.Equals, "true") } } + +func (s *DockerNetworkSuite) TestDockerNetworkConnectToHostFromOtherNetwork(c *check.C) { + dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top") + c.Assert(waitRun("container1"), check.IsNil) + dockerCmd(c, "network", "disconnect", "bridge", "container1") + out, _, err := dockerCmdWithError("network", "connect", "host", "container1") + c.Assert(err, checker.NotNil, check.Commentf(out)) + c.Assert(out, checker.Contains, runconfig.ErrConflictHostNetwork.Error()) +} + +func (s *DockerNetworkSuite) TestDockerNetworkDisconnectFromHost(c *check.C) { + dockerCmd(c, "run", "-d", "--name", "container1", "--net=host", "busybox", "top") + c.Assert(waitRun("container1"), check.IsNil) + out, _, err := dockerCmdWithError("network", "disconnect", "host", "container1") + c.Assert(err, checker.NotNil, check.Commentf("Should err out disconnect from host")) + c.Assert(out, checker.Contains, runconfig.ErrConflictHostNetwork.Error()) +} diff --git a/runconfig/parse.go b/runconfig/parse.go index 6c1ab51741..dae88de941 100644 --- a/runconfig/parse.go +++ b/runconfig/parse.go @@ -22,6 +22,8 @@ var ( ErrConflictUserDefinedNetworkAndLinks = fmt.Errorf("Conflicting options: --net= can't be used with links. This would result in undefined behavior") // ErrConflictSharedNetwork conflict between private and other networks ErrConflictSharedNetwork = fmt.Errorf("Container sharing network namespace with another container or host cannot be connected to any other network") + // ErrConflictHostNetwork conflict from being disconnected from host network or connected to host network. + ErrConflictHostNetwork = fmt.Errorf("Container cannot be disconnected from host network or connected to host network") // ErrConflictNoNetwork conflict between private and other networks ErrConflictNoNetwork = fmt.Errorf("Container cannot be connected to multiple networks with one of the networks in --none mode") // ErrConflictNetworkAndDNS conflict between --dns and the network mode