diff options
Diffstat (limited to 'net/ipv6/icmp.c')
| -rw-r--r-- | net/ipv6/icmp.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index abedf95fdf2d..b3157a0cc15d 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
| @@ -91,19 +91,22 @@ static struct inet6_protocol icmpv6_protocol = { | |||
| 91 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, | 91 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, |
| 92 | }; | 92 | }; |
| 93 | 93 | ||
| 94 | static __inline__ int icmpv6_xmit_lock(struct sock *sk) | 94 | static __inline__ struct sock *icmpv6_xmit_lock(struct net *net) |
| 95 | { | 95 | { |
| 96 | struct sock *sk; | ||
| 97 | |||
| 96 | local_bh_disable(); | 98 | local_bh_disable(); |
| 97 | 99 | ||
| 100 | sk = icmpv6_sk(net); | ||
| 98 | if (unlikely(!spin_trylock(&sk->sk_lock.slock))) { | 101 | if (unlikely(!spin_trylock(&sk->sk_lock.slock))) { |
| 99 | /* This can happen if the output path (f.e. SIT or | 102 | /* This can happen if the output path (f.e. SIT or |
| 100 | * ip6ip6 tunnel) signals dst_link_failure() for an | 103 | * ip6ip6 tunnel) signals dst_link_failure() for an |
| 101 | * outgoing ICMP6 packet. | 104 | * outgoing ICMP6 packet. |
| 102 | */ | 105 | */ |
| 103 | local_bh_enable(); | 106 | local_bh_enable(); |
| 104 | return 1; | 107 | return NULL; |
| 105 | } | 108 | } |
| 106 | return 0; | 109 | return sk; |
| 107 | } | 110 | } |
| 108 | 111 | ||
| 109 | static __inline__ void icmpv6_xmit_unlock(struct sock *sk) | 112 | static __inline__ void icmpv6_xmit_unlock(struct sock *sk) |
| @@ -392,11 +395,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
| 392 | fl.fl_icmp_code = code; | 395 | fl.fl_icmp_code = code; |
| 393 | security_skb_classify_flow(skb, &fl); | 396 | security_skb_classify_flow(skb, &fl); |
| 394 | 397 | ||
| 395 | sk = icmpv6_sk(net); | 398 | sk = icmpv6_xmit_lock(net); |
| 396 | np = inet6_sk(sk); | 399 | if (sk == NULL) |
| 397 | |||
| 398 | if (icmpv6_xmit_lock(sk)) | ||
| 399 | return; | 400 | return; |
| 401 | np = inet6_sk(sk); | ||
| 400 | 402 | ||
| 401 | if (!icmpv6_xrlim_allow(sk, type, &fl)) | 403 | if (!icmpv6_xrlim_allow(sk, type, &fl)) |
| 402 | goto out; | 404 | goto out; |
| @@ -539,11 +541,10 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
| 539 | fl.fl_icmp_type = ICMPV6_ECHO_REPLY; | 541 | fl.fl_icmp_type = ICMPV6_ECHO_REPLY; |
| 540 | security_skb_classify_flow(skb, &fl); | 542 | security_skb_classify_flow(skb, &fl); |
| 541 | 543 | ||
| 542 | sk = icmpv6_sk(net); | 544 | sk = icmpv6_xmit_lock(net); |
| 543 | np = inet6_sk(sk); | 545 | if (sk == NULL) |
| 544 | |||
| 545 | if (icmpv6_xmit_lock(sk)) | ||
| 546 | return; | 546 | return; |
| 547 | np = inet6_sk(sk); | ||
| 547 | 548 | ||
| 548 | if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) | 549 | if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) |
| 549 | fl.oif = np->mcast_oif; | 550 | fl.oif = np->mcast_oif; |
