diff options
Diffstat (limited to 'net/ipv6/icmp.c')
-rw-r--r-- | net/ipv6/icmp.c | 28 |
1 files changed, 11 insertions, 17 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 11900417b1cc..90868fb42757 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -490,7 +490,8 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | |||
490 | goto out_dst_release; | 490 | goto out_dst_release; |
491 | } | 491 | } |
492 | 492 | ||
493 | idev = in6_dev_get(skb->dev); | 493 | rcu_read_lock(); |
494 | idev = __in6_dev_get(skb->dev); | ||
494 | 495 | ||
495 | err = ip6_append_data(sk, icmpv6_getfrag, &msg, | 496 | err = ip6_append_data(sk, icmpv6_getfrag, &msg, |
496 | len + sizeof(struct icmp6hdr), | 497 | len + sizeof(struct icmp6hdr), |
@@ -500,19 +501,16 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | |||
500 | if (err) { | 501 | if (err) { |
501 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); | 502 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); |
502 | ip6_flush_pending_frames(sk); | 503 | ip6_flush_pending_frames(sk); |
503 | goto out_put; | 504 | } else { |
505 | err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, | ||
506 | len + sizeof(struct icmp6hdr)); | ||
504 | } | 507 | } |
505 | err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, len + sizeof(struct icmp6hdr)); | 508 | rcu_read_unlock(); |
506 | |||
507 | out_put: | ||
508 | if (likely(idev != NULL)) | ||
509 | in6_dev_put(idev); | ||
510 | out_dst_release: | 509 | out_dst_release: |
511 | dst_release(dst); | 510 | dst_release(dst); |
512 | out: | 511 | out: |
513 | icmpv6_xmit_unlock(sk); | 512 | icmpv6_xmit_unlock(sk); |
514 | } | 513 | } |
515 | |||
516 | EXPORT_SYMBOL(icmpv6_send); | 514 | EXPORT_SYMBOL(icmpv6_send); |
517 | 515 | ||
518 | static void icmpv6_echo_reply(struct sk_buff *skb) | 516 | static void icmpv6_echo_reply(struct sk_buff *skb) |
@@ -569,7 +567,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
569 | if (hlimit < 0) | 567 | if (hlimit < 0) |
570 | hlimit = ip6_dst_hoplimit(dst); | 568 | hlimit = ip6_dst_hoplimit(dst); |
571 | 569 | ||
572 | idev = in6_dev_get(skb->dev); | 570 | idev = __in6_dev_get(skb->dev); |
573 | 571 | ||
574 | msg.skb = skb; | 572 | msg.skb = skb; |
575 | msg.offset = 0; | 573 | msg.offset = 0; |
@@ -583,13 +581,10 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
583 | if (err) { | 581 | if (err) { |
584 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); | 582 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); |
585 | ip6_flush_pending_frames(sk); | 583 | ip6_flush_pending_frames(sk); |
586 | goto out_put; | 584 | } else { |
585 | err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, | ||
586 | skb->len + sizeof(struct icmp6hdr)); | ||
587 | } | 587 | } |
588 | err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, skb->len + sizeof(struct icmp6hdr)); | ||
589 | |||
590 | out_put: | ||
591 | if (likely(idev != NULL)) | ||
592 | in6_dev_put(idev); | ||
593 | dst_release(dst); | 588 | dst_release(dst); |
594 | out: | 589 | out: |
595 | icmpv6_xmit_unlock(sk); | 590 | icmpv6_xmit_unlock(sk); |
@@ -840,8 +835,7 @@ static int __net_init icmpv6_sk_init(struct net *net) | |||
840 | /* Enough space for 2 64K ICMP packets, including | 835 | /* Enough space for 2 64K ICMP packets, including |
841 | * sk_buff struct overhead. | 836 | * sk_buff struct overhead. |
842 | */ | 837 | */ |
843 | sk->sk_sndbuf = | 838 | sk->sk_sndbuf = 2 * SKB_TRUESIZE(64 * 1024); |
844 | (2 * ((64 * 1024) + sizeof(struct sk_buff))); | ||
845 | } | 839 | } |
846 | return 0; | 840 | return 0; |
847 | 841 | ||