diff options
author | David S. Miller <davem@davemloft.net> | 2010-02-17 16:41:40 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-17 16:41:40 -0500 |
commit | 069c474e88bb7753183f1eadbd7786c27888c8e3 (patch) | |
tree | 09b0385d34a2d0b302b1f61a2783bfcdc510732f | |
parent | 08326dbe7b5825295ec3711eec53b093549749e5 (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.c | 4 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 13 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 8 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 4 |
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 | ||
772 | int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | 772 | int 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); |
835 | out: | 828 | out: |
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 | ||
604 | int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info) | 604 | int 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 | ||
641 | out: | 637 | out: |
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; |