[PATCH 2/6] Introduce possiblity to have an iterator per variable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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>

---
 docs/schemas/nwfilter.rng                 |   71 ++------
 src/conf/nwfilter_conf.c                  |   35 ++--
 src/conf/nwfilter_conf.h                  |    6 
 src/conf/nwfilter_params.c                |  239 +++++++++++++++++++++++++++---
 src/conf/nwfilter_params.h                |   38 ++++
 src/libvirt_private.syms                  |    1 
 src/nwfilter/nwfilter_ebiptables_driver.c |   13 +
 src/nwfilter/nwfilter_gentech_driver.c    |    8 -
 8 files changed, 307 insertions(+), 104 deletions(-)

Index: libvirt-iterator/src/conf/nwfilter_conf.h
===================================================================
--- libvirt-iterator.orig/src/conf/nwfilter_conf.h
+++ libvirt-iterator/src/conf/nwfilter_conf.h
@@ -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;
Index: libvirt-iterator/src/conf/nwfilter_conf.c
===================================================================
--- libvirt-iterator.orig/src/conf/nwfilter_conf.c
+++ libvirt-iterator/src/conf/nwfilter_conf.c
@@ -272,13 +272,13 @@ virNWFilterRuleDefFree(virNWFilterRuleDe
     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(virNWFilterRule
                          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) {
-        virReportOOMError();
-        return -1;
-    }
-
-    nwf->vars[nwf->nvars] = strdup(var);
-
-    if (!nwf->vars[nwf->nvars]) {
+    if (VIR_REALLOC_N(nwf->varAccess, nwf->nVarAccess + 1) < 0) {
         virReportOOMError();
         return -1;
     }
 
-    item->var = nwf->vars[nwf->nvars++];
+    nwf->varAccess[nwf->nVarAccess++] = varAccess;
+    item->varAccess = varAccess;
 
     return 0;
 }
@@ -3069,7 +3069,8 @@ virNWFilterRuleDefDetailsFormat(virBuffe
                    goto err_exit;
                }
             } else if ((flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
-                virBufferAsprintf(buf, "$%s", item->var);
+                virBufferAddLit(buf, "$");
+                virNWFilterVarAccessPrint(item->varAccess, buf);
             } else {
                asHex = false;
 
Index: libvirt-iterator/src/conf/nwfilter_params.c
===================================================================
--- libvirt-iterator.orig/src/conf/nwfilter_params.c
+++ libvirt-iterator/src/conf/nwfilter_params.c
@@ -310,10 +310,11 @@ virNWFilterVarCombIterEntryInit(virNWFil
 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 @@ virNWFilterVarCombIterEntryAreUniqueEntr
  */
 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(virNWFilter
     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,177 @@ virNWFilterFormatParamAttributes(virBuff
 
     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) {
+            const char *what = "iterator id";
+            if (dest->accessType == VIR_NWFILTER_VAR_ACCESS_ELEMENT)
+                what = "array index";
+            virNWFilterReportError(VIR_ERR_INVALID_ARG,
+                                   _("Malformatted %s"), what);
+            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;
+}
Index: libvirt-iterator/src/conf/nwfilter_params.h
===================================================================
--- libvirt-iterator.orig/src/conf/nwfilter_params.h
+++ libvirt-iterator/src/conf/nwfilter_params.h
@@ -91,6 +91,38 @@ int virNWFilterHashTablePutAll(virNWFilt
 # 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 */
Index: libvirt-iterator/src/libvirt_private.syms
===================================================================
--- libvirt-iterator.orig/src/libvirt_private.syms
+++ libvirt-iterator/src/libvirt_private.syms
@@ -844,6 +844,7 @@ virNWFilterHashTableFree;
 virNWFilterHashTablePut;
 virNWFilterHashTablePutAll;
 virNWFilterHashTableRemoveEntry;
+virNWFilterVarAccessGetVarName;
 virNWFilterVarCombIterCreate;
 virNWFilterVarCombIterFree;
 virNWFilterVarCombIterGetVarValue;
Index: libvirt-iterator/src/nwfilter/nwfilter_ebiptables_driver.c
===================================================================
--- libvirt-iterator.orig/src/nwfilter/nwfilter_ebiptables_driver.c
+++ libvirt-iterator/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -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;
 
Index: libvirt-iterator/src/nwfilter/nwfilter_gentech_driver.c
===================================================================
--- libvirt-iterator.orig/src/nwfilter/nwfilter_gentech_driver.c
+++ libvirt-iterator/src/nwfilter/nwfilter_gentech_driver.c
@@ -500,14 +500,16 @@ virNWFilterDetermineMissingVarsRec(virNW
         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);
                 }
             }
Index: libvirt-iterator/docs/schemas/nwfilter.rng
===================================================================
--- libvirt-iterator.orig/docs/schemas/nwfilter.rng
+++ libvirt-iterator/docs/schemas/nwfilter.rng
@@ -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>

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]