diff --git a/integration/network/bridge/bridge_linux_test.go b/integration/network/bridge/bridge_linux_test.go index 8d3ea66d66..6d59d56f0e 100644 --- a/integration/network/bridge/bridge_linux_test.go +++ b/integration/network/bridge/bridge_linux_test.go @@ -14,6 +14,7 @@ import ( ctr "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/network" "github.com/docker/docker/internal/testutils/networking" + "github.com/docker/docker/libnetwork/drivers/bridge" "github.com/docker/docker/testutil" "github.com/docker/docker/testutil/daemon" "gotest.tools/v3/assert" @@ -315,3 +316,37 @@ func TestFilterForwardPolicy(t *testing.T) { }) } } + +// TestPointToPoint checks that a "/31" --internal network with inhibit_ipv4 +// has two addresses available for containers (no address is reserved for a +// gateway, because it won't be used). +func TestPointToPoint(t *testing.T) { + ctx := setupTest(t) + apiClient := testEnv.APIClient() + + const netName = "testp2pbridge" + network.CreateNoError(ctx, t, apiClient, netName, + network.WithIPAM("192.168.135.0/31", ""), + network.WithInternal(), + network.WithOption(bridge.InhibitIPv4, "true"), + ) + defer network.RemoveNoError(ctx, t, apiClient, netName) + + const ctrName = "ctr1" + id := ctr.Run(ctx, t, apiClient, + ctr.WithNetworkMode(netName), + ctr.WithName(ctrName), + ) + defer apiClient.ContainerRemove(ctx, id, containertypes.RemoveOptions{Force: true}) + + attachCtx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + res := ctr.RunAttach(attachCtx, t, apiClient, + ctr.WithCmd([]string{"ping", "-c1", "-W3", ctrName}...), + ctr.WithNetworkMode(netName), + ) + defer apiClient.ContainerRemove(ctx, res.ContainerID, containertypes.RemoveOptions{Force: true}) + assert.Check(t, is.Equal(res.ExitCode, 0)) + assert.Check(t, is.Equal(res.Stderr.Len(), 0)) + assert.Check(t, is.Contains(res.Stdout.String(), "1 packets transmitted, 1 packets received")) +} diff --git a/libnetwork/drivers/bridge/bridge_linux.go b/libnetwork/drivers/bridge/bridge_linux.go index 10ff4af125..4c333a3331 100644 --- a/libnetwork/drivers/bridge/bridge_linux.go +++ b/libnetwork/drivers/bridge/bridge_linux.go @@ -745,6 +745,19 @@ func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (s return "", nil } +func (d *driver) GetSkipGwAlloc(opts options.Generic) (ipv4, ipv6 bool, _ error) { + // The network doesn't exist yet, so use a dummy id that's long enough to be + // truncated to a short-id (12 characters) and used in the bridge device name. + cfg, err := parseNetworkOptions("dummyNetworkId", opts) + if err != nil { + return false, false, err + } + // cfg.InhibitIPv4 means no gateway address will be assigned to the bridge, if + // the network is also cfg.Internal, there will not be a default route to use + // the gateway address either. + return cfg.InhibitIPv4 && cfg.Internal, false, nil +} + // CreateNetwork creates a new network using the bridge driver. func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error { // Sanity checks