Examples to demonstrate how to configure queue disciplines (qdiscs) using NeST

This directory contains the following examples to understand how queue disciplines can be configured using NeST.

1. choke-point-to-point.py

This program emulates point to point networks that connect four hosts: h1

  • h4 via two routers r1 and r2. One TCP flow is configured from h1 to h3 and one UDP flow is configured from h2 to h4. It is similar to tcp-udp-point-to-point.py in examples/tcp. The links h1 <–> r1, h2 <–> r1, and r2 <–> h3, r2 <–> h4 are edge links. The link r1 <–> r2 is the bottleneck link with lesser bandwidth and higher propagation delays. This program demonstrates how to configure CHOose and Keep for responsive flows, CHOose and Kill for unresponsive flows (choke) queue discipline (qdisc) and obtain the relevant statistics. choke is enabled on the link from r1 to r2, but not from r2 to r1 because data packets flow in one direction only (left to right) in this example.

This program runs for 200 seconds and creates a new directory called choke-point-to-point(date-timestamp)_dump. It contains a README that provides details about the sub-directories and files within this directory. See the plots in netperf, ping and ss sub-directories for this program.

NOTE: This program does not generate the stats for choke qdisc because NeST does not support this feature yet.

Source code

  1# SPDX-License-Identifier: GPL-2.0-only
  2# Copyright (c) 2019-2022 NITK Surathkal
  3
  4########################
  5# SHOULD BE RUN AS ROOT
  6########################
  7from nest.topology import *
  8from nest.experiment import *
  9from nest.topology.network import Network
 10from nest.topology.address_helper import AddressHelper
 11
 12# This program emulates point to point networks that connect four hosts: `h1`
 13# - `h4` via two routers `r1` and `r2`. One TCP flow is configured from `h1` to
 14# `h3` and one UDP flow is configured from `h2` to `h4`. It is similar to
 15# `tcp-udp-point-to-point.py` in `examples/tcp`. The links `h1` <--> `r1`,
 16# `h2` <--> `r1`, and `r2` <--> `h3`, `r2` <--> `h4` are edge links. The link
 17# `r1` <--> `r2` is the bottleneck link with lesser bandwidth and higher
 18# propagation delays. This program demonstrates how to configure CHOose and
 19# Keep for responsive flows, CHOose and Kill for unresponsive flows (`choke`)
 20# queue discipline (qdisc) and obtain the relevant statistics. `choke` is
 21# enabled on the link from `r1` to `r2`, but not from `r2` to `r1` because
 22# data packets flow in one direction only (left to right) in this example.
 23
 24##############################################################################
 25#                              Network Topology                              #
 26#                                                                            #
 27#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 28# h1 --------------------|                          |-------------------- h3 #
 29#           TCP          |                          |         TCP            #
 30#                        |    <- 10mbit, 10ms ->    |                        #
 31#                         r1 -------------------- r2                         #
 32#                        |      choke qdisc -->     |                        #
 33#           UDP          |                          |         UDP            #
 34# h2 --------------------|                          |-------------------- h4 #
 35#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 36#                                                                            #
 37##############################################################################
 38
 39# This program runs for 200 seconds and creates a new directory called
 40# `choke-point-to-point(date-timestamp)_dump`. It contains a `README` that
 41# provides details about the sub-directories and files within this directory.
 42# See the plots in `netperf`, `ping` and `ss` sub-directories for this program.
 43
 44# Create four hosts `h1` to `h4`, and two routers `r1` and `r2`
 45h1 = Node("h1")
 46h2 = Node("h2")
 47h3 = Node("h3")
 48h4 = Node("h4")
 49r1 = Router("r1")
 50r2 = Router("r2")
 51
 52# Set the IPv4 address for the networks
 53n1 = Network("192.168.1.0/24")  # network consisting `h1` and `r1`
 54n2 = Network("192.168.2.0/24")  # network consisting `h2` and `r1`
 55n3 = Network("192.168.3.0/24")  # network between two routers
 56n4 = Network("192.168.4.0/24")  # network consisting `r2` and `h3`
 57n5 = Network("192.168.5.0/24")  # network consisting `r2` and `h4`
 58
 59# Connect `h1` and `h2` to `r1`, `r1` to `r2`, and then `r2` to `h3` and `h4`.
 60# `eth1` to `eth4` are the interfaces at `h1` to `h4`, respectively.
 61# `etr1a`, `etr1b` and `etr1c` are three interfaces at `r1` that connect it
 62# with `h1`, `h2` and `r2`, respectively.
 63# `etr2a`, `etr2b` and `etr2c` are three interfaces at `r2` that connect it
 64# with `r1`, `h3` and `h4`, respectively.
 65(eth1, etr1a) = connect(h1, r1, network=n1)
 66(eth2, etr1b) = connect(h2, r1, network=n2)
 67(etr1c, etr2a) = connect(r1, r2, network=n3)
 68(etr2b, eth3) = connect(r2, h3, network=n4)
 69(etr2c, eth4) = connect(r2, h4, network=n5)
 70
 71# Assign IPv4 addresses to all the interfaces in the network.
 72AddressHelper.assign_addresses()
 73
 74# Configure the parameters of `choke` qdisc.  For more details about `choke`
 75# in Linux, use this command on CLI: `man tc-choke`.
 76qdisc = "choke"
 77choke_parameters = {
 78    "limit": "100",  # set the queue capacity to 100 packets
 79    "min": "5",  # set the minimum threshold to 5 packets
 80    "max": "15",  # set the maximum threshold to 15 packets
 81}
 82
 83# Set the link attributes: `h1` and `h2` --> `r1` --> `r2` --> `h3` and `h4`
 84# Note: we enable `choke` queue discipline on the link from `r1` to `r2`.
 85eth1.set_attributes("1000mbit", "1ms")  # from `h1` to `r1`
 86eth2.set_attributes("1000mbit", "1ms")  # from `h2` to `r1`
 87etr1c.set_attributes("10mbit", "10ms", qdisc, **choke_parameters)  # from `r1` to `r2`
 88etr2b.set_attributes("1000mbit", "1ms")  # from `r2` to `h3`
 89etr2c.set_attributes("1000mbit", "1ms")  # from `r2` to `h4`
 90
 91# Set the link attributes: `h3` and `h4` --> `r2` --> `r1` --> `h1` and `h2`
 92eth3.set_attributes("1000mbit", "1ms")  # from `h3` to `r2`
 93eth4.set_attributes("1000mbit", "1ms")  # from `h4` to `r2`
 94etr2a.set_attributes("10mbit", "10ms")  # from `r2` to `r1`
 95etr1a.set_attributes("1000mbit", "1ms")  # from `r1` to `h1`
 96etr1b.set_attributes("1000mbit", "1ms")  # from `r1` to `h2`
 97
 98# Set default routes in all the hosts and routers.
 99h1.add_route("DEFAULT", eth1)
