[libvirt] [PATCH] 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 --- configure.ac | 8 ++++++++ src/util/virnetdev.c | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 992a778..95d303f 100644 --- a/configure.ac +++ b/configure.ac @@ -2372,6 +2372,14 @@ AC_CHECK_MEMBERS([struct ifreq.ifr_newname, #include <net/if.h> ]) +AC_CHECK_DECLS([link_addr], + [], [], + [#include <sys/types.h> + #include <sys/socket.h> + #include <net/if_dl.h> + ]) + + # Only COPYING.LIB is under version control, yet COPYING # is included as part of the distribution tarball. # Copy one to the other, but only if this is a srcdir-build. diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index d987b8e..0527a27 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -47,6 +47,11 @@ # undef HAVE_STRUCT_IFREQ #endif +#ifdef HAVE_DECL_LINK_ADDR +# include <sys/sockio.h> +# include <net/if_dl.h> +#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) && \ + defined(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) -- 1.8.0

On 05/03/2013 07:35 AM, Roman Bogorodskiy wrote:
- provide virNetDevSetMAC() implementation based on SIOCSIFLLADDR ioctl. - adjust virNetDevExists() to check for ENXIO error because FreeBSD throws it when device doesn't exist --- configure.ac | 8 ++++++++ src/util/virnetdev.c | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-)
+++ b/configure.ac @@ -2372,6 +2372,14 @@ AC_CHECK_MEMBERS([struct ifreq.ifr_newname, #include <net/if.h> ])
+AC_CHECK_DECLS([link_addr],
Maybe a comment mentioning that this is a BSD interface might help future readers.
+++ b/src/util/virnetdev.c @@ -47,6 +47,11 @@ # undef HAVE_STRUCT_IFREQ #endif
+#ifdef HAVE_DECL_LINK_ADDR
Fails 'make syntax-check': src/util/virnetdev.c:50:#ifdef HAVE_DECL_LINK_ADDR maint.mk: HAVE_DECL macros are always defined s/ifdef/if/ to fix
@@ -179,6 +184,40 @@ cleanup: VIR_FORCE_CLOSE(fd); return ret; } +#elif defined(SIOCSIFLLADDR) && defined(HAVE_STRUCT_IFREQ) && \ + defined(HAVE_DECL_LINK_ADDR)
Ouch. 'make syntax-check' didn't pick up on this one. You want s/defined(\(HAVE_DECL_LINK_ADDR\))/\1/, and I have a chore to fix the syntax-checker to spot this one :) ACK, and pushed with this squashed in. diff --git i/src/util/virnetdev.c w/src/util/virnetdev.c index 0527a27..251a66a 100644 --- i/src/util/virnetdev.c +++ w/src/util/virnetdev.c @@ -47,7 +47,7 @@ # undef HAVE_STRUCT_IFREQ #endif -#ifdef HAVE_DECL_LINK_ADDR +#if HAVE_DECL_LINK_ADDR # include <sys/sockio.h> # include <net/if_dl.h> #endif @@ -185,7 +185,7 @@ cleanup: return ret; } #elif defined(SIOCSIFLLADDR) && defined(HAVE_STRUCT_IFREQ) && \ - defined(HAVE_DECL_LINK_ADDR) + HAVE_DECL_LINK_ADDR int virNetDevSetMAC(const char *ifname, const virMacAddrPtr macaddr) { -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Eric Blake wrote:
On 05/03/2013 07:35 AM, Roman Bogorodskiy wrote:
- provide virNetDevSetMAC() implementation based on SIOCSIFLLADDR ioctl. - adjust virNetDevExists() to check for ENXIO error because FreeBSD throws it when device doesn't exist --- configure.ac | 8 ++++++++ src/util/virnetdev.c | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-)
+++ b/configure.ac @@ -2372,6 +2372,14 @@ AC_CHECK_MEMBERS([struct ifreq.ifr_newname, #include <net/if.h> ])
+AC_CHECK_DECLS([link_addr],
Maybe a comment mentioning that this is a BSD interface might help future readers.
+++ b/src/util/virnetdev.c @@ -47,6 +47,11 @@ # undef HAVE_STRUCT_IFREQ #endif
+#ifdef HAVE_DECL_LINK_ADDR
Fails 'make syntax-check':
src/util/virnetdev.c:50:#ifdef HAVE_DECL_LINK_ADDR maint.mk: HAVE_DECL macros are always defined
s/ifdef/if/ to fix
@@ -179,6 +184,40 @@ cleanup: VIR_FORCE_CLOSE(fd); return ret; } +#elif defined(SIOCSIFLLADDR) && defined(HAVE_STRUCT_IFREQ) && \ + defined(HAVE_DECL_LINK_ADDR)
Ouch. 'make syntax-check' didn't pick up on this one. You want s/defined(\(HAVE_DECL_LINK_ADDR\))/\1/, and I have a chore to fix the syntax-checker to spot this one :)
ACK, and pushed with this squashed in.
diff --git i/src/util/virnetdev.c w/src/util/virnetdev.c index 0527a27..251a66a 100644 --- i/src/util/virnetdev.c +++ w/src/util/virnetdev.c @@ -47,7 +47,7 @@ # undef HAVE_STRUCT_IFREQ #endif
-#ifdef HAVE_DECL_LINK_ADDR +#if HAVE_DECL_LINK_ADDR # include <sys/sockio.h> # include <net/if_dl.h> #endif @@ -185,7 +185,7 @@ cleanup: return ret; } #elif defined(SIOCSIFLLADDR) && defined(HAVE_STRUCT_IFREQ) && \ - defined(HAVE_DECL_LINK_ADDR) + HAVE_DECL_LINK_ADDR int virNetDevSetMAC(const char *ifname, const virMacAddrPtr macaddr) {
Eric, thanks for fixing these stupid errors of mine. Do you run 'syntax-check' on your FreeBSD vm? It fails on libvirt_unmarked_diagnostics for me, like this: maint.mk: found unmarked diagnostic(s) gmake: *** [sc_libvirt_unmarked_diagnostics] Error 1 Full log here: http://people.freebsd.org/~novel/misc/libvirt_syntax_check.txt Roman Bogorodskiy

On 05/11/2013 09:05 AM, Roman Bogorodskiy wrote:
Eric, thanks for fixing these stupid errors of mine.
Do you run 'syntax-check' on your FreeBSD vm?
So far, I've just been running it on Fedora. I suspect that it makes some GNU assumptions (at least maint.mk comes from gnulib, and upstream gnulib has already stated that it's okay for maintainer-only tools to assume "sane" systems, where "sane" excludes anything that requires lots of porting effort). That is, while I _know_ syntax-check won't work on Solaris, I don't know whether the fact that it fails on BSD is intentional, or something that can be easily fixed with minimal maintenance nightmares.
It fails on libvirt_unmarked_diagnostics for me, like this:
maint.mk: found unmarked diagnostic(s) gmake: *** [sc_libvirt_unmarked_diagnostics] Error 1
Full log here:
http://people.freebsd.org/~novel/misc/libvirt_syntax_check.txt
I'll take a look. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Eric Blake
-
Roman Bogorodskiy