aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/key/af_key.c7
-rw-r--r--net/xfrm/xfrm_policy.c13
-rw-r--r--net/xfrm/xfrm_user.c6
3 files changed, 20 insertions, 6 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index c269ce6094d6..a20d2fa88db9 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2735,8 +2735,11 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg
2735 audit_info.secid = 0; 2735 audit_info.secid = 0;
2736 err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); 2736 err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info);
2737 err2 = unicast_flush_resp(sk, hdr); 2737 err2 = unicast_flush_resp(sk, hdr);
2738 if (err || err2) 2738 if (err || err2) {
2739 return err ? err : err2; 2739 if (err == -ESRCH) /* empty table - old silent behavior */
2740 return 0;
2741 return err;
2742 }
2740 2743
2741 c.data.type = XFRM_POLICY_TYPE_MAIN; 2744 c.data.type = XFRM_POLICY_TYPE_MAIN;
2742 c.event = XFRM_MSG_FLUSHPOLICY; 2745 c.event = XFRM_MSG_FLUSHPOLICY;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 4368e7b88469..d6eb16d75243 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);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index cd94a9dd1bad..ee04e6bf0e54 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1679,8 +1679,12 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1679 audit_info.sessionid = NETLINK_CB(skb).sessionid; 1679 audit_info.sessionid = NETLINK_CB(skb).sessionid;
1680 audit_info.secid = NETLINK_CB(skb).sid; 1680 audit_info.secid = NETLINK_CB(skb).sid;
1681 err = xfrm_policy_flush(net, type, &audit_info); 1681 err = xfrm_policy_flush(net, type, &audit_info);
1682 if (err) 1682 if (err) {
1683 if (err == -ESRCH) /* empty table */
1684 return 0;
1683 return err; 1685 return err;
1686 }
1687
1684 c.data.type = type; 1688 c.data.type = type;
1685 c.event = nlh->nlmsg_type; 1689 c.event = nlh->nlmsg_type;
1686 c.seq = nlh->nlmsg_seq; 1690 c.seq = nlh->nlmsg_seq;