static void
 isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp)
 {
-       u_char *p = skb->nh.raw; /* hopefully, this was set correctly */
+       /* hopefully, this was set correctly */
+       const u_char *p = skb_network_header(skb);
        unsigned short proto = ntohs(skb->protocol);
        int data_ofs;
        ip_ports *ipp;
 
        addinfo[0] = '\0';
        /* This check stolen from 2.1.72 dev_queue_xmit_nit() */
-       if (skb->nh.raw < skb->data || skb->nh.raw >= skb->tail) {
+       if (p < skb->data || p >= skb->tail) {
                /* fall back to old isdn_net_log_packet method() */
                char * buf = skb->data;
 
 
 
 static inline struct arp_pkt *arp_pkt(const struct sk_buff *skb)
 {
-       return (struct arp_pkt *)skb->nh.raw;
+       return (struct arp_pkt *)skb_network_header(skb);
 }
 
 /* Forward declaration */
 
 static void emulate_large_send_offload(struct sk_buff *skb)
 {
        struct iphdr *iph = skb->nh.iph;
-       struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4));
+       struct tcphdr *th = (struct tcphdr *)(skb_network_header(skb) +
+                                             (iph->ihl * 4));
        unsigned int doffset = (iph->ihl + th->doff) * 4;
        unsigned int mtu = skb_shinfo(skb)->gso_size + doffset;
        unsigned int offset = 0;
                skb_set_mac_header(nskb, -ETH_HLEN);
                skb_reset_network_header(nskb);
                iph = nskb->nh.iph;
-               memcpy(nskb->data, skb->nh.raw, doffset);
+               memcpy(nskb->data, skb_network_header(skb), doffset);
                if (skb_copy_bits(skb,
                                  doffset + offset,
                                  nskb->data + doffset,
                memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
                nskb->pkt_type = skb->pkt_type;
 
-               th = (struct tcphdr*)(nskb->nh.raw + iph->ihl*4);
+               th = (struct tcphdr *)(skb_network_header(nskb) + iph->ihl * 4);
                iph->tot_len = htons(frag_size + doffset);
                iph->id = htons(id);
                iph->check = 0;
 
        dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_SS | XCT_MACTX_CRC_PAD;
 
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               const unsigned char *nh = skb_network_header(skb);
+
                switch (skb->nh.iph->protocol) {
                case IPPROTO_TCP:
                        dflags |= XCT_MACTX_CSUM_TCP;
                        dflags |= XCT_MACTX_IPH((skb->h.raw - skb->nh.raw) >> 2);
-                       dflags |= XCT_MACTX_IPO(skb->nh.raw - skb->data);
+                       dflags |= XCT_MACTX_IPO(nh - skb->data);
                        break;
                case IPPROTO_UDP:
                        dflags |= XCT_MACTX_CSUM_UDP;
                        dflags |= XCT_MACTX_IPH((skb->h.raw - skb->nh.raw) >> 2);
-                       dflags |= XCT_MACTX_IPO(skb->nh.raw - skb->data);
+                       dflags |= XCT_MACTX_IPO(nh - skb->data);
                        break;
                }
        }
 
        }
        /* try something else */
        if (skb->protocol == ETH_P_IPV6)
-               return (skb->nh.raw[24] == 0xff) ? RTN_MULTICAST : 0;
+               return (skb_network_header(skb)[24] == 0xff) ?
+                               RTN_MULTICAST : 0;
        else if (skb->protocol == ETH_P_IP)
-               return ((skb->nh.raw[16] & 0xf0) == 0xe0) ? RTN_MULTICAST : 0;
+               return ((skb_network_header(skb)[16] & 0xf0) == 0xe0) ?
+                               RTN_MULTICAST : 0;
        /* ... */
        if (!memcmp(skb->data, skb->dev->broadcast, 6))
                return RTN_BROADCAST;
 
 
 static inline struct pppoe_hdr *pppoe_hdr(const struct sk_buff *skb)
 {
-       return (struct pppoe_hdr *)skb->nh.raw;
+       return (struct pppoe_hdr *)skb_network_header(skb);
 }
 
 struct pppoe_opt {
 
        skb->tail += len;
 }
 
+static inline unsigned char *skb_network_header(const struct sk_buff *skb)
+{
+       return skb->nh.raw;
+}
+
 static inline void skb_reset_network_header(struct sk_buff *skb)
 {
        skb->nh.raw = skb->data;
 
  */
 
 #define CIPSO_V4_OPTEXIST(x) (IPCB(x)->opt.cipso != 0)
-#define CIPSO_V4_OPTPTR(x) ((x)->nh.raw + IPCB(x)->opt.cipso)
+#define CIPSO_V4_OPTPTR(x) (skb_network_header(x) + IPCB(x)->opt.cipso)
 
 /*
  * DOI List Functions
 
 {
        switch (skb->protocol) {
        case __constant_htons(ETH_P_IP):
-               if (skb->nh.raw + sizeof(struct iphdr) <= skb->tail)
+               if (skb_network_header(skb) + sizeof(struct iphdr) <=
+                   skb->tail)
                        return IP_ECN_set_ce(skb->nh.iph);
                break;
 
        case __constant_htons(ETH_P_IPV6):
-               if (skb->nh.raw + sizeof(struct ipv6hdr) <= skb->tail)
+               if (skb_network_header(skb) + sizeof(struct ipv6hdr) <=
+                   skb->tail)
                        return IP6_ECN_set_ce(skb->nh.ipv6h);
                break;
        }
 
 
 static inline struct llc_pdu_sn *llc_pdu_sn_hdr(struct sk_buff *skb)
 {
-       return (struct llc_pdu_sn *)skb->nh.raw;
+       return (struct llc_pdu_sn *)skb_network_header(skb);
 }
 
 /* Un-numbered PDU format (3 bytes in length) */
 
 static inline struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb)
 {
-       return (struct llc_pdu_un *)skb->nh.raw;
+       return (struct llc_pdu_un *)skb_network_header(skb);
 }
 
 /**
 
                case TCF_LAYER_LINK:
                        return skb->data;
                case TCF_LAYER_NETWORK:
-                       return skb->nh.raw;
+                       return skb_network_header(skb);
                case TCF_LAYER_TRANSPORT:
                        return skb->h.raw;
        }
 
 {
        unsigned char *raw = (u8 *) (skb->nh.ipv6h + 1);
        u32 pkt_len;
-       int off = raw - skb->nh.raw;
+       const unsigned char *nh = skb_network_header(skb);
+       int off = raw - nh;
        int len = (raw[1] + 1) << 3;
 
        if ((raw + len) - skb->data > skb_headlen(skb))
        len -= 2;
 
        while (len > 0) {
-               int optlen = skb->nh.raw[off + 1] + 2;
+               int optlen = nh[off + 1] + 2;
 
-               switch (skb->nh.raw[off]) {
+               switch (nh[off]) {
                case IPV6_TLV_PAD0:
                        optlen = 1;
                        break;
                        break;
 
                case IPV6_TLV_JUMBO:
-                       if (skb->nh.raw[off + 1] != 4 || (off & 3) != 2)
+                       if (nh[off + 1] != 4 || (off & 3) != 2)
                                goto bad;
-                       pkt_len = ntohl(*(__be32 *) (skb->nh.raw + off + 2));
+                       pkt_len = ntohl(*(__be32 *) (nh + off + 2));
                        if (pkt_len <= IPV6_MAXPLEN ||
                            skb->nh.ipv6h->payload_len)
                                goto bad;
                        if (pskb_trim_rcsum(skb,
                                            pkt_len + sizeof(struct ipv6hdr)))
                                goto bad;
+                       nh = skb_network_header(skb);
                        break;
                default:
                        if (optlen > len)
 
                         */
                        skb_reset_mac_header(skb2);
 
-                       if (skb2->nh.raw < skb2->data ||
-                           skb2->nh.raw > skb2->tail) {
+                       if (skb_network_header(skb2) < skb2->data ||
+                           skb_network_header(skb2) > skb2->tail) {
                                if (net_ratelimit())
                                        printk(KERN_CRIT "protocol %04x is "
                                               "buggy, dev %s\n",
        BUG_ON(skb_shinfo(skb)->frag_list);
 
        skb_reset_mac_header(skb);
-       skb->mac_len = skb->nh.raw - skb->data;
+       skb->mac_len = skb->nh.raw - skb->mac.raw;
        __skb_pull(skb, skb->mac_len);
 
        if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
                                segs = ERR_PTR(err);
                                if (err || skb_gso_ok(skb, features))
                                        break;
-                               __skb_push(skb, skb->data - skb->nh.raw);
+                               __skb_push(skb, (skb->data -
+                                                skb_network_header(skb)));
                        }
                        segs = ptype->gso_segment(skb, features);
                        break;
 
        u8 *ptr = NULL;
 
        if (k >= SKF_NET_OFF)
-               ptr = skb->nh.raw + k - SKF_NET_OFF;
+               ptr = skb_network_header(skb) + k - SKF_NET_OFF;
        else if (k >= SKF_LL_OFF)
                ptr = skb_mac_header(skb) + k - SKF_LL_OFF;
 
 
 
                        if (rxopt->srcrt)
                                opt = ipv6_invert_rthdr(sk,
-                                       (struct ipv6_rt_hdr *)(pktopts->nh.raw +
-                                                              rxopt->srcrt));
+                         (struct ipv6_rt_hdr *)(skb_network_header(pktopts) +
+                                                rxopt->srcrt));
                }
 
                if (opt != NULL && opt->srcrt != NULL) {
 
                if (rxopt->srcrt)
                        opt = ipv6_invert_rthdr(sk,
-                               (struct ipv6_rt_hdr *)(ireq6->pktopts->nh.raw +
-                                                      rxopt->srcrt));
+                  (struct ipv6_rt_hdr *)(skb_network_header(ireq6->pktopts) +
+                                         rxopt->srcrt));
        }
 
        if (dst == NULL) {
 
        __le16 tmp;
 
        /* Add back headers */
-       skb_push(skb, skb->data - skb->nh.raw);
+       skb_push(skb, skb->data - skb_network_header(skb));
 
        if ((skb = skb_unshare(skb, GFP_ATOMIC)) == NULL)
                return NET_RX_DROP;
        unsigned char tmp[ETH_ALEN];
 
        /* Add back all headers */
-       skb_push(skb, skb->data - skb->nh.raw);
+       skb_push(skb, skb->data - skb_network_header(skb));
 
        if ((skb = skb_unshare(skb, GFP_ATOMIC)) == NULL)
                return NET_RX_DROP;
 
                iph->id = htons(id++);
                iph->tot_len = htons(skb->len - skb->mac_len);
                iph->check = 0;
-               iph->check = ip_fast_csum(skb->nh.raw, iph->ihl);
+               iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
        } while ((skb = skb->next));
 
 out:
 
        ah = (struct ip_auth_hdr*)skb->data;
        iph = skb->nh.iph;
 
-       ihl = skb->data - skb->nh.raw;
+       ihl = skb->data - skb_network_header(skb);
        memcpy(work_buf, iph, ihl);
 
        iph->ttl = 0;
                }
        }
        ((struct iphdr*)work_buf)->protocol = ah->nexthdr;
