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

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



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.

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 redhat com>
---
 docs/formatnetwork.html.in                         |   26 ++++++++-
 docs/schemas/network.rng                           |   12 ++++
 src/conf/network_conf.c                            |   65 ++++++++++++++++++++
 src/conf/network_conf.h                            |   16 +++++
 src/network/bridge_driver.c                        |   27 ++++++++
 .../nat-network-dns-txt-record.xml                 |   24 +++++++
 .../nat-network-dns-txt-record.xml                 |   24 +++++++
 tests/networkxml2xmltest.c                         |    1 +
 8 files changed, 194 insertions(+), 1 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..2d76d3d 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 @@
             &lt;host mac="00:16:3e:77:e2:ed" name="foo.example.com" ip="192.168.122.10" /&gt;
             &lt;host mac="00:16:3e:3e:a9:1a" name="bar.example.com" ip="192.168.122.11" /&gt;
           &lt;/dhcp&gt;
+          &lt;dns&gt;
+            &lt;txt-record name="example name" value="example value" /&gt;
+          &lt;/dns&gt;
         &lt;/ip&gt;
       &lt;/network&gt;</pre>
 
@@ -199,6 +205,24 @@
         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.0</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 and therefore you should
+        avoid using them since they are automatically replaced by spaces, e.g. <code>
+        name, clarification</code> value of the <code>name</code> tag will be replaced
+        to be <code>name clarification</code> instead. This rule doesn't apply to the
+        record <code>value</code> contents since it supports multiple values separated
+        by commas.
+        <span class="since">Since 0.9.0</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..145ae20 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -435,6 +435,54 @@ 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 (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 +598,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 +882,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..5d901ff 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -442,6 +442,18 @@ networkSaveDnsmasqHostsfile(virNetworkIpDefPtr ipdef,
     return 0;
 }
 
+static char *
+replace_all(char *input, int chr1, int chr2)
+{
+    char *tmp;
+    char *out;
+
+    out = strdup(input);
+    while ((tmp = strchr(out, chr1)) != NULL)
+        out[ strlen(input) - strlen(tmp) ] = chr2;
+
+    return out;
+}
 
 static int
 networkBuildDnsmasqArgv(virNetworkObjPtr network,
@@ -497,6 +509,21 @@ 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",
+                              replace_all(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..d3cdbd5
--- /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 name' 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..d3cdbd5
--- /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 name' 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


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