aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/xfrm6_tunnel.c45
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
141EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); 141EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup);
142 142
143static 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
143static u32 __xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) 158static 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;
166try_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;
178try_next_2:;
179 } 179 }
180 spi = 0; 180 spi = 0;
181 goto out; 181 goto out;
182alloc_spi: 182alloc_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;