Useful to set custom forwarders instead of using the contents of /etc/resolv.conf. It helps me to setup dnsmasq as local nameserver to resolv VM domain names from domain 0, when domain option is used. Signed-off-by: Diego Woitasen <diego.woitasen@xxxxxxxxxxx> --- docs/formatnetwork.html.in | 8 ++++ docs/schemas/network.rng | 5 +++ src/conf/network_conf.c | 43 ++++++++++++++++++++-- src/conf/network_conf.h | 2 + src/network/bridge_driver.c | 8 ++++ .../nat-network-dns-forwarders.conf | 16 ++++++++ .../nat-network-dns-forwarders.xml | 12 ++++++ tests/networkxml2conftest.c | 1 + 8 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 tests/networkxml2confdata/nat-network-dns-forwarders.conf create mode 100644 tests/networkxml2confdata/nat-network-dns-forwarders.xml diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index e1482db..4dd809a 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -631,6 +631,8 @@ <domain name="example.com"/> <dns> <txt name="example" value="example value" /> + <forwarders addr="8.8.8.8" /> + <forwarders addr="8.8.4.4" /> <srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10'/> <host ip='192.168.122.2'> <hostname>myhost</hostname> @@ -685,6 +687,12 @@ Currently supported sub-elements of <code><dns></code> are: <dl> + <dt><code>forwarders</code></dt> + <dd>A <code>dns</code> element can have 0 or more <code>forwarders</code> elements. + Each forwarders element defines an IP address to be used as forwarder + in DNS server configuration. The addr attribute is required and defines the + IP address of every forwarder. <span class="since">Since N/A</span> + </dd> <dt><code>txt</code></dt> <dd>A <code>dns</code> element can have 0 or more <code>txt</code> elements. Each txt element defines a DNS TXT record and has two attributes, both diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng index ab183f1..e0c2b51 100644 --- a/docs/schemas/network.rng +++ b/docs/schemas/network.rng @@ -217,6 +217,11 @@ </attribute> </optional> <zeroOrMore> + <element name="forwarders"> + <attribute name="addr"><ref name="ipAddr"/></attribute> + </element> + </zeroOrMore> + <zeroOrMore> <element name="txt"> <attribute name="name"><ref name="dnsName"/></attribute> <attribute name="value"><text/></attribute> diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index d54f2aa..1c1aa64 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -175,6 +175,11 @@ virNetworkDNSSrvDefClear(virNetworkDNSSrvDefPtr def) static void virNetworkDNSDefClear(virNetworkDNSDefPtr def) { + if (def->forwarders) { + while (def->nfwds) + VIR_FREE(def->forwarders[--def->nfwds]); + VIR_FREE(def->forwarders); + } if (def->txts) { while (def->ntxts) virNetworkDNSTxtDefClear(&def->txts[--def->ntxts]); @@ -1037,8 +1042,9 @@ virNetworkDNSDefParseXML(const char *networkName, xmlNodePtr *hostNodes = NULL; xmlNodePtr *srvNodes = NULL; xmlNodePtr *txtNodes = NULL; + xmlNodePtr *fwdNodes = NULL; char *forwardPlainNames = NULL; - int nhosts, nsrvs, ntxts; + int nfwds, nhosts, nsrvs, ntxts; size_t i; int ret = -1; xmlNodePtr save = ctxt->node; @@ -1058,6 +1064,30 @@ virNetworkDNSDefParseXML(const char *networkName, } } + nfwds = virXPathNodeSet("./forwarders", ctxt, &fwdNodes); + if (nfwds < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("invalid <forwarders> element found in <dns> of network %s"), + networkName); + goto cleanup; + } + if (nfwds > 0) { + if (VIR_ALLOC_N(def->forwarders, nfwds) < 0) + goto cleanup; + + for (i = 0; i < nfwds; i++) { + def->forwarders[i] = virXMLPropString(fwdNodes[i], "addr"); + if (virSocketAddrParse(NULL, def->forwarders[i], AF_UNSPEC) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid forwarder IP address '%s' " + "in network '%s'"), + def->forwarders[i], networkName); + goto cleanup; + } + def->nfwds++; + } + } + nhosts = virXPathNodeSet("./host", ctxt, &hostNodes); if (nhosts < 0) { virReportError(VIR_ERR_XML_ERROR, @@ -1121,6 +1151,7 @@ virNetworkDNSDefParseXML(const char *networkName, ret = 0; cleanup: VIR_FREE(forwardPlainNames); + VIR_FREE(fwdNodes); VIR_FREE(hostNodes); VIR_FREE(srvNodes); VIR_FREE(txtNodes); @@ -2267,13 +2298,14 @@ virNetworkDNSDefFormat(virBufferPtr buf, int result = 0; size_t i, j; - if (!(def->forwardPlainNames || def->nhosts || def->nsrvs || def->ntxts)) + if (!(def->forwardPlainNames || def->forwarders || def->nhosts || + def->nsrvs || def->ntxts)) goto out; virBufferAddLit(buf, "<dns"); if (def->forwardPlainNames) { virBufferAddLit(buf, " forwardPlainNames='yes'"); - if (!(def->nhosts || def->nsrvs || def->ntxts)) { + if (!(def->forwarders || def->nhosts || def->nsrvs || def->ntxts)) { virBufferAddLit(buf, "/>\n"); goto out; } @@ -2282,6 +2314,11 @@ virNetworkDNSDefFormat(virBufferPtr buf, virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 2); + for (i = 0; i < def->nfwds; i++) { + virBufferAsprintf(buf, "<forwarders addr='%s' />\n", + def->forwarders[i]); + } + for (i = 0; i < def->ntxts; i++) { virBufferAsprintf(buf, "<txt name='%s' value='%s'/>\n", def->txts[i].name, diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index c28bfae..b425986 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -122,6 +122,8 @@ struct _virNetworkDNSDef { virNetworkDNSHostDefPtr hosts; size_t nsrvs; virNetworkDNSSrvDefPtr srvs; + size_t nfwds; + char **forwarders; }; typedef struct _virNetworkIpDef virNetworkIpDef; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 3a8be90..a2cfb35 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -708,6 +708,14 @@ networkDnsmasqConfContents(virNetworkObjPtr network, if (!network->def->dns.forwardPlainNames) virBufferAddLit(&configbuf, "domain-needed\n"); + if (network->def->dns.forwarders) { + virBufferAddLit(&configbuf, "no-resolv\n"); + for (i=0; i < network->def->dns.nfwds; i++) { + virBufferAsprintf(&configbuf, "server=%s\n", + network->def->dns.forwarders[i]); + } + } + if (network->def->domain) { virBufferAsprintf(&configbuf, "domain=%s\n" diff --git a/tests/networkxml2confdata/nat-network-dns-forwarders.conf b/tests/networkxml2confdata/nat-network-dns-forwarders.conf new file mode 100644 index 0000000..ebca289 --- /dev/null +++ b/tests/networkxml2confdata/nat-network-dns-forwarders.conf @@ -0,0 +1,16 @@ +##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 +domain-needed +no-resolv +server=8.8.8.8 +server=8.8.4.4 +local=// +except-interface=lo +bind-dynamic +interface=virbr0 +addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts diff --git a/tests/networkxml2confdata/nat-network-dns-forwarders.xml b/tests/networkxml2confdata/nat-network-dns-forwarders.xml new file mode 100644 index 0000000..9cd2667 --- /dev/null +++ b/tests/networkxml2confdata/nat-network-dns-forwarders.xml @@ -0,0 +1,12 @@ +<network> + <name>default</name> + <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9c</uuid> + <forward dev='eth0' mode='nat'/> + <bridge name='virbr0' stp='on' delay='0' /> + <dns> + <forwarders addr='8.8.8.8' /> + <forwarders addr='8.8.4.4' /> + </dns> + <ip address='192.168.122.1' netmask='255.255.255.0'> + </ip> +</network> diff --git a/tests/networkxml2conftest.c b/tests/networkxml2conftest.c index 5825af3..ad50e88 100644 --- a/tests/networkxml2conftest.c +++ b/tests/networkxml2conftest.c @@ -145,6 +145,7 @@ mymain(void) 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("nat-network-dns-forwarders", full); DO_TEST("dhcp6-network", dhcpv6); DO_TEST("dhcp6-nat-network", dhcpv6); DO_TEST("dhcp6host-routed-network", dhcpv6); -- 1.8.1.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list