Hi Stephen, On Thu, May 7, 2026 at 9:03 PM Stephen Hemminger <[email protected]> wrote: > > On Thu, 7 May 2026 11:50:40 +0200 > Maxime Leroy <[email protected]> wrote: > > > Asymmetric ADD/DEL sequences in FIB6 trie (a covering parent > > removed between the ADD and DEL of a longer prefix) eventually > > make ADD fail with -ENOSPC even when the tbl8 pool is empty. > > > > Patch 2/3 is a small reproducer. > > > > Root cause: rsvd_tbl8s is updated by depth_diff recomputed from > > the current RIB, so increments at ADD and decrements at DEL do > > not cancel when the RIB state changes in between. The counter > > drifts and wraps to UINT32_MAX. > > > > The simplest fix I could find (1/3, 3/3) is to drop rsvd_tbl8s > > and use the pool counters already maintained by alloc/free: > > tbl8_pool_pos in trie, cur_tbl8s in dir24_8. The DQ reclaim > > inside tbl8_alloc() is moved into the pre-check. > > > > I am not sure I understood the original intent of keeping > > rsvd_tbl8s separate from the pool counters. In dir24_8 the two > > mirror each other 1:1 and rsvd_tbl8s looks redundant; in trie, > > depth_diff gives it a worst-case-reservation flavor but the > > recomputation from the RIB is exactly what makes it drift. If > > there was a deliberate reason, please point it out. > > > > Patch 3/3 is a no-op cleanup that aligns dir24_8 with the trie > > pattern. > > > > Maxime Leroy (3): > > fib6: fix tbl8 reservation drift in trie > > test/fib6: add reproducer for tbl8 reservation drift > > fib: drop redundant tbl8 reservation counter > > > > app/test/test_fib6.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ > > lib/fib/dir24_8.c | 31 ++++++----------- > > lib/fib/dir24_8.h | 1 - > > lib/fib/trie.c | 23 ++++++------ > > lib/fib/trie.h | 3 +- > > 5 files changed, 104 insertions(+), 37 deletions(-) > > > > Used this a test case for multiple AI reviewers. > Most reported false positives in various places. > But the winner was Claude web (or desktop) with Opus 4.7 extended. > It saw: > > Patch 3 - fib: drop redundant tbl8 reservation counter > Warning: The commit message frames this as removing a "redundant" counter and > claims "Behavior is unchanged for non-DQ modes," but dir24_8 has the same > rsvd_tbl8s drift bug that patch 1/3 fixes for trie6 — this patch silently > fixes it as well. > Trace (no RCU, depth-1 mode): > ADD /28 A (no /24 cover): > - tmp == NULL, pre-check passes > - install_to_fib allocates 1 tbl8 -> cur_tbl8s = 1 > - post-add hook: tmp == NULL -> rsvd_tbl8s++ = 1 > ADD /24 B covering A: > - depth == 24, no rsvd_tbl8s update > - tbl8 entries rewritten, no alloc/free > - state: rsvd_tbl8s = 1, cur_tbl8s = 1 > DEL /28 A (with /24 cover B): > - modify_fib installs B's nh over A's range > - tbl8 becomes uniform -> tbl8_recycle() -> cur_tbl8s = 0 > - post-del check: tmp != NULL (B is the cover) -> rsvd_tbl8s NOT decremented > - state: rsvd_tbl8s = 1, cur_tbl8s = 0 (diverged) > DEL /24 B: > - depth == 24, no rsvd_tbl8s update > - final: rsvd_tbl8s = 1, cur_tbl8s = 0 > Each repetition leaks +1 into rsvd_tbl8s with no actual tbl8 in use. Over > enough cycles, rsvd_tbl8s reaches number_tbl8s and the pre-check rejects > valid /25-/32 ADDs even though the pool is empty. This is the same class of > bug as the IPv6 case, just with smaller per-cycle drift. > The patch should carry: > Fixes: <commit that introduced rsvd_tbl8s in dir24_8> > Cc: [email protected]
Thanks for the AI review. It makes senses. I will fix it for the V1.

