From 06f5c46e5d25fa1306078e8a4aa40c5681f54f52 Mon Sep 17 00:00:00 2001 From: Laine Stump Date: Fri, 28 Oct 2016 11:43:56 -0400 Subject: [PATCH] network: fix endless loop when starting network with multiple IPs and no dhcp 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 the first had no subelement (which would have contained a or subelement, thus requiring DHCP services). 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 (cherry picked from commit bbb333e4813ebe74580e75b0e8c2eb325e3d11ca) --- 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 7b99acafa8..3cf349e468 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -1408,20 +1408,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; }