Skip to content

Commit 5e2a95b

Browse files
avargaadamgeorge309
authored andcommitted
tutorials: enhanced STP/RSTP tutorial
- Swapped 2 steps - Added explanations of protocol mechanisms - Adjusted text: fix convergence times, restart times, remove outdated DISCARDING notes - Added 'Observing the Simulation' sections with hints on packet names, port labels, root path cost, link colors, and state inspection
1 parent cee3d57 commit 5e2a95b

File tree

12 files changed

+662
-295
lines changed

12 files changed

+662
-295
lines changed

tests/fingerprint/tutorials.csv

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@
9090
/tutorials/ospf/, -f omnetpp.ini -c Step24 -r 0, 1000s, 2121-37f9/tplx;3712-1ee9/~tNl;748f-1d2a/~tND;00e6-a064/tyf, PASS,
9191
/tutorials/ospf/, -f omnetpp.ini -c Step25 -r 0, 1000s, dae5-8e27/tplx;09f0-c133/~tNl;9229-92b2/~tND;2aba-5b80/tyf, PASS,
9292

93+
/tutorials/stp/, -f omnetpp.ini -c Step1 -r 0, 20s, c524-4a7d/tplx;da7a-d614/~tNl;f855-b824/~tND;0000-0000/tyf, PASS,
94+
/tutorials/stp/, -f omnetpp.ini -c Step1A -r 0, 100s, 012f-e8c6/tplx;0402-f011/~tNl;e47f-3565/~tND;0000-0000/tyf, PASS,
95+
/tutorials/stp/, -f omnetpp.ini -c Step2 -r 0, 100s, 4277-12f4/tplx;f820-d8ec/~tNl;9d98-31fa/~tND;0000-0000/tyf, PASS,
96+
/tutorials/stp/, -f omnetpp.ini -c Step3 -r 0, 100s, ab69-ca3a/tplx;66a7-7afc/~tNl;e979-3de1/~tND;0000-0000/tyf, PASS,
97+
/tutorials/stp/, -f omnetpp.ini -c Step4 -r 0, 200s, 2194-2e65/tplx;21b6-fe33/~tNl;6323-903d/~tND;0000-0000/tyf, PASS,
98+
/tutorials/stp/, -f omnetpp.ini -c Step5 -r 0, 30s, 3d42-1d1a/tplx;5302-a3f8/~tNl;2b00-8103/~tND;0000-0000/tyf, PASS,
99+
/tutorials/stp/, -f omnetpp.ini -c Step6 -r 0, 200s, 27b6-5fa3/tplx;d92e-8dfb/~tNl;0635-6f17/~tND;0000-0000/tyf, PASS,
100+
/tutorials/stp/, -f omnetpp.ini -c Step7 -r 0, 200s, 2dc7-cb96/tplx;ba0e-3f09/~tNl;ddbf-05f5/~tND;0000-0000/tyf, PASS,
101+
/tutorials/stp/, -f omnetpp.ini -c Step8 -r 0, 200s, aaf0-fe6f/tplx;5dad-f644/~tNl;87b1-af13/~tND;0000-0000/tyf, PASS,
102+
/tutorials/stp/, -f omnetpp.ini -c Step9 -r 0, 200s, 2fd1-dd81/tplx;d20b-ca4a/~tNl;95e2-a8b0/~tND;0000-0000/tyf, PASS,
103+
/tutorials/stp/, -f omnetpp.ini -c Step9A -r 0, 200s, a274-2750/tplx;9c4f-0934/~tNl;7406-0134/~tND;0000-0000/tyf, PASS,
104+
93105
# /tutorials/visualization/, -f oldomnetpp.ini -c VisualizationTutorial01 -r 0, 500s, 0000-0000/tplx, PASS, # old omnetpp.ini
94106
# /tutorials/visualization/, -f oldomnetpp.ini -c VisualizationTutorial02 -r 0, 500s, 0000-0000/tplx, PASS,
95107
# /tutorials/visualization/, -f oldomnetpp.ini -c VisualizationTutorial03 -r 0, 500s, 0000-0000/tplx, PASS, # VisualizationTutorial03 extended

