On 1/4/21 8:05 PM, [email protected] wrote: > > We're able to reproduce the refcount mismatch after some experimentation > as well. > Essentially, it consists of > 1) adding a default route (ip -6 route add dev XXX default) > 2) forcing the creation of an exception route via manually injecting an > ICMPv6 > Packet Too Big into the device. > 3) Replace the default route (ip -6 route change dev XXX default) > 4) Delete the device. (ip link del XXX) > > After adding a call to flush out the exception cache for the route, the > mismatch > is no longer seen: > diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c > index 7a0c877..95e4310 100644 > --- a/net/ipv6/ip6_fib.c > +++ b/net/ipv6/ip6_fib.c > @@ -1215,6 +1215,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, > struct fib6_info *rt, > } > nsiblings = iter->fib6_nsiblings; > iter->fib6_node = NULL; > + rt6_flush_exceptions(iter); > fib6_purge_rt(iter, fn, info->nl_net); > if (rcu_access_pointer(fn->rr_ptr) == iter) > fn->rr_ptr = NULL;
Ah, I see now. rt6_flush_exceptions is called by fib6_del_route, but that won't handle replace. If you look at fib6_purge_rt it already has a call to remove pcpu entries. This call to flush exceptions should go there and the existing one in fib6_del_route can be removed. Also, can you add the reproducer as another test case to tools/testing/selftests/net/pmtu.sh? We definitely need one for this sequence (route, exceptions, replace route).
