diff options
Diffstat (limited to 'net/ipv6/icmp.c')
| -rw-r--r-- | net/ipv6/icmp.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 121d517bf91c..893287ecc628 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
| @@ -436,24 +436,26 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
| 436 | } | 436 | } |
| 437 | 437 | ||
| 438 | if (xfrm_decode_session_reverse(skb, &fl2, AF_INET6)) | 438 | if (xfrm_decode_session_reverse(skb, &fl2, AF_INET6)) |
| 439 | goto out; | 439 | goto relookup_failed; |
| 440 | 440 | ||
| 441 | if (ip6_dst_lookup(sk, &dst2, &fl)) | 441 | if (ip6_dst_lookup(sk, &dst2, &fl)) |
| 442 | goto out; | 442 | goto relookup_failed; |
| 443 | 443 | ||
| 444 | err = xfrm_lookup(&dst2, &fl, sk, XFRM_LOOKUP_ICMP); | 444 | err = xfrm_lookup(&dst2, &fl, sk, XFRM_LOOKUP_ICMP); |
| 445 | if (err == -ENOENT) { | 445 | switch (err) { |
| 446 | case 0: | ||
| 447 | dst_release(dst); | ||
| 448 | dst = dst2; | ||
| 449 | break; | ||
| 450 | case -EPERM: | ||
| 451 | goto out_dst_release; | ||
| 452 | default: | ||
| 453 | relookup_failed: | ||
| 446 | if (!dst) | 454 | if (!dst) |
| 447 | goto out; | 455 | goto out; |
| 448 | goto route_done; | 456 | break; |
| 449 | } | 457 | } |
| 450 | 458 | ||
| 451 | dst_release(dst); | ||
| 452 | dst = dst2; | ||
| 453 | |||
| 454 | if (err) | ||
| 455 | goto out; | ||
| 456 | |||
| 457 | route_done: | 459 | route_done: |
| 458 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) | 460 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) |
| 459 | hlimit = np->mcast_hops; | 461 | hlimit = np->mcast_hops; |
