diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2012-12-05 11:00:35 +0100 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2012-12-05 11:04:02 +0100 |
commit | 5949f936379d49aee62e08ed7a81b6c61a984a1b (patch) | |
tree | e7de3694da073865c974a4ea724b19dc27bddba8 /main/libvirt | |
parent | 58c9ae525a1d2de4edfc273a4f0ae34448daf3c6 (diff) | |
download | aports-5949f936379d49aee62e08ed7a81b6c61a984a1b.tar.bz2 aports-5949f936379d49aee62e08ed7a81b6c61a984a1b.tar.xz |
main/libvirt: add support for SNAT/publicaddr
Patches sent upstream:
http://www.mail-archive.com/libvir-list@redhat.com/msg67516.html
Diffstat (limited to 'main/libvirt')
3 files changed, 491 insertions, 7 deletions
diff --git a/main/libvirt/0001-net-support-set-public-ip-for-forward-mode-nat.patch b/main/libvirt/0001-net-support-set-public-ip-for-forward-mode-nat.patch new file mode 100644 index 0000000000..831466f950 --- /dev/null +++ b/main/libvirt/0001-net-support-set-public-ip-for-forward-mode-nat.patch @@ -0,0 +1,277 @@ +From da1e7fe01acdaf13b3fb9e3cda53627063014da9 Mon Sep 17 00:00:00 2001 +From: Natanael Copa <ncopa@alpinelinux.org> +Date: Tue, 4 Dec 2012 17:03:51 +0100 +Subject: [PATCH] net: support set public ip for forward mode nat + +Support setting which public ip to use for NAT via attribute +publicaddr. This will construct an iptables line using '-j SNAT +--to-source <publicaddr>' instead of '-j MASQUERADE'. + +Signed-off-by: Natanael Copa <ncopa@alpinelinux.org> +--- + docs/formatnetwork.html.in | 4 +++- + src/conf/network_conf.c | 33 +++++++++++++++++++++++++++++++++ + src/conf/network_conf.h | 1 + + src/network/bridge_driver.c | 24 ++++++++++++++++-------- + src/util/iptables.c | 31 ++++++++++++++++++++++++------- + src/util/iptables.h | 6 ++++-- + 6 files changed, 81 insertions(+), 18 deletions(-) + +diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in +index 49206dd..07f9783 100644 +--- a/docs/formatnetwork.html.in ++++ b/docs/formatnetwork.html.in +@@ -125,7 +125,9 @@ + other network device whether ethernet, wireless, dialup, + or VPN. If the <code>dev</code> attribute is set, the + firewall rules will restrict forwarding to the named +- device only. Inbound connections from other networks are ++ device only. If the <code>publicaddr</code> attribute is set, ++ the given source address will be used with iptables' SNAT ++ target. Inbound connections from other networks are + all prohibited; all connections between guests on the same + network, and to/from the host to the guests, are + unrestricted and not NATed.<span class="since">Since +diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c +index 6ce2e63..36128ac 100644 +--- a/src/conf/network_conf.c ++++ b/src/conf/network_conf.c +@@ -174,6 +174,7 @@ void virNetworkDefFree(virNetworkDefPtr def) + VIR_FREE(def->name); + VIR_FREE(def->bridge); + VIR_FREE(def->domain); ++ VIR_FREE(def->publicaddr); + + for (ii = 0 ; ii < def->nForwardPfs && def->forwardPfs ; ii++) { + virNetworkForwardPfDefClear(&def->forwardPfs[ii]); +@@ -1211,6 +1212,22 @@ error: + return result; + } + ++static int ++virValidPublicaddr(const char *publicaddr) ++{ ++ /* only check for max len and valid chars for now */ ++ const int maxlen = sizeof("123.123.123.123-123.123.123.123:65535-65534")-1; ++ int len = strlen(publicaddr); ++ ++ if (len > maxlen) ++ return 0; ++ ++ if (strspn(publicaddr, "0123456789.-:") < len) ++ return 0; ++ ++ return 1; ++} ++ + static virNetworkDefPtr + virNetworkDefParseXML(xmlXPathContextPtr ctxt) + { +@@ -1387,6 +1404,21 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) + def->managed = 1; + } + ++ def->publicaddr = virXPathString("string(./@publicaddr)", ctxt); ++ if (def->publicaddr != NULL) { ++ char *errstr = NULL; ++ if (def->forwardType != VIR_NETWORK_FORWARD_NAT) { ++ errstr = "Attribute 'publicaddr' is only valid with mode='nat'"; ++ } else if (!virValidPublicaddr(def->publicaddr)) { ++ errstr = "Attribute 'publicaddr' must be in the format: ipaddr[-ipaddr][:port[-port]]"; ++ } ++ ++ if (errstr != NULL) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", _(errstr)); ++ goto error; ++ } ++ } ++ + /* all of these modes can use a pool of physical interfaces */ + nForwardIfs = virXPathNodeSet("./interface", ctxt, &forwardIfNodes); + nForwardPfs = virXPathNodeSet("./pf", ctxt, &forwardPfNodes); +@@ -1861,6 +1893,7 @@ char *virNetworkDefFormat(const virNetworkDefPtr def, unsigned int flags) + } + virBufferAddLit(&buf, "<forward"); + virBufferEscapeString(&buf, " dev='%s'", dev); ++ virBufferEscapeString(&buf, " publicaddr='%s'", def->publicaddr); + virBufferAsprintf(&buf, " mode='%s'", mode); + if (def->forwardType == VIR_NETWORK_FORWARD_HOSTDEV) { + if (def->managed == 1) +diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h +index 3e46304..76fb591 100644 +--- a/src/conf/network_conf.h ++++ b/src/conf/network_conf.h +@@ -206,6 +206,7 @@ struct _virNetworkDef { + virPortGroupDefPtr portGroups; + virNetDevBandwidthPtr bandwidth; + virNetDevVlan vlan; ++ char *publicaddr; + }; + + typedef struct _virNetworkObj virNetworkObj; +diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c +index 75f3c3a..04f178b 100644 +--- a/src/network/bridge_driver.c ++++ b/src/network/bridge_driver.c +@@ -1438,7 +1438,8 @@ networkAddMasqueradingIptablesRules(struct network_driver *driver, + &ipdef->address, + prefix, + forwardIf, +- NULL) < 0) { ++ NULL, ++ network->def->publicaddr) < 0) { + virReportError(VIR_ERR_SYSTEM_ERROR, + forwardIf ? + _("failed to add iptables rule to enable masquerading to %s") : +@@ -1452,7 +1453,8 @@ networkAddMasqueradingIptablesRules(struct network_driver *driver, + &ipdef->address, + prefix, + forwardIf, +- "udp") < 0) { ++ "udp", ++ network->def->publicaddr) < 0) { + virReportError(VIR_ERR_SYSTEM_ERROR, + forwardIf ? + _("failed to add iptables rule to enable UDP masquerading to %s") : +@@ -1466,7 +1468,8 @@ networkAddMasqueradingIptablesRules(struct network_driver *driver, + &ipdef->address, + prefix, + forwardIf, +- "tcp") < 0) { ++ "tcp", ++ network->def->publicaddr) < 0) { + virReportError(VIR_ERR_SYSTEM_ERROR, + forwardIf ? + _("failed to add iptables rule to enable TCP masquerading to %s") : +@@ -1482,13 +1485,15 @@ networkAddMasqueradingIptablesRules(struct network_driver *driver, + &ipdef->address, + prefix, + forwardIf, +- "udp"); ++ "udp", ++ network->def->publicaddr); + masqerr4: + iptablesRemoveForwardMasquerade(driver->iptables, + &ipdef->address, + prefix, + forwardIf, +- NULL); ++ NULL, ++ network->def->publicaddr); + masqerr3: + iptablesRemoveForwardAllowRelatedIn(driver->iptables, + &ipdef->address, +@@ -1518,17 +1523,20 @@ networkRemoveMasqueradingIptablesRules(struct network_driver *driver, + &ipdef->address, + prefix, + forwardIf, +- "tcp"); ++ "tcp", ++ network->def->publicaddr); + iptablesRemoveForwardMasquerade(driver->iptables, + &ipdef->address, + prefix, + forwardIf, +- "udp"); ++ "udp", ++ network->def->publicaddr); + iptablesRemoveForwardMasquerade(driver->iptables, + &ipdef->address, + prefix, + forwardIf, +- NULL); ++ NULL, ++ network->def->publicaddr); + + iptablesRemoveForwardAllowRelatedIn(driver->iptables, + &ipdef->address, +diff --git a/src/util/iptables.c b/src/util/iptables.c +index 407ca3a..4a89673 100644 +--- a/src/util/iptables.c ++++ b/src/util/iptables.c +@@ -804,6 +804,7 @@ iptablesForwardMasquerade(iptablesContext *ctx, + unsigned int prefix, + const char *physdev, + const char *protocol, ++ const char *publicaddr, + int action) + { + int ret; +@@ -833,10 +834,24 @@ iptablesForwardMasquerade(iptablesContext *ctx, + if (physdev && physdev[0]) + virCommandAddArgList(cmd, "--out-interface", physdev, NULL); + +- virCommandAddArgList(cmd, "--jump", "MASQUERADE", NULL); ++ /* Use --jump SNAT if public addr is specified */ ++ if (publicaddr && publicaddr[0]) { ++ char tmpstr[sizeof("123.123.123.123-123.123.123.123:65535-65535")]; ++ const char *portstr = ""; + +- if (protocol && protocol[0]) +- virCommandAddArgList(cmd, "--to-ports", "1024-65535", NULL); ++ memset(tmpstr, 0, sizeof(tmpstr)); ++ if (protocol && protocol[0] && (strchr(publicaddr, ':') == NULL)) ++ portstr = ":1024-65535"; ++ snprintf(tmpstr, sizeof(tmpstr), "%s%s", publicaddr, portstr); ++ ++ virCommandAddArgList(cmd, "--jump", "SNAT", ++ "--to-source", tmpstr, NULL); ++ } else { ++ virCommandAddArgList(cmd, "--jump", "MASQUERADE", NULL); ++ ++ if (protocol && protocol[0]) ++ virCommandAddArgList(cmd, "--to-ports", "1024-65535", NULL); ++ } + + ret = iptablesCommandRunAndFree(cmd); + VIR_FREE(networkstr); +@@ -861,9 +876,10 @@ iptablesAddForwardMasquerade(iptablesContext *ctx, + virSocketAddr *netaddr, + unsigned int prefix, + const char *physdev, +- const char *protocol) ++ const char *protocol, ++ const char *publicaddr) + { +- return iptablesForwardMasquerade(ctx, netaddr, prefix, physdev, protocol, ADD); ++ return iptablesForwardMasquerade(ctx, netaddr, prefix, physdev, protocol, publicaddr, ADD); + } + + /** +@@ -884,9 +900,10 @@ iptablesRemoveForwardMasquerade(iptablesContext *ctx, + virSocketAddr *netaddr, + unsigned int prefix, + const char *physdev, +- const char *protocol) ++ const char *protocol, ++ const char *publicaddr) + { +- return iptablesForwardMasquerade(ctx, netaddr, prefix, physdev, protocol, REMOVE); ++ return iptablesForwardMasquerade(ctx, netaddr, prefix, physdev, protocol, publicaddr, REMOVE); + } + + +diff --git a/src/util/iptables.h b/src/util/iptables.h +index e54f8b1..a9d2772 100644 +--- a/src/util/iptables.h ++++ b/src/util/iptables.h +@@ -105,12 +105,14 @@ int iptablesAddForwardMasquerade (iptablesContext *ctx, + virSocketAddr *netaddr, + unsigned int prefix, + const char *physdev, +- const char *protocol); ++ const char *protocol, ++ const char *publicaddr); + int iptablesRemoveForwardMasquerade (iptablesContext *ctx, + virSocketAddr *netaddr, + unsigned int prefix, + const char *physdev, +- const char *protocol); ++ const char *protocol, ++ const char *publicaddr); + int iptablesAddOutputFixUdpChecksum (iptablesContext *ctx, + const char *iface, + int port); +-- +1.8.0.1 + diff --git a/main/libvirt/0001-util-refactor-iptables-command-construction-into-mul.patch b/main/libvirt/0001-util-refactor-iptables-command-construction-into-mul.patch new file mode 100644 index 0000000000..6441577b1e --- /dev/null +++ b/main/libvirt/0001-util-refactor-iptables-command-construction-into-mul.patch @@ -0,0 +1,200 @@ +From d1be257a85234f139c073f7c41f845065dd7246e Mon Sep 17 00:00:00 2001 +From: Natanael Copa <ncopa@alpinelinux.org> +Date: Thu, 22 Nov 2012 13:33:23 +0100 +Subject: [PATCH] util: refactor iptables command construction into multiple + steps + +Instead of creating an iptables command in one shot, do it in steps +so we can add conditional options like physdev and protocol. + +This removes code duplication while keeping existing behaviour. + +Signed-off-by: Natanael Copa <ncopa@alpinelinux.org> +--- + src/util/iptables.c | 130 +++++++++++++++++++++++----------------------------- + 1 file changed, 58 insertions(+), 72 deletions(-) + +diff --git a/src/util/iptables.c b/src/util/iptables.c +index 00a1c29..407ca3a 100644 +--- a/src/util/iptables.c ++++ b/src/util/iptables.c +@@ -127,15 +127,10 @@ iptRulesNew(const char *table, + return NULL; + } + +-static int ATTRIBUTE_SENTINEL +-iptablesAddRemoveRule(iptRules *rules, int family, int action, +- const char *arg, ...) ++static virCommandPtr ++iptablesCommandNew(iptRules *rules, int family, int action) + { +- va_list args; +- int ret; + virCommandPtr cmd = NULL; +- const char *s; +- + #if HAVE_FIREWALLD + virIpTablesInitialize(); + if (firewall_cmd_path) { +@@ -152,16 +147,36 @@ iptablesAddRemoveRule(iptRules *rules, int family, int action, + + virCommandAddArgList(cmd, "--table", rules->table, + action == ADD ? "--insert" : "--delete", +- rules->chain, arg, NULL); ++ rules->chain, NULL); ++ return cmd; ++} ++ ++static int ++iptablesCommandRunAndFree(virCommandPtr cmd) ++{ ++ int ret; ++ ret = virCommandRun(cmd, NULL); ++ virCommandFree(cmd); ++ return ret; ++} ++ ++static int ATTRIBUTE_SENTINEL ++iptablesAddRemoveRule(iptRules *rules, int family, int action, ++ const char *arg, ...) ++{ ++ va_list args; ++ virCommandPtr cmd = NULL; ++ const char *s; ++ ++ cmd = iptablesCommandNew(rules, family, action); ++ virCommandAddArg(cmd, arg); + + va_start(args, arg); + while ((s = va_arg(args, const char *))) + virCommandAddArg(cmd, s); + va_end(args); + +- ret = virCommandRun(cmd, NULL); +- virCommandFree(cmd); +- return ret; ++ return iptablesCommandRunAndFree(cmd); + } + + /** +@@ -370,28 +385,24 @@ iptablesForwardAllowOut(iptablesContext *ctx, + { + int ret; + char *networkstr; ++ virCommandPtr cmd = NULL; + + if (!(networkstr = iptablesFormatNetwork(netaddr, prefix))) + return -1; + +- if (physdev && physdev[0]) { +- ret = iptablesAddRemoveRule(ctx->forward_filter, +- VIR_SOCKET_ADDR_FAMILY(netaddr), +- action, +- "--source", networkstr, +- "--in-interface", iface, +- "--out-interface", physdev, +- "--jump", "ACCEPT", +- NULL); +- } else { +- ret = iptablesAddRemoveRule(ctx->forward_filter, +- VIR_SOCKET_ADDR_FAMILY(netaddr), +- action, +- "--source", networkstr, +- "--in-interface", iface, +- "--jump", "ACCEPT", +- NULL); +- } ++ cmd = iptablesCommandNew(ctx->forward_filter, ++ VIR_SOCKET_ADDR_FAMILY(netaddr), ++ action); ++ virCommandAddArgList(cmd, ++ "--source", networkstr, ++ "--in-interface", iface, NULL); ++ ++ if (physdev && physdev[0]) ++ virCommandAddArgList(cmd, "--out-interface", physdev, NULL); ++ ++ virCommandAddArgList(cmd, "--jump", "ACCEPT", NULL); ++ ++ ret = iptablesCommandRunAndFree(cmd); + VIR_FREE(networkstr); + return ret; + } +@@ -797,6 +808,7 @@ iptablesForwardMasquerade(iptablesContext *ctx, + { + int ret; + char *networkstr; ++ virCommandPtr cmd = NULL; + + if (!(networkstr = iptablesFormatNetwork(netaddr, prefix))) + return -1; +@@ -810,49 +822,23 @@ iptablesForwardMasquerade(iptablesContext *ctx, + return -1; + } + +- if (protocol && protocol[0]) { +- if (physdev && physdev[0]) { +- ret = iptablesAddRemoveRule(ctx->nat_postrouting, +- AF_INET, +- action, +- "--source", networkstr, +- "-p", protocol, +- "!", "--destination", networkstr, +- "--out-interface", physdev, +- "--jump", "MASQUERADE", +- "--to-ports", "1024-65535", +- NULL); +- } else { +- ret = iptablesAddRemoveRule(ctx->nat_postrouting, +- AF_INET, +- action, +- "--source", networkstr, +- "-p", protocol, +- "!", "--destination", networkstr, +- "--jump", "MASQUERADE", +- "--to-ports", "1024-65535", +- NULL); +- } +- } else { +- if (physdev && physdev[0]) { +- ret = iptablesAddRemoveRule(ctx->nat_postrouting, +- AF_INET, +- action, +- "--source", networkstr, +- "!", "--destination", networkstr, +- "--out-interface", physdev, +- "--jump", "MASQUERADE", +- NULL); +- } else { +- ret = iptablesAddRemoveRule(ctx->nat_postrouting, +- AF_INET, +- action, +- "--source", networkstr, +- "!", "--destination", networkstr, +- "--jump", "MASQUERADE", +- NULL); +- } +- } ++ cmd = iptablesCommandNew(ctx->nat_postrouting, AF_INET, action); ++ virCommandAddArgList(cmd, "--source", networkstr, NULL); ++ ++ if (protocol && protocol[0]) ++ virCommandAddArgList(cmd, "-p", protocol, NULL); ++ ++ virCommandAddArgList(cmd, "!", "--destination", networkstr, NULL); ++ ++ if (physdev && physdev[0]) ++ virCommandAddArgList(cmd, "--out-interface", physdev, NULL); ++ ++ virCommandAddArgList(cmd, "--jump", "MASQUERADE", NULL); ++ ++ if (protocol && protocol[0]) ++ virCommandAddArgList(cmd, "--to-ports", "1024-65535", NULL); ++ ++ ret = iptablesCommandRunAndFree(cmd); + VIR_FREE(networkstr); + return ret; + } +-- +1.8.0.1 + diff --git a/main/libvirt/APKBUILD b/main/libvirt/APKBUILD index 623141fd1e..8fb430c2f1 100644 --- a/main/libvirt/APKBUILD +++ b/main/libvirt/APKBUILD @@ -4,7 +4,7 @@ vmajor="1.0.0" vminor="" pkgver="${vmajor}" _ver="${pkgver/_rc/-rc}" -pkgrel=1 +pkgrel=2 pkgdesc="A virtualization API for several hypervisor and container systems" url="http://libvirt.org/" arch="all" @@ -23,17 +23,22 @@ source="http://libvirt.org/sources/$pkgname-$pkgver.tar.gz libvirt.initd uclibc-physmem.patch libvirt-1.0.0-remove-uclibc-mkostemp-redefine.patch + 0001-util-refactor-iptables-command-construction-into-mul.patch + 0001-net-support-set-public-ip-for-forward-mode-nat.patch " _builddir="$srcdir"/$pkgname-$vmajor prepare() { cd "$_builddir" - for patch in $(ls ../*.patch) - do - msg "Applying patch $patch" - patch -p1 < ../$patch || return 1 - done + for patch in $source; do + case $patch in + *.patch) + msg "Applying patch $patch" + patch -p1 -i "$srcdir"/$patch || return 1 + ;; + esac + done } build() { @@ -129,4 +134,6 @@ md5sums="7c8b006de7338e30866bb56738803b21 libvirt-1.0.0.tar.gz 1c84a7baeafe0a7f4e9d7ae5180311b7 libvirt.confd d897df38c7e7fa1a297aa551108633c9 libvirt.initd df9cbfaf8a6e520a4822914a300add4d uclibc-physmem.patch -e992133db641b20cb43dda704518984d libvirt-1.0.0-remove-uclibc-mkostemp-redefine.patch" +e992133db641b20cb43dda704518984d libvirt-1.0.0-remove-uclibc-mkostemp-redefine.patch +671eb364f071e67f58ab2c01ec357567 0001-util-refactor-iptables-command-construction-into-mul.patch +20ef9eab94e9a52aa401ddbcb066aeb2 0001-net-support-set-public-ip-for-forward-mode-nat.patch" |