|
|||||||||||
|
linux-ipsec: Re: Structure alignment etc on Alphas :-(
From: Hugh Redelmeier <hugh(at)trends.net>
Date: Thu Dec 03 1998 - 15:40:41 EST
| This structure does NOT WORK RIGHT on the alpha....
This is an important problem. The fix isn't obvious. Asking for a struct to be unaligned is not the right fix. Structs are perfectly fine for communication within a machine (using one compiling environment). If all players use the same declarations, the compiler will see to it that the layout is consistent. The problem in this case is that the interfaces is a little too tricky. For example, in utils/spi.c, the relevant code is in f_blkrply: struct espblkrply_edata *ed;
if((em = malloc(sizeof(struct encap_msghdr) +
sizeof(struct espblkrply_edata))) == NULL) {
fprintf(stderr, "%s: Memory allocation error\n", program_name);
exit(1);
}
ed = (struct espblkrply_edata *)(em->em_dat);
Notice that no explicit care is given to make sure that em->em_dat is suitably aligned. That's fair: you'd expect the definition of struct encap_msghdr would ensure the alignment. But it doesn't. So this will violate certain constraints in the C standard. Pluto's code makes the same assumption: that em->em_dat is appropriately aligned. But the "failure mode" is different, and so Pluto and spi communicate incompatibly. Since they don't talk to each other, this would seem not to be a problem. But they both talk to the kernel, so at most one can work. The right fix, I think, is to change the em_dat (pseudo) field to be aligned properly. Here is my suggestion for a fix. Untested! Richard: what do you think?
Hugh Redelmeier
struct
struct sa_id Said; /* SA ID */
int If; /* enc i/f for input */
int Alg; /* Algorithm to use */
!
! /* The following union is a surrogate for
! * algorithm-specific data. To insure
! * proper alignment, worst-case fields
! * should be included. It would be even
! * better to include the types that will
! * actually be used, but they may not be
! * defined for each use of this header.
! * The actual length is expected to be longer
! * than is declared here. References are normally
! * made using the em_dat macro, as if it were a
! * field name.
! */
! union { /* Data */
! __u8 Dat[1];
! __u64 Datq[1]; /* maximal alignment (?) */
! } u;
} Xfm;
struct
#define em_rel Eu.Rel
#define em_proto Eu.Xfm.Said.proto #define em_if Eu.Xfm.If #define em_alg Eu.Xfm.Alg ! #define em_dat Eu.Xfm.u.Dat #define em_rel Eu.Rel #define emr_dst emr_said.dst ================ end ================Received on Thu Dec 3 16:14:32 1998 This archive was generated by hypermail 2.1.8 : Wed Aug 23 2006 - 12:59:08 EDT |
||||||||||
|
|||||||||||