Select Page

In our last article, we continued work on our virtual workspace by installing and using Postman with Ryu’s REST API. This time, we are going to look at creating custom Mininet topologies by writing Mininet profiles in Python. Now that we are creating and modifying code and will need some additional project organization, we will start using Atom as our base editor and IDE. We are choosing Atom here because it’s expandable, contains all the features we need for developing OpenFlow controller applications, and is available for all major platforms. This article and future articles will show screenshots and videos with interacting with Atom as the editor, but you are more than welcome to use a different editor if you like.

We’ve also added an overview video for this article:

Atom Setup

Why Atom

For many coders, which editor or IDE we use is a very personal decision and is usually based on many factors, such as ease of use, features, and hackability. Through a console, several options are usually available, such as Vim, Nano, and even Emacs (if you’re in to that sort of thing ;-)). But if such a wonderful editor like Vim is available, why use Atom? Simply put, Atom takes advantage of newer web technologies and has lowered the barrier of entry for plugin developers, which has allowed for not only the basic highlighting of many programming languages, but also interfaces with linters, compilers, and debuggers. There are even plugins that allow different input modes, such as Vim-like keybindings. Further, Atom has deep integration with git and allows for better collaborative development. Personally, I switched from Vim to Atom for everyday use because it has nearly everything I want, and anything it doesn’t have is easy to code. We’ll be keeping in mind that not all our readers use Atom and will make sure no Atom-specific feature is required for following the guides, but we may show tips and tricks with Atom from time to time.

An Atom Setup video following along this section is also available:

Setting Up Atom

In our virtual workspace, installing Atom is almost exactly the same as installing Chrome or any other package in Ubuntu. Simply go to Atom.io, then download and install the package. As of this article, the latest release is version 1.8. For following along, we recommend installing the following packages:

  • Python Development
    • autocomplete-python – autocompletion powered by Jedi
    • linter-pylint – lint python using pylint, automatically installs linter
  • General Development
    • script – run code in atom
  • Quality of Life, completely optional, but seen in screenshots
    • file-icons – improved visual grepping
    • minimap – preview full source code
    • minimap-find-and-replace – integration with find and replace
    • minimap-git-diff – integration with git diff
    • minimap-linter – integration with linter
    • minimap-selection – show buffer’s selection on the minimap
    • vim-mode – vim modal control
    • ex-mode – Ex for vim-mode
    • hyperclick – Ctrl+click Go-to-Definition for autocomplete-python

These can be installed by opening up the Settings tab by pressing Ctrl+, or pressing Ctrl+Shift+P and searching for Settings. Click on Install on the left side of the Settings tab, then search for each package in the list and click its Install button.

The only package that really needs configuration is autocomplete-python and that is to make sure it can find Mininet’s definitions. In the Settings tab, click Packages on the left, and click the “Settings” button in the autocomplete-python card. Scroll down to “Extra Paths for Packages” and enter the location where you cloned Mininet’s repository for manual installation back in Creating a Development Workspace. If you used the exact directories in that article, the location should be /home/<username>/ofworkspace/mininet where <username> is your username in the workspace.

Finally, the hyperclick documentation states that the “highlight” and “perform action” keybindings are using the Alt key. On Linux, it is actually using Ctrl as Alt is used to move windows. In any case, just Ctrl+click a variable in a Python source file to go to its definition if hyperclick is installed. Without hyperclick, you can still use the go-to-definition feature by clicking on, or moving your cursor into, the variable name then pressing Ctrl+Alt+G.

Poking Around Ryu and Mininet

If you are feeling adventurous, feel free to add Ryu’s and Mininet’s sources as project folders in Atom. To do this, click File -> Add Project Folder for each of these projects. If you followed the directions from Creating a Development Workspace, these folders should be in the ofworkspace folder of your home folder. Alternatively, you can add project folders through the command line:

If Atom was not already open, the first atom command will start it. Further atom -a commands will add the project folder to the most recently used Atom window.

Atom Tip – Pending Tabs

When browsing files in Atom, the files will load in a Pending tab. If you do not make any changes to the current file, and then select a different file to view, the contents of the tab will be replaced rather than opening a new tab. This is generally useful when just browsing code, but if you want to keep the tab, right click the tab and click “Keep Pending Tab”. Editing the contents of the tab will automatically cause Atom to keep the tab and opening a new fill will open a new tab.

Defining Mininet Topologies

Now that we have an editor set up, let’s look at how Mininet Topologies are defined. From the previous examples, we’ve been running mininet using only command line options, like this:

This actually works pretty well for simple tests. There are even more complicated topologies that are built in to Mininet, including Tree and Torus. Let’s say we want a custom topology that might reflect a real-world network. Thankfully, Mininet provides a rich scripting environment that makes emulating custom topologies very simple.

Downloadable Content – Full Source Code and Tests

We recommend following along below by typing in the code yourself. After all, you can often learn a lot more by making mistakes and fixing them than just running something from an archive! We also understand that sometimes you just don’t have time for that or may get stuck with a specific example. For this, we have an archive of all the files listed in this article, plus a test script to ensure each works properly.

Download Example Mininet Topologies

To use, simply extract the archive in your workspace:

Replace the filename in the unzip command to the downloaded file location and version number.

Creating a Mininet Project

While experimenting with topologies, we will need a place to store the topology scripts. Let’s create a new directory under our workspace directory:

