Commit 7ac0175a78 for frr

commit 7ac0175a78abc84bfbd1cf966052341e670d9ce5
Author: Donald Sharp <sharpd@nvidia.com>
Date:   Fri Oct 2 13:14:10 2026 -0400

    tests: Use delete_address_on_interface

    Convert the tests to use this new functionality.

    Signed-off-by: Donald Sharp <sharpd@nvidia.com>

diff --git a/tests/topotests/bgp_evpn_mh/test_evpn_mh.py b/tests/topotests/bgp_evpn_mh/test_evpn_mh.py
index 93afcc8e20..6d46b383c4 100644
--- a/tests/topotests/bgp_evpn_mh/test_evpn_mh.py
+++ b/tests/topotests/bgp_evpn_mh/test_evpn_mh.py
@@ -36,6 +36,7 @@ from lib import topotest
 from lib.common_config import (
     create_address_on_interface,
     create_interface_in_kernel,
+    delete_address_on_interface,
     kill_router_daemons,
     start_router_daemons,
 )
@@ -1063,7 +1064,9 @@ def test_evpn_vtep_change():
     assert result is None, assertmsg

     # Cleanup: remove secondary loopback
-    remote_tor.run(f"ip addr del {secondary_vtep}/32 dev lo")
+    delete_address_on_interface(
+        remote_tor.tgen, remote_tor.name, "lo", f"{secondary_vtep}/32"
+    )


 def check_protodown_rc(dut, protodown_rc):
diff --git a/tests/topotests/bgp_link_state_bgp_fabric/test_bgp_link_state_bgp_fabric.py b/tests/topotests/bgp_link_state_bgp_fabric/test_bgp_link_state_bgp_fabric.py
index 2d3ebfe6f8..a80b2e7e12 100644
--- a/tests/topotests/bgp_link_state_bgp_fabric/test_bgp_link_state_bgp_fabric.py
+++ b/tests/topotests/bgp_link_state_bgp_fabric/test_bgp_link_state_bgp_fabric.py
@@ -43,7 +43,10 @@ sys.path.append(os.path.join(CWD, "../"))
 # pylint: disable=C0413
 from lib import topotest
 from lib.topogen import Topogen, TopoRouter, get_topogen
-from lib.common_config import create_address_on_interface
+from lib.common_config import (
+    create_address_on_interface,
+    delete_address_on_interface,
+)
 from lib.topolog import logger

 pytestmark = [pytest.mark.bgpd]
@@ -905,7 +908,7 @@ def test_loopback_address_unset_restore():

     # Step 2: Remove IP address from loopback
     logger.info("Step 2: Removing IP address from loopback interface on r1")
-    r1.run("ip addr del 10.1.1.1/32 dev lo")
+    delete_address_on_interface(r1.tgen, r1.name, "lo", "10.1.1.1/32")

     # Step 3: Verify loopback prefix NLRI is withdrawn
     logger.info("Step 3: Verifying loopback prefix NLRI is withdrawn from rr")
diff --git a/tests/topotests/bgp_mpath_invalid_prefix/test_bgp_mpath_invalid_prefix.py b/tests/topotests/bgp_mpath_invalid_prefix/test_bgp_mpath_invalid_prefix.py
index d568bb3be2..8237aad122 100644
--- a/tests/topotests/bgp_mpath_invalid_prefix/test_bgp_mpath_invalid_prefix.py
+++ b/tests/topotests/bgp_mpath_invalid_prefix/test_bgp_mpath_invalid_prefix.py
@@ -28,7 +28,11 @@ sys.path.append(os.path.join(CWD, "../"))
 from lib import topotest
 from lib.topogen import Topogen, get_topogen
 from lib.topolog import logger
-from lib.common_config import create_interface_in_kernel, step
+from lib.common_config import (
+    create_interface_in_kernel,
+    delete_address_on_interface,
+    step,
+)

 pytestmark = [pytest.mark.bgpd]

@@ -108,7 +112,7 @@ def test_bgp_mpath_flag_not_set_when_route_invalid():
     assert res is not None, "Route 200.1.12.0/24 should become valid after adding interface"

     step("Remove 200.1.12.1/24 from dummy so the route becomes invalid again")
-    r1.run("ip addr del {} dev {}".format(NETWORK_IP, DUMMY_IF))
+    delete_address_on_interface(tgen, "r1", DUMMY_IF, NETWORK_IP)

     def _route_has_no_best():
         out = _get_bgp_prefix_json(r1, NETWORK_PREFIX)
diff --git a/tests/topotests/ospf_4222_recommendation_5/test_ospf_broadcast_router_dynamic_pacing.py b/tests/topotests/ospf_4222_recommendation_5/test_ospf_broadcast_router_dynamic_pacing.py
index 24dd9667c0..1f15a1d965 100644
--- a/tests/topotests/ospf_4222_recommendation_5/test_ospf_broadcast_router_dynamic_pacing.py
+++ b/tests/topotests/ospf_4222_recommendation_5/test_ospf_broadcast_router_dynamic_pacing.py
@@ -17,7 +17,11 @@ import time
 from lib import topotest
 from lib.topogen import Topogen, get_topogen
 from lib.topolog import logger
