A controller is a few small functions
An OpenFlow controller is a program that reacts to messages from switches, and in Python it is only a few small functions. Once you can read one, you can tell what a network will do from its code.
The lab's controller uses os-ken, a Python library for writing OpenFlow controllers.
By the end of this lesson
Note
I can read a small os-ken controller and say what each handler does.
Key words
| Word | What it means |
|---|---|
| Handler | a function that runs when one kind of event happens |
| Packet-in | a message that carries a packet from the switch to the controller |
| Flow-mod | a message that adds a flow to the switch |
| Packet-out | a message that sends one packet on its way |
| os-ken | a Python library for writing OpenFlow controllers |
The cells students fill in are left blank in this preview.
A controller is a set of handlers
A controller does nothing until something happens. Each kind of event has one handler, a function that runs when that event arrives.
In os-ken a line above the function, starting with @set_ev_cls, says which event it handles. You only need to read that line, not write one.
Worked example: two handlers of a switch
| Event | Handler | What it does |
|---|---|---|
| A switch connects | switch_connected | Installs the priority 0 flow that sends unknown packets here |
| A packet arrives that no flow covers | packet_in | Learns, chooses a port, installs a flow and sends this packet on |
The cells students fill in are left blank in this preview.
Handlers chosen by event, in Python
# A controller is a few functions, each one chosen by the kind of event.
def switch_connected(switch):
print(switch, "connected: install the table-miss flow")
def packet_in(switch, port):
print(switch, "packet-in on port", port, ": learn, choose, install")
events = [["connected", "s1", 0], ["packet-in", "s1", 2], ["packet-in", "s1", 1]]
for event in events:
if event[0] == "connected":
switch_connected(event[1])
else:
packet_in(event[1], event[2])
# Add a second connected event for "s2" and run again.
Packet-in, flow-mod and packet-out
Three messages carry the conversation. The switch sends a packet-in when no flow covers a packet, and the packet is inside it.
The controller answers with a flow-mod, which adds a flow, so that later packets are handled in the switch. It also sends a packet-out, because the first packet is still waiting and the new flow only helps the ones after it.
A common mistake
Warning
Many people think the controller sees every packet. It sees only the packets that no flow covers. Once the controller installs a flow, the switch handles the rest of that conversation alone. Learning only costs one trip to the controller for each conversation.
Look at the lab's controller
The lab's own controller lives in a file called switch.py, which part 3 of the lab asks you to finish. You will only look at its handlers, not change it.
First print the line above each function, to see which event it handles. Then start the controller and look at the one flow the first handler wrote.
Which events does switch.py handle
grep -A1 "set_ev_cls(" /etc/sdnlab/switch.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Two events, two handlers
The command printed two groups, separated by --. Each group is an @set_ev_cls line and the function under it.
One handles EventOFPSwitchFeatures, the event of a switch connecting. The other handles EventOFPPacketIn, the event of a packet-in.
The numbers OpenFlow 1.3 uses
python3 -c "from os_ken.ofproto import ofproto_v1_3; print(hex(ofproto_v1_3.OFP_VERSION), hex(ofproto_v1_3.OFPP_FLOOD), hex(ofproto_v1_3.OFPP_CONTROLLER))"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
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.
Start the lab's controller
sudo sdnlab controllerShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
List the flows
sudo ovs-ofctl -O OpenFlow13 dump-flows br0 --no-statsShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
The first handler already ran
The table was empty, and the controller connected. Now there is one flow with priority 0 and the action CONTROLLER. That flow came from switch_connected, the handler for a connecting switch, as a flow-mod.
From here every packet with no better flow becomes a packet-in. Run sudo sdnlab flows to put the lab back.