From 4f595ba61c792267dcd547a0e3c2887ab286e45b Mon Sep 17 00:00:00 2001 From: Laine Stump Date: Tue, 13 Aug 2013 18:56:38 -0400 Subject: [PATCH] network: permit upstream forwarding of unqualified DNS names This resolves the issue that prompted the filing of https://bugzilla.redhat.com/show_bug.cgi?id=928638 (although the request there is for something much larger and more general than this patch). commit f3868259ca0517212e439a65c9060868f673b6c9 disabled the forwarding to upstream DNS servers of unresolved DNS requests for names that had no domain, but were just simple host names (no "." character anywhere in the name). While this behavior is frowned upon by DNS root servers (that's why it was changed in libvirt), it is convenient in some cases, and since dnsmasq can be configured to allow it, it must not be strictly forbidden. This patch restores the old behavior, but since it is usually undesirable, restoring it requires specification of a new option in the network config. Adding the attribute "forwardPlainNames='yes'" to the elemnt does the trick - when that attribute is added to a network config, any simple hostnames that can't be resolved by the network's dnsmasq instance will be forwarded to the DNS servers listed in the host's /etc/resolv.conf for an attempt at resolution (just as any FQDN would be forwarded). When that attribute *isn't* specified, unresolved simple names will *not* be forwarded to the upstream DNS server - this is the default behavior. --- docs/formatnetwork.html.in | 25 ++++++++++++++--- docs/schemas/network.rng | 8 ++++++ src/conf/network_conf.c | 28 +++++++++++++++++-- src/conf/network_conf.h | 1 + src/network/bridge_driver.c | 20 +++++++++---- .../nat-network-dns-forward-plain.conf | 11 ++++++++ .../nat-network-dns-forward-plain.xml | 9 ++++++ .../nat-network-dns-hosts.xml | 2 +- tests/networkxml2conftest.c | 1 + .../nat-network-dns-forward-plain.xml | 9 ++++++ .../nat-network-dns-hosts.xml | 2 +- .../nat-network-dns-forward-plain.xml | 11 ++++++++ tests/networkxml2xmltest.c | 1 + 13 files changed, 114 insertions(+), 14 deletions(-) create mode 100644 tests/networkxml2confdata/nat-network-dns-forward-plain.conf create mode 100644 tests/networkxml2confdata/nat-network-dns-forward-plain.xml create mode 100644 tests/networkxml2xmlin/nat-network-dns-forward-plain.xml create mode 100644 tests/networkxml2xmlout/nat-network-dns-forward-plain.xml diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index eb7c4c722e..e1482db972 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -663,10 +663,27 @@ with the idiosyncrasies of the platform where libvirt is running. Since 0.8.8 -
dns
- The dns element of a network contains configuration information for the - virtual network's DNS server. Since 0.9.3 - Currently supported elements are: +
dns
+
The dns element of a network contains configuration + information for the virtual network's DNS + server Since 0.9.3. + +

+ The dns element + can have an optional forwardPlainNames + attribute Since 1.1.2. + If forwardPlainNames is "no", then DNS resolution + requests for names that are not qualified with a domain + (i.e. names with no "." character) will not be forwarded to + the host's upstream DNS server - they will only be resolved if + they are known locally within the virtual network's own DNS + server. If forwardPlainNames is "yes", + unqualified names will be forwarded to the upstream DNS + server if they can't be resolved by the virtual network's own + DNS server. +

