forked from luck/tmp_suning_uos_patched
xfrm: policy: split list insertion into a helper
... so we can reuse this later without code duplication when we add policy to a second inexact list. Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
ceb159e30a
commit
a927d6af53
|
@ -740,18 +740,12 @@ static bool xfrm_policy_mark_match(struct xfrm_policy *policy,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
|
static struct xfrm_policy *xfrm_policy_insert_list(struct hlist_head *chain,
|
||||||
|
struct xfrm_policy *policy,
|
||||||
|
bool excl)
|
||||||
{
|
{
|
||||||
struct net *net = xp_net(policy);
|
struct xfrm_policy *pol, *newpos = NULL, *delpol = NULL;
|
||||||
struct xfrm_policy *pol;
|
|
||||||
struct xfrm_policy *delpol;
|
|
||||||
struct hlist_head *chain;
|
|
||||||
struct hlist_node *newpos;
|
|
||||||
|
|
||||||
spin_lock_bh(&net->xfrm.xfrm_policy_lock);
|
|
||||||
chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
|
|
||||||
delpol = NULL;
|
|
||||||
newpos = NULL;
|
|
||||||
hlist_for_each_entry(pol, chain, bydst) {
|
hlist_for_each_entry(pol, chain, bydst) {
|
||||||
if (pol->type == policy->type &&
|
if (pol->type == policy->type &&
|
||||||
pol->if_id == policy->if_id &&
|
pol->if_id == policy->if_id &&
|
||||||
|
@ -759,24 +753,41 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
|
||||||
xfrm_policy_mark_match(policy, pol) &&
|
xfrm_policy_mark_match(policy, pol) &&
|
||||||
xfrm_sec_ctx_match(pol->security, policy->security) &&
|
xfrm_sec_ctx_match(pol->security, policy->security) &&
|
||||||
!WARN_ON(delpol)) {
|
!WARN_ON(delpol)) {
|
||||||
if (excl) {
|
if (excl)
|
||||||
spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
|
return ERR_PTR(-EEXIST);
|
||||||
return -EEXIST;
|
|
||||||
}
|
|
||||||
delpol = pol;
|
delpol = pol;
|
||||||
if (policy->priority > pol->priority)
|
if (policy->priority > pol->priority)
|
||||||
continue;
|
continue;
|
||||||
} else if (policy->priority >= pol->priority) {
|
} else if (policy->priority >= pol->priority) {
|
||||||
newpos = &pol->bydst;
|
newpos = pol;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (delpol)
|
if (delpol)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (newpos)
|
if (newpos)
|
||||||
hlist_add_behind_rcu(&policy->bydst, newpos);
|
hlist_add_behind_rcu(&policy->bydst, &newpos->bydst);
|
||||||
else
|
else
|
||||||
hlist_add_head_rcu(&policy->bydst, chain);
|
hlist_add_head_rcu(&policy->bydst, chain);
|
||||||
|
|
||||||
|
return delpol;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
|
||||||
|
{
|
||||||
|
struct net *net = xp_net(policy);
|
||||||
|
struct xfrm_policy *delpol;
|
||||||
|
struct hlist_head *chain;
|
||||||
|
|
||||||
|
spin_lock_bh(&net->xfrm.xfrm_policy_lock);
|
||||||
|
chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
|
||||||
|
delpol = xfrm_policy_insert_list(chain, policy, excl);
|
||||||
|
|
||||||
|
if (IS_ERR(delpol)) {
|
||||||
|
spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
|
||||||
|
return PTR_ERR(delpol);
|
||||||
|
}
|
||||||
|
|
||||||
__xfrm_policy_link(policy, dir);
|
__xfrm_policy_link(policy, dir);
|
||||||
|
|
||||||
/* After previous checking, family can either be AF_INET or AF_INET6 */
|
/* After previous checking, family can either be AF_INET or AF_INET6 */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user