Files

239 lines
9.0 KiB
Python
Executable File

#!/usr/bin/env python3
# 192.168.100.1/32 (lo)
# |
# +--------------+ +-------------+
# | |192.168.50.0/24 | |
# | R1 .1 +----------------+ .2 R2 |-192.168.200.1/32 (lo)
# | .1 | | .1 |
# +--+------+----+ +---+-----+---+
# | | |
# MGMT | | <-192.168.10.0/24 |MGMT
# | | |
# | | |
# +-+------+-------------------------+-----+--+
# | .2 |
# | |
# | |
# +-------------------------------------------+
"""
Static routing
Verify that it is possible to add static routes, both IPv4 and IPv6, and
that data forwarding works as expected via an intermediate device.
"""
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
}]},
"ipv6": {
"forwarding": True,
"address": [{
"ip": "2001:db8:3c4d:10::1",
"prefix-length": 64
}]
}
},
{
"name": link,
"enabled": True,
"ipv4": {
"forwarding": True,
"address": [{
"ip": "192.168.50.1",
"prefix-length": 24
}]
},
"ipv6": {
"forwarding": True,
"address": [{
"ip": "2001:db8:3c4d:50::1",
"prefix-length": 64
}]
}
},
{
"name": "lo",
"enabled": True,
"ipv4": {
"address": [{
"ip": "192.168.100.1",
"prefix-length": 32
}]
},
"ipv6": {
"address": [{
"ip": "2001:db8:3c4d:100::1",
"prefix-length": 128
}]
}
}
]
}
},
"ietf-routing": {
"routing": {
"control-plane-protocols": {
"control-plane-protocol": [{
"type": "infix-routing:static",
"name": "default",
"static-routes": {
"ipv4": {
"route": [{
"destination-prefix": "192.168.200.1/32",
"next-hop": {
"next-hop-address": "192.168.50.2"
}
}]
},
"ipv6": {
"route": [{
"destination-prefix": "2001:db8:3c4d:200::1/128",
"next-hop": {
"next-hop-address": "2001:db8:3c4d:50::2"
}
}]
}
}
}]
}
}
}
})
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
}]
},
"ipv6": {
"forwarding": True,
"address": [{
"ip": "2001:db8:3c4d:50::2",
"prefix-length": 64
}]
}
},
{
"name": "lo",
"enabled": True,
"forwarding": True,
"ipv4": {
"address": [{
"ip": "192.168.200.1",
"prefix-length": 32
}]
},
"ipv6": {
"address": [{
"ip": "2001:db8:3c4d:200::1",
"prefix-length": 128
}]
}
}
]
}
},
"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"
}
}]
},
"ipv6": {
"route": [{
"destination-prefix": "::/0",
"next-hop": {
"next-hop-address": "2001:db8:3c4d: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")
_, R1data = env.ltop.xlate("R1", "data")
_, R2link = env.ltop.xlate("R2", "link")
_, R1link = env.ltop.xlate("R1", "link")
with test.step("Configure targets"):
parallel(config_target1(R1, R1data, R1link),
config_target2(R2, R2link))
with test.step("Wait for routes"):
until(lambda: route.ipv4_route_exist(R1, "192.168.200.1/32"))
until(lambda: route.ipv4_route_exist(R2, "0.0.0.0/0"))
until(lambda: route.ipv6_route_exist(R1, "2001:db8:3c4d:200::1/128"))
until(lambda: route.ipv6_route_exist(R2, "::/0"))
_, hport0 = env.ltop.xlate("PC", "data")
with infamy.IsolatedMacVlan(hport0) as ns0:
with test.step("Configure host addresses and routes"):
ns0.addip("2001:db8:3c4d:10::2", prefix_length=64, proto="ipv6")
ns0.addroute("2001:db8:3c4d:200::1/128", "2001:db8:3c4d:10::1", proto="ipv6")
ns0.addip("192.168.10.2")
ns0.addroute("192.168.200.1/32", "192.168.10.1")
with test.step("Verify that R2 is reachable on 192.168.200.1 from PC:data"):
ns0.must_reach("192.168.200.1")
with test.step("Verify that R2 is reachable on 2001:db8:3c4d:200::1 from PC:data"):
ns0.must_reach("2001:db8:3c4d:200::1")
with test.step("Remove all static routes from R1"):
R1.delete_xpath("/ietf-routing:routing/control-plane-protocols")
parallel(lambda: until(lambda: route.ipv4_route_exist(R1, "192.168.200.1/32") is False),
lambda: until(lambda: route.ipv6_route_exist(R1, "2001:db8:3c4d:200::1/128") is False))
with test.step("Verify R2 is no longer reachable on either IPv4 or IPv6 from PC:data"):
infamy.parallel(ns0.must_not_reach("192.168.200.1"),
ns0.must_not_reach("2001:db8:3c4d:200::1"))
test.succeed()