If you are using Atom, go ahead and add this as a project folder:

Now on to our first topology.

Simple Topology Creation

Before getting into more advanced topologies, let’s create the simplest Mininet script that will allow us to apply a topology and give us a CLI prompt like the Mininet commands we’ve been running so far. Create a new file called ‘minimal.py’ in the Mininet Topologies project directory created above.

With this script, there are a couple options to run it. First, make sure Ryu is running in a separate terminal with the OF1.3 version of simple switch and optionally the REST API:

The last line in the script provides a hook to the mn command that allows it to be imported and the custom topology to be used:

topo-1

But what if we wanted a script to automatically set up the network with the options we’ve been providing the mn command all this time? We can add a bit more to the script:

The script can now be run directly and it will run the runSimpleTopo function, which sets up the global network defaults for us:

topo-2

You can do a lot with scripting the creation of the Mininet network such as automated testing, automatically starting Ryu and more. For simplicity’s sake in this article, we will keep to the first form and use the mn command. We will touch on automated environments in a future article.

Atom Tip – Auto-Completion and Documentation

If you typed the source for minimal.py above, you may have noticed that many of the commands gave you auto-completion results and documentation on the functions specified. This is one of the reasons why having an integrated editor really helps when writing code not only for Mininet and Ryu, but other projects as well.

atomtip-2-crop

Also, remember that you can Ctrl+click (Alt+click on Windows) nearly any function or variable to jump to where it is defined, even if it is an imported library.

Building a Datacenter Topology

In this topology, we have four racks, each with four hosts and a single top-of-rack (ToR) switch. These ToR switches are connected to a central root switch. This represents a simple datacenter.

This topology isn’t all that different from a standard tree topology, but it does demonstrate how to write a topology that is closer to a real network. Ryu’s simple switch shouldn’t have any problem managing this either:

topo-3

In order to keep track of which host belongs to which rack, the names of the hosts and switches are customized. All switches still start with s#, but is suffixed by the rack specified as r#. the only switch that doesn’t have a rack suffix is the root switch. Additionally, the hosts are named similar so that h3r2 means host 3 on rack 2.

Making the Topology Configurable

Our previous topology is a bit too rigid and static. Let’s add the ability to specify how many hosts we want in each rack and how many racks in our network straight from the command line.

topo-4

The topology configuration is in the form of dsconfig,<numRacks>,<numHostsInRack> and can be specified as just dsconfig for the default of 4 and 4. You could also only specify the number of racks and use the default hosts-per-rack like dsconfig,6 (6 racks, 4 hosts per rack).

Adding Redundant Links

In a real datacenter, you will most often have more than one root switch linked in a ring pattern with at least two links going to each ToR switch. This allows for a failure of one of your root switches without bringing down your entire network. Implementing that is simple enough:

However, this does create a problem: loops. Just adding the topology now will cause the network to crumble because our simple switch doesn’t have any basic loop management such as STP. If you kept the original Ryu controller running, you may notice a flood of packets being reported. You may have to press Ctrl+C repeatedly in order for it to stop.

topo-5

Thankfully, Ryu includes a simple switch implementation with STP. Stop the existing Ryu controller and start a new one loading the ryu.app.simple_switch_stp controller application. Note that this example STP switch app only supports OF 1.0, though the library it uses supports OF 1.0 and 1.3.

Then in the other terminal, run Mininet again with the same mn command above. You will immediately see learning entries in the log. Running a pingall right away may result in some packet loss before the entire topology is learned by the controller.

topo-6

The first minute or so running the pingall command will result in packet loss while the controller is learning the network topology. Eventually, the pingall command will complete with no packet loss.

topo-7

Full Redundancy

As a final addition to our datacenter topology, let’s configure it so that every rack has two ToR switches, each connected with a single link to the root switches and provide every host with a connection to both ToR switches in that rack.

Run the topology:

After a few moments (look for FORWARD log entries in Ryu), run the pingall command and it should pass with no packet loss.

topo-8

While we have pingall passing here, it is important to note that we did not go into each host and configured some sort of link aggregation to actually prepare for a switch or link failure. This will be covered in future topics. This does demonstrate, however, that you can emulate nearly any network L2 topology fairly easily. In a real-world environment, STP is probably not the best protocol for HA networks and more advanced switch control would be needed in the controller or from the controller’s base libraries. For example, the ryu.app.simple_switch_stp example app uses an STP library provided by Ryu’s internals.

Automated Testing

Included in the downloadable content for this article is the full source for all the examples above and an automated test script that will test each of those examples. It will even start and stop Ryu with the appropriate controller applications loaded! We’ll be touching more on automated testing with Mininet in a later article, but take a look at the datacenterTests.py file for an example.

To run the tests, assuming you extracted the archive in ~/ofworkspace/, run:

At the end, you should see all tests pass:

mntest-1

You may notice that a couple of the tests (specifically the ones using STP) drop some packets. This is normal and the test allows 15 packets to drop to accommodate the learning period required. Feel free to play around with the test code and see if you can make it so the ping test always passes with zero packet loss. It is possible! =)

We’ve hoped you enjoyed this topic and that you will visit us for the next in the series where we start building our own pluggable Ryu controller app. Make sure to sign up to our mailing list to be notified when these articles are published. Also, please feel free to ask questions and leave comments below. We are always welcome to feedback so we can provide the best content possible.

As always, Happy Coding! =)

Share This