CSEP-561 Spring'22
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode

Project 1: Mininet and an Intro to SDN

Turnin: Online via Gradescope
Teams: Individual or Teams of 2 (register teams on gradescope)
Due: April 27, 2022 @ 11:59PM PDT.

Project Overview

In this project you will learn about Software Defined Networking (SDN). Using Virtualbox, Mininet, and Pox as the implementers of the OpenFlow protocol, you will build simple networks using SDN primitives.

  • First you will learn to use mininet, a SDN-enabled network emulator.
  • For the second portion you will be using POX to implement a simple L2 static firewall via OpenFlow rules determined by your SDN controller.

Background

Software Defined Networking and OpenFlow

Software-Defined Networking (SDN) is a recently proposed networking paradigm in which the data and control planes are decoupled from one another. One can think of the control plane as being the network’s “brain”, i.e., it is responsible for making all decisions, for example, how to forward data, while the data plane is what actually moves the data. In traditional networks, both the control- and data planes are tightly integrated and implemented in the forwarding devices that comprise a network. The SDN control plane is implemented by the “controller” and the data plane by “switches”. The controller acts as the “brain” of the network, and sends commands (“rules”) to the switches on how to handle traffic. OpenFlow has emerged as the de facto SDN standard and specifies how the controller and the switches communicate as well as the rules controllers install on switches.

Mininet

Mininet is a software stack that creates a virtual network on your computer/laptop. It accomplishes this task by creating host namespaces (h1, h2, etc) and connecting them through virtual interfaces. So when we run ping between the linux namespaces h1 and h2, the ping will run from h1s namespace through a virtual interface pair created for h1 and h2, before it reaches h2. If h1 and h2 are connected through a switch as shown in the python code in the Mininet walkthrough, the ping will transit multiple virtual interface pairs. The switches that we will be using are running OpenVSwitch (OVS), a software-defined networking stack. Mininet will connect additional virtual interfaces between each virtual port on the switch with each connected host. The host name space allows each host to see the same file system, but operates as its own process that will run separately from each of the other host processes. The OVS version running on the Ubuntu image supports OpenFlow.

POX

Pox is a research/academic implementation of an OpenVFlow controller. It provides python hooks to program mininet-based software emulated networks.

Assignment

Part 1: Mininet Primer

Learning Objectives (After this section, students will be able to…) :

  • Use Mininet, a widely used self-contained network environment for research and experimentation, to build a test network topology.
  • Use the basic debug tools built into Mininet to test connectivity between virtual hosts and get the state of the openflow switches in their topology.
Virtualbox and Vagrant Installation

Mininet is a tool for building emulated network topologies on a Linux host for experimentation with SDN. To ensure everyone is using the same enviornment and prevent you from messing up the networking on your computer, we’ll run mininet inside of a virtual machine.

To manage the virtual machine, we’ll be using a tool called Vagrant. Vagrant supports multiple “virtualization providers”, but for compatibility with the Ubuntu image we’ll use to run mininet, we suggest using VirtualBox. VirtualBox an open source and freely available virtualization system.

You will need to install both Vagrant and VirtualBox for this assignment. See their respective documentation for your platform for installation instructions:

If you’re using a flavor of Linux or MacOS, you may be able to install instead via package manager or brew, respectively.
Mininet VM Installation With Vagrant

Please follow the instructions here to set up the Vagrant VM for this project. This VM is based off Ubuntu 20.04 and includes a default set of mininet binaries and example scripts. Once you are inside the VM after running vagrant ssh, proceed to the next part.

There are a well known set of issues in using virtualization. If you encounter issues, reach out online and we’ll see how we can help. Some common issues and answers are:

  • Is your computer really old? It might not be able to be virtualized – talk to the staff via Ed.
  • Is your computer really new, and runs on a non-x86 architecture? Talk to the staff via Ed.
  • Make sure that virtualization is enabled in your BIOS.
For folks who would prefer to work in a remote VM, we’re looking into this option, and should have more information soon!
For more information about vagrant, you can checkout this supplemental doc
Using Mininet

Using mininet is described here. You can run it by typing: sudo mn.

