mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
esx: Implement network driver
An ESX server has one or more PhysicalNics that represent the actual hardware NICs. Those can be listed via the interface driver. A libvirt virtual network is mapped to a HostVirtualSwitch. On the physical side a HostVirtualSwitch can be connected to PhysicalNics. On the virtual side a HostVirtualSwitch has HostPortGroups that are mapped to libvirt virtual network's portgroups. Typically there is HostPortGroups named 'VM Network' that is used to connect virtual machines to a HostVirtualSwitch. A second HostPortGroup typically named 'Management Network' is used to connect the hypervisor itself to the HostVirtualSwitch. This one is not mapped to a libvirt virtual network's portgroup. There can be more HostPortGroups than those typical two on a HostVirtualSwitch. +---------------+-------------------+ ...---| | | +-------------+ | HostPortGroup | |---| PhysicalNic | | VM Network | | | vmnic0 | ...---| | | +-------------+ +---------------+ HostVirtualSwitch | | vSwitch0 | +---------------+ | | HostPortGroup | | ...---| Management | | | Network | | +---------------+-------------------+ The virtual counterparts of the PhysicalNic is the HostVirtualNic for the hypervisor and the VirtualEthernetCard for the virtual machines that are grouped into HostPortGroups. +---------------------+ +---------------+---... | VirtualEthernetCard |---| | +---------------------+ | HostPortGroup | +---------------------+ | VM Network | | VirtualEthernetCard |---| | +---------------------+ +---------------+ | +---------------+ +---------------------+ | HostPortGroup | | HostVirtualNic |---| Management | +---------------------+ | Network | +---------------+---... The currently implemented network driver can list, define and undefine HostVirtualSwitches including HostPortGroups for virtual machines. Existing HostVirtualSwitches cannot be edited yet. This will be added in a followup patch.
This commit is contained in:
parent
ba86e5cd3f
commit
b8fa5fd071
@ -27,6 +27,7 @@ src/cpu/cpu_x86.c
|
||||
src/datatypes.c
|
||||
src/driver.c
|
||||
src/esx/esx_driver.c
|
||||
src/esx/esx_network_driver.c
|
||||
src/esx/esx_storage_driver.c
|
||||
src/esx/esx_util.c
|
||||
src/esx/esx_vi.c
|
||||
|
@ -47,8 +47,6 @@
|
||||
#define MAX_BRIDGE_ID 256
|
||||
#define VIR_FROM_THIS VIR_FROM_NETWORK
|
||||
|
||||
VIR_ENUM_DECL(virNetworkForward)
|
||||
|
||||
VIR_ENUM_IMPL(virNetworkForward,
|
||||
VIR_NETWORK_FORWARD_LAST,
|
||||
"none", "nat", "route", "bridge", "private", "vepa", "passthrough" )
|
||||
@ -967,6 +965,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
|
||||
goto error;
|
||||
}
|
||||
VIR_FREE(tmp);
|
||||
def->uuid_specified = true;
|
||||
}
|
||||
|
||||
/* Parse network domain information */
|
||||
|
@ -148,6 +148,7 @@ typedef struct _virNetworkDef virNetworkDef;
|
||||
typedef virNetworkDef *virNetworkDefPtr;
|
||||
struct _virNetworkDef {
|
||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||
bool uuid_specified;
|
||||
char *name;
|
||||
|
||||
char *bridge; /* Name of bridge device */
|
||||
@ -289,4 +290,6 @@ int virNetworkObjIsDuplicate(virNetworkObjListPtr doms,
|
||||
void virNetworkObjLock(virNetworkObjPtr obj);
|
||||
void virNetworkObjUnlock(virNetworkObjPtr obj);
|
||||
|
||||
VIR_ENUM_DECL(virNetworkForward)
|
||||
|
||||
#endif /* __NETWORK_CONF_H__ */
|
||||
|
@ -4,7 +4,7 @@
|
||||
* host networks
|
||||
*
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
* Copyright (C) 2010 Matthias Bolte <matthias.bolte@googlemail.com>
|
||||
* Copyright (C) 2010-2012 Matthias Bolte <matthias.bolte@googlemail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -24,11 +24,13 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "md5.h"
|
||||
#include "internal.h"
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "logging.h"
|
||||
#include "uuid.h"
|
||||
#include "network_conf.h"
|
||||
#include "esx_private.h"
|
||||
#include "esx_network_driver.h"
|
||||
#include "esx_vi.h"
|
||||
@ -37,6 +39,12 @@
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_ESX
|
||||
|
||||
/*
|
||||
* The UUID of a network is the MD5 sum of it's key. Therefore, verify that
|
||||
* UUID and MD5 sum match in size, because we rely on that.
|
||||
*/
|
||||
verify(MD5_DIGEST_SIZE == VIR_UUID_BUFLEN);
|
||||
|
||||
|
||||
|
||||
static virDrvOpenStatus
|
||||
@ -67,10 +75,867 @@ esxNetworkClose(virConnectPtr conn)
|
||||
|
||||
|
||||
|
||||
static int
|
||||
esxNumberOfNetworks(virConnectPtr conn)
|
||||
{
|
||||
esxPrivate *priv = conn->networkPrivateData;
|
||||
esxVI_HostVirtualSwitch *hostVirtualSwitchList = NULL;
|
||||
esxVI_HostVirtualSwitch *hostVirtualSwitch = NULL;
|
||||
int count = 0;
|
||||
|
||||
if (esxVI_EnsureSession(priv->primary) < 0 ||
|
||||
esxVI_LookupHostVirtualSwitchList(priv->primary,
|
||||
&hostVirtualSwitchList) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (hostVirtualSwitch = hostVirtualSwitchList; hostVirtualSwitch != NULL;
|
||||
hostVirtualSwitch = hostVirtualSwitch->_next) {
|
||||
++count;
|
||||
}
|
||||
|
||||
esxVI_HostVirtualSwitch_Free(&hostVirtualSwitchList);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
esxListNetworks(virConnectPtr conn, char **const names, int maxnames)
|
||||
{
|
||||
bool success = false;
|
||||
esxPrivate *priv = conn->networkPrivateData;
|
||||
esxVI_HostVirtualSwitch *hostVirtualSwitchList = NULL;
|
||||
esxVI_HostVirtualSwitch *hostVirtualSwitch = NULL;
|
||||
int count = 0;
|
||||
int i;
|
||||
|
||||
if (maxnames == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (esxVI_EnsureSession(priv->primary) < 0 ||
|
||||
esxVI_LookupHostVirtualSwitchList(priv->primary,
|
||||
&hostVirtualSwitchList) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (hostVirtualSwitch = hostVirtualSwitchList; hostVirtualSwitch != NULL;
|
||||
hostVirtualSwitch = hostVirtualSwitch->_next) {
|
||||
names[count] = strdup(hostVirtualSwitch->name);
|
||||
|
||||
if (names[count] == NULL) {
|
||||
virReportOOMError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
success = true;
|
||||
|
||||
cleanup:
|
||||
if (! success) {
|
||||
for (i = 0; i < count; ++i) {
|
||||
VIR_FREE(names[i]);
|
||||
}
|
||||
|
||||
count = -1;
|
||||
}
|
||||
|
||||
esxVI_HostVirtualSwitch_Free(&hostVirtualSwitchList);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
esxNumberOfDefinedNetworks(virConnectPtr conn ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* ESX networks are always active */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
esxListDefinedNetworks(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
char **const names ATTRIBUTE_UNUSED,
|
||||
int maxnames ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* ESX networks are always active */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static virNetworkPtr
|
||||
esxNetworkLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
|
||||
{
|
||||
virNetworkPtr network = NULL;
|
||||
esxPrivate *priv = conn->networkPrivateData;
|
||||
esxVI_HostVirtualSwitch *hostVirtualSwitchList = NULL;
|
||||
esxVI_HostVirtualSwitch *hostVirtualSwitch = NULL;
|
||||
unsigned char md5[MD5_DIGEST_SIZE]; /* MD5_DIGEST_SIZE = VIR_UUID_BUFLEN = 16 */
|
||||
char uuid_string[VIR_UUID_STRING_BUFLEN] = "";
|
||||
|
||||
if (esxVI_EnsureSession(priv->primary) < 0 ||
|
||||
esxVI_LookupHostVirtualSwitchList(priv->primary,
|
||||
&hostVirtualSwitchList) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (hostVirtualSwitch = hostVirtualSwitchList; hostVirtualSwitch != NULL;
|
||||
hostVirtualSwitch = hostVirtualSwitch->_next) {
|
||||
md5_buffer(hostVirtualSwitch->key, strlen(hostVirtualSwitch->key), md5);
|
||||
|
||||
if (memcmp(uuid, md5, VIR_UUID_BUFLEN) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hostVirtualSwitch == NULL) {
|
||||
virUUIDFormat(uuid, uuid_string);
|
||||
|
||||
virReportError(VIR_ERR_NO_NETWORK,
|
||||
_("Could not find HostVirtualSwitch with UUID '%s'"),
|
||||
uuid_string);
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
network = virGetNetwork(conn, hostVirtualSwitch->name, uuid);
|
||||
|
||||
cleanup:
|
||||
esxVI_HostVirtualSwitch_Free(&hostVirtualSwitchList);
|
||||
|
||||
return network;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static virNetworkPtr
|
||||
esxNetworkLookupByName(virConnectPtr conn, const char *name)
|
||||
{
|
||||
virNetworkPtr network = NULL;
|
||||
esxPrivate *priv = conn->networkPrivateData;
|
||||
esxVI_HostVirtualSwitch *hostVirtualSwitch = NULL;
|
||||
unsigned char md5[MD5_DIGEST_SIZE]; /* MD5_DIGEST_SIZE = VIR_UUID_BUFLEN = 16 */
|
||||
|
||||
if (esxVI_EnsureSession(priv->primary) < 0 ||
|
||||
esxVI_LookupHostVirtualSwitchByName(priv->primary, name,
|
||||
&hostVirtualSwitch,
|
||||
esxVI_Occurrence_RequiredItem) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* HostVirtualSwitch doesn't have a UUID, but we can use the key property
|
||||
* as source for a UUID. The key is unique per host and cannot change
|
||||
* during the lifetime of the HostVirtualSwitch.
|
||||
*
|
||||
* The MD5 sum of the key can be used as UUID, assuming MD5 is considered
|
||||
* to be collision-free enough for this use case.
|
||||
*/
|
||||
md5_buffer(hostVirtualSwitch->key, strlen(hostVirtualSwitch->key), md5);
|
||||
|
||||
network = virGetNetwork(conn, hostVirtualSwitch->name, md5);
|
||||
|
||||
esxVI_HostVirtualSwitch_Free(&hostVirtualSwitch);
|
||||
|
||||
return network;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
esxBandwidthToShapingPolicy(virNetDevBandwidthPtr bandwidth,
|
||||
esxVI_HostNetworkTrafficShapingPolicy **shapingPolicy)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (shapingPolicy == NULL || *shapingPolicy != NULL) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bandwidth->in == NULL || bandwidth->out == NULL ||
|
||||
bandwidth->in->average != bandwidth->out->average ||
|
||||
bandwidth->in->peak != bandwidth->out->peak ||
|
||||
bandwidth->in->burst != bandwidth->out->burst) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("Different inbound and outbound bandwidth is unsupported"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bandwidth->in->average == 0 && bandwidth->in->peak == 0 &&
|
||||
bandwidth->in->burst == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (esxVI_HostNetworkTrafficShapingPolicy_Alloc(shapingPolicy) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
(*shapingPolicy)->enabled = esxVI_Boolean_True;
|
||||
|
||||
if (bandwidth->in->average > 0) {
|
||||
if (esxVI_Long_Alloc(&(*shapingPolicy)->averageBandwidth) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Scale kilobytes per second to bits per second */
|
||||
(*shapingPolicy)->averageBandwidth->value = bandwidth->in->average * 8 * 1000;
|
||||
}
|
||||
|
||||
if (bandwidth->in->peak > 0) {
|
||||
if (esxVI_Long_Alloc(&(*shapingPolicy)->peakBandwidth) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Scale kilobytes per second to bits per second */
|
||||
(*shapingPolicy)->peakBandwidth->value = bandwidth->in->peak * 8 * 1000;
|
||||
}
|
||||
|
||||
if (bandwidth->in->burst > 0) {
|
||||
if (esxVI_Long_Alloc(&(*shapingPolicy)->burstSize) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Scale kilobytes to bytes */
|
||||
(*shapingPolicy)->burstSize->value = bandwidth->in->burst * 1024;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
|
||||
cleanup:
|
||||
if (result < 0) {
|
||||
esxVI_HostNetworkTrafficShapingPolicy_Free(shapingPolicy);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static virNetworkPtr
|
||||
esxNetworkDefineXML(virConnectPtr conn, const char *xml)
|
||||
{
|
||||
virNetworkPtr network = NULL;
|
||||
esxPrivate *priv = conn->networkPrivateData;
|
||||
virNetworkDefPtr def = NULL;
|
||||
esxVI_HostVirtualSwitch *hostVirtualSwitch = NULL;
|
||||
esxVI_HostPortGroup *hostPortGroupList = NULL;
|
||||
esxVI_HostPortGroup *hostPortGroup = NULL;
|
||||
esxVI_HostVirtualSwitchSpec *hostVirtualSwitchSpec = NULL;
|
||||
esxVI_HostVirtualSwitchBondBridge *hostVirtualSwitchBondBridge = NULL;
|
||||
esxVI_PhysicalNic *physicalNicList = NULL;
|
||||
esxVI_PhysicalNic *physicalNic = NULL;
|
||||
esxVI_HostPortGroupSpec *hostPortGroupSpec = NULL;
|
||||
int i;
|
||||
|
||||
unsigned char md5[MD5_DIGEST_SIZE]; /* MD5_DIGEST_SIZE = VIR_UUID_BUFLEN = 16 */
|
||||
|
||||
if (esxVI_EnsureSession(priv->primary) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Parse network XML */
|
||||
def = virNetworkDefParseString(xml);
|
||||
|
||||
if (def == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if an existing HostVirtualSwitch should be edited */
|
||||
if (esxVI_LookupHostVirtualSwitchByName(priv->primary, def->name,
|
||||
&hostVirtualSwitch,
|
||||
esxVI_Occurrence_OptionalItem) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (hostVirtualSwitch != NULL) {
|
||||
/* FIXME */
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("HostVirtualSwitch already exists, editing existing "
|
||||
"ones is not supported yet"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* UUID is derived from the HostVirtualSwitch's key and cannot be specified */
|
||||
if (def->uuid_specified) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("Cannot use predefined UUID"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* FIXME: Add support for NAT */
|
||||
if (def->forwardType != VIR_NETWORK_FORWARD_NONE &&
|
||||
def->forwardType != VIR_NETWORK_FORWARD_BRIDGE) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("Unsupported forward mode '%s'"),
|
||||
virNetworkForwardTypeToString(def->forwardType));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Verify that specified HostPortGroups don't exist already */
|
||||
if (def->nPortGroups > 0) {
|
||||
if (esxVI_LookupHostPortGroupList(priv->primary, &hostPortGroupList) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < def->nPortGroups; ++i) {
|
||||
for (hostPortGroup = hostPortGroupList; hostPortGroup != NULL;
|
||||
hostPortGroup = hostPortGroup->_next) {
|
||||
if (STREQ(def->portGroups[i].name, hostPortGroup->spec->name)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("HostPortGroup with name '%s' exists already"),
|
||||
def->portGroups[i].name);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create HostVirtualSwitch */
|
||||
if (esxVI_HostVirtualSwitchSpec_Alloc(&hostVirtualSwitchSpec) < 0 ||
|
||||
esxVI_Int_Alloc(&hostVirtualSwitchSpec->numPorts) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (def->forwardType != VIR_NETWORK_FORWARD_NONE && def->nForwardIfs > 0) {
|
||||
if (esxVI_HostVirtualSwitchBondBridge_Alloc
|
||||
(&hostVirtualSwitchBondBridge) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hostVirtualSwitchSpec->bridge =
|
||||
(esxVI_HostVirtualSwitchBridge *)hostVirtualSwitchBondBridge;
|
||||
|
||||
/* Lookup PhysicalNic list and match by name to get key */
|
||||
if (esxVI_LookupPhysicalNicList(priv->primary, &physicalNicList) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < def->nForwardIfs; ++i) {
|
||||
bool found = false;
|
||||
|
||||
for (physicalNic = physicalNicList; physicalNic != NULL;
|
||||
physicalNic = physicalNic->_next) {
|
||||
if (STREQ(def->forwardIfs[i].dev, physicalNic->device)) {
|
||||
if (esxVI_String_AppendValueToList
|
||||
(&hostVirtualSwitchBondBridge->nicDevice,
|
||||
physicalNic->key) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Could not find PhysicalNic with name '%s'"),
|
||||
def->forwardIfs[i].dev);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hostVirtualSwitchSpec->numPorts->value = 128;
|
||||
|
||||
if (def->bandwidth != NULL) {
|
||||
if (esxVI_HostNetworkPolicy_Alloc(&hostVirtualSwitchSpec->policy) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (esxBandwidthToShapingPolicy
|
||||
(def->bandwidth,
|
||||
&hostVirtualSwitchSpec->policy->shapingPolicy) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (esxVI_AddVirtualSwitch
|
||||
(priv->primary,
|
||||
priv->primary->hostSystem->configManager->networkSystem,
|
||||
def->name, hostVirtualSwitchSpec) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Create HostPortGroup(s) */
|
||||
for (i = 0; i < def->nPortGroups; ++i) {
|
||||
esxVI_HostPortGroupSpec_Free(&hostPortGroupSpec);
|
||||
|
||||
if (esxVI_HostPortGroupSpec_Alloc(&hostPortGroupSpec) < 0 ||
|
||||
esxVI_HostNetworkPolicy_Alloc(&hostPortGroupSpec->policy) < 0 ||
|
||||
esxVI_Int_Alloc(&hostPortGroupSpec->vlanId) < 0 ||
|
||||
esxVI_String_DeepCopyValue(&hostPortGroupSpec->name,
|
||||
def->portGroups[i].name) < 0 ||
|
||||
esxVI_String_DeepCopyValue(&hostPortGroupSpec->vswitchName,
|
||||
def->name) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hostPortGroupSpec->vlanId->value = 0;
|
||||
|
||||
if (def->portGroups[i].bandwidth != NULL) {
|
||||
if (esxBandwidthToShapingPolicy
|
||||
(def->portGroups[i].bandwidth,
|
||||
&hostPortGroupSpec->policy->shapingPolicy) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (esxVI_AddPortGroup
|
||||
(priv->primary,
|
||||
priv->primary->hostSystem->configManager->networkSystem,
|
||||
hostPortGroupSpec) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lookup created HostVirtualSwitch to get the UUID */
|
||||
if (esxVI_LookupHostVirtualSwitchByName(priv->primary, def->name,
|
||||
&hostVirtualSwitch,
|
||||
esxVI_Occurrence_RequiredItem) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
md5_buffer(hostVirtualSwitch->key, strlen(hostVirtualSwitch->key), md5);
|
||||
|
||||
network = virGetNetwork(conn, hostVirtualSwitch->name, md5);
|
||||
|
||||
cleanup:
|
||||
virNetworkDefFree(def);
|
||||
esxVI_HostVirtualSwitch_Free(&hostVirtualSwitch);
|
||||
esxVI_HostPortGroup_Free(&hostPortGroupList);
|
||||
esxVI_HostVirtualSwitchSpec_Free(&hostVirtualSwitchSpec);
|
||||
esxVI_PhysicalNic_Free(&physicalNicList);
|
||||
esxVI_HostPortGroupSpec_Free(&hostPortGroupSpec);
|
||||
|
||||
return network;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
esxNetworkUndefine(virNetworkPtr network)
|
||||
{
|
||||
int result = -1;
|
||||
esxPrivate *priv = network->conn->networkPrivateData;
|
||||
esxVI_HostVirtualSwitch *hostVirtualSwitch = NULL;
|
||||
esxVI_HostPortGroup *hostPortGroupList = NULL;
|
||||
esxVI_String *hostPortGroupKey = NULL;
|
||||
esxVI_HostPortGroup *hostPortGroup = NULL;
|
||||
esxVI_HostPortGroupPort *hostPortGroupPort = NULL;
|
||||
|
||||
if (esxVI_EnsureSession(priv->primary) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Lookup HostVirtualSwitch and HostPortGroup list*/
|
||||
if (esxVI_LookupHostVirtualSwitchByName(priv->primary, network->name,
|
||||
&hostVirtualSwitch,
|
||||
esxVI_Occurrence_RequiredItem) < 0 ||
|
||||
esxVI_LookupHostPortGroupList(priv->primary, &hostPortGroupList) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Verify that the HostVirtualSwitch is connected to virtual machines only */
|
||||
for (hostPortGroupKey = hostVirtualSwitch->portgroup;
|
||||
hostPortGroupKey != NULL; hostPortGroupKey = hostPortGroupKey->_next) {
|
||||
bool found = false;
|
||||
|
||||
for (hostPortGroup = hostPortGroupList; hostPortGroup != NULL;
|
||||
hostPortGroup = hostPortGroup->_next) {
|
||||
if (STREQ(hostPortGroupKey->value, hostPortGroup->key)) {
|
||||
for (hostPortGroupPort = hostPortGroup->port;
|
||||
hostPortGroupPort != NULL;
|
||||
hostPortGroupPort = hostPortGroupPort->_next) {
|
||||
if (STRNEQ(hostPortGroupPort->type, "virtualMachine")) {
|
||||
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||
_("Cannot undefine HostVirtualSwitch that has a '%s' port"),
|
||||
hostPortGroupPort->type);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Could not find HostPortGroup for key '%s'"),
|
||||
hostPortGroupKey->value);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove all HostPortGroups from the HostVirtualSwitch */
|
||||
for (hostPortGroupKey = hostVirtualSwitch->portgroup;
|
||||
hostPortGroupKey != NULL; hostPortGroupKey = hostPortGroupKey->_next) {
|
||||
bool found = false;
|
||||
|
||||
for (hostPortGroup = hostPortGroupList; hostPortGroup != NULL;
|
||||
hostPortGroup = hostPortGroup->_next) {
|
||||
if (STREQ(hostPortGroupKey->value, hostPortGroup->key)) {
|
||||
if (esxVI_RemovePortGroup
|
||||
(priv->primary,
|
||||
priv->primary->hostSystem->configManager->networkSystem,
|
||||
hostPortGroup->spec->name) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Could not find HostPortGroup for key '%s'"),
|
||||
hostPortGroupKey->value);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, remove HostVirtualSwitch itself */
|
||||
if (esxVI_RemoveVirtualSwitch
|
||||
(priv->primary,
|
||||
priv->primary->hostSystem->configManager->networkSystem,
|
||||
network->name) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
|
||||
cleanup:
|
||||
esxVI_HostVirtualSwitch_Free(&hostVirtualSwitch);
|
||||
esxVI_HostPortGroup_Free(&hostPortGroupList);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
esxShapingPolicyToBandwidth(esxVI_HostNetworkTrafficShapingPolicy *shapingPolicy,
|
||||
virNetDevBandwidthPtr *bandwidth)
|
||||
{
|
||||
if (bandwidth == NULL || *bandwidth != NULL) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (shapingPolicy == NULL || shapingPolicy->enabled != esxVI_Boolean_True) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (VIR_ALLOC(*bandwidth) < 0 ||
|
||||
VIR_ALLOC((*bandwidth)->in) < 0 ||
|
||||
VIR_ALLOC((*bandwidth)->out) < 0) {
|
||||
virReportOOMError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (shapingPolicy->averageBandwidth != NULL) {
|
||||
/* Scale bits per second to kilobytes per second */
|
||||
(*bandwidth)->in->average = shapingPolicy->averageBandwidth->value / 8 / 1000;
|
||||
(*bandwidth)->out->average = shapingPolicy->averageBandwidth->value / 8 / 1000;
|
||||
}
|
||||
|
||||
if (shapingPolicy->peakBandwidth != NULL) {
|
||||
/* Scale bits per second to kilobytes per second */
|
||||
(*bandwidth)->in->peak = shapingPolicy->peakBandwidth->value / 8 / 1000;
|
||||
(*bandwidth)->out->peak = shapingPolicy->peakBandwidth->value / 8 / 1000;
|
||||
}
|
||||
|
||||
if (shapingPolicy->burstSize != NULL) {
|
||||
/* Scale bytes to kilobytes */
|
||||
(*bandwidth)->in->burst = shapingPolicy->burstSize->value / 1024;
|
||||
(*bandwidth)->out->burst = shapingPolicy->burstSize->value / 1024;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char *
|
||||
esxNetworkGetXMLDesc(virNetworkPtr network_, unsigned int flags)
|
||||
{
|
||||
char *xml = NULL;
|
||||
esxPrivate *priv = network_->conn->networkPrivateData;
|
||||
esxVI_HostVirtualSwitch *hostVirtualSwitch = NULL;
|
||||
int count = 0;
|
||||
esxVI_PhysicalNic *physicalNicList = NULL;
|
||||
esxVI_PhysicalNic *physicalNic = NULL;
|
||||
esxVI_String *physicalNicKey = NULL;
|
||||
esxVI_HostPortGroup *hostPortGroupList = NULL;
|
||||
esxVI_HostPortGroup *hostPortGroup = NULL;
|
||||
esxVI_String *propertyNameList = NULL;
|
||||
esxVI_ObjectContent *networkList = NULL;
|
||||
esxVI_ObjectContent *network = NULL;
|
||||
esxVI_String *networkNameList = NULL;
|
||||
esxVI_String *hostPortGroupKey = NULL;
|
||||
esxVI_String *networkName = NULL;
|
||||
virNetworkDefPtr def;
|
||||
|
||||
if (esxVI_EnsureSession(priv->primary) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (VIR_ALLOC(def) < 0) {
|
||||
virReportOOMError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Lookup HostVirtualSwitch */
|
||||
if (esxVI_LookupHostVirtualSwitchByName(priv->primary, network_->name,
|
||||
&hostVirtualSwitch,
|
||||
esxVI_Occurrence_RequiredItem) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
md5_buffer(hostVirtualSwitch->key, strlen(hostVirtualSwitch->key), def->uuid);
|
||||
|
||||
def->name = strdup(hostVirtualSwitch->name);
|
||||
|
||||
if (def->name == NULL) {
|
||||
virReportOOMError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
def->forwardType = VIR_NETWORK_FORWARD_NONE;
|
||||
|
||||
/* Count PhysicalNics on HostVirtualSwitch */
|
||||
count = 0;
|
||||
|
||||
for (physicalNicKey = hostVirtualSwitch->pnic;
|
||||
physicalNicKey != NULL; physicalNicKey = physicalNicKey->_next) {
|
||||
++count;
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
def->forwardType = VIR_NETWORK_FORWARD_BRIDGE;
|
||||
|
||||
if (VIR_ALLOC_N(def->forwardIfs, count) < 0) {
|
||||
virReportOOMError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Find PhysicalNic by key */
|
||||
if (esxVI_LookupPhysicalNicList(priv->primary, &physicalNicList) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (physicalNicKey = hostVirtualSwitch->pnic;
|
||||
physicalNicKey != NULL; physicalNicKey = physicalNicKey->_next) {
|
||||
bool found = false;
|
||||
|
||||
for (physicalNic = physicalNicList; physicalNic != NULL;
|
||||
physicalNic = physicalNic->_next) {
|
||||
if (STREQ(physicalNicKey->value, physicalNic->key)) {
|
||||
def->forwardIfs[def->nForwardIfs].dev = strdup(physicalNic->device);
|
||||
|
||||
if (def->forwardIfs[def->nForwardIfs].dev == NULL) {
|
||||
virReportOOMError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
++def->nForwardIfs;
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Could not find PhysicalNic with key '%s'"),
|
||||
physicalNicKey->value);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Count HostPortGroups on HostVirtualSwitch */
|
||||
count = 0;
|
||||
|
||||
for (hostPortGroupKey = hostVirtualSwitch->portgroup;
|
||||
hostPortGroupKey != NULL; hostPortGroupKey = hostPortGroupKey->_next) {
|
||||
++count;
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
if (VIR_ALLOC_N(def->portGroups, count) < 0) {
|
||||
virReportOOMError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Lookup Network list and create name list */
|
||||
if (esxVI_String_AppendValueToList(&propertyNameList, "name") < 0 ||
|
||||
esxVI_LookupNetworkList(priv->primary, propertyNameList,
|
||||
&networkList) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (network = networkList; network != NULL; network = network->_next) {
|
||||
char *tmp = NULL;
|
||||
|
||||
if (esxVI_GetStringValue(network, "name", &tmp,
|
||||
esxVI_Occurrence_RequiredItem) < 0 ||
|
||||
esxVI_String_AppendValueToList(&networkNameList, tmp) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find HostPortGroup by key */
|
||||
if (esxVI_LookupHostPortGroupList(priv->primary, &hostPortGroupList) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (hostPortGroupKey = hostVirtualSwitch->portgroup;
|
||||
hostPortGroupKey != NULL; hostPortGroupKey = hostPortGroupKey->_next) {
|
||||
bool found = false;
|
||||
|
||||
for (hostPortGroup = hostPortGroupList; hostPortGroup != NULL;
|
||||
hostPortGroup = hostPortGroup->_next) {
|
||||
if (STREQ(hostPortGroupKey->value, hostPortGroup->key)) {
|
||||
/* Find Network for HostPortGroup, there might be none */
|
||||
for (networkName = networkNameList; networkName != NULL;
|
||||
networkName = networkName->_next) {
|
||||
if (STREQ(networkName->value, hostPortGroup->spec->name)) {
|
||||
def->portGroups[def->nPortGroups].name = strdup(networkName->value);
|
||||
|
||||
if (def->portGroups[def->nPortGroups].name == NULL) {
|
||||
virReportOOMError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (hostPortGroup->spec->policy != NULL) {
|
||||
if (esxShapingPolicyToBandwidth
|
||||
(hostPortGroup->spec->policy->shapingPolicy,
|
||||
&def->portGroups[def->nPortGroups].bandwidth) < 0) {
|
||||
++def->nPortGroups;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
++def->nPortGroups;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Could not find HostPortGroup with key '%s'"),
|
||||
hostPortGroupKey->value);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hostVirtualSwitch->spec->policy != NULL) {
|
||||
if (esxShapingPolicyToBandwidth
|
||||
(hostVirtualSwitch->spec->policy->shapingPolicy,
|
||||
&def->bandwidth) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
xml = virNetworkDefFormat(def, flags);
|
||||
|
||||
cleanup:
|
||||
esxVI_HostVirtualSwitch_Free(&hostVirtualSwitch);
|
||||
esxVI_PhysicalNic_Free(&physicalNicList);
|
||||
esxVI_HostPortGroup_Free(&hostPortGroupList);
|
||||
esxVI_String_Free(&propertyNameList);
|
||||
esxVI_ObjectContent_Free(&networkList);
|
||||
esxVI_String_Free(&networkNameList);
|
||||
virNetworkDefFree(def);
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
esxNetworkGetAutostart(virNetworkPtr network ATTRIBUTE_UNUSED,
|
||||
int *autostart)
|
||||
{
|
||||
/* ESX networks are always active */
|
||||
*autostart = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
esxNetworkSetAutostart(virNetworkPtr network ATTRIBUTE_UNUSED,
|
||||
int autostart)
|
||||
{
|
||||
/* Just accept autostart activation, but fail on autostart deactivation */
|
||||
autostart = (autostart != 0);
|
||||
|
||||
if (! autostart) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Cannot deactivate network autostart"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
esxNetworkIsActive(virNetworkPtr network ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* ESX networks are always active */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
esxNetworkIsPersistent(virNetworkPtr network ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* ESX has no concept of transient networks, so all of them are persistent */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static virNetworkDriver esxNetworkDriver = {
|
||||
.name = "ESX",
|
||||
.open = esxNetworkOpen, /* 0.7.6 */
|
||||
.close = esxNetworkClose, /* 0.7.6 */
|
||||
.numOfNetworks = esxNumberOfNetworks, /* 0.10.0 */
|
||||
.listNetworks = esxListNetworks, /* 0.10.0 */
|
||||
.numOfDefinedNetworks = esxNumberOfDefinedNetworks, /* 0.10.0 */
|
||||
.listDefinedNetworks = esxListDefinedNetworks, /* 0.10.0 */
|
||||
.networkLookupByUUID = esxNetworkLookupByUUID, /* 0.10.0 */
|
||||
.networkLookupByName = esxNetworkLookupByName, /* 0.10.0 */
|
||||
.networkDefineXML = esxNetworkDefineXML, /* 0.10.0 */
|
||||
.networkUndefine = esxNetworkUndefine, /* 0.10.0 */
|
||||
.networkGetXMLDesc = esxNetworkGetXMLDesc, /* 0.10.0 */
|
||||
.networkGetAutostart = esxNetworkGetAutostart, /* 0.10.0 */
|
||||
.networkSetAutostart = esxNetworkSetAutostart, /* 0.10.0 */
|
||||
.networkIsActive = esxNetworkIsActive, /* 0.10.0 */
|
||||
.networkIsPersistent = esxNetworkIsPersistent, /* 0.10.0 */
|
||||
};
|
||||
|
||||
|
||||
|
171
src/esx/esx_vi.c
171
src/esx/esx_vi.c
@ -783,6 +783,7 @@ ESX_VI__TEMPLATE__FREE(Context,
|
||||
esxVI_SelectionSpec_Free(&item->selectSet_hostSystemToDatastore);
|
||||
esxVI_SelectionSpec_Free(&item->selectSet_computeResourceToHost);
|
||||
esxVI_SelectionSpec_Free(&item->selectSet_computeResourceToParentToParent);
|
||||
esxVI_SelectionSpec_Free(&item->selectSet_datacenterToNetwork);
|
||||
})
|
||||
|
||||
int
|
||||
@ -1927,6 +1928,13 @@ esxVI_BuildSelectSetCollection(esxVI_Context *ctx)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Datacenter -> network (Network) */
|
||||
if (esxVI_BuildSelectSet(&ctx->selectSet_datacenterToNetwork,
|
||||
"datacenterToNetwork",
|
||||
"Datacenter", "network", NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2094,6 +2102,15 @@ esxVI_LookupObjectContentByType(esxVI_Context *ctx,
|
||||
type, root->type);
|
||||
goto cleanup;
|
||||
}
|
||||
} else if (STREQ(root->type, "Datacenter")) {
|
||||
if (STREQ(type, "Network")) {
|
||||
objectSpec->selectSet = ctx->selectSet_datacenterToNetwork;
|
||||
} else {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Invalid lookup of '%s' from '%s'"),
|
||||
type, root->type);
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Invalid lookup from '%s'"), root->type);
|
||||
@ -4090,6 +4107,160 @@ esxVI_LookupPhysicalNicByMACAddress(esxVI_Context *ctx, const char *mac,
|
||||
|
||||
|
||||
|
||||
int
|
||||
esxVI_LookupHostVirtualSwitchList(esxVI_Context *ctx,
|
||||
esxVI_HostVirtualSwitch **hostVirtualSwitchList)
|
||||
{
|
||||
int result = -1;
|
||||
esxVI_String *propertyNameList = NULL;
|
||||
esxVI_ObjectContent *hostSystem = NULL;
|
||||
esxVI_DynamicProperty *dynamicProperty = NULL;
|
||||
|
||||
if (hostVirtualSwitchList == NULL || *hostVirtualSwitchList != NULL) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (esxVI_String_AppendValueToList(&propertyNameList,
|
||||
"config.network.vswitch") < 0 ||
|
||||
esxVI_LookupHostSystemProperties(ctx, propertyNameList,
|
||||
&hostSystem) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL;
|
||||
dynamicProperty = dynamicProperty->_next) {
|
||||
if (STREQ(dynamicProperty->name, "config.network.vswitch")) {
|
||||
if (esxVI_HostVirtualSwitch_CastListFromAnyType
|
||||
(dynamicProperty->val, hostVirtualSwitchList) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
|
||||
}
|
||||
}
|
||||
|
||||
result = 0;
|
||||
|
||||
cleanup:
|
||||
esxVI_String_Free(&propertyNameList);
|
||||
esxVI_ObjectContent_Free(&hostSystem);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
esxVI_LookupHostVirtualSwitchByName(esxVI_Context *ctx, const char *name,
|
||||
esxVI_HostVirtualSwitch **hostVirtualSwitch,
|
||||
esxVI_Occurrence occurrence)
|
||||
{
|
||||
int result = -1;
|
||||
esxVI_HostVirtualSwitch *hostVirtualSwitchList = NULL;
|
||||
esxVI_HostVirtualSwitch *candidate = NULL;
|
||||
|
||||
if (hostVirtualSwitch == NULL || *hostVirtualSwitch != NULL) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (esxVI_LookupHostVirtualSwitchList(ctx, &hostVirtualSwitchList) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Search for a matching HostVirtualSwitch */
|
||||
for (candidate = hostVirtualSwitchList; candidate != NULL;
|
||||
candidate = candidate->_next) {
|
||||
if (STREQ(candidate->name, name)) {
|
||||
if (esxVI_HostVirtualSwitch_DeepCopy(hostVirtualSwitch,
|
||||
candidate) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Found HostVirtualSwitch with matching name */
|
||||
result = 0;
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (*hostVirtualSwitch == NULL &&
|
||||
occurrence != esxVI_Occurrence_OptionalItem) {
|
||||
virReportError(VIR_ERR_NO_NETWORK,
|
||||
_("Could not find HostVirtualSwitch with name '%s'"),
|
||||
name);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
|
||||
cleanup:
|
||||
esxVI_HostVirtualSwitch_Free(&hostVirtualSwitchList);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
esxVI_LookupHostPortGroupList(esxVI_Context *ctx,
|
||||
esxVI_HostPortGroup **hostPortGroupList)
|
||||
{
|
||||
int result = -1;
|
||||
esxVI_String *propertyNameList = NULL;
|
||||
esxVI_ObjectContent *hostSystem = NULL;
|
||||
esxVI_DynamicProperty *dynamicProperty = NULL;
|
||||
|
||||
if (hostPortGroupList == NULL || *hostPortGroupList != NULL) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (esxVI_String_AppendValueToList(&propertyNameList,
|
||||
"config.network.portgroup") < 0 ||
|
||||
esxVI_LookupHostSystemProperties(ctx, propertyNameList,
|
||||
&hostSystem) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL;
|
||||
dynamicProperty = dynamicProperty->_next) {
|
||||
if (STREQ(dynamicProperty->name, "config.network.portgroup")) {
|
||||
if (esxVI_HostPortGroup_CastListFromAnyType
|
||||
(dynamicProperty->val, hostPortGroupList) < 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_LookupNetworkList(esxVI_Context *ctx, esxVI_String *propertyNameList,
|
||||
esxVI_ObjectContent **networkList)
|
||||
{
|
||||
return esxVI_LookupObjectContentByType(ctx, ctx->datacenter->_reference,
|
||||
"Network", propertyNameList,
|
||||
networkList,
|
||||
esxVI_Occurrence_OptionalList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
esxVI_HandleVirtualMachineQuestion
|
||||
(esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachine,
|
||||
|
@ -227,6 +227,7 @@ struct _esxVI_Context {
|
||||
esxVI_SelectionSpec *selectSet_hostSystemToDatastore;
|
||||
esxVI_SelectionSpec *selectSet_computeResourceToHost;
|
||||
esxVI_SelectionSpec *selectSet_computeResourceToParentToParent;
|
||||
esxVI_SelectionSpec *selectSet_datacenterToNetwork;
|
||||
bool hasQueryVirtualDiskUuid;
|
||||
bool hasSessionIsActive;
|
||||
};
|
||||
@ -492,6 +493,19 @@ int esxVI_LookupPhysicalNicByMACAddress(esxVI_Context *ctx, const char *mac,
|
||||
esxVI_PhysicalNic **physicalNic,
|
||||
esxVI_Occurrence occurrence);
|
||||
|
||||
int esxVI_LookupHostVirtualSwitchList
|
||||
(esxVI_Context *ctx, esxVI_HostVirtualSwitch **hostVirtualSwitchList);
|
||||
|
||||
int esxVI_LookupHostVirtualSwitchByName(esxVI_Context *ctx, const char *name,
|
||||
esxVI_HostVirtualSwitch **hostVirtualSwitch,
|
||||
esxVI_Occurrence occurrence);
|
||||
|
||||
int esxVI_LookupHostPortGroupList(esxVI_Context *ctx,
|
||||
esxVI_HostPortGroup **hostPortGroupList);
|
||||
|
||||
int esxVI_LookupNetworkList(esxVI_Context *ctx, esxVI_String *propertyNameList,
|
||||
esxVI_ObjectContent **networkList);
|
||||
|
||||
int esxVI_HandleVirtualMachineQuestion
|
||||
(esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachine,
|
||||
esxVI_VirtualMachineQuestionInfo *questionInfo, bool autoAnswer,
|
||||
|
@ -338,12 +338,138 @@ object HostNasVolume extends HostFileSystemVolume
|
||||
end
|
||||
|
||||
|
||||
object HostNetOffloadCapabilities
|
||||
Boolean csumOffload o
|
||||
Boolean tcpSegmentation o
|
||||
Boolean zeroCopyXmit o
|
||||
end
|
||||
|
||||
|
||||
object HostNetworkPolicy
|
||||
HostNetworkSecurityPolicy security o
|
||||
HostNicTeamingPolicy nicTeaming o
|
||||
HostNetOffloadCapabilities offloadPolicy o
|
||||
HostNetworkTrafficShapingPolicy shapingPolicy o
|
||||
end
|
||||
|
||||
|
||||
object HostNetworkSecurityPolicy
|
||||
Boolean allowPromiscuous o
|
||||
Boolean macChanges o
|
||||
Boolean forgedTransmits o
|
||||
end
|
||||
|
||||
|
||||
object HostNetworkTrafficShapingPolicy
|
||||
Boolean enabled o
|
||||
Long averageBandwidth o
|
||||
Long peakBandwidth o
|
||||
Long burstSize 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 HostNicTeamingPolicy
|
||||
String policy o
|
||||
Boolean reversePolicy o
|
||||
Boolean notifySwitches o
|
||||
Boolean rollingOrder o
|
||||
HostNicFailureCriteria failureCriteria o
|
||||
HostNicOrderPolicy nicOrder o
|
||||
end
|
||||
|
||||
|
||||
object HostPortGroup
|
||||
String key o
|
||||
HostPortGroupPort port ol
|
||||
String vswitch o
|
||||
HostNetworkPolicy computedPolicy r
|
||||
HostPortGroupSpec spec r
|
||||
end
|
||||
|
||||
|
||||
object HostPortGroupPort
|
||||
String key o
|
||||
String mac ol
|
||||
String type r
|
||||
end
|
||||
|
||||
|
||||
object HostPortGroupSpec
|
||||
String name r
|
||||
Int vlanId r
|
||||
String vswitchName r
|
||||
HostNetworkPolicy policy r
|
||||
end
|
||||
|
||||
|
||||
object HostScsiDiskPartition
|
||||
String diskName r
|
||||
Int partition r
|
||||
end
|
||||
|
||||
|
||||
object HostVirtualSwitch
|
||||
String name r
|
||||
String key r
|
||||
Int numPorts r
|
||||
Int numPortsAvailable r
|
||||
Int mtu o
|
||||
String portgroup ol
|
||||
String pnic ol
|
||||
HostVirtualSwitchSpec spec r
|
||||
end
|
||||
|
||||
|
||||
object HostVirtualSwitchAutoBridge extends HostVirtualSwitchBridge
|
||||
String excludedNicDevice ol
|
||||
end
|
||||
|
||||
|
||||
object HostVirtualSwitchBeaconConfig
|
||||
Int interval r
|
||||
end
|
||||
|
||||
|
||||
object HostVirtualSwitchBondBridge extends HostVirtualSwitchBridge
|
||||
String nicDevice rl
|
||||
HostVirtualSwitchBeaconConfig beacon o
|
||||
end
|
||||
|
||||
|
||||
object HostVirtualSwitchBridge
|
||||
end
|
||||
|
||||
|
||||
object HostVirtualSwitchSimpleBridge extends HostVirtualSwitchBridge
|
||||
String nicDevice r
|
||||
end
|
||||
|
||||
|
||||
object HostVirtualSwitchSpec
|
||||
Int numPorts r
|
||||
HostVirtualSwitchBridge bridge o
|
||||
HostNetworkPolicy policy o
|
||||
Int mtu o
|
||||
end
|
||||
|
||||
|
||||
object HostVmfsVolume extends HostFileSystemVolume
|
||||
Int blockSizeMb r
|
||||
Int maxBlocks r
|
||||
@ -805,6 +931,19 @@ end
|
||||
# Methods
|
||||
#
|
||||
|
||||
method AddPortGroup
|
||||
ManagedObjectReference _this r
|
||||
HostPortGroupSpec portgrp r
|
||||
end
|
||||
|
||||
|
||||
method AddVirtualSwitch
|
||||
ManagedObjectReference _this r
|
||||
String vswitchName r
|
||||
HostVirtualSwitchSpec spec o
|
||||
end
|
||||
|
||||
|
||||
method AnswerVM
|
||||
ManagedObjectReference _this r
|
||||
String questionId r
|
||||
@ -981,12 +1120,24 @@ method RegisterVM_Task returns ManagedObjectReference r
|
||||
end
|
||||
|
||||
|
||||
method RemovePortGroup
|
||||
ManagedObjectReference _this r
|
||||
String pgName r
|
||||
end
|
||||
|
||||
|
||||
method RemoveSnapshot_Task returns ManagedObjectReference r
|
||||
ManagedObjectReference _this r
|
||||
Boolean removeChildren r
|
||||
end
|
||||
|
||||
|
||||
method RemoveVirtualSwitch
|
||||
ManagedObjectReference _this r
|
||||
String vswitchName r
|
||||
end
|
||||
|
||||
|
||||
method RetrieveProperties returns ObjectContent ol
|
||||
ManagedObjectReference _this:propertyCollector r
|
||||
PropertyFilterSpec specSet rl
|
||||
|
@ -1520,6 +1520,11 @@ additional_object_features = { "AutoStartDefaults" : Object.FEATURE__AN
|
||||
Object.FEATURE__ANY_TYPE,
|
||||
"HostDatastoreBrowserSearchResults" : Object.FEATURE__LIST |
|
||||
Object.FEATURE__ANY_TYPE,
|
||||
"HostPortGroup" : Object.FEATURE__LIST |
|
||||
Object.FEATURE__ANY_TYPE,
|
||||
"HostVirtualSwitch" : Object.FEATURE__DEEP_COPY |
|
||||
Object.FEATURE__LIST |
|
||||
Object.FEATURE__ANY_TYPE,
|
||||
"ManagedObjectReference" : Object.FEATURE__ANY_TYPE,
|
||||
"ObjectContent" : Object.FEATURE__DEEP_COPY,
|
||||
"PhysicalNic" : Object.FEATURE__DEEP_COPY |
|
||||
|
Loading…
Reference in New Issue
Block a user