summaryrefslogtreecommitdiffstats
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 c269ce6094d..a20d2fa88db 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
audit_info.secid = 0;
err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info);
err2 = unicast_flush_resp(sk, hdr);
- if (err || err2)
- return err ? err : err2;
+ if (err || err2) {
+ if (err == -ESRCH) /* empty table - old silent behavior */
+ return 0;
+ return err;
+ }
c.data.type = XFRM_POLICY_TYPE_MAIN;
c.event = XFRM_MSG_FLUSHPOLICY;
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
int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
{
- int dir, err = 0;
+ int dir, err = 0, cnt = 0;
+ struct xfrm_policy *dp;
write_lock_bh(&xfrm_policy_lock);
@@ -789,8 +790,10 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
&net->xfrm.policy_inexact[dir], bydst) {
if (pol->type != type)
continue;
- __xfrm_policy_unlink(pol, dir);
+ dp = __xfrm_policy_unlink(pol, dir);
write_unlock_bh(&xfrm_policy_lock);
+ if (dp)
+ cnt++;
xfrm_audit_policy_delete(pol, 1, audit_info->loginuid,
audit_info->sessionid,
@@ -809,8 +812,10 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
bydst) {
if (pol->type != type)
continue;
- __xfrm_policy_unlink(pol, dir);
+ dp = __xfrm_policy_unlink(pol, dir);
write_unlock_bh(&xfrm_policy_lock);
+ if (dp)
+ cnt++;
xfrm_audit_policy_delete(pol, 1,
audit_info->loginuid,
@@ -824,6 +829,8 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
}
}
+ if (!cnt)
+ err = -ESRCH;
atomic_inc(&flow_cache_genid);
out:
write_unlock_bh(&xfrm_policy_lock);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index cd94a9dd1ba..ee04e6bf0e5 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,
audit_info.sessionid = NETLINK_CB(skb).sessionid;
audit_info.secid = NETLINK_CB(skb).sid;
err = xfrm_policy_flush(net, type, &audit_info);
- if (err)
+ if (err) {
+ if (err == -ESRCH) /* empty table */
+ return 0;
return err;
+ }
+
c.data.type = type;
c.event = nlh->nlmsg_type;
c.seq = nlh->nlmsg_seq;