Make: passed Make check: passed Make syntax-check: passed Hi, this is the patch to add support for DNS hosts definition in the network XML description to generate the the hosts file. This patch uses the addnhosts* APIs implemented to the src/util/dnsmasq.c by part 2 of this patch series. Also, tests for the XML to XML definition and command-line regression tests has been added. Michal Signed-off-by: Michal Novotny <minovotn@xxxxxxxxxx> --- docs/formatnetwork.html.in | 7 + docs/schemas/network.rng | 8 ++ src/conf/network_conf.c | 128 ++++++++++++++++++-- src/conf/network_conf.h | 9 ++ src/network/bridge_driver.c | 20 ++- .../networkxml2argvdata/nat-network-dns-hosts.argv | 1 + .../networkxml2argvdata/nat-network-dns-hosts.xml | 19 +++ tests/networkxml2argvtest.c | 1 + tests/networkxml2xmlin/nat-network-dns-hosts.xml | 27 ++++ tests/networkxml2xmlout/nat-network-dns-hosts.xml | 27 ++++ tests/networkxml2xmltest.c | 1 + 11 files changed, 234 insertions(+), 14 deletions(-) create mode 100644 tests/networkxml2argvdata/nat-network-dns-hosts.argv create mode 100644 tests/networkxml2argvdata/nat-network-dns-hosts.xml create mode 100644 tests/networkxml2xmlin/nat-network-dns-hosts.xml create mode 100644 tests/networkxml2xmlout/nat-network-dns-hosts.xml diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index 5211ed2..5d18ed9 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -222,6 +222,13 @@ separated by commas. <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 e27dace..05066a5 100644 --- a/docs/schemas/network.rng +++ b/docs/schemas/network.rng @@ -146,6 +146,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> </element> diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index b7427d0..1f88649 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -435,6 +435,53 @@ virNetworkDHCPRangeDefParseXML(const char *networkName, } static int +virNetworkDNSHostsDefParseXML(virNetworkIpDefPtr def, + xmlNodePtr node, + virSocketAddr ip) +{ + xmlNodePtr cur; + int result = -1; + + if (def->dns->hosts == NULL) { + if (VIR_ALLOC(def->dns->hosts) < 0) + goto oom_error; + def->dns->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->dns->hosts, def->dns->nhosts + 1) < 0) { + VIR_FREE(hostname); + result = -1; + goto oom_error; + } + + def->dns->hosts[def->dns->nhosts].name = strdup(hostname); + def->dns->hosts[def->dns->nhosts].ip = ip; + def->dns->nhosts++; + + VIR_FREE(hostname); + } + } + + cur = cur->next; + } + + return 0; + +oom_error: + virReportOOMError(); + return result; +} + +static int virNetworkDNSDefParseXML(virNetworkIpDefPtr def, xmlNodePtr node) { @@ -476,6 +523,27 @@ virNetworkDNSDefParseXML(virNetworkIpDefPtr def, VIR_FREE(name); VIR_FREE(value); + } 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); + result = virNetworkDNSHostsDefParseXML(def, cur, inaddr); + if (result) + goto error; } cur = cur->next; @@ -485,6 +553,7 @@ virNetworkDNSDefParseXML(virNetworkIpDefPtr def, oom_error: virReportOOMError(); +error: return result; } @@ -888,17 +957,60 @@ virNetworkIpDefFormat(virBufferPtr buf, virBufferAddLit(buf, " </dhcp>\n"); } - if ((def->dns != NULL) && (def->dns->ntxtrecords)) { - int ii; - + if (def->dns != NULL) { 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); + + if (def->dns->ntxtrecords) { + int ii; + + 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); + } + } + if (def->dns->nhosts) { + int ii, j; + char **iplist = NULL; + int iplist_size = 0; + bool in_list; + + if (VIR_ALLOC(iplist) < 0) + goto error; + + for (ii = 0 ; ii < def->dns->nhosts; ii++) { + char *ip = virSocketFormatAddr(&def->dns->hosts[ii].ip); + in_list = false; + for (j = 0; j < iplist_size; j++) + if (STREQ(iplist[j], ip)) + in_list = true; + + if (!in_list) { + virBufferVSprintf(buf, " <host ip='%s'>\n", ip); + + for (j = 0 ; j < def->dns->nhosts; j++) { + char *thisip = virSocketFormatAddr(&def->dns->hosts[j].ip); + if (STREQ(ip, thisip)) + virBufferVSprintf(buf, " <hostname>%s</hostname>\n", + def->dns->hosts[j].name); + } + virBufferVSprintf(buf, " </host>\n"); + + if (VIR_REALLOC_N(iplist, iplist_size + 1) < 0) + goto error; + + iplist[iplist_size] = strdup(ip); + iplist_size++; + } + } + + for (j = 0; j < iplist_size; j++) + VIR_FREE(iplist[j]); + VIR_FREE(iplist); } + virBufferAddLit(buf, " </dns>\n"); - } + } virBufferAddLit(buf, " </ip>\n"); diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 5f47595..305ef0f 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 4ad3143..99a61b0 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -434,13 +434,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 (ipdef->dns) { + for (i = 0; i < ipdef->dns->nhosts; i++) { + virNetworkDNSHostsDefPtr host = &(ipdef->dns->hosts[i]); + if (VIR_SOCKET_HAS_ADDR(&host->ip)) + dnsmasqAddHost(dctx, &host->ip, host->name); + } } if (dnsmasqSave(dctx) < 0) @@ -589,6 +596,7 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, if (dctx->hostsfile->nhosts) virCommandAddArgPair(cmd, "--dhcp-hostsfile", dctx->hostsfile->path); + VIR_DEBUG("ADDN HOSTS: %d => %p", dctx->addnhostsfile->nhosts, ipdef->dns); if (dctx->addnhostsfile->nhosts) virCommandAddArgPair(cmd, "--addn-hosts", dctx->addnhostsfile->path); diff --git a/tests/networkxml2argvdata/nat-network-dns-hosts.argv b/tests/networkxml2argvdata/nat-network-dns-hosts.argv new file mode 100644 index 0000000..99dc724 --- /dev/null +++ b/tests/networkxml2argvdata/nat-network-dns-hosts.argv @@ -0,0 +1 @@ +/usr/sbin/dnsmasq --strict-order --bind-interfaces --pid-file=/var/run/libvirt/network/default.pid --conf-file= --except-interface lo --listen-address 192.168.122.1 --dhcp-range 192.168.122.2,192.168.122.254 --dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases --dhcp-lease-max=253 --dhcp-no-override --dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts diff --git a/tests/networkxml2argvdata/nat-network-dns-hosts.xml b/tests/networkxml2argvdata/nat-network-dns-hosts.xml new file mode 100644 index 0000000..35ee151 --- /dev/null +++ b/tests/networkxml2argvdata/nat-network-dns-hosts.xml @@ -0,0 +1,19 @@ +<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> + <host ip='192.168.122.1'> + <hostname>host</hostname> + <hostname>gateway</hostname> + </host> + </dns> + </ip> +</network> diff --git a/tests/networkxml2argvtest.c b/tests/networkxml2argvtest.c index e3a8bb4..ce09206 100644 --- a/tests/networkxml2argvtest.c +++ b/tests/networkxml2argvtest.c @@ -112,6 +112,7 @@ mymain(int argc, char **argv) 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 0000000..fe545cf --- /dev/null +++ b/tests/networkxml2xmlin/nat-network-dns-hosts.xml @@ -0,0 +1,27 @@ +<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> + <host ip='192.168.122.1'> + <hostname>host</hostname> + <hostname>gateway</hostname> + </host> + </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-hosts.xml b/tests/networkxml2xmlout/nat-network-dns-hosts.xml new file mode 100644 index 0000000..fe545cf --- /dev/null +++ b/tests/networkxml2xmlout/nat-network-dns-hosts.xml @@ -0,0 +1,27 @@ +<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> + <host ip='192.168.122.1'> + <hostname>host</hostname> + <hostname>gateway</hostname> + </host> + </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 beb00ef..f5c5715 100644 --- a/tests/networkxml2xmltest.c +++ b/tests/networkxml2xmltest.c @@ -91,6 +91,7 @@ mymain(int argc, char **argv) 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