Avoid casting to "i6addr_t *", because that type requires 64-bit

alignment and nothing guarantees that IPv6 packets in mbufs are 8-byte
aligned.  gcc was coalescing adjacent 32-bit compares into "ldx" on
sparc64, leading to alignment faults when processing icmp6 arriving on
gif with IPv4 outer addresses.

Fix mostly from darrenr@.  Discussed extensively on port-sparc64.
This commit is contained in:
gdt 2007-07-19 14:04:34 +00:00
parent ecd360e001
commit 7143faccbb
2 changed files with 13 additions and 12 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fil.c,v 1.38 2007/06/24 22:16:35 mlelstv Exp $ */
/* $NetBSD: fil.c,v 1.39 2007/07/19 14:04:34 gdt Exp $ */
/*
* Copyright (C) 1993-2003 by Darren Reed.
@ -154,7 +154,7 @@ struct file;
#if !defined(lint)
#if defined(__NetBSD__)
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fil.c,v 1.38 2007/06/24 22:16:35 mlelstv Exp $");
__KERNEL_RCSID(0, "$NetBSD: fil.c,v 1.39 2007/07/19 14:04:34 gdt Exp $");
#else
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)Id: fil.c,v 2.243.2.109 2007/05/31 12:27:33 darrenr Exp";
@ -771,7 +771,7 @@ fr_info_t *fin;
icmp6 = fin->fin_dp;
ip6 = (ip6_t *)((char *)icmp6 + ICMPERR_ICMPHLEN);
if (IP6_NEQ(&fin->fin_fi.fi_dst,
(i6addr_t *)&ip6->ip6_src))
&ip6->ip6_src))
fin->fin_flx |= FI_BAD;
minicmpsz = ICMP6ERR_IPICMPHLEN - sizeof(ip6_t);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_fil.h,v 1.13 2007/06/16 10:52:27 martin Exp $ */
/* $NetBSD: ip_fil.h,v 1.14 2007/07/19 14:04:34 gdt Exp $ */
/*
* Copyright (C) 1993-2001, 2003 by Darren Reed.
@ -158,14 +158,15 @@ typedef union i6addr {
#define iplookupptr vptr[0]
#define iplookupfunc lptr[1]
#define I60(x) (((i6addr_t *)(x))->i6[0])
#define I61(x) (((i6addr_t *)(x))->i6[1])
#define I62(x) (((i6addr_t *)(x))->i6[2])
#define I63(x) (((i6addr_t *)(x))->i6[3])
#define HI60(x) ntohl(((i6addr_t *)(x))->i6[0])
#define HI61(x) ntohl(((i6addr_t *)(x))->i6[1])
#define HI62(x) ntohl(((i6addr_t *)(x))->i6[2])
#define HI63(x) ntohl(((i6addr_t *)(x))->i6[3])
/* Avoid casting to a type presuming 64-bit alignment. */
#define I60(x) (((u_32_t *)(x))[0])
#define I61(x) (((u_32_t *)(x))[1])
#define I62(x) (((u_32_t *)(x))[2])
#define I63(x) (((u_32_t *)(x))[3])
#define HI60(x) ntohl(((u_32_t *)(x))[0])
#define HI61(x) ntohl(((u_32_t *)(x))[1])
#define HI62(x) ntohl(((u_32_t *)(x))[2])
#define HI63(x) ntohl(((u_32_t *)(x))[3])
#define IP6_EQ(a,b) ((I63(a) == I63(b)) && (I62(a) == I62(b)) && \
(I61(a) == I61(b)) && (I60(a) == I60(b)))