From a7fbb7237f63c4c0d09cfd35c93fbe2e126bc471 Mon Sep 17 00:00:00 2001
From: Marco Capitani <m.capitani@nextworks.it>
Date: Tue, 11 Apr 2017 13:08:30 +0200
Subject: IRATI config file generation

---
 rumba/model.py                      |  11 +-
 rumba/prototypes/irati.py           | 168 ++++++++++++++++-
 rumba/prototypes/irati_templates.py | 349 ++++++++++++++++++++++++++++++++++++
 rumba/testbeds/qemu.py              |  20 ++-
 4 files changed, 535 insertions(+), 13 deletions(-)
 create mode 100644 rumba/prototypes/irati_templates.py

diff --git a/rumba/model.py b/rumba/model.py
index faf353c..4a9a1be 100644
--- a/rumba/model.py
+++ b/rumba/model.py
@@ -298,7 +298,9 @@ class ShimUDPIPCP(IPCP):
 # @nodes: Nodes in the experiment
 #
 class Experiment:
-    def __init__(self, testbed, nodes=None):
+    def __init__(self, testbed, nodes=None, config_file=None):
+        if config_file:
+            nodes = self.read_config_file(config_file)
         if nodes is None:
             nodes = list()
         self.nodes = nodes
@@ -311,13 +313,12 @@ class Experiment:
         self.generate()
 
     @staticmethod
-    def from_config_file(testbed, filename='demo.conf'):
+    def read_config_file(filename='demo.conf'):
         """
         :type testbed: Testbed 
-        :rtype: Experiment
         :param testbed: the testbed for the experiment
         :param filename: name of the .conf file 
-        :return: an Experiment object
+        :return: the nodes list for the configuration file
         """
 
         shims = {}
@@ -407,7 +408,7 @@ class Experiment:
                                  for x, l in node_data['dif_registrations'].items()}
             parsed_nodes.append(Node(name, difs, dif_registrations))
 
-        return Experiment(testbed=testbed, nodes=parsed_nodes)
+        return parsed_nodes
 
     def __repr__(self):
         s = ""
diff --git a/rumba/prototypes/irati.py b/rumba/prototypes/irati.py
index 37a6fbe..df963c5 100644
--- a/rumba/prototypes/irati.py
+++ b/rumba/prototypes/irati.py
@@ -17,14 +17,17 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA  02110-1301  USA
+import copy
+import json
 
 import rumba.ssh_support as ssh
 import rumba.model as mod
+import rumba.prototypes.irati_templates as irati_templates
 
 # An experiment over the IRATI implementation
 class Experiment(mod.Experiment):
-    def __init__(self, testbed, nodes=None):
-        mod.Experiment.__init__(self, testbed, nodes)
+    def __init__(self, testbed, nodes=None, config_file=None):
+        mod.Experiment.__init__(self, testbed, nodes, config_file)
 
     def setup(self):
         cmds = list()
@@ -46,3 +49,164 @@ class Experiment(mod.Experiment):
         print("Setting up IRATI on the nodes...")
         self.setup()
         print("[IRATI experiment] end")
+
+
+class ConfBuilder(object):
+
+    def __init__(self, experiment):
+        self.write_conf(experiment)
+
+    @staticmethod
+    def write_conf(experiment):
+        """
+        :type experiment: Experiment
+        :param experiment: the experiment to be configured
+        """
+        ipcmconfs = dict()
+
+        # TODO ask: what are these, and how are they represented in experiment?
+        # Are these bindings or registration (in node)? In gen.py these are given on a per-dif basis...
+        app_mappings = []
+
+        # If some app directives were specified, use those to build da.map.
+        # Otherwise, assume the standard applications are to be mapped in
+        # the DIF with the highest rank.
+        if len(app_mappings) == 0:
+            if len(experiment.dif_ordering) > 0:
+                for adm in irati_templates.da_map_base["applicationToDIFMappings"]:
+                    adm["difName"] = "%s" % (experiment.dif_ordering[-1],)
+        # else:
+        #     irati_templates.da_map_base["applicationToDIFMappings"] = []
+        #     for apm in app_mappings:
+        #         irati_templates.da_map_base["applicationToDIFMappings"].append({
+        #             "encodedAppName": apm['name'],
+        #             "difName": "%s.DIF" % (apm['dif'])
+        #         })
+
+        # TODO ask: I guess this will need to be added, and in that case we should add it to the qemu plugin too...
+        # Where should we take it in input?
+        manager = False
+        mgmt_dif_name = 'NMS'
+
+        if manager:
+            # Add MAD/Manager configuration
+            irati_templates.ipcmconf_base["addons"] = {
+                "mad": {
+                    "managerAppName": "",
+                    "NMSDIFs": [{"DIF": "%s" % mgmt_dif_name}],
+                    "managerConnections": [{
+                        "managerAppName": "manager-1--",
+                        "DIF": "%s" % mgmt_dif_name
+                    }]
+                }
+            }
+
+        for node in experiment.nodes:  # type: mod.Node
+            ipcmconfs[node.name] = copy.deepcopy(irati_templates.ipcmconf_base)
+            if manager:
+                ipcmconfs[node.name]["addons"]["mad"]["managerAppName"] = "%s.mad-1--" % (node.name)
+
+        difconfs = dict()
+        ipcp2shim_map = {}  # We will need it in a sec
+        for dif in experiment.dif_ordering:  # type: mod.DIF
+            if isinstance(dif, mod.ShimEthDIF):
+                ipcp2shim_map.update({ipcp.name: dif for ipcp in dif.ipcps})
+            elif isinstance(dif, mod.NormalDIF):
+                difconfs[dif.name] = dict()
+                for node in dif.members:
+                    difconfs[dif.name][node.name] = copy.deepcopy(irati_templates.normal_dif_base)
+
+        for node in experiment.nodes:  # type: mod.Node
+            ipcmconf = ipcmconfs[node.name]
+
+            for ipcp in node.ipcps:  # type: mod.ShimEthIPCP
+                if isinstance(ipcp, mod.ShimEthIPCP):
+                    node_name, port_id = ipcp.ifname.split('.')
+                    shim = ipcp2shim_map[ipcp.name]  # type: mod.ShimEthDIF
+                    ipcmconf["ipcProcessesToCreate"].append({
+                        "apName": "eth.%d.IPCP" % int(port_id),
+                        "apInstance": "1",
+                        "difName": shim.name
+                    })
+
+                    template_file_name = 'shimeth.%s.%s.dif' % (node_name, shim.name)
+                    ipcmconf["difConfigurations"].append({
+                        "name": shim.name,
+                        "template": template_file_name
+                    })
+
+                    fout = open(template_file_name, 'w')
+                    fout.write(json.dumps({"difType": "shim-eth-vlan",
+                                           "configParameters": {
+                                               "interface-name": "ifc%d" % (int(port_id),)
+                                           }
+                                           },
+                                          indent=4, sort_keys=True))
+                    fout.close()
+
+        # Run over dif_ordering array, to make sure each IPCM config has
+        # the correct ordering for the ipcProcessesToCreate list of operations.
+        # If we iterated over the difs map, the order would be randomic, and so
+        # some IPCP registrations in lower DIFs may fail. This would happen because
+        # at the moment of registration, it may be that the IPCP of the lower DIF
+        # has not been created yet.
+        shims = ipcp2shim_map.values()
+        for dif in experiment.dif_ordering:  # type: mod.NormalDIF
+
+            if dif in shims:
+                # Shims are managed separately, in the previous loop
+                continue
+
+            for node in dif.members:  # type: mod.Node
+                node_name = node.name
+                node_id = int(node.full_name.split(':')[1]) - 2222
+                ipcmconf = ipcmconfs[node_name]
+
+                # TODO ask: here was vm['id']. Does the name work or does it have to be the id (sequential from 1)?
+                normal_ipcp = {"apName": "%s.%s.IPCP" % (dif.name, node_name),
+                               "apInstance": "1",
+                               "difName": "%s" % (dif.name,),
+                               "difsToRegisterAt": []}
+
+                for lower_dif in node.dif_registrations[dif]:  # type: mod.DIF
+                    normal_ipcp["difsToRegisterAt"].append(lower_dif.name)
+
+                ipcmconf["ipcProcessesToCreate"].append(normal_ipcp)
+
+                ipcmconf["difConfigurations"].append({
+                    "name": "%s" % (dif.name,),
+                    "template": "normal.%s.%s.dif" % (node_name, dif.name,)
+                })
+
+                # Fill in the map of IPCP addresses. This could be moved at difconfs
+                # deepcopy-time
+                # TODO what to do for id? Get it from full_name (i.e.: address:port)? Ugly, but might work
+                for other_node in dif.members:  # type: mod.Node
+                    difconfs[dif.name][other_node.name]["knownIPCProcessAddresses"].append({
+                        "apName": "%s.%s.IPCP" % (dif.name, node_name),
+                        "apInstance": "1",
+                        "address": 16 + node_id
+                    })
+                for path, ps in dif.policies.items():
+                    # if policy['nodes'] == [] or vmname in policy['nodes']:
+                    # TODO: policies can be applied per-node (and not just per-dif)? With what syntax?
+                        irati_templates.translate_policy(difconfs[dif.name][node_name], path,
+                                                         ps, parms=[])
+                    # TODO: what is the syntax for the policy parameters?
+
+        # Dump the DIF Allocator map
+        with open('da.map', 'w') as da_map_file:
+            json.dump(irati_templates.da_map_base, da_map_file, indent=4, sort_keys=True)
+
+        for node in experiment.nodes:
+            # Dump the IPCM configuration files
+            with open('%s.ipcm.conf' % (node.name,), 'w') as node_file:
+                json.dump(ipcmconfs[node.name], node_file, indent=4, sort_keys=True)
+
+        for dif in experiment.dif_ordering:  # type: mod.DIF
+            dif_conf = difconfs.get(dif.name, None)
+            if dif_conf:
+                # Dump the normal DIF configuration files
+                for node in dif.members:
+                    with open('normal.%s.%s.dif' % (node.name, dif.name), 'w') as dif_conf_file:
+                        json.dump(dif_conf[node.name], dif_conf_file, indent=4, sort_keys=True)
diff --git a/rumba/prototypes/irati_templates.py b/rumba/prototypes/irati_templates.py
new file mode 100644
index 0000000..9b03abb
--- /dev/null
+++ b/rumba/prototypes/irati_templates.py
@@ -0,0 +1,349 @@
+#
+# Copyright (C) 2014-2017 Nextworks
+# Author: Vincenzo Maffione <v.maffione@nextworks.it>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+# Environment setup for VMs. Standard linux approach
+env_dict = {'installpath': '/usr', 'varpath': ''}
+
+# Template for a IPCM configuration file
+ipcmconf_base = {
+    "configFileVersion": "1.4.1",
+    "localConfiguration": {
+        "installationPath": "%(installpath)s/bin" % env_dict,
+        "libraryPath": "%(installpath)s/lib" % env_dict,
+        "logPath": "%(varpath)s/var/log" % env_dict,
+        "consoleSocket": "%(varpath)s/var/run/ipcm-console.sock" % env_dict,
+        "pluginsPaths": [
+                "%(installpath)s/lib/rinad/ipcp" % env_dict,
+                "/lib/modules/4.1.33-irati/extra"
+        ]
+        },
+
+    "ipcProcessesToCreate": [],
+    "difConfigurations": [],
+}
+
+
+da_map_base = {
+    "applicationToDIFMappings": [
+        {
+            "encodedAppName": "rina.apps.echotime.server-1--",
+            "difName": "n.DIF"
+        },
+        {
+            "encodedAppName": "traffic.generator.server-1--",
+            "difName": "n.DIF"
+        }
+    ],
+}
+
+
+# Template for a normal DIF configuration file
+normal_dif_base =  {
+    "difType" : "normal-ipc",
+    "dataTransferConstants" : {
+        "addressLength" : 2,
+        "cepIdLength" : 2,
+        "lengthLength" : 2,
+        "portIdLength" : 2,
+        "qosIdLength" : 2,
+        "rateLength" : 4,
+        "frameLength" : 4,
+        "sequenceNumberLength" : 4,
+        "ctrlSequenceNumberLength" : 4,
+        "maxPduSize" : 10000,
+        "maxPduLifetime" : 60000
+    },
+
+    "qosCubes" : [ {
+            "name" : "unreliablewithflowcontrol",
+            "id" : 1,
+            "partialDelivery" : False,
+            "orderedDelivery" : True,
+            "efcpPolicies" : {
+                "dtpPolicySet" : {
+                    "name" : "default",
+                    "version" : "0"
+                },
+                "initialATimer" : 0,
+                "dtcpPresent" : True,
+                "dtcpConfiguration" : {
+                    "dtcpPolicySet" : {
+                        "name" : "default",
+                        "version" : "0"
+                    },
+                    "rtxControl" : False,
+                    "flowControl" : True,
+                    "flowControlConfig" : {
+                        "rateBased" : False,
+                        "windowBased" : True,
+                        "windowBasedConfig" : {
+                            "maxClosedWindowQueueLength" : 10,
+                            "initialCredit" : 200
+                        }
+                    }
+                }
+            }
+        }, {
+            "name" : "reliablewithflowcontrol",
+            "id" : 2,
+            "partialDelivery" : False,
+            "orderedDelivery" : True,
+            "maxAllowableGap": 0,
+            "efcpPolicies" : {
+                "dtpPolicySet" : {
+                    "name" : "default",
+                    "version" : "0"
+                },
+                "initialATimer" : 0,
+                "dtcpPresent" : True,
+                "dtcpConfiguration" : {
+                    "dtcpPolicySet" : {
+                        "name" : "default",
+                        "version" : "0"
+                    },
+                    "rtxControl" : True,
+                    "rtxControlConfig" : {
+                        "dataRxmsNmax" : 5,
+                        "initialRtxTime" : 1000
+                    },
+                    "flowControl" : True,
+                    "flowControlConfig" : {
+                        "rateBased" : False,
+                        "windowBased" : True,
+                        "windowBasedConfig" : {
+                            "maxClosedWindowQueueLength" : 10,
+                            "initialCredit" : 200
+                        }
+                    }
+                }
+            }
+        } ],
+
+    "knownIPCProcessAddresses": [],
+
+    "addressPrefixes" : [ {
+            "addressPrefix" : 0,
+            "organization" : "N.Bourbaki"
+        }, {
+            "addressPrefix" : 16,
+            "organization" : "IRATI"
+        } ],
+
+    "rmtConfiguration" : {
+        "pffConfiguration" : {
+            "policySet" : {
+                "name" : "default",
+                "version" : "0"
+            }
+        },
+        "policySet" : {
+            "name" : "default",
+            "version" : "1"
+        }
+    },
+
+    "enrollmentTaskConfiguration" : {
+        "policySet" : {
+            "name" : "default",
+            "version" : "1",
+            "parameters" : [ {
+                "name"  : "enrollTimeoutInMs",
+                "value" : "10000"
+            }, {
+                "name"  : "watchdogPeriodInMs",
+                "value" : "30000"
+            }, {
+                "name"  : "declaredDeadIntervalInMs",
+                "value" : "120000"
+            }, {
+                "name"  : "neighborsEnrollerPeriodInMs",
+                "value" : "0"
+            }, {
+                "name"  : "maxEnrollmentRetries",
+                "value" : "0"
+            } ]
+        }
+     },
+
+    "flowAllocatorConfiguration" : {
+        "policySet" : {
+            "name" : "default",
+            "version" : "1"
+        }
+    },
+
+    "namespaceManagerConfiguration" : {
+        "policySet" : {
+            "name" : "default",
+            "version" : "1"
+        }
+    },
+
+    "securityManagerConfiguration" : {
+        "policySet" : {
+            "name" : "default",
+            "version" : "1"
+        }
+    },
+
+    "resourceAllocatorConfiguration" : {
+        "pduftgConfiguration" : {
+            "policySet" : {
+                "name" : "default",
+                "version" : "0"
+            }
+        }
+    },
+
+    "routingConfiguration" : {
+        "policySet" : {
+            "name" : "link-state",
+            "version" : "1",
+            "parameters" : [ {
+                    "name"  : "objectMaximumAge",
+                    "value" : "10000"
+                },{
+                    "name"  : "waitUntilReadCDAP",
+                    "value" : "5001"
+                },{
+                    "name"  : "waitUntilError",
+                    "value" : "5001"
+                },{
+                    "name"  : "waitUntilPDUFTComputation",
+                    "value" : "103"
+                },{
+                    "name"  : "waitUntilFSODBPropagation",
+                    "value" : "101"
+                },{
+                    "name"  : "waitUntilAgeIncrement",
+                    "value" : "997"
+                },{
+                    "name"  : "routingAlgorithm",
+                    "value" : "Dijkstra"
+                }]
+        }
+    }
+}
+
+
+def ps_set(d, k, v, parms):
+    if k not in d:
+        d[k] = {'name': '', 'version': '1'}
+
+    if d[k]["name"] == v and "parameters" in d[k]:
+        cur_names = [p["name"] for p in d[k]["parameters"]]
+        for p in parms:
+            name, value = p.split('=')
+            if name in cur_names:
+                for i in range(len(d[k]["parameters"])):
+                    if d[k]["parameters"][i]["name"] == name:
+                        d[k]["parameters"][i]["value"] = value
+                        break
+            else:
+                d[k]["parameters"].append({ 'name': name, 'value': value })
+
+    elif len(parms) > 0:
+        d[k]["parameters"] = [ { 'name': p.split('=')[0], 'value': p.split('=')[1]} for p in parms ]
+
+    d[k]["name"] = v
+
+
+def dtp_ps_set(d, v, parms):
+    for i in range(len(d["qosCubes"])):
+        ps_set(d["qosCubes"][i]["efcpPolicies"], "dtpPolicySet", v, parms)
+
+
+def dtcp_ps_set(d, v, parms):
+    for i in range(len(d["qosCubes"])):
+        ps_set(d["qosCubes"][i]["efcpPolicies"]["dtcpConfiguration"], "dtcpPolicySet", v, parms)
+
+
+policy_translator = {
+    'rmt.pff': lambda d, v, p: ps_set(d["rmtConfiguration"]["pffConfiguration"], "policySet", v, p),
+    'rmt': lambda d, v, p: ps_set(d["rmtConfiguration"], "policySet", v, p),
+    'enrollment-task': lambda d, v, p: ps_set(d["enrollmentTaskConfiguration"], "policySet", v, p),
+    'flow-allocator': lambda d, v, p: ps_set(d["flowAllocatorConfiguration"], "policySet", v, p),
+    'namespace-manager': lambda d, v, p: ps_set(d["namespaceManagerConfiguration"], "policySet", v, p),
+    'security-manager': lambda d, v, p: ps_set(d["securityManagerConfiguration"], "policySet", v, p),
+    'routing': lambda d, v, p: ps_set(d["routingConfiguration"], "policySet", v, p),
+    'resource-allocator.pduftg': lambda d, v, p: ps_set(d["resourceAllocatorConfiguration"], "policySet", v, p),
+    'efcp.*.dtcp': None,
+    'efcp.*.dtp': None,
+}
+
+
+def is_security_path(path):
+    sp = path.split('.')
+    return (len(sp) == 3) and (sp[0] == 'security-manager') and (sp[1] in ['auth', 'encrypt', 'ttl', 'errorcheck'])
+
+
+# Do we know this path ?
+def policy_path_valid(path):
+    if path in policy_translator:
+        return True
+
+    # Try to validate security configuration
+    if is_security_path(path):
+            return True
+
+    return False
+
+
+def translate_security_path(d, path, ps, parms):
+    u1, component, profile = path.split('.')
+    if "authSDUProtProfiles" not in d["securityManagerConfiguration"]:
+        d["securityManagerConfiguration"]["authSDUProtProfiles"] = {}
+    d = d["securityManagerConfiguration"]["authSDUProtProfiles"]
+
+    tr = {'auth': 'authPolicy', 'encrypt': 'encryptPolicy',
+          'ttl': 'TTLPolicy', 'errorcheck': 'ErrorCheckPolicy'}
+
+    if profile == 'default':
+        if profile not in d:
+            d["default"] = {}
+
+        ps_set(d["default"], tr[component], ps, parms)
+
+    else: # profile is the name of a DIF
+        if "specific" not in d:
+            d["specific"] = []
+        j = -1
+        for i in range(len(d["specific"])):
+            if d["specific"][i]["underlyingDIF"] == profile + ".DIF":
+                j = i
+                break
+
+        if j == -1: # We need to create an entry for the new DIF
+            d["specific"].append({"underlyingDIF" : profile + ".DIF"})
+
+        ps_set(d["specific"][j], tr[component], ps, parms)
+
+
+def translate_policy(difconf, path, ps, parms):
+    if path =='efcp.*.dtcp':
+        dtcp_ps_set(difconf, ps, parms)
+
+    elif path == 'efcp.*.dtp':
+        dtp_ps_set(difconf, ps, parms)
+
+    elif is_security_path(path):
+        translate_security_path(difconf, path, ps, parms)
+
+    else:
+        policy_translator[path](difconf, ps, parms)
+
diff --git a/rumba/testbeds/qemu.py b/rumba/testbeds/qemu.py
index 1c5d486..220becc 100644
--- a/rumba/testbeds/qemu.py
+++ b/rumba/testbeds/qemu.py
@@ -26,7 +26,7 @@ import rumba.model as mod
 
 
 class Testbed(mod.Testbed):
