- /* When there are no extension headers, we only need to save the first
- * 8 bytes of the base IP header.
- */
- memcpy(tmp_base, top_iph, sizeof(tmp_base));
-
- tmp_ext = NULL;
- extlen = (*pskb)->h.raw - (unsigned char *)(top_iph + 1);
- if (extlen) {
- extlen += sizeof(*tmp_ext);
- tmp_ext = kmalloc(extlen, GFP_ATOMIC);
- if (!tmp_ext) {
+ if (x->props.mode) {
+ err = xfrm6_tunnel_check_size(*pskb);
+ if (err)
+ goto error;
+
+ iph = (*pskb)->nh.ipv6h;
+ (*pskb)->nh.ipv6h = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len);
+ (*pskb)->nh.ipv6h->version = 6;
+ (*pskb)->nh.ipv6h->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
+ (*pskb)->nh.ipv6h->nexthdr = IPPROTO_AH;
+ ipv6_addr_copy(&(*pskb)->nh.ipv6h->saddr,
+ (struct in6_addr *) &x->props.saddr);
+ ipv6_addr_copy(&(*pskb)->nh.ipv6h->daddr,
+ (struct in6_addr *) &x->id.daddr);
+ ah = (struct ip_auth_hdr*)((*pskb)->nh.ipv6h+1);
+ ah->nexthdr = IPPROTO_IPV6;
+ } else {
+ hdr_len = (*pskb)->h.raw - (*pskb)->nh.raw;
+ iph = kmalloc(hdr_len, GFP_ATOMIC);
+ if (!iph) {