How to simulate an IPv6 network using the cloonix network simulator

As we work through this tutorial, we will learn how to use the cloonix graph interface to build a simulation scenario that includes two small IPv6 networks connected to each other by two routers via static routes. We will also learn how cloonix saves network topologies and guest virtual machine root filesystems.

Cloonix IPv6 linux network simulation
Linux IPv6 network simulation running on the cloonix open-source network simulator

The cloonix open-source network simulator uses KVM virtual machines in the simulated network so, in this tutorial, we will demonstrate real Linux router and host configuration procedures.

Procedure summary

First, let’s review the high-level steps we will execute to set up and configure a simulated IPv6 network and then save a network topology and node configurations.

  1. Create root filesystems, one for each virtual machine we plan to create in the simulation
  2. Create static guest virtual machines with the previously-created root filesystems
  3. Connect nodes to create a network topology
  4. Configure each node in the simulated network
  5. Save the network simulation scenario for future use
  6. (Optional) Make changes and save another version of the topology
  7. (Optional) Load a saved network simulation scenario

Step 1: Create root filesystems

We intend to create a scenario made up of static root filesystems so we can preserve all configuration changes when we save the simulation topology.

We must create a new root filesystem for each network element we plan to use in the network simulation. The easiest way to do this is to copy an existing root filesystem. In our post about upgrading a guest virtual machine in cloonix, we already saved a root filesystem that has basic networking software installed and named it jessie-networking.qcow2 in the cloonix bulk directory. We will use that filesystem in this example.

Since this network scenario will have two routers and four clients, we will copy the jessie-networking.qcow2 file and name each copy so it has a unique, descriptive name.

$ cd /home/blinklet/Netsims/cloonix-24.11/bulk/
$ cp jessie-networking.qcow2 Router1.qcow2
$ cp jessie-networking.qcow2 Router2.qcow2
$ cp jessie-networking.qcow2 Client1.qcow2
$ cp jessie-networking.qcow2 Client2.qcow2
$ cp jessie-networking.qcow2 Client3.qcow2
$ cp jessie-networking.qcow2 Client4.qcow2

We now have six unique root filesystems we can use as static filesystems in our network simulation scenario.

Step 2: Create guest virtual machines with static filesystems

We require six nodes in our simulation scenario: two routers and four clients.

Start cloonix

As always, when starting cloonix for the first time, we ensure KVM is set up correctly. Then, we start the cloonix daemon and then the graph interface.

$ sudo modprobe kvm-intel nested=1
$ sudo chmod 666 /dev/kvm
$ cd ~/Netsims/cloonix-24.11
$ ./start_cloonix_net
$ ./graph

Add the Router1 node to the simulation

To create the first router node, right-click on the VM object in the cloonix graph interface. Then configure the virtual machine as listed below:

  • Check the ballooning box
  • Un-check the Append end number box
  • Max eth = “3” (one extra in case we need to use the slirp interface at any time)
  • RAM = “1000”
  • Cores = “1”
  • Use the guest VM Rootfs = “/home/blinklet/Netsims/cloonix-24.11/bulk/Router1.qcow2”
  • Give it the Name = “Router1”

This is what the VM object will look like. Click the OK button.

IPv6-NDP-cloonix-300

Add the Router2 node to the simulation

To create the second router, Router2, right-click on the VM object in the cloonix graph interface. Then configure the virtual machine as listed below:

  • Use the same settings as Router1, except for the following:
  • Use the guest VM Rootfs = “/home/blinklet/Netsims/cloonix-24.11/bulk/Router2.qcow2”
  • Give it the Name = “Router1”

Drag the VM object onto the graph interface. An guest virtual machine named Router2 will appear, colored red.

Add the Client1 node to the simulation

To create the first client, right-click on the VM object in the cloonix graph interface. Then configure the virtual machine as listed below:

  • Check the ballooning box
  • Un-check the Append end number box
  • Max eth = “2” (one extra in case we need to use the slirp interface at any time)
  • RAM = “1000”
  • Cores = “1”
  • Use the guest VM Rootfs = “/home/blinklet/Netsims/cloonix-24.11/bulk/Client1.qcow2”
  • Give it the Name = “Client1”

