提交 9d4e2845 编写于 作者: M Michal Novotny 提交者: Laine Stump

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: NMichal Novotny <minovotn@redhat.com>
Signed-off-by: NLaine Stump <laine@laine.org>
上级 91b7924e
......@@ -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>
......
......@@ -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>
......
......@@ -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);
}
}
......@@ -450,6 +458,71 @@ virNetworkDHCPRangeDefParseXML(const char *networkName,
return 0;
}
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;
......
......@@ -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;
......
......@@ -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);
......
/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
<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>
......@@ -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);
}
......
<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>
<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>
......@@ -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);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册