aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_policy.c35
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);
51static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); 51static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
52static void xfrm_init_pmtu(struct dst_entry *dst); 52static void xfrm_init_pmtu(struct dst_entry *dst);
53 53
54static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
55 int dir);
56
54static inline int 57static 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);
843out: 828out: