Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Read an OpenFlow controller in Python

After this lesson: I can read a small os-ken controller and say what each handler does.

55 min lesson6 commandsSoftware-defined networking lab: Open vSwitch, Mininet and an OpenFlow controller on one VM

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

WordWhat it means
Handlera function that runs when one kind of event happens
Packet-ina message that carries a packet from the switch to the controller
Flow-moda message that adds a flow to the switch
Packet-outa message that sends one packet on its way
os-kena 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

EventHandlerWhat it does
A switch connectsswitch_connectedInstalls the priority 0 flow that sends unknown packets here
A packet arrives that no flow coverspacket_inLearns, 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

Code: 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

Command
grep -A1 "set_ev_cls(" /etc/sdnlab/switch.py

Shown 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

Command
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

Command
sudo sdnlab flows

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Empty the flow table

Command
sudo ovs-ofctl -O OpenFlow13 del-flows br0

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Start the lab's controller

Command
sudo sdnlab controller

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

List the flows

Command
sudo ovs-ofctl -O OpenFlow13 dump-flows br0 --no-stats

Shown 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.

About this lab and its source: Software-defined networking lab: Open vSwitch, Mininet and an OpenFlow controller on one VM

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.