Welcome to minimega!
We are confident you will find minimega and its suite of tools to be incredibly powerful and highly flexible. As with all tools that can offer so much, it can be overwhelming to learn and master, so why should you take the time to do so? One of the primary reasons is the ability to quickly and repeatedly deploy experiment environments that you define, whether notional or representing a real network.
If you have questions about how specific networks behave under specific conditions, but cannot use real systems to experiment, minimega is for you.
Table of Contents
- Why use minimega
- Router Sandwich
- Describing a VM
- Networking
- Launching the Environment
- Launching the Experiment
- Data
Why use minimega?
minimega has tools that will help you
- define virtual endpoints, and create an experiment network of endpoints at scale
- create multiple copies of those experiment networks, segregated by namespace, to facilitate iterative experimentation
- instruments and capture data from your experiment, so you can analyze what you see
- generate background network traffic, modify the quality of service of your network
- and much much more…
- What this guide is
In this module, you will find a top-to-bottom overview of:
- The basics for using minimega
- How to create and modify virtual machines to deploy
- How to define and compose a virtual experiment
- How to instrument the virtual experiment
- How to modify your experiment, traffic files, data, and resources in real time
- How to learn more about every aspect of this process
We will walk through an experiment step by step to give you the basics you will need to get an experiment up and running in minimega.
What this guide is NOT
While this module (module 01) can get you up, running, and using minimega to launch simple experiments quickly, it is NOT a deep-dive into everything minimega can do. If you want a better understanding of how to use minimega and all of the tools it has to offer, we recommend starting with module 02 and working your way through the remaining modules.
Router Sandwich (explained)

This is a very simple experiment comprised of 2 VMs and a router between them. Each VM is in a different network, while the router is part of both networks. In Software Defined Networking (SDN), this network is a virtual one (VLAN). We will go through, step by step, all the minimega commands and supporting files required, to launch this environment. We will then run a simple experiment on this network, and capture data from that experiment.
Breaking it down pt. 1 – Describing a VM
The first part we will talk about is defining the 2 Virtual Machines that will be launched.
# start this experiment in a namespace
namespace sandwich
# describe vm_left
vm config kernel miniccc.kernel
vm config initrd miniccc.initrd
vm config memory 5096
vm config net net_left
vm launch kvm vm_left
# describe vm_right
# We don't need to specify kernel/initrd/memory again
# Our config carries over
vm config net net_right
vm launch kvm vm_right
Step 1 – Namespaces
minimega supports namespaces, so it is a good practice to declare a namespace before anyhing else. That’s why the first command is a namespace command.
Step 2 – Describing the VM
The most important command in minimega for defining a VM is vm
config`. When vm config is run with no parameters it will display the current vm configuration set. You will notice many parameters, but for now we will only consider the following:
- memory: while not necessary, we will increase the memory footprint to 5096 from the default 2048.
- network: We’ll add a nic to this VM and attach it to a VLAN using the alias
net_left
. Under the hood, minimega will take the next available vlan in range (e.g. 100) and use this alias to reference that VLAN. - VM image: more on that next.
A Virtual Machine requires an image from which to boot. For minimega this can be 1 of 2 flavors: KVM or Container. (For details on the difference, see ###training module 2.5### For our purposes, we will use a KVM. minimega supports a number of different KVM image types, but for this experiment we will use a kernel and initrd pair.
To learn how to build your own image to use for launching VMs, please see ###training module 2.5###
Breaking it down pt. 2 – Networking
# and a router
vm config kernel minirouter.kernel
vm config initrd minirouter.initrd
# notice the router has two networks!
vm config net net_left net_right
vm launch kvm router
# configure the router
router router interface 0 10.0.0.1/24
router router dhcp 10.0.0.0 range 10.0.0.2 10.0.0.2
router router dhcp 10.0.0.0 dns 10.0.0.2
router router interface 1 20.0.0.1/24
router router dhcp 20.0.0.0 range 20.0.0.2 20.0.0.2
router router dhcp 20.0.0.0 dns 20.0.0.2
router router route ospf 0 0
router router route ospf 0 1
router router commit
Step 3 – Defining the Router and configure the router
In order to allow network traffic to flow between VMs, we will need to ensure that the VMs are configured for the same network. We can do this many different ways, but here we will demonstrate using minirouter to accomplish this task. First, we change the kernel and initrd pair to use an image that is pre-loaded with the minirouter binary.
Note: it is possible to load all the software required to a single VM image, and use that image for every virtual machine, but that can be impractical. Sometimes, it’s best to use the right image for the right VM.
Next, we add the router VM to both networks: the network vm_left is in, and the network vm_right is in.
After we launch the router, you will notice we issue several router commands to set up the network. Let’s go through them one at a time.
- router router interface 0 10.0.0.1/24
- This command assigns a new interface to the router VM and sets the IP address and mask.
- router router dhcp 10.0.0.0 range 10.0.0.2 10.0.0.2
- This command instructs the router to act as DHCP, listening on 10.0.0.0 for requests.
- The range of IP address to be given out has been restricted to a single address in this case, starting at 10.0.0.2, and ending at the same.
- Then, a second interface is added to the router VM, and again, the router will act as DHCP, listening on and distributing a separate range of IP addresses.
- Then, we define a routing protocol of OSPF. These two lines allow the traffic of each network to cross over via the router.
Details on how OSPF works is beyond the scope of this tutorial, however we recommend the user be familiar with such networking details, if this impacts how you will be configuring your experiment. Finally, after any router commands are defined, the user must commit the commands using the commit command: router router commit. This will apply the changes defined in your commands.
Breaking it down pt. 3 – Launching the Environment
shell echo "start the router first, and give it a chance to configure"
vm start router
shell sleep 10
# "all" is a special keyword
vm start all
shell echo "give VMs 20 seconds to obtain IP..."
shell sleep 20
# make sure everything booted and connected
shell echo "vm info:"
.column id,name,state,vlan,ip,qos vm info
The next command launches the router VM, however you should know that the VM is not yet useable! Launching means it is in a ready state, and waiting to be started. You will notice in the script we sleep for a number of seconds to allow the router configurations to process before proceding. Then, we start all of the VMs. This puts everything in the RUNNING
state, ready for our experiment.
We give the VMs time to launch, POST, and obtain network IPs via DHCP. Then the last line: .column id,name,state,vlan,ip,qos vm info asks minimega to display the specified information for all existing VMs. We are ready to run our experiment.
Breaking it down pt. 4 – Launching the Experiment
# collect some control data
shell echo "vm top:"
vm top
# notice there is no data traveling across the network (rx/tx == 0.00)
# Let's fix that!
# Let's use miniccc to push out a tool to our VMs
cc send file:protonuke
# We will have vm_left server traffic
cc filter name=vm_left
cc background /tmp/miniccc/files/protonuke -serve -http
cc background /tmp/miniccc/files/protonuke -serve -https
# We will have vm_right request http/https
clear cc filter
cc filter name=vm_right
cc background /tmp/miniccc/files/protonuke -level info -logfile proto.log -http -https 10.0.0.2
Step 5 – Conducting an Experiment
minimega has a built-in vm
topcommand that is similar to the
top` command found in typical Linux distributions. Specifically, we can use it to get a broad snapshot of traffic flowing in an out of each VM. However, there is no traffic flow over our network, so there are no values. There is a tool in the minimega suite that we can use to send generic background traffic over the network.
This is called protonuke
and we can send it out to our VMs using minimega’s command and control API. This API, miniccc, can allow us to accomplish a number of tasks including file i/o, command execution, and post-boot VM configuration. For more details on Command and Control, see [[/training/module07.slide][module 07]]
Step 6 – Command and Control
The following command copies the protonuke binary to all VMs:
cc send file:protonuke
By default, minimega looks in /tmp/minimega/files for any file indicated in commands that do not have an explicit path. The next commands run the protonuke binary in the background with specific options for specific traffic:
cc background /tmp/miniccc/files/protonuke -serve -http
cc background /tmp/miniccc/files/protonuke -serve -https
miniccc mastery
miniccc allows you to filter on specific VMs so you can isolate which VMs the command is for:
cc filter name=vm_right
allows us to specify the VM we want to target. You can filter on any property of a VM, including tags. Finally, we run protonuke in the background on vm_right to request http/https traffic, which we told vm_left to serve. We ask it to request from 10.0.0.2 (vm_left) and we set the log to allow info-level detail and print to a file
cc background /tmp/miniccc/files/protonuke -level info -logfile proto.log -http -https 10.0.0.2
Breaking it down pt. 5 – Data
shell echo "Now let's check our traffic levels:"
vm top
# Notice that we have values in rx/tx now
# Notice, also the difference in values for the roles each are playing
# Now let's turn on qos to manipulate the network traffic
qos add vm_left 0 loss 0.5
# this will force the interface for vm_right to drop half the packets it receives to simulate packet loss
# let's see how this changes what we see over the network:
shell sleep 20
vm top
# clean up
#clear namespace sandwich
Step 7: Getting data
Checking v
m
top again, we see that traffic is flowing across the network as indicated by the rx and tx values in the table.

Modifying the Experiment
What would happen if our network experienced a drop in Quality of Service? With minimega, there is a built-in QOS API that allows you to ask these questions. The next commands we run will introduce packet loss to the network:
qos add vm_left 0 loss 0.5
We need to give the network some time to allows the QOS API to take effect.
Checking vm
top one last time, we can see what the packet loss does to the throughput values we see
Wrapping it all up
And that’s it!
You now have a great deal of knowledge in running minimega. Enough so that you can start to create your own experiments and start exploring the countless ways to configure your environment to suit an experiment of your choice. Or build on this experiment and start accumulating data. The choice is yours.
We recommend going through all of the training modules available to you. There is an extraordinary amount of ways to build and deploy your environment with minimega. There are dozens of tools available to you to learn and use.
next up: [[module02.slide][module 02: Getting Running]]