Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / net / ipv6 / esp6.c
index a278d5e..22f0460 100644 (file)
@@ -24,6 +24,7 @@
  *     This file is derived from net/ipv4/esp.c
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
@@ -141,18 +142,26 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
 
        int hdr_len = skb->h.raw - skb->nh.raw;
        int nfrags;
+       unsigned char *tmp_hdr = NULL;
        int ret = 0;
 
        if (!pskb_may_pull(skb, sizeof(struct ipv6_esp_hdr))) {
                ret = -EINVAL;
-               goto out;
+               goto out_nofree;
        }
 
        if (elen <= 0 || (elen & (blksize-1))) {
                ret = -EINVAL;
-               goto out;
+               goto out_nofree;
        }
 
+       tmp_hdr = kmalloc(hdr_len, GFP_ATOMIC);
+       if (!tmp_hdr) {
+               ret = -ENOMEM;
+               goto out_nofree;
+       }
+       memcpy(tmp_hdr, skb->nh.raw, hdr_len);
+
        /* If integrity check is required, do this. */
         if (esp->auth.icv_full_len) {
                u8 sum[esp->auth.icv_full_len];
@@ -213,12 +222,16 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
                /* ... check padding bits here. Silly. :-) */ 
 
                pskb_trim(skb, skb->len - alen - padlen - 2);
+               skb->h.raw = skb_pull(skb, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen);
+               skb->nh.raw += sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen;
+               memcpy(skb->nh.raw, tmp_hdr, hdr_len);
+               skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
                ret = nexthdr[1];
        }
 
-       skb->h.raw = __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen) - hdr_len;
-
 out:
+       kfree(tmp_hdr);
+out_nofree:
        return ret;
 }