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. Changes from V1 to V2: - using asHex boolean in all printf type of functions to select the output format in hex or decimal format Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx> --- docs/schemas/nwfilter.rng | 20 ++++ src/conf/nwfilter_conf.c | 121 +++++++++++++++++------------ src/conf/nwfilter_conf.h | 18 ++-- src/nwfilter/nwfilter_ebiptables_driver.c | 2 tests/nwfilterxml2xmlin/hex-data-test.xml | 56 +++++++++++++ tests/nwfilterxml2xmlout/hex-data-test.xml | 21 +++++ tests/nwfilterxml2xmltest.c | 2 7 files changed, 184 insertions(+), 56 deletions(-) Index: libvirt-acl/src/conf/nwfilter_conf.h =================================================================== --- libvirt-acl.orig/src/conf/nwfilter_conf.h +++ libvirt-acl/src/conf/nwfilter_conf.h @@ -65,15 +65,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 @@ -430,7 +430,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; @@ -438,7 +440,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; } @@ -451,13 +453,17 @@ macProtocolIDFormatter(virBufferPtr buf, virNWFilterRuleDefPtr nwf) { const char *str = NULL; + bool asHex = true; 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) + asHex = false; + virBufferVSprintf(buf, asHex ? "0x%x" : "%d", + nwf->p.ethHdrFilter.dataProtocolID.u.u16); } return 1; } @@ -528,13 +534,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; @@ -585,13 +593,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; @@ -603,13 +613,16 @@ formatIPProtocolID(virBufferPtr buf, virNWFilterRuleDefPtr nwf) { const char *str = NULL; + bool asHex = true; 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) + asHex = false; + virBufferVSprintf(buf, asHex ? "0x%x" : "%d", nwf->p.ipHdrFilter.ipHdr.dataProtocolID.u.u8); } return 1; @@ -617,15 +630,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; } @@ -657,7 +669,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, @@ -671,15 +683,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, @@ -729,34 +741,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, }, @@ -790,29 +802,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), }, { @@ -872,9 +884,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",\ @@ -885,22 +897,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),\ } @@ -909,7 +921,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), }, { @@ -959,12 +971,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), }, { @@ -994,7 +1006,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), }, { @@ -1048,12 +1060,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), }, { @@ -1156,6 +1168,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; @@ -1196,14 +1209,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 @@ -1212,12 +1227,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 @@ -2393,6 +2409,7 @@ virNWFilterRuleDefDetailsFormat(virBuffe int i = 0, j; bool typeShown = 0; bool neverShown = 1; + bool asHex; enum match { MATCH_NONE = 0, MATCH_YES, @@ -2444,19 +2461,27 @@ virNWFilterRuleDefDetailsFormat(virBuffe } else if ((flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) { virBufferVSprintf(buf, "$%s", item->var); } else { - switch (att[i].datatype) { + asHex = false; + + switch (item->datatype) { + case DATATYPE_UINT8_HEX: + asHex = true; 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, asHex ? "0x%x" : "%d", + *(uint8_t *)storage_ptr); break; + case DATATYPE_UINT16_HEX: + asHex = true; case DATATYPE_UINT16: storage_ptr = &item->u.u16; - virBufferVSprintf(buf, "%d", *(uint16_t *)storage_ptr); + virBufferVSprintf(buf, asHex ? "0x%x" : "%d", + *(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 @@ -215,6 +215,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", @@ -224,6 +225,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 @@ -647,6 +647,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> @@ -666,6 +670,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> @@ -686,6 +694,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> @@ -700,6 +712,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> @@ -733,6 +749,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 @@ -121,6 +121,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> -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list