diff options
author | Mikko Rapeli <mikko.rapeli@iki.fi> | 2016-04-24 11:45:00 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-09 21:29:31 -0400 |
commit | 4a91cb61bb995e5571098188092e296192309c77 (patch) | |
tree | ea2bf572fe524d6c1fc5030f748b76da06bef04e | |
parent | b507146bb6b9ac0c0197100ba3e299825a21fed3 (diff) |
uapi glibc compat: fix compile errors when glibc net/if.h included before linux/if.h
glibc's net/if.h contains copies of definitions from linux/if.h and these
conflict and cause build failures if both files are included by application
source code. Changes in uapi headers, which fixed header file dependencies to
include linux/if.h when it was needed, e.g. commit 1ffad83d, made the
net/if.h and linux/if.h incompatibilities visible as build failures for
userspace applications like iproute2 and xtables-addons.
This patch fixes compile errors when glibc net/if.h is included before
linux/if.h:
./linux/if.h:99:21: error: redeclaration of enumerator ‘IFF_NOARP’
./linux/if.h:98:23: error: redeclaration of enumerator ‘IFF_RUNNING’
./linux/if.h:97:26: error: redeclaration of enumerator ‘IFF_NOTRAILERS’
./linux/if.h:96:27: error: redeclaration of enumerator ‘IFF_POINTOPOINT’
./linux/if.h:95:24: error: redeclaration of enumerator ‘IFF_LOOPBACK’
./linux/if.h:94:21: error: redeclaration of enumerator ‘IFF_DEBUG’
./linux/if.h:93:25: error: redeclaration of enumerator ‘IFF_BROADCAST’
./linux/if.h:92:19: error: redeclaration of enumerator ‘IFF_UP’
./linux/if.h:252:8: error: redefinition of ‘struct ifconf’
./linux/if.h:203:8: error: redefinition of ‘struct ifreq’
./linux/if.h:169:8: error: redefinition of ‘struct ifmap’
./linux/if.h:107:23: error: redeclaration of enumerator ‘IFF_DYNAMIC’
./linux/if.h:106:25: error: redeclaration of enumerator ‘IFF_AUTOMEDIA’
./linux/if.h:105:23: error: redeclaration of enumerator ‘IFF_PORTSEL’
./linux/if.h:104:25: error: redeclaration of enumerator ‘IFF_MULTICAST’
./linux/if.h:103:21: error: redeclaration of enumerator ‘IFF_SLAVE’
./linux/if.h:102:22: error: redeclaration of enumerator ‘IFF_MASTER’
./linux/if.h:101:24: error: redeclaration of enumerator ‘IFF_ALLMULTI’
./linux/if.h:100:23: error: redeclaration of enumerator ‘IFF_PROMISC’
The cases where linux/if.h is included before net/if.h need a similar fix in
the glibc side, or the order of include files can be changed userspace
code as a workaround.
This change was tested in x86 userspace on Debian unstable with
scripts/headers_compile_test.sh:
$ make headers_install && \
cd usr/include && ../../scripts/headers_compile_test.sh -l -k
...
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
PASSED libc before kernel test: ./linux/if.h
Reported-by: Jan Engelhardt <jengelh@inai.de>
Reported-by: Josh Boyer <jwboyer@fedoraproject.org>
Reported-by: Stephen Hemminger <shemming@brocade.com>
Reported-by: Waldemar Brodkorb <mail@waldemar-brodkorb.de>
Cc: Gabriel Laskar <gabriel@lse.epita.fr>
Signed-off-by: Mikko Rapeli <mikko.rapeli@iki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/uapi/linux/if.h | 28 | ||||
-rw-r--r-- | include/uapi/linux/libc-compat.h | 44 |
2 files changed, 72 insertions, 0 deletions
diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h index f80277569f24..e601c8c3bdc7 100644 --- a/include/uapi/linux/if.h +++ b/include/uapi/linux/if.h | |||
@@ -19,14 +19,20 @@ | |||
19 | #ifndef _LINUX_IF_H | 19 | #ifndef _LINUX_IF_H |
20 | #define _LINUX_IF_H | 20 | #define _LINUX_IF_H |
21 | 21 | ||
22 | #include <linux/libc-compat.h> /* for compatibility with glibc */ | ||
22 | #include <linux/types.h> /* for "__kernel_caddr_t" et al */ | 23 | #include <linux/types.h> /* for "__kernel_caddr_t" et al */ |
23 | #include <linux/socket.h> /* for "struct sockaddr" et al */ | 24 | #include <linux/socket.h> /* for "struct sockaddr" et al */ |
24 | #include <linux/compiler.h> /* for "__user" et al */ | 25 | #include <linux/compiler.h> /* for "__user" et al */ |
25 | 26 | ||
27 | #if __UAPI_DEF_IF_IFNAMSIZ | ||
26 | #define IFNAMSIZ 16 | 28 | #define IFNAMSIZ 16 |
29 | #endif /* __UAPI_DEF_IF_IFNAMSIZ */ | ||
27 | #define IFALIASZ 256 | 30 | #define IFALIASZ 256 |
28 | #include <linux/hdlc/ioctl.h> | 31 | #include <linux/hdlc/ioctl.h> |
29 | 32 | ||
33 | /* For glibc compatibility. An empty enum does not compile. */ | ||
34 | #if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 && \ | ||
35 | __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0 | ||
30 | /** | 36 | /** |
31 | * enum net_device_flags - &struct net_device flags | 37 | * enum net_device_flags - &struct net_device flags |
32 | * | 38 | * |
@@ -68,6 +74,8 @@ | |||
68 | * @IFF_ECHO: echo sent packets. Volatile. | 74 | * @IFF_ECHO: echo sent packets. Volatile. |
69 | */ | 75 | */ |
70 | enum net_device_flags { | 76 | enum net_device_flags { |
77 | /* for compatibility with glibc net/if.h */ | ||
78 | #if __UAPI_DEF_IF_NET_DEVICE_FLAGS | ||
71 | IFF_UP = 1<<0, /* sysfs */ | 79 | IFF_UP = 1<<0, /* sysfs */ |
72 | IFF_BROADCAST = 1<<1, /* volatile */ | 80 | IFF_BROADCAST = 1<<1, /* volatile */ |
73 | IFF_DEBUG = 1<<2, /* sysfs */ | 81 | IFF_DEBUG = 1<<2, /* sysfs */ |
@@ -84,11 +92,17 @@ enum net_device_flags { | |||
84 | IFF_PORTSEL = 1<<13, /* sysfs */ | 92 | IFF_PORTSEL = 1<<13, /* sysfs */ |
85 | IFF_AUTOMEDIA = 1<<14, /* sysfs */ | 93 | IFF_AUTOMEDIA = 1<<14, /* sysfs */ |
86 | IFF_DYNAMIC = 1<<15, /* sysfs */ | 94 | IFF_DYNAMIC = 1<<15, /* sysfs */ |
95 | #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS */ | ||
96 | #if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO | ||
87 | IFF_LOWER_UP = 1<<16, /* volatile */ | 97 | IFF_LOWER_UP = 1<<16, /* volatile */ |
88 | IFF_DORMANT = 1<<17, /* volatile */ | 98 | IFF_DORMANT = 1<<17, /* volatile */ |
89 | IFF_ECHO = 1<<18, /* volatile */ | 99 | IFF_ECHO = 1<<18, /* volatile */ |
100 | #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ | ||
90 | }; | 101 | }; |
102 | #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 && __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0 */ | ||
91 | 103 | ||
104 | /* for compatibility with glibc net/if.h */ | ||
105 | #if __UAPI_DEF_IF_NET_DEVICE_FLAGS | ||
92 | #define IFF_UP IFF_UP | 106 | #define IFF_UP IFF_UP |
93 | #define IFF_BROADCAST IFF_BROADCAST | 107 | #define IFF_BROADCAST IFF_BROADCAST |
94 | #define IFF_DEBUG IFF_DEBUG | 108 | #define IFF_DEBUG IFF_DEBUG |
@@ -105,9 +119,13 @@ enum net_device_flags { | |||
105 | #define IFF_PORTSEL IFF_PORTSEL | 119 | #define IFF_PORTSEL IFF_PORTSEL |
106 | #define IFF_AUTOMEDIA IFF_AUTOMEDIA | 120 | #define IFF_AUTOMEDIA IFF_AUTOMEDIA |
107 | #define IFF_DYNAMIC IFF_DYNAMIC | 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 | ||
108 | #define IFF_LOWER_UP IFF_LOWER_UP | 125 | #define IFF_LOWER_UP IFF_LOWER_UP |
109 | #define IFF_DORMANT IFF_DORMANT | 126 | #define IFF_DORMANT IFF_DORMANT |
110 | #define IFF_ECHO IFF_ECHO | 127 | #define IFF_ECHO IFF_ECHO |
128 | #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ | ||
111 | 129 | ||
112 | #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\ | 130 | #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\ |
113 | IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) | 131 | IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) |
@@ -166,6 +184,8 @@ enum { | |||
166 | * being very small might be worth keeping for clean configuration. | 184 | * being very small might be worth keeping for clean configuration. |
167 | */ | 185 | */ |
168 | 186 | ||
187 | /* for compatibility with glibc net/if.h */ | ||
188 | #if __UAPI_DEF_IF_IFMAP | ||
169 | struct ifmap { | 189 | struct ifmap { |
170 | unsigned long mem_start; | 190 | unsigned long mem_start; |
171 | unsigned long mem_end; | 191 | unsigned long mem_end; |
@@ -175,6 +195,7 @@ struct ifmap { | |||
175 | unsigned char port; | 195 | unsigned char port; |
176 | /* 3 bytes spare */ | 196 | /* 3 bytes spare */ |
177 | }; | 197 | }; |
198 | #endif /* __UAPI_DEF_IF_IFMAP */ | ||
178 | 199 | ||
179 | struct if_settings { | 200 | struct if_settings { |
180 | unsigned int type; /* Type of physical device or protocol */ | 201 | unsigned int type; /* Type of physical device or protocol */ |
@@ -200,6 +221,8 @@ struct if_settings { | |||
200 | * remainder may be interface specific. | 221 | * remainder may be interface specific. |
201 | */ | 222 | */ |
202 | 223 | ||
224 | /* for compatibility with glibc net/if.h */ | ||
225 | #if __UAPI_DEF_IF_IFREQ | ||
203 | struct ifreq { | 226 | struct ifreq { |
204 | #define IFHWADDRLEN 6 | 227 | #define IFHWADDRLEN 6 |
205 | union | 228 | union |
@@ -223,6 +246,7 @@ struct ifreq { | |||
223 | struct if_settings ifru_settings; | 246 | struct if_settings ifru_settings; |
224 | } ifr_ifru; | 247 | } ifr_ifru; |
225 | }; | 248 | }; |
249 | #endif /* __UAPI_DEF_IF_IFREQ */ | ||
226 | 250 | ||
227 | #define ifr_name ifr_ifrn.ifrn_name /* interface name */ | 251 | #define ifr_name ifr_ifrn.ifrn_name /* interface name */ |
228 | #define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ | 252 | #define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ |
@@ -249,6 +273,8 @@ struct ifreq { | |||
249 | * must know all networks accessible). | 273 | * must know all networks accessible). |
250 | */ | 274 | */ |
251 | 275 | ||
276 | /* for compatibility with glibc net/if.h */ | ||
277 | #if __UAPI_DEF_IF_IFCONF | ||
252 | struct ifconf { | 278 | struct ifconf { |
253 | int ifc_len; /* size of buffer */ | 279 | int ifc_len; /* size of buffer */ |
254 | union { | 280 | union { |
@@ -256,6 +282,8 @@ struct ifconf { | |||
256 | struct ifreq __user *ifcu_req; | 282 | struct ifreq __user *ifcu_req; |
257 | } ifc_ifcu; | 283 | } ifc_ifcu; |
258 | }; | 284 | }; |
285 | #endif /* __UAPI_DEF_IF_IFCONF */ | ||
286 | |||
259 | #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ | 287 | #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ |
260 | #define ifc_req ifc_ifcu.ifcu_req /* array of structures */ | 288 | #define ifc_req ifc_ifcu.ifcu_req /* array of structures */ |
261 | 289 | ||
diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h index 7d024ceb075d..d5e38c73377c 100644 --- a/include/uapi/linux/libc-compat.h +++ b/include/uapi/linux/libc-compat.h | |||
@@ -51,6 +51,40 @@ | |||
51 | /* We have included glibc headers... */ | 51 | /* We have included glibc headers... */ |
52 | #if defined(__GLIBC__) | 52 | #if defined(__GLIBC__) |
53 | 53 | ||
54 | /* Coordinate with glibc net/if.h header. */ | ||
55 | #if defined(_NET_IF_H) | ||
56 | |||
57 | /* GLIBC headers included first so don't define anything | ||
58 | * that would already be defined. */ | ||
59 | |||
60 | #define __UAPI_DEF_IF_IFCONF 0 | ||
61 | #define __UAPI_DEF_IF_IFMAP 0 | ||
62 | #define __UAPI_DEF_IF_IFNAMSIZ 0 | ||
63 | #define __UAPI_DEF_IF_IFREQ 0 | ||
64 | /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */ | ||
65 | #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 0 | ||
66 | /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ | ||
67 | #ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO | ||
68 | #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 | ||
69 | #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ | ||
70 | |||
71 | #else /* _NET_IF_H */ | ||
72 | |||
73 | /* Linux headers included first, and we must define everything | ||
74 | * we need. The expectation is that glibc will check the | ||
75 | * __UAPI_DEF_* defines and adjust appropriately. */ | ||
76 | |||
77 | #define __UAPI_DEF_IF_IFCONF 1 | ||
78 | #define __UAPI_DEF_IF_IFMAP 1 | ||
79 | #define __UAPI_DEF_IF_IFNAMSIZ 1 | ||
80 | #define __UAPI_DEF_IF_IFREQ 1 | ||
81 | /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */ | ||
82 | #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1 | ||
83 | /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ | ||
84 | #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 | ||
85 | |||
86 | #endif /* _NET_IF_H */ | ||
87 | |||
54 | /* Coordinate with glibc netinet/in.h header. */ | 88 | /* Coordinate with glibc netinet/in.h header. */ |
55 | #if defined(_NETINET_IN_H) | 89 | #if defined(_NETINET_IN_H) |
56 | 90 | ||
@@ -117,6 +151,16 @@ | |||
117 | * that we need. */ | 151 | * that we need. */ |
118 | #else /* !defined(__GLIBC__) */ | 152 | #else /* !defined(__GLIBC__) */ |
119 | 153 | ||
154 | /* Definitions for if.h */ | ||
155 | #define __UAPI_DEF_IF_IFCONF 1 | ||
156 | #define __UAPI_DEF_IF_IFMAP 1 | ||
157 | #define __UAPI_DEF_IF_IFNAMSIZ 1 | ||
158 | #define __UAPI_DEF_IF_IFREQ 1 | ||
159 | /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */ | ||
160 | #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1 | ||
161 | /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ | ||
162 | #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 | ||
163 | |||
120 | /* Definitions for in.h */ | 164 | /* Definitions for in.h */ |
121 | #define __UAPI_DEF_IN_ADDR 1 | 165 | #define __UAPI_DEF_IN_ADDR 1 |
122 | #define __UAPI_DEF_IN_IPPROTO 1 | 166 | #define __UAPI_DEF_IN_IPPROTO 1 |