aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@redhat.com>2013-08-15 05:28:10 -0400
committerDavid S. Miller <davem@davemloft.net>2013-09-04 13:12:43 -0400
commitcfd280c91253cc28e4919e349fa7a813b63e71e8 (patch)
tree282754a6992ab65ea105827e14867ca796f72a15
parent42a5a5c128ad33fe25867b838a4dade127b57aee (diff)
net: sync some IP headers with glibc
Solution: ========= - Synchronize linux's `include/uapi/linux/in6.h' with glibc's `inet/netinet/in.h'. - Synchronize glibc's `inet/netinet/in.h with linux's `include/uapi/linux/in6.h'. - Allow including the headers in either other. - First header included defines the structures and macros. Details: ======== The kernel promises not to break the UAPI ABI so I don't see why we can't just have the two userspace headers coordinate? If you include the kernel headers first you get those, and if you include the glibc headers first you get those, and the following patch arranges a coordination and synchronization between the two. Let's handle `include/uapi/linux/in6.h' from linux, and `inet/netinet/in.h' from glibc and ensure they compile in any order and preserve the required ABI. These two patches pass the following compile tests: cat >> test1.c <<EOF int main (void) { return 0; } EOF gcc -c test1.c cat >> test2.c <<EOF int main (void) { return 0; } EOF gcc -c test2.c One wrinkle is that the kernel has a different name for one of the members in ipv6_mreq. In the kernel patch we create a macro to cover the uses of the old name, and while that's not entirely clean it's one of the best solutions (aside from an anonymous union which has other issues). I've reviewed the code and it looks to me like the ABI is assured and everything matches on both sides. Notes: - You want netinet/in.h to include bits/in.h as early as possible, but it needs in_addr so define in_addr early. - You want bits/in.h included as early as possible so you can use the linux specific code to define __USE_KERNEL_DEFS based on the _UAPI_* macro definition and use those to cull in.h. - glibc was missing IPPROTO_MH, added here. Compile tested and inspected. Reported-by: Thomas Backlund <tmb@mageia.org> Cc: Thomas Backlund <tmb@mageia.org> Cc: libc-alpha@sourceware.org Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Cc: David S. Miller <davem@davemloft.net> Tested-by: Cong Wang <amwang@redhat.com> Signed-off-by: Carlos O'Donell <carlos@redhat.com> Signed-off-by: Cong Wang <amwang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/uapi/linux/Kbuild1
-rw-r--r--include/uapi/linux/in.h49
-rw-r--r--include/uapi/linux/in6.h36
-rw-r--r--include/uapi/linux/libc-compat.h103
4 files changed, 169 insertions, 20 deletions
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 997f9f2f0963..e7c94eeb9475 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -227,6 +227,7 @@ header-y += kvm_para.h
227endif 227endif
228 228
229header-y += l2tp.h 229header-y += l2tp.h
230header-y += libc-compat.h
230header-y += limits.h 231header-y += limits.h
231header-y += llc.h 232header-y += llc.h
232header-y += loop.h 233header-y += loop.h
diff --git a/include/uapi/linux/in.h b/include/uapi/linux/in.h
index 9edb441df827..f9e8e496ae5d 100644
--- a/include/uapi/linux/in.h
+++ b/include/uapi/linux/in.h
@@ -24,30 +24,53 @@
24/* Standard well-defined IP protocols. */ 24/* Standard well-defined IP protocols. */
25enum { 25enum {
26 IPPROTO_IP = 0, /* Dummy protocol for TCP */ 26 IPPROTO_IP = 0, /* Dummy protocol for TCP */
27#define IPPROTO_IP IPPROTO_IP
27 IPPROTO_ICMP = 1, /* Internet Control Message Protocol */ 28 IPPROTO_ICMP = 1, /* Internet Control Message Protocol */
29#define IPPROTO_ICMP IPPROTO_ICMP
28 IPPROTO_IGMP = 2, /* Internet Group Management Protocol */ 30 IPPROTO_IGMP = 2, /* Internet Group Management Protocol */
31#define IPPROTO_IGMP IPPROTO_IGMP
29 IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */ 32 IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
33#define IPPROTO_IPIP IPPROTO_IPIP
30 IPPROTO_TCP = 6, /* Transmission Control Protocol */ 34 IPPROTO_TCP = 6, /* Transmission Control Protocol */
35#define IPPROTO_TCP IPPROTO_TCP
31 IPPROTO_EGP = 8, /* Exterior Gateway Protocol */ 36 IPPROTO_EGP = 8, /* Exterior Gateway Protocol */
37#define IPPROTO_EGP IPPROTO_EGP
32 IPPROTO_PUP = 12, /* PUP protocol */ 38 IPPROTO_PUP = 12, /* PUP protocol */
39#define IPPROTO_PUP IPPROTO_PUP
33 IPPROTO_UDP = 17, /* User Datagram Protocol */ 40 IPPROTO_UDP = 17, /* User Datagram Protocol */
41#define IPPROTO_UDP IPPROTO_UDP
34 IPPROTO_IDP = 22, /* XNS IDP protocol */ 42 IPPROTO_IDP = 22, /* XNS IDP protocol */
43#define IPPROTO_IDP IPPROTO_IDP
44 IPPROTO_TP = 29, /* SO Transport Protocol Class 4 */
45#define IPPROTO_TP IPPROTO_TP
35 IPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */ 46 IPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
36 IPPROTO_RSVP = 46, /* RSVP protocol */ 47#define IPPROTO_DCCP IPPROTO_DCCP
48 IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
49#define IPPROTO_IPV6 IPPROTO_IPV6
50 IPPROTO_RSVP = 46, /* RSVP Protocol */
51#define IPPROTO_RSVP IPPROTO_RSVP
37 IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */ 52 IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
38 53#define IPPROTO_GRE IPPROTO_GRE
39 IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */ 54 IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */
40 55#define IPPROTO_ESP IPPROTO_ESP
41 IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */ 56 IPPROTO_AH = 51, /* Authentication Header protocol */
42 IPPROTO_AH = 51, /* Authentication Header protocol */ 57#define IPPROTO_AH IPPROTO_AH
43 IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ 58 IPPROTO_MTP = 92, /* Multicast Transport Protocol */
44 IPPROTO_PIM = 103, /* Protocol Independent Multicast */ 59#define IPPROTO_MTP IPPROTO_MTP
45 60 IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */
46 IPPROTO_COMP = 108, /* Compression Header protocol */ 61#define IPPROTO_BEETPH IPPROTO_BEETPH
47 IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */ 62 IPPROTO_ENCAP = 98, /* Encapsulation Header */
63#define IPPROTO_ENCAP IPPROTO_ENCAP
64 IPPROTO_PIM = 103, /* Protocol Independent Multicast */
65#define IPPROTO_PIM IPPROTO_PIM
66 IPPROTO_COMP = 108, /* Compression Header Protocol */
67#define IPPROTO_COMP IPPROTO_COMP
68 IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */
69#define IPPROTO_SCTP IPPROTO_SCTP
48 IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */ 70 IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
49 71#define IPPROTO_UDPLITE IPPROTO_UDPLITE
50 IPPROTO_RAW = 255, /* Raw IP packets */ 72 IPPROTO_RAW = 255, /* Raw IP packets */
73#define IPPROTO_RAW IPPROTO_RAW
51 IPPROTO_MAX 74 IPPROTO_MAX
52}; 75};
53 76
diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h
index 53b1d56a6e7f..440d5c479145 100644
--- a/include/uapi/linux/in6.h
+++ b/include/uapi/linux/in6.h
@@ -22,22 +22,30 @@
22#define _UAPI_LINUX_IN6_H 22#define _UAPI_LINUX_IN6_H
23 23
24#include <linux/types.h> 24#include <linux/types.h>
25#include <linux/libc-compat.h>
25 26
26/* 27/*
27 * IPv6 address structure 28 * IPv6 address structure
28 */ 29 */
29 30
31#if __UAPI_DEF_IN6_ADDR
30struct in6_addr { 32struct in6_addr {
31 union { 33 union {
32 __u8 u6_addr8[16]; 34 __u8 u6_addr8[16];
35#if __UAPI_DEF_IN6_ADDR_ALT
33 __be16 u6_addr16[8]; 36 __be16 u6_addr16[8];
34 __be32 u6_addr32[4]; 37 __be32 u6_addr32[4];
38#endif
35 } in6_u; 39 } in6_u;
36#define s6_addr in6_u.u6_addr8 40#define s6_addr in6_u.u6_addr8
41#if __UAPI_DEF_IN6_ADDR_ALT
37#define s6_addr16 in6_u.u6_addr16 42#define s6_addr16 in6_u.u6_addr16
38#define s6_addr32 in6_u.u6_addr32 43#define s6_addr32 in6_u.u6_addr32
44#endif
39}; 45};
46#endif /* __UAPI_DEF_IN6_ADDR */
40 47
48#if __UAPI_DEF_SOCKADDR_IN6
41struct sockaddr_in6 { 49struct sockaddr_in6 {
42 unsigned short int sin6_family; /* AF_INET6 */ 50 unsigned short int sin6_family; /* AF_INET6 */
43 __be16 sin6_port; /* Transport layer port # */ 51 __be16 sin6_port; /* Transport layer port # */
@@ -45,7 +53,9 @@ struct sockaddr_in6 {
45 struct in6_addr sin6_addr; /* IPv6 address */ 53 struct in6_addr sin6_addr; /* IPv6 address */
46 __u32 sin6_scope_id; /* scope id (new in RFC2553) */ 54 __u32 sin6_scope_id; /* scope id (new in RFC2553) */
47}; 55};
56#endif /* __UAPI_DEF_SOCKADDR_IN6 */
48 57
58#if __UAPI_DEF_IPV6_MREQ
49struct ipv6_mreq { 59struct ipv6_mreq {
50 /* IPv6 multicast address of group */ 60 /* IPv6 multicast address of group */
51 struct in6_addr ipv6mr_multiaddr; 61 struct in6_addr ipv6mr_multiaddr;
@@ -53,6 +63,7 @@ struct ipv6_mreq {
53 /* local IPv6 address of interface */ 63 /* local IPv6 address of interface */
54 int ipv6mr_ifindex; 64 int ipv6mr_ifindex;
55}; 65};
66#endif /* __UAPI_DEF_IVP6_MREQ */
56 67
57#define ipv6mr_acaddr ipv6mr_multiaddr 68#define ipv6mr_acaddr ipv6mr_multiaddr
58 69
@@ -114,13 +125,24 @@ struct in6_flowlabel_req {
114/* 125/*
115 * IPV6 extension headers 126 * IPV6 extension headers
116 */ 127 */
117#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */ 128#if __UAPI_DEF_IPPROTO_V6
118#define IPPROTO_ROUTING 43 /* IPv6 routing header */ 129enum {
119#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ 130 IPPROTO_HOPOPTS = 0, /* IPv6 hop-by-hop options */
120#define IPPROTO_ICMPV6 58 /* ICMPv6 */ 131#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS
121#define IPPROTO_NONE 59 /* IPv6 no next header */ 132 IPPROTO_ROUTING = 43, /* IPv6 routing header */
122#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ 133#define IPPROTO_ROUTING IPPROTO_ROUTING
123#define IPPROTO_MH 135 /* IPv6 mobility header */ 134 IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header */
135#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT
136 IPPROTO_ICMPV6 = 58, /* ICMPv6 */
137#define IPPROTO_ICMPV6 IPPROTO_ICMPV6
138 IPPROTO_NONE = 59, /* IPv6 no next header */
139#define IPPROTO_NONE IPPROTO_NONE
140 IPPROTO_DSTOPTS = 60, /* IPv6 destination options */
141#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS
142 IPPROTO_MH = 135, /* IPv6 mobility header */
143#define IPPROTO_MH IPPROTO_MH
144};
145#endif /* __UAPI_DEF_IPPROTO_V6 */
124 146
125/* 147/*
126 * IPv6 TLV options. 148 * IPv6 TLV options.
diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h
new file mode 100644
index 000000000000..335e8a7cad39
--- /dev/null
+++ b/include/uapi/linux/libc-compat.h
@@ -0,0 +1,103 @@
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 netinet/in.h header. */
55#if defined(_NETINET_IN_H)
56
57/* GLIBC headers included first so don't define anything
58 * that would already be defined. */
59#define __UAPI_DEF_IN6_ADDR 0
60/* The exception is the in6_addr macros which must be defined
61 * if the glibc code didn't define them. This guard matches
62 * the guard in glibc/inet/netinet/in.h which defines the
63 * additional in6_addr macros e.g. s6_addr16, and s6_addr32. */
64#if defined(__USE_MISC) || defined (__USE_GNU)
65#define __UAPI_DEF_IN6_ADDR_ALT 0
66#else
67#define __UAPI_DEF_IN6_ADDR_ALT 1
68#endif
69#define __UAPI_DEF_SOCKADDR_IN6 0
70#define __UAPI_DEF_IPV6_MREQ 0
71#define __UAPI_DEF_IPPROTO_V6 0
72
73#else
74
75/* Linux headers included first, and we must define everything
76 * we need. The expectation is that glibc will check the
77 * __UAPI_DEF_* defines and adjust appropriately. */
78#define __UAPI_DEF_IN6_ADDR 1
79/* We unconditionally define the in6_addr macros and glibc must
80 * coordinate. */
81#define __UAPI_DEF_IN6_ADDR_ALT 1
82#define __UAPI_DEF_SOCKADDR_IN6 1
83#define __UAPI_DEF_IPV6_MREQ 1
84#define __UAPI_DEF_IPPROTO_V6 1
85
86#endif /* _NETINET_IN_H */
87
88
89/* If we did not see any headers from any supported C libraries,
90 * or we are being included in the kernel, then define everything
91 * that we need. */
92#else /* !defined(__GLIBC__) */
93
94/* Definitions for in6.h */
95#define __UAPI_DEF_IN6_ADDR 1
96#define __UAPI_DEF_IN6_ADDR_ALT 1
97#define __UAPI_DEF_SOCKADDR_IN6 1
98#define __UAPI_DEF_IPV6_MREQ 1
99#define __UAPI_DEF_IPPROTO_V6 1
100
101#endif /* __GLIBC__ */
102
103#endif /* _UAPI_LIBC_COMPAT_H */