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(a)redhat.com>
---
src/Makefile.am | 18 +-
src/nwfilter/nwfilter_ebiptables_driver.c | 326 ++++++++++++++++++++++++++----
tests/Makefile.am | 11 +
tests/nwfilterebiptablestest.c | 116 +++++++++++
4 files changed, 422 insertions(+), 49 deletions(-)
create mode 100644 tests/nwfilterebiptablestest.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 7615294..70ef6b6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1536,6 +1536,9 @@ endif WITH_NODE_DEVICES
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
mod_LTLIBRARIES += libvirt_driver_nwfilter.la
else ! WITH_DRIVER_MODULES
@@ -1543,20 +1546,23 @@ noinst_LTLIBRARIES += libvirt_driver_nwfilter.la
# Stateful, so linked to daemon instead
#libvirt_la_BUILT_LIBADD += libvirt_driver_nwfilter.la
endif ! WITH_DRIVER_MODULES
-libvirt_driver_nwfilter_la_CFLAGS = \
+libvirt_driver_nwfilter_impl_la_CFLAGS = \
$(LIBPCAP_CFLAGS) \
$(LIBNL_CFLAGS) \
$(DBUS_CFLAGS) \
-I$(top_srcdir)/src/access \
-I$(top_srcdir)/src/conf \
$(AM_CFLAGS)
-libvirt_driver_nwfilter_la_LDFLAGS = $(AM_LDFLAGS)
-libvirt_driver_nwfilter_la_LIBADD = $(LIBPCAP_LIBS) $(LIBNL_LIBS) $(DBUS_LIBS)
+libvirt_driver_nwfilter_impl_la_LDFLAGS = $(AM_LDFLAGS)
+libvirt_driver_nwfilter_impl_la_LIBADD = \
+ $(LIBPCAP_LIBS) \
+ $(LIBNL_LIBS) \
+ $(DBUS_LIBS)
if WITH_DRIVER_MODULES
-libvirt_driver_nwfilter_la_LIBADD += ../gnulib/lib/libgnu.la
-libvirt_driver_nwfilter_la_LDFLAGS += -module -avoid-version
+libvirt_driver_nwfilter_impl_la_LIBADD += ../gnulib/lib/libgnu.la
+libvirt_driver_nwfilter_impl_la_LDFLAGS += -module -avoid-version
endif WITH_DRIVER_MODULES
-libvirt_driver_nwfilter_la_SOURCES = $(NWFILTER_DRIVER_SOURCES)
+libvirt_driver_nwfilter_impl_la_SOURCES = $(NWFILTER_DRIVER_SOURCES)
endif WITH_NWFILTER
diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c
b/src/nwfilter/nwfilter_ebiptables_driver.c
index 0361d99..8a53ceb 100644
--- a/src/nwfilter/nwfilter_ebiptables_driver.c
+++ b/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -45,6 +45,7 @@
#include "configmake.h"
#include "intprops.h"
#include "virstring.h"
+#include "virfirewall.h"
#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)
#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_in_str = "-m state --state 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_physdev_in_str = "-m physdev " PHYSDEV_IN;
-static const char *m_physdev_out_str = "-m physdev " PHYSDEV_OUT;
-static const char *m_physdev_out_old_str = "-m physdev " PHYSDEV_OUT_OLD;
+static const char *m_physdev_in_str = "-m physdev --physdev-in";
+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";
#define MATCH_STATE_OUT m_state_out_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_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"
static int ebtablesRemoveBasicRules(const char *ifname);
@@ -661,6 +659,32 @@ _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);
+
+ virFirewallAddRule(fw, layer, "-F", chain, NULL);
+ virFirewallAddRule(fw, layer, "-X", chain, NULL);
+}
+
+
+static void
iptablesRemoveRootChain(virBufferPtr buf,
char prefix,
bool incoming,
@@ -671,6 +695,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
iptablesRemoveTmpRootChain(virBufferPtr buf,
char prefix,
bool incoming,
@@ -702,6 +737,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
iptablesLinkTmpRootChain(virBufferPtr buf,
const char *basechain,
char prefix,
@@ -762,14 +808,14 @@ iptablesSetupVirtInPost(virBufferPtr buf,
static void
-iptablesClearVirtInPost(virBufferPtr buf,
- const char *ifname)
+iptablesClearVirtInPostFW(virFirewallPtr fw,
+ virFirewallLayer layer,
+ const char *ifname)
{
- const char *match = MATCH_PHYSDEV_IN;
- virBufferAsprintf(buf,
- "$IPT -D " VIRT_IN_POST_CHAIN
- " %s %s -j ACCEPT" CMD_SEPARATOR,
- match, ifname);
+ virFirewallAddRule(fw, layer,
+ "-D", VIRT_IN_POST_CHAIN,
+ MATCH_PHYSDEV_IN_FW,
+ ifname, "-j", "ACCEPT", NULL);
}
static void
@@ -817,6 +863,54 @@ _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)
+ virFirewallAddRule(fw, layer,
+ "-D", basechain,
+ MATCH_PHYSDEV_IN_FW, ifname,
+ "-g", chain,
+ NULL);
+ else
+ virFirewallAddRule(fw, layer,
+ "-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)
+ virFirewallAddRule(fw, layer,
+ "-D", basechain,
+ MATCH_PHYSDEV_OUT_OLD_FW, ifname,
+ "-g", chain,
+ NULL);
+}
+
+
+static void
iptablesUnlinkRootChain(virBufferPtr buf,
const char *basechain,
char prefix,
@@ -826,6 +920,17 @@ iptablesUnlinkRootChain(virBufferPtr buf,
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
iptablesUnlinkTmpRootChain(virBufferPtr buf,
@@ -849,6 +954,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
iptablesUnlinkTmpRootChains(virBufferPtr buf,
const char *ifname)
{
@@ -2802,6 +2918,29 @@ _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);
+
+ virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat", "-F", chain, NULL);
+ virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat", "-X", chain, NULL);
+}
+
+
+static void
ebtablesRemoveRootChain(virBufferPtr buf,
bool incoming, const char *ifname)
{
@@ -2810,6 +2949,14 @@ ebtablesRemoveRootChain(virBufferPtr buf,
static void
+ebtablesRemoveRootChainFW(virFirewallPtr fw,
+ bool incoming, const char *ifname)
+{
+ _ebtablesRemoveRootChainFW(fw, incoming, ifname, false);
+}
+
+
+static void
ebtablesRemoveTmpRootChain(virBufferPtr buf,
bool incoming, const char *ifname)
{
@@ -2845,6 +2992,32 @@ _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);
+
+ virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat", "-D",
+ incoming ? EBTABLES_CHAIN_INCOMING : EBTABLES_CHAIN_OUTGOING,
+ incoming ? "-i" : "-o",
+ ifname, "-j", chain, NULL);
+}
+
+
+static void
ebtablesUnlinkRootChain(virBufferPtr buf,
bool incoming, const char *ifname)
{
@@ -2853,6 +3026,14 @@ ebtablesUnlinkRootChain(virBufferPtr buf,
static void
+ebtablesUnlinkRootChainFW(virFirewallPtr fw,
+ bool incoming, const char *ifname)
+{
+ _ebtablesUnlinkRootChainFW(fw, incoming, ifname, false);
+}
+
+
+static void
ebtablesUnlinkTmpRootChain(virBufferPtr buf,
bool incoming, const char *ifname)
{
@@ -2972,6 +3153,58 @@ _ebtablesRemoveSubChains(virBufferPtr buf,
virBufferAddLit(buf, "rm_chains $chains\n");
}
+
+static int
+ebtablesRemoveSubChainsQuery(virFirewallPtr fw,
+ const char *const *lines,
+ void *opaque)
+{
+ size_t i, j;
+ const char *chains = 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; chains[j]; j++) {
+ if (tmp[0] == chains[j] &&
+ tmp[1] == '-') {
+ VIR_DEBUG("Processing chain '%s'", tmp);
+ virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ false, ebtablesRemoveSubChainsQuery,
+ (void *)chains,
+ "-t", "nat", "-L",
tmp, NULL);
+ virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat", "-F", tmp,
NULL);
+ virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat", "-X", tmp,
NULL);
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+static void
+_ebtablesRemoveSubChainsFW(virFirewallPtr fw,
+ const char *ifname,
+ const char *chains)
+{
+ char rootchain[MAX_CHAINNAME_LENGTH];
+ size_t i;
+
+ for (i = 0; chains[i] != 0; i++) {
+ PRINT_ROOT_CHAIN(rootchain, chains[i], ifname);
+ virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ false, ebtablesRemoveSubChainsQuery,
+ (void *)chains,
+ "-t", "nat", "-L",
rootchain, NULL);
+ }
+}
+
static void
ebtablesRemoveSubChains(virBufferPtr buf,
const char *ifname)
@@ -2986,6 +3219,19 @@ ebtablesRemoveSubChains(virBufferPtr buf,
}
static void
+ebtablesRemoveSubChainsFW(virFirewallPtr fw,
+ const char *ifname)
+{
+ char chains[3] = {
+ CHAINPREFIX_HOST_IN,
+ CHAINPREFIX_HOST_OUT,
+ 0
+ };
+
+ _ebtablesRemoveSubChainsFW(fw, ifname, chains);
+}
+
+static void
ebtablesRemoveTmpSubChains(virBufferPtr buf,
const char *ifname)
{
@@ -4052,43 +4298,37 @@ ebiptablesTearOldRules(const char *ifname)
* Unconditionally remove all possible user defined tables and rules
* that were created for the given interface (ifname).
*
- * Always returns 0.
+ * Returns 0 on success, -1 on OOM
*/
static int
ebiptablesAllTeardown(const char *ifname)
{
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (iptables_cmd_path) {
- NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
+ virFirewallPtr fw = virFirewallNew();
+ int ret = -1;
- iptablesUnlinkRootChains(&buf, ifname);
- iptablesClearVirtInPost(&buf, ifname);
- iptablesRemoveRootChains(&buf, ifname);
- }
+ virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
- if (ip6tables_cmd_path) {
- NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
+ iptablesUnlinkRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname);
+ iptablesClearVirtInPostFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname);
+ iptablesRemoveRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname);
- iptablesUnlinkRootChains(&buf, ifname);
- iptablesClearVirtInPost(&buf, ifname);
- iptablesRemoveRootChains(&buf, ifname);
- }
+ iptablesUnlinkRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname);
+ iptablesClearVirtInPostFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname);
+ iptablesRemoveRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname);
- if (ebtables_cmd_path) {
- NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+ ebtablesUnlinkRootChainFW(fw, true, ifname);
+ ebtablesUnlinkRootChainFW(fw, false, ifname);
- ebtablesUnlinkRootChain(&buf, true, ifname);
- ebtablesUnlinkRootChain(&buf, false, ifname);
+ ebtablesRemoveSubChainsFW(fw, ifname);
- ebtablesRemoveSubChains(&buf, ifname);
+ ebtablesRemoveRootChainFW(fw, true, ifname);
+ ebtablesRemoveRootChainFW(fw, false, ifname);
- ebtablesRemoveRootChain(&buf, true, ifname);
- ebtablesRemoveRootChain(&buf, false, ifname);
- }
- ebiptablesExecCLI(&buf, true, NULL);
-
- return 0;
+ virMutexLock(&execCLIMutex);
+ ret = virFirewallApply(fw);
+ virMutexUnlock(&execCLIMutex);
+ virFirewallFree(fw);
+ return ret;
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 75e723f..9547c02 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -268,6 +268,10 @@ endif WITH_STORAGE_SHEEPDOG
test_programs += nwfilterxml2xmltest
+if WITH_NWFILTER
+test_programs += nwfilterebiptablestest
+endif WITH_NWFILTER
+
if WITH_STORAGE
test_programs += storagevolxml2argvtest
endif WITH_STORAGE
@@ -687,6 +691,13 @@ nwfilterxml2xmltest_SOURCES = \
testutils.c testutils.h
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.c \
testutils.c testutils.h
diff --git a/tests/nwfilterebiptablestest.c b/tests/nwfilterebiptablestest.c
new file mode 100644
index 0000000..c05682b
--- /dev/null
+++ b/tests/nwfilterebiptablestest.c
@@ -0,0 +1,116 @@
+/*
+ * 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 =
+ "/usr/sbin/iptables -D libvirt-out -m physdev --physdev-is-bridged
--physdev-out vnet0 -g FO-vnet0\n"
+ "/usr/sbin/iptables -D libvirt-out -m physdev --physdev-out vnet0 -g
FO-vnet0\n"
+ "/usr/sbin/iptables -D libvirt-in -m physdev --physdev-in vnet0 -g
FI-vnet0\n"
+ "/usr/sbin/iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g
HI-vnet0\n"
+ "/usr/sbin/iptables -D libvirt-in-post -m physdev --physdev-in vnet0 -j
ACCEPT\n"
+ "/usr/sbin/iptables -F FO-vnet0\n"
+ "/usr/sbin/iptables -X FO-vnet0\n"
+ "/usr/sbin/iptables -F FI-vnet0\n"
+ "/usr/sbin/iptables -X FI-vnet0\n"
+ "/usr/sbin/iptables -F HI-vnet0\n"
+ "/usr/sbin/iptables -X HI-vnet0\n"
+ "/usr/sbin/ip6tables -D libvirt-out -m physdev --physdev-is-bridged
--physdev-out vnet0 -g FO-vnet0\n"
+ "/usr/sbin/ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g
FO-vnet0\n"
+ "/usr/sbin/ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g
FI-vnet0\n"
+ "/usr/sbin/ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g
HI-vnet0\n"
+ "/usr/sbin/ip6tables -D libvirt-in-post -m physdev --physdev-in vnet0 -j
ACCEPT\n"
+ "/usr/sbin/ip6tables -F FO-vnet0\n"
+ "/usr/sbin/ip6tables -X FO-vnet0\n"
+ "/usr/sbin/ip6tables -F FI-vnet0\n"
+ "/usr/sbin/ip6tables -X FI-vnet0\n"
+ "/usr/sbin/ip6tables -F HI-vnet0\n"
+ "/usr/sbin/ip6tables -X HI-vnet0\n"
+ "/usr/sbin/ebtables -t nat -D PREROUTING -i vnet0 -j
libvirt-I-vnet0\n"
+ "/usr/sbin/ebtables -t nat -D POSTROUTING -o vnet0 -j
libvirt-O-vnet0\n"
+ "/usr/sbin/ebtables -t nat -L libvirt-I-vnet0\n"
+ "/usr/sbin/ebtables -t nat -L libvirt-O-vnet0\n"
+ "/usr/sbin/ebtables -t nat -F libvirt-I-vnet0\n"
+ "/usr/sbin/ebtables -t nat -X libvirt-I-vnet0\n"
+ "/usr/sbin/ebtables -t nat -F libvirt-O-vnet0\n"
+ "/usr/sbin/ebtables -t nat -X libvirt-O-vnet0\n";
+ const char *actual = NULL;
+ int ret = -1;
+
+ virCommandSetDryRun(&buf, NULL, NULL);
+
+ if (ebiptables_driver.allTeardown("vnet0") < 0)
+ goto cleanup;
+
+ if (virBufferError(&buf))
+ goto cleanup;
+
+ actual = virBufferCurrentContent(&buf);
+
+ if (STRNEQ_NULLABLE(actual, expected)) {
+ virtTestDifference(stderr, actual, expected);
+ goto cleanup;
+ }
+
+ ret = 0;
+ cleanup:
+ virCommandSetDryRun(NULL, NULL, NULL);
+ virBufferFreeAndReset(&buf);
+ 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)
--
1.9.0