Signed-off-by: Kristina Hanicova <khanicov@xxxxxxxxxx> --- src/conf/domain_conf.c | 338 +++++++++++++++++++---------------------- 1 file changed, 156 insertions(+), 182 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 22700c3064..5ea2061766 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -10712,7 +10712,13 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt, { virDomainNetDef *def; virDomainHostdevDef *hostdev; - xmlNodePtr cur; + xmlNodePtr source_node = NULL; + xmlNodePtr virtualport_node = NULL; + xmlNodePtr driver_node = NULL; + xmlNodePtr filterref_node = NULL; + xmlNodePtr actual_node = NULL; + xmlNodePtr vlan_node = NULL; + xmlNodePtr bandwidth_node = NULL; xmlNodePtr tmpNode; GHashTable *filterparams = NULL; virDomainActualNetDef *actual = NULL; @@ -10758,6 +10764,8 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt, g_autofree char *vhostuser_type = NULL; g_autofree char *trustGuestRxFilters = NULL; g_autofree char *vhost_path = NULL; + g_autofree char *tap = NULL; + g_autofree char *vhost = NULL; const char *prefix = xmlopt ? xmlopt->config.netPrefix : NULL; if (!(def = virDomainNetDefNew(xmlopt))) @@ -10786,194 +10794,157 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt, goto error; } - cur = node->children; - while (cur != NULL) { - if (cur->type == XML_ELEMENT_NODE) { - if (virXMLNodeNameEqual(cur, "source")) { - xmlNodePtr tmpnode = ctxt->node; + if ((source_node = virXPathNode("./source", ctxt))) { + xmlNodePtr tmpnode = ctxt->node; + ctxt->node = source_node; + if (virDomainNetIPInfoParseXML(_("interface host IP"), ctxt, &def->hostIP) < 0) + goto error; + ctxt->node = tmpnode; - ctxt->node = cur; - if (virDomainNetIPInfoParseXML(_("interface host IP"), - ctxt, &def->hostIP) < 0) - goto error; - ctxt->node = tmpnode; - } - if (!macaddr && virXMLNodeNameEqual(cur, "mac")) { - macaddr = virXMLPropString(cur, "address"); - macaddr_type = virXMLPropString(cur, "type"); - macaddr_check = virXMLPropString(cur, "check"); - } else if (!network && - def->type == VIR_DOMAIN_NET_TYPE_NETWORK && - virXMLNodeNameEqual(cur, "source")) { - network = virXMLPropString(cur, "network"); - portgroup = virXMLPropString(cur, "portgroup"); - if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)) - portid = virXMLPropString(cur, "portid"); - } else if (!internal && - def->type == VIR_DOMAIN_NET_TYPE_INTERNAL && - virXMLNodeNameEqual(cur, "source")) { - internal = virXMLPropString(cur, "name"); - } else if (!bridge && - def->type == VIR_DOMAIN_NET_TYPE_BRIDGE && - virXMLNodeNameEqual(cur, "source")) { - bridge = virXMLPropString(cur, "bridge"); - } else if (!dev && def->type == VIR_DOMAIN_NET_TYPE_DIRECT && - virXMLNodeNameEqual(cur, "source")) { - dev = virXMLPropString(cur, "dev"); - mode = virXMLPropString(cur, "mode"); - } else if (!dev && def->type == VIR_DOMAIN_NET_TYPE_ETHERNET && - virXMLNodeNameEqual(cur, "source")) { - /* This clause is only necessary because from 2010 to - * 2016 it was possible (but never documented) to - * configure the name of the guest-side interface of - * an openvz domain with <source dev='blah'/>. That - * was blatant misuse of <source>, so was likely - * (hopefully) never used, but just in case there was - * somebody using it, we need to generate an error. If - * the openvz driver is ever deprecated, this clause - * can be removed from here. - */ - if ((dev = virXMLPropString(cur, "dev"))) { - virReportError(VIR_ERR_XML_ERROR, - _("Invalid attempt to set <interface type='ethernet'> " - "device name with <source dev='%s'/>. " - "Use <target dev='%s'/> (for host-side) " - "or <guest dev='%s'/> (for guest-side) instead."), - dev, dev, dev); - goto error; - } - } else if (!vhostuser_path && !vhostuser_mode && !vhostuser_type - && def->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER - && virXMLNodeNameEqual(cur, "source")) { - vhostuser_type = virXMLPropString(cur, "type"); - vhostuser_path = virXMLPropString(cur, "path"); - vhostuser_mode = virXMLPropString(cur, "mode"); - if (virDomainChrSourceReconnectDefParseXML(&reconnect, cur, ctxt) < 0) - goto error; + if (def->type == VIR_DOMAIN_NET_TYPE_NETWORK) { + network = virXPathString("string(./source/@network)", ctxt); + portgroup = virXPathString("string(./source/@portgroup)", ctxt); + if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)) + portid = virXPathString("string(./source/@portid)", ctxt); + } - } else if (!dev - && def->type == VIR_DOMAIN_NET_TYPE_VDPA - && virXMLNodeNameEqual(cur, "source")) { - dev = virXMLPropString(cur, "dev"); - } else if (!def->virtPortProfile - && virXMLNodeNameEqual(cur, "virtualport")) { - if (def->type == VIR_DOMAIN_NET_TYPE_NETWORK) { - if (!(def->virtPortProfile - = virNetDevVPortProfileParse(cur, - VIR_VPORT_XML_GENERATE_MISSING_DEFAULTS))) { - goto error; - } - } else if (def->type == VIR_DOMAIN_NET_TYPE_BRIDGE || - def->type == VIR_DOMAIN_NET_TYPE_DIRECT || - def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) { - if (!(def->virtPortProfile - = virNetDevVPortProfileParse(cur, - VIR_VPORT_XML_GENERATE_MISSING_DEFAULTS| - VIR_VPORT_XML_REQUIRE_ALL_ATTRIBUTES| - VIR_VPORT_XML_REQUIRE_TYPE))) { - goto error; - } - } else { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("<virtualport> element unsupported for" - " <interface type='%s'>"), type); - goto error; - } - } else if (!address && - (def->type == VIR_DOMAIN_NET_TYPE_SERVER || - def->type == VIR_DOMAIN_NET_TYPE_CLIENT || - def->type == VIR_DOMAIN_NET_TYPE_MCAST || - def->type == VIR_DOMAIN_NET_TYPE_UDP) && - virXMLNodeNameEqual(cur, "source")) { - address = virXMLPropString(cur, "address"); - port = virXMLPropString(cur, "port"); - if (!localaddr && def->type == VIR_DOMAIN_NET_TYPE_UDP) { - xmlNodePtr tmpnode = ctxt->node; - ctxt->node = cur; - if ((tmpNode = virXPathNode("./local", ctxt))) { - localaddr = virXMLPropString(tmpNode, "address"); - localport = virXMLPropString(tmpNode, "port"); - } - ctxt->node = tmpnode; - } - } else if (!ifname && - virXMLNodeNameEqual(cur, "target")) { - ifname = virXMLPropString(cur, "dev"); - managed_tap = virXMLPropString(cur, "managed"); - } else if ((!ifname_guest || !ifname_guest_actual) && - virXMLNodeNameEqual(cur, "guest")) { - ifname_guest = virXMLPropString(cur, "dev"); - ifname_guest_actual = virXMLPropString(cur, "actual"); - } else if (!linkstate && - virXMLNodeNameEqual(cur, "link")) { - linkstate = virXMLPropString(cur, "state"); - } else if (!script && - virXMLNodeNameEqual(cur, "script")) { - script = virXMLPropString(cur, "path"); - } else if (!downscript && - virXMLNodeNameEqual(cur, "downscript")) { - downscript = virXMLPropString(cur, "path"); - } else if (!domain_name && - virXMLNodeNameEqual(cur, "backenddomain")) { - domain_name = virXMLPropString(cur, "name"); - } else if (virXMLNodeNameEqual(cur, "model")) { - model = virXMLPropString(cur, "type"); - } else if (virXMLNodeNameEqual(cur, "driver")) { - backend = virXMLPropString(cur, "name"); - txmode = virXMLPropString(cur, "txmode"); - ioeventfd = virXMLPropString(cur, "ioeventfd"); - event_idx = virXMLPropString(cur, "event_idx"); - queues = virXMLPropString(cur, "queues"); - rx_queue_size = virXMLPropString(cur, "rx_queue_size"); - tx_queue_size = virXMLPropString(cur, "tx_queue_size"); + if (def->type == VIR_DOMAIN_NET_TYPE_INTERNAL) + internal = virXPathString("string(./source/@name)", ctxt); - if (virDomainVirtioOptionsParseXML(cur, &def->virtio) < 0) - goto error; - } else if (virXMLNodeNameEqual(cur, "filterref")) { - if (filter) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Invalid specification of multiple <filterref>s " - "in a single <interface>")); - goto error; - } - filter = virXMLPropString(cur, "filter"); - virHashFree(filterparams); - filterparams = virNWFilterParseParamAttributes(cur); - } else if (virXMLNodeNameEqual(cur, "boot")) { - /* boot is parsed as part of virDomainDeviceInfoParseXML */ - } else if (!actual && - (flags & VIR_DOMAIN_DEF_PARSE_ACTUAL_NET) && - def->type == VIR_DOMAIN_NET_TYPE_NETWORK && - virXMLNodeNameEqual(cur, "actual")) { - if (virDomainActualNetDefParseXML(cur, ctxt, def, - &actual, flags, xmlopt) < 0) { - goto error; - } - } else if (virXMLNodeNameEqual(cur, "bandwidth")) { - if (virNetDevBandwidthParse(&def->bandwidth, - NULL, - cur, - def->type == VIR_DOMAIN_NET_TYPE_NETWORK) < 0) - goto error; - } else if (virXMLNodeNameEqual(cur, "vlan")) { - if (virNetDevVlanParse(cur, ctxt, &def->vlan) < 0) - goto error; - } else if (virXMLNodeNameEqual(cur, "backend")) { - char *tmp = NULL; + if (def->type == VIR_DOMAIN_NET_TYPE_BRIDGE) + bridge = virXPathString("string(./source/@bridge)", ctxt); - if ((tmp = virXMLPropString(cur, "tap"))) - def->backend.tap = virFileSanitizePath(tmp); - VIR_FREE(tmp); + if (def->type == VIR_DOMAIN_NET_TYPE_DIRECT) { + dev = virXPathString("string(./source/@dev)", ctxt); + mode = virXPathString("string(./source/@mode)", ctxt); + } - if (!vhost_path && (tmp = virXMLPropString(cur, "vhost"))) - vhost_path = virFileSanitizePath(tmp); - VIR_FREE(tmp); + /* This clause is only necessary because from 2010 to 2016 it was + * possible (but never documented) to configure the name of the + * guest-side interface of an openvz domain with <source dev='blah'/>. + * That was blatant misuse of <source>, so was likely (hopefully) + * never used, but just in case there was somebody using it, we + * need to generate an error. If the openvz driver is ever + * deprecated, this clause can be removed from here. + */ + if (def->type == VIR_DOMAIN_NET_TYPE_ETHERNET && + (dev = virXPathString("string(./source/@dev)", ctxt))) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid attempt to set <interface type='ethernet'> " + "device name with <source dev='%s'/>. " + "Use <target dev='%s'/> (for host-side) " + "or <guest dev='%s'/> (for guest-side) instead."), + dev, dev, dev); + goto error; + } + + if (def->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER) { + vhostuser_type = virXPathString("string(./source/@type)", ctxt); + vhostuser_path = virXPathString("string(./source/@path)", ctxt); + vhostuser_mode = virXPathString("string(./source/@mode)", ctxt); + if (virDomainChrSourceReconnectDefParseXML(&reconnect, source_node, ctxt) < 0) + goto error; + } + + if (def->type == VIR_DOMAIN_NET_TYPE_VDPA) + dev = virXPathString("string(./source/@dev)", ctxt); + + if (def->type == VIR_DOMAIN_NET_TYPE_SERVER || + def->type == VIR_DOMAIN_NET_TYPE_CLIENT || + def->type == VIR_DOMAIN_NET_TYPE_MCAST || + def->type == VIR_DOMAIN_NET_TYPE_UDP) { + + address = virXPathString("string(./source/@address)", ctxt); + port = virXPathString("string(./source/@port)", ctxt); + if (def->type == VIR_DOMAIN_NET_TYPE_UDP) { + xmlNodePtr tmp_node = ctxt->node; + ctxt->node = source_node; + if ((tmpNode = virXPathNode("./local", ctxt))) { + localaddr = virXMLPropString(tmpNode, "address"); + localport = virXMLPropString(tmpNode, "port"); + } + ctxt->node = tmp_node; } } - cur = cur->next; } - if (macaddr) { + if ((virtualport_node = virXPathNode("./virtualport", ctxt))) { + if (def->type == VIR_DOMAIN_NET_TYPE_NETWORK) { + if (!(def->virtPortProfile + = virNetDevVPortProfileParse(virtualport_node, + VIR_VPORT_XML_GENERATE_MISSING_DEFAULTS))) { + goto error; + } + } else if (def->type == VIR_DOMAIN_NET_TYPE_BRIDGE || + def->type == VIR_DOMAIN_NET_TYPE_DIRECT || + def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) { + if (!(def->virtPortProfile + = virNetDevVPortProfileParse(virtualport_node, VIR_VPORT_XML_GENERATE_MISSING_DEFAULTS| + VIR_VPORT_XML_REQUIRE_ALL_ATTRIBUTES| + VIR_VPORT_XML_REQUIRE_TYPE))) { + goto error; + } + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("<virtualport> element unsupported for" + " <interface type='%s'>"), type); + goto error; + } + } + + ifname = virXPathString("string(./target/@dev)", ctxt); + managed_tap = virXPathString("string(./target/@managed)", ctxt); + + ifname_guest = virXPathString("string(./guest/@dev)", ctxt); + ifname_guest_actual = virXPathString("string(./guest/@actual)", ctxt); + + linkstate = virXPathString("string(./link/@state)", ctxt); + script = virXPathString("string(./script/@path)", ctxt); + downscript = virXPathString("string(./downscript/@path)", ctxt); + domain_name = virXPathString("string(./backenddomain/@name)", ctxt); + model = virXPathString("string(./model/@type)", ctxt); + + if ((driver_node = virXPathNode("./driver", ctxt)) && + (virDomainVirtioOptionsParseXML(driver_node, &def->virtio) < 0)) + goto error; + + backend = virXPathString("string(./driver/@name)", ctxt); + txmode = virXPathString("string(./driver/@txmode)", ctxt); + ioeventfd = virXPathString("string(./driver/@ioeventfd)", ctxt); + event_idx = virXPathString("string(./driver/@event_idx)", ctxt); + queues = virXPathString("string(./driver/@queues)", ctxt); + rx_queue_size = virXPathString("string(./driver/@rx_queue_size)", ctxt); + tx_queue_size = virXPathString("string(./driver/@tx_queue_size)", ctxt); + + if ((filterref_node = virXPathNode("./filterref", ctxt))) { + filter = virXPathString("string(./filterref/@filter)", ctxt); + virHashFree(filterparams); + filterparams = virNWFilterParseParamAttributes(filterref_node); + } + + if ((flags & VIR_DOMAIN_DEF_PARSE_ACTUAL_NET) && + def->type == VIR_DOMAIN_NET_TYPE_NETWORK && + (actual_node = virXPathNode("./actual", ctxt)) && + (virDomainActualNetDefParseXML(actual_node, ctxt, def, + &actual, flags, xmlopt) < 0)) + goto error; + + if ((bandwidth_node = virXPathNode("./bandwidth", ctxt)) && + (virNetDevBandwidthParse(&def->bandwidth, NULL, bandwidth_node, + def->type == VIR_DOMAIN_NET_TYPE_NETWORK) < 0)) + goto error; + + if ((vlan_node = virXPathNode("./vlan", ctxt)) && + (virNetDevVlanParse(vlan_node, ctxt, &def->vlan) < 0)) + goto error; + + if ((tap = virXPathString("string(./backend/@tap)", ctxt))) + def->backend.tap = virFileSanitizePath(tap); + + if ((vhost = virXPathString("string(./backend/@vhost)", ctxt))) + vhost_path = virFileSanitizePath(vhost); + + if ((macaddr = virXPathString("string(./mac/@address)", ctxt))) { if (virMacAddrParse((const char *)macaddr, &def->mac) < 0) { virReportError(VIR_ERR_XML_ERROR, _("unable to parse mac address '%s'"), @@ -10991,8 +10962,9 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt, def->mac_generated = true; } - if (macaddr_type) { + if ((macaddr_type = virXPathString("string(./mac/@type)", ctxt))) { int tmp; + if ((tmp = virDomainNetMacTypeTypeFromString(macaddr_type)) <= 0) { virReportError(VIR_ERR_XML_ERROR, _("invalid mac address type value: '%s'. Valid " @@ -11002,8 +10974,10 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt, } def->mac_type = tmp; } - if (macaddr_check) { + + if ((macaddr_check = virXPathString("string(./mac/@check)", ctxt))) { int tmpCheck; + if ((tmpCheck = virTristateBoolTypeFromString(macaddr_check)) < 0) { virReportError(VIR_ERR_XML_ERROR, _("invalid mac address check value: '%s'"), -- 2.30.2