LTH-image

Homework Assignment 3

This homework will cover the some of the networking in cloud computing. In particular it will introduce you to software defined networking (SDN). Scott Shenker, professor at the UC Berkeley are giving a lot of good talks on SDN and why we need it, one of which you can find here. The homework is based on this Github turorial so if you find the instructions here confusing, I recommend that you look around in that one:)

Overview

The goal of this homework is to develop a network control application using OpenFlow. OpenFlow is an open interface for remotely controlling the forwarding tables in network switches, routers and access points. The network we will control will be built on Mininet, which creates a realistic virtual network on a single machine (VM).

There are a bunch of available controller platforms to build this application on. However, we recommend using POX (which is written in python). The rest of this homework will be based on it, but as usual, feel free to use whatever platform you wish!

The structure of the homework is as follows:

  1. Install all the necessary software
  2. Learn mininet, and create a topology (starting code exist)
  3. Learn how to connect a remote controller to your network switch
  4. Develop a learning switch (starting code exist)
  5. Develop a flow-based learning switch

Some platforms:

Java: Beacon, Floodlight

Python: POX, Ryu, Nox

Ruby: Trema

Deadline and Deliverables

Deadline for this homework is March 31. You will hand in the source code (usually just two files) and a short text (1/4 - 1/2 page) that answers the following questions:

  • How does a hub work?
  • How does a learning switch work?
    • How can you test if your switch is indeed a learning switch?
    • Show us some output from your switch (e.g. tcp-dump, WireShark screen dump, …)
  • How much more aggregate throughput can you get when using flows?
    • What numbers did you get?
  • How can you measure/know if the performance of a hub/switch is competitive?
    • What numbers are good?

Installing the necessary software

As with the privious homeworks this one does also reqwuire you to install some software. First off you will need to install a Virtual Machine (like VirualBox which is free, or VMware).

  1. Install a Virtual Machine - VirtualBox (is free and works on any platform)
  2. Download and install Mininet - great install instructions can be found here
  3. Make sure that you can ssh into your virtual machine!
  4. Read about mininet
  5. Go through the Mininet tutorial.
  6. Install POX (official tutorial here)
    1. Open a new terminal-window (W1) and ssh into your virtual machine (VM)
    2. In (W1): $ git clone http://github.com/noxrepo/pox

Create a topology in Mininet

There are many different ways of creating a network topology in mininet. Most of them are explained here

To prepare for the next homework assignment, we will learn how to create and define a topology using the mininet API, and Pyhton. Make sure to download and look through our file hw3_start.py (can be found here). In this file we have already created a topology corresponding to the figure below. It also contains some useful comments on how you can change the file so that the switches can use a remote controller - which is exactly what you want when you will create your learning switch!

Follow these steps to familiarize yourself with the topology, and the mininet API:

  1. ssh into your VM
  2. copy hw3_start.py into your VM - can be found here
  3. Run the file
    • $ sudo ./hw3_start.py
    • You should now be in the mininet-client!
    • Investigate what happens when you do the following commands:
    • mininet> pingall
    • mininet> h1 ping h2
    • mininet> h1 ifconfig
    • mininet> s1 ifconfig
    • Exit with mininet> exit
  4. Open hw3_start.py in a text editor:
    • Change the file so that you now connect to a remote controller
    • save it and run it again: $ sudo ./hw3_start.py
    • Do the same commands again and see what happens!!
  5. Let’s now make things interesting!!
    • Change the topology in the file so that it matches the figure below:
    • 5 hosts
    • 2 switches
    • 1 controller (controlling both switches)
    • you can start with the default controller and make sure that everything is connected!
    • then do as above, and connect to a remote controller instead

Connect a controller to your network

When running a remote controller it is up to you to make sure that you actually connect a controller. The controller you specified in your mininet topology (in hw3_start.py) will only ensure that your switch(es) listen for a connection from a remote controller.

These steps will guide you on how to connect a remote controller to your network switch. The remote controller that we will connect is the one that currently acts as a hub. You will later edit this controller so that it instead acts as a learning switch.

  1. Fire up 2 terminal windows and ssh into your VM on both of them
    • To try and keep things clear (W1) = window 1, and (W2) = window 2
  2. (W1): This window will be used to run mininet
    • Open your hw3_start.py-file
    • Make sure that it connects to a remote controller
    • Make sure that it have the topology specified above
    • Run your file: $ sudo ./hw3_start.py
    • Check connectivity: mininet> pingall
    • Should drop all the packets
  3. (W2): This will be used to run your controller
    • go to the pox-folder: $ cd pox/
    • open the following file in a text editor: pox/misc/of_tutorial.py
      • this is the file where the controller is defined
      • look through the code and then close the file
    • Now let’s start the controller!
    • $ ./pox.py log.level --DEBUG misc.of_tutorial
    • This enables logging in debug mode, and that the controller is defined in /misc/of_tutorial.py
    • You should see this ouput (tells you that you’ve connected to the two switches): POX 0.1.0 (betta) / Copyright 2011-2013 James McCauley, et al. DEBUG:core:POX 0.1.0 (betta) going up... DEBUG:core:Running on CPython (2.7.6/Mar 22 2014 22:59:56) DEBUG:core:Platform is Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty INFO:core:POX 0.1.0 (betta) is up. DEBUG:openflow.of_01:Listening on 0.0.0.0:6633 INFO:openflow.of_01:[00-00-00-00-00-02 1] connected DEBUG:misc.of_tutorial:Controlling [00-00-00-00-00-02 1] INFO:openflow.of_01:[00-00-00-00-00-01 2] connected DEBUG:misc.of_tutorial:Controlling [00-00-00-00-00-01 2]
  4. (W1): Try the following commands and see what happens:
    • mininet> pingall
    • mininet> h1 ping h5
    • mininet> iperf

Turing a Hub into a Learning Switch

This is the main part of the homework assignment. Here you will take the provided controller (of_tutorial.py) which acts as a hub and turn it into a learning switch. You should have done the above steps before doing this one!

  1. Fire up 2 terminal windows again, and ssh into your VM
  2. (W1): Will be used for mininet
    • We assume that you know how to start your topology by now…
    • We also assume that you know how to test stuff, and edit stuff..
  3. (W2): Will be used for POX
    • $ cd pox/
    • open: pox/misc/of_tutorial.py in your favorite text editor
    • Study the code! Make sure that you understand how it works as a hub before you continue!!!
      • You’ll see that it calls the function: self.act_like_hub(packet, packet_in) from _handle_PacketIN()
      • The hub will send an incoming packet to every outgoing port: self.resend_packet(packet_in, of.OFPP_ALL)
    • To turn the controller into a switch you need to call self.act_like_switch(packet, packet_in)
    • Change it and connect the controller:
    • $ ./pox.py log.level --DEBUG misc.of_tutorial
    • Check if your switch works! (or maybe you actually have to change some more stuff… ;)
    • Follow the schema outlined by the comments in of_tutorial.py to build your learning switch.
    • During development: when you change something, restart your controller and check if it works!
    • In the sections below you will find some help on Python, POX, and OpenFlow!
    • Again, I recommend looking at the original tutorial for further help!

Python help

If you are unfamiliar with Python, you can check out some good commands below, or this turorial.

  • mactable = {} - Initialize a dictionary
  • mactable[0x123] = 2 - Add an element to it
  • Check for a member in the dictionary: if 0x123 in mactable: print 'element 2 is in mactable' if 0x123 not in mactable: print 'element 2 is not in mactable'

  • log.debug('saw a new MAC!') - Print a debug message in POX

  • log.error('unexpected packet causing system meltdown!') - Print an error message in POX
  • print dir(object) - Print all member variables and functions of an object
  • prepend code with a # - Comment a line of code

OpenFlow and POX help

I highly recommend the OpenFlow POX wiki for any question on OpenFlow and POX. However, I will list some useful commands below:

  • packet.src - Get the source of a packet (the parsed packet data)
  • packet.dst - Get the destination of a packet (the parsed packet data)
  • packet_in.in_port - Get the inport of a packet_in (the actual ofp_packet_in message)
  • self.resend_packet(packet_in, out_port) - Send a packet to a certain port
  • log.debug("Sent packet: %s.%i -> %s.%i" %(mac_src, inport, mac_dst, outport)) - Example of a log.debug message

Installing a flow

To install a flow table entry into a switch you will have to send an ofp_flow_mod message to it. The message contains some fields that need to be set.

ofp_flow_mod message fields:

  • idle_timeout - Number of idle seconds before the flow entry is removed. Defaults to no idle timeout.
  • hard_timeout - Number of seconds before the flow entry is removed. Defaults to no timeout.
  • actions - A list of actions to perform on matching packets (e.g., ofp_action_output)
  • buffer_id - The buffer_id of a buffer to apply the actions to immediately.
  • in_port - If using a buffer_id, this is the associated input port.
  • match - An ofp_match object. By default, this matches everything, so you should probably set some of its fields!

ofp_match fields:

  • dl_src - The data link layer (MAC) source address.
  • dl_dst - The data link layer (MAC) destination address.
  • in_port - The packet input switch port.

Some examples of how to use these fields:

  • To create a new flow_message: msg = of.opf_flow_mod()
  • Set source MAC: msg.match.dl_src = ...
  • Set destination MAC: msg.match.dl_dst = ...
  • Set idle_timout: msg.idle_timeout = ...
  • Set hard_timeout: msg.hard_timeout = ...
  • Choose output port: msg.actions.append(of.ofp_action_output(port = outport))
  • Set the buffer id for the message: msg.buffer_id = packet_in.buffer_id
  • Send the message: self.connection.send(msg)