diff options
-rw-r--r-- | net/xfrm/xfrm_policy.c | 35 |
1 files changed, 10 insertions, 25 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 62a49a1f2475..9c068ab3a834 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -51,6 +51,9 @@ static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family); | |||
51 | static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); | 51 | static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); |
52 | static void xfrm_init_pmtu(struct dst_entry *dst); | 52 | static void xfrm_init_pmtu(struct dst_entry *dst); |
53 | 53 | ||
54 | static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, | ||
55 | int dir); | ||
56 | |||
54 | static inline int | 57 | static inline int |
55 | __xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl) | 58 | __xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl) |
56 | { | 59 | { |
@@ -584,12 +587,8 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
584 | xfrm_pol_hold(policy); | 587 | xfrm_pol_hold(policy); |
585 | net->xfrm.policy_count[dir]++; | 588 | net->xfrm.policy_count[dir]++; |
586 | atomic_inc(&flow_cache_genid); | 589 | atomic_inc(&flow_cache_genid); |
587 | if (delpol) { | 590 | if (delpol) |
588 | hlist_del(&delpol->bydst); | 591 | __xfrm_policy_unlink(delpol, dir); |
589 | hlist_del(&delpol->byidx); | ||
590 | list_del(&delpol->walk.all); | ||
591 | net->xfrm.policy_count[dir]--; | ||
592 | } | ||
593 | policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir); | 592 | policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir); |
594 | hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index)); | 593 | hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index)); |
595 | policy->curlft.add_time = get_seconds(); | 594 | policy->curlft.add_time = get_seconds(); |
@@ -661,10 +660,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u8 type, int dir, | |||
661 | write_unlock_bh(&xfrm_policy_lock); | 660 | write_unlock_bh(&xfrm_policy_lock); |
662 | return pol; | 661 | return pol; |
663 | } | 662 | } |
664 | hlist_del(&pol->bydst); | 663 | __xfrm_policy_unlink(pol, dir); |
665 | hlist_del(&pol->byidx); | ||
666 | list_del(&pol->walk.all); | ||
667 | net->xfrm.policy_count[dir]--; | ||
668 | } | 664 | } |
669 | ret = pol; | 665 | ret = pol; |
670 | break; | 666 | break; |
@@ -705,10 +701,7 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u8 type, int dir, u32 id, | |||
705 | write_unlock_bh(&xfrm_policy_lock); | 701 | write_unlock_bh(&xfrm_policy_lock); |
706 | return pol; | 702 | return pol; |
707 | } | 703 | } |
708 | hlist_del(&pol->bydst); | 704 | __xfrm_policy_unlink(pol, dir); |
709 | hlist_del(&pol->byidx); | ||
710 | list_del(&pol->walk.all); | ||
711 | net->xfrm.policy_count[dir]--; | ||
712 | } | 705 | } |
713 | ret = pol; | 706 | ret = pol; |
714 | break; | 707 | break; |
@@ -789,17 +782,14 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | |||
789 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | 782 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { |
790 | struct xfrm_policy *pol; | 783 | struct xfrm_policy *pol; |
791 | struct hlist_node *entry; | 784 | struct hlist_node *entry; |
792 | int i, killed; | 785 | int i; |
793 | 786 | ||
794 | killed = 0; | ||
795 | again1: | 787 | again1: |
796 | hlist_for_each_entry(pol, entry, | 788 | hlist_for_each_entry(pol, entry, |
797 | &net->xfrm.policy_inexact[dir], bydst) { | 789 | &net->xfrm.policy_inexact[dir], bydst) { |
798 | if (pol->type != type) | 790 | if (pol->type != type) |
799 | continue; | 791 | continue; |
800 | hlist_del(&pol->bydst); | 792 | __xfrm_policy_unlink(pol, dir); |
801 | hlist_del(&pol->byidx); | ||
802 | list_del(&pol->walk.all); | ||
803 | write_unlock_bh(&xfrm_policy_lock); | 793 | write_unlock_bh(&xfrm_policy_lock); |
804 | 794 | ||
805 | xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, | 795 | xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, |
@@ -807,7 +797,6 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | |||
807 | audit_info->secid); | 797 | audit_info->secid); |
808 | 798 | ||
809 | xfrm_policy_kill(pol); | 799 | xfrm_policy_kill(pol); |
810 | killed++; | ||
811 | 800 | ||
812 | write_lock_bh(&xfrm_policy_lock); | 801 | write_lock_bh(&xfrm_policy_lock); |
813 | goto again1; | 802 | goto again1; |
@@ -820,9 +809,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | |||
820 | bydst) { | 809 | bydst) { |
821 | if (pol->type != type) | 810 | if (pol->type != type) |
822 | continue; | 811 | continue; |
823 | hlist_del(&pol->bydst); | 812 | __xfrm_policy_unlink(pol, dir); |
824 | hlist_del(&pol->byidx); | ||
825 | list_del(&pol->walk.all); | ||
826 | write_unlock_bh(&xfrm_policy_lock); | 813 | write_unlock_bh(&xfrm_policy_lock); |
827 | 814 | ||
828 | xfrm_audit_policy_delete(pol, 1, | 815 | xfrm_audit_policy_delete(pol, 1, |
@@ -830,14 +817,12 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | |||
830 | audit_info->sessionid, | 817 | audit_info->sessionid, |
831 | audit_info->secid); | 818 | audit_info->secid); |
832 | xfrm_policy_kill(pol); | 819 | xfrm_policy_kill(pol); |
833 | killed++; | ||
834 | 820 | ||
835 | write_lock_bh(&xfrm_policy_lock); | 821 | write_lock_bh(&xfrm_policy_lock); |
836 | goto again2; | 822 | goto again2; |
837 | } | 823 | } |
838 | } | 824 | } |
839 | 825 | ||
840 | net->xfrm.policy_count[dir] -= killed; | ||
841 | } | 826 | } |
842 | atomic_inc(&flow_cache_genid); | 827 | atomic_inc(&flow_cache_genid); |
843 | out: | 828 | out: |