From: Roy Marples Date: Tue, 2 Feb 2016 23:55:52 +0000 (+0000) Subject: Fix Prefix Delegation assigning the SLA in the correct place. X-Git-Tag: v6.10.2~79 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=07be0a6fa9095641cb2038c2a0d7dc4cf231ae64;p=thirdparty%2Fdhcpcd.git Fix Prefix Delegation assigning the SLA in the correct place. --- diff --git a/ipv6.c b/ipv6.c index ebb616c0..30a36491 100644 --- a/ipv6.c +++ b/ipv6.c @@ -524,8 +524,9 @@ ipv6_userprefix( { uint64_t vh, vl, user_low, user_high; - if (prefix_len < 0 || prefix_len > 128 || - result_len < 0 || result_len > 128) + if (prefix_len < 1 || prefix_len > 128 || + result_len < 1 || result_len > 128 || + user_number == 0) { errno = EINVAL; return -1; @@ -533,19 +534,30 @@ ipv6_userprefix( /* Check that the user_number fits inside result_len less prefix_len */ if (result_len < prefix_len || - ffs64(user_number) > result_len - prefix_len) + fls64(user_number) > result_len - prefix_len) { errno = ERANGE; return -1; } - /* virtually shift user number by dest_len, then split at 64 */ - if (result_len >= 64) { - user_high = user_number << (result_len - 64); + /* Shift user_number so it fit's just inside result_len. + * Shifting by 0 or sizeof(user_number) is undefined, + * so we cater for that. */ + if (result_len == 128) { + user_high = 0; + user_low = user_number; + } else if (result_len > 64) { + if (prefix_len >= 64) + user_high = 0; + else + user_high = user_number >> (result_len - prefix_len); + user_low = user_number << (128 - result_len); + } else if (result_len == 64) { + user_high = user_number; user_low = 0; } else { - user_high = user_number >> (64 - result_len); - user_low = user_number << result_len; + user_high = user_number << (64 - result_len); + user_low = 0; } /* convert to two 64bit host order values */