Signed-off-by: Rob Murray <rob.murray@docker.com>
| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
"context" |
| 7 | 7 |
"strings" |
| 8 | 8 |
"testing" |
| 9 |
+ "time" |
|
| 9 | 10 |
|
| 10 | 11 |
containertypes "github.com/docker/docker/api/types/container" |
| 11 | 12 |
"github.com/docker/docker/api/types/network" |
| ... | ... |
@@ -627,3 +628,35 @@ func TestMACVlanDNS(t *testing.T) {
|
| 627 | 627 |
}) |
| 628 | 628 |
} |
| 629 | 629 |
} |
| 630 |
+ |
|
| 631 |
+// TestPointToPoint checks that no gateway is reserved for a macvlan network |
|
| 632 |
+// with no parent interface (an "internal" network). |
|
| 633 |
+func TestPointToPoint(t *testing.T) {
|
|
| 634 |
+ ctx := testutil.StartSpan(baseContext, t) |
|
| 635 |
+ apiClient := testEnv.APIClient() |
|
| 636 |
+ |
|
| 637 |
+ const netName = "p2pmacvlan" |
|
| 638 |
+ net.CreateNoError(ctx, t, apiClient, netName, |
|
| 639 |
+ net.WithMacvlan(""),
|
|
| 640 |
+ net.WithIPAM("192.168.135.0/31", ""),
|
|
| 641 |
+ ) |
|
| 642 |
+ defer net.RemoveNoError(ctx, t, apiClient, netName) |
|
| 643 |
+ |
|
| 644 |
+ const ctrName = "ctr1" |
|
| 645 |
+ id := container.Run(ctx, t, apiClient, |
|
| 646 |
+ container.WithNetworkMode(netName), |
|
| 647 |
+ container.WithName(ctrName), |
|
| 648 |
+ ) |
|
| 649 |
+ defer apiClient.ContainerRemove(ctx, id, containertypes.RemoveOptions{Force: true})
|
|
| 650 |
+ |
|
| 651 |
+ attachCtx, cancel := context.WithTimeout(ctx, 5*time.Second) |
|
| 652 |
+ defer cancel() |
|
| 653 |
+ res := container.RunAttach(attachCtx, t, apiClient, |
|
| 654 |
+ container.WithCmd([]string{"ping", "-c1", "-W3", ctrName}...),
|
|
| 655 |
+ container.WithNetworkMode(netName), |
|
| 656 |
+ ) |
|
| 657 |
+ defer apiClient.ContainerRemove(ctx, res.ContainerID, containertypes.RemoveOptions{Force: true})
|
|
| 658 |
+ assert.Check(t, is.Equal(res.ExitCode, 0)) |
|
| 659 |
+ assert.Check(t, is.Equal(res.Stderr.Len(), 0)) |
|
| 660 |
+ assert.Check(t, is.Contains(res.Stdout.String(), "1 packets transmitted, 1 packets received")) |
|
| 661 |
+} |
| ... | ... |
@@ -40,7 +40,6 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
|
| 40 | 40 |
// if parent interface not specified, create a dummy type link to use named dummy+net_id |
| 41 | 41 |
if config.Parent == "" {
|
| 42 | 42 |
config.Parent = getDummyName(config.ID) |
| 43 |
- config.Internal = true |
|
| 44 | 43 |
} |
| 45 | 44 |
foundExisting, err := d.createNetwork(config) |
| 46 | 45 |
if err != nil {
|
| ... | ... |
@@ -62,6 +61,15 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
|
| 62 | 62 |
return nil |
| 63 | 63 |
} |
| 64 | 64 |
|
| 65 |
+func (d *driver) GetSkipGwAlloc(opts options.Generic) (ipv4, ipv6 bool, _ error) {
|
|
| 66 |
+ cfg, err := parseNetworkOptions("dummy", opts)
|
|
| 67 |
+ if err != nil {
|
|
| 68 |
+ return false, false, err |
|
| 69 |
+ } |
|
| 70 |
+ // "--internal" networks don't need a gateway address. |
|
| 71 |
+ return cfg.Internal, cfg.Internal, nil |
|
| 72 |
+} |
|
| 73 |
+ |
|
| 65 | 74 |
// createNetwork is used by new network callbacks and persistent network cache |
| 66 | 75 |
func (d *driver) createNetwork(config *configuration) (bool, error) {
|
| 67 | 76 |
foundExisting := false |
| ... | ... |
@@ -225,6 +233,11 @@ func parseNetworkOptions(id string, option options.Generic) (*configuration, err |
| 225 | 225 |
return nil, fmt.Errorf("loopback interface is not a valid macvlan parent link")
|
| 226 | 226 |
} |
| 227 | 227 |
|
| 228 |
+ // With no parent interface, the network is "internal". |
|
| 229 |
+ if config.Parent == "" {
|
|
| 230 |
+ config.Internal = true |
|
| 231 |
+ } |
|
| 232 |
+ |
|
| 228 | 233 |
config.ID = id |
| 229 | 234 |
return config, nil |
| 230 | 235 |
} |