Skip to content

Commit

Permalink
xfrm: policy: split list insertion into a helper
Browse files Browse the repository at this point in the history
... 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>
  • Loading branch information
Florian Westphal authored and Steffen Klassert committed Nov 9, 2018
1 parent ceb159e commit a927d6a
Showing 1 changed file with 27 additions and 16 deletions.
43 changes: 27 additions & 16 deletions net/xfrm/xfrm_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -740,43 +740,54 @@ static bool xfrm_policy_mark_match(struct xfrm_policy *policy,
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;
struct xfrm_policy *delpol;
struct hlist_head *chain;
struct hlist_node *newpos;
struct xfrm_policy *pol, *newpos = NULL, *delpol = NULL;

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) {
if (pol->type == policy->type &&
pol->if_id == policy->if_id &&
!selector_cmp(&pol->selector, &policy->selector) &&
xfrm_policy_mark_match(policy, pol) &&
xfrm_sec_ctx_match(pol->security, policy->security) &&
!WARN_ON(delpol)) {
if (excl) {
spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
return -EEXIST;
}
if (excl)
return ERR_PTR(-EEXIST);
delpol = pol;
if (policy->priority > pol->priority)
continue;
} else if (policy->priority >= pol->priority) {
newpos = &pol->bydst;
newpos = pol;
continue;
}
if (delpol)
break;
}
if (newpos)
hlist_add_behind_rcu(&policy->bydst, newpos);
hlist_add_behind_rcu(&policy->bydst, &newpos->bydst);
else
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);

/* After previous checking, family can either be AF_INET or AF_INET6 */
Expand Down

0 comments on commit a927d6a

Please sign in to comment.