[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