]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ipv6: Remove permanent routes from tb6_gc_hlist when all exceptions expire.
authorKuniyuki Iwashima <kuniyu@google.com>
Fri, 20 Mar 2026 07:22:59 +0000 (07:22 +0000)
committerJakub Kicinski <kuba@kernel.org>
Mon, 23 Mar 2026 23:59:31 +0000 (16:59 -0700)
Commit 5eb902b8e719 ("net/ipv6: Remove expired routes with a
separated list of routes.") introduced a per-table GC list and
changed GC to iterate over that list instead of traversing
the entire route table.

However, it forgot to add permanent routes to tb6_gc_hlist
when exception routes are added.

Commit cfe82469a00f ("ipv6: add exception routes to GC list
in rt6_insert_exception") fixed that issue but introduced
another one.

Even after all exception routes expire, the permanent routes
remain in tb6_gc_hlist, potentially negating the performance
benefits intended by the initial change.

Let's count gc_args->more before and after rt6_age_exceptions()
and remove the permanent route when the delta is 0.

Note that the next patch will reuse fib6_age_exceptions().

Fixes: cfe82469a00f ("ipv6: add exception routes to GC list in rt6_insert_exception")
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Xin Long <lucien.xin@gmail.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20260320072317.2561779-2-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ipv6/ip6_fib.c

index 9058e71241dc376ebff2581ba882357c61d6adb8..fadfca49d6b12dfbfa82166a2a30661bcebbf7b9 100644 (file)
@@ -2348,6 +2348,17 @@ static void fib6_flush_trees(struct net *net)
 /*
  *     Garbage collection
  */
+static void fib6_age_exceptions(struct fib6_info *rt, struct fib6_gc_args *gc_args,
+                               unsigned long now)
+{
+       bool may_expire = rt->fib6_flags & RTF_EXPIRES && rt->expires;
+       int old_more = gc_args->more;
+
+       rt6_age_exceptions(rt, gc_args, now);
+
+       if (!may_expire && old_more == gc_args->more)
+               fib6_remove_gc_list(rt);
+}
 
 static int fib6_age(struct fib6_info *rt, struct fib6_gc_args *gc_args)
 {
@@ -2370,7 +2381,7 @@ static int fib6_age(struct fib6_info *rt, struct fib6_gc_args *gc_args)
         *      Note, that clones are aged out
         *      only if they are not in use now.
         */
-       rt6_age_exceptions(rt, gc_args, now);
+       fib6_age_exceptions(rt, gc_args, now);
 
        return 0;
 }