tutorials/stp/StpTutorial.ned

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import inet.linklayer.ieee8021d.tester.StpTester;
1111
import inet.node.ethernet.Eth1G;
1212
import inet.node.ethernet.EthernetHost;
1313
import inet.node.ethernet.EthernetSwitch;
14-
import inet.visualizer.canvas.integrated.IntegratedCanvasVisualizer;
14+
import inet.visualizer.canvas.integrated.IntegratedMultiCanvasVisualizer;
1515

1616

1717
//
@@ -21,7 +21,7 @@ import inet.visualizer.canvas.integrated.IntegratedCanvasVisualizer;
2121
network LoopNetwork
2222
{
2323
submodules:
24-
visualizer: IntegratedCanvasVisualizer {
24+
visualizer: IntegratedMultiCanvasVisualizer {
2525
@display("p=100,351;is=s");
2626
}
2727
pcapRecorder: PcapRecorder {
@@ -56,22 +56,22 @@ network LoopNetwork
5656
//
5757
network SwitchNetwork
5858
{
59-
@figure[legend](type=text; pos=200,10; text="Port labels: Role/State\nRoles: R=Root D=Designated A=Alternate B=Backup -=NotAssigned X=Disabled\nStates: F=Forwarding L=Learning D=Discarding(RSTP) B=Blocking(STP) N=Listening(STP)");
59+
@figure[simtime](type="simTimeText"; pos=550,400; prefix="SimTime: "; font=,10);
6060
submodules:
6161
stpTester: StpTester {
62-
@display("p=100,100;is=s");
62+
@display("p=100,100,col,60;g=left;is=s");
6363
}
6464
scenarioManager: ScenarioManager {
65-
@display("p=100,200;is=s");
65+
@display("p=100,100,col,60;g=left;is=s");
6666
}
6767
l2NetworkConfigurator: L2NetworkConfigurator {
68-
@display("p=100,300;is=s");
68+
@display("p=100,100,col,60;g=left;is=s");
6969
}
70-
visualizer: IntegratedCanvasVisualizer {
71-
@display("p=213,101;is=s");
70+
visualizer: IntegratedMultiCanvasVisualizer {
71+
@display("p=100,100,col,60;g=left;is=s");
7272
}
7373
pcapRecorder: PcapRecorder {
74-
@display("p=213,200;is=s");
74+
@display("p=100,100,col,60;g=left;is=s");
7575
}
7676
switch1: EthernetSwitch {
7777
@display("p=400,100");
@@ -114,12 +114,29 @@ network SwitchNetwork
114114
host2.ethg <--> Eth1G <--> switch5.ethg++;
115115
}
116116

117+
//
118+
// STP variant of SwitchNetwork with STP-specific legend.
119+
//
120+
network StpSwitchNetwork extends SwitchNetwork
121+
{
122+
@figure[legend](type=text; pos=200,10; text="Port labels: Role/State\nRoles: R=Root D=Designated -=NotAssigned X=Disabled\nStates: F=Forwarding L=Learning B=Blocking N=Listening");
123+
}
124+
125+
//
126+
// RSTP variant of SwitchNetwork with RSTP-specific legend.
127+
//
128+
network RstpSwitchNetwork extends SwitchNetwork
129+
{
130+
@figure[legend](type=text; pos=200,10; text="Port labels: Role/State\nRoles: R=Root D=Designated A=Alternate B=Backup -=NotAssigned X=Disabled\nStates: F=Forwarding L=Learning D=Discarding");
131+
}
132+
117133
//
118134
// Extends SwitchNetwork with four additional switches and four additional hosts,
119-
// creating a larger meshed topology. Used in Steps 6-8.
135+
// creating a larger meshed topology. Used in Steps 5-8.
120136
//
121137
network LargeNet extends SwitchNetwork
122138
{
139+
@figure[simtime](type="simTimeText"; pos=550,520; prefix="SimTime: "; font=,10);
123140
submodules:
124141
switch8: EthernetSwitch {
125142
@display("p=475,370");
@@ -160,6 +177,22 @@ network LargeNet extends SwitchNetwork
160177
host6.ethg <--> Eth1G <--> switch8.ethg++;
161178
}
162179

180+
//
181+
// STP variant of LargeNet with STP-specific legend.
182+
//
183+
network StpLargeNet extends LargeNet
184+
{
185+
@figure[legend](type=text; pos=200,10; text="Port labels: Role/State\nRoles: R=Root D=Designated -=NotAssigned X=Disabled\nStates: F=Forwarding L=Learning B=Blocking N=Listening");
186+
}
187+
188+
//
189+
// RSTP variant of LargeNet with RSTP-specific legend.
190+
//
191+
network RstpLargeNet extends LargeNet
192+
{
193+
@figure[legend](type=text; pos=200,10; text="Port labels: Role/State\nRoles: R=Root D=Designated A=Alternate B=Backup -=NotAssigned X=Disabled\nStates: F=Forwarding L=Learning D=Discarding");
194+
}
195+
163196
//
164197
// Dumbbell-shaped network: two internally meshed clusters of four switches each,
165198
// connected only through two bridge switches in the middle. Used in Step 9.
@@ -176,7 +209,7 @@ network BottleneckNetwork
176209
l2NetworkConfigurator: L2NetworkConfigurator {
177210
@display("p=50,190;is=s");
178211
}
179-
visualizer: IntegratedCanvasVisualizer {
212+
visualizer: IntegratedMultiCanvasVisualizer {
180213
@display("p=50,260;is=s");
181214
}
182215
pcapRecorder: PcapRecorder {

tutorials/stp/doc/conclusion.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ You have learned:
99
- How STP builds a loop-free spanning tree through root bridge election, port role assignment, and the Blocking/Listening/Learning/Forwarding state machine
1010
- How to control the root bridge selection using bridge priorities
1111
- Why STP convergence takes approximately 50 s and what the port states mean
12+
- How STP handles topology changes using the TCN mechanism, and why reconvergence is slow (~50 s)
1213
- How RSTP achieves convergence in approximately 6 s using edge ports and the proposal/agreement mechanism
13-
- How both protocols handle switch failures and link reconnects, with RSTP recovering much faster
14+
- How RSTP handles switch failures and link reconnects much faster than STP
15+
- How RSTP operates on a larger dumbbell-shaped topology where two clusters are connected through a bottleneck
1416

1517
In practice, RSTP (or its successor Multiple Spanning Tree Protocol, MSTP) is
1618
preferred over the original STP in all modern networks due to its significantly

tutorials/stp/doc/step1.rst

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,27 @@ This step demonstrates that loops in a switched network cause frames to
1010
circulate indefinitely, creating a broadcast storm that prevents reliable
1111
communication.
1212

13+
Background
14+
----------
15+
16+
Ethernet switches (also called *bridges* in the IEEE 802.1D standard) forward
17+
frames based on destination MAC addresses. When a switch receives a frame, it
18+
looks up the destination address in its *MAC forwarding table* (also called
19+
*filtering database*). If the address is found, the frame is sent out the
20+
corresponding port; if not, the frame is *flooded* — sent out all ports except
21+
the one it arrived on. Broadcast and multicast frames are always flooded.
22+
23+
Switches build their forwarding tables automatically through *MAC learning*:
24+
when a frame arrives on a port, the switch records the frame's source MAC
25+
address and the port it arrived on. Over time, the table is populated with
26+
entries that map each known host address to a specific port.
27+
28+
In enterprise and data-center networks, redundant links between switches are
29+
common — they protect against individual link or switch failures that would
30+
otherwise partition the network. However, redundant links inevitably create
31+
*loops* in the network topology, and as this step demonstrates, loops and the
32+
flood-and-learn mechanism are a dangerous combination.
33+
1334
The Network
1435
-----------
1536

@@ -43,15 +64,22 @@ Results
4364

4465
When ``host1`` sends a frame to ``host2``, ``switch1`` does not yet know which
4566
port leads to ``host2``, so it floods the frame out all other ports. The frame
46-
arrives at ``switch2`` and ``switch3`` simultaneously. Both switches also don't
47-
know ``host2``'s location and flood the frame further — creating two copies of
48-
the frame circulating in opposite directions around the ring.
67+
arrives at both ``switch2`` and ``switch3``. Neither switch knows ``host2``'s
68+
location either, so both flood the frame further — creating two copies
69+
circulating in opposite directions around the ring.
4970

5071
Each time a switch receives one of these circulating copies, it floods it again,
51-
causing the number of frame copies to grow exponentially. This is a *broadcast
52-
storm*. The MAC forwarding tables in each switch become inconsistent, as the same
53-
MAC address appears on different ports depending on which direction the looping
54-
frames arrive from.
72+
causing the number of frame copies in the network to grow exponentially. This is
73+
a *broadcast storm*.
74+
75+
The loop also causes *MAC table instability*. Consider the path of
76+
``host1``'s frame: when it first arrives at ``switch3`` directly from
77+
``switch1``, the switch learns that ``host1`` is reachable via the port
78+
connected to ``switch1``. Moments later, the *same* frame arrives at
79+
``switch3`` from ``switch2`` (having gone the long way around the ring), and
80+
the switch overwrites its table entry to say ``host1`` is reachable via the
81+
``switch2`` port. This oscillation repeats continuously with each circulating
82+
copy, making the forwarding table useless.
5583

5684
As a result, ``host2`` receives many duplicate copies of each frame sent by
5785
``host1``, and communication is completely unreliable.

tutorials/stp/doc/step2.rst

Lines changed: 86 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,41 +16,59 @@ switches (``switch1``–``switch7``) interconnected with redundant links, and tw
1616
hosts (``host1`` and ``host2``) attached to ``switch6`` and ``switch5``
1717
respectively.
1818

19-
.. figure:: media/LoopNetwork.png
19+
.. figure:: media/SwitchNetwork.png
2020
:align: center
2121

2222
About STP
2323
~~~~~~~~~
2424

25-
STP (IEEE 802.1D-1998) builds a spanning tree over a bridged network to ensure
26-
a loop-free topology. The protocol works as follows:
27-
28-
1. **Root bridge election**: The switch with the lowest bridge ID (priority +
29-
MAC address) becomes the root bridge. By default all switches have the same
30-
priority (32768), so the one with the lowest MAC address wins.
31-
32-
2. **Root port selection**: Each non-root switch selects the port with the
33-
lowest path cost to the root as its *root port*.
34-
35-
3. **Designated port selection**: On each network segment, one port is elected
36-
*designated port* (the one with the lowest path cost to the root). If the
37-
segment has another switch port that is neither a root port nor the designated
38-
port, that port is put in *blocking* state to eliminate the redundant path.
39-
40-
4. **Port states**: STP ports transition through *Blocking → Listening →
41-
Learning → Forwarding*, with each transition taking ``forwardDelay`` seconds
42-
(default 15 s). The total convergence time is therefore approximately 30–50 s.
25+
The Spanning Tree Protocol (STP, IEEE 802.1D-1998) eliminates loops by
26+
computing a *spanning tree* of the network — a subset of links that connects
27+
all switches without forming any cycles. In graph theory, a *spanning tree* of
28+
a connected graph is a tree that includes every node but only enough edges to
29+
keep it connected (exactly *N−1* edges for *N* nodes). Ports on links that are
30+
not part of the spanning tree are placed in a *blocking* state, effectively
31+
deactivating those links for data traffic while keeping them available as
32+
backups.
33+
34+
STP achieves this through a distributed algorithm. Switches exchange *Bridge
35+
Protocol Data Units* (BPDUs) to share topology information and collectively
36+
agree on the tree structure. The algorithm works in the following phases:
37+
38+
**1. Root bridge election.** All switches start by assuming they are the root.
39+
Each switch sends BPDUs containing its own *bridge ID* — a value composed of a
40+
configurable *bridge priority* (default 32768) and the switch's MAC address.
41+
When a switch receives a BPDU with a lower bridge ID than its own, it accepts
42+
the sender's root claim and stops claiming to be root itself. Eventually, the
43+
switch with the numerically lowest bridge ID wins the election and becomes the
44+
*root bridge*. The root bridge is the root of the spanning tree; all paths in
45+
the tree lead toward it.
46+
47+
**2. Root port selection.** Each non-root switch must determine which of its
48+
ports provides the best (lowest-cost) path toward the root bridge. STP assigns
49+
a *path cost* to each port based on its link speed (e.g. 4 for 1 Gbps in the
50+
revised cost table, or 19 for 100 Mbps in the original). Each BPDU carries a
51+
*root path cost* field — the total cost from the sending switch to the root.
52+
When a switch receives a BPDU, it adds the receiving port's own cost to the
53+
advertised root path cost. The port with the lowest total cost to the root
54+
becomes the switch's *root port*. Ties are broken by lowest upstream bridge ID,
55+
then by lowest upstream port ID.
56+
57+
**3. Designated port selection.** For each network segment (link between two
58+
switches), one port must be elected as the *designated port* — the port
59+
responsible for forwarding frames toward the root on that segment. The switch
60+
that can offer the lowest root path cost on that segment wins. Ties are
61+
broken by bridge ID, then port ID. The root bridge's ports are always
62+
designated (cost = 0).
63+
64+
**4. Blocking redundant ports.** Any port that is neither a root port nor a
65+
designated port is placed in *blocking* state — it does not forward data
66+
frames, breaking the loop. These blocked ports continue to receive BPDUs so
67+
they can react if the topology changes.
4368

4469
In INET, STP is implemented by the :ned:`Stp` module, which is enabled per
4570
switch via the ``hasStp = true`` and ``spanningTreeProtocol = "Stp"`` parameters.
4671

47-
.. note::
48-
INET's :ned:`Stp` implementation does not distinguish Blocking and Listening
49-
as separate internal states. Instead, it uses a single ``DISCARDING`` state
50-
(borrowed from RSTP) that covers both, transitioning directly to ``LEARNING``
51-
and then ``FORWARDING``. As a result, the visualization will display
52-
*Discarding* rather than *Blocking* or *Listening* during convergence.
53-
5472
Configuration
5573
~~~~~~~~~~~~~
5674

@@ -67,11 +85,41 @@ as labels on each switch interface.
6785

6886
Traffic from ``host2`` to ``host1`` starts at t=60s, after STP has converged.
6987

88+
Observing the Simulation
89+
~~~~~~~~~~~~~~~~~~~~~~~~
90+
91+
When running the simulation in Qtenv, several visual cues help you follow the
92+
STP algorithm:
93+
94+
- **Packet names** reflect the BPDU type. Periodic hello BPDUs are named
95+
``stp-hello``; topology change notifications are ``stp-tcn``.
96+
- **Port labels** on each switch interface show the port role and state as a
97+
short code, e.g. ``R/F`` (Root/Forwarding), ``D/F`` (Designated/Forwarding),
98+
``D/N`` (Designated/Listening), ``D/L`` (Designated/Learning),
99+
``-/B`` (unassigned/Blocking).
100+
- **Root path cost** is displayed above each switch icon: ``cost: 0`` for
101+
the root bridge, ``cost: 19`` for a switch one hop away over a 100 Mbps link,
102+
etc.
103+
- **Link colors**: black for Forwarding ports, gray for
104+
Blocking/Listening/Learning.
105+
- **Root bridge** is highlighted in cyan with an exclamation mark icon overlay.
106+
- **Inspecting state variables**: double-click on a switch's ``stp`` submodule
107+
in Qtenv to inspect internal variables such as ``bridgeAddress``,
108+
``rootAddress``, ``rootPathCost``, ``isRoot``, and per-port data (in the
109+
interface table).
110+
70111
Results
71112
~~~~~~~
72113

73114
After the simulation starts, STP BPDUs (Bridge Protocol Data Units) are exchanged
74-
between switches. After approximately 50 s, the spanning tree has converged:
115+
between switches. The following video shows the BPDU traffic during the early
116+
phase of convergence:
117+
118+
.. video_noloop:: media/step2arrows2.mp4
119+
:width: 100%
120+
:align: center
121+
122+
After approximately 35 s, the spanning tree has converged:
75123

76124
- **Root bridge**: ``switch1`` (lowest MAC address ``AAAAAA000001``)
77125
- **Blocked ports**: the ports creating redundant paths are blocked (shown in gray)
@@ -80,13 +128,21 @@ between switches. After approximately 50 s, the spanning tree has converged:
80128
.. figure:: media/step2result.png
81129
:align: center
82130

131+
The following video shows the full convergence process in real time. Observe how
132+
port states transition from Blocking through Listening and Learning to
133+
Forwarding over approximately 36 s:
134+
135+
.. video_noloop:: media/step2convergence_realtime2.mp4
136+
:width: 100%
137+
:align: center
138+
83139
After convergence (t=60s), ``host2`` begins sending frames to ``host1`` and
84140
receives replies, confirming that the tree provides full connectivity while
85141
remaining loop-free.
86142

87-
.. video:: media/step2result.mp4
88-
:width: 100%
89-
:align: center
143+
.. video_noloop:: media/step2arrows4.mp4
144+
:width: 100%
145+
:align: center
90146

91147
Sources:
92148
:download:`omnetpp.ini <../omnetpp.ini>`,

0 commit comments

Comments
 (0)