-       skb->h.raw = memcpy(skb->nh.raw += ah_hlen, work_buf, ihl);
+       skb->nh.raw += ah_hlen;
+       skb->h.raw = memcpy(skb_network_header(skb), work_buf, ihl);
        __skb_pull(skb, ah_hlen + ihl);
 
        return 0;
 
        *(u8*)(trailer->tail + clen-skb->len - 2) = (clen - skb->len)-2;
        pskb_put(skb, trailer, clen - skb->len);
 
-       __skb_push(skb, skb->data - skb->nh.raw);
+       __skb_push(skb, skb->data - skb_network_header(skb));
        top_iph = skb->nh.iph;
-       esph = (struct ip_esp_hdr *)(skb->nh.raw + top_iph->ihl*4);
+       esph = (struct ip_esp_hdr *)(skb_network_header(skb) +
+                                    top_iph->ihl * 4);
        top_iph->tot_len = htons(skb->len + alen);
        *(u8*)(trailer->tail - 1) = top_iph->protocol;
 
 
        if (x->encap) {
                struct xfrm_encap_tmpl *encap = x->encap;
-               struct udphdr *uh = (void *)(skb->nh.raw + ihl);
+               struct udphdr *uh = (void *)(skb_network_header(skb) + ihl);
 
                /*
                 * 1) if the NAT-T peer's IP or port changed then
 
                        u8 _inner_type, *itp;
 
                        itp = skb_header_pointer(skb_in,
-                                                skb_in->nh.raw +
+                                                skb_network_header(skb_in) +
                                                 (iph->ihl << 2) +
                                                 offsetof(struct icmphdr,
                                                          type) -
        icmp_param.data.icmph.un.gateway = info;
        icmp_param.data.icmph.checksum   = 0;
        icmp_param.skb    = skb_in;
-       icmp_param.offset = skb_in->nh.raw - skb_in->data;
+       icmp_param.offset = skb_network_offset(skb_in);
        icmp_out_count(icmp_param.data.icmph.type);
        inet_sk(icmp_socket->sk)->tos = tos;
        ipc.addr = iph->saddr;
 
        }
 
        skb_shinfo(head)->frag_list = head->next;
-       skb_push(head, head->data - head->nh.raw);
+       skb_push(head, head->data - skb_network_header(head));
        atomic_sub(head->truesize, &ip_frag_mem);
 
        for (fp=head->next; fp; fp = fp->next) {
 
 void ip_options_build(struct sk_buff * skb, struct ip_options * opt,
                            __be32 daddr, struct rtable *rt, int is_frag)
 {
-       unsigned char * iph = skb->nh.raw;
+       unsigned char *iph = skb_network_header(skb);
 
        memcpy(&(IPCB(skb)->opt), opt, sizeof(struct ip_options));
        memcpy(iph+sizeof(struct iphdr), opt->__data, opt->optlen);
                return 0;
        }
 
-       sptr = skb->nh.raw;
+       sptr = skb_network_header(skb);
        dptr = dopt->__data;
 
        if (skb->dst)
 
 void ip_options_fragment(struct sk_buff * skb)
 {
-       unsigned char * optptr = skb->nh.raw + sizeof(struct iphdr);
+       unsigned char *optptr = skb_network_header(skb) + sizeof(struct iphdr);
        struct ip_options * opt = &(IPCB(skb)->opt);
        int  l = opt->optlen;
        int  optlen;
 
        if (!opt) {
                opt = &(IPCB(skb)->opt);
-               iph = skb->nh.raw;
+               iph = skb_network_header(skb);
                opt->optlen = ((struct iphdr *)iph)->ihl*4 - sizeof(struct iphdr);
                optptr = iph + sizeof(struct iphdr);
                opt->is_data = 0;
        struct   ip_options * opt       = &(IPCB(skb)->opt);
        unsigned char * optptr;
        struct rtable *rt = (struct rtable*)skb->dst;
-       unsigned char *raw = skb->nh.raw;
+       unsigned char *raw = skb_network_header(skb);
 
        if (opt->rr_needaddr) {
                optptr = (unsigned char *)raw + opt->rr;
        int srrspace, srrptr;
        __be32 nexthop;
        struct iphdr *iph = skb->nh.iph;
-       unsigned char * optptr = skb->nh.raw + opt->srr;
+       unsigned char *optptr = skb_network_header(skb) + opt->srr;
        struct rtable *rt = (struct rtable*)skb->dst;
        struct rtable *rt2;
        int err;
 
                                frag->h.raw = frag->data;
                                __skb_push(frag, hlen);
                                skb_reset_network_header(frag);
-                               memcpy(frag->nh.raw, iph, hlen);
+                               memcpy(skb_network_header(frag), iph, hlen);
                                iph = frag->nh.iph;
                                iph->tot_len = htons(frag->len);
                                ip_copy_metadata(frag, skb);
                 *      Copy the packet header into the new buffer.
                 */
 
-               memcpy(skb2->nh.raw, skb->data, hlen);
+               memcpy(skb_network_header(skb2), skb->data, hlen);
 
                /*
                 *      Copy a block of the IP datagram.
        tail_skb = &(skb_shinfo(skb)->frag_list);
 
        /* move skb->data to ip header from ext header */
-       if (skb->data < skb->nh.raw)
+       if (skb->data < skb_network_header(skb))
                __skb_pull(skb, skb_network_offset(skb));
        while ((tmp_skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) {
                __skb_pull(tmp_skb, skb->h.raw - skb->nh.raw);
 
        serr->ee.ee_pad = 0;
        serr->ee.ee_info = info;
        serr->ee.ee_data = 0;
-       serr->addr_offset = (u8*)&(((struct iphdr*)(skb->h.icmph+1))->daddr) - skb->nh.raw;
+       serr->addr_offset = (u8 *)&(((struct iphdr *)(skb->h.icmph + 1))->daddr) -
+                                  skb_network_header(skb);
        serr->port = port;
 
        skb->h.raw = payload;
        serr->ee.ee_pad = 0;
        serr->ee.ee_info = info;
        serr->ee.ee_data = 0;
-       serr->addr_offset = (u8*)&iph->daddr - skb->nh.raw;
+       serr->addr_offset = (u8 *)&iph->daddr - skb_network_header(skb);
        serr->port = port;
 
        skb->h.raw = skb->tail;
        sin = (struct sockaddr_in *)msg->msg_name;
        if (sin) {
                sin->sin_family = AF_INET;
-               sin->sin_addr.s_addr = *(__be32*)(skb->nh.raw + serr->addr_offset);
+               sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) +
+                                                  serr->addr_offset);
                sin->sin_port = serr->port;
                memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
        }
 
                 */
                msg = (struct igmpmsg*)skb_push(skb, sizeof(struct iphdr));
                skb->nh.raw = skb->h.raw = (u8*)msg;
-               memcpy(msg, pkt->nh.raw, sizeof(struct iphdr));
+               memcpy(msg, skb_network_header(pkt), sizeof(struct iphdr));
                msg->im_msgtype = IGMPMSG_WHOLEPKT;
                msg->im_mbz = 0;
                msg->im_vif = reg_vif_num;
 
        if (!ip_vs_make_skb_writable(pskb, tcp_offset + sizeof(*th)))
                return 0;
 
-       th = (struct tcphdr *)((*pskb)->nh.raw + tcp_offset);
+       th = (struct tcphdr *)(skb_network_header(*pskb) + tcp_offset);
 
        /*
         *      Remember seq number in case this pkt gets resized
        if (!ip_vs_make_skb_writable(pskb, tcp_offset + sizeof(*th)))
                return 0;
 
-       th = (struct tcphdr *)((*pskb)->nh.raw + tcp_offset);
+       th = (struct tcphdr *)(skb_network_header(*pskb) + tcp_offset);
 
        /*
         *      Remember seq number in case this pkt gets resized
 
 {
        struct iphdr *iph        = skb->nh.iph;
        unsigned int icmp_offset = iph->ihl*4;
-       struct icmphdr *icmph    = (struct icmphdr *)(skb->nh.raw + icmp_offset);
+       struct icmphdr *icmph    = (struct icmphdr *)(skb_network_header(skb) +
+                                                     icmp_offset);
        struct iphdr *ciph       = (struct iphdr *)(icmph + 1);
 
        if (inout) {
 
        }
 
        arp = (*pskb)->nh.arph;
-       arpptr = (*pskb)->nh.raw + sizeof(*arp);
+       arpptr = skb_network_header(*pskb) + sizeof(*arp);
        pln = arp->ar_pln;
        hln = arp->ar_hln;
        /* We assume that pln and hln were checked in the match */
 
                return -NF_DROP;
        }
 
