Hi,

On an Active/Standby platform (using Linux-HA 2.1.4 RHEL5, in my case), when a 
fail-over/switch-over is initiated and standby machine takes over the virtual 
IP (IPv6), IPv6addr broadcasts an ICMPv6 neighbor advertisement message.

Unfortunately, this ICMPv6 message has its checksum field set to 0 (i.e. not 
computed). The message is thus discarded by recipients.

Maybe this computation should be done by libnet itself. Unfortunately, without 
much time to investigate libnet, I've added code in resources/OCF/IPv6addr.c in 
order to compute the checksum and provide the result to libnet (as a parameter).

Regards,
Pascal ANDRE


--- IPv6addr.c.old 2009-04-30 10:15:16.000000000 +0200
+++ IPv6addr.c 2009-04-30 11:45:43.000000000 +0200
@@ -381,6 +381,58 @@
  return OCF_NOT_RUNNING;
 }

+/* compute ICMPv6 checksum */
+static uint32_t
+cksum_sum(uint16_t *addr, int len, int ntoh)
+{
+ uint16_t * w   = addr;
+ uint16_t   ret = 0;
+ uint32_t   sum = 0;
+
+ while (len > 1) {
+  ret = *w++;
+  if (ntoh) ret = ntohs(ret);
+  sum += ret;
+  len -= 2;
+ }
+
+ if (len == 1) {
+  *(unsigned char *) (&ret) = *(unsigned char *) w;
+  sum += ret;
+ }
+
+ return sum;
+}
+
+static uint16_t
+icmpv6_cksum(struct in6_addr* src_ip, struct libnet_in6_addr* dst_ip, char* 
payload, int payload_len)
+{
+ uint32_t sum = 0;
+ uint16_t val = 0;
+
+ /* IPv6 pseudo header */
+ sum += cksum_sum( src_ip->s6_addr16, 16, 1 );
+ sum += cksum_sum( (uint16_t *)dst_ip, 16, 1 );
+ val = payload_len + (2 * sizeof(uint32_t));
+ sum += cksum_sum( &val, 2, 0 );
+ val = 58;
+ sum += cksum_sum( &val, 2, 0 );
+
+ /* ICMPv6 packet */
+ val = 0x8800;
+ sum += cksum_sum( &val, 2, 0 );
+ val = 0x2000;
+ sum += cksum_sum( &val, 2, 0 );
+ sum += cksum_sum( (uint16_t *)payload, payload_len, 1 );
+
+ /* perform 16-bit one's complement of sum */
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16);
+ val = ~sum;
+
+ return val;
+}
+
 /* Send an unsolicited advertisement packet
  * Please refer to rfc2461
  */
@@ -416,7 +468,7 @@

  libnet_seed_prand(l);
  /* 0x2000: RSO */
- libnet_build_icmpv4_echo(136,0,0,0x2000,0,(u_int8_t *)payload
+ 
libnet_build_icmpv4_echo(136,0,icmpv6_cksum(src_ip,&dst_ip,payload,sizeof(payload)),0x2000,0,(u_int8_t
 *)payload
    ,sizeof(payload), l, LIBNET_PTAG_INITIALIZER);
  libnet_build_ipv6(0,0,LIBNET_ICMPV6_H + sizeof(payload),IPPROTO_ICMP6,
     255,*(struct libnet_in6_addr*)src_ip,
_______________________________________________________
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