+ + Currently supported sub-elements of <dns> are:
txt
A dns element can have 0 or more txt elements. diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng index ded858092a..ab183f1569 100644 --- a/docs/schemas/network.rng +++ b/docs/schemas/network.rng @@ -208,6 +208,14 @@ and other features in the element --> + + + + yes + no + + + diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 9141bbb2ab..bbc980b693 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -1037,6 +1037,7 @@ virNetworkDNSDefParseXML(const char *networkName, xmlNodePtr *hostNodes = NULL; xmlNodePtr *srvNodes = NULL; xmlNodePtr *txtNodes = NULL; + char *forwardPlainNames = NULL; int nhosts, nsrvs, ntxts; size_t i; int ret = -1; @@ -1044,6 +1045,19 @@ virNetworkDNSDefParseXML(const char *networkName, ctxt->node = node; + forwardPlainNames = virXPathString("string(./@forwardPlainNames)", ctxt); + if (forwardPlainNames) { + if (STREQ(forwardPlainNames, "yes")) { + def->forwardPlainNames = true; + } else if (STRNEQ(forwardPlainNames, "no")) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid dns forwardPlainNames setting '%s' " + "in network '%s'"), + forwardPlainNames, networkName); + goto cleanup; + } + } + nhosts = virXPathNodeSet("./host", ctxt, &hostNodes); if (nhosts < 0) { virReportError(VIR_ERR_XML_ERROR, @@ -1106,6 +1120,7 @@ virNetworkDNSDefParseXML(const char *networkName, ret = 0; cleanup: + VIR_FREE(forwardPlainNames); VIR_FREE(hostNodes); VIR_FREE(srvNodes); VIR_FREE(txtNodes); @@ -2252,10 +2267,19 @@ virNetworkDNSDefFormat(virBufferPtr buf, int result = 0; size_t i, j; - if (!(def->nhosts || def->nsrvs || def->ntxts)) + if (!(def->forwardPlainNames || def->nhosts || def->nsrvs || def->ntxts)) goto out; - virBufferAddLit(buf, "\n"); + virBufferAddLit(buf, "forwardPlainNames) { + virBufferAddLit(buf, " forwardPlainNames='yes'"); + if (!(def->nhosts || def->nsrvs || def->ntxts)) { + virBufferAddLit(buf, "/>\n"); + goto out; + } + } + + virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 2); for (i = 0; i < def->ntxts; i++) { diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index a1d3282db4..920e899ad8 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -115,6 +115,7 @@ struct _virNetworkDNSHostDef { typedef struct _virNetworkDNSDef virNetworkDNSDef; typedef virNetworkDNSDef *virNetworkDNSDefPtr; struct _virNetworkDNSDef { + bool forwardPlainNames; size_t ntxts; virNetworkDNSTxtDefPtr txts; size_t nhosts; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index dd30244772..00f2befcaf 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -678,20 +678,28 @@ networkDnsmasqConfContents(virNetworkObjPtr network, "## virsh net-edit %s\n" "## or other application using the libvirt API.\n" "##\n## dnsmasq conf file created by libvirt\n" - "strict-order\n" - "domain-needed\n", + "strict-order\n", network->def->name); + if (!network->def->dns.forwardPlainNames) + virBufferAddLit(&configbuf, "domain-needed\n"); + if (network->def->domain) { virBufferAsprintf(&configbuf, "domain=%s\n" "expand-hosts\n", network->def->domain); } - /* need to specify local even if no domain specified */ - virBufferAsprintf(&configbuf, - "local=/%s/\n", - network->def->domain ? network->def->domain : ""); + + if (network->def->domain || !network->def->dns.forwardPlainNames) { + /* need to specify local even if no domain specified, unless + * the config says we should forward "plain" names (i.e. not + * fully qualified, no '.' characters) + */ + virBufferAsprintf(&configbuf, + "local=/%s/\n", + network->def->domain ? network->def->domain : ""); + } if (pidfile) virBufferAsprintf(&configbuf, "pid-file=%s\n", pidfile); diff --git a/tests/networkxml2confdata/nat-network-dns-forward-plain.conf b/tests/networkxml2confdata/nat-network-dns-forward-plain.conf new file mode 100644 index 0000000000..9a000b8879 --- /dev/null +++ b/tests/networkxml2confdata/nat-network-dns-forward-plain.conf @@ -0,0 +1,11 @@ +##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE +##OVERWRITTEN AND LOST. Changes to this configuration should be made using: +## virsh net-edit default +## or other application using the libvirt API. +## +## dnsmasq conf file created by libvirt +strict-order +except-interface=lo +bind-dynamic +interface=virbr0 +addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts diff --git a/tests/networkxml2confdata/nat-network-dns-forward-plain.xml b/tests/networkxml2confdata/nat-network-dns-forward-plain.xml new file mode 100644 index 0000000000..10bacb5cbb --- /dev/null +++ b/tests/networkxml2confdata/nat-network-dns-forward-plain.xml @@ -0,0 +1,9 @@ + + default + 81ff0d90-c91e-6742-64da-4a736edb9a9c + + + + + + diff --git a/tests/networkxml2confdata/nat-network-dns-hosts.xml b/tests/networkxml2confdata/nat-network-dns-hosts.xml index 2180a5ddcd..351df4fb57 100644 --- a/tests/networkxml2confdata/nat-network-dns-hosts.xml +++ b/tests/networkxml2confdata/nat-network-dns-hosts.xml @@ -4,7 +4,7 @@ - + host gateway diff --git a/tests/networkxml2conftest.c b/tests/networkxml2conftest.c index b234b306a8..5825af3484 100644 --- a/tests/networkxml2conftest.c +++ b/tests/networkxml2conftest.c @@ -144,6 +144,7 @@ mymain(void) DO_TEST("nat-network-dns-txt-record", full); DO_TEST("nat-network-dns-srv-record", full); DO_TEST("nat-network-dns-hosts", full); + DO_TEST("nat-network-dns-forward-plain", full); DO_TEST("dhcp6-network", dhcpv6); DO_TEST("dhcp6-nat-network", dhcpv6); DO_TEST("dhcp6host-routed-network", dhcpv6); diff --git a/tests/networkxml2xmlin/nat-network-dns-forward-plain.xml b/tests/networkxml2xmlin/nat-network-dns-forward-plain.xml new file mode 100644 index 0000000000..10bacb5cbb --- /dev/null +++ b/tests/networkxml2xmlin/nat-network-dns-forward-plain.xml @@ -0,0 +1,9 @@ + + default + 81ff0d90-c91e-6742-64da-4a736edb9a9c + + + + + + diff --git a/tests/networkxml2xmlin/nat-network-dns-hosts.xml b/tests/networkxml2xmlin/nat-network-dns-hosts.xml index 9a83fed17f..954c9dbc9e 100644 --- a/tests/networkxml2xmlin/nat-network-dns-hosts.xml +++ b/tests/networkxml2xmlin/nat-network-dns-hosts.xml @@ -3,7 +3,7 @@ 81ff0d90-c91e-6742-64da-4a736edb9a9c - + host gateway diff --git a/tests/networkxml2xmlout/nat-network-dns-forward-plain.xml b/tests/networkxml2xmlout/nat-network-dns-forward-plain.xml new file mode 100644 index 0000000000..3b50828ae1 --- /dev/null +++ b/tests/networkxml2xmlout/nat-network-dns-forward-plain.xml @@ -0,0 +1,11 @@ + + default + 81ff0d90-c91e-6742-64da-4a736edb9a9c + + + + + + + + diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c index 0dfed161ac..11b3f02228 100644 --- a/tests/networkxml2xmltest.c +++ b/tests/networkxml2xmltest.c @@ -104,6 +104,7 @@ mymain(void) DO_TEST("netboot-proxy-network"); DO_TEST("nat-network-dns-txt-record"); DO_TEST("nat-network-dns-hosts"); + DO_TEST("nat-network-dns-forward-plain"); DO_TEST("8021Qbh-net"); DO_TEST("direct-net"); DO_TEST("host-bridge-net"); -- 2.39.5