diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index 1bb8738730..cd7501d484 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -3296,31 +3296,6 @@ ebtablesRemoveTmpSubChainsFW(virFirewallPtr fw, _ebtablesRemoveSubChainsFW(fw, ifname, chainprefixes_host_temp); } -static void -ebtablesRenameTmpSubChain(virBufferPtr buf, - bool incoming, - const char *ifname, - const char *protocol) -{ - char tmpchain[MAX_CHAINNAME_LENGTH], chain[MAX_CHAINNAME_LENGTH]; - char tmpChainPrefix = incoming ? CHAINPREFIX_HOST_IN_TEMP - : CHAINPREFIX_HOST_OUT_TEMP; - char chainPrefix = incoming ? CHAINPREFIX_HOST_IN - : CHAINPREFIX_HOST_OUT; - - if (protocol) { - PRINT_CHAIN(tmpchain, tmpChainPrefix, ifname, protocol); - PRINT_CHAIN(chain, chainPrefix, ifname, protocol); - } else { - PRINT_ROOT_CHAIN(tmpchain, tmpChainPrefix, ifname); - PRINT_ROOT_CHAIN(chain, chainPrefix, ifname); - } - - virBufferAsprintf(buf, - "$EBT -t nat -E %s %s" CMD_SEPARATOR, - tmpchain, chain); -} - static void ebtablesRenameTmpSubChainFW(virFirewallPtr fw, int incoming, @@ -3345,14 +3320,6 @@ ebtablesRenameTmpSubChainFW(virFirewallPtr fw, "-t", "nat", "-E", tmpchain, chain, NULL); } -static void -ebtablesRenameTmpRootChain(virBufferPtr buf, - bool incoming, - const char *ifname) -{ - ebtablesRenameTmpSubChain(buf, incoming, ifname, NULL); -} - static void ebtablesRenameTmpRootChainFW(virFirewallPtr fw, bool incoming, @@ -3657,60 +3624,48 @@ ebtablesApplyDHCPOnlyRules(const char *ifname, static int ebtablesApplyDropAllRules(const char *ifname) { - virBuffer buf = VIR_BUFFER_INITIALIZER; char chain_in [MAX_CHAINNAME_LENGTH], chain_out[MAX_CHAINNAME_LENGTH]; + virFirewallPtr fw = virFirewallNew(); - if (!ebtables_cmd_path) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("cannot create rules since ebtables tool is " - "missing.")); - return -1; - } + if (ebiptablesAllTeardown(ifname) < 0) + goto error; - ebiptablesAllTeardown(ifname); + virFirewallStartTransaction(fw, 0); - NWFILTER_SET_EBTABLES_SHELLVAR(&buf); - - ebtablesCreateTmpRootChain(&buf, true, ifname); - ebtablesCreateTmpRootChain(&buf, false, ifname); + ebtablesCreateTmpRootChainFW(fw, true, ifname); + ebtablesCreateTmpRootChainFW(fw, false, ifname); PRINT_ROOT_CHAIN(chain_in, CHAINPREFIX_HOST_IN_TEMP, ifname); PRINT_ROOT_CHAIN(chain_out, CHAINPREFIX_HOST_OUT_TEMP, ifname); - virBufferAsprintf(&buf, - CMD_DEF("$EBT -t nat -A %s -j DROP") CMD_SEPARATOR - CMD_EXEC - "%s", + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET, + "-t", "nat", "-A", chain_in, + "-j", "DROP", NULL); - chain_in, - CMD_STOPONERR(true)); + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET, + "-t", "nat", "-A", chain_out, + "-j", "DROP", NULL); - virBufferAsprintf(&buf, - CMD_DEF("$EBT -t nat -A %s -j DROP") CMD_SEPARATOR - CMD_EXEC - "%s", + ebtablesLinkTmpRootChainFW(fw, true, ifname); + ebtablesLinkTmpRootChainFW(fw, false, ifname); + ebtablesRenameTmpRootChainFW(fw, true, ifname); + ebtablesRenameTmpRootChainFW(fw, false, ifname); - chain_out, - CMD_STOPONERR(true)); - - ebtablesLinkTmpRootChain(&buf, true, ifname); - ebtablesLinkTmpRootChain(&buf, false, ifname); - ebtablesRenameTmpRootChain(&buf, true, ifname); - ebtablesRenameTmpRootChain(&buf, false, ifname); - - if (ebiptablesExecCLI(&buf, false, NULL) < 0) + virMutexLock(&execCLIMutex); + if (virFirewallApply(fw) < 0) { + virMutexUnlock(&execCLIMutex); goto tear_down_tmpebchains; + } + virMutexUnlock(&execCLIMutex); + virFirewallFree(fw); return 0; tear_down_tmpebchains: ebtablesCleanAll(ifname); - - virReportError(VIR_ERR_BUILD_FIREWALL, - "%s", - _("Some rules could not be created.")); - + error: + virFirewallFree(fw); return -1; } diff --git a/tests/nwfilterebiptablestest.c b/tests/nwfilterebiptablestest.c index 3f9be3ecdc..df939d5fe8 100644 --- a/tests/nwfilterebiptablestest.c +++ b/tests/nwfilterebiptablestest.c @@ -437,6 +437,78 @@ testNWFilterEBIPTablesApplyDHCPOnlyRules(const void *opaque ATTRIBUTE_UNUSED) } + +static int +testNWFilterEBIPTablesApplyDropAllRules(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" + "ebtables -t nat -N libvirt-J-vnet0\n" + "ebtables -t nat -N libvirt-P-vnet0\n" + "ebtables -t nat -A libvirt-J-vnet0 -j DROP\n" + "ebtables -t nat -A libvirt-P-vnet0 -j DROP\n" + "ebtables -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n" + "ebtables -t nat -A POSTROUTING -o vnet0 -j libvirt-P-vnet0\n" + "ebtables -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n" + "ebtables -t nat -E libvirt-P-vnet0 libvirt-O-vnet0\n"; + char *actual = NULL; + int ret = -1; + + virCommandSetDryRun(&buf, NULL, NULL); + + if (ebiptables_driver.applyDropAllRules("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) { @@ -477,6 +549,11 @@ mymain(void) NULL) < 0) ret = -1; + if (virtTestRun("ebiptablesApplyDropAllRules", + testNWFilterEBIPTablesApplyDropAllRules, + NULL) < 0) + ret = -1; + cleanup: return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }