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