r8169: fix oops in r8169_get_mac_version
[cascardo/linux.git] / net / xfrm / xfrm_policy.c
index 534b29e..9fc4c31 100644 (file)
@@ -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;
        }
 }
 
@@ -2367,8 +2383,8 @@ void __init xfrm_init(void)
 }
 
 #ifdef CONFIG_AUDITSYSCALL
-static inline void xfrm_audit_common_policyinfo(struct xfrm_policy *xp,
-                                               struct audit_buffer *audit_buf)
+static void xfrm_audit_common_policyinfo(struct xfrm_policy *xp,
+                                        struct audit_buffer *audit_buf)
 {
        struct xfrm_sec_ctx *ctx = xp->security;
        struct xfrm_selector *sel = &xp->selector;