<domain name="example.com"/>
<dns>
<txt name="example" value="example value" />
+ <forwarder addr="8.8.8.8"/>
+ <forwarder 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>
Currently supported sub-elements of <code><dns></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
<!-- 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>
<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>
</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 -->
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]);
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;
}
}
+ 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,
ret = 0;
cleanup:
VIR_FREE(forwardPlainNames);
+ VIR_FREE(fwdNodes);
VIR_FREE(hostNodes);
VIR_FREE(srvNodes);
VIR_FREE(txtNodes);
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;
}
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,
virNetworkDNSHostDefPtr hosts;
size_t nsrvs;
virNetworkDNSSrvDefPtr srvs;
+ size_t nfwds;
+ char **forwarders;
};
typedef struct _virNetworkIpDef virNetworkIpDef;
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"
--- /dev/null
+##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
--- /dev/null
+<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>
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);
--- /dev/null
+<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>
--- /dev/null
+<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>
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");