Try   HackMD

Lab 1 - Mininet - Introduction to Mininet

tags: LAB

All the code necessary for this Lab session is available in Poliformat/RSE: Recursos/Laboratorio/código practicas laboratorio, or here: https://bit.ly/codigoRSE2021

In the following:

  • $ or #preceeds Linux commands that should be typed at the shell prompt
  • mininet> preceeds Mininet commands that should be typed at Mininet’s CLI

This lab demonstrates most Mininet commands, as well as its typical usage in concert with the Wireshark dissector.

Mininet will be executed as a Docker container. The Dockefile to create the image can be found here: https://github.com/pmanzoni/mininet-in-a-container
The image can be found here: https://hub.docker.com/r/pmanzoni/mininet-in-a-container

We first start the Mininet container naming it mininet. Open a Terminal and type the following command:

$ docker run -it --rm --privileged -e DISPLAY \
             -v /tmp/.X11-unix:/tmp/.X11-unix \
             -v /lib/modules:/lib/modules \
             --name=mininet \
             pmanzoni/mininet-in-a-container

If you cannot open xterm or other X Window applications, do this on your "Docker host" (not on your containers).

$ xhost +local:*

Part 1: Basic Mininet Usage

From now on you are supposed to work with the terminal where the mininet contaniner is running.

Display Startup Options

Let’s get started with Mininet’s startup options.

Type the following command to display a help message describing Mininet’s startup options:

​​​​# mn -h

check all the possibility offered by this tool.

Interact with Hosts and Switches

Now, start a minimal topology and enter the CLI:

​​​​# mn

You just created this network:

The message:
*** Error setting resource limits. Mininet's performance may be affected.
is expected and is not a problem.

The default topology is the minimal topology, which includes one OpenFlow kernel switch connected to two hosts, plus the OpenFlow reference controller. This topology could also be specified on the command line with --topo=minimal. Other topologies are also available out of the box; see the --topo section in the output of mn -h.

All four entities (2 host processes, 1 switch process, 1 basic controller) are now running in the container; the Mininet CLI comes up.

Some basic commands try them!

  • Display the Mininet CLI commands:
    mininet> help

  • Display the nodes:
    mininet> nodes

  • Display the links:
    mininet> net

  • Dump information about all nodes:
    mininet> dump

You should see the switch, the controller and two hosts listed.

More on commands:

If the first string typed into the Mininet CLI is a host, switch or controller name, the command is executed on that node.
For example, to run ifconfig -a on host h1:

​​​​mininet> h1 ifconfig -a

You should see the host’s h1-eth0 and loopback (lo) interfaces. Note that this interface (h1-eth0) is not seen by the primary Linux system when ifconfig is run, because it is specific to the network namespace of the host process.

In contrast, the switch by default runs in the root network namespace, so running a command on the “switch” is the same as running it from a regular terminal:

​​​​mininet> s1 ifconfig -a

This will show the switch interfaces, plus the container’s connection out (eth0).

1.- Prueba a ejecutar el comando route en los diferentes dispositivos. Este comando se utiliza cuando se quiere trabajar con la tabla de enrutamiento IP/kernel. Se utiliza principalmente para configurar rutas estáticas a hosts o redes específicas a través de una interfaz. Se utiliza para mostrar o actualizar la tabla de enrutamiento IP/kernel.

Apunta el resultado en el documento a entregar.

Note that only the network is virtualized; each host process sees the same set of processes and directories. For example, print the process list from a host process:

​​​​mininet> h1 ps -a

This should be the exact same as that seen by the root network namespace:

​​​​mininet> s1 ps -a

Having everything run in the “root” process namespace is convenient for debugging, because it allows you to see all of the processes from the console using ps, kill, etc.

Test connectivity between hosts

To view control traffic using the OpenFlow Wireshark dissector, first open another Terminal in your host machine and execute:

$ docker exec -it mininet /bin/bash
# wireshark

This will execute wireshark in the mininet container.

Select the loopback interface (lo) and start capturing.

In the display filter box enter the value openflow_v5, then click Apply.

Wireshark will allow you to view all the traffic, in this case openflow related, that is interchanged during the examples.

Now, verify that you can ping from host 0 to host 1:

​​​​mininet> h1 ping -c 1 h2

If a string appears later in the command with a node name, that node name is replaced by its IP address; this happened for h2.

You should see OpenFlow control traffic. The first host ARPs for the MAC address of the second, which causes a packet_in message to go to the controller. The controller then sends a packet_out message to flood the broadcast packet to other ports on the switch (in this example, the only other data port). The second host sees the ARP request and sends a reply. This reply goes to the controller, which sends it to the first host and pushes down a flow entry.

Now the first host knows the MAC address of the second, and can send its ping via an ICMP Echo Request. This request, along with its corresponding reply from the second host, both go the controller and result in a flow entry pushed down (along with the actual packets getting sent out).