-from lib.common_config import create_address_on_interface, step
+from lib.common_config import (
+    create_address_on_interface,
+    delete_address_on_interface,
+    step,
+)
 from util_pcap import PerInterfacePcapManager

 """
@@ -548,8 +552,8 @@ def test_ospf_dynamic_pacing_queue_kick_on_limit_increase():
         "vtysh -c 'conf t' -c 'router ospf' -c 'no redistribute connected' 2>/dev/null || true"
     )
     for i in range(1, 101):
-        tgen.net["r1"].cmd(f"ip addr del 198.51.110.{i}/32 dev lo 2>/dev/null || true")
-        tgen.net["r1"].cmd(f"ip addr del 198.51.111.{i}/32 dev lo 2>/dev/null || true")
+        delete_address_on_interface(tgen, "r1", "lo", f"198.51.110.{i}/32")
+        delete_address_on_interface(tgen, "r1", "lo", f"198.51.111.{i}/32")

     # At 1Mbps, 200 residual LSA withdrawals (~160KB) complete in ~1.3s.
     # Steady-state U settles to 0-5 with no pending LSAs. L=6 ensures drain passes.
@@ -676,7 +680,7 @@ def test_ospf_dynamic_pacing_queue_kick_on_limit_increase():
         "vtysh -c 'conf t' -c 'router ospf' -c 'no redistribute connected'"
     )
     for i in range(1, 101):
-        tgen.net["r1"].cmd(f"ip addr del 198.51.120.{i}/32 dev lo 2>/dev/null || true")
+        delete_address_on_interface(tgen, "r1", "lo", f"198.51.120.{i}/32")

     # Step 7: All three neighbors must reach Full within 20s. Widened from
     # 15s alongside the r2 ack-delay increase above: some of the pre-clear
@@ -712,7 +716,7 @@ def test_ospf_dynamic_pacing_queue_kick_on_limit_increase():
         "vtysh -c 'conf t' -c 'router ospf' -c 'no redistribute connected' 2>/dev/null || true"
     )
     for i in range(1, 101):
-        tgen.net["r1"].cmd(f"ip addr del 198.51.120.{i}/32 dev lo 2>/dev/null || true")
+        delete_address_on_interface(tgen, "r1", "lo", f"198.51.120.{i}/32")
     tgen.net["r1"].cmd("tc qdisc del dev r1-eth0 root 2>/dev/null || true")
     tgen.net["r1"].cmd(
         "tc qdisc add dev r1-eth0 root handle 1: "
diff --git a/tests/topotests/pim_nocache_forward/test_pim_nocache_forward.py b/tests/topotests/pim_nocache_forward/test_pim_nocache_forward.py
index a76a2353d3..ccb3d65990 100644
--- a/tests/topotests/pim_nocache_forward/test_pim_nocache_forward.py
+++ b/tests/topotests/pim_nocache_forward/test_pim_nocache_forward.py
@@ -58,6 +58,7 @@ sys.path.append(os.path.join(CWD, "../"))
 from lib import topotest
 from lib.common_config import (
     create_address_on_interface,
+    delete_address_on_interface,
     step,
     write_test_footer,
     write_test_header,
@@ -592,7 +593,7 @@ def test_wrongvif_prefer_kernel_ingress(request):
     step("Readdress source host on parent path to overlapping-prefix source")
     # SO_BINDTODEVICE uses the interface primary address; temporarily replace
     # 10.10.4.2 so packets are sourced as WRONGVIF_SOURCE toward the parent.
-    h_src.run("ip addr del 10.10.4.2/24 dev h_src-eth0 || true")
+    delete_address_on_interface(tgen, "h_src", "h_src-eth0", "10.10.4.2/24")
     create_address_on_interface(tgen, "h_src", "h_src-eth0", f"{source}/16")
     h_src.run(
         f"ip route replace default via {WRONGVIF_PARENT_SEC.split('/')[0]} || true"
@@ -716,8 +717,8 @@ def test_wrongvif_prefer_kernel_ingress(request):
     """
     )
     h_src.run(f"ip route del {WRONGVIF_TUNNEL_GW}/32 || true")
-    h_src.run(f"ip addr del {source}/16 dev h_src-eth1 || true")
-    h_src.run(f"ip addr del {source}/16 dev h_src-eth0 || true")
+    delete_address_on_interface(tgen, "h_src", "h_src-eth1", f"{source}/16")
+    delete_address_on_interface(tgen, "h_src", "h_src-eth0", f"{source}/16")
     create_address_on_interface(tgen, "h_src", "h_src-eth0", "10.10.4.2/24")
     h_src.run("ip route replace default via 10.10.4.1 || true")