aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r--net/ipv6/ip6_output.c187
1 files changed, 123 insertions, 64 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 305516921aa8..f508171bab73 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -88,8 +88,8 @@ static inline int ip6_output_finish(struct sk_buff *skb)
88/* dev_loopback_xmit for use with netfilter. */ 88/* dev_loopback_xmit for use with netfilter. */
89static int ip6_dev_loopback_xmit(struct sk_buff *newskb) 89static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
90{ 90{
91 newskb->mac.raw = newskb->data; 91 skb_reset_mac_header(newskb);
92 __skb_pull(newskb, newskb->nh.raw - newskb->data); 92 __skb_pull(newskb, skb_network_offset(newskb));
93 newskb->pkt_type = PACKET_LOOPBACK; 93 newskb->pkt_type = PACKET_LOOPBACK;
94 newskb->ip_summed = CHECKSUM_UNNECESSARY; 94 newskb->ip_summed = CHECKSUM_UNNECESSARY;
95 BUG_TRAP(newskb->dst); 95 BUG_TRAP(newskb->dst);
@@ -107,13 +107,13 @@ static int ip6_output2(struct sk_buff *skb)
107 skb->protocol = htons(ETH_P_IPV6); 107 skb->protocol = htons(ETH_P_IPV6);
108 skb->dev = dev; 108 skb->dev = dev;
109 109
110 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) { 110 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {
111 struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL; 111 struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL;
112 struct inet6_dev *idev = ip6_dst_idev(skb->dst); 112 struct inet6_dev *idev = ip6_dst_idev(skb->dst);
113 113
114 if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && 114 if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) &&
115 ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr, 115 ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr,
116 &skb->nh.ipv6h->saddr)) { 116 &ipv6_hdr(skb)->saddr)) {
117 struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); 117 struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
118 118
119 /* Do not check for IFF_ALLMULTI; multicast routing 119 /* Do not check for IFF_ALLMULTI; multicast routing
@@ -124,7 +124,7 @@ static int ip6_output2(struct sk_buff *skb)
124 newskb->dev, 124 newskb->dev,
125 ip6_dev_loopback_xmit); 125 ip6_dev_loopback_xmit);
126 126
127 if (skb->nh.ipv6h->hop_limit == 0) { 127 if (ipv6_hdr(skb)->hop_limit == 0) {
128 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); 128 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS);
129 kfree_skb(skb); 129 kfree_skb(skb);
130 return 0; 130 return 0;
@@ -137,9 +137,17 @@ static int ip6_output2(struct sk_buff *skb)
137 return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish); 137 return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish);
138} 138}
139 139
140static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
141{
142 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
143
144 return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ?
145 skb->dst->dev->mtu : dst_mtu(skb->dst);
146}
147
140int ip6_output(struct sk_buff *skb) 148int ip6_output(struct sk_buff *skb)
141{ 149{
142 if ((skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb)) || 150 if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
143 dst_allfrag(skb->dst)) 151 dst_allfrag(skb->dst))
144 return ip6_fragment(skb, ip6_output2); 152 return ip6_fragment(skb, ip6_output2);
145 else 153 else
@@ -191,7 +199,9 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
191 ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop); 199 ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop);
192 } 200 }
193 201
194 hdr = skb->nh.ipv6h = (struct ipv6hdr*)skb_push(skb, sizeof(struct ipv6hdr)); 202 skb_push(skb, sizeof(struct ipv6hdr));
203 skb_reset_network_header(skb);
204 hdr = ipv6_hdr(skb);
195 205
196 /* 206 /*
197 * Fill in the IPv6 header 207 * Fill in the IPv6 header
@@ -239,6 +249,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
239 return -EMSGSIZE; 249 return -EMSGSIZE;
240} 250}
241 251
252EXPORT_SYMBOL(ip6_xmit);
253
242/* 254/*
243 * To avoid extra problems ND packets are send through this 255 * To avoid extra problems ND packets are send through this
244 * routine. It's code duplication but I really want to avoid 256 * routine. It's code duplication but I really want to avoid
@@ -259,8 +271,9 @@ int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
259 271
260 totlen = len + sizeof(struct ipv6hdr); 272 totlen = len + sizeof(struct ipv6hdr);
261 273
262 hdr = (struct ipv6hdr *) skb_put(skb, sizeof(struct ipv6hdr)); 274 skb_reset_network_header(skb);
263 skb->nh.ipv6h = hdr; 275 skb_put(skb, sizeof(struct ipv6hdr));
276 hdr = ipv6_hdr(skb);
264 277
265 *(__be32*)hdr = htonl(0x60000000); 278 *(__be32*)hdr = htonl(0x60000000);
266 279
@@ -305,7 +318,7 @@ static int ip6_call_ra_chain(struct sk_buff *skb, int sel)
305 318
306static int ip6_forward_proxy_check(struct sk_buff *skb) 319static int ip6_forward_proxy_check(struct sk_buff *skb)
307{ 320{
308 struct ipv6hdr *hdr = skb->nh.ipv6h; 321 struct ipv6hdr *hdr = ipv6_hdr(skb);
309 u8 nexthdr = hdr->nexthdr; 322 u8 nexthdr = hdr->nexthdr;
310 int offset; 323 int offset;
311 324
@@ -319,10 +332,11 @@ static int ip6_forward_proxy_check(struct sk_buff *skb)
319 if (nexthdr == IPPROTO_ICMPV6) { 332 if (nexthdr == IPPROTO_ICMPV6) {
320 struct icmp6hdr *icmp6; 333 struct icmp6hdr *icmp6;
321 334
322 if (!pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) 335 if (!pskb_may_pull(skb, (skb_network_header(skb) +
336 offset + 1 - skb->data)))
323 return 0; 337 return 0;
324 338
325 icmp6 = (struct icmp6hdr *)(skb->nh.raw + offset); 339 icmp6 = (struct icmp6hdr *)(skb_network_header(skb) + offset);
326 340
327 switch (icmp6->icmp6_type) { 341 switch (icmp6->icmp6_type) {
328 case NDISC_ROUTER_SOLICITATION: 342 case NDISC_ROUTER_SOLICITATION:
@@ -361,7 +375,7 @@ static inline int ip6_forward_finish(struct sk_buff *skb)
361int ip6_forward(struct sk_buff *skb) 375int ip6_forward(struct sk_buff *skb)
362{ 376{
363 struct dst_entry *dst = skb->dst; 377 struct dst_entry *dst = skb->dst;
364 struct ipv6hdr *hdr = skb->nh.ipv6h; 378 struct ipv6hdr *hdr = ipv6_hdr(skb);
365 struct inet6_skb_parm *opt = IP6CB(skb); 379 struct inet6_skb_parm *opt = IP6CB(skb);
366 380
367 if (ipv6_devconf.forwarding == 0) 381 if (ipv6_devconf.forwarding == 0)
@@ -372,7 +386,7 @@ int ip6_forward(struct sk_buff *skb)
372 goto drop; 386 goto drop;
373 } 387 }
374 388
375 skb->ip_summed = CHECKSUM_NONE; 389 skb_forward_csum(skb);
376 390
377 /* 391 /*
378 * We DO NOT make any processing on 392 * We DO NOT make any processing on
@@ -388,7 +402,7 @@ int ip6_forward(struct sk_buff *skb)
388 * that different fragments will go along one path. --ANK 402 * that different fragments will go along one path. --ANK
389 */ 403 */
390 if (opt->ra) { 404 if (opt->ra) {
391 u8 *ptr = skb->nh.raw + opt->ra; 405 u8 *ptr = skb_network_header(skb) + opt->ra;
392 if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3])) 406 if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3]))
393 return 0; 407 return 0;
394 } 408 }
@@ -470,7 +484,7 @@ int ip6_forward(struct sk_buff *skb)
470 goto drop; 484 goto drop;
471 } 485 }
472 486
473 hdr = skb->nh.ipv6h; 487 hdr = ipv6_hdr(skb);
474 488
475 /* Mangling hops number delayed to point after skb COW */ 489 /* Mangling hops number delayed to point after skb COW */
476 490
@@ -499,33 +513,18 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
499#ifdef CONFIG_NET_SCHED 513#ifdef CONFIG_NET_SCHED
500 to->tc_index = from->tc_index; 514 to->tc_index = from->tc_index;
501#endif 515#endif
502#ifdef CONFIG_NETFILTER 516 nf_copy(to, from);
503 /* Connection association is same as pre-frag packet */
504 nf_conntrack_put(to->nfct);
505 to->nfct = from->nfct;
506 nf_conntrack_get(to->nfct);
507 to->nfctinfo = from->nfctinfo;
508#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
509 nf_conntrack_put_reasm(to->nfct_reasm);
510 to->nfct_reasm = from->nfct_reasm;
511 nf_conntrack_get_reasm(to->nfct_reasm);
512#endif
513#ifdef CONFIG_BRIDGE_NETFILTER
514 nf_bridge_put(to->nf_bridge);
515 to->nf_bridge = from->nf_bridge;
516 nf_bridge_get(to->nf_bridge);
517#endif
518#endif
519 skb_copy_secmark(to, from); 517 skb_copy_secmark(to, from);
520} 518}
521 519
522int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) 520int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
523{ 521{
524 u16 offset = sizeof(struct ipv6hdr); 522 u16 offset = sizeof(struct ipv6hdr);
525 struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1); 523 struct ipv6_opt_hdr *exthdr =
526 unsigned int packet_len = skb->tail - skb->nh.raw; 524 (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
525 unsigned int packet_len = skb->tail - skb->network_header;
527 int found_rhdr = 0; 526 int found_rhdr = 0;
528 *nexthdr = &skb->nh.ipv6h->nexthdr; 527 *nexthdr = &ipv6_hdr(skb)->nexthdr;
529 528
530 while (offset + 1 <= packet_len) { 529 while (offset + 1 <= packet_len) {
531 530
@@ -550,7 +549,8 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
550 549
551 offset += ipv6_optlen(exthdr); 550 offset += ipv6_optlen(exthdr);
552 *nexthdr = &exthdr->nexthdr; 551 *nexthdr = &exthdr->nexthdr;
553 exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); 552 exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
553 offset);
554 } 554 }
555 555
556 return offset; 556 return offset;
@@ -574,7 +574,20 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
574 hlen = ip6_find_1stfragopt(skb, &prevhdr); 574 hlen = ip6_find_1stfragopt(skb, &prevhdr);
575 nexthdr = *prevhdr; 575 nexthdr = *prevhdr;
576 576
577 mtu = dst_mtu(&rt->u.dst); 577 mtu = ip6_skb_dst_mtu(skb);
578
579 /* We must not fragment if the socket is set to force MTU discovery
580 * or if the skb it not generated by a local socket. (This last
581 * check should be redundant, but it's free.)
582 */
583 if (!np || np->pmtudisc >= IPV6_PMTUDISC_DO) {
584 skb->dev = skb->dst->dev;
585 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
586 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
587 kfree_skb(skb);
588 return -EMSGSIZE;
589 }
590
578 if (np && np->frag_size < mtu) { 591 if (np && np->frag_size < mtu) {
579 if (np->frag_size) 592 if (np->frag_size)
580 mtu = np->frag_size; 593 mtu = np->frag_size;
@@ -616,7 +629,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
616 /* BUILD HEADER */ 629 /* BUILD HEADER */
617 630
618 *prevhdr = NEXTHDR_FRAGMENT; 631 *prevhdr = NEXTHDR_FRAGMENT;
619 tmp_hdr = kmemdup(skb->nh.raw, hlen, GFP_ATOMIC); 632 tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
620 if (!tmp_hdr) { 633 if (!tmp_hdr) {
621 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); 634 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
622 return -ENOMEM; 635 return -ENOMEM;
@@ -624,8 +637,9 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
624 637
625 __skb_pull(skb, hlen); 638 __skb_pull(skb, hlen);
626 fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr)); 639 fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr));
627 skb->nh.raw = __skb_push(skb, hlen); 640 __skb_push(skb, hlen);
628 memcpy(skb->nh.raw, tmp_hdr, hlen); 641 skb_reset_network_header(skb);
642 memcpy(skb_network_header(skb), tmp_hdr, hlen);
629 643
630 ipv6_select_ident(skb, fh); 644 ipv6_select_ident(skb, fh);
631 fh->nexthdr = nexthdr; 645 fh->nexthdr = nexthdr;
@@ -636,7 +650,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
636 first_len = skb_pagelen(skb); 650 first_len = skb_pagelen(skb);
637 skb->data_len = first_len - skb_headlen(skb); 651 skb->data_len = first_len - skb_headlen(skb);
638 skb->len = first_len; 652 skb->len = first_len;
639 skb->nh.ipv6h->payload_len = htons(first_len - sizeof(struct ipv6hdr)); 653 ipv6_hdr(skb)->payload_len = htons(first_len -
654 sizeof(struct ipv6hdr));
640 655
641 dst_hold(&rt->u.dst); 656 dst_hold(&rt->u.dst);
642 657
@@ -645,10 +660,12 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
645 * before previous one went down. */ 660 * before previous one went down. */
646 if (frag) { 661 if (frag) {
647 frag->ip_summed = CHECKSUM_NONE; 662 frag->ip_summed = CHECKSUM_NONE;
648 frag->h.raw = frag->data; 663 skb_reset_transport_header(frag);
649 fh = (struct frag_hdr*)__skb_push(frag, sizeof(struct frag_hdr)); 664 fh = (struct frag_hdr*)__skb_push(frag, sizeof(struct frag_hdr));
650 frag->nh.raw = __skb_push(frag, hlen); 665 __skb_push(frag, hlen);
651 memcpy(frag->nh.raw, tmp_hdr, hlen); 666 skb_reset_network_header(frag);
667 memcpy(skb_network_header(frag), tmp_hdr,
668 hlen);
652 offset += skb->len - hlen - sizeof(struct frag_hdr); 669 offset += skb->len - hlen - sizeof(struct frag_hdr);
653 fh->nexthdr = nexthdr; 670 fh->nexthdr = nexthdr;
654 fh->reserved = 0; 671 fh->reserved = 0;
@@ -656,7 +673,9 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
656 if (frag->next != NULL) 673 if (frag->next != NULL)
657 fh->frag_off |= htons(IP6_MF); 674 fh->frag_off |= htons(IP6_MF);
658 fh->identification = frag_id; 675 fh->identification = frag_id;
659 frag->nh.ipv6h->payload_len = htons(frag->len - sizeof(struct ipv6hdr)); 676 ipv6_hdr(frag)->payload_len =
677 htons(frag->len -
678 sizeof(struct ipv6hdr));
660 ip6_copy_metadata(frag, skb); 679 ip6_copy_metadata(frag, skb);
661 } 680 }
662 681
@@ -733,9 +752,10 @@ slow_path:
733 ip6_copy_metadata(frag, skb); 752 ip6_copy_metadata(frag, skb);
734 skb_reserve(frag, LL_RESERVED_SPACE(rt->u.dst.dev)); 753 skb_reserve(frag, LL_RESERVED_SPACE(rt->u.dst.dev));
735 skb_put(frag, len + hlen + sizeof(struct frag_hdr)); 754 skb_put(frag, len + hlen + sizeof(struct frag_hdr));
736 frag->nh.raw = frag->data; 755 skb_reset_network_header(frag);
737 fh = (struct frag_hdr*)(frag->data + hlen); 756 fh = (struct frag_hdr *)(skb_network_header(frag) + hlen);
738 frag->h.raw = frag->data + hlen + sizeof(struct frag_hdr); 757 frag->transport_header = (frag->network_header + hlen +
758 sizeof(struct frag_hdr));
739 759
740 /* 760 /*
741 * Charge the memory for the fragment to any owner 761 * Charge the memory for the fragment to any owner
@@ -747,7 +767,7 @@ slow_path:
747 /* 767 /*
748 * Copy the packet header into the new buffer. 768 * Copy the packet header into the new buffer.
749 */ 769 */
750 memcpy(frag->nh.raw, skb->data, hlen); 770 skb_copy_from_linear_data(skb, skb_network_header(frag), hlen);
751 771
752 /* 772 /*
753 * Build fragment header. 773 * Build fragment header.
@@ -763,14 +783,15 @@ slow_path:
763 /* 783 /*
764 * Copy a block of the IP datagram. 784 * Copy a block of the IP datagram.
765 */ 785 */
766 if (skb_copy_bits(skb, ptr, frag->h.raw, len)) 786 if (skb_copy_bits(skb, ptr, skb_transport_header(skb), len))
767 BUG(); 787 BUG();
768 left -= len; 788 left -= len;
769 789
770 fh->frag_off = htons(offset); 790 fh->frag_off = htons(offset);
771 if (left > 0) 791 if (left > 0)
772 fh->frag_off |= htons(IP6_MF); 792 fh->frag_off |= htons(IP6_MF);
773 frag->nh.ipv6h->payload_len = htons(frag->len - sizeof(struct ipv6hdr)); 793 ipv6_hdr(frag)->payload_len = htons(frag->len -
794 sizeof(struct ipv6hdr));
774 795
775 ptr += len; 796 ptr += len;
776 offset += len; 797 offset += len;
@@ -861,6 +882,41 @@ static int ip6_dst_lookup_tail(struct sock *sk,
861 goto out_err_release; 882 goto out_err_release;
862 } 883 }
863 884
885#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
886 /*
887 * Here if the dst entry we've looked up
888 * has a neighbour entry that is in the INCOMPLETE
889 * state and the src address from the flow is
890 * marked as OPTIMISTIC, we release the found
891 * dst entry and replace it instead with the
892 * dst entry of the nexthop router
893 */
894 if (!((*dst)->neighbour->nud_state & NUD_VALID)) {
895 struct inet6_ifaddr *ifp;
896 struct flowi fl_gw;
897 int redirect;
898
899 ifp = ipv6_get_ifaddr(&fl->fl6_src, (*dst)->dev, 1);
900
901 redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
902 if (ifp)
903 in6_ifa_put(ifp);
904
905 if (redirect) {
906 /*
907 * We need to get the dst entry for the
908 * default router instead
909 */
910 dst_release(*dst);
911 memcpy(&fl_gw, fl, sizeof(struct flowi));
912 memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
913 *dst = ip6_route_output(sk, &fl_gw);
914 if ((err = (*dst)->error))
915 goto out_err_release;
916 }
917 }
918#endif
919
864 return 0; 920 return 0;
865 921
866out_err_release: 922out_err_release:
@@ -939,10 +995,10 @@ static inline int ip6_ufo_append_data(struct sock *sk,
939 skb_put(skb,fragheaderlen + transhdrlen); 995 skb_put(skb,fragheaderlen + transhdrlen);
940 996
941 /* initialize network header pointer */ 997 /* initialize network header pointer */
942 skb->nh.raw = skb->data; 998 skb_reset_network_header(skb);
943 999
944 /* initialize protocol header pointer */ 1000 /* initialize protocol header pointer */
945 skb->h.raw = skb->data + fragheaderlen; 1001 skb->transport_header = skb->network_header + fragheaderlen;
946 1002
947 skb->ip_summed = CHECKSUM_PARTIAL; 1003 skb->ip_summed = CHECKSUM_PARTIAL;
948 skb->csum = 0; 1004 skb->csum = 0;
@@ -1015,7 +1071,8 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1015 inet->cork.fl = *fl; 1071 inet->cork.fl = *fl;
1016 np->cork.hop_limit = hlimit; 1072 np->cork.hop_limit = hlimit;
1017 np->cork.tclass = tclass; 1073 np->cork.tclass = tclass;
1018 mtu = dst_mtu(rt->u.dst.path); 1074 mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ?
1075 rt->u.dst.dev->mtu : dst_mtu(rt->u.dst.path);
1019 if (np->frag_size < mtu) { 1076 if (np->frag_size < mtu) {
1020 if (np->frag_size) 1077 if (np->frag_size)
1021 mtu = np->frag_size; 1078 mtu = np->frag_size;
@@ -1162,10 +1219,10 @@ alloc_new_skb:
1162 * Find where to start putting bytes 1219 * Find where to start putting bytes
1163 */ 1220 */
1164 data = skb_put(skb, fraglen); 1221 data = skb_put(skb, fraglen);
1165 skb->nh.raw = data + exthdrlen; 1222 skb_set_network_header(skb, exthdrlen);
1166 data += fragheaderlen; 1223 data += fragheaderlen;
1167 skb->h.raw = data + exthdrlen; 1224 skb->transport_header = (skb->network_header +
1168 1225 fragheaderlen);
1169 if (fraggap) { 1226 if (fraggap) {
1170 skb->csum = skb_copy_and_csum_bits( 1227 skb->csum = skb_copy_and_csum_bits(
1171 skb_prev, maxfraglen, 1228 skb_prev, maxfraglen,
@@ -1288,10 +1345,10 @@ int ip6_push_pending_frames(struct sock *sk)
1288 tail_skb = &(skb_shinfo(skb)->frag_list); 1345 tail_skb = &(skb_shinfo(skb)->frag_list);
1289 1346
1290 /* move skb->data to ip header from ext header */ 1347 /* move skb->data to ip header from ext header */
1291 if (skb->data < skb->nh.raw) 1348 if (skb->data < skb_network_header(skb))
1292 __skb_pull(skb, skb->nh.raw - skb->data); 1349 __skb_pull(skb, skb_network_offset(skb));
1293 while ((tmp_skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) { 1350 while ((tmp_skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) {
1294 __skb_pull(tmp_skb, skb->h.raw - skb->nh.raw); 1351 __skb_pull(tmp_skb, skb_network_header_len(skb));
1295 *tail_skb = tmp_skb; 1352 *tail_skb = tmp_skb;
1296 tail_skb = &(tmp_skb->next); 1353 tail_skb = &(tmp_skb->next);
1297 skb->len += tmp_skb->len; 1354 skb->len += tmp_skb->len;
@@ -1303,13 +1360,15 @@ int ip6_push_pending_frames(struct sock *sk)
1303 } 1360 }
1304 1361
1305 ipv6_addr_copy(final_dst, &fl->fl6_dst); 1362 ipv6_addr_copy(final_dst, &fl->fl6_dst);
1306 __skb_pull(skb, skb->h.raw - skb->nh.raw); 1363 __skb_pull(skb, skb_network_header_len(skb));
1307 if (opt && opt->opt_flen) 1364 if (opt && opt->opt_flen)
1308 ipv6_push_frag_opts(skb, opt, &proto); 1365 ipv6_push_frag_opts(skb, opt, &proto);
1309 if (opt && opt->opt_nflen) 1366 if (opt && opt->opt_nflen)
1310 ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst); 1367 ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst);
1311 1368
1312 skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr)); 1369 skb_push(skb, sizeof(struct ipv6hdr));
1370 skb_reset_network_header(skb);
1371 hdr = ipv6_hdr(skb);
1313 1372
1314 *(__be32*)hdr = fl->fl6_flowlabel | 1373 *(__be32*)hdr = fl->fl6_flowlabel |
1315 htonl(0x60000000 | ((int)np->cork.tclass << 20)); 1374 htonl(0x60000000 | ((int)np->cork.tclass << 20));