[libvirt] [PATCH 05/10] conf: put virtPortProfile struct / functions in a common location

Laine Stump laine at laine.org
Tue Jul 5 07:45:53 UTC 2011


virtPortProfiles are currently only used in the domain XML, but will
soon also be used in the network XML. To prepare for that change, this
patch moves the structure definition into util/network.h and the parse
and format functions into util/network.c (I decided that this was a
better choice than macvtap.h/c for something that needed to always be
available on all platforms).

Additionally, the virtPortProfile in the domain interface struct is
now a separately allocated object rather *pointed to by* (rather than
contained in) the main virDomainNetDef object. This is done to make is
easier to figure out when a virtualPortProfile has/hasn't been
specified in a particular config.
---
 src/conf/domain_conf.c    |  208 +++------------------------------------------
 src/conf/domain_conf.h    |    2 +-
 src/libvirt_private.syms  |    2 +
 src/qemu/qemu_command.c   |    4 +-
 src/qemu/qemu_hotplug.c   |    2 +-
 src/qemu/qemu_migration.c |    4 +-
 src/qemu/qemu_process.c   |    2 +-
 src/util/macvtap.c        |    6 +-
 src/util/macvtap.h        |   36 +--------
 src/util/network.c        |  196 ++++++++++++++++++++++++++++++++++++++++++
 src/util/network.h        |   47 ++++++++++
 11 files changed, 271 insertions(+), 238 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 772422d..66a7c59 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -447,11 +447,6 @@ VIR_ENUM_IMPL(virDomainSeclabel, VIR_DOMAIN_SECLABEL_LAST,
               "dynamic",
               "static")
 
-VIR_ENUM_IMPL(virVirtualPort, VIR_VIRTUALPORT_TYPE_LAST,
-              "none",
-              "802.1Qbg",
-              "802.1Qbh")
-
 VIR_ENUM_IMPL(virDomainClockOffset, VIR_DOMAIN_CLOCK_OFFSET_LAST,
               "utc",
               "localtime",
@@ -755,6 +750,7 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
 
     case VIR_DOMAIN_NET_TYPE_DIRECT:
         VIR_FREE(def->data.direct.linkdev);
+        VIR_FREE(def->data.direct.virtPortProfile);
         break;
 
     case VIR_DOMAIN_NET_TYPE_USER:
@@ -2571,146 +2567,6 @@ cleanup:
 }
 
 
