This looks good to me. Acked-by: Kyle Mestery <kmestery@xxxxxxxxx> On Aug 14, 2012, at 2:04 AM, Laine Stump wrote: > Until now, all attributes in a <virtualport> parameter list that were > acceptable for a particular type, were also required. There were no > optional attributes. > > One of the aims of supporting <virtualport> in libvirt's virtual > networks and portgroups is to allow specifying the group-wide > parameters in the network's virtualport, and merge that with the > interface's virtualport, which will have the instance-specific info > (i.e. the interfaceid or instanceid). > > Additionally, the guest's interface XML shouldn't need to know what > type of network connection will be used prior to runtime - it could be > openvswitch, 802.1Qbh, 802.1Qbg, or none of the above - but should > still be able to specify instance-specific info just in case it turns > out to be applicable. > > Finally, up to now, the parser for virtualport has always generated a > random instanceid/interfaceid when appropriate, making it impossible > to leave it blank (which is what's required for virtualports within a > network/portprofile definition). > > This patch modifies the parser and formatter of the <virtualport> > element in the following ways: > > * because most of the attributes in a virNetDevVPortProfile are fixed > size binary data with no reserved values, there is no way to embed a > "this value wasn't specified" sentinel into the existing data. To > solve this problem, the new *_specified fields in the > virNetDevVPortProfile object that were added in a previous patch of > this series are now set when the corresponding attribute is present > during the parse. > > * allow parsing/formatting a <virtualport> that has no type set. In > this case, all fields are settable, but all are also optional. > > * add a GENERATE_MISSING_DEFAULTS flag to the parser - if this flag is > set and an instanceid/interfaceid is expected but not provided, a > random one will be generated. This was previously the default > behavior, but is now done only for virtualports inside an > <interface> definition, not for those in <network> or <portgroup>. > > * add a REQUIRE_ALL_ATTRIBUTES flag to the parser - if this flag is > set the parser will call the new > virNetDevVPortProfileCheckComplete() functions at the end of the > parser to check for any missing attributes (based on type), and > return failure if anything is missing. This used to be default > behavior. Now it is only used for the virtualport defined inside an > interface's <actual> element (by the time you've figured out the > contents of <actual>, you should have all the necessary data to fill > in the entire virtualport) > > * add a REQUIRE_TYPE flag to the parser - if this flag is set, the > parser will return an error if the virtualport has no type > attribute. This also was previously the default behavior, but isn't > needed in the case of the virtualport for a type='network' interface > (i.e. the exact type isn't yet known), or the virtualport of a > portgroup (i.e. the portgroup just has modifiers for the network's > virtualport, which *does* require a type) - in those cases, the > check will be done at domain startup, once the final virtualport is > assembled (this is handled in the next patch). > --- > docs/schemas/networkcommon.rng | 114 ++++++-- > src/conf/domain_conf.c | 25 +- > src/conf/netdev_vport_profile_conf.c | 308 +++++++++++---------- > src/conf/netdev_vport_profile_conf.h | 17 +- > src/conf/network_conf.c | 7 +- > tests/networkxml2xmlin/openvswitch-net.xml | 16 ++ > tests/networkxml2xmlin/vepa-net.xml | 6 +- > tests/networkxml2xmlout/openvswitch-net.xml | 16 ++ > tests/networkxml2xmlout/vepa-net.xml | 6 +- > tests/networkxml2xmltest.c | 1 + > .../qemuxml2argv-net-virtio-network-portgroup.xml | 14 + > 11 files changed, 344 insertions(+), 186 deletions(-) > create mode 100644 tests/networkxml2xmlin/openvswitch-net.xml > create mode 100644 tests/networkxml2xmlout/openvswitch-net.xml > > diff --git a/docs/schemas/networkcommon.rng b/docs/schemas/networkcommon.rng > index 2328892..f2c3330 100644 > --- a/docs/schemas/networkcommon.rng > +++ b/docs/schemas/networkcommon.rng > @@ -15,22 +15,30 @@ > <attribute name="type"> > <value>802.1Qbg</value> > </attribute> > - <element name="parameters"> > - <attribute name="managerid"> > - <ref name="uint8range"/> > - </attribute> > - <attribute name="typeid"> > - <ref name="uint24range"/> > - </attribute> > - <attribute name="typeidversion"> > - <ref name="uint8range"/> > - </attribute> > - <optional> > - <attribute name="instanceid"> > - <ref name="UUID"/> > - </attribute> > - </optional> > - </element> > + <optional> > + <element name="parameters"> > + <optional> > + <attribute name="managerid"> > + <ref name="uint8range"/> > + </attribute> > + </optional> > + <optional> > + <attribute name="typeid"> > + <ref name="uint24range"/> > + </attribute> > + </optional> > + <optional> > + <attribute name="typeidversion"> > + <ref name="uint8range"/> > + </attribute> > + </optional> > + <optional> > + <attribute name="instanceid"> > + <ref name="UUID"/> > + </attribute> > + </optional> > + </element> > + </optional> > </element> > </group> > <group> > @@ -38,11 +46,75 @@ > <attribute name="type"> > <value>802.1Qbh</value> > </attribute> > - <element name="parameters"> > - <attribute name="profileid"> > - <ref name="virtualPortProfileID"/> > - </attribute> > - </element> > + <optional> > + <element name="parameters"> > + <optional> > + <attribute name="profileid"> > + <ref name="virtualPortProfileID"/> > + </attribute> > + </optional> > + </element> > + </optional> > + </element> > + </group> > + <group> > + <element name="virtualport"> > + <attribute name="type"> > + <value>openvswitch</value> > + </attribute> > + <optional> > + <element name="parameters"> > + <optional> > + <attribute name="profileid"> > + <ref name="virtualPortProfileID"/> > + </attribute> > + </optional> > + <optional> > + <attribute name="interfaceid"> > + <ref name="UUID"/> > + </attribute> > + </optional> > + </element> > + </optional> > + </element> > + </group> > + <group> > + <!-- use this when no type attribute is present --> > + <element name="virtualport"> > + <optional> > + <element name="parameters"> > + <optional> > + <attribute name="managerid"> > + <ref name="uint8range"/> > + </attribute> > + </optional> > + <optional> > + <attribute name="typeid"> > + <ref name="uint24range"/> > + </attribute> > + </optional> > + <optional> > + <attribute name="typeidversion"> > + <ref name="uint8range"/> > + </attribute> > + </optional> > + <optional> > + <attribute name="instanceid"> > + <ref name="UUID"/> > + </attribute> > + </optional> > + <optional> > + <attribute name="profileid"> > + <ref name="virtualPortProfileID"/> > + </attribute> > + </optional> > + <optional> > + <attribute name="interfaceid"> > + <ref name="UUID"/> > + </attribute> > + </optional> > + </element> > + </optional> > </element> > </group> > </choice> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index 8f1f244..0cda374 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -4404,8 +4404,13 @@ virDomainActualNetDefParseXML(xmlNodePtr node, > if (actual->type == VIR_DOMAIN_NET_TYPE_BRIDGE || > actual->type == VIR_DOMAIN_NET_TYPE_DIRECT || > actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) { > + /* the virtualport in <actual> should always already > + * have an instanceid/interfaceid if its required, > + * so don't let the parser generate one */ > if (!(actual->virtPortProfile > - = virNetDevVPortProfileParse(virtPortNode))) { > + = virNetDevVPortProfileParse(virtPortNode, > + VIR_VPORT_XML_REQUIRE_ALL_ATTRIBUTES | > + VIR_VPORT_XML_REQUIRE_TYPE))) { > goto error; > } > } else { > @@ -4558,12 +4563,20 @@ virDomainNetDefParseXML(virCapsPtr caps, > mode = virXMLPropString(cur, "mode"); > } else if (!def->virtPortProfile > && xmlStrEqual(cur->name, BAD_CAST "virtualport")) { > - if (def->type == VIR_DOMAIN_NET_TYPE_NETWORK || > - def->type == VIR_DOMAIN_NET_TYPE_BRIDGE || > - def->type == VIR_DOMAIN_NET_TYPE_DIRECT || > - def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) { > + if (def->type == VIR_DOMAIN_NET_TYPE_NETWORK) { > if (!(def->virtPortProfile > - = virNetDevVPortProfileParse(cur))) { > + = 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 { > diff --git a/src/conf/netdev_vport_profile_conf.c b/src/conf/netdev_vport_profile_conf.c > index 31ee9b4..1adff10 100644 > --- a/src/conf/netdev_vport_profile_conf.c > +++ b/src/conf/netdev_vport_profile_conf.c > @@ -37,7 +37,7 @@ VIR_ENUM_IMPL(virNetDevVPort, VIR_NETDEV_VPORT_PROFILE_LAST, > > > virNetDevVPortProfilePtr > -virNetDevVPortProfileParse(xmlNodePtr node) > +virNetDevVPortProfileParse(xmlNodePtr node, unsigned int flags) > { > char *virtPortType; > char *virtPortManagerID = NULL; > @@ -54,22 +54,22 @@ virNetDevVPortProfileParse(xmlNodePtr node) > return NULL; > } > > - virtPortType = virXMLPropString(node, "type"); > - if (!virtPortType) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("missing virtualportprofile type")); > + if ((virtPortType = virXMLPropString(node, "type")) && > + (virtPort->virtPortType = virNetDevVPortTypeFromString(virtPortType)) <= 0) { > + virReportError(VIR_ERR_XML_ERROR, > + _("unknown virtualport type %s"), virtPortType); > goto error; > } > > - if ((virtPort->virtPortType = virNetDevVPortTypeFromString(virtPortType)) <= 0) { > - virReportError(VIR_ERR_XML_ERROR, > - _("unknown virtualportprofile type %s"), virtPortType); > + if ((virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE) && > + (flags & VIR_VPORT_XML_REQUIRE_TYPE)) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("missing required virtualport type")); > goto error; > } > > while (cur != NULL) { > if (xmlStrEqual(cur->name, BAD_CAST "parameters")) { > - > virtPortManagerID = virXMLPropString(cur, "managerid"); > virtPortTypeID = virXMLPropString(cur, "typeid"); > virtPortTypeIDVersion = virXMLPropString(cur, "typeidversion"); > @@ -78,132 +78,119 @@ virNetDevVPortProfileParse(xmlNodePtr node) > virtPortInterfaceID = virXMLPropString(cur, "interfaceid"); > break; > } > - > cur = cur->next; > } > > - switch (virtPort->virtPortType) { > - case VIR_NETDEV_VPORT_PROFILE_8021QBG: > - if (virtPortManagerID != NULL && virtPortTypeID != NULL && > - virtPortTypeIDVersion != NULL) { > - unsigned int val; > - > - if (virStrToLong_ui(virtPortManagerID, NULL, 0, &val)) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("cannot parse value of managerid parameter")); > - goto error; > - } > - > - if (val > 0xff) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("value of managerid out of range")); > - goto error; > - } > - > - virtPort->managerID = (uint8_t)val; > - > - if (virStrToLong_ui(virtPortTypeID, NULL, 0, &val)) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("cannot parse value of typeid parameter")); > - goto error; > - } > + if (virtPortManagerID) { > + unsigned int val; > > - if (val > 0xffffff) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("value for typeid out of range")); > - goto error; > - } > - > - virtPort->typeID = (uint32_t)val; > + if (virStrToLong_ui(virtPortManagerID, NULL, 0, &val)) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("cannot parse value of managerid parameter")); > + goto error; > + } > + if (val > 0xff) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("value of managerid out of range")); > + goto error; > + } > + virtPort->managerID = (uint8_t)val; > + virtPort->managerID_specified = true; > + } > > - if (virStrToLong_ui(virtPortTypeIDVersion, NULL, 0, &val)) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("cannot parse value of typeidversion parameter")); > - goto error; > - } > + if (virtPortTypeID) { > + unsigned int val; > > - if (val > 0xff) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("value of typeidversion out of range")); > - goto error; > - } > + if (virStrToLong_ui(virtPortTypeID, NULL, 0, &val)) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("cannot parse value of typeid parameter")); > + goto error; > + } > + if (val > 0xffffff) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("value for typeid out of range")); > + goto error; > + } > + virtPort->typeID = (uint32_t)val; > + virtPort->typeID_specified = true; > + } > > - virtPort->typeIDVersion = (uint8_t)val; > - > - if (virtPortInstanceID != NULL) { > - if (virUUIDParse(virtPortInstanceID, > - virtPort->instanceID)) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("cannot parse instanceid parameter as a uuid")); > - goto error; > - } > - } else { > - if (virUUIDGenerate(virtPort->instanceID)) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("cannot generate a random uuid for instanceid")); > - goto error; > - } > - } > + if (virtPortTypeIDVersion) { > + unsigned int val; > > - virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBG; > + if (virStrToLong_ui(virtPortTypeIDVersion, NULL, 0, &val)) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("cannot parse value of typeidversion parameter")); > + goto error; > + } > + if (val > 0xff) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("value of typeidversion out of range")); > + goto error; > + } > + virtPort->typeIDVersion = (uint8_t)val; > + virtPort->typeIDVersion_specified = true; > + } > > - } else { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("a parameter is missing for 802.1Qbg description")); > + if (virtPortInstanceID) { > + if (virUUIDParse(virtPortInstanceID, virtPort->instanceID) < 0) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("cannot parse instanceid parameter as a uuid")); > goto error; > } > - break; > - > - case VIR_NETDEV_VPORT_PROFILE_8021QBH: > - if (virtPortProfileID != NULL) { > - if (virStrcpyStatic(virtPort->profileID, > - virtPortProfileID) != NULL) { > - virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBH; > - } else { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("profileid parameter too long")); > - goto error; > - } > - } else { > + virtPort->instanceID_specified = true; > + } > + > + if (virtPortProfileID && > + !virStrcpyStatic(virtPort->profileID, virtPortProfileID)) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("profileid parameter too long")); > + goto error; > + } > + > + if (virtPortInterfaceID) { > + if (virUUIDParse(virtPortInterfaceID, virtPort->interfaceID) < 0) { > virReportError(VIR_ERR_XML_ERROR, "%s", > - _("profileid parameter is missing for 802.1Qbh description")); > + _("cannot parse interfaceid parameter as a uuid")); > goto error; > } > - break; > - case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH: > - if (virtPortInterfaceID != NULL) { > - if (virUUIDParse(virtPortInterfaceID, > - virtPort->interfaceID)) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("cannot parse interfaceid parameter as a uuid")); > - goto error; > - } > - } else { > - if (virUUIDGenerate(virtPort->interfaceID)) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("cannot generate a random uuid for interfaceid")); > + virtPort->interfaceID_specified = true; > + } > + > + /* generate default instanceID/interfaceID if appropriate */ > + if (flags & VIR_VPORT_XML_GENERATE_MISSING_DEFAULTS) { > + if (!virtPort->instanceID_specified && > + (virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_8021QBG || > + virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE)) { > + if (virUUIDGenerate(virtPort->instanceID) < 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("cannot generate a random uuid for instanceid")); > goto error; > } > + virtPort->instanceID_specified = true; > } > - /* profileid is not mandatory for Open vSwitch */ > - if (virtPortProfileID != NULL) { > - if (virStrcpyStatic(virtPort->profileID, > - virtPortProfileID) == NULL) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("profileid parameter too long")); > + if (!virtPort->interfaceID_specified && > + (virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH || > + virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE)) { > + if (virUUIDGenerate(virtPort->interfaceID) < 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("cannot generate a random uuid for interfaceid")); > goto error; > } > - } else { > - virtPort->profileID[0] = '\0'; > + virtPort->interfaceID_specified = true; > } > - break; > + } > > - default: > - virReportError(VIR_ERR_XML_ERROR, > - _("unexpected virtualport type %d"), virtPort->virtPortType); > + /* check for required/unsupported attributes */ > + > + if ((flags & VIR_VPORT_XML_REQUIRE_ALL_ATTRIBUTES) && > + (virNetDevVPortProfileCheckComplete(virtPort, false) < 0)) { > goto error; > } > > + if (virNetDevVPortProfileCheckNoExtras(virtPort) < 0) > + goto error; > + > cleanup: > VIR_FREE(virtPortManagerID); > VIR_FREE(virtPortTypeID); > @@ -224,53 +211,76 @@ int > virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, > virBufferPtr buf) > { > - char uuidstr[VIR_UUID_STRING_BUFLEN]; > + enum virNetDevVPortProfile type; > + bool noParameters; > > - if (!virtPort || virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE) > + if (!virtPort) > return 0; > > - virBufferAsprintf(buf, "<virtualport type='%s'>\n", > - virNetDevVPortTypeToString(virtPort->virtPortType)); > - > - switch (virtPort->virtPortType) { > - case VIR_NETDEV_VPORT_PROFILE_8021QBG: > - virUUIDFormat(virtPort->instanceID, > - uuidstr); > - virBufferAsprintf(buf, > - " <parameters managerid='%d' typeid='%d' " > - "typeidversion='%d' instanceid='%s'/>\n", > - virtPort->managerID, > - virtPort->typeID, > - virtPort->typeIDVersion, > - uuidstr); > - break; > - > - case VIR_NETDEV_VPORT_PROFILE_8021QBH: > - virBufferAsprintf(buf, > - " <parameters profileid='%s'/>\n", > - virtPort->profileID); > - break; > - > - case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH: > - virUUIDFormat(virtPort->interfaceID, > - uuidstr); > - if (virtPort->profileID[0] == '\0') { > - virBufferAsprintf(buf, " <parameters interfaceid='%s'/>\n", > - uuidstr); > + noParameters = !(virtPort->managerID_specified || > + virtPort->typeID_specified || > + virtPort->typeIDVersion_specified || > + virtPort->instanceID_specified || > + virtPort->profileID[0] || > + virtPort->interfaceID_specified); > + > + type = virtPort->virtPortType; > + if (type == VIR_NETDEV_VPORT_PROFILE_NONE) { > + if (noParameters) > + return 0; > + virBufferAddLit(buf, "<virtualport>\n"); > + } else { > + if (noParameters) { > + virBufferAsprintf(buf, "<virtualport type='%s'/>\n", > + virNetDevVPortTypeToString(type)); > + return 0; > } else { > - virBufferAsprintf(buf, " <parameters interfaceid='%s' " > - "profileid='%s'/>\n", uuidstr, > - virtPort->profileID); > + virBufferAsprintf(buf, "<virtualport type='%s'>\n", > + virNetDevVPortTypeToString(type)); > } > + } > + virBufferAddLit(buf, " <parameters"); > > - break; > + if (virtPort->managerID_specified && > + (type == VIR_NETDEV_VPORT_PROFILE_8021QBG || > + type == VIR_NETDEV_VPORT_PROFILE_NONE)) { > + virBufferAsprintf(buf, " managerid='%d'", virtPort->managerID); > + } > + if (virtPort->typeID_specified && > + (type == VIR_NETDEV_VPORT_PROFILE_8021QBG || > + type == VIR_NETDEV_VPORT_PROFILE_NONE)) { > + virBufferAsprintf(buf, " typeid='%d'", virtPort->typeID); > + } > + if (virtPort->typeIDVersion_specified && > + (type == VIR_NETDEV_VPORT_PROFILE_8021QBG || > + type == VIR_NETDEV_VPORT_PROFILE_NONE)) { > + virBufferAsprintf(buf, " typeidversion='%d'", > + virtPort->typeIDVersion); > + } > + if (virtPort->instanceID_specified && > + (type == VIR_NETDEV_VPORT_PROFILE_8021QBG || > + type == VIR_NETDEV_VPORT_PROFILE_NONE)) { > + char uuidstr[VIR_UUID_STRING_BUFLEN]; > > - default: > - virReportError(VIR_ERR_XML_ERROR, > - _("unexpected virtualport type %d"), virtPort->virtPortType); > - return -1; > + virUUIDFormat(virtPort->instanceID, uuidstr); > + virBufferAsprintf(buf, " instanceid='%s'", uuidstr); > + } > + if (virtPort->interfaceID_specified && > + (type == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH || > + type == VIR_NETDEV_VPORT_PROFILE_NONE)) { > + char uuidstr[VIR_UUID_STRING_BUFLEN]; > + > + virUUIDFormat(virtPort->interfaceID, uuidstr); > + virBufferAsprintf(buf, " interfaceid='%s'", uuidstr); > + } > + if (virtPort->profileID[0] && > + (type == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH || > + type == VIR_NETDEV_VPORT_PROFILE_8021QBH || > + type == VIR_NETDEV_VPORT_PROFILE_NONE)) { > + virBufferAsprintf(buf, " profileid='%s'", virtPort->profileID); > } > > + virBufferAddLit(buf, "/>\n"); > virBufferAddLit(buf, "</virtualport>\n"); > return 0; > } > diff --git a/src/conf/netdev_vport_profile_conf.h b/src/conf/netdev_vport_profile_conf.h > index 367bdf3..caf3519 100644 > --- a/src/conf/netdev_vport_profile_conf.h > +++ b/src/conf/netdev_vport_profile_conf.h > @@ -1,5 +1,5 @@ > /* > - * Copyright (C) 2009-2011 Red Hat, Inc. > + * Copyright (C) 2009-2012 Red Hat, Inc. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public > @@ -28,8 +28,21 @@ > # include "buf.h" > # include "xml.h" > > +typedef enum { > + /* generate random defaults for interfaceID/interfaceID > + * when appropriate > + */ > + VIR_VPORT_XML_GENERATE_MISSING_DEFAULTS = (1<<0), > + /* fail if any attribute required for the specified > + * type is missing > + */ > + VIR_VPORT_XML_REQUIRE_ALL_ATTRIBUTES = (1<<1), > + /* fail if no type is specified */ > + VIR_VPORT_XML_REQUIRE_TYPE = (1<<2), > +} virNetDevVPortXMLFlags; > + > virNetDevVPortProfilePtr > -virNetDevVPortProfileParse(xmlNodePtr node); > +virNetDevVPortProfileParse(xmlNodePtr node, unsigned int flags); > > int > virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, > diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c > index a3714d9..783c388 100644 > --- a/src/conf/network_conf.c > +++ b/src/conf/network_conf.c > @@ -899,8 +899,9 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def, > > virtPortNode = virXPathNode("./virtualport", ctxt); > if (virtPortNode && > - (!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode)))) > + (!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode, 0)))) { > goto error; > + } > > bandwidth_node = virXPathNode("./bandwidth", ctxt); > if (bandwidth_node && > @@ -1010,8 +1011,10 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) > > virtPortNode = virXPathNode("./virtualport", ctxt); > if (virtPortNode && > - (!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode)))) > + (!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode, > + VIR_VPORT_XML_REQUIRE_TYPE)))) { > goto error; > + } > > nPortGroups = virXPathNodeSet("./portgroup", ctxt, &portGroupNodes); > if (nPortGroups < 0) > diff --git a/tests/networkxml2xmlin/openvswitch-net.xml b/tests/networkxml2xmlin/openvswitch-net.xml > new file mode 100644 > index 0000000..8aa1897 > --- /dev/null > +++ b/tests/networkxml2xmlin/openvswitch-net.xml > @@ -0,0 +1,16 @@ > +<network> > + <name>openvswitch-net</name> > + <uuid>81ff0d90-c92e-6742-64da-4a736edb9a8b</uuid> > + <forward mode='bridge'/> > + <virtualport type='openvswitch'/> > + <portgroup name='bob' default='yes'> > + <virtualport> > + <parameters profileid='bob-profile'/> > + </virtualport> > + </portgroup> > + <portgroup name='alice'> > + <virtualport> > + <parameters profileid='alice-profile'/> > + </virtualport> > + </portgroup> > +</network> > diff --git a/tests/networkxml2xmlin/vepa-net.xml b/tests/networkxml2xmlin/vepa-net.xml > index b1a40c6..030c1d1 100644 > --- a/tests/networkxml2xmlin/vepa-net.xml > +++ b/tests/networkxml2xmlin/vepa-net.xml > @@ -7,16 +7,16 @@ > <interface dev="eth3"/> > </forward> > <virtualport type="802.1Qbg"> > - <parameters managerid="11" typeid="1193047" typeidversion="2" instanceid="b153fa89-1b87-9719-ec12-99e0054fb844"/> > + <parameters managerid="11" typeid="1193047" typeidversion="2"/> > </virtualport> > <portgroup name="bob" default="yes"> > <virtualport type="802.1Qbg"> > - <parameters managerid="12" typeid="2193047" typeidversion="3" instanceid="5d00e0ba-e15c-959c-fbb6-b595b0655735"/> > + <parameters typeid="2193047" typeidversion="3"/> > </virtualport> > </portgroup> > <portgroup name="alice"> > <virtualport type="802.1Qbg"> > - <parameters managerid="13" typeid="3193047" typeidversion="4" instanceid="70bf45f9-01a8-f5ee-3c0f-e25a0a2e44a6"/> > + <parameters managerid="13"/> > </virtualport> > </portgroup> > </network> > diff --git a/tests/networkxml2xmlout/openvswitch-net.xml b/tests/networkxml2xmlout/openvswitch-net.xml > new file mode 100644 > index 0000000..8aa1897 > --- /dev/null > +++ b/tests/networkxml2xmlout/openvswitch-net.xml > @@ -0,0 +1,16 @@ > +<network> > + <name>openvswitch-net</name> > + <uuid>81ff0d90-c92e-6742-64da-4a736edb9a8b</uuid> > + <forward mode='bridge'/> > + <virtualport type='openvswitch'/> > + <portgroup name='bob' default='yes'> > + <virtualport> > + <parameters profileid='bob-profile'/> > + </virtualport> > + </portgroup> > + <portgroup name='alice'> > + <virtualport> > + <parameters profileid='alice-profile'/> > + </virtualport> > + </portgroup> > +</network> > diff --git a/tests/networkxml2xmlout/vepa-net.xml b/tests/networkxml2xmlout/vepa-net.xml > index af13d0f..4d35a8a 100644 > --- a/tests/networkxml2xmlout/vepa-net.xml > +++ b/tests/networkxml2xmlout/vepa-net.xml > @@ -7,16 +7,16 @@ > <interface dev='eth3'/> > </forward> > <virtualport type='802.1Qbg'> > - <parameters managerid='11' typeid='1193047' typeidversion='2' instanceid='b153fa89-1b87-9719-ec12-99e0054fb844'/> > + <parameters managerid='11' typeid='1193047' typeidversion='2'/> > </virtualport> > <portgroup name='bob' default='yes'> > <virtualport type='802.1Qbg'> > - <parameters managerid='12' typeid='2193047' typeidversion='3' instanceid='5d00e0ba-e15c-959c-fbb6-b595b0655735'/> > + <parameters typeid='2193047' typeidversion='3'/> > </virtualport> > </portgroup> > <portgroup name='alice'> > <virtualport type='802.1Qbg'> > - <parameters managerid='13' typeid='3193047' typeidversion='4' instanceid='70bf45f9-01a8-f5ee-3c0f-e25a0a2e44a6'/> > + <parameters managerid='13'/> > </virtualport> > </portgroup> > </network> > diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c > index 8641c41..5a5531a 100644 > --- a/tests/networkxml2xmltest.c > +++ b/tests/networkxml2xmltest.c > @@ -104,6 +104,7 @@ mymain(void) > DO_TEST("host-bridge-net"); > DO_TEST("vepa-net"); > DO_TEST("bandwidth-network"); > + DO_TEST("openvswitch-net"); > DO_TEST_FULL("passthrough-pf", VIR_NETWORK_XML_INACTIVE); > > return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE; > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-network-portgroup.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-network-portgroup.xml > index 3eb5c88..6d379a0 100644 > --- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-network-portgroup.xml > +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-network-portgroup.xml > @@ -29,6 +29,20 @@ > </virtualport> > <model type='virtio'/> > </interface> > + <interface type='network'> > + <mac address='10:11:22:33:44:55'/> > + <source network='blue' portgroup='sam'/> > + <virtualport> > + <parameters instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f' interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/> > + </virtualport> > + </interface> > + <interface type='network'> > + <mac address='22:11:22:33:44:55'/> > + <source network='blue' portgroup='sam'/> > + <virtualport type='802.1Qbh'> > + <parameters profileid='testhis99'/> > + </virtualport> > + </interface> > <memballoon model='virtio'/> > </devices> > </domain> > -- > 1.7.11.2 > > -- > libvir-list mailing list > libvir-list@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/libvir-list -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list