diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-11-25 20:29:47 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-25 20:29:47 -0500 |
commit | 98806f75ba2afc716e4d2f915d3ac7687546f9c0 (patch) | |
tree | b874e64635822f95adbc630379a50c1932c1dae2 /net/xfrm | |
parent | 64d0cd009718ce64cf0f388142ead7ea41f1f3c8 (diff) |
netns xfrm: trivial netns propagations
Take netns from xfrm_state or xfrm_policy.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 15 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 59 |
2 files changed, 43 insertions, 31 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 1d300862dc04..3d931f52f897 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1069,29 +1069,32 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc | |||
1069 | 1069 | ||
1070 | static void __xfrm_policy_link(struct xfrm_policy *pol, int dir) | 1070 | static void __xfrm_policy_link(struct xfrm_policy *pol, int dir) |
1071 | { | 1071 | { |
1072 | struct net *net = xp_net(pol); | ||
1072 | struct hlist_head *chain = policy_hash_bysel(&pol->selector, | 1073 | struct hlist_head *chain = policy_hash_bysel(&pol->selector, |
1073 | pol->family, dir); | 1074 | pol->family, dir); |
1074 | 1075 | ||
1075 | list_add(&pol->walk.all, &init_net.xfrm.policy_all); | 1076 | list_add(&pol->walk.all, &net->xfrm.policy_all); |
1076 | hlist_add_head(&pol->bydst, chain); | 1077 | hlist_add_head(&pol->bydst, chain); |
1077 | hlist_add_head(&pol->byidx, init_net.xfrm.policy_byidx+idx_hash(pol->index)); | 1078 | hlist_add_head(&pol->byidx, net->xfrm.policy_byidx+idx_hash(pol->index)); |
1078 | init_net.xfrm.policy_count[dir]++; | 1079 | net->xfrm.policy_count[dir]++; |
1079 | xfrm_pol_hold(pol); | 1080 | xfrm_pol_hold(pol); |
1080 | 1081 | ||
1081 | if (xfrm_bydst_should_resize(&init_net, dir, NULL)) | 1082 | if (xfrm_bydst_should_resize(net, dir, NULL)) |
1082 | schedule_work(&init_net.xfrm.policy_hash_work); | 1083 | schedule_work(&net->xfrm.policy_hash_work); |
1083 | } | 1084 | } |
1084 | 1085 | ||
1085 | static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, | 1086 | static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, |
1086 | int dir) | 1087 | int dir) |
1087 | { | 1088 | { |
1089 | struct net *net = xp_net(pol); | ||
1090 | |||
1088 | if (hlist_unhashed(&pol->bydst)) | 1091 | if (hlist_unhashed(&pol->bydst)) |
1089 | return NULL; | 1092 | return NULL; |
1090 | 1093 | ||
1091 | hlist_del(&pol->bydst); | 1094 | hlist_del(&pol->bydst); |
1092 | hlist_del(&pol->byidx); | 1095 | hlist_del(&pol->byidx); |
1093 | list_del(&pol->walk.all); | 1096 | list_del(&pol->walk.all); |
1094 | init_net.xfrm.policy_count[dir]--; | 1097 | net->xfrm.policy_count[dir]--; |
1095 | 1098 | ||
1096 | return pol; | 1099 | return pol; |
1097 | } | 1100 | } |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 72b2956627d6..f3f635d4ee66 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -412,6 +412,7 @@ static inline unsigned long make_jiffies(long secs) | |||
412 | static void xfrm_timer_handler(unsigned long data) | 412 | static void xfrm_timer_handler(unsigned long data) |
413 | { | 413 | { |
414 | struct xfrm_state *x = (struct xfrm_state*)data; | 414 | struct xfrm_state *x = (struct xfrm_state*)data; |
415 | struct net *net = xs_net(x); | ||
415 | unsigned long now = get_seconds(); | 416 | unsigned long now = get_seconds(); |
416 | long next = LONG_MAX; | 417 | long next = LONG_MAX; |
417 | int warn = 0; | 418 | int warn = 0; |
@@ -469,7 +470,7 @@ resched: | |||
469 | expired: | 470 | expired: |
470 | if (x->km.state == XFRM_STATE_ACQ && x->id.spi == 0) { | 471 | if (x->km.state == XFRM_STATE_ACQ && x->id.spi == 0) { |
471 | x->km.state = XFRM_STATE_EXPIRED; | 472 | x->km.state = XFRM_STATE_EXPIRED; |
472 | wake_up(&init_net.xfrm.km_waitq); | 473 | wake_up(&net->xfrm.km_waitq); |
473 | next = 2; | 474 | next = 2; |
474 | goto resched; | 475 | goto resched; |
475 | } | 476 | } |
@@ -522,17 +523,20 @@ EXPORT_SYMBOL(xfrm_state_alloc); | |||
522 | 523 | ||
523 | void __xfrm_state_destroy(struct xfrm_state *x) | 524 | void __xfrm_state_destroy(struct xfrm_state *x) |
524 | { | 525 | { |
526 | struct net *net = xs_net(x); | ||
527 | |||
525 | WARN_ON(x->km.state != XFRM_STATE_DEAD); | 528 | WARN_ON(x->km.state != XFRM_STATE_DEAD); |
526 | 529 | ||
527 | spin_lock_bh(&xfrm_state_gc_lock); | 530 | spin_lock_bh(&xfrm_state_gc_lock); |
528 | hlist_add_head(&x->gclist, &init_net.xfrm.state_gc_list); | 531 | hlist_add_head(&x->gclist, &net->xfrm.state_gc_list); |
529 | spin_unlock_bh(&xfrm_state_gc_lock); | 532 | spin_unlock_bh(&xfrm_state_gc_lock); |
530 | schedule_work(&init_net.xfrm.state_gc_work); | 533 | schedule_work(&net->xfrm.state_gc_work); |
531 | } | 534 | } |
532 | EXPORT_SYMBOL(__xfrm_state_destroy); | 535 | EXPORT_SYMBOL(__xfrm_state_destroy); |
533 | 536 | ||
534 | int __xfrm_state_delete(struct xfrm_state *x) | 537 | int __xfrm_state_delete(struct xfrm_state *x) |
535 | { | 538 | { |
539 | struct net *net = xs_net(x); | ||
536 | int err = -ESRCH; | 540 | int err = -ESRCH; |
537 | 541 | ||
538 | if (x->km.state != XFRM_STATE_DEAD) { | 542 | if (x->km.state != XFRM_STATE_DEAD) { |
@@ -543,7 +547,7 @@ int __xfrm_state_delete(struct xfrm_state *x) | |||
543 | hlist_del(&x->bysrc); | 547 | hlist_del(&x->bysrc); |
544 | if (x->id.spi) | 548 | if (x->id.spi) |
545 | hlist_del(&x->byspi); | 549 | hlist_del(&x->byspi); |
546 | init_net.xfrm.state_num--; | 550 | net->xfrm.state_num--; |
547 | spin_unlock(&xfrm_state_lock); | 551 | spin_unlock(&xfrm_state_lock); |
548 | 552 | ||
549 | /* All xfrm_state objects are created by xfrm_state_alloc. | 553 | /* All xfrm_state objects are created by xfrm_state_alloc. |
@@ -745,12 +749,12 @@ __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) | |||
745 | x->id.proto, family); | 749 | x->id.proto, family); |
746 | } | 750 | } |
747 | 751 | ||
748 | static void xfrm_hash_grow_check(int have_hash_collision) | 752 | static void xfrm_hash_grow_check(struct net *net, int have_hash_collision) |
749 | { | 753 | { |
750 | if (have_hash_collision && | 754 | if (have_hash_collision && |
751 | (init_net.xfrm.state_hmask + 1) < xfrm_state_hashmax && | 755 | (net->xfrm.state_hmask + 1) < xfrm_state_hashmax && |
752 | init_net.xfrm.state_num > init_net.xfrm.state_hmask) | 756 | net->xfrm.state_num > net->xfrm.state_hmask) |
753 | schedule_work(&init_net.xfrm.state_hash_work); | 757 | schedule_work(&net->xfrm.state_hash_work); |
754 | } | 758 | } |
755 | 759 | ||
756 | struct xfrm_state * | 760 | struct xfrm_state * |
@@ -851,7 +855,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
851 | x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; | 855 | x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; |
852 | add_timer(&x->timer); | 856 | add_timer(&x->timer); |
853 | init_net.xfrm.state_num++; | 857 | init_net.xfrm.state_num++; |
854 | xfrm_hash_grow_check(x->bydst.next != NULL); | 858 | xfrm_hash_grow_check(&init_net, x->bydst.next != NULL); |
855 | } else { | 859 | } else { |
856 | x->km.state = XFRM_STATE_DEAD; | 860 | x->km.state = XFRM_STATE_DEAD; |
857 | to_put = x; | 861 | to_put = x; |
@@ -904,48 +908,50 @@ EXPORT_SYMBOL(xfrm_stateonly_find); | |||
904 | 908 | ||
905 | static void __xfrm_state_insert(struct xfrm_state *x) | 909 | static void __xfrm_state_insert(struct xfrm_state *x) |
906 | { | 910 | { |
911 | struct net *net = xs_net(x); | ||
907 | unsigned int h; | 912 | unsigned int h; |
908 | 913 | ||
909 | x->genid = ++xfrm_state_genid; | 914 | x->genid = ++xfrm_state_genid; |
910 | 915 | ||
911 | list_add(&x->km.all, &init_net.xfrm.state_all); | 916 | list_add(&x->km.all, &net->xfrm.state_all); |
912 | 917 | ||
913 | h = xfrm_dst_hash(&init_net, &x->id.daddr, &x->props.saddr, | 918 | h = xfrm_dst_hash(net, &x->id.daddr, &x->props.saddr, |
914 | x->props.reqid, x->props.family); | 919 | x->props.reqid, x->props.family); |
915 | hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h); | 920 | hlist_add_head(&x->bydst, net->xfrm.state_bydst+h); |
916 | 921 | ||
917 | h = xfrm_src_hash(&init_net, &x->id.daddr, &x->props.saddr, x->props.family); | 922 | h = xfrm_src_hash(net, &x->id.daddr, &x->props.saddr, x->props.family); |
918 | hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h); | 923 | hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h); |
919 | 924 | ||
920 | if (x->id.spi) { | 925 | if (x->id.spi) { |
921 | h = xfrm_spi_hash(&init_net, &x->id.daddr, x->id.spi, x->id.proto, | 926 | h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, |
922 | x->props.family); | 927 | x->props.family); |
923 | 928 | ||
924 | hlist_add_head(&x->byspi, init_net.xfrm.state_byspi+h); | 929 | hlist_add_head(&x->byspi, net->xfrm.state_byspi+h); |
925 | } | 930 | } |
926 | 931 | ||
927 | mod_timer(&x->timer, jiffies + HZ); | 932 | mod_timer(&x->timer, jiffies + HZ); |
928 | if (x->replay_maxage) | 933 | if (x->replay_maxage) |
929 | mod_timer(&x->rtimer, jiffies + x->replay_maxage); | 934 | mod_timer(&x->rtimer, jiffies + x->replay_maxage); |
930 | 935 | ||
931 | wake_up(&init_net.xfrm.km_waitq); | 936 | wake_up(&net->xfrm.km_waitq); |
932 | 937 | ||
933 | init_net.xfrm.state_num++; | 938 | net->xfrm.state_num++; |
934 | 939 | ||
935 | xfrm_hash_grow_check(x->bydst.next != NULL); | 940 | xfrm_hash_grow_check(net, x->bydst.next != NULL); |
936 | } | 941 | } |
937 | 942 | ||
938 | /* xfrm_state_lock is held */ | 943 | /* xfrm_state_lock is held */ |
939 | static void __xfrm_state_bump_genids(struct xfrm_state *xnew) | 944 | static void __xfrm_state_bump_genids(struct xfrm_state *xnew) |
940 | { | 945 | { |
946 | struct net *net = xs_net(xnew); | ||
941 | unsigned short family = xnew->props.family; | 947 | unsigned short family = xnew->props.family; |
942 | u32 reqid = xnew->props.reqid; | 948 | u32 reqid = xnew->props.reqid; |
943 | struct xfrm_state *x; | 949 | struct xfrm_state *x; |
944 | struct hlist_node *entry; | 950 | struct hlist_node *entry; |
945 | unsigned int h; | 951 | unsigned int h; |
946 | 952 | ||
947 | h = xfrm_dst_hash(&init_net, &xnew->id.daddr, &xnew->props.saddr, reqid, family); | 953 | h = xfrm_dst_hash(net, &xnew->id.daddr, &xnew->props.saddr, reqid, family); |
948 | hlist_for_each_entry(x, entry, init_net.xfrm.state_bydst+h, bydst) { | 954 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { |
949 | if (x->props.family == family && | 955 | if (x->props.family == family && |
950 | x->props.reqid == reqid && | 956 | x->props.reqid == reqid && |
951 | !xfrm_addr_cmp(&x->id.daddr, &xnew->id.daddr, family) && | 957 | !xfrm_addr_cmp(&x->id.daddr, &xnew->id.daddr, family) && |
@@ -1044,7 +1050,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re | |||
1044 | 1050 | ||
1045 | init_net.xfrm.state_num++; | 1051 | init_net.xfrm.state_num++; |
1046 | 1052 | ||
1047 | xfrm_hash_grow_check(x->bydst.next != NULL); | 1053 | xfrm_hash_grow_check(&init_net, x->bydst.next != NULL); |
1048 | } | 1054 | } |
1049 | 1055 | ||
1050 | return x; | 1056 | return x; |
@@ -1109,8 +1115,9 @@ EXPORT_SYMBOL(xfrm_state_add); | |||
1109 | #ifdef CONFIG_XFRM_MIGRATE | 1115 | #ifdef CONFIG_XFRM_MIGRATE |
1110 | static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp) | 1116 | static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp) |
1111 | { | 1117 | { |
1118 | struct net *net = xs_net(orig); | ||
1112 | int err = -ENOMEM; | 1119 | int err = -ENOMEM; |
1113 | struct xfrm_state *x = xfrm_state_alloc(&init_net); | 1120 | struct xfrm_state *x = xfrm_state_alloc(net); |
1114 | if (!x) | 1121 | if (!x) |
1115 | goto error; | 1122 | goto error; |
1116 | 1123 | ||
@@ -1734,6 +1741,7 @@ EXPORT_SYMBOL(km_state_notify); | |||
1734 | 1741 | ||
1735 | void km_state_expired(struct xfrm_state *x, int hard, u32 pid) | 1742 | void km_state_expired(struct xfrm_state *x, int hard, u32 pid) |
1736 | { | 1743 | { |
1744 | struct net *net = xs_net(x); | ||
1737 | struct km_event c; | 1745 | struct km_event c; |
1738 | 1746 | ||
1739 | c.data.hard = hard; | 1747 | c.data.hard = hard; |
@@ -1742,7 +1750,7 @@ void km_state_expired(struct xfrm_state *x, int hard, u32 pid) | |||
1742 | km_state_notify(x, &c); | 1750 | km_state_notify(x, &c); |
1743 | 1751 | ||
1744 | if (hard) | 1752 | if (hard) |
1745 | wake_up(&init_net.xfrm.km_waitq); | 1753 | wake_up(&net->xfrm.km_waitq); |
1746 | } | 1754 | } |
1747 | 1755 | ||
1748 | EXPORT_SYMBOL(km_state_expired); | 1756 | EXPORT_SYMBOL(km_state_expired); |
@@ -1785,6 +1793,7 @@ EXPORT_SYMBOL(km_new_mapping); | |||
1785 | 1793 | ||
1786 | void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid) | 1794 | void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid) |
1787 | { | 1795 | { |
1796 | struct net *net = xp_net(pol); | ||
1788 | struct km_event c; | 1797 | struct km_event c; |
1789 | 1798 | ||
1790 | c.data.hard = hard; | 1799 | c.data.hard = hard; |
@@ -1793,7 +1802,7 @@ void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid) | |||
1793 | km_policy_notify(pol, dir, &c); | 1802 | km_policy_notify(pol, dir, &c); |
1794 | 1803 | ||
1795 | if (hard) | 1804 | if (hard) |
1796 | wake_up(&init_net.xfrm.km_waitq); | 1805 | wake_up(&net->xfrm.km_waitq); |
1797 | } | 1806 | } |
1798 | EXPORT_SYMBOL(km_policy_expired); | 1807 | EXPORT_SYMBOL(km_policy_expired); |
1799 | 1808 | ||