-static int
-virVirtualPortProfileParamsParseXML(xmlNodePtr node,
-                                    virVirtualPortProfileParamsPtr virtPort)
-{
-    int ret = -1;
-    char *virtPortType;
-    char *virtPortManagerID = NULL;
-    char *virtPortTypeID = NULL;
-    char *virtPortTypeIDVersion = NULL;
-    char *virtPortInstanceID = NULL;
-    char *virtPortProfileID = NULL;
-    xmlNodePtr cur = node->children;
-    const char *msg = NULL;
-
-    virtPortType = virXMLPropString(node, "type");
-    if (!virtPortType)
-        return -1;
-
-    while (cur != NULL) {
-        if (xmlStrEqual(cur->name, BAD_CAST "parameters")) {
-
-            virtPortManagerID = virXMLPropString(cur, "managerid");
-            virtPortTypeID = virXMLPropString(cur, "typeid");
-            virtPortTypeIDVersion = virXMLPropString(cur, "typeidversion");
-            virtPortInstanceID = virXMLPropString(cur, "instanceid");
-            virtPortProfileID = virXMLPropString(cur, "profileid");
-
-            break;
-        }
-
-        cur = cur->next;
-    }
-
-    virtPort->virtPortType = VIR_VIRTUALPORT_NONE;
-
-    switch (virVirtualPortTypeFromString(virtPortType)) {
-
-    case VIR_VIRTUALPORT_8021QBG:
-        if (virtPortManagerID     != NULL && virtPortTypeID     != NULL &&
-            virtPortTypeIDVersion != NULL) {
-            unsigned int val;
-
-            if (virStrToLong_ui(virtPortManagerID, NULL, 0, &val)) {
-                msg = _("cannot parse value of managerid parameter");
-                goto err_exit;
-            }
-
-            if (val > 0xff) {
-                msg = _("value of managerid out of range");
-                goto err_exit;
-            }
-
-            virtPort->u.virtPort8021Qbg.managerID = (uint8_t)val;
-
-            if (virStrToLong_ui(virtPortTypeID, NULL, 0, &val)) {
-                msg = _("cannot parse value of typeid parameter");
-                goto err_exit;
-            }
-
-            if (val > 0xffffff) {
-                msg = _("value for typeid out of range");
-                goto err_exit;
-            }
-
-            virtPort->u.virtPort8021Qbg.typeID = (uint32_t)val;
-
-            if (virStrToLong_ui(virtPortTypeIDVersion, NULL, 0, &val)) {
-                msg = _("cannot parse value of typeidversion parameter");
-                goto err_exit;
-            }
-
-            if (val > 0xff) {
-                msg = _("value of typeidversion out of range");
-                goto err_exit;
-            }
-
-            virtPort->u.virtPort8021Qbg.typeIDVersion = (uint8_t)val;
-
-            if (virtPortInstanceID != NULL) {
-                if (virUUIDParse(virtPortInstanceID,
-                                 virtPort->u.virtPort8021Qbg.instanceID)) {
-                    msg = _("cannot parse instanceid parameter as a uuid");
-                    goto err_exit;
-                }
-            } else {
-                if (virUUIDGenerate(virtPort->u.virtPort8021Qbg.instanceID)) {
-                    msg = _("cannot generate a random uuid for instanceid");
-                    goto err_exit;
-                }
-            }
-
-            virtPort->virtPortType = VIR_VIRTUALPORT_8021QBG;
-            ret = 0;
-        } else {
-            msg = _("a parameter is missing for 802.1Qbg description");
-            goto err_exit;
-        }
-    break;
-
-    case VIR_VIRTUALPORT_8021QBH:
-        if (virtPortProfileID != NULL) {
-            if (virStrcpyStatic(virtPort->u.virtPort8021Qbh.profileID,
-                                virtPortProfileID) != NULL) {
-                virtPort->virtPortType = VIR_VIRTUALPORT_8021QBH;
-                ret = 0;
-            } else {
-                msg = _("profileid parameter too long");
-                goto err_exit;
-            }
-        } else {
-            msg = _("profileid parameter is missing for 802.1Qbh descripion");
-            goto err_exit;
-        }
-    break;
-
-
-    default:
-    case VIR_VIRTUALPORT_NONE:
-    case VIR_VIRTUALPORT_TYPE_LAST:
-        msg = _("unknown virtualport type");
-        goto err_exit;
-    break;
-    }
-
-err_exit:
-
-    if (msg)
-        virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", msg);
-
-    VIR_FREE(virtPortManagerID);
-    VIR_FREE(virtPortTypeID);
-    VIR_FREE(virtPortTypeIDVersion);
-    VIR_FREE(virtPortInstanceID);
-    VIR_FREE(virtPortProfileID);
-    VIR_FREE(virtPortType);
-
-    return ret;
-}
-
-
 /* Parse the XML definition for a network interface
  * @param node XML nodeset to parse for net definition
  * @return 0 on success, -1 on failure
@@ -2742,8 +2598,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
     char *devaddr = NULL;
     char *mode = NULL;
     virNWFilterHashTablePtr filterparams = NULL;
-    virVirtualPortProfileParams virtPort;
-    bool virtPortParsed = false;
+    virVirtualPortProfileParamsPtr virtPort = NULL;
     xmlNodePtr oldnode = ctxt->node;
     int ret;
 
@@ -2789,12 +2644,15 @@ virDomainNetDefParseXML(virCapsPtr caps,
                        xmlStrEqual(cur->name, BAD_CAST "source")) {
                 dev  = virXMLPropString(cur, "dev");
                 mode = virXMLPropString(cur, "mode");
-            } else if (!virtPortParsed &&
+            } else if ((virtPort == NULL) &&
                        (def->type == VIR_DOMAIN_NET_TYPE_DIRECT) &&
                        xmlStrEqual(cur->name, BAD_CAST "virtualport")) {
-                if (virVirtualPortProfileParamsParseXML(cur, &virtPort))
+                const char *errmsg;
+                if (virVirtualPortProfileParamsParseXML(cur, &virtPort, &errmsg) < 0) {
+                    if (errmsg)
+                        virDomainReportError(VIR_ERR_XML_ERROR, "%s", errmsg);
                     goto error;
-                virtPortParsed = true;
+                }
             } else if ((network == NULL) &&
                        ((def->type == VIR_DOMAIN_NET_TYPE_SERVER) ||
                         (def->type == VIR_DOMAIN_NET_TYPE_CLIENT) ||
@@ -2978,8 +2836,10 @@ virDomainNetDefParseXML(virCapsPtr caps,
         } else
             def->data.direct.mode = VIR_MACVTAP_MODE_VEPA;
 
-        if (virtPortParsed)
+        if (virtPort) {
             def->data.direct.virtPortProfile = virtPort;
+            virtPort = NULL;
+        }
 
         def->data.direct.linkdev = dev;
         dev = NULL;
@@ -3087,6 +2947,7 @@ cleanup:
     VIR_FREE(port);
     VIR_FREE(ifname);
     VIR_FREE(dev);
+    VIR_FREE(virtPort);
     VIR_FREE(script);
     VIR_FREE(bridge);
     VIR_FREE(model);
@@ -5270,49 +5131,6 @@ virDomainChrTargetTypeToString(int deviceType,
     return type;
 }
 
-static void
-virVirtualPortProfileFormat(virBufferPtr buf,
-                            virVirtualPortProfileParamsPtr virtPort,
-                            const char *indent)
-{
-    char uuidstr[VIR_UUID_STRING_BUFLEN];
-
-    if (virtPort->virtPortType == VIR_VIRTUALPORT_NONE)
-        return;
-
-    virBufferAsprintf(buf, "%s<virtualport type='%s'>\n",
-                      indent,
-                      virVirtualPortTypeToString(virtPort->virtPortType));
-
-    switch (virtPort->virtPortType) {
-    case VIR_VIRTUALPORT_NONE:
-    case VIR_VIRTUALPORT_TYPE_LAST:
-        break;
-
-    case VIR_VIRTUALPORT_8021QBG:
-        virUUIDFormat(virtPort->u.virtPort8021Qbg.instanceID,
-                      uuidstr);
-        virBufferAsprintf(buf,
-                          "%s  <parameters managerid='%d' typeid='%d' "
-                          "typeidversion='%d' instanceid='%s'/>\n",
-                          indent,
-                          virtPort->u.virtPort8021Qbg.managerID,
-                          virtPort->u.virtPort8021Qbg.typeID,
-                          virtPort->u.virtPort8021Qbg.typeIDVersion,
-                          uuidstr);
-        break;
-
-    case VIR_VIRTUALPORT_8021QBH:
-        virBufferAsprintf(buf,
-                          "%s  <parameters profileid='%s'/>\n",
-                          indent,
-                          virtPort->u.virtPort8021Qbh.profileID);
-        break;
-    }
-
-    virBufferAsprintf(buf, "%s</virtualport>\n", indent);
-}
-
 int virDomainDiskIndexByName(virDomainDefPtr def, const char *name)
 {
     virDomainDiskDefPtr vdisk;
@@ -8674,7 +8492,7 @@ virDomainNetDefFormat(virBufferPtr buf,
         virBufferAsprintf(buf, " mode='%s'",
                    virMacvtapModeTypeToString(def->data.direct.mode));
         virBufferAddLit(buf, "/>\n");
-        virVirtualPortProfileFormat(buf, &def->data.direct.virtPortProfile,
+        virVirtualPortProfileFormat(buf, def->data.direct.virtPortProfile,
                                     "      ");
         break;
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9d28f51..f8771a9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -386,7 +386,7 @@ struct _virDomainNetDef {
         struct {
             char *linkdev;
             int mode; /* enum virMacvtapMode from util/macvtap.h */
