[libvirt] [PATCH v2 1/5] Network: Add TXT record support for virtual DNS service

Michal Novotny minovotn at redhat.com
Fri Apr 1 10:45:52 UTC 2011


Make: passed
Make check: passed
Make syntax-check: passed

Hi,
this is the patch to add support for adding TXT records to the
DNS service running on the virtual network. This has been tested
on Fedora-14 i386 box and tests are also added to RelaxNG schema
and test XML files.

Since spaces are not allowed for the TXT records in DNS they
are rejected and "TXT records in DNS doesn't support spaces"
error message is being output to the user.

It's been tested and checked/syntax-checked and everything was
working fine.

Also, the formatnetwork HTML document has been altered to
include those information about new DNS tag.

Michal

Signed-off-by: Michal Novotny <minovotn at redhat.com>
---
 docs/formatnetwork.html.in                         |   24 ++++++-
 docs/schemas/network.rng                           |   12 +++
 src/conf/network_conf.c                            |   71 ++++++++++++++++++++
 src/conf/network_conf.h                            |   16 +++++
 src/network/bridge_driver.c                        |   15 ++++-
 .../nat-network-dns-txt-record.xml                 |   24 +++++++
 .../nat-network-dns-txt-record.xml                 |   24 +++++++
 tests/networkxml2xmltest.c                         |    1 +
 8 files changed, 185 insertions(+), 2 deletions(-)
 create mode 100644 tests/networkxml2xmlin/nat-network-dns-txt-record.xml
 create mode 100644 tests/networkxml2xmlout/nat-network-dns-txt-record.xml

diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index c6969eb..5211ed2 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -108,7 +108,10 @@
       The final set of elements define the addresses (IPv4 and/or
       IPv6, as well as MAC) to be assigned to the bridge device
       associated with the virtual network, and optionally enable DHCP
-      services.
+      services. The network creation also supports the TXT record in
+      the DNS to expose some information to the guest using this
+      record. This feature could be used in the similar way like DKIM
+      uses TXT records of DNS to expose public key.
     </p>
 
     <pre>
@@ -120,6 +123,9 @@
             <host mac="00:16:3e:77:e2:ed" name="foo.example.com" ip="192.168.122.10" />
             <host mac="00:16:3e:3e:a9:1a" name="bar.example.com" ip="192.168.122.11" />
           </dhcp>
+          <dns>
+            <txt-record name="example" value="example value" />
+          </dns>
         </ip>
       </network></pre>
 
@@ -199,6 +205,22 @@
         element is used.  The BOOTP options currently have to be the same
         for all address ranges and statically assigned addresses.<span
         class="since">Since 0.7.1 (<code>server</code> since 0.7.3).</span>
+      </dd><dt><code>dns</code></dt><dd>Also within the <code>ip</code> element
+        there is an optional <code>dns</code> element. The presence of this element
+        enables configuration and exposal of records in the DNS service on the
+        virtual network. It will further contain one or more <code>txt-record</code>
+        elements. The <code>dns</code> element is supported for both IPv4 and IPv6
+        networks. <span class="since">Since 0.9.1</span>
+      </dd>
+      <dt><code>txt-record</code></dt>
+      <dd>The <code>txt-record</code> element is the definition of TXT record for the
+        DNS service. There are two attributes that both have to be used for the TXT
+        record definition: <code>name</code> and <code>value</code>. The <code>name
+        </code>attribute doesn't support commas in it's value so the names with commas
+        will be rejected. This applies only to names of the TXT record and not values
+        since values (i.e. <code>value</code> contents) supports multiple values
+        separated by commas.
+        <span class="since">Since 0.9.1</span>
       </dd>
     </dl>
 
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 6d01b06..e27dace 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -136,6 +136,18 @@
                 </optional>
               </element>
             </optional>
+            <optional>
+              <!-- Define the DNS related elements like TXT records
+                   and other features -->
+              <element name="dns">
+                <zeroOrMore>
+                  <element name="txt-record">
+                    <attribute name="name"><text/></attribute>
+                    <attribute name="value"><text/></attribute>
+                  </element>
+                </zeroOrMore>
+              </element>
+            </optional>
           </element>
         </zeroOrMore>
       </interleave>
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index dcab9de..b7427d0 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -435,6 +435,60 @@ virNetworkDHCPRangeDefParseXML(const char *networkName,
 }
 
 static int
