Sunday, July 14, 2013

OpenFlow 1.2 switch app with multiple tables

Another OpenFlow switch app?

I'm sorry - there's quite a few of these, but this one is cool. I've been part of a couple of OpenFlow bootcamps in the last year and a bit, and an example that I've used is the pyswitch app that came stock with NOX. It's only a few lines of functional code, but it's a nice example to show what OpenFlow controller code looks like, and how you can easily build a learning switch from scratch. We'd go through a couple of scenarios on the whiteboard, but then we'd find a problem that OpenFlow 1.0 couldn't solve.

Why we need multiple flow tables

Let's say we have two nodes connected to the OpenFlow switch. Node 1 sends a packet to node 2, and the switch doesn't know this MAC address, so it passes the packet up to the controller. The controller learns the MAC address of node 1 (where the packet came from), and assigns it to port 1. It then pushes a flow to the controller to make sure that traffic for node 1 goes out the right port, and then sends the packet on its way.

What happens when node 2 replies?

The switch gets the packet for node 1, has a flow for it, and forwards it. There's a problem here though - because the packet never went to the controller, the switch never learns the MAC address of node 2 - so all traffic to node 2 will go via the controller and clog things up.

The OpenFlow learning switch apps that I've seen deal with this by storing pairs - they match on a destination MAC address *and* on the source MAC address - this way, whenever we get a packet from a new MAC address, we make sure the controller knows and pushes out the right flow. This works perfectly, but it's inefficient - we need O(n^2) flows, meaning 100 MAC address on a switch requires 20,000 flows (one flow in each direction = 2 flows for each pair of mac addresses).

This is where later versions of OpenFlow start to shine. We can create multiple flow tables, so we have an initial table to check the source MAC (and forward to the controller if we don't know it), and a second table to check the destination MAC (and forward to controller, or just flood, if we don't know it). This way we need to record each source MAC once, and each destination MAC once - so 100 MAC addresses on a switch only needs 200 flows - only O(n).

What it looks like

I've spent the whole weekend getting OpenVSwitch working so I could test it, but this is the final product. My good friend Josh suggested I use the Ryu controller as it has OpenFlow 1.2 and 1.3 support. It comes with a simple_switch application for OpenFlow 1.0, so I modified this to make it work with OpenFlow 1.2. There's a couple of subtle differences between the protocols, but once it was refactored for 1.2, it was pretty easy to set up a second table. The code is here if you want it, and you can just clone this repo when you want to use Ryu - it's up to date with the current github version (as of 14 July 2013), but I'm hoping they'll accept my pull request and just add my app into the main build.

Next steps

I really want to get BIRD working with an OpenFlow controller, so we'll see if that happens - I've got BIRD pushing out a stream of JSON routes that anything can pick up, and I just need this to get turned into flows. It really does feel like we're getting closer to a production OpenFlow controller that plugs into a cheap switch and takes a whole internet route table. Now is a very good time to be a network engineer!

1 comment:

  1. It's really good to know about switch apps. Dwyer flow switch is my first choice.