1 /* 2 * xfrm_input.c 3 * 4 * Changes: 5 * YOSHIFUJI Hideaki @USAGI 6 * Split up af-specific portion 7 * 8 */ 9 10 #include <linux/slab.h> 11 #include <linux/module.h> 12 #include <linux/netdevice.h> 13 #include <net/dst.h> 14 #include <net/ip.h> 15 #include <net/xfrm.h> 16 #include <net/ip_tunnels.h> 17 #include <net/ip6_tunnel.h> 18 19 static struct kmem_cache *secpath_cachep __read_mostly; 20 21 static DEFINE_SPINLOCK(xfrm_input_afinfo_lock); 22 static struct xfrm_input_afinfo __rcu *xfrm_input_afinfo[NPROTO]; 23 24 int xfrm_input_register_afinfo(struct xfrm_input_afinfo *afinfo) 25 { 26 int err = 0; 27 28 if (unlikely(afinfo == NULL)) 29 return -EINVAL; 30 if (unlikely(afinfo->family >= NPROTO)) 31 return -EAFNOSUPPORT; 32 spin_lock_bh(&xfrm_input_afinfo_lock); 33 if (unlikely(xfrm_input_afinfo[afinfo->family] != NULL)) 34 err = -EEXIST; 35 else 36 rcu_assign_pointer(xfrm_input_afinfo[afinfo->family], afinfo); 37 spin_unlock_bh(&xfrm_input_afinfo_lock); 38 return err; 39 } 40 EXPORT_SYMBOL(xfrm_input_register_afinfo); 41 42 int xfrm_input_unregister_afinfo(struct xfrm_input_afinfo *afinfo) 43 { 44 int err = 0; 45 46 if (unlikely(afinfo == NULL)) 47 return -EINVAL; 48 if (unlikely(afinfo->family >= NPROTO)) 49 return -EAFNOSUPPORT; 50 spin_lock_bh(&xfrm_input_afinfo_lock); 51 if (likely(xfrm_input_afinfo[afinfo->family] != NULL)) { 52 if (unlikely(xfrm_input_afinfo[afinfo->family] != afinfo)) 53 err = -EINVAL; 54 else 55 RCU_INIT_POINTER(xfrm_input_afinfo[afinfo->family], NULL); 56 } 57 spin_unlock_bh(&xfrm_input_afinfo_lock); 58 synchronize_rcu(); 59 return err; 60 } 61 EXPORT_SYMBOL(xfrm_input_unregister_afinfo); 62 63 static struct xfrm_input_afinfo *xfrm_input_get_afinfo(unsigned int family) 64 { 65 struct xfrm_input_afinfo *afinfo; 66 67 if (unlikely(family >= NPROTO)) 68 return NULL; 69 rcu_read_lock(); 70 afinfo = rcu_dereference(xfrm_input_afinfo[family]); 71 if (unlikely(!afinfo)) 72 rcu_read_unlock(); 73 return afinfo; 74 } 75 76 static void xfrm_input_put_afinfo(struct xfrm_input_afinfo *afinfo) 77 { 78 rcu_read_unlock(); 79 } 80 81 static int xfrm_rcv_cb(struct sk_buff *skb, unsigned int family, u8 protocol, 82 int err) 83 { 84 int ret; 85 struct xfrm_input_afinfo *afinfo = xfrm_input_get_afinfo(family); 86 87 if (!afinfo) 88 return -EAFNOSUPPORT; 89 90 ret = afinfo->callback(skb, protocol, err); 91 xfrm_input_put_afinfo(afinfo); 92 93 return ret; 94 } 95 96 void __secpath_destroy(struct sec_path *sp) 97 { 98 int i; 99 for (i = 0; i < sp->len; i++) 100 xfrm_state_put(sp->xvec[i]); 101 kmem_cache_free(secpath_cachep, sp); 102 } 103 EXPORT_SYMBOL(__secpath_destroy); 104 105 struct sec_path *secpath_dup(struct sec_path *src) 106 { 107 struct sec_path *sp; 108 109 sp = kmem_cache_alloc(secpath_cachep, GFP_ATOMIC); 110 if (!sp) 111 return NULL; 112 113 sp->len = 0; 114 if (src) { 115 int i; 116 117 memcpy(sp, src, sizeof(*sp)); 118 for (i = 0; i < sp->len; i++) 119 xfrm_state_hold(sp->xvec[i]); 120 } 121 atomic_set(&sp->refcnt, 1); 122 return sp; 123 } 124 EXPORT_SYMBOL(secpath_dup); 125 126 /* Fetch spi and seq from ipsec header */ 127 128 int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq) 129 { 130 int offset, offset_seq; 131 int hlen; 132 133 switch (nexthdr) { 134 case IPPROTO_AH: 135 hlen = sizeof(struct ip_auth_hdr); 136 offset = offsetof(struct ip_auth_hdr, spi); 137 offset_seq = offsetof(struct ip_auth_hdr, seq_no); 138 break; 139 case IPPROTO_ESP: 140 hlen = sizeof(struct ip_esp_hdr); 141 offset = offsetof(struct ip_esp_hdr, spi); 142 offset_seq = offsetof(struct ip_esp_hdr, seq_no); 143 break; 144 case IPPROTO_COMP: 145 if (!pskb_may_pull(skb, sizeof(struct ip_comp_hdr))) 146 return -EINVAL; 147 *spi = htonl(ntohs(*(__be16 *)(skb_transport_header(skb) + 2))); 148 *seq = 0; 149 return 0; 150 default: 151 return 1; 152 } 153 154 if (!pskb_may_pull(skb, hlen)) 155 return -EINVAL; 156 157 *spi = *(__be32 *)(skb_transport_header(skb) + offset); 158 *seq = *(__be32 *)(skb_transport_header(skb) + offset_seq); 159 return 0; 160 } 161 162 int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb) 163 { 164 struct xfrm_mode *inner_mode = x->inner_mode; 165 int err; 166 167 err = x->outer_mode->afinfo->extract_input(x, skb); 168 if (err) 169 return err; 170 171 if (x->sel.family == AF_UNSPEC) { 172 inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); 173 if (inner_mode == NULL) 174 return -EAFNOSUPPORT; 175 } 176 177 skb->protocol = inner_mode->afinfo->eth_proto; 178 return inner_mode->input2(x, skb); 179 } 180 EXPORT_SYMBOL(xfrm_prepare_input); 181 182 int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) 183 { 184 struct net *net = dev_net(skb->dev); 185 int err; 186 __be32 seq; 187 __be32 seq_hi; 188 struct xfrm_state *x = NULL; 189 xfrm_address_t *daddr; 190 struct xfrm_mode *inner_mode; 191 u32 mark = skb->mark; 192 unsigned int family; 193 int decaps = 0; 194 int async = 0; 195 196 /* A negative encap_type indicates async resumption. */ 197 if (encap_type < 0) { 198 async = 1; 199 x = xfrm_input_state(skb); 200 seq = XFRM_SKB_CB(skb)->seq.input.low; 201 family = x->outer_mode->afinfo->family; 202 goto resume; 203 } 204 205 daddr = (xfrm_address_t *)(skb_network_header(skb) + 206 XFRM_SPI_SKB_CB(skb)->daddroff); 207 family = XFRM_SPI_SKB_CB(skb)->family; 208 209 /* if tunnel is present override skb->mark value with tunnel i_key */ 210 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) { 211 switch (family) { 212 case AF_INET: 213 mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key); 214 break; 215 case AF_INET6: 216 mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key); 217 break; 218 } 219 } 220 221 /* Allocate new secpath or COW existing one. */ 222 if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) { 223 struct sec_path *sp; 224 225 sp = secpath_dup(skb->sp); 226 if (!sp) { 227 XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR); 228 goto drop; 229 } 230 if (skb->sp) 231 secpath_put(skb->sp); 232 skb->sp = sp; 233 } 234 235 seq = 0; 236 if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) { 237 XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR); 238 goto drop; 239 } 240 241 do { 242 if (skb->sp->len == XFRM_MAX_DEPTH) { 243 XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR); 244 goto drop; 245 } 246 247 x = xfrm_state_lookup(net, mark, daddr, spi, nexthdr, family); 248 if (x == NULL) { 249 XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES); 250 xfrm_audit_state_notfound(skb, family, spi, seq); 251 goto drop; 252 } 253 254 skb->sp->xvec[skb->sp->len++] = x; 255 256 spin_lock(&x->lock); 257 258 if (unlikely(x->km.state != XFRM_STATE_VALID)) { 259 if (x->km.state == XFRM_STATE_ACQ) 260 XFRM_INC_STATS(net, LINUX_MIB_XFRMACQUIREERROR); 261 else 262 XFRM_INC_STATS(net, 263 LINUX_MIB_XFRMINSTATEINVALID); 264 goto drop_unlock; 265 } 266 267 if ((x->encap ? x->encap->encap_type : 0) != encap_type) { 268 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMISMATCH); 269 goto drop_unlock; 270 } 271 272 if (x->repl->check(x, skb, seq)) { 273 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR); 274 goto drop_unlock; 275 } 276 277 if (xfrm_state_check_expire(x)) { 278 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEEXPIRED); 279 goto drop_unlock; 280 } 281 282 spin_unlock(&x->lock); 283 284 if (xfrm_tunnel_check(skb, x, family)) { 285 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR); 286 goto drop; 287 } 288 289 seq_hi = htonl(xfrm_replay_seqhi(x, seq)); 290 291 XFRM_SKB_CB(skb)->seq.input.low = seq; 292 XFRM_SKB_CB(skb)->seq.input.hi = seq_hi; 293 294 skb_dst_force(skb); 295 296 nexthdr = x->type->input(x, skb); 297 298 if (nexthdr == -EINPROGRESS) 299 return 0; 300 resume: 301 spin_lock(&x->lock); 302 if (nexthdr <= 0) { 303 if (nexthdr == -EBADMSG) { 304 xfrm_audit_state_icvfail(x, skb, 305 x->type->proto); 306 x->stats.integrity_failed++; 307 } 308 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR); 309 goto drop_unlock; 310 } 311 312 /* only the first xfrm gets the encap type */ 313 encap_type = 0; 314 315 if (async && x->repl->recheck(x, skb, seq)) { 316 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR); 317 goto drop_unlock; 318 } 319 320 x->repl->advance(x, seq); 321 322 x->curlft.bytes += skb->len; 323 x->curlft.packets++; 324 325 spin_unlock(&x->lock); 326 327 XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; 328 329 inner_mode = x->inner_mode; 330 331 if (x->sel.family == AF_UNSPEC) { 332 inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); 333 if (inner_mode == NULL) { 334 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR); 335 goto drop; 336 } 337 } 338 339 if (inner_mode->input(x, skb)) { 340 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR); 341 goto drop; 342 } 343 344 if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { 345 decaps = 1; 346 break; 347 } 348 349 /* 350 * We need the inner address. However, we only get here for 351 * transport mode so the outer address is identical. 352 */ 353 daddr = &x->id.daddr; 354 family = x->outer_mode->afinfo->family; 355 356 err = xfrm_parse_spi(skb, nexthdr, &spi, &seq); 357 if (err < 0) { 358 XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR); 359 goto drop; 360 } 361 } while (!err); 362 363 err = xfrm_rcv_cb(skb, family, x->type->proto, 0); 364 if (err) 365 goto drop; 366 367 nf_reset(skb); 368 369 if (decaps) { 370 skb_dst_drop(skb); 371 netif_rx(skb); 372 return 0; 373 } else { 374 return x->inner_mode->afinfo->transport_finish(skb, async); 375 } 376 377 drop_unlock: 378 spin_unlock(&x->lock); 379 drop: 380 xfrm_rcv_cb(skb, family, x && x->type ? x->type->proto : nexthdr, -1); 381 kfree_skb(skb); 382 return 0; 383 } 384 EXPORT_SYMBOL(xfrm_input); 385 386 int xfrm_input_resume(struct sk_buff *skb, int nexthdr) 387 { 388 return xfrm_input(skb, nexthdr, 0, -1); 389 } 390 EXPORT_SYMBOL(xfrm_input_resume); 391 392 void __init xfrm_input_init(void) 393 { 394 secpath_cachep = kmem_cache_create("secpath_cache", 395 sizeof(struct sec_path), 396 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, 397 NULL); 398 } 399