On 6 Jun 2007, at 3:40 AM, Hans Werner Strube wrote:
Hardly. ip6_ctlun is a union, not a struct.
Ah, yes. Of course, you are right. This is what I get for debugging
things at 4:00 in the morning (the previous night).
On 6 Jun 2007, at 4:45 AM, Stuart Remphrey wrote:
However, while the ip6_hdrctl union is 64 bits,
it's largest member is only 32 bits.
So it is forced to align to 32 bits, not 64.
But that ought to be fine; IP6_NEQ uses the address field 32 bits at
a time.
typedef union i6addr {
u_32_t i6[4];
struct in_addr in4;
struct in6_addr in6;
void *vptr[2];
lookupfunc_t lptr[2];
struct {
u_short type;
u_short subtype;
char label[12];
} i6un;
} i6addr_t;
#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 IP6_NEQ(a,b) ((I63(a) != I63(b)) || (I62(a) != I62(b)) || \
(I61(a) != I61(b)) || (I60(a) != I60(b)))
So, what's causing the alignment problem? Looking at the assembly,
it's loading into registers and comparing those values 64 bits at a
time. It looks like the compiler (gcc 4.1.2) must be smart enough to
notice the kinds of operations IP6_NEQ is doing, and optimizes it
down to two 64-bit compares. It's certainly efficient, but is that
valid? Someone might not have ensured that the struct was 64-bit
aligned! (Assembly version available to anyone who wants to look at it.)
On 64-bit platforms which care about 64-bit alignment
this may need to be enforced via a 64-bit dummy
union member or pragma.
Probably so. Is there a preferred way to do this, given portability
and coding style constraints?
Thanks,
- Geoff