daemon: automatically set network EnableIPv6 if needed
PR 4f47013feb
added a validation step to `NetworkCreate` to ensure
no IPv6 subnet could be set on a network if its `EnableIPv6` parameter
is false.
Before that, the daemon was accepting such request but was doing nothing
with the IPv6 subnet.
This validation step is now deleted, and we automatically set
`EnableIPv6` if an IPv6 subnet was specified.
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
This commit is contained in:
parent
6ce5aa1cd5
commit
5d5eeac310
3 changed files with 29 additions and 13 deletions
|
@ -30,7 +30,28 @@ const (
|
||||||
ip6 ipFamily = "IPv6"
|
ip6 ipFamily = "IPv6"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ValidateIPAM(ipam *IPAM, enableIPv6 bool) error {
|
// HasIPv6Subnets checks whether there's any IPv6 subnets in the ipam parameter. It ignores any invalid Subnet and nil
|
||||||
|
// ipam.
|
||||||
|
func HasIPv6Subnets(ipam *IPAM) bool {
|
||||||
|
if ipam == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cfg := range ipam.Config {
|
||||||
|
subnet, err := netip.ParsePrefix(cfg.Subnet)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if subnet.Addr().Is6() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateIPAM(ipam *IPAM) error {
|
||||||
if ipam == nil {
|
if ipam == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -51,10 +72,6 @@ func ValidateIPAM(ipam *IPAM, enableIPv6 bool) error {
|
||||||
errs = append(errs, fmt.Errorf("invalid subnet %s: it should be %s", subnet, subnet.Masked()))
|
errs = append(errs, fmt.Errorf("invalid subnet %s: it should be %s", subnet, subnet.Masked()))
|
||||||
}
|
}
|
||||||
|
|
||||||
if !enableIPv6 && subnetFamily == ip6 {
|
|
||||||
errs = append(errs, fmt.Errorf("invalid subnet %s: IPv6 has not been enabled for this network", subnet))
|
|
||||||
}
|
|
||||||
|
|
||||||
if ipRangeErrs := validateIPRange(cfg.IPRange, subnet, subnetFamily); len(ipRangeErrs) > 0 {
|
if ipRangeErrs := validateIPRange(cfg.IPRange, subnet, subnetFamily); len(ipRangeErrs) > 0 {
|
||||||
errs = append(errs, ipRangeErrs...)
|
errs = append(errs, ipRangeErrs...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,12 +30,6 @@ func TestNetworkWithInvalidIPAM(t *testing.T) {
|
||||||
"invalid auxiliary address DefaultGatewayIPv4: parent subnet is an IPv4 block",
|
"invalid auxiliary address DefaultGatewayIPv4: parent subnet is an IPv4 block",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "IPv6 subnet is discarded when IPv6 is disabled",
|
|
||||||
ipam: IPAM{Config: []IPAMConfig{{Subnet: "2001:db8::/32"}}},
|
|
||||||
ipv6: false,
|
|
||||||
expectedErrors: []string{"invalid subnet 2001:db8::/32: IPv6 has not been enabled for this network"},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "Invalid data - Subnet",
|
name: "Invalid data - Subnet",
|
||||||
ipam: IPAM{Config: []IPAMConfig{{Subnet: "foobar"}}},
|
ipam: IPAM{Config: []IPAMConfig{{Subnet: "foobar"}}},
|
||||||
|
@ -128,7 +122,7 @@ func TestNetworkWithInvalidIPAM(t *testing.T) {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
errs := ValidateIPAM(&tc.ipam, tc.ipv6)
|
errs := ValidateIPAM(&tc.ipam)
|
||||||
if tc.expectedErrors == nil {
|
if tc.expectedErrors == nil {
|
||||||
assert.NilError(t, errs)
|
assert.NilError(t, errs)
|
||||||
return
|
return
|
||||||
|
|
|
@ -303,6 +303,10 @@ func (daemon *Daemon) createNetwork(cfg *config.Config, create types.NetworkCrea
|
||||||
return nil, errdefs.Forbidden(errors.New(`This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.`))
|
return nil, errdefs.Forbidden(errors.New(`This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.`))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if network.HasIPv6Subnets(create.IPAM) {
|
||||||
|
create.EnableIPv6 = true
|
||||||
|
}
|
||||||
|
|
||||||
var warning string
|
var warning string
|
||||||
nw, err := daemon.GetNetworkByName(create.Name)
|
nw, err := daemon.GetNetworkByName(create.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -347,9 +351,10 @@ func (daemon *Daemon) createNetwork(cfg *config.Config, create types.NetworkCrea
|
||||||
nwOptions = append(nwOptions, libnetwork.NetworkOptionConfigOnly())
|
nwOptions = append(nwOptions, libnetwork.NetworkOptionConfigOnly())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := network.ValidateIPAM(create.IPAM, create.EnableIPv6); err != nil {
|
if err := network.ValidateIPAM(create.IPAM); err != nil {
|
||||||
return nil, errdefs.InvalidParameter(err)
|
return nil, errdefs.InvalidParameter(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if create.IPAM != nil {
|
if create.IPAM != nil {
|
||||||
ipam := create.IPAM
|
ipam := create.IPAM
|
||||||
v4Conf, v6Conf, err := getIpamConfig(ipam.Config)
|
v4Conf, v6Conf, err := getIpamConfig(ipam.Config)
|
||||||
|
|
Loading…
Reference in a new issue