aboutsummaryrefslogtreecommitdiffstats
path: root/net
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
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')
-rw-r--r--net/key/af_key.c15
-rw-r--r--net/xfrm/xfrm_policy.c104
-rw-r--r--net/xfrm/xfrm_state.c104
-rw-r--r--net/xfrm/xfrm_user.c14
4 files changed, 129 insertions, 108 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 3fa811c46913..9a039acf37e8 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1785,7 +1785,9 @@ static int pfkey_dump_sa(struct pfkey_sock *pfk)
1785 1785
1786static void pfkey_dump_sa_done(struct pfkey_sock *pfk) 1786static void pfkey_dump_sa_done(struct pfkey_sock *pfk)
1787{ 1787{
1788 xfrm_state_walk_done(&pfk->dump.u.state); 1788 struct net *net = sock_net(&pfk->sk);
1789
1790 xfrm_state_walk_done(&pfk->dump.u.state, net);
1789} 1791}
1790 1792
1791static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs) 1793static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs)
@@ -1861,7 +1863,7 @@ static u32 gen_reqid(struct net *net)
1861 reqid = IPSEC_MANUAL_REQID_MAX+1; 1863 reqid = IPSEC_MANUAL_REQID_MAX+1;
1862 xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN); 1864 xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN);
1863 rc = xfrm_policy_walk(net, &walk, check_reqid, (void*)&reqid); 1865 rc = xfrm_policy_walk(net, &walk, check_reqid, (void*)&reqid);
1864 xfrm_policy_walk_done(&walk); 1866 xfrm_policy_walk_done(&walk, net);
1865 if (rc != -EEXIST) 1867 if (rc != -EEXIST)
1866 return reqid; 1868 return reqid;
1867 } while (reqid != start); 1869 } while (reqid != start);
@@ -2660,7 +2662,9 @@ static int pfkey_dump_sp(struct pfkey_sock *pfk)
2660 2662
2661static void pfkey_dump_sp_done(struct pfkey_sock *pfk) 2663static void pfkey_dump_sp_done(struct pfkey_sock *pfk)
2662{ 2664{
2663 xfrm_policy_walk_done(&pfk->dump.u.policy); 2665 struct net *net = sock_net((struct sock *)pfk);
2666
2667 xfrm_policy_walk_done(&pfk->dump.u.policy, net);
2664} 2668}
2665 2669
2666static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs) 2670static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs)
@@ -3570,6 +3574,7 @@ static int pfkey_sendmsg(struct kiocb *kiocb,
3570 struct sk_buff *skb = NULL; 3574 struct sk_buff *skb = NULL;
3571 struct sadb_msg *hdr = NULL; 3575 struct sadb_msg *hdr = NULL;
3572 int err; 3576 int err;
3577 struct net *net = sock_net(sk);
3573 3578
3574 err = -EOPNOTSUPP; 3579 err = -EOPNOTSUPP;
3575 if (msg->msg_flags & MSG_OOB) 3580 if (msg->msg_flags & MSG_OOB)
@@ -3592,9 +3597,9 @@ static int pfkey_sendmsg(struct kiocb *kiocb,
3592 if (!hdr) 3597 if (!hdr)
3593 goto out; 3598 goto out;
3594 3599
3595 mutex_lock(&xfrm_cfg_mutex); 3600 mutex_lock(&net->xfrm.xfrm_cfg_mutex);
3596 err = pfkey_process(sk, skb, hdr); 3601 err = pfkey_process(sk, skb, hdr);
3597 mutex_unlock(&xfrm_cfg_mutex); 3602 mutex_unlock(&net->xfrm.xfrm_cfg_mutex);
3598 3603
3599out: 3604out:
3600 if (err && hdr && pfkey_error(hdr, err, sk) == 0) 3605 if (err && hdr && pfkey_error(hdr, err, sk) == 0)
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))) {
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 68c2f357a183..290479d0746d 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -35,8 +35,6 @@
35 destination/tunnel endpoint. (output) 35 destination/tunnel endpoint. (output)
36 */ 36 */
37 37
38static DEFINE_SPINLOCK(xfrm_state_lock);
39
40static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024; 38static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
41 39
42static inline unsigned int xfrm_dst_hash(struct net *net, 40static inline unsigned int xfrm_dst_hash(struct net *net,
@@ -127,7 +125,7 @@ static void xfrm_hash_resize(struct work_struct *work)
127 goto out_unlock; 125 goto out_unlock;
128 } 126 }
129 127
130 spin_lock_bh(&xfrm_state_lock); 128 spin_lock_bh(&net->xfrm.xfrm_state_lock);
131 129
132 nhashmask = (nsize / sizeof(struct hlist_head)) - 1U; 130 nhashmask = (nsize / sizeof(struct hlist_head)) - 1U;
133 for (i = net->xfrm.state_hmask; i >= 0; i--) 131 for (i = net->xfrm.state_hmask; i >= 0; i--)
@@ -144,7 +142,7 @@ static void xfrm_hash_resize(struct work_struct *work)
144 net->xfrm.state_byspi = nspi; 142 net->xfrm.state_byspi = nspi;
145 net->xfrm.state_hmask = nhashmask; 143 net->xfrm.state_hmask = nhashmask;
146 144
147 spin_unlock_bh(&xfrm_state_lock); 145 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
148 146
149 osize = (ohashmask + 1) * sizeof(struct hlist_head); 147 osize = (ohashmask + 1) * sizeof(struct hlist_head);
150 xfrm_hash_free(odst, osize); 148 xfrm_hash_free(odst, osize);
@@ -535,14 +533,14 @@ int __xfrm_state_delete(struct xfrm_state *x)
535 533
536 if (x->km.state != XFRM_STATE_DEAD) { 534 if (x->km.state != XFRM_STATE_DEAD) {
537 x->km.state = XFRM_STATE_DEAD; 535 x->km.state = XFRM_STATE_DEAD;
538 spin_lock(&xfrm_state_lock); 536 spin_lock(&net->xfrm.xfrm_state_lock);
539 list_del(&x->km.all); 537 list_del(&x->km.all);
540 hlist_del(&x->bydst); 538 hlist_del(&x->bydst);
541 hlist_del(&x->bysrc); 539 hlist_del(&x->bysrc);
542 if (x->id.spi) 540 if (x->id.spi)
543 hlist_del(&x->byspi); 541 hlist_del(&x->byspi);
544 net->xfrm.state_num--; 542 net->xfrm.state_num--;
545 spin_unlock(&xfrm_state_lock); 543 spin_unlock(&net->xfrm.xfrm_state_lock);
546 544
547 /* All xfrm_state objects are created by xfrm_state_alloc. 545 /* All xfrm_state objects are created by xfrm_state_alloc.
548 * The xfrm_state_alloc call gives a reference, and that 546 * The xfrm_state_alloc call gives a reference, and that
@@ -603,7 +601,7 @@ int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info)
603{ 601{
604 int i, err = 0, cnt = 0; 602 int i, err = 0, cnt = 0;
605 603
606 spin_lock_bh(&xfrm_state_lock); 604 spin_lock_bh(&net->xfrm.xfrm_state_lock);
607 err = xfrm_state_flush_secctx_check(net, proto, audit_info); 605 err = xfrm_state_flush_secctx_check(net, proto, audit_info);
608 if (err) 606 if (err)
609 goto out; 607 goto out;
@@ -616,7 +614,7 @@ restart:
616 if (!xfrm_state_kern(x) && 614 if (!xfrm_state_kern(x) &&
617 xfrm_id_proto_match(x->id.proto, proto)) { 615 xfrm_id_proto_match(x->id.proto, proto)) {
618 xfrm_state_hold(x); 616 xfrm_state_hold(x);
619 spin_unlock_bh(&xfrm_state_lock); 617 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
620 618
621 err = xfrm_state_delete(x); 619 err = xfrm_state_delete(x);
622 xfrm_audit_state_delete(x, err ? 0 : 1, 620 xfrm_audit_state_delete(x, err ? 0 : 1,
@@ -627,7 +625,7 @@ restart:
627 if (!err) 625 if (!err)
628 cnt++; 626 cnt++;
629 627
630 spin_lock_bh(&xfrm_state_lock); 628 spin_lock_bh(&net->xfrm.xfrm_state_lock);
631 goto restart; 629 goto restart;
632 } 630 }
633 } 631 }
@@ -636,7 +634,7 @@ restart:
636 err = 0; 634 err = 0;
637 635
638out: 636out:
639 spin_unlock_bh(&xfrm_state_lock); 637 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
640 wake_up(&net->xfrm.km_waitq); 638 wake_up(&net->xfrm.km_waitq);
641 return err; 639 return err;
642} 640}
@@ -644,11 +642,11 @@ EXPORT_SYMBOL(xfrm_state_flush);
644 642
645void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si) 643void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si)
646{ 644{
647 spin_lock_bh(&xfrm_state_lock); 645 spin_lock_bh(&net->xfrm.xfrm_state_lock);
648 si->sadcnt = net->xfrm.state_num; 646 si->sadcnt = net->xfrm.state_num;
649 si->sadhcnt = net->xfrm.state_hmask; 647 si->sadhcnt = net->xfrm.state_hmask;
650 si->sadhmcnt = xfrm_state_hashmax; 648 si->sadhmcnt = xfrm_state_hashmax;
651 spin_unlock_bh(&xfrm_state_lock); 649 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
652} 650}
653EXPORT_SYMBOL(xfrm_sad_getinfo); 651EXPORT_SYMBOL(xfrm_sad_getinfo);
654 652
@@ -801,7 +799,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
801 799
802 to_put = NULL; 800 to_put = NULL;
803 801
804 spin_lock_bh(&xfrm_state_lock); 802 spin_lock_bh(&net->xfrm.xfrm_state_lock);
805 h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family); 803 h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family);
806 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) { 804 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
807 if (x->props.family == encap_family && 805 if (x->props.family == encap_family &&
@@ -886,7 +884,7 @@ out:
886 xfrm_state_hold(x); 884 xfrm_state_hold(x);
887 else 885 else
888 *err = acquire_in_progress ? -EAGAIN : error; 886 *err = acquire_in_progress ? -EAGAIN : error;
889 spin_unlock_bh(&xfrm_state_lock); 887 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
890 if (to_put) 888 if (to_put)
891 xfrm_state_put(to_put); 889 xfrm_state_put(to_put);
892 return x; 890 return x;
@@ -900,7 +898,7 @@ xfrm_stateonly_find(struct net *net, u32 mark,
900 unsigned int h; 898 unsigned int h;
901 struct xfrm_state *rx = NULL, *x = NULL; 899 struct xfrm_state *rx = NULL, *x = NULL;
902 900
903 spin_lock(&xfrm_state_lock); 901 spin_lock(&net->xfrm.xfrm_state_lock);
904 h = xfrm_dst_hash(net, daddr, saddr, reqid, family); 902 h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
905 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) { 903 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
906 if (x->props.family == family && 904 if (x->props.family == family &&
@@ -918,7 +916,7 @@ xfrm_stateonly_find(struct net *net, u32 mark,
918 916
919 if (rx) 917 if (rx)
920 xfrm_state_hold(rx); 918 xfrm_state_hold(rx);
921 spin_unlock(&xfrm_state_lock); 919 spin_unlock(&net->xfrm.xfrm_state_lock);
922 920
923 921
924 return rx; 922 return rx;
@@ -957,7 +955,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
957 xfrm_hash_grow_check(net, x->bydst.next != NULL); 955 xfrm_hash_grow_check(net, x->bydst.next != NULL);
958} 956}
959 957
960/* xfrm_state_lock is held */ 958/* net->xfrm.xfrm_state_lock is held */
961static void __xfrm_state_bump_genids(struct xfrm_state *xnew) 959static void __xfrm_state_bump_genids(struct xfrm_state *xnew)
962{ 960{
963 struct net *net = xs_net(xnew); 961 struct net *net = xs_net(xnew);
@@ -980,14 +978,16 @@ static void __xfrm_state_bump_genids(struct xfrm_state *xnew)
980 978
981void xfrm_state_insert(struct xfrm_state *x) 979void xfrm_state_insert(struct xfrm_state *x)
982{ 980{
983 spin_lock_bh(&xfrm_state_lock); 981 struct net *net = xs_net(x);
982
983 spin_lock_bh(&net->xfrm.xfrm_state_lock);
984 __xfrm_state_bump_genids(x); 984 __xfrm_state_bump_genids(x);
985 __xfrm_state_insert(x); 985 __xfrm_state_insert(x);
986 spin_unlock_bh(&xfrm_state_lock); 986 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
987} 987}
988EXPORT_SYMBOL(xfrm_state_insert); 988EXPORT_SYMBOL(xfrm_state_insert);
989 989
990/* xfrm_state_lock is held */ 990/* net->xfrm.xfrm_state_lock is held */
991static struct xfrm_state *__find_acq_core(struct net *net, 991static struct xfrm_state *__find_acq_core(struct net *net,
992 const struct xfrm_mark *m, 992 const struct xfrm_mark *m,
993 unsigned short family, u8 mode, 993 unsigned short family, u8 mode,
@@ -1079,7 +1079,7 @@ int xfrm_state_add(struct xfrm_state *x)
1079 1079
1080 to_put = NULL; 1080 to_put = NULL;
1081 1081
1082 spin_lock_bh(&xfrm_state_lock); 1082 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1083 1083
1084 x1 = __xfrm_state_locate(x, use_spi, family); 1084 x1 = __xfrm_state_locate(x, use_spi, family);
1085 if (x1) { 1085 if (x1) {
@@ -1108,7 +1108,7 @@ int xfrm_state_add(struct xfrm_state *x)
1108 err = 0; 1108 err = 0;
1109 1109
1110out: 1110out:
1111 spin_unlock_bh(&xfrm_state_lock); 1111 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1112 1112
1113 if (x1) { 1113 if (x1) {
1114 xfrm_state_delete(x1); 1114 xfrm_state_delete(x1);
@@ -1203,16 +1203,16 @@ out:
1203 return NULL; 1203 return NULL;
1204} 1204}
1205 1205
1206/* xfrm_state_lock is held */ 1206/* net->xfrm.xfrm_state_lock is held */
1207struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m) 1207struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net)
1208{ 1208{
1209 unsigned int h; 1209 unsigned int h;
1210 struct xfrm_state *x; 1210 struct xfrm_state *x;
1211 1211
1212 if (m->reqid) { 1212 if (m->reqid) {
1213 h = xfrm_dst_hash(&init_net, &m->old_daddr, &m->old_saddr, 1213 h = xfrm_dst_hash(net, &m->old_daddr, &m->old_saddr,
1214 m->reqid, m->old_family); 1214 m->reqid, m->old_family);
1215 hlist_for_each_entry(x, init_net.xfrm.state_bydst+h, bydst) { 1215 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
1216 if (x->props.mode != m->mode || 1216 if (x->props.mode != m->mode ||
1217 x->id.proto != m->proto) 1217 x->id.proto != m->proto)
1218 continue; 1218 continue;
@@ -1227,9 +1227,9 @@ struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m)
1227 return x; 1227 return x;
1228 } 1228 }
1229 } else { 1229 } else {
1230 h = xfrm_src_hash(&init_net, &m->old_daddr, &m->old_saddr, 1230 h = xfrm_src_hash(net, &m->old_daddr, &m->old_saddr,
1231 m->old_family); 1231 m->old_family);
1232 hlist_for_each_entry(x, init_net.xfrm.state_bysrc+h, bysrc) { 1232 hlist_for_each_entry(x, net->xfrm.state_bysrc+h, bysrc) {
1233 if (x->props.mode != m->mode || 1233 if (x->props.mode != m->mode ||
1234 x->id.proto != m->proto) 1234 x->id.proto != m->proto)
1235 continue; 1235 continue;
@@ -1283,10 +1283,11 @@ int xfrm_state_update(struct xfrm_state *x)
1283 struct xfrm_state *x1, *to_put; 1283 struct xfrm_state *x1, *to_put;
1284 int err; 1284 int err;
1285 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY); 1285 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
1286 struct net *net = xs_net(x);
1286 1287
1287 to_put = NULL; 1288 to_put = NULL;
1288 1289
1289 spin_lock_bh(&xfrm_state_lock); 1290 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1290 x1 = __xfrm_state_locate(x, use_spi, x->props.family); 1291 x1 = __xfrm_state_locate(x, use_spi, x->props.family);
1291 1292
1292 err = -ESRCH; 1293 err = -ESRCH;
@@ -1306,7 +1307,7 @@ int xfrm_state_update(struct xfrm_state *x)
1306 err = 0; 1307 err = 0;
1307 1308
1308out: 1309out:
1309 spin_unlock_bh(&xfrm_state_lock); 1310 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1310 1311
1311 if (to_put) 1312 if (to_put)
1312 xfrm_state_put(to_put); 1313 xfrm_state_put(to_put);
@@ -1377,9 +1378,9 @@ xfrm_state_lookup(struct net *net, u32 mark, const xfrm_address_t *daddr, __be32
1377{ 1378{
1378 struct xfrm_state *x; 1379 struct xfrm_state *x;
1379 1380
1380 spin_lock_bh(&xfrm_state_lock); 1381 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1381 x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family); 1382 x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family);
1382 spin_unlock_bh(&xfrm_state_lock); 1383 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1383 return x; 1384 return x;
1384} 1385}
1385EXPORT_SYMBOL(xfrm_state_lookup); 1386EXPORT_SYMBOL(xfrm_state_lookup);
@@ -1391,9 +1392,9 @@ xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1391{ 1392{
1392 struct xfrm_state *x; 1393 struct xfrm_state *x;
1393 1394
1394 spin_lock_bh(&xfrm_state_lock); 1395 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1395 x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family); 1396 x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family);
1396 spin_unlock_bh(&xfrm_state_lock); 1397 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1397 return x; 1398 return x;
1398} 1399}
1399EXPORT_SYMBOL(xfrm_state_lookup_byaddr); 1400EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
@@ -1405,9 +1406,9 @@ xfrm_find_acq(struct net *net, const struct xfrm_mark *mark, u8 mode, u32 reqid,
1405{ 1406{
1406 struct xfrm_state *x; 1407 struct xfrm_state *x;
1407 1408
1408 spin_lock_bh(&xfrm_state_lock); 1409 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1409 x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create); 1410 x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create);
1410 spin_unlock_bh(&xfrm_state_lock); 1411 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1411 1412
1412 return x; 1413 return x;
1413} 1414}
@@ -1416,17 +1417,17 @@ EXPORT_SYMBOL(xfrm_find_acq);
1416#ifdef CONFIG_XFRM_SUB_POLICY 1417#ifdef CONFIG_XFRM_SUB_POLICY
1417int 1418int
1418xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, 1419xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
1419 unsigned short family) 1420 unsigned short family, struct net *net)
1420{ 1421{
1421 int err = 0; 1422 int err = 0;
1422 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); 1423 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
1423 if (!afinfo) 1424 if (!afinfo)
1424 return -EAFNOSUPPORT; 1425 return -EAFNOSUPPORT;
1425 1426
1426 spin_lock_bh(&xfrm_state_lock); 1427 spin_lock_bh(&net->xfrm.xfrm_state_lock); /*FIXME*/
1427 if (afinfo->tmpl_sort) 1428 if (afinfo->tmpl_sort)
1428 err = afinfo->tmpl_sort(dst, src, n); 1429 err = afinfo->tmpl_sort(dst, src, n);
1429 spin_unlock_bh(&xfrm_state_lock); 1430 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1430 xfrm_state_put_afinfo(afinfo); 1431 xfrm_state_put_afinfo(afinfo);
1431 return err; 1432 return err;
1432} 1433}
@@ -1438,13 +1439,15 @@ xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1438{ 1439{
1439 int err = 0; 1440 int err = 0;
1440 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); 1441 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
1442 struct net *net = xs_net(*dst);
1443
1441 if (!afinfo) 1444 if (!afinfo)
1442 return -EAFNOSUPPORT; 1445 return -EAFNOSUPPORT;
1443 1446
1444 spin_lock_bh(&xfrm_state_lock); 1447 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1445 if (afinfo->state_sort) 1448 if (afinfo->state_sort)
1446 err = afinfo->state_sort(dst, src, n); 1449 err = afinfo->state_sort(dst, src, n);
1447 spin_unlock_bh(&xfrm_state_lock); 1450 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1448 xfrm_state_put_afinfo(afinfo); 1451 xfrm_state_put_afinfo(afinfo);
1449 return err; 1452 return err;
1450} 1453}
@@ -1476,9 +1479,9 @@ struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq)
1476{ 1479{
1477 struct xfrm_state *x; 1480 struct xfrm_state *x;
1478 1481
1479 spin_lock_bh(&xfrm_state_lock); 1482 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1480 x = __xfrm_find_acq_byseq(net, mark, seq); 1483 x = __xfrm_find_acq_byseq(net, mark, seq);
1481 spin_unlock_bh(&xfrm_state_lock); 1484 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1482 return x; 1485 return x;
1483} 1486}
1484EXPORT_SYMBOL(xfrm_find_acq_byseq); 1487EXPORT_SYMBOL(xfrm_find_acq_byseq);
@@ -1536,10 +1539,10 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
1536 } 1539 }
1537 } 1540 }
1538 if (x->id.spi) { 1541 if (x->id.spi) {
1539 spin_lock_bh(&xfrm_state_lock); 1542 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1540 h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family); 1543 h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family);
1541 hlist_add_head(&x->byspi, net->xfrm.state_byspi+h); 1544 hlist_add_head(&x->byspi, net->xfrm.state_byspi+h);
1542 spin_unlock_bh(&xfrm_state_lock); 1545 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1543 1546
1544 err = 0; 1547 err = 0;
1545 } 1548 }
@@ -1562,7 +1565,7 @@ int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1562 if (walk->seq != 0 && list_empty(&walk->all)) 1565 if (walk->seq != 0 && list_empty(&walk->all))
1563 return 0; 1566 return 0;
1564 1567
1565 spin_lock_bh(&xfrm_state_lock); 1568 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1566 if (list_empty(&walk->all)) 1569 if (list_empty(&walk->all))
1567 x = list_first_entry(&net->xfrm.state_all, struct xfrm_state_walk, all); 1570 x = list_first_entry(&net->xfrm.state_all, struct xfrm_state_walk, all);
1568 else 1571 else
@@ -1586,7 +1589,7 @@ int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1586 } 1589 }
1587 list_del_init(&walk->all); 1590 list_del_init(&walk->all);
1588out: 1591out:
1589 spin_unlock_bh(&xfrm_state_lock); 1592 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1590 return err; 1593 return err;
1591} 1594}
1592EXPORT_SYMBOL(xfrm_state_walk); 1595EXPORT_SYMBOL(xfrm_state_walk);
@@ -1600,14 +1603,14 @@ void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto)
1600} 1603}
1601EXPORT_SYMBOL(xfrm_state_walk_init); 1604EXPORT_SYMBOL(xfrm_state_walk_init);
1602 1605
1603void xfrm_state_walk_done(struct xfrm_state_walk *walk) 1606void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net)
1604{ 1607{
1605 if (list_empty(&walk->all)) 1608 if (list_empty(&walk->all))
1606 return; 1609 return;
1607 1610
1608 spin_lock_bh(&xfrm_state_lock); 1611 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1609 list_del(&walk->all); 1612 list_del(&walk->all);
1610 spin_unlock_bh(&xfrm_state_lock); 1613 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1611} 1614}
1612EXPORT_SYMBOL(xfrm_state_walk_done); 1615EXPORT_SYMBOL(xfrm_state_walk_done);
1613 1616
@@ -2026,6 +2029,7 @@ int __net_init xfrm_state_init(struct net *net)
2026 INIT_HLIST_HEAD(&net->xfrm.state_gc_list); 2029 INIT_HLIST_HEAD(&net->xfrm.state_gc_list);
2027 INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task); 2030 INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task);
2028 init_waitqueue_head(&net->xfrm.km_waitq); 2031 init_waitqueue_head(&net->xfrm.km_waitq);
2032 spin_lock_init(&net->xfrm.xfrm_state_lock);
2029 return 0; 2033 return 0;
2030 2034
2031out_byspi: 2035out_byspi:
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 840cc8d9fbe4..16c84608e81e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -877,7 +877,10 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
877static int xfrm_dump_sa_done(struct netlink_callback *cb) 877static int xfrm_dump_sa_done(struct netlink_callback *cb)
878{ 878{
879 struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1]; 879 struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1];
880 xfrm_state_walk_done(walk); 880 struct sock *sk = cb->skb->sk;
881 struct net *net = sock_net(sk);
882
883 xfrm_state_walk_done(walk, net);
881 return 0; 884 return 0;
882} 885}
883 886
@@ -1555,8 +1558,9 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr
1555static int xfrm_dump_policy_done(struct netlink_callback *cb) 1558static int xfrm_dump_policy_done(struct netlink_callback *cb)
1556{ 1559{
1557 struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1]; 1560 struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
1561 struct net *net = sock_net(cb->skb->sk);
1558 1562
1559 xfrm_policy_walk_done(walk); 1563 xfrm_policy_walk_done(walk, net);
1560 return 0; 1564 return 0;
1561} 1565}
1562 1566
@@ -2403,9 +2407,11 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
2403 2407
2404static void xfrm_netlink_rcv(struct sk_buff *skb) 2408static void xfrm_netlink_rcv(struct sk_buff *skb)
2405{ 2409{
2406 mutex_lock(&xfrm_cfg_mutex); 2410 struct net *net = sock_net(skb->sk);
2411
2412 mutex_lock(&net->xfrm.xfrm_cfg_mutex);
2407 netlink_rcv_skb(skb, &xfrm_user_rcv_msg); 2413 netlink_rcv_skb(skb, &xfrm_user_rcv_msg);
2408 mutex_unlock(&xfrm_cfg_mutex); 2414 mutex_unlock(&net->xfrm.xfrm_cfg_mutex);
2409} 2415}
2410 2416
2411static inline size_t xfrm_expire_msgsize(void) 2417static inline size_t xfrm_expire_msgsize(void)