libvirt/src/esx/esx_interface_driver.c

320 lines
8.1 KiB
C
Raw Normal View History

/*
* esx_interface_driver.c: interface driver functions for managing VMware ESX
* host interfaces
*
drivers: prefer unsigned int for flags Now that the public APIs always use unsigned flags, the internal driver callbacks might as well do likewise. * src/driver.h (vrDrvOpen, virDrvDomainCoreDump) (virDrvDomainGetXMLDesc, virDrvNetworkGetXMLDesc) (virDrvNWFilterGetXMLDesc): Update type. * src/remote/remote_protocol.x (remote_open_args) (remote_domain_core_dump_args, remote_domain_get_xml_desc_args) (remote_network_get_xml_desc_args) (remote_nwfilter_get_xml_desc_args): Likewise. * src/test/test_driver.c: Update clients. * src/remote/remote_driver.c: Likewise. * src/xen/xen_hypervisor.c: Likewise. * src/xen/xen_hypervisor.h: Likewise. * src/xen/xen_driver.c: Likewise. * src/xen/xend_internal.c: Likewise. * src/xen/xend_internal.h: Likewise. * src/xen/xm_internal.c: Likewise. * src/xen/xm_internal.h: Likewise. * src/xen/xs_internal.c: Likewise. * src/xen/xs_internal.h: Likewise. * src/xen/xen_inotify.c: Likewise. * src/xen/xen_inotify.h: Likewise. * src/phyp/phyp_driver.c: Likewise. * src/openvz/openvz_driver.c: Likewise. * src/vmware/vmware_driver.c: Likewise. * src/vbox/vbox_driver.c: Likewise. * src/vbox/vbox_tmpl.c: Likewise. * src/xenapi/xenapi_driver.c: Likewise. * src/esx/esx_driver.c: Likewise. * src/esx/esx_interface_driver.c: Likewise. * src/esx/esx_network_driver.c: Likewise. * src/esx/esx_storage_driver.c: Likewise. * src/esx/esx_device_monitor.c: Likewise. * src/esx/esx_secret_driver.c: Likewise. * src/esx/esx_nwfilter_driver.c: Likewise. * src/interface/netcf_driver.c: Likewise. * src/nwfilter/nwfilter_driver.c: Likewise. * src/libxl/libxl_driver.c: Likewise. * src/qemu/qemu_driver.c: Likewise. * src/lxc/lxc_driver.c: Likewise. * src/uml/uml_driver.c: Likewise. * src/network/bridge_driver.c: Likewise. * src/secret/secret_driver.c: Likewise. * src/storage/storage_driver.c: Likewise. * src/node_device/node_device_hal.c: Likewise. * src/node_device/node_device_udev.c: Likewise. * src/remote_protocol-structs: Likewise.
2011-07-06 20:40:19 +00:00
* Copyright (C) 2010-2011 Red Hat, Inc.
* 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
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
*/
#include <config.h>
#include "internal.h"
2012-12-13 17:44:57 +00:00
#include "virutil.h"
2012-12-12 18:06:53 +00:00
#include "viralloc.h"
2012-12-12 17:59:27 +00:00
#include "virlog.h"
2012-12-13 18:01:25 +00:00
#include "viruuid.h"
#include "interface_conf.h"
#include "virsocketaddr.h"
#include "esx_private.h"
#include "esx_interface_driver.h"
#include "esx_vi.h"
#include "esx_vi_methods.h"
#include "esx_util.h"
#define VIR_FROM_THIS VIR_FROM_ESX
static virDrvOpenStatus
esxInterfaceOpen(virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
unsigned int flags)
{
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
if (conn->driver->no != VIR_DRV_ESX) {
return VIR_DRV_OPEN_DECLINED;
}
conn->interfacePrivateData = conn->privateData;
return VIR_DRV_OPEN_SUCCESS;
}
static int
esxInterfaceClose(virConnectPtr conn)
{
conn->interfacePrivateData = NULL;
return 0;
}
static int
esxNumberOfInterfaces(virConnectPtr conn)
{
esxPrivate *priv = conn->interfacePrivateData;
esxVI_PhysicalNic *physicalNicList = NULL;
esxVI_PhysicalNic *physicalNic = NULL;
int count = 0;
if (esxVI_EnsureSession(priv->primary) < 0 ||
esxVI_LookupPhysicalNicList(priv->primary, &physicalNicList) < 0) {
return -1;
}
for (physicalNic = physicalNicList; physicalNic != NULL;
physicalNic = physicalNic->_next) {
++count;
}
esxVI_PhysicalNic_Free(&physicalNicList);
return count;
}
static int
esxListInterfaces(virConnectPtr conn, char **const names, int maxnames)
{
bool success = false;
esxPrivate *priv = conn->interfacePrivateData;
esxVI_PhysicalNic *physicalNicList = NULL;
esxVI_PhysicalNic *physicalNic = NULL;
int count = 0;
int i;
if (maxnames == 0) {
return 0;
}
if (esxVI_EnsureSession(priv->primary) < 0 ||
esxVI_LookupPhysicalNicList(priv->primary, &physicalNicList) < 0) {
return -1;
}
for (physicalNic = physicalNicList; physicalNic != NULL;
physicalNic = physicalNic->_next) {
names[count] = strdup(physicalNic->device);
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_PhysicalNic_Free(&physicalNicList);
return count;
}
static int
esxNumberOfDefinedInterfaces(virConnectPtr conn ATTRIBUTE_UNUSED)
{
/* ESX interfaces are always active */
return 0;
}
static int
esxListDefinedInterfaces(virConnectPtr conn ATTRIBUTE_UNUSED,
char **const names ATTRIBUTE_UNUSED,
int maxnames ATTRIBUTE_UNUSED)
{
/* ESX interfaces are always active */
return 0;
}
static virInterfacePtr
esxInterfaceLookupByName(virConnectPtr conn, const char *name)
{
virInterfacePtr iface = NULL;
esxPrivate *priv = conn->interfacePrivateData;
esxVI_PhysicalNic *physicalNic = NULL;
if (esxVI_EnsureSession(priv->primary) < 0 ||
esxVI_LookupPhysicalNicByMACAddress(priv->primary, name, &physicalNic,
esxVI_Occurrence_RequiredItem) < 0) {
return NULL;
}
iface = virGetInterface(conn, physicalNic->device, physicalNic->mac);
esxVI_PhysicalNic_Free(&physicalNic);
return iface;
}
static virInterfacePtr
esxInterfaceLookupByMACString(virConnectPtr conn, const char *mac)
{
virInterfacePtr iface = NULL;
esxPrivate *priv = conn->interfacePrivateData;
esxVI_PhysicalNic *physicalNic = NULL;
if (esxVI_EnsureSession(priv->primary) < 0 ||
esxVI_LookupPhysicalNicByMACAddress(priv->primary, mac, &physicalNic,
esxVI_Occurrence_RequiredItem) < 0) {
return NULL;
}
iface = virGetInterface(conn, physicalNic->device, physicalNic->mac);
esxVI_PhysicalNic_Free(&physicalNic);
return iface;
}
static char *
esxInterfaceGetXMLDesc(virInterfacePtr iface, unsigned int flags)
{
char *xml = NULL;
esxPrivate *priv = iface->conn->interfacePrivateData;
esxVI_PhysicalNic *physicalNic = NULL;
virInterfaceDef def;
bool hasAddress = false;
virInterfaceProtocolDefPtr protocols;
virInterfaceProtocolDef protocol;
virSocketAddr socketAddress;
virInterfaceIpDefPtr ips;
virInterfaceIpDef ip;
virCheckFlags(VIR_INTERFACE_XML_INACTIVE, NULL);
memset(&def, 0, sizeof(def));
memset(&protocol, 0, sizeof(protocol));
memset(&socketAddress, 0, sizeof(socketAddress));
memset(&ip, 0, sizeof(ip));
if (esxVI_EnsureSession(priv->primary) < 0 ||
esxVI_LookupPhysicalNicByMACAddress(priv->primary, iface->mac,
&physicalNic,
esxVI_Occurrence_RequiredItem) < 0) {
return NULL;
}
def.type = VIR_INTERFACE_TYPE_ETHERNET;
def.name = physicalNic->device;
def.mac = physicalNic->mac;
def.startmode = VIR_INTERFACE_START_ONBOOT;
/* FIXME: Add support for IPv6, requires to use vSphere API 4.0 */
if (physicalNic->spec->ip != NULL) {
protocol.family = (char *)"ipv4";
if (physicalNic->spec->ip->dhcp == esxVI_Boolean_True) {
protocol.dhcp = 1;
}
if (physicalNic->spec->ip->ipAddress != NULL &&
physicalNic->spec->ip->subnetMask != NULL &&
strlen(physicalNic->spec->ip->ipAddress) > 0 &&
strlen(physicalNic->spec->ip->subnetMask) > 0) {
hasAddress = true;
}
if (protocol.dhcp || hasAddress) {
protocols = &protocol;
def.nprotos = 1;
def.protos = &protocols;
}
if (hasAddress &&
!(protocol.dhcp && (flags & VIR_INTERFACE_XML_INACTIVE))) {
ips = &ip;
protocol.nips = 1;
protocol.ips = &ips;
if (virSocketAddrParseIPv4(&socketAddress,
physicalNic->spec->ip->subnetMask) < 0) {
goto cleanup;
}
ip.address = physicalNic->spec->ip->ipAddress;
ip.prefix = virSocketAddrGetNumNetmaskBits(&socketAddress);
}
}
xml = virInterfaceDefFormat(&def);
cleanup:
esxVI_PhysicalNic_Free(&physicalNic);
return xml;
}
static int
esxInterfaceIsActive(virInterfacePtr iface ATTRIBUTE_UNUSED)
{
/* ESX interfaces are always active */
return 1;
}
static virInterfaceDriver esxInterfaceDriver = {
.name = "ESX",
.open = esxInterfaceOpen, /* 0.7.6 */
.close = esxInterfaceClose, /* 0.7.6 */
.numOfInterfaces = esxNumberOfInterfaces, /* 0.10.0 */
.listInterfaces = esxListInterfaces, /* 0.10.0 */
.numOfDefinedInterfaces = esxNumberOfDefinedInterfaces, /* 0.10.0 */
.listDefinedInterfaces = esxListDefinedInterfaces, /* 0.10.0 */
.interfaceLookupByName = esxInterfaceLookupByName, /* 0.10.0 */
.interfaceLookupByMACString = esxInterfaceLookupByMACString, /* 0.10.0 */
.interfaceGetXMLDesc = esxInterfaceGetXMLDesc, /* 0.10.0 */
.interfaceIsActive = esxInterfaceIsActive, /* 0.10.0 */
};
int
esxInterfaceRegister(void)
{
return virRegisterInterfaceDriver(&esxInterfaceDriver);
}