diff --git a/libnetwork/drivers/ipvlan/ipvlan_endpoint.go b/libnetwork/drivers/ipvlan/ipvlan_endpoint.go index faeb8434ac..ef3491b4b7 100644 --- a/libnetwork/drivers/ipvlan/ipvlan_endpoint.go +++ b/libnetwork/drivers/ipvlan/ipvlan_endpoint.go @@ -31,7 +31,7 @@ func (d *driver) CreateEndpoint(ctx context.Context, nid, eid string, ifInfo dri addr: ifInfo.Address(), addrv6: ifInfo.AddressIPv6(), } - if ep.addr == nil { + if ep.addr == nil && ep.addrv6 == nil { return fmt.Errorf("create endpoint was not passed an IP address") } // disallow port mapping -p diff --git a/libnetwork/drivers/ipvlan/ipvlan_joinleave.go b/libnetwork/drivers/ipvlan/ipvlan_joinleave.go index 4414d99626..71f317411e 100644 --- a/libnetwork/drivers/ipvlan/ipvlan_joinleave.go +++ b/libnetwork/drivers/ipvlan/ipvlan_joinleave.go @@ -65,15 +65,17 @@ func (d *driver) Join(ctx context.Context, nid, eid string, sboxKey string, jinf case modeL3, modeL3S: // disable gateway services to add a default gw using dev eth0 only jinfo.DisableGatewayService() - defaultRoute, err := ifaceGateway(defaultV4RouteCidr) - if err != nil { - return err + if ep.addr != nil { + defaultRoute, err := ifaceGateway(defaultV4RouteCidr) + if err != nil { + return err + } + if err := jinfo.AddStaticRoute(defaultRoute.Destination, defaultRoute.RouteType, defaultRoute.NextHop); err != nil { + return fmt.Errorf("failed to set an ipvlan l3/l3s mode ipv4 default gateway: %v", err) + } + log.G(ctx).Debugf("Ipvlan Endpoint Joined with IPv4_Addr: %s, Ipvlan_Mode: %s, Parent: %s", + ep.addr.IP.String(), n.config.IpvlanMode, n.config.Parent) } - if err := jinfo.AddStaticRoute(defaultRoute.Destination, defaultRoute.RouteType, defaultRoute.NextHop); err != nil { - return fmt.Errorf("failed to set an ipvlan l3/l3s mode ipv4 default gateway: %v", err) - } - log.G(ctx).Debugf("Ipvlan Endpoint Joined with IPv4_Addr: %s, Ipvlan_Mode: %s, Parent: %s", - ep.addr.IP.String(), n.config.IpvlanMode, n.config.Parent) // If the endpoint has a v6 address, set a v6 default route if ep.addrv6 != nil { default6Route, err := ifaceGateway(defaultV6RouteCidr) diff --git a/libnetwork/drivers/ipvlan/ipvlan_network.go b/libnetwork/drivers/ipvlan/ipvlan_network.go index 4ffaafb04f..64f87c938d 100644 --- a/libnetwork/drivers/ipvlan/ipvlan_network.go +++ b/libnetwork/drivers/ipvlan/ipvlan_network.go @@ -7,6 +7,7 @@ import ( "fmt" "github.com/containerd/log" + "github.com/docker/docker/errdefs" "github.com/docker/docker/libnetwork/driverapi" "github.com/docker/docker/libnetwork/netlabel" "github.com/docker/docker/libnetwork/ns" @@ -26,9 +27,17 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo return fmt.Errorf("kernel version failed to meet the minimum ipvlan kernel requirement of %d.%d, found %d.%d.%d", ipvlanKernelVer, ipvlanMajorVer, kv.Kernel, kv.Major, kv.Minor) } - // reject a null v4 network - if len(ipV4Data) == 0 || ipV4Data[0].Pool.String() == "0.0.0.0/0" { - return fmt.Errorf("ipv4 pool is empty") + // reject a null v4 network if ipv4 is required + if v, ok := option[netlabel.EnableIPv4]; ok && v.(bool) { + if len(ipV4Data) == 0 || ipV4Data[0].Pool.String() == "0.0.0.0/0" { + return fmt.Errorf("ipv4 pool is empty") + } + } + // reject a null v6 network if ipv6 is required + if v, ok := option[netlabel.EnableIPv6]; ok && v.(bool) { + if len(ipV6Data) == 0 || ipV6Data[0].Pool.String() == "::/0" { + return errdefs.InvalidParameter(fmt.Errorf("ipv6 pool is empty")) + } } // parse and validate the config and bind to networkConfiguration config, err := parseNetworkOptions(nid, option)