This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[COMMITTED] Fix linux/in6.h and netinet/in.h coordination (Bug 20214)
- From: Carlos O'Donell <carlos at redhat dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Tue, 7 Jun 2016 04:48:33 -0400
- Subject: [COMMITTED] Fix linux/in6.h and netinet/in.h coordination (Bug 20214)
- Authentication-results: sourceware.org; auth=none
In: https://sourceware.org/glibc/wiki/Synchronizing_Headers
we explain how we synchronize our headers with Linux kernel
headers.
In order to synchronize with the Linux linux/in6.h and
linux/ipv6.h headers we checked for their guard macros and
then defined __USE_KERNEL_IPV6_DEFS and conditionalized code
on this macro.
In upstream kernel 56c176c9 the _UAPI prefix was stripped and
this broke our synchronized headers again. We now need to check
for _LINUX_IN6_H and _IPV6_H, and keep checking the old versions
of the header guard checks for maximum backwards compatibility
with older Linux headers (the history is actually a bit muddled
here and it appears upstream linus kernel broke this 10 months
*before* our fix was ever applied to glibc, but without glibc
testing we didn't notice and distro kernels have their own
testing to fix this).
The use cases fixed by this patch are:
#include <linux/in6.h>
#include <netinet/in.h>
* Standard set of failures.
~~~
../inet/netinet/in.h:101:5: error: expected identifier before numeric constant
IPPROTO_HOPOPTS = 0, /* IPv6 Hop-by-Hop options. */
^
In file included from ../include/netinet/in.h:3:0,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../inet/netinet/in.h:102:0: error: "IPPROTO_HOPOPTS" redefined [-Werror]
#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:131:0: note: this is the location of the previous definition
#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */
^
In file included from ../include/netinet/in.h:3:0,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../inet/netinet/in.h:104:0: error: "IPPROTO_ROUTING" redefined [-Werror]
#define IPPROTO_ROUTING IPPROTO_ROUTING
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:132:0: note: this is the location of the previous definition
#define IPPROTO_ROUTING 43 /* IPv6 routing header */
^
In file included from ../include/netinet/in.h:3:0,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../inet/netinet/in.h:106:0: error: "IPPROTO_FRAGMENT" redefined [-Werror]
#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:133:0: note: this is the location of the previous definition
#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */
^
In file included from ../include/netinet/in.h:3:0,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../inet/netinet/in.h:108:0: error: "IPPROTO_ICMPV6" redefined [-Werror]
#define IPPROTO_ICMPV6 IPPROTO_ICMPV6
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:134:0: note: this is the location of the previous definition
#define IPPROTO_ICMPV6 58 /* ICMPv6 */
^
In file included from ../include/netinet/in.h:3:0,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../inet/netinet/in.h:110:0: error: "IPPROTO_NONE" redefined [-Werror]
#define IPPROTO_NONE IPPROTO_NONE
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:135:0: note: this is the location of the previous definition
#define IPPROTO_NONE 59 /* IPv6 no next header */
^
In file included from ../include/netinet/in.h:3:0,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../inet/netinet/in.h:112:0: error: "IPPROTO_DSTOPTS" redefined [-Werror]
#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:136:0: note: this is the location of the previous definition
#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */
^
In file included from ../include/netinet/in.h:3:0,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../inet/netinet/in.h:114:0: error: "IPPROTO_MH" redefined [-Werror]
#define IPPROTO_MH IPPROTO_MH
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:137:0: note: this is the location of the previous definition
#define IPPROTO_MH 135 /* IPv6 mobility header */
^
In file included from ../include/netinet/in.h:3:0,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../inet/netinet/in.h:211:8: error: redefinition of âstruct in6_addrâ
struct in6_addr
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:32:8: note: originally defined here
struct in6_addr {
^
In file included from ../include/netinet/in.h:3:0,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../inet/netinet/in.h:221:0: error: "s6_addr" redefined [-Werror]
#define s6_addr __in6_u.__u6_addr8
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:40:0: note: this is the location of the previous definition
#define s6_addr in6_u.u6_addr8
^
In file included from ../include/netinet/in.h:3:0,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../inet/netinet/in.h:223:0: error: "s6_addr16" redefined [-Werror]
# define s6_addr16 __in6_u.__u6_addr16
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:42:0: note: this is the location of the previous definition
#define s6_addr16 in6_u.u6_addr16
^
In file included from ../include/netinet/in.h:3:0,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../inet/netinet/in.h:224:0: error: "s6_addr32" redefined [-Werror]
# define s6_addr32 __in6_u.__u6_addr32
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:43:0: note: this is the location of the previous definition
#define s6_addr32 in6_u.u6_addr32
^
In file included from ../include/netinet/in.h:3:0,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../inet/netinet/in.h:254:8: error: redefinition of âstruct sockaddr_in6â
struct sockaddr_in6
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:49:8: note: originally defined here
struct sockaddr_in6 {
^
In file included from ../include/netinet/in.h:3:0,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../inet/netinet/in.h:290:8: error: redefinition of âstruct ipv6_mreqâ
struct ipv6_mreq
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:59:8: note: originally defined here
struct ipv6_mreq {
^
cc1: all warnings being treated as errors
~~~
* New set of failures related to IPV6_ADD_MEMBERSHIP and IPV6_DROP_MEMBERSHIP:
~~~~
In file included from ../inet/netinet/in.h:37:0,
from ../include/netinet/in.h:3,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../sysdeps/unix/sysv/linux/bits/in.h:218:0: error: "IPV6_ADD_MEMBERSHIP" redefined [-Werror]
# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:169:0: note: this is the location of the previous definition
#define IPV6_ADD_MEMBERSHIP 20
^
In file included from ../inet/netinet/in.h:37:0,
from ../include/netinet/in.h:3,
from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:2:
../sysdeps/unix/sysv/linux/bits/in.h:219:0: error: "IPV6_DROP_MEMBERSHIP" redefined [-Werror]
# define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
^
In file included from ../sysdeps/unix/sysv/linux//tst-ipv6-compat2.c:1:0:
/home/carlos/build/glibc-headers/include/linux/in6.h:170:0: note: this is the location of the previous definition
#define IPV6_DROP_MEMBERSHIP 21
^
cc1: all warnings being treated as errors
~~~~
Notice that in the case of xattr.h the Linux kernel headers
define the __USE_KERNEL_* macro themselves for glibc to use.
This has the added benefit of not needing consistent guard
macro names, just a consistent __USE_KERNEL_* macro name.
Sadly it's just a simple define, and doesn't set the value
of the macro to 0 or 1 (as it should to avoid typos).
Even if we wanted to do this also for linux/in6.h and
linux/ipv6.h, we would still need to support older headers
and define the value ourselves. Therefore the point is moot
but we should look to using a method like this for glibc
and linux with each side defining a __USE_LIBC_* and a
__USE_KERNEL_* feature macros respectively defined to 0
or 1 which avoids guard changes and complex conditionals
duplicated. I will look at proposing something like this.
Passes reg tests based on tests-compile support [1].
Committed.
--
Cheers,
Carlos.
[1] https://www.sourceware.org/ml/libc-alpha/2016-06/msg00162.html
2016-06-07 Carlos O'Donell <carlos@redhat.com>
[BZ #20214]
* sysdeps/unix/sysv/linux/bits/in.h
[defined _UAPI_LINUX_IN6_H || defined _UAPI_IPV6_H
|| defined _LINUX_IN6_H || defined _IPV6_H] (__USE_KERNEL_IPV6_DEFS):
Define to 1.
[!(defined _UAPI_LINUX_IN6_H || defined _UAPI_IPV6_H
|| defined _LINUX_IN6_H || defined _IPV6_H)] (__USE_KERNEL_IPV6_DEFS):
Define to 0.
[!__USE_KERNEL_IPV6_DEFS] (IPV6_ADD_MEMBERSHIP): Define.
[!__USE_KERNEL_IPV6_DEFS] (IPV6_DROP_MEMBERSHIP): Define.
diff --git a/sysdeps/unix/sysv/linux/bits/in.h b/sysdeps/unix/sysv/linux/bits/in.h
index 9bdadf3..4d70a6b 100644
--- a/sysdeps/unix/sysv/linux/bits/in.h
+++ b/sysdeps/unix/sysv/linux/bits/in.h
@@ -25,8 +25,14 @@
kernel then we will not define the IPv6 IPPROTO_* defines, in6_addr (nor the
defines), sockaddr_in6, or ipv6_mreq. Same for in6_ptkinfo or ip6_mtuinfo
in linux/ipv6.h. The ABI used by the linux-kernel and glibc match exactly.
- Neither the linux kernel nor glibc should break this ABI without coordination. */
-#if defined _UAPI_LINUX_IN6_H || defined _UAPI_IPV6_H
+ Neither the linux kernel nor glibc should break this ABI without coordination.
+ In upstream kernel 56c176c9 the _UAPI prefix was stripped so we need to check
+ for _LINUX_IN6_H and _IPV6_H now, and keep checking the old versions for
+ maximum backwards compatibility. */
+#if defined _UAPI_LINUX_IN6_H \
+ || defined _UAPI_IPV6_H \
+ || defined _LINUX_IN6_H \
+ || defined _IPV6_H
/* This is not quite the same API since the kernel always defines s6_addr16 and
s6_addr32. This is not a violation of POSIX since POSIX says "at least the
following member" and that holds true. */
@@ -209,8 +215,10 @@ struct in_pktinfo
#define IPV6_TCLASS 67
/* Obsolete synonyms for the above. */
-#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
-#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
+#if !__USE_KERNEL_IPV6_DEFS
+# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
+# define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
+#endif
#define IPV6_RXHOPOPTS IPV6_HOPOPTS
#define IPV6_RXDSTOPTS IPV6_DSTOPTS