break;
                }
 
-               hash_start = (char*)&(skb->nh.ipv6h->daddr);
-               hash_size = sizeof(skb->nh.ipv6h->daddr);
+               hash_start = (char *)&(ipv6_hdr(skb)->daddr);
+               hash_size = sizeof(ipv6_hdr(skb)->daddr);
                break;
        case ETH_P_IPX:
                if (ipx_hdr(skb)->ipx_checksum !=
 
                        cmd_length = E1000_TXD_CMD_IP;
                        ipcse = skb->h.raw - skb->data - 1;
                } else if (skb->protocol == htons(ETH_P_IPV6)) {
-                       skb->nh.ipv6h->payload_len = 0;
+                       ipv6_hdr(skb)->payload_len = 0;
                        skb->h.th->check =
-                               ~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
-                                                &skb->nh.ipv6h->daddr,
-                                                0,
-                                                IPPROTO_TCP,
-                                                0);
+                               ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+                                                &ipv6_hdr(skb)->daddr,
+                                                0, IPPROTO_TCP, 0);
                        ipcse = 0;
                }
                ipcss = skb_network_offset(skb);
 
                                                  skb->h.raw,
                                                  skb->h.th->doff * 4);
        else
-               eddp = qeth_eddp_create_eddp_data(qhdr, (u8 *)skb->nh.ipv6h,
-                               sizeof(struct ipv6hdr),
-                               (u8 *)skb->h.th, skb->h.th->doff*4);
+               eddp = qeth_eddp_create_eddp_data(qhdr,
+                                                 skb_network_header(skb),
+                                                 sizeof(struct ipv6hdr),
+                                                 skb->h.raw,
+                                                 skb->h.th->doff * 4);
 
        if (eddp == NULL) {
                QETH_DBF_TEXT(trace, 2, "eddpfcnm");
 
                               skb->dst->neighbour->primary_key, 16);
                } else {
                        /* fill in destination address used in ip header */
-                       memcpy(hdr->hdr.l3.dest_addr, &skb->nh.ipv6h->daddr, 16);
+                       memcpy(hdr->hdr.l3.dest_addr,
+                              &ipv6_hdr(skb)->daddr, 16);
                }
        } else { /* passthrough */
                 if((skb->dev->type == ARPHRD_IEEE802_TR) &&
 
 qeth_tso_set_tcpip_header(struct qeth_card *card, struct sk_buff *skb)
 {
        struct iphdr *iph    = ip_hdr(skb);
-       struct ipv6hdr *ip6h = skb->nh.ipv6h;
+       struct ipv6hdr *ip6h = ipv6_hdr(skb);
        struct tcphdr *tcph  = skb->h.th;
 
        tcph->check = 0;
 
 #include <net/if_inet6.h>       /* struct ipv6_mc_socklist */
 #include <net/inet_sock.h>
 
+static inline struct ipv6hdr *ipv6_hdr(const struct sk_buff *skb)
+{
+       return (struct ipv6hdr *)skb_network_header(skb);
+}
+
 /* 
    This structure contains results of exthdrs parsing
    as offsets from skb->nh.
 
        } h;
 
        union {
-               struct ipv6hdr  *ipv6h;
                unsigned char   *raw;
        } nh;
 
 
        case __constant_htons(ETH_P_IPV6):
                if (skb_network_header(skb) + sizeof(struct ipv6hdr) <=
                    skb->tail)
-                       return IP6_ECN_set_ce(skb->nh.ipv6h);
+                       return IP6_ECN_set_ce(ipv6_hdr(skb));
                break;
        }
 
 
 /* We only check the length. A bridge shouldn't do any hop-by-hop stuff anyway */
 static int check_hbh_len(struct sk_buff *skb)
 {
-       unsigned char *raw = (u8 *) (skb->nh.ipv6h + 1);
+       unsigned char *raw = (u8 *)(ipv6_hdr(skb) + 1);
        u32 pkt_len;
        const unsigned char *nh = skb_network_header(skb);
        int off = raw - nh;
                                goto bad;
                        pkt_len = ntohl(*(__be32 *) (nh + off + 2));
                        if (pkt_len <= IPV6_MAXPLEN ||
-                           skb->nh.ipv6h->payload_len)
+                           ipv6_hdr(skb)->payload_len)
                                goto bad;
                        if (pkt_len > skb->len - sizeof(struct ipv6hdr))
                                goto bad;
        if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
                goto inhdr_error;
 
-       hdr = skb->nh.ipv6h;
+       hdr = ipv6_hdr(skb);
 
        if (hdr->version != 6)
                goto inhdr_error;
 
        skb->protocol = protocol;
        skb->dev = odev;
        skb->pkt_type = PACKET_HOST;
-       skb->nh.ipv6h = iph;
+       skb->nh.raw = (unsigned char *)iph;
        skb->h.uh = udph;
 
        if (pkt_dev->nfrags <= 0)
 
 
 static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb)
 {
-       return secure_dccpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
-                                            skb->nh.ipv6h->saddr.s6_addr32,
+       return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32,
+                                            ipv6_hdr(skb)->saddr.s6_addr32,
                                             dccp_hdr(skb)->dccph_dport,
                                             dccp_hdr(skb)->dccph_sport     );
 
 static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
 {
        struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
+       struct ipv6hdr *rxip6h;
        const u32 dccp_hdr_reset_len = sizeof(struct dccp_hdr) +
                                       sizeof(struct dccp_hdr_ext) +
                                       sizeof(struct dccp_hdr_reset);
        dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq);
 
        dccp_csum_outgoing(skb);
-       dh->dccph_checksum = dccp_v6_csum_finish(skb, &rxskb->nh.ipv6h->saddr,
-                                                     &rxskb->nh.ipv6h->daddr);
+       rxip6h = ipv6_hdr(rxskb);
+       dh->dccph_checksum = dccp_v6_csum_finish(skb, &rxip6h->saddr,
+                                                     &rxip6h->daddr);
 
        memset(&fl, 0, sizeof(fl));
-       ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr);
-       ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr);
+       ipv6_addr_copy(&fl.fl6_dst, &rxip6h->saddr);
+       ipv6_addr_copy(&fl.fl6_src, &rxip6h->daddr);
 
        fl.proto = IPPROTO_DCCP;
        fl.oif = inet6_iif(rxskb);
 static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
 {
        const struct dccp_hdr *dh = dccp_hdr(skb);
-       const struct ipv6hdr *iph = skb->nh.ipv6h;
+       const struct ipv6hdr *iph = ipv6_hdr(skb);
        struct sock *nsk;
        struct request_sock **prev;
        /* Find possible connection requests. */
                goto drop_and_free;
 
        ireq6 = inet6_rsk(req);
-       ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr);
-       ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr);
+       ipv6_addr_copy(&ireq6->rmt_addr, &ipv6_hdr(skb)->saddr);
+       ipv6_addr_copy(&ireq6->loc_addr, &ipv6_hdr(skb)->daddr);
        ireq6->pktopts  = NULL;
 
        if (ipv6_opt_accepted(sk, skb) ||
                newnp->pktoptions  = NULL;
                newnp->opt         = NULL;
                newnp->mcast_oif   = inet6_iif(skb);
-               newnp->mcast_hops  = skb->nh.ipv6h->hop_limit;
+               newnp->mcast_hops  = ipv6_hdr(skb)->hop_limit;
 
                /*
                 * No need to charge this sock to the relevant IPv6 refcnt debug socks count
        }
        newnp->opt        = NULL;
        newnp->mcast_oif  = inet6_iif(skb);
-       newnp->mcast_hops = skb->nh.ipv6h->hop_limit;
+       newnp->mcast_hops = ipv6_hdr(skb)->hop_limit;
 
        /*
         * Clone native IPv6 options from listening socket (if any)
                goto discard_it;
 
        /* Step 1: If header checksum is incorrect, drop packet and return. */
-       if (dccp_v6_csum_finish(skb, &skb->nh.ipv6h->saddr,
-                                    &skb->nh.ipv6h->daddr)) {
+       if (dccp_v6_csum_finish(skb, &ipv6_hdr(skb)->saddr,
+                                    &ipv6_hdr(skb)->daddr)) {
                DCCP_WARN("dropped packet with invalid checksum\n");
                goto discard_it;
        }
 
        /* Step 2:
         *      Look up flow ID in table and get corresponding socket */
-       sk = __inet6_lookup(&dccp_hashinfo, &skb->nh.ipv6h->saddr,
+       sk = __inet6_lookup(&dccp_hashinfo, &ipv6_hdr(skb)->saddr,
                            dh->dccph_sport,
-                           &skb->nh.ipv6h->daddr, ntohs(dh->dccph_dport),
+                           &ipv6_hdr(skb)->daddr, ntohs(dh->dccph_dport),
                            inet6_iif(skb));
        /*
         * Step 2:
 
                if (skb->protocol == htons(ETH_P_IP)) {
                        IP_ECN_set_ce(ip_hdr(skb));
                } else if (skb->protocol == htons(ETH_P_IPV6)) {
-                       IP6_ECN_set_ce(skb->nh.ipv6h);
+                       IP6_ECN_set_ce(ipv6_hdr(skb));
                }
        }
 }
                        addr_type = ipv6_addr_type(addr6);
 
                        if (addr_type == IPV6_ADDR_ANY) {
-                               addr6 = &skb->nh.ipv6h->daddr;
+                               addr6 = &ipv6_hdr(skb)->daddr;
                                addr_type = ipv6_addr_type(addr6);
                        }
 
 
 static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
 {
        if (INET_ECN_is_ce(iph->tos))
-               IP6_ECN_set_ce(skb->nh.ipv6h);
+               IP6_ECN_set_ce(ipv6_hdr(skb));
 }
 
 /* Add encapsulation header.
 
         */
 
        struct ipv6_auth_hdr *ah;
+       struct ipv6hdr *ip6h;
        struct ah_data *ahp;
        unsigned char *tmp_hdr = NULL;
        u16 hdr_len;
        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))
+       ip6h = ipv6_hdr(skb);
+       if (ipv6_clear_mutable_options(ip6h, hdr_len, XFRM_POLICY_IN))
                goto free_out;
-       skb->nh.ipv6h->priority    = 0;
-       skb->nh.ipv6h->flow_lbl[0] = 0;
-       skb->nh.ipv6h->flow_lbl[1] = 0;
-       skb->nh.ipv6h->flow_lbl[2] = 0;
-       skb->nh.ipv6h->hop_limit   = 0;
+       ip6h->priority    = 0;
+       ip6h->flow_lbl[0] = 0;
+       ip6h->flow_lbl[1] = 0;
+       ip6h->flow_lbl[2] = 0;
+       ip6h->hop_limit   = 0;
 
        {
                u8 auth_data[MAX_AH_AUTH_LEN];
 
 
        skb_put(skb, sizeof(struct ipv6hdr));
        skb_reset_network_header(skb);
-       iph = skb->nh.ipv6h;
+       iph = ipv6_hdr(skb);
        ipv6_addr_copy(&iph->daddr, &fl->fl6_dst);
 
        serr = SKB_EXT_ERR(skb);
                sin->sin6_flowinfo = 0;
                sin->sin6_scope_id = 0;
                if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
-                       ipv6_addr_copy(&sin->sin6_addr, &skb->nh.ipv6h->saddr);
+                       ipv6_addr_copy(&sin->sin6_addr, &ipv6_hdr(skb)->saddr);
                        if (np->rxopt.all)
                                datagram_recv_ctl(sk, msg, skb);
                        if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
                struct in6_pktinfo src_info;
 
                src_info.ipi6_ifindex = opt->iif;
-               ipv6_addr_copy(&src_info.ipi6_addr, &skb->nh.ipv6h->daddr);
+               ipv6_addr_copy(&src_info.ipi6_addr, &ipv6_hdr(skb)->daddr);
                put_cmsg(msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info);
        }
 
        if (np->rxopt.bits.rxhlim) {
-               int hlim = skb->nh.ipv6h->hop_limit;
+               int hlim = ipv6_hdr(skb)->hop_limit;
                put_cmsg(msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
        }
 
        if (np->rxopt.bits.rxtclass) {
-               int tclass = (ntohl(*(__be32 *)skb->nh.ipv6h) >> 20) & 0xff;
+               int tclass = (ntohl(*(__be32 *)ipv6_hdr(skb)) >> 20) & 0xff;
                put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
        }
 
                 * IPV6_RECVDSTOPTS is more generic. --yoshfuji
                 */
                unsigned int off = sizeof(struct ipv6hdr);
-               u8 nexthdr = skb->nh.ipv6h->nexthdr;
+               u8 nexthdr = ipv6_hdr(skb)->nexthdr;
 
                while (off <= opt->lastopt) {
                        unsigned len;
                struct in6_pktinfo src_info;
 
                src_info.ipi6_ifindex = opt->iif;
-               ipv6_addr_copy(&src_info.ipi6_addr, &skb->nh.ipv6h->daddr);
+               ipv6_addr_copy(&src_info.ipi6_addr, &ipv6_hdr(skb)->daddr);
                put_cmsg(msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
        }
        if (np->rxopt.bits.rxohlim) {
-               int hlim = skb->nh.ipv6h->hop_limit;
+               int hlim = ipv6_hdr(skb)->hop_limit;
                put_cmsg(msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
        }
        if (np->rxopt.bits.ohopopts && opt->hop) {
 
        skb->ip_summed = CHECKSUM_NONE;
 
        esph = (struct ipv6_esp_hdr*)skb->data;
-       iph = skb->nh.ipv6h;
+       iph = ipv6_hdr(skb);
 
        /* Get ivec. This can be wrong, check against another impls. */
        if (esp->conf.ivlen)
 
                /* Actually, it is redundant check. icmp_send
                   will recheck in any case.
                 */
-               if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
+               if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr))
                        break;
        case 2: /* send ICMP PARM PROB regardless and drop packet */
                icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff);
        struct sk_buff *skb = *skbp;
        struct ipv6_destopt_hao *hao;
        struct inet6_skb_parm *opt = IP6CB(skb);
-       struct ipv6hdr *ipv6h = skb->nh.ipv6h;
+       struct ipv6hdr *ipv6h = ipv6_hdr(skb);
        struct in6_addr tmp_addr;
        int ret;
 
                *skbp = skb = skb2;
                hao = (struct ipv6_destopt_hao *)(skb_network_header(skb2) +
                                                  optoff);
-               ipv6h = skb2->nh.ipv6h;
+               ipv6h = ipv6_hdr(skb2);
        }
 
        if (skb->ip_summed == CHECKSUM_COMPLETE)
                return -1;
        }
 
