diff --git a/src/esx/esx_interface_driver.c b/src/esx/esx_interface_driver.c index 5713137..4feadc2 100644 --- a/src/esx/esx_interface_driver.c +++ b/src/esx/esx_interface_driver.c @@ -23,6 +23,10 @@ */ #include +#include +#include +#include +#include #include "internal.h" #include "util.h" @@ -34,10 +38,10 @@ #include "esx_vi.h" #include "esx_vi_methods.h" #include "esx_util.h" +#include "interface_conf.h" #define VIR_FROM_THIS VIR_FROM_ESX - - +#define XML_CAST (const xmlChar*) static virDrvOpenStatus esxInterfaceOpen(virConnectPtr conn, @@ -67,10 +71,565 @@ esxInterfaceClose(virConnectPtr conn) +static int +esxNumOfInterfaces(virConnectPtr conn) +{ + esxPrivate *priv = conn->interfacePrivateData; + esxVI_HostVirtualNic *virtualNicList = NULL; + const esxVI_HostVirtualNic *virtualNic = NULL; + int count = 0; + + if (esxVI_EnsureSession(priv->primary) < 0 || + esxVI_LookupVirtualNicList(priv->primary, &virtualNicList) < 0) { + goto cleanup; + } + + if (virtualNicList == NULL) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not retrieve vNic List")); + + goto cleanup; + } + + for (virtualNic = virtualNicList; + virtualNic != NULL; + virtualNic = virtualNic->_next) { + count++; + } + +cleanup: + esxVI_HostVirtualNic_Free(&virtualNicList); + + return count; +} + + + +static int +esxNumOfDefinedInterfaces(virConnectPtr conn) +{ + conn->interfacePrivateData = NULL; + + // ESX interfaces are always active + return 0; +} + + + +static int +esxListInterfaces(virConnectPtr conn, char **names, int maxnames) +{ + esxPrivate *priv = conn->interfacePrivateData; + esxVI_HostVirtualNic *virtualNicList = NULL; + const esxVI_HostVirtualNic *virtualNic = NULL; + int result = -1; + int i = 0; + + if (esxVI_EnsureSession(priv->primary) < 0 || + esxVI_LookupVirtualNicList(priv->primary, + &virtualNicList) < 0) { + goto cleanup; + } + + if (virtualNicList == NULL) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not retrieve vNIC List")); + goto cleanup; + } + + for (i= 0, virtualNic = virtualNicList; + virtualNic != NULL && i < maxnames; + ++i, virtualNic = virtualNic->_next) { + names[i] = strdup(virtualNic->device); + + if (names[i] == NULL) { + for(;i >=0;--i) { + VIR_FREE(names[i]); + } + virReportOOMError(); + goto cleanup; + } + } + + result = i; + cleanup: + esxVI_HostVirtualNic_Free(&virtualNicList); + + return result; +} + + + +static int +esxListDefinedInterfaces(virConnectPtr conn, char **names, int maxnames) +{ + conn->interfacePrivateData = NULL; + *names = NULL; + + /* keeps compiler happy */ + VIR_DEBUG("Max Interfaces: %d", maxnames); + /* ESX interfaces are always active */ + return 0; +} + + + +static virInterfacePtr +esxInterfaceLookupByName(virConnectPtr conn, const char *name) +{ + esxPrivate *priv = conn->interfacePrivateData; + esxVI_HostVirtualNic *virtualNicList = NULL; + const esxVI_HostVirtualNic *virtualNic = NULL; + virInterfacePtr ret = NULL; + + if (esxVI_EnsureSession(priv->primary) < 0 || + esxVI_LookupVirtualNicList(priv->primary, + &virtualNicList) < 0) { + goto cleanup; + } + + if (virtualNicList == 0) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not retrieve vNIC List")); + goto cleanup; + } + + + for(virtualNic = virtualNicList; + virtualNic != NULL; + virtualNic = virtualNic->_next) { + if (STREQ(virtualNic->device, name)) { + if (virtualNic->spec == NULL || + virtualNic->spec->mac == NULL) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Malformed HostVirtualNicSpec")); + goto cleanup; + } + + ret = virGetInterface(conn, virtualNic->device, virtualNic->spec->mac); + break; + } + } + + cleanup: + esxVI_HostVirtualNic_Free(&virtualNicList); + + return ret; +} + + + +static virInterfacePtr +esxInterfaceLookupByMACString(virConnectPtr conn, const char *mac) +{ + esxPrivate *priv = conn->interfacePrivateData; + esxVI_HostVirtualNic *virtualNicList = NULL; + const esxVI_HostVirtualNic *virtualNic = NULL; + virInterfacePtr ret = NULL; + + if (esxVI_EnsureSession(priv->primary) < 0 || + esxVI_LookupVirtualNicList(priv->primary, + &virtualNicList) < 0) { + goto cleanup; + } + + if (virtualNicList == 0) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not retrieve vNIC List")); + goto cleanup; + } + + + for(virtualNic = virtualNicList; + virtualNic != NULL; + virtualNic = virtualNic->_next) { + if (virtualNic->spec == NULL || + virtualNic->spec->mac == NULL) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Malformed HostVirtualNicSpec")); + goto cleanup; + } + + if (STREQ(virtualNic->spec->mac, mac)) { + ret = + virGetInterface(conn, virtualNic->device, virtualNic->spec->mac); + break; + } + } + + cleanup: + esxVI_HostVirtualNic_Free(&virtualNicList); + + return ret; +} + + +/** + * Generates native XML descritpor for a given interface. + * For instance: + * + * " + * " + * + * + * + * + * + * + * + * + * + * + * + * + */ +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; +} + + + +static char* +esxInterfaceGetXMLDesc(virInterfacePtr iface, unsigned int flags) +{ + esxPrivate *priv = iface->conn->interfacePrivateData; + esxVI_HostVirtualNic *virtualNicList = NULL; + esxVI_HostVirtualNic *virtualNic = NULL; + esxVI_PhysicalNic *physicalNicList = NULL; + esxVI_PhysicalNic *matchingPhysicalNicList = NULL; + esxVI_HostIpRouteConfig *ipRouteConfig = NULL; + esxVI_HostPortGroup *portGroupList = NULL; + esxVI_HostVirtualSwitch *virtualSwitchList = NULL; + esxVI_String *propertyNameList = NULL; + esxVI_ObjectContent *hostSystem = NULL; + esxVI_DynamicProperty *dynamicProperty = NULL; + virInterfaceDefPtr def = NULL; + char *xmlstr = NULL; + char *ret = NULL; + + if (esxVI_EnsureSession(priv->primary) < 0 || + esxVI_String_AppendValueListToList(&propertyNameList, + "config.network.vnic\0" + "config.network.ipRouteConfig\0" + "config.network.vswitch\0" + "config.network.pnic\0" + "config.network.portgroup\0") < 0 || + esxVI_LookupHostSystemProperties(priv->primary, propertyNameList, + &hostSystem) < 0) { + goto cleanup; + } + + for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL; + dynamicProperty = dynamicProperty->_next) { + if (STREQ(dynamicProperty->name, "config.network.vnic")) { + if (esxVI_HostVirtualNic_CastListFromAnyType(dynamicProperty->val, + &virtualNicList) + < 0) { + goto cleanup; + } + } else if (STREQ(dynamicProperty->name, "config.network.ipRouteConfig")) { + if (esxVI_HostIpRouteConfig_CastFromAnyType(dynamicProperty->val, + &ipRouteConfig)) { + goto cleanup; + } + } else if (STREQ(dynamicProperty->name, "config.network.vswitch")) { + if (esxVI_HostVirtualSwitch_CastListFromAnyType + (dynamicProperty->val, &virtualSwitchList) < 0) { + goto cleanup; + } + } else if (STREQ(dynamicProperty->name, "config.network.pnic")) { + if (esxVI_PhysicalNic_CastListFromAnyType(dynamicProperty->val, + &physicalNicList) + < 0) { + goto cleanup; + } + } else if (STREQ(dynamicProperty->name, "config.network.portgroup")) { + if (esxVI_HostPortGroup_CastListFromAnyType(dynamicProperty->val, + &portGroupList) + < 0) { + goto cleanup; + } + } else { + VIR_WARN("Unexpected '%s' property", dynamicProperty->name); + } + } + + if (!virtualNicList || + !ipRouteConfig || + !virtualSwitchList || + !portGroupList) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to retrieve network parameters")); + + goto cleanup; + } + + for (virtualNic = virtualNicList; + virtualNic != NULL; + virtualNic = virtualNic->_next) { + if (STREQ(virtualNic->device, iface->name)) { + break; + } + } + + if (virtualNic == NULL) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not find Interface")); + goto cleanup; + } + + if (esxVI_LookupPhysicalNicFromPortGroup(virtualNic->portgroup, + portGroupList, + virtualSwitchList, + physicalNicList, + &matchingPhysicalNicList) < 0) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("No Physical NIC found matching Virtual NIC's portgroup")); + goto cleanup; + } + + /* create a xml descriptor and parse it using virInterfaceDefParseString */ + xmlstr = esxGetNativeInterfaceXMLDesc(virtualNic, + ipRouteConfig, + matchingPhysicalNicList, + flags); + if (xmlstr == NULL) { + goto cleanup; + } + + def = virInterfaceDefParseString(xmlstr); + if (!def) { + goto cleanup; + } + + ret = virInterfaceDefFormat(def); + if (!ret) { + goto cleanup; + } + + cleanup: + esxVI_HostVirtualNic_Free(&virtualNicList); + esxVI_PhysicalNic_Free(&physicalNicList); + esxVI_PhysicalNic_Free(&matchingPhysicalNicList); + esxVI_HostPortGroup_Free(&portGroupList); + esxVI_HostVirtualSwitch_Free(&virtualSwitchList); + esxVI_HostIpRouteConfig_Free(&ipRouteConfig); + esxVI_ObjectContent_Free(&hostSystem); + esxVI_String_Free(&propertyNameList); + virInterfaceDefFree(def); + VIR_FREE(xmlstr); + + return ret; +} + + + +static int +esxInterfaceUndefine(virInterfacePtr iface) +{ + esxPrivate *priv = iface->conn->interfacePrivateData; + + if (esxVI_RemoveVirtualNic( + priv->primary, + priv->primary->hostSystem->configManager->networkSystem, + iface->name) < 0) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Error deleting interface")); + return -1; + } + + return 0; +} + + + +static int +esxInterfaceCreate(virInterfacePtr iface, unsigned int flags) +{ + iface->conn->interfacePrivateData = NULL; + + virCheckFlags(0, -1); + + /* ESX interfaces are always active */ + return 0; +} + + +static int +esxInterfaceDestroy(virInterfacePtr iface, unsigned int flags) +{ + iface->conn->privateData = NULL; + + virCheckFlags(0, -1); + + /* ESX does not support deactivating interfaces */ + return 1; +} + static virInterfaceDriver esxInterfaceDriver = { .name = "ESX", - .open = esxInterfaceOpen, /* 0.7.6 */ - .close = esxInterfaceClose, /* 0.7.6 */ + .open = esxInterfaceOpen, /* 0.7.6 */ + .close = esxInterfaceClose, /* 0.7.6 */ + .numOfInterfaces = esxNumOfInterfaces, /* 0.9.x */ + .numOfDefinedInterfaces = esxNumOfDefinedInterfaces, /* 0.9.x */ + .listInterfaces = esxListInterfaces, /* 0.9.x */ + .listDefinedInterfaces = esxListDefinedInterfaces, /* 0.9.x */ + .interfaceLookupByName = esxInterfaceLookupByName, /* 0.9.x */ + .interfaceLookupByMACString = esxInterfaceLookupByMACString, /* 0.9.x */ + .interfaceGetXMLDesc = esxInterfaceGetXMLDesc, /* 0.9.x */ + .interfaceUndefine = esxInterfaceUndefine, /* 0.9.x */ + .interfaceCreate = esxInterfaceCreate, /* 0.9.x */ + .interfaceDestroy = esxInterfaceDestroy, /* 0.9.x */ }; diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c index 5b5ab69..df9f8df 100644 --- a/src/esx/esx_vi.c +++ b/src/esx/esx_vi.c @@ -4414,4 +4414,134 @@ esxVI_LookupManagedObjectHelper(esxVI_Context *ctx, +int +esxVI_LookupVirtualNicList(esxVI_Context* ctx, + esxVI_HostVirtualNic** virtualNicList) +{ + int result = -1; + esxVI_String *propertyNameList = NULL; + esxVI_DynamicProperty *dynamicProperty = NULL; + esxVI_ObjectContent* hostSystem = NULL; + + if (esxVI_String_AppendValueListToList( + &propertyNameList, "config.network.vnic\0") < 0 || + esxVI_LookupHostSystemProperties(ctx, propertyNameList, &hostSystem) < 0) { + goto cleanup; + } + + if (hostSystem == NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not retrieve the HostSystem object")); + + goto cleanup; + } + + for (dynamicProperty = hostSystem->propSet; + dynamicProperty != NULL; + dynamicProperty = dynamicProperty->_next) { + if (STREQ(dynamicProperty->name, "config.network.vnic")) { + if (esxVI_HostVirtualNic_CastListFromAnyType(dynamicProperty->val, + virtualNicList) < 0) { + goto cleanup; + } + break; + } else { + VIR_WARN("Unexpected '%s' property", dynamicProperty->name); + } + } + + result = 0; + +cleanup: + esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&hostSystem); + + return result; +} + + + +int +esxVI_LookupPhysicalNicFromPortGroup( + const char *portgroup, + const esxVI_HostPortGroup *portGroupList, + const esxVI_HostVirtualSwitch *virtualSwitchList, + const esxVI_PhysicalNic *physicalNicList, + esxVI_PhysicalNic **ret_physicalNicList) +{ + int result = -1; + const esxVI_HostPortGroup *portGroup = NULL; + const esxVI_HostVirtualSwitch *virtualSwitch = NULL; + esxVI_PhysicalNic *matchingPhysicalNicList = NULL; + const esxVI_PhysicalNic *physicalNic = NULL; + esxVI_PhysicalNic *tempPhysicalNic = NULL; + const esxVI_String *pnicKey = NULL; + + if (portgroup == NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("No Portgroup found!")); + goto cleanup; + } + + /* Go through all the port groups to find the one that matches. */ + for (portGroup = portGroupList; + portGroup != NULL; + portGroup = portGroup->_next) { + if (STREQ(portGroup->spec->name, portgroup)) { + break; + } + } + + if (portGroup == NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not find Host port group")); + goto cleanup; + } + + /* Go through all the virtual switches to find the one that matches */ + for (virtualSwitch = virtualSwitchList; + virtualSwitch != NULL; + virtualSwitch = virtualSwitch->_next) { + if (STREQ(portGroup->spec->vswitchName, virtualSwitch->name)) { + break; + } + } + + if (virtualSwitch == NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not find Virtual Switch")); + goto cleanup; + } + + /* Go through all physical nics */ + for (pnicKey = virtualSwitch->pnic; + pnicKey != NULL; + pnicKey = pnicKey->_next) { + /* O(n^2), but probably faster than a hash due to small N */ + for (physicalNic = physicalNicList; + physicalNic != NULL; + physicalNic = physicalNic->_next) { + + if (STREQ(pnicKey->value, physicalNic->key)) { + if (esxVI_PhysicalNic_DeepCopy(&tempPhysicalNic, + (esxVI_PhysicalNic *)physicalNic) < 0 || + esxVI_PhysicalNic_AppendToList(&matchingPhysicalNicList, + tempPhysicalNic) < 0) { + goto cleanup; + } + tempPhysicalNic = NULL; + } + } + } + + *ret_physicalNicList = matchingPhysicalNicList; + matchingPhysicalNicList = NULL; /* no cleanup needed */ + tempPhysicalNic = NULL; /* no cleanup needed */ + result = 0; + cleanup: + esxVI_PhysicalNic_Free(&matchingPhysicalNicList); + esxVI_PhysicalNic_Free(&tempPhysicalNic); + return result; +} + #include "esx_vi.generated.c" diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h index 78d3986..11bc52e 100644 --- a/src/esx/esx_vi.h +++ b/src/esx/esx_vi.h @@ -487,6 +487,16 @@ int esxVI_ParseHostCpuIdInfo(esxVI_ParsedHostCpuIdInfo *parsedHostCpuIdInfo, int esxVI_ProductVersionToDefaultVirtualHWVersion(esxVI_ProductVersion productVersion); +int esxVI_LookupVirtualNicList(esxVI_Context* ctx, + esxVI_HostVirtualNic** virtualNicList); + +int esxVI_LookupPhysicalNicFromPortGroup( + const char *portgroup, + const esxVI_HostPortGroup *portGroupList, + const esxVI_HostVirtualSwitch *virtualSwitchList, + const esxVI_PhysicalNic *physicalNicList, + esxVI_PhysicalNic **ret_physicalNicList); + # include "esx_vi.generated.h" #endif /* __ESX_VI_H__ */ diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input index 1a67a8c..b99fee6 100644 --- a/src/esx/esx_vi_generator.input +++ b/src/esx/esx_vi_generator.input @@ -57,6 +57,29 @@ enum AutoStartWaitHeartbeatSetting systemDefault end +enum HostConfigChangeOperation + add + edit + remove +end + +enum HostIpConfigIpV6AdressStatus + deprecated + duplicate + inaccessible + invalid + preferred + tentative + unknown +end + +enum HostIpConfigV6AdressConfigType + dhcp + linklayer + manual + other + random +end enum ManagedEntityStatus gray @@ -89,6 +112,12 @@ enum PerfSummaryType none end +enum PortGroupConnecteeType + host + systemManagement + unknown + virtualMachine +end enum PropertyChangeOp add @@ -197,6 +226,12 @@ object DeviceBackedVirtualDiskSpec extends VirtualDiskSpec String device r end +object DistributedVirtualSwitchPortConnection + Int connectionCookie o + String portgroupKey o + String portKey o + String switchUuid r +end object DynamicProperty String name r @@ -316,6 +351,34 @@ object HostFileSystemVolume Long capacity r end +object HostIpConfig + Boolean dhcp r + String ipAddress o + HostIpConfigIpV6AddressConfiguration ipV6Config o + String subnetMask o +end + +object HostIpConfigIpV6Address + String dadState o + String ipAddress r + DateTime lifetime o + String operation o + String origin o + Int prefixLength r +end + +object HostIpConfigIpV6AddressConfiguration + Boolean autoConfigurationEnabled o + Boolean dhcpV6Enabled o + HostIpConfigIpV6Address ipV6Address ol +end + +object HostIpRouteConfig + String defaultGateway o + String gatewayDevice o + String ipV6DefaultGateway o + String ipV6GatewayDevice o +end object HostMountInfo String path o @@ -331,11 +394,134 @@ object HostNasVolume extends HostFileSystemVolume end +object HostNicTeamingPolicy + HostNicFailureCriteria failureCriteria o + HostNicOrderPolicy nicOrder o + Boolean notifySwitches o + String policy o + Boolean reversePolicy o + Boolean rollingOrder o +end + +object HostNetOffloadCapabilities + Boolean csumOffload o + Boolean tcpSegmentation o + Boolean zeroCopyXmit o +end + +object HostNetworkSecurityPolicy + Boolean allowPromiscuous o + Boolean forgedTransmits o + Boolean macChanges o +end + +object HostNetworkPolicy + HostNicTeamingPolicy nicTeaming o + HostNetOffloadCapabilities offloadPolicy o + HostNetworkSecurityPolicy security o + HostNetworkTrafficShapingPolicy shapingPolicy o +end + +object HostNetworkTrafficShapingPolicy + Long averageBandwidth o + Long burstLong o + Boolean enabled o + Long peakBandwidth o +end + +object HostNicFailureCriteria + String checkSpeed o + Int speed o + Boolean checkDuplex o + Boolean fullDuplex o + Boolean checkErrorPercent o + Int percentage o + Boolean checkBeacon o +end + +object HostNicOrderPolicy + String activeNic ol + String standbyNic ol +end + +object HostPortGroup + String key r + HostPortGroupPort port ol + String vswitch r + HostNetworkPolicy computedPolicy r + HostPortGroupSpec spec r +end + +object HostPortGroupPort + String key o + String mac ol + String type r +end + +object HostPortGroupSpec + String name r + HostNetworkPolicy policy r + Int vlanId r + String vswitchName r +end + object HostScsiDiskPartition String diskName r Int partition r end +object HostVirtualNic + String device r + String key r + String port o + String portgroup r + HostVirtualNicSpec spec r +end + +object HostVirtualNicSpec + DistributedVirtualSwitchPortConnection distributedVirtualPort o + HostIpConfig ip o + String mac o + Int mtu o + String portgroup o + Boolean tsoEnabled o +end + + +object HostVirtualSwitch + String key r + Int mtu o + String name r + Int numPorts r + Int numPortsAvailable r + String pnic ol + String portgroup ol + HostVirtualSwitchSpec spec r +end + +object HostVirtualSwitchBridge +end + +object HostVirtualSwitchAutoBridge extends HostVirtualSwitchBridge + String excludedNicDevice ol +end + +object HostVirtualSwitchBeaconBridge extends HostVirtualSwitchBridge + Int interval r +end + +object HostVirtualSwitchBondBridge extends HostVirtualSwitchBridge + HostVirtualSwitchBeaconBridge beacon o + LinkDiscoveryProtocolConfig linkDiscoveryProtocolConfig o + String nicDevice rl +end + +object HostVirtualSwitchSpec + HostVirtualSwitchBridge bridge o + Int mtu o + Int numPorts r + HostNetworkPolicy policy o +end object HostVmfsVolume extends HostFileSystemVolume Int blockSizeMb r @@ -355,6 +541,10 @@ end object IsoImageFileQuery extends FileQuery end +object LinkDiscoveryProtocolConfig + String operation r + String protocol r +end object LocalDatastoreInfo extends DatastoreInfo String path o @@ -398,6 +588,10 @@ object OptionType Boolean valueIsReadonly o end +object OptionValue + String key r + AnyType value r +end object PerfCounterInfo Int key r @@ -454,6 +648,27 @@ object PerfSampleInfo Int interval r end +object PhysicalNic + String device r + String driver o + String key o + PhysicalNicInfo linkSpeed o + String mac r + String pci r + PhysicalNicSpec spec r + PhysicalNicInfo validLinkSpecification ol + Boolean wakeOnLanSupported r +end + +object PhysicalNicInfo + Boolean duplex r + Int speedMb r +end + +object PhysicalNicSpec + HostIpConfig ip o + PhysicalNicInfo linkSpeed o +end object PropertyChange String name r @@ -490,7 +705,6 @@ object ResourceAllocationInfo Long overheadLimit o end - object ResourcePoolResourceUsage Long reservationUsed r Long reservationUsedForVm r @@ -954,6 +1168,10 @@ method RemoveSnapshot_Task returns ManagedObjectReference r Boolean removeChildren r end +method RemoveVirtualNic + ManagedObjectReference _this r + String device r +end method RetrieveProperties returns ObjectContent ol ManagedObjectReference _this:propertyCollector r @@ -1002,6 +1220,16 @@ method UnregisterVM ManagedObjectReference _this r end +method UpdateIpRouteConfig + ManagedObjectReference _this r + HostIpRouteConfig config r +end + +method UpdateVirtualNic + ManagedObjectReference _this r + String device r + HostVirtualNicSpec nic r +end method WaitForUpdates returns UpdateSet r ManagedObjectReference _this:propertyCollector r diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py index 8a128df..787a28c 100755 --- a/src/esx/esx_vi_generator.py +++ b/src/esx/esx_vi_generator.py @@ -371,8 +371,12 @@ class Property(Member): % self.name elif self.occurrence in [OCCURRENCE__REQUIRED_LIST, OCCURRENCE__OPTIONAL_LIST]: - return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_LIST(%s, %s)\n" \ - % (self.type, self.name) + if self.type == "String": + return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_STRING_LIST(%s, %s)\n" \ + % (self.type, self.name) + else: + return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_LIST(%s, %s)\n" \ + % (self.type, self.name) elif self.type == "String": return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, %s)\n" \ % self.name @@ -1505,7 +1509,10 @@ predefined_objects = ["AnyType", additional_enum_features = { "ManagedEntityStatus" : Enum.FEATURE__ANY_TYPE, "TaskInfoState" : Enum.FEATURE__ANY_TYPE, - "VirtualMachinePowerState" : Enum.FEATURE__ANY_TYPE } + "VirtualMachinePowerState" : Enum.FEATURE__ANY_TYPE , + "HostIpConfigIpV6AdressStatus" : Enum.FEATURE__ANY_TYPE, + "HostIpConfigV6AdressConfigType" : Enum.FEATURE__ANY_TYPE, + "PortGroupConnecteeType" : Enum.FEATURE__ANY_TYPE } additional_object_features = { "AutoStartDefaults" : Object.FEATURE__ANY_TYPE, "AutoStartPowerInfo" : Object.FEATURE__ANY_TYPE, @@ -1519,8 +1526,31 @@ additional_object_features = { "AutoStartDefaults" : Object.FEATURE__AN Object.FEATURE__ANY_TYPE, "HostDatastoreBrowserSearchResults" : Object.FEATURE__LIST | Object.FEATURE__ANY_TYPE, + "HostIpConfig" : Object.FEATURE__DEEP_COPY, + "HostIpRouteConfig" : Object.FEATURE__ANY_TYPE, + "HostIpConfigIpV6Address" : Object.FEATURE__LIST | + Object.FEATURE__ANY_TYPE | + Object.FEATURE__DEEP_COPY, + "HostIpConfigIpV6AddressConfiguration" : Object.FEATURE__DEEP_COPY, + "HostPortGroup" : Object.FEATURE__LIST | + Object.FEATURE__ANY_TYPE, + "HostVirtualNic" : Object.FEATURE__ANY_TYPE | + Object.FEATURE__LIST, + "HostVirtualSwitch" : Object.FEATURE__ANY_TYPE | + Object.FEATURE__LIST, + "KeyValue" : Object.FEATURE__ANY_TYPE, "ManagedObjectReference" : Object.FEATURE__ANY_TYPE, + "PhysicalNic" : Object.FEATURE__LIST | + Object.FEATURE__ANY_TYPE | + Object.FEATURE__DEEP_COPY, "ObjectContent" : Object.FEATURE__DEEP_COPY, + "OptionValue" : Object.FEATURE__ANY_TYPE | + Object.FEATURE__LIST, + "PhysicalNic" : Object.FEATURE__LIST | + Object.FEATURE__ANY_TYPE | + Object.FEATURE__DEEP_COPY, + "PhysicalNicSpec" : Object.FEATURE__DEEP_COPY, + "PhysicalNicLinkInfo" : Object.FEATURE__LIST, "ResourcePoolResourceUsage" : Object.FEATURE__ANY_TYPE, "ServiceContent" : Object.FEATURE__DESERIALIZE, "SharesInfo" : Object.FEATURE__ANY_TYPE, diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c index bcc310f..f23af8d 100644 --- a/src/esx/esx_vi_types.c +++ b/src/esx/esx_vi_types.c @@ -475,7 +475,23 @@ continue; \ } - +#define ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_STRING_LIST(_type, _name) \ + if (xmlStrEqual(childNode->name, BAD_CAST #_name)) { \ + char *value = NULL; \ + \ + if (esxVI_String_DeserializeValue(childNode, &value) < 0 || \ + value == NULL) { \ + goto failure; \ + } \ + \ + if (esxVI_##_type##_AppendValueToList(&(*ptrptr)->_name, \ + value) < 0) { \ + VIR_FREE(value); \ + goto failure; \ + } \ + \ + continue; \ + } /* * A required property must be != 0 (NULL for pointers, "undefined" == 0 for