nwfilter: enable hex number inputs in filter XML

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
This commit is contained in:
Stefan Berger 2010-04-26 13:50:40 -04:00
parent 8fa9c22142
commit 5c7c755f50
7 changed files with 184 additions and 56 deletions

View File

@ -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>

View File

@ -430,7 +430,9 @@ checkMacProtocolID(enum attrDatatype datatype, void *value,
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 datatype, void *value,
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 datatype,
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 attrDatatype datatype,
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 macAttributes[] = {
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 arpAttributes[] = {
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 ipAttributes[] = {
},
{
.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 ipv6Attributes[] = {
},
{
.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 ipv6Attributes[] = {
},\
{\
.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 ipv6Attributes[] = {
#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 tcpAttributes[] = {
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 icmpAttributes[] = {
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 tcpipv6Attributes[] = {
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 icmpv6Attributes[] = {
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 node,
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 node,
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 node,
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(virBufferPtr buf,
int i = 0, j;
bool typeShown = 0;
bool neverShown = 1;
bool asHex;
enum match {
MATCH_NONE = 0,
MATCH_YES,
@ -2444,19 +2461,27 @@ virNWFilterRuleDefDetailsFormat(virBufferPtr buf,
} 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:

View File

@ -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),
};

View File

@ -215,6 +215,7 @@ _printDataType(virNWFilterHashTablePtr vars,
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 vars,
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",

View File

@ -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>

View File

@ -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>

View File

@ -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);
}