While writing a couple of test cases for the nwfilter's XML parser I found some cases where the output ended up not looking as expected. So the following changes are in the patch below: - if the protocol ID in the MAC header is an integer, just write it into the datastructure without trying to find a corresponding string for it and if none is found failing - when writing the protocol ID as string, simply write it as integer if no corresponding string can be found - same changes for arpOpcode parsing and printing - same changes for protocol ID in an IP packet - DSCP value needs to be written into the data structure - IP protocol version number is redundant at this level, so remove it - parse the protocol ID found inside an IP packet not only as string but also as uint8 - arrange the display of the src and destination masks to be shown after the src and destination ip address respectively in the XML - the existing libvirt IP address parser accepts for example '25' as an IP address. I want this to be parsed as a CIDR type netmask. So try to parse it as an integer first (CIDR netmask) and if that doesn't work as a dotted IP address style netmask. - instantiation of rules with MAC masks didn't work because they weren't printed into a buffer, yet. Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx> --- src/conf/nwfilter_conf.c | 128 ++++++++++++++---------------- src/nwfilter/nwfilter_ebiptables_driver.c | 1 2 files changed, 61 insertions(+), 68 deletions(-) Index: libvirt-acl/src/conf/nwfilter_conf.c =================================================================== --- libvirt-acl.orig/src/conf/nwfilter_conf.c +++ libvirt-acl/src/conf/nwfilter_conf.c @@ -403,15 +403,12 @@ checkMacProtocolID(enum attrDatatype dat virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED) { int32_t res = -1; - const char *str; if (datatype == DATATYPE_STRING) { if (intMapGetByString(macProtoMap, (char *)value, 1, &res) == 0) res = -1; } else if (datatype == DATATYPE_UINT16) { - if (intMapGetByInt(macProtoMap, - (int32_t)*(uint16_t *)value, &str) == 0) - res = -1; + res = (uint32_t)*(uint16_t *)value; } if (res != -1) { @@ -433,9 +430,10 @@ macProtocolIDFormatter(virBufferPtr buf, nwf->p.ethHdrFilter.dataProtocolID.u.u16, &str)) { virBufferVSprintf(buf, "%s", str); - return 1; + } else { + virBufferVSprintf(buf, "%d", nwf->p.ethHdrFilter.dataProtocolID.u.u16); } - return 0; + return 1; } @@ -500,15 +498,12 @@ arpOpcodeValidator(enum attrDatatype dat virNWFilterRuleDefPtr nwf) { int32_t res = -1; - const char *str; if (datatype == DATATYPE_STRING) { if (intMapGetByString(arpOpcodeMap, (char *)value, 1, &res) == 0) res = -1; } else if (datatype == DATATYPE_UINT16) { - if (intMapGetByInt(arpOpcodeMap, - (uint32_t)*(uint16_t *)value, &str) == 0) - res = -1; + res = (uint32_t)*(uint16_t *)value; } if (res != -1) { @@ -530,9 +525,10 @@ arpOpcodeFormatter(virBufferPtr buf, nwf->p.arpHdrFilter.dataOpcode.u.u16, &str)) { virBufferVSprintf(buf, "%s", str); - return 1; + } else { + virBufferVSprintf(buf, "%d", nwf->p.arpHdrFilter.dataOpcode.u.u16); } - return 0; + return 1; } @@ -560,16 +556,12 @@ static bool checkIPProtocolID(enum attrD virNWFilterRuleDefPtr nwf) { int32_t res = -1; - const char *str; if (datatype == DATATYPE_STRING) { if (intMapGetByString(ipProtoMap, (char *)value, 1, &res) == 0) res = -1; } else if (datatype == DATATYPE_UINT8) { - // may just accept what user provides and not test... - if (intMapGetByInt(ipProtoMap, - (uint32_t)*(uint16_t *)value, &str) == 0) - res = -1; + res = (uint32_t)*(uint16_t *)value; } if (res != -1) { @@ -591,19 +583,24 @@ formatIPProtocolID(virBufferPtr buf, nwf->p.ipHdrFilter.ipHdr.dataProtocolID.u.u8, &str)) { virBufferVSprintf(buf, "%s", str); - return 1; + } else { + virBufferVSprintf(buf, "%d", + nwf->p.ipHdrFilter.ipHdr.dataProtocolID.u.u8); } - return 0; + return 1; } static bool dscpValidator(enum attrDatatype datatype ATTRIBUTE_UNUSED, void *val, - virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED) + virNWFilterRuleDefPtr nwf) { uint8_t dscp = *(uint16_t *)val; if (dscp > 63) return 0; + + nwf->p.ipHdrFilter.ipHdr.dataDSCP.u.u8 = dscp; + return 1; } @@ -685,11 +682,6 @@ static const virXMLAttr2Struct arpAttrib static const virXMLAttr2Struct ipAttributes[] = { COMMON_MAC_PROPS(ipHdrFilter), { - .name = "version", - .datatype = DATATYPE_UINT8, - .dataIdx = offsetof(virNWFilterRuleDef, p.ipHdrFilter.ipHdr.dataIPVersion), - }, - { .name = SRCIPADDR, .datatype = DATATYPE_IPADDR, .dataIdx = offsetof(virNWFilterRuleDef, p.ipHdrFilter.ipHdr.dataSrcIPAddr), @@ -711,7 +703,7 @@ static const virXMLAttr2Struct ipAttribu }, { .name = "protocol", - .datatype = DATATYPE_STRING, + .datatype = DATATYPE_STRING | DATATYPE_UINT8, .dataIdx = offsetof(virNWFilterRuleDef, p.ipHdrFilter.ipHdr.dataProtocolID), .validator= checkIPProtocolID, .formatter= formatIPProtocolID, @@ -756,16 +748,16 @@ static const virXMLAttr2Struct ipv6Attri .dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.ipHdr.dataSrcIPAddr), }, { - .name = DSTIPADDR, - .datatype = DATATYPE_IPV6ADDR, - .dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.ipHdr.dataDstIPAddr), - }, - { .name = SRCIPMASK, .datatype = DATATYPE_IPV6MASK, .dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.ipHdr.dataSrcIPMask), }, { + .name = DSTIPADDR, + .datatype = DATATYPE_IPV6ADDR, + .dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.ipHdr.dataDstIPAddr), + }, + { .name = DSTIPMASK, .datatype = DATATYPE_IPV6MASK, .dataIdx = offsetof(virNWFilterRuleDef, p.ipv6HdrFilter.ipHdr.dataDstIPMask), @@ -818,16 +810,16 @@ static const virXMLAttr2Struct ipv6Attri .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPAddr),\ },\ {\ - .name = DSTIPADDR,\ - .datatype = ADDRTYPE,\ - .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDstIPAddr),\ - },\ - {\ .name = SRCIPMASK,\ .datatype = MASKTYPE,\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataSrcIPMask),\ },\ {\ + .name = DSTIPADDR,\ + .datatype = ADDRTYPE,\ + .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDstIPAddr),\ + },\ + {\ .name = DSTIPMASK,\ .datatype = MASKTYPE,\ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataDstIPMask),\ @@ -1276,26 +1268,26 @@ virNWFilterRuleDetailsParse(virConnectPt case DATATYPE_IPMASK: storage_ptr = &item->u.u8; - if (!virNWIPv4AddressParser(prop, &ipaddr)) { - if (sscanf(prop, "%d", &int_val) == 1) { - if (int_val >= 0 && int_val <= 32) { - if (!validator) - *(uint8_t *)storage_ptr = - (uint8_t)int_val; - found = 1; - data_ptr = &int_val; - } else - rc = -1; + if (virStrToLong_i(prop, NULL, 10, &int_val) == 0) { + if (int_val >= 0 && int_val <= 32) { + if (!validator) + *(uint8_t *)storage_ptr = + (uint8_t)int_val; + found = 1; + data_ptr = &int_val; } else rc = -1; } else { - int_val = virSocketGetNumNetmaskBits( + if (virNWIPv4AddressParser(prop, &ipaddr)) { + int_val = virSocketGetNumNetmaskBits( &ipaddr.addr); - if (int_val >= 0) - *(uint8_t *)storage_ptr = int_val; - else + if (int_val >= 0) + *(uint8_t *)storage_ptr = int_val; + else + rc = -1; + found = 1; + } else rc = -1; - found = 1; } break; @@ -1330,26 +1322,26 @@ virNWFilterRuleDetailsParse(virConnectPt case DATATYPE_IPV6MASK: storage_ptr = &item->u.u8; - if (!virNWIPv6AddressParser(prop, &ipaddr)) { - if (sscanf(prop, "%d", &int_val) == 1) { - if (int_val >= 0 && int_val <= 128) { - if (!validator) - *(uint8_t *)storage_ptr = - (uint8_t)int_val; - found = 1; - data_ptr = &int_val; - } else - rc = -1; + if (virStrToLong_i(prop, NULL, 10, &int_val) == 0) { + if (int_val >= 0 && int_val <= 128) { + if (!validator) + *(uint8_t *)storage_ptr = + (uint8_t)int_val; + found = 1; + data_ptr = &int_val; } else rc = -1; } else { - int_val = virSocketGetNumNetmaskBits( - &ipaddr.addr); - if (int_val >= 0) - *(uint8_t *)storage_ptr = int_val; - else - rc = -1; - found = 1; + if (virNWIPv6AddressParser(prop, &ipaddr)) { + int_val = virSocketGetNumNetmaskBits( + &ipaddr.addr); + if (int_val >= 0) + *(uint8_t *)storage_ptr = int_val; + else + rc = -1; + found = 1; + } else + rc = -1; } break; 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 @@ -189,6 +189,7 @@ printDataType(virConnectPtr conn, break; case DATATYPE_MACADDR: + case DATATYPE_MACMASK: if (bufsize < VIR_MAC_STRING_BUFLEN) { virNWFilterReportError(conn, VIR_ERR_INVALID_NWFILTER, _("Buffer too small for MAC address")); -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list