aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
authorJamal Hadi Salim <hadi@cyberus.ca>2010-02-18 21:00:42 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-19 16:11:50 -0500
commit2f1eb65f366b81aa3c22c31e6e8db26168777ec5 (patch)
tree3c838f5801d0842c586519ddd4d991e22ac3ecd0 /net/xfrm/xfrm_policy.c
parent9e64cc9572b43afcbcd2d004538db435f2cd0587 (diff)
xfrm: Flushing empty SPD generates false events
To see the effect make sure you have an empty SPD. On window1 "ip xfrm mon" and on window2 issue "ip xfrm policy flush" You get prompt back in window2 and you see the flush event on window1. With this fix, you still get prompt on window1 but no event on window2. Thanks to Alexey Dobriyan for finding a bug in earlier version when using pfkey to do the flushing. Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 4368e7b8846..d6eb16d7524 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -771,7 +771,8 @@ xfrm_policy_flush_secctx_check(struct net *net, u8 type, struct xfrm_audit *audi
771 771
772int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) 772int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
773{ 773{
774 int dir, err = 0; 774 int dir, err = 0, cnt = 0;
775 struct xfrm_policy *dp;
775 776
776 write_lock_bh(&xfrm_policy_lock); 777 write_lock_bh(&xfrm_policy_lock);
777 778
@@ -789,8 +790,10 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
789 &net->xfrm.policy_inexact[dir], bydst) { 790 &net->xfrm.policy_inexact[dir], bydst) {
790 if (pol->type != type) 791 if (pol->type != type)
791 continue; 792 continue;
792 __xfrm_policy_unlink(pol, dir); 793 dp = __xfrm_policy_unlink(pol, dir);
793 write_unlock_bh(&xfrm_policy_lock); 794 write_unlock_bh(&xfrm_policy_lock);
795 if (dp)
796 cnt++;
794 797
795 xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, 798 xfrm_audit_policy_delete(pol, 1, audit_info->loginuid,
796 audit_info->sessionid, 799 audit_info->sessionid,
@@ -809,8 +812,10 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
809 bydst) { 812 bydst) {
810 if (pol->type != type) 813 if (pol->type != type)
811 continue; 814 continue;
812 __xfrm_policy_unlink(pol, dir); 815 dp = __xfrm_policy_unlink(pol, dir);
813 write_unlock_bh(&xfrm_policy_lock); 816 write_unlock_bh(&xfrm_policy_lock);
817 if (dp)
818 cnt++;
814 819
815 xfrm_audit_policy_delete(pol, 1, 820 xfrm_audit_policy_delete(pol, 1,
816 audit_info->loginuid, 821 audit_info->loginuid,
@@ -824,6 +829,8 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
824 } 829 }
825 830
826 } 831 }
832 if (!cnt)
833 err = -ESRCH;
827 atomic_inc(&flow_cache_genid); 834 atomic_inc(&flow_cache_genid);
828out: 835out:
829 write_unlock_bh(&xfrm_policy_lock); 836 write_unlock_bh(&xfrm_policy_lock);