There is also a very helpful Mininet community wiki with lots of good up-to-date information about how to use mininet effectively.

Inside of the the mininet CLI, try running other commands like help, net, nodes, links and dump. Mininet starts with a default network that you can poke at. Find the mac address of the hosts, the ethernet ports connected, and the hostnames in the system.

Programming Mininet Topologies

Mininet is also programmable using the python programming language. We have provided some sample topologies here, which should already be downloaded in the VM and unzipped into ~/project-1.

In this directory, you’ll find two different directories: topo and pox. Ignore the pox directory for now (it’s used in part2). In the topo folder there are a variety of python files. These each define a topology for each of the following project portions. Run the project 1 file with sudo python3 project-1/topos/part1.py. It will drop you into the CLI with the network topology defined in the python script.

Deliverables:

Your task in part one is to modify part1.py to represent the following network topology:

A network diagram showing s1 connected directly to four hosts, h1, h2, h3, and h4

After creating the above architecture, you submission should include the following items:

  1. (10 Points) Your modified topos/part1.py file
  2. (10 points) Screenshots of the iperf h1 h4, dump, and pingall commands (from within the mininet cli in your running VM) in pdf format. These will help the TAs validate that your submission was working correctly on your machine if for some reason your submitted code does not work in the grading environment. Put your screenshots in the screenshots/part1 directory.

Part 2: SDN Controllers using POX

Learing Objectives (After this section, students will be able to…):

  • Run their own POX openflow controller to add custom rules to switches in a mininet topology.
  • Build an OpenFlow SDN controller program capable of connecting hosts together via a single programmable switch.
  • Establish connectivity by flooding packets out switch ports.
  • Create match –> action rules to block or allow particular types of traffic through a switch based on layer 2 and layer 3 header information.

In part 1, we experimented with Mininet using its internal controller. In this (and future) parts, we will instead be using our own controller to send commands to the switches. We will be using the POX controller, which is written in Python.

For this assignment you will create a simple firewall using OpenFlow-enabled switches. The term “firewall” is derived from building construction: a firewall is a wall you place in buildings to stop a fire from spreading. In the case of networking, it is the act of providing security by not letting specified traffic pass through the firewall. This feature is good for minimizing attack vectors and limiting the network “surface” exposed to attackers. In this part, we will provide you with the Mininet topology, part2.py, to setup your network which assumes a remote controller listening on the default IP address and port number 127.0.0.1:6633. You do not need to (and should not) modify this file. The topology that this script will setup is as follows. Note that h1 and h4 are on the same subnet and a different one from h2 and h3.

A network diagram showing s1 connected directly to four hosts, h1, h2, h3, and h4, with a central controller

