mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 13:33:15 +00:00
zebra/kernel_socket.c: Use platform alignment
Use the platform-provided RT_ROUNDUP macro to align sockaddrs on the routing socket, rather than using hard-coded assumptions about alignment. Emit a warning if the OS doesn't define alignment macros. Resolves failure of ripngd on NetBSD 6 i386, which changed alignment to uint64_t from long. (cherry picked from commit 273b1bd341afff86ba571e0be296d88dba627136)
This commit is contained in:
parent
9b97a19b10
commit
cfa0ed0949
@ -43,22 +43,52 @@
|
|||||||
extern struct zebra_privs_t zserv_privs;
|
extern struct zebra_privs_t zserv_privs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a sockaddr length, round it up to include pad bytes following
|
* Historically, the BSD routing socket has aligned data following a
|
||||||
* it. Assumes the kernel pads to sizeof(long).
|
* struct sockaddr to sizeof(long), which was 4 bytes on some
|
||||||
|
* platforms, and 8 bytes on others. NetBSD 6 changed the routing
|
||||||
|
* socket to align to sizeof(uint64_t), which is 8 bytes. OS X
|
||||||
|
* appears to align to sizeof(int), which is 4 bytes.
|
||||||
*
|
*
|
||||||
* XXX: why is ROUNDUP(0) sizeof(long)? 0 is an illegal sockaddr
|
* Alignment of zero-sized sockaddrs is nonsensical, but historically
|
||||||
* length anyway (< sizeof (struct sockaddr)), so this shouldn't
|
* BSD defines RT_ROUNDUP(0) to be the alignment interval (rather than
|
||||||
* matter.
|
* 0). We follow this practice without questioning it, but it is a
|
||||||
* On OS X, both 32, 64bit syatems align on 4 byte boundary
|
* bug if quagga calls ROUNDUP with 0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Because of these varying conventions, the only sane approach is for
|
||||||
|
* the <net/route.h> header to define some flavor of ROUNDUP macro.
|
||||||
|
*/
|
||||||
|
#if defined(RT_ROUNDUP)
|
||||||
|
#define ROUNDUP(a) RT_ROUNDUP(a)
|
||||||
|
#endif /* defined(RT_ROUNDUP) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If ROUNDUP has not yet been defined in terms of platform-provided
|
||||||
|
* defines, attempt to cope with heuristics.
|
||||||
|
*/
|
||||||
|
#if !defined(ROUNDUP)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It's a bug for a platform not to define rounding/alignment for
|
||||||
|
* sockaddrs on the routing socket. This warning really is
|
||||||
|
* intentional, to provoke filing bug reports with operating systems
|
||||||
|
* that don't define RT_ROUNDUP or equivalent.
|
||||||
|
*/
|
||||||
|
#warning "net/route.h does not define RT_ROUNDUP; making unwarranted assumptions!"
|
||||||
|
|
||||||
|
/* OS X (Xcode as of 2014-12) is known not to define RT_ROUNDUP */
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#define ROUNDUP(a) \
|
#define ROUNDUP_TYPE long
|
||||||
((a) > 0 ? (1 + (((a) - 1) | (sizeof(int) - 1))) : sizeof(int))
|
|
||||||
#else
|
#else
|
||||||
#define ROUNDUP(a) \
|
#define ROUNDUP_TYPE int
|
||||||
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ROUNDUP(a) \
|
||||||
|
((a) > 0 ? (1 + (((a) - 1) | (sizeof(ROUNDUP_TYPE) - 1))) : sizeof(ROUNDUP_TYPE))
|
||||||
|
|
||||||
|
#endif /* defined(ROUNDUP) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a pointer (sockaddr or void *), return the number of bytes
|
* Given a pointer (sockaddr or void *), return the number of bytes
|
||||||
* taken up by the sockaddr and any padding needed for alignment.
|
* taken up by the sockaddr and any padding needed for alignment.
|
||||||
|
Loading…
Reference in New Issue
Block a user