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 for_each_protocol_rcu(*head, handler) 76 if ((ret = handler->input_handler(skb, nexthdr, spi, encap_type)) != -EINVAL) 77 return ret; 78 79 out: 80 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 81 82 kfree_skb(skb); 83 return 0; 84 } 85 EXPORT_SYMBOL(xfrm4_rcv_encap); 86 87 static int xfrm4_esp_rcv(struct sk_buff *skb) 88 { 89 int ret; 90 struct xfrm4_protocol *handler; 91 92 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL; 93 94 for_each_protocol_rcu(esp4_handlers, handler) 95 if ((ret = handler->handler(skb)) != -EINVAL) 96 return ret; 97 98 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 99 100 kfree_skb(skb); 101 return 0; 102 } 103 104 static int xfrm4_esp_err(struct sk_buff *skb, u32 info) 105 { 106 struct xfrm4_protocol *handler; 107 108 for_each_protocol_rcu(esp4_handlers, handler) 109 if (!handler->err_handler(skb, info)) 110 return 0; 111 112 return -ENOENT; 113 } 114 115 static int xfrm4_ah_rcv(struct sk_buff *skb) 116 { 117 int ret; 118 struct xfrm4_protocol *handler; 119 120 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL; 121 122 for_each_protocol_rcu(ah4_handlers, handler) 123 if ((ret = handler->handler(skb)) != -EINVAL) 124 return ret; 125 126 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 127 128 kfree_skb(skb); 129 return 0; 130 } 131 132 static int xfrm4_ah_err(struct sk_buff *skb, u32 info) 133 { 134 struct xfrm4_protocol *handler; 135 136 for_each_protocol_rcu(ah4_handlers, handler) 137 if (!handler->err_handler(skb, info)) 138 return 0; 139 140 return -ENOENT; 141 } 142 143 static int xfrm4_ipcomp_rcv(struct sk_buff *skb) 144 { 145 int ret; 146 struct xfrm4_protocol *handler; 147 148 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL; 149 150 for_each_protocol_rcu(ipcomp4_handlers, handler) 151 if ((ret = handler->handler(skb)) != -EINVAL) 152 return ret; 153 154 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 155 156 kfree_skb(skb); 157 return 0; 158 } 159 160 static int xfrm4_ipcomp_err(struct sk_buff *skb, u32 info) 161 { 162 struct xfrm4_protocol *handler; 163 164 for_each_protocol_rcu(ipcomp4_handlers, handler) 165 if (!handler->err_handler(skb, info)) 166 return 0; 167 168 return -ENOENT; 169 } 170 171 static const struct net_protocol esp4_protocol = { 172 .handler = xfrm4_esp_rcv, 173 .err_handler = xfrm4_esp_err, 174 .no_policy = 1, 175 .netns_ok = 1, 176 }; 177 178 static const struct net_protocol ah4_protocol = { 179 .handler = xfrm4_ah_rcv, 180 .err_handler = xfrm4_ah_err, 181 .no_policy = 1, 182 .netns_ok = 1, 183 }; 184 185 static const struct net_protocol ipcomp4_protocol = { 186 .handler = xfrm4_ipcomp_rcv, 187 .err_handler = xfrm4_ipcomp_err, 188 .no_policy = 1, 189 .netns_ok = 1, 190 }; 191 192 static const struct xfrm_input_afinfo xfrm4_input_afinfo = { 193 .family = AF_INET, 194 .callback = xfrm4_rcv_cb, 195 }; 196 197 static inline const struct net_protocol *netproto(unsigned char protocol) 198 { 199 switch (protocol) { 200 case IPPROTO_ESP: 201 return &esp4_protocol; 202 case IPPROTO_AH: 203 return &ah4_protocol; 204 case IPPROTO_COMP: 205 return &ipcomp4_protocol; 206 } 207 208 return NULL; 209 } 210 211 int xfrm4_protocol_register(struct xfrm4_protocol *handler, 212 unsigned char protocol) 213 { 214 struct xfrm4_protocol __rcu **pprev; 215 struct xfrm4_protocol *t; 216 bool add_netproto = false; 217 int ret = -EEXIST; 218 int priority = handler->priority; 219 220 if (!proto_handlers(protocol) || !netproto(protocol)) 221 return -EINVAL; 222 223 mutex_lock(&xfrm4_protocol_mutex); 224 225 if (!rcu_dereference_protected(*proto_handlers(protocol), 226 lockdep_is_held(&xfrm4_protocol_mutex))) 227 add_netproto = true; 228 229 for (pprev = proto_handlers(protocol); 230 (t = rcu_dereference_protected(*pprev, 231 lockdep_is_held(&xfrm4_protocol_mutex))) != NULL; 232 pprev = &t->next) { 233 if (t->priority < priority) 234 break; 235 if (t->priority == priority) 236 goto err; 237 } 238 239 handler->next = *pprev; 240 rcu_assign_pointer(*pprev, handler); 241 242 ret = 0; 243 244 err: 245 mutex_unlock(&xfrm4_protocol_mutex); 246 247 if (add_netproto) { 248 if (inet_add_protocol(netproto(protocol), protocol)) { 249 pr_err("%s: can't add protocol\n", __func__); 250 ret = -EAGAIN; 251 } 252 } 253 254 return ret; 255 } 256 EXPORT_SYMBOL(xfrm4_protocol_register); 257 258 int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, 259 unsigned char protocol) 260 { 261 struct xfrm4_protocol __rcu **pprev; 262 struct xfrm4_protocol *t; 263 int ret = -ENOENT; 264 265 if (!proto_handlers(protocol) || !netproto(protocol)) 266 return -EINVAL; 267 268 mutex_lock(&xfrm4_protocol_mutex); 269 270 for (pprev = proto_handlers(protocol); 271 (t = rcu_dereference_protected(*pprev, 272 lockdep_is_held(&xfrm4_protocol_mutex))) != NULL; 273 pprev = &t->next) { 274 if (t == handler) { 275 *pprev = handler->next; 276 ret = 0; 277 break; 278 } 279 } 280 281 if (!rcu_dereference_protected(*proto_handlers(protocol), 282 lockdep_is_held(&xfrm4_protocol_mutex))) { 283 if (inet_del_protocol(netproto(protocol), protocol) < 0) { 284 pr_err("%s: can't remove protocol\n", __func__); 285 ret = -EAGAIN; 286 } 287 } 288 289 mutex_unlock(&xfrm4_protocol_mutex); 290 291 synchronize_net(); 292 293 return ret; 294 } 295 EXPORT_SYMBOL(xfrm4_protocol_deregister); 296 297 void __init xfrm4_protocol_init(void) 298 { 299 xfrm_input_register_afinfo(&xfrm4_input_afinfo); 300 } 301 EXPORT_SYMBOL(xfrm4_protocol_init); 302