Tuesday, February 23, 2016

Emulating Simple Networks with Mininet

In a previous blog post, I wrote about how to set up the environment for using Mininet simulator. Now, it's time to try some simple networks with it. It is important to note that in these emulations, we use python scripts to specify our network components and their connectivity. Then when we run the script, the network gets emulated on our Linux machine.  For this purpose, first of all we should start the Mininet VM and then log in to it remotely from our host Linux machine via SSH with X11 forwarding. How to do this is described in that previous blog post.

Let's start with a simple situation. We are going to define a switch and two hosts, which connects to that switch. Following code segment defines this setup and ping from each host to the other host.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/python

from mininet.topo import Topo
from mininet.net import Mininet
from mininet.util import dumpNodeConnections
from mininet.log import setLogLevel

class SingleSwitchTopo(Topo):
 "Single switch connected to 2 hosts."
 def build(self, n=2):
  switch = self.addSwitch('s1')
  host = self.addHost('h1')
  self.addLink(host, switch)
  host = self.addHost('h2')
  self.addLink(host, switch)

def simpleTest():
 "Create and test a simple network"
 topo = SingleSwitchTopo(n=4)
 net = Mininet(topo)
 net.start()
 print "Dumping host connections"
 dumpNodeConnections(net.hosts)
 print "Testing network connectivity"
 net.pingAll()
 net.stop()

if __name__ == '__main__':
 # Tell mininet to print useful information
 setLogLevel('info')
 simpleTest()

Save the above python script as test-network.py and run it as follows.

sudo python test-network.py

The output of this script is shown below.

Output of simple network
Now, it's time to improve the above script with a little more functionality. We can run a command on each host and display the output of them. Look at the following code which shows those changes to our python script.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/usr/bin/python

from mininet.topo import Topo
from mininet.net import Mininet
from mininet.util import dumpNodeConnections
from mininet.log import setLogLevel

class SingleSwitchTopo(Topo):
 "Single switch connected to 2 hosts."
 def build(self, n=2):
  switch = self.addSwitch('s1')
  host = self.addHost('h1')
  self.addLink(host, switch)
  host = self.addHost('h2')
  self.addLink(host, switch)

def simpleTest():
 "Create and test a simple network"
 topo = SingleSwitchTopo(n=4)
 net = Mininet(topo)
 net.start()
 print "Dumping host connections"
 dumpNodeConnections(net.hosts)
 print "Testing network connectivity"
 net.pingAll()
 
 print "Running ifconfig on the host h1"
 h1 = net.get('h1')
 result = h1.cmd('ifconfig')
 print result

 print "Running ifconfig on the host h2"
 h2 = net.get('h2')
 result = h2.cmd('ifconfig')
 print result

 net.stop()

if __name__ == '__main__':
 # Tell mininet to print useful information
 setLogLevel('info')
 simpleTest()

Now, running the script with above changes results in an output like the following. Please note that since the output is lengthy now, I'm just showing the place of the output which differs from the previous one. Which means the output of the 'ifconfig' commands on each host.

Output of 'ifconfig' command on each host
In addition to directly running commands on each host using the .cmd() function, there's another nice way of interacting with the hosts. For that, we have to take the command line interface of Mininet emulator. It is just a matter of adding a little line. Look at the following python script which simply do that.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/python

from mininet.topo import Topo
from mininet.net import Mininet
from mininet.util import dumpNodeConnections
from mininet.log import setLogLevel
from mininet.cli import CLI

class SingleSwitchTopo(Topo):
 "Single switch connected to 2 hosts."
 def build(self, n=2):
  switch = self.addSwitch('s1')
  host = self.addHost('h1')
  self.addLink(host, switch)
  host = self.addHost('h2')
  self.addLink(host, switch)

def simpleTest():
 "Create and test a simple network"
 topo = SingleSwitchTopo(n=4)
 net = Mininet(topo)
 net.start()
 CLI(net)
 net.stop()

if __name__ == '__main__':
 # Tell mininet to print useful information
 setLogLevel('info')
 simpleTest()

Running the above script results in a much different output than what we received so far. Here, we receive a command prompt from Mininet as follows. We can type various commands on this prompt and get various things done.

Mininet CLI
We can run the xterm terminals on the two hosts h1 and h2 of this network using this CLI interface. For that type the following line on the prompt and press Enter.

xterm h1 h2

By running that command, we now get two new windows with xterm terminals where each terminal belows to a host. Using these terminals, we can run different commands on each host. For example in the following figure, I have typed 'ifconfig' on one xterm to find the IP address of that host and then ping to it from the other host using its xterm terminal.

Ping from one host to the other through xterm


Similarly we can do many more things. Using the xterm of host 2, we can start Wireshark network protocol analyzer and then when we ping from the host 1, wireshark running on host 2 will display the packets. Following figure shows this scenario.
Ping from host 1 to host 2 while running wireshark on host 2.
That's all for now with a single switch and two hosts. Let's look at different other networking topologies in another blog post.

No comments:

Post a Comment