tail[clen - skb->len - 2] = (clen - skb->len) - 2;
        pskb_put(skb, trailer, clen - skb->len);
 
-       __skb_push(skb, skb->data - skb_network_header(skb));
+       __skb_push(skb, -skb_network_offset(skb));
        top_iph = ip_hdr(skb);
        esph = (struct ip_esp_hdr *)(skb_network_header(skb) +
                                     top_iph->ihl * 4);
 
                char hdrs[0];
        } *tmp_ext;
 
-       top_iph = (struct ipv6hdr *)skb->data;
+       top_iph = ipv6_hdr(skb);
        top_iph->payload_len = htons(skb->len - sizeof(*top_iph));
 
-       nexthdr = *skb_network_header(skb);
-       *skb_network_header(skb) = IPPROTO_AH;
+       nexthdr = *skb_mac_header(skb);
+       *skb_mac_header(skb) = IPPROTO_AH;
 
        /* When there are no extension headers, we only need to save the first
         * 8 bytes of the base IP header.
 
        tail[clen-skb->len - 2] = (clen - skb->len) - 2;
        pskb_put(skb, trailer, clen - skb->len);
 
-       top_iph = (struct ipv6hdr *)__skb_push(skb, hdr_len);
+       __skb_push(skb, -skb_network_offset(skb));
+       top_iph = ipv6_hdr(skb);
        esph = (struct ipv6_esp_hdr *)skb_transport_header(skb);
        top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph));
-       *(skb_tail_pointer(trailer) - 1) = *skb_network_header(skb);
-       *skb_network_header(skb) = IPPROTO_ESP;
+       *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb);
+       *skb_mac_header(skb) = IPPROTO_ESP;
 
        esph->spi = x->id.spi;
        esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
 
        pskb_trim(skb, hdr_len + dlen + sizeof(struct ip_comp_hdr));
 
        /* insert ipcomp header and replace datagram */
-       top_iph = (struct ipv6hdr *)skb->data;
+       top_iph = ipv6_hdr(skb);
 
        top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
 
        ipch = (struct ipv6_comp_hdr *)start;
-       ipch->nexthdr = *skb_network_header(skb);
+       ipch->nexthdr = *skb_mac_header(skb);
        ipch->flags = 0;
        ipch->cpi = htons((u16 )ntohl(x->id.spi));
-       *skb_network_header(skb) = IPPROTO_COMP;
+       *skb_mac_header(skb) = IPPROTO_COMP;
 
 out_ok:
        return 0;
 
        u8 nexthdr;
        int len;
 
-       iph = (struct ipv6hdr *)skb->data;
+       iph = ipv6_hdr(skb);
        iph->payload_len = htons(skb->len - sizeof(*iph));
 
-       nexthdr = *skb_network_header(skb);
-       *skb_network_header(skb) = IPPROTO_DSTOPTS;
+       nexthdr = *skb_mac_header(skb);
+       *skb_mac_header(skb) = IPPROTO_DSTOPTS;
 
        dstopt = (struct ipv6_destopt_hdr *)skb_transport_header(skb);
        dstopt->nexthdr = nexthdr;
        struct rt2_hdr *rt2;
        u8 nexthdr;
 
-       iph = (struct ipv6hdr *)skb->data;
+       iph = ipv6_hdr(skb);
        iph->payload_len = htons(skb->len - sizeof(*iph));
 
-       nexthdr = *skb_network_header(skb);
-       *skb_network_header(skb) = IPPROTO_ROUTING;
+       nexthdr = *skb_mac_header(skb);
+       *skb_mac_header(skb) = IPPROTO_ROUTING;
 
        rt2 = (struct rt2_hdr *)skb_transport_header(skb);
        rt2->rt_hdr.nexthdr = nexthdr;
 
  *     payload_len
  *
  * On exit, skb->h will be set to the start of the encapsulation header to be
