Skip to content

Bgp crashes - #21778

Merged
ton31337 merged 2 commits into
FRRouting:masterfrom
donaldsharp:bgp_crashes
Apr 28, 2026
Merged

Bgp crashes#21778
ton31337 merged 2 commits into
FRRouting:masterfrom
donaldsharp:bgp_crashes

Conversation

@donaldsharp

Copy link
Copy Markdown
Member

see individual commits, but stop 2 shutdown crashes that happening in the topotests

@greptile-apps

greptile-apps Bot commented Apr 27, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes two shutdown-order crashes in the BGP EVPN multi-homing code. First, it adds bgp_evpn_es_route_table_purge() to drain leftover bgp_path_info entries from each ES route table before bgp_table_unlock() is reached in bgp_evpn_es_free(), preventing a crash when the pi_hash is non-empty at teardown. Second, it adds a NULL guard on bgp_vrf->l2vnis in bgpevpn_unlink_from_l3vni() to handle the race where VRF EVPN cleanup has already called list_delete(&bgp->l2vnis) (which NULLs the pointer) before late VNI teardown fires.

Confidence Score: 4/5

Safe to merge; both changes are tightly scoped shutdown-path fixes with no impact on the data-plane code path.

Both fixes follow established patterns already present in the codebase (same reap loop, same list_delete NULL-after-free convention) and address confirmed topotest crashes. No new logic is introduced in normal (non-shutdown) operation. Score is 4 rather than 5 because the purge function accesses pi->peer inside bgp_path_info_reap during a phase where the BGP instance may be partially torn down, but this same risk exists in the surrounding callers and the check if (pi->peer) is already present.

bgpd/bgp_evpn_mh.c β€” confirm bgp_path_info_reap is safe when called after bgp instance teardown (peer pointers may be stale).

Important Files Changed

Filename Overview
bgpd/bgp_evpn_mh.c Adds bgp_evpn_es_route_table_purge() to drain path-info entries from the ES route table during shutdown, called from bgp_evpn_mh_finish() before bgp_table_unlock(); logic is a safe duplicate of the existing bgp_evpn_es_route_del_all() inner loop.
bgpd/bgp_evpn_private.h Guards listnode_delete() with a NULL check on bgp_vrf->l2vnis to prevent crash when the list has already been freed (and set to NULL by list_delete()) during VRF teardown before late VNI cleanup runs.

Sequence Diagram

sequenceDiagram
    participant MH as bgp_evpn_mh_finish
    participant Purge as bgp_evpn_es_route_table_purge (NEW)
    participant Reap as bgp_path_info_reap
    participant ESFree as bgp_evpn_es_free
    participant Table as bgp_table_unlock

    MH->>Purge: for each ES in rb_tree
    Purge->>Purge: loop over dest/pi in route_table
    Purge->>Reap: bgp_path_info_mark_for_delete + reap
    Reap-->>Purge: dest (assert non-NULL)
    MH->>MH: force-cleanup ES-EVIs
    MH->>ESFree: bgp_evpn_es_local_info_clear β†’ es_free
    ESFree->>Table: bgp_table_unlock (pi_hash now empty βœ“)

    note over MH,Table: Without the purge, pi_hash non-empty crash here
Loading

Reviews (1): Last reviewed commit: "bgpd: Prevent crash when list is already..." | Re-trigger Greptile

@ton31337 ton31337 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

I am seeing this crash on shutdown:

(gdb) bt
0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:44
1  __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
2  __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
3  0x000073b03f64527e in __GI_raise (sig=6) at ../sysdeps/posix/raise.c:26
4  0x000073b03fb54184 in core_handler (signo=6, siginfo=0x7fffe7e9f770, context=0x7fffe7e9f640) at lib/sigevent.c:268
5  <signal handler called>
6  __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:44
7  __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
8  __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
9  0x000073b03f64527e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
10 0x000073b03f6288ff in __GI_abort () at ./stdlib/abort.c:79
11 0x000073b03fb9d557 in _zlog_assert_failed (xref=0x60176b4ddaa0 <_xref.6>, extra=0x0) at lib/zlog.c:801
12 0x000060176b29555c in bgp_pi_hash_fini (h=0x60177324c238) at ./bgpd/bgp_route.h:761
13 0x000060176b295787 in bgp_table_unlock (rt=0x60177324c220) at bgpd/bgp_table.c:38
14 0x000060176b1b7817 in bgp_evpn_es_free (es=0x60177324c0e0, caller=0x60176b3e2200 <__func__.189> "bgp_evpn_es_local_info_clear") at bgpd/bgp_evpn_mh.c:2112
15 0x000060176b1b7a62 in bgp_evpn_es_local_info_clear (es=0x60177324c0e0, finish=true) at bgpd/bgp_evpn_mh.c:2179
16 0x000060176b1bfd11 in bgp_evpn_mh_finish () at bgpd/bgp_evpn_mh.c:5230
17 0x000060176b17344e in bgp_exit (status=0) at bgpd/bgp_main.c:193
18 0x000060176b17332e in sigint () at bgpd/bgp_main.c:141
19 0x000073b03fb53ef0 in frr_sigevent_process () at lib/sigevent.c:117
20 0x000073b03fb708e5 in event_fetch_inner_loop (m=0x6017729d5f60, event=0x0, fetch=0x7fffe7ea06d0, broken=0x7fffe7ea068e, continued=0x7fffe7ea068f) at lib/event.c:2437
21 0x000073b03fb70c1b in event_fetch (m=0x6017729d5f60, fetch=0x7fffe7ea06d0) at lib/event.c:2569
22 0x000073b03fadd06f in frr_run (loop=0x6017729d5f60) at lib/libfrr.c:1257
23 0x000060176b1740bf in main (argc=7, argv=0x7fffe7ea0968) at bgpd/bgp_main.c:550

The crash is happening because when finishing the pi has for the evpn data
it is not actually cleaned up.  Let's purge that data.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Ensure that the list is actually there on cleanup.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
@ton31337
ton31337 merged commit 146e8cd into FRRouting:master Apr 28, 2026
23 checks passed
@donaldsharp
donaldsharp deleted the bgp_crashes branch April 29, 2026 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants