Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* tunnel4.c: Generic IP tunnel transformer.
0003  *
0004  * Copyright (C) 2003 David S. Miller (davem@redhat.com)
0005  */
0006 
0007 #include <linux/init.h>
0008 #include <linux/module.h>
0009 #include <linux/mutex.h>
0010 #include <linux/mpls.h>
0011 #include <linux/netdevice.h>
0012 #include <linux/skbuff.h>
0013 #include <linux/slab.h>
0014 #include <net/icmp.h>
0015 #include <net/ip.h>
0016 #include <net/protocol.h>
0017 #include <net/xfrm.h>
0018 
0019 static struct xfrm_tunnel __rcu *tunnel4_handlers __read_mostly;
0020 static struct xfrm_tunnel __rcu *tunnel64_handlers __read_mostly;
0021 static struct xfrm_tunnel __rcu *tunnelmpls4_handlers __read_mostly;
0022 static DEFINE_MUTEX(tunnel4_mutex);
0023 
0024 static inline struct xfrm_tunnel __rcu **fam_handlers(unsigned short family)
0025 {
0026     return (family == AF_INET) ? &tunnel4_handlers :
0027         (family == AF_INET6) ? &tunnel64_handlers :
0028         &tunnelmpls4_handlers;
0029 }
0030 
0031 int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family)
0032 {
0033     struct xfrm_tunnel __rcu **pprev;
0034     struct xfrm_tunnel *t;
0035 
0036     int ret = -EEXIST;
0037     int priority = handler->priority;
0038 
0039     mutex_lock(&tunnel4_mutex);
0040 
0041     for (pprev = fam_handlers(family);
0042          (t = rcu_dereference_protected(*pprev,
0043             lockdep_is_held(&tunnel4_mutex))) != NULL;
0044          pprev = &t->next) {
0045         if (t->priority > priority)
0046             break;
0047         if (t->priority == priority)
0048             goto err;
0049     }
0050 
0051     handler->next = *pprev;
0052     rcu_assign_pointer(*pprev, handler);
0053 
0054     ret = 0;
0055 
0056 err:
0057     mutex_unlock(&tunnel4_mutex);
0058 
0059     return ret;
0060 }
0061 EXPORT_SYMBOL(xfrm4_tunnel_register);
0062 
0063 int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family)
0064 {
0065     struct xfrm_tunnel __rcu **pprev;
0066     struct xfrm_tunnel *t;
0067     int ret = -ENOENT;
0068 
0069     mutex_lock(&tunnel4_mutex);
0070 
0071     for (pprev = fam_handlers(family);
0072          (t = rcu_dereference_protected(*pprev,
0073             lockdep_is_held(&tunnel4_mutex))) != NULL;
0074          pprev = &t->next) {
0075         if (t == handler) {
0076             *pprev = handler->next;
0077             ret = 0;
0078             break;
0079         }
0080     }
0081 
0082     mutex_unlock(&tunnel4_mutex);
0083 
0084     synchronize_net();
0085 
0086     return ret;
0087 }
0088 EXPORT_SYMBOL(xfrm4_tunnel_deregister);
0089 
0090 #define for_each_tunnel_rcu(head, handler)      \
0091     for (handler = rcu_dereference(head);       \
0092          handler != NULL;               \
0093          handler = rcu_dereference(handler->next))  \
0094 
0095 static int tunnel4_rcv(struct sk_buff *skb)
0096 {
0097     struct xfrm_tunnel *handler;
0098 
0099     if (!pskb_may_pull(skb, sizeof(struct iphdr)))
0100         goto drop;
0101 
0102     for_each_tunnel_rcu(tunnel4_handlers, handler)
0103         if (!handler->handler(skb))
0104             return 0;
0105 
0106     icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
0107 
0108 drop:
0109     kfree_skb(skb);
0110     return 0;
0111 }
0112 
0113 #if IS_ENABLED(CONFIG_INET_XFRM_TUNNEL)
0114 static int tunnel4_rcv_cb(struct sk_buff *skb, u8 proto, int err)
0115 {
0116     struct xfrm_tunnel __rcu *head;
0117     struct xfrm_tunnel *handler;
0118     int ret;
0119 
0120     head = (proto == IPPROTO_IPIP) ? tunnel4_handlers : tunnel64_handlers;
0121 
0122     for_each_tunnel_rcu(head, handler) {
0123         if (handler->cb_handler) {
0124             ret = handler->cb_handler(skb, err);
0125             if (ret <= 0)
0126                 return ret;
0127         }
0128     }
0129 
0130     return 0;
0131 }
0132 
0133 static const struct xfrm_input_afinfo tunnel4_input_afinfo = {
0134     .family     =   AF_INET,
0135     .is_ipip    =   true,
0136     .callback   =   tunnel4_rcv_cb,
0137 };
0138 #endif
0139 
0140 #if IS_ENABLED(CONFIG_IPV6)
0141 static int tunnel64_rcv(struct sk_buff *skb)
0142 {
0143     struct xfrm_tunnel *handler;
0144 
0145     if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
0146         goto drop;
0147 
0148     for_each_tunnel_rcu(tunnel64_handlers, handler)
0149         if (!handler->handler(skb))
0150             return 0;
0151 
0152     icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
0153 
0154 drop:
0155     kfree_skb(skb);
0156     return 0;
0157 }
0158 #endif
0159 
0160 #if IS_ENABLED(CONFIG_MPLS)
0161 static int tunnelmpls4_rcv(struct sk_buff *skb)
0162 {
0163     struct xfrm_tunnel *handler;
0164 
0165     if (!pskb_may_pull(skb, sizeof(struct mpls_label)))
0166         goto drop;
0167 
0168     for_each_tunnel_rcu(tunnelmpls4_handlers, handler)
0169         if (!handler->handler(skb))
0170             return 0;
0171 
0172     icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
0173 
0174 drop:
0175     kfree_skb(skb);
0176     return 0;
0177 }
0178 #endif
0179 
0180 static int tunnel4_err(struct sk_buff *skb, u32 info)
0181 {
0182     struct xfrm_tunnel *handler;
0183 
0184     for_each_tunnel_rcu(tunnel4_handlers, handler)
0185         if (!handler->err_handler(skb, info))
0186             return 0;
0187 
0188     return -ENOENT;
0189 }
0190 
0191 #if IS_ENABLED(CONFIG_IPV6)
0192 static int tunnel64_err(struct sk_buff *skb, u32 info)
0193 {
0194     struct xfrm_tunnel *handler;
0195 
0196     for_each_tunnel_rcu(tunnel64_handlers, handler)
0197         if (!handler->err_handler(skb, info))
0198             return 0;
0199 
0200     return -ENOENT;
0201 }
0202 #endif
0203 
0204 #if IS_ENABLED(CONFIG_MPLS)
0205 static int tunnelmpls4_err(struct sk_buff *skb, u32 info)
0206 {
0207     struct xfrm_tunnel *handler;
0208 
0209     for_each_tunnel_rcu(tunnelmpls4_handlers, handler)
0210         if (!handler->err_handler(skb, info))
0211             return 0;
0212 
0213     return -ENOENT;
0214 }
0215 #endif
0216 
0217 static const struct net_protocol tunnel4_protocol = {
0218     .handler    =   tunnel4_rcv,
0219     .err_handler    =   tunnel4_err,
0220     .no_policy  =   1,
0221 };
0222 
0223 #if IS_ENABLED(CONFIG_IPV6)
0224 static const struct net_protocol tunnel64_protocol = {
0225     .handler    =   tunnel64_rcv,
0226     .err_handler    =   tunnel64_err,
0227     .no_policy  =   1,
0228 };
0229 #endif
0230 
0231 #if IS_ENABLED(CONFIG_MPLS)
0232 static const struct net_protocol tunnelmpls4_protocol = {
0233     .handler    =   tunnelmpls4_rcv,
0234     .err_handler    =   tunnelmpls4_err,
0235     .no_policy  =   1,
0236 };
0237 #endif
0238 
0239 static int __init tunnel4_init(void)
0240 {
0241     if (inet_add_protocol(&tunnel4_protocol, IPPROTO_IPIP))
0242         goto err;
0243 #if IS_ENABLED(CONFIG_IPV6)
0244     if (inet_add_protocol(&tunnel64_protocol, IPPROTO_IPV6)) {
0245         inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP);
0246         goto err;
0247     }
0248 #endif
0249 #if IS_ENABLED(CONFIG_MPLS)
0250     if (inet_add_protocol(&tunnelmpls4_protocol, IPPROTO_MPLS)) {
0251         inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP);
0252 #if IS_ENABLED(CONFIG_IPV6)
0253         inet_del_protocol(&tunnel64_protocol, IPPROTO_IPV6);
0254 #endif
0255         goto err;
0256     }
0257 #endif
0258 #if IS_ENABLED(CONFIG_INET_XFRM_TUNNEL)
0259     if (xfrm_input_register_afinfo(&tunnel4_input_afinfo)) {
0260         inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP);
0261 #if IS_ENABLED(CONFIG_IPV6)
0262         inet_del_protocol(&tunnel64_protocol, IPPROTO_IPV6);
0263 #endif
0264 #if IS_ENABLED(CONFIG_MPLS)
0265         inet_del_protocol(&tunnelmpls4_protocol, IPPROTO_MPLS);
0266 #endif
0267         goto err;
0268     }
0269 #endif
0270     return 0;
0271 
0272 err:
0273     pr_err("%s: can't add protocol\n", __func__);
0274     return -EAGAIN;
0275 }
0276 
0277 static void __exit tunnel4_fini(void)
0278 {
0279 #if IS_ENABLED(CONFIG_INET_XFRM_TUNNEL)
0280     if (xfrm_input_unregister_afinfo(&tunnel4_input_afinfo))
0281         pr_err("tunnel4 close: can't remove input afinfo\n");
0282 #endif
0283 #if IS_ENABLED(CONFIG_MPLS)
0284     if (inet_del_protocol(&tunnelmpls4_protocol, IPPROTO_MPLS))
0285         pr_err("tunnelmpls4 close: can't remove protocol\n");
0286 #endif
0287 #if IS_ENABLED(CONFIG_IPV6)
0288     if (inet_del_protocol(&tunnel64_protocol, IPPROTO_IPV6))
0289         pr_err("tunnel64 close: can't remove protocol\n");
0290 #endif
0291     if (inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP))
0292         pr_err("tunnel4 close: can't remove protocol\n");
0293 }
0294 
0295 module_init(tunnel4_init);
0296 module_exit(tunnel4_fini);
0297 MODULE_LICENSE("GPL");