[libvirt] [PATCH] nwfilter: enable hex number inputs in filter XML

Stefan Berger stefanb at us.ibm.com
Mon Apr 26 16:44:03 UTC 2010


With this patch I want to enable hex number inputs in the filter XML. A
number that was entered as hex is also printed as hex unless a string
representing the meaning can be found.

I am also extending the schema and adding a test case. A problem with
the DSCP value is fixed on the way as well.

Signed-off-by: Stefan Berger <stefanb at us.ibm.com>

---
 src/conf/nwfilter_conf.c                  |   77 +++++++++++++++++++-----------
 src/conf/nwfilter_conf.h                  |   18 +++----
 src/nwfilter/nwfilter_ebiptables_driver.c |    2 
 3 files changed, 62 insertions(+), 35 deletions(-)

Index: libvirt-acl/src/conf/nwfilter_conf.h
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.h
+++ libvirt-acl/src/conf/nwfilter_conf.h
@@ -83,15 +83,17 @@ enum virNWFilterEntryItemFlags {
 enum attrDatatype {
     DATATYPE_UINT16           = (1 << 0),
     DATATYPE_UINT8            = (1 << 1),
-    DATATYPE_MACADDR          = (1 << 2),
-    DATATYPE_MACMASK          = (1 << 3),
-    DATATYPE_IPADDR           = (1 << 4),
-    DATATYPE_IPMASK           = (1 << 5),
-    DATATYPE_STRING           = (1 << 6),
-    DATATYPE_IPV6ADDR         = (1 << 7),
-    DATATYPE_IPV6MASK         = (1 << 8),
+    DATATYPE_UINT16_HEX       = (1 << 2),
+    DATATYPE_UINT8_HEX        = (1 << 3),
+    DATATYPE_MACADDR          = (1 << 4),
+    DATATYPE_MACMASK          = (1 << 5),
+    DATATYPE_IPADDR           = (1 << 6),
+    DATATYPE_IPMASK           = (1 << 7),
+    DATATYPE_STRING           = (1 << 8),
+    DATATYPE_IPV6ADDR         = (1 << 9),
+    DATATYPE_IPV6MASK         = (1 << 10),
 
-    DATATYPE_LAST             = (1 << 9),
+    DATATYPE_LAST             = (1 << 11),
 };
 
 
Index: libvirt-acl/src/conf/nwfilter_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.c
+++ libvirt-acl/src/conf/nwfilter_conf.c
@@ -415,7 +415,9 @@ checkMacProtocolID(enum attrDatatype dat
     if (datatype == DATATYPE_STRING) {
         if (intMapGetByString(macProtoMap, (char *)value, 1, &res) == 0)
             res = -1;
-    } else if (datatype == DATATYPE_UINT16) {
+        datatype = DATATYPE_UINT16;
+    } else if (datatype == DATATYPE_UINT16 ||
+               datatype == DATATYPE_UINT16_HEX) {
         res = (uint32_t)*(uint16_t *)value;
         if (res < 0x600)
             res = -1;
@@ -423,7 +425,7 @@ checkMacProtocolID(enum attrDatatype dat
 
     if (res != -1) {
         nwf->p.ethHdrFilter.dataProtocolID.u.u16 = res;
-        nwf->p.ethHdrFilter.dataProtocolID.datatype = DATATYPE_UINT16;
+        nwf->p.ethHdrFilter.dataProtocolID.datatype = datatype;
         return 1;
     }
 
@@ -436,13 +438,17 @@ macProtocolIDFormatter(virBufferPtr buf,
                        virNWFilterRuleDefPtr nwf)
 {
     const char *str = NULL;
+    const char *format = "0x%x";
 
     if (intMapGetByInt(macProtoMap,
                        nwf->p.ethHdrFilter.dataProtocolID.u.u16,
                        &str)) {
         virBufferVSprintf(buf, "%s", str);
     } else {
-        virBufferVSprintf(buf, "%d", nwf->p.ethHdrFilter.dataProtocolID.u.u16);
+        if (nwf->p.ethHdrFilter.dataProtocolID.datatype == DATATYPE_UINT16)
+            format = "%d";
+        virBufferVSprintf(buf, format,
+                          nwf->p.ethHdrFilter.dataProtocolID.u.u16);
     }
     return 1;
 }
@@ -513,13 +519,15 @@ arpOpcodeValidator(enum attrDatatype dat
     if (datatype == DATATYPE_STRING) {
         if (intMapGetByString(arpOpcodeMap, (char *)value, 1, &res) == 0)
             res = -1;
-    } else if (datatype == DATATYPE_UINT16) {
+        datatype = DATATYPE_UINT16;
+    } else if (datatype == DATATYPE_UINT16 ||
+               datatype == DATATYPE_UINT16_HEX) {
         res = (uint32_t)*(uint16_t *)value;
     }
 
     if (res != -1) {
         nwf->p.arpHdrFilter.dataOpcode.u.u16 = res;
-        nwf->p.arpHdrFilter.dataOpcode.datatype = DATATYPE_UINT16;
+        nwf->p.arpHdrFilter.dataOpcode.datatype = datatype;
         return 1;
     }
     return 0;
@@ -570,13 +578,15 @@ static bool checkIPProtocolID(enum attrD
     if (datatype == DATATYPE_STRING) {
         if (intMapGetByString(ipProtoMap, (char *)value, 1, &res) == 0)
             res = -1;
-    } else if (datatype == DATATYPE_UINT8) {
+        datatype = DATATYPE_UINT8_HEX;
+    } else if (datatype == DATATYPE_UINT8 ||
+               datatype == DATATYPE_UINT8_HEX) {
         res = (uint32_t)*(uint16_t *)value;
     }
 
     if (res != -1) {
         nwf->p.ipHdrFilter.ipHdr.dataProtocolID.u.u8 = res;
-        nwf->p.ipHdrFilter.ipHdr.dataProtocolID.datatype = DATATYPE_UINT8;
+        nwf->p.ipHdrFilter.ipHdr.dataProtocolID.datatype = datatype;
         return 1;
     }
     return 0;
@@ -588,13 +598,16 @@ formatIPProtocolID(virBufferPtr buf,
                    virNWFilterRuleDefPtr nwf)
 {
     const char *str = NULL;
+    const char *format = "0x%x";
 
     if (intMapGetByInt(ipProtoMap,
                        nwf->p.ipHdrFilter.ipHdr.dataProtocolID.u.u8,
                        &str)) {
         virBufferVSprintf(buf, "%s", str);
     } else {
-        virBufferVSprintf(buf, "%d",
+        if (nwf->p.ipHdrFilter.ipHdr.dataProtocolID.datatype == DATATYPE_UINT8)
+            format = "%d";
+        virBufferVSprintf(buf, format,
                           nwf->p.ipHdrFilter.ipHdr.dataProtocolID.u.u8);
     }
     return 1;
@@ -602,15 +615,14 @@ formatIPProtocolID(virBufferPtr buf,
 
 
 static bool
-dscpValidator(enum attrDatatype datatype ATTRIBUTE_UNUSED, void *val,
+dscpValidator(enum attrDatatype datatype, void *val,
               virNWFilterRuleDefPtr nwf)
 {
     uint8_t dscp = *(uint16_t *)val;
     if (dscp > 63)
         return 0;
 
-    nwf->p.ipHdrFilter.ipHdr.dataDSCP.u.u8 = dscp;
-    nwf->p.ipHdrFilter.ipHdr.dataDSCP.datatype = DATATYPE_UINT8;
+    nwf->p.ipHdrFilter.ipHdr.dataDSCP.datatype = datatype;
 
     return 1;
 }
@@ -642,7 +654,7 @@ static const virXMLAttr2Struct macAttrib
     COMMON_MAC_PROPS(ethHdrFilter),
     {
         .name = "protocolid",
-        .datatype = DATATYPE_UINT16 | DATATYPE_STRING,
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX | DATATYPE_STRING,
         .dataIdx = offsetof(virNWFilterRuleDef, p.ethHdrFilter.dataProtocolID),
         .validator= checkMacProtocolID,
         .formatter= macProtocolIDFormatter,
@@ -656,15 +668,15 @@ static const virXMLAttr2Struct arpAttrib
     COMMON_MAC_PROPS(arpHdrFilter),
     {
         .name = "hwtype",
-        .datatype = DATATYPE_UINT16,
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.arpHdrFilter.dataHWType),
     }, {
         .name = "protocoltype",
-        .datatype = DATATYPE_UINT16,
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.arpHdrFilter.dataProtocolType),
     }, {
         .name = "opcode",
-        .datatype = DATATYPE_UINT16 | DATATYPE_STRING,
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX | DATATYPE_STRING,
         .dataIdx = offsetof(virNWFilterRuleDef, p.arpHdrFilter.dataOpcode),
         .validator= arpOpcodeValidator,
         .formatter= arpOpcodeFormatter,
@@ -714,34 +726,34 @@ static const virXMLAttr2Struct ipAttribu
     },
     {
         .name = "protocol",
-        .datatype = DATATYPE_STRING | DATATYPE_UINT8,
+        .datatype = DATATYPE_STRING | DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.ipHdrFilter.ipHdr.dataProtocolID),
         .validator= checkIPProtocolID,
         .formatter= formatIPProtocolID,
     },
     {
         .name = SRCPORTSTART,
-        .datatype = DATATYPE_UINT16,
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.ipHdrFilter.portData.dataSrcPortStart),
     },
     {
         .name = SRCPORTEND,
-        .datatype = DATATYPE_UINT16,
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.ipHdrFilter.portData.dataSrcPortEnd),
     },
     {
         .name = DSTPORTSTART,
-        .datatype = DATATYPE_UINT16,
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.ipHdrFilter.portData.dataDstPortStart),
     },
     {
         .name = DSTPORTEND,
-        .datatype = DATATYPE_UINT16,
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.ipHdrFilter.portData.dataDstPortEnd),
     },
     {
         .name = DSCP,
-        .datatype = DATATYPE_UINT8,
+        .datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.ipHdrFilter.ipHdr.dataDSCP),
         .validator = dscpValidator,
     },
@@ -775,29 +787,29 @@ static const virXMLAttr2Struct ipv6Attri
     },
     {
         .name = "protocol",
-        .datatype = DATATYPE_STRING | DATATYPE_UINT8,
+        .datatype = DATATYPE_STRING | DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.ipHdr.dataProtocolID),
         .validator= checkIPProtocolID,
         .formatter= formatIPProtocolID,
     },
     {
         .name = SRCPORTSTART,
-        .datatype = DATATYPE_UINT16,
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.portData.dataSrcPortStart),
     },
     {
         .name = SRCPORTEND,
-        .datatype = DATATYPE_UINT16,
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.portData.dataSrcPortEnd),
     },
     {
         .name = DSTPORTSTART,
-        .datatype = DATATYPE_UINT16,
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.portData.dataDstPortStart),
     },
     {
         .name = DSTPORTEND,
-        .datatype = DATATYPE_UINT16,
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.portData.dataDstPortEnd),
     },
     {
@@ -857,9 +869,9 @@ static const virXMLAttr2Struct ipv6Attri
     },\
     {\
         .name = DSCP,\
-        .datatype = DATATYPE_UINT8,\
+        .datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,\
         .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDSCP),\
