/** * virNetDevBandwidthParse: * @bandwidth: parsed bandwidth * @node: XML node * @allowFloor: whether "floor" setting is supported * * Parse bandwidth XML and return pointer to structure. * The @allowFloor attribute indicates whether the caller * is able to support use of the "floor" setting. * * Returns !NULL on success, NULL on error. */ int virNetDevBandwidthParse(virNetDevBandwidthPtr *bandwidth, xmlNodePtr node, bool allowFloor) { int ret = -1; virNetDevBandwidthPtr def = NULL; xmlNodePtr cur; xmlNodePtr in = NULL, out = NULL; if (VIR_ALLOC(def) < 0) return ret; if (!node || !virXMLNodeNameEqual(node, "bandwidth")) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("invalid argument supplied")); goto cleanup; } cur = node->children; while (cur) { if (cur->type == XML_ELEMENT_NODE) { if (virXMLNodeNameEqual(cur, "inbound")) { if (in) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("Only one child <inbound> " "element allowed")); goto cleanup; } in = cur; } else if (virXMLNodeNameEqual(cur, "outbound")) { if (out) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("Only one child <outbound> " "element allowed")); goto cleanup; } out = cur; } /* Silently ignore unknown elements */ } cur = cur->next; } if (in) { if (VIR_ALLOC(def->in) < 0) goto cleanup; if (virNetDevBandwidthParseRate(in, def->in) < 0) { /* helper reported error for us */ goto cleanup; } if (def->in->floor && !allowFloor) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("floor attribute is not supported for this config")); goto cleanup; } } if (out) { if (VIR_ALLOC(def->out) < 0) goto cleanup; if (virNetDevBandwidthParseRate(out, def->out) < 0) { /* helper reported error for us */ goto cleanup; } if (def->out->floor) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("'floor' attribute allowed " "only in <inbound> element")); goto cleanup; } } if (!def->in && !def->out) VIR_FREE(def); *bandwidth = def; def = NULL; ret = 0; cleanup: virNetDevBandwidthFree(def); return ret; }
/** * virNetDevBandwidthParse: * @node: XML node * @net_type: one of virDomainNetType * * Parse bandwidth XML and return pointer to structure. * @net_type tell to which type will/is interface connected to. * Pass -1 if this is not called on interface. * * Returns !NULL on success, NULL on error. */ virNetDevBandwidthPtr virNetDevBandwidthParse(xmlNodePtr node, int net_type) { virNetDevBandwidthPtr def = NULL; xmlNodePtr cur; xmlNodePtr in = NULL, out = NULL; if (VIR_ALLOC(def) < 0) return NULL; if (!node || !xmlStrEqual(node->name, BAD_CAST "bandwidth")) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("invalid argument supplied")); goto error; } cur = node->children; while (cur) { if (cur->type == XML_ELEMENT_NODE) { if (xmlStrEqual(cur->name, BAD_CAST "inbound")) { if (in) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("Only one child <inbound> " "element allowed")); goto error; } in = cur; } else if (xmlStrEqual(cur->name, BAD_CAST "outbound")) { if (out) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("Only one child <outbound> " "element allowed")); goto error; } out = cur; } /* Silently ignore unknown elements */ } cur = cur->next; } if (in) { if (VIR_ALLOC(def->in) < 0) goto error; if (virNetDevBandwidthParseRate(in, def->in) < 0) { /* helper reported error for us */ goto error; } if (def->in->floor && net_type != VIR_DOMAIN_NET_TYPE_NETWORK) { if (net_type == -1) { /* 'floor' on network isn't supported */ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("floor attribute isn't supported for " "network's bandwidth yet")); } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("floor attribute is supported only for " "interfaces of type network")); } goto error; } } if (out) { if (VIR_ALLOC(def->out) < 0) goto error; if (virNetDevBandwidthParseRate(out, def->out) < 0) { /* helper reported error for us */ goto error; } if (def->out->floor) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("'floor' attribute allowed " "only in <inbound> element")); goto error; } } return def; error: virNetDevBandwidthFree(def); return NULL; }