Skip to content

Commit cfd280c

Browse files
codonelldavem330
authored andcommitted
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>
1 parent 42a5a5c commit cfd280c

File tree

4 files changed

+169
-20
lines changed

4 files changed

+169
-20
lines changed

include/uapi/linux/Kbuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ header-y += kvm_para.h
227227
endif
228228

229229
header-y += l2tp.h
230+
header-y += libc-compat.h
230231
header-y += limits.h
231232
header-y += llc.h
232233
header-y += loop.h

include/uapi/linux/in.h

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,53 @@
2424
/* Standard well-defined IP protocols. */
2525
enum {
2626
IPPROTO_IP = 0, /* Dummy protocol for TCP */
27+
#define IPPROTO_IP IPPROTO_IP
2728
IPPROTO_ICMP = 1, /* Internet Control Message Protocol */
29+
#define IPPROTO_ICMP IPPROTO_ICMP
2830
IPPROTO_IGMP = 2, /* Internet Group Management Protocol */
31+
#define IPPROTO_IGMP IPPROTO_IGMP
2932
IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
33+
#define IPPROTO_IPIP IPPROTO_IPIP
3034
IPPROTO_TCP = 6, /* Transmission Control Protocol */
35+
#define IPPROTO_TCP IPPROTO_TCP
3136
IPPROTO_EGP = 8, /* Exterior Gateway Protocol */
37+
#define IPPROTO_EGP IPPROTO_EGP
3238
IPPROTO_PUP = 12, /* PUP protocol */
39+
#define IPPROTO_PUP IPPROTO_PUP
3340
IPPROTO_UDP = 17, /* User Datagram Protocol */
41+
#define IPPROTO_UDP IPPROTO_UDP
3442
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
3546
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
3752
IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
38-
39-
IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
40-
41-
IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */
42-
IPPROTO_AH = 51, /* Authentication Header protocol */
43-
IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */
44-
IPPROTO_PIM = 103, /* Protocol Independent Multicast */
45-
46-
IPPROTO_COMP = 108, /* Compression Header protocol */
47-
IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */
53+
#define IPPROTO_GRE IPPROTO_GRE
54+
IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */
55+
#define IPPROTO_ESP IPPROTO_ESP
56+
IPPROTO_AH = 51, /* Authentication Header protocol */
57+
#define IPPROTO_AH IPPROTO_AH
58+
IPPROTO_MTP = 92, /* Multicast Transport Protocol */
59+
#define IPPROTO_MTP IPPROTO_MTP
60+
IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */
61+
#define IPPROTO_BEETPH IPPROTO_BEETPH
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
4870
IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
49-
50-
IPPROTO_RAW = 255, /* Raw IP packets */
71+
#define IPPROTO_UDPLITE IPPROTO_UDPLITE
72+
IPPROTO_RAW = 255, /* Raw IP packets */
73+
#define IPPROTO_RAW IPPROTO_RAW
5174
IPPROTO_MAX
5275
};
5376

include/uapi/linux/in6.h

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,37 +22,48 @@
2222
#define _UAPI_LINUX_IN6_H
2323

2424
#include <linux/types.h>
25+
#include <linux/libc-compat.h>
2526

2627
/*
2728
* IPv6 address structure
2829
*/
2930

31+
#if __UAPI_DEF_IN6_ADDR
3032
struct in6_addr {
3133
union {
3234
__u8 u6_addr8[16];
35+
#if __UAPI_DEF_IN6_ADDR_ALT
3336
__be16 u6_addr16[8];
3437
__be32 u6_addr32[4];
38+
#endif
3539
} in6_u;
3640
#define s6_addr in6_u.u6_addr8
41+
#if __UAPI_DEF_IN6_ADDR_ALT
3742
#define s6_addr16 in6_u.u6_addr16
3843
#define s6_addr32 in6_u.u6_addr32
44+
#endif
3945
};
46+
#endif /* __UAPI_DEF_IN6_ADDR */
4047

48+
#if __UAPI_DEF_SOCKADDR_IN6
4149
struct sockaddr_in6 {
4250
unsigned short int sin6_family; /* AF_INET6 */
4351
__be16 sin6_port; /* Transport layer port # */
4452
__be32 sin6_flowinfo; /* IPv6 flow information */
4553
struct in6_addr sin6_addr; /* IPv6 address */
4654
__u32 sin6_scope_id; /* scope id (new in RFC2553) */
4755
};
56+
#endif /* __UAPI_DEF_SOCKADDR_IN6 */
4857

58+
#if __UAPI_DEF_IPV6_MREQ
4959
struct ipv6_mreq {
5060
/* IPv6 multicast address of group */
5161
struct in6_addr ipv6mr_multiaddr;
5262

5363
/* local IPv6 address of interface */
5464
int ipv6mr_ifindex;
5565
};
66+
#endif /* __UAPI_DEF_IVP6_MREQ */
5667

5768
#define ipv6mr_acaddr ipv6mr_multiaddr
5869

@@ -114,13 +125,24 @@ struct in6_flowlabel_req {
114125
/*
115126
* IPV6 extension headers
116127
*/
117-
#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */
118-
#define IPPROTO_ROUTING 43 /* IPv6 routing header */
119-
#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */
120-
#define IPPROTO_ICMPV6 58 /* ICMPv6 */
121-
#define IPPROTO_NONE 59 /* IPv6 no next header */
122-
#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */
123-
#define IPPROTO_MH 135 /* IPv6 mobility header */
128+
#if __UAPI_DEF_IPPROTO_V6
129+
enum {
130+
IPPROTO_HOPOPTS = 0, /* IPv6 hop-by-hop options */
131+
#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS
132+
IPPROTO_ROUTING = 43, /* IPv6 routing header */
133+
#define IPPROTO_ROUTING IPPROTO_ROUTING
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 */
124146

125147
/*
126148
* IPv6 TLV options.

include/uapi/linux/libc-compat.h

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 */

0 commit comments

Comments
 (0)