[PATCHv4 2/3] util: Update virNetDevGetIPAddress to get IPv6 addresses

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Luyao Huang <lhuang@xxxxxxxxxx>

Add static virNetDevGetifaddrsAddress to attempt to get the interface
IP address. If getifaddrs is not supported, fall back to
virNetDevGetIPv4AddressIoctl to get the IP address.

This allows IPv6 addresses to be used for <listen type='network>
with device-backed networks.

https://bugzilla.redhat.com/show_bug.cgi?id=1192318

Signed-off-by: Luyao Huang <lhuang@xxxxxxxxxx>
Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx>
Signed-off-by: Ján Tomko <jtomko@xxxxxxxxxx>
---
 src/util/virnetdev.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index 59593f9..a7903c3 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -33,6 +33,10 @@
 #include "virstring.h"
 #include "virutil.h"
 
+#if HAVE_GETIFADDRS
+# include <ifaddrs.h>
+#endif
+
 #include <sys/ioctl.h>
 #include <net/if.h>
 #include <fcntl.h>
@@ -1436,6 +1440,70 @@ virNetDevGetIPv4AddressIoctl(const char *ifname ATTRIBUTE_UNUSED,
 #endif /* ! SIOCGIFADDR */
 
 /**
+ * virNetDevGetifaddrsAddress:
+ * @ifname: name of the interface whose IP address we want
+ * @addr: filled with the IP address
+ *
+ * This function gets the IP address for the interface @ifname
+ * and stores it in @addr
+ *
+ * Returns 0 on success, -1 on failure, -2 on unsupported.
+ */
+#if HAVE_GETIFADDRS
+static int
+virNetDevGetifaddrsAddress(const char *ifname,
+                           virSocketAddrPtr addr)
+{
+    struct ifaddrs *ifap, *ifa;
+    int ret = -1;
+
+    if (getifaddrs(&ifap) < 0) {
+        virReportSystemError(errno,
+                             _("Could not get interface list for '%s'"),
+                             ifname);
+        return -1;
+    }
+
+    for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+        int family = ifa->ifa_addr->sa_family;
+
+        if (STRNEQ_NULLABLE(ifa->ifa_name, ifname))
+            continue;
+        if (family != AF_INET6 && family != AF_INET)
+            continue;
+
+        if (family == AF_INET6) {
+            addr->len = sizeof(addr->data.inet6);
+            memcpy(&addr->data.inet6, ifa->ifa_addr, addr->len);
+        } else {
+            addr->len = sizeof(addr->data.inet4);
+            memcpy(&addr->data.inet4, ifa->ifa_addr, addr->len);
+        }
+        addr->data.stor.ss_family = family;
+        ret = 0;
+        goto cleanup;
+    }
+
+    virReportError(VIR_ERR_INTERNAL_ERROR,
+                   _("no IP address found for interface '%s'"),
+                   ifname);
+ cleanup:
+    freeifaddrs(ifap);
+    return ret;
+}
+
+#else  /* ! HAVE_GETIFADDRS */
+
+static int
+virNetDevGetifaddrsAddress(const char *ifname ATTRIBUTE_UNUSED,
+                           virSocketAddrPtr addr ATTRIBUTE_UNUSED)
+{
+    return -2;
+}
+
+#endif
+
+/**
  * virNetDevGetIPAddress:
  * @ifname: name of the interface whose IP address we want
  * @addr: filled with the IPv4 address
@@ -1454,6 +1522,9 @@ virNetDevGetIPAddress(const char *ifname,
     memset(addr, 0, sizeof(*addr));
     addr->data.stor.ss_family = AF_UNSPEC;
 
+    if ((ret = virNetDevGetifaddrsAddress(ifname, addr)) != -2)
+        return ret;
+
     if ((ret = virNetDevGetIPv4AddressIoctl(ifname, addr)) != -2)
         return ret;
 
-- 
2.0.5

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list





[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]