On 02/13/2015 02:17 AM, Luyao Huang wrote:
Export the required helpers and rework networkGetNetworkAddress to
make it can get IPv6 address.
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
src/conf/network_conf.c | 2 +-
src/conf/network_conf.h | 1 +
src/libvirt_private.syms | 1 +
src/network/bridge_driver.c | 50 ++++++++++++++++++++++++++++++++-------------
src/network/bridge_driver.h | 6 ++++--
src/qemu/qemu_command.c | 4 ++--
6 files changed, 45 insertions(+), 19 deletions(-)
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index f947d89..9eb640b 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -148,7 +148,7 @@ virNetworkDHCPHostDefClear(virNetworkDHCPHostDefPtr def)
VIR_FREE(def->name);
}
-static void
+void
I believe this is unnecessary
virNetworkIpDefClear(virNetworkIpDefPtr def)
{
VIR_FREE(def->family);
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 484522e..0c4b559 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -310,6 +310,7 @@ virNetworkObjPtr virNetworkFindByName(virNetworkObjListPtr nets,
void virNetworkDefFree(virNetworkDefPtr def);
void virNetworkObjFree(virNetworkObjPtr net);
void virNetworkObjListFree(virNetworkObjListPtr vms);
+void virNetworkIpDefClear(virNetworkIpDefPtr def);
Same unnecessary
typedef bool (*virNetworkObjListFilter)(virConnectPtr conn,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f60911c..ff942d8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -559,6 +559,7 @@ virNetworkDeleteConfig;
virNetworkFindByName;
virNetworkFindByUUID;
virNetworkForwardTypeToString;
+virNetworkIpDefClear;
Unnecessary
virNetworkIpDefNetmask;
virNetworkIpDefPrefix;
virNetworkLoadAllConfigs;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 2798010..d1afd16 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4487,6 +4487,7 @@ networkReleaseActualDevice(virDomainDefPtr dom,
* networkGetNetworkAddress:
* @netname: the name of a network
* @netaddr: string representation of IP address for that network.
+ * @family: IP family
@want_ipv6: boolean to force return of IPv6 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
@@ -4503,12 +4504,13 @@ networkReleaseActualDevice(virDomainDefPtr dom,
* completely unsupported.
*/
int
-networkGetNetworkAddress(const char *netname, char **netaddr)
+networkGetNetworkAddress(const char *netname, char **netaddr, int family)
s/int family/bool want_ipv6/
{
int ret = -1;
virNetworkObjPtr network;
virNetworkDefPtr netdef;
- virNetworkIpDefPtr ipdef;
+ virNetworkIpDefPtr ipdef = NULL;
+ virNetworkIpDefPtr ipdef6 = NULL;
The ipdef6 is unnecessary
virSocketAddr addr;
virSocketAddrPtr addrptr = NULL;
char *dev_name = NULL;
@@ -4529,15 +4531,9 @@ networkGetNetworkAddress(const char *netname, char **netaddr)
case VIR_NETWORK_FORWARD_NONE:
case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE:
- /* if there's an ipv4def, get it's address */
+ /* if there's an ipv4def or ipv6def, get it's address */
ipdef = virNetworkDefGetIpByIndex(netdef, AF_INET, 0);
- if (!ipdef) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("network '%s' doesn't have an IPv4
address"),
- netdef->name);
- break;
- }
- addrptr = &ipdef->address;
+ ipdef6 = virNetworkDefGetIpByIndex(netdef, AF_INET6, 0);
Not sure I follow why we're losing the error reporting here...
I'd change this to:
if (want_ipv6)
ipdef = virNetworkDefGetIpByIndex(netdef, AF_INET6, 0);
else
ipdef = virNetworkDefGetIpByIndex(netdef, AF_INET, 0);
if (!ipdef) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("network '%s' doesn't have an '%s'
address"),
netdef->name, want_ipv6 ? "IPv6" : "IPv4");
break;
}
addrptr = &ipdef->address;
NB: virNetworkDefGetIpByIndex() doesn't return a COPY that we must FREE,
it returns a pointer to something owned elsewhere
break;
case VIR_NETWORK_FORWARD_BRIDGE:
@@ -4561,10 +4557,32 @@ networkGetNetworkAddress(const char *netname, char **netaddr)
break;
}
- if (dev_name) {
- if (virNetDevGetIPv4Address(dev_name, &addr) < 0)
- goto error;
- addrptr = &addr;
+ switch ((virDomainGraphicsListenFamily) family) {
+ case VIR_DOMAIN_GRAPHICS_LISTEN_FAMILY_DEFAULT:
+ case VIR_DOMAIN_GRAPHICS_LISTEN_FAMILY_IPV4:
+ if (ipdef)
+ addrptr = &ipdef->address;
+ if (dev_name) {
+ if (virNetDevGetIPv4Address(dev_name, &addr) < 0)
+ goto error;
+ addrptr = &addr;
+ }
+ /*if the family is default and we do not get a ipv4 address
+ *in this place, we will try to get a ipv6 address
+ */
+ if (addrptr || family == VIR_DOMAIN_GRAPHICS_LISTEN_FAMILY_IPV4)
+ break;
+ case VIR_DOMAIN_GRAPHICS_LISTEN_FAMILY_IPV6:
+ if (ipdef6)
+ addrptr = &ipdef6->address;
+ if (dev_name) {
+ if (virNetDevGetIPv6Address(dev_name, &addr) < 0)
+ goto error;
+ addrptr = &addr;
+ }
+ break;
+ case VIR_DOMAIN_GRAPHICS_LISTEN_FAMILY_LAST:
+ break;
This code would then just be:
if (dev_name) {
if (virNetDevGetIPAddress(dev_name, &addr, want_ipv6) < 0)
goto error;
addrptr = &addr;
}
While I can appreciate the logic to "default to" returning the IPv6
address if no IPv4 address was found, I think those details can/should
be left up to the caller to decide whether returning an IPv6 address is
acceptable. Falling through to a try to find/return an IPv6 address
while perhaps being "kind" could result in some caller getting something
it didn't expect and even worse, didn't know how to parse!
}
if (!(addrptr &&
@@ -4579,6 +4597,10 @@ networkGetNetworkAddress(const char *netname, char **netaddr)
return ret;
error:
+ if (ipdef6)
+ virNetworkIpDefClear(ipdef6);
+ if (ipdef)
+ virNetworkIpDefClear(ipdef);
Since virNetworkDefGetIpByIndex is not creating a copy, but rather is
returning the "&def->ips[i];" value, I don't believe we want to do
any
sort of clear here as it then becomes unusable for no reason.
goto cleanup;
}
diff --git a/src/network/bridge_driver.h b/src/network/bridge_driver.h
index 2f801ee..c684c15 100644
--- a/src/network/bridge_driver.h
+++ b/src/network/bridge_driver.h
@@ -44,7 +44,9 @@ int networkReleaseActualDevice(virDomainDefPtr dom,
virDomainNetDefPtr iface)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
-int networkGetNetworkAddress(const char *netname, char **netaddr)
+int networkGetNetworkAddress(const char *netname,
+ char **netaddr,
+ int family)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int networkDnsmasqConfContents(virNetworkObjPtr network,
@@ -57,7 +59,7 @@ int networkDnsmasqConfContents(virNetworkObjPtr network,
# define networkAllocateActualDevice(dom, iface) 0
# define networkNotifyActualDevice(dom, iface) (dom=dom, iface=iface, 0)
# define networkReleaseActualDevice(dom, iface) (dom=dom, iface=iface, 0)
-# define networkGetNetworkAddress(netname, netaddr) (-2)
+# define networkGetNetworkAddress(netname, netaddr, family) (-2)
# define networkDnsmasqConfContents(network, pidfile, configstr, \
dctx, caps) 0
# endif
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9c25788..6bd8f69 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7277,7 +7277,7 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
listenNetwork = virDomainGraphicsListenGetNetwork(graphics, 0);
if (!listenNetwork)
break;
- ret = networkGetNetworkAddress(listenNetwork, &netAddr);
+ ret = networkGetNetworkAddress(listenNetwork, &netAddr,
graphics->listens->family);
if (ret <= -2) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("network-based listen not
possible, "
@@ -7441,7 +7441,7 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg,
listenNetwork = virDomainGraphicsListenGetNetwork(graphics, 0);
if (!listenNetwork)
break;
- ret = networkGetNetworkAddress(listenNetwork, &netAddr);
+ ret = networkGetNetworkAddress(listenNetwork, &netAddr,
graphics->listens->family);
if (ret <= -2) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("network-based listen not possible,
"
These two turn into a boolean 3rd parameter:
(graphics->listens->ipv6 == VIR_TRISTATE_BOOL_YES)
and should be on a separate line to avoid the longer than 80 characters
in a line...
John