Convert the nwfilter ebtablesApplyNewRules 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/conf/nwfilter_conf.c | 22 +-
src/conf/nwfilter_conf.h | 7 +-
src/nwfilter/nwfilter_ebiptables_driver.c | 2748 +++++++++++------------------
src/nwfilter/nwfilter_ebiptables_driver.h | 17 -
4 files changed, 1090 insertions(+), 1704 deletions(-)
diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c
index 968e045..f57dcef 100644
--- a/src/conf/nwfilter_conf.c
+++ b/src/conf/nwfilter_conf.c
@@ -962,13 +962,16 @@ printTCPFlags(virBufferPtr buf, uint8_t flags)
}
-void
-virNWFilterPrintTCPFlags(virBufferPtr buf,
- uint8_t mask, char sep, uint8_t flags)
+char *
+virNWFilterPrintTCPFlags(uint8_t flags)
{
- printTCPFlags(buf, mask);
- virBufferAddChar(buf, sep);
- printTCPFlags(buf, flags);
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ printTCPFlags(&buf, flags);
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ return NULL;
+ }
+ return virBufferContentAndReset(&buf);
}
@@ -977,10 +980,9 @@ tcpFlagsFormatter(virBufferPtr buf,
virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
nwItemDesc *item)
{
- virNWFilterPrintTCPFlags(buf,
- item->u.tcpFlags.mask,
- '/',
- item->u.tcpFlags.flags);
+ printTCPFlags(buf, item->u.tcpFlags.mask);
+ virBufferAddLit(buf, "/");
+ printTCPFlags(buf, item->u.tcpFlags.flags);
return true;
}
diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index 9f9deab..3c7985c 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -82,8 +82,8 @@ enum virNWFilterEntryItemFlags {
# define HAS_ENTRY_ITEM(data) \
(((data)->flags) & NWFILTER_ENTRY_ITEM_FLAG_EXISTS)
-# define ENTRY_GET_NEG_SIGN(data) \
- ((((data)->flags) & NWFILTER_ENTRY_ITEM_FLAG_IS_NEG) ? "!" :
"")
+# define ENTRY_WANT_NEG_SIGN(data) \
+ (((data)->flags) & NWFILTER_ENTRY_ITEM_FLAG_IS_NEG)
/* datatypes appearing in rule attributes */
enum attrDatatype {
@@ -673,8 +673,7 @@ void virNWFilterCallbackDriversLock(void);
void virNWFilterCallbackDriversUnlock(void);
-void virNWFilterPrintTCPFlags(virBufferPtr buf, uint8_t mask,
- char sep, uint8_t flags);
+char *virNWFilterPrintTCPFlags(uint8_t flags);
bool virNWFilterRuleIsProtocolIPv4(virNWFilterRuleDefPtr rule);
diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c
b/src/nwfilter/nwfilter_ebiptables_driver.c
index db6e324..835e068 100644
--- a/src/nwfilter/nwfilter_ebiptables_driver.c
+++ b/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -105,65 +105,6 @@ static enum ctdirStatus iptables_ctdir_corrected;
#define PRINT_CHAIN(buf, prefix, ifname, suffix) \
snprintf(buf, sizeof(buf), "%c-%s-%s", prefix, ifname, suffix)
-/* The collect_chains() script recursively determines all names
- * of ebtables (nat) chains that are 'children' of a given 'root' chain.
- * The typical output of an ebtables call is as follows:
- *
- * #> ebtables -t nat -L libvirt-I-tck-test205002
- * Bridge table: nat
- *
- * Bridge chain: libvirt-I-tck-test205002, entries: 5, policy: ACCEPT
- * -p IPv4 -j I-tck-test205002-ipv4
- * -p ARP -j I-tck-test205002-arp
- * -p 0x8035 -j I-tck-test205002-rarp
- * -p 0x835 -j ACCEPT
- * -j DROP
- */
-static const char ebtables_script_func_collect_chains[] =
- "collect_chains()\n"
- "{\n"
- " for tmp2 in $*; do\n"
- " for tmp in $($EBT -t nat -L $tmp2 | \\\n"
- " sed -n \"/Bridge chain/,\\$ s/.*-j
\\\\([%s]-.*\\\\)/\\\\1/p\");\n"
- " do\n"
- " echo $tmp\n"
- " collect_chains $tmp\n"
- " done\n"
- " done\n"
- "}\n";
-
-static const char ebiptables_script_func_rm_chains[] =
- "rm_chains()\n"
- "{\n"
- " for tmp in $*; do $EBT -t nat -F $tmp; done\n"
- " for tmp in $*; do $EBT -t nat -X $tmp; done\n"
- "}\n";
-
-static const char ebiptables_script_func_rename_chains[] =
- "rename_chain()\n"
- "{\n"
- " $EBT -t nat -F $2\n"
- " $EBT -t nat -X $2\n"
- " $EBT -t nat -E $1 $2\n"
- "}\n"
- "rename_chains()\n"
- "{\n"
- " for tmp in $*; do\n"
- " case $tmp in\n"
- " %c*) rename_chain $tmp %c${tmp#?} ;;\n"
- " %c*) rename_chain $tmp %c${tmp#?} ;;\n"
- " esac\n"
- " done\n"
- "}\n";
-
-static const char ebiptables_script_set_ifs[] =
- "tmp='\n'\n"
- "IFS=' ''\t'$tmp\n";
-
-#define NWFILTER_FUNC_COLLECT_CHAINS ebtables_script_func_collect_chains
-#define NWFILTER_FUNC_RM_CHAINS ebiptables_script_func_rm_chains
-#define NWFILTER_FUNC_RENAME_CHAINS ebiptables_script_func_rename_chains
-#define NWFILTER_FUNC_SET_IFS ebiptables_script_set_ifs
#define NWFILTER_SET_EBTABLES_SHELLVAR(BUFPTR) \
virBufferAsprintf(BUFPTR, "EBT=\"%s\"\n", ebtables_cmd_path);
@@ -180,29 +121,12 @@ static const char ebiptables_script_set_ifs[] =
#define PRINT_IPT_ROOT_CHAIN(buf, prefix, ifname) \
snprintf(buf, sizeof(buf), "%c%c-%s", prefix[0], prefix[1], ifname)
-#define PHYSDEV_IN "--physdev-in"
-
-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-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
-#define MATCH_PHYSDEV_IN m_physdev_in_str
-#define MATCH_PHYSDEV_OUT m_physdev_out_str
-#define MATCH_PHYSDEV_OUT_OLD m_physdev_out_old_str
+static bool newMatchState;
#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);
static int ebiptablesDriverInit(bool privileged);
static void ebiptablesDriverShutdown(void);
@@ -455,55 +379,39 @@ printDataTypeAsHex(virNWFilterVarCombIterPtr vars,
}
-static void
-printCommentVar(virBufferPtr dest, const char *buf)
-{
- size_t i, len = strlen(buf);
-
- virBufferAddLit(dest, COMMENT_VARNAME "='");
-
- if (len > IPTABLES_MAX_COMMENT_LENGTH)
- len = IPTABLES_MAX_COMMENT_LENGTH;
-
- for (i = 0; i < len; i++) {
- if (buf[i] == '\'')
- virBufferAddLit(dest, "'\\''");
- else
- virBufferAddChar(dest, buf[i]);
- }
- virBufferAddLit(dest, "'" CMD_SEPARATOR);
-}
-
-
static int
-ebtablesHandleEthHdr(virBufferPtr buf,
+ebtablesHandleEthHdr(virFirewallPtr fw,
+ virFirewallRulePtr fwrule,
virNWFilterVarCombIterPtr vars,
ethHdrDataDefPtr ethHdr,
bool reverse)
{
char macaddr[VIR_MAC_STRING_BUFLEN];
+ char macmask[VIR_MAC_STRING_BUFLEN];
+ int ret = -1;
if (HAS_ENTRY_ITEM(ðHdr->dataSrcMACAddr)) {
if (printDataType(vars,
macaddr, sizeof(macaddr),
ðHdr->dataSrcMACAddr) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(buf,
- " %s %s %s",
- reverse ? "-d" : "-s",
- ENTRY_GET_NEG_SIGN(ðHdr->dataSrcMACAddr),
- macaddr);
+ virFirewallRuleAddArgList(fw, fwrule,
+ reverse ? "-d" : "-s",
+ NULL);
+ if (ENTRY_WANT_NEG_SIGN(ðHdr->dataSrcMACAddr))
+ virFirewallRuleAddArg(fw, fwrule, "!");
if (HAS_ENTRY_ITEM(ðHdr->dataSrcMACMask)) {
if (printDataType(vars,
- macaddr, sizeof(macaddr),
+ macmask, sizeof(macmask),
ðHdr->dataSrcMACMask) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(buf,
- "/%s",
- macaddr);
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s/%s", macaddr, macmask);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, macaddr);
}
}
@@ -511,96 +419,80 @@ ebtablesHandleEthHdr(virBufferPtr buf,
if (printDataType(vars,
macaddr, sizeof(macaddr),
ðHdr->dataDstMACAddr) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(buf,
- " %s %s %s",
- reverse ? "-s" : "-d",
- ENTRY_GET_NEG_SIGN(ðHdr->dataDstMACAddr),
- macaddr);
+ virFirewallRuleAddArgList(fw, fwrule,
+ reverse ? "-s" : "-d",
+ NULL);
+ if (ENTRY_WANT_NEG_SIGN(ðHdr->dataDstMACAddr))
+ virFirewallRuleAddArg(fw, fwrule, "!");
if (HAS_ENTRY_ITEM(ðHdr->dataDstMACMask)) {
if (printDataType(vars,
- macaddr, sizeof(macaddr),
+ macmask, sizeof(macmask),
ðHdr->dataDstMACMask) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(buf,
- "/%s",
- macaddr);
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s/%s", macaddr, macmask);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, macaddr);
}
}
- return 0;
-
- err_exit:
- virBufferFreeAndReset(buf);
-
- return -1;
+ ret = 0;
+ cleanup:
+ return ret;
}
/************************ iptables support ************************/
-static void
-iptablesLinkIPTablesBaseChain(virBufferPtr buf,
- const char *udchain,
- const char *syschain,
- unsigned int pos)
-{
- virBufferAsprintf(buf,
- "res=$($IPT -L %s -n --line-number | %s '%s')\n"
- "if [ $? -ne 0 ]; then\n"
- " $IPT -I %s %d -j %s\n"
- "else\n"
- " set dummy $res; r=$2\n"
- " if [ \"${r}\" != \"%d\" ];
then\n"
- " " CMD_DEF("$IPT -I %s %d -j %s")
CMD_SEPARATOR
- " " CMD_EXEC
- " %s"
- " r=$(( $r + 1 ))\n"
- " " CMD_DEF("$IPT -D %s ${r}")
CMD_SEPARATOR
- " " CMD_EXEC
- " %s"
- " fi\n"
- "fi\n",
-
- syschain, grep_cmd_path, udchain,
-
- syschain, pos, udchain,
-
- pos,
-
- syschain, pos, udchain,
- CMD_STOPONERR(true),
-
- syschain,
- CMD_STOPONERR(true));
-}
-
static void
-iptablesCreateBaseChains(virBufferPtr buf)
-{
- virBufferAddLit(buf, "$IPT -N " VIRT_IN_CHAIN CMD_SEPARATOR
- "$IPT -N " VIRT_OUT_CHAIN CMD_SEPARATOR
- "$IPT -N " VIRT_IN_POST_CHAIN CMD_SEPARATOR
- "$IPT -N " HOST_IN_CHAIN CMD_SEPARATOR);
- iptablesLinkIPTablesBaseChain(buf,
- VIRT_IN_CHAIN, "FORWARD", 1);
- iptablesLinkIPTablesBaseChain(buf,
- VIRT_OUT_CHAIN, "FORWARD", 2);
- iptablesLinkIPTablesBaseChain(buf,
- VIRT_IN_POST_CHAIN, "FORWARD", 3);
- iptablesLinkIPTablesBaseChain(buf,
- HOST_IN_CHAIN, "INPUT", 1);
+iptablesCreateBaseChainsFW(virFirewallPtr fw,
+ virFirewallLayer layer)
+{
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-N", VIRT_IN_CHAIN, NULL);
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-N", VIRT_OUT_CHAIN, NULL);
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-N", VIRT_IN_POST_CHAIN, NULL);
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-N", HOST_IN_CHAIN, NULL);
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-D", "FORWARD", "-j",
VIRT_IN_CHAIN, NULL);
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-D", "FORWARD", "-j",
VIRT_OUT_CHAIN, NULL);
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-D", "FORWARD", "-j",
VIRT_IN_POST_CHAIN, NULL);
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-D", "INPUT", "-j",
HOST_IN_CHAIN, NULL);
+ virFirewallAddRule(fw, layer,
+ "-I", "FORWARD", "1",
"-j", VIRT_IN_CHAIN, NULL);
+ virFirewallAddRule(fw, layer,
+ "-I", "FORWARD", "2",
"-j", VIRT_OUT_CHAIN, NULL);
+ virFirewallAddRule(fw, layer,
+ "-I", "FORWARD", "3",
"-j", VIRT_IN_POST_CHAIN, NULL);
+ virFirewallAddRule(fw, layer,
+ "-I", "INPUT", "1", "-j",
HOST_IN_CHAIN, NULL);
}
static void
-iptablesCreateTmpRootChain(virBufferPtr buf,
- char prefix,
- bool incoming, const char *ifname)
+iptablesCreateTmpRootChainFW(virFirewallPtr fw,
+ virFirewallLayer layer,
+ char prefix,
+ bool incoming, const char *ifname)
{
char chain[MAX_CHAINNAME_LENGTH];
char chainPrefix[2] = {
@@ -611,50 +503,19 @@ iptablesCreateTmpRootChain(virBufferPtr buf,
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
- virBufferAsprintf(buf,
- CMD_DEF("$IPT -N %s") CMD_SEPARATOR
- CMD_EXEC
- "%s",
- chain,
- CMD_STOPONERR(true));
-}
-
-
-static void
-iptablesCreateTmpRootChains(virBufferPtr buf,
- const char *ifname)
-{
- iptablesCreateTmpRootChain(buf, 'F', false, ifname);
- iptablesCreateTmpRootChain(buf, 'F', true, ifname);
- iptablesCreateTmpRootChain(buf, 'H', true, ifname);
+ virFirewallAddRule(fw, layer,
+ "-N", chain, NULL);
}
static void
-_iptablesRemoveRootChain(virBufferPtr buf,
- char prefix,
- bool incoming, const char *ifname,
- bool isTempChain)
+iptablesCreateTmpRootChainsFW(virFirewallPtr fw,
+ virFirewallLayer layer,
+ const char *ifname)
{
- 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);
-
- virBufferAsprintf(buf,
- "$IPT -F %s" CMD_SEPARATOR
- "$IPT -X %s" CMD_SEPARATOR,
- chain,
- chain);
+ iptablesCreateTmpRootChainFW(fw, layer, 'F', false, ifname);
+ iptablesCreateTmpRootChainFW(fw, layer, 'F', true, ifname);
+ iptablesCreateTmpRootChainFW(fw, layer, 'H', true, ifname);
}
@@ -679,8 +540,12 @@ _iptablesRemoveRootChainFW(virFirewallPtr fw,
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
- virFirewallAddRule(fw, layer, "-F", chain, NULL);
- virFirewallAddRule(fw, layer, "-X", chain, NULL);
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-F", chain, NULL);
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-X", chain, NULL);
}
@@ -696,17 +561,6 @@ iptablesRemoveRootChainFW(virFirewallPtr fw,
static void
-iptablesRemoveTmpRootChain(virBufferPtr buf,
- char prefix,
- bool incoming,
- const char *ifname)
-{
- _iptablesRemoveRootChain(buf, prefix,
- incoming, ifname, true);
-}
-
-
-static void
iptablesRemoveTmpRootChainFW(virFirewallPtr fw,
virFirewallLayer layer,
char prefix,
@@ -719,16 +573,6 @@ iptablesRemoveTmpRootChainFW(virFirewallPtr fw,
static void
-iptablesRemoveTmpRootChains(virBufferPtr buf,
- const char *ifname)
-{
- iptablesRemoveTmpRootChain(buf, 'F', false, ifname);
- iptablesRemoveTmpRootChain(buf, 'F', true, ifname);
- iptablesRemoveTmpRootChain(buf, 'H', true, ifname);
-}
-
-
-static void
iptablesRemoveTmpRootChainsFW(virFirewallPtr fw,
virFirewallLayer layer,
const char *ifname)
@@ -751,10 +595,11 @@ iptablesRemoveRootChainsFW(virFirewallPtr fw,
static void
-iptablesLinkTmpRootChain(virBufferPtr buf,
- const char *basechain,
- char prefix,
- bool incoming, const char *ifname)
+iptablesLinkTmpRootChainFW(virFirewallPtr fw,
+ virFirewallLayer layer,
+ const char *basechain,
+ char prefix,
+ bool incoming, const char *ifname)
{
char chain[MAX_CHAINNAME_LENGTH];
char chainPrefix[2] = {
@@ -762,51 +607,49 @@ iptablesLinkTmpRootChain(virBufferPtr buf,
incoming ? CHAINPREFIX_HOST_IN_TEMP
: CHAINPREFIX_HOST_OUT_TEMP
};
- const char *match = incoming ? MATCH_PHYSDEV_IN
- : MATCH_PHYSDEV_OUT;
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
- virBufferAsprintf(buf,
- CMD_DEF("$IPT -A %s "
- "%s %s -g %s") CMD_SEPARATOR
- CMD_EXEC
- "%s",
- basechain,
- match, ifname, chain,
-
- CMD_STOPONERR(true));
+ if (incoming)
+ virFirewallAddRule(fw, layer,
+ "-A", basechain,
+ MATCH_PHYSDEV_IN_FW,
+ ifname,
+ "-g", chain, NULL);
+ else
+ virFirewallAddRule(fw, layer,
+ "-A", basechain,
+ MATCH_PHYSDEV_OUT_FW,
+ ifname,
+ "-g", chain, NULL);
}
static void
-iptablesLinkTmpRootChains(virBufferPtr buf,
- const char *ifname)
+iptablesLinkTmpRootChainsFW(virFirewallPtr fw,
+ virFirewallLayer layer,
+ const char *ifname)
{
- iptablesLinkTmpRootChain(buf, VIRT_OUT_CHAIN, 'F', false, ifname);
- iptablesLinkTmpRootChain(buf, VIRT_IN_CHAIN, 'F', true, ifname);
- iptablesLinkTmpRootChain(buf, HOST_IN_CHAIN, 'H', true, ifname);
+ iptablesLinkTmpRootChainFW(fw, layer, VIRT_OUT_CHAIN, 'F', false, ifname);
+ iptablesLinkTmpRootChainFW(fw, layer, VIRT_IN_CHAIN, 'F', true, ifname);
+ iptablesLinkTmpRootChainFW(fw, layer, HOST_IN_CHAIN, 'H', true, ifname);
}
static void
-iptablesSetupVirtInPost(virBufferPtr buf,
- const char *ifname)
-{
- const char *match = MATCH_PHYSDEV_IN;
- virBufferAsprintf(buf,
- "res=$($IPT -n -L " VIRT_IN_POST_CHAIN
- " | grep \"\\%s %s\")\n"
- "if [ \"${res}\" = \"\" ]; then "
- CMD_DEF("$IPT"
- " -A " VIRT_IN_POST_CHAIN
- " %s %s -j ACCEPT") CMD_SEPARATOR
- CMD_EXEC
- "%s"
- "fi\n",
- PHYSDEV_IN, ifname,
- match, ifname,
- CMD_STOPONERR(true));
+iptablesSetupVirtInPostFW(virFirewallPtr fw ATTRIBUTE_UNUSED,
+ virFirewallLayer layer ATTRIBUTE_UNUSED,
+ const char *ifname ATTRIBUTE_UNUSED)
+{
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-D", VIRT_IN_POST_CHAIN,
+ MATCH_PHYSDEV_IN_FW,
+ ifname, "-j", "ACCEPT", NULL);
+ virFirewallAddRule(fw, layer,
+ "-A", VIRT_IN_POST_CHAIN,
+ MATCH_PHYSDEV_IN_FW,
+ ifname, "-j", "ACCEPT", NULL);
}
@@ -821,49 +664,6 @@ iptablesClearVirtInPostFW(virFirewallPtr fw,
ifname, "-j", "ACCEPT", NULL);
}
-static void
-_iptablesUnlinkRootChain(virBufferPtr buf,
- const char *basechain,
- char prefix,
- bool incoming, const char *ifname,
- bool 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;
- const char *match = incoming ? MATCH_PHYSDEV_IN
- : MATCH_PHYSDEV_OUT;
- const char *old_match = incoming ? NULL
- : MATCH_PHYSDEV_OUT_OLD;
-
- PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
-
- virBufferAsprintf(buf,
- "$IPT -D %s "
- "%s %s -g %s" CMD_SEPARATOR,
- basechain,
- match, ifname, chain);
-
- /*
- * Previous versions of libvirt may have created a rule
- * with the --physdev-is-bridged missing. Remove this one
- * as well.
- */
- if (old_match)
- virBufferAsprintf(buf,
- "$IPT -D %s "
- "%s %s -g %s" CMD_SEPARATOR,
- basechain,
- old_match, ifname, chain);
-}
-
static void
_iptablesUnlinkRootChainFW(virFirewallPtr fw,
@@ -887,17 +687,19 @@ _iptablesUnlinkRootChainFW(virFirewallPtr fw,
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
if (incoming)
- virFirewallAddRule(fw, layer,
- "-D", basechain,
- MATCH_PHYSDEV_IN_FW, ifname,
- "-g", chain,
- NULL);
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-D", basechain,
+ MATCH_PHYSDEV_IN_FW, ifname,
+ "-g", chain,
+ NULL);
else
- virFirewallAddRule(fw, layer,
- "-D", basechain,
- MATCH_PHYSDEV_OUT_FW, ifname,
- "-g", chain,
- NULL);
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-D", basechain,
+ MATCH_PHYSDEV_OUT_FW, ifname,
+ "-g", chain,
+ NULL);
/*
* Previous versions of libvirt may have created a rule
@@ -905,11 +707,12 @@ _iptablesUnlinkRootChainFW(virFirewallPtr fw,
* as well.
*/
if (!incoming)
- virFirewallAddRule(fw, layer,
- "-D", basechain,
- MATCH_PHYSDEV_OUT_OLD_FW, ifname,
- "-g", chain,
- NULL);
+ virFirewallAddRuleFull(fw, layer,
+ true, NULL, NULL,
+ "-D", basechain,
+ MATCH_PHYSDEV_OUT_OLD_FW, ifname,
+ "-g", chain,
+ NULL);
}
@@ -926,17 +729,6 @@ iptablesUnlinkRootChainFW(virFirewallPtr fw,
static void
-iptablesUnlinkTmpRootChain(virBufferPtr buf,
- const char *basechain,
- char prefix,
- bool incoming, const char *ifname)
-{
- _iptablesUnlinkRootChain(buf,
- basechain, prefix, incoming, ifname, true);
-}
-
-
-static void
iptablesUnlinkTmpRootChainFW(virFirewallPtr fw,
virFirewallLayer layer,
const char *basechain,
@@ -960,16 +752,6 @@ iptablesUnlinkRootChainsFW(virFirewallPtr fw,
static void
-iptablesUnlinkTmpRootChains(virBufferPtr buf,
- const char *ifname)
-{
- iptablesUnlinkTmpRootChain(buf, VIRT_OUT_CHAIN, 'F', false, ifname);
- iptablesUnlinkTmpRootChain(buf, VIRT_IN_CHAIN, 'F', true, ifname);
- iptablesUnlinkTmpRootChain(buf, HOST_IN_CHAIN, 'H', true, ifname);
-}
-
-
-static void
iptablesUnlinkTmpRootChainsFW(virFirewallPtr fw,
virFirewallLayer layer,
const char *ifname)
@@ -1018,24 +800,17 @@ iptablesRenameTmpRootChainsFW(virFirewallPtr fw,
}
-static void
-iptablesInstCommand(virBufferPtr buf,
- const char *cmdstr)
-{
- virBufferAdd(buf, cmdstr, -1);
- virBufferAsprintf(buf, CMD_SEPARATOR "%s",
- CMD_STOPONERR(true));
-}
-
-
static int
-iptablesHandleSrcMacAddr(virBufferPtr buf,
+iptablesHandleSrcMacAddr(virFirewallPtr fw,
+ virFirewallRulePtr fwrule,
virNWFilterVarCombIterPtr vars,
nwItemDescPtr srcMacAddr,
bool directionIn,
bool *srcmacskipped)
{
char macaddr[VIR_MAC_STRING_BUFLEN];
+ int ret = -1;
+
*srcmacskipped = false;
if (HAS_ENTRY_ITEM(srcMacAddr)) {
@@ -1047,40 +822,43 @@ iptablesHandleSrcMacAddr(virBufferPtr buf,
if (printDataType(vars,
macaddr, sizeof(macaddr),
srcMacAddr) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(buf,
- " -m mac %s --mac-source %s",
- ENTRY_GET_NEG_SIGN(srcMacAddr),
- macaddr);
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-m", "mac",
+ NULL);
+ if (ENTRY_WANT_NEG_SIGN(srcMacAddr))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArgList(fw, fwrule,
+ "--mac-source",
+ macaddr,
+ NULL);
}
- return 0;
-
- err_exit:
- virBufferFreeAndReset(buf);
-
- return -1;
+ ret = 0;
+ cleanup:
+ return ret;
}
static int
-iptablesHandleIpHdr(virBufferPtr buf,
- virBufferPtr afterStateMatch,
+iptablesHandleIpHdr(virFirewallPtr fw,
+ virFirewallRulePtr fwrule,
virNWFilterVarCombIterPtr vars,
ipHdrDataDefPtr ipHdr,
bool directionIn,
- bool *skipRule, bool *skipMatch,
- virBufferPtr prefix)
+ bool *skipRule, bool *skipMatch)
{
char ipaddr[INET6_ADDRSTRLEN],
+ ipaddralt[INET6_ADDRSTRLEN],
number[MAX(INT_BUFSIZE_BOUND(uint32_t),
INT_BUFSIZE_BOUND(int))];
- char str[MAX_IPSET_NAME_LENGTH];
const char *src = "--source";
const char *dst = "--destination";
const char *srcrange = "--src-range";
const char *dstrange = "--dst-range";
+ int ret = -1;
+
if (directionIn) {
src = "--destination";
dst = "--source";
@@ -1088,138 +866,116 @@ iptablesHandleIpHdr(virBufferPtr buf,
dstrange = "--src-range";
}
- if (HAS_ENTRY_ITEM(&ipHdr->dataIPSet) &&
- HAS_ENTRY_ITEM(&ipHdr->dataIPSetFlags)) {
-
- if (printDataType(vars,
- str, sizeof(str),
- &ipHdr->dataIPSet) < 0)
- goto err_exit;
-
- virBufferAsprintf(afterStateMatch,
- " -m set --match-set \"%s\" ",
- str);
-
- if (printDataTypeDirection(vars,
- str, sizeof(str),
- &ipHdr->dataIPSetFlags, directionIn) < 0)
- goto err_exit;
-
- virBufferAdd(afterStateMatch, str, -1);
- }
-
if (HAS_ENTRY_ITEM(&ipHdr->dataSrcIPAddr)) {
-
if (printDataType(vars,
ipaddr, sizeof(ipaddr),
&ipHdr->dataSrcIPAddr) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(buf,
- " %s %s %s",
- ENTRY_GET_NEG_SIGN(&ipHdr->dataSrcIPAddr),
- src,
- ipaddr);
+ if (ENTRY_WANT_NEG_SIGN(&ipHdr->dataSrcIPAddr))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, src);
if (HAS_ENTRY_ITEM(&ipHdr->dataSrcIPMask)) {
if (printDataType(vars,
number, sizeof(number),
&ipHdr->dataSrcIPMask) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(buf,
- "/%s",
- number);
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s/%s", ipaddr, number);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, ipaddr);
}
} else if (HAS_ENTRY_ITEM(&ipHdr->dataSrcIPFrom)) {
-
if (printDataType(vars,
ipaddr, sizeof(ipaddr),
&ipHdr->dataSrcIPFrom) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(buf,
- " -m iprange %s %s %s",
- ENTRY_GET_NEG_SIGN(&ipHdr->dataSrcIPFrom),
- srcrange,
- ipaddr);
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-m", "iprange",
+ NULL);
+ if (ENTRY_WANT_NEG_SIGN(&ipHdr->dataSrcIPFrom))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, srcrange);
if (HAS_ENTRY_ITEM(&ipHdr->dataSrcIPTo)) {
if (printDataType(vars,
- ipaddr, sizeof(ipaddr),
+ ipaddralt, sizeof(ipaddralt),
&ipHdr->dataSrcIPTo) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(buf,
- "-%s",
- ipaddr);
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s-%s", ipaddr, ipaddralt);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, ipaddr);
}
}
if (HAS_ENTRY_ITEM(&ipHdr->dataDstIPAddr)) {
-
if (printDataType(vars,
ipaddr, sizeof(ipaddr),
&ipHdr->dataDstIPAddr) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(buf,
- " %s %s %s",
- ENTRY_GET_NEG_SIGN(&ipHdr->dataDstIPAddr),
- dst,
- ipaddr);
+ if (ENTRY_WANT_NEG_SIGN(&ipHdr->dataDstIPAddr))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, dst);
if (HAS_ENTRY_ITEM(&ipHdr->dataDstIPMask)) {
-
if (printDataType(vars,
number, sizeof(number),
&ipHdr->dataDstIPMask) < 0)
- goto err_exit;
-
- virBufferAsprintf(buf,
- "/%s",
- number);
+ goto cleanup;
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s/%s", ipaddr, number);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, ipaddr);
}
} else if (HAS_ENTRY_ITEM(&ipHdr->dataDstIPFrom)) {
-
if (printDataType(vars,
ipaddr, sizeof(ipaddr),
&ipHdr->dataDstIPFrom) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(buf,
- " -m iprange %s %s %s",
- ENTRY_GET_NEG_SIGN(&ipHdr->dataDstIPFrom),
- dstrange,
- ipaddr);
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-m", "iprange",
+ NULL);
+ if (ENTRY_WANT_NEG_SIGN(&ipHdr->dataDstIPFrom))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, dstrange);
if (HAS_ENTRY_ITEM(&ipHdr->dataDstIPTo)) {
-
if (printDataType(vars,
- ipaddr, sizeof(ipaddr),
+ ipaddralt, sizeof(ipaddralt),
&ipHdr->dataDstIPTo) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(buf,
- "-%s",
- ipaddr);
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s-%s", ipaddr, ipaddralt);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, ipaddr);
}
}
if (HAS_ENTRY_ITEM(&ipHdr->dataDSCP)) {
-
if (printDataType(vars,
number, sizeof(number),
&ipHdr->dataDSCP) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(buf,
- " -m dscp %s --dscp %s",
- ENTRY_GET_NEG_SIGN(&ipHdr->dataDSCP),
- number);
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-m", "dscp",
+ NULL);
+ if (ENTRY_WANT_NEG_SIGN(&ipHdr->dataDSCP))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArgList(fw, fwrule,
+ "--dscp", number,
+ NULL);
}
if (HAS_ENTRY_ITEM(&ipHdr->dataConnlimitAbove)) {
@@ -1227,47 +983,93 @@ iptablesHandleIpHdr(virBufferPtr buf,
/* only support for limit in outgoing dir. */
*skipRule = true;
} else {
+ *skipMatch = true;
+ }
+ }
+
+ ret = 0;
+ cleanup:
+ return ret;
+}
+
+
+static int
+iptablesHandleIpHdrAfterStateMatch(virFirewallPtr fw,
+ virFirewallRulePtr fwrule,
+ virNWFilterVarCombIterPtr vars,
+ ipHdrDataDefPtr ipHdr,
+ bool directionIn)
+{
+ char number[MAX(INT_BUFSIZE_BOUND(uint32_t),
+ INT_BUFSIZE_BOUND(int))];
+ char str[MAX_IPSET_NAME_LENGTH];
+ int ret = -1;
+
+ if (HAS_ENTRY_ITEM(&ipHdr->dataIPSet) &&
+ HAS_ENTRY_ITEM(&ipHdr->dataIPSetFlags)) {
+
+ if (printDataType(vars,
+ str, sizeof(str),
+ &ipHdr->dataIPSet) < 0)
+ goto cleanup;
+
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-m", "set",
+ "--match-set", str,
+ NULL);
+
+ if (printDataTypeDirection(vars,
+ str, sizeof(str),
+ &ipHdr->dataIPSetFlags, directionIn) < 0)
+ goto cleanup;
+
+ virFirewallRuleAddArg(fw, fwrule, str);
+ }
+
+ if (HAS_ENTRY_ITEM(&ipHdr->dataConnlimitAbove)) {
+ if (!directionIn) {
if (printDataType(vars,
number, sizeof(number),
&ipHdr->dataConnlimitAbove) < 0)
- goto err_exit;
+ goto cleanup;
/* place connlimit after potential -m state --state ...
since this is the most useful order */
- virBufferAsprintf(afterStateMatch,
- " -m connlimit %s --connlimit-above %s",
- ENTRY_GET_NEG_SIGN(&ipHdr->dataConnlimitAbove),
- number);
- *skipMatch = true;
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-m", "connlimit",
+ NULL);
+ if (ENTRY_WANT_NEG_SIGN(&ipHdr->dataConnlimitAbove))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArgList(fw, fwrule,
+ "--connlimit-above", number,
+ NULL);
}
}
if (HAS_ENTRY_ITEM(&ipHdr->dataComment)) {
- printCommentVar(prefix, ipHdr->dataComment.u.string);
-
/* keep comments behind everything else -- they are packet eval.
no-ops */
- virBufferAddLit(afterStateMatch,
- " -m comment --comment \"$" COMMENT_VARNAME
"\"");
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-m", "comment",
+ "--comment", ipHdr->dataComment.u.string,
+ NULL);
}
- return 0;
-
- err_exit:
- virBufferFreeAndReset(buf);
- virBufferFreeAndReset(afterStateMatch);
-
- return -1;
+ ret = 0;
+ cleanup:
+ return ret;
}
static int
-iptablesHandlePortData(virBufferPtr buf,
+iptablesHandlePortData(virFirewallPtr fw,
+ virFirewallRulePtr fwrule,
virNWFilterVarCombIterPtr vars,
portDataDefPtr portData,
bool directionIn)
{
char portstr[20];
+ char portstralt[20];
const char *sport = "--sport";
const char *dport = "--dport";
if (directionIn) {
@@ -1281,21 +1083,20 @@ iptablesHandlePortData(virBufferPtr buf,
&portData->dataSrcPortStart) < 0)
goto err_exit;
- virBufferAsprintf(buf,
- " %s %s %s",
- ENTRY_GET_NEG_SIGN(&portData->dataSrcPortStart),
- sport,
- portstr);
+ if (ENTRY_WANT_NEG_SIGN(&portData->dataSrcPortStart))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, sport);
if (HAS_ENTRY_ITEM(&portData->dataSrcPortEnd)) {
if (printDataType(vars,
- portstr, sizeof(portstr),
+ portstralt, sizeof(portstralt),
&portData->dataSrcPortEnd) < 0)
goto err_exit;
- virBufferAsprintf(buf,
- ":%s",
- portstr);
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s:%s", portstr, portstralt);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, portstr);
}
}
@@ -1305,21 +1106,20 @@ iptablesHandlePortData(virBufferPtr buf,
&portData->dataDstPortStart) < 0)
goto err_exit;
- virBufferAsprintf(buf,
- " %s %s %s",
- ENTRY_GET_NEG_SIGN(&portData->dataDstPortStart),
- dport,
- portstr);
+ if (ENTRY_WANT_NEG_SIGN(&portData->dataDstPortStart))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, dport);
if (HAS_ENTRY_ITEM(&portData->dataDstPortEnd)) {
if (printDataType(vars,
- portstr, sizeof(portstr),
+ portstralt, sizeof(portstralt),
&portData->dataDstPortEnd) < 0)
goto err_exit;
- virBufferAsprintf(buf,
- ":%s",
- portstr);
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s:%s", portstr, portstralt);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, portstr);
}
}
@@ -1331,9 +1131,10 @@ iptablesHandlePortData(virBufferPtr buf,
static void
-iptablesEnforceDirection(bool directionIn,
- virNWFilterRuleDefPtr rule,
- virBufferPtr buf)
+iptablesEnforceDirection(virFirewallPtr fw,
+ virFirewallRulePtr fwrule,
+ bool directionIn,
+ virNWFilterRuleDefPtr rule)
{
switch (iptables_ctdir_corrected) {
case CTDIR_STATUS_UNKNOWN:
@@ -1347,14 +1148,20 @@ iptablesEnforceDirection(bool directionIn,
}
if (rule->tt != VIR_NWFILTER_RULE_DIRECTION_INOUT)
- virBufferAsprintf(buf, " -m conntrack --ctdir %s",
- (directionIn) ? "Original"
- : "Reply");
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-m", "conntrack",
+ "--ctdir",
+ (directionIn ?
+ "Original" :
+ "Reply"),
+ NULL);
}
/*
* _iptablesCreateRuleInstance:
+ * @fw: the firewall ruleset instance
+ * @layer: the firewall layer
* @chainPrefix : The prefix to put in front of the name of the chain
* @rule: The rule of the filter to convert
* @ifname : The name of the interface to apply the rule to
@@ -1362,11 +1169,8 @@ iptablesEnforceDirection(bool directionIn,
* @match : optional string for state match
* @accept_target : where to jump to on accepted traffic, i.e., "RETURN"
* "ACCEPT"
- * @isIPv6 : Whether this is an IPv6 rule
* @maySkipICMP : whether this rule may under certain circumstances skip
* the ICMP rule from being created
- * @templates: pointer to array to store rule template
- * @ntemplates: pointer to storage rule template count
*
* Convert a single rule into its representation for later instantiation
*
@@ -1374,287 +1178,267 @@ iptablesEnforceDirection(bool directionIn,
* pointed to by res, != 0 otherwise.
*/
static int
-_iptablesCreateRuleInstance(bool directionIn,
+_iptablesCreateRuleInstance(virFirewallPtr fw,
+ virFirewallLayer layer,
+ bool directionIn,
const char *chainPrefix,
virNWFilterRuleDefPtr rule,
const char *ifname,
virNWFilterVarCombIterPtr vars,
const char *match, bool defMatch,
const char *accept_target,
- bool isIPv6,
- bool maySkipICMP,
- char ***templates,
- size_t *ntemplates)
+ bool maySkipICMP)
{
char chain[MAX_CHAINNAME_LENGTH];
char number[MAX(INT_BUFSIZE_BOUND(uint32_t),
INT_BUFSIZE_BOUND(int))];
- virBuffer prefix = VIR_BUFFER_INITIALIZER;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- virBuffer afterStateMatch = VIR_BUFFER_INITIALIZER;
- virBufferPtr final = NULL;
+ char numberalt[MAX(INT_BUFSIZE_BOUND(uint32_t),
+ INT_BUFSIZE_BOUND(int))];
const char *target;
- const char *iptables_cmd = (isIPv6) ? ip6tables_cmd_path
- : iptables_cmd_path;
- unsigned int bufUsed;
bool srcMacSkipped = false;
bool skipRule = false;
bool skipMatch = false;
bool hasICMPType = false;
- char *template;
-
- if (!iptables_cmd) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot create rule since %s tool is "
- "missing."),
- isIPv6 ? "ip6tables" : "iptables");
- goto err_exit;
- }
+ virFirewallRulePtr fwrule;
+ size_t fwruleargs;
+ int ret = -1;
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
switch (rule->prtclType) {
case VIR_NWFILTER_RULE_PROTOCOL_TCP:
case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6:
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$IPT -A %s",
- chain);
+ fwrule = virFirewallAddRule(fw, layer,
+ "-A", chain,
+ "-p", "tcp",
+ NULL);
- virBufferAddLit(&buf, " -p tcp");
+ fwruleargs = virFirewallRuleGetArgCount(fwrule);
- bufUsed = virBufferUse(&buf);
-
- if (iptablesHandleSrcMacAddr(&buf,
+ if (iptablesHandleSrcMacAddr(fw, fwrule,
vars,
&rule->p.tcpHdrFilter.dataSrcMACAddr,
directionIn,
&srcMacSkipped) < 0)
- goto err_exit;
+ goto cleanup;
- if (iptablesHandleIpHdr(&buf,
- &afterStateMatch,
+ if (iptablesHandleIpHdr(fw, fwrule,
vars,
&rule->p.tcpHdrFilter.ipHdr,
directionIn,
- &skipRule, &skipMatch,
- &prefix) < 0)
- goto err_exit;
+ &skipRule, &skipMatch) < 0)
+ goto cleanup;
if (HAS_ENTRY_ITEM(&rule->p.tcpHdrFilter.dataTCPFlags)) {
- virBufferAsprintf(&buf, " %s --tcp-flags ",
- ENTRY_GET_NEG_SIGN(&rule->p.tcpHdrFilter.dataTCPFlags));
- virNWFilterPrintTCPFlags(&buf,
- rule->p.tcpHdrFilter.dataTCPFlags.u.tcpFlags.mask,
- ' ',
- rule->p.tcpHdrFilter.dataTCPFlags.u.tcpFlags.flags);
+ char *flags;
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.tcpHdrFilter.dataTCPFlags))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, "--tcp-flags");
+
+ if (!(flags =
virNWFilterPrintTCPFlags(rule->p.tcpHdrFilter.dataTCPFlags.u.tcpFlags.mask)))
+ goto cleanup;
+ virFirewallRuleAddArg(fw, fwrule, flags);
+ VIR_FREE(flags);
+ if (!(flags =
virNWFilterPrintTCPFlags(rule->p.tcpHdrFilter.dataTCPFlags.u.tcpFlags.flags)))
+ goto cleanup;
+ virFirewallRuleAddArg(fw, fwrule, flags);
+ VIR_FREE(flags);
}
- if (iptablesHandlePortData(&buf,
+ if (iptablesHandlePortData(fw, fwrule,
vars,
&rule->p.tcpHdrFilter.portData,
directionIn) < 0)
- goto err_exit;
+ goto cleanup;
if (HAS_ENTRY_ITEM(&rule->p.tcpHdrFilter.dataTCPOption)) {
if (printDataType(vars,
number, sizeof(number),
&rule->p.tcpHdrFilter.dataTCPOption) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(&buf,
- " %s --tcp-option %s",
-
ENTRY_GET_NEG_SIGN(&rule->p.tcpHdrFilter.dataTCPOption),
- number);
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.tcpHdrFilter.dataTCPOption))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArgList(fw, fwrule,
+ "--tcp-option", number, NULL);
}
break;
case VIR_NWFILTER_RULE_PROTOCOL_UDP:
case VIR_NWFILTER_RULE_PROTOCOL_UDPoIPV6:
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$IPT -A %s",
- chain);
+ fwrule = virFirewallAddRule(fw, layer,
+ "-A", chain,
+ "-p", "udp",
+ NULL);
- virBufferAddLit(&buf, " -p udp");
+ fwruleargs = virFirewallRuleGetArgCount(fwrule);
- bufUsed = virBufferUse(&buf);
-
- if (iptablesHandleSrcMacAddr(&buf,
+ if (iptablesHandleSrcMacAddr(fw, fwrule,
vars,
&rule->p.udpHdrFilter.dataSrcMACAddr,
directionIn,
&srcMacSkipped) < 0)
- goto err_exit;
+ goto cleanup;
- if (iptablesHandleIpHdr(&buf,
- &afterStateMatch,
+ if (iptablesHandleIpHdr(fw, fwrule,
vars,
&rule->p.udpHdrFilter.ipHdr,
directionIn,
- &skipRule, &skipMatch,
- &prefix) < 0)
- goto err_exit;
+ &skipRule, &skipMatch) < 0)
+ goto cleanup;
- if (iptablesHandlePortData(&buf,
+ if (iptablesHandlePortData(fw, fwrule,
vars,
&rule->p.udpHdrFilter.portData,
directionIn) < 0)
- goto err_exit;
+ goto cleanup;
break;
case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE:
case VIR_NWFILTER_RULE_PROTOCOL_UDPLITEoIPV6:
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$IPT -A %s",
- chain);
-
- virBufferAddLit(&buf, " -p udplite");
+ fwrule = virFirewallAddRule(fw, layer,
+ "-A", chain,
+ "-p", "udplite",
+ NULL);
- bufUsed = virBufferUse(&buf);
+ fwruleargs = virFirewallRuleGetArgCount(fwrule);
- if (iptablesHandleSrcMacAddr(&buf,
+ if (iptablesHandleSrcMacAddr(fw, fwrule,
vars,
&rule->p.udpliteHdrFilter.dataSrcMACAddr,
directionIn,
&srcMacSkipped) < 0)
- goto err_exit;
+ goto cleanup;
- if (iptablesHandleIpHdr(&buf,
- &afterStateMatch,
+ if (iptablesHandleIpHdr(fw, fwrule,
vars,
&rule->p.udpliteHdrFilter.ipHdr,
directionIn,
- &skipRule, &skipMatch,
- &prefix) < 0)
- goto err_exit;
+ &skipRule, &skipMatch) < 0)
+ goto cleanup;
break;
case VIR_NWFILTER_RULE_PROTOCOL_ESP:
case VIR_NWFILTER_RULE_PROTOCOL_ESPoIPV6:
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$IPT -A %s",
- chain);
+ fwrule = virFirewallAddRule(fw, layer,
+ "-A", chain,
+ "-p", "esp",
+ NULL);
- virBufferAddLit(&buf, " -p esp");
+ fwruleargs = virFirewallRuleGetArgCount(fwrule);
- bufUsed = virBufferUse(&buf);
-
- if (iptablesHandleSrcMacAddr(&buf,
+ if (iptablesHandleSrcMacAddr(fw, fwrule,
vars,
&rule->p.espHdrFilter.dataSrcMACAddr,
directionIn,
&srcMacSkipped) < 0)
- goto err_exit;
+ goto cleanup;
- if (iptablesHandleIpHdr(&buf,
- &afterStateMatch,
+ if (iptablesHandleIpHdr(fw, fwrule,
vars,
&rule->p.espHdrFilter.ipHdr,
directionIn,
- &skipRule, &skipMatch,
- &prefix) < 0)
- goto err_exit;
+ &skipRule, &skipMatch) < 0)
+ goto cleanup;
break;
case VIR_NWFILTER_RULE_PROTOCOL_AH:
case VIR_NWFILTER_RULE_PROTOCOL_AHoIPV6:
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$IPT -A %s",
- chain);
+ fwrule = virFirewallAddRule(fw, layer,
+ "-A", chain,
+ "-p", "ah",
+ NULL);
- virBufferAddLit(&buf, " -p ah");
+ fwruleargs = virFirewallRuleGetArgCount(fwrule);
- bufUsed = virBufferUse(&buf);
-
- if (iptablesHandleSrcMacAddr(&buf,
+ if (iptablesHandleSrcMacAddr(fw, fwrule,
vars,
&rule->p.ahHdrFilter.dataSrcMACAddr,
directionIn,
&srcMacSkipped) < 0)
- goto err_exit;
+ goto cleanup;
- if (iptablesHandleIpHdr(&buf,
- &afterStateMatch,
+ if (iptablesHandleIpHdr(fw, fwrule,
vars,
&rule->p.ahHdrFilter.ipHdr,
directionIn,
- &skipRule, &skipMatch,
- &prefix) < 0)
- goto err_exit;
+ &skipRule, &skipMatch) < 0)
+ goto cleanup;
break;
case VIR_NWFILTER_RULE_PROTOCOL_SCTP:
case VIR_NWFILTER_RULE_PROTOCOL_SCTPoIPV6:
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$IPT -A %s",
- chain);
-
- virBufferAddLit(&buf, " -p sctp");
+ fwrule = virFirewallAddRule(fw, layer,
+ "-A", chain,
+ "-p", "sctp",
+ NULL);
- bufUsed = virBufferUse(&buf);
+ fwruleargs = virFirewallRuleGetArgCount(fwrule);
- if (iptablesHandleSrcMacAddr(&buf,
+ if (iptablesHandleSrcMacAddr(fw, fwrule,
vars,
&rule->p.sctpHdrFilter.dataSrcMACAddr,
directionIn,
&srcMacSkipped) < 0)
- goto err_exit;
+ goto cleanup;
- if (iptablesHandleIpHdr(&buf,
- &afterStateMatch,
+ if (iptablesHandleIpHdr(fw, fwrule,
vars,
&rule->p.sctpHdrFilter.ipHdr,
directionIn,
- &skipRule, &skipMatch,
- &prefix) < 0)
- goto err_exit;
+ &skipRule, &skipMatch) < 0)
+ goto cleanup;
- if (iptablesHandlePortData(&buf,
+ if (iptablesHandlePortData(fw, fwrule,
vars,
&rule->p.sctpHdrFilter.portData,
directionIn) < 0)
- goto err_exit;
+ goto cleanup;
break;
case VIR_NWFILTER_RULE_PROTOCOL_ICMP:
case VIR_NWFILTER_RULE_PROTOCOL_ICMPV6:
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$IPT -A %s",
- chain);
+ fwrule = virFirewallAddRule(fw, layer,
+ "-A", chain,
+ NULL);
if (rule->prtclType == VIR_NWFILTER_RULE_PROTOCOL_ICMP)
- virBufferAddLit(&buf, " -p icmp");
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-p", "icmp", NULL);
else
- virBufferAddLit(&buf, " -p icmpv6");
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-p", "icmpv6", NULL);
- bufUsed = virBufferUse(&buf);
+ fwruleargs = virFirewallRuleGetArgCount(fwrule);
- if (iptablesHandleSrcMacAddr(&buf,
+ if (iptablesHandleSrcMacAddr(fw, fwrule,
vars,
&rule->p.icmpHdrFilter.dataSrcMACAddr,
directionIn,
&srcMacSkipped) < 0)
- goto err_exit;
+ goto cleanup;
- if (iptablesHandleIpHdr(&buf,
- &afterStateMatch,
+ if (iptablesHandleIpHdr(fw, fwrule,
vars,
&rule->p.icmpHdrFilter.ipHdr,
directionIn,
- &skipRule, &skipMatch,
- &prefix) < 0)
- goto err_exit;
+ &skipRule, &skipMatch) < 0)
+ goto cleanup;
if (HAS_ENTRY_ITEM(&rule->p.icmpHdrFilter.dataICMPType)) {
const char *parm;
hasICMPType = true;
- if (maySkipICMP)
- goto exit_no_error;
+ if (maySkipICMP) {
+ virFirewallRemoveRule(fw, fwrule);
+ ret = 0;
+ goto cleanup;
+ }
if (rule->prtclType == VIR_NWFILTER_RULE_PROTOCOL_ICMP)
parm = "--icmp-type";
@@ -1664,90 +1448,86 @@ _iptablesCreateRuleInstance(bool directionIn,
if (printDataType(vars,
number, sizeof(number),
&rule->p.icmpHdrFilter.dataICMPType) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(&buf,
- " %s %s %s",
- ENTRY_GET_NEG_SIGN(&rule->p.icmpHdrFilter.dataICMPType),
- parm,
- number);
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.icmpHdrFilter.dataICMPType))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, parm);
if (HAS_ENTRY_ITEM(&rule->p.icmpHdrFilter.dataICMPCode)) {
if (printDataType(vars,
- number, sizeof(number),
+ numberalt, sizeof(numberalt),
&rule->p.icmpHdrFilter.dataICMPCode) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(&buf,
- "/%s",
- number);
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s/%s", number, numberalt);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, number);
}
}
break;
case VIR_NWFILTER_RULE_PROTOCOL_IGMP:
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$IPT -A %s",
- chain);
-
- virBufferAddLit(&buf, " -p igmp");
+ fwrule = virFirewallAddRule(fw, layer,
+ "-A", chain,
+ "-p", "igmp",
+ NULL);
- bufUsed = virBufferUse(&buf);
+ fwruleargs = virFirewallRuleGetArgCount(fwrule);
- if (iptablesHandleSrcMacAddr(&buf,
+ if (iptablesHandleSrcMacAddr(fw, fwrule,
vars,
&rule->p.igmpHdrFilter.dataSrcMACAddr,
directionIn,
&srcMacSkipped) < 0)
- goto err_exit;
+ goto cleanup;
- if (iptablesHandleIpHdr(&buf,
- &afterStateMatch,
+ if (iptablesHandleIpHdr(fw, fwrule,
vars,
&rule->p.igmpHdrFilter.ipHdr,
directionIn,
- &skipRule, &skipMatch,
- &prefix) < 0)
- goto err_exit;
+ &skipRule, &skipMatch) < 0)
+ goto cleanup;
break;
case VIR_NWFILTER_RULE_PROTOCOL_ALL:
case VIR_NWFILTER_RULE_PROTOCOL_ALLoIPV6:
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$IPT -A %s",
- chain);
-
- virBufferAddLit(&buf, " -p all");
+ fwrule = virFirewallAddRule(fw, layer,
+ "-A", chain,
+ "-p", "all",
+ NULL);
- bufUsed = virBufferUse(&buf);
+ fwruleargs = virFirewallRuleGetArgCount(fwrule);
- if (iptablesHandleSrcMacAddr(&buf,
+ if (iptablesHandleSrcMacAddr(fw, fwrule,
vars,
&rule->p.allHdrFilter.dataSrcMACAddr,
directionIn,
&srcMacSkipped) < 0)
- goto err_exit;
+ goto cleanup;
- if (iptablesHandleIpHdr(&buf,
- &afterStateMatch,
+ if (iptablesHandleIpHdr(fw, fwrule,
vars,
&rule->p.allHdrFilter.ipHdr,
directionIn,
- &skipRule, &skipMatch,
- &prefix) < 0)
- goto err_exit;
+ &skipRule, &skipMatch) < 0)
+ goto cleanup;
break;
default:
- return -1;
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unexpected protocol %d"),
+ rule->prtclType);
+ goto cleanup;
}
- if ((srcMacSkipped && bufUsed == virBufferUse(&buf)) ||
- skipRule) {
- virBufferFreeAndReset(&buf);
- virBufferFreeAndReset(&prefix);
+ if ((srcMacSkipped &&
+ fwruleargs == virFirewallRuleGetArgCount(fwrule)) ||
+ skipRule) {
+ virFirewallRemoveRule(fw, fwrule);
return 0;
}
@@ -1758,81 +1538,36 @@ _iptablesCreateRuleInstance(bool directionIn,
skipMatch = defMatch;
}
- if (match && !skipMatch)
- virBufferAsprintf(&buf, " %s", match);
-
- if (defMatch && match != NULL && !skipMatch && !hasICMPType)
- iptablesEnforceDirection(directionIn,
- rule,
- &buf);
-
- if (virBufferError(&afterStateMatch)) {
- virBufferFreeAndReset(&buf);
- virBufferFreeAndReset(&prefix);
- virBufferFreeAndReset(&afterStateMatch);
- virReportOOMError();
- return -1;
- }
-
- if (virBufferUse(&afterStateMatch)) {
- char *s = virBufferContentAndReset(&afterStateMatch);
-
- virBufferAdd(&buf, s, -1);
-
- VIR_FREE(s);
- }
-
- virBufferAsprintf(&buf,
- " -j %s" CMD_DEF_POST CMD_SEPARATOR
- CMD_EXEC,
- target);
-
- if (virBufferError(&buf) || virBufferError(&prefix)) {
- virBufferFreeAndReset(&buf);
- virBufferFreeAndReset(&prefix);
- virReportOOMError();
- return -1;
- }
-
- if (virBufferUse(&prefix)) {
- char *s = virBufferContentAndReset(&buf);
-
- virBufferAdd(&prefix, s, -1);
-
- VIR_FREE(s);
-
- final = &prefix;
-
- if (virBufferError(&prefix)) {
- virBufferFreeAndReset(&prefix);
- virReportOOMError();
- return -1;
- }
- } else
- final = &buf;
-
-
- template = virBufferContentAndReset(final);
- if (VIR_APPEND_ELEMENT(*templates, *ntemplates, template) < 0) {
- VIR_FREE(template);
- return -1;
+ if (match && !skipMatch) {
+ if (newMatchState)
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-m", "conntrack",
+ "--ctstate", match,
+ NULL);
+ else
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-m", "state",
+ "--state", match,
+ NULL);
}
- return 0;
-
- err_exit:
- virBufferFreeAndReset(&buf);
- virBufferFreeAndReset(&prefix);
- virBufferFreeAndReset(&afterStateMatch);
+ if (defMatch && match != NULL && !skipMatch && !hasICMPType)
+ iptablesEnforceDirection(fw, fwrule,
+ directionIn,
+ rule);
- return -1;
+ if (iptablesHandleIpHdrAfterStateMatch(fw, fwrule,
+ vars,
+ &rule->p.allHdrFilter.ipHdr,
+ directionIn) < 0)
+ goto cleanup;
- exit_no_error:
- virBufferFreeAndReset(&buf);
- virBufferFreeAndReset(&prefix);
- virBufferFreeAndReset(&afterStateMatch);
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-j", target, NULL);
- return 0;
+ ret = 0;
+ cleanup:
+ return ret;
}
@@ -1841,7 +1576,7 @@ printStateMatchFlags(int32_t flags, char **bufptr)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
virNWFilterPrintStateMatchFlags(&buf,
- "-m state --state ",
+ "",
flags,
false);
if (virBufferError(&buf)) {
@@ -1854,12 +1589,11 @@ printStateMatchFlags(int32_t flags, char **bufptr)
}
static int
-iptablesCreateRuleInstanceStateCtrl(virNWFilterRuleDefPtr rule,
+iptablesCreateRuleInstanceStateCtrl(virFirewallPtr fw,
+ virFirewallLayer layer,
+ virNWFilterRuleDefPtr rule,
const char *ifname,
- virNWFilterVarCombIterPtr vars,
- bool isIPv6,
- char ***templates,
- size_t *ntemplates)
+ virNWFilterVarCombIterPtr vars)
{
int rc;
bool directionIn = false;
@@ -1893,17 +1627,16 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterRuleDefPtr rule,
chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP;
if (create) {
- rc = _iptablesCreateRuleInstance(directionIn,
+ rc = _iptablesCreateRuleInstance(fw,
+ layer,
+ directionIn,
chainPrefix,
rule,
ifname,
vars,
matchState, false,
"RETURN",
- isIPv6,
- maySkipICMP,
- templates,
- ntemplates);
+ maySkipICMP);
VIR_FREE(matchState);
if (rc < 0)
@@ -1925,17 +1658,16 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterRuleDefPtr rule,
chainPrefix[1] = CHAINPREFIX_HOST_OUT_TEMP;
if (create) {
- rc = _iptablesCreateRuleInstance(!directionIn,
+ rc = _iptablesCreateRuleInstance(fw,
+ layer,
+ !directionIn,
chainPrefix,
rule,
ifname,
vars,
matchState, false,
"ACCEPT",
- isIPv6,
- maySkipICMP,
- templates,
- ntemplates);
+ maySkipICMP);
VIR_FREE(matchState);
@@ -1960,17 +1692,16 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterRuleDefPtr rule,
if (create) {
chainPrefix[0] = 'H';
chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP;
- rc = _iptablesCreateRuleInstance(directionIn,
+ rc = _iptablesCreateRuleInstance(fw,
+ layer,
+ directionIn,
chainPrefix,
rule,
ifname,
vars,
matchState, false,
"RETURN",
- isIPv6,
- maySkipICMP,
- templates,
- ntemplates);
+ maySkipICMP);
VIR_FREE(matchState);
}
@@ -1979,12 +1710,11 @@ iptablesCreateRuleInstanceStateCtrl(virNWFilterRuleDefPtr rule,
static int
-iptablesCreateRuleInstance(virNWFilterRuleDefPtr rule,
+iptablesCreateRuleInstance(virFirewallPtr fw,
+ virFirewallLayer layer,
+ virNWFilterRuleDefPtr rule,
const char *ifname,
- virNWFilterVarCombIterPtr vars,
- bool isIPv6,
- char ***templates,
- size_t *ntemplates)
+ virNWFilterVarCombIterPtr vars)
{
int rc;
bool directionIn = false;
@@ -1995,12 +1725,11 @@ iptablesCreateRuleInstance(virNWFilterRuleDefPtr rule,
if (!(rule->flags & RULE_FLAG_NO_STATEMATCH) &&
(rule->flags & IPTABLES_STATE_FLAGS)) {
- return iptablesCreateRuleInstanceStateCtrl(rule,
+ return iptablesCreateRuleInstanceStateCtrl(fw,
+ layer,
+ rule,
ifname,
- vars,
- isIPv6,
- templates,
- ntemplates);
+ vars);
}
if ((rule->tt == VIR_NWFILTER_RULE_DIRECTION_IN) ||
@@ -2019,66 +1748,63 @@ iptablesCreateRuleInstance(virNWFilterRuleDefPtr rule,
maySkipICMP = directionIn || inout;
if (needState)
- matchState = directionIn ? MATCH_STATE_IN : MATCH_STATE_OUT;
+ matchState = directionIn ? "ESTABLISHED" :
"NEW,ESTABLISHED";
else
matchState = NULL;
chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP;
- rc = _iptablesCreateRuleInstance(directionIn,
+ rc = _iptablesCreateRuleInstance(fw,
+ layer,
+ directionIn,
chainPrefix,
rule,
ifname,
vars,
matchState, true,
"RETURN",
- isIPv6,
- maySkipICMP,
- templates,
- ntemplates);
+ maySkipICMP);
if (rc < 0)
return rc;
maySkipICMP = !directionIn || inout;
if (needState)
- matchState = directionIn ? MATCH_STATE_OUT : MATCH_STATE_IN;
+ matchState = directionIn ? "NEW,ESTABLISHED" :
"ESTABLISHED";
else
matchState = NULL;
chainPrefix[1] = CHAINPREFIX_HOST_OUT_TEMP;
- rc = _iptablesCreateRuleInstance(!directionIn,
+ rc = _iptablesCreateRuleInstance(fw,
+ layer,
+ !directionIn,
chainPrefix,
rule,
ifname,
vars,
matchState, true,
"ACCEPT",
- isIPv6,
- maySkipICMP,
- templates,
- ntemplates);
+ maySkipICMP);
if (rc < 0)
return rc;
maySkipICMP = directionIn;
if (needState)
- matchState = directionIn ? MATCH_STATE_IN : MATCH_STATE_OUT;
+ matchState = directionIn ? "ESTABLISHED" :
"NEW,ESTABLISHED";
else
matchState = NULL;
chainPrefix[0] = 'H';
chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP;
- rc = _iptablesCreateRuleInstance(directionIn,
+ rc = _iptablesCreateRuleInstance(fw,
+ layer,
+ directionIn,
chainPrefix,
rule,
ifname,
vars,
matchState, true,
"RETURN",
- isIPv6,
- maySkipICMP,
- templates,
- ntemplates);
+ maySkipICMP);
return rc;
}
@@ -2088,14 +1814,13 @@ iptablesCreateRuleInstance(virNWFilterRuleDefPtr rule,
/*
* ebtablesCreateRuleInstance:
+ * @fw: the firewall ruleset to add to
* @chainPrefix : The prefix to put in front of the name of the chain
* @chainSuffix: The suffix to put on the end of the name of the chain
* @rule: The rule of the filter to convert
* @ifname : The name of the interface to apply the rule to
* @vars : A map containing the variables to resolve
* @reverse : Whether to reverse src and dst attributes
- * @templates: pointer to array to store rule template
- * @ntemplates: pointer to storage rule template count
*
* Convert a single rule into its representation for later instantiation
*
@@ -2103,13 +1828,13 @@ iptablesCreateRuleInstance(virNWFilterRuleDefPtr rule,
* pointed to by res, != 0 otherwise.
*/
static int
-ebtablesCreateRuleInstance(char chainPrefix,
+ebtablesCreateRuleInstance(virFirewallPtr fw,
+ char chainPrefix,
const char *chainSuffix,
virNWFilterRuleDefPtr rule,
const char *ifname,
virNWFilterVarCombIterPtr vars,
- bool reverse,
- char **template)
+ bool reverse)
{
char macaddr[VIR_MAC_STRING_BUFLEN],
ipaddr[INET_ADDRSTRLEN],
@@ -2117,20 +1842,15 @@ ebtablesCreateRuleInstance(char chainPrefix,
ipv6addr[INET6_ADDRSTRLEN],
number[MAX(INT_BUFSIZE_BOUND(uint32_t),
INT_BUFSIZE_BOUND(int))],
- field[MAX(VIR_MAC_STRING_BUFLEN, INET6_ADDRSTRLEN)];
+ numberalt[MAX(INT_BUFSIZE_BOUND(uint32_t),
+ INT_BUFSIZE_BOUND(int))],
+ field[MAX(VIR_MAC_STRING_BUFLEN, INET6_ADDRSTRLEN)],
+ fieldalt[MAX(VIR_MAC_STRING_BUFLEN, INET6_ADDRSTRLEN)];
char chain[MAX_CHAINNAME_LENGTH];
- virBuffer buf = VIR_BUFFER_INITIALIZER;
const char *target;
bool hasMask = false;
-
- *template = NULL;
-
- if (!ebtables_cmd_path) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot create rule since ebtables tool is "
- "missing."));
- goto err_exit;
- }
+ virFirewallRulePtr fwrule;
+ int ret = -1;
if (STREQ(chainSuffix,
virNWFilterChainSuffixTypeToString(
@@ -2140,89 +1860,85 @@ ebtablesCreateRuleInstance(char chainPrefix,
PRINT_CHAIN(chain, chainPrefix, ifname,
chainSuffix);
+#define INST_ITEM(STRUCT, ITEM, CLI) \
+ if (HAS_ENTRY_ITEM(&rule->p.STRUCT.ITEM)) { \
+ if (printDataType(vars, \
+ field, sizeof(field), \
+ &rule->p.STRUCT.ITEM) < 0) \
+ goto cleanup; \
+ virFirewallRuleAddArg(fw, fwrule, CLI); \
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.STRUCT.ITEM)) \
+ virFirewallRuleAddArg(fw, fwrule, "!"); \
+ virFirewallRuleAddArg(fw, fwrule, field); \
+ }
+
+#define INST_ITEM_2PARMS(STRUCT, ITEM, ITEM_HI, CLI, SEP) \
+ if (HAS_ENTRY_ITEM(&rule->p.STRUCT.ITEM)) { \
+ if (printDataType(vars, \
+ field, sizeof(field), \
+ &rule->p.STRUCT.ITEM) < 0) \
+ goto cleanup; \
+ virFirewallRuleAddArg(fw, fwrule, CLI); \
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.STRUCT.ITEM)) \
+ virFirewallRuleAddArg(fw, fwrule, "!"); \
+ if (HAS_ENTRY_ITEM(&rule->p.STRUCT.ITEM_HI)) { \
+ if (printDataType(vars, \
+ fieldalt, sizeof(fieldalt), \
+ &rule->p.STRUCT.ITEM_HI) < 0) \
+ goto cleanup; \
+ virFirewallRuleAddArgFormat(fw, fwrule, \
+ "%s%s%s", field, SEP, fieldalt); \
+ } else { \
+ virFirewallRuleAddArg(fw, fwrule, field); \
+ } \
+ }
+#define INST_ITEM_RANGE(S, I, I_HI, C) \
+ INST_ITEM_2PARMS(S, I, I_HI, C, ":")
+#define INST_ITEM_MASK(S, I, MASK, C) \
+ INST_ITEM_2PARMS(S, I, MASK, C, "/")
switch (rule->prtclType) {
case VIR_NWFILTER_RULE_PROTOCOL_MAC:
+ fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat",
+ "-A", chain, NULL);
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$EBT -t nat -A %s",
- chain);
-
- if (ebtablesHandleEthHdr(&buf,
+ if (ebtablesHandleEthHdr(fw, fwrule,
vars,
&rule->p.ethHdrFilter.ethHdr,
reverse) < 0)
- goto err_exit;
+ goto cleanup;
if (HAS_ENTRY_ITEM(&rule->p.ethHdrFilter.dataProtocolID)) {
if (printDataTypeAsHex(vars,
number, sizeof(number),
&rule->p.ethHdrFilter.dataProtocolID) < 0)
- goto err_exit;
- virBufferAsprintf(&buf,
- " -p %s %s",
-
ENTRY_GET_NEG_SIGN(&rule->p.ethHdrFilter.dataProtocolID),
- number);
+ goto cleanup;
+ virFirewallRuleAddArg(fw, fwrule, "-p");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.ethHdrFilter.dataProtocolID))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, number);
}
- break;
+ break;
case VIR_NWFILTER_RULE_PROTOCOL_VLAN:
+ fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat", "-A",
chain, NULL);
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$EBT -t nat -A %s",
- chain);
-
-
- if (ebtablesHandleEthHdr(&buf,
+ if (ebtablesHandleEthHdr(fw, fwrule,
vars,
&rule->p.vlanHdrFilter.ethHdr,
reverse) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAddLit(&buf,
- " -p 0x8100");
-
-#define INST_ITEM(STRUCT, ITEM, CLI) \
- if (HAS_ENTRY_ITEM(&rule->p.STRUCT.ITEM)) { \
- if (printDataType(vars, \
- field, sizeof(field), \
- &rule->p.STRUCT.ITEM) < 0) \
- goto err_exit; \
- virBufferAsprintf(&buf, \
- " " CLI " %s %s", \
- ENTRY_GET_NEG_SIGN(&rule->p.STRUCT.ITEM), \
- field); \
- }
-
-#define INST_ITEM_2PARMS(STRUCT, ITEM, ITEM_HI, CLI, SEP) \
- if (HAS_ENTRY_ITEM(&rule->p.STRUCT.ITEM)) { \
- if (printDataType(vars, \
- field, sizeof(field), \
- &rule->p.STRUCT.ITEM) < 0) \
- goto err_exit; \
- virBufferAsprintf(&buf, \
- " " CLI " %s %s", \
- ENTRY_GET_NEG_SIGN(&rule->p.STRUCT.ITEM), \
- field); \
- if (HAS_ENTRY_ITEM(&rule->p.STRUCT.ITEM_HI)) { \
- if (printDataType(vars, \
- field, sizeof(field), \
- &rule->p.STRUCT.ITEM_HI) < 0) \
- goto err_exit; \
- virBufferAsprintf(&buf, SEP "%s", field); \
- } \
- }
-#define INST_ITEM_RANGE(S, I, I_HI, C) \
- INST_ITEM_2PARMS(S, I, I_HI, C, ":")
-#define INST_ITEM_MASK(S, I, MASK, C) \
- INST_ITEM_2PARMS(S, I, MASK, C, "/")
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-p", "0x8100", NULL);
INST_ITEM(vlanHdrFilter, dataVlanID, "--vlan-id")
INST_ITEM(vlanHdrFilter, dataVlanEncap, "--vlan-encap")
- break;
+ break;
case VIR_NWFILTER_RULE_PROTOCOL_STP:
-
/* cannot handle inout direction with srcmask set in reverse dir.
since this clashes with -d below... */
if (reverse &&
@@ -2235,18 +1951,17 @@ ebtablesCreateRuleInstance(char chainPrefix,
return -1;
}
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$EBT -t nat -A %s",
- chain);
-
+ fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat", "-A",
chain, NULL);
- if (ebtablesHandleEthHdr(&buf,
+ if (ebtablesHandleEthHdr(fw, fwrule,
vars,
&rule->p.stpHdrFilter.ethHdr,
reverse) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAddLit(&buf, " -d " NWFILTER_MAC_BGA);
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-d", NWFILTER_MAC_BGA, NULL);
INST_ITEM(stpHdrFilter, dataType, "--stp-type")
INST_ITEM(stpHdrFilter, dataFlags, "--stp-flags")
@@ -2268,172 +1983,169 @@ ebtablesCreateRuleInstance(char chainPrefix,
"--stp-hello-time");
INST_ITEM_RANGE(stpHdrFilter, dataFwdDelay, dataFwdDelayHi,
"--stp-forward-delay");
- break;
+ break;
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
case VIR_NWFILTER_RULE_PROTOCOL_RARP:
+ fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat", "-A",
chain, NULL);
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$EBT -t nat -A %s",
- chain);
-
- if (ebtablesHandleEthHdr(&buf,
+ if (ebtablesHandleEthHdr(fw, fwrule,
vars,
&rule->p.arpHdrFilter.ethHdr,
reverse) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(&buf, " -p 0x%x",
- (rule->prtclType == VIR_NWFILTER_RULE_PROTOCOL_ARP)
- ? l3_protocols[L3_PROTO_ARP_IDX].attr
- : l3_protocols[L3_PROTO_RARP_IDX].attr);
+ virFirewallRuleAddArg(fw, fwrule, "-p");
+ virFirewallRuleAddArgFormat(fw, fwrule, "0x%x",
+ (rule->prtclType ==
VIR_NWFILTER_RULE_PROTOCOL_ARP)
+ ? l3_protocols[L3_PROTO_ARP_IDX].attr
+ : l3_protocols[L3_PROTO_RARP_IDX].attr);
if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataHWType)) {
- if (printDataType(vars,
- number, sizeof(number),
- &rule->p.arpHdrFilter.dataHWType) < 0)
- goto err_exit;
- virBufferAsprintf(&buf,
- " --arp-htype %s %s",
- ENTRY_GET_NEG_SIGN(&rule->p.arpHdrFilter.dataHWType),
- number);
+ if (printDataType(vars,
+ number, sizeof(number),
+ &rule->p.arpHdrFilter.dataHWType) < 0)
+ goto cleanup;
+ virFirewallRuleAddArg(fw, fwrule, "--arp-htype");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.arpHdrFilter.dataHWType))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, number);
}
if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataOpcode)) {
if (printDataType(vars,
number, sizeof(number),
&rule->p.arpHdrFilter.dataOpcode) < 0)
- goto err_exit;
- virBufferAsprintf(&buf,
- " --arp-opcode %s %s",
- ENTRY_GET_NEG_SIGN(&rule->p.arpHdrFilter.dataOpcode),
- number);
+ goto cleanup;
+ virFirewallRuleAddArg(fw, fwrule, "--arp-opcode");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.arpHdrFilter.dataOpcode))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, number);
}
if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataProtocolType)) {
if (printDataTypeAsHex(vars,
number, sizeof(number),
&rule->p.arpHdrFilter.dataProtocolType) <
0)
- goto err_exit;
- virBufferAsprintf(&buf,
- " --arp-ptype %s %s",
-
ENTRY_GET_NEG_SIGN(&rule->p.arpHdrFilter.dataProtocolType),
- number);
+ goto cleanup;
+ virFirewallRuleAddArg(fw, fwrule, "--arp-ptype");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.arpHdrFilter.dataProtocolType))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, number);
}
if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataARPSrcIPAddr)) {
if (printDataType(vars,
ipaddr, sizeof(ipaddr),
&rule->p.arpHdrFilter.dataARPSrcIPAddr) < 0)
- goto err_exit;
+ goto cleanup;
if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataARPSrcIPMask)) {
if (printDataType(vars,
ipmask, sizeof(ipmask),
&rule->p.arpHdrFilter.dataARPSrcIPMask) < 0)
- goto err_exit;
+ goto cleanup;
hasMask = true;
}
- virBufferAsprintf(&buf,
- " %s %s %s/%s",
- reverse ? "--arp-ip-dst" : "--arp-ip-src",
-
ENTRY_GET_NEG_SIGN(&rule->p.arpHdrFilter.dataARPSrcIPAddr),
- ipaddr,
- hasMask ? ipmask : "32");
+ virFirewallRuleAddArg(fw, fwrule,
+ reverse ? "--arp-ip-dst" :
"--arp-ip-src");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.arpHdrFilter.dataARPSrcIPAddr))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s/%s", ipaddr, hasMask ? ipmask :
"32");
}
if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataARPDstIPAddr)) {
if (printDataType(vars,
ipaddr, sizeof(ipaddr),
&rule->p.arpHdrFilter.dataARPDstIPAddr) < 0)
- goto err_exit;
+ goto cleanup;
if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataARPDstIPMask)) {
if (printDataType(vars,
ipmask, sizeof(ipmask),
&rule->p.arpHdrFilter.dataARPDstIPMask) < 0)
- goto err_exit;
+ goto cleanup;
hasMask = true;
}
- virBufferAsprintf(&buf,
- " %s %s %s/%s",
- reverse ? "--arp-ip-src" : "--arp-ip-dst",
-
ENTRY_GET_NEG_SIGN(&rule->p.arpHdrFilter.dataARPDstIPAddr),
- ipaddr,
- hasMask ? ipmask : "32");
+ virFirewallRuleAddArg(fw, fwrule,
+ reverse ? "--arp-ip-src" :
"--arp-ip-dst");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.arpHdrFilter.dataARPDstIPAddr))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s/%s", ipaddr, hasMask ? ipmask :
"32");
}
if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataARPSrcMACAddr)) {
if (printDataType(vars,
macaddr, sizeof(macaddr),
&rule->p.arpHdrFilter.dataARPSrcMACAddr) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(&buf,
- " %s %s %s",
- reverse ? "--arp-mac-dst" :
"--arp-mac-src",
-
ENTRY_GET_NEG_SIGN(&rule->p.arpHdrFilter.dataARPSrcMACAddr),
- macaddr);
+ virFirewallRuleAddArg(fw, fwrule,
+ reverse ? "--arp-mac-dst" :
"--arp-mac-src");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.arpHdrFilter.dataARPSrcMACAddr))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, macaddr);
}
if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataARPDstMACAddr)) {
if (printDataType(vars,
macaddr, sizeof(macaddr),
&rule->p.arpHdrFilter.dataARPDstMACAddr) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(&buf,
- " %s %s %s",
- reverse ? "--arp-mac-src" :
"--arp-mac-dst",
-
ENTRY_GET_NEG_SIGN(&rule->p.arpHdrFilter.dataARPDstMACAddr),
- macaddr);
+ virFirewallRuleAddArg(fw, fwrule,
+ reverse ? "--arp-mac-src" :
"--arp-mac-dst");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.arpHdrFilter.dataARPDstMACAddr))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, macaddr);
}
if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataGratuitousARP) &&
rule->p.arpHdrFilter.dataGratuitousARP.u.boolean) {
- virBufferAsprintf(&buf,
- " %s --arp-gratuitous",
-
ENTRY_GET_NEG_SIGN(&rule->p.arpHdrFilter.dataGratuitousARP));
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.arpHdrFilter.dataGratuitousARP))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, "--arp-gratuitous");
}
- break;
+ break;
case VIR_NWFILTER_RULE_PROTOCOL_IP:
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$EBT -t nat -A %s",
- chain);
+ fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat", "-A",
chain, NULL);
- if (ebtablesHandleEthHdr(&buf,
+ if (ebtablesHandleEthHdr(fw, fwrule,
vars,
&rule->p.ipHdrFilter.ethHdr,
reverse) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAddLit(&buf,
- " -p ipv4");
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-p", "ipv4", NULL);
if (HAS_ENTRY_ITEM(&rule->p.ipHdrFilter.ipHdr.dataSrcIPAddr)) {
if (printDataType(vars,
ipaddr, sizeof(ipaddr),
&rule->p.ipHdrFilter.ipHdr.dataSrcIPAddr) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(&buf,
- " %s %s %s",
- reverse ? "--ip-destination" :
"--ip-source",
-
ENTRY_GET_NEG_SIGN(&rule->p.ipHdrFilter.ipHdr.dataSrcIPAddr),
- ipaddr);
+ virFirewallRuleAddArg(fw, fwrule,
+ reverse ? "--ip-destination" :
"--ip-source");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.ipHdrFilter.ipHdr.dataSrcIPAddr))
+ virFirewallRuleAddArg(fw, fwrule, "!");
if (HAS_ENTRY_ITEM(&rule->p.ipHdrFilter.ipHdr.dataSrcIPMask)) {
if (printDataType(vars,
number, sizeof(number),
- &rule->p.ipHdrFilter.ipHdr.dataSrcIPMask)
- < 0)
- goto err_exit;
- virBufferAsprintf(&buf,
- "/%s",
- number);
+ &rule->p.ipHdrFilter.ipHdr.dataSrcIPMask) <
0)
+ goto cleanup;
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s/%s", ipaddr, number);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, ipaddr);
}
}
@@ -2442,23 +2154,22 @@ ebtablesCreateRuleInstance(char chainPrefix,
if (printDataType(vars,
ipaddr, sizeof(ipaddr),
&rule->p.ipHdrFilter.ipHdr.dataDstIPAddr) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(&buf,
- " %s %s %s",
- reverse ? "--ip-source" :
"--ip-destination",
-
ENTRY_GET_NEG_SIGN(&rule->p.ipHdrFilter.ipHdr.dataDstIPAddr),
- ipaddr);
+ virFirewallRuleAddArg(fw, fwrule,
+ reverse ? "--ip-source" :
"--ip-destination");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.ipHdrFilter.ipHdr.dataDstIPAddr))
+ virFirewallRuleAddArg(fw, fwrule, "!");
if (HAS_ENTRY_ITEM(&rule->p.ipHdrFilter.ipHdr.dataDstIPMask)) {
if (printDataType(vars,
number, sizeof(number),
- &rule->p.ipHdrFilter.ipHdr.dataDstIPMask)
- < 0)
- goto err_exit;
- virBufferAsprintf(&buf,
- "/%s",
- number);
+ &rule->p.ipHdrFilter.ipHdr.dataDstIPMask) <
0)
+ goto cleanup;
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s/%s", ipaddr, number);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, ipaddr);
}
}
@@ -2466,65 +2177,59 @@ ebtablesCreateRuleInstance(char chainPrefix,
if (printDataType(vars,
number, sizeof(number),
&rule->p.ipHdrFilter.ipHdr.dataProtocolID) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(&buf,
- " --ip-protocol %s %s",
- ENTRY_GET_NEG_SIGN(&rule->p.ipHdrFilter.ipHdr.dataProtocolID),
- number);
+ virFirewallRuleAddArg(fw, fwrule, "--ip-protocol");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.ipHdrFilter.ipHdr.dataProtocolID))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, number);
}
if (HAS_ENTRY_ITEM(&rule->p.ipHdrFilter.portData.dataSrcPortStart)) {
-
if (printDataType(vars,
number, sizeof(number),
- &rule->p.ipHdrFilter.portData.dataSrcPortStart)
- < 0)
- goto err_exit;
+ &rule->p.ipHdrFilter.portData.dataSrcPortStart) <
0)
+ goto cleanup;
- virBufferAsprintf(&buf,
- " %s %s %s",
- reverse ? "--ip-destination-port" :
"--ip-source-port",
-
ENTRY_GET_NEG_SIGN(&rule->p.ipHdrFilter.portData.dataSrcPortStart),
- number);
+ virFirewallRuleAddArg(fw, fwrule,
+ reverse ? "--ip-destination-port" :
"--ip-source-port");
+ if
(ENTRY_WANT_NEG_SIGN(&rule->p.ipHdrFilter.portData.dataSrcPortStart))
+ virFirewallRuleAddArg(fw, fwrule, "!");
if (HAS_ENTRY_ITEM(&rule->p.ipHdrFilter.portData.dataSrcPortEnd)) {
if (printDataType(vars,
- number, sizeof(number),
- &rule->p.ipHdrFilter.portData.dataSrcPortEnd)
- < 0)
- goto err_exit;
+ numberalt, sizeof(numberalt),
+ &rule->p.ipHdrFilter.portData.dataSrcPortEnd)
< 0)
+ goto cleanup;
- virBufferAsprintf(&buf,
- ":%s",
- number);
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s:%s", number, numberalt);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, number);
}
}
if (HAS_ENTRY_ITEM(&rule->p.ipHdrFilter.portData.dataDstPortStart)) {
-
if (printDataType(vars,
number, sizeof(number),
- &rule->p.ipHdrFilter.portData.dataDstPortStart)
- < 0)
- goto err_exit;
+ &rule->p.ipHdrFilter.portData.dataDstPortStart) <
0)
+ goto cleanup;
- virBufferAsprintf(&buf,
- " %s %s %s",
- reverse ? "--ip-source-port" :
"--ip-destination-port",
-
ENTRY_GET_NEG_SIGN(&rule->p.ipHdrFilter.portData.dataDstPortStart),
- number);
+ virFirewallRuleAddArg(fw, fwrule,
+ reverse ? "--ip-source-port" :
"--ip-destination-port");
+ if
(ENTRY_WANT_NEG_SIGN(&rule->p.ipHdrFilter.portData.dataDstPortStart))
+ virFirewallRuleAddArg(fw, fwrule, "!");
if (HAS_ENTRY_ITEM(&rule->p.ipHdrFilter.portData.dataDstPortEnd)) {
if (printDataType(vars,
- number, sizeof(number),
- &rule->p.ipHdrFilter.portData.dataDstPortEnd)
- < 0)
- goto err_exit;
-
- virBufferAsprintf(&buf,
- ":%s",
- number);
+ numberalt, sizeof(numberalt),
+ &rule->p.ipHdrFilter.portData.dataDstPortEnd)
< 0)
+ goto cleanup;
+
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s:%s", number, numberalt);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, number);
}
}
@@ -2532,50 +2237,48 @@ ebtablesCreateRuleInstance(char chainPrefix,
if (printDataTypeAsHex(vars,
number, sizeof(number),
&rule->p.ipHdrFilter.ipHdr.dataDSCP) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(&buf,
- " --ip-tos %s %s",
- ENTRY_GET_NEG_SIGN(&rule->p.ipHdrFilter.ipHdr.dataDSCP),
- number);
+ virFirewallRuleAddArg(fw, fwrule, "--ip-tos");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.ipHdrFilter.ipHdr.dataDSCP))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, number);
}
- break;
+ break;
case VIR_NWFILTER_RULE_PROTOCOL_IPV6:
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$EBT -t nat -A %s",
- chain);
+ fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat", "-A",
chain, NULL);
- if (ebtablesHandleEthHdr(&buf,
+ if (ebtablesHandleEthHdr(fw, fwrule,
vars,
&rule->p.ipv6HdrFilter.ethHdr,
reverse) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAddLit(&buf,
- " -p ipv6");
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-p", "ipv6", NULL);
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.ipHdr.dataSrcIPAddr)) {
if (printDataType(vars,
ipv6addr, sizeof(ipv6addr),
&rule->p.ipv6HdrFilter.ipHdr.dataSrcIPAddr) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(&buf,
- " %s %s %s",
- reverse ? "--ip6-destination" :
"--ip6-source",
-
ENTRY_GET_NEG_SIGN(&rule->p.ipv6HdrFilter.ipHdr.dataSrcIPAddr),
- ipv6addr);
+ virFirewallRuleAddArg(fw, fwrule,
+ reverse ? "--ip6-destination" :
"--ip6-source");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.ipv6HdrFilter.ipHdr.dataSrcIPAddr))
+ virFirewallRuleAddArg(fw, fwrule, "!");
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.ipHdr.dataSrcIPMask)) {
if (printDataType(vars,
number, sizeof(number),
- &rule->p.ipv6HdrFilter.ipHdr.dataSrcIPMask)
- < 0)
- goto err_exit;
- virBufferAsprintf(&buf,
- "/%s",
- number);
+ &rule->p.ipv6HdrFilter.ipHdr.dataSrcIPMask) <
0)
+ goto cleanup;
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s/%s", ipv6addr, number);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, ipv6addr);
}
}
@@ -2584,23 +2287,22 @@ ebtablesCreateRuleInstance(char chainPrefix,
if (printDataType(vars,
ipv6addr, sizeof(ipv6addr),
&rule->p.ipv6HdrFilter.ipHdr.dataDstIPAddr) < 0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(&buf,
- " %s %s %s",
- reverse ? "--ip6-source" :
"--ip6-destination",
-
ENTRY_GET_NEG_SIGN(&rule->p.ipv6HdrFilter.ipHdr.dataDstIPAddr),
- ipv6addr);
+ virFirewallRuleAddArg(fw, fwrule,
+ reverse ? "--ip6-source" :
"--ip6-destination");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.ipv6HdrFilter.ipHdr.dataDstIPAddr))
+ virFirewallRuleAddArg(fw, fwrule, "!");
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.ipHdr.dataDstIPMask)) {
if (printDataType(vars,
number, sizeof(number),
- &rule->p.ipv6HdrFilter.ipHdr.dataDstIPMask)
- < 0)
- goto err_exit;
- virBufferAsprintf(&buf,
- "/%s",
- number);
+ &rule->p.ipv6HdrFilter.ipHdr.dataDstIPMask) <
0)
+ goto cleanup;
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s/%s", ipv6addr, number);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, ipv6addr);
}
}
@@ -2608,38 +2310,36 @@ ebtablesCreateRuleInstance(char chainPrefix,
if (printDataType(vars,
number, sizeof(number),
&rule->p.ipv6HdrFilter.ipHdr.dataProtocolID) <
0)
- goto err_exit;
+ goto cleanup;
- virBufferAsprintf(&buf,
- " --ip6-protocol %s %s",
- ENTRY_GET_NEG_SIGN(&rule->p.ipv6HdrFilter.ipHdr.dataProtocolID),
- number);
+ virFirewallRuleAddArg(fw, fwrule, "--ip6-protocol");
+ if (ENTRY_WANT_NEG_SIGN(&rule->p.ipv6HdrFilter.ipHdr.dataProtocolID))
+ virFirewallRuleAddArg(fw, fwrule, "!");
+ virFirewallRuleAddArg(fw, fwrule, number);
}
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.portData.dataSrcPortStart)) {
if (printDataType(vars,
number, sizeof(number),
- &rule->p.ipv6HdrFilter.portData.dataSrcPortStart)
- < 0)
- goto err_exit;
+ &rule->p.ipv6HdrFilter.portData.dataSrcPortStart)
< 0)
+ goto cleanup;
- virBufferAsprintf(&buf,
- " %s %s %s",
- reverse ? "--ip6-destination-port" :
"--ip6-source-port",
-
ENTRY_GET_NEG_SIGN(&rule->p.ipv6HdrFilter.portData.dataSrcPortStart),
- number);
+ virFirewallRuleAddArg(fw, fwrule,
+ reverse ? "--ip6-destination-port" :
"--ip6-source-port");
+ if
(ENTRY_WANT_NEG_SIGN(&rule->p.ipv6HdrFilter.portData.dataSrcPortStart))
+ virFirewallRuleAddArg(fw, fwrule, "!");
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.portData.dataSrcPortEnd)) {
if (printDataType(vars,
- number, sizeof(number),
- &rule->p.ipv6HdrFilter.portData.dataSrcPortEnd)
- < 0)
- goto err_exit;
+ numberalt, sizeof(numberalt),
+ &rule->p.ipv6HdrFilter.portData.dataSrcPortEnd)
< 0)
+ goto cleanup;
- virBufferAsprintf(&buf,
- ":%s",
- number);
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s:%s", number, numberalt);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, number);
}
}
@@ -2647,37 +2347,37 @@ ebtablesCreateRuleInstance(char chainPrefix,
if (printDataType(vars,
number, sizeof(number),
- &rule->p.ipv6HdrFilter.portData.dataDstPortStart)
- < 0)
- goto err_exit;
+ &rule->p.ipv6HdrFilter.portData.dataDstPortStart)
< 0)
+ goto cleanup;
- virBufferAsprintf(&buf,
- " %s %s %s",
- reverse ? "--ip6-source-port" :
"--ip6-destination-port",
-
ENTRY_GET_NEG_SIGN(&rule->p.ipv6HdrFilter.portData.dataDstPortStart),
- number);
+ virFirewallRuleAddArg(fw, fwrule,
+ reverse ? "--ip6-source-port" :
"--ip6-destination-port");
+ if
(ENTRY_WANT_NEG_SIGN(&rule->p.ipv6HdrFilter.portData.dataDstPortStart))
+ virFirewallRuleAddArg(fw, fwrule, "!");
if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.portData.dataDstPortEnd)) {
if (printDataType(vars,
- number, sizeof(number),
- &rule->p.ipv6HdrFilter.portData.dataDstPortEnd)
- < 0)
- goto err_exit;
+ numberalt, sizeof(numberalt),
+ &rule->p.ipv6HdrFilter.portData.dataDstPortEnd)
< 0)
+ goto cleanup;
- virBufferAsprintf(&buf,
- ":%s",
- number);
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "%s:%s", number, numberalt);
+ } else {
+ virFirewallRuleAddArg(fw, fwrule, number);
}
}
- break;
+ break;
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
- virBufferAsprintf(&buf,
- CMD_DEF_PRE "$EBT -t nat -A %s",
- chain);
- break;
+ fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat", "-A",
chain, NULL);
+ break;
default:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unexpected rule protocol %d"),
+ rule->prtclType);
return -1;
}
@@ -2686,29 +2386,22 @@ ebtablesCreateRuleInstance(char chainPrefix,
/* REJECT not supported */
target = virNWFilterJumpTargetTypeToString(
VIR_NWFILTER_RULE_ACTION_DROP);
- break;
+ break;
default:
target = virNWFilterJumpTargetTypeToString(rule->action);
}
- virBufferAsprintf(&buf,
- " -j %s" CMD_DEF_POST CMD_SEPARATOR
- CMD_EXEC,
- target);
-
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
- virReportOOMError();
- return -1;
- }
-
- *template = virBufferContentAndReset(&buf);
- return 0;
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-j", target, NULL);
- err_exit:
- virBufferFreeAndReset(&buf);
+#undef INST_ITEM_RANGE
+#undef INST_ITEM_MASK
+#undef INST_ITEM_2PARMS
+#undef INST_ITEM
- return -1;
+ ret = 0;
+ cleanup:
+ return ret;
}
@@ -2727,84 +2420,61 @@ ebtablesCreateRuleInstance(char chainPrefix,
* pointed to by res, -1 otherwise
*/
static int
-ebiptablesCreateRuleInstance(const char *chainSuffix,
+ebiptablesCreateRuleInstance(virFirewallPtr fw,
+ const char *chainSuffix,
virNWFilterRuleDefPtr rule,
const char *ifname,
- virNWFilterVarCombIterPtr vars,
- char ***templates,
- size_t *ntemplates)
+ virNWFilterVarCombIterPtr vars)
{
- size_t i;
-
- *templates = NULL;
- *ntemplates = 0;
+ int ret = -1;
if (virNWFilterRuleIsProtocolEthernet(rule)) {
if (rule->tt == VIR_NWFILTER_RULE_DIRECTION_OUT ||
rule->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT) {
- char *template;
- if (ebtablesCreateRuleInstance(CHAINPREFIX_HOST_IN_TEMP,
+ if (ebtablesCreateRuleInstance(fw,
+ CHAINPREFIX_HOST_IN_TEMP,
chainSuffix,
rule,
ifname,
vars,
- rule->tt ==
VIR_NWFILTER_RULE_DIRECTION_INOUT,
- &template) < 0)
- goto error;
-
- if (VIR_APPEND_ELEMENT(*templates, *ntemplates, template) < 0) {
- VIR_FREE(template);
- goto error;
- }
+ rule->tt ==
VIR_NWFILTER_RULE_DIRECTION_INOUT) < 0)
+ goto cleanup;
}
if (rule->tt == VIR_NWFILTER_RULE_DIRECTION_IN ||
rule->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT) {
- char *template;
- if (ebtablesCreateRuleInstance(CHAINPREFIX_HOST_OUT_TEMP,
+ if (ebtablesCreateRuleInstance(fw,
+ CHAINPREFIX_HOST_OUT_TEMP,
chainSuffix,
rule,
ifname,
vars,
- false,
- &template) < 0)
- goto error;
-
- if (VIR_APPEND_ELEMENT(*templates, *ntemplates, template) < 0) {
- VIR_FREE(template);
- goto error;
- }
+ false) < 0)
+ goto cleanup;
}
} else {
- bool isIPv6;
+ virFirewallLayer layer;
if (virNWFilterRuleIsProtocolIPv6(rule)) {
- isIPv6 = true;
+ layer = VIR_FIREWALL_LAYER_IPV6;
} else if (virNWFilterRuleIsProtocolIPv4(rule)) {
- isIPv6 = false;
+ layer = VIR_FIREWALL_LAYER_IPV4;
} else {
virReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("unexpected protocol type"));
- goto error;
+ goto cleanup;
}
- if (iptablesCreateRuleInstance(rule,
+ if (iptablesCreateRuleInstance(fw,
+ layer,
+ rule,
ifname,
- vars,
- isIPv6,
- templates,
- ntemplates) < 0)
- goto error;
+ vars) < 0)
+ goto cleanup;
}
- return 0;
-
- error:
- for (i = 0; i < *ntemplates; i++)
- VIR_FREE((*templates)[i]);
- VIR_FREE(*templates);
- *templates = NULL;
- *ntemplates = 0;
- return -1;
+ ret = 0;
+ cleanup:
+ return ret;
}
@@ -2839,6 +2509,7 @@ ebiptablesExecCLI(virBufferPtr buf, bool ignoreNonzero, char
**outbuf)
if (outbuf)
VIR_FREE(*outbuf);
+ VIR_INFO("Run [%s]", virBufferCurrentContent(buf));
cmd = virCommandNewArgList("/bin/sh", "-c", NULL);
virCommandAddArgBuffer(cmd, buf);
if (outbuf)
@@ -2857,26 +2528,6 @@ ebiptablesExecCLI(virBufferPtr buf, bool ignoreNonzero, char
**outbuf)
static void
-ebtablesCreateTmpRootChain(virBufferPtr buf,
- bool incoming, const char *ifname)
-{
- char chain[MAX_CHAINNAME_LENGTH];
- char chainPrefix = incoming ? CHAINPREFIX_HOST_IN_TEMP
- : CHAINPREFIX_HOST_OUT_TEMP;
-
- PRINT_ROOT_CHAIN(chain, chainPrefix, ifname);
-
- virBufferAsprintf(buf,
- CMD_DEF("$EBT -t nat -N %s") CMD_SEPARATOR
- CMD_EXEC
- "%s",
- chain,
- CMD_STOPONERR(true));
-
-}
-
-
-static void
ebtablesCreateTmpRootChainFW(virFirewallPtr fw,
int incoming, const char *ifname)
{
@@ -2892,29 +2543,6 @@ ebtablesCreateTmpRootChainFW(virFirewallPtr fw,
static void
-ebtablesLinkTmpRootChain(virBufferPtr buf,
- bool incoming, const char *ifname)
-{
- char chain[MAX_CHAINNAME_LENGTH];
- char chainPrefix = incoming ? CHAINPREFIX_HOST_IN_TEMP
- : CHAINPREFIX_HOST_OUT_TEMP;
- char iodev = incoming ? 'i' : 'o';
-
- PRINT_ROOT_CHAIN(chain, chainPrefix, ifname);
-
- virBufferAsprintf(buf,
- CMD_DEF("$EBT -t nat -A %s -%c %s -j %s") CMD_SEPARATOR
- CMD_EXEC
- "%s",
- incoming ? EBTABLES_CHAIN_INCOMING
- : EBTABLES_CHAIN_OUTGOING,
- iodev, ifname, chain,
-
- CMD_STOPONERR(true));
-}
-
-
-static void
ebtablesLinkTmpRootChainFW(virFirewallPtr fw,
int incoming, const char *ifname)
{
@@ -2933,30 +2561,6 @@ ebtablesLinkTmpRootChainFW(virFirewallPtr fw,
static void
-_ebtablesRemoveRootChain(virBufferPtr buf,
- bool incoming, const char *ifname,
- bool 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);
-
- virBufferAsprintf(buf,
- "$EBT -t nat -F %s" CMD_SEPARATOR
- "$EBT -t nat -X %s" CMD_SEPARATOR,
- chain,
- chain);
-}
-
-
-static void
_ebtablesRemoveRootChainFW(virFirewallPtr fw,
bool incoming, const char *ifname,
int isTempChain)
@@ -2988,14 +2592,6 @@ ebtablesRemoveRootChainFW(virFirewallPtr fw,
static void
-ebtablesRemoveTmpRootChain(virBufferPtr buf,
- bool incoming, const char *ifname)
-{
- _ebtablesRemoveRootChain(buf, incoming, ifname, true);
-}
-
-
-static void
ebtablesRemoveTmpRootChainFW(virFirewallPtr fw,
bool incoming, const char *ifname)
{
@@ -3004,33 +2600,6 @@ ebtablesRemoveTmpRootChainFW(virFirewallPtr fw,
static void
-_ebtablesUnlinkRootChain(virBufferPtr buf,
- bool incoming, const char *ifname,
- bool isTempChain)
-{
- char chain[MAX_CHAINNAME_LENGTH];
- char iodev = incoming ? 'i' : 'o';
- 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);
-
- virBufferAsprintf(buf,
- "$EBT -t nat -D %s -%c %s -j %s" CMD_SEPARATOR,
- incoming ? EBTABLES_CHAIN_INCOMING
- : EBTABLES_CHAIN_OUTGOING,
- iodev, ifname, chain);
-}
-
-
-static void
_ebtablesUnlinkRootChainFW(virFirewallPtr fw,
bool incoming, const char *ifname,
int isTempChain)
@@ -3064,132 +2633,58 @@ ebtablesUnlinkRootChainFW(virFirewallPtr fw,
}
-static void
-ebtablesUnlinkTmpRootChain(virBufferPtr buf,
- bool incoming, const char *ifname)
-{
- _ebtablesUnlinkRootChain(buf, incoming, ifname, true);
-}
-
-
-static void
-ebtablesUnlinkTmpRootChainFW(virFirewallPtr fw,
- int incoming, const char *ifname)
-{
- _ebtablesUnlinkRootChainFW(fw, incoming, ifname, 1);
-}
-
-
-static int
-ebtablesCreateTmpSubChain(ebiptablesRuleInstPtr *inst,
- int *nRuleInstances,
- bool incoming,
- const char *ifname,
- enum l3_proto_idx protoidx,
- const char *filtername,
- virNWFilterChainPriority priority)
-{
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- ebiptablesRuleInstPtr tmp = *inst;
- size_t count = *nRuleInstances;
- char rootchain[MAX_CHAINNAME_LENGTH], chain[MAX_CHAINNAME_LENGTH];
- char chainPrefix = incoming ? CHAINPREFIX_HOST_IN_TEMP
- : CHAINPREFIX_HOST_OUT_TEMP;
- char *protostr = NULL;
-
- PRINT_ROOT_CHAIN(rootchain, chainPrefix, ifname);
- PRINT_CHAIN(chain, chainPrefix, ifname,
- (filtername) ? filtername : l3_protocols[protoidx].val);
-
- switch (protoidx) {
- case L2_PROTO_MAC_IDX:
- ignore_value(VIR_STRDUP(protostr, ""));
- break;
- case L2_PROTO_STP_IDX:
- ignore_value(VIR_STRDUP(protostr, "-d " NWFILTER_MAC_BGA "
"));
- break;
- default:
- ignore_value(virAsprintf(&protostr, "-p 0x%04x ",
- l3_protocols[protoidx].attr));
- break;
- }
-
- if (!protostr)
- return -1;
-
- virBufferAsprintf(&buf,
- CMD_DEF("$EBT -t nat -F %s") CMD_SEPARATOR
- CMD_EXEC
- CMD_DEF("$EBT -t nat -X %s") CMD_SEPARATOR
- CMD_EXEC
- CMD_DEF("$EBT -t nat -N %s") CMD_SEPARATOR
- CMD_EXEC
- "%s"
- CMD_DEF("$EBT -t nat -A %s %s-j %s")
- CMD_SEPARATOR
- CMD_EXEC
- "%s",
-
- chain,
- chain,
- chain,
-
- CMD_STOPONERR(true),
-
- rootchain, protostr, chain,
-
- CMD_STOPONERR(true));
-
- VIR_FREE(protostr);
-
- if (virBufferError(&buf) ||
- VIR_EXPAND_N(tmp, count, 1) < 0) {
- virReportOOMError();
- virBufferFreeAndReset(&buf);
- return -1;
- }
-
- *nRuleInstances = count;
- *inst = tmp;
-
- tmp[*nRuleInstances - 1].priority = priority;
- tmp[*nRuleInstances - 1].commandTemplate =
- virBufferContentAndReset(&buf);
- tmp[*nRuleInstances - 1].neededProtocolChain =
- virNWFilterChainSuffixTypeToString(VIR_NWFILTER_CHAINSUFFIX_ROOT);
-
- return 0;
+static void
+ebtablesUnlinkTmpRootChainFW(virFirewallPtr fw,
+ int incoming, const char *ifname)
+{
+ _ebtablesUnlinkRootChainFW(fw, incoming, ifname, 1);
}
static void
-_ebtablesRemoveSubChains(virBufferPtr buf,
- const char *ifname,
- const char *chains)
+ebtablesCreateTmpSubChainFW(virFirewallPtr fw,
+ bool incoming,
+ const char *ifname,
+ enum l3_proto_idx protoidx,
+ const char *filtername)
{
- char rootchain[MAX_CHAINNAME_LENGTH];
- size_t i;
+ char rootchain[MAX_CHAINNAME_LENGTH], chain[MAX_CHAINNAME_LENGTH];
+ char chainPrefix = incoming ? CHAINPREFIX_HOST_IN_TEMP
+ : CHAINPREFIX_HOST_OUT_TEMP;
+ virFirewallRulePtr fwrule;
+
+ PRINT_ROOT_CHAIN(rootchain, chainPrefix, ifname);
+ PRINT_CHAIN(chain, chainPrefix, ifname,
+ (filtername) ? filtername : l3_protocols[protoidx].val);
- NWFILTER_SET_EBTABLES_SHELLVAR(buf);
+ virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ true, NULL, NULL,
+ "-t", "nat", "-F", chain,
NULL);
+ virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ true, NULL, NULL,
+ "-t", "nat", "-X", chain,
NULL);
+ virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat", "-N", chain, NULL);
- virBufferAsprintf(buf, NWFILTER_FUNC_COLLECT_CHAINS,
- chains);
- virBufferAdd(buf, NWFILTER_FUNC_RM_CHAINS, -1);
+ fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_ETHERNET,
+ "-t", "nat", "-A",
rootchain, NULL);
- virBufferAsprintf(buf, NWFILTER_FUNC_SET_IFS);
- virBufferAddLit(buf, "chains=\"$(collect_chains");
- for (i = 0; chains[i] != 0; i++) {
- PRINT_ROOT_CHAIN(rootchain, chains[i], ifname);
- virBufferAsprintf(buf, " %s", rootchain);
+ switch (protoidx) {
+ case L2_PROTO_MAC_IDX:
+ break;
+ case L2_PROTO_STP_IDX:
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-d", NWFILTER_MAC_BGA, NULL);
+ break;
+ default:
+ virFirewallRuleAddArg(fw, fwrule, "-p");
+ virFirewallRuleAddArgFormat(fw, fwrule,
+ "0x%04x",
+ l3_protocols[protoidx].attr);
+ break;
}
- virBufferAddLit(buf, ")\"\n");
- for (i = 0; chains[i] != 0; i++) {
- PRINT_ROOT_CHAIN(rootchain, chains[i], ifname);
- virBufferAsprintf(buf,
- "$EBT -t nat -F %s\n",
- rootchain);
- }
- virBufferAddLit(buf, "rm_chains $chains\n");
+ virFirewallRuleAddArgList(fw, fwrule,
+ "-j", chain, NULL);
}
@@ -3257,18 +2752,6 @@ ebtablesRemoveSubChainsFW(virFirewallPtr fw,
_ebtablesRemoveSubChainsFW(fw, ifname, chains);
}
-static void
-ebtablesRemoveTmpSubChains(virBufferPtr buf,
- const char *ifname)
-{
- char chains[3] = {
- CHAINPREFIX_HOST_IN_TEMP,
- CHAINPREFIX_HOST_OUT_TEMP,
- 0
- };
-
- _ebtablesRemoveSubChains(buf, ifname, chains);
-}
static void
ebtablesRemoveTmpSubChainsFW(virFirewallPtr fw,
@@ -3381,15 +2864,6 @@ ebtablesRenameTmpSubAndRootChainsFW(virFirewallPtr fw,
ebtablesRenameTmpRootChainFW(fw, false, ifname);
}
-static void
-ebiptablesInstCommand(virBufferPtr buf,
- const char *cmdstr)
-{
- virBufferAdd(buf, cmdstr, -1);
- virBufferAsprintf(buf, CMD_SEPARATOR "%s",
- CMD_STOPONERR(true));
-}
-
/**
* ebiptablesCanApplyBasicRules
@@ -3691,33 +3165,6 @@ ebtablesCleanAll(const char *ifname)
static int
-ebiptablesRuleOrderSort(const void *a, const void *b)
-{
- const ebiptablesRuleInst *insta = a;
- const ebiptablesRuleInst *instb = b;
- const char *root = virNWFilterChainSuffixTypeToString(
- VIR_NWFILTER_CHAINSUFFIX_ROOT);
- bool root_a = STREQ(insta->neededProtocolChain, root);
- bool root_b = STREQ(instb->neededProtocolChain, root);
-
- /* ensure root chain commands appear before all others since
- we will need them to create the child chains */
- if (root_a) {
- if (root_b) {
- goto normal;
- }
- return -1; /* a before b */
- }
- if (root_b) {
- return 1; /* b before a */
- }
- normal:
- /* priorities are limited to range [-1000, 1000] */
- return insta->priority - instb->priority;
-}
-
-
-static int
virNWFilterRuleInstSort(const void *a, const void *b)
{
const virNWFilterRuleInst *insta = a;
@@ -3752,6 +3199,7 @@ virNWFilterRuleInstSortPtr(const void *a, const void *b)
return virNWFilterRuleInstSort(*insta, *instb);
}
+
static int
ebiptablesFilterOrderSort(const virHashKeyValuePair *a,
const virHashKeyValuePair *b)
@@ -3761,6 +3209,7 @@ ebiptablesFilterOrderSort(const virHashKeyValuePair *a,
*(virNWFilterChainPriority *)b->value;
}
+
static void
iptablesCheckBridgeNFCallEnabled(bool isIPv6)
{
@@ -3817,54 +3266,13 @@ ebtablesGetProtoIdxByFiltername(const char *filtername)
return -1;
}
-static int
-ebtablesCreateTmpRootAndSubChains(virBufferPtr buf,
- const char *ifname,
- virHashTablePtr chains,
- bool incoming,
- ebiptablesRuleInstPtr *inst,
- int *nRuleInstances)
-{
- int rc = 0;
- size_t i;
- virHashKeyValuePairPtr filter_names;
- const virNWFilterChainPriority *priority;
-
- ebtablesCreateTmpRootChain(buf, incoming, ifname);
-
- filter_names = virHashGetItems(chains,
- ebiptablesFilterOrderSort);
- if (filter_names == NULL)
- return -1;
-
- for (i = 0; filter_names[i].key; i++) {
- enum l3_proto_idx idx = ebtablesGetProtoIdxByFiltername(
- filter_names[i].key);
- if ((int)idx < 0)
- continue;
- priority = (const virNWFilterChainPriority *)filter_names[i].value;
- rc = ebtablesCreateTmpSubChain(inst, nRuleInstances,
- incoming, ifname, idx,
- filter_names[i].key,
- *priority);
- if (rc < 0)
- break;
- }
-
- VIR_FREE(filter_names);
- return rc;
-}
-
static int
-iptablesRuleInstCommand(virBufferPtr buf,
+iptablesRuleInstCommand(virFirewallPtr fw,
const char *ifname,
virNWFilterRuleInstPtr rule)
{
virNWFilterVarCombIterPtr vciter, tmp;
- char **cmds = NULL;
- size_t ncmds = 0;
- size_t i;
int ret = -1;
/* rule->vars holds all the variables names that this rule will access.
@@ -3878,38 +3286,28 @@ iptablesRuleInstCommand(virBufferPtr buf,
return -1;
do {
- if (ebiptablesCreateRuleInstance(rule->chainSuffix,
+ if (ebiptablesCreateRuleInstance(fw,
+ rule->chainSuffix,
rule->def,
ifname,
- tmp,
- &cmds,
- &ncmds) < 0)
+ tmp) < 0)
goto cleanup;
tmp = virNWFilterVarCombIterNext(tmp);
} while (tmp != NULL);
- for (i = 0; i < ncmds; i++)
- iptablesInstCommand(buf, cmds[i]);
-
ret = 0;
cleanup:
- for (i = 0; i < ncmds; i++)
- VIR_FREE(cmds[i]);
- VIR_FREE(cmds);
virNWFilterVarCombIterFree(vciter);
return ret;
}
static int
-ebtablesRuleInstCommand(virBufferPtr buf,
+ebtablesRuleInstCommand(virFirewallPtr fw,
const char *ifname,
virNWFilterRuleInstPtr rule)
{
virNWFilterVarCombIterPtr vciter, tmp;
- char **cmds = NULL;
- size_t ncmds = 0;
- size_t i;
int ret = -1;
/* rule->vars holds all the variables names that this rule will access.
@@ -3923,28 +3321,90 @@ ebtablesRuleInstCommand(virBufferPtr buf,
return -1;
do {
- if (ebiptablesCreateRuleInstance(rule->chainSuffix,
+ if (ebiptablesCreateRuleInstance(fw,
+ rule->chainSuffix,
rule->def,
ifname,
- tmp,
- &cmds,
- &ncmds) < 0)
+ tmp) < 0)
goto cleanup;
tmp = virNWFilterVarCombIterNext(tmp);
} while (tmp != NULL);
- for (i = 0; i < ncmds; i++)
- ebiptablesInstCommand(buf, cmds[i]);
-
ret = 0;
cleanup:
- for (i = 0; i < ncmds; i++)
- VIR_FREE(cmds[i]);
- VIR_FREE(cmds);
virNWFilterVarCombIterFree(vciter);
return ret;
}
+struct ebtablesSubChainInst {
+ virNWFilterChainPriority priority;
+ bool incoming;
+ enum l3_proto_idx protoidx;
+ const char *filtername;
+};
+
+
+static int
+ebtablesSubChainInstSort(const void *a, const void *b)
+{
+ const struct ebtablesSubChainInst **insta = (const struct ebtablesSubChainInst **)a;
+ const struct ebtablesSubChainInst **instb = (const struct ebtablesSubChainInst **)b;
+
+ /* priorities are limited to range [-1000, 1000] */
+ return (*insta)->priority - (*instb)->priority;
+}
+
+
+static int
+ebtablesGetSubChainInsts(virHashTablePtr chains,
+ bool incoming,
+ struct ebtablesSubChainInst ***insts,
+ size_t *ninsts)
+{
+ virHashKeyValuePairPtr filter_names;
+ size_t i;
+ int ret = -1;
+
+ filter_names = virHashGetItems(chains,
+ ebiptablesFilterOrderSort);
+ if (filter_names == NULL)
+ return -1;
+
+ for (i = 0; filter_names[i].key; i++) {
+ struct ebtablesSubChainInst *inst;
+ enum l3_proto_idx idx = ebtablesGetProtoIdxByFiltername(
+ filter_names[i].key);
+
+ if ((int)idx < 0)
+ continue;
+
+ if (VIR_ALLOC(inst) < 0)
+ goto cleanup;
+ inst->priority = *(const virNWFilterChainPriority *)filter_names[i].value;
+ inst->incoming = incoming;
+ inst->protoidx = idx;
+ inst->filtername = filter_names[i].key;
+
+ if (VIR_APPEND_ELEMENT(*insts, *ninsts, inst) < 0) {
+ VIR_FREE(inst);
+ goto cleanup;
+ }
+ }
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(filter_names);
+ if (ret < 0) {
+ for (i = 0; i < *ninsts; i++) {
+ VIR_FREE(*insts[i]);
+ }
+ VIR_FREE(*insts);
+ *ninsts = 0;
+ }
+ return ret;
+
+}
static int
ebiptablesApplyNewRules(const char *ifname,
@@ -3952,74 +3412,33 @@ ebiptablesApplyNewRules(const char *ifname,
size_t nrules)
{
size_t i, j;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
+ virFirewallPtr fw = virFirewallNew();
virHashTablePtr chains_in_set = virHashCreate(10, NULL);
virHashTablePtr chains_out_set = virHashCreate(10, NULL);
+ bool haveEbtables = false;
bool haveIptables = false;
bool haveIp6tables = false;
- ebiptablesRuleInstPtr ebtChains = NULL;
- int nEbtChains = 0;
char *errmsg = NULL;
+ struct ebtablesSubChainInst **subchains = NULL;
+ size_t nsubchains = 0;
+ int ret = -1;
if (!chains_in_set || !chains_out_set)
- goto exit_free_sets;
+ goto cleanup;
if (nrules)
qsort(rules, nrules, sizeof(rules[0]),
virNWFilterRuleInstSortPtr);
- /* scan the rules to see which chains need to be created */
- for (i = 0; i < nrules; i++) {
- if (virNWFilterRuleIsProtocolEthernet(rules[i]->def)) {
- const char *name = rules[i]->chainSuffix;
- if (rules[i]->def->tt == VIR_NWFILTER_RULE_DIRECTION_OUT ||
- rules[i]->def->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT) {
- if (virHashUpdateEntry(chains_in_set, name,
- &rules[i]->chainPriority) < 0)
- goto exit_free_sets;
- }
- if (rules[i]->def->tt == VIR_NWFILTER_RULE_DIRECTION_IN ||
- rules[i]->def->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT) {
- if (virHashUpdateEntry(chains_out_set, name,
- &rules[i]->chainPriority) < 0)
- goto exit_free_sets;
- }
- }
- }
-
-
/* cleanup whatever may exist */
- if (ebtables_cmd_path) {
- NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
-
- ebtablesUnlinkTmpRootChain(&buf, true, ifname);
- ebtablesUnlinkTmpRootChain(&buf, false, ifname);
- ebtablesRemoveTmpSubChains(&buf, ifname);
- ebtablesRemoveTmpRootChain(&buf, true, ifname);
- ebtablesRemoveTmpRootChain(&buf, false, ifname);
- ebiptablesExecCLI(&buf, true, NULL);
- }
-
- NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
-
- /* create needed chains */
- if ((virHashSize(chains_in_set) > 0 &&
- ebtablesCreateTmpRootAndSubChains(&buf, ifname, chains_in_set, true,
- &ebtChains, &nEbtChains) < 0) ||
- (virHashSize(chains_out_set) > 0 &&
- ebtablesCreateTmpRootAndSubChains(&buf, ifname, chains_out_set, false,
- &ebtChains, &nEbtChains) < 0)) {
- goto tear_down_tmpebchains;
- }
-
- if (nEbtChains > 0)
- qsort(&ebtChains[0], nEbtChains, sizeof(ebtChains[0]),
- ebiptablesRuleOrderSort);
-
- if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
- goto tear_down_tmpebchains;
+ virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
+ ebtablesUnlinkTmpRootChainFW(fw, true, ifname);
+ ebtablesUnlinkTmpRootChainFW(fw, false, ifname);
+ ebtablesRemoveTmpSubChainsFW(fw, ifname);
+ ebtablesRemoveTmpRootChainFW(fw, true, ifname);
+ ebtablesRemoveTmpRootChainFW(fw, false, ifname);
- NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+ virFirewallStartTransaction(fw, 0);
/* walk the list of rules and increase the priority
* of rules in case the chain priority is of higher value;
@@ -4038,188 +3457,173 @@ ebiptablesApplyNewRules(const char *ifname,
}
}
- /* process ebtables commands; interleave commands from filters with
- commands for creating and connecting ebtables chains */
- j = 0;
for (i = 0; i < nrules; i++) {
if (virNWFilterRuleIsProtocolEthernet(rules[i]->def)) {
- while (j < nEbtChains &&
- ebtChains[j].priority <= rules[i]->priority) {
- ebiptablesInstCommand(&buf,
- ebtChains[j++].commandTemplate);
- }
- ebtablesRuleInstCommand(&buf,
- ifname,
- rules[i]);
+ haveEbtables = true;
} else {
if (virNWFilterRuleIsProtocolIPv4(rules[i]->def))
haveIptables = true;
- else if (virNWFilterRuleIsProtocolIPv4(rules[i]->def))
+ else if (virNWFilterRuleIsProtocolIPv6(rules[i]->def))
haveIp6tables = true;
}
}
+ /* process ebtables commands; interleave commands from filters with
+ commands for creating and connecting ebtables chains */
+ if (haveEbtables) {
- while (j < nEbtChains)
- ebiptablesInstCommand(&buf,
- ebtChains[j++].commandTemplate);
+ /* scan the rules to see which chains need to be created */
+ for (i = 0; i < nrules; i++) {
+ if (virNWFilterRuleIsProtocolEthernet(rules[i]->def)) {
+ const char *name = rules[i]->chainSuffix;
+ if (rules[i]->def->tt == VIR_NWFILTER_RULE_DIRECTION_OUT ||
+ rules[i]->def->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT) {
+ if (virHashUpdateEntry(chains_in_set, name,
+ &rules[i]->chainPriority) < 0)
+ goto cleanup;
+ }
+ if (rules[i]->def->tt == VIR_NWFILTER_RULE_DIRECTION_IN ||
+ rules[i]->def->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT) {
+ if (virHashUpdateEntry(chains_out_set, name,
+ &rules[i]->chainPriority) < 0)
+ goto cleanup;
+ }
+ }
+ }
- if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
- goto tear_down_tmpebchains;
+ /* create needed chains */
+ if (virHashSize(chains_in_set) > 0) {
+ ebtablesCreateTmpRootChainFW(fw, true, ifname);
+ if (ebtablesGetSubChainInsts(chains_in_set,
+ true,
+ &subchains,
+ &nsubchains) < 0)
+ goto cleanup;
+ }
+ if (virHashSize(chains_out_set) > 0) {
+ ebtablesCreateTmpRootChainFW(fw, false, ifname);
+ if (ebtablesGetSubChainInsts(chains_out_set,
+ false,
+ &subchains,
+ &nsubchains) < 0)
+ goto cleanup;
+ }
+
+ if (nsubchains > 0)
+ qsort(subchains, nsubchains, sizeof(subchains[0]),
+ ebtablesSubChainInstSort);
+
+ for (i = 0, j = 0; i < nrules; i++) {
+ if (virNWFilterRuleIsProtocolEthernet(rules[i]->def)) {
+ while (j < nsubchains &&
+ subchains[j]->priority <= rules[i]->priority) {
+ ebtablesCreateTmpSubChainFW(fw,
+ subchains[j]->incoming,
+ ifname,
+ subchains[j]->protoidx,
+ subchains[j]->filtername);
+ j++;
+ }
+ if (ebtablesRuleInstCommand(fw,
+ ifname,
+ rules[i]) < 0)
+ goto cleanup;
+ }
+ }
+ while (j < nsubchains) {
+ ebtablesCreateTmpSubChainFW(fw,
+ subchains[j]->incoming,
+ ifname,
+ subchains[j]->protoidx,
+ subchains[j]->filtername);
+ j++;
+ }
+ }
if (haveIptables) {
- NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
-
- iptablesUnlinkTmpRootChains(&buf, ifname);
- iptablesRemoveTmpRootChains(&buf, ifname);
-
- iptablesCreateBaseChains(&buf);
-
- if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
- goto tear_down_tmpebchains;
-
- NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
+ iptablesUnlinkTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname);
+ iptablesRemoveTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname);
- iptablesCreateTmpRootChains(&buf, ifname);
+ iptablesCreateBaseChainsFW(fw, VIR_FIREWALL_LAYER_IPV4);
+ iptablesCreateTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname);
- if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
- goto tear_down_tmpiptchains;
-
- NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
-
- iptablesLinkTmpRootChains(&buf, ifname);
- iptablesSetupVirtInPost(&buf, ifname);
- if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
- goto tear_down_tmpiptchains;
-
- NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
+ iptablesLinkTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname);
+ iptablesSetupVirtInPostFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname);
for (i = 0; i < nrules; i++) {
- if (virNWFilterRuleIsProtocolIPv4(rules[i]->def))
- iptablesRuleInstCommand(&buf,
- ifname,
- rules[i]);
+ if (virNWFilterRuleIsProtocolIPv4(rules[i]->def)) {
+ if (iptablesRuleInstCommand(fw,
+ ifname,
+ rules[i]) < 0)
+ goto cleanup;
+ }
}
- if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
- goto tear_down_tmpiptchains;
-
iptablesCheckBridgeNFCallEnabled(false);
}
if (haveIp6tables) {
- NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
-
- iptablesUnlinkTmpRootChains(&buf, ifname);
- iptablesRemoveTmpRootChains(&buf, ifname);
-
- iptablesCreateBaseChains(&buf);
-
- if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
- goto tear_down_tmpiptchains;
-
- NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
-
- iptablesCreateTmpRootChains(&buf, ifname);
+ iptablesUnlinkTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname);
+ iptablesRemoveTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname);
- if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
- goto tear_down_tmpip6tchains;
+ iptablesCreateBaseChainsFW(fw, VIR_FIREWALL_LAYER_IPV6);
+ iptablesCreateTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname);
- NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
-
- iptablesLinkTmpRootChains(&buf, ifname);
- iptablesSetupVirtInPost(&buf, ifname);
- if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
- goto tear_down_tmpip6tchains;
-
- NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
+ iptablesLinkTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname);
+ iptablesSetupVirtInPostFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname);
for (i = 0; i < nrules; i++) {
- if (virNWFilterRuleIsProtocolIPv6(rules[i]->def))
- iptablesRuleInstCommand(&buf,
- ifname,
- rules[i]);
+ if (virNWFilterRuleIsProtocolIPv6(rules[i]->def)) {
+ if (iptablesRuleInstCommand(fw,
+ ifname,
+ rules[i]) < 0)
+ goto cleanup;
+ }
}
- if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
- goto tear_down_tmpip6tchains;
-
iptablesCheckBridgeNFCallEnabled(true);
}
- NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
-
if (virHashSize(chains_in_set) != 0)
- ebtablesLinkTmpRootChain(&buf, true, ifname);
+ ebtablesLinkTmpRootChainFW(fw, true, ifname);
if (virHashSize(chains_out_set) != 0)
- ebtablesLinkTmpRootChain(&buf, false, ifname);
-
- if (ebiptablesExecCLI(&buf, false, &errmsg) < 0)
- goto tear_down_ebsubchains_and_unlink;
-
- virHashFree(chains_in_set);
- virHashFree(chains_out_set);
-
- for (i = 0; i < nEbtChains; i++)
- VIR_FREE(ebtChains[i].commandTemplate);
- VIR_FREE(ebtChains);
-
- VIR_FREE(errmsg);
-
- return 0;
-
- tear_down_ebsubchains_and_unlink:
- if (ebtables_cmd_path) {
- NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+ ebtablesLinkTmpRootChainFW(fw, false, ifname);
- ebtablesUnlinkTmpRootChain(&buf, true, ifname);
- ebtablesUnlinkTmpRootChain(&buf, false, ifname);
- }
-
- tear_down_tmpip6tchains:
+ virFirewallStartRollback(fw, 0);
+ ebtablesUnlinkTmpRootChainFW(fw, true, ifname);
+ ebtablesUnlinkTmpRootChainFW(fw, false, ifname);
if (haveIp6tables) {
- NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
-
- iptablesUnlinkTmpRootChains(&buf, ifname);
- iptablesRemoveTmpRootChains(&buf, ifname);
+ iptablesUnlinkTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname);
+ iptablesRemoveTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname);
}
- tear_down_tmpiptchains:
if (haveIptables) {
- NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
-
- iptablesUnlinkTmpRootChains(&buf, ifname);
- iptablesRemoveTmpRootChains(&buf, ifname);
+ iptablesUnlinkTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname);
+ iptablesRemoveTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname);
}
- tear_down_tmpebchains:
- if (ebtables_cmd_path) {
- NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+ ebtablesRemoveTmpSubChainsFW(fw, ifname);
+ ebtablesRemoveTmpRootChainFW(fw, true, ifname);
+ ebtablesRemoveTmpRootChainFW(fw, false, ifname);
- ebtablesRemoveTmpSubChains(&buf, ifname);
- ebtablesRemoveTmpRootChain(&buf, true, ifname);
- ebtablesRemoveTmpRootChain(&buf, false, ifname);
+ virMutexLock(&execCLIMutex);
+ if (virFirewallApply(fw) < 0) {
+ virMutexUnlock(&execCLIMutex);
+ goto cleanup;
}
+ virMutexUnlock(&execCLIMutex);
- ebiptablesExecCLI(&buf, true, NULL);
-
- virReportError(VIR_ERR_BUILD_FIREWALL,
- _("Some rules could not be created for "
- "interface %s%s%s"),
- ifname,
- errmsg ? ": " : "",
- errmsg ? errmsg : "");
+ ret = 0;
- exit_free_sets:
+ cleanup:
+ for (i = 0; i < nsubchains; i++)
+ VIR_FREE(subchains[i]);
+ VIR_FREE(subchains);
+ virFirewallFree(fw);
virHashFree(chains_in_set);
virHashFree(chains_out_set);
- for (i = 0; i < nEbtChains; i++)
- VIR_FREE(ebtChains[i].commandTemplate);
- VIR_FREE(ebtChains);
-
VIR_FREE(errmsg);
-
- return -1;
+ return ret;
}
@@ -4544,10 +3948,8 @@ ebiptablesDriverProbeStateMatch(void)
* since version 1.4.16 '-m state --state ...' will be converted to
* '-m conntrack --ctstate ...'
*/
- if (thisversion >= 1 * 1000000 + 4 * 1000 + 16) {
- m_state_out_str = m_state_out_str_new;
- m_state_in_str = m_state_in_str_new;
- }
+ if (thisversion >= 1 * 1000000 + 4 * 1000 + 16)
+ newMatchState = true;
cleanup:
VIR_FREE(cmdout);
diff --git a/src/nwfilter/nwfilter_ebiptables_driver.h
b/src/nwfilter/nwfilter_ebiptables_driver.h
index 8a17452..098d5dd 100644
--- a/src/nwfilter/nwfilter_ebiptables_driver.h
+++ b/src/nwfilter/nwfilter_ebiptables_driver.h
@@ -27,23 +27,6 @@
# define MAX_CHAINNAME_LENGTH 32 /* see linux/netfilter_bridge/ebtables.h */
-enum RuleType {
- RT_EBTABLES,
- RT_IPTABLES,
- RT_IP6TABLES,
-};
-
-typedef struct _ebiptablesRuleInst ebiptablesRuleInst;
-typedef ebiptablesRuleInst *ebiptablesRuleInstPtr;
-struct _ebiptablesRuleInst {
- char *commandTemplate;
- const char *neededProtocolChain;
- virNWFilterChainPriority chainPriority;
- char chainprefix; /* I for incoming, O for outgoing */
- virNWFilterRulePriority priority;
- enum RuleType ruleType;
-};
-
extern virNWFilterTechDriver ebiptables_driver;
# define EBIPTABLES_DRIVER_ID "ebiptables"
--
1.9.0