Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C)2003,2004 USAGI/WIDE Project
0004  *
0005  * Authors  Mitsuru KANDA  <mk@linux-ipv6.org>
0006  *      YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
0007  *
0008  * Based on net/ipv4/xfrm4_tunnel.c
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  * xfrm_tunnel_spi things are for allocating unique id ("spi")
0042  * per xfrm_address_t.
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     /* xfrm6_tunnel native err handling */
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     /* Someone maybe has gotten the xfrm6_tunnel_spi.
0392      * So need to wait it.
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);