[PATCH 2/7] network: add configurable network autoaddr items to driver config

Laine Stump posted 7 patches 3 months, 2 weeks ago
[PATCH 2/7] network: add configurable network autoaddr items to driver config
Posted by Laine Stump 3 months, 2 weeks ago
These options are added to network.conf and virNetworkDriverConfig object:

autoaddr_start - start of the range of subnets to search (def: "192.168.122.0")
autoaddr_end - end of the range of subnets (def: "192.168.255.0")
autoaddr_prefix - prefix of these subnets (def: 24)

They will be used by the network driver when looking for unused
subnets to assign to networks that have "autoaddr='yes'" in one of
their <ip> elements.

Signed-off-by: Laine Stump <laine@redhat.com>
---
 meson.build                              | 14 +++++-
 meson_options.txt                        |  4 ++
 src/network/bridge_driver_conf.c         | 61 ++++++++++++++++++++++++
 src/network/bridge_driver_conf.h         |  4 ++
 src/network/libvirtd_network.aug         |  8 +++-
 src/network/meson.build                  |  6 +++
 src/network/network.conf.in              | 11 +++++
 src/network/test_libvirtd_network.aug.in |  3 ++
 8 files changed, 109 insertions(+), 2 deletions(-)

diff --git a/meson.build b/meson.build
index 06d88ad1f3..71da7db741 100644
--- a/meson.build
+++ b/meson.build
@@ -1646,6 +1646,15 @@ endif
 if not get_option('driver_network').disabled() and conf.has('WITH_LIBVIRTD')
   conf.set('WITH_NETWORK', 1)
 
+  autoaddr_start = get_option('autoaddr_start')
+  conf.set_quoted('AUTOADDR_START', autoaddr_start)
+
+  autoaddr_end = get_option('autoaddr_end')
+  conf.set_quoted('AUTOADDR_END', autoaddr_end)
+
+  autoaddr_prefix = get_option('autoaddr_prefix')
+  conf.set('AUTOADDR_PREFIX', autoaddr_prefix)
+
   firewall_backend_priority = get_option('firewall_backend_priority')
   if firewall_backend_priority.length() == 0
       if host_machine.system() == 'linux'
@@ -2406,7 +2415,10 @@ misc_summary = {
 }
 if conf.has('WITH_NETWORK')
   misc_summary += {
-    'firewall backends': firewall_backend_priority,
+  'autoaddr_start': autoaddr_start,
+  'autoaddr_end': autoaddr_end,
+  'autoaddr_prefix': autoaddr_prefix,
+  'firewall backends': firewall_backend_priority,
   }
 endif
 summary(misc_summary, section: 'Miscellaneous', bool_yn: true, list_sep: ' ')
