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@xxxxxxxxxx> --- 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 @@ <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 name" value="example value" /> + </dns> </ip> </network></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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list