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

Reply via email to