mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 04:25:18 +00:00
Convert nwfilter ebiptablesAllTeardown to virFirewall
Convert the nwfilter ebiptablesAllTeardown method to use the virFirewall object APIs instead of creating shell scripts using virBuffer APIs. This provides a performance improvement through allowing direct use of firewalld dbus APIs and will facilitate automated testing. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
3bf346a124
commit
8d55986427
@ -1538,6 +1538,9 @@ endif WITH_NODE_DEVICES
|
|||||||
|
|
||||||
|
|
||||||
if WITH_NWFILTER
|
if WITH_NWFILTER
|
||||||
|
noinst_LTLIBRARIES += libvirt_driver_nwfilter_impl.la
|
||||||
|
libvirt_driver_nwfilter_la_SOURCES =
|
||||||
|
libvirt_driver_nwfilter_la_LIBADD = libvirt_driver_nwfilter_impl.la
|
||||||
if WITH_DRIVER_MODULES
|
if WITH_DRIVER_MODULES
|
||||||
mod_LTLIBRARIES += libvirt_driver_nwfilter.la
|
mod_LTLIBRARIES += libvirt_driver_nwfilter.la
|
||||||
else ! WITH_DRIVER_MODULES
|
else ! WITH_DRIVER_MODULES
|
||||||
@ -1545,20 +1548,23 @@ noinst_LTLIBRARIES += libvirt_driver_nwfilter.la
|
|||||||
# Stateful, so linked to daemon instead
|
# Stateful, so linked to daemon instead
|
||||||
#libvirt_la_BUILT_LIBADD += libvirt_driver_nwfilter.la
|
#libvirt_la_BUILT_LIBADD += libvirt_driver_nwfilter.la
|
||||||
endif ! WITH_DRIVER_MODULES
|
endif ! WITH_DRIVER_MODULES
|
||||||
libvirt_driver_nwfilter_la_CFLAGS = \
|
libvirt_driver_nwfilter_impl_la_CFLAGS = \
|
||||||
$(LIBPCAP_CFLAGS) \
|
$(LIBPCAP_CFLAGS) \
|
||||||
$(LIBNL_CFLAGS) \
|
$(LIBNL_CFLAGS) \
|
||||||
$(DBUS_CFLAGS) \
|
$(DBUS_CFLAGS) \
|
||||||
-I$(top_srcdir)/src/access \
|
-I$(top_srcdir)/src/access \
|
||||||
-I$(top_srcdir)/src/conf \
|
-I$(top_srcdir)/src/conf \
|
||||||
$(AM_CFLAGS)
|
$(AM_CFLAGS)
|
||||||
libvirt_driver_nwfilter_la_LDFLAGS = $(AM_LDFLAGS)
|
libvirt_driver_nwfilter_impl_la_LDFLAGS = $(AM_LDFLAGS)
|
||||||
libvirt_driver_nwfilter_la_LIBADD = $(LIBPCAP_LIBS) $(LIBNL_LIBS) $(DBUS_LIBS)
|
libvirt_driver_nwfilter_impl_la_LIBADD = \
|
||||||
|
$(LIBPCAP_LIBS) \
|
||||||
|
$(LIBNL_LIBS) \
|
||||||
|
$(DBUS_LIBS)
|
||||||
if WITH_DRIVER_MODULES
|
if WITH_DRIVER_MODULES
|
||||||
libvirt_driver_nwfilter_la_LIBADD += ../gnulib/lib/libgnu.la
|
libvirt_driver_nwfilter_impl_la_LIBADD += ../gnulib/lib/libgnu.la
|
||||||
libvirt_driver_nwfilter_la_LDFLAGS += -module -avoid-version
|
libvirt_driver_nwfilter_impl_la_LDFLAGS += -module -avoid-version
|
||||||
endif WITH_DRIVER_MODULES
|
endif WITH_DRIVER_MODULES
|
||||||
libvirt_driver_nwfilter_la_SOURCES = $(NWFILTER_DRIVER_SOURCES)
|
libvirt_driver_nwfilter_impl_la_SOURCES = $(NWFILTER_DRIVER_SOURCES)
|
||||||
endif WITH_NWFILTER
|
endif WITH_NWFILTER
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include "configmake.h"
|
#include "configmake.h"
|
||||||
#include "intprops.h"
|
#include "intprops.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
|
#include "virfirewall.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NWFILTER
|
#define VIR_FROM_THIS VIR_FROM_NWFILTER
|
||||||
|
|
||||||
@ -180,22 +181,15 @@ static const char ebiptables_script_set_ifs[] =
|
|||||||
snprintf(buf, sizeof(buf), "%c%c-%s", prefix[0], prefix[1], ifname)
|
snprintf(buf, sizeof(buf), "%c%c-%s", prefix[0], prefix[1], ifname)
|
||||||
|
|
||||||
#define PHYSDEV_IN "--physdev-in"
|
#define PHYSDEV_IN "--physdev-in"
|
||||||
#define PHYSDEV_OUT "--physdev-is-bridged --physdev-out"
|
|
||||||
/*
|
|
||||||
* Previous versions of libvirt only used --physdev-out.
|
|
||||||
* To be able to upgrade with running VMs we need to be able to
|
|
||||||
* remove rules generated by those older versions of libvirt.
|
|
||||||
*/
|
|
||||||
#define PHYSDEV_OUT_OLD "--physdev-out"
|
|
||||||
|
|
||||||
static const char *m_state_out_str = "-m state --state NEW,ESTABLISHED";
|
static const char *m_state_out_str = "-m state --state NEW,ESTABLISHED";
|
||||||
static const char *m_state_in_str = "-m state --state ESTABLISHED";
|
static const char *m_state_in_str = "-m state --state ESTABLISHED";
|
||||||
static const char *m_state_out_str_new = "-m conntrack --ctstate NEW,ESTABLISHED";
|
static const char *m_state_out_str_new = "-m conntrack --ctstate NEW,ESTABLISHED";
|
||||||
static const char *m_state_in_str_new = "-m conntrack --ctstate ESTABLISHED";
|
static const char *m_state_in_str_new = "-m conntrack --ctstate ESTABLISHED";
|
||||||
|
|
||||||
static const char *m_physdev_in_str = "-m physdev " PHYSDEV_IN;
|
static const char *m_physdev_in_str = "-m physdev --physdev-in";
|
||||||
static const char *m_physdev_out_str = "-m physdev " PHYSDEV_OUT;
|
static const char *m_physdev_out_str = "-m physdev --physdev-is-bridged --physdev-out";
|
||||||
static const char *m_physdev_out_old_str = "-m physdev " PHYSDEV_OUT_OLD;
|
static const char *m_physdev_out_old_str = "-m physdev --physdev-out";
|
||||||
|
|
||||||
#define MATCH_STATE_OUT m_state_out_str
|
#define MATCH_STATE_OUT m_state_out_str
|
||||||
#define MATCH_STATE_IN m_state_in_str
|
#define MATCH_STATE_IN m_state_in_str
|
||||||
@ -203,6 +197,10 @@ static const char *m_physdev_out_old_str = "-m physdev " PHYSDEV_OUT_OLD;
|
|||||||
#define MATCH_PHYSDEV_OUT m_physdev_out_str
|
#define MATCH_PHYSDEV_OUT m_physdev_out_str
|
||||||
#define MATCH_PHYSDEV_OUT_OLD m_physdev_out_old_str
|
#define MATCH_PHYSDEV_OUT_OLD m_physdev_out_old_str
|
||||||
|
|
||||||
|
#define MATCH_PHYSDEV_IN_FW "-m", "physdev", "--physdev-in"
|
||||||
|
#define MATCH_PHYSDEV_OUT_FW "-m", "physdev", "--physdev-is-bridged", "--physdev-out"
|
||||||
|
#define MATCH_PHYSDEV_OUT_OLD_FW "-m", "physdev", "--physdev-out"
|
||||||
|
|
||||||
#define COMMENT_VARNAME "comment"
|
#define COMMENT_VARNAME "comment"
|
||||||
|
|
||||||
static int ebtablesRemoveBasicRules(const char *ifname);
|
static int ebtablesRemoveBasicRules(const char *ifname);
|
||||||
@ -249,6 +247,12 @@ static const struct ushort_map l3_protocols[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static char chainprefixes_host[3] = {
|
||||||
|
CHAINPREFIX_HOST_IN,
|
||||||
|
CHAINPREFIX_HOST_OUT,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
printVar(virNWFilterVarCombIterPtr vars,
|
printVar(virNWFilterVarCombIterPtr vars,
|
||||||
char *buf, int bufsize,
|
char *buf, int bufsize,
|
||||||
@ -660,6 +664,36 @@ _iptablesRemoveRootChain(virBufferPtr buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_iptablesRemoveRootChainFW(virFirewallPtr fw,
|
||||||
|
virFirewallLayer layer,
|
||||||
|
char prefix,
|
||||||
|
bool incoming, const char *ifname,
|
||||||
|
int isTempChain)
|
||||||
|
{
|
||||||
|
char chain[MAX_CHAINNAME_LENGTH];
|
||||||
|
char chainPrefix[2] = {
|
||||||
|
prefix,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isTempChain)
|
||||||
|
chainPrefix[1] = incoming ? CHAINPREFIX_HOST_IN_TEMP
|
||||||
|
: CHAINPREFIX_HOST_OUT_TEMP;
|
||||||
|
else
|
||||||
|
chainPrefix[1] = incoming ? CHAINPREFIX_HOST_IN
|
||||||
|
: CHAINPREFIX_HOST_OUT;
|
||||||
|
|
||||||
|
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
|
||||||
|
|
||||||
|
virFirewallAddRuleFull(fw, layer,
|
||||||
|
true, NULL, NULL,
|
||||||
|
"-F", chain, NULL);
|
||||||
|
virFirewallAddRuleFull(fw, layer,
|
||||||
|
true, NULL, NULL,
|
||||||
|
"-X", chain, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iptablesRemoveRootChain(virBufferPtr buf,
|
iptablesRemoveRootChain(virBufferPtr buf,
|
||||||
char prefix,
|
char prefix,
|
||||||
@ -670,6 +704,17 @@ iptablesRemoveRootChain(virBufferPtr buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
iptablesRemoveRootChainFW(virFirewallPtr fw,
|
||||||
|
virFirewallLayer layer,
|
||||||
|
char prefix,
|
||||||
|
bool incoming,
|
||||||
|
const char *ifname)
|
||||||
|
{
|
||||||
|
_iptablesRemoveRootChainFW(fw, layer, prefix, incoming, ifname, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iptablesRemoveTmpRootChain(virBufferPtr buf,
|
iptablesRemoveTmpRootChain(virBufferPtr buf,
|
||||||
char prefix,
|
char prefix,
|
||||||
@ -701,6 +746,17 @@ iptablesRemoveRootChains(virBufferPtr buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
iptablesRemoveRootChainsFW(virFirewallPtr fw,
|
||||||
|
virFirewallLayer layer,
|
||||||
|
const char *ifname)
|
||||||
|
{
|
||||||
|
iptablesRemoveRootChainFW(fw, layer, 'F', false, ifname);
|
||||||
|
iptablesRemoveRootChainFW(fw, layer, 'F', true, ifname);
|
||||||
|
iptablesRemoveRootChainFW(fw, layer, 'H', true, ifname);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iptablesLinkTmpRootChain(virBufferPtr buf,
|
iptablesLinkTmpRootChain(virBufferPtr buf,
|
||||||
const char *basechain,
|
const char *basechain,
|
||||||
@ -762,14 +818,15 @@ iptablesSetupVirtInPost(virBufferPtr buf,
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iptablesClearVirtInPost(virBufferPtr buf,
|
iptablesClearVirtInPostFW(virFirewallPtr fw,
|
||||||
const char *ifname)
|
virFirewallLayer layer,
|
||||||
|
const char *ifname)
|
||||||
{
|
{
|
||||||
const char *match = MATCH_PHYSDEV_IN;
|
virFirewallAddRuleFull(fw, layer,
|
||||||
virBufferAsprintf(buf,
|
true, NULL, NULL,
|
||||||
"$IPT -D " VIRT_IN_POST_CHAIN
|
"-D", VIRT_IN_POST_CHAIN,
|
||||||
" %s %s -j ACCEPT" CMD_SEPARATOR,
|
MATCH_PHYSDEV_IN_FW,
|
||||||
match, ifname);
|
ifname, "-j", "ACCEPT", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -816,6 +873,57 @@ _iptablesUnlinkRootChain(virBufferPtr buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_iptablesUnlinkRootChainFW(virFirewallPtr fw,
|
||||||
|
virFirewallLayer layer,
|
||||||
|
const char *basechain,
|
||||||
|
char prefix,
|
||||||
|
bool incoming, const char *ifname,
|
||||||
|
int isTempChain)
|
||||||
|
{
|
||||||
|
char chain[MAX_CHAINNAME_LENGTH];
|
||||||
|
char chainPrefix[2] = {
|
||||||
|
prefix,
|
||||||
|
};
|
||||||
|
if (isTempChain)
|
||||||
|
chainPrefix[1] = incoming ? CHAINPREFIX_HOST_IN_TEMP
|
||||||
|
: CHAINPREFIX_HOST_OUT_TEMP;
|
||||||
|
else
|
||||||
|
chainPrefix[1] = incoming ? CHAINPREFIX_HOST_IN
|
||||||
|
: CHAINPREFIX_HOST_OUT;
|
||||||
|
|
||||||
|
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
|
||||||
|
|
||||||
|
if (incoming)
|
||||||
|
virFirewallAddRuleFull(fw, layer,
|
||||||
|
true, NULL, NULL,
|
||||||
|
"-D", basechain,
|
||||||
|
MATCH_PHYSDEV_IN_FW, ifname,
|
||||||
|
"-g", chain,
|
||||||
|
NULL);
|
||||||
|
else
|
||||||
|
virFirewallAddRuleFull(fw, layer,
|
||||||
|
true, NULL, NULL,
|
||||||
|
"-D", basechain,
|
||||||
|
MATCH_PHYSDEV_OUT_FW, ifname,
|
||||||
|
"-g", chain,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Previous versions of libvirt may have created a rule
|
||||||
|
* with the --physdev-is-bridged missing. Remove this one
|
||||||
|
* as well.
|
||||||
|
*/
|
||||||
|
if (!incoming)
|
||||||
|
virFirewallAddRuleFull(fw, layer,
|
||||||
|
true, NULL, NULL,
|
||||||
|
"-D", basechain,
|
||||||
|
MATCH_PHYSDEV_OUT_OLD_FW, ifname,
|
||||||
|
"-g", chain,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iptablesUnlinkRootChain(virBufferPtr buf,
|
iptablesUnlinkRootChain(virBufferPtr buf,
|
||||||
const char *basechain,
|
const char *basechain,
|
||||||
@ -826,6 +934,17 @@ iptablesUnlinkRootChain(virBufferPtr buf,
|
|||||||
basechain, prefix, incoming, ifname, false);
|
basechain, prefix, incoming, ifname, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
iptablesUnlinkRootChainFW(virFirewallPtr fw,
|
||||||
|
virFirewallLayer layer,
|
||||||
|
const char *basechain,
|
||||||
|
char prefix,
|
||||||
|
bool incoming, const char *ifname)
|
||||||
|
{
|
||||||
|
_iptablesUnlinkRootChainFW(fw, layer,
|
||||||
|
basechain, prefix, incoming, ifname, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iptablesUnlinkTmpRootChain(virBufferPtr buf,
|
iptablesUnlinkTmpRootChain(virBufferPtr buf,
|
||||||
@ -848,6 +967,17 @@ iptablesUnlinkRootChains(virBufferPtr buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
iptablesUnlinkRootChainsFW(virFirewallPtr fw,
|
||||||
|
virFirewallLayer layer,
|
||||||
|
const char *ifname)
|
||||||
|
{
|
||||||
|
iptablesUnlinkRootChainFW(fw, layer, VIRT_OUT_CHAIN, 'F', false, ifname);
|
||||||
|
iptablesUnlinkRootChainFW(fw, layer, VIRT_IN_CHAIN, 'F', true, ifname);
|
||||||
|
iptablesUnlinkRootChainFW(fw, layer, HOST_IN_CHAIN, 'H', true, ifname);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iptablesUnlinkTmpRootChains(virBufferPtr buf,
|
iptablesUnlinkTmpRootChains(virBufferPtr buf,
|
||||||
const char *ifname)
|
const char *ifname)
|
||||||
@ -2801,6 +2931,31 @@ _ebtablesRemoveRootChain(virBufferPtr buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ebtablesRemoveRootChainFW(virFirewallPtr fw,
|
||||||
|
bool incoming, const char *ifname,
|
||||||
|
int isTempChain)
|
||||||
|
{
|
||||||
|
char chain[MAX_CHAINNAME_LENGTH];
|
||||||
|
char chainPrefix;
|
||||||
|
if (isTempChain)
|
||||||
|
chainPrefix = incoming ? CHAINPREFIX_HOST_IN_TEMP
|
||||||
|
: CHAINPREFIX_HOST_OUT_TEMP;
|
||||||
|
else
|
||||||
|
chainPrefix = incoming ? CHAINPREFIX_HOST_IN
|
||||||
|
: CHAINPREFIX_HOST_OUT;
|
||||||
|
|
||||||
|
PRINT_ROOT_CHAIN(chain, chainPrefix, ifname);
|
||||||
|
|
||||||
|
virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET,
|
||||||
|
true, NULL, NULL,
|
||||||
|
"-t", "nat", "-F", chain, NULL);
|
||||||
|
virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET,
|
||||||
|
true, NULL, NULL,
|
||||||
|
"-t", "nat", "-X", chain, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ebtablesRemoveRootChain(virBufferPtr buf,
|
ebtablesRemoveRootChain(virBufferPtr buf,
|
||||||
bool incoming, const char *ifname)
|
bool incoming, const char *ifname)
|
||||||
@ -2809,6 +2964,14 @@ ebtablesRemoveRootChain(virBufferPtr buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ebtablesRemoveRootChainFW(virFirewallPtr fw,
|
||||||
|
bool incoming, const char *ifname)
|
||||||
|
{
|
||||||
|
_ebtablesRemoveRootChainFW(fw, incoming, ifname, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ebtablesRemoveTmpRootChain(virBufferPtr buf,
|
ebtablesRemoveTmpRootChain(virBufferPtr buf,
|
||||||
bool incoming, const char *ifname)
|
bool incoming, const char *ifname)
|
||||||
@ -2844,6 +3007,33 @@ _ebtablesUnlinkRootChain(virBufferPtr buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ebtablesUnlinkRootChainFW(virFirewallPtr fw,
|
||||||
|
bool incoming, const char *ifname,
|
||||||
|
int isTempChain)
|
||||||
|
{
|
||||||
|
char chain[MAX_CHAINNAME_LENGTH];
|
||||||
|
char chainPrefix;
|
||||||
|
|
||||||
|
if (isTempChain) {
|
||||||
|
chainPrefix = incoming ? CHAINPREFIX_HOST_IN_TEMP
|
||||||
|
: CHAINPREFIX_HOST_OUT_TEMP;
|
||||||
|
} else {
|
||||||
|
chainPrefix = incoming ? CHAINPREFIX_HOST_IN
|
||||||
|
: CHAINPREFIX_HOST_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINT_ROOT_CHAIN(chain, chainPrefix, ifname);
|
||||||
|
|
||||||
|
virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET,
|
||||||
|
true, NULL, NULL,
|
||||||
|
"-t", "nat", "-D",
|
||||||
|
incoming ? EBTABLES_CHAIN_INCOMING : EBTABLES_CHAIN_OUTGOING,
|
||||||
|
incoming ? "-i" : "-o",
|
||||||
|
ifname, "-j", chain, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ebtablesUnlinkRootChain(virBufferPtr buf,
|
ebtablesUnlinkRootChain(virBufferPtr buf,
|
||||||
bool incoming, const char *ifname)
|
bool incoming, const char *ifname)
|
||||||
@ -2852,6 +3042,14 @@ ebtablesUnlinkRootChain(virBufferPtr buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ebtablesUnlinkRootChainFW(virFirewallPtr fw,
|
||||||
|
bool incoming, const char *ifname)
|
||||||
|
{
|
||||||
|
_ebtablesUnlinkRootChainFW(fw, incoming, ifname, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ebtablesUnlinkTmpRootChain(virBufferPtr buf,
|
ebtablesUnlinkTmpRootChain(virBufferPtr buf,
|
||||||
bool incoming, const char *ifname)
|
bool incoming, const char *ifname)
|
||||||
@ -2972,6 +3170,60 @@ _ebtablesRemoveSubChains(virBufferPtr buf,
|
|||||||
virBufferAddLit(buf, "rm_chains $chains\n");
|
virBufferAddLit(buf, "rm_chains $chains\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
ebtablesRemoveSubChainsQuery(virFirewallPtr fw,
|
||||||
|
const char *const *lines,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
size_t i, j;
|
||||||
|
const char *chainprefixes = opaque;
|
||||||
|
|
||||||
|
for (i = 0; lines[i] != NULL; i++) {
|
||||||
|
VIR_DEBUG("Considering '%s'", lines[i]);
|
||||||
|
char *tmp = strstr(lines[i], "-j ");
|
||||||
|
if (!tmp)
|
||||||
|
continue;
|
||||||
|
tmp = tmp + 3;
|
||||||
|
for (j = 0; chainprefixes[j]; j++) {
|
||||||
|
if (tmp[0] == chainprefixes[j] &&
|
||||||
|
tmp[1] == '-') {
|
||||||
|
VIR_DEBUG("Processing chain '%s'", tmp);
|
||||||
|
virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET,
|
||||||
|
false, ebtablesRemoveSubChainsQuery,
|
||||||
|
(void *)chainprefixes,
|
||||||
|
"-t", "nat", "-L", tmp, NULL);
|
||||||
|
virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET,
|
||||||
|
true, NULL, NULL,
|
||||||
|
"-t", "nat", "-F", tmp, NULL);
|
||||||
|
virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET,
|
||||||
|
true, NULL, NULL,
|
||||||
|
"-t", "nat", "-X", tmp, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ebtablesRemoveSubChainsFW(virFirewallPtr fw,
|
||||||
|
const char *ifname,
|
||||||
|
const char *chainprefixes)
|
||||||
|
{
|
||||||
|
char rootchain[MAX_CHAINNAME_LENGTH];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; chainprefixes[i] != 0; i++) {
|
||||||
|
PRINT_ROOT_CHAIN(rootchain, chainprefixes[i], ifname);
|
||||||
|
virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET,
|
||||||
|
false, ebtablesRemoveSubChainsQuery,
|
||||||
|
(void *)chainprefixes,
|
||||||
|
"-t", "nat", "-L", rootchain, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ebtablesRemoveSubChains(virBufferPtr buf,
|
ebtablesRemoveSubChains(virBufferPtr buf,
|
||||||
const char *ifname)
|
const char *ifname)
|
||||||
@ -2985,6 +3237,13 @@ ebtablesRemoveSubChains(virBufferPtr buf,
|
|||||||
_ebtablesRemoveSubChains(buf, ifname, chains);
|
_ebtablesRemoveSubChains(buf, ifname, chains);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ebtablesRemoveSubChainsFW(virFirewallPtr fw,
|
||||||
|
const char *ifname)
|
||||||
|
{
|
||||||
|
_ebtablesRemoveSubChainsFW(fw, ifname, chainprefixes_host);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ebtablesRemoveTmpSubChains(virBufferPtr buf,
|
ebtablesRemoveTmpSubChains(virBufferPtr buf,
|
||||||
const char *ifname)
|
const char *ifname)
|
||||||
@ -4052,43 +4311,37 @@ ebiptablesTearOldRules(const char *ifname)
|
|||||||
* Unconditionally remove all possible user defined tables and rules
|
* Unconditionally remove all possible user defined tables and rules
|
||||||
* that were created for the given interface (ifname).
|
* that were created for the given interface (ifname).
|
||||||
*
|
*
|
||||||
* Always returns 0.
|
* Returns 0 on success, -1 on OOM
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ebiptablesAllTeardown(const char *ifname)
|
ebiptablesAllTeardown(const char *ifname)
|
||||||
{
|
{
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
virFirewallPtr fw = virFirewallNew();
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
if (iptables_cmd_path) {
|
virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
|
||||||
NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
|
|
||||||
|
|
||||||
iptablesUnlinkRootChains(&buf, ifname);
|
iptablesUnlinkRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname);
|
||||||
iptablesClearVirtInPost(&buf, ifname);
|
iptablesClearVirtInPostFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname);
|
||||||
iptablesRemoveRootChains(&buf, ifname);
|
iptablesRemoveRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname);
|
||||||
}
|
|
||||||
|
|
||||||
if (ip6tables_cmd_path) {
|
iptablesUnlinkRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname);
|
||||||
NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
|
iptablesClearVirtInPostFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname);
|
||||||
|
iptablesRemoveRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname);
|
||||||
|
|
||||||
iptablesUnlinkRootChains(&buf, ifname);
|
ebtablesUnlinkRootChainFW(fw, true, ifname);
|
||||||
iptablesClearVirtInPost(&buf, ifname);
|
ebtablesUnlinkRootChainFW(fw, false, ifname);
|
||||||
iptablesRemoveRootChains(&buf, ifname);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ebtables_cmd_path) {
|
ebtablesRemoveSubChainsFW(fw, ifname);
|
||||||
NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
|
|
||||||
|
|
||||||
ebtablesUnlinkRootChain(&buf, true, ifname);
|
ebtablesRemoveRootChainFW(fw, true, ifname);
|
||||||
ebtablesUnlinkRootChain(&buf, false, ifname);
|
ebtablesRemoveRootChainFW(fw, false, ifname);
|
||||||
|
|
||||||
ebtablesRemoveSubChains(&buf, ifname);
|
virMutexLock(&execCLIMutex);
|
||||||
|
ret = virFirewallApply(fw);
|
||||||
ebtablesRemoveRootChain(&buf, true, ifname);
|
virMutexUnlock(&execCLIMutex);
|
||||||
ebtablesRemoveRootChain(&buf, false, ifname);
|
virFirewallFree(fw);
|
||||||
}
|
return ret;
|
||||||
ebiptablesExecCLI(&buf, true, NULL);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -272,6 +272,10 @@ endif WITH_STORAGE_SHEEPDOG
|
|||||||
|
|
||||||
test_programs += nwfilterxml2xmltest
|
test_programs += nwfilterxml2xmltest
|
||||||
|
|
||||||
|
if WITH_NWFILTER
|
||||||
|
test_programs += nwfilterebiptablestest
|
||||||
|
endif WITH_NWFILTER
|
||||||
|
|
||||||
if WITH_STORAGE
|
if WITH_STORAGE
|
||||||
test_programs += storagevolxml2argvtest
|
test_programs += storagevolxml2argvtest
|
||||||
endif WITH_STORAGE
|
endif WITH_STORAGE
|
||||||
@ -696,6 +700,13 @@ nwfilterxml2xmltest_SOURCES = \
|
|||||||
testutils.c testutils.h
|
testutils.c testutils.h
|
||||||
nwfilterxml2xmltest_LDADD = $(LDADDS)
|
nwfilterxml2xmltest_LDADD = $(LDADDS)
|
||||||
|
|
||||||
|
if WITH_NWFILTER
|
||||||
|
nwfilterebiptablestest_SOURCES = \
|
||||||
|
nwfilterebiptablestest.c \
|
||||||
|
testutils.c testutils.h
|
||||||
|
nwfilterebiptablestest_LDADD = ../src/libvirt_driver_nwfilter_impl.la $(LDADDS)
|
||||||
|
endif WITH_NWFILTER
|
||||||
|
|
||||||
secretxml2xmltest_SOURCES = \
|
secretxml2xmltest_SOURCES = \
|
||||||
secretxml2xmltest.c \
|
secretxml2xmltest.c \
|
||||||
testutils.c testutils.h
|
testutils.c testutils.h
|
||||||
|
118
tests/nwfilterebiptablestest.c
Normal file
118
tests/nwfilterebiptablestest.c
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* nwfilterebiptablestest.c: Test {eb,ip,ip6}tables rule generation
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "testutils.h"
|
||||||
|
#include "nwfilter/nwfilter_ebiptables_driver.h"
|
||||||
|
#include "virbuffer.h"
|
||||||
|
|
||||||
|
#define __VIR_FIREWALL_PRIV_H_ALLOW__
|
||||||
|
#include "virfirewallpriv.h"
|
||||||
|
|
||||||
|
#define __VIR_COMMAND_PRIV_H_ALLOW__
|
||||||
|
#include "vircommandpriv.h"
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
|
static int
|
||||||
|
testNWFilterEBIPTablesAllTeardown(const void *opaque ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||||
|
const char *expected =
|
||||||
|
"iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
|
||||||
|
"iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
|
||||||
|
"iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
|
||||||
|
"iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
|
||||||
|
"iptables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
|
||||||
|
"iptables -F FO-vnet0\n"
|
||||||
|
"iptables -X FO-vnet0\n"
|
||||||
|
"iptables -F FI-vnet0\n"
|
||||||
|
"iptables -X FI-vnet0\n"
|
||||||
|
"iptables -F HI-vnet0\n"
|
||||||
|
"iptables -X HI-vnet0\n"
|
||||||
|
"ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
|
||||||
|
"ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
|
||||||
|
"ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
|
||||||
|
"ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
|
||||||
|
"ip6tables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
|
||||||
|
"ip6tables -F FO-vnet0\n"
|
||||||
|
"ip6tables -X FO-vnet0\n"
|
||||||
|
"ip6tables -F FI-vnet0\n"
|
||||||
|
"ip6tables -X FI-vnet0\n"
|
||||||
|
"ip6tables -F HI-vnet0\n"
|
||||||
|
"ip6tables -X HI-vnet0\n"
|
||||||
|
"ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n"
|
||||||
|
"ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n"
|
||||||
|
"ebtables -t nat -L libvirt-I-vnet0\n"
|
||||||
|
"ebtables -t nat -L libvirt-O-vnet0\n"
|
||||||
|
"ebtables -t nat -F libvirt-I-vnet0\n"
|
||||||
|
"ebtables -t nat -X libvirt-I-vnet0\n"
|
||||||
|
"ebtables -t nat -F libvirt-O-vnet0\n"
|
||||||
|
"ebtables -t nat -X libvirt-O-vnet0\n";
|
||||||
|
char *actual = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
virCommandSetDryRun(&buf, NULL, NULL);
|
||||||
|
|
||||||
|
if (ebiptables_driver.allTeardown("vnet0") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virBufferError(&buf))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
actual = virBufferContentAndReset(&buf);
|
||||||
|
virtTestClearCommandPath(actual);
|
||||||
|
|
||||||
|
if (STRNEQ_NULLABLE(actual, expected)) {
|
||||||
|
virtTestDifference(stderr, actual, expected);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virCommandSetDryRun(NULL, NULL, NULL);
|
||||||
|
virBufferFreeAndReset(&buf);
|
||||||
|
VIR_FREE(actual);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
mymain(void)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (virFirewallSetBackend(VIR_FIREWALL_BACKEND_DIRECT) < 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virtTestRun("ebiptablesAllTeardown",
|
||||||
|
testNWFilterEBIPTablesAllTeardown,
|
||||||
|
NULL) < 0)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIRT_TEST_MAIN(mymain)
|
Loading…
x
Reference in New Issue
Block a user