Skip to content

Develop and prototype networking simulations on ns-3 inside a docker container using python

Notifications You must be signed in to change notification settings

hameliknaoh/dev-on-ns-3-inside-a-container-using-python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Develop and Prototype Networking Simulations on NS-3 Inside a Docker Container Using Python

The discrete-event network simulator ns-3 is widely used by both the research and the industry communities to prototype and experiment on networking protocols and systems e.g. Deadline-Aware Datacenter TCP (D2TCP) (Sigcomm'12) and DeTail: Reducing the Flow Completion Time Tail in Datacenter Networks (Sigcomm'12).

ns-3 has been initially designed and built to be used primarily in c++. Although c++ allows ns-3 developers to hook at the bare metal of the simulator system as well as the linux operating-system host 🀘, it makes the prototyping process relatively slow ⌚🐒 and tedious πŸ”πŸͺ². Recently, ns-3 maintainers proposed to leverage the versatility of python and enable python development on ns-3 to speed up the prototyping cycle πŸ’‘.

Developing with python in ns-3 relies on scanning the ns-3 c++ modules and generate their respective python bindings. The generation of python bindings in ns-3 is still a work-in-progress, and it requires some extra effort at the developer side to manually build and successfully mix, match and integrate the required libraries for the scanning process. I never say no to build, and I burned some of my saved energy β˜•β›½ and my late-night candles β³πŸ’« getting the ns-3 python-bindings pipeline-generation built. I am shipping a ready-to-use docker image 🐳 for ns-3 (version 3.26) for python development on my docker hub. Feel free to give it a try! For any modification of the ns-3 c++ API, please issue the command ./waf --apiscan=all from the ns-3 home project, to generate the corresponding python bindings.

I will be also providing docker images to automate the python bindings generation for the upcoming ns-3 releases (version >= 3.26). I hope you find this useful ♠️β™₯οΈβ™£οΈβ™¦οΈπŸ’Ž! Happy coding 😁 and peace out! ✌️

System Requirements and Setup

Going ahead, we will be setting up our ns-3 docker box on a Linux environment. The attached build-script.sh to the repository has been tested on a Ubuntu-18.04 machine with the zsh interpreter, but it should also work fine for the rest of Debian and Ubuntu-based Linux distributions that are supported by Docker Inc.: for more details, please check the list of Linux platforms supported by Docker Inc. Clone the git repository, and start running the build-script.sh by issuing the make command. The build-script will update the system packages, install docker and pull my ns-3 docker image from the Docker Hub:

  $ git clone https://github.com/hameliknaoh/dev-on-ns-3-inside-a-container-using-python.git
  $ cd dev-on-ns-3-inside-a-container-using-python/
  $ make

To verify that the setup process was successfull, we should be able to have the hamelik/ns3.26libdependencies docker image listed when the command docker images is issued:

  $ docker imgaes

  REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
  hamelik/ns3.26libdependencies   first               c53ffa37a8e1        9 months ago        4.1GB

We should be also able to have the ns-allinone-3.26.tar.bz2 tarball archive downloaded from the official ns-3 source, and decompressed to the ns-allinone-3.26 folder.

  $ cd dev-on-ns-3-inside-a-container-using-python/
  $ ls -a
  
  .   build-script.sh  ns-allinone-3.26          README.md
  ..  .git             ns-allinone-3.26.tar.bz2  set-up-ns-3-docker-env.sh

Develop and Debug Interactively on NS-3 Inside a Docker Container

To start an ns-3 docker container for development and API scanning with python, we will be using the hamelik/ns3.26libdependencies docker image pulled from my personal hub space. We will be issuing the command docker run and we will be mounting the ns-allinone-3.26 folder as a volume in the container using the -v flag, under/usr/local/. Let's call our ns-3 docker container Hello-NS-3.26:

  $ cd dev-on-ns-3-inside-a-container-using-python/
  $ docker run -it \
    -v `pwd`/ns-allinone-3.26/:/usr/local/ns-allinone-3.26/ \
    --name Hello-NS-3.26 hamelik/ns3.26libdependencies:first

