aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
authorFan Du <fan.du@windriver.com>2013-11-07 04:47:50 -0500
committerSteffen Klassert <steffen.klassert@secunet.com>2013-12-06 00:45:06 -0500
commit283bc9f35bbbcb0e9ab4e6d2427da7f9f710d52d (patch)
tree8b580340bdc0d1f25f4a76dfc39c48760f3f307a /net/xfrm/xfrm_policy.c
parent8d549c4f5d92d80fc6f888fd314e10972ae0ec37 (diff)
xfrm: Namespacify xfrm state/policy locks
By semantics, xfrm layer is fully name space aware, so will the locks, e.g. xfrm_state/pocliy_lock. Ensure exclusive access into state/policy link list for different name space with one global lock is not right in terms of semantics aspect at first place, as they are indeed mutually independent with each other, but also more seriously causes scalability problem. One practical scenario is on a Open Network Stack, more than hundreds of lxc tenants acts as routers within one host, a global xfrm_state/policy_lock becomes the bottleneck. But onces those locks are decoupled in a per-namespace fashion, locks contend is just with in specific name space scope, without causing additional SPD/SAD access delay for other name space. Also this patch improve scalability while as without changing original xfrm behavior. Signed-off-by: Fan Du <fan.du@windriver.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c104
1 files changed, 55 insertions, 49 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 907fd2fa70bc..73b04d3df44e 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -39,12 +39,7 @@
39#define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ)) 39#define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ))
40#define XFRM_MAX_QUEUE_LEN 100 40#define XFRM_MAX_QUEUE_LEN 100
41 41
42DEFINE_MUTEX(xfrm_cfg_mutex);
43EXPORT_SYMBOL(xfrm_cfg_mutex);
44
45static DEFINE_SPINLOCK(xfrm_policy_sk_bundle_lock);
46static struct dst_entry *xfrm_policy_sk_bundles; 42static struct dst_entry *xfrm_policy_sk_bundles;
47static DEFINE_RWLOCK(xfrm_policy_lock);
48 43
49static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock); 44static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock);
50static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO] 45static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO]
@@ -438,7 +433,7 @@ static void xfrm_bydst_resize(struct net *net, int dir)
438 if (!ndst) 433 if (!ndst)
439 return; 434 return;
440 435
441 write_lock_bh(&xfrm_policy_lock); 436 write_lock_bh(&net->xfrm.xfrm_policy_lock);
442 437
443 for (i = hmask; i >= 0; i--) 438 for (i = hmask; i >= 0; i--)
444 xfrm_dst_hash_transfer(odst + i, ndst, nhashmask); 439 xfrm_dst_hash_transfer(odst + i, ndst, nhashmask);
@@ -446,7 +441,7 @@ static void xfrm_bydst_resize(struct net *net, int dir)
446 net->xfrm.policy_bydst[dir].table = ndst; 441 net->xfrm.policy_bydst[dir].table = ndst;
447 net->xfrm.policy_bydst[dir].hmask = nhashmask; 442 net->xfrm.policy_bydst[dir].hmask = nhashmask;
448 443
449 write_unlock_bh(&xfrm_policy_lock); 444 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
450 445
451 xfrm_hash_free(odst, (hmask + 1) * sizeof(struct hlist_head)); 446 xfrm_hash_free(odst, (hmask + 1) * sizeof(struct hlist_head));
452} 447}
@@ -463,7 +458,7 @@ static void xfrm_byidx_resize(struct net *net, int total)
463 if (!nidx) 458 if (!nidx)
464 return; 459 return;
465 460
466 write_lock_bh(&xfrm_policy_lock); 461 write_lock_bh(&net->xfrm.xfrm_policy_lock);
467 462
468 for (i = hmask; i >= 0; i--) 463 for (i = hmask; i >= 0; i--)
469 xfrm_idx_hash_transfer(oidx + i, nidx, nhashmask); 464 xfrm_idx_hash_transfer(oidx + i, nidx, nhashmask);
@@ -471,7 +466,7 @@ static void xfrm_byidx_resize(struct net *net, int total)
471 net->xfrm.policy_byidx = nidx; 466 net->xfrm.policy_byidx = nidx;
472 net->xfrm.policy_idx_hmask = nhashmask; 467 net->xfrm.policy_idx_hmask = nhashmask;
473 468
474 write_unlock_bh(&xfrm_policy_lock); 469 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
475 470
476 xfrm_hash_free(oidx, (hmask + 1) * sizeof(struct hlist_head)); 471 xfrm_hash_free(oidx, (hmask + 1) * sizeof(struct hlist_head));
477} 472}
@@ -504,7 +499,7 @@ static inline int xfrm_byidx_should_resize(struct net *net, int total)
504 499
505void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si) 500void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si)
506{ 501{
507 read_lock_bh(&xfrm_policy_lock); 502 read_lock_bh(&net->xfrm.xfrm_policy_lock);
508 si->incnt = net->xfrm.policy_count[XFRM_POLICY_IN]; 503 si->incnt = net->xfrm.policy_count[XFRM_POLICY_IN];
509 si->outcnt = net->xfrm.policy_count[XFRM_POLICY_OUT]; 504 si->outcnt = net->xfrm.policy_count[XFRM_POLICY_OUT];
510 si->fwdcnt = net->xfrm.policy_count[XFRM_POLICY_FWD]; 505 si->fwdcnt = net->xfrm.policy_count[XFRM_POLICY_FWD];
@@ -513,7 +508,7 @@ void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si)
513 si->fwdscnt = net->xfrm.policy_count[XFRM_POLICY_FWD+XFRM_POLICY_MAX]; 508 si->fwdscnt = net->xfrm.policy_count[XFRM_POLICY_FWD+XFRM_POLICY_MAX];
514 si->spdhcnt = net->xfrm.policy_idx_hmask; 509 si->spdhcnt = net->xfrm.policy_idx_hmask;
515 si->spdhmcnt = xfrm_policy_hashmax; 510 si->spdhmcnt = xfrm_policy_hashmax;
516 read_unlock_bh(&xfrm_policy_lock); 511 read_unlock_bh(&net->xfrm.xfrm_policy_lock);
517} 512}
518EXPORT_SYMBOL(xfrm_spd_getinfo); 513EXPORT_SYMBOL(xfrm_spd_getinfo);
519 514
@@ -636,7 +631,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
636 struct hlist_head *chain; 631 struct hlist_head *chain;
637 struct hlist_node *newpos; 632 struct hlist_node *newpos;
638 633
639 write_lock_bh(&xfrm_policy_lock); 634 write_lock_bh(&net->xfrm.xfrm_policy_lock);
640 chain = policy_hash_bysel(net, &policy->selector, policy->family, dir); 635 chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
641 delpol = NULL; 636 delpol = NULL;
642 newpos = NULL; 637 newpos = NULL;
@@ -647,7 +642,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
647 xfrm_sec_ctx_match(pol->security, policy->security) && 642 xfrm_sec_ctx_match(pol->security, policy->security) &&
648 !WARN_ON(delpol)) { 643 !WARN_ON(delpol)) {
649 if (excl) { 644 if (excl) {
650 write_unlock_bh(&xfrm_policy_lock); 645 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
651 return -EEXIST; 646 return -EEXIST;
652 } 647 }
653 delpol = pol; 648 delpol = pol;
@@ -685,7 +680,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
685 if (!mod_timer(&policy->timer, jiffies + HZ)) 680 if (!mod_timer(&policy->timer, jiffies + HZ))
686 xfrm_pol_hold(policy); 681 xfrm_pol_hold(policy);
687 list_add(&policy->walk.all, &net->xfrm.policy_all); 682 list_add(&policy->walk.all, &net->xfrm.policy_all);
688 write_unlock_bh(&xfrm_policy_lock); 683 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
689 684
690 if (delpol) 685 if (delpol)
691 xfrm_policy_kill(delpol); 686 xfrm_policy_kill(delpol);
@@ -705,7 +700,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type,
705 struct hlist_head *chain; 700 struct hlist_head *chain;
706 701
707 *err = 0; 702 *err = 0;
708 write_lock_bh(&xfrm_policy_lock); 703 write_lock_bh(&net->xfrm.xfrm_policy_lock);
709 chain = policy_hash_bysel(net, sel, sel->family, dir); 704 chain = policy_hash_bysel(net, sel, sel->family, dir);
710 ret = NULL; 705 ret = NULL;
711 hlist_for_each_entry(pol, chain, bydst) { 706 hlist_for_each_entry(pol, chain, bydst) {
@@ -718,7 +713,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type,
718 *err = security_xfrm_policy_delete( 713 *err = security_xfrm_policy_delete(
719 pol->security); 714 pol->security);
720 if (*err) { 715 if (*err) {
721 write_unlock_bh(&xfrm_policy_lock); 716 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
722 return pol; 717 return pol;
723 } 718 }
724 __xfrm_policy_unlink(pol, dir); 719 __xfrm_policy_unlink(pol, dir);
@@ -727,7 +722,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type,
727 break; 722 break;
728 } 723 }
729 } 724 }
730 write_unlock_bh(&xfrm_policy_lock); 725 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
731 726
732 if (ret && delete) 727 if (ret && delete)
733 xfrm_policy_kill(ret); 728 xfrm_policy_kill(ret);
@@ -746,7 +741,7 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type,
746 return NULL; 741 return NULL;
747 742
748 *err = 0; 743 *err = 0;
749 write_lock_bh(&xfrm_policy_lock); 744 write_lock_bh(&net->xfrm.xfrm_policy_lock);
750 chain = net->xfrm.policy_byidx + idx_hash(net, id); 745 chain = net->xfrm.policy_byidx + idx_hash(net, id);
751 ret = NULL; 746 ret = NULL;
752 hlist_for_each_entry(pol, chain, byidx) { 747 hlist_for_each_entry(pol, chain, byidx) {
@@ -757,7 +752,7 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type,
757 *err = security_xfrm_policy_delete( 752 *err = security_xfrm_policy_delete(
758 pol->security); 753 pol->security);
759 if (*err) { 754 if (*err) {
760 write_unlock_bh(&xfrm_policy_lock); 755 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
761 return pol; 756 return pol;
762 } 757 }
763 __xfrm_policy_unlink(pol, dir); 758 __xfrm_policy_unlink(pol, dir);
@@ -766,7 +761,7 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type,
766 break; 761 break;
767 } 762 }
768 } 763 }
769 write_unlock_bh(&xfrm_policy_lock); 764 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
770 765
771 if (ret && delete) 766 if (ret && delete)
772 xfrm_policy_kill(ret); 767 xfrm_policy_kill(ret);
@@ -829,7 +824,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
829{ 824{
830 int dir, err = 0, cnt = 0; 825 int dir, err = 0, cnt = 0;
831 826
832 write_lock_bh(&xfrm_policy_lock); 827 write_lock_bh(&net->xfrm.xfrm_policy_lock);
833 828
834 err = xfrm_policy_flush_secctx_check(net, type, audit_info); 829 err = xfrm_policy_flush_secctx_check(net, type, audit_info);
835 if (err) 830 if (err)
@@ -845,7 +840,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
845 if (pol->type != type) 840 if (pol->type != type)
846 continue; 841 continue;
847 __xfrm_policy_unlink(pol, dir); 842 __xfrm_policy_unlink(pol, dir);
848 write_unlock_bh(&xfrm_policy_lock); 843 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
849 cnt++; 844 cnt++;
850 845
851 xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, 846 xfrm_audit_policy_delete(pol, 1, audit_info->loginuid,
@@ -854,7 +849,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
854 849
855 xfrm_policy_kill(pol); 850 xfrm_policy_kill(pol);
856 851
857 write_lock_bh(&xfrm_policy_lock); 852 write_lock_bh(&net->xfrm.xfrm_policy_lock);
858 goto again1; 853 goto again1;
859 } 854 }
860 855
@@ -866,7 +861,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
866 if (pol->type != type) 861 if (pol->type != type)
867 continue; 862 continue;
868 __xfrm_policy_unlink(pol, dir); 863 __xfrm_policy_unlink(pol, dir);
869 write_unlock_bh(&xfrm_policy_lock); 864 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
870 cnt++; 865 cnt++;
871 866
872 xfrm_audit_policy_delete(pol, 1, 867 xfrm_audit_policy_delete(pol, 1,
@@ -875,7 +870,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
875 audit_info->secid); 870 audit_info->secid);
876 xfrm_policy_kill(pol); 871 xfrm_policy_kill(pol);
877 872
878 write_lock_bh(&xfrm_policy_lock); 873 write_lock_bh(&net->xfrm.xfrm_policy_lock);
879 goto again2; 874 goto again2;
880 } 875 }
881 } 876 }
@@ -884,7 +879,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
884 if (!cnt) 879 if (!cnt)
885 err = -ESRCH; 880 err = -ESRCH;
886out: 881out:
887 write_unlock_bh(&xfrm_policy_lock); 882 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
888 return err; 883 return err;
889} 884}
890EXPORT_SYMBOL(xfrm_policy_flush); 885EXPORT_SYMBOL(xfrm_policy_flush);
@@ -904,7 +899,7 @@ int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
904 if (list_empty(&walk->walk.all) && walk->seq != 0) 899 if (list_empty(&walk->walk.all) && walk->seq != 0)
905 return 0; 900 return 0;
906 901
907 write_lock_bh(&xfrm_policy_lock); 902 write_lock_bh(&net->xfrm.xfrm_policy_lock);
908 if (list_empty(&walk->walk.all)) 903 if (list_empty(&walk->walk.all))
909 x = list_first_entry(&net->xfrm.policy_all, struct xfrm_policy_walk_entry, all); 904 x = list_first_entry(&net->xfrm.policy_all, struct xfrm_policy_walk_entry, all);
910 else 905 else
@@ -930,7 +925,7 @@ int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
930 } 925 }
931 list_del_init(&walk->walk.all); 926 list_del_init(&walk->walk.all);
932out: 927out:
933 write_unlock_bh(&xfrm_policy_lock); 928 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
934 return error; 929 return error;
935} 930}
936EXPORT_SYMBOL(xfrm_policy_walk); 931EXPORT_SYMBOL(xfrm_policy_walk);
@@ -944,14 +939,14 @@ void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type)
944} 939}
945EXPORT_SYMBOL(xfrm_policy_walk_init); 940EXPORT_SYMBOL(xfrm_policy_walk_init);
946 941
947void xfrm_policy_walk_done(struct xfrm_policy_walk *walk) 942void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net)
948{ 943{
949 if (list_empty(&walk->walk.all)) 944 if (list_empty(&walk->walk.all))
950 return; 945 return;
951 946
952 write_lock_bh(&xfrm_policy_lock); 947 write_lock_bh(&net->xfrm.xfrm_policy_lock); /*FIXME where is net? */
953 list_del(&walk->walk.all); 948 list_del(&walk->walk.all);
954 write_unlock_bh(&xfrm_policy_lock); 949 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
955} 950}
956EXPORT_SYMBOL(xfrm_policy_walk_done); 951EXPORT_SYMBOL(xfrm_policy_walk_done);
957 952
@@ -996,7 +991,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type,
996 if (unlikely(!daddr || !saddr)) 991 if (unlikely(!daddr || !saddr))
997 return NULL; 992 return NULL;
998 993
999 read_lock_bh(&xfrm_policy_lock); 994 read_lock_bh(&net->xfrm.xfrm_policy_lock);
1000 chain = policy_hash_direct(net, daddr, saddr, family, dir); 995 chain = policy_hash_direct(net, daddr, saddr, family, dir);
1001 ret = NULL; 996 ret = NULL;
1002 hlist_for_each_entry(pol, chain, bydst) { 997 hlist_for_each_entry(pol, chain, bydst) {
@@ -1032,7 +1027,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type,
1032 if (ret) 1027 if (ret)
1033 xfrm_pol_hold(ret); 1028 xfrm_pol_hold(ret);
1034fail: 1029fail:
1035 read_unlock_bh(&xfrm_policy_lock); 1030 read_unlock_bh(&net->xfrm.xfrm_policy_lock);
1036 1031
1037 return ret; 1032 return ret;
1038} 1033}
@@ -1109,8 +1104,9 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir,
1109 const struct flowi *fl) 1104 const struct flowi *fl)
1110{ 1105{
1111 struct xfrm_policy *pol; 1106 struct xfrm_policy *pol;
1107 struct net *net = sock_net(sk);
1112 1108
1113 read_lock_bh(&xfrm_policy_lock); 1109 read_lock_bh(&net->xfrm.xfrm_policy_lock);
1114 if ((pol = sk->sk_policy[dir]) != NULL) { 1110 if ((pol = sk->sk_policy[dir]) != NULL) {
1115 bool match = xfrm_selector_match(&pol->selector, fl, 1111 bool match = xfrm_selector_match(&pol->selector, fl,
1116 sk->sk_family); 1112 sk->sk_family);
@@ -1134,7 +1130,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir,
1134 pol = NULL; 1130 pol = NULL;
1135 } 1131 }
1136out: 1132out:
1137 read_unlock_bh(&xfrm_policy_lock); 1133 read_unlock_bh(&net->xfrm.xfrm_policy_lock);
1138 return pol; 1134 return pol;
1139} 1135}
1140 1136
@@ -1172,9 +1168,11 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
1172 1168
1173int xfrm_policy_delete(struct xfrm_policy *pol, int dir) 1169int xfrm_policy_delete(struct xfrm_policy *pol, int dir)
1174{ 1170{
1175 write_lock_bh(&xfrm_policy_lock); 1171 struct net *net = xp_net(pol);
1172
1173 write_lock_bh(&net->xfrm.xfrm_policy_lock);
1176 pol = __xfrm_policy_unlink(pol, dir); 1174 pol = __xfrm_policy_unlink(pol, dir);
1177 write_unlock_bh(&xfrm_policy_lock); 1175 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
1178 if (pol) { 1176 if (pol) {
1179 xfrm_policy_kill(pol); 1177 xfrm_policy_kill(pol);
1180 return 0; 1178 return 0;
@@ -1193,7 +1191,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
1193 return -EINVAL; 1191 return -EINVAL;
1194#endif 1192#endif
1195 1193
1196 write_lock_bh(&xfrm_policy_lock); 1194 write_lock_bh(&net->xfrm.xfrm_policy_lock);
1197 old_pol = sk->sk_policy[dir]; 1195 old_pol = sk->sk_policy[dir];
1198 sk->sk_policy[dir] = pol; 1196 sk->sk_policy[dir] = pol;
1199 if (pol) { 1197 if (pol) {
@@ -1210,7 +1208,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
1210 */ 1208 */
1211 __xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir); 1209 __xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir);
1212 } 1210 }
1213 write_unlock_bh(&xfrm_policy_lock); 1211 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
1214 1212
1215 if (old_pol) { 1213 if (old_pol) {
1216 xfrm_policy_kill(old_pol); 1214 xfrm_policy_kill(old_pol);
@@ -1221,6 +1219,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
1221static struct xfrm_policy *clone_policy(const struct xfrm_policy *old, int dir) 1219static struct xfrm_policy *clone_policy(const struct xfrm_policy *old, int dir)
1222{ 1220{
1223 struct xfrm_policy *newp = xfrm_policy_alloc(xp_net(old), GFP_ATOMIC); 1221 struct xfrm_policy *newp = xfrm_policy_alloc(xp_net(old), GFP_ATOMIC);
1222 struct net *net = xp_net(old);
1224 1223
1225 if (newp) { 1224 if (newp) {
1226 newp->selector = old->selector; 1225 newp->selector = old->selector;
@@ -1239,9 +1238,9 @@ static struct xfrm_policy *clone_policy(const struct xfrm_policy *old, int dir)
1239 newp->type = old->type; 1238 newp->type = old->type;
1240 memcpy(newp->xfrm_vec, old->xfrm_vec, 1239 memcpy(newp->xfrm_vec, old->xfrm_vec,
1241 newp->xfrm_nr*sizeof(struct xfrm_tmpl)); 1240 newp->xfrm_nr*sizeof(struct xfrm_tmpl));
1242 write_lock_bh(&xfrm_policy_lock); 1241 write_lock_bh(&net->xfrm.xfrm_policy_lock);
1243 __xfrm_policy_link(newp, XFRM_POLICY_MAX+dir); 1242 __xfrm_policy_link(newp, XFRM_POLICY_MAX+dir);
1244 write_unlock_bh(&xfrm_policy_lock); 1243 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
1245 xfrm_pol_put(newp); 1244 xfrm_pol_put(newp);
1246 } 1245 }
1247 return newp; 1246 return newp;
@@ -2112,10 +2111,10 @@ restart:
2112 2111
2113 dst_hold(&xdst->u.dst); 2112 dst_hold(&xdst->u.dst);
2114 2113
2115 spin_lock_bh(&xfrm_policy_sk_bundle_lock); 2114 spin_lock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock);
2116 xdst->u.dst.next = xfrm_policy_sk_bundles; 2115 xdst->u.dst.next = xfrm_policy_sk_bundles;
2117 xfrm_policy_sk_bundles = &xdst->u.dst; 2116 xfrm_policy_sk_bundles = &xdst->u.dst;
2118 spin_unlock_bh(&xfrm_policy_sk_bundle_lock); 2117 spin_unlock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock);
2119 2118
2120 route = xdst->route; 2119 route = xdst->route;
2121 } 2120 }
@@ -2440,7 +2439,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
2440 } 2439 }
2441 xfrm_nr = ti; 2440 xfrm_nr = ti;
2442 if (npols > 1) { 2441 if (npols > 1) {
2443 xfrm_tmpl_sort(stp, tpp, xfrm_nr, family); 2442 xfrm_tmpl_sort(stp, tpp, xfrm_nr, family, net);
2444 tpp = stp; 2443 tpp = stp;
2445 } 2444 }
2446 2445
@@ -2569,10 +2568,10 @@ static void __xfrm_garbage_collect(struct net *net)
2569{ 2568{
2570 struct dst_entry *head, *next; 2569 struct dst_entry *head, *next;
2571 2570
2572 spin_lock_bh(&xfrm_policy_sk_bundle_lock); 2571 spin_lock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock);
2573 head = xfrm_policy_sk_bundles; 2572 head = xfrm_policy_sk_bundles;
2574 xfrm_policy_sk_bundles = NULL; 2573 xfrm_policy_sk_bundles = NULL;
2575 spin_unlock_bh(&xfrm_policy_sk_bundle_lock); 2574 spin_unlock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock);
2576 2575
2577 while (head) { 2576 while (head) {
2578 next = head->next; 2577 next = head->next;
@@ -2956,6 +2955,13 @@ static int __net_init xfrm_net_init(struct net *net)
2956 rv = xfrm_sysctl_init(net); 2955 rv = xfrm_sysctl_init(net);
2957 if (rv < 0) 2956 if (rv < 0)
2958 goto out_sysctl; 2957 goto out_sysctl;
2958
2959 /* Initialize the per-net locks here */
2960 spin_lock_init(&net->xfrm.xfrm_state_lock);
2961 rwlock_init(&net->xfrm.xfrm_policy_lock);
2962 spin_lock_init(&net->xfrm.xfrm_policy_sk_bundle_lock);
2963 mutex_init(&net->xfrm.xfrm_cfg_mutex);
2964
2959 return 0; 2965 return 0;
2960 2966
2961out_sysctl: 2967out_sysctl:
@@ -3082,7 +3088,7 @@ static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector
3082 struct hlist_head *chain; 3088 struct hlist_head *chain;
3083 u32 priority = ~0U; 3089 u32 priority = ~0U;
3084 3090
3085 read_lock_bh(&xfrm_policy_lock); 3091 read_lock_bh(&net->xfrm.xfrm_policy_lock); /*FIXME*/
3086 chain = policy_hash_direct(net, &sel->daddr, &sel->saddr, sel->family, dir); 3092 chain = policy_hash_direct(net, &sel->daddr, &sel->saddr, sel->family, dir);
3087 hlist_for_each_entry(pol, chain, bydst) { 3093 hlist_for_each_entry(pol, chain, bydst) {
3088 if (xfrm_migrate_selector_match(sel, &pol->selector) && 3094 if (xfrm_migrate_selector_match(sel, &pol->selector) &&
@@ -3105,7 +3111,7 @@ static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector
3105 if (ret) 3111 if (ret)
3106 xfrm_pol_hold(ret); 3112 xfrm_pol_hold(ret);
3107 3113
3108 read_unlock_bh(&xfrm_policy_lock); 3114 read_unlock_bh(&net->xfrm.xfrm_policy_lock);
3109 3115
3110 return ret; 3116 return ret;
3111} 3117}
@@ -3236,7 +3242,7 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
3236 3242
3237 /* Stage 2 - find and update state(s) */ 3243 /* Stage 2 - find and update state(s) */
3238 for (i = 0, mp = m; i < num_migrate; i++, mp++) { 3244 for (i = 0, mp = m; i < num_migrate; i++, mp++) {
3239 if ((x = xfrm_migrate_state_find(mp))) { 3245 if ((x = xfrm_migrate_state_find(mp, net))) {
3240 x_cur[nx_cur] = x; 3246 x_cur[nx_cur] = x;
3241 nx_cur++; 3247 nx_cur++;
3242 if ((xc = xfrm_state_migrate(x, mp))) { 3248 if ((xc = xfrm_state_migrate(x, mp))) {