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