<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Tahoma
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>
<font style="font-size:12pt;" face="Times New Roman" size="3">Thanks for your inputs Daniel, please see inline. <br id="FontBreak"></font><br><br><div><div id="SkyDrivePlaceholder"></div>> Date: Mon, 9 Jul 2012 09:21:36 +0100<br>> From: berrange@redhat.com<br>> To: ata.husain@hotmail.com<br>> CC: libvirt-list@redhat.com<br>> Subject: Re: [libvirt] [PATCH] ESX: interface driver routines<br>> <br>> On Sun, Jul 08, 2012 at 08:52:01AM +0530, Ata Bohra wrote:<br>> > Attached patch adds missing routines to esx interface driver, one of<br>> > the missing routine is esxInterfaceDefineXML. I am currently working<br>> > on it and will update patch soon. Also, patch addresses some of the<br>> > changes needed in esx_vi_generator.py and esx_vi_types.c to deserialize<br>> > "String List" types. <br>> <br>> Thanks for taking the time todo all this work !<br>> <br>> > +/**<br>> > + * Generates native XML descritpor for a given interface.<br>> > + * For instance:<br>> > + *    <interface type="bridge" name="%s"><br>> > + *      <start mode="onboot"/>"<br>> > + *      <mtu size="%d"/>"<br>> > + *      <mac address="%s"/><br>> > + *      <protocol family="ipv4"><br>> > + *         <dhcp/><br>> > + *         <ip address="%s" prefix="%d"/><br>> > + *         <route gateway="%s"/><br>> > + *      </protocol><br>> > + *      <bridge stp="off"><br>> > + *         <interface type="ethernet" name="%s"><br>> > + *            <mac address="%s"/><br>> > + *         </interface><br>> > + *      </bridge><br>> > + *    </interface><br>> > + */<br>> > +static char*<br>> > +esxGetNativeInterfaceXMLDesc(const esxVI_HostVirtualNic *virtualNic,<br>> > +                             const esxVI_HostIpRouteConfig *ipRouteConfig,<br>> > +                             const esxVI_PhysicalNic *physicalNicList,<br>> > +                             const unsigned int flags)<br>> > +{<br>> > +    const esxVI_PhysicalNic *physicalNic = NULL;<br>> > +    xmlDocPtr doc = NULL;<br>> > +    xmlNodePtr root = NULL;<br>> > +    xmlNodePtr startNode = NULL;<br>> > +    xmlNodePtr mtuNode = NULL;<br>> > +    xmlNodePtr protocolNode = NULL;<br>> > +    xmlNodePtr bridgeNode = NULL;<br>> > +    xmlNodePtr dhcpNode = NULL;<br>> > +    xmlChar *xmlbuff = NULL;<br>> > +    int use_static = 0;<br>> > +    struct in_addr addr;<br>> > +    uint32_t host_addr = 0;<br>> > +    int zero_count = 0;<br>> > +    int masklen = 0;<br>> > +    int i = 0;<br>> > +    virBuffer item = VIR_BUFFER_INITIALIZER;<br>> > +    int bufferSize = 0;<br>> > +    char *ret = NULL;<br>> > +<br>> > +    if (VIR_INTERFACE_XML_INACTIVE & flags) {<br>> > +        use_static = 1;<br>> > +    }<br>> > +<br>> > +    doc = xmlNewDoc(XML_CAST "1.0");<br>> > +    root = xmlNewDocNode(doc, NULL, XML_CAST "interface", NULL);<br>> <br>> You must not construct XML documents manually like this. We have<br>> an internal data structure for representing the inteface configuration<br>> that you should populate. This has an API for generating the correct<br>> formed XML document.  See the structs & APIs in src/conf/interface_conf.h<br>> <br>> The same applies for parsing XML too - use the inteface APIs.<br>[AB]: I am using the predefined API provided by src/conf/interface_conf.h/c to generate the libvirt domain XML returned from this function (virInterfaceDefParseString). Analyzing the interface_conf.h, there are couple of ways to get interfaceDefPtr: virInterfaceDefParseString, virInterfaceDefParseFile or virInterfaceDefParseNode. So instead of preparing the native XML by using virBuffer technique I prepared XML document which is then given to virInterfaceDefParseString() to generate virInterfaceDef object and further used to generate libvirt domain interface XML file (virInterfaceDefFormat). While coding I found the XML one easy to read and follow. Please correct me if wrong. <br>> <br>> > +<br>> > +    xmlNewProp(root, XML_CAST "type", XML_CAST "bridge");<br>> > +    xmlNewProp(root, XML_CAST "name", XML_CAST virtualNic->device);<br>> > +    xmlDocSetRootElement(doc, root);<br>> > +<br>> > +    /* define boot start mode */<br>> > +    startNode = xmlNewChild(root, NULL, XML_CAST "start", NULL);<br>> > +    xmlNewProp(startNode, XML_CAST "mode", XML_CAST "onboot");<br>> > +<br>> > +    /* append mtu value */<br>> > +    mtuNode = xmlNewChild(root, NULL, XML_CAST "mtu", NULL);<br>> > +    virBufferAsprintf(&item, "%d",virtualNic->spec->mtu &&<br>> > +                                  virtualNic->spec->mtu->value ?<br>> > +                                  virtualNic->spec->mtu->value :<br>> > +                                  1500);<br>> > +    const char *mtustr = virBufferContentAndReset(&item);<br>> > +    if (mtustr == NULL) {<br>> > +        virReportOOMError();<br>> > +        goto cleanup;<br>> > +    }<br>> > +    xmlNewProp(mtuNode, XML_CAST "size", XML_CAST mtustr);<br>> > +<br>> > +    /* append mac address field */<br>> > +    if (!use_static && virtualNic->spec->mac) {<br>> > +        xmlNodePtr mac_node = xmlNewChild(root, NULL, XML_CAST "mac", NULL);<br>> > +        xmlNewProp(mac_node, XML_CAST "address",<br>> > +                   XML_CAST virtualNic->spec->mac);<br>> > +    }<br>> > +<br>> > +    /* TODO - Handle VLAN (via portgroup?) */<br>> > +    if (virtualNic->spec->ip->subnetMask &&<br>> > +        *virtualNic->spec->ip->subnetMask &&<br>> > +        inet_aton(virtualNic->spec->ip->subnetMask, &addr) == 0) {<br>> > +        ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",<br>> > +                  _("Error parsing netmask"));<br>> > +        goto cleanup;<br>> > +    }<br>> > +<br>> > +    host_addr = ntohl(addr.s_addr);<br>> > +    /* Calculate masklen */<br>> > +    for (i = 0; i < 32; ++i) {<br>> > +        if (host_addr & 0x01) {<br>> > +             break;<br>> > +        }<br>> > +        zero_count++;<br>> > +        host_addr >>= 1;<br>> > +    }<br>> > +    masklen = 32 - zero_count;<br>> > +<br>> > +    /* append protocol field */<br>> > +    /* TODO - Add IPv6 Support */<br>> > +    protocolNode = xmlNewChild(root, NULL, XML_CAST "protocol", NULL);<br>> > +    xmlNewProp(protocolNode, XML_CAST "family", XML_CAST "ipv4");<br>> > +    if (virtualNic->spec->ip->dhcp == 1) {<br>> > +        dhcpNode = xmlNewChild(protocolNode, NULL, XML_CAST "dhcp", NULL);<br>> > +        /* avoids compiler warning */<br>> > +        VIR_DEBUG("dhcpNode name: %s", (char *)dhcpNode->name);<br>> > +    }<br>> > +<br>> > +    if (virtualNic->spec->ip->dhcp != 1 || !use_static) {<br>> > +        if (virtualNic->spec->ip->ipAddress &&<br>> > +            *virtualNic->spec->ip->ipAddress) {<br>> > +            xmlNodePtr ipAddrNode =<br>> > +                xmlNewChild(protocolNode, NULL, XML_CAST "ip", NULL);<br>> > +            xmlNewProp(ipAddrNode, XML_CAST "address", XML_CAST<br>> > +                                virtualNic->spec->ip->ipAddress);<br>> > +<br>> > +            virBufferAsprintf(&item, "%d", masklen);<br>> > +            const char *maskstr = virBufferContentAndReset(&item);<br>> > +            if (maskstr == NULL) {<br>> > +                virReportOOMError();<br>> > +                goto cleanup;<br>> > +            }<br>> > +            xmlNewProp(ipAddrNode, XML_CAST "prefix", XML_CAST maskstr);<br>> > +<br>> > +            xmlNodePtr routeNode =<br>> > +                xmlNewChild(protocolNode, NULL, XML_CAST "route", NULL);<br>> > +            xmlNewProp(routeNode, XML_CAST "gateway",<br>> > +                              XML_CAST ipRouteConfig->defaultGateway);<br>> > +        }<br>> > +    }<br>> > +<br>> > +    /* Add bridge information */<br>> > +    bridgeNode = xmlNewChild(root, NULL, XML_CAST "bridge", NULL);<br>> > +    xmlNewProp(bridgeNode, XML_CAST "stp", XML_CAST "off");<br>> > +<br>> > +    for (physicalNic = physicalNicList;<br>> > +         physicalNic != NULL;<br>> > +         physicalNic = physicalNic->_next) {<br>> > +        xmlNodePtr bridgeIfaceNode =<br>> > +            xmlNewChild(bridgeNode, NULL, XML_CAST "interface", NULL);<br>> > +        xmlNewProp(bridgeIfaceNode, XML_CAST "type", XML_CAST "ethernet");<br>> > +        xmlNewProp(bridgeIfaceNode, XML_CAST "name",<br>> > +          XML_CAST physicalNic->device);<br>> > +<br>> > +        xmlNodePtr bridgeIfaceMacNode =<br>> > +            xmlNewChild(bridgeIfaceNode, NULL, XML_CAST "mac", NULL);<br>> > +        xmlNewProp(bridgeIfaceMacNode, XML_CAST "address",<br>> > +          XML_CAST physicalNic->mac);<br>> > +    }<br>> > +<br>> > +    xmlDocDumpFormatMemory(doc, &xmlbuff, &bufferSize, 1);<br>> > +    if (xmlbuff == NULL) {<br>> > +        virReportOOMError();<br>> > +        goto cleanup;<br>> > +    }<br>> > +<br>> > +    ret = strdup((char *)xmlbuff);<br>> > +    if (ret == NULL) {<br>> > +        virReportOOMError();<br>> > +        goto cleanup;<br>> > +    }<br>> > +<br>> > + cleanup:<br>> > +    VIR_FREE(mtustr);<br>> > +    if (xmlbuff != NULL) {<br>> > +        xmlFree(xmlbuff);<br>> > +    }<br>> > +    xmlFreeDoc(doc);<br>> > +<br>> > +    return ret;<br>> > +}<br>> > +static int<br>> <br>> <br>> Regards,<br>> Daniel<br>> -- <br>> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|<br>> |: http://libvirt.org              -o-             http://virt-manager.org :|<br>> |: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|<br>> |: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|<br><br>Thanks!<br>Ata<br></div>                                    </div></body>
</html>