From: Roman Bogorodskiy Date: Fri, 3 May 2013 13:35:20 +0000 (+0400) Subject: portability: fix virNetDevSetMAC and virNetDevExists on BSD X-Git-Tag: CVE-2013-1962~93 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=95934171fb243ff41a28f4fdd8c4656089f62720;p=thirdparty%2Flibvirt.git portability: fix virNetDevSetMAC and virNetDevExists on BSD - provide virNetDevSetMAC() implementation based on SIOCSIFLLADDR ioctl. - adjust virNetDevExists() to check for ENXIO error because FreeBSD throws it when device doesn't exist Signed-off-by: Eric Blake --- diff --git a/configure.ac b/configure.ac index 992a778500..53f78de11b 100644 --- a/configure.ac +++ b/configure.ac @@ -2371,6 +2371,14 @@ AC_CHECK_MEMBERS([struct ifreq.ifr_newname, [#include #include ]) +# Check for BSD approach for setting MAC addr +AC_CHECK_DECLS([link_addr], + [], [], + [#include + #include + #include + ]) + # Only COPYING.LIB is under version control, yet COPYING # is included as part of the distribution tarball. diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index d987b8eb21..251a66ae6c 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -47,6 +47,11 @@ # undef HAVE_STRUCT_IFREQ #endif +#if HAVE_DECL_LINK_ADDR +# include +# include +#endif + #define VIR_FROM_THIS VIR_FROM_NONE #if defined(HAVE_STRUCT_IFREQ) @@ -110,7 +115,7 @@ int virNetDevExists(const char *ifname) return -1; if (ioctl(fd, SIOCGIFFLAGS, &ifr)) { - if (errno == ENODEV) + if (errno == ENODEV || errno == ENXIO) ret = 0; else virReportSystemError(errno, @@ -179,6 +184,40 @@ cleanup: VIR_FORCE_CLOSE(fd); return ret; } +#elif defined(SIOCSIFLLADDR) && defined(HAVE_STRUCT_IFREQ) && \ + HAVE_DECL_LINK_ADDR +int virNetDevSetMAC(const char *ifname, + const virMacAddrPtr macaddr) +{ + struct ifreq ifr; + struct sockaddr_dl sdl; + char mac[VIR_MAC_STRING_BUFLEN + 1] = ":"; + int s; + int ret = -1; + + if ((s = virNetDevSetupControl(ifname, &ifr)) < 0) + return -1; + + virMacAddrFormat(macaddr, mac + 1); + sdl.sdl_len = sizeof(sdl); + link_addr(mac, &sdl); + + memcpy(ifr.ifr_addr.sa_data, sdl.sdl_data, VIR_MAC_BUFLEN); + ifr.ifr_addr.sa_len = VIR_MAC_BUFLEN; + + if (ioctl(s, SIOCSIFLLADDR, &ifr) < 0) { + virReportSystemError(errno, + _("Cannot set interface MAC on '%s'"), + ifname); + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(s); + + return ret; +} #else int virNetDevSetMAC(const char *ifname, const virMacAddrPtr macaddr ATTRIBUTE_UNUSED)