initial commit with v2.6.9
[linux-2.6.9-moxart.git] / net / xfrm / xfrm_input.c
blobabe2e674cabd46aecc1bfce465dbe72e09b1f17d
1 /*
2 * xfrm_input.c
4 * Changes:
5 * YOSHIFUJI Hideaki @USAGI
6 * Split up af-specific portion
7 *
8 */
10 #include <linux/slab.h>
11 #include <net/ip.h>
12 #include <net/xfrm.h>
14 static kmem_cache_t *secpath_cachep;
16 void __secpath_destroy(struct sec_path *sp)
18 int i;
19 for (i = 0; i < sp->len; i++)
20 xfrm_state_put(sp->x[i].xvec);
21 kmem_cache_free(secpath_cachep, sp);
24 struct sec_path *secpath_dup(struct sec_path *src)
26 struct sec_path *sp;
28 sp = kmem_cache_alloc(secpath_cachep, SLAB_ATOMIC);
29 if (!sp)
30 return NULL;
32 sp->len = 0;
33 if (src) {
34 int i;
36 memcpy(sp, src, sizeof(*sp));
37 for (i = 0; i < sp->len; i++)
38 xfrm_state_hold(sp->x[i].xvec);
40 atomic_set(&sp->refcnt, 1);
41 return sp;
44 /* Fetch spi and seq from ipsec header */
46 int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
48 int offset, offset_seq;
50 switch (nexthdr) {
51 case IPPROTO_AH:
52 offset = offsetof(struct ip_auth_hdr, spi);
53 offset_seq = offsetof(struct ip_auth_hdr, seq_no);
54 break;
55 case IPPROTO_ESP:
56 offset = offsetof(struct ip_esp_hdr, spi);
57 offset_seq = offsetof(struct ip_esp_hdr, seq_no);
58 break;
59 case IPPROTO_COMP:
60 if (!pskb_may_pull(skb, sizeof(struct ip_comp_hdr)))
61 return -EINVAL;
62 *spi = ntohl(ntohs(*(u16*)(skb->h.raw + 2)));
63 *seq = 0;
64 return 0;
65 default:
66 return 1;
69 if (!pskb_may_pull(skb, 16))
70 return -EINVAL;
72 *spi = *(u32*)(skb->h.raw + offset);
73 *seq = *(u32*)(skb->h.raw + offset_seq);
74 return 0;
77 void __init xfrm_input_init(void)
79 secpath_cachep = kmem_cache_create("secpath_cache",
80 sizeof(struct sec_path),
81 0, SLAB_HWCACHE_ALIGN,
82 NULL, NULL);
83 if (!secpath_cachep)
84 panic("XFRM: failed to allocate secpath_cache\n");