From: Ata E Husain <ata.husain(a)hotmail.com>
Includes most of the dirver routines except DefineXML, I am working on it and will update
patch for it soon.
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 <config.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <libxml/parser.h>
#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:
+ * <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;
+}
+
+
+
+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
--
1.7.9.5