lør, 08 03 2008 kl. 16:33 +0100, skrev Mads Chr. Olesen:
> The attached patch adds support for having routed virtual networks, in
> addition to the masquerading setup possible with the "<forward />"
> stanza.
Just found a small error, now it actually compiles.
--
Mads Chr. Olesen <[EMAIL PROTECTED]>
shiyee.dk
? routed-virtual-net.cvs.patch
? src/.qemu_conf.c.swp
? src/.qemu_driver.c.swp
Index: docs/network.rng
===================================================================
RCS file: /data/cvs/libvirt/docs/network.rng,v
retrieving revision 1.1
diff -u -r1.1 network.rng
--- docs/network.rng 24 Jul 2007 09:19:40 -0000 1.1
+++ docs/network.rng 8 Mar 2008 18:59:13 -0000
@@ -58,4 +58,11 @@
<optional><attribute name="dev"><text/></attribute></optional>
</element>
</optional>
+ <optional>
+ <!-- The device through which the bridge is to be routed -->
+ <element name="route">
+ <optional><attribute name="dev"><text/></attribute></optional>
+ </element>
+ </optional>
+
</element>
Index: src/iptables.c
===================================================================
RCS file: /data/cvs/libvirt/src/iptables.c,v
retrieving revision 1.23
diff -u -r1.23 iptables.c
--- src/iptables.c 27 Feb 2008 10:37:19 -0000 1.23
+++ src/iptables.c 8 Mar 2008 18:59:43 -0000
@@ -793,7 +793,7 @@
* and associated with an existing connection
*/
static int
-iptablesForwardAllowIn(iptablesContext *ctx,
+iptablesForwardAllowRelatedIn(iptablesContext *ctx,
const char *network,
const char *iface,
const char *physdev,
@@ -822,6 +822,77 @@
}
/**
+ * 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
* @network: the source network name
Index: src/qemu_conf.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_conf.c,v
retrieving revision 1.41
diff -u -r1.41 qemu_conf.c
--- src/qemu_conf.c 3 Mar 2008 18:11:16 -0000 1.41
+++ src/qemu_conf.c 8 Mar 2008 18:59:51 -0000
@@ -2472,6 +2472,41 @@
}
xmlXPathFreeObject(obj);
+ /* IPv4 routing setup */
+ obj = xmlXPathEval(BAD_CAST "count(/network/route) > 0", ctxt);
+ if ((obj != NULL) && (obj->type == XPATH_BOOLEAN) &&
+ obj->boolval) {
+ if (!def->ipAddress[0] ||
+ !def->netmask[0] ||
+ def->forward) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ "Routing requested, but no IPv4 address/netmask provided, or forwarding already enabled");
+ goto error;
+ }
+
+ def->route = 1;
+ tmp = xmlXPathEval(BAD_CAST "string(/network/route[1]/@dev)", ctxt);
+ if ((tmp != NULL) && (tmp->type == XPATH_STRING) &&
+ (tmp->stringval != NULL) && (tmp->stringval[0] != 0)) {
+ int len;
+ if ((len = xmlStrlen(tmp->stringval)) >= (BR_IFNAME_MAXLEN-1)) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ "route device name '%s' is too long",
+ (char*)tmp->stringval);
+ goto error;
+ }
+ strcpy(def->routeDev, (char*)tmp->stringval);
+ } else {
+ def->routeDev[0] = '\0';
+ }
+ xmlXPathFreeObject(tmp);
+ tmp = NULL;
+ } else {
+ def->route = 0;
+ }
+ xmlXPathFreeObject(obj);
+
+
xmlXPathFreeContext(ctxt);
return def;
@@ -3092,6 +3127,15 @@
}
}
+ if (def->route) {
+ if (def->routeDev[0]) {
+ virBufferVSprintf(buf, " <route dev='%s'/>\n",
+ def->routeDev);
+ } else {
+ virBufferAddLit(buf, " <route/>\n");
+ }
+ }
+
virBufferAddLit(buf, " <bridge");
if (qemudIsActiveNetwork(network)) {
if (virBufferVSprintf(buf, " name='%s'", network->bridge) < 0)
Index: src/qemu_conf.h
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_conf.h,v
retrieving revision 1.19
diff -u -r1.19 qemu_conf.h
--- src/qemu_conf.h 27 Feb 2008 04:35:08 -0000 1.19
+++ src/qemu_conf.h 8 Mar 2008 18:59:52 -0000
@@ -268,6 +268,9 @@
int forward;
char forwardDev[BR_IFNAME_MAXLEN];
+ int route;
+ char routeDev[BR_IFNAME_MAXLEN];
+
char ipAddress[BR_INET_ADDR_MAXLEN];
char netmask[BR_INET_ADDR_MAXLEN];
char network[BR_INET_ADDR_MAXLEN+BR_INET_ADDR_MAXLEN+1];
Index: src/qemu_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_driver.c,v
retrieving revision 1.57
diff -u -r1.57 qemu_driver.c
--- src/qemu_driver.c 27 Feb 2008 04:37:07 -0000 1.57
+++ src/qemu_driver.c 8 Mar 2008 18:59:59 -0000
@@ -948,6 +948,98 @@
}
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->routeDev))) {
+ 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->routeDev))) {
+ 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,
struct qemud_network *network) {
@@ -1014,59 +1106,19 @@
goto err7;
}
-
- /* The remaining rules are only needed for IP forwarding */
- if (!network->def->forward) {
- iptablesSaveRules(driver->iptables);
- 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\n",
- 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\n",
- network->bridge, strerror(err));
- goto err9;
+ /* If masquerading is enabled, set up the rules*/
+ if (network->def->forward) {
+ 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\n",
- strerror(err));
- goto err10;
+ /* else if routing is enabled, set up the rules*/
+ else if (network->def->route) {
+ if (qemudAddRoutingIptablesRules(conn, driver, network))
+ return 1;
}
+ else
+ 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);
@@ -1208,7 +1260,7 @@
if (!qemudAddIptablesRules(conn, driver, network))
goto err_delbr1;
- if (network->def->forward &&
+ if ((network->def->forward || network->def->route) &&
!qemudEnableIpForwarding()) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"failed to enable IP forwarding : %s\n", strerror(err));
--
Libvir-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list