diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-10-03 19:00:26 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-10-04 03:31:02 -0400 |
commit | ae8c05779ac2f286b872db9ebea0c3c0a031ad1e (patch) | |
tree | af273537fa57c67b706b41544bb22bba1dfb9374 /net | |
parent | 667bbcb6c099d1b74f95c6963ddf37a32e7afc29 (diff) |
[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>
Diffstat (limited to 'net')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index b6e2e79d7261..2a7861661f14 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -778,8 +778,9 @@ void xfrm_policy_flush(u8 type) | |||
778 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | 778 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { |
779 | struct xfrm_policy *pol; | 779 | struct xfrm_policy *pol; |
780 | struct hlist_node *entry; | 780 | struct hlist_node *entry; |
781 | int i; | 781 | int i, killed; |
782 | 782 | ||
783 | killed = 0; | ||
783 | again1: | 784 | again1: |
784 | hlist_for_each_entry(pol, entry, | 785 | hlist_for_each_entry(pol, entry, |
785 | &xfrm_policy_inexact[dir], bydst) { | 786 | &xfrm_policy_inexact[dir], bydst) { |
@@ -790,6 +791,7 @@ void xfrm_policy_flush(u8 type) | |||
790 | write_unlock_bh(&xfrm_policy_lock); | 791 | write_unlock_bh(&xfrm_policy_lock); |
791 | 792 | ||
792 | xfrm_policy_kill(pol); | 793 | xfrm_policy_kill(pol); |
794 | killed++; | ||
793 | 795 | ||
794 | write_lock_bh(&xfrm_policy_lock); | 796 | write_lock_bh(&xfrm_policy_lock); |
795 | goto again1; | 797 | goto again1; |
@@ -807,13 +809,14 @@ void xfrm_policy_flush(u8 type) | |||
807 | write_unlock_bh(&xfrm_policy_lock); | 809 | write_unlock_bh(&xfrm_policy_lock); |
808 | 810 | ||
809 | xfrm_policy_kill(pol); | 811 | xfrm_policy_kill(pol); |
812 | killed++; | ||
810 | 813 | ||
811 | write_lock_bh(&xfrm_policy_lock); | 814 | write_lock_bh(&xfrm_policy_lock); |
812 | goto again2; | 815 | goto again2; |
813 | } | 816 | } |
814 | } | 817 | } |
815 | 818 | ||
816 | xfrm_policy_count[dir] = 0; | 819 | xfrm_policy_count[dir] -= killed; |
817 | } | 820 | } |
818 | atomic_inc(&flow_cache_genid); | 821 | atomic_inc(&flow_cache_genid); |
819 | write_unlock_bh(&xfrm_policy_lock); | 822 | write_unlock_bh(&xfrm_policy_lock); |