Project 3: Bufferbloat
Turnin: Online
Teams: Teams of 2 or 3

Overview

In this project, we will use Mininet to study the bufferbloat phenomenon. We will compare the performance of TCP Reno and TCP BBR over a network with slow uplink connection.

For part 1, you will set up a mininet VM and clone the starter code for running the experiment. For part 2, you will implement a mininet network in which the nodes connect over TCP Reno connections. After you complete the TODO fields in the skeleton code, you will generate experiment results using the framework, and answer the related questions. For part 3, you will rerun the experiment using TCP BBR.

Background

For general background on Bufferbloat, look at the following article: BufferBloat: What's Wrong with the Internet?. View this refresher on how to work with the Mininet environment and the official documentation of Mininet Python API.

Introduction

In this project we will study the dynamics of TCP in home networks. Take a look at the figure below which shows a "typical" home network with a Home Router connected to an end host. The Home Router is connected via Cable or DSL to a Headend router at the Internet access provider’s office. We are going to study what happens when we download data from a remote server to the End Host in this home network.

A network diagram of the Home network host connected to a home router which is connected using a DSL cable to the Headend router in the cloud connected to the target server.

In a real network it’s hard to measure cwnd (because it’s private to the server) and the buffer occupancy (because it’s private to the router). To ease our measurement, we are going to emulate the network in Mininet.

Goals

  • Learn first-hand the dynamics of TCP sawtooth and router buffer occupancy in a network.
  • Learn why large router buffers can lead to poor performance. This problem is often called "bufferbloat."
  • Learn the difference between TCP Reno and TCP BBR and how they perform compared to the other.
  • Learn how to use Mininet to create network topologies, run traffic generators, collect statistics and plot them.
  • Learn how to package your experiments so it’s easy for others to run your code.

Part 1: Setup

Mininet VM Installation

To manage the virtual machine, we’ll be using a tool called multipass. If you’re using a flavor of Linux or MacOS, you may be able to install instead via package manager or brew, respectively. You can find link to install multipass here.

OR

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.

Many of the issues that we've seen related to Project 3 can be resolved by following the commands
1. Install a clean new Ubuntu focal VM with multipass: multipass launch --name=project3 focal
2. Start it and copy file in the VM: install.sh
3. Run chmod +777 install.sh and then run ./install.sh - You should be good to go!


Starter Code

In vagrant home directory, download the starter code.

$ cd ~
$ wget https://courses.cs.washington.edu/courses/cse461/24wi/assignments/project3/project3.zip
$ unzip project3.zip

Do not run the starter code unless you fill in code to create a topology in the class BBTopo. Otherwise, it will fail.

In the folder, you should find the files below. bufferbloat.py and run.sh are the only files you need to modify.

File Purpose
run.sh Runs the experiment and generates all graphs in one go.
bufferbloat.py Creates the topology, measures cwnd, queue sizes and RTTs and spawns a webserver.
monitor.py Monitor the queue length
plot_queue.py Plots the queue occupancy at the bottleneck router.
plot_ping.py Parses and plots the RTT reported by ping.
plot_defaults.py Utility functions for creating pretty plots
helper.py Utility functions for plot scripts
webserver.py The script that starts the server
index.html The index file for our server
README Where you will write the instructions of the scripts and answers to the questions.

We will be using python3 for this project. Install the necessary packages using the commands below:

$ sudo apt-get update
$ sudo apt install python3-pip
$ sudo python3 -m pip install mininet matplotlib

Part 2: TCP Reno

Within Mininet, create the following topology. Here h1 is your home computer that has a fast connection (1Gb/s) to your home router with a slow uplink connection (1.5Mb/s). The round-trip propagation delay, or the minimum RTT between h1 and h2 is 20ms. The router buffer size can hold 100 full sized ethernet frames (about 150kB with an MTU of 1500 bytes).

Mininet topology showing the h1 home computer that has a fast connection to home router with a slow uplink connection to h2

Then do the following:

  • Start a long lived TCP flow sending data from h1 to h2. Use iperf/iperf3.
  • Start back-to-back ping train from h1 to h2 10 times a second and record the RTTs.
  • Plot the time series of the following:
    • The RTT reported by ping
    • Queue size at the bottleneck
  • Spawn a webserver on h1. Periodically download the index.html web page (three times every five seconds) from h1 and measure how long it takes to fetch it (on average). The starter code has some hints on how to do this. Make sure that 1) the webpage download data is going in the same direction as the long-lived flow and 2) the curl command successfully fetches the webpage.
  • The long lived flow, ping train, and webserver downloads should all be happening simultaneously.

Repeat the above experiment and replot all two graphs with a smaller router buffer size (Q=20 packets).

Note

  • Always run the script using sudo sudo ./run.sh

  • If your Mininet script does not exit cleanly due to an error (or if you pressed Control-C), you may want to issue a clean command sudo mn -c before you start Mininet again.

Part 2 Questions

Include your answers to the following questions in your README file. Remember to keep answers brief.

  1. What is the average webpage fetch time and its standard deviation when q=20 and q=100?
  2. Why do you see a difference in webpage fetch times with short and large router buffers?
  3. Bufferbloat can occur in other places such as your network interface card (NIC). Check the output of ifconfig eth0 of your mininet VM. What is the (maximum) transmit queue length on the network interface reported by ifconfig? For this queue size, if you assume the queue drains at 100Mb/s, what is the maximum time a packet might wait in the queue before it leaves the NIC?
    You can run ifconfig in the mininet shell by inserting CLI(net) in your script and run it. When the shell launches, for example, run h1 ifconfig to run the command on host h1.
  4. How does the RTT reported by ping vary with the queue size? Describe the relation between the two.
  5. Identify and describe two ways to mitigate the bufferbloat problem.

Part 3: TCP BBR

In this part, we will try to mitigate the bufferbloat problem by using TCP BBR. TCP BBR is a TCP congestion control algorithm developed by Google in 2016. It uses Bottleneck Bandwidth and Round-trip propagation time as an indicator of congestion, in contrast to other loss-based algorithms which use packet loss.

  • Create a new copy of run.sh and call it run_bbr.sh.

  • Modify the shell script to pass bbr as an argument to bufferbloat.py. It accepts --cong for congestion control algorithm. In part 2, TCP Reno is the default value.

  • Run the script and answer the questions below.

Part 3 Questions

  1. What is the average webpage fetch time and its standard deviation when q=20 and q=100?

  2. Compare the webpage fetch time between q=20 and q=100 from Part 3. Which queue length gives a lower fetch time? How is this different from Part 2?

  3. Do you see the difference in the queue size graphs from Part 2 and Part 3? Give a brief explanation for the result you see.

  4. Do you think we have solved bufferbloat problem? Explain your reasoning.

Deliverables

  • Final Code: Remember one of the goals of this assignment is for you to build a system that is easy to type run to reproduce results. Therefore, your final code MUST be runnable as a single shell command (sudo ./run.sh and sudo ./run_bbr.sh).
  • README: A file named README with instructions to reproduce the results as well as the answers to the questions in the previous section. Please identify your answers with the question number, and please keep your answers brief.
  • Plots: There should be 8 plots in total, 4 for part 2 and 4 for part 3. For each part, there are 2 for router buffer sizes 100 and 20 packets. They MUST have the following names and be present in the top level directory of your submission folder.
    • reno-buffer-q100.png, reno-rtt-q100.png
    • reno-buffer-q20.png, reno-rtt-q20.png
    • bbr-buffer-q100.png, bbr-rtt-q100.png
    • bbr-buffer-q20.png, bbr-rtt-q20.png

Submission

Archive the materials (code, README, and plots) into a single .zip file named {{ uwnetid1_uwnetid2_uwnetid3 }}.(zip) and submit it on canvas. Submit only one submission per group