[libvirt] [PATCH 2/3] Add a "forward family" option
Michal Privoznik
mprivozn at redhat.com
Mon Oct 15 14:54:32 UTC 2012
On 15.10.2012 12:27, Benjamin Cama wrote:
> 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(-)
When you introduce new feature to XML schema, you must update
docs/schemas/*.rng and docs/format*.html.in
>
> 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);
%s/virNetworkReportError/virReportError/
> + VIR_FREE(forwardFamily);
> + goto error;
> + }
> + VIR_FREE(forwardFamily);
> + } else {
> + def->forwardFamily = AF_UNSPEC;
> + }
> +
Usually, we create an enum for this and use vir.*TypeFromString() and
vir.*TypeToString();
> 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) {
useless 'if'.
> + 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);
Here is the best place for vir.*TypeToString().
> 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.
>
Michal
More information about the libvir-list
mailing list