For part 2, we will also provide you with a skeleton POX controller: a1part2controller.py. This file will be where you will make your modifications to create the firewall. The boostrap should have setup a link from the ~/pox/pox/misc directory to ~/project-1/pox/a1part2controller.py. If no link is present at ~/pox/pox/misc/a1part2controller.py, you can create a new one by running ln -s ~/project-1/pox/* ~/pox/pox/misc/. You can then launch the controller with the command sudo ~/pox/pox.py misc.a1part2controller. Once the controller is running, you can run mininet with sudo python3 ~/project-1/topos/part2.py.

Using a terminal multiplexer like tmux or screen could be handy for running your controller in a separate terminal window within the VM. Alternatively you can just open multiple SSH connections too :)

The rules s1 will need to implement are as follows:

src ip dst ip protocol action
any ipv4 any ipv4 icmp accept
any any arp accept
any ipv4 any ipv4 - drop

Basically, your Firewall should allow all ARP and ICMP traffic to pass. However, any other type of traffic should be dropped. It as acceptable to flood the allowable traffic out all ports. Be careful! Flow tables match the rule with highest priority first, where priority is established based on the order rules are placed in the table. When you create a rule in the POX controller, you need to also have POX “install” the rule in the switch. This makes it so the switch “remembers” what to do for a few seconds. Do not handle each packet individually inside of the controller! Hint: To do this, look up ofp_flow_mod. The OpenFlow tutorial (specifically " Sending OpenFlow messages with POX") and the POX Wiki are both useful resources for understanding how to use POX.

The Ed board is a great place for swapping resources and asking questions about how to get POX and Mininet working. The goal is to learn networking, not suffer in silence while fighting with a new tool :)
Deliverables:
  1. (10 Points) A screenshot of the pingall command. Note that h1 and h4 should be able to ping each other (h2 and h3 as well), but not across subnets. Also, the iperf h1 h4 command should fail (as you’re blocking IP traffic). This is realized as the command hanging. Put your screenshot in the screenshots/part2 directory.
  2. (10 Points) A screenshot of the output of the dpctl dump-flows command. This should contain all of the rules you’ve inserted into your switch(es). Put your screenshot in the screenshots/part2 directory.
  3. (20 points) Your pox/a1part2controller.py file.

Submission

When you’re ready to turn in your assignment, do the following:

  1. Update the README.txt file to contain the names and UW netid of the member(s) of your team.
  2. Double check you are uploading the latest version of your code and screenshots.
  3. (Optional) If you’re submitting any extensions, make sure you submit them in addition to your regular submission materials as additional files in your archive, not overwriting the regular parts of the assignment!
  4. Archive your entire project-1 directory as a zip archive.
  5. Submit the archive as partner1netid_partner2netid.zip to Gradescope.

Extension 1: Backwards Learning

** Reminder: ** This part of the assignment is for intellectual curiosity only, and is neither part of the grade nor extra credit. As an extenion it’s less fully documented than the main assignment, so please ask questions as needed!

While flooding does allow for establishing connectivity, it wastes link resources with useless packets not destined for the link endpoint. One common approach to lessen the necessity of flooding is backwards learning, where a switch keeps track of the source address of frames it receives, and learns to associate the source addresses with particular ports. When a packet is received for one of the known addresses, it can be sent out the single port rather than flooded.

For this extension, implement backwards learning with the switch s1 and your controller.

  • What is the runtime computational complexity of your solution?
  • What is the runtime memory complexity of your solution in the controller?
  • What is the runtime memory complexity of your solution on the switch?
  • Can your solution handle mobile hosts, which move from port to port (like a phone attached to a building-scale WiFi deployment?)
Deliverables:
  1. Create a new controller file for this part, called a1ext1controller.py in the pox directory implementing your backwards learning logic.
  2. Add the answers to the posed questions as a new section in your README file.

Extension 2: Redundant Paths and Topology

** Reminder: ** This part of the assignment is for intellectual curiosity only, and is neither part of the grade nor extra credit. As an extenion it’s less fully documented than the main assignment, so please ask questions as needed!

So far we have only looked at a simple network with a single switch and no redundant paths between hosts. Consider the following slightly more complex topology, with redundant paths between S1 and S2 and an intermediate switch S3:

[h1@10.0.1.2/24][h2@10.0.0.2/24]        [h3@10.0.0.3/24][h4@10.0.1.3/24]
\                \                            /          /
 \                \                          /          /
  \                \----{s1}----------------/          /
   \-------------------/ | \\-------{s2}--------------/
                         |  \        /
                         |   \-{s3}-/
                         |    /
                    (controller)

A large challenge with redundant L2 paths is the issue of network loops, where a frame cycles infinitely in the network. One straightforward approach is to compute a spanning tree of the network, and only use the links on the spanning tree. This would allow you to at least keep the redundant link available as a backup in case there were a failure in the primary link. Can you program a controller that implements the spanning tree solution? If so, does your controller pick an optimal spanning tree? For which optimality criteria and with what workload assumptions?

While spanning tree allows for connectivity without forwarding loops in the presence of link cycles, it wastes the capacity of the redundant link, essentially pretending like it’s not there. Can you think of a different approach that could leverage the redundant capacity? How does your alternative approach prevent loops? Can you implement it?

Deliverables:
  1. Create a new topology file for this part, called ext2.py in the topos directory creating this more complex topology.
  2. Create a new controller file for this part, called a1ext2controller.py in the pox directory implementing your controller logic.
  3. Add the answers to the posed questions as a new section in your README file.