Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Linux-HA: Dev

Checksum not computed in ICMPv6 neighbor advertisement

 

 

Linux-HA dev RSS feed   Index | Next | Previous | View Threaded


Pascal.Andre at hp

Jun 5, 2009, 2:34 AM

Post #1 of 1 (512 views)
Permalink
Checksum not computed in ICMPv6 neighbor advertisement

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 RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.