moved core markdown documentation to live within to repo, this will eventually be the docs hosted on github and allow them to be versioned with the code
1
docs/Makefile.am
Normal file
|
@ -0,0 +1 @@
|
|||
EXTRA_DIST = $(wildcard *)
|
39
docs/architecture.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
# CORE Architecture
|
||||
|
||||
* Table of Contents
|
||||
{:toc}
|
||||
|
||||
## Main Components
|
||||
|
||||
* CORE Daemon
|
||||
* Manages emulation sessions
|
||||
* Builds the emulated networks using kernel virtualization for nodes and some form of bridging and packet manipulation for virtual networks
|
||||
* Nodes and networks come together via interfaces installed on nodes
|
||||
* Controlled via the CORE GUI
|
||||
* Written in python and can be scripted, given direct control of scenarios
|
||||
* CORE GUI
|
||||
* GUI and daemon communicate using a custom, asynchronous, sockets-based API, known as the CORE API
|
||||
* Drag and drop creation for nodes and network interfaces
|
||||
* Can launch terminals for emulated nodes in running scenarios
|
||||
* Can save/open scenario files to recreate previous sessions
|
||||
* TCL/TK program
|
||||
|
||||

|
||||
|
||||
## How Does it Work?
|
||||
|
||||
A CORE node is a lightweight virtual machine. The CORE framework runs on Linux. CORE uses Linux network namespace virtualization to build virtual nodes, and ties them together with virtual networks using Linux Ethernet bridging.
|
||||
|
||||
### Linux
|
||||
|
||||
Linux network namespaces (also known as netns, LXC, or [Linux containers](http://lxc.sourceforge.net/)) is the primary virtualization technique used by CORE. LXC has been part of the mainline Linux kernel since 2.6.24. Most recent Linux distributions have namespaces-enabled kernels out of the box. A namespace is created using the ```clone()``` system call. Each namespace has its own process environment and private network stack. Network namespaces share the same filesystem in CORE.
|
||||
|
||||
CORE combines these namespaces with Linux Ethernet bridging to form networks. Link characteristics are applied using Linux Netem queuing disciplines. Ebtables is Ethernet frame filtering on Linux bridges. Wireless networks are emulated by controlling which interfaces can send and receive with ebtables rules.
|
||||
|
||||
## Prior Work
|
||||
|
||||
The Tcl/Tk CORE GUI was originally derived from the open source [IMUNES](http://imunes.net) project from the University of Zagreb as a custom project within Boeing Research and Technology's Network Technology research group in 2004. Since then they have developed the CORE framework to use Linux virtualization, have developed a Python framework, and made numerous user- and kernel-space developments, such as support for wireless networks, IPsec, the ability to distribute emulations, simulation integration, and more. The IMUNES project also consists of userspace and kernel components.
|
||||
|
||||
## Open Source Project and Resources
|
||||
|
||||
CORE has been released by Boeing to the open source community under the BSD license. If you find CORE useful for your work, please contribute back to the project. Contributions can be as simple as reporting a bug, dropping a line of encouragement or technical suggestions to the mailing lists, or can also include submitting patches or maintaining aspects of the tool. For contributing to CORE, please visit [CORE GitHub](https://github.com/coreemu/core).
|
88
docs/ctrlnet.md
Normal file
|
@ -0,0 +1,88 @@
|
|||
# CORE Control Network
|
||||
|
||||
* Table of Contents
|
||||
{:toc}
|
||||
|
||||
## Overview
|
||||
|
||||
The CORE control network allows the virtual nodes to communicate with their host environment. There are two types: the primary control network and auxiliary control networks. The primary control network is used mainly for communicating with the virtual nodes from host machines and for master-slave communications in a multi-server distributed environment. Auxiliary control networks have been introduced to for routing namespace hosted emulation software traffic to the test network.
|
||||
|
||||
## Activating the Primary Control Network
|
||||
|
||||
Under the *Session Menu*, the *Options...* dialog has an option to set a *control network prefix*.
|
||||
|
||||
This can be set to a network prefix such as *172.16.0.0/24*. A bridge will be created on the host machine having the last address in the prefix range (e.g. *172.16.0.254*), and each node will have an extra *ctrl0* control interface configured with an address corresponding to its node number (e.g. *172.16.0.3* for *n3*.)
|
||||
|
||||
A default for the primary control network may also be specified by setting the *controlnet* line in the */etc/core/core.conf* configuration file which new sessions will use by default. To simultaneously run multiple sessions with control networks, the session option should be used instead of the *core.conf* default.
|
||||
|
||||
**NOTE: If you have a large scenario with more than 253 nodes, use a control network prefix that allows more than the suggested */24*, such as */23* or greater.**
|
||||
|
||||
**IMPORTANT: Running a session with a control network can fail if a previous session has set up a control network and the its bridge is still up. Close the previous session first or wait for it to complete. If unable to, the *core-daemon* may need to be restarted and the lingering bridge(s) removed manually.**
|
||||
|
||||
```shell
|
||||
# Restart the CORE Daemon
|
||||
sudo /etc/init.d core-daemon restart
|
||||
|
||||
# Remove lingering control network bridges
|
||||
ctrlbridges=`brctl show | grep b.ctrl | awk '{print $1}'`
|
||||
for cb in $ctrlbridges; do
|
||||
sudo ifconfig $cb down
|
||||
sudo brctl delbr $cb
|
||||
done
|
||||
```
|
||||
|
||||
**TIP: If adjustments to the primary control network configuration made in */etc/core/core.conf* do not seem to take affect, check if there is anything set in the *Session Menu*, the *Options...* dialog. They may need to be cleared. These per session settings override the defaults in */etc/core/core.conf*.**
|
||||
|
||||
## Control Network in Distributed Sessions
|
||||
|
||||
When the primary control network is activated for a distributed session, a control network bridge will be created on each of the slave servers, with GRE tunnels back to the master server's bridge. The slave control bridges are not assigned an address. From the host, any of the nodes (local or remote) can be accessed, just like the single server case.
|
||||
|
||||
In some situations, remote emulated nodes need to communicate with the host on which they are running and not the master server. Multiple control network prefixes can be specified in the either the session option or */etc/core/core.conf*, separated by spaces and beginning with the master server. Each entry has the form *"server:prefix"*. For example, if the servers *core1*,*core2*, and *core3* are assigned with nodes in the scenario and using :file:`/etc/core/core.conf` instead of the session option:
|
||||
|
||||
```shell
|
||||
controlnet=core1:172.16.1.0/24 core2:172.16.2.0/24 core3:172.16.1.0/24
|
||||
```
|
||||
|
||||
Then, the control network bridges will be assigned as follows:
|
||||
|
||||
* core1 = 172.16.1.254 (assuming it is the master server),
|
||||
* core2 = 172.16.2.254
|
||||
* core3 = 172.16.3.254
|
||||
|
||||
Tunnels back to the master server will still be built, but it is up to the user to add appropriate routes if networking between control network prefixes is desired. The control network script may help with this.
|
||||
|
||||
## Control Network Script
|
||||
|
||||
A control network script may be specified using the *controlnet_updown_script* option in the */etc/core/core.conf* file. This script will be run after the bridge has been built (and address assigned) with the first argument being the name of the bridge, and the second argument being the keyword *"startup"*. The script will again be invoked prior to bridge removal with the second argument being the keyword *"shutdown"*.
|
||||
|
||||
## Auxiliary Control Networks
|
||||
|
||||
Starting with EMANE 0.9.2, CORE will run EMANE instances within namespaces. Since it is advisable to separate the OTA traffic from other traffic, we will need more than single channel leading out from the namespace. Up to three auxiliary control networks may be defined. Multiple control networks are set up in */etc/core/core.conf* file. Lines *controlnet1*, *controlnet2* and *controlnet3* define the auxiliary networks.
|
||||
|
||||
For example, having the following */etc/core/core.conf*:
|
||||
|
||||
```shell
|
||||
controlnet = core1:172.17.1.0/24 core2:172.17.2.0/24 core3:172.17.3.0/24
|
||||
controlnet1 = core1:172.18.1.0/24 core2:172.18.2.0/24 core3:172.18.3.0/24
|
||||
controlnet2 = core1:172.19.1.0/24 core2:172.19.2.0/24 core3:172.19.3.0/24
|
||||
```
|
||||
|
||||
This will activate the primary and two auxiliary control networks and add interfaces *ctrl0*, *ctrl1*, *ctrl2* to each node. One use case would be to assign *ctrl1* to the OTA manager device and *ctrl2* to the Event Service device in the EMANE Options dialog box and leave *ctrl0* for CORE control traffic.
|
||||
|
||||
**NOTE: *controlnet0* may be used in place of *controlnet* to configure the primary control network.**
|
||||
|
||||
Unlike the primary control network, the auxiliary control networks will not employ tunneling since their primary purpose is for efficiently transporting multicast EMANE OTA and event traffic. Note that there is no per-session configuration for auxiliary control networks.
|
||||
|
||||
To extend the auxiliary control networks across a distributed test environment, host network interfaces need to be added to them. The following lines in */etc/core/core.conf* will add host devices *eth1*, *eth2* and *eth3* to *controlnet1*, *controlnet2*, *controlnet3*:
|
||||
|
||||
```shell
|
||||
controlnetif1 = eth1
|
||||
controlnetif2 = eth2
|
||||
controlnetif3 = eth3
|
||||
```
|
||||
|
||||
**NOTE: There is no need to assign an interface to the primary control network because tunnels are formed between the master and the slaves using IP addresses that are provided in *servers.conf*.**
|
||||
|
||||
Shown below is a representative diagram of the configuration above.
|
||||
|
||||

|
113
docs/devguide.md
Normal file
|
@ -0,0 +1,113 @@
|
|||
# CORE Developer's Guide
|
||||
|
||||
* Table of Contents
|
||||
{:toc}
|
||||
|
||||
## Source Code Guide
|
||||
|
||||
The CORE source consists of several different programming languages for historical reasons. Current development focuses on the Python modules and daemon. Here is a brief description of the source directories.
|
||||
|
||||
These are being actively developed as of CORE 5.1:
|
||||
|
||||
* *gui* - Tcl/Tk GUI. This uses Tcl/Tk because of its roots with the IMUNES
|
||||
project.
|
||||
* *daemon* - Python modules are found in the :file:`daemon/core` directory, the
|
||||
daemon under :file:`daemon/scripts/core-daemon`
|
||||
* *netns* - Python extension modules for Linux Network Namespace support are in :file:`netns`.
|
||||
* *doc* - Documentation for the manual lives here in reStructuredText format.
|
||||
|
||||
Not actively being developed:
|
||||
|
||||
* *ns3* - Python ns3 script support for running CORE.
|
||||
|
||||
## The CORE API
|
||||
|
||||
The CORE API is used between different components of CORE for communication. The GUI communicates with the CORE daemon using the API. One emulation server communicates with another using the API. The API also allows other systems to interact with the CORE emulation. The API allows another system to add, remove, or modify nodes and links, and enables executing commands on the emulated systems. Wireless link parameters are updated on-the-fly based on node positions.
|
||||
|
||||
CORE listens on a local TCP port for API messages. The other system could be software running locally or another machine accessible across the network.
|
||||
|
||||
The CORE API is currently specified in a separate document, available from the CORE website.
|
||||
|
||||
## Linux network namespace Commands
|
||||
|
||||
Linux network namespace containers are often managed using the *Linux Container Tools* or *lxc-tools* package. The lxc-tools website is available here http://lxc.sourceforge.net/ for more information. CORE does not use these management utilities, but includes its own set of tools for instantiating and configuring network namespace containers. This section describes these tools.
|
||||
|
||||
### vnoded command
|
||||
|
||||
The *vnoded* daemon is the program used to create a new namespace, and listen on a control channel for commands that may instantiate other processes. This daemon runs as PID 1 in the container. It is launched automatically by the CORE daemon. The control channel is a UNIX domain socket usually named */tmp/pycore.23098/n3*, for node 3 running on CORE session 23098, for example. Root privileges are required for creating a new namespace.
|
||||
|
||||
### vcmd command
|
||||
|
||||
The *vcmd* program is used to connect to the *vnoded* daemon in a Linux network namespace, for running commands in the namespace. The CORE daemon uses the same channel for setting up a node and running processes within it. This program has two required arguments, the control channel name, and the command line to be run within the namespace. This command does not need to run with root privileges.
|
||||
|
||||
When you double-click on a node in a running emulation, CORE will open a shell window for that node using a command such as:
|
||||
|
||||
```shell
|
||||
gnome-terminal -e vcmd -c /tmp/pycore.50160/n1 -- bash
|
||||
```
|
||||
|
||||
Similarly, the IPv4 routes Observer Widget will run a command to display the routing table using a command such as:
|
||||
|
||||
```shell
|
||||
vcmd -c /tmp/pycore.50160/n1 -- /sbin/ip -4 ro
|
||||
```
|
||||
|
||||
### core-cleanup script
|
||||
|
||||
A script named *core-cleanup* is provided to clean up any running CORE emulations. It will attempt to kill any remaining vnoded processes, kill any EMANE processes, remove the :file:`/tmp/pycore.*` session directories, and remove any bridges or *ebtables* rules. With a *-d* option, it will also kill any running CORE daemon.
|
||||
|
||||
### netns command
|
||||
|
||||
The *netns* command is not used by CORE directly. This utility can be used to run a command in a new network namespace for testing purposes. It does not open a control channel for receiving further commands.
|
||||
|
||||
### Other Useful Commands
|
||||
|
||||
Here are some other Linux commands that are useful for managing the Linux network namespace emulation.
|
||||
|
||||
```shell
|
||||
# view the Linux bridging setup
|
||||
brctl show
|
||||
# view the netem rules used for applying link effects
|
||||
tc qdisc show
|
||||
# view the rules that make the wireless LAN work
|
||||
ebtables -L
|
||||
```
|
||||
|
||||
### Example Command Usage
|
||||
|
||||
Below is a transcript of creating two emulated nodes and connecting them together with a wired link:
|
||||
|
||||
```shell
|
||||
# create node 1 namespace container
|
||||
vnoded -c /tmp/n1.ctl -l /tmp/n1.log -p /tmp/n1.pid
|
||||
# create a virtual Ethernet (veth) pair, installing one end into node 1
|
||||
ip link add name n1.0.1 type veth peer name n1.0
|
||||
ip link set n1.0 netns `cat /tmp/n1.pid`
|
||||
vcmd -c /tmp/n1.ctl -- ip link set lo up
|
||||
vcmd -c /tmp/n1.ctl -- ip link set n1.0 name eth0 up
|
||||
vcmd -c /tmp/n1.ctl -- ip addr add 10.0.0.1/24 dev eth0
|
||||
|
||||
# create node 2 namespace container
|
||||
vnoded -c /tmp/n2.ctl -l /tmp/n2.log -p /tmp/n2.pid
|
||||
# create a virtual Ethernet (veth) pair, installing one end into node 2
|
||||
ip link add name n2.0.1 type veth peer name n2.0
|
||||
ip link set n2.0 netns `cat /tmp/n2.pid`
|
||||
vcmd -c /tmp/n2.ctl -- ip link set lo up
|
||||
vcmd -c /tmp/n2.ctl -- ip link set n2.0 name eth0 up
|
||||
vcmd -c /tmp/n2.ctl -- ip addr add 10.0.0.2/24 eth0
|
||||
|
||||
# bridge together nodes 1 and 2 using the other end of each veth pair
|
||||
brctl addbr b.1.1
|
||||
brctl setfd b.1.1 0
|
||||
brctl addif b.1.1 n1.0.1
|
||||
brctl addif b.1.1 n2.0.1
|
||||
ip link set n1.0.1 up
|
||||
ip link set n2.0.1 up
|
||||
ip link set b.1.1 up
|
||||
|
||||
# display connectivity and ping from node 1 to node 2
|
||||
brctl show
|
||||
vcmd -c /tmp/n1.ctl -- ping 10.0.0.2
|
||||
```
|
||||
|
||||
The above example script can be found as *twonodes.sh* in the *examples/netns* directory. Use *core-cleanup* to clean up after the script.
|
143
docs/emane.md
Normal file
|
@ -0,0 +1,143 @@
|
|||
# CORE/EMANE
|
||||
|
||||
* Table of Contents
|
||||
{:toc}
|
||||
|
||||
## What is EMANE?
|
||||
|
||||
The Extendable Mobile Ad-hoc Network Emulator (EMANE) allows heterogeneous network emulation using a pluggable MAC and PHY layer architecture. The EMANE framework provides an implementation architecture for modeling different radio interface types in the form of *Network Emulation Modules* (NEMs) and incorporating these modules into a real-time emulation running in a distributed environment.
|
||||
|
||||
EMANE is developed by U.S. Naval Research Labs (NRL) Code 5522 and Adjacent Link LLC, who maintain these websites:
|
||||
|
||||
* http://www.nrl.navy.mil/itd/ncs/products/emane
|
||||
* http://www.adjacentlink.com/
|
||||
|
||||
Instead of building Linux Ethernet bridging networks with CORE, higher-fidelity wireless networks can be emulated using EMANE bound to virtual devices. CORE emulates layers 3 and above (network, session, application) with its virtual network stacks and process space for protocols and applications, while EMANE emulates layers 1 and 2 (physical and data link) using its pluggable PHY and MAC models.
|
||||
|
||||
The interface between CORE and EMANE is a TAP device. CORE builds the virtual node using Linux network namespaces, installs the TAP device into the namespace and instantiates one EMANE process in the namespace. The EMANE process binds a user space socket to the TAP device for sending and receiving data from CORE.
|
||||
|
||||
An EMANE instance sends and receives OTA traffic to and from other EMANE instances via a control port (e.g. *ctrl0*, *ctrl1*). It also sends and receives Events to and from the Event Service using the same or a different control port. EMANE models are configured through CORE's WLAN configuration dialog. A corresponding EmaneModel Python class is sub-classed for each supported EMANE model, to provide configuration items and their mapping to XML files. This way new models can be easily supported. When CORE starts the emulation, it generates the appropriate XML files that specify the EMANE NEM configuration, and launches the EMANE daemons.
|
||||
|
||||
Some EMANE models support location information to determine when packets should be dropped. EMANE has an event system where location events are broadcast to all NEMs. CORE can generate these location events when nodes are moved on the canvas. The canvas size and scale dialog has controls for mapping the X,Y coordinate system to a latitude, longitude geographic system that EMANE uses. When specified in the *core.conf* configuration file, CORE can also subscribe to EMANE location events and move the nodes on the canvas as they are moved in the EMANE emulation. This would occur when an Emulation Script Generator, for example, is running a mobility script.
|
||||
|
||||
## EMANE Configuration
|
||||
|
||||
The CORE configuration file */etc/core/core.conf* has options specific to EMANE. An example emane section from the *core.conf* file is shown below:
|
||||
|
||||
```shell
|
||||
# EMANE configuration
|
||||
emane_platform_port = 8101
|
||||
emane_transform_port = 8201
|
||||
emane_event_monitor = False
|
||||
#emane_models_dir = /home/username/.core/myemane
|
||||
# EMANE log level range [0,4] default: 2
|
||||
emane_log_level = 2
|
||||
emane_realtime = True
|
||||
```
|
||||
|
||||
EMANE can be installed from deb or RPM packages or from source. See the [EMANE GitHub](https://github.com/adjacentlink/emane) for full details.
|
||||
|
||||
Here are quick instructions for installing all EMANE packages:
|
||||
|
||||
```shell
|
||||
# install dependencies
|
||||
sudo apt-get install libssl-dev libxml-libxml-perl libxml-simple-perl
|
||||
wget https://adjacentlink.com/downloads/emane/emane-1.2.1-release-1.ubuntu-16_04.amd64.tar.gz
|
||||
tar xzf emane-1.2.1-release-1.ubuntu-16_04.amd64.tar.gz
|
||||
sudo dpkg -i emane-1.2.1-release-1/deb/ubuntu-16_04/amd64/*.deb
|
||||
```
|
||||
|
||||
If you have an EMANE event generator (e.g. mobility or pathloss scripts) and want to have CORE subscribe to EMANE location events, set the following line in the */etc/core/core.conf* configuration file:
|
||||
|
||||
```shell
|
||||
emane_event_monitor = True
|
||||
```
|
||||
|
||||
Do not set the above option to True if you want to manually drag nodes around on the canvas to update their location in EMANE.
|
||||
|
||||
Another common issue is if installing EMANE from source, the default configure prefix will place the DTD files in */usr/local/share/emane/dtd* while CORE expects them in */usr/share/emane/dtd*.
|
||||
|
||||
A symbolic link will fix this:
|
||||
|
||||
```shell
|
||||
sudo ln -s /usr/local/share/emane /usr/share/emane
|
||||
```
|
||||
|
||||
## Custom EMANE Models
|
||||
|
||||
CORE supports custom developed EMANE models by way of dynamically loading user created python files that represent the model. Custom EMANE models should be placed within the path defined by **emane_models_dir** in the CORE configuration file. This path cannot end in **emane**.
|
||||
|
||||
Here is an example model with documentation describing functionality:
|
||||
[Example Model](examplemodel.html)
|
||||
|
||||
|
||||
|
||||
## Single PC with EMANE
|
||||
|
||||
This section describes running CORE and EMANE on a single machine. This is the default mode of operation when building an EMANE network with CORE. The OTA manager and Event service interface are set to use *ctrl0* and the virtual nodes use the primary control channel for communicating with one another. The primary control channel is automatically activated when a scenario involves EMANE. Using the primary control channel prevents your emulation session from sending multicast traffic on your local network and interfering with other EMANE users.
|
||||
|
||||
EMANE is configured through a WLAN node, because it is all about emulating wireless radio networks. Once a node is linked to a WLAN cloud configured with an EMANE model, the radio interface on that node may also be configured separately (apart from the cloud.)
|
||||
|
||||
Double-click on a WLAN node to invoke the WLAN configuration dialog. Click the *EMANE* tab; when EMANE has been properly installed, EMANE wireless modules should be listed in the *EMANE Models* list. (You may need to restart the CORE daemon if it was running prior to installing the EMANE Python bindings.) Click on a model name to enable it.
|
||||
|
||||
When an EMANE model is selected in the *EMANE Models* list, clicking on the *model options* button causes the GUI to query the CORE daemon for configuration items. Each model will have different parameters, refer to the EMANE documentation for an explanation of each item. The defaults values are presented in the dialog. Clicking *Apply* and *Apply* again will store the EMANE model selections.
|
||||
|
||||
The *EMANE options* button allows specifying some global parameters for EMANE, some of which are necessary for distributed operation.
|
||||
|
||||
The RF-PIPE and IEEE 802.11abg models use a Universal PHY that supports geographic location information for determining pathloss between nodes. A default latitude and longitude location is provided by CORE and this location-based pathloss is enabled by default; this is the *pathloss mode* setting for the Universal PHY. Moving a node on the canvas while the emulation is running generates location events for EMANE. To view or change the geographic location or scale of the canvas use the *Canvas Size and Scale* dialog available from the *Canvas* menu.
|
||||
|
||||
Note that conversion between geographic and Cartesian coordinate systems is done using UTM (Universal Transverse Mercator) projection, where different zones of 6 degree longitude bands are defined. The location events generated by CORE may become inaccurate near the zone boundaries for very large scenarios that span multiple UTM zones. It is recommended that EMANE location scripts be used to achieve geo-location accuracy in this situation.
|
||||
|
||||
Clicking the green *Start* button launches the emulation and causes TAP devices to be created in the virtual nodes that are linked to the EMANE WLAN. These devices appear with interface names such as eth0, eth1, etc. The EMANE processes should now be running in each namespace. For a four node scenario:
|
||||
|
||||
```shell
|
||||
ps -aef | grep emane
|
||||
root 1063 969 0 11:46 ? 00:00:00 emane -d --logl 3 -r -f /tmp/pycore.59992/emane4.log /tmp/pycore.59992/platform4.xml
|
||||
root 1117 959 0 11:46 ? 00:00:00 emane -d --logl 3 -r -f /tmp/pycore.59992/emane2.log /tmp/pycore.59992/platform2.xml
|
||||
root 1179 942 0 11:46 ? 00:00:00 emane -d --logl 3 -r -f /tmp/pycore.59992/emane1.log /tmp/pycore.59992/platform1.xml
|
||||
root 1239 979 0 11:46 ? 00:00:00 emane -d --logl 3 -r -f /tmp/pycore.59992/emane5.log /tmp/pycore.59992/platform5.xml
|
||||
```
|
||||
|
||||
The example above shows the EMANE processes started by CORE. To view the configuration generated by CORE, look in the */tmp/pycore.nnnnn/* session directory for a *platform.xml* file and other XML files. One easy way to view this information is by double-clicking one of the virtual nodes, and typing *cd ..* in the shell to go up to the session directory.
|
||||
|
||||

|
||||
|
||||
## Distributed EMANE
|
||||
|
||||
Running CORE and EMANE distributed among two or more emulation servers is similar to running on a single machine. There are a few key configuration items that need to be set in order to be successful, and those are outlined here.
|
||||
|
||||
It is a good idea to maintain separate networks for data (OTA) and control. The control network may be a shared laboratory network, for example, and you do not want multicast traffic on the data network to interfere with other EMANE users. Furthermore, control traffic could interfere with the OTA latency and thoughput and might affect emulation fidelity. The examples described here will use *eth0* as a control interface and *eth1* as a data interface, although using separate interfaces is not strictly required. Note that these interface names refer to interfaces present on the host machine, not virtual interfaces within a node.
|
||||
|
||||
**IMPORTANT: If an auxiliary control network is used, an interface on the host has to be assigned to that network.**
|
||||
|
||||
Each machine that will act as an emulation server needs to have CORE and EMANE installed.
|
||||
|
||||
The IP addresses of the available servers are configured from the CORE emulation servers dialog box (choose *Session* then *Emulation servers...*). This list of servers is stored in a *~/.core/servers.conf* file. The dialog shows available servers, some or all of which may be assigned to nodes on the canvas.
|
||||
|
||||
Nodes need to be assigned to emulation servers. Select several nodes, right-click them, and choose *Assign to* and the name of the desired server. When a node is not assigned to any emulation server, it will be emulated locally. The local machine that the GUI connects with is considered the "master" machine, which in turn connects to the other emulation server "slaves". Public key SSH should be configured from the master to the slaves.
|
||||
|
||||
Under the *EMANE* tab of the EMANE WLAN, click on the *EMANE options* button. This brings up the emane configuration dialog. The *enable OTA Manager channel* should be set to *on*. The *OTA Manager device* and *Event Service device* should be set to a control network device. For example, if you have a primary and auxiliary control network (i.e. controlnet and controlnet1), and you want the OTA traffic to have its dedicated network, set the OTA Manager device to *ctrl1* and the Event Service device to *ctrl0*. The EMANE models can be configured. Click *Apply* to save these settings.
|
||||
|
||||

|
||||
|
||||
**HINT:**
|
||||
Here is a quick checklist for distributed emulation with EMANE.
|
||||
|
||||
1. Follow the steps outlined for normal CORE.
|
||||
2. Under the *EMANE* tab of the EMANE WLAN, click on *EMANE options*.
|
||||
3. Turn on the *OTA Manager channel* and set the *OTA Manager device*.
|
||||
Also set the *Event Service device*.
|
||||
4. Select groups of nodes, right-click them, and assign them to servers
|
||||
using the *Assign to* menu.
|
||||
5. Synchronize your machine's clocks prior to starting the emulation,
|
||||
using *ntp* or *ptp*. Some EMANE models are sensitive to timing.
|
||||
6. Press the *Start* button to launch the distributed emulation.
|
||||
|
||||
|
||||
Now when the Start button is used to instantiate the emulation, the local CORE Python daemon will connect to other emulation servers that have been assigned to nodes. Each server will have its own session directory where the *platform.xml* file and other EMANE XML files are generated. The NEM IDs are automatically coordinated across servers so there is no overlap. Each server also gets its own Platform ID.
|
||||
|
||||
An Ethernet device is used for disseminating multicast EMANE events, as specified in the *configure emane* dialog. EMANE's Event Service can be run with mobility or pathloss scripts as described in :ref:`Single_PC_with_EMANE`. If CORE is not subscribed to location events, it will generate them as nodes are moved on the canvas.
|
||||
|
||||
Double-clicking on a node during runtime will cause the GUI to attempt to SSH to the emulation server for that node and run an interactive shell. The public key SSH configuration should be tested with all emulation servers prior to starting the emulation.
|
||||
|
||||

|
239
docs/examplemodel.html
Normal file
|
@ -0,0 +1,239 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
||||
<title>examplemodel.py</title>
|
||||
<link rel="stylesheet" href="pycco.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id='container'>
|
||||
<div id="background"></div>
|
||||
<div class='section'>
|
||||
<div class='docs'><h1>examplemodel.py</h1></div>
|
||||
</div>
|
||||
<div class='clearall'>
|
||||
<div class='section' id='section-0'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-0'>#</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">core.emane</span> <span class="kn">import</span> <span class="n">emanemanifest</span>
|
||||
<span class="kn">from</span> <span class="nn">core.emane</span> <span class="kn">import</span> <span class="n">emanemodel</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-1'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-1'>#</a>
|
||||
</div>
|
||||
<h1>Custom EMANE Model</h1>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre><span class="k">class</span> <span class="nc">ExampleModel</span><span class="p">(</span><span class="n">emanemodel</span><span class="o">.</span><span class="n">EmaneModel</span><span class="p">):</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-2'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-2'>#</a>
|
||||
</div>
|
||||
<h2>MAC Definition</h2>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-3'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-3'>#</a>
|
||||
</div>
|
||||
<p>Defines the emane model name that will show up in the GUI.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="n">name</span> <span class="o">=</span> <span class="s2">"emane_example"</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-4'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-4'>#</a>
|
||||
</div>
|
||||
<p>Defines that mac library that the model will reference.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="n">mac_library</span> <span class="o">=</span> <span class="s2">"rfpipemaclayer"</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-5'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-5'>#</a>
|
||||
</div>
|
||||
<p>Defines the mac manifest file that will be parsed to obtain configuration options, that will be displayed
|
||||
within the GUI.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="n">mac_xml</span> <span class="o">=</span> <span class="s2">"/usr/share/emane/manifest/rfpipemaclayer.xml"</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-6'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-6'>#</a>
|
||||
</div>
|
||||
<p>Allows you to override options that are maintained within the manifest file above.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="n">mac_defaults</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s2">"pcrcurveuri"</span><span class="p">:</span> <span class="s2">"/usr/share/emane/xml/models/mac/rfpipe/rfpipepcr.xml"</span><span class="p">,</span>
|
||||
<span class="p">}</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-7'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-7'>#</a>
|
||||
</div>
|
||||
<p>Parses the manifest file and converts configurations into core supported formats.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="n">mac_config</span> <span class="o">=</span> <span class="n">emanemanifest</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">mac_xml</span><span class="p">,</span> <span class="n">mac_defaults</span><span class="p">)</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-8'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-8'>#</a>
|
||||
</div>
|
||||
<h2>PHY Definition</h2>
|
||||
<p><strong>NOTE: phy configuration will default to the universal model as seen below and the below section does not
|
||||
have to be included.</strong></p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-9'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-9'>#</a>
|
||||
</div>
|
||||
<p>Defines that phy library that the model will reference, used if you need to provide a custom phy.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="n">phy_library</span> <span class="o">=</span> <span class="bp">None</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-10'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-10'>#</a>
|
||||
</div>
|
||||
<p>Defines the phy manifest file that will be parsed to obtain configuration options, that will be displayed
|
||||
within the GUI.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="n">phy_xml</span> <span class="o">=</span> <span class="s2">"/usr/share/emane/manifest/emanephy.xml"</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-11'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-11'>#</a>
|
||||
</div>
|
||||
<p>Allows you to override options that are maintained within the manifest file above or for the default universal
|
||||
model.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="n">phy_defaults</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s2">"subid"</span><span class="p">:</span> <span class="s2">"1"</span><span class="p">,</span>
|
||||
<span class="s2">"propagationmodel"</span><span class="p">:</span> <span class="s2">"2ray"</span><span class="p">,</span>
|
||||
<span class="s2">"noisemode"</span><span class="p">:</span> <span class="s2">"none"</span>
|
||||
<span class="p">}</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-12'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-12'>#</a>
|
||||
</div>
|
||||
<p>Parses the manifest file and converts configurations into core supported formats.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="n">phy_config</span> <span class="o">=</span> <span class="n">emanemanifest</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">phy_xml</span><span class="p">,</span> <span class="n">phy_defaults</span><span class="p">)</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-13'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-13'>#</a>
|
||||
</div>
|
||||
<h2>Custom override options</h2>
|
||||
<p><strong>NOTE: these options default to what's seen below and do not have to be included.</strong></p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-14'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-14'>#</a>
|
||||
</div>
|
||||
<p>Allows you to ignore options within phy/mac, used typically if you needed to add a custom option for display
|
||||
within the gui.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="n">config_ignore</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-15'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-15'>#</a>
|
||||
</div>
|
||||
<p>Allows you to override how options are displayed with the GUI, using the GUI format of
|
||||
"name:1-2|othername:3-4". This will be parsed into tabs, split by "|" and account for items based on the indexed
|
||||
numbers after ":" for including values in each tab.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="n">config_groups_override</span> <span class="o">=</span> <span class="bp">None</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-16'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-16'>#</a>
|
||||
</div>
|
||||
<p>Allows you to override the default config matrix list. This value by default is the mac_config + phy_config, in
|
||||
that order.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="n">config_matrix_override</span> <span class="o">=</span> <span class="bp">None</span>
|
||||
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
</div>
|
||||
</body>
|
34
docs/index.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
# CORE Documentation
|
||||
|
||||
## Introduction
|
||||
|
||||
CORE (Common Open Research Emulator) is a tool for building virtual networks. As an emulator, CORE builds a representation of a real computer network that runs in real time, as opposed to simulation, where abstract models are used. The live-running emulation can be connected to physical networks and routers. It provides an environment for running real applications and protocols, taking advantage of virtualization provided by the Linux operating system.
|
||||
|
||||
CORE is typically used for network and protocol research, demonstrations, application and platform testing, evaluating networking scenarios, security studies, and increasing the size of physical test networks.
|
||||
|
||||
### Key Features
|
||||
* Efficient and scalable
|
||||
* Runs applications and protocols without modification
|
||||
* Drag and drop GUI
|
||||
* Highly customizable
|
||||
|
||||
## Topics
|
||||
|
||||
* [Architecture](architecture.md)
|
||||
* [Installation](install.md)
|
||||
* [Usage](usage.md)
|
||||
* [Python Scripting](scripting.md)
|
||||
* [Node Types](machine.md)
|
||||
* [CTRLNET](ctrlnet.md)
|
||||
* [EMANE](emane.md)
|
||||
* [NS3](ns3.md)
|
||||
* [Performance](performance.md)
|
||||
* [Developers Guide](devguide.md)
|
||||
|
||||
## Credits
|
||||
|
||||
The CORE project was derived from the open source IMUNES project from the University of Zagreb in 2004. In 2006, changes for CORE were released back to that project, some items of which were adopted. Marko Zec <zec@fer.hr> is the primary developer from the University of Zagreb responsible for the IMUNES (GUI) and VirtNet (kernel) projects. Ana Kukec and Miljenko Mikuc are known contributors.
|
||||
|
||||
Jeff Ahrenholz has been the primary Boeing developer of CORE, and has written this manual. Tom Goff designed the Python framework and has made significant contributions. Claudiu Danilov, Rod Santiago, Kevin Larson, Gary Pei, Phil Spagnolo, and Ian Chakeres have contributed code to CORE. Dan Mackley helped develop the CORE API, originally to interface with a simulator. Jae Kim and Tom Henderson have supervised the project and provided direction.
|
||||
|
||||
Copyright (c) 2005-2018, the Boeing Company.
|
267
docs/install.md
Normal file
|
@ -0,0 +1,267 @@
|
|||
|
||||
# CORE Installation
|
||||
|
||||
* Table of Contents
|
||||
{:toc}
|
||||
|
||||
# Overview
|
||||
|
||||
This section will describe how to set up a CORE machine. Note that the easiest way to install CORE is using a binary package on Ubuntu or Fedora/CentOS (deb or rpm) using the distribution's package manager to automatically install dependencies.
|
||||
|
||||
Ubuntu and Fedora/CentOS Linux are the recommended distributions for running CORE. However, these distributions are not strictly required. CORE will likely work on other flavors of Linux as well.
|
||||
|
||||
The primary dependencies are Tcl/Tk (8.5 or newer) for the GUI, and Python 2.7 for the CORE daemon.
|
||||
|
||||
CORE files are installed to the following directories, when the installation prefix is */usr*.
|
||||
|
||||
Install Path | Description
|
||||
-------------|------------
|
||||
/usr/local/bin/core-gui|GUI startup command
|
||||
/usr/bin/core-daemon|Daemon startup command
|
||||
/usr/bin/|Misc. helper commands/scripts
|
||||
/usr/lib/core|GUI files
|
||||
/usr/lib/python2.7/dist-packages/core|Python modules for daemon/scripts
|
||||
/etc/core/|Daemon configuration files
|
||||
~/.core/|User-specific GUI preferences and scenario files
|
||||
/usr/share/core/|Example scripts and scenarios
|
||||
/usr/share/man/man1/|Command man pages
|
||||
/etc/init.d/core-daemon|SysV startup script for daemon
|
||||
/etc/systemd/system/core-daemon.service|Systemd startup script for daemon
|
||||
|
||||
## Prerequisites
|
||||
|
||||
A Linux operating system is required. The GUI uses the Tcl/Tk scripting toolkit, and the CORE daemon requires Python. Details of the individual software packages required can be found in the installation steps.
|
||||
|
||||
## Required Hardware
|
||||
|
||||
Any computer capable of running Linux should be able to run CORE. Since the physical machine will be hosting numerous virtual machines, as a general rule you should select a machine having as much RAM and CPU resources as possible.
|
||||
|
||||
## Required Software
|
||||
|
||||
CORE requires a Linux operating system because it uses virtualization provided by the kernel. It does not run on Windows or Mac OS X operating systems (unless it is running within a virtual machine guest.) The virtualization technology that CORE currently uses is Linux network namespaces.
|
||||
|
||||
The CORE GUI requires the X.Org X Window system (X11), or can run over a remote X11 session. For specific Tcl/Tk, Python, and other libraries required to run CORE.
|
||||
|
||||
**NOTE: CORE *Services* determine what run on each node. You may require other software packages depending on the services you wish to use. For example, the *HTTP* service will require the *apache2* package.**
|
||||
|
||||
## Installing from Packages
|
||||
|
||||
The easiest way to install CORE is using the pre-built packages. The package managers on Ubuntu or Fedora/CentOS will automatically install dependencies for you. You can obtain the CORE packages from [CORE GitHub](https://github.com/coreemu/core/releases).
|
||||
|
||||
### Installing from Packages on Ubuntu
|
||||
|
||||
Install Quagga for routing. If you plan on working with wireless networks, we recommend installing [OSPF MDR](http://www.nrl.navy.mil/itd/ncs/products/ospf-manet) (replace *amd64* below with *i386* if needed to match your architecture):
|
||||
|
||||
```shell
|
||||
wget https://downloads.pf.itd.nrl.navy.mil/ospf-manet/quagga-0.99.21mr2.2/quagga-mr_0.99.21mr2.2_amd64.deb
|
||||
sudo dpkg -i quagga-mr_0.99.21mr2.2_amd64.deb
|
||||
```
|
||||
|
||||
Or, for the regular Ubuntu version of Quagga:
|
||||
|
||||
```shell
|
||||
sudo apt-get install quagga
|
||||
```
|
||||
|
||||
Install the CORE deb packages for Ubuntu from command line.
|
||||
|
||||
```shell
|
||||
sudo dpkg -i python-core_systemd_5.1_all.deb
|
||||
sudo dpkg -i core-gui_5.1_amd64.deb
|
||||
```
|
||||
|
||||
Start the CORE daemon as root, the systemd installation will auto start the daemon, but you can use the commands below if need be.
|
||||
|
||||
```shell
|
||||
# systemd
|
||||
sudo systemctl start core-daemon
|
||||
|
||||
# sysv
|
||||
sudo service core-daemon start
|
||||
```
|
||||
|
||||
Run the CORE GUI as a normal user:
|
||||
|
||||
```shell
|
||||
core-gui
|
||||
```
|
||||
|
||||
After running the *core-gui* command, a GUI should appear with a canvas for drawing topologies. Messages will print out on the console about connecting to the CORE daemon.
|
||||
|
||||
### Installing from Packages on Fedora/CentOS
|
||||
|
||||
The commands shown here should be run as root. The *x86_64* architecture is shown in the examples below, replace with *i686* is using a 32-bit architecture.
|
||||
|
||||
**CentOS 7 Only: in order to install *tkimg* package you must build from source.**
|
||||
|
||||
Make sure the system is up to date.
|
||||
|
||||
```shell
|
||||
yum update
|
||||
```
|
||||
|
||||
**Optional (Fedora 17+): Fedora 17 and newer have an additional prerequisite providing the required netem kernel modules (otherwise skip this step and have the package manager install it for you.)**
|
||||
|
||||
```shell
|
||||
yum install kernel-modules-extra
|
||||
```
|
||||
|
||||
Install Quagga for routing. If you plan on working with wireless networks, we recommend installing [OSPF MDR](http://www.nrl.navy.mil/itd/ncs/products/ospf-manet):
|
||||
|
||||
```shell
|
||||
wget https://downloads.pf.itd.nrl.navy.mil/ospf-manet/quagga-0.99.21mr2.2/quagga-0.99.21mr2.2-1.el6.x86_64.rpm
|
||||
sudo yum install quagga-0.99.21mr2.2-1.el6.x86_64.rpm
|
||||
```
|
||||
|
||||
Or, for the regular Fedora/CentOS version of Quagga:
|
||||
|
||||
```shell
|
||||
yum install quagga
|
||||
```
|
||||
|
||||
Install the CORE RPM packages and automatically resolve dependencies:
|
||||
|
||||
```shell
|
||||
yum install python-core_sysv_5.1_noarch.rpm
|
||||
yum install core-gui_5.1_x86_64.rpm
|
||||
```
|
||||
|
||||
Turn off SELINUX by setting *SELINUX=disabled* in the */etc/sysconfig/selinux* file, and adding *selinux=0* to the kernel line in your */etc/grub.conf* file; on Fedora 15 and newer, disable sandboxd using ```chkconfig sandbox off```; you need to reboot in order for this change to take effect
|
||||
|
||||
Turn off firewalls:
|
||||
|
||||
```shell
|
||||
systemctl disable firewalld
|
||||
systemctl disable iptables.service
|
||||
systemctl disable ip6tables.service
|
||||
chkconfig iptables off
|
||||
chkconfig ip6tables off
|
||||
```
|
||||
|
||||
You need to reboot after making these changes, or flush the firewall using
|
||||
|
||||
```shell
|
||||
iptables -F
|
||||
ip6tables -F
|
||||
```
|
||||
|
||||
Start the CORE daemon as root.
|
||||
|
||||
```shell
|
||||
# systemd
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl start core-daemon
|
||||
|
||||
# sysv
|
||||
sudo service core-daemon start
|
||||
```
|
||||
|
||||
Run the CORE GUI as a normal user:
|
||||
|
||||
```shell
|
||||
core-gui
|
||||
```
|
||||
|
||||
After running the *core-gui* command, a GUI should appear with a canvas for drawing topologies. Messages will print out on the console about connecting to the CORE daemon.
|
||||
|
||||
### Installing from Source
|
||||
|
||||
This option is listed here for developers and advanced users who are comfortable patching and building source code. Please consider using the binary packages instead for a simplified install experience.
|
||||
|
||||
To build CORE from source on Ubuntu, first install these development packages. These packages are not required for normal binary package installs.
|
||||
|
||||
#### Ubuntu pre-reqs
|
||||
|
||||
```shell
|
||||
sudo apt-get install
|
||||
```
|
||||
|
||||
You can obtain the CORE source from the [CORE GitHub](https://github.com/coreemu/core) page. Choose either a stable release version or the development snapshot available in the *nightly_snapshots* directory.
|
||||
|
||||
```shell
|
||||
tar xzf core-5.1.tar.gz
|
||||
cd core-5.1
|
||||
./bootstrap.sh
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
### Quagga Routing Software
|
||||
|
||||
Virtual networks generally require some form of routing in order to work (e.g. to automatically populate routing tables for routing packets from one subnet to another.) CORE builds OSPF routing protocol configurations by default when the blue router node type is used. The OSPF protocol is available from the [Quagga open source routing suit](http://www.quagga.net).
|
||||
|
||||
Quagga is not specified as a dependency for the CORE packages because there are two different Quagga packages that you may use:
|
||||
|
||||
* [Quagga](http://www.quagga.net) - the standard version of Quagga, suitable for static wired networks, and usually available via your distribution's package manager.
|
||||
|
||||
* [OSPF MANET Designated Routers](http://www.nrl.navy.mil/itd/ncs/products/ospf-manet) (MDR) - the Quagga routing suite with a modified version of OSPFv3, optimized for use with mobile wireless networks. The *mdr* node type (and the MDR service) requires this variant of Quagga.
|
||||
|
||||
If you plan on working with wireless networks, we recommend installing OSPF MDR; otherwise install the standard version of Quagga using your package manager or from source.
|
||||
|
||||
#### Installing Quagga from Packages
|
||||
|
||||
To install the standard version of Quagga from packages, use your package manager (Linux).
|
||||
|
||||
Ubuntu users:
|
||||
|
||||
```shell
|
||||
sudo apt-get install quagga
|
||||
```
|
||||
|
||||
Fedora/CentOS users:
|
||||
|
||||
```shell
|
||||
sudo yum install quagga
|
||||
```
|
||||
|
||||
To install the Quagga variant having OSPFv3 MDR, first download the appropriate package, and install using the package manager.
|
||||
|
||||
Ubuntu users:
|
||||
```shell
|
||||
wget https://downloads.pf.itd.nrl.navy.mil/ospf-manet/quagga-0.99.21mr2.2/quagga-mr_0.99.21mr2.2_amd64.deb
|
||||
sudo dpkg -i quagga-mr_0.99.21mr2.2_amd64.deb
|
||||
```
|
||||
|
||||
Replace *amd64* with *i686* if using a 32-bit architecture.
|
||||
|
||||
Fedora/CentOS users:
|
||||
|
||||
```shell
|
||||
wget https://downloads.pf.itd.nrl.navy.mil/ospf-manet/quagga-0.99.21mr2.2/quagga-0.99.21mr2.2-1.el6.x86_64.rpm
|
||||
sudo yum install quagga-0.99.21mr2.2-1.el6.x86_64.rpm
|
||||
````
|
||||
|
||||
Replace *x86_64* with *i686* if using a 32-bit architecture.
|
||||
|
||||
#### Compiling Quagga for CORE
|
||||
|
||||
To compile Quagga to work with CORE on Linux:
|
||||
|
||||
```shell
|
||||
wget https://downloads.pf.itd.nrl.navy.mil/ospf-manet/quagga-0.99.21mr2.2/quagga-0.99.21mr2.2.tar.gz
|
||||
tar xzf quagga-0.99.21mr2.2.tar.gz
|
||||
cd quagga-0.99
|
||||
./configure --enable-user=root --enable-group=root --with-cflags=-ggdb \\
|
||||
--sysconfdir=/usr/local/etc/quagga --enable-vtysh \\
|
||||
--localstatedir=/var/run/quagga
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
Note that the configuration directory */usr/local/etc/quagga* shown for Quagga above could be */etc/quagga*, if you create a symbolic link from */etc/quagga/Quagga.conf -> /usr/local/etc/quagga/Quagga.conf* on the host. The *quaggaboot.sh* script in a Linux network namespace will try and do this for you if needed.
|
||||
|
||||
If you try to run quagga after installing from source and get an error such as:
|
||||
|
||||
```shell
|
||||
error while loading shared libraries libzebra.so.0
|
||||
```
|
||||
|
||||
this is usually a sign that you have to run ```sudo ldconfig```` to refresh the cache file.
|
||||
|
||||
### VCORE
|
||||
|
||||
CORE is capable of running inside of a virtual machine, using software such as VirtualBox, VMware Server or QEMU. However, CORE itself is performing machine virtualization in order to realize multiple emulated nodes, and running CORE virtually adds additional contention for the physical resources. **For performance reasons, this is not recommended.** Timing inside of a VM often has problems. If you do run CORE from within a VM, it is recommended that you view the GUI with remote X11 over SSH, so the virtual machine does not need to emulate the video card with the X11 application.
|
||||
|
||||
A CORE virtual machine is provided for download, named VCORE. This is the perhaps the easiest way to get CORE up and running as the machine is already set up for you. This may be adequate for initially evaluating the tool but keep in mind the performance limitations of running within VirtualBox or VMware. To install the virtual machine, you first need to obtain VirtualBox from http://www.virtualbox.org, or VMware Server or Player from http://www.vmware.com (this commercial software is distributed for free.) Once virtualization software has been installed, you can import the virtual machine appliance using the *vbox* file for VirtualBox or the *vmx* file for VMware. See the documentation that comes with VCORE for login information.
|
||||
|
22
docs/machine.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
# CORE Node Types
|
||||
|
||||
* Table of Contents
|
||||
{:toc}
|
||||
|
||||
## Overview
|
||||
|
||||
Different node types can be configured in CORE, and each node type has a *machine type* that indicates how the node will be represented at run time. Different machine types allow for different virtualization options.
|
||||
|
||||
## netns nodes
|
||||
|
||||
The *netns* machine type is the default. This is for nodes that will be backed by Linux network namespaces. See :ref:`Linux` for a brief explanation of netns. This default machine type is very lightweight, providing a minimum amount of virtualization in order to emulate a network. Another reason this is designated as the default machine type is because this virtualization technology typically requires no changes to the kernel; it is available out-of-the-box from the latest mainstream Linux distributions.
|
||||
|
||||
## physical nodes
|
||||
|
||||
The *physical* machine type is used for nodes that represent a real Linux-based machine that will participate in the emulated network scenario. This is typically used, for example, to incorporate racks of server machines from an emulation testbed. A physical node is one that is running the CORE daemon (*core-daemon*), but will not be further partitioned into virtual machines. Services that are run on the physical node do not run in an isolated or virtualized environment, but directly on the operating system.
|
||||
|
||||
Physical nodes must be assigned to servers, the same way nodes are assigned to emulation servers with *Distributed Emulation*. The list of available physical nodes currently shares the same dialog box and list as the emulation servers, accessed using the *Emulation Servers...* entry from the *Session* menu.
|
||||
|
||||
Support for physical nodes is under development and may be improved in future releases. Currently, when any node is linked to a physical node, a dashed line is drawn to indicate network tunneling. A GRE tunneling interface will be created on the physical node and used to tunnel traffic to and from the emulated world.
|
||||
|
||||
Double-clicking on a physical node during runtime opens a terminal with an SSH shell to that node. Users should configure public-key SSH login as done with emulation servers.
|
171
docs/ns3.md
Normal file
|
@ -0,0 +1,171 @@
|
|||
# CORE / NS3
|
||||
|
||||
* Table of Contents
|
||||
{:toc}
|
||||
|
||||
**NOTE: Support for ns-3 is limited and not currently being developed.**
|
||||
|
||||
## What is ns-3?
|
||||
|
||||
[ns-3 network simulator](http://www.nsnam.org) is a discrete-event network simulator for Internet systems, targeted primarily for research and educational use. By default, ns-3 simulates entire networks, from applications down to channels, and it does so in simulated time, instead of real (wall-clock) time.
|
||||
|
||||
CORE can run in conjunction with ns-3 to simulate some types of networks. CORE network namespace virtual nodes can have virtual TAP interfaces installed using the simulator for communication. The simulator needs to run at wall clock time with the real-time scheduler. In this type of configuration, the CORE namespaces are used to provide packets to the ns-3 devices and channels. This allows, for example, wireless models developed for ns-3 to be used in an emulation context.
|
||||
|
||||
Users simulate networks with ns-3 by writing C++ programs or Python scripts that import the ns-3 library. Simulation models are objects instantiated in these scripts. Combining the CORE Python modules with ns-3 Python bindings allow a script to easily set up and manage an emulation + simulation environment.
|
||||
|
||||
## ns-3 Scripting
|
||||
|
||||
Currently, ns-3 is supported by writing Python scripts, but not through drag-and-drop actions within the GUI. If you have a copy of the CORE source, look under *ns3/examples/* for example scripts; a CORE installation package puts these under */usr/share/core/examples/corens3*.
|
||||
|
||||
To run these scripts, install CORE so the CORE Python libraries are accessible, and download and build ns-3. This has been tested using ns-3 releases starting with 3.11 (and through 3.16 as of this writing).
|
||||
|
||||
The first step is to open an ns-3 waf shell. [waf](http://code.google.com/p/waf/) is the build system for ns-3. Opening a waf shell as root will merely set some environment variables useful for finding python modules and ns-3 executables. The following environment variables are extended or set by issuing *waf shell*:
|
||||
|
||||
```shell
|
||||
PATH
|
||||
PYTHONPATH
|
||||
LD_LIBRARY_PATH
|
||||
NS3_MODULE_PATH
|
||||
NS3_EXECUTABLE_PATH
|
||||
```
|
||||
|
||||
Open a waf shell as root, so that network namespaces may be instantiated by the script with root permissions. For an example, run the *ns3wifi.py* program, which simply instantiates 10 nodes (by default) and places them on an ns-3 WiFi channel. That is, the script will instantiate 10 namespace nodes, and create a special tap device that sends packets between the namespace node and a special ns-3 simulation node, where the tap device is bridged to an ns-3 WiFi network device, and attached to an ns-3 WiFi channel.
|
||||
|
||||
```shell
|
||||
cd ns-allinone-3.16/ns-3.16
|
||||
sudo ./waf shell
|
||||
# use '/usr/local' below if installed from source
|
||||
cd /usr/share/core/examples/corens3/
|
||||
```
|
||||
|
||||
```python
|
||||
python -i ns3wifi.py
|
||||
# running ns-3 simulation for 600 seconds
|
||||
print session
|
||||
<corens3.obj.Ns3Session object at 0x1963e50>
|
||||
```
|
||||
|
||||
The interactive Python shell allows some interaction with the Python objects for the emulation.
|
||||
|
||||
In another terminal, nodes can be accessed using *vcmd*:
|
||||
|
||||
```shell
|
||||
vcmd -c /tmp/pycore.10781/n1 -- bash
|
||||
root@n1:/tmp/pycore.10781/n1.conf#
|
||||
root@n1:/tmp/pycore.10781/n1.conf# ping 10.0.0.3
|
||||
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
|
||||
64 bytes from 10.0.0.3: icmp_req=1 ttl=64 time=7.99 ms
|
||||
64 bytes from 10.0.0.3: icmp_req=2 ttl=64 time=3.73 ms
|
||||
64 bytes from 10.0.0.3: icmp_req=3 ttl=64 time=3.60 ms
|
||||
^C
|
||||
--- 10.0.0.3 ping statistics ---
|
||||
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
|
||||
rtt min/avg/max/mdev = 3.603/5.111/7.993/2.038 ms
|
||||
root@n1:/tmp/pycore.10781/n1.conf#
|
||||
```
|
||||
|
||||
The ping packets shown above are traversing an ns-3 ad-hoc Wifi simulated network.
|
||||
|
||||
To clean up the session, use the Session.shutdown() method from the Python terminal.
|
||||
|
||||
```python
|
||||
print session
|
||||
<corens3.obj.Ns3Session object at 0x1963e50>
|
||||
session.shutdown()
|
||||
```
|
||||
|
||||
A CORE/ns-3 Python script will instantiate an Ns3Session, which is a CORE Session having CoreNs3Nodes, an ns-3 MobilityHelper, and a fixed duration. The CoreNs3Node inherits from both the CoreNode and the ns-3 Node classes -- it is a network namespace having an associated simulator object. The CORE TunTap interface is used, represented by a ns-3 TapBridge in *CONFIGURE_LOCAL* mode, where ns-3 creates and configures the tap device. An event is scheduled to install the taps at time 0.
|
||||
|
||||
**NOTE: The GUI can be used to run the *ns3wifi.py* and *ns3wifirandomwalk.py* scripts directly. First, *core-daemon* must be stopped and run within the waf root shell. Then the GUI may be run as a normal user, and the *Execute Python Script...* option may be used from the *File* menu. Dragging nodes around in the *ns3wifi.py* example will cause their ns-3 positions to be updated.**
|
||||
|
||||
Users may find the files *ns3wimax.py* and *ns3lte.py* in that example directory; those files were similarly configured, but the underlying ns-3 support is not present as of ns-3.16, so they will not work. Specifically, the ns-3 has to be extended to support bridging the Tap device to an LTE and a WiMax device.
|
||||
|
||||
## Integration details
|
||||
|
||||
The previous example *ns3wifi.py* used Python API from the special Python objects *Ns3Session* and *Ns3WifiNet*. The example program does not import anything directly from the ns-3 python modules; rather, only the above two objects are used, and the API available to configure the underlying ns-3 objects is constrained. For example, *Ns3WifiNet* instantiates a constant-rate 802.11a-based ad hoc network, using a lot of ns-3 defaults.
|
||||
|
||||
However, programs may be written with a blend of ns-3 API and CORE Python API calls. This section examines some of the fundamental objects in the CORE ns-3 support. Source code can be found in *ns3/corens3/obj.py* and example code in *ns3/corens3/examples/*.
|
||||
|
||||
## Ns3Session
|
||||
|
||||
The *Ns3Session* class is a CORE Session that starts an ns-3 simulation thread. ns-3 actually runs as a separate process on the same host as the CORE daemon, and the control of starting and stopping this process is performed by the *Ns3Session* class.
|
||||
|
||||
Example:
|
||||
|
||||
```python
|
||||
session = Ns3Session(persistent=True, duration=opt.duration)
|
||||
```
|
||||
|
||||
Note the use of the duration attribute to control how long the ns-3 simulation should run. By default, the duration is 600 seconds.
|
||||
|
||||
Typically, the session keeps track of the ns-3 nodes (holding a node container for references to the nodes). This is accomplished via the ```addnode()``` method, e.g.:
|
||||
|
||||
```python
|
||||
for i in xrange(1, opt.numnodes + 1):
|
||||
node = session.addnode(name = "n%d" % i)
|
||||
```
|
||||
|
||||
```addnode()``` creates instances of a *CoreNs3Node*, which we'll cover next.
|
||||
|
||||
## CoreNs3Node
|
||||
|
||||
A *CoreNs3Node* is both a CoreNode and an ns-3 node:
|
||||
|
||||
```python
|
||||
class CoreNs3Node(CoreNode, ns.network.Node):
|
||||
"""
|
||||
The CoreNs3Node is both a CoreNode backed by a network namespace and
|
||||
an ns-3 Node simulator object. When linked to simulated networks, the TunTap
|
||||
device will be used.
|
||||
"""
|
||||
```
|
||||
|
||||
## CoreNs3Net
|
||||
|
||||
A *CoreNs3Net* derives from *PyCoreNet*. This network exists entirely in simulation, using the TunTap device to interact between the emulated and the simulated realm. *Ns3WifiNet* is a specialization of this.
|
||||
|
||||
As an example, this type of code would be typically used to add a WiFi network to a session:
|
||||
|
||||
```python
|
||||
wifi = session.addobj(cls=Ns3WifiNet, name="wlan1", rate="OfdmRate12Mbps")
|
||||
wifi.setposition(30, 30, 0)
|
||||
```
|
||||
|
||||
The above two lines will create a wlan1 object and set its initial canvas position. Later in the code, the newnetif method of the CoreNs3Node can be used to add interfaces on particular nodes to this network; e.g.:
|
||||
|
||||
```python
|
||||
for i in xrange(1, opt.numnodes + 1):
|
||||
node = session.addnode(name = "n%d" % i)
|
||||
node.newnetif(wifi, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
|
||||
```
|
||||
|
||||
## Mobility
|
||||
|
||||
Mobility in ns-3 is handled by an object (a MobilityModel) aggregated to an ns-3 node. The MobilityModel is able to report the position of the object in the ns-3 space. This is a slightly different model from, for instance, EMANE, where location is associated with an interface, and the CORE GUI, where mobility is configured by right-clicking on a WiFi cloud.
|
||||
|
||||
The CORE GUI supports the ability to render the underlying ns-3 mobility model, if one is configured, on the CORE canvas. For example, the example program :file:`ns3wifirandomwalk.py` uses five nodes (by default) in a random walk mobility model. This can be executed by starting the core daemon from an ns-3 waf shell:
|
||||
|
||||
```shell
|
||||
sudo bash
|
||||
cd /path/to/ns-3
|
||||
./waf shell
|
||||
core-daemon
|
||||
```
|
||||
|
||||
and in a separate window, starting the CORE GUI (not from a waf shell) and selecting the *Execute Python script...* option from the File menu, selecting the *ns3wifirandomwalk.py* script.
|
||||
|
||||
The program invokes ns-3 mobility through the following statement:
|
||||
|
||||
```python
|
||||
session.setuprandomwalkmobility(bounds=(1000.0, 750.0, 0))
|
||||
```
|
||||
|
||||
This can be replaced by a different mode of mobility, in which nodes are placed according to a constant mobility model, and a special API call to the CoreNs3Net object is made to use the CORE canvas positions.
|
||||
|
||||
```python
|
||||
session.setuprandomwalkmobility(bounds=(1000.0, 750.0, 0))
|
||||
session.setupconstantmobility()
|
||||
wifi.usecorepositions()
|
||||
```
|
||||
|
||||
In this mode, the user dragging around the nodes on the canvas will cause CORE to update the position of the underlying ns-3 nodes.
|
28
docs/performance.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
# CORE Performance
|
||||
|
||||
* Table of Contents
|
||||
{:toc}
|
||||
|
||||
## Overview
|
||||
|
||||
The top question about the performance of CORE is often *how many nodes can it handle?* The answer depends on several factors:
|
||||
|
||||
* Hardware - the number and speed of processors in the computer, the available processor cache, RAM memory, and front-side bus speed may greatly affect overall performance.
|
||||
* Operating system version - distribution of Linux and the specific kernel versions used will affect overall performance.
|
||||
* Active processes - all nodes share the same CPU resources, so if one or more nodes is performing a CPU-intensive task, overall performance will suffer.
|
||||
* Network traffic - the more packets that are sent around the virtual network increases the amount of CPU usage.
|
||||
* GUI usage - widgets that run periodically, mobility scenarios, and other GUI interactions generally consume CPU cycles that may be needed for emulation.
|
||||
|
||||
On a typical single-CPU Xeon 3.0GHz server machine with 2GB RAM running Linux, we have found it reasonable to run 30-75 nodes running OSPFv2 and OSPFv3 routing. On this hardware CORE can instantiate 100 or more nodes, but at that point it becomes critical as to what each of the nodes is doing.
|
||||
|
||||
Because this software is primarily a network emulator, the more appropriate question is *how much network traffic can it handle?* On the same 3.0GHz server described above, running Linux, about 300,000 packets-per-second can be pushed through the system. The number of hops and the size of the packets is less important. The limiting factor is the number of times that the operating system needs to handle a packet. The 300,000 pps figure represents the number of times the system as a whole needed to deal with a packet. As more network hops are added, this increases the number of context switches and decreases the throughput seen on the full length of the network path.
|
||||
|
||||
**NOTE: The right question to be asking is *"how much traffic?"*, not *"how many nodes?"*.**
|
||||
|
||||
For a more detailed study of performance in CORE, refer to the following publications:
|
||||
|
||||
* J\. Ahrenholz, T. Goff, and B. Adamson, Integration of the CORE and EMANE Network Emulators, Proceedings of the IEEE Military Communications Conference 2011, November 2011.
|
||||
|
||||
* Ahrenholz, J., Comparison of CORE Network Emulation Platforms, Proceedings of the IEEE Military Communications Conference 2010, pp. 864-869, November 2010.
|
||||
|
||||
* J\. Ahrenholz, C. Danilov, T. Henderson, and J.H. Kim, CORE: A real-time network emulator, Proceedings of IEEE MILCOM Conference, 2008.
|
190
docs/pycco.css
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*--------------------- Layout and Typography ----------------------------*/
|
||||
body {
|
||||
font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
color: #252519;
|
||||
margin: 0; padding: 0;
|
||||
background: #f5f5ff;
|
||||
}
|
||||
a {
|
||||
color: #261a3b;
|
||||
}
|
||||
a:visited {
|
||||
color: #261a3b;
|
||||
}
|
||||
p {
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 40px 0 15px 0;
|
||||
}
|
||||
h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
}
|
||||
#container {
|
||||
background: white;
|
||||
}
|
||||
#container, div.section {
|
||||
position: relative;
|
||||
}
|
||||
#background {
|
||||
position: absolute;
|
||||
top: 0; left: 580px; right: 0; bottom: 0;
|
||||
background: #f5f5ff;
|
||||
border-left: 1px solid #e5e5ee;
|
||||
z-index: 0;
|
||||
}
|
||||
#jump_to, #jump_page {
|
||||
background: white;
|
||||
-webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
|
||||
-webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
|
||||
font: 10px Arial;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
}
|
||||
#jump_to, #jump_wrapper {
|
||||
position: fixed;
|
||||
right: 0; top: 0;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
#jump_wrapper {
|
||||
padding: 0;
|
||||
display: none;
|
||||
}
|
||||
#jump_to:hover #jump_wrapper {
|
||||
display: block;
|
||||
}
|
||||
#jump_page {
|
||||
padding: 5px 0 3px;
|
||||
margin: 0 0 25px 25px;
|
||||
}
|
||||
#jump_page .source {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
text-decoration: none;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
#jump_page .source:hover {
|
||||
background: #f5f5ff;
|
||||
}
|
||||
#jump_page .source:first-child {
|
||||
}
|
||||
div.docs {
|
||||
float: left;
|
||||
max-width: 500px;
|
||||
min-width: 500px;
|
||||
min-height: 5px;
|
||||
padding: 10px 25px 1px 50px;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
.docs pre {
|
||||
margin: 15px 0 15px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
.docs p tt, .docs p code {
|
||||
background: #f8f8ff;
|
||||
border: 1px solid #dedede;
|
||||
font-size: 12px;
|
||||
padding: 0 0.2em;
|
||||
}
|
||||
.octowrap {
|
||||
position: relative;
|
||||
}
|
||||
.octothorpe {
|
||||
font: 12px Arial;
|
||||
text-decoration: none;
|
||||
color: #454545;
|
||||
position: absolute;
|
||||
top: 3px; left: -20px;
|
||||
padding: 1px 2px;
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
}
|
||||
div.docs:hover .octothorpe {
|
||||
opacity: 1;
|
||||
}
|
||||
div.code {
|
||||
margin-left: 580px;
|
||||
padding: 14px 15px 16px 50px;
|
||||
vertical-align: top;
|
||||
}
|
||||
.code pre, .docs p code {
|
||||
font-size: 12px;
|
||||
}
|
||||
pre, tt, code {
|
||||
line-height: 18px;
|
||||
font-family: Monaco, Consolas, "Lucida Console", monospace;
|
||||
margin: 0; padding: 0;
|
||||
}
|
||||
div.clearall {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------- Syntax Highlighting -----------------------------*/
|
||||
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
|
||||
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
|
||||
body .hll { background-color: #ffffcc }
|
||||
body .c { color: #408080; font-style: italic } /* Comment */
|
||||
body .err { border: 1px solid #FF0000 } /* Error */
|
||||
body .k { color: #954121 } /* Keyword */
|
||||
body .o { color: #666666 } /* Operator */
|
||||
body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
||||
body .cp { color: #BC7A00 } /* Comment.Preproc */
|
||||
body .c1 { color: #408080; font-style: italic } /* Comment.Single */
|
||||
body .cs { color: #408080; font-style: italic } /* Comment.Special */
|
||||
body .gd { color: #A00000 } /* Generic.Deleted */
|
||||
body .ge { font-style: italic } /* Generic.Emph */
|
||||
body .gr { color: #FF0000 } /* Generic.Error */
|
||||
body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
body .gi { color: #00A000 } /* Generic.Inserted */
|
||||
body .go { color: #808080 } /* Generic.Output */
|
||||
body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
body .gs { font-weight: bold } /* Generic.Strong */
|
||||
body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
body .gt { color: #0040D0 } /* Generic.Traceback */
|
||||
body .kc { color: #954121 } /* Keyword.Constant */
|
||||
body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
|
||||
body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
|
||||
body .kp { color: #954121 } /* Keyword.Pseudo */
|
||||
body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
|
||||
body .kt { color: #B00040 } /* Keyword.Type */
|
||||
body .m { color: #666666 } /* Literal.Number */
|
||||
body .s { color: #219161 } /* Literal.String */
|
||||
body .na { color: #7D9029 } /* Name.Attribute */
|
||||
body .nb { color: #954121 } /* Name.Builtin */
|
||||
body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
body .no { color: #880000 } /* Name.Constant */
|
||||
body .nd { color: #AA22FF } /* Name.Decorator */
|
||||
body .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
||||
body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
||||
body .nf { color: #0000FF } /* Name.Function */
|
||||
body .nl { color: #A0A000 } /* Name.Label */
|
||||
body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
body .nt { color: #954121; font-weight: bold } /* Name.Tag */
|
||||
body .nv { color: #19469D } /* Name.Variable */
|
||||
body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
body .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
body .mf { color: #666666 } /* Literal.Number.Float */
|
||||
body .mh { color: #666666 } /* Literal.Number.Hex */
|
||||
body .mi { color: #666666 } /* Literal.Number.Integer */
|
||||
body .mo { color: #666666 } /* Literal.Number.Oct */
|
||||
body .sb { color: #219161 } /* Literal.String.Backtick */
|
||||
body .sc { color: #219161 } /* Literal.String.Char */
|
||||
body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
|
||||
body .s2 { color: #219161 } /* Literal.String.Double */
|
||||
body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
||||
body .sh { color: #219161 } /* Literal.String.Heredoc */
|
||||
body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
||||
body .sx { color: #954121 } /* Literal.String.Other */
|
||||
body .sr { color: #BB6688 } /* Literal.String.Regex */
|
||||
body .s1 { color: #219161 } /* Literal.String.Single */
|
||||
body .ss { color: #19469D } /* Literal.String.Symbol */
|
||||
body .bp { color: #954121 } /* Name.Builtin.Pseudo */
|
||||
body .vc { color: #19469D } /* Name.Variable.Class */
|
||||
body .vg { color: #19469D } /* Name.Variable.Global */
|
||||
body .vi { color: #19469D } /* Name.Variable.Instance */
|
||||
body .il { color: #666666 } /* Literal.Number.Integer.Long */
|
120
docs/scripting.md
Normal file
|
@ -0,0 +1,120 @@
|
|||
|
||||
# CORE Python Scripting
|
||||
|
||||
* Table of Contents
|
||||
{:toc}
|
||||
|
||||
## Overview
|
||||
|
||||
CORE can be used via the GUI or Python scripting. Writing your own Python scripts offers a rich programming environment with complete control over all aspects of the emulation. This chapter provides a brief introduction to scripting. Most of the documentation is available from sample scripts, or online via interactive Python.
|
||||
|
||||
The best starting point is the sample scripts that are included with CORE. If you have a CORE source tree, the example script files can be found under *core/daemon/examples/api/*. When CORE is installed from packages, the example script files will be in */usr/share/core/examples/api/* (or */usr/local/* prefix when installed from source.) For the most part, the example scripts are self-documenting; see the comments contained within the Python code.
|
||||
|
||||
The scripts should be run with root privileges because they create new network namespaces. In general, a CORE Python script does not connect to the CORE daemon, in fact the *core-daemon* is just another Python script that uses the CORE Python modules and exchanges messages with the GUI. To connect the GUI to your scripts, see the included sample scripts that allow for GUI connections.
|
||||
|
||||
Here are the basic elements of a CORE Python script:
|
||||
|
||||
```python
|
||||
from core.emulator.coreemu import CoreEmu
|
||||
from core.emulator.emudata import IpPrefixes
|
||||
from core.enumerations import EventTypes
|
||||
from core.enumerations import NodeTypes
|
||||
|
||||
# ip generator for example
|
||||
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
||||
|
||||
# create emulator instance for creating sessions and utility methods
|
||||
coreemu = CoreEmu()
|
||||
session = coreemu.create_session()
|
||||
|
||||
# must be in configuration state for nodes to start, when using "node_add" below
|
||||
session.set_state(EventTypes.CONFIGURATION_STATE)
|
||||
|
||||
# create switch network node
|
||||
switch = session.add_node(_type=NodeTypes.SWITCH)
|
||||
|
||||
# create nodes
|
||||
for _ in xrange(options.nodes):
|
||||
node = session.add_node()
|
||||
interface = prefixes.create_interface(node)
|
||||
session.add_link(node.objid, switch.objid, interface_one=interface)
|
||||
|
||||
# instantiate session
|
||||
session.instantiate()
|
||||
|
||||
# shutdown session
|
||||
coreemu.shutdown()
|
||||
```
|
||||
|
||||
The above script creates a CORE session having two nodes connected with a hub. The first node pings the second node with 5 ping packets; the result is displayed on screen.
|
||||
|
||||
A good way to learn about the CORE Python modules is via interactive Python. Scripts can be run using *python -i*. Cut and paste the simple script above and you will have two nodes connected by a hub, with one node running a test ping to the other.
|
||||
|
||||
The CORE Python modules are documented with comments in the code. From an interactive Python shell, you can retrieve online help about the various classes and methods; for example *help(nodes.CoreNode)* or *help(Session)*.
|
||||
|
||||
**NOTE: The CORE daemon *core-daemon* manages a list of sessions and allows the GUI to connect and control sessions. Your Python script uses the same CORE modules but runs independently of the daemon. The daemon does not need to be running for your script to work.**
|
||||
|
||||
The session created by a Python script may be viewed in the GUI if certain steps are followed. The GUI has a *File Menu*, *Execute Python script...* option for running a script and automatically connecting to it. Once connected, normal GUI interaction is possible, such as moving and double-clicking nodes, activating Widgets, etc.
|
||||
|
||||
The script should have a line such as the following for running it from the GUI.
|
||||
|
||||
```python
|
||||
if __name__ in ["__main__", "__builtin__"]:
|
||||
main()
|
||||
```
|
||||
|
||||
A script can add sessions to the core-daemon. A global *coreemu* variable is exposed to the script pointing to the *CoreEmu* object.
|
||||
The example below has a fallback to a new CoreEmu object, in the case you would like to run the script standalone, outside of the core-daemon.
|
||||
|
||||
```python
|
||||
coreemu = globals().get("coreemu", CoreEmu())
|
||||
session = coreemu.create_session()
|
||||
```
|
||||
|
||||
Finally, nodes and networks need to have their coordinates set to something, otherwise they will be grouped at the coordinates *<0, 0>*. First sketching the topology in the GUI and then using the *Export Python script* option may help here.
|
||||
|
||||
```python
|
||||
switch.setposition(x=80,y=50)
|
||||
```
|
||||
|
||||
A fully-worked example script that you can launch from the GUI is available in the examples directory.
|
||||
|
||||
## Configuring Services
|
||||
|
||||
Examples setting or configuring custom services for a node.
|
||||
|
||||
```python
|
||||
# create session and node
|
||||
coreemu = CoreEmu()
|
||||
session = coreemu.create_session()
|
||||
node = session.add_node()
|
||||
|
||||
# create and retrieve custom service
|
||||
session.services.set_service(node.objid, "ServiceName")
|
||||
custom_service = session.services.get_service(node.objid, "ServiceName")
|
||||
|
||||
# set custom file data
|
||||
session.services.set_service_file(node.objid, "ServiceName", "FileName", "custom file data")
|
||||
|
||||
# set services to a node, using custom services when defined
|
||||
session.services.add_services(node, node.type, ["Service1", "Service2"])
|
||||
```
|
||||
|
||||
# Configuring EMANE Models
|
||||
|
||||
Examples for configuring custom emane model settings.
|
||||
|
||||
```python
|
||||
# create session and emane network
|
||||
coreemu = CoreEmu()
|
||||
session = coreemu.create_session()
|
||||
emane_network = session.create_emane_network(
|
||||
model=EmaneIeee80211abgModel,
|
||||
geo_reference=(47.57917, -122.13232, 2.00000)
|
||||
)
|
||||
emane_network.setposition(x=80, y=50)
|
||||
|
||||
# set custom emane model config
|
||||
config = {}
|
||||
session.emane.set_model_config(emane_network.objid, EmaneIeee80211abgModel.name, config)
|
||||
```
|
BIN
docs/static/controlnetwork.png
vendored
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
docs/static/core-architecture.jpg
vendored
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
docs/static/core-workflow.jpg
vendored
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
docs/static/distributed-controlnetwork.png
vendored
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
docs/static/distributed-emane-configuration.png
vendored
Normal file
After Width: | Height: | Size: 160 KiB |
BIN
docs/static/distributed-emane-network.png
vendored
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
docs/static/single-pc-emane.png
vendored
Normal file
After Width: | Height: | Size: 131 KiB |