Bridge - skip gateway allocation if no gateway is needed

An "--internal" bridge network will never set up a default route
and, with "-o com.docker.network.bridge.inhibit_ipv4", no Gateway
address will be assigned to the bridge.

So, implement the SkipGwAlloc interface in the bridge driver, and
use it to to indicate that no Gateway address is required in this
specific case.

Signed-off-by: Rob Murray <rob.murray@docker.com>
This commit is contained in:
Rob Murray
2025-01-10 10:38:23 +00:00
parent 38e76ebea9
commit 43f71fb582
2 changed files with 48 additions and 0 deletions

View File

@@ -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"))
}

View File

@@ -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