1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* xfrm4_protocol.c - Generic xfrm protocol multiplexer. 3 * 4 * Copyright (C) 2013 secunet Security Networks AG 5 * 6 * Author: 7 * Steffen Klassert <steffen.klassert@secunet.com> 8 * 9 * Based on: 10 * net/ipv4/tunnel4.c 11 */ 12 13 #include <linux/init.h> 14 #include <linux/mutex.h> 15 #include <linux/skbuff.h> 16 #include <net/icmp.h> 17 #include <net/ip.h> 18 #include <net/protocol.h> 19 #include <net/xfrm.h> 20 21 static struct xfrm4_protocol __rcu *esp4_handlers __read_mostly; 22 static struct xfrm4_protocol __rcu *ah4_handlers __read_mostly; 23 static struct xfrm4_protocol __rcu *ipcomp4_handlers __read_mostly; 24 static DEFINE_MUTEX(xfrm4_protocol_mutex); 25 26 static inline struct xfrm4_protocol __rcu **proto_handlers(u8 protocol) 27 { 28 switch (protocol) { 29 case IPPROTO_ESP: 30 return &esp4_handlers; 31 case IPPROTO_AH: 32 return &ah4_handlers; 33 case IPPROTO_COMP: 34 return &ipcomp4_handlers; 35 } 36 37 return NULL; 38 } 39 40 #define for_each_protocol_rcu(head, handler) \ 41 for (handler = rcu_dereference(head); \ 42 handler != NULL; \ 43 handler = rcu_dereference(handler->next)) \ 44 45 static int xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err) 46 { 47 int ret; 48 struct xfrm4_protocol *handler; 49 struct xfrm4_protocol __rcu **head = proto_handlers(protocol); 50 51 if (!head) 52 return 0; 53 54 for_each_protocol_rcu(*head, handler) 55 if ((ret = handler->cb_handler(skb, err)) <= 0) 56 return ret; 57 58 return 0; 59 } 60 61 int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, 62 int encap_type) 63 { 64 int ret; 65 struct xfrm4_protocol *handler; 66 struct xfrm4_protocol __rcu **head = proto_handlers(nexthdr); 67 68 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL; 69 XFRM_SPI_SKB_CB(skb)->family = AF_INET; 70 XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr); 71 72 if (!head) 73 goto out; 74 75 if (!skb_dst(skb)) { 76 const struct iphdr *iph = ip_hdr(skb); 77 78 if (ip_route_input_noref(skb, iph->daddr, iph->saddr, 79 iph->tos, skb->dev)) 80 goto drop; 81 } 82 83 for_each_protocol_rcu(*head, handler) 84 if ((ret = handler->input_handler(skb, nexthdr, spi, encap_type)) != -EINVAL) 85 return ret; 86 87 out: 88 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 89 90 drop: 91 kfree_skb(skb); 92 return 0; 93 } 94 EXPORT_SYMBOL(xfrm4_rcv_encap); 95 96 static int xfrm4_esp_rcv(struct sk_buff *skb) 97 { 98 int ret; 99 struct xfrm4_protocol *handler; 100 101 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL; 102 103 for_each_protocol_rcu(esp4_handlers, handler) 104 if ((ret = handler->handler(skb)) != -EINVAL) 105 return ret; 106 107 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 108 109 kfree_skb(skb); 110 return 0; 111 } 112 113 static int xfrm4_esp_err(struct sk_buff *skb, u32 info) 114 { 115 struct xfrm4_protocol *handler; 116 117 for_each_protocol_rcu(esp4_handlers, handler) 118 if (!handler->err_handler(skb, info)) 119 return 0; 120 121 return -ENOENT; 122 } 123 124 static int xfrm4_ah_rcv(struct sk_buff *skb) 125 { 126 int ret; 127 struct xfrm4_protocol *handler; 128 129 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL; 130 131 for_each_protocol_rcu(ah4_handlers, handler) 132 if ((ret = handler->handler(skb)) != -EINVAL) 133 return ret; 134 135 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 136 137 kfree_skb(skb); 138 return 0; 139 } 140 141 static int xfrm4_ah_err(struct sk_buff *skb, u32 info) 142 { 143 struct xfrm4_protocol *handler; 144 145 for_each_protocol_rcu(ah4_handlers, handler) 146 if (!handler->err_handler(skb, info)) 147 return 0; 148 149 return -ENOENT; 150 } 151 152 static int xfrm4_ipcomp_rcv(struct sk_buff *skb) 153 { 154 int ret; 155 struct xfrm4_protocol *handler; 156 157 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL; 158 159 for_each_protocol_rcu(ipcomp4_handlers, handler) 160 if ((ret = handler->handler(skb)) != -EINVAL) 161 return ret; 162 163 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 164 165 kfree_skb(skb); 166 return 0; 167 } 168 169 static int xfrm4_ipcomp_err(struct sk_buff *skb, u32 info) 170 { 171 struct xfrm4_protocol *handler; 172 173 for_each_protocol_rcu(ipcomp4_handlers, handler) 174 if (!handler->err_handler(skb, info)) 175 return 0; 176 177 return -ENOENT; 178 } 179 180 static const struct net_protocol esp4_protocol = { 181 .handler = xfrm4_esp_rcv, 182 .err_handler = xfrm4_esp_err, 183 .no_policy = 1, 184 .netns_ok = 1, 185 }; 186 187 static const struct net_protocol ah4_protocol = { 188 .handler = xfrm4_ah_rcv, 189 .err_handler = xfrm4_ah_err, 190 .no_policy = 1, 191 .netns_ok = 1, 192 }; 193 194 static const struct net_protocol ipcomp4_protocol = { 195 .handler = xfrm4_ipcomp_rcv, 196 .err_handler = xfrm4_ipcomp_err, 197 .no_policy = 1, 198 .netns_ok = 1, 199 }; 200 201 static const struct xfrm_input_afinfo xfrm4_input_afinfo = { 202 .family = AF_INET, 203 .callback = xfrm4_rcv_cb, 204 }; 205 206 static inline const struct net_protocol *netproto(unsigned char protocol) 207 { 208 switch (protocol) { 209 case IPPROTO_ESP: 210 return &esp4_protocol; 211 case IPPROTO_AH: 212 return &ah4_protocol; 213 case IPPROTO_COMP: 214 return &ipcomp4_protocol; 215 } 216 217 return NULL; 218 } 219 220 int xfrm4_protocol_register(struct xfrm4_protocol *handler, 221 unsigned char protocol) 222 { 223 struct xfrm4_protocol __rcu **pprev; 224 struct xfrm4_protocol *t; 225 bool add_netproto = false; 226 int ret = -EEXIST; 227 int priority = handler->priority; 228 229 if (!proto_handlers(protocol) || !netproto(protocol)) 230 return -EINVAL; 231 232 mutex_lock(&xfrm4_protocol_mutex); 233 234 if (!rcu_dereference_protected(*proto_handlers(protocol), 235 lockdep_is_held(&xfrm4_protocol_mutex))) 236 add_netproto = true; 237 238 for (pprev = proto_handlers(protocol); 239 (t = rcu_dereference_protected(*pprev, 240 lockdep_is_held(&xfrm4_protocol_mutex))) != NULL; 241 pprev = &t->next) { 242 if (t->priority < priority) 243 break; 244 if (t->priority == priority) 245 goto err; 246 } 247 248 handler->next = *pprev; 249 rcu_assign_pointer(*pprev, handler); 250 251 ret = 0; 252 253 err: 254 mutex_unlock(&xfrm4_protocol_mutex); 255 256 if (add_netproto) { 257 if (inet_add_protocol(netproto(protocol), protocol)) { 258 pr_err("%s: can't add protocol\n", __func__); 259 ret = -EAGAIN; 260 } 261 } 262 263 return ret; 264 } 265 EXPORT_SYMBOL(xfrm4_protocol_register); 266 267 int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, 268 unsigned char protocol) 269 { 270 struct xfrm4_protocol __rcu **pprev; 271 struct xfrm4_protocol *t; 272 int ret = -ENOENT; 273 274 if (!proto_handlers(protocol) || !netproto(protocol)) 275 return -EINVAL; 276 277 mutex_lock(&xfrm4_protocol_mutex); 278 279 for (pprev = proto_handlers(protocol); 280 (t = rcu_dereference_protected(*pprev, 281 lockdep_is_held(&xfrm4_protocol_mutex))) != NULL; 282 pprev = &t->next) { 283 if (t == handler) { 284 *pprev = handler->next; 285 ret = 0; 286 break; 287 } 288 } 289 290 if (!rcu_dereference_protected(*proto_handlers(protocol), 291 lockdep_is_held(&xfrm4_protocol_mutex))) { 292 if (inet_del_protocol(netproto(protocol), protocol) < 0) { 293 pr_err("%s: can't remove protocol\n", __func__); 294 ret = -EAGAIN; 295 } 296 } 297 298 mutex_unlock(&xfrm4_protocol_mutex); 299 300 synchronize_net(); 301 302 return ret; 303 } 304 EXPORT_SYMBOL(xfrm4_protocol_deregister); 305 306 void __init xfrm4_protocol_init(void) 307 { 308 xfrm_input_register_afinfo(&xfrm4_input_afinfo); 309 } 310 EXPORT_SYMBOL(xfrm4_protocol_init); 311