This patch adds the capability of adding individual rules to existing chains.
Signed-off-by: David L Stevens <dlstevens(a)us.ibm.com>
diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index 25f7b60..4b6759a 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -532,6 +532,11 @@ typedef int (*virNWFilterRuleTeardownNewRules)(virConnectPtr conn,
typedef int (*virNWFilterRuleTeardownOldRules)(virConnectPtr conn,
const char *ifname);
+typedef int (*virNWFilterRuleAddRules)(virConnectPtr conn,
+ const char *ifname,
+ int nruleInstances,
+ void **_inst);
+
typedef int (*virNWFilterRuleRemoveRules)(virConnectPtr conn,
const char *ifname,
int nruleInstances,
@@ -572,6 +577,7 @@ struct _virNWFilterTechDriver {
virNWFilterRuleApplyNewRules applyNewRules;
virNWFilterRuleTeardownNewRules tearNewRules;
virNWFilterRuleTeardownOldRules tearOldRules;
+ virNWFilterRuleAddRules addRules;
virNWFilterRuleRemoveRules removeRules;
virNWFilterRuleAllTeardown allTeardown;
virNWFilterRuleFreeInstanceData freeRuleInstance;
diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c
b/src/nwfilter/nwfilter_ebiptables_driver.c
index f74f63b..0cb4d00 100644
--- a/src/nwfilter/nwfilter_ebiptables_driver.c
+++ b/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -3686,6 +3686,78 @@ err_exit:
return rc;
}
+/**
+ * ebiptablesAddRules:
+ * @conn : pointer to virConnect object
+ * @ifname : the name of the interface to which the rules apply
+ * @nRuleInstance : the number of given rules
+ * @_inst : array of rule instantiation data
+ *
+ * Add all rules one after the other
+ *
+ * Return 0 on success, 1 if execution of one or more cleanup
+ * commands failed.
+ */
+static int
+ebiptablesAddRules(virConnectPtr conn,
+ const char *ifname,
+ int nruleInstances,
+ void **_inst)
+{
+ int i;
+ int cli_status;
+ ebiptablesRuleInstPtr *inst = (ebiptablesRuleInstPtr *)_inst;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool haveIptables = false;
+ bool haveIp6tables = false;
+
+ for (i = 0; i < nruleInstances; i++) {
+ sa_assert (inst);
+ switch (inst[i]->ruleType) {
+ case RT_EBTABLES:
+ ebiptablesInstCommand(&buf,
+ inst[i]->commandTemplate,
+ 'A', -1, 1);
+ break;
+ case RT_IPTABLES:
+ if (inst[i]->ruleType == RT_IPTABLES)
+ iptablesInstCommand(&buf,
+ inst[i]->commandTemplate,
+ 'A', -1, 1);
+ haveIptables = true;
+ break;
+ case RT_IP6TABLES:
+ if (inst[i]->ruleType == RT_IP6TABLES)
+ iptablesInstCommand(&buf,
+ inst[i]->commandTemplate,
+ 'A', -1, 1);
+ haveIp6tables = true;
+ break;
+ }
+ }
+
+ if (ebiptablesExecCLI(&buf, &cli_status) || cli_status != 0)
+ goto err_exit;
+
+ if (haveIptables)
+ iptablesCheckBridgeNFCallEnabled(false);
+
+ if (haveIp6tables)
+ iptablesCheckBridgeNFCallEnabled(true);
+
+ return 0;
+
+err_exit:
+ (void) ebiptablesRemoveRules(conn, ifname, nruleInstances, _inst);
+
+ virNWFilterReportError(VIR_ERR_BUILD_FIREWALL,
+ _("Some rules could not be created for "
+ "interface %s."),
+ ifname);
+
+ return 1;
+}
+
/**
* ebiptablesAllTeardown:
@@ -3742,6 +3814,7 @@ virNWFilterTechDriver ebiptables_driver = {
.tearNewRules = ebiptablesTearNewRules,
.tearOldRules = ebiptablesTearOldRules,
.allTeardown = ebiptablesAllTeardown,
+ .addRules = ebiptablesAddRules,
.removeRules = ebiptablesRemoveRules,
.freeRuleInstance = ebiptablesFreeRuleInstance,
.displayRuleInstance = ebiptablesDisplayRuleInstance,