-    def __init__(self, exp_name, username, bzimage, initramfs, proj_name="ARCFIRE", password="",
+    def __init__(self, exp_name, bzimage, initramfs, proj_name="ARCFIRE", password="root", username="root",
                  use_vhost=True, qemu_logs_dir=None):
         mod.Testbed.__init__(self, exp_name, username, password, proj_name)
         self.vms = {}
@@ -88,11 +88,12 @@ class Testbed(mod.Testbed):
         e_queue = multiprocessing.Queue()
         print(experiment.dif_ordering)
         for shim in experiment.dif_ordering:
-            command_list = []
             if not isinstance(shim, mod.ShimEthDIF):
                 # Nothing to do here
                 continue
             self.shims.append(shim)
+            ipcps = shim.ipcps
+            command_list = []
             command_list += ('sudo brctl addbr %(br)s\n'
                              'sudo ip link set %(br)s up'
                              % {'br': shim.name}
@@ -123,6 +124,14 @@ class Testbed(mod.Testbed):
                                      ).split('\n')
 
                 vm['ports'].append({'tap_id': tap_id, 'shim': shim, 'port_id': port_id})
+                ipcp_set = [x for x in ipcps if x in node.ipcps]
+                if len(ipcp_set) > 1:
+                    raise Exception("Error: more than one ipcp in common between shim dif %s and node %s"
+                                    % (shim.name, node.name))
+                ipcp = ipcp_set[0]  # type: mod.ShimEthIPCP
+                assert ipcp.name == '%s.%s' % (shim.name, node.name), \
+                    'Incorrect Shim Ipcp found: expected %s.%s, found %s' % (shim.name, node.name, ipcp.name)
+                ipcp.ifname = tap_id
                 # TODO deal with Ip address (shim UDP DIF).
 
             # Avoid stacking processes if one failed before.
@@ -164,14 +173,15 @@ class Testbed(mod.Testbed):
 
         vmid = 1
 
-        for node in experiment.nodes:
-            name = node.full_name
+        for node in experiment.nodes:  # type: mod.Node
+            name = node.name
             vm = self.vms.setdefault(name, {'vm': node, 'ports': []})
             fwdp = base_port + vmid
             fwdc = fwdp + 10000
             mac = '00:0a:0a:0a:%02x:%02x' % (vmid, 99)
             vm['ssh'] = fwdp
             vm['id'] = vmid
+            node.full_name = "127.0.0.1:%s" % fwdp
 
             vars_dict = {'fwdp': fwdp, 'id': vmid, 'mac': mac,
                          'bzimage': self.bzimage,
@@ -197,7 +207,6 @@ class Testbed(mod.Testbed):
                         '-device %(frontend)s,mac=%(mac)s,netdev=mgmt '
                         '-netdev user,id=mgmt,%(hostfwdstr)s '
                         '-vga std '
-                        '-pidfile rina-%(id)s.pid '
                         '-serial file:%(vmname)s.log '
                         % vars_dict
                         )
@@ -225,7 +234,6 @@ class Testbed(mod.Testbed):
             with open('%s/qemu_out_%s' % (self.qemu_logs_dir, vmid), 'w') as out_file:
                 print('DEBUG: executing >> %s' % command)
                 self.boot_processes.append(subprocess.Popen(command.split(), stdout=out_file))
-                pass
 
             vmid += 1
 
-- 
cgit v1.2.3


From 7f5054816fc68bca1d9d4901d1e365b57a278542 Mon Sep 17 00:00:00 2001
From: Marco Capitani <m.capitani@nextworks.it>
Date: Tue, 11 Apr 2017 15:07:51 +0200
Subject: Testing method fix

---
 rumba/model.py            | 10 ++++------
 rumba/prototypes/irati.py |  4 ++--
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/rumba/model.py b/rumba/model.py
index 4a9a1be..bab92bf 100644
--- a/rumba/model.py
+++ b/rumba/model.py
@@ -298,9 +298,7 @@ class ShimUDPIPCP(IPCP):
 # @nodes: Nodes in the experiment
 #
 class Experiment:
-    def __init__(self, testbed, nodes=None, config_file=None):
-        if config_file:
-            nodes = self.read_config_file(config_file)
+    def __init__(self, testbed, nodes=None):
         if nodes is None:
             nodes = list()
         self.nodes = nodes
@@ -312,8 +310,8 @@ class Experiment:
         # Generate missing information
         self.generate()
 
-    @staticmethod
-    def read_config_file(filename='demo.conf'):
+    @classmethod
+    def from_config_file(cls, testbed, filename='demo.conf'):
         """
         :type testbed: Testbed 
         :param testbed: the testbed for the experiment
@@ -408,7 +406,7 @@ class Experiment:
                                  for x, l in node_data['dif_registrations'].items()}
             parsed_nodes.append(Node(name, difs, dif_registrations))
 
-        return parsed_nodes
+        return cls(testbed=testbed, nodes=parsed_nodes)
 
     def __repr__(self):
         s = ""
diff --git a/rumba/prototypes/irati.py b/rumba/prototypes/irati.py
index df963c5..c4c30c7 100644
--- a/rumba/prototypes/irati.py
+++ b/rumba/prototypes/irati.py
@@ -26,8 +26,8 @@ import rumba.prototypes.irati_templates as irati_templates
 
 # An experiment over the IRATI implementation
 class Experiment(mod.Experiment):
-    def __init__(self, testbed, nodes=None, config_file=None):
-        mod.Experiment.__init__(self, testbed, nodes, config_file)
+    def __init__(self, testbed, nodes=None):
+        mod.Experiment.__init__(self, testbed, nodes)
 
     def setup(self):
         cmds = list()
-- 
cgit v1.2.3


From 46310717c3293054324cc6a0271d855b638df0ff Mon Sep 17 00:00:00 2001
From: Marco Capitani <m.capitani@nextworks.it>
Date: Tue, 11 Apr 2017 15:53:49 +0200
Subject: Resolving node_id issue and general cleanup

---
 rumba/model.py                      | 31 ++++++++----
 rumba/prototypes/irati.py           | 98 +++++++++++++++++++++++--------------
 rumba/prototypes/irati_templates.py | 39 ++++++---------
 rumba/testbeds/qemu.py              | 97 +++++++++++++++++++++++-------------
 4 files changed, 157 insertions(+), 108 deletions(-)

diff --git a/rumba/model.py b/rumba/model.py
index bab92bf..9f6d2c2 100644
--- a/rumba/model.py
+++ b/rumba/model.py
@@ -316,7 +316,7 @@ class Experiment:
         :type testbed: Testbed 
         :param testbed: the testbed for the experiment
         :param filename: name of the .conf file 
-        :return: the nodes list for the configuration file
+        :return: the Experiment
         """
 
         shims = {}
@@ -337,7 +337,8 @@ class Experiment:
                 if line.startswith('#') or line == "":
                     continue
 
-                m = re.match(r'\s*eth\s+([\w-]+)\s+(\d+)([GMK])bps\s+(\w.*)$', line)
+                m = re.match(r'\s*eth\s+([\w-]+)\s+(\d+)([GMK])bps\s+(\w.*)$',
+                             line)
                 if m:
                     shim = m.group(1)
                     speed = int(m.group(2))
@@ -357,7 +358,10 @@ class Experiment:
                     shims[shim] = {'name': shim, 'speed': speed, 'type': 'eth'}
 
                     for vm in vm_list:
-                        nodes.setdefault(vm, {'name': vm, 'difs': [], 'dif_registrations': {}, 'registrations': {}})
+                        nodes.setdefault(vm, {'name': vm,
+                                              'difs': [],
+                                              'dif_registrations': {},
+                                              'registrations': {}})
                         nodes[vm]['difs'].append(shim)
                     continue
 
@@ -372,16 +376,21 @@ class Experiment:
                               % (line_cnt, dif))
                         continue
 
-                    difs.setdefault(dif, {'name': dif})  # Other dict contents might be policies.
+                    difs.setdefault(dif, {'name': dif})
 
                     if vm in nodes and dif in nodes[vm]['dif_registrations']:
-                        print('Error: Line %d: vm %s in dif %s already specified'
-                              % (line_cnt, vm, dif))
+                        print(
+                            'Error: Line %d: vm %s in dif %s already specified'
+                            % (line_cnt, vm, dif))
                         continue
 
-                    nodes.setdefault(vm, {'name': vm, 'difs': [], 'dif_registrations': {}, 'registrations': {}})
+                    nodes.setdefault(vm, {'name': vm,
+                                          'difs': [],
+                                          'dif_registrations': {},
+                                          'registrations': {}})
                     nodes[vm]['difs'].append(dif)
-                    nodes[vm]['dif_registrations'][dif] = dif_list  # It is not defined yet, per check above.
+                    nodes[vm]['dif_registrations'][dif] = dif_list
+                    # It is not defined yet, per check above.
 
                     continue
 
@@ -393,7 +402,8 @@ class Experiment:
         parsed_difs = {}
 
         for shim_name, shim in shims.items():
-            parsed_difs[shim_name] = (ShimEthDIF(shim_name, link_speed=shim['speed']))
+            parsed_difs[shim_name] = (ShimEthDIF(shim_name,
+                                                 link_speed=shim['speed']))
 
         for dif_name, dif in difs.items():
             parsed_difs[dif_name] = (NormalDIF(dif_name))
@@ -403,7 +413,8 @@ class Experiment:
             name = node_data['name']
             difs = [parsed_difs[x] for x in node_data['difs']]
             dif_registrations = {parsed_difs[x]: [parsed_difs[y] for y in l]
-                                 for x, l in node_data['dif_registrations'].items()}
+                                 for x, l
+                                 in node_data['dif_registrations'].items()}
             parsed_nodes.append(Node(name, difs, dif_registrations))
 
         return cls(testbed=testbed, nodes=parsed_nodes)
diff --git a/rumba/prototypes/irati.py b/rumba/prototypes/irati.py
index c4c30c7..9c8b004 100644
--- a/rumba/prototypes/irati.py
+++ b/rumba/prototypes/irati.py
@@ -2,6 +2,7 @@
 # Commands to setup and instruct IRATI
 #
 #    Vincenzo Maffione <v.maffione@nextworks.it>
+#    Marco Capitani <m.capitani@nextworks.it>
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -62,10 +63,17 @@ class ConfBuilder(object):
         :type experiment: Experiment
         :param experiment: the experiment to be configured
         """
+        # Constants and initializations
         ipcmconfs = dict()
+        difconfs = dict()
+        ipcp2shim_map = {}
+        node2id_map = {}
+        manager = False
+        mgmt_dif_name = 'NMS'
 
         # TODO ask: what are these, and how are they represented in experiment?
-        # Are these bindings or registration (in node)? In gen.py these are given on a per-dif basis...
+        # Are these bindings or registration (in node)?
+        #  In gen.py these are given on a per-dif basis...
         app_mappings = []
 
         # If some app directives were specified, use those to build da.map.
@@ -73,20 +81,21 @@ class ConfBuilder(object):
         # the DIF with the highest rank.
         if len(app_mappings) == 0:
             if len(experiment.dif_ordering) > 0:
-                for adm in irati_templates.da_map_base["applicationToDIFMappings"]:
+                for adm in \
+                        irati_templates.da_map_base["applicationToDIFMappings"]:
                     adm["difName"] = "%s" % (experiment.dif_ordering[-1],)
         # else:
         #     irati_templates.da_map_base["applicationToDIFMappings"] = []
         #     for apm in app_mappings:
-        #         irati_templates.da_map_base["applicationToDIFMappings"].append({
+        #         irati_templates.da_map_base["applicationToDIFMappings"]\
+        #             .append({
         #             "encodedAppName": apm['name'],
         #             "difName": "%s.DIF" % (apm['dif'])
         #         })
 
-        # TODO ask: I guess this will need to be added, and in that case we should add it to the qemu plugin too...
+        # TODO ask: I guess this will need to be added,
+        # and in that case we should add it to the qemu plugin too...
         # Where should we take it in input?
-        manager = False
-        mgmt_dif_name = 'NMS'
 
         if manager:
             # Add MAD/Manager configuration
@@ -101,20 +110,24 @@ class ConfBuilder(object):
                 }
             }
 
+        node_number = 1
         for node in experiment.nodes:  # type: mod.Node
+            node2id_map[node.name] = node_number
+            node_number += 1
             ipcmconfs[node.name] = copy.deepcopy(irati_templates.ipcmconf_base)
             if manager:
-                ipcmconfs[node.name]["addons"]["mad"]["managerAppName"] = "%s.mad-1--" % (node.name)
+                ipcmconfs[node.name]["addons"]["mad"]["managerAppName"] \
+                    = "%s.mad-1--" % (node.name,)
 
-        difconfs = dict()
-        ipcp2shim_map = {}  # We will need it in a sec
         for dif in experiment.dif_ordering:  # type: mod.DIF
             if isinstance(dif, mod.ShimEthDIF):
                 ipcp2shim_map.update({ipcp.name: dif for ipcp in dif.ipcps})
             elif isinstance(dif, mod.NormalDIF):
                 difconfs[dif.name] = dict()
                 for node in dif.members:
-                    difconfs[dif.name][node.name] = copy.deepcopy(irati_templates.normal_dif_base)
+                    difconfs[dif.name][node.name] = copy.deepcopy(
+                        irati_templates.normal_dif_base
+                    )
 
         for node in experiment.nodes:  # type: mod.Node
             ipcmconf = ipcmconfs[node.name]
@@ -129,27 +142,29 @@ class ConfBuilder(object):
                         "difName": shim.name
                     })
 
-                    template_file_name = 'shimeth.%s.%s.dif' % (node_name, shim.name)
+                    template_file_name = 'shimeth.%s.%s.dif' \
+                                         % (node_name, shim.name)
                     ipcmconf["difConfigurations"].append({
                         "name": shim.name,
                         "template": template_file_name
                     })
 
                     fout = open(template_file_name, 'w')
-                    fout.write(json.dumps({"difType": "shim-eth-vlan",
-                                           "configParameters": {
-                                               "interface-name": "ifc%d" % (int(port_id),)
-                                           }
-                                           },
-                                          indent=4, sort_keys=True))
+                    fout.write(json.dumps(
+                        {"difType": "shim-eth-vlan",
+                         "configParameters": {
+                             "interface-name": "ifc%d" % (int(port_id),)
+                         }
+                         },
+                        indent=4, sort_keys=True))
                     fout.close()
 
         # Run over dif_ordering array, to make sure each IPCM config has
         # the correct ordering for the ipcProcessesToCreate list of operations.
         # If we iterated over the difs map, the order would be randomic, and so
-        # some IPCP registrations in lower DIFs may fail. This would happen because
-        # at the moment of registration, it may be that the IPCP of the lower DIF
-        # has not been created yet.
+        # some IPCP registrations in lower DIFs may fail.
+        #  This would happen because at the moment of registration,
+        #  it may be that the IPCP of the lower DIF has not been created yet.
         shims = ipcp2shim_map.values()
         for dif in experiment.dif_ordering:  # type: mod.NormalDIF
 
@@ -159,10 +174,8 @@ class ConfBuilder(object):
 
             for node in dif.members:  # type: mod.Node
                 node_name = node.name
-                node_id = int(node.full_name.split(':')[1]) - 2222
                 ipcmconf = ipcmconfs[node_name]
 
-                # TODO ask: here was vm['id']. Does the name work or does it have to be the id (sequential from 1)?
                 normal_ipcp = {"apName": "%s.%s.IPCP" % (dif.name, node_name),
                                "apInstance": "1",
                                "difName": "%s" % (dif.name,),
@@ -178,35 +191,44 @@ class ConfBuilder(object):
                     "template": "normal.%s.%s.dif" % (node_name, dif.name,)
                 })
 
-                # Fill in the map of IPCP addresses. This could be moved at difconfs
-                # deepcopy-time
-                # TODO what to do for id? Get it from full_name (i.e.: address:port)? Ugly, but might work
+                # Fill in the map of IPCP addresses.
+                # This could be moved at difconfs
                 for other_node in dif.members:  # type: mod.Node
-                    difconfs[dif.name][other_node.name]["knownIPCProcessAddresses"].append({
-                        "apName": "%s.%s.IPCP" % (dif.name, node_name),
-                        "apInstance": "1",
-                        "address": 16 + node_id
-                    })
+                    difconfs[dif.name][other_node.name] \
+                        ["knownIPCProcessAddresses"].append({
+                         "apName": "%s.%s.IPCP" % (dif.name, node_name),
+                         "apInstance": "1",
+                         "address": 16 + node2id_map[node_name]})
                 for path, ps in dif.policies.items():
                     # if policy['nodes'] == [] or vmname in policy['nodes']:
-                    # TODO: policies can be applied per-node (and not just per-dif)? With what syntax?
-                        irati_templates.translate_policy(difconfs[dif.name][node_name], path,
-                                                         ps, parms=[])
-                    # TODO: what is the syntax for the policy parameters?
+                    # TODO: policies can be applied per-node
+                    # (and not just per-dif) in rumba? With what syntax?
+                    irati_templates.translate_policy(
+                        difconfs[dif.name][node_name], path, ps, parms=[])
 
         # Dump the DIF Allocator map
         with open('da.map', 'w') as da_map_file:
-            json.dump(irati_templates.da_map_base, da_map_file, indent=4, sort_keys=True)
+            json.dump(irati_templates.da_map_base,
+                      da_map_file,
+                      indent=4,
+                      sort_keys=True)
 
         for node in experiment.nodes:
             # Dump the IPCM configuration files
             with open('%s.ipcm.conf' % (node.name,), 'w') as node_file:
-                json.dump(ipcmconfs[node.name], node_file, indent=4, sort_keys=True)
+                json.dump(ipcmconfs[node.name],
+                          node_file,
+                          indent=4,
+                          sort_keys=True)
 
         for dif in experiment.dif_ordering:  # type: mod.DIF
             dif_conf = difconfs.get(dif.name, None)
             if dif_conf:
                 # Dump the normal DIF configuration files
                 for node in dif.members:
-                    with open('normal.%s.%s.dif' % (node.name, dif.name), 'w') as dif_conf_file:
-                        json.dump(dif_conf[node.name], dif_conf_file, indent=4, sort_keys=True)
+                    with open('normal.%s.%s.dif' % (node.name, dif.name), 'w') \
+                            as dif_conf_file:
+                        json.dump(dif_conf[node.name],
+                                  dif_conf_file,
+                                  indent=4,
+                                  sort_keys=True)
diff --git a/rumba/prototypes/irati_templates.py b/rumba/prototypes/irati_templates.py
index 9b03abb..0f3ef05 100644
--- a/rumba/prototypes/irati_templates.py
+++ b/rumba/prototypes/irati_templates.py
@@ -1,21 +1,3 @@
-#
-# Copyright (C) 2014-2017 Nextworks
-# Author: Vincenzo Maffione <v.maffione@nextworks.it>
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
 # Environment setup for VMs. Standard linux approach
 env_dict = {'installpath': '/usr', 'varpath': ''}
 
@@ -274,14 +256,20 @@ def dtcp_ps_set(d, v, parms):
 
 
 policy_translator = {
-    'rmt.pff': lambda d, v, p: ps_set(d["rmtConfiguration"]["pffConfiguration"], "policySet", v, p),
+    'rmt.pff': lambda d, v, p: ps_set(d["rmtConfiguration"]["pffConfiguration"],
+                                      "policySet", v, p),
     'rmt': lambda d, v, p: ps_set(d["rmtConfiguration"], "policySet", v, p),
-    'enrollment-task': lambda d, v, p: ps_set(d["enrollmentTaskConfiguration"], "policySet", v, p),
-    'flow-allocator': lambda d, v, p: ps_set(d["flowAllocatorConfiguration"], "policySet", v, p),
-    'namespace-manager': lambda d, v, p: ps_set(d["namespaceManagerConfiguration"], "policySet", v, p),
-    'security-manager': lambda d, v, p: ps_set(d["securityManagerConfiguration"], "policySet", v, p),
+    'enrollment-task': lambda d, v, p: ps_set(d["enrollmentTaskConfiguration"],
+                                              "policySet", v, p),
+    'flow-allocator': lambda d, v, p: ps_set(d["flowAllocatorConfiguration"],
+                                             "policySet", v, p),
+    'namespace-manager': lambda d, v, p: ps_set(
+        d["namespaceManagerConfiguration"], "policySet", v, p),
+    'security-manager': lambda d, v, p: ps_set(
+        d["securityManagerConfiguration"], "policySet", v, p),
     'routing': lambda d, v, p: ps_set(d["routingConfiguration"], "policySet", v, p),
-    'resource-allocator.pduftg': lambda d, v, p: ps_set(d["resourceAllocatorConfiguration"], "policySet", v, p),
+    'resource-allocator.pduftg': lambda d, v, p: ps_set(
+        d["resourceAllocatorConfiguration"], "policySet", v, p),
     'efcp.*.dtcp': None,
     'efcp.*.dtp': None,
 }
@@ -289,7 +277,8 @@ policy_translator = {
 
 def is_security_path(path):
     sp = path.split('.')
-    return (len(sp) == 3) and (sp[0] == 'security-manager') and (sp[1] in ['auth', 'encrypt', 'ttl', 'errorcheck'])
+    return (len(sp) == 3) and (sp[0] == 'security-manager') \
+        and (sp[1] in ['auth', 'encrypt', 'ttl', 'errorcheck'])
 
 
 # Do we know this path ?
diff --git a/rumba/testbeds/qemu.py b/rumba/testbeds/qemu.py
index 220becc..73a4f14 100644
--- a/rumba/testbeds/qemu.py
+++ b/rumba/testbeds/qemu.py
@@ -2,6 +2,7 @@
 # QEMU testbed for Rumba
 #
 #    Vincenzo Maffione  <v.maffione@nextworks.it>
+#    Marco Capitani <m.capitani@nextworks.it>
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -26,7 +27,8 @@ import rumba.model as mod
 
 
 class Testbed(mod.Testbed):
-    def __init__(self, exp_name, bzimage, initramfs, proj_name="ARCFIRE", password="root", username="root",
+    def __init__(self, exp_name, bzimage, initramfs, proj_name="ARCFIRE",
+                 password="root", username="root",
                  use_vhost=True, qemu_logs_dir=None):
         mod.Testbed.__init__(self, exp_name, username, password, proj_name)
         self.vms = {}
@@ -34,15 +36,18 @@ class Testbed(mod.Testbed):
         self.bzimage = bzimage
         self.initramfs = initramfs
         self.vhost = use_vhost
-        self.qemu_logs_dir = os.getcwd() if qemu_logs_dir is None else qemu_logs_dir
+        self.qemu_logs_dir = os.getcwd() if qemu_logs_dir is None \
+            else qemu_logs_dir
         self.boot_processes = []
 
     @staticmethod
-    def _run_command_chain(commands, results_queue, error_queue, ignore_errors=False):
+    def _run_command_chain(commands, results_queue,
+                           error_queue, ignore_errors=False):
         """
         Runs (sequentially) the command list.
 
-        On error, breaks and dumps it in error_queue, and interrupts as soon as it is non-empty.
+        On error, breaks and dumps it in error_queue, and interrupts
+        as soon as it is non-empty (unless ignore errors is True).
 
         :type commands: list
         :type results_queue: Queue
@@ -114,23 +119,28 @@ class Testbed(mod.Testbed):
                     speed = '%dmbit' % shim.link_speed
 
                     # Rate limit the traffic transmitted on the TAP interface
-                    command_list += ('sudo tc qdisc add dev %(tap)s handle 1: root '
-                                     'htb default 11\n'
-                                     'sudo tc class add dev %(tap)s parent 1: classid '
-                                     '1:1 htb rate 10gbit\n'
-                                     'sudo tc class add dev %(tap)s parent 1:1 classid '
-                                     '1:11 htb rate %(speed)s'
-                                     % {'tap': tap_id, 'speed': speed}
-                                     ).split('\n')
-
-                vm['ports'].append({'tap_id': tap_id, 'shim': shim, 'port_id': port_id})
+                    command_list += (
+                        'sudo tc qdisc add dev %(tap)s handle 1: root '
+                        'htb default 11\n'
+                        'sudo tc class add dev %(tap)s parent 1: classid '
+                        '1:1 htb rate 10gbit\n'
+                        'sudo tc class add dev %(tap)s parent 1:1 classid '
+                        '1:11 htb rate %(speed)s'
+                        % {'tap': tap_id, 'speed': speed}
+                    ).split('\n')
+
+                vm['ports'].append({'tap_id': tap_id,
+                                    'shim': shim,
+                                    'port_id': port_id})
                 ipcp_set = [x for x in ipcps if x in node.ipcps]
                 if len(ipcp_set) > 1:
-                    raise Exception("Error: more than one ipcp in common between shim dif %s and node %s"
+                    raise Exception("Error: more than one ipcp in common "
+                                    "between shim dif %s and node %s"
                                     % (shim.name, node.name))
                 ipcp = ipcp_set[0]  # type: mod.ShimEthIPCP
                 assert ipcp.name == '%s.%s' % (shim.name, node.name), \
-                    'Incorrect Shim Ipcp found: expected %s.%s, found %s' % (shim.name, node.name, ipcp.name)
+                    'Incorrect Shim Ipcp found: expected %s.%s, found %s' \
+                    % (shim.name, node.name, ipcp.name)
                 ipcp.ifname = tap_id
                 # TODO deal with Ip address (shim UDP DIF).
 
@@ -138,7 +148,10 @@ class Testbed(mod.Testbed):
             if not e_queue.empty():
                 break
             # Launch commands asynchronously
-            process = multiprocessing.Process(target=self._run_command_chain, args=(command_list, r_queue, e_queue))
+            process = multiprocessing.Process(target=self._run_command_chain,
+                                              args=(command_list,
+                                                    r_queue,
+                                                    e_queue))
             shim_processes.append(process)
             process.start()
 
@@ -158,7 +171,8 @@ class Testbed(mod.Testbed):
                 result = r_queue.get(timeout=1)
                 if result == "Command chain ran correctly.":
                     over_processes += 1
-                    print('DEBUG: %s of %s processes completed.' % (over_processes, total_processes))
+                    print('DEBUG: %s of %s processes completed.'
+                          % (over_processes, total_processes))
             except:
                 max_waiting_time -= 1
 
@@ -218,22 +232,27 @@ class Testbed(mod.Testbed):
                 mac = '00:0a:0a:0a:%02x:%02x' % (vmid, port['port_id'])
                 port['mac'] = mac
 
-                command += ('-device %(frontend)s,mac=%(mac)s,netdev=data%(idx)s '
-                            '-netdev tap,ifname=%(tap)s,id=data%(idx)s,script=no,'
-                            'downscript=no%(vhost)s '
-                            % {'mac': mac, 'tap': tap_id, 'idx': port['port_id'],
-                               'frontend': vm_frontend, 'vhost': ',vhost=on' if self.vhost else ''}
-                            )
+                command += (
+                    '-device %(frontend)s,mac=%(mac)s,netdev=data%(idx)s '
+                    '-netdev tap,ifname=%(tap)s,id=data%(idx)s,script=no,'
+                    'downscript=no%(vhost)s '
+                    % {'mac': mac, 'tap': tap_id, 'idx': port['port_id'],
+                       'frontend': vm_frontend,
+                       'vhost': ',vhost=on' if self.vhost else ''}
+                )
 
             booting_budget -= 1
             if booting_budget <= 0:
-                print('Sleeping for %s seconds to give the machines time to boot up.' % boot_backoff)
+                print('Sleeping for %s seconds to give '
+                      'the machines time to boot up.' % boot_backoff)
                 time.sleep(boot_backoff)
                 booting_budget = boot_batch_size
 
-            with open('%s/qemu_out_%s' % (self.qemu_logs_dir, vmid), 'w') as out_file:
+            with open('%s/qemu_out_%s' % (self.qemu_logs_dir, vmid), 'w')\
+                    as out_file:
                 print('DEBUG: executing >> %s' % command)
-                self.boot_processes.append(subprocess.Popen(command.split(), stdout=out_file))
+                self.boot_processes.append(subprocess.Popen(command.split(),
+                                                            stdout=out_file))
 
             vmid += 1
 
@@ -265,9 +284,10 @@ class Testbed(mod.Testbed):
                              'sudo ip tuntap del mode tap name %(tap)s'
                              % {'tap': tap, 'br': shim.name}
                              ).split('\n')
-                process = multiprocessing.Process(target=self._run_command_chain,
-                                                  args=(commands, results_queue, error_queue),
-                                                  kwargs={'ignore_errors': True})
+                process = multiprocessing.Process(
+                    target=self._run_command_chain,
+                    args=(commands, results_queue, error_queue),
+                    kwargs={'ignore_errors': True})
                 port_processes.append(process)
                 process.start()
 
@@ -278,14 +298,17 @@ class Testbed(mod.Testbed):
         while max_waiting_time > 0 and over_processes < total_processes:
             # Check for errors
             if not error_queue.empty():
-                print('Failure while shutting down: %s' % str(error_queue.get()))
+                print(
+                    'Failure while shutting down: %s' % str(error_queue.get())
+                )
                 over_processes += 1
             try:
                 # Check for results
                 result = results_queue.get(timeout=1)
                 if result == "Command chain ran correctly.":
                     over_processes += 1
-                    print('DEBUG: %s of %s tear-down port processes completed.' % (over_processes, total_processes))
+                    print('DEBUG: %s of %s tear-down port processes completed.'
+                          % (over_processes, total_processes))
             except:
                 max_waiting_time -= 1
 
@@ -300,7 +323,9 @@ class Testbed(mod.Testbed):
                          % {'br': shim.name}
                          ).split('\n')
             process = multiprocessing.Process(target=self._run_command_chain,
-                                              args=(commands, results_queue, error_queue),
+                                              args=(commands,
+                                                    results_queue,
+                                                    error_queue),
                                               kwargs={'ignore_errors': True})
             shim_processes.append(process)
             process.start()
@@ -312,13 +337,15 @@ class Testbed(mod.Testbed):
         while max_waiting_time > 0 and over_processes < total_processes:
             # Check for errors
             if not error_queue.empty():
-                print('Failure while shutting down: %s' % str(error_queue.get()))
+                print('Failure while shutting down: %s'
+                      % str(error_queue.get()))
                 over_processes += 1
             try:
                 # Check for results
                 result = results_queue.get(timeout=1)
                 if result == "Command chain ran correctly.":
                     over_processes += 1
-                    print('DEBUG: %s of %s tear-down shim processes completed.' % (over_processes, total_processes))
+                    print('DEBUG: %s of %s tear-down shim processes completed.'
+                          % (over_processes, total_processes))
             except:
                 max_waiting_time -= 1
-- 
cgit v1.2.3


From af692809383b55ec3b9d7cb96e50b553ffbcd496 Mon Sep 17 00:00:00 2001
From: Marco Capitani <m.capitani@nextworks.it>
Date: Thu, 13 Apr 2017 10:32:10 +0200
Subject: IRATI prototype: bootstrap_network method. Now complete & to be
 tested.

---
 rumba/prototypes/irati.py | 147 ++++++++++++++++++++++++++++++++++++++++------
 rumba/testbeds/qemu.py    |   5 +-
 2 files changed, 132 insertions(+), 20 deletions(-)

diff --git a/rumba/prototypes/irati.py b/rumba/prototypes/irati.py
index e06610d..ba8a152 100644
--- a/rumba/prototypes/irati.py
+++ b/rumba/prototypes/irati.py
@@ -21,16 +21,38 @@
 import copy
 import json
 
+import subprocess
+
 import rumba.ssh_support as ssh
 import rumba.model as mod
 import rumba.prototypes.irati_templates as irati_templates
 
+
 # An experiment over the IRATI implementation
+from rumba import ssh_support
+
+
 class Experiment(mod.Experiment):
+
+    @staticmethod
+    def real_sudo(s):
+        return 'sudo ' + s
+
+    @staticmethod
+    def fake_sudo(s):
+        return s
+
     def __init__(self, testbed, nodes=None):
         mod.Experiment.__init__(self, testbed, nodes)
+        self.manager = False
+
+        if self.testbed.username == 'root':
+            self.sudo = self.fake_sudo
+        else:
+            self.sudo = self.real_sudo
 
     def setup(self):
+        """Installs IRATI on the vms."""
         cmds = list()
 
         cmds.append("sudo apt-get update")
@@ -45,36 +67,129 @@ class Experiment(mod.Experiment):
             ssh.execute_commands(self.testbed, node.ssh_config,
                                  cmds, time_out=None)
 
+    def bootstrap_network(self):
+        """Creates the network by enrolling and configuring the nodes"""
+        for node in self.nodes:
+            self.process_node(node)
+        self.enroll_nodes()
+
     def run_prototype(self):
         print("[IRATI experiment] start")
         print("Setting up IRATI on the nodes...")
         self.setup()
         print("[IRATI experiment] end")
 
+    def process_node(self, node):
+        """
+        Installs the configuration and boots up rina on a node
+        :type node: mod.Node
+        :param node: 
+        :return: 
+        """
+        name = node.name
+        gen_files_conf = 'shimeth.%(name)s.*.dif da.map %(name)s.ipcm.conf' % {
+            'name': name}
+        if any(name in dif.members for dif in self.dif_ordering):
+            gen_files_conf = ' '.join(
+                [gen_files_conf, 'normal.%(name)s.*.dif' % {'name': name}])
+        gen_files_bin = 'enroll.py'
+
+        ipcm_components = ['scripting', 'console']
+        if self.manager:
+            ipcm_components.append('mad')
+        ipcm_components = ', '.join(ipcm_components)
+
+        gen_files = ' '.join([gen_files_conf, gen_files_bin])
+
+        sshopts = ('-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
+                   ' -o IdentityFile=buildroot/irati_rsa')
+        format_args = {'name': name,
+                       'ssh': node.ssh_config.port,
+                       'username': self.testbed.username,
+                       'genfiles': gen_files,
+                       'genfilesconf': gen_files_conf,
+                       'genfilesbin': gen_files_bin,
+                       'sshopts': sshopts,
+                       'installpath': '/usr',
+                       'verb': 'DBG',
+                       'ipcmcomps': ipcm_components}
+        try:
+            subprocess.check_call(('scp %(sshopts)s -r -P %(ssh)s '
+                                   '%(genfiles)s %(username)s@localhost:'
+                                   % format_args).split())
+        except subprocess.CalledProcessError as e:
+            raise Exception(str(e))
+
+        # TODO: review ssh opts through ssh support
+
+        cmds = [self.sudo('hostname %(name)s' % format_args),
+                self.sudo('chmd a+rw /dev/irati'),
+                self.sudo('mv %(genfilesconf)s /etc' % format_args),
+                self.sudo('mv %(genfilesbin)s /usr/bin') % format_args]
+
+        # TODO: is the port up on the VM at this point?
+
+        cmds += [self.sudo('modprobe rina-default-plugin'),
+                 self.sudo('%(installpath)s/bin/ipcm -a \"%(ipcmcomps)s\" '
+                           '-c /etc/%(name)s.ipcm.conf -l %(verb)s &> log &'
+                           % format_args)]
+
+        ssh_support.execute_commands(self.testbed, node.ssh_config, cmds)
+
+    def enroll_nodes(self):
+        """Runs the enrollments one by one, respecting dependencies"""
+        for enrollment_list in self.enrollments:
+            for e in enrollment_list:
+                print(
+                    'I am going to enroll %s to DIF %s against neighbor %s,'
+                    ' through lower DIF %s'
+                    % (e['enrollee'],
+                       e['dif'].name,
+                       e['enroller'],
+                       e['lower_dif'].name))
+
+                subprocess.check_call('sleep 2'. split())  # Important!
+
+                e_args = {'ldif': e['lower_dif'].name,
+                          'dif': e['dif'].name,
+                          'name': e['enrollee'].name,
+                          'o_name': e['enroller'].name}
+
+                cmd = self.sudo('enroll.py --lower-dif %(ldif)s --dif %(dif)s '
+                                '--ipcm-conf /etc/%(name)s.ipcm.conf '
+                                '--enrollee-name %(dif)s.%(name)s.IPCP '
+                                '--enroller-name %(dif)s.%(o_name)s.IPCP'
+                           % e_args)
+                ssh_support.execute_command(self.testbed,
+                                            e['enrollee'].ssh_config,
+                                            cmd)
+
 
 class ConfBuilder(object):
 
-    def __init__(self, experiment):
-        self.write_conf(experiment)
+    def __init__(self, experiment, manager):
+        self.write_conf(experiment, manager)
 
     @staticmethod
-    def write_conf(experiment):
+    def write_conf(experiment, manager):
         """
         :type experiment: Experiment
         :param experiment: the experiment to be configured
+        :param manager: boolean indicating if a manager is requested
         """
         # Constants and initializations
         ipcmconfs = dict()
         difconfs = dict()
         ipcp2shim_map = {}
         node2id_map = {}
-        manager = False
         mgmt_dif_name = 'NMS'
 
-        # TODO ask: what are these, and how are they represented in experiment?
-        # Are these bindings or registration (in node)?
-        #  In gen.py these are given on a per-dif basis...
+        # TODO: what format are the mappings registered in? Is this ok?
         app_mappings = []
+        for node in experiment.nodes:
+            app_mappings += [{'name': app, 'dif': dif.name}
+                             for app in node.registrations
+                             for dif in node.registrations[app]]
 
         # If some app directives were specified, use those to build da.map.
         # Otherwise, assume the standard applications are to be mapped in
@@ -84,14 +199,13 @@ class ConfBuilder(object):
                 for adm in \
                         irati_templates.da_map_base["applicationToDIFMappings"]:
                     adm["difName"] = "%s" % (experiment.dif_ordering[-1],)
-        # else:
-        #     irati_templates.da_map_base["applicationToDIFMappings"] = []
-        #     for apm in app_mappings:
-        #         irati_templates.da_map_base["applicationToDIFMappings"]\
-        #             .append({
-        #             "encodedAppName": apm['name'],
-        #             "difName": "%s.DIF" % (apm['dif'])
-        #         })
+        else:
+            irati_templates.da_map_base["applicationToDIFMappings"] = []
+            for apm in app_mappings:
+                irati_templates.da_map_base["applicationToDIFMappings"]\
+                    .append({"encodedAppName": apm['name'],
+                             "difName": "%s" % (apm['dif'])
+                             })
 
         # TODO ask: I guess this will need to be added,
         # and in that case we should add it to the qemu plugin too...
@@ -201,8 +315,7 @@ class ConfBuilder(object):
                          "address": 16 + node2id_map[node_name]})
                 for path, ps in dif.policies.items():
                     # if policy['nodes'] == [] or vmname in policy['nodes']:
-                    # TODO: policies can be applied per-node
-                    # (and not just per-dif) in rumba? With what syntax?
+                    # TODO: manage per-node-policies
                     irati_templates.translate_policy(
                         difconfs[dif.name][node_name], path, ps, parms=[])
 
diff --git a/rumba/testbeds/qemu.py b/rumba/testbeds/qemu.py
index 7255b3c..da3c7b9 100644
--- a/rumba/testbeds/qemu.py
+++ b/rumba/testbeds/qemu.py
@@ -180,9 +180,9 @@ class Testbed(mod.Testbed):
 
         boot_batch_size = max(1, multiprocessing.cpu_count() // 2)
         booting_budget = boot_batch_size
-        boot_backoff = 12 # in seconds
+        boot_backoff = 12  # in seconds
         base_port = 2222
-        vm_memory = 164 # in megabytes
+        vm_memory = 164  # in megabytes
         vm_frontend = 'virtio-net-pci'
 
         vmid = 1
@@ -266,7 +266,6 @@ class Testbed(mod.Testbed):
             print('Sleeping %s secs waiting for the last VMs to boot' % tsleep)
             time.sleep(tsleep)
 
-
     def swap_out(self, experiment):
         """
         :rtype str
-- 
cgit v1.2.3


From fbbc602d9efd9f88ce35b09c02f1226881c32bfb Mon Sep 17 00:00:00 2001
From: Marco Capitani <m.capitani@nextworks.it>
Date: Fri, 14 Apr 2017 11:57:47 +0200
Subject: Bugfixing for IRATI prototype and QEMU testbed

---
 rumba/prototypes/enroll.py          | 117 ++++++++++++++
 rumba/prototypes/irati.py           |   3 +-
 rumba/prototypes/irati_rsa          |  27 ++++
 rumba/prototypes/irati_templates.py | 313 +++++++++++++++++++-----------------
 rumba/testbeds/qemu.py              |  27 ++--
 tools/dc-vpns.conf                  | 114 +++++++++++++
 tools/democonf2rumba.py             |   3 +-
 tools/geant2-renumber.conf          |  86 ++++++++++
 tools/insane-stacking.conf          |  29 ++++
 tools/isp-sec.conf                  | 189 ++++++++++++++++++++++
 tools/resilient-square.conf         |  16 ++
 tools/secure-two-layers.conf        |  25 +++
 tools/seven.conf                    |  34 ++++
 tools/star.conf                     |   7 +
 tools/triangle.conf                 |   9 ++
 tools/tutorial1.conf                |   4 +
 tools/tutorial2.conf                |   6 +
 tools/two-layers.conf               |  17 ++
 18 files changed, 863 insertions(+), 163 deletions(-)
 create mode 100755 rumba/prototypes/enroll.py
 create mode 100644 rumba/prototypes/irati_rsa
 create mode 100644 tools/dc-vpns.conf
 create mode 100644 tools/geant2-renumber.conf
 create mode 100644 tools/insane-stacking.conf
 create mode 100644 tools/isp-sec.conf
 create mode 100644 tools/resilient-square.conf
 create mode 100644 tools/secure-two-layers.conf
 create mode 100644 tools/seven.conf
 create mode 100644 tools/star.conf
 create mode 100644 tools/triangle.conf
 create mode 100644 tools/tutorial1.conf
 create mode 100644 tools/tutorial2.conf
 create mode 100644 tools/two-layers.conf

diff --git a/rumba/prototypes/enroll.py b/rumba/prototypes/enroll.py
new file mode 100755
index 0000000..458736a
--- /dev/null
+++ b/rumba/prototypes/enroll.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+
+#
+# Author: Vincenzo Maffione <v.maffione@nextworks.it>
+#
+
+import argparse
+import socket
+import time
+import re
+
+def printalo(byt):
+    print(repr(byt).replace('\\n', '\n'))
+
+
+def get_response(s):
+    data = bytes()
+    while 1:
+        data += s.recv(1024)
+        lines = str(data).replace('\\n', '\n').split('\n')
+        #print(lines)
+        if lines[-1].find("IPCM") != -1:
+            return lines[:len(lines)-1]
+
+
+description = "Python script to enroll IPCPs"
+epilog = "2016 Vincenzo Maffione <v.maffione@nextworks.it>"
+
+argparser = argparse.ArgumentParser(description = description,
+                                    epilog = epilog)
+argparser.add_argument('--ipcm-conf', help = "Path to the IPCM configuration file",
+                       type = str, required = True)
+argparser.add_argument('--enrollee-name', help = "Name of the enrolling IPCP",
+                       type = str, required = True)
+argparser.add_argument('--dif', help = "Name of DIF to enroll to",
+                       type = str, required = True)
+argparser.add_argument('--lower-dif', help = "Name of the lower level DIF",
+                       type = str, required = True)
+argparser.add_argument('--enroller-name', help = "Name of the remote neighbor IPCP to enroll to",
+                       type = str, required = True)
+args = argparser.parse_args()
+
+socket_name = None
+
+fin = open(args.ipcm_conf, 'r')
+while 1:
+    line = fin.readline()
+    if line == '':
+        break
+
+    m = re.search(r'"(\S+ipcm-console.sock)', line)
+    if m != None:
+        socket_name = m.group(1)
+        break
+fin.close()
+
+if socket_name == None:
+    print('Cannot find %s' % (socket_name))
+    quit(1)
+
+s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+
+connected = False
+trials = 0
+while trials < 4:
+    try:
+        s.connect(socket_name)
+        connected = True
+        break
+    except:
+        pass
+    trials += 1
+    time.sleep(1)
+
+if connected:
+    try:
+        # Receive the banner
+        get_response(s)
+
+        # Send the IPCP list command
+        cmd = 'list-ipcps\n'
+        s.sendall(bytes(cmd, 'ascii'))
+
+        # Get the list of IPCPs and parse it to look for the enroller ID
+        print('Looking up identifier for IPCP %s' % args.enrollee_name)
+        lines = get_response(s)
+        print(lines)
+        enrollee_id = None
+        for line in lines:
+            rs = r'^\s*(\d+)\s*\|\s*' + args.enrollee_name.replace('.', '\\.')
+            m = re.match(rs, line)
+            if m != None:
+                enrollee_id = m.group(1)
+
+        if enrollee_id == None:
+            print('Could not find the ID of enrollee IPCP %s' \
+                    % args.enrollee_name)
+            raise Exception()
+
+        # Send the enroll command
+        cmd = 'enroll-to-dif %s %s %s %s 1\n' \
+                % (enrollee_id, args.dif, args.lower_dif, args.enroller_name)
+        print(cmd)
+
+        s.sendall(bytes(cmd, 'ascii'))
+
+        # Get the enroll command answer
+        lines = get_response(s)
+        print(lines)
+    except:
+        s.close()
+        raise
+
+else:
+    print('Failed to connect to "%s"' % socket_name)
+
+s.close()
diff --git a/rumba/prototypes/irati.py b/rumba/prototypes/irati.py
index 44eadb0..dd7086e 100644
--- a/rumba/prototypes/irati.py
+++ b/rumba/prototypes/irati.py
@@ -114,7 +114,8 @@ class Experiment(mod.Experiment):
         gen_files = ' '.join([gen_files_conf, gen_files_bin_full])
 
         sshopts = ('-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
-                   ' -o IdentityFile=buildroot/irati_rsa')
+                   ' -o IdentityFile=%s'
+                   % (os.path.join(dir_path, 'irati_rsa',)))
         format_args = {'name': name,
                        'ssh': node.ssh_config.port,
                        'username': self.testbed.username,
diff --git a/rumba/prototypes/irati_rsa b/rumba/prototypes/irati_rsa
new file mode 100644
index 0000000..8119a76
--- /dev/null
+++ b/rumba/prototypes/irati_rsa
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAyfuwhIYMa2pCcbLYfeDblxaXNxLcJS8aJFjpwPVdXQoTwO79
+BmbZXFObrdxy3paaYyJBAIpOyAcn4B9oEcpHF7J6+IvDA6TpOf45tZzqVRdZxFd7
+ESPlleCpRxTWTmIFiR8j734v8sj0CXYjiegjhS9izhPobjz3ZaTDO4xfQbQs37JF
+7Xdcbjph/8ExqYyvz9yxU5rbCr3u7AurBRM/o5kfV5Ps+52WXNJT2RTjgQjmL1PQ
+0/K8DATPKW9ns1d90Zguf0cE2oZiUn85ukuvVAAOsvO0GOpncFhEUrTLCw/DMayP
+Wk1mjL1jJDeYbqf1cnOG+Wzt5glueKzSGhh6ewIDAQABAoIBAGN62QeMVhWZcjw5
+j7L/ymdxsuxnF5IgzslUGVz1/BPU4MHHc0tx4GA+tZA94T2MA2IL/uPbOs396D/U
+eBc6/yTGvRYpD9V9pXjwo0+1hxx9sbKoO27HtU3KJtVhh+N3F67fbX2JMuhq3PbD
+/uDvOn9gRVOmLnYNBPRE3/s2ObxLtkbT4QIuSF/XItxECBOwWNyTYdOmqhoz6XzA
+OPN9mGsKPMevWoKTfLffuMncIEyEEtV2Jnck/cHPha2GGuzty+faOGSF7GwHOpfu
+DQTK30lUFRmlHnId5UIRG0J+MfSJhk/VillJwvUFmCYgH5Ur7htDTER7JIeU8ym6
+YxY3HDECgYEA+fnqiqmst9LNXnjGnIAtnIi11DsmwDQaxW+kNvXvJsEWWboUbcPs
+q/Fzm0ACMLHARje4wynzIrBY5Iw8qzTswzPFo9CO4MNw/hvMO1iB0Dvo8rWqMJv4
+b2qsuo9r4QkVt53K6WVG/h9Ua/mqr2AQOaATj1ScGKpx0g10GjVqDGcCgYEAztm1
+NKxwqw/j1Pn5AnRRIMkDgO2O6fXKZEgoBdXDWrlHn4vr8fspNE+DMuonQS8GY7Xd
+a+APpPqNk32WKDCfeuKNZX7gXCnV39GOhNrhpfT14/dea1YEQ03vcxVD1aqkw2jl
+Y+qOG2kDBpYkPPEf5od6cfFvUet15d8NBwJXlM0CgYBypkcGNe/7l3mNvMMLAFbr
+FmCe6EpLmRo2N5APjRiUo7aGjKvV9ChWbDVjnSXkA4J2MhRRnqne3RbIK/GfbHSy
+ysn46iy9taXbRhCTn3JaeT/MIbne9YoqP7jdD+6glbQaNQrdpQ+8ec4Uf7vjF6IZ
+a+vMrzewsGvntTfs1VbAPQKBgQCl+8LRkrISQnzzEOfFFWtoYIUENxxgFxCiadhb
+3k2Vhmm32EKr+Xv18vv3pjd7se1xo6UbBD/phfiHatZMR8Ahjpwh3q7Qpe1uXaz8
+ZNt/HVMW7BADF5HyJB7J/T1ivjzaZVj1VWlVC24XIfHQSTjs9rfFqRRH6ya/H75H
+apS23QKBgCj4TWnRtMsEaZZIamgzxMw1eUdYH27ZeaG0Do+hZ1XGixq4CWxCqxVg
+nwbXRkRYwqI+2zzsaeNji4OX6wJdO7lZntuk4v6O0WeY9aJxGaLkYaRk5eF2TLyW
+IVQbpcC/q1fnCo3HjWxR3w8QYmsQi97AC7xUMsjqwntIGV1QrR7s
+-----END RSA PRIVATE KEY-----
diff --git a/rumba/prototypes/irati_templates.py b/rumba/prototypes/irati_templates.py
index 0f3ef05..b8d9788 100644
--- a/rumba/prototypes/irati_templates.py
+++ b/rumba/prototypes/irati_templates.py
@@ -35,189 +35,197 @@ da_map_base = {
 
 
 # Template for a normal DIF configuration file
-normal_dif_base =  {
-    "difType" : "normal-ipc",
-    "dataTransferConstants" : {
-        "addressLength" : 2,
-        "cepIdLength" : 2,
-        "lengthLength" : 2,
-        "portIdLength" : 2,
-        "qosIdLength" : 2,
-        "rateLength" : 4,
-        "frameLength" : 4,
-        "sequenceNumberLength" : 4,
-        "ctrlSequenceNumberLength" : 4,
-        "maxPduSize" : 10000,
-        "maxPduLifetime" : 60000
+normal_dif_base = {
+    "difType": "normal-ipc",
+    "dataTransferConstants": {
+        "addressLength": 2,
+        "cepIdLength": 2,
+        "lengthLength": 2,
+        "portIdLength": 2,
+        "qosIdLength": 2,
+        "rateLength": 4,
+        "frameLength": 4,
+        "sequenceNumberLength": 4,
+        "ctrlSequenceNumberLength": 4,
+        "maxPduSize": 10000,
+        "maxPduLifetime": 60000
     },
 
-    "qosCubes" : [ {
-            "name" : "unreliablewithflowcontrol",
-            "id" : 1,
-            "partialDelivery" : False,
-            "orderedDelivery" : True,
-            "efcpPolicies" : {
-                "dtpPolicySet" : {
-                    "name" : "default",
-                    "version" : "0"
+    "qosCubes": [
+        {
+            "name": "unreliablewithflowcontrol",
+            "id": 1,
+            "partialDelivery": False,
+            "orderedDelivery": True,
+            "efcpPolicies": {
+                "dtpPolicySet": {
+                    "name": "default",
+                    "version": "0"
                 },
-                "initialATimer" : 0,
-                "dtcpPresent" : True,
-                "dtcpConfiguration" : {
-                    "dtcpPolicySet" : {
-                        "name" : "default",
-                        "version" : "0"
+                "initialATimer": 0,
+                "dtcpPresent": True,
+                "dtcpConfiguration": {
+                    "dtcpPolicySet": {
+                        "name": "default",
+                        "version": "0"
                     },
-                    "rtxControl" : False,
-                    "flowControl" : True,
-                    "flowControlConfig" : {
-                        "rateBased" : False,
-                        "windowBased" : True,
-                        "windowBasedConfig" : {
-                            "maxClosedWindowQueueLength" : 10,
-                            "initialCredit" : 200
+                    "rtxControl": False,
+                    "flowControl": True,
+                    "flowControlConfig": {
+                        "rateBased": False,
+                        "windowBased": True,
+                        "windowBasedConfig": {
+                            "maxClosedWindowQueueLength": 10,
+                            "initialCredit": 200
                         }
                     }
                 }
             }
         }, {
-            "name" : "reliablewithflowcontrol",
-            "id" : 2,
-            "partialDelivery" : False,
-            "orderedDelivery" : True,
+            "name": "reliablewithflowcontrol",
+            "id": 2,
+            "partialDelivery": False,
+            "orderedDelivery": True,
             "maxAllowableGap": 0,
-            "efcpPolicies" : {
-                "dtpPolicySet" : {
-                    "name" : "default",
-                    "version" : "0"
+            "efcpPolicies": {
+                "dtpPolicySet": {
+                    "name": "default",
+                    "version": "0"
                 },
-                "initialATimer" : 0,
-                "dtcpPresent" : True,
-                "dtcpConfiguration" : {
-                    "dtcpPolicySet" : {
-                        "name" : "default",
-                        "version" : "0"
+                "initialATimer": 0,
+                "dtcpPresent": True,
+                "dtcpConfiguration": {
+                    "dtcpPolicySet": {
+                        "name": "default",
+                        "version": "0"
                     },
-                    "rtxControl" : True,
-                    "rtxControlConfig" : {
-                        "dataRxmsNmax" : 5,
-                        "initialRtxTime" : 1000
+                    "rtxControl": True,
+                    "rtxControlConfig": {
+                        "dataRxmsNmax": 5,
+                        "initialRtxTime": 1000
                     },
-                    "flowControl" : True,
-                    "flowControlConfig" : {
-                        "rateBased" : False,
-                        "windowBased" : True,
-                        "windowBasedConfig" : {
-                            "maxClosedWindowQueueLength" : 10,
-                            "initialCredit" : 200
+                    "flowControl": True,
+                    "flowControlConfig": {
+                        "rateBased": False,
+                        "windowBased": True,
+                        "windowBasedConfig": {
+                            "maxClosedWindowQueueLength": 10,
+                            "initialCredit": 200
                         }
                     }
                 }
             }
-        } ],
+        }
+    ],
 
     "knownIPCProcessAddresses": [],
 
-    "addressPrefixes" : [ {
-            "addressPrefix" : 0,
-            "organization" : "N.Bourbaki"
+    "addressPrefixes": [
+        {
+            "addressPrefix": 0,
+            "organization": "N.Bourbaki"
         }, {
-            "addressPrefix" : 16,
-            "organization" : "IRATI"
-        } ],
-
-    "rmtConfiguration" : {
-        "pffConfiguration" : {
-            "policySet" : {
-                "name" : "default",
-                "version" : "0"
+            "addressPrefix": 16,
+            "organization": "IRATI"
+        }
+    ],
+
+    "rmtConfiguration": {
+        "pffConfiguration": {
+            "policySet": {
+                "name": "default",
+                "version": "0"
             }
         },
-        "policySet" : {
-            "name" : "default",
-            "version" : "1"
+        "policySet": {
+            "name": "default",
+            "version": "1"
         }
     },
 
-    "enrollmentTaskConfiguration" : {
-        "policySet" : {
-            "name" : "default",
-            "version" : "1",
-            "parameters" : [ {
-                "name"  : "enrollTimeoutInMs",
-                "value" : "10000"
-            }, {
-                "name"  : "watchdogPeriodInMs",
-                "value" : "30000"
-            }, {
-                "name"  : "declaredDeadIntervalInMs",
-                "value" : "120000"
-            }, {
-                "name"  : "neighborsEnrollerPeriodInMs",
-                "value" : "0"
-            }, {
-                "name"  : "maxEnrollmentRetries",
-                "value" : "0"
-            } ]
+    "enrollmentTaskConfiguration": {
+        "policySet": {
+            "name": "default",
+            "version": "1",
+            "parameters": [
+                {
+                    "name": "enrollTimeoutInMs",
+                    "value": "10000"
+                }, {
+                    "name": "watchdogPeriodInMs",
+                    "value": "30000"
+                }, {
+                    "name": "declaredDeadIntervalInMs",
+                    "value": "120000"
+                }, {
+                    "name": "neighborsEnrollerPeriodInMs",
+                    "value": "0"
+                }, {
+                    "name": "maxEnrollmentRetries",
+                    "value": "0"
+                }
+            ]
         }
-     },
+    },
 
-    "flowAllocatorConfiguration" : {
-        "policySet" : {
-            "name" : "default",
-            "version" : "1"
+    "flowAllocatorConfiguration": {
+        "policySet": {
+            "name": "default",
+            "version": "1"
         }
     },
 
-    "namespaceManagerConfiguration" : {
-        "policySet" : {
-            "name" : "default",
-            "version" : "1"
+    "namespaceManagerConfiguration": {
+        "policySet": {
+            "name": "default",
+            "version": "1"
         }
     },
 
-    "securityManagerConfiguration" : {
-        "policySet" : {
-            "name" : "default",
-            "version" : "1"
+    "securityManagerConfiguration": {
+        "policySet": {
+            "name": "default",
+            "version": "1"
         }
     },
 
-    "resourceAllocatorConfiguration" : {
-        "pduftgConfiguration" : {
-            "policySet" : {
-                "name" : "default",
-                "version" : "0"
+    "resourceAllocatorConfiguration": {
+        "pduftgConfiguration": {
+            "policySet": {
+                "name": "default",
+                "version": "0"
             }
         }
     },
 
-    "routingConfiguration" : {
-        "policySet" : {
-            "name" : "link-state",
-            "version" : "1",
-            "parameters" : [ {
-                    "name"  : "objectMaximumAge",
-                    "value" : "10000"
-                },{
-                    "name"  : "waitUntilReadCDAP",
-                    "value" : "5001"
-                },{
-                    "name"  : "waitUntilError",
-                    "value" : "5001"
-                },{
-                    "name"  : "waitUntilPDUFTComputation",
-                    "value" : "103"
-                },{
-                    "name"  : "waitUntilFSODBPropagation",
-                    "value" : "101"
-                },{
-                    "name"  : "waitUntilAgeIncrement",
-                    "value" : "997"
-                },{
-                    "name"  : "routingAlgorithm",
-                    "value" : "Dijkstra"
-                }]
+    "routingConfiguration": {
+        "policySet": {
+            "name": "link-state",
+            "version": "1",
+            "parameters": [
+                {
+                    "name": "objectMaximumAge",
+                    "value": "10000"
+                }, {
+                    "name": "waitUntilReadCDAP",
+                    "value": "5001"
+                }, {
+                    "name": "waitUntilError",
+                    "value": "5001"
+                }, {
+                    "name": "waitUntilPDUFTComputation",
+                    "value": "103"
+                }, {
+                    "name": "waitUntilFSODBPropagation",
+                    "value": "101"
+                }, {
+                    "name": "waitUntilAgeIncrement",
+                    "value": "997"
+                }, {
+                    "name": "routingAlgorithm",
+                    "value": "Dijkstra"
+                }
+            ]
         }
     }
 }
@@ -237,10 +245,12 @@ def ps_set(d, k, v, parms):
                         d[k]["parameters"][i]["value"] = value
                         break
             else:
-                d[k]["parameters"].append({ 'name': name, 'value': value })
+                d[k]["parameters"].append({'name': name, 'value': value})
 
     elif len(parms) > 0:
-        d[k]["parameters"] = [ { 'name': p.split('=')[0], 'value': p.split('=')[1]} for p in parms ]
+        d[k]["parameters"] = [
+            {'name': p.split('=')[0], 'value': p.split('=')[1]}
+            for p in parms]
 
     d[k]["name"] = v
 
@@ -252,7 +262,8 @@ def dtp_ps_set(d, v, parms):
 
 def dtcp_ps_set(d, v, parms):
     for i in range(len(d["qosCubes"])):
-        ps_set(d["qosCubes"][i]["efcpPolicies"]["dtcpConfiguration"], "dtcpPolicySet", v, parms)
+        ps_set(d["qosCubes"][i]["efcpPolicies"]["dtcpConfiguration"],
+               "dtcpPolicySet", v, parms)
 
 
 policy_translator = {
@@ -267,7 +278,8 @@ policy_translator = {
         d["namespaceManagerConfiguration"], "policySet", v, p),
     'security-manager': lambda d, v, p: ps_set(
         d["securityManagerConfiguration"], "policySet", v, p),
-    'routing': lambda d, v, p: ps_set(d["routingConfiguration"], "policySet", v, p),
+    'routing': lambda d, v, p: ps_set(
+        d["routingConfiguration"], "policySet", v, p),
     'resource-allocator.pduftg': lambda d, v, p: ps_set(
         d["resourceAllocatorConfiguration"], "policySet", v, p),
     'efcp.*.dtcp': None,
@@ -308,7 +320,7 @@ def translate_security_path(d, path, ps, parms):
 
         ps_set(d["default"], tr[component], ps, parms)
 
-    else: # profile is the name of a DIF
+    else:  # profile is the name of a DIF
         if "specific" not in d:
             d["specific"] = []
         j = -1
@@ -317,14 +329,14 @@ def translate_security_path(d, path, ps, parms):
                 j = i
                 break
 
-        if j == -1: # We need to create an entry for the new DIF
-            d["specific"].append({"underlyingDIF" : profile + ".DIF"})
+        if j == -1:  # We need to create an entry for the new DIF
+            d["specific"].append({"underlyingDIF": profile + ".DIF"})
 
         ps_set(d["specific"][j], tr[component], ps, parms)
 
 
 def translate_policy(difconf, path, ps, parms):
-    if path =='efcp.*.dtcp':
+    if path == 'efcp.*.dtcp':
         dtcp_ps_set(difconf, ps, parms)
 
     elif path == 'efcp.*.dtp':
@@ -335,4 +347,3 @@ def translate_policy(difconf, path, ps, parms):
 
     else:
         policy_translator[path](difconf, ps, parms)
-
diff --git a/rumba/testbeds/qemu.py b/rumba/testbeds/qemu.py
index d3e1698..8ccc704 100644
--- a/rumba/testbeds/qemu.py
+++ b/rumba/testbeds/qemu.py
@@ -76,6 +76,8 @@ class Testbed(mod.Testbed):
             results_queue.put("Command chain ran with %d errors" % errors)
 
     def recover_if_names(self, experiment):
+        next_vlan = 10
+        assigned_vlan = {}
         for node in experiment.nodes:
             for ipcp in node.ipcps:
                 if isinstance(ipcp, mod.ShimEthIPCP):
@@ -88,16 +90,20 @@ class Testbed(mod.Testbed):
                     mac = '00:0a:0a:0a:%02x:%02x' % (vm_id, port_id)
                     print('DEBUG: recovering ifname for port: '
                           + port['tap_id'] + '.')
-                    output = ssh_support.return_commands(
+                    output = ssh_support.execute_command(
                         self,
                         node.ssh_config,
-                        ['mac2ifname ' + mac])
-                    print('DEBUG: output is %s' % output)
-                    if not hasattr(output, '__len__') or len(output) != 1:
-                        raise Exception("Could not retrieve ifname for ipcp %s."
-                                        % ipcp.name)
-                    ipcp.ifname = output[0]
-                    args = {'vlan': int(port['shim'].name), 'port': ipcp.ifname}
+                        'mac2ifname ' + mac)
+                    ipcp.ifname = output
+                    try:
+                        vlan = int(port['shim'].name)
+                    except ValueError:
+                        vlan = assigned_vlan.get(port['shim'].name, None)
+                        if vlan is None:
+                            vlan = next_vlan
+                            next_vlan += 10
+                            assigned_vlan[port['shim'].name] = vlan
+                    args = {'vlan': vlan, 'port': ipcp.ifname}
                     cmds = ['ip link set %(port)s up'
                             % args,
                             'ip link add link %(port)s name %(port)s.%(vlan)s '
@@ -109,7 +115,6 @@ class Testbed(mod.Testbed):
                                                  node.ssh_config,
                                                  cmds)
 
-
     def swap_in(self, experiment):
         """
         :type experiment mod.Experiment
@@ -303,6 +308,10 @@ class Testbed(mod.Testbed):
             print('Sleeping %s secs waiting for the last VMs to boot' % tsleep)
             time.sleep(tsleep)
 
+        # TODO: to be removed, we should loop in the ssh part
+        print('Sleeping 5 seconds, just to be on the safe side')
+        time.sleep(5)
+
         self.recover_if_names(experiment)
 
     def swap_out(self, experiment):
diff --git a/tools/dc-vpns.conf b/tools/dc-vpns.conf
new file mode 100644
index 0000000..8bfde51
--- /dev/null
+++ b/tools/dc-vpns.conf
@@ -0,0 +1,114 @@
+eth 110 100Mbps tor1 spine1
+eth 120 100Mbps tor1 spine2
+eth 11 25Mbps s11 tor1
+eth 12 25Mbps s12 tor1
+eth 13 25Mbps s13 tor1
+eth 14 25Mbps s14 tor1
+eth 15 25Mbps s15 tor1
+eth 16 25Mbps s16 tor1
+eth 17 25Mbps s17 tor1
+eth 18 25Mbps s18 tor1
+eth 210 100Mbps tor2 spine1
+eth 220 100Mbps tor2 spine2
+eth 21 25Mbps s21 tor2
+eth 22 25Mbps s22 tor2
+eth 23 25Mbps s23 tor2
+eth 24 25Mbps s24 tor2
+eth 25 25Mbps s25 tor2
+eth 26 25Mbps s26 tor2
+eth 27 25Mbps s27 tor2
+eth 28 25Mbps s28 tor2
+eth 310 100Mbps tor3 spine1
+eth 320 100Mbps tor3 spine2
+eth 31 25Mbps s31 tor3
+eth 32 25Mbps s32 tor3
+eth 33 25Mbps s33 tor3
+eth 34 25Mbps s34 tor3
+eth 35 25Mbps s35 tor3
+eth 36 25Mbps s36 tor3
+eth 37 25Mbps s37 tor3
+eth 38 25Mbps s38 tor3
+eth 410 100Mbps tor4 spine1
+eth 420 100Mbps tor4 spine2
+eth 41 25Mbps s41 tor4
+eth 42 25Mbps s42 tor4
+eth 43 25Mbps s43 tor4
+eth 44 25Mbps s44 tor4
+eth 45 25Mbps s45 tor4
+eth 46 25Mbps s46 tor4
+eth 47 25Mbps s47 tor4
+eth 48 25Mbps s48 tor4
+
+# DIF dcfabric  
+dif dcfabric tor1 110 120
+dif dcfabric tor2 210 220
+dif dcfabric tor3 310 320
+dif dcfabric tor4 410 420
+dif dcfabric spine1 110 210 310 410
+dif dcfabric spine2 120 220 320 420
+
+# DIF VPN1
+dif vpn1 s11 11
+dif vpn1 s12 12
+dif vpn1 s13 13
+dif vpn1 s14 14
+dif vpn1 tor1 11 12 13 14 dcfabric
+dif vpn1 s21 21
+dif vpn1 s22 22
+dif vpn1 s23 23
+dif vpn1 s24 24
+dif vpn1 tor2 21 22 23 24 dcfabric
+
+# DIF VPN2
+dif vpn2 s31 31
+dif vpn2 s32 32
+dif vpn2 s33 33
+dif vpn2 s34 34
+dif vpn2 tor3 31 32 33 34 dcfabric
+dif vpn2 s41 41
+dif vpn2 s42 42
+dif vpn2 s43 43
+dif vpn2 s44 44
+dif vpn2 tor4 41 42 43 44 dcfabric
+
+# DIF VPN3
+dif vpn3 s15 15
+dif vpn3 s16 16
+dif vpn3 s17 17
+dif vpn3 s18 18
+dif vpn3 tor1 15 16 17 18 dcfabric
+dif vpn3 s25 25
+dif vpn3 s26 26
+dif vpn3 s27 27
+dif vpn3 s28 28
+dif vpn3 tor2 25 26 27 28  dcfabric
+
+# DIF VPN4
+dif vpn4 s35 35
+dif vpn4 s36 36
+dif vpn4 s37 37
+dif vpn4 s38 38
+dif vpn4 tor3 35 36 37 38 dcfabric
+dif vpn4 s45 45
+dif vpn4 s46 46
+dif vpn4 s47 47
+dif vpn4 s48 48
+dif vpn4 tor4 45 46 47 48 dcfabric
+
+#Policies
+
+#Multipath FABRIC
+#policy dcfabric spine1,spine2 rmt.pff multipath
+#policy dcfabric spine1,spine2 routing link-state routingAlgorithm=ECMPDijkstra
+#policy dcfabric * rmt cas-ps q_max=1000
+#policy dcfabric * efcp.*.dtcp cas-ps
+
+#Application to DIF mappings
+#appmap vpn1 traffic.generator.server 1
+#appmap vpn1 rina.apps.echotime.server 1
+#appmap vpn2 traffic.generator.server 1
+#appmap vpn2 rina.apps.echotime.server 1
+#appmap vpn3 traffic.generator.server 1
+#appmap vpn3 rina.apps.echotime.server 1
+#appmap vpn4 traffic.generator.server 1
+#appmap vpn4 rina.apps.echotime.server 1
diff --git a/tools/democonf2rumba.py b/tools/democonf2rumba.py
index d9ea8e7..c708e8e 100755
--- a/tools/democonf2rumba.py
+++ b/tools/democonf2rumba.py
@@ -90,8 +90,7 @@ def make_experiment(filename, experiment_class, experiment_kwargs,
                                       'dif_registrations': {},
                                       'registrations': {}})
                 nodes[vm]['difs'].append(dif)
-                nodes[vm]['dif_registrations'] \
-                         [dif] = dif_list
+                nodes[vm]['dif_registrations'][dif] = dif_list
                 # It is not defined yet, per check above.
 
                 continue
diff --git a/tools/geant2-renumber.conf b/tools/geant2-renumber.conf
new file mode 100644
index 0000000..07c014c
--- /dev/null
+++ b/tools/geant2-renumber.conf
@@ -0,0 +1,86 @@
+eth 2000 100Mbps lisbon madrid
+eth 2001 100Mbps lisbon london
+eth 2002 100Mbps london dublin
+eth 2003 100Mbps london paris
+eth 2004 100Mbps london brussels
+eth 2005 100Mbps paris madrid
+eth 2006 100Mbps paris luxemburg
+eth 2007 100Mbps paris bern
+eth 2008 100Mbps madrid bern
+eth 2009 100Mbps bern roma
+eth 2010 100Mbps roma madrid
+eth 2011 100Mbps brussels amsterdam
+eth 2012 100Mbps roma valleta
+eth 2013 100Mbps amsterdam valleta
+eth 2014 100Mbps bern berlin
+eth 2015 100Mbps luxemburg berlin
+eth 2016 100Mbps amsterdam berlin
+eth 2017 100Mbps amsterdam copenhagen
+eth 2018 100Mbps berlin copenhagen
+eth 2019 100Mbps copenhagen oslo
+eth 2020 100Mbps oslo stockholm
+eth 2021 100Mbps stockholm copenhagen
+eth 2023 100Mbps copenhagen tallin
+eth 2024 100Mbps tallin riga
+eth 2025 100Mbps riga vilnius
+eth 2026 100Mbps vilnius warsaw
+eth 2027 100Mbps warsaw berlin
+eth 2028 100Mbps warsaw praha
+eth 2029 100Mbps berlin praha
+eth 2030 100Mbps berlin viena
+eth 2031 100Mbps praha viena
+eth 2032 100Mbps viena budapest
+eth 2034 100Mbps viena ljubljana
+eth 2035 100Mbps ljubljana zagreb
+eth 2036 100Mbps zagreb budapest
+eth 2037 100Mbps budapest sofia
+eth 2038 100Mbps viena athens
+eth 2039 100Mbps sofia athens
+eth 2040 100Mbps athens roma
+eth 2041 100Mbps sofia bucharest
+eth 2042 100Mbps bucharest budapest
+eth 2043 100Mbps athens nicosia
+eth 2044 100Mbps roma nicosia
+eth 2045 100Mbps sofia ankara
+eth 2046 100Mbps bucharest ankara
+eth 2047 100Mbps berlin moscow
+eth 2048 100Mbps copenhagen moscow
+eth 2049 100Mbps roma viena
+
+# DIF renumber  
+dif renumber lisbon 2000 2001
+dif renumber madrid 2000 2005
+dif renumber london 2001 2002 2003 2004
+dif renumber dublin 2002
+dif renumber paris 2003 2005 2006 2007
+dif renumber brussels 2004 2011
+dif renumber luxemburg 2006 2015
+dif renumber bern 2007 2008 2009 2014
+dif renumber roma 2009 2010 2012 2040 2044 2049
+dif renumber amsterdam 2011 2013 2016 2017
+dif renumber valleta 2012 2013
+dif renumber berlin 2014 2015 2016 2018 2027 2029 2030 2047
+dif renumber copenhagen 2017 2018 2019 2021 2023 2048
+dif renumber oslo 2019 2020
+dif renumber stockholm 2020 2021
+dif renumber tallin 2023 2024
+dif renumber riga 2024 2025
+dif renumber vilnius 2025 2026
+dif renumber warsaw 2026 2027 2028
+dif renumber praha 2028 2029 2031
+dif renumber viena 2030 2031 2032 2034 2038
+dif renumber budapest 2032 2036 2037 2042
+dif renumber athens 2038 2039 2040 2043
+dif renumber ljubljana 2034 2035
+dif renumber zagreb 2035 2036
+dif renumber sofia 2037 2039 2041 2045
+dif renumber bucharest 2041 2042 2046
+dif renumber nicosia 2043 2044
+dif renumber ankara 2045 2046
+dif renumber moscow 2047 2048
+
+#Policies
+
+#address-change
+policy renumber * namespace-manager address-change useNewTimeout=20001 deprecateOldTimeout=80001 changePeriod=120001 addressRange=100
+policy renumber * routing link-state objectMaximumAge=10000 waitUntilReadCDAP=5001 waitUntilError=5001 waitUntilPDUFTComputation=103 waitUntilFSODBPropagation=101 waitUntilAgeIncrement=997 waitUntilDeprecateAddress=20001 routingAlgorithm=Dijkstra
diff --git a/tools/insane-stacking.conf b/tools/insane-stacking.conf
new file mode 100644
index 0000000..8032fea
--- /dev/null
+++ b/tools/insane-stacking.conf
@@ -0,0 +1,29 @@
+eth 300 0Mbps a b
+
+# DIF n1 lays over shim DIF 300
+dif n1 a 300
+dif n1 b 300
+
+# n2 lays over n1
+dif n2 a n1
+dif n2 b n1
+
+# n3 lays over n2
+dif n3 a n2
+dif n3 b n2
+
+# n4 lays over n3
+dif n4 a n3
+dif n4 b n3
+
+# n5 lays over n4
+dif n5 a n4
+dif n5 b n4
+
+# n6 lays over n5
+dif n6 a n5
+dif n6 b n5
+
+# n7 lays over n6
+dif n7 a n6
+dif n7 b n6
diff --git a/tools/isp-sec.conf b/tools/isp-sec.conf
new file mode 100644
index 0000000..33a35a6
--- /dev/null
+++ b/tools/isp-sec.conf
@@ -0,0 +1,189 @@
+eth 110 0Mbps cpe11 ar1
+eth 120 0Mbps cpe12 ar1
+eth 130 0Mbps cpe13 ar1
+eth 210 0Mbps cpe21 ar2
+eth 220 0Mbps cpe22 ar2
+eth 230 0Mbps cpe23 ar2
+eth 310 0Mbps cpe31 ar3
+eth 320 0Mbps cpe32 ar3
+eth 330 0Mbps cpe33 ar3
+eth 100 0Mbps ar1 manpe1
+eth 200 0Mbps ar2 manpe1
+eth 300 0Mbps ar3 manpe2
+eth 410 0Mbps manpe1 manpe2
+eth 411 0Mbps manpe1 manpe3
+eth 412 0Mbps manpe1 manpe4
+eth 420 0Mbps manpe2 manpe3
+eth 421 0Mbps manpe2 manpe4
+eth 430 0Mbps manpe3 manpe4
+eth 510 0Mbps manpe3 ser1
+eth 520 0Mbps manpe4 ser2
+eth 600 0Mbps ser1 core1
+eth 610 0Mbps ser1 core2
+eth 620 0Mbps ser2 core1
+eth 630 0Mbps ser2 core2
+eth 700 0Mbps core1 core2
+eth 710 0Mbps core1 core3
+eth 720 0Mbps core2 core4
+eth 730 0Mbps core3 core4
+eth 640 0Mbps core3 edge1
+eth 650 0Mbps core4 edge1
+eth 660 0Mbps core3 edge2
+eth 670 0Mbps core4 edge2
+eth 800 0Mbps edge1 isp2
+eth 810 0Mbps edge1 isp3
+eth 820 0Mbps edge2 isp4
+eth 830 0Mbps edge2 isp5
+
+# DIF core
+dif core ser1 600 610
+dif core ser2 620 630
+dif core core1 600 620 700 710
+dif core core2 610 630 700 720
+dif core core3 640 660 710 730 
+dif core core4 650 670 720 730
+dif core edge1 640 650
+dif core edge2 660 670
+
+# DIF access
+dif access ar1 100
+dif access ar2 200
+dif access ar3 300
+dif access manpe1 100 200 410 411 412
+dif access manpe2 300 410 420 421
+dif access manpe3 411 420 430 510
+dif access manpe4 412 421 430 520
+dif access ser1 510
+dif access ser2 520
+
+# DIF service
+dif service ar1 access
+dif service ar2 access
+dif service ar3 access
+dif service ser1 access core
+dif service ser2 access core
+dif service edge1 core
+dif service edge2 core
+
+# DIF emall1
+dif emall1 cpe11 110
+dif emall1 cpe12 120
+dif emall1 cpe21 210
+dif emall1 cpe22 220
+dif emall1 cpe31 310
+dif emall1 ar1 110 120 service
+dif emall1 ar2 210 220 service
+dif emall1 ar3 310 service
+dif emall1 edge1 service 800
+dif emall1 edge2 service 820
+dif emall1 isp2 800
+dif emall1 isp4 820
+
+# DIF emall2
+dif emall2 cpe13 130
+dif emall2 cpe23 230
+dif emall2 cpe32 320
+dif emall2 cpe33 330
+dif emall2 ar1 130 service
+dif emall2 ar2 230 service
+dif emall2 ar3 320 330 service
+dif emall2 edge1 service 810
+dif emall2 edge2 service 830
+dif emall2 isp3 810
+dif emall2 isp5 830
+
+#policies
+policy emall1 * security-manager.auth.default PSOC_authentication-ssh2 keyExchangeAlg=EDH keystore=/creds/ssh2 keystorePass=test
+policy emall1 * security-manager.encrypt.default default encryptAlg=AES128 macAlg=SHA256 compressAlg=deflate 
+policy emall1 ar1,ar2,ar3,edge1,edge2 security-manager.auth.service PSOC_authentication-none
+policy emall2 * security-manager.auth.default PSOC_authentication-ssh2 keyExchangeAlg=EDH keystore=/creds/ssh2 keystorePass=test
+policy emall2 * security-manager.encrypt.default default encryptAlg=AES128 macAlg=SHA256 compressAlg=deflate
+policy emall2 ar1,ar2,ar3,edge1,edge2 security-manager.auth.service PSOC_authentication-none
+
+#Enrollments
+enroll access ar1 manpe1 100
+enroll access ar2 manpe1 200
+enroll access ar3 manpe2 300
+enroll access ser1 manpe3 510
+enroll access ser2 manpe4 520
+enroll access manpe1 manpe2 410
+enroll access manpe1 manpe3 411
+enroll access manpe1 manpe4 412
+enroll access manpe2 manpe3 420
+enroll access manpe2 manpe4 421
+enroll access manpe3 manpe4 430
+
+enroll core core1 core2 700
+enroll core core1 core3 710
+enroll core core2 core4 720
+enroll core core3 core4 730
+enroll core ser1 core1 600
+enroll core ser1 core2 610
+enroll core ser2 core1 620
+enroll core ser2 core2 630
+enroll core edge1 core3 640
+enroll core edge1 core4 650
+enroll core edge2 core3 660
+enroll core edge2 core4 670
+
+enroll service edge1 edge2 core
+enroll service edge1 ser1 core
+enroll service edge1 ser2 core
+enroll service edge2 ser1 core
+enroll service edge2 ser2 core
+enroll service ser1 ser2 core
+enroll service ar1 ser1 access
+enroll service ar1 ser2 access
+enroll service ar2 ser1 access
+enroll service ar2 ser2 access
+enroll service ar3 ser1 access
+enroll service ar3 ser2 access
+
+enroll emall1 cpe11 ar1 110
+enroll emall1 cpe12 ar1 120
+enroll emall1 cpe21 ar2 210
+enroll emall1 cpe22 ar2 220
+enroll emall1 cpe31 ar3 310
+enroll emall1 ar1 edge1 service
+enroll emall1 ar1 edge2 service
+enroll emall1 ar2 edge1 service
+enroll emall1 ar2 edge2 service
+enroll emall1 ar3 edge1 service
+enroll emall1 ar3 edge2 service
+enroll emall1 edge1 edge2 service
+enroll emall1 isp2 edge1 800
+enroll emall1 isp4 edge2 820
+
+enroll emall2 cpe13 ar1 130
+enroll emall2 cpe23 ar2 230
+enroll emall2 cpe32 ar3 320
+enroll emall2 cpe33 ar3 330
+enroll emall2 ar1 edge1 service
+enroll emall2 ar1 edge2 service
+enroll emall2 ar2 edge1 service
+enroll emall2 ar2 edge2 service
+enroll emall2 ar3 edge1 service
+enroll emall2 ar3 edge2 service
+enroll emall2 edge1 edge2 service
+enroll emall2 isp3 edge1 810
+enroll emall2 isp5 edge2 830
+
+#Overlays
+overlay ar1 overlays/ispsec/ar1
+overlay ar2 overlays/ispsec/ar2
+overlay ar3 overlays/ispsec/ar3
+overlay cpe11 overlays/ispsec/cpe11
+overlay cpe12 overlays/ispsec/cpe12
+overlay cpe13 overlays/ispsec/cpe13
+overlay cpe21 overlays/ispsec/cpe21
+overlay cpe22 overlays/ispsec/cpe22
+overlay cpe23 overlays/ispsec/cpe23
+overlay cpe31 overlays/ispsec/cpe31
+overlay cpe32 overlays/ispsec/cpe32
+overlay cpe33 overlays/ispsec/cpe33
+overlay edge1 overlays/ispsec/edge1
+overlay edge2 overlays/ispsec/edge2
+overlay isp2 overlays/ispsec/isp2
+overlay isp3 overlays/ispsec/isp3
+overlay isp4 overlays/ispsec/isp4
+overlay isp5 overlays/ispsec/isp5
diff --git a/tools/resilient-square.conf b/tools/resilient-square.conf
new file mode 100644
index 0000000..592b6a5
--- /dev/null
+++ b/tools/resilient-square.conf
@@ -0,0 +1,16 @@
+# a, b and c and d are connected through p2p shim DIFs, in circle.
+# Between a and c there is an additional diagonal link.
+eth 300 100Mbps a b
+eth 400 100Mbps b c
+eth 500 100Mbps c d
+eth 600 1Mbps   d a
+eth 700 100Mbps a c
+
+# DIF n1 spans over the p2p shim DIFs
+dif n1 a 300 600 700
+dif n1 b 300 400
+dif n1 c 400 500 700
+dif n1 d 500 600
+
+# Use LFA policy as PDU Forwarding Function
+policy n1 * rmt.pff lfa
diff --git a/tools/secure-two-layers.conf b/tools/secure-two-layers.conf
new file mode 100644
index 0000000..54c1da6
--- /dev/null
+++ b/tools/secure-two-layers.conf
@@ -0,0 +1,25 @@
+eth 300 0Mbps a b
+eth 400 0Mbps b c
+eth 500 0Mbps c d
+
+# DIF n1 spans a,b and c and runs over the shims
+dif n1 a 300
+dif n1 b 300 400
+dif n1 c 400
+
+# DIF n2 spans c and d and runs over the shims
+dif n2 c 500
+dif n2 d 500
+
+# DIF n3 spans over n1 and n2
+dif n3 a n1
+dif n3 c n1 n2
+dif n3 d n2
+
+policy n3 * security-manager.auth.default PSOC_authentication-ssh2 keyExchangeAlg=EDH keystore=/creds keystorePass=test
+policy n3 * security-manager.encrypt.default default encryptAlg=AES128 macAlg=SHA256 compressAlg=deflate
+policy n3 * security-manager.ttl.default default initialValue=50
+policy n3 * security-manager.errorcheck.default CRC32
+policy n3 * security-manager.auth.n1 PSOC_authentication-password password=kf05j.a1234.af0k
+policy n3 * security-manager.ttl.n1 default initialValue=50
+policy n3 * security-manager.errorcheck.n1 CRC32
diff --git a/tools/seven.conf b/tools/seven.conf
new file mode 100644
index 0000000..b25f476
--- /dev/null
+++ b/tools/seven.conf
@@ -0,0 +1,34 @@
+# This configuration realizes the following seven-nodes topology
+#
+# MA ---- MB ---- MC --- MD --- ME
+#                 |             |
+#                 MF            MG
+#
+
+# 300 is a shim-eth-vlan DIF, with nodes a and b
+eth 300 0Mbps a b
+
+# 400 is a shim-eth-vlan DIF, with nodes b and c
+eth 400 0Mbps b c
+
+# 500 is a shim-eth-vlan DIF, with nodes c and f
+eth 500 0Mbps c f
+
+# 600 is a shim-eth-vlan DIF, with nodes c and d
+eth 600 0Mbps c d
+
+# 700 is a shim-eth-vlan DIF, with nodes d and e
+eth 700 0Mbps d e
+
+# 800 is a shim-eth-vlan DIF, with nodes e and g
+eth 800 0Mbps e g
+
+# DIF n1 spans over the two shim DIFs
+dif n1 a 300
+dif n1 b 300 400
+dif n1 c 400 500 600
+dif n1 d 600 700
+dif n1 e 700 800
+dif n1 f 500
+dif n1 g 800
+
diff --git a/tools/star.conf b/tools/star.conf
new file mode 100644
index 0000000..8a4f6ab
--- /dev/null
+++ b/tools/star.conf
@@ -0,0 +1,7 @@
+# a,b and c are in the same L2 domain
+eth 300 0Mbps a b c
+
+# DIF n1 spans over the shim DIF
+dif n1 a 300
+dif n1 b 300
+dif n1 c 300
diff --git a/tools/triangle.conf b/tools/triangle.conf
new file mode 100644
index 0000000..f89811c
--- /dev/null
+++ b/tools/triangle.conf
@@ -0,0 +1,9 @@
+# a, b and c are connected through p2p shim DIFs
+eth 300 10Mbps a b
+eth 400 20Mbps b c
+eth 500 30Mbps a c
+
+# DIF n1 spans over the p2p shim DIFs
+dif n1 a 300 500
+dif n1 b 300 400
+dif n1 c 400 500
diff --git a/tools/tutorial1.conf b/tools/tutorial1.conf
new file mode 100644
index 0000000..8023687
--- /dev/null
+++ b/tools/tutorial1.conf
@@ -0,0 +1,4 @@
+eth 100 0Mbps system1 system2
+
+dif Normal system1 100
+dif Normal system2 100
diff --git a/tools/tutorial2.conf b/tools/tutorial2.conf
new file mode 100644
index 0000000..b43fc17
--- /dev/null
+++ b/tools/tutorial2.conf
@@ -0,0 +1,6 @@
+eth 100 0Mbps system1 system2
+eth 101 0Mbps system2 system3
+
+dif Normal system1 100
+dif Normal system2 100 101
+dif Normal system3 101
diff --git a/tools/two-layers.conf b/tools/two-layers.conf
new file mode 100644
index 0000000..dc1bab2
--- /dev/null
+++ b/tools/two-layers.conf
@@ -0,0 +1,17 @@
+eth 300 0Mbps a b
+eth 400 0Mbps b c
+eth 500 0Mbps c d
+
+# DIF n1 spans a,b and c and runs over the shims
+dif n1 a 300
+dif n1 b 300 400
+dif n1 c 400
+
+# DIF n2 spans c and d and runs over the shims
+dif n2 c 500
+dif n2 d 500
+
+# DIF n3 spans over n1 and n2
+dif n3 a n1
+dif n3 c n1 n2
+dif n3 d n2
-- 
cgit v1.2.3


From fad736c4c6a12e3f73f5d4e100f3f62d7f1467ae Mon Sep 17 00:00:00 2001
From: Marco Capitani <m.capitani@nextworks.it>
Date: Fri, 14 Apr 2017 12:47:32 +0200
Subject: IRATI: moved generated conf files in IRATI_conf folder

---
 rumba/prototypes/irati.py | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/rumba/prototypes/irati.py b/rumba/prototypes/irati.py
index dd7086e..edc49c6 100644
--- a/rumba/prototypes/irati.py
+++ b/rumba/prototypes/irati.py
@@ -53,6 +53,16 @@ class Experiment(mod.Experiment):
         else:
             self.sudo = self.real_sudo
 
+        self._conf_dir = os.path.join(os.getcwd(), 'IRATI_conf')
+        try:
+            os.mkdir(self._conf_dir)
+        except OSError:
+            # Already there, nothing to do
+            pass
+
+    def conf_dir(self, path):
+        return os.path.join(self._conf_dir, path)
+
     def setup(self):
         """Installs IRATI on the vms."""
         setup_irati = False
@@ -104,6 +114,8 @@ class Experiment(mod.Experiment):
                 [gen_files_conf, 'normal.%(name)s.*.dif' % {'name': name}])
         dir_path = os.path.dirname(os.path.abspath(__file__))
         gen_files_bin = 'enroll.py'
+        gen_files_conf_full = \
+            ' '.join([self.conf_dir(x) for x in gen_files_conf.split()])
         gen_files_bin_full = os.path.join(dir_path, 'enroll.py')
 
         ipcm_components = ['scripting', 'console']
@@ -111,7 +123,7 @@ class Experiment(mod.Experiment):
             ipcm_components.append('mad')
         ipcm_components = ', '.join(ipcm_components)
 
-        gen_files = ' '.join([gen_files_conf, gen_files_bin_full])
+        gen_files = ' '.join([gen_files_conf_full, gen_files_bin_full])
 
         sshopts = ('-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
                    ' -o IdentityFile=%s'
@@ -270,11 +282,11 @@ class Experiment(mod.Experiment):
                         "difName": shim.name
                     })
 
-                    template_file_name = 'shimeth.%s.%s.dif' \
-                                         % (node.name, shim.name)
+                    template_file_name = self.conf_dir('shimeth.%s.%s.dif'
+                                                       % (node.name, shim.name))
                     ipcmconf["difConfigurations"].append({
                         "name": shim.name,
-                        "template": template_file_name
+                        "template": os.path.basename(template_file_name)
                     })
 
                     fout = open(template_file_name, 'w')
@@ -334,7 +346,7 @@ class Experiment(mod.Experiment):
                         difconfs[dif.name][node_name], path, ps, parms=[])
 
         # Dump the DIF Allocator map
-        with open('da.map', 'w') as da_map_file:
+        with open(self.conf_dir('da.map'), 'w') as da_map_file:
             json.dump(irati_templates.da_map_base,
                       da_map_file,
                       indent=4,
@@ -342,7 +354,8 @@ class Experiment(mod.Experiment):
 
         for node in self.nodes:
             # Dump the IPCM configuration files
-            with open('%s.ipcm.conf' % (node.name,), 'w') as node_file:
+            with open(self.conf_dir('%s.ipcm.conf'
+                                    % (node.name,)), 'w') as node_file:
                 json.dump(ipcmconfs[node.name],
                           node_file,
                           indent=4,
@@ -353,7 +366,8 @@ class Experiment(mod.Experiment):
             if dif_conf:
                 # Dump the normal DIF configuration files
                 for node in dif.members:
-                    with open('normal.%s.%s.dif' % (node.name, dif.name), 'w') \
+                    with open(self.conf_dir('normal.%s.%s.dif'
+                                            % (node.name, dif.name)), 'w') \
                             as dif_conf_file:
                         json.dump(dif_conf[node.name],
                                   dif_conf_file,
-- 
cgit v1.2.3


From 2f423e0282975b753f6686654f3adc0f535d23d7 Mon Sep 17 00:00:00 2001
From: Marco Capitani <m.capitani@nextworks.it>
Date: Fri, 14 Apr 2017 15:18:28 +0200
Subject: Tester: moving example .conf files

---
 tools/conf-examples/dc-vpns.conf           | 114 +++++++++++++++++
 tools/conf-examples/geant2-renumber.conf   |  86 +++++++++++++
 tools/conf-examples/insane-stacking.conf   |  29 +++++
 tools/conf-examples/isp-sec.conf           | 189 +++++++++++++++++++++++++++++
 tools/conf-examples/resilient-square.conf  |  16 +++
 tools/conf-examples/secure-two-layers.conf |  25 ++++
 tools/conf-examples/seven.conf             |  34 ++++++
 tools/conf-examples/star.conf              |   7 ++
 tools/conf-examples/triangle.conf          |   9 ++
 tools/conf-examples/tutorial1.conf         |   4 +
 tools/conf-examples/tutorial2.conf         |   6 +
 tools/conf-examples/two-layers.conf        |  17 +++
 tools/dc-vpns.conf                         | 114 -----------------
 tools/geant2-renumber.conf                 |  86 -------------
 tools/insane-stacking.conf                 |  29 -----
 tools/isp-sec.conf                         | 189 -----------------------------
 tools/resilient-square.conf                |  16 ---
 tools/secure-two-layers.conf               |  25 ----
 tools/seven.conf                           |  34 ------
 tools/star.conf                            |   7 --
 tools/triangle.conf                        |   9 --
 tools/tutorial1.conf                       |   4 -
 tools/tutorial2.conf                       |   6 -
 tools/two-layers.conf                      |  17 ---
 24 files changed, 536 insertions(+), 536 deletions(-)
 create mode 100644 tools/conf-examples/dc-vpns.conf
 create mode 100644 tools/conf-examples/geant2-renumber.conf
 create mode 100644 tools/conf-examples/insane-stacking.conf
 create mode 100644 tools/conf-examples/isp-sec.conf
 create mode 100644 tools/conf-examples/resilient-square.conf
 create mode 100644 tools/conf-examples/secure-two-layers.conf
 create mode 100644 tools/conf-examples/seven.conf
 create mode 100644 tools/conf-examples/star.conf
 create mode 100644 tools/conf-examples/triangle.conf
 create mode 100644 tools/conf-examples/tutorial1.conf
 create mode 100644 tools/conf-examples/tutorial2.conf
 create mode 100644 tools/conf-examples/two-layers.conf
 delete mode 100644 tools/dc-vpns.conf
 delete mode 100644 tools/geant2-renumber.conf
 delete mode 100644 tools/insane-stacking.conf
 delete mode 100644 tools/isp-sec.conf
 delete mode 100644 tools/resilient-square.conf
 delete mode 100644 tools/secure-two-layers.conf
 delete mode 100644 tools/seven.conf
 delete mode 100644 tools/star.conf
 delete mode 100644 tools/triangle.conf
 delete mode 100644 tools/tutorial1.conf
 delete mode 100644 tools/tutorial2.conf
 delete mode 100644 tools/two-layers.conf

diff --git a/tools/conf-examples/dc-vpns.conf b/tools/conf-examples/dc-vpns.conf
new file mode 100644
index 0000000..8bfde51
--- /dev/null
+++ b/tools/conf-examples/dc-vpns.conf
@@ -0,0 +1,114 @@
+eth 110 100Mbps tor1 spine1
+eth 120 100Mbps tor1 spine2
+eth 11 25Mbps s11 tor1
+eth 12 25Mbps s12 tor1
+eth 13 25Mbps s13 tor1
+eth 14 25Mbps s14 tor1
+eth 15 25Mbps s15 tor1
+eth 16 25Mbps s16 tor1
+eth 17 25Mbps s17 tor1
+eth 18 25Mbps s18 tor1
+eth 210 100Mbps tor2 spine1
+eth 220 100Mbps tor2 spine2
+eth 21 25Mbps s21 tor2
+eth 22 25Mbps s22 tor2
+eth 23 25Mbps s23 tor2
+eth 24 25Mbps s24 tor2
+eth 25 25Mbps s25 tor2
+eth 26 25Mbps s26 tor2
+eth 27 25Mbps s27 tor2
+eth 28 25Mbps s28 tor2
+eth 310 100Mbps tor3 spine1
+eth 320 100Mbps tor3 spine2
+eth 31 25Mbps s31 tor3
+eth 32 25Mbps s32 tor3
+eth 33 25Mbps s33 tor3
+eth 34 25Mbps s34 tor3
+eth 35 25Mbps s35 tor3
+eth 36 25Mbps s36 tor3
+eth 37 25Mbps s37 tor3
+eth 38 25Mbps s38 tor3
+eth 410 100Mbps tor4 spine1
+eth 420 100Mbps tor4 spine2
+eth 41 25Mbps s41 tor4
+eth 42 25Mbps s42 tor4
+eth 43 25Mbps s43 tor4
+eth 44 25Mbps s44 tor4
+eth 45 25Mbps s45 tor4
+eth 46 25Mbps s46 tor4
+eth 47 25Mbps s47 tor4
+eth 48 25Mbps s48 tor4
+
+# DIF dcfabric  
+dif dcfabric tor1 110 120
+dif dcfabric tor2 210 220
+dif dcfabric tor3 310 320
+dif dcfabric tor4 410 420
+dif dcfabric spine1 110 210 310 410
+dif dcfabric spine2 120 220 320 420
+
+# DIF VPN1
+dif vpn1 s11 11
+dif vpn1 s12 12
+dif vpn1 s13 13
+dif vpn1 s14 14
+dif vpn1 tor1 11 12 13 14 dcfabric
+dif vpn1 s21 21
+dif vpn1 s22 22
+dif vpn1 s23 23
+dif vpn1 s24 24
+dif vpn1 tor2 21 22 23 24 dcfabric
+
+# DIF VPN2
+dif vpn2 s31 31
+dif vpn2 s32 32
+dif vpn2 s33 33
+dif vpn2 s34 34
+dif vpn2 tor3 31 32 33 34 dcfabric
+dif vpn2 s41 41
+dif vpn2 s42 42
+dif vpn2 s43 43
+dif vpn2 s44 44
+dif vpn2 tor4 41 42 43 44 dcfabric
+
+# DIF VPN3
+dif vpn3 s15 15
+dif vpn3 s16 16
+dif vpn3 s17 17
+dif vpn3 s18 18
+dif vpn3 tor1 15 16 17 18 dcfabric
+dif vpn3 s25 25
+dif vpn3 s26 26
+dif vpn3 s27 27
+dif vpn3 s28 28
+dif vpn3 tor2 25 26 27 28  dcfabric
+
+# DIF VPN4
+dif vpn4 s35 35
+dif vpn4 s36 36
+dif vpn4 s37 37
+dif vpn4 s38 38
+dif vpn4 tor3 35 36 37 38 dcfabric
+dif vpn4 s45 45
+dif vpn4 s46 46
+dif vpn4 s47 47
+dif vpn4 s48 48
+dif vpn4 tor4 45 46 47 48 dcfabric
+
+#Policies
+
+#Multipath FABRIC
+#policy dcfabric spine1,spine2 rmt.pff multipath
+#policy dcfabric spine1,spine2 routing link-state routingAlgorithm=ECMPDijkstra
+#policy dcfabric * rmt cas-ps q_max=1000
+#policy dcfabric * efcp.*.dtcp cas-ps
+
+#Application to DIF mappings
+#appmap vpn1 traffic.generator.server 1
+#appmap vpn1 rina.apps.echotime.server 1
+#appmap vpn2 traffic.generator.server 1
+#appmap vpn2 rina.apps.echotime.server 1
+#appmap vpn3 traffic.generator.server 1
+#appmap vpn3 rina.apps.echotime.server 1
+#appmap vpn4 traffic.generator.server 1
+#appmap vpn4 rina.apps.echotime.server 1
diff --git a/tools/conf-examples/geant2-renumber.conf b/tools/conf-examples/geant2-renumber.conf
new file mode 100644
index 0000000..07c014c
--- /dev/null
+++ b/tools/conf-examples/geant2-renumber.conf
@@ -0,0 +1,86 @@
+eth 2000 100Mbps lisbon madrid
+eth 2001 100Mbps lisbon london
+eth 2002 100Mbps london dublin
+eth 2003 100Mbps london paris
+eth 2004 100Mbps london brussels
+eth 2005 100Mbps paris madrid
+eth 2006 100Mbps paris luxemburg
+eth 2007 100Mbps paris bern
+eth 2008 100Mbps madrid bern
+eth 2009 100Mbps bern roma
+eth 2010 100Mbps roma madrid
+eth 2011 100Mbps brussels amsterdam
+eth 2012 100Mbps roma valleta
+eth 2013 100Mbps amsterdam valleta
+eth 2014 100Mbps bern berlin
+eth 2015 100Mbps luxemburg berlin
+eth 2016 100Mbps amsterdam berlin
+eth 2017 100Mbps amsterdam copenhagen
+eth 2018 100Mbps berlin copenhagen
+eth 2019 100Mbps copenhagen oslo
+eth 2020 100Mbps oslo stockholm
+eth 2021 100Mbps stockholm copenhagen
+eth 2023 100Mbps copenhagen tallin
+eth 2024 100Mbps tallin riga
+eth 2025 100Mbps riga vilnius
+eth 2026 100Mbps vilnius warsaw
+eth 2027 100Mbps warsaw berlin
+eth 2028 100Mbps warsaw praha
+eth 2029 100Mbps berlin praha
+eth 2030 100Mbps berlin viena
+eth 2031 100Mbps praha viena
+eth 2032 100Mbps viena budapest
+eth 2034 100Mbps viena ljubljana
+eth 2035 100Mbps ljubljana zagreb
+eth 2036 100Mbps zagreb budapest
+eth 2037 100Mbps budapest sofia
+eth 2038 100Mbps viena athens
+eth 2039 100Mbps sofia athens
+eth 2040 100Mbps athens roma
+eth 2041 100Mbps sofia bucharest
+eth 2042 100Mbps bucharest budapest
+eth 2043 100Mbps athens nicosia
+eth 2044 100Mbps roma nicosia
+eth 2045 100Mbps sofia ankara
+eth 2046 100Mbps bucharest ankara
+eth 2047 100Mbps berlin moscow
+eth 2048 100Mbps copenhagen moscow
+eth 2049 100Mbps roma viena
+
+# DIF renumber  
+dif renumber lisbon 2000 2001
+dif renumber madrid 2000 2005
+dif renumber london 2001 2002 2003 2004
+dif renumber dublin 2002
+dif renumber paris 2003 2005 2006 2007
+dif renumber brussels 2004 2011
+dif renumber luxemburg 2006 2015
+dif renumber bern 2007 2008 2009 2014
+dif renumber roma 2009 2010 2012 2040 2044 2049
+dif renumber amsterdam 2011 2013 2016 2017
+dif renumber valleta 2012 2013
+dif renumber berlin 2014 2015 2016 2018 2027 2029 2030 2047
+dif renumber copenhagen 2017 2018 2019 2021 2023 2048
+dif renumber oslo 2019 2020
+dif renumber stockholm 2020 2021
+dif renumber tallin 2023 2024
+dif renumber riga 2024 2025
+dif renumber vilnius 2025 2026
+dif renumber warsaw 2026 2027 2028
+dif renumber praha 2028 2029 2031
+dif renumber viena 2030 2031 2032 2034 2038
+dif renumber budapest 2032 2036 2037 2042
+dif renumber athens 2038 2039 2040 2043
+dif renumber ljubljana 2034 2035
+dif renumber zagreb 2035 2036
+dif renumber sofia 2037 2039 2041 2045
+dif renumber bucharest 2041 2042 2046
+dif renumber nicosia 2043 2044
+dif renumber ankara 2045 2046
+dif renumber moscow 2047 2048
+
+#Policies
+
+#address-change
+policy renumber * namespace-manager address-change useNewTimeout=20001 deprecateOldTimeout=80001 changePeriod=120001 addressRange=100
+policy renumber * routing link-state objectMaximumAge=10000 waitUntilReadCDAP=5001 waitUntilError=5001 waitUntilPDUFTComputation=103 waitUntilFSODBPropagation=101 waitUntilAgeIncrement=997 waitUntilDeprecateAddress=20001 routingAlgorithm=Dijkstra
diff --git a/tools/conf-examples/insane-stacking.conf b/tools/conf-examples/insane-stacking.conf
new file mode 100644
index 0000000..8032fea
--- /dev/null
+++ b/tools/conf-examples/insane-stacking.conf
@@ -0,0 +1,29 @@
+eth 300 0Mbps a b
+
+# DIF n1 lays over shim DIF 300
+dif n1 a 300
+dif n1 b 300
+
+# n2 lays over n1
+dif n2 a n1
+dif n2 b n1
+
+# n3 lays over n2
+dif n3 a n2
+dif n3 b n2
+
+# n4 lays over n3
+dif n4 a n3
+dif n4 b n3
+
+# n5 lays over n4
+dif n5 a n4
+dif n5 b n4
+
+# n6 lays over n5
+dif n6 a n5
+dif n6 b n5
+
+# n7 lays over n6
+dif n7 a n6
+dif n7 b n6
diff --git a/tools/conf-examples/isp-sec.conf b/tools/conf-examples/isp-sec.conf
new file mode 100644
index 0000000..33a35a6
--- /dev/null
+++ b/tools/conf-examples/isp-sec.conf
@@ -0,0 +1,189 @@
+eth 110 0Mbps cpe11 ar1
+eth 120 0Mbps cpe12 ar1
+eth 130 0Mbps cpe13 ar1
+eth 210 0Mbps cpe21 ar2
+eth 220 0Mbps cpe22 ar2
+eth 230 0Mbps cpe23 ar2
+eth 310 0Mbps cpe31 ar3
+eth 320 0Mbps cpe32 ar3
+eth 330 0Mbps cpe33 ar3
+eth 100 0Mbps ar1 manpe1
+eth 200 0Mbps ar2 manpe1
+eth 300 0Mbps ar3 manpe2
+eth 410 0Mbps manpe1 manpe2
+eth 411 0Mbps manpe1 manpe3
+eth 412 0Mbps manpe1 manpe4
+eth 420 0Mbps manpe2 manpe3
+eth 421 0Mbps manpe2 manpe4
+eth 430 0Mbps manpe3 manpe4
+eth 510 0Mbps manpe3 ser1
+eth 520 0Mbps manpe4 ser2
+eth 600 0Mbps ser1 core1
+eth 610 0Mbps ser1 core2
+eth 620 0Mbps ser2 core1
+eth 630 0Mbps ser2 core2
+eth 700 0Mbps core1 core2
+eth 710 0Mbps core1 core3
+eth 720 0Mbps core2 core4
+eth 730 0Mbps core3 core4
+eth 640 0Mbps core3 edge1
+eth 650 0Mbps core4 edge1
+eth 660 0Mbps core3 edge2
+eth 670 0Mbps core4 edge2
+eth 800 0Mbps edge1 isp2
+eth 810 0Mbps edge1 isp3
+eth 820 0Mbps edge2 isp4
+eth 830 0Mbps edge2 isp5
+
+# DIF core
+dif core ser1 600 610
+dif core ser2 620 630
+dif core core1 600 620 700 710
+dif core core2 610 630 700 720
+dif core core3 640 660 710 730 
+dif core core4 650 670 720 730
+dif core edge1 640 650
+dif core edge2 660 670
+
+# DIF access
+dif access ar1 100
+dif access ar2 200
+dif access ar3 300
+dif access manpe1 100 200 410 411 412
+dif access manpe2 300 410 420 421
+dif access manpe3 411 420 430 510
+dif access manpe4 412 421 430 520
+dif access ser1 510
+dif access ser2 520
+
+# DIF service
+dif service ar1 access
+dif service ar2 access
+dif service ar3 access
+dif service ser1 access core
+dif service ser2 access core
+dif service edge1 core
+dif service edge2 core
+
+# DIF emall1
+dif emall1 cpe11 110
+dif emall1 cpe12 120
+dif emall1 cpe21 210
+dif emall1 cpe22 220
+dif emall1 cpe31 310
+dif emall1 ar1 110 120 service
+dif emall1 ar2 210 220 service
+dif emall1 ar3 310 service
+dif emall1 edge1 service 800
+dif emall1 edge2 service 820
+dif emall1 isp2 800
+dif emall1 isp4 820
+
+# DIF emall2
+dif emall2 cpe13 130
+dif emall2 cpe23 230
+dif emall2 cpe32 320
+dif emall2 cpe33 330
+dif emall2 ar1 130 service
+dif emall2 ar2 230 service
+dif emall2 ar3 320 330 service
+dif emall2 edge1 service 810
+dif emall2 edge2 service 830
+dif emall2 isp3 810
+dif emall2 isp5 830
+
+#policies
+policy emall1 * security-manager.auth.default PSOC_authentication-ssh2 keyExchangeAlg=EDH keystore=/creds/ssh2 keystorePass=test
+policy emall1 * security-manager.encrypt.default default encryptAlg=AES128 macAlg=SHA256 compressAlg=deflate 
+policy emall1 ar1,ar2,ar3,edge1,edge2 security-manager.auth.service PSOC_authentication-none
+policy emall2 * security-manager.auth.default PSOC_authentication-ssh2 keyExchangeAlg=EDH keystore=/creds/ssh2 keystorePass=test
+policy emall2 * security-manager.encrypt.default default encryptAlg=AES128 macAlg=SHA256 compressAlg=deflate
+policy emall2 ar1,ar2,ar3,edge1,edge2 security-manager.auth.service PSOC_authentication-none
+
+#Enrollments
+enroll access ar1 manpe1 100
+enroll access ar2 manpe1 200
+enroll access ar3 manpe2 300
+enroll access ser1 manpe3 510
+enroll access ser2 manpe4 520
+enroll access manpe1 manpe2 410
+enroll access manpe1 manpe3 411
+enroll access manpe1 manpe4 412
+enroll access manpe2 manpe3 420
+enroll access manpe2 manpe4 421
+enroll access manpe3 manpe4 430
+
+enroll core core1 core2 700
+enroll core core1 core3 710
+enroll core core2 core4 720
+enroll core core3 core4 730
+enroll core ser1 core1 600
+enroll core ser1 core2 610
+enroll core ser2 core1 620
+enroll core ser2 core2 630
+enroll core edge1 core3 640
+enroll core edge1 core4 650
+enroll core edge2 core3 660
+enroll core edge2 core4 670
+
+enroll service edge1 edge2 core
+enroll service edge1 ser1 core
+enroll service edge1 ser2 core
+enroll service edge2 ser1 core
+enroll service edge2 ser2 core
+enroll service ser1 ser2 core
+enroll service ar1 ser1 access
+enroll service ar1 ser2 access
+enroll service ar2 ser1 access
+enroll service ar2 ser2 access
+enroll service ar3 ser1 access
+enroll service ar3 ser2 access
+
+enroll emall1 cpe11 ar1 110
+enroll emall1 cpe12 ar1 120
+enroll emall1 cpe21 ar2 210
+enroll emall1 cpe22 ar2 220
+enroll emall1 cpe31 ar3 310
+enroll emall1 ar1 edge1 service
+enroll emall1 ar1 edge2 service
+enroll emall1 ar2 edge1 service
+enroll emall1 ar2 edge2 service
+enroll emall1 ar3 edge1 service
+enroll emall1 ar3 edge2 service
+enroll emall1 edge1 edge2 service
+enroll emall1 isp2 edge1 800
+enroll emall1 isp4 edge2 820
+
+enroll emall2 cpe13 ar1 130
+enroll emall2 cpe23 ar2 230
+enroll emall2 cpe32 ar3 320
+enroll emall2 cpe33 ar3 330
+enroll emall2 ar1 edge1 service
+enroll emall2 ar1 edge2 service
+enroll emall2 ar2 edge1 service
+enroll emall2 ar2 edge2 service
+enroll emall2 ar3 edge1 service
+enroll emall2 ar3 edge2 service
+enroll emall2 edge1 edge2 service
+enroll emall2 isp3 edge1 810
+enroll emall2 isp5 edge2 830
+
+#Overlays
+overlay ar1 overlays/ispsec/ar1
+overlay ar2 overlays/ispsec/ar2
+overlay ar3 overlays/ispsec/ar3
+overlay cpe11 overlays/ispsec/cpe11
+overlay cpe12 overlays/ispsec/cpe12
+overlay cpe13 overlays/ispsec/cpe13
+overlay cpe21 overlays/ispsec/cpe21
+overlay cpe22 overlays/ispsec/cpe22
+overlay cpe23 overlays/ispsec/cpe23
+overlay cpe31 overlays/ispsec/cpe31
+overlay cpe32 overlays/ispsec/cpe32
+overlay cpe33 overlays/ispsec/cpe33
+overlay edge1 overlays/ispsec/edge1
+overlay edge2 overlays/ispsec/edge2
+overlay isp2 overlays/ispsec/isp2
+overlay isp3 overlays/ispsec/isp3
+overlay isp4 overlays/ispsec/isp4
+overlay isp5 overlays/ispsec/isp5
diff --git a/tools/conf-examples/resilient-square.conf b/tools/conf-examples/resilient-square.conf
new file mode 100644
index 0000000..592b6a5
--- /dev/null
+++ b/tools/conf-examples/resilient-square.conf
@@ -0,0 +1,16 @@
+# a, b and c and d are connected through p2p shim DIFs, in circle.
+# Between a and c there is an additional diagonal link.
+eth 300 100Mbps a b
+eth 400 100Mbps b c
+eth 500 100Mbps c d
+eth 600 1Mbps   d a
+eth 700 100Mbps a c
+
+# DIF n1 spans over the p2p shim DIFs
+dif n1 a 300 600 700
+dif n1 b 300 400
+dif n1 c 400 500 700
+dif n1 d 500 600
+
+# Use LFA policy as PDU Forwarding Function
+policy n1 * rmt.pff lfa
diff --git a/tools/conf-examples/secure-two-layers.conf b/tools/conf-examples/secure-two-layers.conf
new file mode 100644
index 0000000..54c1da6
--- /dev/null
+++ b/tools/conf-examples/secure-two-layers.conf
@@ -0,0 +1,25 @@
+eth 300 0Mbps a b
+eth 400 0Mbps b c
+eth 500 0Mbps c d
+
+# DIF n1 spans a,b and c and runs over the shims
+dif n1 a 300
+dif n1 b 300 400
+dif n1 c 400
+
+# DIF n2 spans c and d and runs over the shims
+dif n2 c 500
+dif n2 d 500
+
+# DIF n3 spans over n1 and n2
+dif n3 a n1
+dif n3 c n1 n2
+dif n3 d n2
+
+policy n3 * security-manager.auth.default PSOC_authentication-ssh2 keyExchangeAlg=EDH keystore=/creds keystorePass=test
+policy n3 * security-manager.encrypt.default default encryptAlg=AES128 macAlg=SHA256 compressAlg=deflate
+policy n3 * security-manager.ttl.default default initialValue=50
+policy n3 * security-manager.errorcheck.default CRC32
+policy n3 * security-manager.auth.n1 PSOC_authentication-password password=kf05j.a1234.af0k
+policy n3 * security-manager.ttl.n1 default initialValue=50
+policy n3 * security-manager.errorcheck.n1 CRC32
diff --git a/tools/conf-examples/seven.conf b/tools/conf-examples/seven.conf
new file mode 100644
index 0000000..b25f476
--- /dev/null
+++ b/tools/conf-examples/seven.conf
@@ -0,0 +1,34 @@
+# This configuration realizes the following seven-nodes topology
+#
+# MA ---- MB ---- MC --- MD --- ME
+#                 |             |
+#                 MF            MG
+#
+
+# 300 is a shim-eth-vlan DIF, with nodes a and b
+eth 300 0Mbps a b
+
+# 400 is a shim-eth-vlan DIF, with nodes b and c
+eth 400 0Mbps b c
+
+# 500 is a shim-eth-vlan DIF, with nodes c and f
+eth 500 0Mbps c f
+
+# 600 is a shim-eth-vlan DIF, with nodes c and d
+eth 600 0Mbps c d
+
+# 700 is a shim-eth-vlan DIF, with nodes d and e
+eth 700 0Mbps d e
+
+# 800 is a shim-eth-vlan DIF, with nodes e and g
+eth 800 0Mbps e g
+
+# DIF n1 spans over the two shim DIFs
+dif n1 a 300
+dif n1 b 300 400
+dif n1 c 400 500 600
+dif n1 d 600 700
+dif n1 e 700 800
+dif n1 f 500
+dif n1 g 800
+
diff --git a/tools/conf-examples/star.conf b/tools/conf-examples/star.conf
new file mode 100644
index 0000000..8a4f6ab
--- /dev/null
+++ b/tools/conf-examples/star.conf
@@ -0,0 +1,7 @@
+# a,b and c are in the same L2 domain
+eth 300 0Mbps a b c
+
+# DIF n1 spans over the shim DIF
+dif n1 a 300
+dif n1 b 300
+dif n1 c 300
diff --git a/tools/conf-examples/triangle.conf b/tools/conf-examples/triangle.conf
new file mode 100644
index 0000000..f89811c
--- /dev/null
+++ b/tools/conf-examples/triangle.conf
@@ -0,0 +1,9 @@
+# a, b and c are connected through p2p shim DIFs
+eth 300 10Mbps a b
+eth 400 20Mbps b c
+eth 500 30Mbps a c
+
+# DIF n1 spans over the p2p shim DIFs
+dif n1 a 300 500
+dif n1 b 300 400
+dif n1 c 400 500
diff --git a/tools/conf-examples/tutorial1.conf b/tools/conf-examples/tutorial1.conf
new file mode 100644
index 0000000..8023687
--- /dev/null
+++ b/tools/conf-examples/tutorial1.conf
@@ -0,0 +1,4 @@
+eth 100 0Mbps system1 system2
+
+dif Normal system1 100
+dif Normal system2 100
diff --git a/tools/conf-examples/tutorial2.conf b/tools/conf-examples/tutorial2.conf
new file mode 100644
index 0000000..b43fc17
--- /dev/null
+++ b/tools/conf-examples/tutorial2.conf
@@ -0,0 +1,6 @@
+eth 100 0Mbps system1 system2
+eth 101 0Mbps system2 system3
+
+dif Normal system1 100
+dif Normal system2 100 101
+dif Normal system3 101
diff --git a/tools/conf-examples/two-layers.conf b/tools/conf-examples/two-layers.conf
new file mode 100644
index 0000000..dc1bab2
--- /dev/null
+++ b/tools/conf-examples/two-layers.conf
@@ -0,0 +1,17 @@
+eth 300 0Mbps a b
+eth 400 0Mbps b c
+eth 500 0Mbps c d
+
+# DIF n1 spans a,b and c and runs over the shims
+dif n1 a 300
+dif n1 b 300 400
+dif n1 c 400
+
+# DIF n2 spans c and d and runs over the shims
+dif n2 c 500
+dif n2 d 500
+
+# DIF n3 spans over n1 and n2
+dif n3 a n1
+dif n3 c n1 n2
+dif n3 d n2
diff --git a/tools/dc-vpns.conf b/tools/dc-vpns.conf
deleted file mode 100644
index 8bfde51..0000000
--- a/tools/dc-vpns.conf
+++ /dev/null
@@ -1,114 +0,0 @@
-eth 110 100Mbps tor1 spine1
-eth 120 100Mbps tor1 spine2
-eth 11 25Mbps s11 tor1
-eth 12 25Mbps s12 tor1
-eth 13 25Mbps s13 tor1
-eth 14 25Mbps s14 tor1
-eth 15 25Mbps s15 tor1
-eth 16 25Mbps s16 tor1
-eth 17 25Mbps s17 tor1
-eth 18 25Mbps s18 tor1
-eth 210 100Mbps tor2 spine1
-eth 220 100Mbps tor2 spine2
-eth 21 25Mbps s21 tor2
-eth 22 25Mbps s22 tor2
-eth 23 25Mbps s23 tor2
-eth 24 25Mbps s24 tor2
-eth 25 25Mbps s25 tor2
-eth 26 25Mbps s26 tor2
-eth 27 25Mbps s27 tor2
-eth 28 25Mbps s28 tor2
-eth 310 100Mbps tor3 spine1
-eth 320 100Mbps tor3 spine2
-eth 31 25Mbps s31 tor3
-eth 32 25Mbps s32 tor3
-eth 33 25Mbps s33 tor3
-eth 34 25Mbps s34 tor3
-eth 35 25Mbps s35 tor3
-eth 36 25Mbps s36 tor3
-eth 37 25Mbps s37 tor3
-eth 38 25Mbps s38 tor3
-eth 410 100Mbps tor4 spine1
-eth 420 100Mbps tor4 spine2
-eth 41 25Mbps s41 tor4
-eth 42 25Mbps s42 tor4
-eth 43 25Mbps s43 tor4
-eth 44 25Mbps s44 tor4
-eth 45 25Mbps s45 tor4
-eth 46 25Mbps s46 tor4
-eth 47 25Mbps s47 tor4
-eth 48 25Mbps s48 tor4
-
-# DIF dcfabric  
-dif dcfabric tor1 110 120
-dif dcfabric tor2 210 220
-dif dcfabric tor3 310 320
-dif dcfabric tor4 410 420
-dif dcfabric spine1 110 210 310 410
-dif dcfabric spine2 120 220 320 420
-
-# DIF VPN1
-dif vpn1 s11 11
-dif vpn1 s12 12
-dif vpn1 s13 13
-dif vpn1 s14 14
-dif vpn1 tor1 11 12 13 14 dcfabric
-dif vpn1 s21 21
-dif vpn1 s22 22
-dif vpn1 s23 23
-dif vpn1 s24 24
-dif vpn1 tor2 21 22 23 24 dcfabric
-
-# DIF VPN2
-dif vpn2 s31 31
-dif vpn2 s32 32
-dif vpn2 s33 33
-dif vpn2 s34 34
-dif vpn2 tor3 31 32 33 34 dcfabric
-dif vpn2 s41 41
-dif vpn2 s42 42
-dif vpn2 s43 43
-dif vpn2 s44 44
-dif vpn2 tor4 41 42 43 44 dcfabric
-
-# DIF VPN3
-dif vpn3 s15 15
-dif vpn3 s16 16
-dif vpn3 s17 17
-dif vpn3 s18 18
-dif vpn3 tor1 15 16 17 18 dcfabric
-dif vpn3 s25 25
-dif vpn3 s26 26
-dif vpn3 s27 27
-dif vpn3 s28 28
-dif vpn3 tor2 25 26 27 28  dcfabric
-
-# DIF VPN4
-dif vpn4 s35 35
-dif vpn4 s36 36
-dif vpn4 s37 37
-dif vpn4 s38 38
-dif vpn4 tor3 35 36 37 38 dcfabric
-dif vpn4 s45 45
-dif vpn4 s46 46
-dif vpn4 s47 47
-dif vpn4 s48 48
-dif vpn4 tor4 45 46 47 48 dcfabric
-
-#Policies
-
-#Multipath FABRIC
-#policy dcfabric spine1,spine2 rmt.pff multipath
-#policy dcfabric spine1,spine2 routing link-state routingAlgorithm=ECMPDijkstra
-#policy dcfabric * rmt cas-ps q_max=1000
-#policy dcfabric * efcp.*.dtcp cas-ps
-
-#Application to DIF mappings
-#appmap vpn1 traffic.generator.server 1
-#appmap vpn1 rina.apps.echotime.server 1
-#appmap vpn2 traffic.generator.server 1
-#appmap vpn2 rina.apps.echotime.server 1
-#appmap vpn3 traffic.generator.server 1
-#appmap vpn3 rina.apps.echotime.server 1
-#appmap vpn4 traffic.generator.server 1
-#appmap vpn4 rina.apps.echotime.server 1
diff --git a/tools/geant2-renumber.conf b/tools/geant2-renumber.conf
deleted file mode 100644
index 07c014c..0000000
--- a/tools/geant2-renumber.conf
+++ /dev/null
@@ -1,86 +0,0 @@
-eth 2000 100Mbps lisbon madrid
-eth 2001 100Mbps lisbon london
-eth 2002 100Mbps london dublin
-eth 2003 100Mbps london paris
-eth 2004 100Mbps london brussels
-eth 2005 100Mbps paris madrid
-eth 2006 100Mbps paris luxemburg
-eth 2007 100Mbps paris bern
-eth 2008 100Mbps madrid bern
-eth 2009 100Mbps bern roma
-eth 2010 100Mbps roma madrid
-eth 2011 100Mbps brussels amsterdam
-eth 2012 100Mbps roma valleta
-eth 2013 100Mbps amsterdam valleta
-eth 2014 100Mbps bern berlin
-eth 2015 100Mbps luxemburg berlin
-eth 2016 100Mbps amsterdam berlin
-eth 2017 100Mbps amsterdam copenhagen
-eth 2018 100Mbps berlin copenhagen
-eth 2019 100Mbps copenhagen oslo
-eth 2020 100Mbps oslo stockholm
-eth 2021 100Mbps stockholm copenhagen
-eth 2023 100Mbps copenhagen tallin
-eth 2024 100Mbps tallin riga
-eth 2025 100Mbps riga vilnius
-eth 2026 100Mbps vilnius warsaw
-eth 2027 100Mbps warsaw berlin
-eth 2028 100Mbps warsaw praha
-eth 2029 100Mbps berlin praha
-eth 2030 100Mbps berlin viena
-eth 2031 100Mbps praha viena
-eth 2032 100Mbps viena budapest
-eth 2034 100Mbps viena ljubljana
-eth 2035 100Mbps ljubljana zagreb
-eth 2036 100Mbps zagreb budapest
-eth 2037 100Mbps budapest sofia
-eth 2038 100Mbps viena athens
-eth 2039 100Mbps sofia athens
-eth 2040 100Mbps athens roma
-eth 2041 100Mbps sofia bucharest
-eth 2042 100Mbps bucharest budapest
-eth 2043 100Mbps athens nicosia
-eth 2044 100Mbps roma nicosia
-eth 2045 100Mbps sofia ankara
-eth 2046 100Mbps bucharest ankara
-eth 2047 100Mbps berlin moscow
-eth 2048 100Mbps copenhagen moscow
-eth 2049 100Mbps roma viena
-
-# DIF renumber  
-dif renumber lisbon 2000 2001
-dif renumber madrid 2000 2005
-dif renumber london 2001 2002 2003 2004
-dif renumber dublin 2002
-dif renumber paris 2003 2005 2006 2007
-dif renumber brussels 2004 2011
-dif renumber luxemburg 2006 2015
-dif renumber bern 2007 2008 2009 2014
-dif renumber roma 2009 2010 2012 2040 2044 2049
-dif renumber amsterdam 2011 2013 2016 2017
-dif renumber valleta 2012 2013
-dif renumber berlin 2014 2015 2016 2018 2027 2029 2030 2047
-dif renumber copenhagen 2017 2018 2019 2021 2023 2048
-dif renumber oslo 2019 2020
-dif renumber stockholm 2020 2021
-dif renumber tallin 2023 2024
-dif renumber riga 2024 2025
-dif renumber vilnius 2025 2026
-dif renumber warsaw 2026 2027 2028
-dif renumber praha 2028 2029 2031
-dif renumber viena 2030 2031 2032 2034 2038
-dif renumber budapest 2032 2036 2037 2042
-dif renumber athens 2038 2039 2040 2043
-dif renumber ljubljana 2034 2035
-dif renumber zagreb 2035 2036
-dif renumber sofia 2037 2039 2041 2045
-dif renumber bucharest 2041 2042 2046
-dif renumber nicosia 2043 2044
-dif renumber ankara 2045 2046
-dif renumber moscow 2047 2048
-
-#Policies
-
-#address-change
-policy renumber * namespace-manager address-change useNewTimeout=20001 deprecateOldTimeout=80001 changePeriod=120001 addressRange=100
-policy renumber * routing link-state objectMaximumAge=10000 waitUntilReadCDAP=5001 waitUntilError=5001 waitUntilPDUFTComputation=103 waitUntilFSODBPropagation=101 waitUntilAgeIncrement=997 waitUntilDeprecateAddress=20001 routingAlgorithm=Dijkstra
diff --git a/tools/insane-stacking.conf b/tools/insane-stacking.conf
deleted file mode 100644
index 8032fea..0000000
--- a/tools/insane-stacking.conf
+++ /dev/null
@@ -1,29 +0,0 @@
-eth 300 0Mbps a b
-
-# DIF n1 lays over shim DIF 300
-dif n1 a 300
-dif n1 b 300
-
-# n2 lays over n1
-dif n2 a n1
-dif n2 b n1
-
-# n3 lays over n2
-dif n3 a n2
-dif n3 b n2
-
-# n4 lays over n3
-dif n4 a n3
-dif n4 b n3
-
-# n5 lays over n4
-dif n5 a n4
-dif n5 b n4
-
-# n6 lays over n5
-dif n6 a n5
-dif n6 b n5
-
-# n7 lays over n6
-dif n7 a n6
-dif n7 b n6
diff --git a/tools/isp-sec.conf b/tools/isp-sec.conf
deleted file mode 100644
index 33a35a6..0000000
--- a/tools/isp-sec.conf
+++ /dev/null
@@ -1,189 +0,0 @@
-eth 110 0Mbps cpe11 ar1
-eth 120 0Mbps cpe12 ar1
-eth 130 0Mbps cpe13 ar1
-eth 210 0Mbps cpe21 ar2
-eth 220 0Mbps cpe22 ar2
-eth 230 0Mbps cpe23 ar2
-eth 310 0Mbps cpe31 ar3
-eth 320 0Mbps cpe32 ar3
-eth 330 0Mbps cpe33 ar3
-eth 100 0Mbps ar1 manpe1
-eth 200 0Mbps ar2 manpe1
-eth 300 0Mbps ar3 manpe2
-eth 410 0Mbps manpe1 manpe2
-eth 411 0Mbps manpe1 manpe3
-eth 412 0Mbps manpe1 manpe4
-eth 420 0Mbps manpe2 manpe3
-eth 421 0Mbps manpe2 manpe4
-eth 430 0Mbps manpe3 manpe4
-eth 510 0Mbps manpe3 ser1
-eth 520 0Mbps manpe4 ser2
-eth 600 0Mbps ser1 core1
-eth 610 0Mbps ser1 core2
-eth 620 0Mbps ser2 core1
-eth 630 0Mbps ser2 core2
-eth 700 0Mbps core1 core2
-eth 710 0Mbps core1 core3
-eth 720 0Mbps core2 core4
-eth 730 0Mbps core3 core4
-eth 640 0Mbps core3 edge1
-eth 650 0Mbps core4 edge1
-eth 660 0Mbps core3 edge2
-eth 670 0Mbps core4 edge2
-eth 800 0Mbps edge1 isp2
-eth 810 0Mbps edge1 isp3
-eth 820 0Mbps edge2 isp4
-eth 830 0Mbps edge2 isp5
-
-# DIF core
-dif core ser1 600 610
-dif core ser2 620 630
-dif core core1 600 620 700 710
-dif core core2 610 630 700 720
-dif core core3 640 660 710 730 
-dif core core4 650 670 720 730
-dif core edge1 640 650
-dif core edge2 660 670
-
-# DIF access
-dif access ar1 100
-dif access ar2 200
-dif access ar3 300
-dif access manpe1 100 200 410 411 412
-dif access manpe2 300 410 420 421
-dif access manpe3 411 420 430 510
-dif access manpe4 412 421 430 520
-dif access ser1 510
-dif access ser2 520
-
-# DIF service
-dif service ar1 access
-dif service ar2 access
-dif service ar3 access
-dif service ser1 access core
-dif service ser2 access core
-dif service edge1 core
-dif service edge2 core
-
-# DIF emall1
-dif emall1 cpe11 110
-dif emall1 cpe12 120
-dif emall1 cpe21 210
-dif emall1 cpe22 220
-dif emall1 cpe31 310
-dif emall1 ar1 110 120 service
-dif emall1 ar2 210 220 service
-dif emall1 ar3 310 service
-dif emall1 edge1 service 800
-dif emall1 edge2 service 820
-dif emall1 isp2 800
-dif emall1 isp4 820
-
-# DIF emall2
-dif emall2 cpe13 130
-dif emall2 cpe23 230
-dif emall2 cpe32 320
-dif emall2 cpe33 330
-dif emall2 ar1 130 service
-dif emall2 ar2 230 service
-dif emall2 ar3 320 330 service
-dif emall2 edge1 service 810
-dif emall2 edge2 service 830
-dif emall2 isp3 810
-dif emall2 isp5 830
-
-#policies
-policy emall1 * security-manager.auth.default PSOC_authentication-ssh2 keyExchangeAlg=EDH keystore=/creds/ssh2 keystorePass=test
-policy emall1 * security-manager.encrypt.default default encryptAlg=AES128 macAlg=SHA256 compressAlg=deflate 
-policy emall1 ar1,ar2,ar3,edge1,edge2 security-manager.auth.service PSOC_authentication-none
-policy emall2 * security-manager.auth.default PSOC_authentication-ssh2 keyExchangeAlg=EDH keystore=/creds/ssh2 keystorePass=test
-policy emall2 * security-manager.encrypt.default default encryptAlg=AES128 macAlg=SHA256 compressAlg=deflate
-policy emall2 ar1,ar2,ar3,edge1,edge2 security-manager.auth.service PSOC_authentication-none
-
-#Enrollments
-enroll access ar1 manpe1 100
-enroll access ar2 manpe1 200
-enroll access ar3 manpe2 300
-enroll access ser1 manpe3 510
-enroll access ser2 manpe4 520
-enroll access manpe1 manpe2 410
-enroll access manpe1 manpe3 411
-enroll access manpe1 manpe4 412
-enroll access manpe2 manpe3 420
-enroll access manpe2 manpe4 421
-enroll access manpe3 manpe4 430
-
-enroll core core1 core2 700
-enroll core core1 core3 710
-enroll core core2 core4 720
-enroll core core3 core4 730
-enroll core ser1 core1 600
-enroll core ser1 core2 610
-enroll core ser2 core1 620
-enroll core ser2 core2 630
-enroll core edge1 core3 640
-enroll core edge1 core4 650
-enroll core edge2 core3 660
-enroll core edge2 core4 670
-
-enroll service edge1 edge2 core
-enroll service edge1 ser1 core
-enroll service edge1 ser2 core
-enroll service edge2 ser1 core
-enroll service edge2 ser2 core
-enroll service ser1 ser2 core
-enroll service ar1 ser1 access
-enroll service ar1 ser2 access
-enroll service ar2 ser1 access
-enroll service ar2 ser2 access
-enroll service ar3 ser1 access
-enroll service ar3 ser2 access
-
-enroll emall1 cpe11 ar1 110
-enroll emall1 cpe12 ar1 120
-enroll emall1 cpe21 ar2 210
-enroll emall1 cpe22 ar2 220
-enroll emall1 cpe31 ar3 310
-enroll emall1 ar1 edge1 service
-enroll emall1 ar1 edge2 service
-enroll emall1 ar2 edge1 service
-enroll emall1 ar2 edge2 service
-enroll emall1 ar3 edge1 service
-enroll emall1 ar3 edge2 service
-enroll emall1 edge1 edge2 service
-enroll emall1 isp2 edge1 800
-enroll emall1 isp4 edge2 820
-
-enroll emall2 cpe13 ar1 130
-enroll emall2 cpe23 ar2 230
-enroll emall2 cpe32 ar3 320
-enroll emall2 cpe33 ar3 330
-enroll emall2 ar1 edge1 service
-enroll emall2 ar1 edge2 service
-enroll emall2 ar2 edge1 service
-enroll emall2 ar2 edge2 service
-enroll emall2 ar3 edge1 service
-enroll emall2 ar3 edge2 service
-enroll emall2 edge1 edge2 service
-enroll emall2 isp3 edge1 810
-enroll emall2 isp5 edge2 830
-
-#Overlays
-overlay ar1 overlays/ispsec/ar1
-overlay ar2 overlays/ispsec/ar2
-overlay ar3 overlays/ispsec/ar3
-overlay cpe11 overlays/ispsec/cpe11
-overlay cpe12 overlays/ispsec/cpe12
-overlay cpe13 overlays/ispsec/cpe13
-overlay cpe21 overlays/ispsec/cpe21
-overlay cpe22 overlays/ispsec/cpe22
-overlay cpe23 overlays/ispsec/cpe23
-overlay cpe31 overlays/ispsec/cpe31
-overlay cpe32 overlays/ispsec/cpe32
-overlay cpe33 overlays/ispsec/cpe33
-overlay edge1 overlays/ispsec/edge1
-overlay edge2 overlays/ispsec/edge2
-overlay isp2 overlays/ispsec/isp2
-overlay isp3 overlays/ispsec/isp3
-overlay isp4 overlays/ispsec/isp4
-overlay isp5 overlays/ispsec/isp5
diff --git a/tools/resilient-square.conf b/tools/resilient-square.conf
deleted file mode 100644
index 592b6a5..0000000
--- a/tools/resilient-square.conf
+++ /dev/null
@@ -1,16 +0,0 @@
-# a, b and c and d are connected through p2p shim DIFs, in circle.
-# Between a and c there is an additional diagonal link.
-eth 300 100Mbps a b
-eth 400 100Mbps b c
-eth 500 100Mbps c d
-eth 600 1Mbps   d a
-eth 700 100Mbps a c
-
-# DIF n1 spans over the p2p shim DIFs
-dif n1 a 300 600 700
-dif n1 b 300 400
-dif n1 c 400 500 700
-dif n1 d 500 600
-
-# Use LFA policy as PDU Forwarding Function
-policy n1 * rmt.pff lfa
diff --git a/tools/secure-two-layers.conf b/tools/secure-two-layers.conf
deleted file mode 100644
index 54c1da6..0000000
--- a/tools/secure-two-layers.conf
+++ /dev/null
@@ -1,25 +0,0 @@
-eth 300 0Mbps a b
-eth 400 0Mbps b c
-eth 500 0Mbps c d
-
-# DIF n1 spans a,b and c and runs over the shims
-dif n1 a 300
-dif n1 b 300 400
-dif n1 c 400
-
-# DIF n2 spans c and d and runs over the shims
-dif n2 c 500
-dif n2 d 500
-
-# DIF n3 spans over n1 and n2
-dif n3 a n1
-dif n3 c n1 n2
-dif n3 d n2
-
-policy n3 * security-manager.auth.default PSOC_authentication-ssh2 keyExchangeAlg=EDH keystore=/creds keystorePass=test
-policy n3 * security-manager.encrypt.default default encryptAlg=AES128 macAlg=SHA256 compressAlg=deflate
-policy n3 * security-manager.ttl.default default initialValue=50
-policy n3 * security-manager.errorcheck.default CRC32
-policy n3 * security-manager.auth.n1 PSOC_authentication-password password=kf05j.a1234.af0k
-policy n3 * security-manager.ttl.n1 default initialValue=50
-policy n3 * security-manager.errorcheck.n1 CRC32
diff --git a/tools/seven.conf b/tools/seven.conf
deleted file mode 100644
index b25f476..0000000
--- a/tools/seven.conf
+++ /dev/null
@@ -1,34 +0,0 @@
-# This configuration realizes the following seven-nodes topology
-#
-# MA ---- MB ---- MC --- MD --- ME
-#                 |             |
-#                 MF            MG
-#
-
-# 300 is a shim-eth-vlan DIF, with nodes a and b
-eth 300 0Mbps a b
-
-# 400 is a shim-eth-vlan DIF, with nodes b and c
-eth 400 0Mbps b c
-
-# 500 is a shim-eth-vlan DIF, with nodes c and f
-eth 500 0Mbps c f
-
-# 600 is a shim-eth-vlan DIF, with nodes c and d
-eth 600 0Mbps c d
-
-# 700 is a shim-eth-vlan DIF, with nodes d and e
-eth 700 0Mbps d e
-
-# 800 is a shim-eth-vlan DIF, with nodes e and g
-eth 800 0Mbps e g
-
-# DIF n1 spans over the two shim DIFs
-dif n1 a 300
-dif n1 b 300 400
-dif n1 c 400 500 600
-dif n1 d 600 700
-dif n1 e 700 800
-dif n1 f 500
-dif n1 g 800
-
diff --git a/tools/star.conf b/tools/star.conf
deleted file mode 100644
index 8a4f6ab..0000000
--- a/tools/star.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-# a,b and c are in the same L2 domain
-eth 300 0Mbps a b c
-
-# DIF n1 spans over the shim DIF
-dif n1 a 300
-dif n1 b 300
-dif n1 c 300
diff --git a/tools/triangle.conf b/tools/triangle.conf
deleted file mode 100644
index f89811c..0000000
--- a/tools/triangle.conf
+++ /dev/null
@@ -1,9 +0,0 @@
-# a, b and c are connected through p2p shim DIFs
-eth 300 10Mbps a b
-eth 400 20Mbps b c
-eth 500 30Mbps a c
-
-# DIF n1 spans over the p2p shim DIFs
-dif n1 a 300 500
-dif n1 b 300 400
-dif n1 c 400 500
diff --git a/tools/tutorial1.conf b/tools/tutorial1.conf
deleted file mode 100644
index 8023687..0000000
--- a/tools/tutorial1.conf
+++ /dev/null
@@ -1,4 +0,0 @@
-eth 100 0Mbps system1 system2
-
-dif Normal system1 100
-dif Normal system2 100
diff --git a/tools/tutorial2.conf b/tools/tutorial2.conf
deleted file mode 100644
index b43fc17..0000000
--- a/tools/tutorial2.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-eth 100 0Mbps system1 system2
-eth 101 0Mbps system2 system3
-
-dif Normal system1 100
-dif Normal system2 100 101
-dif Normal system3 101
diff --git a/tools/two-layers.conf b/tools/two-layers.conf
deleted file mode 100644
index dc1bab2..0000000
--- a/tools/two-layers.conf
+++ /dev/null
@@ -1,17 +0,0 @@
-eth 300 0Mbps a b
-eth 400 0Mbps b c
-eth 500 0Mbps c d
-
-# DIF n1 spans a,b and c and runs over the shims
-dif n1 a 300
-dif n1 b 300 400
-dif n1 c 400
-
-# DIF n2 spans c and d and runs over the shims
-dif n2 c 500
-dif n2 d 500
-
-# DIF n3 spans over n1 and n2
-dif n3 a n1
-dif n3 c n1 n2
-dif n3 d n2
-- 
cgit v1.2.3


From 6eceae4bf7ee823d6eed276935741b7c107f6105 Mon Sep 17 00:00:00 2001
From: Marco Capitani <m.capitani@nextworks.it>
Date: Fri, 14 Apr 2017 17:52:56 +0200
Subject: Implemented several comments on MR 22:

+ Used paramiko for scp (implemented new method in ssh_support
+ removed (obsoleted) private key for access to vms
+ used setup_vlans from ssh_support
---
 rumba/prototypes/irati.py  | 56 +++++++++++++--------------
 rumba/prototypes/irati_rsa | 27 -------------
 rumba/ssh_support.py       | 96 ++++++++++++++++++++++++++++++++++++++--------
 rumba/testbeds/qemu.py     | 13 +------
 4 files changed, 107 insertions(+), 85 deletions(-)
 delete mode 100644 rumba/prototypes/irati_rsa

diff --git a/rumba/prototypes/irati.py b/rumba/prototypes/irati.py
index edc49c6..89c4fe4 100644
--- a/rumba/prototypes/irati.py
+++ b/rumba/prototypes/irati.py
@@ -31,9 +31,6 @@ import rumba.prototypes.irati_templates as irati_templates
 
 
 # An experiment over the IRATI implementation
-from rumba import ssh_support
-
-
 class Experiment(mod.Experiment):
 
     @staticmethod
@@ -47,6 +44,7 @@ class Experiment(mod.Experiment):
     def __init__(self, testbed, nodes=None):
         mod.Experiment.__init__(self, testbed, nodes)
         self.manager = False
+        self.conf_files = None
 
         if self.testbed.username == 'root':
             self.sudo = self.fake_sudo
@@ -94,7 +92,7 @@ class Experiment(mod.Experiment):
         print("[IRATI experiment] start")
         print("Setting up IRATI on the nodes...")
         self.setup()
-        self.write_conf()
+        self.conf_files = self.write_conf()
         self.bootstrap_network()
         self.run_experiment()
         print("[IRATI experiment] end")
@@ -107,45 +105,34 @@ class Experiment(mod.Experiment):
         :return: 
         """
         name = node.name
-        gen_files_conf = 'shimeth.%(name)s.*.dif da.map %(name)s.ipcm.conf' % {
-            'name': name}
-        if any(node in dif.members for dif in self.dif_ordering):
-            gen_files_conf = ' '.join(
-                [gen_files_conf, 'normal.%(name)s.*.dif' % {'name': name}])
+        gen_files_conf = self.conf_files[node] + ['da.map']
         dir_path = os.path.dirname(os.path.abspath(__file__))
         gen_files_bin = 'enroll.py'
-        gen_files_conf_full = \
-            ' '.join([self.conf_dir(x) for x in gen_files_conf.split()])
-        gen_files_bin_full = os.path.join(dir_path, 'enroll.py')
+        gen_files_conf_full = [self.conf_dir(x) for x in gen_files_conf]
+        gen_files_bin_full = [os.path.join(dir_path, 'enroll.py')]
 
         ipcm_components = ['scripting', 'console']
         if self.manager:
             ipcm_components.append('mad')
         ipcm_components = ', '.join(ipcm_components)
 
-        gen_files = ' '.join([gen_files_conf_full, gen_files_bin_full])
+        gen_files = gen_files_conf_full + gen_files_bin_full
 
-        sshopts = ('-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
-                   ' -o IdentityFile=%s'
-                   % (os.path.join(dir_path, 'irati_rsa',)))
         format_args = {'name': name,
                        'ssh': node.ssh_config.port,
                        'username': self.testbed.username,
                        'genfiles': gen_files,
-                       'genfilesconf': gen_files_conf,
+                       'genfilesconf': ' '.join(gen_files_conf),
                        'genfilesbin': gen_files_bin,
-                       'sshopts': sshopts,
                        'installpath': '/usr',
                        'verb': 'DBG',
                        'ipcmcomps': ipcm_components}
         try:
-            print('DEBUG: executing >> '
-                  'scp %(sshopts)s -r -P %(ssh)s '
-                  '%(genfiles)s %(username)s@localhost:'
-                  % format_args)
-            subprocess.check_call(('scp %(sshopts)s -r -P %(ssh)s '
-                                   '%(genfiles)s %(username)s@localhost:'
-                                   % format_args), shell=True)
+            # TODO: watch out for empty path...
+            ssh.copy_paths_to_testbed(self.testbed,
+                                      node.ssh_config,
+                                      gen_files,
+                                      '')
         except subprocess.CalledProcessError as e:
             raise Exception(str(e))
 
@@ -154,7 +141,8 @@ class Experiment(mod.Experiment):
         cmds = [self.sudo('hostname %(name)s' % format_args),
                 self.sudo('chmod a+rw /dev/irati'),
                 self.sudo('mv %(genfilesconf)s /etc' % format_args),
-                self.sudo('mv %(genfilesbin)s /usr/bin') % format_args]
+                self.sudo('mv %(genfilesbin)s /usr/bin') % format_args,
+                self.sudo('chmod a+x /usr/bin/enroll.py') % format_args]
 
         # TODO: is the port up on the VM at this point?
 
@@ -167,7 +155,7 @@ class Experiment(mod.Experiment):
         # print('Credentials:')
         # print(node.ssh_config.hostname, node.ssh_config.port,
         #       self.testbed.username, self.testbed.password)
-        ssh_support.execute_commands(self.testbed, node.ssh_config, cmds)
+        ssh.execute_commands(self.testbed, node.ssh_config, cmds)
 
     def enroll_nodes(self):
         """Runs the enrollments one by one, respecting dependencies"""
@@ -198,9 +186,9 @@ class Experiment(mod.Experiment):
                 # print(e['enrollee'].ssh_config.hostname,
                 #       e['enrollee'].ssh_config.port,
                 #       self.testbed.username, self.testbed.password)
-                ssh_support.execute_command(self.testbed,
-                                            e['enrollee'].ssh_config,
-                                            cmd)
+                ssh.execute_command(self.testbed,
+                                    e['enrollee'].ssh_config,
+                                    cmd)
 
     def write_conf(self):
         """Write the configuration files"""
@@ -210,6 +198,7 @@ class Experiment(mod.Experiment):
         ipcp2shim_map = {}
         node2id_map = {}
         mgmt_dif_name = 'NMS'
+        conf_files = {}  # dict of per-nod conf files
 
         # TODO: what format are the mappings registered in? Is this ok?
         app_mappings = []
@@ -298,6 +287,8 @@ class Experiment(mod.Experiment):
                          },
                         indent=4, sort_keys=True))
                     fout.close()
+                    conf_files.setdefault(node, []).append(
+                        'shimeth.%s.%s.dif' % (node.name, shim.name))
 
         # Run over dif_ordering array, to make sure each IPCM config has
         # the correct ordering for the ipcProcessesToCreate list of operations.
@@ -360,6 +351,8 @@ class Experiment(mod.Experiment):
                           node_file,
                           indent=4,
                           sort_keys=True)
+            conf_files.setdefault(node, []).append(
+                '%s.ipcm.conf' % (node.name,))
 
         for dif in self.dif_ordering:  # type: mod.DIF
             dif_conf = difconfs.get(dif.name, None)
@@ -373,3 +366,6 @@ class Experiment(mod.Experiment):
                                   dif_conf_file,
                                   indent=4,
                                   sort_keys=True)
+                    conf_files.setdefault(node, []).append(
+                        'normal.%s.%s.dif' % (node.name, dif.name))
+        return conf_files
diff --git a/rumba/prototypes/irati_rsa b/rumba/prototypes/irati_rsa
deleted file mode 100644
index 8119a76..0000000
--- a/rumba/prototypes/irati_rsa
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAyfuwhIYMa2pCcbLYfeDblxaXNxLcJS8aJFjpwPVdXQoTwO79
-BmbZXFObrdxy3paaYyJBAIpOyAcn4B9oEcpHF7J6+IvDA6TpOf45tZzqVRdZxFd7
-ESPlleCpRxTWTmIFiR8j734v8sj0CXYjiegjhS9izhPobjz3ZaTDO4xfQbQs37JF
-7Xdcbjph/8ExqYyvz9yxU5rbCr3u7AurBRM/o5kfV5Ps+52WXNJT2RTjgQjmL1PQ
-0/K8DATPKW9ns1d90Zguf0cE2oZiUn85ukuvVAAOsvO0GOpncFhEUrTLCw/DMayP
-Wk1mjL1jJDeYbqf1cnOG+Wzt5glueKzSGhh6ewIDAQABAoIBAGN62QeMVhWZcjw5
-j7L/ymdxsuxnF5IgzslUGVz1/BPU4MHHc0tx4GA+tZA94T2MA2IL/uPbOs396D/U
-eBc6/yTGvRYpD9V9pXjwo0+1hxx9sbKoO27HtU3KJtVhh+N3F67fbX2JMuhq3PbD
-/uDvOn9gRVOmLnYNBPRE3/s2ObxLtkbT4QIuSF/XItxECBOwWNyTYdOmqhoz6XzA
-OPN9mGsKPMevWoKTfLffuMncIEyEEtV2Jnck/cHPha2GGuzty+faOGSF7GwHOpfu
-DQTK30lUFRmlHnId5UIRG0J+MfSJhk/VillJwvUFmCYgH5Ur7htDTER7JIeU8ym6
-YxY3HDECgYEA+fnqiqmst9LNXnjGnIAtnIi11DsmwDQaxW+kNvXvJsEWWboUbcPs
-q/Fzm0ACMLHARje4wynzIrBY5Iw8qzTswzPFo9CO4MNw/hvMO1iB0Dvo8rWqMJv4
-b2qsuo9r4QkVt53K6WVG/h9Ua/mqr2AQOaATj1ScGKpx0g10GjVqDGcCgYEAztm1
-NKxwqw/j1Pn5AnRRIMkDgO2O6fXKZEgoBdXDWrlHn4vr8fspNE+DMuonQS8GY7Xd
-a+APpPqNk32WKDCfeuKNZX7gXCnV39GOhNrhpfT14/dea1YEQ03vcxVD1aqkw2jl
-Y+qOG2kDBpYkPPEf5od6cfFvUet15d8NBwJXlM0CgYBypkcGNe/7l3mNvMMLAFbr
-FmCe6EpLmRo2N5APjRiUo7aGjKvV9ChWbDVjnSXkA4J2MhRRnqne3RbIK/GfbHSy
-ysn46iy9taXbRhCTn3JaeT/MIbne9YoqP7jdD+6glbQaNQrdpQ+8ec4Uf7vjF6IZ
-a+vMrzewsGvntTfs1VbAPQKBgQCl+8LRkrISQnzzEOfFFWtoYIUENxxgFxCiadhb
-3k2Vhmm32EKr+Xv18vv3pjd7se1xo6UbBD/phfiHatZMR8Ahjpwh3q7Qpe1uXaz8
-ZNt/HVMW7BADF5HyJB7J/T1ivjzaZVj1VWlVC24XIfHQSTjs9rfFqRRH6ya/H75H
-apS23QKBgCj4TWnRtMsEaZZIamgzxMw1eUdYH27ZeaG0Do+hZ1XGixq4CWxCqxVg
-nwbXRkRYwqI+2zzsaeNji4OX6wJdO7lZntuk4v6O0WeY9aJxGaLkYaRk5eF2TLyW
-IVQbpcC/q1fnCo3HjWxR3w8QYmsQi97AC7xUMsjqwntIGV1QrR7s
------END RSA PRIVATE KEY-----
diff --git a/rumba/ssh_support.py b/rumba/ssh_support.py
index 30ada62..3ed4208 100644
--- a/rumba/ssh_support.py
+++ b/rumba/ssh_support.py
@@ -17,9 +17,10 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA  02110-1301  USA
-
+import os
 import paramiko
 
+
 def get_ssh_client():
     ssh_client = paramiko.SSHClient()
     ssh_client.load_system_host_keys()
@@ -27,6 +28,7 @@ def get_ssh_client():
 
     return ssh_client
 
+
 def _print_stream(stream):
         o = str(stream.read()).strip('b\'\"\\n')
         if o != "":
@@ -35,6 +37,7 @@ def _print_stream(stream):
                 print(oi)
         return o
 
+
 def execute_commands(testbed, ssh_config, commands, time_out=3):
     '''
     Remote execution of a list of shell command on hostname. By
@@ -71,6 +74,7 @@ def execute_commands(testbed, ssh_config, commands, time_out=3):
         print(str(e))
         return
 
+
 def execute_command(testbed, ssh_config, command, time_out=3):
     '''
     Remote execution of a list of shell command on hostname. By
@@ -89,6 +93,7 @@ def execute_command(testbed, ssh_config, command, time_out=3):
     if o != None:
         return o
 
+
 def copy_file_to_testbed(testbed, ssh_config, text, file_name):
     '''
     Write a string to a given remote file.
@@ -125,6 +130,58 @@ def copy_file_to_testbed(testbed, ssh_config, text, file_name):
     except Exception as e:
         print(str(e))
 
+
+def copy_paths_to_testbed(testbed, ssh_config, paths, destination):
+    '''
+    Write a string to a given remote file.
+    Overwrite the complete file if it already exists!
+
+    @param testbed: testbed info
+    @param ssh_config: ssh config of the node
+    @param paths: source paths (local) as an iterable
+    @param destination: destination folder name (remote)
+    '''
+    ssh_client = get_ssh_client()
+
+    if destination is not '' and not destination.endswith('/'):
+        destination = destination + '/'
+
+    try:
+        ssh_client.connect(ssh_config.hostname, ssh_config.port,
+                           testbed.username,
+                           testbed.password,
+                           look_for_keys=True)
+
+        sftp_client = ssh_client.open_sftp()
+
+        for path in paths:
+            file_name = os.path.basename(path)
+            dest_file = destination + file_name
+            print("Copying %s to %s@%s:%s path %s" % (
+                path,
+                testbed.username,
+                ssh_config.hostname,
+                ssh_config.port,
+                dest_file))
+            sftp_client.put(path, dest_file)
+
+    except Exception as e:
+        print(str(e))
+
+
+def copy_path_to_testbed(testbed, ssh_config, path, destination):
+    '''
+    Write a string to a given remote file.
+    Overwrite the complete file if it already exists!
+
+    @param testbed: testbed info
+    @param ssh_config: ssh config of the node
+    @param path: source path (local)
+    @param destination: destination folder name (remote)
+    '''
+    copy_paths_to_testbed(testbed, ssh_config, [path], destination)
+
+
 def setup_vlan(testbed, node, vlan_id, int_name):
     '''
     Gets the interface (ethx) to link mapping
@@ -134,22 +191,27 @@ def setup_vlan(testbed, node, vlan_id, int_name):
     @param vlan_id: the VLAN id
     @param int_name: the name of the interface
     '''
+    if testbed.username == 'root':
+        def sudo(s):
+            return s
+    else:
+        def sudo(s):
+            return 'sudo ' + s
+
     print("Setting up VLAN on node " + node.name)
 
-    cmds = list()
-    cmd = "sudo ip link add link " + \
-          str(int_name) + \
-          " name " + str(int_name) + \
-          "." + str(vlan_id) + \
-          " type vlan id " + str(vlan_id)
-    cmds.append(cmd)
-    cmd = "sudo ifconfig " + \
-          str(int_name) + "." + \
-          str(vlan_id) + " up"
-    cmds.append(cmd)
-    cmd = "sudo ethtool -K " + \
-          str(int_name) + " rxvlan off"
-    cmds.append(cmd)
-    cmd = "sudo ethtool -K " + \
-          str(int_name) + " txvlan off"
+    args = {'ifname': str(int_name), 'vlan': str(vlan_id)}
+
+    cmds = [sudo("ip link set %(ifname)s up"
+                 % args),
+            sudo("ip link add link %(ifname)s name "
+                 "%(ifname)s.%(vlan)s type vlan id %(vlan)s"
+                 % args),
+            sudo("ifconfig %(ifname)s.%(vlan)s up"
+                 % args)]
+    # TODO: is ethtool needed? Should install or check if it is present.
+    # cmds += [sudo("ethtool -K %(ifname)s rxvlan off"
+    #               % args),
+    #          sudo("ethtool -K %(ifname)s txvlan off"
+    #               % args)]
     execute_commands(testbed, node.ssh_config, cmds)
diff --git a/rumba/testbeds/qemu.py b/rumba/testbeds/qemu.py
index 8ccc704..174b860 100644
--- a/rumba/testbeds/qemu.py
+++ b/rumba/testbeds/qemu.py
@@ -103,17 +103,8 @@ class Testbed(mod.Testbed):
                             vlan = next_vlan
                             next_vlan += 10
                             assigned_vlan[port['shim'].name] = vlan
-                    args = {'vlan': vlan, 'port': ipcp.ifname}
-                    cmds = ['ip link set %(port)s up'
-                            % args,
-                            'ip link add link %(port)s name %(port)s.%(vlan)s '
-                            'type vlan id %(vlan)s'
-                            % args,
-                            'ip link set %(port)s.%(vlan)s up'
-                            % args]
-                    ssh_support.execute_commands(self,
-                                                 node.ssh_config,
-                                                 cmds)
+                    ssh_support.setup_vlan(self, node,
+                                           vlan, ipcp.ifname)
 
     def swap_in(self, experiment):
         """
-- 
cgit v1.2.3