net: sync some IP headers with glibc
Subsystems (2)
PATCH v2 1/1 net: sync some IP headers with glibc
From: Carlos O'Donell <[email protected]>
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
#include <netinet/in.h>
#include <linux/in6.h>
int main (void) {
return 0;
}
EOF
gcc -c test1.c
cat >> test2.c <<EOF
#include <linux/in6.h>
#include <netinet/in.h>
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.
---
v2: reformat some comments
include/uapi/linux/Kbuild +1 -0
@@ -227,6 +227,7 @@ header-y += kvm_para.h endif header-y += l2tp.h +header-y += libc-compat.h header-y += limits.h header-y += llc.h header-y += loop.h
include/uapi/linux/in.h +36 -13
66 lines not on this page · raw message
include/uapi/linux/in6.h +29 -7
@@ -22,22 +22,30 @@#define _UAPI_LINUX_IN6_H#include <linux/types.h> +#include <linux/libc-compat.h> /* * IPv6 address structure */ +#if __UAPI_DEF_IN6_ADDRstruct in6_addr {union {__u8 u6_addr8[16 ]; +#if __UAPI_DEF_IN6_ADDR_ALT__be16 u6_addr16[8 ];__be32 u6_addr32[4 ]; +#endif } in6_u;#define s6_addr in6_u.u6_addr8 +#if __UAPI_DEF_IN6_ADDR_ALT#define s6_addr16 in6_u.u6_addr16#define s6_addr32 in6_u.u6_addr32 +#endif }; +#endif /* __UAPI_DEF_IN6_ADDR */ +#if __UAPI_DEF_SOCKADDR_IN6 struct sockaddr_in6 { unsigned short int sin6_family; /* AF_INET6 */ __be16 sin6_port; /* Transport layer port # */
@@ -45,7 +53,9 @@ struct sockaddr_in6 {struct in6_addr sin6_addr;/* IPv6 address */ __u32 sin6_scope_id;/* scope id (new in RFC2553) */ }; +#endif /* __UAPI_DEF_SOCKADDR_IN6 */ +#if __UAPI_DEF_IPV6_MREQ struct ipv6_mreq { /* IPv6 multicast address of group */ struct in6_addr ipv6mr_multiaddr;
@@ -53,6 +63,7 @@ struct ipv6_mreq {/* local IPv6 address of interface */ int ipv6mr_ifindex; }; +#endif /* __UAPI_DEF_IVP6_MREQ */ #define ipv6mr_acaddr ipv6mr_multiaddr
@@ -114,13 +125,24 @@ struct in6_flowlabel_req {/* * IPV6 extension headers */ -#define IPPROTO_HOPOPTS 0/* IPv6 hop-by-hop options */ -#define IPPROTO_ROUTING 43/* IPv6 routing header */ -#define IPPROTO_FRAGMENT 44/* IPv6 fragmentation header */ -#define IPPROTO_ICMPV6 58/* ICMPv6 */ -#define IPPROTO_NONE 59/* IPv6 no next header */ -#define IPPROTO_DSTOPTS 60/* IPv6 destination options */ -#define IPPROTO_MH 135/* IPv6 mobility header */ +#if __UAPI_DEF_IPPROTO_V6 +enum { +IPPROTO_HOPOPTS =0 ,/* IPv6 hop-by-hop options */ +#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS + IPPROTO_ROUTING = 43, /* IPv6 routing header */ +#define IPPROTO_ROUTING IPPROTO_ROUTING + IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header */ +#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT + IPPROTO_ICMPV6 = 58, /* ICMPv6 */ +#define IPPROTO_ICMPV6 IPPROTO_ICMPV6 + IPPROTO_NONE = 59, /* IPv6 no next header */ +#define IPPROTO_NONE IPPROTO_NONE + IPPROTO_DSTOPTS = 60, /* IPv6 destination options */ +#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS + IPPROTO_MH = 135, /* IPv6 mobility header */ +#define IPPROTO_MH IPPROTO_MH +}; +#endif /* __UAPI_DEF_IPPROTO_V6 */ /* * IPv6 TLV options.
include/uapi/linux/libc-compat.h new file +103 -0
103 lines not on this page · raw message
PATCH v2 1/1 inet: avoid redefinition of some structs in kernel
From: Carlos O'Donell <[email protected]>
- 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.
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.
2013-08-13 Carlos O'Donell <[email protected]>
Cong Wang <[email protected]>
* sysdeps/unix/sysv/linux/bits/in.h
[_UAPI_LINUX_IN6_H]: Define __USE_KERNEL_IPV6_DEFS.
* inet/netinet/in.h: Move in_addr definition and bits/in.h inclusion before __USE_KERNEL_IPV6_DEFS uses.
* inet/netinet/in.h [!__USE_KERNEL_IPV6_DEFS]: Define IPPROTO_MH, and IPPROTO_BEETPH.
[__USE_KERNEL_IPV6_DEFS]: Don't define any of IPPROTO_*, in6_addr, sockaddr_in6, or ipv6_mreq.
---
inet/netinet/in.h +40 -29
@@ -26,13 +26,21 @@__BEGIN_DECLS +/* Internet address. */ +typedef uint32_t in_addr_t; +struct in_addr + { +in_addr_t s_addr; + }; + +/* Get system-specific definitions. */ +#include <bits/in.h> +/* Standard well-defined IP protocols. */ enum {IPPROTO_IP =0 ,/* Dummy protocol for TCP. */ #define IPPROTO_IP IPPROTO_IP - IPPROTO_HOPOPTS = 0, /* IPv6 Hop-by-Hop options. */ -#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS IPPROTO_ICMP = 1, /* Internet Control Message Protocol. */#define IPPROTO_ICMP IPPROTO_ICMP IPPROTO_IGMP = 2, /* Internet Group Management Protocol. */
@@ -55,10 +63,6 @@ enum#define IPPROTO_DCCP IPPROTO_DCCP IPPROTO_IPV6 = 41, /* IPv6 header. */#define IPPROTO_IPV6 IPPROTO_IPV6 - IPPROTO_ROUTING = 43, /* IPv6 routing header. */ -#define IPPROTO_ROUTING IPPROTO_ROUTING - IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header. */ -#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT IPPROTO_RSVP = 46, /* Reservation Protocol. */#define IPPROTO_RSVP IPPROTO_RSVP IPPROTO_GRE = 47, /* General Routing Encapsulation. */
@@ -67,14 +71,10 @@ enum#define IPPROTO_ESP IPPROTO_ESP IPPROTO_AH = 51, /* authentication header. */#define IPPROTO_AH IPPROTO_AH - IPPROTO_ICMPV6 = 58, /* ICMPv6. */ -#define IPPROTO_ICMPV6 IPPROTO_ICMPV6 - IPPROTO_NONE = 59, /* IPv6 no next header. */ -#define IPPROTO_NONE IPPROTO_NONE - IPPROTO_DSTOPTS = 60, /* IPv6 destination options. */ -#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS IPPROTO_MTP = 92, /* Multicast Transport Protocol. */#define IPPROTO_MTP IPPROTO_MTP + IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET. */ +#define IPPROTO_BEETPH IPPROTO_BEETPH IPPROTO_ENCAP = 98, /* Encapsulation Header. */#define IPPROTO_ENCAP IPPROTO_ENCAP IPPROTO_PIM = 103, /* Protocol Independent Multicast. */
@@ -90,6 +90,28 @@ enumIPPROTO_MAX }; +/* If __USER_KERNEL_IPV6_DEFS is defined then the user has included the kernel +network headers first and we should use those ABI-identical definitions +instead of our own. */ +#ifndef __USE_KERNEL_IPV6_DEFS +enum + { +IPPROTO_HOPOPTS =0 ,/* IPv6 Hop-by-Hop options. */ +#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS + IPPROTO_ROUTING = 43, /* IPv6 routing header. */ +#define IPPROTO_ROUTING IPPROTO_ROUTING + IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header. */ +#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT + IPPROTO_ICMPV6 = 58, /* ICMPv6. */ +#define IPPROTO_ICMPV6 IPPROTO_ICMPV6 + IPPROTO_NONE = 59, /* IPv6 no next header. */ +#define IPPROTO_NONE IPPROTO_NONE + IPPROTO_DSTOPTS = 60, /* IPv6 destination options. */ +#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS + IPPROTO_MH = 135, /* IPv6 mobility header. */ +#define IPPROTO_MH IPPROTO_MH + }; +#endif /* !__USE_KERNEL_IPV6_DEFS */ /* Type to represent a port. */ typedef uint16_t in_port_t ;
@@ -134,15 +156,6 @@ enum IPPORT_USERRESERVED = 5000 }; - -/* Internet address. */ -typedef uint32_t in_addr_t ; -struct in_addr - { -in_addr_t s_addr; - }; - -/* Definitions of the bits in an Internet address integer. On subnets, host and network parts are found according to
@@ -191,7 +204,7 @@ struct in_addr#define INADDR_ALLRTRS_GROUP ((in_addr_t) 0xe0000002)/* 224.0.0.2 */ #define INADDR_MAX_LOCAL_GROUP ((in_addr_t) 0xe00000ff)/* 224.0.0.255 */ - +#ifndef __USE_KERNEL_IPV6_DEFS/* IPv6 address */ struct in6_addr {
@@ -209,6 +222,7 @@ struct in6_addr# define s6_addr32 __in6_u.__u6_addr32 #endif }; +#endif /* !__USE_KERNEL_IPV6_DEFS */ extern const struct in6_addr in6addr_any;/* :: */ extern const struct in6_addr in6addr_loopback;/* ::1 */
@@ -233,6 +247,7 @@ struct sockaddr_in sizeof (struct in_addr)]; }; +#ifndef __USE_KERNEL_IPV6_DEFS/* Ditto, for IPv6. */ struct sockaddr_in6 {
@@ -242,7 +257,7 @@ struct sockaddr_in6struct in6_addr sin6_addr;/* IPv6 address */ uint32_t sin6_scope_id; /* IPv6 scope-id */ }; - +#endif /* !__USE_KERNEL_IPV6_DEFS */ #if defined __USE_MISC || defined __USE_GNU/* IPv4 multicast request. */
@@ -268,7 +283,7 @@ struct ip_mreq_source };#endif - +#ifndef __USE_KERNEL_IPV6_DEFS/* Likewise, for IPv6. */ struct ipv6_mreq {
@@ -278,7 +293,7 @@ struct ipv6_mreq/* local interface */ unsigned int ipv6mr_interface; }; - +#endif /* !__USE_KERNEL_IPV6_DEFS */ #if defined __USE_MISC || defined __USE_GNU/* Multicast group request. */
@@ -349,10 +364,6 @@ struct group_filter * sizeof (struct sockaddr_storage)))#endif - -/* Get system-specific definitions. */ -#include <bits/in.h> -/* Functions to convert between host and network byte order. Please note that these functions normally take `unsigned long int' or
sysdeps/unix/sysv/linux/bits/in.h +12 -0
@@ -21,6 +21,18 @@# error "Never use <bits/in.h> directly; include <netinet/in.h> instead."#endif +/* If the application has already included linux/in6.h from a linux-based +kernel then we will not define the IPv6 IPPROTO_* defines, in6_addr (nor the +defines), sockaddr_in6, or ipv6_mreq. The ABI used by the linux-kernel and +glibc match exactly. Neither the linux kernel nor glibc should break this +ABI without coordination. */ +#ifdef _UAPI_LINUX_IN6_H +/* This is not quite the same API since the kernel always defines s6_addr16 and +s6_addr32. This is not a violation of POSIX since POSIX says "at least the +following member" and that holds true. */ +# define __USE_KERNEL_IPV6_DEFS +#endif +/* Options for use with `getsockopt' and `setsockopt' at the IP level. The first word in the comment at the right is the data type used; "bool" means a boolean value stored in an `int'. */
Re: [GLIBC Patch v2] inet: avoid redefinition of some structs in kernel
Quoted 9 lines · Cong Wang
From: Carlos O'Donell <[email protected]>
- Synchronize linux's
include/uapi/linux/in6.h' with glibc'sinet/netinet/in.h'.
- Synchronize glibc'sinet/netinet/in.h with linux'sinclude/uapi/linux/in6.h'.
- Allow including the headers in either other.
- First header included defines the structures and macros.
Quoted 7 lines
Notes:
- You wantnetinet/in.hto includebits/in.has early as possible, but it needsin_addrso definein_addrearly.
- You wantbits/in.hincluded as early as possible so you can use the linux specific code to define__USE_KERNEL_DEFSbased on the _UAPI_* macro definition and use those to cullin.h.
- glibc was missingIPPROTO_MH, added here.
Andreas,
Would you mind reviewing this?
I'd like an objective review from another senior glibc reviewer.
The goal here is simple, support including the kernel and glibc headers in any order and coordinate structure definitions to maintain the ABI.
The kernel headers often have structures and definitions that are required by specialized userspace applications, and we'd like those applications to be easy to write and maintain. Coordinate the headers is going to make this simpler for everyone.
Cheers,
Carlos.
Quoted 210 lines
Reported-by Thomas Backlund <[email protected]>Cc Thomas Backlund <[email protected]>Cc YOSHIFUJI Hideaki <[email protected]>Cc David S. Miller <[email protected]>Signed-off-by Carlos O'Donell <[email protected]>Tested-by Cong Wang <[email protected]>Signed-off-by Cong Wang <[email protected]>2013-08-13 Carlos O'Donell <[email protected]>
Cong Wang <[email protected]>*
sysdeps/unix/sysv/linux/bits/in.h
[_UAPI_LINUX_IN6_H]: Define__USE_KERNEL_IPV6_DEFS.
*inet/netinet/in.h: Movein_addrdefinition andbits/in.hinclusion before__USE_KERNEL_IPV6_DEFSuses.
*inet/netinet/in.h[!__USE_KERNEL_IPV6_DEFS]: DefineIPPROTO_MH, andIPPROTO_BEETPH.
[__USE_KERNEL_IPV6_DEFS]: Don't define any of IPPROTO_*,in6_addr,sockaddr_in6, oripv6_mreq.
---inet/netinet/in.h +40
-29@@ -26,13 +26,21 @@__BEGIN_DECLS +/* Internet address. */ +typedef uint32_t in_addr_t; +struct in_addr + { +in_addr_t s_addr; + }; + +/* Get system-specific definitions. */ +#include <bits/in.h> +/* Standard well-defined IP protocols. */ enum {IPPROTO_IP =0 ,/* Dummy protocol for TCP. */ #define IPPROTO_IP IPPROTO_IP - IPPROTO_HOPOPTS = 0, /* IPv6 Hop-by-Hop options. */ -#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS IPPROTO_ICMP = 1, /* Internet Control Message Protocol. */#define IPPROTO_ICMP IPPROTO_ICMP IPPROTO_IGMP = 2, /* Internet Group Management Protocol. */@@ -55,10 +63,6 @@ enum#define IPPROTO_DCCP IPPROTO_DCCP IPPROTO_IPV6 = 41, /* IPv6 header. */#define IPPROTO_IPV6 IPPROTO_IPV6 - IPPROTO_ROUTING = 43, /* IPv6 routing header. */ -#define IPPROTO_ROUTING IPPROTO_ROUTING - IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header. */ -#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT IPPROTO_RSVP = 46, /* Reservation Protocol. */#define IPPROTO_RSVP IPPROTO_RSVP IPPROTO_GRE = 47, /* General Routing Encapsulation. */@@ -67,14 +71,10 @@ enum#define IPPROTO_ESP IPPROTO_ESP IPPROTO_AH = 51, /* authentication header. */#define IPPROTO_AH IPPROTO_AH - IPPROTO_ICMPV6 = 58, /* ICMPv6. */ -#define IPPROTO_ICMPV6 IPPROTO_ICMPV6 - IPPROTO_NONE = 59, /* IPv6 no next header. */ -#define IPPROTO_NONE IPPROTO_NONE - IPPROTO_DSTOPTS = 60, /* IPv6 destination options. */ -#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS IPPROTO_MTP = 92, /* Multicast Transport Protocol. */#define IPPROTO_MTP IPPROTO_MTP + IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET. */ +#define IPPROTO_BEETPH IPPROTO_BEETPH IPPROTO_ENCAP = 98, /* Encapsulation Header. */#define IPPROTO_ENCAP IPPROTO_ENCAP IPPROTO_PIM = 103, /* Protocol Independent Multicast. */@@ -90,6 +90,28 @@ enumIPPROTO_MAX }; +/* If __USER_KERNEL_IPV6_DEFS is defined then the user has included the kernel +network headers first and we should use those ABI-identical definitions +instead of our own. */ +#ifndef __USE_KERNEL_IPV6_DEFS +enum + { +IPPROTO_HOPOPTS =0 ,/* IPv6 Hop-by-Hop options. */ +#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS + IPPROTO_ROUTING = 43, /* IPv6 routing header. */ +#define IPPROTO_ROUTING IPPROTO_ROUTING + IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header. */ +#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT + IPPROTO_ICMPV6 = 58, /* ICMPv6. */ +#define IPPROTO_ICMPV6 IPPROTO_ICMPV6 + IPPROTO_NONE = 59, /* IPv6 no next header. */ +#define IPPROTO_NONE IPPROTO_NONE + IPPROTO_DSTOPTS = 60, /* IPv6 destination options. */ +#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS + IPPROTO_MH = 135, /* IPv6 mobility header. */ +#define IPPROTO_MH IPPROTO_MH + }; +#endif /* !__USE_KERNEL_IPV6_DEFS */ /* Type to represent a port. */ typedef uint16_t in_port_t ;@@ -134,15 +156,6 @@ enum IPPORT_USERRESERVED = 5000 }; - -/* Internet address. */ -typedef uint32_t in_addr_t ; -struct in_addr - { -in_addr_t s_addr; - }; - -/* Definitions of the bits in an Internet address integer. On subnets, host and network parts are found according to @@ -191,7 +204,7 @@ struct in_addr#define INADDR_ALLRTRS_GROUP ((in_addr_t) 0xe0000002)/* 224.0.0.2 */ #define INADDR_MAX_LOCAL_GROUP ((in_addr_t) 0xe00000ff)/* 224.0.0.255 */ - +#ifndef __USE_KERNEL_IPV6_DEFS/* IPv6 address */ struct in6_addr {@@ -209,6 +222,7 @@ struct in6_addr# define s6_addr32 __in6_u.__u6_addr32 #endif }; +#endif /* !__USE_KERNEL_IPV6_DEFS */ extern const struct in6_addr in6addr_any;/* :: */ extern const struct in6_addr in6addr_loopback;/* ::1 */ @@ -233,6 +247,7 @@ struct sockaddr_in sizeof (struct in_addr)]; }; +#ifndef __USE_KERNEL_IPV6_DEFS/* Ditto, for IPv6. */ struct sockaddr_in6 {@@ -242,7 +257,7 @@ struct sockaddr_in6struct in6_addr sin6_addr;/* IPv6 address */ uint32_t sin6_scope_id; /* IPv6 scope-id */ }; - +#endif /* !__USE_KERNEL_IPV6_DEFS */ #if defined __USE_MISC || defined __USE_GNU/* IPv4 multicast request. */ @@ -268,7 +283,7 @@ struct ip_mreq_source };#endif - +#ifndef __USE_KERNEL_IPV6_DEFS/* Likewise, for IPv6. */ struct ipv6_mreq {@@ -278,7 +293,7 @@ struct ipv6_mreq/* local interface */ unsigned int ipv6mr_interface; }; - +#endif /* !__USE_KERNEL_IPV6_DEFS */ #if defined __USE_MISC || defined __USE_GNU/* Multicast group request. */ @@ -349,10 +364,6 @@ struct group_filter * sizeof (struct sockaddr_storage)))#endif - -/* Get system-specific definitions. */ -#include <bits/in.h> -/* Functions to convert between host and network byte order. Please note that these functions normally take `unsigned long int' or sysdeps/unix/sysv/linux/bits/in.h +12
-0@@ -21,6 +21,18 @@# error "Never use <bits/in.h> directly; include <netinet/in.h> instead."#endif +/* If the application has already included linux/in6.h from a linux-based +kernel then we will not define the IPv6 IPPROTO_* defines, in6_addr (nor the +defines), sockaddr_in6, or ipv6_mreq. The ABI used by the linux-kernel and +glibc match exactly. Neither the linux kernel nor glibc should break this +ABI without coordination. */ +#ifdef _UAPI_LINUX_IN6_H +/* This is not quite the same API since the kernel always defines s6_addr16 and +s6_addr32. This is not a violation of POSIX since POSIX says "at least the +following member" and that holds true. */ +# define __USE_KERNEL_IPV6_DEFS +#endif +/* Options for use with `getsockopt' and `setsockopt' at the IP level. The first word in the comment at the right is the data type used; "bool" means a boolean value stored in an `int'. */
Re: [GLIBC Patch v2] inet: avoid redefinition of some structs in kernel
In reply to Cong WangQuoted 8 lines · Cong Wang
From: Carlos O'Donell <[email protected]>
- Synchronize linux's
include/uapi/linux/in6.h' with glibc'sinet/netinet/in.h'.
- Synchronize glibc'sinet/netinet/in.h with linux'sinclude/uapi/linux/in6.h'.
- Allow including the headers in either other.
- First header included defines the structures and macros.
Let me first say that I really love where this is going and would love to see more of this work.
Will this work with older kernels as well? Meaning: Can I compile today's user land programs with a new glibc and Kernel 3.10? My reading of the patch assumes it does but I would like to hear that you tested it.
The patch itself looks fine, thanks,
Andreas
Signature · 4 lines
Andreas Jaeger aj@{suse.com,opensuse.org} Twitter/Identica: jaegerandi
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn,Jennifer Guild,Felix Imendörffer,HRB16746 (AG Nürnberg)
GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126Re: [GLIBC Patch v2] inet: avoid redefinition of some structs in kernel
Quoted 10 lines · Andreas Jaeger
Quoted 8 lines · Cong Wang
From: Carlos O'Donell <[email protected]>
- Synchronize linux's
include/uapi/linux/in6.h' with glibc'sinet/netinet/in.h'.
- Synchronize glibc'sinet/netinet/in.h with linux'sinclude/uapi/linux/in6.h'.
- Allow including the headers in either other.
- First header included defines the structures and macros.
Quoted 2 lines
Let me first say that I really love where this is going and would love to see more of this work.
The plan would be to eventually tackle more of the conflicting headers in a uniform way.
Quoted 3 lines
Will this work with older kernels as well? Meaning: Can I compile today's user land programs with a new glibc and Kernel 3.10? My reading of the patch assumes it does but I would like to hear that you tested it.
You can indeed take a new glibc, and a new kernel, and old programs that previously failed to compile will now work. The ABI is maintained and the headers coordinate.
I did not test this explicitly except through the small test case I wrote which permutes inclusion order and the use of various structures defined in the headers.
The only quibble one could have is with Linux. In that if you include the Linux headers first you will get more definitions than required by POSIX e.g. s6_addr16 and s6_add32. However as I note in the comment this is not a violation of POSIX since POSIX says "at least the following member" and that holds true.
Quoted 1 line
The patch itself looks fine, thanks,
Thanks for reviewing.
If the kernel patches get accepted I will check these into glibc 2.19 for Cong.
Cheers,
Carlos.
Re: [GLIBC Patch v2] inet: avoid redefinition of some structs in kernel
In reply to Cong WangQuoted 11 lines · Cong Wang
2013-08-13 Carlos O'Donell <[email protected]>
Cong Wang <[email protected]>*
sysdeps/unix/sysv/linux/bits/in.h
[_UAPI_LINUX_IN6_H]: Define__USE_KERNEL_IPV6_DEFS.
*inet/netinet/in.h: Movein_addrdefinition andbits/in.hinclusion before__USE_KERNEL_IPV6_DEFSuses.
*inet/netinet/in.h[!__USE_KERNEL_IPV6_DEFS]: DefineIPPROTO_MH, andIPPROTO_BEETPH.
[__USE_KERNEL_IPV6_DEFS]: Don't define any of IPPROTO_*,in6_addr,sockaddr_in6, oripv6_mreq.
Cong,
Given that this is a user visible change could you please file a glibc bugzilla bug in sourceware[1] so we can track the commit and so that future users can reopen the bug to discuss any defects?
Then you need to add the BZ# to the ChangeLog, and whomever commits this for you will mark it fixed in the NEWS. We should also write up a NEWS blurb for this since it's the first explicit header coordination of it's kind and we should highlight that so developers take note and help us coordinate more headers.
Cheers,
Carlos.
Re: [GLIBC Patch v2] inet: avoid redefinition of some structs in kernel
Quoted 13 lines · Carlos O'Donell
Quoted 11 lines · Cong Wang
2013-08-13 Carlos O'Donell <[email protected]>
Cong Wang <[email protected]>*
sysdeps/unix/sysv/linux/bits/in.h
[_UAPI_LINUX_IN6_H]: Define__USE_KERNEL_IPV6_DEFS.
*inet/netinet/in.h: Movein_addrdefinition andbits/in.hinclusion before__USE_KERNEL_IPV6_DEFSuses.
*inet/netinet/in.h[!__USE_KERNEL_IPV6_DEFS]: DefineIPPROTO_MH, andIPPROTO_BEETPH.
[__USE_KERNEL_IPV6_DEFS]: Don't define any of IPPROTO_*,in6_addr,sockaddr_in6, oripv6_mreq.
Quoted 5 lines
Cong,
Given that this is a user visible change could you please file a glibc bugzilla bug in sourceware[1] so we can track the commit and so that future users can reopen the bug to discuss any defects?
Done, http://sourceware.org/bugzilla/show_bug.cgi?id=15850
Quoted 7 lines
Then you need to add the BZ# to the ChangeLog, and whomever commits this for you will mark it fixed in the NEWS. We should also write up a NEWS blurb for this since it's the first explicit header coordination of it's kind and we should highlight that so developers take note and help us coordinate more headers.
Should I resend this patch with BZ# included?
Thanks!
Re: [GLIBC Patch v2] inet: avoid redefinition of some structs in kernel
Quoted 14 lines · Cong Wang
Quoted 13 lines · Carlos O'Donell
Quoted 11 lines · Cong Wang
2013-08-13 Carlos O'Donell <[email protected]>
Cong Wang <[email protected]>*
sysdeps/unix/sysv/linux/bits/in.h
[_UAPI_LINUX_IN6_H]: Define__USE_KERNEL_IPV6_DEFS.
*inet/netinet/in.h: Movein_addrdefinition andbits/in.hinclusion before__USE_KERNEL_IPV6_DEFSuses.
*inet/netinet/in.h[!__USE_KERNEL_IPV6_DEFS]: DefineIPPROTO_MH, andIPPROTO_BEETPH.
[__USE_KERNEL_IPV6_DEFS]: Don't define any of IPPROTO_*,in6_addr,sockaddr_in6, oripv6_mreq.
Quoted 7 lines
Quoted 5 lines
Cong,
Given that this is a user visible change could you please file a glibc bugzilla bug in sourceware[1] so we can track the commit and so that future users can reopen the bug to discuss any defects?
Perfect.
Quoted 9 lines
Quoted 7 lines
Then you need to add the BZ# to the ChangeLog, and whomever commits this for you will mark it fixed in the NEWS. We should also write up a NEWS blurb for this since it's the first explicit header coordination of it's kind and we should highlight that so developers take note and help us coordinate more headers.
Should I resend this patch with BZ# included?
No need. But the final ChangeLog should have the BZ# in it, and the committer will add it to the NEWS list of bugs fixed in 2.19.
Cheers,
Carlos.
Re: [GLIBC Patch v2] inet: avoid redefinition of some structs in kernel
In reply to Cong WangQuoted 9 lines · On Thursday 15 August 2013 05:28:11 Cong Wang wrote:
From: Carlos O'Donell <[email protected]>
- Synchronize linux's
include/uapi/linux/in6.h' with glibc'sinet/netinet/in.h'.
- Synchronize glibc'sinet/netinet/in.h with linux'sinclude/uapi/linux/in6.h'.
- Allow including the headers in either other.
- First header included defines the structures and macros.
Quoted 7 lines
Notes:
- You wantnetinet/in.hto includebits/in.has early as possible, but it needsin_addrso definein_addrearly.
- You wantbits/in.hincluded as early as possible so you can use the linux specific code to define__USE_KERNEL_DEFSbased on the _UAPI_* macro definition and use those to cullin.h.
- glibc was missingIPPROTO_MH, added here.
can we get something better documented here in a central location ? having the names laid out in a git commit message and in a few leaf headers does not lend itself to being easily discoverable.
-mike
Re: [GLIBC Patch v2] inet: avoid redefinition of some structs in kernel
Quoted 18 lines · Mike Frysinger
Quoted 9 lines · On Thursday 15 August 2013 05:28:11 Cong Wang wrote:
From: Carlos O'Donell <[email protected]>
- Synchronize linux's
include/uapi/linux/in6.h' with glibc'sinet/netinet/in.h'.
- Synchronize glibc'sinet/netinet/in.h with linux'sinclude/uapi/linux/in6.h'.
- Allow including the headers in either other.
- First header included defines the structures and macros.Quoted 7 lines
Notes:
- You wantnetinet/in.hto includebits/in.has early as possible, but it needsin_addrso definein_addrearly.
- You wantbits/in.hincluded as early as possible so you can use the linux specific code to define__USE_KERNEL_DEFSbased on the _UAPI_* macro definition and use those to cullin.h.
- glibc was missingIPPROTO_MH, added here.
Quoted 3 lines
can we get something better documented here in a central location ? having the names laid out in a git commit message and in a few leaf headers does not lend itself to being easily discoverable.
Care to suggest something?
Cheers,
Carlos.
From: Cong Wang <[email protected]>
Date: Thu, 15 Aug 2013 17:28:10 +0800
Quoted 9 lines
Solution:
=========- Synchronize linux's
include/uapi/linux/in6.h' with glibc'sinet/netinet/in.h'.
- Synchronize glibc'sinet/netinet/in.h with linux'sinclude/uapi/linux/in6.h'.
- Allow including the headers in either other.
- First header included defines the structures and macros.
Applied, thanks for being so patient. I want to spend the past few weeks making sure this is the right way to handle all of this and now I am confident that it is.
Thanks!
Quoted 13 lines · David Miller
From: Cong Wang <[email protected]>
Date: Thu, 15 Aug 2013 17:28:10 +0800Quoted 9 lines
Solution:
=========- Synchronize linux's
include/uapi/linux/in6.h' with glibc'sinet/netinet/in.h'.
- Synchronize glibc'sinet/netinet/in.h with linux'sinclude/uapi/linux/in6.h'.
- Allow including the headers in either other.
- First header included defines the structures and macros.
Quoted 3 lines
Applied, thanks for being so patient. I want to spend the past few weeks making sure this is the right way to handle all of this and now I am confident that it is.
Pushed into 2.19.
If you compile glibc with old non-UAPI kernel headers then this code never triggers and glibc continues to redefine the structures and we have the same problem as always.
If you compile glibc with new UPAI kernel headers, but without the kernel side patch, you fix the build issues only in one order of inclusion i.e. linux header then glibc header. Thus previously your application didn't compile, now it does, but without the kernel side patch some of the constants glibc define may be missing. At that point you need to file a bug against the kernel you are using and request they add the missing constants (or add them yourself).
If you compile glibc with new UAPI kernel headers, and those headers have the kernel side patch then everything works in any inclusion order and the defined constants are the superset of those defined in both implementations.
Note:
- It could have been possible with more added complexity to handle the case where the kernel headers have not been patched. I deemed that because the code never originally compiled that it was fine to continue not compiling in that intermediate state and only support the final state as a complete solution. Feel free to disagree.
commit 6c82a2f8d7c8e21e39237225c819f182ae438db3
Author: Carlos O'Donell <[email protected]> Date: Fri Sep 6 01:02:30 2013 -0400
Coordinate IPv6 definitions for Linux and glibc
This change synchronizes the glibc headers with the Linux kernel headers and arranges to coordinate the definition of structures already defined the Linux kernel UAPI headers.
It is now safe to include glibc's netinet/in.h or Linux's linux/in6.h in any order in a userspace application and you will get the same ABI. The ABI is guaranteed by UAPI and glibc.
Cheers,
Carlos.