This patch adds access to single elements of variables via index. Example:
<rule action='accept' direction='in' priority='500'>
<tcp srcipaddr='$ADDR[1]' srcportstart='$B[2]'/>
</rule>
---
src/conf/nwfilter_params.c | 82 +++++++++++++++++++++++++++++++++++----------
src/conf/nwfilter_params.h | 9 +++-
2 files changed, 71 insertions(+), 20 deletions(-)
Index: libvirt-iterator/src/conf/nwfilter_params.c
===================================================================
--- libvirt-iterator.orig/src/conf/nwfilter_params.c
+++ libvirt-iterator/src/conf/nwfilter_params.c
@@ -35,7 +35,10 @@
#define VIR_FROM_THIS VIR_FROM_NWFILTER
static bool isValidVarValue(const char *value);
-
+static void virNWFilterVarAccessSetIntIterId(virNWFilterVarAccessPtr,
+ unsigned int);
+static unsigned int virNWFilterVarAccessGetIntIterId(
+ const virNWFilterVarAccessPtr);
void
virNWFilterVarValueFree(virNWFilterVarValuePtr val)
@@ -313,7 +316,7 @@ virNWFilterVarCombIterAddVariable(virNWF
const virNWFilterVarAccessPtr varAccess)
{
virNWFilterVarValuePtr varValue;
- unsigned int cardinality;
+ unsigned int maxValue, minValue;
const char *varName = virNWFilterVarAccessGetVarName(varAccess);
varValue = virHashLookup(hash->hashTable, varName);
@@ -324,12 +327,25 @@ virNWFilterVarCombIterAddVariable(virNWF
return -1;
}
- cardinality = virNWFilterVarValueGetCardinality(varValue);
+ switch (virNWFilterVarAccessGetType(varAccess)) {
+ case VIR_NWFILTER_VAR_ACCESS_ELEMENT:
+ maxValue = virNWFilterVarAccessGetIndex(varAccess);
+ minValue = maxValue;
+ break;
+ case VIR_NWFILTER_VAR_ACCESS_ITERATOR:
+ maxValue = virNWFilterVarValueGetCardinality(varValue) - 1;
+ minValue = 0;
+ break;
+ case VIR_NWFILTER_VAR_ACCESS_LAST:
+ return -1;
+ }
if (cie->nVarNames == 0) {
- cie->maxValue = cardinality - 1;
+ cie->maxValue = maxValue;
+ cie->minValue = minValue;
+ cie->curValue = minValue;
} else {
- if (cie->maxValue != cardinality - 1) {
+ if (cie->maxValue != maxValue) {
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
_("Cardinality of list items must be "
"the same for processing them in "
@@ -410,12 +426,13 @@ virNWFilterVarCombIterEntryAreUniqueEntr
*/
virNWFilterVarCombIterPtr
virNWFilterVarCombIterCreate(virNWFilterHashTablePtr hash,
- const virNWFilterVarAccessPtr *varAccess,
+ virNWFilterVarAccessPtr *varAccess,
size_t nVarAccess)
{
virNWFilterVarCombIterPtr res;
unsigned int i, iterId;
int iterIndex = -1;
+ unsigned int nextIntIterId = VIR_NWFILTER_MAX_ITERID + 1;
if (VIR_ALLOC_VAR(res, virNWFilterVarCombIterEntry, 1 + nVarAccess) < 0) {
virReportOOMError();
@@ -442,6 +459,13 @@ virNWFilterVarCombIterCreate(virNWFilter
}
break;
case VIR_NWFILTER_VAR_ACCESS_ELEMENT:
+ iterIndex = res->nIter;
+ virNWFilterVarAccessSetIntIterId(varAccess[i], nextIntIterId);
+ virNWFilterVarCombIterEntryInit(&res->iter[iterIndex],
+ nextIntIterId);
+ nextIntIterId++;
+ res->nIter++;
+ break;
case VIR_NWFILTER_VAR_ACCESS_LAST:
break;
}
@@ -472,7 +496,7 @@ next:
goto next;
break;
} else {
- ci->iter[i].curValue = 0;
+ ci->iter[i].curValue = ci->iter[i].minValue;
}
}
@@ -507,9 +531,15 @@ virNWFilterVarCombIterGetVarValue(virNWF
}
break;
case VIR_NWFILTER_VAR_ACCESS_ELEMENT:
- virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
- _("Element access via index is not possible"));
- return NULL;
+ iterId = virNWFilterVarAccessGetIntIterId(vap);
+ iterIndex = virNWFilterVarCombIterGetIndexByIterId(ci, iterId);
+ if (iterIndex < 0) {
+ virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not get iterator index for "
+ "(internal) iterator ID %u"), iterId);
+ return NULL;
+ }
+ break;
case VIR_NWFILTER_VAR_ACCESS_LAST:
return NULL;
}
@@ -874,7 +904,8 @@ virNWFilterVarAccessEqual(const virNWFil
switch (a->accessType) {
case VIR_NWFILTER_VAR_ACCESS_ELEMENT:
- return (a->u.index == b->u.index);
+ return (a->u.index.index == b->u.index.index &&
+ a->u.index.intIterId == b->u.index.intIterId);
break;
case VIR_NWFILTER_VAR_ACCESS_ITERATOR:
return (a->u.iterId == b->u.iterId);
@@ -938,11 +969,6 @@ virNWFilterVarAccessParse(const char *va
} else {
/* in the form 'IP[<number>] -> element */
dest->accessType = VIR_NWFILTER_VAR_ACCESS_ELEMENT;
- /* not supported (yet) */
- virNWFilterReportError(VIR_ERR_INVALID_ARG,
- _("Variable access in the form "
- "var[<index>] is not supported"));
- goto err_exit;
}
if (virStrToLong_ui(input, &end_ptr, 10, &result) < 0)
@@ -965,7 +991,8 @@ virNWFilterVarAccessParse(const char *va
switch (dest->accessType) {
case VIR_NWFILTER_VAR_ACCESS_ELEMENT:
- dest->u.index = result;
+ dest->u.index.index = result;
+ dest->u.index.intIterId = ~0;
break;
case VIR_NWFILTER_VAR_ACCESS_ITERATOR:
if (result > VIR_NWFILTER_MAX_ITERID) {
@@ -998,7 +1025,7 @@ virNWFilterVarAccessPrint(virNWFilterVar
virBufferAdd(buf, vap->varName, -1);
switch (vap->accessType) {
case VIR_NWFILTER_VAR_ACCESS_ELEMENT:
- virBufferAsprintf(buf, "[%u]", vap->u.index);
+ virBufferAsprintf(buf, "[%u]", vap->u.index.index);
break;
case VIR_NWFILTER_VAR_ACCESS_ITERATOR:
if (vap->u.iterId != 0)
@@ -1026,3 +1053,22 @@ virNWFilterVarAccessGetIterId(const virN
{
return vap->u.iterId;
}
+
+unsigned int
+virNWFilterVarAccessGetIndex(const virNWFilterVarAccessPtr vap)
+{
+ return vap->u.index.index;
+}
+
+static void
+virNWFilterVarAccessSetIntIterId(virNWFilterVarAccessPtr vap,
+ unsigned int intIterId)
+{
+ vap->u.index.intIterId = intIterId;
+}
+
+static unsigned int
+virNWFilterVarAccessGetIntIterId(const virNWFilterVarAccessPtr vap)
+{
+ return vap->u.index.intIterId;
+}
Index: libvirt-iterator/src/conf/nwfilter_params.h
===================================================================
--- libvirt-iterator.orig/src/conf/nwfilter_params.h
+++ libvirt-iterator/src/conf/nwfilter_params.h
@@ -103,7 +103,10 @@ typedef virNWFilterVarAccess *virNWFilte
struct _virNWFilterVarAccess {
enum virNWFilterVarAccessType accessType;
union {
- unsigned int index;
+ struct {
+ unsigned int index;
+ unsigned int intIterId;
+ } index;
unsigned int iterId;
} u;
char *varName;
@@ -121,6 +124,7 @@ const char *virNWFilterVarAccessGetVarNa
enum virNWFilterVarAccessType virNWFilterVarAccessGetType(
const virNWFilterVarAccessPtr vap);
unsigned int virNWFilterVarAccessGetIterId(const virNWFilterVarAccessPtr vap);
+unsigned int virNWFilterVarAccessGetIndex(const virNWFilterVarAccessPtr vap);
typedef struct _virNWFilterVarCombIterEntry virNWFilterVarCombIterEntry;
@@ -131,6 +135,7 @@ struct _virNWFilterVarCombIterEntry {
size_t nVarNames;
unsigned int maxValue;
unsigned int curValue;
+ unsigned int minValue;
};
typedef struct _virNWFilterVarCombIter virNWFilterVarCombIter;
@@ -142,7 +147,7 @@ struct _virNWFilterVarCombIter {
};
virNWFilterVarCombIterPtr virNWFilterVarCombIterCreate(
virNWFilterHashTablePtr hash,
- const virNWFilterVarAccessPtr *vars,
+ virNWFilterVarAccessPtr *vars,
size_t nVars);
void virNWFilterVarCombIterFree(virNWFilterVarCombIterPtr ci);