diff options
Diffstat (limited to 'net/ipv4/icmp.c')
| -rw-r--r-- | net/ipv4/icmp.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index a13c074dac09..40508babad8c 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -591,7 +591,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
| 591 | } | 591 | } |
| 592 | 592 | ||
| 593 | if (xfrm_decode_session_reverse(skb_in, &fl, AF_INET)) | 593 | if (xfrm_decode_session_reverse(skb_in, &fl, AF_INET)) |
| 594 | goto out_unlock; | 594 | goto relookup_failed; |
| 595 | 595 | ||
| 596 | if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL) | 596 | if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL) |
| 597 | err = __ip_route_output_key(net, &rt2, &fl); | 597 | err = __ip_route_output_key(net, &rt2, &fl); |
| @@ -601,7 +601,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
| 601 | 601 | ||
| 602 | fl2.fl4_dst = fl.fl4_src; | 602 | fl2.fl4_dst = fl.fl4_src; |
| 603 | if (ip_route_output_key(net, &rt2, &fl2)) | 603 | if (ip_route_output_key(net, &rt2, &fl2)) |
| 604 | goto out_unlock; | 604 | goto relookup_failed; |
| 605 | 605 | ||
| 606 | /* Ugh! */ | 606 | /* Ugh! */ |
| 607 | odst = skb_in->dst; | 607 | odst = skb_in->dst; |
| @@ -614,21 +614,23 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
| 614 | } | 614 | } |
| 615 | 615 | ||
| 616 | if (err) | 616 | if (err) |
| 617 | goto out_unlock; | 617 | goto relookup_failed; |
| 618 | 618 | ||
| 619 | err = xfrm_lookup((struct dst_entry **)&rt2, &fl, NULL, | 619 | err = xfrm_lookup((struct dst_entry **)&rt2, &fl, NULL, |
| 620 | XFRM_LOOKUP_ICMP); | 620 | XFRM_LOOKUP_ICMP); |
| 621 | if (err == -ENOENT) { | 621 | switch (err) { |
| 622 | case 0: | ||
| 623 | dst_release(&rt->u.dst); | ||
| 624 | rt = rt2; | ||
| 625 | break; | ||
| 626 | case -EPERM: | ||
| 627 | goto ende; | ||
| 628 | default: | ||
| 629 | relookup_failed: | ||
| 622 | if (!rt) | 630 | if (!rt) |
| 623 | goto out_unlock; | 631 | goto out_unlock; |
| 624 | goto route_done; | 632 | break; |
| 625 | } | 633 | } |
| 626 | |||
| 627 | dst_release(&rt->u.dst); | ||
| 628 | rt = rt2; | ||
| 629 | |||
| 630 | if (err) | ||
| 631 | goto out_unlock; | ||
| 632 | } | 634 | } |
| 633 | 635 | ||
| 634 | route_done: | 636 | route_done: |