The ns-3.26 home directory is located under:

  • ./dev-on-ns-3-inside-a-container-using-python/ns-allinone-3.26/ns-3.26/ at the host side.
  • /usr/local/ns-allinone-3.26/ns-3.26/ at the Hello-NS-3.26 docker container side.

Rather than typing the complete full docker run command, we make use of the Makefile attached to the project and simply type:

  $ make ns-3-container-run

At the container side, navigate under /usr/local/ns-allinone-3.26/ns-3.26/ using the cd command, and you will be able to list the following items, in particular, the waf build automation tool:

  # cd /usr/local/ns-allinone-3.26/ns-3.26/
  # ls -a
  
  .                                             LICENSE        build     testpy-output  waf-tools
  ..                                            Makefile       doc       testpy.supp    waf.bat
  .lock-waf_linux2_build                        README         examples  utils          wscript
  .waf-1.8.19-b1fc8f7baef51bd2db4c2971909a568d  RELEASE_NOTES  scratch   utils.py       wutils.py
  AUTHORS                                       VERSION        src       utils.pyc      wutils.pyc
  CHANGES.html                                  bindings       test.py   waf

Fast forward, it is all setted-up now to be able to edit/develop python code on ns-3 at the host side (left side of the following figure) using your favourite code editor (I recommend vscode), and run/debug it interactively at the container side (right side of the following figure) from the terminal.

Configure, Build and Run Python Simulations in NS-3

ns-3 could be configured to be built with a debug, release or optimized profile. In this guide, we will be developing with the debug profile. From the ns-3.26 home directory, we get the network simulator ready for developping following these four steps:

Step 1: Clean the previous build (optional, but a good practice)

  # cd /usr/local/ns-allinone-3.26/ns-3.26/
  # ./waf clean
  
  'clean' finished successfully (0.191s)

Step 2: Configure the project

  # ./waf configure --build-profile=debug --enable-examples --enable-tests
    'configure' finished successfully (2.262s)
  

