Add forwarder attribute to <dns/> element

Useful to set custom forwarders instead of using the contents of
/etc/resolv.conf. It helps me to setup dnsmasq as local nameserver to
resolve VM domain names from domain 0, when domain option is used.

Signed-off-by: Diego Woitasen <diego.woitasen@vhgroup.net>
Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Diego Woitasen 2013-09-13 13:31:07 -03:00 committed by Eric Blake
parent 7ab7c9a2e9
commit 22547b4c98
11 changed files with 160 additions and 32 deletions

View File

@ -631,6 +631,8 @@
&lt;domain name="example.com"/&gt;
&lt;dns&gt;
&lt;txt name="example" value="example value" /&gt;
&lt;forwarder addr="8.8.8.8"/&gt;
&lt;forwarder addr="8.8.4.4"/&gt;
&lt;srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10'/&gt;
&lt;host ip='192.168.122.2'&gt;
&lt;hostname&gt;myhost&lt;/hostname&gt;
@ -685,6 +687,14 @@
Currently supported sub-elements of <code>&lt;dns&gt;</code> are:
<dl>
<dt><code>forwarder</code></dt>
<dd>A <code>dns</code> element can have 0 or
more <code>forwarder</code> elements. Each forwarder
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 1.1.3</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

View File

@ -233,15 +233,21 @@
<!-- Define the DNS related elements like TXT records
and other features in the <dns> element -->
<optional>
<element name="dns">
<optional>
<attribute name="forwardPlainNames">
<choice>
<value>yes</value>
<value>no</value>
</choice>
</attribute>
</optional>
<element name="dns">
<optional>
<attribute name="forwardPlainNames">
<choice>
<value>yes</value>
<value>no</value>
</choice>
</attribute>
</optional>
<interleave>
<zeroOrMore>
<element name="forwarder">
<attribute name="addr"><ref name="ipAddr"/></attribute>
</element>
</zeroOrMore>
<zeroOrMore>
<element name="txt">
<attribute name="name"><ref name="dnsName"/></attribute>
@ -251,13 +257,21 @@
<zeroOrMore>
<element name="srv">
<attribute name="service"><text/></attribute>
<attribute name="protocol"><ref name="protocol"/></attribute>
<attribute name="protocol">
<ref name="protocol"/>
</attribute>
<optional>
<attribute name="domain"><ref name="dnsName"/></attribute>
<attribute name="target"><text/></attribute>
<attribute name="port"><ref name="unsignedShort"/></attribute>
<attribute name="priority"><ref name="unsignedShort"/></attribute>
<attribute name="weight"><ref name="unsignedShort"/></attribute>
<attribute name="port">
<ref name="unsignedShort"/>
</attribute>
<attribute name="priority">
<ref name="unsignedShort"/>
</attribute>
<attribute name="weight">
<ref name="unsignedShort"/>
</attribute>
</optional>
</element>
</zeroOrMore>
@ -269,24 +283,25 @@
</oneOrMore>
</element>
</zeroOrMore>
</element>
</interleave>
</element>
</optional>
<optional>
<ref name="bandwidth"/>
</optional>
<optional>
<optional>
<ref name="bandwidth"/>
</optional>
<optional>
<ref name="vlan"/>
</optional>
<optional>
<element name="link">
<attribute name="state">
<choice>
<value>up</value>
<value>down</value>
</choice>
</attribute>
<empty/>
</element>
</optional>
<optional>
<element name="link">
<attribute name="state">
<choice>
<value>up</value>
<value>down</value>
</choice>
</attribute>
<empty/>
</element>
</optional>
<!-- <ip> element -->

View File

@ -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 nhosts, nsrvs, ntxts, nfwds;
size_t i;
int ret = -1;
xmlNodePtr save = ctxt->node;
@ -1058,6 +1064,30 @@ virNetworkDNSDefParseXML(const char *networkName,
}
}
nfwds = virXPathNodeSet("./forwarder", ctxt, &fwdNodes);
if (nfwds < 0) {
virReportError(VIR_ERR_XML_ERROR,
_("invalid <forwarder> 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, "<forwarder 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,

View File

@ -122,6 +122,8 @@ struct _virNetworkDNSDef {
virNetworkDNSHostDefPtr hosts;
size_t nsrvs;
virNetworkDNSSrvDefPtr srvs;
size_t nfwds;
char **forwarders;
};
typedef struct _virNetworkIpDef virNetworkIpDef;

View File

@ -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"

View File

@ -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

View File

@ -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>
<forwarder addr='8.8.8.8'/>
<forwarder addr='8.8.4.4'/>
</dns>
<ip address='192.168.122.1' netmask='255.255.255.0'>
</ip>
</network>

View File

@ -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);

View File

@ -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>
<forwarder addr='8.8.8.8' />
<forwarder addr='8.8.4.4' />
</dns>
<ip address='192.168.122.1' netmask='255.255.255.0'>
</ip>
</network>

View File

@ -0,0 +1,14 @@
<network>
<name>default</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9c</uuid>
<forward dev='eth0' mode='nat'>
<interface dev='eth0'/>
</forward>
<bridge name='virbr0' stp='on' delay='0'/>
<dns>
<forwarder addr='8.8.8.8'/>
<forwarder addr='8.8.4.4'/>
</dns>
<ip address='192.168.122.1' netmask='255.255.255.0'>
</ip>
</network>

View File

@ -108,6 +108,7 @@ mymain(void)
DO_TEST("nat-network-dns-srv-record-minimal");
DO_TEST("nat-network-dns-hosts");
DO_TEST("nat-network-dns-forward-plain");
DO_TEST("nat-network-dns-forwarders");
DO_TEST("nat-network-forward-nat-address");
DO_TEST("8021Qbh-net");
DO_TEST("direct-net");