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