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> Signed-off-by: Michal Novotny <minovotn@xxxxxxxxxx> --- docs/formatnetwork.html.in | 7 +++ docs/schemas/network.rng | 8 +++ src/conf/network_conf.c | 115 +++++++++++++++++++++++++++++++++++++++++++ src/conf/network_conf.h | 9 +++ src/network/bridge_driver.c | 24 ++++++--- tests/networkxml2argvtest.c | 1 + tests/networkxml2xmltest.c | 1 + 7 files changed, 157 insertions(+), 8 deletions(-) diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index 95d9c1a..6f28d54 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -225,6 +225,13 @@ subelements of the <code>host</code> element. <span class="since">Since 0.9.1</span> </dd> + <dt><code>host</code></dt> + <dd>The <code>host</code> element 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 the IP addresses are identified in the <code>hostname</code> + subelements of the <code>host</code> element. + <span class="since">Since 0.9.1</span> + </dd> </dl> <h2><a name="examples">Example configuration</a></h2> diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng index 3780af5..d28a93d 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 133ac84..56ee1d0 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -435,6 +435,53 @@ virNetworkDHCPRangeDefParseXML(const char *networkName, } static int +virNetworkDNSHostsDefParseXML(virNetworkDNSDefPtr def, + xmlNodePtr node, + virSocketAddr ip) +{ + xmlNodePtr cur; + int ret = -1; + + if (def->hosts == NULL) { + if (VIR_ALLOC(def->hosts) < 0) { + virReportOOMError(); + goto out; + } + def->nhosts = 0; + } + + cur = node->children; + while (cur != NULL) { + if (cur->type == XML_ELEMENT_NODE && + xmlStrEqual(cur->name, BAD_CAST "hostname")) { + if (cur->children != NULL) { + char *hostname; + + hostname = strdup((char *)cur->children->content); + + if (VIR_REALLOC_N(def->hosts, def->nhosts + 1) < 0) { + VIR_FREE(hostname); + ret = -1; + virReportOOMError(); + goto out; + } + + def->hosts[def->nhosts].name = hostname; + def->hosts[def->nhosts].ip = ip; + def->nhosts++; + } + } + + cur = cur->next; + } + + ret = 0; + +out: + return ret; +} + +static int virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef, xmlNodePtr node) { @@ -477,6 +524,27 @@ virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef, def->txtrecords[def->ntxtrecords].name = name; def->txtrecords[def->ntxtrecords].value = value; def->ntxtrecords++; + } else if (cur->type == XML_ELEMENT_NODE && + xmlStrEqual(cur->name, BAD_CAST "host")) { + char *ip; + virSocketAddr inaddr; + memset(&inaddr, 0, sizeof(inaddr)); + + if (!(ip = virXMLPropString(cur, "ip"))) { + cur = cur->next; + continue; + } + if ((ip == NULL) || + (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); + ret = virNetworkDNSHostsDefParseXML(def, cur, inaddr); + if (ret < 0) + goto error; } cur = cur->next; @@ -839,6 +907,53 @@ virNetworkDNSDefFormat(virBufferPtr buf, def->txtrecords[i].value); } + if (def->nhosts) { + int ii, j; + char **iplist = NULL; + int iplist_size = 0; + bool in_list; + + if (VIR_ALLOC(iplist) < 0) { + virReportOOMError(); + result = -1; + goto out; + } + + for (ii = 0 ; ii < def->nhosts; ii++) { + char *ip = virSocketFormatAddr(&def->hosts[ii].ip); + in_list = false; + + for (j = 0; j < iplist_size; j++) + if (STREQ(iplist[j], ip)) + in_list = true; + + if (!in_list) { + virBufferAsprintf(buf, " <host ip='%s'>\n", ip); + + for (j = 0 ; j < def->nhosts; j++) { + char *thisip = virSocketFormatAddr(&def->hosts[j].ip); + if (STREQ(ip, thisip)) + virBufferAsprintf(buf, " <hostname>%s</hostname>\n", + def->hosts[j].name); + } + virBufferAsprintf(buf, " </host>\n"); + + if (VIR_REALLOC_N(iplist, iplist_size + 1) < 0) { + virReportOOMError(); + result = -1; + goto out; + } + + iplist[iplist_size] = ip; + iplist_size++; + } + } + + for (j = 0; j < iplist_size; j++) + VIR_FREE(iplist[j]); + VIR_FREE(iplist); + } + virBufferAddLit(buf, " </dns>\n"); out: return result; diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index d0dac02..50b3713 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -64,9 +64,18 @@ struct _virNetworkDNSTxtRecordsDef { char *value; }; +struct virNetworkDNSHostsDef { + virSocketAddr ip; + char *name; +} virNetworkDNSHostsDef; + +typedef struct virNetworkDNSHostsDef *virNetworkDNSHostsDefPtr; + struct virNetworkDNSDef { unsigned int ntxtrecords; + unsigned int nhosts; virNetworkDNSTxtRecordsDefPtr txtrecords; + virNetworkDNSHostsDefPtr hosts; } virNetworkDNSDef; typedef struct virNetworkDNSDef *virNetworkDNSDefPtr; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 8f68f1c..90bbc1d 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -436,6 +436,7 @@ networkShutdown(void) { static dnsmasqContext* networkSaveDnsmasqHostsfile(virNetworkIpDefPtr ipdef, + virNetworkDNSDefPtr dnsdef, char *name, bool force) { @@ -448,13 +449,20 @@ 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)) + dnsmasqAddHost(dctx, &host->ip, host->name); + } } if (dnsmasqSave(dctx) < 0) @@ -605,7 +613,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); @@ -2241,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/networkxml2argvtest.c b/tests/networkxml2argvtest.c index 5e7f455..78f61ca 100644 --- a/tests/networkxml2argvtest.c +++ b/tests/networkxml2argvtest.c @@ -92,6 +92,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/networkxml2xmltest.c b/tests/networkxml2xmltest.c index 2cc8e56..065166d 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); } -- 1.7.3.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list