[libvirt] [PATCH 2/3] Add a "forward family" option

Benjamin Cama benjamin.cama at telecom-bretagne.eu
Mon Oct 15 10:27:04 UTC 2012


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






More information about the libvir-list mailing list