mirror of https://gitee.com/openkylin/libvirt.git
net: add support for specifying port range for forward mode nat
Let users set the port range to be used for forward mode NAT: ... <forward mode='nat'> <nat> <port start='1024' end='65535'/> </nat> </forward> ... Signed-off-by: Natanael Copa <ncopa@alpinelinux.org> Signed-off-by: Laine Stump <laine@laine.org>
This commit is contained in:
parent
905629f47e
commit
1716e7a6c5
|
@ -138,9 +138,11 @@
|
||||||
0.4.2</span>
|
0.4.2</span>
|
||||||
|
|
||||||
<p><span class="since">Since 1.0.3</span> it is possible to
|
<p><span class="since">Since 1.0.3</span> it is possible to
|
||||||
specify a public IPv4 address range to be used for the NAT by
|
specify a public IPv4 address and port range to be used for
|
||||||
using the <code><nat></code> and
|
the NAT by using the <code><nat></code> subelement.
|
||||||
<code><address></code> subelements.
|
The address range is set with the <code><address></code>
|
||||||
|
subelements and <code>start</code> and <code>stop</code>
|
||||||
|
attributes:
|
||||||
<pre>
|
<pre>
|
||||||
...
|
...
|
||||||
<forward mode='nat'>
|
<forward mode='nat'>
|
||||||
|
@ -154,6 +156,19 @@
|
||||||
<code>start</code> and <code>end</code> attributes to
|
<code>start</code> and <code>end</code> attributes to
|
||||||
the same value.
|
the same value.
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
The port range to be used for the <code><nat></code> can
|
||||||
|
be set via the subelement <code><port></code>:
|
||||||
|
<pre>
|
||||||
|
...
|
||||||
|
<forward mode='nat'>
|
||||||
|
<nat>
|
||||||
|
<port start='500' end='1000'/>
|
||||||
|
</nat>
|
||||||
|
</forward>
|
||||||
|
...
|
||||||
|
</pre>
|
||||||
|
</p>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
<dt><code>route</code></dt>
|
<dt><code>route</code></dt>
|
||||||
|
|
|
@ -1332,7 +1332,8 @@ virNetworkForwardNatDefParseXML(const char *networkName,
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
xmlNodePtr *natAddrNodes = NULL;
|
xmlNodePtr *natAddrNodes = NULL;
|
||||||
int nNatAddrs;
|
xmlNodePtr *natPortNodes = NULL;
|
||||||
|
int nNatAddrs, nNatPorts;
|
||||||
char *addrStart = NULL;
|
char *addrStart = NULL;
|
||||||
char *addrEnd = NULL;
|
char *addrEnd = NULL;
|
||||||
xmlNodePtr save = ctxt->node;
|
xmlNodePtr save = ctxt->node;
|
||||||
|
@ -1389,6 +1390,36 @@ virNetworkForwardNatDefParseXML(const char *networkName,
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ports for SNAT and MASQUERADE */
|
||||||
|
nNatPorts = virXPathNodeSet("./port", ctxt, &natPortNodes);
|
||||||
|
if (nNatPorts < 0) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("invalid <port> element found in <forward> of "
|
||||||
|
"network %s"), networkName);
|
||||||
|
goto cleanup;
|
||||||
|
} else if (nNatPorts > 1) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("Only one <port> element is allowed in <nat> in "
|
||||||
|
"<forward> in network %s"), networkName);
|
||||||
|
goto cleanup;
|
||||||
|
} else if (nNatPorts == 1) {
|
||||||
|
if (virXPathUInt("string(./port[1]/@start)", ctxt, &def->portStart) < 0
|
||||||
|
|| def->portStart > 65535) {
|
||||||
|
|
||||||
|
virReportError(VIR_ERR_XML_DETAIL,
|
||||||
|
_("Missing or invalid 'start' attribute in <port> "
|
||||||
|
"in <nat> in <forward> in network %s"),
|
||||||
|
networkName);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (virXPathUInt("string(./port[1]/@end)", ctxt, &def->portEnd) < 0
|
||||||
|
|| def->portEnd > 65535 || def->portEnd < def->portStart) {
|
||||||
|
virReportError(VIR_ERR_XML_DETAIL,
|
||||||
|
_("Missing or invalid 'end' attribute in <port> in "
|
||||||
|
"<nat> in <forward> in network %s"), networkName);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -2193,16 +2224,25 @@ virNetworkForwardNatDefFormat(virBufferPtr buf,
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!addrEnd && !addrStart)
|
if (!addrEnd && !addrStart && !fwd->portStart && !fwd->portEnd)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
virBufferAddLit(buf, "<nat>\n");
|
virBufferAddLit(buf, "<nat>\n");
|
||||||
virBufferAdjustIndent(buf, 2);
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
|
||||||
virBufferAsprintf(buf, "<address start='%s'", addrStart);
|
if (addrStart) {
|
||||||
if (addrEnd)
|
virBufferAsprintf(buf, "<address start='%s'", addrStart);
|
||||||
virBufferAsprintf(buf, " end='%s'", addrEnd);
|
if (addrEnd)
|
||||||
virBufferAddLit(buf, "/>\n");
|
virBufferAsprintf(buf, " end='%s'", addrEnd);
|
||||||
|
virBufferAddLit(buf, "/>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwd->portStart || fwd->portEnd) {
|
||||||
|
virBufferAsprintf(buf, "<port start='%d'", fwd->portStart);
|
||||||
|
if (fwd->portEnd)
|
||||||
|
virBufferAsprintf(buf, " end='%d'", fwd->portEnd);
|
||||||
|
virBufferAddLit(buf, "/>\n");
|
||||||
|
}
|
||||||
|
|
||||||
virBufferAdjustIndent(buf, -2);
|
virBufferAdjustIndent(buf, -2);
|
||||||
virBufferAddLit(buf, "</nat>\n");
|
virBufferAddLit(buf, "</nat>\n");
|
||||||
|
@ -2260,7 +2300,9 @@ virNetworkDefFormatInternal(virBufferPtr buf,
|
||||||
}
|
}
|
||||||
shortforward = !(def->forward.nifs || def->forward.npfs
|
shortforward = !(def->forward.nifs || def->forward.npfs
|
||||||
|| VIR_SOCKET_ADDR_VALID(&def->forward.addrStart)
|
|| VIR_SOCKET_ADDR_VALID(&def->forward.addrStart)
|
||||||
|| VIR_SOCKET_ADDR_VALID(&def->forward.addrEnd));
|
|| VIR_SOCKET_ADDR_VALID(&def->forward.addrEnd)
|
||||||
|
|| def->forward.portStart
|
||||||
|
|| def->forward.portEnd);
|
||||||
virBufferAsprintf(buf, "%s>\n", shortforward ? "/" : "");
|
virBufferAsprintf(buf, "%s>\n", shortforward ? "/" : "");
|
||||||
virBufferAdjustIndent(buf, 2);
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
|
||||||
|
|
|
@ -175,8 +175,9 @@ struct _virNetworkForwardDef {
|
||||||
size_t nifs;
|
size_t nifs;
|
||||||
virNetworkForwardIfDefPtr ifs;
|
virNetworkForwardIfDefPtr ifs;
|
||||||
|
|
||||||
/* adresses for SNAT */
|
/* ranges for NAT */
|
||||||
virSocketAddr addrStart, addrEnd;
|
virSocketAddr addrStart, addrEnd;
|
||||||
|
unsigned int portStart, portEnd;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _virPortGroupDef virPortGroupDef;
|
typedef struct _virPortGroupDef virPortGroupDef;
|
||||||
|
|
|
@ -1589,6 +1589,8 @@ networkAddMasqueradingIptablesRules(struct network_driver *driver,
|
||||||
forwardIf,
|
forwardIf,
|
||||||
&network->def->forward.addrStart,
|
&network->def->forward.addrStart,
|
||||||
&network->def->forward.addrEnd,
|
&network->def->forward.addrEnd,
|
||||||
|
network->def->forward.portStart,
|
||||||
|
network->def->forward.portEnd,
|
||||||
NULL) < 0) {
|
NULL) < 0) {
|
||||||
virReportError(VIR_ERR_SYSTEM_ERROR,
|
virReportError(VIR_ERR_SYSTEM_ERROR,
|
||||||
forwardIf ?
|
forwardIf ?
|
||||||
|
@ -1605,6 +1607,8 @@ networkAddMasqueradingIptablesRules(struct network_driver *driver,
|
||||||
forwardIf,
|
forwardIf,
|
||||||
&network->def->forward.addrStart,
|
&network->def->forward.addrStart,
|
||||||
&network->def->forward.addrEnd,
|
&network->def->forward.addrEnd,
|
||||||
|
network->def->forward.portStart,
|
||||||
|
network->def->forward.portEnd,
|
||||||
"udp") < 0) {
|
"udp") < 0) {
|
||||||
virReportError(VIR_ERR_SYSTEM_ERROR,
|
virReportError(VIR_ERR_SYSTEM_ERROR,
|
||||||
forwardIf ?
|
forwardIf ?
|
||||||
|
@ -1621,6 +1625,8 @@ networkAddMasqueradingIptablesRules(struct network_driver *driver,
|
||||||
forwardIf,
|
forwardIf,
|
||||||
&network->def->forward.addrStart,
|
&network->def->forward.addrStart,
|
||||||
&network->def->forward.addrEnd,
|
&network->def->forward.addrEnd,
|
||||||
|
network->def->forward.portStart,
|
||||||
|
network->def->forward.portEnd,
|
||||||
"tcp") < 0) {
|
"tcp") < 0) {
|
||||||
virReportError(VIR_ERR_SYSTEM_ERROR,
|
virReportError(VIR_ERR_SYSTEM_ERROR,
|
||||||
forwardIf ?
|
forwardIf ?
|
||||||
|
@ -1639,6 +1645,8 @@ networkAddMasqueradingIptablesRules(struct network_driver *driver,
|
||||||
forwardIf,
|
forwardIf,
|
||||||
&network->def->forward.addrStart,
|
&network->def->forward.addrStart,
|
||||||
&network->def->forward.addrEnd,
|
&network->def->forward.addrEnd,
|
||||||
|
network->def->forward.portStart,
|
||||||
|
network->def->forward.portEnd,
|
||||||
"udp");
|
"udp");
|
||||||
masqerr4:
|
masqerr4:
|
||||||
iptablesRemoveForwardMasquerade(driver->iptables,
|
iptablesRemoveForwardMasquerade(driver->iptables,
|
||||||
|
@ -1647,6 +1655,8 @@ networkAddMasqueradingIptablesRules(struct network_driver *driver,
|
||||||
forwardIf,
|
forwardIf,
|
||||||
&network->def->forward.addrStart,
|
&network->def->forward.addrStart,
|
||||||
&network->def->forward.addrEnd,
|
&network->def->forward.addrEnd,
|
||||||
|
network->def->forward.portStart,
|
||||||
|
network->def->forward.portEnd,
|
||||||
NULL);
|
NULL);
|
||||||
masqerr3:
|
masqerr3:
|
||||||
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
|
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
|
||||||
|
@ -1679,6 +1689,8 @@ networkRemoveMasqueradingIptablesRules(struct network_driver *driver,
|
||||||
forwardIf,
|
forwardIf,
|
||||||
&network->def->forward.addrStart,
|
&network->def->forward.addrStart,
|
||||||
&network->def->forward.addrEnd,
|
&network->def->forward.addrEnd,
|
||||||
|
network->def->forward.portStart,
|
||||||
|
network->def->forward.portEnd,
|
||||||
"tcp");
|
"tcp");
|
||||||
iptablesRemoveForwardMasquerade(driver->iptables,
|
iptablesRemoveForwardMasquerade(driver->iptables,
|
||||||
&ipdef->address,
|
&ipdef->address,
|
||||||
|
@ -1686,6 +1698,8 @@ networkRemoveMasqueradingIptablesRules(struct network_driver *driver,
|
||||||
forwardIf,
|
forwardIf,
|
||||||
&network->def->forward.addrStart,
|
&network->def->forward.addrStart,
|
||||||
&network->def->forward.addrEnd,
|
&network->def->forward.addrEnd,
|
||||||
|
network->def->forward.portStart,
|
||||||
|
network->def->forward.portEnd,
|
||||||
"udp");
|
"udp");
|
||||||
iptablesRemoveForwardMasquerade(driver->iptables,
|
iptablesRemoveForwardMasquerade(driver->iptables,
|
||||||
&ipdef->address,
|
&ipdef->address,
|
||||||
|
@ -1693,6 +1707,8 @@ networkRemoveMasqueradingIptablesRules(struct network_driver *driver,
|
||||||
forwardIf,
|
forwardIf,
|
||||||
&network->def->forward.addrStart,
|
&network->def->forward.addrStart,
|
||||||
&network->def->forward.addrEnd,
|
&network->def->forward.addrEnd,
|
||||||
|
network->def->forward.portStart,
|
||||||
|
network->def->forward.portEnd,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
|
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
|
||||||
|
|
|
@ -807,6 +807,8 @@ iptablesForwardMasquerade(iptablesContext *ctx,
|
||||||
const char *physdev,
|
const char *physdev,
|
||||||
virSocketAddr *addrStart,
|
virSocketAddr *addrStart,
|
||||||
virSocketAddr *addrEnd,
|
virSocketAddr *addrEnd,
|
||||||
|
unsigned int portStart,
|
||||||
|
unsigned int portEnd,
|
||||||
const char *protocol,
|
const char *protocol,
|
||||||
int action)
|
int action)
|
||||||
{
|
{
|
||||||
|
@ -814,6 +816,7 @@ iptablesForwardMasquerade(iptablesContext *ctx,
|
||||||
char *networkstr = NULL;
|
char *networkstr = NULL;
|
||||||
char *addrStartStr = NULL;
|
char *addrStartStr = NULL;
|
||||||
char *addrEndStr = NULL;
|
char *addrEndStr = NULL;
|
||||||
|
char *portRangeStr = NULL;
|
||||||
char *natRangeStr = NULL;
|
char *natRangeStr = NULL;
|
||||||
virCommandPtr cmd = NULL;
|
virCommandPtr cmd = NULL;
|
||||||
|
|
||||||
|
@ -848,19 +851,34 @@ iptablesForwardMasquerade(iptablesContext *ctx,
|
||||||
if (physdev && physdev[0])
|
if (physdev && physdev[0])
|
||||||
virCommandAddArgList(cmd, "--out-interface", physdev, NULL);
|
virCommandAddArgList(cmd, "--out-interface", physdev, NULL);
|
||||||
|
|
||||||
|
if (protocol && protocol[0]) {
|
||||||
|
if (portStart == 0 && portEnd == 0) {
|
||||||
|
portStart = 1024;
|
||||||
|
portEnd = 65535;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (portStart < portEnd && portEnd < 65536) {
|
||||||
|
if (virAsprintf(&portRangeStr, ":%u-%u", portStart, portEnd) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Invalid port range '%u-%u'."),
|
||||||
|
portStart, portEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Use --jump SNAT if public addr is specified */
|
/* Use --jump SNAT if public addr is specified */
|
||||||
if (addrStartStr && addrStartStr[0]) {
|
if (addrStartStr && addrStartStr[0]) {
|
||||||
const char *portStr = "";
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
if (protocol && protocol[0])
|
|
||||||
portStr = ":1024-65535";
|
|
||||||
|
|
||||||
if (addrEndStr && addrEndStr[0]) {
|
if (addrEndStr && addrEndStr[0]) {
|
||||||
r = virAsprintf(&natRangeStr, "%s-%s%s", addrStartStr, addrEndStr,
|
r = virAsprintf(&natRangeStr, "%s-%s%s", addrStartStr, addrEndStr,
|
||||||
portStr);
|
portRangeStr ? portRangeStr : "");
|
||||||
} else {
|
} else {
|
||||||
r = virAsprintf(&natRangeStr, "%s%s", addrStartStr, portStr);
|
r = virAsprintf(&natRangeStr, "%s%s", addrStartStr,
|
||||||
|
portRangeStr ? portRangeStr : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
@ -873,8 +891,8 @@ iptablesForwardMasquerade(iptablesContext *ctx,
|
||||||
} else {
|
} else {
|
||||||
virCommandAddArgList(cmd, "--jump", "MASQUERADE", NULL);
|
virCommandAddArgList(cmd, "--jump", "MASQUERADE", NULL);
|
||||||
|
|
||||||
if (protocol && protocol[0])
|
if (portRangeStr && portRangeStr[0])
|
||||||
virCommandAddArgList(cmd, "--to-ports", "1024-65535", NULL);
|
virCommandAddArgList(cmd, "--to-ports", &portRangeStr[1], NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = virCommandRun(cmd, NULL);
|
ret = virCommandRun(cmd, NULL);
|
||||||
|
@ -883,6 +901,7 @@ cleanup:
|
||||||
VIR_FREE(networkstr);
|
VIR_FREE(networkstr);
|
||||||
VIR_FREE(addrStartStr);
|
VIR_FREE(addrStartStr);
|
||||||
VIR_FREE(addrEndStr);
|
VIR_FREE(addrEndStr);
|
||||||
|
VIR_FREE(portRangeStr);
|
||||||
VIR_FREE(natRangeStr);
|
VIR_FREE(natRangeStr);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -907,9 +926,14 @@ iptablesAddForwardMasquerade(iptablesContext *ctx,
|
||||||
const char *physdev,
|
const char *physdev,
|
||||||
virSocketAddr *addrStart,
|
virSocketAddr *addrStart,
|
||||||
virSocketAddr *addrEnd,
|
virSocketAddr *addrEnd,
|
||||||
|
unsigned int portStart,
|
||||||
|
unsigned int portEnd,
|
||||||
const char *protocol)
|
const char *protocol)
|
||||||
{
|
{
|
||||||
return iptablesForwardMasquerade(ctx, netaddr, prefix, physdev, addrStart, addrEnd, protocol, ADD);
|
return iptablesForwardMasquerade(ctx, netaddr, prefix, physdev,
|
||||||
|
addrStart, addrEnd,
|
||||||
|
portStart, portEnd,
|
||||||
|
protocol, ADD);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -932,9 +956,14 @@ iptablesRemoveForwardMasquerade(iptablesContext *ctx,
|
||||||
const char *physdev,
|
const char *physdev,
|
||||||
virSocketAddr *addrStart,
|
virSocketAddr *addrStart,
|
||||||
virSocketAddr *addrEnd,
|
virSocketAddr *addrEnd,
|
||||||
|
unsigned int portStart,
|
||||||
|
unsigned int portEnd,
|
||||||
const char *protocol)
|
const char *protocol)
|
||||||
{
|
{
|
||||||
return iptablesForwardMasquerade(ctx, netaddr, prefix, physdev, addrStart, addrEnd, protocol, REMOVE);
|
return iptablesForwardMasquerade(ctx, netaddr, prefix, physdev,
|
||||||
|
addrStart, addrEnd,
|
||||||
|
portStart, portEnd,
|
||||||
|
protocol, REMOVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,8 @@ int iptablesAddForwardMasquerade (iptablesContext *ctx,
|
||||||
const char *physdev,
|
const char *physdev,
|
||||||
virSocketAddr *addrStart,
|
virSocketAddr *addrStart,
|
||||||
virSocketAddr *addrEnd,
|
virSocketAddr *addrEnd,
|
||||||
|
unsigned int portStart,
|
||||||
|
unsigned int portEnd,
|
||||||
const char *protocol);
|
const char *protocol);
|
||||||
int iptablesRemoveForwardMasquerade (iptablesContext *ctx,
|
int iptablesRemoveForwardMasquerade (iptablesContext *ctx,
|
||||||
virSocketAddr *netaddr,
|
virSocketAddr *netaddr,
|
||||||
|
@ -116,6 +118,8 @@ int iptablesRemoveForwardMasquerade (iptablesContext *ctx,
|
||||||
const char *physdev,
|
const char *physdev,
|
||||||
virSocketAddr *addrStart,
|
virSocketAddr *addrStart,
|
||||||
virSocketAddr *addrEnd,
|
virSocketAddr *addrEnd,
|
||||||
|
unsigned int portStart,
|
||||||
|
unsigned int portEnd,
|
||||||
const char *protocol);
|
const char *protocol);
|
||||||
int iptablesAddOutputFixUdpChecksum (iptablesContext *ctx,
|
int iptablesAddOutputFixUdpChecksum (iptablesContext *ctx,
|
||||||
const char *iface,
|
const char *iface,
|
||||||
|
|
Loading…
Reference in New Issue