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.c56
1 files changed, 34 insertions, 22 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index f22393e11666..db28c208f329 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -150,13 +150,14 @@ static int ip6_output2(struct sk_buff *skb)
150 ip6_dev_loopback_xmit); 150 ip6_dev_loopback_xmit);
151 151
152 if (ipv6_hdr(skb)->hop_limit == 0) { 152 if (ipv6_hdr(skb)->hop_limit == 0) {
153 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); 153 IP6_INC_STATS(dev_net(dev), idev,
154 IPSTATS_MIB_OUTDISCARDS);
154 kfree_skb(skb); 155 kfree_skb(skb);
155 return 0; 156 return 0;
156 } 157 }
157 } 158 }
158 159
159 IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS); 160 IP6_INC_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCASTPKTS);
160 } 161 }
161 162
162 return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev, 163 return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
@@ -175,7 +176,8 @@ int ip6_output(struct sk_buff *skb)
175{ 176{
176 struct inet6_dev *idev = ip6_dst_idev(skb->dst); 177 struct inet6_dev *idev = ip6_dst_idev(skb->dst);
177 if (unlikely(idev->cnf.disable_ipv6)) { 178 if (unlikely(idev->cnf.disable_ipv6)) {
178 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); 179 IP6_INC_STATS(dev_net(skb->dst->dev), idev,
180 IPSTATS_MIB_OUTDISCARDS);
179 kfree_skb(skb); 181 kfree_skb(skb);
180 return 0; 182 return 0;
181 } 183 }
@@ -194,6 +196,7 @@ int ip6_output(struct sk_buff *skb)
194int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, 196int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
195 struct ipv6_txoptions *opt, int ipfragok) 197 struct ipv6_txoptions *opt, int ipfragok)
196{ 198{
199 struct net *net = sock_net(sk);
197 struct ipv6_pinfo *np = inet6_sk(sk); 200 struct ipv6_pinfo *np = inet6_sk(sk);
198 struct in6_addr *first_hop = &fl->fl6_dst; 201 struct in6_addr *first_hop = &fl->fl6_dst;
199 struct dst_entry *dst = skb->dst; 202 struct dst_entry *dst = skb->dst;
@@ -216,7 +219,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
216 if (skb_headroom(skb) < head_room) { 219 if (skb_headroom(skb) < head_room) {
217 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); 220 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
218 if (skb2 == NULL) { 221 if (skb2 == NULL) {
219 IP6_INC_STATS(ip6_dst_idev(skb->dst), 222 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
220 IPSTATS_MIB_OUTDISCARDS); 223 IPSTATS_MIB_OUTDISCARDS);
221 kfree_skb(skb); 224 kfree_skb(skb);
222 return -ENOBUFS; 225 return -ENOBUFS;
@@ -270,7 +273,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
270 273
271 mtu = dst_mtu(dst); 274 mtu = dst_mtu(dst);
272 if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { 275 if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) {
273 IP6_INC_STATS(ip6_dst_idev(skb->dst), 276 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
274 IPSTATS_MIB_OUTREQUESTS); 277 IPSTATS_MIB_OUTREQUESTS);
275 return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, 278 return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
276 dst_output); 279 dst_output);
@@ -280,7 +283,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
280 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); 283 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
281 skb->dev = dst->dev; 284 skb->dev = dst->dev;
282 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 285 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
283 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); 286 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
284 kfree_skb(skb); 287 kfree_skb(skb);
285 return -EMSGSIZE; 288 return -EMSGSIZE;
286} 289}
@@ -422,7 +425,7 @@ int ip6_forward(struct sk_buff *skb)
422 goto drop; 425 goto drop;
423 426
424 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { 427 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
425 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); 428 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
426 goto drop; 429 goto drop;
427 } 430 }
428 431
@@ -468,13 +471,14 @@ int ip6_forward(struct sk_buff *skb)
468 if (proxied > 0) 471 if (proxied > 0)
469 return ip6_input(skb); 472 return ip6_input(skb);
470 else if (proxied < 0) { 473 else if (proxied < 0) {
471 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); 474 IP6_INC_STATS(net, ip6_dst_idev(dst),
475 IPSTATS_MIB_INDISCARDS);
472 goto drop; 476 goto drop;
473 } 477 }
474 } 478 }
475 479
476 if (!xfrm6_route_forward(skb)) { 480 if (!xfrm6_route_forward(skb)) {
477 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); 481 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
478 goto drop; 482 goto drop;
479 } 483 }
480 dst = skb->dst; 484 dst = skb->dst;
@@ -530,7 +534,7 @@ int ip6_forward(struct sk_buff *skb)
530 } 534 }
531 535
532 if (skb_cow(skb, dst->dev->hard_header_len)) { 536 if (skb_cow(skb, dst->dev->hard_header_len)) {
533 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS); 537 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS);
534 goto drop; 538 goto drop;
535 } 539 }
536 540
@@ -622,6 +626,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
622 __be32 frag_id = 0; 626 __be32 frag_id = 0;
623 int ptr, offset = 0, err=0; 627 int ptr, offset = 0, err=0;
624 u8 *prevhdr, nexthdr = 0; 628 u8 *prevhdr, nexthdr = 0;
629 struct net *net = dev_net(skb->dst->dev);
625 630
626 hlen = ip6_find_1stfragopt(skb, &prevhdr); 631 hlen = ip6_find_1stfragopt(skb, &prevhdr);
627 nexthdr = *prevhdr; 632 nexthdr = *prevhdr;
@@ -635,7 +640,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
635 if (!skb->local_df) { 640 if (!skb->local_df) {
636 skb->dev = skb->dst->dev; 641 skb->dev = skb->dst->dev;
637 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 642 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
638 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); 643 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
644 IPSTATS_MIB_FRAGFAILS);
639 kfree_skb(skb); 645 kfree_skb(skb);
640 return -EMSGSIZE; 646 return -EMSGSIZE;
641 } 647 }
@@ -684,7 +690,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
684 *prevhdr = NEXTHDR_FRAGMENT; 690 *prevhdr = NEXTHDR_FRAGMENT;
685 tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC); 691 tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
686 if (!tmp_hdr) { 692 if (!tmp_hdr) {
687 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); 693 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
694 IPSTATS_MIB_FRAGFAILS);
688 return -ENOMEM; 695 return -ENOMEM;
689 } 696 }
690 697
@@ -735,7 +742,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
735 742
736 err = output(skb); 743 err = output(skb);
737 if(!err) 744 if(!err)
738 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGCREATES); 745 IP6_INC_STATS(net, ip6_dst_idev(&rt->u.dst),
746 IPSTATS_MIB_FRAGCREATES);
739 747
740 if (err || !frag) 748 if (err || !frag)
741 break; 749 break;
@@ -748,7 +756,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
748 kfree(tmp_hdr); 756 kfree(tmp_hdr);
749 757
750 if (err == 0) { 758 if (err == 0) {
751 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGOKS); 759 IP6_INC_STATS(net, ip6_dst_idev(&rt->u.dst),
760 IPSTATS_MIB_FRAGOKS);
752 dst_release(&rt->u.dst); 761 dst_release(&rt->u.dst);
753 return 0; 762 return 0;
754 } 763 }
@@ -759,7 +768,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
759 frag = skb; 768 frag = skb;
760 } 769 }
761 770
762 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGFAILS); 771 IP6_INC_STATS(net, ip6_dst_idev(&rt->u.dst),
772 IPSTATS_MIB_FRAGFAILS);
763 dst_release(&rt->u.dst); 773 dst_release(&rt->u.dst);
764 return err; 774 return err;
765 } 775 }
@@ -793,7 +803,7 @@ slow_path:
793 803
794 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { 804 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
795 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); 805 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
796 IP6_INC_STATS(ip6_dst_idev(skb->dst), 806 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
797 IPSTATS_MIB_FRAGFAILS); 807 IPSTATS_MIB_FRAGFAILS);
798 err = -ENOMEM; 808 err = -ENOMEM;
799 goto fail; 809 goto fail;
@@ -857,15 +867,16 @@ slow_path:
857 if (err) 867 if (err)
858 goto fail; 868 goto fail;
859 869
860 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGCREATES); 870 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
871 IPSTATS_MIB_FRAGCREATES);
861 } 872 }
862 IP6_INC_STATS(ip6_dst_idev(skb->dst), 873 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
863 IPSTATS_MIB_FRAGOKS); 874 IPSTATS_MIB_FRAGOKS);
864 kfree_skb(skb); 875 kfree_skb(skb);
865 return err; 876 return err;
866 877
867fail: 878fail:
868 IP6_INC_STATS(ip6_dst_idev(skb->dst), 879 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
869 IPSTATS_MIB_FRAGFAILS); 880 IPSTATS_MIB_FRAGFAILS);
870 kfree_skb(skb); 881 kfree_skb(skb);
871 return err; 882 return err;
@@ -1385,7 +1396,7 @@ alloc_new_skb:
1385 return 0; 1396 return 0;
1386error: 1397error:
1387 inet->cork.length -= length; 1398 inet->cork.length -= length;
1388 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); 1399 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
1389 return err; 1400 return err;
1390} 1401}
1391 1402
@@ -1409,6 +1420,7 @@ int ip6_push_pending_frames(struct sock *sk)
1409 struct in6_addr final_dst_buf, *final_dst = &final_dst_buf; 1420 struct in6_addr final_dst_buf, *final_dst = &final_dst_buf;
1410 struct inet_sock *inet = inet_sk(sk); 1421 struct inet_sock *inet = inet_sk(sk);
1411 struct ipv6_pinfo *np = inet6_sk(sk); 1422 struct ipv6_pinfo *np = inet6_sk(sk);
1423 struct net *net = sock_net(sk);
1412 struct ipv6hdr *hdr; 1424 struct ipv6hdr *hdr;
1413 struct ipv6_txoptions *opt = np->cork.opt; 1425 struct ipv6_txoptions *opt = np->cork.opt;
1414 struct rt6_info *rt = (struct rt6_info *)inet->cork.dst; 1426 struct rt6_info *rt = (struct rt6_info *)inet->cork.dst;
@@ -1462,7 +1474,7 @@ int ip6_push_pending_frames(struct sock *sk)
1462 skb->mark = sk->sk_mark; 1474 skb->mark = sk->sk_mark;
1463 1475
1464 skb->dst = dst_clone(&rt->u.dst); 1476 skb->dst = dst_clone(&rt->u.dst);
1465 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); 1477 IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
1466 if (proto == IPPROTO_ICMPV6) { 1478 if (proto == IPPROTO_ICMPV6) {
1467 struct inet6_dev *idev = ip6_dst_idev(skb->dst); 1479 struct inet6_dev *idev = ip6_dst_idev(skb->dst);
1468 1480
@@ -1491,7 +1503,7 @@ void ip6_flush_pending_frames(struct sock *sk)
1491 1503
1492 while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { 1504 while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
1493 if (skb->dst) 1505 if (skb->dst)
1494 IP6_INC_STATS(ip6_dst_idev(skb->dst), 1506 IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb->dst),
1495 IPSTATS_MIB_OUTDISCARDS); 1507 IPSTATS_MIB_OUTDISCARDS);
1496 kfree_skb(skb); 1508 kfree_skb(skb);
1497 } 1509 }