Skip to content

bgpd: fix valgrind memory leaks on daemon shutdown#21511

Open
soumyar-roy wants to merge 1 commit intoFRRouting:masterfrom
soumyar-roy:soumya/memleak
Open

bgpd: fix valgrind memory leaks on daemon shutdown#21511
soumyar-roy wants to merge 1 commit intoFRRouting:masterfrom
soumyar-roy:soumya/memleak

Conversation

@soumyar-roy
Copy link
Copy Markdown
Contributor

@soumyar-roy soumyar-roy commented Apr 13, 2026

During daemon termination, the default BGP instance leaks due to two issues:

First, bgp_cleanup_routes() skips EVPN and ENCAP two-level table cleanup for hidden instances, leaving route entries. Add a terminating check so these tables are always cleaned during shutdown.

Second, a circular dependency exists between bgp_free() and VNI lock release: each L2VNI holds a bgp_lock on the default instance via bgpevpn_link_to_l3vni(), but the only code that releases these locks (bgp_evpn_cleanup -> free_vni_entry -> bgpevpn_unlink_from_l3vni) lives inside bgp_free(), which only runs when the lock count reaches zero. Break this cycle by calling bgp_evpn_cleanup() from bgp_delete() during termination, before the final bgp_unlock(). This releases VNI-held locks so the refcount can reach zero and bgp_free() actually executes.

Signed-off-by: Soumya Roy souroy@nvidia.com

UT

Run test:
sudo -E python3 -m pytest --valgrind-memleaks -s -vv test_bgp_evpn_v4_v6_vtep.py

before fix
2026-04-13 21:07:21,108 ERROR: topo: valgrind memleaks found:
33 in /tmp/topotests/bgp_evpn_three_tier_clos_topo1.test_bgp_evpn_v4_v6_vtep/bordertor-11.valgrind.bgpd.257900
2026-04-13 21:07:21,118 ERROR: topo: test failed at "test_bgp_evpn_v4_v6_vtep/test_memory_leak[ipv6]": valgrind memleaks found for daemons: bgpd(33)
2026-04-13 21:07:21,118 INFO: topo: setting error msg: test_bgp_evpn_v4_v6_vtep/test_memory_leak[ipv6]

test_bgp_evpn_v4_v6_vtep.py::test_memory_leak[ipv6] ERROR-------------------------------------------- live log logreport ---------------------------------------------
2026-04-13 21:07:21,203 INFO: topo: Spawn collection of support bundle for spine-1
2026-04-13 21:07:21,203 ERROR: topo: Generation of Support bundle failed 'spine-1'

================================================== ERRORS ===================================================
________________________________ ERROR at teardown of test_memory_leak[ipv6] ________________________________

request = <SubRequest 'module_check_memtest' for <Function test_bgp_summary_neighbor_state[ipv4]>>

@pytest.fixture(autouse=True, scope="module")
def module_check_memtest(request):
    yield
    if request.config.option.valgrind_memleaks:
        if get_topogen() is not None:
          check_for_valgrind_memleaks()

../conftest.py:480:


item = None

def check_for_valgrind_memleaks(item: pytest.Item | None = None) -> None:
    assert topotest.g_pytest_config.option.valgrind_memleaks

    leaks = []
    tgen = get_topogen()  # pylint: disable=redefined-outer-name
    latest = []
    existing = []
    logdir = ""
    if tgen is not None:
        logdir = tgen.logdir
        if hasattr(tgen, "valgrind_existing_files"):
            existing = tgen.valgrind_existing_files
        latest = glob.glob(os.path.join(logdir, "*.valgrind.*"))
        latest = [x for x in latest if "core" not in x]

    if latest:
        test_name = item.name if item else "end-test-module"
        test_path = item.nodeid if item else "end-test-module"
        logging.debug(
            "CHECK valgrind memleaks: %s in %s/**/*.dmp (%s)",
            test_name,
            logdir,
            test_path,
        )

    daemons = set()
    for vfile in latest:
        if vfile in existing:
            continue
        # do not consider memleaks from parent fork (i.e., owned by root)
        if os.stat(vfile).st_uid == 0:
            existing.append(vfile)  # do not check again
            logger.debug("Skipping valgrind file %s owned by root", vfile)
            continue
        logger.debug("Checking valgrind file %s not owned by root", vfile)
        with open(vfile, encoding="ascii") as vf:
            vfcontent = vf.read()
            match = re.search(r"ERROR SUMMARY: (\d+) errors", vfcontent)
            if match:
                existing.append(vfile)  # have summary don't check again
            if match and match.group(1) != "0":
                emsg = "{} in {}".format(match.group(1), vfile)
                leaks.append(emsg)
                daemon = re.match(r".*\.valgrind\.(.*)\.\d+", vfile).group(1)
                daemons.add("{}({})".format(daemon, match.group(1)))

    if tgen is not None:
        tgen.valgrind_existing_files = existing

    if leaks:
        logger.error("valgrind memleaks found:\n\t%s", "\n\t".join(leaks))
      pytest.fail("valgrind memleaks found for daemons: " + " ".join(daemons))

E Failed: valgrind memleaks found for daemons: bgpd(33)

../conftest.py:327: Failed
------------------------------------------- Captured log teardown -------------------------------------------
2026-04-13 21:07:21,108 ERROR: topo: valgrind memleaks found:
33 in /tmp/topotests/bgp_evpn_three_tier_clos_topo1.test_bgp_evpn_v4_v6_vtep/bordertor-11.valgrind.bgpd.257900
============================================= warnings summary ==============================================
../../../../../../../usr/lib/python3/dist-packages/_pytest/config/init.py:1233
/usr/lib/python3/dist-packages/_pytest/config/init.py:1233: PytestConfigWarning: Unknown config option: asyncio_default_fixture_loop_scope

self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")

../../../../../../../usr/lib/python3/dist-packages/_pytest/config/init.py:1233
/usr/lib/python3/dist-packages/_pytest/config/init.py:1233: PytestConfigWarning: Unknown config option: asyncio_mode

self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")

-- Docs: https://docs.pytest.org/en/stable/warnings.html
----------------------------- generated xml file: /tmp/topotests/topotests.xml ------------------------------
========================================== short test summary info ==========================================
ERROR test_bgp_evpn_v4_v6_vtep.py::test_memory_leak[ipv6] - Failed: valgrind memleaks found for daemons: b...
====================== 33 passed, 5 skipped, 2 warnings, 1 error in 272.72s (0:04:32) =======================

tests/topotests/bgp_evpn_three_tier_clos_topo1$ sudo cat /tmp/topotests/bgp_evpn_three_tier_clos_topo1.test_bgp_evpn_v4_v6_vtep/bordertor-11.valgrind.bgpd.257900
[sudo] password for souroy:
==257900== Memcheck, a memory error detector
==257900== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==257900== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==257900== Command: /usr/lib/frr/bgpd --command-log-always --log file:bgpd.log --log-level debug -d
==257900== Parent PID: 257899
==257900==
==257900==
==257900== HEAP SUMMARY:
==257900== in use at exit: 199,675 bytes in 395 blocks
==257900== total heap usage: 446,792 allocs, 446,397 frees, 44,200,817 bytes allocated
==257900==
==257900== 20 bytes in 1 blocks are possibly lost in loss record 12 of 122
==257900== at 0x4865058: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x4C6346F: strdup (strdup.c:42)
==257900== by 0x495FC23: qstrdup (memory.c:123)
==257900== by 0x317B17: bgp_create (bgpd.c:3714)
==257900== by 0x3185DB: bgp_get (bgpd.c:4092)
==257900== by 0x2DAB1F: bgp_get_vty (bgp_vty.c:701)
==257900== by 0x2DAB1F: router_bgp (bgp_vty.c:1744)
==257900== by 0x4923C97: cmd_execute_command_real (command.c:1011)
==257900== by 0x4923D8F: cmd_execute_command (command.c:1070)
==257900== by 0x4923FFB: cmd_execute (command.c:1236)
==257900== by 0x49B6FE7: vty_command (vty.c:593)
==257900== by 0x49B79FB: vty_execute (vty.c:1356)
==257900== by 0x49BA937: vtysh_read (vty.c:2302)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 40 bytes in 1 blocks are possibly lost in loss record 39 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x498BFF7: ringbuf_new (ringbuf.c:16)
==257900== by 0x313C83: bgp_peer_connection_new (bgpd.c:1332)
==257900== by 0x31759F: peer_new (bgpd.c:1698)
==257900== by 0x317AEB: bgp_create (bgpd.c:3711)
==257900== by 0x3185DB: bgp_get (bgpd.c:4092)
==257900== by 0x2DAB1F: bgp_get_vty (bgp_vty.c:701)
==257900== by 0x2DAB1F: router_bgp (bgp_vty.c:1744)
==257900== by 0x4923C97: cmd_execute_command_real (command.c:1011)
==257900== by 0x4923D8F: cmd_execute_command (command.c:1070)
==257900== by 0x4923FFB: cmd_execute (command.c:1236)
==257900== by 0x49B6FE7: vty_command (vty.c:593)
==257900== by 0x49B79FB: vty_execute (vty.c:1356)
==257900== by 0x49BA937: vtysh_read (vty.c:2302)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 64 bytes in 1 blocks are possibly lost in loss record 58 of 122
==257900== at 0x486A190: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495FB13: qrealloc (memory.c:118)
==257900== by 0x49B299F: typesafe_hash_shrink (typesafe.c:191)
==257900== by 0x49AA9F7: rn_hash_node_del (table.c:33)
==257900== by 0x49AA9F7: route_node_delete (table.c:426)
==257900== by 0x2BFECF: route_unlock_node (table.h:266)
==257900== by 0x2BFECF: bgp_dest_unlock_node (bgp_table.c:113)
==257900== by 0x2C4433: adj_free (bgp_updgrp_adv.c:89)
==257900== by 0x2C7D77: subgroup_withdraw_packet (bgp_updgrp_packet.c:1154)
==257900== by 0x27A92B: bgp_generate_updgrp_packets (bgp_packet.c:523)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 80 bytes in 1 blocks are possibly lost in loss record 59 of 122
==257900== at 0x4865058: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F913: qmalloc (memory.c:106)
==257900== by 0x49A7A5F: stream_fifo_new (stream.c:1261)
==257900== by 0x313C5B: bgp_peer_connection_new (bgpd.c:1315)
==257900== by 0x31759F: peer_new (bgpd.c:1698)
==257900== by 0x317AEB: bgp_create (bgpd.c:3711)
==257900== by 0x3185DB: bgp_get (bgpd.c:4092)
==257900== by 0x2DAB1F: bgp_get_vty (bgp_vty.c:701)
==257900== by 0x2DAB1F: router_bgp (bgp_vty.c:1744)
==257900== by 0x4923C97: cmd_execute_command_real (command.c:1011)
==257900== by 0x4923D8F: cmd_execute_command (command.c:1070)
==257900== by 0x4923FFB: cmd_execute (command.c:1236)
==257900== by 0x49B6FE7: vty_command (vty.c:593)
==257900== by 0x49B79FB: vty_execute (vty.c:1356)
==257900== by 0x49BA937: vtysh_read (vty.c:2302)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 80 bytes in 1 blocks are possibly lost in loss record 60 of 122
==257900== at 0x4865058: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F913: qmalloc (memory.c:106)
==257900== by 0x49A7A5F: stream_fifo_new (stream.c:1261)
==257900== by 0x313C63: bgp_peer_connection_new (bgpd.c:1316)
==257900== by 0x31759F: peer_new (bgpd.c:1698)
==257900== by 0x317AEB: bgp_create (bgpd.c:3711)
==257900== by 0x3185DB: bgp_get (bgpd.c:4092)
==257900== by 0x2DAB1F: bgp_get_vty (bgp_vty.c:701)
==257900== by 0x2DAB1F: router_bgp (bgp_vty.c:1744)
==257900== by 0x4923C97: cmd_execute_command_real (command.c:1011)
==257900== by 0x4923D8F: cmd_execute_command (command.c:1070)
==257900== by 0x4923FFB: cmd_execute (command.c:1236)
==257900== by 0x49B6FE7: vty_command (vty.c:593)
==257900== by 0x49B79FB: vty_execute (vty.c:1356)
==257900== by 0x49BA937: vtysh_read (vty.c:2302)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 80 bytes in 1 blocks are possibly lost in loss record 61 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x2BFDAB: bgp_table_init (bgp_table.c:163)
==257900== by 0x28B88F: bgp_afi_node_get (bgp_route.c:266)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x223C8F: update_evpn_type5_route.constprop.0 (bgp_evpn.c:1855)
==257900== by 0x22918B: bgp_evpn_advertise_type5_route (bgp_evpn.c:5665)
==257900== by 0x22C0E3: bgp_evpn_advertise_type5_routes (bgp_evpn.c:5697)
==257900== by 0x22C18F: update_advertise_vrf_routes (bgp_evpn.c:4647)
==257900== by 0x22C18F: update_advertise_vrf_routes (bgp_evpn.c:4633)
==257900== by 0x22D743: bgp_evpn_local_l3vni_add (bgp_evpn.c:7404)
==257900== by 0x305DC3: bgp_zebra_process_local_l3vni (bgp_zebra.c:3465)
==257900== by 0x49C7F43: zclient_read (zclient.c:4885)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 80 bytes in 1 blocks are possibly lost in loss record 62 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x2BFDAB: bgp_table_init (bgp_table.c:163)
==257900== by 0x28B88F: bgp_afi_node_get (bgp_route.c:266)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x223C8F: update_evpn_type5_route.constprop.0 (bgp_evpn.c:1855)
==257900== by 0x22918B: bgp_evpn_advertise_type5_route (bgp_evpn.c:5665)
==257900== by 0x2AAE17: bgp_process_main_one (bgp_route.c:4321)
==257900== by 0x2AB717: process_subq_other_route (bgp_route.c:4795)
==257900== by 0x2AB717: process_subq (bgp_route.c:4842)
==257900== by 0x2AB717: meta_queue_process (bgp_route.c:4878)
==257900== by 0x49BBFFB: work_queue_run (workqueue.c:279)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 96 bytes in 1 blocks are possibly lost in loss record 66 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x49A9ADF: route_table_init_with_delegate (table.c:46)
==257900== by 0x2BFDBB: bgp_table_init (bgp_table.c:165)
==257900== by 0x28B88F: bgp_afi_node_get (bgp_route.c:266)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x223C8F: update_evpn_type5_route.constprop.0 (bgp_evpn.c:1855)
==257900== by 0x22918B: bgp_evpn_advertise_type5_route (bgp_evpn.c:5665)
==257900== by 0x22C0E3: bgp_evpn_advertise_type5_routes (bgp_evpn.c:5697)
==257900== by 0x22C18F: update_advertise_vrf_routes (bgp_evpn.c:4647)
==257900== by 0x22C18F: update_advertise_vrf_routes (bgp_evpn.c:4633)
==257900== by 0x22D743: bgp_evpn_local_l3vni_add (bgp_evpn.c:7404)
==257900== by 0x305DC3: bgp_zebra_process_local_l3vni (bgp_zebra.c:3465)
==257900== by 0x49C7F43: zclient_read (zclient.c:4885)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 96 bytes in 1 blocks are possibly lost in loss record 67 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x49A9ADF: route_table_init_with_delegate (table.c:46)
==257900== by 0x2BFDBB: bgp_table_init (bgp_table.c:165)
==257900== by 0x28B88F: bgp_afi_node_get (bgp_route.c:266)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x223C8F: update_evpn_type5_route.constprop.0 (bgp_evpn.c:1855)
==257900== by 0x22918B: bgp_evpn_advertise_type5_route (bgp_evpn.c:5665)
==257900== by 0x2AAE17: bgp_process_main_one (bgp_route.c:4321)
==257900== by 0x2AB717: process_subq_other_route (bgp_route.c:4795)
==257900== by 0x2AB717: process_subq (bgp_route.c:4842)
==257900== by 0x2AB717: meta_queue_process (bgp_route.c:4878)
==257900== by 0x49BBFFB: work_queue_run (workqueue.c:279)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 152 bytes in 1 blocks are possibly lost in loss record 70 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x49AA4EF: route_node_new (table.c:77)
==257900== by 0x49AA4EF: route_node_get (table.c:322)
==257900== by 0x28B82F: bgp_node_get (bgp_table.h:263)
==257900== by 0x28B82F: bgp_afi_node_get (bgp_route.c:263)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x223C8F: update_evpn_type5_route.constprop.0 (bgp_evpn.c:1855)
==257900== by 0x22918B: bgp_evpn_advertise_type5_route (bgp_evpn.c:5665)
==257900== by 0x22C0E3: bgp_evpn_advertise_type5_routes (bgp_evpn.c:5697)
==257900== by 0x22C18F: update_advertise_vrf_routes (bgp_evpn.c:4647)
==257900== by 0x22C18F: update_advertise_vrf_routes (bgp_evpn.c:4633)
==257900== by 0x22D743: bgp_evpn_local_l3vni_add (bgp_evpn.c:7404)
==257900== by 0x305DC3: bgp_zebra_process_local_l3vni (bgp_zebra.c:3465)
==257900== by 0x49C7F43: zclient_read (zclient.c:4885)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 152 bytes in 1 blocks are possibly lost in loss record 71 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x49AA4EF: route_node_new (table.c:77)
==257900== by 0x49AA4EF: route_node_get (table.c:322)
==257900== by 0x28B82F: bgp_node_get (bgp_table.h:263)
==257900== by 0x28B82F: bgp_afi_node_get (bgp_route.c:263)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x223C8F: update_evpn_type5_route.constprop.0 (bgp_evpn.c:1855)
==257900== by 0x22918B: bgp_evpn_advertise_type5_route (bgp_evpn.c:5665)
==257900== by 0x2AAE17: bgp_process_main_one (bgp_route.c:4321)
==257900== by 0x2AB717: process_subq_other_route (bgp_route.c:4795)
==257900== by 0x2AB717: process_subq (bgp_route.c:4842)
==257900== by 0x2AB717: meta_queue_process (bgp_route.c:4878)
==257900== by 0x49BBFFB: work_queue_run (workqueue.c:279)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 160 bytes in 1 blocks are possibly lost in loss record 75 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x28B8EB: bgp_node_get (bgp_table.h:266)
==257900== by 0x28B8EB: bgp_afi_node_get (bgp_route.c:263)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x223C8F: update_evpn_type5_route.constprop.0 (bgp_evpn.c:1855)
==257900== by 0x22918B: bgp_evpn_advertise_type5_route (bgp_evpn.c:5665)
==257900== by 0x22C0E3: bgp_evpn_advertise_type5_routes (bgp_evpn.c:5697)
==257900== by 0x22C18F: update_advertise_vrf_routes (bgp_evpn.c:4647)
==257900== by 0x22C18F: update_advertise_vrf_routes (bgp_evpn.c:4633)
==257900== by 0x22D743: bgp_evpn_local_l3vni_add (bgp_evpn.c:7404)
==257900== by 0x305DC3: bgp_zebra_process_local_l3vni (bgp_zebra.c:3465)
==257900== by 0x49C7F43: zclient_read (zclient.c:4885)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 160 bytes in 1 blocks are possibly lost in loss record 76 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x28B8EB: bgp_node_get (bgp_table.h:266)
==257900== by 0x28B8EB: bgp_afi_node_get (bgp_route.c:263)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x223C8F: update_evpn_type5_route.constprop.0 (bgp_evpn.c:1855)
==257900== by 0x22918B: bgp_evpn_advertise_type5_route (bgp_evpn.c:5665)
==257900== by 0x2AAE17: bgp_process_main_one (bgp_route.c:4321)
==257900== by 0x2AB717: process_subq_other_route (bgp_route.c:4795)
==257900== by 0x2AB717: process_subq (bgp_route.c:4842)
==257900== by 0x2AB717: meta_queue_process (bgp_route.c:4878)
==257900== by 0x49BBFFB: work_queue_run (workqueue.c:279)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 160 bytes in 4 blocks are possibly lost in loss record 77 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x28BBE3: bgp_evpn_path_info_extra_get (bgp_route.c:417)
==257900== by 0x223FC3: update_evpn_type5_route_entry (bgp_evpn.c:1719)
==257900== by 0x223FC3: update_evpn_type5_route.constprop.0 (bgp_evpn.c:1860)
==257900== by 0x22918B: bgp_evpn_advertise_type5_route (bgp_evpn.c:5665)
==257900== by 0x2AAE17: bgp_process_main_one (bgp_route.c:4321)
==257900== by 0x2AB717: process_subq_other_route (bgp_route.c:4795)
==257900== by 0x2AB717: process_subq (bgp_route.c:4842)
==257900== by 0x2AB717: meta_queue_process (bgp_route.c:4878)
==257900== by 0x49BBFFB: work_queue_run (workqueue.c:279)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 240 bytes in 3 blocks are possibly lost in loss record 78 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x2BFDAB: bgp_table_init (bgp_table.c:163)
==257900== by 0x28B88F: bgp_afi_node_get (bgp_route.c:266)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x225D87: update_evpn_route (bgp_evpn.c:2438)
==257900== by 0x22E13B: bgp_evpn_local_vni_add (bgp_evpn.c:7715)
==257900== by 0x304B6F: bgp_zebra_process_local_vni (bgp_zebra.c:3524)
==257900== by 0x49C7F43: zclient_read (zclient.c:4885)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 288 bytes in 3 blocks are possibly lost in loss record 81 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x49A9ADF: route_table_init_with_delegate (table.c:46)
==257900== by 0x2BFDBB: bgp_table_init (bgp_table.c:165)
==257900== by 0x28B88F: bgp_afi_node_get (bgp_route.c:266)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x225D87: update_evpn_route (bgp_evpn.c:2438)
==257900== by 0x22E13B: bgp_evpn_local_vni_add (bgp_evpn.c:7715)
==257900== by 0x304B6F: bgp_zebra_process_local_vni (bgp_zebra.c:3524)
==257900== by 0x49C7F43: zclient_read (zclient.c:4885)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 288 bytes in 4 blocks are possibly lost in loss record 82 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x28BBBF: bgp_path_info_extra_new (bgp_route.c:317)
==257900== by 0x28BBBF: bgp_evpn_path_info_extra_get (bgp_route.c:415)
==257900== by 0x223FC3: update_evpn_type5_route_entry (bgp_evpn.c:1719)
==257900== by 0x223FC3: update_evpn_type5_route.constprop.0 (bgp_evpn.c:1860)
==257900== by 0x22918B: bgp_evpn_advertise_type5_route (bgp_evpn.c:5665)
==257900== by 0x2AAE17: bgp_process_main_one (bgp_route.c:4321)
==257900== by 0x2AB717: process_subq_other_route (bgp_route.c:4795)
==257900== by 0x2AB717: process_subq (bgp_route.c:4842)
==257900== by 0x2AB717: meta_queue_process (bgp_route.c:4878)
==257900== by 0x49BBFFB: work_queue_run (workqueue.c:279)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 416 bytes in 1 blocks are possibly lost in loss record 87 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x313C1B: bgp_peer_connection_new (bgpd.c:1304)
==257900== by 0x31759F: peer_new (bgpd.c:1698)
==257900== by 0x317AEB: bgp_create (bgpd.c:3711)
==257900== by 0x3185DB: bgp_get (bgpd.c:4092)
==257900== by 0x2DAB1F: bgp_get_vty (bgp_vty.c:701)
==257900== by 0x2DAB1F: router_bgp (bgp_vty.c:1744)
==257900== by 0x4923C97: cmd_execute_command_real (command.c:1011)
==257900== by 0x4923D8F: cmd_execute_command (command.c:1070)
==257900== by 0x4923FFB: cmd_execute (command.c:1236)
==257900== by 0x49B6FE7: vty_command (vty.c:593)
==257900== by 0x49B79FB: vty_execute (vty.c:1356)
==257900== by 0x49BA937: vtysh_read (vty.c:2302)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 456 bytes in 3 blocks are possibly lost in loss record 88 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x49AA4EF: route_node_new (table.c:77)
==257900== by 0x49AA4EF: route_node_get (table.c:322)
==257900== by 0x28B82F: bgp_node_get (bgp_table.h:263)
==257900== by 0x28B82F: bgp_afi_node_get (bgp_route.c:263)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x225D87: update_evpn_route (bgp_evpn.c:2438)
==257900== by 0x22E13B: bgp_evpn_local_vni_add (bgp_evpn.c:7715)
==257900== by 0x304B6F: bgp_zebra_process_local_vni (bgp_zebra.c:3524)
==257900== by 0x49C7F43: zclient_read (zclient.c:4885)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 480 bytes in 3 blocks are possibly lost in loss record 89 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x28B8EB: bgp_node_get (bgp_table.h:266)
==257900== by 0x28B8EB: bgp_afi_node_get (bgp_route.c:263)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x225D87: update_evpn_route (bgp_evpn.c:2438)
==257900== by 0x22E13B: bgp_evpn_local_vni_add (bgp_evpn.c:7715)
==257900== by 0x304B6F: bgp_zebra_process_local_vni (bgp_zebra.c:3524)
==257900== by 0x49C7F43: zclient_read (zclient.c:4885)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 480 bytes in 6 blocks are possibly lost in loss record 90 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x2BFDAB: bgp_table_init (bgp_table.c:163)
==257900== by 0x28B88F: bgp_afi_node_get (bgp_route.c:266)
==257900== by 0x294AF3: bgp_update (bgp_route.c:5734)
==257900== by 0x220E93: process_type5_route (bgp_evpn.c:5296)
==257900== by 0x22A34F: bgp_nlri_parse_evpn (bgp_evpn.c:6530)
==257900== by 0x2794A3: bgp_update_receive (bgp_packet.c:2530)
==257900== by 0x27FA5B: bgp_process_packet (bgp_packet.c:4167)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 480 bytes in 6 blocks are possibly lost in loss record 91 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x2BFDAB: bgp_table_init (bgp_table.c:163)
==257900== by 0x28B88F: bgp_afi_node_get (bgp_route.c:266)
==257900== by 0x294AF3: bgp_update (bgp_route.c:5734)
==257900== by 0x22A4BB: process_type3_route (bgp_evpn.c:5156)
==257900== by 0x22A4BB: bgp_nlri_parse_evpn (bgp_evpn.c:6494)
==257900== by 0x2794A3: bgp_update_receive (bgp_packet.c:2530)
==257900== by 0x27FA5B: bgp_process_packet (bgp_packet.c:4167)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 576 bytes in 6 blocks are possibly lost in loss record 92 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x49A9ADF: route_table_init_with_delegate (table.c:46)
==257900== by 0x2BFDBB: bgp_table_init (bgp_table.c:165)
==257900== by 0x28B88F: bgp_afi_node_get (bgp_route.c:266)
==257900== by 0x294AF3: bgp_update (bgp_route.c:5734)
==257900== by 0x220E93: process_type5_route (bgp_evpn.c:5296)
==257900== by 0x22A34F: bgp_nlri_parse_evpn (bgp_evpn.c:6530)
==257900== by 0x2794A3: bgp_update_receive (bgp_packet.c:2530)
==257900== by 0x27FA5B: bgp_process_packet (bgp_packet.c:4167)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 576 bytes in 6 blocks are possibly lost in loss record 93 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x49A9ADF: route_table_init_with_delegate (table.c:46)
==257900== by 0x2BFDBB: bgp_table_init (bgp_table.c:165)
==257900== by 0x28B88F: bgp_afi_node_get (bgp_route.c:266)
==257900== by 0x294AF3: bgp_update (bgp_route.c:5734)
==257900== by 0x22A4BB: process_type3_route (bgp_evpn.c:5156)
==257900== by 0x22A4BB: bgp_nlri_parse_evpn (bgp_evpn.c:6494)
==257900== by 0x2794A3: bgp_update_receive (bgp_packet.c:2530)
==257900== by 0x27FA5B: bgp_process_packet (bgp_packet.c:4167)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 608 bytes in 4 blocks are possibly lost in loss record 95 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x49AA4EF: route_node_new (table.c:77)
==257900== by 0x49AA4EF: route_node_get (table.c:322)
==257900== by 0x28B89F: bgp_node_get (bgp_table.h:263)
==257900== by 0x28B89F: bgp_afi_node_get (bgp_route.c:275)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x223C8F: update_evpn_type5_route.constprop.0 (bgp_evpn.c:1855)
==257900== by 0x22918B: bgp_evpn_advertise_type5_route (bgp_evpn.c:5665)
==257900== by 0x2AAE17: bgp_process_main_one (bgp_route.c:4321)
==257900== by 0x2AB717: process_subq_other_route (bgp_route.c:4795)
==257900== by 0x2AB717: process_subq (bgp_route.c:4842)
==257900== by 0x2AB717: meta_queue_process (bgp_route.c:4878)
==257900== by 0x49BBFFB: work_queue_run (workqueue.c:279)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 640 bytes in 4 blocks are possibly lost in loss record 97 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x28B95F: bgp_node_get (bgp_table.h:266)
==257900== by 0x28B95F: bgp_afi_node_get (bgp_route.c:275)
==257900== by 0x2236EF: bgp_evpn_global_node_get (bgp_evpn.c:741)
==257900== by 0x223C8F: update_evpn_type5_route.constprop.0 (bgp_evpn.c:1855)
==257900== by 0x22918B: bgp_evpn_advertise_type5_route (bgp_evpn.c:5665)
==257900== by 0x2AAE17: bgp_process_main_one (bgp_route.c:4321)
==257900== by 0x2AB717: process_subq_other_route (bgp_route.c:4795)
==257900== by 0x2AB717: process_subq (bgp_route.c:4842)
==257900== by 0x2AB717: meta_queue_process (bgp_route.c:4878)
==257900== by 0x49BBFFB: work_queue_run (workqueue.c:279)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 640 bytes in 4 blocks are possibly lost in loss record 98 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x28E937: info_make (bgp_route.c:5420)
==257900== by 0x223FAF: update_evpn_type5_route_entry (bgp_evpn.c:1712)
==257900== by 0x223FAF: update_evpn_type5_route.constprop.0 (bgp_evpn.c:1860)
==257900== by 0x22918B: bgp_evpn_advertise_type5_route (bgp_evpn.c:5665)
==257900== by 0x2AAE17: bgp_process_main_one (bgp_route.c:4321)
==257900== by 0x2AB717: process_subq_other_route (bgp_route.c:4795)
==257900== by 0x2AB717: process_subq (bgp_route.c:4842)
==257900== by 0x2AB717: meta_queue_process (bgp_route.c:4878)
==257900== by 0x49BBFFB: work_queue_run (workqueue.c:279)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 912 bytes in 6 blocks are possibly lost in loss record 99 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x49AA4EF: route_node_new (table.c:77)
==257900== by 0x49AA4EF: route_node_get (table.c:322)
==257900== by 0x28B82F: bgp_node_get (bgp_table.h:263)
==257900== by 0x28B82F: bgp_afi_node_get (bgp_route.c:263)
==257900== by 0x294AF3: bgp_update (bgp_route.c:5734)
==257900== by 0x220E93: process_type5_route (bgp_evpn.c:5296)
==257900== by 0x22A34F: bgp_nlri_parse_evpn (bgp_evpn.c:6530)
==257900== by 0x2794A3: bgp_update_receive (bgp_packet.c:2530)
==257900== by 0x27FA5B: bgp_process_packet (bgp_packet.c:4167)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 912 bytes in 6 blocks are possibly lost in loss record 100 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x49AA4EF: route_node_new (table.c:77)
==257900== by 0x49AA4EF: route_node_get (table.c:322)
==257900== by 0x28B82F: bgp_node_get (bgp_table.h:263)
==257900== by 0x28B82F: bgp_afi_node_get (bgp_route.c:263)
==257900== by 0x294AF3: bgp_update (bgp_route.c:5734)
==257900== by 0x22A4BB: process_type3_route (bgp_evpn.c:5156)
==257900== by 0x22A4BB: bgp_nlri_parse_evpn (bgp_evpn.c:6494)
==257900== by 0x2794A3: bgp_update_receive (bgp_packet.c:2530)
==257900== by 0x27FA5B: bgp_process_packet (bgp_packet.c:4167)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 960 bytes in 6 blocks are possibly lost in loss record 101 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x28B8EB: bgp_node_get (bgp_table.h:266)
==257900== by 0x28B8EB: bgp_afi_node_get (bgp_route.c:263)
==257900== by 0x294AF3: bgp_update (bgp_route.c:5734)
==257900== by 0x220E93: process_type5_route (bgp_evpn.c:5296)
==257900== by 0x22A34F: bgp_nlri_parse_evpn (bgp_evpn.c:6530)
==257900== by 0x2794A3: bgp_update_receive (bgp_packet.c:2530)
==257900== by 0x27FA5B: bgp_process_packet (bgp_packet.c:4167)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 960 bytes in 6 blocks are possibly lost in loss record 102 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x28B8EB: bgp_node_get (bgp_table.h:266)
==257900== by 0x28B8EB: bgp_afi_node_get (bgp_route.c:263)
==257900== by 0x294AF3: bgp_update (bgp_route.c:5734)
==257900== by 0x22A4BB: process_type3_route (bgp_evpn.c:5156)
==257900== by 0x22A4BB: bgp_nlri_parse_evpn (bgp_evpn.c:6494)
==257900== by 0x2794A3: bgp_update_receive (bgp_packet.c:2530)
==257900== by 0x27FA5B: bgp_process_packet (bgp_packet.c:4167)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 29,968 bytes in 1 blocks are possibly lost in loss record 121 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x31758F: peer_new (bgpd.c:1695)
==257900== by 0x317AEB: bgp_create (bgpd.c:3711)
==257900== by 0x3185DB: bgp_get (bgpd.c:4092)
==257900== by 0x2DAB1F: bgp_get_vty (bgp_vty.c:701)
==257900== by 0x2DAB1F: router_bgp (bgp_vty.c:1744)
==257900== by 0x4923C97: cmd_execute_command_real (command.c:1011)
==257900== by 0x4923D8F: cmd_execute_command (command.c:1070)
==257900== by 0x4923FFB: cmd_execute (command.c:1236)
==257900== by 0x49B6FE7: vty_command (vty.c:593)
==257900== by 0x49B79FB: vty_execute (vty.c:1356)
==257900== by 0x49BA937: vtysh_read (vty.c:2302)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== 98,302 bytes in 1 blocks are possibly lost in loss record 122 of 122
==257900== at 0x4869F34: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==257900== by 0x495F9F7: qcalloc (memory.c:111)
==257900== by 0x498C007: ringbuf_new (ringbuf.c:17)
==257900== by 0x313C83: bgp_peer_connection_new (bgpd.c:1332)
==257900== by 0x31759F: peer_new (bgpd.c:1698)
==257900== by 0x317AEB: bgp_create (bgpd.c:3711)
==257900== by 0x3185DB: bgp_get (bgpd.c:4092)
==257900== by 0x2DAB1F: bgp_get_vty (bgp_vty.c:701)
==257900== by 0x2DAB1F: router_bgp (bgp_vty.c:1744)
==257900== by 0x4923C97: cmd_execute_command_real (command.c:1011)
==257900== by 0x4923D8F: cmd_execute_command (command.c:1070)
==257900== by 0x4923FFB: cmd_execute (command.c:1236)
==257900== by 0x49B6FE7: vty_command (vty.c:593)
==257900== by 0x49B79FB: vty_execute (vty.c:1356)
==257900== by 0x49BA937: vtysh_read (vty.c:2302)
==257900== by 0x49B14F3: event_call (event.c:2740)
==257900== by 0x495116B: frr_run (libfrr.c:1258)
==257900== by 0x2021EF: main (bgp_main.c:550)
==257900==
==257900== LEAK SUMMARY:
==257900== definitely lost: 0 bytes in 0 blocks
==257900== indirectly lost: 0 bytes in 0 blocks
==257900== possibly lost: 139,602 bytes in 96 blocks
==257900== still reachable: 58,327 bytes in 293 blocks
==257900== suppressed: 1,746 bytes in 6 blocks
==257900== Reachable blocks (those to which a pointer was found) are not shown.
==257900== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==257900==
==257900== For lists of detected and suppressed errors, rerun with: -s
==257900== ERROR SUMMARY: 33 errors from 33 contexts (suppressed: 0 from 0)

