[PATCH v3 3/3] network: Add support for local PTR domains

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <jdenemar@xxxxxxxxxx>
---

Notes:
    Version 3:
    - <ptr> was removed from this patch and will be implemented separately
    - NEWS item
    
    Version 2:
    - RNG schema and tests

 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 +++++++++++++++++++++++++
 tests/networkxml2confdata/ptr-domains-auto.conf | 20 ++++++++++++
 tests/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 9cf940052..390aa2e0d 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -855,14 +855,14 @@
     &lt;hostname&gt;myhostalias&lt;/hostname&gt;
   &lt;/host&gt;
 &lt;/dns&gt;
-&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
+&lt;ip address="192.168.122.1" netmask="255.255.255.0" localPtr="yes"&gt;
   &lt;dhcp&gt;
     &lt;range start="192.168.122.100" end="192.168.122.254"/&gt;
     &lt;host mac="00:16:3e:77:e2:ed" name="foo.example.com" ip="192.168.122.10"/&gt;
     &lt;host mac="00:16:3e:3e:a9:1a" name="bar.example.com" ip="192.168.122.11"/&gt;
   &lt;/dhcp&gt;
 &lt;/ip&gt;
-&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64"/&gt;
+&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" localPtr="yes"/&gt;
 &lt;route family="ipv6" address="2001:db9:ca1:1::" prefix="64" gateway="2001:db8:ca2:2::2"/&gt;
 </pre>
 
@@ -983,11 +983,18 @@
         to specify the type of address &mdash; <code>ipv4</code> or
         <code>ipv6</code>; if no <code>family</code> is given,
         <code>ipv4</code> is assumed. More than one address of each family can
-        be defined for a network. The <code>ip</code> element is supported
-        <span class="since">since 0.3.0</span>. IPv6, multiple addresses on a
-        single network, <code>family</code>, and <code>prefix</code> are
-        supported <span class="since">since 0.8.7</span>. The <code>ip</code>
-        element may contain the following elements:
+        be defined for a network. The optional <code>localPtr</code> attribute
+        (<span class="since">since 3.0.0</span>) configures the DNS server not
+        to forward any reverse DNS requests for IP addresses from the network
+        configured by the <code>address</code> and
+        <code>netmask</code>/<code>prefix</code> 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 <code>ip</code> element is supported <span class="since">since
+        0.3.0</span>. IPv6, multiple addresses on a single network,
+        <code>family</code>, and <code>prefix</code> are supported
+        <span class="since">since 0.8.7</span>. The <code>ip</code> element may
+        contain the following elements:
 
         <dl>
           <dt><code>tftp</code></dt>
diff --git a/docs/news.html.in b/docs/news.html.in
index 80ac304cd..5a34674f1 100644
--- a/docs/news.html.in
+++ b/docs/news.html.in
@@ -16,6 +16,8 @@
     <ul>
       <li><strong>New features</strong>
         <ul>
+          <li>New localPtr attribute for "ip" element in network XML
+          </li>
           <li>qemu: Support QEMU group I/O throttling<br/>
           Add the capability to allow group I/O throttling via a new
           domain &lt;disk&gt; &lt;iotune&gt; subelement "group_name"
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 986119596..8f0a61b5b 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -339,6 +339,9 @@
             <optional>
               <attribute name="family"><ref name="addr-family"/></attribute>
             </optional>
+            <optional>
+              <attribute name="localPtr"><ref name="virYesNo"/></attribute>
+            </optional>
             <interleave>
               <optional>
                 <element name="tftp">
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index b6849ceab..86ce311ee 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 09e091616..b5c9ea24e 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 ae1589d8c..f9022d43c 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 000000000..7f1a393dd
--- /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 000000000..7fe12dc67
--- /dev/null
+++ b/tests/networkxml2confdata/ptr-domains-auto.xml
@@ -0,0 +1,21 @@
+<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' localPtr='yes'>
+    <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>
+  </ip>
+  <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0' localPtr='no'>
+  </ip>
+  <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64' localPtr='yes'>
+  </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/networkxml2conftest.c b/tests/networkxml2conftest.c
index 65a0e3218..a80d3b2d4 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);
-- 
2.11.0

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]
  Powered by Linux