- * filled in by x->type->output and skb->nh will be set to the nextheader field
- * of the extension header directly preceding the encapsulation header, or in
- * its absence, that of the top IP header.  The value of skb->data will always
- * point to the top IP header.
+ * filled in by x->type->output and the mac header will be set to the
+ * nextheader field of the extension header directly preceding the
+ * encapsulation header, or in its absence, that of the top IP header.
+ * The value of skb->data and the network header will always point to the
+ * top IP header.
  */
 static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 {
        iph = ipv6_hdr(skb);
 
        hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
-       skb_set_network_header(skb,
-                              (prevhdr - x->props.header_len) - skb->data);
-       skb_set_transport_header(skb, hdr_len);
        memmove(skb->data, iph, hdr_len);
 
+       skb_set_mac_header(skb, offsetof(struct ipv6hdr, nexthdr));
        skb_reset_network_header(skb);
+       skb_set_transport_header(skb, sizeof(struct ipv6hdr));
        top_iph = ipv6_hdr(skb);
-       skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
-       skb->network_header += offsetof(struct ipv6hdr, nexthdr);
 
        ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
        ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
 
  * space for the route optimization header.
  *
  * On exit, skb->h will be set to the start of the encapsulation header to be
- * filled in by x->type->output and skb->nh will be set to the nextheader field
- * of the extension header directly preceding the encapsulation header, or in
- * its absence, that of the top IP header.  The value of skb->data will always
- * point to the top IP header.
+ * filled in by x->type->output and the mac header will be set to the
+ * nextheader field of the extension header directly preceding the
+ * encapsulation header, or in its absence, that of the top IP header.
+ * The value of skb->data and the network header will always point to the
+ * top IP header.
  */
 static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
 {
        iph = ipv6_hdr(skb);
 
        hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
-       skb_set_network_header(skb,
-                              (prevhdr - x->props.header_len) - skb->data);
+       skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
+       skb_reset_network_header(skb);
        skb_set_transport_header(skb, hdr_len);
        memmove(skb->data, iph, hdr_len);
 
 
  * space for the encapsulation header.
  *
  * On exit, skb->h will be set to the start of the encapsulation header to be
- * filled in by x->type->output and skb->nh will be set to the nextheader field
- * of the extension header directly preceding the encapsulation header, or in
- * its absence, that of the top IP header.  The value of skb->data will always
- * point to the top IP header.
+ * filled in by x->type->output and the mac header will be set to the
+ * nextheader field of the extension header directly preceding the
+ * encapsulation header, or in its absence, that of the top IP header.
+ * The value of skb->data and the network header will always point to the
+ * top IP header.
  */
 static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb)
 {
        iph = ipv6_hdr(skb);
 
        hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
-       skb_set_network_header(skb,
-                              (prevhdr - x->props.header_len) - skb->data);
+       skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
+       skb_reset_network_header(skb);
        skb_set_transport_header(skb, hdr_len);
        memmove(skb->data, iph, hdr_len);
        return 0;
 
  *     payload_len
  *
  * On exit, skb->h will be set to the start of the encapsulation header to be
- * filled in by x->type->output and skb->nh will be set to the nextheader field
- * of the extension header directly preceding the encapsulation header, or in
- * its absence, that of the top IP header.  The value of skb->data will always
- * point to the top IP header.
+ * filled in by x->type->output and the mac header will be set to the
+ * nextheader field of the extension header directly preceding the
+ * encapsulation header, or in its absence, that of the top IP header.
+ * The value of skb->data and the network header will always point to the
+ * top IP header.
  */
 static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
 {
        skb_push(skb, x->props.header_len);
        iph = ipv6_hdr(skb);
 
+       skb_set_mac_header(skb, offsetof(struct ipv6hdr, nexthdr));
        skb_reset_network_header(skb);
+       skb_set_transport_header(skb, sizeof(struct ipv6hdr));
        top_iph = ipv6_hdr(skb);
-       skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
-       skb->network_header   += offsetof(struct ipv6hdr, nexthdr);
 
        top_iph->version = 6;
        if (xdst->route->ops->family == AF_INET6) {
 
 {
        struct ipv6hdr *top_iph;
 
-       top_iph = (struct ipv6hdr *)skb->data;
+       top_iph = ipv6_hdr(skb);
        top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
 
        return 0;
 
 
                spin_unlock_bh(&x->lock);
 
-               skb_reset_network_header(skb);
-
                if (!(skb->dst = dst_pop(dst))) {
                        err = -EHOSTUNREACH;
                        goto error_nolock;