After fix, no valgrind error>>

============================================= warnings summary ==============================================
../../../../../../../usr/lib/python3/dist-packages/_pytest/config/init.py:1233
/usr/lib/python3/dist-packages/_pytest/config/init.py:1233: PytestConfigWarning: Unknown config option: asyncio_default_fixture_loop_scope

self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")

../../../../../../../usr/lib/python3/dist-packages/_pytest/config/init.py:1233
/usr/lib/python3/dist-packages/_pytest/config/init.py:1233: PytestConfigWarning: Unknown config option: asyncio_mode

self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")

-- Docs: https://docs.pytest.org/en/stable/warnings.html
----------------------------- generated xml file: /tmp/topotests/topotests.xml ------------------------------
=========================== 33 passed, 5 skipped, 2 warnings in 265.28s (0:04:25)

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 13, 2026

Greptile Summary

This PR fixes two memory leaks on BGP daemon shutdown: (1) bgp_cleanup_routes() skipped EVPN and ENCAP two-level table cleanup for hidden instances, leaving route entries behind; (2) a circular lock dependency between bgp_free() and VNI teardown prevented bgp_free() from ever executing for the default instance.

The fix adds a !bm->terminating guard to the skip condition in bgp_cleanup_routes(), and breaks the VNI lock cycle by calling bgp_evpn_cleanup() from bgp_delete() during termination before the final bgp_unlock(). The double-call to bgp_evpn_cleanup() (once from bgp_delete, once from bgp_free) is safe because the function guards on bgp->vnihash == NULL at entry, and hash_clean_and_free() sets that pointer to NULL after the first call. hash_iterate() in FRR also explicitly supports hash_release() during iteration by pre-fetching hbnext, so freeing VNI entries while iterating vnihash is safe.

Confidence Score: 5/5

Safe to merge; fix is logically correct with no new crash or data-safety risks introduced.

All remaining findings are P2 (comment/documentation style). The core logic is sound: hash_iterate() explicitly supports hash_release() during iteration, the vnihash == NULL guard makes the double-call to bgp_evpn_cleanup safe, and bgp_table_finish() handles NULL gracefully. No P0/P1 issues were found.

bgpd/bgpd.c — the ordering of bgp_evpn_cleanup before bgp_unlock is load-bearing and deserves a comment to prevent inadvertent reordering.

Important Files Changed

Filename Overview
bgpd/bgpd.c Adds bgp_evpn_cleanup(bgp) call inside bgp_delete() during termination before bgp_unlock() to release VNI-held locks; bgp_free() still calls bgp_evpn_cleanup() but the NULL-guard makes the second call a no-op.
bgpd/bgp_route.c Adds !bm->terminating to the skip-condition in bgp_cleanup_routes() so EVPN and ENCAP two-level tables are cleaned up during daemon shutdown even for hidden instances.
bgpd/bgp_evpn.c Comment-only update: the NOTE block above bgp_zebra_evpn_pop_items_from_announce_fifo() is extended to document the new bgp_delete()->bgp_evpn_cleanup() call path.

Sequence Diagram

