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.c80
1 files changed, 47 insertions, 33 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 3df2c442d90b..c77db0b95e26 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -103,7 +103,8 @@ static int ip6_output_finish(struct sk_buff *skb)
103 else if (dst->neighbour) 103 else if (dst->neighbour)
104 return dst->neighbour->output(skb); 104 return dst->neighbour->output(skb);
105 105
106 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); 106 IP6_INC_STATS_BH(dev_net(dst->dev),
107 ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
107 kfree_skb(skb); 108 kfree_skb(skb);
108 return -EINVAL; 109 return -EINVAL;
109 110
@@ -150,13 +151,14 @@ static int ip6_output2(struct sk_buff *skb)
150 ip6_dev_loopback_xmit); 151 ip6_dev_loopback_xmit);
151 152
152 if (ipv6_hdr(skb)->hop_limit == 0) { 153 if (ipv6_hdr(skb)->hop_limit == 0) {
153 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); 154 IP6_INC_STATS(dev_net(dev), idev,
155 IPSTATS_MIB_OUTDISCARDS);
154 kfree_skb(skb); 156 kfree_skb(skb);
155 return 0; 157 return 0;
156 } 158 }
157 } 159 }
158 160
159 IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS); 161 IP6_INC_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCASTPKTS);
160 } 162 }
161 163
162 return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev, 164 return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
@@ -175,7 +177,8 @@ int ip6_output(struct sk_buff *skb)
175{ 177{
176 struct inet6_dev *idev = ip6_dst_idev(skb->dst); 178 struct inet6_dev *idev = ip6_dst_idev(skb->dst);
177 if (unlikely(idev->cnf.disable_ipv6)) { 179 if (unlikely(idev->cnf.disable_ipv6)) {
178 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); 180 IP6_INC_STATS(dev_net(skb->dst->dev), idev,
181 IPSTATS_MIB_OUTDISCARDS);
179 kfree_skb(skb); 182 kfree_skb(skb);
180 return 0; 183 return 0;
181 } 184 }
@@ -194,6 +197,7 @@ int ip6_output(struct sk_buff *skb)
194int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, 197int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
195 struct ipv6_txoptions *opt, int ipfragok) 198 struct ipv6_txoptions *opt, int ipfragok)
196{ 199{
200 struct net *net = sock_net(sk);
197 struct ipv6_pinfo *np = inet6_sk(sk); 201 struct ipv6_pinfo *np = inet6_sk(sk);
198 struct in6_addr *first_hop = &fl->fl6_dst; 202 struct in6_addr *first_hop = &fl->fl6_dst;
199 struct dst_entry *dst = skb->dst; 203 struct dst_entry *dst = skb->dst;
@@ -216,7 +220,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
216 if (skb_headroom(skb) < head_room) { 220 if (skb_headroom(skb) < head_room) {
217 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); 221 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
218 if (skb2 == NULL) { 222 if (skb2 == NULL) {
219 IP6_INC_STATS(ip6_dst_idev(skb->dst), 223 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
220 IPSTATS_MIB_OUTDISCARDS); 224 IPSTATS_MIB_OUTDISCARDS);
221 kfree_skb(skb); 225 kfree_skb(skb);
222 return -ENOBUFS; 226 return -ENOBUFS;
@@ -270,7 +274,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
270 274
271 mtu = dst_mtu(dst); 275 mtu = dst_mtu(dst);
272 if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { 276 if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) {
273 IP6_INC_STATS(ip6_dst_idev(skb->dst), 277 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
274 IPSTATS_MIB_OUTREQUESTS); 278 IPSTATS_MIB_OUTREQUESTS);
275 return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, 279 return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
276 dst_output); 280 dst_output);
@@ -280,7 +284,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"); 284 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
281 skb->dev = dst->dev; 285 skb->dev = dst->dev;
282 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 286 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
283 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); 287 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
284 kfree_skb(skb); 288 kfree_skb(skb);
285 return -EMSGSIZE; 289 return -EMSGSIZE;
286} 290}
@@ -422,7 +426,7 @@ int ip6_forward(struct sk_buff *skb)
422 goto drop; 426 goto drop;
423 427
424 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { 428 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
425 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); 429 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
426 goto drop; 430 goto drop;
427 } 431 }
428 432
@@ -455,7 +459,8 @@ int ip6_forward(struct sk_buff *skb)
455 skb->dev = dst->dev; 459 skb->dev = dst->dev;
456 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 460 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
457 0, skb->dev); 461 0, skb->dev);
458 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); 462 IP6_INC_STATS_BH(net,
463 ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
459 464
460 kfree_skb(skb); 465 kfree_skb(skb);
461 return -ETIMEDOUT; 466 return -ETIMEDOUT;
@@ -468,13 +473,14 @@ int ip6_forward(struct sk_buff *skb)
468 if (proxied > 0) 473 if (proxied > 0)
469 return ip6_input(skb); 474 return ip6_input(skb);
470 else if (proxied < 0) { 475 else if (proxied < 0) {
471 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); 476 IP6_INC_STATS(net, ip6_dst_idev(dst),
477 IPSTATS_MIB_INDISCARDS);
472 goto drop; 478 goto drop;
473 } 479 }
474 } 480 }
475 481
476 if (!xfrm6_route_forward(skb)) { 482 if (!xfrm6_route_forward(skb)) {
477 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); 483 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
478 goto drop; 484 goto drop;
479 } 485 }
480 dst = skb->dst; 486 dst = skb->dst;
@@ -523,14 +529,16 @@ int ip6_forward(struct sk_buff *skb)
523 /* Again, force OUTPUT device used as source address */ 529 /* Again, force OUTPUT device used as source address */
524 skb->dev = dst->dev; 530 skb->dev = dst->dev;
525 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev); 531 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev);
526 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS); 532 IP6_INC_STATS_BH(net,
527 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_FRAGFAILS); 533 ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS);
534 IP6_INC_STATS_BH(net,
535 ip6_dst_idev(dst), IPSTATS_MIB_FRAGFAILS);
528 kfree_skb(skb); 536 kfree_skb(skb);
529 return -EMSGSIZE; 537 return -EMSGSIZE;
530 } 538 }
531 539
532 if (skb_cow(skb, dst->dev->hard_header_len)) { 540 if (skb_cow(skb, dst->dev->hard_header_len)) {
533 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS); 541 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS);
534 goto drop; 542 goto drop;
535 } 543 }
536 544
@@ -540,12 +548,12 @@ int ip6_forward(struct sk_buff *skb)
540 548
541 hdr->hop_limit--; 549 hdr->hop_limit--;
542 550
543 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS); 551 IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS);
544 return NF_HOOK(PF_INET6, NF_INET_FORWARD, skb, skb->dev, dst->dev, 552 return NF_HOOK(PF_INET6, NF_INET_FORWARD, skb, skb->dev, dst->dev,
545 ip6_forward_finish); 553 ip6_forward_finish);
546 554
547error: 555error:
548 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS); 556 IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS);
549drop: 557drop:
550 kfree_skb(skb); 558 kfree_skb(skb);
551 return -EINVAL; 559 return -EINVAL;
@@ -613,7 +621,6 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
613 621
614static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) 622static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
615{ 623{
616 struct net_device *dev;
617 struct sk_buff *frag; 624 struct sk_buff *frag;
618 struct rt6_info *rt = (struct rt6_info*)skb->dst; 625 struct rt6_info *rt = (struct rt6_info*)skb->dst;
619 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; 626 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
@@ -623,8 +630,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
623 __be32 frag_id = 0; 630 __be32 frag_id = 0;
624 int ptr, offset = 0, err=0; 631 int ptr, offset = 0, err=0;
625 u8 *prevhdr, nexthdr = 0; 632 u8 *prevhdr, nexthdr = 0;
633 struct net *net = dev_net(skb->dst->dev);
626 634
627 dev = rt->u.dst.dev;
628 hlen = ip6_find_1stfragopt(skb, &prevhdr); 635 hlen = ip6_find_1stfragopt(skb, &prevhdr);
629 nexthdr = *prevhdr; 636 nexthdr = *prevhdr;
630 637
@@ -637,7 +644,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
637 if (!skb->local_df) { 644 if (!skb->local_df) {
638 skb->dev = skb->dst->dev; 645 skb->dev = skb->dst->dev;
639 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 646 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
640 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); 647 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
648 IPSTATS_MIB_FRAGFAILS);
641 kfree_skb(skb); 649 kfree_skb(skb);
642 return -EMSGSIZE; 650 return -EMSGSIZE;
643 } 651 }
@@ -686,7 +694,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
686 *prevhdr = NEXTHDR_FRAGMENT; 694 *prevhdr = NEXTHDR_FRAGMENT;
687 tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC); 695 tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
688 if (!tmp_hdr) { 696 if (!tmp_hdr) {
689 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); 697 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
698 IPSTATS_MIB_FRAGFAILS);
690 return -ENOMEM; 699 return -ENOMEM;
691 } 700 }
692 701
@@ -737,7 +746,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
737 746
738 err = output(skb); 747 err = output(skb);
739 if(!err) 748 if(!err)
740 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGCREATES); 749 IP6_INC_STATS(net, ip6_dst_idev(&rt->u.dst),
750 IPSTATS_MIB_FRAGCREATES);
741 751
742 if (err || !frag) 752 if (err || !frag)
743 break; 753 break;
@@ -750,7 +760,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
750 kfree(tmp_hdr); 760 kfree(tmp_hdr);
751 761
752 if (err == 0) { 762 if (err == 0) {
753 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGOKS); 763 IP6_INC_STATS(net, ip6_dst_idev(&rt->u.dst),
764 IPSTATS_MIB_FRAGOKS);
754 dst_release(&rt->u.dst); 765 dst_release(&rt->u.dst);
755 return 0; 766 return 0;
756 } 767 }
@@ -761,7 +772,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
761 frag = skb; 772 frag = skb;
762 } 773 }
763 774
764 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGFAILS); 775 IP6_INC_STATS(net, ip6_dst_idev(&rt->u.dst),
776 IPSTATS_MIB_FRAGFAILS);
765 dst_release(&rt->u.dst); 777 dst_release(&rt->u.dst);
766 return err; 778 return err;
767 } 779 }
@@ -795,7 +807,7 @@ slow_path:
795 807
796 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { 808 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
797 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); 809 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
798 IP6_INC_STATS(ip6_dst_idev(skb->dst), 810 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
799 IPSTATS_MIB_FRAGFAILS); 811 IPSTATS_MIB_FRAGFAILS);
800 err = -ENOMEM; 812 err = -ENOMEM;
801 goto fail; 813 goto fail;
@@ -859,15 +871,16 @@ slow_path:
859 if (err) 871 if (err)
860 goto fail; 872 goto fail;
861 873
862 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGCREATES); 874 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
875 IPSTATS_MIB_FRAGCREATES);
863 } 876 }
864 IP6_INC_STATS(ip6_dst_idev(skb->dst), 877 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
865 IPSTATS_MIB_FRAGOKS); 878 IPSTATS_MIB_FRAGOKS);
866 kfree_skb(skb); 879 kfree_skb(skb);
867 return err; 880 return err;
868 881
869fail: 882fail:
870 IP6_INC_STATS(ip6_dst_idev(skb->dst), 883 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
871 IPSTATS_MIB_FRAGFAILS); 884 IPSTATS_MIB_FRAGFAILS);
872 kfree_skb(skb); 885 kfree_skb(skb);
873 return err; 886 return err;
@@ -982,7 +995,7 @@ static int ip6_dst_lookup_tail(struct sock *sk,
982 995
983out_err_release: 996out_err_release:
984 if (err == -ENETUNREACH) 997 if (err == -ENETUNREACH)
985 IP6_INC_STATS_BH(NULL, IPSTATS_MIB_OUTNOROUTES); 998 IP6_INC_STATS_BH(net, NULL, IPSTATS_MIB_OUTNOROUTES);
986 dst_release(*dst); 999 dst_release(*dst);
987 *dst = NULL; 1000 *dst = NULL;
988 return err; 1001 return err;
@@ -1387,7 +1400,7 @@ alloc_new_skb:
1387 return 0; 1400 return 0;
1388error: 1401error:
1389 inet->cork.length -= length; 1402 inet->cork.length -= length;
1390 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); 1403 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
1391 return err; 1404 return err;
1392} 1405}
1393 1406
@@ -1411,6 +1424,7 @@ int ip6_push_pending_frames(struct sock *sk)
1411 struct in6_addr final_dst_buf, *final_dst = &final_dst_buf; 1424 struct in6_addr final_dst_buf, *final_dst = &final_dst_buf;
1412 struct inet_sock *inet = inet_sk(sk); 1425 struct inet_sock *inet = inet_sk(sk);
1413 struct ipv6_pinfo *np = inet6_sk(sk); 1426 struct ipv6_pinfo *np = inet6_sk(sk);
1427 struct net *net = sock_net(sk);
1414 struct ipv6hdr *hdr; 1428 struct ipv6hdr *hdr;
1415 struct ipv6_txoptions *opt = np->cork.opt; 1429 struct ipv6_txoptions *opt = np->cork.opt;
1416 struct rt6_info *rt = (struct rt6_info *)inet->cork.dst; 1430 struct rt6_info *rt = (struct rt6_info *)inet->cork.dst;
@@ -1464,12 +1478,12 @@ int ip6_push_pending_frames(struct sock *sk)
1464 skb->mark = sk->sk_mark; 1478 skb->mark = sk->sk_mark;
1465 1479
1466 skb->dst = dst_clone(&rt->u.dst); 1480 skb->dst = dst_clone(&rt->u.dst);
1467 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); 1481 IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
1468 if (proto == IPPROTO_ICMPV6) { 1482 if (proto == IPPROTO_ICMPV6) {
1469 struct inet6_dev *idev = ip6_dst_idev(skb->dst); 1483 struct inet6_dev *idev = ip6_dst_idev(skb->dst);
1470 1484
1471 ICMP6MSGOUT_INC_STATS_BH(idev, icmp6_hdr(skb)->icmp6_type); 1485 ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type);
1472 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS); 1486 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
1473 } 1487 }
1474 1488
1475 err = ip6_local_out(skb); 1489 err = ip6_local_out(skb);
@@ -1493,7 +1507,7 @@ void ip6_flush_pending_frames(struct sock *sk)
1493 1507
1494 while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { 1508 while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
1495 if (skb->dst) 1509 if (skb->dst)
1496 IP6_INC_STATS(ip6_dst_idev(skb->dst), 1510 IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb->dst),
1497 IPSTATS_MIB_OUTDISCARDS); 1511 IPSTATS_MIB_OUTDISCARDS);
1498 kfree_skb(skb); 1512 kfree_skb(skb);
1499 } 1513 }