Browse files

IPv6addr fails on /64 prefixes

Hi Simon,

it seems I am the one unlucky guy who uses heartbeat with IPv6....

I started updateing my cluster today to lenny and IPv6addr fails again:

scs1:/etc/heartbeat/resource.d# ./IPv6addr 2001:629:3800:33:0:0:0:122 start
2009/02/16_20:19:50 ERROR:  Generic error
ERROR:  Generic error

I dug into the source of IPv6addr.c and it seems that the mask is too long
and therefore the scan_if isn't matching.

I have a 2001:629:3800:33::/64 subnet but it seems from my debug output
that IPv6addr tries to match /96 bits of the IP address which fails.

My C knowledge is sadly too little to fix this myself.

I would greatly be happy if you could help me with that.



we found some discussion about this issue here:

In post #4 it reads:
The behaviour of shifts defined only if the value of the right operand
is less than the number of bits in the left operand. So shifting a
32-bit value by 32 or more is undefined...

further info in #7:

Better yet, read the first part of section 5.8 of the ISO/IEC 14882:2003

The behavior is undefined if the right operand is negative,
or greater than or equal to the length in bits of the
promoted left operand.

So it seems that my patch is the proper fix in the end after all.
Attached as file, since BT distroyed the formatting.


This bug was reported as Debian bug #515662

Signed-off-by: Simon Horman <>
  • Loading branch information...
1 parent 9cc0d26 commit 04d8aa9b2f9d0f12f14556ddacfea74a5690692d @pkolmann pkolmann committed Feb 20, 2009
Showing with 4 additions and 1 deletion.
  1. +4 −1 heartbeat/IPv6addr.c
@@ -499,7 +499,10 @@ scan_if(struct in6_addr* addr_target, int* plen_target, int use_mask)
n = plen / 32;
memset(mask.s6_addr32 + n + 1, 0, (3 - n) * 4);
s = 32 - plen % 32;
- mask.s6_addr32[n] = 0xffffffff << s;
+ if (s == 32)
+ mask.s6_addr32[n] = 0x0;
+ else
+ mask.s6_addr32[n] = 0xffffffff << s;
mask.s6_addr32[n] = htonl(mask.s6_addr32[n]);

0 comments on commit 04d8aa9

Please sign in to comment.