Commit 83f680da authored by Hideaki Yoshifuji's avatar Hideaki Yoshifuji

[IPV6] Unify common functions to compare ipv6 prefixes.

Signed-off-by: default avatarHideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
parent 0d098fc4
......@@ -305,6 +305,32 @@ static inline int ipv6_addr_equal(const struct in6_addr *a1,
a1->s6_addr32[3] == a2->s6_addr32[3]);
}
static inline int __ipv6_prefix_equal(const u32 *a1, const u32 *a2,
unsigned int prefixlen)
{
unsigned pdw, pbi;
/* check complete u32 in prefix */
pdw = prefixlen >> 5;
if (pdw && memcmp(a1, a2, pdw << 2))
return 0;
/* check incomplete u32 in prefix */
pbi = prefixlen & 0x1f;
if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi))))
return 0;
return 1;
}
static inline int ipv6_prefix_equal(const struct in6_addr *a1,
const struct in6_addr *a2,
unsigned int prefixlen)
{
return __ipv6_prefix_equal(a1->s6_addr32, a2->s6_addr32,
prefixlen);
}
static inline int ipv6_addr_any(const struct in6_addr *a)
{
return ((a->s6_addr32[0] | a->s6_addr32[1] |
......
......@@ -48,32 +48,6 @@ static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr);
/* Big ac list lock for all the sockets */
static DEFINE_RWLOCK(ipv6_sk_ac_lock);
/* XXX ip6_addr_match() and ip6_onlink() really belong in net/core.c */
static int
ip6_addr_match(struct in6_addr *addr1, struct in6_addr *addr2, int prefix)
{
__u32 mask;
int i;
if (prefix > 128 || prefix < 0)
return 0;
if (prefix == 0)
return 1;
for (i=0; i<4; ++i) {
if (prefix >= 32)
mask = ~0;
else
mask = htonl(~0 << (32 - prefix));
if ((addr1->s6_addr32[i] ^ addr2->s6_addr32[i]) & mask)
return 0;
prefix -= 32;
if (prefix <= 0)
break;
}
return 1;
}
static int
ip6_onlink(struct in6_addr *addr, struct net_device *dev)
{
......@@ -87,8 +61,8 @@ ip6_onlink(struct in6_addr *addr, struct net_device *dev)
if (idev) {
read_lock_bh(&idev->lock);
for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
onlink = ip6_addr_match(addr, &ifa->addr,
ifa->prefix_len);
onlink = ipv6_prefix_equal(addr, &ifa->addr,
ifa->prefix_len);
if (onlink)
break;
}
......
......@@ -116,36 +116,6 @@ static __inline__ u32 fib6_new_sernum(void)
* 64bit processors)
*/
/*
* compare "prefix length" bits of an address
*/
static __inline__ int addr_match(void *token1, void *token2, int prefixlen)
{
__u32 *a1 = token1;
__u32 *a2 = token2;
int pdw;
int pbi;
pdw = prefixlen >> 5; /* num of whole __u32 in prefix */
pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */
if (pdw)
if (memcmp(a1, a2, pdw << 2))
return 0;
if (pbi) {
__u32 mask;
mask = htonl((0xffffffff) << (32 - pbi));
if ((a1[pdw] ^ a2[pdw]) & mask)
return 0;
}
return 1;
}
/*
* test bit
*/
......@@ -261,7 +231,7 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr,
* Prefix match
*/
if (plen < fn->fn_bit ||
!addr_match(&key->addr, addr, fn->fn_bit))
!ipv6_prefix_equal(&key->addr, addr, fn->fn_bit))
goto insert_above;
/*
......@@ -667,7 +637,7 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node *root,
key = (struct rt6key *) ((u8 *) fn->leaf +
args->offset);
if (addr_match(&key->addr, args->addr, key->plen))
if (ipv6_prefix_equal(&key->addr, args->addr, key->plen))
return fn;
}
......@@ -718,7 +688,7 @@ static struct fib6_node * fib6_locate_1(struct fib6_node *root,
* Prefix match
*/
if (plen < fn->fn_bit ||
!addr_match(&key->addr, addr, fn->fn_bit))
!ipv6_prefix_equal(&key->addr, addr, fn->fn_bit))
return NULL;
if (plen == fn->fn_bit)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment