#include "viriptables.h"
#include "virstring.h"
#include "virlog.h"
+#include "virfirewall.h"
#define VIR_FROM_THIS VIR_FROM_NONE
static const char networkLocalBroadcast[] = "255.255.255.255/32";
static int
-networkAddMasqueradingFirewallRules(virNetworkObjPtr network,
+networkAddMasqueradingFirewallRules(virFirewallPtr fw,
+ virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
{
int prefix = virNetworkIpDefPrefix(ipdef);
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid prefix or netmask for '%s'"),
network->def->bridge);
- goto masqerr1;
+ return -1;
}
/* allow forwarding packets from the bridge interface */
- if (iptablesAddForwardAllowOut(&ipdef->address,
+ if (iptablesAddForwardAllowOut(fw,
+ &ipdef->address,
prefix,
network->def->bridge,
- forwardIf) < 0) {
- virReportError(VIR_ERR_SYSTEM_ERROR,
- _("failed to add iptables rule to allow forwarding from '%s'"),
- network->def->bridge);
- goto masqerr1;
- }
+ forwardIf) < 0)
+ return -1;
/* allow forwarding packets to the bridge interface if they are
* part of an existing connection
*/
- if (iptablesAddForwardAllowRelatedIn(&ipdef->address,
+ if (iptablesAddForwardAllowRelatedIn(fw,
+ &ipdef->address,
prefix,
network->def->bridge,
- forwardIf) < 0) {
- virReportError(VIR_ERR_SYSTEM_ERROR,
- _("failed to add iptables rule to allow forwarding to '%s'"),
- network->def->bridge);
- goto masqerr2;
- }
+ forwardIf) < 0)
+ return -1;
/*
* Enable masquerading.
*/
/* First the generic masquerade rule for other protocols */
- if (iptablesAddForwardMasquerade(&ipdef->address,
+ if (iptablesAddForwardMasquerade(fw,
+ &ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
- NULL) < 0) {
- if (forwardIf)
- 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;
- }
+ NULL) < 0)
+ return -1;
/* UDP with a source port restriction */
- if (iptablesAddForwardMasquerade(&ipdef->address,
+ if (iptablesAddForwardMasquerade(fw,
+ &ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
- "udp") < 0) {
- if (forwardIf)
- 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;
- }
+ "udp") < 0)
+ return -1;
/* TCP with a source port restriction */
- if (iptablesAddForwardMasquerade(&ipdef->address,
+ if (iptablesAddForwardMasquerade(fw,
+ &ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
- "tcp") < 0) {
- if (forwardIf)
- 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;
- }
+ "tcp") < 0)
+ return -1;
/* exempt local network broadcast address as destination */
- if (iptablesAddDontMasquerade(&ipdef->address,
+ if (iptablesAddDontMasquerade(fw,
+ &ipdef->address,
prefix,
forwardIf,
- networkLocalBroadcast) < 0) {
- if (forwardIf)
- 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;
- }
+ networkLocalBroadcast) < 0)
+ return -1;
/* exempt local multicast range as destination */
- if (iptablesAddDontMasquerade(&ipdef->address,
+ if (iptablesAddDontMasquerade(fw,
+ &ipdef->address,
prefix,
forwardIf,
- networkLocalMulticast) < 0) {
- if (forwardIf)
- 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;
- }
+ networkLocalMulticast) < 0)
+ return -1;
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
-networkRemoveMasqueradingFirewallRules(virNetworkObjPtr network,
+static int
+networkRemoveMasqueradingFirewallRules(virFirewallPtr fw,
+ virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
{
int prefix = virNetworkIpDefPrefix(ipdef);
const char *forwardIf = virNetworkDefForwardIf(network->def, 0);
- if (prefix >= 0) {
- iptablesRemoveDontMasquerade(&ipdef->address,
+ if (prefix < 0)
+ return 0;
+
+ if (iptablesRemoveDontMasquerade(fw,
+ &ipdef->address,
prefix,
forwardIf,
- networkLocalMulticast);
- iptablesRemoveDontMasquerade(&ipdef->address,
+ networkLocalMulticast) < 0)
+ return -1;
+
+ if (iptablesRemoveDontMasquerade(fw,
+ &ipdef->address,
prefix,
forwardIf,
- networkLocalBroadcast);
- iptablesRemoveForwardMasquerade(&ipdef->address,
+ networkLocalBroadcast) < 0)
+ return -1;
+
+ if (iptablesRemoveForwardMasquerade(fw,
+ &ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
- "tcp");
- iptablesRemoveForwardMasquerade(&ipdef->address,
+ "tcp") < 0)
+ return -1;
+
+ if (iptablesRemoveForwardMasquerade(fw,
+ &ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
- "udp");
- iptablesRemoveForwardMasquerade(&ipdef->address,
+ "udp") < 0)
+ return -1;
+
+ if (iptablesRemoveForwardMasquerade(fw,
+ &ipdef->address,
prefix,
forwardIf,
&network->def->forward.addr,
&network->def->forward.port,
- NULL);
+ NULL) < 0)
+ return -1;
- iptablesRemoveForwardAllowRelatedIn(&ipdef->address,
+ if (iptablesRemoveForwardAllowRelatedIn(fw,
+ &ipdef->address,
prefix,
network->def->bridge,
- forwardIf);
- iptablesRemoveForwardAllowOut(&ipdef->address,
+ forwardIf) < 0)
+ return -1;
+
+ if (iptablesRemoveForwardAllowOut(fw,
+ &ipdef->address,
prefix,
network->def->bridge,
- forwardIf);
- }
+ forwardIf) < 0)
+ return -1;
+
+ return 0;
}
+
static int
-networkAddRoutingFirewallRules(virNetworkObjPtr network,
+networkAddRoutingFirewallRules(virFirewallPtr fw,
+ virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
{
int prefix = virNetworkIpDefPrefix(ipdef);
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid prefix or netmask for '%s'"),
network->def->bridge);
- goto routeerr1;
+ return -1;
}
/* allow routing packets from the bridge interface */
- if (iptablesAddForwardAllowOut(&ipdef->address,
+ if (iptablesAddForwardAllowOut(fw,
+ &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;
- }
+ forwardIf) < 0)
+ return -1;
/* allow routing packets to the bridge interface */
- if (iptablesAddForwardAllowIn(&ipdef->address,
+ if (iptablesAddForwardAllowIn(fw,
+ &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;
- }
+ forwardIf) < 0)
+ return -1;
return 0;
-
- routeerr2:
- iptablesRemoveForwardAllowOut(&ipdef->address,
- prefix,
- network->def->bridge,
- forwardIf);
- routeerr1:
- return -1;
}
-static void
-networkRemoveRoutingFirewallRules(virNetworkObjPtr network,
+static int
+networkRemoveRoutingFirewallRules(virFirewallPtr fw,
+ virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
{
int prefix = virNetworkIpDefPrefix(ipdef);
const char *forwardIf = virNetworkDefForwardIf(network->def, 0);
- if (prefix >= 0) {
- iptablesRemoveForwardAllowIn(&ipdef->address,
+ if (prefix < 0)
+ return 0;
+
+ if (iptablesRemoveForwardAllowIn(fw,
+ &ipdef->address,
prefix,
network->def->bridge,
- forwardIf);
+ forwardIf) < 0)
+ return -1;
- iptablesRemoveForwardAllowOut(&ipdef->address,
+ if (iptablesRemoveForwardAllowOut(fw,
+ &ipdef->address,
prefix,
network->def->bridge,
- forwardIf);
+ forwardIf) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static void
+networkAddGeneralIPv4FirewallRules(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 || ipv4def->tftproot)
+ break;
+ }
+
+ /* allow DHCP requests through to dnsmasq */
+ iptablesAddTcpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 67);
+ iptablesAddUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 67);
+ iptablesAddUdpOutput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 68);
+
+ /* allow DNS requests through to dnsmasq */
+ iptablesAddTcpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 53);
+ iptablesAddUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 53);
+
+ /* allow TFTP requests through to dnsmasq if necessary */
+ if (ipv4def && ipv4def->tftproot)
+ iptablesAddUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge, 69);
+
+ /* Catch all rules to block forwarding to/from bridges */
+ iptablesAddForwardRejectOut(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge);
+ iptablesAddForwardRejectIn(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge);
+
+ /* Allow traffic between guests on the same bridge */
+ iptablesAddForwardAllowCross(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge);
+}
+
+static void
+networkRemoveGeneralIPv4FirewallRules(virFirewallPtr fw,
+ virNetworkObjPtr network)
+{
+ size_t i;
+ virNetworkIpDefPtr ipv4def;
+
+ for (i = 0;
+ (ipv4def = virNetworkDefGetIpByIndex(network->def, AF_INET, i));
+ i++) {
+ if (ipv4def->nranges || ipv4def->nhosts || ipv4def->tftproot)
+ break;
}
+
+ iptablesRemoveForwardAllowCross(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge);
+ iptablesRemoveForwardRejectIn(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge);
+ iptablesRemoveForwardRejectOut(fw, VIR_FIREWALL_LAYER_IPV4, network->def->bridge);
+
+ 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);
}
+
/* 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)
+static void
+networkAddGeneralIPv6FirewallRules(virFirewallPtr fw,
+ virNetworkObjPtr network)
{
if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0) &&
!network->def->ipv6nogw) {
- return 0;
+ return;
}
/* 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;
- }
+ 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 */
- 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;
- }
+ iptablesAddForwardAllowCross(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge);
- 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;
+ 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);
}
-
- 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;
}
static void
-networkRemoveGeneralIp6tablesRules(virNetworkObjPtr network)
+networkRemoveGeneralIPv6FirewallRules(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);
+ 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(AF_INET6, network->def->bridge);
- iptablesRemoveForwardRejectIn(AF_INET6, network->def->bridge);
- iptablesRemoveForwardRejectOut(AF_INET6, network->def->bridge);
+ 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 int
-networkAddGeneralFirewallRules(virNetworkObjPtr network)
+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;
for (i = 0;
(ipv4def = virNetworkDefGetIpByIndex(network->def, AF_INET, i));
i++) {
- if (ipv4def->nranges || ipv4def->nhosts || ipv4def->tftproot)
+ if (ipv4def->nranges || ipv4def->nhosts)
break;
}
- /* allow DHCP requests through to dnsmasq */
-
- if (iptablesAddTcpInput(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 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 */
- if (iptablesAddTcpInput(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 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 */
- if (ipv4def && ipv4def->tftproot &&
- iptablesAddUdpInput(AF_INET, network->def->bridge, 69) < 0) {
- 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 */
-
- if (iptablesAddForwardRejectOut(AF_INET, network->def->bridge) < 0) {
- 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 */
- if (iptablesAddForwardAllowCross(AF_INET, network->def->bridge) < 0) {
- 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;
+ if (ipv4def)
+ iptablesAddOutputFixUdpChecksum(fw, network->def->bridge, 68);
}
static void
-networkRemoveGeneralFirewallRules(virNetworkObjPtr network)
+networkRemoveChecksumFirewallRules(virFirewallPtr fw,
+ virNetworkObjPtr network)
{
size_t i;
virNetworkIpDefPtr ipv4def;
- networkRemoveGeneralIp6tablesRules(network);
-
+ /* 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 || ipv4def->tftproot)
+ if (ipv4def->nranges || ipv4def->nhosts)
break;
}
- iptablesRemoveForwardAllowCross(AF_INET, network->def->bridge);
- iptablesRemoveForwardRejectIn(AF_INET, network->def->bridge);
- iptablesRemoveForwardRejectOut(AF_INET, network->def->bridge);
- if (ipv4def && ipv4def->tftproot) {
- iptablesRemoveUdpInput(AF_INET, network->def->bridge, 69);
- }
- iptablesRemoveUdpInput(AF_INET, network->def->bridge, 53);
- iptablesRemoveTcpInput(AF_INET, network->def->bridge, 53);
- if (ipv4def && (ipv4def->nranges || ipv4def->nhosts)) {
- iptablesRemoveOutputFixUdpChecksum(network->def->bridge, 68);
- }
- iptablesRemoveUdpOutput(AF_INET, network->def->bridge, 68);
- iptablesRemoveUdpInput(AF_INET, network->def->bridge, 67);
- iptablesRemoveTcpInput(AF_INET, network->def->bridge, 67);
+ if (ipv4def)
+ iptablesRemoveOutputFixUdpChecksum(fw, network->def->bridge, 68);
}
static int
-networkAddIpSpecificFirewallRules(virNetworkObjPtr network,
+networkAddIpSpecificFirewallRules(virFirewallPtr fw,
+ virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
{
/* NB: in the case of IPv6, routing rules are added when the
if (network->def->forward.type == VIR_NETWORK_FORWARD_NAT) {
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))
- return networkAddRoutingFirewallRules(network, ipdef);
+ return networkAddRoutingFirewallRules(fw, network, ipdef);
} else if (network->def->forward.type == VIR_NETWORK_FORWARD_ROUTE) {
- return networkAddRoutingFirewallRules(network, ipdef);
+ return networkAddRoutingFirewallRules(fw, network, ipdef);
}
return 0;
}
-static void
-networkRemoveIpSpecificFirewallRules(virNetworkObjPtr network,
+static int
+networkRemoveIpSpecificFirewallRules(virFirewallPtr fw,
+ virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
{
if (network->def->forward.type == VIR_NETWORK_FORWARD_NAT) {
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))
- networkRemoveRoutingFirewallRules(network, ipdef);
+ return networkRemoveRoutingFirewallRules(fw, network, ipdef);
} 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 */
int networkAddFirewallRules(virNetworkObjPtr network)
{
- size_t i, j;
+ size_t i;
virNetworkIpDefPtr ipdef;
- virErrorPtr orig_error;
+ virFirewallPtr fw = NULL;
+ int ret = -1;
- /* Add "once per network" rules */
- if (networkAddGeneralFirewallRules(network) < 0)
- return -1;
+ fw = virFirewallNew();
+
+ virFirewallStartTransaction(fw, 0);
+
+ networkAddGeneralFirewallRules(fw, network);
for (i = 0;
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i));
i++) {
- /* Add address-specific iptables rules */
- if (networkAddIpSpecificFirewallRules(network, ipdef) < 0) {
- goto err;
- }
+ if (networkAddIpSpecificFirewallRules(fw, network, ipdef) < 0)
+ goto cleanup;
}
- return 0;
- err:
- /* store the previous error message before attempting removal of rules */
- orig_error = virSaveLastError();
+ virFirewallStartRollback(fw, 0);
- /* The final failed call to networkAddIpSpecificFirewallRules will
- * have removed any rules it created, but we need to remove those
- * added for previous IP addresses.
- */
- for (j = 0; j < i; j++) {
- if ((ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, j)))
- networkRemoveIpSpecificFirewallRules(network, ipdef);
+ for (i = 0;
+ (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i));
+ i++) {
+ if (networkRemoveIpSpecificFirewallRules(fw, network, ipdef) < 0)
+ goto cleanup;
}
- networkRemoveGeneralFirewallRules(network);
+ networkRemoveGeneralFirewallRules(fw, network);
+
+ virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
+ networkAddChecksumFirewallRules(fw, network);
+
+ if (virFirewallApply(fw) < 0)
+ goto cleanup;
- /* return the original error */
- virSetError(orig_error);
- virFreeError(orig_error);
- return -1;
+ ret = 0;
+ cleanup:
+ virFirewallFree(fw);
+ return ret;
}
/* Remove all rules for all ip addresses (and general rules) on a network */
{
size_t i;
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;
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i));
i++) {
- networkRemoveIpSpecificFirewallRules(network, ipdef);
+ if (networkRemoveIpSpecificFirewallRules(fw, network, ipdef) < 0)
+ goto cleanup;
}
- networkRemoveGeneralFirewallRules(network);
+ networkRemoveGeneralFirewallRules(fw, network);
+
+ virFirewallApply(fw);
+
+ cleanup:
+ virFirewallFree(fw);
}
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
enum {
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) {
- cmd = virCommandNew((family == AF_INET6)
- ? IP6TABLES_PATH : IPTABLES_PATH);
- 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,
+static void
+iptablesInput(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port,
int action,
snprintf(portstr, sizeof(portstr), "%d", port);
portstr[sizeof(portstr) - 1] = '\0';
- return iptablesAddRemoveRule("filter", "INPUT",
- family,
- action,
- "--in-interface", iface,
- "--protocol", tcp ? "tcp" : "udp",
- "--destination-port", portstr,
- "--jump", "ACCEPT",
- NULL);
+ virFirewallAddRule(fw, layer,
+ "--table", "filter",
+ action == ADD ? "--insert" : "--delete", "INPUT",
+ "--in-interface", iface,
+ "--protocol", tcp ? "tcp" : "udp",
+ "--destination-port", portstr,
+ "--jump", "ACCEPT",
+ NULL);
}
-static int
-iptablesOutput(int family,
+static void
+iptablesOutput(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port,
int action,
snprintf(portstr, sizeof(portstr), "%d", port);
portstr[sizeof(portstr) - 1] = '\0';
- return iptablesAddRemoveRule("filter", "OUTPUT",
- family,
- action,
- "--out-interface", iface,
- "--protocol", tcp ? "tcp" : "udp",
- "--destination-port", portstr,
- "--jump", "ACCEPT",
- NULL);
+ virFirewallAddRule(fw, layer,
+ "--table", "filter",
+ action == ADD ? "--insert" : "--delete", "OUTPUT",
+ "--out-interface", iface,
+ "--protocol", tcp ? "tcp" : "udp",
+ "--destination-port", portstr,
+ "--jump", "ACCEPT",
+ NULL);
}
/**
*
* Add an input to the IP table allowing access to the given @port on
* the given @iface interface for TCP packets
- *
- * Returns 0 in case of success or an error code in case of error
*/
-
-int
-iptablesAddTcpInput(int family,
+void
+iptablesAddTcpInput(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port)
{
- return iptablesInput(family, iface, port, ADD, 1);
+ iptablesInput(fw, layer, iface, port, ADD, 1);
}
/**
*
* Removes an input from the IP table, hence forbidding access to the given
* @port on the given @iface interface for TCP packets
- *
- * Returns 0 in case of success or an error code in case of error
*/
-int
-iptablesRemoveTcpInput(int family,
+void
+iptablesRemoveTcpInput(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port)
{
- return iptablesInput(family, iface, port, REMOVE, 1);
+ iptablesInput(fw, layer, iface, port, REMOVE, 1);
}
/**
*
* Add an input to the IP table allowing access to the given @port on
* the given @iface interface for UDP packets
- *
- * Returns 0 in case of success or an error code in case of error
*/
-
-int
-iptablesAddUdpInput(int family,
+void
+iptablesAddUdpInput(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port)
{
- return iptablesInput(family, iface, port, ADD, 0);
+ iptablesInput(fw, layer, iface, port, ADD, 0);
}
/**
*
* Removes an input from the IP table, hence forbidding access to the given
* @port on the given @iface interface for UDP packets
- *
- * Returns 0 in case of success or an error code in case of error
*/
-int
-iptablesRemoveUdpInput(int family,
+void
+iptablesRemoveUdpInput(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port)
{
- return iptablesInput(family, iface, port, REMOVE, 0);
+ return iptablesInput(fw, layer, iface, port, REMOVE, 0);
}
/**
*
* Add an output to the IP table allowing access to the given @port from
* the given @iface interface for UDP packets
- *
- * Returns 0 in case of success or an error code in case of error
*/
-
-int
-iptablesAddUdpOutput(int family,
+void
+iptablesAddUdpOutput(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port)
{
- return iptablesOutput(family, iface, port, ADD, 0);
+ iptablesOutput(fw, layer, iface, port, ADD, 0);
}
/**
*
* Removes an output from the IP table, hence forbidding access to the given
* @port from the given @iface interface for UDP packets
- *
- * Returns 0 in case of success or an error code in case of error
*/
-int
-iptablesRemoveUdpOutput(int family,
+void
+iptablesRemoveUdpOutput(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port)
{
- return iptablesOutput(family, iface, port, REMOVE, 0);
+ iptablesOutput(fw, layer, iface, port, REMOVE, 0);
}
* to proceed to WAN
*/
static int
-iptablesForwardAllowOut(virSocketAddr *netaddr,
+iptablesForwardAllowOut(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
const char *physdev,
int action)
{
- int ret;
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)))
return -1;
- cmd = iptablesCommandNew("filter", "FORWARD",
- 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);
+ 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);
- ret = iptablesCommandRunAndFree(cmd);
VIR_FREE(networkstr);
- return ret;
+ return 0;
}
/**
* Returns 0 in case of success or an error code otherwise
*/
int
-iptablesAddForwardAllowOut(virSocketAddr *netaddr,
+iptablesAddForwardAllowOut(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
const char *physdev)
{
- return iptablesForwardAllowOut(netaddr, prefix, iface, physdev, ADD);
+ return iptablesForwardAllowOut(fw, netaddr, prefix, iface, physdev, ADD);
}
/**
* Returns 0 in case of success or an error code otherwise
*/
int
-iptablesRemoveForwardAllowOut(virSocketAddr *netaddr,
+iptablesRemoveForwardAllowOut(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
const char *physdev)
{
- return iptablesForwardAllowOut(netaddr, prefix, iface, physdev, REMOVE);
+ return iptablesForwardAllowOut(fw, netaddr, prefix, iface, physdev, REMOVE);
}
* and associated with an existing connection
*/
static int
-iptablesForwardAllowRelatedIn(virSocketAddr *netaddr,
+iptablesForwardAllowRelatedIn(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
const char *physdev,
int action)
{
- int ret;
+ virFirewallLayer layer = VIR_SOCKET_ADDR_FAMILY(netaddr) == AF_INET ?
+ VIR_FIREWALL_LAYER_IPV4 : VIR_FIREWALL_LAYER_IPV6;
char *networkstr;
if (!(networkstr = iptablesFormatNetwork(netaddr, prefix)))
return -1;
- if (physdev && physdev[0]) {
- ret = iptablesAddRemoveRule("filter", "FORWARD",
- VIR_SOCKET_ADDR_FAMILY(netaddr),
- action,
- "--destination", networkstr,
- "--in-interface", physdev,
- "--out-interface", iface,
- "--match", "conntrack",
- "--ctstate", "ESTABLISHED,RELATED",
- "--jump", "ACCEPT",
- NULL);
- } else {
- ret = iptablesAddRemoveRule("filter", "FORWARD",
- VIR_SOCKET_ADDR_FAMILY(netaddr),
- action,
- "--destination", networkstr,
- "--out-interface", iface,
- "--match", "conntrack",
- "--ctstate", "ESTABLISHED,RELATED",
- "--jump", "ACCEPT",
- NULL);
- }
+ if (physdev && physdev[0])
+ virFirewallAddRule(fw, layer,
+ "--table", "filter",
+ action == ADD ? "--insert" : "--delete", "FORWARD",
+ "--destination", networkstr,
+ "--in-interface", physdev,
+ "--out-interface", iface,
+ "--match", "conntrack",
+ "--ctstate", "ESTABLISHED,RELATED",
+ "--jump", "ACCEPT",
+ NULL);
+ else
+ virFirewallAddRule(fw, layer,
+ "--table", "filter",
+ action == ADD ? "--insert" : "--delete", "FORWARD",
+ "--destination", networkstr,
+ "--out-interface", iface,
+ "--match", "conntrack",
+ "--ctstate", "ESTABLISHED,RELATED",
+ "--jump", "ACCEPT",
+ NULL);
+
VIR_FREE(networkstr);
- return ret;
+ return 0;
}
/**
* Returns 0 in case of success or an error code otherwise
*/
int
-iptablesAddForwardAllowRelatedIn(virSocketAddr *netaddr,
+iptablesAddForwardAllowRelatedIn(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
const char *physdev)
{
- return iptablesForwardAllowRelatedIn(netaddr, prefix, iface, physdev, ADD);
+ return iptablesForwardAllowRelatedIn(fw, netaddr, prefix, iface, physdev, ADD);
}
/**
* Returns 0 in case of success or an error code otherwise
*/
int
-iptablesRemoveForwardAllowRelatedIn(virSocketAddr *netaddr,
+iptablesRemoveForwardAllowRelatedIn(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
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
*/
static int
-iptablesForwardAllowIn(virSocketAddr *netaddr,
+iptablesForwardAllowIn(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
const char *physdev,
int action)
{
- int ret;
+ virFirewallLayer layer = VIR_SOCKET_ADDR_FAMILY(netaddr) == AF_INET ?
+ VIR_FIREWALL_LAYER_IPV4 : VIR_FIREWALL_LAYER_IPV6;
char *networkstr;
if (!(networkstr = iptablesFormatNetwork(netaddr, prefix)))
return -1;
- if (physdev && physdev[0]) {
- ret = iptablesAddRemoveRule("filter", "FORWARD",
- VIR_SOCKET_ADDR_FAMILY(netaddr),
- action,
- "--destination", networkstr,
- "--in-interface", physdev,
- "--out-interface", iface,
- "--jump", "ACCEPT",
- NULL);
- } else {
- ret = iptablesAddRemoveRule("filter", "FORWARD",
- VIR_SOCKET_ADDR_FAMILY(netaddr),
- action,
- "--destination", networkstr,
- "--out-interface", iface,
- "--jump", "ACCEPT",
- NULL);
- }
+ if (physdev && physdev[0])
+ virFirewallAddRule(fw, layer,
+ "--table", "filter",
+ action == ADD ? "--insert" : "--delete", "FORWARD",
+ "--destination", networkstr,
+ "--in-interface", physdev,
+ "--out-interface", iface,
+ "--jump", "ACCEPT",
+ NULL);
+ else
+ virFirewallAddRule(fw, layer,
+ "--table", "filter",
+ action == ADD ? "--insert" : "--delete", "FORWARD",
+ "--destination", networkstr,
+ "--out-interface", iface,
+ "--jump", "ACCEPT",
+ NULL);
VIR_FREE(networkstr);
- return ret;
+ return 0;
}
/**
* Returns 0 in case of success or an error code otherwise
*/
int
-iptablesAddForwardAllowIn(virSocketAddr *netaddr,
+iptablesAddForwardAllowIn(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
const char *physdev)
{
- return iptablesForwardAllowIn(netaddr, prefix, iface, physdev, ADD);
+ return iptablesForwardAllowIn(fw, netaddr, prefix, iface, physdev, ADD);
}
/**
* Returns 0 in case of success or an error code otherwise
*/
int
-iptablesRemoveForwardAllowIn(virSocketAddr *netaddr,
+iptablesRemoveForwardAllowIn(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
const char *physdev)
{
- return iptablesForwardAllowIn(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);
+ return iptablesForwardAllowIn(fw, netaddr, prefix, iface, physdev, REMOVE);
}
/**
*
* Returns 0 in case of success or an error code otherwise
*/
-int
-iptablesAddForwardAllowCross(int family,
+void
+iptablesAddForwardAllowCross(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface)
{
- return iptablesForwardAllowCross(family, iface, ADD);
+ virFirewallAddRule(fw, layer,
+ "--table", "filter",
+ "--insert", "FORWARD",
+ "--in-interface", iface,
+ "--out-interface", iface,
+ "--jump", "ACCEPT",
+ NULL);
}
/**
*
* Returns 0 in case of success or an error code otherwise
*/
-int
-iptablesRemoveForwardAllowCross(int family,
+void
+iptablesRemoveForwardAllowCross(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface)
{
- return iptablesForwardAllowCross(family, iface, REMOVE);
-}
-
-
-/* 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,
- "--jump", "REJECT",
- NULL);
+ virFirewallAddRule(fw, layer,
+ "--table", "filter",
+ "--delete", "FORWARD",
+ "--in-interface", iface,
+ "--out-interface", iface,
+ "--jump", "ACCEPT",
+ NULL);
}
/**
*
* Returns 0 in case of success or an error code otherwise
*/
-int
-iptablesAddForwardRejectOut(int family,
+void
+iptablesAddForwardRejectOut(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface)
{
- return iptablesForwardRejectOut(family, iface, ADD);
+ virFirewallAddRule(fw, layer,
+ "--table", "filter",
+ "--insert", "FORWARD",
+ "--in-interface", iface,
+ "--jump", "REJECT",
+ NULL);
}
/**
*
* Returns 0 in case of success or an error code otherwise
*/
-int
-iptablesRemoveForwardRejectOut(int family,
+void
+iptablesRemoveForwardRejectOut(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface)
{
- return iptablesForwardRejectOut(family, iface, REMOVE);
+ virFirewallAddRule(fw, layer,
+ "--table", "filter",
+ "--delete", "FORWARD",
+ "--in-interface", iface,
+ "--jump", "REJECT",
+ NULL);
}
-
-
-/* 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",
- NULL);
-}
-
/**
* iptablesAddForwardRejectIn:
* @ctx: pointer to the IP table context
*
* Returns 0 in case of success or an error code otherwise
*/
-int
-iptablesAddForwardRejectIn(int family,
+void
+iptablesAddForwardRejectIn(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface)
{
- return iptablesForwardRejectIn(family, iface, ADD);
+ virFirewallAddRule(fw, layer,
+ "--table", "filter",
+ "--insert", "FORWARD",
+ "--out-interface", iface,
+ "--jump", "REJECT",
+ NULL);
}
/**
*
* Returns 0 in case of success or an error code otherwise
*/
-int
-iptablesRemoveForwardRejectIn(int family,
+void
+iptablesRemoveForwardRejectIn(virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface)
{
- return iptablesForwardRejectIn(family, iface, REMOVE);
+ virFirewallAddRule(fw, layer,
+ "--table", "filter",
+ "--delete", "FORWARD",
+ "--out-interface", iface,
+ "--jump", "REJECT",
+ NULL);
}
* with the bridge
*/
static int
-iptablesForwardMasquerade(virSocketAddr *netaddr,
+iptablesForwardMasquerade(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
virSocketAddrRangePtr addr,
char *addrEndStr = NULL;
char *portRangeStr = NULL;
char *natRangeStr = NULL;
- virCommandPtr cmd = NULL;
+ virFirewallRulePtr rule;
if (!(networkstr = iptablesFormatNetwork(netaddr, prefix)))
return -1;
}
}
- cmd = iptablesCommandNew("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 (protocol && protocol[0]) {
+ rule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+ "--table", "nat",
+ action == ADD ? "--insert" : "--delete", "POSTROUTING",
+ "--source", networkstr,
+ "-p", protocol,
+ "!", "--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])
- virCommandAddArgList(cmd, "--out-interface", physdev, NULL);
+ virFirewallRuleAddArgList(fw, rule, "--out-interface", physdev, NULL);
if (protocol && protocol[0]) {
if (port->start == 0 && port->end == 0) {
if (r < 0)
goto cleanup;
- virCommandAddArgList(cmd, "--jump", "SNAT",
+ virFirewallRuleAddArgList(fw, rule,
+ "--jump", "SNAT",
"--to-source", natRangeStr, NULL);
- } else {
- virCommandAddArgList(cmd, "--jump", "MASQUERADE", NULL);
+ } else {
+ virFirewallRuleAddArgList(fw, rule,
+ "--jump", "MASQUERADE", NULL);
- if (portRangeStr && portRangeStr[0])
- virCommandAddArgList(cmd, "--to-ports", &portRangeStr[1], NULL);
- }
+ if (portRangeStr && portRangeStr[0])
+ virFirewallRuleAddArgList(fw, rule,
+ "--to-ports", &portRangeStr[1], NULL);
+ }
- ret = virCommandRun(cmd, NULL);
+ ret = 0;
cleanup:
- virCommandFree(cmd);
VIR_FREE(networkstr);
VIR_FREE(addrStartStr);
VIR_FREE(addrEndStr);
* Returns 0 in case of success or an error code otherwise
*/
int
-iptablesAddForwardMasquerade(virSocketAddr *netaddr,
+iptablesAddForwardMasquerade(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
virSocketAddrRangePtr addr,
virPortRangePtr port,
const char *protocol)
{
- return iptablesForwardMasquerade(netaddr, prefix, physdev, addr, port,
+ return iptablesForwardMasquerade(fw, netaddr, prefix, physdev, addr, port,
protocol, ADD);
}
* Returns 0 in case of success or an error code otherwise
*/
int
-iptablesRemoveForwardMasquerade(virSocketAddr *netaddr,
+iptablesRemoveForwardMasquerade(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
virSocketAddrRangePtr addr,
virPortRangePtr port,
const char *protocol)
{
- return iptablesForwardMasquerade(netaddr, prefix, physdev, addr, port,
+ return iptablesForwardMasquerade(fw, netaddr, prefix, physdev, addr, port,
protocol, REMOVE);
}
* if said traffic targets @destaddr.
*/
static int
-iptablesForwardDontMasquerade(virSocketAddr *netaddr,
+iptablesForwardDontMasquerade(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
const char *destaddr,
{
int ret = -1;
char *networkstr = NULL;
- virCommandPtr cmd = NULL;
if (!(networkstr = iptablesFormatNetwork(netaddr, prefix)))
return -1;
goto cleanup;
}
- cmd = iptablesCommandNew("nat", "POSTROUTING", AF_INET, action);
-
if (physdev && physdev[0])
- virCommandAddArgList(cmd, "--out-interface", physdev, NULL);
-
- virCommandAddArgList(cmd, "--source", networkstr,
- "--destination", destaddr, "--jump", "RETURN", NULL);
- ret = virCommandRun(cmd, 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);
+
+ ret = 0;
cleanup:
- virCommandFree(cmd);
VIR_FREE(networkstr);
return ret;
}
* Returns 0 in case of success or an error code otherwise.
*/
int
-iptablesAddDontMasquerade(virSocketAddr *netaddr,
+iptablesAddDontMasquerade(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
const char *destaddr)
{
- return iptablesForwardDontMasquerade(netaddr, prefix, physdev, destaddr,
+ return iptablesForwardDontMasquerade(fw, netaddr, prefix, physdev, destaddr,
ADD);
}
* Returns 0 in case of success or an error code otherwise.
*/
int
-iptablesRemoveDontMasquerade(virSocketAddr *netaddr,
+iptablesRemoveDontMasquerade(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
const char *destaddr)
{
- return iptablesForwardDontMasquerade(netaddr, prefix, physdev, destaddr,
+ return iptablesForwardDontMasquerade(fw, netaddr, prefix, physdev, destaddr,
REMOVE);
}
-static int
-iptablesOutputFixUdpChecksum(const char *iface,
+static void
+iptablesOutputFixUdpChecksum(virFirewallPtr fw,
+ const char *iface,
int port,
int action)
{
snprintf(portstr, sizeof(portstr), "%d", port);
portstr[sizeof(portstr) - 1] = '\0';
- return iptablesAddRemoveRule("mangle", "POSTROUTING",
- AF_INET,
- action,
- "--out-interface", iface,
- "--protocol", "udp",
- "--destination-port", portstr,
- "--jump", "CHECKSUM", "--checksum-fill",
- NULL);
+ virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+ "--table", "mangle",
+ action == ADD ? "--insert" : "--delete", "POSTROUTING",
+ "--out-interface", iface,
+ "--protocol", "udp",
+ "--destination-port", portstr,
+ "--jump", "CHECKSUM", "--checksum-fill",
+ NULL);
}
/**
* checksum of packets with the given destination @port.
* 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.)
*/
-
-int
-iptablesAddOutputFixUdpChecksum(const char *iface,
+void
+iptablesAddOutputFixUdpChecksum(virFirewallPtr fw,
+ const char *iface,
int port)
{
- return iptablesOutputFixUdpChecksum(iface, port, ADD);
+ iptablesOutputFixUdpChecksum(fw, iface, port, ADD);
}
/**
*
* Removes the checksum fixup rule that was previous added with
* 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
-iptablesRemoveOutputFixUdpChecksum(const char *iface,
+void
+iptablesRemoveOutputFixUdpChecksum(virFirewallPtr fw,
+ const char *iface,
int port)
{
- return iptablesOutputFixUdpChecksum(iface, port, REMOVE);
+ iptablesOutputFixUdpChecksum(fw, iface, port, REMOVE);
}
* Mark McLoughlin <markmc@redhat.com>
*/
-#ifndef __QEMUD_IPTABLES_H__
-# define __QEMUD_IPTABLES_H__
+#ifndef __VIR_IPTABLES_H__
+# define __VIR_IPTABLES_H__
# include "virsocketaddr.h"
+# include "virfirewall.h"
-int iptablesAddTcpInput (int family,
+void iptablesAddTcpInput (virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port);
-int iptablesRemoveTcpInput (int family,
+void iptablesRemoveTcpInput (virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port);
-int iptablesAddUdpInput (int family,
+void iptablesAddUdpInput (virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port);
-int iptablesRemoveUdpInput (int family,
+void iptablesRemoveUdpInput (virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port);
-int iptablesAddUdpOutput (int family,
+void iptablesAddUdpOutput (virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port);
-int iptablesRemoveUdpOutput (int family,
+void iptablesRemoveUdpOutput (virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface,
int port);
-int iptablesAddForwardAllowOut (virSocketAddr *netaddr,
+int iptablesAddForwardAllowOut (virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
- const char *physdev);
-int iptablesRemoveForwardAllowOut (virSocketAddr *netaddr,
+ const char *physdev)
+ ATTRIBUTE_RETURN_CHECK;
+int iptablesRemoveForwardAllowOut (virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
- const char *physdev);
-
-int iptablesAddForwardAllowRelatedIn(virSocketAddr *netaddr,
- unsigned int prefix,
- const char *iface,
- const char *physdev);
-int iptablesRemoveForwardAllowRelatedIn(virSocketAddr *netaddr,
+ const char *physdev)
+ ATTRIBUTE_RETURN_CHECK;
+int iptablesAddForwardAllowRelatedIn(virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
- const char *physdev);
+ const char *physdev)
+ ATTRIBUTE_RETURN_CHECK;
+int iptablesRemoveForwardAllowRelatedIn(virFirewallPtr fw,
+ virSocketAddr *netaddr,
+ unsigned int prefix,
+ const char *iface,
+ const char *physdev)
+ ATTRIBUTE_RETURN_CHECK;
-int iptablesAddForwardAllowIn (virSocketAddr *netaddr,
+int iptablesAddForwardAllowIn (virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
- const char *physdev);
-int iptablesRemoveForwardAllowIn (virSocketAddr *netaddr,
+ const char *physdev)
+ ATTRIBUTE_RETURN_CHECK;
+int iptablesRemoveForwardAllowIn (virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
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);
-int iptablesRemoveForwardAllowCross (int family,
+void iptablesRemoveForwardAllowCross (virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface);
-int iptablesAddForwardRejectOut (int family,
+void iptablesAddForwardRejectOut (virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface);
-int iptablesRemoveForwardRejectOut (int family,
+void iptablesRemoveForwardRejectOut (virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface);
-int iptablesAddForwardRejectIn (int family,
+void iptablesAddForwardRejectIn (virFirewallPtr fw,
+ virFirewallLayer layer,
const char *iface);
-int iptablesRemoveForwardRejectIn (int family,
+void iptablesRemoveForwardRejectIn (virFirewallPtr fw,
+ virFirewallLayer layery,
const char *iface);
-int iptablesAddForwardMasquerade (virSocketAddr *netaddr,
+int iptablesAddForwardMasquerade (virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
virSocketAddrRangePtr addr,
virPortRangePtr port,
- const char *protocol);
-int iptablesRemoveForwardMasquerade (virSocketAddr *netaddr,
+ const char *protocol)
+ ATTRIBUTE_RETURN_CHECK;
+int iptablesRemoveForwardMasquerade (virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
virSocketAddrRangePtr addr,
virPortRangePtr port,
- const char *protocol);
-int iptablesAddDontMasquerade (virSocketAddr *netaddr,
+ const char *protocol)
+ ATTRIBUTE_RETURN_CHECK;
+int iptablesAddDontMasquerade (virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
- const char *destaddr);
-int iptablesRemoveDontMasquerade (virSocketAddr *netaddr,
+ const char *destaddr)
+ ATTRIBUTE_RETURN_CHECK;
+int iptablesRemoveDontMasquerade (virFirewallPtr fw,
+ virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
- const char *destaddr);
-int iptablesAddOutputFixUdpChecksum (const char *iface,
+ const char *destaddr)
+ ATTRIBUTE_RETURN_CHECK;
+void iptablesAddOutputFixUdpChecksum (virFirewallPtr fw,
+ const char *iface,
int port);
-int iptablesRemoveOutputFixUdpChecksum (const char *iface,
+void iptablesRemoveOutputFixUdpChecksum (virFirewallPtr fw,
+ const char *iface,
int port);
-#endif /* __QEMUD_IPTABLES_H__ */
+#endif /* __VIR_IPTABLES_H__ */