mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-01 21:33:02 +02:00
test: Verify route preference (DHCP vs Static)
This commit is contained in:
@@ -13,3 +13,5 @@ include::ospf_unnumbered_interface/Readme.adoc[]
|
||||
include::ospf_multiarea/Readme.adoc[]
|
||||
|
||||
include::ospf_bfd/Readme.adoc[]
|
||||
|
||||
include::route_pref_dhcp/Readme.adoc[]
|
||||
|
||||
@@ -13,3 +13,6 @@
|
||||
|
||||
- name: ospf_bfd
|
||||
case: ospf_bfd/test.py
|
||||
|
||||
- name: route_pref_dhcp
|
||||
case: route_pref_dhcp/test.py
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
=== Route preference: DHCP vs Static
|
||||
==== Description
|
||||
This test configures a device with both a DHCP-acquired route on a
|
||||
dedicated interface and a static route to the same destination on
|
||||
another interface.
|
||||
|
||||
Initially, DHCP is preferred over Static. Afterwards, the static
|
||||
route takes precedence by adjusting the routing preference value
|
||||
to the one lower than DHCP.
|
||||
|
||||
==== Topology
|
||||
ifdef::topdoc[]
|
||||
image::../../test/case/ietf_routing/route_pref_dhcp/topology.svg[Route preference: DHCP vs Static topology]
|
||||
endif::topdoc[]
|
||||
ifndef::topdoc[]
|
||||
ifdef::testgroup[]
|
||||
image::route_pref_dhcp/topology.svg[Route preference: DHCP vs Static topology]
|
||||
endif::testgroup[]
|
||||
ifndef::testgroup[]
|
||||
image::topology.svg[Route preference: DHCP vs Static topology]
|
||||
endif::testgroup[]
|
||||
endif::topdoc[]
|
||||
==== Test sequence
|
||||
. Set up topology and attach to target DUTs
|
||||
. Configure targets. Assign higher priority to the dhcp route
|
||||
. Wait for DHCP and static routes
|
||||
. Verify connectivity from PC:data12 to R2:lo via DHCP
|
||||
. Assign higher priority to the static route
|
||||
. Verify connectivity from PC:data12 to R2:lo via static route
|
||||
|
||||
|
||||
<<<
|
||||
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Route preference: DHCP vs Static
|
||||
|
||||
This test configures a device with both a DHCP-acquired route on a
|
||||
dedicated interface and a static route to the same destination on
|
||||
another interface.
|
||||
|
||||
Initially, DHCP is preferred over Static. Afterwards, the static
|
||||
route takes precedence by adjusting the routing preference value
|
||||
to the one lower than DHCP.
|
||||
"""
|
||||
|
||||
import infamy
|
||||
import infamy.route as route
|
||||
import infamy.dhcp
|
||||
from infamy.util import until, parallel
|
||||
from infamy.netns import IsolatedMacVlans
|
||||
|
||||
def configure_interface(name, ip=None, prefix_length=None, forwarding=True):
|
||||
interface_config = {
|
||||
"name": name,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": forwarding,
|
||||
"address": []
|
||||
}
|
||||
}
|
||||
if ip and prefix_length:
|
||||
interface_config["ipv4"]["address"].append({"ip": ip, "prefix-length": prefix_length})
|
||||
return interface_config
|
||||
|
||||
def config_target1(target, data1, data2, link):
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
configure_interface(data1),
|
||||
configure_interface(data2, "192.168.30.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": "0.0.0.0/0",
|
||||
"next-hop": {"next-hop-address": "192.168.50.2"},
|
||||
"route-preference": 120
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"infix-dhcp-client": {
|
||||
"dhcp-client": {
|
||||
"enabled": True,
|
||||
"client-if": [
|
||||
{
|
||||
"if-name": data1,
|
||||
"enabled": True,
|
||||
"option": [
|
||||
{"name": "broadcast"},
|
||||
{"name": "dns"},
|
||||
{"name": "domain"},
|
||||
{"name": "hostname"},
|
||||
{"name": "ntpsrv"},
|
||||
{"name": "router"},
|
||||
{"name": "subnet"}
|
||||
],
|
||||
"route-preference": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
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),
|
||||
configure_interface("lo", "192.168.200.1", 32)
|
||||
]
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [
|
||||
{
|
||||
"type": "infix-routing:static",
|
||||
"name": "default",
|
||||
"static-routes": {
|
||||
"ipv4": {
|
||||
"route": [{
|
||||
"destination-prefix": "0.0.0.0/0",
|
||||
"next-hop": {"next-hop-address": "192.168.50.1"}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
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. Assign higher priority to the dhcp route"):
|
||||
_, R1data1 = env.ltop.xlate("R1", "data1")
|
||||
_, R1data2 = env.ltop.xlate("R1", "data2")
|
||||
_, R1link = env.ltop.xlate("R1", "link")
|
||||
_, R2data = env.ltop.xlate("R2", "data")
|
||||
_, R2link = env.ltop.xlate("R2", "link")
|
||||
|
||||
parallel(config_target1(R1, R1data1, R1data2, R1link),
|
||||
config_target2(R2, R2data, R2link))
|
||||
|
||||
_, hport_data12 = env.ltop.xlate("PC", "data12")
|
||||
ns0 = infamy.IsolatedMacVlan(hport_data12).start()
|
||||
ns0.addip("192.168.30.3", prefix_length=24)
|
||||
ns0.addroute("default", "192.168.30.1")
|
||||
|
||||
_, hport_data11 = env.ltop.xlate("PC", "data11")
|
||||
_, hport_data2 = env.ltop.xlate("PC", "data2")
|
||||
ifmap={ hport_data11: "a", hport_data2: "b" }
|
||||
ns1 = IsolatedMacVlans(ifmap, False).start()
|
||||
|
||||
ns1.addip(ifname="b", addr="192.168.20.3", prefix_length=24)
|
||||
ns1.addroute("192.168.200.1/32", "192.168.20.2")
|
||||
|
||||
ns1.addip(ifname="a", addr="192.168.10.3", prefix_length=24)
|
||||
ns1.runsh("ip route add default dev a")
|
||||
|
||||
with infamy.dhcp.Server(netns=ns1, ip="192.168.10.1", netmask="255.255.255.0", router="192.168.10.3", iface="a"):
|
||||
with test.step("Wait for DHCP and static routes"):
|
||||
print("Waiting for DHCP and static routes...")
|
||||
until(lambda: route.ipv4_route_exist(R1, "0.0.0.0/0", proto="ietf-routing:static", pref=5), attempts=200)
|
||||
until(lambda: route.ipv4_route_exist(R1, "0.0.0.0/0", proto="ietf-routing:static", pref=120), attempts=200)
|
||||
|
||||
with test.step("Verify connectivity from PC:data12 to R2:lo via DHCP"):
|
||||
dhcp_route_active = route.ipv4_route_exist(R1, "0.0.0.0/0", pref=5, active_check=True)
|
||||
assert dhcp_route_active, "Failed to activate DHCP route: Expected DHCP-acquired route not found."
|
||||
|
||||
ns0.must_reach("192.168.200.1")
|
||||
|
||||
with test.step("Assign higher priority to the static route"):
|
||||
R1.put_config_dicts({
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [
|
||||
{
|
||||
"type": "infix-routing:static",
|
||||
"name": "default",
|
||||
"static-routes": {
|
||||
"ipv4": {
|
||||
"route": [{
|
||||
"destination-prefix": "0.0.0.0/0",
|
||||
"next-hop": {"next-hop-address": "192.168.50.2"},
|
||||
"route-preference": 1
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
with test.step("Verify connectivity from PC:data12 to R2:lo via static route"):
|
||||
ns0.must_reach("192.168.200.1")
|
||||
|
||||
static_route_active = route.ipv4_route_exist(R1, "0.0.0.0/0", pref=1, active_check=True)
|
||||
assert static_route_active, "Static route activation failed: Verify route-preference adjustment on R1."
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,40 @@
|
||||
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> mgmt1 | <data11> data11 | <data12> data12 | <> \n |<data2> data2 | <mgmt2> mgmt2 }",
|
||||
pos="20,50!",
|
||||
kind="controller",
|
||||
];
|
||||
|
||||
R1
|
||||
[
|
||||
label="{ <mgmt> mgmt | <data1> data1 | <data2> data2 | <link> link } | R1 \n 192.168.100.1/32 \n(lo)",
|
||||
pos="60,51.8!",
|
||||
kind="infix",
|
||||
];
|
||||
|
||||
R2
|
||||
[
|
||||
label="{ <link> link | <data> data | <mgmt> mgmt } | R2 \n 192.168.200.1/32 \n(lo)",
|
||||
pos="60,42!",
|
||||
kind="infix",
|
||||
];
|
||||
|
||||
PC:mgmt1 -- R1:mgmt [kind=mgmt, color="lightgray"]
|
||||
PC:mgmt2 -- R2:mgmt [kind=mgmt, color="lightgray"]
|
||||
|
||||
PC:data11 -- R1:data1 [color="black", headlabel="192.168.10.1/24", taillabel="192.168.10.3/24", fontcolor="black"]
|
||||
PC:data12 -- R1:data2 [color="black", headlabel="192.168.30.1/24", taillabel="192.168.30.3/24", fontcolor="black"]
|
||||
PC:data2 -- R2:data [color="black", headlabel="192.168.20.2/24", taillabel="192.168.20.3/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"]
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
|
||||
<!-- Title: route-preference Pages: 1 -->
|
||||
<svg width="706pt" height="221pt"
|
||||
viewBox="0.00 0.00 705.79 221.01" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 217.01)">
|
||||
<title>route-preference</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-217.01 701.79,-217.01 701.79,4 -4,4"/>
|
||||
<!-- PC -->
|
||||
<g id="node1" class="node">
|
||||
<title>PC</title>
|
||||
<polygon fill="none" stroke="black" points="0,-72.86 0,-211.86 99,-211.86 99,-72.86 0,-72.86"/>
|
||||
<text text-anchor="middle" x="16.5" y="-138.66" font-family="DejaVu Sans Mono, Book" font-size="14.00">PC</text>
|
||||
<polyline fill="none" stroke="black" points="33,-72.86 33,-211.86 "/>
|
||||
<text text-anchor="middle" x="66" y="-196.66" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt1</text>
|
||||
<polyline fill="none" stroke="black" points="33,-188.86 99,-188.86 "/>
|
||||
<text text-anchor="middle" x="66" y="-173.66" font-family="DejaVu Sans Mono, Book" font-size="14.00">data11</text>
|
||||
<polyline fill="none" stroke="black" points="33,-165.86 99,-165.86 "/>
|
||||
<text text-anchor="middle" x="66" y="-150.66" font-family="DejaVu Sans Mono, Book" font-size="14.00">data12</text>
|
||||
<polyline fill="none" stroke="black" points="33,-142.86 99,-142.86 "/>
|
||||
<polyline fill="none" stroke="black" points="33,-118.86 99,-118.86 "/>
|
||||
<text text-anchor="middle" x="66" y="-103.66" font-family="DejaVu Sans Mono, Book" font-size="14.00">data2</text>
|
||||
<polyline fill="none" stroke="black" points="33,-95.86 99,-95.86 "/>
|
||||
<text text-anchor="middle" x="66" y="-80.66" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt2</text>
|
||||
</g>
|
||||
<!-- R1 -->
|
||||
<g id="node2" class="node">
|
||||
<title>R1</title>
|
||||
<polygon fill="none" stroke="black" points="474.79,-120.51 474.79,-212.51 697.79,-212.51 697.79,-120.51 474.79,-120.51"/>
|
||||
<text text-anchor="middle" x="503.79" y="-197.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="474.79,-189.51 532.79,-189.51 "/>
|
||||
<text text-anchor="middle" x="503.79" y="-174.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">data1</text>
|
||||
<polyline fill="none" stroke="black" points="474.79,-166.51 532.79,-166.51 "/>
|
||||
<text text-anchor="middle" x="503.79" y="-151.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">data2</text>
|
||||
<polyline fill="none" stroke="black" points="474.79,-143.51 532.79,-143.51 "/>
|
||||
<text text-anchor="middle" x="503.79" y="-128.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
<polyline fill="none" stroke="black" points="532.79,-120.51 532.79,-212.51 "/>
|
||||
<text text-anchor="middle" x="615.29" y="-177.81" font-family="DejaVu Sans Mono, Book" font-size="14.00">R1 </text>
|
||||
<text text-anchor="middle" x="615.29" y="-162.81" font-family="DejaVu Sans Mono, Book" font-size="14.00"> 192.168.100.1/32 </text>
|
||||
<text text-anchor="middle" x="615.29" y="-147.81" font-family="DejaVu Sans Mono, Book" font-size="14.00">(lo)</text>
|
||||
</g>
|
||||
<!-- PC--R1 -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>PC:mgmt1--R1:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M99.5,-200.36C99.5,-200.36 474.29,-201.51 474.29,-201.51"/>
|
||||
</g>
|
||||
<!-- PC--R1 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>PC:data11--R1:data1</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M99.5,-177.36C99.5,-177.36 474.29,-178.51 474.29,-178.51"/>
|
||||
<text text-anchor="middle" x="415.29" y="-182.31" font-family="DejaVu Serif, Book" font-size="14.00">192.168.10.1/24</text>
|
||||
<text text-anchor="middle" x="158.5" y="-181.16" font-family="DejaVu Serif, Book" font-size="14.00">192.168.10.3/24</text>
|
||||
</g>
|
||||
<!-- PC--R1 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>PC:data12--R1:data2</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M99.5,-154.36C99.5,-154.36 474.29,-154.51 474.29,-154.51"/>
|
||||
<text text-anchor="middle" x="415.29" y="-158.31" font-family="DejaVu Serif, Book" font-size="14.00">192.168.30.1/24</text>
|
||||
<text text-anchor="middle" x="158.5" y="-158.16" font-family="DejaVu Serif, Book" font-size="14.00">192.168.30.3/24</text>
|
||||
</g>
|
||||
<!-- R2 -->
|
||||
<g id="node3" class="node">
|
||||
<title>R2</title>
|
||||
<polygon fill="none" stroke="black" points="478.79,-0.5 478.79,-69.5 693.79,-69.5 693.79,-0.5 478.79,-0.5"/>
|
||||
<text text-anchor="middle" x="503.79" y="-54.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
<polyline fill="none" stroke="black" points="478.79,-46.5 528.79,-46.5 "/>
|
||||
<text text-anchor="middle" x="503.79" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
|
||||
<polyline fill="none" stroke="black" points="478.79,-23.5 528.79,-23.5 "/>
|
||||
<text text-anchor="middle" x="503.79" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="528.79,-0.5 528.79,-69.5 "/>
|
||||
<text text-anchor="middle" x="611.29" y="-46.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">R2 </text>
|
||||
<text text-anchor="middle" x="611.29" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00"> 192.168.200.1/32 </text>
|
||||
<text text-anchor="middle" x="611.29" y="-16.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">(lo)</text>
|
||||
</g>
|
||||
<!-- PC--R2 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>PC:mgmt2--R2:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M99.5,-84.36C99.5,-84.36 478.29,-12 478.29,-12"/>
|
||||
</g>
|
||||
<!-- PC--R2 -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>PC:data2--R2:data</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M99.5,-107.36C99.5,-107.36 478.29,-35 478.29,-35"/>
|
||||
<text text-anchor="middle" x="419.29" y="-38.8" font-family="DejaVu Serif, Book" font-size="14.00">192.168.20.2/24</text>
|
||||
<text text-anchor="middle" x="158.5" y="-111.16" font-family="DejaVu Serif, Book" font-size="14.00">192.168.20.3/24</text>
|
||||
</g>
|
||||
<!-- R1--R2 -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>R1:link--R2:link</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M503.29,-120.51C503.29,-120.51 503.29,-70 503.29,-70"/>
|
||||
<text text-anchor="middle" x="507.51" y="-75.36" font-family="DejaVu Serif, Book" font-size="14.00">192.168.50.2/24</text>
|
||||
<text text-anchor="middle" x="499.06" y="-107.75" font-family="DejaVu Serif, Book" font-size="14.00">192.168.50.1/24</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.4 KiB |
Reference in New Issue
Block a user