1 From foo@baz Mon May 16 11:21:32 PDT 2016
2 From: Mikko Rapeli <mikko.rapeli@iki.fi>
3 Date: Sun, 24 Apr 2016 17:45:00 +0200
4 Subject: uapi glibc compat: fix compile errors when glibc net/if.h included before linux/if.h MIME-Version: 1.0
5 Content-Type: text/plain; charset=UTF-8
6 Content-Transfer-Encoding: 8bit
8 From: Mikko Rapeli <mikko.rapeli@iki.fi>
10 [ Upstream commit 4a91cb61bb995e5571098188092e296192309c77 ]
12 glibc's net/if.h contains copies of definitions from linux/if.h and these
13 conflict and cause build failures if both files are included by application
14 source code. Changes in uapi headers, which fixed header file dependencies to
15 include linux/if.h when it was needed, e.g. commit 1ffad83d, made the
16 net/if.h and linux/if.h incompatibilities visible as build failures for
17 userspace applications like iproute2 and xtables-addons.
19 This patch fixes compile errors when glibc net/if.h is included before
22 ./linux/if.h:99:21: error: redeclaration of enumerator ‘IFF_NOARP’
23 ./linux/if.h:98:23: error: redeclaration of enumerator ‘IFF_RUNNING’
24 ./linux/if.h:97:26: error: redeclaration of enumerator ‘IFF_NOTRAILERS’
25 ./linux/if.h:96:27: error: redeclaration of enumerator ‘IFF_POINTOPOINT’
26 ./linux/if.h:95:24: error: redeclaration of enumerator ‘IFF_LOOPBACK’
27 ./linux/if.h:94:21: error: redeclaration of enumerator ‘IFF_DEBUG’
28 ./linux/if.h:93:25: error: redeclaration of enumerator ‘IFF_BROADCAST’
29 ./linux/if.h:92:19: error: redeclaration of enumerator ‘IFF_UP’
30 ./linux/if.h:252:8: error: redefinition of ‘struct ifconf’
31 ./linux/if.h:203:8: error: redefinition of ‘struct ifreq’
32 ./linux/if.h:169:8: error: redefinition of ‘struct ifmap’
33 ./linux/if.h:107:23: error: redeclaration of enumerator ‘IFF_DYNAMIC’
34 ./linux/if.h:106:25: error: redeclaration of enumerator ‘IFF_AUTOMEDIA’
35 ./linux/if.h:105:23: error: redeclaration of enumerator ‘IFF_PORTSEL’
36 ./linux/if.h:104:25: error: redeclaration of enumerator ‘IFF_MULTICAST’
37 ./linux/if.h:103:21: error: redeclaration of enumerator ‘IFF_SLAVE’
38 ./linux/if.h:102:22: error: redeclaration of enumerator ‘IFF_MASTER’
39 ./linux/if.h:101:24: error: redeclaration of enumerator ‘IFF_ALLMULTI’
40 ./linux/if.h:100:23: error: redeclaration of enumerator ‘IFF_PROMISC’
42 The cases where linux/if.h is included before net/if.h need a similar fix in
43 the glibc side, or the order of include files can be changed userspace
46 This change was tested in x86 userspace on Debian unstable with
47 scripts/headers_compile_test.sh:
49 $ make headers_install && \
50 cd usr/include && ../../scripts/headers_compile_test.sh -l -k
52 cc -Wall -c -nostdinc -I /usr/lib/gcc/i586-linux-gnu/5/include -I /usr/lib/gcc/i586-linux-gnu/5/include-fixed -I . -I /home/mcfrisk/src/linux-2.6/usr/headers_compile_test_include.2uX2zH -I /home/mcfrisk/src/linux-2.6/usr/headers_compile_test_include.2uX2zH/i586-linux-gnu -o /dev/null ./linux/if.h_libc_before_kernel.h
53 PASSED libc before kernel test: ./linux/if.h
55 Reported-by: Jan Engelhardt <jengelh@inai.de>
56 Reported-by: Josh Boyer <jwboyer@fedoraproject.org>
57 Reported-by: Stephen Hemminger <shemming@brocade.com>
58 Reported-by: Waldemar Brodkorb <mail@waldemar-brodkorb.de>
59 Cc: Gabriel Laskar <gabriel@lse.epita.fr>
60 Signed-off-by: Mikko Rapeli <mikko.rapeli@iki.fi>
61 Signed-off-by: David S. Miller <davem@davemloft.net>
62 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
64 include/uapi/linux/if.h | 28 ++++++++++++++++++++++++
65 include/uapi/linux/libc-compat.h | 44 +++++++++++++++++++++++++++++++++++++++
66 2 files changed, 72 insertions(+)
68 --- a/include/uapi/linux/if.h
69 +++ b/include/uapi/linux/if.h
74 +#include <linux/libc-compat.h> /* for compatibility with glibc */
75 #include <linux/types.h> /* for "__kernel_caddr_t" et al */
76 #include <linux/socket.h> /* for "struct sockaddr" et al */
77 #include <linux/compiler.h> /* for "__user" et al */
79 +#if __UAPI_DEF_IF_IFNAMSIZ
81 +#endif /* __UAPI_DEF_IF_IFNAMSIZ */
83 #include <linux/hdlc/ioctl.h>
85 +/* For glibc compatibility. An empty enum does not compile. */
86 +#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 && \
87 + __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0
89 * enum net_device_flags - &struct net_device flags
92 * @IFF_ECHO: echo sent packets. Volatile.
94 enum net_device_flags {
95 +/* for compatibility with glibc net/if.h */
96 +#if __UAPI_DEF_IF_NET_DEVICE_FLAGS
97 IFF_UP = 1<<0, /* sysfs */
98 IFF_BROADCAST = 1<<1, /* volatile */
99 IFF_DEBUG = 1<<2, /* sysfs */
100 @@ -84,11 +92,17 @@ enum net_device_flags {
101 IFF_PORTSEL = 1<<13, /* sysfs */
102 IFF_AUTOMEDIA = 1<<14, /* sysfs */
103 IFF_DYNAMIC = 1<<15, /* sysfs */
104 +#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS */
105 +#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
106 IFF_LOWER_UP = 1<<16, /* volatile */
107 IFF_DORMANT = 1<<17, /* volatile */
108 IFF_ECHO = 1<<18, /* volatile */
109 +#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
111 +#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 && __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0 */
113 +/* for compatibility with glibc net/if.h */
114 +#if __UAPI_DEF_IF_NET_DEVICE_FLAGS
115 #define IFF_UP IFF_UP
116 #define IFF_BROADCAST IFF_BROADCAST
117 #define IFF_DEBUG IFF_DEBUG
118 @@ -105,9 +119,13 @@ enum net_device_flags {
119 #define IFF_PORTSEL IFF_PORTSEL
120 #define IFF_AUTOMEDIA IFF_AUTOMEDIA
121 #define IFF_DYNAMIC IFF_DYNAMIC
122 +#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS */
124 +#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
125 #define IFF_LOWER_UP IFF_LOWER_UP
126 #define IFF_DORMANT IFF_DORMANT
127 #define IFF_ECHO IFF_ECHO
128 +#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
130 #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\
131 IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
132 @@ -166,6 +184,8 @@ enum {
133 * being very small might be worth keeping for clean configuration.
136 +/* for compatibility with glibc net/if.h */
137 +#if __UAPI_DEF_IF_IFMAP
139 unsigned long mem_start;
140 unsigned long mem_end;
141 @@ -175,6 +195,7 @@ struct ifmap {
145 +#endif /* __UAPI_DEF_IF_IFMAP */
148 unsigned int type; /* Type of physical device or protocol */
149 @@ -200,6 +221,8 @@ struct if_settings {
150 * remainder may be interface specific.
153 +/* for compatibility with glibc net/if.h */
154 +#if __UAPI_DEF_IF_IFREQ
156 #define IFHWADDRLEN 6
158 @@ -223,6 +246,7 @@ struct ifreq {
159 struct if_settings ifru_settings;
162 +#endif /* __UAPI_DEF_IF_IFREQ */
164 #define ifr_name ifr_ifrn.ifrn_name /* interface name */
165 #define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
166 @@ -249,6 +273,8 @@ struct ifreq {
167 * must know all networks accessible).
170 +/* for compatibility with glibc net/if.h */
171 +#if __UAPI_DEF_IF_IFCONF
173 int ifc_len; /* size of buffer */
175 @@ -256,6 +282,8 @@ struct ifconf {
176 struct ifreq __user *ifcu_req;
179 +#endif /* __UAPI_DEF_IF_IFCONF */
181 #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
182 #define ifc_req ifc_ifcu.ifcu_req /* array of structures */
184 --- a/include/uapi/linux/libc-compat.h
185 +++ b/include/uapi/linux/libc-compat.h
187 /* We have included glibc headers... */
188 #if defined(__GLIBC__)
190 +/* Coordinate with glibc net/if.h header. */
191 +#if defined(_NET_IF_H)
193 +/* GLIBC headers included first so don't define anything
194 + * that would already be defined. */
196 +#define __UAPI_DEF_IF_IFCONF 0
197 +#define __UAPI_DEF_IF_IFMAP 0
198 +#define __UAPI_DEF_IF_IFNAMSIZ 0
199 +#define __UAPI_DEF_IF_IFREQ 0
200 +/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
201 +#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 0
202 +/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
203 +#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
204 +#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
205 +#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
207 +#else /* _NET_IF_H */
209 +/* Linux headers included first, and we must define everything
210 + * we need. The expectation is that glibc will check the
211 + * __UAPI_DEF_* defines and adjust appropriately. */
213 +#define __UAPI_DEF_IF_IFCONF 1
214 +#define __UAPI_DEF_IF_IFMAP 1
215 +#define __UAPI_DEF_IF_IFNAMSIZ 1
216 +#define __UAPI_DEF_IF_IFREQ 1
217 +/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
218 +#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
219 +/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
220 +#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
222 +#endif /* _NET_IF_H */
224 /* Coordinate with glibc netinet/in.h header. */
225 #if defined(_NETINET_IN_H)
229 #else /* !defined(__GLIBC__) */
231 +/* Definitions for if.h */
232 +#define __UAPI_DEF_IF_IFCONF 1
233 +#define __UAPI_DEF_IF_IFMAP 1
234 +#define __UAPI_DEF_IF_IFNAMSIZ 1
235 +#define __UAPI_DEF_IF_IFREQ 1
236 +/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
237 +#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
238 +/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
239 +#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
241 /* Definitions for in.h */
242 #define __UAPI_DEF_IN_ADDR 1
243 #define __UAPI_DEF_IN_IPPROTO 1