* icmp_route_lookup returns wrong source address information
@ 2011-07-20 19:22 Florian Westphal
2011-07-22 7:59 ` David Miller
2011-07-22 13:23 ` David Miller
0 siblings, 2 replies; 5+ messages in thread
From: Florian Westphal @ 2011-07-20 19:22 UTC (permalink / raw)
To: davem; +Cc: netdev
Hello David,
With linux-2.6 and net-next trees, whenever an icmp error message is
sent in response to a to-be-forwarded packet, the destination address
of the original packet is used as the IP header source address.
Example:
$ traceroute breakpoint.cc
traceroute to breakpoint.cc (85.10.199.196), 30 hops max, 40 byte packets
1 chamillionaire.breakpoint.cc (85.10.199.196) 0.476 ms 0.468 ms 0.793 ms
But the expected 1st hop is 192.168.20.7 in my setup.
I bisected this down to 77968b78242ee25e2a4d759f0fca8dd52df6d479
("ipv4: Pass flow keys down into datagram packet building engine.")
Specifically, it is caused by this hunk:
-static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
+static struct rtable *icmp_route_lookup(struct net *net,
+ struct flowi4 *fl4,
[..]
{
- struct flowi4 fl4 = {
- .daddr = (param->replyopts.opt.opt.srr ?
- param->replyopts.opt.opt.faddr : iph->saddr),
- .saddr = saddr,
- .flowi4_tos = RT_TOS(tos),
- .flowi4_proto = IPPROTO_ICMP,
- .fl4_icmp_type = type,
- .fl4_icmp_code = code,
- };
struct rtable *rt, *rt2;
int err;
[..]
- err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(&fl4), AF_INET);
+ err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(fl4), AF_INET);
if (err)
goto relookup_failed;
Problem is that xfrm_decode_session_reverse() may rebuild fl4 from scratch.
In my setup, "goto relookup_failed" will be hit a bit later on, and fl4->saddr will
be set to iph->daddr...
Thanks,
Florian
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: icmp_route_lookup returns wrong source address information 2011-07-20 19:22 icmp_route_lookup returns wrong source address information Florian Westphal @ 2011-07-22 7:59 ` David Miller 2011-07-22 13:23 ` David Miller 1 sibling, 0 replies; 5+ messages in thread From: David Miller @ 2011-07-22 7:59 UTC (permalink / raw) To: fw; +Cc: netdev From: Florian Westphal <fw@strlen.de> Date: Wed, 20 Jul 2011 21:22:58 +0200 > With linux-2.6 and net-next trees, whenever an icmp error message is > sent in response to a to-be-forwarded packet, the destination address > of the original packet is used as the IP header source address. > > Example: > $ traceroute breakpoint.cc > traceroute to breakpoint.cc (85.10.199.196), 30 hops max, 40 byte packets > 1 chamillionaire.breakpoint.cc (85.10.199.196) 0.476 ms 0.468 ms 0.793 ms > > But the expected 1st hop is 192.168.20.7 in my setup. > > I bisected this down to 77968b78242ee25e2a4d759f0fca8dd52df6d479 > ("ipv4: Pass flow keys down into datagram packet building engine.") > > Specifically, it is caused by this hunk: ... > Problem is that xfrm_decode_session_reverse() may rebuild fl4 from scratch. > > In my setup, "goto relookup_failed" will be hit a bit later on, and fl4->saddr will > be set to iph->daddr... Thanks for the detailed report Florian, I'll look into this. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: icmp_route_lookup returns wrong source address information 2011-07-20 19:22 icmp_route_lookup returns wrong source address information Florian Westphal 2011-07-22 7:59 ` David Miller @ 2011-07-22 13:23 ` David Miller 2011-07-22 14:15 ` Florian Westphal 1 sibling, 1 reply; 5+ messages in thread From: David Miller @ 2011-07-22 13:23 UTC (permalink / raw) To: fw; +Cc: netdev From: Florian Westphal <fw@strlen.de> Date: Wed, 20 Jul 2011 21:22:58 +0200 > Problem is that xfrm_decode_session_reverse() may rebuild fl4 from scratch. > > In my setup, "goto relookup_failed" will be hit a bit later on, and fl4->saddr will > be set to iph->daddr... Indeed, we can't use this new fl4 until we commit to using 'rt2'. Please give this patch a try: -------------------- icmp: Fix regression in nexthop resolution during replies. icmp_route_lookup() uses the wrong flow parameters if the reverse session route lookup isn't used. So do not commit to the re-decoded flow until we actually make a final decision to use a real route saved in 'rt2'. Reported-by: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net> --- net/ipv4/icmp.c | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-) diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 5395e45..23ef31b 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -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) -- 1.7.6 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: icmp_route_lookup returns wrong source address information 2011-07-22 13:23 ` David Miller @ 2011-07-22 14:15 ` Florian Westphal 2011-07-22 14:15 ` David Miller 0 siblings, 1 reply; 5+ messages in thread From: Florian Westphal @ 2011-07-22 14:15 UTC (permalink / raw) To: David Miller; +Cc: netdev David Miller <davem@davemloft.net> wrote: > From: Florian Westphal <fw@strlen.de> > Date: Wed, 20 Jul 2011 21:22:58 +0200 > > > Problem is that xfrm_decode_session_reverse() may rebuild fl4 from scratch. > > > > In my setup, "goto relookup_failed" will be hit a bit later on, and fl4->saddr will > > be set to iph->daddr... > > Indeed, we can't use this new fl4 until we commit to using 'rt2'. > > Please give this patch a try: > > -------------------- > icmp: Fix regression in nexthop resolution during replies. > > icmp_route_lookup() uses the wrong flow parameters if the reverse > session route lookup isn't used. > > So do not commit to the re-decoded flow until we actually make a > final decision to use a real route saved in 'rt2'. Thanks, traceroute shows the expected 1st hop again with your patch applied. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: icmp_route_lookup returns wrong source address information 2011-07-22 14:15 ` Florian Westphal @ 2011-07-22 14:15 ` David Miller 0 siblings, 0 replies; 5+ messages in thread From: David Miller @ 2011-07-22 14:15 UTC (permalink / raw) To: fw; +Cc: netdev From: Florian Westphal <fw@strlen.de> Date: Fri, 22 Jul 2011 16:15:31 +0200 > David Miller <davem@davemloft.net> wrote: >> From: Florian Westphal <fw@strlen.de> >> Date: Wed, 20 Jul 2011 21:22:58 +0200 >> >> > Problem is that xfrm_decode_session_reverse() may rebuild fl4 from scratch. >> > >> > In my setup, "goto relookup_failed" will be hit a bit later on, and fl4->saddr will >> > be set to iph->daddr... >> >> Indeed, we can't use this new fl4 until we commit to using 'rt2'. >> >> Please give this patch a try: >> >> -------------------- >> icmp: Fix regression in nexthop resolution during replies. >> >> icmp_route_lookup() uses the wrong flow parameters if the reverse >> session route lookup isn't used. >> >> So do not commit to the re-decoded flow until we actually make a >> final decision to use a real route saved in 'rt2'. > > Thanks, traceroute shows the expected 1st hop again > with your patch applied. Thanks for testing! ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-07-22 14:15 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-07-20 19:22 icmp_route_lookup returns wrong source address information Florian Westphal 2011-07-22 7:59 ` David Miller 2011-07-22 13:23 ` David Miller 2011-07-22 14:15 ` Florian Westphal 2011-07-22 14:15 ` David Miller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox