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 | } |
