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

Below is David Alan's original patch with lots of changes. In particular, it now parses the following XML and stored the data internally. No sending of netlink messages has been implemented here. <interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi managerid='12' typeid='0x123456' typeidversion='1' instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f' /> <filterref filter='clean-traffic'/> </interface> <interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi profileid='my_profile'/> </interface> I'd suggest to use this patch as a base for sending out netlink messages. Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
From a945107f047c7cd71f9c1b74fd74c47d8cdc3670 Mon Sep 17 00:00:00 2001 From: David Allan <dallan@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 | 57 +++++++++++++++++++ src/conf/domain_conf.c | 97 +++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 31 ++++++++++ src/qemu/qemu_conf.c | 11 --- src/qemu/qemu_conf.h | 2 src/qemu/qemu_driver.c | 14 +--- src/util/macvtap.c | 89 +++++++++++++++++++++++++----- src/util/macvtap.h | 7 +- tests/domainschemadata/portprofile.xml | 22 +++++++ 9 files changed, 292 insertions(+), 38 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="vsiProfile"/> + </optional> <ref name="interface-options"/> </interleave> </group> @@ -902,6 +905,33 @@ </optional> </interleave> </define> + <define name="vsiProfile"> + <choice> + <group> + <element name="vsi"> + <attribute name="managerid"> + <ref name="uint8range"/> + </attribute> + <attribute name="typeid"> + <ref name="uint24range"/> + </attribute> + <attribute name="typeidversion"> + <ref name="uint8range"/> + </attribute> + <attribute name="instanceid"> + <ref name="UUID"/> + </attribute> + </element> + </group> + <group> + <element name="vsi"> + <attribute name="profileid"> + <ref name="vsiProfileID"/> + </attribute> + </element> + </group> + </choice> + </define> <!-- An emulator description is just a path to the binary used for the task --> @@ -1769,4 +1799,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="vsiProfileID"> + <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 @@ -1831,7 +1831,13 @@ virDomainNetDefParseXML(virCapsPtr caps, char *internal = NULL; char *devaddr = NULL; char *mode = NULL; + char *vsiManagerID = NULL; + char *vsiTypeID = NULL; + char *vsiTypeIDVersion = NULL; + char *vsiInstanceID = NULL; + char *vsiProfileID = NULL; virNWFilterHashTablePtr filterparams = NULL; + virVSIProfileDefPtr vsi; if (VIR_ALLOC(def) < 0) { virReportOOMError(); @@ -1873,6 +1879,20 @@ virDomainNetDefParseXML(virCapsPtr caps, xmlStrEqual(cur->name, BAD_CAST "source")) { dev = virXMLPropString(cur, "dev"); mode = virXMLPropString(cur, "mode"); + } else if ((vsiManagerID == NULL) && + (vsiTypeID == NULL) && + (vsiTypeIDVersion == NULL) && + (vsiInstanceID == NULL) && + (vsiProfileID == NULL) && + (def->type == VIR_DOMAIN_NET_TYPE_DIRECT) && + xmlStrEqual(cur->name, BAD_CAST "vsi")) { + vsiManagerID = virXMLPropString(cur, "managerid"); + vsiTypeID = virXMLPropString(cur, "typeid"); + vsiTypeIDVersion = virXMLPropString(cur, "typeidversion"); + vsiInstanceID = virXMLPropString(cur, "instanceid"); +#ifdef IFLA_VF_PORT_PROFILE_MAX + vsiProfileID = virXMLPropString(cur, "profileid"); +#endif } else if ((network == NULL) && ((def->type == VIR_DOMAIN_NET_TYPE_SERVER) || (def->type == VIR_DOMAIN_NET_TYPE_CLIENT) || @@ -2049,6 +2069,51 @@ virDomainNetDefParseXML(virCapsPtr caps, } else def->data.direct.mode = VIR_DOMAIN_NETDEV_MACVTAP_MODE_VEPA; + vsi = &def->data.direct.vsiProfile; + +#ifdef IFLA_VF_PORT_PROFILE_MAX + if (vsiProfileID != NULL) { + if (virStrcpyStatic(vsi->u.vsi8021Qbh.profileID, + vsiProfileID) != NULL) { + vsi->vsiType = VIR_VSI_8021QBH; + break; + } + } +#endif + + while (vsiManagerID != NULL && vsiTypeID != NULL && + vsiTypeIDVersion != NULL && vsiInstanceID != NULL) { + unsigned int val; + + if ((virStrToLong_ui(vsiManagerID, NULL, 10, &val) && + virStrToLong_ui(vsiManagerID, NULL, 16, &val) ) || + val > 0xff) + break; + + vsi->u.vsi8021Qbg.managerID = (uint8_t)val; + + if ((virStrToLong_ui(vsiTypeID, NULL, 10, &val) && + virStrToLong_ui(vsiTypeID, NULL, 16, &val) ) || + val > 0xffffff) + break; + + vsi->u.vsi8021Qbg.typeID = (uint32_t)val; + + if ((virStrToLong_ui(vsiTypeIDVersion, NULL, 10, &val) && + virStrToLong_ui(vsiTypeIDVersion, NULL, 16, &val) ) || + val > 0xff) + break; + + vsi->u.vsi8021Qbg.typeIDVersion = (uint8_t)val; + + if (virUUIDParse(vsiInstanceID, + def->data.direct.vsiProfile.u.vsi8021Qbg.instanceID)) + break; + + vsi->vsiType = VIR_VSI_8021QBG; + break; + } + def->data.direct.linkdev = dev; dev = NULL; @@ -2114,6 +2179,11 @@ cleanup: VIR_FREE(internal); VIR_FREE(devaddr); VIR_FREE(mode); + VIR_FREE(vsiManagerID); + VIR_FREE(vsiTypeID); + VIR_FREE(vsiTypeIDVersion); + VIR_FREE(vsiInstanceID); + VIR_FREE(vsiProfileID); virNWFilterHashTableFree(filterparams); return def; @@ -5076,6 +5146,8 @@ virDomainNetDefFormat(virBufferPtr buf, { const char *type = virDomainNetTypeToString(def->type); char *attrs; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virVSIProfileDefPtr vsi; if (!type) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, @@ -5141,6 +5213,31 @@ virDomainNetDefFormat(virBufferPtr buf, virBufferVSprintf(buf, " mode='%s'", virDomainNetdevMacvtapTypeToString(def->data.direct.mode)); virBufferAddLit(buf, "/>\n"); + vsi = &def->data.direct.vsiProfile; + switch (vsi->vsiType) { + case VIR_VSI_INVALID: + break; + + case VIR_VSI_8021QBG: + virUUIDFormat(def->data.direct.vsiProfile.u.vsi8021Qbg.instanceID, + uuidstr); + virBufferVSprintf(buf, + " <vsi managerid='%d' typeid='%d' " + "typeidversion='%d' instanceid='%s'/>\n", + vsi->u.vsi8021Qbg.managerID, + vsi->u.vsi8021Qbg.typeID, + vsi->u.vsi8021Qbg.typeIDVersion, + uuidstr); + break; + +#ifdef IFLA_VF_PORT_PROFILE_MAX + case VIR_VSI_8021QBH: + virBufferVSprintf(buf, + " <vsi profileid='%s'/>\n", + vsi->u.vsi8021Qbh.profileID); + break; +#endif + } break; case VIR_DOMAIN_NET_TYPE_USER: Index: libvirt-acl/src/conf/domain_conf.h =================================================================== --- libvirt-acl.orig/src/conf/domain_conf.h +++ libvirt-acl/src/conf/domain_conf.h @@ -259,6 +259,36 @@ enum virDomainNetdevMacvtapType { }; +#define IFLA_VF_PORT_PROFILE_MAX 40 +enum virVSIType { + VIR_VSI_INVALID, + VIR_VSI_8021QBG, +#ifdef IFLA_VF_PORT_PROFILE_MAX + VIR_VSI_8021QBH, +#endif +}; + +/* profile data for macvtap (VEPA) */ +typedef struct _virVSIProfileDef virVSIProfileDef; +typedef virVSIProfileDef *virVSIProfileDefPtr; +struct _virVSIProfileDef { + enum virVSIType vsiType; + union { + struct { + uint8_t managerID; + uint32_t typeID; // 24 bit valid + uint8_t typeIDVersion; + unsigned char instanceID[VIR_UUID_BUFLEN]; + } vsi8021Qbg; +#ifdef IFLA_VF_PORT_PROFILE_MAX + struct { + char profileID[IFLA_VF_PORT_PROFILE_MAX]; + } vsi8021Qbh; +#endif + } u; +}; + + /* Stores the virtual network interface configuration */ typedef struct _virDomainNetDef virDomainNetDef; typedef virDomainNetDef *virDomainNetDefPtr; @@ -290,6 +320,7 @@ struct _virDomainNetDef { struct { char *linkdev; int mode; + virVSIProfileDef vsiProfile; } direct; } data; char *ifname; 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,13 @@ # define MACVTAP_NAME_PREFIX "macvtap" # define MACVTAP_NAME_PATTERN "macvtap%d" + +# define PREASSOCIATE 0x00 +# define PREASSOCIATE_WITH_RESOURCE_RESERVATION 0x01 +# define ASSOCIATE 0x02 +# define DEASSOCIATE 0x03 + + static int nlOpen(void) { int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); @@ -569,6 +577,45 @@ configMacvtapTap(int tapfd, int vnet_hdr } +static int +setPortProfileId(const char *linkdev ATTRIBUTE_UNUSED, + unsigned char *mac ATTRIBUTE_UNUSED, + int mode ATTRIBUTE_UNUSED, + const virVSIProfileDefPtr profile ATTRIBUTE_UNUSED) +{ + return 0; +} + +static int +associatePortProfileId(const char *linkdev, + unsigned char *mac, + int mode, + const virVSIProfileDefPtr profile) +{ + VIR_DEBUG("Associating port profile '%p' on link device '%s' mode % d ", + profile, linkdev, mode); + + return setPortProfileId(linkdev, + mac, + ASSOCIATE, + profile); +} + + +static int +disassociatePortProfileId(const char *linkdev, + unsigned char *mac, + const virVSIProfileDefPtr profile) +{ + VIR_DEBUG("Disassociating port profile id '%p' on link device '%s' ", + profile, linkdev); + + return setPortProfileId(linkdev, + mac, + DEASSOCIATE, + profile); +} + /** * openMacvtapTap: * Create an instance of a macvtap device and open its tap character @@ -589,9 +636,7 @@ configMacvtapTap(int tapfd, int vnet_hdr */ int openMacvtapTap(const char *tgifname, - const unsigned char *macaddress, - const char *linkdev, - int mode, + virDomainNetDefPtr net, char **res_ifname, int vnet_hdr) { @@ -599,7 +644,7 @@ openMacvtapTap(const char *tgifname, 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 +661,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 +671,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 +685,13 @@ create_name: cr_ifname = ifname; } + rc = associatePortProfileId(net->data.direct.linkdev, + net->mac, + net->data.direct.mode, + &net->data.direct.vsiProfile); + if (rc != 0) + goto link_del_exit; + rc = ifaceUp(cr_ifname); if (rc != 0) { virReportSystemError(errno, @@ -647,7 +700,7 @@ create_name: "MAC address"), cr_ifname); rc = -1; - goto link_del_exit; + goto disassociate_exit; } rc = openTap(cr_ifname, 10); @@ -656,14 +709,19 @@ 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(net->data.direct.linkdev, + net->mac, + &net->data.direct.vsiProfile); + link_del_exit: link_del(cr_ifname); @@ -672,15 +730,20 @@ link_del_exit: /** - * delMacvtapByName: - * @ifname : The name of the macvtap interface + * delMacvtap: + * @net: pointer to virDomainNetDef object * * Delete an interface given its name. */ void -delMacvtap(const char *ifname) +delMacvtap(virDomainNetDefPtr net) { - link_del(ifname); + if (net->ifname) { + disassociatePortProfileId(net->data.direct.linkdev, + net->mac, + &net->data.direct.vsiProfile); + link_del(net->ifname); + } } #endif Index: libvirt-acl/src/util/macvtap.h =================================================================== --- libvirt-acl.orig/src/util/macvtap.h +++ libvirt-acl/src/util/macvtap.h @@ -27,15 +27,14 @@ # 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); -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,27 @@ +<domain type='lxc'> + <name>portprofile</name> + <uuid>00000000-0000-0000-0000-000000000000</uuid> + <memory>1048576</memory> + <os> + <type>exe</type> + <init>/sh</init> + </os> + <devices> + <interface type='direct'> + <source dev='eth0' mode='vepa'/> + <vsi managerid='12' typeid='1193046' typeidversion='1' + instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f'/> + </interface> + <interface type='direct'> + <source dev='eth0' mode='vepa'/> + <vsi profileid='my_profile'/> + </interface> + <interface type='direct'> + <source dev='eth0' mode='vepa'/> + <vsi/> + </interface> + <interface type='direct'> + <source dev='eth0' mode='vepa'/> + </interface> + </devices> +</domain> Index: libvirt-acl/src/qemu/qemu_conf.h =================================================================== --- libvirt-acl.orig/src/qemu/qemu_conf.h +++ libvirt-acl/src/qemu/qemu_conf.h @@ -271,8 +271,6 @@ qemudOpenVhostNet(virDomainNetDefPtr net int qemudPhysIfaceConnect(virConnectPtr conn, struct qemud_driver *driver, virDomainNetDefPtr net, - char *linkdev, - int brmode, unsigned long long qemuCmdFlags); int qemudProbeMachineTypes (const char *binary, Index: libvirt-acl/src/qemu/qemu_driver.c =================================================================== --- libvirt-acl.orig/src/qemu/qemu_driver.c +++ libvirt-acl/src/qemu/qemu_driver.c @@ -3585,10 +3585,8 @@ static void qemudShutdownVMDaemon(struct def = vm->def; for (i = 0; i < def->nnets; i++) { virDomainNetDefPtr net = def->nets[i]; - if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { - if (net->ifname) - delMacvtap(net->ifname); - } + if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) + delMacvtap(net); } #endif @@ -7175,8 +7173,6 @@ static int qemudDomainAttachNetDevice(vi } if ((tapfd = qemudPhysIfaceConnect(conn, driver, net, - net->data.direct.linkdev, - net->data.direct.mode, qemuCmdFlags)) < 0) return -1; } @@ -8146,10 +8142,8 @@ qemudDomainDetachNetDevice(struct qemud_ virNWFilterTearNWFilter(detach); #if WITH_MACVTAP - if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT) { - if (detach->ifname) - delMacvtap(detach->ifname); - } + if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT) + delMacvtap(detach); #endif if ((driver->macFilter) && (detach->ifname != NULL)) { Index: libvirt-acl/src/qemu/qemu_conf.c =================================================================== --- libvirt-acl.orig/src/qemu/qemu_conf.c +++ libvirt-acl/src/qemu/qemu_conf.c @@ -1465,8 +1465,6 @@ int qemudPhysIfaceConnect(virConnectPtr conn, struct qemud_driver *driver, virDomainNetDefPtr net, - char *linkdev, - int brmode, unsigned long long qemuCmdFlags) { int rc; @@ -1479,8 +1477,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); if (rc >= 0) { VIR_FREE(net->ifname); net->ifname = res_ifname; @@ -1500,15 +1497,13 @@ 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; qemuReportError(VIR_ERR_INTERNAL_ERROR, @@ -4130,8 +4125,6 @@ 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); if (tapfd < 0) goto error;

On Mon, May 10, 2010 at 07:57:37PM -0400, Stefan Berger wrote:
Below is David Alan's original patch with lots of changes.
In particular, it now parses the following XML and stored the data internally. No sending of netlink messages has been implemented here.
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi managerid='12' typeid='0x123456' typeidversion='1' instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f' /> <filterref filter='clean-traffic'/> </interface>
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi profileid='my_profile'/> </interface>
I'd suggest to use this patch as a base for sending out netlink messages.
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
I have 2 basic questions: - how can we be sure that if we apply this the XML interface won't need to change due to kernel interfaces, maybe Chris can confirm that the kernel is now stable enough that this should not affect the XML anymore - can I get some signoff from Cisco that there is agreement on this format and that will be sufficient for their need If I get the 2 ACK then I will review and push, assuming the low level activation via netlink can be finalized in another patch. But if there is still too many doubts about the low level, then I prefer to wait a bit since by definition the patch is not functional as-is but rather an attempt at stabilizing the libvirt API level, thanks ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Daniel Veillard <veillard@redhat.com> wrote on 05/11/2010 06:07:58 AM:
On Mon, May 10, 2010 at 07:57:37PM -0400, Stefan Berger wrote:
Below is David Alan's original patch with lots of changes.
In particular, it now parses the following XML and stored the data internally. No sending of netlink messages has been implemented here.
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi managerid='12' typeid='0x123456' typeidversion='1' instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f' /> <filterref filter='clean-traffic'/> </interface>
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi profileid='my_profile'/> </interface>
I'd suggest to use this patch as a base for sending out netlink messages.
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
I have 2 basic questions:
- how can we be sure that if we apply this the XML interface won't need to change due to kernel interfaces, maybe Chris can confirm that the kernel is now stable enough that this should not affect the XML anymore
I have been trying to gather the parameters necessary to trigger the slightly different setup protocols. I cannot be sure that this XML won't change at the moment but would also wait to have it checked in. However, the parser here works to the best of my current knowledge. The netlink messages that require these parameters drive the requirements to the XML. So, I'd wait for the kernel implementation to become stable.
- can I get some signoff from Cisco that there is agreement on this format and that will be sufficient for their need
I'd also like to have 100% re-assurance that the TWO pre-standards we are dealing with here are not going change later on and cause changes affecting the XML. Stefan
If I get the 2 ACK then I will review and push, assuming the low level activation via netlink can be finalized in another patch. But if there is still too many doubts about the low level, then I prefer to wait a bit since by definition the patch is not functional as-is but rather an attempt at stabilizing the libvirt API level,
thanks !
Daniel
-- Daniel Veillard | libxml Gnome XML XSLT toolkit
daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

* Stefan Berger (stefanb@us.ibm.com) wrote:
Daniel Veillard <veillard@redhat.com> wrote on 05/11/2010 06:07:58 AM:
On Mon, May 10, 2010 at 07:57:37PM -0400, Stefan Berger wrote:
Below is David Alan's original patch with lots of changes.
In particular, it now parses the following XML and stored the data internally. No sending of netlink messages has been implemented here.
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi managerid='12' typeid='0x123456' typeidversion='1' instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f' /> <filterref filter='clean-traffic'/> </interface>
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi profileid='my_profile'/> </interface>
I'd suggest to use this patch as a base for sending out netlink messages.
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
I have 2 basic questions:
- how can we be sure that if we apply this the XML interface won't need to change due to kernel interfaces, maybe Chris can confirm that the kernel is now stable enough that this should not affect the XML anymore
I have been trying to gather the parameters necessary to trigger the slightly different setup protocols. I cannot be sure that this XML won't change at the moment but would also wait to have it checked in. However, the parser here works to the best of my current knowledge. The netlink messages that require these parameters drive the requirements to the XML. So, I'd wait for the kernel implementation to become stable.
- can I get some signoff from Cisco that there is agreement on this format and that will be sufficient for their need
I'd also like to have 100% re-assurance that the TWO pre-standards we are dealing with here are not going change later on and cause changes affecting the XML.
Honestly, the only way you'll get that is to wait until they are standards (and even then there's possible changes, additions, etc). The low-level TLVs and the protocol ladder diagrams are not under substantial churn. Names change regularly, but the notion of preassociate/associate/deassociate and the basic id's for VDP payload (database id, profile id, mac+vlan pairs, etc). thanks, -chris

On Tue, 11 May 2010, Stefan Berger wrote:
Daniel Veillard <veillard@redhat.com> wrote on 05/11/2010 06:07:58 AM:
On Mon, May 10, 2010 at 07:57:37PM -0400, Stefan Berger wrote:
Below is David Alan's original patch with lots of changes.
In particular, it now parses the following XML and stored the data internally. No sending of netlink messages has been implemented here.
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi managerid='12' typeid='0x123456' typeidversion='1' instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f' /> <filterref filter='clean-traffic'/> </interface>
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi profileid='my_profile'/> </interface>
I'd suggest to use this patch as a base for sending out netlink messages.
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
I have 2 basic questions:
- how can we be sure that if we apply this the XML interface won't need to change due to kernel interfaces, maybe Chris can confirm that the kernel is now stable enough that this should not affect the XML anymore
I have been trying to gather the parameters necessary to trigger the slightly different setup protocols. I cannot be sure that this XML won't change at the moment but would also wait to have it checked in. However, the parser here works to the best of my current knowledge. The netlink messages that require these parameters drive the requirements to the XML. So, I'd wait for the kernel implementation to become stable.
- can I get some signoff from Cisco that there is agreement on this format and that will be sufficient for their need
I'd also like to have 100% re-assurance that the TWO pre-standards we are dealing with here are not going change later on and cause changes affecting the XML.
As of now the 802.1Qbg WG has voted and taken it forward for drafting. The version 0 spec was written for early implementers. The expectation is that the above parameters will not change for the first version. The public spec is here: http://www.ieee802.org/1/files/public/docs2010/bg-joint-evb-0410v1.pdf I expect the companies listed on page 2 to be implementing the spec in their products in parallel with the overall process. Vivek
Stefan
If I get the 2 ACK then I will review and push, assuming the low level activation via netlink can be finalized in another patch. But if there is still too many doubts about the low level, then I prefer to wait a bit since by definition the patch is not functional as-is but rather an attempt at stabilizing the libvirt API level,
thanks !
Daniel
-- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Mon, May 10, 2010 at 07:57:37PM -0400, Stefan Berger wrote:
Below is David Alan's original patch with lots of changes.
In particular, it now parses the following XML and stored the data internally. No sending of netlink messages has been implemented here.
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi managerid='12' typeid='0x123456' typeidversion='1' instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f' /> <filterref filter='clean-traffic'/> </interface>
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi profileid='my_profile'/> </interface>
Could we have an explanation of what these attributes all mean in the commit message. Also, when we have 2 different sets of attributes, we normally use a type attribute on the element to tell the parser what set of data to expect. So I think this should gain a 'type' attribute here.
@@ -1873,6 +1879,20 @@ virDomainNetDefParseXML(virCapsPtr caps, xmlStrEqual(cur->name, BAD_CAST "source")) { dev = virXMLPropString(cur, "dev"); mode = virXMLPropString(cur, "mode"); + } else if ((vsiManagerID == NULL) && + (vsiTypeID == NULL) && + (vsiTypeIDVersion == NULL) && + (vsiInstanceID == NULL) && + (vsiProfileID == NULL) && + (def->type == VIR_DOMAIN_NET_TYPE_DIRECT) && + xmlStrEqual(cur->name, BAD_CAST "vsi")) { + vsiManagerID = virXMLPropString(cur, "managerid"); + vsiTypeID = virXMLPropString(cur, "typeid"); + vsiTypeIDVersion = virXMLPropString(cur, "typeidversion"); + vsiInstanceID = virXMLPropString(cur, "instanceid"); +#ifdef IFLA_VF_PORT_PROFILE_MAX + vsiProfileID = virXMLPropString(cur, "profileid"); +#endif
XML parsing routines should not be #ifdefd. The XML format is formally defined by the schema and must never change based on compile time options.
} else if ((network == NULL) && ((def->type == VIR_DOMAIN_NET_TYPE_SERVER) || (def->type == VIR_DOMAIN_NET_TYPE_CLIENT) || @@ -2049,6 +2069,51 @@ virDomainNetDefParseXML(virCapsPtr caps, } else def->data.direct.mode = VIR_DOMAIN_NETDEV_MACVTAP_MODE_VEPA;
+ vsi = &def->data.direct.vsiProfile; + +#ifdef IFLA_VF_PORT_PROFILE_MAX + if (vsiProfileID != NULL) { + if (virStrcpyStatic(vsi->u.vsi8021Qbh.profileID, + vsiProfileID) != NULL) { + vsi->vsiType = VIR_VSI_8021QBH; + break; + } + } +#endif
Likewise here
+ + while (vsiManagerID != NULL && vsiTypeID != NULL && + vsiTypeIDVersion != NULL && vsiInstanceID != NULL) { + unsigned int val; + + if ((virStrToLong_ui(vsiManagerID, NULL, 10, &val) && + virStrToLong_ui(vsiManagerID, NULL, 16, &val) ) || + val > 0xff) + break; + + vsi->u.vsi8021Qbg.managerID = (uint8_t)val; + + if ((virStrToLong_ui(vsiTypeID, NULL, 10, &val) && + virStrToLong_ui(vsiTypeID, NULL, 16, &val) ) || + val > 0xffffff) + break; + + vsi->u.vsi8021Qbg.typeID = (uint32_t)val; + + if ((virStrToLong_ui(vsiTypeIDVersion, NULL, 10, &val) && + virStrToLong_ui(vsiTypeIDVersion, NULL, 16, &val) ) || + val > 0xff) + break; + + vsi->u.vsi8021Qbg.typeIDVersion = (uint8_t)val; + + if (virUUIDParse(vsiInstanceID, + def->data.direct.vsiProfile.u.vsi8021Qbg.instanceID)) + break; + + vsi->vsiType = VIR_VSI_8021QBG; + break; + } + def->data.direct.linkdev = dev; dev = NULL;
@@ -2114,6 +2179,11 @@ cleanup: VIR_FREE(internal); VIR_FREE(devaddr); VIR_FREE(mode); + VIR_FREE(vsiManagerID); + VIR_FREE(vsiTypeID); + VIR_FREE(vsiTypeIDVersion); + VIR_FREE(vsiInstanceID); + VIR_FREE(vsiProfileID); virNWFilterHashTableFree(filterparams);
return def; @@ -5076,6 +5146,8 @@ virDomainNetDefFormat(virBufferPtr buf, { const char *type = virDomainNetTypeToString(def->type); char *attrs; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virVSIProfileDefPtr vsi;
if (!type) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, @@ -5141,6 +5213,31 @@ virDomainNetDefFormat(virBufferPtr buf, virBufferVSprintf(buf, " mode='%s'",
virDomainNetdevMacvtapTypeToString(def->data.direct.mode)); virBufferAddLit(buf, "/>\n"); + vsi = &def->data.direct.vsiProfile; + switch (vsi->vsiType) { + case VIR_VSI_INVALID: + break; + + case VIR_VSI_8021QBG: + virUUIDFormat(def->data.direct.vsiProfile.u.vsi8021Qbg.instanceID, + uuidstr); + virBufferVSprintf(buf, + " <vsi managerid='%d' typeid='%d' " + "typeidversion='%d' instanceid='%s'/>\n", + vsi->u.vsi8021Qbg.managerID, + vsi->u.vsi8021Qbg.typeID, + vsi->u.vsi8021Qbg.typeIDVersion, + uuidstr); + break; + +#ifdef IFLA_VF_PORT_PROFILE_MAX + case VIR_VSI_8021QBH: + virBufferVSprintf(buf, + " <vsi profileid='%s'/>\n", + vsi->u.vsi8021Qbh.profileID); + break; +#endif + } break;
case VIR_DOMAIN_NET_TYPE_USER: Index: libvirt-acl/src/conf/domain_conf.h =================================================================== --- libvirt-acl.orig/src/conf/domain_conf.h +++ libvirt-acl/src/conf/domain_conf.h @@ -259,6 +259,36 @@ enum virDomainNetdevMacvtapType { };
+#define IFLA_VF_PORT_PROFILE_MAX 40 +enum virVSIType { + VIR_VSI_INVALID,
This isn't really 'INVALID' - this is better named 'NONE' since its simply an indication that this interface does not have any VSI info defined
+ VIR_VSI_8021QBG, +#ifdef IFLA_VF_PORT_PROFILE_MAX + VIR_VSI_8021QBH, +#endif
And here, etc
+}; + +/* profile data for macvtap (VEPA) */ +typedef struct _virVSIProfileDef virVSIProfileDef; +typedef virVSIProfileDef *virVSIProfileDefPtr; +struct _virVSIProfileDef { + enum virVSIType vsiType; + union { + struct { + uint8_t managerID; + uint32_t typeID; // 24 bit valid + uint8_t typeIDVersion; + unsigned char instanceID[VIR_UUID_BUFLEN]; + } vsi8021Qbg; +#ifdef IFLA_VF_PORT_PROFILE_MAX + struct { + char profileID[IFLA_VF_PORT_PROFILE_MAX]; + } vsi8021Qbh; +#endif + } u; +};
Index: libvirt-acl/tests/domainschemadata/portprofile.xml =================================================================== --- /dev/null +++ libvirt-acl/tests/domainschemadata/portprofile.xml @@ -0,0 +1,27 @@ +<domain type='lxc'> + <name>portprofile</name> + <uuid>00000000-0000-0000-0000-000000000000</uuid> + <memory>1048576</memory> + <os> + <type>exe</type> + <init>/sh</init> + </os> + <devices> + <interface type='direct'> + <source dev='eth0' mode='vepa'/> + <vsi managerid='12' typeid='1193046' typeidversion='1' + instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f'/> + </interface> + <interface type='direct'> + <source dev='eth0' mode='vepa'/> + <vsi profileid='my_profile'/> + </interface> + <interface type='direct'> + <source dev='eth0' mode='vepa'/> + <vsi/> + </interface> + <interface type='direct'> + <source dev='eth0' mode='vepa'/> + </interface> + </devices> +</domain> Index: libvirt-acl/src/qemu/qemu_conf.h =================================================================== --- libvirt-acl.orig/src/qemu/qemu_conf.h +++ libvirt-acl/src/qemu/qemu_conf.h @@ -271,8 +271,6 @@ qemudOpenVhostNet(virDomainNetDefPtr net int qemudPhysIfaceConnect(virConnectPtr conn, struct qemud_driver *driver, virDomainNetDefPtr net, - char *linkdev, - int brmode, unsigned long long qemuCmdFlags);
int qemudProbeMachineTypes (const char *binary, Index: libvirt-acl/src/qemu/qemu_driver.c =================================================================== --- libvirt-acl.orig/src/qemu/qemu_driver.c +++ libvirt-acl/src/qemu/qemu_driver.c @@ -3585,10 +3585,8 @@ static void qemudShutdownVMDaemon(struct def = vm->def; for (i = 0; i < def->nnets; i++) { virDomainNetDefPtr net = def->nets[i]; - if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { - if (net->ifname) - delMacvtap(net->ifname); - } + if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) + delMacvtap(net); } #endif
@@ -7175,8 +7173,6 @@ static int qemudDomainAttachNetDevice(vi }
if ((tapfd = qemudPhysIfaceConnect(conn, driver, net, - net->data.direct.linkdev, - net->data.direct.mode, qemuCmdFlags)) < 0) return -1; } @@ -8146,10 +8142,8 @@ qemudDomainDetachNetDevice(struct qemud_ virNWFilterTearNWFilter(detach);
#if WITH_MACVTAP - if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT) { - if (detach->ifname) - delMacvtap(detach->ifname); - } + if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT) + delMacvtap(detach); #endif
if ((driver->macFilter) && (detach->ifname != NULL)) {
Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

"Daniel P. Berrange" <berrange@redhat.com> wrote on 05/11/2010 06:25:05 AM:
On Mon, May 10, 2010 at 07:57:37PM -0400, Stefan Berger wrote:
Below is David Alan's original patch with lots of changes.
In particular, it now parses the following XML and stored the data internally. No sending of netlink messages has been implemented here.
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi managerid='12' typeid='0x123456' typeidversion='1' instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f' /> <filterref filter='clean-traffic'/> </interface>
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi profileid='my_profile'/> </interface>
Could we have an explanation of what these attributes all mean in the commit message.
To summarize here for now: The 1st provides parameters necessary to run a protocol between the host and the switch to setup switch parameters for a VM's traffic (for example). The protocol will be run by LLDPAD (daemon) getting the parameters passed via netlink messages where libvirt will (likely) send the message in form of a (netlink) multicast to be ignored by the kernel and handled by LLDPAD. The 1st is to support the (pre-)standard 802.1Qbg. The 2nd one provides a similar parameter necessary also for running a protocol between the host and the switch. In this case there will be support by the Ethernet adapter's firmware to run the protocol and libvirt will trigger it via a netlink message digested by the kernel + driver. This is to support the (pre-)standard 802.1Qbh.
Also, when we have 2 different sets of attributes, we normally use a type attribute on the element to tell the parser what set of data to expect. So I think this should gain a 'type' attribute here.
@@ -1873,6 +1879,20 @@ virDomainNetDefParseXML(virCapsPtr caps, xmlStrEqual(cur->name, BAD_CAST "source")) { dev = virXMLPropString(cur, "dev"); mode = virXMLPropString(cur, "mode"); + } else if ((vsiManagerID == NULL) && + (vsiTypeID == NULL) && + (vsiTypeIDVersion == NULL) && + (vsiInstanceID == NULL) && + (vsiProfileID == NULL) && + (def->type == VIR_DOMAIN_NET_TYPE_DIRECT) && + xmlStrEqual(cur->name, BAD_CAST "vsi")) { + vsiManagerID = virXMLPropString(cur, "managerid"); + vsiTypeID = virXMLPropString(cur, "typeid"); + vsiTypeIDVersion = virXMLPropString(cur, "typeidversion"); + vsiInstanceID = virXMLPropString(cur, "instanceid"); +#ifdef IFLA_VF_PORT_PROFILE_MAX + vsiProfileID = virXMLPropString(cur, "profileid"); +#endif
XML parsing routines should not be #ifdefd. The XML format is formally defined by the schema and must never change based on compile time
options.
Ok. I'll do away with this then.
} else if ((network == NULL) && ((def->type == VIR_DOMAIN_NET_TYPE_SERVER) || (def->type == VIR_DOMAIN_NET_TYPE_CLIENT) || @@ -2049,6 +2069,51 @@ virDomainNetDefParseXML(virCapsPtr caps, } else def->data.direct.mode = VIR_DOMAIN_NETDEV_MACVTAP_MODE_VEPA;
+ vsi = &def->data.direct.vsiProfile; + +#ifdef IFLA_VF_PORT_PROFILE_MAX + if (vsiProfileID != NULL) { + if (virStrcpyStatic(vsi->u.vsi8021Qbh.profileID, + vsiProfileID) != NULL) { + vsi->vsiType = VIR_VSI_8021QBH; + break; + } + } +#endif
Likewise here
Ok.
+#define IFLA_VF_PORT_PROFILE_MAX 40 +enum virVSIType { + VIR_VSI_INVALID,
This isn't really 'INVALID' - this is better named 'NONE' since its simply an indication that this interface does not have any VSI info defined
Will change it.
+ VIR_VSI_8021QBG, +#ifdef IFLA_VF_PORT_PROFILE_MAX + VIR_VSI_8021QBH, +#endif
And here, etc
Ok.
+}; + +/* profile data for macvtap (VEPA) */ +typedef struct _virVSIProfileDef virVSIProfileDef; +typedef virVSIProfileDef *virVSIProfileDefPtr; +struct _virVSIProfileDef { + enum virVSIType vsiType; + union { + struct { + uint8_t managerID; + uint32_t typeID; // 24 bit valid + uint8_t typeIDVersion; + unsigned char instanceID[VIR_UUID_BUFLEN]; + } vsi8021Qbg; +#ifdef IFLA_VF_PORT_PROFILE_MAX + struct { + char profileID[IFLA_VF_PORT_PROFILE_MAX]; + } vsi8021Qbh; +#endif
The size of this character array is supposed to be 40 chars as per a kernel #define that will become available through some future kernel include and #define. I'd like to restrict the size of the profile id somewhere when parsing it... What's the best way to do that? Introduce a constant that also has 40 as value ? Stefan

On Tue, May 11, 2010 at 06:54:18AM -0400, Stefan Berger wrote:
"Daniel P. Berrange" <berrange@redhat.com> wrote on 05/11/2010 06:25:05 AM:
On Mon, May 10, 2010 at 07:57:37PM -0400, Stefan Berger wrote:
Below is David Alan's original patch with lots of changes.
In particular, it now parses the following XML and stored the data internally. No sending of netlink messages has been implemented here.
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi managerid='12' typeid='0x123456' typeidversion='1' instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f' /> <filterref filter='clean-traffic'/> </interface>
<interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi profileid='my_profile'/> </interface>
Could we have an explanation of what these attributes all mean in the commit message.
To summarize here for now: The 1st provides parameters necessary to run a protocol between the host and the switch to setup switch parameters for a VM's traffic (for example). The protocol will be run by LLDPAD (daemon) getting the parameters passed via netlink messages where libvirt will (likely) send the message in form of a (netlink) multicast to be ignored by the kernel and handled by LLDPAD. The 1st is to support the (pre-)standard 802.1Qbg.
The 2nd one provides a similar parameter necessary also for running a protocol between the host and the switch. In this case there will be support by the Ethernet adapter's firmware to run the protocol and libvirt will trigger it via a netlink message digested by the kernel + driver. This is to support the (pre-)standard 802.1Qbh.
Also, when we have 2 different sets of attributes, we normally use a type attribute on the element to tell the parser what set of data to expect. So I think this should gain a 'type' attribute here.
@@ -1873,6 +1879,20 @@ virDomainNetDefParseXML(virCapsPtr caps, xmlStrEqual(cur->name, BAD_CAST "source")) { dev = virXMLPropString(cur, "dev"); mode = virXMLPropString(cur, "mode"); + } else if ((vsiManagerID == NULL) && + (vsiTypeID == NULL) && + (vsiTypeIDVersion == NULL) && + (vsiInstanceID == NULL) && + (vsiProfileID == NULL) && + (def->type == VIR_DOMAIN_NET_TYPE_DIRECT) && + xmlStrEqual(cur->name, BAD_CAST "vsi")) { + vsiManagerID = virXMLPropString(cur, "managerid"); + vsiTypeID = virXMLPropString(cur, "typeid"); + vsiTypeIDVersion = virXMLPropString(cur, "typeidversion"); + vsiInstanceID = virXMLPropString(cur, "instanceid"); +#ifdef IFLA_VF_PORT_PROFILE_MAX + vsiProfileID = virXMLPropString(cur, "profileid"); +#endif
XML parsing routines should not be #ifdefd. The XML format is formally defined by the schema and must never change based on compile time
options.
Ok. I'll do away with this then.
} else if ((network == NULL) && ((def->type == VIR_DOMAIN_NET_TYPE_SERVER) || (def->type == VIR_DOMAIN_NET_TYPE_CLIENT) || @@ -2049,6 +2069,51 @@ virDomainNetDefParseXML(virCapsPtr caps, } else def->data.direct.mode = VIR_DOMAIN_NETDEV_MACVTAP_MODE_VEPA;
+ vsi = &def->data.direct.vsiProfile; + +#ifdef IFLA_VF_PORT_PROFILE_MAX + if (vsiProfileID != NULL) { + if (virStrcpyStatic(vsi->u.vsi8021Qbh.profileID, + vsiProfileID) != NULL) { + vsi->vsiType = VIR_VSI_8021QBH; + break; + } + } +#endif
Likewise here
Ok.
+#define IFLA_VF_PORT_PROFILE_MAX 40 +enum virVSIType { + VIR_VSI_INVALID,
This isn't really 'INVALID' - this is better named 'NONE' since its simply an indication that this interface does not have any VSI info defined
Will change it.
+ VIR_VSI_8021QBG, +#ifdef IFLA_VF_PORT_PROFILE_MAX + VIR_VSI_8021QBH, +#endif
And here, etc
Ok.
+}; + +/* profile data for macvtap (VEPA) */ +typedef struct _virVSIProfileDef virVSIProfileDef; +typedef virVSIProfileDef *virVSIProfileDefPtr; +struct _virVSIProfileDef { + enum virVSIType vsiType; + union { + struct { + uint8_t managerID; + uint32_t typeID; // 24 bit valid + uint8_t typeIDVersion; + unsigned char instanceID[VIR_UUID_BUFLEN]; + } vsi8021Qbg; +#ifdef IFLA_VF_PORT_PROFILE_MAX + struct { + char profileID[IFLA_VF_PORT_PROFILE_MAX]; + } vsi8021Qbh; +#endif
The size of this character array is supposed to be 40 chars as per a kernel #define that will become available through some future kernel include and #define. I'd like to restrict the size of the profile id somewhere when parsing it... What's the best way to do that? Introduce a constant that also has 40 as value ?
The XML parsers shouldn't rely on platform #defines, so add a constant in the XML parser itself. Regardless of this, the actual implementation in qemu_driver.c should also check length boundary if the kernel API its using has a fixed buffer size Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

"Daniel P. Berrange" <berrange@redhat.com> wrote on 05/11/2010 06:25:05 AM:
Also, when we have 2 different sets of attributes, we normally use a type attribute on the element to tell the parser what set of data to expect. So I think this should gain a 'type' attribute here.
Like these here <interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi type='802.1Qbg' managerid='12' typeid='0x123456' typeidversion='1' instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f' /> <filterref filter='clean-traffic'/> </interface> <interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi type='802.1Qbh' profileid='my_profile'/> </interface> or more like this <interface type='direct'> <source dev='static' mode='vepa'/> <model type='virtio'/> <vsi type='802.1Qbg'> <parameters managerid='12' typeid='0x123456' typeidversion='1' instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f' /> </vsi> <filterref filter='clean-traffic'/> </interface> ? Stefan
participants (5)
-
Chris Wright
-
Daniel P. Berrange
-
Daniel Veillard
-
Stefan Berger
-
Vivek Kashyap