dect
/
linux-2.6
Archived
13
0
Fork 0

[XFRM]: Respect priority in policy lookups.

Even if we find an exact match in the hash table,
we must inspect the inexact list to look for a match
with a better priority.

Noticed by Masahide NAKAMURA <nakam@linux-ipv6.org>.

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2006-08-25 15:46:46 -07:00
parent 65e3d72654
commit acba48e1a3
1 changed files with 12 additions and 11 deletions

View File

@ -908,6 +908,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
xfrm_address_t *daddr, *saddr;
struct hlist_node *entry;
struct hlist_head *chain;
u32 priority = ~0U;
daddr = xfrm_flowi_daddr(fl, family);
saddr = xfrm_flowi_saddr(fl, family);
@ -919,21 +920,21 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
ret = NULL;
hlist_for_each_entry(pol, entry, chain, bydst) {
if (xfrm_policy_match(pol, fl, type, family, dir)) {
xfrm_pol_hold(pol);
ret = pol;
priority = ret->priority;
break;
}
}
chain = &xfrm_policy_inexact[dir];
hlist_for_each_entry(pol, entry, chain, bydst) {
if (xfrm_policy_match(pol, fl, type, family, dir) &&
pol->priority < priority) {
ret = pol;
break;
}
}
if (!ret) {
chain = &xfrm_policy_inexact[dir];
hlist_for_each_entry(pol, entry, chain, bydst) {
if (xfrm_policy_match(pol, fl, type, family, dir)) {
xfrm_pol_hold(pol);
ret = pol;
break;
}
}
}
if (ret)
xfrm_pol_hold(ret);
read_unlock_bh(&xfrm_policy_lock);
return ret;