Introduce a new function to help to get interface IPv6 address.
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virnetdev.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++
src/util/virnetdev.h | 2 ++
3 files changed, 73 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 645aef1..f60911c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1659,6 +1659,7 @@ virNetDevDelMulti;
virNetDevExists;
virNetDevGetIndex;
virNetDevGetIPv4Address;
+virNetDevGetIPv6Address;
virNetDevGetLinkInfo;
virNetDevGetMAC;
virNetDevGetMTU;
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index 2a0eb43..c1a588e 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -33,6 +33,10 @@
#include "virstring.h"
#include "virutil.h"
+#if defined(HAVE_GETIFADDRS)
+# include <ifaddrs.h>
+#endif
+
#include <sys/ioctl.h>
#include <net/if.h>
#include <fcntl.h>
@@ -1432,6 +1436,72 @@ int virNetDevGetIPv4Address(const char *ifname ATTRIBUTE_UNUSED,
#endif /* ! SIOCGIFADDR */
+/**
+ *virNetDevGetIPv6Address:
+ *@ifname: name of the interface whose IP address we want
+ *@addr: filled with the IPv6 address
+ *
+ *This function gets the IPv6 address for the interface @ifname
+ *and stores it in @addr
+ *
+ *Returns 0 on success, -1 on failure.
+ */
+#if defined(HAVE_GETIFADDRS)
+int virNetDevGetIPv6Address(const char *ifname,
+ virSocketAddrPtr addr)
+{
+ struct ifaddrs *ifap, *ifa;
+ int ret = -1;
+ bool found_one = false;
+
+ if (getifaddrs(&ifap) < 0) {
+ virReportSystemError(errno, "%s",
+ _("Could not get interface list"));
+ return -1;
+ }
+
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ if (STRNEQ(ifa->ifa_name, ifname))
+ continue;
+ found_one = true;
+ if (ifa->ifa_addr->sa_family == AF_INET6)
+ break;
+ }
+
+ if (!ifa) {
+ if (found_one)
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Interface '%s' do not have a IPv6
address"),
+ ifname);
+ else
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Interface '%s' not found"),
+ ifname);
+ goto cleanup;
+ }
+
+ addr->data.stor.ss_family = AF_INET6;
+ addr->len = sizeof(addr->data.inet6);
+ memcpy(&addr->data.inet6, ifa->ifa_addr, addr->len);
+ ret = 0;
+
+ cleanup:
+ freeifaddrs(ifap);
+ return ret;
+}
+
+#else
+
+int virNetDevGetIPv6Address(const char *ifname ATTRIBUTE_UNUSED,
+ virSocketAddrPtr addr ATTRIBUTE_UNUSED)
+{
+ virReportSystemError(ENOSYS, "%s",
+ _("Unable to get IPv6 address on this platform"));
+ return -1;
+}
+
+#endif
+
/**
* virNetDevValidateConfig:
diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h
index de8b480..c065381 100644
--- a/src/util/virnetdev.h
+++ b/src/util/virnetdev.h
@@ -104,6 +104,8 @@ int virNetDevClearIPAddress(const char *ifname,
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
int virNetDevGetIPv4Address(const char *ifname, virSocketAddrPtr addr)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
+int virNetDevGetIPv6Address(const char *ifname, virSocketAddrPtr addr)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
int virNetDevSetMAC(const char *ifname,
--
1.8.3.1