diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index 63600b372e..3d57ac1a41 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" />
+ <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>
@@ -685,6 +687,14 @@
Currently supported sub-elements of <dns>
are:
+ forwarder
+ - A
dns
element can have 0 or
+ more forwarder
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. Since 1.1.3
+
txt
- A
dns
element can have 0 or more txt
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 d7edb09fc4..0e7da89d2b 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -233,15 +233,21 @@
-
-
-
-
- yes
- no
-
-
-
+
+
+
+
+ yes
+ no
+
+
+
+
+
+
+
+
+
@@ -251,13 +257,21 @@
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
@@ -269,24 +283,25 @@
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
- up
- down
-
-
-
-
+
+
+
+
+
+ up
+ down
+
+
+
+
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 654919ecb5..6968e25a34 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 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 element found in 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, "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, "\n",
+ def->forwarders[i]);
+ }
+
for (i = 0; i < def->ntxts; i++) {
virBufferAsprintf(buf, "\n",
def->txts[i].name,
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index c28bfaefc3..b425986046 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 3a8be90f6c..8787bdbcfb 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 0000000000..ebca289575
--- /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 0000000000..8fab78ea3a
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network-dns-forwarders.xml
@@ -0,0 +1,12 @@
+
+ default
+ 81ff0d90-c91e-6742-64da-4a736edb9a9c
+
+
+
+
+
+
+
+
+
diff --git a/tests/networkxml2conftest.c b/tests/networkxml2conftest.c
index 5825af3484..ad50e881bc 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);
diff --git a/tests/networkxml2xmlin/nat-network-dns-forwarders.xml b/tests/networkxml2xmlin/nat-network-dns-forwarders.xml
new file mode 100644
index 0000000000..4d7310d1c6
--- /dev/null
+++ b/tests/networkxml2xmlin/nat-network-dns-forwarders.xml
@@ -0,0 +1,12 @@
+
+ default
+ 81ff0d90-c91e-6742-64da-4a736edb9a9c
+
+
+
+
+
+
+
+
+
diff --git a/tests/networkxml2xmlout/nat-network-dns-forwarders.xml b/tests/networkxml2xmlout/nat-network-dns-forwarders.xml
new file mode 100644
index 0000000000..930a42abc0
--- /dev/null
+++ b/tests/networkxml2xmlout/nat-network-dns-forwarders.xml
@@ -0,0 +1,14 @@
+
+ default
+ 81ff0d90-c91e-6742-64da-4a736edb9a9c
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c
index d04039d634..c4fca0803d 100644
--- a/tests/networkxml2xmltest.c
+++ b/tests/networkxml2xmltest.c
@@ -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");