sequenceDiagram
    participant bgp_delete
    participant bgp_evpn_cleanup
    participant free_vni_entry
    participant bgpevpn_unlink_from_l3vni
    participant bgp_unlock
    participant bgp_free

    note over bgp_delete: bm->terminating = true
    bgp_delete->>bgp_delete: bgp_cleanup_routes()<br/>(now cleans EVPN/ENCAP<br/>tables for hidden inst.)
    bgp_delete->>bgp_evpn_cleanup: bgp_evpn_cleanup(bgp) [NEW]
    loop for each L2VNI in vnihash
        bgp_evpn_cleanup->>free_vni_entry: free_vni_entry()
        free_vni_entry->>bgpevpn_unlink_from_l3vni: bgpevpn_unlink_from_l3vni()
        bgpevpn_unlink_from_l3vni->>bgp_unlock: bgp_unlock(vpn->bgp_vrf)<br/>(releases VNI lock on default BGP)
    end
    bgp_evpn_cleanup->>bgp_evpn_cleanup: hash_clean_and_free(&vnihash)<br/>sets vnihash = NULL
    bgp_delete->>bgp_unlock: bgp_unlock(bgp) — initial ref
    note over bgp_unlock: refcount now 0
    bgp_unlock->>bgp_free: bgp_free(bgp)
    bgp_free->>bgp_evpn_cleanup: bgp_evpn_cleanup(bgp) [existing]
    bgp_evpn_cleanup->>bgp_evpn_cleanup: vnihash == NULL → return early (no-op)
