diff options
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r-- | net/ipv6/ip6_output.c | 67 |
1 files changed, 33 insertions, 34 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 735a2bf4b5f1..7c76e3d18215 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -78,7 +78,7 @@ int __ip6_local_out(struct sk_buff *skb) | |||
78 | len = 0; | 78 | len = 0; |
79 | ipv6_hdr(skb)->payload_len = htons(len); | 79 | ipv6_hdr(skb)->payload_len = htons(len); |
80 | 80 | ||
81 | return nf_hook(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dst->dev, | 81 | return nf_hook(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev, |
82 | dst_output); | 82 | dst_output); |
83 | } | 83 | } |
84 | 84 | ||
@@ -96,7 +96,7 @@ EXPORT_SYMBOL_GPL(ip6_local_out); | |||
96 | 96 | ||
97 | static int ip6_output_finish(struct sk_buff *skb) | 97 | static int ip6_output_finish(struct sk_buff *skb) |
98 | { | 98 | { |
99 | struct dst_entry *dst = skb->dst; | 99 | struct dst_entry *dst = skb_dst(skb); |
100 | 100 | ||
101 | if (dst->hh) | 101 | if (dst->hh) |
102 | return neigh_hh_output(dst->hh, skb); | 102 | return neigh_hh_output(dst->hh, skb); |
@@ -117,7 +117,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb) | |||
117 | __skb_pull(newskb, skb_network_offset(newskb)); | 117 | __skb_pull(newskb, skb_network_offset(newskb)); |
118 | newskb->pkt_type = PACKET_LOOPBACK; | 118 | newskb->pkt_type = PACKET_LOOPBACK; |
119 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 119 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
120 | WARN_ON(!newskb->dst); | 120 | WARN_ON(!skb_dst(newskb)); |
121 | 121 | ||
122 | netif_rx(newskb); | 122 | netif_rx(newskb); |
123 | return 0; | 123 | return 0; |
@@ -126,7 +126,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb) | |||
126 | 126 | ||
127 | static int ip6_output2(struct sk_buff *skb) | 127 | static int ip6_output2(struct sk_buff *skb) |
128 | { | 128 | { |
129 | struct dst_entry *dst = skb->dst; | 129 | struct dst_entry *dst = skb_dst(skb); |
130 | struct net_device *dev = dst->dev; | 130 | struct net_device *dev = dst->dev; |
131 | 131 | ||
132 | skb->protocol = htons(ETH_P_IPV6); | 132 | skb->protocol = htons(ETH_P_IPV6); |
@@ -134,7 +134,7 @@ static int ip6_output2(struct sk_buff *skb) | |||
134 | 134 | ||
135 | if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) { | 135 | if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) { |
136 | struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL; | 136 | struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL; |
137 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); | 137 | struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); |
138 | 138 | ||
139 | if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && | 139 | if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && |
140 | ((mroute6_socket(dev_net(dev)) && | 140 | ((mroute6_socket(dev_net(dev)) && |
@@ -172,21 +172,21 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb) | |||
172 | struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; | 172 | struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; |
173 | 173 | ||
174 | return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ? | 174 | return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ? |
175 | skb->dst->dev->mtu : dst_mtu(skb->dst); | 175 | skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb)); |
176 | } | 176 | } |
177 | 177 | ||
178 | int ip6_output(struct sk_buff *skb) | 178 | int ip6_output(struct sk_buff *skb) |
179 | { | 179 | { |
180 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); | 180 | struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); |
181 | if (unlikely(idev->cnf.disable_ipv6)) { | 181 | if (unlikely(idev->cnf.disable_ipv6)) { |
182 | IP6_INC_STATS(dev_net(skb->dst->dev), idev, | 182 | IP6_INC_STATS(dev_net(skb_dst(skb)->dev), idev, |
183 | IPSTATS_MIB_OUTDISCARDS); | 183 | IPSTATS_MIB_OUTDISCARDS); |
184 | kfree_skb(skb); | 184 | kfree_skb(skb); |
185 | return 0; | 185 | return 0; |
186 | } | 186 | } |
187 | 187 | ||
188 | if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || | 188 | if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || |
189 | dst_allfrag(skb->dst)) | 189 | dst_allfrag(skb_dst(skb))) |
190 | return ip6_fragment(skb, ip6_output2); | 190 | return ip6_fragment(skb, ip6_output2); |
191 | else | 191 | else |
192 | return ip6_output2(skb); | 192 | return ip6_output2(skb); |
@@ -202,7 +202,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
202 | struct net *net = sock_net(sk); | 202 | struct net *net = sock_net(sk); |
203 | struct ipv6_pinfo *np = inet6_sk(sk); | 203 | struct ipv6_pinfo *np = inet6_sk(sk); |
204 | struct in6_addr *first_hop = &fl->fl6_dst; | 204 | struct in6_addr *first_hop = &fl->fl6_dst; |
205 | struct dst_entry *dst = skb->dst; | 205 | struct dst_entry *dst = skb_dst(skb); |
206 | struct ipv6hdr *hdr; | 206 | struct ipv6hdr *hdr; |
207 | u8 proto = fl->proto; | 207 | u8 proto = fl->proto; |
208 | int seg_len = skb->len; | 208 | int seg_len = skb->len; |
@@ -222,7 +222,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
222 | if (skb_headroom(skb) < head_room) { | 222 | if (skb_headroom(skb) < head_room) { |
223 | struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); | 223 | struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); |
224 | if (skb2 == NULL) { | 224 | if (skb2 == NULL) { |
225 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), | 225 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
226 | IPSTATS_MIB_OUTDISCARDS); | 226 | IPSTATS_MIB_OUTDISCARDS); |
227 | kfree_skb(skb); | 227 | kfree_skb(skb); |
228 | return -ENOBUFS; | 228 | return -ENOBUFS; |
@@ -276,7 +276,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
276 | 276 | ||
277 | mtu = dst_mtu(dst); | 277 | mtu = dst_mtu(dst); |
278 | if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { | 278 | if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { |
279 | IP6_UPD_PO_STATS(net, ip6_dst_idev(skb->dst), | 279 | IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)), |
280 | IPSTATS_MIB_OUT, skb->len); | 280 | IPSTATS_MIB_OUT, skb->len); |
281 | return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, | 281 | return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, |
282 | dst_output); | 282 | dst_output); |
@@ -286,7 +286,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
286 | printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); | 286 | printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); |
287 | skb->dev = dst->dev; | 287 | skb->dev = dst->dev; |
288 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); | 288 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); |
289 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); | 289 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); |
290 | kfree_skb(skb); | 290 | kfree_skb(skb); |
291 | return -EMSGSIZE; | 291 | return -EMSGSIZE; |
292 | } | 292 | } |
@@ -416,7 +416,7 @@ static inline int ip6_forward_finish(struct sk_buff *skb) | |||
416 | 416 | ||
417 | int ip6_forward(struct sk_buff *skb) | 417 | int ip6_forward(struct sk_buff *skb) |
418 | { | 418 | { |
419 | struct dst_entry *dst = skb->dst; | 419 | struct dst_entry *dst = skb_dst(skb); |
420 | struct ipv6hdr *hdr = ipv6_hdr(skb); | 420 | struct ipv6hdr *hdr = ipv6_hdr(skb); |
421 | struct inet6_skb_parm *opt = IP6CB(skb); | 421 | struct inet6_skb_parm *opt = IP6CB(skb); |
422 | struct net *net = dev_net(dst->dev); | 422 | struct net *net = dev_net(dst->dev); |
@@ -485,7 +485,7 @@ int ip6_forward(struct sk_buff *skb) | |||
485 | IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); | 485 | IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); |
486 | goto drop; | 486 | goto drop; |
487 | } | 487 | } |
488 | dst = skb->dst; | 488 | dst = skb_dst(skb); |
489 | 489 | ||
490 | /* IPv6 specs say nothing about it, but it is clear that we cannot | 490 | /* IPv6 specs say nothing about it, but it is clear that we cannot |
491 | send redirects to source routed frames. | 491 | send redirects to source routed frames. |
@@ -566,8 +566,8 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
566 | to->pkt_type = from->pkt_type; | 566 | to->pkt_type = from->pkt_type; |
567 | to->priority = from->priority; | 567 | to->priority = from->priority; |
568 | to->protocol = from->protocol; | 568 | to->protocol = from->protocol; |
569 | dst_release(to->dst); | 569 | skb_dst_drop(to); |
570 | to->dst = dst_clone(from->dst); | 570 | skb_dst_set(to, dst_clone(skb_dst(from))); |
571 | to->dev = from->dev; | 571 | to->dev = from->dev; |
572 | to->mark = from->mark; | 572 | to->mark = from->mark; |
573 | 573 | ||
@@ -624,7 +624,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) | |||
624 | static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | 624 | static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
625 | { | 625 | { |
626 | struct sk_buff *frag; | 626 | struct sk_buff *frag; |
627 | struct rt6_info *rt = (struct rt6_info*)skb->dst; | 627 | struct rt6_info *rt = (struct rt6_info*)skb_dst(skb); |
628 | struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; | 628 | struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; |
629 | struct ipv6hdr *tmp_hdr; | 629 | struct ipv6hdr *tmp_hdr; |
630 | struct frag_hdr *fh; | 630 | struct frag_hdr *fh; |
@@ -632,7 +632,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
632 | __be32 frag_id = 0; | 632 | __be32 frag_id = 0; |
633 | int ptr, offset = 0, err=0; | 633 | int ptr, offset = 0, err=0; |
634 | u8 *prevhdr, nexthdr = 0; | 634 | u8 *prevhdr, nexthdr = 0; |
635 | struct net *net = dev_net(skb->dst->dev); | 635 | struct net *net = dev_net(skb_dst(skb)->dev); |
636 | 636 | ||
637 | hlen = ip6_find_1stfragopt(skb, &prevhdr); | 637 | hlen = ip6_find_1stfragopt(skb, &prevhdr); |
638 | nexthdr = *prevhdr; | 638 | nexthdr = *prevhdr; |
@@ -644,9 +644,9 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
644 | * check should be redundant, but it's free.) | 644 | * check should be redundant, but it's free.) |
645 | */ | 645 | */ |
646 | if (!skb->local_df) { | 646 | if (!skb->local_df) { |
647 | skb->dev = skb->dst->dev; | 647 | skb->dev = skb_dst(skb)->dev; |
648 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); | 648 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); |
649 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), | 649 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
650 | IPSTATS_MIB_FRAGFAILS); | 650 | IPSTATS_MIB_FRAGFAILS); |
651 | kfree_skb(skb); | 651 | kfree_skb(skb); |
652 | return -EMSGSIZE; | 652 | return -EMSGSIZE; |
@@ -658,7 +658,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
658 | } | 658 | } |
659 | mtu -= hlen + sizeof(struct frag_hdr); | 659 | mtu -= hlen + sizeof(struct frag_hdr); |
660 | 660 | ||
661 | if (skb_shinfo(skb)->frag_list) { | 661 | if (skb_has_frags(skb)) { |
662 | int first_len = skb_pagelen(skb); | 662 | int first_len = skb_pagelen(skb); |
663 | int truesizes = 0; | 663 | int truesizes = 0; |
664 | 664 | ||
@@ -667,7 +667,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
667 | skb_cloned(skb)) | 667 | skb_cloned(skb)) |
668 | goto slow_path; | 668 | goto slow_path; |
669 | 669 | ||
670 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { | 670 | skb_walk_frags(skb, frag) { |
671 | /* Correct geometry. */ | 671 | /* Correct geometry. */ |
672 | if (frag->len > mtu || | 672 | if (frag->len > mtu || |
673 | ((frag->len & 7) && frag->next) || | 673 | ((frag->len & 7) && frag->next) || |
@@ -680,7 +680,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
680 | 680 | ||
681 | BUG_ON(frag->sk); | 681 | BUG_ON(frag->sk); |
682 | if (skb->sk) { | 682 | if (skb->sk) { |
683 | sock_hold(skb->sk); | ||
684 | frag->sk = skb->sk; | 683 | frag->sk = skb->sk; |
685 | frag->destructor = sock_wfree; | 684 | frag->destructor = sock_wfree; |
686 | truesizes += frag->truesize; | 685 | truesizes += frag->truesize; |
@@ -690,13 +689,13 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
690 | err = 0; | 689 | err = 0; |
691 | offset = 0; | 690 | offset = 0; |
692 | frag = skb_shinfo(skb)->frag_list; | 691 | frag = skb_shinfo(skb)->frag_list; |
693 | skb_shinfo(skb)->frag_list = NULL; | 692 | skb_frag_list_init(skb); |
694 | /* BUILD HEADER */ | 693 | /* BUILD HEADER */ |
695 | 694 | ||
696 | *prevhdr = NEXTHDR_FRAGMENT; | 695 | *prevhdr = NEXTHDR_FRAGMENT; |
697 | tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC); | 696 | tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC); |
698 | if (!tmp_hdr) { | 697 | if (!tmp_hdr) { |
699 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), | 698 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
700 | IPSTATS_MIB_FRAGFAILS); | 699 | IPSTATS_MIB_FRAGFAILS); |
701 | return -ENOMEM; | 700 | return -ENOMEM; |
702 | } | 701 | } |
@@ -809,7 +808,7 @@ slow_path: | |||
809 | 808 | ||
810 | if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { | 809 | if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { |
811 | NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); | 810 | NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); |
812 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), | 811 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
813 | IPSTATS_MIB_FRAGFAILS); | 812 | IPSTATS_MIB_FRAGFAILS); |
814 | err = -ENOMEM; | 813 | err = -ENOMEM; |
815 | goto fail; | 814 | goto fail; |
@@ -873,16 +872,16 @@ slow_path: | |||
873 | if (err) | 872 | if (err) |
874 | goto fail; | 873 | goto fail; |
875 | 874 | ||
876 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), | 875 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
877 | IPSTATS_MIB_FRAGCREATES); | 876 | IPSTATS_MIB_FRAGCREATES); |
878 | } | 877 | } |
879 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), | 878 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
880 | IPSTATS_MIB_FRAGOKS); | 879 | IPSTATS_MIB_FRAGOKS); |
881 | kfree_skb(skb); | 880 | kfree_skb(skb); |
882 | return err; | 881 | return err; |
883 | 882 | ||
884 | fail: | 883 | fail: |
885 | IP6_INC_STATS(net, ip6_dst_idev(skb->dst), | 884 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
886 | IPSTATS_MIB_FRAGFAILS); | 885 | IPSTATS_MIB_FRAGFAILS); |
887 | kfree_skb(skb); | 886 | kfree_skb(skb); |
888 | return err; | 887 | return err; |
@@ -1516,10 +1515,10 @@ int ip6_push_pending_frames(struct sock *sk) | |||
1516 | skb->priority = sk->sk_priority; | 1515 | skb->priority = sk->sk_priority; |
1517 | skb->mark = sk->sk_mark; | 1516 | skb->mark = sk->sk_mark; |
1518 | 1517 | ||
1519 | skb->dst = dst_clone(&rt->u.dst); | 1518 | skb_dst_set(skb, dst_clone(&rt->u.dst)); |
1520 | IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len); | 1519 | IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len); |
1521 | if (proto == IPPROTO_ICMPV6) { | 1520 | if (proto == IPPROTO_ICMPV6) { |
1522 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); | 1521 | struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); |
1523 | 1522 | ||
1524 | ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type); | 1523 | ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type); |
1525 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); | 1524 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); |
@@ -1545,8 +1544,8 @@ void ip6_flush_pending_frames(struct sock *sk) | |||
1545 | struct sk_buff *skb; | 1544 | struct sk_buff *skb; |
1546 | 1545 | ||
1547 | while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { | 1546 | while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { |
1548 | if (skb->dst) | 1547 | if (skb_dst(skb)) |
1549 | IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb->dst), | 1548 | IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb_dst(skb)), |
1550 | IPSTATS_MIB_OUTDISCARDS); | 1549 | IPSTATS_MIB_OUTDISCARDS); |
1551 | kfree_skb(skb); | 1550 | kfree_skb(skb); |
1552 | } | 1551 | } |