Either one of the following patches fixes a bug appearing on big
endian machines where the returned XML is not the one that is expected
(see test/nwfilterxml2xmltest). The problem is due to for example the
casting of a pointers to unsigned integers to void * and then back to 16
bit integers.
I have prepared 2 different solutions for the problem. I think the one
with the union is the better one, which I am posting before the shorted
solution. Both solutions make the nwfilterxml2xmltest pass on a ppc64
machine.
Signed-off-by: Stefan Berger <stefanb(a)us.ibm.com>
Index: libvirt-acl/src/conf/nwfilter_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.c
+++ libvirt-acl/src/conf/nwfilter_conf.c
@@ -379,9 +379,14 @@ virNWFilterPoolObjRemove(virNWFilterPool
}
}
+union data {
+ void *v;
+ char *c;
+ unsigned char *uc;
+ unsigned int ui;
+};
-
-typedef bool (*valueValidator)(enum attrDatatype datatype, void *valptr,
+typedef bool (*valueValidator)(enum attrDatatype datatype, union data
*valptr,
virNWFilterRuleDefPtr nwf);
typedef bool (*valueFormatter)(virBufferPtr buf,
virNWFilterRuleDefPtr nwf);
@@ -407,18 +412,18 @@ static const struct int_map macProtoMap[
static bool
-checkMacProtocolID(enum attrDatatype datatype, void *value,
+checkMacProtocolID(enum attrDatatype datatype, union data *value,
virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED)
{
int32_t res = -1;
if (datatype == DATATYPE_STRING) {
- if (intMapGetByString(macProtoMap, (char *)value, 1, &res) == 0)
+ if (intMapGetByString(macProtoMap, value->c, 1, &res) == 0)
res = -1;
datatype = DATATYPE_UINT16;
} else if (datatype == DATATYPE_UINT16 ||
datatype == DATATYPE_UINT16_HEX) {
- res = (uint32_t)*(uint16_t *)value;
+ res = value->ui;
if (res < 0x600)
res = -1;
}
@@ -485,10 +490,10 @@ checkValidMask(unsigned char *data, int
static bool
checkMACMask(enum attrDatatype datatype ATTRIBUTE_UNUSED,
- void *macMask,
+ union data *macMask,
virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED)
{
- return checkValidMask((unsigned char *)macMask, 6);
+ return checkValidMask(macMask->uc, 6);
}
@@ -511,18 +516,18 @@ static const struct int_map arpOpcodeMap
static bool
arpOpcodeValidator(enum attrDatatype datatype,
- void *value,
+ union data *value,
virNWFilterRuleDefPtr nwf)
{
int32_t res = -1;
if (datatype == DATATYPE_STRING) {
- if (intMapGetByString(arpOpcodeMap, (char *)value, 1, &res) == 0)
+ if (intMapGetByString(arpOpcodeMap, value->c, 1, &res) == 0)
res = -1;
datatype = DATATYPE_UINT16;
} else if (datatype == DATATYPE_UINT16 ||
datatype == DATATYPE_UINT16_HEX) {
- res = (uint32_t)*(uint16_t *)value;
+ res = (uint32_t)value->ui;
}
if (res != -1) {
@@ -570,18 +575,18 @@ static const struct int_map ipProtoMap[]
static bool checkIPProtocolID(enum attrDatatype datatype,
- void *value,
+ union data *value,
virNWFilterRuleDefPtr nwf)
{
int32_t res = -1;
if (datatype == DATATYPE_STRING) {
- if (intMapGetByString(ipProtoMap, (char *)value, 1, &res) == 0)
+ if (intMapGetByString(ipProtoMap, value->c, 1, &res) == 0)
res = -1;
datatype = DATATYPE_UINT8_HEX;
} else if (datatype == DATATYPE_UINT8 ||
datatype == DATATYPE_UINT8_HEX) {
- res = (uint32_t)*(uint16_t *)value;
+ res = (uint32_t)value->ui;
}
if (res != -1) {
@@ -615,10 +620,10 @@ formatIPProtocolID(virBufferPtr buf,
static bool
-dscpValidator(enum attrDatatype datatype, void *val,
+dscpValidator(enum attrDatatype datatype, union data *val,
virNWFilterRuleDefPtr nwf)
{
- uint8_t dscp = *(uint16_t *)val;
+ uint8_t dscp = val->ui;
if (dscp > 63)
return 0;
@@ -1150,7 +1155,8 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
nwItemDesc *item;
int int_val;
unsigned int uint_val;
- void *data_ptr = NULL, *storage_ptr;
+ void *storage_ptr;
+ union data data;
valueValidator validator;
char *match = virXMLPropString(node, "match");
nwIPAddress ipaddr;
@@ -1206,7 +1212,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
if (uint_val <= 0xff) {
*(uint8_t *)storage_ptr = uint_val;
found = 1;
- data_ptr = &uint_val;
+ data.ui = uint_val;
} else
rc = -1;
} else
@@ -1221,7 +1227,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
if (uint_val <= 0xffff) {
*(uint16_t *)storage_ptr = uint_val;
found = 1;
- data_ptr = &uint_val;
+ data.ui = uint_val;
} else
rc = -1;
} else
@@ -1245,7 +1251,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
*(uint8_t *)storage_ptr =
(uint8_t)uint_val;
found = 1;
- data_ptr = &uint_val;
+ data.ui = uint_val;
} else
rc = -1;
} else {
@@ -1278,7 +1284,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
(nwMACAddressPtr)storage_ptr)) {
rc = -1;
}
- data_ptr = storage_ptr;
+ data.v = storage_ptr;
found = 1;
break;
@@ -1299,7 +1305,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
*(uint8_t *)storage_ptr =
(uint8_t)uint_val;
found = 1;
- data_ptr = &uint_val;
+ data.ui = uint_val;
} else
rc = -1;
} else {
@@ -1322,7 +1328,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
rc = -1;
break;
}
- data_ptr = prop;
+ data.c = prop;
found = 1;
break;
@@ -1344,7 +1350,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
*flags = NWFILTER_ENTRY_ITEM_FLAG_EXISTS | flags_set;
item->datatype = datatype >> 1;
if (validator) {
- if (!validator(datatype >> 1, data_ptr, nwf)) {
+ if (!validator(datatype >> 1, &data, nwf)) {
rc = -1;
*flags = 0;
}
=============== 2nd solution =================
Index: libvirt-acl/src/conf/nwfilter_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.c
+++ libvirt-acl/src/conf/nwfilter_conf.c
@@ -181,6 +181,8 @@ static const char dscp_str[] = "
#define DSCP dscp_str
+#define PARSED_INT_TYPE unsigned int
+
/**
* intMapGetByInt:
* @intmap: Pointer to int-to-string map
@@ -418,7 +420,7 @@ checkMacProtocolID(enum attrDatatype dat
datatype = DATATYPE_UINT16;
} else if (datatype == DATATYPE_UINT16 ||
datatype == DATATYPE_UINT16_HEX) {
- res = (uint32_t)*(uint16_t *)value;
+ res = (uint32_t)*(PARSED_INT_TYPE *)value;
if (res < 0x600)
res = -1;
}
@@ -522,7 +524,7 @@ arpOpcodeValidator(enum attrDatatype dat
datatype = DATATYPE_UINT16;
} else if (datatype == DATATYPE_UINT16 ||
datatype == DATATYPE_UINT16_HEX) {
- res = (uint32_t)*(uint16_t *)value;
+ res = (uint32_t)*(PARSED_INT_TYPE *)value;
}
if (res != -1) {
@@ -581,7 +583,7 @@ static bool checkIPProtocolID(enum attrD
datatype = DATATYPE_UINT8_HEX;
} else if (datatype == DATATYPE_UINT8 ||
datatype == DATATYPE_UINT8_HEX) {
- res = (uint32_t)*(uint16_t *)value;
+ res = (uint32_t)*(PARSED_INT_TYPE *)value;
}
if (res != -1) {
@@ -618,7 +620,7 @@ static bool
dscpValidator(enum attrDatatype datatype, void *val,
virNWFilterRuleDefPtr nwf)
{
- uint8_t dscp = *(uint16_t *)val;
+ uint8_t dscp = *(PARSED_INT_TYPE *)val;
if (dscp > 63)
return 0;
@@ -1149,7 +1151,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
enum virNWFilterEntryItemFlags *flags ,match_flag = 0, flags_set = 0;
nwItemDesc *item;
int int_val;
- unsigned int uint_val;
+ PARSED_INT_TYPE uint_val;
void *data_ptr = NULL, *storage_ptr;
valueValidator validator;
char *match = virXMLPropString(node, "match");