CS 485/585 (ECE 440) Computer Networking - Lab 3

CS 485/585 (ECE 440) Computer Networking, Fall 2018

Lab 3 - due Friday November 2 @ midnight

Please meet with your group members and get started on the lab as soon as possible. In general, in this class you will have about 2 weeks from the lab release date until the due date.

Accessing Your Group's Repository for this Lab

I have created a Git repository for each group. You should have already received an invite to access your repository on LoboGit. If you did not receive such an invite, contact me immediately.

The name of your repository will be teamXX, where XX are digits. You should be able to view the repository online at https://lobogit.unm.edu/net-f18/lab3/teamXX.

You will use the git tool on Linux to access the repository.

Cloning the Repository via HTTPS (Easy)

This is the easiest method of accessing your repository. Git will prompt you for your UNM NetID/password.

cd ~
mkdir -p net-f18
cd net-f18
git clone https://lobogit.unm.edu/net-f18/lab3/teamXX.git lab3
cd lab3

Here, you should be able to type "ls" (list files) and see the skeleton structure which your lab 3 submission should follow.

Cloning the Repository via SSH (More Difficult)

If you don't wish to type your NetID/password, you can instead use public-key authentication. First (if you haven't already done so), you need to create a key pair for public-key authentication (git will use this instead of username/password for authentication).

mkdir -p ~/.ssh
chmod 700 ~/.ssh
cd ~/.ssh
ssh-keygen -t rsa -b 4096 -C "YOUR_ADDRESS@unm.edu" -f id_rsa

(where YOUR_ADDRESS@unm.edu is your UNM email address). This creates a public key (id_rsa.pub) and a private key (id_rsa). KEEP YOUR PRIVATE KEY SECURE AT ALL TIMES! Open the public key (id_rsa.pub) in a text editor

pluma ~/.ssh/id_rsa.pub

and copy the contents into the "SSH Keys" section of your "Settings" on LoboGit. Once the public key is added on LoboGit, you can do

cd ~
mkdir -p net-f18
cd net-f18
git clone git@lobogit.unm.edu:net-f18/lab3/teamXX.git lab3
cd lab3

Here, you should be able to type "ls" (list files) and see the skeleton structure which your lab 2 submission should follow.

Setting up a Virtual Machine

For this lab, you will be given a virtual machine (VM) with sudo permissions, i.e., you will have administrative privileges (unlike on the CS lab machines). This will give you greater freedom in experimenting with the machine's protocol stack.

BE CAREFUL when using sudo on your machine! With great power comes great responsibility!

Your VM can only be reached via one of our classroom machines. If you are not in the classroom, you can access the machines remotely:

ssh -X username@b146-xx.cs.unm.edu

(where username is your CS username, and xx is between 01 and 76).

You will need at least two terminals open on the classroom machine, so either open a new terminal, or start a second SSH connection.

In one terminal, type the following commands

cd /b146vpn
openvpn b146fw-udp-1194.ovpn

and enter your CS username/password when prompted. This authenticates you with the virtual private network (VPN) needed to access your VM.

NOTE: if you get an error about the address already being in use, that means the VPN client is already running! In this case, just skip the VPN step and continue with the following instructions.

In the other open terminal, you should be able to log into your VM

ssh -X username@10.200.2.yyy

NOTE: Replace username with the username you've been sent via email (it should be the same as your NetID username). The 10.200.2.yyy is a unique IP address for your VM, which you will be sent via email. DO NOT try to log into a VM until you are assigned a username and IP address via email!

Your VM password is initially set PassXXXXXX!, where XXXXXX is the unique six-digit ID you were assigned via email at the beginning of the class. The first time you log in, you will be asked to change your password. When asked for "Current UNIX password", repeat the PassXXXXXX! password, and then you'll be asked to type a new password twice. The new password can be anything you want (this VM account is not connected to your UNM account, or your CS account -- the VM will only be used in this class).

Once you are logged into your VM, install some utilities:

sudo apt-get install mininet xterm pcapfix python-dpkt python-numpy python-cairo make gnuplot texlive-latex-extra mupdf xpdf evince graphviz iperf3 bridge-utils

sudo sed "s/disable_lua = false/disable_lua = true/g" -i /usr/share/wireshark/init.lua

sudo sed "s/stp_enable=true' %/stp_enable=true' #%/g" -i /usr/lib/python2.7/dist-packages/mininet/node.py