-            virVirtualPortProfileParams virtPortProfile;
+            virVirtualPortProfileParamsPtr virtPortProfile;
         } direct;
     } data;
     struct {
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 626ac6c..a7540d2 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -695,6 +695,8 @@ virSocketParseAddr;
 virSocketParseIpv4Addr;
 virSocketParseIpv6Addr;
 virSocketSetPort;
+virVirtualPortProfileFormat;
+virVirtualPortProfileParamsParseXML;
 
 
 # network_conf.h
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6e4480e..bd47eae 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -127,7 +127,7 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
 
     rc = openMacvtapTap(net->ifname, net->mac, net->data.direct.linkdev,
                         net->data.direct.mode, vnet_hdr, def->uuid,
-                        &net->data.direct.virtPortProfile, &res_ifname,
+                        net->data.direct.virtPortProfile, &res_ifname,
                         vmop, driver->stateDir);
     if (rc >= 0) {
         qemuAuditNetDevice(def, net, res_ifname, true);
@@ -150,7 +150,7 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
                 VIR_FORCE_CLOSE(rc);
                 delMacvtap(net->ifname, net->mac, net->data.direct.linkdev,
                            net->data.direct.mode,
-                           &net->data.direct.virtPortProfile,
+                           net->data.direct.virtPortProfile,
                            driver->stateDir);
                 VIR_FREE(net->ifname);
             }
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index a7f11ab..5049f6e 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1611,7 +1611,7 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver,
     if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
         delMacvtap(detach->ifname, detach->mac, detach->data.direct.linkdev,
                    detach->data.direct.mode,
-                   &detach->data.direct.virtPortProfile,
+                   detach->data.direct.virtPortProfile,
                    driver->stateDir);
         VIR_FREE(detach->ifname);
     }
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index d7b27a0..9622021 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2398,7 +2398,7 @@ qemuMigrationVPAssociatePortProfiles(virDomainDefPtr def) {
             if (vpAssociatePortProfileId(net->ifname,
                                          net->mac,
                                          net->data.direct.linkdev,
-                                         &net->data.direct.virtPortProfile,
+                                         net->data.direct.virtPortProfile,
                                          def->uuid,
                                          VIR_VM_OP_MIGRATE_IN_FINISH) != 0)
                 goto err_exit;
@@ -2415,7 +2415,7 @@ err_exit:
             vpDisassociatePortProfileId(net->ifname,
                                         net->mac,
                                         net->data.direct.linkdev,
-                                        &net->data.direct.virtPortProfile,
+                                        net->data.direct.virtPortProfile,
                                         VIR_VM_OP_MIGRATE_IN_FINISH);
         }
     }
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index f2c439b..fa7face 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2905,7 +2905,7 @@ void qemuProcessStop(struct qemud_driver *driver,
         if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
             delMacvtap(net->ifname, net->mac, net->data.direct.linkdev,
                        net->data.direct.mode,
-                       &net->data.direct.virtPortProfile, driver->stateDir);
+                       net->data.direct.virtPortProfile, driver->stateDir);
             VIR_FREE(net->ifname);
         }
     }