Loading

Comments Outside Diff (1)

  1. bgpd/bgp_evpn.c, line 7769-7770 (link)

    P2 Stale function-header comment

    The comment still says "invoked at the time of bgpd exit or when the BGP instance (default) is being freed," but the function now has a third call site: bgp_delete() when bm->terminating, which fires before the bgp_free() path. The description is not wrong (daemon exit does cover that path semantically), but explicitly naming the bgp_delete() caller here would match the updated NOTE block at line 5380–5381 and make the dual-call contract clearer to future readers.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: bgpd/bgp_evpn.c
    Line: 7769-7770
    
    Comment:
    **Stale function-header comment**
    
    The comment still says "invoked at the time of bgpd exit or when the BGP instance (default) is being freed," but the function now has a third call site: `bgp_delete()` when `bm->terminating`, which fires before the `bgp_free()` path. The description is not wrong (daemon exit does cover that path semantically), but explicitly naming the `bgp_delete()` caller here would match the updated NOTE block at line 5380–5381 and make the dual-call contract clearer to future readers.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: bgpd/bgp_evpn.c
Line: 7769-7770

Comment:
**Stale function-header comment**

The comment still says "invoked at the time of bgpd exit or when the BGP instance (default) is being freed," but the function now has a third call site: `bgp_delete()` when `bm->terminating`, which fires before the `bgp_free()` path. The description is not wrong (daemon exit does cover that path semantically), but explicitly naming the `bgp_delete()` caller here would match the updated NOTE block at line 5380–5381 and make the dual-call contract clearer to future readers.

