[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH] Add forwarders 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 resolv VM
domain names from domain 0, when domain option is used.

Signed-off-by: Diego Woitasen <diego woitasen vhgroup net>
---
 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 @@
         &lt;domain name="example.com"/&gt;
         &lt;dns&gt;
           &lt;txt name="example" value="example value" /&gt;
+          &lt;forwarders addr="8.8.8.8" /&gt;
+          &lt;forwarders 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,12 @@
 
         Currently supported sub-elements of <code>&lt;dns&gt;</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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]