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

[libvirt] [PATCHv3 1/3] v2.0: allow guest to guest IPv6 without gateway definition



This patch adds the capability for virtual guests to do IPv6
communication via a virtual network interface with no IPv6
(gateway) addresses specified.  This capability currently
exists for IPv4.

This patch allows creation of a completely isolated IPv6 network.

Note that virtual guests cannot communication with the virtualization
host via this interface.  Also note that:
      net.ipv6.conf.<interface_name>.disable_ipv6 = 1

Also not that starting libvirtd has set the following:
  net.bridge.bridge-nf-call-arptables = 1
  net.bridge.bridge-nf-call-ip6tables = 1
  net.bridge.bridge-nf-call-iptables = 1
although /etc/syslog.conf has them all set to 0.

To control this behavior so that it is not enabled by default, the parameter
ipv6='yes' on the <network> statement has been added.

Documentation related to this patch has been updated.
The network schema has also been updated.
---
 docs/formatnetwork.html.in  | 28 +++++++++++++++++++++++++++-
 docs/schemas/network.rng    | 10 ++++++++++
 src/conf/network_conf.c     |  8 ++++++++
 src/conf/network_conf.h     |  5 +++++
 src/network/bridge_driver.c | 25 ++++++++++++++++++++-----
 5 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index 49206dd..a3a5ced 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -33,7 +33,7 @@
     </p>
 
     <pre>
-      &lt;network&gt;
+      &lt;network ipv6='yes'&gt;
         &lt;name&gt;default&lt;/name&gt;
         &lt;uuid&gt;3e3fce45-4f53-4fa7-bb32-11f34168b82b&lt;/uuid&gt;
         ...</pre>
@@ -52,6 +52,12 @@
         The format must be RFC 4122 compliant, eg <code>3e3fce45-4f53-4fa7-bb32-11f34168b82b</code>.
         If omitted when defining/creating a new network, a random
         UUID is generated. <span class="since">Since 0.3.0</span></dd>
+      <dt><code>ipv6='yes'</code></dt>
+      <dd>The new, optional parameter <code>ipv6='yes'</code> enables
+        a network definition with no IPv6 gateway addresses specified
+        to have guest-to-guest communications.  For further information,
+        see the example below for the example with no gateway addresses.
+        <span class="since">Since 1.0.1</span></dd>
     </dl>
 
     <h3><a name="elementsConnect">Connectivity</a></h3>
@@ -773,5 +779,25 @@
         &lt;/forward&gt;
       &lt;/network&gt;</pre>
 
+    <h3><a name="examplesNoGateway">Network config with no gateway addresses</a></h3>
+
+    <p>
+    A valid network definition can contain no IPv4 or IPv6 addresses.  Such a definition
+    can be used for a "very private" or "very isolated" network since it will not be
+    possible to communicate with the virtualization host via this network.  However,
+    this virtual network interface can be used for communication between virtual guest
+    systems.  This works for IPv4 and <span class="since">(Since 1.0.1)</span> IPv6.
+    However, the new ipv6='yes' must be added for guest-to-guest IPv6
+    communication.
+    </p>
+
+    <pre>
+      &lt;network ipv6='yes'&gt;
+        &lt;name&gt;nogw&lt;/name&gt;
+        &lt;uuid&gt;7a3b7497-1ec7-8aef-6d5c-38dff9109e93&lt;/uuid&gt;
+        &lt;bridge name="virbr2" stp="on" delay="0" /&gt;
+        &lt;mac address='00:16:3E:5D:C7:9E'/&gt;
+      &lt;/network&gt;</pre>
+
   </body>
 </html>
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 4abfd91..0d67f7f 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -17,6 +17,16 @@
           <data type="unsignedInt"/>
         </attribute>
       </optional>
+      <!-- Enables IPv6 guest-to-guest communications on a network
+           with no gateways addresses specified -->
+      <optional>
+        <attribute name="ipv6">
+         <choice>
+          <value>yes</value>
+          <value>no</value>
+          </choice>
+         </attribute>
+       </optional>
       <interleave>
 
         <!-- The name of the network, used to refer to it through the API
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 6ce2e63..3f9e13c 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -1264,6 +1264,12 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
         def->uuid_specified = true;
     }
 
