aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/af_inet6.c3
-rw-r--r--net/ipv6/ah6.c12
-rw-r--r--net/ipv6/datagram.c31
-rw-r--r--net/ipv6/esp6.c4
-rw-r--r--net/ipv6/exthdrs.c56
-rw-r--r--net/ipv6/icmp.c3
-rw-r--r--net/ipv6/ip6_input.c4
-rw-r--r--net/ipv6/ip6_output.c23
-rw-r--r--net/ipv6/ip6_tunnel.c5
-rw-r--r--net/ipv6/ipcomp6.c4
-rw-r--r--net/ipv6/mip6.c29
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c19
-rw-r--r--net/ipv6/raw.c5
-rw-r--r--net/ipv6/reassembly.c25
-rw-r--r--net/ipv6/tcp_ipv6.c8
-rw-r--r--net/ipv6/xfrm6_input.c6
-rw-r--r--net/ipv6/xfrm6_mode_beet.c2
-rw-r--r--net/ipv6/xfrm6_mode_transport.c6
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c8
-rw-r--r--net/ipv6/xfrm6_policy.c16
20 files changed, 161 insertions, 108 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 2ff070417955..7b917f856e1c 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -693,7 +693,8 @@ int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
693 if (np->rxopt.all) { 693 if (np->rxopt.all) {
694 if ((opt->hop && (np->rxopt.bits.hopopts || 694 if ((opt->hop && (np->rxopt.bits.hopopts ||
695 np->rxopt.bits.ohopopts)) || 695 np->rxopt.bits.ohopopts)) ||
696 ((IPV6_FLOWINFO_MASK & *(__be32*)skb->nh.raw) && 696 ((IPV6_FLOWINFO_MASK &
697 *(__be32 *)skb_network_header(skb)) &&
697 np->rxopt.bits.rxflow) || 698 np->rxopt.bits.rxflow) ||
698 (opt->srcrt && (np->rxopt.bits.srcrt || 699 (opt->srcrt && (np->rxopt.bits.srcrt ||
699 np->rxopt.bits.osrcrt)) || 700 np->rxopt.bits.osrcrt)) ||
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index dc68b7269c3c..1c914386982f 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -238,8 +238,8 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
238 top_iph = (struct ipv6hdr *)skb->data; 238 top_iph = (struct ipv6hdr *)skb->data;
239 top_iph->payload_len = htons(skb->len - sizeof(*top_iph)); 239 top_iph->payload_len = htons(skb->len - sizeof(*top_iph));
240 240
241 nexthdr = *skb->nh.raw; 241 nexthdr = *skb_network_header(skb);
242 *skb->nh.raw = IPPROTO_AH; 242 *skb_network_header(skb) = IPPROTO_AH;
243 243
244 /* When there are no extension headers, we only need to save the first 244 /* When there are no extension headers, we only need to save the first
245 * 8 bytes of the base IP header. 245 * 8 bytes of the base IP header.
@@ -341,7 +341,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
341 pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) 341 pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
342 goto out; 342 goto out;
343 343
344 hdr_len = skb->data - skb->nh.raw; 344 hdr_len = skb->data - skb_network_header(skb);
345 ah = (struct ipv6_auth_hdr*)skb->data; 345 ah = (struct ipv6_auth_hdr*)skb->data;
346 ahp = x->data; 346 ahp = x->data;
347 nexthdr = ah->nexthdr; 347 nexthdr = ah->nexthdr;
@@ -354,7 +354,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
354 if (!pskb_may_pull(skb, ah_hlen)) 354 if (!pskb_may_pull(skb, ah_hlen))
355 goto out; 355 goto out;
356 356
357 tmp_hdr = kmemdup(skb->nh.raw, hdr_len, GFP_ATOMIC); 357 tmp_hdr = kmemdup(skb_network_header(skb), hdr_len, GFP_ATOMIC);
358 if (!tmp_hdr) 358 if (!tmp_hdr)
359 goto out; 359 goto out;
360 if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len, XFRM_POLICY_IN)) 360 if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len, XFRM_POLICY_IN))
@@ -382,7 +382,9 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
382 } 382 }
383 } 383 }
384 384
385 skb->h.raw = memcpy(skb->nh.raw += ah_hlen, tmp_hdr, hdr_len); 385 skb->nh.raw += ah_hlen;
386 memcpy(skb_network_header(skb), tmp_hdr, hdr_len);
387 skb->h.raw = skb->nh.raw;
386 __skb_pull(skb, ah_hlen + hdr_len); 388 __skb_pull(skb, ah_hlen + hdr_len);
387 389
388 kfree(tmp_hdr); 390 kfree(tmp_hdr);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 31a20f17c854..7a86db6163ee 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -227,7 +227,8 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
227 serr->ee.ee_pad = 0; 227 serr->ee.ee_pad = 0;
228 serr->ee.ee_info = info; 228 serr->ee.ee_info = info;
229 serr->ee.ee_data = 0; 229 serr->ee.ee_data = 0;
230 serr->addr_offset = (u8*)&(((struct ipv6hdr*)(icmph+1))->daddr) - skb->nh.raw; 230 serr->addr_offset = (u8 *)&(((struct ipv6hdr *)(icmph + 1))->daddr) -
231 skb_network_header(skb);
231 serr->port = port; 232 serr->port = port;
232 233
233 skb->h.raw = payload; 234 skb->h.raw = payload;
@@ -264,7 +265,7 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info)
264 serr->ee.ee_pad = 0; 265 serr->ee.ee_pad = 0;
265 serr->ee.ee_info = info; 266 serr->ee.ee_info = info;
266 serr->ee.ee_data = 0; 267 serr->ee.ee_data = 0;
267 serr->addr_offset = (u8*)&iph->daddr - skb->nh.raw; 268 serr->addr_offset = (u8 *)&iph->daddr - skb_network_header(skb);
268 serr->port = fl->fl_ip_dport; 269 serr->port = fl->fl_ip_dport;
269 270
270 skb->h.raw = skb->tail; 271 skb->h.raw = skb->tail;
@@ -310,21 +311,24 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
310 311
311 sin = (struct sockaddr_in6 *)msg->msg_name; 312 sin = (struct sockaddr_in6 *)msg->msg_name;
312 if (sin) { 313 if (sin) {
314 const unsigned char *nh = skb_network_header(skb);
313 sin->sin6_family = AF_INET6; 315 sin->sin6_family = AF_INET6;
314 sin->sin6_flowinfo = 0; 316 sin->sin6_flowinfo = 0;
315 sin->sin6_port = serr->port; 317 sin->sin6_port = serr->port;
316 sin->sin6_scope_id = 0; 318 sin->sin6_scope_id = 0;
317 if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) { 319 if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
318 ipv6_addr_copy(&sin->sin6_addr, 320 ipv6_addr_copy(&sin->sin6_addr,
319 (struct in6_addr *)(skb->nh.raw + serr->addr_offset)); 321 (struct in6_addr *)(nh + serr->addr_offset));
320 if (np->sndflow) 322 if (np->sndflow)
321 sin->sin6_flowinfo = *(__be32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK; 323 sin->sin6_flowinfo =
324 (*(__be32 *)(nh + serr->addr_offset - 24) &
325 IPV6_FLOWINFO_MASK);
322 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) 326 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
323 sin->sin6_scope_id = IP6CB(skb)->iif; 327 sin->sin6_scope_id = IP6CB(skb)->iif;
324 } else { 328 } else {
325 ipv6_addr_set(&sin->sin6_addr, 0, 0, 329 ipv6_addr_set(&sin->sin6_addr, 0, 0,
326 htonl(0xffff), 330 htonl(0xffff),
327 *(__be32*)(skb->nh.raw + serr->addr_offset)); 331 *(__be32 *)(nh + serr->addr_offset));
328 } 332 }
329 } 333 }
330 334
@@ -382,6 +386,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
382{ 386{
383 struct ipv6_pinfo *np = inet6_sk(sk); 387 struct ipv6_pinfo *np = inet6_sk(sk);
384 struct inet6_skb_parm *opt = IP6CB(skb); 388 struct inet6_skb_parm *opt = IP6CB(skb);
389 unsigned char *nh = skb_network_header(skb);
385 390
386 if (np->rxopt.bits.rxinfo) { 391 if (np->rxopt.bits.rxinfo) {
387 struct in6_pktinfo src_info; 392 struct in6_pktinfo src_info;
@@ -401,14 +406,14 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
401 put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass); 406 put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
402 } 407 }
403 408
404 if (np->rxopt.bits.rxflow && (*(__be32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) { 409 if (np->rxopt.bits.rxflow && (*(__be32 *)nh & IPV6_FLOWINFO_MASK)) {
405 __be32 flowinfo = *(__be32*)skb->nh.raw & IPV6_FLOWINFO_MASK; 410 __be32 flowinfo = *(__be32 *)nh & IPV6_FLOWINFO_MASK;
406 put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo); 411 put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
407 } 412 }
408 413
409 /* HbH is allowed only once */ 414 /* HbH is allowed only once */
410 if (np->rxopt.bits.hopopts && opt->hop) { 415 if (np->rxopt.bits.hopopts && opt->hop) {
411 u8 *ptr = skb->nh.raw + opt->hop; 416 u8 *ptr = nh + opt->hop;
412 put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr); 417 put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
413 } 418 }
414 419
@@ -428,7 +433,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
428 433
429 while (off <= opt->lastopt) { 434 while (off <= opt->lastopt) {
430 unsigned len; 435 unsigned len;
431 u8 *ptr = skb->nh.raw + off; 436 u8 *ptr = nh + off;
432 437
433 switch(nexthdr) { 438 switch(nexthdr) {
434 case IPPROTO_DSTOPTS: 439 case IPPROTO_DSTOPTS:
@@ -470,19 +475,19 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
470 put_cmsg(msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim); 475 put_cmsg(msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
471 } 476 }
472 if (np->rxopt.bits.ohopopts && opt->hop) { 477 if (np->rxopt.bits.ohopopts && opt->hop) {
473 u8 *ptr = skb->nh.raw + opt->hop; 478 u8 *ptr = nh + opt->hop;
474 put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, (ptr[1]+1)<<3, ptr); 479 put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, (ptr[1]+1)<<3, ptr);
475 } 480 }
476 if (np->rxopt.bits.odstopts && opt->dst0) { 481 if (np->rxopt.bits.odstopts && opt->dst0) {
477 u8 *ptr = skb->nh.raw + opt->dst0; 482 u8 *ptr = nh + opt->dst0;
478 put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr); 483 put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
479 } 484 }
480 if (np->rxopt.bits.osrcrt && opt->srcrt) { 485 if (np->rxopt.bits.osrcrt && opt->srcrt) {
481 struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(skb->nh.raw + opt->srcrt); 486 struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(nh + opt->srcrt);
482 put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, (rthdr->hdrlen+1) << 3, rthdr); 487 put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
483 } 488 }
484 if (np->rxopt.bits.odstopts && opt->dst1) { 489 if (np->rxopt.bits.odstopts && opt->dst1) {
485 u8 *ptr = skb->nh.raw + opt->dst1; 490 u8 *ptr = nh + opt->dst1;
486 put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr); 491 put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
487 } 492 }
488 return 0; 493 return 0;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 363e63ffecca..6e6b57ac8013 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -92,8 +92,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
92 top_iph = (struct ipv6hdr *)__skb_push(skb, hdr_len); 92 top_iph = (struct ipv6hdr *)__skb_push(skb, hdr_len);
93 esph = (struct ipv6_esp_hdr *)skb->h.raw; 93 esph = (struct ipv6_esp_hdr *)skb->h.raw;
94 top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph)); 94 top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph));
95 *(u8*)(trailer->tail - 1) = *skb->nh.raw; 95 *(u8 *)(trailer->tail - 1) = *skb_network_header(skb);
96 *skb->nh.raw = IPPROTO_ESP; 96 *skb_network_header(skb) = IPPROTO_ESP;
97 97
98 esph->spi = x->id.spi; 98 esph->spi = x->id.spi;
99 esph->seq_no = htonl(++x->replay.oseq); 99 esph->seq_no = htonl(++x->replay.oseq);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index fce5abde554f..9ebf120ba6d3 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -50,13 +50,14 @@
50 50
51int ipv6_find_tlv(struct sk_buff *skb, int offset, int type) 51int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
52{ 52{
53 int packet_len = skb->tail - skb->nh.raw; 53 const unsigned char *nh = skb_network_header(skb);
54 int packet_len = skb->tail - nh;
54 struct ipv6_opt_hdr *hdr; 55 struct ipv6_opt_hdr *hdr;
55 int len; 56 int len;
56 57
57 if (offset + 2 > packet_len) 58 if (offset + 2 > packet_len)
58 goto bad; 59 goto bad;
59 hdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); 60 hdr = (struct ipv6_opt_hdr *)(nh + offset);
60 len = ((hdr->hdrlen + 1) << 3); 61 len = ((hdr->hdrlen + 1) << 3);
61 62
62 if (offset + len > packet_len) 63 if (offset + len > packet_len)
@@ -66,7 +67,7 @@ int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
66 len -= 2; 67 len -= 2;
67 68
68 while (len > 0) { 69 while (len > 0) {
69 int opttype = skb->nh.raw[offset]; 70 int opttype = nh[offset];
70 int optlen; 71 int optlen;
71 72
72 if (opttype == type) 73 if (opttype == type)
@@ -77,7 +78,7 @@ int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
77 optlen = 1; 78 optlen = 1;
78 break; 79 break;
79 default: 80 default:
80 optlen = skb->nh.raw[offset + 1] + 2; 81 optlen = nh[offset + 1] + 2;
81 if (optlen > len) 82 if (optlen > len)
82 goto bad; 83 goto bad;
83 break; 84 break;
@@ -113,7 +114,7 @@ static int ip6_tlvopt_unknown(struct sk_buff **skbp, int optoff)
113{ 114{
114 struct sk_buff *skb = *skbp; 115 struct sk_buff *skb = *skbp;
115 116
116 switch ((skb->nh.raw[optoff] & 0xC0) >> 6) { 117 switch ((skb_network_header(skb)[optoff] & 0xC0) >> 6) {
117 case 0: /* ignore */ 118 case 0: /* ignore */
118 return 1; 119 return 1;
119 120
@@ -141,6 +142,7 @@ static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
141{ 142{
142 struct sk_buff *skb = *skbp; 143 struct sk_buff *skb = *skbp;
143 struct tlvtype_proc *curr; 144 struct tlvtype_proc *curr;
145 const unsigned char *nh = skb_network_header(skb);
144 int off = skb->h.raw - skb->nh.raw; 146 int off = skb->h.raw - skb->nh.raw;
145 int len = ((skb->h.raw[1]+1)<<3); 147 int len = ((skb->h.raw[1]+1)<<3);
146 148
@@ -151,9 +153,9 @@ static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
151 len -= 2; 153 len -= 2;
152 154
153 while (len > 0) { 155 while (len > 0) {
154 int optlen = skb->nh.raw[off+1]+2; 156 int optlen = nh[off + 1] + 2;
155 157
156 switch (skb->nh.raw[off]) { 158 switch (nh[off]) {
157 case IPV6_TLV_PAD0: 159 case IPV6_TLV_PAD0:
158 optlen = 1; 160 optlen = 1;
159 break; 161 break;
@@ -165,7 +167,7 @@ static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
165 if (optlen > len) 167 if (optlen > len)
166 goto bad; 168 goto bad;
167 for (curr=procs; curr->type >= 0; curr++) { 169 for (curr=procs; curr->type >= 0; curr++) {
168 if (curr->type == skb->nh.raw[off]) { 170 if (curr->type == nh[off]) {
169 /* type specific length/alignment 171 /* type specific length/alignment
170 checks will be performed in the 172 checks will be performed in the
171 func(). */ 173 func(). */
@@ -211,7 +213,7 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
211 opt->dsthao = opt->dst1; 213 opt->dsthao = opt->dst1;
212 opt->dst1 = 0; 214 opt->dst1 = 0;
213 215
214 hao = (struct ipv6_destopt_hao *)(skb->nh.raw + optoff); 216 hao = (struct ipv6_destopt_hao *)(skb_network_header(skb) + optoff);
215 217
216 if (hao->length != 16) { 218 if (hao->length != 16) {
217 LIMIT_NETDEBUG( 219 LIMIT_NETDEBUG(
@@ -244,8 +246,9 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
244 246
245 /* update all variable using below by copied skbuff */ 247 /* update all variable using below by copied skbuff */
246 *skbp = skb = skb2; 248 *skbp = skb = skb2;
247 hao = (struct ipv6_destopt_hao *)(skb2->nh.raw + optoff); 249 hao = (struct ipv6_destopt_hao *)(skb_network_header(skb2) +
248 ipv6h = (struct ipv6hdr *)skb2->nh.raw; 250 optoff);
251 ipv6h = skb2->nh.ipv6h;
249 } 252 }
250 253
251 if (skb->ip_summed == CHECKSUM_COMPLETE) 254 if (skb->ip_summed == CHECKSUM_COMPLETE)
@@ -406,7 +409,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
406 default: 409 default:
407 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 410 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
408 IPSTATS_MIB_INHDRERRORS); 411 IPSTATS_MIB_INHDRERRORS);
409 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw); 412 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
413 (&hdr->type) - skb_network_header(skb));
410 return -1; 414 return -1;
411 } 415 }
412 416
@@ -443,7 +447,7 @@ looped_back:
443 skb->h.raw += (hdr->hdrlen + 1) << 3; 447 skb->h.raw += (hdr->hdrlen + 1) << 3;
444 opt->dst0 = opt->dst1; 448 opt->dst0 = opt->dst1;
445 opt->dst1 = 0; 449 opt->dst1 = 0;
446 opt->nhoff = (&hdr->nexthdr) - skb->nh.raw; 450 opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
447 return 1; 451 return 1;
448 } 452 }
449 453
@@ -452,7 +456,9 @@ looped_back:
452 if (hdr->hdrlen & 0x01) { 456 if (hdr->hdrlen & 0x01) {
453 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 457 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
454 IPSTATS_MIB_INHDRERRORS); 458 IPSTATS_MIB_INHDRERRORS);
455 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw); 459 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
460 ((&hdr->hdrlen) -
461 skb_network_header(skb)));
456 return -1; 462 return -1;
457 } 463 }
458 break; 464 break;
@@ -479,7 +485,9 @@ looped_back:
479 if (hdr->segments_left > n) { 485 if (hdr->segments_left > n) {
480 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 486 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
481 IPSTATS_MIB_INHDRERRORS); 487 IPSTATS_MIB_INHDRERRORS);
482 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw); 488 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
489 ((&hdr->segments_left) -
490 skb_network_header(skb)));
483 return -1; 491 return -1;
484 } 492 }
485 493
@@ -547,7 +555,7 @@ looped_back:
547 dst_release(xchg(&skb->dst, NULL)); 555 dst_release(xchg(&skb->dst, NULL));
548 ip6_route_input(skb); 556 ip6_route_input(skb);
549 if (skb->dst->error) { 557 if (skb->dst->error) {
550 skb_push(skb, skb->data - skb->nh.raw); 558 skb_push(skb, skb->data - skb_network_header(skb));
551 dst_input(skb); 559 dst_input(skb);
552 return -1; 560 return -1;
553 } 561 }
@@ -565,7 +573,7 @@ looped_back:
565 goto looped_back; 573 goto looped_back;
566 } 574 }
567 575
568 skb_push(skb, skb->data - skb->nh.raw); 576 skb_push(skb, skb->data - skb_network_header(skb));
569 dst_input(skb); 577 dst_input(skb);
570 return -1; 578 return -1;
571} 579}
@@ -656,13 +664,14 @@ EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
656static int ipv6_hop_ra(struct sk_buff **skbp, int optoff) 664static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
657{ 665{
658 struct sk_buff *skb = *skbp; 666 struct sk_buff *skb = *skbp;
667 const unsigned char *nh = skb_network_header(skb);
659 668
660 if (skb->nh.raw[optoff+1] == 2) { 669 if (nh[optoff + 1] == 2) {
661 IP6CB(skb)->ra = optoff; 670 IP6CB(skb)->ra = optoff;
662 return 1; 671 return 1;
663 } 672 }
664 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n", 673 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
665 skb->nh.raw[optoff+1]); 674 nh[optoff + 1]);
666 kfree_skb(skb); 675 kfree_skb(skb);
667 return 0; 676 return 0;
668} 677}
@@ -672,17 +681,18 @@ static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
672static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff) 681static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
673{ 682{
674 struct sk_buff *skb = *skbp; 683 struct sk_buff *skb = *skbp;
684 const unsigned char *nh = skb_network_header(skb);
675 u32 pkt_len; 685 u32 pkt_len;
676 686
677 if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) { 687 if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
678 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", 688 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
679 skb->nh.raw[optoff+1]); 689 nh[optoff+1]);
680 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 690 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
681 IPSTATS_MIB_INHDRERRORS); 691 IPSTATS_MIB_INHDRERRORS);
682 goto drop; 692 goto drop;
683 } 693 }
684 694
685 pkt_len = ntohl(*(__be32*)(skb->nh.raw+optoff+2)); 695 pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
686 if (pkt_len <= IPV6_MAXPLEN) { 696 if (pkt_len <= IPV6_MAXPLEN) {
687 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); 697 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
688 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); 698 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
@@ -727,7 +737,7 @@ int ipv6_parse_hopopts(struct sk_buff **skbp)
727 struct inet6_skb_parm *opt = IP6CB(skb); 737 struct inet6_skb_parm *opt = IP6CB(skb);
728 738
729 /* 739 /*
730 * skb->nh.raw is equal to skb->data, and 740 * skb_network_header(skb) is equal to skb->data, and
731 * skb->h.raw - skb->nh.raw is always equal to 741 * skb->h.raw - skb->nh.raw is always equal to
732 * sizeof(struct ipv6hdr) by definition of 742 * sizeof(struct ipv6hdr) by definition of
733 * hop-by-hop options. 743 * hop-by-hop options.
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index aa4a0a59ffac..e5293b34229f 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -284,7 +284,8 @@ static void mip6_addr_swap(struct sk_buff *skb)
284 if (opt->dsthao) { 284 if (opt->dsthao) {
285 off = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO); 285 off = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
286 if (likely(off >= 0)) { 286 if (likely(off >= 0)) {
287 hao = (struct ipv6_destopt_hao *)(skb->nh.raw + off); 287 hao = (struct ipv6_destopt_hao *)
288 (skb_network_header(skb) + off);
288 ipv6_addr_copy(&tmp, &iph->saddr); 289 ipv6_addr_copy(&tmp, &iph->saddr);
289 ipv6_addr_copy(&iph->saddr, &hao->addr); 290 ipv6_addr_copy(&iph->saddr, &hao->addr);
290 ipv6_addr_copy(&hao->addr, &tmp); 291 ipv6_addr_copy(&hao->addr, &tmp);
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 61e7a6c8141d..aecc74da0721 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -163,7 +163,7 @@ resubmit:
163 if (!pskb_pull(skb, skb->h.raw - skb->data)) 163 if (!pskb_pull(skb, skb->h.raw - skb->data))
164 goto discard; 164 goto discard;
165 nhoff = IP6CB(skb)->nhoff; 165 nhoff = IP6CB(skb)->nhoff;
166 nexthdr = skb->nh.raw[nhoff]; 166 nexthdr = skb_network_header(skb)[nhoff];
167 167
168 raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]); 168 raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]);
169 if (raw_sk && !ipv6_raw_deliver(skb, nexthdr)) 169 if (raw_sk && !ipv6_raw_deliver(skb, nexthdr))
@@ -181,7 +181,7 @@ resubmit:
181 indefinitely. */ 181 indefinitely. */
182 nf_reset(skb); 182 nf_reset(skb);
183 183
184 skb_postpull_rcsum(skb, skb->nh.raw, 184 skb_postpull_rcsum(skb, skb_network_header(skb),
185 skb->h.raw - skb->nh.raw); 185 skb->h.raw - skb->nh.raw);
186 hdr = skb->nh.ipv6h; 186 hdr = skb->nh.ipv6h;
187 if (ipv6_addr_is_multicast(&hdr->daddr) && 187 if (ipv6_addr_is_multicast(&hdr->daddr) &&
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 47d00210cba1..f1dfcc319717 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -323,10 +323,11 @@ static int ip6_forward_proxy_check(struct sk_buff *skb)
323 if (nexthdr == IPPROTO_ICMPV6) { 323 if (nexthdr == IPPROTO_ICMPV6) {
324 struct icmp6hdr *icmp6; 324 struct icmp6hdr *icmp6;
325 325
326 if (!pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) 326 if (!pskb_may_pull(skb, (skb_network_header(skb) +
327 offset + 1 - skb->data)))
327 return 0; 328 return 0;
328 329
329 icmp6 = (struct icmp6hdr *)(skb->nh.raw + offset); 330 icmp6 = (struct icmp6hdr *)(skb_network_header(skb) + offset);
330 331
331 switch (icmp6->icmp6_type) { 332 switch (icmp6->icmp6_type) {
332 case NDISC_ROUTER_SOLICITATION: 333 case NDISC_ROUTER_SOLICITATION:
@@ -392,7 +393,7 @@ int ip6_forward(struct sk_buff *skb)
392 * that different fragments will go along one path. --ANK 393 * that different fragments will go along one path. --ANK
393 */ 394 */
394 if (opt->ra) { 395 if (opt->ra) {
395 u8 *ptr = skb->nh.raw + opt->ra; 396 u8 *ptr = skb_network_header(skb) + opt->ra;
396 if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3])) 397 if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3]))
397 return 0; 398 return 0;
398 } 399 }
@@ -527,7 +528,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
527{ 528{
528 u16 offset = sizeof(struct ipv6hdr); 529 u16 offset = sizeof(struct ipv6hdr);
529 struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1); 530 struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
530 unsigned int packet_len = skb->tail - skb->nh.raw; 531 unsigned int packet_len = skb->tail - skb_network_header(skb);
531 int found_rhdr = 0; 532 int found_rhdr = 0;
532 *nexthdr = &skb->nh.ipv6h->nexthdr; 533 *nexthdr = &skb->nh.ipv6h->nexthdr;
533 534
@@ -554,7 +555,8 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
554 555
555 offset += ipv6_optlen(exthdr); 556 offset += ipv6_optlen(exthdr);
556 *nexthdr = &exthdr->nexthdr; 557 *nexthdr = &exthdr->nexthdr;
557 exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); 558 exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
559 offset);
558 } 560 }
559 561
560 return offset; 562 return offset;
@@ -620,7 +622,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
620 /* BUILD HEADER */ 622 /* BUILD HEADER */
621 623
622 *prevhdr = NEXTHDR_FRAGMENT; 624 *prevhdr = NEXTHDR_FRAGMENT;
623 tmp_hdr = kmemdup(skb->nh.raw, hlen, GFP_ATOMIC); 625 tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
624 if (!tmp_hdr) { 626 if (!tmp_hdr) {
625 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); 627 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
626 return -ENOMEM; 628 return -ENOMEM;
@@ -630,7 +632,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
630 fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr)); 632 fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr));
631 __skb_push(skb, hlen); 633 __skb_push(skb, hlen);
632 skb_reset_network_header(skb); 634 skb_reset_network_header(skb);
633 memcpy(skb->nh.raw, tmp_hdr, hlen); 635 memcpy(skb_network_header(skb), tmp_hdr, hlen);
634 636
635 ipv6_select_ident(skb, fh); 637 ipv6_select_ident(skb, fh);
636 fh->nexthdr = nexthdr; 638 fh->nexthdr = nexthdr;
@@ -654,7 +656,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
654 fh = (struct frag_hdr*)__skb_push(frag, sizeof(struct frag_hdr)); 656 fh = (struct frag_hdr*)__skb_push(frag, sizeof(struct frag_hdr));
655 __skb_push(frag, hlen); 657 __skb_push(frag, hlen);
656 skb_reset_network_header(frag); 658 skb_reset_network_header(frag);
657 memcpy(frag->nh.raw, tmp_hdr, hlen); 659 memcpy(skb_network_header(frag), tmp_hdr,
660 hlen);
658 offset += skb->len - hlen - sizeof(struct frag_hdr); 661 offset += skb->len - hlen - sizeof(struct frag_hdr);
659 fh->nexthdr = nexthdr; 662 fh->nexthdr = nexthdr;
660 fh->reserved = 0; 663 fh->reserved = 0;
@@ -753,7 +756,7 @@ slow_path:
753 /* 756 /*
754 * Copy the packet header into the new buffer. 757 * Copy the packet header into the new buffer.
755 */ 758 */
756 memcpy(frag->nh.raw, skb->data, hlen); 759 memcpy(skb_network_header(frag), skb->data, hlen);
757 760
758 /* 761 /*
759 * Build fragment header. 762 * Build fragment header.
@@ -1329,7 +1332,7 @@ int ip6_push_pending_frames(struct sock *sk)
1329 tail_skb = &(skb_shinfo(skb)->frag_list); 1332 tail_skb = &(skb_shinfo(skb)->frag_list);
1330 1333
1331 /* move skb->data to ip header from ext header */ 1334 /* move skb->data to ip header from ext header */
1332 if (skb->data < skb->nh.raw) 1335 if (skb->data < skb_network_header(skb))
1333 __skb_pull(skb, skb_network_offset(skb)); 1336 __skb_pull(skb, skb_network_offset(skb));
1334 while ((tmp_skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) { 1337 while ((tmp_skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) {
1335 __skb_pull(tmp_skb, skb->h.raw - skb->nh.raw); 1338 __skb_pull(tmp_skb, skb->h.raw - skb->nh.raw);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index a1e4f39c6793..aafbdfa8d785 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -995,9 +995,10 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
995 !ip6_tnl_xmit_ctl(t) || ip6_tnl_addr_conflict(t, ipv6h)) 995 !ip6_tnl_xmit_ctl(t) || ip6_tnl_addr_conflict(t, ipv6h))
996 return -1; 996 return -1;
997 997
998 if ((offset = parse_tlv_tnl_enc_lim(skb, skb->nh.raw)) > 0) { 998 offset = parse_tlv_tnl_enc_lim(skb, skb_network_header(skb));
999 if (offset > 0) {
999 struct ipv6_tlv_tnl_enc_lim *tel; 1000 struct ipv6_tlv_tnl_enc_lim *tel;
1000 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->nh.raw[offset]; 1001 tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset];
1001 if (tel->encap_limit == 0) { 1002 if (tel->encap_limit == 0) {
1002 icmpv6_send(skb, ICMPV6_PARAMPROB, 1003 icmpv6_send(skb, ICMPV6_PARAMPROB,
1003 ICMPV6_HDR_FIELD, offset + 2, skb->dev); 1004 ICMPV6_HDR_FIELD, offset + 2, skb->dev);
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 5724ba9f75de..3e71d1691b7d 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -166,10 +166,10 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
166 top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); 166 top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
167 167
168 ipch = (struct ipv6_comp_hdr *)start; 168 ipch = (struct ipv6_comp_hdr *)start;
169 ipch->nexthdr = *skb->nh.raw; 169 ipch->nexthdr = *skb_network_header(skb);
170 ipch->flags = 0; 170 ipch->flags = 0;
171 ipch->cpi = htons((u16 )ntohl(x->id.spi)); 171 ipch->cpi = htons((u16 )ntohl(x->id.spi));
172 *skb->nh.raw = IPPROTO_COMP; 172 *skb_network_header(skb) = IPPROTO_COMP;
173 173
174out_ok: 174out_ok:
175 return 0; 175 return 0;
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 0afcabdd8ed6..bb4033553f3b 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -99,14 +99,16 @@ int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
99 if (mh->ip6mh_hdrlen < mip6_mh_len(mh->ip6mh_type)) { 99 if (mh->ip6mh_hdrlen < mip6_mh_len(mh->ip6mh_type)) {
100 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH message too short: %d vs >=%d\n", 100 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH message too short: %d vs >=%d\n",
101 mh->ip6mh_hdrlen, mip6_mh_len(mh->ip6mh_type)); 101 mh->ip6mh_hdrlen, mip6_mh_len(mh->ip6mh_type));
102 mip6_param_prob(skb, 0, (&mh->ip6mh_hdrlen) - skb->nh.raw); 102 mip6_param_prob(skb, 0, ((&mh->ip6mh_hdrlen) -
103 skb_network_header(skb)));
103 return -1; 104 return -1;
104 } 105 }
105 106
106 if (mh->ip6mh_proto != IPPROTO_NONE) { 107 if (mh->ip6mh_proto != IPPROTO_NONE) {
107 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n", 108 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n",
108 mh->ip6mh_proto); 109 mh->ip6mh_proto);
109 mip6_param_prob(skb, 0, (&mh->ip6mh_proto) - skb->nh.raw); 110 mip6_param_prob(skb, 0, ((&mh->ip6mh_proto) -
111 skb_network_header(skb)));
110 return -1; 112 return -1;
111 } 113 }
112 114
@@ -152,8 +154,8 @@ static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb)
152 iph = (struct ipv6hdr *)skb->data; 154 iph = (struct ipv6hdr *)skb->data;
153 iph->payload_len = htons(skb->len - sizeof(*iph)); 155 iph->payload_len = htons(skb->len - sizeof(*iph));
154 156
155 nexthdr = *skb->nh.raw; 157 nexthdr = *skb_network_header(skb);
156 *skb->nh.raw = IPPROTO_DSTOPTS; 158 *skb_network_header(skb) = IPPROTO_DSTOPTS;
157 159
158 dstopt = (struct ipv6_destopt_hdr *)skb->h.raw; 160 dstopt = (struct ipv6_destopt_hdr *)skb->h.raw;
159 dstopt->nexthdr = nexthdr; 161 dstopt->nexthdr = nexthdr;
@@ -215,7 +217,8 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct
215 if (likely(opt->dsthao)) { 217 if (likely(opt->dsthao)) {
216 offset = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO); 218 offset = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
217 if (likely(offset >= 0)) 219 if (likely(offset >= 0))
218 hao = (struct ipv6_destopt_hao *)(skb->nh.raw + offset); 220 hao = (struct ipv6_destopt_hao *)
221 (skb_network_header(skb) + offset);
219 } 222 }
220 223
221 skb_get_timestamp(skb, &stamp); 224 skb_get_timestamp(skb, &stamp);
@@ -254,7 +257,8 @@ static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb,
254{ 257{
255 u16 offset = sizeof(struct ipv6hdr); 258 u16 offset = sizeof(struct ipv6hdr);
256 struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1); 259 struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
257 unsigned int packet_len = skb->tail - skb->nh.raw; 260 const unsigned char *nh = skb_network_header(skb);
261 unsigned int packet_len = skb->tail - nh;
258 int found_rhdr = 0; 262 int found_rhdr = 0;
259 263
260 *nexthdr = &skb->nh.ipv6h->nexthdr; 264 *nexthdr = &skb->nh.ipv6h->nexthdr;
@@ -288,7 +292,7 @@ static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb,
288 292
289 offset += ipv6_optlen(exthdr); 293 offset += ipv6_optlen(exthdr);
290 *nexthdr = &exthdr->nexthdr; 294 *nexthdr = &exthdr->nexthdr;
291 exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); 295 exthdr = (struct ipv6_opt_hdr *)(nh + offset);
292 } 296 }
293 297
294 return offset; 298 return offset;
@@ -361,8 +365,8 @@ static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb)
361 iph = (struct ipv6hdr *)skb->data; 365 iph = (struct ipv6hdr *)skb->data;
362 iph->payload_len = htons(skb->len - sizeof(*iph)); 366 iph->payload_len = htons(skb->len - sizeof(*iph));
363 367
364 nexthdr = *skb->nh.raw; 368 nexthdr = *skb_network_header(skb);
365 *skb->nh.raw = IPPROTO_ROUTING; 369 *skb_network_header(skb) = IPPROTO_ROUTING;
366 370
367 rt2 = (struct rt2_hdr *)skb->h.raw; 371 rt2 = (struct rt2_hdr *)skb->h.raw;
368 rt2->rt_hdr.nexthdr = nexthdr; 372 rt2->rt_hdr.nexthdr = nexthdr;
@@ -384,7 +388,8 @@ static int mip6_rthdr_offset(struct xfrm_state *x, struct sk_buff *skb,
384{ 388{
385 u16 offset = sizeof(struct ipv6hdr); 389 u16 offset = sizeof(struct ipv6hdr);
386 struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1); 390 struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
387 unsigned int packet_len = skb->tail - skb->nh.raw; 391 const unsigned char *nh = skb_network_header(skb);
392 unsigned int packet_len = skb->tail - nh;
388 int found_rhdr = 0; 393 int found_rhdr = 0;
389 394
390 *nexthdr = &skb->nh.ipv6h->nexthdr; 395 *nexthdr = &skb->nh.ipv6h->nexthdr;
@@ -397,7 +402,7 @@ static int mip6_rthdr_offset(struct xfrm_state *x, struct sk_buff *skb,
397 case NEXTHDR_ROUTING: 402 case NEXTHDR_ROUTING:
398 if (offset + 3 <= packet_len) { 403 if (offset + 3 <= packet_len) {
399 struct ipv6_rt_hdr *rt; 404 struct ipv6_rt_hdr *rt;
400 rt = (struct ipv6_rt_hdr *)(skb->nh.raw + offset); 405 rt = (struct ipv6_rt_hdr *)(nh + offset);
401 if (rt->type != 0) 406 if (rt->type != 0)
402 return offset; 407 return offset;
403 } 408 }
@@ -417,7 +422,7 @@ static int mip6_rthdr_offset(struct xfrm_state *x, struct sk_buff *skb,
417 422
418 offset += ipv6_optlen(exthdr); 423 offset += ipv6_optlen(exthdr);
419 *nexthdr = &exthdr->nexthdr; 424 *nexthdr = &exthdr->nexthdr;
420 exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); 425 exthdr = (struct ipv6_opt_hdr *)(nh + offset);
421 } 426 }
422 427
423 return offset; 428 return offset;
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index c311b9a12ca6..bc1d09584008 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -408,11 +408,12 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
408 return -1; 408 return -1;
409 } 409 }
410 410
411 if (skb->ip_summed == CHECKSUM_COMPLETE) 411 if (skb->ip_summed == CHECKSUM_COMPLETE) {
412 const unsigned char *nh = skb_network_header(skb);
412 skb->csum = csum_sub(skb->csum, 413 skb->csum = csum_sub(skb->csum,
413 csum_partial(skb->nh.raw, 414 csum_partial(nh, (u8 *)(fhdr + 1) - nh,
414 (u8*)(fhdr + 1) - skb->nh.raw,
415 0)); 415 0));
416 }
416 417
417 /* Is this the final fragment? */ 418 /* Is this the final fragment? */
418 if (!(fhdr->frag_off & htons(IP6_MF))) { 419 if (!(fhdr->frag_off & htons(IP6_MF))) {
@@ -583,7 +584,9 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
583 BUG_TRAP(NFCT_FRAG6_CB(head)->offset == 0); 584 BUG_TRAP(NFCT_FRAG6_CB(head)->offset == 0);
584 585
585 /* Unfragmented part is taken from the first segment. */ 586 /* Unfragmented part is taken from the first segment. */
586 payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len - sizeof(struct frag_hdr); 587 payload_len = ((head->data - skb_network_header(head)) -
588 sizeof(struct ipv6hdr) + fq->len -
589 sizeof(struct frag_hdr));
587 if (payload_len > IPV6_MAXPLEN) { 590 if (payload_len > IPV6_MAXPLEN) {
588 DEBUGP("payload len is too large.\n"); 591 DEBUGP("payload len is too large.\n");
589 goto out_oversize; 592 goto out_oversize;
@@ -624,7 +627,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
624 627
625 /* We have to remove fragment header from datagram and to relocate 628 /* We have to remove fragment header from datagram and to relocate
626 * header in order to calculate ICV correctly. */ 629 * header in order to calculate ICV correctly. */
627 head->nh.raw[fq->nhoffset] = head->h.raw[0]; 630 skb_network_header(head)[fq->nhoffset] = head->h.raw[0];
628 memmove(head->head + sizeof(struct frag_hdr), head->head, 631 memmove(head->head + sizeof(struct frag_hdr), head->head,
629 (head->data - head->head) - sizeof(struct frag_hdr)); 632 (head->data - head->head) - sizeof(struct frag_hdr));
630 head->mac.raw += sizeof(struct frag_hdr); 633 head->mac.raw += sizeof(struct frag_hdr);
@@ -632,7 +635,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
632 635
633 skb_shinfo(head)->frag_list = head->next; 636 skb_shinfo(head)->frag_list = head->next;
634 head->h.raw = head->data; 637 head->h.raw = head->data;
635 skb_push(head, head->data - head->nh.raw); 638 skb_push(head, head->data - skb_network_header(head));
636 atomic_sub(head->truesize, &nf_ct_frag6_mem); 639 atomic_sub(head->truesize, &nf_ct_frag6_mem);
637 640
638 for (fp=head->next; fp; fp = fp->next) { 641 for (fp=head->next; fp; fp = fp->next) {
@@ -653,7 +656,9 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
653 656
654 /* Yes, and fold redundant checksum back. 8) */ 657 /* Yes, and fold redundant checksum back. 8) */
655 if (head->ip_summed == CHECKSUM_COMPLETE) 658 if (head->ip_summed == CHECKSUM_COMPLETE)
656 head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum); 659 head->csum = csum_partial(skb_network_header(head),
660 head->h.raw - head->nh.raw,
661 head->csum);
657 662
658 fq->fragments = NULL; 663 fq->fragments = NULL;
659 664
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 5f26645195dc..9b2bcde73f19 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -361,7 +361,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
361 skb->ip_summed = CHECKSUM_UNNECESSARY; 361 skb->ip_summed = CHECKSUM_UNNECESSARY;
362 362
363 if (skb->ip_summed == CHECKSUM_COMPLETE) { 363 if (skb->ip_summed == CHECKSUM_COMPLETE) {
364 skb_postpull_rcsum(skb, skb->nh.raw, 364 skb_postpull_rcsum(skb, skb_network_header(skb),
365 skb->h.raw - skb->nh.raw); 365 skb->h.raw - skb->nh.raw);
366 if (!csum_ipv6_magic(&skb->nh.ipv6h->saddr, 366 if (!csum_ipv6_magic(&skb->nh.ipv6h->saddr,
367 &skb->nh.ipv6h->daddr, 367 &skb->nh.ipv6h->daddr,
@@ -488,7 +488,8 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
488 goto out; 488 goto out;
489 489
490 offset = rp->offset; 490 offset = rp->offset;
491 total_len = inet_sk(sk)->cork.length - (skb->nh.raw - skb->data); 491 total_len = inet_sk(sk)->cork.length - (skb_network_header(skb) -
492 skb->data);
492 if (offset >= total_len - 1) { 493 if (offset >= total_len - 1) {
493 err = -EINVAL; 494 err = -EINVAL;
494 ip6_flush_pending_frames(sk); 495 ip6_flush_pending_frames(sk);
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 1dde449379fb..f85e49acb91a 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -436,13 +436,18 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
436 if ((unsigned int)end > IPV6_MAXPLEN) { 436 if ((unsigned int)end > IPV6_MAXPLEN) {
437 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 437 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
438 IPSTATS_MIB_INHDRERRORS); 438 IPSTATS_MIB_INHDRERRORS);
439 icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw); 439 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
440 ((u8 *)&fhdr->frag_off -
441 skb_network_header(skb)));
440 return; 442 return;
441 } 443 }
442 444
443 if (skb->ip_summed == CHECKSUM_COMPLETE) 445 if (skb->ip_summed == CHECKSUM_COMPLETE) {
446 const unsigned char *nh = skb_network_header(skb);
444 skb->csum = csum_sub(skb->csum, 447 skb->csum = csum_sub(skb->csum,
445 csum_partial(skb->nh.raw, (u8*)(fhdr+1)-skb->nh.raw, 0)); 448 csum_partial(nh, (u8 *)(fhdr + 1) - nh,
449 0));
450 }
446 451
447 /* Is this the final fragment? */ 452 /* Is this the final fragment? */
448 if (!(fhdr->frag_off & htons(IP6_MF))) { 453 if (!(fhdr->frag_off & htons(IP6_MF))) {
@@ -605,7 +610,9 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
605 BUG_TRAP(FRAG6_CB(head)->offset == 0); 610 BUG_TRAP(FRAG6_CB(head)->offset == 0);
606 611
607 /* Unfragmented part is taken from the first segment. */ 612 /* Unfragmented part is taken from the first segment. */
608 payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len - sizeof(struct frag_hdr); 613 payload_len = ((head->data - skb_network_header(head)) -
614 sizeof(struct ipv6hdr) + fq->len -
615 sizeof(struct frag_hdr));
609 if (payload_len > IPV6_MAXPLEN) 616 if (payload_len > IPV6_MAXPLEN)
610 goto out_oversize; 617 goto out_oversize;
611 618
@@ -639,7 +646,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
639 /* We have to remove fragment header from datagram and to relocate 646 /* We have to remove fragment header from datagram and to relocate
640 * header in order to calculate ICV correctly. */ 647 * header in order to calculate ICV correctly. */
641 nhoff = fq->nhoffset; 648 nhoff = fq->nhoffset;
642 head->nh.raw[nhoff] = head->h.raw[0]; 649 skb_network_header(head)[nhoff] = head->h.raw[0];
643 memmove(head->head + sizeof(struct frag_hdr), head->head, 650 memmove(head->head + sizeof(struct frag_hdr), head->head,
644 (head->data - head->head) - sizeof(struct frag_hdr)); 651 (head->data - head->head) - sizeof(struct frag_hdr));
645 head->mac.raw += sizeof(struct frag_hdr); 652 head->mac.raw += sizeof(struct frag_hdr);
@@ -647,7 +654,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
647 654
648 skb_shinfo(head)->frag_list = head->next; 655 skb_shinfo(head)->frag_list = head->next;
649 head->h.raw = head->data; 656 head->h.raw = head->data;
650 skb_push(head, head->data - head->nh.raw); 657 skb_push(head, head->data - skb_network_header(head));
651 atomic_sub(head->truesize, &ip6_frag_mem); 658 atomic_sub(head->truesize, &ip6_frag_mem);
652 659
653 for (fp=head->next; fp; fp = fp->next) { 660 for (fp=head->next; fp; fp = fp->next) {
@@ -671,7 +678,9 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
671 678
672 /* Yes, and fold redundant checksum back. 8) */ 679 /* Yes, and fold redundant checksum back. 8) */
673 if (head->ip_summed == CHECKSUM_COMPLETE) 680 if (head->ip_summed == CHECKSUM_COMPLETE)
674 head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum); 681 head->csum = csum_partial(skb_network_header(head),
682 head->h.raw - head->nh.raw,
683 head->csum);
675 684
676 rcu_read_lock(); 685 rcu_read_lock();
677 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMOKS); 686 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMOKS);
@@ -725,7 +734,7 @@ static int ipv6_frag_rcv(struct sk_buff **skbp)
725 skb->h.raw += sizeof(struct frag_hdr); 734 skb->h.raw += sizeof(struct frag_hdr);
726 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMOKS); 735 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMOKS);
727 736
728 IP6CB(skb)->nhoff = (u8*)fhdr - skb->nh.raw; 737 IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb);
729 return 1; 738 return 1;
730 } 739 }
731 740
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 92f99927d12d..80a52ab1e384 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -486,7 +486,9 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
486 struct sk_buff *pktopts = treq->pktopts; 486 struct sk_buff *pktopts = treq->pktopts;
487 struct inet6_skb_parm *rxopt = IP6CB(pktopts); 487 struct inet6_skb_parm *rxopt = IP6CB(pktopts);
488 if (rxopt->srcrt) 488 if (rxopt->srcrt)
489 opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt)); 489 opt = ipv6_invert_rthdr(sk,
490 (struct ipv6_rt_hdr *)(skb_network_header(pktopts) +
491 rxopt->srcrt));
490 } 492 }
491 493
492 if (opt && opt->srcrt) { 494 if (opt && opt->srcrt) {
@@ -1389,7 +1391,9 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1389 opt == NULL && treq->pktopts) { 1391 opt == NULL && treq->pktopts) {
1390 struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts); 1392 struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
1391 if (rxopt->srcrt) 1393 if (rxopt->srcrt)
1392 opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr *)(treq->pktopts->nh.raw + rxopt->srcrt)); 1394 opt = ipv6_invert_rthdr(sk,
1395 (struct ipv6_rt_hdr *)(skb_network_header(treq->pktopts) +
1396 rxopt->srcrt));
1393 } 1397 }
1394 1398
1395 if (dst == NULL) { 1399 if (dst == NULL) {
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 33a1b9200431..5c929f886129 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -28,7 +28,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
28 unsigned int nhoff; 28 unsigned int nhoff;
29 29
30 nhoff = IP6CB(skb)->nhoff; 30 nhoff = IP6CB(skb)->nhoff;
31 nexthdr = skb->nh.raw[nhoff]; 31 nexthdr = skb_network_header(skb)[nhoff];
32 32
33 seq = 0; 33 seq = 0;
34 if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) 34 if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
@@ -58,7 +58,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
58 if (nexthdr <= 0) 58 if (nexthdr <= 0)
59 goto drop_unlock; 59 goto drop_unlock;
60 60
61 skb->nh.raw[nhoff] = nexthdr; 61 skb_network_header(skb)[nhoff] = nexthdr;
62 62
63 if (x->props.replay_window) 63 if (x->props.replay_window)
64 xfrm_replay_advance(x, seq); 64 xfrm_replay_advance(x, seq);
@@ -113,7 +113,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
113 } else { 113 } else {
114#ifdef CONFIG_NETFILTER 114#ifdef CONFIG_NETFILTER
115 skb->nh.ipv6h->payload_len = htons(skb->len); 115 skb->nh.ipv6h->payload_len = htons(skb->len);
116 __skb_push(skb, skb->data - skb->nh.raw); 116 __skb_push(skb, skb->data - skb_network_header(skb));
117 117
118 NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL, 118 NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
119 ip6_rcv_finish); 119 ip6_rcv_finish);
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index c015bfde2b1c..247e2d5d2acf 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -67,7 +67,7 @@ static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb)
67 goto out; 67 goto out;
68 68
69 skb_push(skb, size); 69 skb_push(skb, size);
70 memmove(skb->data, skb->nh.raw, size); 70 memmove(skb->data, skb_network_header(skb), size);
71 skb_reset_network_header(skb); 71 skb_reset_network_header(skb);
72 72
73 old_mac = skb_mac_header(skb); 73 old_mac = skb_mac_header(skb);
diff --git a/net/ipv6/xfrm6_mode_transport.c b/net/ipv6/xfrm6_mode_transport.c
index 3a4b39b12bad..ace0bbf4f25d 100644
--- a/net/ipv6/xfrm6_mode_transport.c
+++ b/net/ipv6/xfrm6_mode_transport.c
@@ -53,8 +53,10 @@ static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb)
53{ 53{
54 int ihl = skb->data - skb->h.raw; 54 int ihl = skb->data - skb->h.raw;
55 55
56 if (skb->h.raw != skb->nh.raw) 56 if (skb->h.raw != skb->nh.raw) {
57 skb->nh.raw = memmove(skb->h.raw, skb->nh.raw, ihl); 57 memmove(skb->h.raw, skb_network_header(skb), ihl);
58 skb->nh.raw = skb->h.raw;
59 }
58 skb->nh.ipv6h->payload_len = htons(skb->len + ihl - 60 skb->nh.ipv6h->payload_len = htons(skb->len + ihl -
59 sizeof(struct ipv6hdr)); 61 sizeof(struct ipv6hdr));
60 skb->h.raw = skb->data; 62 skb->h.raw = skb->data;
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 8ce5ef2d0b1c..498f17b5c42f 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -87,9 +87,10 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
87{ 87{
88 int err = -EINVAL; 88 int err = -EINVAL;
89 const unsigned char *old_mac; 89 const unsigned char *old_mac;
90 const unsigned char *nh = skb_network_header(skb);
90 91
91 if (skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPV6 92 if (nh[IP6CB(skb)->nhoff] != IPPROTO_IPV6 &&
92 && skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPIP) 93 nh[IP6CB(skb)->nhoff] != IPPROTO_IPIP)
93 goto out; 94 goto out;
94 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 95 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
95 goto out; 96 goto out;
@@ -98,7 +99,8 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
98 (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) 99 (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
99 goto out; 100 goto out;
100 101
101 if (skb->nh.raw[IP6CB(skb)->nhoff] == IPPROTO_IPV6) { 102 nh = skb_network_header(skb);
103 if (nh[IP6CB(skb)->nhoff] == IPPROTO_IPV6) {
102 if (x->props.flags & XFRM_STATE_DECAP_DSCP) 104 if (x->props.flags & XFRM_STATE_DECAP_DSCP)
103 ipv6_copy_dscp(skb->nh.ipv6h, skb->h.ipv6h); 105 ipv6_copy_dscp(skb->nh.ipv6h, skb->h.ipv6h);
104 if (!(x->props.flags & XFRM_STATE_NOECN)) 106 if (!(x->props.flags & XFRM_STATE_NOECN))
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index d8a585bd2cb4..cb5a723d4cb4 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -273,14 +273,16 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
273 u16 offset = skb->h.raw - skb->nh.raw; 273 u16 offset = skb->h.raw - skb->nh.raw;
274 struct ipv6hdr *hdr = skb->nh.ipv6h; 274 struct ipv6hdr *hdr = skb->nh.ipv6h;
275 struct ipv6_opt_hdr *exthdr; 275 struct ipv6_opt_hdr *exthdr;
276 u8 nexthdr = skb->nh.raw[IP6CB(skb)->nhoff]; 276 const unsigned char *nh = skb_network_header(skb);
277 u8 nexthdr = nh[IP6CB(skb)->nhoff];
277 278
278 memset(fl, 0, sizeof(struct flowi)); 279 memset(fl, 0, sizeof(struct flowi));
279 ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr); 280 ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr);
280 ipv6_addr_copy(&fl->fl6_src, &hdr->saddr); 281 ipv6_addr_copy(&fl->fl6_src, &hdr->saddr);
281 282
282 while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) { 283 while (pskb_may_pull(skb, nh + offset + 1 - skb->data)) {
283 exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); 284 nh = skb_network_header(skb);
285 exthdr = (struct ipv6_opt_hdr *)(nh + offset);
284 286
285 switch (nexthdr) { 287 switch (nexthdr) {
286 case NEXTHDR_ROUTING: 288 case NEXTHDR_ROUTING:
@@ -288,7 +290,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
288 case NEXTHDR_DEST: 290 case NEXTHDR_DEST:
289 offset += ipv6_optlen(exthdr); 291 offset += ipv6_optlen(exthdr);
290 nexthdr = exthdr->nexthdr; 292 nexthdr = exthdr->nexthdr;
291 exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); 293 exthdr = (struct ipv6_opt_hdr *)(nh + offset);
292 break; 294 break;
293 295
294 case IPPROTO_UDP: 296 case IPPROTO_UDP:
@@ -296,7 +298,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
296 case IPPROTO_TCP: 298 case IPPROTO_TCP:
297 case IPPROTO_SCTP: 299 case IPPROTO_SCTP:
298 case IPPROTO_DCCP: 300 case IPPROTO_DCCP:
299 if (pskb_may_pull(skb, skb->nh.raw + offset + 4 - skb->data)) { 301 if (pskb_may_pull(skb, nh + offset + 4 - skb->data)) {
300 __be16 *ports = (__be16 *)exthdr; 302 __be16 *ports = (__be16 *)exthdr;
301 303
302 fl->fl_ip_sport = ports[0]; 304 fl->fl_ip_sport = ports[0];
@@ -306,7 +308,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
306 return; 308 return;
307 309
308 case IPPROTO_ICMPV6: 310 case IPPROTO_ICMPV6:
309 if (pskb_may_pull(skb, skb->nh.raw + offset + 2 - skb->data)) { 311 if (pskb_may_pull(skb, nh + offset + 2 - skb->data)) {
310 u8 *icmp = (u8 *)exthdr; 312 u8 *icmp = (u8 *)exthdr;
311 313
312 fl->fl_icmp_type = icmp[0]; 314 fl->fl_icmp_type = icmp[0];
@@ -317,7 +319,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
317 319
318#ifdef CONFIG_IPV6_MIP6 320#ifdef CONFIG_IPV6_MIP6
319 case IPPROTO_MH: 321 case IPPROTO_MH:
320 if (pskb_may_pull(skb, skb->nh.raw + offset + 3 - skb->data)) { 322 if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
321 struct ip6_mh *mh; 323 struct ip6_mh *mh;
322 mh = (struct ip6_mh *)exthdr; 324 mh = (struct ip6_mh *)exthdr;
323 325