diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv6/xfrm6_tunnel.c | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index 639fe8a6ff1e..c2b278138604 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c | |||
@@ -140,12 +140,26 @@ __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) | |||
140 | 140 | ||
141 | EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); | 141 | EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); |
142 | 142 | ||
143 | static int __xfrm6_tunnel_spi_check(u32 spi) | ||
144 | { | ||
145 | struct xfrm6_tunnel_spi *x6spi; | ||
146 | int index = xfrm6_tunnel_spi_hash_byspi(spi); | ||
147 | struct hlist_node *pos; | ||
148 | |||
149 | hlist_for_each_entry(x6spi, pos, | ||
150 | &xfrm6_tunnel_spi_byspi[index], | ||
151 | list_byspi) { | ||
152 | if (x6spi->spi == spi) | ||
153 | return -1; | ||
154 | } | ||
155 | return index; | ||
156 | } | ||
157 | |||
143 | static u32 __xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) | 158 | static u32 __xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) |
144 | { | 159 | { |
145 | u32 spi; | 160 | u32 spi; |
146 | struct xfrm6_tunnel_spi *x6spi; | 161 | struct xfrm6_tunnel_spi *x6spi; |
147 | struct hlist_node *pos; | 162 | int index; |
148 | unsigned index; | ||
149 | 163 | ||
150 | if (xfrm6_tunnel_spi < XFRM6_TUNNEL_SPI_MIN || | 164 | if (xfrm6_tunnel_spi < XFRM6_TUNNEL_SPI_MIN || |
151 | xfrm6_tunnel_spi >= XFRM6_TUNNEL_SPI_MAX) | 165 | xfrm6_tunnel_spi >= XFRM6_TUNNEL_SPI_MAX) |
@@ -154,32 +168,19 @@ static u32 __xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) | |||
154 | xfrm6_tunnel_spi++; | 168 | xfrm6_tunnel_spi++; |
155 | 169 | ||
156 | for (spi = xfrm6_tunnel_spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) { | 170 | for (spi = xfrm6_tunnel_spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) { |
157 | index = xfrm6_tunnel_spi_hash_byspi(spi); | 171 | index = __xfrm6_tunnel_spi_check(spi); |
158 | hlist_for_each_entry(x6spi, pos, | 172 | if (index >= 0) |
159 | &xfrm6_tunnel_spi_byspi[index], | 173 | goto alloc_spi; |
160 | list_byspi) { | ||
161 | if (x6spi->spi == spi) | ||
162 | goto try_next_1; | ||
163 | } | ||
164 | xfrm6_tunnel_spi = spi; | ||
165 | goto alloc_spi; | ||
166 | try_next_1:; | ||
167 | } | 174 | } |
168 | for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tunnel_spi; spi++) { | 175 | for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tunnel_spi; spi++) { |
169 | index = xfrm6_tunnel_spi_hash_byspi(spi); | 176 | index = __xfrm6_tunnel_spi_check(spi); |
170 | hlist_for_each_entry(x6spi, pos, | 177 | if (index >= 0) |
171 | &xfrm6_tunnel_spi_byspi[index], | 178 | goto alloc_spi; |
172 | list_byspi) { | ||
173 | if (x6spi->spi == spi) | ||
174 | goto try_next_2; | ||
175 | } | ||
176 | xfrm6_tunnel_spi = spi; | ||
177 | goto alloc_spi; | ||
178 | try_next_2:; | ||
179 | } | 179 | } |
180 | spi = 0; | 180 | spi = 0; |
181 | goto out; | 181 | goto out; |
182 | alloc_spi: | 182 | alloc_spi: |
183 | xfrm6_tunnel_spi = spi; | ||
183 | x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, GFP_ATOMIC); | 184 | x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, GFP_ATOMIC); |
184 | if (!x6spi) | 185 | if (!x6spi) |
185 | goto out; | 186 | goto out; |