+    /* check if definitions with no IPv6 gateway addresses is to
+     * allow guest-to-guest communications.
+     */
+    if (virXPathBoolean("boolean(./@ipv6)", ctxt) == 1)
+        def->ipv6nogw = true;
+
     /* Parse network domain information */
     def->domain = virXPathString("string(./domain[1]/@name)", ctxt);
 
@@ -1839,6 +1845,8 @@ char *virNetworkDefFormat(const virNetworkDefPtr def, unsigned int flags)
     if (!(flags & VIR_NETWORK_XML_INACTIVE) && (def->connections > 0)) {
         virBufferAsprintf(&buf, " connections='%d'", def->connections);
     }
+    if (def->ipv6nogw)
+        virBufferAddLit(&buf, " ipv6='yes'");
     virBufferAddLit(&buf, ">\n");
     virBufferAdjustIndent(&buf, 2);
     virBufferEscapeString(&buf, "<name>%s</name>\n", def->name);
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 3e46304..949b3d2 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -184,6 +184,11 @@ struct _virNetworkDef {
     virMacAddr mac; /* mac address of bridge device */
     bool mac_specified;
 
+    /* specified if ip6tables rules added
+     * when no ipv6 gateway addresses specified.
+     */
+    bool ipv6nogw;
+
     int forwardType;    /* One of virNetworkForwardType constants */
     int managed;        /* managed attribute for hostdev mode */
 
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 75f3c3a..cb2997d 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -1617,13 +1617,18 @@ networkRemoveRoutingIptablesRules(struct network_driver *driver,
     }
 }
 
-/* Add all once/network rules required for IPv6 (if any IPv6 addresses are defined) */
+/* Add all once/network rules required for IPv6.
+ * If no IPv6 addresses are defined and <network ipv6='yes'> is
+ * specified, then allow IPv6 commuinications between virtual systems.
+ * If any IPv6 addresses are defined, then add the rules for regular operation.
+ */
 static int
 networkAddGeneralIp6tablesRules(struct network_driver *driver,
                                virNetworkObjPtr network)
 {
 
-    if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0))
+    if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0) &&
+                !network->def->ipv6nogw)
         return 0;
 
     /* Catch all rules to block forwarding to/from bridges */
@@ -1653,6 +1658,10 @@ networkAddGeneralIp6tablesRules(struct network_driver *driver,
         goto err3;
     }
 
+    /* if no IPv6 addresses are defined, we are done. */
+    if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0))
+        return 0;
+
     /* allow DNS over IPv6 */
     if (iptablesAddTcpInput(driver->iptables, AF_INET6,
                             network->def->bridge, 53) < 0) {
@@ -1689,11 +1698,17 @@ static void
 networkRemoveGeneralIp6tablesRules(struct network_driver *driver,
                                   virNetworkObjPtr network)
 {
-    if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0))
+    if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0) &&
+                !network->def->ipv6nogw)
         return;
+    if (virNetworkDefGetIpByIndex(network->def, AF_INET6, 0)) {
+        iptablesRemoveUdpInput(driver->iptables, AF_INET6, network->def->bridge, 53);
+        iptablesRemoveTcpInput(driver->iptables, AF_INET6, network->def->bridge, 53);
+    }
 
-    iptablesRemoveUdpInput(driver->iptables, AF_INET6, network->def->bridge, 53);
-    iptablesRemoveTcpInput(driver->iptables, AF_INET6, network->def->bridge, 53);
+    /* the following rules are there if no IPv6 address has been defined
+     * but network->def->ipv6nogw == true
+     */
     iptablesRemoveForwardAllowCross(driver->iptables, AF_INET6, network->def->bridge);
     iptablesRemoveForwardRejectIn(driver->iptables, AF_INET6, network->def->bridge);
     iptablesRemoveForwardRejectOut(driver->iptables, AF_INET6, network->def->bridge);
-- 
1.7.11.7


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