]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
3e72e7e14247ca054ae8b73af9cafe3087e59598
[thirdparty/kernel/stable-queue.git] /
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
7
8 From: Mikko Rapeli <mikko.rapeli@iki.fi>
9
10 [ Upstream commit 4a91cb61bb995e5571098188092e296192309c77 ]
11
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.
18
19 This patch fixes compile errors when glibc net/if.h is included before
20 linux/if.h:
21
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’
41
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
44 code as a workaround.
45
46 This change was tested in x86 userspace on Debian unstable with
47 scripts/headers_compile_test.sh:
48
49 $ make headers_install && \
50 cd usr/include && ../../scripts/headers_compile_test.sh -l -k
51 ...
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
54
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>
63 ---
64 include/uapi/linux/if.h | 28 ++++++++++++++++++++++++
65 include/uapi/linux/libc-compat.h | 44 +++++++++++++++++++++++++++++++++++++++
66 2 files changed, 72 insertions(+)
67
68 --- a/include/uapi/linux/if.h
69 +++ b/include/uapi/linux/if.h
70 @@ -19,14 +19,20 @@
71 #ifndef _LINUX_IF_H
72 #define _LINUX_IF_H
73
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 */
78
79 +#if __UAPI_DEF_IF_IFNAMSIZ
80 #define IFNAMSIZ 16
81 +#endif /* __UAPI_DEF_IF_IFNAMSIZ */
82 #define IFALIASZ 256
83 #include <linux/hdlc/ioctl.h>
84
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
88 /**
89 * enum net_device_flags - &struct net_device flags
90 *
91 @@ -68,6 +74,8 @@
92 * @IFF_ECHO: echo sent packets. Volatile.
93 */
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 */
110 };
111 +#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 && __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0 */
112
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 */
123 +
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 */
129
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.
134 */
135
136 +/* for compatibility with glibc net/if.h */
137 +#if __UAPI_DEF_IF_IFMAP
138 struct ifmap {
139 unsigned long mem_start;
140 unsigned long mem_end;
141 @@ -175,6 +195,7 @@ struct ifmap {
142 unsigned char port;
143 /* 3 bytes spare */
144 };
145 +#endif /* __UAPI_DEF_IF_IFMAP */
146
147 struct if_settings {
148 unsigned int type; /* Type of physical device or protocol */
149 @@ -200,6 +221,8 @@ struct if_settings {
150 * remainder may be interface specific.
151 */
152
153 +/* for compatibility with glibc net/if.h */
154 +#if __UAPI_DEF_IF_IFREQ
155 struct ifreq {
156 #define IFHWADDRLEN 6
157 union
158 @@ -223,6 +246,7 @@ struct ifreq {
159 struct if_settings ifru_settings;
160 } ifr_ifru;
161 };
162 +#endif /* __UAPI_DEF_IF_IFREQ */
163
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).
168 */
169
170 +/* for compatibility with glibc net/if.h */
171 +#if __UAPI_DEF_IF_IFCONF
172 struct ifconf {
173 int ifc_len; /* size of buffer */
174 union {
175 @@ -256,6 +282,8 @@ struct ifconf {
176 struct ifreq __user *ifcu_req;
177 } ifc_ifcu;
178 };
179 +#endif /* __UAPI_DEF_IF_IFCONF */
180 +
181 #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
182 #define ifc_req ifc_ifcu.ifcu_req /* array of structures */
183
184 --- a/include/uapi/linux/libc-compat.h
185 +++ b/include/uapi/linux/libc-compat.h
186 @@ -51,6 +51,40 @@
187 /* We have included glibc headers... */
188 #if defined(__GLIBC__)
189
190 +/* Coordinate with glibc net/if.h header. */
191 +#if defined(_NET_IF_H)
192 +
193 +/* GLIBC headers included first so don't define anything
194 + * that would already be defined. */
195 +
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 */
206 +
207 +#else /* _NET_IF_H */
208 +
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. */
212 +
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
221 +
222 +#endif /* _NET_IF_H */
223 +
224 /* Coordinate with glibc netinet/in.h header. */
225 #if defined(_NETINET_IN_H)
226
227 @@ -117,6 +151,16 @@
228 * that we need. */
229 #else /* !defined(__GLIBC__) */
230
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
240 +
241 /* Definitions for in.h */
242 #define __UAPI_DEF_IN_ADDR 1
243 #define __UAPI_DEF_IN_IPPROTO 1