mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
virNWFilterRuleDefDetailsFormat: Refactor formatter
Format the rule attributes in two passes, first for positive 'match' and second pass for negative. This removes the crazy logic for switching between match modes inside the formatter. The refactor makes it also more clear in which cases we actually do format something. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
59a1455012
commit
9cb4e78ffd
@ -2701,146 +2701,119 @@ static void
|
|||||||
virNWFilterRuleDefDetailsFormat(virBuffer *buf,
|
virNWFilterRuleDefDetailsFormat(virBuffer *buf,
|
||||||
const char *type,
|
const char *type,
|
||||||
const virXMLAttr2Struct *att,
|
const virXMLAttr2Struct *att,
|
||||||
virNWFilterRuleDef *def)
|
virNWFilterRuleDef *def,
|
||||||
|
bool negative,
|
||||||
|
bool *hasAttrs)
|
||||||
{
|
{
|
||||||
size_t i = 0, j;
|
g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
|
||||||
bool typeShown = false;
|
bool present = false;
|
||||||
bool neverShown = true;
|
size_t i;
|
||||||
bool asHex;
|
size_t j;
|
||||||
enum match {
|
|
||||||
MATCH_NONE = 0,
|
|
||||||
MATCH_YES,
|
|
||||||
MATCH_NO
|
|
||||||
} matchShown = MATCH_NONE;
|
|
||||||
nwItemDesc *item;
|
|
||||||
|
|
||||||
while (att[i].name) {
|
if (negative)
|
||||||
virNWFilterEntryItemFlags flags;
|
virBufferAddLit(&attrBuf, " match='no'");
|
||||||
|
|
||||||
|
for (i = 0; att[i].name; i++) {
|
||||||
|
nwItemDesc *item;
|
||||||
|
|
||||||
VIR_WARNINGS_NO_CAST_ALIGN
|
VIR_WARNINGS_NO_CAST_ALIGN
|
||||||
item = (nwItemDesc *)((char *)def + att[i].dataIdx);
|
item = (nwItemDesc *)((char *)def + att[i].dataIdx);
|
||||||
VIR_WARNINGS_RESET
|
VIR_WARNINGS_RESET
|
||||||
|
|
||||||
flags = item->flags;
|
if (!(item->flags & NWFILTER_ENTRY_ITEM_FLAG_EXISTS))
|
||||||
if ((flags & NWFILTER_ENTRY_ITEM_FLAG_EXISTS)) {
|
continue;
|
||||||
if (!typeShown) {
|
|
||||||
virBufferAsprintf(buf, "<%s", type);
|
if (negative != !!(item->flags & NWFILTER_ENTRY_ITEM_FLAG_IS_NEG))
|
||||||
typeShown = true;
|
continue;
|
||||||
neverShown = false;
|
|
||||||
|
present = true;
|
||||||
|
*hasAttrs = true;
|
||||||
|
|
||||||
|
virBufferAsprintf(&attrBuf, " %s='", att[i].name);
|
||||||
|
|
||||||
|
if (att[i].formatter && !(item->flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
|
||||||
|
if (!att[i].formatter(&attrBuf, def, item)) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("formatter for %1$s %2$s reported error"),
|
||||||
|
type, att[i].name);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
} else if ((item->flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
|
||||||
|
virBufferAddChar(&attrBuf, '$');
|
||||||
|
virNWFilterVarAccessPrint(item->varAccess, &attrBuf);
|
||||||
|
} else {
|
||||||
|
|
||||||
if ((flags & NWFILTER_ENTRY_ITEM_FLAG_IS_NEG)) {
|
switch (item->datatype) {
|
||||||
if (matchShown == MATCH_NONE) {
|
|
||||||
virBufferAddLit(buf, " match='no'");
|
case DATATYPE_UINT8_HEX:
|
||||||
matchShown = MATCH_NO;
|
virBufferAsprintf(&attrBuf, "0x%x", item->u.u8);
|
||||||
} else if (matchShown == MATCH_YES) {
|
break;
|
||||||
virBufferAddLit(buf, "/>\n");
|
|
||||||
typeShown = false;
|
case DATATYPE_IPMASK:
|
||||||
matchShown = MATCH_NONE;
|
case DATATYPE_IPV6MASK:
|
||||||
continue;
|
/* display all masks in CIDR format */
|
||||||
}
|
case DATATYPE_UINT8:
|
||||||
} else {
|
virBufferAsprintf(&attrBuf, "%d", item->u.u8);
|
||||||
if (matchShown == MATCH_NO) {
|
break;
|
||||||
virBufferAddLit(buf, "/>\n");
|
|
||||||
typeShown = false;
|
case DATATYPE_UINT16_HEX:
|
||||||
matchShown = MATCH_NONE;
|
virBufferAsprintf(&attrBuf, "0x%x", item->u.u16);
|
||||||
continue;
|
break;
|
||||||
}
|
|
||||||
matchShown = MATCH_YES;
|
case DATATYPE_UINT16:
|
||||||
|
virBufferAsprintf(&attrBuf, "%d", item->u.u16);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DATATYPE_UINT32_HEX:
|
||||||
|
virBufferAsprintf(&attrBuf, "0x%x", item->u.u32);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DATATYPE_UINT32:
|
||||||
|
virBufferAsprintf(&attrBuf, "%u", item->u.u32);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DATATYPE_IPADDR:
|
||||||
|
case DATATYPE_IPV6ADDR:
|
||||||
|
virNWIPAddressFormat(&attrBuf, &item->u.ipaddr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DATATYPE_MACMASK:
|
||||||
|
case DATATYPE_MACADDR:
|
||||||
|
for (j = 0; j < 6; j++)
|
||||||
|
virBufferAsprintf(&attrBuf, "%02x%s",
|
||||||
|
item->u.macaddr.addr[j],
|
||||||
|
(j < 5) ? ":" : "");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DATATYPE_STRINGCOPY:
|
||||||
|
virBufferEscapeString(&attrBuf, "%s", item->u.string);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DATATYPE_BOOLEAN:
|
||||||
|
if (item->u.boolean)
|
||||||
|
virBufferAddLit(&attrBuf, "true");
|
||||||
|
else
|
||||||
|
virBufferAddLit(&attrBuf, "false");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DATATYPE_IPSETNAME:
|
||||||
|
case DATATYPE_IPSETFLAGS:
|
||||||
|
case DATATYPE_STRING:
|
||||||
|
case DATATYPE_LAST:
|
||||||
|
default:
|
||||||
|
virBufferAsprintf(&attrBuf,
|
||||||
|
"UNSUPPORTED DATATYPE 0x%02x\n",
|
||||||
|
att[i].datatype);
|
||||||
}
|
}
|
||||||
|
|
||||||
virBufferAsprintf(buf, " %s='",
|
|
||||||
att[i].name);
|
|
||||||
if (att[i].formatter && !(flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
|
|
||||||
if (!att[i].formatter(buf, def, item)) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("formatter for %1$s %2$s reported error"),
|
|
||||||
type,
|
|
||||||
att[i].name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if ((flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
|
|
||||||
virBufferAddChar(buf, '$');
|
|
||||||
virNWFilterVarAccessPrint(item->varAccess, buf);
|
|
||||||
} else {
|
|
||||||
asHex = false;
|
|
||||||
|
|
||||||
switch (item->datatype) {
|
|
||||||
|
|
||||||
case DATATYPE_UINT8_HEX:
|
|
||||||
asHex = true;
|
|
||||||
G_GNUC_FALLTHROUGH;
|
|
||||||
case DATATYPE_IPMASK:
|
|
||||||
case DATATYPE_IPV6MASK:
|
|
||||||
/* display all masks in CIDR format */
|
|
||||||
case DATATYPE_UINT8:
|
|
||||||
virBufferAsprintf(buf, asHex ? "0x%x" : "%d",
|
|
||||||
item->u.u8);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DATATYPE_UINT16_HEX:
|
|
||||||
asHex = true;
|
|
||||||
G_GNUC_FALLTHROUGH;
|
|
||||||
case DATATYPE_UINT16:
|
|
||||||
virBufferAsprintf(buf, asHex ? "0x%x" : "%d",
|
|
||||||
item->u.u16);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DATATYPE_UINT32_HEX:
|
|
||||||
asHex = true;
|
|
||||||
G_GNUC_FALLTHROUGH;
|
|
||||||
case DATATYPE_UINT32:
|
|
||||||
virBufferAsprintf(buf, asHex ? "0x%x" : "%u",
|
|
||||||
item->u.u32);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DATATYPE_IPADDR:
|
|
||||||
case DATATYPE_IPV6ADDR:
|
|
||||||
virNWIPAddressFormat(buf,
|
|
||||||
&item->u.ipaddr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DATATYPE_MACMASK:
|
|
||||||
case DATATYPE_MACADDR:
|
|
||||||
for (j = 0; j < 6; j++)
|
|
||||||
virBufferAsprintf(buf, "%02x%s",
|
|
||||||
item->u.macaddr.addr[j],
|
|
||||||
(j < 5) ? ":" : "");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DATATYPE_STRINGCOPY:
|
|
||||||
virBufferEscapeString(buf, "%s", item->u.string);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DATATYPE_BOOLEAN:
|
|
||||||
if (item->u.boolean)
|
|
||||||
virBufferAddLit(buf, "true");
|
|
||||||
else
|
|
||||||
virBufferAddLit(buf, "false");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DATATYPE_IPSETNAME:
|
|
||||||
case DATATYPE_IPSETFLAGS:
|
|
||||||
case DATATYPE_STRING:
|
|
||||||
case DATATYPE_LAST:
|
|
||||||
default:
|
|
||||||
virBufferAsprintf(buf,
|
|
||||||
"UNSUPPORTED DATATYPE 0x%02x\n",
|
|
||||||
att[i].datatype);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
virBufferAddLit(buf, "'");
|
|
||||||
}
|
}
|
||||||
i++;
|
|
||||||
|
virBufferAddLit(&attrBuf, "'");
|
||||||
}
|
}
|
||||||
if (typeShown)
|
|
||||||
virBufferAddLit(buf, "/>\n");
|
|
||||||
|
|
||||||
if (neverShown)
|
if (!present)
|
||||||
virBufferAsprintf(buf,
|
return;
|
||||||
"<%s/>\n", type);
|
|
||||||
|
|
||||||
return;
|
virXMLFormatElement(buf, type, &attrBuf, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2861,10 +2834,17 @@ virNWFilterRuleDefFormat(virBuffer *buf,
|
|||||||
virBufferAddLit(&attrBuf, " statematch='false'");
|
virBufferAddLit(&attrBuf, " statematch='false'");
|
||||||
|
|
||||||
for (i = 0; virAttr[i].id; i++) {
|
for (i = 0; virAttr[i].id; i++) {
|
||||||
|
bool hasAttrs = false;
|
||||||
|
|
||||||
if (virAttr[i].prtclType != def->prtclType)
|
if (virAttr[i].prtclType != def->prtclType)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
virNWFilterRuleDefDetailsFormat(&childBuf, virAttr[i].id, virAttr[i].att, def);
|
virNWFilterRuleDefDetailsFormat(&childBuf, virAttr[i].id, virAttr[i].att, def, false, &hasAttrs);
|
||||||
|
virNWFilterRuleDefDetailsFormat(&childBuf, virAttr[i].id, virAttr[i].att, def, true, &hasAttrs);
|
||||||
|
|
||||||
|
if (!hasAttrs)
|
||||||
|
virBufferAsprintf(&childBuf, "<%s/>\n", virAttr[i].id);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<filter name='testcase' chain='root'>
|
<filter name='testcase' chain='root'>
|
||||||
<uuid>01a992d2-f8c8-7c27-f69b-ab0a9d377379</uuid>
|
<uuid>01a992d2-f8c8-7c27-f69b-ab0a9d377379</uuid>
|
||||||
<rule action='accept' direction='in' priority='100'>
|
<rule action='accept' direction='in' priority='100'>
|
||||||
<tcp match='no' srcipaddr='10.1.2.3' srcipmask='32' srcportstart='22' dstportstart='22'/>
|
|
||||||
<tcp comment='comment'/>
|
<tcp comment='comment'/>
|
||||||
|
<tcp match='no' srcipaddr='10.1.2.3' srcipmask='32' srcportstart='22' dstportstart='22'/>
|
||||||
</rule>
|
</rule>
|
||||||
</filter>
|
</filter>
|
||||||
|
Loading…
Reference in New Issue
Block a user