mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
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:
parent
3a0ca7de51
commit
a66fc27d89
@ -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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allow routing packets from the bridge interface */
|
/* allow routing 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 routing from '%s'"),
|
|
||||||
network->def->bridge);
|
|
||||||
goto routeerr1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allow routing packets to the bridge interface */
|
/* allow routing packets to the bridge interface */
|
||||||
if (iptablesAddForwardAllowIn(&ipdef->address,
|
if (iptablesAddForwardAllowIn(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 routing to '%s'"),
|
|
||||||
network->def->bridge);
|
|
||||||
goto routeerr2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
routeerr2:
|
|
||||||
iptablesRemoveForwardAllowOut(&ipdef->address,
|
|
||||||
prefix,
|
|
||||||
network->def->bridge,
|
|
||||||
forwardIf);
|
|
||||||
routeerr1:
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static int
|
||||||
networkRemoveRoutingFirewallRules(virNetworkObjPtr network,
|
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)
|
||||||
|
return -1;
|
||||||
|
|
||||||
iptablesRemoveForwardAllowOut(&ipdef->address,
|
if (iptablesRemoveForwardAllowOut(fw,
|
||||||
|
&ipdef->address,
|
||||||
prefix,
|
prefix,
|
||||||
network->def->bridge,
|
network->def->bridge,
|
||||||
forwardIf);
|
forwardIf) < 0)
|
||||||
}
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
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
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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 void
|
||||||
|
networkAddGeneralIPv6FirewallRules(virFirewallPtr fw,
|
||||||
|
virNetworkObjPtr network)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0) &&
|
||||||
|
!network->def->ipv6nogw) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
iptablesRemoveUdpInput(AF_INET, network->def->bridge, 53);
|
|
||||||
iptablesRemoveTcpInput(AF_INET, network->def->bridge, 53);
|
/* Catch all rules to block forwarding to/from bridges */
|
||||||
if (ipv4def && (ipv4def->nranges || ipv4def->nhosts)) {
|
iptablesAddForwardRejectOut(fw, VIR_FIREWALL_LAYER_IPV6, network->def->bridge);
|
||||||
iptablesRemoveOutputFixUdpChecksum(network->def->bridge, 68);
|
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);
|
||||||
}
|
}
|
||||||
iptablesRemoveUdpOutput(AF_INET, network->def->bridge, 68);
|
}
|
||||||
iptablesRemoveUdpInput(AF_INET, network->def->bridge, 67);
|
|
||||||
iptablesRemoveTcpInput(AF_INET, network->def->bridge, 67);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
|
||||||
err:
|
virFirewallStartRollback(fw, 0);
|
||||||
/* store the previous error message before attempting removal of rules */
|
|
||||||
orig_error = virSaveLastError();
|
|
||||||
|
|
||||||
/* The final failed call to networkAddIpSpecificFirewallRules will
|
for (i = 0;
|
||||||
* have removed any rules it created, but we need to remove those
|
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i));
|
||||||
* added for previous IP addresses.
|
i++) {
|
||||||
*/
|
if (networkRemoveIpSpecificFirewallRules(fw, network, ipdef) < 0)
|
||||||
for (j = 0; j < i; j++) {
|
goto cleanup;
|
||||||
if ((ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, j)))
|
|
||||||
networkRemoveIpSpecificFirewallRules(network, ipdef);
|
|
||||||
}
|
}
|
||||||
networkRemoveGeneralFirewallRules(network);
|
networkRemoveGeneralFirewallRules(fw, network);
|
||||||
|
|
||||||
/* return the original error */
|
virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
|
||||||
virSetError(orig_error);
|
networkAddChecksumFirewallRules(fw, network);
|
||||||
virFreeError(orig_error);
|
|
||||||
return -1;
|
if (virFirewallApply(fw) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virFirewallFree(fw);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -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,
|
||||||
|
const char *iface,
|
||||||
|
const char *physdev)
|
||||||
|
ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
|
int iptablesAddForwardAllowIn (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 iptablesRemoveForwardAllowIn (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;
|
||||||
unsigned int prefix,
|
|
||||||
const char *iface,
|
|
||||||
const char *physdev);
|
|
||||||
|
|
||||||
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__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user