The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8229

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) ===
Allows DHCP/RA to be disabled.


From 19b1f4ea200277bbcb3519e4ec630bee769b7156 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Wed, 9 Dec 2020 13:58:55 +0000
Subject: [PATCH 1/7] lxd/network/openvswitch/ovn: Exports
 LogicalSwitchDHCPOptionsDelete and adds optional UUID filter for deletion

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/network/openvswitch/ovn.go | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/lxd/network/openvswitch/ovn.go b/lxd/network/openvswitch/ovn.go
index 643e6d7047..d7ad3079ee 100644
--- a/lxd/network/openvswitch/ovn.go
+++ b/lxd/network/openvswitch/ovn.go
@@ -325,7 +325,7 @@ func (o *OVN) LogicalSwitchDelete(switchName OVNSwitch) 
error {
                return err
        }
 
-       err = o.logicalSwitchDHCPOptionsDelete(switchName)
+       err = o.LogicalSwitchDHCPOptionsDelete(switchName)
        if err != nil {
                return err
        }
@@ -549,8 +549,9 @@ func (o *OVN) LogicalSwitchDHCPOptionsGet(switchName 
OVNSwitch) ([]OVNDHCPOptsSe
        return dhcpOpts, nil
 }
 
-// logicalSwitchDHCPOptionsDelete deletes any DHCP options defined for a 
switch.
-func (o *OVN) logicalSwitchDHCPOptionsDelete(switchName OVNSwitch) error {
+// LogicalSwitchDHCPOptionsDelete deletes any DHCP options defined for a 
switch.
+// Optionally accepts one or more specific UUID records to delete (if they are 
associated to the specified switch).
+func (o *OVN) LogicalSwitchDHCPOptionsDelete(switchName OVNSwitch, onlyUUID 
...string) error {
        existingOpts, err := o.nbctl("--format=csv", "--no-headings", 
"--data=bare", "--colum=_uuid", "find", "dhcp_options",
                fmt.Sprintf("external_ids:lxd_switch=%s", string(switchName)),
        )
@@ -558,12 +559,28 @@ func (o *OVN) logicalSwitchDHCPOptionsDelete(switchName 
OVNSwitch) error {
                return err
        }
 
+       shouldDelete := func(existingUUID string) bool {
+               if len(onlyUUID) <= 0 {
+                       return true // Delete all records if no UUID filter 
supplied.
+               }
+
+               for _, uuid := range onlyUUID {
+                       if existingUUID == uuid {
+                               return true
+                       }
+               }
+
+               return false
+       }
+
        existingOpts = strings.TrimSpace(existingOpts)
        if existingOpts != "" {
                for _, uuid := range strings.Split(existingOpts, "\n") {
-                       _, err = o.nbctl("destroy", "dhcp_options", uuid)
-                       if err != nil {
-                               return err
+                       if shouldDelete(uuid) {
+                               _, err = o.nbctl("destroy", "dhcp_options", 
uuid)
+                               if err != nil {
+                                       return err
+                               }
                        }
                }
        }

From f893eb22808c247ac88fe0051bc53b91fc66dae8 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Wed, 9 Dec 2020 14:02:45 +0000
Subject: [PATCH 2/7] lxc/network/driver/ovn: Adds ipv4.dhcp and ipv6.dhcp
 boolean settings

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/network/driver_ovn.go | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index dc7668e853..4723a8445f 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -180,6 +180,7 @@ func (n *ovn) Validate(config map[string]string) error {
 
                        return 
validate.Optional(validate.IsNetworkAddressCIDRV4)(value)
                },
+               "ipv4.dhcp": validate.Optional(validate.IsBool),
                "ipv6.address": func(value string) error {
                        if validate.IsOneOf(value, []string{"none", "auto"}) == 
nil {
                                return nil
@@ -187,6 +188,7 @@ func (n *ovn) Validate(config map[string]string) error {
 
                        return 
validate.Optional(validate.IsNetworkAddressCIDRV6)(value)
                },
+               "ipv6.dhcp":          validate.Optional(validate.IsBool),
                "ipv6.dhcp.stateful": validate.Optional(validate.IsBool),
                "ipv4.nat":           validate.Optional(validate.IsBool),
                "ipv6.nat":           validate.Optional(validate.IsBool),

From 9067bf591633532827a2708cccdc3d779f92c7cc Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Wed, 9 Dec 2020 14:08:08 +0000
Subject: [PATCH 3/7] lxc/network/driver/ovn: Modifies setup to only activate
 DHCP/RA if its enabled on network

Also removes old DHCP option records if DHCP is being disabled.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/network/driver_ovn.go | 61 +++++++++++++++++++++++++++------------
 1 file changed, 42 insertions(+), 19 deletions(-)

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index 4723a8445f..d0c35a2a0d 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -1605,6 +1605,8 @@ func (n *ovn) setup(update bool) error {
        }
 
        var dhcpv4UUID, dhcpv6UUID string
+       dhcpV4Subnet := n.DHCPv4Subnet()
+       dhcpV6Subnet := n.DHCPv6Subnet()
 
        if update {
                // Find first existing DHCP options set for IPv4 and IPv6 and 
update them instead of adding sets.
@@ -1613,25 +1615,60 @@ func (n *ovn) setup(update bool) error {
                        return errors.Wrapf(err, "Failed getting existing DHCP 
settings for internal switch")
                }
 
+               var deleteDHCPRecords []string // DHCP option records to delete 
if DHCP is being disabled.
+
                for _, existingOpt := range existingOpts {
                        if existingOpt.CIDR.IP.To4() == nil {
                                if dhcpv6UUID == "" {
                                        dhcpv6UUID = existingOpt.UUID
+
+                                       if dhcpV6Subnet == nil {
+                                               deleteDHCPRecords = 
append(deleteDHCPRecords, dhcpv6UUID)
+                                       }
                                }
                        } else {
                                if dhcpv4UUID == "" {
                                        dhcpv4UUID = existingOpt.UUID
+
+                                       if dhcpV4Subnet == nil {
+                                               deleteDHCPRecords = 
append(deleteDHCPRecords, dhcpv4UUID)
+                                       }
                                }
                        }
                }
+
+               if len(deleteDHCPRecords) > 0 {
+                       err = 
client.LogicalSwitchDHCPOptionsDelete(n.getIntSwitchName(), 
deleteDHCPRecords...)
+                       if err != nil {
+                               return errors.Wrapf(err, "Failed deleting 
existing DHCP settings for internal switch")
+                       }
+               }
        }
 
        // Internal router port IPs (in CIDR format).
        intRouterIPs := []*net.IPNet{}
 
-       // Create DHCPv4 options for internal switch.
        if routerIntPortIPv4Net != nil {
-               err = 
client.LogicalSwitchDHCPv4OptionsSet(n.getIntSwitchName(), dhcpv4UUID, 
routerIntPortIPv4Net, &openvswitch.OVNDHCPv4Opts{
+               intRouterIPs = append(intRouterIPs, &net.IPNet{
+                       IP:   routerIntPortIPv4,
+                       Mask: routerIntPortIPv4Net.Mask,
+               })
+       }
+
+       if routerIntPortIPv6Net != nil {
+               intRouterIPs = append(intRouterIPs, &net.IPNet{
+                       IP:   routerIntPortIPv6,
+                       Mask: routerIntPortIPv6Net.Mask,
+               })
+       }
+
+       if len(intRouterIPs) <= 0 {
+               return fmt.Errorf("No IPs defined for network router")
+       }
+
+       // Create DHCPv4 options for internal switch.
+       if dhcpV4Subnet != nil {
+               err = 
client.LogicalSwitchDHCPv4OptionsSet(n.getIntSwitchName(), dhcpv4UUID, 
dhcpV4Subnet, &openvswitch.OVNDHCPv4Opts{
                        ServerID:           routerIntPortIPv4,
                        ServerMAC:          routerMAC,
                        Router:             routerIntPortIPv4,
@@ -1643,16 +1680,11 @@ func (n *ovn) setup(update bool) error {
                if err != nil {
                        return errors.Wrapf(err, "Failed adding DHCPv4 settings 
for internal switch")
                }
-
-               intRouterIPs = append(intRouterIPs, &net.IPNet{
-                       IP:   routerIntPortIPv4,
-                       Mask: routerIntPortIPv4Net.Mask,
-               })
        }
 
        // Create DHCPv6 options for internal switch.
-       if routerIntPortIPv6Net != nil {
-               err = 
client.LogicalSwitchDHCPv6OptionsSet(n.getIntSwitchName(), dhcpv6UUID, 
routerIntPortIPv6Net, &openvswitch.OVNDHCPv6Opts{
+       if dhcpV6Subnet != nil {
+               err = 
client.LogicalSwitchDHCPv6OptionsSet(n.getIntSwitchName(), dhcpv6UUID, 
dhcpV6Subnet, &openvswitch.OVNDHCPv6Opts{
                        ServerID:           routerMAC,
                        RecursiveDNSServer: uplinkNet.dnsIPv6,
                        DNSSearchList:      n.getDNSSearchList(),
@@ -1660,18 +1692,9 @@ func (n *ovn) setup(update bool) error {
                if err != nil {
                        return errors.Wrapf(err, "Failed adding DHCPv6 settings 
for internal switch")
                }
-
-               intRouterIPs = append(intRouterIPs, &net.IPNet{
-                       IP:   routerIntPortIPv6,
-                       Mask: routerIntPortIPv6Net.Mask,
-               })
        }
 
        // Create internal router port.
-       if len(intRouterIPs) <= 0 {
-               return fmt.Errorf("No IPs defined for network router")
-       }
-
        err = client.LogicalRouterPortAdd(n.getRouterName(), 
n.getRouterIntPortName(), routerMAC, intRouterIPs...)
        if err != nil {
                return errors.Wrapf(err, "Failed adding internal router port")
@@ -1679,7 +1702,7 @@ func (n *ovn) setup(update bool) error {
        revert.Add(func() { 
client.LogicalRouterPortDelete(n.getRouterIntPortName()) })
 
        // Set IPv6 router advertisement settings.
-       if routerIntPortIPv6Net != nil {
+       if dhcpV6Subnet != nil {
                adressMode := openvswitch.OVNIPv6AddressModeSLAAC
                if shared.IsTrue(n.config["ipv6.dhcp.stateful"]) {
                        adressMode = openvswitch.OVNIPv6AddressModeDHCPStateful

From 1ba16cffc87d151eeece2fcacd548f09f8fdddb3 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Wed, 9 Dec 2020 14:08:59 +0000
Subject: [PATCH 4/7] lxd/network/driver/ovn: Updates InstanceDevicePortAdd to
 respect DHCP options on network

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/network/driver_ovn.go | 23 ++++++++---------------
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index d0c35a2a0d..d467867c10 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -2118,26 +2118,19 @@ func (n *ovn) InstanceDevicePortAdd(instanceUUID 
string, instanceName string, de
                return "", errors.Wrapf(err, "Failed to load uplink network 
%q", n.config["network"])
        }
 
-       // Get DHCP options IDs.
-       if validate.IsOneOf(n.getRouterIntPortIPv4Net(), []string{"none", ""}) 
!= nil {
-               _, routerIntPortIPv4Net, err := 
net.ParseCIDR(n.getRouterIntPortIPv4Net())
-               if err != nil {
-                       return "", err
-               }
+       dhcpv4Subnet := n.DHCPv4Subnet()
+       dhcpv6Subnet := n.DHCPv6Subnet()
 
-               dhcpV4ID, err = 
client.LogicalSwitchDHCPOptionsGetID(n.getIntSwitchName(), routerIntPortIPv4Net)
+       // Get DHCP options IDs.
+       if dhcpv4Subnet != nil {
+               dhcpV4ID, err = 
client.LogicalSwitchDHCPOptionsGetID(n.getIntSwitchName(), dhcpv4Subnet)
                if err != nil {
                        return "", err
                }
        }
 
-       if validate.IsOneOf(n.getRouterIntPortIPv6Net(), []string{"none", ""}) 
!= nil {
-               _, routerIntPortIPv6Net, err := 
net.ParseCIDR(n.getRouterIntPortIPv6Net())
-               if err != nil {
-                       return "", err
-               }
-
-               dhcpv6ID, err = 
client.LogicalSwitchDHCPOptionsGetID(n.getIntSwitchName(), routerIntPortIPv6Net)
+       if dhcpv6Subnet != nil {
+               dhcpv6ID, err = 
client.LogicalSwitchDHCPOptionsGetID(n.getIntSwitchName(), dhcpv6Subnet)
                if err != nil {
                        return "", err
                }
@@ -2156,7 +2149,7 @@ func (n *ovn) InstanceDevicePortAdd(instanceUUID string, 
instanceName string, de
                        }
 
                        if !hasIPv6 {
-                               eui64IP, err := 
eui64.ParseMAC(routerIntPortIPv6Net.IP, mac)
+                               eui64IP, err := eui64.ParseMAC(dhcpv6Subnet.IP, 
mac)
                                if err != nil {
                                        return "", errors.Wrapf(err, "Failed 
generating EUI64 for instance port %q", mac.String())
                                }

From 33a6d4d8a6aac553bfbb7bbf15ad450e186fed3b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Wed, 9 Dec 2020 14:09:24 +0000
Subject: [PATCH 5/7] lxd/network/driver/ovn: Updates DHCPv4Subnet and
 DHCPv6Subnet to use IP helper functions

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/network/driver_ovn.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index d467867c10..280482c4ac 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -2411,7 +2411,7 @@ func (n *ovn) DHCPv4Subnet() *net.IPNet {
                return nil
        }
 
-       _, subnet, err := net.ParseCIDR(n.config["ipv4.address"])
+       _, subnet, err := net.ParseCIDR(n.getRouterIntPortIPv4Net())
        if err != nil {
                return nil
        }
@@ -2426,7 +2426,7 @@ func (n *ovn) DHCPv6Subnet() *net.IPNet {
                return nil
        }
 
-       _, subnet, err := net.ParseCIDR(n.config["ipv6.address"])
+       _, subnet, err := net.ParseCIDR(n.getRouterIntPortIPv6Net())
        if err != nil {
                return nil
        }

From 0b8ae947101f75bbd1d7423cbf7e2c8c8707bb21 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Wed, 9 Dec 2020 14:12:14 +0000
Subject: [PATCH 6/7] api: Adds network_ovn_dhcp extension

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 doc/api-extensions.md | 5 +++++
 shared/version/api.go | 1 +
 2 files changed, 6 insertions(+)

diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index c1645d4f86..92c63f2199 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -1242,3 +1242,8 @@ Adds `ovn.ingress_mode` setting for `physical` networks.
 Sets the method that OVN NIC external IPs will be advertised on uplink network.
 
 Either `l2proxy` (proxy ARP/NDP) or `routed`.
+
+## network\_ovn\_dhcp
+Adds `ipv4.dhcp` and `ipv6.dhcp` settings for `ovn` networks.
+
+Allows DHCP (and RA for IPv6) to be disabled. Defaults to on.
diff --git a/shared/version/api.go b/shared/version/api.go
index ee1ee5a6a8..2c8b4d2176 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -240,6 +240,7 @@ var APIExtensions = []string{
        "resources_network_usb",
        "resources_disk_address",
        "network_physical_ovn_ingress_mode",
+       "network_ovn_dhcp",
 }
 
 // APIExtensionsCount returns the number of available API extensions.

From 567f795f599a26b30f5e06e43bc661a0152dbed9 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Wed, 9 Dec 2020 14:13:18 +0000
Subject: [PATCH 7/7] doc/networks: Adds ipv4.dhcp and ipv6.dhcp docs for OVN
 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 cd06506e85..c0ead486b3 100644
--- a/doc/networks.md
+++ b/doc/networks.md
@@ -297,8 +297,10 @@ bridge.mtu                      | integer   | -            
         | 1442
 dns.domain                      | string    | -                     | lxd      
                 | Domain to advertise to DHCP clients and use for DNS 
resolution
 dns.search                      | string    | -                     | -        
                 | Full comma separated domain search list, defaulting to 
`dns.domain` value
 ipv4.address                    | string    | standard mode         | auto (on 
create only)     | IPv4 address for the bridge (CIDR notation). Use "none" to 
turn off IPv4 or "auto" to generate a new random unused subnet
+ipv4.dhcp                       | boolean   | ipv4 address          | true     
                 | Whether to allocate addresses using DHCP
 ipv4.nat                        | boolean   | ipv4 address          | false    
                 | Whether to NAT (will default to true if unset and a random 
ipv4.address is generated)
 ipv6.address                    | string    | standard mode         | auto (on 
create only)     | IPv6 address for the bridge (CIDR notation). Use "none" to 
turn off IPv6 or "auto" to generate a new random unused subnet
+ipv6.dhcp                       | boolean   | ipv6 address          | true     
                 | Whether to provide additional network configuration over DHCP
 ipv6.dhcp.stateful              | boolean   | ipv6 dhcp             | false    
                 | Whether to allocate addresses using DHCP
 ipv6.nat                        | boolean   | ipv6 address          | false    
                 | Whether to NAT (will default to true if unset and a random 
ipv6.address is generated)
 network                         | string    | -                     | -        
                 | Uplink network to use for external network access
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to