[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