mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-01 21:33:02 +02:00
test: vlan_iface_termination: Add test
This will fail on a system running a vanilla kernel, where the dut's ports are backed by mv88e6xxx, because: 1. The ports are attached to the same bridge, and are thus in the same PVT group. 2. Creation of the VLAN uppers causes the DSA layer to add both ports to the same VTU entry. As a result, hardware behaves as if both ports had been configured as tagged members of VLAN 10, instead of just terminating incoming traffic locally. Add this test to catch hardware which behaves in this way.
This commit is contained in:
@@ -61,3 +61,6 @@
|
||||
|
||||
- name: iface_enable_disable
|
||||
case: iface_enable_disable/test.py
|
||||
|
||||
- name: vlan_iface_termination
|
||||
case: vlan_iface_termination/test.py
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
=== VLAN Interface Termination
|
||||
==== Description
|
||||
Verify that VLANs stacked on top of an interfaces that are also
|
||||
attached to a VLAN filtering bridge are always locally terminated.
|
||||
|
||||
....
|
||||
.-------------------.
|
||||
| dut |
|
||||
| |
|
||||
| a.10 br0 b.10 |
|
||||
| \ / \ / |
|
||||
'------a-----b------'
|
||||
| |
|
||||
| |
|
||||
.------a-----b------.
|
||||
| |
|
||||
| host |
|
||||
| |
|
||||
'-------------------'
|
||||
....
|
||||
|
||||
In this setup, even though VLAN 10 is allowed to ingress and egress on
|
||||
both `a` and `b`, _bridging_ of packets from one to the other must
|
||||
_not_ be allowed.
|
||||
|
||||
==== Topology
|
||||
ifdef::topdoc[]
|
||||
image::../../test/case/ietf_interfaces/vlan_iface_termination/topology.svg[VLAN Interface Termination topology]
|
||||
endif::topdoc[]
|
||||
ifndef::topdoc[]
|
||||
ifdef::testgroup[]
|
||||
image::vlan_iface_termination/topology.svg[VLAN Interface Termination topology]
|
||||
endif::testgroup[]
|
||||
ifndef::testgroup[]
|
||||
image::topology.svg[VLAN Interface Termination topology]
|
||||
endif::testgroup[]
|
||||
endif::topdoc[]
|
||||
==== Test sequence
|
||||
. Set up topology and attach to dut
|
||||
. Configure bridge and VLAN interfaces on dut
|
||||
. Configure IP addresses and VLAN interfaces on host
|
||||
. Verify that host:a reaches host:b with untagged packets
|
||||
. Verify that traffic on VLAN 10 from host:a does not reach host:b
|
||||
. Verify that host:a can reach dut on VLAN 10
|
||||
. Verify that host:b can reach dut on VLAN 10
|
||||
|
||||
|
||||
<<<
|
||||
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
#!/usr/bin/env python3
|
||||
r"""VLAN Interface Termination
|
||||
|
||||
Verify that VLANs stacked on top of an interfaces that are also
|
||||
attached to a VLAN filtering bridge are always locally terminated.
|
||||
|
||||
....
|
||||
.-------------------.
|
||||
| dut |
|
||||
| |
|
||||
| a.10 br0 b.10 |
|
||||
| \ / \ / |
|
||||
'------a-----b------'
|
||||
| |
|
||||
| |
|
||||
.------a-----b------.
|
||||
| |
|
||||
| host |
|
||||
| |
|
||||
'-------------------'
|
||||
....
|
||||
|
||||
In this setup, even though VLAN 10 is allowed to ingress and egress on
|
||||
both `a` and `b`, _bridging_ of packets from one to the other must
|
||||
_not_ be allowed.
|
||||
|
||||
"""
|
||||
import infamy
|
||||
|
||||
with infamy.Test() as test:
|
||||
with test.step("Set up topology and attach to dut"):
|
||||
env = infamy.Env()
|
||||
dut = env.attach("dut", "mgmt")
|
||||
|
||||
with test.step("Configure bridge and VLAN interfaces on dut"):
|
||||
_, hporta = env.ltop.xlate("host", "a")
|
||||
_, hportb = env.ltop.xlate("host", "b")
|
||||
_, dporta = env.ltop.xlate( "dut", "a")
|
||||
_, dportb = env.ltop.xlate( "dut", "b")
|
||||
|
||||
dut.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": "br0",
|
||||
"type": "infix-if-type:bridge",
|
||||
"enabled": True,
|
||||
"bridge": {
|
||||
"vlans": {
|
||||
"vlan": [
|
||||
{
|
||||
"vid": 1,
|
||||
"untagged": [dporta, dportb]
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": dporta,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"pvid": 1,
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": f"{dporta}.10",
|
||||
"type": "infix-if-type:vlan",
|
||||
"vlan": {
|
||||
"id": 10,
|
||||
"lower-layer-if": dporta,
|
||||
},
|
||||
"ipv4": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "10.10.1.2",
|
||||
"prefix-length": 24,
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": dportb,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"pvid": 1,
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": f"{dportb}.10",
|
||||
"type": "infix-if-type:vlan",
|
||||
"vlan": {
|
||||
"id": 10,
|
||||
"lower-layer-if": dportb,
|
||||
},
|
||||
"ipv4": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "10.10.2.2",
|
||||
"prefix-length": 24,
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
with infamy.IsolatedMacVlan(hporta) as nsa, \
|
||||
infamy.IsolatedMacVlan(hportb) as nsb:
|
||||
|
||||
with test.step("Configure IP addresses and VLAN interfaces on host"):
|
||||
nsa.addip("10.0.1.1")
|
||||
nsa.runsh("""
|
||||
set -ex
|
||||
ip link add dev vlan10 link iface up type vlan id 10
|
||||
ip addr add 10.10.1.1/24 dev vlan10
|
||||
""")
|
||||
|
||||
nsb.addip("10.0.1.2")
|
||||
nsb.runsh("""
|
||||
set -ex
|
||||
ip link add dev vlan10 link iface up type vlan id 10
|
||||
ip addr add 10.10.2.1/24 dev vlan10
|
||||
""")
|
||||
|
||||
with test.step("Verify that host:a reaches host:b with untagged packets"):
|
||||
nsa.must_reach("10.0.1.2")
|
||||
|
||||
with test.step("Verify that traffic on VLAN 10 from host:a does not reach host:b"):
|
||||
infamy.parallel(lambda: nsa.runsh("timeout -s INT 5 ping -i 0.2 -b 10.10.1.255 || true"),
|
||||
lambda: nsb.must_not_receive("ip src 10.10.1.1"))
|
||||
|
||||
with test.step("Verify that host:a can reach dut on VLAN 10"):
|
||||
nsa.must_reach("10.10.1.2")
|
||||
|
||||
with test.step("Verify that host:b can reach dut on VLAN 10"):
|
||||
nsb.must_reach("10.10.2.2")
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,24 @@
|
||||
graph "vlan-iface-termination" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+22";
|
||||
|
||||
node [shape=record, fontname="DejaVu Sans Mono, Book"];
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
host [
|
||||
label="host | { <mgmt> mgmt | <a> a | <b> b }",
|
||||
pos="0,0!",
|
||||
kind="controller",
|
||||
];
|
||||
|
||||
dut [
|
||||
label="{ <mgmt> mgmt | <a> a | <b> b } | dut",
|
||||
pos="6,0!",
|
||||
kind="infix",
|
||||
];
|
||||
|
||||
host:mgmt -- dut:mgmt [kind=mgmt, color="lightgray"]
|
||||
host:a -- dut:a
|
||||
host:b -- dut:b
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?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: vlan-iface-termination Pages: 1 -->
|
||||
<svg width="254pt" height="78pt"
|
||||
viewBox="0.00 0.00 254.02 78.00" 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 74)">
|
||||
<title>vlan-iface-termination</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-74 250.02,-74 250.02,4 -4,4"/>
|
||||
<!-- host -->
|
||||
<g id="node1" class="node">
|
||||
<title>host</title>
|
||||
<polygon fill="none" stroke="black" points="0,-0.5 0,-69.5 100,-69.5 100,-0.5 0,-0.5"/>
|
||||
<text text-anchor="middle" x="25" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">host</text>
|
||||
<polyline fill="none" stroke="black" points="50,-0.5 50,-69.5 "/>
|
||||
<text text-anchor="middle" x="75" y="-54.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="50,-46.5 100,-46.5 "/>
|
||||
<text text-anchor="middle" x="75" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">a</text>
|
||||
<polyline fill="none" stroke="black" points="50,-23.5 100,-23.5 "/>
|
||||
<text text-anchor="middle" x="75" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">b</text>
|
||||
</g>
|
||||
<!-- dut -->
|
||||
<g id="node2" class="node">
|
||||
<title>dut</title>
|
||||
<polygon fill="none" stroke="black" points="155.02,-0.5 155.02,-69.5 246.02,-69.5 246.02,-0.5 155.02,-0.5"/>
|
||||
<text text-anchor="middle" x="180.02" y="-54.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="155.02,-46.5 205.02,-46.5 "/>
|
||||
<text text-anchor="middle" x="180.02" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">a</text>
|
||||
<polyline fill="none" stroke="black" points="155.02,-23.5 205.02,-23.5 "/>
|
||||
<text text-anchor="middle" x="180.02" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">b</text>
|
||||
<polyline fill="none" stroke="black" points="205.02,-0.5 205.02,-69.5 "/>
|
||||
<text text-anchor="middle" x="225.52" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">dut</text>
|
||||
</g>
|
||||
<!-- host--dut -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>host:mgmt--dut:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M100,-58C100,-58 154.52,-58 154.52,-58"/>
|
||||
</g>
|
||||
<!-- host--dut -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>host:a--dut:a</title>
|
||||
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M100,-35C100,-35 154.52,-35 154.52,-35"/>
|
||||
</g>
|
||||
<!-- host--dut -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>host:b--dut:b</title>
|
||||
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M100,-12C100,-12 154.52,-12 154.52,-12"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
Reference in New Issue
Block a user