|
@@ -315,14 +315,6 @@ void xfrm_policy_destroy(struct xfrm_policy *policy)
|
|
|
}
|
|
|
EXPORT_SYMBOL(xfrm_policy_destroy);
|
|
|
|
|
|
-static void xfrm_queue_purge(struct sk_buff_head *list)
|
|
|
-{
|
|
|
- struct sk_buff *skb;
|
|
|
-
|
|
|
- while ((skb = skb_dequeue(list)) != NULL)
|
|
|
- kfree_skb(skb);
|
|
|
-}
|
|
|
-
|
|
|
/* Rule must be locked. Release descentant resources, announce
|
|
|
* entry dead. The rule must be unlinked from lists to the moment.
|
|
|
*/
|
|
@@ -335,7 +327,7 @@ static void xfrm_policy_kill(struct xfrm_policy *policy)
|
|
|
|
|
|
if (del_timer(&policy->polq.hold_timer))
|
|
|
xfrm_pol_put(policy);
|
|
|
- xfrm_queue_purge(&policy->polq.hold_queue);
|
|
|
+ skb_queue_purge(&policy->polq.hold_queue);
|
|
|
|
|
|
if (del_timer(&policy->timer))
|
|
|
xfrm_pol_put(policy);
|
|
@@ -708,6 +700,9 @@ static void xfrm_policy_requeue(struct xfrm_policy *old,
|
|
|
struct xfrm_policy_queue *pq = &old->polq;
|
|
|
struct sk_buff_head list;
|
|
|
|
|
|
+ if (skb_queue_empty(&pq->hold_queue))
|
|
|
+ return;
|
|
|
+
|
|
|
__skb_queue_head_init(&list);
|
|
|
|
|
|
spin_lock_bh(&pq->hold_queue.lock);
|
|
@@ -716,9 +711,6 @@ static void xfrm_policy_requeue(struct xfrm_policy *old,
|
|
|
xfrm_pol_put(old);
|
|
|
spin_unlock_bh(&pq->hold_queue.lock);
|
|
|
|
|
|
- if (skb_queue_empty(&list))
|
|
|
- return;
|
|
|
-
|
|
|
pq = &new->polq;
|
|
|
|
|
|
spin_lock_bh(&pq->hold_queue.lock);
|
|
@@ -1012,7 +1004,9 @@ int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
|
|
|
if (list_empty(&walk->walk.all))
|
|
|
x = list_first_entry(&net->xfrm.policy_all, struct xfrm_policy_walk_entry, all);
|
|
|
else
|
|
|
- x = list_entry(&walk->walk.all, struct xfrm_policy_walk_entry, all);
|
|
|
+ x = list_first_entry(&walk->walk.all,
|
|
|
+ struct xfrm_policy_walk_entry, all);
|
|
|
+
|
|
|
list_for_each_entry_from(x, &net->xfrm.policy_all, all) {
|
|
|
if (x->dead)
|
|
|
continue;
|
|
@@ -1120,6 +1114,9 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type,
|
|
|
}
|
|
|
chain = &net->xfrm.policy_inexact[dir];
|
|
|
hlist_for_each_entry(pol, chain, bydst) {
|
|
|
+ if ((pol->priority >= priority) && ret)
|
|
|
+ break;
|
|
|
+
|
|
|
err = xfrm_policy_match(pol, fl, type, family, dir);
|
|
|
if (err) {
|
|
|
if (err == -ESRCH)
|
|
@@ -1128,13 +1125,13 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type,
|
|
|
ret = ERR_PTR(err);
|
|
|
goto fail;
|
|
|
}
|
|
|
- } else if (pol->priority < priority) {
|
|
|
+ } else {
|
|
|
ret = pol;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- if (ret)
|
|
|
- xfrm_pol_hold(ret);
|
|
|
+
|
|
|
+ xfrm_pol_hold(ret);
|
|
|
fail:
|
|
|
read_unlock_bh(&net->xfrm.xfrm_policy_lock);
|
|
|
|
|
@@ -1955,7 +1952,7 @@ out:
|
|
|
|
|
|
purge_queue:
|
|
|
pq->timeout = 0;
|
|
|
- xfrm_queue_purge(&pq->hold_queue);
|
|
|
+ skb_queue_purge(&pq->hold_queue);
|
|
|
xfrm_pol_put(pol);
|
|
|
}
|
|
|
|
|
@@ -2814,7 +2811,7 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
|
|
|
return -EAFNOSUPPORT;
|
|
|
spin_lock(&xfrm_policy_afinfo_lock);
|
|
|
if (unlikely(xfrm_policy_afinfo[afinfo->family] != NULL))
|
|
|
- err = -ENOBUFS;
|
|
|
+ err = -EEXIST;
|
|
|
else {
|
|
|
struct dst_ops *dst_ops = afinfo->dst_ops;
|
|
|
if (likely(dst_ops->kmem_cachep == NULL))
|
|
@@ -3209,16 +3206,17 @@ static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *
|
|
|
}
|
|
|
chain = &net->xfrm.policy_inexact[dir];
|
|
|
hlist_for_each_entry(pol, chain, bydst) {
|
|
|
+ if ((pol->priority >= priority) && ret)
|
|
|
+ break;
|
|
|
+
|
|
|
if (xfrm_migrate_selector_match(sel, &pol->selector) &&
|
|
|
- pol->type == type &&
|
|
|
- pol->priority < priority) {
|
|
|
+ pol->type == type) {
|
|
|
ret = pol;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (ret)
|
|
|
- xfrm_pol_hold(ret);
|
|
|
+ xfrm_pol_hold(ret);
|
|
|
|
|
|
read_unlock_bh(&net->xfrm.xfrm_policy_lock);
|
|
|
|