0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/xfrm.h>
0012 #include <linux/slab.h>
0013 #include <linux/rculist.h>
0014 #include <net/ip.h>
0015 #include <net/xfrm.h>
0016 #include <net/ipv6.h>
0017 #include <linux/ipv6.h>
0018 #include <linux/icmpv6.h>
0019 #include <linux/mutex.h>
0020 #include <net/netns/generic.h>
0021
0022 #define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256
0023 #define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256
0024
0025 #define XFRM6_TUNNEL_SPI_MIN 1
0026 #define XFRM6_TUNNEL_SPI_MAX 0xffffffff
0027
0028 struct xfrm6_tunnel_net {
0029 struct hlist_head spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
0030 struct hlist_head spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
0031 u32 spi;
0032 };
0033
0034 static unsigned int xfrm6_tunnel_net_id __read_mostly;
0035 static inline struct xfrm6_tunnel_net *xfrm6_tunnel_pernet(struct net *net)
0036 {
0037 return net_generic(net, xfrm6_tunnel_net_id);
0038 }
0039
0040
0041
0042
0043
0044 struct xfrm6_tunnel_spi {
0045 struct hlist_node list_byaddr;
0046 struct hlist_node list_byspi;
0047 xfrm_address_t addr;
0048 u32 spi;
0049 refcount_t refcnt;
0050 struct rcu_head rcu_head;
0051 };
0052
0053 static DEFINE_SPINLOCK(xfrm6_tunnel_spi_lock);
0054
0055 static struct kmem_cache *xfrm6_tunnel_spi_kmem __read_mostly;
0056
0057 static inline unsigned int xfrm6_tunnel_spi_hash_byaddr(const xfrm_address_t *addr)
0058 {
0059 unsigned int h;
0060
0061 h = ipv6_addr_hash((const struct in6_addr *)addr);
0062 h ^= h >> 16;
0063 h ^= h >> 8;
0064 h &= XFRM6_TUNNEL_SPI_BYADDR_HSIZE - 1;
0065
0066 return h;
0067 }
0068
0069 static inline unsigned int xfrm6_tunnel_spi_hash_byspi(u32 spi)
0070 {
0071 return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE;
0072 }
0073
0074 static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr)
0075 {
0076 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
0077 struct xfrm6_tunnel_spi *x6spi;
0078
0079 hlist_for_each_entry_rcu(x6spi,
0080 &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
0081 list_byaddr, lockdep_is_held(&xfrm6_tunnel_spi_lock)) {
0082 if (xfrm6_addr_equal(&x6spi->addr, saddr))
0083 return x6spi;
0084 }
0085
0086 return NULL;
0087 }
0088
0089 __be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr)
0090 {
0091 struct xfrm6_tunnel_spi *x6spi;
0092 u32 spi;
0093
0094 rcu_read_lock_bh();
0095 x6spi = __xfrm6_tunnel_spi_lookup(net, saddr);
0096 spi = x6spi ? x6spi->spi : 0;
0097 rcu_read_unlock_bh();
0098 return htonl(spi);
0099 }
0100 EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup);
0101
0102 static int __xfrm6_tunnel_spi_check(struct net *net, u32 spi)
0103 {
0104 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
0105 struct xfrm6_tunnel_spi *x6spi;
0106 int index = xfrm6_tunnel_spi_hash_byspi(spi);
0107
0108 hlist_for_each_entry(x6spi,
0109 &xfrm6_tn->spi_byspi[index],
0110 list_byspi) {
0111 if (x6spi->spi == spi)
0112 return -1;
0113 }
0114 return index;
0115 }
0116
0117 static u32 __xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr)
0118 {
0119 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
0120 u32 spi;
0121 struct xfrm6_tunnel_spi *x6spi;
0122 int index;
0123
0124 if (xfrm6_tn->spi < XFRM6_TUNNEL_SPI_MIN ||
0125 xfrm6_tn->spi >= XFRM6_TUNNEL_SPI_MAX)
0126 xfrm6_tn->spi = XFRM6_TUNNEL_SPI_MIN;
0127 else
0128 xfrm6_tn->spi++;
0129
0130 for (spi = xfrm6_tn->spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) {
0131 index = __xfrm6_tunnel_spi_check(net, spi);
0132 if (index >= 0)
0133 goto alloc_spi;
0134
0135 if (spi == XFRM6_TUNNEL_SPI_MAX)
0136 break;
0137 }
0138 for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tn->spi; spi++) {
0139 index = __xfrm6_tunnel_spi_check(net, spi);
0140 if (index >= 0)
0141 goto alloc_spi;
0142 }
0143 spi = 0;
0144 goto out;
0145 alloc_spi:
0146 xfrm6_tn->spi = spi;
0147 x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, GFP_ATOMIC);
0148 if (!x6spi)
0149 goto out;
0150
0151 memcpy(&x6spi->addr, saddr, sizeof(x6spi->addr));
0152 x6spi->spi = spi;
0153 refcount_set(&x6spi->refcnt, 1);
0154
0155 hlist_add_head_rcu(&x6spi->list_byspi, &xfrm6_tn->spi_byspi[index]);
0156
0157 index = xfrm6_tunnel_spi_hash_byaddr(saddr);
0158 hlist_add_head_rcu(&x6spi->list_byaddr, &xfrm6_tn->spi_byaddr[index]);
0159 out:
0160 return spi;
0161 }
0162
0163 __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr)
0164 {
0165 struct xfrm6_tunnel_spi *x6spi;
0166 u32 spi;
0167
0168 spin_lock_bh(&xfrm6_tunnel_spi_lock);
0169 x6spi = __xfrm6_tunnel_spi_lookup(net, saddr);
0170 if (x6spi) {
0171 refcount_inc(&x6spi->refcnt);
0172 spi = x6spi->spi;
0173 } else
0174 spi = __xfrm6_tunnel_alloc_spi(net, saddr);
0175 spin_unlock_bh(&xfrm6_tunnel_spi_lock);
0176
0177 return htonl(spi);
0178 }
0179 EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi);
0180
0181 static void x6spi_destroy_rcu(struct rcu_head *head)
0182 {
0183 kmem_cache_free(xfrm6_tunnel_spi_kmem,
0184 container_of(head, struct xfrm6_tunnel_spi, rcu_head));
0185 }
0186
0187 static void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr)
0188 {
0189 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
0190 struct xfrm6_tunnel_spi *x6spi;
0191 struct hlist_node *n;
0192
0193 spin_lock_bh(&xfrm6_tunnel_spi_lock);
0194
0195 hlist_for_each_entry_safe(x6spi, n,
0196 &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
0197 list_byaddr)
0198 {
0199 if (xfrm6_addr_equal(&x6spi->addr, saddr)) {
0200 if (refcount_dec_and_test(&x6spi->refcnt)) {
0201 hlist_del_rcu(&x6spi->list_byaddr);
0202 hlist_del_rcu(&x6spi->list_byspi);
0203 call_rcu(&x6spi->rcu_head, x6spi_destroy_rcu);
0204 break;
0205 }
0206 }
0207 }
0208 spin_unlock_bh(&xfrm6_tunnel_spi_lock);
0209 }
0210
0211 static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
0212 {
0213 skb_push(skb, -skb_network_offset(skb));
0214 return 0;
0215 }
0216
0217 static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
0218 {
0219 return skb_network_header(skb)[IP6CB(skb)->nhoff];
0220 }
0221
0222 static int xfrm6_tunnel_rcv(struct sk_buff *skb)
0223 {
0224 struct net *net = dev_net(skb->dev);
0225 const struct ipv6hdr *iph = ipv6_hdr(skb);
0226 __be32 spi;
0227
0228 spi = xfrm6_tunnel_spi_lookup(net, (const xfrm_address_t *)&iph->saddr);
0229 return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi, NULL);
0230 }
0231
0232 static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
0233 u8 type, u8 code, int offset, __be32 info)
0234 {
0235
0236 switch (type) {
0237 case ICMPV6_DEST_UNREACH:
0238 switch (code) {
0239 case ICMPV6_NOROUTE:
0240 case ICMPV6_ADM_PROHIBITED:
0241 case ICMPV6_NOT_NEIGHBOUR:
0242 case ICMPV6_ADDR_UNREACH:
0243 case ICMPV6_PORT_UNREACH:
0244 default:
0245 break;
0246 }
0247 break;
0248 case ICMPV6_PKT_TOOBIG:
0249 break;
0250 case ICMPV6_TIME_EXCEED:
0251 switch (code) {
0252 case ICMPV6_EXC_HOPLIMIT:
0253 break;
0254 case ICMPV6_EXC_FRAGTIME:
0255 default:
0256 break;
0257 }
0258 break;
0259 case ICMPV6_PARAMPROB:
0260 switch (code) {
0261 case ICMPV6_HDR_FIELD: break;
0262 case ICMPV6_UNK_NEXTHDR: break;
0263 case ICMPV6_UNK_OPTION: break;
0264 }
0265 break;
0266 default:
0267 break;
0268 }
0269
0270 return 0;
0271 }
0272
0273 static int xfrm6_tunnel_init_state(struct xfrm_state *x)
0274 {
0275 if (x->props.mode != XFRM_MODE_TUNNEL)
0276 return -EINVAL;
0277
0278 if (x->encap)
0279 return -EINVAL;
0280
0281 x->props.header_len = sizeof(struct ipv6hdr);
0282
0283 return 0;
0284 }
0285
0286 static void xfrm6_tunnel_destroy(struct xfrm_state *x)
0287 {
0288 struct net *net = xs_net(x);
0289
0290 xfrm6_tunnel_free_spi(net, (xfrm_address_t *)&x->props.saddr);
0291 }
0292
0293 static const struct xfrm_type xfrm6_tunnel_type = {
0294 .owner = THIS_MODULE,
0295 .proto = IPPROTO_IPV6,
0296 .init_state = xfrm6_tunnel_init_state,
0297 .destructor = xfrm6_tunnel_destroy,
0298 .input = xfrm6_tunnel_input,
0299 .output = xfrm6_tunnel_output,
0300 };
0301
0302 static struct xfrm6_tunnel xfrm6_tunnel_handler __read_mostly = {
0303 .handler = xfrm6_tunnel_rcv,
0304 .err_handler = xfrm6_tunnel_err,
0305 .priority = 3,
0306 };
0307
0308 static struct xfrm6_tunnel xfrm46_tunnel_handler __read_mostly = {
0309 .handler = xfrm6_tunnel_rcv,
0310 .err_handler = xfrm6_tunnel_err,
0311 .priority = 3,
0312 };
0313
0314 static int __net_init xfrm6_tunnel_net_init(struct net *net)
0315 {
0316 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
0317 unsigned int i;
0318
0319 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
0320 INIT_HLIST_HEAD(&xfrm6_tn->spi_byaddr[i]);
0321 for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++)
0322 INIT_HLIST_HEAD(&xfrm6_tn->spi_byspi[i]);
0323 xfrm6_tn->spi = 0;
0324
0325 return 0;
0326 }
0327
0328 static void __net_exit xfrm6_tunnel_net_exit(struct net *net)
0329 {
0330 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
0331 unsigned int i;
0332
0333 xfrm_flush_gc();
0334 xfrm_state_flush(net, 0, false, true);
0335
0336 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
0337 WARN_ON_ONCE(!hlist_empty(&xfrm6_tn->spi_byaddr[i]));
0338
0339 for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++)
0340 WARN_ON_ONCE(!hlist_empty(&xfrm6_tn->spi_byspi[i]));
0341 }
0342
0343 static struct pernet_operations xfrm6_tunnel_net_ops = {
0344 .init = xfrm6_tunnel_net_init,
0345 .exit = xfrm6_tunnel_net_exit,
0346 .id = &xfrm6_tunnel_net_id,
0347 .size = sizeof(struct xfrm6_tunnel_net),
0348 };
0349
0350 static int __init xfrm6_tunnel_init(void)
0351 {
0352 int rv;
0353
0354 xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi",
0355 sizeof(struct xfrm6_tunnel_spi),
0356 0, SLAB_HWCACHE_ALIGN,
0357 NULL);
0358 if (!xfrm6_tunnel_spi_kmem)
0359 return -ENOMEM;
0360 rv = register_pernet_subsys(&xfrm6_tunnel_net_ops);
0361 if (rv < 0)
0362 goto out_pernet;
0363 rv = xfrm_register_type(&xfrm6_tunnel_type, AF_INET6);
0364 if (rv < 0)
0365 goto out_type;
0366 rv = xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6);
0367 if (rv < 0)
0368 goto out_xfrm6;
0369 rv = xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET);
0370 if (rv < 0)
0371 goto out_xfrm46;
0372 return 0;
0373
0374 out_xfrm46:
0375 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
0376 out_xfrm6:
0377 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
0378 out_type:
0379 unregister_pernet_subsys(&xfrm6_tunnel_net_ops);
0380 out_pernet:
0381 kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
0382 return rv;
0383 }
0384
0385 static void __exit xfrm6_tunnel_fini(void)
0386 {
0387 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
0388 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
0389 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
0390 unregister_pernet_subsys(&xfrm6_tunnel_net_ops);
0391
0392
0393
0394 rcu_barrier();
0395 kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
0396 }
0397
0398 module_init(xfrm6_tunnel_init);
0399 module_exit(xfrm6_tunnel_fini);
0400 MODULE_LICENSE("GPL");
0401 MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_IPV6);