Skip to content

Commit

Permalink
Release 1.5
Browse files Browse the repository at this point in the history
  • Loading branch information
David Fialho committed Nov 5, 2017
2 parents 7e63708 + 80c53f3 commit 4ba1e05
Show file tree
Hide file tree
Showing 4 changed files with 292 additions and 26 deletions.
192 changes: 190 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,190 @@
# routing-simulator
A event-driven routing simulator for path-vector routing protocols like BGP
# SS-BGP Routing Simulator

An event-driven routing simulator for Self-Stable BGP (SS-BGP). It is also capable to run the well known Border Gateway Protocol (BGP).

## Prerequisites

The simulator is a java application, thus it requires the Java Runtime Environment (JRE) to run (version 8 or above). See the instructions on how to install the JRE on [Linux](https://docs.oracle.com/javase/8/docs/technotes/guides/install/linux_jre.html#CFHBJIIG), [Windows](https://docs.oracle.com/javase/8/docs/technotes/guides/install/windows_jre_install.html#CHDEDHAJ), and [macOS](https://docs.oracle.com/javase/8/docs/technotes/guides/install/mac_jre.html).

## Installation

The simulator application is composed of a single, self-contained, JAR file. It does not need to be installed on the system. The only "installation" step required is downloading the application's JAR file. To do this,

1. Go to [releases](https://github.com/ssbgp/routing-simulator/releases) and download, from the latest release section, a file called `ssbgp-simulator-{version}.jar`, where `{version}` corresponds to the release version.

1. Assuming the JRE is properly installed, open up the command line and type the following command, replacing `<path-to-jar-file>` with the path to the JAR file previously downloaded.

java -jar <path-to-jar-file> -v

If everything went ok, the message `SS-BGP Simulator: {version}` should be present in the terminal prompt, where `{version}` corresponds to the version of the application that was downloaded. If any issues occur, check out the [Troubleshooting](Troubleshooting) section for solutions to common problems.

## Basic Usage

The [Installation](#installation) section already showed how to run the simulator application using the `-v` option to show the simulator's version. This command is useful to determine if we are running the expected version of the simulator. But, it does not do much else.

**From this point on will assume the path to the simulator's JAR file is `simulator.jar`**

To perform simulations, the simulator requires at least (1) a topology file and (2) a destination.

1. The topology file describes the network to be simulated, that is, the set of nodes and the links between them. Not only that, it also specifies, for each node, the protocol and MRAI value used by that node. See the [Topology File](#topology-file) section to learn how to create these files;

2. A destination is a node in the network, that announces itself to all other nodes. Hence, this node is the starting point of the simulation.

The command to perform a single simulation is as follows.

java -jar simulator.jar -t <topology-file> -d <destination>

The `<topology-file>` parameter should be replaced with the path to the topology file to be used in the simulation, and the `<destination>` parameter must substituted with an integer value corresponding to the ID of the node to behave as the destination.

The last command will execute a single simulation run for the specified destination. To have the simulator perform multiple simulation runs with a single command, you need to use the `-c` option followed by the number of runs that you want to execute.

java -jar simulator.jar -t <topology-file> -d <destination> -c <repetitions>

#### Output

By default, the simulator outputs two files to the current working directory: a `.meta.txt` file and a `.basic.csv`.

The `-o` can be used to redirect the output to a different directory.

java -jar simulator.jar -t <topology-file> -d <destination> -o <output-directory>

Replacing `<output-directory>` with the path to the directory where the simulator should store the output files.

The first file is a simple text file, which includes some information about the setup of the simulation, such as the version of the simulator, the name of the topology file, etc. The second file contains the actual output of the simulation, the data obtained from the simulation. It is a Comma Separated Values (CSV) file containing a table with 8 columns and multiple rows (excluding the header row). Each row shows data corresponding to each simulation run. We suggest opening this file with a spreadsheet application, such as MS Excel or LibreOffice's Calc.

| Note |
|:---|
| If the `-c N` option was used, than the table will have `N` rows (excluding the header row), one row per simulation run. If the `-c` option was not used, than only a single simulation run was performed and, therefore, the file will contain only a single row.* |

Each column in the table corresponds to a piece of information collected by the simulator during the execution of each simulation run. The table includes the following columns:

- **Simulation** - number identifying each simulation
- **Delay Seed** - seed used to generate the random message delays
- **Termination Time (Total)** - the termination time of the last node to terminate
- **Termination Time (Avg.)** - the average of the termination times of each node
- **Message Count** - the total number of messages sent during the simulation
- **Detection Count** - the total number of detections/deactivations performed during the simulation
- **Terminated** - a flag indicating whether or not the simulation terminated before reaching the maximum threshold
- **Disconnected Count** - the number of nodes that were disconnected when the simulation terminated

**Note:** *time* in this context refers to simulation time and not processing (real) time.

#### How to ask for help?
Last but not least, the most important command in any command line tool is the one that can help you. To obtain some information about each option that is available, run the simulator with option `-h/--help`, as follows.

java -jar simulator.jar --help

There are other useful options, not shown in this section, that may be of use. Those are described in the [Advanced Usage](#advanced-usage) section.

## Topology File

The topology file is a text file with a predefined format. The format is very simple. Each line includes a single key and multiple values associated with that key. Keys are separated from values with an equals sign `=` and values are separated between each other with a straight line `|`.

There are only two possible keys: `node` and `link`. The former describes a node, and the latter a link. Nodes have 3 values,

- an ID, that must be unique for each node;
- a protocol label
- and, an MRAI value.

The protocol label is one of BGP, SSBGP, ISSBGP, SSBGP2, and ISSBGP2. The specified label determines the protocol deployed by the node. This allows simulating with different nodes deploying different protocols.

Links connect two nodes in a single direction. Routing messages flow in the opposite direction of the links. Since links are unidirectional, it is possible to represent unidirectional connections, with routing messages traveling from a node A to a node B, but not from B to A. A link has 3 values. The first two values correspond to the IDs of the nodes connected by that link: the first ID corresponds to the link's tail and the second ID to the head. The third value is a relationship label. A relationship label describes how routes are transformed when they are imported from and exported through a link. Currently, 6 different labels are supported:

- R+ - peer+ relationship
- R* - peer* relationship
- C - customer relationship
- R - peer relationship
- P - provider relationship
- S - sibling relationship

*See [Relationships](#relationships) section to learn more about relationships.*

Here is an example of a topology file with 3 nodes and 4 links.

node = 0 | BGP | 5000
node = 1 | SSBGP | 3000
node = 2 | SSBGP2 | 1000
link = 1 | 0 | C
link = 2 | 0 | C
link = 1 | 2 | R+
link = 2 | 1 | R+

Each node deploys a different protocol: node 0 deploys BGP, node 1 deploys SS-BGP, and node 2 deploys the SS-BGP version 2. The same is through for the MRAI values: node 0 uses an MRAI of 5000, while nodes 1 and 2 use MRAI values of 3000 and 1000, respectively.

There is a *customer link* from node 1 to node 0, and another one from node 2 to node 0. Nodes 1 and 2 are connected in both directions through peer+ links.

### Relationships
In progress...

## Advanced Usage

### How to change the minimum and maximum message delays?

The order with which routing messages are processed affects the routing behavior, thus affecting the overall development of the routing protocol. This order is defined by the delays imposed by the network and its components. The simulator aggregates all these delays in a single value that assigns to each routing message. These value are generated using a normal distribution. A minimum and maximum delay can be specified, using the `-min/--mindelay` and `-max/--maxdelay` options. This will force the delay generator to generate uniform delay values within the specified interval.

Here is example of how to use this options.

java -jar simulator.jar -t topology.topo -d 0 -c 10 -min 100 -max 1000

This command executes 10 simulation runs, advertising destination with ID `0` on the topology specified in file `topology.topo`. All routing messages will be subjected to delays with values between `100` and `1000` (both inclusive).

By default, that is if the `-min` and `-max` options are not used, then the minimum and maximum delays are set to 1, meaning that all messages will have a delay of 1.

### How to repeat the exact same simulation?

The randomness of the delays imposed to the routing messages makes harder to reproduce a simulation run. But, not that hard. The generator that generates these delays accepts a seed value that determines the sequence of delays that it generates. Therefore, to reproduce a simulation we need to force the simulator to use the same seed value as the one used on that simulation. That can be accomplished with the `-seed` option as follows.

java -jar simulator.jar -t topology.topo -d 0 -min 100 -max 1000 -seed 129312379172

This command will execute a single simulation run using `129312379172` as the seed to generate the message delays.

*Warning: make sure that input parameters are exactly the same as well!*

Since the only thing we need is the initial seed used in a previous simulation to reproduce it, we need to know where to get that value. It can be obtained from the `.basic.csv` file, output by the simulator.

| Note |
|:---|
| By default, the first seed used to generate the message delays during the first simulation run is obtained from the current time (real time). The seeds used for the next simulation runs are obtained from the last value generated in the previous simulation. |

### How to set the simulation threshold?

Each run simulates the advertisement of a single destination over a network. It terminates once all nodes have reached a stable state, that is none of them has any new route to announce, and no route is currently in transit. However, the Border Gateway Protocol (BGP) does not give any guarantee of termination. Thus, the simulation itself may never terminate. To prevent this from happening, a threshold value is established for each simulation run. This threshold value corresponds to the maximum simulation time. If the simulation reaches this threshold, it is immediately interrupted and labeled as *not terminated*.

The threshold value is set to 1000000 by default. This value can be changed with the `-th/--threshold` option as follows.

java -jar simulator.jar -t topology.topo -d 0 -c 10 -th 15000000

This command will execute 10 simulation runs. Each one will use the 15000000 as the threshold value.

*Suggestion: consider adjusting the threshold value accordingly to the minimum and maximum delay values.*

### How to simulate with stubs?
In progress...

### How to obtain more information about each node?

By default, the simulator outputs global information about the protocol. To obtain more detailed information about each node, the `-rn/--reportnodes` option is available. Use it as follows.

java -jar simulator.jar -t topology.topo -d 0 -c 10 --reportnodes

With this option enabled, the simulator will output a different file with extension `.nodes.csv`. This is also a CSV file containing a table. This table shows the following information for each node and each simulation:

- **Local Preference** - LOCAL-PREF of route elected by the node;
- **Next-hop** - ID of neighbor elected by the node;
- **Path Length** - length of the AS-PATH of route elected by the node;
- **Termination Time** - time at which the node sent its last route.

The first two columns of the table include the simulation number and the ID of the node. This simulation number corresponds to the same number included in the `.basic.csv`.

## Troubleshooting

1. When I try to run the simulator, I get the following error message.

Error: Unable to access jarfile

This error is shown when the path to the JAR file is not correct. Make sure the specified path points to the correct JAR file.

## Authors

- David Fialho - Simulator development, SS-BGP protocol development
- João Luís Sobrinho - SS-BGP protocol development
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
application.version=1.4
application.version=1.5
1 change: 1 addition & 0 deletions src/main/kotlin/ui/cli/CLIApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ object CLIApplication: Application {
} catch (e: InputArgumentsException) {
console.error("Input arguments are invalid.")
console.error("Cause: ${e.message ?: "No information available."}")
console.info("Try the '-h' option to see more information")
exitProcess(1)

} catch (e: Exception){
Expand Down
123 changes: 100 additions & 23 deletions src/main/kotlin/ui/cli/InputArgumentsParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ import core.simulator.Engine
import core.simulator.RandomDelayGenerator
import io.InterdomainTopologyReaderHandler
import io.parseInterdomainExtender
import org.apache.commons.cli.CommandLine
import org.apache.commons.cli.DefaultParser
import org.apache.commons.cli.Options
import org.apache.commons.cli.ParseException
import org.apache.commons.cli.*
import simulation.*
import java.io.File
import java.util.*
import kotlin.system.exitProcess


/**
* Created on 30-08-2017
Expand All @@ -20,9 +19,13 @@ import java.util.*
*/
class InputArgumentsParser {

//region Options
private val MAIN_COMMAND = "ssbgp-simulator"

// Information Options
private val HELP = "help"
private val VERSION = "version"

// Execution Options
private val TOPOLOGY_FILE = "topology"
private val DESTINATION = "destination"
private val REPETITIONS = "repetitions"
Expand All @@ -37,18 +40,88 @@ class InputArgumentsParser {
private val options = Options()

init {
// setup the command options
options.addOption("v", VERSION, false, "show the version number")
options.addOption("t", TOPOLOGY_FILE, true, "path to topology file")
options.addOption("d", DESTINATION, true, "ID of the destination")
options.addOption("c", REPETITIONS, true, "number of repetitions")
options.addOption("o", REPORT_DIRECTORY, true, "directory where to output results")
options.addOption(MIN_DELAY, true, "minimum message delay (inclusive)")
options.addOption(MAX_DELAY, true, "maximum message delay (inclusive)")
options.addOption("th", THRESHOLD, true, "threshold value")
options.addOption(SEED, true, "first seed used to generate message delays")
options.addOption(STUBS, true, "path to stubs file")
options.addOption("rn", NODE_REPORT, false, "output data for each individual node")

options.apply {

// Information Options
addOption(Option.builder("h")
.desc("Print help")
.required(false)
.hasArg(false)
.longOpt(HELP)
.build())
addOption(Option.builder("V")
.desc("Print application's version")
.required(false)
.hasArg(false)
.longOpt(VERSION)
.build())

// Execution Options
addOption(Option.builder("t")
.desc("Topology file to simulate with")
.hasArg(true)
.argName("topology-file")
.longOpt(TOPOLOGY_FILE)
.build())
addOption(Option.builder("d")
.desc("ID of destination node")
.hasArg(true)
.argName("destination")
.longOpt(DESTINATION)
.build())
addOption(Option.builder("c")
.desc("Number of executions to run [default: 1]")
.hasArg(true)
.argName("executions")
.longOpt(REPETITIONS)
.build())
addOption(Option.builder("o")
.desc("Directory to place reports [default: working directory]")
.hasArg(true)
.argName("out-directory")
.longOpt(REPORT_DIRECTORY)
.build())
addOption(Option.builder("min")
.desc("Minimum delay applied to the routing messages [default: 1]")
.hasArg(true)
.argName("mindelay")
.longOpt(MIN_DELAY)
.build())
addOption(Option.builder("max")
.desc("Maximum delay applied to the routing messages [default: 1]")
.hasArg(true)
.argName("maxdelay")
.longOpt(MAX_DELAY)
.build())
addOption(Option.builder("th")
.desc("Maximum amount simulation time [default: 1000000]")
.hasArg(true)
.argName("threshold")
.longOpt(THRESHOLD)
.build())
addOption(Option.builder("s")
.desc("Seed used to generate the delays in the first execution")
.required(false)
.hasArg(true)
.argName("threshold")
.longOpt(SEED)
.build())
addOption(Option.builder("S")
.desc("Stubs file")
.required(false)
.hasArg(true)
.argName("stubs-file")
.longOpt(STUBS)
.build())
addOption(Option.builder("rn")
.desc("Output data for each individual node")
.required(false)
.hasArg(false)
.longOpt(NODE_REPORT)
.build())
}

}

@Throws(InputArgumentsException::class)
Expand All @@ -60,15 +133,18 @@ class InputArgumentsParser {
throw InputArgumentsException(e.message.toString())
}

if (commandLine.hasOption(VERSION)) {
if (commandLine.hasOption(HELP)) {
val formatter = HelpFormatter()
formatter.width = 100

if (commandLine.options.size > 1) {
throw InputArgumentsException("when option -v/-version is specified, no more options are expected ")
}
val usageHeader = "\nOptions:"
formatter.printHelp(MAIN_COMMAND, usageHeader, options, "", true)
exitProcess(0)
}

if (commandLine.hasOption(VERSION)) {
println("SS-BGP Simulator: ${Engine.version()}")

System.exit(0)
exitProcess(0)
}

commandLine.let {
Expand Down Expand Up @@ -128,6 +204,7 @@ class InputArgumentsParser {
return Pair(runner, execution)
}
}

@Throws(InputArgumentsException::class)
private fun getFile(commandLine: CommandLine, option: String, default: Optional<File>? = null): Optional<File> {
verifyOption(commandLine, option, default)
Expand Down

0 comments on commit 4ba1e05

Please sign in to comment.