aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c123
1 files changed, 65 insertions, 58 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 841b32a2e680..832b47c1de80 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -34,7 +34,7 @@
34 34
35#include "xfrm_hash.h" 35#include "xfrm_hash.h"
36 36
37int sysctl_xfrm_larval_drop __read_mostly; 37int sysctl_xfrm_larval_drop __read_mostly = 1;
38 38
39#ifdef CONFIG_XFRM_STATISTICS 39#ifdef CONFIG_XFRM_STATISTICS
40DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics) __read_mostly; 40DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics) __read_mostly;
@@ -46,7 +46,7 @@ EXPORT_SYMBOL(xfrm_cfg_mutex);
46 46
47static DEFINE_RWLOCK(xfrm_policy_lock); 47static DEFINE_RWLOCK(xfrm_policy_lock);
48 48
49static struct list_head xfrm_policy_bytype[XFRM_POLICY_TYPE_MAX]; 49static struct list_head xfrm_policy_all;
50unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2]; 50unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2];
51EXPORT_SYMBOL(xfrm_policy_count); 51EXPORT_SYMBOL(xfrm_policy_count);
52 52
@@ -164,7 +164,7 @@ static void xfrm_policy_timer(unsigned long data)
164 164
165 read_lock(&xp->lock); 165 read_lock(&xp->lock);
166 166
167 if (xp->dead) 167 if (xp->walk.dead)
168 goto out; 168 goto out;
169 169
170 dir = xfrm_policy_id2dir(xp->index); 170 dir = xfrm_policy_id2dir(xp->index);
@@ -236,7 +236,7 @@ struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp)
236 policy = kzalloc(sizeof(struct xfrm_policy), gfp); 236 policy = kzalloc(sizeof(struct xfrm_policy), gfp);
237 237
238 if (policy) { 238 if (policy) {
239 INIT_LIST_HEAD(&policy->bytype); 239 INIT_LIST_HEAD(&policy->walk.all);
240 INIT_HLIST_NODE(&policy->bydst); 240 INIT_HLIST_NODE(&policy->bydst);
241 INIT_HLIST_NODE(&policy->byidx); 241 INIT_HLIST_NODE(&policy->byidx);
242 rwlock_init(&policy->lock); 242 rwlock_init(&policy->lock);
@@ -252,17 +252,13 @@ EXPORT_SYMBOL(xfrm_policy_alloc);
252 252
253void xfrm_policy_destroy(struct xfrm_policy *policy) 253void xfrm_policy_destroy(struct xfrm_policy *policy)
254{ 254{
255 BUG_ON(!policy->dead); 255 BUG_ON(!policy->walk.dead);
256 256
257 BUG_ON(policy->bundles); 257 BUG_ON(policy->bundles);
258 258
259 if (del_timer(&policy->timer)) 259 if (del_timer(&policy->timer))
260 BUG(); 260 BUG();
261 261
262 write_lock_bh(&xfrm_policy_lock);
263 list_del(&policy->bytype);
264 write_unlock_bh(&xfrm_policy_lock);
265
266 security_xfrm_policy_free(policy->security); 262 security_xfrm_policy_free(policy->security);
267 kfree(policy); 263 kfree(policy);
268} 264}
@@ -310,8 +306,8 @@ static void xfrm_policy_kill(struct xfrm_policy *policy)
310 int dead; 306 int dead;
311 307
312 write_lock_bh(&policy->lock); 308 write_lock_bh(&policy->lock);
313 dead = policy->dead; 309 dead = policy->walk.dead;
314 policy->dead = 1; 310 policy->walk.dead = 1;
315 write_unlock_bh(&policy->lock); 311 write_unlock_bh(&policy->lock);
316 312
317 if (unlikely(dead)) { 313 if (unlikely(dead)) {
@@ -609,6 +605,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
609 if (delpol) { 605 if (delpol) {
610 hlist_del(&delpol->bydst); 606 hlist_del(&delpol->bydst);
611 hlist_del(&delpol->byidx); 607 hlist_del(&delpol->byidx);
608 list_del(&delpol->walk.all);
612 xfrm_policy_count[dir]--; 609 xfrm_policy_count[dir]--;
613 } 610 }
614 policy->index = delpol ? delpol->index : xfrm_gen_index(policy->type, dir); 611 policy->index = delpol ? delpol->index : xfrm_gen_index(policy->type, dir);
@@ -617,7 +614,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
617 policy->curlft.use_time = 0; 614 policy->curlft.use_time = 0;
618 if (!mod_timer(&policy->timer, jiffies + HZ)) 615 if (!mod_timer(&policy->timer, jiffies + HZ))
619 xfrm_pol_hold(policy); 616 xfrm_pol_hold(policy);
620 list_add_tail(&policy->bytype, &xfrm_policy_bytype[policy->type]); 617 list_add(&policy->walk.all, &xfrm_policy_all);
621 write_unlock_bh(&xfrm_policy_lock); 618 write_unlock_bh(&xfrm_policy_lock);
622 619
623 if (delpol) 620 if (delpol)
@@ -684,6 +681,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
684 } 681 }
685 hlist_del(&pol->bydst); 682 hlist_del(&pol->bydst);
686 hlist_del(&pol->byidx); 683 hlist_del(&pol->byidx);
684 list_del(&pol->walk.all);
687 xfrm_policy_count[dir]--; 685 xfrm_policy_count[dir]--;
688 } 686 }
689 ret = pol; 687 ret = pol;
@@ -727,6 +725,7 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
727 } 725 }
728 hlist_del(&pol->bydst); 726 hlist_del(&pol->bydst);
729 hlist_del(&pol->byidx); 727 hlist_del(&pol->byidx);
728 list_del(&pol->walk.all);
730 xfrm_policy_count[dir]--; 729 xfrm_policy_count[dir]--;
731 } 730 }
732 ret = pol; 731 ret = pol;
@@ -840,6 +839,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
840 continue; 839 continue;
841 hlist_del(&pol->bydst); 840 hlist_del(&pol->bydst);
842 hlist_del(&pol->byidx); 841 hlist_del(&pol->byidx);
842 list_del(&pol->walk.all);
843 write_unlock_bh(&xfrm_policy_lock); 843 write_unlock_bh(&xfrm_policy_lock);
844 844
845 xfrm_audit_policy_delete(pol, 1, 845 xfrm_audit_policy_delete(pol, 1,
@@ -867,60 +867,68 @@ int xfrm_policy_walk(struct xfrm_policy_walk *walk,
867 int (*func)(struct xfrm_policy *, int, int, void*), 867 int (*func)(struct xfrm_policy *, int, int, void*),
868 void *data) 868 void *data)
869{ 869{
870 struct xfrm_policy *old, *pol, *last = NULL; 870 struct xfrm_policy *pol;
871 struct xfrm_policy_walk_entry *x;
871 int error = 0; 872 int error = 0;
872 873
873 if (walk->type >= XFRM_POLICY_TYPE_MAX && 874 if (walk->type >= XFRM_POLICY_TYPE_MAX &&
874 walk->type != XFRM_POLICY_TYPE_ANY) 875 walk->type != XFRM_POLICY_TYPE_ANY)
875 return -EINVAL; 876 return -EINVAL;
876 877
877 if (walk->policy == NULL && walk->count != 0) 878 if (list_empty(&walk->walk.all) && walk->seq != 0)
878 return 0; 879 return 0;
879 880
880 old = pol = walk->policy; 881 write_lock_bh(&xfrm_policy_lock);
881 walk->policy = NULL; 882 if (list_empty(&walk->walk.all))
882 read_lock_bh(&xfrm_policy_lock); 883 x = list_first_entry(&xfrm_policy_all, struct xfrm_policy_walk_entry, all);
883 884 else
884 for (; walk->cur_type < XFRM_POLICY_TYPE_MAX; walk->cur_type++) { 885 x = list_entry(&walk->walk.all, struct xfrm_policy_walk_entry, all);
885 if (walk->type != walk->cur_type && 886 list_for_each_entry_from(x, &xfrm_policy_all, all) {
886 walk->type != XFRM_POLICY_TYPE_ANY) 887 if (x->dead)
887 continue; 888 continue;
888 889 pol = container_of(x, struct xfrm_policy, walk);
889 if (pol == NULL) { 890 if (walk->type != XFRM_POLICY_TYPE_ANY &&
890 pol = list_first_entry(&xfrm_policy_bytype[walk->cur_type], 891 walk->type != pol->type)
891 struct xfrm_policy, bytype); 892 continue;
892 } 893 error = func(pol, xfrm_policy_id2dir(pol->index),
893 list_for_each_entry_from(pol, &xfrm_policy_bytype[walk->cur_type], bytype) { 894 walk->seq, data);
894 if (pol->dead) 895 if (error) {
895 continue; 896 list_move_tail(&walk->walk.all, &x->all);
896 if (last) { 897 goto out;
897 error = func(last, xfrm_policy_id2dir(last->index),
898 walk->count, data);
899 if (error) {
900 xfrm_pol_hold(last);
901 walk->policy = last;
902 goto out;
903 }
904 }
905 last = pol;
906 walk->count++;
907 } 898 }
908 pol = NULL; 899 walk->seq++;
909 } 900 }
910 if (walk->count == 0) { 901 if (walk->seq == 0) {
911 error = -ENOENT; 902 error = -ENOENT;
912 goto out; 903 goto out;
913 } 904 }
914 if (last) 905 list_del_init(&walk->walk.all);
915 error = func(last, xfrm_policy_id2dir(last->index), 0, data);
916out: 906out:
917 read_unlock_bh(&xfrm_policy_lock); 907 write_unlock_bh(&xfrm_policy_lock);
918 if (old != NULL)
919 xfrm_pol_put(old);
920 return error; 908 return error;
921} 909}
922EXPORT_SYMBOL(xfrm_policy_walk); 910EXPORT_SYMBOL(xfrm_policy_walk);
923 911
912void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type)
913{
914 INIT_LIST_HEAD(&walk->walk.all);
915 walk->walk.dead = 1;
916 walk->type = type;
917 walk->seq = 0;
918}
919EXPORT_SYMBOL(xfrm_policy_walk_init);
920
921void xfrm_policy_walk_done(struct xfrm_policy_walk *walk)
922{
923 if (list_empty(&walk->walk.all))
924 return;
925
926 write_lock_bh(&xfrm_policy_lock);
927 list_del(&walk->walk.all);
928 write_unlock_bh(&xfrm_policy_lock);
929}
930EXPORT_SYMBOL(xfrm_policy_walk_done);
931
924/* 932/*
925 * Find policy to apply to this flow. 933 * Find policy to apply to this flow.
926 * 934 *
@@ -1077,6 +1085,7 @@ static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
1077 struct hlist_head *chain = policy_hash_bysel(&pol->selector, 1085 struct hlist_head *chain = policy_hash_bysel(&pol->selector,
1078 pol->family, dir); 1086 pol->family, dir);
1079 1087
1088 list_add(&pol->walk.all, &xfrm_policy_all);
1080 hlist_add_head(&pol->bydst, chain); 1089 hlist_add_head(&pol->bydst, chain);
1081 hlist_add_head(&pol->byidx, xfrm_policy_byidx+idx_hash(pol->index)); 1090 hlist_add_head(&pol->byidx, xfrm_policy_byidx+idx_hash(pol->index));
1082 xfrm_policy_count[dir]++; 1091 xfrm_policy_count[dir]++;
@@ -1094,6 +1103,7 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
1094 1103
1095 hlist_del(&pol->bydst); 1104 hlist_del(&pol->bydst);
1096 hlist_del(&pol->byidx); 1105 hlist_del(&pol->byidx);
1106 list_del(&pol->walk.all);
1097 xfrm_policy_count[dir]--; 1107 xfrm_policy_count[dir]--;
1098 1108
1099 return pol; 1109 return pol;
@@ -1719,7 +1729,7 @@ restart:
1719 1729
1720 for (pi = 0; pi < npols; pi++) { 1730 for (pi = 0; pi < npols; pi++) {
1721 read_lock_bh(&pols[pi]->lock); 1731 read_lock_bh(&pols[pi]->lock);
1722 pol_dead |= pols[pi]->dead; 1732 pol_dead |= pols[pi]->walk.dead;
1723 read_unlock_bh(&pols[pi]->lock); 1733 read_unlock_bh(&pols[pi]->lock);
1724 } 1734 }
1725 1735
@@ -1731,8 +1741,7 @@ restart:
1731 * We can't enlist stable bundles either. 1741 * We can't enlist stable bundles either.
1732 */ 1742 */
1733 write_unlock_bh(&policy->lock); 1743 write_unlock_bh(&policy->lock);
1734 if (dst) 1744 dst_free(dst);
1735 dst_free(dst);
1736 1745
1737 if (pol_dead) 1746 if (pol_dead)
1738 XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLDEAD); 1747 XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLDEAD);
@@ -1748,8 +1757,7 @@ restart:
1748 err = xfrm_dst_update_origin(dst, fl); 1757 err = xfrm_dst_update_origin(dst, fl);
1749 if (unlikely(err)) { 1758 if (unlikely(err)) {
1750 write_unlock_bh(&policy->lock); 1759 write_unlock_bh(&policy->lock);
1751 if (dst) 1760 dst_free(dst);
1752 dst_free(dst);
1753 XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); 1761 XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
1754 goto error; 1762 goto error;
1755 } 1763 }
@@ -2416,9 +2424,7 @@ static void __init xfrm_policy_init(void)
2416 panic("XFRM: failed to allocate bydst hash\n"); 2424 panic("XFRM: failed to allocate bydst hash\n");
2417 } 2425 }
2418 2426
2419 for (dir = 0; dir < XFRM_POLICY_TYPE_MAX; dir++) 2427 INIT_LIST_HEAD(&xfrm_policy_all);
2420 INIT_LIST_HEAD(&xfrm_policy_bytype[dir]);
2421
2422 INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task); 2428 INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task);
2423 register_netdevice_notifier(&xfrm_dev_notifier); 2429 register_netdevice_notifier(&xfrm_dev_notifier);
2424} 2430}
@@ -2602,7 +2608,7 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol,
2602 int i, j, n = 0; 2608 int i, j, n = 0;
2603 2609
2604 write_lock_bh(&pol->lock); 2610 write_lock_bh(&pol->lock);
2605 if (unlikely(pol->dead)) { 2611 if (unlikely(pol->walk.dead)) {
2606 /* target policy has been deleted */ 2612 /* target policy has been deleted */
2607 write_unlock_bh(&pol->lock); 2613 write_unlock_bh(&pol->lock);
2608 return -ENOENT; 2614 return -ENOENT;
@@ -2673,7 +2679,8 @@ static int xfrm_migrate_check(struct xfrm_migrate *m, int num_migrate)
2673} 2679}
2674 2680
2675int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type, 2681int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
2676 struct xfrm_migrate *m, int num_migrate) 2682 struct xfrm_migrate *m, int num_migrate,
2683 struct xfrm_kmaddress *k)
2677{ 2684{
2678 int i, err, nx_cur = 0, nx_new = 0; 2685 int i, err, nx_cur = 0, nx_new = 0;
2679 struct xfrm_policy *pol = NULL; 2686 struct xfrm_policy *pol = NULL;
@@ -2717,7 +2724,7 @@ int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
2717 } 2724 }
2718 2725
2719 /* Stage 5 - announce */ 2726 /* Stage 5 - announce */
2720 km_migrate(sel, dir, type, m, num_migrate); 2727 km_migrate(sel, dir, type, m, num_migrate, k);
2721 2728
2722 xfrm_pol_put(pol); 2729 xfrm_pol_put(pol);
2723 2730