-       *dataoff = (*pskb)->nh.raw - (*pskb)->data + (*pskb)->nh.iph->ihl*4;
+       *dataoff = skb_network_offset(*pskb) + (*pskb)->nh.iph->ihl * 4;
        *protonum = (*pskb)->nh.iph->protocol;
 
        return NF_ACCEPT;
        if (!help || !help->helper)
                return NF_ACCEPT;
 
-       return help->helper->help(pskb,
-                              (*pskb)->nh.raw - (*pskb)->data
-                                              + (*pskb)->nh.iph->ihl*4,
-                              ct, ctinfo);
+       return help->helper->help(pskb, (skb_network_offset(*pskb) +
+                                        (*pskb)->nh.iph->ihl * 4),
+                                 ct, ctinfo);
 }
 
 static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
 
        }
        nf_reset(skb);
 
-       skb_push(skb, skb->data - skb->nh.raw);
+       skb_push(skb, skb->data - skb_network_header(skb));
 
        raw_rcv_skb(sk, skb);
        return 0;
 
                        return;
 
                skb_set_mac_header(nskb, skb_mac_header(skb) - skb->head);
-               nskb->nh.raw = nskb->data + (skb->nh.raw - skb->head);
+               nskb->nh.raw = nskb->data + (skb_network_header(skb) - skb->head);
                nskb->h.raw = nskb->data + (skb->h.raw - skb->head);
 
                skb_reserve(nskb, header);
 
                return 0;
        } else {
 #ifdef CONFIG_NETFILTER
-               __skb_push(skb, skb->data - skb->nh.raw);
+               __skb_push(skb, skb->data - skb_network_header(skb));
                skb->nh.iph->tot_len = htons(skb->len);
                ip_send_check(skb->nh.iph);
 
 
        }
 
        skb->nh.raw = skb->data + (phlen - sizeof(*iph));