Drag the VM object onto the graph interface. An guest virtual machine named Router2 will appear, colored red.

Add the remaining three Client nodes to the simulation

Repeat the process used to create the Client1 node, except use the other Client root filesystems created in Step 1 and name each new client Client2, Client3 and Client4.

  • Client1
    • Rootfs = “/home/blinklet/Netsims/cloonix-24.11/bulk/Client1.qcow2”
    • Name = “Client1”
  • Client2
    • Rootfs = “/home/blinklet/Netsims/cloonix-24.11/bulk/Client2.qcow2”
    • Name = “Client2”
  • Client3
    • Rootfs = “/home/blinklet/Netsims/cloonix-24.11/bulk/Client3.qcow2”
    • Name = “Client3”

The guest virtual machines will appear as red circles. When they finish starting up, they will turn blue.

Drag VM objects onto canvas
New guest virtual machines starting up

Step 3: Connect nodes to create a network topology

Once the new static guest virtual machines are started, we build the network topology using the LAN object to connect nodes to each other.

Hide extra interfaces

We created one extra interface on each guest virtual machine we created. If we are required to update or install new software on any of the guest virtual machines, we will use these extra interfaces to connect a guest virtual machine to the internet via the slirp interface. For now, we will hide these extra interfaces because they are not part of the simulation.

Right-click on each interface we wish to hide and select Hidden/Visible from the menu. The interface will disappear from the canvas.

Hide unused interfaces
Hide unused interfaces

If we need to use any hidden interfaces or nodes again, right-click on a blank area of the canvas and select Hidden/Visible from the menu. A window pops up that shows the all the hidden network elements.

Uncheck the boxes to make hidden elements visible again
Uncheck the boxes to make hidden elements visible again

Uncheck the box next to the required interface to make visible on the cloonix graph interface.

Turn off motion

Turn off motion because, when you connect LANs to interfaces, the VMs and LANs start moving to create a mathematically symmetrical network topology. We want to manually arrange the nodes and interfaces on the graph interface.

To turn of the Motion feature, right-click on a blank part of the graph interface and select the menu command Motion → stop.

Stop motion to prevent objects moving around when they are connected together
Stop motion to prevent objects moving around when they are connected together

Add LANs

To add a LAN, drag the LAN object onto the graph interface. A small grey circle appears. Drag two more LAN objects onto the graph so we have three LANs.

To connect a LAN to a guest virtual machine, double-click on the LAN to which we need to connect. It will turn purple. Then, click on an interface on the guest virtual machine to which we want to connect.

Add LANs and connect nodes together
Add LANs and connect nodes together

As a useful convention, we chose to connect all the eth0 interface on each virtual machine on the same network to the eth0 interface on the router connected to that network and we connected the eth1 interface on each router together.

Arrange nodes in the network topology

Now drag the nodes around to create a logical network topology. To move all nodes at the same time, click on a blank spot on the graph and drag.

Drag interfaces around the VM by click-dragging the small green circle that represents the interface. At the end, we should have a topology that looks like this:

Final network topology
Final network topology

Change color of VMs

Cloonix allows you to set the color of each VM. In this example, this is useful to annotate VMs that are in the same subnet. We’ll color Client1 and Client2 blue, Client3 and Client4 cyan, and Router1 and Router2 brown

Change color of nodes, if you find it helpful
Change color of nodes, if you find it helpful

Right-click on the VM and select Color from the menu, then select one of the three available colors

Colorized topology
Colorized topology

Step 4: Configure the network elements

Login to each guest VM and configure networking features so that we can simulate the operation of a small IPv6 network. In this example, the client nodes are all configured using standard Linux configuration files. We also configure standard Linux configuration files on Router1 but we use the quagga open-source router on Router2, just to show an alternative way to configure routing.

Configure all clients

Each client has the same physical setup: one interface, eth0, connected to a LAN. So, double-click on each Client virtual machine to open up a terminal session ans make the following configuration changes on every Client.

