summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Novotny <minovotn@redhat.com>2011-06-24 12:04:40 +0200
committerLaine Stump <laine@laine.org>2011-06-24 16:15:36 -0400
commit9d4e2845d498edcf46fe339537fe473f24d75f66 (patch)
treefe3ac34dcd676e51ae825e8576ae27cd94397324
parentNetwork: Add additional hosts internal infrastructure (diff)
downloadlibvirt-9d4e2845d498edcf46fe339537fe473f24d75f66.tar.gz
libvirt-9d4e2845d498edcf46fe339537fe473f24d75f66.tar.bz2
libvirt-9d4e2845d498edcf46fe339537fe473f24d75f66.zip
Network: Add support for DNS hosts definition to the network XML
This commit introduces names definition for the DNS hosts file using the following syntax: <dns> <host ip="192.168.1.1"> <name>alias1</name> <name>alias2</name> </host> </dns> Some of the improvements and fixes were done by Laine Stump so I'm putting him into the SOB clause again ;-) Signed-off-by: Michal Novotny <minovotn@redhat.com> Signed-off-by: Laine Stump <laine@laine.org>
-rw-r--r--docs/formatnetwork.html.in8
-rw-r--r--docs/schemas/network.rng8
-rw-r--r--src/conf/network_conf.c94
-rw-r--r--src/conf/network_conf.h10
-rw-r--r--src/network/bridge_driver.c28
-rw-r--r--tests/networkxml2argvdata/nat-network-dns-hosts.argv1
-rw-r--r--tests/networkxml2argvdata/nat-network-dns-hosts.xml14
-rw-r--r--tests/networkxml2argvtest.c1
-rw-r--r--tests/networkxml2xmlin/nat-network-dns-hosts.xml14
-rw-r--r--tests/networkxml2xmlout/nat-network-dns-hosts.xml14
-rw-r--r--tests/networkxml2xmltest.c1
11 files changed, 184 insertions, 9 deletions
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index 4a5cb0347..cbec7af59 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -184,6 +184,14 @@
or commas. value is a single string that can contain multiple values
separated by commas. <span class="since">Since 0.9.3</span>
</dd>
+ <dt><code>host</code></dt>
+ <dd>The <code>host</code> element within <code>dns</code> is the
+ definition of DNS hosts to be passed to the DNS service. The IP
+ address is identified by the <code>ip</code> attribute and the names
+ for that IP address are identified in the <code>hostname</code>
+ sub-elements of the <code>host</code> element.
+ <span class="since">Since 0.9.3</span>
+ </dd>
</dl>
</dd>
<dt><code>dhcp</code></dt>
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index c42382e4d..05f45e548 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -97,6 +97,14 @@
<attribute name="value"><text/></attribute>
</element>
</zeroOrMore>
+ <zeroOrMore>
+ <element name="host">
+ <attribute name="ip"><ref name="ipv4-addr"/></attribute>
+ <oneOrMore>
+ <element name="hostname"><text/></element>
+ </oneOrMore>
+ </element>
+ </zeroOrMore>
</element>
</optional>
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index d8f1e25c2..d0860d874 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -114,6 +114,14 @@ static void virNetworkDNSDefFree(virNetworkDNSDefPtr def)
}
VIR_FREE(def->txtrecords);
}
+ if (def->nhosts) {
+ while (def->nhosts--) {
+ while (def->hosts[def->nhosts].nnames--)
+ VIR_FREE(def->hosts[def->nhosts].names[def->hosts[def->nhosts].nnames]);
+ VIR_FREE(def->hosts[def->nhosts].names);
+ }
+ VIR_FREE(def->hosts);
+ }
VIR_FREE(def);
}
}
@@ -451,6 +459,71 @@ virNetworkDHCPRangeDefParseXML(const char *networkName,
}
static int
+virNetworkDNSHostsDefParseXML(virNetworkDNSDefPtr def,
+ xmlNodePtr node)
+{
+ xmlNodePtr cur;
+ char *ip;
+ virSocketAddr inaddr;
+ int ret = -1;
+
+ if (def->hosts == NULL) {
+ if (VIR_ALLOC(def->hosts) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ def->nhosts = 0;
+ }
+
+ if (!(ip = virXMLPropString(node, "ip")) ||
+ (virSocketParseAddr(ip, &inaddr, AF_UNSPEC) < 0)) {
+ virNetworkReportError(VIR_ERR_XML_DETAIL,
+ _("Missing IP address in DNS host definition"));
+ VIR_FREE(ip);
+ goto error;
+ }
+ VIR_FREE(ip);
+
+ if (VIR_REALLOC_N(def->hosts, def->nhosts + 1) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ def->hosts[def->nhosts].ip = inaddr;
+ def->hosts[def->nhosts].nnames = 0;
+
+ if (VIR_ALLOC(def->hosts[def->nhosts].names) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ cur = node->children;
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "hostname")) {
+ if (cur->children != NULL) {
+ if (VIR_REALLOC_N(def->hosts[def->nhosts].names, def->hosts[def->nhosts].nnames + 1) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ def->hosts[def->nhosts].names[def->hosts[def->nhosts].nnames] = strdup((char *)cur->children->content);
+ def->hosts[def->nhosts].nnames++;
+ }
+ }
+
+ cur = cur->next;
+ }
+
+ def->nhosts++;
+
+ ret = 0;
+
+error:
+ return ret;
+}
+
+static int
virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef,
xmlNodePtr node)
{
@@ -496,6 +569,11 @@ virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef,
def->ntxtrecords++;
name = NULL;
value = NULL;
+ } else if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "host")) {
+ ret = virNetworkDNSHostsDefParseXML(def, cur);
+ if (ret < 0)
+ goto error;
}
cur = cur->next;
@@ -854,6 +932,22 @@ virNetworkDNSDefFormat(virBufferPtr buf,
def->txtrecords[i].value);
}
+ if (def->nhosts) {
+ int ii, j;
+
+ for (ii = 0 ; ii < def->nhosts; ii++) {
+ char *ip = virSocketFormatAddr(&def->hosts[ii].ip);
+
+ virBufferAsprintf(buf, " <host ip='%s'>\n", ip);
+
+ for (j = 0; j < def->hosts[ii].nnames; j++)
+ virBufferAsprintf(buf, " <hostname>%s</hostname>\n",
+ def->hosts[ii].names[j]);
+
+ virBufferAsprintf(buf, " </host>\n");
+ }
+ }
+
virBufferAddLit(buf, " </dns>\n");
out:
return result;
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index d0dac0219..d7d295199 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -64,9 +64,19 @@ struct _virNetworkDNSTxtRecordsDef {
char *value;
};
+struct virNetworkDNSHostsDef {
+ virSocketAddr ip;
+ int nnames;
+ char **names;
+} virNetworkDNSHostsDef;
+
+typedef struct virNetworkDNSHostsDef *virNetworkDNSHostsDefPtr;
+
struct virNetworkDNSDef {
unsigned int ntxtrecords;
virNetworkDNSTxtRecordsDefPtr txtrecords;
+ unsigned int nhosts;
+ virNetworkDNSHostsDefPtr hosts;
} virNetworkDNSDef;
typedef struct virNetworkDNSDef *virNetworkDNSDefPtr;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 448afbdfb..1b1113241 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -435,10 +435,11 @@ networkShutdown(void) {
static dnsmasqContext*
networkSaveDnsmasqHostsfile(virNetworkIpDefPtr ipdef,
+ virNetworkDNSDefPtr dnsdef,
char *name,
bool force)
{
- unsigned int i;
+ unsigned int i, j;
dnsmasqContext *dctx = dnsmasqContextNew(name,
DNSMASQ_STATE_DIR);
@@ -447,13 +448,22 @@ networkSaveDnsmasqHostsfile(virNetworkIpDefPtr ipdef,
goto cleanup;
}
- if (! force && virFileExists(dctx->hostsfile->path))
- return 0;
+ if (!(! force && virFileExists(dctx->hostsfile->path))) {
+ for (i = 0; i < ipdef->nhosts; i++) {
+ virNetworkDHCPHostDefPtr host = &(ipdef->hosts[i]);
+ if ((host->mac) && VIR_SOCKET_HAS_ADDR(&host->ip))
+ dnsmasqAddDhcpHost(dctx, host->mac, &host->ip, host->name);
+ }
+ }
- for (i = 0; i < ipdef->nhosts; i++) {
- virNetworkDHCPHostDefPtr host = &(ipdef->hosts[i]);
- if ((host->mac) && VIR_SOCKET_HAS_ADDR(&host->ip))
- dnsmasqAddDhcpHost(dctx, host->mac, &host->ip, host->name);
+ if (dnsdef) {
+ for (i = 0; i < dnsdef->nhosts; i++) {
+ virNetworkDNSHostsDefPtr host = &(dnsdef->hosts[i]);
+ if (VIR_SOCKET_HAS_ADDR(&host->ip)) {
+ for (j = 0; j < host->nnames; j++)
+ dnsmasqAddHost(dctx, &host->ip, host->names[j]);
+ }
+ }
}
if (dnsmasqSave(dctx) < 0)
@@ -604,7 +614,7 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
if (ipdef->nranges || ipdef->nhosts)
virCommandAddArg(cmd, "--dhcp-no-override");
- if ((dctx = networkSaveDnsmasqHostsfile(ipdef, network->def->name, false))) {
+ if ((dctx = networkSaveDnsmasqHostsfile(ipdef, network->def->dns, network->def->name, false))) {
if (dctx->hostsfile->nhosts)
virCommandAddArgPair(cmd, "--dhcp-hostsfile",
dctx->hostsfile->path);
@@ -2239,7 +2249,7 @@ static virNetworkPtr networkDefine(virConnectPtr conn, const char *xml) {
}
}
if (ipv4def) {
- dnsmasqContext* dctx = networkSaveDnsmasqHostsfile(ipv4def, network->def->name, true);
+ dnsmasqContext* dctx = networkSaveDnsmasqHostsfile(ipv4def, network->def->dns, network->def->name, true);
if (dctx == NULL)
goto cleanup;
dnsmasqContextFree(dctx);
diff --git a/tests/networkxml2argvdata/nat-network-dns-hosts.argv b/tests/networkxml2argvdata/nat-network-dns-hosts.argv
new file mode 100644
index 000000000..d240bf41c
--- /dev/null
+++ b/tests/networkxml2argvdata/nat-network-dns-hosts.argv
@@ -0,0 +1 @@
+/usr/sbin/dnsmasq --strict-order --bind-interfaces --conf-file= --except-interface lo --listen-address 192.168.122.1 --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts \ No newline at end of file
diff --git a/tests/networkxml2argvdata/nat-network-dns-hosts.xml b/tests/networkxml2argvdata/nat-network-dns-hosts.xml
new file mode 100644
index 000000000..9a83fed17
--- /dev/null
+++ b/tests/networkxml2argvdata/nat-network-dns-hosts.xml
@@ -0,0 +1,14 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9c</uuid>
+ <forward dev='eth0' mode='nat'/>
+ <bridge name='virbr0' stp='on' delay='0' />
+ <dns>
+ <host ip='192.168.122.1'>
+ <hostname>host</hostname>
+ <hostname>gateway</hostname>
+ </host>
+ </dns>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ </ip>
+</network>
diff --git a/tests/networkxml2argvtest.c b/tests/networkxml2argvtest.c
index 98c84ad7f..16d57a9c7 100644
--- a/tests/networkxml2argvtest.c
+++ b/tests/networkxml2argvtest.c
@@ -101,6 +101,7 @@ mymain(void)
DO_TEST("netboot-network");
DO_TEST("netboot-proxy-network");
DO_TEST("nat-network-dns-txt-record");
+ DO_TEST("nat-network-dns-hosts");
return (ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
diff --git a/tests/networkxml2xmlin/nat-network-dns-hosts.xml b/tests/networkxml2xmlin/nat-network-dns-hosts.xml
new file mode 100644
index 000000000..9a83fed17
--- /dev/null
+++ b/tests/networkxml2xmlin/nat-network-dns-hosts.xml
@@ -0,0 +1,14 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9c</uuid>
+ <forward dev='eth0' mode='nat'/>
+ <bridge name='virbr0' stp='on' delay='0' />
+ <dns>
+ <host ip='192.168.122.1'>
+ <hostname>host</hostname>
+ <hostname>gateway</hostname>
+ </host>
+ </dns>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ </ip>
+</network>
diff --git a/tests/networkxml2xmlout/nat-network-dns-hosts.xml b/tests/networkxml2xmlout/nat-network-dns-hosts.xml
new file mode 100644
index 000000000..9a83fed17
--- /dev/null
+++ b/tests/networkxml2xmlout/nat-network-dns-hosts.xml
@@ -0,0 +1,14 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9c</uuid>
+ <forward dev='eth0' mode='nat'/>
+ <bridge name='virbr0' stp='on' delay='0' />
+ <dns>
+ <host ip='192.168.122.1'>
+ <hostname>host</hostname>
+ <hostname>gateway</hostname>
+ </host>
+ </dns>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ </ip>
+</network>
diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c
index 2cc8e560f..065166d72 100644
--- a/tests/networkxml2xmltest.c
+++ b/tests/networkxml2xmltest.c
@@ -87,6 +87,7 @@ mymain(void)
DO_TEST("netboot-network");
DO_TEST("netboot-proxy-network");
DO_TEST("nat-network-dns-txt-record");
+ DO_TEST("nat-network-dns-hosts");
return (ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
}