Internal macvlan networks don't need a gateway address.

Signed-off-by: Rob Murray <rob.murray@docker.com>
This commit is contained in:
Rob Murray
2025-01-03 18:24:27 +00:00
parent 8b13cde274
commit 2f60d15ddf
2 changed files with 47 additions and 1 deletions

View File

@@ -6,6 +6,7 @@ import (
"context"
"strings"
"testing"
"time"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
@@ -627,3 +628,35 @@ func TestMACVlanDNS(t *testing.T) {
})
}
}
// TestPointToPoint checks that no gateway is reserved for a macvlan network
// with no parent interface (an "internal" network).
func TestPointToPoint(t *testing.T) {
ctx := testutil.StartSpan(baseContext, t)
apiClient := testEnv.APIClient()
const netName = "p2pmacvlan"
net.CreateNoError(ctx, t, apiClient, netName,
net.WithMacvlan(""),
net.WithIPAM("192.168.135.0/31", ""),
)
defer net.RemoveNoError(ctx, t, apiClient, netName)
const ctrName = "ctr1"
id := container.Run(ctx, t, apiClient,
container.WithNetworkMode(netName),
container.WithName(ctrName),
)
defer apiClient.ContainerRemove(ctx, id, containertypes.RemoveOptions{Force: true})
attachCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
res := container.RunAttach(attachCtx, t, apiClient,
container.WithCmd([]string{"ping", "-c1", "-W3", ctrName}...),
container.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

@@ -40,7 +40,6 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
// if parent interface not specified, create a dummy type link to use named dummy+net_id
if config.Parent == "" {
config.Parent = getDummyName(config.ID)
config.Internal = true
}
foundExisting, err := d.createNetwork(config)
if err != nil {
@@ -62,6 +61,15 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
return nil
}
func (d *driver) GetSkipGwAlloc(opts options.Generic) (ipv4, ipv6 bool, _ error) {
cfg, err := parseNetworkOptions("dummy", opts)
if err != nil {
return false, false, err
}
// "--internal" networks don't need a gateway address.
return cfg.Internal, cfg.Internal, nil
}
// createNetwork is used by new network callbacks and persistent network cache
func (d *driver) createNetwork(config *configuration) (bool, error) {
foundExisting := false
@@ -225,6 +233,11 @@ func parseNetworkOptions(id string, option options.Generic) (*configuration, err
return nil, fmt.Errorf("loopback interface is not a valid macvlan parent link")
}
// With no parent interface, the network is "internal".
if config.Parent == "" {
config.Internal = true
}
config.ID = id
return config, nil
}