mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-06 23:43:20 +02:00
test: add new tests for RIP
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -7,9 +7,13 @@ Tests verifying standard routing protocols and configuration:
|
||||
- OSPF basic neighbor discovery and LSA exchange
|
||||
- OSPF unnumbered interface configuration
|
||||
- OSPF multi-area configuration and inter-area routing
|
||||
- OSPF with BFD (Bidirectional Forwarding Detection)
|
||||
- OSPF with BFD (Bidirectional Forwarding Detection)
|
||||
- OSPF default route advertisement and propagation
|
||||
- OSPF debug logging configuration and verification
|
||||
- RIP basic neighbor discovery and route exchange
|
||||
- RIP passive interface configuration
|
||||
- RIP route redistribution (connected, static, and OSPF)
|
||||
- RIP multi-hop routing with multiple neighbors
|
||||
- Route preference handling for OSPF routes
|
||||
- Route preference handling for DHCP-learned routes
|
||||
- Administrative distance configuration (route preference 255)
|
||||
@@ -42,6 +46,22 @@ include::ospf_debug/Readme.adoc[]
|
||||
|
||||
<<<
|
||||
|
||||
include::rip_basic/Readme.adoc[]
|
||||
|
||||
<<<
|
||||
|
||||
include::rip_passive_interface/Readme.adoc[]
|
||||
|
||||
<<<
|
||||
|
||||
include::rip_redistribute/Readme.adoc[]
|
||||
|
||||
<<<
|
||||
|
||||
include::rip_multihop/Readme.adoc[]
|
||||
|
||||
<<<
|
||||
|
||||
include::route_pref_ospf/Readme.adoc[]
|
||||
|
||||
<<<
|
||||
|
||||
@@ -28,3 +28,15 @@
|
||||
|
||||
- name: OSPF Debug Logging
|
||||
case: ospf_debug/test.py
|
||||
|
||||
- name: RIP Basic
|
||||
case: rip_basic/test.py
|
||||
|
||||
- name: RIP Passive Interface
|
||||
case: rip_passive_interface/test.py
|
||||
|
||||
- name: RIP Redistribution
|
||||
case: rip_redistribute/test.py
|
||||
|
||||
- name: RIP Multi-hop
|
||||
case: rip_multihop/test.py
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
test.adoc
|
||||
@@ -0,0 +1,28 @@
|
||||
=== RIP Basic
|
||||
|
||||
ifdef::topdoc[:imagesdir: {topdoc}../../test/case/routing/rip_basic]
|
||||
|
||||
==== Description
|
||||
|
||||
Verifies basic RIP functionality by configuring two routers (R1 and R2)
|
||||
with RIP on their interconnecting link. The test ensures RIP routes are
|
||||
exchanged between the routers and end-to-end connectivity is achieved.
|
||||
|
||||
The test PC uses data1 interface to connect to R1's data port, and data2
|
||||
interface to connect to R2's data port (which does not have RIP enabled).
|
||||
This verifies that RIP status information remains accessible when a router
|
||||
has non-RIP interfaces.
|
||||
|
||||
==== Topology
|
||||
|
||||
image::topology.svg[RIP Basic topology, align=center, scaledwidth=75%]
|
||||
|
||||
==== Sequence
|
||||
|
||||
. Set up topology and attach to target DUTs
|
||||
. Configure targets
|
||||
. Wait for RIP routes to be exchanged
|
||||
. Test connectivity from PC:data1 to R2 loopback via RIP
|
||||
. Test connectivity from PC:data2 to R1 loopback via RIP
|
||||
|
||||
|
||||
Executable
+215
@@ -0,0 +1,215 @@
|
||||
#!/usr/bin/env python3
|
||||
"""RIP Basic
|
||||
|
||||
Verifies basic RIP functionality by configuring two routers (R1 and R2)
|
||||
with RIP on their interconnecting link. The test ensures RIP routes are
|
||||
exchanged between the routers and end-to-end connectivity is achieved.
|
||||
|
||||
The test PC uses data1 interface to connect to R1's data port, and data2
|
||||
interface to connect to R2's data port (which does not have RIP enabled).
|
||||
This verifies that RIP status information remains accessible when a router
|
||||
has non-RIP interfaces.
|
||||
|
||||
"""
|
||||
|
||||
import infamy
|
||||
import infamy.route as route
|
||||
from infamy.util import until, parallel
|
||||
|
||||
|
||||
def config_target1(target, data, link):
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": data,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.10.1",
|
||||
"prefix-length": 24
|
||||
}]}
|
||||
}, {
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.50.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": "lo",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.100.1",
|
||||
"prefix-length": 32
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R1"
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:static",
|
||||
"name": "default",
|
||||
"static-routes": {
|
||||
"ipv4": {
|
||||
"route": [{
|
||||
"destination-prefix": "192.168.33.1/32",
|
||||
"next-hop": {
|
||||
"special-next-hop": "blackhole"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"type": "infix-routing:ripv2",
|
||||
"name": "default",
|
||||
"rip": {
|
||||
"timers": {
|
||||
"update-interval": 5,
|
||||
"invalid-interval": 15,
|
||||
"flush-interval": 20
|
||||
},
|
||||
"redistribute": {
|
||||
"redistribute": [{
|
||||
"protocol": "static"
|
||||
}, {
|
||||
"protocol": "connected"
|
||||
}]
|
||||
},
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"interface": link
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def config_target2(target, link, data):
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.50.2",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": data,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.60.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": "lo",
|
||||
"enabled": True,
|
||||
"forwarding": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.200.1",
|
||||
"prefix-length": 32
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R2"
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ripv2",
|
||||
"name": "default",
|
||||
"rip": {
|
||||
"timers": {
|
||||
"update-interval": 5,
|
||||
"invalid-interval": 15,
|
||||
"flush-interval": 20
|
||||
},
|
||||
"redistribute": {
|
||||
"redistribute": [{
|
||||
"protocol": "connected"
|
||||
}]
|
||||
},
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"interface": link
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
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"):
|
||||
_, R1data = env.ltop.xlate("R1", "data")
|
||||
_, R2link = env.ltop.xlate("R2", "link")
|
||||
_, R1link = env.ltop.xlate("R1", "link")
|
||||
_, R2data = env.ltop.xlate("R2", "data")
|
||||
|
||||
parallel(config_target1(R1, R1data, R1link),
|
||||
config_target2(R2, R2link, R2data))
|
||||
|
||||
with test.step("Wait for RIP routes to be exchanged"):
|
||||
print("Waiting for RIP routes to propagate...")
|
||||
# R1 should learn R2's loopback
|
||||
until(lambda: route.ipv4_route_exist(R1, "192.168.200.1/32", proto="ietf-rip:rip"), attempts=40)
|
||||
# R2 should learn R1's loopback
|
||||
until(lambda: route.ipv4_route_exist(R2, "192.168.100.1/32", proto="ietf-rip:rip"), attempts=40)
|
||||
# R2 should learn R1's static route (redistributed)
|
||||
until(lambda: route.ipv4_route_exist(R2, "192.168.33.1/32", proto="ietf-rip:rip"), attempts=40)
|
||||
|
||||
with test.step("Test connectivity from PC:data1 to R2 loopback via RIP"):
|
||||
_, hport0 = env.ltop.xlate("PC", "data1")
|
||||
with infamy.IsolatedMacVlan(hport0) as ns0:
|
||||
ns0.addip("192.168.10.2")
|
||||
ns0.addroute("192.168.200.1/32", "192.168.10.1")
|
||||
ns0.must_reach("192.168.200.1")
|
||||
|
||||
with test.step("Test connectivity from PC:data2 to R1 loopback via RIP"):
|
||||
_, hport1 = env.ltop.xlate("PC", "data2")
|
||||
with infamy.IsolatedMacVlan(hport1) as ns1:
|
||||
ns1.addip("192.168.60.2")
|
||||
ns1.addroute("192.168.100.1/32", "192.168.60.1")
|
||||
ns1.must_reach("192.168.100.1")
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,34 @@
|
||||
graph "2x2" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+40";
|
||||
size=10
|
||||
|
||||
node [shape=record, fontname="DejaVu Sans Mono, Book"];
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
PC [
|
||||
label="PC | { <mgmt1> mgmt1 | <data1> data1 | \n\n\n\n\n\n\n\n | <mgmt2> mgmt2 | <data2> data2 }",
|
||||
pos="20,50!",
|
||||
requires="controller",
|
||||
];
|
||||
|
||||
R1 [
|
||||
label="{ <mgmt> mgmt | <data> data | <link> link} | R1 \n 192.168.100.1/32 \n(lo)",
|
||||
pos="190,85!",
|
||||
|
||||
requires="infix",
|
||||
];
|
||||
R2 [
|
||||
label="{ <link> link | <mgmt> mgmt | <data> data } | R2 \n 192.168.200.1/32 \n(lo)",
|
||||
pos="190,15!",
|
||||
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
PC:mgmt1 -- R1:mgmt [requires="mgmt", color="lightgray"]
|
||||
PC:mgmt2 -- R2:mgmt [requires="mgmt", color="lightgray"]
|
||||
PC:data1 -- R1:data [color="black", label="192.168.10.0/24", headlabel=".1", taillabel=".2", labeldistance=2, fontcolor="black"]
|
||||
R1:link -- R2:link [label="192.168.50.0/24", headlabel=".2", taillabel=".1", labeldistance=2, fontcolor="black", color="black"]
|
||||
PC:data2 -- R2:data [label="192.168.60.0/24", headlabel=".1", taillabel=".2", labeldistance=2, fontcolor="black", color="black"]
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?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: 2x2 Pages: 1 -->
|
||||
<svg width="574pt" height="249pt"
|
||||
viewBox="0.00 0.00 573.90 248.51" 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 244.51)">
|
||||
<title>2x2</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-244.51 569.9,-244.51 569.9,4 -4,4"/>
|
||||
<!-- PC -->
|
||||
<g id="node1" class="node">
|
||||
<title>PC</title>
|
||||
<polygon fill="none" stroke="black" points="0,-6.5 0,-234.5 91,-234.5 91,-6.5 0,-6.5"/>
|
||||
<text text-anchor="middle" x="16.5" y="-116.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">PC</text>
|
||||
<polyline fill="none" stroke="black" points="33,-6.5 33,-234.5 "/>
|
||||
<text text-anchor="middle" x="62" y="-219.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt1</text>
|
||||
<polyline fill="none" stroke="black" points="33,-211.5 91,-211.5 "/>
|
||||
<text text-anchor="middle" x="62" y="-196.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data1</text>
|
||||
<polyline fill="none" stroke="black" points="33,-188.5 91,-188.5 "/>
|
||||
<polyline fill="none" stroke="black" points="33,-52.5 91,-52.5 "/>
|
||||
<text text-anchor="middle" x="62" y="-37.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt2</text>
|
||||
<polyline fill="none" stroke="black" points="33,-29.5 91,-29.5 "/>
|
||||
<text text-anchor="middle" x="62" y="-14.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data2</text>
|
||||
</g>
|
||||
<!-- R1 -->
|
||||
<g id="node2" class="node">
|
||||
<title>R1</title>
|
||||
<polygon fill="none" stroke="black" points="350.9,-171.01 350.9,-240.01 565.9,-240.01 565.9,-171.01 350.9,-171.01"/>
|
||||
<text text-anchor="middle" x="375.9" y="-224.81" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="350.9,-217.01 400.9,-217.01 "/>
|
||||
<text text-anchor="middle" x="375.9" y="-201.81" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
|
||||
<polyline fill="none" stroke="black" points="350.9,-194.01 400.9,-194.01 "/>
|
||||
<text text-anchor="middle" x="375.9" y="-178.81" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
<polyline fill="none" stroke="black" points="400.9,-171.01 400.9,-240.01 "/>
|
||||
<text text-anchor="middle" x="483.4" y="-216.81" font-family="DejaVu Sans Mono, Book" font-size="14.00">R1 </text>
|
||||
<text text-anchor="middle" x="483.4" y="-201.81" font-family="DejaVu Sans Mono, Book" font-size="14.00"> 192.168.100.1/32 </text>
|
||||
<text text-anchor="middle" x="483.4" y="-186.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="M91.5,-223.5C91.5,-223.5 350.4,-228.51 350.4,-228.51"/>
|
||||
</g>
|
||||
<!-- PC--R1 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>PC:data1--R1:data</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M91.5,-200.5C91.5,-200.5 350.4,-205.51 350.4,-205.51"/>
|
||||
<text text-anchor="middle" x="161.95" y="-206.81" font-family="DejaVu Serif, Book" font-size="14.00">192.168.10.0/24</text>
|
||||
<text text-anchor="middle" x="332.11" y="-209.91" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
<text text-anchor="middle" x="109.79" y="-188.7" font-family="DejaVu Serif, Book" font-size="14.00">.2</text>
|
||||
</g>
|
||||
<!-- R2 -->
|
||||
<g id="node3" class="node">
|
||||
<title>R2</title>
|
||||
<polygon fill="none" stroke="black" points="350.9,-1 350.9,-70 565.9,-70 565.9,-1 350.9,-1"/>
|
||||
<text text-anchor="middle" x="375.9" y="-54.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
<polyline fill="none" stroke="black" points="350.9,-47 400.9,-47 "/>
|
||||
<text text-anchor="middle" x="375.9" y="-31.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="350.9,-24 400.9,-24 "/>
|
||||
<text text-anchor="middle" x="375.9" y="-8.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
|
||||
<polyline fill="none" stroke="black" points="400.9,-1 400.9,-70 "/>
|
||||
<text text-anchor="middle" x="483.4" y="-46.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">R2 </text>
|
||||
<text text-anchor="middle" x="483.4" y="-31.8" font-family="DejaVu Sans Mono, Book" font-size="14.00"> 192.168.200.1/32 </text>
|
||||
<text text-anchor="middle" x="483.4" y="-16.8" 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="M91.5,-40.5C91.5,-40.5 350.4,-35.5 350.4,-35.5"/>
|
||||
</g>
|
||||
<!-- PC--R2 -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>PC:data2--R2:data</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M91.5,-17.5C91.5,-17.5 350.4,-12.5 350.4,-12.5"/>
|
||||
<text text-anchor="middle" x="250.45" y="-3.8" font-family="DejaVu Serif, Book" font-size="14.00">192.168.60.0/24</text>
|
||||
<text text-anchor="middle" x="332.44" y="-17.6" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
<text text-anchor="middle" x="109.46" y="-5" font-family="DejaVu Serif, Book" font-size="14.00">.2</text>
|
||||
</g>
|
||||
<!-- R1--R2 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>R1:link--R2:link</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M375.4,-170.51C375.4,-170.51 375.4,-70.5 375.4,-70.5"/>
|
||||
<text text-anchor="middle" x="316.4" y="-124.3" font-family="DejaVu Serif, Book" font-size="14.00">192.168.50.0/24</text>
|
||||
<text text-anchor="middle" x="383.85" y="-84.92" font-family="DejaVu Serif, Book" font-size="14.00">.2</text>
|
||||
<text text-anchor="middle" x="366.95" y="-148.69" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
@@ -0,0 +1 @@
|
||||
test.adoc
|
||||
Executable
+314
@@ -0,0 +1,314 @@
|
||||
#!/usr/bin/env python3
|
||||
"""RIP Multi-hop
|
||||
|
||||
Verifies RIP functionality across multiple hops with three routers in a line
|
||||
topology (R1 -- R2 -- R3). This test ensures:
|
||||
- RIP routes propagate through multiple hops
|
||||
- R2 (middle router) has two RIP neighbors
|
||||
- End-to-end connectivity works across the RIP network
|
||||
|
||||
Topology:
|
||||
PC:data1 -- R1 -- R2 -- R3 -- PC:data2
|
||||
"""
|
||||
|
||||
import infamy
|
||||
import infamy.route as route
|
||||
from infamy.util import until, parallel
|
||||
|
||||
|
||||
def config_r1(target, data, link):
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": data,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.10.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.50.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": "lo",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.11.1",
|
||||
"prefix-length": 32
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R1"
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ripv2",
|
||||
"name": "default",
|
||||
"rip": {
|
||||
"timers": {
|
||||
"update-interval": 5,
|
||||
"invalid-interval": 15,
|
||||
"flush-interval": 20
|
||||
},
|
||||
"redistribute": {
|
||||
"redistribute": [{
|
||||
"protocol": "connected"
|
||||
}]
|
||||
},
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"interface": link
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def config_r2(target, west, east):
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": west,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.50.2",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": east,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.60.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": "lo",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.22.1",
|
||||
"prefix-length": 32
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R2"
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ripv2",
|
||||
"name": "default",
|
||||
"rip": {
|
||||
"timers": {
|
||||
"update-interval": 5,
|
||||
"invalid-interval": 15,
|
||||
"flush-interval": 20
|
||||
},
|
||||
"redistribute": {
|
||||
"redistribute": [{
|
||||
"protocol": "connected"
|
||||
}]
|
||||
},
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"interface": west
|
||||
}, {
|
||||
"interface": east
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def config_r3(target, link, data):
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.60.2",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": data,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.70.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": "lo",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.33.1",
|
||||
"prefix-length": 32
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R3"
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ripv2",
|
||||
"name": "default",
|
||||
"rip": {
|
||||
"timers": {
|
||||
"update-interval": 5,
|
||||
"invalid-interval": 15,
|
||||
"flush-interval": 20
|
||||
},
|
||||
"redistribute": {
|
||||
"redistribute": [{
|
||||
"protocol": "connected"
|
||||
}]
|
||||
},
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"interface": link
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
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")
|
||||
R3 = env.attach("R3", "mgmt")
|
||||
|
||||
with test.step("Configure routers"):
|
||||
_, R1data = env.ltop.xlate("R1", "data")
|
||||
_, R1link = env.ltop.xlate("R1", "link")
|
||||
_, R2west = env.ltop.xlate("R2", "west")
|
||||
_, R2east = env.ltop.xlate("R2", "east")
|
||||
_, R3link = env.ltop.xlate("R3", "link")
|
||||
_, R3data = env.ltop.xlate("R3", "data")
|
||||
|
||||
parallel(config_r1(R1, R1data, R1link),
|
||||
config_r2(R2, R2west, R2east),
|
||||
config_r3(R3, R3link, R3data))
|
||||
|
||||
with test.step("Wait for RIP routes to be exchanged"):
|
||||
print("Waiting for RIP routes to propagate...")
|
||||
# R1 should learn R2's loopback
|
||||
until(lambda: route.ipv4_route_exist(R1, "192.168.22.1/32", proto="ietf-rip:rip"), attempts=40)
|
||||
# R1 should learn R3's loopback (via R2)
|
||||
until(lambda: route.ipv4_route_exist(R1, "192.168.33.1/32", proto="ietf-rip:rip"), attempts=40)
|
||||
# R2 should learn R1's loopback
|
||||
until(lambda: route.ipv4_route_exist(R2, "192.168.11.1/32", proto="ietf-rip:rip"), attempts=40)
|
||||
# R2 should learn R3's loopback
|
||||
until(lambda: route.ipv4_route_exist(R2, "192.168.33.1/32", proto="ietf-rip:rip"), attempts=40)
|
||||
# R3 should learn R2's loopback
|
||||
until(lambda: route.ipv4_route_exist(R3, "192.168.22.1/32", proto="ietf-rip:rip"), attempts=40)
|
||||
# R3 should learn R1's loopback (via R2)
|
||||
until(lambda: route.ipv4_route_exist(R3, "192.168.11.1/32", proto="ietf-rip:rip"), attempts=40)
|
||||
|
||||
with test.step("Verify R2 has two RIP neighbors"):
|
||||
print("Checking R2 has two RIP neighbors...")
|
||||
# R2 should have neighbors: 192.168.50.1 (R1) and 192.168.60.2 (R3)
|
||||
# Query without predicates to avoid RESTCONF encoding issues
|
||||
routing_data = R2.get_data("/ietf-routing:routing/control-plane-protocols")
|
||||
|
||||
# Navigate to RIP protocol
|
||||
protocols = routing_data.get("routing", {}).get("control-plane-protocols", {}).get("control-plane-protocol", [])
|
||||
if not protocols:
|
||||
raise Exception("No protocols found")
|
||||
|
||||
# Find RIP protocol
|
||||
rip = None
|
||||
for protocol in protocols:
|
||||
if protocol.get("type") == "infix-routing:ripv2" and protocol.get("name") == "default":
|
||||
rip = protocol.get("rip", {})
|
||||
break
|
||||
|
||||
if not rip:
|
||||
raise Exception("RIP protocol not found in control-plane-protocols")
|
||||
|
||||
ipv4_data = rip.get("ipv4", {})
|
||||
neighbors_data = ipv4_data.get("neighbors", {})
|
||||
neighbor_list = neighbors_data.get("neighbor", [])
|
||||
|
||||
assert len(neighbor_list) == 2, f"Expected 2 neighbors, found {len(neighbor_list)}"
|
||||
|
||||
neighbor_ips = [n.get("ipv4-address") for n in neighbor_list]
|
||||
assert "192.168.50.1" in neighbor_ips, "R1 not in neighbor list"
|
||||
assert "192.168.60.2" in neighbor_ips, "R3 not in neighbor list"
|
||||
print(f"R2 has correct neighbors: {neighbor_ips}")
|
||||
|
||||
with test.step("Test end-to-end connectivity PC:data1 to R3 loopback"):
|
||||
_, hport1 = env.ltop.xlate("PC", "data1")
|
||||
with infamy.IsolatedMacVlan(hport1) as ns1:
|
||||
ns1.addip("192.168.10.2")
|
||||
ns1.addroute("192.168.33.1/32", "192.168.10.1")
|
||||
ns1.must_reach("192.168.33.1")
|
||||
|
||||
with test.step("Test end-to-end connectivity PC:data2 to R1 loopback"):
|
||||
_, hport2 = env.ltop.xlate("PC", "data2")
|
||||
with infamy.IsolatedMacVlan(hport2) as ns2:
|
||||
ns2.addip("192.168.70.2")
|
||||
ns2.addroute("192.168.11.1/32", "192.168.70.1")
|
||||
ns2.must_reach("192.168.11.1")
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,41 @@
|
||||
graph "rip-multihop" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+40";
|
||||
size=10
|
||||
|
||||
node [shape=record, fontname="DejaVu Sans Mono, Book"];
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
PC [
|
||||
label="PC | { <mgmt1> mgmt1 | <data1> data1 | \n\n\n\n | <mgmt2> mgmt2 | <mgmt3> mgmt3 | <data2> data2 }",
|
||||
pos="20,54!",
|
||||
requires="controller",
|
||||
];
|
||||
|
||||
R1 [
|
||||
label="{ <mgmt> mgmt | <data> data | <link> link} | R1 \n 192.168.11.1/32 \n(lo)",
|
||||
pos="100,70!",
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
R2 [
|
||||
label="{ <west> west | <mgmt> mgmt | <east> east } | R2 \n 192.168.22.1/32 \n(lo)",
|
||||
pos="100,50!",
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
R3 [
|
||||
label="{ <link> link | <mgmt> mgmt | <data> data } | R3 \n 192.168.33.1/32 \n(lo)",
|
||||
pos="100,30!",
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
PC:mgmt1 -- R1:mgmt [requires="mgmt", color="lightgray"]
|
||||
PC:mgmt2 -- R2:mgmt [requires="mgmt", color="lightgray"]
|
||||
PC:mgmt3 -- R3:mgmt [requires="mgmt", color="lightgray"]
|
||||
PC:data1 -- R1:data [label="192.168.10.0/24", headlabel=".1", taillabel=".2", labeldistance=2, fontcolor="black", color="black"]
|
||||
R1:link -- R2:west [label="192.168.50.0/24", headlabel=".2", taillabel=".1", labeldistance=2, fontcolor="black", color="black"]
|
||||
R2:east -- R3:link [label="192.168.60.0/24", headlabel=".2", taillabel=".1", labeldistance=2, fontcolor="black", color="black"]
|
||||
R3:data -- PC:data2 [label="192.168.70.0/24", headlabel=".2", taillabel=".1", labeldistance=2, fontcolor="black", color="black"]
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?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: rip-multihop Pages: 1 -->
|
||||
<svg width="720pt" height="360pt"
|
||||
viewBox="0.00 0.00 720.00 359.57" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(0.86 0.86) rotate(0) translate(4 414.03)">
|
||||
<title>rip-multihop</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-414.03 833.07,-414.03 833.07,4 -4,4"/>
|
||||
<!-- PC -->
|
||||
<g id="node1" class="node">
|
||||
<title>PC</title>
|
||||
<polygon fill="none" stroke="black" points="0,-145.52 0,-332.52 91,-332.52 91,-145.52 0,-145.52"/>
|
||||
<text text-anchor="middle" x="16.5" y="-235.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">PC</text>
|
||||
<polyline fill="none" stroke="black" points="33,-145.52 33,-332.52 "/>
|
||||
<text text-anchor="middle" x="62" y="-317.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt1</text>
|
||||
<polyline fill="none" stroke="black" points="33,-309.52 91,-309.52 "/>
|
||||
<text text-anchor="middle" x="62" y="-294.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">data1</text>
|
||||
<polyline fill="none" stroke="black" points="33,-286.52 91,-286.52 "/>
|
||||
<polyline fill="none" stroke="black" points="33,-214.52 91,-214.52 "/>
|
||||
<text text-anchor="middle" x="62" y="-199.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt2</text>
|
||||
<polyline fill="none" stroke="black" points="33,-191.52 91,-191.52 "/>
|
||||
<text text-anchor="middle" x="62" y="-176.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt3</text>
|
||||
<polyline fill="none" stroke="black" points="33,-168.52 91,-168.52 "/>
|
||||
<text text-anchor="middle" x="62" y="-153.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">data2</text>
|
||||
</g>
|
||||
<!-- R1 -->
|
||||
<g id="node2" class="node">
|
||||
<title>R1</title>
|
||||
<polygon fill="none" stroke="black" points="622.07,-340.53 622.07,-409.53 829.07,-409.53 829.07,-340.53 622.07,-340.53"/>
|
||||
<text text-anchor="middle" x="647.07" y="-394.33" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="622.07,-386.53 672.07,-386.53 "/>
|
||||
<text text-anchor="middle" x="647.07" y="-371.33" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
|
||||
<polyline fill="none" stroke="black" points="622.07,-363.53 672.07,-363.53 "/>
|
||||
<text text-anchor="middle" x="647.07" y="-348.33" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
<polyline fill="none" stroke="black" points="672.07,-340.53 672.07,-409.53 "/>
|
||||
<text text-anchor="middle" x="750.57" y="-386.33" font-family="DejaVu Sans Mono, Book" font-size="14.00">R1 </text>
|
||||
<text text-anchor="middle" x="750.57" y="-371.33" font-family="DejaVu Sans Mono, Book" font-size="14.00"> 192.168.11.1/32 </text>
|
||||
<text text-anchor="middle" x="750.57" y="-356.33" 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="M91.5,-321.02C91.5,-321.02 621.57,-398.03 621.57,-398.03"/>
|
||||
</g>
|
||||
<!-- PC--R1 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>PC:data1--R1:data</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M91.5,-298.02C91.5,-298.02 621.57,-375.03 621.57,-375.03"/>
|
||||
<text text-anchor="middle" x="297.53" y="-340.33" font-family="DejaVu Serif, Book" font-size="14.00">192.168.10.0/24</text>
|
||||
<text text-anchor="middle" x="602.41" y="-377.09" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
<text text-anchor="middle" x="110.65" y="-288.56" font-family="DejaVu Serif, Book" font-size="14.00">.2</text>
|
||||
</g>
|
||||
<!-- R2 -->
|
||||
<g id="node3" class="node">
|
||||
<title>R2</title>
|
||||
<polygon fill="none" stroke="black" points="622.07,-170.52 622.07,-239.52 829.07,-239.52 829.07,-170.52 622.07,-170.52"/>
|
||||
<text text-anchor="middle" x="647.07" y="-224.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">west</text>
|
||||
<polyline fill="none" stroke="black" points="622.07,-216.52 672.07,-216.52 "/>
|
||||
<text text-anchor="middle" x="647.07" y="-201.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="622.07,-193.52 672.07,-193.52 "/>
|
||||
<text text-anchor="middle" x="647.07" y="-178.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">east</text>
|
||||
<polyline fill="none" stroke="black" points="672.07,-170.52 672.07,-239.52 "/>
|
||||
<text text-anchor="middle" x="750.57" y="-216.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">R2 </text>
|
||||
<text text-anchor="middle" x="750.57" y="-201.32" font-family="DejaVu Sans Mono, Book" font-size="14.00"> 192.168.22.1/32 </text>
|
||||
<text text-anchor="middle" x="750.57" y="-186.32" 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="M91.5,-203.02C91.5,-203.02 621.57,-205.02 621.57,-205.02"/>
|
||||
</g>
|
||||
<!-- R3 -->
|
||||
<g id="node4" class="node">
|
||||
<title>R3</title>
|
||||
<polygon fill="none" stroke="black" points="622.07,-0.5 622.07,-69.5 829.07,-69.5 829.07,-0.5 622.07,-0.5"/>
|
||||
<text text-anchor="middle" x="647.07" y="-54.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
<polyline fill="none" stroke="black" points="622.07,-46.5 672.07,-46.5 "/>
|
||||
<text text-anchor="middle" x="647.07" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="622.07,-23.5 672.07,-23.5 "/>
|
||||
<text text-anchor="middle" x="647.07" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
|
||||
<polyline fill="none" stroke="black" points="672.07,-0.5 672.07,-69.5 "/>
|
||||
<text text-anchor="middle" x="750.57" y="-46.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">R3 </text>
|
||||
<text text-anchor="middle" x="750.57" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00"> 192.168.33.1/32 </text>
|
||||
<text text-anchor="middle" x="750.57" y="-16.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">(lo)</text>
|
||||
</g>
|
||||
<!-- PC--R3 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>PC:mgmt3--R3:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M91.5,-180.02C91.5,-180.02 621.57,-35 621.57,-35"/>
|
||||
</g>
|
||||
<!-- R1--R2 -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>R1:link--R2:west</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M646.57,-340.03C646.57,-340.03 646.57,-240.02 646.57,-240.02"/>
|
||||
<text text-anchor="middle" x="587.57" y="-293.83" font-family="DejaVu Serif, Book" font-size="14.00">192.168.50.0/24</text>
|
||||
<text text-anchor="middle" x="655.02" y="-254.44" font-family="DejaVu Serif, Book" font-size="14.00">.2</text>
|
||||
<text text-anchor="middle" x="638.12" y="-318.21" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
</g>
|
||||
<!-- R2--R3 -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>R2:east--R3:link</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M646.57,-170.02C646.57,-170.02 646.57,-70 646.57,-70"/>
|
||||
<text text-anchor="middle" x="587.57" y="-123.81" font-family="DejaVu Serif, Book" font-size="14.00">192.168.60.0/24</text>
|
||||
<text text-anchor="middle" x="655.02" y="-84.43" font-family="DejaVu Serif, Book" font-size="14.00">.2</text>
|
||||
<text text-anchor="middle" x="638.12" y="-148.19" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
</g>
|
||||
<!-- R3--PC -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>R3:data--PC:data2</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M621.57,-12C621.57,-12 91.5,-157.02 91.5,-157.02"/>
|
||||
<text text-anchor="middle" x="297.53" y="-88.31" font-family="DejaVu Serif, Book" font-size="14.00">192.168.70.0/24</text>
|
||||
<text text-anchor="middle" x="106.75" y="-140.38" font-family="DejaVu Serif, Book" font-size="14.00">.2</text>
|
||||
<text text-anchor="middle" x="606.31" y="-21.24" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.9 KiB |
@@ -0,0 +1 @@
|
||||
test.adoc
|
||||
@@ -0,0 +1,29 @@
|
||||
=== RIP Passive Interface
|
||||
|
||||
ifdef::topdoc[:imagesdir: {topdoc}../../test/case/routing/rip_passive_interface]
|
||||
|
||||
==== Description
|
||||
|
||||
Verifies RIP passive interface functionality. A passive interface means that
|
||||
RIP will include the interface's network in routing updates but will not send
|
||||
or receive RIP updates on that interface.
|
||||
|
||||
R1 has two RIP-enabled interfaces:
|
||||
- data: Passive interface (192.168.10.0/24 advertised but no updates sent/received)
|
||||
- link: Active interface (RIP updates exchanged with R2)
|
||||
|
||||
R2 should learn about 192.168.10.0/24 from R1 via the link interface, even
|
||||
though the data interface is passive.
|
||||
|
||||
==== Topology
|
||||
|
||||
image::topology.svg[RIP Passive Interface topology, align=center, scaledwidth=75%]
|
||||
|
||||
==== Sequence
|
||||
|
||||
. Set up topology and attach to target DUTs
|
||||
. Configure targets
|
||||
. Wait for RIP to exchange routes
|
||||
. Verify connectivity to passive interface network
|
||||
|
||||
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env python3
|
||||
"""RIP Passive Interface
|
||||
|
||||
Verifies RIP passive interface functionality. A passive interface means that
|
||||
RIP will include the interface's network in routing updates but will not send
|
||||
or receive RIP updates on that interface.
|
||||
|
||||
R1 has two RIP-enabled interfaces:
|
||||
- data: Passive interface (192.168.10.0/24 advertised but no updates sent/received)
|
||||
- link: Active interface (RIP updates exchanged with R2)
|
||||
|
||||
R2 should learn about 192.168.10.0/24 from R1 via the link interface, even
|
||||
though the data interface is passive.
|
||||
|
||||
"""
|
||||
|
||||
import infamy
|
||||
import infamy.route as route
|
||||
from infamy.util import until, parallel
|
||||
|
||||
|
||||
def config_target1(target, data, link):
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": data,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.10.1",
|
||||
"prefix-length": 24
|
||||
}]}
|
||||
}, {
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.50.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R1"
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ripv2",
|
||||
"name": "default",
|
||||
"rip": {
|
||||
"timers": {
|
||||
"update-interval": 5,
|
||||
"invalid-interval": 15,
|
||||
"flush-interval": 20
|
||||
},
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"interface": data,
|
||||
"passive": None
|
||||
}, {
|
||||
"interface": link
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def config_target2(target, link):
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.50.2",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R2"
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ripv2",
|
||||
"name": "default",
|
||||
"rip": {
|
||||
"timers": {
|
||||
"update-interval": 5,
|
||||
"invalid-interval": 15,
|
||||
"flush-interval": 20
|
||||
},
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"interface": link
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
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"):
|
||||
_, R1data = env.ltop.xlate("R1", "data")
|
||||
_, R2link = env.ltop.xlate("R2", "link")
|
||||
_, R1link = env.ltop.xlate("R1", "link")
|
||||
|
||||
parallel(config_target1(R1, R1data, R1link),
|
||||
config_target2(R2, R2link))
|
||||
|
||||
with test.step("Wait for RIP to exchange routes"):
|
||||
print("Waiting for RIP routes to propagate...")
|
||||
# R2 should learn about R1's passive interface network (192.168.10.0/24)
|
||||
# even though it's passive, R1 should still advertise it
|
||||
until(lambda: route.ipv4_route_exist(R2, "192.168.10.0/24", proto="ietf-rip:rip"), attempts=40)
|
||||
|
||||
with test.step("Verify connectivity to passive interface network"):
|
||||
# Test that we can reach the passive interface from PC
|
||||
_, hport0 = env.ltop.xlate("PC", "data")
|
||||
with infamy.IsolatedMacVlan(hport0) as ns0:
|
||||
ns0.addip("192.168.10.2")
|
||||
# No need for route since we're on the same network
|
||||
ns0.must_reach("192.168.10.1")
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,33 @@
|
||||
graph "rip-passive" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+30";
|
||||
size=10
|
||||
|
||||
node [shape=record, fontname="DejaVu Sans Mono, Book"];
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
PC [
|
||||
label="PC | { <mgmt1> mgmt1 | <data> data | <mgmt2> mgmt2 }",
|
||||
pos="20,50!",
|
||||
requires="controller",
|
||||
];
|
||||
|
||||
R1 [
|
||||
label="{ <mgmt> mgmt | <data> data | <link> link} | R1",
|
||||
pos="160,60!",
|
||||
|
||||
requires="infix",
|
||||
];
|
||||
R2 [
|
||||
label="{ <link> link | <mgmt> mgmt } | R2",
|
||||
pos="160,30!",
|
||||
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
PC:mgmt1 -- R1:mgmt [requires="mgmt", color="lightgray"]
|
||||
PC:mgmt2 -- R2:mgmt [requires="mgmt", color="lightgray"]
|
||||
PC:data -- R1:data [color="black", label="192.168.10.0/24", headlabel=".1", taillabel=".2", labeldistance=2, fontcolor="black"]
|
||||
R1:link -- R2:link [taillabel="192.168.50.0/24", headlabel=".2", taillabel=".1", labeldistance=2, fontcolor="black", color="black"]
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?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: rip-passive Pages: 1 -->
|
||||
<svg width="718pt" height="200pt"
|
||||
viewBox="0.00 0.00 718.06 200.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 196.01)">
|
||||
<title>rip-passive</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-196.01 714.06,-196.01 714.06,4 -4,4"/>
|
||||
<!-- PC -->
|
||||
<g id="node1" class="node">
|
||||
<title>PC</title>
|
||||
<polygon fill="none" stroke="black" points="0,-78.01 0,-147.01 91,-147.01 91,-78.01 0,-78.01"/>
|
||||
<text text-anchor="middle" x="16.5" y="-108.81" font-family="DejaVu Sans Mono, Book" font-size="14.00">PC</text>
|
||||
<polyline fill="none" stroke="black" points="33,-78.01 33,-147.01 "/>
|
||||
<text text-anchor="middle" x="62" y="-131.81" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt1</text>
|
||||
<polyline fill="none" stroke="black" points="33,-124.01 91,-124.01 "/>
|
||||
<text text-anchor="middle" x="62" y="-108.81" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
|
||||
<polyline fill="none" stroke="black" points="33,-101.01 91,-101.01 "/>
|
||||
<text text-anchor="middle" x="62" y="-85.81" 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="627.06,-122.51 627.06,-191.51 710.06,-191.51 710.06,-122.51 627.06,-122.51"/>
|
||||
<text text-anchor="middle" x="652.06" y="-176.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="627.06,-168.51 677.06,-168.51 "/>
|
||||
<text text-anchor="middle" x="652.06" y="-153.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
|
||||
<polyline fill="none" stroke="black" points="627.06,-145.51 677.06,-145.51 "/>
|
||||
<text text-anchor="middle" x="652.06" y="-130.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
<polyline fill="none" stroke="black" points="677.06,-122.51 677.06,-191.51 "/>
|
||||
<text text-anchor="middle" x="693.56" y="-153.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">R1</text>
|
||||
</g>
|
||||
<!-- PC--R1 -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>PC:mgmt1--R1:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M91.5,-135.51C91.5,-135.51 626.56,-180.01 626.56,-180.01"/>
|
||||
</g>
|
||||
<!-- PC--R1 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>PC:data--R1:data</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M91.5,-112.51C91.5,-112.51 626.56,-157.01 626.56,-157.01"/>
|
||||
<text text-anchor="middle" x="300.03" y="-138.56" font-family="DejaVu Serif, Book" font-size="14.00">192.168.10.0/24</text>
|
||||
<text text-anchor="middle" x="607.8" y="-160.23" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
<text text-anchor="middle" x="110.26" y="-101.89" font-family="DejaVu Serif, Book" font-size="14.00">.2</text>
|
||||
</g>
|
||||
<!-- R2 -->
|
||||
<g id="node3" class="node">
|
||||
<title>R2</title>
|
||||
<polygon fill="none" stroke="black" points="627.06,-0.5 627.06,-46.5 710.06,-46.5 710.06,-0.5 627.06,-0.5"/>
|
||||
<text text-anchor="middle" x="652.06" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
<polyline fill="none" stroke="black" points="627.06,-23.5 677.06,-23.5 "/>
|
||||
<text text-anchor="middle" x="652.06" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="677.06,-0.5 677.06,-46.5 "/>
|
||||
<text text-anchor="middle" x="693.56" y="-19.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">R2</text>
|
||||
</g>
|
||||
<!-- PC--R2 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>PC:mgmt2--R2:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M91.5,-89.51C91.5,-89.51 626.56,-11.5 626.56,-11.5"/>
|
||||
</g>
|
||||
<!-- R1--R2 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>R1:link--R2:link</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M651.56,-122.01C651.56,-122.01 651.56,-46.5 651.56,-46.5"/>
|
||||
<text text-anchor="middle" x="660.01" y="-60.93" font-family="DejaVu Serif, Book" font-size="14.00">.2</text>
|
||||
<text text-anchor="middle" x="643.11" y="-100.19" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
@@ -0,0 +1 @@
|
||||
test.adoc
|
||||
@@ -0,0 +1,37 @@
|
||||
=== RIP Redistribution
|
||||
|
||||
ifdef::topdoc[:imagesdir: {topdoc}../../test/case/routing/rip_redistribute]
|
||||
|
||||
==== Description
|
||||
|
||||
Verifies that RIP can redistribute routes from other protocols.
|
||||
|
||||
Topology:
|
||||
- R1: Gateway router running both RIP and OSPF
|
||||
- RIP interface to R2
|
||||
- OSPF interface to R3
|
||||
- Redistributes OSPF routes into RIP
|
||||
- Redistributes RIP routes into OSPF
|
||||
|
||||
- R2: RIP-only router with loopback 192.168.200.1/32
|
||||
|
||||
- R3: OSPF-only router with loopback 192.168.100.1/32
|
||||
|
||||
Expected behavior:
|
||||
- R2 (RIP) should learn R3's OSPF loopback (192.168.100.1/32) via RIP redistribution
|
||||
- R3 (OSPF) should learn R2's RIP loopback (192.168.200.1/32) via OSPF redistribution
|
||||
|
||||
==== Topology
|
||||
|
||||
image::topology.svg[RIP Redistribution topology, align=center, scaledwidth=75%]
|
||||
|
||||
==== Sequence
|
||||
|
||||
. Set up topology and attach to target DUTs
|
||||
. Configure routers
|
||||
. Wait for OSPF to converge on R1-R3 link
|
||||
. Wait for RIP to converge on R1-R2 link
|
||||
. Verify R2 (RIP) learns R3's OSPF routes via redistribution
|
||||
. Verify R3 (OSPF) learns R2's RIP routes via redistribution
|
||||
|
||||
|
||||
Executable
+286
@@ -0,0 +1,286 @@
|
||||
#!/usr/bin/env python3
|
||||
"""RIP Redistribution
|
||||
|
||||
Verifies that RIP can redistribute routes from other protocols.
|
||||
|
||||
Topology:
|
||||
- R1: Gateway router running both RIP and OSPF
|
||||
- RIP interface to R2
|
||||
- OSPF interface to R3
|
||||
- Redistributes OSPF routes into RIP
|
||||
- Redistributes RIP routes into OSPF
|
||||
|
||||
- R2: RIP-only router with loopback 192.168.200.1/32
|
||||
|
||||
- R3: OSPF-only router with loopback 192.168.100.1/32
|
||||
|
||||
Expected behavior:
|
||||
- R2 (RIP) should learn R3's OSPF loopback (192.168.100.1/32) via RIP redistribution
|
||||
- R3 (OSPF) should learn R2's RIP loopback (192.168.200.1/32) via OSPF redistribution
|
||||
|
||||
"""
|
||||
|
||||
import infamy
|
||||
import infamy.route as route
|
||||
from infamy.util import until, parallel
|
||||
|
||||
|
||||
def config_r1_gateway(target, rip_link, ospf_link):
|
||||
"""Configure R1 as gateway running both RIP and OSPF"""
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": rip_link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.50.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": ospf_link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.60.1",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R1"
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ripv2",
|
||||
"name": "default",
|
||||
"rip": {
|
||||
"timers": {
|
||||
"update-interval": 5,
|
||||
"invalid-interval": 15,
|
||||
"flush-interval": 20
|
||||
},
|
||||
"redistribute": {
|
||||
"redistribute": [{
|
||||
"protocol": "ospf"
|
||||
}, {
|
||||
"protocol": "connected"
|
||||
}]
|
||||
},
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"interface": rip_link
|
||||
}]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"type": "infix-routing:ospfv2",
|
||||
"name": "default",
|
||||
"ospf": {
|
||||
"redistribute": {
|
||||
"redistribute": [{
|
||||
"protocol": "rip"
|
||||
}, {
|
||||
"protocol": "connected"
|
||||
}]
|
||||
},
|
||||
"areas": {
|
||||
"area": [{
|
||||
"area-id": "0.0.0.0",
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"enabled": True,
|
||||
"name": ospf_link,
|
||||
"hello-interval": 1,
|
||||
"dead-interval": 3
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def config_r2_rip(target, link):
|
||||
"""Configure R2 with RIP only"""
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.50.2",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": "lo",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.200.1",
|
||||
"prefix-length": 32
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R2"
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ripv2",
|
||||
"name": "default",
|
||||
"rip": {
|
||||
"timers": {
|
||||
"update-interval": 5,
|
||||
"invalid-interval": 15,
|
||||
"flush-interval": 20
|
||||
},
|
||||
"redistribute": {
|
||||
"redistribute": [{
|
||||
"protocol": "connected"
|
||||
}]
|
||||
},
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"interface": link
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def config_r3_ospf(target, link):
|
||||
"""Configure R3 with OSPF only"""
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": link,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"forwarding": True,
|
||||
"address": [{
|
||||
"ip": "192.168.60.2",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": "lo",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.100.1",
|
||||
"prefix-length": 32
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": "R3"
|
||||
}
|
||||
},
|
||||
"ietf-routing": {
|
||||
"routing": {
|
||||
"control-plane-protocols": {
|
||||
"control-plane-protocol": [{
|
||||
"type": "infix-routing:ospfv2",
|
||||
"name": "default",
|
||||
"ospf": {
|
||||
"redistribute": {
|
||||
"redistribute": [{
|
||||
"protocol": "connected"
|
||||
}]
|
||||
},
|
||||
"areas": {
|
||||
"area": [{
|
||||
"area-id": "0.0.0.0",
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"enabled": True,
|
||||
"name": link,
|
||||
"hello-interval": 1,
|
||||
"dead-interval": 3
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
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")
|
||||
R3 = env.attach("R3", "mgmt")
|
||||
|
||||
with test.step("Configure routers"):
|
||||
_, R1rip = env.ltop.xlate("R1", "rip")
|
||||
_, R1ospf = env.ltop.xlate("R1", "ospf")
|
||||
_, R2link = env.ltop.xlate("R2", "link")
|
||||
_, R3link = env.ltop.xlate("R3", "link")
|
||||
|
||||
parallel(config_r1_gateway(R1, R1rip, R1ospf),
|
||||
config_r2_rip(R2, R2link),
|
||||
config_r3_ospf(R3, R3link))
|
||||
|
||||
with test.step("Wait for OSPF to converge on R1-R3 link"):
|
||||
print("Waiting for OSPF convergence...")
|
||||
# R1 should learn R3's loopback via OSPF
|
||||
until(lambda: route.ipv4_route_exist(R1, "192.168.100.1/32", proto="ietf-ospf:ospfv2"), attempts=40)
|
||||
# R3 should learn R1's OSPF link via OSPF
|
||||
until(lambda: route.ipv4_route_exist(R3, "192.168.60.0/24", proto="ietf-ospf:ospfv2"), attempts=40)
|
||||
|
||||
with test.step("Wait for RIP to converge on R1-R2 link"):
|
||||
print("Waiting for RIP convergence...")
|
||||
# R1 should learn R2's loopback via RIP
|
||||
until(lambda: route.ipv4_route_exist(R1, "192.168.200.1/32", proto="ietf-rip:rip"), attempts=40)
|
||||
# R2 should learn R1's OSPF link (192.168.60.0/24) via RIP (redistributed from connected)
|
||||
until(lambda: route.ipv4_route_exist(R2, "192.168.60.0/24", proto="ietf-rip:rip"), attempts=40)
|
||||
|
||||
with test.step("Verify R2 (RIP) learns R3's OSPF routes via redistribution"):
|
||||
print("Checking OSPF->RIP redistribution...")
|
||||
# R2 should learn R3's loopback (OSPF route) via RIP redistribution on R1
|
||||
until(lambda: route.ipv4_route_exist(R2, "192.168.100.1/32", proto="ietf-rip:rip"), attempts=40)
|
||||
|
||||
with test.step("Verify R3 (OSPF) learns R2's RIP routes via redistribution"):
|
||||
print("Checking RIP->OSPF redistribution...")
|
||||
# R3 should learn R2's loopback (RIP route) via OSPF redistribution on R1
|
||||
until(lambda: route.ipv4_route_exist(R3, "192.168.200.1/32", proto="ietf-ospf:ospfv2"), attempts=40)
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,39 @@
|
||||
graph "rip-redistribute" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+40";
|
||||
size=10
|
||||
|
||||
node [shape=record, fontname="DejaVu Sans Mono, Book"];
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
PC [
|
||||
label="PC | { <mgmt3> mgmt3 | \n\n | <mgmt1> mgmt1 | \n\n | <mgmt2> mgmt2 }",
|
||||
pos="20,50!",
|
||||
requires="controller",
|
||||
];
|
||||
|
||||
R3 [
|
||||
label="{ <mgmt> mgmt | <link> link } | R3 (OSPF) \n 192.168.100.1/32 \n(lo)",
|
||||
pos="100,100!",
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
R1 [
|
||||
label="{ <ospf> ospf | <mgmt> mgmt | <rip> rip } | R1 (ASBR)",
|
||||
pos="91,50!",
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
R2 [
|
||||
label="{ <link> link | <mgmt> mgmt } | R2 (RIP) \n 192.168.200.1/32 \n(lo)",
|
||||
pos="100,10!",
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
PC:mgmt3 -- R3:mgmt [requires="mgmt", color="lightgray"]
|
||||
PC:mgmt1 -- R1:mgmt [requires="mgmt", color="lightgray"]
|
||||
PC:mgmt2 -- R2:mgmt [requires="mgmt", color="lightgray"]
|
||||
R3:link -- R1:ospf [label="192.168.60.0/24", headlabel=".1", taillabel=".2", labeldistance=2, fontcolor="black", color="blue"]
|
||||
R1:rip -- R2:link [label="192.168.50.0/24", headlabel=".2", taillabel=".1", labeldistance=2, fontcolor="black", color="black"]
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?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: rip-redistribute Pages: 1 -->
|
||||
<svg width="485pt" height="427pt"
|
||||
viewBox="0.00 0.00 485.03 426.54" 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 422.54)">
|
||||
<title>rip-redistribute</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-422.54 481.03,-422.54 481.03,4 -4,4"/>
|
||||
<!-- PC -->
|
||||
<g id="node1" class="node">
|
||||
<title>PC</title>
|
||||
<polygon fill="none" stroke="black" points="0,-114.52 0,-263.52 91,-263.52 91,-114.52 0,-114.52"/>
|
||||
<text text-anchor="middle" x="16.5" y="-185.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">PC</text>
|
||||
<polyline fill="none" stroke="black" points="33,-114.52 33,-263.52 "/>
|
||||
<text text-anchor="middle" x="62" y="-248.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt3</text>
|
||||
<polyline fill="none" stroke="black" points="33,-240.52 91,-240.52 "/>
|
||||
<polyline fill="none" stroke="black" points="33,-200.52 91,-200.52 "/>
|
||||
<text text-anchor="middle" x="62" y="-185.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt1</text>
|
||||
<polyline fill="none" stroke="black" points="33,-177.52 91,-177.52 "/>
|
||||
<polyline fill="none" stroke="black" points="33,-137.52 91,-137.52 "/>
|
||||
<text text-anchor="middle" x="62" y="-122.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt2</text>
|
||||
</g>
|
||||
<!-- R3 -->
|
||||
<g id="node2" class="node">
|
||||
<title>R3</title>
|
||||
<polygon fill="none" stroke="black" points="262.03,-365.04 262.03,-418.04 477.03,-418.04 477.03,-365.04 262.03,-365.04"/>
|
||||
<text text-anchor="middle" x="287.03" y="-401.34" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="262.03,-392.04 312.03,-392.04 "/>
|
||||
<text text-anchor="middle" x="287.03" y="-374.84" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
<polyline fill="none" stroke="black" points="312.03,-365.04 312.03,-418.04 "/>
|
||||
<text text-anchor="middle" x="394.53" y="-402.84" font-family="DejaVu Sans Mono, Book" font-size="14.00">R3 (OSPF) </text>
|
||||
<text text-anchor="middle" x="394.53" y="-387.84" font-family="DejaVu Sans Mono, Book" font-size="14.00"> 192.168.100.1/32 </text>
|
||||
<text text-anchor="middle" x="394.53" y="-372.84" font-family="DejaVu Sans Mono, Book" font-size="14.00">(lo)</text>
|
||||
</g>
|
||||
<!-- PC--R3 -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>PC:mgmt3--R3:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M91.5,-252.02C91.5,-252.02 261.53,-405.54 261.53,-405.54"/>
|
||||
</g>
|
||||
<!-- R1 -->
|
||||
<g id="node3" class="node">
|
||||
<title>R1</title>
|
||||
<polygon fill="none" stroke="black" points="262.58,-154.52 262.58,-223.52 403.58,-223.52 403.58,-154.52 262.58,-154.52"/>
|
||||
<text text-anchor="middle" x="287.58" y="-208.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">ospf</text>
|
||||
<polyline fill="none" stroke="black" points="262.58,-200.52 312.58,-200.52 "/>
|
||||
<text text-anchor="middle" x="287.58" y="-185.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="262.58,-177.52 312.58,-177.52 "/>
|
||||
<text text-anchor="middle" x="287.58" y="-162.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">rip</text>
|
||||
<polyline fill="none" stroke="black" points="312.58,-154.52 312.58,-223.52 "/>
|
||||
<text text-anchor="middle" x="358.08" y="-185.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">R1 (ASBR)</text>
|
||||
</g>
|
||||
<!-- PC--R1 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>PC:mgmt1--R1:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M91.5,-189.02C91.5,-189.02 262.08,-189.02 262.08,-189.02"/>
|
||||
</g>
|
||||
<!-- R2 -->
|
||||
<g id="node4" class="node">
|
||||
<title>R2</title>
|
||||
<polygon fill="none" stroke="black" points="262.03,-0.5 262.03,-53.5 477.03,-53.5 477.03,-0.5 262.03,-0.5"/>
|
||||
<text text-anchor="middle" x="287.03" y="-36.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
|
||||
<polyline fill="none" stroke="black" points="262.03,-27.5 312.03,-27.5 "/>
|
||||
<text text-anchor="middle" x="287.03" y="-10.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="312.03,-0.5 312.03,-53.5 "/>
|
||||
<text text-anchor="middle" x="394.53" y="-38.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">R2 (RIP) </text>
|
||||
<text text-anchor="middle" x="394.53" y="-23.3" font-family="DejaVu Sans Mono, Book" font-size="14.00"> 192.168.200.1/32 </text>
|
||||
<text text-anchor="middle" x="394.53" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">(lo)</text>
|
||||
</g>
|
||||
<!-- PC--R2 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>PC:mgmt2--R2:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M91.5,-126.02C91.5,-126.02 261.53,-14 261.53,-14"/>
|
||||
</g>
|
||||
<!-- R3--R1 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>R3:link--R1:ospf</title>
|
||||
<path fill="none" stroke="blue" stroke-width="2" d="M286.53,-364.54C286.53,-364.54 287.08,-224.02 287.08,-224.02"/>
|
||||
<text text-anchor="middle" x="227.81" y="-298.08" font-family="DejaVu Serif, Book" font-size="14.00">192.168.60.0/24</text>
|
||||
<text text-anchor="middle" x="295.46" y="-238.48" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
<text text-anchor="middle" x="278.15" y="-342.68" font-family="DejaVu Serif, Book" font-size="14.00">.2</text>
|
||||
</g>
|
||||
<!-- R1--R2 -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>R1:rip--R2:link</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M287.08,-154.02C287.08,-154.02 286.53,-54 286.53,-54"/>
|
||||
<text text-anchor="middle" x="227.81" y="-107.81" font-family="DejaVu Serif, Book" font-size="14.00">192.168.50.0/24</text>
|
||||
<text text-anchor="middle" x="295.08" y="-68.38" font-family="DejaVu Serif, Book" font-size="14.00">.2</text>
|
||||
<text text-anchor="middle" x="278.53" y="-132.24" font-family="DejaVu Serif, Book" font-size="14.00">.1</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.9 KiB |
Reference in New Issue
Block a user