[libvirt] [PATCH v7] vepa: parsing for 802.1Qb{g|h} XML
Chris Wright
chrisw at redhat.com
Fri May 21 23:46:47 UTC 2010
* Stefan Berger (stefanb at linux.vnet.ibm.com) wrote:
> Below is David Alan's original patch with lots of changes.
>
> In particular, it now parses the following two XML descriptions, one
> for 802.1Qbg and 802.1Qbh and stored the data internally. The actual
> triggering of the switch setup protocol has not been implemented
> here but the relevant code to do that should go into the functions
> associatePortProfileId() and disassociatePortProfileId().
For future work, have you thought about preassociate on migration?
> <interface type='direct'>
> <source dev='eth0.100' mode='vepa'/>
> <model type='virtio'/>
> <virtualport type='802.1Qbg'>
> <parameters managerid='12' typeid='0x123456' typeidversion='1'
> instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f'/>
> </virtualport>
> <filterref filter='clean-traffic'/>
> </interface>
>
> <interface type='direct'>
> <source dev='eth0.100' mode='vepa'/>
> <model type='virtio'/>
> <virtualport type='802.1Qbh'>
> <parameters profileid='my_profile'/>
> </virtualport>
> </interface>
>
> I'd suggest to use this patch as a base for triggering the setup
> protocol with the 802.1Qb{g|h} switch.
>
> Changes from V6 to V7:
> - make sure that the error code returned by openMacvtapTap() is a negative number
> in case the associatePortProfileId() function failed.
>
> Changes from V5 to V6:
> - renaming vsi in the XML to virtualport
> - replace all occurrences of vsi in the source as well
>
> Changes from V4 to V5:
> - removing mode and MAC address parameters from the functions that
> will communicate with the hareware diretctly or indirectly
>
> Changes from V3 to V4:
> - moving the associate and disassociate functions to the end of the
> file for subsequent patches to easier make them generally available
> for export
> - passing the macvtap interface name rather than the link device since
> this otherwise gives funny side effects when using netlink messages
> where IFLA_IFNAME and IFLA_ADDRESS are specified and the link dev
> all of a sudden gets the MAC address of the macvtap interface.
> - Removing rc = -1 error indications in the case of 802.1Qbg|h setup in case
> we wanted to use hook scripts for the setup and so the setup doesn't fail
> here.
>
> Changes from V2 to V3:
> - if instance ID UUID is not supplied it will automatically be generated
> - adapted schema to make instance ID UUID optional
> - added test case
>
> Some of the changes from V1 to V2:
> - parser and XML generator have been separated into their own
> functions so they can be re-used elsewhere (passthrough case
> for example)
> - Adapted XML parser and generator support the above shown type
> (802.1Qbg, 802.1Qbh).
> - Adapted schema to above XML
> - Adapted test XML to above XML
> - Passing through the VM's UUID which seems to be necessary for
> 802.1Qbh -- sorry no host UUID
> - adding virtual function ID to association function, in case it's
> necessary to use (for SR-IOV)
>
> Signed-off-by: Stefan Berger <stefanb at us.ibm.com>
This is looking like pretty complete infrastructure to me. Have you
been able generate test (dis)associate messages through this framework w/
the vsi patches? Pending that (I can see you are able to at least
generate debug messages showing the thing work), and some minor nits
below.
Acked-by: Chris Wright <chrisw at redhat.com>
> >From a945107f047c7cd71f9c1b74fd74c47d8cdc3670 Mon Sep 17 00:00:00 2001
> From: David Allan <dallan at redhat.com>
> Date: Fri, 12 Mar 2010 13:25:04 -0500
> Subject: [PATCH 1/1] POC of port profile id support
>
> * Modified schema per DanPB's feedback
> * Added test for modified schema
> ---
> docs/schemas/domain.rng | 69 ++++++++++++++
> src/conf/domain_conf.c | 155 +++++++++++++++++++++++++++++++++
> src/conf/domain_conf.h | 35 +++++++
> src/qemu/qemu_conf.c | 18 +--
> src/qemu/qemu_conf.h | 5 -
> src/qemu/qemu_driver.c | 17 +--
> src/util/macvtap.c | 151 +++++++++++++++++++++++++++-----
> src/util/macvtap.h | 10 +-
> tests/domainschemadata/portprofile.xml | 36 +++++++
> 9 files changed, 446 insertions(+), 50 deletions(-)
> create mode 100644 tests/domainschemadata/portprofile.xml
>
> Index: libvirt-acl/docs/schemas/domain.rng
> ===================================================================
> --- libvirt-acl.orig/docs/schemas/domain.rng
> +++ libvirt-acl/docs/schemas/domain.rng
> @@ -817,6 +817,9 @@
> </optional>
> <empty/>
> </element>
> + <optional>
> + <ref name="virtualPortProfile"/>
> + </optional>
> <ref name="interface-options"/>
> </interleave>
> </group>
> @@ -902,6 +905,45 @@
> </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
> -->
> @@ -1769,4 +1811,31 @@
> <param name="pattern">[a-zA-Z0-9_\.:]+</param>
> </data>
> </define>
> + <define name="uint8range">
> + <choice>
> + <data type="string">
> + <param name="pattern">0x[0-9a-fA-F]{1,2}</param>
> + </data>
> + <data type="int">
> + <param name="minInclusive">0</param>
> + <param name="maxInclusive">255</param>
> + </data>
> + </choice>
> + </define>
> + <define name="uint24range">
> + <choice>
> + <data type="string">
> + <param name="pattern">0x[0-9a-fA-F]{1,6}</param>
> + </data>
> + <data type="int">
> + <param name="minInclusive">0</param>
> + <param name="maxInclusive">16777215</param>
> + </data>
> + </choice>
> + </define>
> + <define name="virtualPortProfileID">
> + <data type="string">
> + <param name="maxLength">39</param>
> + </data>
> + </define>
> </grammar>
> Index: libvirt-acl/src/conf/domain_conf.c
> ===================================================================
> --- libvirt-acl.orig/src/conf/domain_conf.c
> +++ libvirt-acl/src/conf/domain_conf.c
> @@ -242,6 +242,11 @@ VIR_ENUM_IMPL(virDomainNetdevMacvtap, VI
> "private",
> "bridge")
>
> +VIR_ENUM_IMPL(virVirtualPort, VIR_VIRTUALPORT_TYPE_LAST,
> + "none",
> + "802.1Qbg",
> + "802.1Qbh")
> +
> VIR_ENUM_IMPL(virDomainClockOffset, VIR_DOMAIN_CLOCK_OFFSET_LAST,
> "utc",
> "localtime",
> @@ -1807,6 +1812,145 @@ cleanup:
> }
>
>
> +static void
static int so we can capture an error?
> +virVirtualPortProfileDefParseXML(xmlNodePtr node,
> + virVirtualPortProfileDefPtr virtPort)
> +{
> + char *virtPortType;
> + char *virtPortManagerID = NULL;
> + char *virtPortTypeID = NULL;
> + char *virtPortTypeIDVersion = NULL;
> + char *virtPortInstanceID = NULL;
> + char *virtPortProfileID = NULL;
> + xmlNodePtr cur = node->children;
int ret = -1;
> +
> + virtPortType = virXMLPropString(node, "type");
> + if (!virtPortType)
> + return;
> +
> + 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;
s/break/goto out/
> + }
> +
> + 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, 10, &val) &&
> + virStrToLong_ui(virtPortManagerID, NULL, 16, &val) ) ||
Why not a baseless strtol (0 instead of 10 and 16)? And I think this
should give some virDomainReportError() so that we can figure out what's
happening when the xml is incorrect.
Ditto for parsing the whole thing...
> + val > 0xff)
> + break;
s/break/goto out/
> +
> + virtPort->u.virtPort8021Qbg.managerID = (uint8_t)val;
> +
> + if ((virStrToLong_ui(virtPortTypeID, NULL, 10, &val) &&
> + virStrToLong_ui(virtPortTypeID, NULL, 16, &val) ) ||
> + val > 0xffffff)
> + break;
> +
> + virtPort->u.virtPort8021Qbg.typeID = (uint32_t)val;
> +
> + if ((virStrToLong_ui(virtPortTypeIDVersion, NULL, 10, &val) &&
> + virStrToLong_ui(virtPortTypeIDVersion, NULL, 16, &val) ) ||
> + val > 0xff)
> + break;
> +
> + virtPort->u.virtPort8021Qbg.typeIDVersion = (uint8_t)val;
> +
> + if (virtPortInstanceID != NULL) {
> + if (virUUIDParse(virtPortInstanceID, virtPort->u.virtPort8021Qbg.instanceID))
> + break;
> + } else {
> + if (virUUIDGenerate(virtPort->u.virtPort8021Qbg.instanceID))
> + break;
> + }
> +
> + virtPort->virtPortType = VIR_VIRTUALPORT_8021QBG;
> + }
> + break;
> +
> + case VIR_VIRTUALPORT_8021QBH:
> + if (virtPortProfileID != NULL) {
> + if (virStrcpyStatic(virtPort->u.virtPort8021Qbh.profileID,
> + virtPortProfileID) != NULL)
> + virtPort->virtPortType = VIR_VIRTUALPORT_8021QBH;
> + }
> + break;
> +
> +
> + default:
> + case VIR_VIRTUALPORT_NONE:
> + case VIR_VIRTUALPORT_TYPE_LAST:
> + break;
error cases, no? goto out
> + }
> +
ret = 0;
out:
> + VIR_FREE(virtPortManagerID);
> + VIR_FREE(virtPortTypeID);
> + VIR_FREE(virtPortTypeIDVersion);
> + VIR_FREE(virtPortInstanceID);
> + VIR_FREE(virtPortProfileID);
> + VIR_FREE(virtPortType);
return ret;
> +}
> +
> +
> +static void
> +virVirtualPortProfileFormat(virBufferPtr buf, virVirtualPortProfileDefPtr virtPort,
> + const char *indent)
> +{
> + char uuidstr[VIR_UUID_STRING_BUFLEN];
> +
> + if (virtPort->virtPortType == VIR_VIRTUALPORT_NONE)
> + return;
> +
> + virBufferVSprintf(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);
> + virBufferVSprintf(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:
> + virBufferVSprintf(buf,
> + "%s <parameters profileid='%s'/>\n",
> + indent,
> + virtPort->u.virtPort8021Qbh.profileID);
> + break;
> + }
> +
> + virBufferVSprintf(buf, "%s</virtualport>\n", indent);
> +}
> +
> +
> /* Parse the XML definition for a network interface
> * @param node XML nodeset to parse for net definition
> * @return 0 on success, -1 on failure
> @@ -1832,6 +1976,8 @@ virDomainNetDefParseXML(virCapsPtr caps,
> char *devaddr = NULL;
> char *mode = NULL;
> virNWFilterHashTablePtr filterparams = NULL;
> + virVirtualPortProfileDef virtPort;
> + bool virtPortParsed = false;
>
> if (VIR_ALLOC(def) < 0) {
> virReportOOMError();
> @@ -1873,6 +2019,11 @@ virDomainNetDefParseXML(virCapsPtr caps,
> xmlStrEqual(cur->name, BAD_CAST "source")) {
> dev = virXMLPropString(cur, "dev");
> mode = virXMLPropString(cur, "mode");
> + } else if ((virtPortParsed == false) &&
> + (def->type == VIR_DOMAIN_NET_TYPE_DIRECT) &&
> + xmlStrEqual(cur->name, BAD_CAST "virtualport")) {
> + virVirtualPortProfileDefParseXML(cur, &virtPort);
> + virtPortParsed = true;
> } else if ((network == NULL) &&
> ((def->type == VIR_DOMAIN_NET_TYPE_SERVER) ||
> (def->type == VIR_DOMAIN_NET_TYPE_CLIENT) ||
> @@ -2048,6 +2199,8 @@ virDomainNetDefParseXML(virCapsPtr caps,
> } else
> def->data.direct.mode = VIR_DOMAIN_NETDEV_MACVTAP_MODE_VEPA;
>
> + def->data.direct.virtPortProfile = virtPort;
> +
> def->data.direct.linkdev = dev;
> dev = NULL;
>
> @@ -5140,6 +5293,8 @@ virDomainNetDefFormat(virBufferPtr buf,
> virBufferVSprintf(buf, " mode='%s'",
> virDomainNetdevMacvtapTypeToString(def->data.direct.mode));
> virBufferAddLit(buf, "/>\n");
> + virVirtualPortProfileFormat(buf, &def->data.direct.virtPortProfile,
> + " ");
> 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,39 @@ enum virDomainNetdevMacvtapType {
> };
>
>
> +enum virVirtualPortType {
> + VIR_VIRTUALPORT_NONE,
> + VIR_VIRTUALPORT_8021QBG,
> + VIR_VIRTUALPORT_8021QBH,
> +
> + VIR_VIRTUALPORT_TYPE_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 _virVirtualPortProfileDef virVirtualPortProfileDef;
> +typedef virVirtualPortProfileDef *virVirtualPortProfileDefPtr;
> +struct _virVirtualPortProfileDef {
> + 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;
> +};
> +
> +
> /* Stores the virtual network interface configuration */
> typedef struct _virDomainNetDef virDomainNetDef;
> typedef virDomainNetDef *virDomainNetDefPtr;
> @@ -290,6 +323,7 @@ struct _virDomainNetDef {
> struct {
> char *linkdev;
> int mode;
> + virVirtualPortProfileDef virtPortProfile;
> } direct;
> } data;
> char *ifname;
> @@ -1089,6 +1123,7 @@ VIR_ENUM_DECL(virDomainSeclabel)
> VIR_ENUM_DECL(virDomainClockOffset)
>
> VIR_ENUM_DECL(virDomainNetdevMacvtap)
> +VIR_ENUM_DECL(virVirtualPort)
>
> VIR_ENUM_DECL(virDomainTimerName)
> VIR_ENUM_DECL(virDomainTimerTrack)
> Index: libvirt-acl/src/util/macvtap.c
> ===================================================================
> --- libvirt-acl.orig/src/util/macvtap.c
> +++ libvirt-acl/src/util/macvtap.c
> @@ -43,6 +43,7 @@
>
> # include "util.h"
> # include "memory.h"
> +# include "logging.h"
> # include "macvtap.h"
> # include "interface.h"
> # include "conf/domain_conf.h"
> @@ -57,6 +58,16 @@
> # define MACVTAP_NAME_PREFIX "macvtap"
> # define MACVTAP_NAME_PATTERN "macvtap%d"
>
> +
> +static int associatePortProfileId(const char *macvtap_ifname,
> + const virVirtualPortProfileDefPtr virtPort,
> + int vf,
> + const unsigned char *vmuuid);
> +
> +static int disassociatePortProfileId(const char *macvtap_ifname,
> + const virVirtualPortProfileDefPtr virtPort);
> +
> +
> static int nlOpen(void)
> {
> int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
> @@ -567,39 +578,38 @@ configMacvtapTap(int tapfd, int vnet_hdr
>
> return 0;
> }
> -
> -
> /**
> * openMacvtapTap:
> * Create an instance of a macvtap device and open its tap character
> * device.
> * @tgifname: Interface name that the macvtap is supposed to have. May
> * be NULL if this function is supposed to choose a name
> - * @macaddress: The MAC address for the macvtap device
> - * @linkdev: The interface name of the NIC to connect to the external bridge
> - * @mode_str: String describing the mode. Valid are 'bridge', 'vepa' and
> - * 'private'.
> + * @net: pointer to the virDomainNetDef object describing the direct
> + * type if an interface
> * @res_ifname: Pointer to a string pointer where the actual name of the
> * interface will be stored into if everything succeeded. It is up
> * to the caller to free the string.
> + * @vnet_hdr: Whether to enable IFF_VNET_HDR on the interface
> + * @vmuuid: The (raw) UUID of the VM
> *
> * Returns file descriptor of the tap device in case of success,
> * negative value otherwise with error reported.
> *
> + * Open a macvtap device and trigger the switch setup protocol
> + * if valid port profile parameters were provided.
> */
> int
> openMacvtapTap(const char *tgifname,
> - const unsigned char *macaddress,
> - const char *linkdev,
> - int mode,
> + virDomainNetDefPtr net,
Any reason to keep tgifname now that you're passing full virDomainNetDefPtr?
> char **res_ifname,
> - int vnet_hdr)
> + int vnet_hdr,
> + const unsigned char *vmuuid)
> {
> const char *type = "macvtap";
> int c, rc;
> char ifname[IFNAMSIZ];
> int retries, do_retry = 0;
> - uint32_t macvtapMode = macvtapModeFromInt(mode);
> + uint32_t macvtapMode = macvtapModeFromInt(net->data.direct.mode);
> const char *cr_ifname;
> int ifindex;
>
> @@ -616,7 +626,7 @@ openMacvtapTap(const char *tgifname,
> return -1;
> }
> cr_ifname = tgifname;
> - rc = link_add(type, macaddress, 6, tgifname, linkdev,
> + rc = link_add(type, net->mac, 6, tgifname, net->data.direct.linkdev,
> macvtapMode, &do_retry);
> if (rc)
> return -1;
> @@ -626,7 +636,8 @@ create_name:
> for (c = 0; c < 8192; c++) {
> snprintf(ifname, sizeof(ifname), MACVTAP_NAME_PATTERN, c);
> if (ifaceGetIndex(false, ifname, &ifindex) == ENODEV) {
> - rc = link_add(type, macaddress, 6, ifname, linkdev,
> + rc = link_add(type, net->mac, 6, ifname,
> + net->data.direct.linkdev,
> macvtapMode, &do_retry);
> if (rc == 0)
> break;
> @@ -639,6 +650,14 @@ create_name:
> cr_ifname = ifname;
> }
>
> + if (associatePortProfileId(cr_ifname,
> + &net->data.direct.virtPortProfile,
> + -1,
> + vmuuid) != 0) {
> + rc = -1;
> + goto link_del_exit;
> + }
> +
> rc = ifaceUp(cr_ifname);
> if (rc != 0) {
> virReportSystemError(errno,
> @@ -647,7 +666,7 @@ create_name:
> "MAC address"),
> cr_ifname);
> rc = -1;
> - goto link_del_exit;
> + goto disassociate_exit;
> }
>
> rc = openTap(cr_ifname, 10);
> @@ -656,14 +675,18 @@ create_name:
> if (configMacvtapTap(rc, vnet_hdr) < 0) {
> close(rc);
> rc = -1;
> - goto link_del_exit;
> + goto disassociate_exit;
> }
> *res_ifname = strdup(cr_ifname);
> } else
> - goto link_del_exit;
> + goto disassociate_exit;
>
> return rc;
>
> +disassociate_exit:
> + disassociatePortProfileId(cr_ifname,
> + &net->data.direct.virtPortProfile);
> +
> link_del_exit:
> link_del(cr_ifname);
>
> @@ -673,14 +696,102 @@ link_del_exit:
>
> /**
> * delMacvtap:
> - * @ifname : The name of the macvtap interface
> + * @net: pointer to virDomainNetDef object
> *
> - * Delete an interface given its name.
> + * Delete an interface given its name. Disassociate
> + * it with the switch if port profile parameters
> + * were provided.
> */
> void
> -delMacvtap(const char *ifname)
> +delMacvtap(virDomainNetDefPtr net)
> {
> - link_del(ifname);
> + if (net->ifname) {
> + disassociatePortProfileId(net->ifname,
> + &net->data.direct.virtPortProfile);
> + link_del(net->ifname);
> + }
> }
>
> #endif
> +
> +
> +/**
> + * associatePortProfile
> + *
> + * @macvtap_ifname: The name of the macvtap device
> + * @virtPort: pointer to the object holding port profile parameters
> + * @vf: virtual function number, -1 if to be ignored
> + * @vmuuid : the UUID of the virtual machine
> + *
> + * Associate a port on a swtich with a profile. This function
> + * may notify a kernel driver or an external daemon to run
> + * the setup protocol. If profile parameters were not supplied
> + * by the user, then this function returns without doing
> + * anything.
> + *
> + * Returns 0 in case of success, != 0 otherwise with error
> + * having been reported.
> + */
> +static int
> +associatePortProfileId(const char *macvtap_ifname,
> + const virVirtualPortProfileDefPtr virtPort,
> + int vf,
> + const unsigned char *vmuuid)
> +{
> + int rc = 0;
> + VIR_DEBUG("Associating port profile '%p' on link device '%s'",
> + virtPort, macvtap_ifname);
> + (void)vf;
> + (void)vmuuid;
> +
> + switch (virtPort->virtPortType) {
> + case VIR_VIRTUALPORT_NONE:
> + case VIR_VIRTUALPORT_TYPE_LAST:
> + break;
If we capture these on parsing and error out, then these could be
invalid here.
> +
> + case VIR_VIRTUALPORT_8021QBG:
> +
> + break;
> +
> + case VIR_VIRTUALPORT_8021QBH:
> +
> + break;
> + }
> +
> + return rc;
> +}
> +
> +
> +/**
> + * disassociatePortProfile
> + *
> + * @macvtap_ifname: The name of the macvtap device
> + * @virtPort: point to object holding port profile parameters
> + *
> + * Returns 0 in case of success, != 0 otherwise with error
> + * having been reported.
> + */
> +static int
> +disassociatePortProfileId(const char *macvtap_ifname,
> + const virVirtualPortProfileDefPtr virtPort)
> +{
> + int rc = 0;
> + VIR_DEBUG("Disassociating port profile id '%p' on link device '%s' ",
> + virtPort, macvtap_ifname);
> +
> + switch (virtPort->virtPortType) {
> + case VIR_VIRTUALPORT_NONE:
> + case VIR_VIRTUALPORT_TYPE_LAST:
> + break;
If we capture these on parsing and error out, then these could be
invalid here.
> + case VIR_VIRTUALPORT_8021QBG:
> +
> + break;
> +
> + case VIR_VIRTUALPORT_8021QBH:
> +
> + break;
> + }
> +
> + return rc;
> +}
> Index: libvirt-acl/src/util/macvtap.h
> ===================================================================
> --- libvirt-acl.orig/src/util/macvtap.h
> +++ libvirt-acl/src/util/macvtap.h
> @@ -27,15 +27,15 @@
> # if defined(WITH_MACVTAP)
>
> # include "internal.h"
> +# include "conf/domain_conf.h"
>
> int openMacvtapTap(const char *ifname,
> - const unsigned char *macaddress,
> - const char *linkdev,
> - int mode,
> + virDomainNetDefPtr net,
> char **res_ifname,
> - int vnet_hdr);
> + int vnet_hdr,
> + const unsigned char *vmuuid);
>
> -void delMacvtap(const char *ifname);
> +void delMacvtap(virDomainNetDefPtr net);
>
> # endif /* WITH_MACVTAP */
>
> Index: libvirt-acl/tests/domainschemadata/portprofile.xml
> ===================================================================
> --- /dev/null
> +++ libvirt-acl/tests/domainschemadata/portprofile.xml
> @@ -0,0 +1,36 @@
> +<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'/>
> + <virtualport type='802.1Qbg'>
> + <parameters managerid='12' typeid='1193046' typeidversion='1'
> + instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f'/>
> + </virtualport>
> + </interface>
> + <interface type='direct'>
> + <source dev='eth0' mode='vepa'/>
> + <virtualport type='802.1Qbg'>
> + <parameters managerid='12' typeid='1193046' typeidversion='1'/>
> + </virtualport>
> + </interface>
> + <interface type='direct'>
> + <source dev='eth0' mode='vepa'/>
> + <virtualport type='802.1Qbh'>
> + <parameters profileid='my_profile'/>
> + </virtualport>
> + </interface>
> + <interface type='direct'>
> + <source dev='eth0' mode='vepa'/>
> + </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
> @@ -274,9 +274,8 @@ qemudOpenVhostNet(virDomainNetDefPtr net
> int qemudPhysIfaceConnect(virConnectPtr conn,
> struct qemud_driver *driver,
> virDomainNetDefPtr net,
> - char *linkdev,
> - int brmode,
> - unsigned long long qemuCmdFlags);
> + unsigned long long qemuCmdFlags,
> + const unsigned char *vmuuid);
>
> int qemudProbeMachineTypes (const char *binary,
> virCapsGuestMachinePtr **machines,
> Index: libvirt-acl/src/qemu/qemu_driver.c
> ===================================================================
> --- libvirt-acl.orig/src/qemu/qemu_driver.c
> +++ libvirt-acl/src/qemu/qemu_driver.c
> @@ -3702,10 +3702,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
>
> @@ -7464,9 +7462,8 @@ static int qemudDomainAttachNetDevice(vi
> }
>
> if ((tapfd = qemudPhysIfaceConnect(conn, driver, net,
> - net->data.direct.linkdev,
> - net->data.direct.mode,
> - qemuCmdFlags)) < 0)
> + qemuCmdFlags,
> + vm->def->uuid)) < 0)
> return -1;
> }
>
> @@ -8509,10 +8506,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)) {
> Index: libvirt-acl/src/qemu/qemu_conf.c
> ===================================================================
> --- libvirt-acl.orig/src/qemu/qemu_conf.c
> +++ libvirt-acl/src/qemu/qemu_conf.c
> @@ -1470,9 +1470,8 @@ int
> qemudPhysIfaceConnect(virConnectPtr conn,
> struct qemud_driver *driver,
> virDomainNetDefPtr net,
> - char *linkdev,
> - int brmode,
> - unsigned long long qemuCmdFlags)
> + unsigned long long qemuCmdFlags,
> + const unsigned char *vmuuid)
> {
> int rc;
> #if WITH_MACVTAP
> @@ -1484,8 +1483,7 @@ qemudPhysIfaceConnect(virConnectPtr conn
> net->model && STREQ(net->model, "virtio"))
> vnet_hdr = 1;
>
> - rc = openMacvtapTap(net->ifname, net->mac, linkdev, brmode,
> - &res_ifname, vnet_hdr);
> + rc = openMacvtapTap(net->ifname, net, &res_ifname, vnet_hdr, vmuuid);
> if (rc >= 0) {
> VIR_FREE(net->ifname);
> net->ifname = res_ifname;
> @@ -1505,17 +1503,16 @@ qemudPhysIfaceConnect(virConnectPtr conn
> if (err) {
> close(rc);
> rc = -1;
> - delMacvtap(net->ifname);
> + delMacvtap(net);
> }
> }
> }
> #else
> (void)conn;
> (void)net;
> - (void)linkdev;
> - (void)brmode;
> (void)qemuCmdFlags;
> (void)driver;
> + (void)vmuuid;
> qemuReportError(VIR_ERR_INTERNAL_ERROR,
> "%s", _("No support for macvtap device"));
> rc = -1;
> @@ -4135,9 +4132,8 @@ int qemudBuildCommandLine(virConnectPtr
> goto no_memory;
> } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
> int tapfd = qemudPhysIfaceConnect(conn, driver, net,
> - net->data.direct.linkdev,
> - net->data.direct.mode,
> - qemuCmdFlags);
> + qemuCmdFlags,
> + def->uuid);
> if (tapfd < 0)
> goto error;
>
>
> --
> 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