aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-02-17 16:41:40 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-17 16:41:40 -0500
commit069c474e88bb7753183f1eadbd7786c27888c8e3 (patch)
tree09b0385d34a2d0b302b1f61a2783bfcdc510732f
parent08326dbe7b5825295ec3711eec53b093549749e5 (diff)
xfrm: Revert false event eliding commits.
As reported by Alexey Dobriyan: -------------------- setkey now takes several seconds to run this simple script and it spits "recv: Resource temporarily unavailable" messages. #!/usr/sbin/setkey -f flush; spdflush; add A B ipcomp 44 -m tunnel -C deflate; add B A ipcomp 45 -m tunnel -C deflate; spdadd A B any -P in ipsec ipcomp/tunnel/192.168.1.2-192.168.1.3/use; spdadd B A any -P out ipsec ipcomp/tunnel/192.168.1.3-192.168.1.2/use; -------------------- Obviously applications want the events even when the table is empty. So we cannot make this behavioral change. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/key/af_key.c4
-rw-r--r--net/xfrm/xfrm_policy.c13
-rw-r--r--net/xfrm/xfrm_state.c8
-rw-r--r--net/xfrm/xfrm_user.c4
4 files changed, 9 insertions, 20 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 8b8e26a9e401..79d2c0f3c334 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1751,7 +1751,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
1751 audit_info.secid = 0; 1751 audit_info.secid = 0;
1752 err = xfrm_state_flush(net, proto, &audit_info); 1752 err = xfrm_state_flush(net, proto, &audit_info);
1753 if (err) 1753 if (err)
1754 return 0; 1754 return err;
1755 c.data.proto = proto; 1755 c.data.proto = proto;
1756 c.seq = hdr->sadb_msg_seq; 1756 c.seq = hdr->sadb_msg_seq;
1757 c.pid = hdr->sadb_msg_pid; 1757 c.pid = hdr->sadb_msg_pid;
@@ -2713,7 +2713,7 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg
2713 audit_info.secid = 0; 2713 audit_info.secid = 0;
2714 err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); 2714 err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info);
2715 if (err) 2715 if (err)
2716 return 0; 2716 return err;
2717 c.data.type = XFRM_POLICY_TYPE_MAIN; 2717 c.data.type = XFRM_POLICY_TYPE_MAIN;
2718 c.event = XFRM_MSG_FLUSHPOLICY; 2718 c.event = XFRM_MSG_FLUSHPOLICY;
2719 c.pid = hdr->sadb_msg_pid; 2719 c.pid = hdr->sadb_msg_pid;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index cfceb6616ec1..2c5d93181f13 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -771,8 +771,7 @@ 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, cnt = 0; 774 int dir, err = 0;
775 struct xfrm_policy *dp;
776 775
777 write_lock_bh(&xfrm_policy_lock); 776 write_lock_bh(&xfrm_policy_lock);
778 777
@@ -790,10 +789,8 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
790 &net->xfrm.policy_inexact[dir], bydst) { 789 &net->xfrm.policy_inexact[dir], bydst) {
791 if (pol->type != type) 790 if (pol->type != type)
792 continue; 791 continue;
793 dp = __xfrm_policy_unlink(pol, dir); 792 __xfrm_policy_unlink(pol, dir);
794 write_unlock_bh(&xfrm_policy_lock); 793 write_unlock_bh(&xfrm_policy_lock);
795 if (dp)
796 cnt++;
797 794
798 xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, 795 xfrm_audit_policy_delete(pol, 1, audit_info->loginuid,
799 audit_info->sessionid, 796 audit_info->sessionid,
@@ -812,10 +809,8 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
812 bydst) { 809 bydst) {
813 if (pol->type != type) 810 if (pol->type != type)
814 continue; 811 continue;
815 dp = __xfrm_policy_unlink(pol, dir); 812 __xfrm_policy_unlink(pol, dir);
816 write_unlock_bh(&xfrm_policy_lock); 813 write_unlock_bh(&xfrm_policy_lock);
817 if (dp)
818 cnt++;
819 814
820 xfrm_audit_policy_delete(pol, 1, 815 xfrm_audit_policy_delete(pol, 1,
821 audit_info->loginuid, 816 audit_info->loginuid,
@@ -829,8 +824,6 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
829 } 824 }
830 825
831 } 826 }
832 if (!cnt)
833 err = -ESRCH;
834 atomic_inc(&flow_cache_genid); 827 atomic_inc(&flow_cache_genid);
835out: 828out:
836 write_unlock_bh(&xfrm_policy_lock); 829 write_unlock_bh(&xfrm_policy_lock);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 9fa3322b2a7d..c9d6a5f1348d 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -603,14 +603,13 @@ xfrm_state_flush_secctx_check(struct net *net, u8 proto, struct xfrm_audit *audi
603 603
604int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info) 604int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info)
605{ 605{
606 int i, err = 0, cnt = 0; 606 int i, err = 0;
607 607
608 spin_lock_bh(&xfrm_state_lock); 608 spin_lock_bh(&xfrm_state_lock);
609 err = xfrm_state_flush_secctx_check(net, proto, audit_info); 609 err = xfrm_state_flush_secctx_check(net, proto, audit_info);
610 if (err) 610 if (err)
611 goto out; 611 goto out;
612 612
613 err = -ESRCH;
614 for (i = 0; i <= net->xfrm.state_hmask; i++) { 613 for (i = 0; i <= net->xfrm.state_hmask; i++) {
615 struct hlist_node *entry; 614 struct hlist_node *entry;
616 struct xfrm_state *x; 615 struct xfrm_state *x;
@@ -627,16 +626,13 @@ restart:
627 audit_info->sessionid, 626 audit_info->sessionid,
628 audit_info->secid); 627 audit_info->secid);
629 xfrm_state_put(x); 628 xfrm_state_put(x);
630 if (!err)
631 cnt++;
632 629
633 spin_lock_bh(&xfrm_state_lock); 630 spin_lock_bh(&xfrm_state_lock);
634 goto restart; 631 goto restart;
635 } 632 }
636 } 633 }
637 } 634 }
638 if (cnt) 635 err = 0;
639 err = 0;
640 636
641out: 637out:
642 spin_unlock_bh(&xfrm_state_lock); 638 spin_unlock_bh(&xfrm_state_lock);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index b0fb7d3bc15e..943c8712bd97 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1525,7 +1525,7 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
1525 audit_info.secid = NETLINK_CB(skb).sid; 1525 audit_info.secid = NETLINK_CB(skb).sid;
1526 err = xfrm_state_flush(net, p->proto, &audit_info); 1526 err = xfrm_state_flush(net, p->proto, &audit_info);
1527 if (err) 1527 if (err)
1528 return 0; 1528 return err;
1529 c.data.proto = p->proto; 1529 c.data.proto = p->proto;
1530 c.event = nlh->nlmsg_type; 1530 c.event = nlh->nlmsg_type;
1531 c.seq = nlh->nlmsg_seq; 1531 c.seq = nlh->nlmsg_seq;
@@ -1677,7 +1677,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1677 audit_info.secid = NETLINK_CB(skb).sid; 1677 audit_info.secid = NETLINK_CB(skb).sid;
1678 err = xfrm_policy_flush(net, type, &audit_info); 1678 err = xfrm_policy_flush(net, type, &audit_info);
1679 if (err) 1679 if (err)
1680 return 0; 1680 return err;
1681 c.data.type = type; 1681 c.data.type = type;
1682 c.event = nlh->nlmsg_type; 1682 c.event = nlh->nlmsg_type;
1683 c.seq = nlh->nlmsg_seq; 1683 c.seq = nlh->nlmsg_seq;