diff --git a/docs/schemas/nwfilter.rng b/docs/schemas/nwfilter.rng index b9d72760afb0558331889251e951ceca132494ef..c81e410bd1a14602785b6a1d296709eeb7f5eeb7 100644 --- a/docs/schemas/nwfilter.rng +++ b/docs/schemas/nwfilter.rng @@ -312,7 +312,7 @@ - + @@ -321,7 +321,7 @@ - + diff --git a/src/conf/nwfilter_params.c b/src/conf/nwfilter_params.c index c63c807a3395684ac1e015f3f79d3a25e8357e69..2fba3513908bb875ad8e17aff78aa864a2a34f44 100644 --- a/src/conf/nwfilter_params.c +++ b/src/conf/nwfilter_params.c @@ -604,7 +604,7 @@ isValidVarName(const char *var) static bool isValidVarValue(const char *value) { - return value[strspn(value, VALID_VARVALUE)] == 0; + return (value[strspn(value, VALID_VARVALUE)] == 0) && (strlen(value) != 0); } static virNWFilterVarValuePtr @@ -636,15 +636,22 @@ virNWFilterParseParamAttributes(xmlNodePtr cur) if (nam != NULL && val != NULL) { if (!isValidVarName(nam)) goto skip_entry; - value = virNWFilterParseVarValue(val); - if (!value) + if (!isValidVarValue(val)) goto skip_entry; - if (virNWFilterHashTablePut(table, nam, value, 1)) { - VIR_FREE(nam); - VIR_FREE(val); - virNWFilterVarValueFree(value); - virNWFilterHashTableFree(table); - return NULL; + value = virHashLookup(table->hashTable, nam); + if (value) { + /* add value to existing value -> list */ + if (virNWFilterVarValueAddValue(value, val) < 0) { + value = NULL; + goto err_exit; + } + val = NULL; + } else { + value = virNWFilterParseVarValue(val); + if (!value) + goto skip_entry; + if (virNWFilterHashTablePut(table, nam, value, 1)) + goto err_exit; } value = NULL; } @@ -657,39 +664,66 @@ skip_entry: cur = cur->next; } return table; + +err_exit: + VIR_FREE(nam); + VIR_FREE(val); + virNWFilterVarValueFree(value); + virNWFilterHashTableFree(table); + return NULL; } -static void -_formatParameterAttrs(void *payload, const void *name, void *data) +static int +virNWFilterFormatParameterNameSorter(const virHashKeyValuePairPtr a, + const virHashKeyValuePairPtr b) { - virBufferPtr buf = data; - - virBufferAsprintf(buf, " \n", - (const char *)name, - (char *)payload); + return strcmp((const char *)a->key, (const char *)b->key); } - int virNWFilterFormatParamAttributes(virBufferPtr buf, virNWFilterHashTablePtr table, const char *filterref) { - int count = virHashSize(table->hashTable); + virHashKeyValuePairPtr items; + int i, j, card, numKeys; + + numKeys = virHashSize(table->hashTable); - if (count < 0) { + if (numKeys < 0) { virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing filter parameter table")); return -1; } + + items = virHashGetItems(table->hashTable, + virNWFilterFormatParameterNameSorter); + if (!items) + return -1; + virBufferAsprintf(buf, "\n"); - virHashForEach(table->hashTable, _formatParameterAttrs, buf); + for (i = 0; i < numKeys; i++) { + const virNWFilterVarValuePtr value = + (const virNWFilterVarValuePtr)items[i].value; + + card = virNWFilterVarValueGetCardinality(value); + + for (j = 0; j < card; j++) + virBufferAsprintf(buf, + " \n", + (const char *)items[i].key, + virNWFilterVarValueGetNthValue(value, j)); + + } virBufferAddLit(buf, "\n"); } else { virBufferAddLit(buf, "/>\n"); } + + VIR_FREE(items); + return 0; }