Setting top to : /usr/local/ns-allinone-3.26/ns-3.26
Setting out to : /usr/local/ns-allinone-3.26/ns-3.26/build
Checking for 'gcc' (C compiler) : /usr/bin/gcc
Checking for cc version : 4.9.4
Checking for 'g++' (C++ compiler) : /usr/bin/g++
Checking for compilation flag -Wl,--soname=foo support : ok
Checking for program 'python' : /usr/bin/python
Checking for python version : (2, 7, 6, 'final', 0)
python-config : /usr/bin/python-config
Asking python-config for pyembed '--cflags --libs --ldflags' flags : yes
Testing pyembed configuration : yes
Asking python-config for pyext '--cflags --libs --ldflags' flags : yes
Testing pyext configuration : yes
Checking for compilation flag -fvisibility=hidden support : ok
Checking for compilation flag -Wno-array-bounds support : ok
Checking for pybindgen location : ../pybindgen-0.17.0.post57+nga6376f2 (guessed)
Checking for python module 'pybindgen' : 0.17.0.post57+nga6376f2
Checking for pybindgen version : 0.17.0.post57+nga6376f2
Checking for code snippet : yes
Checking for types uint64_t and unsigned long equivalence : no
Checking for code snippet : no
Checking for types uint64_t and unsigned long long equivalence : yes
Checking for the apidefs that can be used for Python bindings : gcc-LP64
Checking for internal GCC cxxabi : complete
Checking for python module 'pygccxml' : 1.0.0
Checking for pygccxml version : 1.0.0
Checking for program 'gccxml' : /usr/bin/gccxml
Checking for gccxml version : 0.9.0
Checking boost includes : headers not found, please provide a --boost-includes argument (see help)
Checking boost includes : headers not found, please provide a --boost-includes argument (see help)
Checking for click location : not found
Checking for program 'pkg-config' : /usr/bin/pkg-config
Checking for 'gtk+-2.0' >= 2.12 : yes
Checking for 'libxml-2.0' >= 2.7 : yes
Checking for type uint128_t : not found
Checking for type __uint128_t : yes
Checking high precision implementation : 128-bit integer (default)
Checking for header stdint.h : yes
Checking for header inttypes.h : yes
Checking for header sys/inttypes.h : not found
Checking for header sys/types.h : yes
Checking for header sys/stat.h : yes
Checking for header dirent.h : yes
Checking for header stdlib.h : yes
Checking for header signal.h : yes
Checking for header pthread.h : yes
Checking for header stdint.h : yes
Checking for header inttypes.h : yes
Checking for header sys/inttypes.h : not found
Checking for library rt : yes
Checking for header sys/ioctl.h : yes
Checking for header net/if.h : yes
Checking for header net/ethernet.h : yes
Checking for header linux/if_tun.h : yes
Checking for header netpacket/packet.h : yes
Checking for NSC location : not found
Checking for 'sqlite3' : yes
Checking for header linux/if_tun.h : yes
Checking for python module 'gtk' : ok
Checking for python module 'goocanvas' : 0.14.1
Checking for python module 'pygraphviz' : 1.2
Checking for program 'sudo' : /usr/bin/sudo
Checking for program 'valgrind' : /usr/bin/valgrind
Checking for 'gsl' : yes
python-config : not found
Checking for compilation flag -Wno-error=deprecated-d... support : ok
Checking for compilation flag -Wno-error=deprecated-d... support : ok
Checking for compilation flag -fstrict-aliasing support : ok
Checking for compilation flag -fstrict-aliasing support : ok
Checking for compilation flag -Wstrict-aliasing support : ok
Checking for compilation flag -Wstrict-aliasing support : ok
Checking for program 'doxygen' : /usr/bin/doxygen
---- Summary of optional NS-3 features:
Build profile : debug
Build directory :
BRITE Integration : not enabled (BRITE not enabled (see option --with-brite))
DES Metrics event collection : not enabled (defaults to disabled)
Emulation FdNetDevice : enabled
Examples : enabled
File descriptor NetDevice : enabled
GNU Scientific Library (GSL) : enabled
Gcrypt library : not enabled (libgcrypt not found: you can use libgcrypt-config to find its location.)
GtkConfigStore : enabled
MPI Support : not enabled (option --enable-mpi not selected)
NS-3 Click Integration : not enabled (nsclick not enabled (see option --with-nsclick))
NS-3 OpenFlow Integration : not enabled (Required boost libraries not found)
Network Simulation Cradle : not enabled (NSC not found (see option --with-nsc))
PlanetLab FdNetDevice : not enabled (PlanetLab operating system not detected (see option --force-planetlab))
PyViz visualizer : enabled
Python API Scanning Support : enabled
Python Bindings : enabled
Real Time Simulator : enabled
SQlite stats data output : enabled
Tap Bridge : enabled
Tap FdNetDevice : enabled
Tests : enabled
Threading Primitives : enabled
Use sudo to set suid bit : not enabled (option --enable-sudo not selected)
XmlIo : enabled
'configure' finished successfully (2.262s)

Step 3: Build the project

  # ./waf build
    'build' finished successfully (7m25.441s)
  

Waf: Entering directory `/usr/local/ns-allino ne-3.26/ns-3.26/build'
[ 1/2631] Compiling install-ns3-header: ns3/antenna-model.h
[ 2/2631] Compiling install-ns3-header: ns3/isotropic-antenna-model.h
[ 4/2631] Compiling install-ns3-header: ns3/angles.h
[ 5/2631] Compiling install-ns3-header: ns3/parabolic-antenna-model.h
[ 5/2631] Compiling install-ns3-header: ns3/cosine-antenna-model.h
[ 6/2631] Processing command (${PYTHON}): ../bindings/python/ns3modulegen-modular.py ../src/antenna/bindings/modulegen__gcc_LP64.py -> src/antenna/bindings/ns3module.cc src/antenna/bindings/ns3module.h src/antenna/bindings/ns3modulegen.log

[ 7/2631] Compiling install-ns3-header: ns3/aodv-packet.h
[ 8/2631] Compiling install-ns3-header: ns3/aodv-neighbor.h
[ 9/2631] Compiling install-ns3-header: ns3/aodv-rqueue.h
[ 10/2631] Compiling install-ns3-header: ns3/aodv-routing-protocol.h
[ 11/2631] Compiling install-ns3-header: ns3/aodv-rtable.h
[ 12/2631] Compiling install-ns3-header: ns3/aodv-id-cache.h
[ 14/2631] Compiling install-ns3-header: ns3/aodv-dpd.h
[ 14/2631] Compiling install-ns3-header: ns3/aodv-helper.h
[ 15/2631] Processing command (${PYTHON}): ../bindings/python/ns3modulegen-modular.py ../src/aodv/bindings/modulegen__gcc_LP64.py -> src/aodv/bindings/ns3module.cc src/aodv/bindings/ns3module.h src/aodv/bindings/ns3modulegen.log

...
...

[2619/2631] Linking build/bindings/python/ns/point_to_point.so
[2620/2631] Linking build/utils/ns3.26-test-runner-debug
[2622/2631] Compiling src/fd-net-device/helper/encode-decode.cc
[2622/2631] Compiling src/fd-net-device/helper/tap-device-creator.cc
[2623/2631] Compiling src/fd-net-device/helper/creator-utils.cc
[2624/2631] Linking build/src/fd-net-device/ns3.26-tap-device-creator-debug
[2625/2631] Compiling src/fd-net-device/helper/raw-sock-creator.cc
[2626/2631] Compiling src/fd-net-device/helper/encode-decode.cc
[2627/2631] Compiling src/fd-net-device/helper/creator-utils.cc
[2628/2631] Linking build/src/fd-net-device/ns3.26-raw-sock-creator-debug
[2629/2631] Compiling src/tap-bridge/model/tap-creator.cc
[2630/2631] Compiling src/tap-bridge/model/tap-encode-decode.cc
[2631/2631] Linking build/src/tap-bridge/ns3.26-tap-creator-debug
Waf: Leaving directory `/home/ns-allinone-3.26/ns-3.26/build'
Build commands will be stored in build/compile_commands.json
'build' finished successfully (7m25.441s)

Modules built:
antenna aodv applications
bridge buildings config-store
core csma csma-layout
dsdv dsr energy
fd-net-device flow-monitor internet
internet-apps lr-wpan lte
mesh mobility mpi
netanim (no Python) network nix-vector-routing
olsr point-to-point point-to-point-layout
propagation sixlowpan spectrum
stats tap-bridge test (no Python)
topology-read traffic-control uan
virtual-net-device visualizer wave
wifi wimax

Modules not built (see ns-3 tutorial for explanation):
brite click openflow

Step 4: Run Your First Python Simulation Script in NS-3

The ns-3 distribution is initially shipped with three python simulation scripts first.py, second.py, and third.py, that are located under examples/tutorial/. Let's run the first script that is simulating an echo message exchange between a client and a server.

  # cd /usr/local/ns-allinone-3.26/ns-3.26/
  # ./waf --pyrun examples/tutorial/first.py
  
  Waf: Entering directory `/usr/local/ns-allinone-3.26/ns-3.26/build'
  Waf: Leaving directory `/usr/local/ns-allinone-3.26/ns-3.26/build'
  Build commands will be stored in build/compile_commands.json
  'build' finished successfully (2.054s)

  Modules built:
  antenna                   aodv                      applications              
  bridge                    buildings                 config-store              
  core                      csma                      csma-layout               
  dsdv                      dsr                       energy                    
  fd-net-device             flow-monitor              internet                  
  internet-apps             lr-wpan                   lte                       
  mesh                      mobility                  mpi                       
  netanim (no Python)       network                   nix-vector-routing        
  olsr                      point-to-point            point-to-point-layout     
  propagation               sixlowpan                 spectrum                  
  stats                     tap-bridge                test (no Python)          
  topology-read             traffic-control           uan                       
  virtual-net-device        visualizer                wave                      
  wifi                      wimax                     

  Modules not built (see ns-3 tutorial for explanation):
  brite                     click                     openflow                  

  At time 2s client sent 1024 bytes to 10.1.1.2 port 9
  At time 2.00369s server received 1024 bytes from 10.1.1.1 port 49153
  At time 2.00369s server sent 1024 bytes to 10.1.1.1 port 49153
  At time 2.00737s client received 1024 bytes from 10.1.1.2 port 9

NS-3 C++ API Scanning and Python Module Generation

To test that the ns-3 c++ api scanning is properly working, issue the command

  # ./waf --apiscan=all

The ./waf --apiscan=all automation tool will be scanning all the ns-3 modules

  Waf: Entering directory `/usr/local/ns-allinone-3.26/ns-3.26/build'
  Modules to scan:  ['antenna', 'aodv', 'applications', 'bridge', 'buildings', 'config-store', 
                      'core', 'csma', 'csma-layout', 'dsdv', 'dsr', 'energy', 'fd-net-device', 
                      'flow-monitor', 'internet', 'internet-apps', 'lr-wpan', 'lte', 'mesh', 
                      'mobility', 'mpi', 'network', 'nix-vector-routing', 'olsr', 'point-to-point', 
                      'point-to-point-layout', 'propagation', 'sixlowpan', 'spectrum', 'stats', 
                      'tap-bridge', 'topology-read', 'traffic-control', 'uan', 'virtual-net-device', 
                      'visualizer', 'wave', 'wifi', 'wimax']

When waf is done scanning, a green message will be outputted in the terminal specifying the operation duration as well as the successfully built modules.

  Waf: Leaving directory `/usr/local/ns-allinone-3.26/ns-3.26/build'
  Build commands will be stored in build/compile_commands.json
  'build' finished successfully (19m42.182s)

  Modules built:
  antenna                   aodv                      applications              
  bridge                    buildings                 config-store              
  core                      csma                      csma-layout               
  dsdv                      dsr                       energy                    
  fd-net-device             flow-monitor              internet                  
  internet-apps             lr-wpan                   lte                       
  mesh                      mobility                  mpi                       
  netanim (no Python)       network                   nix-vector-routing        
  olsr                      point-to-point            point-to-point-layout     
  propagation               sixlowpan                 spectrum                  
  stats                     tap-bridge                test (no Python)          
  topology-read             traffic-control           uan                       
  virtual-net-device        visualizer                wave                      
  wifi                      wimax                     

  Modules not built (see ns-3 tutorial for explanation):
  brite                     click                     openflow 

If a specific module with the name my_module has only been changed, it can be scanned as follows: this will obviously help to cut down the scanning process execution time.

  # ./waf --apiscan=my_module

It is completely possible to detach and re-attach to the Hello-NS-3.26 docker container at any time:

  • To detach from the Hello-NS-3.26 docker container, you can use the shortcut ctrl+p ctrl+q
  • To re-attach, you can issue the command docker attach Hello-NS-3.26 or make ns-3-container-attach
  • To kill the docker container, detach first and then issue the command docker kill Hello-NS-3.26 or make ns-3-container-kill
  • To remove the container, you can issue the command docker rm Hello-NS-3.26 or make ns-3-container-rm
  • To clean the ns-3-allinone project, run make clean

About

Develop and prototype networking simulations on ns-3 inside a docker container using python

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published