@ -380,6 +380,7 @@ static struct rtable *icmp_route_lookup(struct net *net,
struct icmp_bxm * param )
{
struct rtable * rt , * rt2 ;
struct flowi4 fl4_dec ;
int err ;
memset ( fl4 , 0 , sizeof ( * fl4 ) ) ;
@ -408,19 +409,19 @@ static struct rtable *icmp_route_lookup(struct net *net,
} else
return rt ;
err = xfrm_decode_session_reverse ( skb_in , flowi4_to_flowi ( fl4 ) , AF_INET ) ;
err = xfrm_decode_session_reverse ( skb_in , flowi4_to_flowi ( & fl4_dec ) , AF_INET ) ;
if ( err )
goto relookup_failed ;
if ( inet_addr_type ( net , fl4 - > saddr ) = = RTN_LOCAL ) {
rt2 = __ip_route_output_key ( net , fl4 ) ;
if ( inet_addr_type ( net , fl4_dec . saddr ) = = RTN_LOCAL ) {
rt2 = __ip_route_output_key ( net , & fl4_dec ) ;
if ( IS_ERR ( rt2 ) )
err = PTR_ERR ( rt2 ) ;
} else {
struct flowi4 fl4_2 = { } ;
unsigned long orefdst ;
fl4_2 . daddr = fl4 - > saddr ;
fl4_2 . daddr = fl4_dec . saddr ;
rt2 = ip_route_output_key ( net , & fl4_2 ) ;
if ( IS_ERR ( rt2 ) ) {
err = PTR_ERR ( rt2 ) ;
@ -428,7 +429,7 @@ static struct rtable *icmp_route_lookup(struct net *net,
}
/* Ugh! */
orefdst = skb_in - > _skb_refdst ; /* save old refdst */
err = ip_route_input ( skb_in , fl4 - > daddr , fl4 - > saddr ,
err = ip_route_input ( skb_in , fl4_dec . daddr , fl4_dec . saddr ,
RT_TOS ( tos ) , rt2 - > dst . dev ) ;
dst_release ( & rt2 - > dst ) ;
@ -440,10 +441,11 @@ static struct rtable *icmp_route_lookup(struct net *net,
goto relookup_failed ;
rt2 = ( struct rtable * ) xfrm_lookup ( net , & rt2 - > dst ,
flowi4_to_flowi ( fl4 ) , NULL ,
flowi4_to_flowi ( & fl4_dec ) , NULL ,
XFRM_LOOKUP_ICMP ) ;
if ( ! IS_ERR ( rt2 ) ) {
dst_release ( & rt - > dst ) ;
memcpy ( fl4 , & fl4_dec , sizeof ( * fl4 ) ) ;
rt = rt2 ;
} else if ( PTR_ERR ( rt2 ) = = - EPERM ) {
if ( rt )