One fabric, eleven proofs
The browser is your control room. Linux bridge state and namespace traffic are the evidence.
Prepare WSL2 Ubuntu
Move the script into your Linux home directory, install the open-source tools and pass doctor.
cp /mnt/c/Users/YOUR-WINDOWS-USER/Downloads/mission-layer2-grand-finale.sh ~/
cd ~
chmod +x mission-layer2-grand-finale.shsudo ./mission-layer2-grand-finale.sh installsudo ./mission-layer2-grand-finale.sh doctor- Expected result
- Every tool, Scapy, WSL2 and Linux bridge creation pass.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.
Build and verify the campus fabric
Create four bridges, four trunks, four namespaces, two VLANs and one protected STP path.
sudo ./mission-layer2-grand-finale.sh buildsudo ./mission-layer2-grand-finale.sh verify- Expected result
- Hosts A, B and C communicate in VLAN 110. VLAN 120 stays isolated. STP protects a redundant path.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.
Continue only when every verification line passes.
Elect a different STP root
Lower West priority and watch every bridge agree on the new root.
sudo ./mission-layer2-grand-finale.sh demo root-electionsudo ./mission-layer2-grand-finale.sh fixsudo ./mission-layer2-grand-finale.sh verify- Expected result
- West becomes root because its bridge priority is lowest. Fix restores Core.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.
Read STP port roles and states
Prove that a physically healthy redundant link can remain blocked by design.
sudo ./mission-layer2-grand-finale.sh demo port-roles- Expected result
- Forwarding links carry frames. A blocking port prevents a Layer 2 loop.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.
Prove the VLAN boundaries
Combine membership output with same-VLAN success and cross-VLAN failure.
sudo ./mission-layer2-grand-finale.sh demo vlan-boundaries- Expected result
- A reaches B in VLAN 110. A cannot reach the application in VLAN 120 without routing.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.
Watch the FDB learn again
Flush dynamic entries, generate traffic and inspect learned source MAC addresses.
sudo ./mission-layer2-grand-finale.sh demo fdb-learning- Expected result
- Host MAC addresses reappear on the ports where their source frames arrived.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.
Capture unknown-unicast flooding
Send one frame to an unknown destination and let Host C prove the flood.
sudo ./mission-layer2-grand-finale.sh demo unknown-unicast- Expected result
- Host C captures 02:00:00:de:ad:03. The capture stops after one frame or five seconds.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.
Measure the broadcast domain
Capture one broadcast simultaneously inside VLAN 110 and VLAN 120.
sudo ./mission-layer2-grand-finale.sh demo broadcast-domain- Expected result
- Host C sees MISSION-BROADCAST. The VLAN 120 application does not.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.
Prune a VLAN from an active trunk
Keep the link and STP healthy while VLAN 110 disappears from one trunk endpoint.
sudo ./mission-layer2-grand-finale.sh demo trunk-pruningsudo ./mission-layer2-grand-finale.sh fixsudo ./mission-layer2-grand-finale.sh verify- Expected result
- Physical and STP pass, but VLAN 110 membership is missing until repaired.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.
Break an access-port PVID
Move Host B untagged ingress into VLAN 130 without taking the link down.
sudo ./mission-layer2-grand-finale.sh demo pvid-mismatchsudo ./mission-layer2-grand-finale.sh fixsudo ./mission-layer2-grand-finale.sh verify- Expected result
- Host B remains up, its PVID becomes 130 and VLAN 110 service fails until repaired.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.
Move a MAC without changing the host
Attach Host B to East while keeping the same namespace, IP and MAC.
sudo ./mission-layer2-grand-finale.sh demo mac-movesudo ./mission-layer2-grand-finale.sh fix- Expected result
- Host B keeps its identity while the learned switch port changes.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.
Engineer the STP path cost
Make the East-West trunk expensive and watch STP recompute its preferred tree.
sudo ./mission-layer2-grand-finale.sh demo path-costsudo ./mission-layer2-grand-finale.sh fix- Expected result
- East-West cost changes from 100 to 500. Fix restores the baseline.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.
Finish with active-link failover
Cut Core-West during a bounded ping and observe the protected path become useful.
sudo ./mission-layer2-grand-finale.sh demo link-failoversudo ./mission-layer2-grand-finale.sh fixsudo ./mission-layer2-grand-finale.sh verify- Expected result
- Core-West goes down, an alternate path transitions and A-to-B traffic resumes.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.
You proved eleven distinct Layer 2 behaviors with real kernel state and bounded namespace traffic.
Clean the fabric, keep the evidence
Remove every Lab 03 namespace, veth and bridge. Timestamped results remain.
sudo ./mission-layer2-grand-finale.sh destroyip netns list | grep '^mls1-g-' || echo "Lab 03 namespaces removed"
ip -br link show | grep '^mls1-g-' || echo "Lab 03 links removed"- Expected result
- No mls1-g namespace, link or bridge remains. Evidence stays under results/.
- Evidence
- The script writes or prints the kernel state used to support the conclusion.