Re: [PATCH net] ipv4: require matching source address for route hint reuse

From: Yizhou Zhao

Date: Tue Jul 21 2026 - 22:55:04 EST


Hi Ido,

Thanks for your review.

> On Jul 20, 2026, at 20:16, Ido Schimmel <idosch@xxxxxxxxxx> wrote:
>
> On Tue, Jul 14, 2026 at 08:26:17PM +0800, Yizhou Zhao wrote:
>> IPv4 list receive can reuse a route from the previous skb in the same
>> receive batch. The current eligibility check only compares the destination
>> address and TOS before calling ip_route_use_hint().
>>
>> For forwarded routes, ip_route_use_hint() skips fib_validate_source()
>> unless the hinted route is local. This means a packet with a different
>> source address can reuse a forwarding dst created for an earlier packet
>> and avoid source validation such as strict rp_filter.
>
> I'm not sure why we are skipping source validation for non-local routes.
>
> The comment above ip_route_use_hint() says "Implements all the
> saddr-related checks as ip_route_input_slow()". I agree that
> ip_route_input_slow() only does source validation for RTN_LOCAL, but for
> RTN_UNICAST it is calling ip_mkroute_input(), which eventually calls
> fib_validate_source().
>
> Paolo, WDYT about always performing source validation [1]?
>
>>
>> In a KASAN QEMU router with strict rp_filter on the ingress device, a
>
> Why mention KASAN? How is it related to this bug / patch?

The KASAN mention was only intended to describe the test kernel, but I
agree that it is not relevant to the issue itself and should be removed.

>
>> bad-only burst was dropped entirely, however, a paired valid/bad burst
>> with the same destination/TOS made all of the bad packets pass rp_filter.
>>
>> Require the source address to match before reusing the hint. Packets from
>> the same source/destination/TOS still take the fast path; packets whose
>> source changes go through the normal route lookup and source validation
>> path.
>
> I agree that it fixes the problem, but we will always pay the
> performance penalty, even when rp_filter is disabled. According to
> commit 02b24941619f ("ipv4: use dst hint for ipv4 list receive"), there
> is still a performance gain when we perform the source validation
> per-packet.
>
> [1]
> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
> index 3f3de5164d6e..89338111793b 100644
> --- a/net/ipv4/route.c
> +++ b/net/ipv4/route.c
> @@ -2194,6 +2194,7 @@ ip_route_use_hint(struct sk_buff *skb, __be32 daddr, __be32 saddr,
> struct rtable *rt = skb_rtable(hint);
> struct net *net = dev_net(dev);
> u32 tag = 0;
> + int oif = 0;
>
> if (!in_dev)
> return reason;
> @@ -2214,14 +2215,13 @@ ip_route_use_hint(struct sk_buff *skb, __be32 daddr, __be32 saddr,
> }
>
> if (!(rt->rt_flags & RTCF_LOCAL))
> - goto skip_validate_source;
> + oif = dst_dev_rcu(&rt->dst)->ifindex;
>
> - reason = fib_validate_source_reason(skb, saddr, daddr, dscp, 0, dev,
> + reason = fib_validate_source_reason(skb, saddr, daddr, dscp, oif, dev,
> in_dev, &tag);
> if (reason)
> goto martian_source;
>
> -skip_validate_source:
> skb_dst_copy(skb, hint);
> return SKB_NOT_DROPPED_YET;

The approach in [1] looks better to me. It appears to make the hint path
consistent with the source validation performed by __mkroute_input(),
while still allowing the route hint to be reused.

I'll wait for Paolo’s comments before preparing a v2.

Thanks,
Yizhou