/*
* _iptablesCreateRuleInstance:
* @chainPrefix : The prefix to put in front of the name of the chain
- * @nwfilter : The filter
* @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
- * @res : The data structure to store the result(s) into
* @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
*
static int
_iptablesCreateRuleInstance(bool directionIn,
const char *chainPrefix,
- virNWFilterDefPtr nwfilter,
virNWFilterRuleDefPtr rule,
const char *ifname,
virNWFilterVarCombIterPtr vars,
- virNWFilterRuleInstPtr res,
const char *match, bool defMatch,
const char *accept_target,
bool isIPv6,
- bool maySkipICMP)
+ bool maySkipICMP,
+ char ***templates,
+ size_t *ntemplates)
{
char chain[MAX_CHAINNAME_LENGTH];
char number[MAX(INT_BUFSIZE_BOUND(uint32_t),
bool skipRule = false;
bool skipMatch = false;
bool hasICMPType = false;
+ char *template;
if (!iptables_cmd) {
virReportError(VIR_ERR_INTERNAL_ERROR,
final = &buf;
- return ebiptablesAddRuleInst(res,
- virBufferContentAndReset(final),
- nwfilter->chainsuffix,
- nwfilter->chainPriority,
- '\0',
- rule->priority,
- (isIPv6) ? RT_IP6TABLES : RT_IPTABLES);
+ template = virBufferContentAndReset(final);
+ if (VIR_APPEND_ELEMENT(*templates, *ntemplates, template) < 0) {
+ VIR_FREE(template);
+ return -1;
+ }
+ return 0;
err_exit:
virBufferFreeAndReset(&buf);
}
static int
-iptablesCreateRuleInstanceStateCtrl(virNWFilterDefPtr nwfilter,
- virNWFilterRuleDefPtr rule,
+iptablesCreateRuleInstanceStateCtrl(virNWFilterRuleDefPtr rule,
const char *ifname,
virNWFilterVarCombIterPtr vars,
- virNWFilterRuleInstPtr res,
- bool isIPv6)
+ bool isIPv6,
+ char ***templates,
+ size_t *ntemplates)
{
int rc;
bool directionIn = false;
if (create) {
rc = _iptablesCreateRuleInstance(directionIn,
chainPrefix,
- nwfilter,
rule,
ifname,
vars,
- res,
matchState, false,
"RETURN",
isIPv6,
- maySkipICMP);
+ maySkipICMP,
+ templates,
+ ntemplates);
VIR_FREE(matchState);
if (rc < 0)
if (create) {
rc = _iptablesCreateRuleInstance(!directionIn,
chainPrefix,
- nwfilter,
rule,
ifname,
vars,
- res,
matchState, false,
"ACCEPT",
isIPv6,
- maySkipICMP);
+ maySkipICMP,
+ templates,
+ ntemplates);
VIR_FREE(matchState);
chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP;
rc = _iptablesCreateRuleInstance(directionIn,
chainPrefix,
- nwfilter,
rule,
ifname,
vars,
- res,
matchState, false,
"RETURN",
isIPv6,
- maySkipICMP);
+ maySkipICMP,
+ templates,
+ ntemplates);
VIR_FREE(matchState);
}
static int
-iptablesCreateRuleInstance(virNWFilterDefPtr nwfilter,
- virNWFilterRuleDefPtr rule,
+iptablesCreateRuleInstance(virNWFilterRuleDefPtr rule,
const char *ifname,
virNWFilterVarCombIterPtr vars,
- virNWFilterRuleInstPtr res,
- bool isIPv6)
+ bool isIPv6,
+ char ***templates,
+ size_t *ntemplates)
{
int rc;
bool directionIn = false;
if (!(rule->flags & RULE_FLAG_NO_STATEMATCH) &&
(rule->flags & IPTABLES_STATE_FLAGS)) {
- return iptablesCreateRuleInstanceStateCtrl(nwfilter,
- rule,
+ return iptablesCreateRuleInstanceStateCtrl(rule,
ifname,
vars,
- res,
- isIPv6);
+ isIPv6,
+ templates,
+ ntemplates);
}
if ((rule->tt == VIR_NWFILTER_RULE_DIRECTION_IN) ||
chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP;
rc = _iptablesCreateRuleInstance(directionIn,
chainPrefix,
- nwfilter,
rule,
ifname,
vars,
- res,
matchState, true,
"RETURN",
isIPv6,
- maySkipICMP);
+ maySkipICMP,
+ templates,
+ ntemplates);
if (rc < 0)
return rc;
chainPrefix[1] = CHAINPREFIX_HOST_OUT_TEMP;
rc = _iptablesCreateRuleInstance(!directionIn,
chainPrefix,
- nwfilter,
rule,
ifname,
vars,
- res,
matchState, true,
"ACCEPT",
isIPv6,
- maySkipICMP);
+ maySkipICMP,
+ templates,
+ ntemplates);
if (rc < 0)
return rc;
chainPrefix[1] = CHAINPREFIX_HOST_IN_TEMP;
rc = _iptablesCreateRuleInstance(directionIn,
chainPrefix,
- nwfilter,
rule,
ifname,
vars,
- res,
matchState, true,
"RETURN",
isIPv6,
- maySkipICMP);
+ maySkipICMP,
+ templates,
+ ntemplates);
return rc;
}
/*
* ebtablesCreateRuleInstance:
* @chainPrefix : The prefix to put in front of the name of the chain
- * @nwfilter : The filter
+ * @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
- * @res : The data structure to store the result(s) into
* @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
*
*/
static int
ebtablesCreateRuleInstance(char chainPrefix,
- virNWFilterDefPtr nwfilter,
+ const char *chainSuffix,
virNWFilterRuleDefPtr rule,
const char *ifname,
virNWFilterVarCombIterPtr vars,
- virNWFilterRuleInstPtr res,
- bool reverse)
+ bool reverse,
+ char **template)
{
char macaddr[VIR_MAC_STRING_BUFLEN],
ipaddr[INET_ADDRSTRLEN],
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 "
goto err_exit;
}
- if (STREQ(nwfilter->chainsuffix,
+ if (STREQ(chainSuffix,
virNWFilterChainSuffixTypeToString(
VIR_NWFILTER_CHAINSUFFIX_ROOT)))
PRINT_ROOT_CHAIN(chain, chainPrefix, ifname);
else
PRINT_CHAIN(chain, chainPrefix, ifname,
- nwfilter->chainsuffix);
+ chainSuffix);
switch (rule->prtclType) {
return -1;
}
- return ebiptablesAddRuleInst(res,
- virBufferContentAndReset(&buf),
- nwfilter->chainsuffix,
- nwfilter->chainPriority,
- chainPrefix,
- rule->priority,
- RT_EBTABLES);
+ *template = virBufferContentAndReset(&buf);
+ return 0;
err_exit:
virBufferFreeAndReset(&buf);
/*
* ebiptablesCreateRuleInstance:
- * @nwfilter : The filter
+ * @chainPriority : The priority 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
* pointed to by res, -1 otherwise
*/
static int
-ebiptablesCreateRuleInstance(virNWFilterDefPtr nwfilter,
+ebiptablesCreateRuleInstance(virNWFilterChainPriority chainPriority,
+ const char *chainSuffix,
virNWFilterRuleDefPtr rule,
const char *ifname,
virNWFilterVarCombIterPtr vars,
virNWFilterRuleInstPtr res)
{
- int rc = 0;
-
if (virNWFilterRuleIsProtocolEthernet(rule)) {
if (rule->tt == VIR_NWFILTER_RULE_DIRECTION_OUT ||
rule->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT) {
- rc = ebtablesCreateRuleInstance(CHAINPREFIX_HOST_IN_TEMP,
- nwfilter,
- rule,
- ifname,
- vars,
- res,
- rule->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT);
- if (rc < 0)
- return rc;
+ char *template;
+ if (ebtablesCreateRuleInstance(CHAINPREFIX_HOST_IN_TEMP,
+ chainSuffix,
+ rule,
+ ifname,
+ vars,
+ rule->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT,
+ &template) < 0)
+ return -1;
+
+ if (ebiptablesAddRuleInst(res,
+ template,
+ chainSuffix,
+ chainPriority,
+ CHAINPREFIX_HOST_IN_TEMP,
+ rule->priority,
+ RT_EBTABLES) < 0) {
+ VIR_FREE(template);
+ return -1;
+ }
}
if (rule->tt == VIR_NWFILTER_RULE_DIRECTION_IN ||
rule->tt == VIR_NWFILTER_RULE_DIRECTION_INOUT) {
- rc = ebtablesCreateRuleInstance(CHAINPREFIX_HOST_OUT_TEMP,
- nwfilter,
- rule,
- ifname,
- vars,
- res,
- false);
+ char *template;
+ if (ebtablesCreateRuleInstance(CHAINPREFIX_HOST_OUT_TEMP,
+ chainSuffix,
+ rule,
+ ifname,
+ vars,
+ false,
+ &template) < 0)
+ return -1;
+
+ if (ebiptablesAddRuleInst(res,
+ template,
+ chainSuffix,
+ chainPriority,
+ CHAINPREFIX_HOST_OUT_TEMP,
+ rule->priority,
+ RT_EBTABLES) < 0) {
+ VIR_FREE(template);
+ return -1;
+ }
}
} else {
bool isIPv6;
+ char **templates = NULL;
+ size_t ntemplates = 0;
+ size_t i, j;
if (virNWFilterRuleIsProtocolIPv6(rule)) {
isIPv6 = true;
} else if (virNWFilterRuleIsProtocolIPv4(rule)) {
return -1;
}
- rc = iptablesCreateRuleInstance(nwfilter,
- rule,
- ifname,
- vars,
- res,
- isIPv6);
+ if (iptablesCreateRuleInstance(rule,
+ ifname,
+ vars,
+ isIPv6,
+ &templates,
+ &ntemplates) < 0)
+ return -1;
+
+ for (i = 0; i < ntemplates; i++) {
+ if (ebiptablesAddRuleInst(res,
+ templates[i],
+ chainSuffix,
+ chainPriority,
+ '\0',
+ rule->priority,
+ (isIPv6) ? RT_IP6TABLES : RT_IPTABLES) < 0) {
+ for (j = i; j < ntemplates; j++)
+ VIR_FREE(templates[j]);
+ return -1;
+ }
+ }
}
- return rc;
+ return 0;
}
static int
return -1;
do {
- rc = ebiptablesCreateRuleInstance(nwfilter,
+ rc = ebiptablesCreateRuleInstance(nwfilter->chainPriority,
+ nwfilter->chainsuffix,
rule,
ifname,
tmp,