diff --git a/integration/service/network_test.go b/integration/service/network_test.go index ba4a18a68c..a8dd2e955c 100644 --- a/integration/service/network_test.go +++ b/integration/service/network_test.go @@ -9,6 +9,7 @@ import ( "github.com/docker/docker/integration/internal/container" net "github.com/docker/docker/integration/internal/network" "github.com/docker/docker/integration/internal/swarm" + "github.com/docker/docker/testutil/daemon" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" "gotest.tools/v3/skip" @@ -115,3 +116,21 @@ func TestDockerNetworkReConnect(t *testing.T) { assert.NilError(t, err) assert.Check(t, is.DeepEqual(n1, n2)) } + +// Check that a swarm-scoped network can't have EnableIPv4=false. +func TestSwarmNoDisableIPv4(t *testing.T) { + skip.If(t, testEnv.DaemonInfo.OSType == "windows") + ctx := setupTest(t) + + d := swarm.NewSwarm(ctx, t, testEnv, daemon.WithExperimental()) + defer d.Stop(t) + client := d.NewClientT(t) + defer client.Close() + + _, err := net.Create(ctx, client, "overlay-v6-only", + net.WithDriver("overlay"), + net.WithAttachable(), + net.WithIPv4(false), + ) + assert.Check(t, is.ErrorContains(err, "IPv4 cannot be disabled in a Swarm scoped network")) +} diff --git a/libnetwork/controller.go b/libnetwork/controller.go index 1e3d211248..0a8fe2e062 100644 --- a/libnetwork/controller.go +++ b/libnetwork/controller.go @@ -550,6 +550,9 @@ func (c *Controller) NewNetwork(networkType, name string, id string, options ... if (caps.DataScope == scope.Global || nw.scope == scope.Swarm) && c.isSwarmNode() && !nw.dynamic { if c.isManager() { + if !nw.enableIPv4 { + return nil, types.InvalidParameterErrorf("IPv4 cannot be disabled in a Swarm scoped network") + } // For non-distributed controlled environment, globalscoped non-dynamic networks are redirected to Manager return nil, ManagerRedirectError(name) }