Lines Matching +full:- +full:spi
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Authors Mitsuru KANDA <mk@linux-ipv6.org>
6 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
31 u32 spi; member
41 * xfrm_tunnel_spi things are for allocating unique id ("spi")
48 u32 spi; member
64 h &= XFRM6_TUNNEL_SPI_BYADDR_HSIZE - 1; in xfrm6_tunnel_spi_hash_byaddr()
69 static inline unsigned int xfrm6_tunnel_spi_hash_byspi(u32 spi) in xfrm6_tunnel_spi_hash_byspi() argument
71 return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE; in xfrm6_tunnel_spi_hash_byspi()
80 &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)], in __xfrm6_tunnel_spi_lookup()
82 if (xfrm6_addr_equal(&x6spi->addr, saddr)) in __xfrm6_tunnel_spi_lookup()
92 u32 spi; in xfrm6_tunnel_spi_lookup() local
96 spi = x6spi ? x6spi->spi : 0; in xfrm6_tunnel_spi_lookup()
98 return htonl(spi); in xfrm6_tunnel_spi_lookup()
102 static int __xfrm6_tunnel_spi_check(struct net *net, u32 spi) in __xfrm6_tunnel_spi_check() argument
106 int index = xfrm6_tunnel_spi_hash_byspi(spi); in __xfrm6_tunnel_spi_check()
109 &xfrm6_tn->spi_byspi[index], in __xfrm6_tunnel_spi_check()
111 if (x6spi->spi == spi) in __xfrm6_tunnel_spi_check()
112 return -1; in __xfrm6_tunnel_spi_check()
120 u32 spi; in __xfrm6_tunnel_alloc_spi() local
124 if (xfrm6_tn->spi < XFRM6_TUNNEL_SPI_MIN || in __xfrm6_tunnel_alloc_spi()
125 xfrm6_tn->spi >= XFRM6_TUNNEL_SPI_MAX) in __xfrm6_tunnel_alloc_spi()
126 xfrm6_tn->spi = XFRM6_TUNNEL_SPI_MIN; in __xfrm6_tunnel_alloc_spi()
128 xfrm6_tn->spi++; in __xfrm6_tunnel_alloc_spi()
130 for (spi = xfrm6_tn->spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) { in __xfrm6_tunnel_alloc_spi()
131 index = __xfrm6_tunnel_spi_check(net, spi); in __xfrm6_tunnel_alloc_spi()
135 if (spi == XFRM6_TUNNEL_SPI_MAX) in __xfrm6_tunnel_alloc_spi()
138 for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tn->spi; spi++) { in __xfrm6_tunnel_alloc_spi()
139 index = __xfrm6_tunnel_spi_check(net, spi); in __xfrm6_tunnel_alloc_spi()
143 spi = 0; in __xfrm6_tunnel_alloc_spi()
146 xfrm6_tn->spi = spi; in __xfrm6_tunnel_alloc_spi()
151 memcpy(&x6spi->addr, saddr, sizeof(x6spi->addr)); in __xfrm6_tunnel_alloc_spi()
152 x6spi->spi = spi; in __xfrm6_tunnel_alloc_spi()
153 refcount_set(&x6spi->refcnt, 1); in __xfrm6_tunnel_alloc_spi()
155 hlist_add_head_rcu(&x6spi->list_byspi, &xfrm6_tn->spi_byspi[index]); in __xfrm6_tunnel_alloc_spi()
158 hlist_add_head_rcu(&x6spi->list_byaddr, &xfrm6_tn->spi_byaddr[index]); in __xfrm6_tunnel_alloc_spi()
160 return spi; in __xfrm6_tunnel_alloc_spi()
166 u32 spi; in xfrm6_tunnel_alloc_spi() local
171 refcount_inc(&x6spi->refcnt); in xfrm6_tunnel_alloc_spi()
172 spi = x6spi->spi; in xfrm6_tunnel_alloc_spi()
174 spi = __xfrm6_tunnel_alloc_spi(net, saddr); in xfrm6_tunnel_alloc_spi()
177 return htonl(spi); in xfrm6_tunnel_alloc_spi()
196 &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)], in xfrm6_tunnel_free_spi()
199 if (xfrm6_addr_equal(&x6spi->addr, saddr)) { in xfrm6_tunnel_free_spi()
200 if (refcount_dec_and_test(&x6spi->refcnt)) { in xfrm6_tunnel_free_spi()
201 hlist_del_rcu(&x6spi->list_byaddr); in xfrm6_tunnel_free_spi()
202 hlist_del_rcu(&x6spi->list_byspi); in xfrm6_tunnel_free_spi()
203 call_rcu(&x6spi->rcu_head, x6spi_destroy_rcu); in xfrm6_tunnel_free_spi()
213 skb_push(skb, -skb_network_offset(skb)); in xfrm6_tunnel_output()
219 return skb_network_header(skb)[IP6CB(skb)->nhoff]; in xfrm6_tunnel_input()
224 struct net *net = dev_net(skb->dev); in xfrm6_tunnel_rcv()
226 __be32 spi; in xfrm6_tunnel_rcv() local
228 spi = xfrm6_tunnel_spi_lookup(net, (const xfrm_address_t *)&iph->saddr); in xfrm6_tunnel_rcv()
229 return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi, NULL); in xfrm6_tunnel_rcv()
275 if (x->props.mode != XFRM_MODE_TUNNEL) { in xfrm6_tunnel_init_state()
277 return -EINVAL; in xfrm6_tunnel_init_state()
280 if (x->encap) { in xfrm6_tunnel_init_state()
282 return -EINVAL; in xfrm6_tunnel_init_state()
285 x->props.header_len = sizeof(struct ipv6hdr); in xfrm6_tunnel_init_state()
294 xfrm6_tunnel_free_spi(net, (xfrm_address_t *)&x->props.saddr); in xfrm6_tunnel_destroy()
324 INIT_HLIST_HEAD(&xfrm6_tn->spi_byaddr[i]); in xfrm6_tunnel_net_init()
326 INIT_HLIST_HEAD(&xfrm6_tn->spi_byspi[i]); in xfrm6_tunnel_net_init()
327 xfrm6_tn->spi = 0; in xfrm6_tunnel_net_init()
341 WARN_ON_ONCE(!hlist_empty(&xfrm6_tn->spi_byaddr[i])); in xfrm6_tunnel_net_exit()
344 WARN_ON_ONCE(!hlist_empty(&xfrm6_tn->spi_byspi[i])); in xfrm6_tunnel_net_exit()
360 return -ENOMEM; in xfrm6_tunnel_init()