Commit dd8c6b8303 for frr

commit dd8c6b83030748566bd9888f8d9395220fca1042
Author: Philippe Guibert <philippe.guibert@6wind.com>
Date:   Thu Nov 5 16:22:03 2026 +0100

    bgpd: fix use after free of rd tables on hidden default instance

    When the default BGP instance has a local VPN network and is removed,
    then configured again, bgpd crashes at the next walk of its networks:

    > router bgp 65500
    >  address-family ipv4 vpn
    >   network 10.0.0.1/32 rd 1:1 label 100
    > !
    > no router bgp 65500
    > router bgp 65500
    >  no bgp network import-check

    > ERROR: AddressSanitizer: heap-use-after-free on address 0x5070003249d0
    > READ of size 8 at 0x5070003249d0 thread T0
    >     #0 in bgp_table_top bgpd/bgp_table.h:254
    >     #1 in bgp_static_redo_import_check bgpd/bgp_route.c:9686
    >     #2 in no_bgp_network_import_check bgpd/bgp_vty.c:5029
    > freed by thread T0 here:
    >     #2 in bgp_table_unlock bgpd/bgp_table.c:44
    >     #3 in bgp_static_delete bgpd/bgp_route.c:9651
    >     #4 in bgp_delete bgpd/bgpd.c:4832
    >     #5 in no_router_bgp bgpd/bgp_vty.c:1989
    > previously allocated by thread T0 here:
    >     #2 in bgp_table_init bgpd/bgp_table.c:187
    >     #3 in bgp_static_set bgpd/bgp_route.c:9397
    >     #4 in vpnv4_network bgpd/bgp_mplsvpn.c:3504

    Because its ipv4 vpn table is not empty, the default instance is only
    hidden by bgp_delete(), and is reused by the next 'router bgp'.
    bgp_delete() calls bgp_static_delete(), which frees the per-RD tables of
    the static VPN, ENCAP and EVPN networks, but leaves the RD node pointing
    to the freed table, and keeps the node lock. Any later walk of the
    networks, or a new network with the same RD, uses the freed table.

    Fix this by resetting the RD node information and unlocking the node
    after freeing the table, as bgp_cleanup_routes() does.

    Fixes: 4d0e7a49cf8d ("bgpd: VRF-Lite fix default bgp delete")
    Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 67ebeca2ce..bd91659c9a 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -9652,7 +9652,10 @@ void bgp_static_delete(struct bgp *bgp)
 					assert(rm);
 				}

-				bgp_table_unlock(table);
+				bgp_table_finish(&table);
+				bgp_dest_set_bgp_table_info(dest, NULL);
+				dest = bgp_dest_unlock_node(dest);
+				assert(dest);
 			} else {
 				bgp_static = bgp_dest_get_bgp_static_info(dest);
 				bgp_static_withdraw(bgp,