]> xenbits.xensource.com Git - libvirt.git/commitdiff
Added patches for routed networking from Mads Chr. Olesen
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 28 Mar 2008 20:38:21 +0000 (20:38 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 28 Mar 2008 20:38:21 +0000 (20:38 +0000)
AUTHORS
ChangeLog
docs/network.rng
src/iptables.c
src/iptables.h
src/qemu_conf.c
src/qemu_conf.h
src/qemu_driver.c

diff --git a/AUTHORS b/AUTHORS
index 1c570bcb5cb9437cc85a046a755c444f854f5363..b4e9c9d653eca1651df4e0ce054ebcb9627416db 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -40,6 +40,7 @@ Patches have also been contributed by:
   Chris Lalancette     <clalance@redhat.com>
   Guido Guenther       <agx@sigxcpu.org>
   Daniel Hokka Zakrisson <daniel@hozac.com>
+  Mads Chr. Olesen     <shiyee@shiyee.dk>
 
   [....send patches to get your name here....]
 
index ff060ad6727327ff1d2545fc9d2d8fe4a0010d5c..77375a340b540296c6f719cf415f2e31e6ee5692 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,14 @@
-Fri Mar 27 13:55:56 EDT 2008 Daniel P. Berrange <berrange@redhat.com>
+Fri Mar 28 16:34:56 EDT 2008 Daniel P. Berrange <berrange@redhat.com>
+
+       * src/network.rng: Add new routed networking schema
+       * src/iptables.c, src/iptables.h: Add iptablesAddForwardAllowRelatedIn
+       and iptablesRemoveForwardAllowRelatedIn
+       * src/qemu_conf.h: Add attribute for routed networking
+       * src/qemu_conf.c: Parse / format new networking attributes
+       * src/qemu_driver.c: Support routed networking config
+       (patches from Mads Chr. Olesen)
+       
+Fri Mar 28 13:55:56 EDT 2008 Daniel P. Berrange <berrange@redhat.com>
 
        * src/storage_conf.c: Fix XML output tag for FS storage pools
        directory path
index a3a4b88367469a7230760c0e93e9bb269808b9e2..d84bb2d01f417a83e46e4da16d3c19505a57de25 100644 (file)
          rest of the network -->
     <element name="forward">
       <optional><attribute name="dev"><text/></attribute></optional>
+      <optional>
+        <attribute name="mode">
+          <choice>
+            <value>nat</value>
+            <value>routed</value>
+          </choice>
+        </attribute>
+      </optional>
     </element>
   </optional>
 </element>
index 6390e49c6bd6653500a3261c4f8d4f5e00b493c9..c08a00e74c3fd0ad63840fa55610f8689f6e31c2 100644 (file)
@@ -793,7 +793,7 @@ iptablesRemoveForwardAllowOut(iptablesContext *ctx,
  * and associated with an existing connection
  */
 static int
-iptablesForwardAllowIn(iptablesContext *ctx,
+iptablesForwardAllowRelatedIn(iptablesContext *ctx,
                        const char *network,
                        const char *iface,
                        const char *physdev,
@@ -821,6 +821,77 @@ iptablesForwardAllowIn(iptablesContext *ctx,
     }
 }
 
+/**
+ * iptablesAddForwardAllowRelatedIn:
+ * @ctx: pointer to the IP table context
+ * @network: the source network name
+ * @iface: the output interface name
+ * @physdev: the physical input device or NULL
+ *
+ * Add rules to the IP table context to allow the traffic for the
+ * network @network on @physdev device to be forwarded to
+ * interface @iface, if it is part of an existing connection.
+ *
+ * Returns 0 in case of success or an error code otherwise
+ */
+int
+iptablesAddForwardAllowRelatedIn(iptablesContext *ctx,
+                          const char *network,
+                          const char *iface,
+                          const char *physdev)
+{
+    return iptablesForwardAllowRelatedIn(ctx, network, iface, physdev, ADD);
+}
+
+/**
+ * iptablesRemoveForwardAllowRelatedIn:
+ * @ctx: pointer to the IP table context
+ * @network: the source network name
+ * @iface: the output interface name
+ * @physdev: the physical input device or NULL
+ *
+ * Remove rules from the IP table context hence forbidding the traffic for
+ * network @network on @physdev device to be forwarded to
+ * interface @iface, if it is part of an existing connection.
+ *
+ * Returns 0 in case of success or an error code otherwise
+ */
+int
+iptablesRemoveForwardAllowRelatedIn(iptablesContext *ctx,
+                             const char *network,
+                             const char *iface,
+                             const char *physdev)
+{
+    return iptablesForwardAllowRelatedIn(ctx, network, iface, physdev, REMOVE);
+}
+
+/* Allow all traffic destined to the bridge, with a valid network address
+ */
+static int
+iptablesForwardAllowIn(iptablesContext *ctx,
+                       const char *network,
+                       const char *iface,
+                       const char *physdev,
+                       int action)
+{
+    if (physdev && physdev[0]) {
+        return iptablesAddRemoveRule(ctx->forward_filter,
+                                     action,
+                                     "--destination", network,
+                                     "--in-interface", physdev,
+                                     "--out-interface", iface,
+                                     "--jump", "ACCEPT",
+                                     NULL);
+    } else {
+        return iptablesAddRemoveRule(ctx->forward_filter,
+                                     action,
+                                     "--destination", network,
+                                     "--out-interface", iface,
+                                     "--jump", "ACCEPT",
+                                     NULL);
+    }
+}
+
 /**
  * iptablesAddForwardAllowIn:
  * @ctx: pointer to the IP table context
index 6fe017428e9a64e1294626e9a10c82c1200ad4a9..e33513ec1ab5c55db9b6eb7a0f49ff59946ce061 100644 (file)
@@ -55,6 +55,15 @@ int              iptablesRemoveForwardAllowOut   (iptablesContext *ctx,
                                                   const char *iface,
                                                   const char *physdev);
 
+int              iptablesAddForwardAllowRelatedIn(iptablesContext *ctx,
+                                                  const char *network,
+                                                  const char *iface,
+                                                  const char *physdev);
+int              iptablesRemoveForwardAllowRelatedIn(iptablesContext *ctx,
+                                                  const char *network,
+                                                  const char *iface,
+                                                  const char *physdev);
+
 int              iptablesAddForwardAllowIn       (iptablesContext *ctx,
                                                   const char *network,
                                                   const char *iface,
index bafea8c9fdc8181e4147678cbc9c3d65e3a6e080..6ff0852f3733b79bca4ec5c92f526d221cfb371b 100644 (file)
@@ -2521,6 +2521,17 @@ static struct qemud_network_def *qemudParseNetworkXML(virConnectPtr conn,
         }
 
         def->forward = 1;
+
+        tmp = xmlXPathEval(BAD_CAST "string(/network/forward[1]/@mode)", ctxt);
+        if ((tmp != NULL) && (tmp->type == XPATH_STRING) &&
+            (tmp->stringval != NULL) && (xmlStrEqual(tmp->stringval, BAD_CAST "route"))) {
+            def->forwardMode = QEMUD_NET_FORWARD_ROUTE;
+        } else {
+            def->forwardMode = QEMUD_NET_FORWARD_NAT;
+        }
+        xmlXPathFreeObject(tmp);
+        tmp = NULL;
+
         tmp = xmlXPathEval(BAD_CAST "string(/network/forward[1]/@dev)", ctxt);
         if ((tmp != NULL) && (tmp->type == XPATH_STRING) &&
             (tmp->stringval != NULL) && (tmp->stringval[0] != 0)) {
@@ -3160,10 +3171,10 @@ char *qemudGenerateNetworkXML(virConnectPtr conn,
 
     if (def->forward) {
         if (def->forwardDev[0]) {
-            virBufferVSprintf(buf, "  <forward dev='%s'/>\n",
-                              def->forwardDev);
+            virBufferVSprintf(buf, "  <forward dev='%s' mode='%s'/>\n",
+                              def->forwardDev, (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat"));
         } else {
-            virBufferAddLit(buf, "  <forward/>\n");
+            virBufferVSprintf(buf, "  <forward mode='%s'/>\n", (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat"));
         }
     }
 
index c1aae7565118ae6589ba966fa5dfa3c54b8bde36..f52b359b43bbf46fe918eb30b878d9246f25bc79 100644 (file)
@@ -83,6 +83,12 @@ enum qemud_vm_net_type {
     QEMUD_NET_BRIDGE,
 };
 
+/* 2 possible types of forwarding */
+enum qemud_vm_net_forward_type {
+    QEMUD_NET_FORWARD_NAT,
+    QEMUD_NET_FORWARD_ROUTE,
+};
+
 #define QEMUD_MAX_NAME_LEN 50
 #define QEMUD_MAX_XML_LEN 4096
 #define QEMUD_MAX_ERROR_LEN 1024
@@ -266,6 +272,7 @@ struct qemud_network_def {
     int forwardDelay;
 
     int forward;
+    int forwardMode; /* From qemud_vm_net_forward_type */
     char forwardDev[BR_IFNAME_MAXLEN];
 
     char ipAddress[BR_INET_ADDR_MAXLEN];
index d68f0791c0b0999144997e7048e570ad653a8f2c..3c6a18dd46e2ad0a130a4cf5898edb6d43775654 100644 (file)
@@ -948,6 +948,98 @@ dhcpStartDhcpDaemon(virConnectPtr conn,
     return ret;
 }
 
+static int
+qemudAddMasqueradingIptablesRules(virConnectPtr conn,
+                      struct qemud_driver *driver,
+                      struct qemud_network *network) {
+    int err;
+    /* allow forwarding packets from the bridge interface */
+    if ((err = iptablesAddForwardAllowOut(driver->iptables,
+                                          network->def->network,
+                                          network->bridge,
+                                          network->def->forwardDev))) {
+        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to allow forwarding from '%s' : %s\n"),
+                         network->bridge, strerror(err));
+        goto masqerr1;
+    }
+
+    /* allow forwarding packets to the bridge interface if they are part of an existing connection */
+    if ((err = iptablesAddForwardAllowRelatedIn(driver->iptables,
+                                         network->def->network,
+                                         network->bridge,
+                                         network->def->forwardDev))) {
+        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to allow forwarding to '%s' : %s\n"),
+                         network->bridge, strerror(err));
+        goto masqerr2;
+    }
+
+    /* enable masquerading */
+    if ((err = iptablesAddForwardMasquerade(driver->iptables,
+                                            network->def->network,
+                                            network->def->forwardDev))) {
+        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to enable masquerading : %s\n"),
+                         strerror(err));
+        goto masqerr3;
+    }
+
+    return 1;
+
+ masqerr3:
+    iptablesRemoveForwardAllowRelatedIn(driver->iptables,
+                                 network->def->network,
+                                 network->bridge,
+                                 network->def->forwardDev);
+ masqerr2:
+    iptablesRemoveForwardAllowOut(driver->iptables,
+                                  network->def->network,
+                                  network->bridge,
+                                  network->def->forwardDev);
+ masqerr1:
+    return 0;
+}
+
+static int
+qemudAddRoutingIptablesRules(virConnectPtr conn,
+                      struct qemud_driver *driver,
+                      struct qemud_network *network) {
+    int err;
+    /* allow routing packets from the bridge interface */
+    if ((err = iptablesAddForwardAllowOut(driver->iptables,
+                                          network->def->network,
+                                          network->bridge,
+                                          network->def->forwardDev))) {
+        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to allow routing from '%s' : %s\n"),
+                         network->bridge, strerror(err));
+        goto routeerr1;
+    }
+
+    /* allow routing packets to the bridge interface */
+    if ((err = iptablesAddForwardAllowIn(driver->iptables,
+                                         network->def->network,
+                                         network->bridge,
+                                         network->def->forwardDev))) {
+        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to allow routing to '%s' : %s\n"),
+                         network->bridge, strerror(err));
+        goto routeerr2;
+    }
+
+    return 1;
+
+
+ routeerr2:
+    iptablesRemoveForwardAllowOut(driver->iptables,
+                                  network->def->network,
+                                  network->bridge,
+                                  network->def->forwardDev);
+ routeerr1:
+    return 0;
+}
+
 static int
 qemudAddIptablesRules(virConnectPtr conn,
                       struct qemud_driver *driver,
@@ -1023,53 +1115,17 @@ qemudAddIptablesRules(virConnectPtr conn,
         return 1;
     }
 
-    /* allow forwarding packets from the bridge interface */
-    if ((err = iptablesAddForwardAllowOut(driver->iptables,
-                                          network->def->network,
-                                          network->bridge,
-                                          network->def->forwardDev))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow forwarding from '%s' : %s"),
-                         network->bridge, strerror(err));
-        goto err8;
-    }
-
-    /* allow forwarding packets to the bridge interface if they are part of an existing connection */
-    if ((err = iptablesAddForwardAllowIn(driver->iptables,
-                                         network->def->network,
-                                         network->bridge,
-                                         network->def->forwardDev))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow forwarding to '%s' : %s"),
-                         network->bridge, strerror(err));
-        goto err9;
+    /* If masquerading is enabled, set up the rules*/
+    if (network->def->forwardMode == QEMUD_NET_FORWARD_NAT) {
+        if (qemudAddMasqueradingIptablesRules(conn, driver, network))
+            return 1;
     }
-
-    /* enable masquerading */
-    if ((err = iptablesAddForwardMasquerade(driver->iptables,
-                                            network->def->network,
-                                            network->def->forwardDev))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to enable masquerading : %s"),
-                         strerror(err));
-        goto err10;
+    /* else if routing is enabled, set up the rules*/
+    else if (network->def->forwardMode == QEMUD_NET_FORWARD_ROUTE) {
+        if (qemudAddRoutingIptablesRules(conn, driver, network))
+            return 1;
     }
 
-    iptablesSaveRules(driver->iptables);
-
-    return 1;
-
- err10:
-    iptablesRemoveForwardAllowIn(driver->iptables,
-                                 network->def->network,
-                                 network->bridge,
-                                 network->def->forwardDev);
- err9:
-    iptablesRemoveForwardAllowOut(driver->iptables,
-                                  network->def->network,
-                                  network->bridge,
-                                  network->def->forwardDev);
- err8:
     iptablesRemoveForwardAllowCross(driver->iptables,
                                     network->bridge);
  err7: