#define VIR_FROM_THIS VIR_FROM_NWFILTER
+static bool isValidVarValue(const char *value);
+
+
+static void
+virNWFilterVarValueFree(virNWFilterVarValuePtr val)
+{
+ unsigned i;
+
+ if (!val)
+ return;
+
+ switch (val->valType) {
+ case NWFILTER_VALUE_TYPE_SIMPLE:
+ VIR_FREE(val->u.simple.value);
+ break;
+ case NWFILTER_VALUE_TYPE_ARRAY:
+ for (i = 0; i < val->u.array.nValues; i++)
+ VIR_FREE(val->u.array.values[i]);
+ VIR_FREE(val->u.array.values);
+ break;
+ case NWFILTER_VALUE_TYPE_LAST:
+ break;
+ }
+ VIR_FREE(val);
+}
+
+static virNWFilterVarValuePtr
+virNWFilterVarValueCopy(const virNWFilterVarValuePtr val)
+{
+ virNWFilterVarValuePtr res;
+ unsigned i;
+ char *str;
+
+ if (VIR_ALLOC(res) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+ res->valType = val->valType;
+
+ switch (res->valType) {
+ case NWFILTER_VALUE_TYPE_SIMPLE:
+ if (val->u.simple.value) {
+ res->u.simple.value = strdup(val->u.simple.value);
+ if (!res->u.simple.value)
+ goto err_exit;
+ }
+ break;
+ case NWFILTER_VALUE_TYPE_ARRAY:
+ if (VIR_ALLOC_N(res->u.array.values, val->u.array.nValues))
+ goto err_exit;
+ res->u.array.nValues = val->u.array.nValues;
+ for (i = 0; i < val->u.array.nValues; i++) {
+ str = strdup(val->u.array.values[i]);
+ if (!str)
+ goto err_exit;
+ res->u.array.values[i] = str;
+ }
+ break;
+ case NWFILTER_VALUE_TYPE_LAST:
+ break;
+ }
+
+ return res;
+
+err_exit:
+ virReportOOMError();
+ virNWFilterVarValueFree(res);
+ return NULL;
+}
+
+virNWFilterVarValuePtr
+virNWFilterVarValueCreateSimple(char *value)
+{
+ virNWFilterVarValuePtr val;
+
+ if (!isValidVarValue(value)) {
+ virNWFilterReportError(VIR_ERR_INVALID_ARG,
+ _("Variable value contains invalid character"));
+ return NULL;
+ }
+
+ if (VIR_ALLOC(val) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ val->valType = NWFILTER_VALUE_TYPE_SIMPLE;
+ val->u.simple.value = value;
+
+ return val;
+}
+
+virNWFilterVarValuePtr
+virNWFilterVarValueCreateSimpleCopyValue(const char *value)
+{
+ char *val = strdup(value);
+
+ if (!val) {
+ virReportOOMError();
+ return NULL;
+ }
+ return virNWFilterVarValueCreateSimple(val);
+}
+
+const char *
+virNWFilterVarValueGetSimple(const virNWFilterVarValuePtr val)
+{
+ if (val->valType == NWFILTER_VALUE_TYPE_SIMPLE)
+ return val->u.simple.value;
+ return NULL;
+}
+
+const char *
+virNWFilterVarValueGetNthValue(virNWFilterVarValuePtr val, unsigned int idx)
+{
+ const char *res = NULL;
+
+ switch (val->valType) {
+ case NWFILTER_VALUE_TYPE_SIMPLE:
+ if (idx == 0)
+ res = val->u.simple.value;
+ break;
+ case NWFILTER_VALUE_TYPE_ARRAY:
+ if (idx < val->u.array.nValues)
+ res = val->u.array.values[idx];
+ break;
+ case NWFILTER_VALUE_TYPE_LAST:
+ break;
+ }
+
+ return res;
+}
+
+unsigned int
+virNWFilterVarValueGetCardinality(const virNWFilterVarValuePtr val)
+{
+ switch (val->valType) {
+ case NWFILTER_VALUE_TYPE_SIMPLE:
+ return 1;
+ break;
+ case NWFILTER_VALUE_TYPE_ARRAY:
+ return val->u.array.nValues;
+ break;
+ case NWFILTER_VALUE_TYPE_LAST:
+ return 0;
+ }
+ return 0;
+}
+
+int
+virNWFilterVarValueAddValue(virNWFilterVarValuePtr val, char *value)
+{
+ char *tmp;
+ int rc = -1;
+
+ switch (val->valType) {
+ case NWFILTER_VALUE_TYPE_SIMPLE:
+ /* switch to array */
+ tmp = val->u.simple.value;
+ if (VIR_ALLOC_N(val->u.array.values, 2) < 0) {
+ val->u.simple.value = tmp;
+ virReportOOMError();
+ return -1;
+ }
+ val->valType = NWFILTER_VALUE_TYPE_ARRAY;
+ val->u.array.nValues = 2;
+ val->u.array.values[0] = tmp;
+ val->u.array.values[1] = value;
+ rc = 0;
+ break;
+
+ case NWFILTER_VALUE_TYPE_ARRAY:
+ if (VIR_EXPAND_N(val->u.array.values,
+ val->u.array.nValues, 1) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ val->u.array.values[val->u.array.nValues - 1] = value;
+ rc = 0;
+ break;
+
+ case NWFILTER_VALUE_TYPE_LAST:
+ break;
+ }
+
+ return rc;
+}
+
static void
hashDataFree(void *payload, const void *name ATTRIBUTE_UNUSED)
{
- VIR_FREE(payload);
+ virNWFilterVarValueFree(payload);
}
int
virNWFilterHashTablePut(virNWFilterHashTablePtr table,
const char *name,
- char *val,
+ virNWFilterVarValuePtr val,
int copyName)
{
if (!virHashLookup(table->hashTable, name)) {
addToTable(void *payload, const void *name, void *data)
{
struct addToTableStruct *atts = (struct addToTableStruct *)data;
- char *val;
+ virNWFilterVarValuePtr val;
if (atts->errOccurred)
return;
- val = strdup((char *)payload);
+ val = virNWFilterVarValueCopy((virNWFilterVarValuePtr)payload);
if (!val) {
virReportOOMError();
atts->errOccurred = 1;
_("Could not put variable '%s' into hashmap"),
(const char *)name);
atts->errOccurred = 1;
- VIR_FREE(val);
+ virNWFilterVarValueFree(val);
}
}
return value[strspn(value, VALID_VARVALUE)] == 0;
}
+static virNWFilterVarValuePtr
+virNWFilterParseVarValue(const char *val)
+{
+ return virNWFilterVarValueCreateSimpleCopyValue(val);
+}
virNWFilterHashTablePtr
virNWFilterParseParamAttributes(xmlNodePtr cur)
{
char *nam, *val;
+ virNWFilterVarValuePtr value;
virNWFilterHashTablePtr table = virNWFilterHashTableCreate(0);
if (!table) {
if (xmlStrEqual(cur->name, BAD_CAST "parameter")) {
nam = virXMLPropString(cur, "name");
val = virXMLPropString(cur, "value");
+ value = NULL;
if (nam != NULL && val != NULL) {
if (!isValidVarName(nam))
goto skip_entry;
- if (!isValidVarValue(nam))
+ value = virNWFilterParseVarValue(val);
+ if (!value)
goto skip_entry;
- if (virNWFilterHashTablePut(table, nam, val, 1)) {
+ if (virNWFilterHashTablePut(table, nam, value, 1)) {
VIR_FREE(nam);
VIR_FREE(val);
+ virNWFilterVarValueFree(value);
virNWFilterHashTableFree(table);
return NULL;
}
- val = NULL;
+ value = NULL;
}
skip_entry:
+ virNWFilterVarValueFree(value);
VIR_FREE(nam);
VIR_FREE(val);
}
# include "hash.h"
# include "buf.h"
+enum virNWFilterVarValueType {
+ NWFILTER_VALUE_TYPE_SIMPLE,
+ NWFILTER_VALUE_TYPE_ARRAY,
+
+ NWFILTER_VALUE_TYPE_LAST
+};
+
+typedef struct _virNWFilterVarValue virNWFilterVarValue;
+typedef virNWFilterVarValue *virNWFilterVarValuePtr;
+struct _virNWFilterVarValue {
+ enum virNWFilterVarValueType valType;
+ union {
+ struct {
+ char *value;
+ } simple;
+ struct {
+ char **values;
+ size_t nValues;
+ } array;
+ } u;
+};
+
+virNWFilterVarValuePtr virNWFilterVarValueCreateSimple(char *);
+virNWFilterVarValuePtr virNWFilterVarValueCreateSimpleCopyValue(const char *);
+const char *virNWFilterVarValueGetSimple(const virNWFilterVarValuePtr val);
+const char *virNWFilterVarValueGetNthValue(virNWFilterVarValuePtr val,
+ unsigned int idx);
+unsigned int virNWFilterVarValueGetCardinality(const virNWFilterVarValuePtr);
+int virNWFilterVarValueAddValue(virNWFilterVarValuePtr val, char *value);
+
typedef struct _virNWFilterHashTable virNWFilterHashTable;
typedef virNWFilterHashTable *virNWFilterHashTablePtr;
struct _virNWFilterHashTable {
void virNWFilterHashTableFree(virNWFilterHashTablePtr table);
int virNWFilterHashTablePut(virNWFilterHashTablePtr table,
const char *name,
- char *val,
+ virNWFilterVarValuePtr val,
int freeName);
int virNWFilterHashTableRemoveEntry(virNWFilterHashTablePtr table,
const char *name);
char *macaddr,
char *ipaddr)
{
+ virNWFilterVarValue *val;
+
if (macaddr) {
+ val = virNWFilterVarValueCreateSimple(macaddr);
+ if (!val)
+ return 1;
+
if (virHashAddEntry(table->hashTable,
NWFILTER_STD_VAR_MAC,
- macaddr) < 0) {
+ val) < 0) {
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Could not add variable 'MAC' to hashmap"));
return 1;
}
if (ipaddr) {
+ val = virNWFilterVarValueCreateSimple(ipaddr);
+ if (!val)
+ return 1;
+
if (virHashAddEntry(table->hashTable,
NWFILTER_STD_VAR_IP,
- ipaddr) < 0) {
+ val) < 0) {
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Could not add variable 'IP' to hashmap"));
return 1;
int rc = 0;
int i, j;
virNWFilterDefPtr next_filter;
+ virNWFilterVarValuePtr val;
for (i = 0; i < filter->nentries; i++) {
virNWFilterRuleDefPtr rule = filter->filterEntries[i]->rule;
/* check all variables of this rule */
for (j = 0; j < rule->nvars; j++) {
if (!virHashLookup(vars->hashTable, rule->vars[j])) {
+ val = virNWFilterVarValueCreateSimpleCopyValue("1");
+ if (!val) {
+ rc = 1;
+ break;
+ }
virNWFilterHashTablePut(missing_vars, rule->vars[j],
- strdup("1"), 1);
+ val, 1);
}
}
+ if (rc)
+ break;
} else if (inc) {
VIR_DEBUG("Following filter %s\n", inc->filterref);
obj = virNWFilterObjFindByName(&driver->nwfilters, inc->filterref);