[libvirt] [PATCH] vepa: parsing for 802.1Qb{g|h} XML

Daniel P. Berrange berrange at redhat.com
Tue May 11 10:25:05 UTC 2010


On Mon, May 10, 2010 at 07:57:37PM -0400, Stefan Berger wrote:
> Below is David Alan's original patch with lots of changes. 
> 
> In particular, it now parses the following XML and stored the data
> internally. No sending of netlink messages has been implemented here.
> 
>    <interface type='direct'>
>       <source dev='static' mode='vepa'/>
>       <model type='virtio'/>
>       <vsi managerid='12' typeid='0x123456' typeidversion='1'
>            instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f' />
>       <filterref filter='clean-traffic'/>
>     </interface>
> 
>     <interface type='direct'>
>       <source dev='static' mode='vepa'/>
>       <model type='virtio'/>
>       <vsi profileid='my_profile'/>
>     </interface>

Could we have an explanation of what these attributes all mean in
the commit message. 

Also, when we have 2 different sets of attributes, we normally use
a type attribute on the element to tell the parser what set of
data to expect. So I think this should gain a 'type' attribute here.

> @@ -1873,6 +1879,20 @@ virDomainNetDefParseXML(virCapsPtr caps,
>                         xmlStrEqual(cur->name, BAD_CAST "source")) {
>                  dev  = virXMLPropString(cur, "dev");
>                  mode = virXMLPropString(cur, "mode");
> +            } else if ((vsiManagerID == NULL) &&
> +                       (vsiTypeID == NULL) &&
> +                       (vsiTypeIDVersion == NULL) &&
> +                       (vsiInstanceID == NULL) &&
> +                       (vsiProfileID == NULL) &&
> +                       (def->type == VIR_DOMAIN_NET_TYPE_DIRECT) &&
> +                       xmlStrEqual(cur->name, BAD_CAST "vsi")) {
> +                vsiManagerID = virXMLPropString(cur, "managerid");
> +                vsiTypeID = virXMLPropString(cur, "typeid");
> +                vsiTypeIDVersion = virXMLPropString(cur,
> "typeidversion");
> +                vsiInstanceID = virXMLPropString(cur, "instanceid");
> +#ifdef IFLA_VF_PORT_PROFILE_MAX
> +                vsiProfileID = virXMLPropString(cur, "profileid");
> +#endif

XML parsing routines should not be #ifdefd. The XML format is formally
defined by the schema and must never change based on compile time options.

>              } else if ((network == NULL) &&
>                         ((def->type == VIR_DOMAIN_NET_TYPE_SERVER) ||
>                          (def->type == VIR_DOMAIN_NET_TYPE_CLIENT) ||
> @@ -2049,6 +2069,51 @@ virDomainNetDefParseXML(virCapsPtr caps,
>          } else
>              def->data.direct.mode =
> VIR_DOMAIN_NETDEV_MACVTAP_MODE_VEPA;
>  
> +        vsi = &def->data.direct.vsiProfile;
> +
> +#ifdef IFLA_VF_PORT_PROFILE_MAX
> +        if (vsiProfileID != NULL) {
> +            if (virStrcpyStatic(vsi->u.vsi8021Qbh.profileID,
> +                                vsiProfileID) != NULL) {
> +                vsi->vsiType = VIR_VSI_8021QBH;
> +                break;
> +            }
> +        }
> +#endif

Likewise here

> +
> +        while (vsiManagerID     != NULL && vsiTypeID     != NULL &&
> +               vsiTypeIDVersion != NULL && vsiInstanceID != NULL) {
> +            unsigned int val;
> +
> +            if ((virStrToLong_ui(vsiManagerID, NULL, 10, &val) &&
> +                 virStrToLong_ui(vsiManagerID, NULL, 16, &val)   ) ||
> +                val > 0xff)
> +                break;
> +
> +            vsi->u.vsi8021Qbg.managerID = (uint8_t)val;
> +
> +            if ((virStrToLong_ui(vsiTypeID, NULL, 10, &val) &&
> +                 virStrToLong_ui(vsiTypeID, NULL, 16, &val)   ) ||
> +                val > 0xffffff)
> +                break;
> +
> +            vsi->u.vsi8021Qbg.typeID = (uint32_t)val;
> +
> +            if ((virStrToLong_ui(vsiTypeIDVersion, NULL, 10, &val) &&
> +                 virStrToLong_ui(vsiTypeIDVersion, NULL, 16, &val)   )
> ||
> +                val > 0xff)
> +                break;
> +
> +            vsi->u.vsi8021Qbg.typeIDVersion = (uint8_t)val;
> +
> +            if (virUUIDParse(vsiInstanceID,
> +
> def->data.direct.vsiProfile.u.vsi8021Qbg.instanceID))
> +                break;
> +
> +            vsi->vsiType = VIR_VSI_8021QBG;
> +            break;
> +        }
> +
>          def->data.direct.linkdev = dev;
>          dev = NULL;
>  
> @@ -2114,6 +2179,11 @@ cleanup:
>      VIR_FREE(internal);
>      VIR_FREE(devaddr);
>      VIR_FREE(mode);
> +    VIR_FREE(vsiManagerID);
> +    VIR_FREE(vsiTypeID);
> +    VIR_FREE(vsiTypeIDVersion);
> +    VIR_FREE(vsiInstanceID);
> +    VIR_FREE(vsiProfileID);
>      virNWFilterHashTableFree(filterparams);
>  
>      return def;
> @@ -5076,6 +5146,8 @@ virDomainNetDefFormat(virBufferPtr buf,
>  {
>      const char *type = virDomainNetTypeToString(def->type);
>      char *attrs;
> +    char uuidstr[VIR_UUID_STRING_BUFLEN];
> +    virVSIProfileDefPtr vsi;
>  
>      if (!type) {
>          virDomainReportError(VIR_ERR_INTERNAL_ERROR,
> @@ -5141,6 +5213,31 @@ virDomainNetDefFormat(virBufferPtr buf,
>          virBufferVSprintf(buf, " mode='%s'",
> 
> virDomainNetdevMacvtapTypeToString(def->data.direct.mode));
>          virBufferAddLit(buf, "/>\n");
> +        vsi = &def->data.direct.vsiProfile;
> +        switch (vsi->vsiType) {
> +        case VIR_VSI_INVALID:
> +            break;
> +
> +        case VIR_VSI_8021QBG:
> +
> virUUIDFormat(def->data.direct.vsiProfile.u.vsi8021Qbg.instanceID,
> +                          uuidstr);
> +            virBufferVSprintf(buf,
> +                              "      <vsi managerid='%d' typeid='%d' "
> +                              "typeidversion='%d' instanceid='%s'/>\n",
> +                              vsi->u.vsi8021Qbg.managerID,
> +                              vsi->u.vsi8021Qbg.typeID,
> +                              vsi->u.vsi8021Qbg.typeIDVersion,
> +                              uuidstr);
> +            break;
> +
> +#ifdef IFLA_VF_PORT_PROFILE_MAX
> +        case VIR_VSI_8021QBH:
> +            virBufferVSprintf(buf,
> +                              "      <vsi profileid='%s'/>\n",
> +                              vsi->u.vsi8021Qbh.profileID);
> +            break;
> +#endif
> +        }
>          break;
>  
>      case VIR_DOMAIN_NET_TYPE_USER:
> Index: libvirt-acl/src/conf/domain_conf.h
> ===================================================================
> --- libvirt-acl.orig/src/conf/domain_conf.h
> +++ libvirt-acl/src/conf/domain_conf.h
> @@ -259,6 +259,36 @@ enum virDomainNetdevMacvtapType {
>  };
>  
>  
> +#define IFLA_VF_PORT_PROFILE_MAX 40
> +enum virVSIType {
> +    VIR_VSI_INVALID,

This isn't really 'INVALID' - this is better named 'NONE'
since its simply an indication that this interface does not
have any VSI info defined

> +    VIR_VSI_8021QBG,
> +#ifdef IFLA_VF_PORT_PROFILE_MAX
> +    VIR_VSI_8021QBH,
> +#endif

And here, etc

> +};
> +
> +/* profile data for macvtap (VEPA) */
> +typedef struct _virVSIProfileDef virVSIProfileDef;
> +typedef virVSIProfileDef *virVSIProfileDefPtr;
> +struct _virVSIProfileDef {
> +    enum virVSIType   vsiType;
> +    union {
> +        struct {
> +            uint8_t       managerID;
> +            uint32_t      typeID; // 24 bit valid
> +            uint8_t       typeIDVersion;
> +            unsigned char instanceID[VIR_UUID_BUFLEN];
> +        } vsi8021Qbg;
> +#ifdef IFLA_VF_PORT_PROFILE_MAX
> +        struct {
> +            char          profileID[IFLA_VF_PORT_PROFILE_MAX];
> +        } vsi8021Qbh;
> +#endif
> +    } u;
> +};

> Index: libvirt-acl/tests/domainschemadata/portprofile.xml
> ===================================================================
> --- /dev/null
> +++ libvirt-acl/tests/domainschemadata/portprofile.xml
> @@ -0,0 +1,27 @@
> +<domain type='lxc'>
> +  <name>portprofile</name>
> +  <uuid>00000000-0000-0000-0000-000000000000</uuid>
> +  <memory>1048576</memory>
> +    <os>
> +        <type>exe</type>
> +        <init>/sh</init>
> +    </os>
> +  <devices>
> +    <interface type='direct'>
> +      <source dev='eth0' mode='vepa'/>
> +      <vsi managerid='12' typeid='1193046' typeidversion='1'
> +      instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f'/>
> +    </interface>
> +    <interface type='direct'>
> +      <source dev='eth0' mode='vepa'/>
> +      <vsi profileid='my_profile'/>
> +    </interface>
> +    <interface type='direct'>
> +      <source dev='eth0' mode='vepa'/>
> +      <vsi/>
> +    </interface>
> +    <interface type='direct'>
> +      <source dev='eth0' mode='vepa'/>
> +    </interface>
> +  </devices>
> +</domain>
> Index: libvirt-acl/src/qemu/qemu_conf.h
> ===================================================================
> --- libvirt-acl.orig/src/qemu/qemu_conf.h
> +++ libvirt-acl/src/qemu/qemu_conf.h
> @@ -271,8 +271,6 @@ qemudOpenVhostNet(virDomainNetDefPtr net
>  int qemudPhysIfaceConnect(virConnectPtr conn,
>                            struct qemud_driver *driver,
>                            virDomainNetDefPtr net,
> -                          char *linkdev,
> -                          int brmode,
>                            unsigned long long qemuCmdFlags);
>  
>  int         qemudProbeMachineTypes      (const char *binary,
> Index: libvirt-acl/src/qemu/qemu_driver.c
> ===================================================================
> --- libvirt-acl.orig/src/qemu/qemu_driver.c
> +++ libvirt-acl/src/qemu/qemu_driver.c
> @@ -3585,10 +3585,8 @@ static void qemudShutdownVMDaemon(struct
>      def = vm->def;
>      for (i = 0; i < def->nnets; i++) {
>          virDomainNetDefPtr net = def->nets[i];
> -        if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
> -            if (net->ifname)
> -                delMacvtap(net->ifname);
> -        }
> +        if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT)
> +            delMacvtap(net);
>      }
>  #endif
>  
> @@ -7175,8 +7173,6 @@ static int qemudDomainAttachNetDevice(vi
>          }
>  
>          if ((tapfd = qemudPhysIfaceConnect(conn, driver, net,
> -                                           net->data.direct.linkdev,
> -                                           net->data.direct.mode,
>                                             qemuCmdFlags)) < 0)
>              return -1;
>      }
> @@ -8146,10 +8142,8 @@ qemudDomainDetachNetDevice(struct qemud_
>      virNWFilterTearNWFilter(detach);
>  
>  #if WITH_MACVTAP
> -    if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
> -        if (detach->ifname)
> -            delMacvtap(detach->ifname);
> -    }
> +    if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT)
> +        delMacvtap(detach);
>  #endif
>  
>      if ((driver->macFilter) && (detach->ifname != NULL)) {


Regards,
Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list