A switch that works out where everyone is
A learning switch is a switch that works out which port each computer is on by watching the frames that arrive. It matters because without learning a switch would have to send every frame out of every port.
The idea is small, and it is the first thing you will teach a controller to do.
By the end of this lesson
Note
I can explain how a switch learns which port a MAC address is on.
Key words
| Word | What it means | Example |
|---|---|---|
| MAC address | the address burned into a network card | 00:00:00:00:00:01 |
| Source address | the address of the computer that sent the frame | |
| Destination address | the address of the computer the frame is for | |
| Learning table | a list that pairs each MAC address with a port | |
| Flooding | sending a frame out of every port but the one it came in on |
The cells students fill in are left blank in this preview.
A switch learns from the source address
Every frame carries two addresses: where it came from and where it is going. When a frame arrives on port 2 from computer B, the switch learns that B is reachable through port 2. It writes that in its learning table.
Then, when a frame arrives for B, the switch looks B up and sends it out of port 2 only.
Worked example: four frames reach a new switch
| Frame | Arrives on | From to | Table afterwards | Sent to |
|---|---|---|---|---|
| 1 | Port 1 | A to B | A: 1 | Flood, B is unknown |
| 2 | Port 2 | B to A | A: 1, B: 2 | Port 1 |
| 3 | Port 1 | A to B | A: 1, B: 2 | Port 2 |
| 4 | Port 3 | C to A | A: 1, B: 2, C: 3 | Port 1 |
The cells students fill in are left blank in this preview.
The same four frames in Python
# A learning switch with a dictionary: MAC address -> port.
table = {}
# Each frame: port it arrived on, source MAC, destination MAC.
frames = [[1, "A", "B"], [2, "B", "A"], [1, "A", "B"], [3, "C", "A"]]
for frame in frames:
port = frame[0]
source = frame[1]
dest = frame[2]
table[source] = port # learn from the source
if dest in table:
print(source, "to", dest, "-> port", table[dest])
else:
print(source, "to", dest, "-> flood")
print(table)
# Change the last frame to [2, "C", "A"] and run again: C has moved.
Flooding is the answer to not knowing
When the destination is not in the table, the switch cannot know the right port. So it floods: it sends the frame out of every port except the one it came in on.
The right computer receives it, the others ignore it, and when it answers, the switch learns where it is. The next frames need no flooding.
A common mistake
Warning
Many people think the switch learns the destination from each frame, since that is the address it uses. It learns the source. The source tells it where a computer is. The destination is only looked up, and when it is not in the table, the frame is flooded.
Watch a finished learning switch
Open vSwitch has a learning switch built in, and the flow action normal turns it on. Your lab's own task asks you not to use it, because the point there is to build the learning yourself. Here you only look at one at work.
Its learning table is the forwarding database, fdb. You will print it before and after a ping, then clear it.
Rebuild the lab with no controller
sudo sdnlab flowsShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Empty the flow table
sudo ovs-ofctl -O OpenFlow13 del-flows br0Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Turn on the built-in learning switch
sudo ovs-ofctl -O OpenFlow13 add-flow br0 priority=1,actions=normalShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Print the learning table
sudo ovs-appctl fdb/show br0Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Ping h2 from h1
sudo ip netns exec h1 ping -c 1 -W 1 -q 10.0.0.2 | grep -o ", 0% packet loss"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Print the learning table again
sudo ovs-appctl fdb/show br0Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Two computers learned, and one did not
Before the ping the table held no line for h1 or h2. A line marked LOCAL, for the switch itself, may be there. After it, there are lines for port 1 and port 2, with the MAC addresses of h1 and h2.
The Age column counts seconds since the switch last heard from that address. h3 is not listed: it has sent nothing yet.
Count the lines for h1 and h2
sudo ovs-appctl fdb/show br0 | grep -c 00:00:00:00:00:0Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Clear the learning table
sudo ovs-appctl fdb/flush br0Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Print it once more
sudo ovs-appctl fdb/show br0Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Forgetting is part of learning
After the flush the lines for h1 and h2 are gone, so the switch has forgotten them. It will flood until it hears from the computers again.
A switch also forgets an address that has been quiet for a while, so a computer that moves is not lost for ever. Run sudo sdnlab flows to put the lab back.