mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-11-03 11:51:11 +00:00
network: provide internal API to return IP of a network
The new listenNetwork attribute needs to learn an IP address based on a named network. This patch provides a function networkGetNetworkAddress which provides that. Some networks have an IP address explicitly in their configuration (ie, those with a forward type of "none", "route", or "nat"). For those, we can just return the IP address from the config. The rest will have a physical device associated with them (either via <bridge name='...'/>, <forward ... dev='...'/>, or possibly via a pool of interfaces inside the network's <forward> element) and we will need to ask the kernel for a current IP address of that device (via the newly added ifaceGetIPAddress) If networkGetNetworkAddress encounters an error while trying to learn the address for a network, it will return -1. In the case that libvirt has been compiled without the network driver, the call is a macro which reduces to -2. This allows differentiating between a failure of the network driver, and its complete absence.
This commit is contained in:
parent
c5d1592e20
commit
239322cbd4
@ -5,5 +5,6 @@
|
|||||||
# bridge_driver.h
|
# bridge_driver.h
|
||||||
networkAllocateActualDevice;
|
networkAllocateActualDevice;
|
||||||
networkBuildDhcpDaemonCommandLine;
|
networkBuildDhcpDaemonCommandLine;
|
||||||
|
networkGetNetworkAddress;
|
||||||
networkNotifyActualDevice;
|
networkNotifyActualDevice;
|
||||||
networkReleaseActualDevice;
|
networkReleaseActualDevice;
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
#include "iptables.h"
|
#include "iptables.h"
|
||||||
#include "bridge.h"
|
#include "bridge.h"
|
||||||
|
#include "interface.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "dnsmasq.h"
|
#include "dnsmasq.h"
|
||||||
#include "util/network.h"
|
#include "util/network.h"
|
||||||
@ -3090,3 +3091,103 @@ cleanup:
|
|||||||
iface->data.network.actual = NULL;
|
iface->data.network.actual = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* networkGetNetworkAddress:
|
||||||
|
* @netname: the name of a network
|
||||||
|
* @netaddr: string representation of IP address for that network.
|
||||||
|
*
|
||||||
|
* Attempt to return an IP (v4) address associated with the named
|
||||||
|
* network. If a libvirt virtual network, that will be provided in the
|
||||||
|
* configuration. For host bridge and direct (macvtap) networks, we
|
||||||
|
* must do an ioctl to learn the address.
|
||||||
|
*
|
||||||
|
* Note: This function returns the 1st IPv4 address it finds. It might
|
||||||
|
* be useful if it was more flexible, but the current use (getting a
|
||||||
|
* listen address for qemu's vnc/spice graphics server) can only use a
|
||||||
|
* single address anyway.
|
||||||
|
*
|
||||||
|
* Returns 0 on success, and puts a string (which must be free'd by
|
||||||
|
* the caller) into *netaddr. Returns -1 on failure or -2 if
|
||||||
|
* completely unsupported.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
networkGetNetworkAddress(const char *netname, char **netaddr)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
struct network_driver *driver = driverState;
|
||||||
|
virNetworkObjPtr network = NULL;
|
||||||
|
virNetworkDefPtr netdef;
|
||||||
|
virNetworkIpDefPtr ipdef;
|
||||||
|
virSocketAddr addr;
|
||||||
|
virSocketAddrPtr addrptr = NULL;
|
||||||
|
char *devname = NULL;
|
||||||
|
|
||||||
|
*netaddr = NULL;
|
||||||
|
networkDriverLock(driver);
|
||||||
|
network = virNetworkFindByName(&driver->networks, netname);
|
||||||
|
networkDriverUnlock(driver);
|
||||||
|
if (!network) {
|
||||||
|
networkReportError(VIR_ERR_NO_NETWORK,
|
||||||
|
_("no network with matching name '%s'"),
|
||||||
|
netname);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
netdef = network->def;
|
||||||
|
|
||||||
|
switch (netdef->forwardType) {
|
||||||
|
case VIR_NETWORK_FORWARD_NONE:
|
||||||
|
case VIR_NETWORK_FORWARD_NAT:
|
||||||
|
case VIR_NETWORK_FORWARD_ROUTE:
|
||||||
|
/* if there's an ipv4def, get it's address */
|
||||||
|
ipdef = virNetworkDefGetIpByIndex(netdef, AF_INET, 0);
|
||||||
|
if (!ipdef) {
|
||||||
|
networkReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("network '%s' doesn't have an IPv4 address"),
|
||||||
|
netdef->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
addrptr = &ipdef->address;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_NETWORK_FORWARD_BRIDGE:
|
||||||
|
if ((devname = netdef->bridge))
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
* fall through if netdef->bridge wasn't set, since this is
|
||||||
|
* also a direct-mode interface.
|
||||||
|
*/
|
||||||
|
case VIR_NETWORK_FORWARD_PRIVATE:
|
||||||
|
case VIR_NETWORK_FORWARD_VEPA:
|
||||||
|
case VIR_NETWORK_FORWARD_PASSTHROUGH:
|
||||||
|
if ((netdef->nForwardIfs > 0) && netdef->forwardIfs)
|
||||||
|
devname = netdef->forwardIfs[0].dev;
|
||||||
|
|
||||||
|
if (!devname) {
|
||||||
|
networkReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("network '%s' has no associated interface or bridge"),
|
||||||
|
netdef->name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devname) {
|
||||||
|
if (ifaceGetIPAddress(devname, &addr)) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("Failed to get IP address for '%s' (network '%s')"),
|
||||||
|
devname, netdef->name);
|
||||||
|
} else {
|
||||||
|
addrptr = &addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addrptr &&
|
||||||
|
(*netaddr = virSocketFormatAddr(addrptr))) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (network)
|
||||||
|
virNetworkObjUnlock(network);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -43,6 +43,9 @@ int networkNotifyActualDevice(virDomainNetDefPtr iface)
|
|||||||
int networkReleaseActualDevice(virDomainNetDefPtr iface)
|
int networkReleaseActualDevice(virDomainNetDefPtr iface)
|
||||||
ATTRIBUTE_NONNULL(1);
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
|
int networkGetNetworkAddress(const char *netname, char **netaddr)
|
||||||
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
int networkBuildDhcpDaemonCommandLine(virNetworkObjPtr network,
|
int networkBuildDhcpDaemonCommandLine(virNetworkObjPtr network,
|
||||||
virCommandPtr *cmdout, char *pidfile,
|
virCommandPtr *cmdout, char *pidfile,
|
||||||
dnsmasqContext *dctx)
|
dnsmasqContext *dctx)
|
||||||
@ -52,6 +55,7 @@ int networkBuildDhcpDaemonCommandLine(virNetworkObjPtr network,
|
|||||||
# define networkAllocateActualDevice(iface) 0
|
# define networkAllocateActualDevice(iface) 0
|
||||||
# define networkNotifyActualDevice(iface) 0
|
# define networkNotifyActualDevice(iface) 0
|
||||||
# define networkReleaseActualDevice(iface) 0
|
# define networkReleaseActualDevice(iface) 0
|
||||||
|
# defing networkGetNetworkAddress(netname, netaddr) (-2)
|
||||||
# define networkBuildDhcpDaemonCommandLine(network, cmdout, pidfile, dctx) 0
|
# define networkBuildDhcpDaemonCommandLine(network, cmdout, pidfile, dctx) 0
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user