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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list