diff options
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r-- | net/ipv6/ip6_output.c | 84 |
1 files changed, 47 insertions, 37 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 66716911962e..e05ecbb1412d 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -88,7 +88,7 @@ static inline int ip6_output_finish(struct sk_buff *skb) | |||
88 | } else if (dst->neighbour) | 88 | } else if (dst->neighbour) |
89 | return dst->neighbour->output(skb); | 89 | return dst->neighbour->output(skb); |
90 | 90 | ||
91 | IP6_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); | 91 | IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); |
92 | kfree_skb(skb); | 92 | kfree_skb(skb); |
93 | return -EINVAL; | 93 | return -EINVAL; |
94 | 94 | ||
@@ -118,6 +118,7 @@ static int ip6_output2(struct sk_buff *skb) | |||
118 | 118 | ||
119 | if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) { | 119 | if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) { |
120 | struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL; | 120 | struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL; |
121 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); | ||
121 | 122 | ||
122 | if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && | 123 | if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && |
123 | ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr, | 124 | ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr, |
@@ -133,13 +134,13 @@ static int ip6_output2(struct sk_buff *skb) | |||
133 | ip6_dev_loopback_xmit); | 134 | ip6_dev_loopback_xmit); |
134 | 135 | ||
135 | if (skb->nh.ipv6h->hop_limit == 0) { | 136 | if (skb->nh.ipv6h->hop_limit == 0) { |
136 | IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); | 137 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); |
137 | kfree_skb(skb); | 138 | kfree_skb(skb); |
138 | return 0; | 139 | return 0; |
139 | } | 140 | } |
140 | } | 141 | } |
141 | 142 | ||
142 | IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); | 143 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS); |
143 | } | 144 | } |
144 | 145 | ||
145 | return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish); | 146 | return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish); |
@@ -182,12 +183,14 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
182 | 183 | ||
183 | if (skb_headroom(skb) < head_room) { | 184 | if (skb_headroom(skb) < head_room) { |
184 | struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); | 185 | struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); |
185 | kfree_skb(skb); | 186 | if (skb2 == NULL) { |
186 | skb = skb2; | 187 | IP6_INC_STATS(ip6_dst_idev(skb->dst), |
187 | if (skb == NULL) { | 188 | IPSTATS_MIB_OUTDISCARDS); |
188 | IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); | 189 | kfree_skb(skb); |
189 | return -ENOBUFS; | 190 | return -ENOBUFS; |
190 | } | 191 | } |
192 | kfree_skb(skb); | ||
193 | skb = skb2; | ||
191 | if (sk) | 194 | if (sk) |
192 | skb_set_owner_w(skb, sk); | 195 | skb_set_owner_w(skb, sk); |
193 | } | 196 | } |
@@ -217,7 +220,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
217 | if (tclass < 0) | 220 | if (tclass < 0) |
218 | tclass = 0; | 221 | tclass = 0; |
219 | 222 | ||
220 | *(u32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel; | 223 | *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel; |
221 | 224 | ||
222 | hdr->payload_len = htons(seg_len); | 225 | hdr->payload_len = htons(seg_len); |
223 | hdr->nexthdr = proto; | 226 | hdr->nexthdr = proto; |
@@ -230,7 +233,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
230 | 233 | ||
231 | mtu = dst_mtu(dst); | 234 | mtu = dst_mtu(dst); |
232 | if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) { | 235 | if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) { |
233 | IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); | 236 | IP6_INC_STATS(ip6_dst_idev(skb->dst), |
237 | IPSTATS_MIB_OUTREQUESTS); | ||
234 | return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, | 238 | return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, |
235 | dst_output); | 239 | dst_output); |
236 | } | 240 | } |
@@ -239,7 +243,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
239 | printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); | 243 | printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); |
240 | skb->dev = dst->dev; | 244 | skb->dev = dst->dev; |
241 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); | 245 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); |
242 | IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); | 246 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); |
243 | kfree_skb(skb); | 247 | kfree_skb(skb); |
244 | return -EMSGSIZE; | 248 | return -EMSGSIZE; |
245 | } | 249 | } |
@@ -267,7 +271,7 @@ int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev, | |||
267 | hdr = (struct ipv6hdr *) skb_put(skb, sizeof(struct ipv6hdr)); | 271 | hdr = (struct ipv6hdr *) skb_put(skb, sizeof(struct ipv6hdr)); |
268 | skb->nh.ipv6h = hdr; | 272 | skb->nh.ipv6h = hdr; |
269 | 273 | ||
270 | *(u32*)hdr = htonl(0x60000000); | 274 | *(__be32*)hdr = htonl(0x60000000); |
271 | 275 | ||
272 | hdr->payload_len = htons(len); | 276 | hdr->payload_len = htons(len); |
273 | hdr->nexthdr = proto; | 277 | hdr->nexthdr = proto; |
@@ -373,7 +377,7 @@ int ip6_forward(struct sk_buff *skb) | |||
373 | goto error; | 377 | goto error; |
374 | 378 | ||
375 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { | 379 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { |
376 | IP6_INC_STATS(IPSTATS_MIB_INDISCARDS); | 380 | IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); |
377 | goto drop; | 381 | goto drop; |
378 | } | 382 | } |
379 | 383 | ||
@@ -406,7 +410,7 @@ int ip6_forward(struct sk_buff *skb) | |||
406 | skb->dev = dst->dev; | 410 | skb->dev = dst->dev; |
407 | icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, | 411 | icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, |
408 | 0, skb->dev); | 412 | 0, skb->dev); |
409 | IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); | 413 | IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); |
410 | 414 | ||
411 | kfree_skb(skb); | 415 | kfree_skb(skb); |
412 | return -ETIMEDOUT; | 416 | return -ETIMEDOUT; |
@@ -419,13 +423,13 @@ int ip6_forward(struct sk_buff *skb) | |||
419 | if (proxied > 0) | 423 | if (proxied > 0) |
420 | return ip6_input(skb); | 424 | return ip6_input(skb); |
421 | else if (proxied < 0) { | 425 | else if (proxied < 0) { |
422 | IP6_INC_STATS(IPSTATS_MIB_INDISCARDS); | 426 | IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); |
423 | goto drop; | 427 | goto drop; |
424 | } | 428 | } |
425 | } | 429 | } |
426 | 430 | ||
427 | if (!xfrm6_route_forward(skb)) { | 431 | if (!xfrm6_route_forward(skb)) { |
428 | IP6_INC_STATS(IPSTATS_MIB_INDISCARDS); | 432 | IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); |
429 | goto drop; | 433 | goto drop; |
430 | } | 434 | } |
431 | dst = skb->dst; | 435 | dst = skb->dst; |
@@ -464,14 +468,14 @@ int ip6_forward(struct sk_buff *skb) | |||
464 | /* Again, force OUTPUT device used as source address */ | 468 | /* Again, force OUTPUT device used as source address */ |
465 | skb->dev = dst->dev; | 469 | skb->dev = dst->dev; |
466 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev); | 470 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev); |
467 | IP6_INC_STATS_BH(IPSTATS_MIB_INTOOBIGERRORS); | 471 | IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS); |
468 | IP6_INC_STATS_BH(IPSTATS_MIB_FRAGFAILS); | 472 | IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_FRAGFAILS); |
469 | kfree_skb(skb); | 473 | kfree_skb(skb); |
470 | return -EMSGSIZE; | 474 | return -EMSGSIZE; |
471 | } | 475 | } |
472 | 476 | ||
473 | if (skb_cow(skb, dst->dev->hard_header_len)) { | 477 | if (skb_cow(skb, dst->dev->hard_header_len)) { |
474 | IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); | 478 | IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS); |
475 | goto drop; | 479 | goto drop; |
476 | } | 480 | } |
477 | 481 | ||
@@ -481,11 +485,11 @@ int ip6_forward(struct sk_buff *skb) | |||
481 | 485 | ||
482 | hdr->hop_limit--; | 486 | hdr->hop_limit--; |
483 | 487 | ||
484 | IP6_INC_STATS_BH(IPSTATS_MIB_OUTFORWDATAGRAMS); | 488 | IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS); |
485 | return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish); | 489 | return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish); |
486 | 490 | ||
487 | error: | 491 | error: |
488 | IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); | 492 | IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS); |
489 | drop: | 493 | drop: |
490 | kfree_skb(skb); | 494 | kfree_skb(skb); |
491 | return -EINVAL; | 495 | return -EINVAL; |
@@ -499,12 +503,12 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
499 | dst_release(to->dst); | 503 | dst_release(to->dst); |
500 | to->dst = dst_clone(from->dst); | 504 | to->dst = dst_clone(from->dst); |
501 | to->dev = from->dev; | 505 | to->dev = from->dev; |
506 | to->mark = from->mark; | ||
502 | 507 | ||
503 | #ifdef CONFIG_NET_SCHED | 508 | #ifdef CONFIG_NET_SCHED |
504 | to->tc_index = from->tc_index; | 509 | to->tc_index = from->tc_index; |
505 | #endif | 510 | #endif |
506 | #ifdef CONFIG_NETFILTER | 511 | #ifdef CONFIG_NETFILTER |
507 | to->nfmark = from->nfmark; | ||
508 | /* Connection association is same as pre-frag packet */ | 512 | /* Connection association is same as pre-frag packet */ |
509 | nf_conntrack_put(to->nfct); | 513 | nf_conntrack_put(to->nfct); |
510 | to->nfct = from->nfct; | 514 | to->nfct = from->nfct; |
@@ -571,7 +575,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
571 | struct ipv6hdr *tmp_hdr; | 575 | struct ipv6hdr *tmp_hdr; |
572 | struct frag_hdr *fh; | 576 | struct frag_hdr *fh; |
573 | unsigned int mtu, hlen, left, len; | 577 | unsigned int mtu, hlen, left, len; |
574 | u32 frag_id = 0; | 578 | __be32 frag_id = 0; |
575 | int ptr, offset = 0, err=0; | 579 | int ptr, offset = 0, err=0; |
576 | u8 *prevhdr, nexthdr = 0; | 580 | u8 *prevhdr, nexthdr = 0; |
577 | 581 | ||
@@ -620,14 +624,13 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
620 | skb_shinfo(skb)->frag_list = NULL; | 624 | skb_shinfo(skb)->frag_list = NULL; |
621 | /* BUILD HEADER */ | 625 | /* BUILD HEADER */ |
622 | 626 | ||
623 | tmp_hdr = kmalloc(hlen, GFP_ATOMIC); | 627 | tmp_hdr = kmemdup(skb->nh.raw, hlen, GFP_ATOMIC); |
624 | if (!tmp_hdr) { | 628 | if (!tmp_hdr) { |
625 | IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); | 629 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); |
626 | return -ENOMEM; | 630 | return -ENOMEM; |
627 | } | 631 | } |
628 | 632 | ||
629 | *prevhdr = NEXTHDR_FRAGMENT; | 633 | *prevhdr = NEXTHDR_FRAGMENT; |
630 | memcpy(tmp_hdr, skb->nh.raw, hlen); | ||
631 | __skb_pull(skb, hlen); | 634 | __skb_pull(skb, hlen); |
632 | fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr)); | 635 | fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr)); |
633 | skb->nh.raw = __skb_push(skb, hlen); | 636 | skb->nh.raw = __skb_push(skb, hlen); |
@@ -643,7 +646,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
643 | skb->data_len = first_len - skb_headlen(skb); | 646 | skb->data_len = first_len - skb_headlen(skb); |
644 | skb->len = first_len; | 647 | skb->len = first_len; |
645 | skb->nh.ipv6h->payload_len = htons(first_len - sizeof(struct ipv6hdr)); | 648 | skb->nh.ipv6h->payload_len = htons(first_len - sizeof(struct ipv6hdr)); |
646 | 649 | ||
650 | dst_hold(&rt->u.dst); | ||
647 | 651 | ||
648 | for (;;) { | 652 | for (;;) { |
649 | /* Prepare header of the next frame, | 653 | /* Prepare header of the next frame, |
@@ -667,7 +671,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
667 | 671 | ||
668 | err = output(skb); | 672 | err = output(skb); |
669 | if(!err) | 673 | if(!err) |
670 | IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES); | 674 | IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGCREATES); |
671 | 675 | ||
672 | if (err || !frag) | 676 | if (err || !frag) |
673 | break; | 677 | break; |
@@ -680,7 +684,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
680 | kfree(tmp_hdr); | 684 | kfree(tmp_hdr); |
681 | 685 | ||
682 | if (err == 0) { | 686 | if (err == 0) { |
683 | IP6_INC_STATS(IPSTATS_MIB_FRAGOKS); | 687 | IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGOKS); |
688 | dst_release(&rt->u.dst); | ||
684 | return 0; | 689 | return 0; |
685 | } | 690 | } |
686 | 691 | ||
@@ -690,7 +695,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
690 | frag = skb; | 695 | frag = skb; |
691 | } | 696 | } |
692 | 697 | ||
693 | IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); | 698 | IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGFAILS); |
699 | dst_release(&rt->u.dst); | ||
694 | return err; | 700 | return err; |
695 | } | 701 | } |
696 | 702 | ||
@@ -723,7 +729,8 @@ slow_path: | |||
723 | 729 | ||
724 | if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { | 730 | if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { |
725 | NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); | 731 | NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); |
726 | IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); | 732 | IP6_INC_STATS(ip6_dst_idev(skb->dst), |
733 | IPSTATS_MIB_FRAGFAILS); | ||
727 | err = -ENOMEM; | 734 | err = -ENOMEM; |
728 | goto fail; | 735 | goto fail; |
729 | } | 736 | } |
@@ -784,15 +791,17 @@ slow_path: | |||
784 | if (err) | 791 | if (err) |
785 | goto fail; | 792 | goto fail; |
786 | 793 | ||
787 | IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES); | 794 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGCREATES); |
788 | } | 795 | } |
796 | IP6_INC_STATS(ip6_dst_idev(skb->dst), | ||
797 | IPSTATS_MIB_FRAGOKS); | ||
789 | kfree_skb(skb); | 798 | kfree_skb(skb); |
790 | IP6_INC_STATS(IPSTATS_MIB_FRAGOKS); | ||
791 | return err; | 799 | return err; |
792 | 800 | ||
793 | fail: | 801 | fail: |
802 | IP6_INC_STATS(ip6_dst_idev(skb->dst), | ||
803 | IPSTATS_MIB_FRAGFAILS); | ||
794 | kfree_skb(skb); | 804 | kfree_skb(skb); |
795 | IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); | ||
796 | return err; | 805 | return err; |
797 | } | 806 | } |
798 | 807 | ||
@@ -1265,7 +1274,7 @@ alloc_new_skb: | |||
1265 | return 0; | 1274 | return 0; |
1266 | error: | 1275 | error: |
1267 | inet->cork.length -= length; | 1276 | inet->cork.length -= length; |
1268 | IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); | 1277 | IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); |
1269 | return err; | 1278 | return err; |
1270 | } | 1279 | } |
1271 | 1280 | ||
@@ -1311,7 +1320,7 @@ int ip6_push_pending_frames(struct sock *sk) | |||
1311 | 1320 | ||
1312 | skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr)); | 1321 | skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr)); |
1313 | 1322 | ||
1314 | *(u32*)hdr = fl->fl6_flowlabel | | 1323 | *(__be32*)hdr = fl->fl6_flowlabel | |
1315 | htonl(0x60000000 | ((int)np->cork.tclass << 20)); | 1324 | htonl(0x60000000 | ((int)np->cork.tclass << 20)); |
1316 | 1325 | ||
1317 | if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) | 1326 | if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) |
@@ -1326,7 +1335,7 @@ int ip6_push_pending_frames(struct sock *sk) | |||
1326 | skb->priority = sk->sk_priority; | 1335 | skb->priority = sk->sk_priority; |
1327 | 1336 | ||
1328 | skb->dst = dst_clone(&rt->u.dst); | 1337 | skb->dst = dst_clone(&rt->u.dst); |
1329 | IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); | 1338 | IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); |
1330 | err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); | 1339 | err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); |
1331 | if (err) { | 1340 | if (err) { |
1332 | if (err > 0) | 1341 | if (err > 0) |
@@ -1357,7 +1366,8 @@ void ip6_flush_pending_frames(struct sock *sk) | |||
1357 | struct sk_buff *skb; | 1366 | struct sk_buff *skb; |
1358 | 1367 | ||
1359 | while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { | 1368 | while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { |
1360 | IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); | 1369 | IP6_INC_STATS(ip6_dst_idev(skb->dst), |
1370 | IPSTATS_MIB_OUTDISCARDS); | ||
1361 | kfree_skb(skb); | 1371 | kfree_skb(skb); |
1362 | } | 1372 | } |
1363 | 1373 | ||