søn, 09 03 2008 kl. 21:09 +0000, skrev Daniel P. Berrange: > On Sat, Mar 08, 2008 at 04:33:32PM +0100, Mads Chr. Olesen wrote: > > I have added a <route dev="ethX" /> stanza (dev is optional), completely > > equivalent to the <forward /> stanza. > > This is still forwarding of traffic, so I think we should just use the > existing <forward/> element and have an extra attribute to indiciate > the type of forwarding, eg > > <forward/> (defaults to mode="nat" for compat) > <forward mode="nat"/> > <forward mode="route"/> > <forward mode="nat" dev="ethX"/> > <forward mode="route" dev="ethX"/> Sure, makes sense - an updated patch is attached. > I'm a little unclear on how this actually works. You add iptables rules to > allow traffic in/out, but you're not adding any routing table entries, nor > turning on proxy_arp, so I don't see how this will actually work in practice. > > Are you assuming the admin has already added suitable routing rules & turned > on proxy arp ? Well, in my case (dedicated server, hetzner.de) this is all that is needed. My physical interface has IP 85.10.XXX.XXX, and then I have a secondary IP range which gets routed at that interface, IP range 78.47.YYY.YYY/30. I then setup my virtual interface with an IP in that range, by setting <ip address="78.47.YYY.YYY" netmask="255.255.255.248" /> Thus, to get packets routed at the virtual machines, it just needs to be allowed by iptables, and /proc/sys/net/ipv4/ip_forward needs to be set to 1. Other setups obviously might need more work. -- Mads Chr. Olesen <shiyee@xxxxxxxxx> shiyee.dk
? routed-virtual-net.cvs.patch ? routed-virtual-net.cvs.patch2 ? docs/.network.rng.swp ? src/.iptables.c.swp ? src/.iptables.h.swp ? src/.qemu_conf.c.swp ? src/.qemu_conf.h.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 10 Mar 2008 20:51:19 -0000 @@ -56,6 +56,14 @@ 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: 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 10 Mar 2008 20:51:22 -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/iptables.h =================================================================== RCS file: /data/cvs/libvirt/src/iptables.h,v retrieving revision 1.3 diff -u -r1.3 iptables.h --- src/iptables.h 10 Jan 2008 14:01:00 -0000 1.3 +++ src/iptables.h 10 Mar 2008 20:51:23 -0000 @@ -55,6 +55,15 @@ 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: 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 10 Mar 2008 20:51:31 -0000 @@ -2451,6 +2451,17 @@ } 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)) { @@ -3085,10 +3096,10 @@ 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: 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 10 Mar 2008 20:51:32 -0000 @@ -83,6 +83,12 @@ 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 @@ int forwardDelay; int forward; + int forwardMode; /* From qemud_vm_net_forward_type */ char forwardDev[BR_IFNAME_MAXLEN]; char ipAddress[BR_INET_ADDR_MAXLEN]; 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 10 Mar 2008 20:51:40 -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->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, struct qemud_network *network) { @@ -1021,52 +1113,17 @@ 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; - } - - /* 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; + /* If masquerading is enabled, set up the rules*/ + if (network->def->forwardMode == QEMUD_NET_FORWARD_NAT) { + if (qemudAddMasqueradingIptablesRules(conn, driver, network)) + return 1; + } + /* 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);
-- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list