On Fri, Jan 26, 2018 at 11:40:17AM -0800, Wei Wang wrote: > From: Wei Wang <wei...@google.com> > > In current route cache aging logic, if a route has both RTF_EXPIRE and > RTF_GATEWAY set, the route will only be removed if the neighbor cache > has no RTN_ROUTE flag. Otherwise, even if the route has expired, it You meant NTF_ROUTER instead of RTN_ROUTE?
> won't get deleted. > Fix this logic to always check if the route has expired first and then > do the gateway neighbor cache check if previous check decide to not > remove the exception entry. > > Fixes: 1859bac04fb6 ("ipv6: remove from fib tree aged out RTF_CACHE dst") > Signed-off-by: Wei Wang <wei...@google.com> > Signed-off-by: Eric Dumazet <eduma...@google.com> Nice catch! Acked-by: Martin KaFai Lau <ka...@fb.com> > --- > net/ipv6/route.c | 20 ++++++++++++-------- > 1 file changed, 12 insertions(+), 8 deletions(-) > > diff --git a/net/ipv6/route.c b/net/ipv6/route.c > index 0458b761f3c5..a560fb1d0230 100644 > --- a/net/ipv6/route.c > +++ b/net/ipv6/route.c > @@ -1586,12 +1586,19 @@ static void rt6_age_examine_exception(struct > rt6_exception_bucket *bucket, > * EXPIRES exceptions - e.g. pmtu-generated ones are pruned when > * expired, independently from their aging, as per RFC 8201 section 4 > */ > - if (!(rt->rt6i_flags & RTF_EXPIRES) && > - time_after_eq(now, rt->dst.lastuse + gc_args->timeout)) { > - RT6_TRACE("aging clone %p\n", rt); > + if (!(rt->rt6i_flags & RTF_EXPIRES)) { > + if (time_after_eq(now, rt->dst.lastuse + gc_args->timeout)) { > + RT6_TRACE("aging clone %p\n", rt); > + rt6_remove_exception(bucket, rt6_ex); > + return; > + } > + } else if (time_after(jiffies, rt->dst.expires)) { > + RT6_TRACE("purging expired route %p\n", rt); > rt6_remove_exception(bucket, rt6_ex); > return; > - } else if (rt->rt6i_flags & RTF_GATEWAY) { > + } > + > + if (rt->rt6i_flags & RTF_GATEWAY) { > struct neighbour *neigh; > __u8 neigh_flags = 0; > > @@ -1606,11 +1613,8 @@ static void rt6_age_examine_exception(struct > rt6_exception_bucket *bucket, > rt6_remove_exception(bucket, rt6_ex); > return; > } > - } else if (__rt6_check_expired(rt)) { > - RT6_TRACE("purging expired route %p\n", rt); > - rt6_remove_exception(bucket, rt6_ex); > - return; > } > + > gc_args->more++; > } > > -- > 2.16.0.rc1.238.g530d649a79-goog >