[libvirt] [PATCH] build: work around broken kernel headers

From: Eric Blake <eblake redhat com>

To: libvir-list redhat com

Subject: [libvirt] [PATCH] build: work around broken kernel headers

Date: Tue, 23 Jul 2013 18:00:37 -0600

Thanks to a lack of coordination between kernel and glibc folks,
it has been impossible to mix code using <linux/in.h> and
<net/in.h> for some time now. On at least RHEL 6, <linux/if_bridge.h>
tries to use the kernel side, and fails due to our desire to use
the glibc side elsewhere:
In file included from /usr/include/linux/if_bridge.h:17,
from util/virnetdevbridge.c:42:
/usr/include/linux/in6.h:31: error: redefinition of ‘struct in6_addr’
/usr/include/linux/in6.h:48: error: redefinition of ‘struct sockaddr_in6’
/usr/include/linux/in6.h:56: error: redefinition of ‘struct ipv6_mreq’
Thankfully, the kernel layout of these structs is ABI-compatible,
they only differ in the type system presented to the C compiler.
While there are other versions of kernel headers that avoid the
problem, it is easier to just work around the issue than to expect
all developers to upgrade to working kernel headers.
* src/util/virnetdevbridge.c (includes): Coerce the kernel version
of in.h to not collide with the normal version.
Signed-off-by: Eric Blake <eblake redhat com>
---
Tested on RHEL 6.4 and Fedora 19, and pushing under the build-breaker
rule.
src/util/virnetdevbridge.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c
index ae9276c..5d52e23 100644
--- a/src/util/virnetdevbridge.c
+++ b/src/util/virnetdevbridge.c
@@ -39,7 +39,18 @@
#ifdef __linux__
# include <linux/sockios.h>
# include <linux/param.h> /* HZ */
+/* Depending on the version of kernel vs. glibc, there may be a collision
+ * between <net/in.h> and kernel IPv6 structures. The different types
+ * are ABI compatible, but choke the C type system; work around it by
+ * using temporary redefinitions. */
+# define in6_addr in6_addr_
+# define sockaddr_in6 sockaddr_in6_
+# define ipv6_mreq ipv6_mreq_
+# include <linux/in6.h>
# include <linux/if_bridge.h> /* SYSFS_BRIDGE_ATTR */
+# undef in6_addr
+# undef sockaddr_in6
+# undef ipv6_mreq
# define JIFFIES_TO_MS(j) (((j)*1000)/HZ)
# define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000)
--
1.7.1