-        /*.validator = dscpValidator,*/\
+        .validator = dscpValidator,\
     },\
     {\
         .name = "connlimit-above",\
@@ -870,22 +882,22 @@ static const virXMLAttr2Struct ipv6Attri
 #define COMMON_PORT_PROPS(STRUCT) \
     {\
         .name = SRCPORTSTART,\
-        .datatype = DATATYPE_UINT16,\
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,\
         .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.portData.dataSrcPortStart),\
     },\
     {\
         .name = SRCPORTEND,\
-        .datatype = DATATYPE_UINT16,\
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,\
         .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.portData.dataSrcPortEnd),\
     },\
     {\
         .name = DSTPORTSTART,\
-        .datatype = DATATYPE_UINT16,\
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,\
         .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.portData.dataDstPortStart),\
     },\
     {\
         .name = DSTPORTEND,\
-        .datatype = DATATYPE_UINT16,\
+        .datatype = DATATYPE_UINT16 | DATATYPE_UINT16_HEX,\
         .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.portData.dataDstPortEnd),\
     }
 
@@ -894,7 +906,7 @@ static const virXMLAttr2Struct tcpAttrib
     COMMON_PORT_PROPS(tcpHdrFilter),
     {
         .name = "option",
-        .datatype = DATATYPE_UINT8,
+        .datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.tcpHdrFilter.dataTCPOption),
     },
     {
@@ -944,12 +956,12 @@ static const virXMLAttr2Struct icmpAttri
     COMMON_IP_PROPS(icmpHdrFilter, DATATYPE_IPADDR, DATATYPE_IPMASK),
     {
         .name = "type",
-        .datatype = DATATYPE_UINT8,
+        .datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.icmpHdrFilter.dataICMPType),
     },
     {
         .name = "code",
-        .datatype = DATATYPE_UINT8,
+        .datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.icmpHdrFilter.dataICMPCode),
     },
     {
@@ -979,7 +991,7 @@ static const virXMLAttr2Struct tcpipv6At
     COMMON_PORT_PROPS(tcpHdrFilter),
     {
         .name = "option",
-        .datatype = DATATYPE_UINT8,
+        .datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.tcpHdrFilter.dataTCPOption),
     },
     {
@@ -1033,12 +1045,12 @@ static const virXMLAttr2Struct icmpv6Att
     COMMON_IP_PROPS(icmpHdrFilter, DATATYPE_IPV6ADDR, DATATYPE_IPV6MASK),
     {
         .name = "type",
-        .datatype = DATATYPE_UINT8,
+        .datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.icmpHdrFilter.dataICMPType),
     },
     {
         .name = "code",
-        .datatype = DATATYPE_UINT8,
+        .datatype = DATATYPE_UINT8 | DATATYPE_UINT8_HEX,
         .dataIdx = offsetof(virNWFilterRuleDef, p.icmpHdrFilter.dataICMPCode),
     },
     {
@@ -1142,6 +1154,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
     valueValidator validator;
     char *match = virXMLPropString(node, "match");
     nwIPAddress ipaddr;
+    int base;
 
     if (match && STREQ(match, "no"))
         match_flag = NWFILTER_ENTRY_ITEM_FLAG_IS_NEG;
@@ -1182,14 +1195,16 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
 
                     validator = att[idx].validator;
 
-                    switch (datatype) {
+                    base = 10;
 
+                    switch (datatype) {
+                        case DATATYPE_UINT8_HEX:
+                            base = 16;
                         case DATATYPE_UINT8:
                             storage_ptr = &item->u.u8;
-                            if (virStrToLong_ui(prop, NULL, 10, &uint_val) >= 0) {
+                            if (virStrToLong_ui(prop, NULL, base, &uint_val) >= 0) {
                                 if (uint_val <= 0xff) {
-                                    if (!validator)
-                                        *(uint8_t *)storage_ptr = uint_val;
+                                    *(uint8_t *)storage_ptr = uint_val;
                                     found = 1;
                                     data_ptr = &uint_val;
                                 } else
@@ -1198,12 +1213,13 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
                                 rc = -1;
                         break;
 
+                        case DATATYPE_UINT16_HEX:
+                            base = 16;
                         case DATATYPE_UINT16:
                             storage_ptr = &item->u.u16;
-                            if (virStrToLong_ui(prop, NULL, 10, &uint_val) >= 0) {
+                            if (virStrToLong_ui(prop, NULL, base, &uint_val) >= 0) {
                                 if (uint_val <= 0xffff) {
-                                    if (!validator)
-                                        *(uint16_t *)storage_ptr = uint_val;
+                                    *(uint16_t *)storage_ptr = uint_val;
                                     found = 1;
                                     data_ptr = &uint_val;
                                 } else
@@ -2380,6 +2396,7 @@ virNWFilterRuleDefDetailsFormat(virBuffe
     int i = 0, j;
     bool typeShown = 0;
     bool neverShown = 1;
+    const char *format;
     enum match {
         MATCH_NONE = 0,
         MATCH_YES,
@@ -2431,19 +2448,25 @@ virNWFilterRuleDefDetailsFormat(virBuffe
             } else if ((flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
                 virBufferVSprintf(buf, "$%s", item->var);
             } else {
-               switch (att[i].datatype) {
+               format = "%d";
+
+               switch (item->datatype) {
 
+               case DATATYPE_UINT8_HEX:
+                   format = "0x%x";
                case DATATYPE_IPMASK:
                case DATATYPE_IPV6MASK:
                    // display all masks in CIDR format
                case DATATYPE_UINT8:
                    storage_ptr = &item->u.u8;
-                   virBufferVSprintf(buf, "%d", *(uint8_t *)storage_ptr);
+                   virBufferVSprintf(buf, format, *(uint8_t *)storage_ptr);
                break;
 
+               case DATATYPE_UINT16_HEX:
+                   format = "0x%x";
                case DATATYPE_UINT16:
                    storage_ptr = &item->u.u16;
-                   virBufferVSprintf(buf, "%d", *(uint16_t *)storage_ptr);
+                   virBufferVSprintf(buf, format, *(uint16_t *)storage_ptr);
                break;
 
                case DATATYPE_IPADDR:
Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -233,6 +233,7 @@ _printDataType(virNWFilterHashTablePtr v
     break;
 
     case DATATYPE_UINT16:
+    case DATATYPE_UINT16_HEX:
         if (snprintf(buf, bufsize, asHex ? "0x%x" : "%d",
                      item->u.u16) >= bufsize) {
             virNWFilterReportError(VIR_ERR_INVALID_NWFILTER, "%s",
@@ -242,6 +243,7 @@ _printDataType(virNWFilterHashTablePtr v
     break;
 
     case DATATYPE_UINT8:
+    case DATATYPE_UINT8_HEX:
         if (snprintf(buf, bufsize, asHex ? "0x%x" : "%d",
                      item->u.u8) >= bufsize) {
             virNWFilterReportError(VIR_ERR_INVALID_NWFILTER, "%s",
Index: libvirt-acl/docs/schemas/nwfilter.rng
===================================================================
--- libvirt-acl.orig/docs/schemas/nwfilter.rng
+++ libvirt-acl/docs/schemas/nwfilter.rng
@@ -656,6 +656,10 @@
 
   <define name="sixbitrange">
     <choice>
+      <data type="string">
+        <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>
@@ -675,6 +679,10 @@
         <param name="pattern">$[a-zA-Z0-9_]+</param>
       </data>
 
+      <data type="string">
+        <param name="pattern">0x([6-9a-fA-F][0-9a-fA-F]{2}|[0-9a-fA-F]{4})</param>
+      </data>
+
       <data type="int">
         <param name="minInclusive">1536</param>
         <param name="maxInclusive">65535</param>
@@ -695,6 +703,10 @@
         <param name="pattern">$[a-zA-Z0-9_]+</param>
       </data>
 
+      <data type="string">
+        <param name="pattern">0x[0-9a-fA-F]{1,2}</param>
+      </data>
+
       <data type="int">
         <param name="minInclusive">0</param>
         <param name="maxInclusive">255</param>
@@ -709,6 +721,10 @@
         <param name="pattern">$[a-zA-Z0-9_]+</param>
       </data>
 
+      <data type="string">
+        <param name="pattern">0x[0-9a-fA-F]{1,4}</param>
+      </data>
+
       <data type="int">
         <param name="minInclusive">0</param>
         <param name="maxInclusive">65535</param>
@@ -742,6 +758,10 @@
         <param name="pattern">$[a-zA-Z0-9_]+</param>
       </data>
 
+      <data type="string">
+        <param name="pattern">0x[0-9a-fA-F]{1,2}</param>
+      </data>
+
       <data type="int">
         <param name="minInclusive">0</param>
         <param name="maxInclusive">255</param>
Index: libvirt-acl/tests/nwfilterxml2xmlin/hex-data-test.xml
===================================================================
--- /dev/null
+++ libvirt-acl/tests/nwfilterxml2xmlin/hex-data-test.xml
@@ -0,0 +1,56 @@
+<filter name='testcase'>
+  <uuid>01a992d2-f8c8-7c27-f69b-ab0a9d377379</uuid>
+
+  <rule action='accept' direction='in'>
+    <mac protocolid='0x1234'/>
+  </rule>
+
+  <rule action='accept' direction='out'>
+     <ip  srcmacaddr='1:2:3:4:5:6' srcmacmask='ff:ff:ff:ff:ff:ff'
+          dstmacaddr='aa:bb:cc:dd:ee:ff' dstmacmask='ff:ff:ff:ff:ff:ff'
+          srcipaddr='10.1.2.3' srcipmask='255.255.255.255'
+          dstipaddr='10.1.2.3' dstipmask='255.255.255.255'
+          protocol='udp'
+          srcportstart='0x123' srcportend='0x234'
+          dstportstart='0x3456' dstportend='0x4567'
+          dscp='0x32'/>
+  </rule>
+
+  <rule action='accept' direction='out'>
+     <ipv6 srcmacaddr='1:2:3:4:5:6' srcmacmask='ff:ff:ff:ff:ff:fe'
+           dstmacaddr='aa:bb:cc:dd:ee:ff' dstmacmask='ff:ff:ff:ff:ff:80'
+           srcipaddr='::10.1.2.3' srcipmask='22'
+           dstipaddr='::10.1.2.3'
+           dstipmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:8000'
+           protocol='tcp'
+           srcportstart='0x111' srcportend='400'
+           dstportstart='0x3333' dstportend='65535'/>
+  </rule>
+
+  <rule action='accept' direction='out'>
+     <arp srcmacaddr='1:2:3:4:5:6' srcmacmask='ff:ff:ff:ff:ff:ff'
+          dstmacaddr='aa:bb:cc:dd:ee:ff' dstmacmask='ff:ff:ff:ff:ff:ff'
+          hwtype='0x12'
+          protocoltype='0x56'
+          opcode='Request'
+          arpsrcmacaddr='1:2:3:4:5:6'
+          arpdstmacaddr='a:b:c:d:e:f'/>
+  </rule>
+
+  <rule action='accept' direction='out'>
+     <udp srcmacaddr='1:2:3:4:5:6'
+          dstipaddr='10.1.2.3' dstipmask='255.255.255.255'
+          dscp='0x22'
+          srcportstart='0x123' srcportend='400'
+          dstportstart='0x234' dstportend='0x444'/>
+  </rule>
+
+  <rule action='accept' direction='in'>
+     <tcp-ipv6 srcmacaddr='1:2:3:4:5:6'
+               srcipaddr='a:b:c::' srcipmask='128'
+               dscp='0x40'
+               srcportstart='0x20' srcportend='0x21'
+               dstportstart='0x100' dstportend='0x1111'/>
+  </rule>
+
+</filter>
Index: libvirt-acl/tests/nwfilterxml2xmltest.c
===================================================================
--- libvirt-acl.orig/tests/nwfilterxml2xmltest.c
+++ libvirt-acl/tests/nwfilterxml2xmltest.c
@@ -122,6 +122,8 @@ mymain(int argc, char **argv)
 
     DO_TEST("conntrack-test");
 
+    DO_TEST("hex-data-test");
+
     return (ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
 }
 
Index: libvirt-acl/tests/nwfilterxml2xmlout/hex-data-test.xml
===================================================================
--- /dev/null
+++ libvirt-acl/tests/nwfilterxml2xmlout/hex-data-test.xml
@@ -0,0 +1,21 @@
+<filter name='testcase' chain='root'>
+  <uuid>01a992d2-f8c8-7c27-f69b-ab0a9d377379</uuid>
+  <rule action='accept' direction='in' priority='500'>
+    <mac protocolid='0x1234'/>
+  </rule>
+  <rule action='accept' direction='out' priority='500'>
+    <ip srcmacaddr='01:02:03:04:05:06' srcmacmask='ff:ff:ff:ff:ff:ff' dstmacaddr='aa:bb:cc:dd:ee:ff' dstmacmask='ff:ff:ff:ff:ff:ff' srcipaddr='10.1.2.3' srcipmask='32' dstipaddr='10.1.2.3' dstipmask='32' protocol='udp' srcportstart='0x123' srcportend='0x234' dstportstart='0x3456' dstportend='0x4567' dscp='0x32'/>
+  </rule>
+  <rule action='accept' direction='out' priority='500'>
+    <ipv6 srcmacaddr='01:02:03:04:05:06' srcmacmask='ff:ff:ff:ff:ff:fe' dstmacaddr='aa:bb:cc:dd:ee:ff' dstmacmask='ff:ff:ff:ff:ff:80' srcipaddr='::10.1.2.3' srcipmask='22' dstipaddr='::10.1.2.3' dstipmask='113' protocol='tcp' srcportstart='0x111' srcportend='400' dstportstart='0x3333' dstportend='65535'/>
+  </rule>
+  <rule action='accept' direction='out' priority='500'>
+    <arp srcmacaddr='01:02:03:04:05:06' srcmacmask='ff:ff:ff:ff:ff:ff' dstmacaddr='aa:bb:cc:dd:ee:ff' dstmacmask='ff:ff:ff:ff:ff:ff' hwtype='0x12' protocoltype='0x56' opcode='Request' arpsrcmacaddr='01:02:03:04:05:06' arpdstmacaddr='0a:0b:0c:0d:0e:0f'/>
+  </rule>
+  <rule action='accept' direction='out' priority='500'>
+    <udp srcmacaddr='01:02:03:04:05:06' dstipaddr='10.1.2.3' dstipmask='32' dscp='0x22' srcportstart='0x123' srcportend='400' dstportstart='0x234' dstportend='0x444'/>
+  </rule>
+  <rule action='accept' direction='in' priority='500'>
+    <tcp-ipv6 srcmacaddr='01:02:03:04:05:06' srcipaddr='a:b:c::' srcipmask='128' srcportstart='0x20' srcportend='0x21' dstportstart='0x100' dstportend='0x1111'/>
+  </rule>
+</filter>




More information about the libvir-list mailing list