From 927acaedec7effbe67a154d8bfa0e67f7d08e6c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Mon, 8 Jun 2020 14:35:02 +0100 Subject: [PATCH] conf: add an attribute to turn on NAT for IPv6 virtual networks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Historically IPv6 did not support NAT, so when IPv6 was added to libvirt's virtual networks, when requesting 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 Reviewed-by: Laine Stump Signed-off-by: Daniel P. Berrangé --- docs/formatnetwork.html.in | 14 +++++++++ docs/schemas/network.rng | 5 +++ src/conf/network_conf.c | 31 +++++++++++++++++-- src/conf/network_conf.h | 2 ++ .../nat-network-forward-nat-ipv6.xml | 10 ++++++ .../nat-network-forward-nat-ipv6.xml | 10 ++++++ tests/networkxml2xmltest.c | 1 + 7 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 tests/networkxml2xmlin/nat-network-forward-nat-ipv6.xml create mode 100644 tests/networkxml2xmlout/nat-network-forward-nat-ipv6.xml diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index 0383e2d891..fb740111b1 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -276,6 +276,20 @@ </nat> </forward> ... + +

+ Since 6.5.0 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. +

+
+...
+  <forward mode='nat'>
+    <nat ipv6='yes'/>
+  </forward>
+...
route
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng index 88b6f4dfdd..3a5eb3ced4 100644 --- a/docs/schemas/network.rng +++ b/docs/schemas/network.rng @@ -181,6 +181,11 @@ + + + + + diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index f1d22b25b1..caccc6b1b9 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -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, "\n"); + virBufferAddLit(buf, "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); diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index f2dc388ef0..e3a61c62ea 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -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 index 0000000000..c360941e1e --- /dev/null +++ b/tests/networkxml2xmlin/nat-network-forward-nat-ipv6.xml @@ -0,0 +1,10 @@ + + default + 81ff0d90-c91e-6742-64da-4a736edb9a9b + + + + + + + diff --git a/tests/networkxml2xmlout/nat-network-forward-nat-ipv6.xml b/tests/networkxml2xmlout/nat-network-forward-nat-ipv6.xml new file mode 100644 index 0000000000..cfec391ee2 --- /dev/null +++ b/tests/networkxml2xmlout/nat-network-forward-nat-ipv6.xml @@ -0,0 +1,10 @@ + + default + 81ff0d90-c91e-6742-64da-4a736edb9a9b + + + + + + + diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c index 700744785a..17817418b7 100644 --- a/tests/networkxml2xmltest.c +++ b/tests/networkxml2xmltest.c @@ -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");