[libvirt] [PATCH 16/26] Convert nwfilter ebiptablesAllTeardown to virFirewall

Daniel P. Berrange berrange at redhat.com
Tue Apr 8 15:38:08 UTC 2014


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 at 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




More information about the libvir-list mailing list