Skip to content

Topology Writing

Michael Albert edited this page Jun 15, 2017 · 7 revisions

A basic guide on how to write a topology file. A good starting point for topology writing, for more detailed information visit the Topology Syntax Guide.

Basic YAML

A basic understanding of YAML is useful and will be covered below, however YAML supports many advanced features. Here is an interesting tutorial: https://learnxinyminutes.com/docs/yaml/

You can play around with YAML here: http://yaml-online-parser.appspot.com/

Comments

Comments are denoted by a '#'

# this is a comment

Maps

Maps are simply key-value pairs denoted by a colon (":").

mapKey: mapValue

mapKey:
  submapKey1 : submapVal1 #the value for mapKey is a map of its own (submap) through indenting

Sequences

Sequence items are denoted by a dash ("-").

- list item 1
- list item 2
- list item 3

Combined

Key:
  valueSubMap:
    - item 1
    - item 2
  valueSubMap2:
    - item 3
    - item 4

NOTE: YAML is a superset of json, and json syntax can be used for sequences and maps (see aforementioned tutorial).

Now that we understand the basics of YAML, let's move on to writing topologies.

Topology Writing Preface

A Topology in it's most basic form consists of nodes and links between nodes. The point of connection between a link and a node is an interface. This syntax built on top of the YAML language relies heavily on the use of interfaces (ifaces) and the ability to "provide" (to have an interface not connected to a link) or to "accept" them (have an unconnected end of a link). In addition, only one topology should be declared per file, and the filename should match the topology name (with the addition of a ".yaml"). This allows for proper inclusion (see below).

Simple Declarations

A simple, unconnected Node with 2 interfaces:

node:
    - 2ethNode:             # Name of node
        ifaces:             # Declaring interfaces
            - eth0          # Naming interfaces
            - eth1

A simple, unconnected CSMA link (comments denoted by '#'):

link:
    - simpleCsma:           # Name of link I am creating
        type: csma          # type of link (relates to a type of NS-3 link)
        ifacesAccepted:     # declaring that there are unconnected link ends
            - first         # naming the interface acceptors for future reference
            - second

Now, let's connect two nodes via a link:

nodes:                          # Declare nodes
    - 1ethNode1:                # Name of first node
        ifaces:
            - eth0
    - 1ethNode2:                # Name of second node
        ifaces:
            - eth0
link:                           # Declare links
    - nodeLinker:               # Name of link
        type: csma
        ifaces:                 # Connect interfaces to link
            - 1ethNode1 eth0 10.0.0.1   # Connect 1st node's eth0 and assign ip
            - 1ethNode2 eth0 10.0.0.2   # Connect 2nd node's eth0 and assign ip

Templating and Inclusion (Includes)

In the previous example, two nearly identical (but differently named) nodes were created. To make it easier to create duplicates of nodes or links, templates can be declared for each. This is an identical topology to the one previously declared:

nodes:                          # Declare nodes
    - 1ethNode:                 # Name of template node
        ifaces:
            - eth0
        num: 2                  # Instantiate TWO nodes of this type, this turns the node into an anonymous template
link:
    - nodeLinker:
        type: csma
        ifaces:                 # Connect interfaces to link
            - 1ethNode_1 eth0 10.0.0.1  # Reference the instantiated node of a template via '_#', indexing starts at 1
            - 1ethNode_2 eth0 10.0.0.2  # Connect 2nd node's eth0

The previous topology is an example of an anonymous template. Anonymous templates are instantiated within a topology, and cannot be instantiated in another topology directly.

To prevent redundancy between topologies, explicit templates can be declared. Explicit templates can be included from one file into another. An example of explicit templates.

nodeTemplates.yaml

nodeTemplates:
    - 1ethNode:
        ifaces:
            - eth0

Now, let's use that template in a topology. To do so, we need to tell the parser we are using another file to help construct our topology. This is done via the "includes"

myTopology.yaml

includes:
    - nodeTemplates             # List other files referenced

nodes:                          # Declare nodes
    - myNode:                   # Name of instantiated nodes
        template: 1ethNode      # Which template to instantiate these nodes from
        num: 2                  # Instantiate TWO nodes of this type
link:
    - nodeLinker:
        type: csma
        ifaces:                 # Connect interfaces to link
            - myNode_1 eth0 10.0.0.1    # Reference the instantiated node of a template via '_#', indexing starts at 1
            - myNode_2 eth0 10.0.0.2    # Connect 2nd node's eth0

The same templating can be done with links.

linkTemplates.yaml

linkTemplates:
    - csmaLink:
        type: csma
        ifacesAccepted:
            - first
            - second

Now, let's use both of our templates in a topology.

myTopology.yaml

includes:
    - nodeTemplates                 # List other files referenced
    - linkTemplates

myTopology:                             # Explicit declaration of topology name (as opposed to implicit using filename)
    nodes:                              # Declare nodes
        - myNode:                       # Name of instantiated nodes
            template: 1ethNode          # Which template to instantiate these nodes from
            num: 2                      # Instantiate TWO nodes of this type
    link:
        - nodeLinker:
            template: csmaLink
            ifaces:                     # Connect interfaces to link
                - first: myNode_1 eth0 10.0.0.1  # Connect 1st node's eth0 to first ifaceAccepted
                - second: myNode_2 eth0 10.0.0.2 # Connect 2nd node's eth0 to second ifaceAccepted

Notice, this time we explicitly named the topology 'myTopology', this is useful when including topologies in another topology. Below is a simple topology that will be instantiated/included in another topology:

simpleTop.yaml

simpleTop:                          # Name of topology
    nodes:
        - 1ethNode:
            ifaces:
                - eth0
        - 2ethNode:
            ifaces:
                - eth0
                - eth1
    link:
        - nodeLinker:
            type: csma
            ifaces:
                - 1ethNode eth0 10.0.0.1
                - 2ethNode eth0 10.0.0.2
    ifacesProvided:                 # Declare there are unconnected interfaces
        - looseIface:               # Name the unconnected interface
            2ethNode eth1           # Map the name to the actual interface

Now, we'll instantiate two of the above topologies, and connect them with a link

twoSimpleTops.yaml

includes:
    - simpleTop

twoSimpleTops:
    topologies:
        - simpleTopology:                      #Instantiate two instances of simpleTop
            template: simpleTop
            num: 2
    links:
        - linkThem:
            type: csma
            ifaces:
                - simpleTopology_1 looseIface 11.0.0.1   #Reference the ifaces by what they were named in the ifacesProvided of the subTopology
                - simpleTopology_2 looseIface 11.0.0.2

Inheritance

When using templates for nodes, links, or topologies, an important factor to understand is the use of inheritance and how it applies to those structures.

In the scope of this project, inheritance refers to the sharing of attributes between a template and it's child element. In much the same way as Object-Oriented Programming, child element's declared attributes should override the attributes of the template (NOTE: the ability to override attributes is only partially supported as of 25 May '17, see the topology item's wiki page).

IP/MAC Address Assignment

IPs are assigned to interfaces when they are connected to an IfaceAcceptor/Link

Look back at the twoSimpleTops topology, and notice that both of the sub topologies instantiated have the same internal IP addresses (10.0.0.1 and 10.0.0.2). This can be problematic for routing decisions, so the "offset" tag can be used. This offset is applied to all of the IP addresses assigned within the topology being offset.

Offset twoSimpleTops.yaml

includes:
    - simpleTop

twoSimpleTops:
    topologies:
        - simpleTopology:                      #Instantiate two instances of simpleTop
            template: simpleTop
            num: 2
            offset: 
                simpleTopology_2: 0.0.1.0 #Adds 0.0.1.0 to all ip addresses in sub top
    links:
        - linkThem:
            type: csma
            ifaces:
                - simpleTopology_1 looseIface 11.0.0.1   #Reference the ifaces by what they were named in the ifacesProvided of the subTopology
                - simpleTopology_2 looseIface 11.0.0.2

Positions and Rotations

Nodes and topologies are positionable; able to be placed distant for each other in a virtual 3D space through ns-3's mobility modules. Positions can be time-based, so that nodes/topologies move relative to each other during the simulation. LocationTopology below is an example of static and time-based positioning of nodes.

LocationTopology:
    nodes:
        - node1:
            iface: eth0
            position: 0 10 0 #static x, y, z position
        - node2:
            iface: eth0
            positions: #moving node
                0: 0 0 0 #time is key (0), mapped to x, y, z
                10: 0 5 0 #time 10, position 0, 5, 0
                20: 0 30 0 #time 20, pos 0, 30, 0
        - node3: #the same thing done via templating
            iface: eth0
            positions:
                node3_1: 0 10 0 #key to positions sub map is node name
                node3_2:
                    0: 0 0 0
                    10: 0 5 0
                    20: 0 30 0

In addition, ns3-lxc allows these positions to be rotated at the topology level. Rotating a topology rotates its sub topology's and node's positions (and hence movements) around the topologies base position.

include: locationTopology
RotatedTop:
    topologies:
        - locTop1:
            template: LocationTopology
            position: 100 0 0 #add 100 0 0 to every position within this sub topology
            rotation: 180 #rotate top's positions by 180 degrees around 100 0 0
        - locTop2:
            template: LocationTopology
            positions:
                0: 20 0 0 #rotation is maintained even through movement
                33: 20 30 3
            rotation: 90
        - locTop3: #the same as above but declared via anonymous templating
            template: LocationTopology
            num: 2
            positions:
                locTop3_1: 100 0 0
                locTop3_2:
                    0: 20 0 0
                    33: 20 30 3
            rotations:
                locTop3_1: 180
                locTop3_2: 90