100h2.add_route("DEFAULT", eth2)
101h3.add_route("DEFAULT", eth3)
102h4.add_route("DEFAULT", eth4)
103r1.add_route("DEFAULT", etr1c)
104r2.add_route("DEFAULT", etr2a)
105
106# Set up an Experiment. This API takes the name of the experiment as a string.
107exp = Experiment("choke-point-to-point")
108
109# Configure one flow from `h1` to `h3` and another from `h2` to `h4`.
110flow1 = Flow(h1, h3, eth3.get_address(), 0, 200, 1)
111flow2 = Flow(h2, h4, eth4.get_address(), 0, 200, 1)
112
113# Use `flow1` as a TCP flow. TCP CUBIC is default in Linux.
114exp.add_tcp_flow(flow1)
115
116# Use `flow2` as a UDP flow, and set the rate at which it would send packets.
117exp.add_udp_flow(flow2, target_bandwidth="9mbit")
118
119# The following line enables collection of stats for the qdisc installed on
120# `etr1c` interface (connecting `r1` to `r2`), but it is commented because NeST
121# does not support stats collection for `choke` qdisc.
122# exp.require_qdisc_stats(etr1c)
123
124# Run the experiment
125exp.run()

2. codel-point-to-point.py

This program emulates point to point networks that connect four hosts: h1

  • h4 via two routers r1 and r2. One TCP flow is configured from h1 to h3 and one UDP flow is configured from h2 to h4. It is similar to tcp-udp-point-to-point.py in examples/tcp. The links h1 <–> r1, h2 <–> r1, and r2 <–> h3, r2 <–> h4 are edge links. The link r1 <–> r2 is the bottleneck link with lesser bandwidth and higher propagation delays. This program demonstrates how to configure Controlled Delay (codel) queue discipline (qdisc) and obtain the relevant statistics. codel is enabled on the link from r1 to r2, but not from r2 to r1 because data packets flow in one direction only (left to right) in this example.

This program runs for 200 seconds and creates a new directory called codel-point-to-point(date-timestamp)_dump. It contains a README that provides details about the sub-directories and files within this directory. See the plots in netperf, ping, ss and tc sub-directories for this program.

Source code

  1# SPDX-License-Identifier: GPL-2.0-only
  2# Copyright (c) 2019-2022 NITK Surathkal
  3
  4########################
  5# SHOULD BE RUN AS ROOT
  6########################
  7from nest.topology import *
  8from nest.experiment import *
  9from nest.topology.network import Network
 10from nest.topology.address_helper import AddressHelper
 11
 12# This program emulates point to point networks that connect four hosts: `h1`
 13# - `h4` via two routers `r1` and `r2`. One TCP flow is configured from `h1` to
 14# `h3` and one UDP flow is configured from `h2` to `h4`. It is similar to
 15# `tcp-udp-point-to-point.py` in `examples/tcp`. The links `h1` <--> `r1`,
 16# `h2` <--> `r1`, and `r2` <--> `h3`, `r2` <--> `h4` are edge links. The link
 17# `r1` <--> `r2` is the bottleneck link with lesser bandwidth and higher
 18# propagation delays. This program demonstrates how to configure Controlled
 19# Delay (`codel`) queue discipline (qdisc) and obtain the relevant statistics.
 20# `codel` is enabled on the link from `r1` to `r2`, but not from `r2` to `r1`
 21# because data packets flow in one direction only (left to right) in this
 22# example.
 23
 24##############################################################################
 25#                              Network Topology                              #
 26#                                                                            #
 27#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 28# h1 --------------------|                          |-------------------- h3 #
 29#           TCP          |                          |         TCP            #
 30#                        |    <- 10mbit, 10ms ->    |                        #
 31#                         r1 -------------------- r2                         #
 32#                        |      codel qdisc -->     |                        #
 33#           UDP          |                          |         UDP            #
 34# h2 --------------------|                          |-------------------- h4 #
 35#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 36#                                                                            #
 37##############################################################################
 38
 39# This program runs for 200 seconds and creates a new directory called
 40# `codel-point-to-point(date-timestamp)_dump`. It contains a `README` that
 41# provides details about the sub-directories and files within this directory.
 42# See the plots in `netperf`, `ping`, `ss` and `tc` sub-directories for this
 43# program.
 44
 45# Create four hosts `h1` to `h4`, and two routers `r1` and `r2`
 46h1 = Node("h1")
 47h2 = Node("h2")
 48h3 = Node("h3")
 49h4 = Node("h4")
 50r1 = Router("r1")
 51r2 = Router("r2")
 52
 53# Set the IPv4 address for the networks
 54n1 = Network("192.168.1.0/24")  # network consisting `h1` and `r1`
 55n2 = Network("192.168.2.0/24")  # network consisting `h2` and `r1`
 56n3 = Network("192.168.3.0/24")  # network between two routers
 57n4 = Network("192.168.4.0/24")  # network consisting `r2` and `h3`
 58n5 = Network("192.168.5.0/24")  # network consisting `r2` and `h4`
 59
 60# Connect `h1` and `h2` to `r1`, `r1` to `r2`, and then `r2` to `h3` and `h4`.
 61# `eth1` to `eth4` are the interfaces at `h1` to `h4`, respectively.
 62# `etr1a`, `etr1b` and `etr1c` are three interfaces at `r1` that connect it
 63# with `h1`, `h2` and `r2`, respectively.
 64# `etr2a`, `etr2b` and `etr2c` are three interfaces at `r2` that connect it
 65# with `r1`, `h3` and `h4`, respectively.
 66(eth1, etr1a) = connect(h1, r1, network=n1)
 67(eth2, etr1b) = connect(h2, r1, network=n2)
 68(etr1c, etr2a) = connect(r1, r2, network=n3)
 69(etr2b, eth3) = connect(r2, h3, network=n4)
 70(etr2c, eth4) = connect(r2, h4, network=n5)
 71
 72# Assign IPv4 addresses to all the interfaces in the network.
 73AddressHelper.assign_addresses()
 74
 75# Configure the parameters of `codel` qdisc.  For more details about `codel`
 76# in Linux, use this command on CLI: `man tc-codel`.
 77qdisc = "codel"
 78codel_parameters = {
 79    "limit": "100",  # set the queue capacity to 100 packets
 80    "target": "2ms",  # set the target queue delay to 2ms (default is 5ms)
 81    "interval": "24ms",  # set the interval value to 24ms (default is 100ms)
 82}
 83
 84# Set the link attributes: `h1` and `h2` --> `r1` --> `r2` --> `h3` and `h4`
 85# Note: we enable `codel` queue discipline on the link from `r1` to `r2`.
 86eth1.set_attributes("1000mbit", "1ms")  # from `h1` to `r1`
 87eth2.set_attributes("1000mbit", "1ms")  # from `h2` to `r1`
 88etr1c.set_attributes("10mbit", "10ms", qdisc, **codel_parameters)  # from `r1` to `r2`
 89etr2b.set_attributes("1000mbit", "1ms")  # from `r2` to `h3`
 90etr2c.set_attributes("1000mbit", "1ms")  # from `r2` to `h4`
 91
 92# Set the link attributes: `h3` and `h4` --> `r2` --> `r1` --> `h1` and `h2`
 93eth3.set_attributes("1000mbit", "1ms")  # from `h3` to `r2`
 94eth4.set_attributes("1000mbit", "1ms")  # from `h4` to `r2`
 95etr2a.set_attributes("10mbit", "10ms")  # from `r2` to `r1`
 96etr1a.set_attributes("1000mbit", "1ms")  # from `r1` to `h1`
 97etr1b.set_attributes("1000mbit", "1ms")  # from `r1` to `h2`
 98
 99# Set default routes in all the hosts and routers.
