Configuring a Virtual Network
A virtual network's topology and routing protocols are specified by means of a configuration file containing Ruby objects and variables. The basic idea is to define a Node object for each router in your experiment, and a Link object between two Node objects for each virtual link. The Node and Link objects can be further customized to produce different experimental behaviors. Some knowledge of Ruby is useful but not essential for configuring an experiment. Jump ahead to:
- An example configuration file
- Specifying global defaults
- Creating Slice objects
- Creating Node objects
- Creating Link objects
- Configuring routing protocols
- Specifying external destinations
- Running OpenVPN servers
A simple virtual network configuration file is given below. This file is stored as config/vini.rb. It does the following:
- Sets up a simple five-node virtual network running OSPF.
- Configures two of the nodes as NAT egress points for nearby destinations.
- Runs OpenVPN servers on one node.
- Provides some additional host information so that the scripts do not have actively gather it.
### Specify global defaults
### Slices
$iias = Slice.new(13654, 4801, 'princeton_iias', true, 'XORP')
### Nodes
$pr = Node.new('vini1.princeton.vini-veritas.net', $iias, 'pr')
$ny1 = Node.new('vini1.newy.internet2.vini-veritas.net', $iias, 'ny1')
$ch1 = Node.new('vini1.chic.internet2.vini-veritas.net', $iias, 'ch1')
$ny2 = Node.new('vini2.newy.internet2.vini-veritas.net', $iias, 'ny2')
$ch2 = Node.new('vini2.chic.internet2.vini-veritas.net', $iias, 'ch2')
### Links
$l1 = Link.new($pr, $ny1, 50)
$l2 = Link.new($pr, $ny2, 50)
$l3 = Link.new($ny1, $ch1, 700)
$l4 = Link.new($ny2, $ch2, 700)
$l5 = Link.new($ny1, $ny2, 1)
$l6 = Link.new($ch1, $ch2, 1)
### External destinations
$ch1.add_nat_dests(['66.158.71.0/24'])
$ch2.add_nat_dests(['66.158.71.0/24'])
### OpenVPN servers
$pr.openvpn(true)
### Additional node configuration
### Specifying host info means we don't need to ssh to node
$pr.hostinfo("128.112.139.43", "10.0.1.1", "00:FF:0A:00:01:01")
$ny1.hostinfo("64.57.18.82", "10.0.20.1", "00:FF:0A:00:14:01")
$ch1.hostinfo("64.57.18.18", "10.0.18.1", "00:FF:0A:00:12:01")
$ny2.hostinfo("64.57.18.83", "10.0.21.1", "00:FF:0A:00:15:01")
$ch2.hostinfo("64.57.18.19", "10.0.19.1", "00:FF:0A:00:13:01")
The rest of this page describes the different commands in this configuration file.
Several Ruby variables specify global variables for the experiment. Global variables with default values may be omitted from the preamble or overridden by specifying a new value. Any without defaults must be included.
- $prio_boost = true | false
- Optional, default: false. Run the router and Click with real-time priority. Note that you can only activate this option if your slice is privileged; contact Andy Bavier (acb@cs.princeton.edu) to request the appropriate privilege for your slice.
- $run_ospf = true | false
- Optional, default: true. Run the OSPF protocol on experiment nodes.
- $run_ibgp = true | false
- Optional, default: false. Run the iBGP protocol on experiment nodes.
You must declare one or more Slice objects, representing the slice or slices in which the experiment will run. The format is:
- $slice = Slice.new(<control port>, <UDP port>,'<slice name>', <click forwarding>, '<router>')
- Declare a slice to participate in the experiment. All fields are required. In order, the fields are:
- The TCP port that Click runs its control (telnet) interface on. Pick an unused port.
- The UDP port on which overlay traffic is tunneled. Pick an unused port.
- The name of your PlanetLab/VINI slice.
- Whether to enable IP forwarding in the Click FEA (true | false). This option is only meaningful with the XORP router.
- What router software to run ("XORP" | "Quagga" | "none").
Each router in your experiment must be declared by a Node object. The format is:
- $node = Node.new('<node DNS name>', $slice, 'label')
- Declare a node (that has already added to your slice) to participate in the experiment, and the slice on that node. The label field is optional. It specifies a short string to represent the node in the configuration files; each node must have a unique label. If a label is not specified, the default is to use the second component of the node's DNS name (e.g., for planetlab2.atla.internet2.planet-lab.org the label is "atla"). This generates a descriptive label for the PlanetLab Internet2 nodes at least.
The current values of the global variables are used as defaults for the Node.
Normally, the configuration scripts log into each node to discover its IP and MAC addresses. You can avoid this behavior by specifying the information in your config file. The format is:
- $node.hostinfo('<real IP>', '<tap0 IP>', '<tap0 MAC>')
- Add IP and MAC address information needed by the scripts to Node object $node.
Virtual links between nodes are declared using a Link object. The format is:
- $link = Link.new($node0, $node1, <OSPF cost>, <loss rate>)
- Declare a virtual link between Node objects $node0 and $node1. The OSPF cost and loss rate fields are optional.
The current values of the global variables are used as defaults for the Link.
PL-VINI currently supports the OSPF and iBGP routing protocols. OSPF advertises routes to the private 10.0.0.0/8 addresses associated with an IIAS experiment. iBGP advertises routes to external destinations, unless it is not being run, in which case OSPF advertises these routes.
OSPF configuration
The OSPF protocol is run by default. It can be turned off on all nodes using the global variable $run_ospf. Currently no additional OSPF configuration options are provided beyond the ability to set the OSPF link cost when the Link object is created.
iBGP Configuration
The iBGP protocol is not run by default. It can be activated on all nodes using the global variable $run_ibgp. It can also be enabled on individual nodes as follows:
- $node.ibgp( true | false )
- Enables or disables iBGP configuration for $node.
All nodes running iBGP peer with all other iBGP nodes.
Specifying external destinations
External destinations, reachable via NAPT, can be added for each node. The node will advertise routes to these destinations via its routing protocols as described above. Packets arriving at the node for that prefix will exit the virtual network onto the real network via NAPT. The format is:
- $node.add_nat_dests(['<prefix1>', '<prefix2>', ...])
- Adds the specified prefixes to those for which the node will serve as a NAT egress.
Each experiment node can run an OpenVPN server; external OpenVPN clients can connect to this server and inject their traffic into the virtual network. The format is:
- $node.openvpn( true | false )
- Enables or disables the OpenVPN server for a node. It is off by default.

