[libvirt] [PATCH V1 2/4] Create rules for each member of a list
Stefan Berger
stefanb at linux.vnet.ibm.com
Sat Oct 22 21:48:10 UTC 2011
I rewrote some parts of this patch here. Will send out a V2.
Stefan
On 10/21/2011 03:31 PM, Stefan Berger wrote:
> This patch extends the NWFilter driver for Linux (ebiptables) to create
> rules for each member of a previously introduced list. If for example
> an attribute value looks like this:
>
> IP = [10.0.0.1, 10.0.0.2, 10.0.0.3]
>
> then 3 rules will be generated for a rule accessing the variable 'IP',
> one for each member of the list. The effect of this is that this now
> allows for filtering for multiple values in one field. This can then be
> used to support for filtering/allowing of multiple IP addresses per
> interface.
>
> An interator is introduced that extracts each member of a list and
> puts it into a hash table which then is passed to the function creating
> a rule. For the above example the iterator would cause 3 loops.
>
> Signed-off-by: Stefan Berger<stefanb at linux.vnet.ibm.com>
>
> ---
> src/conf/nwfilter_params.c | 146 ++++++++++++++++++++++++++++++
> src/conf/nwfilter_params.h | 25 +++++
> src/libvirt_private.syms | 4
> src/nwfilter/nwfilter_ebiptables_driver.c | 44 ++++++++-
> 4 files changed, 218 insertions(+), 1 deletion(-)
>
> Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
> ===================================================================
> --- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.c
> +++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
> @@ -2513,6 +2513,48 @@ ebiptablesCreateRuleInstance(virConnectP
> return rc;
> }
>
> +static int
> +ebiptablesCreateRuleInstanceCombinations(
> + virConnectPtr conn ATTRIBUTE_UNUSED,
> + enum virDomainNetType nettype ATTRIBUTE_UNUSED,
> + virNWFilterDefPtr nwfilter,
> + virNWFilterRuleDefPtr rule,
> + const char *ifname,
> + virNWFilterHashTablePtr vars,
> + virNWFilterRuleInstPtr res)
> +{
> + int rc = 0;
> + virNWFilterVarCombIterPtr iter;
> + virNWFilterHashTablePtr itervars;
> +
> + /* rule->vars holds all the variables names that this rule will access.
> + * iterate over all combinations of the variables' values and instantiate
> + * the filtering rule with each combination.
> + */
> + iter = virNWFilterVarCombIterCreate(vars, rule->vars, rule->nvars);
> + if (!iter) {
> + return 1;
> + }
> +
> + itervars = virNWFilterVarCombIterFirst(iter);
> +
> + while (rc == 0&& itervars != NULL) {
> + rc = ebiptablesCreateRuleInstance(conn,
> + nettype,
> + nwfilter,
> + rule,
> + ifname,
> + itervars,
> + res);
> + if (rc)
> + break;
> + itervars = virNWFilterVarCombIterNext(iter,&rc);
> + };
> +
> + virNWFilterVarCombIterFree(iter);
> +
> + return rc;
> +}
>
> static int
> ebiptablesFreeRuleInstance(void *_inst)
> @@ -3896,7 +3938,7 @@ virNWFilterTechDriver ebiptables_driver
> .init = ebiptablesDriverInit,
> .shutdown = ebiptablesDriverShutdown,
>
> - .createRuleInstance = ebiptablesCreateRuleInstance,
> + .createRuleInstance = ebiptablesCreateRuleInstanceCombinations,
> .applyNewRules = ebiptablesApplyNewRules,
> .tearNewRules = ebiptablesTearNewRules,
> .tearOldRules = ebiptablesTearOldRules,
> Index: libvirt-acl/src/conf/nwfilter_params.c
> ===================================================================
> --- libvirt-acl.orig/src/conf/nwfilter_params.c
> +++ libvirt-acl/src/conf/nwfilter_params.c
> @@ -288,6 +288,152 @@ virNWFilterVarValueAddValue(virNWFilterV
> return rc;
> }
>
> +void
> +virNWFilterVarCombIterFree(virNWFilterVarCombIterPtr ci)
> +{
> + if (!ci)
> + return;
> +
> + virNWFilterHashTableFree(ci->hashTable);
> + VIR_FREE(ci);
> +}
> +
> +virNWFilterVarCombIterPtr
> +virNWFilterVarCombIterCreate(virNWFilterHashTablePtr hash,
> + char * const *vars, unsigned int nVars)
> +{
> + virNWFilterVarCombIterPtr res;
> + virNWFilterVarValuePtr value, orig;
> + unsigned int i;
> + const char *val;
> +
> + if (VIR_ALLOC_VAR(res, virNWFilterVarCombEntry, nVars)< 0) {
> + virReportOOMError();
> + return NULL;
> + }
> +
> + res->hashTable = virNWFilterHashTableCreate(nVars);
> + res->nEntries = nVars;
> + res->orig = hash;
> +
> + for (i = 0; i< nVars; i++) {
> + orig = virHashLookup(hash->hashTable, vars[i]);
> + if (orig == NULL) {
> + virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Could not find value for variable '%s'"),
> + vars[i]);
> + goto err_exit;
> + }
> +
> + res->entry[i].key = vars[i];
> + res->entry[i].cardinality = virNWFilterVarValueGetCardinality(orig);
> +
> + val = virNWFilterVarValueGetNthValue(orig, 0);
> + if (!val) {
> + virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Could not get 0.th value of "
> + "variable '%s'"),
> + res->entry[i].key);
> + goto err_exit;
> + }
> +
> + value = virNWFilterVarValueCreateSimple(val, true);
> + if (!value) {
> + virReportOOMError();
> + goto err_exit;
> + }
> +
> + if (virNWFilterHashTablePut(res->hashTable, vars[i], value, false)) {
> + virReportOOMError();
> + goto err_exit;
> + }
> + }
> +
> + return res;
> +
> +err_exit:
> + virNWFilterVarCombIterFree(res);
> + return NULL;
> +}
> +
> +virNWFilterHashTablePtr
> +virNWFilterVarCombIterFirst(virNWFilterVarCombIterPtr ci)
> +{
> + return ci->hashTable;
> +}
> +
> +virNWFilterHashTablePtr
> +virNWFilterVarCombIterNext(virNWFilterVarCombIterPtr ci, int *error)
> +{
> + unsigned int i;
> + virNWFilterVarValuePtr value;
> + bool done = false;
> + bool end = (ci->nEntries == 0) ||
> + (ci->nEntries == 1&& ci->entry[0].cardinality == 1);
> + const char *val;
> +
> + *error = 0;
> +
> + if (end)
> + return NULL;
> +
> + for (i = 0; i< ci->nEntries; i++) {
> + if (ci->entry[i].cardinality == 1)
> + continue;
> +
> + ci->entry[i].idx++;
> + if (ci->entry[i].idx< ci->entry[i].cardinality) {
> + done = true;
> + } else {
> + ci->entry[i].idx = 0;
> + }
> +
> + value = virHashLookup(ci->orig->hashTable, ci->entry[i].key);
> + if (!value) {
> + virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Could not find value for variable '%s'"),
> + ci->entry[i].key);
> + *error = 1;
> + break;
> + }
> +
> + val = virNWFilterVarValueGetNthValue(value, ci->entry[i].idx);
> + if (!val) {
> + virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Could not get nth (%u) value of "
> + "variable '%s'"),
> + ci->entry[i].idx, ci->entry[i].key);
> + *error = 1;
> + break;
> + }
> +
> + value = virNWFilterVarValueCreateSimple(val, true);
> + if (!value) {
> + virReportOOMError();
> + *error = 1;
> + break;
> + }
> +
> + if (virNWFilterHashTablePut(ci->hashTable, ci->entry[i].key,
> + value, false)) {
> + virReportOOMError();
> + *error = 1;
> + break;
> + }
> +
> + if (done || *error)
> + break;
> + }
> +
> + if (ci->nEntries == i)
> + end = true;
> +
> + if (end || *error)
> + return NULL;
> +
> + return ci->hashTable;
> +}
> +
> static void
> hashDataFree(void *payload, const void *name ATTRIBUTE_UNUSED)
> {
> Index: libvirt-acl/src/conf/nwfilter_params.h
> ===================================================================
> --- libvirt-acl.orig/src/conf/nwfilter_params.h
> +++ libvirt-acl/src/conf/nwfilter_params.h
> @@ -89,4 +89,29 @@ int virNWFilterHashTablePutAll(virNWFilt
> # define VALID_VARVALUE \
> "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.:"
>
> +typedef struct _virNWFilterVarCombEntry virNWFilterVarCombEntry;
> +struct _virNWFilterVarCombEntry {
> + const char *key;
> + unsigned int idx;
> + unsigned int cardinality;
> +};
> +
> +typedef struct _virNWFilterVarCombIter virNWFilterVarCombIter;
> +typedef virNWFilterVarCombIter *virNWFilterVarCombIterPtr;
> +struct _virNWFilterVarCombIter {
> + virNWFilterHashTablePtr hashTable;
> + virNWFilterHashTablePtr orig;
> + unsigned int nEntries;
> + virNWFilterVarCombEntry entry[1];
> +};
> +virNWFilterVarCombIterPtr virNWFilterVarCombIterCreate(
> + virNWFilterHashTablePtr hash,
> + char * const *vars,
> + unsigned int nvars);
> +
> +void virNWFilterVarCombIterFree(virNWFilterVarCombIterPtr combiter);
> +virNWFilterHashTablePtr virNWFilterVarCombIterFirst(virNWFilterVarCombIterPtr);
> +virNWFilterHashTablePtr virNWFilterVarCombIterNext(virNWFilterVarCombIterPtr,
> + int *error);
> +
> #endif /* NWFILTER_PARAMS_H */
> Index: libvirt-acl/src/libvirt_private.syms
> ===================================================================
> --- libvirt-acl.orig/src/libvirt_private.syms
> +++ libvirt-acl/src/libvirt_private.syms
> @@ -878,6 +878,10 @@ virNWFilterHashTableFree;
> virNWFilterHashTablePut;
> virNWFilterHashTablePutAll;
> virNWFilterHashTableRemoveEntry;
> +virNWFilterVarCombIterCreate;
> +virNWFilterVarCombIterFirst;
> +virNWFilterVarCombIterFree;
> +virNWFilterVarCombIterNext;
> virNWFilterVarValueCreateSimple;
> virNWFilterVarValueGetSimple;
>
>
More information about the libvir-list
mailing list