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: |