The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8233
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Adds `ipv4.routes.anycast` and `ipv6.routes.anycast` boolean settings for `physical` networks. Defaults to false. Allows OVN networks using physical network as uplink to relax external subnet/route overlap detection when used with `ovn.ingress_mode=routed`.
From 3bff5fac1e39e625ace73878bf4c182e6fb2f2dd Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Wed, 9 Dec 2020 17:29:07 +0000 Subject: [PATCH 1/6] doc/networks: Adds ipv4.routes.anycast and ipv6.routes.anycast to physical networks Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- doc/networks.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/networks.md b/doc/networks.md index 8877835e70..55082dcc82 100644 --- a/doc/networks.md +++ b/doc/networks.md @@ -324,8 +324,10 @@ vlan | integer | - | - ipv4.gateway | string | standard mode | - | IPv4 address for the gateway and network (CIDR notation) ipv4.ovn.ranges | string | - | - | Comma separate list of IPv4 ranges to use for child OVN network routers (FIRST-LAST format) ipv4.routes | string | ipv4 address | - | Comma separated list of additional IPv4 CIDR subnets that can be used with child OVN networks ipv4.routes.external setting +ipv4.routes.anycast | boolean | ipv4 address | false | Allow the overlapping routes to be used on multiple networks/NIC at the same time. ipv6.gateway | string | standard mode | - | IPv6 address for the gateway and network (CIDR notation) ipv6.ovn.ranges | string | - | - | Comma separate list of IPv6 ranges to use for child OVN network routers (FIRST-LAST format) ipv6.routes | string | ipv6 address | - | Comma separated list of additional IPv6 CIDR subnets that can be used with child OVN networks ipv6.routes.external setting +ipv6.routes.anycast | boolean | ipv6 address | false | Allow the overlapping routes to be used on multiple networks/NIC at the same time. dns.nameservers | string | standard mode | - | List of DNS server IPs on physical network ovn.ingress_mode | string | standard mode | l2proxy | Sets the method that OVN NIC external IPs will be advertised on uplink network. Either `l2proxy` (proxy ARP/NDP) or `routed`. From 33ac2d80492c9efd3ab433c60dff755f607fd3e9 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Wed, 9 Dec 2020 17:30:09 +0000 Subject: [PATCH 2/6] lxd/network/driver/physical: Adds ipv4.routes.anycast and ipv6.routes.anycast options Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_physical.go | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lxd/network/driver_physical.go b/lxd/network/driver_physical.go index 99a8be7f11..6cf8bd31e1 100644 --- a/lxd/network/driver_physical.go +++ b/lxd/network/driver_physical.go @@ -34,18 +34,20 @@ func (n *physical) DBType() db.NetworkType { // Validate network config. func (n *physical) Validate(config map[string]string) error { rules := map[string]func(value string) error{ - "parent": validate.Required(validate.IsNotEmpty, validInterfaceName), - "mtu": validate.Optional(validate.IsNetworkMTU), - "vlan": validate.Optional(validate.IsNetworkVLAN), - "maas.subnet.ipv4": validate.IsAny, - "maas.subnet.ipv6": validate.IsAny, - "ipv4.gateway": validate.Optional(validate.IsNetworkAddressCIDRV4), - "ipv6.gateway": validate.Optional(validate.IsNetworkAddressCIDRV6), - "ipv4.ovn.ranges": validate.Optional(validate.IsNetworkRangeV4List), - "ipv6.ovn.ranges": validate.Optional(validate.IsNetworkRangeV6List), - "ipv4.routes": validate.Optional(validate.IsNetworkV4List), - "ipv6.routes": validate.Optional(validate.IsNetworkV6List), - "dns.nameservers": validate.Optional(validate.IsNetworkAddressList), + "parent": validate.Required(validate.IsNotEmpty, validInterfaceName), + "mtu": validate.Optional(validate.IsNetworkMTU), + "vlan": validate.Optional(validate.IsNetworkVLAN), + "maas.subnet.ipv4": validate.IsAny, + "maas.subnet.ipv6": validate.IsAny, + "ipv4.gateway": validate.Optional(validate.IsNetworkAddressCIDRV4), + "ipv6.gateway": validate.Optional(validate.IsNetworkAddressCIDRV6), + "ipv4.ovn.ranges": validate.Optional(validate.IsNetworkRangeV4List), + "ipv6.ovn.ranges": validate.Optional(validate.IsNetworkRangeV6List), + "ipv4.routes": validate.Optional(validate.IsNetworkV4List), + "ipv4.routes.anycast": validate.Optional(validate.IsBool), + "ipv6.routes": validate.Optional(validate.IsNetworkV6List), + "ipv6.routes.anycast": validate.Optional(validate.IsBool), + "dns.nameservers": validate.Optional(validate.IsNetworkAddressList), "ovn.ingress_mode": validate.Optional(func(value string) error { return validate.IsOneOf(value, []string{"l2proxy", "routed"}) }), From 7ef94afe314e18d40723b71e73a993aa55884a0a Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Wed, 9 Dec 2020 17:30:35 +0000 Subject: [PATCH 3/6] lxd/network/driver/ovn: Adds uplinkHasIngressRoutedAnycastIPv4 and uplinkHasIngressRoutedAnycastIPv6 functions For centralising the logic to ascertain if routed anycast ingress uplink mode is enabled. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_ovn.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 280482c4ac..2f4a3bfa79 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -2557,3 +2557,13 @@ func (n *ovn) ovnProjectNetworksWithUplink(uplink string, projectNetworks map[st return ovnProjectNetworksWithOurUplink } + +// uplinkHasIngressRoutedAnycastIPv4 returns true if the uplink network has IPv4 routed ingress anycast enabled. +func (n *ovn) uplinkHasIngressRoutedAnycastIPv4(uplink *api.Network) bool { + return shared.IsTrue(uplink.Config["ipv4.routes.anycast"]) && uplink.Config["ovn.ingress_mode"] == "routed" +} + +// uplinkHasIngressRoutedAnycastIPv6 returns true if the uplink network has routed IPv6 ingress anycast enabled. +func (n *ovn) uplinkHasIngressRoutedAnycastIPv6(uplink *api.Network) bool { + return shared.IsTrue(uplink.Config["ipv6.routes.anycast"]) && uplink.Config["ovn.ingress_mode"] == "routed" +} From 525fc9a2380b73f93a76d560c29aec53f250fb52 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Wed, 9 Dec 2020 17:31:17 +0000 Subject: [PATCH 4/6] lxc/network/driver/ovn: Skip overlap detection of networks external subnets when uplink is in anycast routed ingress mode Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_ovn.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 2f4a3bfa79..ece2009f18 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -278,6 +278,10 @@ func (n *ovn) Validate(config map[string]string) error { return err } + // Check if uplink has routed ingress anycast mode enabled, as this relaxes the overlap checks. + ipv4UplinkAnycast := n.uplinkHasIngressRoutedAnycastIPv4(uplink) + ipv6UplinkAnycast := n.uplinkHasIngressRoutedAnycastIPv6(uplink) + for _, externalSubnet := range externalSubnets { // Check the external subnet is allowed within both the uplink's external routes and any // project restricted subnets. @@ -286,6 +290,15 @@ func (n *ovn) Validate(config map[string]string) error { return err } + // Skip overlap checks if external subnet's protocol has anycast mode enabled on uplink. + if externalSubnet.IP.To4() == nil { + if ipv6UplinkAnycast == true { + continue + } + } else if ipv4UplinkAnycast == true { + continue + } + // Check the external subnet doesn't fall within any existing OVN network external subnets. for _, ovnNetworkExternalSubnet := range ovnNetworkExternalSubnets { if SubnetContains(ovnNetworkExternalSubnet, externalSubnet) || SubnetContains(externalSubnet, ovnNetworkExternalSubnet) { From 5543ed07ae21f546db4d73ede1cf601a48c67348 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Wed, 9 Dec 2020 17:31:49 +0000 Subject: [PATCH 5/6] lxd/network/driver/ovn: Skip NIC external route overlap detection when uplink is in anycast routed ingress mode Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_ovn.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index ece2009f18..0c01386158 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -2079,6 +2079,10 @@ func (n *ovn) InstanceDevicePortValidateExternalRoutes(deviceInstance instance.I } } + // Check if uplink has routed ingress anycast mode enabled, as this relaxes the overlap checks. + ipv4UplinkAnycast := n.uplinkHasIngressRoutedAnycastIPv4(uplink) + ipv6UplinkAnycast := n.uplinkHasIngressRoutedAnycastIPv6(uplink) + for _, portExternalRoute := range portExternalRoutes { // Check the external port route is allowed within both the uplink's external routes and any // project restricted subnets. @@ -2087,6 +2091,15 @@ func (n *ovn) InstanceDevicePortValidateExternalRoutes(deviceInstance instance.I return err } + // Skip overlap checks if the external route's protocol has anycast mode enabled on the uplink. + if portExternalRoute.IP.To4() == nil { + if ipv6UplinkAnycast == true { + continue + } + } else if ipv4UplinkAnycast == true { + continue + } + // Check the external port route doesn't fall within any existing OVN network external subnets. for _, ovnNetworkExternalSubnet := range ovnNetworkExternalSubnets { if SubnetContains(ovnNetworkExternalSubnet, portExternalRoute) || SubnetContains(portExternalRoute, ovnNetworkExternalSubnet) { From 2f021596ab4f02ff63209f6dd8c3493e097daed8 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Wed, 9 Dec 2020 17:34:38 +0000 Subject: [PATCH 6/6] api: Adds network_physical_routes_anycast extension Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- doc/api-extensions.md | 6 ++++++ shared/version/api.go | 1 + 2 files changed, 7 insertions(+) diff --git a/doc/api-extensions.md b/doc/api-extensions.md index 92c63f2199..23a8918266 100644 --- a/doc/api-extensions.md +++ b/doc/api-extensions.md @@ -1247,3 +1247,9 @@ Either `l2proxy` (proxy ARP/NDP) or `routed`. Adds `ipv4.dhcp` and `ipv6.dhcp` settings for `ovn` networks. Allows DHCP (and RA for IPv6) to be disabled. Defaults to on. + +## network\_physical\_routes\_anycast +Adds `ipv4.routes.anycast` and `ipv6.routes.anycast` boolean settings for `physical` networks. Defaults to false. + +Allows OVN networks using physical network as uplink to relax external subnet/route overlap detection when used +with `ovn.ingress_mode=routed`. diff --git a/shared/version/api.go b/shared/version/api.go index 2c8b4d2176..1b86bae7a3 100644 --- a/shared/version/api.go +++ b/shared/version/api.go @@ -241,6 +241,7 @@ var APIExtensions = []string{ "resources_disk_address", "network_physical_ovn_ingress_mode", "network_ovn_dhcp", + "network_physical_routes_anycast", } // APIExtensionsCount returns the number of available API extensions.
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel