Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b791160b5af4ea95c72fb59d13079664beca1963
Commit:     b791160b5af4ea95c72fb59d13079664beca1963
Parent:     82453021b8be85171350c695d7ebafe7b517c812
Author:     YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
AuthorDate: Sun Feb 17 23:29:30 2008 -0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Sun Feb 17 23:29:30 2008 -0800

    [XFRM]: Fix ordering issue in xfrm_dst_hash_transfer().
    
    Keep ordering of policy entries with same selector in
    xfrm_dst_hash_transfer().
    
    Issue should not appear in usual cases because multiple policy entries
    with same selector are basically not allowed so far.  Bug was pointed
    out by Sebastien Decugis <[EMAIL PROTECTED]>.
    
    We could convert bydst from hlist to list and use list_add_tail()
    instead.
    
    Signed-off-by: YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
    Acked-by: Sebastien Decugis <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/xfrm/xfrm_policy.c |   20 ++++++++++++++++++--
 1 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 47219f9..9fc4c31 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;
        }
 }
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to