summaryrefslogtreecommitdiffstats
path: root/include/net/ipv6.h
diff options
context:
space:
mode:
authorJames Bottomley <jejb@titanic.(none)>2005-11-10 08:29:07 -0600
committerJames Bottomley <jejb@titanic.(none)>2005-11-10 08:29:07 -0600
commit8a87a0b6313109d2fea87b1271d497c954ce2ca8 (patch)
tree1b7ae51ff681e27118590e9cab4bf0ce38f5d80e /include/net/ipv6.h
parente6a04466ba965875a6132700fabb2f2c0249c41a (diff)
parent3b44f137b9a846c5452d9e6e1271b79b1dbcc942 (diff)
downloadlinux-8a87a0b6313109d2fea87b1271d497c954ce2ca8.tar.bz2
Merge by hand (whitespace conflicts in libata.h)
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'include/net/ipv6.h')
-rw-r--r--include/net/ipv6.h67
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,
char *,
unsigned int, unsigned int);
-
-extern int ipv6_addr_type(const struct in6_addr *addr);
+extern int __ipv6_addr_type(const struct in6_addr *addr);
+static inline int ipv6_addr_type(const struct in6_addr *addr)
+{
+ return __ipv6_addr_type(addr) & 0xffff;
+}
static inline int ipv6_addr_scope(const struct in6_addr *addr)
{
- return ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
+ return __ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
+}
+
+static inline int __ipv6_addr_src_scope(int type)
+{
+ return (type == IPV6_ADDR_ANY ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16));
+}
+
+static inline int ipv6_addr_src_scope(const struct in6_addr *addr)
+{
+ return __ipv6_addr_src_scope(__ipv6_addr_type(addr));
}
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)
}
/*
+ * find the first different bit between two addresses
+ * length of address must be a multiple of 32bits
+ */
+static inline int __ipv6_addr_diff(const void *token1, const void *token2, int addrlen)
+{
+ const __u32 *a1 = token1, *a2 = token2;
+ int i;
+
+ addrlen >>= 2;
+
+ for (i = 0; i < addrlen; i++) {
+ __u32 xb = a1[i] ^ a2[i];
+ if (xb) {
+ int j = 31;
+
+ xb = ntohl(xb);
+ while ((xb & (1 << j)) == 0)
+ j--;
+
+ return (i * 32 + 31 - j);
+ }
+ }
+
+ /*
+ * we should *never* get to this point since that
+ * would mean the addrs are equal
+ *
+ * However, we do get to it 8) And exacly, when
+ * addresses are equal 8)
+ *
+ * ip route add 1111::/128 via ...
+ * ip route add 1111::/64 via ...
+ * and we are here.
+ *
+ * Ideally, this function should stop comparison
+ * at prefix length. It does not, but it is still OK,
+ * if returned value is greater than prefix length.
+ * --ANK (980803)
+ */
+ return (addrlen << 5);
+}
+
+static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2)
+{
+ return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
+}
+
+/*
* Prototypes exported by ipv6
*/