Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* xfrm4_protocol.c - Generic xfrm protocol multiplexer.
0003  *
0004  * Copyright (C) 2013 secunet Security Networks AG
0005  *
0006  * Author:
0007  * Steffen Klassert <steffen.klassert@secunet.com>
0008  *
0009  * Based on:
0010  * net/ipv4/tunnel4.c
0011  */
0012 
0013 #include <linux/init.h>
0014 #include <linux/mutex.h>
0015 #include <linux/skbuff.h>
0016 #include <net/icmp.h>
0017 #include <net/ip.h>
0018 #include <net/protocol.h>
0019 #include <net/xfrm.h>
0020 
0021 static struct xfrm4_protocol __rcu *esp4_handlers __read_mostly;
0022 static struct xfrm4_protocol __rcu *ah4_handlers __read_mostly;
0023 static struct xfrm4_protocol __rcu *ipcomp4_handlers __read_mostly;
0024 static DEFINE_MUTEX(xfrm4_protocol_mutex);
0025 
0026 static inline struct xfrm4_protocol __rcu **proto_handlers(u8 protocol)
0027 {
0028     switch (protocol) {
0029     case IPPROTO_ESP:
0030         return &esp4_handlers;
0031     case IPPROTO_AH:
0032         return &ah4_handlers;
0033     case IPPROTO_COMP:
0034         return &ipcomp4_handlers;
0035     }
0036 
0037     return NULL;
0038 }
0039 
0040 #define for_each_protocol_rcu(head, handler)        \
0041     for (handler = rcu_dereference(head);       \
0042          handler != NULL;               \
0043          handler = rcu_dereference(handler->next))  \
0044 
0045 static int xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err)
0046 {
0047     int ret;
0048     struct xfrm4_protocol *handler;
0049     struct xfrm4_protocol __rcu **head = proto_handlers(protocol);
0050 
0051     if (!head)
0052         return 0;
0053 
0054     for_each_protocol_rcu(*head, handler)
0055         if ((ret = handler->cb_handler(skb, err)) <= 0)
0056             return ret;
0057 
0058     return 0;
0059 }
0060 
0061 int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
0062             int encap_type)
0063 {
0064     int ret;
0065     struct xfrm4_protocol *handler;
0066     struct xfrm4_protocol __rcu **head = proto_handlers(nexthdr);
0067 
0068     XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
0069     XFRM_SPI_SKB_CB(skb)->family = AF_INET;
0070     XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
0071 
0072     if (!head)
0073         goto out;
0074 
0075     if (!skb_dst(skb)) {
0076         const struct iphdr *iph = ip_hdr(skb);
0077 
0078         if (ip_route_input_noref(skb, iph->daddr, iph->saddr,
0079                      iph->tos, skb->dev))
0080             goto drop;
0081     }
0082 
0083     for_each_protocol_rcu(*head, handler)
0084         if ((ret = handler->input_handler(skb, nexthdr, spi, encap_type)) != -EINVAL)
0085             return ret;
0086 
0087 out:
0088     icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
0089 
0090 drop:
0091     kfree_skb(skb);
0092     return 0;
0093 }
0094 EXPORT_SYMBOL(xfrm4_rcv_encap);
0095 
0096 static int xfrm4_esp_rcv(struct sk_buff *skb)
0097 {
0098     int ret;
0099     struct xfrm4_protocol *handler;
0100 
0101     XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
0102 
0103     for_each_protocol_rcu(esp4_handlers, handler)
0104         if ((ret = handler->handler(skb)) != -EINVAL)
0105             return ret;
0106 
0107     icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
0108 
0109     kfree_skb(skb);
0110     return 0;
0111 }
0112 
0113 static int xfrm4_esp_err(struct sk_buff *skb, u32 info)
0114 {
0115     struct xfrm4_protocol *handler;
0116 
0117     for_each_protocol_rcu(esp4_handlers, handler)
0118         if (!handler->err_handler(skb, info))
0119             return 0;
0120 
0121     return -ENOENT;
0122 }
0123 
0124 static int xfrm4_ah_rcv(struct sk_buff *skb)
0125 {
0126     int ret;
0127     struct xfrm4_protocol *handler;
0128 
0129     XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
0130 
0131     for_each_protocol_rcu(ah4_handlers, handler)
0132         if ((ret = handler->handler(skb)) != -EINVAL)
0133             return ret;
0134 
0135     icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
0136 
0137     kfree_skb(skb);
0138     return 0;
0139 }
0140 
0141 static int xfrm4_ah_err(struct sk_buff *skb, u32 info)
0142 {
0143     struct xfrm4_protocol *handler;
0144 
0145     for_each_protocol_rcu(ah4_handlers, handler)
0146         if (!handler->err_handler(skb, info))
0147             return 0;
0148 
0149     return -ENOENT;
0150 }
0151 
0152 static int xfrm4_ipcomp_rcv(struct sk_buff *skb)
0153 {
0154     int ret;
0155     struct xfrm4_protocol *handler;
0156 
0157     XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
0158 
0159     for_each_protocol_rcu(ipcomp4_handlers, handler)
0160         if ((ret = handler->handler(skb)) != -EINVAL)
0161             return ret;
0162 
0163     icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
0164 
0165     kfree_skb(skb);
0166     return 0;
0167 }
0168 
0169 static int xfrm4_ipcomp_err(struct sk_buff *skb, u32 info)
0170 {
0171     struct xfrm4_protocol *handler;
0172 
0173     for_each_protocol_rcu(ipcomp4_handlers, handler)
0174         if (!handler->err_handler(skb, info))
0175             return 0;
0176 
0177     return -ENOENT;
0178 }
0179 
0180 static const struct net_protocol esp4_protocol = {
0181     .handler    =   xfrm4_esp_rcv,
0182     .err_handler    =   xfrm4_esp_err,
0183     .no_policy  =   1,
0184 };
0185 
0186 static const struct net_protocol ah4_protocol = {
0187     .handler    =   xfrm4_ah_rcv,
0188     .err_handler    =   xfrm4_ah_err,
0189     .no_policy  =   1,
0190 };
0191 
0192 static const struct net_protocol ipcomp4_protocol = {
0193     .handler    =   xfrm4_ipcomp_rcv,
0194     .err_handler    =   xfrm4_ipcomp_err,
0195     .no_policy  =   1,
0196 };
0197 
0198 static const struct xfrm_input_afinfo xfrm4_input_afinfo = {
0199     .family     =   AF_INET,
0200     .callback   =   xfrm4_rcv_cb,
0201 };
0202 
0203 static inline const struct net_protocol *netproto(unsigned char protocol)
0204 {
0205     switch (protocol) {
0206     case IPPROTO_ESP:
0207         return &esp4_protocol;
0208     case IPPROTO_AH:
0209         return &ah4_protocol;
0210     case IPPROTO_COMP:
0211         return &ipcomp4_protocol;
0212     }
0213 
0214     return NULL;
0215 }
0216 
0217 int xfrm4_protocol_register(struct xfrm4_protocol *handler,
0218                 unsigned char protocol)
0219 {
0220     struct xfrm4_protocol __rcu **pprev;
0221     struct xfrm4_protocol *t;
0222     bool add_netproto = false;
0223     int ret = -EEXIST;
0224     int priority = handler->priority;
0225 
0226     if (!proto_handlers(protocol) || !netproto(protocol))
0227         return -EINVAL;
0228 
0229     mutex_lock(&xfrm4_protocol_mutex);
0230 
0231     if (!rcu_dereference_protected(*proto_handlers(protocol),
0232                        lockdep_is_held(&xfrm4_protocol_mutex)))
0233         add_netproto = true;
0234 
0235     for (pprev = proto_handlers(protocol);
0236          (t = rcu_dereference_protected(*pprev,
0237             lockdep_is_held(&xfrm4_protocol_mutex))) != NULL;
0238          pprev = &t->next) {
0239         if (t->priority < priority)
0240             break;
0241         if (t->priority == priority)
0242             goto err;
0243     }
0244 
0245     handler->next = *pprev;
0246     rcu_assign_pointer(*pprev, handler);
0247 
0248     ret = 0;
0249 
0250 err:
0251     mutex_unlock(&xfrm4_protocol_mutex);
0252 
0253     if (add_netproto) {
0254         if (inet_add_protocol(netproto(protocol), protocol)) {
0255             pr_err("%s: can't add protocol\n", __func__);
0256             ret = -EAGAIN;
0257         }
0258     }
0259 
0260     return ret;
0261 }
0262 EXPORT_SYMBOL(xfrm4_protocol_register);
0263 
0264 int xfrm4_protocol_deregister(struct xfrm4_protocol *handler,
0265                   unsigned char protocol)
0266 {
0267     struct xfrm4_protocol __rcu **pprev;
0268     struct xfrm4_protocol *t;
0269     int ret = -ENOENT;
0270 
0271     if (!proto_handlers(protocol) || !netproto(protocol))
0272         return -EINVAL;
0273 
0274     mutex_lock(&xfrm4_protocol_mutex);
0275 
0276     for (pprev = proto_handlers(protocol);
0277          (t = rcu_dereference_protected(*pprev,
0278             lockdep_is_held(&xfrm4_protocol_mutex))) != NULL;
0279          pprev = &t->next) {
0280         if (t == handler) {
0281             *pprev = handler->next;
0282             ret = 0;
0283             break;
0284         }
0285     }
0286 
0287     if (!rcu_dereference_protected(*proto_handlers(protocol),
0288                        lockdep_is_held(&xfrm4_protocol_mutex))) {
0289         if (inet_del_protocol(netproto(protocol), protocol) < 0) {
0290             pr_err("%s: can't remove protocol\n", __func__);
0291             ret = -EAGAIN;
0292         }
0293     }
0294 
0295     mutex_unlock(&xfrm4_protocol_mutex);
0296 
0297     synchronize_net();
0298 
0299     return ret;
0300 }
0301 EXPORT_SYMBOL(xfrm4_protocol_deregister);
0302 
0303 void __init xfrm4_protocol_init(void)
0304 {
0305     xfrm_input_register_afinfo(&xfrm4_input_afinfo);
0306 }