Repeat the last ping:

​​​​mininet> h1 ping -c 1 h2

You should see a much lower ping time for the second try (< 100us). A flow entry covering ICMP ping traffic was previously installed in the switch, so no control traffic was generated, and the packets immediately pass through the switch.

An easier way to run this test is to use the Mininet CLI built-in pingall command, which does an all-pairs ping:

​​​​mininet> pingall

Exiting

To leave Mininet, from the CLI:

​​​​mininet> exit

Cleanup

If Mininet crashes for some reason, clean it up:

​​​​# mn -c

Part 2: Advanced Startup Options

Changing Topology Size and Type

The default topology is a single switch connected to two hosts. You could change this to a different topo with --topo, and pass parameters for that topology’s creation. For example, to verify all-pairs ping connectivity with one switch and three hosts:

Run a regression test:

​​​​# mn --test pingall --topo single,3

Another example, with a linear topology:

​​​​# mn --test pingall --topo linear,4

2.- Dibuja la estructura de red que obtienes con este ultimo .
Apunta el resultado en el documento a entregar.

Mininet allows you to set link parameters, and these can even be set automatically from the command line:

​​​​ # mn --link tc,bw=10,delay=10ms

3.- Utilizando ping calcula la diferencia con el caso sin definir los "link parameters"
Apunta el resultado en el documento a entregar.

4.- Ahora repite lo mismo pero utilizando el comando iperf. ¿Como?
Detalla como lo has hecho en el documento a entregar.
(Ayuda: usa el comando help de mininet)

It can sometimes be helpful to bring links up and down, for example for fault tolerance testing,

To disable both halves of a virtual ethernet pair:

​​​​mininet> link s1 h1 down

You should see an OpenFlow Port Status Change notification get generated. Try pingall does it work? To bring the link back up:

​​​​mininet> link s1 h1 up

XTerm Display

Before doing this part, do the following to improve the readibility of the xterm:
# cd
# xrdb ./.Xresources

To start an xterm for every host and switch, pass the -x option:

# mn -x

After a second, the xterms will pop up, with automatically set window names.

Alternately, you can bring up additional xterms as shown below.

​​​​mininet> xterm h1 h2

You can tell whether an xterm is in the root namespace by checking ifconfig; if all interfaces are shown (including eth0), it’s in the root namespace. Additionally, its title should contain “(root)”.

By default, only the hosts are put in a separate namespace; the window for each switch is unnecessary (that is, equivalent to a regular terminal), but can be a convenient place to run and leave up switch debug commands, such as flow counter dumps.

Xterms are also useful for running interactive commands that you may need to cancel, for which you’d like to see the output.

For example, start mininet with:
# mn -x

In the xterm labeled “switch: s1 (root)”, run:

# ovs-ofctl dump-flows tcp:127.0.0.1:6654

ovs-ofctl is a management utility that enable some control over the OpenFlow switch

Nothing will print out; the switch has no flows added.

Now, in the xterm labeled “host: h1”, run:

# ping 10.0.0.2

Go back to s1 and dump the flows. You should see multiple flow entries now. We'll see the details of flows in the next laboratory session.

Run a simple web server and client

Remember that ping isn’t the only command you can run on a host! Mininet hosts can run any command or application that is available to the underlying Linux system (or VM) and its file system. You can also enter any bash command, including job control (&, jobs, kill, etc..)

5.- Sabiendo que:

  • $ python2 -m SimpleHTTPServer 80
    ejecuta un simple HTTP server, y que:
  • $ wget -O - __HTTP_server_address__
    ejecuta una get como cliente al server __HTTP_server_address__

indica la secuencias de ordenes para ejecutar el server HTTP en h1 y el cliente get en h2 en la topologia minima de Mininet.

Detalla como lo has hecho en el documento a entregar.

Part 3: Python API Examples

Python Interpreter

If a Mininet command line starts with py, then that command is executed with Python. This is useful for extending Mininet, as well as probing its inner workings. Each host, switch, and controller has an associated Node object.

At the Mininet CLI, run:

​​​​mininet> py 'hello ' + 'world'

Print the accessible local variables:

​​​​mininet> py locals()

Next, see the methods and properties available for a node, using the dir() function:

​​​​mininet> py dir(s1)

You can read the on-line documentation for methods available on a node by using the help() function:

​​​​mininet> py help(h1) 

(Press "q" to quit reading the documentation.)

You can also evaluate methods of variables:

​​​​mininet> py h1.IP()

Python can be used to create network to be evalauted. With a few lines of Python code, you can create a flexible topology which can be configured based on the parameters you pass into it, and reused for multiple experiments.

Naming in Mininet
In order to use Mininet effectively, it is important to understand its naming scheme for hosts, switches and interfaces.
Usually, hosts are called h1..hN and switches are called s1..sN.

For clarity, interfaces belonging to a node are named beginning with the node's name, for example h1-eth0 is host h1's default interface, and s1-eth1 is switch s1's first data port.

Host interfaces are only visible from within the host itself, but switch data ports are visible in the "root" namespace (you can see them by typing ip link show in another window while Mininet is running.) As a result, it's easy to examine switch interfaces but slightly trickier to examine host interfaces, since you must tell the host to do so (typically using host.cmd().)

For example, here is a simple network topology (File: fourhostnet.py) which consists of 4 hosts connected to a single switch (s1):

#!/usr/bin/python # File: fourhostnet.py from mininet.net import Mininet from mininet.node import OVSController from mininet.cli import CLI from mininet.log import setLogLevel, info def emptyNet(): "Create an empty network and add nodes to it." net = Mininet( controller=OVSController ) info( '*** Adding controller\n' ) net.addController( 'c0' ) info( '*** Adding hosts\n' ) h1 = net.addHost( 'h1', ip='10.0.0.1' ) h2 = net.addHost( 'h2', ip='10.0.0.2' ) h3 = net.addHost( 'h3', ip='10.0.0.3' ) h4 = net.addHost( 'h4', ip='10.0.0.4' ) info( '*** Adding switch\n' ) s1 = net.addSwitch( 's1' ) info( '*** Creating links\n' ) net.addLink( h1, s1 ) net.addLink( h2, s1 ) net.addLink( h3, s1 ) net.addLink( h4, s1 ) info( '*** Starting network\n') net.start() info( '*** Running CLI\n' ) CLI( net ) info( '*** Stopping network' ) net.stop() if __name__ == '__main__': setLogLevel( 'info' ) emptyNet()

Important classes, methods, functions and variables in the above code include:

  • addSwitch(): adds a switch to a topology and returns the switch name
  • addHost(): adds a host to a topology and returns the host name
  • addLink(): adds a bidirectional link to a topology (and returns a link key, but this is not important). Links in Mininet are bidirectional unless noted otherwise.
  • Mininet: main class to create and manage a network
  • start(): starts your network
  • pingAll(): tests connectivity by trying to have all nodes ping each other
  • stop(): stops your network
  • net.hosts: all the hosts in a network
  • dumpNodeConnections(): dumps connections to/from a set of nodes.
  • setLogLevel( 'info' | 'debug' | 'output' ): set Mininet's default output level; 'info' is recommended as it provides useful information.

Running this script:

​​​​$ python2 fourhostnet.py

should result in something like the following:

    *** Adding controller
    *** Adding hosts
    *** Adding switch
    *** Creating links
    *** Starting network
    *** Configuring hosts
    h1 h2 h3 h4 
    *** Starting controller
    c0 
    *** Starting 1 switches
    s1 ...
    *** Running CLI
    *** Starting CLI:
    mininet> 

use ping or pingall to evaluate connectivity.

Host Configuration Methods

Mininet hosts provide a number of convenience methods for network configuration:

  • IP(): Return IP address of a host or specific interface.
  • MAC(): Return MAC address of a host or specific interface.
  • setARP(): Add a static ARP entry to a host's ARP cache.
  • setIP(): Set the IP address for a host or specific interface.
  • setMAC(): Set the MAC address for a host or specific interface

For example:

​​​​print "Host", h1.name, "has IP address", h1.IP(), "and MAC address", h1.MAC()

6.- Modifica el codigo de la red de arriba para que imprima la direccion IP y el MAC de cada host

Detalla como lo has hecho en el documento a entregar.

Setting Performance Parameters

In addition to basic behavioral networking, Mininet provides performance limiting and isolation features, through the CPULimitedHost and TCLink classes.

from mininet.node import CPULimitedHost from mininet.link import TCLink ... net = Mininet( controller=Controller, host = CPULimitedHost, link = TCLink )
  • self.addHost(name, cpu=f): This allows you to specify a fraction of overall system CPU resources which will be allocated to the virtual host.

  • self.addLink( node1, node2, bw=10, delay='5ms', max_queue_size=1000, loss=10, use_htb=True): adds a bidirectional link with bandwidth, delay and loss characteristics, with a maximum queue size of 1000 packets using the Hierarchical Token Bucket rate limiter and netem delay/loss emulator. The parameter bw is expressed as a number in Mbit; delay is expressed as a string with units in place (e.g. '5ms', '100us', '1s'); loss is expressed as a percentage (between 0 and 100); and max_queue_size is expressed in packets.

7.- Modifica el codigo de la red de arriba, para que los enlaces sean de 10 Mbps y con un retardo de 10ms. Calcula las prestaciones del enlace entre h1 y h3

Detalla como lo has hecho en el documento a entregar.