mirror of https://gitee.com/openkylin/libvirt.git
Introduce possibility to have an iterator per variable
This patch introduces the capability to use a different iterator per variable. The currently supported notation of variables in a filtering rule like <rule action='accept' direction='out'> <tcp srcipaddr='$A' srcportstart='$B'/> </rule> processes the two lists 'A' and 'B' in parallel. This means that A and B must have the same number of 'N' elements and that 'N' rules will be instantiated (assuming all tuples from A and B are unique). In this patch we now introduce the assignment of variables to different iterators. Therefore a rule like <rule action='accept' direction='out'> <tcp srcipaddr='$A[@1]' srcportstart='$B[@2]'/> </rule> will now create every combination of elements in A with elements in B since A has been assigned to an iterator with Id '1' and B has been assigned to an iterator with Id '2', thus processing their value independently. The first rule has an equivalent notation of <rule action='accept' direction='out'> <tcp srcipaddr='$A[@0]' srcportstart='$B[@0]'/> </rule>
This commit is contained in:
parent
134c56764f
commit
80e9a5cd4c
|
@ -811,12 +811,15 @@
|
|||
</choice>
|
||||
</define>
|
||||
|
||||
<define name="variable-name-type">
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+(\[[ ]*[@]?[0-9]+[ ]*\])?</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name="addrMAC">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
<ref name="variable-name-type"/>
|
||||
|
||||
<data type="string">
|
||||
<param name="pattern">([a-fA-F0-9]{1,2}:){5}[a-fA-F0-9]{1,2}</param>
|
||||
|
@ -826,10 +829,7 @@
|
|||
|
||||
<define name="addrIP">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
<ref name="variable-name-type"/>
|
||||
|
||||
<data type="string">
|
||||
<param name="pattern">([0-2]?[0-9]?[0-9]\.){3}[0-2]?[0-9]?[0-9]</param>
|
||||
|
@ -839,10 +839,7 @@
|
|||
|
||||
<define name="addrIPv6">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
<ref name="variable-name-type"/>
|
||||
|
||||
<data type="string">
|
||||
<param name="pattern">([a-fA-F0-9]{0,4}:){2,7}([a-fA-F0-9]*)(([0-2]?[0-9]?[0-9]\.){3}[0-2]?[0-9]?[0-9])?</param>
|
||||
|
@ -852,10 +849,7 @@
|
|||
|
||||
<define name="addrMask">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
<ref name="variable-name-type"/>
|
||||
|
||||
<data type="int">
|
||||
<param name="minInclusive">0</param>
|
||||
|
@ -870,10 +864,7 @@
|
|||
|
||||
<define name="addrMaskv6">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
<ref name="variable-name-type"/>
|
||||
|
||||
<data type="int">
|
||||
<param name="minInclusive">0</param>
|
||||
|
@ -892,10 +883,7 @@
|
|||
<param name="pattern">0x([0-3][0-9a-fA-F]|[0-9a-fA-F])</param>
|
||||
</data>
|
||||
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
<ref name="variable-name-type"/>
|
||||
|
||||
<data type="int">
|
||||
<param name="minInclusive">0</param>
|
||||
|
@ -906,10 +894,7 @@
|
|||
|
||||
<define name="mac-protocolid">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
<ref name="variable-name-type"/>
|
||||
|
||||
<data type="string">
|
||||
<param name="pattern">0x([6-9a-fA-F][0-9a-fA-F]{2}|[0-9a-fA-F]{4})</param>
|
||||
|
@ -932,10 +917,7 @@
|
|||
|
||||
<define name="vlan-vlanid">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
<ref name="variable-name-type"/>
|
||||
|
||||
<data type="string">
|
||||
<param name="pattern">0x([0-9a-fA-F]{1,3})</param>
|
||||
|
@ -950,10 +932,7 @@
|
|||
|
||||
<define name="uint8range">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
<ref name="variable-name-type"/>
|
||||
|
||||
<data type="string">
|
||||
<param name="pattern">0x[0-9a-fA-F]{1,2}</param>
|
||||
|
@ -968,10 +947,7 @@
|
|||
|
||||
<define name="uint16range">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
<ref name="variable-name-type"/>
|
||||
|
||||
<data type="string">
|
||||
<param name="pattern">0x[0-9a-fA-F]{1,4}</param>
|
||||
|
@ -986,10 +962,7 @@
|
|||
|
||||
<define name="uint32range">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
<ref name="variable-name-type"/>
|
||||
|
||||
<data type="string">
|
||||
<param name="pattern">0x[0-9a-fA-F]{1,8}</param>
|
||||
|
@ -1015,10 +988,7 @@
|
|||
|
||||
<define name="arpOpcodeType">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
<ref name="variable-name-type"/>
|
||||
|
||||
<data type="int">
|
||||
<param name="minInclusive">0</param>
|
||||
|
@ -1034,10 +1004,7 @@
|
|||
|
||||
<define name="ipProtocolType">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
<ref name="variable-name-type"/>
|
||||
|
||||
<data type="string">
|
||||
<param name="pattern">0x[0-9a-fA-F]{1,2}</param>
|
||||
|
|
|
@ -272,13 +272,13 @@ virNWFilterRuleDefFree(virNWFilterRuleDefPtr def) {
|
|||
if (!def)
|
||||
return;
|
||||
|
||||
for (i = 0; i < def->nvars; i++)
|
||||
VIR_FREE(def->vars[i]);
|
||||
for (i = 0; i < def->nVarAccess; i++)
|
||||
virNWFilterVarAccessFree(def->varAccess[i]);
|
||||
|
||||
for (i = 0; i < def->nstrings; i++)
|
||||
VIR_FREE(def->strings[i]);
|
||||
|
||||
VIR_FREE(def->vars);
|
||||
VIR_FREE(def->varAccess);
|
||||
VIR_FREE(def->strings);
|
||||
|
||||
VIR_FREE(def);
|
||||
|
@ -358,28 +358,28 @@ virNWFilterRuleDefAddVar(virNWFilterRuleDefPtr nwf,
|
|||
const char *var)
|
||||
{
|
||||
int i = 0;
|
||||
virNWFilterVarAccessPtr varAccess;
|
||||
|
||||
if (nwf->vars) {
|
||||
for (i = 0; i < nwf->nvars; i++)
|
||||
if (STREQ(nwf->vars[i], var)) {
|
||||
item->var = nwf->vars[i];
|
||||
varAccess = virNWFilterVarAccessParse(var);
|
||||
if (varAccess == NULL)
|
||||
return -1;
|
||||
|
||||
if (nwf->varAccess) {
|
||||
for (i = 0; i < nwf->nVarAccess; i++)
|
||||
if (virNWFilterVarAccessEqual(nwf->varAccess[i], varAccess)) {
|
||||
virNWFilterVarAccessFree(varAccess);
|
||||
item->varAccess = nwf->varAccess[i];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (VIR_REALLOC_N(nwf->vars, nwf->nvars+1) < 0) {
|
||||
if (VIR_EXPAND_N(nwf->varAccess, nwf->nVarAccess, 1) < 0) {
|
||||
virReportOOMError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
nwf->vars[nwf->nvars] = strdup(var);
|
||||
|
||||
if (!nwf->vars[nwf->nvars]) {
|
||||
virReportOOMError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
item->var = nwf->vars[nwf->nvars++];
|
||||
nwf->varAccess[nwf->nVarAccess - 1] = varAccess;
|
||||
item->varAccess = varAccess;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3069,7 +3069,8 @@ virNWFilterRuleDefDetailsFormat(virBufferPtr buf,
|
|||
goto err_exit;
|
||||
}
|
||||
} else if ((flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
|
||||
virBufferAsprintf(buf, "$%s", item->var);
|
||||
virBufferAddChar(buf, '$');
|
||||
virNWFilterVarAccessPrint(item->varAccess, buf);
|
||||
} else {
|
||||
asHex = false;
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ typedef struct _nwItemDesc nwItemDesc;
|
|||
typedef nwItemDesc *nwItemDescPtr;
|
||||
struct _nwItemDesc {
|
||||
enum virNWFilterEntryItemFlags flags;
|
||||
char *var;
|
||||
virNWFilterVarAccessPtr varAccess;
|
||||
enum attrDatatype datatype;
|
||||
union {
|
||||
nwMACAddress macaddr;
|
||||
|
@ -470,8 +470,8 @@ struct _virNWFilterRuleDef {
|
|||
sctpHdrFilterDef sctpHdrFilter;
|
||||
} p;
|
||||
|
||||
int nvars;
|
||||
char **vars;
|
||||
size_t nVarAccess;
|
||||
virNWFilterVarAccessPtr *varAccess;
|
||||
|
||||
int nstrings;
|
||||
char **strings;
|
||||
|
|
|
@ -310,10 +310,11 @@ virNWFilterVarCombIterEntryInit(virNWFilterVarCombIterEntryPtr cie,
|
|||
static int
|
||||
virNWFilterVarCombIterAddVariable(virNWFilterVarCombIterEntryPtr cie,
|
||||
virNWFilterHashTablePtr hash,
|
||||
const char *varName)
|
||||
const virNWFilterVarAccessPtr varAccess)
|
||||
{
|
||||
virNWFilterVarValuePtr varValue;
|
||||
unsigned int cardinality;
|
||||
const char *varName = virNWFilterVarAccessGetVarName(varAccess);
|
||||
|
||||
varValue = virHashLookup(hash->hashTable, varName);
|
||||
if (varValue == NULL) {
|
||||
|
@ -409,13 +410,14 @@ virNWFilterVarCombIterEntryAreUniqueEntries(virNWFilterVarCombIterEntryPtr cie,
|
|||
*/
|
||||
virNWFilterVarCombIterPtr
|
||||
virNWFilterVarCombIterCreate(virNWFilterHashTablePtr hash,
|
||||
char * const *vars, unsigned int nVars)
|
||||
const virNWFilterVarAccessPtr *varAccess,
|
||||
size_t nVarAccess)
|
||||
{
|
||||
virNWFilterVarCombIterPtr res;
|
||||
unsigned int i, iterId;
|
||||
int iterIndex;
|
||||
int iterIndex = -1;
|
||||
|
||||
if (VIR_ALLOC_VAR(res, virNWFilterVarCombIterEntry, 1) < 0) {
|
||||
if (VIR_ALLOC_VAR(res, virNWFilterVarCombIterEntry, 1 + nVarAccess) < 0) {
|
||||
virReportOOMError();
|
||||
return NULL;
|
||||
}
|
||||
|
@ -428,22 +430,24 @@ virNWFilterVarCombIterCreate(virNWFilterHashTablePtr hash,
|
|||
res->nIter = 1;
|
||||
virNWFilterVarCombIterEntryInit(&res->iter[0], iterId);
|
||||
|
||||
for (i = 0; i < nVars; i++) {
|
||||
|
||||
/* currently always access @0 */
|
||||
iterId = 0;
|
||||
|
||||
iterIndex = virNWFilterVarCombIterGetIndexByIterId(res, iterId);
|
||||
if (iterIndex < 0) {
|
||||
/* future: create new iterator. for now it's a bug */
|
||||
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Could not find iterator with id %u"),
|
||||
iterId);
|
||||
goto err_exit;
|
||||
for (i = 0; i < nVarAccess; i++) {
|
||||
switch (virNWFilterVarAccessGetType(varAccess[i])) {
|
||||
case VIR_NWFILTER_VAR_ACCESS_ITERATOR:
|
||||
iterId = virNWFilterVarAccessGetIterId(varAccess[i]);
|
||||
iterIndex = virNWFilterVarCombIterGetIndexByIterId(res, iterId);
|
||||
if (iterIndex < 0) {
|
||||
iterIndex = res->nIter;
|
||||
virNWFilterVarCombIterEntryInit(&res->iter[iterIndex], iterId);
|
||||
res->nIter++;
|
||||
}
|
||||
break;
|
||||
case VIR_NWFILTER_VAR_ACCESS_ELEMENT:
|
||||
case VIR_NWFILTER_VAR_ACCESS_LAST:
|
||||
break;
|
||||
}
|
||||
|
||||
if (virNWFilterVarCombIterAddVariable(&res->iter[iterIndex],
|
||||
hash, vars[i]) < 0)
|
||||
hash, varAccess[i]) < 0)
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
|
@ -482,16 +486,33 @@ next:
|
|||
|
||||
const char *
|
||||
virNWFilterVarCombIterGetVarValue(virNWFilterVarCombIterPtr ci,
|
||||
const char *varName)
|
||||
const virNWFilterVarAccessPtr vap)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i, iterId;
|
||||
bool found = false;
|
||||
const char *res = NULL;
|
||||
virNWFilterVarValuePtr value;
|
||||
unsigned int iterIndex;
|
||||
int iterIndex = -1;
|
||||
const char *varName = virNWFilterVarAccessGetVarName(vap);
|
||||
|
||||
/* currently always accessing iter @0 */
|
||||
iterIndex = 0;
|
||||
switch (virNWFilterVarAccessGetType(vap)) {
|
||||
case VIR_NWFILTER_VAR_ACCESS_ITERATOR:
|
||||
iterId = virNWFilterVarAccessGetIterId(vap);
|
||||
iterIndex = virNWFilterVarCombIterGetIndexByIterId(ci, iterId);
|
||||
if (iterIndex < 0) {
|
||||
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Could not get iterator index for "
|
||||
"iterator ID %u"), iterId);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case VIR_NWFILTER_VAR_ACCESS_ELEMENT:
|
||||
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Element access via index is not possible"));
|
||||
return NULL;
|
||||
case VIR_NWFILTER_VAR_ACCESS_LAST:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ci->iter[iterIndex].nVarNames; i++) {
|
||||
if (STREQ(ci->iter[iterIndex].varNames[i], varName)) {
|
||||
|
@ -830,3 +851,178 @@ virNWFilterFormatParamAttributes(virBufferPtr buf,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
virNWFilterVarAccessFree(virNWFilterVarAccessPtr varAccess)
|
||||
{
|
||||
if (!varAccess)
|
||||
return;
|
||||
|
||||
VIR_FREE(varAccess->varName);
|
||||
VIR_FREE(varAccess);
|
||||
}
|
||||
|
||||
bool
|
||||
virNWFilterVarAccessEqual(const virNWFilterVarAccessPtr a,
|
||||
const virNWFilterVarAccessPtr b)
|
||||
{
|
||||
if (a->accessType != b->accessType)
|
||||
return false;
|
||||
|
||||
if (STRNEQ(a->varName, b->varName))
|
||||
return false;
|
||||
|
||||
switch (a->accessType) {
|
||||
case VIR_NWFILTER_VAR_ACCESS_ELEMENT:
|
||||
return (a->u.index == b->u.index);
|
||||
break;
|
||||
case VIR_NWFILTER_VAR_ACCESS_ITERATOR:
|
||||
return (a->u.iterId == b->u.iterId);
|
||||
break;
|
||||
case VIR_NWFILTER_VAR_ACCESS_LAST:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a variable access like
|
||||
* IP, IP[@2], IP[3]
|
||||
*/
|
||||
virNWFilterVarAccessPtr
|
||||
virNWFilterVarAccessParse(const char *varAccess)
|
||||
{
|
||||
size_t idx, varNameLen;
|
||||
virNWFilterVarAccessPtr dest;
|
||||
const char *input = varAccess;
|
||||
|
||||
if (VIR_ALLOC(dest) < 0) {
|
||||
virReportOOMError();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
idx = strspn(input, VALID_VARNAME);
|
||||
|
||||
if (input[idx] == '\0') {
|
||||
/* in the form 'IP', which is equivalent to IP[@0] */
|
||||
dest->varName = strndup(input, idx);
|
||||
if (!dest->varName) {
|
||||
virReportOOMError();
|
||||
goto err_exit;
|
||||
}
|
||||
dest->accessType = VIR_NWFILTER_VAR_ACCESS_ITERATOR;
|
||||
dest->u.iterId = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
if (input[idx] == '[') {
|
||||
char *end_ptr;
|
||||
unsigned int result;
|
||||
bool parseError = false;
|
||||
|
||||
varNameLen = idx;
|
||||
|
||||
dest->varName = strndup(input, varNameLen);
|
||||
if (!dest->varName) {
|
||||
virReportOOMError();
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
input += idx + 1;
|
||||
virSkipSpaces(&input);
|
||||
|
||||
if (*input == '@') {
|
||||
/* in the form 'IP[@<number>] -> iterator */
|
||||
dest->accessType = VIR_NWFILTER_VAR_ACCESS_ITERATOR;
|
||||
input++;
|
||||
} 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)
|
||||
parseError = true;
|
||||
if (!parseError) {
|
||||
input = end_ptr;
|
||||
virSkipSpaces(&input);
|
||||
if (*input != ']')
|
||||
parseError = true;
|
||||
}
|
||||
if (parseError) {
|
||||
if (dest->accessType == VIR_NWFILTER_VAR_ACCESS_ELEMENT)
|
||||
virNWFilterReportError(VIR_ERR_INVALID_ARG,
|
||||
_("Malformatted array index"));
|
||||
else
|
||||
virNWFilterReportError(VIR_ERR_INVALID_ARG,
|
||||
_("Malformatted iterator id"));
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
switch (dest->accessType) {
|
||||
case VIR_NWFILTER_VAR_ACCESS_ELEMENT:
|
||||
dest->u.index = result;
|
||||
break;
|
||||
case VIR_NWFILTER_VAR_ACCESS_ITERATOR:
|
||||
if (result > VIR_NWFILTER_MAX_ITERID) {
|
||||
virNWFilterReportError(VIR_ERR_INVALID_ARG,
|
||||
_("Iterator ID exceeds maximum ID "
|
||||
"of %u"), VIR_NWFILTER_MAX_ITERID);
|
||||
goto err_exit;
|
||||
}
|
||||
dest->u.iterId = result;
|
||||
break;
|
||||
case VIR_NWFILTER_VAR_ACCESS_LAST:
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
return dest;
|
||||
} else {
|
||||
virNWFilterReportError(VIR_ERR_INVALID_ARG,
|
||||
_("Malformatted variable"));
|
||||
}
|
||||
|
||||
err_exit:
|
||||
virNWFilterVarAccessFree(dest);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
virNWFilterVarAccessPrint(virNWFilterVarAccessPtr vap, virBufferPtr buf)
|
||||
{
|
||||
virBufferAdd(buf, vap->varName, -1);
|
||||
switch (vap->accessType) {
|
||||
case VIR_NWFILTER_VAR_ACCESS_ELEMENT:
|
||||
virBufferAsprintf(buf, "[%u]", vap->u.index);
|
||||
break;
|
||||
case VIR_NWFILTER_VAR_ACCESS_ITERATOR:
|
||||
if (vap->u.iterId != 0)
|
||||
virBufferAsprintf(buf, "[@%u]", vap->u.iterId);
|
||||
break;
|
||||
case VIR_NWFILTER_VAR_ACCESS_LAST:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
virNWFilterVarAccessGetVarName(const virNWFilterVarAccessPtr vap)
|
||||
{
|
||||
return vap->varName;
|
||||
}
|
||||
|
||||
enum virNWFilterVarAccessType
|
||||
virNWFilterVarAccessGetType(const virNWFilterVarAccessPtr vap)
|
||||
{
|
||||
return vap->accessType;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
virNWFilterVarAccessGetIterId(const virNWFilterVarAccessPtr vap)
|
||||
{
|
||||
return vap->u.iterId;
|
||||
}
|
||||
|
|
|
@ -91,6 +91,38 @@ int virNWFilterHashTablePutAll(virNWFilterHashTablePtr src,
|
|||
# define VALID_VARVALUE \
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.:"
|
||||
|
||||
enum virNWFilterVarAccessType {
|
||||
VIR_NWFILTER_VAR_ACCESS_ELEMENT = 0,
|
||||
VIR_NWFILTER_VAR_ACCESS_ITERATOR = 1,
|
||||
|
||||
VIR_NWFILTER_VAR_ACCESS_LAST,
|
||||
};
|
||||
|
||||
typedef struct _virNWFilterVarAccess virNWFilterVarAccess;
|
||||
typedef virNWFilterVarAccess *virNWFilterVarAccessPtr;
|
||||
struct _virNWFilterVarAccess {
|
||||
enum virNWFilterVarAccessType accessType;
|
||||
union {
|
||||
unsigned int index;
|
||||
unsigned int iterId;
|
||||
} u;
|
||||
char *varName;
|
||||
};
|
||||
|
||||
# define VIR_NWFILTER_MAX_ITERID 1000
|
||||
|
||||
void virNWFilterVarAccessFree(virNWFilterVarAccessPtr varAccess);
|
||||
bool virNWFilterVarAccessEqual(const virNWFilterVarAccessPtr a,
|
||||
const virNWFilterVarAccessPtr b);
|
||||
virNWFilterVarAccessPtr virNWFilterVarAccessParse(const char *varAccess);
|
||||
void virNWFilterVarAccessPrint(virNWFilterVarAccessPtr vap,
|
||||
virBufferPtr buf);
|
||||
const char *virNWFilterVarAccessGetVarName(const virNWFilterVarAccessPtr vap);
|
||||
enum virNWFilterVarAccessType virNWFilterVarAccessGetType(
|
||||
const virNWFilterVarAccessPtr vap);
|
||||
unsigned int virNWFilterVarAccessGetIterId(const virNWFilterVarAccessPtr vap);
|
||||
|
||||
|
||||
typedef struct _virNWFilterVarCombIterEntry virNWFilterVarCombIterEntry;
|
||||
typedef virNWFilterVarCombIterEntry *virNWFilterVarCombIterEntryPtr;
|
||||
struct _virNWFilterVarCombIterEntry {
|
||||
|
@ -110,12 +142,14 @@ struct _virNWFilterVarCombIter {
|
|||
};
|
||||
virNWFilterVarCombIterPtr virNWFilterVarCombIterCreate(
|
||||
virNWFilterHashTablePtr hash,
|
||||
char * const *vars, unsigned int nVars);
|
||||
const virNWFilterVarAccessPtr *vars,
|
||||
size_t nVars);
|
||||
|
||||
void virNWFilterVarCombIterFree(virNWFilterVarCombIterPtr ci);
|
||||
virNWFilterVarCombIterPtr virNWFilterVarCombIterNext(
|
||||
virNWFilterVarCombIterPtr ci);
|
||||
const char *virNWFilterVarCombIterGetVarValue(virNWFilterVarCombIterPtr ci,
|
||||
const char *varname);
|
||||
const virNWFilterVarAccessPtr);
|
||||
|
||||
|
||||
#endif /* NWFILTER_PARAMS_H */
|
||||
|
|
|
@ -832,6 +832,7 @@ virNWFilterHashTableFree;
|
|||
virNWFilterHashTablePut;
|
||||
virNWFilterHashTablePutAll;
|
||||
virNWFilterHashTableRemoveEntry;
|
||||
virNWFilterVarAccessGetVarName;
|
||||
virNWFilterVarCombIterCreate;
|
||||
virNWFilterVarCombIterFree;
|
||||
virNWFilterVarCombIterGetVarValue;
|
||||
|
|
|
@ -230,17 +230,19 @@ printVar(virNWFilterVarCombIterPtr vars,
|
|||
if ((item->flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
|
||||
const char *val;
|
||||
|
||||
val = virNWFilterVarCombIterGetVarValue(vars, item->var);
|
||||
val = virNWFilterVarCombIterGetVarValue(vars, item->varAccess);
|
||||
if (!val) {
|
||||
/* error has been reported */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!virStrcpy(buf, val, bufsize)) {
|
||||
const char *varName;
|
||||
|
||||
varName = virNWFilterVarAccessGetVarName(item->varAccess);
|
||||
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Buffer too small to print MAC address "
|
||||
"'%s' into"),
|
||||
item->var);
|
||||
_("Buffer too small to print variable "
|
||||
"'%s' into"), varName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -2631,7 +2633,8 @@ ebiptablesCreateRuleInstanceIterate(
|
|||
* iterate over all combinations of the variables' values and instantiate
|
||||
* the filtering rule with each combination.
|
||||
*/
|
||||
vciter = virNWFilterVarCombIterCreate(vars, rule->vars, rule->nvars);
|
||||
vciter = virNWFilterVarCombIterCreate(vars,
|
||||
rule->varAccess, rule->nVarAccess);
|
||||
if (!vciter)
|
||||
return -1;
|
||||
|
||||
|
|
|
@ -500,14 +500,16 @@ virNWFilterDetermineMissingVarsRec(virNWFilterDefPtr filter,
|
|||
virNWFilterIncludeDefPtr inc = filter->filterEntries[i]->include;
|
||||
if (rule) {
|
||||
/* check all variables of this rule */
|
||||
for (j = 0; j < rule->nvars; j++) {
|
||||
if (!virHashLookup(vars->hashTable, rule->vars[j])) {
|
||||
for (j = 0; j < rule->nVarAccess; j++) {
|
||||
const char *varName;
|
||||
varName = virNWFilterVarAccessGetVarName(rule->varAccess[j]);
|
||||
if (!virHashLookup(vars->hashTable, varName)) {
|
||||
val = virNWFilterVarValueCreateSimpleCopyValue("1");
|
||||
if (!val) {
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
virNWFilterHashTablePut(missing_vars, rule->vars[j],
|
||||
virNWFilterHashTablePut(missing_vars, varName,
|
||||
val, 1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue