[IPSEC]: Separate inner/outer mode processing on input
[powerpc.git] / net / xfrm / xfrm_input.c
index ee15bda..4c803f7 100644 (file)
@@ -49,39 +49,55 @@ EXPORT_SYMBOL(secpath_dup);
 int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
 {
        int offset, offset_seq;
+       int hlen;
 
        switch (nexthdr) {
        case IPPROTO_AH:
+               hlen = sizeof(struct ip_auth_hdr);
                offset = offsetof(struct ip_auth_hdr, spi);
                offset_seq = offsetof(struct ip_auth_hdr, seq_no);
                break;
        case IPPROTO_ESP:
+               hlen = sizeof(struct ip_esp_hdr);
                offset = offsetof(struct ip_esp_hdr, spi);
                offset_seq = offsetof(struct ip_esp_hdr, seq_no);
                break;
        case IPPROTO_COMP:
                if (!pskb_may_pull(skb, sizeof(struct ip_comp_hdr)))
                        return -EINVAL;
-               *spi = htonl(ntohs(*(__be16*)(skb->h.raw + 2)));
+               *spi = htonl(ntohs(*(__be16*)(skb_transport_header(skb) + 2)));
                *seq = 0;
                return 0;
        default:
                return 1;
        }
 
-       if (!pskb_may_pull(skb, 16))
+       if (!pskb_may_pull(skb, hlen))
                return -EINVAL;
 
-       *spi = *(__be32*)(skb->h.raw + offset);
-       *seq = *(__be32*)(skb->h.raw + offset_seq);
+       *spi = *(__be32*)(skb_transport_header(skb) + offset);
+       *seq = *(__be32*)(skb_transport_header(skb) + offset_seq);
        return 0;
 }
 EXPORT_SYMBOL(xfrm_parse_spi);
 
+int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+       int err;
+
+       err = x->outer_mode->afinfo->extract_input(x, skb);
+       if (err)
+               return err;
+
+       skb->protocol = x->inner_mode->afinfo->eth_proto;
+       return x->inner_mode->input2(x, skb);
+}
+EXPORT_SYMBOL(xfrm_prepare_input);
+
 void __init xfrm_input_init(void)
 {
        secpath_cachep = kmem_cache_create("secpath_cache",
                                           sizeof(struct sec_path),
                                           0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-                                          NULL, NULL);
+                                          NULL);
 }