conf: put virtPortProfile struct / functions in a common location

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).
This commit is contained in:
Laine Stump 2011-06-29 00:38:10 -04:00
parent 6fe5fde292
commit a3d95b550b
11 changed files with 309 additions and 269 deletions

View File

@ -8,6 +8,7 @@ schema_DATA = \
domainsnapshot.rng \
interface.rng \
network.rng \
networkcommon.rng \
nodedev.rng \
nwfilter.rng \
secret.rng \

View File

@ -7,6 +7,7 @@
<include href='basictypes.rng'/>
<include href='storageencryption.rng'/>
<include href='networkcommon.rng'/>
<!--
description element, maybe placed anywhere under the root
@ -1182,45 +1183,6 @@
</optional>
</interleave>
</define>
<define name="virtualPortProfile">
<choice>
<group>
<element name="virtualport">
<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>
</element>
</group>
<group>
<element name="virtualport">
<attribute name="type">
<value>802.1Qbh</value>
</attribute>
<element name="parameters">
<attribute name="profileid">
<ref name="virtualPortProfileID"/>
</attribute>
</element>
</element>
</group>
</choice>
</define>
<!--
An emulator description is just a path to the binary used for the task
-->
@ -2539,9 +2501,4 @@
<param name="pattern">[a-zA-Z0-9_\.:]+</param>
</data>
</define>
<define name="virtualPortProfileID">
<data type="string">
<param name="maxLength">39</param>
</data>
</define>
</grammar>

View File

@ -0,0 +1,50 @@
<?xml version="1.0"?>
<!-- network-related definitions used in multiple grammars -->
<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<define name="virtualPortProfileID">
<data type="string">
<param name="maxLength">39</param>
</data>
</define>
<define name="virtualPortProfile">
<choice>
<group>
<element name="virtualport">
<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>
</element>
</group>
<group>
<element name="virtualport">
<attribute name="type">
<value>802.1Qbh</value>
</attribute>
<element name="parameters">
<attribute name="profileid">
<ref name="virtualPortProfileID"/>
</attribute>
</element>
</element>
</group>
</choice>
</define>
</grammar>

View File

@ -1077,6 +1077,7 @@ fi
%{_datadir}/libvirt/schemas/storageencryption.rng
%{_datadir}/libvirt/schemas/nwfilter.rng
%{_datadir}/libvirt/schemas/basictypes.rng
%{_datadir}/libvirt/schemas/networkcommon.rng
%{_datadir}/libvirt/cpu_map.xml

View File

@ -109,6 +109,7 @@ rm -rf $RPM_BUILD_ROOT
%{_mingw32_datadir}/libvirt/schemas/secret.rng
%{_mingw32_datadir}/libvirt/schemas/storageencryption.rng
%{_mingw32_datadir}/libvirt/schemas/basictypes.rng
%{_mingw32_datadir}/libvirt/schemas/networkcommon.rng
%{_mingw32_datadir}/libvirt/cpu_map.xml

View File

@ -467,11 +467,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",
@ -2591,146 +2586,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
@ -2812,7 +2667,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
} else if (!virtPortParsed &&
(def->type == VIR_DOMAIN_NET_TYPE_DIRECT) &&
xmlStrEqual(cur->name, BAD_CAST "virtualport")) {
if (virVirtualPortProfileParamsParseXML(cur, &virtPort))
if (virVirtualPortProfileParseXML(cur, &virtPort))
goto error;
virtPortParsed = true;
} else if ((network == NULL) &&
@ -5319,49 +5174,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;

View File

@ -714,6 +714,8 @@ virSocketParseAddr;
virSocketParseIpv4Addr;
virSocketParseIpv6Addr;
virSocketSetPort;
virVirtualPortProfileFormat;
virVirtualPortProfileParseXML;
# network_conf.h

View File

@ -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:

View File

@ -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)

View File

@ -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,202 @@ virSocketAddrPrefixToNetmask(unsigned int prefix,
error:
return result;
}
/* virtualPortProfile utilities */
VIR_ENUM_IMPL(virVirtualPort, VIR_VIRTUALPORT_TYPE_LAST,
"none",
"802.1Qbg",
"802.1Qbh")
int
virVirtualPortProfileParseXML(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;
virtPortType = virXMLPropString(node, "type");
if (!virtPortType) {
virSocketError(VIR_ERR_XML_ERROR, "%s",
_("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)) {
virSocketError(VIR_ERR_XML_ERROR, "%s",
_("cannot parse value of managerid parameter"));
goto error;
}
if (val > 0xff) {
virSocketError(VIR_ERR_XML_ERROR, "%s",
_("value of managerid out of range"));
goto error;
}
virtPort->u.virtPort8021Qbg.managerID = (uint8_t)val;
if (virStrToLong_ui(virtPortTypeID, NULL, 0, &val)) {
virSocketError(VIR_ERR_XML_ERROR, "%s",
_("cannot parse value of typeid parameter"));
goto error;
}
if (val > 0xffffff) {
virSocketError(VIR_ERR_XML_ERROR, "%s",
_("value for typeid out of range"));
goto error;
}
virtPort->u.virtPort8021Qbg.typeID = (uint32_t)val;
if (virStrToLong_ui(virtPortTypeIDVersion, NULL, 0, &val)) {
virSocketError(VIR_ERR_XML_ERROR, "%s",
_("cannot parse value of typeidversion parameter"));
goto error;
}
if (val > 0xff) {
virSocketError(VIR_ERR_XML_ERROR, "%s",
_("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)) {
virSocketError(VIR_ERR_XML_ERROR, "%s",
_("cannot parse instanceid parameter as a uuid"));
goto error;
}
} else {
if (virUUIDGenerate(virtPort->u.virtPort8021Qbg.instanceID)) {
virSocketError(VIR_ERR_XML_ERROR, "%s",
_("cannot generate a random uuid for instanceid"));
goto error;
}
}
virtPort->virtPortType = VIR_VIRTUALPORT_8021QBG;
ret = 0;
} else {
virSocketError(VIR_ERR_XML_ERROR, "%s",
_("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 {
virSocketError(VIR_ERR_XML_ERROR, "%s",
_("profileid parameter too long"));
goto error;
}
} else {
virSocketError(VIR_ERR_XML_ERROR, "%s",
_("profileid parameter is missing for 802.1Qbh descripion"));
goto error;
}
break;
default:
case VIR_VIRTUALPORT_NONE:
case VIR_VIRTUALPORT_TYPE_LAST:
virSocketError(VIR_ERR_XML_ERROR, "%s",
_("unknown virtualport type"));
goto error;
break;
}
error:
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);
}

View File

@ -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,47 @@ 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
virVirtualPortProfileParseXML(xmlNodePtr node,
virVirtualPortProfileParamsPtr virtPort);
void
virVirtualPortProfileFormat(virBufferPtr buf,
virVirtualPortProfileParamsPtr virtPort,
const char *indent);
#endif /* __VIR_NETWORK_H__ */