[libvirt] [PATCH v2] nwfilter: enable hex number inputs in filter XML
by Stefan Berger
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(a)us.ibm.com>
---
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>
14 years, 7 months
[libvirt] [PATCH] nwfilter: enable hex number inputs in filter XML
by Stefan Berger
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(a)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>
14 years, 7 months
[libvirt] Q of Libvirt and Xen
by �������... ����������...
Hi ! sir
I'm newbie of xen and libvirt. I'm practice use libvirt API for control xen on CenOS 5.4 using C language. How can I learn it. I can't found a simple C file for testing libvirt and xen. please suggest me for How can I using libvirt for control xen with C and May I have a example code C for run testing a libvirt.
Thinks. Migkie
_________________________________________________________________
The New Busy think 9 to 5 is a cute idea. Combine multiple calendars with Hotmail.
http://www.windowslive.com/campaign/thenewbusy?tile=multicalendar&ocid=PI...
14 years, 7 months
[libvirt] [PATCH] esx: Distribute generated methods code
by Matthias Bolte
---
src/Makefile.am | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 17b2226..00ab65d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -255,6 +255,8 @@ ESX_DRIVER_SOURCES = \
esx/esx_vmx.c esx/esx_vmx.h
ESX_DRIVER_GENERATED = \
+ esx/esx_vi_methods.generated.c \
+ esx/esx_vi_methods.generated.h \
esx/esx_vi_types.generated.c \
esx/esx_vi_types.generated.h \
esx/esx_vi_types.generated.typedef \
--
1.6.3.3
14 years, 7 months
[libvirt] Libvirt debug API
by Chris Lalancette
Hello,
In response to a lot of the talk of qemud lately on qemu-devel, the
libvirt community would like to put forward a proposal to help enable
debug/advanced options when using various hypervisors. The goals of
this API are:
1) To enable more rapid access to hypervisor features before proper
libvirt API's are designed around them.
2) To facilitate debugging and access to advanced features that may
not fit into the normal libvirt world-view.
Caveats:
1) Unlike other libvirt API's, this one will explicitly *not* be
guaranteed ABI/API compatible between libvirt updates.
2) Again unlike other libvirt API's, access and configuration of
the debug section of a domain will be highly hypervisor dependent.
3) Application developers will be strongly discouraged from using
this API because of the above 2 issues. To help in this, the
API's will be in a separate library that developers will explicitly
have to link to, and it will have a different (but largely compatible)
wire protocol.
4) We don't expect this API to solve all of the issues brought up
during the qemud discussion. Our initial goal is just to give
ready access of the qemu command-line and monitor to developers.
With that being said, our initial proposal follows. We expect this
to evolve over time as we get more feedback, but we think this
proposal addresses at least 2 of the major pain points qemu developers
have while trying to use libvirt.
The initial debug XML for qemu would be:
<domain type='kvm'>
<name>myguest</name>
...
<debug>
<monitorpassthrough/>
<commandline>
<extra>qemu arguments</extra>
<alter option="optname">
<rename>newname</rename>
<match>REGEXP</match>
<modify>foo=on</modify>
<extra>-bar</extra>
</alter>
</commandline>
</debug>
</domain>
Raw access to the qemu monitor will be disabled by default; the
<monitorpassthrough/> tag enables the ability to send QMP (or
text, if you are using older qemu) messages straight through to the
monitor. To do this there will be an additional API entry point
named virDomainDebugCommand() which takes an arbitrary string
and passes it to the monitor, and returns an arbitrary string as
a result. Thus you could pass in either "info cpus" if using the
text monitor or '{ "execute": "query-cpus" }' if using QMP.
The <commandline><extra> tag does exactly what you might expect; appends
the exact string to the qemu command-line.
The <alter> tag gets more interesting. The idea is that <alter> would
allow you to modify the libvirt-generated qemu command-line in arbitrary
ways. How this would work is probably best explained with some examples:
<commandline>
<alter option="-net">
<rename>-netdev</rename>
</alter>
</commandline>
In this example, all options named -net on the qemu command-line are
renamed to -netdev.
<commandline>
<alter option="-net">
<extra>-usbtablet</extra>
</alter>
</commandline>
In this example, if (and only if) a -net option is seen, then -usbtablet is
appended to the qemu command-line.
<commandline>
<alter option="-net">
<match>\(.*name=hostnet0.*\)</match>
<modify>\1,tap</modify>
</alter>
</commandline>
This gets more complicated (but also more powerful). In this case, any -net
option where the argument *also* matches the regex in <match> will be modified to append
the ",tap" string. Think of it as a sed expression, s/match/modify/, against the
argument to the -net option, and it makes more sense.
We are hoping to refine this proposal based on feedback, so comments and criticisms
are welcome!
--
Chris Lalancette
14 years, 7 months
[libvirt] [PATCH] fix make dist, ESX method generated files missing
by Daniel Veillard
it was missing the new ESX method generated files, leading to a failure
to build the resulting tarball, so I commited this simple fix,
Daniel
diff --git a/src/Makefile.am b/src/Makefile.am
index 6435f01..fc64927 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -256,6 +256,8 @@ ESX_DRIVER_SOURCES = \
esx/esx_vmx.c esx/esx_vmx.h
ESX_DRIVER_GENERATED = \
+ esx/esx_vi_methods.generated.c \
+ esx/esx_vi_methods.generated.h \
esx/esx_vi_types.generated.c \
esx/esx_vi_types.generated.h \
esx/esx_vi_types.generated.typedef \
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
14 years, 7 months
[libvirt] [PATCH 0/1] port profile id
by David Allan
The following proof of concept patch attempts to show how we might support the use of port profile IDs. The ID would be associated with an interface on a VM and provided to the network infrastructure at VM start time. Since the interfaces by which the id can be provided are still in flux, the use function is only a stub.
Dave
David Allan (1):
Initial POC of port profile id support
docs/schemas/domain.rng | 8 ++++++++
src/conf/domain_conf.c | 12 ++++++++++++
src/conf/domain_conf.h | 1 +
src/libvirt_private.syms | 3 +++
src/qemu/qemu_conf.c | 12 ++++++++++++
src/util/macvtap.c | 13 +++++++++++++
src/util/macvtap.h | 4 ++++
7 files changed, 53 insertions(+), 0 deletions(-)
14 years, 7 months
[libvirt] virsh is not working for other than root users.
by Kumar L Srikanth-B22348
Hi,
I am using libvirt 0.8.0 on Fedora 32 bit system.
When I issue "virsh -c lxc:///" with root permissions I m able to see
'virsh' console.
But, if I changed to other user say "su srikanth", and issue the same
command, I am not able to see the virsh console. I am getting
"authentication failed" error.
Can anybody please help me in solving the issue?
Regards,
Srikanth.
14 years, 7 months
[libvirt] Question on xm and virsh listing
by Nandini Chandra
I'd like to understand the exact mechanism for retrieving the list of
guests by xm/xend and virsh/libvirt.In what situations could the output
of 'xm list' differ from 'virsh list'?Which of these two is more accurate?
I'd appreciate any pointers.
Thanks.
14 years, 7 months
[libvirt] libvir and VDE
by Erik de Castro Lopo
Hi all,
I am currently looking at looking at virsh to mamange my kvm and
qemu VMs, but find that libvir doesn't support VDE networking which
I prefer over other networking options.
An obvious first step to adding support for VDE networking would
be to allow the domxml-from-native subcommand to parse "-net vde"
arguments like:
-net vde,vlan=0,group=vde2-net,mode=0770,sock=/var/run/qemu-vde-ctl
Apart from that, what else is required to support VDE networks in
libvir?
Cheers,
Erik
--
----------------------------------------------------------------------
Erik de Castro Lopo
http://www.mega-nerd.com/
14 years, 7 months