aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-15 12:40:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-15 12:40:05 -0400
commit2ed0e21b30b53d3a94e204196e523e6c8f732b56 (patch)
treede2635426477d86338a9469ce09ba0626052288f /net/ipv6/ip6_output.c
parent0fa213310cd8fa7a51071cdcf130e26fa56e9549 (diff)
parent9cbc1cb8cd46ce1f7645b9de249b2ce8460129bb (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1244 commits) pkt_sched: Rename PSCHED_US2NS and PSCHED_NS2US ipv4: Fix fib_trie rebalancing Bluetooth: Fix issue with uninitialized nsh.type in DTL-1 driver Bluetooth: Fix Kconfig issue with RFKILL integration PIM-SM: namespace changes ipv4: update ARPD help text net: use a deferred timer in rt_check_expire ieee802154: fix kconfig bool/tristate muckup bonding: initialization rework bonding: use is_zero_ether_addr bonding: network device names are case sensative bonding: elminate bad refcount code bonding: fix style issues bonding: fix destructor bonding: remove bonding read/write semaphore bonding: initialize before registration bonding: bond_create always called with default parameters x_tables: Convert printk to pr_err netfilter: conntrack: optional reliable conntrack event delivery list_nulls: add hlist_nulls_add_head and hlist_nulls_del ...
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r--net/ipv6/ip6_output.c74
1 files changed, 37 insertions, 37 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 9fb49c3b518a..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
97static int ip6_output_finish(struct sk_buff *skb) 97static 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
127static int ip6_output2(struct sk_buff *skb) 127static 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)) &&
@@ -159,7 +159,8 @@ static int ip6_output2(struct sk_buff *skb)
159 } 159 }
160 } 160 }
161 161
162 IP6_INC_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCASTPKTS); 162 IP6_UPD_PO_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCAST,
163 skb->len);
163 } 164 }
164 165
165 return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev, 166 return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
@@ -171,21 +172,21 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
171 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; 172 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
172 173
173 return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ? 174 return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ?
174 skb->dst->dev->mtu : dst_mtu(skb->dst); 175 skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
175} 176}
176 177
177int ip6_output(struct sk_buff *skb) 178int ip6_output(struct sk_buff *skb)
178{ 179{
179 struct inet6_dev *idev = ip6_dst_idev(skb->dst); 180 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
180 if (unlikely(idev->cnf.disable_ipv6)) { 181 if (unlikely(idev->cnf.disable_ipv6)) {
181 IP6_INC_STATS(dev_net(skb->dst->dev), idev, 182 IP6_INC_STATS(dev_net(skb_dst(skb)->dev), idev,
182 IPSTATS_MIB_OUTDISCARDS); 183 IPSTATS_MIB_OUTDISCARDS);
183 kfree_skb(skb); 184 kfree_skb(skb);
184 return 0; 185 return 0;
185 } 186 }
186 187
187 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)) ||
188 dst_allfrag(skb->dst)) 189 dst_allfrag(skb_dst(skb)))
189 return ip6_fragment(skb, ip6_output2); 190 return ip6_fragment(skb, ip6_output2);
190 else 191 else
191 return ip6_output2(skb); 192 return ip6_output2(skb);
@@ -201,7 +202,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
201 struct net *net = sock_net(sk); 202 struct net *net = sock_net(sk);
202 struct ipv6_pinfo *np = inet6_sk(sk); 203 struct ipv6_pinfo *np = inet6_sk(sk);
203 struct in6_addr *first_hop = &fl->fl6_dst; 204 struct in6_addr *first_hop = &fl->fl6_dst;
204 struct dst_entry *dst = skb->dst; 205 struct dst_entry *dst = skb_dst(skb);
205 struct ipv6hdr *hdr; 206 struct ipv6hdr *hdr;
206 u8 proto = fl->proto; 207 u8 proto = fl->proto;
207 int seg_len = skb->len; 208 int seg_len = skb->len;
@@ -221,7 +222,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
221 if (skb_headroom(skb) < head_room) { 222 if (skb_headroom(skb) < head_room) {
222 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); 223 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
223 if (skb2 == NULL) { 224 if (skb2 == NULL) {
224 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), 225 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
225 IPSTATS_MIB_OUTDISCARDS); 226 IPSTATS_MIB_OUTDISCARDS);
226 kfree_skb(skb); 227 kfree_skb(skb);
227 return -ENOBUFS; 228 return -ENOBUFS;
@@ -275,8 +276,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
275 276
276 mtu = dst_mtu(dst); 277 mtu = dst_mtu(dst);
277 if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { 278 if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) {
278 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), 279 IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)),
279 IPSTATS_MIB_OUTREQUESTS); 280 IPSTATS_MIB_OUT, skb->len);
280 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,
281 dst_output); 282 dst_output);
282 } 283 }
@@ -285,7 +286,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
285 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); 286 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
286 skb->dev = dst->dev; 287 skb->dev = dst->dev;
287 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 288 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
288 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);
289 kfree_skb(skb); 290 kfree_skb(skb);
290 return -EMSGSIZE; 291 return -EMSGSIZE;
291} 292}
@@ -415,7 +416,7 @@ static inline int ip6_forward_finish(struct sk_buff *skb)
415 416
416int ip6_forward(struct sk_buff *skb) 417int ip6_forward(struct sk_buff *skb)
417{ 418{
418 struct dst_entry *dst = skb->dst; 419 struct dst_entry *dst = skb_dst(skb);
419 struct ipv6hdr *hdr = ipv6_hdr(skb); 420 struct ipv6hdr *hdr = ipv6_hdr(skb);
420 struct inet6_skb_parm *opt = IP6CB(skb); 421 struct inet6_skb_parm *opt = IP6CB(skb);
421 struct net *net = dev_net(dst->dev); 422 struct net *net = dev_net(dst->dev);
@@ -484,7 +485,7 @@ int ip6_forward(struct sk_buff *skb)
484 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); 485 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
485 goto drop; 486 goto drop;
486 } 487 }
487 dst = skb->dst; 488 dst = skb_dst(skb);
488 489
489 /* 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
490 send redirects to source routed frames. 491 send redirects to source routed frames.
@@ -565,8 +566,8 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
565 to->pkt_type = from->pkt_type; 566 to->pkt_type = from->pkt_type;
566 to->priority = from->priority; 567 to->priority = from->priority;
567 to->protocol = from->protocol; 568 to->protocol = from->protocol;
568 dst_release(to->dst); 569 skb_dst_drop(to);
569 to->dst = dst_clone(from->dst); 570 skb_dst_set(to, dst_clone(skb_dst(from)));
570 to->dev = from->dev; 571 to->dev = from->dev;
571 to->mark = from->mark; 572 to->mark = from->mark;
572 573
@@ -623,7 +624,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
623static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) 624static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
624{ 625{
625 struct sk_buff *frag; 626 struct sk_buff *frag;
626 struct rt6_info *rt = (struct rt6_info*)skb->dst; 627 struct rt6_info *rt = (struct rt6_info*)skb_dst(skb);
627 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; 628 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
628 struct ipv6hdr *tmp_hdr; 629 struct ipv6hdr *tmp_hdr;
629 struct frag_hdr *fh; 630 struct frag_hdr *fh;
@@ -631,7 +632,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
631 __be32 frag_id = 0; 632 __be32 frag_id = 0;
632 int ptr, offset = 0, err=0; 633 int ptr, offset = 0, err=0;
633 u8 *prevhdr, nexthdr = 0; 634 u8 *prevhdr, nexthdr = 0;
634 struct net *net = dev_net(skb->dst->dev); 635 struct net *net = dev_net(skb_dst(skb)->dev);
635 636
636 hlen = ip6_find_1stfragopt(skb, &prevhdr); 637 hlen = ip6_find_1stfragopt(skb, &prevhdr);
637 nexthdr = *prevhdr; 638 nexthdr = *prevhdr;
@@ -643,9 +644,9 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
643 * check should be redundant, but it's free.) 644 * check should be redundant, but it's free.)
644 */ 645 */
645 if (!skb->local_df) { 646 if (!skb->local_df) {
646 skb->dev = skb->dst->dev; 647 skb->dev = skb_dst(skb)->dev;
647 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 648 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
648 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), 649 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
649 IPSTATS_MIB_FRAGFAILS); 650 IPSTATS_MIB_FRAGFAILS);
650 kfree_skb(skb); 651 kfree_skb(skb);
651 return -EMSGSIZE; 652 return -EMSGSIZE;
@@ -657,7 +658,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
657 } 658 }
658 mtu -= hlen + sizeof(struct frag_hdr); 659 mtu -= hlen + sizeof(struct frag_hdr);
659 660
660 if (skb_shinfo(skb)->frag_list) { 661 if (skb_has_frags(skb)) {
661 int first_len = skb_pagelen(skb); 662 int first_len = skb_pagelen(skb);
662 int truesizes = 0; 663 int truesizes = 0;
663 664
@@ -666,7 +667,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
666 skb_cloned(skb)) 667 skb_cloned(skb))
667 goto slow_path; 668 goto slow_path;
668 669
669 for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { 670 skb_walk_frags(skb, frag) {
670 /* Correct geometry. */ 671 /* Correct geometry. */
671 if (frag->len > mtu || 672 if (frag->len > mtu ||
672 ((frag->len & 7) && frag->next) || 673 ((frag->len & 7) && frag->next) ||
@@ -679,7 +680,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
679 680
680 BUG_ON(frag->sk); 681 BUG_ON(frag->sk);
681 if (skb->sk) { 682 if (skb->sk) {
682 sock_hold(skb->sk);
683 frag->sk = skb->sk; 683 frag->sk = skb->sk;
684 frag->destructor = sock_wfree; 684 frag->destructor = sock_wfree;
685 truesizes += frag->truesize; 685 truesizes += frag->truesize;
@@ -689,13 +689,13 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
689 err = 0; 689 err = 0;
690 offset = 0; 690 offset = 0;
691 frag = skb_shinfo(skb)->frag_list; 691 frag = skb_shinfo(skb)->frag_list;
692 skb_shinfo(skb)->frag_list = NULL; 692 skb_frag_list_init(skb);
693 /* BUILD HEADER */ 693 /* BUILD HEADER */
694 694
695 *prevhdr = NEXTHDR_FRAGMENT; 695 *prevhdr = NEXTHDR_FRAGMENT;
696 tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC); 696 tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
697 if (!tmp_hdr) { 697 if (!tmp_hdr) {
698 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), 698 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
699 IPSTATS_MIB_FRAGFAILS); 699 IPSTATS_MIB_FRAGFAILS);
700 return -ENOMEM; 700 return -ENOMEM;
701 } 701 }
@@ -808,7 +808,7 @@ slow_path:
808 808
809 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) {
810 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); 810 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
811 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), 811 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
812 IPSTATS_MIB_FRAGFAILS); 812 IPSTATS_MIB_FRAGFAILS);
813 err = -ENOMEM; 813 err = -ENOMEM;
814 goto fail; 814 goto fail;
@@ -872,16 +872,16 @@ slow_path:
872 if (err) 872 if (err)
873 goto fail; 873 goto fail;
874 874
875 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), 875 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
876 IPSTATS_MIB_FRAGCREATES); 876 IPSTATS_MIB_FRAGCREATES);
877 } 877 }
878 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), 878 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
879 IPSTATS_MIB_FRAGOKS); 879 IPSTATS_MIB_FRAGOKS);
880 kfree_skb(skb); 880 kfree_skb(skb);
881 return err; 881 return err;
882 882
883fail: 883fail:
884 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), 884 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
885 IPSTATS_MIB_FRAGFAILS); 885 IPSTATS_MIB_FRAGFAILS);
886 kfree_skb(skb); 886 kfree_skb(skb);
887 return err; 887 return err;
@@ -1515,10 +1515,10 @@ int ip6_push_pending_frames(struct sock *sk)
1515 skb->priority = sk->sk_priority; 1515 skb->priority = sk->sk_priority;
1516 skb->mark = sk->sk_mark; 1516 skb->mark = sk->sk_mark;
1517 1517
1518 skb->dst = dst_clone(&rt->u.dst); 1518 skb_dst_set(skb, dst_clone(&rt->u.dst));
1519 IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); 1519 IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
1520 if (proto == IPPROTO_ICMPV6) { 1520 if (proto == IPPROTO_ICMPV6) {
1521 struct inet6_dev *idev = ip6_dst_idev(skb->dst); 1521 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
1522 1522
1523 ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type); 1523 ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type);
1524 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); 1524 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
@@ -1544,8 +1544,8 @@ void ip6_flush_pending_frames(struct sock *sk)
1544 struct sk_buff *skb; 1544 struct sk_buff *skb;
1545 1545
1546 while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { 1546 while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
1547 if (skb->dst) 1547 if (skb_dst(skb))
1548 IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb->dst), 1548 IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb_dst(skb)),
1549 IPSTATS_MIB_OUTDISCARDS); 1549 IPSTATS_MIB_OUTDISCARDS);
1550 kfree_skb(skb); 1550 kfree_skb(skb);
1551 } 1551 }