diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-11-25 20:17:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-25 20:17:24 -0500 |
commit | d320bbb306f2085892bc958781e8fcaf5d491589 (patch) | |
tree | b86290122569b7201be6df4632eeca4fd4483ef9 | |
parent | 73d189dce486cd6693fa29169b1aac0872efbcea (diff) |
netns xfrm: per-netns xfrm_state_bysrc hash
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/netns/xfrm.h | 1 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 23 |
2 files changed, 15 insertions, 9 deletions
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h index 02487b39ce53..bfcd5a3e25b6 100644 --- a/include/net/netns/xfrm.h +++ b/include/net/netns/xfrm.h | |||
@@ -14,6 +14,7 @@ struct netns_xfrm { | |||
14 | * offending SA. | 14 | * offending SA. |
15 | */ | 15 | */ |
16 | struct hlist_head *state_bydst; | 16 | struct hlist_head *state_bydst; |
17 | struct hlist_head *state_bysrc; | ||
17 | }; | 18 | }; |
18 | 19 | ||
19 | #endif | 20 | #endif |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 08b78895ffbc..52d828bdf3d7 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -44,7 +44,6 @@ u32 sysctl_xfrm_acq_expires __read_mostly = 30; | |||
44 | 44 | ||
45 | static DEFINE_SPINLOCK(xfrm_state_lock); | 45 | static DEFINE_SPINLOCK(xfrm_state_lock); |
46 | 46 | ||
47 | static struct hlist_head *xfrm_state_bysrc __read_mostly; | ||
48 | static struct hlist_head *xfrm_state_byspi __read_mostly; | 47 | static struct hlist_head *xfrm_state_byspi __read_mostly; |
49 | static unsigned int xfrm_state_hmask __read_mostly; | 48 | static unsigned int xfrm_state_hmask __read_mostly; |
50 | static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024; | 49 | static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024; |
@@ -154,12 +153,12 @@ static void xfrm_hash_resize(struct work_struct *__unused) | |||
154 | nhashmask); | 153 | nhashmask); |
155 | 154 | ||
156 | odst = init_net.xfrm.state_bydst; | 155 | odst = init_net.xfrm.state_bydst; |
157 | osrc = xfrm_state_bysrc; | 156 | osrc = init_net.xfrm.state_bysrc; |
158 | ospi = xfrm_state_byspi; | 157 | ospi = xfrm_state_byspi; |
159 | ohashmask = xfrm_state_hmask; | 158 | ohashmask = xfrm_state_hmask; |
160 | 159 | ||
161 | init_net.xfrm.state_bydst = ndst; | 160 | init_net.xfrm.state_bydst = ndst; |
162 | xfrm_state_bysrc = nsrc; | 161 | init_net.xfrm.state_bysrc = nsrc; |
163 | xfrm_state_byspi = nspi; | 162 | xfrm_state_byspi = nspi; |
164 | xfrm_state_hmask = nhashmask; | 163 | xfrm_state_hmask = nhashmask; |
165 | 164 | ||
@@ -712,7 +711,7 @@ static struct xfrm_state *__xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm | |||
712 | struct xfrm_state *x; | 711 | struct xfrm_state *x; |
713 | struct hlist_node *entry; | 712 | struct hlist_node *entry; |
714 | 713 | ||
715 | hlist_for_each_entry(x, entry, xfrm_state_bysrc+h, bysrc) { | 714 | hlist_for_each_entry(x, entry, init_net.xfrm.state_bysrc+h, bysrc) { |
716 | if (x->props.family != family || | 715 | if (x->props.family != family || |
717 | x->id.proto != proto) | 716 | x->id.proto != proto) |
718 | continue; | 717 | continue; |
@@ -850,7 +849,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
850 | list_add(&x->km.all, &init_net.xfrm.state_all); | 849 | list_add(&x->km.all, &init_net.xfrm.state_all); |
851 | hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h); | 850 | hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h); |
852 | h = xfrm_src_hash(daddr, saddr, family); | 851 | h = xfrm_src_hash(daddr, saddr, family); |
853 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); | 852 | hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h); |
854 | if (x->id.spi) { | 853 | if (x->id.spi) { |
855 | h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family); | 854 | h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family); |
856 | hlist_add_head(&x->byspi, xfrm_state_byspi+h); | 855 | hlist_add_head(&x->byspi, xfrm_state_byspi+h); |
@@ -923,7 +922,7 @@ static void __xfrm_state_insert(struct xfrm_state *x) | |||
923 | hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h); | 922 | hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h); |
924 | 923 | ||
925 | h = xfrm_src_hash(&x->id.daddr, &x->props.saddr, x->props.family); | 924 | h = xfrm_src_hash(&x->id.daddr, &x->props.saddr, x->props.family); |
926 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); | 925 | hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h); |
927 | 926 | ||
928 | if (x->id.spi) { | 927 | if (x->id.spi) { |
929 | h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, | 928 | h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, |
@@ -1048,7 +1047,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re | |||
1048 | list_add(&x->km.all, &init_net.xfrm.state_all); | 1047 | list_add(&x->km.all, &init_net.xfrm.state_all); |
1049 | hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h); | 1048 | hlist_add_head(&x->bydst, init_net.xfrm.state_bydst+h); |
1050 | h = xfrm_src_hash(daddr, saddr, family); | 1049 | h = xfrm_src_hash(daddr, saddr, family); |
1051 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); | 1050 | hlist_add_head(&x->bysrc, init_net.xfrm.state_bysrc+h); |
1052 | 1051 | ||
1053 | xfrm_state_num++; | 1052 | xfrm_state_num++; |
1054 | 1053 | ||
@@ -1218,7 +1217,7 @@ struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m) | |||
1218 | } else { | 1217 | } else { |
1219 | h = xfrm_src_hash(&m->old_daddr, &m->old_saddr, | 1218 | h = xfrm_src_hash(&m->old_daddr, &m->old_saddr, |
1220 | m->old_family); | 1219 | m->old_family); |
1221 | hlist_for_each_entry(x, entry, xfrm_state_bysrc+h, bysrc) { | 1220 | hlist_for_each_entry(x, entry, init_net.xfrm.state_bysrc+h, bysrc) { |
1222 | if (x->props.mode != m->mode || | 1221 | if (x->props.mode != m->mode || |
1223 | x->id.proto != m->proto) | 1222 | x->id.proto != m->proto) |
1224 | continue; | 1223 | continue; |
@@ -2084,13 +2083,17 @@ int __net_init xfrm_state_init(struct net *net) | |||
2084 | net->xfrm.state_bydst = xfrm_hash_alloc(sz); | 2083 | net->xfrm.state_bydst = xfrm_hash_alloc(sz); |
2085 | if (!net->xfrm.state_bydst) | 2084 | if (!net->xfrm.state_bydst) |
2086 | goto out_bydst; | 2085 | goto out_bydst; |
2087 | xfrm_state_bysrc = xfrm_hash_alloc(sz); | 2086 | net->xfrm.state_bysrc = xfrm_hash_alloc(sz); |
2087 | if (!net->xfrm.state_bysrc) | ||
2088 | goto out_bysrc; | ||
2088 | xfrm_state_byspi = xfrm_hash_alloc(sz); | 2089 | xfrm_state_byspi = xfrm_hash_alloc(sz); |
2089 | xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1); | 2090 | xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1); |
2090 | 2091 | ||
2091 | INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task); | 2092 | INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task); |
2092 | return 0; | 2093 | return 0; |
2093 | 2094 | ||
2095 | out_bysrc: | ||
2096 | xfrm_hash_free(net->xfrm.state_bydst, sz); | ||
2094 | out_bydst: | 2097 | out_bydst: |
2095 | return -ENOMEM; | 2098 | return -ENOMEM; |
2096 | } | 2099 | } |
@@ -2102,6 +2105,8 @@ void xfrm_state_fini(struct net *net) | |||
2102 | WARN_ON(!list_empty(&net->xfrm.state_all)); | 2105 | WARN_ON(!list_empty(&net->xfrm.state_all)); |
2103 | 2106 | ||
2104 | sz = (xfrm_state_hmask + 1) * sizeof(struct hlist_head); | 2107 | sz = (xfrm_state_hmask + 1) * sizeof(struct hlist_head); |
2108 | WARN_ON(!hlist_empty(net->xfrm.state_bysrc)); | ||
2109 | xfrm_hash_free(net->xfrm.state_bysrc, sz); | ||
2105 | WARN_ON(!hlist_empty(net->xfrm.state_bydst)); | 2110 | WARN_ON(!hlist_empty(net->xfrm.state_bydst)); |
2106 | xfrm_hash_free(net->xfrm.state_bydst, sz); | 2111 | xfrm_hash_free(net->xfrm.state_bydst, sz); |
2107 | } | 2112 | } |