diff --git a/src/util/macvtap.c b/src/util/macvtap.c
index 30343c8..052f76b 100644
--- a/src/util/macvtap.c
+++ b/src/util/macvtap.c
@@ -50,6 +50,7 @@
 
 #include "util.h"
 #include "macvtap.h"
+#include "network.h"
 
 VIR_ENUM_IMPL(virMacvtapMode, VIR_MACVTAP_MODE_LAST,
               "vepa",
@@ -1089,7 +1090,7 @@ vpAssociatePortProfileId(const char *macvtap_ifname,
 
     VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virVMOperationTypeToString(vmOp));
 
-    if (vmOp == VIR_VM_OP_NO_OP)
+    if (!virtPort || vmOp == VIR_VM_OP_NO_OP)
         return 0;
 
     switch (virtPort->virtPortType) {
@@ -1145,6 +1146,9 @@ vpDisassociatePortProfileId(const char *macvtap_ifname,
 
     VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virVMOperationTypeToString(vmOp));
 
+    if (!virtPort)
+       return 0;
+
     switch (virtPort->virtPortType) {
     case VIR_VIRTUALPORT_NONE:
     case VIR_VIRTUALPORT_TYPE_LAST:
diff --git a/src/util/macvtap.h b/src/util/macvtap.h
index 1b85989..8e8613d 100644
--- a/src/util/macvtap.h
+++ b/src/util/macvtap.h
@@ -25,15 +25,6 @@
 
 # include <config.h>
 
-
-enum virVirtualPortType {
-    VIR_VIRTUALPORT_NONE,
-    VIR_VIRTUALPORT_8021QBG,
-    VIR_VIRTUALPORT_8021QBH,
-
-    VIR_VIRTUALPORT_TYPE_LAST,
-};
-
 /* the mode type for macvtap devices */
 enum virMacvtapMode {
     VIR_MACVTAP_MODE_VEPA,
@@ -44,31 +35,6 @@ enum virMacvtapMode {
     VIR_MACVTAP_MODE_LAST,
 };
 
-
-# ifdef IFLA_VF_PORT_PROFILE_MAX
-#  define LIBVIRT_IFLA_VF_PORT_PROFILE_MAX IFLA_VF_PORT_PROFILE_MAX
-# else
-#  define LIBVIRT_IFLA_VF_PORT_PROFILE_MAX 40
-# endif
-
-/* profile data for macvtap (VEPA) */
-typedef struct _virVirtualPortProfileParams virVirtualPortProfileParams;
-typedef virVirtualPortProfileParams *virVirtualPortProfileParamsPtr;
-struct _virVirtualPortProfileParams {
-    enum virVirtualPortType   virtPortType;
-    union {
-        struct {
-            uint8_t       managerID;
-            uint32_t      typeID; /* 24 bit valid */
-            uint8_t       typeIDVersion;
-            unsigned char instanceID[VIR_UUID_BUFLEN];
-        } virtPort8021Qbg;
-        struct {
-            char          profileID[LIBVIRT_IFLA_VF_PORT_PROFILE_MAX];
-        } virtPort8021Qbh;
-    } u;
-};
-
 enum virVMOperationType {
     VIR_VM_OP_CREATE,
     VIR_VM_OP_SAVE,
@@ -85,6 +51,7 @@ enum virVMOperationType {
 # if WITH_MACVTAP
 
 #  include "internal.h"
+#  include "network.h"
 
 int openMacvtapTap(const char *ifname,
                    const unsigned char *macaddress,
@@ -119,7 +86,6 @@ int vpDisassociatePortProfileId(const char *macvtap_ifname,
 
 # endif /* WITH_MACVTAP */
 
-VIR_ENUM_DECL(virVirtualPort)
 VIR_ENUM_DECL(virVMOperation)
 VIR_ENUM_DECL(virMacvtapMode)
 
diff --git a/src/util/network.c b/src/util/network.c
index eb16e0c..6f5458a 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -12,6 +12,7 @@
 #include <arpa/inet.h>
 
 #include "memory.h"
+#include "uuid.h"
 #include "network.h"
 #include "util.h"
 #include "virterror_internal.h"
@@ -674,3 +675,198 @@ virSocketAddrPrefixToNetmask(unsigned int prefix,
 error:
     return result;
 }
+
+/* virtualPortProfile utilities */
+
+VIR_ENUM_IMPL(virVirtualPort, VIR_VIRTUALPORT_TYPE_LAST,
+              "none",
+              "802.1Qbg",
+              "802.1Qbh")
+
+int
+virVirtualPortProfileParamsParseXML(xmlNodePtr node,
+                                    virVirtualPortProfileParamsPtr *virtPort,
+                                    const char **errmsg)
+{
+    int ret = -1;
+    char *virtPortType;
+    char *virtPortManagerID = NULL;
+    char *virtPortTypeID = NULL;
+    char *virtPortTypeIDVersion = NULL;
+    char *virtPortInstanceID = NULL;
+    char *virtPortProfileID = NULL;
+    xmlNodePtr cur = node->children;
+
+    *errmsg = NULL;
+    if (VIR_ALLOC(*virtPort) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    virtPortType = virXMLPropString(node, "type");
+    if (!virtPortType) {
+        *errmsg = _("missing virtualportprofile 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");
+            virtPortInstanceID = virXMLPropString(cur, "instanceid");
+            virtPortProfileID = virXMLPropString(cur, "profileid");
+
+            break;
+        }
+
+        cur = cur->next;
+    }
+
+    (*virtPort)->virtPortType = VIR_VIRTUALPORT_NONE;
+
+    switch (virVirtualPortTypeFromString(virtPortType)) {
+
+    case VIR_VIRTUALPORT_8021QBG:
+        if (virtPortManagerID     != NULL && virtPortTypeID     != NULL &&
+            virtPortTypeIDVersion != NULL) {
+            unsigned int val;
+
+            if (virStrToLong_ui(virtPortManagerID, NULL, 0, &val)) {
+                *errmsg = _("cannot parse value of managerid parameter");
+                goto error;
+            }
+
+            if (val > 0xff) {
+                *errmsg = _("value of managerid out of range");
+                goto error;
+            }
+
+            (*virtPort)->u.virtPort8021Qbg.managerID = (uint8_t)val;
+
+            if (virStrToLong_ui(virtPortTypeID, NULL, 0, &val)) {
+                *errmsg = _("cannot parse value of typeid parameter");
+                goto error;
+            }
+
+            if (val > 0xffffff) {
+                *errmsg = _("value for typeid out of range");
+                goto error;
+            }
+
+            (*virtPort)->u.virtPort8021Qbg.typeID = (uint32_t)val;
+
+            if (virStrToLong_ui(virtPortTypeIDVersion, NULL, 0, &val)) {
+                *errmsg = _("cannot parse value of typeidversion parameter");
+                goto error;
+            }
+
+            if (val > 0xff) {
+                *errmsg = _("value of typeidversion out of range");
+                goto error;
+            }
+
+            (*virtPort)->u.virtPort8021Qbg.typeIDVersion = (uint8_t)val;
+
+            if (virtPortInstanceID != NULL) {
+                if (virUUIDParse(virtPortInstanceID,
+                                 (*virtPort)->u.virtPort8021Qbg.instanceID)) {
+                    *errmsg = _("cannot parse instanceid parameter as a uuid");
+                    goto error;
+                }
+            } else {
+                if (virUUIDGenerate((*virtPort)->u.virtPort8021Qbg.instanceID)) {
+                    *errmsg = _("cannot generate a random uuid for instanceid");
+                    goto error;
+                }
+            }
+
+            (*virtPort)->virtPortType = VIR_VIRTUALPORT_8021QBG;
+            ret = 0;
+        } else {
+            *errmsg = _("a parameter is missing for 802.1Qbg description");
+            goto error;
+        }
+    break;
+
+    case VIR_VIRTUALPORT_8021QBH:
+        if (virtPortProfileID != NULL) {
+            if (virStrcpyStatic((*virtPort)->u.virtPort8021Qbh.profileID,
+                                virtPortProfileID) != NULL) {
+                (*virtPort)->virtPortType = VIR_VIRTUALPORT_8021QBH;
+                ret = 0;
+            } else {
+                *errmsg = _("profileid parameter too long");
+                goto error;
+            }
+        } else {
+            *errmsg = _("profileid parameter is missing for 802.1Qbh descripion");
+            goto error;
+        }
+    break;
+
+
+    default:
+    case VIR_VIRTUALPORT_NONE:
+    case VIR_VIRTUALPORT_TYPE_LAST:
+        *errmsg = _("unknown virtualport type");
+        goto error;
+    break;
+    }
+
+error:
+    if (ret < 0)
+        VIR_FREE(*virtPort);
+    VIR_FREE(virtPortManagerID);
+    VIR_FREE(virtPortTypeID);
+    VIR_FREE(virtPortTypeIDVersion);
+    VIR_FREE(virtPortInstanceID);
+    VIR_FREE(virtPortProfileID);
+    VIR_FREE(virtPortType);
+
+    return ret;
+}
+
+void
+virVirtualPortProfileFormat(virBufferPtr buf,
+                            virVirtualPortProfileParamsPtr virtPort,
+                            const char *indent)
+{
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+    if (!virtPort || virtPort->virtPortType == VIR_VIRTUALPORT_NONE)
+        return;
+
+    virBufferAsprintf(buf, "%s<virtualport type='%s'>\n",
+                      indent,
+                      virVirtualPortTypeToString(virtPort->virtPortType));
+
+    switch (virtPort->virtPortType) {
+    case VIR_VIRTUALPORT_NONE:
+    case VIR_VIRTUALPORT_TYPE_LAST:
+        break;
+
+    case VIR_VIRTUALPORT_8021QBG:
+        virUUIDFormat(virtPort->u.virtPort8021Qbg.instanceID,
+                      uuidstr);
+        virBufferAsprintf(buf,
+                          "%s  <parameters managerid='%d' typeid='%d' "
+                          "typeidversion='%d' instanceid='%s'/>\n",
+                          indent,
+                          virtPort->u.virtPort8021Qbg.managerID,
+                          virtPort->u.virtPort8021Qbg.typeID,
+                          virtPort->u.virtPort8021Qbg.typeIDVersion,
+                          uuidstr);
+        break;
+
+    case VIR_VIRTUALPORT_8021QBH:
+        virBufferAsprintf(buf,
+                          "%s  <parameters profileid='%s'/>\n",
+                          indent,
+                          virtPort->u.virtPort8021Qbh.profileID);
+        break;
+    }
+
+    virBufferAsprintf(buf, "%s</virtualport>\n", indent);
+}
diff --git a/src/util/network.h b/src/util/network.h
index ed0b78c..ab50178 100644
--- a/src/util/network.h
+++ b/src/util/network.h
@@ -12,6 +12,8 @@
 # define __VIR_NETWORK_H__
 
 # include "internal.h"
+# include "buf.h"
+# include "util.h"
 
 # include <sys/types.h>
 # include <sys/socket.h>
@@ -20,6 +22,7 @@
 # endif
 # include <netdb.h>
 # include <netinet/in.h>
+# include <xml.h>
 
 typedef struct {
     union {
@@ -90,4 +93,48 @@ int virSocketAddrPrefixToNetmask(unsigned int prefix,
                                  virSocketAddrPtr netmask,
                                  int family);
 
+/* virtualPortProfile utilities */
+# ifdef IFLA_VF_PORT_PROFILE_MAX
+#  define LIBVIRT_IFLA_VF_PORT_PROFILE_MAX IFLA_VF_PORT_PROFILE_MAX
+# else
+#  define LIBVIRT_IFLA_VF_PORT_PROFILE_MAX 40
+# endif
+
+enum virVirtualPortType {
+    VIR_VIRTUALPORT_NONE,
+    VIR_VIRTUALPORT_8021QBG,
+    VIR_VIRTUALPORT_8021QBH,
+
+    VIR_VIRTUALPORT_TYPE_LAST,
+};
+
+VIR_ENUM_DECL(virVirtualPort)
+
+/* profile data for macvtap (VEPA) */
+typedef struct _virVirtualPortProfileParams virVirtualPortProfileParams;
+typedef virVirtualPortProfileParams *virVirtualPortProfileParamsPtr;
+struct _virVirtualPortProfileParams {
+    enum virVirtualPortType   virtPortType;
+    union {
+        struct {
+            uint8_t       managerID;
+            uint32_t      typeID; /* 24 bit valid */
+            uint8_t       typeIDVersion;
+            unsigned char instanceID[VIR_UUID_BUFLEN];
+        } virtPort8021Qbg;
+        struct {
+            char          profileID[LIBVIRT_IFLA_VF_PORT_PROFILE_MAX];
+        } virtPort8021Qbh;
+    } u;
+};
+
+int
+virVirtualPortProfileParamsParseXML(xmlNodePtr node,
+                                    virVirtualPortProfileParamsPtr *virtPort,
+                                    const char **errmsg);
+void
+virVirtualPortProfileFormat(virBufferPtr buf,
+                            virVirtualPortProfileParamsPtr virtPort,
+                            const char *indent);
+
 #endif /* __VIR_NETWORK_H__ */
-- 
1.7.3.4




More information about the libvir-list mailing list