Signed-off-by: Kristina Hanicova <khanicov(a)redhat.com>
---
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