mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-30 12:33:02 +02:00
test/case: add bridge forwarding tests (single-DUT, dual-DUT, VLAN separation)
This commit is contained in:
committed by
Tobias Waldekranz
parent
fc7d212696
commit
7432ff10aa
@@ -4,4 +4,6 @@
|
||||
- case: dual_bridge.py
|
||||
- case: bridge_vlan.py
|
||||
- case: ipv4_autoconf.py
|
||||
|
||||
- case: bridge_fwd_sgl_dut.py
|
||||
- case: bridge_fwd_dual_dut.py
|
||||
- case: bridge_vlan_separation.py
|
||||
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
#!/usr/bin/env python3
|
||||
# ,-------------------------------------, ,-------------------------------------,
|
||||
# | dut1:data2 | | dut2:data2 |
|
||||
# | br0 ----------|-------|--------- br0 |
|
||||
# | / \ | | / \ |
|
||||
# |dut1:mgmt dut1:data0 dut1:data1 | | dut2:data0 dut2:data1 dut2:mgmt |
|
||||
# '-------------------------------------' '-------------------------------------'
|
||||
# | | | | | |
|
||||
# | | | | | |
|
||||
# ,-----------------------------------------------------------------------------------------,
|
||||
# | host:mgmt0 host:data0 host:data1 host:data2 host:data3 host:mgmt1 |
|
||||
# | [10.0.0.2] [10.0.0.3] [10.0.0.4] |
|
||||
# | (ns11) (ns20) (ns21) |
|
||||
# | |
|
||||
# | [ HOST ] |
|
||||
# '-----------------------------------------------------------------------------------------'
|
||||
|
||||
import infamy
|
||||
|
||||
with infamy.Test() as test:
|
||||
with test.step("Initialize"):
|
||||
env = infamy.Env(infamy.std_topology("2x4"))
|
||||
dut1 = env.attach("dut1", "mgmt")
|
||||
dut2 = env.attach("dut2", "mgmt")
|
||||
|
||||
with test.step("Configure a bridge with triple physical port"):
|
||||
_, tport10 = env.ltop.xlate("dut1", "data0")
|
||||
_, tport11 = env.ltop.xlate("dut1", "data1")
|
||||
_, tport12 = env.ltop.xlate("dut1", "data2")
|
||||
_, tport20 = env.ltop.xlate("dut2", "data0")
|
||||
_, tport21 = env.ltop.xlate("dut2", "data1")
|
||||
_, tport22 = env.ltop.xlate("dut2", "data2")
|
||||
|
||||
dut1.put_config_dict("ietf-interfaces", {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": "br0",
|
||||
"type": "iana-if-type:bridge",
|
||||
"enabled": True,
|
||||
"bridge": {
|
||||
"vlans": {
|
||||
"vlan": [
|
||||
{
|
||||
"vid": 10,
|
||||
"untagged": [ tport10, tport11 ],
|
||||
"tagged": [ "br0", tport12 ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": tport10,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"pvid": 10,
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": tport11,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"pvid": 10,
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": tport12,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0",
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
dut2.put_config_dict("ietf-interfaces", {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": "br0",
|
||||
"type": "iana-if-type:bridge",
|
||||
"enabled": True,
|
||||
"bridge": {
|
||||
"vlans": {
|
||||
"vlan": [
|
||||
{
|
||||
"vid": 10,
|
||||
"untagged": [ tport20, tport21 ],
|
||||
"tagged": [ "br0", tport22 ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": tport20,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"pvid": 10,
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": tport21,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"pvid": 10,
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": tport22,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0",
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
with test.step("Ping host:data20 [10.0.0.3] and host:data21 [10.0.0.4]"\
|
||||
"from host:data11 [10.0.0.2]"):
|
||||
|
||||
_, hport11 = env.ltop.xlate("host", "data11")
|
||||
_, hport20 = env.ltop.xlate("host", "data20")
|
||||
_, hport21 = env.ltop.xlate("host", "data21")
|
||||
|
||||
with infamy.IsolatedMacVlan(hport11) as ns11, \
|
||||
infamy.IsolatedMacVlan(hport20) as ns20, \
|
||||
infamy.IsolatedMacVlan(hport21) as ns21:
|
||||
|
||||
ns11.addip("10.0.0.2")
|
||||
ns20.addip("10.0.0.3")
|
||||
ns21.addip("10.0.0.4")
|
||||
|
||||
ns11.must_reach("10.0.0.3")
|
||||
ns11.must_reach("10.0.0.4")
|
||||
|
||||
test.succeed()
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python3
|
||||
# ,-----------------------------------------,
|
||||
# | |
|
||||
# | br0 |
|
||||
# | / \ |
|
||||
# | target:mgmt tgt:data0 tgt:data1 |
|
||||
# '-----------------------------------------'
|
||||
# | | |
|
||||
# | | |
|
||||
# ,------------------------------------------,
|
||||
# | host:mgmt host:data0 host:data1 |
|
||||
# | [10.0.0.1] [10.0.0.2] |
|
||||
# | (ns0) (ns1) |
|
||||
# | |
|
||||
# | [ HOST ] |
|
||||
# '------------------------------------------'
|
||||
|
||||
import infamy
|
||||
|
||||
with infamy.Test() as test:
|
||||
with test.step("Initialize"):
|
||||
env = infamy.Env(infamy.std_topology("1x3"))
|
||||
target = env.attach("target", "mgmt")
|
||||
|
||||
with test.step("Configure a bridge with dual physical port"):
|
||||
_, tport0 = env.ltop.xlate("target", "data0")
|
||||
_, tport1 = env.ltop.xlate("target", "data1")
|
||||
|
||||
target.put_config_dict("ietf-interfaces", {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": "br0",
|
||||
"type": "iana-if-type:bridge",
|
||||
"enabled": True,
|
||||
},
|
||||
{
|
||||
"name": tport0,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": tport1,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
with test.step("Ping host:data1 [10.0.0.2] from host:data0 [10.0.0.1]"):
|
||||
_, hport0 = env.ltop.xlate("host", "data0")
|
||||
_, hport1 = env.ltop.xlate("host", "data1")
|
||||
|
||||
with infamy.IsolatedMacVlan(hport0) as ns0, \
|
||||
infamy.IsolatedMacVlan(hport1) as ns1 :
|
||||
|
||||
ns1.addip("10.0.0.2")
|
||||
ns0.addip("10.0.0.1")
|
||||
|
||||
ns0.must_reach("10.0.0.2")
|
||||
|
||||
test.succeed()
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
#!/usr/bin/env python3
|
||||
# ,-------------------------------------, ,-------------------------------------,
|
||||
# | dut1:data2 | | dut2:data2 |
|
||||
# | br0 ----------|-------|--------- br0 |
|
||||
# | / \ | | / \ |
|
||||
# |dut1:mgmt dut1:data0 dut1:data1 | | dut2:data0 dut2:data1 dut2:mgmt |
|
||||
# '-------------------------------------' '-------------------------------------'
|
||||
# | | | | | |
|
||||
# | | | | | |
|
||||
# ,-----------------------------------------------------------------------------------------,
|
||||
# | host:mgmt0 host:data0 host:data1 host:data2 host:data3 host:mgmt1 |
|
||||
# | [10.0.0.1] [10.0.0.2] [10.0.0.3] [10.0.0.4] |
|
||||
# | (ns10) (ns11) (ns20) (ns21) |
|
||||
# | |
|
||||
# | [ HOST ] |
|
||||
# '-----------------------------------------------------------------------------------------'
|
||||
|
||||
import infamy
|
||||
|
||||
with infamy.Test() as test:
|
||||
with test.step("Initialize"):
|
||||
env = infamy.Env(infamy.std_topology("2x4"))
|
||||
dut1 = env.attach("dut1", "mgmt")
|
||||
dut2 = env.attach("dut2", "mgmt")
|
||||
|
||||
with test.step("Configure a bridge with triple physical port"):
|
||||
_, tport10 = env.ltop.xlate("dut1", "data0")
|
||||
_, tport11 = env.ltop.xlate("dut1", "data1")
|
||||
_, tport12 = env.ltop.xlate("dut1", "data2")
|
||||
_, tport20 = env.ltop.xlate("dut2", "data0")
|
||||
_, tport21 = env.ltop.xlate("dut2", "data1")
|
||||
_, tport22 = env.ltop.xlate("dut2", "data2")
|
||||
|
||||
dut1.put_config_dict("ietf-interfaces", {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": "br0",
|
||||
"type": "iana-if-type:bridge",
|
||||
"enabled": True,
|
||||
"bridge": {
|
||||
"vlans": {
|
||||
"vlan": [
|
||||
{
|
||||
"vid": 10,
|
||||
"untagged": [ tport10 ],
|
||||
"tagged": [ "br0", tport12 ]
|
||||
},
|
||||
{
|
||||
"vid": 20,
|
||||
"untagged": [ tport11 ],
|
||||
"tagged": [ "br0", tport12 ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": tport10,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"pvid": 10,
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": tport11,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"pvid": 20,
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": tport12,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0",
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
dut2.put_config_dict("ietf-interfaces", {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": "br0",
|
||||
"type": "iana-if-type:bridge",
|
||||
"enabled": True,
|
||||
"bridge": {
|
||||
"vlans": {
|
||||
"vlan": [
|
||||
{
|
||||
"vid": 10,
|
||||
"untagged": [ tport20 ],
|
||||
"tagged": [ "br0", tport22 ]
|
||||
},
|
||||
{
|
||||
"vid": 20,
|
||||
"untagged": [ tport21 ],
|
||||
"tagged": [ "br0", tport22 ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": tport20,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"pvid": 10,
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": tport21,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"pvid": 20,
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": tport22,
|
||||
"type": "iana-if-type:ethernetCsmacd",
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0",
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
with test.step("Ping host:data20 [10.0.0.3] from host:data10 [10.0.0.1] through <bridge-vlan-10>" \
|
||||
" and host:data21 [10.0.0.4] from host:data11 [10.0.0.2] through <bridge-vlan-20>"):
|
||||
|
||||
_, hport10 = env.ltop.xlate("host", "data10")
|
||||
_, hport11 = env.ltop.xlate("host", "data11")
|
||||
_, hport20 = env.ltop.xlate("host", "data20")
|
||||
_, hport21 = env.ltop.xlate("host", "data21")
|
||||
|
||||
with infamy.IsolatedMacVlan(hport10) as ns10, \
|
||||
infamy.IsolatedMacVlan(hport11) as ns11, \
|
||||
infamy.IsolatedMacVlan(hport20) as ns20, \
|
||||
infamy.IsolatedMacVlan(hport21) as ns21:
|
||||
|
||||
ns10.addip("10.0.0.1")
|
||||
ns11.addip("10.0.0.2")
|
||||
ns20.addip("10.0.0.3")
|
||||
ns21.addip("10.0.0.4")
|
||||
|
||||
ns10.must_reach("10.0.0.3")
|
||||
ns11.must_reach("10.0.0.4")
|
||||
|
||||
ns10.must_not_reach("10.0.0.4")
|
||||
ns11.must_not_reach("10.0.0.3")
|
||||
ns10.must_not_reach("10.0.0.2")
|
||||
ns11.must_not_reach("10.0.0.1")
|
||||
|
||||
test.succeed()
|
||||
+22
-2
@@ -63,6 +63,26 @@ class IsolatedMacVlan:
|
||||
args, kwargs = self._mangle_subprocess_args(args, kwargs)
|
||||
return subprocess.Popen(*args, **kwargs)
|
||||
|
||||
def runsh(self, script):
|
||||
def runsh(self, script, *args, **kwargs):
|
||||
return self.run("/bin/sh", text=True, input=script,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, *args, **kwargs)
|
||||
|
||||
def addip(self, addr, subnet=24):
|
||||
self.runsh(f"""
|
||||
set -ex
|
||||
ip link set iface up
|
||||
ip addr add {addr}/{subnet} dev iface
|
||||
""", check=True)
|
||||
|
||||
def ping(self, daddr, count=1, timeout=2, check=False):
|
||||
return self.runsh(f"""set -ex; ping -c {count} -w {timeout} {daddr}""", check=check)
|
||||
|
||||
def must_reach(self, daddr):
|
||||
res = self.ping(daddr)
|
||||
if res.returncode != 0:
|
||||
raise Exception(res.stdout)
|
||||
|
||||
def must_not_reach(self, daddr):
|
||||
res = self.ping(daddr)
|
||||
if res.returncode == 0:
|
||||
raise Exception(res.stdout)
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
graph "1x3" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+20";
|
||||
|
||||
node [shape=record, fontname="monospace"];
|
||||
edge [color="cornflowerblue", penwidth="2"];
|
||||
|
||||
host [
|
||||
label="host | { <tgt> tgt | <data0> data0 | <data1> data1 }",
|
||||
pos="0,12!",
|
||||
kind="controller",
|
||||
];
|
||||
|
||||
target [
|
||||
label="{ <mgmt> mgmt | <data0> data0 | <data1> data1 } | target",
|
||||
pos="10,12!",
|
||||
|
||||
kind="infix",
|
||||
];
|
||||
|
||||
host:tgt -- target:mgmt [kind=mgmt]
|
||||
host:data0 -- target:data0
|
||||
host:data1 -- target:data1
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
graph "2x4" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+20";
|
||||
|
||||
node [shape=record, fontname="monospace"];
|
||||
edge [color="cornflowerblue", penwidth="2"];
|
||||
|
||||
host [
|
||||
label="host | { <mgmt1> mgmt1 | <data10> data10 | <data11> data11 | <mgmt2> mgmt2 | <data20> data20 | <data21> data21 }",
|
||||
pos="0,15!",
|
||||
kind="controller",
|
||||
];
|
||||
|
||||
dut1 [
|
||||
label="{ <mgmt> mgmt | <data0> data0 | <data1> data1 } | dut1 | { <data2> data2 }",
|
||||
pos="10,18!",
|
||||
|
||||
kind="infix",
|
||||
];
|
||||
|
||||
dut2 [
|
||||
label="{ <mgmt> mgmt | <data0> data0 | <data1> data1 } | dut2 | { <data2> data2 }",
|
||||
pos="10,12!",
|
||||
|
||||
kind="infix",
|
||||
];
|
||||
|
||||
host:mgmt1 -- dut1:mgmt [kind=mgmt]
|
||||
host:data10 -- dut1:data0
|
||||
host:data11 -- dut1:data1
|
||||
|
||||
host:mgmt2 -- dut2:mgmt [kind=mgmt]
|
||||
host:data20 -- dut2:data0
|
||||
host:data21 -- dut2:data1
|
||||
|
||||
dut1:data2 -- dut2:data2
|
||||
}
|
||||
Reference in New Issue
Block a user