[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH] network: fix endless loop when starting network with multiple IPs and no dhcp



(From the "How the Hell did I not see this?" files)

commit 9065cfaa added the ability to disable DNS services for a
libvirt virtual network. If neither DNS nor DHCP is needed for a
network, then we don't need to start dnsmasq, so code was added to
check for this.

Unfortunately, it was written with a great lack of attention to detail
(I can say that, because I was the author), and the loop that checked
if DHCP is needed for the network would never end if the network had
multiple IP addresses, and none of them had a <dhcp> section (which
would have contained a <range> or <host> element).

This patch rewrites the check to be more compact and (more
importantly) finite.

This bug was present in release 2.2.0 and 2.3.0, so will need to be
backported to any relevant maintainence branches.

Reported here:
  https://www.redhat.com/archives/libvirt-users/2016-October/msg00032.html
  https://www.redhat.com/archives/libvirt-users/2016-October/msg00045.html
---
 src/network/bridge_driver.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 9d7fc31..a3ee3f3 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -1410,20 +1410,22 @@ networkStartDhcpDaemon(virNetworkDriverStatePtr driver,
     int ret = -1;
     dnsmasqContext *dctx = NULL;
 
-    if (!(ipdef = virNetworkDefGetIPByIndex(network->def, AF_UNSPEC, 0))) {
-        /* no IP addresses, so we don't need to run */
-        ret = 0;
-        goto cleanup;
-    }
-
     /* see if there are any IP addresses that need a dhcp server */
-    for (i = 0; ipdef && !needDnsmasq;
-         ipdef = virNetworkDefGetIPByIndex(network->def, AF_UNSPEC, i + 1)) {
+    i = 0;
+    while ((ipdef = virNetworkDefGetIPByIndex(network->def, AF_UNSPEC, i))) {
+        i++;
         if (ipdef->nranges || ipdef->nhosts)
             needDnsmasq = true;
     }
 
+    if (i == 0) {
+        /* no IP addresses at all, so we don't need to run */
+        ret = 0;
+        goto cleanup;
+    }
+
     if (!needDnsmasq && network->def->dns.enable == VIR_TRISTATE_BOOL_NO) {
+        /* no DHCP services needed, and user disabled DNS service */
         ret = 0;
         goto cleanup;
     }
-- 
2.7.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]