Преглед изворни кода

Merge pull request #47356 from robmry/47329_restore_internal_bridge_addr

Make 'internal' bridge networks accessible from host
Sebastiaan van Stijn пре 1 година
родитељ
комит
7bf8d2606e

+ 57 - 0
integration/networking/bridge_test.go

@@ -477,3 +477,60 @@ func TestDefaultBridgeAddresses(t *testing.T) {
 		})
 	}
 }
+
+// Test that a container on an 'internal' network has IP connectivity with
+// the host (on its own subnet, because the n/w bridge has an address on that
+// subnet, and it's in the host's namespace).
+// Regression test for https://github.com/moby/moby/issues/47329
+func TestInternalNwConnectivity(t *testing.T) {
+	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
+
+	ctx := setupTest(t)
+
+	d := daemon.New(t)
+	d.StartWithBusybox(ctx, t, "-D", "--experimental", "--ip6tables")
+	defer d.Stop(t)
+
+	c := d.NewClientT(t)
+	defer c.Close()
+
+	const bridgeName = "intnw"
+	const gw4 = "172.30.0.1"
+	const gw6 = "fda9:4130:4715::1234"
+	network.CreateNoError(ctx, t, c, bridgeName,
+		network.WithInternal(),
+		network.WithIPv6(),
+		network.WithIPAM("172.30.0.0/24", gw4),
+		network.WithIPAM("fda9:4130:4715::/64", gw6),
+		network.WithDriver("bridge"),
+		network.WithOption("com.docker.network.bridge.name", bridgeName),
+	)
+	defer network.RemoveNoError(ctx, t, c, bridgeName)
+
+	const ctrName = "intctr"
+	id := container.Run(ctx, t, c,
+		container.WithName(ctrName),
+		container.WithImage("busybox:latest"),
+		container.WithCmd("top"),
+		container.WithNetworkMode(bridgeName),
+	)
+	defer c.ContainerRemove(ctx, id, containertypes.RemoveOptions{Force: true})
+
+	execCtx, cancel := context.WithTimeout(ctx, 20*time.Second)
+	defer cancel()
+
+	res := container.ExecT(execCtx, t, c, id, []string{"ping", "-c1", "-W3", gw4})
+	assert.Check(t, is.Equal(res.ExitCode, 0))
+	assert.Check(t, is.Equal(res.Stderr(), ""))
+	assert.Check(t, is.Contains(res.Stdout(), "1 packets transmitted, 1 packets received"))
+
+	res = container.ExecT(execCtx, t, c, id, []string{"ping6", "-c1", "-W3", gw6})
+	assert.Check(t, is.Equal(res.ExitCode, 0))
+	assert.Check(t, is.Equal(res.Stderr(), ""))
+	assert.Check(t, is.Contains(res.Stdout(), "1 packets transmitted, 1 packets received"))
+
+	// Addresses outside the internal subnet must not be accessible.
+	res = container.ExecT(execCtx, t, c, id, []string{"ping", "-c1", "-W3", "8.8.8.8"})
+	assert.Check(t, is.Equal(res.ExitCode, 1))
+	assert.Check(t, is.Contains(res.Stderr(), "Network is unreachable"))
+}

+ 4 - 6
libnetwork/drivers/bridge/setup_ipv4_linux.go

@@ -32,10 +32,6 @@ func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
 	//             are decoupled, we should assign it only when it's really needed.
 	i.bridgeIPv4 = config.AddressIPv4
 
-	if config.Internal {
-		return nil
-	}
-
 	if !config.InhibitIPv4 {
 		addrv4List, err := i.addresses(netlink.FAMILY_V4)
 		if err != nil {
@@ -57,8 +53,10 @@ func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
 		}
 	}
 
-	// Store the default gateway
-	i.gatewayIPv4 = config.AddressIPv4.IP
+	if !config.Internal {
+		// Store the default gateway
+		i.gatewayIPv4 = config.AddressIPv4.IP
+	}
 
 	return nil
 }

+ 2 - 2
libnetwork/drivers/bridge/setup_verify_linux.go

@@ -20,12 +20,12 @@ func setupVerifyAndReconcileIPv4(config *networkConfiguration, i *bridgeInterfac
 	addrv4, _ := selectIPv4Address(addrsv4, config.AddressIPv4)
 
 	// Verify that the bridge has an IPv4 address.
-	if !config.Internal && addrv4.IPNet == nil {
+	if addrv4.IPNet == nil {
 		return &ErrNoIPAddr{}
 	}
 
 	// Verify that the bridge IPv4 address matches the requested configuration.
-	if config.AddressIPv4 != nil && addrv4.IPNet != nil && !addrv4.IP.Equal(config.AddressIPv4.IP) {
+	if config.AddressIPv4 != nil && !addrv4.IP.Equal(config.AddressIPv4.IP) {
 		return &IPv4AddrNoMatchError{IP: addrv4.IP, CfgIP: config.AddressIPv4.IP}
 	}