* Stefan Berger (stefanb@xxxxxxxxxxxxxxxxxx) 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@xxxxxxxxxx> 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@xxxxxxxxxx> > >From a945107f047c7cd71f9c1b74fd74c47d8cdc3670 Mon Sep 17 00:00:00 2001 > From: David Allan <dallan@xxxxxxxxxx> > 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@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/libvir-list -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list