Convert bridge driver over to use new firewall APIs

Update the iptablesXXXX methods so that instead of directly
executing iptables commands, they populate rules in an
instance of virFirewallPtr. The bridge driver can thus
construct the ruleset and then invoke it in one operation
having rollback handled automatically.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2014-03-06 17:01:13 +00:00
parent 3a0ca7de51
commit a66fc27d89
3 changed files with 659 additions and 836 deletions

View File

@ -28,6 +28,7 @@
#include "viriptables.h" #include "viriptables.h"
#include "virstring.h" #include "virstring.h"
#include "virlog.h" #include "virlog.h"
#include "virfirewall.h"
#define VIR_FROM_THIS VIR_FROM_NONE #define VIR_FROM_THIS VIR_FROM_NONE
@ -134,7 +135,8 @@ static const char networkLocalMulticast[] = "224.0.0.0/24";
static const char networkLocalBroadcast[] = "255.255.255.255/32"; static const char networkLocalBroadcast[] = "255.255.255.255/32";
static int static int
networkAddMasqueradingFirewallRules(virNetworkObjPtr network, networkAddMasqueradingFirewallRules(virFirewallPtr fw,
virNetworkObjPtr network,
virNetworkIpDefPtr ipdef) virNetworkIpDefPtr ipdef)
{ {
int prefix = virNetworkIpDefPrefix(ipdef); int prefix = virNetworkIpDefPrefix(ipdef);
@ -144,32 +146,26 @@ networkAddMasqueradingFirewallRules(virNetworkObjPtr network,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid prefix or netmask for '%s'"), _("Invalid prefix or netmask for '%s'"),
network->def->bridge); network->def->bridge);
goto masqerr1; return -1;
} }
/* allow forwarding packets from the bridge interface */ /* allow forwarding packets from the bridge interface */
if (iptablesAddForwardAllowOut(&ipdef->address, if (iptablesAddForwardAllowOut(fw,
&ipdef->address,
prefix, prefix,
network->def->bridge, network->def->bridge,
forwardIf) < 0) { forwardIf) < 0)
virReportError(VIR_ERR_SYSTEM_ERROR, return -1;
_("failed to add iptables rule to allow forwarding from '%s'"),
network->def->bridge);
goto masqerr1;
}
/* allow forwarding packets to the bridge interface if they are /* allow forwarding packets to the bridge interface if they are
* part of an existing connection * part of an existing connection
*/ */
if (iptablesAddForwardAllowRelatedIn(&ipdef->address, if (iptablesAddForwardAllowRelatedIn(fw,
&ipdef->address,
prefix, prefix,
network->def->bridge, network->def->bridge,
forwardIf) < 0) { forwardIf) < 0)
virReportError(VIR_ERR_SYSTEM_ERROR, return -1;
_("failed to add iptables rule to allow forwarding to '%s'"),
network->def->bridge);
goto masqerr2;
}
/* /*
* Enable masquerading. * Enable masquerading.
@ -204,176 +200,127 @@ networkAddMasqueradingFirewallRules(virNetworkObjPtr network,
*/ */
/* First the generic masquerade rule for other protocols */ /* First the generic masquerade rule for other protocols */
if (iptablesAddForwardMasquerade(&ipdef->address, if (iptablesAddForwardMasquerade(fw,
&ipdef->address,
prefix, prefix,
forwardIf, forwardIf,
&network->def->forward.addr, &network->def->forward.addr,
&network->def->forward.port, &network->def->forward.port,
NULL) < 0) { NULL) < 0)
if (forwardIf) return -1;
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to enable masquerading to %s"),
forwardIf);
else
virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
_("failed to add iptables rule to enable masquerading"));
goto masqerr3;
}
/* UDP with a source port restriction */ /* UDP with a source port restriction */
if (iptablesAddForwardMasquerade(&ipdef->address, if (iptablesAddForwardMasquerade(fw,
&ipdef->address,
prefix, prefix,
forwardIf, forwardIf,
&network->def->forward.addr, &network->def->forward.addr,
&network->def->forward.port, &network->def->forward.port,
"udp") < 0) { "udp") < 0)
if (forwardIf) return -1;
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to enable UDP masquerading to %s"),
forwardIf);
else
virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
_("failed to add iptables rule to enable UDP masquerading"));
goto masqerr4;
}
/* TCP with a source port restriction */ /* TCP with a source port restriction */
if (iptablesAddForwardMasquerade(&ipdef->address, if (iptablesAddForwardMasquerade(fw,
&ipdef->address,
prefix, prefix,
forwardIf, forwardIf,
&network->def->forward.addr, &network->def->forward.addr,
&network->def->forward.port, &network->def->forward.port,
"tcp") < 0) { "tcp") < 0)
if (forwardIf) return -1;
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to enable TCP masquerading to %s"),
forwardIf);
else
virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
_("failed to add iptables rule to enable TCP masquerading"));
goto masqerr5;
}
/* exempt local network broadcast address as destination */ /* exempt local network broadcast address as destination */
if (iptablesAddDontMasquerade(&ipdef->address, if (iptablesAddDontMasquerade(fw,
&ipdef->address,
prefix, prefix,
forwardIf, forwardIf,
networkLocalBroadcast) < 0) { networkLocalBroadcast) < 0)
if (forwardIf) return -1;
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to prevent local broadcast masquerading on %s"),
forwardIf);
else
virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
_("failed to add iptables rule to prevent local broadcast masquerading"));
goto masqerr6;
}
/* exempt local multicast range as destination */ /* exempt local multicast range as destination */
if (iptablesAddDontMasquerade(&ipdef->address, if (iptablesAddDontMasquerade(fw,
&ipdef->address,
prefix, prefix,
forwardIf, forwardIf,
networkLocalMulticast) < 0) { networkLocalMulticast) < 0)
if (forwardIf) return -1;
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to prevent local multicast masquerading on %s"),
forwardIf);
else
virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
_("failed to add iptables rule to prevent local multicast masquerading"));
goto masqerr7;
}
return 0; return 0;
masqerr7:
iptablesRemoveDontMasquerade(&ipdef->address,
prefix,
forwardIf,
networkLocalBroadcast);
masqerr6:
iptablesRemoveForwardMasquerade(&ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
"tcp");
masqerr5:
iptablesRemoveForwardMasquerade(&ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
"udp");
masqerr4:
iptablesRemoveForwardMasquerade(&ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
NULL);
masqerr3:
iptablesRemoveForwardAllowRelatedIn(&ipdef->address,
prefix,
network->def->bridge,
forwardIf);
masqerr2:
iptablesRemoveForwardAllowOut(&ipdef->address,
prefix,
network->def->bridge,
forwardIf);
masqerr1:
return -1;
} }
static void static int
networkRemoveMasqueradingFirewallRules(virNetworkObjPtr network, networkRemoveMasqueradingFirewallRules(virFirewallPtr fw,
virNetworkObjPtr network,
virNetworkIpDefPtr ipdef) virNetworkIpDefPtr ipdef)
{ {
int prefix = virNetworkIpDefPrefix(ipdef); int prefix = virNetworkIpDefPrefix(ipdef);
const char *forwardIf = virNetworkDefForwardIf(network->def, 0); const char *forwardIf = virNetworkDefForwardIf(network->def, 0);
if (prefix >= 0) { if (prefix < 0)
iptablesRemoveDontMasquerade(&ipdef->address, return 0;
prefix,
forwardIf,
networkLocalMulticast);
iptablesRemoveDontMasquerade(&ipdef->address,
prefix,
forwardIf,
networkLocalBroadcast);
iptablesRemoveForwardMasquerade(&ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
"tcp");
iptablesRemoveForwardMasquerade(&ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
"udp");
iptablesRemoveForwardMasquerade(&ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
NULL);
iptablesRemoveForwardAllowRelatedIn(&ipdef->address, if (iptablesRemoveDontMasquerade(fw,
&ipdef->address,
prefix,
forwardIf,
networkLocalMulticast) < 0)
return -1;
if (iptablesRemoveDontMasquerade(fw,
&ipdef->address,
prefix,
forwardIf,
networkLocalBroadcast) < 0)
return -1;
if (iptablesRemoveForwardMasquerade(fw,
&ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
"tcp") < 0)
return -1;
if (iptablesRemoveForwardMasquerade(fw,
&ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
"udp") < 0)
return -1;
if (iptablesRemoveForwardMasquerade(fw,
&ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
NULL) < 0)
return -1;
if (iptablesRemoveForwardAllowRelatedIn(fw,
&ipdef->address,
prefix, prefix,
network->def->bridge, network->def->bridge,
forwardIf); forwardIf) < 0)
iptablesRemoveForwardAllowOut(&ipdef->address, return -1;
if (iptablesRemoveForwardAllowOut(fw,
&ipdef->address,
prefix, prefix,
network->def->bridge, network->def->bridge,
forwardIf); forwardIf) < 0)
} return -1;
return 0;
} }
static int static int
networkAddRoutingFirewallRules(virNetworkObjPtr network, networkAddRoutingFirewallRules(virFirewallPtr fw,
virNetworkObjPtr network,
virNetworkIpDefPtr ipdef) virNetworkIpDefPtr ipdef)
{ {
int prefix = virNetworkIpDefPrefix(ipdef); int prefix = virNetworkIpDefPrefix(ipdef);
@ -383,168 +330,61 @@ networkAddRoutingFirewallRules(virNetworkObjPtr network,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid prefix or netmask for '%s'"), _("Invalid prefix or netmask for '%s'"),
network->def->bridge); network->def->bridge);
goto routeerr1;
}
/* allow routing packets from the bridge interface */
if (iptablesAddForwardAllowOut(&ipdef->address,
prefix,
network->def->bridge,
forwardIf) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow routing from '%s'"),
network->def->bridge);
goto routeerr1;
}
/* allow routing packets to the bridge interface */
if (iptablesAddForwardAllowIn(&ipdef->address,
prefix,
network->def->bridge,
forwardIf) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow routing to '%s'"),
network->def->bridge);
goto routeerr2;
}
return 0;
routeerr2:
iptablesRemoveForwardAllowOut(&ipdef->address,
prefix,
network->def->bridge,
forwardIf);
routeerr1:
return -1; return -1;
} }
/* allow routing packets from the bridge interface */
if (iptablesAddForwardAllowOut(fw,
&ipdef->address,
prefix,
network->def->bridge,
forwardIf) < 0)
return -1;
static void /* allow routing packets to the bridge interface */
networkRemoveRoutingFirewallRules(virNetworkObjPtr network, if (iptablesAddForwardAllowIn(fw,
&ipdef->address,
prefix,
network->def->bridge,
forwardIf) < 0)
return -1;
return 0;
}
static int
networkRemoveRoutingFirewallRules(virFirewallPtr fw,
virNetworkObjPtr network,
virNetworkIpDefPtr ipdef) virNetworkIpDefPtr ipdef)
{ {
int prefix = virNetworkIpDefPrefix(ipdef); int prefix = virNetworkIpDefPrefix(ipdef);
const char *forwardIf = virNetworkDefForwardIf(network->def, 0); const char *forwardIf = virNetworkDefForwardIf(network->def, 0);
if (prefix >= 0) { if (prefix < 0)
iptablesRemoveForwardAllowIn(&ipdef->address, return 0;
if (iptablesRemoveForwardAllowIn(fw,
&ipdef->address,
prefix, prefix,
network->def->bridge, network->def->bridge,
forwardIf); forwardIf) < 0)
iptablesRemoveForwardAllowOut(&ipdef->address,
prefix,
network->def->bridge,
forwardIf);
}
}
/* Add all once/network rules required for IPv6.
* If no IPv6 addresses are defined and <network ipv6='yes'> is
* specified, then allow IPv6 commuinications between virtual systems.
* If any IPv6 addresses are defined, then add the rules for regular operation.
*/
static int
networkAddGeneralIp6tablesRules(virNetworkObjPtr network)
{
if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0) &&
!network->def->ipv6nogw) {
return 0;
}
/* Catch all rules to block forwarding to/from bridges */
if (iptablesAddForwardRejectOut(AF_INET6, network->def->bridge) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add ip6tables rule to block outbound traffic from '%s'"),
network->def->bridge);
goto err1;
}
if (iptablesAddForwardRejectIn(AF_INET6, network->def->bridge) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add ip6tables rule to block inbound traffic to '%s'"),
network->def->bridge);
goto err2;
}
/* Allow traffic between guests on the same bridge */
if (iptablesAddForwardAllowCross(AF_INET6, network->def->bridge) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add ip6tables rule to allow cross bridge traffic on '%s'"),
network->def->bridge);
goto err3;
}
/* if no IPv6 addresses are defined, we are done. */
if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0))
return 0;
/* allow DNS over IPv6 */
if (iptablesAddTcpInput(AF_INET6, network->def->bridge, 53) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add ip6tables rule to allow DNS requests from '%s'"),
network->def->bridge);
goto err4;
}
if (iptablesAddUdpInput(AF_INET6, network->def->bridge, 53) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add ip6tables rule to allow DNS requests from '%s'"),
network->def->bridge);
goto err5;
}
if (iptablesAddUdpInput(AF_INET6, network->def->bridge, 547) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add ip6tables rule to allow DHCP6 requests from '%s'"),
network->def->bridge);
goto err6;
}
return 0;
/* unwind in reverse order from the point of failure */
err6:
iptablesRemoveUdpInput(AF_INET6, network->def->bridge, 53);
err5:
iptablesRemoveTcpInput(AF_INET6, network->def->bridge, 53);
err4:
iptablesRemoveForwardAllowCross(AF_INET6, network->def->bridge);
err3:
iptablesRemoveForwardRejectIn(AF_INET6, network->def->bridge);
err2:
iptablesRemoveForwardRejectOut(AF_INET6, network->def->bridge);
err1:
return -1; return -1;
if (iptablesRemoveForwardAllowOut(fw,
&ipdef->address,
prefix,
network->def->bridge,
forwardIf) < 0)
return -1;
return 0;
} }
static void static void
networkRemoveGeneralIp6tablesRules(virNetworkObjPtr network) networkAddGeneralIPv4FirewallRules(virFirewallPtr fw,
{ virNetworkObjPtr network)
if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0) &&
!network->def->ipv6nogw) {
return;
}
if (virNetworkDefGetIpByIndex(network->def, AF_INET6, 0)) {
iptablesRemoveUdpInput(AF_INET6, network->def->bridge, 547);
iptablesRemoveUdpInput(AF_INET6, network->def->bridge, 53);
iptablesRemoveTcpInput(AF_INET6, network->def->bridge, 53);
}
/* the following rules are there if no IPv6 address has been defined
* but network->def->ipv6nogw == true
*/
iptablesRemoveForwardAllowCross(AF_INET6, network->def->bridge);
iptablesRemoveForwardRejectIn(AF_INET6, network->def->bridge);
iptablesRemoveForwardRejectOut(AF_INET6, network->def->bridge);
}
static int
networkAddGeneralFirewallRules(virNetworkObjPtr network)
{ {
size_t i; size_t i;
virNetworkIpDefPtr ipv4def; virNetworkIpDefPtr ipv4def;
@ -559,130 +399,33 @@ networkAddGeneralFirewallRules(virNetworkObjPtr network)
} }
/* allow DHCP requests through to dnsmasq */ /* allow DHCP requests through to dnsmasq */
iptablesAddTcpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 67);
if (iptablesAddTcpInput(AF_INET, network->def->bridge, 67) < 0) { iptablesAddUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 67);
virReportError(VIR_ERR_SYSTEM_ERROR, iptablesAddUdpOutput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 68);
_("failed to add iptables rule to allow DHCP requests from '%s'"),
network->def->bridge);
goto err1;
}
if (iptablesAddUdpInput(AF_INET, network->def->bridge, 67) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow DHCP requests from '%s'"),
network->def->bridge);
goto err2;
}
if (iptablesAddUdpOutput(AF_INET, network->def->bridge, 68) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow DHCP replies to '%s'"),
network->def->bridge);
goto err3;
}
/* If we are doing local DHCP service on this network, attempt to
* add a rule that will fixup the checksum of DHCP response
* packets back to the guests (but report failure without
* aborting, since not all iptables implementations support it).
*/
if (ipv4def && (ipv4def->nranges || ipv4def->nhosts) &&
(iptablesAddOutputFixUdpChecksum(network->def->bridge, 68) < 0)) {
VIR_WARN("Could not add rule to fixup DHCP response checksums "
"on network '%s'.", network->def->name);
VIR_WARN("May need to update iptables package & kernel to support CHECKSUM rule.");
}
/* allow DNS requests through to dnsmasq */ /* allow DNS requests through to dnsmasq */
if (iptablesAddTcpInput(AF_INET, network->def->bridge, 53) < 0) { iptablesAddTcpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 53);
virReportError(VIR_ERR_SYSTEM_ERROR, iptablesAddUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 53);
_("failed to add iptables rule to allow DNS requests from '%s'"),
network->def->bridge);
goto err4;
}
if (iptablesAddUdpInput(AF_INET, network->def->bridge, 53) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow DNS requests from '%s'"),
network->def->bridge);
goto err5;
}
/* allow TFTP requests through to dnsmasq if necessary */ /* allow TFTP requests through to dnsmasq if necessary */
if (ipv4def && ipv4def->tftproot && if (ipv4def && ipv4def->tftproot)
iptablesAddUdpInput(AF_INET, network->def->bridge, 69) < 0) { iptablesAddUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 69);
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow TFTP requests from '%s'"),
network->def->bridge);
goto err6;
}
/* Catch all rules to block forwarding to/from bridges */ /* Catch all rules to block forwarding to/from bridges */
iptablesAddForwardRejectOut(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge);
if (iptablesAddForwardRejectOut(AF_INET, network->def->bridge) < 0) { iptablesAddForwardRejectIn(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge);
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to block outbound traffic from '%s'"),
network->def->bridge);
goto err7;
}
if (iptablesAddForwardRejectIn(AF_INET, network->def->bridge) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to block inbound traffic to '%s'"),
network->def->bridge);
goto err8;
}
/* Allow traffic between guests on the same bridge */ /* Allow traffic between guests on the same bridge */
if (iptablesAddForwardAllowCross(AF_INET, network->def->bridge) < 0) { iptablesAddForwardAllowCross(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge);
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow cross bridge traffic on '%s'"),
network->def->bridge);
goto err9;
} }
/* add IPv6 general rules, if needed */
if (networkAddGeneralIp6tablesRules(network) < 0) {
goto err10;
}
return 0;
/* unwind in reverse order from the point of failure */
err10:
iptablesRemoveForwardAllowCross(AF_INET, network->def->bridge);
err9:
iptablesRemoveForwardRejectIn(AF_INET, network->def->bridge);
err8:
iptablesRemoveForwardRejectOut(AF_INET, network->def->bridge);
err7:
if (ipv4def && ipv4def->tftproot) {
iptablesRemoveUdpInput(AF_INET, network->def->bridge, 69);
}
err6:
iptablesRemoveUdpInput(AF_INET, network->def->bridge, 53);
err5:
iptablesRemoveTcpInput(AF_INET, network->def->bridge, 53);
err4:
iptablesRemoveUdpOutput(AF_INET, network->def->bridge, 68);
err3:
iptablesRemoveUdpInput(AF_INET, network->def->bridge, 67);
err2:
iptablesRemoveTcpInput(AF_INET, network->def->bridge, 67);
err1:
return -1;
}
static void static void
networkRemoveGeneralFirewallRules(virNetworkObjPtr network) networkRemoveGeneralIPv4FirewallRules(virFirewallPtr fw,
virNetworkObjPtr network)
{ {
size_t i; size_t i;
virNetworkIpDefPtr ipv4def; virNetworkIpDefPtr ipv4def;
networkRemoveGeneralIp6tablesRules(network);
for (i = 0; for (i = 0;
(ipv4def = virNetworkDefGetIpByIndex(network->def, AF_INET, i)); (ipv4def = virNetworkDefGetIpByIndex(network->def, AF_INET, i));
i++) { i++) {
@ -690,25 +433,143 @@ networkRemoveGeneralFirewallRules(virNetworkObjPtr network)
break; break;
} }
iptablesRemoveForwardAllowCross(AF_INET, network->def->bridge); iptablesRemoveForwardAllowCross(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge);
iptablesRemoveForwardRejectIn(AF_INET, network->def->bridge); iptablesRemoveForwardRejectIn(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge);
iptablesRemoveForwardRejectOut(AF_INET, network->def->bridge); iptablesRemoveForwardRejectOut(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge);
if (ipv4def && ipv4def->tftproot) {
iptablesRemoveUdpInput(AF_INET, network->def->bridge, 69); if (ipv4def && ipv4def->tftproot)
iptablesRemoveUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 69);
iptablesRemoveUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 53);
iptablesRemoveTcpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 53);
iptablesRemoveUdpOutput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 68);
iptablesRemoveUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 67);
iptablesRemoveTcpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 67);
} }
iptablesRemoveUdpInput(AF_INET, network->def->bridge, 53);
iptablesRemoveTcpInput(AF_INET, network->def->bridge, 53);
if (ipv4def && (ipv4def->nranges || ipv4def->nhosts)) { /* Add all once/network rules required for IPv6.
iptablesRemoveOutputFixUdpChecksum(network->def->bridge, 68); * If no IPv6 addresses are defined and <network ipv6='yes'> is
* specified, then allow IPv6 commuinications between virtual systems.
* If any IPv6 addresses are defined, then add the rules for regular operation.
*/
static void
networkAddGeneralIPv6FirewallRules(virFirewallPtr fw,
virNetworkObjPtr network)
{
if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0) &&
!network->def->ipv6nogw) {
return;
} }
iptablesRemoveUdpOutput(AF_INET, network->def->bridge, 68);
iptablesRemoveUdpInput(AF_INET, network->def->bridge, 67); /* Catch all rules to block forwarding to/from bridges */
iptablesRemoveTcpInput(AF_INET, network->def->bridge, 67); iptablesAddForwardRejectOut(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge);
iptablesAddForwardRejectIn(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge);
/* Allow traffic between guests on the same bridge */
iptablesAddForwardAllowCross(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge);
if (virNetworkDefGetIpByIndex(network->def, AF_INET6, 0)) {
/* allow DNS over IPv6 */
iptablesAddTcpInput(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge, 53);
iptablesAddUdpInput(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge, 53);
iptablesAddUdpInput(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge, 547);
}
}
static void
networkRemoveGeneralIPv6FirewallRules(virFirewallPtr fw,
virNetworkObjPtr network)
{
if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0) &&
!network->def->ipv6nogw) {
return;
}
if (virNetworkDefGetIpByIndex(network->def, AF_INET6, 0)) {
iptablesRemoveUdpInput(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge, 547);
iptablesRemoveUdpInput(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge, 53);
iptablesRemoveTcpInput(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge, 53);
}
/* the following rules are there if no IPv6 address has been defined
* but network->def->ipv6nogw == true
*/
iptablesRemoveForwardAllowCross(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge);
iptablesRemoveForwardRejectIn(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge);
iptablesRemoveForwardRejectOut(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge);
}
static void
networkAddGeneralFirewallRules(virFirewallPtr fw,
virNetworkObjPtr network)
{
networkAddGeneralIPv4FirewallRules(fw, network);
networkAddGeneralIPv6FirewallRules(fw, network);
}
static void
networkRemoveGeneralFirewallRules(virFirewallPtr fw,
virNetworkObjPtr network)
{
networkRemoveGeneralIPv4FirewallRules(fw, network);
networkRemoveGeneralIPv6FirewallRules(fw, network);
}
static void
networkAddChecksumFirewallRules(virFirewallPtr fw,
virNetworkObjPtr network)
{
size_t i;
virNetworkIpDefPtr ipv4def;
/* First look for first IPv4 address that has dhcp or tftpboot defined. */
/* We support dhcp config on 1 IPv4 interface only. */
for (i = 0;
(ipv4def = virNetworkDefGetIpByIndex(network->def, AF_INET, i));
i++) {
if (ipv4def->nranges || ipv4def->nhosts)
break;
}
/* If we are doing local DHCP service on this network, attempt to
* add a rule that will fixup the checksum of DHCP response
* packets back to the guests (but report failure without
* aborting, since not all iptables implementations support it).
*/
if (ipv4def)
iptablesAddOutputFixUdpChecksum(fw, network->def->bridge, 68);
}
static void
networkRemoveChecksumFirewallRules(virFirewallPtr fw,
virNetworkObjPtr network)
{
size_t i;
virNetworkIpDefPtr ipv4def;
/* First look for first IPv4 address that has dhcp or tftpboot defined. */
/* We support dhcp config on 1 IPv4 interface only. */
for (i = 0;
(ipv4def = virNetworkDefGetIpByIndex(network->def, AF_INET, i));
i++) {
if (ipv4def->nranges || ipv4def->nhosts)
break;
}
if (ipv4def)
iptablesRemoveOutputFixUdpChecksum(fw, network->def->bridge, 68);
} }
static int static int
networkAddIpSpecificFirewallRules(virNetworkObjPtr network, networkAddIpSpecificFirewallRules(virFirewallPtr fw,
virNetworkObjPtr network,
virNetworkIpDefPtr ipdef) virNetworkIpDefPtr ipdef)
{ {
/* NB: in the case of IPv6, routing rules are added when the /* NB: in the case of IPv6, routing rules are added when the
@ -717,70 +578,74 @@ networkAddIpSpecificFirewallRules(virNetworkObjPtr network,
if (network->def->forward.type == VIR_NETWORK_FORWARD_NAT) { if (network->def->forward.type == VIR_NETWORK_FORWARD_NAT) {
if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET))
return networkAddMasqueradingFirewallRules(network, ipdef); return networkAddMasqueradingFirewallRules(fw, network, ipdef);
else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6))
return networkAddRoutingFirewallRules(network, ipdef); return networkAddRoutingFirewallRules(fw, network, ipdef);
} else if (network->def->forward.type == VIR_NETWORK_FORWARD_ROUTE) { } else if (network->def->forward.type == VIR_NETWORK_FORWARD_ROUTE) {
return networkAddRoutingFirewallRules(network, ipdef); return networkAddRoutingFirewallRules(fw, network, ipdef);
} }
return 0; return 0;
} }
static void static int
networkRemoveIpSpecificFirewallRules(virNetworkObjPtr network, networkRemoveIpSpecificFirewallRules(virFirewallPtr fw,
virNetworkObjPtr network,
virNetworkIpDefPtr ipdef) virNetworkIpDefPtr ipdef)
{ {
if (network->def->forward.type == VIR_NETWORK_FORWARD_NAT) { if (network->def->forward.type == VIR_NETWORK_FORWARD_NAT) {
if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET))
networkRemoveMasqueradingFirewallRules(network, ipdef); return networkRemoveMasqueradingFirewallRules(fw, network, ipdef);
else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6))
networkRemoveRoutingFirewallRules(network, ipdef); return networkRemoveRoutingFirewallRules(fw, network, ipdef);
} else if (network->def->forward.type == VIR_NETWORK_FORWARD_ROUTE) { } else if (network->def->forward.type == VIR_NETWORK_FORWARD_ROUTE) {
networkRemoveRoutingFirewallRules(network, ipdef); return networkRemoveRoutingFirewallRules(fw, network, ipdef);
} }
return 0;
} }
/* Add all rules for all ip addresses (and general rules) on a network */ /* Add all rules for all ip addresses (and general rules) on a network */
int networkAddFirewallRules(virNetworkObjPtr network) int networkAddFirewallRules(virNetworkObjPtr network)
{ {
size_t i, j; size_t i;
virNetworkIpDefPtr ipdef; virNetworkIpDefPtr ipdef;
virErrorPtr orig_error; virFirewallPtr fw = NULL;
int ret = -1;
/* Add "once per network" rules */ fw = virFirewallNew();
if (networkAddGeneralFirewallRules(network) < 0)
return -1; virFirewallStartTransaction(fw, 0);
networkAddGeneralFirewallRules(fw, network);
for (i = 0; for (i = 0;
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i)); (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i));
i++) { i++) {
/* Add address-specific iptables rules */ if (networkAddIpSpecificFirewallRules(fw, network, ipdef) < 0)
if (networkAddIpSpecificFirewallRules(network, ipdef) < 0) { goto cleanup;
goto err;
} }
virFirewallStartRollback(fw, 0);
for (i = 0;
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i));
i++) {
if (networkRemoveIpSpecificFirewallRules(fw, network, ipdef) < 0)
goto cleanup;
} }
return 0; networkRemoveGeneralFirewallRules(fw, network);
err: virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
/* store the previous error message before attempting removal of rules */ networkAddChecksumFirewallRules(fw, network);
orig_error = virSaveLastError();
/* The final failed call to networkAddIpSpecificFirewallRules will if (virFirewallApply(fw) < 0)
* have removed any rules it created, but we need to remove those goto cleanup;
* added for previous IP addresses.
*/
for (j = 0; j < i; j++) {
if ((ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, j)))
networkRemoveIpSpecificFirewallRules(network, ipdef);
}
networkRemoveGeneralFirewallRules(network);
/* return the original error */ ret = 0;
virSetError(orig_error); cleanup:
virFreeError(orig_error); virFirewallFree(fw);
return -1; return ret;
} }
/* Remove all rules for all ip addresses (and general rules) on a network */ /* Remove all rules for all ip addresses (and general rules) on a network */
@ -788,11 +653,25 @@ void networkRemoveFirewallRules(virNetworkObjPtr network)
{ {
size_t i; size_t i;
virNetworkIpDefPtr ipdef; virNetworkIpDefPtr ipdef;
virFirewallPtr fw = NULL;
fw = virFirewallNew();
virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
networkRemoveChecksumFirewallRules(fw, network);
virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
for (i = 0; for (i = 0;
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i)); (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i));
i++) { i++) {
networkRemoveIpSpecificFirewallRules(network, ipdef); if (networkRemoveIpSpecificFirewallRules(fw, network, ipdef) < 0)
goto cleanup;
} }
networkRemoveGeneralFirewallRules(network); networkRemoveGeneralFirewallRules(fw, network);
virFirewallApply(fw);
cleanup:
virFirewallFree(fw);
} }

