[XFRM]: Clearing xfrm_policy_count[] to zero during flush is incorrect.

When we flush policies, we do a type match so we might not
actually delete all policies matching a certain direction.

So keep track of how many policies we actually kill and
subtract that number from xfrm_policy_count[dir] at the
end.

Based upon a patch by Masahide NAKAMURA.

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2006-10-03 16:00:26 -07:00
parent 667bbcb6c0
commit ae8c05779a

View file

@ -778,8 +778,9 @@ void xfrm_policy_flush(u8 type)
for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
struct xfrm_policy *pol; struct xfrm_policy *pol;
struct hlist_node *entry; struct hlist_node *entry;
int i; int i, killed;
killed = 0;
again1: again1:
hlist_for_each_entry(pol, entry, hlist_for_each_entry(pol, entry,
&xfrm_policy_inexact[dir], bydst) { &xfrm_policy_inexact[dir], bydst) {
@ -790,6 +791,7 @@ void xfrm_policy_flush(u8 type)
write_unlock_bh(&xfrm_policy_lock); write_unlock_bh(&xfrm_policy_lock);
xfrm_policy_kill(pol); xfrm_policy_kill(pol);
killed++;
write_lock_bh(&xfrm_policy_lock); write_lock_bh(&xfrm_policy_lock);
goto again1; goto again1;
@ -807,13 +809,14 @@ void xfrm_policy_flush(u8 type)
write_unlock_bh(&xfrm_policy_lock); write_unlock_bh(&xfrm_policy_lock);
xfrm_policy_kill(pol); xfrm_policy_kill(pol);
killed++;
write_lock_bh(&xfrm_policy_lock); write_lock_bh(&xfrm_policy_lock);
goto again2; goto again2;
} }
} }
xfrm_policy_count[dir] = 0; xfrm_policy_count[dir] -= killed;
} }
atomic_inc(&flow_cache_genid); atomic_inc(&flow_cache_genid);
write_unlock_bh(&xfrm_policy_lock); write_unlock_bh(&xfrm_policy_lock);