100h1.add_route("DEFAULT", eth1)
101h2.add_route("DEFAULT", eth2)
102h3.add_route("DEFAULT", eth3)
103h4.add_route("DEFAULT", eth4)
104r1.add_route("DEFAULT", etr1c)
105r2.add_route("DEFAULT", etr2a)
106
107# Set up an Experiment. This API takes the name of the experiment as a string.
108exp = Experiment("codel-point-to-point")
109
110# Configure one flow from `h1` to `h3` and another from `h2` to `h4`.
111flow1 = Flow(h1, h3, eth3.get_address(), 0, 200, 1)
112flow2 = Flow(h2, h4, eth4.get_address(), 0, 200, 1)
113
114# Use `flow1` as a TCP flow. TCP CUBIC is default in Linux.
115exp.add_tcp_flow(flow1)
116
117# Use `flow2` as a UDP flow, and set the rate at which it would send packets.
118exp.add_udp_flow(flow2, target_bandwidth="9mbit")
119
120# Enable collection of stats for `codel` qdisc installed on `etr1c` interface,
121# connecting `r1` to `r2`.
122exp.require_qdisc_stats(etr1c)
123
124# Run the experiment
125exp.run()

3. fq-codel-point-to-point.py

This program emulates point to point networks that connect four hosts: h1

  • h4 via two routers r1 and r2. One TCP flow is configured from h1 to h3 and one UDP flow is configured from h2 to h4. It is similar to tcp-udp-point-to-point.py in examples/tcp. The links h1 <–> r1, h2 <–> r1, and r2 <–> h3, r2 <–> h4 are edge links. The link r1 <–> r2 is the bottleneck link with lesser bandwidth and higher propagation delays. This program demonstrates how to configure Flow Queue Controlled Delay (fq_codel) queue discipline (qdisc) and obtain relevant statistics. fq_codel is enabled on the link from r1 to r2, but not from r2 to r1 because data packets flow in one direction only (left to right) in this example.

This program runs for 200 seconds and creates a new directory called fq-codel-point-to-point(date-timestamp)_dump. It contains a README that provides details about the sub-directories and files within this directory. See the plots in netperf, ping, ss and tc sub-directories for this program.

Source code

  1# SPDX-License-Identifier: GPL-2.0-only
  2# Copyright (c) 2019-2022 NITK Surathkal
  3
  4########################
  5# SHOULD BE RUN AS ROOT
  6########################
  7from nest.topology import *
  8from nest.experiment import *
  9from nest.topology.network import Network
 10from nest.topology.address_helper import AddressHelper
 11
 12# This program emulates point to point networks that connect four hosts: `h1`
 13# - `h4` via two routers `r1` and `r2`. One TCP flow is configured from `h1` to
 14# `h3` and one UDP flow is configured from `h2` to `h4`. It is similar to
 15# `tcp-udp-point-to-point.py` in `examples/tcp`. The links `h1` <--> `r1`,
 16# `h2` <--> `r1`, and `r2` <--> `h3`, `r2` <--> `h4` are edge links. The link
 17# `r1` <--> `r2` is the bottleneck link with lesser bandwidth and higher
 18# propagation delays. This program demonstrates how to configure Flow Queue
 19# Controlled Delay (`fq_codel`) queue discipline (qdisc) and obtain relevant
 20# statistics. `fq_codel` is enabled on the link from `r1` to `r2`, but not from
 21# `r2` to `r1` because data packets flow in one direction only (left to right)
 22# in this example.
 23
 24##############################################################################
 25#                              Network Topology                              #
 26#                                                                            #
 27#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 28# h1 --------------------|                          |-------------------- h3 #
 29#           TCP          |                          |         TCP            #
 30#                        |    <- 10mbit, 10ms ->    |                        #
 31#                         r1 -------------------- r2                         #
 32#                        |    fq_codel qdisc -->    |                        #
 33#           UDP          |                          |         UDP            #
 34# h2 --------------------|                          |-------------------- h4 #
 35#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 36#                                                                            #
 37##############################################################################
 38
 39# This program runs for 200 seconds and creates a new directory called
 40# `fq-codel-point-to-point(date-timestamp)_dump`. It contains a `README` that
 41# provides details about the sub-directories and files within this directory.
 42# See the plots in `netperf`, `ping`, `ss` and `tc` sub-directories for this
 43# program.
 44
 45# Create four hosts `h1` to `h4`, and two routers `r1` and `r2`
 46h1 = Node("h1")
 47h2 = Node("h2")
 48h3 = Node("h3")
 49h4 = Node("h4")
 50r1 = Router("r1")
 51r2 = Router("r2")
 52
 53# Set the IPv4 address for the networks
 54n1 = Network("192.168.1.0/24")  # network consisting `h1` and `r1`
 55n2 = Network("192.168.2.0/24")  # network consisting `h2` and `r1`
 56n3 = Network("192.168.3.0/24")  # network between two routers
 57n4 = Network("192.168.4.0/24")  # network consisting `r2` and `h3`
 58n5 = Network("192.168.5.0/24")  # network consisting `r2` and `h4`
 59
 60# Connect `h1` and `h2` to `r1`, `r1` to `r2`, and then `r2` to `h3` and `h4`.
 61# `eth1` to `eth4` are the interfaces at `h1` to `h4`, respectively.
 62# `etr1a`, `etr1b` and `etr1c` are three interfaces at `r1` that connect it
 63# with `h1`, `h2` and `r2`, respectively.
 64# `etr2a`, `etr2b` and `etr2c` are three interfaces at `r2` that connect it
 65# with `r1`, `h3` and `h4`, respectively.
 66(eth1, etr1a) = connect(h1, r1, network=n1)
 67(eth2, etr1b) = connect(h2, r1, network=n2)
 68(etr1c, etr2a) = connect(r1, r2, network=n3)
 69(etr2b, eth3) = connect(r2, h3, network=n4)
 70(etr2c, eth4) = connect(r2, h4, network=n5)
 71
 72# Assign IPv4 addresses to all the interfaces in the network.
 73AddressHelper.assign_addresses()
 74
 75# Configure the parameters of `fq_codel` qdisc.  For more details about
 76# `fq_codel` in Linux, use this command on CLI: `man tc-fq_codel`.
 77qdisc = "fq_codel"
 78fq_codel_parameters = {
 79    "limit": "100",  # set the queue capacity to 100 packets
 80    "flows": "2",  # set the number of flows to 2
 81    "target": "2ms",  # set the target queue delay to 2ms (default is 5ms)
 82    "interval": "24ms",  # set the interval value to 24ms (default is 100ms)
 83}
 84
 85# Set the link attributes: `h1` and `h2` --> `r1` --> `r2` --> `h3` and `h4`
 86# Note: we enable `fq_codel` queue discipline on the link from `r1` to `r2`.
 87eth1.set_attributes("1000mbit", "1ms")  # from `h1` to `r1`
 88eth2.set_attributes("1000mbit", "1ms")  # from `h2` to `r1`
 89etr1c.set_attributes("10mbit", "10ms", qdisc, **fq_codel_parameters)  # `r1` to `r2`
 90etr2b.set_attributes("1000mbit", "1ms")  # from `r2` to `h3`
 91etr2c.set_attributes("1000mbit", "1ms")  # from `r2` to `h4`
 92
 93# Set the link attributes: `h3` and `h4` --> `r2` --> `r1` --> `h1` and `h2`
 94eth3.set_attributes("1000mbit", "1ms")  # from `h3` to `r2`
 95eth4.set_attributes("1000mbit", "1ms")  # from `h4` to `r2`
 96etr2a.set_attributes("10mbit", "10ms")  # from `r2` to `r1`
 97etr1a.set_attributes("1000mbit", "1ms")  # from `r1` to `h1`
 98etr1b.set_attributes("1000mbit", "1ms")  # from `r1` to `h2`
 99
100# Set default routes in all the hosts and routers.
101h1.add_route("DEFAULT", eth1)
102h2.add_route("DEFAULT", eth2)
103h3.add_route("DEFAULT", eth3)
104h4.add_route("DEFAULT", eth4)
105r1.add_route("DEFAULT", etr1c)
106r2.add_route("DEFAULT", etr2a)
107
108# Set up an Experiment. This API takes the name of the experiment as a string.
109exp = Experiment("fq-codel-point-to-point")
110
111# Configure one flow from `h1` to `h3` and another from `h2` to `h4`.
112flow1 = Flow(h1, h3, eth3.get_address(), 0, 200, 1)
113flow2 = Flow(h2, h4, eth4.get_address(), 0, 200, 1)
114
115# Use `flow1` as a TCP flow. TCP CUBIC is default in Linux.
116exp.add_tcp_flow(flow1)
117
118# Use `flow2` as a UDP flow, and set the rate at which it would send packets.
119exp.add_udp_flow(flow2, target_bandwidth="9mbit")
120
121# Enable collection of stats for `fq_codel` qdisc installed on `etr1c`
122# interface, connecting `r1` to `r2`.
123exp.require_qdisc_stats(etr1c)
124
125# Run the experiment
126exp.run()

4. fq-pie-point-to-point.py

This program emulates point to point networks that connect four hosts: h1

  • h4 via two routers r1 and r2. One TCP flow is configured from h1 to h3 and one UDP flow is configured from h2 to h4. It is similar to tcp-udp-point-to-point.py in examples/tcp. The links h1 <–> r1, h2 <–> r1, and r2 <–> h3, r2 <–> h4 are edge links. The link r1 <–> r2 is the bottleneck link with lesser bandwidth and higher propagation delays. This program demonstrates how to configure Flow Queue Proportional Integral controller Enhanced (fq_pie) queue discipline (qdisc) and obtain the relevant statistics. fq_pie is enabled on the link from r1 to r2, but not from r2 to r1 because data packets flow in one direction only (left to right) in this example.

This program runs for 200 seconds and creates a new directory called fq-pie-point-to-point(date-timestamp)_dump. It contains a README that provides details about the sub-directories and files within this directory. See the plots in netperf, ping, ss and tc sub-directories for this program.

Source code

  1# SPDX-License-Identifier: GPL-2.0-only
  2# Copyright (c) 2019-2022 NITK Surathkal
  3
  4########################
  5# SHOULD BE RUN AS ROOT
  6########################
  7from nest.topology import *
  8from nest.experiment import *
  9from nest.topology.network import Network
 10from nest.topology.address_helper import AddressHelper
 11
 12# This program emulates point to point networks that connect four hosts: `h1`
 13# - `h4` via two routers `r1` and `r2`. One TCP flow is configured from `h1` to
 14# `h3` and one UDP flow is configured from `h2` to `h4`. It is similar to
 15# `tcp-udp-point-to-point.py` in `examples/tcp`. The links `h1` <--> `r1`,
 16# `h2` <--> `r1`, and `r2` <--> `h3`, `r2` <--> `h4` are edge links. The link
 17# `r1` <--> `r2` is the bottleneck link with lesser bandwidth and higher
 18# propagation delays. This program demonstrates how to configure Flow Queue
 19# Proportional Integral controller Enhanced (`fq_pie`) queue discipline (qdisc)
 20# and obtain the relevant statistics. `fq_pie` is enabled on the link from `r1`
 21# to `r2`, but not from `r2` to `r1` because data packets flow in one direction
 22# only (left to right) in this example.
 23
 24##############################################################################
 25#                              Network Topology                              #
 26#                                                                            #
 27#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 28# h1 --------------------|                          |-------------------- h3 #
 29#           TCP          |                          |         TCP            #
 30#                        |    <- 10mbit, 10ms ->    |                        #
 31#                         r1 -------------------- r2                         #
 32#                        |     fq_pie qdisc -->     |                        #
 33#           UDP          |                          |         UDP            #
 34# h2 --------------------|                          |-------------------- h4 #
 35#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 36#                                                                            #
 37##############################################################################
 38
 39# This program runs for 200 seconds and creates a new directory called
 40# `fq-pie-point-to-point(date-timestamp)_dump`. It contains a `README` that
 41# provides details about the sub-directories and files within this directory.
 42# See the plots in `netperf`, `ping`, `ss` and `tc` sub-directories for this
 43# program.
 44
 45# Create four hosts `h1` to `h4`, and two routers `r1` and `r2`
 46h1 = Node("h1")
 47h2 = Node("h2")
 48h3 = Node("h3")
 49h4 = Node("h4")
 50r1 = Router("r1")
 51r2 = Router("r2")
 52
 53# Set the IPv4 address for the networks
 54n1 = Network("192.168.1.0/24")  # network consisting `h1` and `r1`
 55n2 = Network("192.168.2.0/24")  # network consisting `h2` and `r1`
 56n3 = Network("192.168.3.0/24")  # network between two routers
 57n4 = Network("192.168.4.0/24")  # network consisting `r2` and `h3`
 58n5 = Network("192.168.5.0/24")  # network consisting `r2` and `h4`
 59
 60# Connect `h1` and `h2` to `r1`, `r1` to `r2`, and then `r2` to `h3` and `h4`.
 61# `eth1` to `eth4` are the interfaces at `h1` to `h4`, respectively.
 62# `etr1a`, `etr1b` and `etr1c` are three interfaces at `r1` that connect it
 63# with `h1`, `h2` and `r2`, respectively.
 64# `etr2a`, `etr2b` and `etr2c` are three interfaces at `r2` that connect it
 65# with `r1`, `h3` and `h4`, respectively.
 66(eth1, etr1a) = connect(h1, r1, network=n1)
 67(eth2, etr1b) = connect(h2, r1, network=n2)
 68(etr1c, etr2a) = connect(r1, r2, network=n3)
 69(etr2b, eth3) = connect(r2, h3, network=n4)
 70(etr2c, eth4) = connect(r2, h4, network=n5)
 71
 72# Assign IPv4 addresses to all the interfaces in the network.
 73AddressHelper.assign_addresses()
 74
 75# Configure the parameters of `fq_pie` qdisc.  For more details about `fq_pie`
 76# in Linux, use this command on CLI: `man tc-fq_pie`.
 77qdisc = "fq_pie"
 78fq_pie_parameters = {
 79    "limit": "100",  # set the queue capacity to 100 packets
 80    "flows": "2",  # set the number of flows to 2
 81    "target": "2ms",  # set the target queue delay to 2ms (default is 5ms)
 82}
 83
 84# Set the link attributes: `h1` and `h2` --> `r1` --> `r2` --> `h3` and `h4`
 85# Note: we enable `fq_pie` queue discipline on the link from `r1` to `r2`.
 86eth1.set_attributes("1000mbit", "1ms")  # from `h1` to `r1`
 87eth2.set_attributes("1000mbit", "1ms")  # from `h2` to `r1`
 88etr1c.set_attributes("10mbit", "10ms", qdisc, **fq_pie_parameters)  # `r1` to `r2`
 89etr2b.set_attributes("1000mbit", "1ms")  # from `r2` to `h3`
 90etr2c.set_attributes("1000mbit", "1ms")  # from `r2` to `h4`
 91
 92# Set the link attributes: `h3` and `h4` --> `r2` --> `r1` --> `h1` and `h2`
 93eth3.set_attributes("1000mbit", "1ms")  # from `h3` to `r2`
 94eth4.set_attributes("1000mbit", "1ms")  # from `h4` to `r2`
 95etr2a.set_attributes("10mbit", "10ms")  # from `r2` to `r1`
 96etr1a.set_attributes("1000mbit", "1ms")  # from `r1` to `h1`
 97etr1b.set_attributes("1000mbit", "1ms")  # from `r1` to `h2`
 98
 99# Set default routes in all the hosts and routers.
100h1.add_route("DEFAULT", eth1)
101h2.add_route("DEFAULT", eth2)
102h3.add_route("DEFAULT", eth3)
103h4.add_route("DEFAULT", eth4)
104r1.add_route("DEFAULT", etr1c)
105r2.add_route("DEFAULT", etr2a)
106
107# Set up an Experiment. This API takes the name of the experiment as a string.
108exp = Experiment("fq-pie-point-to-point")
109
110# Configure one flow from `h1` to `h3` and another from `h2` to `h4`.
111flow1 = Flow(h1, h3, eth3.get_address(), 0, 200, 1)
112flow2 = Flow(h2, h4, eth4.get_address(), 0, 200, 1)
113
114# Use `flow1` as a TCP flow. TCP CUBIC is default in Linux.
115exp.add_tcp_flow(flow1)
116
117# Use `flow2` as a UDP flow, and set the rate at which it would send packets.
118exp.add_udp_flow(flow2, target_bandwidth="9mbit")
119
120# Enable collection of stats for `fq_pie` qdisc installed on `etr1c` interface,
121# connecting `r1` to `r2`.
122exp.require_qdisc_stats(etr1c)
123
124# Run the experiment
125exp.run()

5. pfifo-point-to-point.py

This program emulates point to point networks that connect four hosts: h1

  • h4 via two routers r1 and r2. One TCP flow is configured from h1 to h3 and one UDP flow is configured from h2 to h4. It is similar to tcp-udp-point-to-point.py in examples/tcp. The links h1 <–> r1, h2 <–> r1, and r2 <–> h3, r2 <–> h4 are edge links. The link r1 <–> r2 is the bottleneck link with lesser bandwidth and higher propagation delays. This program demonstrates how to configure pfifo queue discipline (qdisc) and obtain the relevant statistics. pfifo is enabled on the link from r1 to r2, but not from r2 to r1 because data packets flow in one direction only (left to right) in this example.

This program runs for 200 seconds and creates a new directory called pfifo-point-to-point(date-timestamp)_dump. It contains a README that provides details about the sub-directories and files within this directory. See the plots in netperf, ping, ss and tc sub-directories for this program.

Source code

  1# SPDX-License-Identifier: GPL-2.0-only
  2# Copyright (c) 2019-2022 NITK Surathkal
  3
  4########################
  5# SHOULD BE RUN AS ROOT
  6########################
  7from nest.topology import *
  8from nest.experiment import *
  9from nest.topology.network import Network
 10from nest.topology.address_helper import AddressHelper
 11
 12# This program emulates point to point networks that connect four hosts: `h1`
 13# - `h4` via two routers `r1` and `r2`. One TCP flow is configured from `h1` to
 14# `h3` and one UDP flow is configured from `h2` to `h4`. It is similar to
 15# `tcp-udp-point-to-point.py` in `examples/tcp`. The links `h1` <--> `r1`,
 16# `h2` <--> `r1`, and `r2` <--> `h3`, `r2` <--> `h4` are edge links. The link
 17# `r1` <--> `r2` is the bottleneck link with lesser bandwidth and higher
 18# propagation delays. This program demonstrates how to configure `pfifo` queue
 19# discipline (qdisc) and obtain the relevant statistics. `pfifo` is enabled on
 20# the link from `r1` to `r2`, but not from `r2` to `r1` because data packets
 21# flow in one direction only (left to right) in this example.
 22
 23##############################################################################
 24#                              Network Topology                              #
 25#                                                                            #
 26#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 27# h1 --------------------|                          |-------------------- h3 #
 28#           TCP          |                          |         TCP            #
 29#                        |    <- 10mbit, 10ms ->    |                        #
 30#                         r1 -------------------- r2                         #
 31#                        |      pfifo qdisc -->     |                        #
 32#           UDP          |                          |         UDP            #
 33# h2 --------------------|                          |-------------------- h4 #
 34#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 35#                                                                            #
 36##############################################################################
 37
 38# This program runs for 200 seconds and creates a new directory called
 39# `pfifo-point-to-point(date-timestamp)_dump`. It contains a `README` that
 40# provides details about the sub-directories and files within this directory.
 41# See the plots in `netperf`, `ping`, `ss` and `tc` sub-directories for this
 42# program.
 43
 44# Create four hosts `h1` to `h4`, and two routers `r1` and `r2`
 45h1 = Node("h1")
 46h2 = Node("h2")
 47h3 = Node("h3")
 48h4 = Node("h4")
 49r1 = Router("r1")
 50r2 = Router("r2")
 51
 52# Set the IPv4 address for the networks
 53n1 = Network("192.168.1.0/24")  # network consisting `h1` and `r1`
 54n2 = Network("192.168.2.0/24")  # network consisting `h2` and `r1`
 55n3 = Network("192.168.3.0/24")  # network between two routers
 56n4 = Network("192.168.4.0/24")  # network consisting `r2` and `h3`
 57n5 = Network("192.168.5.0/24")  # network consisting `r2` and `h4`
 58
 59# Connect `h1` and `h2` to `r1`, `r1` to `r2`, and then `r2` to `h3` and `h4`.
 60# `eth1` to `eth4` are the interfaces at `h1` to `h4`, respectively.
 61# `etr1a`, `etr1b` and `etr1c` are three interfaces at `r1` that connect it
 62# with `h1`, `h2` and `r2`, respectively.
 63# `etr2a`, `etr2b` and `etr2c` are three interfaces at `r2` that connect it
 64# with `r1`, `h3` and `h4`, respectively.
 65(eth1, etr1a) = connect(h1, r1, network=n1)
 66(eth2, etr1b) = connect(h2, r1, network=n2)
 67(etr1c, etr2a) = connect(r1, r2, network=n3)
 68(etr2b, eth3) = connect(r2, h3, network=n4)
 69(etr2c, eth4) = connect(r2, h4, network=n5)
 70
 71# Assign IPv4 addresses to all the interfaces in the network.
 72AddressHelper.assign_addresses()
 73
 74# Configure the parameters of `pfifo` qdisc.  For more details about `pfifo`
 75# in Linux, use this command on CLI: `man tc-pfifo`.
 76qdisc = "pfifo"
 77pfifo_parameters = {"limit": "100"}  # set the queue capacity to 100 packets
 78
 79# Set the link attributes: `h1` and `h2` --> `r1` --> `r2` --> `h3` and `h4`
 80# Note: we enable `pfifo` queue discipline on the link from `r1` to `r2`.
 81eth1.set_attributes("1000mbit", "1ms")  # from `h1` to `r1`
 82eth2.set_attributes("1000mbit", "1ms")  # from `h2` to `r1`
 83etr1c.set_attributes("10mbit", "10ms", qdisc, **pfifo_parameters)  # from `r1` to `r2`
 84etr2b.set_attributes("1000mbit", "1ms")  # from `r2` to `h3`
 85etr2c.set_attributes("1000mbit", "1ms")  # from `r2` to `h4`
 86
 87# Set the link attributes: `h3` and `h4` --> `r2` --> `r1` --> `h1` and `h2`
 88eth3.set_attributes("1000mbit", "1ms")  # from `h3` to `r2`
 89eth4.set_attributes("1000mbit", "1ms")  # from `h4` to `r2`
 90etr2a.set_attributes("10mbit", "10ms")  # from `r2` to `r1`
 91etr1a.set_attributes("1000mbit", "1ms")  # from `r1` to `h1`
 92etr1b.set_attributes("1000mbit", "1ms")  # from `r1` to `h2`
 93
 94# Set default routes in all the hosts and routers.
 95h1.add_route("DEFAULT", eth1)
 96h2.add_route("DEFAULT", eth2)
 97h3.add_route("DEFAULT", eth3)
 98h4.add_route("DEFAULT", eth4)
 99r1.add_route("DEFAULT", etr1c)
100r2.add_route("DEFAULT", etr2a)
101
102# Set up an Experiment. This API takes the name of the experiment as a string.
103exp = Experiment("pfifo-point-to-point")
104
105# Configure one flow from `h1` to `h3` and another from `h2` to `h4`.
106flow1 = Flow(h1, h3, eth3.get_address(), 0, 200, 1)
107flow2 = Flow(h2, h4, eth4.get_address(), 0, 200, 1)
108
109# Use `flow1` as a TCP flow. TCP CUBIC is default in Linux.
110exp.add_tcp_flow(flow1)
111
112# Use `flow2` as a UDP flow, and set the rate at which it would send packets.
113exp.add_udp_flow(flow2, target_bandwidth="9mbit")
114
115# Enable collection of stats for `pfifo` qdisc installed on `etr1c` interface,
116# connecting `r1` to `r2`.
117exp.require_qdisc_stats(etr1c)
118
119# Run the experiment
120exp.run()

6. pie-point-to-point.py

This program emulates point to point networks that connect four hosts: h1

  • h4 via two routers r1 and r2. One TCP flow is configured from h1 to h3 and one UDP flow is configured from h2 to h4. It is similar to tcp-udp-point-to-point.py in examples/tcp. The links h1 <–> r1, h2 <–> r1, and r2 <–> h3, r2 <–> h4 are edge links. The link r1 <–> r2 is the bottleneck link with lesser bandwidth and higher propagation delays. This program demonstrates how to configure Proportional Integral controller Enhanced (pie) queue discipline (qdisc) and obtain the relevant statistics. pie is enabled on the link from r1 to r2, but not from r2 to r1 because data packets flow in one direction only (left to right) in this example.

This program runs for 200 seconds and creates a new directory called pie-point-to-point(date-timestamp)_dump. It contains a README that provides details about the sub-directories and files within this directory. See the plots in netperf, ping, ss and tc sub-directories for this program.

Source code

  1# SPDX-License-Identifier: GPL-2.0-only
  2# Copyright (c) 2019-2022 NITK Surathkal
  3
  4########################
  5# SHOULD BE RUN AS ROOT
  6########################
  7from nest.topology import *
  8from nest.experiment import *
  9from nest.topology.network import Network
 10from nest.topology.address_helper import AddressHelper
 11
 12# This program emulates point to point networks that connect four hosts: `h1`
 13# - `h4` via two routers `r1` and `r2`. One TCP flow is configured from `h1` to
 14# `h3` and one UDP flow is configured from `h2` to `h4`. It is similar to
 15# `tcp-udp-point-to-point.py` in `examples/tcp`. The links `h1` <--> `r1`,
 16# `h2` <--> `r1`, and `r2` <--> `h3`, `r2` <--> `h4` are edge links. The link
 17# `r1` <--> `r2` is the bottleneck link with lesser bandwidth and higher
 18# propagation delays. This program demonstrates how to configure Proportional
 19# Integral controller Enhanced (`pie`) queue discipline (qdisc) and obtain the
 20# relevant statistics. `pie` is enabled on the link from `r1` to `r2`, but
 21# not from `r2` to `r1` because data packets flow in one direction only (left
 22# to right) in this example.
 23
 24##############################################################################
 25#                              Network Topology                              #
 26#                                                                            #
 27#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 28# h1 --------------------|                          |-------------------- h3 #
 29#           TCP          |                          |         TCP            #
 30#                        |    <- 10mbit, 10ms ->    |                        #
 31#                         r1 -------------------- r2                         #
 32#                        |       pie qdisc -->      |                        #
 33#           UDP          |                          |         UDP            #
 34# h2 --------------------|                          |-------------------- h4 #
 35#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 36#                                                                            #
 37##############################################################################
 38
 39# This program runs for 200 seconds and creates a new directory called
 40# `pie-point-to-point(date-timestamp)_dump`. It contains a `README` that
 41# provides details about the sub-directories and files within this directory.
 42# See the plots in `netperf`, `ping`, `ss` and `tc` sub-directories for this
 43# program.
 44
 45# Create four hosts `h1` to `h4`, and two routers `r1` and `r2`
 46h1 = Node("h1")
 47h2 = Node("h2")
 48h3 = Node("h3")
 49h4 = Node("h4")
 50r1 = Router("r1")
 51r2 = Router("r2")
 52
 53# Set the IPv4 address for the networks
 54n1 = Network("192.168.1.0/24")  # network consisting `h1` and `r1`
 55n2 = Network("192.168.2.0/24")  # network consisting `h2` and `r1`
 56n3 = Network("192.168.3.0/24")  # network between two routers
 57n4 = Network("192.168.4.0/24")  # network consisting `r2` and `h3`
 58n5 = Network("192.168.5.0/24")  # network consisting `r2` and `h4`
 59
 60# Connect `h1` and `h2` to `r1`, `r1` to `r2`, and then `r2` to `h3` and `h4`.
 61# `eth1` to `eth4` are the interfaces at `h1` to `h4`, respectively.
 62# `etr1a`, `etr1b` and `etr1c` are three interfaces at `r1` that connect it
 63# with `h1`, `h2` and `r2`, respectively.
 64# `etr2a`, `etr2b` and `etr2c` are three interfaces at `r2` that connect it
 65# with `r1`, `h3` and `h4`, respectively.
 66(eth1, etr1a) = connect(h1, r1, network=n1)
 67(eth2, etr1b) = connect(h2, r1, network=n2)
 68(etr1c, etr2a) = connect(r1, r2, network=n3)
 69(etr2b, eth3) = connect(r2, h3, network=n4)
 70(etr2c, eth4) = connect(r2, h4, network=n5)
 71
 72# Assign IPv4 addresses to all the interfaces in the network.
 73AddressHelper.assign_addresses()
 74
 75# Configure the parameters of `pie` qdisc.  For more details about `pie`
 76# in Linux, use this command on CLI: `man tc-pie`.
 77qdisc = "pie"
 78pie_parameters = {
 79    "limit": "100",  # set the queue capacity to 100 packets
 80    "target": "2ms",  # set the target queue delay to 2ms (default is 15ms)
 81}
 82
 83# Set the link attributes: `h1` and `h2` --> `r1` --> `r2` --> `h3` and `h4`
 84# Note: we enable `pie` queue discipline on the link from `r1` to `r2`.
 85eth1.set_attributes("1000mbit", "1ms")  # from `h1` to `r1`
 86eth2.set_attributes("1000mbit", "1ms")  # from `h2` to `r1`
 87etr1c.set_attributes("10mbit", "10ms", qdisc, **pie_parameters)  # from `r1` to `r2`
 88etr2b.set_attributes("1000mbit", "1ms")  # from `r2` to `h3`
 89etr2c.set_attributes("1000mbit", "1ms")  # from `r2` to `h4`
 90
 91# Set the link attributes: `h3` and `h4` --> `r2` --> `r1` --> `h1` and `h2`
 92eth3.set_attributes("1000mbit", "1ms")  # from `h3` to `r2`
 93eth4.set_attributes("1000mbit", "1ms")  # from `h4` to `r2`
 94etr2a.set_attributes("10mbit", "10ms")  # from `r2` to `r1`
 95etr1a.set_attributes("1000mbit", "1ms")  # from `r1` to `h1`
 96etr1b.set_attributes("1000mbit", "1ms")  # from `r1` to `h2`
 97
 98# Set default routes in all the hosts and routers.
 99h1.add_route("DEFAULT", eth1)
100h2.add_route("DEFAULT", eth2)
101h3.add_route("DEFAULT", eth3)
102h4.add_route("DEFAULT", eth4)
103r1.add_route("DEFAULT", etr1c)
104r2.add_route("DEFAULT", etr2a)
105
106# Set up an Experiment. This API takes the name of the experiment as a string.
107exp = Experiment("pie-point-to-point")
108
109# Configure one flow from `h1` to `h3` and another from `h2` to `h4`.
110flow1 = Flow(h1, h3, eth3.get_address(), 0, 200, 1)
111flow2 = Flow(h2, h4, eth4.get_address(), 0, 200, 1)
112
113# Use `flow1` as a TCP flow. TCP CUBIC is default in Linux.
114exp.add_tcp_flow(flow1)
115
116# Use `flow2` as a UDP flow, and set the rate at which it would send packets.
117exp.add_udp_flow(flow2, target_bandwidth="9mbit")
118
119# Enable collection of stats for `pie` qdisc installed on `etr1c` interface,
120# connecting `r1` to `r2`.
121exp.require_qdisc_stats(etr1c)
122
123# Run the experiment
124exp.run()

7. red-point-to-point.py

This program emulates point to point networks that connect four hosts: h1

  • h4 via two routers r1 and r2. One TCP flow is configured from h1 to h3 and one UDP flow is configured from h2 to h4. It is similar to tcp-udp-point-to-point.py in examples/tcp. The links h1 <–> r1, h2 <–> r1, and r2 <–> h3, r2 <–> h4 are edge links. The link r1 <–> r2 is the bottleneck link with lesser bandwidth and higher propagation delays. This program demonstrates how to configure Random Early Detection (red) queue discipline (qdisc) and obtain relevant statistics. red is enabled on the link from r1 to r2, but not from r2 to r1 because data packets flow in one direction only (left to right) in this example.

This program runs for 200 seconds and creates a new directory called red-point-to-point(date-timestamp)_dump. It contains a README that provides details about the sub-directories and files within this directory. See the plots in netperf, ping and ss sub-directories for this program.

NOTE: This program does not generate the stats for red qdisc because NeST does not support this feature yet.

Source code

  1# SPDX-License-Identifier: GPL-2.0-only
  2# Copyright (c) 2019-2022 NITK Surathkal
  3
  4########################
  5# SHOULD BE RUN AS ROOT
  6########################
  7from nest.topology import *
  8from nest.experiment import *
  9from nest.topology.network import Network
 10from nest.topology.address_helper import AddressHelper
 11
 12# This program emulates point to point networks that connect four hosts: `h1`
 13# - `h4` via two routers `r1` and `r2`. One TCP flow is configured from `h1` to
 14# `h3` and one UDP flow is configured from `h2` to `h4`. It is similar to
 15# `tcp-udp-point-to-point.py` in `examples/tcp`. The links `h1` <--> `r1`,
 16# `h2` <--> `r1`, and `r2` <--> `h3`, `r2` <--> `h4` are edge links. The link
 17# `r1` <--> `r2` is the bottleneck link with lesser bandwidth and higher
 18# propagation delays. This program demonstrates how to configure Random Early
 19# Detection (`red`) queue discipline (qdisc) and obtain relevant statistics.
 20# `red` is enabled on the link from `r1` to `r2`, but not from `r2` to `r1`
 21# because data packets flow in one direction only (left to right) in this
 22# example.
 23
 24##############################################################################
 25#                              Network Topology                              #
 26#                                                                            #
 27#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 28# h1 --------------------|                          |-------------------- h3 #
 29#           TCP          |                          |         TCP            #
 30#                        |    <- 10mbit, 10ms ->    |                        #
 31#                         r1 -------------------- r2                         #
 32#                        |       red qdisc -->      |                        #
 33#           UDP          |                          |         UDP            #
 34# h2 --------------------|                          |-------------------- h4 #
 35#    <- 1000mbit, 1ms ->                              <- 1000mbit, 1ms ->    #
 36#                                                                            #
 37##############################################################################
 38
 39# This program runs for 200 seconds and creates a new directory called
 40# `red-point-to-point(date-timestamp)_dump`. It contains a `README` that
 41# provides details about the sub-directories and files within this directory.
 42# See the plots in `netperf`, `ping` and `ss` sub-directories for this program.
 43
 44# Create four hosts `h1` to `h4`, and two routers `r1` and `r2`
 45h1 = Node("h1")
 46h2 = Node("h2")
 47h3 = Node("h3")
 48h4 = Node("h4")
 49r1 = Router("r1")
 50r2 = Router("r2")
 51
 52# Set the IPv4 address for the networks
 53n1 = Network("192.168.1.0/24")  # network consisting `h1` and `r1`
 54n2 = Network("192.168.2.0/24")  # network consisting `h2` and `r1`
 55n3 = Network("192.168.3.0/24")  # network between two routers
 56n4 = Network("192.168.4.0/24")  # network consisting `r2` and `h3`
 57n5 = Network("192.168.5.0/24")  # network consisting `r2` and `h4`
 58
 59# Connect `h1` and `h2` to `r1`, `r1` to `r2`, and then `r2` to `h3` and `h4`.
 60# `eth1` to `eth4` are the interfaces at `h1` to `h4`, respectively.
 61# `etr1a`, `etr1b` and `etr1c` are three interfaces at `r1` that connect it
 62# with `h1`, `h2` and `r2`, respectively.
 63# `etr2a`, `etr2b` and `etr2c` are three interfaces at `r2` that connect it
 64# with `r1`, `h3` and `h4`, respectively.
 65(eth1, etr1a) = connect(h1, r1, network=n1)
 66(eth2, etr1b) = connect(h2, r1, network=n2)
 67(etr1c, etr2a) = connect(r1, r2, network=n3)
 68(etr2b, eth3) = connect(r2, h3, network=n4)
 69(etr2c, eth4) = connect(r2, h4, network=n5)
 70
 71# Assign IPv4 addresses to all the interfaces in the network.
 72AddressHelper.assign_addresses()
 73
 74# Configure the parameters of `red` qdisc.  For more details about `red`
 75# in Linux, use this command on CLI: `man tc-red`.
 76qdisc = "red"
 77red_parameters = {
 78    "limit": "150000",  # set the queue capacity to 150000 bytes
 79    "min": "7500",  # set the minimum threshold to 7500 bytes
 80    "max": "22500",  # set the maximum threshold to 22500 bytes
 81}
 82
 83# Set the link attributes: `h1` and `h2` --> `r1` --> `r2` --> `h3` and `h4`
 84# Note: we enable `red` queue discipline on the link from `r1` to `r2`.
 85eth1.set_attributes("1000mbit", "1ms")  # from `h1` to `r1`
 86eth2.set_attributes("1000mbit", "1ms")  # from `h2` to `r1`
 87etr1c.set_attributes("10mbit", "10ms", qdisc, **red_parameters)  # from `r1` to `r2`
 88etr2b.set_attributes("1000mbit", "1ms")  # from `r2` to `h3`
 89etr2c.set_attributes("1000mbit", "1ms")  # from `r2` to `h4`
 90
 91# Set the link attributes: `h3` and `h4` --> `r2` --> `r1` --> `h1` and `h2`
 92eth3.set_attributes("1000mbit", "1ms")  # from `h3` to `r2`
 93eth4.set_attributes("1000mbit", "1ms")  # from `h4` to `r2`
 94etr2a.set_attributes("10mbit", "10ms")  # from `r2` to `r1`
 95etr1a.set_attributes("1000mbit", "1ms")  # from `r1` to `h1`
 96etr1b.set_attributes("1000mbit", "1ms")  # from `r1` to `h2`
 97
 98# Set default routes in all the hosts and routers.
 99h1.add_route("DEFAULT", eth1)
100h2.add_route("DEFAULT", eth2)
101h3.add_route("DEFAULT", eth3)
102h4.add_route("DEFAULT", eth4)
103r1.add_route("DEFAULT", etr1c)
104r2.add_route("DEFAULT", etr2a)
105
106# Set up an Experiment. This API takes the name of the experiment as a string.
107exp = Experiment("red-point-to-point")
108
109# Configure one flow from `h1` to `h3` and another from `h2` to `h4`.
110flow1 = Flow(h1, h3, eth3.get_address(), 0, 200, 1)
111flow2 = Flow(h2, h4, eth4.get_address(), 0, 200, 1)
112
113# Use `flow1` as a TCP flow. TCP CUBIC is default in Linux.
114exp.add_tcp_flow(flow1)
115
116# Use `flow2` as a UDP flow, and set the rate at which it would send packets.
117exp.add_udp_flow(flow2, target_bandwidth="9mbit")
118
119# The following line enables collection of stats for the qdisc installed on
120# `etr1c` interface (connecting `r1` to `r2`), but it is commented because NeST
121# does not support stats collection for `red` qdisc.
122# exp.require_qdisc_stats(etr1c)
123
124# Run the experiment
125exp.run()