```suggestion
 * Cleanup EVPN information - invoked at the time of bgpd exit:
 * called from bgp_delete() (while bm->terminating) to release VNI locks
 * before bgp_unlock(), and called again from bgp_free() (no-op on second
 * call because vnihash is NULL after the first call).
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: bgpd/bgpd.c
Line: 4590-4596

Comment:
**Missing comment explaining why `bgp_evpn_cleanup` precedes `bgp_unlock`**

The ordering here is load-bearing: `bgp_evpn_cleanup` must run before `bgp_unlock` so that the VNI-held `bgp_lock` references on the default instance are released and the refcount can actually reach zero. Without a comment, the relationship between these two calls is non-obvious and could easily be reordered by a future refactor. A short inline comment — similar to the `/* initial reference */` annotation on `bgp_unlock` — would capture the intent.

```suggestion
	if (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating) {
		if (bm->terminating)
			/*
			 * Release VNI-held bgp_lock references so the
			 * subsequent bgp_unlock() can drive refcount to zero
			 * and trigger bgp_free().  bgp_free() will call
			 * bgp_evpn_cleanup() again, but the NULL vnihash
			 * guard makes that second call a no-op.
			 */
			bgp_evpn_cleanup(bgp);

		if (bgp->process_queue)
			work_queue_free_and_null(&bgp->process_queue);
		bgp_unlock(bgp); /* initial reference */
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "bgpd: fix valgrind memory leaks on daemo..." | Re-trigger Greptile

Comment thread bgpd/bgpd.c
@soumyar-roy soumyar-roy force-pushed the soumya/memleak branch 2 times, most recently from 5562a38 to be7a728 Compare April 14, 2026 14:53
@riw777 riw777 self-requested a review April 14, 2026 15:30
During daemon termination, the default BGP instance leaks due to
two issues:

First, bgp_cleanup_routes() skips EVPN and ENCAP two-level table
cleanup for hidden instances, leaving route entries. Add a terminating
check so these tables are always cleaned during shutdown.

Second, a circular dependency exists between bgp_free() and VNI lock
release: each L2VNI holds a bgp_lock on the default instance via
bgpevpn_link_to_l3vni(), but the only code that releases these locks
(bgp_evpn_cleanup -> free_vni_entry -> bgpevpn_unlink_from_l3vni) lives
inside bgp_free(), which only runs when the lock count reaches zero.
Break this cycle by calling bgp_evpn_cleanup() from bgp_delete() during
termination, before the final bgp_unlock(). This releases VNI-held
locks so the refcount can reach zero and bgp_free() actually executes.

Signed-off-by: Soumya Roy <souroy@nvidia.com>
@soumyar-roy
Copy link
Copy Markdown
Contributor Author

Comments added in code. CI passed too.

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.

1 participant