]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Add forwarder attribute to <dns/> element
authorDiego Woitasen <diego.woitasen@vhgroup.net>
Fri, 13 Sep 2013 16:31:07 +0000 (13:31 -0300)
committerEric Blake <eblake@redhat.com>
Tue, 17 Sep 2013 23:47:33 +0000 (17:47 -0600)
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>
docs/formatnetwork.html.in
docs/schemas/network.rng
src/conf/network_conf.c
src/conf/network_conf.h
src/network/bridge_driver.c
tests/networkxml2confdata/nat-network-dns-forwarders.conf [new file with mode: 0644]
tests/networkxml2confdata/nat-network-dns-forwarders.xml [new file with mode: 0644]
tests/networkxml2conftest.c
tests/networkxml2xmlin/nat-network-dns-forwarders.xml [new file with mode: 0644]
tests/networkxml2xmlout/nat-network-dns-forwarders.xml [new file with mode: 0644]
tests/networkxml2xmltest.c

index 63600b372e67c872cb4fb453a6d47a249ac1b659..3d57ac1a419d5c951d9a9448cba9517a9e673047 100644 (file)
         &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;
 
         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
index d7edb09fc498c5a88ef7171eb87a0ac7889ce384..0e7da89d2ba4ddddb6d71a73bca153a5c678385e 100644 (file)
         <!-- 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 -->
index 654919ecb5aa090c0c394e607963e994316ae10f..6968e25a3476210db7f60d5837cb285e0cb84e6a 100644 (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,
index c28bfaefc35548aadf98426438d2747c7d6b5790..b42598604642965981cfc1a8dd094500b362cbe2 100644 (file)
@@ -122,6 +122,8 @@ struct _virNetworkDNSDef {
     virNetworkDNSHostDefPtr hosts;
     size_t nsrvs;
     virNetworkDNSSrvDefPtr srvs;
+    size_t nfwds;
+    char **forwarders;
 };
 
 typedef struct _virNetworkIpDef virNetworkIpDef;
index 3a8be90f6c76f8fb44d0d5411e65ac8663eb7771..8787bdbcfb2ac15fdef6fc06968441264bf49465 100644 (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"
diff --git a/tests/networkxml2confdata/nat-network-dns-forwarders.conf b/tests/networkxml2confdata/nat-network-dns-forwarders.conf
new file mode 100644 (file)
index 0000000..ebca289
--- /dev/null
@@ -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 (file)
index 0000000..8fab78e
--- /dev/null
@@ -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>
index 5825af3484c3f5ee00f7c4da8ba6088bf5081629..ad50e881bce3a4f7d46310d8f07e33b053ec35de 100644 (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);
diff --git a/tests/networkxml2xmlin/nat-network-dns-forwarders.xml b/tests/networkxml2xmlin/nat-network-dns-forwarders.xml
new file mode 100644 (file)
index 0000000..4d7310d
--- /dev/null
@@ -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>
diff --git a/tests/networkxml2xmlout/nat-network-dns-forwarders.xml b/tests/networkxml2xmlout/nat-network-dns-forwarders.xml
new file mode 100644 (file)
index 0000000..930a42a
--- /dev/null
@@ -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>
index d04039d6340b45fbc7ac05e0ef56ac69d1166597..c4fca0803d821ebac9709bd73584f52da08f0870 100644 (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");