It allows to specify forwarding only for IPv4 or IPv6. Not specifying it enables forwarding for both protocols. --- src/conf/network_conf.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++- src/conf/network_conf.h | 1 + 2 files changed, 58 insertions(+), 1 deletions(-) diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 891d48c..8c2ae9b 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -1204,6 +1204,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) xmlNodePtr virtPortNode = NULL; xmlNodePtr forwardNode = NULL; int nIps, nPortGroups, nForwardIfs, nForwardPfs, nForwardAddrs; + char *forwardFamily = NULL; char *forwardDev = NULL; char *forwardManaged = NULL; char *type = NULL; @@ -1358,6 +1359,23 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) def->forwardType = VIR_NETWORK_FORWARD_NAT; } + forwardFamily = virXPathString("string(./@family)", ctxt); + if (forwardFamily) { + if (STREQ(forwardFamily, "ipv4")) { + def->forwardFamily = AF_INET; + } else if (STREQ(forwardFamily, "ipv6")) { + def->forwardFamily = AF_INET6; + } else { + virNetworkReportError(VIR_ERR_XML_ERROR, + _("Unknown forward family '%s'"), forwardFamily); + VIR_FREE(forwardFamily); + goto error; + } + VIR_FREE(forwardFamily); + } else { + def->forwardFamily = AF_UNSPEC; + } + forwardDev = virXPathString("string(./@dev)", ctxt); forwardManaged = virXPathString("string(./@managed)", ctxt); if(forwardManaged != NULL) { @@ -1515,8 +1533,16 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) VIR_FREE(forwardIfNodes); VIR_FREE(forwardAddrNodes); switch (def->forwardType) { - case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_NAT: + if (def->forwardFamily == AF_INET6) { + virNetworkReportError(VIR_ERR_XML_ERROR, + _("%s forwarding is not allowed in IPv6 (network '%s')"), + virNetworkForwardTypeToString(def->forwardType), + def->name); + goto error; + } + /* fall through to next case */ + case VIR_NETWORK_FORWARD_ROUTE: /* It's pointless to specify L3 forwarding without specifying * the network we're on. */ @@ -1527,6 +1553,25 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) def->name); goto error; } + /* If forwarding for one family only, an address from this family + * must be present + */ + if (def->forwardFamily) { + int ii; + for (ii = 0; ii < def->nips; ii++) { + if (VIR_SOCKET_ADDR_IS_FAMILY(&def->ips[ii].address, def->forwardFamily)) + break; + } + if (ii == def->nips) { + char ipVersion = def->forwardFamily == AF_INET6 ? '6' : '4'; + virNetworkReportError(VIR_ERR_XML_ERROR, + _("%s IPv%c forwarding requested, but no IPv%c address provided for network '%s'"), + virNetworkForwardTypeToString(def->forwardType), + ipVersion, ipVersion, + def->name); + goto error; + } + } if (def->nForwardIfs > 1) { virReportError(VIR_ERR_XML_ERROR, _("multiple forwarding interfaces specified for network '%s', only one is supported"), @@ -1555,6 +1600,13 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) def->name); goto error; } + if (def->forwardFamily) { + virNetworkReportError(VIR_ERR_XML_ERROR, + _("bridge forward family option only allowed in route and nat mode, not in %s (network '%s')"), + virNetworkForwardTypeToString(def->forwardType), + def->name); + goto error; + } break; } } @@ -1830,6 +1882,8 @@ char *virNetworkDefFormat(const virNetworkDefPtr def, unsigned int flags) if (!def->nForwardPfs) dev = virNetworkDefForwardIf(def, 0); const char *mode = virNetworkForwardTypeToString(def->forwardType); + const char *family = (def->forwardFamily == AF_INET ? "ipv4" : + def->forwardFamily == AF_INET6 ? "ipv6" : NULL); if (!mode) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -1846,6 +1900,8 @@ char *virNetworkDefFormat(const virNetworkDefPtr def, unsigned int flags) else virBufferAddLit(&buf, " managed='no'"); } + if (family) + virBufferEscapeString(&buf, " family='%s'", family); virBufferAsprintf(&buf, "%s>\n", (def->nForwardIfs || def->nForwardPfs) ? "" : "/"); virBufferAdjustIndent(&buf, 2); diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 55502fb..61ecbc1 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -186,6 +186,7 @@ struct _virNetworkDef { int forwardType; /* One of virNetworkForwardType constants */ int managed; /* managed attribute for hostdev mode */ + int forwardFamily; /* AF_INET or AF_INET6 - AF_UNSPEC for both */ /* If there are multiple forward devices (i.e. a pool of * interfaces), they will be listed here. -- 1.7.2.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list