Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2d5ccca

Browse files
committed
Test routed n/w inter-network communication
Add an integration test to check that a container on a network with gateway-mode=nat can access a container on a network with gateway-mode=routed, but not vice-versa. Signed-off-by: Rob Murray <[email protected]>
1 parent e8753e4 commit 2d5ccca

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

integration/networking/bridge_linux_test.go

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package networking
33
import (
44
"context"
55
"fmt"
6+
"net"
67
"os/exec"
78
"regexp"
89
"strings"
@@ -14,9 +15,12 @@ import (
1415
"github.com/docker/docker/client"
1516
"github.com/docker/docker/integration/internal/container"
1617
"github.com/docker/docker/integration/internal/network"
18+
"github.com/docker/docker/internal/testutils/networking"
19+
"github.com/docker/docker/libnetwork/drivers/bridge"
1720
"github.com/docker/docker/libnetwork/netlabel"
1821
"github.com/docker/docker/testutil"
1922
"github.com/docker/docker/testutil/daemon"
23+
"github.com/docker/go-connections/nat"
2024
"github.com/google/go-cmp/cmp/cmpopts"
2125
"gotest.tools/v3/assert"
2226
is "gotest.tools/v3/assert/cmp"
@@ -335,6 +339,153 @@ func TestBridgeINC(t *testing.T) {
335339
}
336340
}
337341

342+
// TestBridgeINCRouted makes sure a container on a gateway-mode=nat network can establish
343+
// a connection to a container on a gateway-mode=routed network, but not vice-versa.
344+
func TestBridgeINCRouted(t *testing.T) {
345+
ctx := setupTest(t)
346+
347+
d := daemon.New(t)
348+
d.StartWithBusybox(ctx, t)
349+
t.Cleanup(func() { d.Stop(t) })
350+
351+
c := d.NewClientT(t)
352+
t.Cleanup(func() { c.Close() })
353+
354+
type ctrDesc struct {
355+
id string
356+
ipv4 string
357+
ipv6 string
358+
}
359+
360+
// Create a network and run a container on it.
361+
// Run http servers on ports 80 and 81, but only map/open port 80.
362+
createNet := func(gwMode string) ctrDesc {
363+
netName := "test-" + gwMode
364+
network.CreateNoError(ctx, t, c, netName,
365+
network.WithDriver("bridge"),
366+
network.WithIPv6(),
367+
network.WithOption(bridge.BridgeName, "br-"+gwMode),
368+
network.WithOption(bridge.IPv4GatewayMode, gwMode),
369+
network.WithOption(bridge.IPv6GatewayMode, gwMode),
370+
)
371+
t.Cleanup(func() {
372+
network.RemoveNoError(ctx, t, c, netName)
373+
})
374+
375+
ctrId := container.Run(ctx, t, c,
376+
container.WithNetworkMode(netName),
377+
container.WithName("ctr-"+gwMode),
378+
container.WithExposedPorts("80/tcp"),
379+
container.WithPortMap(nat.PortMap{"80/tcp": {}}),
380+
)
381+
t.Cleanup(func() {
382+
c.ContainerRemove(ctx, ctrId, containertypes.RemoveOptions{Force: true})
383+
})
384+
385+
container.ExecT(ctx, t, c, ctrId, []string{"httpd", "-p", "80"})
386+
container.ExecT(ctx, t, c, ctrId, []string{"httpd", "-p", "81"})
387+
388+
insp := container.Inspect(ctx, t, c, ctrId)
389+
return ctrDesc{
390+
id: ctrId,
391+
ipv4: insp.NetworkSettings.Networks[netName].IPAddress,
392+
ipv6: insp.NetworkSettings.Networks[netName].GlobalIPv6Address,
393+
}
394+
}
395+
396+
natDesc := createNet("nat")
397+
routedDesc := createNet("routed")
398+
399+
const (
400+
httpSuccess = "404 Not Found"
401+
httpFail = "download timed out"
402+
pingSuccess = 0
403+
pingFail = 1
404+
)
405+
406+
testcases := []struct {
407+
name string
408+
from ctrDesc
409+
to ctrDesc
410+
port string
411+
expPingExit int
412+
expHttpStderr string
413+
}{
414+
{
415+
name: "nat to routed open port",
416+
from: natDesc,
417+
to: routedDesc,
418+
port: "80",
419+
expPingExit: pingSuccess,
420+
expHttpStderr: httpSuccess,
421+
},
422+
{
423+
name: "nat to routed closed port",
424+
from: natDesc,
425+
to: routedDesc,
426+
port: "81",
427+
expPingExit: pingSuccess,
428+
expHttpStderr: httpFail,
429+
},
430+
{
431+
name: "routed to nat open port",
432+
from: routedDesc,
433+
to: natDesc,
434+
port: "80",
435+
expPingExit: pingFail,
436+
expHttpStderr: httpFail,
437+
},
438+
{
439+
name: "routed to nat closed port",
440+
from: routedDesc,
441+
to: natDesc,
442+
port: "81",
443+
expPingExit: pingFail,
444+
expHttpStderr: httpFail,
445+
},
446+
}
447+
448+
for _, fwdPolicy := range []string{"ACCEPT", "DROP"} {
449+
networking.SetFilterForwardPolicies(t, fwdPolicy)
450+
t.Run(fwdPolicy, func(t *testing.T) {
451+
for _, tc := range testcases {
452+
t.Run(tc.name+"/v4/ping", func(t *testing.T) {
453+
t.Parallel()
454+
ctx := testutil.StartSpan(ctx, t)
455+
pingRes4 := container.ExecT(ctx, t, c, tc.from.id, []string{
456+
"ping", "-4", "-c1", "-W3", tc.to.ipv4,
457+
})
458+
assert.Check(t, is.Equal(pingRes4.ExitCode, tc.expPingExit))
459+
})
460+
t.Run(tc.name+"/v6/ping", func(t *testing.T) {
461+
t.Parallel()
462+
ctx := testutil.StartSpan(ctx, t)
463+
pingRes6 := container.ExecT(ctx, t, c, tc.from.id, []string{
464+
"ping", "-6", "-c1", "-W3", tc.to.ipv6,
465+
})
466+
assert.Check(t, is.Equal(pingRes6.ExitCode, tc.expPingExit))
467+
})
468+
t.Run(tc.name+"/v4/http", func(t *testing.T) {
469+
t.Parallel()
470+
ctx := testutil.StartSpan(ctx, t)
471+
httpRes4 := container.ExecT(ctx, t, c, tc.from.id, []string{
472+
"wget", "-T3", "http://" + net.JoinHostPort(tc.to.ipv4, tc.port),
473+
})
474+
assert.Check(t, is.Contains(httpRes4.Stderr(), tc.expHttpStderr))
475+
})
476+
t.Run(tc.name+"/v6/http", func(t *testing.T) {
477+
t.Parallel()
478+
ctx := testutil.StartSpan(ctx, t)
479+
httpRes6 := container.ExecT(ctx, t, c, tc.from.id, []string{
480+
"wget", "-T3", "http://" + net.JoinHostPort(tc.to.ipv6, tc.port),
481+
})
482+
assert.Check(t, is.Contains(httpRes6.Stderr(), tc.expHttpStderr))
483+
})
484+
}
485+
})
486+
}
487+
}
488+
338489
func TestDefaultBridgeIPv6(t *testing.T) {
339490
ctx := setupTest(t)
340491

0 commit comments

Comments
 (0)