-       memmove(skb->nh.raw, iph, sizeof(*iph));
+       memmove(skb_network_header(skb), iph, sizeof(*iph));
        skb->h.raw = skb->data + (phlen + optlen);
        skb->data = skb->h.raw;
 
        else
                iph->protocol = protocol;
        iph->check = 0;
-       iph->check = ip_fast_csum(skb->nh.raw, iph->ihl);
+       iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
        err = 0;
 out:
        return err;
 
 
        skb_push(skb, x->props.header_len);
        skb_reset_network_header(skb);
-       memmove(skb->nh.raw, iph, ihl);
+       memmove(skb_network_header(skb), iph, ihl);
        return 0;
 }
 
        int ihl = skb->data - skb->h.raw;
 
        if (skb->h.raw != skb->nh.raw) {
-               memmove(skb->h.raw, skb->nh.raw, ihl);
+               memmove(skb->h.raw, skb_network_header(skb), ihl);
                skb->nh.raw = skb->h.raw;
        }
        skb->nh.iph->tot_len = htons(skb->len + ihl);
 
 _decode_session4(struct sk_buff *skb, struct flowi *fl)
 {
        struct iphdr *iph = skb->nh.iph;
-       u8 *xprth = skb->nh.raw + iph->ihl*4;
+       u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
 
        memset(fl, 0, sizeof(struct flowi));
        if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) {
 
        if (np->rxopt.all) {
                if ((opt->hop && (np->rxopt.bits.hopopts ||
                                  np->rxopt.bits.ohopopts)) ||
-                   ((IPV6_FLOWINFO_MASK & *(__be32*)skb->nh.raw) &&
+                   ((IPV6_FLOWINFO_MASK &
+                     *(__be32 *)skb_network_header(skb)) &&
                     np->rxopt.bits.rxflow) ||
                    (opt->srcrt && (np->rxopt.bits.srcrt ||
                     np->rxopt.bits.osrcrt)) ||
 
        top_iph = (struct ipv6hdr *)skb->data;
        top_iph->payload_len = htons(skb->len - sizeof(*top_iph));
 
-       nexthdr = *skb->nh.raw;
-       *skb->nh.raw = IPPROTO_AH;
+       nexthdr = *skb_network_header(skb);
+       *skb_network_header(skb) = IPPROTO_AH;
 
        /* When there are no extension headers, we only need to save the first
         * 8 bytes of the base IP header.
            pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
                goto out;
 
-       hdr_len = skb->data - skb->nh.raw;
+       hdr_len = skb->data - skb_network_header(skb);
        ah = (struct ipv6_auth_hdr*)skb->data;
        ahp = x->data;
        nexthdr = ah->nexthdr;
        if (!pskb_may_pull(skb, ah_hlen))
                goto out;
 
-       tmp_hdr = kmemdup(skb->nh.raw, hdr_len, GFP_ATOMIC);
+       tmp_hdr = kmemdup(skb_network_header(skb), hdr_len, GFP_ATOMIC);
        if (!tmp_hdr)
                goto out;
        if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len, XFRM_POLICY_IN))
                }
        }
 
-       skb->h.raw = memcpy(skb->nh.raw += ah_hlen, tmp_hdr, hdr_len);
+       skb->nh.raw += ah_hlen;
+       memcpy(skb_network_header(skb), tmp_hdr, hdr_len);
+       skb->h.raw = skb->nh.raw;
        __skb_pull(skb, ah_hlen + hdr_len);
 
        kfree(tmp_hdr);
 
        serr->ee.ee_pad = 0;
        serr->ee.ee_info = info;
        serr->ee.ee_data = 0;
-       serr->addr_offset = (u8*)&(((struct ipv6hdr*)(icmph+1))->daddr) - skb->nh.raw;
+       serr->addr_offset = (u8 *)&(((struct ipv6hdr *)(icmph + 1))->daddr) -
+                                 skb_network_header(skb);
        serr->port = port;
 
        skb->h.raw = payload;
        serr->ee.ee_pad = 0;
        serr->ee.ee_info = info;
        serr->ee.ee_data = 0;
-       serr->addr_offset = (u8*)&iph->daddr - skb->nh.raw;
+       serr->addr_offset = (u8 *)&iph->daddr - skb_network_header(skb);
        serr->port = fl->fl_ip_dport;
 
        skb->h.raw = skb->tail;
 
        sin = (struct sockaddr_in6 *)msg->msg_name;
        if (sin) {
+               const unsigned char *nh = skb_network_header(skb);
                sin->sin6_family = AF_INET6;
                sin->sin6_flowinfo = 0;
                sin->sin6_port = serr->port;
                sin->sin6_scope_id = 0;
                if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
                        ipv6_addr_copy(&sin->sin6_addr,
-                         (struct in6_addr *)(skb->nh.raw + serr->addr_offset));
+                                 (struct in6_addr *)(nh + serr->addr_offset));
                        if (np->sndflow)
-                               sin->sin6_flowinfo = *(__be32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK;
+                               sin->sin6_flowinfo =
+                                       (*(__be32 *)(nh + serr->addr_offset - 24) &
+                                        IPV6_FLOWINFO_MASK);
                        if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
                                sin->sin6_scope_id = IP6CB(skb)->iif;
                } else {
                        ipv6_addr_set(&sin->sin6_addr, 0, 0,
                                      htonl(0xffff),
-                                     *(__be32*)(skb->nh.raw + serr->addr_offset));
+                                     *(__be32 *)(nh + serr->addr_offset));
                }
        }
 
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct inet6_skb_parm *opt = IP6CB(skb);
+       unsigned char *nh = skb_network_header(skb);
 
        if (np->rxopt.bits.rxinfo) {
                struct in6_pktinfo src_info;
                put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
        }
 
-       if (np->rxopt.bits.rxflow && (*(__be32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) {
-               __be32 flowinfo = *(__be32*)skb->nh.raw & IPV6_FLOWINFO_MASK;
+       if (np->rxopt.bits.rxflow && (*(__be32 *)nh & IPV6_FLOWINFO_MASK)) {
+               __be32 flowinfo = *(__be32 *)nh & IPV6_FLOWINFO_MASK;
                put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
        }
 
        /* HbH is allowed only once */
        if (np->rxopt.bits.hopopts && opt->hop) {
-               u8 *ptr = skb->nh.raw + opt->hop;
+               u8 *ptr = nh + opt->hop;
                put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
        }
 
 
                while (off <= opt->lastopt) {
                        unsigned len;
-                       u8 *ptr = skb->nh.raw + off;
+                       u8 *ptr = nh + off;
 
                        switch(nexthdr) {
                        case IPPROTO_DSTOPTS:
                put_cmsg(msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
        }
        if (np->rxopt.bits.ohopopts && opt->hop) {
-               u8 *ptr = skb->nh.raw + opt->hop;
+               u8 *ptr = nh + opt->hop;
                put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, (ptr[1]+1)<<3, ptr);
        }
        if (np->rxopt.bits.odstopts && opt->dst0) {
-               u8 *ptr = skb->nh.raw + opt->dst0;
+               u8 *ptr = nh + opt->dst0;
                put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
        }
        if (np->rxopt.bits.osrcrt && opt->srcrt) {
-               struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(skb->nh.raw + opt->srcrt);
+               struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(nh + opt->srcrt);
                put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
        }
        if (np->rxopt.bits.odstopts && opt->dst1) {
-               u8 *ptr = skb->nh.raw + opt->dst1;
+               u8 *ptr = nh + opt->dst1;
                put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
        }
        return 0;
 
        top_iph = (struct ipv6hdr *)__skb_push(skb, hdr_len);
        esph = (struct ipv6_esp_hdr *)skb->h.raw;
        top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph));
-       *(u8*)(trailer->tail - 1) = *skb->nh.raw;
-       *skb->nh.raw = IPPROTO_ESP;
+       *(u8 *)(trailer->tail - 1) = *skb_network_header(skb);
+       *skb_network_header(skb) = IPPROTO_ESP;
 
        esph->spi = x->id.spi;
        esph->seq_no = htonl(++x->replay.oseq);
 
 
 int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
 {
-       int packet_len = skb->tail - skb->nh.raw;
+       const unsigned char *nh = skb_network_header(skb);
+       int packet_len = skb->tail - nh;
        struct ipv6_opt_hdr *hdr;
        int len;
 
        if (offset + 2 > packet_len)
                goto bad;
-       hdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+       hdr = (struct ipv6_opt_hdr *)(nh + offset);
        len = ((hdr->hdrlen + 1) << 3);
 
        if (offset + len > packet_len)
        len -= 2;
 
        while (len > 0) {
-               int opttype = skb->nh.raw[offset];
+               int opttype = nh[offset];
                int optlen;
 
                if (opttype == type)
                        optlen = 1;
                        break;
                default:
-                       optlen = skb->nh.raw[offset + 1] + 2;
+                       optlen = nh[offset + 1] + 2;
                        if (optlen > len)
                                goto bad;
                        break;
 {
        struct sk_buff *skb = *skbp;
 
-       switch ((skb->nh.raw[optoff] & 0xC0) >> 6) {
+       switch ((skb_network_header(skb)[optoff] & 0xC0) >> 6) {
        case 0: /* ignore */
                return 1;
 
 {
        struct sk_buff *skb = *skbp;
        struct tlvtype_proc *curr;
+       const unsigned char *nh = skb_network_header(skb);
        int off = skb->h.raw - skb->nh.raw;
        int len = ((skb->h.raw[1]+1)<<3);
 
        len -= 2;
 
        while (len > 0) {
-               int optlen = skb->nh.raw[off+1]+2;
+               int optlen = nh[off + 1] + 2;
 
-               switch (skb->nh.raw[off]) {
+               switch (nh[off]) {
                case IPV6_TLV_PAD0:
                        optlen = 1;
                        break;
                        if (optlen > len)
                                goto bad;
                        for (curr=procs; curr->type >= 0; curr++) {
-                               if (curr->type == skb->nh.raw[off]) {
+                               if (curr->type == nh[off]) {
                                        /* type specific length/alignment
                                           checks will be performed in the
                                           func(). */
        opt->dsthao = opt->dst1;
        opt->dst1 = 0;
 
-       hao = (struct ipv6_destopt_hao *)(skb->nh.raw + optoff);
+       hao = (struct ipv6_destopt_hao *)(skb_network_header(skb) + optoff);
 
        if (hao->length != 16) {
                LIMIT_NETDEBUG(
 
                /* update all variable using below by copied skbuff */
                *skbp = skb = skb2;
-               hao = (struct ipv6_destopt_hao *)(skb2->nh.raw + optoff);
-               ipv6h = (struct ipv6hdr *)skb2->nh.raw;
+               hao = (struct ipv6_destopt_hao *)(skb_network_header(skb2) +
+                                                 optoff);
+               ipv6h = skb2->nh.ipv6h;
        }
 
        if (skb->ip_summed == CHECKSUM_COMPLETE)
        default:
                IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
                                 IPSTATS_MIB_INHDRERRORS);
-               icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
+               icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
+                                 (&hdr->type) - skb_network_header(skb));
                return -1;
        }
 
                skb->h.raw += (hdr->hdrlen + 1) << 3;
                opt->dst0 = opt->dst1;
                opt->dst1 = 0;
-               opt->nhoff = (&hdr->nexthdr) - skb->nh.raw;
+               opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
                return 1;
        }
 
                if (hdr->hdrlen & 0x01) {
                        IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
                                         IPSTATS_MIB_INHDRERRORS);
-                       icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
+                       icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
+                                         ((&hdr->hdrlen) -
+                                          skb_network_header(skb)));
                        return -1;
                }
                break;
        if (hdr->segments_left > n) {
                IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
                                 IPSTATS_MIB_INHDRERRORS);
-               icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
+               icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
+                                 ((&hdr->segments_left) -
+                                  skb_network_header(skb)));
                return -1;
        }
 
        dst_release(xchg(&skb->dst, NULL));
        ip6_route_input(skb);
        if (skb->dst->error) {
-               skb_push(skb, skb->data - skb->nh.raw);
+               skb_push(skb, skb->data - skb_network_header(skb));
                dst_input(skb);
                return -1;
        }
                goto looped_back;
        }
 
-       skb_push(skb, skb->data - skb->nh.raw);
+       skb_push(skb, skb->data - skb_network_header(skb));
        dst_input(skb);
        return -1;
 }
 static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
 {
        struct sk_buff *skb = *skbp;
+       const unsigned char *nh = skb_network_header(skb);
 
-       if (skb->nh.raw[optoff+1] == 2) {
+       if (nh[optoff + 1] == 2) {
                IP6CB(skb)->ra = optoff;
                return 1;
        }
        LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
-                      skb->nh.raw[optoff+1]);
+                      nh[optoff + 1]);
        kfree_skb(skb);
        return 0;
 }
 static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
 {
        struct sk_buff *skb = *skbp;
+       const unsigned char *nh = skb_network_header(skb);
        u32 pkt_len;
 
-       if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
+       if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
                LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
-                              skb->nh.raw[optoff+1]);
+                              nh[optoff+1]);
                IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
                                 IPSTATS_MIB_INHDRERRORS);
                goto drop;
        }
 
-       pkt_len = ntohl(*(__be32*)(skb->nh.raw+optoff+2));
+       pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
        if (pkt_len <= IPV6_MAXPLEN) {
                IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
                icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
        struct inet6_skb_parm *opt = IP6CB(skb);
 
        /*
-        * skb->nh.raw is equal to skb->data, and
+        * skb_network_header(skb) is equal to skb->data, and
         * skb->h.raw - skb->nh.raw is always equal to
         * sizeof(struct ipv6hdr) by definition of
         * hop-by-hop options.
 
        if (opt->dsthao) {
                off = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
                if (likely(off >= 0)) {
-                       hao = (struct ipv6_destopt_hao *)(skb->nh.raw + off);
+                       hao = (struct ipv6_destopt_hao *)
+                                       (skb_network_header(skb) + off);
                        ipv6_addr_copy(&tmp, &iph->saddr);
                        ipv6_addr_copy(&iph->saddr, &hao->addr);
                        ipv6_addr_copy(&hao->addr, &tmp);
 
        if (!pskb_pull(skb, skb->h.raw - skb->data))
                goto discard;
        nhoff = IP6CB(skb)->nhoff;
-       nexthdr = skb->nh.raw[nhoff];
+       nexthdr = skb_network_header(skb)[nhoff];
 
        raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]);
        if (raw_sk && !ipv6_raw_deliver(skb, nexthdr))
                           indefinitely. */
                        nf_reset(skb);
 
-                       skb_postpull_rcsum(skb, skb->nh.raw,
+                       skb_postpull_rcsum(skb, skb_network_header(skb),
                                           skb->h.raw - skb->nh.raw);
                        hdr = skb->nh.ipv6h;
                        if (ipv6_addr_is_multicast(&hdr->daddr) &&
 
        if (nexthdr == IPPROTO_ICMPV6) {
                struct icmp6hdr *icmp6;
 
-               if (!pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data))
+               if (!pskb_may_pull(skb, (skb_network_header(skb) +
+                                        offset + 1 - skb->data)))
                        return 0;
 
-               icmp6 = (struct icmp6hdr *)(skb->nh.raw + offset);
+               icmp6 = (struct icmp6hdr *)(skb_network_header(skb) + offset);
 
                switch (icmp6->icmp6_type) {
                case NDISC_ROUTER_SOLICITATION:
         *      that different fragments will go along one path. --ANK
         */
        if (opt->ra) {
-               u8 *ptr = skb->nh.raw + opt->ra;
+               u8 *ptr = skb_network_header(skb) + opt->ra;
                if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3]))
                        return 0;
        }
 {
        u16 offset = sizeof(struct ipv6hdr);
        struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
-       unsigned int packet_len = skb->tail - skb->nh.raw;
+       unsigned int packet_len = skb->tail - skb_network_header(skb);
        int found_rhdr = 0;
        *nexthdr = &skb->nh.ipv6h->nexthdr;
 
 
                offset += ipv6_optlen(exthdr);
                *nexthdr = &exthdr->nexthdr;
-               exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+               exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
+                                                offset);
        }
 
        return offset;
                /* BUILD HEADER */
 
                *prevhdr = NEXTHDR_FRAGMENT;
-               tmp_hdr = kmemdup(skb->nh.raw, hlen, GFP_ATOMIC);
+               tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
                if (!tmp_hdr) {
                        IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
                        return -ENOMEM;
                fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr));
                __skb_push(skb, hlen);
                skb_reset_network_header(skb);
-               memcpy(skb->nh.raw, tmp_hdr, hlen);
+               memcpy(skb_network_header(skb), tmp_hdr, hlen);
 
                ipv6_select_ident(skb, fh);
                fh->nexthdr = nexthdr;
                                fh = (struct frag_hdr*)__skb_push(frag, sizeof(struct frag_hdr));
                                __skb_push(frag, hlen);
                                skb_reset_network_header(frag);
-                               memcpy(frag->nh.raw, tmp_hdr, hlen);
+                               memcpy(skb_network_header(frag), tmp_hdr,
+                                      hlen);
                                offset += skb->len - hlen - sizeof(struct frag_hdr);
                                fh->nexthdr = nexthdr;
                                fh->reserved = 0;
                /*
                 *      Copy the packet header into the new buffer.
                 */
-               memcpy(frag->nh.raw, skb->data, hlen);
+               memcpy(skb_network_header(frag), skb->data, hlen);
 
                /*
                 *      Build fragment header.
        tail_skb = &(skb_shinfo(skb)->frag_list);
 
        /* move skb->data to ip header from ext header */
-       if (skb->data < skb->nh.raw)
+       if (skb->data < skb_network_header(skb))
                __skb_pull(skb, skb_network_offset(skb));
        while ((tmp_skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) {
                __skb_pull(tmp_skb, skb->h.raw - skb->nh.raw);
 
            !ip6_tnl_xmit_ctl(t) || ip6_tnl_addr_conflict(t, ipv6h))
                return -1;
 
-       if ((offset = parse_tlv_tnl_enc_lim(skb, skb->nh.raw)) > 0) {
+       offset = parse_tlv_tnl_enc_lim(skb, skb_network_header(skb));
+       if (offset > 0) {
                struct ipv6_tlv_tnl_enc_lim *tel;
-               tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->nh.raw[offset];
+               tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset];
                if (tel->encap_limit == 0) {
                        icmpv6_send(skb, ICMPV6_PARAMPROB,
                                    ICMPV6_HDR_FIELD, offset + 2, skb->dev);
 
        top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
 
        ipch = (struct ipv6_comp_hdr *)start;
-       ipch->nexthdr = *skb->nh.raw;
+       ipch->nexthdr = *skb_network_header(skb);
        ipch->flags = 0;
        ipch->cpi = htons((u16 )ntohl(x->id.spi));
-       *skb->nh.raw = IPPROTO_COMP;
+       *skb_network_header(skb) = IPPROTO_COMP;
 
 out_ok:
        return 0;
 
        if (mh->ip6mh_hdrlen < mip6_mh_len(mh->ip6mh_type)) {
                LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH message too short: %d vs >=%d\n",
                               mh->ip6mh_hdrlen, mip6_mh_len(mh->ip6mh_type));
-               mip6_param_prob(skb, 0, (&mh->ip6mh_hdrlen) - skb->nh.raw);
+               mip6_param_prob(skb, 0, ((&mh->ip6mh_hdrlen) -
+                                        skb_network_header(skb)));
                return -1;
        }
 
        if (mh->ip6mh_proto != IPPROTO_NONE) {
                LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n",
                               mh->ip6mh_proto);
-               mip6_param_prob(skb, 0, (&mh->ip6mh_proto) - skb->nh.raw);
+               mip6_param_prob(skb, 0, ((&mh->ip6mh_proto) -
+                                        skb_network_header(skb)));
                return -1;
        }
 
        iph = (struct ipv6hdr *)skb->data;
        iph->payload_len = htons(skb->len - sizeof(*iph));
 
-       nexthdr = *skb->nh.raw;
-       *skb->nh.raw = IPPROTO_DSTOPTS;
+       nexthdr = *skb_network_header(skb);
+       *skb_network_header(skb) = IPPROTO_DSTOPTS;
 
        dstopt = (struct ipv6_destopt_hdr *)skb->h.raw;
        dstopt->nexthdr = nexthdr;
        if (likely(opt->dsthao)) {
                offset = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
                if (likely(offset >= 0))
-                       hao = (struct ipv6_destopt_hao *)(skb->nh.raw + offset);
+                       hao = (struct ipv6_destopt_hao *)
+                                       (skb_network_header(skb) + offset);
        }
 
        skb_get_timestamp(skb, &stamp);
 {
        u16 offset = sizeof(struct ipv6hdr);
        struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
-       unsigned int packet_len = skb->tail - skb->nh.raw;
+       const unsigned char *nh = skb_network_header(skb);
+       unsigned int packet_len = skb->tail - nh;
        int found_rhdr = 0;
 
        *nexthdr = &skb->nh.ipv6h->nexthdr;
 
                offset += ipv6_optlen(exthdr);
                *nexthdr = &exthdr->nexthdr;
-               exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+               exthdr = (struct ipv6_opt_hdr *)(nh + offset);
        }
 
        return offset;
        iph = (struct ipv6hdr *)skb->data;
        iph->payload_len = htons(skb->len - sizeof(*iph));
 
-       nexthdr = *skb->nh.raw;
-       *skb->nh.raw = IPPROTO_ROUTING;
+       nexthdr = *skb_network_header(skb);
+       *skb_network_header(skb) = IPPROTO_ROUTING;
 
        rt2 = (struct rt2_hdr *)skb->h.raw;
        rt2->rt_hdr.nexthdr = nexthdr;
 {
        u16 offset = sizeof(struct ipv6hdr);
        struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
-       unsigned int packet_len = skb->tail - skb->nh.raw;
+       const unsigned char *nh = skb_network_header(skb);
+       unsigned int packet_len = skb->tail - nh;
        int found_rhdr = 0;
 
        *nexthdr = &skb->nh.ipv6h->nexthdr;
                case NEXTHDR_ROUTING:
                        if (offset + 3 <= packet_len) {
                                struct ipv6_rt_hdr *rt;
-                               rt = (struct ipv6_rt_hdr *)(skb->nh.raw + offset);
+                               rt = (struct ipv6_rt_hdr *)(nh + offset);
                                if (rt->type != 0)
                                        return offset;
                        }
 
                offset += ipv6_optlen(exthdr);
                *nexthdr = &exthdr->nexthdr;
-               exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+               exthdr = (struct ipv6_opt_hdr *)(nh + offset);
        }
 
        return offset;
 
                return -1;
        }
 
-       if (skb->ip_summed == CHECKSUM_COMPLETE)
+       if (skb->ip_summed == CHECKSUM_COMPLETE) {
+               const unsigned char *nh = skb_network_header(skb);
                skb->csum = csum_sub(skb->csum,
-                                    csum_partial(skb->nh.raw,
-                                                 (u8*)(fhdr + 1) - skb->nh.raw,
+                                    csum_partial(nh, (u8 *)(fhdr + 1) - nh,
                                                  0));
+       }
 
        /* Is this the final fragment? */
        if (!(fhdr->frag_off & htons(IP6_MF))) {
        BUG_TRAP(NFCT_FRAG6_CB(head)->offset == 0);
 
        /* Unfragmented part is taken from the first segment. */
-       payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len - sizeof(struct frag_hdr);
+       payload_len = ((head->data - skb_network_header(head)) -
+                      sizeof(struct ipv6hdr) + fq->len -
+                      sizeof(struct frag_hdr));
        if (payload_len > IPV6_MAXPLEN) {
                DEBUGP("payload len is too large.\n");
                goto out_oversize;
 
        /* We have to remove fragment header from datagram and to relocate
         * header in order to calculate ICV correctly. */
-       head->nh.raw[fq->nhoffset] = head->h.raw[0];
+       skb_network_header(head)[fq->nhoffset] = head->h.raw[0];
        memmove(head->head + sizeof(struct frag_hdr), head->head,
                (head->data - head->head) - sizeof(struct frag_hdr));
        head->mac.raw += sizeof(struct frag_hdr);
 
        skb_shinfo(head)->frag_list = head->next;
        head->h.raw = head->data;
-       skb_push(head, head->data - head->nh.raw);
+       skb_push(head, head->data - skb_network_header(head));
        atomic_sub(head->truesize, &nf_ct_frag6_mem);
 
        for (fp=head->next; fp; fp = fp->next) {
 
        /* Yes, and fold redundant checksum back. 8) */
        if (head->ip_summed == CHECKSUM_COMPLETE)
-               head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
+               head->csum = csum_partial(skb_network_header(head),
+                                         head->h.raw - head->nh.raw,
+                                         head->csum);
 
        fq->fragments = NULL;
 
 
                skb->ip_summed = CHECKSUM_UNNECESSARY;
 
        if (skb->ip_summed == CHECKSUM_COMPLETE) {
-               skb_postpull_rcsum(skb, skb->nh.raw,
+               skb_postpull_rcsum(skb, skb_network_header(skb),
                                   skb->h.raw - skb->nh.raw);
                if (!csum_ipv6_magic(&skb->nh.ipv6h->saddr,
                                     &skb->nh.ipv6h->daddr,
                goto out;
 
        offset = rp->offset;
-       total_len = inet_sk(sk)->cork.length - (skb->nh.raw - skb->data);
+       total_len = inet_sk(sk)->cork.length - (skb_network_header(skb) -
+                                               skb->data);
        if (offset >= total_len - 1) {
                err = -EINVAL;
                ip6_flush_pending_frames(sk);
 
        if ((unsigned int)end > IPV6_MAXPLEN) {
                IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
                                 IPSTATS_MIB_INHDRERRORS);
-               icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw);
+               icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
+                                 ((u8 *)&fhdr->frag_off -
+                                  skb_network_header(skb)));
                return;
        }
 
-       if (skb->ip_summed == CHECKSUM_COMPLETE)
+       if (skb->ip_summed == CHECKSUM_COMPLETE) {
+               const unsigned char *nh = skb_network_header(skb);
                skb->csum = csum_sub(skb->csum,
-                                    csum_partial(skb->nh.raw, (u8*)(fhdr+1)-skb->nh.raw, 0));
+                                    csum_partial(nh, (u8 *)(fhdr + 1) - nh,
+                                                 0));
+       }
 
        /* Is this the final fragment? */
        if (!(fhdr->frag_off & htons(IP6_MF))) {
        BUG_TRAP(FRAG6_CB(head)->offset == 0);
 
        /* Unfragmented part is taken from the first segment. */
-       payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len - sizeof(struct frag_hdr);
+       payload_len = ((head->data - skb_network_header(head)) -
+                      sizeof(struct ipv6hdr) + fq->len -
+                      sizeof(struct frag_hdr));
        if (payload_len > IPV6_MAXPLEN)
                goto out_oversize;
 
        /* We have to remove fragment header from datagram and to relocate
         * header in order to calculate ICV correctly. */
        nhoff = fq->nhoffset;
-       head->nh.raw[nhoff] = head->h.raw[0];
+       skb_network_header(head)[nhoff] = head->h.raw[0];
        memmove(head->head + sizeof(struct frag_hdr), head->head,
                (head->data - head->head) - sizeof(struct frag_hdr));
        head->mac.raw += sizeof(struct frag_hdr);
 
        skb_shinfo(head)->frag_list = head->next;
        head->h.raw = head->data;
-       skb_push(head, head->data - head->nh.raw);
+       skb_push(head, head->data - skb_network_header(head));
        atomic_sub(head->truesize, &ip6_frag_mem);
 
        for (fp=head->next; fp; fp = fp->next) {
 
        /* Yes, and fold redundant checksum back. 8) */
        if (head->ip_summed == CHECKSUM_COMPLETE)
-               head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
+               head->csum = csum_partial(skb_network_header(head),
+                                         head->h.raw - head->nh.raw,
+                                         head->csum);
 
        rcu_read_lock();
        IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMOKS);
                skb->h.raw += sizeof(struct frag_hdr);
                IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMOKS);
 
-               IP6CB(skb)->nhoff = (u8*)fhdr - skb->nh.raw;
+               IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb);
                return 1;
        }
 
 
                        struct sk_buff *pktopts = treq->pktopts;
                        struct inet6_skb_parm *rxopt = IP6CB(pktopts);
                        if (rxopt->srcrt)
-                               opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt));
+                               opt = ipv6_invert_rthdr(sk,
+                         (struct ipv6_rt_hdr *)(skb_network_header(pktopts) +
+                                                rxopt->srcrt));
                }
 
                if (opt && opt->srcrt) {
            opt == NULL && treq->pktopts) {
                struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
                if (rxopt->srcrt)
-                       opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr *)(treq->pktopts->nh.raw + rxopt->srcrt));
+                       opt = ipv6_invert_rthdr(sk,
+                  (struct ipv6_rt_hdr *)(skb_network_header(treq->pktopts) +
+                                         rxopt->srcrt));
        }
 
        if (dst == NULL) {
 
        unsigned int nhoff;
 
        nhoff = IP6CB(skb)->nhoff;
-       nexthdr = skb->nh.raw[nhoff];
+       nexthdr = skb_network_header(skb)[nhoff];
 
        seq = 0;
        if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
                if (nexthdr <= 0)
                        goto drop_unlock;
 
-               skb->nh.raw[nhoff] = nexthdr;
+               skb_network_header(skb)[nhoff] = nexthdr;
 
                if (x->props.replay_window)
                        xfrm_replay_advance(x, seq);
        } else {
 #ifdef CONFIG_NETFILTER
                skb->nh.ipv6h->payload_len = htons(skb->len);
-               __skb_push(skb, skb->data - skb->nh.raw);
+               __skb_push(skb, skb->data - skb_network_header(skb));
 
                NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
                        ip6_rcv_finish);
 
                goto out;
 
        skb_push(skb, size);
-       memmove(skb->data, skb->nh.raw, size);
+       memmove(skb->data, skb_network_header(skb), size);
        skb_reset_network_header(skb);
 
        old_mac = skb_mac_header(skb);
 
 {
        int ihl = skb->data - skb->h.raw;
 
-       if (skb->h.raw != skb->nh.raw)
-               skb->nh.raw = memmove(skb->h.raw, skb->nh.raw, ihl);
+       if (skb->h.raw != skb->nh.raw) {
+               memmove(skb->h.raw, skb_network_header(skb), ihl);
+               skb->nh.raw = skb->h.raw;
+       }
        skb->nh.ipv6h->payload_len = htons(skb->len + ihl -
                                           sizeof(struct ipv6hdr));
        skb->h.raw = skb->data;
 
 {
        int err = -EINVAL;
        const unsigned char *old_mac;
+       const unsigned char *nh = skb_network_header(skb);
 
-       if (skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPV6
-           && skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPIP)
+       if (nh[IP6CB(skb)->nhoff] != IPPROTO_IPV6 &&
+           nh[IP6CB(skb)->nhoff] != IPPROTO_IPIP)
                goto out;
        if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
                goto out;
            (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
                goto out;
 
-       if (skb->nh.raw[IP6CB(skb)->nhoff] == IPPROTO_IPV6) {
+       nh = skb_network_header(skb);
+       if (nh[IP6CB(skb)->nhoff] == IPPROTO_IPV6) {
                if (x->props.flags & XFRM_STATE_DECAP_DSCP)
                        ipv6_copy_dscp(skb->nh.ipv6h, skb->h.ipv6h);
                if (!(x->props.flags & XFRM_STATE_NOECN))
 
        u16 offset = skb->h.raw - skb->nh.raw;
        struct ipv6hdr *hdr = skb->nh.ipv6h;
        struct ipv6_opt_hdr *exthdr;
-       u8 nexthdr = skb->nh.raw[IP6CB(skb)->nhoff];
+       const unsigned char *nh = skb_network_header(skb);
+       u8 nexthdr = nh[IP6CB(skb)->nhoff];
 
        memset(fl, 0, sizeof(struct flowi));
        ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr);
        ipv6_addr_copy(&fl->fl6_src, &hdr->saddr);
 
-       while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) {
-               exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+       while (pskb_may_pull(skb, nh + offset + 1 - skb->data)) {
+               nh = skb_network_header(skb);
+               exthdr = (struct ipv6_opt_hdr *)(nh + offset);
 
                switch (nexthdr) {
                case NEXTHDR_ROUTING:
                case NEXTHDR_DEST:
                        offset += ipv6_optlen(exthdr);
                        nexthdr = exthdr->nexthdr;
-                       exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+                       exthdr = (struct ipv6_opt_hdr *)(nh + offset);
                        break;
 
                case IPPROTO_UDP:
                case IPPROTO_TCP:
                case IPPROTO_SCTP:
                case IPPROTO_DCCP:
-                       if (pskb_may_pull(skb, skb->nh.raw + offset + 4 - skb->data)) {
+                       if (pskb_may_pull(skb, nh + offset + 4 - skb->data)) {
                                __be16 *ports = (__be16 *)exthdr;
 
                                fl->fl_ip_sport = ports[0];
                        return;
 
                case IPPROTO_ICMPV6:
-                       if (pskb_may_pull(skb, skb->nh.raw + offset + 2 - skb->data)) {
+                       if (pskb_may_pull(skb, nh + offset + 2 - skb->data)) {
                                u8 *icmp = (u8 *)exthdr;
 
                                fl->fl_icmp_type = icmp[0];
 
 #ifdef CONFIG_IPV6_MIP6
                case IPPROTO_MH:
-                       if (pskb_may_pull(skb, skb->nh.raw + offset + 3 - skb->data)) {
+                       if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
                                struct ip6_mh *mh;
                                mh = (struct ip6_mh *)exthdr;
 
 
                return -1;
 
        tcplen = (*pskb)->len - tcphoff;
-       tcph = (struct tcphdr *)((*pskb)->nh.raw + tcphoff);
+       tcph = (struct tcphdr *)(skb_network_header(*pskb) + tcphoff);
 
        /* Since it passed flags test in tcp match, we know it is is
           not a fragment, and has data >= tcp header length.  SYN
                        return -1;
                kfree_skb(*pskb);
                *pskb = newskb;
-               tcph = (struct tcphdr *)((*pskb)->nh.raw + tcphoff);
+               tcph = (struct tcphdr *)(skb_network_header(*pskb) + tcphoff);
        }
 
        skb_put((*pskb), TCPOLEN_MSS);
 
                }
        }
 
-       pptr = skb->nh.raw;
+       pptr = skb_network_header(skb);
 
        spin_lock(&p->tcf_lock);
 
 
        } stack[TC_U32_MAXDEPTH];
 
        struct tc_u_hnode *ht = (struct tc_u_hnode*)tp->root;
-       u8 *ptr = skb->nh.raw;
+       u8 *ptr = skb_network_header(skb);
        struct tc_u_knode *n;
        int sdepth = 0;
        int off2 = 0;
 
                        struct tcf_pkt_info *info)
 {
        struct tc_u32_key *key = (struct tc_u32_key *) em->data;
-       unsigned char *ptr = skb->nh.raw;
+       const unsigned char *ptr = skb_network_header(skb);
 
        if (info) {
                if (info->ptr)