diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index 9cf940052b7314654c43234efa4fad799f51c1b9..291dcea12b72512829d90858cae6a88b2c63a26f 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 80ac304cd705e9402c0325943ab12cc765920202..5a34674f157b1d1150dbadc07b1404b7902da400 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 98611959660c37ab9eb1c673dfb63a196dd39a82..8f0a61b5bc7ce20102a5ddb7e788c7958c53c3f6 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 b6849ceab44ac819e10cda4b2b8ac469a2af6521..86ce311ee1ba1a05f0713b9823a56a722db2abfb 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 09e091616250040d818e3bccf3cd179217ca82cb..b5c9ea24ecd71586f84076ab28d546f34cccee73 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 ae1589d8c962109aa27d7c6af9d705b32b68ac99..f9022d43c2601e91bee4d21a5838bf739ccf7367 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 0000000000000000000000000000000000000000..7f1a393dd5a24c164fcc0b6d1ce3fdd81c40e3d5
--- /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 0000000000000000000000000000000000000000..7fe12dc671cb2d7c6664a7ad09c4d7e71286653f
--- /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 65a0e3218f39d7d495973863153d6280b71ac3be..a80d3b2d45d31f1542fc6e422168a6743872d5c2 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);