+virNetworkDNSDefParseXML(virNetworkIpDefPtr def,
+                         xmlNodePtr node)
+{
+
+    xmlNodePtr cur;
+    int result = -1;
+
+    if (VIR_ALLOC(def->dns))
+        goto oom_error;
+
+    cur = node->children;
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE &&
+            xmlStrEqual(cur->name, BAD_CAST "txt-record")) {
+            char *name, *value;
+
+            if (!(name = virXMLPropString(cur, "name"))) {
+                cur = cur->next;
+                continue;
+            }
+            if (!(value = virXMLPropString(cur, "value"))) {
+                VIR_FREE(name);
+                cur = cur->next;
+                continue;
+            }
+
+            if (strchr(name, ' ') != NULL) {
+                virNetworkReportError(VIR_ERR_XML_DETAIL,
+                                      _("TXT record names in DNS doesn't support spaces"));
+                return -1;
+            }
+
+            if (VIR_REALLOC_N(def->dns->txtrecords, def->dns->ntxtrecords + 1) < 0)
+                goto oom_error;
+
+            def->dns->txtrecords[def->dns->ntxtrecords].name = strdup(name);
+            def->dns->txtrecords[def->dns->ntxtrecords].value = strdup(value);
+            def->dns->ntxtrecords++;
+
+            VIR_FREE(name);
+            VIR_FREE(value);
+        }
+
+        cur = cur->next;
+    }
+
+    return 0;
+
+oom_error:
+    virReportOOMError();
+    return result;
+}
+
+static int
 virNetworkIPParseXML(const char *networkName,
                      virNetworkIpDefPtr def,
                      xmlNodePtr node,
@@ -550,6 +604,12 @@ virNetworkIPParseXML(const char *networkName,
                     goto error;
 
             } else if (cur->type == XML_ELEMENT_NODE &&
+                       xmlStrEqual(cur->name, BAD_CAST "dns")) {
+                result = virNetworkDNSDefParseXML(def, cur);
+                if (result)
+                    goto error;
+
+            } else if (cur->type == XML_ELEMENT_NODE &&
                        xmlStrEqual(cur->name, BAD_CAST "tftp")) {
                 char *root;
 
@@ -828,6 +888,17 @@ virNetworkIpDefFormat(virBufferPtr buf,
 
         virBufferAddLit(buf, "    </dhcp>\n");
     }
+    if ((def->dns != NULL) && (def->dns->ntxtrecords)) {
+        int ii;
+
+        virBufferAddLit(buf, "    <dns>\n");
+        for (ii = 0 ; ii < def->dns->ntxtrecords ; ii++) {
+            virBufferVSprintf(buf, "      <txt-record name='%s' value='%s' />\n",
+                              def->dns->txtrecords[ii].name,
+                              def->dns->txtrecords[ii].value);
+        }
+        virBufferAddLit(buf, "    </dns>\n");
+    }
 
     virBufferAddLit(buf, "  </ip>\n");
 
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 281124b..5f47595 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -57,6 +57,20 @@ struct _virNetworkDHCPHostDef {
     virSocketAddr ip;
 };
 
+typedef struct _virNetworkDNSTxtRecordsDef virNetworkDNSTxtRecordsDef;
+typedef virNetworkDNSTxtRecordsDef *virNetworkDNSTxtRecordsDefPtr;
+struct _virNetworkDNSTxtRecordsDef {
+    char *name;
+    char *value;
+};
+
+struct virNetworkDNSDef {
+    unsigned int ntxtrecords;
+    virNetworkDNSTxtRecordsDefPtr txtrecords;
+} virNetworkDNSDef;
+
+typedef struct virNetworkDNSDef *virNetworkDNSDefPtr;
+
 typedef struct _virNetworkIpDef virNetworkIpDef;
 typedef virNetworkIpDef *virNetworkIpDefPtr;
 struct _virNetworkIpDef {
@@ -75,6 +89,8 @@ struct _virNetworkIpDef {
     unsigned int nranges;        /* Zero or more dhcp ranges */
     virNetworkDHCPRangeDefPtr ranges;
 
+    virNetworkDNSDefPtr dns;     /* DNS related settings for DNSMasq */
+
     unsigned int nhosts;         /* Zero or more dhcp hosts */
     virNetworkDHCPHostDefPtr hosts;
 
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index ea2bfd4..2e299f5 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -442,7 +442,6 @@ networkSaveDnsmasqHostsfile(virNetworkIpDefPtr ipdef,
     return 0;
 }
 
-
 static int
 networkBuildDnsmasqArgv(virNetworkObjPtr network,
                         virNetworkIpDefPtr ipdef,
@@ -497,6 +496,20 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
     if (network->def->forwardType == VIR_NETWORK_FORWARD_NONE)
         virCommandAddArg(cmd, "--dhcp-option=3");
 
+    if (ipdef->dns != NULL) {
+        int i;
+
+        for (i = 0; i < ipdef->dns->ntxtrecords; i++) {
+            virBuffer buf = VIR_BUFFER_INITIALIZER;
+            virBufferVSprintf(&buf, "%s,%s",
+                              ipdef->dns->txtrecords[i].name,
+                              ipdef->dns->txtrecords[i].value);
+
+            virCommandAddArgPair(cmd, "--txt-record", virBufferContentAndReset(&buf));
+            VIR_FREE(buf);
+        }
+    }
+
     /*
      * --interface does not actually work with dnsmasq < 2.47,
      * due to DAD for ipv6 addresses on the interface.
diff --git a/tests/networkxml2xmlin/nat-network-dns-txt-record.xml b/tests/networkxml2xmlin/nat-network-dns-txt-record.xml
new file mode 100644
index 0000000..d3e795d
--- /dev/null
+++ b/tests/networkxml2xmlin/nat-network-dns-txt-record.xml
@@ -0,0 +1,24 @@
+<network>
+  <name>default</name>
+  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+  <forward dev='eth1' mode='nat'/>
+  <bridge name='virbr0' stp='on' delay='0' />
+  <ip address='192.168.122.1' netmask='255.255.255.0'>
+    <dhcp>
+      <range start='192.168.122.2' end='192.168.122.254' />
+      <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
+      <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
+    </dhcp>
+    <dns>
+      <txt-record name='example' value='example value' />
+    </dns>
+  </ip>
+  <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
+  </ip>
+  <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
+  </ip>
+  <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+  </ip>
+  <ip family='ipv4' address='10.24.10.1'>
+  </ip>
+</network>
diff --git a/tests/networkxml2xmlout/nat-network-dns-txt-record.xml b/tests/networkxml2xmlout/nat-network-dns-txt-record.xml
new file mode 100644
index 0000000..d3e795d
--- /dev/null
+++ b/tests/networkxml2xmlout/nat-network-dns-txt-record.xml
@@ -0,0 +1,24 @@
+<network>
+  <name>default</name>
+  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+  <forward dev='eth1' mode='nat'/>
+  <bridge name='virbr0' stp='on' delay='0' />
+  <ip address='192.168.122.1' netmask='255.255.255.0'>
+    <dhcp>
+      <range start='192.168.122.2' end='192.168.122.254' />
+      <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
+      <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
+    </dhcp>
+    <dns>
+      <txt-record name='example' value='example value' />
+    </dns>
+  </ip>
+  <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
+  </ip>
+  <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
+  </ip>
+  <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+  </ip>
+  <ip family='ipv4' address='10.24.10.1'>
+  </ip>
+</network>
diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c
index 7805548..beb00ef 100644
--- a/tests/networkxml2xmltest.c
+++ b/tests/networkxml2xmltest.c
@@ -90,6 +90,7 @@ mymain(int argc, char **argv)
     DO_TEST("nat-network");
     DO_TEST("netboot-network");
     DO_TEST("netboot-proxy-network");
+    DO_TEST("nat-network-dns-txt-record");
 
     return (ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
 }
-- 
1.7.3.2




More information about the libvir-list mailing list