* and associated with an existing connection
*/
static int
-iptablesForwardAllowIn(iptablesContext *ctx,
+iptablesForwardAllowRelatedIn(iptablesContext *ctx,
const char *network,
const char *iface,
const char *physdev,
}
}
+/**
+ * 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
}
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)) {
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"));
}
}
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,
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: