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 
0009 #define pr_fmt(fmt) "IPv6: " fmt
0010 
0011 #include <linux/icmpv6.h>
0012 #include <linux/init.h>
0013 #include <linux/module.h>
0014 #include <linux/mutex.h>
0015 #include <linux/netdevice.h>
0016 #include <linux/skbuff.h>
0017 #include <linux/slab.h>
0018 #include <net/ipv6.h>
0019 #include <net/protocol.h>
0020 #include <net/xfrm.h>
0021 
0022 static struct xfrm6_tunnel __rcu *tunnel6_handlers __read_mostly;
0023 static struct xfrm6_tunnel __rcu *tunnel46_handlers __read_mostly;
0024 static struct xfrm6_tunnel __rcu *tunnelmpls6_handlers __read_mostly;
0025 static DEFINE_MUTEX(tunnel6_mutex);
0026 
0027 static inline int xfrm6_tunnel_mpls_supported(void)
0028 {
0029     return IS_ENABLED(CONFIG_MPLS);
0030 }
0031 
0032 int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family)
0033 {
0034     struct xfrm6_tunnel __rcu **pprev;
0035     struct xfrm6_tunnel *t;
0036     int ret = -EEXIST;
0037     int priority = handler->priority;
0038 
0039     mutex_lock(&tunnel6_mutex);
0040 
0041     switch (family) {
0042     case AF_INET6:
0043         pprev = &tunnel6_handlers;
0044         break;
0045     case AF_INET:
0046         pprev = &tunnel46_handlers;
0047         break;
0048     case AF_MPLS:
0049         pprev = &tunnelmpls6_handlers;
0050         break;
0051     default:
0052         goto err;
0053     }
0054 
0055     for (; (t = rcu_dereference_protected(*pprev,
0056             lockdep_is_held(&tunnel6_mutex))) != NULL;
0057          pprev = &t->next) {
0058         if (t->priority > priority)
0059             break;
0060         if (t->priority == priority)
0061             goto err;
0062     }
0063 
0064     handler->next = *pprev;
0065     rcu_assign_pointer(*pprev, handler);
0066 
0067     ret = 0;
0068 
0069 err:
0070     mutex_unlock(&tunnel6_mutex);
0071 
0072     return ret;
0073 }
0074 EXPORT_SYMBOL(xfrm6_tunnel_register);
0075 
0076 int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family)
0077 {
0078     struct xfrm6_tunnel __rcu **pprev;
0079     struct xfrm6_tunnel *t;
0080     int ret = -ENOENT;
0081 
0082     mutex_lock(&tunnel6_mutex);
0083 
0084     switch (family) {
0085     case AF_INET6:
0086         pprev = &tunnel6_handlers;
0087         break;
0088     case AF_INET:
0089         pprev = &tunnel46_handlers;
0090         break;
0091     case AF_MPLS:
0092         pprev = &tunnelmpls6_handlers;
0093         break;
0094     default:
0095         goto err;
0096     }
0097 
0098     for (; (t = rcu_dereference_protected(*pprev,
0099             lockdep_is_held(&tunnel6_mutex))) != NULL;
0100          pprev = &t->next) {
0101         if (t == handler) {
0102             *pprev = handler->next;
0103             ret = 0;
0104             break;
0105         }
0106     }
0107 
0108 err:
0109     mutex_unlock(&tunnel6_mutex);
0110 
0111     synchronize_net();
0112 
0113     return ret;
0114 }
0115 EXPORT_SYMBOL(xfrm6_tunnel_deregister);
0116 
0117 #define for_each_tunnel_rcu(head, handler)      \
0118     for (handler = rcu_dereference(head);       \
0119          handler != NULL;               \
0120          handler = rcu_dereference(handler->next))  \
0121 
0122 static int tunnelmpls6_rcv(struct sk_buff *skb)
0123 {
0124     struct xfrm6_tunnel *handler;
0125 
0126     if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
0127         goto drop;
0128 
0129     for_each_tunnel_rcu(tunnelmpls6_handlers, handler)
0130         if (!handler->handler(skb))
0131             return 0;
0132 
0133     icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
0134 
0135 drop:
0136     kfree_skb(skb);
0137     return 0;
0138 }
0139 
0140 static int tunnel6_rcv(struct sk_buff *skb)
0141 {
0142     struct xfrm6_tunnel *handler;
0143 
0144     if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
0145         goto drop;
0146 
0147     for_each_tunnel_rcu(tunnel6_handlers, handler)
0148         if (!handler->handler(skb))
0149             return 0;
0150 
0151     icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
0152 
0153 drop:
0154     kfree_skb(skb);
0155     return 0;
0156 }
0157 
0158 #if IS_ENABLED(CONFIG_INET6_XFRM_TUNNEL)
0159 static int tunnel6_rcv_cb(struct sk_buff *skb, u8 proto, int err)
0160 {
0161     struct xfrm6_tunnel __rcu *head;
0162     struct xfrm6_tunnel *handler;
0163     int ret;
0164 
0165     head = (proto == IPPROTO_IPV6) ? tunnel6_handlers : tunnel46_handlers;
0166 
0167     for_each_tunnel_rcu(head, handler) {
0168         if (handler->cb_handler) {
0169             ret = handler->cb_handler(skb, err);
0170             if (ret <= 0)
0171                 return ret;
0172         }
0173     }
0174 
0175     return 0;
0176 }
0177 
0178 static const struct xfrm_input_afinfo tunnel6_input_afinfo = {
0179     .family     =   AF_INET6,
0180     .is_ipip    =   true,
0181     .callback   =   tunnel6_rcv_cb,
0182 };
0183 #endif
0184 
0185 static int tunnel46_rcv(struct sk_buff *skb)
0186 {
0187     struct xfrm6_tunnel *handler;
0188 
0189     if (!pskb_may_pull(skb, sizeof(struct iphdr)))
0190         goto drop;
0191 
0192     for_each_tunnel_rcu(tunnel46_handlers, handler)
0193         if (!handler->handler(skb))
0194             return 0;
0195 
0196     icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
0197 
0198 drop:
0199     kfree_skb(skb);
0200     return 0;
0201 }
0202 
0203 static int tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
0204             u8 type, u8 code, int offset, __be32 info)
0205 {
0206     struct xfrm6_tunnel *handler;
0207 
0208     for_each_tunnel_rcu(tunnel6_handlers, handler)
0209         if (!handler->err_handler(skb, opt, type, code, offset, info))
0210             return 0;
0211 
0212     return -ENOENT;
0213 }
0214 
0215 static int tunnel46_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
0216              u8 type, u8 code, int offset, __be32 info)
0217 {
0218     struct xfrm6_tunnel *handler;
0219 
0220     for_each_tunnel_rcu(tunnel46_handlers, handler)
0221         if (!handler->err_handler(skb, opt, type, code, offset, info))
0222             return 0;
0223 
0224     return -ENOENT;
0225 }
0226 
0227 static int tunnelmpls6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
0228                u8 type, u8 code, int offset, __be32 info)
0229 {
0230     struct xfrm6_tunnel *handler;
0231 
0232     for_each_tunnel_rcu(tunnelmpls6_handlers, handler)
0233         if (!handler->err_handler(skb, opt, type, code, offset, info))
0234             return 0;
0235 
0236     return -ENOENT;
0237 }
0238 
0239 static const struct inet6_protocol tunnel6_protocol = {
0240     .handler    = tunnel6_rcv,
0241     .err_handler    = tunnel6_err,
0242     .flags          = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
0243 };
0244 
0245 static const struct inet6_protocol tunnel46_protocol = {
0246     .handler    = tunnel46_rcv,
0247     .err_handler    = tunnel46_err,
0248     .flags          = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
0249 };
0250 
0251 static const struct inet6_protocol tunnelmpls6_protocol = {
0252     .handler    = tunnelmpls6_rcv,
0253     .err_handler    = tunnelmpls6_err,
0254     .flags          = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
0255 };
0256 
0257 static int __init tunnel6_init(void)
0258 {
0259     if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) {
0260         pr_err("%s: can't add protocol\n", __func__);
0261         return -EAGAIN;
0262     }
0263     if (inet6_add_protocol(&tunnel46_protocol, IPPROTO_IPIP)) {
0264         pr_err("%s: can't add protocol\n", __func__);
0265         inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6);
0266         return -EAGAIN;
0267     }
0268     if (xfrm6_tunnel_mpls_supported() &&
0269         inet6_add_protocol(&tunnelmpls6_protocol, IPPROTO_MPLS)) {
0270         pr_err("%s: can't add protocol\n", __func__);
0271         inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6);
0272         inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP);
0273         return -EAGAIN;
0274     }
0275 #if IS_ENABLED(CONFIG_INET6_XFRM_TUNNEL)
0276     if (xfrm_input_register_afinfo(&tunnel6_input_afinfo)) {
0277         pr_err("%s: can't add input afinfo\n", __func__);
0278         inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6);
0279         inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP);
0280         if (xfrm6_tunnel_mpls_supported())
0281             inet6_del_protocol(&tunnelmpls6_protocol, IPPROTO_MPLS);
0282         return -EAGAIN;
0283     }
0284 #endif
0285     return 0;
0286 }
0287 
0288 static void __exit tunnel6_fini(void)
0289 {
0290 #if IS_ENABLED(CONFIG_INET6_XFRM_TUNNEL)
0291     if (xfrm_input_unregister_afinfo(&tunnel6_input_afinfo))
0292         pr_err("%s: can't remove input afinfo\n", __func__);
0293 #endif
0294     if (inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP))
0295         pr_err("%s: can't remove protocol\n", __func__);
0296     if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6))
0297         pr_err("%s: can't remove protocol\n", __func__);
0298     if (xfrm6_tunnel_mpls_supported() &&
0299         inet6_del_protocol(&tunnelmpls6_protocol, IPPROTO_MPLS))
0300         pr_err("%s: can't remove protocol\n", __func__);
0301 }
0302 
0303 module_init(tunnel6_init);
0304 module_exit(tunnel6_fini);
0305 MODULE_LICENSE("GPL");