[libvirt] [PATCHv2 8/9] conf: support partially-specified <virtualport> in parser and formatter
Kyle Mestery (kmestery)
kmestery at cisco.com
Tue Aug 14 13:32:56 UTC 2012
This looks good to me.
Acked-by: Kyle Mestery <kmestery at cisco.com>
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 at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
More information about the libvir-list
mailing list