aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/ipv6.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/ipv6.h')
-rw-r--r--include/net/ipv6.h48
1 files changed, 48 insertions, 0 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 65ec86678a08..98661fa4fc78 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -341,6 +341,54 @@ static inline int ipv6_addr_any(const struct in6_addr *a)
341} 341}
342 342
343/* 343/*
344 * find the first different bit between two addresses
345 * length of address must be a multiple of 32bits
346 */
347static inline int __ipv6_addr_diff(const void *token1, const void *token2, int addrlen)
348{
349 const __u32 *a1 = token1, *a2 = token2;
350 int i;
351
352 addrlen >>= 2;
353
354 for (i = 0; i < addrlen; i++) {
355 __u32 xb = a1[i] ^ a2[i];
356 if (xb) {
357 int j = 31;
358
359 xb = ntohl(xb);
360 while ((xb & (1 << j)) == 0)
361 j--;
362
363 return (i * 32 + 31 - j);
364 }
365 }
366
367 /*
368 * we should *never* get to this point since that
369 * would mean the addrs are equal
370 *
371 * However, we do get to it 8) And exacly, when
372 * addresses are equal 8)
373 *
374 * ip route add 1111::/128 via ...
375 * ip route add 1111::/64 via ...
376 * and we are here.
377 *
378 * Ideally, this function should stop comparison
379 * at prefix length. It does not, but it is still OK,
380 * if returned value is greater than prefix length.
381 * --ANK (980803)
382 */
383 return (addrlen << 5);
384}
385
386static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2)
387{
388 return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
389}
390
391/*
344 * Prototypes exported by ipv6 392 * Prototypes exported by ipv6
345 */ 393 */
346 394