I programmed OpenFlow 1.3 flow tables directly on Open vSwitch using match-action rules with priorities, idle timeouts, and output actions. Installing proactive flows revealed exactly how the southbound protocol turns controller intent into packet forwarding.

Objective & Context

OpenFlow is the canonical SDN southbound protocol: a switch matches packet fields against prioritized table entries and applies actions. This lab manipulates flows by hand with ovs-ofctl to make the abstraction concrete before automating it from a controller.

Learning Objectives

  • Install proactive flows on an OVS switch with ovs-ofctl.
  • Use priority values to control which entry wins when matches overlap.
  • Write match fields (in_port, dl_dst, nw_dst) and actions (output, drop, mod).
  • Read per-flow packet and byte counters with dump-flows.
  • Explain the packet-in path for table misses.

Environment & Prerequisites

Prerequisites

  • Open vSwitch with OpenFlow 1.3 enabled; a Mininet topology.
  • ovs-ofctl and ovs-vsctl tooling.
  • Understanding of match fields (in_port, dl_dst, nw_dst).
  • Open vSwitch with OpenFlow 1.3 enabled and a Mininet topology running.
  • ovs-ofctl and ovs-vsctl installed (sudo apt install -y openvswitch-switch).
  • Understanding of match fields: in_port, dl_dst, nw_dst.
  • Root or sudo access for OVS commands.

Step-by-Step Execution

1. Install a proactive forwarding flow

ovs-ofctl -O OpenFlow13 add-flow s1 "priority=200,in_port=1,actions=output:2"

Expected output:

(no output: add-flow succeeds silently; the flow is installed)

What this teaches: a flow entry is a prioritized match plus an action, which is the entire OpenFlow programming model.

2. Add a higher-priority drop rule

ovs-ofctl -O OpenFlow13 add-flow s1 "priority=300,ip,nw_dst=10.0.0.9,actions=drop"

Expected output:

(no output: the higher-priority drop rule is installed above the forward rule)

What this teaches: priority resolves overlapping matches deterministically, so a drop rule can override a forward rule.

Two subtleties: actions=drop installs an empty action set (the OpenFlow way to say discard), and nw_dst=10.0.0.9 matches a single /32 address unless a mask is given. Flows installed by hand live alongside controller flows: a connected controller can overwrite or expire them, so re-dump the table after any controller event.

3. Inspect counters per flow

ovs-ofctl -O OpenFlow13 dump-flows s1

Expected output:

priority=300,ip,nw_dst=10.0.0.9 actions=drop  n_packets=14
priority=200,in_port=1 actions=output:2       n_packets=88

What this teaches: per-flow counters are the ground truth of what the switch actually did with packets.

How It Works

OpenFlow splits the switch into a flow table and a secure channel to the controller. Each table entry has match fields (which packets it applies to), a priority (which entry wins on overlap), counters (packets and bytes seen), and actions (what to do: forward, drop, modify, or send to the controller).

When a packet arrives, the switch walks the table top-down by priority and applies the first matching entry's actions. If nothing matches, the default behavior is a table miss: the switch buffers the packet and sends a packet-in message to the controller, which can then install a flow reactively. Proactive flows, installed ahead of time as in this lab, avoid that round trip.

Counters make flows observable. n_packets and n_bytes per entry show exactly how much traffic each rule handled, which is how you verify that the drop rule caught the target host and the forward rule carried everything else. Without counters, flow programming is guesswork.

Validation & Testing

Send traffic and confirm the higher-priority drop wins over the forward rule, with packet counters incrementing on the matched entry. Pass criteria: priority ordering observed and counters confirm which flow handled each packet.

Troubleshooting

SymptomLikely causeFix
Flow appears installed but traffic is unaffectedA higher-priority entry matches first, or the flow went to the wrong tableDump flows sorted by priority and confirm your entry is the first match for the test traffic
ovs-ofctl reports unknown OVSDB or connection refusedovsdb-server not running or the bridge name is wrongCheck ovs-vsctl show and confirm the bridge name (s1) exists
add-flow rejected with a syntax errorMatch field or action invalid for the negotiated OpenFlow versionForce -O OpenFlow13 and check field names against the OVS manual for that version
Counters stay at zeroTraffic never reaches the switch or matches a different entryGenerate test traffic and re-dump; zero counters on a live path mean a mismatch
Flows vanish after a whileIdle or hard timeouts expired the entriesRe-add with explicit timeouts or check that the controller is not deleting them
Advanced: Troubleshooting
  • Flow not matching: a higher-priority entry may shadow it; dump and check ordering.
  • Version errors: always pass -O OpenFlow13 consistently.
  • Flows expire: set idle_timeout=0 for permanent proactive rules.

Key Results

  • Installed proactive flows with explicit priority and action semantics.
  • Verified priority resolution between a forward and a drop rule.
  • Read per-flow packet counters to confirm handling, not assumptions.
  • Built the manual baseline later automated via an SDN controller app.

Key Takeaways

  • Priority, not position, decides which overlapping flow wins.
  • Proactive flows avoid controller round trips; reactive flows adapt to new traffic.
  • Always verify with dump-flows counters, never assume installation equals effect.
  • Match as narrowly as needed: broad matches create surprising interactions.

Practice Challenges

Challenge 1: Rate-limit with a meter

Goal: Attach an OpenFlow meter to cap one host at 1 Mbit/s and verify with iperf.

Hint: Create the meter with ovs-ofctl -O OpenFlow13 meter-mod, then reference it in a flow action.

Challenge 2: Rewrite a destination MAC

Goal: Add a flow that rewrites dl_dst for traffic to one host and confirm delivery still works.

Hint: Use actions=mod_dl_dst:<mac>,output:<port> with a priority above the normal forward flow.