Commit 61c05fcd authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

[IPSEC]: Order SPD using priority.

parent 32ac8e51
...@@ -244,22 +244,34 @@ static u32 xfrm_gen_index(int dir) ...@@ -244,22 +244,34 @@ static u32 xfrm_gen_index(int dir)
int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
{ {
struct xfrm_policy *pol, **p; struct xfrm_policy *pol, **p;
struct xfrm_policy *delpol = NULL;
struct xfrm_policy **newpos = NULL;
write_lock_bh(&xfrm_policy_lock); write_lock_bh(&xfrm_policy_lock);
for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) { for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) {
if (memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0) { if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0) {
if (excl) { if (excl) {
write_unlock_bh(&xfrm_policy_lock); write_unlock_bh(&xfrm_policy_lock);
return -EEXIST; return -EEXIST;
} }
*p = pol->next;
delpol = pol;
if (policy->priority > pol->priority)
continue;
} else if (policy->priority >= pol->priority)
continue;
if (!newpos)
newpos = p;
if (delpol)
break; break;
} }
} if (newpos)
p = newpos;
xfrm_pol_hold(policy); xfrm_pol_hold(policy);
policy->next = pol ? pol->next : NULL; policy->next = *p;
*p = policy; *p = policy;
atomic_inc(&flow_cache_genid); atomic_inc(&flow_cache_genid);
policy->index = pol ? pol->index : xfrm_gen_index(dir); policy->index = delpol ? delpol->index : xfrm_gen_index(dir);
policy->curlft.add_time = (unsigned long)xtime.tv_sec; policy->curlft.add_time = (unsigned long)xtime.tv_sec;
policy->curlft.use_time = 0; policy->curlft.use_time = 0;
if (policy->lft.hard_add_expires_seconds && if (policy->lft.hard_add_expires_seconds &&
...@@ -267,10 +279,10 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) ...@@ -267,10 +279,10 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
xfrm_pol_hold(policy); xfrm_pol_hold(policy);
write_unlock_bh(&xfrm_policy_lock); write_unlock_bh(&xfrm_policy_lock);
if (pol) { if (delpol) {
atomic_dec(&pol->refcnt); atomic_dec(&delpol->refcnt);
xfrm_policy_kill(pol); xfrm_policy_kill(delpol);
xfrm_pol_put(pol); xfrm_pol_put(delpol);
} }
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment