Tutorial

In this section, we shall emulate some simple topologies and run network experiments on them using NeST. In doing so, we shall cover some of the most commonly used APIs in NeST.

Let’s begin by building a simple topology with just 2 nodes.

1. Peer-to-Peer topology (p2p)

Below is the ASCII representation of the topology:

n1 ---- n2

Above, we have two nodes, n1 and n2 connected via an ethernet cable. Let’s build this topology using NeST!

i) Building topology

Open a blank file in your favorite editor. You may name this file as p2p.py. In the tutorial, we shall give small snippets of code which you can copy-paste into the editor one by one. The entire source code will be given at the end.

The very first step is to import NeST:

from nest.experiment import *
from nest.topology import *

The topology submodule in NeST provides APIs to build emulated network topologies, and the experiment submodule provides APIs to run network experiments in the emulated topologies.

Next, let’s create the two nodes, n1 and n2:

n1 = Node("n1")
n2 = Node("n2")

Node is a class defined in NeST which emulates a node internally. Note that Node takes a string parameter, representing the node name. This will be needed later while using the experiment module. (Internally, Node uses network namespaces for emulation. Refer Introduction to Developer docs to know more).

Now that two nodes are created, let’s connect them using “virtual ethernet cables” (veth pairs):

(n1_n2, n2_n1) = connect(n1, n2)

The connect API firstly creates a veth pair, which are two network interfaces connected to each other. Next, it assigns one of the interfaces to n1 and the other interface to n2. So, n1_n2 interface is present in n1 and n2_n1 interface is in n2. And since n1_n2 and n2_n1 are two endpoints of a virtual ethernet cable, n1 and n2 are now connected to each other!

We are just one step away from sending packets between n1 and n2. We will need to assign addresses to each of the interfaces first:

n1_n2.set_address("10.0.0.1/24")
n2_n1.set_address("10.0.0.2/24")

We have assigned address 10.0.0.1 to n1_n2 and 10.0.0.2 to n2_n1. The /24 in the address specifies the subnet and we want both interfaces to be in the same subnet.

And congrats, you have successfully built the topology! Let’s run the python program to verify. Save the p2p.py file, fire up your terminal and run the below command in the same directory as the p2p.py file:

$ sudo python3 p2p.py
[INFO] : Cleaned up environment!

If you get output shown above, then the program ran successfully for you! If not, then there is likely an error in the way NeST was installed. Please refer Installation and ensure that you have run all the required steps.

When the above program was run, the required topology was created by NeST. On exit, as the output of the program indicates, this topology is deleted. But just creating a topology is not useful, let’s generate network traffic in this topology and visualize the various parameters in the traffic as plots.

The p2p.py upto this point should contain the following:

from nest.experiment import *
from nest.topology import *

n1 = Node("n1:)
n2 = Node("n2")

(n1_n2, n2_n1) = connect(n1, n2)

n1_n2.set_address("10.0.0.1/24")
n2_n1.set_address("10.0.0.2/24")

ii) Running network experiment

Firstly, let’s set some delay and bandwidth to the link between n1 and n2:

n1_n2.set_attributes("5mbit", "5ms")
n2_n1.set_attributes("10mbit", "100ms")

The first API call, n1_n2.set_attributes("5mbit", "5ms") sets the bandwith to be 5 mbit and delay to be 5 ms in the link, in the direction of n1 to n2.

The second API call sets the bandwidth and delay in the link, in the direction of n2 to n1. Note that the bandwidth and delay need not be the same in both directions, as in real-life scenario where download bandwidth are typically higher than upload bandwidth.

Next, let’s define a Flow object, representing the network traffic to be generated in the topology:

flow = Flow(n1, n2, n2_n1.address, 0, 60, 2)

The above API defines a flow between the two nodes n1 and n2. The parameters of Flow are: source_node, destination_node, destination_address, start_time, stop_time and number_of_streams.

Hence, we have defined a flow from n0 to n1 for a duration of 60 seconds, starting at 0s and with 2 streams. The start time and stop time may seem irrelevant for specifying the duration of flow, but they are useful for scenrios where we have mutiple flows with different start and stop times.

Note that we just defined a Flow object above, it doesn’t actually create the network traffic. We shall do that below:

exp = Experiment('tcp_2up')
exp.add_tcp_flow(flow)

exp.run()

First we create an Experiment object. Note that it takes in string parameter for experiment name. We have named it as ‘tcp_2up’ since we are generating a flow with 2 streams from n1 to n2.

Next, we add the previously defined flow object in the experiment exp using the add_tcp_flow API. Note that the default TCP congestion algorithm used is cubic.

Finally, we run the experiment with exp.run(). Now the defined flow will run on the emulated topology. Let’s run the program and check the output we get!

The p2p.py at this point should be:

from nest.experiment import *
from nest.topology import *

n1 = Node('n1')
n2 = Node('n2')

(n1_n2, n2_n1) = connect(n1, n2)

n1_n2.set_address('10.0.0.1/24')
n2_n1.set_address('10.0.0.2/24')

n1_n2.set_attributes('5mbit', '5ms')
n2_n1.set_attributes('10mbit', '100ms')

flow = Flow(n1, n2, n2_n1.address, 0, 60, 2)

exp = Experiment('tcp_2up')
exp.add_tcp_flow(flow)

exp.run()

Save the p2p.py file and run the below command in your terminal:

$ sudo python3 p2p.py

[INFO] : Running experiment tcp_2up
[INFO] : Running 2 netperf flows from n1 to 10.0.0.2...
[INFO] : Running ss on nodes...
[INFO] : Experiment complete!
[INFO] : Parsing statistics...
[INFO] : Output results as JSON dump
[INFO] : Plotting results...
[INFO] : Plotting complete!
[INFO] : Cleaned up environment!

We have run a network experiment on our topology! You will find a folder generated by NeST whose name looks similar to: tcp_2up(12-01-2021-12:29:34)_dump. The name will wary slightly based on the time you ran the NeST program.

Inside this folder, you will find the stats collected by NeST. The contents of the folder should be as follows:

$ ls -1 tcp_2up(12-01-2021-12.29.34)_dump
netperf/
netperf.json
ping/
ping.json
README.txt
ss/
ss.json
README.txt

That’s a handful of files! Among all those files, we see a file called README.txt. This file describes in detail the contents of the files in the folder. We highly urge you to read this file to get a better idea of the stats obtained by NeST.