diff --git a/test/case/ietf_routing/Readme.adoc b/test/case/ietf_routing/Readme.adoc index afc73832..0a54ca87 100644 --- a/test/case/ietf_routing/Readme.adoc +++ b/test/case/ietf_routing/Readme.adoc @@ -17,3 +17,5 @@ include::ospf_bfd/Readme.adoc[] include::route_pref_ospf/Readme.adoc[] include::route_pref_dhcp/Readme.adoc[] + +include::route_pref_255/Readme.adoc[] diff --git a/test/case/ietf_routing/ietf_routing.yaml b/test/case/ietf_routing/ietf_routing.yaml index 00f59493..4c70c1e7 100644 --- a/test/case/ietf_routing/ietf_routing.yaml +++ b/test/case/ietf_routing/ietf_routing.yaml @@ -19,3 +19,6 @@ - name: route_pref_dhcp case: route_pref_dhcp/test.py + +- name: route_pref_255 + case: route_pref_255/test.py diff --git a/test/case/ietf_routing/route_pref_255/Readme.adoc b/test/case/ietf_routing/route_pref_255/Readme.adoc new file mode 100644 index 00000000..661dcf4b --- /dev/null +++ b/test/case/ietf_routing/route_pref_255/Readme.adoc @@ -0,0 +1,29 @@ +=== Route preference: Static Route Activation and Maximum Distance +==== Description +This test configures a device with a static route to a destination with +a moderate routing preference (254), verifying that it becomes active. +Then, the routing preference is increased to the maximum value (255), +which should prevent the route from becoming active. + +==== Topology +ifdef::topdoc[] +image::../../test/case/ietf_routing/route_pref_255/topology.svg[Route preference: Static Route Activation and Maximum Distance topology] +endif::topdoc[] +ifndef::topdoc[] +ifdef::testgroup[] +image::route_pref_255/topology.svg[Route preference: Static Route Activation and Maximum Distance topology] +endif::testgroup[] +ifndef::testgroup[] +image::topology.svg[Route preference: Static Route Activation and Maximum Distance topology] +endif::testgroup[] +endif::topdoc[] +==== Test sequence +. Set up topology and attach to target DUTs +. Configure targets with active static route +. Verify that static route with preference 254 is active +. Update static route preference to 255 +. Verify that high-preference static route (255) does not become active + + +<<< + diff --git a/test/case/ietf_routing/route_pref_255/test.py b/test/case/ietf_routing/route_pref_255/test.py new file mode 100755 index 00000000..df949358 --- /dev/null +++ b/test/case/ietf_routing/route_pref_255/test.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +""" +Route preference: Static Route Activation and Maximum Distance + +This test configures a device with a static route to a destination with +a moderate routing preference (254), verifying that it becomes active. +Then, the routing preference is increased to the maximum value (255), +which should prevent the route from becoming active. +""" + +import infamy +import infamy.route as route +from infamy.util import until, parallel + +def configure_interface(name, ip, prefix_length, forwarding=True): + return { + "name": name, + "enabled": True, + "ipv4": { + "forwarding": forwarding, + "address": [{"ip": ip, "prefix-length": prefix_length}] + } + } + +def config_target1_initial(target, data, link): + target.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [ + configure_interface(data, "192.168.10.1", 24), + configure_interface(link, "192.168.50.1", 24) + ] + } + }, + "ietf-routing": { + "routing": { + "control-plane-protocols": { + "control-plane-protocol": [ + { + "type": "infix-routing:static", + "name": "default", + "static-routes": { + "ipv4": { + "route": [{ + "destination-prefix": "192.168.20.0/24", + "next-hop": {"next-hop-address": "192.168.50.2"}, + "route-preference": 254 + }] + } + } + } + ] + } + } + } + }) + +def config_target1_update(target): + target.put_config_dicts({ + "ietf-routing": { + "routing": { + "control-plane-protocols": { + "control-plane-protocol": [ + { + "type": "infix-routing:static", + "name": "default", + "static-routes": { + "ipv4": { + "route": [{ + "destination-prefix": "192.168.20.0/24", + "next-hop": {"next-hop-address": "192.168.50.2"}, + "route-preference": 255 + }] + } + } + } + ] + } + } + } + }) + +def config_target2(target, data, link): + target.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [ + configure_interface(data, "192.168.20.2", 24), + configure_interface(link, "192.168.50.2", 24) + ] + } + } + }) + +with infamy.Test() as test: + with test.step("Set up topology and attach to target DUTs"): + env = infamy.Env() + R1 = env.attach("R1", "mgmt") + R2 = env.attach("R2", "mgmt") + + with test.step("Configure targets with active static route"): + _, R1data = env.ltop.xlate("R1", "data") + _, R1link = env.ltop.xlate("R1", "link") + _, R2data = env.ltop.xlate("R2", "data") + _, R2link = env.ltop.xlate("R2", "link") + + parallel(config_target1_initial(R1, R1data, R1link), config_target2(R2, R2data, R2link)) + + with test.step("Verify that static route with preference 254 is active"): + until(lambda: route.ipv4_route_exist(R1, "192.168.20.0/24", proto="ietf-routing:static", active_check=True)) + + with test.step("Update static route preference to 255"): + config_target1_update(R1) + + with test.step("Verify that high-preference static route (255) does not become active"): + until(lambda: not route.ipv4_route_exist(R1, "192.168.20.0/24", proto="ietf-routing:static", active_check=True)) + + test.succeed() diff --git a/test/case/ietf_routing/route_pref_255/topology.dot b/test/case/ietf_routing/route_pref_255/topology.dot new file mode 100644 index 00000000..034d8a1c --- /dev/null +++ b/test/case/ietf_routing/route_pref_255/topology.dot @@ -0,0 +1,38 @@ +graph "route-preference" { + layout="neato"; + overlap="false"; + esep="+20"; + size=10 + + node [shape=record, fontname="DejaVu Sans Mono, Book"]; + edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"]; + + PC + [ + label="PC | { mgmt1 | data1 | data2 | mgmt2 }", + pos="20,58!", + kind="controller", + ]; + + R1 + [ + label="{ mgmt | data | link } | R1", + pos="80,60!", + kind="infix", + ]; + + R2 + [ + label="{ link | data | mgmt } | R2", + pos="80,42!", + kind="infix", + ]; + + PC:mgmt1 -- R1:mgmt [kind=mgmt, color="lightgray"] + PC:mgmt2 -- R2:mgmt [kind=mgmt, color="lightgray"] + + PC:data1 -- R1:data [color="black", headlabel="192.168.10.1/24", taillabel="192.168.10.11/24", fontcolor="black"] + PC:data2 -- R2:data [color="black", headlabel="192.168.20.2/24", taillabel="192.168.20.22/24", fontcolor="black"] + + R1:link -- R2:link [headlabel="192.168.50.2/24", taillabel="192.168.50.1/24", labeldistance=1, fontcolor="black", color="black"] +} diff --git a/test/case/ietf_routing/route_pref_255/topology.svg b/test/case/ietf_routing/route_pref_255/topology.svg new file mode 100644 index 00000000..9f51b89d --- /dev/null +++ b/test/case/ietf_routing/route_pref_255/topology.svg @@ -0,0 +1,81 @@ + + + + + + +route-preference + + + +PC + +PC + +mgmt1 + +data1 + +data2 + +mgmt2 + + + +R1 + +mgmt + +data + +link + +R1 + + + +PC:mgmt1--R1:mgmt + + + + +PC:data1--R1:data + +192.168.10.1/24 +192.168.10.11/24 + + + +R2 + +link + +data + +mgmt + +R2 + + + +PC:mgmt2--R2:mgmt + + + + +PC:data2--R2:data + +192.168.20.2/24 +192.168.20.22/24 + + + +R1:link--R2:link + +192.168.50.2/24 +192.168.50.1/24 + + +