summaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
authorLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-02-26 14:26:14 +1100
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-02-26 14:26:14 +1100
commit91e229bbad6524aabaac8717b2f559283670c37a (patch)
tree84a55e4ac2dcf23add97bd9fde3e9cb232c12b30 /net/xfrm/xfrm_policy.c
parent6e5e93424dc66542c548dfaa3bfebe30d46d50dd (diff)
parentbfa274e2436fc7ef72ef51c878083647f1cfd429 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-linus
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 47219f98053..9fc4c315f6c 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -331,15 +331,31 @@ static void xfrm_dst_hash_transfer(struct hlist_head *list,
struct hlist_head *ndsttable,
unsigned int nhashmask)
{
- struct hlist_node *entry, *tmp;
+ struct hlist_node *entry, *tmp, *entry0 = NULL;
struct xfrm_policy *pol;
+ unsigned int h0 = 0;
+redo:
hlist_for_each_entry_safe(pol, entry, tmp, list, bydst) {
unsigned int h;
h = __addr_hash(&pol->selector.daddr, &pol->selector.saddr,
pol->family, nhashmask);
- hlist_add_head(&pol->bydst, ndsttable+h);
+ if (!entry0) {
+ hlist_del(entry);
+ hlist_add_head(&pol->bydst, ndsttable+h);
+ h0 = h;
+ } else {
+ if (h != h0)
+ continue;
+ hlist_del(entry);
+ hlist_add_after(entry0, &pol->bydst);
+ }
+ entry0 = entry;
+ }
+ if (!hlist_empty(list)) {
+ entry0 = NULL;
+ goto redo;
}
}