Edit the /etc/networking/interfaces file:

# vi /etc/network/interfaces

and add the following lines to the file on each client, then save the file.

auto eth0
iface eth0 inet manual
   up ip link set dev $IFACE up
   down ip link set dev $IFACE down

Restart the networking service

# service networking restart

Configure Router1

The router, Router1, has two interfaces: eth0 is connected to a network used by client machines and eth1 is connected to the other router.

First, we need to enable IPv6 forwarding. A router needs to be able to forward packets received on one interface out to another interface.

Double-click on Router1 to open a terminal session and edit the sysctl.conf file.

# vi /etc/sysctl.conf

Uncomment the following line in the file, then save the file:

net.ipv6.conf.all.forwarding=1

Activate the changes by forcing the Linux system to parse the file again:

# sysctl -p /etc/sysctl.conf

Set up the ethernet interfaces and static routes. We need to give each interface an global IPv6 address. We also add an extra link-local IPv6 address on the eth1 interface, just to make the routing configuration easier to read.

We also set up a static route so the router can forward packets from the blue subnet to the cyan subnet. We used the fe80::2/64 link-local address we manually created on Router2 (see below) when configuring the static route — because it is easier to type in a short address than the system-generated link-local address.

Edit the file /etc/network/interfaces:

# vi /etc/network/interfaces

Add the following lines to the file, then save the file:

auto eth0
iface eth0 inet6 static
address 2001:db8:0:1::1
netmask 64
auto eth1
iface eth1 inet6 static
address 2001:db8:0:2::1
netmask 64    
iface eth1 inet6 static
address fe80::1
netmask 64
up ip -6 route add 2001:db8:0:3::/64 via fe80::2 dev eth1
down ip -6 route add 2001:db8:0:3::/64 via fe80::2 dev eth1

Restart the networking service to activate the changes:

# service networking restart

Configure radvd. The radvd daemon provides IPv6 automatic address configuration. It runs on the router and sends Router Advertisements to hosts on the LAN, advertising the global IPv6 prefix that the hosts should use to automatically create global IPv6 addresses.

Edit the radvd.conf file:

# vi /etc/radvd.conf

Add the following lines to the file, then save the file:

interface eth0
{
    AdvSendAdvert on;
    prefix 2001:db8:0:1::/64 { };
};

Start the radvd daemon

# service radvd start

Configure Router2

On the second router, Router2, we use the quagga open-source routing service. We still need to make some changes to the interfaces configuration file but we do not need to enter any network-layer information, because we will enter that information into the quagga command-line interface.

Double-click on Router2 to open a terminal session. To enable IPv6 forwarding, edit the sysctl.conf file:

# vi /etc/sysctl.conf

Uncomment the following line, then save the file:

net.ipv6.conf.all.forwarding=1

Activate the changes:

# sysctl -p /etc/sysctl.conf

Edit the file /etc/network/interfaces:

# vi /etc/network/interfaces

Add the following text to the file, then save the file:

auto eth0
iface eth0 inet manual
   up ip link set dev $IFACE up
   down ip link set dev $IFACE down
auto eth1
iface eth1 inet manual
   up ip link set dev $IFACE up
   down ip link set dev $IFACE down

To set up quagga on Router2, we first edit the /etc/quagga/daemons file and enable the daemons that quagga will start. In this example, we use only static routes, so we need to enable only the Zebra daemon.

Edit the quagga daemons file:

# vi /etc/quagga/daemons

Enable the quagga daemons we need. For now, just enable zebra: change “no” to “yes” on the zebra line in the file, then save the file.

zebra=yes
bgpd=no
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
babeld=no

Create the Zebra configuration file and the vtysh configuration file. The files must exist or quagga will not start. We can create blank files or we can use an example file from the quagga documentaion package. In this example, we will copy the example files to the correct location so quagga can use it.

# cp /usr/share/doc/quagga/examples/vtysh.conf.sample /etc/quagga/vtysh.conf
# cp /usr/share/doc/quagga/examples/zebra.conf.sample /etc/quagga/zebra.conf

