/*
* nwfilter_ebiptables_driver.c: driver for ebtables/iptables on tap devices
*
- * Copyright (C) 2011-2013 Red Hat, Inc.
+ * Copyright (C) 2011-2014 Red Hat, Inc.
* Copyright (C) 2010-2012 IBM Corp.
* Copyright (C) 2010-2012 Stefan Berger
*
/**
* ebiptablesExecCLI:
- * @buf : pointer to virBuffer containing the string with the commands to
- * execute.
- * @status: Pointer to an integer for returning the WEXITSTATUS of the
- * commands executed via the script the was run.
+ * @buf: pointer to virBuffer containing the string with the commands to
+ * execute.
+ * @ignoreNonzero: true if non-zero status is not fatal
* @outbuf: Optional pointer to a string that will hold the buffer with
* output of the executed command. The actual buffer holding
* the message will be newly allocated by this function and
* script.
*
* Execute a sequence of commands (held in the given buffer) as a /bin/sh
- * script and return the status of the execution in *status (if status is
- * NULL, then the script must exit with status 0).
+ * script. Depending on ignoreNonzero, this function will fail if the
+ * script has unexpected status.
*/
static int
-ebiptablesExecCLI(virBufferPtr buf,
- int *status, char **outbuf)
+ebiptablesExecCLI(virBufferPtr buf, bool ignoreNonzero, char **outbuf)
{
int rc = -1;
virCommandPtr cmd;
-
- if (status)
- *status = 0;
+ int status;
if (!virBufferError(buf) && !virBufferUse(buf))
return 0;
virMutexLock(&execCLIMutex);
- rc = virCommandRun(cmd, status);
+ rc = virCommandRun(cmd, ignoreNonzero ? &status : NULL);
virMutexUnlock(&execCLIMutex);
ebtablesLinkTmpRootChain(&buf, 1, ifname, 1);
ebtablesRenameTmpRootChain(&buf, 1, ifname);
- if (ebiptablesExecCLI(&buf, NULL, NULL) < 0)
+ if (ebiptablesExecCLI(&buf, false, NULL) < 0)
goto tear_down_tmpebchains;
return 0;
ebtablesRenameTmpRootChain(&buf, 0, ifname);
}
- if (ebiptablesExecCLI(&buf, NULL, NULL) < 0)
+ if (ebiptablesExecCLI(&buf, false, NULL) < 0)
goto tear_down_tmpebchains;
return 0;
ebtablesRenameTmpRootChain(&buf, 1, ifname);
ebtablesRenameTmpRootChain(&buf, 0, ifname);
- if (ebiptablesExecCLI(&buf, NULL, NULL) < 0)
+ if (ebiptablesExecCLI(&buf, false, NULL) < 0)
goto tear_down_tmpebchains;
return 0;
static int ebtablesCleanAll(const char *ifname)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
- int cli_status;
if (!ebtables_cmd_path)
return 0;
ebtablesRemoveTmpRootChain(&buf, 1, ifname);
ebtablesRemoveTmpRootChain(&buf, 0, ifname);
- ebiptablesExecCLI(&buf, &cli_status, NULL);
+ ebiptablesExecCLI(&buf, true, NULL);
return 0;
}
void **_inst)
{
size_t i, j;
- int cli_status;
ebiptablesRuleInstPtr *inst = (ebiptablesRuleInstPtr *)_inst;
virBuffer buf = VIR_BUFFER_INITIALIZER;
virHashTablePtr chains_in_set = virHashCreate(10, NULL);
ebtablesRemoveTmpSubChains(&buf, ifname);
ebtablesRemoveTmpRootChain(&buf, 1, ifname);
ebtablesRemoveTmpRootChain(&buf, 0, ifname);
- ebiptablesExecCLI(&buf, &cli_status, NULL);
+ ebiptablesExecCLI(&buf, true, NULL);
}
NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
qsort(&ebtChains[0], nEbtChains, sizeof(ebtChains[0]),
ebiptablesRuleOrderSort);
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0)
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
goto tear_down_tmpebchains;
NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
ebtChains[j++].commandTemplate,
'A', -1, 1);
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0)
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
goto tear_down_tmpebchains;
if (haveIptables) {
iptablesCreateBaseChains(&buf);
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0)
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
goto tear_down_tmpebchains;
NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
iptablesCreateTmpRootChains(&buf, ifname);
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0)
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
goto tear_down_tmpiptchains;
NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
iptablesLinkTmpRootChains(&buf, ifname);
iptablesSetupVirtInPost(&buf, ifname);
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0)
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
goto tear_down_tmpiptchains;
NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
'A', -1, 1);
}
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0)
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
goto tear_down_tmpiptchains;
iptablesCheckBridgeNFCallEnabled(false);
iptablesCreateBaseChains(&buf);
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0)
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
goto tear_down_tmpiptchains;
NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
iptablesCreateTmpRootChains(&buf, ifname);
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0)
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
goto tear_down_tmpip6tchains;
NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
iptablesLinkTmpRootChains(&buf, ifname);
iptablesSetupVirtInPost(&buf, ifname);
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0)
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
goto tear_down_tmpip6tchains;
NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
'A', -1, 1);
}
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0)
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
goto tear_down_tmpip6tchains;
iptablesCheckBridgeNFCallEnabled(true);
if (virHashSize(chains_out_set) != 0)
ebtablesLinkTmpRootChain(&buf, 0, ifname, 1);
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0)
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
goto tear_down_ebsubchains_and_unlink;
virHashFree(chains_in_set);
ebtablesRemoveTmpRootChain(&buf, 0, ifname);
}
- ebiptablesExecCLI(&buf, &cli_status, NULL);
+ ebiptablesExecCLI(&buf, true, NULL);
virReportError(VIR_ERR_BUILD_FIREWALL,
_("Some rules could not be created for "
static int
ebiptablesTearNewRules(const char *ifname)
{
- int cli_status;
virBuffer buf = VIR_BUFFER_INITIALIZER;
if (iptables_cmd_path) {
ebtablesRemoveTmpRootChain(&buf, 0, ifname);
}
- ebiptablesExecCLI(&buf, &cli_status, NULL);
+ ebiptablesExecCLI(&buf, true, NULL);
return 0;
}
static int
ebiptablesTearOldRules(const char *ifname)
{
- int cli_status;
virBuffer buf = VIR_BUFFER_INITIALIZER;
/* switch to new iptables user defined chains */
iptablesRemoveRootChains(&buf, ifname);
iptablesRenameTmpRootChains(&buf, ifname);
- ebiptablesExecCLI(&buf, &cli_status, NULL);
+ ebiptablesExecCLI(&buf, true, NULL);
}
if (ip6tables_cmd_path) {
iptablesRemoveRootChains(&buf, ifname);
iptablesRenameTmpRootChains(&buf, ifname);
- ebiptablesExecCLI(&buf, &cli_status, NULL);
+ ebiptablesExecCLI(&buf, true, NULL);
}
if (ebtables_cmd_path) {
ebtablesRenameTmpSubAndRootChains(&buf, ifname);
- ebiptablesExecCLI(&buf, &cli_status, NULL);
+ ebiptablesExecCLI(&buf, true, NULL);
}
return 0;
int nruleInstances,
void **_inst)
{
- int rc = 0;
- int cli_status;
+ int rc = -1;
size_t i;
virBuffer buf = VIR_BUFFER_INITIALIZER;
ebiptablesRuleInstPtr *inst = (ebiptablesRuleInstPtr *)_inst;
'D', -1,
0);
- if (ebiptablesExecCLI(&buf, &cli_status, NULL) < 0)
- goto err_exit;
+ if (ebiptablesExecCLI(&buf, true, NULL) < 0)
+ goto cleanup;
- if (cli_status) {
- virReportError(VIR_ERR_BUILD_FIREWALL,
- "%s",
- _("error while executing CLI commands"));
- rc = -1;
- }
+ rc = 0;
-err_exit:
+cleanup:
return rc;
}
ebiptablesAllTeardown(const char *ifname)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
- int cli_status;
if (iptables_cmd_path) {
NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
ebtablesRemoveRootChain(&buf, 1, ifname);
ebtablesRemoveRootChain(&buf, 0, ifname);
}
- ebiptablesExecCLI(&buf, &cli_status, NULL);
+ ebiptablesExecCLI(&buf, true, NULL);
return 0;
}
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *firewall_cmd_path;
char *output = NULL;
- int status;
int ret = -1;
if (!virNWFilterDriverIsWatchingFirewallD())
"%s",
CMD_STOPONERR(1));
- if (ebiptablesExecCLI(&buf, &status, &output) < 0 ||
- status != 0) {
+ if (ebiptablesExecCLI(&buf, false, &output) < 0) {
VIR_INFO("firewalld support disabled for nwfilter");
} else {
VIR_INFO("firewalld support enabled for nwfilter");
"%s",
CMD_STOPONERR(1));
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0) {
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0) {
VIR_FREE(ebtables_cmd_path);
VIR_ERROR(_("Testing of ebtables command failed: %s"),
errmsg);
"%s",
CMD_STOPONERR(1));
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0) {
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0) {
VIR_FREE(iptables_cmd_path);
VIR_ERROR(_("Testing of iptables command failed: %s"),
errmsg);
"%s",
CMD_STOPONERR(1));
- if (ebiptablesExecCLI(&buf, NULL, &errmsg) < 0) {
+ if (ebiptablesExecCLI(&buf, false, &errmsg) < 0) {
VIR_FREE(ip6tables_cmd_path);
VIR_ERROR(_("Testing of ip6tables command failed: %s"),
errmsg);
virBufferAsprintf(&buf,
"$IPT --version");
- if (ebiptablesExecCLI(&buf, NULL, &cmdout) < 0) {
+ if (ebiptablesExecCLI(&buf, false, &cmdout) < 0) {
VIR_ERROR(_("Testing of iptables command failed: %s"),
cmdout);
return;