-       if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
+       if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
            skb->pkt_type != PACKET_HOST) {
                IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
                                 IPSTATS_MIB_INADDRERRORS);
 #ifdef CONFIG_IPV6_MIP6
        case IPV6_SRCRT_TYPE_2:
                if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
-                                    (xfrm_address_t *)&skb->nh.ipv6h->saddr,
+                                    (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
                                     IPPROTO_ROUTING) < 0) {
                        IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
                                         IPSTATS_MIB_INADDRERRORS);
        }
 
        ipv6_addr_copy(&daddr, addr);
-       ipv6_addr_copy(addr, &skb->nh.ipv6h->daddr);
-       ipv6_addr_copy(&skb->nh.ipv6h->daddr, &daddr);
+       ipv6_addr_copy(addr, &ipv6_hdr(skb)->daddr);
+       ipv6_addr_copy(&ipv6_hdr(skb)->daddr, &daddr);
 
        dst_release(xchg(&skb->dst, NULL));
        ip6_route_input(skb);
        }
 
        if (skb->dst->dev->flags&IFF_LOOPBACK) {
-               if (skb->nh.ipv6h->hop_limit <= 1) {
+               if (ipv6_hdr(skb)->hop_limit <= 1) {
                        IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
                                         IPSTATS_MIB_INHDRERRORS);
                        icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
                        kfree_skb(skb);
                        return -1;
                }
-               skb->nh.ipv6h->hop_limit--;
+               ipv6_hdr(skb)->hop_limit--;
                goto looped_back;
        }
 
                icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
                return 0;
        }
