Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next
Steffen Klassert says: ==================== pull request (net-next): ipsec-next 2015-05-28 1) Remove xfrm_queue_purge as this is the same as skb_queue_purge. 2) Optimize policy and state walk. 3) Use a sane return code if afinfo registration fails. 4) Only check fori a acquire state if the state is not valid. 5) Remove a unnecessary NULL check before xfrm_pol_hold as it checks the input for NULL. 6) Return directly if the xfrm hold queue is empty, avoid to take a lock as it is nothing to do in this case. 7) Optimize the inexact policy search and allow for matching of policies with priority ~0U. All from Li RongQing. Please pull or let me know if there are problems. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
a74eab639e
@ -29,7 +29,7 @@ int xfrm_input_register_afinfo(struct xfrm_input_afinfo *afinfo)
|
||||
return -EAFNOSUPPORT;
|
||||
spin_lock_bh(&xfrm_input_afinfo_lock);
|
||||
if (unlikely(xfrm_input_afinfo[afinfo->family] != NULL))
|
||||
err = -ENOBUFS;
|
||||
err = -EEXIST;
|
||||
else
|
||||
rcu_assign_pointer(xfrm_input_afinfo[afinfo->family], afinfo);
|
||||
spin_unlock_bh(&xfrm_input_afinfo_lock);
|
||||
@ -239,13 +239,13 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
|
||||
skb->sp->xvec[skb->sp->len++] = x;
|
||||
|
||||
spin_lock(&x->lock);
|
||||
if (unlikely(x->km.state == XFRM_STATE_ACQ)) {
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMACQUIREERROR);
|
||||
goto drop_unlock;
|
||||
}
|
||||
|
||||
if (unlikely(x->km.state != XFRM_STATE_VALID)) {
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEINVALID);
|
||||
if (x->km.state == XFRM_STATE_ACQ)
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMACQUIREERROR);
|
||||
else
|
||||
XFRM_INC_STATS(net,
|
||||
LINUX_MIB_XFRMINSTATEINVALID);
|
||||
goto drop_unlock;
|
||||
}
|
||||
|
||||
|
@ -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 @@ static void xfrm_policy_queue_process(unsigned long arg)
|
||||
|
||||
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);
|
||||
|
||||
|
@ -1626,7 +1626,7 @@ int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
|
||||
if (list_empty(&walk->all))
|
||||
x = list_first_entry(&net->xfrm.state_all, struct xfrm_state_walk, all);
|
||||
else
|
||||
x = list_entry(&walk->all, struct xfrm_state_walk, all);
|
||||
x = list_first_entry(&walk->all, struct xfrm_state_walk, all);
|
||||
list_for_each_entry_from(x, &net->xfrm.state_all, all) {
|
||||
if (x->state == XFRM_STATE_DEAD)
|
||||
continue;
|
||||
@ -1908,7 +1908,7 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo)
|
||||
return -EAFNOSUPPORT;
|
||||
spin_lock_bh(&xfrm_state_afinfo_lock);
|
||||
if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL))
|
||||
err = -ENOBUFS;
|
||||
err = -EEXIST;
|
||||
else
|
||||
rcu_assign_pointer(xfrm_state_afinfo[afinfo->family], afinfo);
|
||||
spin_unlock_bh(&xfrm_state_afinfo_lock);
|
||||
|
Loading…
Reference in New Issue
Block a user