diff options
Diffstat (limited to 'include/net/ipv6.h')
-rw-r--r-- | include/net/ipv6.h | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 53c76c8a6900..0a2ad51cff82 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -254,12 +254,25 @@ typedef int (*inet_getfrag_t) (const void *data, | |||
254 | char *, | 254 | char *, |
255 | unsigned int, unsigned int); | 255 | unsigned int, unsigned int); |
256 | 256 | ||
257 | 257 | extern int __ipv6_addr_type(const struct in6_addr *addr); | |
258 | extern int ipv6_addr_type(const struct in6_addr *addr); | 258 | static inline int ipv6_addr_type(const struct in6_addr *addr) |
259 | { | ||
260 | return __ipv6_addr_type(addr) & 0xffff; | ||
261 | } | ||
259 | 262 | ||
260 | static inline int ipv6_addr_scope(const struct in6_addr *addr) | 263 | static inline int ipv6_addr_scope(const struct in6_addr *addr) |
261 | { | 264 | { |
262 | return ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK; | 265 | return __ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK; |
266 | } | ||
267 | |||
268 | static inline int __ipv6_addr_src_scope(int type) | ||
269 | { | ||
270 | return (type == IPV6_ADDR_ANY ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16)); | ||
271 | } | ||
272 | |||
273 | static inline int ipv6_addr_src_scope(const struct in6_addr *addr) | ||
274 | { | ||
275 | return __ipv6_addr_src_scope(__ipv6_addr_type(addr)); | ||
263 | } | 276 | } |
264 | 277 | ||
265 | static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2) | 278 | static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2) |
@@ -343,6 +356,54 @@ static inline int ipv6_addr_any(const struct in6_addr *a) | |||
343 | } | 356 | } |
344 | 357 | ||
345 | /* | 358 | /* |
359 | * find the first different bit between two addresses | ||
360 | * length of address must be a multiple of 32bits | ||
361 | */ | ||
362 | static inline int __ipv6_addr_diff(const void *token1, const void *token2, int addrlen) | ||
363 | { | ||
364 | const __u32 *a1 = token1, *a2 = token2; | ||
365 | int i; | ||
366 | |||
367 | addrlen >>= 2; | ||
368 | |||
369 | for (i = 0; i < addrlen; i++) { | ||
370 | __u32 xb = a1[i] ^ a2[i]; | ||
371 | if (xb) { | ||
372 | int j = 31; | ||
373 | |||
374 | xb = ntohl(xb); | ||
375 | while ((xb & (1 << j)) == 0) | ||
376 | j--; | ||
377 | |||
378 | return (i * 32 + 31 - j); | ||
379 | } | ||
380 | } | ||
381 | |||
382 | /* | ||
383 | * we should *never* get to this point since that | ||
384 | * would mean the addrs are equal | ||
385 | * | ||
386 | * However, we do get to it 8) And exacly, when | ||
387 | * addresses are equal 8) | ||
388 | * | ||
389 | * ip route add 1111::/128 via ... | ||
390 | * ip route add 1111::/64 via ... | ||
391 | * and we are here. | ||
392 | * | ||
393 | * Ideally, this function should stop comparison | ||
394 | * at prefix length. It does not, but it is still OK, | ||
395 | * if returned value is greater than prefix length. | ||
396 | * --ANK (980803) | ||
397 | */ | ||
398 | return (addrlen << 5); | ||
399 | } | ||
400 | |||
401 | static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2) | ||
402 | { | ||
403 | return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); | ||
404 | } | ||
405 | |||
406 | /* | ||
346 | * Prototypes exported by ipv6 | 407 | * Prototypes exported by ipv6 |
347 | */ | 408 | */ |
348 | 409 | ||