-       if (skb->nh.ipv6h->payload_len) {
+       if (ipv6_hdr(skb)->payload_len) {
                IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
                icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
                return 0;
 
 
 static int is_ineligible(struct sk_buff *skb)
 {
-       int ptr = (u8*)(skb->nh.ipv6h+1) - skb->data;
+       int ptr = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
        int len = skb->len - ptr;
-       __u8 nexthdr = skb->nh.ipv6h->nexthdr;
+       __u8 nexthdr = ipv6_hdr(skb)->nexthdr;
 
        if (len < 0)
                return 1;
 #ifdef CONFIG_IPV6_MIP6
 static void mip6_addr_swap(struct sk_buff *skb)
 {
-       struct ipv6hdr *iph = skb->nh.ipv6h;
+       struct ipv6hdr *iph = ipv6_hdr(skb);
        struct inet6_skb_parm *opt = IP6CB(skb);
        struct ipv6_destopt_hao *hao;
        struct in6_addr tmp;
                 struct net_device *dev)
 {
        struct inet6_dev *idev = NULL;
-       struct ipv6hdr *hdr = skb->nh.ipv6h;
+       struct ipv6hdr *hdr = ipv6_hdr(skb);
        struct sock *sk;
        struct ipv6_pinfo *np;
        struct in6_addr *saddr = NULL;
        int hlimit;
        int tclass;
 
-       saddr = &skb->nh.ipv6h->daddr;
+       saddr = &ipv6_hdr(skb)->daddr;
 
        if (!ipv6_unicast_destination(skb))
                saddr = NULL;
 
        memset(&fl, 0, sizeof(fl));
        fl.proto = IPPROTO_ICMPV6;
-       ipv6_addr_copy(&fl.fl6_dst, &skb->nh.ipv6h->saddr);
+       ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
        if (saddr)
                ipv6_addr_copy(&fl.fl6_src, saddr);
        fl.oif = skb->dev->ifindex;
        if (!pskb_may_pull(skb, inner_offset+8))
                return;
 
-       saddr = &skb->nh.ipv6h->saddr;
-       daddr = &skb->nh.ipv6h->daddr;
+       saddr = &ipv6_hdr(skb)->saddr;
+       daddr = &ipv6_hdr(skb)->daddr;
 
        /* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
           Without this we will not able f.e. to make source routed
 
        ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INMSGS);
 
-       saddr = &skb->nh.ipv6h->saddr;
-       daddr = &skb->nh.ipv6h->daddr;
+       saddr = &ipv6_hdr(skb)->saddr;
+       daddr = &ipv6_hdr(skb)->daddr;
 
        /* Perform checksum. */
        switch (skb->ip_summed) {
 
        if (unlikely(!pskb_may_pull(skb, sizeof(*hdr))))
                goto err;
 
-       hdr = skb->nh.ipv6h;
+       hdr = ipv6_hdr(skb);
 
        if (hdr->version != 6)
                goto err;
                        IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS);
                        goto drop;
                }
-               hdr = skb->nh.ipv6h;
+               hdr = ipv6_hdr(skb);
        }
 
        if (hdr->nexthdr == NEXTHDR_HOP) {
 
                        skb_postpull_rcsum(skb, skb_network_header(skb),
                                           skb->h.raw - skb->nh.raw);
-                       hdr = skb->nh.ipv6h;
+                       hdr = ipv6_hdr(skb);
                        if (ipv6_addr_is_multicast(&hdr->daddr) &&
                            !ipv6_chk_mcast_addr(skb->dev, &hdr->daddr,
                            &hdr->saddr) &&
 
        IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS);
 
-       hdr = skb->nh.ipv6h;
+       hdr = ipv6_hdr(skb);
        deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) ||
            ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);
 
 
        skb->protocol = htons(ETH_P_IPV6);
        skb->dev = dev;
 
-       if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) {
+       if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {
                struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL;
                struct inet6_dev *idev = ip6_dst_idev(skb->dst);
 
                if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) &&
-                   ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr,
-                               &skb->nh.ipv6h->saddr)) {
+                   ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr,
+                                       &ipv6_hdr(skb)->saddr)) {
                        struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
 
                        /* Do not check for IFF_ALLMULTI; multicast routing
                                        newskb->dev,
                                        ip6_dev_loopback_xmit);
 
-                       if (skb->nh.ipv6h->hop_limit == 0) {
+                       if (ipv6_hdr(skb)->hop_limit == 0) {
                                IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS);
                                kfree_skb(skb);
                                return 0;
 
        skb_push(skb, sizeof(struct ipv6hdr));
        skb_reset_network_header(skb);
-       hdr = skb->nh.ipv6h;
+       hdr = ipv6_hdr(skb);
 
        /*
         *      Fill in the IPv6 header
 
        totlen = len + sizeof(struct ipv6hdr);
 
-       hdr = (struct ipv6hdr *) skb_put(skb, sizeof(struct ipv6hdr));
-       skb->nh.ipv6h = hdr;
+       skb->nh.raw = skb_put(skb, sizeof(struct ipv6hdr));
+       hdr = ipv6_hdr(skb);
 
        *(__be32*)hdr = htonl(0x60000000);
 
 
 static int ip6_forward_proxy_check(struct sk_buff *skb)
 {
-       struct ipv6hdr *hdr = skb->nh.ipv6h;
+       struct ipv6hdr *hdr = ipv6_hdr(skb);
        u8 nexthdr = hdr->nexthdr;
        int offset;
 
 int ip6_forward(struct sk_buff *skb)
 {
        struct dst_entry *dst = skb->dst;
-       struct ipv6hdr *hdr = skb->nh.ipv6h;
+       struct ipv6hdr *hdr = ipv6_hdr(skb);
        struct inet6_skb_parm *opt = IP6CB(skb);
 
        if (ipv6_devconf.forwarding == 0)
                goto drop;
        }
 
-       hdr = skb->nh.ipv6h;
+       hdr = ipv6_hdr(skb);
 
        /* Mangling hops number delayed to point after skb COW */
 
 int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 {
        u16 offset = sizeof(struct ipv6hdr);
-       struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
+       struct ipv6_opt_hdr *exthdr =
+                               (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
        unsigned int packet_len = skb->tail - skb_network_header(skb);
        int found_rhdr = 0;
-       *nexthdr = &skb->nh.ipv6h->nexthdr;
+       *nexthdr = &ipv6_hdr(skb)->nexthdr;
 
        while (offset + 1 <= packet_len) {
 
                first_len = skb_pagelen(skb);
                skb->data_len = first_len - skb_headlen(skb);
                skb->len = first_len;
-               skb->nh.ipv6h->payload_len = htons(first_len - sizeof(struct ipv6hdr));
+               ipv6_hdr(skb)->payload_len = htons(first_len -
+                                                  sizeof(struct ipv6hdr));
 
                dst_hold(&rt->u.dst);
 
                                if (frag->next != NULL)
                                        fh->frag_off |= htons(IP6_MF);
                                fh->identification = frag_id;
-                               frag->nh.ipv6h->payload_len = htons(frag->len - sizeof(struct ipv6hdr));
+                               ipv6_hdr(frag)->payload_len =
+                                               htons(frag->len -
+                                                     sizeof(struct ipv6hdr));
                                ip6_copy_metadata(frag, skb);
                        }
 
                fh->frag_off = htons(offset);
                if (left > 0)
                        fh->frag_off |= htons(IP6_MF);
-               frag->nh.ipv6h->payload_len = htons(frag->len - sizeof(struct ipv6hdr));
+               ipv6_hdr(frag)->payload_len = htons(frag->len -
+                                                   sizeof(struct ipv6hdr));
 
                ptr += len;
                offset += len;
 
        skb_push(skb, sizeof(struct ipv6hdr));
        skb_reset_network_header(skb);
-       hdr = skb->nh.ipv6h;
+       hdr = ipv6_hdr(skb);
 
        *(__be32*)hdr = fl->fl6_flowlabel |
                     htonl(0x60000000 | ((int)np->cork.tclass << 20));
 
                skb_reset_network_header(skb2);
 
                /* Try to guess incoming interface */
-               rt = rt6_lookup(&skb2->nh.ipv6h->saddr, NULL, 0, 0);
+               rt = rt6_lookup(&ipv6_hdr(skb2)->saddr, NULL, 0, 0);
 
                if (rt && rt->rt6i_dev)
                        skb2->dev = rt->rt6i_dev;
                                        struct sk_buff *skb)
 {
        if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY)
-               ipv6_copy_dscp(ipv6h, skb->nh.ipv6h);
+               ipv6_copy_dscp(ipv6h, ipv6_hdr(skb));
 
        if (INET_ECN_is_ce(ipv6_get_dsfield(ipv6h)))
-               IP6_ECN_set_ce(skb->nh.ipv6h);
+               IP6_ECN_set_ce(ipv6_hdr(skb));
 }
 
 static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
                                                    struct ipv6hdr *ipv6h,
                                                    struct sk_buff *skb))
 {
-       struct ipv6hdr *ipv6h;
        struct ip6_tnl *t;
-
-       ipv6h = skb->nh.ipv6h;
+       struct ipv6hdr *ipv6h = ipv6_hdr(skb);
 
        read_lock(&ip6_tnl_lock);
 
 {
        struct ip6_tnl *t = netdev_priv(dev);
        struct net_device_stats *stats = &t->stat;
-       struct ipv6hdr *ipv6h = skb->nh.ipv6h;
+       struct ipv6hdr *ipv6h = ipv6_hdr(skb);
        struct ipv6_tel_txoption opt;
        struct dst_entry *dst;
        struct net_device *tdev;
        }
        skb_push(skb, sizeof(struct ipv6hdr));
        skb_reset_network_header(skb);
-       ipv6h = skb->nh.ipv6h;
+       ipv6h = ipv6_hdr(skb);
        *(__be32*)ipv6h = fl->fl6_flowlabel | htonl(0x60000000);
        dsfield = INET_ECN_encapsulate(0, dsfield);
        ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
 ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ip6_tnl *t = netdev_priv(dev);
-       struct ipv6hdr *ipv6h = skb->nh.ipv6h;
+       struct ipv6hdr *ipv6h = ipv6_hdr(skb);
        int encap_limit = -1;
        __u16 offset;
        struct flowi fl;
 
        skb->ip_summed = CHECKSUM_NONE;
 
        /* Remove ipcomp header and decompress original payload */
-       iph = skb->nh.ipv6h;
+       iph = ipv6_hdr(skb);
        ipch = (void *)skb->data;
        skb->h.raw = skb->nh.raw + sizeof(*ipch);
        __skb_pull(skb, sizeof(*ipch));
 
        if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
                goto out;
 
-       ipv6h = skb->nh.ipv6h;
+       ipv6h = ipv6_hdr(skb);
        __skb_pull(skb, sizeof(*ipv6h));
        err = -EPROTONOSUPPORT;
 
        if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
                goto out;
 
-       ipv6h = skb->nh.ipv6h;
+       ipv6h = ipv6_hdr(skb);
        __skb_pull(skb, sizeof(*ipv6h));
        segs = ERR_PTR(-EPROTONOSUPPORT);
 
                goto out;
 
        for (skb = segs; skb; skb = skb->next) {
-               ipv6h = skb->nh.ipv6h;
+               ipv6h = ipv6_hdr(skb);
                ipv6h->payload_len = htons(skb->len - skb->mac_len -
                                           sizeof(*ipv6h));
        }
 
                return -EINVAL;
 
        /* compute payload length excluding extension headers */
-       len = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr);
-       len -= (char *)skb->h.raw - (char *)skb->nh.ipv6h;
+       len = ntohs(ipv6_hdr(skb)->payload_len) + sizeof(struct ipv6hdr);
+       len -= skb->h.raw - skb->nh.raw;
 
        /* Drop queries with not link local source */