Change the owner and permissions of the quagga configuration files, so quagga can write to the configuration files:

# chown quagga.quaggavty /etc/quagga/*.conf
# chmod 640 /etc/quagga/*.conf

Start the Quagga daemons, then start the vty shell

# service quagga start
# vtysh

Configure Router2 using the vty shell commands:

conf term
int eth0
no shutdown
no ipv6 nd suppress-ra
ipv6 address 2001:db8:0:3::1/64
ipv6 nd prefix 2001:db8:0:3::/64
exit
int eth1
no shutdown
ipv6 address 2001:db8:0:2::2/64
ipv6 address fe80::2/64
exit
ipv6 route 2001:db8:0:1::/64 fe80::1 eth1
exit

Again, when configuring the static route, we use the fe80::1/64 link-local address we manually created on Router1 (see above).

Save the quagga configuration files and exit quagga using the vty shell commands:

write
exit

Test the setup

Now, that the routers are configured, each client should have a global IPv6 address automatically assigned and should be reachable from any point on the network. To test this, ping from Client4 to Client1.

Determine the IPv6 address of the eth0 interface on Client1 using the ifconfig eth0 command. In this case, it was 2001:db8:0:1:a4:7eff:fe02:300. On Client4, ping Client1 by entering the command:

# ping6 2001:db8:0:1:a4:7eff:fe02:300

The ping should be successful. We have successfully configured and simulated a routed IPv6 network.

Step 5: Save the static network simulation scenario

Now, save the topology using the cloonix menu command Save Topo,rootfs,configs.

Save topology and static filesystems
Save topology and static filesystems

In the file save dialogue window, enter the name of the saved scenario. Click the Save button. This creates a new directory that contains the topology and the root filesystems for each node in the scenario. Because we used static guest machines, the configuration files we created on each node are saved in the root filesystems for each node.

Step 6: Make changes and save another version of the scenario

To demonstrate how cloonix manages scenario files, we make some changes to the scenario and then save another version. This is an optional step, to demonstrate how cloonix manages scenario files.

Add sniffers to the topology

It is useful to have sniffers set up in the parts of the network where we may want to analyze data packets. Sniffers may only be connected to LAN objects. We will connect a sniffer to each of the three LANs in the scenario.

Drag the snf object onto the canvas three times to create three sniffers. Then connect each sniffer to one of the LANs as shown in the diagram.

Add traffic sniffers
Add traffic sniffers

Save new topology

When we save the topology again, we see we cannot save using the same name. We must create a new name for the changed scenario and save it.

Save new version
Save new version

In this example, we save a new scenario named ipv6-example-v2.

Step 7: Load saved network simulation scenario

To test that we can load a saved scenario, we must quit cloonix to clear the previous simulation and then start it again. Use the ctrl -k command to quit cloonix and delete all processes owned by cloonix.

$ cd ~/Netsims/cloonix-24.11
$ ./ctrl -k

Then start cloonix again

$ ./start_cloonix_net
$ ./graph

Load saved topology

To load a saved topology, right-click on the graph interface and select the Load Topo menu command.

description
Load Topo menu command

Choose the topology we want to load. In this case, it is our most recently saved version, IPv6-example-v2.

IPv6-NDP-cloonix-340
Select the topology to load

The topology will build up and the guest machines will start. Each machine still has the configurations we created during the previous steps so the scenario should be operational as soon as all the guest virtual machiones start.

Load topology in progress
Load topology in progress

After a while, we see that the topology is fully loaded. The nodes change color from red to one of the three configured colors: blue, cyan, or brown. We can ping between Client nodes to prove the scenario is working.

Topology load completed
Topology load completed

Conclusion

We showed how to set up a network simulation scenario in the cloonix open-source network simulator using static guest machines. We demonstrated that static guest machines allow us to save node configurations.

We also showed how to set up persistent IPv6 routing configurations on IPv6 routers using either standard configuration files or quagga. We demonstrated the procedures we would use on real Linux routers.