aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikko Rapeli <mikko.rapeli@iki.fi>2016-04-24 11:45:00 -0400
committerDavid S. Miller <davem@davemloft.net>2016-05-09 21:29:31 -0400
commit4a91cb61bb995e5571098188092e296192309c77 (patch)
treeea2bf572fe524d6c1fc5030f748b76da06bef04e
parentb507146bb6b9ac0c0197100ba3e299825a21fed3 (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.h28
-rw-r--r--include/uapi/linux/libc-compat.h44
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 */
70enum net_device_flags { 76enum 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
169struct ifmap { 189struct 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
179struct if_settings { 200struct 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
203struct ifreq { 226struct 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
252struct ifconf { 278struct 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