mkdir -p ~/git && cd ~/git
git clone https://github.com/hgn/captcp.git
cd captcp
sudo make install
cd ~

Part 1 - Basic Forwarding in Mininet (30 points)

In the previous lab, we used Mininet to create a virtualized network, where hosts could communicate with each other. There, we used bridge devices to simulate simple switching behavior. In this lab, we will instead use Layer 3 switches (routers), which allow us to customize what paths packets are forwarded on in the network. In particular, we will use OpenFlow 1.0 software switches in Mininet.

First, on your VM, build the OpenFlow utilities:

sudo apt-get install autoconf pkg-config

git clone https://github.com/mininet/openflow.git
cd openflow
sed "s/TABLE_LINEAR_MAX_FLOWS[^0-9]*[0-9]\+/TABLE_LINEAR_MAX_FLOWS 10000/g" -i udatapath/chain.h
./boot.sh
./configure LIBS=-lrt
make
sudo make install
cd ..

This should install several utilities, the main one being ofdatapath, the switch implementation that we will use in Mininet. These are software-defined networking (SDN) switches, so a basic SDN controller is also provided. For now, we will NOT use the SDN functionality! Don't start the controller for the remainder of this lab (it will modify the forwarding rules on your switches).

To start Mininet using the OpenFlow switches, do the following:

sudo mn --switch=user --controller=remote --topo=tree,depth=2,fanout=2

You can now use the dpctl utility to add forwarding rules to the switches. For example, in another terminal (or in a Mininet xterm), you can type:

sudo dpctl add-flow unix:/tmp/s2 "idle_timeout=0,hard_timeout=0,in_port=1,ip,nw_src=10.0.0.1,nw_dst=10.0.0.3,actions=output:3"
sudo dpctl add-flow unix:/tmp/s1 "idle_timeout=0,hard_timeout=0,in_port=1,ip,nw_src=10.0.0.1,nw_dst=10.0.0.3,actions=output:2"
sudo dpctl add-flow unix:/tmp/s3 "idle_timeout=0,hard_timeout=0,in_port=3,ip,nw_src=10.0.0.1,nw_dst=10.0.0.3,actions=output:1"

sudo dpctl add-flow unix:/tmp/s2 "idle_timeout=0,hard_timeout=0,in_port=1,arp,nw_src=10.0.0.1,nw_dst=10.0.0.3,actions=output:3"
sudo dpctl add-flow unix:/tmp/s1 "idle_timeout=0,hard_timeout=0,in_port=1,arp,nw_src=10.0.0.1,nw_dst=10.0.0.3,actions=output:2"
sudo dpctl add-flow unix:/tmp/s3 "idle_timeout=0,hard_timeout=0,in_port=3,arp,nw_src=10.0.0.1,nw_dst=10.0.0.3,actions=output:1"

sudo dpctl add-flow unix:/tmp/s3 "idle_timeout=0,hard_timeout=0,in_port=1,ip,nw_src=10.0.0.3,nw_dst=10.0.0.1,actions=output:3"
sudo dpctl add-flow unix:/tmp/s1 "idle_timeout=0,hard_timeout=0,in_port=2,ip,nw_src=10.0.0.3,nw_dst=10.0.0.1,actions=output:1"
sudo dpctl add-flow unix:/tmp/s2 "idle_timeout=0,hard_timeout=0,in_port=3,ip,nw_src=10.0.0.3,nw_dst=10.0.0.1,actions=output:1"

sudo dpctl add-flow unix:/tmp/s3 "idle_timeout=0,hard_timeout=0,in_port=1,arp,nw_src=10.0.0.3,nw_dst=10.0.0.1,actions=output:3"
sudo dpctl add-flow unix:/tmp/s1 "idle_timeout=0,hard_timeout=0,in_port=2,arp,nw_src=10.0.0.3,nw_dst=10.0.0.1,actions=output:1"
sudo dpctl add-flow unix:/tmp/s2 "idle_timeout=0,hard_timeout=0,in_port=3,arp,nw_src=10.0.0.3,nw_dst=10.0.0.1,actions=output:1"

Note - you can look at the forwarding rules on a specific switch:

sudo dpctl dump-flows unix:/tmp/s2

After adding the above rules, in Mininet, you should be able to do

h1 ping h3

