
On Sun, Jul 08, 2012 at 11:36:47AM -0700, Ata Bohra wrote:
From: Ata E Husain <ata.husain@hotmail.com>
Includes most of the dirver routines except DefineXML, I am working on it and will update patch for it soon.
+/** + * Generates native XML descritpor for a given interface. + * For instance: + * <interface type="bridge" name="%s"> + * <start mode="onboot"/>" + * <mtu size="%d"/>" + * <mac address="%s"/> + * <protocol family="ipv4"> + * <dhcp/> + * <ip address="%s" prefix="%d"/> + * <route gateway="%s"/> + * </protocol> + * <bridge stp="off"> + * <interface type="ethernet" name="%s"> + * <mac address="%s"/> + * </interface> + * </bridge> + * </interface> + */ +static char* +esxGetNativeInterfaceXMLDesc(const esxVI_HostVirtualNic *virtualNic, + const esxVI_HostIpRouteConfig *ipRouteConfig, + const esxVI_PhysicalNic *physicalNicList, + const unsigned int flags) +{ + const esxVI_PhysicalNic *physicalNic = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr root = NULL; + xmlNodePtr startNode = NULL; + xmlNodePtr mtuNode = NULL; + xmlNodePtr protocolNode = NULL; + xmlNodePtr bridgeNode = NULL; + xmlNodePtr dhcpNode = NULL; + xmlChar *xmlbuff = NULL; + int use_static = 0; + struct in_addr addr; + uint32_t host_addr = 0; + int zero_count = 0; + int masklen = 0; + int i = 0; + virBuffer item = VIR_BUFFER_INITIALIZER; + int bufferSize = 0; + char *ret = NULL; + + if (VIR_INTERFACE_XML_INACTIVE & flags) { + use_static = 1; + } + + doc = xmlNewDoc(XML_CAST "1.0"); + root = xmlNewDocNode(doc, NULL, XML_CAST "interface", NULL); + + xmlNewProp(root, XML_CAST "type", XML_CAST "bridge"); + xmlNewProp(root, XML_CAST "name", XML_CAST virtualNic->device); + xmlDocSetRootElement(doc, root); + + /* define boot start mode */ + startNode = xmlNewChild(root, NULL, XML_CAST "start", NULL); + xmlNewProp(startNode, XML_CAST "mode", XML_CAST "onboot"); + + /* append mtu value */ + mtuNode = xmlNewChild(root, NULL, XML_CAST "mtu", NULL); + virBufferAsprintf(&item, "%d",virtualNic->spec->mtu && + virtualNic->spec->mtu->value ? + virtualNic->spec->mtu->value : + 1500); + const char *mtustr = virBufferContentAndReset(&item); + if (mtustr == NULL) { + virReportOOMError(); + goto cleanup; + } + xmlNewProp(mtuNode, XML_CAST "size", XML_CAST mtustr); + + /* append mac address field */ + if (!use_static && virtualNic->spec->mac) { + xmlNodePtr mac_node = xmlNewChild(root, NULL, XML_CAST "mac", NULL); + xmlNewProp(mac_node, XML_CAST "address", + XML_CAST virtualNic->spec->mac); + } + + /* TODO - Handle VLAN (via portgroup?) */ + if (virtualNic->spec->ip->subnetMask && + *virtualNic->spec->ip->subnetMask && + inet_aton(virtualNic->spec->ip->subnetMask, &addr) == 0) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Error parsing netmask")); + goto cleanup; + } + + host_addr = ntohl(addr.s_addr); + /* Calculate masklen */ + for (i = 0; i < 32; ++i) { + if (host_addr & 0x01) { + break; + } + zero_count++; + host_addr >>= 1; + } + masklen = 32 - zero_count; + + /* append protocol field */ + /* TODO - Add IPv6 Support */ + protocolNode = xmlNewChild(root, NULL, XML_CAST "protocol", NULL); + xmlNewProp(protocolNode, XML_CAST "family", XML_CAST "ipv4"); + if (virtualNic->spec->ip->dhcp == 1) { + dhcpNode = xmlNewChild(protocolNode, NULL, XML_CAST "dhcp", NULL); + /* avoids compiler warning */ + VIR_DEBUG("dhcpNode name: %s", (char *)dhcpNode->name); + } + + if (virtualNic->spec->ip->dhcp != 1 || !use_static) { + if (virtualNic->spec->ip->ipAddress && + *virtualNic->spec->ip->ipAddress) { + xmlNodePtr ipAddrNode = + xmlNewChild(protocolNode, NULL, XML_CAST "ip", NULL); + xmlNewProp(ipAddrNode, XML_CAST "address", XML_CAST + virtualNic->spec->ip->ipAddress); + + virBufferAsprintf(&item, "%d", masklen); + const char *maskstr = virBufferContentAndReset(&item); + if (maskstr == NULL) { + virReportOOMError(); + goto cleanup; + } + xmlNewProp(ipAddrNode, XML_CAST "prefix", XML_CAST maskstr); + + xmlNodePtr routeNode = + xmlNewChild(protocolNode, NULL, XML_CAST "route", NULL); + xmlNewProp(routeNode, XML_CAST "gateway", + XML_CAST ipRouteConfig->defaultGateway); + } + } + + /* Add bridge information */ + bridgeNode = xmlNewChild(root, NULL, XML_CAST "bridge", NULL); + xmlNewProp(bridgeNode, XML_CAST "stp", XML_CAST "off"); + + for (physicalNic = physicalNicList; + physicalNic != NULL; + physicalNic = physicalNic->_next) { + xmlNodePtr bridgeIfaceNode = + xmlNewChild(bridgeNode, NULL, XML_CAST "interface", NULL); + xmlNewProp(bridgeIfaceNode, XML_CAST "type", XML_CAST "ethernet"); + xmlNewProp(bridgeIfaceNode, XML_CAST "name", + XML_CAST physicalNic->device); + + xmlNodePtr bridgeIfaceMacNode = + xmlNewChild(bridgeIfaceNode, NULL, XML_CAST "mac", NULL); + xmlNewProp(bridgeIfaceMacNode, XML_CAST "address", + XML_CAST physicalNic->mac); + } + + xmlDocDumpFormatMemory(doc, &xmlbuff, &bufferSize, 1); + if (xmlbuff == NULL) { + virReportOOMError(); + goto cleanup; + } + + ret = strdup((char *)xmlbuff); + if (ret == NULL) { + virReportOOMError(); + goto cleanup; + } + + cleanup: + VIR_FREE(mtustr); + if (xmlbuff != NULL) { + xmlFree(xmlbuff); + } + xmlFreeDoc(doc); + + return ret; +}
Same comment as on your previous posting - don't construct the XML by hand. Use the APIs in src/conf/interface_conf.h Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|