mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-02 13:53:01 +02:00
test: Verify ieee-group-forward LLDP
This commit is contained in:
@@ -11,6 +11,8 @@ include::lldp_enable_disable/Readme.adoc[]
|
||||
|
||||
include::lldp_admin_status/Readme.adoc[]
|
||||
|
||||
include::lldp_ieee_group_forward/Readme.adoc[]
|
||||
|
||||
include::ssh_server_config/Readme.adoc[]
|
||||
|
||||
include::ssh_key_authentication/Readme.adoc[]
|
||||
|
||||
@@ -4,3 +4,6 @@
|
||||
|
||||
- name: lldp_admin_status
|
||||
case: lldp_admin_status/test.py
|
||||
|
||||
- name: lldp_ieee_group_forward
|
||||
case: lldp_ieee_group_forward/test.py
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
lldp_ieee_group_forward.adoc
|
||||
@@ -0,0 +1,28 @@
|
||||
=== LLDP IEEE Group Forward
|
||||
==== Description
|
||||
Verify that LLDP packets can be flooded to all ports on a bridge.
|
||||
Operation and non-operation are confirmed using tcpdump.
|
||||
|
||||
==== Topology
|
||||
ifdef::topdoc[]
|
||||
image::{topdoc}../../test/case/infix_services/lldp_ieee_group_forward/topology.svg[LLDP IEEE Group Forward topology]
|
||||
endif::topdoc[]
|
||||
ifndef::topdoc[]
|
||||
ifdef::testgroup[]
|
||||
image::lldp_ieee_group_forward/topology.svg[LLDP IEEE Group Forward topology]
|
||||
endif::testgroup[]
|
||||
ifndef::testgroup[]
|
||||
image::topology.svg[LLDP IEEE Group Forward topology]
|
||||
endif::testgroup[]
|
||||
endif::topdoc[]
|
||||
==== Test sequence
|
||||
. Set up topology and attach to target DUT
|
||||
. Enable target interfaces and create bridge
|
||||
. Disable LLDP on target
|
||||
. Verify LLDP absence on host:data2
|
||||
. Enable LLDP flooding by setting group forward
|
||||
. Verify LLDP arrival on host:data2
|
||||
|
||||
|
||||
<<<
|
||||
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""LLDP IEEE Group Forward
|
||||
|
||||
Verify that LLDP packets can be flooded to all ports on a bridge.
|
||||
Operation and non-operation are confirmed using tcpdump.
|
||||
"""
|
||||
|
||||
import time
|
||||
import threading
|
||||
import infamy
|
||||
|
||||
from scapy.all import Ether, sendp
|
||||
from scapy.contrib.lldp import (
|
||||
LLDPDU, LLDPDUChassisID, LLDPDUPortID,
|
||||
LLDPDUTimeToLive, LLDPDUEndOfLLDPDU
|
||||
)
|
||||
|
||||
SNIFFING_DURATION = 3
|
||||
|
||||
LLDP_INTERVAL = 1
|
||||
LLDP_TTL = 3
|
||||
LLDP_MULTICAST_MAC = "01:80:C2:00:00:0E"
|
||||
LLDP_ETHERTYPE = 0x88cc
|
||||
|
||||
CHASSIS_ID = "Chassis-Test"
|
||||
SRC_MAC = "02:01:02:03:04:05"
|
||||
|
||||
BRIDGE = "br0"
|
||||
|
||||
def send_lldp_packet(iface):
|
||||
eth = Ether(src=SRC_MAC, dst=LLDP_MULTICAST_MAC, type=LLDP_ETHERTYPE)
|
||||
lldpdu = eth / LLDPDU()
|
||||
lldpdu /= LLDPDUChassisID(subtype=7, id=CHASSIS_ID)
|
||||
lldpdu /= LLDPDUPortID(subtype=5, id=iface)
|
||||
lldpdu /= LLDPDUTimeToLive(ttl=LLDP_TTL)
|
||||
lldpdu /= LLDPDUEndOfLLDPDU()
|
||||
sendp(lldpdu, iface=iface, verbose=False)
|
||||
|
||||
def send_lldp_packets_continuously(iface, stop_event):
|
||||
time.sleep(LLDP_INTERVAL/2)
|
||||
while not stop_event.is_set():
|
||||
send_lldp_packet(iface)
|
||||
time.sleep(LLDP_INTERVAL)
|
||||
|
||||
def capture_traffic(iface):
|
||||
with infamy.IsolatedMacVlan(iface) as netns:
|
||||
sniffer = infamy.Sniffer(netns, f"ether proto {LLDP_ETHERTYPE}")
|
||||
with sniffer:
|
||||
time.sleep(SNIFFING_DURATION)
|
||||
return sniffer.output()
|
||||
|
||||
def start_lldp_sender_thread(iface):
|
||||
stop = threading.Event()
|
||||
thread = threading.Thread(
|
||||
target=send_lldp_packets_continuously,
|
||||
args=(iface, stop)
|
||||
)
|
||||
thread.start()
|
||||
return stop, thread
|
||||
|
||||
with infamy.Test() as test:
|
||||
with test.step("Set up topology and attach to target DUT"):
|
||||
env = infamy.Env()
|
||||
target = env.attach("target", "mgmt")
|
||||
_, hdata1 = env.ltop.xlate("host", "data1")
|
||||
_, hdata2 = env.ltop.xlate("host", "data2")
|
||||
|
||||
with test.step("Configure interfaces and disable LLDP daemon"):
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": BRIDGE,
|
||||
"type": "infix-if-type:bridge",
|
||||
"enabled": True,
|
||||
},
|
||||
{
|
||||
"name": target["data1"],
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": target["data2"],
|
||||
"enabled": True,
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ieee802-dot1ab-lldp": {
|
||||
"lldp": {
|
||||
"enabled": False
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
stop_event, sender_thread = start_lldp_sender_thread(hdata1)
|
||||
|
||||
try:
|
||||
with test.step("Verify LLDP absence on host:data2"):
|
||||
captured_traffic = capture_traffic(hdata2)
|
||||
if "LLDP" in captured_traffic.stdout:
|
||||
test.fail()
|
||||
|
||||
finally:
|
||||
stop_event.set()
|
||||
sender_thread.join()
|
||||
|
||||
with test.step("Enable LLDP flooding by setting group forward"):
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": BRIDGE,
|
||||
"infix-interfaces:bridge": {
|
||||
"ieee-group-forward": [
|
||||
"lldp"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
stop_event, sender_thread = start_lldp_sender_thread(hdata1)
|
||||
|
||||
try:
|
||||
with test.step("Verify LLDP arrival on host:data2"):
|
||||
captured_traffic = capture_traffic(hdata2)
|
||||
if "LLDP" not in captured_traffic.stdout:
|
||||
test.fail()
|
||||
|
||||
finally:
|
||||
stop_event.set()
|
||||
sender_thread.join()
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,24 @@
|
||||
graph "1x3" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+80";
|
||||
|
||||
node [shape=record, fontname="DejaVu Sans Mono, Book"];
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
host [
|
||||
label="host | { <mgmt> mgmt | <data1> data1 | <data2> data2 }",
|
||||
pos="0,12!",
|
||||
requires="controller",
|
||||
];
|
||||
|
||||
target [
|
||||
label="{ <mgmt> mgmt | <data1> data1 | <data2> data2 } | target",
|
||||
pos="10,12!",
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
host:mgmt -- target:mgmt [requires="mgmt", color="lightgray"]
|
||||
host:data1 -- target:data1 [color="black", requires="ieee-mc"]
|
||||
host:data2 -- target:data2 [color="black", requires="ieee-mc"]
|
||||
}
|
||||
@@ -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: 1x3 Pages: 1 -->
|
||||
<svg width="440pt" height="78pt"
|
||||
viewBox="0.00 0.00 440.03 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>1x3</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-74 436.03,-74 436.03,4 -4,4"/>
|
||||
<!-- host -->
|
||||
<g id="node1" class="node">
|
||||
<title>host</title>
|
||||
<polygon fill="none" stroke="black" points="0,-0.5 0,-69.5 108,-69.5 108,-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="79" y="-54.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="50,-46.5 108,-46.5 "/>
|
||||
<text text-anchor="middle" x="79" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data1</text>
|
||||
<polyline fill="none" stroke="black" points="50,-23.5 108,-23.5 "/>
|
||||
<text text-anchor="middle" x="79" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data2</text>
|
||||
</g>
|
||||
<!-- target -->
|
||||
<g id="node2" class="node">
|
||||
<title>target</title>
|
||||
<polygon fill="none" stroke="black" points="308.03,-0.5 308.03,-69.5 432.03,-69.5 432.03,-0.5 308.03,-0.5"/>
|
||||
<text text-anchor="middle" x="337.03" y="-54.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="308.03,-46.5 366.03,-46.5 "/>
|
||||
<text text-anchor="middle" x="337.03" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data1</text>
|
||||
<polyline fill="none" stroke="black" points="308.03,-23.5 366.03,-23.5 "/>
|
||||
<text text-anchor="middle" x="337.03" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data2</text>
|
||||
<polyline fill="none" stroke="black" points="366.03,-0.5 366.03,-69.5 "/>
|
||||
<text text-anchor="middle" x="399.03" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">target</text>
|
||||
</g>
|
||||
<!-- host--target -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>host:mgmt--target:mgmt</title>
|
||||
<path fill="none" stroke="lightgray" stroke-width="2" d="M108,-58C108,-58 308.03,-58 308.03,-58"/>
|
||||
</g>
|
||||
<!-- host--target -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>host:data1--target:data1</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M108,-35C108,-35 308.03,-35 308.03,-35"/>
|
||||
</g>
|
||||
<!-- host--target -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>host:data2--target:data2</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M108,-12C108,-12 308.03,-12 308.03,-12"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
Reference in New Issue
Block a user