-       if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr)&IPV6_ADDR_LINKLOCAL))
+       if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL))
                return -EINVAL;
 
        idev = in6_dev_get(skb->dev);
        hdr = (struct icmp6hdr*) skb->h.raw;
 
        /* Drop reports with not link local source */
-       addr_type = ipv6_addr_type(&skb->nh.ipv6h->saddr);
+       addr_type = ipv6_addr_type(&ipv6_hdr(skb)->saddr);
        if (addr_type != IPV6_ADDR_ANY &&
            !(addr_type&IPV6_ADDR_LINKLOCAL))
                return -EINVAL;
                unsigned char ha[MAX_ADDR_LEN];
                int err;
 
-               ndisc_mc_map(&skb->nh.ipv6h->daddr, ha, dev, 1);
+               ndisc_mc_map(&ipv6_hdr(skb)->daddr, ha, dev, 1);
                err = dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len);
                if (err < 0) {
                        kfree_skb(skb);
 
 static void mld_sendpack(struct sk_buff *skb)
 {
-       struct ipv6hdr *pip6 = skb->nh.ipv6h;
+       struct ipv6hdr *pip6 = ipv6_hdr(skb);
        struct mld2_report *pmr = (struct mld2_report *)skb->h.raw;
        int payload_len, mldlen;
        struct inet6_dev *idev = in6_dev_get(skb->dev);
        int err;
 
        IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
-       payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h -
-               sizeof(struct ipv6hdr);
+       payload_len = skb->tail - skb_network_header(skb) - sizeof(*pip6);
        mldlen = skb->tail - skb->h.raw;
        pip6->payload_len = htons(payload_len);
 
 
 
 static int mip6_destopt_input(struct xfrm_state *x, struct sk_buff *skb)
 {
-       struct ipv6hdr *iph = skb->nh.ipv6h;
+       struct ipv6hdr *iph = ipv6_hdr(skb);
        struct ipv6_destopt_hdr *destopt = (struct ipv6_destopt_hdr *)skb->data;
 
        if (!ipv6_addr_equal(&iph->saddr, (struct in6_addr *)x->coaddr) &&
 
        skb_get_timestamp(skb, &stamp);
 
-       if (!mip6_report_rl_allow(&stamp, &skb->nh.ipv6h->daddr,
-                                 hao ? &hao->addr : &skb->nh.ipv6h->saddr,
+       if (!mip6_report_rl_allow(&stamp, &ipv6_hdr(skb)->daddr,
+                                 hao ? &hao->addr : &ipv6_hdr(skb)->saddr,
                                  opt->iif))
                goto out;
 
        memset(&sel, 0, sizeof(sel));
-       memcpy(&sel.daddr, (xfrm_address_t *)&skb->nh.ipv6h->daddr,
+       memcpy(&sel.daddr, (xfrm_address_t *)&ipv6_hdr(skb)->daddr,
               sizeof(sel.daddr));
        sel.prefixlen_d = 128;
-       memcpy(&sel.saddr, (xfrm_address_t *)&skb->nh.ipv6h->saddr,
+       memcpy(&sel.saddr, (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
               sizeof(sel.saddr));
        sel.prefixlen_s = 128;
        sel.family = AF_INET6;
                               u8 **nexthdr)
 {
        u16 offset = sizeof(struct ipv6hdr);
-       struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
+       struct ipv6_opt_hdr *exthdr =
+                                  (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
        const unsigned char *nh = skb_network_header(skb);
        unsigned int packet_len = skb->tail - nh;
        int found_rhdr = 0;
 
-       *nexthdr = &skb->nh.ipv6h->nexthdr;
+       *nexthdr = &ipv6_hdr(skb)->nexthdr;
 
        while (offset + 1 <= packet_len) {
 
                             u8 **nexthdr)
 {
        u16 offset = sizeof(struct ipv6hdr);
-       struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
+       struct ipv6_opt_hdr *exthdr =
+                                  (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
        const unsigned char *nh = skb_network_header(skb);
        unsigned int packet_len = skb->tail - nh;
        int found_rhdr = 0;
 
-       *nexthdr = &skb->nh.ipv6h->nexthdr;
+       *nexthdr = &ipv6_hdr(skb)->nexthdr;
 
        while (offset + 1 <= packet_len) {
 
 
                                       dev->addr_len, dev->type);
 
        /* checksum */
-       msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
+       msg->icmph.icmp6_cksum = csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
                                                 daddr, len,
                                                 IPPROTO_ICMPV6,
                                                 csum_partial((__u8 *) msg,
                                       dev->addr_len, dev->type);
 
        /* checksum */
-       hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
+       hdr->icmp6_cksum = csum_ipv6_magic(&ipv6_hdr(skb)->saddr, daddr, len,
                                           IPPROTO_ICMPV6,
                                           csum_partial((__u8 *) hdr, len, 0));
 
        struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
        int probes = atomic_read(&neigh->probes);
 
-       if (skb && ipv6_chk_addr(&skb->nh.ipv6h->saddr, dev, 1))
-               saddr = &skb->nh.ipv6h->saddr;
+       if (skb && ipv6_chk_addr(&ipv6_hdr(skb)->saddr, dev, 1))
+               saddr = &ipv6_hdr(skb)->saddr;
 
        if ((probes -= neigh->parms->ucast_probes) < 0) {
                if (!(neigh->nud_state & NUD_VALID)) {
 static void ndisc_recv_ns(struct sk_buff *skb)
 {
        struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
-       struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
-       struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
+       struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
+       struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
        u8 *lladdr = NULL;
        u32 ndoptlen = skb->tail - msg->opt;
        struct ndisc_options ndopts;
 static void ndisc_recv_na(struct sk_buff *skb)
 {
        struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
-       struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
-       struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
+       struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
+       struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
        u8 *lladdr = NULL;
        u32 ndoptlen = skb->tail - msg->opt;
        struct ndisc_options ndopts;
        unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
        struct neighbour *neigh;
        struct inet6_dev *idev;
-       struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
+       struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
        struct ndisc_options ndopts;
        u8 *lladdr = NULL;
 
 
        optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);
 
-       if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
+       if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
                ND_PRINTK2(KERN_WARNING
                           "ICMPv6 RA: source address is not link-local.\n");
                return;
                pref = ICMPV6_ROUTER_PREF_MEDIUM;
 #endif
 
-       rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
+       rt = rt6_get_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev);
 
        if (rt)
                neigh = rt->rt6i_nexthop;
                ND_PRINTK3(KERN_DEBUG
                           "ICMPv6 RA: adding default router.\n");
 
-               rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev, pref);
+               rt = rt6_add_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev, pref);
                if (rt == NULL) {
                        ND_PRINTK0(KERN_ERR
                                   "ICMPv6 RA: %s() failed to add default route.\n",
         */
 
        if (!neigh)
-               neigh = __neigh_lookup(&nd_tbl, &skb->nh.ipv6h->saddr,
+               neigh = __neigh_lookup(&nd_tbl, &ipv6_hdr(skb)->saddr,
                                       skb->dev, 1);
        if (neigh) {
                u8 *lladdr = NULL;
                        if (((struct route_info *)p)->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
                                continue;
                        rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3,
-                                     &skb->nh.ipv6h->saddr);
+                                     &ipv6_hdr(skb)->saddr);
                }
        }
 #endif
        int optlen;
        u8 *lladdr = NULL;
 
-       if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
+       if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
                ND_PRINTK2(KERN_WARNING
                           "ICMPv6 Redirect: source address is not link-local.\n");
                return;
 
        neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
        if (neigh) {
-               rt6_redirect(dest, &skb->nh.ipv6h->daddr,
-                            &skb->nh.ipv6h->saddr, neigh, lladdr,
+               rt6_redirect(dest, &ipv6_hdr(skb)->daddr,
+                            &ipv6_hdr(skb)->saddr, neigh, lladdr,
                             on_link);
                neigh_release(neigh);
        }
                return;
        }
 
-       if (!ipv6_addr_equal(&skb->nh.ipv6h->daddr, target) &&
+       if (!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, target) &&
            !(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
                ND_PRINTK2(KERN_WARNING
                        "ICMPv6 Redirect: target address is not link-local.\n");
                return;
        }
 
-       ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr,
+       ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &ipv6_hdr(skb)->saddr,
                        dev->ifindex);
 
        dst = ip6_route_output(NULL, &fl);
        hlen = 0;
 
        skb_reserve(buff, LL_RESERVED_SPACE(dev));
-       ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
+       ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr,
                   IPPROTO_ICMPV6, len);
 
        icmph = (struct icmp6hdr *)skb_put(buff, len);
        addrp = (struct in6_addr *)(icmph + 1);
        ipv6_addr_copy(addrp, target);
        addrp++;
-       ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
+       ipv6_addr_copy(addrp, &ipv6_hdr(skb)->daddr);
 
        opt = (u8*) (addrp + 1);
 
        *(opt++) = (rd_len >> 3);
        opt += 6;
 
-       memcpy(opt, skb->nh.ipv6h, rd_len - 8);
+       memcpy(opt, ipv6_hdr(skb), rd_len - 8);
 
-       icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &skb->nh.ipv6h->saddr,
+       icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr,
                                             len, IPPROTO_ICMPV6,
                                             csum_partial((u8 *) icmph, len, 0));
 
 
        __skb_push(skb, skb->data-skb->h.raw);
 
-       if (skb->nh.ipv6h->hop_limit != 255) {
+       if (ipv6_hdr(skb)->hop_limit != 255) {
                ND_PRINTK2(KERN_WARNING
                           "ICMPv6 NDISC: invalid hop-limit: %d\n",
-                          skb->nh.ipv6h->hop_limit);
+                          ipv6_hdr(skb)->hop_limit);
                return 0;
        }
 
 
 
 int ip6_route_me_harder(struct sk_buff *skb)
 {
-       struct ipv6hdr *iph = skb->nh.ipv6h;
+       struct ipv6hdr *iph = ipv6_hdr(skb);
        struct dst_entry *dst;
        struct flowi fl = {
                .oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
        struct ip6_rt_info *rt_info = nf_info_reroute(info);
 
        if (info->hook == NF_IP6_LOCAL_OUT) {
-               struct ipv6hdr *iph = skb->nh.ipv6h;
+               struct ipv6hdr *iph = ipv6_hdr(skb);
 
                rt_info->daddr = iph->daddr;
                rt_info->saddr = iph->saddr;
        struct ip6_rt_info *rt_info = nf_info_reroute(info);
 
        if (info->hook == NF_IP6_LOCAL_OUT) {
-               struct ipv6hdr *iph = (*pskb)->nh.ipv6h;
+               struct ipv6hdr *iph = ipv6_hdr(*pskb);
                if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) ||
                    !ipv6_addr_equal(&iph->saddr, &rt_info->saddr))
                        return ip6_route_me_harder(*pskb);
 __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
                             unsigned int dataoff, u_int8_t protocol)
 {
-       struct ipv6hdr *ip6h = skb->nh.ipv6h;
+       struct ipv6hdr *ip6h = ipv6_hdr(skb);
        __sum16 csum = 0;
 
        switch (skb->ip_summed) {
 
 {
        size_t i;
        unsigned long ret;
-       const struct ipv6hdr *ipv6 = skb->nh.ipv6h;
+       const struct ipv6hdr *ipv6 = ipv6_hdr(skb);
 
 #define FWINV(bool,invflg) ((bool) ^ !!(ip6info->invflags & invflg))
 
                                goto no_match;
 
                        ADD_COUNTER(e->counters,
-                                   ntohs((*pskb)->nh.ipv6h->payload_len)
+                                   ntohs(ipv6_hdr(*pskb)->payload_len)
                                    + IPV6_HDR_LEN,
                                    1);
 
 int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
                  int target, unsigned short *fragoff)
 {
-       unsigned int start = (u8*)(skb->nh.ipv6h + 1) - skb->data;
-       u8 nexthdr = skb->nh.ipv6h->nexthdr;
+       unsigned int start = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
+       u8 nexthdr = ipv6_hdr(skb)->nexthdr;
        unsigned int len = skb->len - start;
 
        if (fragoff)
 
        if (!skb_make_writable(pskb, (*pskb)->len))
                return NF_DROP;
 
-       ip6h = (*pskb)->nh.ipv6h;
+       ip6h = ipv6_hdr(*pskb);
 
        switch (info->mode) {
                case IP6T_HL_SET:
 
                        printk(" ");
        }
 
-       dump_packet(loginfo, skb, (u8*)skb->nh.ipv6h - skb->data, 1);
+       dump_packet(loginfo, skb, skb_network_offset(skb), 1);
        printk("\n");
        spin_unlock_bh(&log_lock);
 }
 
        struct tcphdr otcph, *tcph;
        unsigned int otcplen, hh_len;
        int tcphoff, needs_ack;
-       struct ipv6hdr *oip6h = oldskb->nh.ipv6h, *ip6h;
+       struct ipv6hdr *oip6h = ipv6_hdr(oldskb), *ip6h;
        struct dst_entry *dst = NULL;
        u8 proto;
        struct flowi fl;
 
        skb_put(nskb, sizeof(struct ipv6hdr));
        skb_reset_network_header(nskb);
-       ip6h = nskb->nh.ipv6h;
+       ip6h = ipv6_hdr(nskb);
        ip6h->version = 6;
        ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
        ip6h->nexthdr = IPPROTO_TCP;
        tcph->check = 0;
 
        /* Adjust TCP checksum */
-       tcph->check = csum_ipv6_magic(&nskb->nh.ipv6h->saddr,
-                                     &nskb->nh.ipv6h->daddr,
+       tcph->check = csum_ipv6_magic(&ipv6_hdr(nskb)->saddr,
+                                     &ipv6_hdr(nskb)->daddr,
                                      sizeof(struct tcphdr), IPPROTO_TCP,
                                      csum_partial((char *)tcph,
                                                   sizeof(struct tcphdr), 0));
 
        memset(eui64, 0, sizeof(eui64));
 
        if (eth_hdr(skb)->h_proto == htons(ETH_P_IPV6)) {
-               if (skb->nh.ipv6h->version == 0x6) {
+               if (ipv6_hdr(skb)->version == 0x6) {
                        memcpy(eui64, eth_hdr(skb)->h_source, 3);
                        memcpy(eui64 + 5, eth_hdr(skb)->h_source + 3, 3);
                        eui64[3] = 0xff;
                        eui64[0] |= 0x02;
 
                        i = 0;
-                       while ((skb->nh.ipv6h->saddr.s6_addr[8+i] == eui64[i])
+                       while ((ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i])
                               && (i < 8))
                                i++;
 
 
                 int offset, unsigned int protoff, int *hotdrop)
 {
        const struct ip6t_hl_info *info = matchinfo;
-       const struct ipv6hdr *ip6h = skb->nh.ipv6h;
+       const struct ipv6hdr *ip6h = ipv6_hdr(skb);
 
        switch (info->mode) {
                case IP6T_HL_EQ:
 
        /* Make sure this isn't an evil packet */
 
        /* type of the 1st exthdr */
-       nexthdr = skb->nh.ipv6h->nexthdr;
+       nexthdr = ipv6_hdr(skb)->nexthdr;
        /* pointer to the 1st exthdr */
        ptr = sizeof(struct ipv6hdr);
        /* available length */
 
 #endif
 
        /* save source/dest address, mark, hoplimit, flowlabel, priority,  */
-       memcpy(&saddr, &(*pskb)->nh.ipv6h->saddr, sizeof(saddr));
-       memcpy(&daddr, &(*pskb)->nh.ipv6h->daddr, sizeof(daddr));
+       memcpy(&saddr, &ipv6_hdr(*pskb)->saddr, sizeof(saddr));
+       memcpy(&daddr, &ipv6_hdr(*pskb)->daddr, sizeof(daddr));
        mark = (*pskb)->mark;
-       hop_limit = (*pskb)->nh.ipv6h->hop_limit;
+       hop_limit = ipv6_hdr(*pskb)->hop_limit;
 
        /* flowlabel and prio (includes version, which shouldn't change either */
-       flowlabel = *((u_int32_t *) (*pskb)->nh.ipv6h);
+       flowlabel = *((u_int32_t *)ipv6_hdr(*pskb));
 
        ret = ip6t_do_table(pskb, hook, in, out, &packet_mangler);
 
        if (ret != NF_DROP && ret != NF_STOLEN
-               && (memcmp(&(*pskb)->nh.ipv6h->saddr, &saddr, sizeof(saddr))
-                   || memcmp(&(*pskb)->nh.ipv6h->daddr, &daddr, sizeof(daddr))
+               && (memcmp(&ipv6_hdr(*pskb)->saddr, &saddr, sizeof(saddr))
+                   || memcmp(&ipv6_hdr(*pskb)->daddr, &daddr, sizeof(daddr))
                    || (*pskb)->mark != mark
-                   || (*pskb)->nh.ipv6h->hop_limit != hop_limit))
+                   || ipv6_hdr(*pskb)->hop_limit != hop_limit))
                return ip6_route_me_harder(*pskb) == 0 ? ret : NF_DROP;
 
        return ret;
 
 ipv6_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
             u_int8_t *protonum)
 {
-       unsigned int extoff;
-       unsigned char pnum;
-       int protoff;
-
-       extoff = (u8*)((*pskb)->nh.ipv6h + 1) - (*pskb)->data;
-       pnum = (*pskb)->nh.ipv6h->nexthdr;
-
-       protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
-                                        (*pskb)->len - extoff);
-
+       unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data;
+       unsigned char pnum = ipv6_hdr(*pskb)->nexthdr;
+       int protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
+                                            (*pskb)->len - extoff);
        /*
         * (protoff == (*pskb)->len) mean that the packet doesn't have no data
         * except of IPv6 & ext headers. but it's tracked anyway. - YK
        struct nf_conn_help *help;
        enum ip_conntrack_info ctinfo;
        unsigned int ret, protoff;
-       unsigned int extoff = (u8*)((*pskb)->nh.ipv6h + 1)
-                             - (*pskb)->data;
-       unsigned char pnum = (*pskb)->nh.ipv6h->nexthdr;
+       unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data;
+       unsigned char pnum = ipv6_hdr(*pskb)->nexthdr;
 
 
        /* This is where we call the helper: as the packet goes out. */
 
        }
 
        offset = ntohs(fhdr->frag_off) & ~0x7;
-       end = offset + (ntohs(skb->nh.ipv6h->payload_len) -
-                       ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
+       end = offset + (ntohs(ipv6_hdr(skb)->payload_len) -
+                       ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
 
        if ((unsigned int)end > IPV6_MAXPLEN) {
                DEBUGP("offset is too large.\n");
        head->next = NULL;
        head->dev = dev;
        head->tstamp = fq->stamp;
-       head->nh.ipv6h->payload_len = htons(payload_len);
+       ipv6_hdr(head)->payload_len = htons(payload_len);
 
        /* Yes, and fold redundant checksum back. 8) */
        if (head->ip_summed == CHECKSUM_COMPLETE)
 static int
 find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
 {
-       u8 nexthdr = skb->nh.ipv6h->nexthdr;
-       u8 prev_nhoff = (u8 *)&skb->nh.ipv6h->nexthdr - skb->data;
-       int start = (u8 *)(skb->nh.ipv6h+1) - skb->data;
+       u8 nexthdr = ipv6_hdr(skb)->nexthdr;
+       u8 prev_nhoff = (u8 *)&ipv6_hdr(skb)->nexthdr - skb->data;
+       int start = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
        int len = skb->len - start;
        u8 prevhdr = NEXTHDR_IPV6;
 
        struct sk_buff *ret_skb = NULL;
 
        /* Jumbo payload inhibits frag. header */
-       if (skb->nh.ipv6h->payload_len == 0) {
+       if (ipv6_hdr(skb)->payload_len == 0) {
                DEBUGP("payload len = 0\n");
                return skb;
        }
        }
 
        clone->h.raw = clone->data + fhoff;
-       hdr = clone->nh.ipv6h;
+       hdr = ipv6_hdr(clone);
        fhdr = (struct frag_hdr *)clone->h.raw;
 
        if (!(fhdr->frag_off & htons(0xFFF9))) {
 
        int delivered = 0;
        __u8 hash;
 
-       saddr = &skb->nh.ipv6h->saddr;
+       saddr = &ipv6_hdr(skb)->saddr;
        daddr = saddr + 1;
 
        hash = nexthdr & (MAX_INET_PROTOS - 1);
        if (skb->ip_summed == CHECKSUM_COMPLETE) {
                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,
+               if (!csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+                                    &ipv6_hdr(skb)->daddr,
                                     skb->len, inet->num, skb->csum))
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
        }
        if (skb->ip_summed != CHECKSUM_UNNECESSARY)
-               skb->csum = ~csum_unfold(csum_ipv6_magic(&skb->nh.ipv6h->saddr,
-                                            &skb->nh.ipv6h->daddr,
-                                            skb->len, inet->num, 0));
+               skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+                                                        &ipv6_hdr(skb)->daddr,
+                                                        skb->len,
+                                                        inet->num, 0));
 
        if (inet->hdrincl) {
                if (skb_checksum_complete(skb)) {
        if (sin6) {
                sin6->sin6_family = AF_INET6;
                sin6->sin6_port = 0;
-               ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
+               ipv6_addr_copy(&sin6->sin6_addr, &ipv6_hdr(skb)->saddr);
                sin6->sin6_flowinfo = 0;
                sin6->sin6_scope_id = 0;
                if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
 
        skb_put(skb, length);
        skb_reset_network_header(skb);
-       iph = skb->nh.ipv6h;
+       iph = ipv6_hdr(skb);
 
        skb->ip_summed = CHECKSUM_NONE;
 
 
                goto err;
 
        offset = ntohs(fhdr->frag_off) & ~0x7;
-       end = offset + (ntohs(skb->nh.ipv6h->payload_len) -
-                       ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
+       end = offset + (ntohs(ipv6_hdr(skb)->payload_len) -
+                       ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
 
        if ((unsigned int)end > IPV6_MAXPLEN) {
                IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
        head->next = NULL;
        head->dev = dev;
        head->tstamp = fq->stamp;
-       head->nh.ipv6h->payload_len = htons(payload_len);
+       ipv6_hdr(head)->payload_len = htons(payload_len);
        IP6CB(head)->nhoff = nhoff;
 
        *skb_in = head;
        struct net_device *dev = skb->dev;
        struct frag_hdr *fhdr;
        struct frag_queue *fq;
-       struct ipv6hdr *hdr;
-
-       hdr = skb->nh.ipv6h;
+       struct ipv6hdr *hdr = ipv6_hdr(skb);
 
        IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMREQDS);
 
                return -1;
        }
 
-       hdr = skb->nh.ipv6h;
+       hdr = ipv6_hdr(skb);
        fhdr = (struct frag_hdr *)skb->h.raw;
 
        if (!(fhdr->frag_off & htons(0xFFF9))) {
 
 
 void ip6_route_input(struct sk_buff *skb)
 {
-       struct ipv6hdr *iph = skb->nh.ipv6h;
+       struct ipv6hdr *iph = ipv6_hdr(skb);
        int flags = RT6_LOOKUP_F_HAS_SADDR;
        struct flowi fl = {
                .iif = skb->dev->ifindex,
        int type;
        switch (ipstats_mib_noroutes) {
        case IPSTATS_MIB_INNOROUTES:
-               type = ipv6_addr_type(&skb->nh.ipv6h->daddr);
+               type = ipv6_addr_type(&ipv6_hdr(skb)->daddr);
                if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) {
                        IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS);
                        break;
 
 static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
 {
        if (INET_ECN_is_ce(iph->tos))
-               IP6_ECN_set_ce(skb->nh.ipv6h);
+               IP6_ECN_set_ce(ipv6_hdr(skb));
 }
 
 static int ipip6_rcv(struct sk_buff *skb)
        struct ip_tunnel *tunnel = netdev_priv(dev);
        struct net_device_stats *stats = &tunnel->stat;
        struct iphdr  *tiph = &tunnel->parms.iph;
-       struct ipv6hdr *iph6 = skb->nh.ipv6h;
+       struct ipv6hdr *iph6 = ipv6_hdr(skb);
        u8     tos = tunnel->parms.iph.tos;
        struct rtable *rt;                      /* Route to the other host */
        struct net_device *tdev;                        /* Device to other host */
                addr_type = ipv6_addr_type(addr6);
 
                if (addr_type == IPV6_ADDR_ANY) {
-                       addr6 = &skb->nh.ipv6h->daddr;
+                       addr6 = &ipv6_hdr(skb)->daddr;
                        addr_type = ipv6_addr_type(addr6);
                }
 
                        skb_set_owner_w(new_skb, skb->sk);
                dev_kfree_skb(skb);
                skb = new_skb;
-               iph6 = skb->nh.ipv6h;
+               iph6 = ipv6_hdr(skb);
        }
 
        skb->h.raw = skb->nh.raw;
 
 
 static __u32 tcp_v6_init_sequence(struct sk_buff *skb)
 {
-       return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
-                                           skb->nh.ipv6h->saddr.s6_addr32,
+       return secure_tcpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32,
+                                           ipv6_hdr(skb)->saddr.s6_addr32,
                                            skb->h.th->dest,
                                            skb->h.th->source);
 }
 {
        __u8 *hash_location = NULL;
        struct tcp_md5sig_key *hash_expected;
-       struct ipv6hdr *ip6h = skb->nh.ipv6h;
+       struct ipv6hdr *ip6h = ipv6_hdr(skb);
        struct tcphdr *th = skb->h.th;
        int length = (th->doff << 2) - sizeof (*th);
        int genhash;
        if (!pskb_may_pull(skb, sizeof(*th)))
                return -EINVAL;
 
-       ipv6h = skb->nh.ipv6h;
+       ipv6h = ipv6_hdr(skb);
        th = skb->h.th;
 
        th->check = 0;
 
 #ifdef CONFIG_TCP_MD5SIG
        if (sk)
-               key = tcp_v6_md5_do_lookup(sk, &skb->nh.ipv6h->daddr);
+               key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr);
        else
                key = NULL;
 
                               (TCPOPT_NOP << 16) |
                               (TCPOPT_MD5SIG << 8) |
                               TCPOLEN_MD5SIG);
-               tcp_v6_do_calc_md5_hash((__u8*)&opt[1],
-                                       key,
-                                       &skb->nh.ipv6h->daddr,
-                                       &skb->nh.ipv6h->saddr,
-                                       t1, IPPROTO_TCP,
-                                       tot_len);
+               tcp_v6_do_calc_md5_hash((__u8 *)&opt[1], key,
+                                       &ipv6_hdr(skb)->daddr,
+                                       &ipv6_hdr(skb)->saddr,
+                                       t1, IPPROTO_TCP, tot_len);
        }
 #endif
 
        buff->csum = csum_partial((char *)t1, sizeof(*t1), 0);
 
        memset(&fl, 0, sizeof(fl));
-       ipv6_addr_copy(&fl.fl6_dst, &skb->nh.ipv6h->saddr);
-       ipv6_addr_copy(&fl.fl6_src, &skb->nh.ipv6h->daddr);
+       ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
+       ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr);
 
        t1->check = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst,
                                    sizeof(*t1), IPPROTO_TCP,
 
 #ifdef CONFIG_TCP_MD5SIG
        if (!tw && skb->sk) {
-               key = tcp_v6_md5_do_lookup(skb->sk, &skb->nh.ipv6h->daddr);
+               key = tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr);
        } else if (tw && tw->tw_md5_keylen) {
                tw_key.key = tw->tw_md5_key;
                tw_key.keylen = tw->tw_md5_keylen;
        if (key) {
                *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
                                (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
-               tcp_v6_do_calc_md5_hash((__u8 *)topt,
-                                       key,
-                                       &skb->nh.ipv6h->daddr,
-                                       &skb->nh.ipv6h->saddr,
-                                       t1, IPPROTO_TCP,
-                                       tot_len);
+               tcp_v6_do_calc_md5_hash((__u8 *)topt, key,
+                                       &ipv6_hdr(skb)->daddr,
+                                       &ipv6_hdr(skb)->saddr,
+                                       t1, IPPROTO_TCP, tot_len);
        }
 #endif
 
        buff->csum = csum_partial((char *)t1, tot_len, 0);
 
        memset(&fl, 0, sizeof(fl));
-       ipv6_addr_copy(&fl.fl6_dst, &skb->nh.ipv6h->saddr);
-       ipv6_addr_copy(&fl.fl6_src, &skb->nh.ipv6h->daddr);
+       ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
+       ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr);
 
        t1->check = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst,
                                    tot_len, IPPROTO_TCP,
 
        /* Find possible connection requests. */
        req = inet6_csk_search_req(sk, &prev, th->source,
-                                  &skb->nh.ipv6h->saddr,
-                                  &skb->nh.ipv6h->daddr, inet6_iif(skb));
+                                  &ipv6_hdr(skb)->saddr,
+                                  &ipv6_hdr(skb)->daddr, inet6_iif(skb));
        if (req)
                return tcp_check_req(sk, skb, req, prev);
 
-       nsk = __inet6_lookup_established(&tcp_hashinfo, &skb->nh.ipv6h->saddr,
-                                        th->source, &skb->nh.ipv6h->daddr,
+       nsk = __inet6_lookup_established(&tcp_hashinfo, &ipv6_hdr(skb)->saddr,
+                                        th->source, &ipv6_hdr(skb)->daddr,
                                         ntohs(th->dest), inet6_iif(skb));
 
        if (nsk) {
        tcp_openreq_init(req, &tmp_opt, skb);
 
        treq = inet6_rsk(req);
-       ipv6_addr_copy(&treq->rmt_addr, &skb->nh.ipv6h->saddr);
-       ipv6_addr_copy(&treq->loc_addr, &skb->nh.ipv6h->daddr);
+       ipv6_addr_copy(&treq->rmt_addr, &ipv6_hdr(skb)->saddr);
+       ipv6_addr_copy(&treq->loc_addr, &ipv6_hdr(skb)->daddr);
        TCP_ECN_create_request(req, skb->h.th);
        treq->pktopts = NULL;
        if (ipv6_opt_accepted(sk, skb) ||
                newnp->pktoptions  = NULL;
                newnp->opt         = NULL;
                newnp->mcast_oif   = inet6_iif(skb);
-               newnp->mcast_hops  = skb->nh.ipv6h->hop_limit;
+               newnp->mcast_hops  = ipv6_hdr(skb)->hop_limit;
 
                /*
                 * No need to charge this sock to the relevant IPv6 refcnt debug socks count
        }
        newnp->opt        = NULL;
        newnp->mcast_oif  = inet6_iif(skb);
-       newnp->mcast_hops = skb->nh.ipv6h->hop_limit;
+       newnp->mcast_hops = ipv6_hdr(skb)->hop_limit;
 
        /* Clone native IPv6 options from listening socket (if any)
 
 static __sum16 tcp_v6_checksum_init(struct sk_buff *skb)
 {
        if (skb->ip_summed == CHECKSUM_COMPLETE) {
-               if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
-                                 &skb->nh.ipv6h->daddr,skb->csum)) {
+               if (!tcp_v6_check(skb->h.th, skb->len, &ipv6_hdr(skb)->saddr,
+                                 &ipv6_hdr(skb)->daddr, skb->csum)) {
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
                        return 0;
                }
        }
 
-       skb->csum = ~csum_unfold(tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
-                                 &skb->nh.ipv6h->daddr, 0));
+       skb->csum = ~csum_unfold(tcp_v6_check(skb->h.th, skb->len,
+                                             &ipv6_hdr(skb)->saddr,
+                                             &ipv6_hdr(skb)->daddr, 0));
 
        if (skb->len <= 76) {
                return __skb_checksum_complete(skb);
                if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo)
                        np->mcast_oif = inet6_iif(opt_skb);
                if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
-                       np->mcast_hops = opt_skb->nh.ipv6h->hop_limit;
+                       np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit;
                if (ipv6_opt_accepted(sk, opt_skb)) {
                        skb_set_owner_r(opt_skb, sk);
                        opt_skb = xchg(&np->pktoptions, opt_skb);
                                    skb->len - th->doff*4);
        TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
        TCP_SKB_CB(skb)->when = 0;
-       TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(skb->nh.ipv6h);
+       TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb));
        TCP_SKB_CB(skb)->sacked = 0;
 
-       sk = __inet6_lookup(&tcp_hashinfo, &skb->nh.ipv6h->saddr, th->source,
-                           &skb->nh.ipv6h->daddr, ntohs(th->dest),
+       sk = __inet6_lookup(&tcp_hashinfo, &ipv6_hdr(skb)->saddr, th->source,
+                           &ipv6_hdr(skb)->daddr, ntohs(th->dest),
                            inet6_iif(skb));
 
        if (!sk)
                struct sock *sk2;
 
                sk2 = inet6_lookup_listener(&tcp_hashinfo,
-                                           &skb->nh.ipv6h->daddr,
+                                           &ipv6_hdr(skb)->daddr,
                                            ntohs(th->dest), inet6_iif(skb));
                if (sk2 != NULL) {
                        struct inet_timewait_sock *tw = inet_twsk(sk);
 
                        ipv6_addr_set(&sin6->sin6_addr, 0, 0,
                                      htonl(0xffff), ip_hdr(skb)->saddr);
                else {
-                       ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
+                       ipv6_addr_copy(&sin6->sin6_addr,
+                                      &ipv6_hdr(skb)->saddr);
                        if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
                                sin6->sin6_scope_id = IP6CB(skb)->iif;
                }
                return 1;
        }
        if (skb->ip_summed == CHECKSUM_COMPLETE &&
-           !csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
+           !csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
                             skb->len, proto, skb->csum))
                skb->ip_summed = CHECKSUM_UNNECESSARY;
 
        if (skb->ip_summed != CHECKSUM_UNNECESSARY)
-               skb->csum = ~csum_unfold(csum_ipv6_magic(&skb->nh.ipv6h->saddr,
-                                                        &skb->nh.ipv6h->daddr,
+               skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+                                                        &ipv6_hdr(skb)->daddr,
                                                         skb->len, proto, 0));
 
        return 0;
        if (!pskb_may_pull(skb, sizeof(struct udphdr)))
                goto short_packet;
 
-       saddr = &skb->nh.ipv6h->saddr;
-       daddr = &skb->nh.ipv6h->daddr;
+       saddr = &ipv6_hdr(skb)->saddr;
+       daddr = &ipv6_hdr(skb)->daddr;
        uh = skb->h.uh;
 
        ulen = ntohs(uh->len);
                if (ulen < skb->len) {
                        if (pskb_trim_rcsum(skb, ulen))
                                goto short_packet;
-                       saddr = &skb->nh.ipv6h->saddr;
-                       daddr = &skb->nh.ipv6h->daddr;
+                       saddr = &ipv6_hdr(skb)->saddr;
+                       daddr = &ipv6_hdr(skb)->daddr;
                        uh = skb->h.uh;
                }
        }
 
                goto drop;
 
        do {
-               struct ipv6hdr *iph = skb->nh.ipv6h;
+               struct ipv6hdr *iph = ipv6_hdr(skb);
 
                if (xfrm_nr == XFRM_MAX_DEPTH)
                        goto drop;
                return -1;
        } else {
 #ifdef CONFIG_NETFILTER
-               skb->nh.ipv6h->payload_len = htons(skb->len);
+               ipv6_hdr(skb)->payload_len = htons(skb->len);
                __skb_push(skb, skb->data - skb_network_header(skb));
 
                NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
 
        int hdr_len;
 
        skb_push(skb, x->props.header_len);
-       iph = skb->nh.ipv6h;
+       iph = ipv6_hdr(skb);
 
        hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
        skb->nh.raw = prevhdr - x->props.header_len;
        memmove(skb->data, iph, hdr_len);
 
        skb_reset_network_header(skb);
-       top_iph = skb->nh.ipv6h;
+       top_iph = ipv6_hdr(skb);
        skb->nh.raw = &top_iph->nexthdr;
        skb->h.ipv6h = top_iph + 1;
 
        skb_set_mac_header(skb, -skb->mac_len);
        memmove(skb_mac_header(skb), old_mac, skb->mac_len);
 
-       ip6h = skb->nh.ipv6h;
+       ip6h = ipv6_hdr(skb);
        ip6h->payload_len = htons(skb->len - size);
        ipv6_addr_copy(&ip6h->daddr, (struct in6_addr *) &x->sel.daddr.a6);
        ipv6_addr_copy(&ip6h->saddr, (struct in6_addr *) &x->sel.saddr.a6);
 
        int hdr_len;
 
        skb_push(skb, x->props.header_len);
-       iph = skb->nh.ipv6h;
+       iph = ipv6_hdr(skb);
 
        hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
        skb->nh.raw = prevhdr - x->props.header_len;
 
        int hdr_len;
 
        skb_push(skb, x->props.header_len);
-       iph = skb->nh.ipv6h;
+       iph = ipv6_hdr(skb);
 
        hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
        skb->nh.raw = prevhdr - x->props.header_len;
                memmove(skb->h.raw, skb_network_header(skb), ihl);
                skb->nh.raw = skb->h.raw;
        }
-       skb->nh.ipv6h->payload_len = htons(skb->len + ihl -
+       ipv6_hdr(skb)->payload_len = htons(skb->len + ihl -
                                           sizeof(struct ipv6hdr));
        skb->h.raw = skb->data;
        return 0;
 
 
 static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
 {
-       struct ipv6hdr *outer_iph = skb->nh.ipv6h;
+       struct ipv6hdr *outer_iph = ipv6_hdr(skb);
        struct ipv6hdr *inner_iph = skb->h.ipv6h;
 
        if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph)))
 
 static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb)
 {
-       if (INET_ECN_is_ce(ipv6_get_dsfield(skb->nh.ipv6h)))
+       if (INET_ECN_is_ce(ipv6_get_dsfield(ipv6_hdr(skb))))
                        IP_ECN_set_ce(skb->h.ipiph);
 }
 
        int dsfield;
 
        skb_push(skb, x->props.header_len);
-       iph = skb->nh.ipv6h;
+       iph = ipv6_hdr(skb);
 
        skb_reset_network_header(skb);
-       top_iph = skb->nh.ipv6h;
+       top_iph = ipv6_hdr(skb);
        skb->nh.raw = &top_iph->nexthdr;
        skb->h.ipv6h = top_iph + 1;
 
        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);
+                       ipv6_copy_dscp(ipv6_hdr(skb), skb->h.ipv6h);
                if (!(x->props.flags & XFRM_STATE_NOECN))
                        ipip6_ecn_decapsulate(skb);
        } else {
 
 _decode_session6(struct sk_buff *skb, struct flowi *fl)
 {
        u16 offset = skb->h.raw - skb->nh.raw;
-       struct ipv6hdr *hdr = skb->nh.ipv6h;
+       struct ipv6hdr *hdr = ipv6_hdr(skb);
        struct ipv6_opt_hdr *exthdr;
        const unsigned char *nh = skb_network_header(skb);
        u8 nexthdr = nh[IP6CB(skb)->nhoff];
 
 
 static int xfrm6_tunnel_rcv(struct sk_buff *skb)
 {
-       struct ipv6hdr *iph = skb->nh.ipv6h;
+       struct ipv6hdr *iph = ipv6_hdr(skb);
        __be32 spi;
 
        spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
 
                            const void *targinfo)
 {
        const struct xt_DSCP_info *dinfo = targinfo;
-       u_int8_t dscp = ipv6_get_dsfield((*pskb)->nh.ipv6h) >> XT_DSCP_SHIFT;
+       u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(*pskb)) >> XT_DSCP_SHIFT;
 
        if (dscp != dinfo->dscp) {
                if (!skb_make_writable(pskb, sizeof(struct ipv6hdr)))
                        return NF_DROP;
 
-               ipv6_change_dsfield((*pskb)->nh.ipv6h, (__u8)(~XT_DSCP_MASK),
+               ipv6_change_dsfield(ipv6_hdr(*pskb), (__u8)(~XT_DSCP_MASK),
                                    dinfo->dscp << XT_DSCP_SHIFT);
        }
        return XT_CONTINUE;
 
                  const struct xt_target *target,
                  const void *targinfo)
 {
-       struct ipv6hdr *ipv6h = (*pskb)->nh.ipv6h;
+       struct ipv6hdr *ipv6h = ipv6_hdr(*pskb);
        u8 nexthdr;
        int tcphoff;
        int ret;
        if (ret < 0)
                return NF_DROP;
        if (ret > 0) {
-               ipv6h = (*pskb)->nh.ipv6h;
+               ipv6h = ipv6_hdr(*pskb);
                ipv6h->payload_len = htons(ntohs(ipv6h->payload_len) + ret);
        }
        return XT_CONTINUE;
 
                  int *hotdrop)
 {
        const struct xt_dscp_info *info = matchinfo;
-       u_int8_t dscp = ipv6_get_dsfield(skb->nh.ipv6h) >> XT_DSCP_SHIFT;
+       u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
 
        return (dscp == info->dscp) ^ !!info->invert;
 }
 
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
        case AF_INET6:
                if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP)
-                       memcpy(&dst->addr.ip6.dst, &skb->nh.ipv6h->daddr,
+                       memcpy(&dst->addr.ip6.dst, &ipv6_hdr(skb)->daddr,
                               sizeof(dst->addr.ip6.dst));
                if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP)
-                       memcpy(&dst->addr.ip6.src, &skb->nh.ipv6h->saddr,
+                       memcpy(&dst->addr.ip6.src, &ipv6_hdr(skb)->saddr,
                               sizeof(dst->addr.ip6.src));
 
                if (!(hinfo->cfg.mode &
 
        int *hotdrop)
 {
        const struct xt_length_info *info = matchinfo;
-       u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr);
+       const u_int16_t pktlen = (ntohs(ipv6_hdr(skb)->payload_len) +
+                                 sizeof(struct ipv6hdr));
 
        return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
 }
 
        u8 tunnelid = 0;
        u8 *xprt;
 #if RSVP_DST_LEN == 4
-       struct ipv6hdr *nhptr = skb->nh.ipv6h;
+       struct ipv6hdr *nhptr = ipv6_hdr(skb);
 #else
        struct iphdr *nhptr = ip_hdr(skb);
 #endif
 
                                        & ~INET_ECN_MASK;
                                break;
                        case __constant_htons(ETH_P_IPV6):
-                               skb->tc_index = ipv6_get_dsfield(skb->nh.ipv6h)
+                               skb->tc_index = ipv6_get_dsfield(ipv6_hdr(skb))
                                        & ~INET_ECN_MASK;
                                break;
                        default:
                                            p->value[index]);
                        break;
                case __constant_htons(ETH_P_IPV6):
-                       ipv6_change_dsfield(skb->nh.ipv6h, p->mask[index],
+                       ipv6_change_dsfield(ipv6_hdr(skb), p->mask[index],
                                            p->value[index]);
                        break;
                default:
 
        }
        case __constant_htons(ETH_P_IPV6):
        {
-               struct ipv6hdr *iph = skb->nh.ipv6h;
+               struct ipv6hdr *iph = ipv6_hdr(skb);
                h = iph->daddr.s6_addr32[3];
                h2 = iph->saddr.s6_addr32[3]^iph->nexthdr;
                if (iph->nexthdr == IPPROTO_TCP ||
 
        sh = (struct sctphdr *) skb->h.raw;
        if (is_saddr) {
                *port  = sh->source;
-               from = &skb->nh.ipv6h->saddr;
+               from = &ipv6_hdr(skb)->saddr;
        } else {
                *port = sh->dest;
-               from = &skb->nh.ipv6h->daddr;
+               from = &ipv6_hdr(skb)->daddr;
        }
        ipv6_addr_copy(&addr->v6.sin6_addr, from);
 }
 /* Was this packet marked by Explicit Congestion Notification? */
 static int sctp_v6_is_ce(const struct sk_buff *skb)
 {
-       return *((__u32 *)(skb->nh.ipv6h)) & htonl(1<<20);
+       return *((__u32 *)(ipv6_hdr(skb))) & htonl(1 << 20);
 }
 
 /* Dump the v6 addr to the seq file. */
                }
 
                /* Otherwise, just copy the v6 address. */
-               ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
+               ipv6_addr_copy(&sin6->sin6_addr, &ipv6_hdr(skb)->saddr);
                if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
                        struct sctp_ulpevent *ev = sctp_skb2event(skb);
                        sin6->sin6_scope_id = ev->iif;