and see the pings succeed. These dpctl commands have added forwarding rules to switches s1, s2, and s3, which allow packets to flow from h1 to h3. Please check out the dpctl man page for useful information about how the forwarding rules are formatted, etc.

man dpctl

Task A - Write a simple program (in Java/C/Python) which takes as input depth and fanout arguments, and produces the forwarding rules (in the dpctl format) which allow communication between all of the hosts in Mininet for a topology with that depth and fanout. In other words, after installing the forwarding rules, pingall should succeed in Mininet.

NOTE - there is apparently a bug in Mininet that breaks TCP when you're using the OpenFlow switches. If you want to start a TCP connection, e.g., run netcat or iperf between h1 and h3, you will need to run the following command on each host you want to use:

ethtool -K `ifconfig | head -n 1 | cut -d" " -f 1` tx off

Part 2 - Broadcast Routing using the Omnet++ Network Simulator (30 points)

In this part of the lab, we will gain some experience using the network simulator Omnet++. This approach is different than Mininet, in that the simulator runs everything in a user-space software program (Mininet, on the other hand, uses your machine's networking stack). This is useful in many ways - for example, it gives us more fine-grained control over timing in our experiments.

First, install Omnet++ on your VM. This will take quite a long time (upwards of 30 minutes on my VM):

sudo apt-get install qtdeclarative5-dev qt5-default openscenegraph libopenscenegraph-dev osgearth libosgearth-dev tk-dev flex bison gcc g++ default-jdk libpcap-dev

wget https://www.cs.unm.edu/~jrmcclurg/class/omnetpp-4.6-src.tgz

tar -xvf omnetpp-4.6-src.tgz
cd omnetpp-4.6

. setenv
./configure CC=gcc CXX=g++
make

echo export PATH=\$PATH:`pwd`/bin >> ~/.bashrc
cd ..

If all goes well, you should now have a command called omnetpp which starts the simulator.

Task A - Create a new Omnet++ project using the skeleton source files provided in your repository. This simulates broadcast routing, and demonstrates a broadcast storm - a problematic situation in which packets circulate indefinitely. Your task is to graph the number of packets being sent versus time (for each node), and observe just how extreme the situation can get. Information about how to graph things is here.

To create the new project:

  • File -> New Omnet++ Project
  • Name: lab3
  • Next -> Empty project with src and simulations folders
  • Finish
  • Delete src/package.ned from the project
  • Put mynode.cc, basic.msg, lab3.ini, lab3.ned (from the broadcast folder in your repository) in src
  • Select src
  • Project -> Build All
  • Run -> Run As -> Omnet++ Simulation
  • OK

Task B - Modify the code to eliminate the broadcast storm, using, e.g., a technique based on sequence numbers or reverse path forwarding. Documentation for the Omnet++ API is here.

Part 3 - Link-State Routing (30 points)

In this part of the project, we will implement a link-state routing protocol. The Java code included in your repository allows you to load a DOT topology such as example.dot (by using the File -> Open menu), and modify link costs by selecting a link(s) and pressing the up/down arrows. Nodes can be moved by dragging. The topology can be exported to a new DOT file by using the File -> Save menu.

You can run the code as follows:

javac *.java
java Simulator example.dot

Task A - Add code to the runLinkState() method in Network.java which runs a link state algorithm to statically determine the lowest-cost paths for fowarding in the network. Your code should call setNexts(map) on each node, giving it a mapping map from destinations to next hops. In other words map.get(dst) should return a node nxt which is the next hop in the path to destination node dst. One algorithm you might want to look at is Floyd-Warshall.

Right-clicking on two hosts allows you to see the computed shortest-path between them. The path will be updated as you modify link costs, etc. If you want to turn off this auto-update behavior, run the program like this (you will then be given a menu item which allows you to manually run your link-state algorithm):

java Simulator example.dot -noauto

Part 4 - Documentation (10 points)

Clearly document (using source-code comments) all of your work. Also fill in the README.md file (preferably using Markdown syntax) with a brief writeup about the design choices you made in your code.

Providing adequate documentation helps me see that you understand the code you've written.

Part 5 - EXTRA CREDIT - Distance-Vector Routing in Omnet++ (20 EXTRA points)

Using Part 2 of this lab as a starting point, create a simulation in Omnet++ that shows how the basic distance-vector routing algorithm works. The simulation should build the forwarding tables on each node (actual routing based on the contents of the forwarding tables is not required).