View File

@ -54,56 +54,6 @@ VIR_LOG_INIT("util.iptables");
bool iptables_supports_xlock = false; bool iptables_supports_xlock = false;
#if HAVE_FIREWALLD
static char *firewall_cmd_path = NULL;
#endif
static int
virIpTablesOnceInit(void)
{
virCommandPtr cmd;
int status;
#if HAVE_FIREWALLD
firewall_cmd_path = virFindFileInPath("firewall-cmd");
if (!firewall_cmd_path) {
VIR_INFO("firewall-cmd not found on system. "
"firewalld support disabled for iptables.");
} else {
cmd = virCommandNew(firewall_cmd_path);
virCommandAddArgList(cmd, "--state", NULL);
/* don't log non-zero status */
if (virCommandRun(cmd, &status) < 0 || status != 0) {
VIR_INFO("firewall-cmd found but disabled for iptables");
VIR_FREE(firewall_cmd_path);
firewall_cmd_path = NULL;
} else {
VIR_INFO("using firewalld for iptables commands");
}
virCommandFree(cmd);
}
if (firewall_cmd_path)
return 0;
#endif
cmd = virCommandNew(IPTABLES_PATH);
virCommandAddArgList(cmd, "-w", "-L", "-n", NULL);
/* don't log non-zero status */
if (virCommandRun(cmd, &status) < 0 || status != 0) {
VIR_INFO("xtables locking not supported by your iptables");
} else {
VIR_INFO("using xtables locking for iptables");
iptables_supports_xlock = true;
}
virCommandFree(cmd);
return 0;
}
VIR_ONCE_GLOBAL_INIT(virIpTables)
#define VIR_FROM_THIS VIR_FROM_NONE #define VIR_FROM_THIS VIR_FROM_NONE
enum { enum {
@ -111,63 +61,10 @@ enum {
REMOVE REMOVE
}; };
static virCommandPtr
iptablesCommandNew(const char *table, const char *chain, int family, int action)
{
virCommandPtr cmd = NULL;
virIpTablesInitialize();
#if HAVE_FIREWALLD
if (firewall_cmd_path) {
cmd = virCommandNew(firewall_cmd_path);
virCommandAddArgList(cmd, "--direct", "--passthrough",
(family == AF_INET6) ? "ipv6" : "ipv4", NULL);
}
#endif
if (cmd == NULL) { static void
cmd = virCommandNew((family == AF_INET6) iptablesInput(virFirewallPtr fw,
? IP6TABLES_PATH : IPTABLES_PATH); virFirewallLayer layer,
if (iptables_supports_xlock)
virCommandAddArgList(cmd, "-w", NULL);
}
virCommandAddArgList(cmd, "--table", table,
action == ADD ? "--insert" : "--delete",
chain, NULL);
return cmd;
}
static int
iptablesCommandRunAndFree(virCommandPtr cmd)
{
int ret;
ret = virCommandRun(cmd, NULL);
virCommandFree(cmd);
return ret;
}
static int ATTRIBUTE_SENTINEL
iptablesAddRemoveRule(const char *table, const char *chain, int family, int action,
const char *arg, ...)
{
va_list args;
virCommandPtr cmd = NULL;
const char *s;
cmd = iptablesCommandNew(table, chain, family, action);
virCommandAddArg(cmd, arg);
va_start(args, arg);
while ((s = va_arg(args, const char *)))
virCommandAddArg(cmd, s);
va_end(args);
return iptablesCommandRunAndFree(cmd);
}
static int
iptablesInput(int family,
const char *iface, const char *iface,
int port, int port,
int action, int action,
@ -178,9 +75,9 @@ iptablesInput(int family,
snprintf(portstr, sizeof(portstr), "%d", port); snprintf(portstr, sizeof(portstr), "%d", port);
portstr[sizeof(portstr) - 1] = '\0'; portstr[sizeof(portstr) - 1] = '\0';
return iptablesAddRemoveRule("filter", "INPUT", virFirewallAddRule(fw, layer,
family, "--table", "filter",
action, action == ADD ? "--insert" : "--delete", "INPUT",
"--in-interface", iface, "--in-interface", iface,
"--protocol", tcp ? "tcp" : "udp", "--protocol", tcp ? "tcp" : "udp",
"--destination-port", portstr, "--destination-port", portstr,
@ -188,8 +85,9 @@ iptablesInput(int family,
NULL); NULL);
} }
static int static void
iptablesOutput(int family, iptablesOutput(virFirewallPtr fw,
virFirewallLayer layer,
const char *iface, const char *iface,
int port, int port,
int action, int action,
@ -200,9 +98,9 @@ iptablesOutput(int family,
snprintf(portstr, sizeof(portstr), "%d", port); snprintf(portstr, sizeof(portstr), "%d", port);
portstr[sizeof(portstr) - 1] = '\0'; portstr[sizeof(portstr) - 1] = '\0';
return iptablesAddRemoveRule("filter", "OUTPUT", virFirewallAddRule(fw, layer,
family, "--table", "filter",
action, action == ADD ? "--insert" : "--delete", "OUTPUT",
"--out-interface", iface, "--out-interface", iface,
"--protocol", tcp ? "tcp" : "udp", "--protocol", tcp ? "tcp" : "udp",
"--destination-port", portstr, "--destination-port", portstr,
@ -218,16 +116,14 @@ iptablesOutput(int family,
* *
* Add an input to the IP table allowing access to the given @port on * Add an input to the IP table allowing access to the given @port on
* the given @iface interface for TCP packets * the given @iface interface for TCP packets
*
* Returns 0 in case of success or an error code in case of error
*/ */
void
int iptablesAddTcpInput(virFirewallPtr fw,
iptablesAddTcpInput(int family, virFirewallLayer layer,
const char *iface, const char *iface,
int port) int port)
{ {
return iptablesInput(family, iface, port, ADD, 1); iptablesInput(fw, layer, iface, port, ADD, 1);
} }
/** /**
@ -238,15 +134,14 @@ iptablesAddTcpInput(int family,
* *
* Removes an input from the IP table, hence forbidding access to the given * Removes an input from the IP table, hence forbidding access to the given
* @port on the given @iface interface for TCP packets * @port on the given @iface interface for TCP packets
*
* Returns 0 in case of success or an error code in case of error
*/ */
int void
iptablesRemoveTcpInput(int family, iptablesRemoveTcpInput(virFirewallPtr fw,
virFirewallLayer layer,
const char *iface, const char *iface,
int port) int port)
{ {
return iptablesInput(family, iface, port, REMOVE, 1); iptablesInput(fw, layer, iface, port, REMOVE, 1);
} }
/** /**
@ -257,16 +152,14 @@ iptablesRemoveTcpInput(int family,
* *
* Add an input to the IP table allowing access to the given @port on * Add an input to the IP table allowing access to the given @port on
* the given @iface interface for UDP packets * the given @iface interface for UDP packets
*
* Returns 0 in case of success or an error code in case of error
*/ */
void
int iptablesAddUdpInput(virFirewallPtr fw,
iptablesAddUdpInput(int family, virFirewallLayer layer,
const char *iface, const char *iface,
int port) int port)
{ {
return iptablesInput(family, iface, port, ADD, 0); iptablesInput(fw, layer, iface, port, ADD, 0);
} }
/** /**
@ -277,15 +170,14 @@ iptablesAddUdpInput(int family,
* *
* Removes an input from the IP table, hence forbidding access to the given * Removes an input from the IP table, hence forbidding access to the given
* @port on the given @iface interface for UDP packets * @port on the given @iface interface for UDP packets
*
* Returns 0 in case of success or an error code in case of error
*/ */
int void
iptablesRemoveUdpInput(int family, iptablesRemoveUdpInput(virFirewallPtr fw,
virFirewallLayer layer,
const char *iface, const char *iface,
int port) int port)
{ {
return iptablesInput(family, iface, port, REMOVE, 0); return iptablesInput(fw, layer, iface, port, REMOVE, 0);
} }
/** /**
@ -296,16 +188,14 @@ iptablesRemoveUdpInput(int family,
* *
* Add an output to the IP table allowing access to the given @port from * Add an output to the IP table allowing access to the given @port from
* the given @iface interface for UDP packets * the given @iface interface for UDP packets
*
* Returns 0 in case of success or an error code in case of error
*/ */
void
int iptablesAddUdpOutput(virFirewallPtr fw,
iptablesAddUdpOutput(int family, virFirewallLayer layer,
const char *iface, const char *iface,
int port) int port)
{ {
return iptablesOutput(family, iface, port, ADD, 0); iptablesOutput(fw, layer, iface, port, ADD, 0);
} }
/** /**
@ -316,15 +206,14 @@ iptablesAddUdpOutput(int family,
* *
* Removes an output from the IP table, hence forbidding access to the given * Removes an output from the IP table, hence forbidding access to the given
* @port from the given @iface interface for UDP packets * @port from the given @iface interface for UDP packets
*
* Returns 0 in case of success or an error code in case of error
*/ */
int void
iptablesRemoveUdpOutput(int family, iptablesRemoveUdpOutput(virFirewallPtr fw,
virFirewallLayer layer,
const char *iface, const char *iface,
int port) int port)
{ {
return iptablesOutput(family, iface, port, REMOVE, 0); iptablesOutput(fw, layer, iface, port, REMOVE, 0);
} }
@ -364,34 +253,40 @@ static char *iptablesFormatNetwork(virSocketAddr *netaddr,
* to proceed to WAN * to proceed to WAN
*/ */
static int static int
iptablesForwardAllowOut(virSocketAddr *netaddr, iptablesForwardAllowOut(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev, const char *physdev,
int action) int action)
{ {
int ret;
char *networkstr; char *networkstr;
virCommandPtr cmd = NULL; virFirewallLayer layer = VIR_SOCKET_ADDR_FAMILY(netaddr) == AF_INET ?
VIR_FIREWALL_LAYER_IPV4 : VIR_FIREWALL_LAYER_IPV6;
if (!(networkstr = iptablesFormatNetwork(netaddr, prefix))) if (!(networkstr = iptablesFormatNetwork(netaddr, prefix)))
return -1; return -1;
cmd = iptablesCommandNew("filter", "FORWARD",
VIR_SOCKET_ADDR_FAMILY(netaddr),
action);
virCommandAddArgList(cmd,
"--source", networkstr,
"--in-interface", iface, NULL);
if (physdev && physdev[0]) if (physdev && physdev[0])
virCommandAddArgList(cmd, "--out-interface", physdev, NULL); virFirewallAddRule(fw, layer,
"--table", "filter",
action == ADD ? "--insert" : "--delete", "FORWARD",
"--source", networkstr,
"--in-interface", iface,
"--out-interface", physdev,
"--jump", "ACCEPT",
NULL);
else
virFirewallAddRule(fw, layer,
"--table", "filter",
action == ADD ? "--insert" : "--delete", "FORWARD",
"--source", networkstr,
"--in-interface", iface,
"--jump", "ACCEPT",
NULL);
virCommandAddArgList(cmd, "--jump", "ACCEPT", NULL);
ret = iptablesCommandRunAndFree(cmd);
VIR_FREE(networkstr); VIR_FREE(networkstr);
return ret; return 0;
} }
/** /**
@ -408,12 +303,13 @@ iptablesForwardAllowOut(virSocketAddr *netaddr,
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int int
iptablesAddForwardAllowOut(virSocketAddr *netaddr, iptablesAddForwardAllowOut(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev) const char *physdev)
{ {
return iptablesForwardAllowOut(netaddr, prefix, iface, physdev, ADD); return iptablesForwardAllowOut(fw, netaddr, prefix, iface, physdev, ADD);
} }
/** /**
@ -430,12 +326,13 @@ iptablesAddForwardAllowOut(virSocketAddr *netaddr,
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int int
iptablesRemoveForwardAllowOut(virSocketAddr *netaddr, iptablesRemoveForwardAllowOut(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev) const char *physdev)
{ {
return iptablesForwardAllowOut(netaddr, prefix, iface, physdev, REMOVE); return iptablesForwardAllowOut(fw, netaddr, prefix, iface, physdev, REMOVE);
} }
@ -443,22 +340,24 @@ iptablesRemoveForwardAllowOut(virSocketAddr *netaddr,
* and associated with an existing connection * and associated with an existing connection
*/ */
static int static int
iptablesForwardAllowRelatedIn(virSocketAddr *netaddr, iptablesForwardAllowRelatedIn(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev, const char *physdev,
int action) int action)
{ {
int ret; virFirewallLayer layer = VIR_SOCKET_ADDR_FAMILY(netaddr) == AF_INET ?
VIR_FIREWALL_LAYER_IPV4 : VIR_FIREWALL_LAYER_IPV6;
char *networkstr; char *networkstr;
if (!(networkstr = iptablesFormatNetwork(netaddr, prefix))) if (!(networkstr = iptablesFormatNetwork(netaddr, prefix)))
return -1; return -1;
if (physdev && physdev[0]) { if (physdev && physdev[0])
ret = iptablesAddRemoveRule("filter", "FORWARD", virFirewallAddRule(fw, layer,
VIR_SOCKET_ADDR_FAMILY(netaddr), "--table", "filter",
action, action == ADD ? "--insert" : "--delete", "FORWARD",
"--destination", networkstr, "--destination", networkstr,
"--in-interface", physdev, "--in-interface", physdev,
"--out-interface", iface, "--out-interface", iface,
@ -466,19 +365,19 @@ iptablesForwardAllowRelatedIn(virSocketAddr *netaddr,
"--ctstate", "ESTABLISHED,RELATED", "--ctstate", "ESTABLISHED,RELATED",
"--jump", "ACCEPT", "--jump", "ACCEPT",
NULL); NULL);
} else { else
ret = iptablesAddRemoveRule("filter", "FORWARD", virFirewallAddRule(fw, layer,
VIR_SOCKET_ADDR_FAMILY(netaddr), "--table", "filter",
action, action == ADD ? "--insert" : "--delete", "FORWARD",
"--destination", networkstr, "--destination", networkstr,
"--out-interface", iface, "--out-interface", iface,
"--match", "conntrack", "--match", "conntrack",
"--ctstate", "ESTABLISHED,RELATED", "--ctstate", "ESTABLISHED,RELATED",
"--jump", "ACCEPT", "--jump", "ACCEPT",
NULL); NULL);
}
VIR_FREE(networkstr); VIR_FREE(networkstr);
return ret; return 0;
} }
/** /**
@ -495,12 +394,13 @@ iptablesForwardAllowRelatedIn(virSocketAddr *netaddr,
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int int
iptablesAddForwardAllowRelatedIn(virSocketAddr *netaddr, iptablesAddForwardAllowRelatedIn(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev) const char *physdev)
{ {
return iptablesForwardAllowRelatedIn(netaddr, prefix, iface, physdev, ADD); return iptablesForwardAllowRelatedIn(fw, netaddr, prefix, iface, physdev, ADD);
} }
/** /**
@ -517,49 +417,51 @@ iptablesAddForwardAllowRelatedIn(virSocketAddr *netaddr,
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int int
iptablesRemoveForwardAllowRelatedIn(virSocketAddr *netaddr, iptablesRemoveForwardAllowRelatedIn(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev) const char *physdev)
{ {
return iptablesForwardAllowRelatedIn(netaddr, prefix, iface, physdev, REMOVE); return iptablesForwardAllowRelatedIn(fw, netaddr, prefix, iface, physdev, REMOVE);
} }
/* Allow all traffic destined to the bridge, with a valid network address /* Allow all traffic destined to the bridge, with a valid network address
*/ */
static int static int
iptablesForwardAllowIn(virSocketAddr *netaddr, iptablesForwardAllowIn(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev, const char *physdev,
int action) int action)
{ {
int ret; virFirewallLayer layer = VIR_SOCKET_ADDR_FAMILY(netaddr) == AF_INET ?
VIR_FIREWALL_LAYER_IPV4 : VIR_FIREWALL_LAYER_IPV6;
char *networkstr; char *networkstr;
if (!(networkstr = iptablesFormatNetwork(netaddr, prefix))) if (!(networkstr = iptablesFormatNetwork(netaddr, prefix)))
return -1; return -1;
if (physdev && physdev[0]) { if (physdev && physdev[0])
ret = iptablesAddRemoveRule("filter", "FORWARD", virFirewallAddRule(fw, layer,
VIR_SOCKET_ADDR_FAMILY(netaddr), "--table", "filter",
action, action == ADD ? "--insert" : "--delete", "FORWARD",
"--destination", networkstr, "--destination", networkstr,
"--in-interface", physdev, "--in-interface", physdev,
"--out-interface", iface, "--out-interface", iface,
"--jump", "ACCEPT", "--jump", "ACCEPT",
NULL); NULL);
} else { else
ret = iptablesAddRemoveRule("filter", "FORWARD", virFirewallAddRule(fw, layer,
VIR_SOCKET_ADDR_FAMILY(netaddr), "--table", "filter",
action, action == ADD ? "--insert" : "--delete", "FORWARD",
"--destination", networkstr, "--destination", networkstr,
"--out-interface", iface, "--out-interface", iface,
"--jump", "ACCEPT", "--jump", "ACCEPT",
NULL); NULL);
}
VIR_FREE(networkstr); VIR_FREE(networkstr);
return ret; return 0;
} }
/** /**
@ -576,12 +478,13 @@ iptablesForwardAllowIn(virSocketAddr *netaddr,
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int int
iptablesAddForwardAllowIn(virSocketAddr *netaddr, iptablesAddForwardAllowIn(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev) const char *physdev)
{ {
return iptablesForwardAllowIn(netaddr, prefix, iface, physdev, ADD); return iptablesForwardAllowIn(fw, netaddr, prefix, iface, physdev, ADD);
} }
/** /**
@ -598,30 +501,13 @@ iptablesAddForwardAllowIn(virSocketAddr *netaddr,
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int int
iptablesRemoveForwardAllowIn(virSocketAddr *netaddr, iptablesRemoveForwardAllowIn(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev) const char *physdev)
{ {
return iptablesForwardAllowIn(netaddr, prefix, iface, physdev, REMOVE); return iptablesForwardAllowIn(fw, netaddr, prefix, iface, physdev, REMOVE);
}
/* Allow all traffic between guests on the same bridge,
* with a valid network address
*/
static int
iptablesForwardAllowCross(int family,
const char *iface,
int action)
{
return iptablesAddRemoveRule("filter", "FORWARD",
family,
action,
"--in-interface", iface,
"--out-interface", iface,
"--jump", "ACCEPT",
NULL);
} }
/** /**
@ -635,11 +521,18 @@ iptablesForwardAllowCross(int family,
* *
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int void
iptablesAddForwardAllowCross(int family, iptablesAddForwardAllowCross(virFirewallPtr fw,
virFirewallLayer layer,
const char *iface) const char *iface)
{ {
return iptablesForwardAllowCross(family, iface, ADD); virFirewallAddRule(fw, layer,
"--table", "filter",
"--insert", "FORWARD",
"--in-interface", iface,
"--out-interface", iface,
"--jump", "ACCEPT",
NULL);
} }
/** /**
@ -653,27 +546,17 @@ iptablesAddForwardAllowCross(int family,
* *
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int void
iptablesRemoveForwardAllowCross(int family, iptablesRemoveForwardAllowCross(virFirewallPtr fw,
virFirewallLayer layer,
const char *iface) const char *iface)
{ {
return iptablesForwardAllowCross(family, iface, REMOVE); virFirewallAddRule(fw, layer,
} "--table", "filter",
"--delete", "FORWARD",
/* Drop all traffic trying to forward from the bridge.
* ie the bridge is the in interface
*/
static int
iptablesForwardRejectOut(int family,
const char *iface,
int action)
{
return iptablesAddRemoveRule("filter", "FORWARD",
family,
action,
"--in-interface", iface, "--in-interface", iface,
"--jump", "REJECT", "--out-interface", iface,
"--jump", "ACCEPT",
NULL); NULL);
} }
@ -687,11 +570,17 @@ iptablesForwardRejectOut(int family,
* *
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int void
iptablesAddForwardRejectOut(int family, iptablesAddForwardRejectOut(virFirewallPtr fw,
virFirewallLayer layer,
const char *iface) const char *iface)
{ {
return iptablesForwardRejectOut(family, iface, ADD); virFirewallAddRule(fw, layer,
"--table", "filter",
"--insert", "FORWARD",
"--in-interface", iface,
"--jump", "REJECT",
NULL);
} }
/** /**
@ -704,32 +593,20 @@ iptablesAddForwardRejectOut(int family,
* *
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int void
iptablesRemoveForwardRejectOut(int family, iptablesRemoveForwardRejectOut(virFirewallPtr fw,
virFirewallLayer layer,
const char *iface) const char *iface)
{ {
return iptablesForwardRejectOut(family, iface, REMOVE); virFirewallAddRule(fw, layer,
} "--table", "filter",
"--delete", "FORWARD",
"--in-interface", iface,
/* Drop all traffic trying to forward to the bridge.
* ie the bridge is the out interface
*/
static int
iptablesForwardRejectIn(int family,
const char *iface,
int action)
{
return iptablesAddRemoveRule("filter", "FORWARD",
family,
action,
"--out-interface", iface,
"--jump", "REJECT", "--jump", "REJECT",
NULL); NULL);
} }
/** /**
* iptablesAddForwardRejectIn: * iptablesAddForwardRejectIn:
* @ctx: pointer to the IP table context * @ctx: pointer to the IP table context
@ -740,11 +617,17 @@ iptablesForwardRejectIn(int family,
* *
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int void
iptablesAddForwardRejectIn(int family, iptablesAddForwardRejectIn(virFirewallPtr fw,
virFirewallLayer layer,
const char *iface) const char *iface)
{ {
return iptablesForwardRejectIn(family, iface, ADD); virFirewallAddRule(fw, layer,
"--table", "filter",
"--insert", "FORWARD",
"--out-interface", iface,
"--jump", "REJECT",
NULL);
} }
/** /**
@ -757,11 +640,17 @@ iptablesAddForwardRejectIn(int family,
* *
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int void
iptablesRemoveForwardRejectIn(int family, iptablesRemoveForwardRejectIn(virFirewallPtr fw,
virFirewallLayer layer,
const char *iface) const char *iface)
{ {
return iptablesForwardRejectIn(family, iface, REMOVE); virFirewallAddRule(fw, layer,
"--table", "filter",
"--delete", "FORWARD",
"--out-interface", iface,
"--jump", "REJECT",
NULL);
} }
@ -769,7 +658,8 @@ iptablesRemoveForwardRejectIn(int family,
* with the bridge * with the bridge
*/ */
static int static int
iptablesForwardMasquerade(virSocketAddr *netaddr, iptablesForwardMasquerade(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *physdev, const char *physdev,
virSocketAddrRangePtr addr, virSocketAddrRangePtr addr,
@ -783,7 +673,7 @@ iptablesForwardMasquerade(virSocketAddr *netaddr,
char *addrEndStr = NULL; char *addrEndStr = NULL;
char *portRangeStr = NULL; char *portRangeStr = NULL;
char *natRangeStr = NULL; char *natRangeStr = NULL;
virCommandPtr cmd = NULL; virFirewallRulePtr rule;
if (!(networkstr = iptablesFormatNetwork(netaddr, prefix))) if (!(networkstr = iptablesFormatNetwork(netaddr, prefix)))
return -1; return -1;
@ -805,16 +695,25 @@ iptablesForwardMasquerade(virSocketAddr *netaddr,
} }
} }
cmd = iptablesCommandNew("nat", "POSTROUTING", AF_INET, action); if (protocol && protocol[0]) {
virCommandAddArgList(cmd, "--source", networkstr, NULL); rule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
"--table", "nat",
if (protocol && protocol[0]) action == ADD ? "--insert" : "--delete", "POSTROUTING",
virCommandAddArgList(cmd, "-p", protocol, NULL); "--source", networkstr,
"-p", protocol,
virCommandAddArgList(cmd, "!", "--destination", networkstr, NULL); "!", "--destination", networkstr,
NULL);
} else {
rule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
"--table", "nat",
action == ADD ? "--insert" : "--delete", "POSTROUTING",
"--source", networkstr,
"!", "--destination", networkstr,
NULL);
}
if (physdev && physdev[0]) if (physdev && physdev[0])
virCommandAddArgList(cmd, "--out-interface", physdev, NULL); virFirewallRuleAddArgList(fw, rule, "--out-interface", physdev, NULL);
if (protocol && protocol[0]) { if (protocol && protocol[0]) {
if (port->start == 0 && port->end == 0) { if (port->start == 0 && port->end == 0) {
@ -848,18 +747,20 @@ iptablesForwardMasquerade(virSocketAddr *netaddr,
if (r < 0) if (r < 0)
goto cleanup; goto cleanup;
virCommandAddArgList(cmd, "--jump", "SNAT", virFirewallRuleAddArgList(fw, rule,
"--jump", "SNAT",
"--to-source", natRangeStr, NULL); "--to-source", natRangeStr, NULL);
} else { } else {
virCommandAddArgList(cmd, "--jump", "MASQUERADE", NULL); virFirewallRuleAddArgList(fw, rule,
"--jump", "MASQUERADE", NULL);
if (portRangeStr && portRangeStr[0]) if (portRangeStr && portRangeStr[0])
virCommandAddArgList(cmd, "--to-ports", &portRangeStr[1], NULL); virFirewallRuleAddArgList(fw, rule,
"--to-ports", &portRangeStr[1], NULL);
} }
ret = virCommandRun(cmd, NULL); ret = 0;
cleanup: cleanup:
virCommandFree(cmd);
VIR_FREE(networkstr); VIR_FREE(networkstr);
VIR_FREE(addrStartStr); VIR_FREE(addrStartStr);
VIR_FREE(addrEndStr); VIR_FREE(addrEndStr);
@ -882,14 +783,15 @@ iptablesForwardMasquerade(virSocketAddr *netaddr,
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int int
iptablesAddForwardMasquerade(virSocketAddr *netaddr, iptablesAddForwardMasquerade(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *physdev, const char *physdev,
virSocketAddrRangePtr addr, virSocketAddrRangePtr addr,
virPortRangePtr port, virPortRangePtr port,
const char *protocol) const char *protocol)
{ {
return iptablesForwardMasquerade(netaddr, prefix, physdev, addr, port, return iptablesForwardMasquerade(fw, netaddr, prefix, physdev, addr, port,
protocol, ADD); protocol, ADD);
} }
@ -907,14 +809,15 @@ iptablesAddForwardMasquerade(virSocketAddr *netaddr,
* Returns 0 in case of success or an error code otherwise * Returns 0 in case of success or an error code otherwise
*/ */
int int
iptablesRemoveForwardMasquerade(virSocketAddr *netaddr, iptablesRemoveForwardMasquerade(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *physdev, const char *physdev,
virSocketAddrRangePtr addr, virSocketAddrRangePtr addr,
virPortRangePtr port, virPortRangePtr port,
const char *protocol) const char *protocol)
{ {
return iptablesForwardMasquerade(netaddr, prefix, physdev, addr, port, return iptablesForwardMasquerade(fw, netaddr, prefix, physdev, addr, port,
protocol, REMOVE); protocol, REMOVE);
} }
@ -923,7 +826,8 @@ iptablesRemoveForwardMasquerade(virSocketAddr *netaddr,
* if said traffic targets @destaddr. * if said traffic targets @destaddr.
*/ */
static int static int
iptablesForwardDontMasquerade(virSocketAddr *netaddr, iptablesForwardDontMasquerade(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *physdev, const char *physdev,
const char *destaddr, const char *destaddr,
@ -931,7 +835,6 @@ iptablesForwardDontMasquerade(virSocketAddr *netaddr,
{ {
int ret = -1; int ret = -1;
char *networkstr = NULL; char *networkstr = NULL;
virCommandPtr cmd = NULL;
if (!(networkstr = iptablesFormatNetwork(netaddr, prefix))) if (!(networkstr = iptablesFormatNetwork(netaddr, prefix)))
return -1; return -1;
@ -944,16 +847,26 @@ iptablesForwardDontMasquerade(virSocketAddr *netaddr,
goto cleanup; goto cleanup;
} }
cmd = iptablesCommandNew("nat", "POSTROUTING", AF_INET, action);
if (physdev && physdev[0]) if (physdev && physdev[0])
virCommandAddArgList(cmd, "--out-interface", physdev, NULL); virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
"--table", "nat",
action == ADD ? "--insert" : "--delete", "POSTROUTING",
"--out-interface", physdev,
"--source", networkstr,
"--destination", destaddr,
"--jump", "RETURN",
NULL);
else
virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
"--table", "nat",
action == ADD ? "--insert" : "--delete", "POSTROUTING",
"--source", networkstr,
"--destination", destaddr,
"--jump", "RETURN",
NULL);
virCommandAddArgList(cmd, "--source", networkstr, ret = 0;
"--destination", destaddr, "--jump", "RETURN", NULL);
ret = virCommandRun(cmd, NULL);
cleanup: cleanup:
virCommandFree(cmd);
VIR_FREE(networkstr); VIR_FREE(networkstr);
return ret; return ret;
} }
@ -973,12 +886,13 @@ iptablesForwardDontMasquerade(virSocketAddr *netaddr,
* Returns 0 in case of success or an error code otherwise. * Returns 0 in case of success or an error code otherwise.
*/ */
int int
iptablesAddDontMasquerade(virSocketAddr *netaddr, iptablesAddDontMasquerade(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *physdev, const char *physdev,
const char *destaddr) const char *destaddr)
{ {
return iptablesForwardDontMasquerade(netaddr, prefix, physdev, destaddr, return iptablesForwardDontMasquerade(fw, netaddr, prefix, physdev, destaddr,
ADD); ADD);
} }
@ -997,18 +911,20 @@ iptablesAddDontMasquerade(virSocketAddr *netaddr,
* Returns 0 in case of success or an error code otherwise. * Returns 0 in case of success or an error code otherwise.
*/ */
int int
iptablesRemoveDontMasquerade(virSocketAddr *netaddr, iptablesRemoveDontMasquerade(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *physdev, const char *physdev,
const char *destaddr) const char *destaddr)
{ {
return iptablesForwardDontMasquerade(netaddr, prefix, physdev, destaddr, return iptablesForwardDontMasquerade(fw, netaddr, prefix, physdev, destaddr,
REMOVE); REMOVE);
} }
static int static void
iptablesOutputFixUdpChecksum(const char *iface, iptablesOutputFixUdpChecksum(virFirewallPtr fw,
const char *iface,
int port, int port,
int action) int action)
{ {
@ -1017,9 +933,9 @@ iptablesOutputFixUdpChecksum(const char *iface,
snprintf(portstr, sizeof(portstr), "%d", port); snprintf(portstr, sizeof(portstr), "%d", port);
portstr[sizeof(portstr) - 1] = '\0'; portstr[sizeof(portstr) - 1] = '\0';
return iptablesAddRemoveRule("mangle", "POSTROUTING", virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
AF_INET, "--table", "mangle",
action, action == ADD ? "--insert" : "--delete", "POSTROUTING",
"--out-interface", iface, "--out-interface", iface,
"--protocol", "udp", "--protocol", "udp",
"--destination-port", portstr, "--destination-port", portstr,
@ -1037,16 +953,13 @@ iptablesOutputFixUdpChecksum(const char *iface,
* checksum of packets with the given destination @port. * checksum of packets with the given destination @port.
* the given @iface interface for TCP packets. * the given @iface interface for TCP packets.
* *
* Returns 0 in case of success or an error code in case of error.
* (NB: if the system's iptables does not support checksum mangling,
* this will return an error, which should be ignored.)
*/ */
void
int iptablesAddOutputFixUdpChecksum(virFirewallPtr fw,
iptablesAddOutputFixUdpChecksum(const char *iface, const char *iface,
int port) int port)
{ {
return iptablesOutputFixUdpChecksum(iface, port, ADD); iptablesOutputFixUdpChecksum(fw, iface, port, ADD);
} }
/** /**
@ -1057,14 +970,11 @@ iptablesAddOutputFixUdpChecksum(const char *iface,
* *
* Removes the checksum fixup rule that was previous added with * Removes the checksum fixup rule that was previous added with
* iptablesAddOutputFixUdpChecksum. * iptablesAddOutputFixUdpChecksum.
*
* Returns 0 in case of success or an error code in case of error
* (again, if iptables doesn't support checksum fixup, this will
* return an error, which should be ignored)
*/ */
int void
iptablesRemoveOutputFixUdpChecksum(const char *iface, iptablesRemoveOutputFixUdpChecksum(virFirewallPtr fw,
const char *iface,
int port) int port)
{ {
return iptablesOutputFixUdpChecksum(iface, port, REMOVE); iptablesOutputFixUdpChecksum(fw, iface, port, REMOVE);
} }

View File

@ -21,97 +21,131 @@
* Mark McLoughlin <markmc@redhat.com> * Mark McLoughlin <markmc@redhat.com>
*/ */
#ifndef __QEMUD_IPTABLES_H__ #ifndef __VIR_IPTABLES_H__
# define __QEMUD_IPTABLES_H__ # define __VIR_IPTABLES_H__
# include "virsocketaddr.h" # include "virsocketaddr.h"
# include "virfirewall.h"
int iptablesAddTcpInput (int family, void iptablesAddTcpInput (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface, const char *iface,
int port); int port);
int iptablesRemoveTcpInput (int family, void iptablesRemoveTcpInput (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface, const char *iface,
int port); int port);
int iptablesAddUdpInput (int family, void iptablesAddUdpInput (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface, const char *iface,
int port); int port);
int iptablesRemoveUdpInput (int family, void iptablesRemoveUdpInput (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface, const char *iface,
int port); int port);
int iptablesAddUdpOutput (int family, void iptablesAddUdpOutput (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface, const char *iface,
int port); int port);
int iptablesRemoveUdpOutput (int family, void iptablesRemoveUdpOutput (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface, const char *iface,
int port); int port);
int iptablesAddForwardAllowOut (virSocketAddr *netaddr, int iptablesAddForwardAllowOut (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev); const char *physdev)
int iptablesRemoveForwardAllowOut (virSocketAddr *netaddr, ATTRIBUTE_RETURN_CHECK;
int iptablesRemoveForwardAllowOut (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev); const char *physdev)
ATTRIBUTE_RETURN_CHECK;
int iptablesAddForwardAllowRelatedIn(virSocketAddr *netaddr, int iptablesAddForwardAllowRelatedIn(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev); const char *physdev)
int iptablesRemoveForwardAllowRelatedIn(virSocketAddr *netaddr, ATTRIBUTE_RETURN_CHECK;
int iptablesRemoveForwardAllowRelatedIn(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev); const char *physdev)
ATTRIBUTE_RETURN_CHECK;
int iptablesAddForwardAllowIn (virSocketAddr *netaddr, int iptablesAddForwardAllowIn (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev); const char *physdev)
int iptablesRemoveForwardAllowIn (virSocketAddr *netaddr, ATTRIBUTE_RETURN_CHECK;
int iptablesRemoveForwardAllowIn (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *iface, const char *iface,
const char *physdev); const char *physdev)
ATTRIBUTE_RETURN_CHECK;
int iptablesAddForwardAllowCross (int family, void iptablesAddForwardAllowCross (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface); const char *iface);
int iptablesRemoveForwardAllowCross (int family, void iptablesRemoveForwardAllowCross (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface); const char *iface);
int iptablesAddForwardRejectOut (int family, void iptablesAddForwardRejectOut (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface); const char *iface);
int iptablesRemoveForwardRejectOut (int family, void iptablesRemoveForwardRejectOut (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface); const char *iface);
int iptablesAddForwardRejectIn (int family, void iptablesAddForwardRejectIn (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface); const char *iface);
int iptablesRemoveForwardRejectIn (int family, void iptablesRemoveForwardRejectIn (virFirewallPtr fw,
virFirewallLayer layery,
const char *iface); const char *iface);
int iptablesAddForwardMasquerade (virSocketAddr *netaddr, int iptablesAddForwardMasquerade (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *physdev, const char *physdev,
virSocketAddrRangePtr addr, virSocketAddrRangePtr addr,
virPortRangePtr port, virPortRangePtr port,
const char *protocol); const char *protocol)
int iptablesRemoveForwardMasquerade (virSocketAddr *netaddr, ATTRIBUTE_RETURN_CHECK;
int iptablesRemoveForwardMasquerade (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *physdev, const char *physdev,
virSocketAddrRangePtr addr, virSocketAddrRangePtr addr,
virPortRangePtr port, virPortRangePtr port,
const char *protocol); const char *protocol)
int iptablesAddDontMasquerade (virSocketAddr *netaddr, ATTRIBUTE_RETURN_CHECK;
int iptablesAddDontMasquerade (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *physdev, const char *physdev,
const char *destaddr); const char *destaddr)
int iptablesRemoveDontMasquerade (virSocketAddr *netaddr, ATTRIBUTE_RETURN_CHECK;
int iptablesRemoveDontMasquerade (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix, unsigned int prefix,
const char *physdev, const char *physdev,
const char *destaddr); const char *destaddr)
int iptablesAddOutputFixUdpChecksum (const char *iface, ATTRIBUTE_RETURN_CHECK;
void iptablesAddOutputFixUdpChecksum (virFirewallPtr fw,
const char *iface,
int port); int port);
int iptablesRemoveOutputFixUdpChecksum (const char *iface, void iptablesRemoveOutputFixUdpChecksum (virFirewallPtr fw,
const char *iface,
int port); int port);
#endif /* __QEMUD_IPTABLES_H__ */ #endif /* __VIR_IPTABLES_H__ */