diff options
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 203 |
1 files changed, 100 insertions, 103 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 9a91f7431c41..4b98b25793c5 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 | ||
42 | DEFINE_MUTEX(xfrm_cfg_mutex); | ||
43 | EXPORT_SYMBOL(xfrm_cfg_mutex); | ||
44 | |||
45 | static DEFINE_SPINLOCK(xfrm_policy_sk_bundle_lock); | ||
46 | static struct dst_entry *xfrm_policy_sk_bundles; | 42 | static struct dst_entry *xfrm_policy_sk_bundles; |
47 | static DEFINE_RWLOCK(xfrm_policy_lock); | ||
48 | 43 | ||
49 | static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock); | 44 | static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock); |
50 | static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO] | 45 | static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO] |
@@ -176,7 +171,7 @@ static inline unsigned long make_jiffies(long secs) | |||
176 | 171 | ||
177 | static void xfrm_policy_timer(unsigned long data) | 172 | static void xfrm_policy_timer(unsigned long data) |
178 | { | 173 | { |
179 | struct xfrm_policy *xp = (struct xfrm_policy*)data; | 174 | struct xfrm_policy *xp = (struct xfrm_policy *)data; |
180 | unsigned long now = get_seconds(); | 175 | unsigned long now = get_seconds(); |
181 | long next = LONG_MAX; | 176 | long next = LONG_MAX; |
182 | int warn = 0; | 177 | int warn = 0; |
@@ -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 | ||
505 | void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si) | 500 | void 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 | } |
518 | EXPORT_SYMBOL(xfrm_spd_getinfo); | 513 | EXPORT_SYMBOL(xfrm_spd_getinfo); |
519 | 514 | ||
@@ -538,7 +533,7 @@ static void xfrm_hash_resize(struct work_struct *work) | |||
538 | 533 | ||
539 | /* Generate new index... KAME seems to generate them ordered by cost | 534 | /* Generate new index... KAME seems to generate them ordered by cost |
540 | * of an absolute inpredictability of ordering of rules. This will not pass. */ | 535 | * of an absolute inpredictability of ordering of rules. This will not pass. */ |
541 | static u32 xfrm_gen_index(struct net *net, int dir) | 536 | static u32 xfrm_gen_index(struct net *net, int dir, u32 index) |
542 | { | 537 | { |
543 | static u32 idx_generator; | 538 | static u32 idx_generator; |
544 | 539 | ||
@@ -548,8 +543,14 @@ static u32 xfrm_gen_index(struct net *net, int dir) | |||
548 | u32 idx; | 543 | u32 idx; |
549 | int found; | 544 | int found; |
550 | 545 | ||
551 | idx = (idx_generator | dir); | 546 | if (!index) { |
552 | idx_generator += 8; | 547 | idx = (idx_generator | dir); |
548 | idx_generator += 8; | ||
549 | } else { | ||
550 | idx = index; | ||
551 | index = 0; | ||
552 | } | ||
553 | |||
553 | if (idx == 0) | 554 | if (idx == 0) |
554 | idx = 8; | 555 | idx = 8; |
555 | list = net->xfrm.policy_byidx + idx_hash(net, idx); | 556 | list = net->xfrm.policy_byidx + idx_hash(net, idx); |
@@ -630,7 +631,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
630 | struct hlist_head *chain; | 631 | struct hlist_head *chain; |
631 | struct hlist_node *newpos; | 632 | struct hlist_node *newpos; |
632 | 633 | ||
633 | write_lock_bh(&xfrm_policy_lock); | 634 | write_lock_bh(&net->xfrm.xfrm_policy_lock); |
634 | chain = policy_hash_bysel(net, &policy->selector, policy->family, dir); | 635 | chain = policy_hash_bysel(net, &policy->selector, policy->family, dir); |
635 | delpol = NULL; | 636 | delpol = NULL; |
636 | newpos = NULL; | 637 | newpos = NULL; |
@@ -641,7 +642,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
641 | xfrm_sec_ctx_match(pol->security, policy->security) && | 642 | xfrm_sec_ctx_match(pol->security, policy->security) && |
642 | !WARN_ON(delpol)) { | 643 | !WARN_ON(delpol)) { |
643 | if (excl) { | 644 | if (excl) { |
644 | write_unlock_bh(&xfrm_policy_lock); | 645 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
645 | return -EEXIST; | 646 | return -EEXIST; |
646 | } | 647 | } |
647 | delpol = pol; | 648 | delpol = pol; |
@@ -672,14 +673,14 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
672 | xfrm_policy_requeue(delpol, policy); | 673 | xfrm_policy_requeue(delpol, policy); |
673 | __xfrm_policy_unlink(delpol, dir); | 674 | __xfrm_policy_unlink(delpol, dir); |
674 | } | 675 | } |
675 | policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir); | 676 | policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir, policy->index); |
676 | hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index)); | 677 | hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index)); |
677 | policy->curlft.add_time = get_seconds(); | 678 | policy->curlft.add_time = get_seconds(); |
678 | policy->curlft.use_time = 0; | 679 | policy->curlft.use_time = 0; |
679 | if (!mod_timer(&policy->timer, jiffies + HZ)) | 680 | if (!mod_timer(&policy->timer, jiffies + HZ)) |
680 | xfrm_pol_hold(policy); | 681 | xfrm_pol_hold(policy); |
681 | list_add(&policy->walk.all, &net->xfrm.policy_all); | 682 | list_add(&policy->walk.all, &net->xfrm.policy_all); |
682 | write_unlock_bh(&xfrm_policy_lock); | 683 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
683 | 684 | ||
684 | if (delpol) | 685 | if (delpol) |
685 | xfrm_policy_kill(delpol); | 686 | xfrm_policy_kill(delpol); |
@@ -699,7 +700,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type, | |||
699 | struct hlist_head *chain; | 700 | struct hlist_head *chain; |
700 | 701 | ||
701 | *err = 0; | 702 | *err = 0; |
702 | write_lock_bh(&xfrm_policy_lock); | 703 | write_lock_bh(&net->xfrm.xfrm_policy_lock); |
703 | chain = policy_hash_bysel(net, sel, sel->family, dir); | 704 | chain = policy_hash_bysel(net, sel, sel->family, dir); |
704 | ret = NULL; | 705 | ret = NULL; |
705 | hlist_for_each_entry(pol, chain, bydst) { | 706 | hlist_for_each_entry(pol, chain, bydst) { |
@@ -712,7 +713,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type, | |||
712 | *err = security_xfrm_policy_delete( | 713 | *err = security_xfrm_policy_delete( |
713 | pol->security); | 714 | pol->security); |
714 | if (*err) { | 715 | if (*err) { |
715 | write_unlock_bh(&xfrm_policy_lock); | 716 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
716 | return pol; | 717 | return pol; |
717 | } | 718 | } |
718 | __xfrm_policy_unlink(pol, dir); | 719 | __xfrm_policy_unlink(pol, dir); |
@@ -721,7 +722,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type, | |||
721 | break; | 722 | break; |
722 | } | 723 | } |
723 | } | 724 | } |
724 | write_unlock_bh(&xfrm_policy_lock); | 725 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
725 | 726 | ||
726 | if (ret && delete) | 727 | if (ret && delete) |
727 | xfrm_policy_kill(ret); | 728 | xfrm_policy_kill(ret); |
@@ -740,7 +741,7 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type, | |||
740 | return NULL; | 741 | return NULL; |
741 | 742 | ||
742 | *err = 0; | 743 | *err = 0; |
743 | write_lock_bh(&xfrm_policy_lock); | 744 | write_lock_bh(&net->xfrm.xfrm_policy_lock); |
744 | chain = net->xfrm.policy_byidx + idx_hash(net, id); | 745 | chain = net->xfrm.policy_byidx + idx_hash(net, id); |
745 | ret = NULL; | 746 | ret = NULL; |
746 | hlist_for_each_entry(pol, chain, byidx) { | 747 | hlist_for_each_entry(pol, chain, byidx) { |
@@ -751,7 +752,7 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type, | |||
751 | *err = security_xfrm_policy_delete( | 752 | *err = security_xfrm_policy_delete( |
752 | pol->security); | 753 | pol->security); |
753 | if (*err) { | 754 | if (*err) { |
754 | write_unlock_bh(&xfrm_policy_lock); | 755 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
755 | return pol; | 756 | return pol; |
756 | } | 757 | } |
757 | __xfrm_policy_unlink(pol, dir); | 758 | __xfrm_policy_unlink(pol, dir); |
@@ -760,7 +761,7 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type, | |||
760 | break; | 761 | break; |
761 | } | 762 | } |
762 | } | 763 | } |
763 | write_unlock_bh(&xfrm_policy_lock); | 764 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
764 | 765 | ||
765 | if (ret && delete) | 766 | if (ret && delete) |
766 | xfrm_policy_kill(ret); | 767 | xfrm_policy_kill(ret); |
@@ -823,7 +824,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | |||
823 | { | 824 | { |
824 | int dir, err = 0, cnt = 0; | 825 | int dir, err = 0, cnt = 0; |
825 | 826 | ||
826 | write_lock_bh(&xfrm_policy_lock); | 827 | write_lock_bh(&net->xfrm.xfrm_policy_lock); |
827 | 828 | ||
828 | err = xfrm_policy_flush_secctx_check(net, type, audit_info); | 829 | err = xfrm_policy_flush_secctx_check(net, type, audit_info); |
829 | if (err) | 830 | if (err) |
@@ -839,7 +840,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | |||
839 | if (pol->type != type) | 840 | if (pol->type != type) |
840 | continue; | 841 | continue; |
841 | __xfrm_policy_unlink(pol, dir); | 842 | __xfrm_policy_unlink(pol, dir); |
842 | write_unlock_bh(&xfrm_policy_lock); | 843 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
843 | cnt++; | 844 | cnt++; |
844 | 845 | ||
845 | xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, | 846 | xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, |
@@ -848,7 +849,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | |||
848 | 849 | ||
849 | xfrm_policy_kill(pol); | 850 | xfrm_policy_kill(pol); |
850 | 851 | ||
851 | write_lock_bh(&xfrm_policy_lock); | 852 | write_lock_bh(&net->xfrm.xfrm_policy_lock); |
852 | goto again1; | 853 | goto again1; |
853 | } | 854 | } |
854 | 855 | ||
@@ -860,7 +861,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | |||
860 | if (pol->type != type) | 861 | if (pol->type != type) |
861 | continue; | 862 | continue; |
862 | __xfrm_policy_unlink(pol, dir); | 863 | __xfrm_policy_unlink(pol, dir); |
863 | write_unlock_bh(&xfrm_policy_lock); | 864 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
864 | cnt++; | 865 | cnt++; |
865 | 866 | ||
866 | xfrm_audit_policy_delete(pol, 1, | 867 | xfrm_audit_policy_delete(pol, 1, |
@@ -869,7 +870,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | |||
869 | audit_info->secid); | 870 | audit_info->secid); |
870 | xfrm_policy_kill(pol); | 871 | xfrm_policy_kill(pol); |
871 | 872 | ||
872 | write_lock_bh(&xfrm_policy_lock); | 873 | write_lock_bh(&net->xfrm.xfrm_policy_lock); |
873 | goto again2; | 874 | goto again2; |
874 | } | 875 | } |
875 | } | 876 | } |
@@ -878,7 +879,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | |||
878 | if (!cnt) | 879 | if (!cnt) |
879 | err = -ESRCH; | 880 | err = -ESRCH; |
880 | out: | 881 | out: |
881 | write_unlock_bh(&xfrm_policy_lock); | 882 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
882 | return err; | 883 | return err; |
883 | } | 884 | } |
884 | EXPORT_SYMBOL(xfrm_policy_flush); | 885 | EXPORT_SYMBOL(xfrm_policy_flush); |
@@ -898,7 +899,7 @@ int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk, | |||
898 | if (list_empty(&walk->walk.all) && walk->seq != 0) | 899 | if (list_empty(&walk->walk.all) && walk->seq != 0) |
899 | return 0; | 900 | return 0; |
900 | 901 | ||
901 | write_lock_bh(&xfrm_policy_lock); | 902 | write_lock_bh(&net->xfrm.xfrm_policy_lock); |
902 | if (list_empty(&walk->walk.all)) | 903 | if (list_empty(&walk->walk.all)) |
903 | 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); |
904 | else | 905 | else |
@@ -924,7 +925,7 @@ int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk, | |||
924 | } | 925 | } |
925 | list_del_init(&walk->walk.all); | 926 | list_del_init(&walk->walk.all); |
926 | out: | 927 | out: |
927 | write_unlock_bh(&xfrm_policy_lock); | 928 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
928 | return error; | 929 | return error; |
929 | } | 930 | } |
930 | EXPORT_SYMBOL(xfrm_policy_walk); | 931 | EXPORT_SYMBOL(xfrm_policy_walk); |
@@ -938,14 +939,14 @@ void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type) | |||
938 | } | 939 | } |
939 | EXPORT_SYMBOL(xfrm_policy_walk_init); | 940 | EXPORT_SYMBOL(xfrm_policy_walk_init); |
940 | 941 | ||
941 | void xfrm_policy_walk_done(struct xfrm_policy_walk *walk) | 942 | void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net) |
942 | { | 943 | { |
943 | if (list_empty(&walk->walk.all)) | 944 | if (list_empty(&walk->walk.all)) |
944 | return; | 945 | return; |
945 | 946 | ||
946 | write_lock_bh(&xfrm_policy_lock); | 947 | write_lock_bh(&net->xfrm.xfrm_policy_lock); /*FIXME where is net? */ |
947 | list_del(&walk->walk.all); | 948 | list_del(&walk->walk.all); |
948 | write_unlock_bh(&xfrm_policy_lock); | 949 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
949 | } | 950 | } |
950 | EXPORT_SYMBOL(xfrm_policy_walk_done); | 951 | EXPORT_SYMBOL(xfrm_policy_walk_done); |
951 | 952 | ||
@@ -990,7 +991,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type, | |||
990 | if (unlikely(!daddr || !saddr)) | 991 | if (unlikely(!daddr || !saddr)) |
991 | return NULL; | 992 | return NULL; |
992 | 993 | ||
993 | read_lock_bh(&xfrm_policy_lock); | 994 | read_lock_bh(&net->xfrm.xfrm_policy_lock); |
994 | chain = policy_hash_direct(net, daddr, saddr, family, dir); | 995 | chain = policy_hash_direct(net, daddr, saddr, family, dir); |
995 | ret = NULL; | 996 | ret = NULL; |
996 | hlist_for_each_entry(pol, chain, bydst) { | 997 | hlist_for_each_entry(pol, chain, bydst) { |
@@ -1026,7 +1027,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type, | |||
1026 | if (ret) | 1027 | if (ret) |
1027 | xfrm_pol_hold(ret); | 1028 | xfrm_pol_hold(ret); |
1028 | fail: | 1029 | fail: |
1029 | read_unlock_bh(&xfrm_policy_lock); | 1030 | read_unlock_bh(&net->xfrm.xfrm_policy_lock); |
1030 | 1031 | ||
1031 | return ret; | 1032 | return ret; |
1032 | } | 1033 | } |
@@ -1103,8 +1104,9 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, | |||
1103 | const struct flowi *fl) | 1104 | const struct flowi *fl) |
1104 | { | 1105 | { |
1105 | struct xfrm_policy *pol; | 1106 | struct xfrm_policy *pol; |
1107 | struct net *net = sock_net(sk); | ||
1106 | 1108 | ||
1107 | read_lock_bh(&xfrm_policy_lock); | 1109 | read_lock_bh(&net->xfrm.xfrm_policy_lock); |
1108 | if ((pol = sk->sk_policy[dir]) != NULL) { | 1110 | if ((pol = sk->sk_policy[dir]) != NULL) { |
1109 | bool match = xfrm_selector_match(&pol->selector, fl, | 1111 | bool match = xfrm_selector_match(&pol->selector, fl, |
1110 | sk->sk_family); | 1112 | sk->sk_family); |
@@ -1128,7 +1130,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, | |||
1128 | pol = NULL; | 1130 | pol = NULL; |
1129 | } | 1131 | } |
1130 | out: | 1132 | out: |
1131 | read_unlock_bh(&xfrm_policy_lock); | 1133 | read_unlock_bh(&net->xfrm.xfrm_policy_lock); |
1132 | return pol; | 1134 | return pol; |
1133 | } | 1135 | } |
1134 | 1136 | ||
@@ -1166,9 +1168,11 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, | |||
1166 | 1168 | ||
1167 | int xfrm_policy_delete(struct xfrm_policy *pol, int dir) | 1169 | int xfrm_policy_delete(struct xfrm_policy *pol, int dir) |
1168 | { | 1170 | { |
1169 | write_lock_bh(&xfrm_policy_lock); | 1171 | struct net *net = xp_net(pol); |
1172 | |||
1173 | write_lock_bh(&net->xfrm.xfrm_policy_lock); | ||
1170 | pol = __xfrm_policy_unlink(pol, dir); | 1174 | pol = __xfrm_policy_unlink(pol, dir); |
1171 | write_unlock_bh(&xfrm_policy_lock); | 1175 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
1172 | if (pol) { | 1176 | if (pol) { |
1173 | xfrm_policy_kill(pol); | 1177 | xfrm_policy_kill(pol); |
1174 | return 0; | 1178 | return 0; |
@@ -1187,12 +1191,12 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol) | |||
1187 | return -EINVAL; | 1191 | return -EINVAL; |
1188 | #endif | 1192 | #endif |
1189 | 1193 | ||
1190 | write_lock_bh(&xfrm_policy_lock); | 1194 | write_lock_bh(&net->xfrm.xfrm_policy_lock); |
1191 | old_pol = sk->sk_policy[dir]; | 1195 | old_pol = sk->sk_policy[dir]; |
1192 | sk->sk_policy[dir] = pol; | 1196 | sk->sk_policy[dir] = pol; |
1193 | if (pol) { | 1197 | if (pol) { |
1194 | pol->curlft.add_time = get_seconds(); | 1198 | pol->curlft.add_time = get_seconds(); |
1195 | pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir); | 1199 | pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir, 0); |
1196 | __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir); | 1200 | __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir); |
1197 | } | 1201 | } |
1198 | if (old_pol) { | 1202 | if (old_pol) { |
@@ -1204,7 +1208,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol) | |||
1204 | */ | 1208 | */ |
1205 | __xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir); | 1209 | __xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir); |
1206 | } | 1210 | } |
1207 | write_unlock_bh(&xfrm_policy_lock); | 1211 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
1208 | 1212 | ||
1209 | if (old_pol) { | 1213 | if (old_pol) { |
1210 | xfrm_policy_kill(old_pol); | 1214 | xfrm_policy_kill(old_pol); |
@@ -1215,6 +1219,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol) | |||
1215 | static struct xfrm_policy *clone_policy(const struct xfrm_policy *old, int dir) | 1219 | static struct xfrm_policy *clone_policy(const struct xfrm_policy *old, int dir) |
1216 | { | 1220 | { |
1217 | 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); | ||
1218 | 1223 | ||
1219 | if (newp) { | 1224 | if (newp) { |
1220 | newp->selector = old->selector; | 1225 | newp->selector = old->selector; |
@@ -1233,9 +1238,9 @@ static struct xfrm_policy *clone_policy(const struct xfrm_policy *old, int dir) | |||
1233 | newp->type = old->type; | 1238 | newp->type = old->type; |
1234 | memcpy(newp->xfrm_vec, old->xfrm_vec, | 1239 | memcpy(newp->xfrm_vec, old->xfrm_vec, |
1235 | newp->xfrm_nr*sizeof(struct xfrm_tmpl)); | 1240 | newp->xfrm_nr*sizeof(struct xfrm_tmpl)); |
1236 | write_lock_bh(&xfrm_policy_lock); | 1241 | write_lock_bh(&net->xfrm.xfrm_policy_lock); |
1237 | __xfrm_policy_link(newp, XFRM_POLICY_MAX+dir); | 1242 | __xfrm_policy_link(newp, XFRM_POLICY_MAX+dir); |
1238 | write_unlock_bh(&xfrm_policy_lock); | 1243 | write_unlock_bh(&net->xfrm.xfrm_policy_lock); |
1239 | xfrm_pol_put(newp); | 1244 | xfrm_pol_put(newp); |
1240 | } | 1245 | } |
1241 | return newp; | 1246 | return newp; |
@@ -1281,7 +1286,7 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl, | |||
1281 | xfrm_address_t *saddr = xfrm_flowi_saddr(fl, family); | 1286 | xfrm_address_t *saddr = xfrm_flowi_saddr(fl, family); |
1282 | xfrm_address_t tmp; | 1287 | xfrm_address_t tmp; |
1283 | 1288 | ||
1284 | for (nx=0, i = 0; i < policy->xfrm_nr; i++) { | 1289 | for (nx = 0, i = 0; i < policy->xfrm_nr; i++) { |
1285 | struct xfrm_state *x; | 1290 | struct xfrm_state *x; |
1286 | xfrm_address_t *remote = daddr; | 1291 | xfrm_address_t *remote = daddr; |
1287 | xfrm_address_t *local = saddr; | 1292 | xfrm_address_t *local = saddr; |
@@ -1311,9 +1316,9 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl, | |||
1311 | error = (x->km.state == XFRM_STATE_ERROR ? | 1316 | error = (x->km.state == XFRM_STATE_ERROR ? |
1312 | -EINVAL : -EAGAIN); | 1317 | -EINVAL : -EAGAIN); |
1313 | xfrm_state_put(x); | 1318 | xfrm_state_put(x); |
1314 | } | 1319 | } else if (error == -ESRCH) { |
1315 | else if (error == -ESRCH) | ||
1316 | error = -EAGAIN; | 1320 | error = -EAGAIN; |
1321 | } | ||
1317 | 1322 | ||
1318 | if (!tmpl->optional) | 1323 | if (!tmpl->optional) |
1319 | goto fail; | 1324 | goto fail; |
@@ -1321,7 +1326,7 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl, | |||
1321 | return nx; | 1326 | return nx; |
1322 | 1327 | ||
1323 | fail: | 1328 | fail: |
1324 | for (nx--; nx>=0; nx--) | 1329 | for (nx--; nx >= 0; nx--) |
1325 | xfrm_state_put(xfrm[nx]); | 1330 | xfrm_state_put(xfrm[nx]); |
1326 | return error; | 1331 | return error; |
1327 | } | 1332 | } |
@@ -1358,7 +1363,7 @@ xfrm_tmpl_resolve(struct xfrm_policy **pols, int npols, const struct flowi *fl, | |||
1358 | return cnx; | 1363 | return cnx; |
1359 | 1364 | ||
1360 | fail: | 1365 | fail: |
1361 | for (cnx--; cnx>=0; cnx--) | 1366 | for (cnx--; cnx >= 0; cnx--) |
1362 | xfrm_state_put(tpp[cnx]); | 1367 | xfrm_state_put(tpp[cnx]); |
1363 | return error; | 1368 | return error; |
1364 | 1369 | ||
@@ -1636,20 +1641,22 @@ free_dst: | |||
1636 | goto out; | 1641 | goto out; |
1637 | } | 1642 | } |
1638 | 1643 | ||
1639 | static int inline | 1644 | #ifdef CONFIG_XFRM_SUB_POLICY |
1640 | xfrm_dst_alloc_copy(void **target, const void *src, int size) | 1645 | static int xfrm_dst_alloc_copy(void **target, const void *src, int size) |
1641 | { | 1646 | { |
1642 | if (!*target) { | 1647 | if (!*target) { |
1643 | *target = kmalloc(size, GFP_ATOMIC); | 1648 | *target = kmalloc(size, GFP_ATOMIC); |
1644 | if (!*target) | 1649 | if (!*target) |
1645 | return -ENOMEM; | 1650 | return -ENOMEM; |
1646 | } | 1651 | } |
1652 | |||
1647 | memcpy(*target, src, size); | 1653 | memcpy(*target, src, size); |
1648 | return 0; | 1654 | return 0; |
1649 | } | 1655 | } |
1656 | #endif | ||
1650 | 1657 | ||
1651 | static int inline | 1658 | static int xfrm_dst_update_parent(struct dst_entry *dst, |
1652 | xfrm_dst_update_parent(struct dst_entry *dst, const struct xfrm_selector *sel) | 1659 | const struct xfrm_selector *sel) |
1653 | { | 1660 | { |
1654 | #ifdef CONFIG_XFRM_SUB_POLICY | 1661 | #ifdef CONFIG_XFRM_SUB_POLICY |
1655 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | 1662 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; |
@@ -1660,8 +1667,8 @@ xfrm_dst_update_parent(struct dst_entry *dst, const struct xfrm_selector *sel) | |||
1660 | #endif | 1667 | #endif |
1661 | } | 1668 | } |
1662 | 1669 | ||
1663 | static int inline | 1670 | static int xfrm_dst_update_origin(struct dst_entry *dst, |
1664 | xfrm_dst_update_origin(struct dst_entry *dst, const struct flowi *fl) | 1671 | const struct flowi *fl) |
1665 | { | 1672 | { |
1666 | #ifdef CONFIG_XFRM_SUB_POLICY | 1673 | #ifdef CONFIG_XFRM_SUB_POLICY |
1667 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | 1674 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; |
@@ -1699,7 +1706,7 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family, | |||
1699 | xfrm_pols_put(pols, *num_pols); | 1706 | xfrm_pols_put(pols, *num_pols); |
1700 | return PTR_ERR(pols[1]); | 1707 | return PTR_ERR(pols[1]); |
1701 | } | 1708 | } |
1702 | (*num_pols) ++; | 1709 | (*num_pols)++; |
1703 | (*num_xfrms) += pols[1]->xfrm_nr; | 1710 | (*num_xfrms) += pols[1]->xfrm_nr; |
1704 | } | 1711 | } |
1705 | } | 1712 | } |
@@ -1753,7 +1760,7 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, | |||
1753 | } | 1760 | } |
1754 | 1761 | ||
1755 | xdst->num_pols = num_pols; | 1762 | xdst->num_pols = num_pols; |
1756 | memcpy(xdst->pols, pols, sizeof(struct xfrm_policy*) * num_pols); | 1763 | memcpy(xdst->pols, pols, sizeof(struct xfrm_policy *) * num_pols); |
1757 | xdst->policy_genid = atomic_read(&pols[0]->genid); | 1764 | xdst->policy_genid = atomic_read(&pols[0]->genid); |
1758 | 1765 | ||
1759 | return xdst; | 1766 | return xdst; |
@@ -1896,8 +1903,7 @@ static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net, | |||
1896 | if (IS_ERR(xdst)) | 1903 | if (IS_ERR(xdst)) |
1897 | return xdst; | 1904 | return xdst; |
1898 | 1905 | ||
1899 | if (net->xfrm.sysctl_larval_drop || num_xfrms <= 0 || | 1906 | if (net->xfrm.sysctl_larval_drop || num_xfrms <= 0) |
1900 | (fl->flowi_flags & FLOWI_FLAG_CAN_SLEEP)) | ||
1901 | return xdst; | 1907 | return xdst; |
1902 | 1908 | ||
1903 | dst1 = &xdst->u.dst; | 1909 | dst1 = &xdst->u.dst; |
@@ -2023,7 +2029,7 @@ make_dummy_bundle: | |||
2023 | } | 2029 | } |
2024 | xdst->num_pols = num_pols; | 2030 | xdst->num_pols = num_pols; |
2025 | xdst->num_xfrms = num_xfrms; | 2031 | xdst->num_xfrms = num_xfrms; |
2026 | memcpy(xdst->pols, pols, sizeof(struct xfrm_policy*) * num_pols); | 2032 | memcpy(xdst->pols, pols, sizeof(struct xfrm_policy *) * num_pols); |
2027 | 2033 | ||
2028 | dst_hold(&xdst->u.dst); | 2034 | dst_hold(&xdst->u.dst); |
2029 | return &xdst->flo; | 2035 | return &xdst->flo; |
@@ -2072,7 +2078,6 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, | |||
2072 | u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT); | 2078 | u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT); |
2073 | int i, err, num_pols, num_xfrms = 0, drop_pols = 0; | 2079 | int i, err, num_pols, num_xfrms = 0, drop_pols = 0; |
2074 | 2080 | ||
2075 | restart: | ||
2076 | dst = NULL; | 2081 | dst = NULL; |
2077 | xdst = NULL; | 2082 | xdst = NULL; |
2078 | route = NULL; | 2083 | route = NULL; |
@@ -2106,10 +2111,10 @@ restart: | |||
2106 | 2111 | ||
2107 | dst_hold(&xdst->u.dst); | 2112 | dst_hold(&xdst->u.dst); |
2108 | 2113 | ||
2109 | spin_lock_bh(&xfrm_policy_sk_bundle_lock); | 2114 | spin_lock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock); |
2110 | xdst->u.dst.next = xfrm_policy_sk_bundles; | 2115 | xdst->u.dst.next = xfrm_policy_sk_bundles; |
2111 | xfrm_policy_sk_bundles = &xdst->u.dst; | 2116 | xfrm_policy_sk_bundles = &xdst->u.dst; |
2112 | spin_unlock_bh(&xfrm_policy_sk_bundle_lock); | 2117 | spin_unlock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock); |
2113 | 2118 | ||
2114 | route = xdst->route; | 2119 | route = xdst->route; |
2115 | } | 2120 | } |
@@ -2133,7 +2138,7 @@ restart: | |||
2133 | 2138 | ||
2134 | num_pols = xdst->num_pols; | 2139 | num_pols = xdst->num_pols; |
2135 | num_xfrms = xdst->num_xfrms; | 2140 | num_xfrms = xdst->num_xfrms; |
2136 | memcpy(pols, xdst->pols, sizeof(struct xfrm_policy*) * num_pols); | 2141 | memcpy(pols, xdst->pols, sizeof(struct xfrm_policy *) * num_pols); |
2137 | route = xdst->route; | 2142 | route = xdst->route; |
2138 | } | 2143 | } |
2139 | 2144 | ||
@@ -2152,23 +2157,8 @@ restart: | |||
2152 | 2157 | ||
2153 | return make_blackhole(net, family, dst_orig); | 2158 | return make_blackhole(net, family, dst_orig); |
2154 | } | 2159 | } |
2155 | if (fl->flowi_flags & FLOWI_FLAG_CAN_SLEEP) { | ||
2156 | DECLARE_WAITQUEUE(wait, current); | ||
2157 | 2160 | ||
2158 | add_wait_queue(&net->xfrm.km_waitq, &wait); | 2161 | err = -EAGAIN; |
2159 | set_current_state(TASK_INTERRUPTIBLE); | ||
2160 | schedule(); | ||
2161 | set_current_state(TASK_RUNNING); | ||
2162 | remove_wait_queue(&net->xfrm.km_waitq, &wait); | ||
2163 | |||
2164 | if (!signal_pending(current)) { | ||
2165 | dst_release(dst); | ||
2166 | goto restart; | ||
2167 | } | ||
2168 | |||
2169 | err = -ERESTART; | ||
2170 | } else | ||
2171 | err = -EAGAIN; | ||
2172 | 2162 | ||
2173 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES); | 2163 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES); |
2174 | goto error; | 2164 | goto error; |
@@ -2344,7 +2334,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
2344 | if (skb->sp) { | 2334 | if (skb->sp) { |
2345 | int i; | 2335 | int i; |
2346 | 2336 | ||
2347 | for (i=skb->sp->len-1; i>=0; i--) { | 2337 | for (i = skb->sp->len-1; i >= 0; i--) { |
2348 | struct xfrm_state *x = skb->sp->xvec[i]; | 2338 | struct xfrm_state *x = skb->sp->xvec[i]; |
2349 | if (!xfrm_selector_match(&x->sel, &fl, family)) { | 2339 | if (!xfrm_selector_match(&x->sel, &fl, family)) { |
2350 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMISMATCH); | 2340 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMISMATCH); |
@@ -2390,7 +2380,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
2390 | pol->curlft.use_time = get_seconds(); | 2380 | pol->curlft.use_time = get_seconds(); |
2391 | 2381 | ||
2392 | pols[0] = pol; | 2382 | pols[0] = pol; |
2393 | npols ++; | 2383 | npols++; |
2394 | #ifdef CONFIG_XFRM_SUB_POLICY | 2384 | #ifdef CONFIG_XFRM_SUB_POLICY |
2395 | if (pols[0]->type != XFRM_POLICY_TYPE_MAIN) { | 2385 | if (pols[0]->type != XFRM_POLICY_TYPE_MAIN) { |
2396 | pols[1] = xfrm_policy_lookup_bytype(net, XFRM_POLICY_TYPE_MAIN, | 2386 | pols[1] = xfrm_policy_lookup_bytype(net, XFRM_POLICY_TYPE_MAIN, |
@@ -2402,7 +2392,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
2402 | return 0; | 2392 | return 0; |
2403 | } | 2393 | } |
2404 | pols[1]->curlft.use_time = get_seconds(); | 2394 | pols[1]->curlft.use_time = get_seconds(); |
2405 | npols ++; | 2395 | npols++; |
2406 | } | 2396 | } |
2407 | } | 2397 | } |
2408 | #endif | 2398 | #endif |
@@ -2434,7 +2424,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
2434 | } | 2424 | } |
2435 | xfrm_nr = ti; | 2425 | xfrm_nr = ti; |
2436 | if (npols > 1) { | 2426 | if (npols > 1) { |
2437 | xfrm_tmpl_sort(stp, tpp, xfrm_nr, family); | 2427 | xfrm_tmpl_sort(stp, tpp, xfrm_nr, family, net); |
2438 | tpp = stp; | 2428 | tpp = stp; |
2439 | } | 2429 | } |
2440 | 2430 | ||
@@ -2563,10 +2553,10 @@ static void __xfrm_garbage_collect(struct net *net) | |||
2563 | { | 2553 | { |
2564 | struct dst_entry *head, *next; | 2554 | struct dst_entry *head, *next; |
2565 | 2555 | ||
2566 | spin_lock_bh(&xfrm_policy_sk_bundle_lock); | 2556 | spin_lock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock); |
2567 | head = xfrm_policy_sk_bundles; | 2557 | head = xfrm_policy_sk_bundles; |
2568 | xfrm_policy_sk_bundles = NULL; | 2558 | xfrm_policy_sk_bundles = NULL; |
2569 | spin_unlock_bh(&xfrm_policy_sk_bundle_lock); | 2559 | spin_unlock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock); |
2570 | 2560 | ||
2571 | while (head) { | 2561 | while (head) { |
2572 | next = head->next; | 2562 | next = head->next; |
@@ -2906,12 +2896,12 @@ static void xfrm_policy_fini(struct net *net) | |||
2906 | flush_work(&net->xfrm.policy_hash_work); | 2896 | flush_work(&net->xfrm.policy_hash_work); |
2907 | #ifdef CONFIG_XFRM_SUB_POLICY | 2897 | #ifdef CONFIG_XFRM_SUB_POLICY |
2908 | audit_info.loginuid = INVALID_UID; | 2898 | audit_info.loginuid = INVALID_UID; |
2909 | audit_info.sessionid = -1; | 2899 | audit_info.sessionid = (unsigned int)-1; |
2910 | audit_info.secid = 0; | 2900 | audit_info.secid = 0; |
2911 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_SUB, &audit_info); | 2901 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_SUB, &audit_info); |
2912 | #endif | 2902 | #endif |
2913 | audit_info.loginuid = INVALID_UID; | 2903 | audit_info.loginuid = INVALID_UID; |
2914 | audit_info.sessionid = -1; | 2904 | audit_info.sessionid = (unsigned int)-1; |
2915 | audit_info.secid = 0; | 2905 | audit_info.secid = 0; |
2916 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); | 2906 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); |
2917 | 2907 | ||
@@ -2950,6 +2940,13 @@ static int __net_init xfrm_net_init(struct net *net) | |||
2950 | rv = xfrm_sysctl_init(net); | 2940 | rv = xfrm_sysctl_init(net); |
2951 | if (rv < 0) | 2941 | if (rv < 0) |
2952 | goto out_sysctl; | 2942 | goto out_sysctl; |
2943 | |||
2944 | /* Initialize the per-net locks here */ | ||
2945 | spin_lock_init(&net->xfrm.xfrm_state_lock); | ||
2946 | rwlock_init(&net->xfrm.xfrm_policy_lock); | ||
2947 | spin_lock_init(&net->xfrm.xfrm_policy_sk_bundle_lock); | ||
2948 | mutex_init(&net->xfrm.xfrm_cfg_mutex); | ||
2949 | |||
2953 | return 0; | 2950 | return 0; |
2954 | 2951 | ||
2955 | out_sysctl: | 2952 | out_sysctl: |
@@ -2992,7 +2989,7 @@ static void xfrm_audit_common_policyinfo(struct xfrm_policy *xp, | |||
2992 | audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s", | 2989 | audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s", |
2993 | ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str); | 2990 | ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str); |
2994 | 2991 | ||
2995 | switch(sel->family) { | 2992 | switch (sel->family) { |
2996 | case AF_INET: | 2993 | case AF_INET: |
2997 | audit_log_format(audit_buf, " src=%pI4", &sel->saddr.a4); | 2994 | audit_log_format(audit_buf, " src=%pI4", &sel->saddr.a4); |
2998 | if (sel->prefixlen_s != 32) | 2995 | if (sel->prefixlen_s != 32) |
@@ -3017,7 +3014,7 @@ static void xfrm_audit_common_policyinfo(struct xfrm_policy *xp, | |||
3017 | } | 3014 | } |
3018 | 3015 | ||
3019 | void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | 3016 | void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, |
3020 | kuid_t auid, u32 sessionid, u32 secid) | 3017 | kuid_t auid, unsigned int sessionid, u32 secid) |
3021 | { | 3018 | { |
3022 | struct audit_buffer *audit_buf; | 3019 | struct audit_buffer *audit_buf; |
3023 | 3020 | ||
@@ -3032,7 +3029,7 @@ void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | |||
3032 | EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); | 3029 | EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); |
3033 | 3030 | ||
3034 | void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, | 3031 | void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, |
3035 | kuid_t auid, u32 sessionid, u32 secid) | 3032 | kuid_t auid, unsigned int sessionid, u32 secid) |
3036 | { | 3033 | { |
3037 | struct audit_buffer *audit_buf; | 3034 | struct audit_buffer *audit_buf; |
3038 | 3035 | ||
@@ -3069,15 +3066,15 @@ static bool xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp, | |||
3069 | return false; | 3066 | return false; |
3070 | } | 3067 | } |
3071 | 3068 | ||
3072 | static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector *sel, | 3069 | static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *sel, |
3073 | u8 dir, u8 type) | 3070 | u8 dir, u8 type, struct net *net) |
3074 | { | 3071 | { |
3075 | struct xfrm_policy *pol, *ret = NULL; | 3072 | struct xfrm_policy *pol, *ret = NULL; |
3076 | struct hlist_head *chain; | 3073 | struct hlist_head *chain; |
3077 | u32 priority = ~0U; | 3074 | u32 priority = ~0U; |
3078 | 3075 | ||
3079 | read_lock_bh(&xfrm_policy_lock); | 3076 | read_lock_bh(&net->xfrm.xfrm_policy_lock); /*FIXME*/ |
3080 | chain = policy_hash_direct(&init_net, &sel->daddr, &sel->saddr, sel->family, dir); | 3077 | chain = policy_hash_direct(net, &sel->daddr, &sel->saddr, sel->family, dir); |
3081 | hlist_for_each_entry(pol, chain, bydst) { | 3078 | hlist_for_each_entry(pol, chain, bydst) { |
3082 | if (xfrm_migrate_selector_match(sel, &pol->selector) && | 3079 | if (xfrm_migrate_selector_match(sel, &pol->selector) && |
3083 | pol->type == type) { | 3080 | pol->type == type) { |
@@ -3086,7 +3083,7 @@ static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector | |||
3086 | break; | 3083 | break; |
3087 | } | 3084 | } |
3088 | } | 3085 | } |
3089 | chain = &init_net.xfrm.policy_inexact[dir]; | 3086 | chain = &net->xfrm.policy_inexact[dir]; |
3090 | hlist_for_each_entry(pol, chain, bydst) { | 3087 | hlist_for_each_entry(pol, chain, bydst) { |
3091 | if (xfrm_migrate_selector_match(sel, &pol->selector) && | 3088 | if (xfrm_migrate_selector_match(sel, &pol->selector) && |
3092 | pol->type == type && | 3089 | pol->type == type && |
@@ -3099,7 +3096,7 @@ static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector | |||
3099 | if (ret) | 3096 | if (ret) |
3100 | xfrm_pol_hold(ret); | 3097 | xfrm_pol_hold(ret); |
3101 | 3098 | ||
3102 | read_unlock_bh(&xfrm_policy_lock); | 3099 | read_unlock_bh(&net->xfrm.xfrm_policy_lock); |
3103 | 3100 | ||
3104 | return ret; | 3101 | return ret; |
3105 | } | 3102 | } |
@@ -3210,7 +3207,7 @@ static int xfrm_migrate_check(const struct xfrm_migrate *m, int num_migrate) | |||
3210 | 3207 | ||
3211 | int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, | 3208 | int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, |
3212 | struct xfrm_migrate *m, int num_migrate, | 3209 | struct xfrm_migrate *m, int num_migrate, |
3213 | struct xfrm_kmaddress *k) | 3210 | struct xfrm_kmaddress *k, struct net *net) |
3214 | { | 3211 | { |
3215 | int i, err, nx_cur = 0, nx_new = 0; | 3212 | int i, err, nx_cur = 0, nx_new = 0; |
3216 | struct xfrm_policy *pol = NULL; | 3213 | struct xfrm_policy *pol = NULL; |
@@ -3223,14 +3220,14 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, | |||
3223 | goto out; | 3220 | goto out; |
3224 | 3221 | ||
3225 | /* Stage 1 - find policy */ | 3222 | /* Stage 1 - find policy */ |
3226 | if ((pol = xfrm_migrate_policy_find(sel, dir, type)) == NULL) { | 3223 | if ((pol = xfrm_migrate_policy_find(sel, dir, type, net)) == NULL) { |
3227 | err = -ENOENT; | 3224 | err = -ENOENT; |
3228 | goto out; | 3225 | goto out; |
3229 | } | 3226 | } |
3230 | 3227 | ||
3231 | /* Stage 2 - find and update state(s) */ | 3228 | /* Stage 2 - find and update state(s) */ |
3232 | for (i = 0, mp = m; i < num_migrate; i++, mp++) { | 3229 | for (i = 0, mp = m; i < num_migrate; i++, mp++) { |
3233 | if ((x = xfrm_migrate_state_find(mp))) { | 3230 | if ((x = xfrm_migrate_state_find(mp, net))) { |
3234 | x_cur[nx_cur] = x; | 3231 | x_cur[nx_cur] = x; |
3235 | nx_cur++; | 3232 | nx_cur++; |
3236 | if ((xc = xfrm_state_migrate(x, mp))) { | 3233 | if ((xc = xfrm_state_migrate(x, mp))) { |