Commit 39e3a7a59e for frr

commit 39e3a7a59e9148de831524b835a1246c3e31707e
Author: Carmine Scarpitta <cscarpit@cisco.com>
Date:   Mon Oct 19 11:13:54 2026 +0200

    tests: Verify SRv6 SID release across VRF recreation

    Add a test case to show that the uDT46 SID is released when Vrf30 is deleted
    and allocated again when it is recreated. Verify the SID Manager context and
    static route before and after recreation.

    Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>

diff --git a/tests/topotests/static_srv6_sids/test_static_srv6_sids.py b/tests/topotests/static_srv6_sids/test_static_srv6_sids.py
index c42b14ae70..ec73a2dff9 100755
--- a/tests/topotests/static_srv6_sids/test_static_srv6_sids.py
+++ b/tests/topotests/static_srv6_sids/test_static_srv6_sids.py
@@ -54,6 +54,46 @@ def check_srv6_static_sids(router, expected_file, exact=False):
     assert result is None, "Failed"


+def check_srv6_static_sid_route(router, route, expected_present):
+    def _check():
+        output = json.loads(router.vtysh_cmd("show ipv6 route static json"))
+        route_present = route in output
+        if route_present == expected_present:
+            return None
+        state = "present" if route_present else "absent"
+        expected_state = "present" if expected_present else "absent"
+        return "Static route {} is {}, expected {}".format(route, state, expected_state)
+
+    _, result = topotest.run_and_expect(_check, None, count=15, wait=1)
+    assert result is None, "Failed: {}".format(result)
+
+
+def check_srv6_sid_manager(router, sid, expected_context):
+    def _check():
+        output = json.loads(router.vtysh_cmd("show segment-routing srv6 sid json"))
+        sid_info = output.get(sid)
+
+        if expected_context is None:
+            if sid_info is None:
+                return None
+            return "SID {} is still allocated: {}".format(sid, sid_info)
+
+        if sid_info is None:
+            return "SID {} is not allocated".format(sid)
+
+        actual_context = sid_info.get("context", {})
+        for key, expected_value in expected_context.items():
+            actual_value = actual_context.get(key)
+            if actual_value != expected_value:
+                return "SID {} has context {}, expected {}={}".format(
+                    sid, actual_context, key, expected_value
+                )
+        return None
+
+    _, result = topotest.run_and_expect(_check, None, count=15, wait=1)
+    assert result is None, "Failed: {}".format(result)
+
+
 def setup_module(mod):
     # This topotest sets net.vrf.strict_mode during setup. That sysctl is
     # available only after the VRF module is loaded; if the module is not loaded,
@@ -775,6 +815,56 @@ def test_srv6_static_sids_same_address_missing_locator():
     check_srv6_static_sids(router, "expected_srv6_sids.json")


+def test_srv6_static_sid_vrf_recreation():
+    """Release and reallocate a static uDT46 SID as its VRF is recreated."""
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+    router = tgen.gears["r1"]
+
+    sid = "fcbb:bbbb:1:fe30::"
+    sid_prefix = "{}/64".format(sid)
+    check_srv6_static_sids(router, "expected_srv6_sids.json")
+    check_srv6_sid_manager(router, sid, {"vrfName": "Vrf30"})
+
+    logger.info("Delete Vrf30")
+    router.run("ip link del Vrf30")
+    check_srv6_sid_manager(router, sid, None)
+    check_srv6_static_sid_route(router, sid_prefix, expected_present=False)
+
+    logger.info("Recreate Vrf30 with the same table ID")
+    router.run("ip link add Vrf30 type vrf table 30")
+    router.run("ip link set Vrf30 up")
+    check_srv6_sid_manager(router, sid, {"vrfName": "Vrf30"})
+    check_srv6_static_sids(router, "expected_srv6_sids.json")
+
+    logger.info("Delete the uDT46 SID")
+    router.vtysh_cmd(
+        """
+        configure terminal
+         segment-routing
+          srv6
+           static-sids
+            no sid fcbb:bbbb:1:fe30::/64 locator MAIN behavior uDT46 vrf Vrf30
+        """
+    )
+    check_srv6_sid_manager(router, sid, None)
+    check_srv6_static_sid_route(router, sid_prefix, expected_present=False)
+
+    logger.info("Reallocate the uDT46 SID")
+    router.vtysh_cmd(
+        """
+        configure terminal
+         segment-routing
+          srv6
+           static-sids
+            sid fcbb:bbbb:1:fe30::/64 locator MAIN behavior uDT46 vrf Vrf30
+        """
+    )
+    check_srv6_sid_manager(router, sid, {"vrfName": "Vrf30"})
+    check_srv6_static_sids(router, "expected_srv6_sids.json")
+
+
 if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
     sys.exit(pytest.main(args))