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

Skip to content

Commit 3a523c9

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 ddb8ab4 commit 3a523c9

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed

integration/networking/bridge_linux_test.go

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"flag"
66
"fmt"
7+
"net"
78
"os/exec"
89
"regexp"
910
"strconv"
@@ -17,6 +18,7 @@ import (
1718
"github.com/docker/docker/integration/internal/container"
1819
"github.com/docker/docker/integration/internal/network"
1920
n "github.com/docker/docker/integration/network"
21+
"github.com/docker/docker/internal/testutils/networking"
2022
"github.com/docker/docker/libnetwork/drivers/bridge"
2123
"github.com/docker/docker/libnetwork/netlabel"
2224
"github.com/docker/docker/testutil"
@@ -340,6 +342,153 @@ func TestBridgeINC(t *testing.T) {
340342
}
341343
}
342344

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

0 commit comments

Comments
 (0)