2010/8/11 Simon Horman <ho...@verge.net.au>:
>> > http://hg.linux-ha.org/agents/rev/612e2966f372
>>
>> I've had to commit a small revision, because on IA64, the memory on the
>> stack is not aligned properly for the cast to struct nd_neighbor_advert
>> * - http://hg.linux-ha.org/agents/rev/d206bc8f1303
>>
>> I apologize for the uglyness; it was the only way I could make gcc
>> shutup and get the alignment right. If someone can make the alignment
>> properly on the stack, I'm all ears ...
>
> You are right, that is a bit ugly.
> But I have no better ideas at this time :-(

How about this patch or along this line?
It assumes GCC but ICC should have a similar feature if you want to support it.

Alternatively, having an union with an u_int8_t array and a struct
should make an alignment correctly, I think.

-- 
Keisuke MORI
# HG changeset patch
# User Keisuke MORI <kskm...@intellilink.co.jp>
# Date 1281491442 -32400
# Node ID b12ca86af66197498cbf537ccc7ad4ff56cdf63b
# Parent  d206bc8f13039b332e76a93a86e8e550b67781da
[mq]: ipv6addr-alignment.patch

diff -r d206bc8f1303 -r b12ca86af661 heartbeat/IPv6addr.c
--- a/heartbeat/IPv6addr.c	Mon Aug 09 21:51:19 2010 +0200
+++ b/heartbeat/IPv6addr.c	Wed Aug 11 10:50:42 2010 +0900
@@ -89,7 +89,6 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <malloc.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -424,10 +423,17 @@
 	int ifindex;
 	int hop;
 	struct ifreq ifr;
-	u_int8_t *payload;
-	int    payload_size;
-	struct nd_neighbor_advert *na;
-	struct nd_opt_hdr *opt;
+
+	/* GCC is assumed.
+	 * If you want to port to other than GCC, make sure that
+	 * the packet is packed correctly.
+	 */ 
+	struct neighbor_advert {
+		struct nd_neighbor_advert na;
+		struct nd_opt_hdr opt;
+		u_int8_t hwaddr[HWADDR_LEN];
+	} __attribute__ ((packed)) payload;
+
 	struct sockaddr_in6 src_sin6;
 	struct sockaddr_in6 dst_sin6;
 
@@ -473,39 +479,27 @@
 	}
 
 	/* build a neighbor advertisement message */
-	payload_size = sizeof(struct nd_neighbor_advert)
-			 + sizeof(struct nd_opt_hdr) + HWADDR_LEN;
-	payload = memalign(sysconf(_SC_PAGESIZE), payload_size);
-	if (!payload) {
-		cl_log(LOG_ERR, "malloc for payload failed");
-		goto err;
-	}
-	memset(payload, 0, payload_size);
+	memset((void *)&payload, 0, sizeof(payload));
 
-	/* Ugly typecast from ia64 hell! */
-	na = (struct nd_neighbor_advert *)((void *)payload);
-	na->nd_na_type = ND_NEIGHBOR_ADVERT;
-	na->nd_na_code = 0;
-	na->nd_na_cksum = 0; /* calculated by kernel */
-	na->nd_na_flags_reserved = ND_NA_FLAG_OVERRIDE;
-	na->nd_na_target = *src_ip;
+	payload.na.nd_na_type = ND_NEIGHBOR_ADVERT;
+	payload.na.nd_na_code = 0;
+	payload.na.nd_na_cksum = 0; /* calculated by kernel */
+	payload.na.nd_na_flags_reserved = ND_NA_FLAG_OVERRIDE;
+	payload.na.nd_na_target = *src_ip;
 
 	/* options field; set the target link-layer address */
-	opt = (struct nd_opt_hdr *)(payload + sizeof(struct nd_neighbor_advert));
-	opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
-	opt->nd_opt_len = 1; /* The length of the option in units of 8 octets */
-	memcpy(payload + sizeof(struct nd_neighbor_advert)
-			+ sizeof(struct nd_opt_hdr),
-	       &ifr.ifr_hwaddr.sa_data, HWADDR_LEN);
+	payload.opt.nd_opt_type = ND_OPT_TARGET_LINKADDR;
+	payload.opt.nd_opt_len = 1; /* The length of the option in units of 8 octets */
+	memcpy(payload.hwaddr, &ifr.ifr_hwaddr.sa_data, HWADDR_LEN);
 
 	/* sending an unsolicited neighbor advertisement to all */
 	memset(&dst_sin6, 0, sizeof(dst_sin6));
 	dst_sin6.sin6_family = AF_INET6;
 	inet_pton(AF_INET6, BCAST_ADDR, &dst_sin6.sin6_addr); /* should not fail */
 
-	if (sendto(fd, payload, payload_size, 0,
+	if (sendto(fd, (void *)&payload, sizeof(payload), 0,
 		   (struct sockaddr *)&dst_sin6, sizeof(dst_sin6))
-	    != payload_size) {
+	    != sizeof(payload)) {
 		cl_log(LOG_ERR, "sendto(%s) failed: %s",
 		       if_name, strerror(errno));
 		goto err;
@@ -515,7 +509,6 @@
 
 err:
 	close(fd);
-	free(payload);
 	return status;
 }
 
_______________________________________________________
Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/

Reply via email to