From 09896b008eb416b1ef05e1175a89458c981879a0 Mon Sep 17 00:00:00 2001 From: Niels van Adrichem Date: Wed, 11 Sep 2019 15:27:55 +0200 Subject: [PATCH 01/16] Disable MAC learning on Wlan networks --- daemon/core/nodes/network.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/daemon/core/nodes/network.py b/daemon/core/nodes/network.py index 2359ac41..eb1b3592 100644 --- a/daemon/core/nodes/network.py +++ b/daemon/core/nodes/network.py @@ -991,6 +991,10 @@ class WlanNode(CoreNetwork): # mobility model such as scripted self.mobility = None + # TODO: move to startup method + if start: + utils.check_cmd([constants.BRCTL_BIN, "setageing", self.brname, "0"]) + def attach(self, netif): """ Attach a network interface. From b43a686d6b79d6cbf54b0261f7345f31cec8c6ad Mon Sep 17 00:00:00 2001 From: Huy Pham Date: Thu, 12 Sep 2019 10:23:46 -0700 Subject: [PATCH 02/16] initial documentation improvements --- daemon/core/api/grpc/server.py | 6 + daemon/core/nodes/base.py | 3 +- docs/architecture.md | 2 +- docs/distributed.md | 5 +- docs/emane.md | 2 +- docs/scripting.md | 2 +- docs/usage.md | 328 +++++++++++---------------------- 7 files changed, 125 insertions(+), 223 deletions(-) diff --git a/daemon/core/api/grpc/server.py b/daemon/core/api/grpc/server.py index 95dde116..0295ed1a 100644 --- a/daemon/core/api/grpc/server.py +++ b/daemon/core/api/grpc/server.py @@ -58,6 +58,12 @@ def get_config_groups(config, configurable_options): def get_links(session, node): + """ + Get + :param session: + :param node: + :return: + """ links = [] for link_data in node.all_link_data(0): link = convert_link(session, link_data) diff --git a/daemon/core/nodes/base.py b/daemon/core/nodes/base.py index 1ce21aca..2267202e 100644 --- a/daemon/core/nodes/base.py +++ b/daemon/core/nodes/base.py @@ -170,7 +170,7 @@ class NodeBase(object): :param str lon: longitude :param str alt: altitude :return: node data object - :rtype: core.data.NodeData + :rtype: core.emulator.data.NodeData """ if self.apitype is None: return None @@ -696,6 +696,7 @@ class CoreNode(CoreNodeBase): logging.debug("interface mac: %s - %s", veth.name, veth.hwaddr) try: + # add network interface to the node. If unsuccessful, destroy the network interface and raise exception. self.addnetif(veth, ifindex) except ValueError as e: veth.shutdown() diff --git a/docs/architecture.md b/docs/architecture.md index 724bca79..e9d4a9e5 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -32,7 +32,7 @@ CORE combines these namespaces with Linux Ethernet bridging to form networks. Li ## 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. +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, distribute emulation, simulation integration, and more. The IMUNES project also consists of userspace and kernel components. ## Open Source Project and Resources diff --git a/docs/distributed.md b/docs/distributed.md index b251c4ca..076476db 100644 --- a/docs/distributed.md +++ b/docs/distributed.md @@ -110,7 +110,7 @@ be emulated locally on the master. When entering Execute mode, the CORE GUI will deploy the node on its assigned emulation server. Another way to assign emulation servers is to select one or more nodes using -the select tool (shift-click to select multiple), and right-click one of the +the select tool (ctrl-click to select multiple), and right-click one of the nodes and choose *Assign to...*. The **CORE emulation servers** dialog box may also be used to assign nodes to @@ -176,5 +176,6 @@ emane_event_generate = True then start (or restart) the daemon. 1. Installed and configure public-key SSH access on all servers (if you want to use double-click shells or Widgets.) -1. Assign nodes to desired servers, empty for master server +1. Choose the servers that participate in distributed emulation. +1. Assign nodes to desired servers, empty for master server. 1. Press the **Start** button to launch the distributed emulation. diff --git a/docs/emane.md b/docs/emane.md index 90c5ce2c..c3a983b8 100644 --- a/docs/emane.md +++ b/docs/emane.md @@ -16,7 +16,7 @@ Instead of building Linux Ethernet bridging networks with CORE, higher-fidelity 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. +An EMANE instance sends and receives OTA (Over-The-Air) 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. diff --git a/docs/scripting.md b/docs/scripting.md index 9f8594ea..6985b7d8 100644 --- a/docs/scripting.md +++ b/docs/scripting.md @@ -46,7 +46,7 @@ session.instantiate() 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. +The above script creates a CORE session having two nodes connected with a switch. 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. diff --git a/docs/usage.md b/docs/usage.md index 12ec9d8a..4f54daf3 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -69,59 +69,41 @@ The toolbar is a row of buttons that runs vertically along the left side of the When CORE is in Edit mode (the default), the vertical Editing Toolbar exists on the left side of the CORE window. Below are brief descriptions for each toolbar item, starting from the top. Most of the tools are grouped into related sub-menus, which appear when you click on their group icon. -* ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/select.gif) *Selection Tool* - default tool for selecting, moving, configuring nodes -* ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/start.gif) *Start button* - starts Execute mode, instantiates the emulation -* ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/link.gif) *Link* - the Link Tool allows network links to be drawn between two nodes by clicking and dragging the mouse -* ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/router.gif) *Network-layer virtual nodes* - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/router.gif) *Router* - runs Quagga OSPFv2 and OSPFv3 routing to forward packets - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/host.gif) *Host* - emulated server machine having a default route, runs SSH server - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/pc.gif) *PC* - basic emulated machine having a default route, runs no processes by default - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/mdr.gif) *MDR* - runs Quagga OSPFv3 MDR routing for MANET-optimized routing - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/router_green.gif) *PRouter* - physical router represents a real testbed machine - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/document-properties.gif) *Edit* - edit node types button invokes the CORE Node Types dialog. New types of nodes may be created having different icons and names. The default services that are started with each node type can be changed here. -* ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/hub.gif) *Link-layer nodes* - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/hub.gif) *Hub* - the Ethernet hub forwards incoming packets to every connected node - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/lanswitch.gif) *Switch* - the Ethernet switch intelligently forwards incoming packets to attached hosts using an Ethernet address hash table - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/wlan.gif) *Wireless LAN* - when routers are connected to this WLAN node, they join a wireless network and an antenna is drawn instead of a connecting line; the WLAN node typically controls connectivity between attached wireless nodes based on the distance between them - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/rj45.gif) *RJ45* - with the RJ45 Physical Interface Tool, emulated nodes can be linked to real physical interfaces; using this tool, real networks and devices can be physically connected to the live-running emulation - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/tunnel.gif) *Tunnel* - the Tunnel Tool allows connecting together more than one CORE emulation using GRE tunnels +* ![alt text](../gui/icons/tiny/select.gif) *Selection Tool* - default tool for selecting, moving, configuring nodes +* ![alt text](../gui/icons/tiny/start.gif) *Start button* - starts Execute mode, instantiates the emulation +* ![alt text](../gui/icons/tiny/link.gif) *Link* - the Link Tool allows network links to be drawn between two nodes by clicking and dragging the mouse +* ![alt text](../gui/icons/tiny/router.gif) *Network-layer virtual nodes* + * ![alt text](../gui/icons/tiny/router.gif) *Router* - runs Quagga OSPFv2 and OSPFv3 routing to forward packets + * ![alt text](../gui/icons/tiny/host.gif) *Host* - emulated server machine having a default route, runs SSH server + * ![alt text](../gui/icons/tiny/pc.gif) *PC* - basic emulated machine having a default route, runs no processes by default + * ![alt text](../gui/icons/tiny/mdr.gif) *MDR* - runs Quagga OSPFv3 MDR routing for MANET-optimized routing + * ![alt text](../gui/icons/tiny/router_green.gif) *PRouter* - physical router represents a real testbed machine + * ![alt text](../gui/icons/tiny/document-properties.gif) *Edit* - edit node types button invokes the CORE Node Types dialog. New types of nodes may be created having different icons and names. The default services that are started with each node type can be changed here. +* ![alt text](../gui/icons/tiny/hub.gif) *Link-layer nodes* + * ![alt text](../gui/icons/tiny/hub.gif) *Hub* - the Ethernet hub forwards incoming packets to every connected node + * ![alt text](../gui/icons/tiny/lanswitch.gif) *Switch* - the Ethernet switch intelligently forwards incoming packets to attached hosts using an Ethernet address hash table + * ![alt text](../gui/icons/tiny/wlan.gif) *Wireless LAN* - when routers are connected to this WLAN node, they join a wireless network and an antenna is drawn instead of a connecting line; the WLAN node typically controls connectivity between attached wireless nodes based on the distance between them + * ![alt text](../gui/icons/tiny/rj45.gif) *RJ45* - with the RJ45 Physical Interface Tool, emulated nodes can be linked to real physical interfaces; using this tool, real networks and devices can be physically connected to the live-running emulation + * ![alt text](../gui/icons/tiny/tunnel.gif) *Tunnel* - the Tunnel Tool allows connecting together more than one CORE emulation using GRE tunnels * *Annotation Tools* - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/marker.gif) *Marker* - for drawing marks on the canvas - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/oval.gif) *Oval* - for drawing circles on the canvas that appear in the background - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/rectangle.gif) *Rectangle* - for drawing rectangles on the canvas that appear in the background - * ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/text.gif) *Text* - for placing text captions on the canvas + * ![alt text](../gui/icons/tiny/marker.gif) *Marker* - for drawing marks on the canvas + * ![alt text](../gui/icons/tiny/oval.gif) *Oval* - for drawing circles on the canvas that appear in the background + * ![alt text](../gui/icons/tiny/rectangle.gif) *Rectangle* - for drawing rectangles on the canvas that appear in the background + * ![alt text](../gui/icons/tiny/text.gif) *Text* - for placing text captions on the canvas ### Execution Toolbar When the Start button is pressed, CORE switches to Execute mode, and the Edit toolbar on the left of the CORE window is replaced with the Execution toolbar Below are the items on this toolbar, starting from the top. -* ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/select.gif) *Selection Tool* - in Execute mode, the Selection Tool can be used for moving nodes around the canvas, and double-clicking on a node will open a shell window for that node; right-clicking on a node invokes a pop-up menu of run-time options for that node -* ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/stop.gif) *Stop button* - stops Execute mode, terminates the emulation, returns CORE to edit mode. -* ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/observe.gif) *Observer Widgets Tool* - clicking on this magnifying glass icon - invokes a menu for easily selecting an Observer Widget. The icon has a darker - gray background when an Observer Widget is active, during which time moving - the mouse over a node will pop up an information display for that node. -* ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/plot.gif) *Plot Tool* - with this tool enabled, clicking on any link will - activate the Throughput Widget and draw a small, scrolling throughput plot - on the canvas. The plot shows the real-time kbps traffic for that link. - The plots may be dragged around the canvas; right-click on a - plot to remove it. -* ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/marker.gif) *Marker* - for drawing freehand lines on the canvas, useful during - demonstrations; markings are not saved -* ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/twonode.gif) *Two-node Tool* - click to choose a starting and ending node, and - run a one-time *traceroute* between those nodes or a continuous *ping -R* - between nodes. The output is displayed in real time in a results box, while - the IP addresses are parsed and the complete network path is highlighted on - the CORE display. -* ![alt text](https://github.com/coreemu/core/blob/master/gui/icons/tiny/run.gif) *Run Tool* - this tool allows easily running a command on all or a - subset of all nodes. A list box allows selecting any of the nodes. A text - entry box allows entering any command. The command should return immediately, - otherwise the display will block awaiting response. The *ping* command, for - example, with no parameters, is not a good idea. The result of each command - is displayed in a results box. The first occurrence of the special text - "NODE" will be replaced with the node name. The command will not be attempted - to run on nodes that are not routers, PCs, or hosts, even if they are - selected. +||| +|---|---| +| ![alt text](../gui/icons/tiny/select.gif) *Selection Tool* | in Execute mode, the Selection Tool can be used for moving nodes around the canvas, and double-clicking on a node will open a shell window for that node; right-clicking on a node invokes a pop-up menu of run-time options for that node. | +| ![alt text](../gui/icons/tiny/stop.gif) *Stop button* | stops Execute mode, terminates the emulation, returns CORE to edit mode. | +| ![alt text](../gui/icons/tiny/observe.gif) *Observer Widgets Tool* | clicking on this magnifying glass icon invokes a menu for easily selecting an Observer Widget. The icon has a darker gray background when an Observer Widget is active, during which time moving the mouse over a node will pop up an information display for that node. | +| ![alt text](../gui/icons/tiny/plot.gif) *Plot Tool* | with this tool enabled, clicking on any link will activate the Throughput Widget and draw a small, scrolling throughput plot on the canvas. The plot shows the real-time kbps traffic for that link. The plots may be dragged around the canvas; right-click on a plot to remove it. | +| ![alt text](../gui/icons/tiny/marker.gif) *Marker* | for drawing freehand lines on the canvas, useful during demonstrations; markings are not saved. | +| ![alt text](../gui/icons/tiny/twonode.gif) *Two-node Tool* | click to choose a starting and ending node, and run a one-time *traceroute* between those nodes or a continuous *ping -R* between nodes. The output is displayed in real time in a results box, while the IP addresses are parsed and the complete network path is highlighted on the CORE display. | +| ![alt text](../gui/icons/tiny/run.gif) *Run Tool* | this tool allows easily running a command on all or a subset of all nodes. A list box allows selecting any of the nodes. A text entry box allows entering any command. The command should return immediately, otherwise the display will block awaiting response. The *ping* command, for example, with no parameters, is not a good idea. The result of each command is displayed in a results box. The first occurrence of the special text "NODE" will be replaced with the node name. The command will not be attempted to run on nodes that are not routers, PCs, or hosts, even if they are selected. | ## Menubar @@ -134,175 +116,92 @@ menu, by clicking the dashed line at the top. The File menu contains options for manipulating the **.imn** Configuration Files. Generally, these menu items should not be used in Execute mode. -* *New* - this starts a new file with an empty canvas. -* *Open* - invokes the File Open dialog box for selecting a new **.imn** - or XML file to open. You can change the default path used for this dialog - in the Preferences Dialog. -* *Save* - saves the current topology. If you have not yet specified a file - name, the Save As dialog box is invoked. -* *Save As XML* - invokes the Save As dialog box for selecting a new - **.xml** file for saving the current configuration in the XML file. -* *Save As imn* - invokes the Save As dialog box for selecting a new - **.imn** topology file for saving the current configuration. Files are saved in the - *IMUNES network configuration* file -* *Export Python script* - prints Python snippets to the console, for inclusion - in a CORE Python script. -* *Execute XML or Python script* - invokes a File Open dialog box for selecting an XML file to run or a - Python script to run and automatically connect to. If a Python script, the script must create - a new CORE Session and add this session to the daemon's list of sessions - in order for this to work -* *Execute Python script with options* - invokes a File Open dialog box for selecting a - Python script to run and automatically connect to. After a selection is made, - a Python Script Options dialog box is invoked to allow for command-line options to be added. - The Python script must create a new CORE Session and add this session to the daemon's list of sessions - in order for this to work -* *Open current file in editor* - this opens the current topology file in the - **vim** text editor. First you need to save the file. Once the file has been - edited with a text editor, you will need to reload the file to see your - changes. The text editor can be changed from the Preferences Dialog. -* *Print* - this uses the Tcl/Tk postscript command to print the current canvas - to a printer. A dialog is invoked where you can specify a printing command, - the default being **lpr**. The postscript output is piped to the print - command. -* *Save screenshot* - saves the current canvas as a postscript graphic file. -* Recently used files - above the Quit menu command is a list of recently use - files, if any have been opened. You can clear this list in the - Preferences dialog box. You can specify the number of files to keep in - this list from the Preferences dialog. Click on one of the file names - listed to open that configuration file. -* *Quit* - the Quit command should be used to exit the CORE GUI. CORE may - prompt for termination if you are currently in Execute mode. Preferences and - the recently-used files list are saved. +||| +|---|---| +| *New* |this starts a new file with an empty canvas. | +| *Open* | invokes the File Open dialog box for selecting a new **.imn** or XML file to open. You can change the default path used for this dialog in the Preferences Dialog. | +| *Save* | saves the current topology. If you have not yet specified a file name, the Save As dialog box is invoked. | +| *Save As XML* | invokes the Save As dialog box for selecting a new **.xml** file for saving the current configuration in the XML file. | +| *Save As imn* | invokes the Save As dialog box for selecting a new **.imn** topology file for saving the current configuration. Files are saved in the *IMUNES network configuration* file. | +| *Export Python script* | prints Python snippets to the console, for inclusion in a CORE Python script. | +| *Execute XML or Python script* | invokes a File Open dialog box for selecting an XML file to run or a Python script to run and automatically connect to. If a Python script, the script must create a new CORE Session and add this session to the daemon's list of sessions in order for this to work. | +| *Execute Python script with options* | invokes a File Open dialog box for selecting a Python script to run and automatically connect to. After a selection is made, a Python Script Options dialog box is invoked to allow for command-line options to be added. The Python script must create a new CORE Session and add this session to the daemon's list of sessions in order for this to work. | +| *Open current file in editor* | this opens the current topology file in the **vim** text editor. First you need to save the file. Once the file has been edited with a text editor, you will need to reload the file to see your changes. The text editor can be changed from the Preferences Dialog. | +| *Print* | this uses the Tcl/Tk postscript command to print the current canvas to a printer. A dialog is invoked where you can specify a printing command, the default being **lpr**. The postscript output is piped to the print command. | +| *Save screenshot* | saves the current canvas as a postscript graphic file. | +| *Recently used files* | above the Quit menu command is a list of recently use files, if any have been opened. You can clear this list in the Preferences dialog box. You can specify the number of files to keep in this list from the Preferences dialog. Click on one of the file names listed to open that configuration file. | +| *Quit* | the Quit command should be used to exit the CORE GUI. CORE may prompt for termination if you are currently in Execute mode. Preferences and the recently-used files list are saved. | ### Edit Menu -* *Undo* - attempts to undo the last edit in edit mode. -* *Redo* - attempts to redo an edit that has been undone. -* *Cut*, *Copy*, *Paste* - used to cut, copy, and paste a selection. When nodes - are pasted, their node numbers are automatically incremented, and existing - links are preserved with new IP addresses assigned. Services and their - customizations are copied to the new node, but care should be taken as - node IP addresses have changed with possibly old addresses remaining in any - custom service configurations. Annotations may also be copied and pasted. -* *Select All* - selects all items on the canvas. Selected items can be moved - as a group. -* *Select Adjacent* - select all nodes that are linked to the already selected - node(s). For wireless nodes this simply selects the WLAN node(s) that the - wireless node belongs to. You can use this by clicking on a node and pressing - CTRL+N to select the adjacent nodes. -* *Find...* - invokes the *Find* dialog box. The Find dialog can be used to - search for nodes by name or number. Results are listed in a table that - includes the node or link location and details such as IP addresses or - link parameters. Clicking on a result will focus the canvas on that node - or link, switching canvases if necessary. -* *Clear marker* - clears any annotations drawn with the marker tool. Also - clears any markings used to indicate a node's status. -* *Preferences...* - invokes the Preferences dialog box. +||| +|---|---| +| *Undo* | attempts to undo the last edit in edit mode. | +| *Redo* | attempts to redo an edit that has been undone. | +| *Cut*, *Copy*, *Paste* | used to cut, copy, and paste a selection. When nodes are pasted, their node numbers are automatically incremented, and existing links are preserved with new IP addresses assigned. Services and their customizations are copied to the new node, but care should be taken as node IP addresses have changed with possibly old addresses remaining in any custom service configurations. Annotations may also be copied and pasted. +| *Select All* | selects all items on the canvas. Selected items can be moved as a group. | +| *Select Adjacent* | select all nodes that are linked to the already selected node(s). For wireless nodes this simply selects the WLAN node(s) that the wireless node belongs to. You can use this by clicking on a node and pressing CTRL+N to select the adjacent nodes. | +| *Find...* | invokes the *Find* dialog box. The Find dialog can be used to search for nodes by name or number. Results are listed in a table that includes the node or link location and details such as IP addresses or link parameters. Clicking on a result will focus the canvas on that node or link, switching canvases if necessary. | +| *Clear marker* | clears any annotations drawn with the marker tool. Also clears any markings used to indicate a node's status. | +| *Preferences...* | invokes the Preferences dialog box. | ### Canvas Menu The canvas menu provides commands for adding, removing, changing, and switching to different editing canvases. -* *New* - creates a new empty canvas at the right of all existing canvases. -* *Manage...* - invokes the *Manage Canvases* dialog box, where canvases may be - renamed and reordered, and you can easily switch to one of the canvases by - selecting it. -* *Delete* - deletes the current canvas and all items that it contains. -* *Size/scale...* - invokes a Canvas Size and Scale dialog that allows - configuring the canvas size, scale, and geographic reference point. The size - controls allow changing the width and height of the current canvas, in pixels - or meters. The scale allows specifying how many meters are equivalent to 100 - pixels. The reference point controls specify the latitude, longitude, and - altitude reference point used to convert between geographic and Cartesian - coordinate systems. By clicking the *Save as default* option, all new - canvases will be created with these properties. The default canvas size can - also be changed in the Preferences dialog box. -* *Wallpaper...* - used for setting the canvas background image, -* *Previous*, *Next*, *First*, *Last* - used for switching the active canvas to - the first, last, or adjacent canvas. +||| +|---|---| +| *New* | creates a new empty canvas at the right of all existing canvases. | +| *Manage...* | invokes the *Manage Canvases* dialog box, where canvases may be renamed and reordered, and you can easily switch to one of the canvases by selecting it. | +| *Delete* | deletes the current canvas and all items that it contains. | +| *Size/scale...* | invokes a Canvas Size and Scale dialog that allows configuring the canvas size, scale, and geographic reference point. The size controls allow changing the width and height of the current canvas, in pixels or meters. The scale allows specifying how many meters are equivalent to 100 pixels. The reference point controls specify the latitude, longitude, and altitude reference point used to convert between geographic and Cartesian coordinate systems. By clicking the *Save as default* option, all new canvases will be created with these properties. The default canvas size can also be changed in the Preferences dialog box. +| *Wallpaper...* | used for setting the canvas background image. | +| *Previous*, *Next*, *First*, *Last* | used for switching the active canvas to the first, last, or adjacent canvas. | ### View Menu The View menu features items for controlling what is displayed on the drawing canvas. -* *Show* - opens a submenu of items that can be displayed or hidden, such as - interface names, addresses, and labels. Use these options to help declutter - the display. These options are generally saved in the topology - files, so scenarios have a more consistent look when copied from one computer - to another. -* *Show hidden nodes* - reveal nodes that have been hidden. Nodes are hidden by - selecting one or more nodes, right-clicking one and choosing *hide*. -* *Locked* - toggles locked view; when the view is locked, nodes cannot be - moved around on the canvas with the mouse. This could be useful when - sharing the topology with someone and you do not expect them to change - things. -* *3D GUI...* - launches a 3D GUI by running the command defined under - Preferences, *3D GUI command*. This is typically a script that runs - the SDT3D display. SDT is the Scripted Display Tool from NRL that is based on - NASA's Java-based WorldWind virtual globe software. -* *Zoom In* - magnifies the display. You can also zoom in by clicking *zoom - 100%* label in the status bar, or by pressing the **+** (plus) key. -* *Zoom Out* - reduces the size of the display. You can also zoom out by - right-clicking *zoom 100%* label in the status bar or by pressing the **-** - (minus) key. +||| +|---|---| +| *Show* | opens a submenu of items that can be displayed or hidden, such as interface names, addresses, and labels. Use these options to help declutter the display. These options are generally saved in the topology files, so scenarios have a more consistent look when copied from one computer to another. | +| *Show hidden nodes* | reveal nodes that have been hidden. Nodes are hidden by selecting one or more nodes, right-clicking one and choosing *hide*. | +| *Locked* | toggles locked view; when the view is locked, nodes cannot be moved around on the canvas with the mouse. This could be useful when sharing the topology with someone and you do not expect them to change things. | +| *3D GUI...* | launches a 3D GUI by running the command defined under Preferences, *3D GUI command*. This is typically a script that runs the SDT3D display. SDT is the Scripted Display Tool from NRL that is based on NASA's Java-based WorldWind virtual globe software. | +| *Zoom In* | magnifies the display. You can also zoom in by clicking *zoom 100%* label in the status bar, or by pressing the **+** (plus) key. | +| *Zoom Out* | reduces the size of the display. You can also zoom out by right-clicking *zoom 100%* label in the status bar or by pressing the **-** (minus) key. | ### Tools Menu The tools menu lists different utility functions. -* *Autorearrange all* - automatically arranges all nodes on the canvas. Nodes - having a greater number of links are moved to the center. This mode can - continue to run while placing nodes. To turn off this autorearrange mode, - click on a blank area of the canvas with the select tool, or choose this menu - option again. -* *Autorearrange selected* - automatically arranges the selected nodes on the - canvas. -* *Align to grid* - moves nodes into a grid formation, starting with the - smallest-numbered node in the upper-left corner of the canvas, arranging - nodes in vertical columns. -* *Traffic...* - invokes the CORE Traffic Flows dialog box, which allows - configuring, starting, and stopping MGEN traffic flows for the emulation. -* *IP addresses...* - invokes the IP Addresses dialog box for configuring which - IPv4/IPv6 prefixes are used when automatically addressing new interfaces. -* *MAC addresses...* - invokes the MAC Addresses dialog box for configuring the - starting number used as the lowest byte when generating each interface MAC - address. This value should be changed when tunneling between CORE emulations - to prevent MAC address conflicts. -* *Build hosts file...* - invokes the Build hosts File dialog box for - generating **/etc/hosts** file entries based on IP addresses used in the - emulation. -* *Renumber nodes...* - invokes the Renumber Nodes dialog box, which allows - swapping one node number with another in a few clicks. -* *Experimental...* - menu of experimental options, such as a tool to convert - ns-2 scripts to IMUNES imn topologies, supporting only basic ns-2 - functionality, and a tool for automatically dividing up a topology into - partitions. -* *Topology generator* - opens a submenu of topologies to generate. You can - first select the type of node that the topology should consist of, or routers - will be chosen by default. Nodes may be randomly placed, aligned in grids, or - various other topology patterns. - * *Random* - nodes are randomly placed about the canvas, but are not linked - together. This can be used in conjunction with a WLAN node to quickly create a wireless network. - * *Grid* - nodes are placed in horizontal rows starting in the upper-left - corner, evenly spaced to the right; nodes are not linked to each other. - * *Connected Grid* - nodes are placed in an N x M (width and height) - rectangular grid, and each node is linked to the node above, below, left - and right of itself. - * *Chain* - nodes are linked together one after the other in a chain. - * *Star* - one node is placed in the center with N nodes surrounding it in a - circular pattern, with each node linked to the center node - * *Cycle* - nodes are arranged in a circular pattern with every node - connected to its neighbor to form a closed circular path. - * *Wheel* - the wheel pattern links nodes in a combination of both Star and - Cycle patterns. - * *Cube* - generate a cube graph of nodes - * *Clique* - creates a clique graph of nodes, where every node is connected - to every other node - * *Bipartite* - creates a bipartite graph of nodes, having two disjoint sets - of vertices. -* *Debugger...* - opens the CORE Debugger window for executing arbitrary Tcl/Tk - commands. +||| +|---|---| +| *Autorearrange all* |automatically arranges all nodes on the canvas. Nodes having a greater number of links are moved to the center. This mode can continue to run while placing nodes. To turn off this autorearrange mode, click on a blank area of the canvas with the select tool, or choose this menu option again. | +| *Autorearrange selected* | automatically arranges the selected nodes on the canvas. | +| *Align to grid* | moves nodes into a grid formation, starting with the smallest-numbered node in the upper-left corner of the canvas, arranging nodes in vertical columns. | +| *Traffic...* | invokes the CORE Traffic Flows dialog box, which allows configuring, starting, and stopping MGEN traffic flows for the emulation. | +| *IP addresses...* | invokes the IP Addresses dialog box for configuring which IPv4/IPv6 prefixes are used when automatically addressing new interfaces. | +| *MAC addresses...* | invokes the MAC Addresses dialog box for configuring the starting number used as the lowest byte when generating each interface MAC address. This value should be changed when tunneling between CORE emulations to prevent MAC address conflicts. | +| *Build hosts file...* | invokes the Build hosts File dialog box for generating **/etc/hosts** file entries based on IP addresses used in the emulation. | +| *Renumber nodes...* | invokes the Renumber Nodes dialog box, which allows swapping one node number with another in a few clicks. | +| *Experimental...* | menu of experimental options, such as a tool to convert ns-2 scripts to IMUNES imn topologies, supporting only basic ns-2 functionality, and a tool for automatically dividing up a topology into partitions. | +| *Topology generator* | opens a submenu of topologies to generate. You can first select the type of node that the topology should consist of, or routers will be chosen by default. Nodes may be randomly placed, aligned in grids, or various other topology patterns. All of the supported patterns are listed in the table below. | +| *Debugger...* | opens the CORE Debugger window for executing arbitrary Tcl/Tk commands. | + +| |Different topology patterns| +|---|---| +| *Random* | nodes are randomly placed about the canvas, but are not linked together. This can be used in conjunction with a WLAN node to quickly create a wireless network. | +| *Grid* | nodes are placed in horizontal rows starting in the upper-left corner, evenly spaced to the right; nodes are not linked to each other. | +| *Connected Grid* | nodes are placed in an N x M (width and height) rectangular grid, and each node is linked to the node above, below, left and right of itself. | +| *Chain* | nodes are linked together one after the other in a chain. | +| *Star* | one node is placed in the center with N nodes surrounding it in a circular pattern, with each node linked to the center node. | +| *Cycle* | nodes are arranged in a circular pattern with every node connected to its neighbor to form a closed circular path. | +| *Wheel* | the wheel pattern links nodes in a combination of both Star and Cycle patterns. | +| *Cube* | generate a cube graph of nodes. | +| *Clique* | creates a clique graph of nodes, where every node is connected to every other node. | +| *Bipartite* | creates a bipartite graph of nodes, having two disjoint sets of vertices. | ### Widgets Menu @@ -611,9 +510,10 @@ The wireless LAN (WLAN) is covered in the next section. ### Wireless Networks The wireless LAN node allows you to build wireless networks where moving nodes -around affects the connectivity between them. The wireless LAN, or WLAN, node -appears as a small cloud. The WLAN offers several levels of wireless emulation -fidelity, depending on your modeling needs. +around affects the connectivity between them. Connection between a pair of nodes is stronger +when the nodes are closer while connection is weaker when the nodes are further away. +The wireless LAN, or WLAN, node appears as a small cloud. The WLAN offers +several levels of wireless emulation fidelity, depending on your modeling needs. The WLAN tool can be extended with plug-ins for different levels of wireless fidelity. The basic on/off range is the default setting available on all @@ -622,10 +522,10 @@ complexity and CPU usage. The availability of certain plug-ins varies depending on platform. See the table below for a brief overview of wireless model types. -Model|Type|Supported Platform(s)|Fidelity|Description ------|----|---------------------|--------|----------- -|Basic|on/off|Linux|Low|Ethernet bridging with ebtables -|EMANE|Plug-in|Linux|High|TAP device connected to EMANE emulator with pluggable MAC and PHY radio types +|Model|Type|Supported Platform(s)|Fidelity|Description| +|-----|----|---------------------|--------|-----------| +|Basic|on/off|Linux|Low|Ethernet bridging with ebtables| +|EMANE|Plug-in|Linux|High|TAP device connected to EMANE emulator with pluggable MAC and PHY radio types| To quickly build a wireless network, you can first place several router nodes onto the canvas. If you have the @@ -774,19 +674,13 @@ that CORE will create. In version 1.0, the XML file is also referred to as the Scenario Plan. The Scenario Plan will be logically made up of the following: -* **Network Plan** - describes nodes, hosts, interfaces, and the networks to - which they belong. -* **Motion Plan** - describes position and motion patterns for nodes in an - emulation. -* **Services Plan** - describes services (protocols, applications) and traffic - flows that are associated with certain nodes. -* **Visualization Plan** - meta-data that is not part of the NRL XML schema but - used only by CORE. For example, GUI options, canvas and annotation info, etc. - are contained here. -* **Test Bed Mappings** - describes mappings of nodes, interfaces and EMANE modules in the scenario to - test bed hardware. - CORE includes Test Bed Mappings in XML files that are saved while the scenario is running. - +||| +|---|---| +| **Network Plan** | describes nodes. hosts, interfaces, and the networks to which they belong. | +| **Motion Plan** | describes position and motion patterns for nodes in an emulation. | +| **Services Plan** | describes services (protocols, applications) and traffic flows that are associated with certain nodes. | +| **Visualization Plan** | meta-data that is not part of the NRL XML schema but used only by CORE. For example, GUI options, canvas and annotation info, etc. are contained here. | +| **Test Bed Mappings** | describes mappings of nodes, interfaces and EMANE modules in the scenario to test bed hardware. CORE includes Test Bed Mappings in XML files that are saved while the scenario is running. | The **.imn** file format comes from IMUNES, and is basically Tcl lists of nodes, links, etc. From 1843b5f709b26cea376fb8e4dc349a2fc8fba7f1 Mon Sep 17 00:00:00 2001 From: Huy Pham Date: Fri, 13 Sep 2019 11:07:04 -0700 Subject: [PATCH 03/16] further updates to python docs and docs files --- daemon/core/api/grpc/server.py | 393 ++++++++++++++++++++++++++++++++- daemon/core/config.py | 2 +- daemon/core/nodes/base.py | 7 +- docs/performance.md | 12 +- docs/services.md | 18 +- docs/usage.md | 108 ++++----- 6 files changed, 459 insertions(+), 81 deletions(-) diff --git a/daemon/core/api/grpc/server.py b/daemon/core/api/grpc/server.py index bbb3c67d..af283083 100644 --- a/daemon/core/api/grpc/server.py +++ b/daemon/core/api/grpc/server.py @@ -35,12 +35,27 @@ _INTERFACE_REGEX = re.compile(r"\d+") def convert_value(value): + """ + Convert value into string. + + :param value: value + :return: string conversion of the value + :rtype: str + """ if value is not None: value = str(value) return value +# TODO add comments def get_config_groups(config, configurable_options): + """ + ??? + + :param core.config.Configuration config: configuration + :param core.config.ConfigurableOptions configurable_options: configurable options + :return: + """ groups = [] config_options = [] @@ -66,11 +81,13 @@ def get_config_groups(config, configurable_options): return groups +# TODO add comments def get_links(session, node): """ Get - :param session: - :param node: + + :param core.emulator.Session session: node's section + :param core.nodes.base.CoreNode node: node to get links from :return: """ links = [] @@ -81,6 +98,14 @@ def get_links(session, node): def get_emane_model_id(node_id, interface_id): + """ + Get EMANE model id + + :param int node_id: node id + :param int interface_id: interface id + :return: EMANE model id + :rtype: int + """ if interface_id >= 0: return node_id * 1000 + interface_id else: @@ -88,6 +113,14 @@ def get_emane_model_id(node_id, interface_id): def convert_link(session, link_data): + """ + Convert link_data into core protobuf Link + + :param core.emulator.session.Session session: + :param core.emulator.data.LinkData link_data: + :return: core protobuf Link + :rtype: core.api.grpc.core_pb2.Link + """ interface_one = None if link_data.interface1_id is not None: node = session.get_node(link_data.node1_id) @@ -146,6 +179,7 @@ def convert_link(session, link_data): ) +# TODO add comments def get_net_stats(): with open("/proc/net/dev", "r") as f: data = f.readlines()[2:] @@ -162,7 +196,14 @@ def get_net_stats(): return stats +# TODO add comment class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): + """ + Create CoreGrpcServer instance + + :param core.emulator.coreemu.CoreEmu coreemu: coreemu object + """ + def __init__(self, coreemu): super(CoreGrpcServer, self).__init__() self.coreemu = coreemu @@ -194,6 +235,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): self.server.stop(None) def get_session(self, session_id, context): + """ + Retrieve session given the session id + + :param int session_id: session id + :param grpc.ServicerContext context: + :return: session object that satisfies. If session not found then raise an exception. + :rtype: core.emulator.session.Session + """ session = self.coreemu.sessions.get(session_id) if not session: context.abort( @@ -202,6 +251,15 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return session def get_node(self, session, node_id, context): + """ + Retrieve node given session and node id + + :param core.emulator.session.Session session: session that contains the node + :param int node_id: node id + :param grpc.ServicerContext context: + :return: node object that satisfies. If node not found then raise an exception. + :rtype: core.nodes.base.CoreNode + """ try: return session.get_node(node_id) except KeyError: @@ -210,6 +268,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): ) def CreateSession(self, request, context): + """ + Create a session + + :param core.api.grpc.core_pb2.CreateSessionRequest request: create-session request + :param grpc.ServicerContext context: + :return: a create-session response + :rtype: core.api.grpc.core_pb2.CreateSessionResponse + """ logging.debug("create session: %s", request) session = self.coreemu.create_session(request.session_id) session.set_state(EventTypes.DEFINITION_STATE) @@ -220,11 +286,27 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): ) def DeleteSession(self, request, context): + """ + Delete the session + + :param core.api.grpc.core_pb2.DeleteSessionRequest request: delete-session request + :param grpc.ServicerContext context: context object + :return: a delete-session response + :rtype: core.api.grpc.core_pb2.DeleteSessionResponse + """ logging.debug("delete session: %s", request) result = self.coreemu.delete_session(request.session_id) return core_pb2.DeleteSessionResponse(result=result) def GetSessions(self, request, context): + """ + Delete the session + + :param core.api.grpc.core_pb2.GetSessionRequest request: get-session request + :param grpc.ServicerContext context: context object + :return: a delete-session response + :rtype: core.api.grpc.core_pb2.DeleteSessionResponse + """ logging.debug("get sessions: %s", request) sessions = [] for session_id in self.coreemu.sessions: @@ -236,6 +318,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.GetSessionsResponse(sessions=sessions) def GetSessionLocation(self, request, context): + """ + Retrieve a requested session location + + :param core.api.grpc.core_pb2.GetSessionLocationRequest request: get-session-location request + :param grpc.ServicerContext context: context object + :return: a get-session-location response + :rtype: core.api.grpc.core_pb2.GetSessionLocationResponse + """ logging.debug("get session location: %s", request) session = self.get_session(request.session_id, context) x, y, z = session.location.refxyz @@ -246,6 +336,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): ) def SetSessionLocation(self, request, context): + """ + Set session location + + :param core.api.grpc.core_pb2.SetSessionLocationRequest request: set-session-location request + :param grpc.ServicerContext context: context object + :return: a set-session-location-response + :rtype: core.api.grpc.core_pb2.SetSessionLocationResponse + """ logging.debug("set session location: %s", request) session = self.get_session(request.session_id, context) session.location.refxyz = ( @@ -260,6 +358,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.SetSessionLocationResponse(result=True) def SetSessionState(self, request, context): + """ + Set session state + + :param core.api.grpc.core_pb2.SetSessionStateRequest request: set-session-state request + :param grpc.ServicerContext context:context object + :return: set-session-state response + :rtype: core.api.grpc.core_pb2.SetSessionStateResponse + """ logging.debug("set session state: %s", request) session = self.get_session(request.session_id, context) @@ -284,6 +390,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.SetSessionStateResponse(result=result) + # TODO add comments def GetSessionOptions(self, request, context): logging.debug("get session options: %s", request) session = self.get_session(request.session_id, context) @@ -293,6 +400,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): groups = get_config_groups(defaults, session.options) return core_pb2.GetSessionOptionsResponse(groups=groups) + # TODO add comments def SetSessionOptions(self, request, context): logging.debug("set session options: %s", request) session = self.get_session(request.session_id, context) @@ -301,6 +409,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.SetSessionOptionsResponse(result=True) def GetSession(self, request, context): + """ + Retrieve requested session + + :param core.api.grpc.core_pb2.GetSessionRequest request: get-session request + :param grpc.ServicerContext context: context object + :return: get-session response + :rtype: core.api.grpc.core_bp2.GetSessionResponse + """ logging.debug("get session: %s", request) session = self.get_session(request.session_id, context) @@ -345,6 +461,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): session_proto = core_pb2.Session(state=session.state, nodes=nodes, links=links) return core_pb2.GetSessionResponse(session=session_proto) + # TODO add comments def Events(self, request, context): session = self.get_session(request.session_id, context) queue = Queue() @@ -389,7 +506,15 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): session.event_handlers.remove(queue.put) self._cancel_stream(context) + # TODO add comment def _handle_node_event(self, event): + """ + Handle node event when there is a node event + + :param event: an event in the event queue + :return: node event that contains node id, name, model, position, and services + :rtype: core.api.grpc.core_pb2.Node Event + """ position = core_pb2.Position(x=event.x_position, y=event.y_position) services = event.services or "" services = services.split("|") @@ -402,7 +527,15 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): ) return core_pb2.NodeEvent(node=node_proto) + # TODO add comments def _handle_link_event(self, event): + """ + Handle link event when there is a link event + + :param event: an event from the event queue + :return: link event that has message type and link information + :rtype: core.api.grpc.core_pb2.LinkEvent + """ interface_one = None if event.interface1_id is not None: interface_one = core_pb2.Interface( @@ -450,7 +583,15 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): ) return core_pb2.LinkEvent(message_type=event.message_type, link=link) + # TODO add comments def _handle_session_event(self, event): + """ + Handle session event when there is a session event + + :param event: + :return: session event + :rtype: core.api.grpc.core_pb2.SessionEvent + """ event_time = event.time if event_time is not None: event_time = float(event_time) @@ -463,7 +604,15 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): session_id=event.session, ) + # TODO add comments def _handle_config_event(self, event): + """ + Handle configuration event when there is configuration event + + :param event: + :return: configuration event + :rtype: core.api.grpc.core_pb2.ConfigEvent + """ session_id = None if event.session is not None: session_id = int(event.session) @@ -484,7 +633,12 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): data_types=event.data_types, ) + # TODO add comments def _handle_exception_event(self, event): + """ + :param event: + :return: + """ return core_pb2.ExceptionEvent( node_id=event.node, session_id=int(event.session), @@ -495,6 +649,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): opaque=event.opaque, ) + # TODO add comments def _handle_file_event(self, event): return core_pb2.FileEvent( message_type=event.message_type, @@ -509,6 +664,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): compressed_data=event.compressed_data, ) + # TODO add comments def Throughputs(self, request, context): delay = 3 last_check = None @@ -561,6 +717,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): time.sleep(delay) def AddNode(self, request, context): + """ + Add node to requested session + + :param core.api.grpc.core_pb2.AddNodeRequest request: add-node request + :param grpc.ServicerContext context: context object + :return: add-node response + :rtype: core.api.grpc.core_pb2.AddNodeResponse + """ logging.debug("add node: %s", request) session = self.get_session(request.session_id, context) @@ -590,6 +754,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.AddNodeResponse(node_id=node.id) def GetNode(self, request, context): + """ + Retrieve node + + :param core.api.grpc.core_pb2.GetNodeRequest request: get-node request + :param grpc.ServicerContext context: context object + :return: get-node response + :rtype: core.api.grpc.core_pb2.GetNodeResponse + """ logging.debug("get node: %s", request) session = self.get_session(request.session_id, context) node = self.get_node(session, request.node_id, context) @@ -634,6 +806,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.GetNodeResponse(node=node_proto, interfaces=interfaces) def EditNode(self, request, context): + """ + Edit node + + :param core.api.grpc.core_bp2.EditNodeRequest request: edit-node request + :param grpc.ServicerContext context: context object + :return: edit-node response + :rtype: core.api.grpc.core_pb2.EditNodeResponse + """ logging.debug("edit node: %s", request) session = self.get_session(request.session_id, context) node_id = request.node_id @@ -653,12 +833,26 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.EditNodeResponse(result=result) def DeleteNode(self, request, context): + """ + Delete node + + :param core.api.grpc.core_pb2.DeleteNodeRequest request: delete-node request + :param grpc.ServicerContext context: context object + :return: core.api.grpc.core_pb2.DeleteNodeResponse + """ logging.debug("delete node: %s", request) session = self.get_session(request.session_id, context) result = session.delete_node(request.node_id) return core_pb2.DeleteNodeResponse(result=result) def NodeCommand(self, request, context): + """ + Run command on a node + + :param core.api.grpc.core_pb2.NodeCommandRequest request: node-command request + :param grpc.ServicerContext context: context object + :return: core.api.grpc.core_pb2.NodeCommandResponse + """ logging.debug("sending node command: %s", request) session = self.get_session(request.session_id, context) node = self.get_node(session, request.node_id, context) @@ -666,6 +860,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.NodeCommandResponse(output=output) def GetNodeTerminal(self, request, context): + """ + Retrieve terminal command string of a node + + :param core.api.grpc.core_pb2.GetNodeTerminalRequest request: get-node-terminal request + :param grpc.ServicerContext context: context object + :return: get-node-terminal response + :rtype: core.api.grpc.core_bp2.GetNodeTerminalResponse + """ logging.debug("getting node terminal: %s", request) session = self.get_session(request.session_id, context) node = self.get_node(session, request.node_id, context) @@ -673,6 +875,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.GetNodeTerminalResponse(terminal=terminal) def GetNodeLinks(self, request, context): + """ + Retrieve all links form a requested node + + :param core.api.grpc.core_pb2.GetNodeLinksRequest request: get-node-links request + :param grpc.ServicerContext context: context object + :return: get-node-links response + :rtype: core.api.grpc.core_pb2.GetNodeLinksResponse + """ logging.debug("get node links: %s", request) session = self.get_session(request.session_id, context) node = self.get_node(session, request.node_id, context) @@ -680,6 +890,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.GetNodeLinksResponse(links=links) def AddLink(self, request, context): + """ + Add link to a session + + :param core.api.grpc.core_pb2.AddLinkRequest request: add-link request + :param grpc.ServicerContext context: context object + :return: add-link response + :rtype: core.api.grpc.AddLinkResponse + """ logging.debug("add link: %s", request) session = self.get_session(request.session_id, context) @@ -761,6 +979,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.AddLinkResponse(result=True) def EditLink(self, request, context): + """ + Edit a link + + :param core.api.grpc.core_pb2.EditLinkRequest request: edit-link request + :param grpc.ServicerContext context: context object + :return: edit-link response + :rtype: core.api.grpc.core_pb2.EditLinkResponse + """ logging.debug("edit link: %s", request) session = self.get_session(request.session_id, context) node_one_id = request.node_one_id @@ -786,6 +1012,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.EditLinkResponse(result=True) def DeleteLink(self, request, context): + """ + Delete a link + + :param core.api.grpc.core_pb2.DeleteLinkRequest request: delete-link request + :param grpc.ServicerContext context: context object + :return: delete-link response + :rtype: core.api.grpc.core_pb2.DeleteLinkResponse + """ logging.debug("delete link: %s", request) session = self.get_session(request.session_id, context) node_one_id = request.node_one_id @@ -809,6 +1043,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.GetHooksResponse(hooks=hooks) def AddHook(self, request, context): + """ + Add hook to a session + + :param core.api.grpc.core_pb2.AddHookRequest request: add-hook request + :param grpc.ServicerContext context: context object + :return: add-hook response + :rtype: core.api.grpc.core_pb2.AddHookResponse + """ logging.debug("add hook: %s", request) session = self.get_session(request.session_id, context) hook = request.hook @@ -816,6 +1058,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.AddHookResponse(result=True) def GetMobilityConfigs(self, request, context): + """ + Retrieve all mobility configurations from a session + + :param core.api.grpc.core_pb2.GetMobilityConfigsRequest request: get-mobility-configurations request + :param grpc.ServicerContext context: context object + :return: get-mobility-configurations response that has a list of configurations + :rtype: core.api.grpc.core_pb2.GetMobilityConfigsResponse + """ logging.debug("get mobility configs: %s", request) session = self.get_session(request.session_id, context) response = core_pb2.GetMobilityConfigsResponse() @@ -832,6 +1082,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return response def GetMobilityConfig(self, request, context): + """ + Retrieve mobility configuration of a node + + :param core.api.grpc.core_pb2.GetMobilityConfigRequest request: get-mobility-configuration request + :param grpc.ServicerContext context: context object + :return: get-mobility-configuration response + :rtype: core.api.grpc.core_pb2.GetMobilityConfigResponse + """ logging.debug("get mobility config: %s", request) session = self.get_session(request.session_id, context) config = session.mobility.get_model_config( @@ -841,6 +1099,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.GetMobilityConfigResponse(groups=groups) def SetMobilityConfig(self, request, context): + """ + Set mobility configuration of a node + + :param core.api.grpc.core_pb2.SetMobilityConfigRequest request: set-mobility-configuration request + :param grpc.ServicerContext context: context object + :return: set-mobility-configuration response + "rtype" core.api.grpc.SetMobilityConfigResponse + """ logging.debug("set mobility config: %s", request) session = self.get_session(request.session_id, context) session.mobility.set_model_config( @@ -849,6 +1115,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.SetMobilityConfigResponse(result=True) def MobilityAction(self, request, context): + """ + Take mobility action whether to start, pause, stop or none of those + + :param core.api.grpc.core_pb2.MobilityActionRequest request: mobility-action request + :param grpc.ServicerContext context: context object + :return: mobility-action response + :rtype: core.api.grpc.core_pb2.MobilityActionResponse + """ logging.debug("mobility action: %s", request) session = self.get_session(request.session_id, context) node = self.get_node(session, request.node_id, context) @@ -864,6 +1138,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.MobilityActionResponse(result=result) def GetServices(self, request, context): + """ + Retrieve all the services that are running + + :param core.api.grpc.core_pb2.GetServicesRequest request: get-service request + :param grpc.ServicerContext context: context object + :return: get-services response + :rtype: core.api.grpc.core_pb2.GetServicesResponse + """ logging.debug("get services: %s", request) services = [] for name in ServiceManager.services: @@ -873,6 +1155,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.GetServicesResponse(services=services) def GetServiceDefaults(self, request, context): + """ + Retrieve all the default services of all node types in a session + + :param core.api.grpc.core_pb2.GetServiceDefaultsRequest request: get-default-service request + :param grpc.ServicerContext context: context object + :return: get-service-defaults response about all the available default services + :rtype: core.api.grpc.core_pb2.GetServiceDefaultsResponse + """ logging.debug("get service defaults: %s", request) session = self.get_session(request.session_id, context) all_service_defaults = [] @@ -884,6 +1174,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): all_service_defaults.append(service_defaults) return core_pb2.GetServiceDefaultsResponse(defaults=all_service_defaults) + # TODO add comments def SetServiceDefaults(self, request, context): logging.debug("set service defaults: %s", request) session = self.get_session(request.session_id, context) @@ -895,6 +1186,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.SetServiceDefaultsResponse(result=True) def GetNodeService(self, request, context): + """ + Retrieve a requested service from a node + + :param core.api.grpc.core_pb2.GetNodeServiceRequest request: get-node-service request + :param grpc.ServicerContext context: context object + :return: get-node-service response about the requested service + :rtype: core.api.grpc.core_pb2.GetNodeServiceResponse + """ logging.debug("get node service: %s", request) session = self.get_session(request.session_id, context) service = session.services.get_service( @@ -915,6 +1214,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.GetNodeServiceResponse(service=service_proto) def GetNodeServiceFile(self, request, context): + """ + Retrieve a requested service file from a node + + :param core.api.grpc.core_pb2.GetNodeServiceFileRequest request: get-node-service request + :param grpc.ServicerContext context: context object + :return: get-node-service response about the requested service + :rtype: core.api.grpc.core_pb2.GetNodeServiceFileResponse + """ logging.debug("get node service file: %s", request) session = self.get_session(request.session_id, context) node = self.get_node(session, request.node_id, context) @@ -931,6 +1238,15 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.GetNodeServiceFileResponse(data=file_data.data) def SetNodeService(self, request, context): + """ + Set a node service for a node + + :param core.api.grpc.core_pb2.SetNodeServiceRequest request: set-node-service request + that has info to set a node service + :param grpc.ServicerContext context: context object + :return: set-node-service response + :rtype: core.api.grpc.core_pb2.SetNodeServiceResponse + """ logging.debug("set node service: %s", request) session = self.get_session(request.session_id, context) session.services.set_service(request.node_id, request.service) @@ -941,6 +1257,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.SetNodeServiceResponse(result=True) def SetNodeServiceFile(self, request, context): + """ + Store the customized service file in the service config + + :param core.api.grpc.core_pb2.SetNodeServiceFileRequest request: set-node-service-file request + :param grpc.ServicerContext context: context object + :return: set-node-service-file response + :rtype: core.api.grpc.core_pb2.SetNodeServiceFileResponse + """ logging.debug("set node service file: %s", request) session = self.get_session(request.session_id, context) session.services.set_service_file( @@ -949,6 +1273,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.SetNodeServiceFileResponse(result=True) def ServiceAction(self, request, context): + """ + Take action whether to start, stop, restart, validate the service or none of the above + + :param core.api.grpc.core_pb2.ServiceActionRequest request: service-action request + :param grpcServicerContext context: context object + :return: service-action response about status of action + :rtype: core.api.grpc.core_pb2.ServiceActionResponse + """ logging.debug("service action: %s", request) session = self.get_session(request.session_id, context) node = self.get_node(session, request.node_id, context) @@ -980,6 +1312,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.ServiceActionResponse(result=result) def GetWlanConfig(self, request, context): + """ + Retrieve wireless-lan configuration of a node + + :param core.api.grpc.core_pb2.GetWlanConfigRequest request: get-wlan-configuration request + :param context: core.api.grpc.core_pb2.GetWlanConfigResponse + :return: get-wlan-configuration response about the wlan configuration of a node + :rtype: core.api.grpc.core_pb2.GetWlanConfigResponse + """ logging.debug("get wlan config: %s", request) session = self.get_session(request.session_id, context) config = session.mobility.get_model_config( @@ -989,6 +1329,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.GetWlanConfigResponse(groups=groups) def SetWlanConfig(self, request, context): + """ + Set configuration data for a model + + :param core.api.grpc.core_pb2.SetWlanConfigRequest request: set-wlan-configuration request + :param grpc.ServicerContext context: context object + :return: set-wlan-configuration response + :rtype: core.api.grpc.core_pb2.SetWlanConfigResponse + """ logging.debug("set wlan config: %s", request) session = self.get_session(request.session_id, context) session.mobility.set_model_config( @@ -1000,6 +1348,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.SetWlanConfigResponse(result=True) def GetEmaneConfig(self, request, context): + """ + Retrieve EMANE configuration of a session + + :param core.api.grpc.core_pb2.GetEmanConfigRequest request: get-EMANE-configuration request + :param grpc.ServicerContext context: context object + :return: get-EMANE-configuration response + :rtype: core.api.grpc.core_pb2.GetEmaneConfigResponse + """ logging.debug("get emane config: %s", request) session = self.get_session(request.session_id, context) config = session.emane.get_configs() @@ -1007,13 +1363,29 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.GetEmaneConfigResponse(groups=groups) def SetEmaneConfig(self, request, context): + """ + Set EMANE configuration of a session + + :param core.api.grpc.core_pb2.SetEmaneConfigRequest request: set-EMANE-configuration request + :param grpc.ServicerContext context: context object + :return: set-EMANE-configuration response + :rtype: core.api.grpc.core_pb2.SetEmaneConfigResponse + """ logging.debug("set emane config: %s", request) session = self.get_session(request.session_id, context) config = session.emane.get_configs() config.update(request.config) return core_pb2.SetEmaneConfigResponse(result=True) + # TODO add comment def GetEmaneModels(self, request, context): + """ + Retrieve all the EMANE models in the session + + :param request: + :param context: + :return: + """ logging.debug("get emane models: %s", request) session = self.get_session(request.session_id, context) models = [] @@ -1058,6 +1430,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return response def SaveXml(self, request, context): + """ + Export the session nto the EmulationScript XML format + + :param core.api.grpc.core_pb2.SaveXmlRequest request: save xml request + :param grpc SrvicerContext context: context object + :return: save-xml response + :rtype: core.api.grpc.core_pb2.SaveXmlResponse + """ logging.debug("save xml: %s", request) session = self.get_session(request.session_id, context) @@ -1070,6 +1450,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.SaveXmlResponse(data=data) def OpenXml(self, request, context): + """ + Import a session from the EmulationScript XML format + + :param core.api.grpc.OpenXmlRequest request: open-xml request + :param grpc.ServicerContext context: context object + :return: Open-XML response or raise an exception if invalid XML file + :rtype: core.api.grpc.core_pb2.OpenXMLResponse + """ logging.debug("open xml: %s", request) session = self.coreemu.create_session() session.set_state(EventTypes.CONFIGURATION_STATE) @@ -1086,6 +1474,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): self.coreemu.delete_session(session.id) context.abort(grpc.StatusCode.INVALID_ARGUMENT, "invalid xml file") + # TODO add comment def GetInterfaces(self, request, context): interfaces = [] for interface in os.listdir("/sys/class/net"): diff --git a/daemon/core/config.py b/daemon/core/config.py index 66b4bde6..f63ad59a 100644 --- a/daemon/core/config.py +++ b/daemon/core/config.py @@ -351,7 +351,7 @@ class ModelManager(ConfigurableManager): def get_model_config(self, node_id, model_name): """ - Set configuration data for a model. + Retrieve configuration data for a model. :param int node_id: node id to set model configuration for :param str model_name: model to set configuration for diff --git a/daemon/core/nodes/base.py b/daemon/core/nodes/base.py index 7e9c741f..821c65e2 100644 --- a/daemon/core/nodes/base.py +++ b/daemon/core/nodes/base.py @@ -210,7 +210,7 @@ class NodeBase(object): :param flags: message flags :return: list of link data - :rtype: core.data.LinkData + :rtype: [core.data.LinkData] """ return [] @@ -1109,6 +1109,11 @@ class CoreNetworkBase(NodeBase): """ Build link data objects for this network. Each link object describes a link between this network and a node. + + :param int flags: message type + :return: list of link data + :rtype: [core.data.LinkData] + """ all_links = [] diff --git a/docs/performance.md b/docs/performance.md index b057dd23..6688815a 100644 --- a/docs/performance.md +++ b/docs/performance.md @@ -7,11 +7,13 @@ 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. +||| +|---|---| +| 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. diff --git a/docs/services.md b/docs/services.md index 15037ac2..44eeb63f 100644 --- a/docs/services.md +++ b/docs/services.md @@ -24,17 +24,13 @@ shutdown commands, and meta-data associated with a node. Here are the default node types and their services: -* *router* - zebra, OSFPv2, OSPFv3, and IPForward services for IGP - link-state routing. -* *host* - DefaultRoute and SSH services, representing an SSH server having a - default route when connected directly to a router. -* *PC* - DefaultRoute service for having a default route when connected - directly to a router. -* *mdr* - zebra, OSPFv3MDR, and IPForward services for - wireless-optimized MANET Designated Router routing. -* *prouter* - a physical router, having the same default services as the - *router* node type; for incorporating Linux testbed machines into an - emulation. +||| +|---|---| +| *router* | zebra, OSFPv2, OSPFv3, and IPForward services for IGP link-state routing. | +| *host* | DefaultRoute and SSH services, representing an SSH server having a default route when connected directly to a router. | +| *PC* | DefaultRoute service for having a default route when connected directly to a router. | +| *mdr* | zebra, OSPFv3MDR, and IPForward services for wireless-optimized MANET Designated Router routing. | +| *prouter* | a physical router, having the same default services as the *router* node type; for incorporating Linux testbed machines into an emulation. | Configuration files can be automatically generated by each service. For example, CORE automatically generates routing protocol configuration for the diff --git a/docs/usage.md b/docs/usage.md index 4f54daf3..cef142ac 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -72,24 +72,34 @@ When CORE is in Edit mode (the default), the vertical Editing Toolbar exists on * ![alt text](../gui/icons/tiny/select.gif) *Selection Tool* - default tool for selecting, moving, configuring nodes * ![alt text](../gui/icons/tiny/start.gif) *Start button* - starts Execute mode, instantiates the emulation * ![alt text](../gui/icons/tiny/link.gif) *Link* - the Link Tool allows network links to be drawn between two nodes by clicking and dragging the mouse -* ![alt text](../gui/icons/tiny/router.gif) *Network-layer virtual nodes* - * ![alt text](../gui/icons/tiny/router.gif) *Router* - runs Quagga OSPFv2 and OSPFv3 routing to forward packets - * ![alt text](../gui/icons/tiny/host.gif) *Host* - emulated server machine having a default route, runs SSH server - * ![alt text](../gui/icons/tiny/pc.gif) *PC* - basic emulated machine having a default route, runs no processes by default - * ![alt text](../gui/icons/tiny/mdr.gif) *MDR* - runs Quagga OSPFv3 MDR routing for MANET-optimized routing - * ![alt text](../gui/icons/tiny/router_green.gif) *PRouter* - physical router represents a real testbed machine - * ![alt text](../gui/icons/tiny/document-properties.gif) *Edit* - edit node types button invokes the CORE Node Types dialog. New types of nodes may be created having different icons and names. The default services that are started with each node type can be changed here. -* ![alt text](../gui/icons/tiny/hub.gif) *Link-layer nodes* - * ![alt text](../gui/icons/tiny/hub.gif) *Hub* - the Ethernet hub forwards incoming packets to every connected node - * ![alt text](../gui/icons/tiny/lanswitch.gif) *Switch* - the Ethernet switch intelligently forwards incoming packets to attached hosts using an Ethernet address hash table - * ![alt text](../gui/icons/tiny/wlan.gif) *Wireless LAN* - when routers are connected to this WLAN node, they join a wireless network and an antenna is drawn instead of a connecting line; the WLAN node typically controls connectivity between attached wireless nodes based on the distance between them - * ![alt text](../gui/icons/tiny/rj45.gif) *RJ45* - with the RJ45 Physical Interface Tool, emulated nodes can be linked to real physical interfaces; using this tool, real networks and devices can be physically connected to the live-running emulation - * ![alt text](../gui/icons/tiny/tunnel.gif) *Tunnel* - the Tunnel Tool allows connecting together more than one CORE emulation using GRE tunnels +* ![alt text](../gui/icons/tiny/router.gif) *Network-layer virtual nodes consist of the following:* + +||| +|---|---| +| ![alt text](../gui/icons/tiny/router.gif) *Router* | runs Quagga OSPFv2 and OSPFv3 routing to forward packets. | +| ![alt text](../gui/icons/tiny/host.gif) *Host* | emulated server machine having a default route, runs SSH server. | +| ![alt text](../gui/icons/tiny/pc.gif) *PC* | basic emulated machine having a default route, runs no processes by default. | +| ![alt text](../gui/icons/tiny/mdr.gif) *MDR* | runs Quagga OSPFv3 MDR routing for MANET-optimized routing. | +| ![alt text](../gui/icons/tiny/router_green.gif) *PRouter* | physical router represents a real testbed machine. | +| ![alt text](../gui/icons/tiny/document-properties.gif) *Edit* | edit node types button invokes the CORE Node Types dialog. New types of nodes may be created having different icons and names. The default services that are started with each node type can be changed here. | +* ![alt text](../gui/icons/tiny/hub.gif) *Link-layer nodes consist of the following:* + +||| +|---|---| +| ![alt text](../gui/icons/tiny/hub.gif) *Hub* | the Ethernet hub forwards incoming packets to every connected node. | +| ![alt text](../gui/icons/tiny/lanswitch.gif) *Switch* | the Ethernet switch intelligently forwards incoming packets to attached hosts using an Ethernet address hash table. | +| ![alt text](../gui/icons/tiny/wlan.gif) *Wireless LAN* | when routers are connected to this WLAN node, they join a wireless network and an antenna is drawn instead of a connecting line; the WLAN node typically controls connectivity between attached wireless nodes based on the distance between them. | +| ![alt text](../gui/icons/tiny/rj45.gif) *RJ45* | with the RJ45 Physical Interface Tool, emulated nodes can be linked to real physical interfaces; using this tool, real networks and devices can be physically connected to the live-running emulation. | +| ![alt text](../gui/icons/tiny/tunnel.gif) *Tunnel* | the Tunnel Tool allows connecting together more than one CORE emulation using GRE tunnels. | + * *Annotation Tools* - * ![alt text](../gui/icons/tiny/marker.gif) *Marker* - for drawing marks on the canvas - * ![alt text](../gui/icons/tiny/oval.gif) *Oval* - for drawing circles on the canvas that appear in the background - * ![alt text](../gui/icons/tiny/rectangle.gif) *Rectangle* - for drawing rectangles on the canvas that appear in the background - * ![alt text](../gui/icons/tiny/text.gif) *Text* - for placing text captions on the canvas + +||| +|---|---| +| ![alt text](../gui/icons/tiny/marker.gif) *Marker* - for drawing marks on the canvas. | +| ![alt text](../gui/icons/tiny/oval.gif) *Oval* - for drawing circles on the canvas that appear in the background. | +| ![alt text](../gui/icons/tiny/rectangle.gif) *Rectangle* - for drawing rectangles on the canvas that appear in the background. | +| ![alt text](../gui/icons/tiny/text.gif) *Text* - for placing text captions on the canvas. | ### Execution Toolbar @@ -259,50 +269,26 @@ The Session Menu has entries for starting, stopping, and managing sessions, in addition to global options such as node types, comments, hooks, servers, and options. -* *Start* or *Stop* - this starts or stops the emulation, performing the same - function as the green Start or red Stop button. -* *Change sessions...* - invokes the CORE Sessions dialog box containing a list - of active CORE sessions in the daemon. Basic session information such as - name, node count, start time, and a thumbnail are displayed. This dialog - allows connecting to different sessions, shutting them down, or starting - a new session. -* *Node types...* - invokes the CORE Node Types dialog, performing the same - function as the Edit button on the Network-Layer Nodes toolbar. -* *Comments...* - invokes the CORE Session Comments window where optional - text comments may be specified. These comments are saved at the top of the - configuration file, and can be useful for describing the topology or how - to use the network. -* *Hooks...* - invokes the CORE Session Hooks window where scripts may be - configured for a particular session state. The top of the window has a list - of configured hooks, and buttons on the bottom left allow adding, editing, - and removing hook scripts. The new or edit button will open a hook script - editing window. A hook script is a shell script invoked on the host (not - within a virtual node). - * *definition* - used by the GUI to tell the backend to clear any state. - * *configuration* - when the user presses the *Start* button, node, link, and - other configuration data is sent to the backend. This state is also - reached when the user customizes a service. - * *instantiation* - after configuration data has been sent, just before the nodes are created. - * *runtime* - all nodes and networks have been - built and are running. (This is the same state at which - the previously-named *global experiment script* was run.) - * *datacollect* - the user has pressed the - *Stop* button, but before services have been stopped and nodes have been - shut down. This is a good time to collect log files and other data from the - nodes. - * *shutdown* - all nodes and networks have been shut down and destroyed. -* *Reset node positions* - if you have moved nodes around - using the mouse or by using a mobility module, choosing this item will reset - all nodes to their original position on the canvas. The node locations are - remembered when you first press the Start button. -* *Emulation servers...* - invokes the CORE emulation - servers dialog for configuring. -* *Change Sessions...* - invokes the Sessions dialog for switching between different - running sessions. This dialog is presented during startup when one or - more sessions are already running. -* *Options...* - presents per-session options, such as the IPv4 prefix to be - used, if any, for a control network the ability to preserve - the session directory; and an on/off switch for SDT3D support. +||| +|---|---| +| *Start* or *Stop* | this starts or stops the emulation, performing the same function as the green Start or red Stop button. | +| *Change sessions...* | invokes the CORE Sessions dialog box containing a list of active CORE sessions in the daemon. Basic session information such as name, node count, start time, and a thumbnail are displayed. This dialog allows connecting to different sessions, shutting them down, or starting a new session. | +| *Node types...* | invokes the CORE Node Types dialog, performing the same function as the Edit button on the Network-Layer Nodes toolbar. | +| *Comments...* | invokes the CORE Session Comments window where optional text comments may be specified. These comments are saved at the top of the configuration file, and can be useful for describing the topology or how to use the network. | +| *Hooks...* | invokes the CORE Session Hooks window where scripts may be configured for a particular session state. The session states are defined in the table right below. The top of the window has a list of configured hooks, and buttons on the bottom left allow adding, editing, and removing hook scripts. The new or edit button will open a hook script editing window. A hook script is a shell script invoked on the host (not within a virtual node). | +| *Reset node positions* | if you have moved nodes around using the mouse or by using a mobility module, choosing this item will reset all nodes to their original position on the canvas. The node locations are remembered when you first press the Start button. | +| *Emulation servers...* | invokes the CORE emulation servers dialog for configuring. | +| *Change Sessions...* | invokes the Sessions dialog for switching between different running sessions. This dialog is presented during startup when one or more sessions are already running. | +| *Options...* | presents per-session options, such as the IPv4 prefix to be used, if any, for a control network the ability to preserve the session directory; and an on/off switch for SDT3D support. | + +| |Session states| +|---|---| +| *definition* | used by the GUI to tell the backend to clear any state. | +| *configuration* | when the user presses the *Start* button, node, link, and other configuration data is sent to the backend. This state is also reached when the user customizes a service. | +| *instantiation* | after configuration data has been sent, just before the nodes are created. | +| *runtime* | all nodes and networks have been built and are running. (This is the same state at which the previously-named *global experiment script* was run.) +| *datacollect* | the user has pressed the *Stop* button, but before services have been stopped and nodes have been shut down. This is a good time to collect log files and other data from the nodes. | +| *shutdown* | all nodes and networks have been shut down and destroyed. | ### Help Menu From edcb3d3472970c8ae0810d731e84a7b11b4a96b5 Mon Sep 17 00:00:00 2001 From: Huy Pham Date: Fri, 13 Sep 2019 16:21:07 -0700 Subject: [PATCH 04/16] updates on python comments 4:20pm friday --- daemon/core/api/grpc/server.py | 114 +++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 28 deletions(-) diff --git a/daemon/core/api/grpc/server.py b/daemon/core/api/grpc/server.py index 23140a97..1d997899 100644 --- a/daemon/core/api/grpc/server.py +++ b/daemon/core/api/grpc/server.py @@ -47,14 +47,14 @@ def convert_value(value): return value -# TODO add comments def get_config_groups(config, configurable_options): """ - ??? + Retrieve configuration groups in a form that is used by the grpc server :param core.config.Configuration config: configuration :param core.config.ConfigurableOptions configurable_options: configurable options - :return: + :return: list of configuration groups + :rtype: [core.api.grpc.core_pb2.ConfigGroup] """ groups = [] config_options = [] @@ -81,14 +81,13 @@ def get_config_groups(config, configurable_options): return groups -# TODO add comments def get_links(session, node): """ - Get + Retrieve a list of links for grpc to use :param core.emulator.Session session: node's section :param core.nodes.base.CoreNode node: node to get links from - :return: + :return: [core.api.grpc.core_pb2.Link] """ links = [] for link_data in node.all_link_data(0): @@ -179,8 +178,13 @@ def convert_link(session, link_data): ) -# TODO add comments def get_net_stats(): + """ + Retrieve status about the current interfaces in the system + + :return: send and receive status of the interfaces in the system + :rtype: dict + """ with open("/proc/net/dev", "r") as f: data = f.readlines()[2:] @@ -196,7 +200,6 @@ def get_net_stats(): return stats -# TODO add comment class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): """ Create CoreGrpcServer instance @@ -506,14 +509,13 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): session.event_handlers.remove(queue.put) self._cancel_stream(context) - # TODO add comment def _handle_node_event(self, event): """ Handle node event when there is a node event - :param event: an event in the event queue + :param core.emulator.data.NodeData event: node data :return: node event that contains node id, name, model, position, and services - :rtype: core.api.grpc.core_pb2.Node Event + :rtype: core.api.grpc.core_pb2.NodeEvent """ position = core_pb2.Position(x=event.x_position, y=event.y_position) services = event.services or "" @@ -527,12 +529,11 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): ) return core_pb2.NodeEvent(node=node_proto) - # TODO add comments def _handle_link_event(self, event): """ Handle link event when there is a link event - :param event: an event from the event queue + :param core.emulator.data.LinkData event: link data :return: link event that has message type and link information :rtype: core.api.grpc.core_pb2.LinkEvent """ @@ -583,12 +584,11 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): ) return core_pb2.LinkEvent(message_type=event.message_type, link=link) - # TODO add comments def _handle_session_event(self, event): """ Handle session event when there is a session event - :param event: + :param core.emulator.data.EventData event: event data :return: session event :rtype: core.api.grpc.core_pb2.SessionEvent """ @@ -604,12 +604,11 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): session_id=event.session, ) - # TODO add comments def _handle_config_event(self, event): """ Handle configuration event when there is configuration event - :param event: + :param core.emulator.data.ConfigData event: configuration data :return: configuration event :rtype: core.api.grpc.core_pb2.ConfigEvent """ @@ -633,11 +632,13 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): data_types=event.data_types, ) - # TODO add comments def _handle_exception_event(self, event): """ - :param event: - :return: + Handle exception event when there is exception event + + :param core.emulator.data.ExceptionData event: exception data + :return: exception event + :rtype: core.api.grpc.core_pb2.ExceptionEvent """ return core_pb2.ExceptionEvent( node_id=event.node, @@ -649,8 +650,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): opaque=event.opaque, ) - # TODO add comments def _handle_file_event(self, event): + """ + Handle file event + + :param core.emulator.data.FileData event: file data + :return: file event + :rtype: core.api.grpc.core_pb2.FileEvent + """ return core_pb2.FileEvent( message_type=event.message_type, node_id=event.node, @@ -664,8 +671,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): compressed_data=event.compressed_data, ) - # TODO add comments def Throughputs(self, request, context): + """ + Calculate average throughput after every certain amount of delay time + + :param core.api.grpc.core_pb2.ThroughputsRequest request: throughputs request + :param grpc.SrevicerContext context: context object + :return: nothing + """ delay = 3 last_check = None last_stats = None @@ -1032,6 +1045,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.DeleteLinkResponse(result=True) def GetHooks(self, request, context): + """ + Retrieve all hooks from a session + + :param core.api.grpc.core_pb2.GetHooksRequest request: get-hook request + :param grpc.ServicerContext context: context object + :return: get-hooks response about all the hooks in all session states + :rtype: core.api.grpc.core_pb2.GetHooksResponse + """ logging.debug("get hooks: %s", request) session = self.get_session(request.session_id, context) hooks = [] @@ -1174,8 +1195,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): all_service_defaults.append(service_defaults) return core_pb2.GetServiceDefaultsResponse(defaults=all_service_defaults) - # TODO add comments def SetServiceDefaults(self, request, context): + """ + Set new default services to the session after whipping out the old ones + :param core.api.grpc.core_pb2.SetServiceDefaults request: set-service-defaults request + :param grpc.ServicerContext context: context object + :return: set-service-defaults response + :rtype: core.api.grpc.core_pb2 SetServiceDefaultsResponse + """ logging.debug("set service defaults: %s", request) session = self.get_session(request.session_id, context) session.services.default_services.clear() @@ -1377,14 +1404,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): config.update(request.config) return core_pb2.SetEmaneConfigResponse(result=True) - # TODO add comment def GetEmaneModels(self, request, context): """ Retrieve all the EMANE models in the session - :param request: - :param context: - :return: + :param core.api.grpc.core_pb2.GetEmaneModelRequest request: get-emane-model request + :param grpc.ServicerContext context: context object + :return: get-EMANE-models response that has all the models + :rtype: core.api.grpc.core_pb2.GetEmaneModelsResponse """ logging.debug("get emane models: %s", request) session = self.get_session(request.session_id, context) @@ -1396,6 +1423,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.GetEmaneModelsResponse(models=models) def GetEmaneModelConfig(self, request, context): + """ + Retrieve EMANE model configuration of a node + + :param core.api.grpc.core_pb2.GetEmaneModelConfigRequest request: get-EMANE-model-configuration request + :param grpc.ServicerContext context: context object + :return: get-EMANE-model-configuration response + :rtype: core.api.grpc.core_pb2.GetEmaneModelConfigResponse + """ logging.debug("get emane model config: %s", request) session = self.get_session(request.session_id, context) model = session.emane.models[request.model] @@ -1405,6 +1440,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.GetEmaneModelConfigResponse(groups=groups) def SetEmaneModelConfig(self, request, context): + """ + Set EMANE model configuration of a node + + :param core.api.grpc.core_pb2.SetEmaneModelConfigRequest request: set-EMANE-model-configuration request + :param grpc.ServicerContext context: context object + :return: set-EMANE-model-configuration response + :rtype: core.api.grpc.core_pb2.SetEmaneModelConfigResponse + """ logging.debug("set emane model config: %s", request) session = self.get_session(request.session_id, context) _id = get_emane_model_id(request.node_id, request.interface_id) @@ -1412,6 +1455,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.SetEmaneModelConfigResponse(result=True) def GetEmaneModelConfigs(self, request, context): + """ + Retrieve all EMANE model configurations of a session + + :param core.api.grpc.core_pb2.GetEmaneModelConfigsRequest request: get-EMANE-model-configurations request + :param grpc.ServicerContext context: context object + :return: get-EMANE-model-configurations response that has all the EMANE configurations + :rtype: core.api.grpc.core_pb2.GetEmaneModelConfigsResponse + """ logging.debug("get emane model configs: %s", request) session = self.get_session(request.session_id, context) response = core_pb2.GetEmaneModelConfigsResponse() @@ -1474,8 +1525,15 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): self.coreemu.delete_session(session.id) context.abort(grpc.StatusCode.INVALID_ARGUMENT, "invalid xml file") - # TODO add comment def GetInterfaces(self, request, context): + """ + Retrieve all the interfaces of the system including bridges, virtual ethernet, and loopback + + :param core.api.grpc.core_pb2.GetInterfacesRequest request: get-interfaces request + :param grpc.ServicerContext context: context object + :return: get-interfaces response that has all the system's interfaces + :rtype: core.api.grpc.core_pb2.GetInterfacesResponse + """ interfaces = [] for interface in os.listdir("/sys/class/net"): if ( From b333859d8600a5d6f09d2245da2d23dbb0a3e4fb Mon Sep 17 00:00:00 2001 From: Huy Pham Date: Mon, 16 Sep 2019 12:55:00 -0700 Subject: [PATCH 05/16] finish up server.py and fix 2 broken links --- daemon/core/api/grpc/server.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/daemon/core/api/grpc/server.py b/daemon/core/api/grpc/server.py index 1d997899..0a15f8f0 100644 --- a/daemon/core/api/grpc/server.py +++ b/daemon/core/api/grpc/server.py @@ -257,7 +257,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): """ Retrieve node given session and node id - :param core.emulator.session.Session session: session that contains the node + :param core.emulator.session.Session session: session that has the node :param int node_id: node id :param grpc.ServicerContext context: :return: node object that satisfies. If node not found then raise an exception. @@ -393,8 +393,15 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): return core_pb2.SetSessionStateResponse(result=result) - # TODO add comments def GetSessionOptions(self, request, context): + """ + Retrieve session options + + :param core.api.grpc.core_pb2.GetSessionOptions request: get-session-options request + :param grpc.ServicerContext context: context object + :return: get-session-options response about all session's options + :rtype: core.api.grpc.core_pb2.GetSessionOptions + """ logging.debug("get session options: %s", request) session = self.get_session(request.session_id, context) config = session.options.get_configs() @@ -403,8 +410,15 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): groups = get_config_groups(defaults, session.options) return core_pb2.GetSessionOptionsResponse(groups=groups) - # TODO add comments def SetSessionOptions(self, request, context): + """ + Update a session's configuration + + :param core.api.grpc.core_pb2.SetSessionOptions request: set-session-options request + :param grpc.ServicerContext context: context object + :return: set-session-options response + :rtype: core.api.grpc.core_pb2.SetSessionOptionsResponse + """ logging.debug("set session options: %s", request) session = self.get_session(request.session_id, context) config = session.options.get_configs() @@ -464,7 +478,6 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): session_proto = core_pb2.Session(state=session.state, nodes=nodes, links=links) return core_pb2.GetSessionResponse(session=session_proto) - # TODO add comments def Events(self, request, context): session = self.get_session(request.session_id, context) queue = Queue() From 7c1f1977746edfc3434c2d66da0931986d4f0686 Mon Sep 17 00:00:00 2001 From: Huy Pham Date: Mon, 16 Sep 2019 16:13:49 -0700 Subject: [PATCH 06/16] fix links --- docs/emane.md | 6 +++--- docs/services.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/emane.md b/docs/emane.md index c3a983b8..3162b808 100644 --- a/docs/emane.md +++ b/docs/emane.md @@ -9,8 +9,8 @@ The Extendable Mobile Ad-hoc Network Emulator (EMANE) allows heterogeneous netwo 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. @@ -68,7 +68,7 @@ sudo ln -s /usr/local/share/emane /usr/share/emane 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](/daemon/examples/myemane/examplemodel.py) +[Example Model](../daemon/examples/myemane/examplemodel.py) ## Single PC with EMANE diff --git a/docs/services.md b/docs/services.md index 44eeb63f..de742b8f 100644 --- a/docs/services.md +++ b/docs/services.md @@ -135,7 +135,7 @@ ideas for a service before adding a new service type. ### Creating New Service -1. Modify the [Example Service File](/daemon/examples/myservices/sample.py) +1. Modify the [Example Service File](../daemon/examples/myservices/sample.py) to do what you want. It could generate config/script files, mount per-node directories, start processes/scripts, etc. sample.py is a Python file that defines one or more classes to be imported. You can create multiple Python From 463d4d145e8f5ecf91607ea7812a63ffbfc0dbcf Mon Sep 17 00:00:00 2001 From: Huy Pham Date: Mon, 16 Sep 2019 16:55:41 -0700 Subject: [PATCH 07/16] test new table format on performance.md --- docs/performance.md | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/docs/performance.md b/docs/performance.md index 6688815a..9c325f00 100644 --- a/docs/performance.md +++ b/docs/performance.md @@ -7,13 +7,30 @@ 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. | + + + + + + + + + + + + + + + + + + + + + + + +
Hardwarethe 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 versiondistribution of Linux and the specific kernel versions used will affect overall performance.
Active processesall nodes share the same CPU resources, so if one or more nodes is performing a CPU-intensive task, overall performance will suffer.
Network trafficthe more packets that are sent around the virtual network increases the amount of CPU usage.
GUI usagewidgets 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. From 22189122e67ac5aa558b5084880b1dd8b9098220 Mon Sep 17 00:00:00 2001 From: Huy Pham Date: Tue, 17 Sep 2019 09:33:55 -0700 Subject: [PATCH 08/16] add text to markdown table headers, fix some return types, fix emane link --- daemon/core/nodes/base.py | 8 ++++---- docs/emane.md | 2 +- docs/performance.md | 32 ++++++++------------------------ docs/services.md | 2 +- docs/usage.md | 34 +++++++++++++++++----------------- 5 files changed, 31 insertions(+), 47 deletions(-) diff --git a/daemon/core/nodes/base.py b/daemon/core/nodes/base.py index 821c65e2..2f3d7b64 100644 --- a/daemon/core/nodes/base.py +++ b/daemon/core/nodes/base.py @@ -115,7 +115,7 @@ class NodeBase(object): :param bool sort: boolean used to determine if interfaces should be sorted :return: network interfaces - :rtype: list + :rtype: list[core.nodes.interfaces.CoreInterface] """ if sort: return [self._netif[x] for x in sorted(self._netif)] @@ -210,7 +210,7 @@ class NodeBase(object): :param flags: message flags :return: list of link data - :rtype: [core.data.LinkData] + :rtype: list[core.data.LinkData] """ return [] @@ -308,7 +308,7 @@ class CoreNodeBase(NodeBase): :param int ifindex: interface of index to attach :param core.nodes.interface.CoreInterface net: network to attach - :return: + :return: nothing """ if ifindex not in self._netif: raise ValueError("ifindex %s does not exist" % ifindex) @@ -1112,7 +1112,7 @@ class CoreNetworkBase(NodeBase): :param int flags: message type :return: list of link data - :rtype: [core.data.LinkData] + :rtype: list[core.data.LinkData] """ all_links = [] diff --git a/docs/emane.md b/docs/emane.md index 3162b808..d0e8b11a 100644 --- a/docs/emane.md +++ b/docs/emane.md @@ -9,7 +9,7 @@ The Extendable Mobile Ad-hoc Network Emulator (EMANE) allows heterogeneous netwo EMANE is developed by U.S. Naval Research Labs (NRL) Code 5522 and Adjacent Link LLC, who maintain these websites: -* +* * 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. diff --git a/docs/performance.md b/docs/performance.md index 9c325f00..d048eea1 100644 --- a/docs/performance.md +++ b/docs/performance.md @@ -7,30 +7,14 @@ The top question about the performance of CORE is often *how many nodes can it handle?* The answer depends on several factors: - - - - - - - - - - - - - - - - - - - - - - - -
Hardwarethe 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 versiondistribution of Linux and the specific kernel versions used will affect overall performance.
Active processesall nodes share the same CPU resources, so if one or more nodes is performing a CPU-intensive task, overall performance will suffer.
Network trafficthe more packets that are sent around the virtual network increases the amount of CPU usage.
GUI usagewidgets that run periodically, mobility scenarios, and other GUI interactions generally consume CPU cycles that may be needed for emulation.
+| Factor | How that factor might affect performance | +|---|---| +| 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. diff --git a/docs/services.md b/docs/services.md index de742b8f..ec38c462 100644 --- a/docs/services.md +++ b/docs/services.md @@ -24,7 +24,7 @@ shutdown commands, and meta-data associated with a node. Here are the default node types and their services: -||| +| Node type | Services | |---|---| | *router* | zebra, OSFPv2, OSPFv3, and IPForward services for IGP link-state routing. | | *host* | DefaultRoute and SSH services, representing an SSH server having a default route when connected directly to a router. | diff --git a/docs/usage.md b/docs/usage.md index cef142ac..c27d508e 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -74,7 +74,7 @@ When CORE is in Edit mode (the default), the vertical Editing Toolbar exists on * ![alt text](../gui/icons/tiny/link.gif) *Link* - the Link Tool allows network links to be drawn between two nodes by clicking and dragging the mouse * ![alt text](../gui/icons/tiny/router.gif) *Network-layer virtual nodes consist of the following:* -||| +| Network-layer node | Description | |---|---| | ![alt text](../gui/icons/tiny/router.gif) *Router* | runs Quagga OSPFv2 and OSPFv3 routing to forward packets. | | ![alt text](../gui/icons/tiny/host.gif) *Host* | emulated server machine having a default route, runs SSH server. | @@ -84,7 +84,7 @@ When CORE is in Edit mode (the default), the vertical Editing Toolbar exists on | ![alt text](../gui/icons/tiny/document-properties.gif) *Edit* | edit node types button invokes the CORE Node Types dialog. New types of nodes may be created having different icons and names. The default services that are started with each node type can be changed here. | * ![alt text](../gui/icons/tiny/hub.gif) *Link-layer nodes consist of the following:* -||| +| Link-layer node | Description | |---|---| | ![alt text](../gui/icons/tiny/hub.gif) *Hub* | the Ethernet hub forwards incoming packets to every connected node. | | ![alt text](../gui/icons/tiny/lanswitch.gif) *Switch* | the Ethernet switch intelligently forwards incoming packets to attached hosts using an Ethernet address hash table. | @@ -94,18 +94,18 @@ When CORE is in Edit mode (the default), the vertical Editing Toolbar exists on * *Annotation Tools* -||| +| Tool | Functionality | |---|---| -| ![alt text](../gui/icons/tiny/marker.gif) *Marker* - for drawing marks on the canvas. | -| ![alt text](../gui/icons/tiny/oval.gif) *Oval* - for drawing circles on the canvas that appear in the background. | -| ![alt text](../gui/icons/tiny/rectangle.gif) *Rectangle* - for drawing rectangles on the canvas that appear in the background. | -| ![alt text](../gui/icons/tiny/text.gif) *Text* - for placing text captions on the canvas. | +| ![alt text](../gui/icons/tiny/marker.gif) *Marker* | for drawing marks on the canvas. | +| ![alt text](../gui/icons/tiny/oval.gif) *Oval* | for drawing circles on the canvas that appear in the background. | +| ![alt text](../gui/icons/tiny/rectangle.gif) *Rectangle* | for drawing rectangles on the canvas that appear in the background. | +| ![alt text](../gui/icons/tiny/text.gif) *Text* | for placing text captions on the canvas. | ### Execution Toolbar When the Start button is pressed, CORE switches to Execute mode, and the Edit toolbar on the left of the CORE window is replaced with the Execution toolbar Below are the items on this toolbar, starting from the top. -||| +| Tool | Functionality | |---|---| | ![alt text](../gui/icons/tiny/select.gif) *Selection Tool* | in Execute mode, the Selection Tool can be used for moving nodes around the canvas, and double-clicking on a node will open a shell window for that node; right-clicking on a node invokes a pop-up menu of run-time options for that node. | | ![alt text](../gui/icons/tiny/stop.gif) *Stop button* | stops Execute mode, terminates the emulation, returns CORE to edit mode. | @@ -126,7 +126,7 @@ menu, by clicking the dashed line at the top. The File menu contains options for manipulating the **.imn** Configuration Files. Generally, these menu items should not be used in Execute mode. -||| +| Option | Functionality | |---|---| | *New* |this starts a new file with an empty canvas. | | *Open* | invokes the File Open dialog box for selecting a new **.imn** or XML file to open. You can change the default path used for this dialog in the Preferences Dialog. | @@ -144,7 +144,7 @@ Execute mode. ### Edit Menu -||| +| Option | Functionality | |---|---| | *Undo* | attempts to undo the last edit in edit mode. | | *Redo* | attempts to redo an edit that has been undone. | @@ -159,7 +159,7 @@ Execute mode. The canvas menu provides commands for adding, removing, changing, and switching to different editing canvases. -||| +| Option | Functionality | |---|---| | *New* | creates a new empty canvas at the right of all existing canvases. | | *Manage...* | invokes the *Manage Canvases* dialog box, where canvases may be renamed and reordered, and you can easily switch to one of the canvases by selecting it. | @@ -173,7 +173,7 @@ The canvas menu provides commands for adding, removing, changing, and switching The View menu features items for controlling what is displayed on the drawing canvas. -||| +| Option | Functionality | |---|---| | *Show* | opens a submenu of items that can be displayed or hidden, such as interface names, addresses, and labels. Use these options to help declutter the display. These options are generally saved in the topology files, so scenarios have a more consistent look when copied from one computer to another. | | *Show hidden nodes* | reveal nodes that have been hidden. Nodes are hidden by selecting one or more nodes, right-clicking one and choosing *hide*. | @@ -186,7 +186,7 @@ canvas. The tools menu lists different utility functions. -||| +| Option | Functionality | |---|---| | *Autorearrange all* |automatically arranges all nodes on the canvas. Nodes having a greater number of links are moved to the center. This mode can continue to run while placing nodes. To turn off this autorearrange mode, click on a blank area of the canvas with the select tool, or choose this menu option again. | | *Autorearrange selected* | automatically arranges the selected nodes on the canvas. | @@ -200,7 +200,7 @@ The tools menu lists different utility functions. | *Topology generator* | opens a submenu of topologies to generate. You can first select the type of node that the topology should consist of, or routers will be chosen by default. Nodes may be randomly placed, aligned in grids, or various other topology patterns. All of the supported patterns are listed in the table below. | | *Debugger...* | opens the CORE Debugger window for executing arbitrary Tcl/Tk commands. | -| |Different topology patterns| +| Pattern | Description | |---|---| | *Random* | nodes are randomly placed about the canvas, but are not linked together. This can be used in conjunction with a WLAN node to quickly create a wireless network. | | *Grid* | nodes are placed in horizontal rows starting in the upper-left corner, evenly spaced to the right; nodes are not linked to each other. | @@ -269,7 +269,7 @@ The Session Menu has entries for starting, stopping, and managing sessions, in addition to global options such as node types, comments, hooks, servers, and options. -||| +| Option | Functionality | |---|---| | *Start* or *Stop* | this starts or stops the emulation, performing the same function as the green Start or red Stop button. | | *Change sessions...* | invokes the CORE Sessions dialog box containing a list of active CORE sessions in the daemon. Basic session information such as name, node count, start time, and a thumbnail are displayed. This dialog allows connecting to different sessions, shutting them down, or starting a new session. | @@ -281,7 +281,7 @@ and options. | *Change Sessions...* | invokes the Sessions dialog for switching between different running sessions. This dialog is presented during startup when one or more sessions are already running. | | *Options...* | presents per-session options, such as the IPv4 prefix to be used, if any, for a control network the ability to preserve the session directory; and an on/off switch for SDT3D support. | -| |Session states| +| Session state | Description | |---|---| | *definition* | used by the GUI to tell the backend to clear any state. | | *configuration* | when the user presses the *Start* button, node, link, and other configuration data is sent to the backend. This state is also reached when the user customizes a service. | @@ -660,7 +660,7 @@ that CORE will create. In version 1.0, the XML file is also referred to as the Scenario Plan. The Scenario Plan will be logically made up of the following: -||| +| Plan | Description | |---|---| | **Network Plan** | describes nodes. hosts, interfaces, and the networks to which they belong. | | **Motion Plan** | describes position and motion patterns for nodes in an emulation. | From 51e8be223e9f087aef1817a37a8771a5d5119c0f Mon Sep 17 00:00:00 2001 From: Huy Pham Date: Tue, 17 Sep 2019 10:12:03 -0700 Subject: [PATCH 09/16] fix tables and add sub-headers --- docs/usage.md | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index c27d508e..7f8cf672 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -69,10 +69,12 @@ The toolbar is a row of buttons that runs vertically along the left side of the When CORE is in Edit mode (the default), the vertical Editing Toolbar exists on the left side of the CORE window. Below are brief descriptions for each toolbar item, starting from the top. Most of the tools are grouped into related sub-menus, which appear when you click on their group icon. -* ![alt text](../gui/icons/tiny/select.gif) *Selection Tool* - default tool for selecting, moving, configuring nodes -* ![alt text](../gui/icons/tiny/start.gif) *Start button* - starts Execute mode, instantiates the emulation -* ![alt text](../gui/icons/tiny/link.gif) *Link* - the Link Tool allows network links to be drawn between two nodes by clicking and dragging the mouse -* ![alt text](../gui/icons/tiny/router.gif) *Network-layer virtual nodes consist of the following:* +| Toolbar item | Functionality | +|---|---| +| ![alt text](../gui/icons/tiny/select.gif) *Selection Tool* | default tool for selecting, moving, configuring nodes. | +| ![alt text](../gui/icons/tiny/start.gif) *Start button* | starts Execute mode, instantiates the emulation. | +| ![alt text](../gui/icons/tiny/link.gif) *Link* | the Link Tool allows network links to be drawn between two nodes by clicking and dragging the mouse. | +### ![alt text](../gui/icons/tiny/router.gif) Network-layer virtual nodes | Network-layer node | Description | |---|---| @@ -82,7 +84,7 @@ When CORE is in Edit mode (the default), the vertical Editing Toolbar exists on | ![alt text](../gui/icons/tiny/mdr.gif) *MDR* | runs Quagga OSPFv3 MDR routing for MANET-optimized routing. | | ![alt text](../gui/icons/tiny/router_green.gif) *PRouter* | physical router represents a real testbed machine. | | ![alt text](../gui/icons/tiny/document-properties.gif) *Edit* | edit node types button invokes the CORE Node Types dialog. New types of nodes may be created having different icons and names. The default services that are started with each node type can be changed here. | -* ![alt text](../gui/icons/tiny/hub.gif) *Link-layer nodes consist of the following:* +### ![alt text](../gui/icons/tiny/hub.gif) Link-layer nodes | Link-layer node | Description | |---|---| @@ -92,7 +94,7 @@ When CORE is in Edit mode (the default), the vertical Editing Toolbar exists on | ![alt text](../gui/icons/tiny/rj45.gif) *RJ45* | with the RJ45 Physical Interface Tool, emulated nodes can be linked to real physical interfaces; using this tool, real networks and devices can be physically connected to the live-running emulation. | | ![alt text](../gui/icons/tiny/tunnel.gif) *Tunnel* | the Tunnel Tool allows connecting together more than one CORE emulation using GRE tunnels. | -* *Annotation Tools* +### Anotation Tools | Tool | Functionality | |---|---| @@ -547,14 +549,11 @@ See the [EMANE](emane.md) chapter for details on using EMANE. CORE has a few ways to script mobility. -* ns-2 script - the script specifies either absolute positions - or waypoints with a velocity. Locations are given with Cartesian coordinates. -* CORE API - an external entity can move nodes by sending CORE API Node - messages with updated X,Y coordinates; the **coresendmsg** utility - allows a shell script to generate these messages. -* EMANE events - see [EMANE](emane.md) for details on using EMANE scripts to move - nodes around. Location information is typically given as latitude, longitude, - and altitude. +| Option | Description | +|---|---| +| ns-2 script | the script specifies either absolute positions or waypoints with a velocity. Locations are given with Cartesian coordinates. | +| CORE API | an external entity can move nodes by sending CORE API Node messages with updated X,Y coordinates; the **coresendmsg** utility allows a shell script to generate these messages. | +| EMANE events | see [EMANE](emane.md) for details on using EMANE scripts to move nodes around. Location information is typically given as latitude, longitude, and altitude. | For the first method, you can create a mobility script using a text editor, or using a tool such as [BonnMotion](http://net.cs.uni-bonn.de/wg/cs/applications/bonnmotion/), and associate the script with one of the wireless From 976f06dc1000cea5542c4fab9e0ddb7ba845594a Mon Sep 17 00:00:00 2001 From: bharnden Date: Tue, 17 Sep 2019 10:13:51 -0700 Subject: [PATCH 10/16] removed unwanted logging line from corexml.py --- daemon/core/xml/corexml.py | 1 - 1 file changed, 1 deletion(-) diff --git a/daemon/core/xml/corexml.py b/daemon/core/xml/corexml.py index 63ffb290..31618277 100644 --- a/daemon/core/xml/corexml.py +++ b/daemon/core/xml/corexml.py @@ -423,7 +423,6 @@ class CoreXmlWriter(object): def write_network(self, node): # ignore p2p and other nodes that are not part of the api if not node.apitype: - logging.warning("ignoring node with no apitype: %s", node) return network = NetworkElement(self.session, node) From 9fc77511f29ad4a7b287fac9f2e970f781c2a91f Mon Sep 17 00:00:00 2001 From: Blake Harnden Date: Wed, 18 Sep 2019 12:34:44 -0700 Subject: [PATCH 11/16] adding gh action workflow --- .github/workflows/daemon-checks.yml | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/daemon-checks.yml diff --git a/.github/workflows/daemon-checks.yml b/.github/workflows/daemon-checks.yml new file mode 100644 index 00000000..9202e30a --- /dev/null +++ b/.github/workflows/daemon-checks.yml @@ -0,0 +1,31 @@ +name: Daemon Checks + +on: [push] + +jobs: + build: + runs-on: ubuntu-1804 + steps: + - uses: actions/checkout@v1 + - name: Set up Python 3.7 + uses: actions/setup-python@v1 + with: + python-version: 3.7 + - name: Install pipenv + run: | + python -m pip install --upgrade pip + pip install pipenv + cd daemon + pipenv install --dev + - name: isort + run: | + cd daemon + pipenv run isort + - name: black + run: | + cd daemon + pipenv run black --exclude ".+_pb2.*.py|doc|build|utm\.py" . + - name: flake8 + run: | + cd daemon + pipenv run flake8 From 0dec7af9eb80cb929de504d7739896be869aecf2 Mon Sep 17 00:00:00 2001 From: Blake Harnden Date: Wed, 18 Sep 2019 12:38:38 -0700 Subject: [PATCH 12/16] workflow formatting cleanup --- .github/workflows/daemon-checks.yml | 46 ++++++++++++++--------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/daemon-checks.yml b/.github/workflows/daemon-checks.yml index 9202e30a..3f1f464e 100644 --- a/.github/workflows/daemon-checks.yml +++ b/.github/workflows/daemon-checks.yml @@ -6,26 +6,26 @@ jobs: build: runs-on: ubuntu-1804 steps: - - uses: actions/checkout@v1 - - name: Set up Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - name: Install pipenv - run: | - python -m pip install --upgrade pip - pip install pipenv - cd daemon - pipenv install --dev - - name: isort - run: | - cd daemon - pipenv run isort - - name: black - run: | - cd daemon - pipenv run black --exclude ".+_pb2.*.py|doc|build|utm\.py" . - - name: flake8 - run: | - cd daemon - pipenv run flake8 + - uses: actions/checkout@v1 + - name: Set up Python 3.7 + uses: actions/setup-python@v1 + with: + python-version: 3.7 + - name: Install pipenv + run: | + python -m pip install --upgrade pip + pip install pipenv + cd daemon + pipenv install --dev + - name: isort + run: | + cd daemon + pipenv run isort + - name: black + run: | + cd daemon + pipenv run black --exclude ".+_pb2.*.py|doc|build|utm\.py" . + - name: flake8 + run: | + cd daemon + pipenv run flake8 From 42710864226f7b89c48415e6f32f58b5b687ed88 Mon Sep 17 00:00:00 2001 From: Blake Harnden Date: Wed, 18 Sep 2019 12:56:24 -0700 Subject: [PATCH 13/16] update workflow to use 18.04 correctly --- .github/workflows/daemon-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/daemon-checks.yml b/.github/workflows/daemon-checks.yml index 3f1f464e..53fd0538 100644 --- a/.github/workflows/daemon-checks.yml +++ b/.github/workflows/daemon-checks.yml @@ -4,7 +4,7 @@ on: [push] jobs: build: - runs-on: ubuntu-1804 + runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v1 - name: Set up Python 3.7 From 5baf4adad109feeefecc4ec7336e511a620afe58 Mon Sep 17 00:00:00 2001 From: Blake Harnden Date: Thu, 19 Sep 2019 08:30:20 -0700 Subject: [PATCH 14/16] gh auto - update to compensate for not building setup.py --- .github/workflows/daemon-checks.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/daemon-checks.yml b/.github/workflows/daemon-checks.yml index 53fd0538..882a7de5 100644 --- a/.github/workflows/daemon-checks.yml +++ b/.github/workflows/daemon-checks.yml @@ -16,6 +16,7 @@ jobs: python -m pip install --upgrade pip pip install pipenv cd daemon + cp setup.py.in setup.py pipenv install --dev - name: isort run: | From 009ecd96bb0ac48ca338db6fd949e4b358eff433 Mon Sep 17 00:00:00 2001 From: Blake Harnden Date: Thu, 19 Sep 2019 08:35:04 -0700 Subject: [PATCH 15/16] gh action - update black to report status for failure --- .github/workflows/daemon-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/daemon-checks.yml b/.github/workflows/daemon-checks.yml index 882a7de5..95937006 100644 --- a/.github/workflows/daemon-checks.yml +++ b/.github/workflows/daemon-checks.yml @@ -25,7 +25,7 @@ jobs: - name: black run: | cd daemon - pipenv run black --exclude ".+_pb2.*.py|doc|build|utm\.py" . + pipenv run black --check --exclude ".+_pb2.*.py|doc|build|utm\.py|setup\.py" . - name: flake8 run: | cd daemon From ae6291a1f338d6be097ff97e23188f6d8d2d410f Mon Sep 17 00:00:00 2001 From: Blake Harnden Date: Thu, 19 Sep 2019 08:36:59 -0700 Subject: [PATCH 16/16] gh action - update isort to only check --- .github/workflows/daemon-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/daemon-checks.yml b/.github/workflows/daemon-checks.yml index 95937006..023f5165 100644 --- a/.github/workflows/daemon-checks.yml +++ b/.github/workflows/daemon-checks.yml @@ -21,7 +21,7 @@ jobs: - name: isort run: | cd daemon - pipenv run isort + pipenv run isort -c - name: black run: | cd daemon