]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: add an attribute to turn on NAT for IPv6 virtual networks
authorDaniel P. Berrangé <berrange@redhat.com>
Mon, 8 Jun 2020 13:35:02 +0000 (14:35 +0100)
committerDaniel P. Berrangé <berrange@redhat.com>
Mon, 15 Jun 2020 16:10:15 +0000 (17:10 +0100)
Historically IPv6 did not support NAT, so when IPv6 was added to
libvirt's virtual networks, when requesting <forward mode="nat"/>
libvirt will NOT apply NAT to IPv6 traffic, only IPv4 traffic.

This is an annoying historical design decision as it means we
cannot enable IPv6 automatically. We thus need to introduce a
new attribute

   <forward mode="nat">
     <nat ipv6="yes"/>
   </forward>

Reviewed-by: Laine Stump <laine@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
docs/formatnetwork.html.in
docs/schemas/network.rng
src/conf/network_conf.c
src/conf/network_conf.h
tests/networkxml2xmlin/nat-network-forward-nat-ipv6.xml [new file with mode: 0644]
tests/networkxml2xmlout/nat-network-forward-nat-ipv6.xml [new file with mode: 0644]
tests/networkxml2xmltest.c

index 0383e2d891aecbc94ad96c68c26c89cc824ca4dd..fb740111b143ab530d65c213ceda96c46729e67c 100644 (file)
     &lt;/nat&gt;
   &lt;/forward&gt;
 ...</pre>
+
+            <p>
+              <span class="since">Since 6.5.0</span> it is possible to
+              enable NAT with IPv6 networking. As noted above, IPv6
+              has historically done plain forwarding and thus to avoid
+              breaking historical compatibility, IPv6 NAT must be
+              explicitly requested.
+            </p>
+            <pre>
+...
+  &lt;forward mode='nat'&gt;
+    &lt;nat ipv6='yes'/&gt;
+  &lt;/forward&gt;
+...</pre>
           </dd>
 
           <dt><code>route</code></dt>
index 88b6f4dfdd0c4dd8d2af550af35a1e2a5963fcb9..3a5eb3ced4be3d34d74df3c36148413a83206d0f 100644 (file)
               </optional>
               <optional>
                 <element name='nat'>
+                  <optional>
+                    <attribute name="ipv6">
+                      <ref name="virYesNo"/>
+                    </attribute>
+                  </optional>
                   <interleave>
                     <optional>
                       <element name='address'>
index f1d22b25b12b4e1504e3592747edd88b25d4e00f..caccc6b1b9881010eda2c306d80abfbd0c5df277 100644 (file)
@@ -1358,6 +1358,7 @@ virNetworkForwardNatDefParseXML(const char *networkName,
     int nNatAddrs, nNatPorts;
     char *addrStart = NULL;
     char *addrEnd = NULL;
+    char *ipv6 = NULL;
     VIR_XPATH_NODE_AUTORESTORE(ctxt);
 
     ctxt->node = node;
@@ -1369,6 +1370,21 @@ virNetworkForwardNatDefParseXML(const char *networkName,
         goto cleanup;
     }
 
+    ipv6 = virXMLPropString(node, "ipv6");
+    if (ipv6) {
+        int natIPv6;
+        if ((natIPv6 = virTristateBoolTypeFromString(ipv6)) <= 0) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("Invalid ipv6 setting '%s' "
+                             "in network '%s' NAT"),
+                           ipv6, networkName);
+            VIR_FREE(ipv6);
+            goto cleanup;
+        }
+        def->natIPv6 = natIPv6;
+        VIR_FREE(ipv6);
+    }
+
     /* addresses for SNAT */
     nNatAddrs = virXPathNodeSet("./address", ctxt, &natAddrNodes);
     if (nNatAddrs < 0) {
@@ -2516,10 +2532,18 @@ virNetworkForwardNatDefFormat(virBufferPtr buf,
             goto cleanup;
     }
 
-    if (!addrEnd && !addrStart && !fwd->port.start && !fwd->port.end)
+    if (!addrEnd && !addrStart && !fwd->port.start && !fwd->port.end && !fwd->natIPv6)
         return 0;
 
-    virBufferAddLit(buf, "<nat>\n");
+    virBufferAddLit(buf, "<nat");
+    if (fwd->natIPv6)
+        virBufferAsprintf(buf, " ipv6='%s'", virTristateBoolTypeToString(fwd->natIPv6));
+
+    if (!addrEnd && !addrStart && !fwd->port.start && !fwd->port.end) {
+        virBufferAddLit(buf, "/>\n");
+        return 0;
+    }
+    virBufferAddLit(buf, ">\n");
     virBufferAdjustIndent(buf, 2);
 
     if (addrStart) {
@@ -2627,7 +2651,8 @@ virNetworkDefFormatBuf(virBufferPtr buf,
                          || def->forward.port.start
                          || def->forward.port.end
                          || (def->forward.driverName
-                             != VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT));
+                             != VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT)
+                         || def->forward.natIPv6);
         virBufferAsprintf(buf, "%s>\n", shortforward ? "/" : "");
         virBufferAdjustIndent(buf, 2);
 
index f2dc388ef0997d3d6b496a985a1ac07adaf8ee43..e3a61c62eae640b0e34ab1c61ecfebee4ab472b6 100644 (file)
@@ -244,6 +244,8 @@ struct _virNetworkForwardDef {
     /* ranges for NAT */
     virSocketAddrRange addr;
     virPortRange port;
+
+    virTristateBool natIPv6;
 };
 
 typedef struct _virPortGroupDef virPortGroupDef;
diff --git a/tests/networkxml2xmlin/nat-network-forward-nat-ipv6.xml b/tests/networkxml2xmlin/nat-network-forward-nat-ipv6.xml
new file mode 100644 (file)
index 0000000..c360941
--- /dev/null
@@ -0,0 +1,10 @@
+<network>
+  <name>default</name>
+  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+  <bridge name="virbr0"/>
+  <forward mode="nat">
+    <nat ipv6="yes"/>
+  </forward>
+  <ip family="ipv6" address="2001:db8:ac10:fe01::1" prefix="64">
+  </ip>
+</network>
diff --git a/tests/networkxml2xmlout/nat-network-forward-nat-ipv6.xml b/tests/networkxml2xmlout/nat-network-forward-nat-ipv6.xml
new file mode 100644 (file)
index 0000000..cfec391
--- /dev/null
@@ -0,0 +1,10 @@
+<network>
+  <name>default</name>
+  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+  <forward mode='nat'>
+    <nat ipv6='yes'/>
+  </forward>
+  <bridge name='virbr0' stp='on' delay='0'/>
+  <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
+  </ip>
+</network>
index 700744785a74d85fea91f7831ccef4cf0bb70c89..17817418b7b351a44d24c1eb96898f9a5e116a4f 100644 (file)
@@ -140,6 +140,7 @@ mymain(void)
     DO_TEST("nat-network-dns-forward-plain");
     DO_TEST("nat-network-dns-forwarders");
     DO_TEST("nat-network-dns-forwarder-no-resolv");
+    DO_TEST("nat-network-forward-nat-ipv6");
     DO_TEST("nat-network-forward-nat-address");
     DO_TEST("nat-network-forward-nat-no-address");
     DO_TEST("nat-network-mtu");