1 /* 2 * Compatibility interface for userspace libc header coordination: 3 * 4 * Define compatibility macros that are used to control the inclusion or 5 * exclusion of UAPI structures and definitions in coordination with another 6 * userspace C library. 7 * 8 * This header is intended to solve the problem of UAPI definitions that 9 * conflict with userspace definitions. If a UAPI header has such conflicting 10 * definitions then the solution is as follows: 11 * 12 * * Synchronize the UAPI header and the libc headers so either one can be 13 * used and such that the ABI is preserved. If this is not possible then 14 * no simple compatibility interface exists (you need to write translating 15 * wrappers and rename things) and you can't use this interface. 16 * 17 * Then follow this process: 18 * 19 * (a) Include libc-compat.h in the UAPI header. 20 * e.g. #include <linux/libc-compat.h> 21 * This include must be as early as possible. 22 * 23 * (b) In libc-compat.h add enough code to detect that the comflicting 24 * userspace libc header has been included first. 25 * 26 * (c) If the userspace libc header has been included first define a set of 27 * guard macros of the form __UAPI_DEF_FOO and set their values to 1, else 28 * set their values to 0. 29 * 30 * (d) Back in the UAPI header with the conflicting definitions, guard the 31 * definitions with: 32 * #if __UAPI_DEF_FOO 33 * ... 34 * #endif 35 * 36 * This fixes the situation where the linux headers are included *after* the 37 * libc headers. To fix the problem with the inclusion in the other order the 38 * userspace libc headers must be fixed like this: 39 * 40 * * For all definitions that conflict with kernel definitions wrap those 41 * defines in the following: 42 * #if !__UAPI_DEF_FOO 43 * ... 44 * #endif 45 * 46 * This prevents the redefinition of a construct already defined by the kernel. 47 */ 48 #ifndef _UAPI_LIBC_COMPAT_H 49 #define _UAPI_LIBC_COMPAT_H 50 51 /* We have included glibc headers... */ 52 #if defined(__GLIBC__) 53 54 /* Coordinate with glibc net/if.h header. */ 55 #if defined(_NET_IF_H) && defined(__USE_MISC) 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 88 /* Coordinate with glibc netinet/in.h header. */ 89 #if defined(_NETINET_IN_H) 90 91 /* GLIBC headers included first so don't define anything 92 * that would already be defined. */ 93 #define __UAPI_DEF_IN_ADDR 0 94 #define __UAPI_DEF_IN_IPPROTO 0 95 #define __UAPI_DEF_IN_PKTINFO 0 96 #define __UAPI_DEF_IP_MREQ 0 97 #define __UAPI_DEF_SOCKADDR_IN 0 98 #define __UAPI_DEF_IN_CLASS 0 99 100 #define __UAPI_DEF_IN6_ADDR 0 101 /* The exception is the in6_addr macros which must be defined 102 * if the glibc code didn't define them. This guard matches 103 * the guard in glibc/inet/netinet/in.h which defines the 104 * additional in6_addr macros e.g. s6_addr16, and s6_addr32. */ 105 #if defined(__USE_MISC) || defined (__USE_GNU) 106 #define __UAPI_DEF_IN6_ADDR_ALT 0 107 #else 108 #define __UAPI_DEF_IN6_ADDR_ALT 1 109 #endif 110 #define __UAPI_DEF_SOCKADDR_IN6 0 111 #define __UAPI_DEF_IPV6_MREQ 0 112 #define __UAPI_DEF_IPPROTO_V6 0 113 #define __UAPI_DEF_IPV6_OPTIONS 0 114 #define __UAPI_DEF_IN6_PKTINFO 0 115 #define __UAPI_DEF_IP6_MTUINFO 0 116 117 #else 118 119 /* Linux headers included first, and we must define everything 120 * we need. The expectation is that glibc will check the 121 * __UAPI_DEF_* defines and adjust appropriately. */ 122 #define __UAPI_DEF_IN_ADDR 1 123 #define __UAPI_DEF_IN_IPPROTO 1 124 #define __UAPI_DEF_IN_PKTINFO 1 125 #define __UAPI_DEF_IP_MREQ 1 126 #define __UAPI_DEF_SOCKADDR_IN 1 127 #define __UAPI_DEF_IN_CLASS 1 128 129 #define __UAPI_DEF_IN6_ADDR 1 130 /* We unconditionally define the in6_addr macros and glibc must 131 * coordinate. */ 132 #define __UAPI_DEF_IN6_ADDR_ALT 1 133 #define __UAPI_DEF_SOCKADDR_IN6 1 134 #define __UAPI_DEF_IPV6_MREQ 1 135 #define __UAPI_DEF_IPPROTO_V6 1 136 #define __UAPI_DEF_IPV6_OPTIONS 1 137 #define __UAPI_DEF_IN6_PKTINFO 1 138 #define __UAPI_DEF_IP6_MTUINFO 1 139 140 #endif /* _NETINET_IN_H */ 141 142 /* Coordinate with glibc netipx/ipx.h header. */ 143 #if defined(__NETIPX_IPX_H) 144 145 #define __UAPI_DEF_SOCKADDR_IPX 0 146 #define __UAPI_DEF_IPX_ROUTE_DEFINITION 0 147 #define __UAPI_DEF_IPX_INTERFACE_DEFINITION 0 148 #define __UAPI_DEF_IPX_CONFIG_DATA 0 149 #define __UAPI_DEF_IPX_ROUTE_DEF 0 150 151 #else /* defined(__NETIPX_IPX_H) */ 152 153 #define __UAPI_DEF_SOCKADDR_IPX 1 154 #define __UAPI_DEF_IPX_ROUTE_DEFINITION 1 155 #define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1 156 #define __UAPI_DEF_IPX_CONFIG_DATA 1 157 #define __UAPI_DEF_IPX_ROUTE_DEF 1 158 159 #endif /* defined(__NETIPX_IPX_H) */ 160 161 /* Definitions for xattr.h */ 162 #if defined(_SYS_XATTR_H) 163 #define __UAPI_DEF_XATTR 0 164 #else 165 #define __UAPI_DEF_XATTR 1 166 #endif 167 168 /* If we did not see any headers from any supported C libraries, 169 * or we are being included in the kernel, then define everything 170 * that we need. */ 171 #else /* !defined(__GLIBC__) */ 172 173 /* Definitions for if.h */ 174 #define __UAPI_DEF_IF_IFCONF 1 175 #define __UAPI_DEF_IF_IFMAP 1 176 #define __UAPI_DEF_IF_IFNAMSIZ 1 177 #define __UAPI_DEF_IF_IFREQ 1 178 /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */ 179 #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1 180 /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ 181 #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 182 183 /* Definitions for in.h */ 184 #define __UAPI_DEF_IN_ADDR 1 185 #define __UAPI_DEF_IN_IPPROTO 1 186 #define __UAPI_DEF_IN_PKTINFO 1 187 #define __UAPI_DEF_IP_MREQ 1 188 #define __UAPI_DEF_SOCKADDR_IN 1 189 #define __UAPI_DEF_IN_CLASS 1 190 191 /* Definitions for in6.h */ 192 #define __UAPI_DEF_IN6_ADDR 1 193 #define __UAPI_DEF_IN6_ADDR_ALT 1 194 #define __UAPI_DEF_SOCKADDR_IN6 1 195 #define __UAPI_DEF_IPV6_MREQ 1 196 #define __UAPI_DEF_IPPROTO_V6 1 197 #define __UAPI_DEF_IPV6_OPTIONS 1 198 #define __UAPI_DEF_IN6_PKTINFO 1 199 #define __UAPI_DEF_IP6_MTUINFO 1 200 201 /* Definitions for ipx.h */ 202 #define __UAPI_DEF_SOCKADDR_IPX 1 203 #define __UAPI_DEF_IPX_ROUTE_DEFINITION 1 204 #define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1 205 #define __UAPI_DEF_IPX_CONFIG_DATA 1 206 #define __UAPI_DEF_IPX_ROUTE_DEF 1 207 208 /* Definitions for xattr.h */ 209 #define __UAPI_DEF_XATTR 1 210 211 #endif /* __GLIBC__ */ 212 213 #endif /* _UAPI_LIBC_COMPAT_H */ 214