From 3d98acc9e36b3bce5745508cedd138b1a1683d97 Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Thu, 8 Dec 2016 22:23:09 +0100 Subject: [PATCH] network: Add support for local PTR domains Similarly to localOnly DNS domain, localPtr attribute can be used to tell the DNS server not to forward reverse lookups for unknown IPs which belong to the virtual network. Signed-off-by: Jiri Denemark --- docs/formatnetwork.html.in | 21 ++++++---- docs/news.html.in | 2 + docs/schemas/network.rng | 3 ++ src/conf/network_conf.c | 19 +++++++++ src/conf/network_conf.h | 2 + src/network/bridge_driver.c | 41 +++++++++++++++++++ .../networkxml2confdata/ptr-domains-auto.conf | 20 +++++++++ .../networkxml2confdata/ptr-domains-auto.xml | 21 ++++++++++ tests/networkxml2conftest.c | 1 + 9 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 tests/networkxml2confdata/ptr-domains-auto.conf create mode 100644 tests/networkxml2confdata/ptr-domains-auto.xml diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index 9cf940052b..291dcea12b 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -855,14 +855,14 @@ <hostname>myhostalias</hostname> </host> </dns> -<ip address="192.168.122.1" netmask="255.255.255.0"> +<ip address="192.168.122.1" netmask="255.255.255.0" localPtr="yes"> <dhcp> <range start="192.168.122.100" end="192.168.122.254"/> <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> </ip> -<ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64"/> +<ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" localPtr="yes"/> <route family="ipv6" address="2001:db9:ca1:1::" prefix="64" gateway="2001:db8:ca2:2::2"/> @@ -983,11 +983,18 @@ to specify the type of address — ipv4 or ipv6; if no family is given, ipv4 is assumed. More than one address of each family can - be defined for a network. The ip element is supported - since 0.3.0. IPv6, multiple addresses on a - single network, family, and prefix are - supported since 0.8.7. The ip - element may contain the following elements: + be defined for a network. The optional localPtr attribute + (since 3.0.0) configures the DNS server to + not forward any reverse DNS requests for IP addresses from the network + configured by the address and + netmask/prefix attributes. For some unusual + network prefixes (not divisible by 8 for IPv4 or not divisible by 4 for + IPv6) libvirt may be unable to compute the PTR domain automatically. + The ip element is supported since + 0.3.0. IPv6, multiple addresses on a single network, + family, and prefix are supported + since 0.8.7. The ip element may + contain the following elements:
tftp
diff --git a/docs/news.html.in b/docs/news.html.in index 80ac304cd7..5a34674f15 100644 --- a/docs/news.html.in +++ b/docs/news.html.in @@ -16,6 +16,8 @@
  • New features
      +
    • New localPtr attribute for "ip" element in network XML +
    • qemu: Support QEMU group I/O throttling
      Add the capability to allow group I/O throttling via a new domain <disk> <iotune> subelement "group_name" diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng index 9861195966..8f0a61b5bc 100644 --- a/docs/schemas/network.rng +++ b/docs/schemas/network.rng @@ -339,6 +339,9 @@ + + + diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index b6849ceab4..86ce311ee1 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -1507,6 +1507,7 @@ virNetworkIPDefParseXML(const char *networkName, unsigned long prefix = 0; int prefixRc; int result = -1; + char *localPtr = NULL; save = ctxt->node; ctxt->node = node; @@ -1549,6 +1550,17 @@ virNetworkIPDefParseXML(const char *networkName, else def->prefix = prefix; + localPtr = virXPathString("string(./@localPtr)", ctxt); + if (localPtr) { + def->localPTR = virTristateBoolTypeFromString(localPtr); + if (def->localPTR <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid localPtr value '%s' in network '%s'"), + localPtr, networkName); + goto cleanup; + } + } + /* validate address, etc. for each family */ if ((def->family == NULL) || (STREQ(def->family, "ipv4"))) { if (!(VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) || @@ -1627,6 +1639,7 @@ virNetworkIPDefParseXML(const char *networkName, virNetworkIPDefClear(def); VIR_FREE(address); VIR_FREE(netmask); + VIR_FREE(localPtr); ctxt->node = save; return result; @@ -2652,6 +2665,12 @@ virNetworkIPDefFormat(virBufferPtr buf, } if (def->prefix > 0) virBufferAsprintf(buf, " prefix='%u'", def->prefix); + + if (def->localPTR) { + virBufferAsprintf(buf, " localPtr='%s'", + virTristateBoolTypeToString(def->localPTR)); + } + virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 2); diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 09e0916162..b5c9ea24ec 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -162,6 +162,8 @@ struct _virNetworkIPDef { unsigned int prefix; /* ipv6 - only prefix allowed */ virSocketAddr netmask; /* ipv4 - either netmask or prefix specified */ + int localPTR; /* virTristateBool */ + size_t nranges; /* Zero or more dhcp ranges */ virSocketAddrRangePtr ranges; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index ae1589d8c9..f9022d43c2 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -994,6 +994,43 @@ networkBuildDnsmasqHostsList(dnsmasqContext *dctx, } +static int +networkDnsmasqConfLocalPTRs(virBufferPtr buf, + virNetworkDefPtr def) +{ + virNetworkIPDefPtr ip; + size_t i; + char *ptr = NULL; + int rc; + + for (i = 0; i < def->nips; i++) { + ip = def->ips + i; + + if (ip->localPTR != VIR_TRISTATE_BOOL_YES) + continue; + + if ((rc = virSocketAddrPTRDomain(&ip->address, + virNetworkIPDefPrefix(ip), + &ptr)) < 0) { + if (rc == -2) { + int family = VIR_SOCKET_ADDR_FAMILY(&ip->address); + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("PTR domain for %s network with prefix %u " + "cannot be automatically created"), + (family == AF_INET) ? "IPv4" : "IPv6", + virNetworkIPDefPrefix(ip)); + } + return -1; + } + + virBufferAsprintf(buf, "local=/%s/\n", ptr); + VIR_FREE(ptr); + } + + return 0; +} + + int networkDnsmasqConfContents(virNetworkObjPtr network, const char *pidfile, @@ -1079,6 +1116,10 @@ networkDnsmasqConfContents(virNetworkObjPtr network, network->def->domain); } + if (wantDNS && + networkDnsmasqConfLocalPTRs(&configbuf, network->def) < 0) + goto cleanup; + if (wantDNS && network->def->dns.forwardPlainNames == VIR_TRISTATE_BOOL_NO) { virBufferAddLit(&configbuf, "domain-needed\n"); /* need to specify local=// whether or not a domain is diff --git a/tests/networkxml2confdata/ptr-domains-auto.conf b/tests/networkxml2confdata/ptr-domains-auto.conf new file mode 100644 index 0000000000..7f1a393dd5 --- /dev/null +++ b/tests/networkxml2confdata/ptr-domains-auto.conf @@ -0,0 +1,20 @@ +##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE +##OVERWRITTEN AND LOST. Changes to this configuration should be made using: +## virsh net-edit default +## or other application using the libvirt API. +## +## dnsmasq conf file created by libvirt +strict-order +local=/122.168.192.in-addr.arpa/ +local=/1.0.e.f.0.1.c.a.8.b.d.0.1.0.0.2.ip6.arpa/ +except-interface=lo +bind-dynamic +interface=virbr0 +dhcp-range=192.168.122.2,192.168.122.254 +dhcp-no-override +dhcp-authoritative +dhcp-lease-max=253 +dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile +addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts +dhcp-range=2001:db8:ac10:fe01::1,ra-only +dhcp-range=2001:db8:ac10:fd01::1,ra-only diff --git a/tests/networkxml2confdata/ptr-domains-auto.xml b/tests/networkxml2confdata/ptr-domains-auto.xml new file mode 100644 index 0000000000..7fe12dc671 --- /dev/null +++ b/tests/networkxml2confdata/ptr-domains-auto.xml @@ -0,0 +1,21 @@ + + default + 81ff0d90-c91e-6742-64da-4a736edb9a9b + + + + + + + + + + + + + + + + + + diff --git a/tests/networkxml2conftest.c b/tests/networkxml2conftest.c index 65a0e3218f..a80d3b2d45 100644 --- a/tests/networkxml2conftest.c +++ b/tests/networkxml2conftest.c @@ -129,6 +129,7 @@ mymain(void) DO_TEST("dhcp6-network", dhcpv6); DO_TEST("dhcp6-nat-network", dhcpv6); DO_TEST("dhcp6host-routed-network", dhcpv6); + DO_TEST("ptr-domains-auto", dhcpv6); virObjectUnref(dhcpv6); virObjectUnref(full); -- GitLab