diff --git a/meson_options.txt b/meson_options.txt
index 2d440c63d8..7a1a86211e 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -118,6 +118,10 @@ option('firewalld', type: 'feature', value: 'auto', description: 'firewalld supp
 # dep:firewalld
 option('firewalld_zone', type: 'feature', value: 'auto', description: 'whether to install firewalld libvirt zone')
 option('firewall_backend_priority', type: 'array', choices: ['nftables', 'iptables'], value: [], description: 'order in which to try firewall backends')
+option('autoaddr_start', type: 'string', value: '192.168.122.0', description: 'Start of range of IPv4 subnets to choose an unused subnet from')
+option('autoaddr_end', type: 'string', value: '192.168.255.0', description: 'End of range of IPv4 subnets to choose an unused subnet from')
+option('autoaddr_prefix', type: 'integer', value: 24, description: 'prefix of IPv4 subnets to choose an unused subnet from')
+
 option('host_validate', type: 'feature', value: 'auto', description: 'build virt-host-validate')
 option('init_script', type: 'combo', choices: ['systemd', 'openrc', 'check', 'none'], value: 'check', description: 'Style of init script to install')
 option('loader_nvram', type: 'string', value: '', description: 'Pass list of pairs of <loader>:<nvram> paths. Both pairs and list items are separated by a colon.')
diff --git a/src/network/bridge_driver_conf.c b/src/network/bridge_driver_conf.c
index 9da5e790b7..cb2915550f 100644
--- a/src/network/bridge_driver_conf.c
+++ b/src/network/bridge_driver_conf.c
@@ -65,6 +65,13 @@ virNetworkLoadDriverConfig(virNetworkDriverConfig *cfg G_GNUC_UNUSED,
                            const char *filename)
 {
     g_autoptr(virConf) conf = NULL;
+
+    const char *autoaddrStart = "192.168.122.0";
+    const char *autoaddrEnd = "192.168.255.0";
+    unsigned int autoaddrPrefix = 24;
+    g_autofree char *autoaddrStartFromConf = NULL;
+    g_autofree char *autoaddrEndFromConf = NULL;
+
     g_autofree char *fwBackendStr = NULL;
     bool fwBackendSelected = false;
     size_t i;
@@ -88,6 +95,36 @@ virNetworkLoadDriverConfig(virNetworkDriverConfig *cfg G_GNUC_UNUSED,
 
         /* use virConfGetValue*(conf, ...) functions to read any settings into cfg */
 
+        if (virConfGetValueString(conf, "autoaddr_start", &autoaddrStartFromConf) < 0)
+            return -1;
+        if (autoaddrStartFromConf) {
+            VIR_DEBUG("autoaddr_start setting requested from config file %s: '%s'",
+                      filename, autoaddrStartFromConf);
+            autoaddrStart = autoaddrStartFromConf;
+        }
+
+        if (virConfGetValueString(conf, "autoaddr_end", &autoaddrEndFromConf) < 0)
+            return -1;
+        if (autoaddrEndFromConf) {
+            VIR_DEBUG("autoaddr_end setting requested from config file %s: '%s'",
+                      filename, autoaddrEndFromConf);
+            autoaddrEnd = autoaddrEndFromConf;
+        }
+
+        switch (virConfGetValueUInt(conf, "autoaddr_prefix", &autoaddrPrefix)) {
+        case 1:
+            VIR_DEBUG("autoaddr_prefix setting requested from config file %s: '%u'",
+                      filename, autoaddrPrefix);
+            break;
+
+        case 0:
+            break;
+
+        case -1:
+        default:
+            return -1;
+        }
+
         if (virConfGetValueString(conf, "firewall_backend", &fwBackendStr) < 0)
             return -1;
 
@@ -106,6 +143,30 @@ virNetworkLoadDriverConfig(virNetworkDriverConfig *cfg G_GNUC_UNUSED,
         }
     }
 
+    if (virSocketAddrParse(&cfg->autoaddrStart, autoaddrStart, AF_INET) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("invalid autoaddr_start '%1$s' in network driver config file %2$s, must be numeric IPv4 network address"),
+                       autoaddrStart, filename);
+        return -1;
+    }
+
+    if (virSocketAddrParse(&cfg->autoaddrEnd, autoaddrEnd, AF_INET) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("invalid autoaddr_end '%1$s' in network driver config file %2$s, must be numeric IPv4 network address"),
+                       autoaddrStart, filename);
+        return -1;
+    }
+
+    if ((cfg->autoaddrPrefix = autoaddrPrefix) > 32) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Invalid IPv4 prefix '%1$u' in network driver config file %2$s"),
+                       autoaddrPrefix, filename);
+        return -1;
+    }
+
+    VIR_INFO("autoaddr_start='%s' autoaddr_end='%s' autoaddr_prefix='%u'",
+             autoaddrStart, autoaddrEnd, autoaddrPrefix);
+
     for (i = 0; i < nFwBackends && !fwBackendSelected; i++) {
 
         switch ((virFirewallBackend)fwBackends[i]) {
diff --git a/src/network/bridge_driver_conf.h b/src/network/bridge_driver_conf.h
index 8f221f391e..7ebf77037d 100644
--- a/src/network/bridge_driver_conf.h
+++ b/src/network/bridge_driver_conf.h
@@ -39,6 +39,10 @@ struct _virNetworkDriverConfig {
     char *pidDir;
     char *dnsmasqStateDir;
 
+    virSocketAddr autoaddrStart;
+    virSocketAddr autoaddrEnd;
+    unsigned int autoaddrPrefix;
+
     virFirewallBackend firewallBackend;
 };
 
diff --git a/src/network/libvirtd_network.aug b/src/network/libvirtd_network.aug
index 5d6d72dd92..5212505e1f 100644
--- a/src/network/libvirtd_network.aug
+++ b/src/network/libvirtd_network.aug
@@ -22,10 +22,16 @@ module Libvirtd_network =
    let int_entry       (kw:string) = [ key kw . value_sep . int_val ]
    let str_array_entry (kw:string) = [ key kw . value_sep . str_array_val ]
 
+   let autoaddr_entry = str_entry "autoaddr_start"
+                      | str_entry "autoaddr_end"
+                      | int_entry "autoaddr_prefix"
+
    let firewall_backend_entry = str_entry "firewall_backend"
 
    (* Each entry in the config is one of the following *)
-   let entry = firewall_backend_entry
+   let entry = autoaddr_entry
+             | firewall_backend_entry
+
    let comment = [ label "#comment" . del /#[ \t]*/ "# " .  store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
    let empty = [ label "#empty" . eol ]
 
diff --git a/src/network/meson.build b/src/network/meson.build
index 07cd5cda55..8faff6eb1c 100644
--- a/src/network/meson.build
+++ b/src/network/meson.build
@@ -51,6 +51,9 @@ if conf.has('WITH_NETWORK')
   }
 
   network_options_conf = configuration_data({
+    'AUTOADDR_START': autoaddr_start,
+    'AUTOADDR_END': autoaddr_end,
+    'AUTOADDR_PREFIX': autoaddr_prefix,
     'FIREWALL_BACKEND_PRIORITY': ', '.join(firewall_backend_priority),
     'FIREWALL_BACKEND': firewall_backend_priority[0],
   })
@@ -62,6 +65,9 @@ if conf.has('WITH_NETWORK')
   )
 
   network_options_hack_conf = configuration_data({
+    'AUTOADDR_START': autoaddr_start,
+    'AUTOADDR_END': autoaddr_end,
+    'AUTOADDR_PREFIX': autoaddr_prefix,
     'FIREWALL_BACKEND_PRIORITY': ', '.join(firewall_backend_priority),
     'FIREWALL_BACKEND': firewall_backend_priority[0],
     # This hack is necessary because the output file is going to be
diff --git a/src/network/network.conf.in b/src/network/network.conf.in
index 5ed64a04a5..83a27df04c 100644
--- a/src/network/network.conf.in
+++ b/src/network/network.conf.in
@@ -27,3 +27,14 @@
 #   reloaded using the new backend.)
 #
 #firewall_backend = "@FIREWALL_BACKEND@"
+#
+# autoaddr_start
+# autoaddr_end
+# autoaddr_prefix
+#
+#   These three setting specify the range of subnets that should be used
+#   for networks that have "autoaddr='yes'"
+#
+#autoaddr_start = "@AUTOADDR_START@"
+#autoaddr_end = "@AUTOADDR_END@"
+#autoaddr_prefix = @AUTOADDR_PREFIX@
diff --git a/src/network/test_libvirtd_network.aug.in b/src/network/test_libvirtd_network.aug.in
index 9e29a9192f..6edcbaed62 100644
--- a/src/network/test_libvirtd_network.aug.in
+++ b/src/network/test_libvirtd_network.aug.in
@@ -3,3 +3,6 @@ module Test_libvirtd_network =
 
   test Libvirtd_network.lns get conf =
 { "firewall_backend" = "@FIREWALL_BACKEND@" }
+{ "autoaddr_start" = "@AUTOADDR_START@" }
+{ "autoaddr_end" = "@AUTOADDR_END@" }
+{ "autoaddr_prefix" = "@AUTOADDR_PREFIX@" }
-- 
2.45.2
Re: [PATCH 2/7] network: add configurable network autoaddr items to driver config
Posted by Daniel P. Berrangé 3 months, 2 weeks ago
On Wed, Aug 07, 2024 at 01:15:58PM -0400, Laine Stump wrote:
> These options are added to network.conf and virNetworkDriverConfig object:
> 
> autoaddr_start - start of the range of subnets to search (def: "192.168.122.0")
> autoaddr_end - end of the range of subnets (def: "192.168.255.0")
> autoaddr_prefix - prefix of these subnets (def: 24)

So I guess $prefix here is telling us that we need to iterate over
the octet at the end of $prefix. ie the 3rd digit in these examples.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
Re: [PATCH 2/7] network: add configurable network autoaddr items to driver config
Posted by Laine Stump 3 months, 2 weeks ago
On 8/7/24 1:41 PM, Daniel P. Berrangé wrote:
> On Wed, Aug 07, 2024 at 01:15:58PM -0400, Laine Stump wrote:
>> These options are added to network.conf and virNetworkDriverConfig object:
>>
>> autoaddr_start - start of the range of subnets to search (def: "192.168.122.0")
>> autoaddr_end - end of the range of subnets (def: "192.168.255.0")
>> autoaddr_prefix - prefix of these subnets (def: 24)
> 
> So I guess $prefix here is telling us that we need to iterate over
> the octet at the end of $prefix. ie the 3rd digit in these examples.

The code isn't really thinking of it as octets at all, just 32 bits, and 
the prefix is telling how many of those bits are the network part of the 
address; it just increments the network part by 1 each time (by shifting 
right $prefix-32 bits, incrementing by 1, then shifting left $prefix-32 
bits).
Re: [PATCH 2/7] network: add configurable network autoaddr items to driver config
Posted by Daniel P. Berrangé 3 months, 1 week ago
On Wed, Aug 07, 2024 at 02:00:24PM -0400, Laine Stump wrote:
> On 8/7/24 1:41 PM, Daniel P. Berrangé wrote:
> > On Wed, Aug 07, 2024 at 01:15:58PM -0400, Laine Stump wrote:
> > > These options are added to network.conf and virNetworkDriverConfig object:
> > > 
> > > autoaddr_start - start of the range of subnets to search (def: "192.168.122.0")
> > > autoaddr_end - end of the range of subnets (def: "192.168.255.0")
> > > autoaddr_prefix - prefix of these subnets (def: 24)
> > 
> > So I guess $prefix here is telling us that we need to iterate over
> > the octet at the end of $prefix. ie the 3rd digit in these examples.
> 
> The code isn't really thinking of it as octets at all, just 32 bits, and the
> prefix is telling how many of those bits are the network part of the
> address; it just increments the network part by 1 each time (by shifting
> right $prefix-32 bits, incrementing by 1, then shifting left $prefix-32
> bits).

Ok, I guess that makes sense.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|