summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2009-02-11 20:07:04 +0000
committerclaudio <claudio@openbsd.org>2009-02-11 20:07:04 +0000
commit7d38feda58ef5bc417a3011f85c0e4242c32dd42 (patch)
tree2d96675f06ad63d59e810390cc5c7a4faba8492b
parentsync text to previous a little; (diff)
downloadwireguard-openbsd-7d38feda58ef5bc417a3011f85c0e4242c32dd42.tar.xz
wireguard-openbsd-7d38feda58ef5bc417a3011f85c0e4242c32dd42.zip
Because IPv6 fucked up and created a badly sized struct sockaddr_in6 we need
to add some pading on 64bit archs. Use a helper struct plus some ROUNDUP() magic to get the size correct. Tested on i386 and amd64 by Graeme Lee "graeme (at) omni (dot) net (dot) au" Some sort of OK by henning@ (he ignores the non-v4 code)
-rw-r--r--usr.sbin/bgpd/kroute.c46
1 files changed, 24 insertions, 22 deletions
diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c
index dcf7ab4e7dc..cfad55a7cbe 100644
--- a/usr.sbin/bgpd/kroute.c
+++ b/usr.sbin/bgpd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.164 2009/02/09 08:20:11 claudio Exp $ */
+/* $OpenBSD: kroute.c,v 1.165 2009/02/11 20:07:04 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1813,8 +1813,8 @@ inet6applymask(struct in6_addr *dest, const struct in6_addr *src, int prefixlen)
dest->s6_addr[i] = src->s6_addr[i] & mask.s6_addr[i];
}
-#define ROUNDUP(a, size) \
- (((a) & ((size) - 1)) ? (1 + ((a) | ((size) - 1))) : (a))
+#define ROUNDUP(a) \
+ (((a) & ((sizeof(long)) - 1)) ? (1 + ((a) | ((sizeof(long)) - 1))) : (a))
void
get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
@@ -1825,7 +1825,7 @@ get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
if (addrs & (1 << i)) {
rti_info[i] = sa;
sa = (struct sockaddr *)((char *)(sa) +
- ROUNDUP(sa->sa_len, sizeof(long)));
+ ROUNDUP(sa->sa_len));
} else
rti_info[i] = NULL;
}
@@ -2059,9 +2059,10 @@ send_rt6msg(int fd, int action, struct kroute6 *kroute)
{
struct iovec iov[5];
struct rt_msghdr hdr;
- struct sockaddr_in6 prefix;
- struct sockaddr_in6 nexthop;
- struct sockaddr_in6 mask;
+ struct pad {
+ struct sockaddr_in6 addr;
+ char pad[sizeof(long)];
+ } prefix, nexthop, mask;
struct sockaddr_rtlabel label;
int iovcnt = 0;
@@ -2086,43 +2087,44 @@ send_rt6msg(int fd, int action, struct kroute6 *kroute)
iov[iovcnt++].iov_len = sizeof(hdr);
bzero(&prefix, sizeof(prefix));
- prefix.sin6_len = sizeof(prefix);
- prefix.sin6_family = AF_INET6;
- memcpy(&prefix.sin6_addr, &kroute->prefix, sizeof(struct in6_addr));
+ prefix.addr.sin6_len = sizeof(struct sockaddr_in6);
+ prefix.addr.sin6_family = AF_INET6;
+ memcpy(&prefix.addr.sin6_addr, &kroute->prefix,
+ sizeof(struct in6_addr));
/* XXX scope does not matter or? */
/* adjust header */
hdr.rtm_addrs |= RTA_DST;
- hdr.rtm_msglen += sizeof(prefix);
+ hdr.rtm_msglen += ROUNDUP(sizeof(struct sockaddr_in6));
/* adjust iovec */
iov[iovcnt].iov_base = &prefix;
- iov[iovcnt++].iov_len = sizeof(prefix);
+ iov[iovcnt++].iov_len = ROUNDUP(sizeof(struct sockaddr_in6));
if (memcmp(&kroute->nexthop, &in6addr_any, sizeof(struct in6_addr))) {
bzero(&nexthop, sizeof(nexthop));
- nexthop.sin6_len = sizeof(nexthop);
- nexthop.sin6_family = AF_INET6;
- memcpy(&nexthop.sin6_addr, &kroute->nexthop,
+ nexthop.addr.sin6_len = sizeof(struct sockaddr_in6);
+ nexthop.addr.sin6_family = AF_INET6;
+ memcpy(&nexthop.addr.sin6_addr, &kroute->nexthop,
sizeof(struct in6_addr));
/* adjust header */
hdr.rtm_flags |= RTF_GATEWAY;
hdr.rtm_addrs |= RTA_GATEWAY;
- hdr.rtm_msglen += sizeof(nexthop);
+ hdr.rtm_msglen += ROUNDUP(sizeof(struct sockaddr_in6));
/* adjust iovec */
iov[iovcnt].iov_base = &nexthop;
- iov[iovcnt++].iov_len = sizeof(nexthop);
+ iov[iovcnt++].iov_len = ROUNDUP(sizeof(struct sockaddr_in6));
}
bzero(&mask, sizeof(mask));
- mask.sin6_len = sizeof(mask);
- mask.sin6_family = AF_INET6;
- memcpy(&mask.sin6_addr, prefixlen2mask6(kroute->prefixlen),
+ mask.addr.sin6_len = sizeof(struct sockaddr_in6);
+ mask.addr.sin6_family = AF_INET6;
+ memcpy(&mask.addr.sin6_addr, prefixlen2mask6(kroute->prefixlen),
sizeof(struct in6_addr));
/* adjust header */
hdr.rtm_addrs |= RTA_NETMASK;
- hdr.rtm_msglen += sizeof(mask);
+ hdr.rtm_msglen += ROUNDUP(sizeof(struct sockaddr_in6));
/* adjust iovec */
iov[iovcnt].iov_base = &mask;
- iov[iovcnt++].iov_len = sizeof(mask);
+ iov[iovcnt++].iov_len = ROUNDUP(sizeof(struct sockaddr_in6));
if (kroute->labelid) {
bzero(&label, sizeof(label));